1845 lines
42 KiB
C++
1845 lines
42 KiB
C++
#ifndef BOLT_CST_HPP
|
|
#define BOLT_CST_HPP
|
|
|
|
#include <cctype>
|
|
#include <istream>
|
|
#include <iterator>
|
|
#include <unordered_map>
|
|
#include <variant>
|
|
#include <vector>
|
|
|
|
#include "zen/config.hpp"
|
|
|
|
#include "bolt/Integer.hpp"
|
|
#include "bolt/String.hpp"
|
|
#include "bolt/ByteString.hpp"
|
|
|
|
namespace bolt {
|
|
|
|
class Type;
|
|
|
|
class Token;
|
|
class SourceFile;
|
|
class Scope;
|
|
class Pattern;
|
|
class Expression;
|
|
class Statement;
|
|
|
|
class TextLoc {
|
|
public:
|
|
|
|
size_t Line = 1;
|
|
size_t Column = 1;
|
|
|
|
inline bool isEmpty() const noexcept {
|
|
return Line == 0 && Column == 0;
|
|
}
|
|
|
|
inline void advance(const ByteString& Text) {
|
|
for (auto Chr: Text) {
|
|
if (Chr == '\n') {
|
|
Line++;
|
|
Column = 1;
|
|
} else {
|
|
Column++;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline TextLoc operator+(const ByteString& Text) const {
|
|
TextLoc Out { Line, Column };
|
|
Out.advance(Text);
|
|
return Out;
|
|
}
|
|
|
|
static TextLoc empty() {
|
|
return TextLoc { 0, 0 };
|
|
}
|
|
|
|
};
|
|
|
|
struct TextRange {
|
|
TextLoc Start;
|
|
TextLoc End;
|
|
};
|
|
|
|
class TextFile {
|
|
|
|
ByteString Path;
|
|
ByteString Text;
|
|
|
|
std::vector<size_t> LineOffsets;
|
|
|
|
public:
|
|
|
|
TextFile(ByteString Path, ByteString Text);
|
|
|
|
size_t getLine(size_t Offset) const;
|
|
size_t getColumn(size_t Offset) const;
|
|
size_t getStartOffset(size_t Line) const;
|
|
|
|
size_t getLineCount() const;
|
|
|
|
ByteString getPath() const;
|
|
|
|
ByteString getText() const;
|
|
|
|
};
|
|
|
|
enum class NodeKind {
|
|
Equals,
|
|
Colon,
|
|
Comma,
|
|
Dot,
|
|
DotDot,
|
|
Tilde,
|
|
LParen,
|
|
RParen,
|
|
LBracket,
|
|
RBracket,
|
|
LBrace,
|
|
RBrace,
|
|
RArrow,
|
|
RArrowAlt,
|
|
LetKeyword,
|
|
MutKeyword,
|
|
PubKeyword,
|
|
TypeKeyword,
|
|
ReturnKeyword,
|
|
ModKeyword,
|
|
StructKeyword,
|
|
ClassKeyword,
|
|
InstanceKeyword,
|
|
ElifKeyword,
|
|
IfKeyword,
|
|
ElseKeyword,
|
|
MatchKeyword,
|
|
Invalid,
|
|
EndOfFile,
|
|
BlockStart,
|
|
BlockEnd,
|
|
LineFoldEnd,
|
|
CustomOperator,
|
|
Assignment,
|
|
Identifier,
|
|
IdentifierAlt,
|
|
StringLiteral,
|
|
IntegerLiteral,
|
|
TypeclassConstraintExpression,
|
|
EqualityConstraintExpression,
|
|
QualifiedTypeExpression,
|
|
ReferenceTypeExpression,
|
|
ArrowTypeExpression,
|
|
VarTypeExpression,
|
|
NestedTypeExpression,
|
|
TupleTypeExpression,
|
|
BindPattern,
|
|
LiteralPattern,
|
|
ReferenceExpression,
|
|
MatchCase,
|
|
MatchExpression,
|
|
MemberExpression,
|
|
TupleExpression,
|
|
NestedExpression,
|
|
ConstantExpression,
|
|
CallExpression,
|
|
InfixExpression,
|
|
PrefixExpression,
|
|
RecordExpressionField,
|
|
RecordExpression,
|
|
ExpressionStatement,
|
|
ReturnStatement,
|
|
IfStatement,
|
|
IfStatementPart,
|
|
TypeAssert,
|
|
Parameter,
|
|
LetBlockBody,
|
|
LetExprBody,
|
|
LetDeclaration,
|
|
RecordDeclarationField,
|
|
RecordDeclaration,
|
|
ClassDeclaration,
|
|
InstanceDeclaration,
|
|
SourceFile,
|
|
};
|
|
|
|
struct SymbolPath {
|
|
std::vector<ByteString> Modules;
|
|
ByteString Name;
|
|
};
|
|
|
|
template<typename T>
|
|
NodeKind getNodeType();
|
|
|
|
class Node {
|
|
|
|
unsigned RefCount = 1;
|
|
|
|
const NodeKind Kind;
|
|
|
|
public:
|
|
|
|
Node* Parent = nullptr;
|
|
|
|
inline void ref() {
|
|
++RefCount;
|
|
}
|
|
|
|
inline void unref() {
|
|
--RefCount;
|
|
if (RefCount == 0) {
|
|
delete this;
|
|
}
|
|
}
|
|
|
|
void setParents();
|
|
|
|
virtual Token* getFirstToken() const = 0;
|
|
virtual Token* getLastToken() const = 0;
|
|
|
|
virtual std::size_t getStartLine() const;
|
|
virtual std::size_t getStartColumn() const;
|
|
virtual std::size_t getEndLine() const;
|
|
virtual std::size_t getEndColumn() const;
|
|
|
|
inline NodeKind getKind() const noexcept {
|
|
return Kind;
|
|
}
|
|
|
|
template<typename T>
|
|
bool is() const noexcept {
|
|
return Kind == getNodeType<T>();
|
|
}
|
|
|
|
template<>
|
|
bool is<Expression>() const noexcept {
|
|
return Kind == NodeKind::ReferenceExpression
|
|
|| Kind == NodeKind::ConstantExpression
|
|
|| Kind == NodeKind::PrefixExpression
|
|
|| Kind == NodeKind::InfixExpression
|
|
|| Kind == NodeKind::CallExpression
|
|
|| Kind == NodeKind::NestedExpression;
|
|
}
|
|
|
|
template<typename T>
|
|
T* as() {
|
|
ZEN_ASSERT(is<T>());
|
|
return static_cast<T*>(this);
|
|
}
|
|
|
|
virtual TextRange getRange() const;
|
|
|
|
inline Node(NodeKind Type):
|
|
Kind(Type) {}
|
|
|
|
const SourceFile* getSourceFile() const;
|
|
SourceFile* getSourceFile();
|
|
|
|
virtual Scope* getScope();
|
|
|
|
virtual ~Node();
|
|
|
|
};
|
|
|
|
enum class SymbolKind {
|
|
Var,
|
|
Class,
|
|
Type,
|
|
};
|
|
|
|
class Scope {
|
|
|
|
Node* Source;
|
|
std::unordered_multimap<ByteString, std::tuple<Node*, SymbolKind>> Mapping;
|
|
|
|
void scan(Node* X);
|
|
|
|
void addBindings(Pattern* P, Node* ToInsert);
|
|
|
|
public:
|
|
|
|
Scope(Node* Source);
|
|
|
|
/**
|
|
* Performs a direct lookup in this scope for the given symbol.
|
|
*
|
|
* This method will never traverse to parent scopes and will always return a
|
|
* symbol that belongs to this scope, if any is found.
|
|
*
|
|
* \returns nullptr when no such symbol could be found in this scope.
|
|
*/
|
|
Node* lookupDirect(SymbolPath Path, SymbolKind Kind = SymbolKind::Var);
|
|
|
|
/**
|
|
* Find the symbol with the given name, either in this scope or in any of
|
|
* the parent ones.
|
|
*
|
|
* \returns nullptr when no such symbol could be found in any of the scopes.
|
|
*/
|
|
Node* lookup(SymbolPath Path, SymbolKind Kind = SymbolKind::Var);
|
|
|
|
Scope* getParentScope();
|
|
|
|
};
|
|
|
|
class Token : public Node {
|
|
|
|
TextLoc StartLoc;
|
|
|
|
public:
|
|
|
|
Token(NodeKind Type, TextLoc StartLoc): Node(Type), StartLoc(StartLoc) {}
|
|
|
|
virtual std::string getText() const = 0;
|
|
|
|
inline Token* getFirstToken() const override {
|
|
ZEN_UNREACHABLE
|
|
}
|
|
|
|
inline Token* getLastToken() const override {
|
|
ZEN_UNREACHABLE
|
|
}
|
|
|
|
inline TextLoc getStartLoc() const {
|
|
return StartLoc;
|
|
}
|
|
|
|
TextLoc getEndLoc() const;
|
|
|
|
inline size_t getStartLine() const override {
|
|
return StartLoc.Line;
|
|
}
|
|
|
|
inline size_t getStartColumn() const override {
|
|
return StartLoc.Column;
|
|
}
|
|
|
|
inline size_t getEndLine() const override {
|
|
return getEndLoc().Line;
|
|
}
|
|
|
|
inline size_t getEndColumn() const override {
|
|
return getEndLoc().Column;
|
|
}
|
|
|
|
TextRange getRange() const override {
|
|
return { getStartLoc(), getEndLoc() };
|
|
}
|
|
|
|
};
|
|
|
|
class Equals : public Token {
|
|
public:
|
|
|
|
inline Equals(TextLoc StartLoc):
|
|
Token(NodeKind::Equals, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::Equals;
|
|
}
|
|
|
|
};
|
|
|
|
class Colon : public Token {
|
|
public:
|
|
|
|
inline Colon(TextLoc StartLoc):
|
|
Token(NodeKind::Colon, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::Colon;
|
|
}
|
|
|
|
};
|
|
|
|
class Comma : public Token {
|
|
public:
|
|
|
|
inline Comma(TextLoc StartLoc):
|
|
Token(NodeKind::Comma, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::Comma;
|
|
}
|
|
|
|
};
|
|
|
|
class Dot : public Token {
|
|
public:
|
|
|
|
inline Dot(TextLoc StartLoc):
|
|
Token(NodeKind::Dot, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::Dot;
|
|
}
|
|
|
|
};
|
|
|
|
class DotDot : public Token {
|
|
public:
|
|
|
|
inline DotDot(TextLoc StartLoc):
|
|
Token(NodeKind::DotDot, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::DotDot;
|
|
}
|
|
|
|
};
|
|
|
|
class Tilde : public Token {
|
|
public:
|
|
|
|
inline Tilde(TextLoc StartLoc):
|
|
Token(NodeKind::Tilde, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::Tilde;
|
|
}
|
|
|
|
};
|
|
|
|
class LParen : public Token {
|
|
public:
|
|
|
|
inline LParen(TextLoc StartLoc):
|
|
Token(NodeKind::LParen, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::LParen;
|
|
}
|
|
|
|
};
|
|
|
|
class RParen : public Token {
|
|
public:
|
|
|
|
inline RParen(TextLoc StartLoc):
|
|
Token(NodeKind::RParen, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::RParen;
|
|
}
|
|
|
|
};
|
|
|
|
class LBracket : public Token {
|
|
public:
|
|
|
|
inline LBracket(TextLoc StartLoc):
|
|
Token(NodeKind::LBracket, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::LBracket;
|
|
}
|
|
|
|
};
|
|
|
|
class RBracket : public Token {
|
|
public:
|
|
|
|
inline RBracket(TextLoc StartLoc):
|
|
Token(NodeKind::RBracket, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::RBracket;
|
|
}
|
|
|
|
};
|
|
|
|
class LBrace : public Token {
|
|
public:
|
|
|
|
inline LBrace(TextLoc StartLoc):
|
|
Token(NodeKind::LBrace, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::LBrace;
|
|
}
|
|
|
|
};
|
|
|
|
class RBrace : public Token {
|
|
public:
|
|
|
|
inline RBrace(TextLoc StartLoc):
|
|
Token(NodeKind::RBrace, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::RBrace;
|
|
}
|
|
|
|
};
|
|
|
|
class RArrow : public Token {
|
|
public:
|
|
|
|
inline RArrow(TextLoc StartLoc):
|
|
Token(NodeKind::RArrow, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::RArrow;
|
|
}
|
|
|
|
};
|
|
|
|
class RArrowAlt : public Token {
|
|
public:
|
|
|
|
inline RArrowAlt(TextLoc StartLoc):
|
|
Token(NodeKind::RArrowAlt, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::RArrowAlt;
|
|
}
|
|
|
|
};
|
|
|
|
class LetKeyword : public Token {
|
|
public:
|
|
|
|
inline LetKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::LetKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::LetKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class MutKeyword : public Token {
|
|
public:
|
|
|
|
inline MutKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::MutKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::MutKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class PubKeyword : public Token {
|
|
public:
|
|
|
|
inline PubKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::PubKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::PubKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class TypeKeyword : public Token {
|
|
public:
|
|
|
|
inline TypeKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::TypeKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::TypeKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class ReturnKeyword : public Token {
|
|
public:
|
|
|
|
inline ReturnKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ReturnKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::ReturnKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class ModKeyword : public Token {
|
|
public:
|
|
|
|
inline ModKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ModKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::ModKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class StructKeyword : public Token {
|
|
public:
|
|
|
|
inline StructKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::StructKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::StructKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class ClassKeyword : public Token {
|
|
public:
|
|
|
|
inline ClassKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ClassKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::ClassKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class InstanceKeyword : public Token {
|
|
public:
|
|
|
|
inline InstanceKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::InstanceKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::InstanceKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class ElifKeyword : public Token {
|
|
public:
|
|
|
|
inline ElifKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ElifKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::ElifKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class IfKeyword : public Token {
|
|
public:
|
|
|
|
inline IfKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::IfKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::IfKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class ElseKeyword : public Token {
|
|
public:
|
|
|
|
inline ElseKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ElseKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::ElseKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class MatchKeyword : public Token {
|
|
public:
|
|
|
|
inline MatchKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::MatchKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::MatchKeyword;
|
|
}
|
|
|
|
};
|
|
|
|
class Invalid : public Token {
|
|
public:
|
|
|
|
inline Invalid(TextLoc StartLoc):
|
|
Token(NodeKind::Invalid, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::Invalid;
|
|
}
|
|
|
|
};
|
|
|
|
class EndOfFile : public Token {
|
|
public:
|
|
|
|
inline EndOfFile(TextLoc StartLoc):
|
|
Token(NodeKind::EndOfFile, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::EndOfFile;
|
|
}
|
|
|
|
};
|
|
|
|
class BlockStart : public Token {
|
|
public:
|
|
|
|
inline BlockStart(TextLoc StartLoc):
|
|
Token(NodeKind::BlockStart, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::BlockStart;
|
|
}
|
|
|
|
};
|
|
|
|
class BlockEnd : public Token {
|
|
public:
|
|
|
|
inline BlockEnd(TextLoc StartLoc):
|
|
Token(NodeKind::BlockEnd, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::BlockEnd;
|
|
}
|
|
|
|
};
|
|
|
|
class LineFoldEnd : public Token {
|
|
public:
|
|
|
|
inline LineFoldEnd(TextLoc StartLoc):
|
|
Token(NodeKind::LineFoldEnd, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::LineFoldEnd;
|
|
}
|
|
|
|
};
|
|
|
|
class CustomOperator : public Token {
|
|
public:
|
|
|
|
ByteString Text;
|
|
|
|
CustomOperator(ByteString Text, TextLoc StartLoc):
|
|
Token(NodeKind::CustomOperator, StartLoc), Text(Text) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::CustomOperator;
|
|
}
|
|
|
|
};
|
|
|
|
class Assignment : public Token {
|
|
public:
|
|
|
|
ByteString Text;
|
|
|
|
Assignment(ByteString Text, TextLoc StartLoc):
|
|
Token(NodeKind::Assignment, StartLoc), Text(Text) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::Assignment;
|
|
}
|
|
|
|
};
|
|
|
|
class Symbol : public Token {
|
|
public:
|
|
|
|
inline Symbol(NodeKind Kind, TextLoc StartLoc):
|
|
Token(Kind, StartLoc) {}
|
|
|
|
virtual ByteString getCanonicalText() = 0;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::Identifier
|
|
|| N->getKind() == NodeKind::IdentifierAlt;
|
|
}
|
|
|
|
};
|
|
|
|
class Identifier : public Symbol {
|
|
public:
|
|
|
|
ByteString Text;
|
|
|
|
Identifier(ByteString Text, TextLoc StartLoc = TextLoc::empty()):
|
|
Symbol(NodeKind::Identifier, StartLoc), Text(Text) {}
|
|
|
|
ByteString getCanonicalText() override;
|
|
|
|
std::string getText() const override;
|
|
|
|
bool isTypeVar() const;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::Identifier;
|
|
}
|
|
|
|
};
|
|
|
|
class IdentifierAlt : public Symbol {
|
|
public:
|
|
|
|
ByteString Text;
|
|
|
|
IdentifierAlt(ByteString Text, TextLoc StartLoc):
|
|
Symbol(NodeKind::IdentifierAlt, StartLoc), Text(Text) {}
|
|
|
|
ByteString getCanonicalText() override;
|
|
|
|
std::string getText() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::IdentifierAlt;
|
|
}
|
|
|
|
};
|
|
|
|
using Value = std::variant<ByteString, Integer>;
|
|
|
|
class Literal : public Token {
|
|
public:
|
|
|
|
inline Literal(NodeKind Kind, TextLoc StartLoc):
|
|
Token(Kind, StartLoc) {}
|
|
|
|
virtual Value getValue() = 0;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::StringLiteral
|
|
|| N->getKind() == NodeKind::IntegerLiteral;
|
|
}
|
|
|
|
};
|
|
|
|
class StringLiteral : public Literal {
|
|
public:
|
|
|
|
ByteString Text;
|
|
|
|
StringLiteral(ByteString Text, TextLoc StartLoc):
|
|
Literal(NodeKind::StringLiteral, StartLoc), Text(Text) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
Value getValue() override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::StringLiteral;
|
|
}
|
|
|
|
};
|
|
|
|
class IntegerLiteral : public Literal {
|
|
public:
|
|
|
|
Integer V;
|
|
|
|
IntegerLiteral(Integer Value, TextLoc StartLoc):
|
|
Literal(NodeKind::IntegerLiteral, StartLoc), V(Value) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
inline Integer getInteger() const noexcept {
|
|
return V;
|
|
}
|
|
|
|
Value getValue() override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::IntegerLiteral;
|
|
}
|
|
|
|
};
|
|
|
|
class TypedNode : public Node {
|
|
protected:
|
|
|
|
Type* Ty;
|
|
|
|
inline TypedNode(NodeKind Kind):
|
|
Node(Kind) {}
|
|
|
|
public:
|
|
|
|
inline void setType(Type* Ty2) {
|
|
Ty = Ty2;
|
|
}
|
|
|
|
inline Type* getType() const noexcept {
|
|
ZEN_ASSERT(Ty != nullptr);
|
|
return Ty;
|
|
}
|
|
|
|
};
|
|
|
|
class TypeExpression : public TypedNode {
|
|
protected:
|
|
|
|
TypeExpression(NodeKind Kind):
|
|
TypedNode(Kind) {}
|
|
|
|
};
|
|
|
|
class ConstraintExpression : public Node {
|
|
public:
|
|
|
|
inline ConstraintExpression(NodeKind Kind):
|
|
Node(Kind) {}
|
|
|
|
};
|
|
|
|
class VarTypeExpression;
|
|
|
|
class TypeclassConstraintExpression : public ConstraintExpression {
|
|
public:
|
|
|
|
IdentifierAlt* Name;
|
|
std::vector<VarTypeExpression*> TEs;
|
|
|
|
TypeclassConstraintExpression(
|
|
IdentifierAlt* Name,
|
|
std::vector<VarTypeExpression*> TEs
|
|
): ConstraintExpression(NodeKind::TypeclassConstraintExpression),
|
|
Name(Name),
|
|
TEs(TEs) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::TypeclassConstraintExpression;
|
|
}
|
|
|
|
};
|
|
|
|
class EqualityConstraintExpression : public ConstraintExpression {
|
|
public:
|
|
|
|
TypeExpression* Left;
|
|
class Tilde* Tilde;
|
|
TypeExpression* Right;
|
|
|
|
inline EqualityConstraintExpression(
|
|
TypeExpression* Left,
|
|
class Tilde* Tilde,
|
|
TypeExpression* Right
|
|
): ConstraintExpression(NodeKind::EqualityConstraintExpression),
|
|
Left(Left),
|
|
Tilde(Tilde),
|
|
Right(Right) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::EqualityConstraintExpression;
|
|
}
|
|
|
|
};
|
|
|
|
class QualifiedTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
std::vector<std::tuple<ConstraintExpression*, Comma*>> Constraints;
|
|
class RArrowAlt* RArrowAlt;
|
|
TypeExpression* TE;
|
|
|
|
QualifiedTypeExpression(
|
|
std::vector<std::tuple<ConstraintExpression*, Comma*>> Constraints,
|
|
class RArrowAlt* RArrowAlt,
|
|
TypeExpression* TE
|
|
): TypeExpression(NodeKind::QualifiedTypeExpression),
|
|
Constraints(Constraints),
|
|
RArrowAlt(RArrowAlt),
|
|
TE(TE) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::QualifiedTypeExpression;
|
|
}
|
|
|
|
};
|
|
|
|
class ReferenceTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
|
|
IdentifierAlt* Name;
|
|
|
|
ReferenceTypeExpression(
|
|
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath,
|
|
IdentifierAlt* Name
|
|
): TypeExpression(NodeKind::ReferenceTypeExpression),
|
|
ModulePath(ModulePath),
|
|
Name(Name) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
SymbolPath getSymbolPath() const;
|
|
|
|
};
|
|
|
|
class ArrowTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
std::vector<TypeExpression*> ParamTypes;
|
|
TypeExpression* ReturnType;
|
|
|
|
inline ArrowTypeExpression(
|
|
std::vector<TypeExpression*> ParamTypes,
|
|
TypeExpression* ReturnType
|
|
): TypeExpression(NodeKind::ArrowTypeExpression),
|
|
ParamTypes(ParamTypes),
|
|
ReturnType(ReturnType) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class VarTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
Identifier* Name;
|
|
|
|
inline VarTypeExpression(Identifier* Name):
|
|
TypeExpression(NodeKind::VarTypeExpression), Name(Name) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class NestedTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
LParen* LParen;
|
|
TypeExpression* TE;
|
|
RParen* RParen;
|
|
|
|
inline NestedTypeExpression(
|
|
class LParen* LParen,
|
|
TypeExpression* TE,
|
|
class RParen* RParen
|
|
): TypeExpression(NodeKind::NestedTypeExpression),
|
|
LParen(LParen),
|
|
TE(TE),
|
|
RParen(RParen) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class TupleTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
LParen* LParen;
|
|
std::vector<std::tuple<TypeExpression*, Comma*>> Elements;
|
|
RParen* RParen;
|
|
|
|
inline TupleTypeExpression(
|
|
class LParen* LParen,
|
|
std::vector<std::tuple<TypeExpression*, Comma*>> Elements,
|
|
class RParen* RParen
|
|
): TypeExpression(NodeKind::TupleTypeExpression),
|
|
LParen(LParen),
|
|
Elements(Elements),
|
|
RParen(RParen) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class Pattern : public Node {
|
|
protected:
|
|
|
|
inline Pattern(NodeKind Type):
|
|
Node(Type) {}
|
|
|
|
};
|
|
|
|
class BindPattern : public Pattern {
|
|
public:
|
|
|
|
Identifier* Name;
|
|
|
|
BindPattern(
|
|
Identifier* Name
|
|
): Pattern(NodeKind::BindPattern),
|
|
Name(Name) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::BindPattern;
|
|
}
|
|
|
|
};
|
|
|
|
class LiteralPattern : public Pattern {
|
|
public:
|
|
|
|
class Literal* Literal;
|
|
|
|
LiteralPattern(class Literal* Literal):
|
|
Pattern(NodeKind::LiteralPattern),
|
|
Literal(Literal) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::LiteralPattern;
|
|
}
|
|
|
|
};
|
|
|
|
class Expression : public TypedNode {
|
|
protected:
|
|
|
|
inline Expression(NodeKind Kind):
|
|
TypedNode(Kind) {}
|
|
|
|
};
|
|
|
|
class ReferenceExpression : public Expression {
|
|
public:
|
|
|
|
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
|
|
Symbol* Name;
|
|
|
|
ReferenceExpression(
|
|
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath,
|
|
Symbol* Name
|
|
): Expression(NodeKind::ReferenceExpression),
|
|
ModulePath(ModulePath),
|
|
Name(Name) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
SymbolPath getSymbolPath() const;
|
|
|
|
};
|
|
|
|
class MatchCase : public Node {
|
|
public:
|
|
|
|
class Pattern* Pattern;
|
|
class RArrowAlt* RArrowAlt;
|
|
class Expression* Expression;
|
|
|
|
inline MatchCase(
|
|
class Pattern* Pattern,
|
|
class RArrowAlt* RArrowAlt,
|
|
class Expression* Expression
|
|
): Node(NodeKind::MatchCase),
|
|
Pattern(Pattern),
|
|
RArrowAlt(RArrowAlt),
|
|
Expression(Expression) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class MatchExpression : public Expression {
|
|
public:
|
|
|
|
class MatchKeyword* MatchKeyword;
|
|
Expression* Value;
|
|
class BlockStart* BlockStart;
|
|
std::vector<MatchCase*> Cases;
|
|
|
|
inline MatchExpression(
|
|
class MatchKeyword* MatchKeyword,
|
|
Expression* Value,
|
|
class BlockStart* BlockStart,
|
|
std::vector<MatchCase*> Cases
|
|
): Expression(NodeKind::MatchExpression),
|
|
MatchKeyword(MatchKeyword),
|
|
Value(Value),
|
|
BlockStart(BlockStart),
|
|
Cases(Cases) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class MemberExpression : public Expression {
|
|
public:
|
|
|
|
Expression* E;
|
|
Dot* Dot;
|
|
Token* Name;
|
|
|
|
inline MemberExpression(
|
|
class Expression* E,
|
|
class Dot* Dot,
|
|
Token* Name
|
|
): Expression(NodeKind::MemberExpression),
|
|
E(E),
|
|
Dot(Dot),
|
|
Name(Name) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
inline Expression* getExpression() const {
|
|
return E;
|
|
}
|
|
|
|
};
|
|
|
|
class TupleExpression : public Expression {
|
|
public:
|
|
|
|
class LParen* LParen;
|
|
std::vector<std::tuple<Expression*, Comma*>> Elements;
|
|
class RParen* RParen;
|
|
|
|
inline TupleExpression(
|
|
class LParen* LParen,
|
|
std::vector<std::tuple<Expression*, Comma*>> Elements,
|
|
class RParen* RParen
|
|
): Expression(NodeKind::TupleExpression),
|
|
LParen(LParen),
|
|
Elements(Elements),
|
|
RParen(RParen) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class NestedExpression : public Expression {
|
|
public:
|
|
|
|
class LParen* LParen;
|
|
Expression* Inner;
|
|
class RParen* RParen;
|
|
|
|
inline NestedExpression(
|
|
class LParen* LParen,
|
|
Expression* Inner,
|
|
class RParen* RParen
|
|
): Expression(NodeKind::NestedExpression),
|
|
LParen(LParen),
|
|
Inner(Inner),
|
|
RParen(RParen) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class ConstantExpression : public Expression {
|
|
public:
|
|
|
|
class Literal* Token;
|
|
|
|
ConstantExpression(
|
|
class Literal* Token
|
|
): Expression(NodeKind::ConstantExpression),
|
|
Token(Token) {}
|
|
|
|
class Token* getFirstToken() const override;
|
|
class Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class CallExpression : public Expression {
|
|
public:
|
|
|
|
Expression* Function;
|
|
std::vector<Expression*> Args;
|
|
|
|
CallExpression(
|
|
Expression* Function,
|
|
std::vector<Expression*> Args
|
|
): Expression(NodeKind::CallExpression),
|
|
Function(Function),
|
|
Args(Args) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class InfixExpression : public Expression {
|
|
public:
|
|
|
|
Expression* LHS;
|
|
Token* Operator;
|
|
Expression* RHS;
|
|
|
|
InfixExpression(Expression* LHS, Token* Operator, Expression* RHS):
|
|
Expression(NodeKind::InfixExpression),
|
|
LHS(LHS),
|
|
Operator(Operator),
|
|
RHS(RHS) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class PrefixExpression : public Expression {
|
|
public:
|
|
|
|
Token* Operator;
|
|
Expression* Argument;
|
|
|
|
PrefixExpression(
|
|
Token* Operator,
|
|
Expression* Argument
|
|
): Expression(NodeKind::PrefixExpression),
|
|
Operator(Operator),
|
|
Argument(Argument) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class RecordExpressionField : public Node {
|
|
public:
|
|
|
|
Identifier* Name;
|
|
Equals* Equals;
|
|
Expression* E;
|
|
|
|
inline RecordExpressionField(
|
|
Identifier* Name,
|
|
class Equals* Equals,
|
|
Expression* E
|
|
): Node(NodeKind::RecordExpressionField),
|
|
Name(Name),
|
|
Equals(Equals),
|
|
E(E) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
inline Expression* getExpression() const {
|
|
return E;
|
|
}
|
|
|
|
};
|
|
|
|
class RecordExpression : public Expression {
|
|
public:
|
|
|
|
LBrace* LBrace;
|
|
std::vector<std::tuple<RecordExpressionField*, Comma*>> Fields;
|
|
RBrace* RBrace;
|
|
|
|
inline RecordExpression(
|
|
class LBrace* LBrace,
|
|
std::vector<std::tuple<RecordExpressionField*, Comma*>> Fields,
|
|
class RBrace* RBrace
|
|
): Expression(NodeKind::RecordExpression),
|
|
LBrace(LBrace),
|
|
Fields(Fields),
|
|
RBrace(RBrace) {}
|
|
|
|
};
|
|
|
|
class Statement : public Node {
|
|
protected:
|
|
|
|
inline Statement(NodeKind Type):
|
|
Node(Type) {}
|
|
|
|
};
|
|
|
|
class ExpressionStatement : public Statement {
|
|
public:
|
|
|
|
class Expression* Expression;
|
|
|
|
ExpressionStatement(class Expression* Expression):
|
|
Statement(NodeKind::ExpressionStatement), Expression(Expression) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class IfStatementPart : public Node {
|
|
public:
|
|
|
|
Token* Keyword;
|
|
Expression* Test;
|
|
class BlockStart* BlockStart;
|
|
std::vector<Node*> Elements;
|
|
|
|
inline IfStatementPart(
|
|
Token* Keyword,
|
|
Expression* Test,
|
|
class BlockStart* BlockStart,
|
|
std::vector<Node*> Elements
|
|
): Node(NodeKind::IfStatementPart),
|
|
Keyword(Keyword),
|
|
Test(Test),
|
|
BlockStart(BlockStart),
|
|
Elements(Elements) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class IfStatement : public Statement {
|
|
public:
|
|
|
|
std::vector<IfStatementPart*> Parts;
|
|
|
|
inline IfStatement(std::vector<IfStatementPart*> Parts):
|
|
Statement(NodeKind::IfStatement), Parts(Parts) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class ReturnStatement : public Statement {
|
|
public:
|
|
|
|
class ReturnKeyword* ReturnKeyword;
|
|
class Expression* Expression;
|
|
|
|
ReturnStatement(
|
|
class ReturnKeyword* ReturnKeyword,
|
|
class Expression* Expression
|
|
): Statement(NodeKind::ReturnStatement),
|
|
ReturnKeyword(ReturnKeyword),
|
|
Expression(Expression) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class TypeAssert : public Node {
|
|
public:
|
|
|
|
class Colon* Colon;
|
|
class TypeExpression* TypeExpression;
|
|
|
|
TypeAssert(
|
|
class Colon* Colon,
|
|
class TypeExpression* TypeExpression
|
|
): Node(NodeKind::TypeAssert),
|
|
Colon(Colon),
|
|
TypeExpression(TypeExpression) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class Parameter : public Node {
|
|
public:
|
|
|
|
Parameter(
|
|
class Pattern* Pattern,
|
|
class TypeAssert* TypeAssert
|
|
): Node(NodeKind::Parameter),
|
|
Pattern(Pattern),
|
|
TypeAssert(TypeAssert) {}
|
|
|
|
class Pattern* Pattern;
|
|
class TypeAssert* TypeAssert;
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class LetBody : public Node {
|
|
public:
|
|
|
|
LetBody(NodeKind Type): Node(Type) {}
|
|
|
|
};
|
|
|
|
class LetBlockBody : public LetBody {
|
|
public:
|
|
|
|
class BlockStart* BlockStart;
|
|
std::vector<Node*> Elements;
|
|
|
|
LetBlockBody(
|
|
class BlockStart* BlockStart,
|
|
std::vector<Node*> Elements
|
|
): LetBody(NodeKind::LetBlockBody),
|
|
BlockStart(BlockStart),
|
|
Elements(Elements) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class LetExprBody : public LetBody {
|
|
public:
|
|
|
|
class Equals* Equals;
|
|
class Expression* Expression;
|
|
|
|
LetExprBody(
|
|
class Equals* Equals,
|
|
class Expression* Expression
|
|
): LetBody(NodeKind::LetExprBody),
|
|
Equals(Equals),
|
|
Expression(Expression) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class Type;
|
|
class InferContext;
|
|
|
|
class LetDeclaration : public Node {
|
|
|
|
Scope* TheScope = nullptr;
|
|
|
|
public:
|
|
|
|
bool IsCycleActive = false;
|
|
InferContext* Ctx;
|
|
class Type* Ty;
|
|
|
|
class PubKeyword* PubKeyword;
|
|
class LetKeyword* LetKeyword;
|
|
class MutKeyword* MutKeyword;
|
|
class Pattern* Pattern;
|
|
std::vector<Parameter*> Params;
|
|
class TypeAssert* TypeAssert;
|
|
LetBody* Body;
|
|
|
|
LetDeclaration(
|
|
class PubKeyword* PubKeyword,
|
|
class LetKeyword* LetKeywod,
|
|
class MutKeyword* MutKeyword,
|
|
class Pattern* Pattern,
|
|
std::vector<Parameter*> Params,
|
|
class TypeAssert* TypeAssert,
|
|
LetBody* Body
|
|
): Node(NodeKind::LetDeclaration),
|
|
PubKeyword(PubKeyword),
|
|
LetKeyword(LetKeywod),
|
|
MutKeyword(MutKeyword),
|
|
Pattern(Pattern),
|
|
Params(Params),
|
|
TypeAssert(TypeAssert),
|
|
Body(Body) {}
|
|
|
|
inline Scope* getScope() override {
|
|
if (TheScope == nullptr) {
|
|
TheScope = new Scope(this);
|
|
}
|
|
return TheScope;
|
|
}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::LetDeclaration;
|
|
}
|
|
|
|
};
|
|
|
|
class InstanceDeclaration : public Node {
|
|
public:
|
|
|
|
class InstanceKeyword* InstanceKeyword;
|
|
IdentifierAlt* Name;
|
|
std::vector<TypeExpression*> TypeExps;
|
|
class BlockStart* BlockStart;
|
|
std::vector<Node*> Elements;
|
|
|
|
InstanceDeclaration(
|
|
class InstanceKeyword* InstanceKeyword,
|
|
IdentifierAlt* Name,
|
|
std::vector<TypeExpression*> TypeExps,
|
|
class BlockStart* BlockStart,
|
|
std::vector<Node*> Elements
|
|
): Node(NodeKind::InstanceDeclaration),
|
|
InstanceKeyword(InstanceKeyword),
|
|
Name(Name),
|
|
TypeExps(TypeExps),
|
|
BlockStart(BlockStart),
|
|
Elements(Elements) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::InstanceDeclaration;
|
|
}
|
|
|
|
};
|
|
|
|
class ClassDeclaration : public Node {
|
|
public:
|
|
|
|
class PubKeyword* PubKeyword;
|
|
class ClassKeyword* ClassKeyword;
|
|
IdentifierAlt* Name;
|
|
std::vector<VarTypeExpression*> TypeVars;
|
|
class BlockStart* BlockStart;
|
|
std::vector<Node*> Elements;
|
|
|
|
ClassDeclaration(
|
|
class PubKeyword* PubKeyword,
|
|
class ClassKeyword* ClassKeyword,
|
|
IdentifierAlt* Name,
|
|
std::vector<VarTypeExpression*> TypeVars,
|
|
class BlockStart* BlockStart,
|
|
std::vector<Node*> Elements
|
|
): Node(NodeKind::ClassDeclaration),
|
|
PubKeyword(PubKeyword),
|
|
ClassKeyword(ClassKeyword),
|
|
Name(Name),
|
|
TypeVars(TypeVars),
|
|
BlockStart(BlockStart),
|
|
Elements(Elements) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::ClassDeclaration;
|
|
}
|
|
|
|
};
|
|
|
|
class RecordDeclarationField : public Node {
|
|
public:
|
|
|
|
RecordDeclarationField(
|
|
Identifier* Name,
|
|
class Colon* Colon,
|
|
class TypeExpression* TypeExpression
|
|
): Node(NodeKind::RecordDeclarationField),
|
|
Name(Name),
|
|
Colon(Colon),
|
|
TypeExpression(TypeExpression) {}
|
|
|
|
Identifier* Name;
|
|
class Colon* Colon;
|
|
class TypeExpression* TypeExpression;
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class RecordDeclaration : public Node {
|
|
public:
|
|
|
|
class PubKeyword* PubKeyword;
|
|
class StructKeyword* StructKeyword;
|
|
Identifier* Name;
|
|
class BlockStart* BlockStart;
|
|
std::vector<RecordDeclarationField*> Fields;
|
|
|
|
RecordDeclaration(
|
|
class PubKeyword* PubKeyword,
|
|
class StructKeyword* StructKeyword,
|
|
Identifier* Name,
|
|
class BlockStart* BlockStart,
|
|
std::vector<RecordDeclarationField*> Fields
|
|
): Node(NodeKind::RecordDeclaration),
|
|
PubKeyword(PubKeyword),
|
|
StructKeyword(StructKeyword),
|
|
Name(Name),
|
|
BlockStart(BlockStart),
|
|
Fields(Fields) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
};
|
|
|
|
class SourceFile : public Node {
|
|
|
|
Scope* TheScope = nullptr;
|
|
|
|
public:
|
|
|
|
TextFile& File;
|
|
|
|
std::vector<Node*> Elements;
|
|
|
|
SourceFile(TextFile& File, std::vector<Node*> Elements):
|
|
Node(NodeKind::SourceFile), File(File), Elements(Elements) {}
|
|
|
|
inline TextFile& getTextFile() {
|
|
return File;
|
|
}
|
|
|
|
inline const TextFile& getTextFile() const {
|
|
return File;
|
|
}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
inline Scope* getScope() override {
|
|
if (TheScope == nullptr) {
|
|
TheScope = new Scope(this);
|
|
}
|
|
return TheScope;
|
|
}
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::SourceFile;
|
|
}
|
|
|
|
};
|
|
|
|
template<> inline NodeKind getNodeType<Equals>() { return NodeKind::Equals; }
|
|
template<> inline NodeKind getNodeType<Colon>() { return NodeKind::Colon; }
|
|
template<> inline NodeKind getNodeType<Dot>() { return NodeKind::Dot; }
|
|
template<> inline NodeKind getNodeType<DotDot>() { return NodeKind::DotDot; }
|
|
template<> inline NodeKind getNodeType<Tilde>() { return NodeKind::Tilde; }
|
|
template<> inline NodeKind getNodeType<LParen>() { return NodeKind::LParen; }
|
|
template<> inline NodeKind getNodeType<RParen>() { return NodeKind::RParen; }
|
|
template<> inline NodeKind getNodeType<LBracket>() { return NodeKind::LBracket; }
|
|
template<> inline NodeKind getNodeType<RBracket>() { return NodeKind::RBracket; }
|
|
template<> inline NodeKind getNodeType<LBrace>() { return NodeKind::LBrace; }
|
|
template<> inline NodeKind getNodeType<RBrace>() { return NodeKind::RBrace; }
|
|
template<> inline NodeKind getNodeType<RArrow>() { return NodeKind::RArrow; }
|
|
template<> inline NodeKind getNodeType<RArrowAlt>() { return NodeKind::RArrowAlt; }
|
|
template<> inline NodeKind getNodeType<LetKeyword>() { return NodeKind::LetKeyword; }
|
|
template<> inline NodeKind getNodeType<MutKeyword>() { return NodeKind::MutKeyword; }
|
|
template<> inline NodeKind getNodeType<PubKeyword>() { return NodeKind::PubKeyword; }
|
|
template<> inline NodeKind getNodeType<TypeKeyword>() { return NodeKind::TypeKeyword; }
|
|
template<> inline NodeKind getNodeType<ReturnKeyword>() { return NodeKind::ReturnKeyword; }
|
|
template<> inline NodeKind getNodeType<ModKeyword>() { return NodeKind::ModKeyword; }
|
|
template<> inline NodeKind getNodeType<StructKeyword>() { return NodeKind::StructKeyword; }
|
|
template<> inline NodeKind getNodeType<ClassKeyword>() { return NodeKind::ClassKeyword; }
|
|
template<> inline NodeKind getNodeType<InstanceKeyword>() { return NodeKind::InstanceKeyword; }
|
|
template<> inline NodeKind getNodeType<ElifKeyword>() { return NodeKind::ElifKeyword; }
|
|
template<> inline NodeKind getNodeType<IfKeyword>() { return NodeKind::IfKeyword; }
|
|
template<> inline NodeKind getNodeType<MatchKeyword>() { return NodeKind::MatchKeyword; }
|
|
template<> inline NodeKind getNodeType<ElseKeyword>() { return NodeKind::ElseKeyword; }
|
|
template<> inline NodeKind getNodeType<Invalid>() { return NodeKind::Invalid; }
|
|
template<> inline NodeKind getNodeType<EndOfFile>() { return NodeKind::EndOfFile; }
|
|
template<> inline NodeKind getNodeType<BlockStart>() { return NodeKind::BlockStart; }
|
|
template<> inline NodeKind getNodeType<BlockEnd>() { return NodeKind::BlockEnd; }
|
|
template<> inline NodeKind getNodeType<LineFoldEnd>() { return NodeKind::LineFoldEnd; }
|
|
template<> inline NodeKind getNodeType<CustomOperator>() { return NodeKind::CustomOperator; }
|
|
template<> inline NodeKind getNodeType<Assignment>() { return NodeKind::Assignment; }
|
|
template<> inline NodeKind getNodeType<Identifier>() { return NodeKind::Identifier; }
|
|
template<> inline NodeKind getNodeType<IdentifierAlt>() { return NodeKind::IdentifierAlt; }
|
|
template<> inline NodeKind getNodeType<StringLiteral>() { return NodeKind::StringLiteral; }
|
|
template<> inline NodeKind getNodeType<IntegerLiteral>() { return NodeKind::IntegerLiteral; }
|
|
template<> inline NodeKind getNodeType<QualifiedTypeExpression>() { return NodeKind::QualifiedTypeExpression; }
|
|
template<> inline NodeKind getNodeType<ReferenceTypeExpression>() { return NodeKind::ReferenceTypeExpression; }
|
|
template<> inline NodeKind getNodeType<ArrowTypeExpression>() { return NodeKind::ArrowTypeExpression; }
|
|
template<> inline NodeKind getNodeType<BindPattern>() { return NodeKind::BindPattern; }
|
|
template<> inline NodeKind getNodeType<ReferenceExpression>() { return NodeKind::ReferenceExpression; }
|
|
template<> inline NodeKind getNodeType<NestedExpression>() { return NodeKind::NestedExpression; }
|
|
template<> inline NodeKind getNodeType<ConstantExpression>() { return NodeKind::ConstantExpression; }
|
|
template<> inline NodeKind getNodeType<CallExpression>() { return NodeKind::CallExpression; }
|
|
template<> inline NodeKind getNodeType<InfixExpression>() { return NodeKind::InfixExpression; }
|
|
template<> inline NodeKind getNodeType<PrefixExpression>() { return NodeKind::PrefixExpression; }
|
|
template<> inline NodeKind getNodeType<ExpressionStatement>() { return NodeKind::ExpressionStatement; }
|
|
template<> inline NodeKind getNodeType<ReturnStatement>() { return NodeKind::ReturnStatement; }
|
|
template<> inline NodeKind getNodeType<IfStatement>() { return NodeKind::IfStatement; }
|
|
template<> inline NodeKind getNodeType<IfStatementPart>() { return NodeKind::IfStatementPart; }
|
|
template<> inline NodeKind getNodeType<TypeAssert>() { return NodeKind::TypeAssert; }
|
|
template<> inline NodeKind getNodeType<Parameter>() { return NodeKind::Parameter; }
|
|
template<> inline NodeKind getNodeType<LetBlockBody>() { return NodeKind::LetBlockBody; }
|
|
template<> inline NodeKind getNodeType<LetExprBody>() { return NodeKind::LetExprBody; }
|
|
template<> inline NodeKind getNodeType<LetDeclaration>() { return NodeKind::LetDeclaration; }
|
|
template<> inline NodeKind getNodeType<RecordDeclarationField>() { return NodeKind::RecordDeclarationField; }
|
|
template<> inline NodeKind getNodeType<RecordDeclaration>() { return NodeKind::RecordDeclaration; }
|
|
template<> inline NodeKind getNodeType<ClassDeclaration>() { return NodeKind::ClassDeclaration; }
|
|
template<> inline NodeKind getNodeType<InstanceDeclaration>() { return NodeKind::InstanceDeclaration; }
|
|
template<> inline NodeKind getNodeType<SourceFile>() { return NodeKind::SourceFile; }
|
|
|
|
}
|
|
|
|
#endif
|