fancy 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }