Refactor semantics to provide a more block-y IR (#2349)

As a step towards builtins, provide more blocks. The intent is that any significant scope change will become its own NodeBlock. Builtins should produce the first set of node blocks.

Note, SemanticsIR as set up here isn't handling ordering of import processing -- I haven't thought that through much beyond that we probably want some lighter-weight processing of the parse tree to achieve it. But I think the essence of loading builtins first as their own IR block is... probably right?
This commit is contained in:
Jon Ross-Perkins
2022-10-25 17:23:04 -07:00
committed by GitHub
parent d51ca271af
commit 0755598fa8
14 changed files with 232 additions and 130 deletions
@@ -8,6 +8,7 @@
#include "common/check.h"
#include "toolchain/parser/parse_tree.h"
#include "toolchain/semantics/semantics_ir.h"
#include "toolchain/semantics/semantics_node.h"
namespace Carbon {
@@ -29,40 +30,27 @@ class SemanticsParseTreeHandler {
llvm::Optional<SemanticsNodeId> result_id;
};
auto Push(ParseTree::Node parse_node) -> void {
node_stack_.push_back({parse_node, llvm::None});
}
// Adds a node to the current block, returning the produced ID.
auto AddNode(SemanticsNode node) -> SemanticsNodeId;
auto Push(ParseTree::Node parse_node, SemanticsNode node) -> void {
auto node_id = semantics_->AddNode(node);
node_stack_.push_back({parse_node, node_id});
}
// Pushes a parse tree onto the stack. Used when there is no IR generated by
// the node.
auto Push(ParseTree::Node parse_node) -> void;
auto Pop(ParseNodeKind pop_parse_kind) -> void {
auto back = node_stack_.back();
auto parse_kind = parse_tree_->node_kind(back.parse_node);
CARBON_CHECK(parse_kind == pop_parse_kind)
<< "Expected " << pop_parse_kind << ", found " << parse_kind;
CARBON_CHECK(!back.result_id) << "Expected no result ID on " << parse_kind;
node_stack_.pop_back();
}
// Pushes a parse tree onto the stack, storing the SemanticsNode as the
// result.
auto Push(ParseTree::Node parse_node, SemanticsNode node) -> void;
auto PopWithResult() -> SemanticsNodeId {
auto back = node_stack_.back();
auto node_id = *back.result_id;
node_stack_.pop_back();
return node_id;
}
// Pops the top of the stack, verifying that it's the expected kind.
auto Pop(ParseNodeKind pop_parse_kind) -> void;
auto PopWithResult(ParseNodeKind pop_parse_kind) -> SemanticsNodeId {
auto back = node_stack_.back();
auto parse_kind = parse_tree_->node_kind(back.parse_node);
auto node_id = *back.result_id;
CARBON_CHECK(parse_kind == pop_parse_kind)
<< "Expected " << pop_parse_kind << ", found " << parse_kind;
node_stack_.pop_back();
return node_id;
}
// Pops the top of the stack, returning the result_id. Must only be called for
// nodes that have results.
auto PopWithResult() -> SemanticsNodeId;
// Pops the top of the stack, verifying that it's the expected kind and
// returning the result_id. Must only be called for nodes that have results.
auto PopWithResult(ParseNodeKind pop_parse_kind) -> SemanticsNodeId;
// Parse node handlers.
auto HandleDeclaredName(ParseTree::Node parse_node) -> void;
@@ -84,6 +72,10 @@ class SemanticsParseTreeHandler {
// The stack during Build. Will contain file-level parse nodes on return.
llvm::SmallVector<TraversalStackEntry> node_stack_;
// The stack of node blocks during build. Only updated on ParseTree nodes that
// affect the stack.
llvm::SmallVector<SemanticsNodeBlockId> node_block_stack_;
};
} // namespace Carbon