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, Object?]]
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, Object?]
- #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.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/ibex/tables/compact_productions.rb', line 81 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 46 47 48 |
# 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, Object?]] productions.each_with_index do |production, index| lhs = production.fetch(:lhs) #: Integer length = production.fetch(:length) #: Integer action = production[:action] #: Symbol? lhs_ids << lhs lengths << length actions << 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
52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/ibex/tables/compact_productions.rb', line 52 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?
112 113 114 115 116 |
# File 'lib/ibex/tables/compact_productions.rb', line 112 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, Object?]
154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/ibex/tables/compact_productions.rb', line 154 def decode(index, ) entry = {} #: Hash[Symbol, Object?] 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
98 99 100 |
# File 'lib/ibex/tables/compact_productions.rb', line 98 def direct_values? @direct_values end |
#flags!(value) ⇒ Integer
119 120 121 122 123 |
# File 'lib/ibex/tables/compact_productions.rb', line 119 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
105 106 107 108 109 |
# File 'lib/ibex/tables/compact_productions.rb', line 105 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.
126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/ibex/tables/compact_productions.rb', line 126 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.
142 143 144 145 146 147 148 149 150 151 |
# File 'lib/ibex/tables/compact_productions.rb', line 142 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 |