fancy 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/README.md +4 -1
  2. data/Rakefile +8 -0
  3. data/bin/fyi +25 -20
  4. data/bin/ifancy +39 -5
  5. data/{extconf.rb → boot/extconf.rb} +1 -1
  6. data/boot/fancy_ext/block_env.rb +0 -14
  7. data/boot/fancy_ext/kernel.rb +6 -2
  8. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  9. data/examples/actor.fy +37 -0
  10. data/examples/armstrong_numbers.fy +1 -1
  11. data/examples/curl_async.fy +37 -0
  12. data/examples/echo.fy +1 -1
  13. data/examples/factorial.fy +1 -1
  14. data/examples/future_composition.fy +20 -0
  15. data/examples/game_of_life.fy +2 -2
  16. data/examples/person.fy +4 -8
  17. data/examples/rbx/blocks.fy +1 -1
  18. data/examples/return.fy +1 -1
  19. data/examples/struct.fy +9 -0
  20. data/lib/argv.fy +2 -2
  21. data/lib/array.fy +157 -0
  22. data/lib/block.fy +18 -1
  23. data/lib/boot.fy +5 -1
  24. data/lib/compiler/ast/class_def.fy +1 -1
  25. data/lib/compiler/ast/identifier.fy +2 -2
  26. data/lib/compiler/ast/message_send.fy +2 -2
  27. data/lib/compiler/ast/method_def.fy +2 -2
  28. data/lib/compiler/ast/try_catch.fy +5 -1
  29. data/lib/documentation.fy +1 -1
  30. data/lib/enumerable.fy +3 -7
  31. data/lib/enumerator.fy +77 -0
  32. data/lib/false_class.fy +52 -0
  33. data/lib/fancy_spec.fy +40 -12
  34. data/lib/fdoc.fy +2 -2
  35. data/lib/file.fy +8 -1
  36. data/lib/future.fy +23 -2
  37. data/lib/iteration.fy +60 -0
  38. data/lib/main.fy +4 -4
  39. data/lib/nil_class.fy +14 -22
  40. data/lib/number.fy +51 -0
  41. data/lib/object.fy +126 -43
  42. data/lib/package/installer.fy +1 -1
  43. data/lib/parser/ext/lexer.lex +6 -1
  44. data/lib/parser/ext/parser.y +18 -0
  45. data/lib/parser/methods.fy +20 -2
  46. data/lib/proxy.fy +20 -3
  47. data/lib/rbx.fy +0 -1
  48. data/lib/rbx/array.fy +4 -138
  49. data/lib/rbx/block.fy +25 -1
  50. data/lib/rbx/class.fy +21 -0
  51. data/lib/rbx/exception.fy +1 -0
  52. data/lib/rbx/fiber.fy +1 -0
  53. data/lib/rbx/file.fy +8 -0
  54. data/lib/rbx/integer.fy +0 -8
  55. data/lib/rbx/method.fy +34 -7
  56. data/lib/rbx/no_method_error.fy +8 -1
  57. data/lib/rbx/object.fy +3 -32
  58. data/lib/rbx/range.fy +13 -1
  59. data/lib/rbx/regexp.fy +3 -0
  60. data/lib/rbx/string.fy +6 -1
  61. data/lib/rbx/system.fy +20 -2
  62. data/lib/set.fy +2 -2
  63. data/lib/string.fy +1 -1
  64. data/lib/struct.fy +15 -12
  65. data/lib/symbol.fy +2 -2
  66. data/lib/true_class.fy +16 -20
  67. data/lib/version.fy +1 -1
  68. data/tests/argv.fy +1 -0
  69. data/tests/array.fy +33 -2
  70. data/tests/block.fy +44 -0
  71. data/tests/class.fy +102 -88
  72. data/tests/control_flow.fy +131 -8
  73. data/tests/enumerator.fy +85 -0
  74. data/tests/exception.fy +13 -13
  75. data/tests/file.fy +4 -13
  76. data/tests/future.fy +26 -0
  77. data/tests/method.fy +83 -72
  78. data/tests/nil_class.fy +20 -13
  79. data/tests/number.fy +16 -9
  80. data/tests/object.fy +39 -20
  81. data/tests/string.fy +7 -0
  82. data/tests/true_class.fy +4 -4
  83. data/tools/fancy-mode.el +1 -1
  84. metadata +15 -20
  85. data/boot/compiler/parser/ext/fancy_parser.bundle +0 -0
  86. data/boot/rbx-compiler/parser/Makefile +0 -162
  87. data/boot/rbx-compiler/parser/lexer.c +0 -2316
  88. data/boot/rbx-compiler/parser/lexer.h +0 -315
  89. data/boot/rbx-compiler/parser/parser.c +0 -3105
  90. data/boot/rbx-compiler/parser/parser.h +0 -114
  91. data/lib/lazy_array.fy +0 -23
  92. data/lib/parser/ext/Makefile +0 -162
  93. data/lib/parser/ext/fancy_parser.bundle +0 -0
  94. data/lib/parser/ext/lexer.c +0 -2360
  95. data/lib/parser/ext/lexer.h +0 -315
  96. data/lib/parser/ext/parser.c +0 -3382
  97. data/lib/parser/ext/parser.h +0 -118
  98. data/lib/rbx/false_class.fy +0 -58
data/tests/block.fy CHANGED
@@ -139,4 +139,48 @@ FancySpec describe: Block with: {
139
139
  b receiver: "Hello, World!"
140
140
  b receiver should == "Hello, World!"
141
141
  }
142
+
143
+ it: "should call a block with a different receiver" for: 'call_with_receiver when: {
144
+ class ClassA {
145
+ def inspect {
146
+ "in ClassA#inspect"
147
+ }
148
+ }
149
+ class ClassB {
150
+ def inspect {
151
+ "in ClassB#inspect"
152
+ }
153
+ }
154
+ def self inspect {
155
+ "in self#inspect"
156
+ }
157
+ block = {
158
+ self inspect
159
+ }
160
+ block call should == "in self#inspect"
161
+ block call_with_receiver: (ClassA new) . should == "in ClassA#inspect"
162
+ block call_with_receiver: (ClassB new) . should == "in ClassB#inspect"
163
+ }
164
+
165
+ it: "should call a block with arguments and a different receiver" for: 'call:with_receiver: when: {
166
+ class ClassC {
167
+ def inspect: x {
168
+ "in ClassC#inspect: #{x}"
169
+ }
170
+ }
171
+ class ClassD {
172
+ def inspect: x {
173
+ "in ClassD#inspect: #{x}"
174
+ }
175
+ }
176
+ def self inspect: x {
177
+ "in self#inspect: #{x}"
178
+ }
179
+ block = |arg| {
180
+ self inspect: arg
181
+ }
182
+ block call: [42] . should == "in self#inspect: 42"
183
+ block call: [42] with_receiver: (ClassC new) . should == "in ClassC#inspect: 42"
184
+ block call: [42] with_receiver: (ClassD new) . should == "in ClassD#inspect: 42"
185
+ }
142
186
  }
data/tests/class.fy CHANGED
@@ -172,34 +172,34 @@ FancySpec describe: Class with: {
172
172
  instance foo: "Test!" . should == "In AClass#foo: with bar = Test!"
173
173
  }
174
174
 
175
- # it: "should call superclass method by calling super" when: {
176
- # class SuperClass {
177
- # read_slots: ['name]
178
- # def initialize: name {
179
- # @name = name
180
- # }
181
- # }
182
- # class SubClass : SuperClass {
183
- # read_slots: ['age]
175
+ it: "should call superclass method by using super" when: {
176
+ class SuperClass {
177
+ read_slots: ['name]
178
+ def initialize: name {
179
+ @name = name
180
+ }
181
+ }
182
+ class SubClass : SuperClass {
183
+ read_slots: ['age]
184
184
 
185
- # def initialize: age {
186
- # super initialize: "SubClass"
187
- # @age = age
188
- # }
189
- # def initialize {
190
- # super initialize: "SubClass"
191
- # @age = 0
192
- # }
193
- # }
185
+ def initialize: age {
186
+ super initialize: "SubClass"
187
+ @age = age
188
+ }
189
+
190
+ def initialize {
191
+ initialize: 0
192
+ }
193
+ }
194
194
 
195
- # sub = SubClass new: 42
196
- # sub name should == "SubClass"
197
- # sub age should == 42
195
+ sub = SubClass new: 42
196
+ sub name should == "SubClass"
197
+ sub age should == 42
198
198
 
199
- # sub2 = SubClass new
200
- # sub2 name should == "SubClass"
201
- # sub2 age should == 0
202
- # }
199
+ sub2 = SubClass new
200
+ sub2 name should == "SubClass"
201
+ sub2 age should == 0
202
+ }
203
203
 
204
204
  it: "should return its superclass" when: {
205
205
  Fixnum superclass should == Integer
@@ -212,19 +212,19 @@ FancySpec describe: Class with: {
212
212
  NoMethodError superclass should == NameError
213
213
  }
214
214
 
215
- # it: "should create a new Class dynamically" when: {
216
- # x = Class new
217
- # x is_a?: Class . should == true
218
- # x new is_a?: x . should == true
219
- # x new is_a?: Object . should == true
220
- # x new class should == x
221
-
222
- # # Symbol as superclass
223
- # y = Class new: Symbol
224
- # y is_a?: Class . should == true
225
- # y new is_a?: Symbol . should == true
226
- # y new is_a?: Object . should == true
227
- # }
215
+ it: "should create a new Class dynamically" when: {
216
+ x = Class new
217
+ x is_a?: Class . should == true
218
+ x new is_a?: x . should == true
219
+ x new is_a?: Object . should == true
220
+ x new class should == x
221
+
222
+ # Symbol as superclass
223
+ y = Class new: String
224
+ y is_a?: Class . should == true
225
+ y new is_a?: String . should == true
226
+ # y new is_a?: Object . should == true
227
+ }
228
228
 
229
229
  it: "should only be able to call the public method from outside the Class" when: {
230
230
  x = ClassWithPrivate new
@@ -232,12 +232,12 @@ FancySpec describe: Class with: {
232
232
  try {
233
233
  x private_method should == nil # should fail
234
234
  } catch NoMethodError => e {
235
- e method_name should == "private_method"
235
+ e method_name should == 'private_method
236
236
  }
237
237
  try {
238
238
  x protected_method should == nil # should fail
239
239
  } catch NoMethodError => e {
240
- e method_name should == "protected_method"
240
+ e method_name should == 'protected_method
241
241
  }
242
242
  }
243
243
 
@@ -253,28 +253,28 @@ FancySpec describe: Class with: {
253
253
  Super subclass?: Sub . should == nil
254
254
  }
255
255
 
256
- # it: "should dynamically create a subclass of another class" for: 'is_a?: when: {
257
- # subclass = String subclass: {
258
- # def foo {
259
- # "hello, world!"
260
- # }
261
- # }
262
- # subclass is_a?: Class . should == true
263
- # subclass subclass?: String . should == true
264
- # subclass new is_a?: subclass . should == true
265
- # subclass new foo should == "hello, world!"
266
-
267
- # # now the same with Class##new:body:
268
- # subclass2 = Class superclass: Symbol body: {
269
- # def foo {
270
- # "hello, world, again!"
271
- # }
272
- # }
273
- # subclass2 is_a?: Class . should == true
274
- # subclass2 subclass?: String . should == true
275
- # subclass2 new is_a?: subclass2 . should == true
276
- # subclass2 new foo should == "hello, world, again!"
277
- # }
256
+ it: "should dynamically create a subclass of another class" for: 'is_a?: when: {
257
+ subclass = String subclass: {
258
+ def foo {
259
+ "hello, world!"
260
+ }
261
+ }
262
+ subclass is_a?: Class . should == true
263
+ subclass subclass?: String . should == true
264
+ subclass new is_a?: subclass . should == true
265
+ subclass new foo should == "hello, world!"
266
+
267
+ # now the same with Class##new:body:
268
+ subclass2 = Class superclass: String body: {
269
+ def foo {
270
+ "hello, world, again!"
271
+ }
272
+ }
273
+ subclass2 is_a?: Class . should == true
274
+ subclass2 subclass?: String . should == true
275
+ subclass2 new is_a?: subclass2 . should == true
276
+ subclass2 new foo should == "hello, world, again!"
277
+ }
278
278
 
279
279
  it: "should undefine an instance method" for: 'undefine_method: when: {
280
280
  class Foo {
@@ -288,7 +288,7 @@ FancySpec describe: Class with: {
288
288
  try {
289
289
  f instance_method should == nil # should not get here
290
290
  } catch NoMethodError => e {
291
- e method_name should == "instance_method"
291
+ e method_name should == 'instance_method
292
292
  }
293
293
  }
294
294
 
@@ -312,34 +312,34 @@ FancySpec describe: Class with: {
312
312
  try {
313
313
  Foo class_method should == nil # should not get here
314
314
  } catch NoMethodError => e {
315
- e method_name should == "class_method"
315
+ e method_name should == 'class_method
316
316
  }
317
317
  }
318
318
 
319
- # it: "should have nested classes" when: {
320
- # class Outer {
321
- # class Inner {
322
- # class InnerMost {
323
- # def foobar {
324
- # "foobar!"
325
- # }
326
- # }
327
- # }
328
- # }
329
- # Outer is_a?: Class . should == true
330
- # Outer::Inner is_a?: Class . should == true
331
- # Outer::Inner::InnerMost is_a?: Class . should == true
332
- # obj = Outer::Inner::InnerMost new
333
- # obj foobar should == "foobar!"
334
-
335
- # # change InnerMost#foobar
336
- # class Outer::Inner::InnerMost {
337
- # def foobar {
338
- # "oh no!"
339
- # }
340
- # }
341
- # obj foobar . should == "oh no!"
342
- # }
319
+ it: "should have nested classes" when: {
320
+ class Outer {
321
+ class Inner {
322
+ class InnerMost {
323
+ def foobar {
324
+ "foobar!"
325
+ }
326
+ }
327
+ }
328
+ }
329
+ Outer is_a?: Class . should == true
330
+ Outer::Inner is_a?: Class . should == true
331
+ Outer::Inner::InnerMost is_a?: Class . should == true
332
+ obj = Outer::Inner::InnerMost new
333
+ obj foobar should == "foobar!"
334
+
335
+ # change InnerMost#foobar
336
+ class Outer::Inner::InnerMost {
337
+ def foobar {
338
+ "oh no!"
339
+ }
340
+ }
341
+ obj foobar . should == "oh no!"
342
+ }
343
343
 
344
344
  it: "should not override existing classes with the same name in a nested class" when: {
345
345
  StdArray = Array
@@ -433,6 +433,20 @@ FancySpec describe: Class with: {
433
433
  obj bar should == "in foo!"
434
434
  }
435
435
 
436
+ it: "should have an alias method for a ruby method defined" for: 'alias_method:for_ruby: when: {
437
+ try {
438
+ [] equal?: [1,2] . should == true # should fail
439
+ } catch NoMethodError => e {
440
+ e method_name should == 'equal?:
441
+ }
442
+
443
+ class Array {
444
+ alias_method: 'equal?: for_ruby: 'equal?
445
+ }
446
+
447
+ [] equal?: [1,2] . should == false
448
+ }
449
+
436
450
  it: "should have the correct list of ancestors" for: 'ancestors when: {
437
451
  class A {
438
452
  }
@@ -43,37 +43,160 @@ FancySpec describe: "Control Flow" with: {
43
43
  }
44
44
  }
45
45
 
46
- it: "should only call the block if it's a true-ish value" for: 'if_do: when: {
47
- 1 if_do: |num| {
46
+ it: "should only call the block if it's a true-ish value" for: 'if_true: when: {
47
+ 1 if_true: |num| {
48
48
  num * 10
49
49
  } . should == 10
50
50
 
51
- nil if_do: {
51
+ nil if_true: {
52
52
  "nope"
53
53
  } . should == nil
54
54
 
55
- false if_do: {
55
+ false if_true: {
56
56
  "nope again"
57
57
  } . should == nil
58
58
  }
59
59
 
60
- it: "should call the then_block if it's a true-ish value and call the else_block otherwise" for: 'if_do:else: when: {
61
- 1 if_do: |num| {
60
+ it: "should call the then_block if it's a true-ish value and call the else_block otherwise" for: 'if_true:else: when: {
61
+ 1 if_true: |num| {
62
62
  num * 10
63
63
  } else: {
64
64
  nil
65
65
  } . should == 10
66
66
 
67
- nil if_do: {
67
+ nil if_true: {
68
68
  "nope"
69
69
  } else: {
70
70
  "yup"
71
71
  } . should == "yup"
72
72
 
73
- false if_do: {
73
+ false if_true: {
74
74
  "nope again"
75
75
  } else: {
76
76
  "yup again"
77
77
  } . should == "yup again"
78
78
  }
79
+
80
+ it: "should be possible to override the if_true:else: method and work accordingly in conditionals" when: {
81
+ class AClasThatIsLikeFalse {
82
+ def if_true: block else: another_block {
83
+ another_block call
84
+ }
85
+ }
86
+
87
+ obj = AClasThatIsLikeFalse new
88
+ if: obj then: {
89
+ 'fail
90
+ } else: {
91
+ 'success
92
+ } . should == 'success
93
+
94
+ # let's get rid of this custom if_true:else: method
95
+ AClasThatIsLikeFalse undefine_method: 'if_true:else:
96
+
97
+ if: obj then: {
98
+ 'now_this_is_success
99
+ } else: {
100
+ 'fail
101
+ } . should == 'now_this_is_success
102
+ }
103
+
104
+ it: "should break from an iteration" for: 'break when: {
105
+ x = 0
106
+ until: { x == 10 } do: {
107
+ x = x + 1
108
+ { break } if: (x == 5)
109
+ }
110
+ x == 5 should == true
111
+ }
112
+
113
+ it: "should break from an iteration with return value" for: 'break: when: {
114
+ x = 0
115
+ y = until: { x == 10 } do: {
116
+ x = x + 1
117
+ { break: 42 } if: (x == 5)
118
+ }
119
+
120
+ x should == 5
121
+ y should == 42
122
+ }
123
+
124
+ it: "should skip an iteration over a Range" for: 'next when: {
125
+ total = 0
126
+ (1..10) each: |i| {
127
+ { next } if: (i == 5)
128
+ total = total + i
129
+ }
130
+ total should == 50
131
+ }
132
+
133
+ it: "should skip an iteration over an Array" for: 'next when: {
134
+ total = 0
135
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] each: |i| {
136
+ { next } if: (i == 5)
137
+ total = total + i
138
+ }
139
+ total should == 50
140
+ }
141
+
142
+ it: "should skip an iteration over an Hash" for: 'next when: {
143
+ total = 0
144
+ <['a => 1, 'b => 2, 'c => 3, 'd => 4, 'e => 5, 'f => 6]> each: |k v| {
145
+ { next } if: (k == 'd)
146
+ total = total + v
147
+ }
148
+ total should == 17
149
+ }
150
+
151
+ it: "stops any loop type at the correct spot" for: 'break when: {
152
+ i = 0
153
+ loop: {
154
+ { break } if: (i == 3)
155
+ i = i + 1
156
+ }
157
+ i should == 3
158
+
159
+ i = 0
160
+ while: { i < 5 } do: {
161
+ { break } if: (i == 3)
162
+ i = i + 1
163
+ }
164
+ i should == 3
165
+
166
+ i = 0
167
+ 0 upto: 5 do: |n| {
168
+ i = n
169
+ { break } if: (n == 3)
170
+ }
171
+ i should == 3
172
+ }
173
+
174
+ it: "stops any loop type at the correct spot" for: 'break: when: {
175
+ i = 0
176
+ loop: {
177
+ { break: i } if: (i == 2)
178
+ i = i + 1
179
+ } . should == 2
180
+
181
+ i = 0
182
+ while: { i < 5 } do: {
183
+ { break: i } if: (i == 2)
184
+ i = i + 1
185
+ } . should == 2
186
+
187
+ i = 0
188
+ 0 upto: 5 do: |n| {
189
+ i = n
190
+ { break: n } if: (n == 2)
191
+ }
192
+ i should == 2
193
+ }
194
+
195
+ it: "should allow empty try blocks" when: {
196
+ x = "foo"
197
+ try {
198
+ } finally {
199
+ x should == "foo"
200
+ }
201
+ }
79
202
  }