Implement cons, car, cdr, null?, pair? resolves #1
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use crate::interpreter::has_tag;
|
||||
use crate::parser::make_symbol;
|
||||
use crate::parser::Datum;
|
||||
use crate::parser::Datum::*;
|
||||
use std::io;
|
||||
@@ -89,14 +91,91 @@ pub fn lt(args: Vec<Datum>) -> Datum {
|
||||
|
||||
pub fn display(args: Vec<Datum>) -> Datum {
|
||||
for i in 1..args.len() {
|
||||
match &args[i] {
|
||||
Boolean(b) => print!("{}", b),
|
||||
Number(n) => print!("{}", n),
|
||||
String(s) => print!("{}", s),
|
||||
List(v) => print!("{:?}", v),
|
||||
_ => panic!("DISPLAY -- cannot-print {:?}", args[i]),
|
||||
};
|
||||
print!("{}", args[i]);
|
||||
}
|
||||
io::stdout().flush().ok().expect("Could not flush stdout");
|
||||
Unspecified
|
||||
}
|
||||
|
||||
pub fn list(mut args: Vec<Datum>) -> Datum {
|
||||
args[0] = make_symbol("list");
|
||||
Datum::List(args)
|
||||
}
|
||||
|
||||
pub fn cons(mut args: Vec<Datum>) -> Datum {
|
||||
if args.len() != 3 {
|
||||
panic!("CONS -- two args expected {:?}", args);
|
||||
}
|
||||
let a = std::mem::take(&mut args[1]);
|
||||
let b = std::mem::take(&mut args[2]);
|
||||
match b {
|
||||
List(b_vec) if has_tag(&b_vec, "list") => {
|
||||
let mut r_vec = vec![make_symbol("list"), a];
|
||||
r_vec.append(&mut b_vec[1..].to_vec());
|
||||
Datum::List(r_vec)
|
||||
}
|
||||
_ => Datum::Pair(Box::new((a, b))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn car(mut args: Vec<Datum>) -> Datum {
|
||||
if args.len() != 2 {
|
||||
panic!("CAR -- expected a single arg {:?}", args);
|
||||
}
|
||||
let a = std::mem::take(&mut args[1]);
|
||||
match a {
|
||||
List(mut v) if has_tag(&v, "list") => std::mem::take(&mut v[1]),
|
||||
Pair(p) => p.0,
|
||||
_ => panic!("CAR -- could not get car {:?}", a),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cdr(mut args: Vec<Datum>) -> Datum {
|
||||
if args.len() != 2 {
|
||||
panic!("CDR -- expected a single arg {:?}", args);
|
||||
}
|
||||
let a = std::mem::take(&mut args[1]);
|
||||
match a {
|
||||
List(v) if has_tag(&v, "list") => {
|
||||
let mut v_cdr = v[1..].to_vec();
|
||||
v_cdr[0] = make_symbol("list");
|
||||
List(v_cdr)
|
||||
}
|
||||
Pair(p) => p.1,
|
||||
_ => panic!("CAR -- could not get car {:?}", a),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pair(args: Vec<Datum>) -> Datum {
|
||||
if args.len() != 2 {
|
||||
panic!("PAIR? -- expected a single arg {:?}", args);
|
||||
}
|
||||
match &args[1] {
|
||||
List(v) if has_tag(&v, "list") => {
|
||||
if v.len() == 1 {
|
||||
Boolean(false)
|
||||
} else {
|
||||
Boolean(true)
|
||||
}
|
||||
}
|
||||
Pair(_) => Boolean(true),
|
||||
_ => Boolean(false),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn null(args: Vec<Datum>) -> Datum {
|
||||
if args.len() != 2 {
|
||||
panic!("PAIR? -- expected a single arg {:?}", args);
|
||||
}
|
||||
match &args[1] {
|
||||
List(v) if has_tag(&v, "list") => {
|
||||
if v.len() == 1 {
|
||||
Boolean(true)
|
||||
} else {
|
||||
Boolean(false)
|
||||
}
|
||||
}
|
||||
Pair(_) => Boolean(false),
|
||||
_ => Boolean(false),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user