2022-08-19 19:52:57 +02:00
|
|
|
|
2022-08-24 12:36:43 +02:00
|
|
|
#include "zen/config.hpp"
|
|
|
|
|
2022-08-19 19:52:57 +02:00
|
|
|
#include "bolt/CST.hpp"
|
2023-05-20 23:48:26 +02:00
|
|
|
#include "bolt/CSTVisitor.hpp"
|
2022-08-19 19:52:57 +02:00
|
|
|
|
|
|
|
namespace bolt {
|
|
|
|
|
2023-05-24 19:38:04 +02:00
|
|
|
TextFile::TextFile(ByteString Path, ByteString Text):
|
|
|
|
Path(Path), Text(Text) {
|
|
|
|
LineOffsets.push_back(0);
|
|
|
|
for (size_t I = 0; I < Text.size(); I++) {
|
|
|
|
auto Chr = Text[I];
|
|
|
|
if (Chr == '\n') {
|
|
|
|
LineOffsets.push_back(I+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
LineOffsets.push_back(Text.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t TextFile::getLineCount() const {
|
|
|
|
return LineOffsets.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t TextFile::getStartOffset(size_t Line) const {
|
|
|
|
return LineOffsets[Line-1];
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t TextFile::getLine(size_t Offset) const {
|
|
|
|
ZEN_ASSERT(Offset < Text.size());
|
|
|
|
for (size_t I = 0; I < LineOffsets.size(); ++I) {
|
|
|
|
if (LineOffsets[I] > Offset) {
|
|
|
|
return I;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t TextFile::getColumn(size_t Offset) const {
|
|
|
|
auto Line = getLine(Offset);
|
|
|
|
auto StartOffset = getStartOffset(Line);
|
|
|
|
return Offset - StartOffset + 1 ;
|
|
|
|
}
|
|
|
|
|
|
|
|
ByteString TextFile::getPath() const {
|
|
|
|
return Path;
|
|
|
|
}
|
|
|
|
|
|
|
|
ByteString TextFile::getText() const {
|
|
|
|
return Text;
|
|
|
|
}
|
|
|
|
|
2023-04-12 11:15:36 +02:00
|
|
|
Scope::Scope(Node* Source):
|
|
|
|
Source(Source) {
|
|
|
|
scan(Source);
|
|
|
|
}
|
|
|
|
|
2023-05-28 19:07:52 +02:00
|
|
|
void Scope::addSymbol(ByteString Name, Node* Decl, SymbolKind Kind) {
|
|
|
|
Mapping.emplace(Name, std::make_tuple(Decl, Kind));
|
|
|
|
}
|
|
|
|
|
2023-04-12 11:15:36 +02:00
|
|
|
void Scope::scan(Node* X) {
|
2023-05-20 23:48:26 +02:00
|
|
|
switch (X->getKind()) {
|
|
|
|
case NodeKind::SourceFile:
|
2023-04-12 11:15:36 +02:00
|
|
|
{
|
2023-05-20 23:48:26 +02:00
|
|
|
auto File = static_cast<SourceFile*>(X);
|
|
|
|
for (auto Element: File->Elements) {
|
2023-05-30 13:34:39 +02:00
|
|
|
scanChild(Element);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2023-05-30 21:34:40 +02:00
|
|
|
case NodeKind::FunctionDeclaration:
|
2023-05-30 13:34:39 +02:00
|
|
|
{
|
2023-05-30 21:34:40 +02:00
|
|
|
auto Decl = static_cast<FunctionDeclaration*>(X);
|
2023-05-30 13:34:39 +02:00
|
|
|
for (auto Param: Decl->Params) {
|
|
|
|
visitPattern(Param->Pattern, Param);
|
|
|
|
}
|
|
|
|
if (Decl->Body) {
|
|
|
|
scanChild(Decl->Body);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scope::scanChild(Node* X) {
|
|
|
|
switch (X->getKind()) {
|
|
|
|
case NodeKind::LetExprBody:
|
|
|
|
case NodeKind::ExpressionStatement:
|
2023-05-30 15:27:21 +02:00
|
|
|
case NodeKind::IfStatement:
|
2023-05-30 13:34:39 +02:00
|
|
|
case NodeKind::ReturnStatement:
|
|
|
|
break;
|
|
|
|
case NodeKind::LetBlockBody:
|
|
|
|
{
|
|
|
|
auto Block = static_cast<LetBlockBody*>(X);
|
|
|
|
for (auto Element: Block->Elements) {
|
|
|
|
scanChild(Element);
|
2023-04-12 11:15:36 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2023-05-30 15:27:21 +02:00
|
|
|
case NodeKind::InstanceDeclaration:
|
|
|
|
// We ignore let-declarations inside instance-declarations for now
|
|
|
|
break;
|
2023-05-20 23:48:26 +02:00
|
|
|
case NodeKind::ClassDeclaration:
|
2023-04-12 11:15:36 +02:00
|
|
|
{
|
2023-05-20 23:48:26 +02:00
|
|
|
auto Decl = static_cast<ClassDeclaration*>(X);
|
2023-05-28 19:07:52 +02:00
|
|
|
addSymbol(Decl->Name->getCanonicalText(), Decl, SymbolKind::Class);
|
2023-05-20 23:48:26 +02:00
|
|
|
for (auto Element: Decl->Elements) {
|
2023-05-30 13:34:39 +02:00
|
|
|
scanChild(Element);
|
2023-05-20 23:48:26 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2023-05-30 21:34:40 +02:00
|
|
|
case NodeKind::VariableDeclaration:
|
2023-05-20 23:48:26 +02:00
|
|
|
{
|
2023-05-30 21:34:40 +02:00
|
|
|
auto Decl = static_cast<VariableDeclaration*>(X);
|
2023-05-28 19:07:52 +02:00
|
|
|
visitPattern(Decl->Pattern, Decl);
|
|
|
|
break;
|
|
|
|
}
|
2023-05-30 21:34:40 +02:00
|
|
|
case NodeKind::FunctionDeclaration:
|
|
|
|
{
|
|
|
|
auto Decl = static_cast<FunctionDeclaration*>(X);
|
|
|
|
addSymbol(Decl->Name->getCanonicalText(), Decl, SymbolKind::Var);
|
|
|
|
break;
|
|
|
|
}
|
2023-05-28 19:07:52 +02:00
|
|
|
case NodeKind::RecordDeclaration:
|
|
|
|
{
|
|
|
|
auto Decl = static_cast<RecordDeclaration*>(X);
|
|
|
|
addSymbol(Decl->Name->getCanonicalText(), Decl, SymbolKind::Type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NodeKind::VariantDeclaration:
|
|
|
|
{
|
|
|
|
auto Decl = static_cast<VariantDeclaration*>(X);
|
|
|
|
addSymbol(Decl->Name->getCanonicalText(), Decl, SymbolKind::Type);
|
2023-04-12 11:15:36 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-28 19:07:52 +02:00
|
|
|
void Scope::visitPattern(Pattern* X, Node* Decl) {
|
2023-05-20 23:48:26 +02:00
|
|
|
switch (X->getKind()) {
|
|
|
|
case NodeKind::BindPattern:
|
2023-04-12 11:15:36 +02:00
|
|
|
{
|
|
|
|
auto Y = static_cast<BindPattern*>(X);
|
2023-05-28 19:07:52 +02:00
|
|
|
addSymbol(Y->Name->Text, Decl, SymbolKind::Var);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NodeKind::NamedPattern:
|
|
|
|
{
|
|
|
|
auto Y = static_cast<NamedPattern*>(X);
|
|
|
|
for (auto P: Y->Patterns) {
|
|
|
|
visitPattern(P, Decl);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NodeKind::NestedPattern:
|
|
|
|
{
|
|
|
|
auto Y = static_cast<NestedPattern*>(X);
|
|
|
|
visitPattern(Y->P, Decl);
|
2023-04-12 11:15:36 +02:00
|
|
|
break;
|
|
|
|
}
|
2023-05-21 20:16:15 +02:00
|
|
|
case NodeKind::LiteralPattern:
|
|
|
|
break;
|
2023-04-12 11:15:36 +02:00
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-21 20:33:06 +02:00
|
|
|
Node* Scope::lookupDirect(SymbolPath Path, SymbolKind Kind) {
|
|
|
|
ZEN_ASSERT(Path.Modules.empty());
|
|
|
|
auto Match = Mapping.find(Path.Name);
|
|
|
|
if (Match != Mapping.end() && std::get<1>(Match->second) == Kind) {
|
|
|
|
return std::get<0>(Match->second);
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2023-05-21 20:14:41 +02:00
|
|
|
Node* Scope::lookup(SymbolPath Path, SymbolKind Kind) {
|
2023-05-20 23:48:26 +02:00
|
|
|
ZEN_ASSERT(Path.Modules.empty());
|
2022-08-26 22:10:18 +02:00
|
|
|
auto Curr = this;
|
|
|
|
do {
|
2023-05-30 13:34:39 +02:00
|
|
|
auto Found = Curr->lookupDirect(Path, Kind);
|
2023-05-21 20:33:06 +02:00
|
|
|
if (Found) {
|
|
|
|
return Found;
|
2022-08-26 22:10:18 +02:00
|
|
|
}
|
|
|
|
Curr = Curr->getParentScope();
|
|
|
|
} while (Curr != nullptr);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scope* Scope::getParentScope() {
|
|
|
|
if (Source->Parent == nullptr) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return Source->Parent->getScope();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
const SourceFile* Node::getSourceFile() const {
|
|
|
|
const Node* CurrNode = this;
|
|
|
|
for (;;) {
|
|
|
|
if (CurrNode->Kind == NodeKind::SourceFile) {
|
|
|
|
return static_cast<const SourceFile*>(CurrNode);
|
|
|
|
}
|
|
|
|
CurrNode = CurrNode->Parent;
|
|
|
|
ZEN_ASSERT(CurrNode != nullptr);
|
|
|
|
}
|
|
|
|
}
|
2022-08-24 12:36:43 +02:00
|
|
|
SourceFile* Node::getSourceFile() {
|
2023-05-24 14:11:59 +02:00
|
|
|
Node* CurrNode = this;
|
2022-08-24 12:36:43 +02:00
|
|
|
for (;;) {
|
2023-05-20 23:48:26 +02:00
|
|
|
if (CurrNode->Kind == NodeKind::SourceFile) {
|
2022-08-24 20:57:26 +02:00
|
|
|
return static_cast<SourceFile*>(CurrNode);
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
CurrNode = CurrNode->Parent;
|
|
|
|
ZEN_ASSERT(CurrNode != nullptr);
|
2023-05-24 14:11:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::size_t Node::getStartLine() const {
|
|
|
|
return getFirstToken()->getStartLine();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::size_t Node::getStartColumn() const {
|
|
|
|
return getFirstToken()->getStartColumn();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::size_t Node::getEndLine() const {
|
|
|
|
return getLastToken()->getEndLine();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::size_t Node::getEndColumn() const {
|
|
|
|
return getLastToken()->getEndColumn();
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
TextRange Node::getRange() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return TextRange {
|
|
|
|
getFirstToken()->getStartLoc(),
|
|
|
|
getLastToken()->getEndLoc(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-08-26 22:10:18 +02:00
|
|
|
Scope* Node::getScope() {
|
2023-05-21 20:14:41 +02:00
|
|
|
return Parent->getScope();
|
2022-08-26 22:10:18 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 20:33:32 +02:00
|
|
|
TextLoc Token::getEndLoc() const {
|
2023-05-24 19:38:04 +02:00
|
|
|
auto Loc = StartLoc;
|
|
|
|
Loc.advance(getText());
|
|
|
|
return Loc;
|
2022-08-24 20:57:26 +02:00
|
|
|
}
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
void Node::setParents() {
|
2022-08-24 12:36:43 +02:00
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
struct SetParentsVisitor : public CSTVisitor<SetParentsVisitor> {
|
2022-08-24 12:36:43 +02:00
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
std::vector<Node*> Parents { nullptr };
|
2022-08-24 12:36:43 +02:00
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
void visit(Node* N) {
|
|
|
|
N->Parent = Parents.back();
|
|
|
|
Parents.push_back(N);
|
|
|
|
visitEachChild(N);
|
|
|
|
Parents.pop_back();
|
|
|
|
}
|
2022-08-24 12:36:43 +02:00
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
};
|
2022-08-24 12:36:43 +02:00
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
SetParentsVisitor V;
|
|
|
|
V.visit(this);
|
2022-08-24 12:36:43 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Node::~Node() {
|
2022-08-19 19:52:57 +02:00
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
struct UnrefVisitor : public CSTVisitor<UnrefVisitor> {
|
2022-08-19 19:52:57 +02:00
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
void visit(Node* N) {
|
|
|
|
N->unref();
|
|
|
|
visitEachChild(N);
|
|
|
|
}
|
2022-08-21 16:25:52 +02:00
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
};
|
2022-08-19 19:52:57 +02:00
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
UnrefVisitor V;
|
|
|
|
V.visitEachChild(this);
|
2022-08-19 19:52:57 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
bool Identifier::isTypeVar() const {
|
|
|
|
for (auto C: Text) {
|
|
|
|
if (!((C >= 97 && C <= 122) || C == '_')) {
|
|
|
|
return false;
|
|
|
|
}
|
2022-08-25 23:04:09 +02:00
|
|
|
}
|
2023-05-20 23:48:26 +02:00
|
|
|
return true;
|
2022-08-25 23:04:09 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* TypeclassConstraintExpression::getFirstToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
return Name;
|
2022-08-19 19:52:57 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* TypeclassConstraintExpression::getLastToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
if (!TEs.empty()) {
|
|
|
|
return TEs.back()->getLastToken();
|
2022-08-19 19:52:57 +02:00
|
|
|
}
|
2023-05-20 23:48:26 +02:00
|
|
|
return Name;
|
2022-08-19 19:52:57 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* EqualityConstraintExpression::getFirstToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
return Left->getFirstToken();
|
2022-08-19 19:52:57 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* EqualityConstraintExpression::getLastToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
return Left->getLastToken();
|
2022-08-19 19:52:57 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* QualifiedTypeExpression::getFirstToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
if (!Constraints.empty()) {
|
|
|
|
return std::get<0>(Constraints.front())->getFirstToken();
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
2023-05-20 23:48:26 +02:00
|
|
|
return TE->getFirstToken();
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* QualifiedTypeExpression::getLastToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
return TE->getLastToken();
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ReferenceTypeExpression::getFirstToken() const {
|
2023-05-21 00:25:01 +02:00
|
|
|
if (!ModulePath.empty()) {
|
|
|
|
return std::get<0>(ModulePath.front());
|
|
|
|
}
|
|
|
|
return Name;
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ReferenceTypeExpression::getLastToken() const {
|
2023-05-21 00:25:01 +02:00
|
|
|
return Name;
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ArrowTypeExpression::getFirstToken() const {
|
2022-08-25 19:04:25 +02:00
|
|
|
if (ParamTypes.size()) {
|
|
|
|
return ParamTypes.front()->getFirstToken();
|
|
|
|
}
|
|
|
|
return ReturnType->getFirstToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ArrowTypeExpression::getLastToken() const {
|
2022-08-25 19:04:25 +02:00
|
|
|
return ReturnType->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-28 19:07:52 +02:00
|
|
|
Token* AppTypeExpression::getFirstToken() const {
|
|
|
|
return Op->getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* AppTypeExpression::getLastToken() const {
|
|
|
|
if (Args.size()) {
|
|
|
|
return Args.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return Op->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* VarTypeExpression::getLastToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* VarTypeExpression::getFirstToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* NestedTypeExpression::getLastToken() const {
|
2023-05-23 22:36:01 +02:00
|
|
|
return LParen;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* NestedTypeExpression::getFirstToken() const {
|
2023-05-23 22:36:01 +02:00
|
|
|
return RParen;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* TupleTypeExpression::getLastToken() const {
|
2023-05-23 22:36:01 +02:00
|
|
|
return LParen;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* TupleTypeExpression::getFirstToken() const {
|
2023-05-23 22:36:01 +02:00
|
|
|
return RParen;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* BindPattern::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* BindPattern::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* LiteralPattern::getFirstToken() const {
|
2023-05-21 17:36:44 +02:00
|
|
|
return Literal;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* LiteralPattern::getLastToken() const {
|
2023-05-21 17:36:44 +02:00
|
|
|
return Literal;
|
|
|
|
}
|
|
|
|
|
2023-05-28 19:07:52 +02:00
|
|
|
Token* NamedPattern::getFirstToken() const {
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* NamedPattern::getLastToken() const {
|
|
|
|
if (Patterns.size()) {
|
|
|
|
return Patterns.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* NestedPattern::getFirstToken() const {
|
|
|
|
return LParen;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* NestedPattern::getLastToken() const {
|
|
|
|
return RParen;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ReferenceExpression::getFirstToken() const {
|
2023-05-21 00:25:01 +02:00
|
|
|
if (!ModulePath.empty()) {
|
|
|
|
return std::get<0>(ModulePath.front());
|
|
|
|
}
|
|
|
|
return Name;
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ReferenceExpression::getLastToken() const {
|
2023-05-21 00:25:01 +02:00
|
|
|
return Name;
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* MatchCase::getFirstToken() const {
|
2023-05-21 11:30:25 +02:00
|
|
|
return Pattern->getFirstToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* MatchCase::getLastToken() const {
|
2023-05-21 11:30:25 +02:00
|
|
|
return Expression->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* MatchExpression::getFirstToken() const {
|
2023-05-21 11:30:25 +02:00
|
|
|
return MatchKeyword;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* MatchExpression::getLastToken() const {
|
2023-05-21 11:30:25 +02:00
|
|
|
if (!Cases.empty()) {
|
|
|
|
return Cases.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return BlockStart;
|
|
|
|
}
|
|
|
|
|
2023-05-29 20:37:23 +02:00
|
|
|
Token* RecordExpressionField::getFirstToken() const {
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* RecordExpressionField::getLastToken() const {
|
|
|
|
return E->getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* RecordExpression::getFirstToken() const {
|
|
|
|
return LBrace;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* RecordExpression::getLastToken() const {
|
|
|
|
return RBrace;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* MemberExpression::getFirstToken() const {
|
2023-05-22 11:54:52 +02:00
|
|
|
return E->getFirstToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* MemberExpression::getLastToken() const {
|
2023-05-22 11:54:52 +02:00
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* TupleExpression::getFirstToken() const {
|
2023-05-22 17:06:31 +02:00
|
|
|
return LParen;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* TupleExpression::getLastToken() const {
|
2023-05-22 17:06:31 +02:00
|
|
|
return RParen;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* NestedExpression::getFirstToken() const {
|
2022-08-26 22:10:18 +02:00
|
|
|
return LParen;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* NestedExpression::getLastToken() const {
|
2022-08-26 22:10:18 +02:00
|
|
|
return RParen;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ConstantExpression::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Token;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ConstantExpression::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Token;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* CallExpression::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Function->getFirstToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* CallExpression::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (Args.size()) {
|
|
|
|
return Args.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return Function->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* InfixExpression::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return LHS->getFirstToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* InfixExpression::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return RHS->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* PrefixExpression::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Operator;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* PrefixExpression::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Argument->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ExpressionStatement::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Expression->getFirstToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ExpressionStatement::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Expression->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ReturnStatement::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return ReturnKeyword;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ReturnStatement::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (Expression) {
|
|
|
|
return Expression->getLastToken();
|
|
|
|
}
|
|
|
|
return ReturnKeyword;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* IfStatementPart::getFirstToken() const {
|
2022-08-25 23:04:09 +02:00
|
|
|
return Keyword;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* IfStatementPart::getLastToken() const {
|
2022-08-25 23:04:09 +02:00
|
|
|
if (Elements.size()) {
|
|
|
|
return Elements.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return BlockStart;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* IfStatement::getFirstToken() const {
|
2022-08-25 23:04:09 +02:00
|
|
|
ZEN_ASSERT(Parts.size());
|
|
|
|
return Parts.front()->getFirstToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* IfStatement::getLastToken() const {
|
2022-08-25 23:04:09 +02:00
|
|
|
ZEN_ASSERT(Parts.size());
|
|
|
|
return Parts.back()->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* TypeAssert::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Colon;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* TypeAssert::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return TypeExpression->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* Parameter::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Pattern->getFirstToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* Parameter::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (TypeAssert) {
|
|
|
|
return TypeAssert->getLastToken();
|
|
|
|
}
|
|
|
|
return Pattern->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* LetBlockBody::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return BlockStart;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* LetBlockBody::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (Elements.size()) {
|
|
|
|
return Elements.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return BlockStart;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* LetExprBody::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Equals;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* LetExprBody::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Expression->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-30 21:34:40 +02:00
|
|
|
Token* FunctionDeclaration::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (PubKeyword) {
|
|
|
|
return PubKeyword;
|
|
|
|
}
|
2023-05-30 21:34:40 +02:00
|
|
|
return FnKeyword;
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-30 21:34:40 +02:00
|
|
|
Token* FunctionDeclaration::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (Body) {
|
|
|
|
return Body->getLastToken();
|
|
|
|
}
|
|
|
|
if (TypeAssert) {
|
|
|
|
return TypeAssert->getLastToken();
|
|
|
|
}
|
|
|
|
if (Params.size()) {
|
|
|
|
return Params.back()->getLastToken();
|
|
|
|
}
|
2023-05-30 21:34:40 +02:00
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* VariableDeclaration::getFirstToken() const {
|
|
|
|
if (PubKeyword) {
|
|
|
|
return PubKeyword;
|
|
|
|
}
|
|
|
|
return LetKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* VariableDeclaration::getLastToken() const {
|
|
|
|
if (Body) {
|
|
|
|
return Body->getLastToken();
|
|
|
|
}
|
|
|
|
if (TypeAssert) {
|
|
|
|
return TypeAssert->getLastToken();
|
|
|
|
}
|
2022-08-24 12:36:43 +02:00
|
|
|
return Pattern->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-26 15:36:14 +02:00
|
|
|
Token* RecordDeclarationField::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2023-05-26 15:36:14 +02:00
|
|
|
Token* RecordDeclarationField::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return TypeExpression->getLastToken();
|
|
|
|
}
|
|
|
|
|
2023-05-26 15:36:14 +02:00
|
|
|
Token* RecordDeclaration::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (PubKeyword) {
|
|
|
|
return PubKeyword;
|
|
|
|
}
|
|
|
|
return StructKeyword;
|
|
|
|
}
|
|
|
|
|
2023-05-26 15:36:14 +02:00
|
|
|
Token* RecordDeclaration::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (Fields.size()) {
|
2023-05-28 19:07:52 +02:00
|
|
|
return Fields.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return BlockStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* VariantDeclaration::getFirstToken() const {
|
|
|
|
if (PubKeyword) {
|
|
|
|
return PubKeyword;
|
|
|
|
}
|
|
|
|
return EnumKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* VariantDeclaration::getLastToken() const {
|
|
|
|
if (Members.size()) {
|
|
|
|
return Members.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return BlockStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* TupleVariantDeclarationMember::getFirstToken() const {
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* TupleVariantDeclarationMember::getLastToken() const {
|
|
|
|
if (Elements.size()) {
|
|
|
|
return Elements.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* RecordVariantDeclarationMember::getFirstToken() const {
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* RecordVariantDeclarationMember::getLastToken() const {
|
|
|
|
if (Fields.size()) {
|
|
|
|
return Fields.back()->getLastToken();
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
return BlockStart;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* InstanceDeclaration::getFirstToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
return InstanceKeyword;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* InstanceDeclaration::getLastToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
if (!Elements.empty()) {
|
|
|
|
return Elements.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return BlockStart;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ClassDeclaration::getFirstToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
if (PubKeyword != nullptr) {
|
|
|
|
return PubKeyword;
|
|
|
|
}
|
|
|
|
return ClassKeyword;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ClassDeclaration::getLastToken() const {
|
2023-05-20 23:48:26 +02:00
|
|
|
if (!Elements.empty()) {
|
|
|
|
return Elements.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return BlockStart;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* SourceFile::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (Elements.size()) {
|
|
|
|
return Elements.front()->getFirstToken();
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* SourceFile::getLastToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (Elements.size()) {
|
|
|
|
return Elements.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-08-19 19:52:57 +02:00
|
|
|
std::string Equals::getText() const {
|
|
|
|
return "=";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Colon::getText() const {
|
|
|
|
return ":";
|
|
|
|
}
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
std::string Comma::getText() const {
|
|
|
|
return ",";
|
|
|
|
}
|
|
|
|
|
2022-08-25 19:04:25 +02:00
|
|
|
std::string RArrow::getText() const {
|
|
|
|
return "->";
|
|
|
|
}
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
std::string RArrowAlt::getText() const {
|
|
|
|
return "=>";
|
|
|
|
}
|
|
|
|
|
2022-08-19 19:52:57 +02:00
|
|
|
std::string Dot::getText() const {
|
|
|
|
return ".";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string LParen::getText() const {
|
|
|
|
return "(";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string RParen::getText() const {
|
|
|
|
return ")";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string LBracket::getText() const {
|
|
|
|
return "[";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string RBracket::getText() const {
|
|
|
|
return "]";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string LBrace::getText() const {
|
|
|
|
return "{";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string RBrace::getText() const {
|
|
|
|
return "}";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string LetKeyword::getText() const {
|
|
|
|
return "let";
|
|
|
|
}
|
|
|
|
|
2023-05-30 21:34:40 +02:00
|
|
|
std::string FnKeyword::getText() const {
|
|
|
|
return "fn";
|
|
|
|
}
|
|
|
|
|
2022-08-19 19:52:57 +02:00
|
|
|
std::string MutKeyword::getText() const {
|
|
|
|
return "mut";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string PubKeyword::getText() const {
|
|
|
|
return "pub";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string TypeKeyword::getText() const {
|
|
|
|
return "type";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string ReturnKeyword::getText() const {
|
|
|
|
return "return";
|
|
|
|
}
|
|
|
|
|
2022-08-25 23:04:09 +02:00
|
|
|
std::string IfKeyword::getText() const {
|
|
|
|
return "if";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string ElseKeyword::getText() const {
|
|
|
|
return "else";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string ElifKeyword::getText() const {
|
|
|
|
return "elif";
|
|
|
|
}
|
|
|
|
|
2023-05-21 11:30:25 +02:00
|
|
|
std::string MatchKeyword::getText() const {
|
|
|
|
return "match";
|
|
|
|
}
|
|
|
|
|
2022-08-19 19:52:57 +02:00
|
|
|
std::string ModKeyword::getText() const {
|
|
|
|
return "mod";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string StructKeyword::getText() const {
|
|
|
|
return "struct";
|
|
|
|
}
|
|
|
|
|
2023-05-28 19:07:52 +02:00
|
|
|
std::string EnumKeyword::getText() const {
|
|
|
|
return "enum";
|
|
|
|
}
|
|
|
|
|
2022-08-19 19:52:57 +02:00
|
|
|
std::string Invalid::getText() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string EndOfFile::getText() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string BlockStart::getText() const {
|
|
|
|
return ".";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string BlockEnd::getText() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string LineFoldEnd::getText() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string CustomOperator::getText() const {
|
|
|
|
return Text;
|
|
|
|
}
|
2022-08-21 16:25:52 +02:00
|
|
|
|
|
|
|
std::string Assignment::getText() const {
|
|
|
|
return Text + "=";
|
|
|
|
}
|
2022-08-19 19:52:57 +02:00
|
|
|
|
|
|
|
std::string Identifier::getText() const {
|
|
|
|
return Text;
|
|
|
|
}
|
|
|
|
|
2023-05-21 00:25:01 +02:00
|
|
|
std::string IdentifierAlt::getText() const {
|
|
|
|
return Text;
|
|
|
|
}
|
|
|
|
|
2022-08-19 19:52:57 +02:00
|
|
|
std::string StringLiteral::getText() const {
|
|
|
|
return "\"" + Text + "\"";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string IntegerLiteral::getText() const {
|
2023-05-21 17:36:44 +02:00
|
|
|
return std::to_string(V);
|
2022-08-19 19:52:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string DotDot::getText() const {
|
|
|
|
return "..";
|
|
|
|
}
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
std::string Tilde::getText() const {
|
|
|
|
return "~";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string ClassKeyword::getText() const {
|
|
|
|
return "class";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string InstanceKeyword::getText() const {
|
|
|
|
return "instance";
|
|
|
|
}
|
|
|
|
|
2023-05-21 14:50:28 +02:00
|
|
|
ByteString Identifier::getCanonicalText() {
|
|
|
|
return Text;
|
|
|
|
}
|
|
|
|
|
|
|
|
ByteString IdentifierAlt::getCanonicalText() {
|
|
|
|
return Text;
|
|
|
|
}
|
|
|
|
|
2023-05-21 17:36:44 +02:00
|
|
|
Value StringLiteral::getValue() {
|
|
|
|
return Text;
|
|
|
|
}
|
|
|
|
|
|
|
|
Value IntegerLiteral::getValue() {
|
|
|
|
return V;
|
|
|
|
}
|
|
|
|
|
2023-05-21 00:25:01 +02:00
|
|
|
SymbolPath ReferenceExpression::getSymbolPath() const {
|
2022-08-26 22:10:18 +02:00
|
|
|
std::vector<ByteString> ModuleNames;
|
2023-05-21 00:25:01 +02:00
|
|
|
for (auto [Name, Dot]: ModulePath) {
|
2023-05-21 14:50:28 +02:00
|
|
|
ModuleNames.push_back(Name->getCanonicalText());
|
2022-08-26 22:10:18 +02:00
|
|
|
}
|
2023-05-21 14:50:28 +02:00
|
|
|
return SymbolPath { ModuleNames, Name->getCanonicalText() };
|
2022-08-26 22:10:18 +02:00
|
|
|
}
|
|
|
|
|
2022-08-19 19:52:57 +02:00
|
|
|
}
|
|
|
|
|