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/bin/fancy ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env rbx
2
+ # -*- ruby -*-
3
+
4
+ base = File.dirname(__FILE__)
5
+ require File.expand_path("../boot/fancy_ext", base)
6
+
7
+ # Use the bootstrapping code loader.
8
+ require File.expand_path("../boot/load", base)
9
+
10
+ do_retry = true
11
+ begin
12
+ Fancy::CodeLoader.load_compiled_file File.expand_path("../lib/boot", base)
13
+
14
+ # Remove the bootstrapping code loader
15
+ bcl = Fancy.send :remove_const, :CodeLoader
16
+ bcl.load_compiled_file File.expand_path("../lib/rbx/code_loader", base)
17
+
18
+ # Initialize the load path
19
+ Fancy::CodeLoader.push_loadpath File.expand_path("../lib", base)
20
+
21
+ # Load compiler+eval support
22
+ Fancy::CodeLoader.load_compiled_file File.expand_path("../lib/eval", base)
23
+
24
+ # Run main
25
+ Fancy::CodeLoader.load_compiled_file File.expand_path("../lib/main", base)
26
+
27
+ rescue RuntimeError => e
28
+ if e.message =~ /File not found (.*)lib\/boot.fyc/
29
+ if do_retry
30
+ puts "Fancy hasn't been bootstrapped yet. Doing that now.\n\n"
31
+ `cd #{base} && rbx -S rake clean && rbx -S rake`
32
+ do_retry = false
33
+ retry
34
+ else
35
+ raise e
36
+ end
37
+ else
38
+ raise e
39
+ end
40
+ end
data/bin/fdoc ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env rbx
2
+ # -*- ruby -*-
3
+
4
+ class Fancy; end
5
+ class Fancy::Parser; end
6
+
7
+ # fdoc is a documentation generator for fancy.
8
+ # This is a ruby script because we need to setup a hook
9
+ # BEFORE any fancy code is loaded. So we can create
10
+ # documentation for Fancy's builtin objects as well.
11
+ # See fdoc.
12
+ base = File.expand_path("../boot", File.dirname(__FILE__))
13
+ require File.expand_path("rbx-compiler/parser/fancy_parser", base)
14
+ require File.expand_path("rbx-compiler/compiler", base)
15
+ require File.expand_path("code_loader", base)
16
+ require File.expand_path("fancy_ext", base)
17
+
18
+ Fancy::CodeLoader.load_compiled_file File.expand_path("../lib/rbx/documentation.fyc", base)
19
+ Fancy::CodeLoader.load_compiled_file File.expand_path("../lib/fdoc_hook.fyc", base)
20
+
21
+ Fancy::CodeLoader.load_compiled_file File.expand_path("../lib/rbx.fyc", base)
22
+
23
+ Fancy::CodeLoader.load_compiled_file File.expand_path("../lib/fdoc.fyc", base)
data/bin/fyi ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env fancy
2
+ # -*- fancy -*-
3
+
4
+ ARGV[1] if_do: |ident| {
5
+ "Documentation for: '" ++ ident ++ "' :" println;
6
+ ident includes?: "#" . if_true: {
7
+ parts = (ident split: "#");
8
+ obj = (parts[0]) eval;
9
+ method = obj method: (parts[1]);
10
+ method documentation println
11
+ } else: {
12
+ obj = ident eval;
13
+ obj documentation println
14
+ }
15
+ } else: {
16
+ ["Prints the documentation string for a given object or one if its methods",
17
+ "Usage:",
18
+ "fyi [ObjectIdentifier]",
19
+ "fyi [ObjectIdentifier]#[MethodName]",
20
+ "",
21
+ "Example: fyi Array#each:"] println
22
+ }
data/bin/ifancy ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env fancy
2
+ # -*- fancy -*-
3
+
4
+ require("readline")
5
+
6
+ ["Welcome to the (still very simple) Fancy REPL",
7
+ "Fancy " ++ FANCY_VERSION] println
8
+
9
+ ARGV rest each: |file| {
10
+ "LOADING: " ++ file println
11
+ require: file
12
+ }
13
+
14
+ # handle SIGINT
15
+ trap("INT") {
16
+ "Quitting." println
17
+ System exit
18
+ }
19
+
20
+ Console newline;
21
+
22
+ def double_or_empty?: line {
23
+ (line =~ /^\s*$/) or: (Readline HISTORY to_a[-2] == line)
24
+ }
25
+
26
+
27
+ try {
28
+ bnd = binding()
29
+
30
+ { Readline readline(">> ", true) } while_do: |line| {
31
+
32
+ double_or_empty?: line . if_true: {
33
+ Readline::HISTORY pop()
34
+ }
35
+
36
+ line =~ /^\s*$/ if_false: {
37
+ try {
38
+ Fancy eval: line binding: bnd . inspect println
39
+ } catch Exception => e {
40
+ e message() println
41
+ }
42
+ }
43
+ }
44
+ } catch Interrupt => e {
45
+ System exit
46
+ }
data/boot/README ADDED
@@ -0,0 +1,12 @@
1
+ This directory contains all the code for compiling Fancy source files
2
+ (.fy) to Rubinius bytecode files (.fyc).
3
+
4
+ The compiler implementation is in the compiler/ directory.
5
+
6
+ The fancy_ext/ directory contains a small amount of methods defined in
7
+ Ruby to existing classes in Rubinius to allow Fancy to run on rbx. See
8
+ fancy_ext.rb for more information.
9
+
10
+ The parser/ directory contains the bison & flex written parser and
11
+ lexer which are used as a C-extension in rbx to generate the
12
+ appropriate AST node instances in parser/parser.rb.
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env rbx
2
+
3
+ base = File.dirname(__FILE__) + "/"
4
+
5
+ # load in fancy specific extensions
6
+ require base + "fancy_ext"
7
+
8
+ require base + "/rbx-compiler/compiler"
9
+ require base + "/rbx-compiler/compiler/command"
10
+
11
+ # only used for bin/fdoc at the moment
12
+ # this is just temporary and was copied from and old version
13
+ # of rbx/fancy_code_loader.rb
14
+
15
+ class Fancy
16
+ class CodeLoader
17
+ class << self
18
+ SOURCE_FILE_EXTENSION = "fy"
19
+ COMPILED_FILE_EXTENSION = "fyc"
20
+
21
+ @@load_path = []
22
+ @@compiled = {}
23
+ @@loaded = {}
24
+ @@current_dir = []
25
+
26
+ def push_loadpath path
27
+ @@load_path << path unless @@load_path.include? path
28
+ end
29
+
30
+ # Throws an exception for a given filename that wasn't found and
31
+ # thus could not be loaded.
32
+ def load_error(filename)
33
+ raise "LoadError: Can't find file: #{filename}"
34
+ end
35
+
36
+ # Returns the name of a file or nil, if it doesn't exist.
37
+ # Might append a ".fy" extension, if it's missing for the given
38
+ # filename.
39
+ def find_file(filename)
40
+ filename_with_ext = filename + ".#{SOURCE_FILE_EXTENSION}"
41
+ if !File.exists?(filename) || File.directory?(filename)
42
+ return filename_with_ext if File.exists? filename_with_ext
43
+ else
44
+ return filename
45
+ end
46
+ nil
47
+ end
48
+
49
+ # Finds a file in a given path and returns the filename including
50
+ # the path.
51
+ def find_file_in_path(file, path)
52
+ find_file(path + "/" + file)
53
+ end
54
+
55
+ # Tries to find a file with a given name in the LOADPATH array
56
+ # (all paths that have been seen while loading other files so
57
+ # far), starting with the @current_dir (the directory, the current
58
+ # running fancy source file is in).
59
+ def filename_for(filename)
60
+ if f = find_file(filename)
61
+ return f
62
+ else
63
+ if @@current_dir.last && f = find_file_in_path(filename, @@current_dir.last)
64
+ return f
65
+ end
66
+ @@load_path.each do |p|
67
+ begin
68
+ if f = find_file_in_path(filename, p)
69
+ return f
70
+ end
71
+ rescue
72
+ end
73
+ end
74
+ end
75
+ load_error filename
76
+ end
77
+
78
+ # Returns the source filename for a given filename.
79
+ # E.g. "foo.fyc" => "foo.fy"
80
+ def source_filename_for(filename)
81
+ if filename =~ /.compiled.#{COMPILED_FILE_EXTENSION}$/
82
+ return filename[0..-14]
83
+ elsif filename =~ /.#{COMPILED_FILE_EXTENSION}$/
84
+ return filename[0..-2]
85
+ end
86
+ filename
87
+ end
88
+
89
+ # Returns the compiled filename for a given filename.
90
+ # E.g. "foo.fy" => "foo.fyc", "foo" => "foo.compiled.rbc"
91
+ def compiled_filename_for(filename)
92
+ if filename =~ /.#{COMPILED_FILE_EXTENSION}$/
93
+ return filename
94
+ end
95
+ if filename =~ /\.#{SOURCE_FILE_EXTENSION}$/
96
+ return filename + "c"
97
+ else
98
+ return filename + ".compiled.#{COMPILED_FILE_EXTENSION}"
99
+ end
100
+ end
101
+
102
+ # Optionally compiles a file, if not done yet and returns the
103
+ # compiled file's name.
104
+ def optionally_compile_file(f)
105
+ source_filename = source_filename_for(f)
106
+ filename = filename_for(source_filename)
107
+ compiled_file = compiled_filename_for(filename)
108
+ unless @@compiled[filename]
109
+ if !File.exists?(compiled_file) ||
110
+ File.stat(compiled_file).mtime < File.stat(filename).mtime
111
+ Compiler.compile_fancy_file filename, nil, 1, false
112
+ else
113
+ @@compiled[filename] = true
114
+ end
115
+ end
116
+ compiled_file
117
+ end
118
+
119
+ # Loads a compiled fancy bytecode file.
120
+ # If +find_file+ is set to false, it will just use the given
121
+ # filename without looking up the file in the LOADPATH.
122
+ def load_compiled_file(filename, find_file = true)
123
+ if find_file
124
+ filename = filename_for(filename)
125
+ file = compiled_filename_for(filename)
126
+ end
127
+
128
+ file = optionally_compile_file(file)
129
+
130
+ unless @@loaded[file]
131
+ unless File.exists? file
132
+ load_error file
133
+ end
134
+
135
+ dirname = File.dirname(file)
136
+ push_loadpath dirname
137
+ @@current_dir.push dirname
138
+ @@loaded[file] = true
139
+
140
+ cl = Rubinius::CodeLoader.new(file)
141
+ cm = cl.load_compiled_file(file, 0)
142
+
143
+ script = cm.create_script(false)
144
+ script.file_path = filename
145
+
146
+ MAIN.__send__ :__script__
147
+
148
+ @@current_dir.pop
149
+ end
150
+ end
151
+ alias_method "require:", :load_compiled_file
152
+ end
153
+ end
154
+ end
155
+
156
+ if $0 == __FILE__
157
+ # load & run file
158
+ file = ARGV.shift
159
+ raise "Expected a fancy file to load" unless file
160
+ if File.exists? file
161
+ Fancy::CodeLoader.load_compiled_file file
162
+ else
163
+ Fancy::CodeLoader.load_compiled_file(base + "../lib/main.fyc")
164
+ end
165
+ end
data/boot/compile.fy ADDED
@@ -0,0 +1,3 @@
1
+ # Bootstrap Usage:
2
+ # rbx boot/load.rb boot/compiler/boot.fyc boot/compiler/compiler.fyc boot/compiler/command.fyc boot/compile.fyc -- <FILES_TO_COMPILE>
3
+ Fancy Compiler Command run: ARGV
data/boot/fancy_ext.rb ADDED
@@ -0,0 +1,13 @@
1
+ # The fancy_ext directory contains Rubinius-specific code (mostly
2
+ # extension methods) for existing classes that need to be defined in
3
+ # Ruby in order for Fancy to work correctly on rbx.
4
+ # The amount of code should be kept as small as possible, as we want
5
+ # to write as much in Fancy as possible.
6
+
7
+ base = File.dirname(__FILE__) + "/fancy_ext/"
8
+ require base + "kernel"
9
+ require base + "module"
10
+ require base + "object"
11
+ require base + "block_env"
12
+ require base + "class"
13
+ require base + "string_helper"
@@ -0,0 +1,29 @@
1
+ # in Fancy we use the BlockEnvironment as Block
2
+ Block = Rubinius::BlockEnvironment
3
+
4
+ class Block
5
+ define_method("while_true:") do |block|
6
+ while tmp = self.call
7
+ block.call(tmp)
8
+ end
9
+ end
10
+
11
+ # call without arguments
12
+ alias_method :":call", :call
13
+
14
+ define_method("call:") do |args|
15
+ if args.first.is_a?(Array) && args.size == 1
16
+ call args.first
17
+ else
18
+ call *args
19
+ end
20
+ end
21
+
22
+ define_method("call_with_receiver:") do |obj|
23
+ call_under obj, method.scope
24
+ end
25
+
26
+ define_method("call:with_receiver:") do |args, obj|
27
+ call_under obj, method.scope, *args
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ class Class
2
+ # the define_constructor_class_method: method defines a constructor
3
+ # class method.
4
+ # e.g. for an instance method named "initialize:foo:" we'll define a class
5
+ # method named "new:foo:" which creates a new instance of the class
6
+ # (via allocate) & call the "initialize:foo:" method on it, before
7
+ # returning the new instance.
8
+ # NOTE:
9
+ # the method_name argument to "define_constructor_class_method:"
10
+ # contains only the rest of the method name, not including the
11
+ # "initialize:" or "new:", so we'll have to prepend it ourselves
12
+ define_method("define_constructor_class_method:") do |method_name|
13
+ self.metaclass.send(:define_method, "new:" + method_name) do |*args|
14
+ obj = self.allocate
15
+ obj.send("initialize:" + method_name, *args)
16
+ return obj
17
+ end
18
+ end
19
+
20
+ define_method(":define_forward_method_missing") do
21
+ define_method("method_missing") do |method_name, *args|
22
+ self.send("unknown_message:with_params:", method_name, args)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,12 @@
1
+ module Kernel
2
+
3
+ alias_method :":metaclass", :metaclass
4
+
5
+ def fancy_require(file, compile = false)
6
+ if compile
7
+ file = Fancy::CodeLoader.compile_file! file
8
+ end
9
+ find_file = !compile
10
+ Fancy::CodeLoader.load_compiled_file file, find_file
11
+ end
12
+ end
@@ -0,0 +1,89 @@
1
+ class Module
2
+
3
+ # Fancy version does not restricts to only modules.
4
+ define_method :"include:" do |modules|
5
+ modules = [modules] unless modules.kind_of?(Array)
6
+ modules.reverse_each do |mod|
7
+ mod.send :"append_features:", self
8
+ mod.send :included, self
9
+ end
10
+ end
11
+
12
+ # Fancy version does not restricts to only modules.
13
+ ###
14
+ #
15
+ # Called when this Module is being included in another Module.
16
+ # This may be overridden for custom behaviour. The default
17
+ # is to add constants, instance methods and module variables
18
+ # of this Module and all Modules that this one includes to +klass+.
19
+ #
20
+ # See also #include.
21
+ #
22
+ define_method :"append_features:" do |klass|
23
+ # check other.frozen
24
+ # taint other from self
25
+
26
+ insert_at = klass
27
+ mod = self
28
+ changed = false
29
+
30
+ while mod
31
+
32
+ # Check for a cyclic include
33
+ if mod == klass
34
+ raise ArgumentError, "cyclic include detected"
35
+ end
36
+
37
+ # Try and detect check_mod in klass's heirarchy, and where.
38
+ #
39
+ # I (emp) tried to use Module#< here, but we need to also know
40
+ # where in the heirarchy the module is to change the insertion point.
41
+ # Since Module#< doesn't report that, we're going to just search directly.
42
+ #
43
+ superclass_seen = false
44
+ add = true
45
+
46
+ k = klass.direct_superclass
47
+ while k
48
+ if k.kind_of? Rubinius::IncludedModule
49
+ # Oh, we found it.
50
+ if k == mod
51
+ # ok, if we're still within the directly included modules
52
+ # of klass, then put future things after mod, not at the
53
+ # beginning.
54
+ insert_at = k unless superclass_seen
55
+ add = false
56
+ break
57
+ end
58
+ else
59
+ superclass_seen = true
60
+ end
61
+
62
+ k = k.direct_superclass
63
+ end
64
+
65
+ if add
66
+ if mod.kind_of? Rubinius::IncludedModule
67
+ original_mod = mod.module
68
+ else
69
+ original_mod = mod
70
+ end
71
+
72
+ im = Rubinius::IncludedModule.new(original_mod).attach_to insert_at
73
+ insert_at = im
74
+
75
+ changed = true
76
+ end
77
+
78
+ mod = mod.direct_superclass
79
+ end
80
+
81
+ if changed
82
+ method_table.each do |meth, obj, vis|
83
+ Rubinius::VM.reset_method_cache meth
84
+ end
85
+ end
86
+
87
+ return self
88
+ end
89
+ end