Start handling numeric patterns

Still need to add eval support for this
This commit is contained in:
greg 2018-10-16 01:38:41 -07:00
parent fc7c86be1a
commit 8619c94217
2 changed files with 25 additions and 9 deletions

View File

@ -216,7 +216,7 @@ impl<'a> State<'a> {
CaseMatch { box cond, alternatives } => match self.expression(Node::Expr(cond))? { CaseMatch { box cond, alternatives } => match self.expression(Node::Expr(cond))? {
Node::PrimObject { name, tag, items } => { Node::PrimObject { name, tag, items } => {
for alt in alternatives { for alt in alternatives {
if alt.tag.map(|t| t == tag).unwrap_or(true) { if alt.tag.map(|t| t == tag).unwrap_or(true) { //TODO add guard check - the semantics
let mut inner_state = State { let mut inner_state = State {
values: self.values.new_scope(None), values: self.values.new_scope(None),
symbol_table_handle: self.symbol_table_handle.clone(), symbol_table_handle: self.symbol_table_handle.clone(),

View File

@ -1,6 +1,6 @@
use std::rc::Rc; use std::rc::Rc;
use ast::{AST, Statement, Expression, Declaration, Discriminator, IfExpressionBody, Pattern, PatternLiteral, Guard, HalfExpr}; use ast::{AST, Statement, Expression, ExpressionType, Declaration, Discriminator, IfExpressionBody, Pattern, PatternLiteral, Guard, HalfExpr};
use symbol_table::{Symbol, SymbolSpec, SymbolTable}; use symbol_table::{Symbol, SymbolSpec, SymbolTable};
use builtin::{BinOp, PrefixOp}; use builtin::{BinOp, PrefixOp};
@ -136,9 +136,7 @@ impl Expression {
fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, symbol_table: &SymbolTable) -> Expr { fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, symbol_table: &SymbolTable) -> Expr {
let cond = Box::new(match *discriminator { let cond = Box::new(match *discriminator {
Discriminator::Simple(ref expr) => expr.reduce(symbol_table), Discriminator::Simple(ref expr) => expr.reduce(symbol_table),
Discriminator::BinOp(ref expr, ref binop) => { Discriminator::BinOp(ref expr, ref binop) => panic!("Can't yet handle binop discriminators")
panic!()
}
}); });
match *body { match *body {
IfExpressionBody::SimpleConditional(ref then_clause, ref else_clause) => { IfExpressionBody::SimpleConditional(ref then_clause, ref else_clause) => {
@ -157,7 +155,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
}; };
let alternatives = vec![ let alternatives = vec![
pat.to_alternative(then_clause, symbol_table), pat.to_alternative(&cond, then_clause, symbol_table),
Alternative { Alternative {
tag: None, tag: None,
guard: None, guard: None,
@ -175,7 +173,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
let alternatives = guard_arms.iter().map(|arm| match arm.guard { let alternatives = guard_arms.iter().map(|arm| match arm.guard {
Guard::Pat(ref p) => { Guard::Pat(ref p) => {
let item = arm.body.iter().map(|expr| expr.reduce(symbol_table)).collect(); let item = arm.body.iter().map(|expr| expr.reduce(symbol_table)).collect();
p.to_alternative(item, symbol_table) p.to_alternative(&cond, item, symbol_table)
}, },
Guard::HalfExpr(HalfExpr { op: _, expr: _ }) => { Guard::HalfExpr(HalfExpr { op: _, expr: _ }) => {
unimplemented!() unimplemented!()
@ -187,7 +185,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
} }
impl Pattern { impl Pattern {
fn to_alternative(&self, item: Vec<Stmt>, symbol_table: &SymbolTable) -> Alternative { fn to_alternative(&self, cond: &Box<Expr>, item: Vec<Stmt>, symbol_table: &SymbolTable) -> Alternative {
use self::Pattern::*; use self::Pattern::*;
fn handle_symbol(symbol: &Symbol, subpatterns: &Vec<Pattern>, item: Vec<Stmt>) -> Alternative { fn handle_symbol(symbol: &Symbol, subpatterns: &Vec<Pattern>, item: Vec<Stmt>) -> Alternative {
@ -221,7 +219,25 @@ impl Pattern {
}, },
Ignored => unimplemented!(), Ignored => unimplemented!(),
Literal(lit) => match lit { Literal(lit) => match lit {
PatternLiteral::NumPattern { neg, num } => unimplemented!(), PatternLiteral::NumPattern { neg, num } => {
let comparison = Expr::Lit(match (neg, num) {
(false, ExpressionType::NatLiteral(n)) => Lit::Nat(*n),
(false, ExpressionType::FloatLiteral(f)) => Lit::Float(*f),
(true, ExpressionType::NatLiteral(n)) => Lit::Int(-1*(*n as i64)),
(true, ExpressionType::FloatLiteral(f)) => Lit::Float(-1.0*f),
_ => panic!("This should never happen")
});
let guard = Some(Expr::Call {
f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("=".to_string())))),
args: vec![comparison, *cond.clone()]
});
Alternative {
tag: None,
guard,
bound_vars: vec![],
item
}
},
PatternLiteral::StringPattern(_s) => unimplemented!(), PatternLiteral::StringPattern(_s) => unimplemented!(),
PatternLiteral::BoolPattern(_b) => unimplemented!(), PatternLiteral::BoolPattern(_b) => unimplemented!(),
PatternLiteral::VarPattern(var) => match symbol_table.lookup_by_name(var) { PatternLiteral::VarPattern(var) => match symbol_table.lookup_by_name(var) {