Class: Idl::VariableAssignmentAst
- Includes:
- Executable
- Defined in:
- lib/idlc/ast.rb,
lib/idlc/passes/prune.rb,
lib/idlc/passes/gen_adoc.rb
Overview
represents a scalar variable assignment statement
for example, these will result in a VariableAssignmentAst
# given: Bits<XLEN> zero;
zero = XLEN'b0
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
- #const_eval?(symtab) ⇒ Boolean
-
#execute(symtab) ⇒ void
“execute” the statement by updating the variables in the symbol table.
- #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object
-
#initialize(input, interval, lhs_ast, rhs_ast) ⇒ VariableAssignmentAst
constructor
A new instance of VariableAssignmentAst.
- #lhs ⇒ Object
- #nullify_assignments(symtab) ⇒ Object
- #prune(symtab, forced_type: nil) ⇒ Object
- #rhs ⇒ Object
- #to_h ⇒ Object
- #to_idl ⇒ Object
-
#type_check(symtab, strict:) ⇒ void
type check this node and all children.
- #var(symtab) ⇒ Object
Methods included from Executable
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, #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, lhs_ast, rhs_ast) ⇒ VariableAssignmentAst
Returns a new instance of VariableAssignmentAst.
2847 2848 2849 2850 |
# File 'lib/idlc/ast.rb', line 2847 def initialize(input, interval, lhs_ast, rhs_ast) super(input, interval, [lhs_ast, rhs_ast]) @vars = {} end |
Class Method Details
.from_h(yaml, source_mapper) ⇒ Object
2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 |
# File 'lib/idlc/ast.rb', line 2911 def self.from_h(yaml, source_mapper) raise "Bad YAML" unless yaml.key?("kind") && yaml.fetch("kind") == "var_assignment" input = input_from_source_yaml(yaml.fetch("source"), source_mapper) interval = interval_from_source_yaml(yaml.fetch("source")) VariableAssignmentAst.new( input, interval, T.cast(AstNode.from_h(yaml.fetch("var"), source_mapper), RvalueAst), T.cast(AstNode.from_h(yaml.fetch("value"), source_mapper), RvalueAst) ) end |
Instance Method Details
#const_eval?(symtab) ⇒ Boolean
2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 |
# File 'lib/idlc/ast.rb', line 2827 def const_eval?(symtab) return false if !lhs.const_eval?(symtab) if rhs.const_eval?(symtab) true else lhs_var = symtab.get(lhs.name) type_error "variable #{lhs.name} was not declared" if lhs_var.nil? || !lhs_var.is_a?(Var) lhs_var.const_incompatible! false end end |
#execute(symtab) ⇒ void
This method returns an undefined value.
“execute” the statement by updating the variables in the symbol table
2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 |
# File 'lib/idlc/ast.rb', line 2878 def execute(symtab) if lhs.is_a?(CsrWriteAst) value_error "CSR writes are never compile-time-known" else variable = var(symtab) internal_error "No variable #{lhs.text_value}" if variable.nil? unless variable.type.global? value_result = value_try do variable.value = rhs.value(symtab) end value_else(value_result) do variable.value = nil value_error "" end end end end |
#gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object
246 247 248 |
# File 'lib/idlc/passes/gen_adoc.rb', line 246 def gen_adoc(indent = 0, indent_spaces: 2) "#{' ' * indent}#{lhs.gen_adoc(0, indent_spaces:)} = #{rhs.gen_adoc(0, indent_spaces:)}" end |
#lhs ⇒ Object
2842 |
# File 'lib/idlc/ast.rb', line 2842 def lhs = T.cast(@children.fetch(0), IdAst) |
#nullify_assignments(symtab) ⇒ Object
137 138 139 140 141 142 |
# File 'lib/idlc/passes/prune.rb', line 137 def nullify_assignments(symtab) sym = symtab.get(lhs.text_value) unless sym.nil? sym.value = nil end end |
#prune(symtab, forced_type: nil) ⇒ Object
129 130 131 132 133 134 135 136 |
# File 'lib/idlc/passes/prune.rb', line 129 def prune(symtab, forced_type: nil) new_ast = VariableAssignmentAst.new(input, interval, lhs.dup, rhs.prune(symtab)) value_try do new_ast.execute(symtab) end # value_else: execute already sets nil on failure, nothing more to do new_ast end |
#rhs ⇒ Object
2845 |
# File 'lib/idlc/ast.rb', line 2845 def rhs = T.cast(@children.fetch(1), RvalueAst) |
#to_h ⇒ Object
2903 2904 2905 2906 2907 2908 |
# File 'lib/idlc/ast.rb', line 2903 def to_h = { "kind" => "var_assignment", "var" => lhs.to_h, "value" => rhs.to_h, "source" => source_yaml } |
#to_idl ⇒ Object
2900 |
# File 'lib/idlc/ast.rb', line 2900 def to_idl = "#{lhs.to_idl} = #{rhs.to_idl}" |
#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
2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 |
# File 'lib/idlc/ast.rb', line 2853 def type_check(symtab, strict:) lhs.type_check(symtab, strict:) lhs_var = symtab.get(lhs.name) type_error "Cannot assign to a const" if lhs_var.type.const? && !lhs_var.for_loop_iter? rhs.type_check(symtab, strict:) if lhs_var.type.const? && lhs_var.for_loop_iter? # also check that the rhs is const_eval type_error "Assignment would make iteration variable non-const" unless rhs.type(symtab).const? end unless rhs.type(symtab).convertable_to?(lhs.type(symtab)) type_error "Incompatible type in assignment (#{lhs.type(symtab)}, #{rhs.type(symtab)})" end end |
#var(symtab) ⇒ Object
2868 2869 2870 2871 2872 2873 2874 2875 |
# File 'lib/idlc/ast.rb', line 2868 def var(symtab) variable = @vars[symtab.name] if variable.nil? variable = symtab.get(lhs.text_value) @vars[symtab.name] = variable end variable end |