diff --git a/schala-lang/language/src/reduced_ir/mod.rs b/schala-lang/language/src/reduced_ir/mod.rs index c4af742..3a1223a 100644 --- a/schala-lang/language/src/reduced_ir/mod.rs +++ b/schala-lang/language/src/reduced_ir/mod.rs @@ -269,6 +269,12 @@ pub enum Expression { ReductionError(String), } +impl Expression { + pub fn unit() -> Self { + Expression::Tuple(vec![]) + } +} + #[derive(Debug)] pub struct FunctionDefinition { pub body: Vec diff --git a/schala-lang/language/src/tree_walk_eval/mod.rs b/schala-lang/language/src/tree_walk_eval/mod.rs index 455a741..785e0b3 100644 --- a/schala-lang/language/src/tree_walk_eval/mod.rs +++ b/schala-lang/language/src/tree_walk_eval/mod.rs @@ -241,8 +241,59 @@ impl<'a> State<'a> { } else { Nat(l / r).into() }, + (Modulo, Lit(Nat(l)), Lit(Nat(r))) => Nat(l % r).into(), + (Exponentiation, Lit(Nat(l)), Lit(Nat(r))) => Nat(l ^ r).into(), + (BitwiseAnd, Lit(Nat(l)), Lit(Nat(r))) => Nat(l & r).into(), + (BitwiseOr, Lit(Nat(l)), Lit(Nat(r))) => Nat(l | r).into(), + + /* comparisons */ + (Equality, Lit(Nat(l)), Lit(Nat(r))) => Bool(l == r).into(), + (Equality, Lit(Int(l)), Lit(Int(r))) => Bool(l == r).into(), + (Equality, Lit(Float(l)), Lit(Float(r))) => Bool(l == r).into(), + (Equality, Lit(Bool(l)), Lit(Bool(r))) => Bool(l == r).into(), + (Equality, Lit(StringLit(ref l)), Lit(StringLit(ref r))) => Bool(l == r).into(), + + (LessThan, Lit(Nat(l)), Lit(Nat(r))) => Bool(l < r).into(), + (LessThan, Lit(Int(l)), Lit(Int(r))) => Bool(l < r).into(), + (LessThan, Lit(Float(l)), Lit(Float(r))) => Bool(l < r).into(), + + (LessThanOrEqual, Lit(Nat(l)), Lit(Nat(r))) => Bool(l <= r).into(), + (LessThanOrEqual, Lit(Int(l)), Lit(Int(r))) => Bool(l <= r).into(), + (LessThanOrEqual, Lit(Float(l)), Lit(Float(r))) => Bool(l <= r).into(), + + (GreaterThan, Lit(Nat(l)), Lit(Nat(r))) => Bool(l > r).into(), + (GreaterThan, Lit(Int(l)), Lit(Int(r))) => Bool(l > r).into(), + (GreaterThan, Lit(Float(l)), Lit(Float(r))) => Bool(l > r).into(), + + (GreaterThanOrEqual, Lit(Nat(l)), Lit(Nat(r))) => Bool(l >= r).into(), + (GreaterThanOrEqual, Lit(Int(l)), Lit(Int(r))) => Bool(l >= r).into(), + (GreaterThanOrEqual, Lit(Float(l)), Lit(Float(r))) => Bool(l >= r).into(), + (binop, lhs, rhs) => return Err(format!("Invalid binop expression {:?} {:?} {:?}", lhs, binop, rhs)), }, + (prefix, &[ref arg]) => match (prefix, arg) { + (BooleanNot, Lit(Bool(true))) => Bool(false), + (BooleanNot, Lit(Bool(false))) => Bool(true), + (Negate, Lit(Nat(n))) => Int(-(*n as i64)), + (Negate, Lit(Int(n))) => Int(-(*n as i64)), + (Increment, Lit(Int(n))) => Int(*n), + (Increment, Lit(Nat(n))) => Nat(*n), + _ => return Err("No valid prefix op".to_string()) + }.into(), + /* builtin functions */ + (IOPrint, &[ref anything]) => { + print!("{}", expr_to_repl(anything)); + Primitive::Tuple(vec![]) + }, + (IOPrintLn, &[ref anything]) => { + println!("{}", expr_to_repl(anything)); + Primitive::Tuple(vec![]) + }, + (IOGetLine, &[]) => { + let mut buf = String::new(); + std::io::stdin().read_line(&mut buf).expect("Error readling line in 'getline'"); + StringLit(Rc::new(buf.trim().to_string())).into() + }, (x, args) => return Err(format!("bad or unimplemented builtin {:?} | {:?}", x, args)), }) }