; (cd "C:\\Users/fengk/Desktop/304FinalProject") (load "alltogether.ss") (define eval-one-exp (lambda (exp) (eval-tree (sp exp) (empty-env)) )) (define ev (lambda (exp) (eval-tree (sp exp) (empty-env)) )) (define rep (lambda () (display ">>->") (let ([input (read)]) (if (eq? input '(exit)) ;then (display "Bye..........") ;else (let* ( ;[aa (display input)] [parsed-tree (sp input)] [response (eval-tree parsed-tree (empty-env) )]) (display response) (newline) ;(display "global-env") ;(display global-env) ;(newline) (rep)))))) (define eval-tree (lambda (exp env) (cond [(null? exp) exp] [(and (list? exp) (list? (car exp))) ;list of list...recursively eval them ! (cons (eval-tree (car exp) env) (eval-tree (cdr exp) env))] [else (cond [(eqv? (car exp) 'null-exp) (cadr exp)] ;[(eqv? (car exp) 'quote-exp) '(NothingToDoooooooooooooo)] [(eqv? (car exp) 'set!-exp) (set-env env (cadr exp) (eval-tree (caddr exp) env))] [(eqv? (car exp) 'lit-exp) (if (pair? (cadr exp)) ;val ### (cadr (cadr exp)) ;val get rid of (quote ~) (cadr exp))] ;val [(eqv? (car exp) 'begin-exp) (let let-loop ([exps (cadr exp)]) (if (null? (cdr exps)) ;then (eval-tree (car exps) env) ;else (begin (eval-tree (car exps) env) (let-loop (cdr exps)))))] [(eqv? (car exp) 'var-exp) (apply-env env (cadr exp))] [(eqv? (car exp) 'if-exp) (if (eval-tree (cadr exp) env) ;test (eval-tree (caddr exp) env))] ;consequent [(eqv? (car exp) 'if-alt-exp) (if (eval-tree (cadr exp) env) ;test (eval-tree (caddr exp) env) ;consequent (eval-tree (cadddr exp) env))] ;alternative [(eqv? (car exp) 'lambda-exp) (list 'closure (cadr exp) ;id (caddr exp) ;body env)] ;env [(eqv? (car exp) 'define-exp) (define-env env (cadr exp) (eval-tree (caddr exp) env))] [(eqv? (car exp) 'cond-exp) (cond-recur (cadr exp) (extend-env (list 'else) (list #t) env) )] ;[(eqv? (car exp) 'case-exp) (case-exp-helper (cadr exp) (caddr exp) env)] ;[(eqv? (car exp) 'while-exp) (while-recur (cadr exp) (caddr exp) env)] ;[while-exp (test express) (eval-while test express env)] [(eqv? (car exp) 'or-exp) (or-exp-helper2 (or-exp-helper (cadr exp) env))] [(eqv? (car exp) 'and-exp) (and-exp-helper2 (and-exp-helper (cadr exp) env))] [(eqv? (car exp) 'let-exp) ;(apply begin-eval ;retune the last exp's value (return-last (map ; map it (lambda (x) ; plug in exp and then eval the exp with env (eval-tree ; expressions x ; enviroments (extend-env (cadr exp) ;vars (map (lambda (x) (eval-tree x env)) (caddr exp)) ;values env))) (cadddr exp) ;plug in the body ))] [(eqv? (car exp) 'letrec-exp) (eval-letrec (cadr exp) (caddr exp) (cadddr exp) env)] ;[(eqv? (car exp) 'named-let-exp) #f] ;[(eqv? (car exp) 'let*-exp) #f] [(eqv? (car exp) 'app-exp) (let ( [procedure (eval-tree (cadr exp) env)] ;operator [arg (eval-tree (caddr exp) env)]) ;operand (apply-proc procedure arg env))] )]))) ;;;;;;;;;;;;;;;;;;;;;;;;;;helper functions;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define eval-letrec (lambda (vars vals body env) (cond [(null? vars) (eval-tree (syntax-expand (list 'let-exp vars vals body)) env)] [else ((lambda (x) (car (reverse x))) (eval-tree body (expand-env-letrec vars vals env)))]))) ; (define case-exp-helper ; (lambda ( var cases env) ; (cond ; [(eqv? 'else (caar cases)) (eval-tree (cadar cases) env)] ; [(contains? var (caar cases)) (eval-tree (cadar cases) env)] ; [(case-exp-helper var (cdr cases) env )]))) (define contains? (lambda (x list) (if (null? list) #f (if (equal? (car list) x) #t (if (null? (cdr list)) #f (contains? x (cdr list))))))) (define or-exp-helper (lambda (conds env) (let* ([test (null? conds)][con (if test '() (eval-tree (car conds) env))]) (cond [(null? con) #f] [con con] [else (or-exp-helper (cdr conds) env)])))) (define or-exp-helper2 (lambda(x) (if x x #f))) (define and-exp-helper (lambda (conds env) (let* ([test (null? conds)][con (if test '() (eval-tree (car conds) env))]) (cond [(null? conds) #t] [(null? (cdr conds)) con] [(not con) con] [else (and-exp-helper (cdr conds) env)])))) (define and-exp-helper2 (lambda(x) (if x x #f))) (define cond-recur (lambda (ls env) (cond [(null? ls) '()] [(eval-tree (caar ls) env) (eval-tree (cadar ls) env)] [(cond-recur (cdr ls) env)] ))) ; (define begin-eval ;return the last value ; (case-lambda ;case-lambda is bad! ; [(x) x] ; [(x . rest) (apply begin-eval rest)])) (define return-last (lambda (x) (cond [(eqv? (cdr x) '()) (car x)] [else (return-last (cdr x))]))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define *prim-proc-names* '(for-each remove append eof-object? close-port open-input-file cadddr newline eqv? string? boolean? display read load + - * display / add1 sub1 zero? not < > <= >= = cons car cdr list null? assq assv eq? equal? atom? length list->vector vector->list vector make-vector vector-ref vector? number? symbol? set-car! set-cdr! vector-set! caar cadr cdar cddr caaar caadr cadar caddr cdaar cdadr cddar cdddr list? pair? procedure? void map apply)) (define init-env (map (lambda (name) (list name name)) *prim-proc-names*)) (define global-env init-env) ; (define apply-proc ; (lambda (procs args env) ; (cond ; [(contains? procs *prim-proc-names*) ; (apply-primitives procs args env)] ; [(eqv? (car procs) 'closure) ; (let* ( ; [var (if (symbol? (cadr procs)) (list (cadr procs)) (cadr procs))] ;id/vars ; [arg (if (symbol? args) (list args) args)] ; [new-env (extend-env var arg (cadddr procs))]) ;env ; (apply eval-lambda (list(eval-all (caddr procs) new-env))) ; )]))) ;body (define apply-proc (lambda (procs args env) ;(display "applyproc = ")(display procs)(newline) ;(display "applyargs = ")(display args)(newline) ;(display "applyenv = ")(display env)(newline) (cond [(contains? procs *prim-proc-names*) (apply-primitives procs args env)] [(eqv? (car procs) 'closure) (if (not(list? (cadr procs))) ;dotted-list varible (let* ( ;[try1 (display "#proc = ")] ;[try2 (display proc)] ;[try3 (display "#args = ")] ;[try4 (display args)] ;[try5 (display "#env = ")] ;[try5 (display env)] ;[try6 (display "##########Dotted-list#########")] [lambda-vars (cadr procs)] [proper-list-vars (dotted-lambda-vars lambda-vars)] [new-env (extend-env proper-list-vars ;var (dotted-lambda-args (length proper-list-vars) args);arg env)]);old-env ;(eval-all body new-env) (apply eval-lambda (list(eval-all (caddr procs) new-env))) ) ;normal varible (let* ( ;[try1 (display "#proc = ")] ;[try2 (display procs)] ;[k1 (newline)] ;[try3 (display "#args = ")] ;[try4 (display args)] ;[k2 (newline)] ;[try5 (display "#env = ")] ;[try5 (display env)] ;[k3 (newline)] ;[try6 (display "##########Normal-list#########")] ;[k4 (newline)] [var (if (symbol? (cadr procs)) (list (cadr procs)) (cadr procs))] ;id/vars [arg (if (symbol? args) (list args) args)] [new-env (extend-env var arg (cadddr procs))]) ;env ### (apply eval-lambda (list(eval-all (caddr procs) new-env))) ))]))) ;body (define eval-lambda (lambda (first . rest) ;need to implement lambda (x.y) /done! (cond [(null? rest) first] [else (apply eval-lambda rest)]))) (define dotted-lambda-vars (lambda (vars) (cond ([symbol? vars] (list vars)) (else (cons (car vars) (dotted-lambda-vars (cdr vars))))))) (define dotted-lambda-args (lambda (length args) (if (= length 1) (list args) (cons (car args) (dotted-lambda-args (- length 1) (cdr args)))))) (define eval-all (lambda (cmds env) (cond [(null? (car cmds)) '()] [else (eval-tree (list 'begin-exp cmds) env)]))) (define deconstruct-list (lambda (list) (cond ([null? list] '()) ([list? (car list)] (append (car list) (deconstruct-list (cdr list)))) (else (cons (car list) (deconstruct-list (cdr list))))))) (define 1st car) (define 2nd cadr) (define 3rd caddr) (define apply-primitives (lambda (prim-proc args env) (cond [(eqv? prim-proc 'display) (apply display args)] [(eqv? prim-proc '+) (begin ;(display " + args= ") ;(display args) ;(newline) (apply + args))] [(eqv? prim-proc '-) (apply - args)] [(eqv? prim-proc '*) (apply * args)] [(eqv? prim-proc '/) (apply / args)] [(eqv? prim-proc 'add1) (+ (1st args) 1)] [(eqv? prim-proc 'sub1) (- (1st args) 1)] [(eqv? prim-proc 'zero?) (eqv? 0 (1st args))] [(eqv? prim-proc 'not) (not (1st args))] [(eqv? prim-proc '<) (< (1st args) (2nd args))] [(eqv? prim-proc '>) (> (1st args) (2nd args))] [(eqv? prim-proc '<=) (<= (1st args) (2nd args))] [(eqv? prim-proc '>=) (>= (1st args) (2nd args))] [(eqv? prim-proc '=) (= (1st args) (2nd args))] [(eqv? prim-proc 'cons) (cons (1st args) (2nd args))] [(eqv? prim-proc 'car) (1st (1st args))] [(eqv? prim-proc 'cdr) (cdr (1st args))] [(eqv? prim-proc 'list) args] [(eqv? prim-proc 'null?) (null? (1st args))] [(eqv? prim-proc 'eq?) (eq? (1st args) (2nd args))] [(eqv? prim-proc 'equal?) (equal? (1st args) (2nd args))] [(eqv? prim-proc 'eqv?) (eqv? (1st args) (2nd args))] [(eqv? prim-proc 'atom?) (atom? (1st args))] [(eqv? prim-proc 'length) (length (1st args))] [(eqv? prim-proc 'list->vector) (list->vector (1st args))] [(eqv? prim-proc 'vector->list) (vector->list (1st args))] [(eqv? prim-proc 'vector) (apply vector args)] [(eqv? prim-proc 'make-vector) (if (null? (cdr args)) (make-vector (1st args)) (make-vector (1st args) (2nd args)))] [(eqv? prim-proc 'vector-ref) (vector-ref (1st args) (2nd args))] [(eqv? prim-proc 'vector?) (vector? (1st args))] [(eqv? prim-proc 'boolean?) (boolean? (1st args))] [(eqv? prim-proc 'string?) (string? (1st args))] [(eqv? prim-proc 'number?) (number? (1st args))] [(eqv? prim-proc 'symbol?) (symbol? (1st args))] [(eqv? prim-proc 'set-car!) (set-car! (1st args) (2nd args))] [(eqv? prim-proc 'set-cdr!) (set-cdr! (1st args) (2nd args))] [(eqv? prim-proc 'vector-set!) (vector-set! (1st args) (2nd args) (3rd args))] [(eqv? prim-proc 'caar) (caar (1st args))] [(eqv? prim-proc 'cadr) (cadr (1st args))] [(eqv? prim-proc 'cdar) (cdar (1st args))] [(eqv? prim-proc 'cddr) (cddr (1st args))] [(eqv? prim-proc 'caaar) (caaar (1st args))] [(eqv? prim-proc 'caadr) (caadr (1st args))] [(eqv? prim-proc 'cadar) (cadar (1st args))] [(eqv? prim-proc 'caddr) (caddr (1st args))] [(eqv? prim-proc 'cdaar) (cdaar (1st args))] [(eqv? prim-proc 'cdadr) (cdadr (1st args))] [(eqv? prim-proc 'cddar) (cddar (1st args))] [(eqv? prim-proc 'cdddr) (cdddr (1st args))] [(eqv? prim-proc 'cadddr) (cadddr (1st args))] [(eqv? prim-proc 'list?) (list? (1st args))] [(eqv? prim-proc 'pair?) (pair? (1st args))] [(eqv? prim-proc 'procedure?) (procedure? (1st args))] [(eqv? prim-proc 'void) (void)] [(eqv? prim-proc 'map) (map (lambda (x) (apply-proc (car args) (list x) env)) (cadr args))] [(eqv? prim-proc 'apply) (apply-proc (car args) (deconstruct-list (cdr args)) env)] [(eqv? prim-proc 'assq) (assq (1st args) (2nd args))] [(eqv? prim-proc 'assv) (assv (1st args) (2nd args))] [(eqv? prim-proc 'remove) (remove (1st args) (2nd args))] [(eqv? prim-proc 'for-each) (for-each (1st args) (2nd args)(3rd args))] [(eqv? prim-proc 'append) (append (1st args) (2nd args))] [(eqv? prim-proc 'display) (display args)] [(eqv? prim-proc 'newline) (newline)] [(eqv? prim-proc 'read) (read )] [(eqv? prim-proc 'open-input-file) (open-input-file (1st args))] [(eqv? prim-proc 'eof-object?) (eof-object? (1st args))] [(eqv? prim-proc 'close-port) (close-port (1st args))] [(eqv? prim-proc 'load) (let ([file (open-input-file "alltogether.ss")]) (let read-file ([exp (read file)]) (if (eof-object? exp) ;then (close-port file) ;else (begin (eval-one-exp exp) (read-file (read file))))))] [else (error 'apply-prim-proc"Invalid primitive procedure name: ~s" prim-op)]))) ;===================================== env ================================== (define empty-env (lambda () '())) (define reset-global-env ;reset the global-env to contain only primitives. (lambda () (set! global-env (map (lambda (name) (list name name)) *prim-proc-names*)))) (define extend-env ; ( (env) + ((syms...) ###) + (env) + () ) (lambda (syms vals env) ;[display "extend env with"] ;[newline] ;[display "syms = "] ;[display syms] ;[newline] ;[display "vals = "] ;[display vals] ;[newline] (cons (cons syms (list->vector vals)) env))) (define expand-env-letrec ;for letrec (lambda (vars vals old-env) (let* ( [len (length vars)] [vec (make-vector len)] [env (cons (cons vars vec) old-env)]) (for-each (lambda (pos val) (if (eq? (car val) 'lambda-exp) (vector-set! vec pos (list 'closure (cadr val) (caddr val) env)) (vector-set! vec pos (eval-tree val env)))) (iota len) vals) env))) (define apply-env (lambda (env sym) (if (null? env) (apply-global-env sym) (let* ([syms (caar env)] [vals (cdar env)] [new-env (cdr env)] [pos (list-find-position sym syms)]) (cond [(number? pos) (vector-ref vals pos) ] [else (apply-env new-env sym)]))))) (define set-env (lambda (env sym new-val) ;[display "set-env-sym ="] ;[display sym] ;[newline] ;[display "set-env-val ="] ;[display new-val] ;[newline] (if (null? env) (set-global-env sym new-val) (let* ( [syms (caar env)] [vals (cdar env)] [new-env (cdr env)] [pos (list-find-position sym syms)]) (cond [(number? pos) (vector-set! vals pos new-val)] [else (set-env new-env sym new-val)]))))) (define define-env (lambda (env sym new-val) (define-global-env sym new-val))) (define apply-global-env ;change the global-env (lambda (sym) (let ([val (assq sym global-env)] ;get the value from global-env. [try0 (display "func= ")] [try1 (display sym)] [try2 (newline)] ) ; so that i know which function is being used ;if not exist will have val=#f, or got a list of (var val) (cadr val) ;get the value ))) (define set-global-env ; (lambda (sym new-val) (let ([ind (assq sym global-env)]) ;get the binding list (f x) (set! global-env (cons (cons sym (list new-val))(remove ind global-env)))))) ;replace it! (define define-global-env ;same as above (lambda (sym new-val) (let ([ind (assq sym global-env)]) ;get the chunk (if ind (set! global-env (cons (cons sym (list new-val))(remove ind global-env))) ;replace it! (set! global-env (cons (cons sym (list new-val)) global-env)))))) ;add it! (define list-find-position ;find the position of a element in a list (lambda (sym los) (list-index (lambda (sym1) (eqv? sym1 sym)) los))) (define list-index ;helper for the list-find-position (lambda (pred ls) (cond [(null? ls) #f] [(pred (car ls)) 0] [else (let [(list-index-r (list-index pred (cdr ls)))] (if (number? list-index-r) (+ list-index-r 1) #f))]))) (define iota ;return (0 1 2 3 4....x-1) for making up the searching index (lambda (x) (if (= x 0) '() (append (iota (- x 1)) (list (- x 1)))))) ;=========================================== parser ===================== (define sp (lambda (x) (syntax-expand (parse-expression x)))) (define is-literal? (lambda (x) (and (or (boolean? x) (number? x) (string? x) (vector? x) (if (pair? x) (if (not (null? (car x))) (eqv? (car x) 'quote) #f) #f)) (not (null? x))))) (define parse-expression (lambda (datum) (cond ((is-literal? datum) (cons 'lit-exp (list datum))) ((symbol? datum) (cons 'var-exp (list datum))) ((boolean? datum) (cons 'var-exp (list datum))) ((number? datum) (cons 'var-exp (list datum))) ((vector? datum) (cons 'var-exp (list datum))) ((string? datum) (cons 'var-exp (list datum))) ((null? datum) (cons 'var-exp (list datum))) [(pair? datum) (cond ;;lambda expression [(eq? (car datum) 'lambda) (list 'lambda-exp (cadr datum) (map parse-expression (cddr datum)))] ;;if expression [(and (eqv? (car datum) 'if) (not (null? (cdr datum))) (not (null? (cddr datum))) (null? (cdddr datum))) (list 'if-exp (parse-expression (cadr datum)) (parse-expression (caddr datum)) )] ;;if-alt expression [(eq? (car datum) 'if) (list 'if-alt-exp (parse-expression (cadr datum)) (parse-expression (caddr datum)) (parse-expression (cadddr datum)))] ;begin expression [(eq? (car datum) 'begin) (list 'begin-exp (map parse-expression (cdr datum)))] ;set! expression [(eqv? (car datum) 'set!) (list 'set!-exp (cadr datum) (parse-expression (caddr datum)))] ;quote expression [(eqv? (car datum) 'quote) (list 'lit-exp (cadr datum))] ;while expression [(eqv? (car datum) 'while) (list 'while-exp (parse-expression (cadr datum)) ;test (map parse-expression (cddr datum)))] ;express ;let expression ([eqv? (car datum) 'let] (cond ([symbol? (cadr datum)] (list 'named-let-exp (cadr datum) (map car (caddr datum)) (map parse-expression (map cadr (caddr datum))) (map parse-expression (cdddr datum)))) (else (list 'let-exp (map car (cadr datum)) (map parse-expression (map cadr (cadr datum))) (map parse-expression (cddr datum)))))) ;let* expression ([eqv? (car datum) 'let*] (list 'let*-exp (map car (cadr datum)) (map parse-expression (map cadr (cadr datum))) (map parse-expression (cddr datum)))) ;letrec expression [(eqv? (car datum) 'letrec) (list 'letrec-exp (map car (cadr datum)) (map parse-expression (map cadr (cadr datum))) (map parse-expression (cddr datum)))] ;cond-expression [(eqv? (car datum) 'cond) (list 'cond-exp (map append (map (lambda (l) (map parse-expression l)) (cdr datum)) ) )] ;case-expression ;[(eqv? (car datum) 'case) ;(list 'case-exp ; (parse-expression (cadr datum)) ; (map case-parse-help (cddr datum)))] ;OR-expression [(eqv? (car datum) 'and) (list 'and-exp (map parse-expression (cdr datum)))] ;AND expression [(eqv? (car datum) 'or) (list 'or-exp (map parse-expression (cdr datum)))] ;define expression [(eqv? (car datum) 'define) (list 'define-exp (cadr datum) (parse-expression (caddr datum)))] ;[else (app-exp (map parse-expression datum))] [else (list 'app-exp (parse-expression (car datum)) (map parse-expression (cdr datum)))])] [else (display "invalid syntax") ]))) ;(define case-parse-help ; (lambda(ls) ; (cond ; [(list? (car ls)) (cons (map parse-expression (car ls)) (list(parse-expression (cadr ls))))] ; [(eqv? 'else (car ls)) (cons (car ls) (list(parse-expression (cadr ls))))] ; ))) (define syntax-expand (lambda (exp) (cond [(eqv? (car exp) 'var-exp) exp] [(eqv? (car exp) 'lit-exp) exp] [(eqv? (car exp) 'quote-exp) exp] [(eqv? (car exp) 'define-exp) (list 'define-exp (cadr exp) (syntax-expand (caddr exp)))] [(eqv? (car exp) 'lambda-exp) (list 'lambda-exp (cadr exp) ;id() (map syntax-expand (caddr exp)))] ;body [(eqv? (car exp) 'app-exp) (list 'app-exp (syntax-expand (cadr exp)) ;oprator (map syntax-expand (caddr exp)))] ;operand [(eqv? (car exp) 'set!-exp) (list 'set!-exp (cadr exp) ;var (syntax-expand (caddr exp)))] ;val [(eqv? (car exp) 'let-exp) (list 'app-exp (list 'lambda-exp (cadr exp) ;vars (map syntax-expand (cadddr exp))) ;body (map syntax-expand (caddr exp)) ;value )] [(eqv? (car exp) 'let*-exp) (if (null? (cadr exp)) ;vars ;then (syntax-expand (list 'let-exp (cadr exp) ;vars (caddr exp) ;values (cadddr exp))) ;body ;else (syntax-expand (list 'let-exp (list (car (cadr exp))) ;vars (list (car (caddr exp))) ;values (list (syntax-expand (list 'let*-exp (cdr (cadr exp)) ;vars (cdr (caddr exp)) ;values (cadddr exp)))) ;body )))] [(eqv? (car exp) 'if-exp) (list 'if-exp (syntax-expand (cadr exp)) ;tesjt (syntax-expand (caddr exp)))] ;consequent [(eqv? (car exp) 'if-alt-exp) (list 'if-alt-exp (syntax-expand (cadr exp)) ;test (syntax-expand (caddr exp)) ;consequent (syntax-expand (cadddr exp)))] ;alternate [(eqv? (car exp) 'null-exp) exp] [(eqv? (car exp) 'begin-exp) (list 'begin-exp (map syntax-expand (cadr exp)))] ;body [(eqv? (car exp) 'cond-exp) (list 'cond-exp (map cond-expand-helper (cadr exp)))] ;cases ; [(eqv? (car exp) 'case-exp) ; (case-exp (cadr exp) (map case-expand-helper (caddr exp)))] ;cases [(eqv? (car exp) 'and-exp) (list 'and-exp (map syntax-expand (cadr exp)))] ;conds [(eqv? (car exp) 'or-exp) (list 'or-exp (map syntax-expand (cadr exp)))] ;conds [(eqv? (car exp) 'named-let-exp) (list 'letrec-exp (list (cadr exp)) ;name (list (syntax-expand (list 'lambda-exp (caddr exp) (car(cddddr exp))))) ;vars bodies (list (syntax-expand (list 'app-exp (parse-expression (cadr exp)) (cadddr exp)))))] [(eqv? (car exp) 'letrec-exp) (list 'letrec-exp (cadr exp) (map syntax-expand (caddr exp)) (map syntax-expand (cadddr exp)))] ))) (define cond-expand-helper (lambda (x) (if (eq? 'else (car x)) (cons 'else (map syntax-expand (cdr x))) (cons (syntax-expand (car x)) (map syntax-expand (cdr x)))))) ;(define case-expand-helper ; (lambda (x) (cons (car x) (map syntax-expand (cdr x)))))