sardonyx 0.2.1 → 0.3.4
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 +93 -23
- data/lib/sdx/vm/scope.rb +1 -2
- data/lib/sdx/vm/vm.rb +60 -42
- 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: 5d369226413f552c8f1cb2fc20675a4364c2d4ec03f7b22897c341567a6da09e
|
|
4
|
+
data.tar.gz: a39fb4fb82a76ea92c4799e3a5b51f52c62d7dfd853402a0e83877b790bda36c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9714fee82b1115876a3533a4e9cf9cb82875f6c0b4e2749ceeb1fc63218b262364e52cfd0e4649c8b1f825206a1772572033fe2d6f569f88fa1def58477f3e30
|
|
7
|
+
data.tar.gz: 858e1cffdf236a2ef9fb14e7af794d68b6ca83c9724ef05b02c65d7ce2ba73954e808ace033d8423fe52f9dde6ebbc54c56adc6036bc177b6a9ce4888711ae69
|
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.
|
|
19
|
-
|
|
25
|
+
puts "Sardonyx v0.3.4"
|
|
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 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,
|
|
@@ -29,25 +42,78 @@ module Parser
|
|
|
29
42
|
/\A[A-Za-z_][A-Za-z0-9_]*([:.][A-Za-z_][A-Za-z0-9_]*)*/ => :name
|
|
30
43
|
}
|
|
31
44
|
|
|
45
|
+
class << self
|
|
46
|
+
attr_accessor :lines
|
|
47
|
+
end
|
|
48
|
+
|
|
32
49
|
def self.lex(code)
|
|
50
|
+
@@lines = code.split "\n"
|
|
33
51
|
lexed = []
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
|
42
67
|
break
|
|
43
68
|
end
|
|
44
|
-
|
|
45
|
-
if !
|
|
46
|
-
|
|
47
|
-
|
|
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
|
|
48
114
|
end
|
|
49
115
|
end
|
|
50
|
-
lexed
|
|
116
|
+
[ lexed, @@lines ]
|
|
51
117
|
end
|
|
52
118
|
end
|
|
53
119
|
|
|
@@ -623,9 +689,9 @@ module Parser
|
|
|
623
689
|
(self.parse_for tokens)
|
|
624
690
|
end
|
|
625
691
|
|
|
626
|
-
def self.parse(tokens, path)
|
|
692
|
+
def self.parse(tokens, path, lines)
|
|
627
693
|
parsed = []
|
|
628
|
-
while tokens.size > 0
|
|
694
|
+
while State::state == :ok and tokens.size > 0
|
|
629
695
|
e = self.parse_expr tokens
|
|
630
696
|
if e
|
|
631
697
|
if e[0].nodetype == :require
|
|
@@ -638,19 +704,23 @@ module Parser
|
|
|
638
704
|
end
|
|
639
705
|
end
|
|
640
706
|
unless code
|
|
641
|
-
|
|
642
|
-
|
|
707
|
+
error "Cannot find file #{e[0].value}.sdx anywhere in path"
|
|
708
|
+
State::state = :error
|
|
643
709
|
end
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
710
|
+
tokens = tokens[e[1]..-1]
|
|
711
|
+
lexed, _ = Lexer.lex code
|
|
712
|
+
tokens = [*lexed, *tokens]
|
|
647
713
|
else
|
|
648
714
|
parsed << e[0]
|
|
715
|
+
tokens = tokens[e[1]..-1]
|
|
649
716
|
end
|
|
650
|
-
tokens = tokens[e[1]..-1]
|
|
651
717
|
else
|
|
652
|
-
|
|
653
|
-
|
|
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
|
|
654
724
|
end
|
|
655
725
|
end
|
|
656
726
|
parsed
|
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
|
@@ -14,6 +14,18 @@ def codify(val)
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
def stringify(val)
|
|
18
|
+
if val.value.fields["__as_string"]
|
|
19
|
+
if val.value.fields["__as_string"].respond_to? :fields
|
|
20
|
+
(val.value.fields["__as_string"].fields["__call"].call [], val.scope).internal
|
|
21
|
+
else
|
|
22
|
+
(val.value.fields["__as_string"]).call.internal
|
|
23
|
+
end
|
|
24
|
+
else
|
|
25
|
+
val.value.to_s
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
17
29
|
class VM
|
|
18
30
|
attr_accessor :bc_io
|
|
19
31
|
|
|
@@ -28,14 +40,6 @@ class VM
|
|
|
28
40
|
return true
|
|
29
41
|
end
|
|
30
42
|
end
|
|
31
|
-
|
|
32
|
-
def stringify(val)
|
|
33
|
-
if val.value.fields["__as_string"]
|
|
34
|
-
(call val.value.fields["__as_string"], [], val.scope).internal
|
|
35
|
-
else
|
|
36
|
-
val.value.to_s
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
43
|
|
|
40
44
|
def call(val, *args)
|
|
41
45
|
if val.respond_to? :value and val.value.respond_to? :fields
|
|
@@ -220,13 +224,15 @@ class VM
|
|
|
220
224
|
|
|
221
225
|
def error(msg)
|
|
222
226
|
puts "\x1b[0;31mError in VM: #{msg}\x1b[0;0m"
|
|
223
|
-
|
|
227
|
+
@stack = []
|
|
228
|
+
State::state = :error
|
|
224
229
|
end
|
|
225
230
|
|
|
226
231
|
def interpret(do_end=true) # builds stack from bytecode
|
|
227
232
|
loop do
|
|
228
233
|
loaded_bytes = load_bytes(1) # loads in first byte for initial instruction
|
|
229
234
|
break if loaded_bytes[0] == :end_prg # end of program reached
|
|
235
|
+
break if State::state != :ok
|
|
230
236
|
|
|
231
237
|
case loaded_bytes[0]
|
|
232
238
|
when :make
|
|
@@ -302,7 +308,7 @@ class VM
|
|
|
302
308
|
res = (call a.value.fields["__add"], b.value)
|
|
303
309
|
push_to_stack (to_var res)
|
|
304
310
|
else
|
|
305
|
-
error "Cannot use + on #{a
|
|
311
|
+
error "Cannot use + on #{codify a}"
|
|
306
312
|
end
|
|
307
313
|
when :sub
|
|
308
314
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -310,7 +316,7 @@ class VM
|
|
|
310
316
|
res = (call a.value.fields["__sub"], b.value)
|
|
311
317
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
312
318
|
else
|
|
313
|
-
error "Cannot use - on #{a
|
|
319
|
+
error "Cannot use - on #{codify a}"
|
|
314
320
|
end
|
|
315
321
|
when :mul
|
|
316
322
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -318,7 +324,7 @@ class VM
|
|
|
318
324
|
res = (call a.value.fields["__mul"], b.value)
|
|
319
325
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
320
326
|
else
|
|
321
|
-
error "Cannot use * on #{a
|
|
327
|
+
error "Cannot use * on #{codify a}"
|
|
322
328
|
end
|
|
323
329
|
when :div
|
|
324
330
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -326,7 +332,7 @@ class VM
|
|
|
326
332
|
res = (call a.value.fields["__div"], b.value)
|
|
327
333
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
328
334
|
else
|
|
329
|
-
error "Cannot use / on #{a
|
|
335
|
+
error "Cannot use / on #{codify a}"
|
|
330
336
|
end
|
|
331
337
|
when :mod
|
|
332
338
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -334,7 +340,7 @@ class VM
|
|
|
334
340
|
res = (call a.value.fields["__mod"], b.value)
|
|
335
341
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
336
342
|
else
|
|
337
|
-
error "Cannot use % on #{a
|
|
343
|
+
error "Cannot use % on #{codify a}"
|
|
338
344
|
end
|
|
339
345
|
when :pow
|
|
340
346
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -342,7 +348,7 @@ class VM
|
|
|
342
348
|
res = (call a.value.fields["__pow"], b.value)
|
|
343
349
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
344
350
|
else
|
|
345
|
-
error "Cannot use ^ on #{a
|
|
351
|
+
error "Cannot use ^ on #{codify a}"
|
|
346
352
|
end
|
|
347
353
|
when :eq
|
|
348
354
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -350,7 +356,7 @@ class VM
|
|
|
350
356
|
res = (call a.value.fields["__eq"], b.value)
|
|
351
357
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
352
358
|
else
|
|
353
|
-
error "Cannot use == on #{a
|
|
359
|
+
error "Cannot use == on #{codify a}"
|
|
354
360
|
end
|
|
355
361
|
when :ne
|
|
356
362
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -358,7 +364,7 @@ class VM
|
|
|
358
364
|
res = (call a.value.fields["__neq"], b.value)
|
|
359
365
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
360
366
|
else
|
|
361
|
-
error "Cannot use != on #{a
|
|
367
|
+
error "Cannot use != on #{codify a}"
|
|
362
368
|
end
|
|
363
369
|
when :lt
|
|
364
370
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -366,7 +372,7 @@ class VM
|
|
|
366
372
|
res = (call a.value.fields["__lt"], b.value)
|
|
367
373
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
368
374
|
else
|
|
369
|
-
error "Cannot use < on #{a
|
|
375
|
+
error "Cannot use < on #{codify a}"
|
|
370
376
|
end
|
|
371
377
|
when :gt
|
|
372
378
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -374,7 +380,7 @@ class VM
|
|
|
374
380
|
res = (call a.value.fields["__gt"], b.value)
|
|
375
381
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
376
382
|
else
|
|
377
|
-
error "Cannot use > on #{a
|
|
383
|
+
error "Cannot use > on #{codify a}"
|
|
378
384
|
end
|
|
379
385
|
when :le
|
|
380
386
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -382,7 +388,7 @@ class VM
|
|
|
382
388
|
res = (call a.value.fields["__le"], b.value)
|
|
383
389
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
384
390
|
else
|
|
385
|
-
error "Cannot use <= on #{a
|
|
391
|
+
error "Cannot use <= on #{codify a}"
|
|
386
392
|
end
|
|
387
393
|
when :ge
|
|
388
394
|
b, a = pop_from_stack, pop_from_stack
|
|
@@ -390,7 +396,7 @@ class VM
|
|
|
390
396
|
res = (call a.value.fields["__ge"], b.value)
|
|
391
397
|
push_to_stack (Variable.new res, (get_type res), @global)
|
|
392
398
|
else
|
|
393
|
-
error "Cannot use >= on #{a
|
|
399
|
+
error "Cannot use >= on #{codify a}"
|
|
394
400
|
end
|
|
395
401
|
when :jmpi
|
|
396
402
|
val = pop_from_stack
|
|
@@ -420,12 +426,16 @@ class VM
|
|
|
420
426
|
if val.value.fields["__reset"]
|
|
421
427
|
call val.value.fields["__reset"]
|
|
422
428
|
push_to_stack val
|
|
429
|
+
else
|
|
430
|
+
error "Cannot reset #{codify val}"
|
|
423
431
|
end
|
|
424
432
|
when :iter
|
|
425
433
|
val = pop_from_stack
|
|
426
434
|
if val.value.fields["__iter"]
|
|
427
435
|
res = call val.value.fields["__iter"]
|
|
428
436
|
push_to_stack res
|
|
437
|
+
else
|
|
438
|
+
error "Cannot iterate #{codify val}"
|
|
429
439
|
end
|
|
430
440
|
when :end
|
|
431
441
|
if do_end
|
|
@@ -436,45 +446,53 @@ class VM
|
|
|
436
446
|
if callable val
|
|
437
447
|
args = []
|
|
438
448
|
(arity val).internal.times do
|
|
449
|
+
break if State::state != :ok
|
|
439
450
|
this = pop_from_stack
|
|
440
|
-
|
|
451
|
+
if !this
|
|
441
452
|
error "Not enough arguments: expected #{val.value.fields["__arity"].internal}, got #{args.size}"
|
|
453
|
+
else
|
|
454
|
+
args << this
|
|
442
455
|
end
|
|
443
|
-
args << this
|
|
444
456
|
end
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
457
|
+
if State::state == :ok
|
|
458
|
+
scope = nil
|
|
459
|
+
begin
|
|
460
|
+
scope = val.scope
|
|
461
|
+
rescue
|
|
462
|
+
scope = @global
|
|
463
|
+
end
|
|
464
|
+
ret = call val, *args
|
|
465
|
+
if ret
|
|
466
|
+
push_to_stack ret
|
|
467
|
+
end
|
|
454
468
|
end
|
|
455
469
|
else
|
|
456
|
-
error "Cannot call #{
|
|
470
|
+
error "Cannot call #{codify val}"
|
|
457
471
|
end
|
|
458
472
|
when :new
|
|
459
473
|
val = pop_from_stack
|
|
460
474
|
if val.value.fields["__new"] and val.value.fields["__arity"]
|
|
461
475
|
args = []
|
|
462
476
|
val.value.fields["__arity"].internal.times do
|
|
477
|
+
break if State::state != :ok
|
|
463
478
|
this = pop_from_stack
|
|
464
|
-
|
|
479
|
+
if !this
|
|
465
480
|
error "Not enough arguments: expected #{val.value.fields["__arity"].internal}, got #{args.size}"
|
|
481
|
+
else
|
|
482
|
+
args << this
|
|
466
483
|
end
|
|
467
|
-
args << this
|
|
468
|
-
end
|
|
469
|
-
f = Proc.new do |args, scope|
|
|
470
|
-
call val.value.fields["__new"], args, scope
|
|
471
484
|
end
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
485
|
+
if State::state == :ok
|
|
486
|
+
f = Proc.new do |args, scope|
|
|
487
|
+
call val.value.fields["__new"], args, scope
|
|
488
|
+
end
|
|
489
|
+
ret = Variable.new (InstantiatedObj.new f.call args, @global), :instobj, @global
|
|
490
|
+
if ret
|
|
491
|
+
push_to_stack ret
|
|
492
|
+
end
|
|
475
493
|
end
|
|
476
494
|
else
|
|
477
|
-
error "Cannot instantiate #{
|
|
495
|
+
error "Cannot instantiate #{codify val}"
|
|
478
496
|
end
|
|
479
497
|
end
|
|
480
498
|
end
|