Skip to content

Commit 2f06214

Browse files
committed
A stack-based interpreter; useful for checking stack overflow in interpreter.
1 parent 27dd4b3 commit 2f06214

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#lang racket
2+
(require "ast.rkt"
3+
(prefix-in % "interp-prims.rkt"))
4+
(provide interp-prim1 interp-prim2 interp-prim3)
5+
6+
;; Op1 Value -> Answer
7+
(define (interp-prim1 p1 v) (%interp-prim1 p1 v))
8+
9+
;; Op2 Value Stack -> Answer
10+
(define (interp-prim2 p v2 s)
11+
(%interp-prim2 p (first s) v2))
12+
13+
;; Op3 Value Stack -> Answer
14+
(define (interp-prim3 p v3 s)
15+
(%interp-prim3 p (second s) (first s) v3))

langs/iniquity/interp-stack.rkt

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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

Comments
 (0)