fancy 0.3.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 (242) hide show
  1. data/AUTHORS +7 -0
  2. data/LICENSE +19 -0
  3. data/README +173 -0
  4. data/Rakefile +255 -0
  5. data/bin/fancy +40 -0
  6. data/bin/fdoc +23 -0
  7. data/bin/fyi +22 -0
  8. data/bin/ifancy +46 -0
  9. data/boot/README +12 -0
  10. data/boot/code_loader.rb +165 -0
  11. data/boot/compile.fy +3 -0
  12. data/boot/fancy_ext.rb +13 -0
  13. data/boot/fancy_ext/block_env.rb +29 -0
  14. data/boot/fancy_ext/class.rb +26 -0
  15. data/boot/fancy_ext/kernel.rb +12 -0
  16. data/boot/fancy_ext/module.rb +89 -0
  17. data/boot/fancy_ext/object.rb +34 -0
  18. data/boot/fancy_ext/string_helper.rb +10 -0
  19. data/boot/load.rb +72 -0
  20. data/boot/rbx-compiler/README +12 -0
  21. data/boot/rbx-compiler/compiler.rb +24 -0
  22. data/boot/rbx-compiler/compiler/ast.rb +23 -0
  23. data/boot/rbx-compiler/compiler/ast/README +11 -0
  24. data/boot/rbx-compiler/compiler/ast/array_literal.rb +13 -0
  25. data/boot/rbx-compiler/compiler/ast/assign.rb +57 -0
  26. data/boot/rbx-compiler/compiler/ast/block.rb +70 -0
  27. data/boot/rbx-compiler/compiler/ast/class_def.rb +35 -0
  28. data/boot/rbx-compiler/compiler/ast/expression_list.rb +57 -0
  29. data/boot/rbx-compiler/compiler/ast/hash_literal.rb +11 -0
  30. data/boot/rbx-compiler/compiler/ast/identifier.rb +120 -0
  31. data/boot/rbx-compiler/compiler/ast/match.rb +81 -0
  32. data/boot/rbx-compiler/compiler/ast/message_send.rb +71 -0
  33. data/boot/rbx-compiler/compiler/ast/method_def.rb +116 -0
  34. data/boot/rbx-compiler/compiler/ast/node.rb +6 -0
  35. data/boot/rbx-compiler/compiler/ast/range_literal.rb +22 -0
  36. data/boot/rbx-compiler/compiler/ast/require.rb +20 -0
  37. data/boot/rbx-compiler/compiler/ast/return.rb +29 -0
  38. data/boot/rbx-compiler/compiler/ast/ruby_args.rb +35 -0
  39. data/boot/rbx-compiler/compiler/ast/script.rb +56 -0
  40. data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +39 -0
  41. data/boot/rbx-compiler/compiler/ast/string_literal.rb +14 -0
  42. data/boot/rbx-compiler/compiler/ast/super.rb +25 -0
  43. data/boot/rbx-compiler/compiler/ast/try_catch_block.rb +220 -0
  44. data/boot/rbx-compiler/compiler/ast/tuple_literal.rb +33 -0
  45. data/boot/rbx-compiler/compiler/command.rb +39 -0
  46. data/boot/rbx-compiler/compiler/compiler.rb +83 -0
  47. data/boot/rbx-compiler/compiler/stages.rb +99 -0
  48. data/boot/rbx-compiler/parser.rb +2 -0
  49. data/boot/rbx-compiler/parser/README +15 -0
  50. data/boot/rbx-compiler/parser/Rakefile +54 -0
  51. data/boot/rbx-compiler/parser/extconf.rb +3 -0
  52. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  53. data/boot/rbx-compiler/parser/fancy_parser.c +46 -0
  54. data/boot/rbx-compiler/parser/fancy_parser.h +8 -0
  55. data/boot/rbx-compiler/parser/lexer.lex +180 -0
  56. data/boot/rbx-compiler/parser/parser.rb +356 -0
  57. data/boot/rbx-compiler/parser/parser.y +711 -0
  58. data/boot/rsexp_pretty_printer.rb +76 -0
  59. data/doc/api/fancy.css +93 -0
  60. data/doc/api/fancy.jsonp +1 -0
  61. data/doc/api/fdoc.js +187 -0
  62. data/doc/api/index.html +57 -0
  63. data/doc/api/underscore-min.js +18 -0
  64. data/doc/features.md +228 -0
  65. data/examples/argv.fy +8 -0
  66. data/examples/arithmetic.fy +7 -0
  67. data/examples/armstrong_numbers.fy +33 -0
  68. data/examples/array.fy +52 -0
  69. data/examples/blocks.fy +15 -0
  70. data/examples/boolean.fy +24 -0
  71. data/examples/call_with_receiver.fy +9 -0
  72. data/examples/class.fy +68 -0
  73. data/examples/closures.fy +24 -0
  74. data/examples/constant_access.fy +15 -0
  75. data/examples/default_args.fy +17 -0
  76. data/examples/define_methods.fy +15 -0
  77. data/examples/documentation.fy +57 -0
  78. data/examples/documentation_formatters.fy +25 -0
  79. data/examples/echo.fy +16 -0
  80. data/examples/empty_catch.fy +4 -0
  81. data/examples/exception.fy +9 -0
  82. data/examples/factorial.fy +12 -0
  83. data/examples/fibonacci.fy +16 -0
  84. data/examples/files.fy +23 -0
  85. data/examples/finally.fy +5 -0
  86. data/examples/game_of_life.fy +148 -0
  87. data/examples/hashes.fy +7 -0
  88. data/examples/hello_world.fy +6 -0
  89. data/examples/html_generator.fy +54 -0
  90. data/examples/implicit_return.fy +3 -0
  91. data/examples/matchers.fy +6 -0
  92. data/examples/methods.fy +29 -0
  93. data/examples/nested_classes.fy +27 -0
  94. data/examples/nested_try.fy +9 -0
  95. data/examples/numbers.fy +12 -0
  96. data/examples/pattern_matching.fy +40 -0
  97. data/examples/person.fy +65 -0
  98. data/examples/project-euler/01.fy +8 -0
  99. data/examples/project-euler/02.fy +21 -0
  100. data/examples/project-euler/28.fy +33 -0
  101. data/examples/rbx/and_or.fy +7 -0
  102. data/examples/rbx/blocks.fy +22 -0
  103. data/examples/rbx/classes.fy +32 -0
  104. data/examples/rbx/hello.fy +8 -0
  105. data/examples/rbx/include.fy +12 -0
  106. data/examples/rbx/inherit.fy +11 -0
  107. data/examples/rbx/methods.fy +15 -0
  108. data/examples/rbx/nested_classes.fy +9 -0
  109. data/examples/rbx/require.fy +3 -0
  110. data/examples/rbx/strings.fy +5 -0
  111. data/examples/regex.fy +7 -0
  112. data/examples/require.fy +7 -0
  113. data/examples/retry.fy +12 -0
  114. data/examples/return.fy +13 -0
  115. data/examples/ruby_require.fy +7 -0
  116. data/examples/ruby_send.fy +3 -0
  117. data/examples/singleton_methods.fy +21 -0
  118. data/examples/stupid_quicksort.fy +12 -0
  119. data/examples/threads.fy +18 -0
  120. data/examples/tuple.fy +8 -0
  121. data/examples/webserver/webserver.fy +18 -0
  122. data/lib/argv.fy +36 -0
  123. data/lib/array.fy +207 -0
  124. data/lib/block.fy +88 -0
  125. data/lib/boot.fy +41 -0
  126. data/lib/class.fy +106 -0
  127. data/lib/compiler.fy +14 -0
  128. data/lib/compiler/ast.fy +40 -0
  129. data/lib/compiler/ast/assign.fy +96 -0
  130. data/lib/compiler/ast/block.fy +84 -0
  131. data/lib/compiler/ast/class_def.fy +33 -0
  132. data/lib/compiler/ast/expression_list.fy +47 -0
  133. data/lib/compiler/ast/identifier.fy +113 -0
  134. data/lib/compiler/ast/literals.fy +122 -0
  135. data/lib/compiler/ast/match.fy +88 -0
  136. data/lib/compiler/ast/message_send.fy +110 -0
  137. data/lib/compiler/ast/method_def.fy +90 -0
  138. data/lib/compiler/ast/node.fy +7 -0
  139. data/lib/compiler/ast/range.fy +16 -0
  140. data/lib/compiler/ast/require.fy +15 -0
  141. data/lib/compiler/ast/return.fy +23 -0
  142. data/lib/compiler/ast/script.fy +52 -0
  143. data/lib/compiler/ast/singleton_method_def.fy +35 -0
  144. data/lib/compiler/ast/super.fy +17 -0
  145. data/lib/compiler/ast/try_catch.fy +176 -0
  146. data/lib/compiler/ast/tuple_literal.fy +34 -0
  147. data/lib/compiler/command.fy +51 -0
  148. data/lib/compiler/compiler.fy +73 -0
  149. data/lib/compiler/stages.fy +81 -0
  150. data/lib/directory.fy +17 -0
  151. data/lib/documentation.fy +115 -0
  152. data/lib/enumerable.fy +269 -0
  153. data/lib/eval.fy +31 -0
  154. data/lib/fancy_spec.fy +202 -0
  155. data/lib/fdoc.fy +359 -0
  156. data/lib/fdoc_hook.fy +10 -0
  157. data/lib/file.fy +54 -0
  158. data/lib/hash.fy +56 -0
  159. data/lib/main.fy +80 -0
  160. data/lib/method.fy +22 -0
  161. data/lib/nil_class.fy +56 -0
  162. data/lib/number.fy +87 -0
  163. data/lib/object.fy +170 -0
  164. data/lib/package.fy +61 -0
  165. data/lib/package/dependency.fy +24 -0
  166. data/lib/package/installer.fy +180 -0
  167. data/lib/package/specification.fy +55 -0
  168. data/lib/package/uninstaller.fy +15 -0
  169. data/lib/parser.fy +4 -0
  170. data/lib/parser/ext/README +15 -0
  171. data/lib/parser/ext/ext.c +42 -0
  172. data/lib/parser/ext/ext.h +8 -0
  173. data/lib/parser/ext/extconf.rb +3 -0
  174. data/lib/parser/ext/lexer.lex +187 -0
  175. data/lib/parser/ext/parser.y +744 -0
  176. data/lib/parser/methods.fy +297 -0
  177. data/lib/rbx.fy +37 -0
  178. data/lib/rbx/array.fy +237 -0
  179. data/lib/rbx/bignum.fy +23 -0
  180. data/lib/rbx/block.fy +9 -0
  181. data/lib/rbx/class.fy +129 -0
  182. data/lib/rbx/code_loader.fy +192 -0
  183. data/lib/rbx/console.fy +63 -0
  184. data/lib/rbx/directory.fy +46 -0
  185. data/lib/rbx/documentation.fy +64 -0
  186. data/lib/rbx/environment_variables.fy +3 -0
  187. data/lib/rbx/exception.fy +30 -0
  188. data/lib/rbx/false_class.fy +58 -0
  189. data/lib/rbx/fiber.fy +25 -0
  190. data/lib/rbx/file.fy +191 -0
  191. data/lib/rbx/fixnum.fy +25 -0
  192. data/lib/rbx/float.fy +14 -0
  193. data/lib/rbx/hash.fy +38 -0
  194. data/lib/rbx/integer.fy +15 -0
  195. data/lib/rbx/io.fy +30 -0
  196. data/lib/rbx/match_data.fy +9 -0
  197. data/lib/rbx/method.fy +22 -0
  198. data/lib/rbx/name_error.fy +3 -0
  199. data/lib/rbx/no_method_error.fy +15 -0
  200. data/lib/rbx/object.fy +117 -0
  201. data/lib/rbx/range.fy +15 -0
  202. data/lib/rbx/regexp.fy +9 -0
  203. data/lib/rbx/string.fy +63 -0
  204. data/lib/rbx/symbol.fy +12 -0
  205. data/lib/rbx/system.fy +37 -0
  206. data/lib/rbx/tcp_server.fy +6 -0
  207. data/lib/rbx/tcp_socket.fy +7 -0
  208. data/lib/rbx/thread.fy +75 -0
  209. data/lib/rbx/tuple.fy +37 -0
  210. data/lib/set.fy +61 -0
  211. data/lib/stack.fy +51 -0
  212. data/lib/string.fy +58 -0
  213. data/lib/struct.fy +13 -0
  214. data/lib/symbol.fy +23 -0
  215. data/lib/true_class.fy +43 -0
  216. data/lib/tuple.fy +68 -0
  217. data/lib/version.fy +6 -0
  218. data/tests/argv.fy +13 -0
  219. data/tests/array.fy +343 -0
  220. data/tests/assignment.fy +53 -0
  221. data/tests/block.fy +103 -0
  222. data/tests/class.fy +409 -0
  223. data/tests/control_flow.fy +79 -0
  224. data/tests/documentation.fy +24 -0
  225. data/tests/exception.fy +115 -0
  226. data/tests/file.fy +86 -0
  227. data/tests/hash.fy +101 -0
  228. data/tests/method.fy +131 -0
  229. data/tests/nil_class.fy +55 -0
  230. data/tests/number.fy +128 -0
  231. data/tests/object.fy +125 -0
  232. data/tests/parsing/sexp.fy +50 -0
  233. data/tests/pattern_matching.fy +82 -0
  234. data/tests/range.fy +11 -0
  235. data/tests/set.fy +10 -0
  236. data/tests/stack.fy +22 -0
  237. data/tests/string.fy +102 -0
  238. data/tests/symbol.fy +17 -0
  239. data/tests/true_class.fy +63 -0
  240. data/tests/tuple.fy +21 -0
  241. data/tools/fancy-mode.el +63 -0
  242. metadata +321 -0
@@ -0,0 +1,55 @@
1
+ FancySpec describe: NilClass with: {
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
6
+ }
7
+
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
12
+ }
13
+
14
+ it: "should be true for calling or: with any non-nil value" for: 'or: when: {
15
+ nil or: true . should == true
16
+ nil or: 'foo . should == true
17
+ }
18
+
19
+ it: "should be nil for calling or: with a nil value" for: 'or: when: {
20
+ nil or: nil . should == false
21
+ }
22
+
23
+ it: "should be true for calling || with any non-nil value" for: '|| when: {
24
+ (nil || true) should == true
25
+ (nil || 'foo) should == true
26
+ }
27
+
28
+ it: "should be nil for calling || with a nil value" for: '|| when: {
29
+ (nil || nil) should == false
30
+ }
31
+
32
+ it: "should NOT call the block" for: 'if_true: when: {
33
+ nil if_true: { 'then } . should == nil
34
+ }
35
+
36
+ it: "should call the block" for: 'if_false: when: {
37
+ nil if_false: { 'false } . should == 'false
38
+ }
39
+
40
+ it: "should be nil" for: 'nil? when: {
41
+ nil nil? should == true
42
+ }
43
+
44
+ it: "should be false" for: 'false? when: {
45
+ nil false? should == true
46
+ }
47
+
48
+ it: "should NOT be true" for: 'true? when: {
49
+ nil true? should == false
50
+ }
51
+
52
+ it: "should call the block if nil" for: 'if_nil: when: {
53
+ nil if_nil: { 'is_nil } . should == 'is_nil
54
+ }
55
+ }
data/tests/number.fy ADDED
@@ -0,0 +1,128 @@
1
+ FancySpec describe: Number with: {
2
+ it: "should add two numbers correctly" for: '+ when: {
3
+ n1 = 20
4
+ n2 = 22
5
+ n1 + n2 should == 42
6
+ }
7
+
8
+ it: "should subtract two numbers correctly" for: '- when: {
9
+ n1 = 20
10
+ n2 = 22
11
+ n1 - n2 should == -2
12
+ }
13
+
14
+ it: "should multiply two numbers correctly" for: '* when: {
15
+ n1 = 20
16
+ n2 = 22
17
+ n1 * n2 should == 440
18
+ }
19
+
20
+ it: "should divide two numbers correctly" for: '/ when: {
21
+ n1 = 20
22
+ n2 = 10
23
+ n1 / n2 should == 2
24
+ }
25
+
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
+ }
33
+ }
34
+
35
+ it: "should calculate the correct modulo value" for: 'modulo: when: {
36
+ 9 % 4 should == 1
37
+ 10 modulo: 2 . should == 0
38
+ }
39
+
40
+ it: "should do proper integer division" for: 'div: when: {
41
+ 50 div: 10 . should == 5
42
+ 55 div: 10 . should == 5
43
+ 5 div: 10 . should == 0
44
+ ((55 div: 10) * 10) + (55 modulo: 10) should == 55
45
+ }
46
+
47
+ it: "should be the negation" for: 'negate when: {
48
+ 42 negate should == -42
49
+ }
50
+
51
+ it: "should be odd" for: 'odd? when: {
52
+ 1 odd? should == true
53
+ 1 even? should == false
54
+ }
55
+
56
+ it: "should be even" for: 'even? when: {
57
+ 2 odd? should == false
58
+ 2 even? should == true
59
+ }
60
+
61
+ it: "should return an array from 0 upto 10" for: 'upto: when: {
62
+ 0 upto: 10 . should == [0,1,2,3,4,5,6,7,8,9,10]
63
+ }
64
+
65
+ it: "should return an array from 10 downto 0" for: 'downto: when: {
66
+ 10 downto: 0 . should == [10,9,8,7,6,5,4,3,2,1,0]
67
+ }
68
+
69
+ it: "should calculate the given power of itself" for: '** when: {
70
+ 2 ** 3 should == 8
71
+ 2 ** 0 should == 1
72
+ 2 ** 1 should == 2
73
+ 0 upto: 10 do_each: |i| {
74
+ i ** 0 should == 1
75
+ i ** 1 should == i
76
+ i ** 2 should == (i squared)
77
+ }
78
+ }
79
+
80
+ it: "should be the square of self" for: 'squared when: {
81
+ 5 squared should == 25
82
+ 10 squared should == 100
83
+ 20 upto: 50 do_each: |i| {
84
+ i squared should == (i * i)
85
+ }
86
+ }
87
+
88
+ it: "should be the double value of self" for: 'doubled when: {
89
+ 5 doubled should == 10
90
+ 10 doubled should == 20
91
+ 20 upto: 50 do_each: |i| {
92
+ i doubled should == (i + i)
93
+ }
94
+ }
95
+
96
+ it: "should be the same when using underscores within the literal" when: {
97
+ 50000 should == 50_000
98
+ 100_000 should == 100000
99
+ 100_000 should == 100_000
100
+ 100_000 should == 100000.0
101
+ 100_000.0 should == 100000
102
+ 100_999.999 should == 100999.999
103
+ }
104
+
105
+ it: "should evaluate octal literals correctly" when: {
106
+ 0o00 should == 0
107
+ 0o01 should == 1
108
+ 0o07 should == 7
109
+ 0o10 should == 8
110
+ 0o70 should == 56
111
+ }
112
+
113
+ it: "should evaluate binary literals correctly" when: {
114
+ 0b00 should == 0
115
+ 0b01 should == 1
116
+ 0b10 should == 2
117
+ 0b11 should == 3
118
+ 0b100 should == 4
119
+ }
120
+
121
+ it: "should evaluate hexadecimal literals correctly" when: {
122
+ 0x00 should == 0
123
+ 0x01 should == 1
124
+ 0x0A should == 10
125
+ 0xA0 should == 160
126
+ 0xFF should == 255
127
+ }
128
+ }
data/tests/object.fy ADDED
@@ -0,0 +1,125 @@
1
+ FancySpec describe: Object with: {
2
+ it: "should dynamically evaluate a message-send with no arguments" when: {
3
+ obj = 42
4
+ obj send: "to_s" . should == "42"
5
+ }
6
+
7
+ it: "should dynamically evaluate a message-send with a list of arguments" when: {
8
+ obj = "hello, world"
9
+ obj send: "from:to:" params: [0,4] . should == "hello"
10
+ }
11
+
12
+ it: "should dynamically define slotvalues" when: {
13
+ obj = Object new
14
+ obj get_slot: 'foo . should == nil
15
+ obj set_slot: 'foo value: "hello, world"
16
+ obj get_slot: 'foo . should == "hello, world"
17
+ }
18
+
19
+ it: "should undefine a singleton method" when: {
20
+ def self a_singleton_method {
21
+ "a singleton method!"
22
+ }
23
+ self a_singleton_method should == "a singleton method!"
24
+ self undefine_singleton_method: 'a_singleton_method
25
+ try {
26
+ self a_singleton_method should == nil # should not get here
27
+ } catch NoMethodError => e {
28
+ e method_name should == "a_singleton_method"
29
+ }
30
+ }
31
+
32
+ it: "should return its class" when: {
33
+ nil class should == NilClass
34
+ true class should == TrueClass
35
+ "foo" class should == String
36
+ 'bar class should == Symbol
37
+ { 'a_block } class should == Block
38
+ }
39
+
40
+ it: "should call unkown_message:with_params: when calling an undefined method" when: {
41
+ class UnknownMessage {
42
+ def unknown_message: message with_params: params {
43
+ "Got: " ++ message ++ " " ++ params
44
+ }
45
+ }
46
+
47
+ obj = UnknownMessage new
48
+ obj this_is_not_defined: "It's true!" . should == "Got: this_is_not_defined: It's true!"
49
+ }
50
+
51
+ it: "should return a correct string representation" when: {
52
+ 3 to_s should == "3"
53
+ 'foo to_s should == "foo"
54
+ nil to_s should == ""
55
+ }
56
+
57
+ it: "should return a correct array representation" when: {
58
+ nil to_a should == []
59
+ 'foo to_a should == ['foo]
60
+ <['foo => "bar", 'bar => "baz"]> to_a should =? [['bar, "baz"], ['foo, "bar"]]
61
+ }
62
+
63
+ it: "should return a correct fixnum representation" when: {
64
+ nil to_i should == 0
65
+ 3 to_i should == 3
66
+ 3.28437 to_i should == 3
67
+ }
68
+
69
+ it: "should be an Object of the correct Class (or Superclass)" when: {
70
+ Object new is_a?: Object . should == true
71
+ "foo" is_a?: String . should == true
72
+ "foo" is_a?: Object . should == true
73
+ 1123 is_a?: Fixnum . should == true
74
+ 1123 is_a?: Object . should == true
75
+ 132.123 is_a?: Float . should == true
76
+ 132.123 is_a?: Object . should == true
77
+ }
78
+
79
+ # boolean messages
80
+
81
+ it: "should be true for calling and: with non-nil values" for: 'and: when: {
82
+ 'foo and: 'bar . should == true
83
+ }
84
+
85
+ it: "should be false for calling and: with a nil value" for: 'and: when: {
86
+ 'foo and: nil . should == false
87
+ }
88
+
89
+ it: "should be true for calling && with non-nil values" for: '&& when: {
90
+ ('foo && 'bar) should == true
91
+ }
92
+
93
+ it: "should be false for calling && with a nil value" for: '&& when: {
94
+ ('foo && nil) should == false
95
+ }
96
+
97
+
98
+ it: "should be true for calling or: with any value" for: 'or: when: {
99
+ 'foo or: 'bar . should == true
100
+ 'foo or: nil . should == true
101
+ }
102
+
103
+ it: "should be true for calling || with any value" for: '|| when: {
104
+ ('foo || 'bar) should == true
105
+ ('foo || nil) should == true
106
+ }
107
+
108
+ # end boolean messages
109
+
110
+ it: "should NOT be nil for non-nil values" for: 'nil? when: {
111
+ 'foo nil? should == nil
112
+ 1 nil? should == nil
113
+ "hello" nil? should == nil
114
+ }
115
+
116
+ it: "should NOT be false for non-nil values" for: 'false? when: {
117
+ 'foo false? should == nil
118
+ "hello, world" false? should == nil
119
+ }
120
+
121
+ it: "should not be true" for: 'true? when: {
122
+ 'foo true? should == nil
123
+ "hello, world" true? should == nil
124
+ }
125
+ }
@@ -0,0 +1,50 @@
1
+ FancySpec describe: "S-Expression" for: String with: {
2
+ it: "should be correct for assignment" for: 'to_sexp when: {
3
+ "x = 3" to_sexp should == ['exp_list, [['assign, ['ident, 'x], ['int_lit, 3]]]]
4
+ "foobar = nil" to_sexp should == ['exp_list, [['assign, ['ident, 'foobar], ['ident, 'nil]]]]
5
+ }
6
+
7
+ it: "should be correct for symbol literals" for: 'to_sexp when: {
8
+ "'foo" to_sexp should == ['exp_list, [['symbol_lit, 'foo]]]
9
+ }
10
+
11
+ it: "should be correct for string literals" for: 'to_sexp when: {
12
+ # "\"foo\"" to_sexp should == ['exp_list, [['string_lit, "foo"]]
13
+ }
14
+
15
+ it: "should be correct for integer literals" for: 'to_sexp when: {
16
+ "3" to_sexp should == ['exp_list, [['int_lit, 3]]]
17
+ "-3" to_sexp should == ['exp_list, [['int_lit, -3]]]
18
+ "0" to_sexp should == ['exp_list, [['int_lit, 0]]]
19
+ }
20
+
21
+ it: "should be correct for double literals" for: 'to_sexp when: {
22
+ "3.5" to_sexp should == ['exp_list, [['double_lit, 3.5]]]
23
+ "-3.5" to_sexp should == ['exp_list, [['double_lit, -3.5]]]
24
+ "0.0" to_sexp should == ['exp_list, [['double_lit, 0.0]]]
25
+ }
26
+
27
+ it: "should be correct for array literals" for: 'to_sexp when: {
28
+ "[1,2,3]" to_sexp should == ['exp_list, [['array_lit, [['int_lit, 1], ['int_lit, 2], ['int_lit, 3]]]]]
29
+
30
+ "[[1,2],[3,4]]" to_sexp should == .
31
+ ['exp_list, [['array_lit, [['array_lit, [['int_lit, 1], ['int_lit, 2]]],
32
+ ['array_lit, [['int_lit, 3], ['int_lit, 4]]]]]]]
33
+
34
+ "[]" to_sexp should == ['exp_list, [['array_lit, []]]]
35
+ }
36
+
37
+ it: "should be able to parse multiple expressions in one string" for: 'to_sexp when: {
38
+ "x = 1; y = 2" to_sexp should == ['exp_list, [['assign, ['ident, 'x], ['int_lit, 1]],
39
+ ['assign, ['ident, 'y], ['int_lit, 2]]]]
40
+ }
41
+
42
+ it: "should parse an RubyArgsLiteral correctly" for: 'to_sexp when: {
43
+ "obj foo: ~[1,2]" to_sexp should == .
44
+ ['exp_list, [['message_send, ['ident, 'obj],
45
+ ['ident, 'foo:],
46
+ [['rb_args_lit, ['array_lit,
47
+ [['int_lit, 1],
48
+ ['int_lit, 2]]]]]]]]
49
+ }
50
+ }
@@ -0,0 +1,82 @@
1
+ FancySpec describe: "Pattern Matching" with: {
2
+ it: "should match a value correctly by its class" when: {
3
+ def do_match: obj {
4
+ match obj -> {
5
+ case String -> 'string
6
+ case Fixnum -> 'fixnum
7
+ case _ -> 'anything
8
+ }
9
+ }
10
+
11
+ do_match: "foo" . should == 'string
12
+ do_match: 42 . should == 'fixnum
13
+ do_match: 'symbol . should == 'anything
14
+ do_match: Object . should == 'anything
15
+ do_match: 32.32 . should == 'anything
16
+ }
17
+
18
+ it: "should bind a given match arg, if present, to the result of the match operation" when: {
19
+ match "foobarbaz" -> {
20
+ case /foo([a-z]+)baz/ -> |matcher|
21
+ local1, local2, local3 = 'ignore, 'this_too, 'this_also
22
+ matcher[1] should == "bar"
23
+ }
24
+ }
25
+
26
+ it: "should only bind given match arg to the scope of the match case" when: {
27
+ match "foobarbaz" -> {
28
+ case /foo([a-z]+)baz/ -> |local_of_case|
29
+ local_of_case == nil . should == false
30
+ }
31
+
32
+ local_of_case should == nil
33
+ }
34
+
35
+ it: "should only bind locals of the match clause to the scope of the match case" when: {
36
+ match "foobarbaz" -> {
37
+ case /foo([a-z]+)baz/ -> |local_of_case|
38
+ local1 = "Hi, I am some local, that should be gone after this block."
39
+ }
40
+
41
+ local1 should == nil
42
+ }
43
+
44
+ it: "should bind any additional match args to the matched values" when: {
45
+ str = "foo bar baz"
46
+ match str -> {
47
+ case /^foo (.*) (.*)$/ -> |all, match1, match2|
48
+ all class should == MatchData
49
+ match1 should == "bar"
50
+ match2 should == "baz"
51
+ }
52
+ }
53
+
54
+ it: "should return an instance of the apropriate MatchData class" when: {
55
+ def create_tuple: num {
56
+ (num, num * num) # create a Tuple
57
+ }
58
+
59
+ match create_tuple: 10 -> {
60
+ case Tuple -> |md, x, y, z|
61
+ # convention: md[0] always holds the entire object that was matched.
62
+ md[0] should == (create_tuple: 10)
63
+ x should == 10
64
+ y should == 100
65
+ z should == nil # tuple only has 2 entries
66
+ }
67
+ }
68
+
69
+ it: "should match an array correctly" when: {
70
+ def create_array: num {
71
+ [num, num ** 2, num ** 3, num ** 4]
72
+ }
73
+
74
+ match create_array: 2 -> {
75
+ case Array -> |_, a,b,c,d|
76
+ a should == 2
77
+ b should == (2 ** 2)
78
+ c should == (2 ** 3)
79
+ d should == (2 ** 4)
80
+ }
81
+ }
82
+ }
data/tests/range.fy ADDED
@@ -0,0 +1,11 @@
1
+ FancySpec describe: Range with: {
2
+ it: "have the correct amount of elements" for: 'size when: {
3
+ Range new: 1 to: 10 . to_a size should == 10
4
+ (1..10) to_a size should == 10
5
+ ("a".."z") to_a size should == 26
6
+ }
7
+
8
+ it: "should have a working literal syntax" when: {
9
+ (1..10) should == (Range new: 1 to: 10)
10
+ }
11
+ }