-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathopsig.m
277 lines (265 loc) · 8.36 KB
/
opsig.m
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
export Opsig
const opsig <- class Opsig (Tree) [xxname : Ident, xxparams : Tree, xxresults : Tree, xxwhere : Tree]
class export operation literal [ln : Integer, xxname : Ident, pn : Ident, pt : Tree, rn : Ident, rt : Tree] -> [r : OpSigType]
var pl, rl : Tree
if pn !== nil then
pl <- seq.singleton[param.create[ln, Sym.create[ln, pn], pt.copy[0]]]
end if
if rn !== nil then
rl <- seq.singleton[param.create[ln, Sym.create[ln, pn], pt.copy[0]]]
end if
r <- self.create[ln, xxname, pl, rl, nil]
end literal
field isFunction : Boolean <- false
field mustBeCompilerExecuted : Boolean <- false
field name : Ident <- xxname
field params : Tree <- xxparams
field results : Tree <- xxresults
field xwhere : Tree <- xxwhere
field st : SymbolTable
export function upperbound -> [r : Integer]
r <- 2
end upperbound
export function getElement [i : Integer] -> [r : Tree]
if i = 0 then
r <- params
elseif i = 1 then
r <- results
elseif i = 2 then
r <- xwhere
end if
end getElement
export operation setElement [i : Integer, r : Tree]
if i = 0 then
params <- r
elseif i = 1 then
results <- r
elseif i = 2 then
xwhere <- r
end if
end setElement
export operation copy [i : Integer] -> [r : Tree]
var nparams, nresults, nxwhere : Tree
if params !== nil then nparams <- params.copy[i] end if
if results !== nil then nresults <- results.copy[i] end if
if xwhere !== nil then nxwhere <- xwhere.copy[i] end if
const realr <- opsig.create[ln, name, nparams, nresults, nxwhere]
realr$isFunction <- isFunction
realr$mustBeCompilerExecuted <- mustBeCompilerExecuted
r <- realr
end copy
operation initTypeVariable [psym : Symbol]
if !psym$isTypeVariable then
psym$isTypeVariable <- true
if psym$value == nil then
const tcopy : Tree <-
Environment$env$atlit.create[
self$ln,
Literal.StringL[0, "junk"],
sym.create[self$ln,
Environment$Env$ITable.Lookup["whocares", 999]],
seq.create[self$ln]
]
(view tcopy as typeobject t operation setIsTypeVariable[Boolean] end t)$isTypeVariable <- true
psym$value <- tcopy
end if
end if
end initTypeVariable
export operation findManifests -> [changed : Boolean]
changed <- false
if params !== nil then
for i : Integer <- 0 while i < params.upperbound by i <- i + 1
const psym : Symbol <- (view (view params[i] as Param)$xsym as Sym)$mysym
if !psym$isTypeVariable then
for j : Integer <- i + 1 while j <= params.upperbound by j <- j + 1
const t : Tree <- (view params[j] as Param)$xtype
if nameof t = "asym" then
const tsym : Symbol <- (view t as Sym)$mysym
if psym == tsym then
self.initTypeVariable[psym]
changed <- true
end if
end if
end for
if results !== nil then
for j : Integer <- 0 while j <= results.upperbound by j <- j + 1
const t : Tree <- (view results[j] as Param)$xtype
if nameof t = "asym" then
const tsym : Symbol <- (view t as Sym)$mysym
if psym == tsym then
self.initTypeVariable[psym]
changed <- true
end if
end if
end for
end if
end if
end for
end if
changed <- changed | FTree.findManifests[self]
end findManifests
export operation isInDefinition
% Make sure that each parameter and result has a name
if params !== nil then
for i : Integer <- 0 while i <= params.upperbound by i <- i + 1
const p <- view params[i] as Param
if p$xsym == nil then
Environment$env.SemanticError[ln, "Parameter %d needs a name", { i + 1}]
end if
end for
end if
if results !== nil then
for i : Integer <- 0 while i <= results.upperbound by i <- i + 1
const p <- view results[i] as Param
if p$xsym == nil then
Environment$env.SemanticError[ln, "Result %d needs a name", { i + 1}]
end if
end for
end if
end isInDefinition
export operation defineSymbols[pst : SymbolTable]
% Check restrictions on functions
%
if isFunction and self$nress != 1 then
Environment$env.SemanticError[ln, "Function must return 1 result, not %d", {self$nress}]
end if
if pst$context != COpDef then
st <- SymbolTable.create[pst, COpSig]
st$myTree <- self
else
st <- pst
end if
if params !== nil then
st$kind <- SParam
params.defineSymbols[st]
end if
if results !== nil then
st$kind <- SResult
results.defineSymbols[st]
end if
if xwhere !== nil then
for i : Integer <- 0 while i <= xwhere.upperbound by i <- i + 1
const X <- typeobject hasNeedsToBeCompilerExecuted
function getNeedsToBeCompilerExecuted -> [Boolean]
end hasNeedsToBeCompilerExecuted
const awhere <- view xwhere[i] as X
if awhere$needsToBeCompilerExecuted then
self$mustBeCompilerExecuted <- true
exit
end if
end for
xwhere.defineSymbols[st]
end if
end defineSymbols
export operation getNArgs -> [r : Integer]
if params == nil then
r <- 0
else
r <- params.upperbound + 1
end if
end getNArgs
export operation getNRess -> [r : Integer]
if results == nil then
r <- 0
else
r <- results.upperbound + 1
end if
end getNRess
export operation resolveSymbols [pst : SymbolTable, nexp : Integer]
FTree.resolveSymbols[self$st, self, 0]
end resolveSymbols
export operation generate [ct : Printable]
const par <- self$params
const res <- self$results
var nameasstring : String <- name$name
const ctname <- nameof ct
const env : EnvironmentType <- Environment$env
if ctname = "abytecode" then
if env$useAbCons and par !== nil then
par.generate[ct]
end if
if res !== nil then res.generate[ct] end if
elseif ctname = "anopvectore" then
const opve <- view ct as OpVectorE
opve$name <- nameasstring
if par == nil then
nameasstring <- nameasstring || "@0"
else
opve$nargs <- par.upperbound + 1
nameasstring <- nameasstring || "@" || (par.upperbound + 1).asString
end if
if res !== nil then
opve$nress <- res.upperbound + 1
end if
nameasstring <- nameasstring || "@" || opve$nress.asString
opve$id <- opnametooid.Lookup[nameasstring]
elseif ctname = "anatcode" then
% build an entry in the op vector ct.ops for me
const ctasat <- view ct as ATCode
const ops <- ctasat$ops
const ove : ATOpVectorE <- ATOpVectorE.create[nameasstring]
ops.addUpper[ove]
ove$isFunction <- self$isFunction
if par == nil then
nameasstring <- nameasstring || "@0"
else
nameasstring <- nameasstring || "@" || (par.upperbound + 1).asString
end if
if res == nil then
nameasstring <- nameasstring || "@0"
else
nameasstring <- nameasstring || "@" || (res.upperbound + 1).asString
end if
ove$id <- opnametooid.Lookup[nameasstring]
if par !== nil then
const limit <- par.upperbound
ove$Arguments <- ATTypeVector.create
for i : Integer <- 0 while i <= limit by i<-i+1
const t <- par[i].asType
if t !== nil then
const r <- view t as hasID
if env$traceassignTypes then
env.printf["Found a thing %S with id %x\n", { r, r$id }]
end if
ove$arguments.addUpper[RefByID.create[r$id]]
else
if env$traceassignTypes then
env.printf["Found a thing %S whose astype is nil\n", {par[i]}]
end if
ove$arguments.addUpper[nil]
end if
end for
end if
if res !== nil then
const limit <- res.upperbound
ove$Results <- ATTypeVector.create
for i : Integer <- 0 while i <= limit by i<-i+1
const t <- res[i].asType
if t !== nil then
const r <- view t as hasID
if env$traceassigntypes then
env.printf["Found a thing %S with id %x\n", { r, r$id }]
end if
ove$results.addUpper[RefByID.create[r$id]]
else
if env$traceassignTypes then
env.printf["Found a thing %S whose astype is nil\n", {res[i]}]
end if
ove$results.addUpper[nil]
end if
end for
end if
end if
end generate
export function same [o : Tree] -> [r : Boolean]
r <- false
if nameof o = "anopsig" then
const oo <- view o as OpSig
r <- self$name$name = oo$name$name and
(self$nargs = oo$nargs or self$name$name = "create")
end if
end same
export function asString -> [r : String]
r <- "opsig"
end asString
end Opsig