From d229a578371231bb269126699e49d56e6e898237 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 23 Feb 2018 19:06:37 -0800 Subject: [PATCH] Finished initial BinOp/PrefixOp --- src/schala_lang/builtin.rs | 40 +++++++++++++++++++++++++++++++++ src/schala_lang/eval.rs | 16 +++++++------ src/schala_lang/typechecking.rs | 3 ++- 3 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 src/schala_lang/builtin.rs diff --git a/src/schala_lang/builtin.rs b/src/schala_lang/builtin.rs new file mode 100644 index 0000000..c9288f3 --- /dev/null +++ b/src/schala_lang/builtin.rs @@ -0,0 +1,40 @@ +use std::rc::Rc; + +#[derive(Debug, PartialEq, Clone)] +pub struct BinOp { + pub sigil: Rc +} + +#[derive(Debug, PartialEq, Clone)] +pub struct PrefixOp { + pub sigil: Rc +} + +impl BinOp { + pub fn from_sigil(sigil: Rc) -> BinOp { + BinOp { sigil } + } + pub fn min_precedence() -> i32 { + i32::min_value() + } + + pub fn get_precedence(op: &str) -> i32 { + match op { + "+" | "-" => 10, + "*" | "/" | "%" => 20, + _ => 30, + } + } +} + +impl PrefixOp { + pub fn from_sigil(sigil: Rc) -> PrefixOp { + PrefixOp { sigil } + } + pub fn is_prefix(op: &str) -> bool { + match op { + "+" | "-" | "!" | "~" => true, + _ => false, + } + } +} diff --git a/src/schala_lang/eval.rs b/src/schala_lang/eval.rs index 39b23aa..424fd96 100644 --- a/src/schala_lang/eval.rs +++ b/src/schala_lang/eval.rs @@ -1,4 +1,5 @@ -use schala_lang::parsing::{AST, Statement, Declaration, Expression, Variant, ExpressionType, Operation}; +use schala_lang::parsing::{AST, Statement, Declaration, Expression, Variant, ExpressionType}; +use schala_lang::builtin::{BinOp, PrefixOp}; use std::collections::HashMap; use std::rc::Rc; @@ -162,12 +163,12 @@ impl State { } } - fn eval_binexp(&mut self, op: Operation, lhs: Box, rhs: Box) -> EvalResult { + fn eval_binexp(&mut self, op: BinOp, lhs: Box, rhs: Box) -> EvalResult { use self::FullyEvaluatedExpr::*; let evaled_lhs = self.eval_expr(*lhs)?; let evaled_rhs = self.eval_expr(*rhs)?; - let opstr: &str = &op.0; - Ok(match (opstr, evaled_lhs, evaled_rhs) { + let sigil: &str = op.sigil.as_ref().as_str(); + Ok(match (sigil, evaled_lhs, evaled_rhs) { ("+", UnsignedInt(l), UnsignedInt(r)) => UnsignedInt(l + r), ("++", Str(s1), Str(s2)) => Str(format!("{}{}", s1, s2)), ("-", UnsignedInt(l), UnsignedInt(r)) => UnsignedInt(l - r), @@ -178,12 +179,13 @@ impl State { }) } - fn eval_prefix_exp(&mut self, op: Operation, expr: Box) -> EvalResult { + fn eval_prefix_exp(&mut self, op: PrefixOp, expr: Box) -> EvalResult { use self::FullyEvaluatedExpr::*; let evaled_expr = self.eval_expr(*expr)?; - let opstr: &str = &op.0; - Ok(match (opstr, evaled_expr) { + let sigil: &str = op.sigil.as_ref().as_str(); + + Ok(match (sigil, evaled_expr) { ("!", Bool(true)) => Bool(false), ("!", Bool(false)) => Bool(true), ("-", UnsignedInt(n)) => SignedInt(-1*(n as i64)), diff --git a/src/schala_lang/typechecking.rs b/src/schala_lang/typechecking.rs index dab25d9..a160052 100644 --- a/src/schala_lang/typechecking.rs +++ b/src/schala_lang/typechecking.rs @@ -2,6 +2,7 @@ use std::rc::Rc; use std::collections::HashMap; use schala_lang::parsing; +use schala_lang::builtin; pub struct TypeContext { bindings: HashMap, Type> @@ -129,7 +130,7 @@ impl TypeContext { _ => Err(format!("Type not yet implemented")) } } - fn infer_optype(&mut self, _op: &parsing::Operation) -> TypeResult { + fn infer_optype(&mut self, _op: &builtin::BinOp) -> TypeResult { use self::Type::*; use self::TConst::*; //this is a shim; not all ops are binops from int -> int -> int Ok(Func(bx!(Const(Int)), bx!(Func(bx!(Const(Int)), bx!(Const(Int))))))