Class: Ibex::Frontend::DSL::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/frontend/dsl.rb,
sig/ibex/frontend/dsl.rbs

Overview

Mutable definition context whose output is an immutable-shape AST.

Instance Method Summary collapse

Constructor Details

#initialize(class_name:, superclass:, file:) ⇒ Builder

Returns a new instance of Builder.

RBS:

  • (class_name: Object, superclass: Object?, file: String) -> void

Parameters:

  • class_name: (Object)
  • superclass: (Object, nil)
  • file: (String)


26
27
28
29
30
31
32
33
34
# File 'lib/ibex/frontend/dsl.rb', line 26

def initialize(class_name:, superclass:, file:)
  @class_name = class_name.to_s
  @superclass = superclass&.to_s
  @file = file
  @line = 1
  @declarations = [] #: Array[AST::declaration]
  @rules = [] #: Array[AST::Rule]
  @user_code = Hash.new { |hash, key| hash[key] = Array.new(0) } #: AST::user_code
end

Instance Method Details

#convert(name, expression) ⇒ void

This method returns an undefined value.

RBS:

  • (Object name, Object expression) -> void

Parameters:

  • name (Object)
  • expression (Object)


77
78
79
80
81
# File 'lib/ibex/frontend/dsl.rb', line 77

def convert(name, expression)
  location = next_location
  pair = AST::Conversion.new(name: name.to_s, expression: expression.to_s, loc: location)
  @declarations << AST::Convert.new(pairs: [pair], loc: location)
end

#display(name, value) ⇒ void

This method returns an undefined value.

RBS:

  • (Object name, Object value) -> void

Parameters:

  • name (Object)
  • value (Object)


84
85
86
87
# File 'lib/ibex/frontend/dsl.rb', line 84

def display(name, value)
  @declarations << AST::DisplayName.new(name: name.to_s, value: (value, "display"),
                                        loc: next_location)
end

#expect(conflicts) ⇒ void

This method returns an undefined value.

RBS:

  • (Integer conflicts) -> void

Parameters:

  • conflicts (Integer)


47
48
49
# File 'lib/ibex/frontend/dsl.rb', line 47

def expect(conflicts)
  @declarations << AST::Expect.new(conflicts: conflicts, loc: next_location)
end

#group(*alternatives) ⇒ AST::Group

RBS:

  • (*Object alternatives) -> AST::Group

Parameters:

  • alternatives (Object)

Returns:



143
144
145
146
# File 'lib/ibex/frontend/dsl.rb', line 143

def group(*alternatives)
  normalized = alternatives.map { |alternative| Array(alternative).map { |item| normalize_item(item) } }
  AST::Group.new(alternatives: normalized, loc: next_location)
end

#inline(code) ⇒ AST::InlineAction

RBS:

  • (Object code) -> AST::InlineAction

Parameters:

  • code (Object)

Returns:



155
156
157
# File 'lib/ibex/frontend/dsl.rb', line 155

def inline(code)
  AST::InlineAction.new(code: code.to_s, loc: next_location)
end

#metadata_value(value, feature) ⇒ String

RBS:

  • (Object value, String feature) -> String

Parameters:

  • value (Object)
  • feature (String)

Returns:

  • (String)


186
187
188
189
190
191
192
193
194
# File 'lib/ibex/frontend/dsl.rb', line 186

def (value, feature)
  string = value.to_s
  raise ArgumentError, "#{feature} value must not be empty" if string.strip.empty?
  raise ArgumentError, "#{feature} value must be a single line" if string.match?(/[\r\n]/)
  raise ArgumentError, "#{feature} value must not contain control characters" if
    string.match?(/[[:cntrl:]]/)

  string
end

#next_locationLocation

RBS:

  • () -> Location

Returns:



177
178
179
180
181
# File 'lib/ibex/frontend/dsl.rb', line 177

def next_location
  location = Location.new(file: @file, line: @line, column: 1)
  @line += 1
  location
end

#normalize_item(item) ⇒ AST::item

RBS:

  • (Object item) -> AST::item

Parameters:

  • item (Object)

Returns:

  • (AST::item)


167
168
169
170
171
172
173
174
# File 'lib/ibex/frontend/dsl.rb', line 167

def normalize_item(item)
  if item.respond_to?(:loc)
    located_item = item #: AST::item
    return located_item
  end

  ref(item)
end

#on_error_reduce(*names) ⇒ void

This method returns an undefined value.

RBS:

  • (*Object names) -> void

Parameters:

  • names (Object)


62
63
64
# File 'lib/ibex/frontend/dsl.rb', line 62

def on_error_reduce(*names)
  @declarations << AST::OnErrorReduce.new(names: names.map(&:to_s), loc: next_location)
end

#optional(item) ⇒ AST::Optional

RBS:

  • (Object item) -> AST::Optional

Parameters:

  • item (Object)

Returns:



136
137
# File 'lib/ibex/frontend/dsl.rb', line 136

def optional(item) = AST::Optional.new(item: normalize_item(item), loc: next_location)
# @rbs (Object item) -> AST::Star

#options(*names) ⇒ void

This method returns an undefined value.

RBS:

  • (*Object names) -> void

Parameters:

  • names (Object)


42
43
44
# File 'lib/ibex/frontend/dsl.rb', line 42

def options(*names)
  @declarations << AST::Options.new(names: names.map(&:to_s), loc: next_location)
end

#param(name, semantic_type = nil) ⇒ void

This method returns an undefined value.

RBS:

  • (Object name, ?Object? semantic_type) -> void

Parameters:

  • name (Object)
  • semantic_type (Object, nil) (defaults to: nil)


96
97
98
99
# File 'lib/ibex/frontend/dsl.rb', line 96

def param(name, semantic_type = nil)
  type = semantic_type && (semantic_type, "%param")
  @declarations << AST::Parameter.new(name: name.to_s, semantic_type: type, loc: next_location)
end

#plus(item) ⇒ AST::Plus

RBS:

  • (Object item) -> AST::Plus

Parameters:

  • item (Object)

Returns:



140
# File 'lib/ibex/frontend/dsl.rb', line 140

def plus(item) = AST::Plus.new(item: normalize_item(item), loc: next_location)

#precedence(direction: :low_to_high) {|arg0| ... } ⇒ void

This method returns an undefined value.

RBS:

  • (?direction: Symbol) { (PrecedenceBuilder) -> void } -> void

Parameters:

  • direction: (Symbol) (defaults to: :low_to_high)

Yields:

Yield Parameters:

Yield Returns:

  • (void)


107
108
109
110
111
112
# File 'lib/ibex/frontend/dsl.rb', line 107

def precedence(direction: :low_to_high)
  location = next_location
  builder = PrecedenceBuilder.new(self)
  yield builder
  @declarations << AST::Precedence.new(direction: direction, levels: builder.levels, loc: location)
end

#printer(name, code) ⇒ void

This method returns an undefined value.

RBS:

  • (Object name, Object code) -> void

Parameters:

  • name (Object)
  • code (Object)


102
103
104
# File 'lib/ibex/frontend/dsl.rb', line 102

def printer(name, code)
  @declarations << AST::Printer.new(name: name.to_s, code: code.to_s, loc: next_location)
end

#recover_sync(*names) ⇒ void

This method returns an undefined value.

RBS:

  • (*Object names) -> void

Parameters:

  • names (Object)


57
58
59
# File 'lib/ibex/frontend/dsl.rb', line 57

def recover_sync(*names)
  @declarations << AST::Recovery.new(sync_tokens: names.map(&:to_s), loc: next_location)
end

#ref(name, as: nil) ⇒ AST::SymbolReference

RBS:

  • (Object name, ?as: Object?) -> AST::SymbolReference

Parameters:

  • name (Object)
  • as: (Object, nil) (defaults to: nil)

Returns:



131
132
133
# File 'lib/ibex/frontend/dsl.rb', line 131

def ref(name, as: nil)
  AST::SymbolReference.new(name: name.to_s, named_reference: as&.to_s, loc: next_location)
end

#rule(lhs) {|arg0| ... } ⇒ void

This method returns an undefined value.

RBS:

  • (Object lhs) { (RuleBuilder) -> void } -> void

Parameters:

  • lhs (Object)

Yields:

Yield Parameters:

Yield Returns:

  • (void)


115
116
117
118
119
120
121
122
# File 'lib/ibex/frontend/dsl.rb', line 115

def rule(lhs)
  location = next_location
  builder = RuleBuilder.new(self, location)
  yield builder
  @rules << AST::Rule.new(
    lhs: lhs.to_s, parameters: [], alternatives: builder.alternatives, loc: location, inline: false
  )
end

#separated_list(item, separator, nonempty: false) ⇒ AST::SeparatedList

RBS:

  • (Object item, Object separator, ?nonempty: bool) -> AST::SeparatedList

Parameters:

  • item (Object)
  • separator (Object)
  • nonempty: (Boolean) (defaults to: false)

Returns:



149
150
151
152
# File 'lib/ibex/frontend/dsl.rb', line 149

def separated_list(item, separator, nonempty: false)
  AST::SeparatedList.new(item: normalize_item(item), separator: normalize_item(separator),
                         nonempty: nonempty, loc: next_location)
end

#star(item) ⇒ AST::Star

RBS:

  • (Object item) -> AST::Star

Parameters:

  • item (Object)

Returns:



138
139
# File 'lib/ibex/frontend/dsl.rb', line 138

def star(item) = AST::Star.new(item: normalize_item(item), loc: next_location)
# @rbs (Object item) -> AST::Plus

#start(*names) ⇒ void

This method returns an undefined value.

RBS:

  • (*Object names) -> void

Parameters:

  • names (Object)


52
53
54
# File 'lib/ibex/frontend/dsl.rb', line 52

def start(*names)
  @declarations << AST::Start.new(names: names.map(&:to_s), loc: next_location)
end

#test_accept(source) ⇒ void

This method returns an undefined value.

RBS:

  • (Object source) -> void

Parameters:

  • source (Object)


67
68
69
# File 'lib/ibex/frontend/dsl.rb', line 67

def test_accept(source)
  @declarations << AST::GrammarTest.new(expectation: :accept, source: source.to_s, loc: next_location)
end

#test_reject(source) ⇒ void

This method returns an undefined value.

RBS:

  • (Object source) -> void

Parameters:

  • source (Object)


72
73
74
# File 'lib/ibex/frontend/dsl.rb', line 72

def test_reject(source)
  @declarations << AST::GrammarTest.new(expectation: :reject, source: source.to_s, loc: next_location)
end

#to_astAST::Root

RBS:

  • () -> AST::Root

Returns:



160
161
162
163
164
# File 'lib/ibex/frontend/dsl.rb', line 160

def to_ast
  location = Location.new(file: @file, line: 1, column: 1)
  AST::Root.new(class_name: @class_name, superclass: @superclass, declarations: @declarations,
                rules: @rules, user_code: @user_code, loc: location)
end

#token(*names) ⇒ void

This method returns an undefined value.

RBS:

  • (*Object names) -> void

Parameters:

  • names (Object)


37
38
39
# File 'lib/ibex/frontend/dsl.rb', line 37

def token(*names)
  @declarations << AST::Tokens.new(names: names.map(&:to_s), loc: next_location)
end

#type(name, value) ⇒ void

This method returns an undefined value.

RBS:

  • (Object name, Object value) -> void

Parameters:

  • name (Object)
  • value (Object)


90
91
92
93
# File 'lib/ibex/frontend/dsl.rb', line 90

def type(name, value)
  @declarations << AST::SemanticType.new(name: name.to_s, value: (value, "type"),
                                         loc: next_location)
end

#user_code(name, code) ⇒ void

This method returns an undefined value.

RBS:

  • (Object name, Object code) -> void

Parameters:

  • name (Object)
  • code (Object)


125
126
127
128
# File 'lib/ibex/frontend/dsl.rb', line 125

def user_code(name, code)
  key = name.to_s
  @user_code[key] << AST::UserCode.new(name: key, code: code.to_s, loc: next_location)
end