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,8 @@
1
+ # Problem 1
2
+ # If we list all the natural numbers below 10 that are multiples of 3
3
+ # or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
4
+ # Find the sum of all the multiples of 3 or 5 below 1000.
5
+
6
+ 0 upto: 999 .
7
+ select: |x| { x % 3 == 0 or: (x % 5 == 0) } .
8
+ sum println
@@ -0,0 +1,21 @@
1
+ # Problem 2
2
+ # Each new term in the Fibonacci sequence is generated by adding the
3
+ # previous two terms. By starting with 1 and 2, the first 10 terms will
4
+ # be:
5
+ # 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
6
+ # Find the sum of all the even-valued terms in the sequence which do
7
+ # not exceed four million.
8
+
9
+ fibs = [1, 2]
10
+
11
+ # insert into fibs as long as the sum of the last two numbers doesn't
12
+ # exceed 4000000
13
+ while: { fibs[-1] + (fibs[-2]) <= 4000000 } do: {
14
+ fibs << (fibs last: 2 . sum)
15
+ }
16
+
17
+ "fibonacci sequence:" println
18
+ fibs inspect println
19
+
20
+ "sum: " print
21
+ fibs select: 'even? . sum println
@@ -0,0 +1,33 @@
1
+ # Problem 28
2
+ # What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral
3
+ # formed in the same way?
4
+
5
+ # Starting with the number 1 and moving to the right in a clockwise
6
+ # direction a 5 by 5 spiral is formed as follows:
7
+ #
8
+ # 21 22 23 24 25
9
+ # 20 7 8 9 10
10
+ # 19 6 1 2 11
11
+ # 18 5 4 3 12
12
+ # 17 16 15 14 13
13
+ #
14
+ # It can be verified that the sum of the numbers on the diagonals is 101.
15
+
16
+ taille = 1001
17
+ pas = taille - 1
18
+ number = taille ** 2
19
+ coins = 1
20
+ sum = number
21
+
22
+ while: { pas > 0 } do: {
23
+ number = number - pas
24
+ sum = sum + number
25
+ if: (coins == 4) then: {
26
+ coins = 1
27
+ pas = pas - 2
28
+ } else: {
29
+ coins = coins + 1
30
+ }
31
+ }
32
+
33
+ "The sum of the numbers of the diagonals of the matrix is: " ++ sum println
@@ -0,0 +1,7 @@
1
+ true and: nil . inspect println
2
+ nil and: true . inspect println
3
+ true and: true . inspect println
4
+
5
+ nil or: nil . inspect println
6
+ nil or: true . inspect println
7
+ true or: nil . inspect println
@@ -0,0 +1,22 @@
1
+ 2 times: |i| {
2
+ i println
3
+ }
4
+
5
+ 1 upto: 4 do_each: |i| {
6
+ i println
7
+ }
8
+
9
+ x = 0
10
+ while: { x < 4 } do: {
11
+ "in while_true, with x = " ++ x println
12
+ x = x + 1
13
+ }
14
+
15
+ b = |x, y| {
16
+ "x is: " ++ (x inspect) println
17
+ "y is: " ++ (y inspect) println
18
+ x + y println
19
+ }
20
+
21
+ b call: [1,2]
22
+
@@ -0,0 +1,32 @@
1
+ class Person {
2
+ @@a_classvar = "foo"
3
+ def initialize: name {
4
+ @name = name
5
+ }
6
+
7
+ def to_s {
8
+ "Person with name: " ++ @name
9
+ }
10
+
11
+ def Person class_var {
12
+ @@a_classvar
13
+ }
14
+ }
15
+
16
+ p = Person new: "Christopher"
17
+ p println
18
+ Person class_var println
19
+
20
+ class PersonWithAge : Person {
21
+ def initialize: name age: age {
22
+ @name = name
23
+ @age = age
24
+ }
25
+
26
+ def to_s {
27
+ super to_s ++ " and age: " ++ @age
28
+ }
29
+ }
30
+
31
+ p2 = PersonWithAge new: "Christopher" age: 23
32
+ p2 println
@@ -0,0 +1,8 @@
1
+ "Hello from Fancy, " + "Rubinius!!" println
2
+ 44 + 323.2323 println
3
+
4
+ def foo: x {
5
+ x + x println
6
+ }
7
+
8
+ foo: 10
@@ -0,0 +1,12 @@
1
+ class Hello {
2
+ def hello {
3
+ "Hello " ++ @name println
4
+ }
5
+ }
6
+
7
+ class World {
8
+ include: Hello
9
+ def initialize { @name = "World" }
10
+ }
11
+
12
+ World new hello
@@ -0,0 +1,11 @@
1
+ class Hello {
2
+ def hello {
3
+ "Hello " ++ (self name) . println
4
+ }
5
+ }
6
+
7
+ class World : Hello {
8
+ def name { "World" }
9
+ }
10
+
11
+ World new hello
@@ -0,0 +1,15 @@
1
+ # A simple example of one method calling another in self.
2
+ def hello {
3
+ "Hello " ++ (self world)
4
+ }
5
+
6
+ def world { "World" }
7
+
8
+
9
+ self hello println
10
+
11
+ def hello_to: obj {
12
+ "Hello, " ++ obj println
13
+ }
14
+
15
+ hello_to: "World!"
@@ -0,0 +1,9 @@
1
+ class Outer {
2
+ class Inner {
3
+ def foo: bar {
4
+ "foo got: " ++ bar println
5
+ }
6
+ }
7
+ }
8
+
9
+ Outer::Inner new foo: "yay!"
@@ -0,0 +1,3 @@
1
+ require: "hello.fy"
2
+
3
+ "Now executing from require.fy!" println
@@ -0,0 +1,5 @@
1
+ "foo bar baz" split: " " . each: |x| {
2
+ x println
3
+ }
4
+
5
+ "hello \t world" println
data/examples/regex.fy ADDED
@@ -0,0 +1,7 @@
1
+ regex = /[a-z]+[A-Z]*foo/
2
+ str = "heLLofoo"
3
+
4
+ if: (str =~ regex) then: |idx| {
5
+ "match at index: #{idx} with character: " print
6
+ str[idx] inspect println
7
+ }
@@ -0,0 +1,7 @@
1
+ # require.fy
2
+ # Examples of fancy code reusing and evaluation facilities
3
+
4
+ require: "arithmetic.fy"
5
+
6
+ "in require.fnc!" println
7
+ ARGV println # prints any given command-line arguments as an array
data/examples/retry.fy ADDED
@@ -0,0 +1,12 @@
1
+ y = 0
2
+ x = 0
3
+ try {
4
+ x = 10 / y
5
+ } catch ZeroDivisionError {
6
+ y println
7
+ x println
8
+ y = 2
9
+ retry
10
+ }
11
+ y println
12
+ x println
@@ -0,0 +1,13 @@
1
+ def foo: block {
2
+ 1 upto: 10 do_each: |i| {
3
+ val = block call: [i]
4
+ if: (block call: [i]) then: {
5
+ return i # non-local return from "foo:"
6
+ }
7
+ }
8
+ return "yay"
9
+ }
10
+
11
+ foo: |x| { x == 6 } . println
12
+ foo: |x| { x == 0 } . println
13
+ foo: |x| { return_local true } . println # local return
@@ -0,0 +1,7 @@
1
+ # ruby_require.fy
2
+ # Example of Ruby code reusing and evaluation from inside fancy
3
+
4
+ require("examples/ruby_file")
5
+
6
+ obj = RubyClass new
7
+ obj ruby_method("foo", "bar")
@@ -0,0 +1,3 @@
1
+ [3, 2, 1] reverse() each() |a| { puts(a) }
2
+ "Hello" sub("ll", "y") println
3
+ [3, 2, 1] map() |a| { a * 2 } inject(0) |s i| { s + i } println
@@ -0,0 +1,21 @@
1
+ def self singleton_method {
2
+ "in singleton_method" println
3
+ }
4
+
5
+ self singleton_method
6
+
7
+ arr = [1,2,3]
8
+
9
+ def arr foobar {
10
+ self each: |x| {
11
+ "foobar: " ++ x println
12
+ }
13
+ }
14
+
15
+ arr foobar
16
+
17
+ def Array empty! {
18
+ []
19
+ }
20
+
21
+ Array empty! inspect println
@@ -0,0 +1,12 @@
1
+ def quicksort: arr {
2
+ match arr size -> {
3
+ case (0..1) -> arr
4
+ case _ ->
5
+ piv = arr at: $ rand(arr size)
6
+ (quicksort: $ arr select: |x| { x < piv }) + (quicksort: $ arr select: |x| { x >= piv })
7
+ }
8
+ }
9
+
10
+ arr = 0 upto: 10 . map: { rand(100) }
11
+ arr inspect println
12
+ quicksort: arr . inspect println
@@ -0,0 +1,18 @@
1
+ # threads.fy
2
+ # Example of threads in fancy
3
+
4
+ threads = []
5
+ 10 times: |i| {
6
+ t = Thread new: {
7
+ "Running Thread #" ++ i println
8
+ i times: {
9
+ "." print
10
+ System sleep: 1500 # sleep 1,5 sec
11
+ }
12
+ }
13
+ threads << t
14
+ }
15
+
16
+ "Waiting for all Threads to end..." print
17
+ threads each: 'join
18
+
data/examples/tuple.fy ADDED
@@ -0,0 +1,8 @@
1
+ # tuple.fy
2
+
3
+ tuple = (1,2,3)
4
+ tuple size println
5
+
6
+ (1,"foo",'bar) [0] inspect println
7
+
8
+ (1, "foo", 'bar) == (1, "foo", 'bar) println
@@ -0,0 +1,18 @@
1
+ # webserver.fy
2
+ # Example of a simple webserver written in fancy, using Ruby socket library
3
+
4
+ require("socket")
5
+ host = "127.0.0.1"
6
+ port = 3000
7
+ webserver = TCPServer new(host, port)
8
+ "Webserver running at: #{host}:#{port}" println
9
+ loop: {
10
+ session = webserver accept
11
+ session print: "HTTP/1.1 200/OK\r\nContent-type:text/html\r\n\r\n"
12
+ request = session readln
13
+ filename = "examples/webserver/index.html"
14
+ displayfile = File open(filename, "r")
15
+ content = displayfile read
16
+ session print: content
17
+ session close
18
+ }
data/lib/argv.fy ADDED
@@ -0,0 +1,36 @@
1
+ def ARGV for_option: op_name do: block {
2
+ "Runs a given block if an option is in ARGV."
3
+
4
+ ARGV index: op_name . if_do: |idx| {
5
+ if: (block argcount > 0) then: {
6
+ ARGV[idx + 1] if_do: |arg| {
7
+ block call: [arg]
8
+ ARGV remove_at: idx
9
+ ARGV remove_at: idx
10
+ }
11
+ } else: {
12
+ block call
13
+ ARGV remove_at: idx
14
+ }
15
+ }
16
+ }
17
+
18
+ def ARGV for_options: op_names do: block {
19
+ "Runs a given block if any of the given options is in ARGV."
20
+
21
+ op_names size times: |i| {
22
+ if: (ARGV index: (op_names[i])) then: |idx| {
23
+ if: (block argcount > 0) then: {
24
+ if: (ARGV[idx + 1]) then: |arg| {
25
+ block call: [arg]
26
+ ARGV remove_at: idx
27
+ ARGV remove_at: idx
28
+ }
29
+ } else: {
30
+ block call
31
+ ARGV remove_at: idx
32
+ }
33
+ return true
34
+ }
35
+ }
36
+ }
data/lib/array.fy ADDED
@@ -0,0 +1,207 @@
1
+ class Array {
2
+ """
3
+ Array class.
4
+ Arrays are dynamically resizable containers with a constant-time
5
+ index-based access to members.
6
+ """
7
+
8
+ include: FancyEnumerable
9
+
10
+ def [] index {
11
+ """
12
+ Given an Array of 2 Numbers, it returns the sub-array between the
13
+ given indices.
14
+ If given a Number, returns the element at that index.
15
+ """
16
+
17
+ # if given an Array, interpret it as a from:to: range subarray
18
+ if: (index is_a?: Array) then: {
19
+ from: (index[0]) to: (index[1])
20
+ } else: {
21
+ at: index
22
+ }
23
+ }
24
+
25
+ def rest {
26
+ "Returns all elements except the first one as a new Array."
27
+ from: 1 to: -1
28
+ }
29
+
30
+ def =? other {
31
+ """
32
+ @other Other @Array@ to compare this one to.
33
+
34
+ Compares two Arrays where order does not matter.
35
+ """
36
+
37
+ if: (other is_a?: Array) then: {
38
+ if: (self size != (other size)) then: {
39
+ nil
40
+ } else: {
41
+ all?: |x| { other includes?: x }
42
+ }
43
+ }
44
+ }
45
+
46
+ def find: item {
47
+ """
48
+ @item @Object@ / Element to find in the @Array@.
49
+ @return @item if, it's found in the @Array@, otherwise @nil.
50
+
51
+ Returns the item, if it's in the Array or nil (if not found).
52
+ """
53
+
54
+ if: (item is_a?: Block) then: {
55
+ find_by: item
56
+ } else: {
57
+ if: (index: item) then: |idx| {
58
+ at: idx
59
+ }
60
+ }
61
+ }
62
+
63
+ def find_by: block {
64
+ """
65
+ @block @Block@ to be called for each element in the @Array@.
66
+ @return The first element, for which @block yields @true.
67
+
68
+ Like find: but takes a block that gets called with each element to find it.
69
+ """
70
+
71
+ self each: |x| {
72
+ if: (block call: [x]) then: {
73
+ return x
74
+ }
75
+ }
76
+ }
77
+
78
+ def values_at: idx_arr {
79
+ """
80
+ @idx_arr @Array@ of indices.
81
+ @return @Array@ of all the items with the given indices in @idx_arr.
82
+
83
+ Returns new @Array@ with elements at given indices.
84
+ """
85
+
86
+ values = []
87
+ idx_arr each: |idx| {
88
+ values << (at: idx)
89
+ }
90
+ values
91
+ }
92
+
93
+ def >> other_arr {
94
+ """
95
+ @other_arr @Array@ to be appended to @self.
96
+ @return New @Array@ with @other_arr and @self appended.
97
+
98
+ Returns new Array with elements of other_arr appended to these.
99
+ """
100
+
101
+ arr = self clone
102
+ arr append: other_arr
103
+ }
104
+
105
+ def join {
106
+ """
107
+ @return Elements of @Array@ joined to a @String@.
108
+
109
+ Joins all elements with the empty @String@.
110
+ [\"hello\", \"world\", \"!\"] join # => \"hello, world!\"
111
+ """
112
+
113
+ join: ""
114
+ }
115
+
116
+ def select!: condition {
117
+ """
118
+ @condition A condition @Block@ (or something @Callable) for selecting items from @self.
119
+ @return @self, but changed with all elements removed that don't yield @true for @condition.
120
+
121
+ Removes all elements in place, that don't meet the condition.
122
+ """
123
+
124
+ reject!: |x| { condition call: [x] . not }
125
+ return self
126
+ }
127
+
128
+ def compact! {
129
+ """
130
+ @return @self
131
+
132
+ Removes all nil-value elements in place.
133
+ """
134
+
135
+ reject!: |x| { x nil? }
136
+ return self
137
+ }
138
+
139
+ def remove: obj {
140
+ """
141
+ @obj Object to be removed within @self.
142
+ @return @self, with all occurances of @obj removed.
143
+
144
+ Removes all occurances of obj in the Array.
145
+ """
146
+
147
+ remove_at: (indices_of: obj)
148
+ }
149
+
150
+ def remove_if: condition {
151
+ """
152
+ @condition @Block@ (or @Callable) that indicates, if an element should be removed from @self.
153
+ @return @self, with all elements removed for which @condition yields true.
154
+
155
+ Like @Array#remove:@, but taking a condition @Block@.
156
+ Removes all elements that meet the given condition @Block@.
157
+ """
158
+
159
+ remove_at: (select_with_index: |x i| { condition call: [x] } .
160
+ map: 'second)
161
+ }
162
+
163
+ def println {
164
+ "Prints each element on a seperate line."
165
+
166
+ each: |x| {
167
+ x println
168
+ }
169
+ }
170
+
171
+ def to_s {
172
+ "Returns @String@ representation of @Array@."
173
+
174
+ reduce: |x y| { x ++ y } init_val: ""
175
+ }
176
+
177
+ def * num {
178
+ """
179
+ Returns a new @Array@ that contains the elements of self num times
180
+ in a row.
181
+ """
182
+
183
+ arr = []
184
+ num times: {
185
+ arr append: self
186
+ }
187
+ arr
188
+ }
189
+
190
+ def + other_arr {
191
+ "Returns concatenation with another @Array@."
192
+
193
+ self clone append: other_arr
194
+ }
195
+
196
+ def indices {
197
+ "Returns an @Array@ of all the indices of an @Array@."
198
+
199
+ 0 upto: (self size - 1)
200
+ }
201
+
202
+ def Array === object {
203
+ if: (object is_a?: Array) then: {
204
+ return [object] + object
205
+ }
206
+ }
207
+ }