Add support for !=
, <
, <=
, >
, >=
This commit is contained in:
parent
407a6b267e
commit
f638ec66b4
@ -150,6 +150,14 @@ pub enum Expression {
|
|||||||
left: Box<Expression>,
|
left: Box<Expression>,
|
||||||
right: Box<Expression>,
|
right: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
LessThan {
|
||||||
|
left: Box<Expression>,
|
||||||
|
right: Box<Expression>,
|
||||||
|
},
|
||||||
|
LessThanOrEquals {
|
||||||
|
left: Box<Expression>,
|
||||||
|
right: Box<Expression>,
|
||||||
|
},
|
||||||
|
|
||||||
// Other Operators
|
// Other Operators
|
||||||
ListAdd {
|
ListAdd {
|
||||||
|
@ -152,7 +152,7 @@ wshack = _{ (wsnc | (comment ~ &(ws* ~ Expr)))* }
|
|||||||
Expr = { prefix* ~ ws* ~ Term ~ ws* ~ postfix* ~ (ws* ~ infix ~ ws* ~ prefix* ~ ws* ~ Term ~ wshack ~ postfix*)* }
|
Expr = { prefix* ~ ws* ~ Term ~ ws* ~ postfix* ~ (ws* ~ infix ~ ws* ~ prefix* ~ ws* ~ Term ~ wshack ~ postfix*)* }
|
||||||
|
|
||||||
// INFIX
|
// 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 = { "+" }
|
add = { "+" }
|
||||||
sub = { "-" }
|
sub = { "-" }
|
||||||
mul = { "*" }
|
mul = { "*" }
|
||||||
@ -161,6 +161,11 @@ pow = { "^" }
|
|||||||
modulo = { "%" }
|
modulo = { "%" }
|
||||||
listAdd = { "++" }
|
listAdd = { "++" }
|
||||||
equals = { "==" }
|
equals = { "==" }
|
||||||
|
notEquals = { "!=" }
|
||||||
|
greaterThan = { ">" }
|
||||||
|
lessThan = { "<" }
|
||||||
|
greaterThanOrEqual = { ">=" }
|
||||||
|
lessThanOrEqual = { "<=" }
|
||||||
|
|
||||||
// BUG: these should have forced whitespace at the start!
|
// BUG: these should have forced whitespace at the start!
|
||||||
// (lookbehind wouldn't be the worst feature in the world for a parser grammar!)
|
// (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! {
|
lazy_static! {
|
||||||
static ref PRATT_PARSER: PrattParser<Rule> = PrattParser::new()
|
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::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::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::mul, Assoc::Left) | Op::infix(Rule::div, Assoc::Left))
|
||||||
.op(Op::infix(Rule::pow, Assoc::Right))
|
.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::mul => Expression::Mul { left: Box::new(lhs?), right: Box::new(rhs?) },
|
||||||
Rule::div => Expression::Div { 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::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::bor => Expression::BOr { left: Box::new(lhs?), right: Box::new(rhs?) },
|
||||||
Rule::band => Expression::BAnd { 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:?}!"),
|
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 } => {
|
Expression::ListAdd { left, right } => {
|
||||||
let lval = self.evaluate_expression(scope_idx, &left, loc)?;
|
let lval = self.evaluate_expression(scope_idx, &left, loc)?;
|
||||||
let rval = self.evaluate_expression(scope_idx, &right, loc)?;
|
let rval = self.evaluate_expression(scope_idx, &right, loc)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user