-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsyntax.rb
More file actions
239 lines (188 loc) · 3.21 KB
/
Copy pathsyntax.rb
File metadata and controls
239 lines (188 loc) · 3.21 KB
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
RESERVED = {
'if' => :IF,'else' => :ELSE,'then' => :THEN,'true' => :TRUE,'false' => :FALSE, 'fix' => :FIX,
'let' => :LET,'in' => :IN,'fun' => :FUN,"->" => :ARROW,"(" => :LPAREN,")" => :RPAREN,
"=" => :EQ, "+" => :PLUS, "-" => :MINUS, "*" => :MULT,"\/" => :div,
"<" => :LT, ">" => :GT
}
RESERVED_V = {
'true' => true,
'false' => false,
'nil' => nil
}
class Exp
end
class Binexp < Exp
attr_accessor :binop,:exp1,:exp2
def initialize(binop,exp1,exp2)
@binop = binop
@exp1 = exp1
@exp2 = exp2
end
end
class Ifexp < Exp
attr_accessor :cond,:exp1,:exp2
def initialize(cond,exp1,exp2)
@cond = cond
@exp1 = exp1
@exp2 = exp2
end
end
class Funexp < Exp
attr_accessor :id,:exp
def initialize(id,exp)
@id = id
@exp = exp
end
end
class Appexp < Exp
attr_accessor :exp1,:exp2
def initialize(exp1,exp2)
@exp1 = exp1
@exp2 = exp2
end
end
class Letexp < Exp
attr_accessor :id,:exp1,:exp2
def initialize(id,exp1,exp2)
@id = id
@exp1 = exp1
@exp2 = exp2
end
end
class Exval < Exp
attr_accessor :val
def initialize(val)
@val = val
end
end
class IntV < Exval
end
class BoolV < Exval
end
class ProcV < Exval
attr_accessor :id, :exp, :dnval
def initialize(id,exp,dnval)
@id = id
@exp = exp
@dnval = dnval
end
def to_s
"<fun>"
end
def changeDnval(exp)
@dnval = exp
end
end
class Fixexp < Exp
attr_accessor :id1,:id2,:exp1,:exp2
def initialize(id1,id2,exp1,exp2)
@id1 = id1
@id2 = id2
@exp1 = exp1
@exp2 = exp2
end
end
class Decl
attr_accessor :id,:exp
def initialize(id,exp)
@id = id
@exp = exp
end
end
class Fixdecl
attr_accessor :id1,:id2,:exp
def initialize(id1,id2,exp)
@id1 = id1
@id2 = id2
@exp = exp
end
end
class Typescheme
attr_accessor :tyvarls, :ty
def initialize(ls,type)
@tyvarls = ls
@ty = type
end
def freevar
ftv =getFreshTyvar(@type)
ftv ? ftv - @tyvarls : []
end
def iseq(type)
@tyvarls == type.tyvarls && @ty == type.ty
end
end
class Type < Typescheme
def type
self.class
end
def iseq(type2)
case self
when Tyint
Tyint === type2
when Tybool
Tybool === type2
when Tyvar
Tyvar === type2 && self.tyvar == type2.tyvar
when Tyfun
Tyfun === type2 && self.pty.iseq(type2.pty) && self.rty.iseq(type2.rty)
else false
end
end
end
class Tyint < Type
def initialize
end
def display
return "int"
end
end
class Tybool < Type
def initialize
end
def display
return "bool"
end
end
class Tyvar < Type
attr_accessor :tyvar
def initialize(num)
@tyvar = num
end
def display
@tyvar
end
end
class Tyfun < Type
attr_accessor :pty,:rty
def initialize(pty,rty)
@pty = pty
@rty = rty
end
def display
"(#{pty.display} -> #{rty.display})"
end
end
$counter = 0
def fresh
$counter = $counter + 1
end
def getFreshTyvar(type)
case type
when Tyint,Tybool
[]
when Tyfun
([getFreshTyvar(type.pty)] + [getFreshTyvar(type.rty)]).flatten
when Tyvar
[type.tyvar]
end
end
def subset(g1,g2)
copy = g2
g1.each do |e|
copy.reject!{|item| e.iseq(item)}
return copy
end
end
def tyscOf(ty)
Typescheme.new([],ty)
end