;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; A meta-circular interpreter for Scheme ;;; function to evaluate a [little] Scheme expression ;;; A [little] Scheme expression is one of: ;;; - constant (number,bool) NUMBER #t #f ;;; - lambda expression (lambda VARS BODY) ;;; - variable V ;;; - quoted form (quote VALUE) ;;; - if expression (if TEST THEN-PART ELSE-PART) ;;; - function calls (F X1 ... Xn) ;;; Evaluate lScheme expression e in environment env, represented ;;; as alist of variable names (symbols) to lScheme values. (define my-eval (lambda (e env) (cond ((number? e) e) ((equal? e #t) #t) ((equal? e #f) #f) ((symbol? e) (lookup-variable e env)) ((pair? e) (let ((s (car e))) (cond ((equal? s 'lambda) 'xxx-lambda) ((equal? s 'if) (my-eval (if (my-eval (cadr e) env) (caddr e) (cadddr e)) env)) ((equal? s 'quote) (cadr e)) ((equal? s 'let) (eval-let e env)) (else ;; regular function call (let ((vs (map (lambda (e) (my-eval e env)) e))) (my-apply (car vs) (cdr vs)))))))))) (define my-apply (lambda (f vals) (apply f vals))) ;;; look up variable s in environment env, or if not found, in global environment. (define lookup-variable (lambda (s env) (cond ((assoc s env) => cadr) ((equal? s '+) (lambda (x y) (+ x y))) ((equal? s 'car) car) ((equal? s 'cons) cons) (else 'unbound-variable)))) ;;; e has shape: (let ((VAR VEXPR) ...) BODY) (define eval-let (lambda (e env) (let ((clauses (cadr e)) (body (caddr e))) (my-eval body (append (map (lambda (clause) (let ((var (car clause)) (e (cadr clause))) (list var (my-eval e env)))) clauses) env)))))