scheme evaluation
#lang racket (define built-in-names '(define lambda set! + - * /)) (define (make-empty-env enclosing) (cons (make-immutable-hash) enclosing)) (define (get-global-env) (let ((global-frame (make-immutable-hash (map (lambda (x) (cons x 'BUILT-IN-FUNCTION)) built-in-names)))) (cons global-frame 0))) (define (get-global-env-map) (make-immutable-hash (list (cons 1 (get-global-env))))) (define (env-lookup env-map env-id key) (if (zero? env-id) (error (string-append "Wasn't able to find key " (symbol->string key) " in any environment.")) (let* ((env (hash-ref env-map env-id)) (value (hash-ref (car env) key 'NOT-FOUND))) (if (equal? value 'NOT-FOUND) (env-lookup env-map (cdr env) key) value)))) (define (env-add-key-value env-map env-id key value) (let* ((env (hash-ref env-map env-id)) (frame (car env)) (new-frame (hash-set frame key value)) (new-env (cons new-frame (cdr env)))) (hash-set env-map env-id new-env))) (define (env-remove env-map env-id) (hash-remove env-map env-id)) (hash-set (get-global-env-map) 2 (make-empty-env 1)) (define symbol-ht (make-immutable-hash (map (lambda (x) (cons x 'BUILT-IN-FUNCTION)) built-in-names))) (define (my-eval expr env-id env-map) (cond [(number? expr) (cons expr env-map)] [(string? expr) (cons expr env-map)] [(boolean? expr) (cons expr env-map)] [(null? expr) (cons expr env-map)] [(symbol? (car expr)) (cond [(hash-has-key? symbol-ht (car expr)) (cons (env-lookup (get-global-env-map) env-id (car expr)) env-map)] [else (cons (eval expr) env-map)])] [else (error "Unknown expression type:" expr)]) ) (define (even? n) (= (remainder n 2) 0)) (define (length elems) (if (empty? elems) 0 (+ 1 (length (cdr elems))))) (define (eval-prog expr) (list-ref (foldl cons '() (map (lambda (function) (eval function)) expr)) 0) )