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 {
|
2023-05-31 15:05:47 +02:00
|
|
|
return LineOffsets.size()-1;
|
2023-05-24 19:38:04 +02:00
|
|
|
}
|
|
|
|
|
2023-05-31 15:05:47 +02:00
|
|
|
size_t TextFile::getStartOffsetOfLine(size_t Line) const {
|
|
|
|
ZEN_ASSERT(Line-1 < LineOffsets.size());
|
2023-05-24 19:38:04 +02:00
|
|
|
return LineOffsets[Line-1];
|
|
|
|
}
|
|
|
|
|
2023-05-31 15:05:47 +02:00
|
|
|
size_t TextFile::getEndOffsetOfLine(size_t Line) const {
|
|
|
|
ZEN_ASSERT(Line <= LineOffsets.size());
|
|
|
|
if (Line == LineOffsets.size()) {
|
|
|
|
return Text.size();
|
|
|
|
}
|
|
|
|
return LineOffsets[Line];
|
|
|
|
}
|
|
|
|
|
2023-05-24 19:38:04 +02:00
|
|
|
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);
|
2023-05-31 15:05:47 +02:00
|
|
|
auto StartOffset = getStartOffsetOfLine(Line);
|
2023-05-24 19:38:04 +02:00
|
|
|
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;
|
|
|
|
}
|
2024-02-19 14:17:12 +01:00
|
|
|
case NodeKind::MatchCase:
|
|
|
|
{
|
|
|
|
auto Case = static_cast<MatchCase*>(X);
|
|
|
|
visitPattern(Case->Pattern, Case);
|
|
|
|
break;
|
|
|
|
}
|
2023-06-03 14:35:02 +02:00
|
|
|
case NodeKind::LetDeclaration:
|
2023-05-30 13:34:39 +02:00
|
|
|
{
|
2023-06-03 14:35:02 +02:00
|
|
|
auto Decl = static_cast<LetDeclaration*>(X);
|
|
|
|
ZEN_ASSERT(Decl->isFunction());
|
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);
|
2024-02-04 17:44:58 +01:00
|
|
|
addSymbol(getCanonicalText(Decl->Name), 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-06-03 14:35:02 +02:00
|
|
|
case NodeKind::LetDeclaration:
|
2023-05-20 23:48:26 +02:00
|
|
|
{
|
2023-06-03 14:35:02 +02:00
|
|
|
auto Decl = static_cast<LetDeclaration*>(X);
|
|
|
|
// No matter if it is a function or a variable, by visiting the pattern
|
|
|
|
// we add all relevant bindings to the current scope.
|
2023-05-28 19:07:52 +02:00
|
|
|
visitPattern(Decl->Pattern, Decl);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NodeKind::RecordDeclaration:
|
|
|
|
{
|
|
|
|
auto Decl = static_cast<RecordDeclaration*>(X);
|
2024-02-04 17:44:58 +01:00
|
|
|
addSymbol(getCanonicalText(Decl->Name), Decl, SymbolKind::Type);
|
2023-05-28 19:07:52 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NodeKind::VariantDeclaration:
|
|
|
|
{
|
|
|
|
auto Decl = static_cast<VariantDeclaration*>(X);
|
2024-02-04 17:44:58 +01:00
|
|
|
addSymbol(getCanonicalText(Decl->Name), Decl, SymbolKind::Type);
|
2023-06-05 15:53:24 +02:00
|
|
|
for (auto Member: Decl->Members) {
|
|
|
|
switch (Member->getKind()) {
|
|
|
|
case NodeKind::TupleVariantDeclarationMember:
|
|
|
|
{
|
|
|
|
auto T = static_cast<TupleVariantDeclarationMember*>(Member);
|
2024-02-04 17:44:58 +01:00
|
|
|
addSymbol(getCanonicalText(T->Name), Decl, SymbolKind::Constructor);
|
2023-06-05 15:53:24 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NodeKind::RecordVariantDeclarationMember:
|
|
|
|
{
|
|
|
|
auto R = static_cast<RecordVariantDeclarationMember*>(Member);
|
2024-02-04 17:44:58 +01:00
|
|
|
addSymbol(getCanonicalText(R->Name), Decl, SymbolKind::Constructor);
|
2023-06-05 15:53:24 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
|
|
|
}
|
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);
|
2024-02-04 17:44:58 +01:00
|
|
|
addSymbol(getCanonicalText(Y->Name), Decl, SymbolKind::Var);
|
2023-05-28 19:07:52 +02:00
|
|
|
break;
|
|
|
|
}
|
2024-01-22 01:11:06 +01:00
|
|
|
case NodeKind::RecordPattern:
|
|
|
|
{
|
|
|
|
auto Y = static_cast<RecordPattern*>(X);
|
|
|
|
for (auto [Field, Comma]: Y->Fields) {
|
|
|
|
if (Field->Pattern) {
|
|
|
|
visitPattern(Field->Pattern, Decl);
|
|
|
|
} else if (Field->Name) {
|
|
|
|
addSymbol(Field->Name->Text, Decl, SymbolKind::Var);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2024-01-21 05:40:35 +01:00
|
|
|
case NodeKind::NamedRecordPattern:
|
2023-05-28 19:07:52 +02:00
|
|
|
{
|
2024-01-21 05:40:35 +01:00
|
|
|
auto Y = static_cast<NamedRecordPattern*>(X);
|
|
|
|
for (auto [Field, Comma]: Y->Fields) {
|
|
|
|
if (Field->Pattern) {
|
|
|
|
visitPattern(Field->Pattern, Decl);
|
2024-01-22 01:11:06 +01:00
|
|
|
} else if (Field->Name) {
|
2024-01-21 05:40:35 +01:00
|
|
|
addSymbol(Field->Name->Text, Decl, SymbolKind::Var);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NodeKind::NamedTuplePattern:
|
|
|
|
{
|
|
|
|
auto Y = static_cast<NamedTuplePattern*>(X);
|
2023-05-28 19:07:52 +02:00
|
|
|
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-31 12:38:29 +02:00
|
|
|
case NodeKind::TuplePattern:
|
|
|
|
{
|
|
|
|
auto Y = static_cast<TuplePattern*>(X);
|
|
|
|
for (auto [Element, Comma]: Y->Elements) {
|
|
|
|
visitPattern(Element, Decl);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NodeKind::ListPattern:
|
|
|
|
{
|
|
|
|
auto Y = static_cast<ListPattern*>(X);
|
|
|
|
for (auto [Element, Separator]: Y->Elements) {
|
|
|
|
visitPattern(Element, Decl);
|
|
|
|
}
|
|
|
|
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
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-05-31 13:14:46 +02:00
|
|
|
void Node::unref() {
|
2022-08-19 19:52:57 +02:00
|
|
|
|
2023-05-31 13:14:46 +02:00
|
|
|
--RefCount;
|
2022-08-19 19:52:57 +02:00
|
|
|
|
2023-05-31 13:14:46 +02:00
|
|
|
if (RefCount == 0) {
|
2022-08-21 16:25:52 +02:00
|
|
|
|
2023-05-31 13:14:46 +02:00
|
|
|
// You may be wondering why we aren't unreffing the children in the
|
|
|
|
// destructor. This is due to a behaviour in Clang where a top-level
|
|
|
|
// destructor ~Node() wont get access to the fields in derived classes
|
|
|
|
// because they may already have been destroyed.
|
|
|
|
struct UnrefVisitor : public CSTVisitor<UnrefVisitor> {
|
|
|
|
void visit(Node* N) {
|
|
|
|
N->unref();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
UnrefVisitor V;
|
|
|
|
V.visitEachChild(this);
|
2022-08-19 19:52:57 +02:00
|
|
|
|
2023-05-31 13:14:46 +02:00
|
|
|
delete 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-06-08 14:52:22 +02:00
|
|
|
Token* ExpressionAnnotation::getFirstToken() const {
|
|
|
|
return At;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* ExpressionAnnotation::getLastToken() const {
|
|
|
|
return Expression->getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* TypeAssertAnnotation::getFirstToken() const {
|
|
|
|
return At;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* TypeAssertAnnotation::getLastToken() const {
|
|
|
|
return TE->getLastToken();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2024-01-21 08:51:50 +01:00
|
|
|
Token* RecordTypeExpressionField::getFirstToken() const {
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* RecordTypeExpressionField::getLastToken() const {
|
|
|
|
return TE->getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* RecordTypeExpression::getFirstToken() const {
|
|
|
|
return LBrace;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* RecordTypeExpression::getLastToken() const {
|
|
|
|
return RBrace;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2024-02-04 17:44:58 +01:00
|
|
|
Token* WrappedOperator::getFirstToken() const {
|
|
|
|
return LParen;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* WrappedOperator::getLastToken() const {
|
|
|
|
return RParen;
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* BindPattern::getFirstToken() const {
|
2024-02-04 17:44:58 +01:00
|
|
|
switch (Name->getKind()) {
|
|
|
|
case NodeKind::Identifier:
|
|
|
|
return static_cast<Identifier*>(Name);
|
|
|
|
case NodeKind::IdentifierAlt:
|
|
|
|
return static_cast<IdentifierAlt*>(Name);
|
|
|
|
case NodeKind::WrappedOperator:
|
|
|
|
return static_cast<WrappedOperator*>(Name)->LParen;
|
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* BindPattern::getLastToken() const {
|
2024-02-04 17:44:58 +01:00
|
|
|
switch (Name->getKind()) {
|
|
|
|
case NodeKind::Identifier:
|
|
|
|
return static_cast<Identifier*>(Name);
|
|
|
|
case NodeKind::IdentifierAlt:
|
|
|
|
return static_cast<IdentifierAlt*>(Name);
|
|
|
|
case NodeKind::WrappedOperator:
|
|
|
|
return static_cast<WrappedOperator*>(Name)->RParen;
|
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2024-01-21 05:40:35 +01:00
|
|
|
Token* RecordPatternField::getFirstToken() const {
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* RecordPatternField::getLastToken() const {
|
|
|
|
if (Pattern) {
|
|
|
|
return Pattern->getLastToken();
|
|
|
|
}
|
|
|
|
if (Equals) {
|
|
|
|
return Equals;
|
|
|
|
}
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2024-01-22 01:11:06 +01:00
|
|
|
Token* RecordPattern::getFirstToken() const {
|
|
|
|
return LBrace;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* RecordPattern::getLastToken() const {
|
|
|
|
return RBrace;
|
|
|
|
}
|
|
|
|
|
2024-01-21 05:40:35 +01:00
|
|
|
Token* NamedRecordPattern::getFirstToken() const {
|
|
|
|
if (!ModulePath.empty()) {
|
|
|
|
return std::get<0>(ModulePath.back());
|
|
|
|
}
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* NamedRecordPattern::getLastToken() const {
|
|
|
|
return RBrace;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* NamedTuplePattern::getFirstToken() const {
|
2023-05-28 19:07:52 +02:00
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2024-01-21 05:40:35 +01:00
|
|
|
Token* NamedTuplePattern::getLastToken() const {
|
2023-05-28 19:07:52 +02:00
|
|
|
if (Patterns.size()) {
|
|
|
|
return Patterns.back()->getLastToken();
|
|
|
|
}
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2023-05-31 12:38:29 +02:00
|
|
|
Token* TuplePattern::getFirstToken() const {
|
|
|
|
return LParen;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* TuplePattern::getLastToken() const {
|
|
|
|
return RParen;
|
|
|
|
}
|
|
|
|
|
2023-05-28 19:07:52 +02:00
|
|
|
Token* NestedPattern::getFirstToken() const {
|
|
|
|
return LParen;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* NestedPattern::getLastToken() const {
|
|
|
|
return RParen;
|
|
|
|
}
|
|
|
|
|
2023-05-31 12:38:29 +02:00
|
|
|
Token* ListPattern::getFirstToken() const {
|
|
|
|
return LBracket;
|
|
|
|
}
|
|
|
|
|
|
|
|
Token* ListPattern::getLastToken() const {
|
|
|
|
return RBracket;
|
|
|
|
}
|
|
|
|
|
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());
|
|
|
|
}
|
2024-02-04 17:44:58 +01:00
|
|
|
switch (Name->getKind()) {
|
|
|
|
case NodeKind::Identifier:
|
|
|
|
return static_cast<Identifier*>(Name);
|
|
|
|
case NodeKind::IdentifierAlt:
|
|
|
|
return static_cast<IdentifierAlt*>(Name);
|
|
|
|
case NodeKind::WrappedOperator:
|
|
|
|
return static_cast<WrappedOperator*>(Name)->LParen;
|
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* ReferenceExpression::getLastToken() const {
|
2024-02-04 17:44:58 +01:00
|
|
|
switch (Name->getKind()) {
|
|
|
|
case NodeKind::Identifier:
|
|
|
|
return static_cast<Identifier*>(Name);
|
|
|
|
case NodeKind::IdentifierAlt:
|
|
|
|
return static_cast<IdentifierAlt*>(Name);
|
|
|
|
case NodeKind::WrappedOperator:
|
|
|
|
return static_cast<WrappedOperator*>(Name)->RParen;
|
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
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-06-08 14:52:22 +02:00
|
|
|
Token* LiteralExpression::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
return Token;
|
|
|
|
}
|
|
|
|
|
2023-06-08 14:52:22 +02:00
|
|
|
Token* LiteralExpression::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 {
|
2023-06-08 14:52:22 +02:00
|
|
|
return Left->getFirstToken();
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 14:11:59 +02:00
|
|
|
Token* InfixExpression::getLastToken() const {
|
2023-06-08 14:52:22 +02:00
|
|
|
return Right->getLastToken();
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
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-06-03 14:35:02 +02:00
|
|
|
Token* LetDeclaration::getFirstToken() const {
|
2022-08-24 12:36:43 +02:00
|
|
|
if (PubKeyword) {
|
|
|
|
return PubKeyword;
|
|
|
|
}
|
2023-06-03 14:35:02 +02:00
|
|
|
if (ForeignKeyword) {
|
|
|
|
return ForeignKeyword;
|
|
|
|
}
|
|
|
|
return LetKeyword;
|
2022-08-24 12:36:43 +02:00
|
|
|
}
|
|
|
|
|
2023-06-03 14:35:02 +02:00
|
|
|
Token* LetDeclaration::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();
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2024-01-21 08:51:50 +01:00
|
|
|
std::string VBar::getText() const {
|
|
|
|
return "|";
|
|
|
|
}
|
|
|
|
|
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-06-03 14:35:02 +02:00
|
|
|
std::string ForeignKeyword::getText() const {
|
|
|
|
return "foreign";
|
2023-05-30 21:34:40 +02:00
|
|
|
}
|
|
|
|
|
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 "~";
|
|
|
|
}
|
|
|
|
|
2023-06-08 14:52:22 +02:00
|
|
|
std::string At::getText() const {
|
|
|
|
return "@";
|
|
|
|
}
|
|
|
|
|
2023-05-20 23:48:26 +02:00
|
|
|
std::string ClassKeyword::getText() const {
|
|
|
|
return "class";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string InstanceKeyword::getText() const {
|
|
|
|
return "instance";
|
|
|
|
}
|
|
|
|
|
2024-02-04 17:44:58 +01:00
|
|
|
ByteString getCanonicalText(const Symbol* N) {
|
|
|
|
switch (N->getKind()) {
|
|
|
|
case NodeKind::Identifier:
|
|
|
|
return static_cast<const Identifier*>(N)->Text;
|
|
|
|
case NodeKind::IdentifierAlt:
|
|
|
|
return static_cast<const IdentifierAlt*>(N)->Text;
|
|
|
|
case NodeKind::CustomOperator:
|
|
|
|
return static_cast<const CustomOperator*>(N)->Text;
|
|
|
|
case NodeKind::VBar:
|
|
|
|
return static_cast<const VBar*>(N)->getText();
|
|
|
|
case NodeKind::WrappedOperator:
|
|
|
|
return static_cast<const WrappedOperator*>(N)->getOperator()->getText();
|
|
|
|
default:
|
|
|
|
ZEN_UNREACHABLE
|
|
|
|
}
|
2023-05-21 14:50:28 +02:00
|
|
|
}
|
|
|
|
|
2023-06-02 20:58:03 +02:00
|
|
|
LiteralValue StringLiteral::getValue() {
|
2023-05-21 17:36:44 +02:00
|
|
|
return Text;
|
|
|
|
}
|
|
|
|
|
2023-06-02 20:58:03 +02:00
|
|
|
LiteralValue IntegerLiteral::getValue() {
|
2023-05-21 17:36:44 +02:00
|
|
|
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) {
|
2024-02-04 17:44:58 +01:00
|
|
|
ModuleNames.push_back(getCanonicalText(Name));
|
2022-08-26 22:10:18 +02:00
|
|
|
}
|
2024-02-04 17:44:58 +01:00
|
|
|
return SymbolPath { ModuleNames, getCanonicalText(Name) };
|
2022-08-26 22:10:18 +02:00
|
|
|
}
|
|
|
|
|
2022-08-19 19:52:57 +02:00
|
|
|
}
|
|
|
|
|