Class: Idl::BitfieldDefinitionAst

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

Overview

represents a bitfield defintion

# this will result in a BitfieldDefinitionAst
bitfield (64) Sv39PageTableEntry {
  N 63
  PBMT 62-61
  Reserved 60-54
  PPN2 53-28
  PPN1 27-19
  PPN0 18-10
  PPN 53-10 # in addition to the components, we define the entire PPN
  RSW  9-8
  D 7
  A 6
  G 5
  U 4
  X 3
  W 2
  R 1
  V 0
}

Instance Method Summary collapse

Constructor Details

#initialize(input, interval, name, size, fields) ⇒ BitfieldDefinitionAst

Returns a new instance of BitfieldDefinitionAst.



1254
1255
1256
1257
1258
1259
1260
# File 'lib/idl/ast.rb', line 1254

def initialize(input, interval, name, size, fields)
  super(input, interval, [name, size] + fields)

  @name = name
  @size = size
  @fields = fields
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



1304
1305
1306
1307
1308
1309
1310
1311
# File 'lib/idl/ast.rb', line 1304

def add_symbol(symtab)
  internal_error "All Bitfields should be declared at global scope" unless symtab.levels == 1

  t = type(symtab)
  internal_error "Type is nil" if t.nil?

  symtab.add!(name, t)
end

#element_namesArray<String>

Returns Array of all element names, in the same order as those from #element_ranges.

Returns:

  • (Array<String>)

    Array of all element names, in the same order as those from #element_ranges



1276
1277
1278
1279
1280
# File 'lib/idl/ast.rb', line 1276

def element_names
  return @element_names unless @element_names.nil?

  @element_names = @fields.map(&:name)
end

#element_ranges(symtab) ⇒ Array<Range>

Returns Array of all element ranges, in the same order as those from #element_names.

Returns:

  • (Array<Range>)

    Array of all element ranges, in the same order as those from #element_names.



1284
1285
1286
1287
1288
# File 'lib/idl/ast.rb', line 1284

def element_ranges(symtab)
  return @element_ranges unless @element_ranges.nil?

  @element_ranges = @fields.map{ |f| f.range(symtab) }
end

#freeze_tree(global_symtab) ⇒ Object

freeze the entire tree from further modification This is also an opportunity to pre-calculate anything that only needs global symbols

Parameters:

  • global_symtab (SymbolTable)

    Symbol table with global scope populated



1263
1264
1265
1266
1267
1268
# File 'lib/idl/ast.rb', line 1263

def freeze_tree(global_symtab)
  return if frozen?

  type(global_symtab)
  freeze
end

#nameString

Returns bitfield name.

Returns:

  • (String)

    bitfield name



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

def name = @name.text_value

#size(symtab) ⇒ Integer

Returns The number of bits in the Bitfield.

Returns:

  • (Integer)

    The number of bits in the Bitfield



1271
1272
1273
# File 'lib/idl/ast.rb', line 1271

def size(symtab)
  @size.value(symtab)
end

#to_idlString

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

Returns:

  • (String)

    IDL code for the node



1332
1333
1334
1335
1336
1337
1338
1339
# File 'lib/idl/ast.rb', line 1332

def to_idl
  idl = ["bitfield (#{@size.to_idl}) #{@name.to_idl} { "]
  @fields.each do |f|
    idl << f.to_idl
  end
  idl << "}"
  idl.join("\n")
end

#type(symtab) ⇒ Type

Return the type of this node

Parameters:

Returns:

  • (Type)

    The type of the node



1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
# File 'lib/idl/ast.rb', line 1314

def type(symtab)
  return @type unless @type.nil?

  @type = BitfieldType.new(
    name,
    @size.value(symtab),
    element_names,
    element_ranges(symtab)
  )
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:



1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
# File 'lib/idl/ast.rb', line 1291

def type_check(symtab)
  @size.type_check(symtab)
  @fields.each do |f|
    f.type_check(symtab)
    r = f.range(symtab)
    type_error "Field position (#{r}) is larger than the bitfield width (#{@size.value(symtab)} #{@size.text_value})" if r.first >= @size.value(symtab)
  end

  add_symbol(symtab)
  @name.type_check(symtab)
end

#value(_symtab, _archdef) ⇒ Integer, Boolean

Return the compile-time-known value of the node

Parameters:

Returns:

  • (Integer)

    if the compile-time-known value is an integer

  • (Boolean)

    if the compile-time-known value is a boolean

Raises:



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

def value(_symtab, _archdef) = raise AstNode::InternalError, "Bitfield defintions have no value"