Fix ', add if and = along with bools

This commit is contained in:
2023-02-08 01:54:53 -05:00
parent c801f604c2
commit d861d91397
3 changed files with 39 additions and 11 deletions

View File

@@ -1,15 +1,23 @@
use std::rc::Rc; use std::rc::Rc;
#[derive(Debug)] #[derive(Debug, Eq, PartialEq)]
pub enum Form { pub enum Form {
Nil,
Int(i32), Int(i32),
Bool(bool),
Symbol(String), Symbol(String),
Pair(Rc<Form>,Rc<Form>), Pair(Rc<Form>,Rc<Form>),
DeriComb { se: Rc<Form>, de: Option<String>, params: Rc<Form>, body: Rc<Form> },
PrimComb(String, fn(Rc<Form>, Rc<Form>) -> Rc<Form>), PrimComb(String, fn(Rc<Form>, Rc<Form>) -> Rc<Form>),
Nil, DeriComb { se: Rc<Form>, de: Option<String>, params: Rc<Form>, body: Rc<Form> },
} }
impl Form { impl Form {
pub fn truthy(&self) -> bool {
match self {
Form::Bool(b) => *b,
Form::Nil => false,
_ => true,
}
}
pub fn int(&self) -> Option<i32> { pub fn int(&self) -> Option<i32> {
match self { match self {
Form::Int(i) => Some(*i), Form::Int(i) => Some(*i),

View File

@@ -8,7 +8,7 @@ pub Term: Form = {
NUM => Form::Int(i32::from_str(<>).unwrap()), NUM => Form::Int(i32::from_str(<>).unwrap()),
SYM => Form::Symbol(<>.to_owned()), SYM => Form::Symbol(<>.to_owned()),
"(" <ListInside?> ")" => <>.unwrap_or(Form::Nil), "(" <ListInside?> ")" => <>.unwrap_or(Form::Nil),
"'" <Term> => Form::Pair(Rc::new(Form::Symbol("quote".to_owned())), Rc::new(<>)), "'" <Term> => Form::Pair(Rc::new(Form::Symbol("quote".to_owned())), Rc::new(Form::Pair(Rc::new(<>), Rc::new(Form::Nil)))),
}; };
ListInside: Form = { ListInside: Form = {
<Term> => Form::Pair(Rc::new(<>), Rc::new(Form::Nil)), <Term> => Form::Pair(Rc::new(<>), Rc::new(Form::Nil)),
@@ -20,8 +20,8 @@ match {
")", ")",
".", ".",
"'", "'",
r"[0-9]+" => NUM, r"[0-9]+" => NUM,
r"[a-zA-Z+*/_-][\w+*/_-]*" => SYM, r"[a-zA-Z+*/_=-][\w+*/=_-]*" => SYM,
r"(;[^\n]*\n)|\s+" => { } r"(;[^\n]*\n)|\s+" => { }
} }

View File

@@ -105,8 +105,20 @@ fn main() {
Rc::new(Form::DeriComb { se: e, de, params, body }) Rc::new(Form::DeriComb { se: e, de, params, body })
}))), }))),
("quote", Rc::new(Form::PrimComb("quote".to_owned(), |e, p| { ("=", Rc::new(Form::PrimComb("=".to_owned(), |e, p| {
p let a = eval(Rc::clone(&e), p.car().unwrap());
let b = eval(e, p.cdr().unwrap().car().unwrap());
Rc::new(Form::Bool(a == b))
}))),
("if", Rc::new(Form::PrimComb("if".to_owned(), |e, p| {
if eval(Rc::clone(&e), p.car().unwrap()).truthy() {
eval(e, p.cdr().unwrap().car().unwrap())
} else if let Some(els) = p.cdr().unwrap().cdr().and_then(|x| x.car()) {
eval(e, els)
} else {
// should we really allow this? (2 arg if with no else)
Rc::new(Form::Nil)
}
}))), }))),
("+", Rc::new(Form::PrimComb("+".to_owned(), |e, p| { ("+", Rc::new(Form::PrimComb("+".to_owned(), |e, p| {
let a = eval(Rc::clone(&e), p.car().unwrap()).int().unwrap(); let a = eval(Rc::clone(&e), p.car().unwrap()).int().unwrap();
@@ -124,9 +136,17 @@ fn main() {
("cdr", Rc::new(Form::PrimComb("cdr".to_owned(), |e, p| { ("cdr", Rc::new(Form::PrimComb("cdr".to_owned(), |e, p| {
eval(Rc::clone(&e), p.car().unwrap()).cdr().unwrap() eval(Rc::clone(&e), p.car().unwrap()).cdr().unwrap()
}))), }))),
("quote", Rc::new(Form::PrimComb("quote".to_owned(), |e, p| {
p.car().unwrap()
}))),
]); ]);
//let input = "(+ 2 (car (cons 4 '(1 2))))"; //let input = "(+ 2 (car (cons 4 '(1 2))))";
let input = "((vau d p (+ (eval (car p) d) 13)) (+ 1 3))"; let input = "(= 17 ((vau d p (+ (eval (car p) d) 13)) (+ 1 3)))";
let result = eval(env, Rc::new(grammar::TermParser::new().parse(input).unwrap())); //let input = "(if (= 2 2) (+ 1 2) (+ 3 4))";
//let input = "(quote a)";
//let input = "'a";
let parsed_input = grammar::TermParser::new().parse(input).unwrap();
println!("Parsed input is {:?}", parsed_input);
let result = eval(env, Rc::new(parsed_input));
println!("Result is {:?}", result); println!("Result is {:?}", result);
} }