Class: Idl::AryElementAccessAst

Inherits:
AstNode
  • Object
show all
Includes:
Rvalue
Defined in:
lib/idl/ast.rb

Instance Method Summary collapse

Constructor Details

#initialize(input, interval, var, index) ⇒ AryElementAccessAst

Returns a new instance of AryElementAccessAst.



1493
1494
1495
# File 'lib/idl/ast.rb', line 1493

def initialize(input, interval, var, index)
  super(input, interval, [var, index])
end

Instance Method Details

#indexObject



1491
# File 'lib/idl/ast.rb', line 1491

def index = @children[1]

#to_idlString

Return valid IDL representation of the node (and its subtree)

Returns:

  • (String)

    IDL code for the node



1556
# File 'lib/idl/ast.rb', line 1556

def to_idl = "#{var.to_idl}[#{index.to_idl}]"

#type(symtab) ⇒ Object



1527
1528
1529
1530
1531
1532
1533
1534
1535
# File 'lib/idl/ast.rb', line 1527

def type(symtab)
  if var.type(symtab).kind == :array
    var.type(symtab).sub_type
  elsif var.type(symtab).integral?
    Bits1Type
  else
    internal_error "Bad ary element access"
  end
end

#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

Parameters:

Raises:



1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
# File 'lib/idl/ast.rb', line 1498

def type_check(symtab)
  var.type_check(symtab)
  index.type_check(symtab)

  type_error "Array index must be integral" unless index.type(symtab).integral?

  if var.type(symtab).kind == :array
    value_result = value_try do
      index_value = index.value(symtab)
      if var.type(symtab).width != :unknown
        type_error "Array index out of range" if index_value >= var.type(symtab).width
      end
    end # Ok, doesn't need to be known

  elsif var.type(symtab).integral?
    if var.type(symtab).kind == :bits
      value_result = value_try do
        index_value = index.value(symtab)
        if index_value >= var.type(symtab).width
          type_error "Bits element index (#{index_value}) out of range (max #{var.type(symtab).width - 1}) in access '#{text_value}'"
        end
      end # OK, doesn need to be known
    end

  else
    type_error "Array element access can only be used with integral types and arrays"
  end
end

#value(symtab) ⇒ Object



1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
# File 'lib/idl/ast.rb', line 1537

def value(symtab)
  if var.type(symtab).integral?
    (var.value(symtab) >> index.value(symtab)) & 1
  else
    value_error "X registers are not compile-time-known" if var.text_value == "X"

    ary = var.value(symtab)
    # internal_error "Not an array" unless ary.type.kind == :array

    internal_error "Not an array (is a #{ary.class.name})" unless ary.is_a?(Array)

    idx = index.value(symtab)
    internal_error "Index out of range; make sure type_check is called" if idx >= ary.size

    ary[idx]
  end
end

#values(symtab) ⇒ Array<Integer>, ... Originally defined in module Rvalue

Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

For most AstNodes, this will just be a single-entry array

Parameters:

  • symtab (SymbolTable)

    The context for the evaulation

Returns:

  • (Array<Integer>)

    The complete list of compile-time-known values, when they are integral

  • (Array<Boolean>)

    The complete list of compile-time-known values, when they are booleans

  • (AstNode::ValueError)

    if the list of values is not knowable at compile time

#varObject



1490
# File 'lib/idl/ast.rb', line 1490

def var = @children[0]