mirah 0.0.12-java → 0.1.0-java
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/History.txt +372 -0
- data/README.txt +4 -5
- data/Rakefile +178 -55
- data/examples/appengine/Readme +3 -3
- data/examples/appengine/src/org/mirah/MirahApp.mirah +1 -1
- data/examples/appengine/src/org/mirah/list.dhtml +1 -1
- data/examples/bintrees.mirah +1 -1
- data/examples/edb.mirah +1 -1
- data/examples/fib.mirah +1 -1
- data/examples/interfaces.mirah +1 -1
- data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +4 -5
- data/examples/maven/README.txt +1 -1
- data/examples/maven/src/main/mirah/hello_mirah.mirah +1 -1
- data/examples/plugins/appengine/Rakefile +1 -1
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/MetaModel.mirah +1 -1
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +1 -1
- data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +1 -1
- data/examples/rosettacode/100-doors.mirah +6 -6
- data/examples/rosettacode/README.txt +3 -3
- data/examples/rosettacode/boolean-values.mirah +1 -1
- data/examples/rosettacode/comments.mirah +1 -1
- data/examples/rosettacode/count-occurrences-of-a-substring.mirah +1 -1
- data/examples/rosettacode/factorial.mirah +1 -1
- data/examples/rosettacode/fibonacci.mirah +1 -1
- data/examples/rosettacode/fizz-buzz.mirah +2 -2
- data/examples/rosettacode/flatten-a-list.mirah +4 -4
- data/examples/rosettacode/guess-the-number.mirah +2 -2
- data/examples/rosettacode/hamming-numbers.mirah +4 -4
- data/examples/rosettacode/is-string-numeric.mirah +22 -22
- data/examples/rosettacode/palindrome.mirah +2 -2
- data/examples/rosettacode/random-numbers.mirah +1 -1
- data/examples/rosettacode/repeat-a-string.mirah +1 -1
- data/examples/rosettacode/reverse-a-string.mirah +1 -1
- data/examples/rosettacode/rot-13.mirah +5 -5
- data/examples/rosettacode/secure-temporary-file.mirah +2 -2
- data/examples/rosettacode/sleep.mirah +1 -1
- data/examples/rosettacode/string-length.mirah +5 -5
- data/examples/swing.mirah +1 -1
- data/examples/test.edb +1 -1
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-builtins.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/javalib/mirah-util.jar +0 -0
- data/lib/duby.rb +1 -1
- data/lib/mirah.rb +50 -28
- data/lib/mirah/ast.rb +15 -605
- data/lib/mirah/ast/scope.rb +98 -69
- data/lib/mirah/commands.rb +1 -1
- data/lib/mirah/commands/base.rb +7 -7
- data/lib/mirah/commands/compile.rb +3 -3
- data/lib/mirah/commands/parse.rb +7 -5
- data/lib/mirah/commands/run.rb +12 -19
- data/lib/mirah/compiler.rb +15 -23
- data/lib/mirah/errors.rb +16 -1
- data/lib/mirah/generator.rb +79 -39
- data/lib/mirah/jvm/compiler.rb +1 -19
- data/lib/mirah/jvm/compiler/base.rb +233 -90
- data/lib/mirah/jvm/compiler/jvm_bytecode.rb +675 -363
- data/lib/mirah/jvm/method_lookup.rb +134 -65
- data/lib/mirah/jvm/typer.rb +10 -5
- data/lib/mirah/jvm/types.rb +10 -2
- data/lib/mirah/jvm/types/array_type.rb +10 -12
- data/lib/mirah/{compiler/type.rb → jvm/types/ast_ext.rb} +12 -8
- data/lib/mirah/jvm/types/basic_types.rb +26 -33
- data/lib/mirah/jvm/types/bitescript_ext.rb +1 -1
- data/lib/mirah/jvm/types/block_type.rb +15 -0
- data/lib/mirah/jvm/types/boolean.rb +8 -4
- data/lib/mirah/jvm/types/dynamic_type.rb +12 -13
- data/lib/mirah/jvm/types/enumerable.rb +7 -7
- data/lib/mirah/jvm/types/extensions.rb +11 -6
- data/lib/mirah/jvm/types/factory.rb +624 -94
- data/lib/mirah/jvm/types/floats.rb +21 -15
- data/lib/mirah/jvm/types/generic_type.rb +72 -0
- data/lib/mirah/jvm/types/implicit_nil_type.rb +29 -0
- data/lib/mirah/jvm/types/integers.rb +26 -71
- data/lib/mirah/jvm/types/interface_definition.rb +3 -3
- data/lib/mirah/jvm/types/intrinsics.rb +203 -168
- data/lib/mirah/jvm/types/literals.rb +6 -6
- data/lib/mirah/jvm/types/meta_type.rb +13 -4
- data/lib/mirah/jvm/types/methods.rb +281 -93
- data/lib/mirah/jvm/types/null_type.rb +17 -5
- data/lib/mirah/jvm/types/number.rb +10 -7
- data/lib/mirah/jvm/types/primitive_type.rb +17 -6
- data/lib/mirah/jvm/types/source_mirror.rb +12 -7
- data/lib/mirah/jvm/types/type.rb +107 -23
- data/lib/mirah/jvm/types/type_definition.rb +25 -10
- data/lib/mirah/jvm/types/unreachable_type.rb +1 -1
- data/lib/mirah/jvm/types/void_type.rb +3 -3
- data/lib/mirah/parser.rb +154 -16
- data/lib/mirah/plugin/edb.rb +1 -1
- data/lib/mirah/transform.rb +1 -2
- data/lib/mirah/transform/ast_ext.rb +24 -43
- data/lib/mirah/transform/transformer.rb +29 -224
- data/lib/mirah/typer.rb +2 -16
- data/lib/mirah/util/argument_processor.rb +25 -10
- data/lib/mirah/util/class_loader.rb +1 -1
- data/lib/mirah/util/compilation_state.rb +16 -17
- data/lib/mirah/util/delegate.rb +2 -2
- data/lib/mirah/util/logging.rb +110 -0
- data/lib/mirah/util/process_errors.rb +69 -11
- data/lib/mirah/version.rb +1 -1
- data/test/core/commands_test.rb +6 -24
- data/test/core/env_test.rb +5 -5
- data/{lib/mirah/jvm/source_generator/typer.rb → test/core/generator_test.rb} +9 -9
- data/test/core/typer_test.rb +196 -158
- data/test/core/util/argument_processor_test.rb +10 -10
- data/test/core/util/class_loader_test.rb +6 -5
- data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
- data/test/jvm/annotations_test.rb +5 -5
- data/test/jvm/blocks_test.rb +140 -88
- data/test/jvm/bytecode_test_helper.rb +112 -94
- data/test/jvm/cast_test.rb +162 -0
- data/test/jvm/constructors_test.rb +18 -8
- data/test/jvm/enumerable_test.rb +77 -44
- data/test/jvm/example_test.rb +53 -0
- data/test/jvm/factory_test.rb +7 -1
- data/test/jvm/generics_test.rb +57 -0
- data/test/jvm/hash_test.rb +106 -0
- data/test/jvm/import_test.rb +81 -0
- data/test/jvm/interface_test.rb +73 -0
- data/test/jvm/java_typer_test.rb +92 -66
- data/{lib/mirah/typer/base.rb → test/jvm/jvm_commands_test.rb} +6 -10
- data/test/jvm/jvm_compiler_test.rb +170 -604
- data/test/jvm/list_extensions_test.rb +23 -0
- data/test/jvm/macros_test.rb +197 -32
- data/test/jvm/main_method_test.rb +4 -4
- data/test/jvm/numeric_extensions_test.rb +13 -0
- data/test/jvm/rescue_test.rb +73 -16
- data/test/jvm/varargs_test.rb +65 -0
- data/test/test_helper.rb +1 -2
- metadata +234 -251
- data/examples/SortClosure$__xform_tmp_1.class +0 -0
- data/examples/SortClosure$__xform_tmp_2.class +0 -0
- data/examples/SortClosure.class +0 -0
- data/examples/macros/StringEachChar$Extension1.class +0 -0
- data/lib/mirah/ast/call.rb +0 -345
- data/lib/mirah/ast/class.rb +0 -359
- data/lib/mirah/ast/flow.rb +0 -381
- data/lib/mirah/ast/intrinsics.rb +0 -563
- data/lib/mirah/ast/literal.rb +0 -178
- data/lib/mirah/ast/local.rb +0 -112
- data/lib/mirah/ast/method.rb +0 -408
- data/lib/mirah/ast/structure.rb +0 -387
- data/lib/mirah/ast/type.rb +0 -146
- data/lib/mirah/commands/base.rb~ +0 -57
- data/lib/mirah/compiler/call.rb +0 -45
- data/lib/mirah/compiler/class.rb +0 -81
- data/lib/mirah/compiler/flow.rb +0 -109
- data/lib/mirah/compiler/literal.rb +0 -130
- data/lib/mirah/compiler/local.rb +0 -59
- data/lib/mirah/compiler/method.rb +0 -44
- data/lib/mirah/compiler/structure.rb +0 -65
- data/lib/mirah/jvm/compiler/java_source.rb +0 -787
- data/lib/mirah/jvm/method_lookup.rb~ +0 -247
- data/lib/mirah/jvm/source_generator/builder.rb +0 -468
- data/lib/mirah/jvm/source_generator/loops.rb +0 -131
- data/lib/mirah/jvm/source_generator/precompile.rb +0 -210
- data/lib/mirah/plugin/gwt.rb +0 -189
- data/lib/mirah/plugin/java.rb +0 -70
- data/lib/mirah/transform/error.rb +0 -13
- data/lib/mirah/transform/helper.rb +0 -765
- data/lib/mirah/typer/simple.rb +0 -384
- data/lib/mirah/version.rb~ +0 -18
- data/test/core/ast_test.rb +0 -382
- data/test/core/compilation_test.rb +0 -130
- data/test/core/macros_test.rb +0 -61
- data/test/jvm/javac_test_helper.rb +0 -89
- data/test/jvm/jvm_compiler_test.rb~ +0 -2181
- data/test/plugins/gwt_test.rb +0 -69
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
|
|
16
|
-
module Mirah
|
|
17
|
-
module AST
|
|
18
|
-
class Arguments
|
|
19
|
-
def compile(compiler, expression)
|
|
20
|
-
# TODO: what does it mean for a method to be an expression?
|
|
21
|
-
args.each {|arg| compiler.declare_argument(arg.name, arg.inferred_type)} if args
|
|
22
|
-
rescue Exception => ex
|
|
23
|
-
raise Mirah::InternalCompilerError.wrap(ex, self)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
class MethodDefinition
|
|
28
|
-
def compile(compiler, expression)
|
|
29
|
-
# TODO: what does it mean for a method to be an expression?
|
|
30
|
-
compiler.define_method(self)
|
|
31
|
-
rescue Exception => ex
|
|
32
|
-
raise Mirah::InternalCompilerError.wrap(ex, self)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
class ConstructorDefinition
|
|
37
|
-
def compile(compiler, expression)
|
|
38
|
-
compiler.constructor(self)
|
|
39
|
-
rescue Exception => ex
|
|
40
|
-
raise Mirah::InternalCompilerError.wrap(ex, self)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
|
|
16
|
-
module Mirah
|
|
17
|
-
module AST
|
|
18
|
-
class Body
|
|
19
|
-
def compile(compiler, expression)
|
|
20
|
-
compiler.line(line_number)
|
|
21
|
-
compiler.body(self, expression)
|
|
22
|
-
rescue Exception => ex
|
|
23
|
-
raise Mirah::InternalCompilerError.wrap(ex, self)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
class ScopedBody
|
|
28
|
-
def compile(compiler, expression)
|
|
29
|
-
compiler.line(line_number)
|
|
30
|
-
compiler.scoped_body(self, expression)
|
|
31
|
-
rescue Exception => ex
|
|
32
|
-
raise Mirah::InternalCompilerError.wrap(ex, self)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
class BindingReference
|
|
37
|
-
def compile(compiler, expression)
|
|
38
|
-
if expression
|
|
39
|
-
compiler.line(line_number)
|
|
40
|
-
compiler.binding_reference
|
|
41
|
-
end
|
|
42
|
-
rescue Exception => ex
|
|
43
|
-
raise Mirah::InternalCompilerError.wrap(ex, self)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
class Script
|
|
48
|
-
def compile(compiler, expression)
|
|
49
|
-
# TODO: what does it mean for a script to be an expression? possible?
|
|
50
|
-
compiler.define_main(self)
|
|
51
|
-
rescue Exception => ex
|
|
52
|
-
raise Mirah::InternalCompilerError.wrap(ex, self)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
class Noop
|
|
57
|
-
def compile(compiler, expression)
|
|
58
|
-
# TODO: what does it mean for a noop to be an expression
|
|
59
|
-
# nothing
|
|
60
|
-
rescue Exception => ex
|
|
61
|
-
raise Mirah::InternalCompilerError.wrap(ex, self)
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
@@ -1,787 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
|
|
16
|
-
require 'mirah'
|
|
17
|
-
require 'mirah/ast'
|
|
18
|
-
require 'mirah/jvm/types'
|
|
19
|
-
require 'mirah/jvm/compiler'
|
|
20
|
-
require 'mirah/jvm/source_generator/builder'
|
|
21
|
-
require 'mirah/jvm/source_generator/precompile'
|
|
22
|
-
require 'mirah/jvm/source_generator/loops'
|
|
23
|
-
|
|
24
|
-
class String
|
|
25
|
-
def compile(compiler, expression)
|
|
26
|
-
compiler.method.print self if expression
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
module Mirah
|
|
31
|
-
module JVM
|
|
32
|
-
module Compiler
|
|
33
|
-
class JavaSource < Base
|
|
34
|
-
JVMTypes = Mirah::JVM::Types
|
|
35
|
-
attr_accessor :lvalue
|
|
36
|
-
|
|
37
|
-
Operators = [
|
|
38
|
-
'+', '-', '+@', '-@', '/', '%', '*', '<',
|
|
39
|
-
'<=', '==', '!=', '>=', '>',
|
|
40
|
-
'<<', '>>', '>>>', '|', '&', '^', '~'
|
|
41
|
-
]
|
|
42
|
-
ArrayOps = [
|
|
43
|
-
'[]', '[]=', 'length'
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
ImplicitReturn = Struct.new(:value)
|
|
47
|
-
|
|
48
|
-
def initialize
|
|
49
|
-
super
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def file_builder(filename)
|
|
53
|
-
Mirah::JavaSource::Builder.new(filename, self)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def output_type
|
|
57
|
-
"source files"
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def define_class(class_def, expression)
|
|
61
|
-
with(:type => class_def.inferred_type,
|
|
62
|
-
:class => class_def.inferred_type.define(@file),
|
|
63
|
-
:static => false) do
|
|
64
|
-
annotate(@class, class_def.annotations)
|
|
65
|
-
class_def.body.compile(self, false) if class_def.body
|
|
66
|
-
@class.stop unless @method && @method.name == 'main' && @class == @method.klass
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def define_method(node)
|
|
71
|
-
base_define_method(node, false) do |method, _|
|
|
72
|
-
with :method => method do
|
|
73
|
-
log "Starting new method #{node.name}"
|
|
74
|
-
@method.start
|
|
75
|
-
|
|
76
|
-
prepare_binding(node) do
|
|
77
|
-
declare_locals(node.static_scope)
|
|
78
|
-
unless method.returns_void?
|
|
79
|
-
self.return(ImplicitReturn.new(node.body))
|
|
80
|
-
else
|
|
81
|
-
node.body.compile(self, false) if node.body
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
log "Method #{node.name} complete!"
|
|
86
|
-
@method.stop
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def annotate(node, annotations)
|
|
92
|
-
node.annotate(annotations)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def define_optarg_chain(name, arg, return_type,
|
|
96
|
-
args_for_opt, arg_types_for_opt)
|
|
97
|
-
# declare all args so they get their values
|
|
98
|
-
@method.print "return " unless method.returns_void?
|
|
99
|
-
@method.print "this." unless @static
|
|
100
|
-
@method.print "#{name}("
|
|
101
|
-
@method.print args_for_opt.map(&:name).join(', ')
|
|
102
|
-
@method.print ', 'if args_for_opt.size > 0
|
|
103
|
-
arg.value.compile(self, true)
|
|
104
|
-
|
|
105
|
-
# invoke the next one in the chain
|
|
106
|
-
@method.print ");\n"
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def constructor(node)
|
|
110
|
-
super(node, false) do |method, _|
|
|
111
|
-
with :method => method do
|
|
112
|
-
@method.start
|
|
113
|
-
if node.delegate_args
|
|
114
|
-
delegate = if node.calls_super
|
|
115
|
-
"super"
|
|
116
|
-
else
|
|
117
|
-
"this"
|
|
118
|
-
end
|
|
119
|
-
method.print "#{delegate}("
|
|
120
|
-
node.delegate_args.each_with_index do |arg, index|
|
|
121
|
-
method.print ', ' unless index == 0
|
|
122
|
-
raise "Invalid constructor argument #{arg}" unless arg.expr?(self)
|
|
123
|
-
arg.compile(self, true)
|
|
124
|
-
end
|
|
125
|
-
method.puts ");"
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
prepare_binding(node) do
|
|
129
|
-
declare_locals(node.static_scope)
|
|
130
|
-
node.body.compile(self, false) if node.body
|
|
131
|
-
end
|
|
132
|
-
method.stop
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def prepare_binding(scope)
|
|
138
|
-
if scope.has_binding?
|
|
139
|
-
type = scope.binding_type
|
|
140
|
-
@binding = @bindings[type]
|
|
141
|
-
@method.puts "#{type.to_source} $binding = new #{type.to_source}();"
|
|
142
|
-
if scope.respond_to? :arguments
|
|
143
|
-
scope.arguments.args.each do |param|
|
|
144
|
-
if scope.static_scope.captured?(param.name)
|
|
145
|
-
captured_local_declare(scope, param.name, param.inferred_type)
|
|
146
|
-
@method.puts "$binding.#{param.name} = #{param.name};"
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
begin
|
|
152
|
-
yield
|
|
153
|
-
ensure
|
|
154
|
-
if scope.has_binding?
|
|
155
|
-
@binding.stop
|
|
156
|
-
@binding = nil
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def define_closure(class_def, expression)
|
|
162
|
-
compiler = ClosureCompiler.new(@file, @type, self)
|
|
163
|
-
compiler.define_class(class_def, expression)
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
def return(node)
|
|
167
|
-
if method.returns_void?
|
|
168
|
-
@method.puts 'return;'
|
|
169
|
-
return
|
|
170
|
-
end
|
|
171
|
-
if node.value.expr?(self)
|
|
172
|
-
@method.print 'return '
|
|
173
|
-
node.value.compile(self, true)
|
|
174
|
-
@method.puts ';'
|
|
175
|
-
else
|
|
176
|
-
store_value('return ', node.value)
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def _raise(node)
|
|
181
|
-
if node.expr?(self)
|
|
182
|
-
@method.print 'throw '
|
|
183
|
-
node.compile(self, true)
|
|
184
|
-
@method.puts ';'
|
|
185
|
-
else
|
|
186
|
-
store_value('throw ', node)
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
def rescue(node, expression)
|
|
191
|
-
@method.block 'try' do
|
|
192
|
-
if node.else_node.nil?
|
|
193
|
-
maybe_store(node.body, expression) if node.body
|
|
194
|
-
else
|
|
195
|
-
node.body.compile(self, false) if node.body
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
|
-
node.clauses.each do |clause|
|
|
199
|
-
clause.types.each do |type|
|
|
200
|
-
name = scoped_local_name(clause.name || 'tmp$ex', clause.static_scope)
|
|
201
|
-
@method.declare_local(type, name, false)
|
|
202
|
-
@method.block "catch (#{type.to_source} #{name})" do
|
|
203
|
-
declare_locals(clause.static_scope)
|
|
204
|
-
maybe_store(clause.body, expression)
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
if node.else_node
|
|
209
|
-
maybe_store(node.else_node, expression)
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def ensure(node, expression)
|
|
214
|
-
@method.block 'try' do
|
|
215
|
-
maybe_store(node.body, expression)
|
|
216
|
-
end
|
|
217
|
-
@method.block 'finally' do
|
|
218
|
-
node.clause.compile(self, false)
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
def line(num)
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def declare_local(name, type)
|
|
226
|
-
@method.declare_local(type, name)
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
def declare_field(name, type, annotations, static_field)
|
|
230
|
-
@class.declare_field(name, type, @static || static_field, 'private', annotations)
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
def local(scope, name, type)
|
|
234
|
-
name = scoped_local_name(name, scope)
|
|
235
|
-
@method.print name
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def field(name, type, annotations, static_field)
|
|
239
|
-
name = name[1..-1] if name =~ /^@/
|
|
240
|
-
declare_field(name, type, annotations, static_field)
|
|
241
|
-
@method.print "#{this}.#{name}"
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
def this(method=nil)
|
|
245
|
-
if method && method.static?
|
|
246
|
-
method.declaring_class.name
|
|
247
|
-
elsif @self_scope && @self_scope.self_node && @self_scope.self_node != :self
|
|
248
|
-
scoped_local_name('self', @self_scope)
|
|
249
|
-
else
|
|
250
|
-
@static ? @class.class_name : 'this'
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
def declare_locals(scope)
|
|
255
|
-
scope.locals.each do |name|
|
|
256
|
-
full_name = scoped_local_name(name, scope)
|
|
257
|
-
unless scope.captured?(name) || method.local?(full_name)
|
|
258
|
-
declare_local(full_name, scope.local_type(name))
|
|
259
|
-
end
|
|
260
|
-
end
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def local_assign(scope, name, type, expression, value)
|
|
264
|
-
simple = value.expr?(self)
|
|
265
|
-
value = value.precompile(self)
|
|
266
|
-
name = scoped_local_name(name, scope)
|
|
267
|
-
if method.local?(name)
|
|
268
|
-
if expression
|
|
269
|
-
if simple
|
|
270
|
-
@method.print '('
|
|
271
|
-
else
|
|
272
|
-
@method.print @lvalue
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
@method.print "#{name} = "
|
|
276
|
-
value.compile(self, true)
|
|
277
|
-
if simple && expression
|
|
278
|
-
@method.print ')'
|
|
279
|
-
else
|
|
280
|
-
@method.puts ';'
|
|
281
|
-
end
|
|
282
|
-
else
|
|
283
|
-
@method.declare_local(type, name) do
|
|
284
|
-
value.compile(self, true)
|
|
285
|
-
end
|
|
286
|
-
if expression
|
|
287
|
-
@method.puts "#{@lvalue}#{name};"
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
def field_declare(name, type, annotations)
|
|
293
|
-
name = name[1..-1] if name =~ /^@/
|
|
294
|
-
declare_field(name, type, annotations)
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
def local_declare(scope, name, type)
|
|
298
|
-
name = scoped_local_name(name, scope)
|
|
299
|
-
declare_local(name, type)
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
def field_assign(name, type, expression, value, annotations, static_field)
|
|
303
|
-
name = name[1..-1] if name =~ /^@/
|
|
304
|
-
declare_field(name, type, annotations, static_field)
|
|
305
|
-
lvalue = "#{@lvalue if expression}#{this}.#{name} = "
|
|
306
|
-
store_value(lvalue, value)
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
def captured_local_declare(scope, name, type)
|
|
310
|
-
unless declared_captures[name]
|
|
311
|
-
declared_captures[name] = type
|
|
312
|
-
@binding.declare_field(name, type, false, '')
|
|
313
|
-
end
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
def captured_local(scope, name, type)
|
|
317
|
-
captured_local_declare(scope, name, type)
|
|
318
|
-
@method.print "$binding.#{name}"
|
|
319
|
-
end
|
|
320
|
-
|
|
321
|
-
def captured_local_assign(node, expression)
|
|
322
|
-
scope, name, type = node.containing_scope, node.name, node.inferred_type
|
|
323
|
-
captured_local_declare(scope, name, type)
|
|
324
|
-
lvalue = "#{@lvalue if expression}$binding.#{name} = "
|
|
325
|
-
store_value(lvalue, node.value)
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
def store_value(lvalue, value)
|
|
329
|
-
if value.is_a? String
|
|
330
|
-
@method.puts "#{lvalue}#{value};"
|
|
331
|
-
elsif value.expr?(self)
|
|
332
|
-
@method.print lvalue
|
|
333
|
-
value.compile(self, true)
|
|
334
|
-
@method.puts ';'
|
|
335
|
-
else
|
|
336
|
-
with :lvalue => lvalue do
|
|
337
|
-
value.compile(self, true)
|
|
338
|
-
end
|
|
339
|
-
end
|
|
340
|
-
end
|
|
341
|
-
|
|
342
|
-
def assign(name, value)
|
|
343
|
-
store_value("#{name} = ", value)
|
|
344
|
-
name
|
|
345
|
-
end
|
|
346
|
-
|
|
347
|
-
def maybe_store(value, expression)
|
|
348
|
-
if expression
|
|
349
|
-
store_value(@lvalue, value)
|
|
350
|
-
else
|
|
351
|
-
value.compile(self, false)
|
|
352
|
-
end
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
def body(body, expression)
|
|
356
|
-
super(body, expression) do |last|
|
|
357
|
-
maybe_store(last, expression)
|
|
358
|
-
end
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
def scoped_body(scope, expression)
|
|
362
|
-
if @method
|
|
363
|
-
@method.block do
|
|
364
|
-
super
|
|
365
|
-
end
|
|
366
|
-
else
|
|
367
|
-
super
|
|
368
|
-
end
|
|
369
|
-
end
|
|
370
|
-
|
|
371
|
-
def branch_expression(node)
|
|
372
|
-
node.condition.compile(self, true)
|
|
373
|
-
@method.print ' ? ('
|
|
374
|
-
if node.body
|
|
375
|
-
node.body.compile(self, true)
|
|
376
|
-
else
|
|
377
|
-
@method.print @method.init_value(node.inferred_type)
|
|
378
|
-
end
|
|
379
|
-
@method.print ') : ('
|
|
380
|
-
if node.else
|
|
381
|
-
node.else.compile(self, true)
|
|
382
|
-
else
|
|
383
|
-
@method.print @method.init_value(node.inferred_type)
|
|
384
|
-
end
|
|
385
|
-
@method.print ')'
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
def branch(node, expression)
|
|
389
|
-
if expression && node.expr?(self)
|
|
390
|
-
return branch_expression(node)
|
|
391
|
-
end
|
|
392
|
-
predicate = node.condition.predicate.precompile(self)
|
|
393
|
-
@method.print 'if ('
|
|
394
|
-
predicate.compile(self, true)
|
|
395
|
-
@method.block ")" do
|
|
396
|
-
if node.body
|
|
397
|
-
maybe_store(node.body, expression)
|
|
398
|
-
elsif expression
|
|
399
|
-
store_value(@lvalue, @method.init_value(node.inferred_type))
|
|
400
|
-
end
|
|
401
|
-
end
|
|
402
|
-
if node.else || expression
|
|
403
|
-
@method.block 'else' do
|
|
404
|
-
if node.else
|
|
405
|
-
maybe_store(node.else, expression)
|
|
406
|
-
else
|
|
407
|
-
store_value(@lvalue, @method.init_value(node.inferred_type))
|
|
408
|
-
end
|
|
409
|
-
end
|
|
410
|
-
end
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
def loop(loop, expression)
|
|
414
|
-
if loop.redo? || loop.post || !loop.condition.predicate.expr?(self)
|
|
415
|
-
loop = ComplexWhileLoop.new(loop, self)
|
|
416
|
-
else
|
|
417
|
-
loop = SimpleWhileLoop.new(loop, self)
|
|
418
|
-
end
|
|
419
|
-
with(:loop => loop) do
|
|
420
|
-
loop.compile(expression)
|
|
421
|
-
end
|
|
422
|
-
end
|
|
423
|
-
|
|
424
|
-
def expr?(target, params)
|
|
425
|
-
!([target] + params).any? {|x| x.kind_of? Mirah::AST::TempValue}
|
|
426
|
-
end
|
|
427
|
-
|
|
428
|
-
def operator(target, op, params, expression)
|
|
429
|
-
simple = expr?(target, params)
|
|
430
|
-
if expression && !simple
|
|
431
|
-
@method.print @lvalue
|
|
432
|
-
end
|
|
433
|
-
if params.size == 0
|
|
434
|
-
# unary operator
|
|
435
|
-
op = op[0,1]
|
|
436
|
-
@method.print op
|
|
437
|
-
target.compile(self, true)
|
|
438
|
-
else
|
|
439
|
-
@method.print '('
|
|
440
|
-
other = params[0]
|
|
441
|
-
target.compile(self, true)
|
|
442
|
-
@method.print " #{op} "
|
|
443
|
-
other.compile(self, true)
|
|
444
|
-
@method.print ')'
|
|
445
|
-
end
|
|
446
|
-
unless expression && simple
|
|
447
|
-
@method.puts ';'
|
|
448
|
-
end
|
|
449
|
-
end
|
|
450
|
-
|
|
451
|
-
def precompile_nodes(nodes)
|
|
452
|
-
if nodes.all? {|n| n.expr?(self)}
|
|
453
|
-
nodes
|
|
454
|
-
else
|
|
455
|
-
nodes.map do |node|
|
|
456
|
-
tempval = node.precompile(self)
|
|
457
|
-
if node == tempval && !node.kind_of?(Mirah::AST::Literal)
|
|
458
|
-
tempval = node.temp(self)
|
|
459
|
-
end
|
|
460
|
-
tempval
|
|
461
|
-
end
|
|
462
|
-
end
|
|
463
|
-
end
|
|
464
|
-
|
|
465
|
-
def compile_args(call)
|
|
466
|
-
precompile_nodes(call.parameters)
|
|
467
|
-
end
|
|
468
|
-
|
|
469
|
-
def self_type
|
|
470
|
-
type = AST.type(nil, @class.name.tr('/', '.'))
|
|
471
|
-
type = type.meta if @static
|
|
472
|
-
type
|
|
473
|
-
end
|
|
474
|
-
|
|
475
|
-
def super_call(call, expression)
|
|
476
|
-
super_method_call(this, call, compile_args(call), expression)
|
|
477
|
-
end
|
|
478
|
-
|
|
479
|
-
def cast(call, expression)
|
|
480
|
-
args = compile_args(call)
|
|
481
|
-
simple = call.expr?(self)
|
|
482
|
-
@method.print @lvalue if expression && !simple
|
|
483
|
-
@method.print "((#{call.inferred_type.to_source})("
|
|
484
|
-
args.each{|arg| arg.compile(self, true)}
|
|
485
|
-
@method.print "))"
|
|
486
|
-
@method.puts ';' unless simple && expression
|
|
487
|
-
end
|
|
488
|
-
|
|
489
|
-
def self_call(call, expression)
|
|
490
|
-
if call.cast?
|
|
491
|
-
cast(call, expression)
|
|
492
|
-
else
|
|
493
|
-
type = call.scope.static_scope.self_type
|
|
494
|
-
type = type.meta if (@static && type == @type)
|
|
495
|
-
params = call.parameters.map do |param|
|
|
496
|
-
param.inferred_type
|
|
497
|
-
end
|
|
498
|
-
method = type.get_method(call.name, params)
|
|
499
|
-
method_call(this(method), call, compile_args(call), expression)
|
|
500
|
-
end
|
|
501
|
-
end
|
|
502
|
-
|
|
503
|
-
def call(call, expression)
|
|
504
|
-
return cast(call, expression) if call.cast?
|
|
505
|
-
if Mirah::AST::Constant === call.target || Mirah::AST::Colon2 === call.target
|
|
506
|
-
target = call.target.inferred_type.to_source
|
|
507
|
-
else
|
|
508
|
-
target = call.precompile_target(self)
|
|
509
|
-
end
|
|
510
|
-
params = compile_args(call)
|
|
511
|
-
|
|
512
|
-
if Operators.include? call.name
|
|
513
|
-
operator(target, call.name, params, expression)
|
|
514
|
-
elsif call.target.inferred_type.array? && ArrayOps.include?(call.name)
|
|
515
|
-
array_op(target, call.name, params, expression)
|
|
516
|
-
elsif call.name == 'nil?'
|
|
517
|
-
operator(target, '==', ['null'], expression)
|
|
518
|
-
else
|
|
519
|
-
method_call(target, call, params, expression)
|
|
520
|
-
end
|
|
521
|
-
end
|
|
522
|
-
|
|
523
|
-
def array_op(target, name, args, expression)
|
|
524
|
-
simple = expr?(target, args)
|
|
525
|
-
index, value = args
|
|
526
|
-
if expression && !simple
|
|
527
|
-
@method.print @lvalue
|
|
528
|
-
end
|
|
529
|
-
target.compile(self, true)
|
|
530
|
-
if name == 'length'
|
|
531
|
-
@method.print '.length'
|
|
532
|
-
else
|
|
533
|
-
@method.print '['
|
|
534
|
-
index.compile(self, true)
|
|
535
|
-
@method.print ']'
|
|
536
|
-
if name == '[]='
|
|
537
|
-
@method.print " = "
|
|
538
|
-
value.compile(self, true)
|
|
539
|
-
end
|
|
540
|
-
end
|
|
541
|
-
unless simple && expression
|
|
542
|
-
@method.puts ';'
|
|
543
|
-
end
|
|
544
|
-
end
|
|
545
|
-
|
|
546
|
-
def break(node)
|
|
547
|
-
error("break outside of loop", node) unless @loop
|
|
548
|
-
@loop.break
|
|
549
|
-
end
|
|
550
|
-
|
|
551
|
-
def next(node)
|
|
552
|
-
error("next outside of loop", node) unless @loop
|
|
553
|
-
@loop.next
|
|
554
|
-
end
|
|
555
|
-
|
|
556
|
-
def redo(node)
|
|
557
|
-
error("redo outside of loop", node) unless @loop
|
|
558
|
-
@loop.redo
|
|
559
|
-
end
|
|
560
|
-
|
|
561
|
-
# TODO: merge cleanly with method_call logic
|
|
562
|
-
def super_method_call(target, call, params, expression)
|
|
563
|
-
simple = call.expr?(self)
|
|
564
|
-
method = call.method(self)
|
|
565
|
-
unless simple || method.return_type.void?
|
|
566
|
-
@method.print @lvalue if expression
|
|
567
|
-
end
|
|
568
|
-
if method.constructor?
|
|
569
|
-
@method.print "super("
|
|
570
|
-
else
|
|
571
|
-
@method.print "super.#{method.name}("
|
|
572
|
-
end
|
|
573
|
-
params.each_with_index do |param, index|
|
|
574
|
-
@method.print ', ' unless index == 0
|
|
575
|
-
param.compile(self, true)
|
|
576
|
-
end
|
|
577
|
-
if simple && expression
|
|
578
|
-
@method.print ')'
|
|
579
|
-
else
|
|
580
|
-
@method.puts ');'
|
|
581
|
-
end
|
|
582
|
-
if method.return_type.void? && expression
|
|
583
|
-
@method.print @lvalue
|
|
584
|
-
if method.static?
|
|
585
|
-
@method.puts 'null;'
|
|
586
|
-
else
|
|
587
|
-
target.compile(self, true)
|
|
588
|
-
@method.puts ';'
|
|
589
|
-
end
|
|
590
|
-
end
|
|
591
|
-
|
|
592
|
-
end
|
|
593
|
-
|
|
594
|
-
def method_call(target, call, params, expression)
|
|
595
|
-
simple = call.expr?(self)
|
|
596
|
-
method = call.method(self)
|
|
597
|
-
unless simple || method.return_type.void?
|
|
598
|
-
@method.print @lvalue if expression
|
|
599
|
-
end
|
|
600
|
-
|
|
601
|
-
# preamble
|
|
602
|
-
if method.constructor?
|
|
603
|
-
@method.print "new "
|
|
604
|
-
target.compile(self, true)
|
|
605
|
-
@method.print '('
|
|
606
|
-
elsif method.field?
|
|
607
|
-
target.compile(self, true)
|
|
608
|
-
@method.print ".#{method.name}"
|
|
609
|
-
if method.argument_types.size == 1
|
|
610
|
-
@method.print " = ("
|
|
611
|
-
end
|
|
612
|
-
elsif Mirah::JVM::Types::Intrinsic === method
|
|
613
|
-
method.call(self, call, expression)
|
|
614
|
-
return
|
|
615
|
-
else
|
|
616
|
-
@method.print "(" if Mirah::AST::StringConcat === target
|
|
617
|
-
target.compile(self, true)
|
|
618
|
-
@method.print ")" if Mirah::AST::StringConcat === target
|
|
619
|
-
@method.print ".#{method.name}("
|
|
620
|
-
end
|
|
621
|
-
|
|
622
|
-
# args
|
|
623
|
-
params.each_with_index do |param, index|
|
|
624
|
-
@method.print ', ' unless index == 0
|
|
625
|
-
param.compile(self, true)
|
|
626
|
-
end
|
|
627
|
-
|
|
628
|
-
# postamble
|
|
629
|
-
if !method.field? || (method.field? && method.argument_types.size == 1)
|
|
630
|
-
if simple && expression
|
|
631
|
-
@method.print ')'
|
|
632
|
-
else
|
|
633
|
-
@method.puts ');'
|
|
634
|
-
end
|
|
635
|
-
end
|
|
636
|
-
|
|
637
|
-
# cleanup
|
|
638
|
-
if method.return_type.void? && expression
|
|
639
|
-
@method.print @lvalue
|
|
640
|
-
if method.static?
|
|
641
|
-
@method.puts 'null;'
|
|
642
|
-
else
|
|
643
|
-
target.compile(self, true)
|
|
644
|
-
@method.puts ';'
|
|
645
|
-
end
|
|
646
|
-
end
|
|
647
|
-
end
|
|
648
|
-
|
|
649
|
-
def temp(expression, value=nil)
|
|
650
|
-
value ||= expression
|
|
651
|
-
type = value.inferred_type
|
|
652
|
-
if value.expr?(self)
|
|
653
|
-
@method.tmp(type) do
|
|
654
|
-
value.compile(self, true)
|
|
655
|
-
end
|
|
656
|
-
else
|
|
657
|
-
assign(@method.tmp(type), value)
|
|
658
|
-
end
|
|
659
|
-
end
|
|
660
|
-
|
|
661
|
-
def empty_array(type, size)
|
|
662
|
-
sizevar = size.precompile(self)
|
|
663
|
-
@method.print "#{@lvalue unless size.expr?(self)}new #{type.name}["
|
|
664
|
-
sizevar.compile(self, true)
|
|
665
|
-
@method.print ']'
|
|
666
|
-
end
|
|
667
|
-
|
|
668
|
-
def string(value)
|
|
669
|
-
@method.print value.inspect
|
|
670
|
-
end
|
|
671
|
-
|
|
672
|
-
def boolean(value)
|
|
673
|
-
@method.print value ? 'true' : 'false'
|
|
674
|
-
end
|
|
675
|
-
|
|
676
|
-
def regexp(value, flags = 0)
|
|
677
|
-
@method.print "java.util.regex.Pattern.compile("
|
|
678
|
-
@method.print value.inspect
|
|
679
|
-
@method.print ")"
|
|
680
|
-
end
|
|
681
|
-
|
|
682
|
-
def array(node, expression)
|
|
683
|
-
if expression
|
|
684
|
-
# create unmodifiable list from array (simplest way to do this in Java source)
|
|
685
|
-
@method.print "java.util.Collections.unmodifiableList(java.util.Arrays.asList("
|
|
686
|
-
|
|
687
|
-
# elements, as expressions
|
|
688
|
-
comma = false
|
|
689
|
-
node.children.each do |n|
|
|
690
|
-
@method.print ", " if comma
|
|
691
|
-
n.compile(self, true)
|
|
692
|
-
comma = true
|
|
693
|
-
end
|
|
694
|
-
|
|
695
|
-
@method.print("))")
|
|
696
|
-
else
|
|
697
|
-
# elements, as non-expressions
|
|
698
|
-
# TODO: ensure they're all reference types!
|
|
699
|
-
node.children.each do |n|
|
|
700
|
-
n.compile(self, false)
|
|
701
|
-
end
|
|
702
|
-
end
|
|
703
|
-
end
|
|
704
|
-
|
|
705
|
-
def build_string(orig_nodes, expression)
|
|
706
|
-
if expression
|
|
707
|
-
nodes = precompile_nodes(orig_nodes)
|
|
708
|
-
simple = nodes.equal?(orig_nodes)
|
|
709
|
-
|
|
710
|
-
unless simple
|
|
711
|
-
@method.print(lvalue)
|
|
712
|
-
end
|
|
713
|
-
|
|
714
|
-
@method.print '"" + ' unless nodes.first.kind_of?(Mirah::AST::String)
|
|
715
|
-
|
|
716
|
-
nodes.first.compile(self, true)
|
|
717
|
-
|
|
718
|
-
nodes[1..-1].each do |node|
|
|
719
|
-
@method.print ' + '
|
|
720
|
-
node.compile(self, true)
|
|
721
|
-
end
|
|
722
|
-
unless simple
|
|
723
|
-
@method.puts ';'
|
|
724
|
-
end
|
|
725
|
-
else
|
|
726
|
-
orig_nodes.each {|n| n.compile(self, false)}
|
|
727
|
-
end
|
|
728
|
-
end
|
|
729
|
-
|
|
730
|
-
def to_string(body, expression)
|
|
731
|
-
body.compile(self, expression)
|
|
732
|
-
end
|
|
733
|
-
|
|
734
|
-
def null
|
|
735
|
-
@method.print 'null'
|
|
736
|
-
end
|
|
737
|
-
|
|
738
|
-
def binding_reference
|
|
739
|
-
@method.print '$binding'
|
|
740
|
-
end
|
|
741
|
-
|
|
742
|
-
def real_self
|
|
743
|
-
@method.print 'this'
|
|
744
|
-
end
|
|
745
|
-
|
|
746
|
-
def print(node)
|
|
747
|
-
value = node.parameters[0]
|
|
748
|
-
value = value && value.precompile(self)
|
|
749
|
-
if node.println
|
|
750
|
-
@method.print "System.out.println("
|
|
751
|
-
else
|
|
752
|
-
@method.print "System.out.print("
|
|
753
|
-
end
|
|
754
|
-
value.compile(self, true) if value
|
|
755
|
-
@method.puts ');'
|
|
756
|
-
end
|
|
757
|
-
|
|
758
|
-
class ClosureCompiler < JavaSource
|
|
759
|
-
def initialize(file, type, parent)
|
|
760
|
-
@file = file
|
|
761
|
-
@type = type
|
|
762
|
-
@parent = parent
|
|
763
|
-
end
|
|
764
|
-
|
|
765
|
-
def prepare_binding(scope)
|
|
766
|
-
if scope.has_binding?
|
|
767
|
-
type = scope.binding_type
|
|
768
|
-
@binding = @parent.get_binding(type)
|
|
769
|
-
@method.puts("#{type.to_source} $binding = this.binding;")
|
|
770
|
-
end
|
|
771
|
-
begin
|
|
772
|
-
yield
|
|
773
|
-
ensure
|
|
774
|
-
if scope.has_binding?
|
|
775
|
-
@binding = nil
|
|
776
|
-
end
|
|
777
|
-
end
|
|
778
|
-
end
|
|
779
|
-
|
|
780
|
-
def declared_captures
|
|
781
|
-
@parent.declared_captures(@binding)
|
|
782
|
-
end
|
|
783
|
-
end
|
|
784
|
-
end
|
|
785
|
-
end
|
|
786
|
-
end
|
|
787
|
-
end
|