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/lib/rbx/bignum.fy ADDED
@@ -0,0 +1,23 @@
1
+ class Bignum {
2
+ include: Number
3
+
4
+ ruby_alias: '==
5
+ ruby_alias: '-
6
+ ruby_alias: '+
7
+ ruby_alias: '*
8
+ ruby_alias: '/
9
+ ruby_alias: '<
10
+ ruby_alias: '>
11
+ ruby_alias: '<=
12
+ ruby_alias: '>=
13
+ ruby_alias: '===
14
+ ruby_alias: 'chr
15
+ ruby_alias: 'to_i
16
+ ruby_alias: '**
17
+ ruby_alias: '&
18
+
19
+ alias_method: 'to_s: for: 'to_s
20
+ alias_method: 'modulo: for: 'modulo
21
+ alias_method: ":%" for: "modulo:" # prepend with : so we dont overwrite ruby's % operator
22
+ alias_method: 'div: for: 'div
23
+ }
data/lib/rbx/block.fy ADDED
@@ -0,0 +1,9 @@
1
+ # Block = BlockEnvironment
2
+
3
+ class Block {
4
+ def argcount {
5
+ "Returns the amount of arguments (arity) a Block takes."
6
+
7
+ arity()
8
+ }
9
+ }
data/lib/rbx/class.fy ADDED
@@ -0,0 +1,129 @@
1
+ class Class {
2
+ ruby_alias: 'superclass
3
+ ruby_alias: '===
4
+ ruby_alias: 'ancestors
5
+
6
+ def new {
7
+ """
8
+ @return A new @Class@ subclassed from @Object@.
9
+
10
+ Creates a new @Class@ instance by subclassing @Object@.
11
+ """
12
+
13
+ obj = self allocate()
14
+ obj initialize
15
+ obj
16
+ }
17
+
18
+ # calls initialize:, if defined
19
+ def new: superclass {
20
+ """
21
+ @superclass The superclass to inherit from.
22
+ @return A new @Class@ inherited from @superclass.
23
+
24
+ Creates a new @Class@ instance by subclassing @superclass.
25
+ """
26
+
27
+ obj = self allocate()
28
+ obj initialize: superclass
29
+ obj
30
+ }
31
+
32
+ def Class superclass: superclass body: body_block {
33
+ """
34
+ @superclass The superclass to inherit from.
35
+ @body_block A @Block@ that is used as the body of the new @Class@.
36
+ @return A new @Class@ inherited from @superclass.
37
+
38
+ Creates a new @Class@ by subclassing @superclass and using
39
+ @body_block as its body.
40
+ """
41
+
42
+ new(superclass, &body_block)
43
+ }
44
+
45
+ def define_method: name with: block {
46
+ """
47
+ @name Name of the method to be defined.
48
+ @block A @Block@ that is used as the method's body.
49
+
50
+ Defines an instance method on a @Class@ with a given name and
51
+ body.
52
+ """
53
+
54
+ define_method(message_name: name, &block)
55
+ }
56
+
57
+ def undefine_method: name {
58
+ """
59
+ @name Name of the method to undefine (remove) from a @Class@.
60
+
61
+ Undefines an instance method on a Class with a given name.
62
+ """
63
+
64
+ remove_method(message_name: name)
65
+ }
66
+
67
+ def define_class_method: name with: block {
68
+ """
69
+ @name Name of the class method to be defined.
70
+ @block A @Block@ to be used as the class methods body.
71
+
72
+ Defines a class method on a @Class@ (a singleton method) with a
73
+ given name and body.
74
+ """
75
+
76
+ define_singleton_method: name with: block
77
+ }
78
+
79
+ def undefine_class_method: name {
80
+ """
81
+ @name Name of the class method to undefine (remove).
82
+
83
+ Undefines a class method on a @Class@ with a given name.
84
+ """
85
+
86
+ undefine_singleton_method: name
87
+ }
88
+
89
+ def subclass: body_block {
90
+ """
91
+ @body_block A @Block@ that gets used as the body of the @Class@.
92
+ @return A new @Class@ inherited from @self.
93
+
94
+ Creates a new @Class@ with @self as superclass and the given body.
95
+ """
96
+
97
+ Class superclass: self body: body_block
98
+ }
99
+
100
+ def nested_classes {
101
+ """
102
+ @return @Array@ of all nested classes for @self.
103
+
104
+ Returns all the nested classes within a @Class@ as an @Array@.
105
+ """
106
+
107
+ "Not Yet Implemented" raise!
108
+ }
109
+
110
+ def instance_method: name {
111
+ """
112
+ @name Name of the instance method to return.
113
+ @return The instance @Method@ with the given @name or @nil.
114
+
115
+ Returns an instance method for a @Class@ with a given name.
116
+ """
117
+
118
+ self instance_method(message_name: name)
119
+ }
120
+
121
+ def alias_method_rbx: new_method_name for: old_method_name {
122
+ """
123
+ Rbx specific version of alias_method:for: due to bootstrap order
124
+ reasons. Should not be used directly.
125
+ """
126
+
127
+ alias_method(message_name: new_method_name, message_name: old_method_name)
128
+ }
129
+ }
@@ -0,0 +1,192 @@
1
+ class Fancy {
2
+ class CodeLoader {
3
+ """
4
+ Fancy CodeLoader.
5
+
6
+ Is used to load Fancy source (.fy) and compiled (.fyc) files into
7
+ the runtime.
8
+ """
9
+
10
+ SOURCE_FILE_EXTENSION = "fy"
11
+ COMPILED_FILE_EXTENSION = "fyc"
12
+
13
+ @@load_path = []
14
+ @@loaded = <[]>
15
+ @@compiled = <[]>
16
+ @@file_stack = []
17
+ @@current_dir = []
18
+
19
+ def self file_stack {
20
+ @@file_stack
21
+ }
22
+
23
+ def self loaded {
24
+ @@loaded
25
+ }
26
+
27
+ def self load_path {
28
+ @@load_path
29
+ }
30
+
31
+ def self push_loadpath: path {
32
+ """
33
+ @path The path to add to the @LOADPATH
34
+
35
+ Adds a given path to Fancy's @LOADPATH.
36
+ """
37
+ { @@load_path << path } unless: $ @@load_path includes?: path
38
+ }
39
+
40
+ # Throws an exception for a given filename that wasn't found and
41
+ # thus could not be loaded.
42
+ def self load_error: filename {
43
+ "LoadError: Can't find file: " ++ filename raise!
44
+ }
45
+
46
+ # Returns the name of a file or nil, if it doesn't exist.
47
+ # Might append a ".fy" extension, if it's missing for the given
48
+ # filename.
49
+ def self find_file: filename {
50
+ filename_with_ext = filename + "." + SOURCE_FILE_EXTENSION
51
+ if: ({File exists?(filename) not} || {File directory?(filename)}) then: {
52
+ { return filename_with_ext } if: $ File exists?(filename_with_ext)
53
+ } else: {
54
+ return filename
55
+ }
56
+ nil
57
+ }
58
+
59
+ # Finds a file in a given path and returns the filename including
60
+ # the path.
61
+ def self find_file: file in_path: path {
62
+ find_file: $ path + "/" + file
63
+ }
64
+
65
+
66
+ # Tries to find a file with a given name in the LOADPATH array
67
+ # (all paths that have been seen while loading other files so
68
+ # far), starting with the @current_dir (the directory, the current
69
+ # running fancy source file is in).
70
+ def self filename_for: filename {
71
+ if: (find_file: filename) then: |f| {
72
+ return f
73
+ } else: {
74
+ if: (@@current_dir last) then: {
75
+ if: (find_file: filename in_path: (@@current_dir last)) then: |f| {
76
+ return f
77
+ }
78
+ }
79
+ @@load_path each: |p| {
80
+ try {
81
+ if: (find_file: filename in_path: p) then: |f| {
82
+ return f
83
+ }
84
+ } catch {
85
+ }
86
+ }
87
+ }
88
+ load_error: filename
89
+ }
90
+
91
+ # Returns the source filename for a given filename.
92
+ # E.g. "foo.fyc" => "foo.fy"
93
+ def self source_filename_for: file {
94
+ match file -> {
95
+ case /.*\.compiled\.fyc$/ -> file from: 0 to: -14
96
+ case /.*\.fyc$/ -> file from: 0 to: -2
97
+ case /\.fy$/ -> file
98
+ case _ -> file
99
+ }
100
+ }
101
+
102
+ # Returns the compiled filename for a given filename.
103
+ # E.g. "foo.fy" => "foo.fyc", "foo" => "foo.compiled.rbc"
104
+ def self compiled_filename_for: file {
105
+ match file -> {
106
+ case /\.fyc$/ -> file
107
+ case /\.fy$/ -> file + "c"
108
+ case _ -> file + ".compiled.fyc"
109
+ }
110
+ }
111
+
112
+ # Optionally compiles a file, if not done yet and returns the
113
+ # compiled file's name.
114
+ def self optionally_compile_file: f {
115
+ source_filename = source_filename_for: f
116
+ filename = filename_for: source_filename
117
+ compiled_file = compiled_filename_for: filename
118
+ unless: (@@compiled[filename]) do: {
119
+ if: ({File exists?(compiled_file) not} || \
120
+ {File stat(compiled_file) mtime() <((File stat(filename) mtime()))}) then: {
121
+ # Rubinius::Compiler.compile_fancy_file filename, nil, 1, false
122
+ Compiler compile_file: filename to: compiled_file
123
+ } else: {
124
+ @@compiled at: filename put: true
125
+ }
126
+ }
127
+ compiled_file
128
+ }
129
+
130
+
131
+ # Loads a compiled fancy bytecode file.
132
+ # If +find_file+ is set to false, it will just use the given
133
+ # filename without looking up the file in the LOADPATH.
134
+ def self load_compiled_file: source_file find_file: find_file (true) {
135
+ compiled_file = source_file
136
+
137
+ if: find_file then: {
138
+ source_file = filename_for: source_file
139
+
140
+ dir = File expand_path(File dirname(source_file), ".")
141
+ source_file = File expand_path(File basename(source_file), dir)
142
+
143
+ compiled_file = compiled_filename_for: source_file
144
+ }
145
+
146
+ compiled_file = optionally_compile_file: compiled_file
147
+
148
+ unless: (@@loaded[compiled_file]) do: {
149
+ unless: (File exists?(compiled_file)) do: {
150
+ load_error: compiled_file
151
+ }
152
+
153
+ dirname = File dirname(compiled_file)
154
+ push_loadpath: dirname
155
+ @@current_dir push(dirname)
156
+ @@loaded at: compiled_file put: true
157
+
158
+ cl = Rubinius::CodeLoader new(compiled_file)
159
+ cm = cl load_compiled_file(compiled_file, 0)
160
+
161
+ script = cm create_script(false)
162
+ script file_path=(source_file)
163
+
164
+
165
+ try {
166
+ @@file_stack push(source_file)
167
+ MAIN __send__('__script__)
168
+ } finally {
169
+ @@current_dir pop()
170
+ @@file_stack pop()
171
+ }
172
+ }
173
+ }
174
+
175
+ def self current_file: compiled_from {
176
+ @@file_stack last
177
+ }
178
+
179
+ def self file_not_found: file {
180
+ "File not found: " ++ file . raise!
181
+ }
182
+
183
+ def self fancy_require: file {
184
+ load_compiled_file: file find_file: true
185
+ }
186
+
187
+ self metaclass send('alias_method, "require:", "fancy_require:")
188
+ self metaclass send('alias_method, "load:", "load_compiled_file:")
189
+ self metaclass send('alias_method, "load_compiled_file", "load_compiled_file:")
190
+ self metaclass send('alias_method, "push_loadpath", "push_loadpath:")
191
+ }
192
+ }
@@ -0,0 +1,63 @@
1
+ class Console {
2
+ "Console class. Used for @STDIO."
3
+
4
+ def Console newline {
5
+ "Prints a newline to @STDOUT."
6
+
7
+ STDOUT puts()
8
+ }
9
+
10
+ def Console print: obj {
11
+ """
12
+ @obj Object to be printed on @STDOUT.
13
+
14
+ Prints a given object on @STDOUT.
15
+ """
16
+
17
+ STDOUT print(obj)
18
+ }
19
+
20
+ def Console println: obj {
21
+ """
22
+ @obj Object to be printed on @STDOUT, followed by a newline.
23
+
24
+ Prints a given object on @STDOUT, followed by a newline.
25
+ """
26
+
27
+ STDOUT puts(obj)
28
+ }
29
+
30
+ def Console readln: message {
31
+
32
+ """
33
+ @message A @String@ that should be printed to @STDOUT before reading from @STDIN.
34
+ @return Line (@String@) read from @STDIN.
35
+
36
+ Prints a given message to @STDOUT, followed by reading a line from
37
+ @STDIN.
38
+ """
39
+
40
+ Console print: message
41
+ if: (STDIN eof?) then: {
42
+ nil
43
+ } else: {
44
+ STDIN gets() chomp
45
+ }
46
+ }
47
+
48
+ def Console readln {
49
+ """
50
+ @return Line (@String@) read from @STDIN.
51
+
52
+ Reads a line from @STDIN and returns it as a @String@.
53
+ """
54
+
55
+ STDIN gets() chomp
56
+ }
57
+
58
+ def Console clear {
59
+ "Clears the @Console@."
60
+
61
+ STDOUT print("\033[H\033[2J")
62
+ }
63
+ }
@@ -0,0 +1,46 @@
1
+ class Directory {
2
+ def self create: dirname {
3
+ """
4
+ @dirname Path of @Directory@ to create.
5
+
6
+ Creates a new @Directory@ on the filesystem, possibly throwing
7
+ IOError Exceptions that might occur.
8
+ """
9
+
10
+ try {
11
+ Dir mkdir(dirname)
12
+ } catch Errno::EEXIST => e {
13
+ IOError new: (e message) . raise!
14
+ }
15
+ }
16
+
17
+ def self create!: dirname {
18
+ """
19
+ @dirname Path of @Directory@ to create.
20
+
21
+ Creates a new @Directory@ on the filesystem, ignoring any
22
+ Exceptions that might occur.
23
+ Basically works like running `mkdir -p` on the shell.
24
+ """
25
+
26
+ try {
27
+ create: dirname
28
+ } catch IOError {
29
+ }
30
+ }
31
+
32
+
33
+ def self delete: dirname {
34
+ """
35
+ @dirname Path to @Directory@ to delete.
36
+
37
+ Deletes a directory with a given name, if it's empty.
38
+ """
39
+
40
+ try {
41
+ Dir delete(dirname)
42
+ } catch Exception => e {
43
+ IOError new: (e message) . raise!
44
+ }
45
+ }
46
+ }