Class: Idl::IsaAst
Overview
top-level AST node
Defined Under Namespace
Classes: Memo
Constant Summary
Constants inherited from AstNode
AstNode::Bits1Type, AstNode::Bits32Type, AstNode::Bits64Type, AstNode::BoolType, AstNode::ConstBoolType, AstNode::PossiblyUnknownBits1Type, AstNode::PossiblyUnknownBits32Type, AstNode::PossiblyUnknownBits64Type, AstNode::ReachableFunctionCacheType, AstNode::StringType, AstNode::VoidType
Instance Attribute Summary
Attributes inherited from AstNode
#children, #input, #interval, #parent
Class Method Summary collapse
Instance Method Summary collapse
-
#add_global_symbols(symtab) ⇒ Object
Add all the global symbols to symtab.
-
#bitfields ⇒ Array<AstNode>
List of all bitfield definitions.
- #const_eval?(symtab) ⇒ Boolean
- #definitions ⇒ Object
-
#enums ⇒ Array<AstNode>
List of all enum definitions.
-
#fetch ⇒ FetchAst
Fetch body.
-
#functions ⇒ Array<AstNode>
List of all function definitions.
-
#globals ⇒ Array<AstNode>
List of all global variable definitions.
-
#initialize(input, interval, children) ⇒ IsaAst
constructor
A new instance of IsaAst.
-
#replace_include!(include_ast, isa_ast) ⇒ Object
replaces an include statement with the ast in that file, making it a direct child of this IsaAst.
-
#structs ⇒ Array<AstNode>
List of all struct definitions.
- #to_h ⇒ Object
- #to_idl ⇒ Object
-
#type_check(symtab, strict:) ⇒ void
type check this node and all children.
Methods inherited from AstNode
#always_terminates?, #declaration?, #executable?, extract_base_var_name, #find_ancestor, #find_dst_registers, #find_referenced_csrs, #find_src_registers, #freeze_tree, #gen_adoc, #gen_option_adoc, #input_file, input_from_source_yaml, #inspect, #internal_error, interval_from_source_yaml, #lineno, #lines_around, #nullify_assignments, #pass_find_return_values, #path, #print_ast, #prune, #reachable_exceptions, #reachable_functions, #set_input_file, #set_input_file_unless_already_set, #source_line_file_offsets, #source_starting_offset, #source_yaml, #starting_line, #text_value, #truncation_warn, #type_error, #unindent, value_else, #value_else, value_error, #value_error, value_try, #value_try, write_back_nested
Constructor Details
Class Method Details
.from_h(yaml, source_mapper) ⇒ Object
1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 |
# File 'lib/idlc/ast.rb', line 1467 def self.from_h(yaml, source_mapper) raise "Bad YAML" unless yaml.key?("kind") && yaml.fetch("kind") == "isa" input = input_from_source_yaml(yaml.fetch("source"), source_mapper) interval = interval_from_source_yaml(yaml.fetch("source")) kids = yaml.fetch("children").map do |child_yaml| child_kind = child_yaml.fetch("kind") case child_kind when "global_var_decl" GlobalAst.from_h(child_yaml, source_mapper) when "global_var_decl_with_init" GlobalWithInitializationAst.from_h(child_yaml, source_mapper) when "enum_decl" EnumDefinitionAst.from_h(child_yaml, source_mapper) when "builtin_enum_decl" BuiltinEnumDefinitionAst.from_h(child_yaml, source_mapper) when "bitfield_decl" BitfieldDefinitionAst.from_h(child_yaml, source_mapper) when "struct_decl" StructDefinitionAst.from_h(child_yaml, source_mapper) when "function_decl" FunctionDefAst.from_h(child_yaml, source_mapper) when "fetch_decl" FetchAst.from_h(child_yaml, source_mapper) else raise "Unhandled ISA child: #{child_kind}" end end node = IsaAst.new(input, interval, kids) node.set_input_file(yaml.fetch("source").fetch("file")) node end |
Instance Method Details
#add_global_symbols(symtab) ⇒ Object
Add all the global symbols to symtab
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 |
# File 'lib/idlc/ast.rb', line 1409 def add_global_symbols(symtab) raise "Symtab is not at global scope" unless symtab.levels == 1 enums.each { |g| g.add_symbol(symtab); } bitfields.each { |g| g.add_symbol(symtab) } # Functions must be registered before globals so that global variable # initializers can call functions (e.g. FLEN = implemented?(...) ? 64 : 32). # FunctionDefAst#add_symbol only stores the FunctionType; it does not # evaluate the body, so adding functions before globals is safe. functions.each { |g| g.add_symbol(symtab) } globals.each { |g| g.add_symbol(symtab) } structs.each { |g| g.add_symbol(symtab) } end |
#bitfields ⇒ Array<AstNode>
Returns List of all bitfield definitions.
1388 |
# File 'lib/idlc/ast.rb', line 1388 def bitfields = definitions.grep(BitfieldDefinitionAst) |
#const_eval?(symtab) ⇒ Boolean
1379 |
# File 'lib/idlc/ast.rb', line 1379 def const_eval?(symtab) = false |
#definitions ⇒ Object
1376 |
# File 'lib/idlc/ast.rb', line 1376 def definitions = children |
#enums ⇒ Array<AstNode>
Returns List of all enum definitions.
1385 |
# File 'lib/idlc/ast.rb', line 1385 def enums = definitions.select { |e| e.is_a?(EnumDefinitionAst) || e.is_a?(BuiltinEnumDefinitionAst) } |
#fetch ⇒ FetchAst
Returns Fetch body.
1397 1398 1399 1400 1401 1402 1403 1404 |
# File 'lib/idlc/ast.rb', line 1397 def fetch @memo.fetch ||= begin raise "No fetch block defined" if definitions.grep(FetchAst).size == 0 definitions.grep(FetchAst)[0] end end |
#functions ⇒ Array<AstNode>
Returns List of all function definitions.
1394 |
# File 'lib/idlc/ast.rb', line 1394 def functions = definitions.grep(FunctionDefAst) |
#globals ⇒ Array<AstNode>
Returns List of all global variable definitions.
1382 |
# File 'lib/idlc/ast.rb', line 1382 def globals = definitions.select { |d| d.is_a?(GlobalWithInitializationAst) || d.is_a?(GlobalAst) } |
#replace_include!(include_ast, isa_ast) ⇒ Object
replaces an include statement with the ast in that file, making it a direct child of this IsaAst
1428 1429 1430 1431 1432 1433 1434 1435 |
# File 'lib/idlc/ast.rb', line 1428 def replace_include!(include_ast, isa_ast) # find the index of the child idx = children.index(include_ast) internal_error "Can't find include ast in children" if idx.nil? @children[idx] = isa_ast.children @children.flatten! end |
#structs ⇒ Array<AstNode>
Returns List of all struct definitions.
1391 |
# File 'lib/idlc/ast.rb', line 1391 def structs = definitions.grep(StructDefinitionAst) |
#to_h ⇒ Object
1460 1461 1462 1463 1464 |
# File 'lib/idlc/ast.rb', line 1460 def to_h = { "kind" => "isa", "children" => children.map(&:to_h), "source" => source_yaml } |
#to_idl ⇒ Object
1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 |
# File 'lib/idlc/ast.rb', line 1446 def to_idl <<~IDL %version 1.0 #{globals.map(&:to_idl).join("\n")} #{enums.map(&:to_idl).join("\n")} #{bitfields.map(&:to_idl).join("\n")} #{structs.map(&:to_idl).join("\n")} #{functions.map(&:to_idl).join("\n")} #{fetch.to_idl} IDL end |
#type_check(symtab, strict:) ⇒ 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
1438 1439 1440 1441 1442 1443 |
# File 'lib/idlc/ast.rb', line 1438 def type_check(symtab, strict:) definitions.each { |d| d.type_check(symtab, strict:) } fetch_blocks = definitions.grep(FetchAst) type_error "Multiple fetch blocks defined" if fetch_blocks.size > 1 end |