|
| 1 | +#lang racket |
| 2 | +(provide interp interp-env) |
| 3 | +(require "ast.rkt" |
| 4 | + "env.rkt" |
| 5 | + "interp-prims-stack.rkt" |
| 6 | + "max-stack.rkt") |
| 7 | + |
| 8 | +(define *stack-limit* 10000) |
| 9 | + |
| 10 | +;; type Answer = Value | 'err |
| 11 | + |
| 12 | +;; type Value = |
| 13 | +;; | Integer |
| 14 | +;; | Boolean |
| 15 | +;; | Character |
| 16 | +;; | Eof |
| 17 | +;; | Void |
| 18 | +;; | '() |
| 19 | +;; | (cons Value Value) |
| 20 | +;; | (box Value) |
| 21 | +;; | (vector Value ...) |
| 22 | +;; | (string Char ...) |
| 23 | + |
| 24 | +;; type CEnv = (Listof Id) |
| 25 | +;; type Stack = (Listof Value) |
| 26 | +;; type Defns = (Listof Defn) |
| 27 | + |
| 28 | +;; Prog -> Answer |
| 29 | +(define (interp p) |
| 30 | + (match p |
| 31 | + [(Prog ds e) |
| 32 | + (if (>= (max-stack e) *stack-limit*) |
| 33 | + 'err |
| 34 | + (interp-env e '() ds '()))])) |
| 35 | + |
| 36 | +(define (lookup-address r x) |
| 37 | + (match r |
| 38 | + ['() (error "unbound variable")] |
| 39 | + [(cons y r) |
| 40 | + (if (eq? x y) |
| 41 | + 0 |
| 42 | + (add1 (lookup-address r x)))])) |
| 43 | + |
| 44 | +;; Expr CEnv Defns Stack -> Answer |
| 45 | +(define (interp-env e r ds s) |
| 46 | + (printf "stack: ~a~n" s) |
| 47 | + (match e |
| 48 | + [(Int i) i] |
| 49 | + [(Bool b) b] |
| 50 | + [(Char c) c] |
| 51 | + [(Eof) eof] |
| 52 | + [(Empty) '()] |
| 53 | + [(Var x) (list-ref s (lookup-address r x))] |
| 54 | + [(Str s) s] |
| 55 | + [(Prim0 'void) (void)] |
| 56 | + [(Prim0 'read-byte) (read-byte)] |
| 57 | + [(Prim0 'peek-byte) (peek-byte)] |
| 58 | + [(Prim1 p e) |
| 59 | + (match (interp-env e r ds s) |
| 60 | + ['err 'err] |
| 61 | + [v (interp-prim1 p v)])] |
| 62 | + [(Prim2 p e1 e2) |
| 63 | + (match (interp-env e1 r ds s) |
| 64 | + ['err 'err] |
| 65 | + [v1 (match (interp-env e2 (cons #f r) ds (cons v1 s)) |
| 66 | + ['err 'err] |
| 67 | + [v2 (interp-prim2 p v2 (cons v1 s))])])] |
| 68 | + [(Prim3 p e1 e2 e3) |
| 69 | + (match (interp-env e1 r ds s) |
| 70 | + ['err 'err] |
| 71 | + [v1 (match (interp-env e2 (cons #f r) ds (cons v1 s)) |
| 72 | + ['err 'err] |
| 73 | + [v2 (match (interp-env e3 (cons #f (cons #f r)) ds (cons v2 (cons v1 s))) |
| 74 | + ['err 'err] |
| 75 | + [v3 (interp-prim3 p v3 (cons v2 (cons v1 s)))])])])] |
| 76 | + [(If p e1 e2) |
| 77 | + (match (interp-env p r ds s) |
| 78 | + ['err 'err] |
| 79 | + [v |
| 80 | + (if v |
| 81 | + (interp-env e1 r ds s) |
| 82 | + (interp-env e2 r ds s))])] |
| 83 | + [(Begin e1 e2) |
| 84 | + (match (interp-env e1 r ds s) |
| 85 | + ['err 'err] |
| 86 | + [_ (interp-env e2 r ds s)])] |
| 87 | + [(Let x e1 e2) |
| 88 | + (match (interp-env e1 r ds s) |
| 89 | + ['err 'err] |
| 90 | + [v (interp-env e2 (cons x r) ds (cons v s))])] |
| 91 | + [(App f es) |
| 92 | + (match (interp-env* es (cons #f r) ds (cons 'return s)) |
| 93 | + ['err 'err] |
| 94 | + [vs |
| 95 | + (match (defns-lookup ds f) |
| 96 | + [(Defn f xs e) |
| 97 | + ; check arity matches |
| 98 | + (if (= (length xs) (length es)) |
| 99 | + (begin (printf "~a\n" (+ (length (append (cons #f vs) s)) (max-stack e))) |
| 100 | + (if (>= (+ (length (append (cons #f vs) s)) (max-stack e)) *stack-limit*) |
| 101 | + 'err |
| 102 | + (interp-env e xs ds (append vs (list 'return) s)))) |
| 103 | + 'err)])])])) |
| 104 | + |
| 105 | +;; (Listof Expr) CEnv Defns Stack -> Stack | 'err |
| 106 | +(define (interp-env* es r ds s) |
| 107 | + (match es |
| 108 | + ['() '()] |
| 109 | + [(cons e es) |
| 110 | + (match (interp-env e r ds s) |
| 111 | + ['err 'err] |
| 112 | + [v (match (interp-env* es (cons #f r) ds (cons v s)) |
| 113 | + ['err 'err] |
| 114 | + [vs (cons v vs)])])])) |
| 115 | + |
| 116 | +;; Defns Symbol -> Defn |
| 117 | +(define (defns-lookup ds f) |
| 118 | + (findf (match-lambda [(Defn g _ _) (eq? f g)]) |
| 119 | + ds)) |
| 120 | + |
| 121 | +(define (zip xs ys) |
| 122 | + (match* (xs ys) |
| 123 | + [('() '()) '()] |
| 124 | + [((cons x xs) (cons y ys)) |
| 125 | + (cons (list x y) |
| 126 | + (zip xs ys))])) |
0 commit comments