; YourDSL - How to rewrite your function
; ------------------------------
; The Little Lisper 3rd Edition
; Chapter 10
; Exercise 4
; Common Lisp
; http://t...content-available-to-author-only...r.com/thelittlelisper
; http://t...content-available-to-author-only...t.com/2010/06/little-lisper-chapter-10-what-is-value.html
; http://t...content-available-to-author-only...t.com/2010/06/little-lisper.html
; ------------------------------
(defun build (a b)
(cons a (cons b '())))
(setf e4
'(3 (quote a)(quote b)))
(defun list-to-action (e)
(cond
((atom (car e))
(cond
((eq (car e) (quote quote))
'*quote)
((eq (car e) (quote lambda))
'*lambda)
((eq (car e) (quote cond))
'*cond)
(t '*application)))
(t '*application)))
(defun atom-to-action (e)
(cond
((numberp e) '*self-evaluating)
(t '*identifier)))
(defun expression-to-action (e)
(cond
((atom e) (atom-to-action e))
(t (list-to-action e))))
(defun meaning (e table)
(funcall (expression-to-action e) e table))
(defun value_ (e)
(meaning e (quote ())))
(defun *self-evaluating (e table)
e)
(defun *quote (e table)
(text-of-quotation e))
(defun text-of-quotation (l)
(second l))
(defun *identifier (e table)
(lookup-in-table
e table 'initial-table))
(defun initial-table (name)
(cond
((eq name (quote t)) t)
((eq name (quote nil)) nil)
(t (build
(quote primitive)
name))))
(defun lookup-in-table (name table table-f)
(cond
((null table) (funcall table-f name))
(t (lookup-in-entry
name
(car table)
(lambda (name)
(lookup-in-table
name
(cdr table)
table-f))))))
(defun lookup-in-entry (name entry entry-f)
(lookup-in-entry-help
name
(first entry)
(second entry)
entry-f))
(defun lookup-in-entry-help (name names values entry-f)
(cond
((null names) (funcall entry-f name))
((eq (car names) name)
(car values))
(t (lookup-in-entry-help
name
(cdr names)
(cdr values)
entry-f))))
(defun *application (e table)
(apply_
(meaning (function-of e) table)
(evlis (arguments-of e) table)))
(defun evcon (lines table)
(cond
((meaning
(question-of (car lines)) table)
(meaning
(answer-of (car lines)) table))
(t (evcon (cdr lines) table))))
(defun question-of (l)
(first l))
(defun answer-of (l)
(second l))
(defun *cond (e table)
(evcon (cond-lines e) table))
(defun cond-lines (l)
(cdr l))
(defun apply_ (fun vals)
(cond
((primitive? fun)
(apply-primitive
(second fun) vals))
((non-primitive? fun)
(apply-closure
(second fun) vals))))
(defun primitive? (l)
(eq
(first l)
(quote primitive)))
(defun non-primitive? (l)
(eq
(first l)
(quote non-primitive)))
(defun add1 (n)
(+ 1 n))
(defun apply-primitive (name vals)
(cond
((eq name (quote car))
(car (first vals)))
((eq name (quote cdr))
(cdr (first vals)))
((eq name (quote cons))
(cons (first vals) (second vals)))
((eq name (quote eq))
(eq (first vals) (second vals)))
((eq name (quote atom))
(atom (first vals) ))
((eq name (quote not))
(not (first vals) ))
((eq name (quote null))
(null (first vals) ))
((eq name (quote number))
(numberp (first vals) ))
((eq name (quote zero))
(zero (first vals) ))
((eq name (quote add1))
(add1 (first vals) ) )
((eq name (quote sub1))
(sub1 (first vals) )) ))
(defun function-of (l)
(car l))
(defun arguments-of (l)
(cdr l))
(defun evlis (args table)
(cond
((null args) (quote ()))
(t (cons (meaning (car args) table)
(evlis (cdr args) table)))))
(defun apply-closure (closure vals)
(meaning (body-of closure)
(extend-table
(new-entry
(formals-of closure) vals)
(table-of closure))))
(defun body-of (l)
(third l))
(defun extend-table (a b)
(cons a b))
(defun new-entry (a b)
(build a b))
(defun formals-of (l)
(second l))
(defun table-of (l)
(first l))
(defun *lambda (e table)
(build (quote non-primitive)
(cons table (cdr e))))
; ------------------------------
(setf e3
'((lambda (x)
((lambda (x)
(add1 x))
(add1 4)))
6))
(print (value_ e3))
; 6
; Its doing 4 + 1 = 5 then passing that to add1 - the final 6 is ignored
; from the first lambda - you can change the 6 to -1 and get the same value
;stepping through
(meaning e3 '())
;6
(expression-to-action e3)
;*APPLICATION
(*application e3 '())
;6
(meaning (function-of e3) '())
; (NON-PRIMITIVE (NIL (X) ((LAMBDA (X) (ADD1 X)) (ADD1 4))))
(evlis (arguments-of e3) '())
; (6)
(apply_ '(NON-PRIMITIVE (NIL (X) ((LAMBDA (X) (ADD1 X)) (ADD1 4)))) '(6))
; 6
(function-of e3)
; (LAMBDA (X) ((LAMBDA (X) (ADD1 X)) (ADD1 4)))
(meaning '(LAMBDA (X) ((LAMBDA (X) (ADD1 X)) (ADD1 4))) '())
; (NON-PRIMITIVE (NIL (X) ((LAMBDA (X) (ADD1 X)) (ADD1 4))))
(expression-to-action '(LAMBDA (X) ((LAMBDA (X) (ADD1 X)) (ADD1 4))) )
; *LAMBDA
(funcall '*LAMBDA '(LAMBDA (X) ((LAMBDA (X) (ADD1 X)) (ADD1 4))) '())
; (NON-PRIMITIVE (NIL (X) ((LAMBDA (X) (ADD1 X)) (ADD1 4)))) ?