Class: Ibex::Runtime::CST::Kind

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/runtime/cst/kind.rb,
sig/ibex/runtime/cst/kind.rbs

Overview

Grammar-specific integer kind names and interval predicates.

Constant Summary collapse

EMPTY_FIELDS =

: Hash[String, field_slot]

Returns:

  • (Object)
empty_fields.freeze

Instance Method Summary collapse

Constructor Details

#initialize(metadata, slots: {}) ⇒ Kind

Returns a new instance of Kind.

RBS:

  • (metadata metadata, ?slots: Hash[Integer, slot]) -> void

Parameters:

  • metadata (metadata)
  • slots: (Hash[Integer, slot]) (defaults to: {})


43
44
45
46
47
48
49
50
51
52
53
# File 'lib/ibex/runtime/cst/kind.rb', line 43

def initialize(, slots: {})
  @names = .fetch(:names).dup.freeze
  @terminal_range = .fetch(:terminal_range).dup.freeze
  @nonterminal_range = .fetch(:nonterminal_range).dup.freeze
  @named = .fetch(:named).dup.freeze
  @named_nonterminals = .fetch(:named_nonterminals).dup.freeze
  @trivia = .fetch(:trivia).dup.freeze
  @synthetic = .fetch(:synthetic).dup.freeze
  @field_slots = build_field_slots(slots)
  freeze
end

Instance Method Details

#build_field_slots(slots) ⇒ Hash[Integer, Hash[String, field_slot]]

RBS:

  • (Hash[Integer, slot] slots) -> Hash[Integer, Hash[String, field_slot]]

Parameters:

  • slots (Hash[Integer, slot])

Returns:

  • (Hash[Integer, Hash[String, field_slot]])


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/ibex/runtime/cst/kind.rb', line 110

def build_field_slots(slots)
  values = {} #: Hash[Integer, Hash[String, field_slot]]
  slots.each_value do |slot|
    kind = slot.fetch(:node_kind)
    fields = slot.fetch(:fields).to_h do |name, field_slot|
      index = field_slot.is_a?(Hash) ? field_slot.fetch(:index) : field_slot
      [name, index]
    end.freeze
    previous = values[kind]
    raise ArgumentError, "conflicting CST fields for kind #{kind}" if previous && previous != fields

    values[kind] = fields
  end
  values.freeze
end

#error?(kind) ⇒ Boolean

RBS:

  • (Integer kind) -> bool

Parameters:

  • kind (Integer)

Returns:

  • (Boolean)


78
79
80
# File 'lib/ibex/runtime/cst/kind.rb', line 78

def error?(kind)
  kind == @synthetic["lexical_error_token"] || kind == @synthetic["error_node"]
end

#fetch(name) ⇒ Integer

RBS:

  • (String | Symbol name) -> Integer

Parameters:

  • name (String, Symbol)

Returns:

  • (Integer)


61
62
63
64
# File 'lib/ibex/runtime/cst/kind.rb', line 61

def fetch(name)
  key = name.to_s
  @named[key] || @trivia[key] || @synthetic.fetch(key)
end

#fields(kind) ⇒ Hash[String, field_slot]

Return the named field-to-physical-slot mapping for a kind.

RBS:

  • (Integer kind) -> Hash[String, field_slot]

Parameters:

  • kind (Integer)

Returns:

  • (Hash[String, field_slot])


90
# File 'lib/ibex/runtime/cst/kind.rb', line 90

def fields(kind) = @field_slots.fetch(kind, EMPTY_FIELDS)

#name(kind) ⇒ String

RBS:

  • (Integer kind) -> String

Parameters:

  • kind (Integer)

Returns:

  • (String)


56
57
58
# File 'lib/ibex/runtime/cst/kind.rb', line 56

def name(kind)
  @names.fetch(kind)
end

#nonterminal?(kind) ⇒ Boolean

RBS:

  • (Integer kind) -> bool

Parameters:

  • kind (Integer)

Returns:

  • (Boolean)


70
71
72
# File 'lib/ibex/runtime/cst/kind.rb', line 70

def nonterminal?(kind)
  within?(@nonterminal_range, kind) || @named_nonterminals.key?(kind)
end

#nonterminal_of(kind) ⇒ Integer

Map a named node kind to its physical nonterminal kind.

RBS:

  • (Integer kind) -> Integer

Parameters:

  • kind (Integer)

Returns:

  • (Integer)


84
85
86
# File 'lib/ibex/runtime/cst/kind.rb', line 84

def nonterminal_of(kind)
  @named_nonterminals.fetch(kind, kind)
end

#terminal?(kind) ⇒ Boolean

RBS:

  • (Integer kind) -> bool

Parameters:

  • kind (Integer)

Returns:

  • (Boolean)


67
# File 'lib/ibex/runtime/cst/kind.rb', line 67

def terminal?(kind) = within?(@terminal_range, kind)

#to_hmetadata

Return the serialization-safe kind metadata.

RBS:

  • () -> metadata

Returns:

  • (metadata)


94
95
96
97
98
99
100
101
# File 'lib/ibex/runtime/cst/kind.rb', line 94

def to_h
  value = {
    names: @names, terminal_range: @terminal_range, nonterminal_range: @nonterminal_range,
    named: @named, named_nonterminals: @named_nonterminals,
    trivia: @trivia, synthetic: @synthetic
  } #: metadata
  value.freeze
end

#trivia?(kind) ⇒ Boolean

RBS:

  • (Integer kind) -> bool

Parameters:

  • kind (Integer)

Returns:

  • (Boolean)


75
# File 'lib/ibex/runtime/cst/kind.rb', line 75

def trivia?(kind) = @trivia.value?(kind)

#within?(range, kind) ⇒ Boolean

RBS:

  • (Array[Integer] range, Integer kind) -> bool

Parameters:

  • range (Array[Integer])
  • kind (Integer)

Returns:

  • (Boolean)


127
128
129
# File 'lib/ibex/runtime/cst/kind.rb', line 127

def within?(range, kind)
  kind >= range.fetch(0) && kind < range.fetch(1)
end