Class: Ibex::Tables::CompactActions

Inherits:
Compact
  • Object
show all
Defined in:
lib/ibex/tables/compact_actions.rb

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 =

: Integer

0
ERROR_CODE =

: Integer

-1 #: Integer
SHIFT_BASE =

: Integer

1
REDUCE_BASE =

: Integer

-2 #: Integer

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

Constructor Details

#initialize(offsets:, codes:, checks:, row_count:, encoding: :signed, column_count: nil) ⇒ CompactActions

Returns a new instance of CompactActions.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/ibex/tables/compact_actions.rb', line 97

def initialize(offsets:, codes:, checks:, row_count:, encoding: :signed, column_count: nil)
  unless encoding == :signed
    raise ArgumentError, "unknown compact action encoding #{encoding.inspect}; expected :signed"
  end

  @codes = codes.freeze
  @column_count = column_count
  @dense_codes = dense_action_layout(offsets, codes, checks, row_count, column_count)
  decoded_cache = {} #: Hash[Integer, IR::runtime_action]
  decoded = codes.map do |code|
    next unless code

    unpacked = self.class.unpack(code) #: IR::runtime_action
    decoded_cache[code] ||= unpacked
  end
  super(offsets: offsets, values: decoded, checks: checks, row_count: row_count)
end

Instance Attribute Details

#codesObject (readonly)

: Array



16
17
18
# File 'lib/ibex/tables/compact_actions.rb', line 16

def codes
  @codes
end

#column_countObject (readonly)

: Integer?



18
19
20
# File 'lib/ibex/tables/compact_actions.rb', line 18

def column_count
  @column_count
end

#dense_codesObject (readonly)

: Array?



17
18
19
# File 'lib/ibex/tables/compact_actions.rb', line 17

def dense_codes
  @dense_codes
end

Class Method Details

.build(rows) ⇒ Object



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

def build(rows)
  packed_rows = rows.map do |row|
    row.transform_values { |action| pack(action) }
  end
  layout = Compact.build(packed_rows, dense: false)
  codes = layout.values #: Array[Integer?]
  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: codes,
    checks: layout.checks,
    row_count: layout.row_count,
    encoding: :signed,
    column_count: column_count
  )
end

.pack(action) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/ibex/tables/compact_actions.rb', line 58

def pack(action)
  return unless action

  case action.fetch(0)
  when :accept then ACCEPT_CODE
  when :error then ERROR_CODE
  when :shift
    state = action.fetch(1) #: Integer
    SHIFT_BASE + state
  when :reduce
    production = action.fetch(1) #: Integer
    REDUCE_BASE - production
  else raise ArgumentError, "unknown compact parser action #{action.inspect}"
  end
end

.packed(offsets, codes, checks, row_count:, encoding: :signed, column_count: nil) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/ibex/tables/compact_actions.rb', line 42

def packed(offsets, codes, checks, row_count:, encoding: :signed, column_count: nil)
  unless encoding == :signed
    raise ArgumentError, "unknown compact action encoding #{encoding.inspect}; expected :signed"
  end

  new(
    offsets: PackedIntegers.decode_required(offsets),
    codes: PackedIntegers.decode_signed(codes),
    checks: PackedIntegers.decode(checks),
    row_count: row_count,
    encoding: encoding,
    column_count: column_count
  )
end

.unpack(code) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/ibex/tables/compact_actions.rb', line 75

def unpack(code)
  return unless code

  if code == ACCEPT_CODE
    accept = [:accept].freeze #: [:accept]
    return accept
  end
  if code == ERROR_CODE
    error = [:error].freeze #: [:error]
    return error
  end
  if code.positive?
    shift = [:shift, code - SHIFT_BASE].freeze #: [:shift, Integer]
    return shift
  end

  [:reduce, REDUCE_BASE - code].freeze #: [:reduce, Integer]
end

Instance Method Details

#row(row) ⇒ Object

rubocop:disable Lint/UselessMethodDefinition -- narrows the inherited row contract for typed parser actions.



117
118
119
# File 'lib/ibex/tables/compact_actions.rb', line 117

def row(row)
  super #: Hash[Integer, IR::runtime_action]
end