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
|
Schala is a Rust framework written to make it easy to
|
||||||
create and experiment with toy programming languages. It provides
|
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,
|
for tokenizing text, parsing tokens, evaluating an abstract syntax tree,
|
||||||
and other tasks that are common to all programming languages.
|
and other tasks that are common to all programming languages.
|
||||||
|
|
||||||
|
@ -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::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user