Class: Idl::VariableDeclarationAst
- Inherits:
-
AstNode
- Object
- AstNode
- Idl::VariableDeclarationAst
show all
- Includes:
- Declaration
- Defined in:
- lib/idlc/ast.rb,
lib/idlc/passes/prune.rb,
lib/idlc/passes/gen_adoc.rb
Overview
represents a single variable declaration (without assignment)
for example:
Bits<64> doubleword
Boolean has_property
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
#declaration?
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, #gen_option_adoc, #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, #text_value, #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, type_name, id, ary_size) ⇒ VariableDeclarationAst
Returns a new instance of VariableDeclarationAst.
3679
3680
3681
3682
3683
3684
3685
3686
3687
|
# File 'lib/idlc/ast.rb', line 3679
def initialize(input, interval, type_name, id, ary_size)
if ary_size.nil?
super(input, interval, [type_name, id])
else
super(input, interval, [type_name, id, ary_size])
end
@global = false
end
|
Class Method Details
.from_h(yaml, source_mapper) ⇒ Object
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
|
# File 'lib/idlc/ast.rb', line 3788
def self.from_h(yaml, source_mapper)
raise "Bad YAML" unless yaml.key?("kind") && yaml.fetch("kind") == "var_decl"
input = input_from_source_yaml(yaml.fetch("source"), source_mapper)
interval = interval_from_source_yaml(yaml.fetch("source"))
if yaml.fetch("type").key?("array_size")
VariableDeclarationAst.new(
input, interval,
T.cast(AstNode.from_h(yaml.fetch("type").fetch("element_type"), source_mapper), TypeNameAst),
T.cast(AstNode.from_h(yaml.fetch("name"), source_mapper), IdAst),
T.cast(AstNode.from_h(yaml.fetch("type").fetch("array_size"), source_mapper), RvalueAst)
)
else
VariableDeclarationAst.new(
input, interval,
T.cast(AstNode.from_h(yaml.fetch("type"), source_mapper), TypeNameAst),
T.cast(AstNode.from_h(yaml.fetch("name"), source_mapper), IdAst),
nil
)
end
end
|
Instance Method Details
#add_symbol(symtab) ⇒ Object
3755
3756
3757
3758
3759
3760
3761
3762
3763
|
# File 'lib/idlc/ast.rb', line 3755
def add_symbol(symtab)
if @global
symtab.add!(id.text_value, Var.new(id.text_value, decl_type(symtab), nil))
else
type_error "No Type '#{type_name.text_value}'" if decl_type(symtab).nil?
symtab.add(id.text_value, Var.new(id.text_value, decl_type(symtab), T.must(decl_type(symtab)).default))
end
end
|
#ary_size ⇒ Object
3665
|
# File 'lib/idlc/ast.rb', line 3665
def ary_size = children[2].nil? ? nil : T.cast(children.fetch(2), RvalueAst)
|
#const_eval?(symtab) ⇒ Boolean
3653
3654
3655
3656
|
# File 'lib/idlc/ast.rb', line 3653
def const_eval?(symtab)
add_symbol(symtab)
true
end
|
#decl_type(symtab) ⇒ Object
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
|
# File 'lib/idlc/ast.rb', line 3695
def decl_type(symtab)
dtype = type_name.type(symtab)
return nil if dtype.nil?
qualifiers = []
qualifiers << :const if T.must(id.text_value[0]).upcase == id.text_value[0]
qualifiers << :global if @global
dtype = Type.new(:enum_ref, enum_class: T.cast(dtype, EnumerationType), qualifiers:) if dtype.kind == :enum
unless ary_size.nil?
value_result = value_try do
dtype = Type.new(:array, width: T.cast(T.must(ary_size).value(symtab), Integer), sub_type: dtype, qualifiers:)
end
value_else(value_result) do
dtype = Type.new(:array, width: :unknown, sub_type: dtype, qualifiers:)
end
end
dtype
end
|
#gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object
179
180
181
|
# File 'lib/idlc/passes/gen_adoc.rb', line 179
def gen_adoc(indent = 0, indent_spaces: 2)
"#{' ' * indent}#{type_name.gen_adoc(0, indent_spaces:)} #{id.gen_adoc(0, indent_spaces:)}"
end
|
#id ⇒ Object
3662
|
# File 'lib/idlc/ast.rb', line 3662
def id = T.cast(children.fetch(1), IdAst)
|
#make_global ⇒ Object
3690
3691
3692
|
# File 'lib/idlc/ast.rb', line 3690
def make_global
@global = true
end
|
#name ⇒ Object
3668
|
# File 'lib/idlc/ast.rb', line 3668
def name = id.text_value
|
#prune(symtab, forced_type: nil) ⇒ Object
947
948
949
950
|
# File 'lib/idlc/passes/prune.rb', line 947
def prune(symtab, forced_type: nil)
add_symbol(symtab)
dup
end
|
#to_h ⇒ Object
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
|
# File 'lib/idlc/ast.rb', line 3776
def to_h = {
"kind" => "var_decl",
"type" => ary_size.nil? ? type_name.to_h : {
"kind" => "array_decl",
"array_size" => ary_size.to_h,
"element_type" => type_name.to_h
},
"name" => id.to_h,
"source" => source_yaml
}
|
#to_idl ⇒ Object
3767
3768
3769
3770
3771
3772
3773
|
# File 'lib/idlc/ast.rb', line 3767
def to_idl
if ary_size.nil?
"#{type_name.to_idl} #{id.to_idl}"
else
"#{type_name.to_idl} #{id.to_idl}[#{T.must(ary_size).to_idl}]"
end
end
|
#type(symtab) ⇒ Object
3720
|
# File 'lib/idlc/ast.rb', line 3720
def type(symtab) = decl_type(symtab)
|
#type_check(symtab, add_sym: true, strict:, is_function_arg: false) ⇒ 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
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
|
# File 'lib/idlc/ast.rb', line 3723
def type_check(symtab, add_sym: true, strict:, is_function_arg: false)
type_name.type_check(symtab, strict:)
dtype = type_name.type(symtab)
type_error "No type '#{type_name.text_value}'" if dtype.nil?
if !is_function_arg && id.text_value[0] == T.must(id.text_value[0]).upcase
type_error "Constants must be initialized at declaration"
end
type_error "Cannot use reserved word '#{id.text_value}' as variable name" if ReservedWords::RESERVED.include?(id.text_value)
unless ary_size.nil?
T.must(ary_size).type_check(symtab, strict:)
value_result = value_try do
T.must(ary_size).value(symtab)
end
value_else(value_result) do
type_error "Array size (#{T.must(ary_size).text_value}) must be a constant" unless T.must(ary_size).type(symtab).const?
end
end
add_symbol(symtab) if add_sym
id.type_check(symtab, strict:)
end
|
#type_name ⇒ Object
3659
|
# File 'lib/idlc/ast.rb', line 3659
def type_name = T.cast(children.fetch(0), TypeNameAst)
|