From a60b735fe4c9b157e16205015f7173e9feb5080d Mon Sep 17 00:00:00 2001 From: bnewbold Date: Wed, 20 Apr 2016 18:01:13 -0400 Subject: rust: implement lambda_action --- minimal.rs | 56 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/minimal.rs b/minimal.rs index 55c67dc..58e7273 100644 --- a/minimal.rs +++ b/minimal.rs @@ -206,7 +206,7 @@ fn scheme_repr<'a>(ast: &SchemeExpr) -> Result { //////////// Expression Evaluation fn quote_action<'a>(list: &'a Vec, ctx: HashMap<&str, SchemeExpr<'a>>) -> Result, &'static str> { - // XXX: why can't I '.map()' here? + // XXX: why can't I '.map()' here? (try .iter().skip(1)...) let mut body = Vec::::new(); for el in list[1..].to_vec() { body.push(el.clone()); @@ -214,7 +214,7 @@ fn quote_action<'a>(list: &'a Vec, ctx: HashMap<&str, SchemeExpr<'a> Ok(SchemeExpr::SchemeList(body)) } -fn cond_action<'a>(list: &'a Vec, ctx: HashMap<&str, SchemeExpr<'a>>) -> Result, &'static str> { +fn cond_action<'a>(list: &'a Vec, ctx: HashMap<&'a str, SchemeExpr<'a>>) -> Result, &'static str> { for line in list.iter().skip(1) { match line { &SchemeExpr::SchemeList(ref inner) => { @@ -235,11 +235,31 @@ fn cond_action<'a>(list: &'a Vec, ctx: HashMap<&str, SchemeExpr<'a>> Ok(SchemeExpr::SchemeNull) } -fn lambda_action<'a>(list: &'a Vec, ctx: HashMap<&str, SchemeExpr<'a>>) -> Result, &'static str> { - Ok(SchemeExpr::SchemeQuote(list[1..].to_vec())) +fn lambda_action<'a>(list: &'a Vec, ctx: HashMap<&'a str, SchemeExpr<'a>>) -> Result, &'static str> { + if list.len() < 3 { + return Err("lambda must have a bind and at least one body expr"); + } + let mut binds = Vec::::new(); + let bind_list = match &list[1] { + &SchemeExpr::SchemeList(ref bl) => bl, + _ => { return Err("second arg to lambda must be a list of binds") }, + }; + for bind in bind_list { + match bind { + &SchemeExpr::SchemeSymbol(_) => + binds.push(bind.clone()), + _ => return Err("lambda binds must all be non-builtin symbols") + } + } + let mut body = list.iter().skip(2).map(|x| x.clone()).collect(); + Ok(SchemeExpr::SchemeProcedure(binds, body, ctx.clone())) +} + +fn apply_action<'a>(list: &'a Vec, ctx: HashMap<&'a str, SchemeExpr<'a>>) -> Result, &'static str> { + Ok(SchemeExpr::SchemeNull) } -fn scheme_meaning<'a>(ast: &'a SchemeExpr, ctx: HashMap<&str, SchemeExpr<'a>>) -> Result, &'static str> { +fn scheme_meaning<'a>(ast: &'a SchemeExpr, ctx: HashMap<&'a str, SchemeExpr<'a>>) -> Result, &'static str> { return match ast { // "identity actions" &SchemeExpr::SchemeTrue => Ok(ast.clone()), @@ -257,18 +277,20 @@ fn scheme_meaning<'a>(ast: &'a SchemeExpr, ctx: HashMap<&str, SchemeExpr<'a>>) - None => Err("symbol not defined"), }, &SchemeExpr::SchemeList(ref list) => { - if list.len() >= 2 { - match list[0] { - SchemeExpr::SchemeBuiltin("quote") => - quote_action(list, ctx), - SchemeExpr::SchemeBuiltin("cond") => - cond_action(list, ctx), - SchemeExpr::SchemeBuiltin("lambda") => - lambda_action(list, ctx), - _ => Ok(SchemeExpr::SchemeNull) - } - } else { - Err("weird short expression") + match list[0] { + SchemeExpr::SchemeBuiltin("quote") => + quote_action(list, ctx), + SchemeExpr::SchemeBuiltin("cond") => + cond_action(list, ctx), + SchemeExpr::SchemeBuiltin("lambda") => + lambda_action(list, ctx), + SchemeExpr::SchemeBuiltin(_) => + apply_action(list, ctx), + SchemeExpr::SchemeProcedure(_, _, _) => + apply_action(list, ctx), + SchemeExpr::SchemeList(_) => + apply_action(list, ctx), + _ => Ok(SchemeExpr::SchemeNull) }}, } } -- cgit v1.2.3