sardonyx 0.1.843 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/sdx +43 -19
- data/lib/sdx/compiler/parser.rb +297 -119
- data/lib/sdx/vm/datatypes.rb +0 -2
- data/lib/sdx/vm/scope.rb +1 -2
- data/lib/sdx/vm/vm.rb +50 -35
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a47addbe2b460c689ce05c124e596fef8a63d8c9c90eb7338144d34a5932bc69
|
|
4
|
+
data.tar.gz: 7699f23fe1516749a0086df90f5ca7056339ff1f4a229c6cf8d31d260ba238af
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f69b3a81744ab1b790c6d9f327a8e07ab55045af74c2bc852418c124e6651b8fea663c4d9b163f7eb4b7792c07678f7fa0b6c372bacdcc53fbed901a628315e
|
|
7
|
+
data.tar.gz: 3c0ec1b0ffe241e2996069bba3edf81a50c92e8d821397a430ca2a5edc59e57716a2c52b0f12ab8774962d0a7a539b257cf5f6ed01ecf86b44286fcfab745f6e
|
data/bin/sdx
CHANGED
|
@@ -3,33 +3,57 @@ require "sdx/compiler/parser"
|
|
|
3
3
|
require "sdx/compiler/compiler"
|
|
4
4
|
require "sdx/vm/vm"
|
|
5
5
|
require "stringio"
|
|
6
|
+
require "readline"
|
|
7
|
+
|
|
8
|
+
if (ENV.fetch("SDX_PATH", "").split ":") == []
|
|
9
|
+
puts "\x1b[0;33mLooks like you don't have anything in your SDX_PATH! You should install the stdlib at https://github.com/SardonyxLang/SardonyxStd.\x1b[0;0m"
|
|
10
|
+
end
|
|
6
11
|
|
|
7
12
|
if ARGV.size == 1
|
|
8
13
|
path = [(File.expand_path File.dirname ARGV[0]), *(ENV.fetch("SDX_PATH", "").split ":")]
|
|
9
14
|
code = File.read ARGV[0]
|
|
10
|
-
lexed = Parser::Lexer.lex code
|
|
11
|
-
ast = Parser::Parser.parse lexed, path
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
lexed, lines = Parser::Lexer.lex code
|
|
16
|
+
ast = Parser::Parser.parse lexed, path, lines
|
|
17
|
+
if State::state == :ok
|
|
18
|
+
bc = Compiler::Compiler.compile ast
|
|
19
|
+
vm = VM.new StringIO.new bc
|
|
20
|
+
vm.interpret
|
|
21
|
+
end
|
|
15
22
|
else
|
|
16
23
|
path = [(File.expand_path Dir.pwd), *(ENV.fetch("SDX_PATH", "").split ":")]
|
|
17
24
|
vm = VM.new StringIO.new ""
|
|
18
|
-
puts "Sardonyx v0.1
|
|
19
|
-
|
|
25
|
+
puts "Sardonyx v0.3.1"
|
|
26
|
+
puts "Type :help for help, or :exit to exit"
|
|
20
27
|
loop do
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
begin
|
|
29
|
+
code = Readline.readline("> ", true)
|
|
30
|
+
rescue Interrupt
|
|
31
|
+
puts "^C"
|
|
32
|
+
code = ""
|
|
33
|
+
end
|
|
34
|
+
unless code
|
|
35
|
+
puts ":exit"
|
|
36
|
+
exit 0
|
|
37
|
+
end
|
|
38
|
+
case code
|
|
39
|
+
when ":exit"
|
|
40
|
+
exit 0
|
|
41
|
+
when ":help"
|
|
42
|
+
puts "See sardonyxlang.github.io/docs for documentation - for now, try entering \"5 + 5\""
|
|
43
|
+
else
|
|
44
|
+
lexed, lines = Parser::Lexer.lex code
|
|
45
|
+
ast = Parser::Parser.parse lexed, path, lines
|
|
46
|
+
if State::state == :ok
|
|
47
|
+
bc = Compiler::Compiler.compile ast
|
|
48
|
+
vm.bc_io = StringIO.new bc
|
|
49
|
+
vm.byte_pos = 0
|
|
50
|
+
vm.interpret false
|
|
51
|
+
val = vm.stack[-1]
|
|
52
|
+
vm.clear
|
|
53
|
+
if val
|
|
54
|
+
puts vm.stringify val
|
|
55
|
+
end
|
|
56
|
+
end
|
|
33
57
|
end
|
|
34
58
|
end
|
|
35
59
|
end
|
data/lib/sdx/compiler/parser.rb
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
|
+
class State
|
|
2
|
+
class << self
|
|
3
|
+
attr_accessor :state
|
|
4
|
+
end
|
|
5
|
+
@@state = :ok
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def error(msg)
|
|
9
|
+
puts "\x1b[0;31mError in parser: #{msg}\x1b[0;0m"
|
|
10
|
+
end
|
|
11
|
+
|
|
1
12
|
module Parser
|
|
13
|
+
|
|
2
14
|
class Lexer
|
|
3
15
|
TOKENS = {
|
|
16
|
+
/\A#.*/ => :comment,
|
|
4
17
|
/\Aif/ => :if,
|
|
5
18
|
/\Aelse/ => :else,
|
|
6
19
|
/\Awhile/ => :while,
|
|
@@ -11,11 +24,12 @@ module Parser
|
|
|
11
24
|
/\Anew/ => :new,
|
|
12
25
|
/\Arequire/ => :require,
|
|
13
26
|
/\A(true|false)/ => :bool,
|
|
14
|
-
/\A(<|>|<=|>=|==|!=)/ => :op,
|
|
15
|
-
/\A(\+|-|\*|\/|%)?=/ => :eq,
|
|
16
|
-
/\A(\+|-|\*|\/|%)/ => :op,
|
|
17
|
-
/\A-?[0-9]+/ => :number,
|
|
18
27
|
/\A-?[0-9]+\.[0-9]+/ => :float,
|
|
28
|
+
/\A-?[0-9]+/ => :number,
|
|
29
|
+
/\A(\+|-)/ => :l1op,
|
|
30
|
+
/\A(\/|\*|%|\^)/ => :l2op,
|
|
31
|
+
/\A(<|>|<=|>=|==|!=)/ => :l1op,
|
|
32
|
+
/\A(\+|-|\*|\/|%)?=/ => :eq,
|
|
19
33
|
/\A"([^"]|\\")*"/ => :string,
|
|
20
34
|
/\Anil/ => :nil,
|
|
21
35
|
/\A\(/ => :lpar,
|
|
@@ -28,25 +42,78 @@ module Parser
|
|
|
28
42
|
/\A[A-Za-z_][A-Za-z0-9_]*([:.][A-Za-z_][A-Za-z0-9_]*)*/ => :name
|
|
29
43
|
}
|
|
30
44
|
|
|
45
|
+
class << self
|
|
46
|
+
attr_accessor :lines
|
|
47
|
+
end
|
|
48
|
+
|
|
31
49
|
def self.lex(code)
|
|
50
|
+
@@lines = code.split "\n"
|
|
32
51
|
lexed = []
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
52
|
+
comment = false
|
|
53
|
+
line = col = 0
|
|
54
|
+
State::state = :ok
|
|
55
|
+
while State::state == :ok and code.size > 0
|
|
56
|
+
while true
|
|
57
|
+
if code.size != 0 and code[0] == "\n"
|
|
58
|
+
col = 0
|
|
59
|
+
line += 1
|
|
60
|
+
code = code[1..-1]
|
|
61
|
+
elsif code.size != 0 and code[0].strip.empty?
|
|
62
|
+
if State::state == :ok
|
|
63
|
+
col += 1
|
|
64
|
+
end
|
|
65
|
+
code = code[1..-1]
|
|
66
|
+
else
|
|
41
67
|
break
|
|
42
68
|
end
|
|
43
|
-
|
|
44
|
-
if !
|
|
45
|
-
|
|
46
|
-
|
|
69
|
+
end
|
|
70
|
+
if !comment && (code.start_with? "#>")
|
|
71
|
+
comment = true
|
|
72
|
+
code = code[2..-1]
|
|
73
|
+
elsif comment && (code.start_with? "<#")
|
|
74
|
+
comment = false
|
|
75
|
+
code = code[2..-1]
|
|
76
|
+
elsif comment
|
|
77
|
+
code = code[1..-1]
|
|
78
|
+
else
|
|
79
|
+
found = false
|
|
80
|
+
TOKENS.each { |re, tag|
|
|
81
|
+
if (code =~ re) != nil
|
|
82
|
+
found = true
|
|
83
|
+
m = (re.match code)
|
|
84
|
+
if tag != :comment
|
|
85
|
+
lexed << [ m[0], tag, line, col ]
|
|
86
|
+
end
|
|
87
|
+
code = code[(m.end 0)..-1]
|
|
88
|
+
col += (m.end 0)
|
|
89
|
+
while true
|
|
90
|
+
if code.size != 0 and code[0] == "\n"
|
|
91
|
+
col = 0
|
|
92
|
+
line += 1
|
|
93
|
+
code = code[1..-1]
|
|
94
|
+
elsif code.size != 0 and code[0].strip.empty?
|
|
95
|
+
if State::state == :ok
|
|
96
|
+
col += 1
|
|
97
|
+
end
|
|
98
|
+
code = code[1..-1]
|
|
99
|
+
else
|
|
100
|
+
break
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
break
|
|
104
|
+
end
|
|
105
|
+
}
|
|
106
|
+
if !found
|
|
107
|
+
error %{
|
|
108
|
+
Invalid code at #{line}:#{col}
|
|
109
|
+
#{" " * line.to_s.size} |
|
|
110
|
+
#{line} | #{@@lines[line].rstrip}
|
|
111
|
+
#{" " * line.to_s.size} | #{" " * col}^ here}
|
|
112
|
+
State::state = :error
|
|
113
|
+
end
|
|
47
114
|
end
|
|
48
115
|
end
|
|
49
|
-
lexed
|
|
116
|
+
[ lexed, @@lines ]
|
|
50
117
|
end
|
|
51
118
|
end
|
|
52
119
|
|
|
@@ -124,13 +191,15 @@ module Parser
|
|
|
124
191
|
|
|
125
192
|
def self.parse_parens(tokens)
|
|
126
193
|
if self.expect tokens, :lpar
|
|
127
|
-
tokens = tokens[1
|
|
128
|
-
|
|
194
|
+
tokens = tokens[1..-1]
|
|
195
|
+
res = self.parse_expr tokens
|
|
196
|
+
unless res
|
|
129
197
|
return nil
|
|
130
198
|
end
|
|
131
199
|
e, part = self.parse_expr tokens
|
|
132
|
-
tokens = tokens[part
|
|
133
|
-
|
|
200
|
+
tokens = tokens[part..-1]
|
|
201
|
+
res = self.expect tokens, :rpar
|
|
202
|
+
unless res
|
|
134
203
|
return nil
|
|
135
204
|
end
|
|
136
205
|
return [e, part + 2]
|
|
@@ -143,7 +212,7 @@ module Parser
|
|
|
143
212
|
unless (self.expect tokens, :lbrack)
|
|
144
213
|
return nil
|
|
145
214
|
end
|
|
146
|
-
tokens = tokens[1
|
|
215
|
+
tokens = tokens[1..-1]
|
|
147
216
|
children = []
|
|
148
217
|
total = 1
|
|
149
218
|
while true
|
|
@@ -151,13 +220,14 @@ module Parser
|
|
|
151
220
|
total += 1
|
|
152
221
|
break
|
|
153
222
|
end
|
|
154
|
-
|
|
223
|
+
res = self.parse_expr tokens
|
|
224
|
+
unless res
|
|
155
225
|
return nil
|
|
156
226
|
end
|
|
157
|
-
e, part =
|
|
227
|
+
e, part = res
|
|
158
228
|
children << e
|
|
159
229
|
total += part
|
|
160
|
-
tokens = tokens[part
|
|
230
|
+
tokens = tokens[part..-1]
|
|
161
231
|
if self.expect tokens, :rbrack
|
|
162
232
|
total += 1
|
|
163
233
|
break
|
|
@@ -166,7 +236,7 @@ module Parser
|
|
|
166
236
|
return nil
|
|
167
237
|
end
|
|
168
238
|
total += 1
|
|
169
|
-
tokens = tokens[1
|
|
239
|
+
tokens = tokens[1..-1]
|
|
170
240
|
end
|
|
171
241
|
[ (Node.new :list, "", children), total ]
|
|
172
242
|
end
|
|
@@ -175,7 +245,7 @@ module Parser
|
|
|
175
245
|
unless (self.expect tokens, :lbrace)
|
|
176
246
|
return nil
|
|
177
247
|
end
|
|
178
|
-
tokens = tokens[1
|
|
248
|
+
tokens = tokens[1..-1]
|
|
179
249
|
children = []
|
|
180
250
|
total = 1
|
|
181
251
|
while true
|
|
@@ -187,7 +257,7 @@ module Parser
|
|
|
187
257
|
if e
|
|
188
258
|
children << e[0]
|
|
189
259
|
total += e[1]
|
|
190
|
-
tokens = tokens[e[1]
|
|
260
|
+
tokens = tokens[e[1]..-1]
|
|
191
261
|
else
|
|
192
262
|
puts "Syntax error at token ", tokens[0]
|
|
193
263
|
Kernel.exit 1
|
|
@@ -198,41 +268,52 @@ module Parser
|
|
|
198
268
|
end
|
|
199
269
|
|
|
200
270
|
def self.parse_literal(tokens)
|
|
201
|
-
(self.parse_block tokens) ||
|
|
271
|
+
(self.parse_block tokens) ||
|
|
272
|
+
(self.parse_bool tokens) ||
|
|
273
|
+
(self.parse_float tokens) ||
|
|
274
|
+
(self.parse_name tokens) ||
|
|
275
|
+
(self.parse_number tokens) ||
|
|
276
|
+
(self.parse_list tokens) ||
|
|
277
|
+
(self.parse_string tokens) ||
|
|
278
|
+
(self.parse_nil tokens) ||
|
|
279
|
+
(self.parse_parens tokens)
|
|
202
280
|
end
|
|
203
281
|
|
|
204
282
|
def self.parse_call(tokens)
|
|
205
|
-
|
|
283
|
+
res = (self.parse_literal tokens)
|
|
284
|
+
unless res
|
|
206
285
|
return nil
|
|
207
286
|
end
|
|
208
|
-
callee =
|
|
287
|
+
callee = res
|
|
209
288
|
total = callee[1]
|
|
210
|
-
tokens = tokens[total
|
|
289
|
+
tokens = tokens[total..-1]
|
|
211
290
|
callee = callee[0]
|
|
212
291
|
if self.expect tokens, :lpar
|
|
213
292
|
args = []
|
|
214
|
-
tokens = tokens[1
|
|
293
|
+
tokens = tokens[1..-1]
|
|
215
294
|
total += 1
|
|
216
295
|
if self.expect tokens, :rpar
|
|
217
296
|
return [ (Node.new :call, callee, args), total + 1 ]
|
|
218
297
|
end
|
|
219
298
|
while true
|
|
220
|
-
|
|
299
|
+
res = (self.parse_expr tokens)
|
|
300
|
+
unless res
|
|
221
301
|
return nil
|
|
222
302
|
end
|
|
223
|
-
arg, part =
|
|
303
|
+
arg, part = res
|
|
224
304
|
total += part
|
|
225
|
-
tokens = tokens[part
|
|
305
|
+
tokens = tokens[part..-1]
|
|
226
306
|
args << arg
|
|
227
|
-
total += 1
|
|
228
307
|
if self.expect tokens, :rpar
|
|
229
|
-
tokens = tokens[1
|
|
308
|
+
tokens = tokens[1..-1]
|
|
309
|
+
total += 1
|
|
230
310
|
break
|
|
231
311
|
end
|
|
232
312
|
unless (self.expect tokens, :comma)
|
|
233
313
|
return nil
|
|
234
314
|
end
|
|
235
|
-
|
|
315
|
+
total += 1
|
|
316
|
+
tokens = tokens[1..-1]
|
|
236
317
|
end
|
|
237
318
|
return [ (Node.new :call, callee, args), total ]
|
|
238
319
|
else
|
|
@@ -245,36 +326,38 @@ module Parser
|
|
|
245
326
|
return nil
|
|
246
327
|
end
|
|
247
328
|
total = 1
|
|
248
|
-
tokens = tokens[1
|
|
329
|
+
tokens = tokens[1..-1]
|
|
249
330
|
if self.lookahead tokens, :lpar, 1
|
|
250
|
-
|
|
331
|
+
res = (self.parse_literal tokens)
|
|
332
|
+
unless res
|
|
251
333
|
return nil
|
|
252
334
|
end
|
|
253
|
-
callee =
|
|
335
|
+
callee = res
|
|
254
336
|
callee = callee[0]
|
|
255
337
|
args = []
|
|
256
|
-
tokens = tokens[2
|
|
338
|
+
tokens = tokens[2..-1]
|
|
257
339
|
total += 2
|
|
258
340
|
if self.expect tokens, :rpar
|
|
259
341
|
return [ (Node.new :call, callee, args), total + 1 ]
|
|
260
342
|
end
|
|
261
343
|
while true
|
|
262
|
-
|
|
344
|
+
res = (self.parse_expr tokens)
|
|
345
|
+
unless res
|
|
263
346
|
return nil
|
|
264
347
|
end
|
|
265
|
-
arg, part =
|
|
348
|
+
arg, part = res
|
|
266
349
|
total += part
|
|
267
|
-
tokens = tokens[part
|
|
350
|
+
tokens = tokens[part..-1]
|
|
268
351
|
args << arg
|
|
269
352
|
total += 1
|
|
270
353
|
if self.expect tokens, :rpar
|
|
271
|
-
tokens = tokens[1
|
|
354
|
+
tokens = tokens[1..-1]
|
|
272
355
|
break
|
|
273
356
|
end
|
|
274
357
|
unless (self.expect tokens, :comma)
|
|
275
358
|
return nil
|
|
276
359
|
end
|
|
277
|
-
tokens = tokens[1
|
|
360
|
+
tokens = tokens[1..-1]
|
|
278
361
|
end
|
|
279
362
|
return [ (Node.new :new, callee, args), total ]
|
|
280
363
|
else
|
|
@@ -287,30 +370,33 @@ module Parser
|
|
|
287
370
|
return nil
|
|
288
371
|
end
|
|
289
372
|
total = 1
|
|
290
|
-
tokens = tokens[1
|
|
291
|
-
|
|
373
|
+
tokens = tokens[1..-1]
|
|
374
|
+
res = self.parse_expr tokens
|
|
375
|
+
unless res
|
|
292
376
|
return nil
|
|
293
377
|
end
|
|
294
|
-
e, part =
|
|
378
|
+
e, part = res
|
|
295
379
|
total += part
|
|
296
|
-
tokens = tokens[part
|
|
297
|
-
|
|
380
|
+
tokens = tokens[part..-1]
|
|
381
|
+
res = self.parse_expr tokens
|
|
382
|
+
unless res
|
|
298
383
|
return nil
|
|
299
384
|
end
|
|
300
|
-
block, part =
|
|
385
|
+
block, part = res
|
|
301
386
|
total += part
|
|
302
|
-
tokens = tokens[part
|
|
387
|
+
tokens = tokens[part..-1]
|
|
303
388
|
el = nil
|
|
304
389
|
if self.expect tokens, :else
|
|
305
390
|
total += 1
|
|
306
|
-
tokens = tokens[1
|
|
307
|
-
|
|
391
|
+
tokens = tokens[1..-1]
|
|
392
|
+
res = self.parse_expr tokens
|
|
393
|
+
unless res
|
|
308
394
|
return nil
|
|
309
395
|
end
|
|
310
|
-
el, part =
|
|
396
|
+
el, part = res
|
|
311
397
|
total += part
|
|
312
398
|
end
|
|
313
|
-
|
|
399
|
+
[ (Node.new :if, e, [block, el]), total ]
|
|
314
400
|
end
|
|
315
401
|
|
|
316
402
|
def self.parse_while(tokens)
|
|
@@ -318,19 +404,21 @@ module Parser
|
|
|
318
404
|
return nil
|
|
319
405
|
end
|
|
320
406
|
total = 1
|
|
321
|
-
tokens = tokens[1
|
|
322
|
-
|
|
407
|
+
tokens = tokens[1..-1]
|
|
408
|
+
res = self.parse_expr tokens
|
|
409
|
+
unless res
|
|
323
410
|
return nil
|
|
324
411
|
end
|
|
325
|
-
e, part =
|
|
412
|
+
e, part = res
|
|
326
413
|
total += part
|
|
327
|
-
tokens = tokens[part
|
|
328
|
-
|
|
414
|
+
tokens = tokens[part..-1]
|
|
415
|
+
res = self.parse_expr tokens
|
|
416
|
+
unless res
|
|
329
417
|
return nil
|
|
330
418
|
end
|
|
331
|
-
block, part =
|
|
419
|
+
block, part = res
|
|
332
420
|
total += part
|
|
333
|
-
|
|
421
|
+
[ (Node.new :while, e, [block]), total ]
|
|
334
422
|
end
|
|
335
423
|
|
|
336
424
|
def self.parse_for(tokens)
|
|
@@ -338,47 +426,120 @@ module Parser
|
|
|
338
426
|
return nil
|
|
339
427
|
end
|
|
340
428
|
total = 1
|
|
341
|
-
tokens = tokens[1
|
|
429
|
+
tokens = tokens[1..-1]
|
|
342
430
|
name = nil
|
|
343
431
|
if self.expect tokens, :name and self.lookahead tokens, :in, 1
|
|
344
432
|
name = tokens[0][0]
|
|
345
433
|
total += 2
|
|
346
|
-
tokens = tokens[2
|
|
434
|
+
tokens = tokens[2..-1]
|
|
347
435
|
end
|
|
348
|
-
|
|
436
|
+
res = self.parse_expr tokens
|
|
437
|
+
unless res
|
|
349
438
|
return nil
|
|
350
439
|
end
|
|
351
|
-
e, part =
|
|
440
|
+
e, part = res
|
|
352
441
|
total += part
|
|
353
|
-
tokens = tokens[part
|
|
354
|
-
|
|
442
|
+
tokens = tokens[part..-1]
|
|
443
|
+
res = self.parse_expr tokens
|
|
444
|
+
unless res
|
|
355
445
|
return nil
|
|
356
446
|
end
|
|
357
|
-
block, part =
|
|
447
|
+
block, part = res
|
|
358
448
|
total += part
|
|
359
|
-
|
|
449
|
+
[ (Node.new :for, e, [name, block]), total ]
|
|
360
450
|
end
|
|
361
451
|
|
|
362
|
-
def self.
|
|
452
|
+
def self.parse_factor(tokens)
|
|
453
|
+
(self.parse_call tokens) ||
|
|
454
|
+
(self.parse_require tokens) ||
|
|
455
|
+
(self.parse_new tokens) ||
|
|
456
|
+
(self.parse_object tokens) ||
|
|
457
|
+
(self.parse_fn tokens) ||
|
|
458
|
+
(self.parse_assign tokens) ||
|
|
459
|
+
(self.parse_literal tokens) ||
|
|
460
|
+
(self.parse_if tokens) ||
|
|
461
|
+
(self.parse_while tokens) ||
|
|
462
|
+
(self.parse_for tokens)
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def self.parse_term(tokens)
|
|
363
466
|
total = 0
|
|
364
|
-
|
|
467
|
+
res = self.parse_factor tokens
|
|
468
|
+
unless res
|
|
365
469
|
return nil
|
|
366
470
|
end
|
|
367
|
-
lhs, part =
|
|
471
|
+
lhs, part = res
|
|
368
472
|
total += part
|
|
369
|
-
tokens = tokens[part
|
|
370
|
-
unless self.expect tokens, :
|
|
473
|
+
tokens = tokens[part..-1]
|
|
474
|
+
unless self.expect tokens, :l2op
|
|
475
|
+
return [lhs, part]
|
|
476
|
+
end
|
|
477
|
+
op = tokens[0][0]
|
|
478
|
+
total += 1
|
|
479
|
+
tokens = tokens[1..-1]
|
|
480
|
+
res = self.parse_factor tokens
|
|
481
|
+
unless res
|
|
371
482
|
return nil
|
|
372
483
|
end
|
|
484
|
+
rhs, part = res
|
|
485
|
+
total += part
|
|
486
|
+
tokens = tokens[part..-1]
|
|
487
|
+
out = (Node.new :op, op, [lhs])
|
|
488
|
+
while self.expect tokens, :l2op
|
|
489
|
+
op = tokens[0][0]
|
|
490
|
+
total += 1
|
|
491
|
+
tokens = tokens[1..-1]
|
|
492
|
+
res = self.parse_term tokens
|
|
493
|
+
unless res
|
|
494
|
+
return nil
|
|
495
|
+
end
|
|
496
|
+
rhs2, part = res
|
|
497
|
+
total += part
|
|
498
|
+
tokens = tokens[part..-1]
|
|
499
|
+
rhs = Node.new :op, op, [rhs, rhs2]
|
|
500
|
+
end
|
|
501
|
+
out.children << rhs
|
|
502
|
+
[out, total]
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
def self.parse_op(tokens)
|
|
506
|
+
total = 0
|
|
507
|
+
res = self.parse_term tokens
|
|
508
|
+
unless res
|
|
509
|
+
return nil
|
|
510
|
+
end
|
|
511
|
+
lhs, part = res
|
|
512
|
+
total += part
|
|
513
|
+
tokens = tokens[part..-1]
|
|
514
|
+
unless self.expect tokens, :l1op
|
|
515
|
+
return [lhs, part]
|
|
516
|
+
end
|
|
373
517
|
op = tokens[0][0]
|
|
374
518
|
total += 1
|
|
375
|
-
tokens = tokens[1
|
|
376
|
-
|
|
519
|
+
tokens = tokens[1..-1]
|
|
520
|
+
res = self.parse_term tokens
|
|
521
|
+
unless res
|
|
377
522
|
return nil
|
|
378
523
|
end
|
|
379
|
-
rhs, part =
|
|
524
|
+
rhs, part = res
|
|
380
525
|
total += part
|
|
381
|
-
|
|
526
|
+
tokens = tokens[part..-1]
|
|
527
|
+
out = (Node.new :op, op, [lhs])
|
|
528
|
+
while self.expect tokens, :l1op
|
|
529
|
+
op = tokens[0][0]
|
|
530
|
+
total += 1
|
|
531
|
+
tokens = tokens[1..-1]
|
|
532
|
+
res = self.parse_term tokens
|
|
533
|
+
unless res
|
|
534
|
+
return nil
|
|
535
|
+
end
|
|
536
|
+
rhs2, part = res
|
|
537
|
+
total += part
|
|
538
|
+
tokens = tokens[part..-1]
|
|
539
|
+
rhs = Node.new :op, op, [rhs, rhs2]
|
|
540
|
+
end
|
|
541
|
+
out.children << rhs
|
|
542
|
+
[out, total]
|
|
382
543
|
end
|
|
383
544
|
|
|
384
545
|
def self.parse_assign(tokens)
|
|
@@ -388,19 +549,20 @@ module Parser
|
|
|
388
549
|
end
|
|
389
550
|
name = tokens[0][0]
|
|
390
551
|
total += 1
|
|
391
|
-
tokens = tokens[1
|
|
552
|
+
tokens = tokens[1..-1]
|
|
392
553
|
unless self.expect tokens, :eq
|
|
393
554
|
return nil
|
|
394
555
|
end
|
|
395
556
|
eq = tokens[0][0]
|
|
396
557
|
total += 1
|
|
397
|
-
tokens = tokens[1
|
|
398
|
-
|
|
558
|
+
tokens = tokens[1..-1]
|
|
559
|
+
res = self.parse_expr tokens
|
|
560
|
+
unless res
|
|
399
561
|
return nil
|
|
400
562
|
end
|
|
401
|
-
rhs, part =
|
|
563
|
+
rhs, part = res
|
|
402
564
|
total += part
|
|
403
|
-
|
|
565
|
+
[ (Node.new :assign, eq, [name, rhs]), total]
|
|
404
566
|
end
|
|
405
567
|
|
|
406
568
|
def self.parse_fn(tokens)
|
|
@@ -408,23 +570,23 @@ module Parser
|
|
|
408
570
|
return nil
|
|
409
571
|
end
|
|
410
572
|
total = 1
|
|
411
|
-
tokens = tokens[1
|
|
573
|
+
tokens = tokens[1..-1]
|
|
412
574
|
unless self.expect tokens, :name
|
|
413
575
|
return nil
|
|
414
576
|
end
|
|
415
577
|
name = tokens[0][0]
|
|
416
578
|
total += 1
|
|
417
|
-
tokens = tokens[1
|
|
579
|
+
tokens = tokens[1..-1]
|
|
418
580
|
unless self.expect tokens, :lpar
|
|
419
581
|
return nil
|
|
420
582
|
end
|
|
421
583
|
total += 1
|
|
422
|
-
tokens = tokens[1
|
|
584
|
+
tokens = tokens[1..-1]
|
|
423
585
|
args = []
|
|
424
586
|
while true
|
|
425
587
|
if self.expect tokens, :rpar
|
|
426
588
|
total += 1
|
|
427
|
-
tokens = tokens[1
|
|
589
|
+
tokens = tokens[1..-1]
|
|
428
590
|
break
|
|
429
591
|
end
|
|
430
592
|
unless self.expect tokens, :name
|
|
@@ -432,24 +594,25 @@ module Parser
|
|
|
432
594
|
end
|
|
433
595
|
args << tokens[0][0]
|
|
434
596
|
total += 1
|
|
435
|
-
tokens = tokens[1
|
|
597
|
+
tokens = tokens[1..-1]
|
|
436
598
|
if self.expect tokens, :rpar
|
|
437
599
|
total += 1
|
|
438
|
-
tokens = tokens[1
|
|
600
|
+
tokens = tokens[1..-1]
|
|
439
601
|
break
|
|
440
602
|
end
|
|
441
603
|
unless self.expect tokens, :comma
|
|
442
604
|
return nil
|
|
443
605
|
end
|
|
444
606
|
total += 1
|
|
445
|
-
tokens = tokens[1
|
|
607
|
+
tokens = tokens[1..-1]
|
|
446
608
|
end
|
|
447
|
-
|
|
609
|
+
res = self.parse_expr tokens
|
|
610
|
+
unless res
|
|
448
611
|
return nil
|
|
449
612
|
end
|
|
450
|
-
body, part =
|
|
613
|
+
body, part = res
|
|
451
614
|
total += part
|
|
452
|
-
|
|
615
|
+
[ (Node.new :fn, name, [args, body]), total ]
|
|
453
616
|
end
|
|
454
617
|
|
|
455
618
|
def self.parse_object(tokens)
|
|
@@ -457,21 +620,21 @@ module Parser
|
|
|
457
620
|
return nil
|
|
458
621
|
end
|
|
459
622
|
total = 1
|
|
460
|
-
tokens = tokens[1
|
|
623
|
+
tokens = tokens[1..-1]
|
|
461
624
|
unless self.expect tokens, :name
|
|
462
625
|
return nil
|
|
463
626
|
end
|
|
464
627
|
name = tokens[0][0]
|
|
465
628
|
total += 1
|
|
466
|
-
tokens = tokens[1
|
|
629
|
+
tokens = tokens[1..-1]
|
|
467
630
|
args = []
|
|
468
631
|
if self.expect tokens, :lpar
|
|
469
632
|
total += 1
|
|
470
|
-
tokens = tokens[1
|
|
633
|
+
tokens = tokens[1..-1]
|
|
471
634
|
while true
|
|
472
635
|
if self.expect tokens, :rpar
|
|
473
636
|
total += 1
|
|
474
|
-
tokens = tokens[1
|
|
637
|
+
tokens = tokens[1..-1]
|
|
475
638
|
break
|
|
476
639
|
end
|
|
477
640
|
unless self.expect tokens, :name
|
|
@@ -479,45 +642,56 @@ module Parser
|
|
|
479
642
|
end
|
|
480
643
|
args << tokens[0][0]
|
|
481
644
|
total += 1
|
|
482
|
-
tokens = tokens[1
|
|
645
|
+
tokens = tokens[1..-1]
|
|
483
646
|
if self.expect tokens, :rpar
|
|
484
647
|
total += 1
|
|
485
|
-
tokens = tokens[1
|
|
648
|
+
tokens = tokens[1..-1]
|
|
486
649
|
break
|
|
487
650
|
end
|
|
488
651
|
unless self.expect tokens, :comma
|
|
489
652
|
return nil
|
|
490
653
|
end
|
|
491
654
|
total += 1
|
|
492
|
-
tokens = tokens[1
|
|
655
|
+
tokens = tokens[1..-1]
|
|
493
656
|
end
|
|
494
657
|
end
|
|
495
|
-
|
|
658
|
+
res = self.parse_expr tokens
|
|
659
|
+
unless res
|
|
496
660
|
return nil
|
|
497
661
|
end
|
|
498
|
-
body, part =
|
|
662
|
+
body, part = res
|
|
499
663
|
total += part
|
|
500
|
-
|
|
664
|
+
[ (Node.new :object, name, [args, body]), total ]
|
|
501
665
|
end
|
|
502
666
|
|
|
503
667
|
def self.parse_require(tokens)
|
|
504
668
|
unless self.expect tokens, :require
|
|
505
669
|
return nil
|
|
506
670
|
end
|
|
507
|
-
tokens = tokens[1
|
|
671
|
+
tokens = tokens[1..-1]
|
|
508
672
|
unless self.expect tokens, :string
|
|
509
673
|
return nil
|
|
510
674
|
end
|
|
511
|
-
|
|
675
|
+
[ (Node.new :require, tokens[0][0][1..-2], []), 2 ]
|
|
512
676
|
end
|
|
513
677
|
|
|
514
678
|
def self.parse_expr(tokens)
|
|
515
|
-
(self.
|
|
679
|
+
(self.parse_op tokens) ||
|
|
680
|
+
(self.parse_call tokens) ||
|
|
681
|
+
(self.parse_require tokens) ||
|
|
682
|
+
(self.parse_new tokens) ||
|
|
683
|
+
(self.parse_object tokens) ||
|
|
684
|
+
(self.parse_fn tokens) ||
|
|
685
|
+
(self.parse_assign tokens) ||
|
|
686
|
+
(self.parse_literal tokens) ||
|
|
687
|
+
(self.parse_if tokens) ||
|
|
688
|
+
(self.parse_while tokens) ||
|
|
689
|
+
(self.parse_for tokens)
|
|
516
690
|
end
|
|
517
691
|
|
|
518
|
-
def self.parse(tokens, path)
|
|
692
|
+
def self.parse(tokens, path, lines)
|
|
519
693
|
parsed = []
|
|
520
|
-
while tokens.size > 0
|
|
694
|
+
while State::state == :ok and tokens.size > 0
|
|
521
695
|
e = self.parse_expr tokens
|
|
522
696
|
if e
|
|
523
697
|
if e[0].nodetype == :require
|
|
@@ -530,19 +704,23 @@ module Parser
|
|
|
530
704
|
end
|
|
531
705
|
end
|
|
532
706
|
unless code
|
|
533
|
-
|
|
534
|
-
|
|
707
|
+
error "Cannot find file #{e[0].value}.sdx anywhere in path"
|
|
708
|
+
State::state = :error
|
|
535
709
|
end
|
|
536
710
|
lexed = Lexer.lex code
|
|
537
|
-
ast = self.parse lexed, path
|
|
711
|
+
ast = self.parse lexed, path, (code.split "\n")
|
|
538
712
|
parsed.concat ast
|
|
539
713
|
else
|
|
540
714
|
parsed << e[0]
|
|
541
715
|
end
|
|
542
|
-
tokens = tokens[e[1]
|
|
716
|
+
tokens = tokens[e[1]..-1]
|
|
543
717
|
else
|
|
544
|
-
|
|
545
|
-
|
|
718
|
+
error %{
|
|
719
|
+
Unexpected token #{tokens[0][1]} at #{tokens[0][2]}:#{tokens[0][3]}
|
|
720
|
+
#{" " * tokens[0][2].to_s.size} |
|
|
721
|
+
#{tokens[0][2]} | #{lines[tokens[0][2]].rstrip}
|
|
722
|
+
#{" " * tokens[0][2].to_s.size} | #{" " * tokens[0][3]}^ here}
|
|
723
|
+
State::state = :error
|
|
546
724
|
end
|
|
547
725
|
end
|
|
548
726
|
parsed
|
data/lib/sdx/vm/datatypes.rb
CHANGED
data/lib/sdx/vm/scope.rb
CHANGED
|
@@ -3,7 +3,6 @@ class GLOBAL_SCOPE
|
|
|
3
3
|
|
|
4
4
|
def error(msg)
|
|
5
5
|
puts "\x1b[0;31mError in VM: #{msg}\x1b[0;0m"
|
|
6
|
-
exit 1
|
|
7
6
|
end
|
|
8
7
|
|
|
9
8
|
def initialize(variables={})
|
|
@@ -25,7 +24,7 @@ class GLOBAL_SCOPE
|
|
|
25
24
|
name.each do |part|
|
|
26
25
|
val = scope.variables[part]
|
|
27
26
|
unless val
|
|
28
|
-
|
|
27
|
+
return nil
|
|
29
28
|
end
|
|
30
29
|
case val.value
|
|
31
30
|
when InstantiatedObj
|
data/lib/sdx/vm/vm.rb
CHANGED
|
@@ -165,7 +165,8 @@ class VM
|
|
|
165
165
|
0x36 => :lt,
|
|
166
166
|
0x37 => :gt,
|
|
167
167
|
0x38 => :le,
|
|
168
|
-
0x39 => :ge
|
|
168
|
+
0x39 => :ge,
|
|
169
|
+
0x28 => :pow,
|
|
169
170
|
}
|
|
170
171
|
bytes = []
|
|
171
172
|
begin
|
|
@@ -219,13 +220,15 @@ class VM
|
|
|
219
220
|
|
|
220
221
|
def error(msg)
|
|
221
222
|
puts "\x1b[0;31mError in VM: #{msg}\x1b[0;0m"
|
|
222
|
-
|
|
223
|
+
@stack = []
|
|
224
|
+
State::state = :error
|
|
223
225
|
end
|
|
224
226
|
|
|
225
227
|
def interpret(do_end=true) # builds stack from bytecode
|
|
226
228
|
loop do
|
|
227
229
|
loaded_bytes = load_bytes(1) # loads in first byte for initial instruction
|
|
228
230
|
break if loaded_bytes[0] == :end_prg # end of program reached
|
|
231
|
+
break if State::state != :ok
|
|
229
232
|
|
|
230
233
|
case loaded_bytes[0]
|
|
231
234
|
when :make
|
|
@@ -301,7 +304,7 @@ class VM
|
|
|
301
304
|
res = (call a.value.fields["__add"], b.value)
|
|
302
305
|
push_to_stack (to_var res)
|
|
303
306
|
else
|
|
304
|
-
error "Cannot use + on #{a
|
|
307
|
+
error "Cannot use + on #{codify a}"
|
|
305
308
|
end
|
|
306
309
|
when :sub
|
|
307
310
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -309,7 +312,7 @@ class VM
|
|
|
309
312
|
res = (call a.value.fields["__sub"], b.value)
|
|
310
313
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
311
314
|
else
|
|
312
|
-
error "Cannot use - on #{a
|
|
315
|
+
error "Cannot use - on #{codify a}"
|
|
313
316
|
end
|
|
314
317
|
when :mul
|
|
315
318
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -317,7 +320,7 @@ class VM
|
|
|
317
320
|
res = (call a.value.fields["__mul"], b.value)
|
|
318
321
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
319
322
|
else
|
|
320
|
-
error "Cannot use * on #{a
|
|
323
|
+
error "Cannot use * on #{codify a}"
|
|
321
324
|
end
|
|
322
325
|
when :div
|
|
323
326
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -325,7 +328,7 @@ class VM
|
|
|
325
328
|
res = (call a.value.fields["__div"], b.value)
|
|
326
329
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
327
330
|
else
|
|
328
|
-
error "Cannot use / on #{a
|
|
331
|
+
error "Cannot use / on #{codify a}"
|
|
329
332
|
end
|
|
330
333
|
when :mod
|
|
331
334
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -333,7 +336,7 @@ class VM
|
|
|
333
336
|
res = (call a.value.fields["__mod"], b.value)
|
|
334
337
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
335
338
|
else
|
|
336
|
-
error "Cannot use % on #{a
|
|
339
|
+
error "Cannot use % on #{codify a}"
|
|
337
340
|
end
|
|
338
341
|
when :pow
|
|
339
342
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -341,7 +344,7 @@ class VM
|
|
|
341
344
|
res = (call a.value.fields["__pow"], b.value)
|
|
342
345
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
343
346
|
else
|
|
344
|
-
error "Cannot use ^ on #{a
|
|
347
|
+
error "Cannot use ^ on #{codify a}"
|
|
345
348
|
end
|
|
346
349
|
when :eq
|
|
347
350
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -349,7 +352,7 @@ class VM
|
|
|
349
352
|
res = (call a.value.fields["__eq"], b.value)
|
|
350
353
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
351
354
|
else
|
|
352
|
-
error "Cannot use == on #{a
|
|
355
|
+
error "Cannot use == on #{codify a}"
|
|
353
356
|
end
|
|
354
357
|
when :ne
|
|
355
358
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -357,7 +360,7 @@ class VM
|
|
|
357
360
|
res = (call a.value.fields["__neq"], b.value)
|
|
358
361
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
359
362
|
else
|
|
360
|
-
error "Cannot use != on #{a
|
|
363
|
+
error "Cannot use != on #{codify a}"
|
|
361
364
|
end
|
|
362
365
|
when :lt
|
|
363
366
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -365,7 +368,7 @@ class VM
|
|
|
365
368
|
res = (call a.value.fields["__lt"], b.value)
|
|
366
369
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
367
370
|
else
|
|
368
|
-
error "Cannot use < on #{a
|
|
371
|
+
error "Cannot use < on #{codify a}"
|
|
369
372
|
end
|
|
370
373
|
when :gt
|
|
371
374
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -373,7 +376,7 @@ class VM
|
|
|
373
376
|
res = (call a.value.fields["__gt"], b.value)
|
|
374
377
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
375
378
|
else
|
|
376
|
-
error "Cannot use > on #{a
|
|
379
|
+
error "Cannot use > on #{codify a}"
|
|
377
380
|
end
|
|
378
381
|
when :le
|
|
379
382
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -381,7 +384,7 @@ class VM
|
|
|
381
384
|
res = (call a.value.fields["__le"], b.value)
|
|
382
385
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
383
386
|
else
|
|
384
|
-
error "Cannot use <= on #{a
|
|
387
|
+
error "Cannot use <= on #{codify a}"
|
|
385
388
|
end
|
|
386
389
|
when :ge
|
|
387
390
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -389,7 +392,7 @@ class VM
|
|
|
389
392
|
res = (call a.value.fields["__ge"], b.value)
|
|
390
393
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
391
394
|
else
|
|
392
|
-
error "Cannot use >= on #{a
|
|
395
|
+
error "Cannot use >= on #{codify a}"
|
|
393
396
|
end
|
|
394
397
|
when :jmpi
|
|
395
398
|
val = pop_from_stack
|
|
@@ -419,12 +422,16 @@ class VM
|
|
|
419
422
|
if val.value.fields["__reset"]
|
|
420
423
|
call val.value.fields["__reset"]
|
|
421
424
|
push_to_stack val
|
|
425
|
+
else
|
|
426
|
+
error "Cannot reset #{codify val}"
|
|
422
427
|
end
|
|
423
428
|
when :iter
|
|
424
429
|
val = pop_from_stack
|
|
425
430
|
if val.value.fields["__iter"]
|
|
426
431
|
res = call val.value.fields["__iter"]
|
|
427
432
|
push_to_stack res
|
|
433
|
+
else
|
|
434
|
+
error "Cannot iterate #{codify val}"
|
|
428
435
|
end
|
|
429
436
|
when :end
|
|
430
437
|
if do_end
|
|
@@ -435,45 +442,53 @@ class VM
|
|
|
435
442
|
if callable val
|
|
436
443
|
args = []
|
|
437
444
|
(arity val).internal.times do
|
|
445
|
+
break if State::state != :ok
|
|
438
446
|
this = pop_from_stack
|
|
439
|
-
|
|
447
|
+
if !this
|
|
440
448
|
error "Not enough arguments: expected #{val.value.fields["__arity"].internal}, got #{args.size}"
|
|
449
|
+
else
|
|
450
|
+
args << this
|
|
441
451
|
end
|
|
442
|
-
args << this
|
|
443
452
|
end
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
+
if State::state == :ok
|
|
454
|
+
scope = nil
|
|
455
|
+
begin
|
|
456
|
+
scope = val.scope
|
|
457
|
+
rescue
|
|
458
|
+
scope = @global
|
|
459
|
+
end
|
|
460
|
+
ret = call val, *args
|
|
461
|
+
if ret
|
|
462
|
+
push_to_stack ret
|
|
463
|
+
end
|
|
453
464
|
end
|
|
454
465
|
else
|
|
455
|
-
error "Cannot call #{
|
|
466
|
+
error "Cannot call #{codify val}"
|
|
456
467
|
end
|
|
457
468
|
when :new
|
|
458
469
|
val = pop_from_stack
|
|
459
470
|
if val.value.fields["__new"] and val.value.fields["__arity"]
|
|
460
471
|
args = []
|
|
461
472
|
val.value.fields["__arity"].internal.times do
|
|
473
|
+
break if State::state != :ok
|
|
462
474
|
this = pop_from_stack
|
|
463
|
-
|
|
475
|
+
if !this
|
|
464
476
|
error "Not enough arguments: expected #{val.value.fields["__arity"].internal}, got #{args.size}"
|
|
477
|
+
else
|
|
478
|
+
args << this
|
|
465
479
|
end
|
|
466
|
-
args << this
|
|
467
|
-
end
|
|
468
|
-
f = Proc.new do |args, scope|
|
|
469
|
-
call val.value.fields["__new"], args, scope
|
|
470
480
|
end
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
481
|
+
if State::state == :ok
|
|
482
|
+
f = Proc.new do |args, scope|
|
|
483
|
+
call val.value.fields["__new"], args, scope
|
|
484
|
+
end
|
|
485
|
+
ret = Variable.new (InstantiatedObj.new f.call args, @global), :instobj, @global
|
|
486
|
+
if ret
|
|
487
|
+
push_to_stack ret
|
|
488
|
+
end
|
|
474
489
|
end
|
|
475
490
|
else
|
|
476
|
-
error "Cannot instantiate #{
|
|
491
|
+
error "Cannot instantiate #{codify val}"
|
|
477
492
|
end
|
|
478
493
|
end
|
|
479
494
|
end
|