fancy 0.3.3 → 0.4.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.
- data/README.md +14 -14
- data/Rakefile +16 -4
- data/bin/fancy +3 -0
- data/bin/fspec +20 -0
- data/bin/fyi +27 -11
- data/bin/ifancy +1 -1
- data/boot/fancy_ext.rb +1 -0
- data/boot/fancy_ext/block_env.rb +1 -9
- data/boot/fancy_ext/delegator.rb +64 -0
- data/boot/fancy_ext/object.rb +4 -0
- data/boot/fancy_ext/thread.rb +4 -0
- data/boot/load.rb +5 -1
- data/boot/rbx-compiler/compiler/ast.rb +0 -1
- data/boot/rbx-compiler/compiler/ast/class_def.rb +2 -0
- data/boot/rbx-compiler/compiler/ast/method_def.rb +2 -0
- data/boot/rbx-compiler/compiler/ast/node.rb +10 -0
- data/boot/rbx-compiler/compiler/ast/ruby_args.rb +12 -0
- data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +2 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/lexer.lex +5 -11
- data/boot/rbx-compiler/parser/parser.rb +16 -5
- data/boot/rbx-compiler/parser/parser.y +39 -24
- data/doc/api/fancy.css +1 -1
- data/doc/api/fancy.jsonp +1 -1
- data/doc/api/fdoc.js +22 -4
- data/doc/api/index.html +5 -6
- data/doc/api/jquery-ui.min.js +401 -0
- data/doc/api/jquery.tools.min.js +192 -0
- data/doc/api/themeswitchertool.js +250 -0
- data/doc/features.md +17 -0
- data/examples/actor_bunnies.fy +32 -0
- data/examples/actors.fy +26 -0
- data/examples/actors_primitive.fy +27 -0
- data/examples/actors_ring.fy +37 -0
- data/examples/armstrong_numbers.fy +1 -1
- data/examples/array.fy +7 -9
- data/examples/async_send.fy +1 -2
- data/examples/blocks.fy +4 -4
- data/examples/call_with_receiver.fy +1 -1
- data/examples/class.fy +1 -1
- data/examples/default_args.fy +4 -1
- data/examples/define_methods.fy +2 -2
- data/examples/echo.fy +1 -1
- data/examples/factorial.fy +1 -1
- data/examples/future_composition.fy +2 -2
- data/examples/futures.fy +0 -5
- data/examples/game_of_life.fy +1 -1
- data/examples/person.fy +1 -1
- data/lib/argv.fy +7 -2
- data/lib/array.fy +109 -42
- data/lib/block.fy +39 -14
- data/lib/boot.fy +2 -0
- data/lib/class.fy +2 -0
- data/lib/compiler/ast.fy +2 -1
- data/lib/compiler/ast/assign.fy +2 -3
- data/lib/compiler/ast/async_send.fy +1 -15
- data/lib/compiler/ast/class_def.fy +2 -1
- data/lib/compiler/ast/expression_list.fy +4 -5
- data/lib/compiler/ast/future_send.fy +1 -10
- data/lib/compiler/ast/goto.fy +46 -0
- data/lib/compiler/ast/identifier.fy +9 -7
- data/lib/compiler/ast/literals.fy +8 -1
- data/lib/compiler/ast/match.fy +14 -4
- data/lib/compiler/ast/message_send.fy +34 -6
- data/lib/compiler/ast/method_def.fy +6 -6
- data/lib/compiler/ast/node.fy +3 -3
- data/lib/compiler/ast/range.fy +1 -0
- data/lib/compiler/ast/script.fy +0 -2
- data/lib/compiler/ast/singleton_method_def.fy +2 -4
- data/lib/compiler/ast/string_interpolation.fy +17 -0
- data/lib/compiler/ast/super.fy +5 -4
- data/lib/compiler/ast/try_catch.fy +8 -6
- data/lib/compiler/ast/tuple_literal.fy +3 -2
- data/lib/compiler/command.fy +0 -1
- data/lib/compiler/compiler.fy +1 -5
- data/lib/compiler/stages.fy +6 -14
- data/lib/documentation.fy +57 -46
- data/lib/enumerable.fy +257 -23
- data/lib/enumerator.fy +122 -15
- data/lib/false_class.fy +10 -1
- data/lib/fancy_spec.fy +263 -61
- data/lib/fdoc.fy +11 -25
- data/lib/fiber.fy +11 -0
- data/lib/file.fy +8 -11
- data/lib/future.fy +84 -5
- data/lib/hash.fy +65 -14
- data/lib/integer.fy +35 -0
- data/lib/iteration.fy +54 -29
- data/lib/message.fy +6 -0
- data/lib/method.fy +0 -16
- data/lib/nil_class.fy +58 -8
- data/lib/number.fy +49 -22
- data/lib/object.fy +371 -65
- data/lib/package.fy +24 -1
- data/lib/package/installer.fy +5 -9
- data/lib/package/specification.fy +2 -2
- data/lib/parser/ext/lexer.lex +15 -11
- data/lib/parser/ext/parser.y +70 -23
- data/lib/parser/methods.fy +33 -14
- data/lib/proxy.fy +33 -3
- data/lib/range.fy +28 -0
- data/lib/rbx.fy +3 -1
- data/lib/rbx/actor.fy +53 -0
- data/lib/rbx/alpha.fy +31 -0
- data/lib/rbx/array.fy +21 -12
- data/lib/rbx/bignum.fy +6 -2
- data/lib/rbx/block.fy +23 -26
- data/lib/rbx/class.fy +54 -2
- data/lib/rbx/code_loader.fy +8 -4
- data/lib/rbx/date.fy +9 -0
- data/lib/rbx/directory.fy +18 -0
- data/lib/rbx/environment_variables.fy +1 -0
- data/lib/rbx/exception.fy +9 -2
- data/lib/rbx/fiber.fy +22 -4
- data/lib/rbx/file.fy +5 -5
- data/lib/rbx/fixnum.fy +5 -0
- data/lib/rbx/float.fy +11 -3
- data/lib/rbx/hash.fy +31 -16
- data/lib/rbx/integer.fy +1 -0
- data/lib/rbx/io.fy +17 -7
- data/lib/rbx/match_data.fy +15 -4
- data/lib/rbx/method.fy +40 -7
- data/lib/rbx/name_error.fy +4 -0
- data/lib/rbx/object.fy +92 -24
- data/lib/rbx/range.fy +20 -6
- data/lib/rbx/regexp.fy +11 -3
- data/lib/rbx/string.fy +51 -1
- data/lib/rbx/stringio.fy +17 -0
- data/lib/rbx/symbol.fy +15 -1
- data/lib/rbx/system.fy +20 -2
- data/lib/rbx/tcp_server.fy +4 -1
- data/lib/rbx/tcp_socket.fy +11 -0
- data/lib/rbx/time.fy +6 -0
- data/lib/rbx/tuple.fy +14 -5
- data/lib/set.fy +144 -29
- data/lib/stack.fy +42 -11
- data/lib/string.fy +118 -8
- data/lib/struct.fy +13 -3
- data/lib/symbol.fy +21 -2
- data/lib/thread_pool.fy +2 -1
- data/lib/true_class.fy +45 -7
- data/lib/tuple.fy +27 -9
- data/lib/version.fy +2 -2
- data/ruby_lib/fancy +43 -0
- data/ruby_lib/fdoc +23 -0
- data/ruby_lib/fspec +3 -0
- data/ruby_lib/fyi +3 -0
- data/ruby_lib/ifancy +3 -0
- data/tests/argv.fy +5 -9
- data/tests/array.fy +323 -196
- data/tests/assignment.fy +29 -29
- data/tests/block.fy +72 -59
- data/tests/class.fy +227 -138
- data/tests/control_flow.fy +83 -51
- data/tests/documentation.fy +8 -8
- data/tests/enumerable.fy +8 -0
- data/tests/enumerator.fy +47 -29
- data/tests/exception.fy +49 -32
- data/tests/file.fy +28 -28
- data/tests/fixnum.fy +170 -0
- data/tests/future.fy +24 -7
- data/tests/hash.fy +55 -38
- data/tests/method.fy +50 -43
- data/tests/nil_class.fy +37 -37
- data/tests/object.fy +152 -70
- data/tests/pattern_matching.fy +67 -31
- data/tests/range.fy +6 -6
- data/tests/set.fy +101 -4
- data/tests/stack.fy +14 -5
- data/tests/string.fy +115 -61
- data/tests/stringio.fy +18 -0
- data/tests/struct.fy +27 -0
- data/tests/symbol.fy +19 -6
- data/tests/true_class.fy +34 -34
- data/tests/tuple.fy +30 -12
- metadata +103 -81
- data/boot/rbx-compiler/compiler/ast/require.rb +0 -20
- data/examples/actor.fy +0 -37
- data/examples/curl_async.fy +0 -37
- data/lib/compiler/ast/require.fy +0 -15
- data/tests/number.fy +0 -135
- data/tests/parsing/sexp.fy +0 -50
data/lib/block.fy
CHANGED
|
@@ -28,27 +28,38 @@ class Block {
|
|
|
28
28
|
{ call not } while_true: block
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
"Same as Block#while_false:"
|
|
33
|
-
|
|
34
|
-
while_false: block
|
|
35
|
-
}
|
|
31
|
+
alias_method: 'while_nil: for: 'while_false:
|
|
36
32
|
|
|
37
33
|
def while_true: work {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
"""
|
|
35
|
+
@work @Block@ to call while @self yields @true.
|
|
36
|
+
|
|
37
|
+
Calls @work while calling @self yields a @true-ish value.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
brk = { return nil }
|
|
42
|
+
loop() {
|
|
43
|
+
try {
|
|
44
|
+
call if_true: work else: brk
|
|
45
|
+
} catch Fancy NextIteration => ex {
|
|
46
|
+
ex result
|
|
47
|
+
}
|
|
43
48
|
}
|
|
44
|
-
}
|
|
49
|
+
} catch Fancy BreakIteration => ex {
|
|
50
|
+
return ex result
|
|
51
|
+
} catch Fancy StopIteration => ex {
|
|
52
|
+
return ex result
|
|
53
|
+
}
|
|
45
54
|
}
|
|
46
55
|
|
|
47
56
|
alias_method: 'while_do: for: 'while_true:
|
|
48
57
|
|
|
49
58
|
def until_do: block {
|
|
50
59
|
"""
|
|
51
|
-
|
|
60
|
+
@block @Block@ to be called while @self yields @nil or @false.
|
|
61
|
+
|
|
62
|
+
Calls a given Block as long as @self yields @nil or @false.
|
|
52
63
|
"""
|
|
53
64
|
|
|
54
65
|
self while_false: block
|
|
@@ -56,6 +67,8 @@ class Block {
|
|
|
56
67
|
|
|
57
68
|
def until: block {
|
|
58
69
|
"""
|
|
70
|
+
@block Condition @Block@ to be called to determine if @self should be called.
|
|
71
|
+
|
|
59
72
|
Calls @self while @block yields @nil or @false.
|
|
60
73
|
"""
|
|
61
74
|
|
|
@@ -83,13 +96,21 @@ class Block {
|
|
|
83
96
|
}
|
|
84
97
|
|
|
85
98
|
def if: obj {
|
|
86
|
-
"
|
|
99
|
+
"""
|
|
100
|
+
@obj Condition object to determine if @self should be called.
|
|
101
|
+
|
|
102
|
+
Calls @self if @obj is true-ish.
|
|
103
|
+
"""
|
|
87
104
|
|
|
88
105
|
if: obj then: self
|
|
89
106
|
}
|
|
90
107
|
|
|
91
108
|
def unless: obj {
|
|
92
|
-
"
|
|
109
|
+
"""
|
|
110
|
+
@obj Condition object to determine if @self should not be called.
|
|
111
|
+
|
|
112
|
+
Opposite of Block#if:. Calls @self if @obj is false-ish.
|
|
113
|
+
"""
|
|
93
114
|
|
|
94
115
|
unless: obj do: self
|
|
95
116
|
}
|
|
@@ -104,4 +125,8 @@ class Block {
|
|
|
104
125
|
|
|
105
126
|
call: [val]
|
|
106
127
|
}
|
|
128
|
+
|
|
129
|
+
def Block name {
|
|
130
|
+
"Block"
|
|
131
|
+
}
|
|
107
132
|
}
|
data/lib/boot.fy
CHANGED
|
@@ -22,9 +22,11 @@ require: "number"
|
|
|
22
22
|
require: "enumerable"
|
|
23
23
|
require: "string"
|
|
24
24
|
require: "array"
|
|
25
|
+
require: "range"
|
|
25
26
|
require: "tuple"
|
|
26
27
|
require: "block"
|
|
27
28
|
require: "iteration"
|
|
29
|
+
require: "integer"
|
|
28
30
|
require: "enumerator"
|
|
29
31
|
require: "file"
|
|
30
32
|
require: "directory"
|
data/lib/class.fy
CHANGED
data/lib/compiler/ast.fy
CHANGED
|
@@ -36,7 +36,8 @@ require: "ast/block"
|
|
|
36
36
|
require: "ast/class_def"
|
|
37
37
|
require: "ast/tuple_literal"
|
|
38
38
|
require: "ast/range"
|
|
39
|
-
require: "ast/require"
|
|
40
39
|
require: "ast/match"
|
|
41
40
|
require: "ast/try_catch"
|
|
42
41
|
require: "ast/return"
|
|
42
|
+
require: "ast/goto"
|
|
43
|
+
require: "ast/string_interpolation"
|
data/lib/compiler/ast/assign.fy
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class Fancy AST {
|
|
2
|
-
|
|
3
2
|
class Assignment : Node {
|
|
4
|
-
def initialize: @line var: @lvalue value: @rvalue {
|
|
3
|
+
def initialize: @line var: @lvalue value: @rvalue {
|
|
4
|
+
}
|
|
5
5
|
|
|
6
6
|
def bytecode: g {
|
|
7
7
|
pos(g)
|
|
@@ -92,5 +92,4 @@ class Fancy AST {
|
|
|
92
92
|
Rubinius AST ConstantAssignment new(@line, name, value) bytecode(g)
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
|
|
96
95
|
}
|
|
@@ -5,21 +5,7 @@ class Fancy AST {
|
|
|
5
5
|
|
|
6
6
|
def bytecode: g {
|
|
7
7
|
pos(g)
|
|
8
|
-
|
|
9
|
-
body = ExpressionList new: @line list: [@message_send]
|
|
10
|
-
block = BlockLiteral new: @line args: (BlockArgs new: @line) body: body
|
|
11
|
-
|
|
12
|
-
fiber = MessageSend new: @line \
|
|
13
|
-
message: (Identifier from: "new:" line: @line) \
|
|
14
|
-
to: (Identifier from: "Fiber" line: @line) \
|
|
15
|
-
args: (MessageArgs new: @line args: [block])
|
|
16
|
-
|
|
17
|
-
schedule_send = MessageSend new: @line \
|
|
18
|
-
message: (Identifier from: "add:" line: @line) \
|
|
19
|
-
to: (Identifier from: "Scheduler" line: @line) \
|
|
20
|
-
args: (MessageArgs new: @line args: [fiber])
|
|
21
|
-
|
|
22
|
-
schedule_send bytecode: g
|
|
8
|
+
@message_send redirect_via: 'send_async:with_params: . bytecode: g
|
|
23
9
|
}
|
|
24
10
|
}
|
|
25
11
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
class Fancy AST {
|
|
2
2
|
class ClassDef : Rubinius AST Class {
|
|
3
|
-
def initialize: @line name: @name parent: @parent body: @body {
|
|
3
|
+
def initialize: @line name: @name parent: @parent body: @body (ExpressionList new: @line) {
|
|
4
|
+
{ @body = ExpressionList new: @line } unless: @body
|
|
4
5
|
name = nil
|
|
5
6
|
if: (@name is_a?: NestedConstant) then: {
|
|
6
7
|
name = @name scoped
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
class Fancy AST {
|
|
2
|
-
|
|
3
2
|
class ExpressionList : Node {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
read_slot: 'expressions
|
|
4
|
+
|
|
5
|
+
def initialize: @line list: @expressions ([]) {
|
|
6
|
+
}
|
|
6
7
|
|
|
7
8
|
def unshift_expression: expression {
|
|
8
9
|
@expressions unshift(expression)
|
|
@@ -41,7 +42,5 @@ class Fancy AST {
|
|
|
41
42
|
@expressions shift()
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
|
-
|
|
45
45
|
}
|
|
46
|
-
|
|
47
46
|
}
|
|
@@ -5,16 +5,7 @@ class Fancy AST {
|
|
|
5
5
|
|
|
6
6
|
def bytecode: g {
|
|
7
7
|
pos(g)
|
|
8
|
-
|
|
9
|
-
body = ExpressionList new: @line list: [@message_send]
|
|
10
|
-
block = BlockLiteral new: @line args: (BlockArgs new: @line) body: body
|
|
11
|
-
|
|
12
|
-
future_send = MessageSend new: @line \
|
|
13
|
-
message: (Identifier from: "new:" line: @line) \
|
|
14
|
-
to: (Identifier from: "Future" line: @line) \
|
|
15
|
-
args: (MessageArgs new: @line args: [block])
|
|
16
|
-
|
|
17
|
-
future_send bytecode: g
|
|
8
|
+
@message_send redirect_via: 'send_future:with_params: . bytecode: g
|
|
18
9
|
}
|
|
19
10
|
}
|
|
20
11
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
class Rubinius Generator {
|
|
2
|
+
def ip: @ip
|
|
3
|
+
def ip {
|
|
4
|
+
@ip
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
class Fancy AST {
|
|
9
|
+
class Label : Node {
|
|
10
|
+
@@registry = <[]>
|
|
11
|
+
def Label [name] {
|
|
12
|
+
@@registry[name]
|
|
13
|
+
}
|
|
14
|
+
def Label [name]: label {
|
|
15
|
+
@@registry[name]: label
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
def initialize: @line name: @name
|
|
19
|
+
def bytecode: g {
|
|
20
|
+
pos(g)
|
|
21
|
+
label = Label[@name]
|
|
22
|
+
unless: label do: {
|
|
23
|
+
label = g new_label()
|
|
24
|
+
Label[@name]: label
|
|
25
|
+
}
|
|
26
|
+
tmp = g ip
|
|
27
|
+
g ip: (tmp + 2)
|
|
28
|
+
label set!()
|
|
29
|
+
g ip: tmp
|
|
30
|
+
g push_nil()
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
class Goto : Node {
|
|
35
|
+
def initialize: @line label_name: @label_name
|
|
36
|
+
def bytecode: g {
|
|
37
|
+
pos(g)
|
|
38
|
+
label = Label[@label_name]
|
|
39
|
+
unless: label do: {
|
|
40
|
+
label = g new_label()
|
|
41
|
+
Label[@label_name]: label
|
|
42
|
+
}
|
|
43
|
+
g goto(label)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
class Fancy AST {
|
|
2
|
-
|
|
3
2
|
class Identifier : Node {
|
|
4
3
|
read_slots: ['string, 'line]
|
|
5
|
-
|
|
4
|
+
read_write_slot: 'ruby_ident
|
|
6
5
|
|
|
7
6
|
@@gen_ident_start = 0
|
|
8
7
|
|
|
@@ -18,7 +17,11 @@ class Fancy AST {
|
|
|
18
17
|
Identifier from: ("______gen_ident______" ++ @@gen_ident_start) line: line
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
def initialize: @line string: @string ruby_ident: @ruby_ident (false) {
|
|
20
|
+
def initialize: @line string: @string ruby_ident: @ruby_ident (false) {
|
|
21
|
+
match @string {
|
|
22
|
+
case /^ | $/ -> @string = "|"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
22
25
|
|
|
23
26
|
def name {
|
|
24
27
|
@string to_sym()
|
|
@@ -53,9 +56,9 @@ class Fancy AST {
|
|
|
53
56
|
def bytecode: g {
|
|
54
57
|
pos(g)
|
|
55
58
|
match @string {
|
|
56
|
-
case "true" -> g push_true()
|
|
57
|
-
case "false" -> g push_false()
|
|
58
|
-
case "nil" -> g push_nil()
|
|
59
|
+
# case "true" -> g push_true()
|
|
60
|
+
# case "false" -> g push_false()
|
|
61
|
+
# case "nil" -> g push_nil()
|
|
59
62
|
case _ ->
|
|
60
63
|
if: (g state() scope() search_local(name)) then: {
|
|
61
64
|
Rubinius AST LocalVariableAccess new(@line, name) bytecode(g)
|
|
@@ -115,5 +118,4 @@ class Fancy AST {
|
|
|
115
118
|
scoped bytecode(g)
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
|
-
|
|
119
121
|
}
|
|
@@ -44,7 +44,7 @@ class Fancy AST {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
class CurrentLine : Node {
|
|
47
|
-
def initialize: @line {}
|
|
47
|
+
def initialize: @line { }
|
|
48
48
|
def bytecode: g {
|
|
49
49
|
pos(g)
|
|
50
50
|
FixnumLiteral new: @line value: @line . bytecode: g
|
|
@@ -79,6 +79,13 @@ class Fancy AST {
|
|
|
79
79
|
pos(g)
|
|
80
80
|
bytecode(g)
|
|
81
81
|
}
|
|
82
|
+
def method_name: receiver ruby_send: ruby_send {
|
|
83
|
+
if: ruby_send then: {
|
|
84
|
+
'self
|
|
85
|
+
} else: {
|
|
86
|
+
':self
|
|
87
|
+
}
|
|
88
|
+
}
|
|
82
89
|
}
|
|
83
90
|
|
|
84
91
|
class SymbolLiteral : Rubinius AST SymbolLiteral {
|
data/lib/compiler/ast/match.fy
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
class Fancy AST {
|
|
2
|
-
|
|
3
2
|
class Match : Node {
|
|
4
3
|
def initialize: @line expr: @expr body: @clauses {
|
|
5
4
|
}
|
|
6
5
|
|
|
7
|
-
|
|
8
6
|
def bytecode: g set_match_args: clause {
|
|
9
7
|
"Generates bytecode for setting match clause arguments, if needed"
|
|
10
8
|
|
|
@@ -66,10 +64,22 @@ class Fancy AST {
|
|
|
66
64
|
clause_labels each_with_index: |label i| {
|
|
67
65
|
label set!()
|
|
68
66
|
g pop()
|
|
67
|
+
|
|
68
|
+
# set any new locals created in the match clause body to nil afterwards
|
|
69
|
+
# so they're only visible in the current clause body.
|
|
70
|
+
detected_locals = g detected_locals()
|
|
71
|
+
|
|
69
72
|
@clauses[i] body bytecode: g
|
|
70
73
|
|
|
74
|
+
new_detected_locals = g detected_locals()
|
|
75
|
+
new_detected_locals - detected_locals times: |i| {
|
|
76
|
+
g push_nil()
|
|
77
|
+
g set_local(i + detected_locals)
|
|
78
|
+
g pop()
|
|
79
|
+
}
|
|
80
|
+
|
|
71
81
|
# set match_arg locals slot to nil, so they're only visible
|
|
72
|
-
# within the
|
|
82
|
+
# within the match clause body
|
|
73
83
|
@match_arg_vars each: |marg_var| {
|
|
74
84
|
g push_nil()
|
|
75
85
|
g set_local(marg_var slot())
|
|
@@ -85,6 +95,7 @@ class Fancy AST {
|
|
|
85
95
|
|
|
86
96
|
class MatchClause : Node {
|
|
87
97
|
read_slots: ['expr, 'body, 'match_args]
|
|
98
|
+
|
|
88
99
|
def initialize: @line expr: @expr body: @body args: @match_args {
|
|
89
100
|
if: (@expr kind_of?: Identifier) then: {
|
|
90
101
|
if: (@expr string == "_") then: {
|
|
@@ -94,5 +105,4 @@ class Fancy AST {
|
|
|
94
105
|
@match_args = @match_args map: 'name
|
|
95
106
|
}
|
|
96
107
|
}
|
|
97
|
-
|
|
98
108
|
}
|
|
@@ -1,18 +1,45 @@
|
|
|
1
1
|
class Fancy AST {
|
|
2
|
-
|
|
3
2
|
class MessageSend : Node {
|
|
4
3
|
read_write_slots: ['name, 'receiver, 'args]
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
def initialize: @line message: @name to: @receiver (Self new: @line) args: @args (MessageArgs new: @line) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
def redirect_via: redirect_message {
|
|
9
|
+
message_name = SymbolLiteral new: @line value: (@name string to_sym)
|
|
10
|
+
orig_args = ArrayLiteral new: @line array: $ @args args
|
|
11
|
+
args = MessageArgs new: @line args: $ [message_name, orig_args]
|
|
12
|
+
|
|
13
|
+
ms = MessageSend new: @line \
|
|
14
|
+
message: (Identifier from: (redirect_message to_s) line: @line) \
|
|
15
|
+
to: @receiver \
|
|
16
|
+
args: args
|
|
17
|
+
}
|
|
6
18
|
|
|
7
19
|
def bytecode: g {
|
|
8
20
|
pos(g)
|
|
9
21
|
if: (@receiver is_a?: Super) then: {
|
|
10
22
|
SuperSend new: @line message: @name args: @args . bytecode: g
|
|
11
23
|
} else: {
|
|
24
|
+
|
|
25
|
+
# check if we might have a block invocation using block(x,y) syntax.
|
|
26
|
+
if: ruby_send? then: {
|
|
27
|
+
if: (@receiver is_a?: Self) then: {
|
|
28
|
+
if: (g state() scope() search_local(@name name)) then: {
|
|
29
|
+
@name bytecode: g
|
|
30
|
+
args = ArrayLiteral new: @line array: (@args args)
|
|
31
|
+
args bytecode: g
|
|
32
|
+
g send('call:, 1, false)
|
|
33
|
+
return nil
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
12
38
|
@receiver bytecode: g
|
|
13
39
|
@args bytecode: g
|
|
14
40
|
pos(g)
|
|
15
41
|
{ g allow_private() } if: (@receiver is_a?: Self)
|
|
42
|
+
|
|
16
43
|
sym = @name method_name: @receiver ruby_send: ruby_send?
|
|
17
44
|
if: has_splat? then: {
|
|
18
45
|
{ g push_nil() } unless: ruby_block?
|
|
@@ -41,8 +68,10 @@ class Fancy AST {
|
|
|
41
68
|
}
|
|
42
69
|
|
|
43
70
|
class MessageArgs : Node {
|
|
44
|
-
|
|
45
|
-
|
|
71
|
+
read_slot: 'args
|
|
72
|
+
|
|
73
|
+
def initialize: @line args: @args ([]) {
|
|
74
|
+
}
|
|
46
75
|
|
|
47
76
|
def bytecode: g {
|
|
48
77
|
pos(g)
|
|
@@ -70,7 +99,7 @@ class Fancy AST {
|
|
|
70
99
|
|
|
71
100
|
|
|
72
101
|
class RubyArgs : MessageArgs {
|
|
73
|
-
def initialize: @line args: @args block: @block (nil) {
|
|
102
|
+
def initialize: @line args: @args ([]) block: @block (nil) {
|
|
74
103
|
{ @args = @args array } unless: (@args is_a?: Array)
|
|
75
104
|
@block if_nil: {
|
|
76
105
|
if: (@args last kind_of?: Identifier) then: {
|
|
@@ -106,5 +135,4 @@ class Fancy AST {
|
|
|
106
135
|
@splat nil? not
|
|
107
136
|
}
|
|
108
137
|
}
|
|
109
|
-
|
|
110
138
|
}
|