boolean operators
This commit is contained in:
parent
652106135c
commit
4ef3fdb46d
4 changed files with 31 additions and 6 deletions
21
src/eval.rs
21
src/eval.rs
|
@ -152,6 +152,8 @@ pub fn eval_expr(expr: &Expr, env: EnvRef) -> Result<Value, RuntimeError> {
|
|||
=> eval_assignment(lhs, rhs, op, env),
|
||||
Some(OpType::Additive) | Some(OpType::Multiplicative)
|
||||
=> eval_binary(lhs, rhs, op, env),
|
||||
Some(OpType::Boolean)
|
||||
=> eval_boolean(lhs, rhs, op, env),
|
||||
Some(OpType::Comparison)
|
||||
=> eval_comp(lhs, rhs, op, env),
|
||||
o => todo!("{:?}", o) // TODO other operations
|
||||
|
@ -178,7 +180,6 @@ pub fn eval_expr(expr: &Expr, env: EnvRef) -> Result<Value, RuntimeError> {
|
|||
let idx = eval_expr(index, env)?;
|
||||
l.index(&idx).map_err(|e| RuntimeError { message: e, pos: pos.clone() })
|
||||
},
|
||||
e => todo!("{:?}", e) // TODO other expression types
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,6 +276,23 @@ pub fn eval_binary(lhs: &Box<Expr>, rhs: &Box<Expr>, op: &Token, env: EnvRef) ->
|
|||
}.map_err(|e| RuntimeError { message: e, pos: op.pos.clone() })
|
||||
}
|
||||
|
||||
pub fn eval_boolean(lhs: &Box<Expr>, rhs: &Box<Expr>, op: &Token, env: EnvRef) -> Result<Value, RuntimeError> {
|
||||
let l = eval_expr(lhs, env.clone())?;
|
||||
match op.ty {
|
||||
TokenType::DoubleAmper => if l.truthy() {
|
||||
eval_expr(rhs, env)
|
||||
} else {
|
||||
Ok(l)
|
||||
},
|
||||
TokenType::DoublePipe => if !l.truthy() {
|
||||
eval_expr(rhs, env)
|
||||
} else {
|
||||
Ok(l)
|
||||
},
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eval_comp(lhs: &Box<Expr>, rhs: &Box<Expr>, op: &Token, env: EnvRef) -> Result<Value, RuntimeError> {
|
||||
let l = eval_expr(lhs, env.clone())?;
|
||||
let r = eval_expr(rhs, env)?;
|
||||
|
@ -308,6 +326,7 @@ pub fn eval_unary(arg: &Box<Expr>, op: &Token, env: EnvRef) -> Result<Value, Run
|
|||
let a = eval_expr(arg, env)?;
|
||||
match op.ty {
|
||||
TokenType::Minus => -a,
|
||||
TokenType::Bang => Ok(Value::Bool(!a.truthy())),
|
||||
_ => todo!(),
|
||||
}.map_err(|e| RuntimeError { message: e, pos: op.pos.clone() })
|
||||
}
|
|
@ -261,7 +261,11 @@ impl Parser {
|
|||
}
|
||||
|
||||
fn pipeline(&mut self) -> Result<Expr, ParserError> {
|
||||
self.expr(OpType::Pipeline, Self::comparison)
|
||||
self.expr(OpType::Pipeline, Self::boolean)
|
||||
}
|
||||
|
||||
fn boolean(&mut self) -> Result<Expr, ParserError> {
|
||||
self.expr(OpType::Boolean, Self::comparison)
|
||||
}
|
||||
|
||||
fn comparison(&mut self) -> Result<Expr, ParserError> {
|
||||
|
|
|
@ -58,6 +58,8 @@ impl TokenType {
|
|||
| Self::StarEqual | Self::SlashEqual | Self::DoubleSlashEqual
|
||||
| Self::CaretEqual | Self::PercentEqual => Some(OpType::Assignment),
|
||||
|
||||
Self::DoubleAmper | Self::DoublePipe => Some(OpType::Boolean),
|
||||
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +67,7 @@ impl TokenType {
|
|||
|
||||
#[derive(Clone,Copy,Debug,PartialEq)]
|
||||
pub enum OpType {
|
||||
Assignment, Comparison, Pipeline, Additive, Multiplicative, Exponential
|
||||
Assignment, Comparison, Pipeline, Additive, Multiplicative, Exponential, Boolean
|
||||
}
|
||||
|
||||
impl OpType {
|
||||
|
|
|
@ -151,7 +151,7 @@ impl Value {
|
|||
|
||||
pub fn assign_index(&self, idx: &Value, value: Value) -> Result<(), String> {
|
||||
match self {
|
||||
Self::String(s) => todo!("Can't mutate strings yet"),
|
||||
Self::String(_) => todo!("Can't mutate strings yet"),
|
||||
Self::List(l) => match idx {
|
||||
Value::Int(i) if *i >= 0 && (*i as usize) < l.borrow().len() => {
|
||||
l.borrow_mut()[*i as usize] = value;
|
||||
|
@ -314,7 +314,7 @@ impl_numeric_op!(Add, add, {
|
|||
Ok(s.into())
|
||||
}
|
||||
(List(a), List(b)) => {
|
||||
let mut a = (**a).clone();
|
||||
let a = (**a).clone();
|
||||
a.borrow_mut().append(&mut (**b).borrow().clone());
|
||||
Ok(a.into())
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue