Start handling numeric patterns
Still need to add eval support for this
This commit is contained in:
parent
fc7c86be1a
commit
8619c94217
@ -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(),
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user