Class: Ibex::Tables::CompactActions
- Inherits:
-
Compact
- Object
- Compact
- Ibex::Tables::CompactActions
show all
- Defined in:
- lib/ibex/tables/compact_actions.rb,
sig/ibex/tables/compact_actions.rbs
Overview
Compact action table with an integer-coded hot representation and a
compatible decoded lookup surface for the generic runtime.
Constant Summary
collapse
- ACCEPT_CODE =
0
- ERROR_CODE =
-1
- SHIFT_BASE =
1
- REDUCE_BASE =
-2
- LEGACY_ERROR_CODE =
1
- LEGACY_SHIFT_BASE =
2
- LEGACY_REDUCE_BASE =
3
Constants inherited
from Compact
Ibex::Tables::Compact::DENSE_CELL_LIMIT
Instance Attribute Summary collapse
Attributes inherited from Compact
#checks, #dense_values, #dense_width, #offsets, #row_count, #values
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Compact
#lookup, #row, #self?.dense_layout, #self?.initialize, #self?.lookup, #self?.row
Constructor Details
#initialize(offsets:, codes:, checks:, row_count:, encoding: :legacy, column_count: nil) ⇒ CompactActions
Returns a new instance of CompactActions.
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/ibex/tables/compact_actions.rb', line 94
def initialize(offsets:, codes:, checks:, row_count:, encoding: :legacy, column_count: nil)
codes = codes.map { |code| self.class.legacy_to_signed(code) } if encoding == :legacy
unless %i[legacy signed].include?(encoding)
raise ArgumentError, "unknown compact action encoding #{encoding.inspect}"
end
@codes = codes.freeze
@column_count = column_count
@dense_codes = dense_action_layout(offsets, codes, checks, row_count, column_count)
decoded_cache = {} decoded = codes.map do |code|
code.nil? ? nil : decoded_cache[code] ||= self.class.unpack(code)
end
super(offsets: offsets, values: decoded, checks: checks, row_count: row_count)
end
|
Instance Attribute Details
#codes ⇒ Array[Integer?]
20
21
22
|
# File 'lib/ibex/tables/compact_actions.rb', line 20
def codes
@codes
end
|
#column_count ⇒ Integer?
22
23
24
|
# File 'lib/ibex/tables/compact_actions.rb', line 22
def column_count
@column_count
end
|
#dense_codes ⇒ Array[Integer?]?
21
22
23
|
# File 'lib/ibex/tables/compact_actions.rb', line 21
def dense_codes
@dense_codes
end
|
Class Method Details
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
# File 'lib/ibex/tables/compact_actions.rb', line 26
def build(rows)
packed_rows = rows.map do |row|
row.transform_values { |action| pack(action) }
end
layout = Compact.build(packed_rows, dense: false)
column_count = rows.flat_map(&:keys).max.to_i + 1
column_count = nil if (rows.length * column_count) > Compact::DENSE_CELL_LIMIT
new(
offsets: layout.offsets,
codes: layout.values,
checks: layout.checks,
row_count: layout.row_count,
encoding: :signed,
column_count: column_count
)
end
|
.legacy_to_signed(code) ⇒ Integer?
Convert codes emitted before signed compact actions without changing
their generated table literals.
.pack(action) ⇒ Integer?
57
58
59
60
61
62
63
64
65
66
67
|
# File 'lib/ibex/tables/compact_actions.rb', line 57
def pack(action)
return unless action
case action.fetch(0)
when :accept then ACCEPT_CODE
when :error then ERROR_CODE
when :shift then SHIFT_BASE + action.fetch(1)
when :reduce then REDUCE_BASE - action.fetch(1)
else raise ArgumentError, "unknown compact parser action #{action.inspect}"
end
end
|
.packed(offsets, codes, checks, row_count:, encoding: :legacy, column_count: nil) ⇒ CompactActions
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/ibex/tables/compact_actions.rb', line 45
def packed(offsets, codes, checks, row_count:, encoding: :legacy, column_count: nil)
new(
offsets: PackedIntegers.decode_required(offsets),
codes: encoding == :signed ? PackedIntegers.decode_signed(codes) : PackedIntegers.decode(codes),
checks: PackedIntegers.decode(checks),
row_count: row_count,
encoding: encoding,
column_count: column_count
)
end
|
.unpack(code) ⇒ Object
70
71
72
73
74
75
76
77
|
# File 'lib/ibex/tables/compact_actions.rb', line 70
def unpack(code)
return unless code
return [:accept].freeze if code == ACCEPT_CODE
return [:error].freeze if code == ERROR_CODE
return [:shift, code - SHIFT_BASE].freeze if code.positive?
[:reduce, REDUCE_BASE - code].freeze
end
|
Instance Method Details
#dense_action_layout(offsets, codes, checks, row_count, column_count) ⇒ Array[Integer?]?
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/ibex/tables/compact_actions.rb', line 114
def dense_action_layout(offsets, codes, checks, row_count, column_count)
return nil unless column_count
raise ArgumentError, "compact action column count must be positive" unless column_count.positive?
return nil if (row_count * column_count) > Compact::DENSE_CELL_LIMIT
dense = Array.new(row_count * column_count) checks.each_index do |index|
row = checks[index]
next unless row
column = index - offsets.fetch(row)
raise ArgumentError, "compact action column exceeds the dense row width" unless
column.between?(0, column_count - 1)
dense[(row * column_count) + column] = codes[index]
end
dense.freeze
end
|