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
data/examples/files.fy ADDED
@@ -0,0 +1,23 @@
1
+ # files.fy
2
+ # File handling examples
3
+
4
+ {
5
+ Directory create: "tmp/"
6
+ } unless: $ Directory exists?: "tmp/"
7
+
8
+ File open: "tmp/Hello-World.txt" modes: ['write] with: |f| {
9
+ f writeln: "Hello, world"
10
+ }
11
+
12
+ File delete: "tmp/Hello-World.txt"
13
+
14
+ arr = [1,2,3,4]
15
+ File open: "tmp/Array-Test.txt" modes: ['write] with: |f| {
16
+ arr each: |x| {
17
+ f writeln: x
18
+ }
19
+ }
20
+
21
+ File delete: "tmp/Array-Test.txt"
22
+
23
+ Directory delete: "tmp/"
@@ -0,0 +1,5 @@
1
+ try {
2
+ "Hello" println
3
+ } finally {
4
+ "World" println
5
+ }
@@ -0,0 +1,148 @@
1
+ # game_of_life.fy
2
+ # Conway's Game of Life in Fancy :)
3
+
4
+ class World {
5
+ read_write_slots: ['matrix]
6
+
7
+ def World with_height: height and_width: width {
8
+ World new: [height, width]
9
+ }
10
+
11
+ def initialize {
12
+ # the offsets are the positions to check for neighbors relative to
13
+ # each position (e.g. [-1,-1] points to the upper left neighbor of
14
+ # each cell)
15
+ @offsets = [[-1, -1], [-1, 0], [-1, 1],
16
+ [0, -1], [0, 1],
17
+ [1, -1], [1, 0], [1, 1]]
18
+ }
19
+
20
+ def initialize: size {
21
+ "Initialize a World with a given size ([height, width])."
22
+
23
+ self initialize
24
+ height = size[0]
25
+ width = size[1]
26
+ @last_alive = []
27
+ @matrix = Array new: height
28
+ height times: |i| {
29
+ @matrix at: i put: (Array new: width with: 0)
30
+ }
31
+ }
32
+
33
+ def [] index {
34
+ "Return the row for a given index."
35
+ @matrix[index]
36
+ }
37
+
38
+ def simulate: amount_generations {
39
+ "Simulate the World for a given amount of iterations (generations)."
40
+
41
+ display: 0
42
+ amount_generations times: |i| {
43
+ System sleep: 500 # sleep 500 ms
44
+ self simulate
45
+ display: (i + 1)
46
+ }
47
+ }
48
+
49
+ def display {
50
+ "Display the World (print on Screen)."
51
+
52
+ @matrix each: |row| {
53
+ row each: |entry| {
54
+ if: (entry == 0) then: {
55
+ " " print
56
+ } else: {
57
+ ". " print
58
+ }
59
+ }
60
+ "" println
61
+ }
62
+ }
63
+
64
+ def display: iteration {
65
+ "Display the World (print on Screen) with the current iteration count."
66
+
67
+ Console clear
68
+ "Generation: " ++ iteration println
69
+ self display
70
+ }
71
+
72
+ def was_alive?: pos {
73
+ "Indicates, if a cell ([row,column]) was alive in the last generation."
74
+
75
+ @last_alive[pos[0]] if_do: |row| {
76
+ row[pos[1]] == 1
77
+ }
78
+ }
79
+
80
+ def live: pos {
81
+ "Sets the given cell ([row,column]) alive."
82
+ (@matrix[pos[0]]) at: (pos[1]) put: 1
83
+ }
84
+
85
+ def die: pos {
86
+ "Sets the given cell ([row,column]) dead."
87
+ (@matrix[pos[0]]) at: (pos[1]) put: 0
88
+ }
89
+
90
+ def simulate {
91
+ "Simulates the world one iteration."
92
+
93
+ @last_alive = @matrix map: |row| { row select_with_index: |c| { c == 1 } }
94
+ @matrix each_with_index: |row i| {
95
+ row each_with_index: |column j| {
96
+ # check amount of neighbors
97
+ n_neighbors = neighbors_of: [i, j]
98
+ if: (was_alive?: [i,j]) then: {
99
+ if: ({n_neighbors <= 1} || {n_neighbors >= 4}) then: {
100
+ die: [i,j]
101
+ } else: {
102
+ live: [i,j]
103
+ }
104
+ } else: {
105
+ if: (n_neighbors == 3) then: {
106
+ live: [i,j]
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+
113
+ def neighbors_of: pos {
114
+ row = pos[0]
115
+ column = pos[1]
116
+
117
+ neighbors = @offsets map: |o| {
118
+ @matrix[row + (o[0])] if_do: |r| {
119
+ r[column + (o[1])]
120
+ }
121
+ }
122
+ neighbors select: |x| { x != 0 } . size
123
+ }
124
+ }
125
+
126
+ X = 1
127
+ PULSAR = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
128
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
129
+ [0, 0, 0, 0, X, X, X, 0, 0, 0, X, X, X, 0, 0, 0],
130
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
131
+ [0, 0, X, 0, 0, 0, 0, X, 0, X, 0, 0, 0, 0, X, 0],
132
+ [0, 0, X, 0, 0, 0, 0, X, 0, X, 0, 0, 0, 0, X, 0],
133
+ [0, 0, X, 0, 0, 0, 0, X, 0, X, 0, 0, 0, 0, X, 0],
134
+ [0, 0, 0, 0, X, X, X, 0, 0, 0, X, X, X, 0, 0, 0],
135
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
136
+ [0, 0, 0, 0, X, X, X, 0, 0, 0, X, X, X, 0, 0, 0],
137
+ [0, 0, X, 0, 0, 0, 0, X, 0, X, 0, 0, 0, 0, X, 0],
138
+ [0, 0, X, 0, 0, 0, 0, X, 0, X, 0, 0, 0, 0, X, 0],
139
+ [0, 0, X, 0, 0, 0, 0, X, 0, X, 0, 0, 0, 0, X, 0],
140
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
141
+ [0, 0, 0, 0, X, X, X, 0, 0, 0, X, X, X, 0, 0, 0],
142
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
143
+ ]
144
+
145
+ w = World new
146
+ w matrix: PULSAR
147
+
148
+ w simulate: 20
@@ -0,0 +1,7 @@
1
+ h = <['foo => 'bar, 'bar => 'baz, 'baz => 42.5]>
2
+ h at: 'foo . println
3
+ h['bar] println
4
+ h['baz] println
5
+
6
+ h = <[ 2 + 2 => 5 ]>
7
+ h[4] println
@@ -0,0 +1,6 @@
1
+ # hello_world.fy
2
+ # The classic "hello world" program in fancy
3
+
4
+ Console println: "Hello, World!"
5
+ # another way of doing this:
6
+ "Hello, World again!" println
@@ -0,0 +1,54 @@
1
+ # html_generator.fy
2
+ # Simple HTML generator written in fancy
3
+
4
+ class String {
5
+ def but_last {
6
+ # same as: self from: 0 to: -2
7
+ # and: self from: 0 to: (self size - 2)
8
+ self[[0,-2]]
9
+ }
10
+ }
11
+
12
+ class HTML {
13
+ def open_tag: name {
14
+ "<" ++ (name but_last) ++ ">"
15
+ }
16
+
17
+ def close_tag: name {
18
+ "</" ++ (name but_last) ++ ">"
19
+ }
20
+
21
+ def unknown_message: name with_params: params {
22
+ name = name to_s
23
+ str = open_tag: name
24
+
25
+ body = params first call
26
+ if: (body is_a?: Array) then: {
27
+ body = body join
28
+ }
29
+
30
+ str ++ body ++ (close_tag: name)
31
+ }
32
+ }
33
+
34
+ # lets generate some simple HTML output )
35
+ h = HTML new
36
+ h html: {
37
+ h body: {
38
+ [
39
+ h div: {
40
+ "hello, world!"
41
+ },
42
+ h div: {
43
+ h p: {
44
+ "OKIDOKI"
45
+ }
46
+ },
47
+ h div: {
48
+ h h3: {
49
+ "oh no!"
50
+ }
51
+ }
52
+ ]
53
+ }
54
+ } . println
@@ -0,0 +1,3 @@
1
+ # Methods implicitly return the last expression.
2
+ def hello { "Hello!" }
3
+ self hello println
@@ -0,0 +1,6 @@
1
+ # matchers.fy
2
+
3
+ match "foobarbaz" -> {
4
+ case /foo([a-z]+)baz/ -> |matcher|
5
+ matcher[1] println # => bar
6
+ }
@@ -0,0 +1,29 @@
1
+ # methods.fy
2
+ # Examples of methods definitions, and method overriding in fancy
3
+
4
+ class Foo {
5
+ def bar {
6
+ Console println: "version 1"
7
+ }
8
+ }
9
+
10
+ f = Foo new
11
+ f bar # prints: version 1
12
+
13
+ # redefine Foo#bar
14
+ class Foo {
15
+ def bar {
16
+ Console println: "version 2"
17
+ }
18
+ }
19
+
20
+ f bar # prints: version 2
21
+
22
+ # redefine Foo#bar again
23
+ class Foo {
24
+ def bar {
25
+ Console println: "version 3"
26
+ }
27
+ }
28
+
29
+ f bar # prints: version 3
@@ -0,0 +1,27 @@
1
+ # nested_classes.fy
2
+ # Example of nested classes in fancy
3
+
4
+ class Outer {
5
+ class Inner {
6
+ def to_s {
7
+ "Outerr::Inner"
8
+ }
9
+ }
10
+
11
+ def to_s {
12
+ "Outer"
13
+ }
14
+ }
15
+
16
+
17
+ o = Outer new
18
+ o println
19
+ i = Outer::Inner new
20
+ i println
21
+
22
+ class Outer InnerTwo {
23
+ def to_s { "Outer InnerTwo" }
24
+ }
25
+
26
+ i = Outer InnerTwo new
27
+ i println
@@ -0,0 +1,9 @@
1
+ try {
2
+ try {
3
+ StdError new: "Propagated exception" . raise!
4
+ } catch String => not_matched {
5
+ "Should not enter here" println
6
+ }
7
+ } catch Object => anything {
8
+ anything println
9
+ }
@@ -0,0 +1,12 @@
1
+ # numbers.fy
2
+ # Examples of fancy's number objects
3
+
4
+ -10 abs println # prints: 10
5
+ 10 abs println # prints: 10
6
+ 0 abs println # prints: 0
7
+
8
+ "" println
9
+
10
+ -10 negate println # prints: 10
11
+ 10 negate println # prints: -10
12
+ 0 negate println # prints: 0
@@ -0,0 +1,40 @@
1
+ # pattern_matching.fy
2
+ # Examples of pattern matching facilities in fancy
3
+
4
+ class PatternMatching {
5
+ def match_it: obj {
6
+ match obj -> {
7
+ case String -> "It's a String!" println
8
+ case Fixnum -> "It's a Number!" println
9
+ case _ -> "Aything else!" println
10
+ }
11
+ }
12
+
13
+ def match_with_extract: str {
14
+ match str -> {
15
+ # m holds the MatchData object, m1 & m2 the first and second matches
16
+ case /^(.*) : (.*)$/ -> |m, m1, m2|
17
+ "First match: #{m1}" println
18
+ "Second match: #{m2}" println
19
+ }
20
+ }
21
+ }
22
+
23
+ pm = PatternMatching new
24
+ pm match_it: "foo"
25
+ pm match_it: 42
26
+ pm match_it: 'foo
27
+
28
+ pm match_with_extract: "Hello : World!"
29
+
30
+ # more pattern matching:
31
+
32
+ def do_it: num {
33
+ (num, num * num)
34
+ }
35
+
36
+ match do_it: 10 -> {
37
+ case Tuple -> |_, x, y| # first arg is a Tuple MatchData object (not used here).
38
+ x inspect println # 10
39
+ y inspect println # 100
40
+ }
@@ -0,0 +1,65 @@
1
+ # person.fy
2
+ # Annotated example of fancy's classes mechanism
3
+
4
+ class City {
5
+ read_slots: ['city]
6
+ def initialize: name {
7
+ @name = name
8
+ }
9
+
10
+ def to_s {
11
+ "City: " ++ @name
12
+ }
13
+ }
14
+
15
+ class Person {
16
+ # creates getters & setters for slots
17
+ read_write_slots: ['name, 'age, 'city]
18
+
19
+ # Person constructor method for creating a new person with a name,
20
+ # age and city.
21
+ # A method that starts with initialize: will cause a class factory
22
+ # method being generated, that calls this method when being called.
23
+ # The name of the class factory method is the same as the instance
24
+ # method but having initialize: replaced by new:.
25
+ # So in this case: Person##new:age:city:
26
+ # which calls this instance method internally
27
+ def initialize: name age: age city: city {
28
+ @name = name
29
+ @age = age
30
+ @city = city
31
+ }
32
+
33
+ def go_to: city {
34
+ # The .-operator (dot) manages left associativity and treats
35
+ # everything left of it as one expression and everything right of
36
+ # it as a method_call to the left. In this case the following line
37
+ # of code is equivalent to:
38
+ ## (city is_a?: City) if_true: { ... }
39
+
40
+ # While using parentheses would definately work, the dot-operator
41
+ # makes left-grouping of expressions much easier.
42
+ # In contrast to e.g. Smalltalk, Fancy isn't compiled but
43
+ # interpreted so there usually is not some predefined knowledge of
44
+ # which methods exist etc., which makes it impossible to determine
45
+ # if we're dealing with a two-argument method call or a chained
46
+ # method call ('is_a?:if_true:' vs. '(is_a?: ..) if_true: ..')
47
+ city is_a?: City . if_true: {
48
+ @city = city
49
+ }
50
+ }
51
+
52
+ def to_s {
53
+ "Person: " ++ @name ++ ", " ++ @age ++ " years old, living in " ++ @city
54
+ }
55
+ }
56
+
57
+ # usage example:
58
+ osna = City new: "Osnabrück"
59
+ p = Person new: "Christopher" age: 23 city: osna
60
+ p println
61
+
62
+ berlin = City new: "Berlin"
63
+ p go_to: berlin # => p city will then be set to berlin
64
+
65
+ p println