; Can you change a function-table to a function?
; ------------------------------
; The Little Lisper 3rd Edition
; Chapter 10
; Exercise 8
; 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 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))))
; ----------------------
;old definition
(defun *lambda (e table)
; (print '--*lambda--)
; (print e)
; (print table)
(build (quote non-primitive)
(cons table (cdr e))))
;new definition
(defun *lambda8 (e table)
(build
(quote non-primitive)
(lambda (vals)
(meaning (body-of e)
(extend-table
(new-entry (formals-of e) vals)
table)))))
;1. Find out what *lambda function is called with (adding print statements to lambda function
(value_ '((lambda (x) (add1 x)) 12))
;--APPLY-CLOSURE--
;(NIL (X) (ADD1 X))
;(12)
;13
;2. Try to see if arguments can be passed to function
(*lambda '(lambda (x) (add1 x)) '())
;(NON-PRIMITIVE (NIL (X) (ADD1 X)))
;3. Try passing arguments to new function
(*lambda8 '(lambda (x) (add1 x)) '())
;(NON-PRIMITIVE #<Interpreted Closure (:INTERNAL *LAMBDA8) @ #x20eeb09a>)
(cdr (*lambda8 '(lambda (x) (add1 x)) '()))
;(#<Interpreted Closure (:INTERNAL *LAMBDA8) @ #x20f6769a>)
(car (cdr (*lambda8 '(lambda (x) (add1 x)) '())))
;#<Interpreted Closure (:INTERNAL *LAMBDA8) @ #x20f70e7a>
(funcall (car (cdr (*lambda8 '(lambda (x) (add1 x)) '()))) '(12))
; 13
;4 So we need to modify what calls lambda to be like this
(defun meaning8 (e table)
(funcall (expression-to-action e) e table))
(defun list-to-action8 (e)
(cond
((atom (car e))
(cond
((eq (car e) (quote quote))
'*quote)
((eq (car e) (quote lambda))
'*lambda8)
((eq (car e) (quote cond))
'*cond)
(t '*application)))
(t '*application)))
(defun expression-to-action8 (e)
(cond
((atom e) (atom-to-action e))
(t (list-to-action8 e))))
(defun meaning8 (e table);funcall here?
(funcall (expression-to-action8 e) e table))
(defun value8 (e)
(meaning8 e (quote ())))
(print (value8 '(add1 1)))
;2
(print (value_ '((lambda (x) (add1 x)) 12)))
; 13
;(value5 '((lambda (x) (add1 x)) 12))
; NIL
(print (value8 '((lambda (x) (add1 x)) 12)))
;13