; YourDSL - building fns by eval'ing an expr
; ------------------------------
; The Little Lisper 3rd Edition
; Chapter 10
; Exercise 9
; 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)))
(setf e3
'((lambda (x)
(add1 4))
6))
(defun atom-to-action (e)
(cond
((numberp e) '*self-evaluating)
(t '*identifier)))
(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 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))))
; ----------------------
(defun initial-table (name)
; (print '--initial-table--)
; (print name)
(cond ((eq name 'add1) (print 'buildingAdd1)))
(cond
((eq name (quote t)) t)
((eq name (quote nil)) nil)
(t (build
(quote primitive)
name))))
(print (value_ e3))
;--APPLY-CLOSURE--
;(NIL (X) ((LAMBDA (X) (ADD1 X)) (ADD1 4)))
;(6)
;BUILDINGADD1
;--APPLY-CLOSURE--
;((((X) (6))) (X) (ADD1 X))
;(5)
;BUILDINGADD1
; 6
; inserted print statement in gets called twice
(defun initial-table9 (add1)
(lambda (name)
(cond
((eq name (quote t)) t)
((eq name (quote NIL)) NIL)
((eq name (quote add1)) add1)
(t (build (quote primitive) name))))
(build (quote primitive) add1))
(defun initial-table9 (add1)
(lambda (name)
(cond
((eq name (quote t)) t)
((eq name (quote NIL)) NIL)
((eq name (quote add1)) add1)
((eq name (quote quote)) *quote)
((eq name (quote identifier)) *identifier)
((eq name (quote lambda)) *lambda)
((eq name (quote cond)) *cond)
((eq name (quote application)) *application)
(t (build (quote primitive) name))))
(build (quote primitive) add1))
(defun *identifier9 (e table)
(lookup-in-table
e table 'initial-table9))
(defun atom-to-action9 (e)
(cond
((numberp e) '*self-evaluating)
(t '*identifier9)))
(defun expression-to-action9 (e)
(cond
((atom e) (atom-to-action9 e))
(t (list-to-action e))))
(defun meaning9 (e table)
(funcall (expression-to-action9 e) e table))
(defun value9 (e)
(meaning9 e (quote ())))
(print (value9 e3))
;--APPLY-CLOSURE--
;(NIL (X) ((LAMBDA (X) (ADD1 X)) (ADD1 4)))
;(6)
;BUILDINGADD1
;--APPLY-CLOSURE--
;((((X) (6))) (X) (ADD1 X))
;(5)
;BUILDINGADD1
;6
; 'primitive doesn't get called