From a01b6c874e9431524d7c3ccf3d0a8b09c02ef43b Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 23 Dec 2016 17:15:23 -0800 Subject: [PATCH] Small-step function arg evaluation --- Cargo.toml | 1 + src/eval.rs | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c1ad0f2..2249978 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ authors = ["greg "] simplerepl = { path = "../simplerepl" } llvm-sys = "*" +take_mut = "0.1.3" diff --git a/src/eval.rs b/src/eval.rs index 990a70d..fd72815 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -1,3 +1,5 @@ +extern crate take_mut; + use std::collections::HashMap; use parser::{AST, ASTNode, Expression, Function}; @@ -189,11 +191,22 @@ impl Evaluator { (self.reduce_binop(op, left, right), None) //can assume both arguments are maximally reduced } }, - Call(name, args) => { - let reduced_args: Vec = args.into_iter().map(|arg| { - self.reduce_expr(arg).0 - }).collect(); - self.reduce_call(name, reduced_args) + Call(name, mut args) => { + let mut f = true; + for arg in args.iter_mut() { + if arg.is_reducible() { + take_mut::take(arg, |arg| { + self.reduce_expr(arg).0 + }); + f = false; + break; + } + } + if f { + self.reduce_call(name, args) + } else { + (Call(name, args), None) + } }, Conditional(_,_,_) => unimplemented!(), }