Class: Ibex::Codegen::ActionMethodSource

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/codegen/action_method_source.rb

Overview

Builds semantic method source shared by runtime and static shadow output.

Instance Method Summary collapse

Constructor Details

#initialize(grammar, generated_action_abi: nil) ⇒ ActionMethodSource

Returns a new instance of ActionMethodSource.



15
16
17
18
# File 'lib/ibex/codegen/action_method_source.rb', line 15

def initialize(grammar, generated_action_abi: nil)
  @grammar = grammar
  @generated_action_abi = generated_action_abi || GeneratedActionABI::Cache.new
end

Instance Method Details

#column_sensitive?(source) ⇒ Boolean

Returns:

  • (Boolean)


95
96
97
98
99
100
101
102
# File 'lib/ibex/codegen/action_method_source.rb', line 95

def column_sensitive?(source)
  return false unless source.include?("<<")

  require "ripper"
  tokens = Object.const_get(:Ripper).__send__(:lex, source)
  # @type var tokens: Array[[[Integer, Integer], Symbol, String, untyped]]
  tokens.any? { |_position, event, _token, _state| event == :on_heredoc_beg }
end

#compiled_action_method_source(production) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ibex/codegen/action_method_source.rb', line 45

def compiled_action_method_source(production)
  action = production.action
  source = "private def _ibex_action_#{production.id}#{action_parameters(production)}; "
  append_parameter_values(source, production: production)
  return "#{source}#{default_value_expression(production)}\nend" unless action

  if action.context_length.positive?
    source << "val = _values.last(#{action.context_length}); "
    source << "_ibex_locations = _ibex_location_stack.last(#{action.context_length}); "
  end
  action.named_refs.each do |reference|
    source << "#{reference[:name]} = #{value_expression(production, reference[:index])}; "
  end
  append_named_values(source, action.named_refs)
  append_action_body(source, production, action)
  source << "\nend"
end

#composed_fragment_method_source(production, step, index) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/ibex/codegen/action_method_source.rb', line 21

def composed_fragment_method_source(production, step, index)
  source = "private def #{composed_fragment_name(production, index)}" \
           "(val, _values, _ibex_locations, _ibex_location_stack, _ibex_location); "
  append_parameter_values(source)
  context_length = step.fetch(:context_length)
  if context_length.positive?
    source << "val = _values.last(#{context_length}); "
    source << "_ibex_locations = _ibex_location_stack.last(#{context_length}); "
  end
  named_refs = step.fetch(:named_refs)
  named_refs.each { |reference| source << "#{reference[:name]} = val[#{reference[:index]}]; " }
  append_named_values(source, named_refs)
  source << "result = val[0]; " if step.fetch(:result_var)
  source << composed_semantic_code(step)
  source << "\nresult" if step.fetch(:result_var)
  source << "\nend"
end

#composed_fragment_name(production, index) ⇒ Object



40
41
42
# File 'lib/ibex/codegen/action_method_source.rb', line 40

def composed_fragment_name(production, index)
  "_ibex_inline_fragment_#{production.id}_#{index}"
end

#direct_action_method_source(production) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ibex/codegen/action_method_source.rb', line 64

def direct_action_method_source(production)
  action = production.action
  lines = [
    "private def _ibex_action_#{production.id}#{action_parameters(production)}"
  ]
  append_direct_parameter_values(lines, production: production)
  if action&.context_length&.positive?
    lines << "  val = _values.last(#{action.context_length})"
    lines << "  _ibex_locations = _ibex_location_stack.last(#{action.context_length})"
  end
  if action&.named_refs&.any?
    action.named_refs.each do |reference|
      lines << "  #{reference[:name]} = #{value_expression(production, reference[:index])}"
    end
    names = action.named_refs.map { |reference| reference[:name] }
    lines << "  _ibex_named_values = [#{names.join(', ')}]"
  end
  append_direct_action_body(lines, production, action)
  lines << "end"
  lines.join("\n")
end

#value_printer_method_source(symbol_id, printer) ⇒ Object



87
88
89
90
91
92
# File 'lib/ibex/codegen/action_method_source.rb', line 87

def value_printer_method_source(symbol_id, printer)
  source = "private def _ibex_value_printer_#{symbol_id}(value); "
  append_parameter_values(source)
  source << printer[:code]
  source << "\nend"
end