Class: Idl::AryElementAssignmentAst
- Includes:
- Executable
- Defined in:
- lib/idl/ast.rb
Overview
represents an array element assignement
for example:
X[rs1] = XLEN'd0
Instance Method Summary collapse
-
#execute(symtab) ⇒ void
“execute” the statement by updating the variables in the symbol table.
-
#execute_unknown(symtab) ⇒ void
“execute” the statement, forcing any variable assignments to an unknown state This is used down unknown conditional paths.
- #idx ⇒ Object
-
#initialize(input, interval, lhs, idx, rhs) ⇒ AryElementAssignmentAst
constructor
A new instance of AryElementAssignmentAst.
- #lhs ⇒ Object
- #rhs ⇒ Object
-
#to_idl ⇒ String
Return valid IDL representation of the node (and its subtree).
-
#type_check(symtab) ⇒ void
type check this node and all children.
Constructor Details
#initialize(input, interval, lhs, idx, rhs) ⇒ AryElementAssignmentAst
Returns a new instance of AryElementAssignmentAst.
1748 1749 1750 |
# File 'lib/idl/ast.rb', line 1748 def initialize(input, interval, lhs, idx, rhs) super(input, interval, [lhs, idx, rhs]) end |
Instance Method Details
#execute(symtab) ⇒ void
This method returns an undefined value.
“execute” the statement by updating the variables in the symbol table
1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 |
# File 'lib/idl/ast.rb', line 1787 def execute(symtab) lhs_type = lhs.type(symtab) return if lhs_type.global? case lhs_type.kind when :array idx_value = idx.value(symtab) lhs_value = lhs.value(symtab) value_result = value_try do lhs_value[idx_value] = rhs.value(symtab) end value_else(value_result) do lhs_value[idx_value] = nil value_error "right-hand side of array element assignment is unknown" end when :bits var = symtab.get(lhs.text_value) value_result = value_try do v = rhs.value(symtab) var.value = (lhs.value(symtab) & ~0) | ((v & 1) << idx.value(symtab)) end value_else(value_result) do var.value = nil end else internal_error "unexpected type for array element assignment" end end |
#execute_unknown(symtab) ⇒ void
This method returns an undefined value.
“execute” the statement, forcing any variable assignments to an unknown state This is used down unknown conditional paths.
1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 |
# File 'lib/idl/ast.rb', line 1817 def execute_unknown(symtab) case lhs.type(symtab).kind when :array lhs_value = lhs.value(symtab) value_result = value_try do idx_value = idx.value(symtab) value_result = value_try do lhs_value[idx_value] = rhs.value(symtab) end value_else(value_result) do lhs_value[idx_value] = nil value_error "right-hand side of array element assignment is unknown" end end value_else(value_result) do # the idx isn't known; the entire array must become unknown lhs_value.map! { |_v| nil } end when :bits var = symtab.get(lhs.text_value) value_result = value_try do v = rhs.value(symtab) var.value = (lhs.value & ~0) | ((v & 1) << idx.value(symtab)) end value_else(value_result) do var.value = nil end else internal_error "unexpected type for array element assignment" end end |
#idx ⇒ Object
1745 |
# File 'lib/idl/ast.rb', line 1745 def idx = @children[1] |
#lhs ⇒ Object
1744 |
# File 'lib/idl/ast.rb', line 1744 def lhs = @children[0] |
#rhs ⇒ Object
1746 |
# File 'lib/idl/ast.rb', line 1746 def rhs = @children[2] |
#to_idl ⇒ String
Return valid IDL representation of the node (and its subtree)
1850 |
# File 'lib/idl/ast.rb', line 1850 def to_idl = "#{lhs.to_idl}[#{idx.to_idl}] = #{rhs.to_idl}" |
#type_check(symtab) ⇒ 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
1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 |
# File 'lib/idl/ast.rb', line 1753 def type_check(symtab) lhs.type_check(symtab) unless [:array, :bits].include?(lhs.type(symtab).kind) type_error "#{lhs.text_value} must be an array or an integral type" end type_errpr "Assigning to a constant" if lhs.type(symtab).const? idx.type_check(symtab) type_error "Index must be integral" unless idx.type(symtab).integral? value_result = value_try do idx_value = idx.value(symtab) type_error "Array index (#{idx.text_value} = #{idx_value}) out of range (< #{var.type(symtab).width})" if idx_value >= lhs.type(symtab).width end # OK, doesn't need to be known rhs.type_check(symtab) case lhs.type(symtab).kind when :array unless rhs.type(symtab).convertable_to?(lhs.type(symtab).sub_type) type_error "Incompatible type in array assignment" end when :bits unless rhs.type(symtab).convertable_to?(Bits1Type) type_error "Incompatible type in integer slice assignement" end else internal_error "Unexpected type on array element assignment" end end |