From 18ed2090ec383fa3e15365ebad90b6a5af919b60 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Tue, 19 Apr 2016 20:54:27 -0400 Subject: rust: refactors Merge SchemeAtom and SchemeExpr enums. Make a lot more things references (not pass-by-value). Add lifetime annotations all over the place. Thanks for help Samantha! --- minimal.rs | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/minimal.rs b/minimal.rs index 1db7405..84474b7 100644 --- a/minimal.rs +++ b/minimal.rs @@ -14,17 +14,13 @@ use std::io::Write; //let const SCHEME_BUILTINS = ("lambda", "quote", "cond", "else", "cons", "car", "cdr", "null?", "eq?", "atom?", "zero?", "number?", "+", "-", "*", "/"); #[allow(dead_code)] -enum SchemeAtom<'a> { +enum SchemeExpr<'a> { SchemeNull, SchemeTrue, SchemeFalse, SchemeNum(f64), SchemeBuiltin(&'a str), SchemeStr(&'a str), -} - -enum SchemeExpr<'a> { - SchemeAtom(SchemeAtom<'a>), SchemeList(Vec>), } @@ -46,42 +42,55 @@ fn scheme_parse_num(s: &String) -> Result { return Ok(num); } -fn scheme_parse_sexpr(sexpr: Vec<&String>) -> Result { - let ret = sexpr.into_iter().map(|el| SchemeExpr::SchemeAtom(SchemeAtom::SchemeStr(el))).collect(); +fn scheme_parse_sexpr<'a>(sexpr: &Vec<&'a String>) -> Result, &'static str> { + let ret = sexpr.into_iter().map(|el| SchemeExpr::SchemeStr(el)).collect(); return Ok(SchemeExpr::SchemeList(ret)) } -fn scheme_parse(tokens: SchemeExpr) -> Result { - return Ok(SchemeExpr::SchemeAtom(SchemeAtom::SchemeNull)); +fn scheme_parse<'a>(tokens: &SchemeExpr) -> Result, &'static str> { + return Ok(SchemeExpr::SchemeNull); } -fn scheme_eval(ast: SchemeExpr) -> Result { - return Ok(SchemeExpr::SchemeAtom(SchemeAtom::SchemeNull)); +fn scheme_eval<'a>(ast: &SchemeExpr) -> Result, &'static str> { + return Ok(SchemeExpr::SchemeNull); } -fn scheme_repr(ast: SchemeExpr) -> Result { - return Ok("It Worked!".to_string()); +fn scheme_repr<'a>(ast: &SchemeExpr) -> Result { + return match ast { + &SchemeExpr::SchemeTrue => Ok("#t".to_string()), + &SchemeExpr::SchemeFalse => Ok("#t".to_string()), + &SchemeExpr::SchemeNull => Ok("'()".to_string()), + &SchemeExpr::SchemeList(ref list) => { + let mut ret: String = + list.iter().fold("(".to_string(), + |acc, ref el| acc + &scheme_repr(&el).unwrap()); + ret.push_str(")"); + Ok(ret) + }, + _ => Err("don't know how to repr something"), + } } fn main() { let stdin = io::stdin(); let mut stdout = io::stdout(); - let raw_input = &mut String::new(); loop { + let raw_input = &mut String::new(); stdout.write(b"\nminimal-rust> ").unwrap(); stdout.flush().unwrap(); - raw_input.clear(); stdin.read_line(raw_input).unwrap(); + let raw_input = raw_input; // UGH if raw_input.len() == 0 { stdout.write(b"\nCiao!\n").unwrap(); return; } - let tokens = scheme_tokenize(raw_input).unwrap(); - let sexpr = scheme_parse_sexpr(tokens).unwrap(); - let ast = scheme_parse(sexpr).unwrap(); - let resp = scheme_eval(ast).unwrap(); - println!("{}", scheme_repr(resp).unwrap()); + let tokens = scheme_tokenize(&raw_input).unwrap(); + let sexpr = scheme_parse_sexpr(&tokens).unwrap(); + let ast = scheme_parse(&sexpr).unwrap(); + let resp = scheme_eval(&ast).unwrap(); + println!("{}", scheme_repr(&resp).unwrap()); } } + -- cgit v1.2.3