-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathifclause.m
139 lines (123 loc) · 3.43 KB
/
ifclause.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
export Ifclause
const ifclause <- class Ifclause (Tree) [xxexp : Tree, xxstats : Tree]
field exp : Tree <- xxexp
field stats : Tree <- xxstats
field st : SymbolTable
export function upperbound -> [r : Integer]
r <- 1
end upperbound
export function getElement [i : Integer] -> [r : Tree]
if i = 0 then
r <- exp
elseif i = 1 then
r <- stats
end if
end getElement
export operation setElement [i : Integer, r : Tree]
if i = 0 then
exp <- r
elseif i = 1 then
stats <- r
end if
end setElement
export operation copy [i : Integer] -> [r : Tree]
var nexp, nstats : Tree
if exp !== nil then nexp <- exp.copy[i] end if
if stats !== nil then nstats <- stats.copy[i] end if
r <- ifclause.create[ln, nexp, nstats]
end copy
export operation flatten [ininvoke : Boolean, indecls : Tree] -> [r : Tree, outdecls : Tree]
var decls : Tree
var val : Tree
assert !ininvoke
val, decls <- exp.flatten[ininvoke, nil]
if decls !== nil then
exp <- Eblock.create[ln, decls, val]
else
assert val == exp
end if
outdecls <- indecls
r <- self
end flatten
export operation shouldUseCase [xsym :Symbol, min : Integer, max : Integer]
-> [r : Boolean, nsymb : Symbol, s : Sym, nmin : Integer, nmax : Integer, val : Integer]
r <- false
if nameof exp = "aninvoc" then
const i <- view exp as Invoc
const t <- i$target
const o <- i$xopname
const a <- i$args
var arg : Tree
var str, argstr : String
% Check the target
if nameof t = "asym" then
s <- view t as Sym
if xsym == nil then
nsymb <- s$mysym
else
nsymb <- xsym
end if
if s$mysym !== nsymb then return end if
else
return
end if
% check the opname
if o$name != "=" then return end if
% check the args
if a.upperbound != 0 then return end if
arg <- a[0]
if nameof arg = "anarg" then arg <- arg[0] end if
argstr <- nameof arg
if argstr != "aliteral" then return end if
const asLiteral <- (view arg as Literal)
const index <- asLiteral$index
const valstr <- asLiteral$str
if index = IntegerIndex then
val <- Integer.literal[valstr]
elseif index = CharacterIndex then
val <- valstr[0].ord
else
return
end if
if min == nil or val < min then
nmin <- val
else
nmin <- min
end if
if max == nil or val > max then
nmax <- val
else
nmax <- max
end if
r <- true
else
return
end if
end shouldUseCase
export operation defineSymbols[pst : SymbolTable]
self$exp.defineSymbols[pst]
self$st <- SymbolTable.create[pst, CBlock]
self$st$myTree <- self
self$stats.defineSymbols[self$st]
end defineSymbols
export operation resolveSymbols [pst : SymbolTable, nexp : Integer]
self$exp.resolveSymbols[self$st, 1]
self$stats.resolveSymbols[self$st, 0]
end resolveSymbols
export operation typeCheck
const booleantype <- (view BuiltinLit.findTree[0x1003, nil] as hasInstAT).getInstAT.asType
var t : hasConforms
t <- view exp.getAT as hasConforms
if t !== nil then t <- view t.asType as hasConforms end if
if t == nil then
Environment$env.ttypecheck["No type for if clause on %d\n",
{ exp$ln }]
elseif !t.conformsTo[exp$ln, booleantype] then
Environment$env.SemanticError[exp$ln, "boolean required", nil]
end if
FTree.typeCheck[self]
end typeCheck
export function asString -> [r : String]
r <- "ifclause"
end asString
end Ifclause