Class: Idl::VariableDeclarationAst

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

Overview

represents a single variable declaration (without assignment)

for example:

Bits<64> doubleword
Boolean has_property

Instance Method Summary collapse

Constructor Details

#initialize(input, interval, type_name, id, ary_size) ⇒ VariableDeclarationAst

Returns a new instance of VariableDeclarationAst.



2246
2247
2248
2249
2250
2251
2252
2253
2254
# File 'lib/idl/ast.rb', line 2246

def initialize(input, interval, type_name, id, ary_size)
  if ary_size.nil?
    super(input, interval, [type_name, id])
  else
    super(input, interval, [type_name, id, 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



2319
2320
2321
2322
2323
2324
2325
2326
2327
# File 'lib/idl/ast.rb', line 2319

def add_symbol(symtab)
  if @global
    # fill global with nil to prevent its use in compile-time evaluation
    symtab.add!(id.text_value, Var.new(id.text_value, decl_type(symtab), nil))
  else
    type_error "No Type '#{type_name.text_value}'" if decl_type(symtab).nil?
    symtab.add(id.text_value, Var.new(id.text_value, decl_type(symtab), decl_type(symtab).default))
  end
end

#ary_sizeObject



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

def ary_size = children[2]

#decl_type(symtab) ⇒ Object



2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
# File 'lib/idl/ast.rb', line 2260

def decl_type(symtab)
  dtype = type_name.type(symtab)

  return nil if dtype.nil?

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

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

  # dtype = dtype.clone.qualify(q.text_value.to_sym) unless q.empty?

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

  dtype
end

#idObject



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

def id = children[1]

#make_globalObject



2256
2257
2258
# File 'lib/idl/ast.rb', line 2256

def make_global
  @global = true
end

#nameObject



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

def name = id.text_value

#to_idlString

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

Returns:

  • (String)

    IDL code for the node



2330
2331
2332
2333
2334
2335
2336
# File 'lib/idl/ast.rb', line 2330

def to_idl
  if ary_size.nil?
    "#{type_name.to_idl} #{id.to_idl}"
  else
    "#{type_name.to_idl} #{id.to_idl}[#{ary_size.to_idl}]"
  end
end

#type(symtab) ⇒ Object



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

def type(symtab) = decl_type(symtab)

#type_check(symtab, add_sym = true) ⇒ 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:



2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
# File 'lib/idl/ast.rb', line 2289

def type_check(symtab, add_sym = true)
  type_name.type_check(symtab)
  dtype = type_name.type(symtab)

  type_error "No type '#{type_name.text_value}'" if dtype.nil?

  type_error "Constants must be initialized at declaration" if id.text_value[0] == id.text_value[0].upcase

  unless ary_size.nil?
    ary_size.type_check(symtab)
    value_result = value_try do
      ary_size.value(symtab)
    end
    value_else(value_result) do
      # if this is a fully configured ConfiguredArchitecture, this is an error because all constants are supposed to be known
      if symtab.cfg_arch.fully_configured?
        type_error "Array size (#{ary_size.text_value}) must be known at compile time"
      else
        # otherwise, it's ok that we don't know the value yet, as long as the value is a const
        type_error "Array size (#{ary_size.text_value}) must be a constant" unless ary_size.type(symtab).const?
      end
    end
  end

  add_symbol(symtab) if add_sym

  id.type_check(symtab)
end

#type_nameObject



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

def type_name = children[0]