diff --git a/src/eval.rs b/src/eval.rs index 9748344..c9d1376 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -150,8 +150,10 @@ pub fn eval_expr(expr: &Expr, env: EnvRef) -> Result { Expr::Binary { lhs, rhs, op } => match op.ty.get_op_type() { Some(OpType::Assignment) => eval_assignment(lhs, rhs, op, env), - Some(OpType::Additive) | Some(OpType::Multiplicative) + 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 { 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, rhs: &Box, op: &Token, env: EnvRef) -> }.map_err(|e| RuntimeError { message: e, pos: op.pos.clone() }) } +pub fn eval_boolean(lhs: &Box, rhs: &Box, op: &Token, env: EnvRef) -> Result { + 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, rhs: &Box, op: &Token, env: EnvRef) -> Result { let l = eval_expr(lhs, env.clone())?; let r = eval_expr(rhs, env)?; @@ -308,6 +326,7 @@ pub fn eval_unary(arg: &Box, op: &Token, env: EnvRef) -> Result -a, + TokenType::Bang => Ok(Value::Bool(!a.truthy())), _ => todo!(), }.map_err(|e| RuntimeError { message: e, pos: op.pos.clone() }) } \ No newline at end of file diff --git a/src/parser.rs b/src/parser.rs index 83317b1..7ee246f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -261,7 +261,11 @@ impl Parser { } fn pipeline(&mut self) -> Result { - self.expr(OpType::Pipeline, Self::comparison) + self.expr(OpType::Pipeline, Self::boolean) + } + + fn boolean(&mut self) -> Result { + self.expr(OpType::Boolean, Self::comparison) } fn comparison(&mut self) -> Result { diff --git a/src/token.rs b/src/token.rs index 06414e4..86c4783 100644 --- a/src/token.rs +++ b/src/token.rs @@ -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 { diff --git a/src/value.rs b/src/value.rs index 9a4a314..0186294 100644 --- a/src/value.rs +++ b/src/value.rs @@ -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()) },