From ba67b8c67ba6e06d3e7e1764ae1436613720fabc Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Fri, 10 Feb 2023 01:01:04 -0500 Subject: [PATCH] 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" --- kr/src/ast.rs | 7 +++++++ kr/src/grammar.lalrpop | 4 ++++ kr/src/main.rs | 13 +++++++------ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/kr/src/ast.rs b/kr/src/ast.rs index 88494ea..c6b2e0c 100644 --- a/kr/src/ast.rs +++ b/kr/src/ast.rs @@ -55,5 +55,12 @@ impl Form { _ => None, } } + pub fn append(&self, x: Rc
) -> Option { + 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, + } + } } diff --git a/kr/src/grammar.lalrpop b/kr/src/grammar.lalrpop index 266de55..21c51ce 100644 --- a/kr/src/grammar.lalrpop +++ b/kr/src/grammar.lalrpop @@ -9,6 +9,9 @@ pub Term: Form = { SYM => Form::Symbol(<>.to_owned()), "(" ")" => <>.unwrap_or(Form::Nil), "'" => Form::Pair(Rc::new(Form::Symbol("quote".to_owned())), Rc::new(Form::Pair(Rc::new(<>), Rc::new(Form::Nil)))), + "!" => { + h.append(Rc::new(t)).unwrap() + }, }; ListInside: Form = { => Form::Pair(Rc::new(<>), Rc::new(Form::Nil)), @@ -20,6 +23,7 @@ match { ")", ".", "'", + "!", r"[0-9]+" => NUM, r"[a-zA-Z+*/_=?%&|^-][\w+*/=_?%&|^-]*" => SYM, r"(;[^\n]*\n)|\s+" => { } diff --git a/kr/src/main.rs b/kr/src/main.rs index 23e19b1..7dc0035 100644 --- a/kr/src/main.rs +++ b/kr/src/main.rs @@ -62,16 +62,17 @@ fn parse_test() { 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?) true", true); + eval_test(&g, &e, "((vau root_env _ (eval 'a (cons (cons 'a 2) root_env))))", 2); let LET = " - ((vau root_env _ (eval '(let1 a 8 (+ a 9)) + !((vau root_env p (eval (car p) (cons (cons 'let1 + (vau de p (eval (car (cdr (cdr p))) (cons (cons (car p) (eval (car (cdr p)) de)) de))) + ) root_env))))"; - (vau de p (eval (car (cdr (cdr p))) (cons (cons (car p) (eval (car (cdr p)) de)) de))) - ) root_env)))) - "; - - eval_test(&g, &e, LET, 17); + eval_test(&g, &e, &format!("{} (let1 x 10 (+ x 7))", LET), 17); // TODO, finish lambda let LAMBDA = "