mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
FEATURE: Add the %%
modulo operator.
This commit is contained in:
parent
de97109681
commit
c7a87894ba
@ -62,3 +62,13 @@ assert {
|
|||||||
ok = (1 == 1) || (1 != 1) == true,
|
ok = (1 == 1) || (1 != 1) == true,
|
||||||
desc = "(1 == 1) && (1 != 1) == true",
|
desc = "(1 == 1) && (1 != 1) == true",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
assert {
|
||||||
|
ok = 4 %% 2 == 0,
|
||||||
|
desc = "4 %% 2 is 0",
|
||||||
|
};
|
||||||
|
|
||||||
|
assert {
|
||||||
|
ok = 4 %% 3 == 1,
|
||||||
|
desc = "4 %% 3 is 1",
|
||||||
|
};
|
@ -392,6 +392,7 @@ pub enum BinaryExprType {
|
|||||||
Sub,
|
Sub,
|
||||||
Mul,
|
Mul,
|
||||||
Div,
|
Div,
|
||||||
|
Mod,
|
||||||
// Boolean
|
// Boolean
|
||||||
AND,
|
AND,
|
||||||
OR,
|
OR,
|
||||||
@ -433,6 +434,7 @@ impl BinaryExprType {
|
|||||||
// Product operators are next tightly bound
|
// Product operators are next tightly bound
|
||||||
BinaryExprType::Mul => 4,
|
BinaryExprType::Mul => 4,
|
||||||
BinaryExprType::Div => 4,
|
BinaryExprType::Div => 4,
|
||||||
|
BinaryExprType::Mod => 4,
|
||||||
// Boolean operators bind tighter than math
|
// Boolean operators bind tighter than math
|
||||||
BinaryExprType::AND => 5,
|
BinaryExprType::AND => 5,
|
||||||
BinaryExprType::OR => 5,
|
BinaryExprType::OR => 5,
|
||||||
|
@ -613,6 +613,33 @@ impl<'a> FileBuilder<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mod_vals(
|
||||||
|
&self,
|
||||||
|
lpos: &Position,
|
||||||
|
rpos: &Position,
|
||||||
|
left: Rc<Val>,
|
||||||
|
right: Rc<Val>,
|
||||||
|
) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
|
match *left {
|
||||||
|
Val::Int(i) => {
|
||||||
|
eval_binary_expr!(&Val::Int(ii), rpos, right, Val::Int(i % ii), "Integer")
|
||||||
|
}
|
||||||
|
Val::Float(f) => {
|
||||||
|
eval_binary_expr!(&Val::Float(ff), rpos, right, Val::Float(f % ff), "Float")
|
||||||
|
}
|
||||||
|
ref expr => {
|
||||||
|
return Err(Box::new(error::BuildError::new(
|
||||||
|
format!(
|
||||||
|
"{} does not support the 'modulus' operation",
|
||||||
|
expr.type_name()
|
||||||
|
),
|
||||||
|
error::ErrorType::Unsupported,
|
||||||
|
lpos.clone(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn divide_vals(
|
fn divide_vals(
|
||||||
&self,
|
&self,
|
||||||
lpos: &Position,
|
lpos: &Position,
|
||||||
@ -964,6 +991,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
&BinaryExprType::Sub => self.subtract_vals(&def.pos, def.right.pos(), left, right),
|
&BinaryExprType::Sub => self.subtract_vals(&def.pos, def.right.pos(), left, right),
|
||||||
&BinaryExprType::Mul => self.multiply_vals(&def.pos, def.right.pos(), left, right),
|
&BinaryExprType::Mul => self.multiply_vals(&def.pos, def.right.pos(), left, right),
|
||||||
&BinaryExprType::Div => self.divide_vals(&def.pos, def.right.pos(), left, right),
|
&BinaryExprType::Div => self.divide_vals(&def.pos, def.right.pos(), left, right),
|
||||||
|
&BinaryExprType::Mod => self.mod_vals(&def.pos, def.right.pos(), left, right),
|
||||||
// Handle Comparison operators here
|
// Handle Comparison operators here
|
||||||
&BinaryExprType::Equal => self.do_deep_equal(def.right.pos(), left, right),
|
&BinaryExprType::Equal => self.do_deep_equal(def.right.pos(), left, right),
|
||||||
&BinaryExprType::GT => self.do_gt(&def.right.pos(), left, right),
|
&BinaryExprType::GT => self.do_gt(&def.right.pos(), left, right),
|
||||||
|
@ -59,7 +59,10 @@ make_fn!(
|
|||||||
(Element::Op(BinaryExprType::Mul))),
|
(Element::Op(BinaryExprType::Mul))),
|
||||||
do_each!(
|
do_each!(
|
||||||
_ => punct!("/"),
|
_ => punct!("/"),
|
||||||
(Element::Op(BinaryExprType::Div)))
|
(Element::Op(BinaryExprType::Div))),
|
||||||
|
do_each!(
|
||||||
|
_ => punct!("%%"),
|
||||||
|
(Element::Op(BinaryExprType::Mod)))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -175,6 +178,9 @@ fn parse_product_operator(i: SliceIter<Element>) -> Result<SliceIter<Element>, B
|
|||||||
&BinaryExprType::Div => {
|
&BinaryExprType::Div => {
|
||||||
return Result::Complete(i_.clone(), op.clone());
|
return Result::Complete(i_.clone(), op.clone());
|
||||||
}
|
}
|
||||||
|
&BinaryExprType::Mod => {
|
||||||
|
return Result::Complete(i_.clone(), op.clone());
|
||||||
|
}
|
||||||
_other => {
|
_other => {
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
@ -423,9 +429,9 @@ pub fn op_expression<'a>(i: SliceIter<'a, Token>) -> Result<SliceIter<Token>, Ex
|
|||||||
);
|
);
|
||||||
Result::Fail(err)
|
Result::Fail(err)
|
||||||
}
|
}
|
||||||
Result::Abort(_e) => {
|
Result::Abort(e) => {
|
||||||
let err = Error::new(
|
let err = Error::new(
|
||||||
"Abort while parsing operator expression",
|
format!("Abort while parsing operator expression\n{}", e),
|
||||||
Box::new(rest.clone()),
|
Box::new(rest.clone()),
|
||||||
);
|
);
|
||||||
Result::Abort(err)
|
Result::Abort(err)
|
||||||
|
@ -198,6 +198,10 @@ make_fn!(slashtok<OffsetStrIter, Token>,
|
|||||||
do_text_token_tok!(TokenType::PUNCT, "/")
|
do_text_token_tok!(TokenType::PUNCT, "/")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
make_fn!(modulustok<OffsetStrIter, Token>,
|
||||||
|
do_text_token_tok!(TokenType::PUNCT, "%%")
|
||||||
|
);
|
||||||
|
|
||||||
make_fn!(pcttok<OffsetStrIter, Token>,
|
make_fn!(pcttok<OffsetStrIter, Token>,
|
||||||
do_text_token_tok!(TokenType::PUNCT, "%")
|
do_text_token_tok!(TokenType::PUNCT, "%")
|
||||||
);
|
);
|
||||||
@ -403,6 +407,7 @@ fn token<'a>(input: OffsetStrIter<'a>) -> Result<OffsetStrIter<'a>, Token> {
|
|||||||
startok,
|
startok,
|
||||||
comment, // Note comment must come before slashtok
|
comment, // Note comment must come before slashtok
|
||||||
slashtok,
|
slashtok,
|
||||||
|
modulustok,
|
||||||
pcttok,
|
pcttok,
|
||||||
eqeqtok,
|
eqeqtok,
|
||||||
notequaltok,
|
notequaltok,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user