C311 Assignment 3 (Simple Interpreter)

;;
;; C311 Assignment 3
;; Simple Interpreter
;; Due T 02/11/97 @ 11:59pm
;;


;;
;; -- data access procedures --
;;
(define variable? symbol?)
(define literal? number?)
(define app->rator car)
(define app->rands cdr)
(define args->1st  car)
(define args->2nd  cadr)
(define args->all  (lambda (x) x))



;;
;; -- primitive procedures --
;;

(define my-equal
  (lambda (x y)
    (if (= x y) 1 0)))

(define my-zero
  (lambda (x)
    (if (zero? x) 1 0)))

(define my-greater
  (lambda (x y)
    (if (> x y) 1 0)))

(define my-less
  (lambda (x y)
    (if (< x y) 1 0)))

(define my-null
  (lambda (ls)
    (if (null? ls) 1 0)))

(define *prim-op-names* '(+ - * add1 sub1 cons car cdr list null
			   equal zero greater less))
(define *prim-op-procs* (list
			  + - * add1 sub1 cons car cdr list my-null
			  my-equal my-zero my-greater my-less))

; old definition.  Not needed anymore.
'(define apply-prim-op
  (lambda (prim-op args)
    (case prim-op
      ((+)    (+    (args->1st args) (args->2nd args)))
      ((-)    (-    (args->1st args) (args->2nd args)))
      ((*)    (*    (args->1st args) (args->2nd args)))
      ((add1) (+    (args->1st args) 1))
      ((sub1) (-    (args->1st args) 1))
      ((cons) (cons (args->1st args) (args->2nd args)))
      ((car)  (car  (args->1st args)))
      ((cdr)  (cdr  (args->1st args)))
      ((list)       (args->all args))
      (else (error 'apply-prim-op "Invalid prim-op name: ~s" prim-op)))))

; old definition.  Not neeeded any more.
'(define make-prim-proc
  (lambda (prim-op-name)
    (list 'prim-proc prim-op-name)))




;;
;; -- environment procedures --
;;
(define the-empty-env
  (list 'empty-env))

(define extend-env
  (lambda (sym-list val-list env)
    (list 'extended-env sym-list (list->vector val-list) env)))

(define apply-env
  (lambda (env symbol)
    (record-case env
      (empty-env ()
	(error 'empty-env "no association for symbol: ~s" symbol))
      (extended-env (sym-list val-vector env)
	(let ((x (memq symbol sym-list)))
	  (if x
	    (vector-ref val-vector (- (length sym-list) (length x)))
	    (apply-env env symbol))))
      (else (error 'apply-env "Invalid finite function: ~s" env)))))

(define init-env
  (extend-env
    '(emptylist)
    '(())
    (extend-env
      *prim-op-names*
      *prim-op-procs*	; was: (map make-prim-proc *prim-op-names*)
      the-empty-env)))



;;
;; -- interpreter procedures --
;;
(define eval-exp
  (lambda (exp)
    (cond
      ((literal? exp) exp)
      ((variable? exp) (apply-env init-env exp))
      (else
	(record-case exp
	  (if (test then else)
	      (if (true-value? (eval-exp test))
		  (eval-exp then)
		  (eval-exp else)))
	  (else
	    (let ((proc (eval-exp (app->rator exp)))
		  (args (eval-rands (app->rands exp))))
	      (apply-proc proc args))))))))

(define eval-rands
  (lambda (rands)
    (map eval-exp rands)))

; old definition.
'(define apply-proc
  (lambda (proc args)
    (if (pair? proc)
	(record-case proc
	  (prim-proc (prim-op) (apply-prim-op prim-op args))
	  (else (error 'apply-proc "Invalid procedure: ~s" proc)))
	(error 'apply-proc "Invalid procedure: ~s" proc))))

(define apply-proc apply)


;;
;; -- read-eval-print-loop procedures --
;;
(define run eval-exp)

(define repl ; read-eval-print loop
  (lambda ()
    (display "--> ")
    (write (run (read)))
    (newline)
    (repl)))



;;
;; -- helper procedures --
;;
(define true-value?
  (lambda (x)
    (not (zero? x))))


Last modified on Sun Sep 22 16:55:41 1996