3027 lines
65 KiB
C++
3027 lines
65 KiB
C++
#ifndef BOLT_CST_HPP
|
|
#define BOLT_CST_HPP
|
|
|
|
#include <stdint.h>
|
|
#include <cmath>
|
|
#include <cstdlib>
|
|
#include <unordered_map>
|
|
#include <variant>
|
|
#include <vector>
|
|
#include <optional>
|
|
|
|
#include "zen/config.hpp"
|
|
#include "zen/range.hpp"
|
|
|
|
#include "bolt/Common.hpp"
|
|
#include "bolt/Integer.hpp"
|
|
#include "bolt/String.hpp"
|
|
#include "bolt/ByteString.hpp"
|
|
#include "bolt/Type.hpp"
|
|
|
|
namespace bolt {
|
|
|
|
class Token;
|
|
class SourceFile;
|
|
class Scope;
|
|
class Pattern;
|
|
class Expression;
|
|
|
|
class TextLoc {
|
|
public:
|
|
|
|
std::size_t Line = 1;
|
|
std::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<std::size_t> LineOffsets;
|
|
|
|
public:
|
|
|
|
TextFile(ByteString Path, ByteString Text);
|
|
|
|
std::size_t getLine(std::size_t Offset) const;
|
|
std::size_t getColumn(std::size_t Offset) const;
|
|
std::size_t getStartOffsetOfLine(std::size_t Line) const;
|
|
std::size_t getEndOffsetOfLine(std::size_t Line) const;
|
|
|
|
std::size_t getLineCount() const;
|
|
|
|
ByteString getPath() const;
|
|
|
|
ByteString getText() const;
|
|
|
|
};
|
|
|
|
enum class NodeKind {
|
|
|
|
// Plain tokens
|
|
Assignment,
|
|
At,
|
|
Backslash,
|
|
Colon,
|
|
Comma,
|
|
CustomOperator,
|
|
DoKeyword,
|
|
Dot,
|
|
DotDot,
|
|
Equals,
|
|
Identifier,
|
|
IdentifierAlt,
|
|
LBrace,
|
|
LBracket,
|
|
LParen,
|
|
RArrow,
|
|
RArrowAlt,
|
|
RBrace,
|
|
RBracket,
|
|
RParen,
|
|
Tilde,
|
|
VBar,
|
|
WrappedOperator,
|
|
|
|
// Keywords
|
|
ClassKeyword,
|
|
ElifKeyword,
|
|
ElseKeyword,
|
|
EnumKeyword,
|
|
FnKeyword,
|
|
ForeignKeyword,
|
|
IfKeyword,
|
|
InstanceKeyword,
|
|
LetKeyword,
|
|
MatchKeyword,
|
|
ModKeyword,
|
|
MutKeyword,
|
|
PubKeyword,
|
|
ReturnKeyword,
|
|
StructKeyword,
|
|
TypeKeyword,
|
|
|
|
// Virtual tokens
|
|
BlockStart,
|
|
BlockEnd,
|
|
LineFoldEnd,
|
|
EndOfFile,
|
|
Invalid,
|
|
|
|
// Literal tokens
|
|
StringLiteral,
|
|
IntegerLiteral,
|
|
|
|
// Annotations
|
|
ExpressionAnnotation,
|
|
TypeAssertAnnotation,
|
|
|
|
// Constraint expressions
|
|
TypeclassConstraintExpression,
|
|
EqualityConstraintExpression,
|
|
|
|
RecordTypeExpressionField,
|
|
|
|
// Type expressions
|
|
AppTypeExpression,
|
|
ArrowTypeExpression,
|
|
NestedTypeExpression,
|
|
QualifiedTypeExpression,
|
|
RecordTypeExpression,
|
|
ReferenceTypeExpression,
|
|
TupleTypeExpression,
|
|
VarTypeExpression,
|
|
|
|
RecordPatternField,
|
|
|
|
// Patterns
|
|
BindPattern,
|
|
ListPattern,
|
|
LiteralPattern,
|
|
NamedRecordPattern,
|
|
NamedTuplePattern,
|
|
NestedPattern,
|
|
RecordPattern,
|
|
TuplePattern,
|
|
|
|
MatchCase,
|
|
RecordExpressionField,
|
|
IfExpressionPart,
|
|
|
|
// Expressions
|
|
BlockExpression,
|
|
CallExpression,
|
|
FunctionExpression,
|
|
IfExpression,
|
|
InfixExpression,
|
|
LiteralExpression,
|
|
MatchExpression,
|
|
MemberExpression,
|
|
NestedExpression,
|
|
PrefixExpression,
|
|
RecordExpression,
|
|
ReferenceExpression,
|
|
ReturnExpression,
|
|
TupleExpression,
|
|
|
|
TypeAssert,
|
|
Parameter,
|
|
|
|
// Bodies of a let-declaration or function declaration
|
|
LetBlockBody,
|
|
LetExprBody,
|
|
|
|
// Function declarations
|
|
PrefixFunctionDeclaration,
|
|
InfixFunctionDeclaration,
|
|
SuffixFunctionDeclaration,
|
|
NamedFunctionDeclaration,
|
|
|
|
RecordDeclarationField,
|
|
TupleVariantDeclarationMember,
|
|
RecordVariantDeclarationMember,
|
|
|
|
// Other declarations
|
|
ClassDeclaration,
|
|
InstanceDeclaration,
|
|
RecordDeclaration,
|
|
VariableDeclaration,
|
|
VariantDeclaration,
|
|
|
|
SourceFile,
|
|
};
|
|
|
|
struct SymbolPath {
|
|
std::vector<ByteString> Modules;
|
|
ByteString Name;
|
|
};
|
|
|
|
template<typename T>
|
|
NodeKind getNodeType();
|
|
|
|
enum NodeFlags {
|
|
NodeFlags_TypeIsSolved = 1,
|
|
};
|
|
|
|
using NodeFlagsMask = unsigned;
|
|
|
|
class Node;
|
|
|
|
template<typename T>
|
|
bool _is_helper(const Node* N) noexcept;
|
|
|
|
class Node {
|
|
|
|
unsigned RefCount = 1;
|
|
|
|
const NodeKind K;
|
|
|
|
public:
|
|
|
|
NodeFlagsMask Flags = 0;
|
|
Node* Parent = nullptr;
|
|
|
|
inline void ref() {
|
|
++RefCount;
|
|
}
|
|
|
|
void unref();
|
|
|
|
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 K;
|
|
}
|
|
|
|
virtual TextRange getRange() const;
|
|
|
|
inline Node(NodeKind Type):
|
|
K(Type) {}
|
|
|
|
const SourceFile* getSourceFile() const;
|
|
SourceFile* getSourceFile();
|
|
|
|
virtual Scope* getScope();
|
|
|
|
virtual ~Node() {}
|
|
|
|
};
|
|
|
|
enum class SymbolKind {
|
|
Var,
|
|
Class,
|
|
Type,
|
|
Constructor,
|
|
};
|
|
|
|
class Scope {
|
|
|
|
Node* Source;
|
|
std::unordered_multimap<ByteString, std::tuple<Node*, SymbolKind>> Mapping;
|
|
|
|
void addSymbol(ByteString Name, Node* Decl, SymbolKind Kind);
|
|
|
|
void scan(Node* X);
|
|
void scanChild(Node* X);
|
|
|
|
void visitPattern(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 std::size_t getStartLine() const override {
|
|
return StartLoc.Line;
|
|
}
|
|
|
|
inline std::size_t getStartColumn() const override {
|
|
return StartLoc.Column;
|
|
}
|
|
|
|
inline std::size_t getEndLine() const override {
|
|
return getEndLoc().Line;
|
|
}
|
|
|
|
inline std::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 constexpr NodeKind Kind = NodeKind::Equals;
|
|
|
|
};
|
|
|
|
class VBar : public Token {
|
|
public:
|
|
|
|
inline VBar(TextLoc StartLoc):
|
|
Token(NodeKind::VBar, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::VBar;
|
|
|
|
};
|
|
|
|
class Colon : public Token {
|
|
public:
|
|
|
|
inline Colon(TextLoc StartLoc):
|
|
Token(NodeKind::Colon, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::Colon;
|
|
|
|
};
|
|
|
|
class Comma : public Token {
|
|
public:
|
|
|
|
inline Comma(TextLoc StartLoc):
|
|
Token(NodeKind::Comma, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::Comma;
|
|
|
|
};
|
|
|
|
class Dot : public Token {
|
|
public:
|
|
|
|
inline Dot(TextLoc StartLoc):
|
|
Token(NodeKind::Dot, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::Dot;
|
|
|
|
};
|
|
|
|
class DotDot : public Token {
|
|
public:
|
|
|
|
inline DotDot(TextLoc StartLoc):
|
|
Token(NodeKind::DotDot, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::DotDot;
|
|
|
|
};
|
|
|
|
class Tilde : public Token {
|
|
public:
|
|
|
|
inline Tilde(TextLoc StartLoc):
|
|
Token(NodeKind::Tilde, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::Tilde;
|
|
|
|
};
|
|
|
|
class At : public Token {
|
|
public:
|
|
|
|
inline At(TextLoc StartLoc):
|
|
Token(NodeKind::At, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::At;
|
|
|
|
};
|
|
|
|
class Backslash : public Token {
|
|
public:
|
|
|
|
inline Backslash(TextLoc StartLoc):
|
|
Token(NodeKind::Backslash, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::Backslash;
|
|
|
|
};
|
|
|
|
class DoKeyword : public Token {
|
|
public:
|
|
|
|
inline DoKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::DoKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::DoKeyword;
|
|
|
|
};
|
|
|
|
class LParen : public Token {
|
|
public:
|
|
|
|
inline LParen(TextLoc StartLoc):
|
|
Token(NodeKind::LParen, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::LParen;
|
|
|
|
};
|
|
|
|
class RParen : public Token {
|
|
public:
|
|
|
|
inline RParen(TextLoc StartLoc):
|
|
Token(NodeKind::RParen, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RParen;
|
|
|
|
};
|
|
|
|
class LBracket : public Token {
|
|
public:
|
|
|
|
inline LBracket(TextLoc StartLoc):
|
|
Token(NodeKind::LBracket, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::LBracket;
|
|
|
|
};
|
|
|
|
class RBracket : public Token {
|
|
public:
|
|
|
|
inline RBracket(TextLoc StartLoc):
|
|
Token(NodeKind::RBracket, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RBracket;
|
|
|
|
};
|
|
|
|
class LBrace : public Token {
|
|
public:
|
|
|
|
inline LBrace(TextLoc StartLoc):
|
|
Token(NodeKind::LBrace, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::LBrace;
|
|
|
|
};
|
|
|
|
class RBrace : public Token {
|
|
public:
|
|
|
|
inline RBrace(TextLoc StartLoc):
|
|
Token(NodeKind::RBrace, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RBrace;
|
|
|
|
};
|
|
|
|
class RArrow : public Token {
|
|
public:
|
|
|
|
inline RArrow(TextLoc StartLoc):
|
|
Token(NodeKind::RArrow, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RArrow;
|
|
|
|
};
|
|
|
|
class RArrowAlt : public Token {
|
|
public:
|
|
|
|
inline RArrowAlt(TextLoc StartLoc):
|
|
Token(NodeKind::RArrowAlt, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RArrowAlt;
|
|
|
|
};
|
|
|
|
class LetKeyword : public Token {
|
|
public:
|
|
|
|
inline LetKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::LetKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::LetKeyword;
|
|
|
|
};
|
|
|
|
class MutKeyword : public Token {
|
|
public:
|
|
|
|
inline MutKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::MutKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::MutKeyword;
|
|
|
|
};
|
|
|
|
class PubKeyword : public Token {
|
|
public:
|
|
|
|
inline PubKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::PubKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::PubKeyword;
|
|
|
|
};
|
|
|
|
class ForeignKeyword : public Token {
|
|
public:
|
|
|
|
inline ForeignKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ForeignKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ForeignKeyword;
|
|
|
|
};
|
|
|
|
class TypeKeyword : public Token {
|
|
public:
|
|
|
|
inline TypeKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::TypeKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::TypeKeyword;
|
|
|
|
};
|
|
|
|
class ReturnKeyword : public Token {
|
|
public:
|
|
|
|
inline ReturnKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ReturnKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ReturnKeyword;
|
|
|
|
};
|
|
|
|
class ModKeyword : public Token {
|
|
public:
|
|
|
|
inline ModKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ModKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ModKeyword;
|
|
|
|
};
|
|
|
|
class StructKeyword : public Token {
|
|
public:
|
|
|
|
inline StructKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::StructKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::StructKeyword;
|
|
|
|
};
|
|
|
|
class EnumKeyword : public Token {
|
|
public:
|
|
|
|
inline EnumKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::EnumKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::EnumKeyword;
|
|
|
|
};
|
|
|
|
class FnKeyword : public Token {
|
|
public:
|
|
|
|
inline FnKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::FnKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::FnKeyword;
|
|
|
|
};
|
|
|
|
class ClassKeyword : public Token {
|
|
public:
|
|
|
|
inline ClassKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ClassKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ClassKeyword;
|
|
|
|
};
|
|
|
|
class InstanceKeyword : public Token {
|
|
public:
|
|
|
|
inline InstanceKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::InstanceKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::InstanceKeyword;
|
|
|
|
};
|
|
|
|
class ElifKeyword : public Token {
|
|
public:
|
|
|
|
inline ElifKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ElifKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ElifKeyword;
|
|
|
|
};
|
|
|
|
class IfKeyword : public Token {
|
|
public:
|
|
|
|
inline IfKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::IfKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::IfKeyword;
|
|
|
|
};
|
|
|
|
class ElseKeyword : public Token {
|
|
public:
|
|
|
|
inline ElseKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::ElseKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ElseKeyword;
|
|
|
|
};
|
|
|
|
class MatchKeyword : public Token {
|
|
public:
|
|
|
|
inline MatchKeyword(TextLoc StartLoc):
|
|
Token(NodeKind::MatchKeyword, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::MatchKeyword;
|
|
|
|
};
|
|
|
|
class Invalid : public Token {
|
|
public:
|
|
|
|
inline Invalid(TextLoc StartLoc):
|
|
Token(NodeKind::Invalid, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::Invalid;
|
|
|
|
};
|
|
|
|
class EndOfFile : public Token {
|
|
public:
|
|
|
|
inline EndOfFile(TextLoc StartLoc):
|
|
Token(NodeKind::EndOfFile, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::EndOfFile;
|
|
|
|
};
|
|
|
|
class BlockStart : public Token {
|
|
public:
|
|
|
|
inline BlockStart(TextLoc StartLoc):
|
|
Token(NodeKind::BlockStart, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::BlockStart;
|
|
|
|
};
|
|
|
|
class BlockEnd : public Token {
|
|
public:
|
|
|
|
inline BlockEnd(TextLoc StartLoc):
|
|
Token(NodeKind::BlockEnd, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::BlockEnd;
|
|
|
|
};
|
|
|
|
class LineFoldEnd : public Token {
|
|
public:
|
|
|
|
inline LineFoldEnd(TextLoc StartLoc):
|
|
Token(NodeKind::LineFoldEnd, StartLoc) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
static constexpr const NodeKind Kind = 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;
|
|
|
|
std::string getCanonicalText() const;
|
|
|
|
static constexpr const NodeKind Kind = 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 constexpr const NodeKind Kind = NodeKind::Assignment;
|
|
|
|
};
|
|
|
|
class Identifier : public Token {
|
|
public:
|
|
|
|
ByteString Text;
|
|
|
|
Identifier(ByteString Text, TextLoc StartLoc = TextLoc::empty()):
|
|
Token(NodeKind::Identifier, StartLoc), Text(Text) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
ByteString getCanonicalText() const;
|
|
|
|
bool isTypeVar() const;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::Identifier;
|
|
|
|
};
|
|
|
|
class IdentifierAlt : public Token {
|
|
public:
|
|
|
|
ByteString Text;
|
|
|
|
IdentifierAlt(ByteString Text, TextLoc StartLoc):
|
|
Token(NodeKind::IdentifierAlt, StartLoc), Text(Text) {}
|
|
|
|
std::string getText() const override;
|
|
|
|
ByteString getCanonicalText() const;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::IdentifierAlt;
|
|
|
|
};
|
|
|
|
using LiteralValue = std::variant<ByteString, Integer>;
|
|
|
|
class Literal : public Token {
|
|
public:
|
|
|
|
inline Literal(NodeKind Kind, TextLoc StartLoc):
|
|
Token(Kind, StartLoc) {}
|
|
|
|
virtual LiteralValue 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;
|
|
|
|
LiteralValue getValue() override;
|
|
|
|
static constexpr const NodeKind Kind = 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;
|
|
}
|
|
|
|
inline int asInt() const {
|
|
ZEN_ASSERT(V >= std::numeric_limits<int>::min() && V <= std::numeric_limits<int>::max());
|
|
return V;
|
|
}
|
|
|
|
LiteralValue getValue() override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::IntegerLiteral;
|
|
|
|
};
|
|
|
|
/// Base node for things that can be used as an operator
|
|
///
|
|
/// This includes the following nodes:
|
|
/// - VBar
|
|
/// - CustomOperator
|
|
class Operator {
|
|
|
|
Node* N;
|
|
|
|
Operator(Node* N):
|
|
N(N) {}
|
|
|
|
public:
|
|
|
|
Operator() {}
|
|
|
|
Operator(VBar* N):
|
|
N(N) {}
|
|
|
|
Operator(CustomOperator* N):
|
|
N(N) {}
|
|
|
|
static Operator from_raw_node(Node* N) {
|
|
ZEN_ASSERT(isa<Operator>(N));
|
|
return N;
|
|
}
|
|
|
|
inline NodeKind getKind() const {
|
|
return N->getKind();
|
|
}
|
|
|
|
inline bool isVBar() const {
|
|
return N->getKind() == NodeKind::VBar;
|
|
}
|
|
|
|
inline bool isCustomOperator() const {
|
|
return N->getKind() == NodeKind::CustomOperator;
|
|
}
|
|
|
|
VBar* asVBar() const {
|
|
return static_cast<VBar*>(N);
|
|
}
|
|
|
|
CustomOperator* asCustomOperator() const {
|
|
return static_cast<CustomOperator*>(N);
|
|
}
|
|
|
|
operator Node*() const {
|
|
return N;
|
|
}
|
|
|
|
/// Get the name that is actually represented by an operator, without all the
|
|
/// syntactic sugar.
|
|
virtual ByteString getCanonicalText() const;
|
|
|
|
Token* getFirstToken() const;
|
|
Token* getLastToken() const;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::VBar
|
|
|| N->getKind() == NodeKind::CustomOperator;
|
|
}
|
|
|
|
};
|
|
class WrappedOperator : public Node {
|
|
public:
|
|
|
|
class LParen* LParen;
|
|
Operator Op;
|
|
class RParen* RParen;
|
|
|
|
WrappedOperator(
|
|
class LParen* LParen,
|
|
Operator Operator,
|
|
class RParen* RParen
|
|
): Node(NodeKind::WrappedOperator),
|
|
LParen(LParen),
|
|
Op(Operator),
|
|
RParen(RParen) {}
|
|
|
|
inline Operator getOperator() const {
|
|
return Op;
|
|
}
|
|
|
|
ByteString getCanonicalText() const {
|
|
return Op.getCanonicalText();
|
|
}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::WrappedOperator;
|
|
|
|
};
|
|
|
|
/// Base node for things that can be used as a symbol
|
|
///
|
|
/// This includes the following nodes:
|
|
/// - WrappedOperator
|
|
/// - Identifier
|
|
/// - IdentifierAlt
|
|
class Symbol {
|
|
|
|
Node* N;
|
|
|
|
Symbol(Node* N):
|
|
N(N) {}
|
|
|
|
public:
|
|
|
|
Symbol() {}
|
|
|
|
Symbol(WrappedOperator* N):
|
|
N(N) {}
|
|
|
|
Symbol(Identifier* N):
|
|
N(N) {}
|
|
|
|
Symbol(IdentifierAlt* N):
|
|
N(N) {}
|
|
|
|
static Symbol from_raw_node(Node* N) {
|
|
ZEN_ASSERT(isa<Symbol>(N));
|
|
return N;
|
|
}
|
|
|
|
NodeKind getKind() const {
|
|
return N->getKind();
|
|
}
|
|
|
|
bool isWrappedOperator() const {
|
|
return N->getKind() == NodeKind::WrappedOperator;
|
|
}
|
|
|
|
bool isIdentifier() const {
|
|
return N->getKind() == NodeKind::Identifier;
|
|
}
|
|
|
|
bool isIdentifierAlt() const {
|
|
return N->getKind() == NodeKind::IdentifierAlt;
|
|
}
|
|
|
|
IdentifierAlt* asIdentifierAlt() const {
|
|
return cast<IdentifierAlt>(N);
|
|
}
|
|
|
|
Identifier* asIdentifier() const {
|
|
return cast<Identifier>(N);
|
|
}
|
|
|
|
WrappedOperator* asWrappedOperator() const {
|
|
return cast<WrappedOperator>(N);
|
|
}
|
|
|
|
operator Node*() const {
|
|
return N;
|
|
}
|
|
|
|
/// Get the name that is actually represented by a symbol, without all the
|
|
/// syntactic sugar.
|
|
ByteString getCanonicalText() const;
|
|
|
|
Token* getFirstToken() const;
|
|
Token* getLastToken() const;
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::Identifier
|
|
|| N->getKind() == NodeKind::IdentifierAlt
|
|
|| N->getKind() == NodeKind::WrappedOperator;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
class Annotation : public Node {
|
|
public:
|
|
|
|
inline Annotation(NodeKind Kind):
|
|
Node(Kind) {}
|
|
|
|
};
|
|
|
|
class AnnotationContainer {
|
|
public:
|
|
|
|
std::vector<Annotation*> Annotations;
|
|
|
|
inline AnnotationContainer():
|
|
Annotations({}) {}
|
|
|
|
inline AnnotationContainer(std::vector<Annotation*> Annotations):
|
|
Annotations(Annotations) {}
|
|
|
|
};
|
|
|
|
class ExpressionAnnotation : public Annotation {
|
|
public:
|
|
|
|
class At* At;
|
|
class Expression* Expression;
|
|
|
|
inline ExpressionAnnotation(
|
|
class At* At,
|
|
class Expression* Expression
|
|
): Annotation(NodeKind::ExpressionAnnotation),
|
|
At(At),
|
|
Expression(Expression) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
inline class Expression* getExpression() const noexcept {
|
|
return Expression;
|
|
}
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ExpressionAnnotation;
|
|
|
|
};
|
|
|
|
class TypeExpression;
|
|
|
|
class TypeAssertAnnotation : public Annotation {
|
|
public:
|
|
|
|
class At* At;
|
|
class Colon* Colon;
|
|
TypeExpression* TE;
|
|
|
|
inline TypeAssertAnnotation(
|
|
class At* At,
|
|
class Colon* Colon,
|
|
TypeExpression* TE
|
|
): Annotation(NodeKind::TypeAssertAnnotation),
|
|
At(At),
|
|
Colon(Colon),
|
|
TE(TE) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
inline TypeExpression* getTypeExpression() const noexcept {
|
|
return TE;
|
|
}
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::TypeAssertAnnotation;
|
|
|
|
};
|
|
|
|
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;
|
|
}
|
|
|
|
static bool classof(const Node* N);
|
|
|
|
};
|
|
|
|
class TypeExpression : public TypedNode, AnnotationContainer {
|
|
protected:
|
|
|
|
inline TypeExpression(NodeKind Kind, std::vector<Annotation*> Annotations = {}):
|
|
TypedNode(Kind), AnnotationContainer(Annotations) {}
|
|
|
|
public:
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::ReferenceTypeExpression
|
|
|| N->getKind() == NodeKind::AppTypeExpression
|
|
|| N->getKind() == NodeKind::NestedTypeExpression
|
|
|| N->getKind() == NodeKind::ArrowTypeExpression
|
|
|| N->getKind() == NodeKind::VarTypeExpression
|
|
|| N->getKind() == NodeKind::TupleTypeExpression
|
|
|| N->getKind() == NodeKind::RecordTypeExpression
|
|
|| N->getKind() == NodeKind::QualifiedTypeExpression;
|
|
}
|
|
|
|
};
|
|
|
|
class ConstraintExpression : public Node {
|
|
public:
|
|
|
|
inline ConstraintExpression(NodeKind Kind):
|
|
Node(Kind) {}
|
|
|
|
};
|
|
|
|
class RecordTypeExpressionField : public Node {
|
|
public:
|
|
|
|
Identifier* Name;
|
|
class Colon* Colon;
|
|
TypeExpression* TE;
|
|
|
|
inline RecordTypeExpressionField(
|
|
Identifier* Name,
|
|
class Colon* Colon,
|
|
TypeExpression* TE
|
|
): Node(NodeKind::RecordTypeExpressionField),
|
|
Name(Name),
|
|
Colon(Colon),
|
|
TE(TE) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RecordTypeExpressionField;
|
|
|
|
};
|
|
|
|
class RecordTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
class LBrace* LBrace;
|
|
std::vector<std::tuple<RecordTypeExpressionField*, Comma*>> Fields;
|
|
class VBar* VBar;
|
|
TypeExpression* Rest;
|
|
class RBrace* RBrace;
|
|
|
|
inline RecordTypeExpression(
|
|
class LBrace* LBrace,
|
|
std::vector<std::tuple<RecordTypeExpressionField*, Comma*>> Fields,
|
|
class VBar* VBar,
|
|
TypeExpression* Rest,
|
|
class RBrace* RBrace
|
|
): TypeExpression(NodeKind::RecordTypeExpression),
|
|
LBrace(LBrace),
|
|
Fields(Fields),
|
|
VBar(VBar),
|
|
Rest(Rest),
|
|
RBrace(RBrace) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RecordTypeExpression;
|
|
|
|
};
|
|
|
|
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 constexpr const NodeKind Kind = 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 constexpr const NodeKind Kind = 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 constexpr const NodeKind Kind = 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;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ReferenceTypeExpression;
|
|
|
|
};
|
|
|
|
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;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ArrowTypeExpression;
|
|
|
|
};
|
|
|
|
class AppTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
TypeExpression* Op;
|
|
std::vector<TypeExpression*> Args;
|
|
|
|
inline AppTypeExpression(
|
|
TypeExpression* Op,
|
|
std::vector<TypeExpression*> Args
|
|
): TypeExpression(NodeKind::AppTypeExpression),
|
|
Op(Op),
|
|
Args(Args) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::AppTypeExpression;
|
|
|
|
};
|
|
|
|
class VarTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
Identifier* Name;
|
|
|
|
inline VarTypeExpression(Identifier* Name):
|
|
TypeExpression(NodeKind::VarTypeExpression), Name(Name) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::VarTypeExpression;
|
|
|
|
};
|
|
|
|
class NestedTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
class LParen* LParen;
|
|
TypeExpression* TE;
|
|
class 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;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::NestedTypeExpression;
|
|
|
|
};
|
|
|
|
class TupleTypeExpression : public TypeExpression {
|
|
public:
|
|
|
|
class LParen* LParen;
|
|
std::vector<std::tuple<TypeExpression*, Comma*>> Elements;
|
|
class 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;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::TupleTypeExpression;
|
|
|
|
};
|
|
|
|
|
|
class Pattern : public Node {
|
|
protected:
|
|
|
|
inline Pattern(NodeKind Type):
|
|
Node(Type) {}
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::BindPattern
|
|
|| N->getKind() == NodeKind::ListPattern
|
|
|| N->getKind() == NodeKind::LiteralPattern
|
|
|| N->getKind() == NodeKind::NamedRecordPattern
|
|
|| N->getKind() == NodeKind::NamedTuplePattern
|
|
|| N->getKind() == NodeKind::NestedPattern
|
|
|| N->getKind() == NodeKind::RecordPattern
|
|
|| N->getKind() == NodeKind::TuplePattern;
|
|
}
|
|
|
|
};
|
|
|
|
class BindPattern : public Pattern {
|
|
public:
|
|
|
|
Identifier* Name;
|
|
|
|
BindPattern(
|
|
Identifier* Name
|
|
): Pattern(NodeKind::BindPattern),
|
|
Name(Name) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = 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 constexpr const NodeKind Kind = NodeKind::LiteralPattern;
|
|
|
|
};
|
|
|
|
class RecordPatternField : public Node {
|
|
public:
|
|
|
|
class DotDot* DotDot;
|
|
Identifier* Name;
|
|
class Equals* Equals;
|
|
class Pattern* Pattern;
|
|
|
|
inline RecordPatternField(
|
|
class DotDot* DotDot,
|
|
Identifier* Name,
|
|
class Equals* Equals,
|
|
class Pattern* Pattern
|
|
): Node(NodeKind::RecordPatternField),
|
|
DotDot(DotDot),
|
|
Name(Name),
|
|
Equals(Equals),
|
|
Pattern(Pattern) {}
|
|
|
|
inline RecordPatternField(
|
|
Identifier* Name,
|
|
class Equals* Equals,
|
|
class Pattern* Pattern
|
|
): RecordPatternField(nullptr, Name, Equals, Pattern) {}
|
|
|
|
inline RecordPatternField(
|
|
class DotDot* DotDot
|
|
): RecordPatternField(DotDot, nullptr, nullptr, nullptr) {}
|
|
|
|
inline RecordPatternField(
|
|
class DotDot* DotDot,
|
|
class Pattern* Pattern
|
|
): RecordPatternField(DotDot, nullptr, nullptr, Pattern) {}
|
|
|
|
inline RecordPatternField(
|
|
Identifier* Name
|
|
): RecordPatternField(nullptr, Name, nullptr, nullptr) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RecordPatternField;
|
|
|
|
};
|
|
|
|
class RecordPattern : public Pattern {
|
|
public:
|
|
|
|
class LBrace* LBrace;
|
|
std::vector<std::tuple<RecordPatternField*, Comma*>> Fields;
|
|
class RBrace* RBrace;
|
|
|
|
inline RecordPattern(
|
|
class LBrace* LBrace,
|
|
std::vector<std::tuple<RecordPatternField*, Comma*>> Fields,
|
|
class RBrace* RBrace
|
|
): Pattern(NodeKind::RecordPattern),
|
|
LBrace(LBrace),
|
|
Fields(Fields),
|
|
RBrace(RBrace) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RecordPattern;
|
|
|
|
};
|
|
|
|
class NamedRecordPattern : public Pattern {
|
|
public:
|
|
|
|
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
|
|
IdentifierAlt* Name;
|
|
class LBrace* LBrace;
|
|
std::vector<std::tuple<RecordPatternField*, Comma*>> Fields;
|
|
class RBrace* RBrace;
|
|
|
|
inline NamedRecordPattern(
|
|
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath,
|
|
IdentifierAlt* Name,
|
|
class LBrace* LBrace,
|
|
std::vector<std::tuple<RecordPatternField*, Comma*>> Fields,
|
|
class RBrace* RBrace
|
|
): Pattern(NodeKind::NamedRecordPattern),
|
|
ModulePath(ModulePath),
|
|
Name(Name),
|
|
LBrace(LBrace),
|
|
Fields(Fields),
|
|
RBrace(RBrace) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::NamedRecordPattern;
|
|
|
|
};
|
|
|
|
class NamedTuplePattern : public Pattern {
|
|
public:
|
|
|
|
IdentifierAlt* Name;
|
|
std::vector<Pattern*> Patterns;
|
|
|
|
inline NamedTuplePattern(
|
|
IdentifierAlt* Name,
|
|
std::vector<Pattern*> Patterns
|
|
): Pattern(NodeKind::NamedTuplePattern),
|
|
Name(Name),
|
|
Patterns(Patterns) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::NamedTuplePattern;
|
|
|
|
};
|
|
|
|
class TuplePattern : public Pattern {
|
|
public:
|
|
|
|
class LParen* LParen;
|
|
std::vector<std::tuple<Pattern*, Comma*>> Elements;
|
|
class RParen* RParen;
|
|
|
|
inline TuplePattern(
|
|
class LParen* LParen,
|
|
std::vector<std::tuple<Pattern*, Comma*>> Elements,
|
|
class RParen* RParen
|
|
): Pattern(NodeKind::TuplePattern),
|
|
LParen(LParen),
|
|
Elements(Elements),
|
|
RParen(RParen) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::TuplePattern;
|
|
|
|
};
|
|
|
|
class NestedPattern : public Pattern {
|
|
public:
|
|
|
|
class LParen* LParen;
|
|
Pattern* P;
|
|
class RParen* RParen;
|
|
|
|
inline NestedPattern(
|
|
class LParen* LParen,
|
|
Pattern* P,
|
|
class RParen* RParen
|
|
): Pattern(NodeKind::NestedPattern),
|
|
LParen(LParen),
|
|
P(P),
|
|
RParen(RParen) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::NestedPattern;
|
|
|
|
};
|
|
|
|
class ListPattern : public Pattern {
|
|
public:
|
|
|
|
class LBracket* LBracket;
|
|
std::vector<std::tuple<Pattern*, Comma*>> Elements;
|
|
class RBracket* RBracket;
|
|
|
|
inline ListPattern(
|
|
class LBracket* LBracket,
|
|
std::vector<std::tuple<Pattern*, Comma*>> Elements,
|
|
class RBracket* RBracket
|
|
): Pattern(NodeKind::ListPattern),
|
|
LBracket(LBracket),
|
|
Elements(Elements),
|
|
RBracket(RBracket) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ListPattern;
|
|
|
|
};
|
|
|
|
class Expression : public TypedNode, public AnnotationContainer {
|
|
protected:
|
|
|
|
inline Expression(NodeKind Kind, std::vector<Annotation*> Annotations = {}):
|
|
TypedNode(Kind), AnnotationContainer(Annotations) {}
|
|
|
|
public:
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::ReferenceExpression
|
|
|| N->getKind() == NodeKind::NestedExpression
|
|
|| N->getKind() == NodeKind::CallExpression
|
|
|| N->getKind() == NodeKind::FunctionExpression
|
|
|| N->getKind() == NodeKind::TupleExpression
|
|
|| N->getKind() == NodeKind::InfixExpression
|
|
|| N->getKind() == NodeKind::RecordExpression
|
|
|| N->getKind() == NodeKind::MatchExpression
|
|
|| N->getKind() == NodeKind::BlockExpression
|
|
|| N->getKind() == NodeKind::MemberExpression
|
|
|| N->getKind() == NodeKind::LiteralExpression
|
|
|| N->getKind() == NodeKind::BlockExpression
|
|
|| N->getKind() == NodeKind::IfExpression
|
|
|| N->getKind() == NodeKind::ReturnExpression
|
|
|| N->getKind() == NodeKind::PrefixExpression;
|
|
}
|
|
|
|
};
|
|
|
|
class ReferenceExpression : public Expression {
|
|
public:
|
|
|
|
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
|
|
Symbol Name;
|
|
|
|
inline ReferenceExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath,
|
|
Symbol Name
|
|
): Expression(NodeKind::ReferenceExpression, Annotations),
|
|
ModulePath(ModulePath),
|
|
Name(Name) {}
|
|
|
|
inline ReferenceExpression(
|
|
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath,
|
|
Symbol Name
|
|
): ReferenceExpression({}, ModulePath, Name) {}
|
|
|
|
inline ByteString getNameAsString() const noexcept {
|
|
return Name.getCanonicalText();
|
|
}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
SymbolPath getSymbolPath() const;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ReferenceExpression;
|
|
|
|
};
|
|
|
|
class MatchCase : public Node {
|
|
|
|
Scope* TheScope = nullptr;
|
|
|
|
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;
|
|
|
|
inline Scope* getScope() override {
|
|
if (TheScope == nullptr) {
|
|
TheScope = new Scope(this);
|
|
}
|
|
return TheScope;
|
|
}
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::MatchCase;
|
|
|
|
};
|
|
|
|
class MatchExpression : public Expression {
|
|
public:
|
|
|
|
class MatchKeyword* MatchKeyword;
|
|
Expression* Value;
|
|
class BlockStart* BlockStart;
|
|
std::vector<MatchCase*> Cases;
|
|
|
|
inline MatchExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
class MatchKeyword* MatchKeyword,
|
|
Expression* Value,
|
|
class BlockStart* BlockStart,
|
|
std::vector<MatchCase*> Cases
|
|
): Expression(NodeKind::MatchExpression, Annotations),
|
|
MatchKeyword(MatchKeyword),
|
|
Value(Value),
|
|
BlockStart(BlockStart),
|
|
Cases(Cases) {}
|
|
|
|
inline MatchExpression(
|
|
class MatchKeyword* MatchKeyword,
|
|
Expression* Value,
|
|
class BlockStart* BlockStart,
|
|
std::vector<MatchCase*> Cases
|
|
): MatchExpression({}, MatchKeyword, Value, BlockStart, Cases) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::MatchExpression;
|
|
|
|
};
|
|
|
|
class BlockExpression : public Expression {
|
|
public:
|
|
|
|
class DoKeyword* DoKeyword;
|
|
class BlockStart* BlockStart;
|
|
std::vector<Node*> Elements;
|
|
|
|
inline BlockExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
class DoKeyword* DoKeyword,
|
|
class BlockStart* BlockStart,
|
|
std::vector<Node*> Elements
|
|
): Expression(NodeKind::BlockExpression, Annotations),
|
|
DoKeyword(DoKeyword),
|
|
BlockStart(BlockStart),
|
|
Elements(Elements) {}
|
|
|
|
inline BlockExpression(
|
|
class DoKeyword* DoKeyword,
|
|
class BlockStart* BlockStart,
|
|
std::vector<Node*> Elements
|
|
): BlockExpression({}, DoKeyword, BlockStart, Elements) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::BlockExpression;
|
|
|
|
};
|
|
|
|
class MemberExpression : public Expression {
|
|
public:
|
|
|
|
Expression* E;
|
|
class Dot* Dot;
|
|
Token* Name;
|
|
|
|
inline MemberExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
class Expression* E,
|
|
class Dot* Dot,
|
|
Token* Name
|
|
): Expression(NodeKind::MemberExpression, Annotations),
|
|
E(E),
|
|
Dot(Dot),
|
|
Name(Name) {}
|
|
|
|
inline MemberExpression(
|
|
Expression* E,
|
|
class Dot* Dot,
|
|
Token* Name
|
|
): MemberExpression({}, E, Dot, Name) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
inline Expression* getExpression() const {
|
|
return E;
|
|
}
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::MemberExpression;
|
|
|
|
};
|
|
|
|
class TupleExpression : public Expression {
|
|
public:
|
|
|
|
class LParen* LParen;
|
|
std::vector<std::tuple<Expression*, Comma*>> Elements;
|
|
class RParen* RParen;
|
|
|
|
inline TupleExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
class LParen* LParen,
|
|
std::vector<std::tuple<Expression*, Comma*>> Elements,
|
|
class RParen* RParen
|
|
): Expression(NodeKind::TupleExpression, Annotations),
|
|
LParen(LParen),
|
|
Elements(Elements),
|
|
RParen(RParen) {}
|
|
|
|
inline TupleExpression(
|
|
class LParen* LParen,
|
|
std::vector<std::tuple<Expression*, Comma*>> Elements,
|
|
class RParen* RParen
|
|
): TupleExpression({}, LParen, Elements, RParen) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::TupleExpression;
|
|
|
|
};
|
|
|
|
class NestedExpression : public Expression {
|
|
public:
|
|
|
|
class LParen* LParen;
|
|
Expression* Inner;
|
|
class RParen* RParen;
|
|
|
|
inline NestedExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
class LParen* LParen,
|
|
Expression* Inner,
|
|
class RParen* RParen
|
|
): Expression(NodeKind::NestedExpression, Annotations),
|
|
LParen(LParen),
|
|
Inner(Inner),
|
|
RParen(RParen) {}
|
|
|
|
|
|
inline NestedExpression(
|
|
class LParen* LParen,
|
|
Expression* Inner,
|
|
class RParen* RParen
|
|
): NestedExpression({}, LParen, Inner, RParen) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::NestedExpression;
|
|
|
|
};
|
|
|
|
class LiteralExpression : public Expression {
|
|
public:
|
|
|
|
Literal* Token;
|
|
|
|
inline LiteralExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
Literal* Token
|
|
): Expression(NodeKind::LiteralExpression, Annotations),
|
|
Token(Token) {}
|
|
|
|
inline LiteralExpression(Literal* Token):
|
|
LiteralExpression({}, Token) {}
|
|
|
|
inline ByteString getAsText() {
|
|
ZEN_ASSERT(Token->getKind() == NodeKind::StringLiteral);
|
|
return static_cast<StringLiteral*>(Token)->Text;
|
|
}
|
|
|
|
inline int getAsInt() {
|
|
ZEN_ASSERT(Token->getKind() == NodeKind::IntegerLiteral);
|
|
return static_cast<IntegerLiteral*>(Token)->asInt();
|
|
}
|
|
|
|
class Token* getFirstToken() const override;
|
|
class Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::LiteralExpression;
|
|
|
|
};
|
|
|
|
class CallExpression : public Expression {
|
|
public:
|
|
|
|
Expression* Function;
|
|
std::vector<Expression*> Args;
|
|
|
|
inline CallExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
Expression* Function,
|
|
std::vector<Expression*> Args
|
|
): Expression(NodeKind::CallExpression, Annotations),
|
|
Function(Function),
|
|
Args(Args) {}
|
|
|
|
inline CallExpression(
|
|
Expression* Function,
|
|
std::vector<Expression*> Args
|
|
): CallExpression({}, Function, Args) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::CallExpression;
|
|
|
|
};
|
|
|
|
class FunctionExpression : public Expression {
|
|
|
|
public:
|
|
|
|
Backslash* Backslash;
|
|
std::vector<Pattern*> Params;
|
|
RArrow* RArrow;
|
|
Expression* E;
|
|
|
|
inline FunctionExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
class Backslash* Backslash,
|
|
std::vector<Pattern*> Params,
|
|
class RArrow* RArrow,
|
|
class Expression* E
|
|
): Expression(NodeKind::FunctionExpression, Annotations),
|
|
Backslash(Backslash),
|
|
Params(Params),
|
|
RArrow(RArrow),
|
|
E(E) {}
|
|
|
|
inline FunctionExpression(
|
|
class Backslash* Backslash,
|
|
std::vector<Pattern*> Params,
|
|
class RArrow* RArrow,
|
|
class Expression* Expression
|
|
): FunctionExpression({}, Backslash, Params, RArrow, Expression) {}
|
|
|
|
std::size_t countParams() {
|
|
return Params.size();
|
|
}
|
|
|
|
auto getParameters() {
|
|
return zen::make_iterator_range(Params);
|
|
}
|
|
|
|
Expression* getExpression() const {
|
|
return E;
|
|
}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::FunctionExpression;
|
|
|
|
};
|
|
|
|
class InfixExpression : public Expression {
|
|
public:
|
|
|
|
Expression* Left;
|
|
Operator Operator;
|
|
Expression* Right;
|
|
|
|
inline InfixExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
Expression* Left,
|
|
class Operator Operator,
|
|
Expression* Right
|
|
): Expression(NodeKind::InfixExpression, Annotations),
|
|
Left(Left),
|
|
Operator(Operator),
|
|
Right(Right) {}
|
|
|
|
inline InfixExpression(
|
|
Expression* Left,
|
|
class Operator Operator,
|
|
Expression* Right
|
|
): InfixExpression({}, Left, Operator, Right) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::InfixExpression;
|
|
|
|
};
|
|
|
|
class PrefixExpression : public Expression {
|
|
public:
|
|
|
|
Token* Operator;
|
|
Expression* Argument;
|
|
|
|
inline PrefixExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
Token* Operator,
|
|
Expression* Argument
|
|
): Expression(NodeKind::PrefixExpression, Annotations),
|
|
Operator(Operator),
|
|
Argument(Argument) {}
|
|
|
|
inline PrefixExpression(
|
|
Token* Operator,
|
|
Expression* Argument
|
|
): PrefixExpression({}, Operator, Argument) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::PrefixExpression;
|
|
|
|
};
|
|
|
|
class RecordExpressionField : public Node {
|
|
public:
|
|
|
|
Identifier* Name;
|
|
class 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;
|
|
|
|
bool hasExpression() const {
|
|
return E;
|
|
}
|
|
|
|
inline Expression* getExpression() const {
|
|
ZEN_ASSERT(E != nullptr);
|
|
return E;
|
|
}
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RecordExpressionField;
|
|
|
|
};
|
|
|
|
class RecordExpression : public Expression {
|
|
public:
|
|
|
|
class LBrace* LBrace;
|
|
std::vector<std::tuple<RecordExpressionField*, Comma*>> Fields;
|
|
class RBrace* RBrace;
|
|
|
|
inline RecordExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
class LBrace* LBrace,
|
|
std::vector<std::tuple<RecordExpressionField*, Comma*>> Fields,
|
|
class RBrace* RBrace
|
|
): Expression(NodeKind::RecordExpression, Annotations),
|
|
LBrace(LBrace),
|
|
Fields(Fields),
|
|
RBrace(RBrace) {}
|
|
|
|
inline RecordExpression(
|
|
class LBrace* LBrace,
|
|
std::vector<std::tuple<RecordExpressionField*, Comma*>> Fields,
|
|
class RBrace* RBrace
|
|
): RecordExpression({}, LBrace, Fields, RBrace) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RecordExpression;
|
|
|
|
};
|
|
|
|
class IfExpressionPart : public Node, public AnnotationContainer {
|
|
public:
|
|
|
|
Token* Keyword;
|
|
Expression* Test;
|
|
class BlockStart* BlockStart;
|
|
std::vector<Node*> Elements;
|
|
|
|
inline IfExpressionPart(
|
|
std::vector<Annotation*> Annotations,
|
|
Token* Keyword,
|
|
Expression* Test,
|
|
class BlockStart* BlockStart,
|
|
std::vector<Node*> Elements
|
|
): Node(NodeKind::IfExpressionPart),
|
|
AnnotationContainer(Annotations),
|
|
Keyword(Keyword),
|
|
Test(Test),
|
|
BlockStart(BlockStart),
|
|
Elements(Elements) {}
|
|
|
|
inline IfExpressionPart(
|
|
Token* Keyword,
|
|
Expression* Test,
|
|
class BlockStart* BlockStart,
|
|
std::vector<Node*> Elements
|
|
): IfExpressionPart({}, Keyword, Test, BlockStart, Elements) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::IfExpressionPart;
|
|
|
|
};
|
|
|
|
class IfExpression : public Expression {
|
|
public:
|
|
|
|
std::vector<IfExpressionPart*> Parts;
|
|
|
|
inline IfExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
std::vector<IfExpressionPart*> Parts
|
|
): Expression(NodeKind::IfExpression, Annotations),
|
|
Parts(Parts) {}
|
|
|
|
|
|
inline IfExpression(std::vector<IfExpressionPart*> Parts):
|
|
IfExpression({}, Parts) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::IfExpression;
|
|
|
|
};
|
|
|
|
class ReturnExpression : public Expression {
|
|
public:
|
|
|
|
class ReturnKeyword* ReturnKeyword;
|
|
Expression* E;
|
|
|
|
inline ReturnExpression(
|
|
std::vector<Annotation*> Annotations,
|
|
class ReturnKeyword* ReturnKeyword,
|
|
Expression* E
|
|
): Expression(NodeKind::ReturnExpression, Annotations),
|
|
ReturnKeyword(ReturnKeyword),
|
|
E(E) {}
|
|
|
|
inline ReturnExpression(
|
|
class ReturnKeyword* ReturnKeyword,
|
|
class Expression* Expression
|
|
): ReturnExpression({}, ReturnKeyword, Expression) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
bool hasExpression() const {
|
|
return E;
|
|
}
|
|
|
|
Expression* getExpression() {
|
|
return E;
|
|
}
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::ReturnExpression;
|
|
|
|
};
|
|
|
|
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;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::TypeAssert;
|
|
|
|
};
|
|
|
|
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;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::Parameter;
|
|
|
|
};
|
|
|
|
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;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::LetBlockBody;
|
|
|
|
};
|
|
|
|
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;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::LetExprBody;
|
|
|
|
};
|
|
|
|
class Declaration : public TypedNode, public AnnotationContainer {
|
|
|
|
std::optional<TypeScheme> Scm;
|
|
|
|
protected:
|
|
|
|
|
|
inline Declaration(NodeKind Kind, std::vector<Annotation*> Annotations = {}):
|
|
TypedNode(Kind), AnnotationContainer(Annotations) {}
|
|
|
|
public:
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::VariantDeclaration
|
|
|| N->getKind() == NodeKind::RecordDeclaration
|
|
|| N->getKind() == NodeKind::VariantDeclaration
|
|
|| N->getKind() == NodeKind::PrefixFunctionDeclaration
|
|
|| N->getKind() == NodeKind::InfixFunctionDeclaration
|
|
|| N->getKind() == NodeKind::SuffixFunctionDeclaration
|
|
|| N->getKind() == NodeKind::NamedFunctionDeclaration;
|
|
}
|
|
|
|
const TypeScheme& getScheme() const {
|
|
ZEN_ASSERT(Scm.has_value());
|
|
return *Scm;
|
|
}
|
|
|
|
bool hasScheme() const {
|
|
return Scm.has_value();
|
|
}
|
|
|
|
void setScheme(TypeScheme NewScm) {
|
|
Scm = NewScm;
|
|
}
|
|
|
|
};
|
|
|
|
class FunctionDeclaration : public Declaration {
|
|
|
|
Scope* TheScope = nullptr;
|
|
|
|
public:
|
|
|
|
bool IsCycleActive = false;
|
|
bool Visited = false;
|
|
|
|
FunctionDeclaration(NodeKind Kind, std::vector<Annotation*> Annotations = {}):
|
|
Declaration(Kind, Annotations) {}
|
|
|
|
virtual bool isPublic() const = 0;
|
|
|
|
virtual bool isForeign() const = 0;
|
|
|
|
virtual ByteString getNameAsString() const = 0;
|
|
|
|
virtual std::vector<Parameter*> getParams() const = 0;
|
|
|
|
virtual TypeAssert* getTypeAssert() const = 0;
|
|
|
|
bool hasTypeAssert() const {
|
|
return getTypeAssert();
|
|
}
|
|
|
|
virtual LetBody* getBody() const = 0;
|
|
|
|
bool hasBody() const {
|
|
return getBody();
|
|
}
|
|
|
|
inline Scope* getScope() override {
|
|
if (TheScope == nullptr) {
|
|
TheScope = new Scope(this);
|
|
}
|
|
return TheScope;
|
|
}
|
|
|
|
bool isInstance() const noexcept {
|
|
return Parent->getKind() == NodeKind::InstanceDeclaration;
|
|
}
|
|
|
|
bool isClass() const noexcept {
|
|
return Parent->getKind() == NodeKind::ClassDeclaration;
|
|
}
|
|
|
|
static bool classof(const Node* N) {
|
|
return N->getKind() == NodeKind::PrefixFunctionDeclaration
|
|
|| N->getKind() == NodeKind::InfixFunctionDeclaration
|
|
|| N->getKind() == NodeKind::SuffixFunctionDeclaration
|
|
|| N->getKind() == NodeKind::NamedFunctionDeclaration;
|
|
}
|
|
|
|
};
|
|
|
|
class PrefixFunctionDeclaration : public FunctionDeclaration {
|
|
public:
|
|
|
|
class PubKeyword* PubKeyword;
|
|
class ForeignKeyword* ForeignKeyword;
|
|
class FnKeyword* FnKeyword;
|
|
class Operator Name;
|
|
Parameter* Param;
|
|
class TypeAssert* TypeAssert;
|
|
LetBody* Body;
|
|
|
|
PrefixFunctionDeclaration(
|
|
class std::vector<Annotation*> Annotations,
|
|
class PubKeyword* PubKeyword,
|
|
class ForeignKeyword* ForeignKeyword,
|
|
class FnKeyword* FnKeyword,
|
|
Operator Name,
|
|
Parameter* Param,
|
|
class TypeAssert* TypeAssert,
|
|
LetBody* Body
|
|
): FunctionDeclaration(NodeKind::PrefixFunctionDeclaration, Annotations),
|
|
PubKeyword(PubKeyword),
|
|
ForeignKeyword(ForeignKeyword),
|
|
FnKeyword(FnKeyword),
|
|
Name(Name),
|
|
Param(Param),
|
|
TypeAssert(TypeAssert),
|
|
Body(Body) {}
|
|
|
|
bool isPublic() const override {
|
|
return PubKeyword != nullptr;
|
|
}
|
|
|
|
bool isForeign() const override {
|
|
return ForeignKeyword != nullptr;
|
|
}
|
|
|
|
ByteString getNameAsString() const override {
|
|
return Name.getCanonicalText();
|
|
}
|
|
|
|
std::vector<Parameter*> getParams() const override {
|
|
return { Param };
|
|
}
|
|
|
|
class TypeAssert* getTypeAssert() const override {
|
|
return TypeAssert;
|
|
}
|
|
|
|
LetBody* getBody() const override {
|
|
return Body;
|
|
}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::PrefixFunctionDeclaration;
|
|
|
|
};
|
|
|
|
class SuffixFunctionDeclaration : public FunctionDeclaration {
|
|
public:
|
|
|
|
class PubKeyword* PubKeyword;
|
|
class ForeignKeyword* ForeignKeyword;
|
|
class FnKeyword* FnKeyword;
|
|
Parameter* Param;
|
|
class Operator Name;
|
|
class TypeAssert* TypeAssert;
|
|
LetBody* Body;
|
|
|
|
SuffixFunctionDeclaration(
|
|
class std::vector<Annotation*> Annotations,
|
|
class PubKeyword* PubKeyword,
|
|
class ForeignKeyword* ForeignKeyword,
|
|
class FnKeyword* FnKeyword,
|
|
Parameter* Param,
|
|
Operator Name,
|
|
class TypeAssert* TypeAssert,
|
|
LetBody* Body
|
|
): FunctionDeclaration(NodeKind::SuffixFunctionDeclaration, Annotations),
|
|
PubKeyword(PubKeyword),
|
|
ForeignKeyword(ForeignKeyword),
|
|
FnKeyword(FnKeyword),
|
|
Name(Name),
|
|
Param(Param),
|
|
TypeAssert(TypeAssert),
|
|
Body(Body) {}
|
|
|
|
bool isPublic() const override {
|
|
return PubKeyword != nullptr;
|
|
}
|
|
|
|
bool isForeign() const override {
|
|
return ForeignKeyword != nullptr;
|
|
}
|
|
|
|
ByteString getNameAsString() const override {
|
|
return Name.getCanonicalText();
|
|
}
|
|
|
|
std::vector<Parameter*> getParams() const override {
|
|
return { Param };
|
|
}
|
|
|
|
class TypeAssert* getTypeAssert() const override {
|
|
return TypeAssert;
|
|
}
|
|
|
|
LetBody* getBody() const override {
|
|
return Body;
|
|
}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::SuffixFunctionDeclaration;
|
|
|
|
};
|
|
|
|
class InfixFunctionDeclaration : public FunctionDeclaration {
|
|
public:
|
|
|
|
class PubKeyword* PubKeyword;
|
|
class ForeignKeyword* ForeignKeyword;
|
|
class FnKeyword* FnKeyword;
|
|
Parameter* Left;
|
|
class Operator Name;
|
|
Parameter* Right;
|
|
class TypeAssert* TypeAssert;
|
|
LetBody* Body;
|
|
|
|
InfixFunctionDeclaration(
|
|
class std::vector<Annotation*> Annotations,
|
|
class PubKeyword* PubKeyword,
|
|
class ForeignKeyword* ForeignKeyword,
|
|
class FnKeyword* FnKeyword,
|
|
Parameter* Left,
|
|
class Operator Name,
|
|
Parameter* Right,
|
|
class TypeAssert* TypeAssert,
|
|
LetBody* Body
|
|
): FunctionDeclaration(NodeKind::InfixFunctionDeclaration, Annotations),
|
|
PubKeyword(PubKeyword),
|
|
ForeignKeyword(ForeignKeyword),
|
|
FnKeyword(FnKeyword),
|
|
Left(Left),
|
|
Name(Name),
|
|
Right(Right),
|
|
TypeAssert(TypeAssert),
|
|
Body(Body) {}
|
|
|
|
bool isPublic() const override {
|
|
return PubKeyword != nullptr;
|
|
}
|
|
|
|
bool isForeign() const override {
|
|
return ForeignKeyword != nullptr;
|
|
}
|
|
|
|
ByteString getNameAsString() const override {
|
|
return Name.getCanonicalText();
|
|
}
|
|
|
|
std::vector<Parameter*> getParams() const override {
|
|
return { Left, Right };
|
|
}
|
|
|
|
class TypeAssert* getTypeAssert() const override {
|
|
return TypeAssert;
|
|
}
|
|
|
|
LetBody* getBody() const override {
|
|
return Body;
|
|
}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::InfixFunctionDeclaration;
|
|
|
|
};
|
|
|
|
class NamedFunctionDeclaration : public FunctionDeclaration {
|
|
public:
|
|
|
|
class PubKeyword* PubKeyword;
|
|
class ForeignKeyword* ForeignKeyword;
|
|
class FnKeyword* FnKeyword;
|
|
class Symbol Name;
|
|
std::vector<Parameter*> Params;
|
|
class TypeAssert* TypeAssert;
|
|
LetBody* Body;
|
|
|
|
NamedFunctionDeclaration(
|
|
class std::vector<Annotation*> Annotations,
|
|
class PubKeyword* PubKeyword,
|
|
class ForeignKeyword* ForeignKeyword,
|
|
class FnKeyword* FnKeyword,
|
|
class Symbol Name,
|
|
std::vector<Parameter*> Params,
|
|
class TypeAssert* TypeAssert,
|
|
LetBody* Body
|
|
): FunctionDeclaration(NodeKind::NamedFunctionDeclaration, Annotations),
|
|
PubKeyword(PubKeyword),
|
|
ForeignKeyword(ForeignKeyword),
|
|
FnKeyword(FnKeyword),
|
|
Name(Name),
|
|
Params(Params),
|
|
TypeAssert(TypeAssert),
|
|
Body(Body) {}
|
|
|
|
bool isPublic() const override {
|
|
return PubKeyword != nullptr;
|
|
}
|
|
|
|
bool isForeign() const override {
|
|
return ForeignKeyword != nullptr;
|
|
}
|
|
|
|
ByteString getNameAsString() const override {
|
|
return Name.getCanonicalText();
|
|
}
|
|
|
|
std::vector<Parameter*> getParams() const override {
|
|
return Params;
|
|
}
|
|
|
|
class TypeAssert* getTypeAssert() const override {
|
|
return TypeAssert;
|
|
}
|
|
|
|
LetBody* getBody() const override {
|
|
return Body;
|
|
}
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::NamedFunctionDeclaration;
|
|
|
|
};
|
|
|
|
class VariableDeclaration : public Declaration {
|
|
public:
|
|
|
|
class PubKeyword* PubKeyword;
|
|
class LetKeyword* LetKeyword;
|
|
class MutKeyword* MutKeyword;
|
|
class Pattern* Pattern;
|
|
class TypeAssert* TypeAssert;
|
|
LetBody* Body;
|
|
|
|
VariableDeclaration(
|
|
class std::vector<Annotation*> Annotations,
|
|
class PubKeyword* PubKeyword,
|
|
class LetKeyword* LetKeyword,
|
|
class MutKeyword* MutKeyword,
|
|
class Pattern* Pattern,
|
|
class TypeAssert* TypeAssert,
|
|
LetBody* Body
|
|
): Declaration(NodeKind::VariableDeclaration, Annotations),
|
|
PubKeyword(PubKeyword),
|
|
LetKeyword(LetKeyword),
|
|
MutKeyword(MutKeyword),
|
|
Pattern(Pattern),
|
|
TypeAssert(TypeAssert),
|
|
Body(Body) {}
|
|
|
|
Symbol getName() const noexcept {
|
|
ZEN_ASSERT(Pattern->getKind() == NodeKind::BindPattern);
|
|
return static_cast<BindPattern*>(Pattern)->Name;
|
|
}
|
|
|
|
ByteString getNameAsString() const noexcept {
|
|
return getName().getCanonicalText();
|
|
}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
bool hasExpression() const {
|
|
return Body;
|
|
}
|
|
|
|
Expression* getExpression() {
|
|
ZEN_ASSERT(Body->getKind() == NodeKind::LetExprBody);
|
|
return static_cast<LetExprBody*>(Body)->Expression;
|
|
}
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::VariableDeclaration;
|
|
|
|
};
|
|
|
|
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 constexpr const NodeKind Kind = 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 constexpr const NodeKind Kind = 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;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RecordDeclarationField;
|
|
|
|
};
|
|
|
|
class RecordDeclaration : public Declaration {
|
|
public:
|
|
|
|
class PubKeyword* PubKeyword;
|
|
class StructKeyword* StructKeyword;
|
|
IdentifierAlt* Name;
|
|
std::vector<VarTypeExpression*> Vars;
|
|
class BlockStart* BlockStart;
|
|
std::vector<RecordDeclarationField*> Fields;
|
|
|
|
RecordDeclaration(
|
|
class PubKeyword* PubKeyword,
|
|
class StructKeyword* StructKeyword,
|
|
IdentifierAlt* Name,
|
|
std::vector<VarTypeExpression*> Vars,
|
|
class BlockStart* BlockStart,
|
|
std::vector<RecordDeclarationField*> Fields
|
|
): Declaration(NodeKind::RecordDeclaration),
|
|
PubKeyword(PubKeyword),
|
|
StructKeyword(StructKeyword),
|
|
Name(Name),
|
|
Vars(Vars),
|
|
BlockStart(BlockStart),
|
|
Fields(Fields) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RecordDeclaration;
|
|
|
|
};
|
|
|
|
class VariantDeclarationMember : public Node {
|
|
public:
|
|
|
|
inline VariantDeclarationMember(NodeKind Kind):
|
|
Node(Kind) {}
|
|
|
|
};
|
|
|
|
class TupleVariantDeclarationMember : public VariantDeclarationMember {
|
|
public:
|
|
|
|
IdentifierAlt* Name;
|
|
std::vector<TypeExpression*> Elements;
|
|
|
|
inline TupleVariantDeclarationMember(
|
|
IdentifierAlt* Name,
|
|
std::vector<TypeExpression*> Elements
|
|
): VariantDeclarationMember(NodeKind::TupleVariantDeclarationMember),
|
|
Name(Name),
|
|
Elements(Elements) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::TupleVariantDeclarationMember;
|
|
|
|
};
|
|
|
|
class RecordVariantDeclarationMember : public VariantDeclarationMember {
|
|
public:
|
|
|
|
IdentifierAlt* Name;
|
|
class BlockStart* BlockStart;
|
|
std::vector<RecordDeclarationField*> Fields;
|
|
|
|
inline RecordVariantDeclarationMember(
|
|
IdentifierAlt* Name,
|
|
class BlockStart* BlockStart,
|
|
std::vector<RecordDeclarationField*> Fields
|
|
): VariantDeclarationMember(NodeKind::RecordVariantDeclarationMember),
|
|
Name(Name),
|
|
BlockStart(BlockStart),
|
|
Fields(Fields) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::RecordVariantDeclarationMember;
|
|
|
|
};
|
|
|
|
class VariantDeclaration : public Declaration {
|
|
public:
|
|
|
|
class PubKeyword* PubKeyword;
|
|
class EnumKeyword* EnumKeyword;
|
|
class IdentifierAlt* Name;
|
|
std::vector<VarTypeExpression*> TVs;
|
|
class BlockStart* BlockStart;
|
|
std::vector<VariantDeclarationMember*> Members;
|
|
|
|
inline VariantDeclaration(
|
|
class PubKeyword* PubKeyword,
|
|
class EnumKeyword* EnumKeyword,
|
|
class IdentifierAlt* Name,
|
|
std::vector<VarTypeExpression*> TVs,
|
|
class BlockStart* BlockStart,
|
|
std::vector<VariantDeclarationMember*> Members
|
|
): Declaration(NodeKind::VariantDeclaration),
|
|
PubKeyword(PubKeyword),
|
|
EnumKeyword(EnumKeyword),
|
|
Name(Name),
|
|
TVs(TVs),
|
|
BlockStart(BlockStart),
|
|
Members(Members) {}
|
|
|
|
Token* getFirstToken() const override;
|
|
Token* getLastToken() const override;
|
|
|
|
static constexpr const NodeKind Kind = NodeKind::VariantDeclaration;
|
|
|
|
};
|
|
|
|
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 constexpr const NodeKind Kind = NodeKind::SourceFile;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|