mylisp01.rkt
;---------------------------
(module mylisp01 racket
(displayln "mylisp01 module loaded!!")
(displayln "--------------------------")
(provide (all-defined-out))
(require compatibility/mlist)
;;;
;-------------------------
(define (my-eval exp env)
(cond ((self-evaluating? exp) exp)
((variable? exp) (lookup-variable-value exp env))
((quoted? exp) (text-of-quotation exp))
((my-set-and-define? exp) (eval-definition exp env))
((if? exp) (eval-if exp env))
((lambda? exp)
(make-procedure (lambda-parameters exp)
(lambda-body exp)
env))
((begin? exp) (eval-sequence (begin-actions exp) env))
((application? exp) ;;复合表达式 e10
(my-apply (my-eval (operator exp) env)
(list-of-values (operands exp) env)
env))
(else
(error "Unknown expression type -- EVAL" exp))
))
;----------------------------
;;;----------environment start------------------
;;;用hash表实现,缺点过程是内部的,不知道怎么垃圾回收
;;;(frame1 frame2 ...)
;;;frame: hash-table
(define (init-environment) (box '()))
(define (env-box env) (box env))
(define (env-unbox env) (unbox env))
(define (env-set! old-env new-unbox-env)
(box-cas! old-env (unbox old-env) new-unbox-env))
(define (first-frame env) (car env))
(define (rest-environment env) (cdr env))
(define (extend-environment vars contents base-env)
(let ((base-unbox-env (env-unbox base-env))
(new-unbox-env (make-hash)))
(env-set! base-env (cons (make-frame vars contents new-unbox-env) base-unbox-env))
base-env))
(define (reduce-environment base-env)
(let ((base-unbox-env (env-unbox base-env)))
(env-set! base-env (cdr base-unbox-env))
base-env))
(define (make-frame vars contents new-unbox-env)
(cond ((not (pair? vars))
(hash-set! new-unbox-env vars contents)
new-unbox-env)
(else
(let ((vars-len (length vars))
(contents-len (length contents)))
(cond ((= vars-len contents-len)
(let loop ((vars vars) (contents contents))
(cond ((null? vars) new-unbox-env)
(else
(hash-set! new-unbox-env (car vars) (car contents))
(loop (cdr vars) (cdr contents))))))
(else
(error "vars-num != contents-num" vars contents)))))))
;;;((variable? exp) (lookup-variable-value exp env))
(define (lookup-variable-value exp env)
(let ((unbox-env (env-unbox env)))
(cond ((null? unbox-env) (error "env is null!" unbox-env))
(else
(let ((frame (first-frame unbox-env))
(rest-env (env-box (rest-environment unbox-env))))
(cond ((hash-ref frame exp #f) => (lambda (x) x))
(else
(lookup-variable-value exp rest-env))))))))
;;;------environment page end-------------------------
;;;tagged-list?
(define (tagged-list? exp tag)
(if (pair? exp)
(eq? (car exp) tag)
#f))
;;;((self-evaluating? exp) exp)
(define (self-evaluating? exp)
(or (number? exp)
(string? exp)))
;;;((variable? exp) (lookup-variable-value exp env))
(define (variable? exp)
(symbol? exp))
;;;((quoted? exp) (text-of-quotation exp))
(define (quoted? exp)
(tagged-list? exp 'quote))
(define (text-of-quotation exp) (cadr exp))
(define (make-quoted exp)
(cons 'quote exp))
;;;((my-set-and-define? exp) (eval-definition exp env))
(define (my-set-and-define? exp)
(or (tagged-list? exp 'set!) (tagged-list? exp 'define)))
;;;(define fun ...)
;;;(define fun (lambda arg ...))
;;;(define fun (lambda (args) ...))
;;;(define (fun args) ...)
(define (eval-definition exp env)
(let ((first-exp (cadr exp))
(rest-exp (cddr exp)))
(cond ((pair? first-exp)
(let ((fun-name (car first-exp))
(fun-args (cdr first-exp))
(body rest-exp))
(extend-environment fun-name
(make-procedure fun-args body env)
env)
(cons (list fun-name fun-args) "ok!-(fun args)")))
(else
(let ((fun-name first-exp))
(extend-environment fun-name
(my-eval (car rest-exp) env)
env)
(cons (list fun-name) "ok!-vars"))))))
;;;;接下页
;---------------------------
(module mylisp01 racket
(displayln "mylisp01 module loaded!!")
(displayln "--------------------------")
(provide (all-defined-out))
(require compatibility/mlist)
;;;
;-------------------------
(define (my-eval exp env)
(cond ((self-evaluating? exp) exp)
((variable? exp) (lookup-variable-value exp env))
((quoted? exp) (text-of-quotation exp))
((my-set-and-define? exp) (eval-definition exp env))
((if? exp) (eval-if exp env))
((lambda? exp)
(make-procedure (lambda-parameters exp)
(lambda-body exp)
env))
((begin? exp) (eval-sequence (begin-actions exp) env))
((application? exp) ;;复合表达式 e10
(my-apply (my-eval (operator exp) env)
(list-of-values (operands exp) env)
env))
(else
(error "Unknown expression type -- EVAL" exp))
))
;----------------------------
;;;----------environment start------------------
;;;用hash表实现,缺点过程是内部的,不知道怎么垃圾回收
;;;(frame1 frame2 ...)
;;;frame: hash-table
(define (init-environment) (box '()))
(define (env-box env) (box env))
(define (env-unbox env) (unbox env))
(define (env-set! old-env new-unbox-env)
(box-cas! old-env (unbox old-env) new-unbox-env))
(define (first-frame env) (car env))
(define (rest-environment env) (cdr env))
(define (extend-environment vars contents base-env)
(let ((base-unbox-env (env-unbox base-env))
(new-unbox-env (make-hash)))
(env-set! base-env (cons (make-frame vars contents new-unbox-env) base-unbox-env))
base-env))
(define (reduce-environment base-env)
(let ((base-unbox-env (env-unbox base-env)))
(env-set! base-env (cdr base-unbox-env))
base-env))
(define (make-frame vars contents new-unbox-env)
(cond ((not (pair? vars))
(hash-set! new-unbox-env vars contents)
new-unbox-env)
(else
(let ((vars-len (length vars))
(contents-len (length contents)))
(cond ((= vars-len contents-len)
(let loop ((vars vars) (contents contents))
(cond ((null? vars) new-unbox-env)
(else
(hash-set! new-unbox-env (car vars) (car contents))
(loop (cdr vars) (cdr contents))))))
(else
(error "vars-num != contents-num" vars contents)))))))
;;;((variable? exp) (lookup-variable-value exp env))
(define (lookup-variable-value exp env)
(let ((unbox-env (env-unbox env)))
(cond ((null? unbox-env) (error "env is null!" unbox-env))
(else
(let ((frame (first-frame unbox-env))
(rest-env (env-box (rest-environment unbox-env))))
(cond ((hash-ref frame exp #f) => (lambda (x) x))
(else
(lookup-variable-value exp rest-env))))))))
;;;------environment page end-------------------------
;;;tagged-list?
(define (tagged-list? exp tag)
(if (pair? exp)
(eq? (car exp) tag)
#f))
;;;((self-evaluating? exp) exp)
(define (self-evaluating? exp)
(or (number? exp)
(string? exp)))
;;;((variable? exp) (lookup-variable-value exp env))
(define (variable? exp)
(symbol? exp))
;;;((quoted? exp) (text-of-quotation exp))
(define (quoted? exp)
(tagged-list? exp 'quote))
(define (text-of-quotation exp) (cadr exp))
(define (make-quoted exp)
(cons 'quote exp))
;;;((my-set-and-define? exp) (eval-definition exp env))
(define (my-set-and-define? exp)
(or (tagged-list? exp 'set!) (tagged-list? exp 'define)))
;;;(define fun ...)
;;;(define fun (lambda arg ...))
;;;(define fun (lambda (args) ...))
;;;(define (fun args) ...)
(define (eval-definition exp env)
(let ((first-exp (cadr exp))
(rest-exp (cddr exp)))
(cond ((pair? first-exp)
(let ((fun-name (car first-exp))
(fun-args (cdr first-exp))
(body rest-exp))
(extend-environment fun-name
(make-procedure fun-args body env)
env)
(cons (list fun-name fun-args) "ok!-(fun args)")))
(else
(let ((fun-name first-exp))
(extend-environment fun-name
(my-eval (car rest-exp) env)
env)
(cons (list fun-name) "ok!-vars"))))))
;;;;接下页