Add support for parsing more nodes and small fixes
- AppTypeExpression, NestedPattern, NamedPattern and VariantDeclaration can now be parsed. - Fixed some memory leaks when a parse error is encountered
This commit is contained in:
parent
ad460bc4a2
commit
dfaa91c9b6
6 changed files with 622 additions and 59 deletions
|
@ -108,6 +108,7 @@ namespace bolt {
|
||||||
ReturnKeyword,
|
ReturnKeyword,
|
||||||
ModKeyword,
|
ModKeyword,
|
||||||
StructKeyword,
|
StructKeyword,
|
||||||
|
EnumKeyword,
|
||||||
ClassKeyword,
|
ClassKeyword,
|
||||||
InstanceKeyword,
|
InstanceKeyword,
|
||||||
ElifKeyword,
|
ElifKeyword,
|
||||||
|
@ -130,11 +131,14 @@ namespace bolt {
|
||||||
QualifiedTypeExpression,
|
QualifiedTypeExpression,
|
||||||
ReferenceTypeExpression,
|
ReferenceTypeExpression,
|
||||||
ArrowTypeExpression,
|
ArrowTypeExpression,
|
||||||
|
AppTypeExpression,
|
||||||
VarTypeExpression,
|
VarTypeExpression,
|
||||||
NestedTypeExpression,
|
NestedTypeExpression,
|
||||||
TupleTypeExpression,
|
TupleTypeExpression,
|
||||||
BindPattern,
|
BindPattern,
|
||||||
LiteralPattern,
|
LiteralPattern,
|
||||||
|
NamedPattern,
|
||||||
|
NestedPattern,
|
||||||
ReferenceExpression,
|
ReferenceExpression,
|
||||||
MatchCase,
|
MatchCase,
|
||||||
MatchExpression,
|
MatchExpression,
|
||||||
|
@ -158,6 +162,9 @@ namespace bolt {
|
||||||
LetDeclaration,
|
LetDeclaration,
|
||||||
RecordDeclarationField,
|
RecordDeclarationField,
|
||||||
RecordDeclaration,
|
RecordDeclaration,
|
||||||
|
VariantDeclaration,
|
||||||
|
TupleVariantDeclarationMember,
|
||||||
|
RecordVariantDeclarationMember,
|
||||||
ClassDeclaration,
|
ClassDeclaration,
|
||||||
InstanceDeclaration,
|
InstanceDeclaration,
|
||||||
SourceFile,
|
SourceFile,
|
||||||
|
@ -252,9 +259,11 @@ namespace bolt {
|
||||||
Node* Source;
|
Node* Source;
|
||||||
std::unordered_multimap<ByteString, std::tuple<Node*, SymbolKind>> Mapping;
|
std::unordered_multimap<ByteString, std::tuple<Node*, SymbolKind>> Mapping;
|
||||||
|
|
||||||
|
void addSymbol(ByteString Name, Node* Decl, SymbolKind Kind);
|
||||||
|
|
||||||
void scan(Node* X);
|
void scan(Node* X);
|
||||||
|
|
||||||
void addBindings(Pattern* P, Node* ToInsert);
|
void visitPattern(Pattern* P, Node* ToInsert);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -622,6 +631,20 @@ namespace bolt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EnumKeyword : public Token {
|
||||||
|
public:
|
||||||
|
|
||||||
|
inline EnumKeyword(TextLoc StartLoc):
|
||||||
|
Token(NodeKind::EnumKeyword, StartLoc) {}
|
||||||
|
|
||||||
|
std::string getText() const override;
|
||||||
|
|
||||||
|
static bool classof(const Node* N) {
|
||||||
|
return N->getKind() == NodeKind::EnumKeyword;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class ClassKeyword : public Token {
|
class ClassKeyword : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -1067,6 +1090,24 @@ namespace bolt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class VarTypeExpression : public TypeExpression {
|
class VarTypeExpression : public TypeExpression {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -1167,6 +1208,45 @@ namespace bolt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NamedPattern : public Pattern {
|
||||||
|
public:
|
||||||
|
|
||||||
|
IdentifierAlt* Name;
|
||||||
|
std::vector<Pattern*> Patterns;
|
||||||
|
|
||||||
|
inline NamedPattern(
|
||||||
|
IdentifierAlt* Name,
|
||||||
|
std::vector<Pattern*> Patterns
|
||||||
|
): Pattern(NodeKind::NamedPattern),
|
||||||
|
Name(Name),
|
||||||
|
Patterns(Patterns) {}
|
||||||
|
|
||||||
|
Token* getFirstToken() const override;
|
||||||
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class Expression : public TypedNode {
|
class Expression : public TypedNode {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -1741,6 +1821,83 @@ namespace bolt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class RecordVariantDeclarationMember : public VariantDeclarationMember {
|
||||||
|
public:
|
||||||
|
|
||||||
|
IdentifierAlt* Name;
|
||||||
|
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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class VariantDeclaration : public Node {
|
||||||
|
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
|
||||||
|
): Node(NodeKind::VariantDeclaration),
|
||||||
|
PubKeyword(PubKeyword),
|
||||||
|
EnumKeyword(EnumKeyword),
|
||||||
|
Name(Name),
|
||||||
|
TVs(TVs),
|
||||||
|
BlockStart(BlockStart),
|
||||||
|
Members(Members) {}
|
||||||
|
|
||||||
|
Token* getFirstToken() const override;
|
||||||
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class SourceFile : public Node {
|
class SourceFile : public Node {
|
||||||
|
|
||||||
Scope* TheScope = nullptr;
|
Scope* TheScope = nullptr;
|
||||||
|
@ -1798,6 +1955,7 @@ namespace bolt {
|
||||||
template<> inline NodeKind getNodeType<ReturnKeyword>() { return NodeKind::ReturnKeyword; }
|
template<> inline NodeKind getNodeType<ReturnKeyword>() { return NodeKind::ReturnKeyword; }
|
||||||
template<> inline NodeKind getNodeType<ModKeyword>() { return NodeKind::ModKeyword; }
|
template<> inline NodeKind getNodeType<ModKeyword>() { return NodeKind::ModKeyword; }
|
||||||
template<> inline NodeKind getNodeType<StructKeyword>() { return NodeKind::StructKeyword; }
|
template<> inline NodeKind getNodeType<StructKeyword>() { return NodeKind::StructKeyword; }
|
||||||
|
template<> inline NodeKind getNodeType<EnumKeyword>() { return NodeKind::EnumKeyword; }
|
||||||
template<> inline NodeKind getNodeType<ClassKeyword>() { return NodeKind::ClassKeyword; }
|
template<> inline NodeKind getNodeType<ClassKeyword>() { return NodeKind::ClassKeyword; }
|
||||||
template<> inline NodeKind getNodeType<InstanceKeyword>() { return NodeKind::InstanceKeyword; }
|
template<> inline NodeKind getNodeType<InstanceKeyword>() { return NodeKind::InstanceKeyword; }
|
||||||
template<> inline NodeKind getNodeType<ElifKeyword>() { return NodeKind::ElifKeyword; }
|
template<> inline NodeKind getNodeType<ElifKeyword>() { return NodeKind::ElifKeyword; }
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "zen/config.hpp"
|
||||||
|
|
||||||
#include "bolt/CST.hpp"
|
#include "bolt/CST.hpp"
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
@ -53,6 +55,8 @@ namespace bolt {
|
||||||
return static_cast<D*>(this)->visitModKeyword(static_cast<ModKeyword*>(N));
|
return static_cast<D*>(this)->visitModKeyword(static_cast<ModKeyword*>(N));
|
||||||
case NodeKind::StructKeyword:
|
case NodeKind::StructKeyword:
|
||||||
return static_cast<D*>(this)->visitStructKeyword(static_cast<StructKeyword*>(N));
|
return static_cast<D*>(this)->visitStructKeyword(static_cast<StructKeyword*>(N));
|
||||||
|
case NodeKind::EnumKeyword:
|
||||||
|
return static_cast<D*>(this)->visitEnumKeyword(static_cast<EnumKeyword*>(N));
|
||||||
case NodeKind::ClassKeyword:
|
case NodeKind::ClassKeyword:
|
||||||
return static_cast<D*>(this)->visitClassKeyword(static_cast<ClassKeyword*>(N));
|
return static_cast<D*>(this)->visitClassKeyword(static_cast<ClassKeyword*>(N));
|
||||||
case NodeKind::InstanceKeyword:
|
case NodeKind::InstanceKeyword:
|
||||||
|
@ -97,6 +101,8 @@ namespace bolt {
|
||||||
return static_cast<D*>(this)->visitReferenceTypeExpression(static_cast<ReferenceTypeExpression*>(N));
|
return static_cast<D*>(this)->visitReferenceTypeExpression(static_cast<ReferenceTypeExpression*>(N));
|
||||||
case NodeKind::ArrowTypeExpression:
|
case NodeKind::ArrowTypeExpression:
|
||||||
return static_cast<D*>(this)->visitArrowTypeExpression(static_cast<ArrowTypeExpression*>(N));
|
return static_cast<D*>(this)->visitArrowTypeExpression(static_cast<ArrowTypeExpression*>(N));
|
||||||
|
case NodeKind::AppTypeExpression:
|
||||||
|
return static_cast<D*>(this)->visitAppTypeExpression(static_cast<AppTypeExpression*>(N));
|
||||||
case NodeKind::VarTypeExpression:
|
case NodeKind::VarTypeExpression:
|
||||||
return static_cast<D*>(this)->visitVarTypeExpression(static_cast<VarTypeExpression*>(N));
|
return static_cast<D*>(this)->visitVarTypeExpression(static_cast<VarTypeExpression*>(N));
|
||||||
case NodeKind::NestedTypeExpression:
|
case NodeKind::NestedTypeExpression:
|
||||||
|
@ -107,6 +113,10 @@ namespace bolt {
|
||||||
return static_cast<D*>(this)->visitBindPattern(static_cast<BindPattern*>(N));
|
return static_cast<D*>(this)->visitBindPattern(static_cast<BindPattern*>(N));
|
||||||
case NodeKind::LiteralPattern:
|
case NodeKind::LiteralPattern:
|
||||||
return static_cast<D*>(this)->visitLiteralPattern(static_cast<LiteralPattern*>(N));
|
return static_cast<D*>(this)->visitLiteralPattern(static_cast<LiteralPattern*>(N));
|
||||||
|
case NodeKind::NamedPattern:
|
||||||
|
return static_cast<D*>(this)->visitNamedPattern(static_cast<NamedPattern*>(N));
|
||||||
|
case NodeKind::NestedPattern:
|
||||||
|
return static_cast<D*>(this)->visitNestedPattern(static_cast<NestedPattern*>(N));
|
||||||
case NodeKind::ReferenceExpression:
|
case NodeKind::ReferenceExpression:
|
||||||
return static_cast<D*>(this)->visitReferenceExpression(static_cast<ReferenceExpression*>(N));
|
return static_cast<D*>(this)->visitReferenceExpression(static_cast<ReferenceExpression*>(N));
|
||||||
case NodeKind::MatchCase:
|
case NodeKind::MatchCase:
|
||||||
|
@ -153,6 +163,12 @@ namespace bolt {
|
||||||
return static_cast<D*>(this)->visitStructDeclarationField(static_cast<RecordDeclarationField*>(N));
|
return static_cast<D*>(this)->visitStructDeclarationField(static_cast<RecordDeclarationField*>(N));
|
||||||
case NodeKind::RecordDeclaration:
|
case NodeKind::RecordDeclaration:
|
||||||
return static_cast<D*>(this)->visitStructDeclaration(static_cast<RecordDeclaration*>(N));
|
return static_cast<D*>(this)->visitStructDeclaration(static_cast<RecordDeclaration*>(N));
|
||||||
|
case NodeKind::VariantDeclaration:
|
||||||
|
return static_cast<D*>(this)->visitVariantDeclaration(static_cast<VariantDeclaration*>(N));
|
||||||
|
case NodeKind::TupleVariantDeclarationMember:
|
||||||
|
return static_cast<D*>(this)->visitTupleVariantDeclarationMember(static_cast<TupleVariantDeclarationMember*>(N));
|
||||||
|
case NodeKind::RecordVariantDeclarationMember:
|
||||||
|
return static_cast<D*>(this)->visitRecordVariantDeclarationMember(static_cast<RecordVariantDeclarationMember*>(N));
|
||||||
case NodeKind::ClassDeclaration:
|
case NodeKind::ClassDeclaration:
|
||||||
return static_cast<D*>(this)->visitClassDeclaration(static_cast<ClassDeclaration*>(N));
|
return static_cast<D*>(this)->visitClassDeclaration(static_cast<ClassDeclaration*>(N));
|
||||||
case NodeKind::InstanceDeclaration:
|
case NodeKind::InstanceDeclaration:
|
||||||
|
@ -256,6 +272,10 @@ namespace bolt {
|
||||||
visitToken(N);
|
visitToken(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitEnumKeyword(EnumKeyword* N) {
|
||||||
|
visitToken(N);
|
||||||
|
}
|
||||||
|
|
||||||
void visitClassKeyword(ClassKeyword* N) {
|
void visitClassKeyword(ClassKeyword* N) {
|
||||||
visitToken(N);
|
visitToken(N);
|
||||||
}
|
}
|
||||||
|
@ -352,6 +372,10 @@ namespace bolt {
|
||||||
visitTypeExpression(N);
|
visitTypeExpression(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitAppTypeExpression(AppTypeExpression* N) {
|
||||||
|
visitTypeExpression(N);
|
||||||
|
}
|
||||||
|
|
||||||
void visitVarTypeExpression(VarTypeExpression* N) {
|
void visitVarTypeExpression(VarTypeExpression* N) {
|
||||||
visitTypeExpression(N);
|
visitTypeExpression(N);
|
||||||
}
|
}
|
||||||
|
@ -376,6 +400,14 @@ namespace bolt {
|
||||||
visitPattern(N);
|
visitPattern(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitNamedPattern(NamedPattern* N) {
|
||||||
|
visitPattern(N);
|
||||||
|
}
|
||||||
|
|
||||||
|
void visitNestedPattern(NestedPattern* N) {
|
||||||
|
visitPattern(N);
|
||||||
|
}
|
||||||
|
|
||||||
void visitExpression(Expression* N) {
|
void visitExpression(Expression* N) {
|
||||||
visitNode(N);
|
visitNode(N);
|
||||||
}
|
}
|
||||||
|
@ -480,6 +512,22 @@ namespace bolt {
|
||||||
visitNode(N);
|
visitNode(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitVariantDeclaration(VariantDeclaration* N) {
|
||||||
|
visitNode(N);
|
||||||
|
}
|
||||||
|
|
||||||
|
void visitVariantDeclarationMember(VariantDeclarationMember* N) {
|
||||||
|
visitNode(N);
|
||||||
|
}
|
||||||
|
|
||||||
|
void visitTupleVariantDeclarationMember(TupleVariantDeclarationMember* N) {
|
||||||
|
visitVariantDeclarationMember(N);
|
||||||
|
}
|
||||||
|
|
||||||
|
void visitRecordVariantDeclarationMember(RecordVariantDeclarationMember* N) {
|
||||||
|
visitVariantDeclarationMember(N);
|
||||||
|
}
|
||||||
|
|
||||||
void visitClassDeclaration(ClassDeclaration* N) {
|
void visitClassDeclaration(ClassDeclaration* N) {
|
||||||
visitNode(N);
|
visitNode(N);
|
||||||
}
|
}
|
||||||
|
@ -559,6 +607,9 @@ namespace bolt {
|
||||||
case NodeKind::StructKeyword:
|
case NodeKind::StructKeyword:
|
||||||
visitEachChild(static_cast<StructKeyword*>(N));
|
visitEachChild(static_cast<StructKeyword*>(N));
|
||||||
break;
|
break;
|
||||||
|
case NodeKind::EnumKeyword:
|
||||||
|
visitEachChild(static_cast<EnumKeyword*>(N));
|
||||||
|
break;
|
||||||
case NodeKind::ClassKeyword:
|
case NodeKind::ClassKeyword:
|
||||||
visitEachChild(static_cast<ClassKeyword*>(N));
|
visitEachChild(static_cast<ClassKeyword*>(N));
|
||||||
break;
|
break;
|
||||||
|
@ -625,6 +676,9 @@ namespace bolt {
|
||||||
case NodeKind::ArrowTypeExpression:
|
case NodeKind::ArrowTypeExpression:
|
||||||
visitEachChild(static_cast<ArrowTypeExpression*>(N));
|
visitEachChild(static_cast<ArrowTypeExpression*>(N));
|
||||||
break;
|
break;
|
||||||
|
case NodeKind::AppTypeExpression:
|
||||||
|
visitEachChild(static_cast<AppTypeExpression*>(N));
|
||||||
|
break;
|
||||||
case NodeKind::VarTypeExpression:
|
case NodeKind::VarTypeExpression:
|
||||||
visitEachChild(static_cast<VarTypeExpression*>(N));
|
visitEachChild(static_cast<VarTypeExpression*>(N));
|
||||||
break;
|
break;
|
||||||
|
@ -640,6 +694,12 @@ namespace bolt {
|
||||||
case NodeKind::LiteralPattern:
|
case NodeKind::LiteralPattern:
|
||||||
visitEachChild(static_cast<LiteralPattern*>(N));
|
visitEachChild(static_cast<LiteralPattern*>(N));
|
||||||
break;
|
break;
|
||||||
|
case NodeKind::NamedPattern:
|
||||||
|
visitEachChild(static_cast<NamedPattern*>(N));
|
||||||
|
break;
|
||||||
|
case NodeKind::NestedPattern:
|
||||||
|
visitEachChild(static_cast<NestedPattern*>(N));
|
||||||
|
break;
|
||||||
case NodeKind::ReferenceExpression:
|
case NodeKind::ReferenceExpression:
|
||||||
visitEachChild(static_cast<ReferenceExpression*>(N));
|
visitEachChild(static_cast<ReferenceExpression*>(N));
|
||||||
break;
|
break;
|
||||||
|
@ -709,6 +769,15 @@ namespace bolt {
|
||||||
case NodeKind::RecordDeclarationField:
|
case NodeKind::RecordDeclarationField:
|
||||||
visitEachChild(static_cast<RecordDeclarationField*>(N));
|
visitEachChild(static_cast<RecordDeclarationField*>(N));
|
||||||
break;
|
break;
|
||||||
|
case NodeKind::VariantDeclaration:
|
||||||
|
visitEachChild(static_cast<VariantDeclaration*>(N));
|
||||||
|
break;
|
||||||
|
case NodeKind::TupleVariantDeclarationMember:
|
||||||
|
visitEachChild(static_cast<TupleVariantDeclarationMember*>(N));
|
||||||
|
break;
|
||||||
|
case NodeKind::RecordVariantDeclarationMember:
|
||||||
|
visitEachChild(static_cast<RecordVariantDeclarationMember*>(N));
|
||||||
|
break;
|
||||||
case NodeKind::ClassDeclaration:
|
case NodeKind::ClassDeclaration:
|
||||||
visitEachChild(static_cast<ClassDeclaration*>(N));
|
visitEachChild(static_cast<ClassDeclaration*>(N));
|
||||||
break;
|
break;
|
||||||
|
@ -788,6 +857,9 @@ namespace bolt {
|
||||||
void visitEachChild(StructKeyword* N) {
|
void visitEachChild(StructKeyword* N) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitEachChild(EnumKeyword* N) {
|
||||||
|
}
|
||||||
|
|
||||||
void visitEachChild(ClassKeyword* N) {
|
void visitEachChild(ClassKeyword* N) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,6 +950,13 @@ namespace bolt {
|
||||||
BOLT_VISIT(N->ReturnType);
|
BOLT_VISIT(N->ReturnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitEachChild(AppTypeExpression* N) {
|
||||||
|
BOLT_VISIT(N->Op);
|
||||||
|
for (auto Arg: N->Args) {
|
||||||
|
BOLT_VISIT(Arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void visitEachChild(VarTypeExpression* N) {
|
void visitEachChild(VarTypeExpression* N) {
|
||||||
BOLT_VISIT(N->Name);
|
BOLT_VISIT(N->Name);
|
||||||
}
|
}
|
||||||
|
@ -907,6 +986,19 @@ namespace bolt {
|
||||||
BOLT_VISIT(N->Literal);
|
BOLT_VISIT(N->Literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitEachChild(NamedPattern* N) {
|
||||||
|
BOLT_VISIT(N->Name);
|
||||||
|
for (auto P: N->Patterns) {
|
||||||
|
BOLT_VISIT(P);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void visitEachChild(NestedPattern* N) {
|
||||||
|
BOLT_VISIT(N->LParen);
|
||||||
|
BOLT_VISIT(N->P);
|
||||||
|
BOLT_VISIT(N->RParen);
|
||||||
|
}
|
||||||
|
|
||||||
void visitEachChild(ReferenceExpression* N) {
|
void visitEachChild(ReferenceExpression* N) {
|
||||||
for (auto [Name, Dot]: N->ModulePath) {
|
for (auto [Name, Dot]: N->ModulePath) {
|
||||||
BOLT_VISIT(Name);
|
BOLT_VISIT(Name);
|
||||||
|
@ -1082,6 +1174,36 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitEachChild(VariantDeclaration* N) {
|
||||||
|
if (N->PubKeyword) {
|
||||||
|
BOLT_VISIT(N->PubKeyword);
|
||||||
|
}
|
||||||
|
BOLT_VISIT(N->EnumKeyword);
|
||||||
|
BOLT_VISIT(N->Name);
|
||||||
|
for (auto TV: N->TVs) {
|
||||||
|
BOLT_VISIT(TV);
|
||||||
|
}
|
||||||
|
BOLT_VISIT(N->BlockStart);
|
||||||
|
for (auto Member: N->Members) {
|
||||||
|
BOLT_VISIT(Member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void visitEachChild(TupleVariantDeclarationMember* N) {
|
||||||
|
BOLT_VISIT(N->Name);
|
||||||
|
for (auto Element: N->Elements) {
|
||||||
|
BOLT_VISIT(Element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void visitEachChild(RecordVariantDeclarationMember* N) {
|
||||||
|
BOLT_VISIT(N->Name);
|
||||||
|
BOLT_VISIT(N->BlockStart);
|
||||||
|
for (auto Field: N->Fields) {
|
||||||
|
BOLT_VISIT(Field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void visitEachChild(ClassDeclaration* N) {
|
void visitEachChild(ClassDeclaration* N) {
|
||||||
if (N->PubKeyword) {
|
if (N->PubKeyword) {
|
||||||
BOLT_VISIT(N->PubKeyword);
|
BOLT_VISIT(N->PubKeyword);
|
||||||
|
|
|
@ -53,9 +53,7 @@ namespace bolt {
|
||||||
std::optional<OperatorInfo> getInfix(Token* T);
|
std::optional<OperatorInfo> getInfix(Token* T);
|
||||||
|
|
||||||
bool isInfix(Token* T);
|
bool isInfix(Token* T);
|
||||||
|
|
||||||
bool isPrefix(Token* T);
|
bool isPrefix(Token* T);
|
||||||
|
|
||||||
bool isSuffix(Token* T);
|
bool isSuffix(Token* T);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -73,6 +71,8 @@ namespace bolt {
|
||||||
|
|
||||||
Token* expectToken(NodeKind Ty);
|
Token* expectToken(NodeKind Ty);
|
||||||
|
|
||||||
|
std::vector<RecordDeclarationField*> parseRecordFields();
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* expectToken() {
|
T* expectToken() {
|
||||||
return static_cast<T*>(expectToken(getNodeType<T>()));
|
return static_cast<T*>(expectToken(getNodeType<T>()));
|
||||||
|
@ -86,6 +86,7 @@ namespace bolt {
|
||||||
|
|
||||||
ConstraintExpression* parseConstraintExpression();
|
ConstraintExpression* parseConstraintExpression();
|
||||||
|
|
||||||
|
TypeExpression* parseAppTypeExpression();
|
||||||
TypeExpression* parsePrimitiveTypeExpression();
|
TypeExpression* parsePrimitiveTypeExpression();
|
||||||
TypeExpression* parseQualifiedTypeExpression();
|
TypeExpression* parseQualifiedTypeExpression();
|
||||||
TypeExpression* parseArrowTypeExpression();
|
TypeExpression* parseArrowTypeExpression();
|
||||||
|
@ -101,6 +102,7 @@ namespace bolt {
|
||||||
|
|
||||||
TypeExpression* parseTypeExpression();
|
TypeExpression* parseTypeExpression();
|
||||||
|
|
||||||
|
Pattern* parsePrimitivePattern();
|
||||||
Pattern* parsePattern();
|
Pattern* parsePattern();
|
||||||
|
|
||||||
Parameter* parseParam();
|
Parameter* parseParam();
|
||||||
|
@ -131,6 +133,8 @@ namespace bolt {
|
||||||
|
|
||||||
RecordDeclaration* parseRecordDeclaration();
|
RecordDeclaration* parseRecordDeclaration();
|
||||||
|
|
||||||
|
VariantDeclaration* parseVariantDeclaration();
|
||||||
|
|
||||||
Node* parseSourceElement();
|
Node* parseSourceElement();
|
||||||
|
|
||||||
SourceFile* parseSourceFile();
|
SourceFile* parseSourceFile();
|
||||||
|
|
110
src/CST.cc
110
src/CST.cc
|
@ -55,6 +55,10 @@ namespace bolt {
|
||||||
scan(Source);
|
scan(Source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scope::addSymbol(ByteString Name, Node* Decl, SymbolKind Kind) {
|
||||||
|
Mapping.emplace(Name, std::make_tuple(Decl, Kind));
|
||||||
|
}
|
||||||
|
|
||||||
void Scope::scan(Node* X) {
|
void Scope::scan(Node* X) {
|
||||||
switch (X->getKind()) {
|
switch (X->getKind()) {
|
||||||
case NodeKind::ExpressionStatement:
|
case NodeKind::ExpressionStatement:
|
||||||
|
@ -72,7 +76,7 @@ namespace bolt {
|
||||||
case NodeKind::ClassDeclaration:
|
case NodeKind::ClassDeclaration:
|
||||||
{
|
{
|
||||||
auto Decl = static_cast<ClassDeclaration*>(X);
|
auto Decl = static_cast<ClassDeclaration*>(X);
|
||||||
Mapping.emplace(Decl->Name->getCanonicalText(), std::make_tuple(Decl, SymbolKind::Class));
|
addSymbol(Decl->Name->getCanonicalText(), Decl, SymbolKind::Class);
|
||||||
for (auto Element: Decl->Elements) {
|
for (auto Element: Decl->Elements) {
|
||||||
scan(Element);
|
scan(Element);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +88,19 @@ namespace bolt {
|
||||||
case NodeKind::LetDeclaration:
|
case NodeKind::LetDeclaration:
|
||||||
{
|
{
|
||||||
auto Decl = static_cast<LetDeclaration*>(X);
|
auto Decl = static_cast<LetDeclaration*>(X);
|
||||||
addBindings(Decl->Pattern, Decl);
|
visitPattern(Decl->Pattern, Decl);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -92,12 +108,26 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scope::addBindings(Pattern* X, Node* ToInsert) {
|
void Scope::visitPattern(Pattern* X, Node* Decl) {
|
||||||
switch (X->getKind()) {
|
switch (X->getKind()) {
|
||||||
case NodeKind::BindPattern:
|
case NodeKind::BindPattern:
|
||||||
{
|
{
|
||||||
auto Y = static_cast<BindPattern*>(X);
|
auto Y = static_cast<BindPattern*>(X);
|
||||||
Mapping.emplace(Y->Name->Text, std::make_tuple(ToInsert, SymbolKind::Var));
|
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);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NodeKind::LiteralPattern:
|
case NodeKind::LiteralPattern:
|
||||||
|
@ -287,6 +317,17 @@ namespace bolt {
|
||||||
return ReturnType->getLastToken();
|
return ReturnType->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token* AppTypeExpression::getFirstToken() const {
|
||||||
|
return Op->getFirstToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
Token* AppTypeExpression::getLastToken() const {
|
||||||
|
if (Args.size()) {
|
||||||
|
return Args.back()->getLastToken();
|
||||||
|
}
|
||||||
|
return Op->getLastToken();
|
||||||
|
}
|
||||||
|
|
||||||
Token* VarTypeExpression::getLastToken() const {
|
Token* VarTypeExpression::getLastToken() const {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
@ -327,6 +368,25 @@ namespace bolt {
|
||||||
return Literal;
|
return Literal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
Token* ReferenceExpression::getFirstToken() const {
|
Token* ReferenceExpression::getFirstToken() const {
|
||||||
if (!ModulePath.empty()) {
|
if (!ModulePath.empty()) {
|
||||||
return std::get<0>(ModulePath.front());
|
return std::get<0>(ModulePath.front());
|
||||||
|
@ -531,7 +591,43 @@ namespace bolt {
|
||||||
|
|
||||||
Token* RecordDeclaration::getLastToken() const {
|
Token* RecordDeclaration::getLastToken() const {
|
||||||
if (Fields.size()) {
|
if (Fields.size()) {
|
||||||
Fields.back()->getLastToken();
|
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();
|
||||||
}
|
}
|
||||||
return BlockStart;
|
return BlockStart;
|
||||||
}
|
}
|
||||||
|
@ -667,6 +763,10 @@ namespace bolt {
|
||||||
return "struct";
|
return "struct";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string EnumKeyword::getText() const {
|
||||||
|
return "enum";
|
||||||
|
}
|
||||||
|
|
||||||
std::string Invalid::getText() const {
|
std::string Invalid::getText() const {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
278
src/Parser.cc
278
src/Parser.cc
|
@ -26,8 +26,10 @@
|
||||||
// includes tokens. This avoids memory leaks. And yes, they matter when the
|
// includes tokens. This avoids memory leaks. And yes, they matter when the
|
||||||
// compiler is permanently on such as in a language server.
|
// compiler is permanently on such as in a language server.
|
||||||
//
|
//
|
||||||
// 5. Always unref() a LineFoldEnd obtained via Tokens.get(), since it will
|
// 5. Always unref() a LineFoldEnd or BlockEnd obtained via Tokens.get(), since
|
||||||
// never be stored somewhere
|
// it will never be stored somewhere
|
||||||
|
//
|
||||||
|
// 6. Maintain the invariant that a wrong parse will never advance the input stream.
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
|
@ -100,7 +102,7 @@ namespace bolt {
|
||||||
return T;
|
return T;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pattern* Parser::parsePattern() {
|
Pattern* Parser::parsePrimitivePattern() {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
switch (T0->getKind()) {
|
switch (T0->getKind()) {
|
||||||
case NodeKind::StringLiteral:
|
case NodeKind::StringLiteral:
|
||||||
|
@ -110,6 +112,52 @@ namespace bolt {
|
||||||
case NodeKind::Identifier:
|
case NodeKind::Identifier:
|
||||||
Tokens.get();
|
Tokens.get();
|
||||||
return new BindPattern(static_cast<Identifier*>(T0));
|
return new BindPattern(static_cast<Identifier*>(T0));
|
||||||
|
case NodeKind::IdentifierAlt:
|
||||||
|
Tokens.get();
|
||||||
|
return new NamedPattern(static_cast<IdentifierAlt*>(T0), {});
|
||||||
|
case NodeKind::LParen:
|
||||||
|
{
|
||||||
|
Tokens.get();
|
||||||
|
auto LParen = static_cast<class LParen*>(T0);
|
||||||
|
auto T1 = Tokens.peek();
|
||||||
|
RParen* RParen;
|
||||||
|
if (T1->getKind() == NodeKind::IdentifierAlt) {
|
||||||
|
Tokens.get();
|
||||||
|
auto Name = static_cast<IdentifierAlt*>(T1);
|
||||||
|
std::vector<Pattern*> Patterns;
|
||||||
|
for (;;) {
|
||||||
|
auto T2 = Tokens.peek();
|
||||||
|
if (T2->getKind() == NodeKind::RParen) {
|
||||||
|
Tokens.get();
|
||||||
|
RParen = static_cast<class RParen*>(T2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto P = parsePrimitivePattern();
|
||||||
|
if (!P) {
|
||||||
|
LParen->unref();
|
||||||
|
for (auto P: Patterns) {
|
||||||
|
P->unref();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
Patterns.push_back(P);
|
||||||
|
}
|
||||||
|
return new NestedPattern { LParen, new NamedPattern { Name, Patterns }, RParen };
|
||||||
|
} else {
|
||||||
|
auto P = parsePattern();
|
||||||
|
if (!P) {
|
||||||
|
LParen->unref();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto RParen = expectToken<class RParen>();
|
||||||
|
if (!RParen) {
|
||||||
|
LParen->unref();
|
||||||
|
P->unref();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return new NestedPattern { LParen, P, RParen };
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// Tokens.get();
|
// Tokens.get();
|
||||||
DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector { NodeKind::Identifier, NodeKind::StringLiteral, NodeKind::IntegerLiteral });
|
DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector { NodeKind::Identifier, NodeKind::StringLiteral, NodeKind::IntegerLiteral });
|
||||||
|
@ -117,6 +165,10 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pattern* Parser::parsePattern() {
|
||||||
|
return parsePrimitivePattern();
|
||||||
|
}
|
||||||
|
|
||||||
TypeExpression* Parser::parseTypeExpression() {
|
TypeExpression* Parser::parseTypeExpression() {
|
||||||
return parseQualifiedTypeExpression();
|
return parseQualifiedTypeExpression();
|
||||||
}
|
}
|
||||||
|
@ -292,8 +344,39 @@ after_tuple_element:
|
||||||
return new ReferenceTypeExpression(ModulePath, static_cast<IdentifierAlt*>(Name));
|
return new ReferenceTypeExpression(ModulePath, static_cast<IdentifierAlt*>(Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeExpression* Parser::parseAppTypeExpression() {
|
||||||
|
auto OpTy = parsePrimitiveTypeExpression();
|
||||||
|
if (!OpTy) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::vector<TypeExpression*> ArgTys;
|
||||||
|
for (;;) {
|
||||||
|
auto T1 = Tokens.peek();
|
||||||
|
auto Kind = T1->getKind();
|
||||||
|
if (Kind == NodeKind::RArrow || Kind == NodeKind::Equals || Kind == NodeKind::BlockStart || Kind == NodeKind::LineFoldEnd || Kind == NodeKind::EndOfFile || Kind == NodeKind::RParen) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto TE = parsePrimitiveTypeExpression();
|
||||||
|
if (!TE) {
|
||||||
|
OpTy->unref();
|
||||||
|
for (auto Arg: ArgTys) {
|
||||||
|
Arg->unref();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
ArgTys.push_back(TE);
|
||||||
|
}
|
||||||
|
if (ArgTys.empty()) {
|
||||||
|
return OpTy;
|
||||||
|
}
|
||||||
|
return new AppTypeExpression { OpTy, ArgTys };
|
||||||
|
}
|
||||||
|
|
||||||
TypeExpression* Parser::parseArrowTypeExpression() {
|
TypeExpression* Parser::parseArrowTypeExpression() {
|
||||||
auto RetType = parsePrimitiveTypeExpression();
|
auto RetType = parseAppTypeExpression();
|
||||||
|
if (RetType == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
std::vector<TypeExpression*> ParamTypes;
|
std::vector<TypeExpression*> ParamTypes;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T1 = Tokens.peek();
|
auto T1 = Tokens.peek();
|
||||||
|
@ -302,7 +385,7 @@ after_tuple_element:
|
||||||
}
|
}
|
||||||
Tokens.get();
|
Tokens.get();
|
||||||
ParamTypes.push_back(RetType);
|
ParamTypes.push_back(RetType);
|
||||||
RetType = parsePrimitiveTypeExpression();
|
RetType = parseAppTypeExpression();
|
||||||
if (!RetType) {
|
if (!RetType) {
|
||||||
for (auto ParamType: ParamTypes) {
|
for (auto ParamType: ParamTypes) {
|
||||||
ParamType->unref();
|
ParamType->unref();
|
||||||
|
@ -321,7 +404,6 @@ after_tuple_element:
|
||||||
if (!T0) {
|
if (!T0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Tokens.get();
|
|
||||||
auto T1 = Tokens.peek();
|
auto T1 = Tokens.peek();
|
||||||
Expression* Value;
|
Expression* Value;
|
||||||
BlockStart* BlockStart;
|
BlockStart* BlockStart;
|
||||||
|
@ -346,7 +428,7 @@ after_tuple_element:
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T2 = Tokens.peek();
|
auto T2 = Tokens.peek();
|
||||||
if (llvm::isa<BlockEnd>(T2)) {
|
if (llvm::isa<BlockEnd>(T2)) {
|
||||||
Tokens.get();
|
Tokens.get()->unref();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto Pattern = parsePattern();
|
auto Pattern = parsePattern();
|
||||||
|
@ -657,7 +739,7 @@ finish:
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T2 = Tokens.peek();
|
auto T2 = Tokens.peek();
|
||||||
if (T2->getKind() == NodeKind::BlockEnd) {
|
if (T2->getKind() == NodeKind::BlockEnd) {
|
||||||
Tokens.get();
|
Tokens.get()->unref();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto Element = parseLetBodyElement();
|
auto Element = parseLetBodyElement();
|
||||||
|
@ -681,7 +763,7 @@ finish:
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T5 = Tokens.peek();
|
auto T5 = Tokens.peek();
|
||||||
if (T5->getKind() == NodeKind::BlockEnd) {
|
if (T5->getKind() == NodeKind::BlockEnd) {
|
||||||
Tokens.get();
|
Tokens.get()->unref();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto Element = parseLetBodyElement();
|
auto Element = parseLetBodyElement();
|
||||||
|
@ -784,7 +866,7 @@ after_params:
|
||||||
Elements.push_back(Element);
|
Elements.push_back(Element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Tokens.get();
|
Tokens.get()->unref(); // Always a BlockEnd
|
||||||
Body = new LetBlockBody(static_cast<BlockStart*>(T2), Elements);
|
Body = new LetBlockBody(static_cast<BlockStart*>(T2), Elements);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -966,7 +1048,7 @@ after_vars:
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T2 = Tokens.peek();
|
auto T2 = Tokens.peek();
|
||||||
if (T2->is<BlockEnd>()) {
|
if (T2->is<BlockEnd>()) {
|
||||||
Tokens.get();
|
Tokens.get()->unref();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto Element = parseClassElement();
|
auto Element = parseClassElement();
|
||||||
|
@ -1044,7 +1126,7 @@ after_vars:
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T2 = Tokens.peek();
|
auto T2 = Tokens.peek();
|
||||||
if (T2->is<BlockEnd>()) {
|
if (T2->is<BlockEnd>()) {
|
||||||
Tokens.get();
|
Tokens.get()->unref();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto Element = parseClassElement();
|
auto Element = parseClassElement();
|
||||||
|
@ -1063,6 +1145,38 @@ after_vars:
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<RecordDeclarationField*> Parser::parseRecordFields() {
|
||||||
|
std::vector<RecordDeclarationField*> Fields;
|
||||||
|
for (;;) {
|
||||||
|
auto T1 = Tokens.peek();
|
||||||
|
if (T1->getKind() == NodeKind::BlockEnd) {
|
||||||
|
Tokens.get()->unref();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto Name = expectToken<Identifier>();
|
||||||
|
if (!Name) {
|
||||||
|
skipToLineFoldEnd();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto Colon = expectToken<class Colon>();
|
||||||
|
if (!Colon) {
|
||||||
|
Name->unref();
|
||||||
|
skipToLineFoldEnd();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto TE = parseTypeExpression();
|
||||||
|
if (!TE) {
|
||||||
|
Name->unref();
|
||||||
|
Colon->unref();
|
||||||
|
skipToLineFoldEnd();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
checkLineFoldEnd();
|
||||||
|
Fields.push_back(new RecordDeclarationField { Name, Colon, TE });
|
||||||
|
}
|
||||||
|
return Fields;
|
||||||
|
}
|
||||||
|
|
||||||
RecordDeclaration* Parser::parseRecordDeclaration() {
|
RecordDeclaration* Parser::parseRecordDeclaration() {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
PubKeyword* Pub = nullptr;
|
PubKeyword* Pub = nullptr;
|
||||||
|
@ -1087,6 +1201,17 @@ after_vars:
|
||||||
skipToLineFoldEnd();
|
skipToLineFoldEnd();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
std::vector<VarTypeExpression*> Vars;
|
||||||
|
for (;;) {
|
||||||
|
auto T1 = Tokens.peek();
|
||||||
|
if (T1->getKind() == NodeKind::BlockStart) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto Var = parseVarTypeExpression();
|
||||||
|
if (Var) {
|
||||||
|
Vars.push_back(Var);
|
||||||
|
}
|
||||||
|
}
|
||||||
auto BS = expectToken<BlockStart>();
|
auto BS = expectToken<BlockStart>();
|
||||||
if (!BS) {
|
if (!BS) {
|
||||||
if (Pub) {
|
if (Pub) {
|
||||||
|
@ -1097,50 +1222,99 @@ after_vars:
|
||||||
skipToLineFoldEnd();
|
skipToLineFoldEnd();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
std::vector<RecordDeclarationField*> Fields;
|
auto Fields = parseRecordFields();
|
||||||
|
Tokens.get()->unref(); // Always a LineFoldEnd
|
||||||
|
return new RecordDeclaration { Pub, Struct, Name, Vars, BS, Fields };
|
||||||
|
}
|
||||||
|
|
||||||
|
VariantDeclaration* Parser::parseVariantDeclaration() {
|
||||||
|
auto T0 = Tokens.peek();
|
||||||
|
PubKeyword* Pub = nullptr;
|
||||||
|
if (T0->getKind() == NodeKind::MutKeyword) {
|
||||||
|
Tokens.get();
|
||||||
|
Pub = static_cast<PubKeyword*>(T0);
|
||||||
|
}
|
||||||
|
auto Enum = expectToken<EnumKeyword>();
|
||||||
|
if (!Enum) {
|
||||||
|
if (Pub) {
|
||||||
|
Pub->unref();
|
||||||
|
}
|
||||||
|
skipToLineFoldEnd();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto Name = expectToken<IdentifierAlt>();
|
||||||
|
if (!Name) {
|
||||||
|
if (Pub) {
|
||||||
|
Pub->unref();
|
||||||
|
}
|
||||||
|
Enum->unref();
|
||||||
|
skipToLineFoldEnd();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::vector<VarTypeExpression*> TVs;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T1 = Tokens.get();
|
auto T0 = Tokens.peek();
|
||||||
if (T1->getKind() == NodeKind::BlockEnd) {
|
if (T0->getKind() == NodeKind::BlockStart) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (T1->getKind() != NodeKind::Identifier) {
|
auto Var = parseVarTypeExpression();
|
||||||
DE.add<UnexpectedTokenDiagnostic>(File, T1, std::vector { NodeKind::Identifier });
|
if (Var) {
|
||||||
if (Pub) {
|
TVs.push_back(Var);
|
||||||
Pub->unref();
|
|
||||||
}
|
|
||||||
Struct->unref();
|
|
||||||
Name->unref();
|
|
||||||
T1->unref();
|
|
||||||
skipToLineFoldEnd();
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
auto Colon = expectToken<class Colon>();
|
|
||||||
if (!Colon) {
|
|
||||||
if (Pub) {
|
|
||||||
Pub->unref();
|
|
||||||
}
|
|
||||||
Struct->unref();
|
|
||||||
Name->unref();
|
|
||||||
T1->unref();
|
|
||||||
skipToLineFoldEnd();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto TE = parseTypeExpression();
|
|
||||||
if (!TE) {
|
|
||||||
if (Pub) {
|
|
||||||
Pub->unref();
|
|
||||||
}
|
|
||||||
Struct->unref();
|
|
||||||
Name->unref();
|
|
||||||
T1->unref();
|
|
||||||
Colon->unref();
|
|
||||||
skipToLineFoldEnd();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
checkLineFoldEnd();
|
|
||||||
}
|
}
|
||||||
Tokens.get(); // Always a LineFoldEnd
|
auto BS = expectToken<BlockStart>();
|
||||||
return new RecordDeclaration { Pub, Struct, Name, BS, Fields };
|
if (!BS) {
|
||||||
|
if (Pub) {
|
||||||
|
Pub->unref();
|
||||||
|
}
|
||||||
|
Enum->unref();
|
||||||
|
Name->unref();
|
||||||
|
skipToLineFoldEnd();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::vector<VariantDeclarationMember*> Members;
|
||||||
|
for (;;) {
|
||||||
|
next_member:
|
||||||
|
auto T0 = Tokens.peek();
|
||||||
|
if (T0->getKind() == NodeKind::BlockEnd) {
|
||||||
|
Tokens.get()->unref();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto Name = expectToken<IdentifierAlt>();
|
||||||
|
if (!Name) {
|
||||||
|
skipToLineFoldEnd();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto T1 = Tokens.peek();
|
||||||
|
if (T1->getKind() == NodeKind::BlockStart) {
|
||||||
|
Tokens.get();
|
||||||
|
auto BS = static_cast<BlockStart*>(T1);
|
||||||
|
auto Fields = parseRecordFields();
|
||||||
|
// TODO continue; on error in Fields
|
||||||
|
Members.push_back(new RecordVariantDeclarationMember { Name, BS, Fields });
|
||||||
|
} else {
|
||||||
|
std::vector<TypeExpression*> Elements;
|
||||||
|
for (;;) {
|
||||||
|
auto T2 = Tokens.peek();
|
||||||
|
if (T2->getKind() == NodeKind::LineFoldEnd) {
|
||||||
|
Tokens.get()->unref();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto TE = parsePrimitiveTypeExpression();
|
||||||
|
if (!TE) {
|
||||||
|
Name->unref();
|
||||||
|
for (auto El: Elements) {
|
||||||
|
El->unref();
|
||||||
|
}
|
||||||
|
goto next_member;
|
||||||
|
}
|
||||||
|
Elements.push_back(TE);
|
||||||
|
}
|
||||||
|
Members.push_back(new TupleVariantDeclarationMember { Name, Elements });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkLineFoldEnd();
|
||||||
|
return new VariantDeclaration { Pub, Enum, Name, TVs, BS, Members };
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* Parser::parseClassElement() {
|
Node* Parser::parseClassElement() {
|
||||||
|
@ -1170,6 +1344,8 @@ after_vars:
|
||||||
return parseInstanceDeclaration();
|
return parseInstanceDeclaration();
|
||||||
case NodeKind::StructKeyword:
|
case NodeKind::StructKeyword:
|
||||||
return parseRecordDeclaration();
|
return parseRecordDeclaration();
|
||||||
|
case NodeKind::EnumKeyword:
|
||||||
|
return parseVariantDeclaration();
|
||||||
default:
|
default:
|
||||||
return parseExpressionStatement();
|
return parseExpressionStatement();
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ namespace bolt {
|
||||||
{ "class", NodeKind::ClassKeyword },
|
{ "class", NodeKind::ClassKeyword },
|
||||||
{ "instance", NodeKind::InstanceKeyword },
|
{ "instance", NodeKind::InstanceKeyword },
|
||||||
{ "struct", NodeKind::StructKeyword },
|
{ "struct", NodeKind::StructKeyword },
|
||||||
|
{ "enum", NodeKind::EnumKeyword },
|
||||||
};
|
};
|
||||||
|
|
||||||
Scanner::Scanner(TextFile& File, Stream<Char>& Chars):
|
Scanner::Scanner(TextFile& File, Stream<Char>& Chars):
|
||||||
|
@ -245,6 +246,8 @@ digit_finish:
|
||||||
return new InstanceKeyword(StartLoc);
|
return new InstanceKeyword(StartLoc);
|
||||||
case NodeKind::StructKeyword:
|
case NodeKind::StructKeyword:
|
||||||
return new StructKeyword(StartLoc);
|
return new StructKeyword(StartLoc);
|
||||||
|
case NodeKind::EnumKeyword:
|
||||||
|
return new EnumKeyword(StartLoc);
|
||||||
default:
|
default:
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue