From b8df09e956e5b216b6983ee3f0a2e8c6d757e1a0 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 29 Oct 2018 01:50:43 -0700 Subject: [PATCH] Change eval strategy to use conditional sigil --- schala-lang/language/src/eval.rs | 24 +++++++++++++++++++++--- schala-lang/language/src/reduced_ast.rs | 14 +++++++------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/schala-lang/language/src/eval.rs b/schala-lang/language/src/eval.rs index 66b3a7e..88ee439 100644 --- a/schala-lang/language/src/eval.rs +++ b/schala-lang/language/src/eval.rs @@ -116,6 +116,23 @@ impl Expr { _ => format!("{:?}", self), } } + + fn replace_conditional_target_sigil(self, replacement: &Expr) -> Expr { + use self::Expr::*; + + match self { + ConditionalTargetSigilValue => replacement.clone(), + Unit | Lit(_) | Func(_) | Val(_) | Constructor { .. } | + CaseMatch { .. } | UnimplementedSigilValue => self, + Tuple(exprs) => Tuple(exprs.into_iter().map(|e| e.replace_conditional_target_sigil(replacement)).collect()), + Call { f, args } => { + let new_args = args.into_iter().map(|e| e.replace_conditional_target_sigil(replacement)).collect(); + Call { f, args: new_args } + }, + Conditional { .. } => panic!("Dunno if I need this, but if so implement"), + Assign { .. } => panic!("I'm pretty sure I don't need this"), + } + } } impl<'a> State<'a> { @@ -194,7 +211,7 @@ impl<'a> State<'a> { Assign { box val, box expr } => self.assign_expression(val, expr), Unit => Ok(Node::Expr(Unit)), CaseMatch { box cond, alternatives } => self.case_match_expression(cond, alternatives), - ConditionalTargetPlaceholder => Err(format!("This value shouldn't exist here")), + ConditionalTargetSigilValue => Ok(Node::Expr(ConditionalTargetSigilValue)), UnimplementedSigilValue => Err(format!("Sigil value eval not implemented")), } } @@ -379,11 +396,12 @@ fn case_match_expression(&mut self, cond: Expr, alternatives: Vec) return Err(format!("PrimObject failed pattern match")); }, Node::PrimTuple { .. } => Err(format!("Tuples not implemented")), //TODO make a distinction between not yet implemented and an actual runtime error - Node::Expr(_e) => { + Node::Expr(e) => { for alt in alternatives { match (alt.guard, alt.tag) { (Some(ref guard_expr), None) => { - match self.expression(guard_expr.clone().to_node())? { + let guard_expr = guard_expr.clone().replace_conditional_target_sigil(&e); + match self.expression(guard_expr.to_node())? { Node::Expr(Expr::Lit(::reduced_ast::Lit::Bool(true))) => return self.block(alt.item), _ => continue, diff --git a/schala-lang/language/src/reduced_ast.rs b/schala-lang/language/src/reduced_ast.rs index d37a592..8c404ba 100644 --- a/schala-lang/language/src/reduced_ast.rs +++ b/schala-lang/language/src/reduced_ast.rs @@ -48,7 +48,7 @@ pub enum Expr { then_clause: Vec, else_clause: Vec, }, - ConditionalTargetPlaceholder, + ConditionalTargetSigilValue, CaseMatch { cond: Box, alternatives: Vec @@ -163,7 +163,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, }; let alternatives = vec![ - pat.to_alternative(&cond, then_clause, symbol_table), + pat.to_alternative(then_clause, symbol_table), Alternative::default(else_clause), ]; @@ -178,7 +178,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, match arm.guard { Guard::Pat(ref p) => { let item = arm.body.iter().map(|expr| expr.reduce(symbol_table)).collect(); - let alt = p.to_alternative(&cond, item, symbol_table); + let alt = p.to_alternative(item, symbol_table); alternatives.push(alt); }, Guard::HalfExpr(HalfExpr { op: _, expr: _ }) => { @@ -196,7 +196,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, impl Pattern { - fn to_alternative(&self, cond: &Box, item: Vec, symbol_table: &SymbolTable) -> Alternative { + fn to_alternative(&self, item: Vec, symbol_table: &SymbolTable) -> Alternative { use self::Pattern::*; fn handle_symbol(symbol: &Symbol, subpatterns: &Vec, item: Vec) -> Alternative { @@ -253,7 +253,7 @@ impl Pattern { }); let guard = Some(Expr::Call { f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("==".to_string())))), - args: vec![comparison, *cond.clone()] + args: vec![comparison, Expr::ConditionalTargetSigilValue], }); Alternative { tag: None, @@ -266,11 +266,11 @@ impl Pattern { PatternLiteral::StringPattern(_s) => unimplemented!(), PatternLiteral::BoolPattern(b) => { let guard = Some(if *b { - *cond.clone() + Expr::ConditionalTargetSigilValue } else { Expr::Call { f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("!".to_string())))), - args: vec![*cond.clone()] + args: vec![Expr::ConditionalTargetSigilValue] } }); Alternative {