Files
carbon-lang/toolchain/parser/parse_node_kind.h
T
Jon Ross-Perkins 1f8508204b 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 `::`).
2022-10-20 12:50:10 -07:00

79 lines
2.8 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_PARSER_PARSE_NODE_KIND_H_
#define CARBON_TOOLCHAIN_PARSER_PARSE_NODE_KIND_H_
#include <cstdint>
#include <iterator>
#include "common/ostream.h"
#include "llvm/ADT/StringRef.h"
namespace Carbon {
// A class wrapping an enumeration of the different kinds of nodes in the parse
// tree.
//
// Rather than using a raw enumerator for each distinct kind of node produced by
// the parser, we wrap the enumerator in a class to expose a more rich API
// including bidirectional mappings to string spellings of the different kinds
// and any relevant classification.
//
// Instances of this type should always be created using the `constexpr` static
// member functions. These instances are designed specifically to be usable in
// `case` labels of `switch` statements just like an enumerator would.
class ParseNodeKind {
// Note that this must be declared earlier in the class so that its type can
// be used, for example in the conversion operator.
enum class KindEnum : uint8_t {
#define CARBON_PARSE_NODE_KIND(Name) Name,
#include "toolchain/parser/parse_node_kind.def"
};
public:
// `clang-format` has a bug with spacing around `->` returns in macros. See
// https://bugs.llvm.org/show_bug.cgi?id=48320 for details.
#define CARBON_PARSE_NODE_KIND(Name) \
static constexpr auto Name()->ParseNodeKind { \
return ParseNodeKind(KindEnum::Name); \
}
#include "toolchain/parser/parse_node_kind.def"
// The default constructor is deleted because objects of this type should
// always be constructed using the above factory functions for each unique
// kind.
ParseNodeKind() = delete;
friend auto operator==(ParseNodeKind lhs, ParseNodeKind rhs) -> bool {
return lhs.kind_ == rhs.kind_;
}
friend auto operator!=(ParseNodeKind lhs, ParseNodeKind rhs) -> bool {
return lhs.kind_ != rhs.kind_;
}
// Gets a friendly name for the token for logging or debugging.
[[nodiscard]] auto name() const -> llvm::StringRef;
// Enable conversion to our private enum, including in a `constexpr` context,
// to enable usage in `switch` and `case`. The enum remains private and
// nothing else should be using this function.
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr operator KindEnum() const { return kind_; }
void Print(llvm::raw_ostream& out) const { out << name(); }
private:
constexpr explicit ParseNodeKind(KindEnum k) : kind_(k) {}
KindEnum kind_;
};
// We expect the parse node kind to fit compactly into 8 bits.
static_assert(sizeof(ParseNodeKind) == 1, "Kind objects include padding!");
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_PARSER_PARSE_NODE_KIND_H_