Class: Mirah::AST::MacroDefinition
Instance Attribute Summary collapse
Attributes included from Named
#name
Attributes inherited from Node
#children, #inferred_type, #newline, #parent, #position
Class Method Summary
collapse
Instance Method Summary
collapse
-
#annotate(type, class_name) ⇒ Object
-
#argument_types ⇒ Object
-
#build_and_load_extension(parent, name, state) ⇒ Object
-
#build_ast(name, parent, transformer) ⇒ Object
-
#compile_ast(name, ast, transformer) ⇒ Object
-
#infer(typer, expression) ⇒ Object
-
#initialize(parent, line_number, name, &block) ⇒ MacroDefinition
constructor
A new instance of MacroDefinition.
-
#signature ⇒ Object
Methods included from Scoped
#containing_scope, #scope
Methods included from Named
#string_value, #to_s, #validate_name
Methods inherited from Node
#<<, ===, #[], #[]=, #_dump, _load, #_set_parent, child, child_name, #child_nodes, #each, #empty?, #expr?, #inferred_type!, #initialize_copy, #insert, #inspect, #inspect_children, #line_number, #log, #precompile, #resolve_if, #resolved!, #resolved?, #simple_name, #string_value, #temp, #to_s, #top_level?, #validate_child, #validate_children
Constructor Details
#initialize(parent, line_number, name, &block) ⇒ MacroDefinition
Returns a new instance of MacroDefinition.
263
264
265
266
|
# File 'lib/mirah/ast/intrinsics.rb', line 263
def initialize(parent, line_number, name, &block)
super(parent, line_number, &block)
self.name = name
end
|
Instance Attribute Details
#proxy ⇒ Object
Returns the value of attribute proxy.
256
257
258
|
# File 'lib/mirah/ast/intrinsics.rb', line 256
def proxy
@proxy
end
|
Class Method Details
.new(*args, &block) ⇒ Object
258
259
260
261
|
# File 'lib/mirah/ast/intrinsics.rb', line 258
def self.new(*args, &block)
real_node = super
real_node.proxy = NodeProxy.new(real_node)
end
|
Instance Method Details
#annotate(type, class_name) ⇒ Object
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
|
# File 'lib/mirah/ast/intrinsics.rb', line 329
def annotate(type, class_name)
node = type.unmeta.node
if node
extension = node.annotation('duby.anno.Extensions')
extension ||= begin
node.annotations << Annotation.new(
nil, nil, BiteScript::ASM::Type.getObjectType('duby/anno/Extensions'))
node.annotations[-1].runtime = false
node.annotations[-1]
end
extension['macros'] ||= []
macro = Annotation.new(nil, nil,
BiteScript::ASM::Type.getObjectType('duby/anno/Macro'))
macro['name'] = name
macro['signature'] = BiteScript::Signature.signature(*signature)
macro['class'] = class_name
extension['macros'] << macro
else
puts "Warning: No ClassDefinition for #{type.name}. Macros can't be loaded from disk."
end
end
|
#build_and_load_extension(parent, name, state) ⇒ Object
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
|
# File 'lib/mirah/ast/intrinsics.rb', line 311
def build_and_load_extension(parent, name, state)
transformer = Mirah::Transform::Transformer.new(state)
transformer.filename = name.gsub(".", "/")
orig_factory = Mirah::AST.type_factory
new_factory = orig_factory.dup
Mirah::AST.type_factory = new_factory
ast = build_ast(name, parent, transformer)
classes = compile_ast(name, ast, transformer)
loader = Mirah::Util::ClassLoader.new(
JRuby.runtime.jruby_class_loader, classes)
klass = loader.loadClass(name, true)
if state.save_extensions
annotate(parent, name)
end
Mirah::AST.type_factory = orig_factory
klass
end
|
#build_ast(name, parent, transformer) ⇒ Object
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
|
# File 'lib/mirah/ast/intrinsics.rb', line 383
def build_ast(name, parent, transformer)
ast = Mirah::AST.parse_ruby("begin;end")
ast = transformer.transform(ast, nil)
extension = transformer.define_class(position, name)
extension.implements(Mirah::AST.type(nil, 'duby.lang.compiler.Macro'))
extension.static_scope.import('duby.lang.compiler.Node', 'Node')
extension.static_scope.package = scope.static_scope.package
extension.define_constructor(
position,
['mirah', Mirah::AST.type(nil, 'duby.lang.compiler.Compiler')],
['call', Mirah::AST.type(nil, 'duby.lang.compiler.Call')]) do |c|
transformer.eval("@mirah = mirah;@call = call", '-', c, 'mirah', 'call')
end
node_type = Mirah::AST.type(nil, 'duby.lang.compiler.Node')
expand = extension.define_method(
position, 'expand', node_type)
args = []
arguments.each_with_index do |arg, i|
args << if arg.kind_of?(BlockArgument)
"@call.block"
else
"Node(args.get(#{i}))"
end
end
expand.body = transformer.eval(<<-end)
args = @call.arguments
_expand(#{args.join(', ')})
end
actual_args = arguments.map do |arg|
type = if arg.kind_of?(BlockArgument)
Mirah::AST.type(nil, 'duby.lang.compiler.Block')
else
node_type
end
[arg.name, type, arg.position]
end
m = extension.define_method(position, '_expand', node_type, *actual_args)
scope.static_scope.imports.each do |short, long|
m.static_scope.import(long, short)
end
scope.static_scope.search_packages.each do |package|
m.static_scope.import(package, '*')
end
m.body = self.body
ast.body = extension
ast
end
|
#compile_ast(name, ast, transformer) ⇒ Object
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
|
# File 'lib/mirah/ast/intrinsics.rb', line 352
def compile_ast(name, ast, transformer)
begin
typer = Mirah::JVM::Typer.new(transformer)
typer.infer(ast, false)
typer.resolve(true)
typer.errors.each do |e|
raise e
end
ensure
puts ast.inspect if transformer.state.verbose
end
compiler = Mirah::JVM::Compiler::JVMBytecode.new
ast.compile(compiler, false)
class_map = {}
compiler.generate do |outfile, builder|
bytes = builder.generate
name = builder.class_name.gsub(/\//, '.')
class_map[name] = Mirah::Util::ClassLoader.binary_string bytes
if transformer.state.save_extensions
outfile = "#{transformer.destination}#{outfile}"
FileUtils.mkdir_p(File.dirname(outfile))
File.open(outfile, 'wb') do |f|
f.write(bytes)
end
end
end
class_map
end
|
#infer(typer, expression) ⇒ Object
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
|
# File 'lib/mirah/ast/intrinsics.rb', line 268
def infer(typer, expression)
resolve_if(typer) do
self_type = scope.static_scope.self_type
extension_name = "%s$%s" % [self_type.name,
typer.transformer.tmp("Extension%s")]
klass = build_and_load_extension(self_type,
extension_name,
typer.transformer.state)
typer.known_types['self'] = self_type
arg_types = argument_types
macro = self_type.add_compiled_macro(klass, name, arg_types)
if arguments[-1].kind_of?(BlockArgument) && arguments[-1].optional?
arg_types.pop
self_type.add_method(name, arg_types, macro)
end
proxy.__inline__(Noop.new(parent, position))
proxy.infer(typer, expression)
end
end
|
#signature ⇒ Object
303
304
305
306
307
308
309
|
# File 'lib/mirah/ast/intrinsics.rb', line 303
def signature
args = argument_types
if args.size > 0 && args[-1].block?
args[-1] = BiteScript::ASM::Type.getObjectType('duby.lang.compiler.Block')
end
[nil] + args
end
|