define ts readevalprintloop echon TS let exp ts

  • Slides: 12
Download presentation
(define (ts: read-eval-print-loop) (echon "TS==> ") (let* ((exp (ts: read)) (value (ts: eval exp

(define (ts: read-eval-print-loop) (echon "TS==> ") (let* ((exp (ts: read)) (value (ts: eval exp *ts: top-level-env*))) (unless (void? value) (write value) (newline)) (ts: read-eval-print-loop)))

Eval in the environment model: • to evaluate a compound expression other than a

Eval in the environment model: • to evaluate a compound expression other than a special form, evaluate the subexpressions and apply the value of the first to the rest • to evaluate a primitive expression • if it's a symbol, look it up in the environment using the lookup rule • if it's a constant or already evaluated, just return the value

; ; ; Evaluate an expression in an environment. (defgeneric (ts: eval (exp <top>)

; ; ; Evaluate an expression in an environment. (defgeneric (ts: eval (exp <top>) (env <env>))) ; ; ; Default method: return the expression as the ; ; ; value. Numbers, booleans, strings, etc. will ; ; ; evaluate to themselves. (defmethod (ts: eval (exp <top>) (env <env>)) exp)

; ; ; Evaluate a symbol by ; ; ; looking it up in

; ; ; Evaluate a symbol by ; ; ; looking it up in the environment (defmethod (ts: eval (var <symbol>) (env <env>)) (let ((bv (env-lookup-binding env var))) (if bv (binding-value bv) (unbound-var env var))))

; ; ; The exp is of the form (e 1 e 2 e

; ; ; The exp is of the form (e 1 e 2 e 3. . . en) ; ; ; extract the first expression and use ; ; ; eval-combination to evaluate (defmethod (ts: eval (combination <pair>) (env <env>)) (ts: eval-combination (head combination) (tail combination) env)) ; ; ; Evaluate a combination expression of the form ; ; ; (operator e 1 e 2 e 3. . . en) where args is the list ; ; ; of expressions e 1 e 2 e 3. . . en. (defgeneric (ts: eval-combination operator sub-exps (env <env>))) ; ; ; The default method evaluates the operator and the ; ; ; sub-expressions and then applies the operator value ; ; ; to the sub-expression values. Notice that application ; ; ; does not take an environment as an argument. (defmethod (ts: eval-combination operator sub-exps (env <env>)) (ts: apply (ts: eval operator env) (map (lambda (e) (ts: eval e env)) sub-exps)))

Apply in the environment model • To apply a procedure, • bind the arguments

Apply in the environment model • To apply a procedure, • bind the arguments to the parameters in a new frame • extend the environment in the procedure with the new frame • evaluate the body of the procedure in the new environment • To apply a special form, use a particular rule for that special form • To apply a primitive (built-in) function, do the computation for that primitive

; ; ; Apply a primitive or closure value to a list of argument

; ; ; Apply a primitive or closure value to a list of argument values. (defgeneric (ts: apply value args)) ; ; ; We use Swindle to apply a primitive operator ; ; ; such as +, *, - to arguments (defmethod (ts: apply (operator <procedure>) args) (apply operator args))

; ; ; To apply a closure, zip the formal arguments ; ; ;

; ; ; To apply a closure, zip the formal arguments ; ; ; and actual arguments into a list of bindings, ; ; ; create a new frame with those bindings, and ; ; ; link the environment of the closure in to ; ; ; create a new environment. Then evaluate the ; ; ; body of the closure in the new environment. (defmethod (ts: apply (operator <closure>) args) (let ((env (make <nested-env> : previous-env (closure-env operator) : frame-bindings (zip-bindings (closure-args operator) args)))) (ts: eval (closure-body operator) env)))

; ; ; A binding has a symbol and a value. (defclass <binding> ()

; ; ; A binding has a symbol and a value. (defclass <binding> () (binding-symbol : type <symbol> : initarg : binding-symbol : accessor binding-symbol) (binding-value : initarg : binding-value : accessor binding-value)) ; ; ; A frame is a list of bindings. (defclass <frame> () (frame-bindings : type <list> ; of bindings : initarg : frame-bindings : initvalue null : accessor frame-bindings))

; ; ; A top-level environment is just a frame. (defclass <env> (<frame>)) ;

; ; ; A top-level environment is just a frame. (defclass <env> (<frame>)) ; ; ; A nested environment is an environment (i. e. , ; ; ; frame) and a previous environment. (defclass <nested-env> (<env>) (previous-env : type <env> : initarg : previous-env : accessor previous-env))

; ; ; A utility function for combining a list of symbols ; ;

; ; ; A utility function for combining a list of symbols ; ; ; (formal parameters) and a list of values (actual ; ; ; parameters) into bindings. (define (zip-bindings formals actuals) (cond ((and (null? formals) (null? actuals)) null) ((null? formals) (error "too many arguments")) ((null? actuals) (error "too few arguments")) (else (cons (make <binding> : binding-symbol (head formals) : binding-value (head actuals)) (zip-bindings (tail formals) (tail actuals))))))

; ; ; A closure has a list of parameter symbols, ; ; ;

; ; ; A closure has a list of parameter symbols, ; ; ; a body expression, and an environment. (defclass <closure> () (closure-args : type <list> ; of symbols : initarg : closure-args : accessor closure-args) (closure-body : initarg : closure-body : accessor closure-body) (closure-env : type <env> : initarg : closure-env : accessor closure-env)) ; ; ; Special form (lambda (x 1. . . xn) e) -- create a ; ; ; closure and return it as the value of the combination. (defmethod (ts: eval-combination (operator = 'lambda) sub-exps (env <env>)) (make <closure> : closure-args (first sub-exps) ; (x 1. . . xn) : closure-body (second sub-exps) ; e : closure-env env))