Skip to content

Commit 6a86bb8

Browse files
committed
WIP: Loot with new AST
Things left TODO: * Rewrite the defunctionalization in terms of the AST * Allow arbitrary 'begin in the program (currently we only support top-level begin)
1 parent 8b2f85d commit 6a86bb8

8 files changed

Lines changed: 432 additions & 208 deletions

File tree

www/notes/loot/ast.rkt

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#lang racket
2+
(provide (all-defined-out))
3+
4+
;; type Prog = [FunDef] Expr
5+
6+
;; type FunDef = Variable [Variable] Expr
7+
8+
;; type Expr =
9+
;; | Integer
10+
;; | Boolean
11+
;; | Character
12+
;; | Variable
13+
;; | Prim1 Expr
14+
;; | Prim2 Expr Expr
15+
;; | Lam Name [Variable] Expr <--- New for Loot
16+
;; | App Expr [Expr] <--- Changed for Loot
17+
;; | If Expr Expr Expr
18+
;; | Let (Binding list) Expr
19+
;; | LetRec (Binding list) Expr <--- New for Loot (See the lecture notes!)
20+
;; | Nil
21+
22+
;; Note: Fun and Call, from Knock, are gone!
23+
;; They have been made redundant by the combination
24+
;; of Lam (which is new) and App (which has been modified)
25+
26+
;; type Prim1 = 'add1 | 'sub1 | 'zero? | box | unbox | car | cdr
27+
;; type Prim2 = '+ | '- | cons
28+
29+
;; type Binding = Variable Expr
30+
31+
;; type Variable = Symbol (except 'add1 'sub1 'if, etc.)
32+
33+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
34+
;;;;;; The represenation of top-level programs
35+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
36+
37+
(struct prog (ds e) #:transparent)
38+
39+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
40+
;;;;;; The represenation of a function definition
41+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
42+
43+
;; A FunDef has a symbol for the function's name,
44+
;; a list of symbols representing the names of the function's
45+
;; arguments, and one expression that forms the body of the function.
46+
(struct fundef (name args body) #:transparent)
47+
48+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
49+
;;;;;; The Expr data structure
50+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
51+
52+
;; An Expr can be viewed as having 'kinds' of nodes.
53+
;;
54+
;; * The nodes that represnt an expression themselves
55+
;;
56+
;; * The nodes that are part of an expression, but no an expression themselves
57+
58+
;; The below are the former:
59+
60+
(struct int-e (i) #:transparent)
61+
(struct bool-e (b) #:transparent)
62+
(struct char-e (c) #:transparent)
63+
(struct var-e (v) #:transparent)
64+
(struct prim-e (p es) #:transparent)
65+
(struct lam-e (vs es) #:transparent) ; <- new for Loot
66+
(struct lam-t (n vs es) #:transparent) ; <- new for Loot (for when we tag the lambdas)
67+
(struct app-e (f es) #:transparent) ; <- changed for Loot
68+
(struct if-e (e t f) #:transparent)
69+
(struct let-e (bs b) #:transparent)
70+
(struct letr-e (bs b) #:transparent) ; <- new for Loot
71+
(struct nil-e () #:transparent)
72+
73+
;; The next is the latter:
74+
75+
;; A binding holds a symbol representing the bound variable and
76+
;; Expr that represents the value that will be bound to that variable
77+
(struct binding (v e) #:transparent)
78+
79+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
80+
;;;;;; AST utility functions (predicates)
81+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
82+
83+
(define unops '(add1 sub1 zero? box unbox empty? car cdr))
84+
(define biops '(+ - cons))
85+
86+
;; Any -> Boolean
87+
(define (prim? x)
88+
(and (symbol? x)
89+
(memq x (append unops biops))))
90+
91+
;; Any -> Boolean
92+
(define (biop? x)
93+
(and (symbol? x)
94+
(memq x biops)))
95+
96+
;; Any -> Boolean
97+
(define (unop? x)
98+
(and (symbol? x)
99+
(memq x unops)))
100+
101+
(define (value? v)
102+
(or (int-e? v)
103+
(bool-e? v)))
104+
105+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
106+
;;;;;; AST utility functions (getters)
107+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
108+
109+
;; It will sometimes be useful to get the list of all the variables that are
110+
;; introduced by a `let`
111+
;; [Binding] -> [Symbol]
112+
(define (get-vars bs)
113+
(match bs
114+
['() '()]
115+
[(cons (binding v _) bs) (cons v (get-vars bs))]))
116+
117+
;; Get all of the _definitions_ from a list of bindings
118+
;; [Binding] -> [Expr]
119+
(define (get-defs bs)
120+
(match bs
121+
['() '()]
122+
[(cons (binding _ def) bs) (cons def (get-defs bs))]))
123+
124+
125+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
126+
;;;;;; AST utility functions (maps)
127+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
128+
129+
(define (bindings-map-def f bs)
130+
(match bs
131+
['() '()]
132+
[(cons (binding n def) bs)
133+
(cons (binding n (f def)) (bindings-map-def f bs))]))
134+
135+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
136+
;;;;;; AST utility functions (printers)
137+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
138+
139+
;; We have switched to using `#:transparent` above, so this should only be
140+
;; necessary if you're desperate when debugging :'(
141+
142+
;; Given a Program, construct an sexpr that has the same shape
143+
(define (prog-debug p)
144+
(match p
145+
[(prog ds e) `(prog ,(map fundef-debug ds) ,(ast-debug e))]))
146+
147+
;; Given a FunDef, construct an sexpr that has the same shape
148+
(define (fundef-debug def)
149+
(match def
150+
[(fundef name args body) `(fundef ,name ,args ,(ast-debug body))]))
151+
152+
;; Given an AST, construct an sexpr that has the same shape
153+
(define (ast-debug a)
154+
(match a
155+
[(int-e i) `(int-e ,i)]
156+
[(bool-e b) `(bool-e ,b)]
157+
[(char-e c) `(char-e ,c)]
158+
[(var-e v) `(var-e ,v)]
159+
[(nil-e) ''()]
160+
[(prim-e p es) `(prim-e ,p ,@(map ast-debug es))]
161+
[(lam-t n vs e)`(lam-t ,n ,vs ,(ast-debug e))]
162+
[(lam-e vs e) `(lam-e ,vs ,(ast-debug e))]
163+
[(app-e f es) `(app-e ,(ast-debug f) ,@(map ast-debug es))]
164+
[(if-e e t f) `(if-e ,(ast-debug e)
165+
,(ast-debug t)
166+
,(ast-debug f))]
167+
[(let-e bs b) `(let-e ,(binding-debug bs) ,(ast-debug b))]
168+
[(letr-e bs b) `(letr-e ,(binding-debug bs) ,(ast-debug b))]))
169+
170+
(define (binding-debug bnds)
171+
(match bnds
172+
['() '()]
173+
[(cons (binding v e) bnds) `((,v ,(ast-debug e)) ,@(binding-debug bnds))]))

www/notes/loot/compile-file.rkt

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
#lang racket
22
(provide (all-defined-out))
3-
(require "compile.rkt" #;"syntax.rkt" "asm/printer.rkt")
3+
(require "compile.rkt" "syntax.rkt" "asm/printer.rkt")
44

55
;; String -> Void
66
;; Compile contents of given file name,
77
;; emit asm code on stdout
88
(define (main fn)
99
(with-input-from-file fn
1010
(λ ()
11-
(let ((p (read-program)))
12-
; assumed OK for now
13-
;(unless (and (prog? p) (closed? p))
14-
; (error "syntax error"))
15-
(asm-display (compile p))))))
16-
17-
(define (read-program)
18-
(regexp-match "^#lang racket" (current-input-port))
19-
(read))
11+
(let ((c (read-line))
12+
(p (read)))
13+
(asm-display (compile (sexpr->prog p)))))))

0 commit comments

Comments
 (0)