Pattern-matching in reduced AST

This commit is contained in:
greg 2018-07-24 03:12:00 -07:00
parent 75bf4b5697
commit a2b1b0f953
2 changed files with 33 additions and 27 deletions

View File

@ -1,6 +1,6 @@
use std::rc::Rc; use std::rc::Rc;
use ast::{AST, Statement, Expression, Declaration, Discriminator, IfExpressionBody}; use ast::{AST, Statement, Expression, Declaration, Discriminator, IfExpressionBody, Pattern};
use symbol_table::{Symbol, SymbolSpec, SymbolTable}; use symbol_table::{Symbol, SymbolSpec, SymbolTable};
use builtin::{BinOp, PrefixOp}; use builtin::{BinOp, PrefixOp};
@ -45,6 +45,10 @@ pub enum Expr {
then_clause: Vec<Stmt>, then_clause: Vec<Stmt>,
else_clause: Vec<Stmt>, else_clause: Vec<Stmt>,
}, },
Match {
cond: Box<Expr>,
arms: Vec<(Pattern, Vec<Stmt>)>
},
UnimplementedSigilValue UnimplementedSigilValue
} }
@ -112,36 +116,38 @@ impl Expression {
args: arguments.iter().map(|arg| arg.reduce(symbol_table)).collect(), args: arguments.iter().map(|arg| arg.reduce(symbol_table)).collect(),
}, },
TupleLiteral(exprs) => Expr::Tuple(exprs.iter().map(|e| e.reduce(symbol_table)).collect()), TupleLiteral(exprs) => Expr::Tuple(exprs.iter().map(|e| e.reduce(symbol_table)).collect()),
IfExpression { discriminator, body } => { IfExpression { discriminator, body } => reduce_if_expression(discriminator, body, symbol_table),
let cond = Box::new(match **discriminator {
Discriminator::Simple(ref expr) => expr.reduce(symbol_table),
_ => panic!(),
});
match **body {
IfExpressionBody::SimpleConditional(ref then_clause, ref else_clause) => {
let then_clause = then_clause.iter().map(|expr| expr.reduce(symbol_table)).collect();
let else_clause = match else_clause {
None => vec![],
Some(stmts) => stmts.iter().map(|expr| expr.reduce(symbol_table)).collect(),
};
Expr::Conditional { cond, then_clause, else_clause }
},
IfExpressionBody::SimplePatternMatch(ref pat, ref then_clause, ref else_clause) => {
let then_clause = then_clause.iter().map(|expr| expr.reduce(symbol_table)).collect();
let else_clause = match else_clause {
None => vec![],
Some(stmts) => stmts.iter().map(|expr| expr.reduce(symbol_table)).collect(),
};
Expr::Conditional { cond, then_clause, else_clause }
},
_ => panic!(),
}
},
_ => Expr::UnimplementedSigilValue, _ => Expr::UnimplementedSigilValue,
} }
} }
} }
fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, symbol_table: &SymbolTable) -> Expr {
let cond = Box::new(match *discriminator {
Discriminator::Simple(ref expr) => expr.reduce(symbol_table),
_ => panic!(),
});
match *body {
IfExpressionBody::SimpleConditional(ref then_clause, ref else_clause) => {
let then_clause = then_clause.iter().map(|expr| expr.reduce(symbol_table)).collect();
let else_clause = match else_clause {
None => vec![],
Some(stmts) => stmts.iter().map(|expr| expr.reduce(symbol_table)).collect(),
};
Expr::Conditional { cond, then_clause, else_clause }
},
IfExpressionBody::SimplePatternMatch(ref pat, ref then_clause, ref else_clause) => {
let then_clause = then_clause.iter().map(|expr| expr.reduce(symbol_table)).collect();
let else_clause = match else_clause {
None => vec![],
Some(stmts) => stmts.iter().map(|expr| expr.reduce(symbol_table)).collect(),
};
Expr::Conditional { cond, then_clause, else_clause }
},
_ => panic!(),
}
}
impl Declaration { impl Declaration {
fn reduce(&self, symbol_table: &SymbolTable) -> Stmt { fn reduce(&self, symbol_table: &SymbolTable) -> Stmt {
use self::Declaration::*; use self::Declaration::*;