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.
- data/AUTHORS +7 -0
- data/LICENSE +19 -0
- data/README +173 -0
- data/Rakefile +255 -0
- data/bin/fancy +40 -0
- data/bin/fdoc +23 -0
- data/bin/fyi +22 -0
- data/bin/ifancy +46 -0
- data/boot/README +12 -0
- data/boot/code_loader.rb +165 -0
- data/boot/compile.fy +3 -0
- data/boot/fancy_ext.rb +13 -0
- data/boot/fancy_ext/block_env.rb +29 -0
- data/boot/fancy_ext/class.rb +26 -0
- data/boot/fancy_ext/kernel.rb +12 -0
- data/boot/fancy_ext/module.rb +89 -0
- data/boot/fancy_ext/object.rb +34 -0
- data/boot/fancy_ext/string_helper.rb +10 -0
- data/boot/load.rb +72 -0
- data/boot/rbx-compiler/README +12 -0
- data/boot/rbx-compiler/compiler.rb +24 -0
- data/boot/rbx-compiler/compiler/ast.rb +23 -0
- data/boot/rbx-compiler/compiler/ast/README +11 -0
- data/boot/rbx-compiler/compiler/ast/array_literal.rb +13 -0
- data/boot/rbx-compiler/compiler/ast/assign.rb +57 -0
- data/boot/rbx-compiler/compiler/ast/block.rb +70 -0
- data/boot/rbx-compiler/compiler/ast/class_def.rb +35 -0
- data/boot/rbx-compiler/compiler/ast/expression_list.rb +57 -0
- data/boot/rbx-compiler/compiler/ast/hash_literal.rb +11 -0
- data/boot/rbx-compiler/compiler/ast/identifier.rb +120 -0
- data/boot/rbx-compiler/compiler/ast/match.rb +81 -0
- data/boot/rbx-compiler/compiler/ast/message_send.rb +71 -0
- data/boot/rbx-compiler/compiler/ast/method_def.rb +116 -0
- data/boot/rbx-compiler/compiler/ast/node.rb +6 -0
- data/boot/rbx-compiler/compiler/ast/range_literal.rb +22 -0
- data/boot/rbx-compiler/compiler/ast/require.rb +20 -0
- data/boot/rbx-compiler/compiler/ast/return.rb +29 -0
- data/boot/rbx-compiler/compiler/ast/ruby_args.rb +35 -0
- data/boot/rbx-compiler/compiler/ast/script.rb +56 -0
- data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +39 -0
- data/boot/rbx-compiler/compiler/ast/string_literal.rb +14 -0
- data/boot/rbx-compiler/compiler/ast/super.rb +25 -0
- data/boot/rbx-compiler/compiler/ast/try_catch_block.rb +220 -0
- data/boot/rbx-compiler/compiler/ast/tuple_literal.rb +33 -0
- data/boot/rbx-compiler/compiler/command.rb +39 -0
- data/boot/rbx-compiler/compiler/compiler.rb +83 -0
- data/boot/rbx-compiler/compiler/stages.rb +99 -0
- data/boot/rbx-compiler/parser.rb +2 -0
- data/boot/rbx-compiler/parser/README +15 -0
- data/boot/rbx-compiler/parser/Rakefile +54 -0
- data/boot/rbx-compiler/parser/extconf.rb +3 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/fancy_parser.c +46 -0
- data/boot/rbx-compiler/parser/fancy_parser.h +8 -0
- data/boot/rbx-compiler/parser/lexer.lex +180 -0
- data/boot/rbx-compiler/parser/parser.rb +356 -0
- data/boot/rbx-compiler/parser/parser.y +711 -0
- data/boot/rsexp_pretty_printer.rb +76 -0
- data/doc/api/fancy.css +93 -0
- data/doc/api/fancy.jsonp +1 -0
- data/doc/api/fdoc.js +187 -0
- data/doc/api/index.html +57 -0
- data/doc/api/underscore-min.js +18 -0
- data/doc/features.md +228 -0
- data/examples/argv.fy +8 -0
- data/examples/arithmetic.fy +7 -0
- data/examples/armstrong_numbers.fy +33 -0
- data/examples/array.fy +52 -0
- data/examples/blocks.fy +15 -0
- data/examples/boolean.fy +24 -0
- data/examples/call_with_receiver.fy +9 -0
- data/examples/class.fy +68 -0
- data/examples/closures.fy +24 -0
- data/examples/constant_access.fy +15 -0
- data/examples/default_args.fy +17 -0
- data/examples/define_methods.fy +15 -0
- data/examples/documentation.fy +57 -0
- data/examples/documentation_formatters.fy +25 -0
- data/examples/echo.fy +16 -0
- data/examples/empty_catch.fy +4 -0
- data/examples/exception.fy +9 -0
- data/examples/factorial.fy +12 -0
- data/examples/fibonacci.fy +16 -0
- data/examples/files.fy +23 -0
- data/examples/finally.fy +5 -0
- data/examples/game_of_life.fy +148 -0
- data/examples/hashes.fy +7 -0
- data/examples/hello_world.fy +6 -0
- data/examples/html_generator.fy +54 -0
- data/examples/implicit_return.fy +3 -0
- data/examples/matchers.fy +6 -0
- data/examples/methods.fy +29 -0
- data/examples/nested_classes.fy +27 -0
- data/examples/nested_try.fy +9 -0
- data/examples/numbers.fy +12 -0
- data/examples/pattern_matching.fy +40 -0
- data/examples/person.fy +65 -0
- data/examples/project-euler/01.fy +8 -0
- data/examples/project-euler/02.fy +21 -0
- data/examples/project-euler/28.fy +33 -0
- data/examples/rbx/and_or.fy +7 -0
- data/examples/rbx/blocks.fy +22 -0
- data/examples/rbx/classes.fy +32 -0
- data/examples/rbx/hello.fy +8 -0
- data/examples/rbx/include.fy +12 -0
- data/examples/rbx/inherit.fy +11 -0
- data/examples/rbx/methods.fy +15 -0
- data/examples/rbx/nested_classes.fy +9 -0
- data/examples/rbx/require.fy +3 -0
- data/examples/rbx/strings.fy +5 -0
- data/examples/regex.fy +7 -0
- data/examples/require.fy +7 -0
- data/examples/retry.fy +12 -0
- data/examples/return.fy +13 -0
- data/examples/ruby_require.fy +7 -0
- data/examples/ruby_send.fy +3 -0
- data/examples/singleton_methods.fy +21 -0
- data/examples/stupid_quicksort.fy +12 -0
- data/examples/threads.fy +18 -0
- data/examples/tuple.fy +8 -0
- data/examples/webserver/webserver.fy +18 -0
- data/lib/argv.fy +36 -0
- data/lib/array.fy +207 -0
- data/lib/block.fy +88 -0
- data/lib/boot.fy +41 -0
- data/lib/class.fy +106 -0
- data/lib/compiler.fy +14 -0
- data/lib/compiler/ast.fy +40 -0
- data/lib/compiler/ast/assign.fy +96 -0
- data/lib/compiler/ast/block.fy +84 -0
- data/lib/compiler/ast/class_def.fy +33 -0
- data/lib/compiler/ast/expression_list.fy +47 -0
- data/lib/compiler/ast/identifier.fy +113 -0
- data/lib/compiler/ast/literals.fy +122 -0
- data/lib/compiler/ast/match.fy +88 -0
- data/lib/compiler/ast/message_send.fy +110 -0
- data/lib/compiler/ast/method_def.fy +90 -0
- data/lib/compiler/ast/node.fy +7 -0
- data/lib/compiler/ast/range.fy +16 -0
- data/lib/compiler/ast/require.fy +15 -0
- data/lib/compiler/ast/return.fy +23 -0
- data/lib/compiler/ast/script.fy +52 -0
- data/lib/compiler/ast/singleton_method_def.fy +35 -0
- data/lib/compiler/ast/super.fy +17 -0
- data/lib/compiler/ast/try_catch.fy +176 -0
- data/lib/compiler/ast/tuple_literal.fy +34 -0
- data/lib/compiler/command.fy +51 -0
- data/lib/compiler/compiler.fy +73 -0
- data/lib/compiler/stages.fy +81 -0
- data/lib/directory.fy +17 -0
- data/lib/documentation.fy +115 -0
- data/lib/enumerable.fy +269 -0
- data/lib/eval.fy +31 -0
- data/lib/fancy_spec.fy +202 -0
- data/lib/fdoc.fy +359 -0
- data/lib/fdoc_hook.fy +10 -0
- data/lib/file.fy +54 -0
- data/lib/hash.fy +56 -0
- data/lib/main.fy +80 -0
- data/lib/method.fy +22 -0
- data/lib/nil_class.fy +56 -0
- data/lib/number.fy +87 -0
- data/lib/object.fy +170 -0
- data/lib/package.fy +61 -0
- data/lib/package/dependency.fy +24 -0
- data/lib/package/installer.fy +180 -0
- data/lib/package/specification.fy +55 -0
- data/lib/package/uninstaller.fy +15 -0
- data/lib/parser.fy +4 -0
- data/lib/parser/ext/README +15 -0
- data/lib/parser/ext/ext.c +42 -0
- data/lib/parser/ext/ext.h +8 -0
- data/lib/parser/ext/extconf.rb +3 -0
- data/lib/parser/ext/lexer.lex +187 -0
- data/lib/parser/ext/parser.y +744 -0
- data/lib/parser/methods.fy +297 -0
- data/lib/rbx.fy +37 -0
- data/lib/rbx/array.fy +237 -0
- data/lib/rbx/bignum.fy +23 -0
- data/lib/rbx/block.fy +9 -0
- data/lib/rbx/class.fy +129 -0
- data/lib/rbx/code_loader.fy +192 -0
- data/lib/rbx/console.fy +63 -0
- data/lib/rbx/directory.fy +46 -0
- data/lib/rbx/documentation.fy +64 -0
- data/lib/rbx/environment_variables.fy +3 -0
- data/lib/rbx/exception.fy +30 -0
- data/lib/rbx/false_class.fy +58 -0
- data/lib/rbx/fiber.fy +25 -0
- data/lib/rbx/file.fy +191 -0
- data/lib/rbx/fixnum.fy +25 -0
- data/lib/rbx/float.fy +14 -0
- data/lib/rbx/hash.fy +38 -0
- data/lib/rbx/integer.fy +15 -0
- data/lib/rbx/io.fy +30 -0
- data/lib/rbx/match_data.fy +9 -0
- data/lib/rbx/method.fy +22 -0
- data/lib/rbx/name_error.fy +3 -0
- data/lib/rbx/no_method_error.fy +15 -0
- data/lib/rbx/object.fy +117 -0
- data/lib/rbx/range.fy +15 -0
- data/lib/rbx/regexp.fy +9 -0
- data/lib/rbx/string.fy +63 -0
- data/lib/rbx/symbol.fy +12 -0
- data/lib/rbx/system.fy +37 -0
- data/lib/rbx/tcp_server.fy +6 -0
- data/lib/rbx/tcp_socket.fy +7 -0
- data/lib/rbx/thread.fy +75 -0
- data/lib/rbx/tuple.fy +37 -0
- data/lib/set.fy +61 -0
- data/lib/stack.fy +51 -0
- data/lib/string.fy +58 -0
- data/lib/struct.fy +13 -0
- data/lib/symbol.fy +23 -0
- data/lib/true_class.fy +43 -0
- data/lib/tuple.fy +68 -0
- data/lib/version.fy +6 -0
- data/tests/argv.fy +13 -0
- data/tests/array.fy +343 -0
- data/tests/assignment.fy +53 -0
- data/tests/block.fy +103 -0
- data/tests/class.fy +409 -0
- data/tests/control_flow.fy +79 -0
- data/tests/documentation.fy +24 -0
- data/tests/exception.fy +115 -0
- data/tests/file.fy +86 -0
- data/tests/hash.fy +101 -0
- data/tests/method.fy +131 -0
- data/tests/nil_class.fy +55 -0
- data/tests/number.fy +128 -0
- data/tests/object.fy +125 -0
- data/tests/parsing/sexp.fy +50 -0
- data/tests/pattern_matching.fy +82 -0
- data/tests/range.fy +11 -0
- data/tests/set.fy +10 -0
- data/tests/stack.fy +22 -0
- data/tests/string.fy +102 -0
- data/tests/symbol.fy +17 -0
- data/tests/true_class.fy +63 -0
- data/tests/tuple.fy +21 -0
- data/tools/fancy-mode.el +63 -0
- metadata +321 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
class Fancy
|
2
|
+
class AST
|
3
|
+
|
4
|
+
class RubyArgs < Node
|
5
|
+
def initialize(line, args, block = nil)
|
6
|
+
super(line)
|
7
|
+
@args = args
|
8
|
+
# If no block given and last arg is a block identifier
|
9
|
+
if block.nil? &&
|
10
|
+
args.array.last.kind_of?(Fancy::AST::Identifier) &&
|
11
|
+
args.array.last.identifier =~ /^&\w/
|
12
|
+
block = args.array.pop
|
13
|
+
block = Fancy::AST::Identifier.new(block.line, block.identifier[1..-1])
|
14
|
+
end
|
15
|
+
@block = block
|
16
|
+
end
|
17
|
+
|
18
|
+
def bytecode(g)
|
19
|
+
@args.array.each do |a|
|
20
|
+
a.bytecode(g)
|
21
|
+
end
|
22
|
+
@block.bytecode(g) if @block
|
23
|
+
end
|
24
|
+
|
25
|
+
def size
|
26
|
+
@args.array.size
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_block?
|
30
|
+
not @block.nil?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class Fancy
|
2
|
+
class AST
|
3
|
+
|
4
|
+
class Script < Node
|
5
|
+
attr_reader :body, :filename
|
6
|
+
|
7
|
+
@@stack = []
|
8
|
+
|
9
|
+
def push_script
|
10
|
+
@@stack.push self
|
11
|
+
end
|
12
|
+
|
13
|
+
def pop_script
|
14
|
+
@@stack.pop
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.current
|
18
|
+
@@stack.last
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(line, filename, body)
|
22
|
+
super(line)
|
23
|
+
@filename = filename
|
24
|
+
@body = body
|
25
|
+
end
|
26
|
+
|
27
|
+
def bytecode(g)
|
28
|
+
begin
|
29
|
+
push_script
|
30
|
+
|
31
|
+
#docs, code = body.expressions.partition do |s|
|
32
|
+
# s.kind_of?(Rubinius::AST::StringLiteral)
|
33
|
+
#end
|
34
|
+
|
35
|
+
#if code.empty?
|
36
|
+
# only literal string found, we have to evaluate to it, not
|
37
|
+
# use as documentation.
|
38
|
+
# docs, code = [], docs
|
39
|
+
#end
|
40
|
+
|
41
|
+
#code.each { |c| c.bytecode(g) }
|
42
|
+
@body.bytecode(g)
|
43
|
+
|
44
|
+
# the docs array has top-level expressions that are
|
45
|
+
# simply string literals, we can use them for file-level
|
46
|
+
# documentation.
|
47
|
+
# TODO: implement file documentation here.
|
48
|
+
ensure
|
49
|
+
pop_script
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Fancy
|
2
|
+
class AST
|
3
|
+
|
4
|
+
class SingletonMethodDef < Rubinius::AST::DefineSingleton
|
5
|
+
def initialize(line, obj_ident, method_ident, args, body, access = :public)
|
6
|
+
@line = line
|
7
|
+
@receiver = obj_ident
|
8
|
+
@name = method_ident.method_name(@receiver)
|
9
|
+
@arguments = args
|
10
|
+
@body = SingletonMethodDefScope.new line, @name, args, body
|
11
|
+
@access = access
|
12
|
+
end
|
13
|
+
|
14
|
+
def bytecode(g)
|
15
|
+
g.push_self
|
16
|
+
g.send @access, 0
|
17
|
+
g.pop
|
18
|
+
super(g)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class SingletonMethodDefScope < Rubinius::AST::DefineSingletonScope
|
23
|
+
def initialize(line, name, args, body)
|
24
|
+
@line = line
|
25
|
+
@name = name
|
26
|
+
@arguments = args
|
27
|
+
@body = body
|
28
|
+
end
|
29
|
+
|
30
|
+
def bytecode(g, recv)
|
31
|
+
#docstring = @body.shift_docstring
|
32
|
+
super(g, recv)
|
33
|
+
#MethodDef.set_docstring(g, docstring, @line, @arguments.names)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Fancy
|
2
|
+
class AST
|
3
|
+
class StringLiteral < Rubinius::AST::StringLiteral
|
4
|
+
def initialize(line, str)
|
5
|
+
super(line, unescape_chars(str))
|
6
|
+
end
|
7
|
+
|
8
|
+
def unescape_chars(str)
|
9
|
+
str.gsub("\\r", "\r").gsub("\\t", "\t").gsub("\\n", "\n").gsub("\\v", "\v").gsub("\\b", "\b").
|
10
|
+
gsub("\\f", "\f").gsub("\\a", "\a").gsub("\\\\", "\\").gsub("\\?", "\?").gsub("\\'", "\'").gsub('\\"', '\"').gsub("\\\"", "\"")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Fancy
|
2
|
+
class AST
|
3
|
+
|
4
|
+
class Super < Node
|
5
|
+
def initialize(line)
|
6
|
+
super(line)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class SuperSend < Node
|
11
|
+
def initialize(line, method_name, args)
|
12
|
+
super(line)
|
13
|
+
@method_name = method_name.name.to_sym
|
14
|
+
@args = args
|
15
|
+
end
|
16
|
+
|
17
|
+
def bytecode(g)
|
18
|
+
pos(g)
|
19
|
+
@args.bytecode(g)
|
20
|
+
g.send_super @method_name, @args.size
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
class Fancy
|
2
|
+
class AST
|
3
|
+
|
4
|
+
class TryCatchBlock < Node
|
5
|
+
def initialize(line, body, handlers, finally)
|
6
|
+
super(line)
|
7
|
+
@body = body
|
8
|
+
@handlers = handlers
|
9
|
+
@finally = finally || Rubinius::AST::NilLiteral.new(line)
|
10
|
+
end
|
11
|
+
|
12
|
+
def bytecode(g)
|
13
|
+
pos(g)
|
14
|
+
|
15
|
+
g.push_modifiers
|
16
|
+
|
17
|
+
outer_retry = g.new_label
|
18
|
+
this_retry = g.new_label
|
19
|
+
reraise = g.new_label
|
20
|
+
|
21
|
+
# save the current exception into a stack local
|
22
|
+
g.push_exception_state
|
23
|
+
outer_ex = g.new_stack_local
|
24
|
+
g.set_stack_local outer_ex
|
25
|
+
g.pop
|
26
|
+
|
27
|
+
# retry label for re-entering the try body
|
28
|
+
this_retry.set!
|
29
|
+
|
30
|
+
handler = g.new_label
|
31
|
+
finally = g.new_label
|
32
|
+
done = g.new_label
|
33
|
+
|
34
|
+
g.setup_unwind handler, Rubinius::AST::RescueType
|
35
|
+
|
36
|
+
# make a break available to use
|
37
|
+
if current_break = g.break
|
38
|
+
g.break = g.new_label
|
39
|
+
end
|
40
|
+
|
41
|
+
# use lazy label to patch up prematuraly leaving a try body
|
42
|
+
# via retry
|
43
|
+
if outer_retry
|
44
|
+
g.retry = g.new_label
|
45
|
+
end
|
46
|
+
|
47
|
+
# also handle redo unwinding through the rescue
|
48
|
+
if current_redo = g.redo
|
49
|
+
g.redo = g.new_label
|
50
|
+
end
|
51
|
+
|
52
|
+
@body.bytecode(g)
|
53
|
+
|
54
|
+
g.pop_unwind
|
55
|
+
g.pop
|
56
|
+
g.goto finally
|
57
|
+
|
58
|
+
|
59
|
+
if current_break
|
60
|
+
if g.break.used?
|
61
|
+
g.break.set!
|
62
|
+
g.pop_unwind
|
63
|
+
|
64
|
+
# Reset the outer exception
|
65
|
+
g.push_stack_local outer_ex
|
66
|
+
g.restore_exception_state
|
67
|
+
|
68
|
+
g.goto current_break
|
69
|
+
end
|
70
|
+
|
71
|
+
g.break = current_break
|
72
|
+
end
|
73
|
+
|
74
|
+
if current_redo
|
75
|
+
if g.redo.used?
|
76
|
+
g.redo.set!
|
77
|
+
g.pop_unwind
|
78
|
+
|
79
|
+
# Reset the outer exception
|
80
|
+
g.push_stack_local outer_ex
|
81
|
+
g.restore_exception_state
|
82
|
+
|
83
|
+
g.goto current_redo
|
84
|
+
end
|
85
|
+
|
86
|
+
g.redo = current_redo
|
87
|
+
end
|
88
|
+
|
89
|
+
if outer_retry
|
90
|
+
if g.retry.used?
|
91
|
+
g.retry.set!
|
92
|
+
g.pop_unwind
|
93
|
+
|
94
|
+
# Reset the outer exception
|
95
|
+
g.push_stack_local outer_ex
|
96
|
+
g.restore_exception_state
|
97
|
+
|
98
|
+
g.goto outer_retry
|
99
|
+
end
|
100
|
+
|
101
|
+
g.retry = outer_retry
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# We jump here if an exception has occurred in the body
|
106
|
+
handler.set!
|
107
|
+
|
108
|
+
# Expose the retry label here only, not before this
|
109
|
+
g.retry = this_retry
|
110
|
+
|
111
|
+
# Save exception state to use in reraise
|
112
|
+
g.push_exception_state
|
113
|
+
|
114
|
+
raised_exc_state = g.new_stack_local
|
115
|
+
g.set_stack_local raised_exc_state
|
116
|
+
g.pop
|
117
|
+
|
118
|
+
# Save the current exception, so that calling #=== can't trample
|
119
|
+
# it.
|
120
|
+
g.push_current_exception
|
121
|
+
|
122
|
+
@handlers.bytecode(g, finally)
|
123
|
+
|
124
|
+
reraise.set!
|
125
|
+
# Execute the finally block before propagating the exception
|
126
|
+
@finally.bytecode(g)
|
127
|
+
|
128
|
+
# remove the exception so we have the state
|
129
|
+
g.pop
|
130
|
+
# restore the state and reraise
|
131
|
+
g.push_stack_local raised_exc_state
|
132
|
+
g.restore_exception_state
|
133
|
+
g.reraise
|
134
|
+
|
135
|
+
finally.set!
|
136
|
+
@finally.bytecode(g)
|
137
|
+
|
138
|
+
done.set!
|
139
|
+
|
140
|
+
g.push_stack_local outer_ex
|
141
|
+
g.restore_exception_state
|
142
|
+
g.pop_modifiers
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
class ExceptHandler < Node
|
148
|
+
def initialize(line, condition, var, body)
|
149
|
+
super(line)
|
150
|
+
@condition = condition
|
151
|
+
@var = var
|
152
|
+
@body = body
|
153
|
+
end
|
154
|
+
|
155
|
+
def bytecode(g, finally)
|
156
|
+
nothing = g.new_label
|
157
|
+
|
158
|
+
@condition.bytecode(g)
|
159
|
+
g.push_current_exception
|
160
|
+
g.send :===, 1
|
161
|
+
g.gif nothing
|
162
|
+
|
163
|
+
if @var
|
164
|
+
Fancy::AST::Assignment.new(line, @var, CurrentException.new(line)).bytecode(g)
|
165
|
+
g.pop
|
166
|
+
end
|
167
|
+
|
168
|
+
@body.bytecode(g)
|
169
|
+
g.pop unless @body.empty?
|
170
|
+
|
171
|
+
g.clear_exception
|
172
|
+
g.pop
|
173
|
+
|
174
|
+
g.goto finally
|
175
|
+
nothing.set!
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
class CurrentException < Node
|
181
|
+
def initialize(line)
|
182
|
+
super(line)
|
183
|
+
end
|
184
|
+
|
185
|
+
def bytecode(g)
|
186
|
+
g.push_current_exception
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
class Handlers < Node
|
191
|
+
def initialize(line, *handlers)
|
192
|
+
super(line)
|
193
|
+
@handlers = handlers
|
194
|
+
end
|
195
|
+
|
196
|
+
def bytecode(g, finally)
|
197
|
+
@handlers.each do |handler|
|
198
|
+
handler.bytecode(g, finally)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def add_handler(handler)
|
203
|
+
@handlers.push(handler)
|
204
|
+
self
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
class Retry < Node
|
209
|
+
def initialize(line)
|
210
|
+
super(line)
|
211
|
+
end
|
212
|
+
|
213
|
+
def bytecode(g)
|
214
|
+
g.pop
|
215
|
+
g.goto g.retry
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Fancy
|
2
|
+
class AST
|
3
|
+
|
4
|
+
class TupleLiteral < Node
|
5
|
+
attr_accessor :elements
|
6
|
+
def initialize(line, *elements)
|
7
|
+
super(line)
|
8
|
+
@elements = elements
|
9
|
+
end
|
10
|
+
|
11
|
+
def bytecode(g)
|
12
|
+
ms = MessageSend.new(@line,
|
13
|
+
Identifier.new(@line, "Rubinius::Tuple"),
|
14
|
+
Identifier.new(@line, "new"),
|
15
|
+
MessageArgs.new(@line,
|
16
|
+
RubyArgs.new(@line,
|
17
|
+
ArrayLiteral.new(@line, Rubinius::AST::FixnumLiteral.new(@line, @elements.size)))))
|
18
|
+
ms.bytecode(g)
|
19
|
+
@elements.each_with_index do |e, i|
|
20
|
+
g.dup
|
21
|
+
MessageSend.new(@line,
|
22
|
+
Nothing.new,
|
23
|
+
Identifier.new(@line, "at:put:"),
|
24
|
+
MessageArgs.new(@line,
|
25
|
+
Rubinius::AST::FixnumLiteral.new(@line, i),
|
26
|
+
e)).bytecode(g)
|
27
|
+
g.pop
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
class Fancy
|
4
|
+
class Compiler
|
5
|
+
class Command
|
6
|
+
def self.option_flag(argv, name)
|
7
|
+
argv.delete name
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.option_value(argv, name)
|
11
|
+
if idx = argv.index(name)
|
12
|
+
value = argv.delete_at(idx + 1)
|
13
|
+
argv.delete_at(idx)
|
14
|
+
value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.run(argv)
|
19
|
+
batch = option_flag(argv, "--batch")
|
20
|
+
print = option_flag(argv, "-B")
|
21
|
+
src_path = option_value(argv, "--source-path")
|
22
|
+
out_path = option_value(argv, "--output-path")
|
23
|
+
argv.each do |f|
|
24
|
+
out = nil
|
25
|
+
if out_path && src_path
|
26
|
+
out = f.sub(src_path, out_path) + "c"
|
27
|
+
end
|
28
|
+
compile(f, out, batch, print)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.compile(file, out = nil, info_output = false, print = false)
|
33
|
+
puts "Compiling #{file}" if info_output
|
34
|
+
FileUtils.mkdir_p(File.dirname(out)) if out
|
35
|
+
Compiler.compile_fancy_file file, out, 1, print
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|