a quasiquote / unquote mechanism in newlisp.
Note the use of uq and uq@.
Code: Select all
;; usage: (qq (x y (uq (+ 1 2)) (uq@ (list 1 2 3))))
;; ==> (x y 3 1 2 3)
(define-macro (qq s-expr)
(qq-eval s-expr))
;; Since qq is a macro you can't use (args) within.
;; Use qq-eval instead which is not a macro and thus
;; (args) will not capture the qq's (args).
;; usage: (qq-eval '(x y (uq (+ 1 2)) (uq@ (list 1 2 3))))
;; ==> (x y 3 1 2 3)
(define (qq-eval s-expr , i)
(if (list? s-expr)
(begin
(setq i 0)
(while (< i (length s-expr))
(let ((ss-expr (nth i s-expr)))
(if (list? ss-expr)
(cond
((= 'uq (first ss-expr))
(nth-set i s-expr (eval (qq-eval (last ss-expr))))
(inc 'i))
((= 'uq@ (first ss-expr))
(let ((ss-exprs (eval (qq-eval (last ss-expr)))))
(if (list? ss-exprs)
(begin
(pop s-expr i)
(dotimes (j (length ss-exprs))
(push (nth j ss-exprs) s-expr i)
(inc 'i)))
(begin
(nth-set i s-expr ss-exprs)
(inc 'i)))))
(true
(nth-set i s-expr (qq-eval ss-expr))
(inc 'i)))
(begin
(inc 'i)
s-expr))))
s-expr)
s-expr))
The following demonstrates the use of qq and qq-eval.
Code: Select all
;; Abbreviation for lambda or fn
(define-macro (\ )
(eval (qq-eval '(lambda (uq (first (args))) (uq@ (rest (args)))))))
;; Abbreviation for define
(define-macro (: _var-or-fn _value)
(if (list? _var-or-fn)
(eval (qq-eval '(define (uq _var-or-fn) (uq@ (rest (args))))))
(eval (qq (set _var-or-fn (uq _value))))))
appears in the expression being quasiquoted.
I'm hoping this makes writing macros more
convenient in newLisp.
Warning: I've only briefly tested this.