Pattern-matching in reduced AST
This commit is contained in:
parent
75bf4b5697
commit
a2b1b0f953
@ -3,7 +3,7 @@
|
||||
|
||||
Schala is a Rust framework written to make it easy to
|
||||
create and experiment with toy programming languages. It provides
|
||||
a common REPL, and a trait `ProgrammingLanguage` with provisions
|
||||
a common REPL, and a trait `ProgrammingLanguage` with provisions
|
||||
for tokenizing text, parsing tokens, evaluating an abstract syntax tree,
|
||||
and other tasks that are common to all programming languages.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
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 builtin::{BinOp, PrefixOp};
|
||||
|
||||
@ -45,6 +45,10 @@ pub enum Expr {
|
||||
then_clause: Vec<Stmt>,
|
||||
else_clause: Vec<Stmt>,
|
||||
},
|
||||
Match {
|
||||
cond: Box<Expr>,
|
||||
arms: Vec<(Pattern, Vec<Stmt>)>
|
||||
},
|
||||
UnimplementedSigilValue
|
||||
}
|
||||
|
||||
@ -112,36 +116,38 @@ impl Expression {
|
||||
args: arguments.iter().map(|arg| arg.reduce(symbol_table)).collect(),
|
||||
},
|
||||
TupleLiteral(exprs) => Expr::Tuple(exprs.iter().map(|e| e.reduce(symbol_table)).collect()),
|
||||
IfExpression { discriminator, body } => {
|
||||
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!(),
|
||||
}
|
||||
},
|
||||
IfExpression { discriminator, body } => reduce_if_expression(discriminator, body, symbol_table),
|
||||
_ => 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 {
|
||||
fn reduce(&self, symbol_table: &SymbolTable) -> Stmt {
|
||||
use self::Declaration::*;
|
||||
|
Loading…
Reference in New Issue
Block a user