Class: Idl::VariableDeclarationWithInitializationAst

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

Overview

reprents a single variable declaration with initialization

for example:

Bits<64> doubleword = 64'hdeadbeef
Boolean has_property = true

Instance Method Summary collapse

Constructor Details

#initialize(input, interval, type_name_ast, var_write_ast, ary_size, rval_ast) ⇒ VariableDeclarationWithInitializationAst

Returns a new instance of VariableDeclarationWithInitializationAst.



2358
2359
2360
2361
2362
2363
2364
2365
# File 'lib/idl/ast.rb', line 2358

def initialize(input, interval, type_name_ast, var_write_ast, ary_size, rval_ast)
  if ary_size.nil?
    super(input, interval, [type_name_ast, var_write_ast, rval_ast])
  else
    super(input, interval, [type_name_ast, var_write_ast, rval_ast, ary_size])
  end
  @global = false
end

Instance Method Details

#add_symbol(symtab) ⇒ Object

Add symbol(s) at the outermost scope of the symbol table

Parameters:

  • symtab (SymbolTable)

    Symbol table at the scope that the symbol(s) will be inserted



2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
# File 'lib/idl/ast.rb', line 2432

def add_symbol(symtab)
  if @global
    if lhs.text_value[0] == lhs.text_value[0].upcase
      # const, add the value if it's known
      value_result = value_try do
        symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab), rhs.value(symtab)))
      end
      value_else(value_result) do
        symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab)))
      end
    else
      # mutable globals never have a compile-time value
      symtab.add!(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab)))
    end
  else
    value_result = value_try do
      symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab), rhs.value(symtab)))
    end
    value_else(value_result) do
      symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab)))
    end
  end
end

#ary_sizeObject



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

def ary_size = @children[3]

#execute(symtab) ⇒ void

This method returns an undefined value.

“execute” the statement by updating the variables in the symbol table

Parameters:

  • symtab (SymbolTable)

    The symbol table for the context

Raises:

  • ValueError if some part of the statement cannot be executed at compile time



2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
# File 'lib/idl/ast.rb', line 2457

def execute(symtab)
  value_error "TODO: Array declaration" unless ary_size.nil?
  rhs_value = nil
  return if @global # never executed at compile time

  value_result = value_try do
    rhs_value = rhs.value(symtab)
  end
  value_else(value_result) do
    symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab), nil))
    value_error "value of right-hand side of variable initialization is unknown"
  end
  symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab), rhs_value))
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.

Parameters:

  • symtab (SymbolTable)

    The symbol table for the context

Raises:

  • ValueError if some part of the statement cannot be executed at compile time



2473
2474
2475
# File 'lib/idl/ast.rb', line 2473

def execute_unknown(symtab)
  symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab), nil))
end

#lhsObject



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

def lhs = @children[1]

#lhs_type(symtab) ⇒ Object



2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
# File 'lib/idl/ast.rb', line 2371

def lhs_type(symtab)
  decl_type = type_name.type(symtab).clone
  type_error "No type '#{type_name.text_value}' on line #{lineno}" if decl_type.nil?

  qualifiers = []
  qualifiers << :const if lhs.text_value[0].upcase == lhs.text_value[0]
  qualifiers << :global if @global

  decl_type = Type.new(:enum_ref, enum_class: decl_type) if decl_type.kind == :enum

  qualifiers.each do |q|
    decl_type.qualify(q)
  end

  unless ary_size.nil?
    value_result = value_try do
      decl_type = Type.new(:array, sub_type: decl_type, width: ary_size.value(symtab), qualifiers:)
    end
    value_else(value_result) do
      type_error "Array size must be known at compile time"
    end
  end

  decl_type
end

#make_globalObject



2367
2368
2369
# File 'lib/idl/ast.rb', line 2367

def make_global
  @global = true
end

#rhsObject



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

def rhs = @children[2]

#to_idlString

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

Returns:

  • (String)

    IDL code for the node



2478
2479
2480
2481
2482
2483
2484
# File 'lib/idl/ast.rb', line 2478

def to_idl
  if ary_size.nil?
    "#{type_name.to_idl} #{lhs.to_idl} = #{rhs.to_idl}"
  else
    "#{type_name.to_idl} #{lhs.to_idl}[#{ary_size.to_idl}] = #{rhs.to_idl}"
  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:



2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
# File 'lib/idl/ast.rb', line 2398

def type_check(symtab)
  rhs.type_check(symtab)

  type_name.type_check(symtab)

  ary_size&.type_check(symtab)

  decl_type = lhs_type(symtab)


  if decl_type.const?
    # this is a constant; ensure we are assigning a constant value
    value_result = value_try do
      symtab.add(lhs.text_value, Var.new(lhs.text_value, decl_type.clone, rhs.value(symtab)))
    end
    value_else(value_result) do
      unless rhs.type(symtab).const?
        type_error "Declaring constant with a non-constant value (#{e})"
      end
      symtab.add(lhs.text_value, Var.new(lhs.text_value, decl_type.clone))
    end
  else
    symtab.add(lhs.text_value, Var.new(lhs.text_value, decl_type.clone))
  end

  lhs.type_check(symtab)

  # now check that the assignment is compatible
  return if rhs.type(symtab).convertable_to?(decl_type)

  type_error "Incompatible type (#{decl_type}, #{rhs.type(symtab)}) in assignment"
end

#type_nameObject



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

def type_name = @children[0]