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
@@ -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
  }