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.
266
267
268
269
|
# File 'lib/mirah/ast/intrinsics.rb', line 266
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.
259
260
261
|
# File 'lib/mirah/ast/intrinsics.rb', line 259
def proxy
@proxy
end
|
Class Method Details
.new(*args, &block) ⇒ Object
261
262
263
264
|
# File 'lib/mirah/ast/intrinsics.rb', line 261
def self.new(*args, &block)
real_node = super
real_node.proxy = NodeProxy.new(real_node)
end
|
Instance Method Details
#annotate(type, class_name) ⇒ Object
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
|
# File 'lib/mirah/ast/intrinsics.rb', line 332
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
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
|
# File 'lib/mirah/ast/intrinsics.rb', line 314
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
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
443
444
445
|
# File 'lib/mirah/ast/intrinsics.rb', line 386
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
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
382
383
384
|
# File 'lib/mirah/ast/intrinsics.rb', line 355
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
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
# File 'lib/mirah/ast/intrinsics.rb', line 271
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
306
307
308
309
310
311
312
|
# File 'lib/mirah/ast/intrinsics.rb', line 306
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
|