
基于 PALI第七章:任意位置的函数
增加 if分支表达式,let表达式, begin表达式; desuger,prase,deprase组。
重写 number-calculate,
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
#lang plai-typed
;;;------------------Inner Expression--------------------------- (define-type Expr [Nmb (n : number)] [Add (l : Expr) (r : Expr)] [Sub (l : Expr) (r : Expr)] [Mul (l : Expr) (r : Expr)] [Div (l : Expr) (r : Expr)] [Idf (e : symbol)] [Lambda (para : symbol) (body : Expr)] [Apply (fun : Expr) (argu : Expr)] [If (test : Expr) (t-expr : Expr) (f-expr : Expr)] [Test (mktest : symbol) (f-test : Expr) (t-test : Expr)])
(define-type S-Expr [S-Nmb (n : number)] [S-Add (l : S-Expr) (r : S-Expr)] [S-Sub (l : S-Expr) (r : S-Expr)] [S-Mul (l : S-Expr) (r : S-Expr)] [S-Div (l : S-Expr) (r : S-Expr)] [S-Idf (e : symbol)] [S-Lambda (para : symbol) (body : S-Expr)] [S-Apply (fun : S-Expr) (argu : S-Expr)] [S-If (test : S-Expr) (t-expr : S-Expr) (f-expr : S-Expr)] [S-Test (mktest : symbol) (f-test : S-Expr) (t-test : S-Expr)] [Let (idf : symbol) (expr : S-Expr) (in : S-Expr)] [Begin (first : S-Expr) (then : S-Expr)])
(define-type Value [NmbV (n : number)] [Bool (test-result : Boolen)] [Closure (para : symbol) (body : Expr) (env : Env)])
(define-type Boolen [True] [False])
;;;------------------Envrionment Expression--------------------- (define-type Binding [Bind (idf : symbol) (value : Value)])
(define-type-alias Env [listof Binding])
;;--envrionment handler------- (define globle-env empty)
(define (extend-env [bind : Binding] [env : Env]) (cons bind env))
;;----find-idf-value symbol & Env -> Value ----- (define (find-idf-value [idf : symbol] [env : Env]) : Value (cond [(empty? env) (error 'find-idf-value "No such idf!")] [(equal? idf (Bind-idf (first env))) (Bind-value (first env))] [else (find-idf-value idf (rest env))]))
;;-------------------Core prase :: s-expression -> Expr ------------------- (define (prase [expr : s-expression]) : S-Expr (cond [(s-exp-number? expr) (S-Nmb (s-exp->number expr))] [(s-exp-symbol? expr) (S-Idf (s-exp->symbol expr))] [(s-exp-list? expr) (let ([expr-list (s-exp->list expr)]) (cond [(s-exp-list? (first expr-list)) (S-Apply (prase (first expr-list)) (prase (second expr-list)))] [else (case (s-exp->symbol (first expr-list)) [(lambda) (S-Lambda (s-exp->symbol (second expr-list)) (prase (third expr-list)))] [(+) (S-Add (prase (second expr-list)) (prase (third expr-list)))] [(-) (S-Sub (prase (second expr-list)) (prase (third expr-list)))] [(*) (S-Mul (prase (second expr-list)) (prase (third expr-list)))] [(/) (S-Div (prase (second expr-list)) (prase (third expr-list)))] [(=) (S-Test '= (prase (second expr-list)) (prase (third expr-list)))] [(>) (S-Test '> (prase (second expr-list)) (prase (third expr-list)))] [(<) (S-Test '< (prase (second expr-list)) (prase (third expr-list)))] [(if) (S-If (let ([test (s-exp->list (second expr-list))]) (S-Test (s-exp->symbol (first test)) (prase (second test)) (prase (third test)))) (prase (third expr-list)) (prase (fourth expr-list)))] ;;<suger> [(let) (let ([bind (s-exp->list (second expr-list))] [in (prase (third expr-list))]) (let ([idf (s-exp->symbol (first bind))] [expr (prase (second bind))]) (Let idf expr in)))] [(begin) (Begin (prase (second expr-list)) (prase (third expr-list)))] [else (S-Apply (prase (first expr-list)) (prase (second expr-list)))])]))]))
;; desuger :: Expr -> S-Expr (define (desuger [s-expr : S-Expr]) : Expr (type-case S-Expr s-expr [S-Nmb (n) (Nmb n)] [S-Add (l r) (Add (desuger l) (desuger r))] [S-Sub (l r) (Sub (desuger l) (desuger r))] [S-Mul (l r) (Mul (desuger l) (desuger r))] [S-Div (l r) (Div (desuger l) (desuger r))] [S-Idf (idf) (Idf idf)] [S-Lambda (para body) (Lambda para (desuger body))] [S-Apply (fun argu) (Apply (desuger fun) (desuger argu))] [S-If (test t-expr f-expr) (If (desuger test) (desuger t-expr) (desuger f-expr))] [S-Test (mktest f-test t-test) (Test mktest (desuger f-test) (desuger t-test))] ;;<desuger-core> [Let (idf expr in) (Apply (Lambda idf (desuger in)) (desuger expr))] [Begin (first then) (Apply (Lambda 'Nil (desuger then)) (desuger first))]))
;;------------Core interp ::Expr & Env -> Value--------------- (define (interp [expr : Expr] [env : Env]) : Value (type-case Expr expr [Nmb (n) (NmbV n)] [Idf (idf) (find-idf-value idf env)] [Lambda (para body) (Closure para body env)] [Apply (fun argu) (let ([fundef (interp fun env)]) (interp (Closure-body fundef) (extend-env (Bind (Closure-para fundef) (interp argu env)) (Closure-env fundef))))] [If (test t-expr f-expr) (let ([test-result (Bool-test-result (interp test env))]) (type-case Boolen test-result [True () (interp t-expr env)] [False () (interp f-expr env)]))] [Test (mktest f-test t-test) (test-handle mktest (interp f-test env) (interp t-test env))] [else (calcu-handle expr env)]))
;;----interp hepler---- (define (calcu-handle [expr : Expr] [env : Env]) : Value (type-case Expr expr [Add (l r) (calculate + (interp l env) (interp r env))] [Sub (l r) (calculate - (interp l env) (interp r env))] [Mul (l r) (calculate * (interp l env) (interp r env))] [Div (l r) (calculate / (interp l env) (interp r env))] [else (error 'calcu-handle "operater error!")]))
(define (calculate fun [l : Value] [r : Value]) : Value (cond [(and (NmbV? l) (NmbV? r)) (NmbV (fun (NmbV-n l) (NmbV-n r)))] [else (error 'caculate "One of input isn`t number!")]))
(define (test-handle [mktest : symbol] [l-value : Value] [r-value : Value]) : Value (case mktest ((=) (if (= (NmbV-n l-value) (NmbV-n r-value)) (Bool (True)) (Bool (False)))) ((>) (if (> (NmbV-n l-value) (NmbV-n r-value)) (Bool (True)) (Bool (False)))) ((<) (if (< (NmbV-n l-value) (NmbV-n r-value)) (Bool (True)) (Bool (False))))))
;;---------------------Out Expression------------------------ (define (devalue [value : Value]) : s-expression (type-case Value value [NmbV (n) (number->s-exp n)] [Bool (boolen) (type-case Boolen boolen [True () (symbol->s-exp 'True)] [False () (symbol->s-exp 'False)])] [Closure (para body env) `(lambda ,(symbol->s-exp para) ,(deprase body) Env: < ,(deenv env) >)])) (define (deenv [env : Env]) : s-expression (cond [(empty? env) '()] [else `((let ([bind (first env)]) `(,(symbol->s-exp (Bind-idf bind)) ,(devalue (Bind-value bind)))) (deenv (rest env)))]))
(define (deprase [expr : Expr]) : s-expression (cond [(Idf? expr) (symbol->s-exp (Idf-e expr))] [(Lambda? expr) `(lambda ,(symbol->s-exp (Lambda-para expr)) ,(deprase (Lambda-body expr)))] [else `(,(deprase (Apply-fun expr)) ,(deprase (Apply-argu expr)))]))
;;;Ohhh! finally it works!!! (define (eval [s-expr : s-expression]) : s-expression (devalue (interp (desuger (prase s-expr)) globle-env)))
|
近期评论