; Make your DSL expressions scalable
; ------------------------------
; The Little Lisper 3rd Edition
; Chapter 7
; Exercise 5
; 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-7-shadows.html
; http://t...content-available-to-author-only...t.com/2010/06/little-lisper.html
; ------------------------------
(setf l1 '())
(setf l2 '(3 + (66 6)))
(setf aexp4 5)
; ------------------------------
(defun notatom (lat)
(not (atom lat)))
(defun sub1 (n)
(- n 1))
(defun isoperator (a)
(cond
((null a) NIL)
((eq a '+) t)
((eq a '*) t)
((eq a '^) t)
(t NIL)))
(defun operator (aexp_)
(car (cdr aexp_)))
(defun numbered? (aexp_)
(cond
((atom aexp_) (numberp aexp_)) ;note use of primitive numberp
(t (and
(numbered? (car aexp_))
(numbered?
(car (cdr (cdr aexp_))))))))
;numbered? tests whether a representation of an arithmetic expression only contains numbers besides the +, * and ^
(print (numbered? '(1 + 2)))
;T
(print (numbered? '(1 + a)))
;NIL (false)
(defun 1st-sub-exp (aexp_)
(car aexp_))
(print (1st-sub-exp '(1 + 2)))
(defun 2nd-sub-exp (aexp_)
(car (cdr (cdr aexp_))))
(print (2nd-sub-exp '(1 + 2)))
;value returns what we think is the natural value of a numbered arithemetic expression
(defun value__ (aexp_)
(cond
((numberp aexp_) aexp_)
((eq (operator aexp_) '+)
(+ (value__ (1st-sub-exp aexp_))
(value__ (2nd-sub-exp aexp_))))
((eq (operator aexp_) '*)
(* (value__ (1st-sub-exp aexp_))
(value__ (2nd-sub-exp aexp_))))
(t
(^ (value__ (1st-sub-exp aexp_))
(value__ (2nd-sub-exp aexp_))))))
(print (value__ '(1 + 2)))
;define numbered? for arbitrary length list
(defun numbered_? (aexp_)
(cond
((null aexp_) t)
((notatom (car aexp_))
(and
(numbered? (car aexp_))
(numbered_? (cdr aexp_))))
((numberp (car aexp_))
(numbered_? (cdr aexp_)))
(t NIL)))
(defun numbered? (aexp_)
(cond
((null aexp_) NIL)
((isoperator (car aexp_))
(numbered_? (cdr aexp_)))
(t nil)))
(print (numbered?'(+ 1 2 3 4 5)))
;T
(print (numbered?'(+ 1 2 3 (* 3 4))))
;T
;define value? for an arbitrary length list
(defun addvec (vec)
(cond
((null vec) 0)
((notatom (car vec))
(+ (value_ (car vec))
(addvec (cdr vec))))
(t (+ (car vec)(addvec (cdr vec))))))
(print (addvec '(1 2 3)))
;6
(defun multvec (vec)
(cond
((null vec) 1)
((notatom (car vec))
(* (value_ (car vec))
(multvec (cdr vec))))
(t (* (car vec)(multvec (cdr vec))))))
(print (multvec '(1 2 3)))
;6
(defun ^_ (n m)
(cond
((= 0 m) 1)
(t (* n (^_ n (sub1 m))))))
(^_ 2 3)
;8
(defun value_ (aexp_)
(cond
((numberp aexp_) aexp_)
((notatom (car aexp_))
(value_ (car aexp_))
(value_ (cdr aexp_)))
((eq (car aexp_) '+)
(addvec (cdr aexp_)))
((eq (car aexp_) '*)
(multvec (cdr aexp_)))
(t
(^_ (value_ (1st-sub-expr aexp_))
(value_ (2nd-sub-expr aexp_))))))
(print (value_ '(+ 3 2 (* 7 8))))
;61
(print (value_ '(* 3 4 5 6)))
;360