Class: Idl::IdAst
- Inherits:
-
AstNode
show all
- Includes:
- Rvalue
- Defined in:
- lib/idlc/ast.rb,
lib/idlc/passes/prune.rb,
lib/idlc/passes/gen_adoc.rb,
lib/idlc/passes/gen_option_adoc.rb
Overview
an identifier
Used for variables
Constant Summary
Constants inherited
from AstNode
AstNode::Bits1Type, AstNode::Bits32Type, AstNode::Bits64Type, AstNode::BoolType, AstNode::ConstBoolType, AstNode::PossiblyUnknownBits1Type, AstNode::PossiblyUnknownBits32Type, AstNode::PossiblyUnknownBits64Type, AstNode::ReachableFunctionCacheType, AstNode::StringType, AstNode::VoidType
Instance Attribute Summary
Attributes inherited from AstNode
#children, #input, #interval, #parent
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Rvalue
#truncate, #values
Methods inherited from AstNode
#always_terminates?, #declaration?, #executable?, extract_base_var_name, #find_ancestor, #find_dst_registers, #find_referenced_csrs, #find_src_registers, #freeze_tree, #input_file, input_from_source_yaml, #inspect, #internal_error, interval_from_source_yaml, #lineno, #lines_around, #nullify_assignments, #pass_find_return_values, #path, #print_ast, #reachable_exceptions, #reachable_functions, #set_input_file, #set_input_file_unless_already_set, #source_line_file_offsets, #source_starting_offset, #source_yaml, #starting_line, #truncation_warn, #type_error, #unindent, value_else, #value_else, value_error, #value_error, value_try, #value_try, write_back_nested
Constructor Details
#initialize(input, interval, name) ⇒ IdAst
Returns a new instance of IdAst.
1090
1091
1092
1093
1094
|
# File 'lib/idlc/ast.rb', line 1090
def initialize(input, interval, name)
super(input, interval, EMPTY_ARRAY)
@name = name
@const = T.let((text_value[0] == T.must(text_value[0]).upcase), T::Boolean)
end
|
Class Method Details
.from_h(yaml, source_mapper) ⇒ Object
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
|
# File 'lib/idlc/ast.rb', line 1185
def self.from_h(yaml, source_mapper)
raise "Bad YAML" unless yaml.key?("kind") && yaml.fetch("kind") == "id"
input = input_from_source_yaml(yaml.fetch("source"), source_mapper)
interval = interval_from_source_yaml(yaml.fetch("source"))
if input.nil?
IdAst.new(yaml.fetch("name"), 0...yaml.fetch("name").length, yaml.fetch("name"))
else
raise "name does match input: '#{yaml.fetch("name")}', '#{input[T.must(interval)]}'" unless yaml.fetch("name") == input[T.must(interval)]
IdAst.new(input, T.must(interval), T.must(input[T.must(interval)]))
end
end
|
Instance Method Details
#const? ⇒ Boolean
1122
|
# File 'lib/idlc/ast.rb', line 1122
def const? = @const
|
#const_eval?(symtab) ⇒ Boolean
1080
|
# File 'lib/idlc/ast.rb', line 1080
def const_eval?(symtab) = const? || symtab.get(name).const_eval?
|
#gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object
163
164
165
|
# File 'lib/idlc/passes/gen_adoc.rb', line 163
def gen_adoc(indent = 0, indent_spaces: 2)
"#{' ' * indent}#{text_value}"
end
|
#gen_option_adoc ⇒ Object
97
98
99
|
# File 'lib/idlc/passes/gen_option_adoc.rb', line 97
def gen_option_adoc
text_value
end
|
#max_value(symtab) ⇒ Object
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
|
# File 'lib/idlc/ast.rb', line 1138
def max_value(symtab)
max = T.let(:unknown, T.any(Integer, Symbol))
value_result = value_try do
max = value(symtab)
end
value_else(value_result) do
var = symtab.get(name)
if !var.nil? && var.param?
param = T.must(symtab.param(text_value))
if param.schema.max_val_known?
max = param.schema.max_val
end
end
end
max
end
|
#min_value(symtab) ⇒ Object
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
|
# File 'lib/idlc/ast.rb', line 1156
def min_value(symtab)
min = T.let(:unknown, T.any(Integer, Symbol))
value_result = value_try do
min = value(symtab)
end
value_else(value_result) do
var = symtab.get(name)
if !var.nil? && var.param?
param = T.must(symtab.param(text_value))
if param.schema.min_val_known?
min = param.schema.min_val
end
end
end
min
end
|
#name ⇒ Object
1084
|
# File 'lib/idlc/ast.rb', line 1084
def name = @name
|
#prune(symtab, forced_type: nil) ⇒ Object
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
|
# File 'lib/idlc/passes/prune.rb', line 773
def prune(symtab, forced_type: nil)
value_result = value_try do
value_error "Not pruning struct types" if type(symtab).kind == :struct
v = value(symtab)
if type(symtab).kind == :bits
if type(symtab).width == :unknown
value_error "Unknown width"
end
end
return PruneHelpers.create_literal(symtab, v, type(symtab), forced_type: forced_type || type(symtab))
end
value_else(value_result) do
dup
end
end
|
#text_value ⇒ Object
1087
|
# File 'lib/idlc/ast.rb', line 1087
def text_value = @name
|
#to_h ⇒ Object
1178
1179
1180
1181
1182
|
# File 'lib/idlc/ast.rb', line 1178
def to_h = {
"kind" => "id",
"name" => name,
"source" => source_yaml
}
|
#to_idl ⇒ Object
1175
|
# File 'lib/idlc/ast.rb', line 1175
def to_idl = name
|
#type(symtab) ⇒ Object
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
|
# File 'lib/idlc/ast.rb', line 1104
def type(symtab)
return @type unless @type.nil?
type_error "Symbol '#{name}' not found" if symtab.get(name).nil?
sym = symtab.get(name)
if sym.is_a?(Type)
sym
elsif sym.is_a?(Var)
sym.type
else
internal_error "Unexpected object on the symbol table"
end
end
|
#type_check(symtab, strict:) ⇒ void
This method returns an undefined value.
type check this node and all children
Calls to #type and/or #value may depend on type_check being called first with the same symtab. If not, those functions may raise an AstNode::InternalError
1097
1098
1099
1100
|
# File 'lib/idlc/ast.rb', line 1097
def type_check(symtab, strict:)
type_error "Cannot use reserved word '#{name}' as variable name" if ReservedWords::RESERVED.include?(name)
type_error "no symbol named '#{name}'" if symtab.get(name).nil?
end
|
#value(symtab) ⇒ Object
Return the compile-time-known value of the node
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
|
# File 'lib/idlc/ast.rb', line 1125
def value(symtab)
var = symtab.get(name)
type_error "Variable '#{name}' was not found" if var.nil?
value_error "Value of '#{name}' not known" if var.value.nil?
v = var.value
value_error "Value of #{name} is unknown" if v == :unknown
v
end
|