fancy 0.3.2 → 0.3.3

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 (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
@@ -0,0 +1,85 @@
1
+ FancySpec describe: FancyEnumerator with: {
2
+ it: "iterates with 'next" for: 'new: when: {
3
+ enum = FancyEnumerator new: (42..50)
4
+ enum next should == 42
5
+ enum next should == 43
6
+ }
7
+
8
+ it: "peeks to find next element" for: 'peek when: {
9
+ enum = FancyEnumerator new: (42..50)
10
+ enum peek should == 42
11
+ enum peek should == 42
12
+ enum next should == 42
13
+
14
+ enum peek should == 43
15
+ enum peek should == 43
16
+ enum next should == 43
17
+ }
18
+
19
+ it: "turns an object with 'each: into an FancyEnumerator" for: 'to_enum when: {
20
+ enum = (42..45) to_enum
21
+ enum next should == 42
22
+ }
23
+
24
+ it: "turns an object with given method into an FancyEnumerator" for: 'to_enum: when: {
25
+ o = {}
26
+ def o iter: block {
27
+ 1 upto: 10 do: block
28
+ }
29
+ enum = o to_enum: 'iter:
30
+ enum next should == 1
31
+ }
32
+
33
+ it: "rewinds to the beginning of the iteration" for: 'rewind when: {
34
+ enum = (42..45) to_enum
35
+ check = {
36
+ enum peek should == 42
37
+ enum next should == 42
38
+ enum peek should == 43
39
+ enum next should == 43
40
+ }
41
+
42
+ check call
43
+ enum rewind
44
+ check call
45
+ }
46
+
47
+ it: "raises Fancy StopIteration when out of values" for: 'next when: {
48
+ o = Object new
49
+ def o each: block { block call: [1] }
50
+ e = o to_enum
51
+
52
+ e next should == 1
53
+ try {
54
+ e next
55
+ "We should not reach this line" should == true
56
+ } catch (Fancy StopIteration) => ex {
57
+ ex result should == nil
58
+ }
59
+ }
60
+
61
+ it: "sets result on Fancy StopIteration when out of values" for: 'next when: {
62
+ o = Object new
63
+ def o each: block {
64
+ block call: [1]
65
+ 42
66
+ }
67
+ e = o to_enum
68
+
69
+ e next should == 1
70
+ try {
71
+ e next
72
+ "We should not reach this line" should == true
73
+ } catch (Fancy StopIteration) => ex {
74
+ ex result should == 42
75
+ }
76
+ }
77
+
78
+ it: "iterates with an object" for: 'with:each: when: {
79
+ enum = (42..45) to_enum
80
+ result = enum with: [] each: |val, obj| { obj << val }
81
+ result should == [42, 43, 44, 45]
82
+ }
83
+ }
84
+
85
+ # => [:each, :each_with_index, :each_with_object, :with_index, :with_object, :next_values, :peek_values, :next, :peek, :feed, :rewind, :inspect]
data/tests/exception.fy CHANGED
@@ -70,20 +70,20 @@ FancySpec describe: StdError with: {
70
70
  }
71
71
  }
72
72
 
73
- # it: "should raise and catch a custom exception correctly" for: 'raise! when: {
74
- # class MyError : StdError{
75
- # def initialize {
76
- # super initialize: "MyError message"
77
- # }
78
- # }
73
+ it: "should raise and catch a custom exception correctly" for: 'raise! when: {
74
+ class MyError : StdError{
75
+ def initialize {
76
+ initialize: "MyError message"
77
+ }
78
+ }
79
79
 
80
- # try {
81
- # MyError new raise!
82
- # nil should == true # will fail
83
- # } catch MyError => e {
84
- # e message should == "MyError message"
85
- # }
86
- # }
80
+ try {
81
+ MyError new raise!
82
+ nil should == true # will fail
83
+ } catch MyError => e {
84
+ e message should == "MyError message"
85
+ }
86
+ }
87
87
 
88
88
  it: "should restart itself after being fixed in a catch clause" when: {
89
89
  y = 0
data/tests/file.fy CHANGED
@@ -12,12 +12,9 @@ FancySpec describe: File with: {
12
12
  file open? should == false
13
13
  }
14
14
 
15
- # it: "should be closed when not correctly opened" for: 'open? when: {
16
- # file = File new
17
- # file open? should == nil
18
- # file close
19
- # file open? should == nil
20
- # }
15
+ it: "should be closed when not correctly opened" for: 'open? when: {
16
+ { file = File new } should raise: ArgumentError
17
+ }
21
18
 
22
19
  it: "should write and read from a file correctly" for: 'writeln: when: {
23
20
  filename = "/tmp/read_write_test.txt"
@@ -43,13 +40,7 @@ FancySpec describe: File with: {
43
40
  }
44
41
 
45
42
  it: "should raise an IOError exception when trying to open an invalid file" when: {
46
- try {
47
- file = File open: "/foo/bar/baz" modes: ['read]
48
- nil should == true # this shouldn't execute
49
- } catch IOError => e {
50
- #e filename should == "/foo/bar/baz"
51
- #e modes should == ['read]
52
- }
43
+ { file = File open: "/foo/bar/baz" modes: ['read] } should raise: IOError
53
44
  }
54
45
 
55
46
  it: "should rename a File" when: {
data/tests/future.fy ADDED
@@ -0,0 +1,26 @@
1
+ FancySpec describe: Future with: {
2
+ it: "should compose Futures to create execution pipelines" for: '&& when: {
3
+ def some_computation: num {
4
+ num upto: (num ** num ** num)
5
+ }
6
+
7
+ f = self @ some_computation: 2 && @{select: 'even?} && 'size
8
+ f is_a?: Future . should == true
9
+ f value is_a?: Fixnum . should == true
10
+ }
11
+ }
12
+
13
+ FancySpec describe: FutureCollection with: {
14
+ it: "should execute a block for each future in the collection when it's ready" for: 'each: when: {
15
+ futures = 0 upto: 10 . map: |i| {
16
+ i ** i @ ** i
17
+ }
18
+
19
+ fc = FutureCollection new: futures
20
+ fc each: |val| {
21
+ val is_a?: Integer . should == true
22
+ }
23
+
24
+ fc await_all
25
+ }
26
+ }
data/tests/method.fy CHANGED
@@ -14,57 +14,57 @@ FancySpec describe: Method with: {
14
14
  # x give_me_the_sender! should == self
15
15
  # }
16
16
 
17
- # it: "should return the amount of arguments a Method takes" for: 'argcount when: {
18
- # class Foo {
19
- # def no_args {
20
- # }
21
- # def one_arg: yo {
22
- # }
23
- # def two: a args: b {
24
- # }
25
- # def three: a args: b ok: c {
26
- # }
27
- # }
17
+ it: "should return the amount of arguments a Method takes" for: 'argcount when: {
18
+ class Foo {
19
+ def no_args {
20
+ }
21
+ def one_arg: yo {
22
+ }
23
+ def two: a args: b {
24
+ }
25
+ def three: a args: b ok: c {
26
+ }
27
+ }
28
28
 
29
- # Foo method: 'no_args . argcount should == 0
30
- # Foo method: "one_arg:" . argcount should == 1
31
- # Foo method: "two:args:" . argcount should == 2
32
- # Foo method: "three:args:ok:" . argcount should == 3
33
- # }
29
+ Foo instance_method: 'no_args . arity should == 0
30
+ Foo instance_method: "one_arg:" . arity should == 1
31
+ Foo instance_method: "two:args:" . arity should == 2
32
+ Foo instance_method: "three:args:ok:" . arity should == 3
33
+ }
34
34
 
35
- # it: "should return the return value" when: {
36
- # def foo: bar {
37
- # return "returning!"
38
- # bar # will never get executed
39
- # }
35
+ it: "should return the return value" when: {
36
+ def foo: bar {
37
+ return "returning!"
38
+ bar # will never get executed
39
+ }
40
40
 
41
- # foo: "yay" . should == "returning!"
41
+ foo: "yay" . should == "returning!"
42
42
 
43
- # # another example
43
+ # another example
44
44
 
45
- # def f: x {
46
- # x < 10 if_true: {
47
- # return 100
48
- # }
49
- # 0
50
- # }
45
+ def f: x {
46
+ x < 10 if_true: {
47
+ return 100
48
+ }
49
+ 0
50
+ }
51
51
 
52
- # f: 10 . should == 0
53
- # f: 9 . should == 100
52
+ f: 10 . should == 0
53
+ f: 9 . should == 100
54
54
 
55
- # # and another one
55
+ # and another one
56
56
 
57
- # def foo {
58
- # 10 times: |i| {
59
- # i == 8 if_true: {
60
- # return i # nested return
61
- # }
62
- # }
63
- # return 0
64
- # }
57
+ def foo {
58
+ 10 times: |i| {
59
+ i == 8 if_true: {
60
+ return i # nested return
61
+ }
62
+ }
63
+ return 0
64
+ }
65
65
 
66
- # self foo should == 8
67
- # }
66
+ foo should == 8
67
+ }
68
68
 
69
69
  it: "should return only from block-scope not from method-scope" when: {
70
70
  def self foo {
@@ -75,42 +75,42 @@ FancySpec describe: Method with: {
75
75
  }
76
76
  0
77
77
  }
78
- self foo should == 8
78
+ foo should == 8
79
79
  }
80
80
 
81
- # it: "should return locally (from block-scope not from method-scope" when: {
82
- # def self foo {
83
- # [1,2,3] select: |x| { return_local x != 3 }
84
- # }
85
- # self foo should == [1,2]
86
- # }
81
+ it: "should return locally (from block-scope not from method-scope" when: {
82
+ def self foo {
83
+ [1,2,3] select: |x| { return_local x != 3 }
84
+ }
85
+ foo should == [1,2]
86
+ }
87
87
 
88
- # class Foo {
89
- # def bar {
90
- # }
91
- # def private private_bar {
92
- # }
93
- # def protected protected_bar {
94
- # }
95
- # }
88
+ class Foo {
89
+ def bar {
90
+ }
91
+ def private private_bar {
92
+ }
93
+ def protected protected_bar {
94
+ }
95
+ }
96
96
 
97
- # it: "should be public" for: 'public? when: {
98
- # Foo method: 'bar . public? should == true
99
- # Foo method: 'private_bar . public? should == nil
100
- # Foo method: 'protected_bar . public? should == nil
101
- # }
97
+ it: "should be public" for: 'public? when: {
98
+ Foo instance_method: 'bar . public? should == true
99
+ Foo instance_method: 'private_bar . public? should == false
100
+ Foo instance_method: 'protected_bar . public? should == false
101
+ }
102
102
 
103
- # it: "should be private" for: 'private? when: {
104
- # Foo method: 'bar . private? should == nil
105
- # Foo method: 'private_bar . private? should == true
106
- # Foo method: 'protected_bar . private? should == nil
107
- # }
103
+ it: "should be private" for: 'private? when: {
104
+ Foo instance_method: 'bar . private? should == false
105
+ Foo instance_method: 'private_bar . private? should == true
106
+ Foo instance_method: 'protected_bar . private? should == false
107
+ }
108
108
 
109
- # it: "should be protected" for: 'protected? when: {
110
- # Foo method: 'bar . protected? should == nil
111
- # Foo method: 'private_bar . protected? should == nil
112
- # Foo method: 'protected_bar . protected? should == true
113
- # }
109
+ it: "should be protected" for: 'protected? when: {
110
+ Foo instance_method: 'bar . protected? should == false
111
+ Foo instance_method: 'private_bar . protected? should == false
112
+ Foo instance_method: 'protected_bar . protected? should == true
113
+ }
114
114
 
115
115
  it: "should set the default values for optional argument, when not passed in" when: {
116
116
  def foo: arg1 bar: arg2 ("foo") baz: arg3 (nil) {
@@ -122,6 +122,17 @@ FancySpec describe: Method with: {
122
122
  foo: "hello" . should == "hellofoo"
123
123
  }
124
124
 
125
+ it: "should have default values for all arguments, if none given" when: {
126
+ def a: arg1 ("foo") b: arg2 ("bar") c: arg3 ("baz") {
127
+ [arg1, arg2, arg3]
128
+ }
129
+
130
+ a: "hello" b: "world" c: "!" . should == ["hello", "world", "!"]
131
+ a: "hello" b: "world" . should == ["hello", "world", "baz"]
132
+ a: "hello" . should == ["hello", "bar", "baz"]
133
+ a should == ["foo", "bar", "baz"]
134
+ }
135
+
125
136
  it: "should return multiple values (as a Tuple)" when: {
126
137
  def multiple_return_values: x {
127
138
  (x, x + x, x + x + x)
data/tests/nil_class.fy CHANGED
@@ -1,23 +1,30 @@
1
1
  FancySpec describe: NilClass with: {
2
2
  it: "should be false for calling and: with any value" for: 'and: when: {
3
- nil and: true . should == false
4
- nil and: 'foo . should == false
5
- nil and: nil . should == false
3
+ nil and: true . should == nil
4
+ nil and: 'foo . should == nil
5
+ nil and: nil . should == nil
6
+ false and: true . should == false
7
+ false and: 'foo . should == false
8
+ false and: nil . should == false
6
9
  }
7
10
 
8
- it: "should be false for calling && with any value" for: '&& when: {
9
- (nil && true) should == false
10
- (nil && 'foo) should == false
11
- (nil && nil) should == false
11
+ it: "should be nil/false for calling && with any value" for: '&& when: {
12
+ (nil && true) should == nil
13
+ (nil && 'foo) should == nil
14
+ (nil && nil) should == nil
15
+ (false && true) should == false
16
+ (false && 'foo) should == false
17
+ (false && nil) should == false
12
18
  }
13
19
 
14
20
  it: "should be true for calling or: with any non-nil value" for: 'or: when: {
15
21
  nil or: true . should == true
16
- nil or: 'foo . should == true
22
+ nil or: 'foo . should == 'foo
17
23
  }
18
24
 
19
- it: "should be nil for calling or: with a nil value" for: 'or: when: {
20
- nil or: nil . should == false
25
+ it: "should be nil/false for calling or: with a nil/false value" for: 'or: when: {
26
+ nil or: nil . should == nil
27
+ nil or: false . should == false
21
28
  }
22
29
 
23
30
  it: "should be true for calling || with any non-nil value" for: '|| when: {
@@ -33,8 +40,8 @@ FancySpec describe: NilClass with: {
33
40
  nil if_true: { 'then } . should == nil
34
41
  }
35
42
 
36
- it: "should call the block" for: 'if_false: when: {
37
- nil if_false: { 'false } . should == 'false
43
+ it: "should not call the block" for: 'if_false: when: {
44
+ nil if_false: { 'false } . should == nil
38
45
  }
39
46
 
40
47
  it: "should be nil" for: 'nil? when: {
@@ -42,7 +49,7 @@ FancySpec describe: NilClass with: {
42
49
  }
43
50
 
44
51
  it: "should be false" for: 'false? when: {
45
- nil false? should == true
52
+ nil false? should == false
46
53
  }
47
54
 
48
55
  it: "should NOT be true" for: 'true? when: {
data/tests/number.fy CHANGED
@@ -24,12 +24,7 @@ FancySpec describe: Number with: {
24
24
  }
25
25
 
26
26
  it: "should raise an exception when dividing by zero" when: {
27
- try {
28
- 10 / 0
29
- "This should not happen!" should == nil
30
- } catch ZeroDivisionError => err {
31
- err message should == "divided by 0"
32
- }
27
+ { 10 / 0 } should raise: ZeroDivisionError
33
28
  }
34
29
 
35
30
  it: "should calculate the correct modulo value" for: 'modulo: when: {
@@ -62,15 +57,27 @@ FancySpec describe: Number with: {
62
57
  0 upto: 10 . should == [0,1,2,3,4,5,6,7,8,9,10]
63
58
  }
64
59
 
60
+ it: "should iterate from 1 upto 10" for: 'upto:do: when: {
61
+ sum = 0
62
+ 1 upto: 10 do: |n| { sum = sum + n }
63
+ sum should == 55
64
+ }
65
+
65
66
  it: "should return an array from 10 downto 0" for: 'downto: when: {
66
67
  10 downto: 0 . should == [10,9,8,7,6,5,4,3,2,1,0]
67
68
  }
68
69
 
70
+ it: "should iterate from 10 downto 1" for: 'downto:do: when: {
71
+ sum = 0
72
+ 10 downto: 1 do: |n| { sum = sum + n }
73
+ sum should == 55
74
+ }
75
+
69
76
  it: "should calculate the given power of itself" for: '** when: {
70
77
  2 ** 3 should == 8
71
78
  2 ** 0 should == 1
72
79
  2 ** 1 should == 2
73
- 0 upto: 10 do_each: |i| {
80
+ 0 upto: 10 do: |i| {
74
81
  i ** 0 should == 1
75
82
  i ** 1 should == i
76
83
  i ** 2 should == (i squared)
@@ -80,7 +87,7 @@ FancySpec describe: Number with: {
80
87
  it: "should be the square of self" for: 'squared when: {
81
88
  5 squared should == 25
82
89
  10 squared should == 100
83
- 20 upto: 50 do_each: |i| {
90
+ 20 upto: 50 do: |i| {
84
91
  i squared should == (i * i)
85
92
  }
86
93
  }
@@ -88,7 +95,7 @@ FancySpec describe: Number with: {
88
95
  it: "should be the double value of self" for: 'doubled when: {
89
96
  5 doubled should == 10
90
97
  10 doubled should == 20
91
- 20 upto: 50 do_each: |i| {
98
+ 20 upto: 50 do: |i| {
92
99
  i doubled should == (i + i)
93
100
  }
94
101
  }