Add "!" syntatic form - a bit like the single quote, but !(a b c) d => !(a b c d). Useful for like !(let a 1) (+ a 3) or w/e. Break out some of the infinate nesting"
This commit is contained in:
@@ -55,5 +55,12 @@ impl Form {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn append(&self, x: Rc<Form>) -> Option<Form> {
|
||||||
|
match self {
|
||||||
|
Form::Pair(car, cdr) => cdr.append(x).map(|x| Form::Pair(Rc::clone(car), Rc::new(x))),
|
||||||
|
Form::Nil => Some(Form::Pair(x, Rc::new(Form::Nil))),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ pub Term: Form = {
|
|||||||
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(Form::Pair(Rc::new(<>), Rc::new(Form::Nil)))),
|
"'" <Term> => Form::Pair(Rc::new(Form::Symbol("quote".to_owned())), Rc::new(Form::Pair(Rc::new(<>), Rc::new(Form::Nil)))),
|
||||||
|
"!" <h: Term> <t: Term> => {
|
||||||
|
h.append(Rc::new(t)).unwrap()
|
||||||
|
},
|
||||||
};
|
};
|
||||||
ListInside: Form = {
|
ListInside: Form = {
|
||||||
<Term> => Form::Pair(Rc::new(<>), Rc::new(Form::Nil)),
|
<Term> => Form::Pair(Rc::new(<>), Rc::new(Form::Nil)),
|
||||||
@@ -20,6 +23,7 @@ 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+" => { }
|
||||||
|
|||||||
@@ -62,16 +62,17 @@ fn parse_test() {
|
|||||||
eval_test(&g, &e, "(bool? true)", true);
|
eval_test(&g, &e, "(bool? true)", true);
|
||||||
eval_test(&g, &e, "(bool? 1)", false);
|
eval_test(&g, &e, "(bool? 1)", false);
|
||||||
|
|
||||||
|
eval_test(&g, &e, "!(bool?) 1", false);
|
||||||
|
eval_test(&g, &e, "!(bool?) true", true);
|
||||||
|
|
||||||
eval_test(&g, &e, "((vau root_env _ (eval 'a (cons (cons 'a 2) root_env))))", 2);
|
eval_test(&g, &e, "((vau root_env _ (eval 'a (cons (cons 'a 2) root_env))))", 2);
|
||||||
let LET = "
|
let LET = "
|
||||||
((vau root_env _ (eval '(let1 a 8 (+ a 9))
|
!((vau root_env p (eval (car p)
|
||||||
(cons (cons 'let1
|
(cons (cons 'let1
|
||||||
|
|
||||||
(vau de p (eval (car (cdr (cdr p))) (cons (cons (car p) (eval (car (cdr p)) de)) de)))
|
(vau de p (eval (car (cdr (cdr p))) (cons (cons (car p) (eval (car (cdr p)) de)) de)))
|
||||||
) root_env))))
|
) root_env))))";
|
||||||
";
|
|
||||||
|
|
||||||
eval_test(&g, &e, LET, 17);
|
eval_test(&g, &e, &format!("{} (let1 x 10 (+ x 7))", LET), 17);
|
||||||
|
|
||||||
// TODO, finish lambda
|
// TODO, finish lambda
|
||||||
let LAMBDA = "
|
let LAMBDA = "
|
||||||
|
|||||||
Reference in New Issue
Block a user