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

@ -152,6 +152,8 @@ pub fn eval_expr(expr: &Expr, env: EnvRef) -> Result<Value, RuntimeError> {
=> eval_assignment(lhs, rhs, op, env), => eval_assignment(lhs, rhs, op, env),
Some(OpType::Additive) | Some(OpType::Multiplicative) Some(OpType::Additive) | Some(OpType::Multiplicative)
=> eval_binary(lhs, rhs, op, env), => eval_binary(lhs, rhs, op, env),
Some(OpType::Boolean)
=> eval_boolean(lhs, rhs, op, env),
Some(OpType::Comparison) Some(OpType::Comparison)
=> eval_comp(lhs, rhs, op, env), => eval_comp(lhs, rhs, op, env),
o => todo!("{:?}", o) // TODO other operations 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)?; let idx = eval_expr(index, env)?;
l.index(&idx).map_err(|e| RuntimeError { message: e, pos: pos.clone() }) 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() }) }.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> { 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 l = eval_expr(lhs, env.clone())?;
let r = eval_expr(rhs, env)?; 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)?; let a = eval_expr(arg, env)?;
match op.ty { match op.ty {
TokenType::Minus => -a, TokenType::Minus => -a,
TokenType::Bang => Ok(Value::Bool(!a.truthy())),
_ => todo!(), _ => todo!(),
}.map_err(|e| RuntimeError { message: e, pos: op.pos.clone() }) }.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> { 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> { fn comparison(&mut self) -> Result<Expr, ParserError> {

View file

@ -58,6 +58,8 @@ impl TokenType {
| Self::StarEqual | Self::SlashEqual | Self::DoubleSlashEqual | Self::StarEqual | Self::SlashEqual | Self::DoubleSlashEqual
| Self::CaretEqual | Self::PercentEqual => Some(OpType::Assignment), | Self::CaretEqual | Self::PercentEqual => Some(OpType::Assignment),
Self::DoubleAmper | Self::DoublePipe => Some(OpType::Boolean),
_ => None _ => None
} }
} }
@ -65,7 +67,7 @@ impl TokenType {
#[derive(Clone,Copy,Debug,PartialEq)] #[derive(Clone,Copy,Debug,PartialEq)]
pub enum OpType { pub enum OpType {
Assignment, Comparison, Pipeline, Additive, Multiplicative, Exponential Assignment, Comparison, Pipeline, Additive, Multiplicative, Exponential, Boolean
} }
impl OpType { impl OpType {

View file

@ -151,7 +151,7 @@ impl Value {
pub fn assign_index(&self, idx: &Value, value: Value) -> Result<(), String> { pub fn assign_index(&self, idx: &Value, value: Value) -> Result<(), String> {
match self { match self {
Self::String(s) => todo!("Can't mutate strings yet"), Self::String(_) => todo!("Can't mutate strings yet"),
Self::List(l) => match idx { Self::List(l) => match idx {
Value::Int(i) if *i >= 0 && (*i as usize) < l.borrow().len() => { Value::Int(i) if *i >= 0 && (*i as usize) < l.borrow().len() => {
l.borrow_mut()[*i as usize] = value; l.borrow_mut()[*i as usize] = value;
@ -314,7 +314,7 @@ impl_numeric_op!(Add, add, {
Ok(s.into()) Ok(s.into())
} }
(List(a), List(b)) => { (List(a), List(b)) => {
let mut a = (**a).clone(); let a = (**a).clone();
a.borrow_mut().append(&mut (**b).borrow().clone()); a.borrow_mut().append(&mut (**b).borrow().clone());
Ok(a.into()) Ok(a.into())
}, },