Class: Mirah::AST::Arguments

Inherits:
Node
  • Object
show all
Defined in:
lib/mirah/ast/method.rb,
lib/mirah/compiler/method.rb

Instance Attribute Summary

Attributes inherited from Node

#children, #inferred_type, #newline, #parent, #position

Instance Method Summary collapse

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_children

Constructor Details

#initialize(parent, line_number, &block) ⇒ Arguments

Returns a new instance of Arguments.



24
25
26
# File 'lib/mirah/ast/method.rb', line 24

def initialize(parent, line_number, &block)
  super(parent, line_number, &block)
end

Instance Method Details

#arg_types_match(arg_node, child_index) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/mirah/ast/method.rb', line 40

def arg_types_match(arg_node, child_index)
  if RequiredArgument == arg_node && (child_index == 0 || child_index == 3)
    return true
  else
    return OptionalArgument == arg_node && child_index == 1
  end
end

#argsObject



94
95
96
97
98
# File 'lib/mirah/ast/method.rb', line 94

def args
  args = (required || []) + (opt_args || [])
  args << block_arg if block_arg
  return args
end

#compile(compiler, expression) ⇒ Object



19
20
21
22
23
24
# File 'lib/mirah/compiler/method.rb', line 19

def compile(compiler, expression)
  # TODO: what does it mean for a method to be an expression?
  args.each {|arg| compiler.declare_argument(arg.name, arg.inferred_type)} if args
rescue Exception => ex
  raise Mirah::InternalCompilerError.wrap(ex, self)
end

#infer(typer, expression) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/mirah/ast/method.rb', line 28

def infer(typer, expression)
  unless resolved?
    @inferred_type = args ? args.map {|arg| typer.infer(arg, true)} : []
    if @inferred_type.all?
      resolved!
    else
      typer.defer(self)
    end
  end
  @inferred_type
end

#merge_args(args, child_index) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/mirah/ast/method.rb', line 68

def merge_args(args, child_index)
  args.parent = self if Argument === args
  case args
  when Arguments
    args.children.each_with_index {|child, i| merge_args(child, i)}
  when ::Array
    args.each {|arg| merge_args(arg, child_index)}
  when RequiredArgument
    if child_index > 2
      self.required2 << args
    else
      self.required << args
    end
  when OptionalArgument
    self.opt_args << args
  when RestArgument
    raise "Multiple rest args" unless rest_arg.nil?
    self.rest_arg = args
  when BlockArgument
    raise "Multiple block args" unless block_arg.nil?
    self.block_arg = args
  else
    raise "Unknown argument type #{args.class}"
  end
end

#validate_child(args, child_index) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/mirah/ast/method.rb', line 48

def validate_child(args, child_index)
  if args.kind_of?(::Array)
    args.each_with_index do |arg, arg_index|
      if UnquotedValue === arg
        actual_arg = arg.f_arg
        if arg_types_match(actual_arg, child_index)
          args[arg_index] = actual_arg
          actual_arg.parent = self
        else
          args[arg_index, 1] = []
          merge_args(actual_arg, child_index)
        end
      end
    end
  elsif UnquotedValue == args
    @children[child_index] = nil
    merge_args(args.f_arg, child_index)
  end
end