From f2282f01010e089c528388b0a5f1682a8fee17ea Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 18 Oct 2018 01:49:42 -0700 Subject: [PATCH] case_match_expression split out into its own method --- schala-lang/language/src/eval.rs | 93 +++++++++++++++++--------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/schala-lang/language/src/eval.rs b/schala-lang/language/src/eval.rs index a4983ac..d3256f6 100644 --- a/schala-lang/language/src/eval.rs +++ b/schala-lang/language/src/eval.rs @@ -7,7 +7,7 @@ use std::io; use itertools::Itertools; use util::ScopeStack; -use reduced_ast::{ReducedAST, Stmt, Expr, Lit, Func}; +use reduced_ast::{ReducedAST, Stmt, Expr, Lit, Func, Alternative}; use symbol_table::{SymbolSpec, Symbol, SymbolTable}; pub struct State<'a> { @@ -193,49 +193,7 @@ impl<'a> State<'a> { Conditional { box cond, then_clause, else_clause } => self.conditional(cond, then_clause, else_clause), Assign { box val, box expr } => self.assign_expression(val, expr), Unit => Ok(Node::Expr(Unit)), - CaseMatch { box cond, alternatives } => match self.expression(Node::Expr(cond))? { - Node::PrimObject { name, tag, items } => { - for alt in alternatives { - if alt.tag.map(|t| t == tag).unwrap_or(true) { - let mut inner_state = State { - values: self.values.new_scope(None), - symbol_table_handle: self.symbol_table_handle.clone(), - }; - for (bound_var, val) in alt.bound_vars.iter().zip(items.iter()) { - if let Some(bv) = bound_var.as_ref() { - inner_state.values.insert(bv.clone(), ValueEntry::Binding { constant: true, val: val.clone() }); - } - } - - if let Some(guard_expr) = alt.guard { - let evaled_guard = inner_state.expression(guard_expr.to_node()); - println!("EVALED GUARD: {:?}", evaled_guard); - //continue - } - - return inner_state.block(alt.item) - } - } - 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) => { - for alt in alternatives { - match (alt.guard, alt.tag) { - (Some(ref guard_expr), None) => { - match self.expression(guard_expr.clone().to_node())? { - Node::Expr(Expr::Lit(::reduced_ast::Lit::Bool(true))) => - return self.block(alt.item), - _ => continue, - } - }, - (None, None) => return self.block(alt.item), - _ => return Err(format!("Shouldn't match an expr against a pattern")) - } - } - return Err(format!("Expr Failed pattern match")); - } - }, + CaseMatch { box cond, alternatives } => self.case_match_expression(cond, alternatives), UnimplementedSigilValue => Err(format!("Sigil value eval not implemented")) } } @@ -393,6 +351,53 @@ impl<'a> State<'a> { Ok(Node::Expr(Expr::Unit)) } +fn case_match_expression(&mut self, cond: Expr, alternatives: Vec) -> EvalResult { + match self.expression(Node::Expr(cond))? { + Node::PrimObject { name, tag, items } => { + for alt in alternatives { + if alt.tag.map(|t| t == tag).unwrap_or(true) { + let mut inner_state = State { + values: self.values.new_scope(None), + symbol_table_handle: self.symbol_table_handle.clone(), + }; + for (bound_var, val) in alt.bound_vars.iter().zip(items.iter()) { + if let Some(bv) = bound_var.as_ref() { + inner_state.values.insert(bv.clone(), ValueEntry::Binding { constant: true, val: val.clone() }); + } + } + + if let Some(guard_expr) = alt.guard { + let evaled_guard = inner_state.expression(guard_expr.to_node()); + println!("EVALED GUARD: {:?}", evaled_guard); + //continue + } + + return inner_state.block(alt.item) + } + } + 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) => { + for alt in alternatives { + match (alt.guard, alt.tag) { + (Some(ref guard_expr), None) => { + match self.expression(guard_expr.clone().to_node())? { + Node::Expr(Expr::Lit(::reduced_ast::Lit::Bool(true))) => + return self.block(alt.item), + _ => continue, + } + }, + (None, None) => return self.block(alt.item), + _ => return Err(format!("Shouldn't match an expr against a pattern")) + } + } + return Err(format!("Expr Failed pattern match")); + } + + } +} + fn value(&mut self, name: Rc) -> EvalResult { use self::ValueEntry::*; use self::Func::*;