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.



3510
3511
3512
3513
3514
# File 'lib/idl/ast.rb', line 3510

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



3604
3605
3606
# File 'lib/idl/ast.rb', line 3604

def exp
  expression
end

#expressionObject



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

def expression = @children[0]

#invert(symtab) ⇒ Object



3516
3517
3518
3519
3520
3521
3522
3523
3524
# File 'lib/idl/ast.rb', line 3516

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



3609
3610
3611
# File 'lib/idl/ast.rb', line 3609

def op
  @op
end

#to_idlString

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

Returns:

  • (String)

    IDL code for the node



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

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:



3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
# File 'lib/idl/ast.rb', line 3527

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:



3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
# File 'lib/idl/ast.rb', line 3543

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



3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
# File 'lib/idl/ast.rb', line 3571

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
  t = type(symtab)
  if t.integral?
    if t.width == :unknown
      value_error("Unknown width for truncation")
    end
    val_trunc = val & ((1 << t.width) - 1)
    if t.signed? && ((((val_trunc >> (t.width - 1))) & 1) == 1)
      # need to make this negative!
      # take the twos compliment
      val_trunc = -((1 << t.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 evaluation

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