boolean operators

This commit is contained in:
TriMill 2022-09-11 01:14:54 -04:00
parent 652106135c
commit 4ef3fdb46d
4 changed files with 31 additions and 6 deletions

View File

@ -150,8 +150,10 @@ pub fn eval_expr(expr: &Expr, env: EnvRef) -> Result<Value, RuntimeError> {
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<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() })
}

View File

@ -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> {

View File

@ -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 {

View File

@ -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())
},