From bf0202f74dd68eb6664d19c603cf69e97d5a16d7 Mon Sep 17 00:00:00 2001 From: Sahas Subramanian Date: Sat, 18 Nov 2023 14:26:22 +0100 Subject: [PATCH] Replace `let*` implementation with `let` `let` was already functioning like `let*`, so now both the functions have the `let*` behaviour. And with this `let*` is no longer a macro that expands to nested `let`s, but a special form that's faster to execute. --- src/builtin/functions/functions.rs | 5 +++- src/builtin/macros.rs | 36 ------------------------ tests/tests.rs | 44 +++++++++++++++--------------- 3 files changed, 26 insertions(+), 59 deletions(-) diff --git a/src/builtin/functions/functions.rs b/src/builtin/functions/functions.rs index d443cb7..209067c 100644 --- a/src/builtin/functions/functions.rs +++ b/src/builtin/functions/functions.rs @@ -15,6 +15,7 @@ use crate::{destruct_bind, list}; use std::convert::TryInto; use std::rc::Rc; +use tulisp_proc_macros::crate_add_func; use tulisp_proc_macros::{crate_fn, crate_fn_no_eval}; pub(super) fn reduce_with( @@ -203,7 +204,7 @@ pub(crate) fn add(ctx: &mut TulispContext) { Ok(value) } - #[crate_fn_no_eval(add_func = "ctx", name = "let")] + #[crate_fn_no_eval] fn impl_let( ctx: &mut TulispContext, varlist: TulispObject, @@ -254,6 +255,8 @@ pub(crate) fn add(ctx: &mut TulispContext) { ret } + crate_add_func!(ctx, impl_let, "let"); + crate_add_func!(ctx, impl_let, "let*"); #[crate_fn_no_eval(add_func = "ctx")] fn progn(ctx: &mut TulispContext, rest: TulispObject) -> Result { diff --git a/src/builtin/macros.rs b/src/builtin/macros.rs index 33dc97f..b86dbc6 100644 --- a/src/builtin/macros.rs +++ b/src/builtin/macros.rs @@ -1,8 +1,5 @@ use std::rc::Rc; -use tulisp_proc_macros::{crate_add_macro, crate_fn_no_eval}; - -use crate::cons::Cons; use crate::context::TulispContext; use crate::error::Error; use crate::TulispObject; @@ -41,37 +38,6 @@ fn thread_last(_ctx: &mut TulispContext, vv: &TulispObject) -> Result Result { - fn unwrap_varlist( - ctx: &mut TulispContext, - varlist: TulispObject, - body: TulispObject, - ) -> Result { - destruct_bind!((nextvar &rest rest) = varlist); - - let mut ret = Cons::new(ctx.intern("let"), TulispObject::nil()); - ret.push(list!(,nextvar)?)?; - if !rest.null() { - ret.push(unwrap_varlist(ctx, rest, body)?)?; - } else { - for ele in body.base_iter() { - ret.push(ele.clone())?; - } - } - Ok(TulispValue::List { - cons: ret, - ctxobj: Some(ctx.intern("let").get()?), - } - .into_ref()) - } - unwrap_varlist(ctx, varlist, rest) -} - pub(crate) fn add(ctx: &mut TulispContext) { ctx.intern("->") .set_scope(TulispValue::Macro(Rc::new(thread_first)).into_ref()) @@ -85,6 +51,4 @@ pub(crate) fn add(ctx: &mut TulispContext) { ctx.intern("thread-last") .set_scope(TulispValue::Macro(Rc::new(thread_last)).into_ref()) .unwrap(); - - crate_add_macro!(ctx, let_star, "let*"); } diff --git a/tests/tests.rs b/tests/tests.rs index 11ec26c..24694dc 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -178,7 +178,7 @@ fn test_conditionals() -> Result<(), Error> { tulisp_assert! { program: "(macroexpand '(if-let (c) (+ c 10) 2))", - result_str: "'(let ((s (and t c))) (if s (+ c 10) 2))", + result_str: "'(let* ((s (and t c))) (if s (+ c 10) 2))", } tulisp_assert! { program: "(defun test (&optional c) (if-let (c) (+ c 10) 2)) (list (test) (test 2))", @@ -203,27 +203,27 @@ fn test_conditionals() -> Result<(), Error> { tulisp_assert! { program: "(macroexpand '(when-let (c) (+ c 10)))", - result_str: "'(let ((s (and t c))) (if s (+ c 10) nil))", + result_str: "'(let* ((s (and t c))) (if s (+ c 10) nil))", } tulisp_assert! { program: "(macroexpand '(when-let (c) (+ c 10) 2))", - result_str: "'(let ((s (and t c))) (if s (progn (+ c 10) 2) nil))", + result_str: "'(let* ((s (and t c))) (if s (progn (+ c 10) 2) nil))", } tulisp_assert! { program: "(macroexpand '(when-let ((q c) d (w 10)) 2 (+ c d w)))", result_str: r#"' - (let ((q (and t c))) - (let ((d (and q d))) - (let ((w (and d 10))) - (if w - (progn 2 (+ c d w)) - nil)))) + (let* ((q (and t c)) + (d (and q d)) + (w (and d 10))) + (if w + (progn 2 (+ c d w)) + nil)) "#, } tulisp_assert! { program: "(macroexpand '(while-let (c) (+ c 10)))", - result_str: "'(while (let ((s (and t c))) (if s (progn (+ c 10) t) nil)))", + result_str: "'(while (let* ((s (and t c))) (if s (progn (+ c 10) t) nil)))", } tulisp_assert! { program: "(let ((ll '(1 2 3)) (vv 0)) (while-let (x (car ll)) (setq ll (cdr ll)) (setq vv (+ vv x))) vv)", @@ -835,18 +835,18 @@ fn test_threading_macros() -> Result<(), Error> { (print a)))) "##, result_str: r##" - '(let ((s (and t a))) - (let ((s (and s b))) - (if s - (print a) - (let ((s (and t a))) - (if s - (print a) - (let ((s (and t b))) - (if s - (print b) - nil))))))) - "##, + '(let* ((s (and t a)) + (s (and s b))) + (if s + (print a) + (let* ((s (and t a))) + (if s + (print a) + (let* ((s (and t b))) + (if s + (print b) + nil)))))) + "##, } tulisp_assert! {