+(def (quote def!)
+ (macro (name value rest)
+ (list
+ def
+ (list quote name)
+ value)
+ )
+ )
+
+(begin
+ (def! append
+ (lexpr (args)
+ (def! append-list
+ (lambda (a b)
+ (cond ((null? a) b)
+ (else (cons (car a) (append-list (cdr a) b)))
+ )
+ )
+ )
+
+ (def! append-lists
+ (lambda (lists)
+ (cond ((null? lists) lists)
+ ((null? (cdr lists)) (car lists))
+ (else (append-list (car lists) (append-lists (cdr lists))))
+ )
+ )
+ )
+ (append-lists args)
+ )
+ )
+ 'append)
+
+(append '(a b c) '(d e f) '(g h i))
+
+ ; boolean operators
+
+(begin
+ (def! or
+ (macro (l)
+ (def! _or
+ (lambda (l)
+ (cond ((null? l) #f)
+ ((null? (cdr l))
+ (car l))
+ (else
+ (list
+ cond
+ (list
+ (car l))
+ (list
+ 'else
+ (_or (cdr l))
+ )
+ )
+ )
+ )
+ )
+ )
+ (_or l)))
+ 'or)
+
+ ; execute to resolve macros
+
+(or #f #t)
+
+(begin
+ (def! and
+ (macro (l)
+ (def! _and
+ (lambda (l)
+ (cond ((null? l) #t)
+ ((null? (cdr l))
+ (car l))
+ (else
+ (list
+ cond
+ (list
+ (car l)
+ (_and (cdr l))
+ )
+ )
+ )
+ )
+ )
+ )
+ (_and l)))
+ 'and)
+
+ ; execute to resolve macros
+
+(and #t #f)
+
+(begin
+ (def! quasiquote
+ (macro (x rest)
+ (def! constant?
+ ; A constant value is either a pair starting with quote,
+ ; or anything which is neither a pair nor a symbol
+
+ (lambda (exp)
+ (cond ((pair? exp)
+ (eq? (car exp) 'quote)
+ )
+ (else
+ (not (symbol? exp))
+ )
+ )
+ )
+ )
+ (def! combine-skeletons
+ (lambda (left right exp)
+ (cond
+ ((and (constant? left) (constant? right))
+ (cond ((and (eqv? (eval left) (car exp))
+ (eqv? (eval right) (cdr exp)))
+ (list 'quote exp)
+ )
+ (else
+ (list 'quote (cons (eval left) (eval right)))
+ )
+ )
+ )
+ ((null? right)
+ (list 'list left)
+ )
+ ((and (pair? right) (eq? (car right) 'list))
+ (cons 'list (cons left (cdr right)))
+ )
+ (else
+ (list 'cons left right)
+ )
+ )
+ )
+ )
+
+ (def! expand-quasiquote
+ (lambda (exp nesting)
+ (cond
+
+ ; non cons -- constants
+ ; themselves, others are
+ ; quoted
+
+ ((not (pair? exp))
+ (cond ((constant? exp)
+ exp
+ )
+ (else
+ (list 'quote exp)
+ )
+ )
+ )
+
+ ; check for an unquote exp and
+ ; add the param unquoted
+
+ ((and (eq? (car exp) 'unquote) (= (length exp) 2))
+ (cond ((= nesting 0)
+ (car (cdr exp))
+ )
+ (else
+ (combine-skeletons ''unquote
+ (expand-quasiquote (cdr exp) (- nesting 1))
+ exp))
+ )
+ )
+
+ ; nested quasi-quote --
+ ; construct the right
+ ; expression
+
+ ((and (eq? (car exp) 'quasiquote) (= (length exp) 2))
+ (combine-skeletons ''quasiquote
+ (expand-quasiquote (cdr exp) (+ nesting 1))
+ exp))
+
+ ; check for an
+ ; unquote-splicing member,
+ ; compute the expansion of the
+ ; value and append the rest of
+ ; the quasiquote result to it
+
+ ((and (pair? (car exp))
+ (eq? (car (car exp)) 'unquote-splicing)
+ (= (length (car exp)) 2))
+ (cond ((= nesting 0)
+ (list 'append (car (cdr (car exp)))
+ (expand-quasiquote (cdr exp) nesting))
+ )
+ (else
+ (combine-skeletons (expand-quasiquote (car exp) (- nesting 1))
+ (expand-quasiquote (cdr exp) nesting)
+ exp))
+ )
+ )