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