Rewrite semantics towards a more pure instruction model (#2320)

This rewrites semantics towards a more pure instruction model, in pursuit of the simple instruction-style output.

I think I can get this approach to type-check as it goes along, but obviously this change doesn't prove that yet. I'm separating it out because it's a large rewrite of the semantics structure, tossing out a lot of what was there before. But I think it does help towards several requests, like setting up a clear path for consolidating duplicate identifiers and making the node style more standardized.

I expect to need to pass multiple args to function calls, that'd probably be storing vectors of args similar to how I'm showing identifiers and integer literals stored.

This removes the semantics namespace because (a) it was getting annoying writing the `::` everywhere, and (b) I think the leaning with Carbon is to avoid namespaces (@chandlerc asked not to put SemanticsIR/SemanticsFactory in a namespace, which is the crux of the issue). But, it's still necessary to avoid name conflicts so I just prefix everything with "Semantics" (still a lot of typing, but no `::`).
This commit is contained in:
Jon Ross-Perkins
2022-10-20 12:50:10 -07:00
committed by GitHub
parent f6248a4b6f
commit 1f8508204b
25 changed files with 541 additions and 645 deletions
+39 -40
View File
@@ -7,53 +7,52 @@
#include "common/check.h"
#include "llvm/Support/FormatVariadic.h"
#include "toolchain/lexer/tokenized_buffer.h"
#include "toolchain/semantics/semantics_node.h"
namespace Carbon {
auto SemanticsIR::Print(llvm::raw_ostream& out) const -> void {
PrintBlock(out, 0, root_block());
out << "\n";
}
auto SemanticsIR::PrintBlock(llvm::raw_ostream& out, int indent,
llvm::ArrayRef<Semantics::NodeRef> node_refs) const
-> void {
out << "{\n";
int child_indent = indent + 2;
for (const auto& node_ref : node_refs) {
out.indent(child_indent);
Print(out, child_indent, node_ref);
out << ",\n";
out << "identifiers = {\n";
for (int32_t i = 0; i < static_cast<int32_t>(identifiers_.size()); ++i) {
out.indent(2);
out << SemanticsIdentifierId(i) << " = \"" << identifiers_[i] << "\";\n";
}
out.indent(indent);
out << "}";
}
out << "},\n";
auto SemanticsIR::Print(llvm::raw_ostream& out, int indent,
Semantics::NodeRef node_ref) const -> void {
switch (node_ref.kind()) {
case Semantics::NodeKind::BinaryOperator:
nodes_.Get<Semantics::BinaryOperator>(node_ref).Print(out);
return;
case Semantics::NodeKind::Function:
nodes_.Get<Semantics::Function>(node_ref).Print(
out, indent,
[&](int block_indent, llvm::ArrayRef<Semantics::NodeRef> block) {
PrintBlock(out, block_indent, block);
});
return;
case Semantics::NodeKind::IntegerLiteral:
nodes_.Get<Semantics::IntegerLiteral>(node_ref).Print(out);
return;
case Semantics::NodeKind::Return:
nodes_.Get<Semantics::Return>(node_ref).Print(out);
return;
case Semantics::NodeKind::SetName:
nodes_.Get<Semantics::SetName>(node_ref).Print(out);
return;
case Semantics::NodeKind::Invalid:
CARBON_FATAL() << "Invalid NodeRef kind";
out << "integer_literals = {\n";
for (int32_t i = 0; i < static_cast<int32_t>(integer_literals_.size()); ++i) {
out.indent(2);
out << SemanticsIntegerLiteralId(i) << " = " << integer_literals_[i]
<< ";\n";
}
out << "},\n";
out << "nodes = {\n";
int indent = 2;
for (int32_t i = 0; i < static_cast<int32_t>(nodes_.size()); ++i) {
SemanticsNode node = nodes_[i];
// Adjust indent for block contents.
switch (node.kind()) {
case SemanticsNodeKind::CodeBlockStart():
case SemanticsNodeKind::FunctionDefinitionStart():
out.indent(indent);
indent += 2;
break;
case SemanticsNodeKind::CodeBlockEnd():
case SemanticsNodeKind::FunctionDefinitionEnd():
indent -= 2;
out.indent(indent);
break;
default:
// No indentation change.
out.indent(indent);
break;
}
out << SemanticsNodeId(i) << " = " << node << ";\n";
}
out << "}\n";
}
} // namespace Carbon