mirah 0.0.5-java → 0.0.6-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 +33 -0
- data/README.txt +2 -3
- data/Rakefile +5 -0
- data/bin/duby +0 -0
- data/bin/dubyc +0 -0
- data/bin/dubyp +0 -0
- data/bin/jrubyp +0 -0
- data/bin/mirah +0 -0
- data/bin/mirah.cmd +14 -14
- data/bin/mirahc +0 -0
- data/bin/mirahc.cmd +14 -14
- data/bin/mirahp +0 -0
- data/bin/mirahp.cmd +14 -14
- data/examples/Dynamic.class +0 -0
- data/examples/SizeThing.class +0 -0
- data/examples/plugins/appengine/Rakefile +3 -1
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/MetaModel.mirah +385 -0
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +58 -15
- data/examples/wiki/war/public/javascripts/prettify.js +0 -0
- data/examples/wiki/war/public/stylesheets/prettify.css +0 -0
- data/javalib/dynalink-0.1.jar +0 -0
- data/javalib/jsr292-mock.jar +0 -0
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/lib/mirah.rb +45 -25
- data/lib/mirah/ast.rb +81 -27
- data/lib/mirah/ast/call.rb +62 -71
- data/lib/mirah/ast/class.rb +23 -26
- data/lib/mirah/ast/flow.rb +38 -62
- data/lib/mirah/ast/intrinsics.rb +59 -37
- data/lib/mirah/ast/literal.rb +16 -14
- data/lib/mirah/ast/local.rb +8 -8
- data/lib/mirah/ast/method.rb +33 -19
- data/lib/mirah/ast/structure.rb +54 -13
- data/lib/mirah/ast/type.rb +8 -11
- data/lib/mirah/compiler.rb +86 -0
- data/lib/mirah/errors.rb +60 -0
- data/lib/mirah/jvm/base.rb +5 -11
- data/lib/mirah/jvm/compiler.rb +12 -1
- data/lib/mirah/jvm/source_compiler.rb +10 -2
- data/lib/mirah/jvm/source_generator/builder.rb +3 -1
- data/lib/mirah/jvm/source_generator/precompile.rb +6 -0
- data/lib/mirah/jvm/typer.rb +6 -1
- data/lib/mirah/jvm/types.rb +8 -0
- data/lib/mirah/jvm/types/factory.rb +34 -10
- data/lib/mirah/jvm/types/intrinsics.rb +12 -5
- data/lib/mirah/jvm/types/methods.rb +5 -9
- data/lib/mirah/plugin/gwt.rb +3 -2
- data/lib/mirah/transform.rb +68 -10
- data/lib/mirah/transform2.rb +10 -1
- data/lib/mirah/typer.rb +5 -10
- data/lib/mirah/version.rb +1 -1
- data/test/test_compilation.rb +1 -1
- data/test/test_java_typer.rb +10 -0
- data/test/test_javac_compiler.rb +4 -2
- data/test/test_jvm_compiler.rb +132 -9
- data/test/test_macros.rb +51 -0
- data/test/test_typer.rb +29 -25
- metadata +13 -21
- data/examples/plugins/appengine/lib/com/google/appengine/ext/duby/db/datastore.rb +0 -390
- data/javalib/JRubyParser.jar +0 -0
- data/javalib/dynalang-invoke-0.1.jar +0 -0
- data/lib/mirah/nbcompiler.rb +0 -44
data/lib/mirah/errors.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Mirah
|
2
|
+
class MirahError < StandardError
|
3
|
+
attr_accessor :position
|
4
|
+
attr_accessor :cause
|
5
|
+
|
6
|
+
def initialize(message, position=nil)
|
7
|
+
super(message)
|
8
|
+
@position = position
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class NodeError < MirahError
|
13
|
+
attr_reader :node
|
14
|
+
|
15
|
+
def initialize(message, node=nil)
|
16
|
+
position = node.position if node
|
17
|
+
super(message, position)
|
18
|
+
@node = node
|
19
|
+
end
|
20
|
+
|
21
|
+
def node=(node)
|
22
|
+
@position = node ? node.position : nil
|
23
|
+
@node = node
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.wrap(ex, node)
|
27
|
+
if ex.kind_of?(NodeError)
|
28
|
+
ex.node ||= node
|
29
|
+
return ex
|
30
|
+
elsif ex.kind_of?(MirahError)
|
31
|
+
ex.position ||= node.position
|
32
|
+
return ex
|
33
|
+
else
|
34
|
+
new_ex = new(ex.message, node)
|
35
|
+
new_ex.cause = ex
|
36
|
+
new_ex.position ||= ex.position if ex.respond_to?(:position)
|
37
|
+
new_ex.set_backtrace(ex.backtrace)
|
38
|
+
return new_ex
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def position
|
43
|
+
if node && node.position
|
44
|
+
node.position
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class SyntaxError < NodeError
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
class InferenceError < NodeError
|
56
|
+
end
|
57
|
+
|
58
|
+
class InternalCompilerError < NodeError
|
59
|
+
end
|
60
|
+
end
|
data/lib/mirah/jvm/base.rb
CHANGED
@@ -18,12 +18,7 @@ module Mirah
|
|
18
18
|
class JVMCompilerBase
|
19
19
|
attr_accessor :filename, :method, :static, :class
|
20
20
|
|
21
|
-
class CompilationError <
|
22
|
-
attr_accessor :node
|
23
|
-
def initialize(msg, node = nil)
|
24
|
-
super(msg)
|
25
|
-
@node = node
|
26
|
-
end
|
21
|
+
class CompilationError < Mirah::NodeError
|
27
22
|
end
|
28
23
|
|
29
24
|
def initialize
|
@@ -41,8 +36,7 @@ module Mirah
|
|
41
36
|
begin
|
42
37
|
ast.compile(self, expression)
|
43
38
|
rescue => ex
|
44
|
-
Mirah.
|
45
|
-
raise ex
|
39
|
+
raise Mirah::InternalCompilerError.wrap(ex, ast)
|
46
40
|
end
|
47
41
|
log "Compilation successful!"
|
48
42
|
end
|
@@ -196,8 +190,7 @@ module Mirah
|
|
196
190
|
scope = body.static_scope
|
197
191
|
declare_locals(scope)
|
198
192
|
if scope != @self_scope
|
199
|
-
|
200
|
-
if scope.self_node
|
193
|
+
if scope.self_node && scope.self_node != :self
|
201
194
|
# FIXME This is a horrible hack!
|
202
195
|
# Instead we should eliminate unused self's.
|
203
196
|
unless scope.self_type.name == 'mirah.impl.Builtin'
|
@@ -205,6 +198,7 @@ module Mirah
|
|
205
198
|
scope, 'self', scope.self_type, false, scope.self_node)
|
206
199
|
end
|
207
200
|
end
|
201
|
+
@self_scope = scope
|
208
202
|
end
|
209
203
|
end
|
210
204
|
# all except the last element in a body of code is treated as a statement
|
@@ -238,7 +232,7 @@ module Mirah
|
|
238
232
|
alias float fixnum
|
239
233
|
|
240
234
|
def compile_self
|
241
|
-
if @self_scope && @self_scope.self_node
|
235
|
+
if @self_scope && @self_scope.self_node && @self_scope.self_node != :self
|
242
236
|
local(@self_scope, 'self', @self_scope.self_type)
|
243
237
|
else
|
244
238
|
real_self
|
data/lib/mirah/jvm/compiler.rb
CHANGED
@@ -120,6 +120,17 @@ module Mirah
|
|
120
120
|
@method.new type
|
121
121
|
@method.dup
|
122
122
|
@method.invokespecial type, "<init>", [@method.void]
|
123
|
+
if scope.respond_to? :arguments
|
124
|
+
scope.arguments.args.each do |param|
|
125
|
+
name = param.name
|
126
|
+
param_type = param.inferred_type
|
127
|
+
if scope.static_scope.captured?(param.name)
|
128
|
+
@method.dup
|
129
|
+
type.load(@method, @method.local(name, param_type))
|
130
|
+
@method.putfield(type, name, param_type)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
123
134
|
type.store(@method, @method.local('$binding', type))
|
124
135
|
end
|
125
136
|
begin
|
@@ -716,7 +727,7 @@ module Mirah
|
|
716
727
|
@method.dup
|
717
728
|
n.compile(self, true)
|
718
729
|
# TODO this feels like it should be in the node.compile itself
|
719
|
-
if n.inferred_type
|
730
|
+
if n.inferred_type!.primitive?
|
720
731
|
n.inferred_type.box(@method)
|
721
732
|
end
|
722
733
|
@method.invokeinterface java::util::List, "add", [@method.boolean, @method.object]
|
@@ -128,6 +128,14 @@ module Mirah
|
|
128
128
|
type = scope.binding_type
|
129
129
|
@binding = @bindings[type]
|
130
130
|
@method.puts "#{type.to_source} $binding = new #{type.to_source}();"
|
131
|
+
if scope.respond_to? :arguments
|
132
|
+
scope.arguments.args.each do |param|
|
133
|
+
if scope.static_scope.captured?(param.name)
|
134
|
+
captured_local_declare(scope, param.name, param.inferred_type)
|
135
|
+
@method.puts "$binding.#{param.name} = #{param.name};"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
131
139
|
end
|
132
140
|
begin
|
133
141
|
yield
|
@@ -218,7 +226,7 @@ module Mirah
|
|
218
226
|
def this(method=nil)
|
219
227
|
if method && method.static?
|
220
228
|
method.declaring_class.name
|
221
|
-
elsif @self_scope && @self_scope.self_node
|
229
|
+
elsif @self_scope && @self_scope.self_node && @self_scope.self_node != :self
|
222
230
|
scoped_local_name('self', @self_scope)
|
223
231
|
else
|
224
232
|
@static ? @class.class_name : 'this'
|
@@ -472,7 +480,7 @@ module Mirah
|
|
472
480
|
|
473
481
|
def call(call, expression)
|
474
482
|
return cast(call, expression) if call.cast?
|
475
|
-
if Mirah::AST::Constant === call.target
|
483
|
+
if Mirah::AST::Constant === call.target || Mirah::AST::Colon2 === call.target
|
476
484
|
target = call.target.inferred_type.to_source
|
477
485
|
else
|
478
486
|
target = call.precompile_target(self)
|
@@ -231,7 +231,9 @@ module Mirah
|
|
231
231
|
end
|
232
232
|
|
233
233
|
def finish_declaration
|
234
|
+
raise if @stopped
|
234
235
|
return if @declaration_finished
|
236
|
+
|
235
237
|
@declaration_finished = true
|
236
238
|
modifiers = "public#{' static' if @static}#{' abstract' if @abstract}"
|
237
239
|
print "#{modifiers} class #{class_name} extends #{superclass.name}"
|
@@ -247,8 +249,8 @@ module Mirah
|
|
247
249
|
end
|
248
250
|
|
249
251
|
def stop
|
250
|
-
finish_declaration
|
251
252
|
return if @stopped
|
253
|
+
finish_declaration
|
252
254
|
@methods.each do |method|
|
253
255
|
@out << method.out
|
254
256
|
end
|
data/lib/mirah/jvm/typer.rb
CHANGED
@@ -42,7 +42,12 @@ module Mirah
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def type_reference(scope, name, array=false, meta=false)
|
45
|
-
|
45
|
+
begin
|
46
|
+
@factory.type(scope, name, array, meta)
|
47
|
+
rescue NameError => ex
|
48
|
+
known_types[name] = Mirah::AST.error_type
|
49
|
+
raise Mirah::InferenceError.wrap(ex, nil)
|
50
|
+
end
|
46
51
|
end
|
47
52
|
|
48
53
|
def name
|
data/lib/mirah/jvm/types.rb
CHANGED
@@ -146,6 +146,14 @@ module Mirah
|
|
146
146
|
method.anewarray(self)
|
147
147
|
end
|
148
148
|
|
149
|
+
def pop(method)
|
150
|
+
if wide?
|
151
|
+
method.pop2
|
152
|
+
else
|
153
|
+
method.pop
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
149
157
|
def superclass
|
150
158
|
raise "Incomplete type #{self}" unless jvm_type
|
151
159
|
AST.type(nil, jvm_type.superclass) if jvm_type.superclass
|
@@ -106,22 +106,26 @@ module Mirah::JVM::Types
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def find_type(scope, name)
|
109
|
+
saved_ex = nil
|
109
110
|
begin
|
110
111
|
return get_type(name)
|
111
112
|
rescue NameError => ex
|
112
|
-
|
113
|
+
saved_ex = ex
|
113
114
|
end
|
114
115
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
116
|
+
if scope
|
117
|
+
imports = scope.static_scope.imports
|
118
|
+
if imports.include?(name)
|
119
|
+
name = imports[name] while imports.include?(name)
|
120
|
+
return get_type(name)
|
121
|
+
end
|
120
122
|
|
121
|
-
|
122
|
-
|
123
|
-
|
123
|
+
# TODO support inner class names
|
124
|
+
if name !~ /\./
|
125
|
+
return package_search(name, scope)
|
126
|
+
end
|
124
127
|
end
|
128
|
+
raise saved_ex
|
125
129
|
end
|
126
130
|
|
127
131
|
def package_search(name, scope)
|
@@ -141,7 +145,27 @@ module Mirah::JVM::Types
|
|
141
145
|
def get_type(full_name)
|
142
146
|
type = @known_types[full_name]
|
143
147
|
return type.basic_type if type
|
144
|
-
|
148
|
+
begin
|
149
|
+
mirror = get_mirror(full_name)
|
150
|
+
rescue NameError => ex
|
151
|
+
if full_name =~ /^(.+)\.([^.]+)/
|
152
|
+
outer_name = $1
|
153
|
+
inner_name = $2
|
154
|
+
begin
|
155
|
+
outer_type = get_type(outer_name)
|
156
|
+
full_name = "#{outer_type.name}$#{inner_name}"
|
157
|
+
rescue NameError
|
158
|
+
raise ex
|
159
|
+
end
|
160
|
+
mirror = get_mirror(full_name)
|
161
|
+
else
|
162
|
+
raise ex
|
163
|
+
end
|
164
|
+
end
|
165
|
+
type = Type.new(mirror).load_extensions
|
166
|
+
if full_name.include? '$'
|
167
|
+
@known_types[full_name.gsub('$', '.')] = type
|
168
|
+
end
|
145
169
|
@known_types[full_name] = type
|
146
170
|
end
|
147
171
|
|
@@ -74,18 +74,25 @@ module Mirah::JVM::Types
|
|
74
74
|
|
75
75
|
def add_compiled_macro(klass, name, arg_types)
|
76
76
|
add_macro(name, *arg_types) do |duby, call|
|
77
|
+
# Ick. We need to preserve the scope of the arguments to the macro.
|
78
|
+
# However the only way to do that is to wrap them in a ScopedBody.
|
79
|
+
# It'd be better if we didn't have to expose this wrapper node to
|
80
|
+
# the user code.
|
81
|
+
call.parameters = call.parameters.map do |arg|
|
82
|
+
wrapper = Mirah::AST::ScopedBody.new(call.parent, call.position)
|
83
|
+
wrapper.static_scope = call.scope.static_scope
|
84
|
+
wrapper << arg
|
85
|
+
end
|
77
86
|
expander = klass.constructors[0].newInstance(duby, call)
|
78
87
|
ast = expander.expand
|
79
88
|
if ast
|
89
|
+
body = Mirah::AST::ScopedBody.new(call.parent, call.position)
|
90
|
+
body << ast
|
80
91
|
if call.target
|
81
|
-
body = Mirah::AST::ScopedBody.new(call.parent, call.position)
|
82
92
|
body.static_scope.self_type = call.target.inferred_type!
|
83
93
|
body.static_scope.self_node = call.target
|
84
|
-
body << ast
|
85
|
-
body
|
86
|
-
else
|
87
|
-
ast
|
88
94
|
end
|
95
|
+
body
|
89
96
|
else
|
90
97
|
Mirah::AST::Noop.new(call.parent, call.position)
|
91
98
|
end
|
@@ -207,11 +207,7 @@ module Mirah::JVM::Types
|
|
207
207
|
end
|
208
208
|
|
209
209
|
unless expression || void?
|
210
|
-
|
211
|
-
compiler.method.pop2
|
212
|
-
else
|
213
|
-
compiler.method.pop
|
214
|
-
end
|
210
|
+
return_type.pop(compiler.method)
|
215
211
|
end
|
216
212
|
end
|
217
213
|
|
@@ -238,7 +234,7 @@ module Mirah::JVM::Types
|
|
238
234
|
end
|
239
235
|
|
240
236
|
unless expression || void?
|
241
|
-
compiler.method
|
237
|
+
return_type.pop(compiler.method)
|
242
238
|
end
|
243
239
|
end
|
244
240
|
end
|
@@ -255,7 +251,7 @@ module Mirah::JVM::Types
|
|
255
251
|
# TODO: inference phase needs to track that signature is void
|
256
252
|
# but actual type is null object
|
257
253
|
compiler.method.aconst_null if expression && void?
|
258
|
-
compiler.method
|
254
|
+
return_type.pop(compiler.method) unless expression || void?
|
259
255
|
end
|
260
256
|
end
|
261
257
|
|
@@ -290,7 +286,7 @@ module Mirah::JVM::Types
|
|
290
286
|
[return_type, target, *@types])
|
291
287
|
|
292
288
|
unless expression
|
293
|
-
compiler.method
|
289
|
+
return_type.pop(compiler.method)
|
294
290
|
end
|
295
291
|
|
296
292
|
compiler.bootstrap_dynamic
|
@@ -422,7 +418,7 @@ module Mirah::JVM::Types
|
|
422
418
|
|
423
419
|
begin
|
424
420
|
descriptors = types.map {|type| BiteScript::Signature.class_id(type)}
|
425
|
-
method = jvm_type.getDeclaredMethod(name, *descriptors)
|
421
|
+
method = jvm_type.getDeclaredMethod(name, *descriptors) if jvm_type
|
426
422
|
|
427
423
|
if method.nil? && superclass
|
428
424
|
method = superclass.java_method(name, *types) rescue nil
|
data/lib/mirah/plugin/gwt.rb
CHANGED
@@ -107,9 +107,10 @@ module Mirah::AST
|
|
107
107
|
compiler.define_jsni_method(self)
|
108
108
|
end
|
109
109
|
|
110
|
-
def infer(typer)
|
110
|
+
def infer(typer, expression)
|
111
111
|
@static ||= scope.static_scope.self_type.meta? unless scope.nil?
|
112
112
|
@defining_class ||= begin
|
113
|
+
static_scope.self_node = :self
|
113
114
|
static_scope.self_type = if static?
|
114
115
|
scope.static_scope.self_type.meta
|
115
116
|
else
|
@@ -117,7 +118,7 @@ module Mirah::AST
|
|
117
118
|
end
|
118
119
|
end
|
119
120
|
resolve_if(typer) do
|
120
|
-
argument_types = typer.infer(arguments)
|
121
|
+
argument_types = typer.infer(arguments, true)
|
121
122
|
if argument_types.all?
|
122
123
|
typer.learn_method_type(defining_class, name, argument_types,
|
123
124
|
signature[:return], signature[:throws])
|
data/lib/mirah/transform.rb
CHANGED
@@ -15,16 +15,16 @@
|
|
15
15
|
|
16
16
|
require 'base64'
|
17
17
|
require 'jruby'
|
18
|
+
require 'mirah/errors'
|
18
19
|
|
19
20
|
module Mirah
|
20
21
|
module Transform
|
21
|
-
class Error <
|
22
|
-
attr_reader :position
|
22
|
+
class Error < Mirah::MirahError
|
23
|
+
attr_reader :position
|
23
24
|
def initialize(msg, position, cause=nil)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@cause = cause
|
25
|
+
position = position.position if position.respond_to? :position
|
26
|
+
super(msg, position)
|
27
|
+
self.cause = cause
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -145,14 +145,35 @@ module Mirah
|
|
145
145
|
duby_node
|
146
146
|
end
|
147
147
|
|
148
|
-
def dump_ast(node)
|
148
|
+
def dump_ast(node, call=nil)
|
149
149
|
encoded = nil
|
150
150
|
values = Mirah::AST::Unquote.extract_values do
|
151
151
|
encoded = Base64.encode64(Marshal.dump(node))
|
152
152
|
end
|
153
|
+
scope = call.scope.static_scope if call
|
153
154
|
result = Mirah::AST::Array.new(nil, node.position)
|
154
|
-
|
155
|
-
|
155
|
+
if encoded.size < 65535
|
156
|
+
result << Mirah::AST::String.new(result, node.position, encoded)
|
157
|
+
else
|
158
|
+
strings = Mirah::AST::StringConcat.new(result, node.position)
|
159
|
+
result << strings
|
160
|
+
while encoded.size >= 65535
|
161
|
+
chunk = encoded[0, 65535]
|
162
|
+
encoded[0, 65535] = ""
|
163
|
+
strings << Mirah::AST::String.new(strings, node.position, chunk)
|
164
|
+
end
|
165
|
+
strings << Mirah::AST::String.new(strings, node.position, encoded)
|
166
|
+
end
|
167
|
+
values.each do |value|
|
168
|
+
if call
|
169
|
+
scoped_value = Mirah::AST::ScopedBody.new(result, value.position)
|
170
|
+
scoped_value << value
|
171
|
+
scoped_value.static_scope = scope
|
172
|
+
else
|
173
|
+
scoped_value = value
|
174
|
+
end
|
175
|
+
result << scoped_value
|
176
|
+
end
|
156
177
|
return result
|
157
178
|
end
|
158
179
|
|
@@ -179,9 +200,33 @@ module Mirah
|
|
179
200
|
node
|
180
201
|
end
|
181
202
|
|
182
|
-
def constant(name)
|
203
|
+
def constant(name, array=false)
|
183
204
|
node = eval("Foo")
|
184
205
|
node.name = name
|
206
|
+
node.array = array
|
207
|
+
node
|
208
|
+
end
|
209
|
+
|
210
|
+
def cast(type, value)
|
211
|
+
if value.kind_of?(String)
|
212
|
+
value = Mirah::AST::Local.new(@extra_body, @extra_body.position, value)
|
213
|
+
end
|
214
|
+
fcall = eval("Foo()")
|
215
|
+
fcall.name = type
|
216
|
+
fcall.parameters = [value]
|
217
|
+
fcall
|
218
|
+
end
|
219
|
+
|
220
|
+
def string(value)
|
221
|
+
node = eval('"Foo"')
|
222
|
+
node.literal = value
|
223
|
+
node
|
224
|
+
end
|
225
|
+
|
226
|
+
def empty_array(type_node, size_node)
|
227
|
+
node = eval('int[0]')
|
228
|
+
node.type_node = type_node
|
229
|
+
node.size = size_node
|
185
230
|
node
|
186
231
|
end
|
187
232
|
|
@@ -206,6 +251,19 @@ module Mirah
|
|
206
251
|
append_node Mirah::AST::ClassDefinition.new(@extra_body, position, name, &block)
|
207
252
|
end
|
208
253
|
|
254
|
+
def defineClass(name, superclass=nil)
|
255
|
+
define_class(@extra_body.position, name) do |class_def|
|
256
|
+
superclass = constant(superclass)
|
257
|
+
superclass.parent = class_def
|
258
|
+
[superclass, body(class_def)]
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def body(parent=nil)
|
263
|
+
parent ||= @extra_body
|
264
|
+
Mirah::AST::Body.new(parent, parent.position)
|
265
|
+
end
|
266
|
+
|
209
267
|
def define_closure(position, name, enclosing_type)
|
210
268
|
target = self
|
211
269
|
parent = @extra_body
|