Define a base class for all AST nodes. (#947)

Also implement code-generation to manage the resulting boilerplate.
This commit is contained in:
Geoff Romer
2021-11-16 11:54:47 -08:00
committed by GitHub
parent d854fb93cb
commit 7a5b8434c8
24 changed files with 965 additions and 543 deletions
+55 -64
View File
@@ -31,14 +31,9 @@ class StaticScope;
// every concrete derived class must have a corresponding enumerator
// in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
// details.
class Declaration : public NamedEntityInterface {
class Declaration : public virtual AstNode, public NamedEntity {
public:
enum class Kind {
FunctionDeclaration,
ClassDeclaration,
ChoiceDeclaration,
VariableDeclaration,
};
~Declaration() override = 0;
Declaration(const Member&) = delete;
auto operator=(const Member&) -> Declaration& = delete;
@@ -46,15 +41,15 @@ class Declaration : public NamedEntityInterface {
void Print(llvm::raw_ostream& out) const;
LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
// Returns the enumerator corresponding to the most-derived type of this
// object.
auto kind() const -> Kind { return kind_; }
auto named_entity_kind() const -> NamedEntityKind override {
return NamedEntityKind::Declaration;
static auto classof(const AstNode* node) -> bool {
return InheritsFromDeclaration(node->kind());
}
auto source_loc() const -> SourceLocation override { return source_loc_; }
// Returns the enumerator corresponding to the most-derived type of this
// object.
auto kind() const -> DeclarationKind {
return static_cast<DeclarationKind>(root_kind());
}
// The static type of the declared entity. Cannot be called before
// typechecking.
@@ -73,33 +68,30 @@ class Declaration : public NamedEntityInterface {
// Constructs a Declaration representing syntax at the given line number.
// `kind` must be the enumerator corresponding to the most-derived type being
// constructed.
Declaration(Kind kind, SourceLocation source_loc)
: kind_(kind), source_loc_(source_loc) {}
Declaration() = default;
private:
const Kind kind_;
SourceLocation source_loc_;
std::optional<Nonnull<const Value*>> static_type_;
};
// TODO: expand the kinds of things that can be deduced parameters.
// For now, only generic parameters are supported.
struct GenericBinding : public NamedEntityInterface {
struct GenericBinding : public virtual AstNode, public NamedEntity {
public:
GenericBinding(SourceLocation source_loc, std::string name,
Nonnull<Expression*> type)
: source_loc_(source_loc), name_(std::move(name)), type_(type) {}
: AstNode(AstNodeKind::GenericBinding, source_loc),
name_(std::move(name)),
type_(type) {}
auto named_entity_kind() const -> NamedEntityKind override {
return NamedEntityKind::GenericBinding;
static auto classof(const AstNode* node) -> bool {
return InheritsFromGenericBinding(node->kind());
}
auto source_loc() const -> SourceLocation override { return source_loc_; }
auto name() const -> const std::string& { return name_; }
auto type() const -> const Expression& { return *type_; }
private:
SourceLocation source_loc_;
std::string name_;
Nonnull<Expression*> type_;
};
@@ -190,15 +182,15 @@ class FunctionDeclaration : public Declaration {
Nonnull<TuplePattern*> param_pattern,
ReturnTerm return_term,
std::optional<Nonnull<Block*>> body)
: Declaration(Kind::FunctionDeclaration, source_loc),
: AstNode(AstNodeKind::FunctionDeclaration, source_loc),
name_(std::move(name)),
deduced_parameters_(std::move(deduced_params)),
param_pattern_(param_pattern),
return_term_(return_term),
body_(body) {}
static auto classof(const Declaration* decl) -> bool {
return decl->kind() == Kind::FunctionDeclaration;
static auto classof(const AstNode* node) -> bool {
return InheritsFromFunctionDeclaration(node->kind());
}
void PrintDepth(int depth, llvm::raw_ostream& out) const;
@@ -232,12 +224,12 @@ class ClassDeclaration : public Declaration {
public:
ClassDeclaration(SourceLocation source_loc, std::string name,
std::vector<Nonnull<Member*>> members)
: Declaration(Kind::ClassDeclaration, source_loc),
: AstNode(AstNodeKind::ClassDeclaration, source_loc),
name_(std::move(name)),
members_(std::move(members)) {}
static auto classof(const Declaration* decl) -> bool {
return decl->kind() == Kind::ClassDeclaration;
static auto classof(const AstNode* node) -> bool {
return InheritsFromClassDeclaration(node->kind());
}
auto name() const -> const std::string& { return name_; }
@@ -253,42 +245,41 @@ class ClassDeclaration : public Declaration {
StaticScope static_scope_;
};
class ChoiceDeclaration : public Declaration {
class AlternativeSignature : public virtual AstNode, public NamedEntity {
public:
class Alternative : public NamedEntityInterface {
public:
Alternative(SourceLocation source_loc, std::string name,
Nonnull<Expression*> signature)
: source_loc_(source_loc),
name_(std::move(name)),
signature_(signature) {}
auto named_entity_kind() const -> NamedEntityKind override {
return NamedEntityKind::ChoiceDeclarationAlternative;
}
auto source_loc() const -> SourceLocation override { return source_loc_; }
auto name() const -> const std::string& { return name_; }
auto signature() const -> const Expression& { return *signature_; }
private:
SourceLocation source_loc_;
std::string name_;
Nonnull<Expression*> signature_;
};
ChoiceDeclaration(SourceLocation source_loc, std::string name,
std::vector<Nonnull<Alternative*>> alternatives)
: Declaration(Kind::ChoiceDeclaration, source_loc),
AlternativeSignature(SourceLocation source_loc, std::string name,
Nonnull<Expression*> signature)
: AstNode(AstNodeKind::AlternativeSignature, source_loc),
name_(std::move(name)),
alternatives_(std::move(alternatives)) {}
signature_(signature) {}
static auto classof(const Declaration* decl) -> bool {
return decl->kind() == Kind::ChoiceDeclaration;
static auto classof(const AstNode* node) -> bool {
return InheritsFromAlternativeSignature(node->kind());
}
auto name() const -> const std::string& { return name_; }
auto alternatives() const -> llvm::ArrayRef<Nonnull<const Alternative*>> {
auto signature() const -> const Expression& { return *signature_; }
private:
std::string name_;
Nonnull<Expression*> signature_;
};
class ChoiceDeclaration : public Declaration {
public:
ChoiceDeclaration(SourceLocation source_loc, std::string name,
std::vector<Nonnull<AlternativeSignature*>> alternatives)
: AstNode(AstNodeKind::ChoiceDeclaration, source_loc),
name_(std::move(name)),
alternatives_(std::move(alternatives)) {}
static auto classof(const AstNode* node) -> bool {
return InheritsFromChoiceDeclaration(node->kind());
}
auto name() const -> const std::string& { return name_; }
auto alternatives() const
-> llvm::ArrayRef<Nonnull<const AlternativeSignature*>> {
return alternatives_;
}
@@ -298,7 +289,7 @@ class ChoiceDeclaration : public Declaration {
private:
std::string name_;
std::vector<Nonnull<Alternative*>> alternatives_;
std::vector<Nonnull<AlternativeSignature*>> alternatives_;
StaticScope static_scope_;
};
@@ -308,12 +299,12 @@ class VariableDeclaration : public Declaration {
VariableDeclaration(SourceLocation source_loc,
Nonnull<BindingPattern*> binding,
Nonnull<Expression*> initializer)
: Declaration(Kind::VariableDeclaration, source_loc),
: AstNode(AstNodeKind::VariableDeclaration, source_loc),
binding_(binding),
initializer_(initializer) {}
static auto classof(const Declaration* decl) -> bool {
return decl->kind() == Kind::VariableDeclaration;
static auto classof(const AstNode* node) -> bool {
return InheritsFromVariableDeclaration(node->kind());
}
auto binding() const -> const BindingPattern& { return *binding_; }