Some fixes and new pattern syntax
- Fix critical bug in deallocator - Add TuplePattern - Add ListPattern - Make Checker hold a ListType
This commit is contained in:
parent
fa294b826e
commit
717a2a663a
8 changed files with 264 additions and 40 deletions
|
@ -140,7 +140,9 @@ namespace bolt {
|
||||||
BindPattern,
|
BindPattern,
|
||||||
LiteralPattern,
|
LiteralPattern,
|
||||||
NamedPattern,
|
NamedPattern,
|
||||||
|
TuplePattern,
|
||||||
NestedPattern,
|
NestedPattern,
|
||||||
|
ListPattern,
|
||||||
ReferenceExpression,
|
ReferenceExpression,
|
||||||
MatchCase,
|
MatchCase,
|
||||||
MatchExpression,
|
MatchExpression,
|
||||||
|
@ -1244,6 +1246,27 @@ namespace bolt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TuplePattern : public Pattern {
|
||||||
|
public:
|
||||||
|
|
||||||
|
LParen* LParen;
|
||||||
|
std::vector<std::tuple<Pattern*, Comma*>> Elements;
|
||||||
|
RParen* RParen;
|
||||||
|
|
||||||
|
inline TuplePattern(
|
||||||
|
class LParen* LParen,
|
||||||
|
std::vector<std::tuple<Pattern*, Comma*>> Elements,
|
||||||
|
class RParen* RParen
|
||||||
|
): Pattern(NodeKind::TuplePattern),
|
||||||
|
LParen(LParen),
|
||||||
|
Elements(Elements),
|
||||||
|
RParen(RParen) {}
|
||||||
|
|
||||||
|
Token* getFirstToken() const override;
|
||||||
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class NestedPattern : public Pattern {
|
class NestedPattern : public Pattern {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -1265,6 +1288,28 @@ namespace bolt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ListPattern : public Pattern {
|
||||||
|
public:
|
||||||
|
|
||||||
|
class LBracket* LBracket;
|
||||||
|
std::vector<std::tuple<Pattern*, Comma*>> Elements;
|
||||||
|
class RBracket* RBracket;
|
||||||
|
|
||||||
|
inline ListPattern(
|
||||||
|
class LBracket* LBracket,
|
||||||
|
std::vector<std::tuple<Pattern*, Comma*>> Elements,
|
||||||
|
class RBracket* RBracket
|
||||||
|
): Pattern(NodeKind::ListPattern),
|
||||||
|
LBracket(LBracket),
|
||||||
|
Elements(Elements),
|
||||||
|
RBracket(RBracket) {}
|
||||||
|
|
||||||
|
Token* getFirstToken() const override;
|
||||||
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Expression : public TypedNode {
|
class Expression : public TypedNode {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,9 @@ namespace bolt {
|
||||||
BOLT_GEN_CASE(BindPattern)
|
BOLT_GEN_CASE(BindPattern)
|
||||||
BOLT_GEN_CASE(LiteralPattern)
|
BOLT_GEN_CASE(LiteralPattern)
|
||||||
BOLT_GEN_CASE(NamedPattern)
|
BOLT_GEN_CASE(NamedPattern)
|
||||||
|
BOLT_GEN_CASE(TuplePattern)
|
||||||
BOLT_GEN_CASE(NestedPattern)
|
BOLT_GEN_CASE(NestedPattern)
|
||||||
|
BOLT_GEN_CASE(ListPattern)
|
||||||
BOLT_GEN_CASE(ReferenceExpression)
|
BOLT_GEN_CASE(ReferenceExpression)
|
||||||
BOLT_GEN_CASE(MatchCase)
|
BOLT_GEN_CASE(MatchCase)
|
||||||
BOLT_GEN_CASE(MatchExpression)
|
BOLT_GEN_CASE(MatchExpression)
|
||||||
|
@ -334,10 +336,18 @@ namespace bolt {
|
||||||
visitPattern(N);
|
visitPattern(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitTuplePattern(TuplePattern* N) {
|
||||||
|
visitPattern(N);
|
||||||
|
}
|
||||||
|
|
||||||
void visitNestedPattern(NestedPattern* N) {
|
void visitNestedPattern(NestedPattern* N) {
|
||||||
visitPattern(N);
|
visitPattern(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitListPattern(ListPattern* N) {
|
||||||
|
visitPattern(N);
|
||||||
|
}
|
||||||
|
|
||||||
void visitExpression(Expression* N) {
|
void visitExpression(Expression* N) {
|
||||||
visitNode(N);
|
visitNode(N);
|
||||||
}
|
}
|
||||||
|
@ -536,7 +546,9 @@ namespace bolt {
|
||||||
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(NamedPattern)
|
||||||
|
BOLT_GEN_CHILD_CASE(TuplePattern)
|
||||||
BOLT_GEN_CHILD_CASE(NestedPattern)
|
BOLT_GEN_CHILD_CASE(NestedPattern)
|
||||||
|
BOLT_GEN_CHILD_CASE(ListPattern)
|
||||||
BOLT_GEN_CHILD_CASE(ReferenceExpression)
|
BOLT_GEN_CHILD_CASE(ReferenceExpression)
|
||||||
BOLT_GEN_CHILD_CASE(MatchCase)
|
BOLT_GEN_CHILD_CASE(MatchCase)
|
||||||
BOLT_GEN_CHILD_CASE(MatchExpression)
|
BOLT_GEN_CHILD_CASE(MatchExpression)
|
||||||
|
@ -774,12 +786,34 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitEachChild(TuplePattern* N) {
|
||||||
|
BOLT_VISIT(N->LParen);
|
||||||
|
for (auto [P, Comma]: N->Elements) {
|
||||||
|
BOLT_VISIT(P);
|
||||||
|
if (Comma) {
|
||||||
|
BOLT_VISIT(Comma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BOLT_VISIT(N->RParen);
|
||||||
|
}
|
||||||
|
|
||||||
void visitEachChild(NestedPattern* N) {
|
void visitEachChild(NestedPattern* N) {
|
||||||
BOLT_VISIT(N->LParen);
|
BOLT_VISIT(N->LParen);
|
||||||
BOLT_VISIT(N->P);
|
BOLT_VISIT(N->P);
|
||||||
BOLT_VISIT(N->RParen);
|
BOLT_VISIT(N->RParen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void visitEachChild(ListPattern* N) {
|
||||||
|
BOLT_VISIT(N->LBracket);
|
||||||
|
for (auto [Element, Separator]: N->Elements) {
|
||||||
|
BOLT_VISIT(Element);
|
||||||
|
if (Separator) {
|
||||||
|
BOLT_VISIT(Separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BOLT_VISIT(N->RBracket);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -175,6 +175,7 @@ namespace bolt {
|
||||||
size_t NextTypeVarId = 0;
|
size_t NextTypeVarId = 0;
|
||||||
|
|
||||||
Type* BoolType;
|
Type* BoolType;
|
||||||
|
Type* ListType;
|
||||||
Type* IntType;
|
Type* IntType;
|
||||||
Type* StringType;
|
Type* StringType;
|
||||||
|
|
||||||
|
|
|
@ -103,8 +103,10 @@ namespace bolt {
|
||||||
|
|
||||||
TypeExpression* parseTypeExpression();
|
TypeExpression* parseTypeExpression();
|
||||||
|
|
||||||
Pattern* parsePrimitivePattern();
|
ListPattern* parseListPattern();
|
||||||
Pattern* parsePattern();
|
Pattern* parsePrimitivePattern(bool IsNarrow);
|
||||||
|
Pattern* parseWidePattern();
|
||||||
|
Pattern* parseNarrowPattern();
|
||||||
|
|
||||||
Parameter* parseParam();
|
Parameter* parseParam();
|
||||||
|
|
||||||
|
|
34
src/CST.cc
34
src/CST.cc
|
@ -163,6 +163,22 @@ namespace bolt {
|
||||||
visitPattern(Y->P, Decl);
|
visitPattern(Y->P, Decl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
case NodeKind::LiteralPattern:
|
case NodeKind::LiteralPattern:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -278,8 +294,8 @@ namespace bolt {
|
||||||
struct UnrefVisitor : public CSTVisitor<UnrefVisitor> {
|
struct UnrefVisitor : public CSTVisitor<UnrefVisitor> {
|
||||||
|
|
||||||
void visit(Node* N) {
|
void visit(Node* N) {
|
||||||
N->unref();
|
|
||||||
visitEachChild(N);
|
visitEachChild(N);
|
||||||
|
N->unref();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -412,6 +428,14 @@ namespace bolt {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token* TuplePattern::getFirstToken() const {
|
||||||
|
return LParen;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token* TuplePattern::getLastToken() const {
|
||||||
|
return RParen;
|
||||||
|
}
|
||||||
|
|
||||||
Token* NestedPattern::getFirstToken() const {
|
Token* NestedPattern::getFirstToken() const {
|
||||||
return LParen;
|
return LParen;
|
||||||
}
|
}
|
||||||
|
@ -420,6 +444,14 @@ namespace bolt {
|
||||||
return RParen;
|
return RParen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token* ListPattern::getFirstToken() const {
|
||||||
|
return LBracket;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token* ListPattern::getLastToken() const {
|
||||||
|
return RBracket;
|
||||||
|
}
|
||||||
|
|
||||||
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());
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
// TODO Add a pattern that only performs a type assert
|
// TODO Add a pattern that only performs a type assert
|
||||||
|
|
||||||
|
// TODO create the constraint in addConstraint, not the other way round
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
@ -101,6 +103,7 @@ namespace bolt {
|
||||||
BoolType = createConType("Bool");
|
BoolType = createConType("Bool");
|
||||||
IntType = createConType("Int");
|
IntType = createConType("Int");
|
||||||
StringType = createConType("String");
|
StringType = createConType("String");
|
||||||
|
ListType = createConType("List");
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheme* Checker::lookup(ByteString Name) {
|
Scheme* Checker::lookup(ByteString Name) {
|
||||||
|
@ -1075,6 +1078,26 @@ namespace bolt {
|
||||||
return RetTy;
|
return RetTy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case NodeKind::TuplePattern:
|
||||||
|
{
|
||||||
|
auto P = static_cast<TuplePattern*>(Pattern);
|
||||||
|
std::vector<Type*> ElementTypes;
|
||||||
|
for (auto [Element, Comma]: P->Elements) {
|
||||||
|
ElementTypes.push_back(inferPattern(Element));
|
||||||
|
}
|
||||||
|
return new TTuple(ElementTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
case NodeKind::ListPattern:
|
||||||
|
{
|
||||||
|
auto P = static_cast<ListPattern*>(Pattern);
|
||||||
|
auto ElementType = createTypeVar();
|
||||||
|
for (auto [Element, Separator]: P->Elements) {
|
||||||
|
addConstraint(new CEqual(ElementType, inferPattern(Element), P));
|
||||||
|
}
|
||||||
|
return new TApp(ListType, ElementType);
|
||||||
|
}
|
||||||
|
|
||||||
case NodeKind::NestedPattern:
|
case NodeKind::NestedPattern:
|
||||||
{
|
{
|
||||||
auto P = static_cast<NestedPattern*>(Pattern);
|
auto P = static_cast<NestedPattern*>(Pattern);
|
||||||
|
@ -1292,6 +1315,7 @@ namespace bolt {
|
||||||
addBinding("String", new Forall(StringType));
|
addBinding("String", new Forall(StringType));
|
||||||
addBinding("Int", new Forall(IntType));
|
addBinding("Int", new Forall(IntType));
|
||||||
addBinding("Bool", new Forall(BoolType));
|
addBinding("Bool", new Forall(BoolType));
|
||||||
|
addBinding("List", new Forall(ListType));
|
||||||
addBinding("True", new Forall(BoolType));
|
addBinding("True", new Forall(BoolType));
|
||||||
addBinding("False", new Forall(BoolType));
|
addBinding("False", new Forall(BoolType));
|
||||||
auto A = createTypeVar();
|
auto A = createTypeVar();
|
||||||
|
|
|
@ -128,6 +128,8 @@ namespace bolt {
|
||||||
return "an if-statement";
|
return "an if-statement";
|
||||||
case NodeKind::IfStatementPart:
|
case NodeKind::IfStatementPart:
|
||||||
return "a branch of an if-statement";
|
return "a branch of an if-statement";
|
||||||
|
case NodeKind::ListPattern:
|
||||||
|
return "a list pattern";
|
||||||
default:
|
default:
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
158
src/Parser.cc
158
src/Parser.cc
|
@ -102,7 +102,49 @@ namespace bolt {
|
||||||
return T;
|
return T;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pattern* Parser::parsePrimitivePattern() {
|
ListPattern* Parser::parseListPattern() {
|
||||||
|
auto LBracket = expectToken<class LBracket>();
|
||||||
|
if (!LBracket) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::vector<std::tuple<Pattern*, Comma*>> Elements;
|
||||||
|
RBracket* RBracket;
|
||||||
|
auto T0 = Tokens.peek();
|
||||||
|
if (T0->getKind() == NodeKind::RBracket) {
|
||||||
|
Tokens.get();
|
||||||
|
RBracket = static_cast<class RBracket*>(T0);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
auto P = parseWidePattern();
|
||||||
|
if (!P) {
|
||||||
|
LBracket->unref();
|
||||||
|
for (auto [Element, Separator]: Elements) {
|
||||||
|
Element->unref();
|
||||||
|
Separator->unref();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto T1 = Tokens.peek();
|
||||||
|
switch (T1->getKind()) {
|
||||||
|
case NodeKind::Comma:
|
||||||
|
Tokens.get();
|
||||||
|
Elements.push_back(std::make_tuple(P, static_cast<Comma*>(T1)));
|
||||||
|
break;
|
||||||
|
case NodeKind::RBracket:
|
||||||
|
Tokens.get();
|
||||||
|
Elements.push_back(std::make_tuple(P, nullptr));
|
||||||
|
RBracket = static_cast<class RBracket*>(T1);
|
||||||
|
goto finish;
|
||||||
|
default:
|
||||||
|
DE.add<UnexpectedTokenDiagnostic>(File, T1, std::vector { NodeKind::Comma, NodeKind::RBracket });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finish:
|
||||||
|
return new ListPattern { LBracket, Elements, RBracket };
|
||||||
|
}
|
||||||
|
|
||||||
|
Pattern* Parser::parsePrimitivePattern(bool IsNarrow) {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
switch (T0->getKind()) {
|
switch (T0->getKind()) {
|
||||||
case NodeKind::StringLiteral:
|
case NodeKind::StringLiteral:
|
||||||
|
@ -113,60 +155,102 @@ namespace bolt {
|
||||||
Tokens.get();
|
Tokens.get();
|
||||||
return new BindPattern(static_cast<Identifier*>(T0));
|
return new BindPattern(static_cast<Identifier*>(T0));
|
||||||
case NodeKind::IdentifierAlt:
|
case NodeKind::IdentifierAlt:
|
||||||
|
{
|
||||||
Tokens.get();
|
Tokens.get();
|
||||||
return new NamedPattern(static_cast<IdentifierAlt*>(T0), {});
|
auto Name = static_cast<IdentifierAlt*>(T0);
|
||||||
|
if (IsNarrow) {
|
||||||
|
return new NamedPattern(Name, {});
|
||||||
|
}
|
||||||
|
std::vector<Pattern*> Patterns;
|
||||||
|
for (;;) {
|
||||||
|
auto T2 = Tokens.peek();
|
||||||
|
if (T2->getKind() == NodeKind::RParen
|
||||||
|
|| T2->getKind() == NodeKind::RBracket
|
||||||
|
|| T2->getKind() == NodeKind::RBrace
|
||||||
|
|| T2->getKind() == NodeKind::Comma
|
||||||
|
|| T2->getKind() == NodeKind::Colon
|
||||||
|
|| T2->getKind() == NodeKind::Equals
|
||||||
|
|| T2->getKind() == NodeKind::BlockStart
|
||||||
|
|| T2->getKind() == NodeKind::RArrowAlt) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto P = parseNarrowPattern();
|
||||||
|
if (!P) {
|
||||||
|
Name->unref();
|
||||||
|
for (auto P: Patterns) {
|
||||||
|
P->unref();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
Patterns.push_back(P);
|
||||||
|
}
|
||||||
|
return new NamedPattern { Name, Patterns };
|
||||||
|
}
|
||||||
|
case NodeKind::LBracket:
|
||||||
|
return parseListPattern();
|
||||||
case NodeKind::LParen:
|
case NodeKind::LParen:
|
||||||
{
|
{
|
||||||
Tokens.get();
|
Tokens.get();
|
||||||
auto LParen = static_cast<class LParen*>(T0);
|
auto LParen = static_cast<class LParen*>(T0);
|
||||||
auto T1 = Tokens.peek();
|
std::vector<std::tuple<Pattern*, Comma*>> Elements;
|
||||||
RParen* RParen;
|
RParen* RParen;
|
||||||
if (T1->getKind() == NodeKind::IdentifierAlt) {
|
for (;;) {
|
||||||
Tokens.get();
|
auto P = parseWidePattern();
|
||||||
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) {
|
if (!P) {
|
||||||
LParen->unref();
|
LParen->unref();
|
||||||
|
for (auto [P, Comma]: Elements) {
|
||||||
|
P->unref();
|
||||||
|
Comma->unref();
|
||||||
|
}
|
||||||
|
// TODO maybe skip to next comma?
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto RParen = expectToken<class RParen>();
|
auto T1 = Tokens.peek();
|
||||||
if (!RParen) {
|
if (T1->getKind() == NodeKind::Comma) {
|
||||||
|
Tokens.get();
|
||||||
|
Elements.push_back(std::make_tuple(P, static_cast<Comma*>(T1)));
|
||||||
|
} else if (T1->getKind() == NodeKind::RParen) {
|
||||||
|
Tokens.get();
|
||||||
|
RParen = static_cast<class RParen*>(T1);
|
||||||
|
Elements.push_back(std::make_tuple(P, nullptr));
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
DE.add<UnexpectedTokenDiagnostic>(File, T1, std::vector { NodeKind::Comma, NodeKind::RParen });
|
||||||
LParen->unref();
|
LParen->unref();
|
||||||
P->unref();
|
for (auto [P, Comma]: Elements) {
|
||||||
|
P->unref();
|
||||||
|
Comma->unref();
|
||||||
|
}
|
||||||
|
// TODO maybe skip to next comma?
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
return new NestedPattern { LParen, P, RParen };
|
|
||||||
}
|
}
|
||||||
|
if (Elements.size() == 1) {
|
||||||
|
return new NestedPattern { LParen, std::get<0>(Elements.front()), RParen };
|
||||||
|
}
|
||||||
|
return new TuplePattern(LParen, Elements, RParen);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// Tokens.get();
|
// Tokens.get();
|
||||||
DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector { NodeKind::Identifier, NodeKind::IdentifierAlt, NodeKind::StringLiteral, NodeKind::IntegerLiteral });
|
DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector {
|
||||||
|
NodeKind::Identifier,
|
||||||
|
NodeKind::IdentifierAlt,
|
||||||
|
NodeKind::StringLiteral,
|
||||||
|
NodeKind::IntegerLiteral,
|
||||||
|
NodeKind::LParen,
|
||||||
|
NodeKind::LBracket
|
||||||
|
});
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pattern* Parser::parsePattern() {
|
Pattern* Parser::parseWidePattern() {
|
||||||
return parsePrimitivePattern();
|
return parsePrimitivePattern(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pattern* Parser::parseNarrowPattern() {
|
||||||
|
return parsePrimitivePattern(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeExpression* Parser::parseTypeExpression() {
|
TypeExpression* Parser::parseTypeExpression() {
|
||||||
|
@ -431,7 +515,7 @@ after_tuple_element:
|
||||||
Tokens.get()->unref();
|
Tokens.get()->unref();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto Pattern = parsePattern();
|
auto Pattern = parseWidePattern();
|
||||||
if (!Pattern) {
|
if (!Pattern) {
|
||||||
skipToLineFoldEnd();
|
skipToLineFoldEnd();
|
||||||
continue;
|
continue;
|
||||||
|
@ -863,7 +947,7 @@ VariableDeclaration* Parser::parseVariableDeclaration() {
|
||||||
Tokens.get();
|
Tokens.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto P = parsePattern();
|
auto P = parseWidePattern();
|
||||||
if (!P) {
|
if (!P) {
|
||||||
if (Pub) {
|
if (Pub) {
|
||||||
Pub->unref();
|
Pub->unref();
|
||||||
|
@ -993,7 +1077,7 @@ finish:
|
||||||
case NodeKind::Colon:
|
case NodeKind::Colon:
|
||||||
goto after_params;
|
goto after_params;
|
||||||
default:
|
default:
|
||||||
auto P = parsePattern();
|
auto P = parseNarrowPattern();
|
||||||
if (!P) {
|
if (!P) {
|
||||||
Tokens.get();
|
Tokens.get();
|
||||||
P = new BindPattern(new Identifier("_"));
|
P = new BindPattern(new Identifier("_"));
|
||||||
|
|
Loading…
Reference in a new issue