Module: Ibex::NormalizeInlineExpansion

Included in:
Normalizer
Defined in:
lib/ibex/normalize/inline_expansion.rb,
sig/ibex/normalize/inline_expansion.rbs

Overview

Deterministically substitutes inline-rule productions before LR construction. rubocop:disable Metrics/ModuleLength -- expansion, action plans, and id remapping share one invariant.

Instance Method Summary collapse

Instance Method Details

#advance_inline_expansion_frame?(frames, definitions, worklist, variants, location) ⇒ Boolean

RBS:

  • (Array[Hash[Symbol, untyped]] frames, Hash[Integer, Array[IR::Production]] definitions, Array[Array[Hash[Symbol, untyped]]] worklist, Array[Hash[Symbol, untyped]] variants, IR::location? location) -> bool

Parameters:

  • frames (Array[Hash[Symbol, untyped]])
  • definitions (Hash[Integer, Array[IR::Production]])
  • worklist (Array[Array[Hash[Symbol, untyped]]])
  • variants (Array[Hash[Symbol, untyped]])
  • location (IR::location, nil)

Returns:

  • (Boolean)


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ibex/normalize/inline_expansion.rb', line 66

def advance_inline_expansion_frame?(frames, definitions, worklist, variants, location)
  frame = frames.fetch(-1)
  current = frame.fetch(:production)
  index = frame.fetch(:index)
  symbol_id = current.rhs.fetch(index)
  frame[:index] = index + 1
  unless @inline_symbol_ids.include?(symbol_id)
    frame[:variant] = append_inline_symbol(frame.fetch(:variant), symbol_id)
    return false
  end

  choices = definitions.fetch(symbol_id)
  if choices.one?
    frames << inline_expansion_frame(choices.fetch(0), symbol_id)
    return false
  end

  schedule_inline_choice_branches(frames, choices, symbol_id, worklist)
  enforce_inline_choice_limit!(variants.length + worklist.length, location)
  true
end

#append_inline_array(left, right) ⇒ Array[untyped]

RBS:

  • (Array[untyped] left, Array[untyped] right) -> Array[untyped]

Parameters:

  • left (Array[untyped])
  • right (Array[untyped])

Returns:

  • (Array[untyped])


193
194
195
# File 'lib/ibex/normalize/inline_expansion.rb', line 193

def append_inline_array(left, right)
  left.empty? ? right : left + right
end

#append_inline_symbol(variant, symbol_id) ⇒ Hash[Symbol, untyped]

RBS:

  • (Hash[Symbol, untyped] variant, Integer symbol_id) -> Hash[Symbol, untyped]

Parameters:

  • variant (Hash[Symbol, untyped])
  • symbol_id (Integer)

Returns:

  • (Hash[Symbol, untyped])


152
153
154
155
156
157
158
159
160
161
162
# File 'lib/ibex/normalize/inline_expansion.rb', line 152

def append_inline_symbol(variant, symbol_id)
  # @type self: Normalizer
  rhs = variant.fetch(:rhs)
  terminal = @symbols.fetch(symbol_id).terminal?
  variant.merge(
    rhs: rhs + [symbol_id],
    logical_refs: variant.fetch(:logical_refs) + [[:physical, rhs.length]],
    precedence_override: terminal ? nil : variant[:precedence_override],
    precedence_contributes: terminal || variant.fetch(:precedence_contributes)
  )
end

#charge_inline_expansion!(production) ⇒ void

This method returns an undefined value.

RBS:

  • (IR::Production production) -> void

Parameters:



368
369
370
371
# File 'lib/ibex/normalize/inline_expansion.rb', line 368

def charge_inline_expansion!(production)
  @inline_expansion_count += 1
  enforce_inline_choice_limit!(@inline_expansion_count, production.origin[:loc])
end

#clone_inline_expansion_frames(frames) ⇒ Array[Hash[Symbol, untyped]]

RBS:

  • (Array[Hash[Symbol, untyped]] frames) -> Array[Hash[Symbol, untyped]]

Parameters:

  • frames (Array[Hash[Symbol, untyped]])

Returns:

  • (Array[Hash[Symbol, untyped]])


123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/ibex/normalize/inline_expansion.rb', line 123

def clone_inline_expansion_frames(frames)
  frames.map do |frame|
    variant = frame.fetch(:variant)
    frame.merge(
      variant: variant.merge(
        rhs: variant.fetch(:rhs).dup,
        steps: variant.fetch(:steps).dup,
        logical_refs: variant.fetch(:logical_refs).dup
      )
    )
  end
end

#combine_inline_variant(parent, child) ⇒ Hash[Symbol, untyped]

RBS:

  • (Hash[Symbol, untyped] parent, Hash[Symbol, untyped] child) -> Hash[Symbol, untyped]

Parameters:

  • parent (Hash[Symbol, untyped])
  • child (Hash[Symbol, untyped])

Returns:

  • (Hash[Symbol, untyped])


165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ibex/normalize/inline_expansion.rb', line 165

def combine_inline_variant(parent, child)
  physical_offset = parent.fetch(:rhs).length
  step_offset = parent.fetch(:steps).length
  steps = combined_inline_steps(parent, child, physical_offset, step_offset)
  parent.merge(
    rhs: append_inline_array(parent.fetch(:rhs), child.fetch(:rhs)),
    steps: append_inline_array(parent.fetch(:steps), steps),
    logical_refs: parent.fetch(:logical_refs) + [
      remap_inline_reference(child.fetch(:output_ref), physical_offset, step_offset)
    ],
    inline_used: true,
    inline_rule: parent[:inline_rule] || child[:inline_rule],
    precedence_override: combined_inline_precedence(parent, child),
    precedence_contributes: parent.fetch(:precedence_contributes) ||
      child.fetch(:precedence_contributes),
    parameter: parent[:parameter] || child[:parameter]
  )
end

#combined_inline_precedence(parent, child) ⇒ Integer?

RBS:

  • (Hash[Symbol, untyped] parent, Hash[Symbol, untyped] child) -> Integer?

Parameters:

  • parent (Hash[Symbol, untyped])
  • child (Hash[Symbol, untyped])

Returns:

  • (Integer, nil)


198
199
200
201
202
# File 'lib/ibex/normalize/inline_expansion.rb', line 198

def combined_inline_precedence(parent, child)
  return child[:precedence_override] if child.fetch(:precedence_contributes)

  parent[:precedence_override]
end

#combined_inline_steps(parent, child, physical_offset, step_offset) ⇒ Array[Hash[Symbol, untyped]]

RBS:

  • (Hash[Symbol, untyped] parent, Hash[Symbol, untyped] child, Integer physical_offset, Integer step_offset) -> Array[Hash[Symbol, untyped]]

Parameters:

  • parent (Hash[Symbol, untyped])
  • child (Hash[Symbol, untyped])
  • physical_offset (Integer)
  • step_offset (Integer)

Returns:

  • (Array[Hash[Symbol, untyped]])


186
187
188
189
190
# File 'lib/ibex/normalize/inline_expansion.rb', line 186

def combined_inline_steps(parent, child, physical_offset, step_offset)
  return child.fetch(:steps) if physical_offset.zero? && step_offset.zero? && parent.fetch(:logical_refs).empty?

  remap_inline_steps(parent, child, physical_offset, step_offset)
end

#complete_inline_expansion_frame?(frames, variants, worklist, location) ⇒ Boolean

RBS:

  • (Array[Hash[Symbol, untyped]] frames, Array[Hash[Symbol, untyped]] variants, Array[Array[Hash[Symbol, untyped]]] worklist, IR::location? location) -> bool

Parameters:

  • frames (Array[Hash[Symbol, untyped]])
  • variants (Array[Hash[Symbol, untyped]])
  • worklist (Array[Array[Hash[Symbol, untyped]]])
  • location (IR::location, nil)

Returns:

  • (Boolean)


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/ibex/normalize/inline_expansion.rb', line 100

def complete_inline_expansion_frame?(frames, variants, worklist, location)
  frame = frames.fetch(-1)
  current = frame.fetch(:production)
  completed = finish_inline_precedence(frame.fetch(:variant), current)
  frames.pop
  if frames.empty?
    variants << completed
    enforce_inline_choice_limit!(variants.length + worklist.length, location)
    return true
  end

  choice = finish_inline_choice(completed, current, frame.fetch(:symbol_id))
  parent = frames.fetch(-1)
  parent[:variant] = combine_inline_variant(parent.fetch(:variant), choice)
  false
end

#composed_inline_action(production, physical_length, steps) ⇒ IR::Action

RBS:

  • (IR::Production production, Integer physical_length, Array[Hash[Symbol, untyped]]) -> IR::Action

Parameters:

  • production (IR::Production)
  • physical_length (Integer)
  • (Array[Hash[Symbol, untyped]])

Returns:



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/ibex/normalize/inline_expansion.rb', line 292

def composed_inline_action(production, physical_length, steps)
  action = production.action
  fragments = steps.map do |step|
    { kind: step.fetch(:kind), source: inline_source_provenance(step.fetch(:loc)) }
  end
  plan_steps = steps.map { |step| composition_plan_step(step, physical_length) }
  composition = {
    strategy: "sequence",
    fragments: fragments,
    plan: { version: 1, physical: physical_length, steps: plan_steps }
  } #: IR::action_composition
  IR::Action.new(
    code: action&.code || inline_implicit_code(production.rhs.length),
    location: action&.location || production.origin.fetch(:loc),
    composition: composition
  )
end

#composed_inline_production(production, variant, id) ⇒ IR::Production

RBS:

  • (IR::Production production, Hash[Symbol, untyped] variant, Integer id) -> IR::Production

Parameters:

  • production (IR::Production)
  • variant (Hash[Symbol, untyped])
  • id (Integer)

Returns:



276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/ibex/normalize/inline_expansion.rb', line 276

def composed_inline_production(production, variant, id)
  steps = variant.fetch(:steps)
  caller = inline_action_step(
    production, variant.fetch(:logical_refs), variant.fetch(:rhs).length, :rule, nil
  )
  all_steps = steps + [caller]
  action = composed_inline_action(production, variant.fetch(:rhs).length, all_steps)
  IR::Production.new(
    id: id, lhs: production.lhs, rhs: variant.fetch(:rhs), action: action,
    precedence_override: variant[:precedence_override], origin: production.origin,
    documentation: production.documentation,
    expansion: inline_production_expansion(production, variant)
  )
end

#composition_plan_step(step, physical_length) ⇒ Hash[Symbol, untyped]

RBS:

  • (Hash[Symbol, untyped] step, Integer physical_length) -> Hash[Symbol, untyped]

Parameters:

  • step (Hash[Symbol, untyped])
  • physical_length (Integer)

Returns:

  • (Hash[Symbol, untyped])


311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/ibex/normalize/inline_expansion.rb', line 311

def composition_plan_step(step, physical_length)
  {
    kind: step.fetch(:kind),
    rule: step[:rule],
    code: step[:code],
    loc: step.fetch(:loc),
    named_refs: step.fetch(:named_refs),
    context_length: step.fetch(:context_length),
    inputs: step.fetch(:inputs).map { |reference| resolve_inline_reference(reference, physical_length) },
    stack_inputs: step.fetch(:stack_inputs).map do |reference|
      resolve_inline_reference(reference, physical_length)
    end,
    lookahead: step.fetch(:lookahead) < physical_length ? step.fetch(:lookahead) : nil,
    result_var: step.fetch(:result_var),
    result_type: step[:result_type]
  }
end

#copy_inline_production(production, id) ⇒ IR::Production

RBS:

  • (IR::Production production, Integer id) -> IR::Production

Parameters:

Returns:



359
360
361
362
363
364
365
# File 'lib/ibex/normalize/inline_expansion.rb', line 359

def copy_inline_production(production, id)
  IR::Production.new(
    id: id, lhs: production.lhs, rhs: production.rhs, action: production.action,
    precedence_override: production.precedence_override, origin: production.origin,
    documentation: production.documentation, expansion: production.expansion
  )
end

#drain_inline_expansion_frames(frames, definitions, worklist, variants, location) ⇒ void

This method returns an undefined value.

RBS:

  • (Array[Hash[Symbol, untyped]] frames, Hash[Integer, Array[IR::Production]] definitions, Array[Array[Hash[Symbol, untyped]]] worklist, Array[Hash[Symbol, untyped]] variants, IR::location? location) -> void

Parameters:

  • frames (Array[Hash[Symbol, untyped]])
  • definitions (Hash[Integer, Array[IR::Production]])
  • worklist (Array[Array[Hash[Symbol, untyped]]])
  • variants (Array[Hash[Symbol, untyped]])
  • location (IR::location, nil)


51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ibex/normalize/inline_expansion.rb', line 51

def drain_inline_expansion_frames(frames, definitions, worklist, variants, location)
  loop do
    frame = frames.fetch(-1)
    current = frame.fetch(:production)
    if frame.fetch(:index) < current.rhs.length
      return if advance_inline_expansion_frame?(frames, definitions, worklist, variants, location)
    elsif complete_inline_expansion_frame?(frames, variants, worklist, location)
      return
    end
  end
end

#empty_inline_variant(production) ⇒ Hash[Symbol, untyped]

RBS:

  • (IR::Production production) -> Hash[Symbol, untyped]

Parameters:

Returns:

  • (Hash[Symbol, untyped])


137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/ibex/normalize/inline_expansion.rb', line 137

def empty_inline_variant(production)
  {
    rhs: [],
    steps: [],
    logical_refs: [],
    output_ref: nil,
    inline_used: false,
    inline_rule: nil,
    precedence_override: nil,
    precedence_contributes: false,
    parameter: production.expansion&.dig(:parameter)
  }
end

#enforce_inline_choice_limit!(count, location) ⇒ void

This method returns an undefined value.

RBS:

  • (Integer count, IR::location? location) -> void

Parameters:

  • count (Integer)
  • location (IR::location, nil)


374
375
376
377
378
379
# File 'lib/ibex/normalize/inline_expansion.rb', line 374

def enforce_inline_choice_limit!(count, location)
  # @type self: Normalizer
  return if count <= @max_inline_expansions

  fail_hash(location, "inline expansion limit of #{@max_inline_expansions} exceeded")
end

#expand_inline_production(production, definitions) ⇒ Array[Hash[Symbol, untyped]]

Explicit heap frames avoid tying grammar depth to the Ruby call stack. The single-definition path reuses its accumulated arrays, so a long acyclic chain remains linear in the size of its final action plan.

RBS:

  • (IR::Production production, Hash[Integer, Array[IR::Production]] definitions) -> Array[Hash[Symbol, untyped]]

Parameters:

Returns:

  • (Array[Hash[Symbol, untyped]])


37
38
39
40
41
42
43
44
45
46
# File 'lib/ibex/normalize/inline_expansion.rb', line 37

def expand_inline_production(production, definitions)
  # @type self: Normalizer
  variants = [] #: Array[Hash[Symbol, untyped]]
  worklist = [[inline_expansion_frame(production, nil)]] #: Array[Array[Hash[Symbol, untyped]]]
  until worklist.empty?
    frames = worklist.pop || raise(Ibex::Error, "internal inline expansion worklist underflow")
    drain_inline_expansion_frames(frames, definitions, worklist, variants, production.origin[:loc])
  end
  variants
end

#expand_inline_rulesvoid

This method returns an undefined value.

RBS:

  • () -> void



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/ibex/normalize/inline_expansion.rb', line 10

def expand_inline_rules
  # @type self: Normalizer
  return if @inline_symbol_ids.empty?

  definitions = @productions.group_by(&:lhs)
  expanded = [] #: Array[IR::Production]
  @productions.each do |production|
    next if @inline_symbol_ids.include?(production.lhs)

    variants = expand_inline_production(production, definitions)
    variants.each do |variant|
      if variant[:inline_used]
        charge_inline_expansion!(production)
        expanded << composed_inline_production(production, variant, expanded.length)
      else
        expanded << copy_inline_production(production, expanded.length)
      end
    end
  end
  rebuild_inline_symbols(expanded)
end

#finish_inline_choice(variant, production, symbol_id) ⇒ Hash[Symbol, untyped]

RBS:

  • (Hash[Symbol, untyped] variant, IR::Production production, Integer symbol_id) -> Hash[Symbol, untyped]

Parameters:

  • variant (Hash[Symbol, untyped])
  • production (IR::Production)
  • symbol_id (Integer)

Returns:

  • (Hash[Symbol, untyped])


243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/ibex/normalize/inline_expansion.rb', line 243

def finish_inline_choice(variant, production, symbol_id)
  steps = variant.fetch(:steps)
  rule = @inline_rule_by_symbol.fetch(symbol_id)
  step = inline_action_step(production, variant.fetch(:logical_refs), variant.fetch(:rhs).length, :inline, rule)
  steps << step
  variant.merge(
    steps: steps,
    output_ref: [:step, steps.length - 1],
    inline_used: true,
    inline_rule: rule
  )
end

#finish_inline_precedence(variant, production) ⇒ Hash[Symbol, untyped]

RBS:

  • (Hash[Symbol, untyped] variant, IR::Production production) -> Hash[Symbol, untyped]

Parameters:

Returns:

  • (Hash[Symbol, untyped])


233
234
235
236
237
238
239
# File 'lib/ibex/normalize/inline_expansion.rb', line 233

def finish_inline_precedence(variant, production)
  explicit = production.precedence_override
  variant.merge(
    precedence_override: explicit || variant[:precedence_override],
    precedence_contributes: !explicit.nil? || variant.fetch(:precedence_contributes)
  )
end

#inline_action_step(production, inputs, lookahead, kind, rule) ⇒ Hash[Symbol, untyped]

RBS:

  • (IR::Production production, Array[Array[Symbol | Integer]] inputs, Integer lookahead, Symbol kind, String? rule) -> Hash[Symbol, untyped]

Parameters:

  • production (IR::Production)
  • inputs (Array[Array[Symbol | Integer]])
  • lookahead (Integer)
  • kind (Symbol)
  • rule (String, nil)

Returns:

  • (Hash[Symbol, untyped])


258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/ibex/normalize/inline_expansion.rb', line 258

def inline_action_step(production, inputs, lookahead, kind, rule)
  action = production.action
  {
    kind: kind,
    rule: rule,
    code: action&.code,
    loc: action&.location || production.origin.fetch(:loc),
    named_refs: action&.named_refs || [],
    context_length: action&.context_length || 0,
    inputs: inputs,
    stack_inputs: [],
    lookahead: lookahead,
    result_var: @options.fetch(:result_var),
    result_type: @symbols.fetch(production.lhs).semantic_type
  }
end

#inline_expansion_frame(production, symbol_id) ⇒ Hash[Symbol, untyped]

RBS:

  • (IR::Production production, Integer? symbol_id) -> Hash[Symbol, untyped]

Parameters:

Returns:

  • (Hash[Symbol, untyped])


118
119
120
# File 'lib/ibex/normalize/inline_expansion.rb', line 118

def inline_expansion_frame(production, symbol_id)
  { production: production, symbol_id: symbol_id, index: 0, variant: empty_inline_variant(production) }
end

#inline_implicit_code(rhs_length) ⇒ String

RBS:

  • (Integer rhs_length) -> String

Parameters:

  • rhs_length (Integer)

Returns:

  • (String)


338
339
340
341
# File 'lib/ibex/normalize/inline_expansion.rb', line 338

def inline_implicit_code(rhs_length)
  expression = rhs_length.zero? ? "nil" : "val[0]"
  @options.fetch(:result_var) ? " result = #{expression} " : " #{expression} "
end

#inline_production_expansion(production, variant) ⇒ IR::production_expansion

RBS:

  • (IR::Production production, Hash[Symbol, untyped] variant) -> IR::production_expansion

Parameters:

Returns:

  • (IR::production_expansion)


349
350
351
352
353
354
355
356
# File 'lib/ibex/normalize/inline_expansion.rb', line 349

def inline_production_expansion(production, variant)
  existing = production.expansion
  {
    parameter: existing&.dig(:parameter) || variant[:parameter],
    inline: { rule: variant.fetch(:inline_rule) },
    include_chain: existing&.dig(:include_chain) || []
  }
end

#inline_source_provenance(location) ⇒ IR::source_provenance

RBS:

  • (IR::location location) -> IR::source_provenance

Parameters:

  • location (IR::location)

Returns:

  • (IR::source_provenance)


344
345
346
# File 'lib/ibex/normalize/inline_expansion.rb', line 344

def inline_source_provenance(location)
  { file: location[:file], root: @resolution&.root_directory, byte_span: nil }
end

#rebuild_inline_symbols(productions) ⇒ void

This method returns an undefined value.

RBS:

  • (Array[IR::Production] productions) -> void

Parameters:



382
383
384
385
386
387
388
389
390
# File 'lib/ibex/normalize/inline_expansion.rb', line 382

def rebuild_inline_symbols(productions)
  kept = @symbols.reject { |definition| @inline_symbol_ids.include?(definition.id) }
  id_map = kept.each_with_index.to_h { |definition, id| [definition.id, id] }
  @symbols = kept.each_with_index.map { |definition, id| remap_inline_symbol(definition, id) }
  @symbols_by_name = @symbols.to_h { |definition| [definition.name, definition] }
  @productions = productions.each_with_index.map do |production, id|
    remap_inline_production(production, id, id_map)
  end
end

#remap_inline_production(production, id, id_map) ⇒ IR::Production

RBS:

  • (IR::Production production, Integer id, Hash[Integer, Integer] id_map) -> IR::Production

Parameters:

  • production (IR::Production)
  • id (Integer)
  • id_map (Hash[Integer, Integer])

Returns:



403
404
405
406
407
408
409
410
411
# File 'lib/ibex/normalize/inline_expansion.rb', line 403

def remap_inline_production(production, id, id_map)
  IR::Production.new(
    id: id, lhs: id_map.fetch(production.lhs),
    rhs: production.rhs.map { |symbol_id| id_map.fetch(symbol_id) },
    action: production.action,
    precedence_override: production.precedence_override && id_map.fetch(production.precedence_override),
    origin: production.origin, documentation: production.documentation, expansion: production.expansion
  )
end

#remap_inline_reference(reference, physical_offset, step_offset) ⇒ Array[Symbol | Integer]

RBS:

  • (Array[Symbol | Integer] reference, Integer physical_offset, Integer step_offset) -> Array[Symbol | Integer]

Parameters:

  • reference (Array[Symbol | Integer])
  • physical_offset (Integer)
  • step_offset (Integer)

Returns:

  • (Array[Symbol | Integer])


224
225
226
227
228
229
230
# File 'lib/ibex/normalize/inline_expansion.rb', line 224

def remap_inline_reference(reference, physical_offset, step_offset)
  kind, index = reference
  raise Ibex::Error, "invalid inline slot kind" unless kind.is_a?(Symbol)
  raise Ibex::Error, "invalid inline slot reference" unless index.is_a?(Integer)

  [kind, index + (kind == :physical ? physical_offset : step_offset)]
end

#remap_inline_steps(parent, child, physical_offset, step_offset) ⇒ Array[Hash[Symbol, untyped]]

RBS:

  • (Hash[Symbol, untyped] parent, Hash[Symbol, untyped] child, Integer physical_offset, Integer step_offset) -> Array[Hash[Symbol, untyped]]

Parameters:

  • parent (Hash[Symbol, untyped])
  • child (Hash[Symbol, untyped])
  • physical_offset (Integer)
  • step_offset (Integer)

Returns:

  • (Array[Hash[Symbol, untyped]])


206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/ibex/normalize/inline_expansion.rb', line 206

def remap_inline_steps(parent, child, physical_offset, step_offset)
  child.fetch(:steps).map do |step|
    inputs = step.fetch(:inputs).map do |reference|
      remap_inline_reference(reference, physical_offset, step_offset)
    end
    stack_inputs = step.fetch(:stack_inputs).map do |reference|
      remap_inline_reference(reference, physical_offset, step_offset)
    end
    step.merge(
      inputs: inputs,
      stack_inputs: parent.fetch(:logical_refs) + stack_inputs,
      lookahead: step.fetch(:lookahead) + physical_offset
    )
  end
end

#remap_inline_symbol(definition, id) ⇒ IR::GrammarSymbol

RBS:

  • (IR::GrammarSymbol definition, Integer id) -> IR::GrammarSymbol

Parameters:

Returns:



393
394
395
396
397
398
399
400
# File 'lib/ibex/normalize/inline_expansion.rb', line 393

def remap_inline_symbol(definition, id)
  IR::GrammarSymbol.new(
    id: id, name: definition.name, kind: definition.kind, reserved: definition.reserved,
    precedence: definition.precedence, location: definition.location,
    display_name: definition.display_name, semantic_type: definition.semantic_type,
    documentation: definition.documentation
  )
end

#resolve_inline_reference(reference, physical_length) ⇒ Integer

RBS:

  • (Array[Symbol | Integer] reference, Integer physical_length) -> Integer

Parameters:

  • reference (Array[Symbol | Integer])
  • physical_length (Integer)

Returns:

  • (Integer)


330
331
332
333
334
335
# File 'lib/ibex/normalize/inline_expansion.rb', line 330

def resolve_inline_reference(reference, physical_length)
  kind, index = reference
  raise Ibex::Error, "invalid inline slot reference" unless index.is_a?(Integer)

  index + (kind == :step ? physical_length : 0)
end

#schedule_inline_choice_branches(frames, choices, symbol_id, worklist) ⇒ void

This method returns an undefined value.

RBS:

  • (Array[Hash[Symbol, untyped]] frames, Array[IR::Production] choices, Integer symbol_id, Array[Array[Hash[Symbol, untyped]]] worklist) -> void

Parameters:

  • frames (Array[Hash[Symbol, untyped]])
  • choices (Array[IR::Production])
  • symbol_id (Integer)
  • worklist (Array[Array[Hash[Symbol, untyped]]])


90
91
92
93
94
95
96
# File 'lib/ibex/normalize/inline_expansion.rb', line 90

def schedule_inline_choice_branches(frames, choices, symbol_id, worklist)
  choices.reverse_each do |choice|
    branch = clone_inline_expansion_frames(frames)
    branch << inline_expansion_frame(choice, symbol_id)
    worklist << branch
  end
end