aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2016-04-26 00:20:30 -0400
committerbnewbold <bnewbold@robocracy.org>2016-04-26 00:20:30 -0400
commit2e5ae3f0c26dcf3a64a1ae39b00690a73c9084bd (patch)
treeb3ebb05ede6711c060605bf9a754fc6825ccf830
parentef9ee326260a902f600a2a83fbb785ee935ac904 (diff)
downloadspectrum-2e5ae3f0c26dcf3a64a1ae39b00690a73c9084bd.zip
spectrum-2e5ae3f0c26dcf3a64a1ae39b00690a73c9084bd.tar.gz
rust: have car and cdr handle 'quote' (hack)
-rw-r--r--minimal.scm10
-rw-r--r--rust/spectrum.rs27
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>,
&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<SchemeExpr>,
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<SchemeExpr>,
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" => {