mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-29 09:04:55 +01:00
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 `::`).
138 lines
5.0 KiB
C++
138 lines
5.0 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#ifndef CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_H_
|
|
#define CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_H_
|
|
|
|
#include <cstdint>
|
|
|
|
#include "common/ostream.h"
|
|
#include "toolchain/semantics/semantics_node_kind.h"
|
|
|
|
namespace Carbon {
|
|
|
|
// Type-safe storage of Node IDs.
|
|
struct SemanticsNodeId {
|
|
SemanticsNodeId() : id(-1) {}
|
|
explicit SemanticsNodeId(int32_t id) : id(id) {}
|
|
SemanticsNodeId(SemanticsNodeId const&) = default;
|
|
auto operator=(const SemanticsNodeId& other) -> SemanticsNodeId& = default;
|
|
|
|
void Print(llvm::raw_ostream& out) const { out << "%" << id; }
|
|
|
|
int32_t id;
|
|
};
|
|
|
|
// Type-safe storage of identifiers.
|
|
struct SemanticsIdentifierId {
|
|
SemanticsIdentifierId() : id(-1) {}
|
|
explicit SemanticsIdentifierId(int32_t id) : id(id) {}
|
|
|
|
void Print(llvm::raw_ostream& out) const { out << "%s" << id; }
|
|
|
|
int32_t id;
|
|
};
|
|
|
|
// Type-safe storage of integer literals.
|
|
struct SemanticsIntegerLiteralId {
|
|
SemanticsIntegerLiteralId() : id(-1) {}
|
|
explicit SemanticsIntegerLiteralId(int32_t id) : id(id) {}
|
|
|
|
void Print(llvm::raw_ostream& out) const { out << "%s" << id; }
|
|
|
|
int32_t id;
|
|
};
|
|
|
|
struct SemanticsTwoNodeIds {
|
|
SemanticsNodeId nodes[2];
|
|
};
|
|
|
|
union SemanticsNodeArgs {
|
|
struct None {};
|
|
|
|
SemanticsNodeArgs() : no_args() {}
|
|
explicit SemanticsNodeArgs(SemanticsNodeId one_node) : one_node(one_node) {}
|
|
explicit SemanticsNodeArgs(SemanticsTwoNodeIds two_nodes)
|
|
: two_nodes(two_nodes) {}
|
|
explicit SemanticsNodeArgs(SemanticsIdentifierId identifier)
|
|
: identifier(identifier) {}
|
|
explicit SemanticsNodeArgs(SemanticsIntegerLiteralId integer_literal)
|
|
: integer_literal(integer_literal) {}
|
|
|
|
None no_args;
|
|
SemanticsNodeId one_node;
|
|
SemanticsTwoNodeIds two_nodes;
|
|
SemanticsIdentifierId identifier;
|
|
SemanticsIntegerLiteralId integer_literal;
|
|
};
|
|
// TODO: This is currently 8 bytes only because of two_nodes; others are only 4
|
|
// bytes. The NodeKind is 1 byte; if we reduced this structure to 7 bytes (3.5
|
|
// bytes per node), we could potentially change SemanticsNode from 12 bytes to 8
|
|
// bytes. This may be worth investigating further.
|
|
static_assert(sizeof(SemanticsNodeArgs) == 8, "Unexpected OneOfArgs size");
|
|
|
|
// The standard structure for nodes.
|
|
class SemanticsNode {
|
|
public:
|
|
// Define factory functions for each node kind. These should improve type
|
|
// safety by enforcing argument counts.
|
|
// `clang-format` has a bug with spacing around `->` returns here. See
|
|
// https://bugs.llvm.org/show_bug.cgi?id=48320 for details.
|
|
#define CARBON_SEMANTICS_MAKE_no_args(Name) \
|
|
static auto Make##Name()->SemanticsNode { \
|
|
return SemanticsNode(SemanticsNodeKind::Name(), SemanticsNodeArgs()); \
|
|
}
|
|
#define CARBON_SEMANTICS_MAKE_one_node(Name) \
|
|
static auto Make##Name(SemanticsNodeId one_node)->SemanticsNode { \
|
|
return SemanticsNode(SemanticsNodeKind::Name(), \
|
|
SemanticsNodeArgs(one_node)); \
|
|
}
|
|
#define CARBON_SEMANTICS_MAKE_two_nodes(Name) \
|
|
static auto Make##Name(SemanticsNodeId node1, SemanticsNodeId node2) \
|
|
->SemanticsNode { \
|
|
return SemanticsNode( \
|
|
SemanticsNodeKind::Name(), \
|
|
SemanticsNodeArgs(SemanticsTwoNodeIds{node1, node2})); \
|
|
}
|
|
#define CARBON_SEMANTICS_MAKE_identifier(Name) \
|
|
static auto Make##Name(SemanticsIdentifierId identifier)->SemanticsNode { \
|
|
return SemanticsNode(SemanticsNodeKind::Name(), \
|
|
SemanticsNodeArgs(identifier)); \
|
|
}
|
|
#define CARBON_SEMANTICS_MAKE_integer_literal(Name) \
|
|
static auto Make##Name(SemanticsIntegerLiteralId integer_literal) \
|
|
->SemanticsNode { \
|
|
return SemanticsNode(SemanticsNodeKind::Name(), \
|
|
SemanticsNodeArgs(integer_literal)); \
|
|
}
|
|
|
|
#define CARBON_SEMANTICS_NODE_KIND(Name, ArgsType) \
|
|
CARBON_SEMANTICS_MAKE_##ArgsType(Name)
|
|
#include "toolchain/semantics/semantics_node_kind.def"
|
|
|
|
#undef CARBON_SEMANTICS_MAKE_no_args
|
|
#undef CARBON_SEMANTICS_MAKE_one_node
|
|
#undef CARBON_SEMANTICS_MAKE_two_nodes
|
|
#undef CARBON_SEMANTICS_MAKE_identifier
|
|
#undef CARBON_SEMANTICS_MAKE_integer_literal
|
|
|
|
SemanticsNode() : kind_(SemanticsNodeKind::Invalid()) {}
|
|
|
|
auto kind() -> SemanticsNodeKind { return kind_; }
|
|
|
|
void Print(llvm::raw_ostream& out) const;
|
|
|
|
private:
|
|
SemanticsNode(SemanticsNodeKind kind, SemanticsNodeArgs one_of_args)
|
|
: kind_(kind), one_of_args_(one_of_args) {}
|
|
|
|
SemanticsNodeKind kind_;
|
|
|
|
SemanticsNodeArgs one_of_args_;
|
|
};
|
|
|
|
} // namespace Carbon
|
|
|
|
#endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_H_
|