Add NamedRecordPattern and rename NamedPattern to NamedTuplePattern

This commit is contained in:
Sam Vervaeck 2024-01-21 05:40:35 +01:00
parent 7ac3c39164
commit 1b5c32fe29
Signed by: samvv
SSH key fingerprint: SHA256:dIg0ywU1OP+ZYifrYxy8c5esO72cIKB+4/9wkZj1VaY
7 changed files with 353 additions and 63 deletions

View file

@ -141,7 +141,9 @@ namespace bolt {
TupleTypeExpression, TupleTypeExpression,
BindPattern, BindPattern,
LiteralPattern, LiteralPattern,
NamedPattern, RecordPatternField,
NamedRecordPattern,
NamedTuplePattern,
TuplePattern, TuplePattern,
NestedPattern, NestedPattern,
ListPattern, ListPattern,
@ -1313,16 +1315,68 @@ namespace bolt {
}; };
class NamedPattern : public Pattern { class RecordPatternField : public Node {
public:
Identifier* Name;
Equals* Equals;
Pattern* Pattern;
inline RecordPatternField(
Identifier* Name,
class Equals* Equals,
class Pattern* Pattern
): Node(NodeKind::RecordPatternField),
Name(Name),
Equals(Equals),
Pattern(Pattern) {}
inline RecordPatternField(
Identifier* Name
): RecordPatternField(Name, nullptr, nullptr) {}
Token* getFirstToken() const override;
Token* getLastToken() const override;
};
class NamedRecordPattern : public Pattern {
public:
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
IdentifierAlt* Name;
LBrace* LBrace;
std::vector<std::tuple<RecordPatternField*, Comma*>> Fields;
RBrace* RBrace;
inline NamedRecordPattern(
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath,
IdentifierAlt* Name,
class LBrace* LBrace,
std::vector<std::tuple<RecordPatternField*, Comma*>> Fields,
class RBrace* RBrace
): Pattern(NodeKind::NamedRecordPattern),
ModulePath(ModulePath),
Name(Name),
LBrace(LBrace),
Fields(Fields),
RBrace(RBrace) {}
Token* getFirstToken() const override;
Token* getLastToken() const override;
};
class NamedTuplePattern : public Pattern {
public: public:
IdentifierAlt* Name; IdentifierAlt* Name;
std::vector<Pattern*> Patterns; std::vector<Pattern*> Patterns;
inline NamedPattern( inline NamedTuplePattern(
IdentifierAlt* Name, IdentifierAlt* Name,
std::vector<Pattern*> Patterns std::vector<Pattern*> Patterns
): Pattern(NodeKind::NamedPattern), ): Pattern(NodeKind::NamedTuplePattern),
Name(Name), Name(Name),
Patterns(Patterns) {} Patterns(Patterns) {}

View file

@ -73,7 +73,9 @@ namespace bolt {
BOLT_GEN_CASE(TupleTypeExpression) BOLT_GEN_CASE(TupleTypeExpression)
BOLT_GEN_CASE(BindPattern) BOLT_GEN_CASE(BindPattern)
BOLT_GEN_CASE(LiteralPattern) BOLT_GEN_CASE(LiteralPattern)
BOLT_GEN_CASE(NamedPattern) BOLT_GEN_CASE(RecordPatternField)
BOLT_GEN_CASE(NamedRecordPattern)
BOLT_GEN_CASE(NamedTuplePattern)
BOLT_GEN_CASE(TuplePattern) BOLT_GEN_CASE(TuplePattern)
BOLT_GEN_CASE(NestedPattern) BOLT_GEN_CASE(NestedPattern)
BOLT_GEN_CASE(ListPattern) BOLT_GEN_CASE(ListPattern)
@ -351,7 +353,15 @@ namespace bolt {
static_cast<D*>(this)->visitPattern(N); static_cast<D*>(this)->visitPattern(N);
} }
void visitNamedPattern(NamedPattern* N) { void visitRecordPatternField(RecordPatternField* N) {
static_cast<D*>(this)->visitNode(N);
}
void visitNamedRecordPattern(NamedRecordPattern* N) {
static_cast<D*>(this)->visitPattern(N);
}
void visitNamedTuplePattern(NamedTuplePattern* N) {
static_cast<D*>(this)->visitPattern(N); static_cast<D*>(this)->visitPattern(N);
} }
@ -563,7 +573,9 @@ namespace bolt {
BOLT_GEN_CHILD_CASE(TupleTypeExpression) BOLT_GEN_CHILD_CASE(TupleTypeExpression)
BOLT_GEN_CHILD_CASE(BindPattern) BOLT_GEN_CHILD_CASE(BindPattern)
BOLT_GEN_CHILD_CASE(LiteralPattern) BOLT_GEN_CHILD_CASE(LiteralPattern)
BOLT_GEN_CHILD_CASE(NamedPattern) BOLT_GEN_CHILD_CASE(RecordPatternField)
BOLT_GEN_CHILD_CASE(NamedRecordPattern)
BOLT_GEN_CHILD_CASE(NamedTuplePattern)
BOLT_GEN_CHILD_CASE(TuplePattern) BOLT_GEN_CHILD_CASE(TuplePattern)
BOLT_GEN_CHILD_CASE(NestedPattern) BOLT_GEN_CHILD_CASE(NestedPattern)
BOLT_GEN_CHILD_CASE(ListPattern) BOLT_GEN_CHILD_CASE(ListPattern)
@ -810,7 +822,36 @@ namespace bolt {
BOLT_VISIT(N->Literal); BOLT_VISIT(N->Literal);
} }
void visitEachChild(NamedPattern* N) { void visitEachChild(RecordPatternField* N) {
BOLT_VISIT(N->Name);
if (N->Equals) {
BOLT_VISIT(N->Equals);
}
if (N->Pattern) {
BOLT_VISIT(N->Pattern);
}
}
void visitEachChild(NamedRecordPattern* N) {
for (auto [Name, Dot]: N->ModulePath) {
BOLT_VISIT(Name);
if (Dot) {
BOLT_VISIT(Dot);
}
}
BOLT_VISIT(N->Name);
BOLT_VISIT(N->LBrace);
for (auto [Field, Comma]: N->Fields) {
BOLT_VISIT(Field);
if (Comma) {
BOLT_VISIT(Comma);
}
}
BOLT_VISIT(N->LBrace);
BOLT_VISIT(N->RBrace);
}
void visitEachChild(NamedTuplePattern* N) {
BOLT_VISIT(N->Name); BOLT_VISIT(N->Name);
for (auto P: N->Patterns) { for (auto P: N->Patterns) {
BOLT_VISIT(P); BOLT_VISIT(P);

View file

@ -71,7 +71,8 @@ namespace bolt {
Token* expectToken(NodeKind Ty); Token* expectToken(NodeKind Ty);
std::vector<RecordDeclarationField*> parseRecordFields(); std::vector<RecordDeclarationField*> parseRecordDeclarationFields();
std::optional<std::vector<std::tuple<RecordPatternField*, Comma*>>> parseRecordPatternFields();
template<typename T> template<typename T>
T* expectToken() { T* expectToken() {
@ -97,7 +98,8 @@ namespace bolt {
std::vector<Annotation*> parseAnnotations(); std::vector<Annotation*> parseAnnotations();
void checkLineFoldEnd(); void checkLineFoldEnd();
void skipToLineFoldEnd(); void skipPastLineFoldEnd();
void skipToRBrace();
public: public:

View file

@ -3,6 +3,7 @@
#include "bolt/CST.hpp" #include "bolt/CST.hpp"
#include "bolt/CSTVisitor.hpp" #include "bolt/CSTVisitor.hpp"
#include <variant>
namespace bolt { namespace bolt {
@ -173,9 +174,21 @@ namespace bolt {
addSymbol(Y->Name->Text, Decl, SymbolKind::Var); addSymbol(Y->Name->Text, Decl, SymbolKind::Var);
break; break;
} }
case NodeKind::NamedPattern: case NodeKind::NamedRecordPattern:
{ {
auto Y = static_cast<NamedPattern*>(X); auto Y = static_cast<NamedRecordPattern*>(X);
for (auto [Field, Comma]: Y->Fields) {
if (Field->Pattern) {
visitPattern(Field->Pattern, Decl);
} else {
addSymbol(Field->Name->Text, Decl, SymbolKind::Var);
}
}
break;
}
case NodeKind::NamedTuplePattern:
{
auto Y = static_cast<NamedTuplePattern*>(X);
for (auto P: Y->Patterns) { for (auto P: Y->Patterns) {
visitPattern(P, Decl); visitPattern(P, Decl);
} }
@ -464,11 +477,36 @@ namespace bolt {
return Literal; return Literal;
} }
Token* NamedPattern::getFirstToken() const { Token* RecordPatternField::getFirstToken() const {
return Name; return Name;
} }
Token* NamedPattern::getLastToken() const { Token* RecordPatternField::getLastToken() const {
if (Pattern) {
return Pattern->getLastToken();
}
if (Equals) {
return Equals;
}
return Name;
}
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 {
return Name;
}
Token* NamedTuplePattern::getLastToken() const {
if (Patterns.size()) { if (Patterns.size()) {
return Patterns.back()->getLastToken(); return Patterns.back()->getLastToken();
} }

View file

@ -1113,13 +1113,13 @@ namespace bolt {
return Ty; return Ty;
} }
case NodeKind::NamedPattern: case NodeKind::NamedTuplePattern:
{ {
auto P = static_cast<NamedPattern*>(Pattern); auto P = static_cast<NamedTuplePattern*>(Pattern);
auto Scm = lookup(P->Name->getCanonicalText(), SymKind::Var); auto Scm = lookup(P->Name->getCanonicalText(), SymKind::Var);
std::vector<Type*> ParamTypes; std::vector<Type*> ElementTypes;
for (auto P2: P->Patterns) { for (auto P2: P->Patterns) {
ParamTypes.push_back(inferPattern(P2, Constraints, TVs)); ElementTypes.push_back(inferPattern(P2, Constraints, TVs));
} }
if (!Scm) { if (!Scm) {
DE.add<BindingNotFoundDiagnostic>(P->Name->getCanonicalText(), P->Name); DE.add<BindingNotFoundDiagnostic>(P->Name->getCanonicalText(), P->Name);
@ -1127,7 +1127,32 @@ namespace bolt {
} }
auto Ty = instantiate(Scm, P); auto Ty = instantiate(Scm, P);
auto RetTy = createTypeVar(); auto RetTy = createTypeVar();
makeEqual(Ty, Type::buildArrow(ParamTypes, RetTy), P); makeEqual(Ty, Type::buildArrow(ElementTypes, RetTy), P);
return RetTy;
}
case NodeKind::NamedRecordPattern:
{
auto P = static_cast<NamedRecordPattern*>(Pattern);
auto Scm = lookup(P->Name->getCanonicalText(), SymKind::Var);
if (Scm == nullptr) {
DE.add<BindingNotFoundDiagnostic>(P->Name->getCanonicalText(), P->Name);
return createTypeVar();
}
auto RecordTy = new Type(TNil());
for (auto [Field, Comma]: P->Fields) {
Type* FieldTy;
if (Field->Pattern) {
FieldTy = inferPattern(Field->Pattern, Constraints, TVs);
} else {
FieldTy = createTypeVar();
addBinding(Field->Name->getCanonicalText(), new Forall(TVs, Constraints, FieldTy), SymKind::Var);
}
RecordTy = new Type(TField(Field->Name->getCanonicalText(), new Type(TPresent(FieldTy)), RecordTy));
}
auto Ty = instantiate(Scm, P);
auto RetTy = createTypeVar();
makeEqual(Ty, new Type(TArrow(RecordTy, RetTy)), P);
return RetTy; return RetTy;
} }

View file

@ -89,7 +89,7 @@ namespace bolt {
return "a tuple type expression"; return "a tuple type expression";
case NodeKind::BindPattern: case NodeKind::BindPattern:
return "a variable binder"; return "a variable binder";
case NodeKind::NamedPattern: case NodeKind::NamedTuplePattern:
return "a pattern for a variant member"; return "a pattern for a variant member";
case NodeKind::TuplePattern: case NodeKind::TuplePattern:
return "a pattern for a tuple"; return "a pattern for a tuple";

View file

@ -150,6 +150,39 @@ finish:
return new ListPattern { LBracket, Elements, RBracket }; return new ListPattern { LBracket, Elements, RBracket };
} }
std::optional<std::vector<std::tuple<RecordPatternField*, Comma*>>> Parser::parseRecordPatternFields() {
std::vector<std::tuple<RecordPatternField*, Comma*>> Fields;
for (;;) {
auto T0 = Tokens.peek();
if (T0->getKind() == NodeKind::RBrace) {
break;
}
auto Name = expectToken<Identifier>();
Equals* Equals = nullptr;
Pattern* Pattern = nullptr;
auto T1 = Tokens.peek();
if (T1->getKind() == NodeKind::Equals) {
Tokens.get();
Equals = static_cast<class Equals*>(T1);
Pattern = parseWidePattern();
}
auto Field = new RecordPatternField(Name, Equals, Pattern);
auto T2 = Tokens.peek();
if (T2->getKind() == NodeKind::RBrace) {
Fields.push_back(std::make_tuple(Field, nullptr));
break;
}
if (T2->getKind() != NodeKind::Comma) {
DE.add<UnexpectedTokenDiagnostic>(File, T2, std::vector { NodeKind::RBrace, NodeKind::Comma });
return {};
}
Tokens.get();
auto Comma = static_cast<class Comma*>(T2);
Fields.push_back(std::make_tuple(Field, Comma));
}
return Fields;
}
Pattern* Parser::parsePrimitivePattern(bool IsNarrow) { Pattern* Parser::parsePrimitivePattern(bool IsNarrow) {
auto T0 = Tokens.peek(); auto T0 = Tokens.peek();
switch (T0->getKind()) { switch (T0->getKind()) {
@ -165,7 +198,19 @@ finish:
Tokens.get(); Tokens.get();
auto Name = static_cast<IdentifierAlt*>(T0); auto Name = static_cast<IdentifierAlt*>(T0);
if (IsNarrow) { if (IsNarrow) {
return new NamedPattern(Name, {}); return new NamedTuplePattern(Name, {});
}
auto T1 = Tokens.peek();
if (T1->getKind() == NodeKind::LBrace) {
auto LBrace = static_cast<class LBrace*>(T1);
Tokens.get();
auto Fields = parseRecordPatternFields();
if (!Fields) {
skipToRBrace();
return nullptr;
}
auto RBrace = static_cast<class RBrace*>(Tokens.get());
return new NamedRecordPattern({}, Name, LBrace, *Fields, RBrace);
} }
std::vector<Pattern*> Patterns; std::vector<Pattern*> Patterns;
for (;;) { for (;;) {
@ -190,7 +235,7 @@ finish:
} }
Patterns.push_back(P); Patterns.push_back(P);
} }
return new NamedPattern { Name, Patterns }; return new NamedTuplePattern { Name, Patterns };
} }
case NodeKind::LBracket: case NodeKind::LBracket:
return parseListPattern(); return parseListPattern();
@ -523,20 +568,20 @@ after_tuple_element:
} }
auto Pattern = parseWidePattern(); auto Pattern = parseWidePattern();
if (!Pattern) { if (!Pattern) {
skipToLineFoldEnd(); skipPastLineFoldEnd();
continue; continue;
} }
auto RArrowAlt = expectToken<class RArrowAlt>(); auto RArrowAlt = expectToken<class RArrowAlt>();
if (!RArrowAlt) { if (!RArrowAlt) {
Pattern->unref(); Pattern->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
continue; continue;
} }
auto Expression = parseExpression(); auto Expression = parseExpression();
if (!Expression) { if (!Expression) {
Pattern->unref(); Pattern->unref();
RArrowAlt->unref(); RArrowAlt->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
continue; continue;
} }
checkLineFoldEnd(); checkLineFoldEnd();
@ -853,7 +898,7 @@ finish:
ExpressionStatement* Parser::parseExpressionStatement() { ExpressionStatement* Parser::parseExpressionStatement() {
auto E = parseExpression(); auto E = parseExpression();
if (!E) { if (!E) {
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
checkLineFoldEnd(); checkLineFoldEnd();
@ -875,7 +920,7 @@ finish:
Expression = parseExpression(); Expression = parseExpression();
if (!Expression) { if (!Expression) {
ReturnKeyword->unref(); ReturnKeyword->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
checkLineFoldEnd(); checkLineFoldEnd();
@ -890,14 +935,14 @@ finish:
auto Test = parseExpression(); auto Test = parseExpression();
if (!Test) { if (!Test) {
IfKeyword->unref(); IfKeyword->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
auto T1 = expectToken<BlockStart>(); auto T1 = expectToken<BlockStart>();
if (!T1) { if (!T1) {
IfKeyword->unref(); IfKeyword->unref();
Test->unref(); Test->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
std::vector<Node*> Then; std::vector<Node*> Then;
@ -980,7 +1025,7 @@ finish:
if (Foreign) { if (Foreign) {
Foreign->unref(); Foreign->unref();
} }
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
Let = static_cast<LetKeyword*>(T0); Let = static_cast<LetKeyword*>(T0);
@ -1002,7 +1047,7 @@ finish:
if (Mut) { if (Mut) {
Mut->unref(); Mut->unref();
} }
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
@ -1034,7 +1079,7 @@ after_params:
if (TE) { if (TE) {
TA = new TypeAssert(static_cast<Colon*>(T2), TE); TA = new TypeAssert(static_cast<Colon*>(T2), TE);
} else { } else {
skipToLineFoldEnd(); skipPastLineFoldEnd();
goto finish; goto finish;
} }
T2 = Tokens.peek(); T2 = Tokens.peek();
@ -1064,7 +1109,7 @@ after_params:
Tokens.get(); Tokens.get();
auto E = parseExpression(); auto E = parseExpression();
if (!E) { if (!E) {
skipToLineFoldEnd(); skipPastLineFoldEnd();
goto finish; goto finish;
} }
Body = new LetExprBody(static_cast<Equals*>(T2), E); Body = new LetExprBody(static_cast<Equals*>(T2), E);
@ -1195,13 +1240,13 @@ after_vars:
InstanceDeclaration* Parser::parseInstanceDeclaration() { InstanceDeclaration* Parser::parseInstanceDeclaration() {
auto InstanceKeyword = expectToken<class InstanceKeyword>(); auto InstanceKeyword = expectToken<class InstanceKeyword>();
if (!InstanceKeyword) { if (!InstanceKeyword) {
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
auto Name = expectToken<IdentifierAlt>(); auto Name = expectToken<IdentifierAlt>();
if (!Name) { if (!Name) {
InstanceKeyword->unref(); InstanceKeyword->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
std::vector<TypeExpression*> TypeExps; std::vector<TypeExpression*> TypeExps;
@ -1217,7 +1262,7 @@ after_vars:
for (auto TE: TypeExps) { for (auto TE: TypeExps) {
TE->unref(); TE->unref();
} }
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
TypeExps.push_back(TE); TypeExps.push_back(TE);
@ -1229,7 +1274,7 @@ after_vars:
for (auto TE: TypeExps) { for (auto TE: TypeExps) {
TE->unref(); TE->unref();
} }
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
std::vector<Node*> Elements; std::vector<Node*> Elements;
@ -1266,7 +1311,7 @@ after_vars:
if (PubKeyword) { if (PubKeyword) {
PubKeyword->unref(); PubKeyword->unref();
} }
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
auto Name = expectToken<IdentifierAlt>(); auto Name = expectToken<IdentifierAlt>();
@ -1275,7 +1320,7 @@ after_vars:
PubKeyword->unref(); PubKeyword->unref();
} }
ClassKeyword->unref(); ClassKeyword->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
std::vector<VarTypeExpression*> TypeVars; std::vector<VarTypeExpression*> TypeVars;
@ -1293,7 +1338,7 @@ after_vars:
for (auto TV: TypeVars) { for (auto TV: TypeVars) {
TV->unref(); TV->unref();
} }
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
TypeVars.push_back(TE); TypeVars.push_back(TE);
@ -1307,7 +1352,7 @@ after_vars:
for (auto TV: TypeVars) { for (auto TV: TypeVars) {
TV->unref(); TV->unref();
} }
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
std::vector<Node*> Elements; std::vector<Node*> Elements;
@ -1333,7 +1378,7 @@ after_vars:
); );
} }
std::vector<RecordDeclarationField*> Parser::parseRecordFields() { std::vector<RecordDeclarationField*> Parser::parseRecordDeclarationFields() {
std::vector<RecordDeclarationField*> Fields; std::vector<RecordDeclarationField*> Fields;
for (;;) { for (;;) {
auto T1 = Tokens.peek(); auto T1 = Tokens.peek();
@ -1343,20 +1388,20 @@ after_vars:
} }
auto Name = expectToken<Identifier>(); auto Name = expectToken<Identifier>();
if (!Name) { if (!Name) {
skipToLineFoldEnd(); skipPastLineFoldEnd();
continue; continue;
} }
auto Colon = expectToken<class Colon>(); auto Colon = expectToken<class Colon>();
if (!Colon) { if (!Colon) {
Name->unref(); Name->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
continue; continue;
} }
auto TE = parseTypeExpression(); auto TE = parseTypeExpression();
if (!TE) { if (!TE) {
Name->unref(); Name->unref();
Colon->unref(); Colon->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
continue; continue;
} }
checkLineFoldEnd(); checkLineFoldEnd();
@ -1377,7 +1422,7 @@ after_vars:
if (Pub) { if (Pub) {
Pub->unref(); Pub->unref();
} }
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
auto Name = expectToken<IdentifierAlt>(); auto Name = expectToken<IdentifierAlt>();
@ -1386,7 +1431,7 @@ after_vars:
Pub->unref(); Pub->unref();
} }
Struct->unref(); Struct->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
std::vector<VarTypeExpression*> Vars; std::vector<VarTypeExpression*> Vars;
@ -1407,10 +1452,10 @@ after_vars:
} }
Struct->unref(); Struct->unref();
Name->unref(); Name->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
auto Fields = parseRecordFields(); auto Fields = parseRecordDeclarationFields();
Tokens.get()->unref(); // Always a LineFoldEnd Tokens.get()->unref(); // Always a LineFoldEnd
return new RecordDeclaration { Pub, Struct, Name, Vars, BS, Fields }; return new RecordDeclaration { Pub, Struct, Name, Vars, BS, Fields };
} }
@ -1427,7 +1472,7 @@ after_vars:
if (Pub) { if (Pub) {
Pub->unref(); Pub->unref();
} }
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
auto Name = expectToken<IdentifierAlt>(); auto Name = expectToken<IdentifierAlt>();
@ -1436,7 +1481,7 @@ after_vars:
Pub->unref(); Pub->unref();
} }
Enum->unref(); Enum->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
std::vector<VarTypeExpression*> TVs; std::vector<VarTypeExpression*> TVs;
@ -1457,7 +1502,7 @@ after_vars:
} }
Enum->unref(); Enum->unref();
Name->unref(); Name->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
std::vector<VariantDeclarationMember*> Members; std::vector<VariantDeclarationMember*> Members;
@ -1470,14 +1515,14 @@ next_member:
} }
auto Name = expectToken<IdentifierAlt>(); auto Name = expectToken<IdentifierAlt>();
if (!Name) { if (!Name) {
skipToLineFoldEnd(); skipPastLineFoldEnd();
continue; continue;
} }
auto T1 = Tokens.peek(); auto T1 = Tokens.peek();
if (T1->getKind() == NodeKind::BlockStart) { if (T1->getKind() == NodeKind::BlockStart) {
Tokens.get(); Tokens.get();
auto BS = static_cast<BlockStart*>(T1); auto BS = static_cast<BlockStart*>(T1);
auto Fields = parseRecordFields(); auto Fields = parseRecordDeclarationFields();
// TODO continue; on error in Fields // TODO continue; on error in Fields
Members.push_back(new RecordVariantDeclarationMember { Name, BS, Fields }); Members.push_back(new RecordVariantDeclarationMember { Name, BS, Fields });
} else { } else {
@ -1514,7 +1559,7 @@ next_member:
// TODO // TODO
default: default:
DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector<NodeKind> { NodeKind::LetKeyword, NodeKind::TypeKeyword }); DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector<NodeKind> { NodeKind::LetKeyword, NodeKind::TypeKeyword });
skipToLineFoldEnd(); skipPastLineFoldEnd();
return nullptr; return nullptr;
} }
} }
@ -1584,7 +1629,7 @@ next_member:
auto E = parseExpression(); auto E = parseExpression();
if (!E) { if (!E) {
At->unref(); At->unref();
skipToLineFoldEnd(); skipPastLineFoldEnd();
continue; continue;
} }
checkLineFoldEnd(); checkLineFoldEnd();
@ -1602,26 +1647,111 @@ next_annotation:;
return Annotations; return Annotations;
} }
void Parser::skipToLineFoldEnd() { void Parser::skipToRBrace() {
unsigned Level = 0; unsigned ParenLevel = 0;
unsigned BracketLevel = 0;
unsigned BraceLevel = 0;
unsigned BlockLevel = 0;
for (;;) {
auto T0 = Tokens.peek();
switch (T0->getKind()) {
case NodeKind::EndOfFile:
return;
case NodeKind::LineFoldEnd:
Tokens.get()->unref();
if (BlockLevel == 0 && ParenLevel == 0 && BracketLevel == 0 && BlockLevel == 0) {
return;
}
break;
case NodeKind::BlockStart:
Tokens.get()->unref();
BlockLevel++;
break;
case NodeKind::BlockEnd:
Tokens.get()->unref();
BlockLevel--;
break;
case NodeKind::LParen:
Tokens.get()->unref();
ParenLevel++;
break;
case NodeKind::LBracket:
Tokens.get()->unref();
BracketLevel++;
break;
case NodeKind::LBrace:
Tokens.get()->unref();
BraceLevel++;
break;
case NodeKind::RParen:
Tokens.get()->unref();
ParenLevel--;
break;
case NodeKind::RBracket:
Tokens.get()->unref();
BracketLevel--;
break;
case NodeKind::RBrace:
if (BlockLevel == 0 && ParenLevel == 0 && BracketLevel == 0 && BlockLevel == 0) {
return;
}
Tokens.get()->unref();
BraceLevel--;
break;
default:
Tokens.get()->unref();
break;
}
}
}
void Parser::skipPastLineFoldEnd() {
unsigned ParenLevel = 0;
unsigned BracketLevel = 0;
unsigned BraceLevel = 0;
unsigned BlockLevel = 0;
for (;;) { for (;;) {
auto T0 = Tokens.get(); auto T0 = Tokens.get();
switch (T0->getKind()) { switch (T0->getKind()) {
case NodeKind::EndOfFile: case NodeKind::EndOfFile:
return; return;
case NodeKind::LineFoldEnd: case NodeKind::LineFoldEnd:
T0->unref(); T0->unref();
if (Level == 0) { if (BlockLevel == 0 && ParenLevel == 0 && BracketLevel == 0 && BlockLevel == 0) {
return; return;
} }
break; break;
case NodeKind::BlockStart: case NodeKind::BlockStart:
T0->unref(); T0->unref();
Level++; BlockLevel++;
break; break;
case NodeKind::BlockEnd: case NodeKind::BlockEnd:
T0->unref(); T0->unref();
Level--; BlockLevel--;
break;
case NodeKind::LParen:
T0->unref();
ParenLevel++;
break;
case NodeKind::LBracket:
T0->unref();
BracketLevel++;
break;
case NodeKind::LBrace:
T0->unref();
BraceLevel++;
break;
case NodeKind::RParen:
T0->unref();
ParenLevel--;
break;
case NodeKind::RBracket:
T0->unref();
BracketLevel--;
break;
case NodeKind::RBrace:
T0->unref();
BraceLevel--;
break; break;
default: default:
T0->unref(); T0->unref();
@ -1636,7 +1766,7 @@ next_annotation:;
Tokens.get()->unref(); Tokens.get()->unref();
} else { } else {
DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector { NodeKind::LineFoldEnd }); DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector { NodeKind::LineFoldEnd });
skipToLineFoldEnd(); skipPastLineFoldEnd();
} }
} }