C311 Assignment 4 (Procedures and Assignment)

;;
;; C311 Assignment 4
;; Procedures and Assignment
;; Due T 02/18/97 $ 11:59pm
;;


;;
;; -- data access procedures --
;;
(define variable? symbol?)
(define literal? number?)
(define app->rator car)
(define app->rands cdr)
(define decl->var  car)
(define decl->exp  cadr)


;;
;; -- 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))




;;
;; -- closure procedures --
;;

; old definition.
'(define make-closure
  (lambda (formals body env)
    (list 'closure formals body env)))

(define make-closure
  (lambda (formals body env)
    (lambda args
      (eval-exp body (extend-env formals args env)))))



;;
;; -- 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)))
	      (make-dvalue val-vector (- (length sym-list) (length x)))
	      (apply-env env symbol))))
      (else (error 'apply-env "Invalid finite function: ~s" env)))))

(define make-dvalue cons)

(define denoted-set!
  (lambda (denoted-value new-value)
    (vector-set! (car denoted-value) (cdr denoted-value) new-value)))

(define denoted->expressed
  (lambda (dvalue)
    (vector-ref (car dvalue) (cdr dvalue))))

(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 env)
    (cond
      ((literal? exp) exp)
      ((variable? exp) (denoted->expressed (apply-env env exp)))
      (else
	(record-case exp
	  (lambda (formals body)
	    (make-closure formals body env))
	  (if (test then else)
	      (if (true-value? (eval-exp test env))
		  (eval-exp then env)
		  (eval-exp else env)))
	  (set! (var exp)
		(let ([binding (apply-env env var)]
		      [value   (eval-exp exp env)])
		  (denoted-set! binding value)))
	  (begin (exp1 exp2)
	    (eval-exp exp1 env)
	    (eval-exp exp2 env))
	  (else
	    (let ((proc (eval-exp (app->rator exp) env))
		  (args (eval-rands (app->rands exp) env)))
	      (apply-proc proc args))))))))

(define eval-rands
  (lambda (rands env)
    (map (lambda (exp) (eval-exp exp env))
      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)



;;
;; -- expander procedures --
;;

(define expand
  (lambda (exp)
    (cond
      ((literal? exp) exp)
      ((variable? exp) exp)
      (else 
	(record-case exp
	  (let (decls body)
	    (let ((vars (map decl->var decls))
		  (exps (map decl->exp decls)))
	      (cons (list 'lambda vars (expand body))
		(map expand exps))))
	  (lambda (formals body)
	    (list 'lambda formals (expand body)))
	  (begin list-of-expr
	    (cond
	      [(null? list-of-expr) (error 'expand "invalid syntax: (begin)")]
	      [(null? (cdr list-of-expr))
	       (expand (car list-of-expr))]
	      [else (list 'begin
		      (expand (car list-of-expr))
		      (expand (cons 'begin (cdr list-of-expr))))]))
	  (else (map expand exp)))))))



;;
;; -- read-eval-print-loop procedures --
;;
(define run
  (lambda (exp)
    (eval-exp (expand exp) init-env)))

(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 Thu Sep 26 18:06:08 1996