Add support for !=
, <
, <=
, >
, >=
This commit is contained in:
parent
407a6b267e
commit
f638ec66b4
@ -150,6 +150,14 @@ pub enum Expression {
|
||||
left: Box<Expression>,
|
||||
right: Box<Expression>,
|
||||
},
|
||||
LessThan {
|
||||
left: Box<Expression>,
|
||||
right: Box<Expression>,
|
||||
},
|
||||
LessThanOrEquals {
|
||||
left: Box<Expression>,
|
||||
right: Box<Expression>,
|
||||
},
|
||||
|
||||
// Other Operators
|
||||
ListAdd {
|
||||
|
@ -152,7 +152,7 @@ wshack = _{ (wsnc | (comment ~ &(ws* ~ Expr)))* }
|
||||
Expr = { prefix* ~ ws* ~ Term ~ ws* ~ postfix* ~ (ws* ~ infix ~ ws* ~ prefix* ~ ws* ~ Term ~ wshack ~ postfix*)* }
|
||||
|
||||
// INFIX
|
||||
infix = _{ add | sub | mul | div | pow | modulo | listAdd | equals | band | bor }
|
||||
infix = _{ add | sub | mul | div | pow | modulo | listAdd | equals | notEquals | greaterThanOrEqual | lessThanOrEqual | greaterThan | lessThan | band | bor }
|
||||
add = { "+" }
|
||||
sub = { "-" }
|
||||
mul = { "*" }
|
||||
@ -161,6 +161,11 @@ pow = { "^" }
|
||||
modulo = { "%" }
|
||||
listAdd = { "++" }
|
||||
equals = { "==" }
|
||||
notEquals = { "!=" }
|
||||
greaterThan = { ">" }
|
||||
lessThan = { "<" }
|
||||
greaterThanOrEqual = { ">=" }
|
||||
lessThanOrEqual = { "<=" }
|
||||
|
||||
// BUG: these should have forced whitespace at the start!
|
||||
// (lookbehind wouldn't be the worst feature in the world for a parser grammar!)
|
||||
|
@ -42,7 +42,12 @@ fn error<R: Copy + Debug + Hash + Ord>(msg: &str, span: Span) -> PCError<R> {
|
||||
lazy_static! {
|
||||
static ref PRATT_PARSER: PrattParser<Rule> = PrattParser::new()
|
||||
.op(Op::infix(Rule::band, Assoc::Left) | Op::infix(Rule::bor, Assoc::Left))
|
||||
.op(Op::infix(Rule::equals, Assoc::Left))
|
||||
.op(Op::infix(Rule::equals, Assoc::Left)
|
||||
| Op::infix(Rule::notEquals, Assoc::Left)
|
||||
| Op::infix(Rule::lessThan, Assoc::Left)
|
||||
| Op::infix(Rule::greaterThan, Assoc::Left)
|
||||
| Op::infix(Rule::greaterThanOrEqual, Assoc::Left)
|
||||
| Op::infix(Rule::lessThanOrEqual, Assoc::Left))
|
||||
.op(Op::infix(Rule::add, Assoc::Left) | Op::infix(Rule::sub, Assoc::Left))
|
||||
.op(Op::infix(Rule::mul, Assoc::Left) | Op::infix(Rule::div, Assoc::Left))
|
||||
.op(Op::infix(Rule::pow, Assoc::Right))
|
||||
@ -294,6 +299,11 @@ impl HornbeamParser {
|
||||
Rule::mul => Expression::Mul { left: Box::new(lhs?), right: Box::new(rhs?) },
|
||||
Rule::div => Expression::Div { left: Box::new(lhs?), right: Box::new(rhs?) },
|
||||
Rule::equals => Expression::Equals { left: Box::new(lhs?), right: Box::new(rhs?) },
|
||||
Rule::notEquals => Expression::BNot { sub: Box::new(Expression::Equals { left: Box::new(lhs?), right: Box::new(rhs?) }) },
|
||||
Rule::lessThan => Expression::LessThan { left: Box::new(lhs?), right: Box::new(rhs?) },
|
||||
Rule::lessThanOrEqual => Expression::LessThanOrEquals { left: Box::new(lhs?), right: Box::new(rhs?) },
|
||||
Rule::greaterThan => Expression::BNot { sub: Box::new(Expression::LessThanOrEquals { left: Box::new(lhs?), right: Box::new(rhs?) }) },
|
||||
Rule::greaterThanOrEqual => Expression::BNot { sub: Box::new(Expression::LessThan { left: Box::new(lhs?), right: Box::new(rhs?) }) },
|
||||
Rule::bor => Expression::BOr { left: Box::new(lhs?), right: Box::new(rhs?) },
|
||||
Rule::band => Expression::BAnd { left: Box::new(lhs?), right: Box::new(rhs?) },
|
||||
other => unimplemented!("unimp infix {other:?}!"),
|
||||
|
@ -618,6 +618,34 @@ impl<'a, O: OutputSystem + Send, LS: LocalisationSystem + Sync + Send> Interpret
|
||||
}),
|
||||
}
|
||||
}
|
||||
Expression::LessThan { left, right } => {
|
||||
let lval = self.evaluate_expression(scope_idx, &left, loc)?;
|
||||
let rval = self.evaluate_expression(scope_idx, &right, loc)?;
|
||||
|
||||
match (lval, rval) {
|
||||
(Value::Int(lint), Value::Int(rint)) => Ok(Value::Bool(lint < rint)),
|
||||
(Value::Str(lstr), Value::Str(rstr)) => Ok(Value::Bool(lstr < rstr)),
|
||||
(lother, rother) => Err(InterpreterError::TypeError {
|
||||
context: "LessThan".to_string(),
|
||||
conflict: format!("can't test {lother:?} < {rother:?}!"),
|
||||
location: loc.clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
Expression::LessThanOrEquals { left, right } => {
|
||||
let lval = self.evaluate_expression(scope_idx, &left, loc)?;
|
||||
let rval = self.evaluate_expression(scope_idx, &right, loc)?;
|
||||
|
||||
match (lval, rval) {
|
||||
(Value::Int(lint), Value::Int(rint)) => Ok(Value::Bool(lint <= rint)),
|
||||
(Value::Str(lstr), Value::Str(rstr)) => Ok(Value::Bool(lstr <= rstr)),
|
||||
(lother, rother) => Err(InterpreterError::TypeError {
|
||||
context: "LessThanOrEquals".to_string(),
|
||||
conflict: format!("can't test {lother:?} <= {rother:?}!"),
|
||||
location: loc.clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
Expression::ListAdd { left, right } => {
|
||||
let lval = self.evaluate_expression(scope_idx, &left, loc)?;
|
||||
let rval = self.evaluate_expression(scope_idx, &right, loc)?;
|
||||
|
Loading…
Reference in New Issue
Block a user