-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathast.rkt
146 lines (127 loc) · 4.12 KB
/
ast.rkt
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
#lang racket/base
;; (provide node/app node/prim node/foreign node/var node/lambda node/immediate type/arrow)
(require racket/generic)
(provide (all-defined-out))
(module+ test
(require rackunit))
(define-generics node
[typeof node]
[set-type! node new-type])
;; Known AST node types:
;; - app (application)
;; - prim (primitive operation)
;; - foreign (foreign function---look up in db for definition)
;; - var (variable reference)
;; - lambda (lambda function)
;; - let
;;
;; Observable types: (these are the names used in the program)
;; - integer
;; - boolean
;; - character
;;
;; Opaque types:
;; - (function (arg-type ...) return-type)
#;(define-syntax defnode
(syntax-rules ()
[(defnode name (fields ...))
(struct node/name
(type fields ...)
#:mutable #:transparent
#:methods gen:node
;; Foo... how do I do this part? I don't know how to build up symbols and intern them
)]))
;; Labels declaration
(struct node/labels
(type lvars body)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/labels-type node))
(define (set-type! node new-type) (set-node/labels-type! node new-type))])
;; Label-variable (a symbol -> (code (param ...) (free-var ...) expr) mapping)
(struct node/lvar
(type name params free-vars body)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/labels-type node))
(define (set-type! node new-type) (set-node/labels-type! node new-type))])
;; Function application
(struct node/app
(type func args)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/app-type node))
(define (set-type! node new-type) (set-node/app-type! node new-type))])
;; Primitive operation
(struct node/prim
(type name arity args)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/prim-type node))
(define (set-type! node new-type) (set-node/prim-type! node new-type))])
;; Foreign function call
(struct node/foreign
(type name arity args)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/foreign-type node))
(define (set-type! node new-type) (set-node/foreign-type! node new-type))])
;; Variable reference
(struct node/var
(type name)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/var-type node))
(define (set-type! node new-type) (set-node/var-type! node new-type))])
(struct node/if
(type condition t-case f-case)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/if-type node))
(define (set-type! node new-type) (set-node/if-type! node new-type))])
(struct node/let
(type bindings body)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/let-type node))
(define (set-type! node new-type) (set-node/let-type! node new-type))])
(struct node/let-binding
(type variable value)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/let-binding-type node))
(define (set-type! node new-type) (set-node/let-binding-type! node new-type))])
;; Closure context
(struct node/closure
(type fun-label var-bindings)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/closure-type node))
(define (set-type! node new-type) (set-node/closure-type! node new-type))])
;; A lambda
(struct node/lambda
(type params body)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/lambda-type node))
(define (set-type! node new-type) (set-node/lambda-type! node new-type))])
;; Immediate values: integers, string litterals, etc.
(struct node/immediate
(type value)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/immediate-type node))
(define (set-type! node new-type) (set-node/immediate-type! node new-type))])
;; Type annotation
(struct node/ann
(type value)
#:mutable #:transparent
#:methods gen:node
[(define (typeof node) (node/ann-type node))
(define (set-type! node new-type) (set-node/ann-type! node new-type))])
(struct type/observable
(name))
;; Arrow type
(struct type/arrow
(params body [name #:auto])
#:mutable #:transparent #:auto-value 'arrow)