From 2e5ae3f0c26dcf3a64a1ae39b00690a73c9084bd Mon Sep 17 00:00:00 2001 From: bnewbold Date: Tue, 26 Apr 2016 00:20:30 -0400 Subject: rust: have car and cdr handle 'quote' (hack) --- minimal.scm | 10 +++++----- rust/spectrum.rs | 27 ++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/minimal.scm b/minimal.scm index 6e4c3c4..5c953e6 100644 --- a/minimal.scm +++ b/minimal.scm @@ -20,7 +20,7 @@ (define first (lambda (p) (car p))) -(define second +(define second (lambda (p) (car (cdr p)))) (define third @@ -58,7 +58,7 @@ (lambda (name table table-f) (cond ((null? table) (table-f name)) - (else (lookup-in-entry name + (else (lookup-in-entry name (car table) (lambda (n) (lookup-in-table n (cdr table) table-f))))))) @@ -105,9 +105,9 @@ ; need generic true/false booleans, a number type, and a symbol type ; also need a mutable "table" collection (define *const - (lambda (e table) - (cond - ((number? e) e) + (lambda (e table) + (cond + ((number? e) e) ((eq? e #t) #t) ((eq? e #f) #f) (else (build (quote builtin) e))))) diff --git a/rust/spectrum.rs b/rust/spectrum.rs index be41ca8..8325798 100644 --- a/rust/spectrum.rs +++ b/rust/spectrum.rs @@ -51,7 +51,7 @@ enum SchemeExpr { //////////// Lexing, Parsing, and Printing fn is_scheme_whitespace(c: char) -> bool{ - " \r\n".find(c) != None + " \t\r\n".find(c) != None } fn is_scheme_sep(c: char) -> bool { @@ -67,7 +67,7 @@ fn is_valid_identifier(s: &str) -> bool { return false; } for (i, c) in s.chars().enumerate() { - if !(c.is_alphabetic() || c == '*' || c == '?' || c == '!' || c == '-' || (c.is_numeric() && i > 0)) { + if !( c.is_alphabetic() || "*?!-:".find(c) != None || (c.is_numeric() && i > 0) ) { return false; } } @@ -535,7 +535,11 @@ fn apply_action(list: &Vec, &SchemeExpr::SchemeList(ref list) => { Ok(list[0].clone()) }, - _ => Err(format!("car only takes lists")) + &SchemeExpr::SchemeQuote(ref list) => { + Ok(list[0].clone()) + }, + _ => Err(format!("car only takes lists and quotes (got {})", + scheme_repr(&args[0]).unwrap())) } }, "cdr" => { @@ -550,7 +554,15 @@ fn apply_action(list: &Vec, Ok(SchemeExpr::SchemeNull) } }, - _ => Err(format!("cdr only takes lists")) + &SchemeExpr::SchemeQuote(ref list) => { + if list.len() > 1 { + Ok(SchemeExpr::SchemeList(list[1..].to_vec())) + } else { + Ok(SchemeExpr::SchemeNull) + } + }, + _ => Err(format!("cdr only takes lists and quotes (got {})", + scheme_repr(&args[0]):unwrap())) } }, "cons" => { @@ -566,7 +578,12 @@ fn apply_action(list: &Vec, ret.extend_from_slice(list); Ok(SchemeExpr::SchemeList(ret)) }, - _ => Err(format!("cons second arg must be list or null")) + &SchemeExpr::SchemeQuote(ref list) => { + let mut ret = vec![args[0].clone()]; + ret.extend_from_slice(list); + Ok(SchemeExpr::SchemeList(ret)) + }, + _ => Err(format!("cons second arg must be list, quote, or null")) } }, "begin" => { -- cgit v1.2.3