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.
Files changed (182) hide show
  1. data/README.md +14 -14
  2. data/Rakefile +16 -4
  3. data/bin/fancy +3 -0
  4. data/bin/fspec +20 -0
  5. data/bin/fyi +27 -11
  6. data/bin/ifancy +1 -1
  7. data/boot/fancy_ext.rb +1 -0
  8. data/boot/fancy_ext/block_env.rb +1 -9
  9. data/boot/fancy_ext/delegator.rb +64 -0
  10. data/boot/fancy_ext/object.rb +4 -0
  11. data/boot/fancy_ext/thread.rb +4 -0
  12. data/boot/load.rb +5 -1
  13. data/boot/rbx-compiler/compiler/ast.rb +0 -1
  14. data/boot/rbx-compiler/compiler/ast/class_def.rb +2 -0
  15. data/boot/rbx-compiler/compiler/ast/method_def.rb +2 -0
  16. data/boot/rbx-compiler/compiler/ast/node.rb +10 -0
  17. data/boot/rbx-compiler/compiler/ast/ruby_args.rb +12 -0
  18. data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +2 -0
  19. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  20. data/boot/rbx-compiler/parser/lexer.lex +5 -11
  21. data/boot/rbx-compiler/parser/parser.rb +16 -5
  22. data/boot/rbx-compiler/parser/parser.y +39 -24
  23. data/doc/api/fancy.css +1 -1
  24. data/doc/api/fancy.jsonp +1 -1
  25. data/doc/api/fdoc.js +22 -4
  26. data/doc/api/index.html +5 -6
  27. data/doc/api/jquery-ui.min.js +401 -0
  28. data/doc/api/jquery.tools.min.js +192 -0
  29. data/doc/api/themeswitchertool.js +250 -0
  30. data/doc/features.md +17 -0
  31. data/examples/actor_bunnies.fy +32 -0
  32. data/examples/actors.fy +26 -0
  33. data/examples/actors_primitive.fy +27 -0
  34. data/examples/actors_ring.fy +37 -0
  35. data/examples/armstrong_numbers.fy +1 -1
  36. data/examples/array.fy +7 -9
  37. data/examples/async_send.fy +1 -2
  38. data/examples/blocks.fy +4 -4
  39. data/examples/call_with_receiver.fy +1 -1
  40. data/examples/class.fy +1 -1
  41. data/examples/default_args.fy +4 -1
  42. data/examples/define_methods.fy +2 -2
  43. data/examples/echo.fy +1 -1
  44. data/examples/factorial.fy +1 -1
  45. data/examples/future_composition.fy +2 -2
  46. data/examples/futures.fy +0 -5
  47. data/examples/game_of_life.fy +1 -1
  48. data/examples/person.fy +1 -1
  49. data/lib/argv.fy +7 -2
  50. data/lib/array.fy +109 -42
  51. data/lib/block.fy +39 -14
  52. data/lib/boot.fy +2 -0
  53. data/lib/class.fy +2 -0
  54. data/lib/compiler/ast.fy +2 -1
  55. data/lib/compiler/ast/assign.fy +2 -3
  56. data/lib/compiler/ast/async_send.fy +1 -15
  57. data/lib/compiler/ast/class_def.fy +2 -1
  58. data/lib/compiler/ast/expression_list.fy +4 -5
  59. data/lib/compiler/ast/future_send.fy +1 -10
  60. data/lib/compiler/ast/goto.fy +46 -0
  61. data/lib/compiler/ast/identifier.fy +9 -7
  62. data/lib/compiler/ast/literals.fy +8 -1
  63. data/lib/compiler/ast/match.fy +14 -4
  64. data/lib/compiler/ast/message_send.fy +34 -6
  65. data/lib/compiler/ast/method_def.fy +6 -6
  66. data/lib/compiler/ast/node.fy +3 -3
  67. data/lib/compiler/ast/range.fy +1 -0
  68. data/lib/compiler/ast/script.fy +0 -2
  69. data/lib/compiler/ast/singleton_method_def.fy +2 -4
  70. data/lib/compiler/ast/string_interpolation.fy +17 -0
  71. data/lib/compiler/ast/super.fy +5 -4
  72. data/lib/compiler/ast/try_catch.fy +8 -6
  73. data/lib/compiler/ast/tuple_literal.fy +3 -2
  74. data/lib/compiler/command.fy +0 -1
  75. data/lib/compiler/compiler.fy +1 -5
  76. data/lib/compiler/stages.fy +6 -14
  77. data/lib/documentation.fy +57 -46
  78. data/lib/enumerable.fy +257 -23
  79. data/lib/enumerator.fy +122 -15
  80. data/lib/false_class.fy +10 -1
  81. data/lib/fancy_spec.fy +263 -61
  82. data/lib/fdoc.fy +11 -25
  83. data/lib/fiber.fy +11 -0
  84. data/lib/file.fy +8 -11
  85. data/lib/future.fy +84 -5
  86. data/lib/hash.fy +65 -14
  87. data/lib/integer.fy +35 -0
  88. data/lib/iteration.fy +54 -29
  89. data/lib/message.fy +6 -0
  90. data/lib/method.fy +0 -16
  91. data/lib/nil_class.fy +58 -8
  92. data/lib/number.fy +49 -22
  93. data/lib/object.fy +371 -65
  94. data/lib/package.fy +24 -1
  95. data/lib/package/installer.fy +5 -9
  96. data/lib/package/specification.fy +2 -2
  97. data/lib/parser/ext/lexer.lex +15 -11
  98. data/lib/parser/ext/parser.y +70 -23
  99. data/lib/parser/methods.fy +33 -14
  100. data/lib/proxy.fy +33 -3
  101. data/lib/range.fy +28 -0
  102. data/lib/rbx.fy +3 -1
  103. data/lib/rbx/actor.fy +53 -0
  104. data/lib/rbx/alpha.fy +31 -0
  105. data/lib/rbx/array.fy +21 -12
  106. data/lib/rbx/bignum.fy +6 -2
  107. data/lib/rbx/block.fy +23 -26
  108. data/lib/rbx/class.fy +54 -2
  109. data/lib/rbx/code_loader.fy +8 -4
  110. data/lib/rbx/date.fy +9 -0
  111. data/lib/rbx/directory.fy +18 -0
  112. data/lib/rbx/environment_variables.fy +1 -0
  113. data/lib/rbx/exception.fy +9 -2
  114. data/lib/rbx/fiber.fy +22 -4
  115. data/lib/rbx/file.fy +5 -5
  116. data/lib/rbx/fixnum.fy +5 -0
  117. data/lib/rbx/float.fy +11 -3
  118. data/lib/rbx/hash.fy +31 -16
  119. data/lib/rbx/integer.fy +1 -0
  120. data/lib/rbx/io.fy +17 -7
  121. data/lib/rbx/match_data.fy +15 -4
  122. data/lib/rbx/method.fy +40 -7
  123. data/lib/rbx/name_error.fy +4 -0
  124. data/lib/rbx/object.fy +92 -24
  125. data/lib/rbx/range.fy +20 -6
  126. data/lib/rbx/regexp.fy +11 -3
  127. data/lib/rbx/string.fy +51 -1
  128. data/lib/rbx/stringio.fy +17 -0
  129. data/lib/rbx/symbol.fy +15 -1
  130. data/lib/rbx/system.fy +20 -2
  131. data/lib/rbx/tcp_server.fy +4 -1
  132. data/lib/rbx/tcp_socket.fy +11 -0
  133. data/lib/rbx/time.fy +6 -0
  134. data/lib/rbx/tuple.fy +14 -5
  135. data/lib/set.fy +144 -29
  136. data/lib/stack.fy +42 -11
  137. data/lib/string.fy +118 -8
  138. data/lib/struct.fy +13 -3
  139. data/lib/symbol.fy +21 -2
  140. data/lib/thread_pool.fy +2 -1
  141. data/lib/true_class.fy +45 -7
  142. data/lib/tuple.fy +27 -9
  143. data/lib/version.fy +2 -2
  144. data/ruby_lib/fancy +43 -0
  145. data/ruby_lib/fdoc +23 -0
  146. data/ruby_lib/fspec +3 -0
  147. data/ruby_lib/fyi +3 -0
  148. data/ruby_lib/ifancy +3 -0
  149. data/tests/argv.fy +5 -9
  150. data/tests/array.fy +323 -196
  151. data/tests/assignment.fy +29 -29
  152. data/tests/block.fy +72 -59
  153. data/tests/class.fy +227 -138
  154. data/tests/control_flow.fy +83 -51
  155. data/tests/documentation.fy +8 -8
  156. data/tests/enumerable.fy +8 -0
  157. data/tests/enumerator.fy +47 -29
  158. data/tests/exception.fy +49 -32
  159. data/tests/file.fy +28 -28
  160. data/tests/fixnum.fy +170 -0
  161. data/tests/future.fy +24 -7
  162. data/tests/hash.fy +55 -38
  163. data/tests/method.fy +50 -43
  164. data/tests/nil_class.fy +37 -37
  165. data/tests/object.fy +152 -70
  166. data/tests/pattern_matching.fy +67 -31
  167. data/tests/range.fy +6 -6
  168. data/tests/set.fy +101 -4
  169. data/tests/stack.fy +14 -5
  170. data/tests/string.fy +115 -61
  171. data/tests/stringio.fy +18 -0
  172. data/tests/struct.fy +27 -0
  173. data/tests/symbol.fy +19 -6
  174. data/tests/true_class.fy +34 -34
  175. data/tests/tuple.fy +30 -12
  176. metadata +103 -81
  177. data/boot/rbx-compiler/compiler/ast/require.rb +0 -20
  178. data/examples/actor.fy +0 -37
  179. data/examples/curl_async.fy +0 -37
  180. data/lib/compiler/ast/require.fy +0 -15
  181. data/tests/number.fy +0 -135
  182. data/tests/parsing/sexp.fy +0 -50
@@ -28,27 +28,38 @@ class Block {
28
28
  { call not } while_true: block
29
29
  }
30
30
 
31
- def while_nil: block {
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
- call if_true: |val| {
40
- work call: [val]
41
- } else: {
42
- break
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
- } loop
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
- Calls a given Block as long as @self returns @nil or @false.
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
- "Calls itself if the given object is true-ish."
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
- "Opposite of Block#if:. Calls itself if the given object is false-ish."
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
  }
@@ -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"
@@ -6,6 +6,8 @@ class Class {
6
6
  or Smalltalk.
7
7
  """
8
8
 
9
+ forwards_unary_ruby_methods
10
+
9
11
  def define_slot_reader: slotname {
10
12
  """
11
13
  @slotname Name of the slot to define a getter method for.
@@ -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"
@@ -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
- read_slots: ['expressions]
5
- def initialize: @line list: @expressions ([]) {}
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
- read_write_slots: ['ruby_ident]
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 {
@@ -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 case body
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
- def initialize: @line message: @name to: @receiver args: @args { }
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
- read_slots: ['args]
45
- def initialize: @line args: @args { }
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
  }