Class: Idl::UnaryOperatorExpressionAst

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

Overview

represents a unary operator

for example:

-value
~value
!bool_variable

Instance Method Summary collapse

Constructor Details

#initialize(input, interval, op, expression) ⇒ UnaryOperatorExpressionAst

Returns a new instance of UnaryOperatorExpressionAst.



3491
3492
3493
3494
3495
# File 'lib/idl/ast.rb', line 3491

def initialize(input, interval, op, expression)
  super(input, interval, [expression])

  @op = op
end

Instance Method Details

#expAstNode

Returns the operated-on expression.

Returns:

  • (AstNode)

    the operated-on expression



3581
3582
3583
# File 'lib/idl/ast.rb', line 3581

def exp
  expression
end

#expressionObject



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

def expression = @children[0]

#invert(symtab) ⇒ Object



3497
3498
3499
3500
3501
3502
3503
3504
3505
# File 'lib/idl/ast.rb', line 3497

def invert(symtab)
  unless symtab.nil?
    type_error "Not a boolean operator" unless type(symtab).kind == :boolean
  end

  type_error "Invert only works with !" unless op == "!"

  expression
end

#opString

Returns The operator.

Returns:

  • (String)

    The operator



3586
3587
3588
# File 'lib/idl/ast.rb', line 3586

def op
  @op
end

#to_idlString

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

Returns:

  • (String)

    IDL code for the node



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

def to_idl = "#{op}#{expression.to_idl}"

#type(symtab) ⇒ Type

Given a specific symbol table, return the type of this node.

Should not be called until #type_check is called with the same arguments

Parameters:

Returns:

  • (Type)

    The type of the node

Raises:



3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
# File 'lib/idl/ast.rb', line 3508

def type(symtab)
  case op
  when "-", "~"
    exp.type(symtab).clone
  when "!"
    if exp.type(symtab).const?
      ConstBoolType
    else
      BoolType
    end
  else
    internal_error "unhandled op #{op}"
  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:



3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
# File 'lib/idl/ast.rb', line 3524

def type_check(symtab)
  exp.type_check(symtab)

  case op
  when "-"
    unless [:bits, :bitfield].include?(exp.type(symtab).kind)
      type_error "#{exp.type(symtab)} does not support unary #{op} operator"
    end

    # type_error "Unary minus only works on signed values" unless exp.type(symtab).signed?
  when "~"
    unless [:bits, :bitfield].include?(exp.type(symtab).kind)
      type_error "#{exp.type(symtab)} does not support unary #{op} operator"
    end
  when "!"
    unless exp.type(symtab).convertable_to?(:boolean)
      if exp.type(symtab).kind == :bits
        type_error "#{exp.type(symtab)} does not support unary #{op} operator. Perhaps you want '#{exp.text_value} != 0'?"
      else
        type_error "#{exp.type(symtab)} does not support unary #{op} operator"
      end
    end
  else
    internal_error "Unhandled op #{op}"
  end
end

#value(symtab) ⇒ Object

Return the compile-time-known value of the node



3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
# File 'lib/idl/ast.rb', line 3552

def value(symtab)
  val = val_trunc =
    case op
    when "-"
      -exp.value(symtab)
    when "~"
      ~exp.value(symtab)
    when "!"
      !exp.value(symtab)
    else
      internal_error "Unhandled unary op #{op}"
    end
  if type(symtab).integral?
    val_trunc = val & ((1 << type(symtab).width) - 1)
    if type(symtab).signed? && ((((val_trunc >> (type(symtab).width - 1))) & 1) == 1)
      # need to make this negative!
      # take the twos compliment
      val_trunc = -((1 << type(symtab).width) - val_trunc)
    end
  end

  if op != "~"
    warn "#{text_value} is truncated due to insufficient bit width (from #{val} to #{val_trunc} on line #{lineno})" if val_trunc != val
  end

  val_trunc
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