Class: Ibex::Tables::CompactProductions
- Inherits:
-
Array
- Object
- Array
- Ibex::Tables::CompactProductions
- Defined in:
- lib/ibex/tables/compact_productions.rb,
sig/ibex/tables/compact_productions.rbs
Overview
Production metadata with parallel primitive arrays for the direct parser and a compatible Array-of-Hash surface for generic runtime consumers.
Constant Summary collapse
- VALUES_ACTION =
[Hash[Symbol, untyped]]
1- BORROWED_VALUES_ACTION =
2- LOCATION_ACTION =
4- COMPOSITION_ACTION =
8- POSITIONAL_ACTION =
16- VALID_FLAGS =
VALUES_ACTION | BORROWED_VALUES_ACTION | LOCATION_ACTION | COMPOSITION_ACTION | POSITIONAL_ACTION
- CORE_FIELDS =
%i[ lhs length action values_action borrowed_values_action location_action composition_action ].freeze
Instance Attribute Summary collapse
- #actions ⇒ Array[Symbol?] readonly
- #flags ⇒ Array[Integer] readonly
- #lengths ⇒ Array[Integer] readonly
- #lhs_ids ⇒ Array[Integer] readonly
Class Method Summary collapse
- .build(productions) ⇒ CompactProductions
- .packed(lhs_ids, lengths, flags, metadata: {}) ⇒ CompactProductions
Instance Method Summary collapse
- #action!(value) ⇒ Symbol?
- #decode(index, metadata) ⇒ Hash[Symbol, untyped]
- #direct_values? ⇒ Boolean
- #flags!(value) ⇒ Integer
-
#initialize(lhs_ids:, lengths:, actions:, flags:, metadata: {}) ⇒ CompactProductions
constructor
A new instance of CompactProductions.
- #nonnegative_integer!(value, name) ⇒ Integer
- #validate_markers! ⇒ void
- #validate_metadata!(metadata, size) ⇒ void
Constructor Details
#initialize(lhs_ids:, lengths:, actions:, flags:, metadata: {}) ⇒ CompactProductions
Returns a new instance of CompactProductions.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/ibex/tables/compact_productions.rb', line 78 def initialize(lhs_ids:, lengths:, actions:, flags:, metadata: {}) size = lhs_ids.length unless lengths.length == size && actions.length == size && flags.length == size raise ArgumentError, "compact production arrays must have the same length" end @lhs_ids = lhs_ids.map { |value| nonnegative_integer!(value, "lhs") }.freeze @lengths = lengths.map { |value| nonnegative_integer!(value, "length") }.freeze @actions = actions.map { |value| action!(value) }.freeze @flags = flags.map { |value| flags!(value) }.freeze validate_markers! (, size) super(Array.new(size) { |index| decode(index, [index]) }) freeze end |
Instance Attribute Details
#actions ⇒ Array[Symbol?] (readonly)
23 24 25 |
# File 'lib/ibex/tables/compact_productions.rb', line 23 def actions @actions end |
#flags ⇒ Array[Integer] (readonly)
24 25 26 |
# File 'lib/ibex/tables/compact_productions.rb', line 24 def flags @flags end |
#lengths ⇒ Array[Integer] (readonly)
22 23 24 |
# File 'lib/ibex/tables/compact_productions.rb', line 22 def lengths @lengths end |
#lhs_ids ⇒ Array[Integer] (readonly)
21 22 23 |
# File 'lib/ibex/tables/compact_productions.rb', line 21 def lhs_ids @lhs_ids end |
Class Method Details
.build(productions) ⇒ CompactProductions
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/ibex/tables/compact_productions.rb', line 28 def build(productions) lhs_ids = [] #: Array[Integer] lengths = [] #: Array[Integer] actions = [] #: Array[Symbol?] flags = [] #: Array[Integer] = {} #: Hash[Integer, Hash[Symbol, untyped]] productions.each_with_index do |production, index| lhs_ids << production.fetch(:lhs) lengths << production.fetch(:length) actions << production[:action] flags << flags_for(production) extra = production.except( :lhs, :length, :action, :values_action, :borrowed_values_action, :location_action, :composition_action ) [index] = extra unless extra.empty? end new(lhs_ids: lhs_ids, lengths: lengths, actions: actions, flags: flags, metadata: ) end |
.packed(lhs_ids, lengths, flags, metadata: {}) ⇒ CompactProductions
49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/ibex/tables/compact_productions.rb', line 49 def packed(lhs_ids, lengths, flags, metadata: {}) decoded_flags = PackedIntegers.decode_required(flags) actions = decoded_flags.each_index.map do |index| :"_ibex_action_#{index}" unless decoded_flags[index].zero? end new( lhs_ids: PackedIntegers.decode_required(lhs_ids), lengths: PackedIntegers.decode_required(lengths), actions: actions, flags: decoded_flags, metadata: ) end |
Instance Method Details
#action!(value) ⇒ Symbol?
109 110 111 112 113 |
# File 'lib/ibex/tables/compact_productions.rb', line 109 def action!(value) return value if value.nil? || value.is_a?(Symbol) raise ArgumentError, "compact production action must be a Symbol or nil" end |
#decode(index, metadata) ⇒ Hash[Symbol, untyped]
151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/ibex/tables/compact_productions.rb', line 151 def decode(index, ) entry = {} #: Hash[Symbol, untyped] entry[:lhs] = @lhs_ids[index] entry[:length] = @lengths[index] entry[:action] = @actions[index] value = @flags[index] entry[:values_action] = true if value.anybits?(VALUES_ACTION) entry[:borrowed_values_action] = true if value.anybits?(BORROWED_VALUES_ACTION) entry[:location_action] = true if value.anybits?(LOCATION_ACTION) entry[:composition_action] = true if value.anybits?(COMPOSITION_ACTION) entry[:positional_action] = true if value.anybits?(POSITIONAL_ACTION) entry.merge!() if entry.freeze end |
#direct_values? ⇒ Boolean
95 96 97 |
# File 'lib/ibex/tables/compact_productions.rb', line 95 def direct_values? @direct_values end |
#flags!(value) ⇒ Integer
116 117 118 119 120 |
# File 'lib/ibex/tables/compact_productions.rb', line 116 def flags!(value) return value if value.is_a?(Integer) && !value.negative? && value.nobits?(~VALID_FLAGS) raise ArgumentError, "compact production flags are invalid" end |
#nonnegative_integer!(value, name) ⇒ Integer
102 103 104 105 106 |
# File 'lib/ibex/tables/compact_productions.rb', line 102 def nonnegative_integer!(value, name) return value if value.is_a?(Integer) && !value.negative? raise ArgumentError, "compact production #{name} must be a nonnegative Integer" end |
#validate_markers! ⇒ void
This method returns an undefined value.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/ibex/tables/compact_productions.rb', line 123 def validate_markers! @flags.each_with_index do |value, index| borrowed = value.anybits?(BORROWED_VALUES_ACTION) values = value.anybits?(VALUES_ACTION) positional = value.anybits?(POSITIONAL_ACTION) raise ArgumentError, "borrowed production #{index} must be a values action" if borrowed && !values if positional && value.anybits?(VALUES_ACTION | LOCATION_ACTION | COMPOSITION_ACTION) raise ArgumentError, "positional production #{index} cannot combine action ABI flags" end end @direct_values = @actions.each_index.all? do |index| @actions[index].nil? || @flags[index].anybits?(VALUES_ACTION | POSITIONAL_ACTION) end end |
#validate_metadata!(metadata, size) ⇒ void
This method returns an undefined value.
139 140 141 142 143 144 145 146 147 148 |
# File 'lib/ibex/tables/compact_productions.rb', line 139 def (, size) .each do |index, entry| unless index.is_a?(Integer) && index.between?(0, size - 1) && entry.is_a?(Hash) raise ArgumentError, "compact production metadata is invalid" end if entry.keys.any? { |key| CORE_FIELDS.include?(key) } raise ArgumentError, "compact production metadata cannot replace core fields" end end end |