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/AUTHORS ADDED
@@ -0,0 +1,7 @@
1
+ # Here's a (YAML-formatted) list of all people that have contributed to Fancy.
2
+
3
+ - Christopher Bertels: { email: chris@fancy-lang.org, website: http://www.fancy-lang.org, irc: bakkdoor }
4
+ - Christian Kruse:
5
+ - Jose Narvaez: { email: goyox86@gmail.com, irc: goyox86, twitter: goyox86 }
6
+ - Nils Haldenwang: { email: n.haldenwang@googlemail.com, website: http://www.nils-haldenwang.de, irc: NilsH }
7
+ - Victor Hugo Borja: { email: vic.borja@gmail.com, irc: vborja, twitter: vborja }
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010, 2011, Christopher Bertels
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
7
+ disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
9
+ disclaimer in the documentation and/or other materials provided with the distribution.
10
+ * Neither the name of the original authors nor the names of its contributors may be used to endorse or promote
11
+ products derived from this software without specific prior written permission.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
14
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
16
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
17
+ SERVICES; LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
18
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
19
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,173 @@
1
+ The Fancy Programming Language
2
+ (C) 2010, 2011 Christopher Bertels <chris@fancy-lang.org>
3
+ http://www.fancy-lang.org
4
+
5
+ ----------------------------------------------------------------------
6
+
7
+ Fancy is a dynamic, object-oriented programming language heavily
8
+ inspired by Smalltalk, Ruby and Erlang. It supports dynamic code
9
+ evaluation (as in Ruby & Smalltalk), class-based mixins, (simple)
10
+ pattern matching, runtime introspection & reflection, "monkey
11
+ patching" and much more. It runs on Rubinius, the Ruby VM, and thus
12
+ has first-class integration with Ruby's core library and any
13
+ additional Ruby libraries that run on Rubinius, including most
14
+ C-extensions.
15
+ It will support concurrency via the actor-model, including first-class
16
+ futures and async operation semantics built into the language.
17
+
18
+ For a quick feature overview, have a look at doc/features.md
19
+
20
+ ----------------------------------------------------------------------
21
+
22
+ It’s still in development, the implementation has evolved from an
23
+ interpreter written in C++ to a fully bootstrapped bytecode compiler
24
+ for the Rubinius VM (http://www.rubini.us).
25
+ You can see the self-hosted compiler implementation in lib/compiler/.
26
+
27
+ If you want to help out, feel free to contact us:
28
+ http://github.com/bakkdoor/fancy/wiki/Get-in-touch
29
+
30
+ For some example code have a look at the examples/ directory.
31
+
32
+ There's also lots of test coverage code. Have a look at the tests/
33
+ directory for these. The tests are written in FancySpec, a simple
34
+ testing library (somewhat similar to Ruby's RSpec). FancySpec's
35
+ implementation can be viewed in lib/fancy_spec.fy.
36
+
37
+ ----------------------------------------------------------------------
38
+
39
+ Compiling / Installing from source:
40
+ ------------------------------------
41
+
42
+ Dependencies:
43
+ ------------------------
44
+
45
+ - Rubinius.
46
+ For now you'll need a recent version from the git repository.
47
+ We suggest using rvm and installing rbx-head.
48
+ See http://rvm.beginrescueend.com/ for more information.
49
+ - Rake.
50
+ - GNU Bison ( version 2.4 and higher otherwise you will get a Segmentation fault ).
51
+ - GNU Flex.
52
+
53
+ Given the tools & libraries mentioned above, Fancy _should_ build without problems
54
+ on most *nix systems. We successfully have built Fancy on Debian & Ubuntu, OpenSuSE
55
+ and Mac OS X 10.5 and 10.6.
56
+
57
+ Standard building procedure:
58
+ ------------------------
59
+
60
+ Building Fancy is just that easy:
61
+
62
+ $ cd <fancy_source_path>
63
+ $ rake
64
+
65
+ This should go pretty fast. It actually compiles Fancy's standard
66
+ library and compiler several times. Once via the bootstrap compiler
67
+ written in Ruby (see boot/rbx-compiler), and then via the self-hosted
68
+ compiler (see lib/compiler/) itself.
69
+
70
+ Once the bootstrapping process is done, you can run the hello world example:
71
+
72
+ $ ./bin/fancy examples/hello_world.fy
73
+
74
+ ----------------------------
75
+ Some technical information:
76
+ ----------------------------
77
+
78
+ As the language is running on the Rubinius VM, Fancy shares the same
79
+ runtime with Ruby. All of Fancy is built upon Ruby objects, so for
80
+ example when you open the String class in Fancy, it's just Ruby's
81
+ String class.
82
+
83
+ Because of this, and because in Fancy's standard library (lib/*.fy) we
84
+ can define methods with the same name as they're defined in Ruby (but
85
+ taking no arguments), we have decided not to overwrite the Ruby
86
+ methods.
87
+ This ensures that all Ruby libraries for example can use Ruby's
88
+ Kernel#print or any other method in Ruby's kernel and work seamlessly.
89
+
90
+ Here's an example:
91
+
92
+ class Object {
93
+ def print {
94
+ "Print itself to the Console."
95
+ Console print: self
96
+ }
97
+ }
98
+
99
+ To meet this goal, the Fancy compiler renames Fancy methods taking no
100
+ arguments (like the previous "print" example) to a method named
101
+ ":print". Using explicit parens syntax will allow you to invoke any
102
+ Ruby method.
103
+
104
+ someObject print # Will actually invoke the Fancy ":print" method.
105
+ someObject print() # With explicit parens invokes the Ruby method.
106
+
107
+ Ruby method invocation supports passing a block variable to Ruby as a proc.
108
+
109
+ class Something {
110
+ def open: block {
111
+ someRubyMethod(arg0, arg1, &block)
112
+ }
113
+ }
114
+ Something new open: |s| { s work }
115
+
116
+ # with this syntax, calling ruby's inject is just as easy.
117
+ # This example will print the number 6
118
+ [1, 2, 3] inject(0) |sum, num| { sum + num } println
119
+
120
+
121
+ What's already working?
122
+ ------------------------
123
+
124
+ - Class definitions
125
+ (including nested classes that work like modules / namespaces)
126
+ - Instance & class method definitions
127
+ - Default arguments
128
+ - Literal syntax for:
129
+ - Strings, Symbols, Integers, Floats, Arrays, Hashes (HashMaps), Blocks (closures),
130
+ Ranges, Tuples, Regular Expressions
131
+ - Method & Operator calls
132
+ - Instance & class variable access
133
+ - Dynamic getter and setter method definitions (similar to Ruby's attr_acessor)
134
+ - Loops
135
+ - Support for closures via Blocks
136
+ - Local & non-local returns from Blocks & Methods
137
+ - File reading and writing
138
+ - Class-Mixins (including methods of one class into another)
139
+ - Exception handling (try, catch, finally & retry)
140
+ - Simple pattern matching (work-in-progress)
141
+ - Calling, using and extending arbitrary Ruby classes and methods
142
+ (including C-extensions), as well as passing blocks and splat
143
+ arguments to Ruby methods.
144
+
145
+
146
+ What's still missing?
147
+ ----------------------
148
+
149
+ - Concurrency stuff (Actor-model based concurrency, Futures etc)
150
+ - Some more advanced stuff, e.g. runtime inspection of method calls
151
+ via MethodContext etc. (saved for later)
152
+
153
+
154
+ How is it implemented?
155
+ -----------------------
156
+
157
+ - The lexer & parser are built with GNU Flex & GNU Bison.
158
+ And used as a Ruby c-extension from Rubinius.
159
+ The parser simply invokes methods on Fancy::Parser to build the AST.
160
+ See: rbx/parser/parser.y & rbx/parser/parser.rb
161
+
162
+ - Once the AST is built, we use Rubinius' excellent compiler chain
163
+ to compile it to bytecode.
164
+
165
+ - The bin/fancy file is simply a Rubinius code loader for .fy files.
166
+
167
+ ----------------------------------------------------------------------
168
+
169
+ Copyright:
170
+ -----------
171
+
172
+ Fancy is licensed under the terms of the BSD license. For more
173
+ information on licensing issues have a look at the LICENSE file.
data/Rakefile ADDED
@@ -0,0 +1,255 @@
1
+ require 'rbconfig'
2
+
3
+ def say(*msg)
4
+ puts(*msg) unless RakeFileUtils.verbose_flag == false
5
+ end
6
+
7
+ def sh!(*args, &block)
8
+ old_verbose = RakeFileUtils.verbose_flag
9
+ begin
10
+ RakeFileUtils.verbose_flag = nil if RakeFileUtils.verbose_flag == :default
11
+ sh(*args, &block)
12
+ ensure
13
+ RakeFileUtils.verbose_flag = old_verbose
14
+ end
15
+ end
16
+
17
+ def _(f, base = File.dirname(__FILE__))
18
+ File.expand_path(f, base)
19
+ end
20
+
21
+
22
+ dl_ext = RbConfig::CONFIG['DLEXT']
23
+ ext_dir = _("lib/parser/ext")
24
+ parser_e = _("fancy_parser.#{dl_ext}", ext_dir)
25
+ load_rb = _("boot/load.rb")
26
+
27
+ namespace :parser do
28
+
29
+ lexer_lex = _("lexer.lex", ext_dir)
30
+ lexer_c = _("lexer.c", ext_dir)
31
+ parser_y = _("parser.y", ext_dir)
32
+ parser_c = _("parser.c", ext_dir)
33
+ extconf = _("extconf.rb", ext_dir)
34
+ makefile = _("Makefile", ext_dir)
35
+
36
+ file lexer_c => file(lexer_lex) do
37
+ Dir.chdir(ext_dir) do
38
+ sh! 'flex', '--outfile', lexer_c, '--header-file=lexer.h', lexer_lex
39
+ end
40
+ end
41
+
42
+ file parser_c => file(parser_y) do
43
+ Dir.chdir(ext_dir) { sh! 'bison', '--output', parser_c, '-d', '-v', parser_y }
44
+ end
45
+
46
+ file makefile => file(extconf) do
47
+ Dir.chdir(ext_dir) { sh! 'rbx', extconf }
48
+ end
49
+
50
+ desc "Generate parser source from flex/bison"
51
+ task :generate => [parser_c, lexer_c, makefile]
52
+
53
+ file parser_e => file(makefile) do
54
+ sh! 'make', '-C', ext_dir
55
+ end
56
+
57
+ desc "Compile the parser extension"
58
+ task :compile => file(parser_e)
59
+
60
+ desc "Removed generated parser sources"
61
+ task :remove do
62
+ rm_f [_("parser.h", ext_dir), _("lexer.h", ext_dir)], :verbose => false
63
+ rm_f [makefile, parser_c, lexer_c], :verbose => false
64
+ end
65
+
66
+ desc "Clean compiled files."
67
+ task :clean do
68
+ rm_f Dir.glob(_("*.{o,so,rbc,log,output,bundle}", ext_dir)), :verbose => false
69
+ rm_rf [_("conftest.dSYM", ext_dir)], :verbose => true
70
+ end
71
+
72
+ end
73
+
74
+
75
+ namespace :compiler do
76
+
77
+ boot_parser_e = _("boot/compiler/parser/ext/"+File.basename(parser_e))
78
+
79
+ file boot_parser_e => file(parser_e) do
80
+ mkdir_p File.dirname(boot_parser_e), :verbose => false
81
+ cp parser_e, boot_parser_e, :verbose => false
82
+ end
83
+
84
+ task :clean do
85
+ rm_f boot_parser_e, :verbose => false
86
+ rm_rf _("boot/rbx-compiler/parser/conftest.dSYM")
87
+ rm_rf _("boot/compiler"), :verbose => false
88
+ end
89
+
90
+ desc "Compile fancy using the stable compiler (from boot/compiler)."
91
+ task :compile => file(boot_parser_e) do
92
+ say "Compiling fancy using stable compiler."
93
+
94
+ cmd = ['rbx -Xint', load_rb]
95
+ cmd << _("boot/compiler/boot.fyc")
96
+ cmd << _("boot/compiler/compiler.fyc")
97
+ cmd << _("boot/compiler/compiler/command.fyc")
98
+ cmd << _("boot/compiler/compile.fyc")
99
+ cmd << "--"
100
+ cmd << "--batch" if RakeFileUtils.verbose_flag == true
101
+
102
+ sources = Dir.glob("lib/**/*.fy")
103
+ system (cmd + sources).join(" ")
104
+ end
105
+
106
+ load("boot/rbx-compiler/parser/Rakefile")
107
+
108
+ desc "Compile fancy using boot/rbx-compiler into boot/compiler/"
109
+ task :rootstrap => "compiler:rbx_parser:ext" do
110
+ say "Compiling fancy into boot/compiler using ruby-based compiler from boot/rbx-compiler."
111
+
112
+ output = _("boot/compiler")
113
+
114
+ cmd = ['rbx -Xint']
115
+ cmd << _("boot/rbx-compiler/compiler.rb")
116
+ cmd << "--batch" if RakeFileUtils.verbose_flag == true
117
+ cmd << "--output-path" << output
118
+
119
+ src_path = ["--source-path", _("lib")]
120
+ sources = Dir.glob(_("lib/**/*.fy"))
121
+ system (cmd + src_path + sources).join(" ")
122
+
123
+ src_path = ["--source-path", _("boot")]
124
+ sources = Dir.glob(_("boot/*.fy"))
125
+ system (cmd + src_path + sources).join(" ")
126
+
127
+ sh! "rbx", _("boot/rbx-compiler/compiler.rb"), _("boot/compile.fy")
128
+
129
+ end
130
+
131
+ desc "Compile fancy using lib/ compiler into boot/compiler/"
132
+ task :wootstrap do
133
+
134
+ say "Compiling fancy into boot/compiler using development compiler from lib/"
135
+
136
+ output = _("boot/.wootstrap")
137
+
138
+ cmd = ['rbx -Xint', load_rb]
139
+ cmd << _("lib/boot.fyc")
140
+ cmd << _("lib/compiler.fyc")
141
+ cmd << _("lib/compiler/command.fyc")
142
+ cmd << _("boot/compiler/compile.fyc")
143
+ cmd << "--"
144
+ cmd << "--batch" if RakeFileUtils.verbose_flag == true
145
+ cmd << "--output-path" << output
146
+
147
+ sources = Dir.glob("lib/**/*.fy")
148
+ system (cmd + sources).join(" ")
149
+
150
+ mkdir_p _("parser/ext", output), :verbose => false
151
+ cp parser_e, _("parser/ext", output), :verbose => false
152
+
153
+ say "Using fresh built compiler as `stable compiler' in boot/compiler"
154
+
155
+ rm_rf _("boot/compiler")
156
+ mv _("boot/.wootstrap"), _("boot/compiler")
157
+ end
158
+
159
+ task :bootstrap => ["parser:generate", "rbx_parser:ext", file(boot_parser_e)] do
160
+ ["compiler:rootstrap", "compiler:compile", "compiler:wootstrap"].each do |t|
161
+ task(t).reenable
162
+ task(t).execute
163
+ end
164
+ end
165
+
166
+ task :diff do
167
+ require 'open3'
168
+ sources = Dir.glob(_("lib/**/*.fy"))
169
+
170
+ say "Compiling fancy using stable compiler."
171
+ cmd = ['rbx', load_rb]
172
+ cmd << _("lib/boot.fyc")
173
+ cmd << _("lib/compiler.fyc")
174
+ cmd << _("lib/compiler/command.fyc")
175
+ cmd << _("boot/compiler/compiler.fyc")
176
+ cmd << "--"
177
+
178
+ sources.each do |file|
179
+ f = file.gsub(_("lib"), _("diff/fy-compiler")).gsub(/.fy$/, ".asm")
180
+ puts f
181
+ mkdir_p File.dirname(f), :verbose => false
182
+ Open3.popen3 *(cmd + [file, "-B"]) do |stdin, stdout, stderr|
183
+ File.open(f, "w") { |bc| bc.print stdout.read }
184
+ end
185
+ end
186
+
187
+
188
+ cmd = ['rbx']
189
+ cmd << _("boot/rbx-compiler/compiler.rb")
190
+
191
+ sources.each do |file|
192
+ f = file.gsub(_("lib"), _("diff/rb-compiler")).gsub(/.fy$/, ".asm")
193
+ puts f
194
+ mkdir_p File.dirname(f), :verbose => false
195
+ Open3.popen3 *(cmd + [file, "-B"]) do |stdin, stdout, stderr|
196
+ File.open(f, "w") { |bc| bc.print stdout.read }
197
+ end
198
+ end
199
+
200
+ sources.each do |file|
201
+ a = file.gsub(_("lib"), _("diff/rb-compiler")).gsub(/.fy$/, ".asm")
202
+ b = file.gsub(_("lib"), _("diff/fy-compiler")).gsub(/.fy$/, ".asm")
203
+ f = file.gsub(_("lib"), _("diff/diffs")).gsub(/.fy$/, ".diff")
204
+ mkdir_p File.dirname(f), :verbose => false
205
+ puts f
206
+ Open3.popen3 'diff', '-u9999', a, b do |stdin, stdout|
207
+ File.open(f, "w") { |bc| bc.print stdout.read }
208
+ end
209
+ end
210
+
211
+ end
212
+
213
+ end
214
+
215
+ desc "Deletes all .rbc and .fyc files."
216
+ task :clean_compiled do
217
+ compiled = Dir.glob(_ "**/*.{rbc,fyc}")
218
+ rm_f compiled, :verbose => false
219
+ end
220
+
221
+ desc "Clean compiled files."
222
+ task :clean => ["parser:clean", "parser:remove", "compiler:clean", :clean_compiled]
223
+
224
+
225
+ def compile(source)
226
+ cmd = ['rbx', _("boot/load.rb")]
227
+ cmd << _("lib/boot.fyc")
228
+ cmd << _("lib/compiler.fyc")
229
+ cmd << _("lib/compiler/command.fyc")
230
+ cmd << _("boot/compile.fyc")
231
+ cmd << "--"
232
+ cmd << "--batch" if RakeFileUtils.verbose_flag == true
233
+ cmd << source.to_s
234
+ sh! *cmd
235
+ end
236
+
237
+ sources = Dir.glob(_("{lib,boot}/**/*.fy")).map { |f| file f }
238
+ compiled = sources.map { |s| file((s.to_s+"c") => [s, file(parser_e)]) { compile s } }
239
+
240
+ task :bootstrap_if_needed do
241
+ task(:bootstrap).invoke unless File.directory? _("boot/compiler")
242
+ end
243
+
244
+ task :compile => compiled
245
+
246
+ desc "Runs the test suite."
247
+ task :test do
248
+ sh! _('bin/fancy'),
249
+ '-e', 'ARGV rest rest each: |f| { require: f }',
250
+ *Dir.glob(_("tests/*.fy"))
251
+ end
252
+
253
+ task :bootstrap => ["compiler:bootstrap"]
254
+
255
+ task :default => [:bootstrap_if_needed, :compile]