Handle function definition before use
And some other ReducedAST - Evaluation niceties
This commit is contained in:
parent
6d93c758a2
commit
8d6fea942f
@ -8,12 +8,17 @@ pub struct ReducedAST(pub Vec<Stmt>);
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Stmt {
|
pub enum Stmt {
|
||||||
|
PreBinding {
|
||||||
|
name: Rc<String>,
|
||||||
|
func: Func,
|
||||||
|
},
|
||||||
Binding {
|
Binding {
|
||||||
name: Rc<String>,
|
name: Rc<String>,
|
||||||
constant: bool,
|
constant: bool,
|
||||||
expr: Expr,
|
expr: Expr,
|
||||||
},
|
},
|
||||||
Expr(Expr),
|
Expr(Expr),
|
||||||
|
Noop,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -111,17 +116,18 @@ impl Expression {
|
|||||||
impl Declaration {
|
impl Declaration {
|
||||||
fn reduce(&self) -> Stmt {
|
fn reduce(&self) -> Stmt {
|
||||||
use self::Declaration::*;
|
use self::Declaration::*;
|
||||||
|
use ::parsing::Signature;
|
||||||
match self {
|
match self {
|
||||||
Binding {name, constant, expr } => Stmt::Binding { name: name.clone(), constant: *constant, expr: expr.reduce() },
|
Binding {name, constant, expr } => Stmt::Binding { name: name.clone(), constant: *constant, expr: expr.reduce() },
|
||||||
FuncDecl(::parsing::Signature { name, params, .. }, statements) => Stmt::Binding {
|
FuncDecl(Signature { name, params, .. }, statements) => Stmt::PreBinding {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
constant: true,
|
func: Func::UserDefined {
|
||||||
expr: Expr::Func(Func::UserDefined {
|
name: Some(name.clone()),
|
||||||
name: None,
|
|
||||||
params: params.iter().map(|param| param.0.clone()).collect(),
|
params: params.iter().map(|param| param.0.clone()).collect(),
|
||||||
body: statements.iter().map(|stmt| stmt.reduce()).collect(),
|
body: statements.iter().map(|stmt| stmt.reduce()).collect(),
|
||||||
})
|
}
|
||||||
},
|
},
|
||||||
|
TypeDecl(_,_) => Stmt::Noop,
|
||||||
_ => Stmt::Expr(Expr::UnimplementedSigilValue)
|
_ => Stmt::Expr(Expr::UnimplementedSigilValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,6 +318,12 @@ impl Expr {
|
|||||||
impl<'a> State<'a> {
|
impl<'a> State<'a> {
|
||||||
pub fn evaluate(&mut self, ast: ReducedAST, repl: bool) -> Vec<Result<String, String>> {
|
pub fn evaluate(&mut self, ast: ReducedAST, repl: bool) -> Vec<Result<String, String>> {
|
||||||
let mut acc = vec![];
|
let mut acc = vec![];
|
||||||
|
|
||||||
|
// handle prebindings
|
||||||
|
for statement in ast.0.iter() {
|
||||||
|
self.prebinding(statement);
|
||||||
|
}
|
||||||
|
|
||||||
for statement in ast.0 {
|
for statement in ast.0 {
|
||||||
match self.statement(statement) {
|
match self.statement(statement) {
|
||||||
Ok(Some(ref output)) if repl => acc.push(Ok(output.to_repl())),
|
Ok(Some(ref output)) if repl => acc.push(Ok(output.to_repl())),
|
||||||
@ -331,6 +337,20 @@ impl<'a> State<'a> {
|
|||||||
acc
|
acc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn prebinding(&mut self, stmt: &Stmt) {
|
||||||
|
match stmt {
|
||||||
|
Stmt::PreBinding { name, func } => {
|
||||||
|
let v_entry = ValueEntry::Binding { constant: true, val: Expr::Func(func.clone()) };
|
||||||
|
self.values.insert(name.clone(), v_entry);
|
||||||
|
},
|
||||||
|
Stmt::Expr(_expr) => {
|
||||||
|
//TODO have this support things like nested function defs
|
||||||
|
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn statement(&mut self, stmt: Stmt) -> EvalResult<Option<Expr>> {
|
fn statement(&mut self, stmt: Stmt) -> EvalResult<Option<Expr>> {
|
||||||
match stmt {
|
match stmt {
|
||||||
Stmt::Binding { name, constant, expr } => {
|
Stmt::Binding { name, constant, expr } => {
|
||||||
@ -339,6 +359,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
},
|
},
|
||||||
Stmt::Expr(expr) => Ok(Some(self.expression(expr)?)),
|
Stmt::Expr(expr) => Ok(Some(self.expression(expr)?)),
|
||||||
|
Stmt::PreBinding {..} | Stmt::Noop => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,6 +492,8 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
fn value(&mut self, name: Rc<String>) -> EvalResult<Expr> {
|
fn value(&mut self, name: Rc<String>) -> EvalResult<Expr> {
|
||||||
use self::ValueEntry::*;
|
use self::ValueEntry::*;
|
||||||
|
//TODO add a layer of indirection here to talk to the symbol table first, and only then look up
|
||||||
|
//in the values table
|
||||||
match self.values.lookup(&name) {
|
match self.values.lookup(&name) {
|
||||||
None => return Err(format!("Value {} not found", *name)),
|
None => return Err(format!("Value {} not found", *name)),
|
||||||
Some(lookup) => match lookup {
|
Some(lookup) => match lookup {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
println(a(4))
|
println(sua(4))
|
||||||
|
|
||||||
fn sua(x): Int {
|
fn sua(x): Int {
|
||||||
x + 10
|
x + 10
|
||||||
|
Loading…
Reference in New Issue
Block a user