application/octet-stream
•
1.73 KB
•
34 lines
[def quasiquote-real [δ [l depth]
[if [pair? l]
[do [def lcar [car l]]
[if l
[cond [[pair? lcar] [if [eq? [car lcar] 'unquote-splicing]
[if [zero? depth]
[do [def result [eval* [cadr lcar]]]
[if [pair? result]
[append result [quasiquote-real [cdr l] depth]]
[throw [list :unquote-splicing-wrong-type "unquote splicing operations must return a list, not a single value" result]]]]
[cons [quasiquote-real lcar depth] [quasiquote-real [cdr l] depth]]]
[cons [quasiquote-real lcar depth] [quasiquote-real [cdr l] depth]]]]
[[eq? lcar 'unquote] [if [zero? depth]
[eval* [cadr l]]
[cons lcar [quasiquote-real [cdr l] [- depth 1]]]]]
[[eq? lcar 'quasiquote] [cons lcar [quasiquote-real [cdr l] [+ 1 depth]]]]
[#t [cons lcar [quasiquote-real [cdr l] depth]]]
]
#nil]]
l]
]]
[def quasiquote [δ [@list]
"Quasiquote"
[quasiquote-real @list 0]
]]
[defun unquote [expr]
[throw [list :unquote-without-quasiquote "unquote should only occure inside a quasiquote, never evaluated directly"]]
]
[defun unquote-splicing [expr]
[throw [list :unquote-splicing-without-quasiquote "unquote-splicing should only occure inside a quasiquote, never evaluated directly"]]
]