From e386a7095bfd55873bb1f422f0a43dd64479d606 Mon Sep 17 00:00:00 2001 From: Sam Vervaeck Date: Wed, 10 Jul 2024 17:14:54 +0200 Subject: [PATCH] Adjust syntax to distinguish between variables and functions --- include/bolt/CST.hpp | 41 ++++--- include/bolt/CSTVisitor.hpp | 223 ++++++++++++++++++------------------ include/bolt/Checker.hpp | 2 +- include/bolt/Parser.hpp | 3 +- src/CST.cc | 15 +-- src/Checker.cc | 30 ++++- src/Parser.cc | 201 ++++++++++++++++++++++++-------- src/Scanner.cc | 3 + 8 files changed, 331 insertions(+), 187 deletions(-) diff --git a/include/bolt/CST.hpp b/include/bolt/CST.hpp index c01a9c96e..267c3e7e5 100644 --- a/include/bolt/CST.hpp +++ b/include/bolt/CST.hpp @@ -118,6 +118,7 @@ enum class NodeKind { ElifKeyword, ElseKeyword, EnumKeyword, + FnKeyword, ForeignKeyword, IfKeyword, InstanceKeyword, @@ -686,6 +687,18 @@ public: }; +class FnKeyword : public Token { +public: + + inline FnKeyword(TextLoc StartLoc): + Token(NodeKind::FnKeyword, StartLoc) {} + + std::string getText() const override; + + static constexpr const NodeKind Kind = NodeKind::FnKeyword; + +}; + class ClassKeyword : public Token { public: @@ -2424,7 +2437,7 @@ public: class PubKeyword* PubKeyword; class ForeignKeyword* ForeignKeyword; - class LetKeyword* LetKeyword; + class FnKeyword* FnKeyword; class Operator Name; Parameter* Param; class TypeAssert* TypeAssert; @@ -2434,7 +2447,7 @@ public: class std::vector Annotations, class PubKeyword* PubKeyword, class ForeignKeyword* ForeignKeyword, - class LetKeyword* LetKeyword, + class FnKeyword* FnKeyword, Operator Name, Parameter* Param, class TypeAssert* TypeAssert, @@ -2442,7 +2455,7 @@ public: ): FunctionDeclaration(NodeKind::PrefixFunctionDeclaration, Annotations), PubKeyword(PubKeyword), ForeignKeyword(ForeignKeyword), - LetKeyword(LetKeyword), + FnKeyword(FnKeyword), Name(Name), Param(Param), TypeAssert(TypeAssert), @@ -2484,7 +2497,7 @@ public: class PubKeyword* PubKeyword; class ForeignKeyword* ForeignKeyword; - class LetKeyword* LetKeyword; + class FnKeyword* FnKeyword; Parameter* Param; class Operator Name; class TypeAssert* TypeAssert; @@ -2494,7 +2507,7 @@ public: class std::vector Annotations, class PubKeyword* PubKeyword, class ForeignKeyword* ForeignKeyword, - class LetKeyword* LetKeyword, + class FnKeyword* FnKeyword, Parameter* Param, Operator Name, class TypeAssert* TypeAssert, @@ -2502,7 +2515,7 @@ public: ): FunctionDeclaration(NodeKind::SuffixFunctionDeclaration, Annotations), PubKeyword(PubKeyword), ForeignKeyword(ForeignKeyword), - LetKeyword(LetKeyword), + FnKeyword(FnKeyword), Name(Name), Param(Param), TypeAssert(TypeAssert), @@ -2544,7 +2557,7 @@ public: class PubKeyword* PubKeyword; class ForeignKeyword* ForeignKeyword; - class LetKeyword* LetKeyword; + class FnKeyword* FnKeyword; Parameter* Left; class Operator Name; Parameter* Right; @@ -2555,7 +2568,7 @@ public: class std::vector Annotations, class PubKeyword* PubKeyword, class ForeignKeyword* ForeignKeyword, - class LetKeyword* LetKeyword, + class FnKeyword* FnKeyword, Parameter* Left, class Operator Name, Parameter* Right, @@ -2564,7 +2577,7 @@ public: ): FunctionDeclaration(NodeKind::InfixFunctionDeclaration, Annotations), PubKeyword(PubKeyword), ForeignKeyword(ForeignKeyword), - LetKeyword(LetKeyword), + FnKeyword(FnKeyword), Left(Left), Name(Name), Right(Right), @@ -2607,7 +2620,7 @@ public: class PubKeyword* PubKeyword; class ForeignKeyword* ForeignKeyword; - class LetKeyword* LetKeyword; + class FnKeyword* FnKeyword; class Symbol Name; std::vector Params; class TypeAssert* TypeAssert; @@ -2617,7 +2630,7 @@ public: class std::vector Annotations, class PubKeyword* PubKeyword, class ForeignKeyword* ForeignKeyword, - class LetKeyword* LetKeyword, + class FnKeyword* FnKeyword, class Symbol Name, std::vector Params, class TypeAssert* TypeAssert, @@ -2625,7 +2638,7 @@ public: ): FunctionDeclaration(NodeKind::NamedFunctionDeclaration, Annotations), PubKeyword(PubKeyword), ForeignKeyword(ForeignKeyword), - LetKeyword(LetKeyword), + FnKeyword(FnKeyword), Name(Name), Params(Params), TypeAssert(TypeAssert), @@ -2665,18 +2678,15 @@ class VariableDeclaration : public Declaration { public: class PubKeyword* PubKeyword; - class ForeignKeyword* ForeignKeyword; class LetKeyword* LetKeyword; class MutKeyword* MutKeyword; class Pattern* Pattern; - std::vector Params; class TypeAssert* TypeAssert; LetBody* Body; VariableDeclaration( class std::vector Annotations, class PubKeyword* PubKeyword, - class ForeignKeyword* ForeignKeyword, class LetKeyword* LetKeyword, class MutKeyword* MutKeyword, class Pattern* Pattern, @@ -2684,7 +2694,6 @@ public: LetBody* Body ): Declaration(NodeKind::VariableDeclaration, Annotations), PubKeyword(PubKeyword), - ForeignKeyword(ForeignKeyword), LetKeyword(LetKeyword), MutKeyword(MutKeyword), Pattern(Pattern), diff --git a/include/bolt/CSTVisitor.hpp b/include/bolt/CSTVisitor.hpp index 8fcfe9bc5..462943f23 100644 --- a/include/bolt/CSTVisitor.hpp +++ b/include/bolt/CSTVisitor.hpp @@ -46,6 +46,7 @@ public: BOLT_GEN_CASE(ModKeyword) BOLT_GEN_CASE(StructKeyword) BOLT_GEN_CASE(EnumKeyword) + BOLT_GEN_CASE(FnKeyword) BOLT_GEN_CASE(ClassKeyword) BOLT_GEN_CASE(InstanceKeyword) BOLT_GEN_CASE(ElifKeyword) @@ -265,6 +266,10 @@ protected: static_cast(this)->visitToken(N); } + void visitFnKeyword(FnKeyword* N) { + static_cast(this)->visitToken(N); + } + void visitClassKeyword(ClassKeyword* N) { static_cast(this)->visitToken(N); } @@ -595,7 +600,7 @@ public: #define BOLT_GEN_CHILD_CASE(name) \ case NodeKind::name: \ - visitEachChild(static_cast(N)); \ + visitEachChildImpl(static_cast(N)); \ break; switch (N->getKind()) { @@ -625,6 +630,7 @@ public: BOLT_GEN_CHILD_CASE(ModKeyword) BOLT_GEN_CHILD_CASE(StructKeyword) BOLT_GEN_CHILD_CASE(EnumKeyword) + BOLT_GEN_CHILD_CASE(FnKeyword) BOLT_GEN_CHILD_CASE(ClassKeyword) BOLT_GEN_CHILD_CASE(InstanceKeyword) BOLT_GEN_CHILD_CASE(ElifKeyword) @@ -701,172 +707,175 @@ public: } } - void visitEachChild(VBar* N) { + void visitEachChildImpl(VBar* N) { } - void visitEachChild(Equals* N) { + void visitEachChildImpl(Equals* N) { } - void visitEachChild(Colon* N) { + void visitEachChildImpl(Colon* N) { } - void visitEachChild(Comma* N) { + void visitEachChildImpl(Comma* N) { } - void visitEachChild(Dot* N) { + void visitEachChildImpl(Dot* N) { } - void visitEachChild(DotDot* N) { + void visitEachChildImpl(DotDot* N) { } - void visitEachChild(Tilde* N) { + void visitEachChildImpl(Tilde* N) { } - void visitEachChild(At* N) { + void visitEachChildImpl(At* N) { } - void visitEachChild(DoKeyword* N) { + void visitEachChildImpl(DoKeyword* N) { } - void visitEachChild(LParen* N) { + void visitEachChildImpl(LParen* N) { } - void visitEachChild(RParen* N) { + void visitEachChildImpl(RParen* N) { } - void visitEachChild(LBracket* N) { + void visitEachChildImpl(LBracket* N) { } - void visitEachChild(RBracket* N) { + void visitEachChildImpl(RBracket* N) { } - void visitEachChild(LBrace* N) { + void visitEachChildImpl(LBrace* N) { } - void visitEachChild(RBrace* N) { + void visitEachChildImpl(RBrace* N) { } - void visitEachChild(RArrow* N) { + void visitEachChildImpl(RArrow* N) { } - void visitEachChild(RArrowAlt* N) { + void visitEachChildImpl(RArrowAlt* N) { } - void visitEachChild(LetKeyword* N) { + void visitEachChildImpl(LetKeyword* N) { } - void visitEachChild(ForeignKeyword* N) { + void visitEachChildImpl(ForeignKeyword* N) { } - void visitEachChild(MutKeyword* N) { + void visitEachChildImpl(MutKeyword* N) { } - void visitEachChild(PubKeyword* N) { + void visitEachChildImpl(PubKeyword* N) { } - void visitEachChild(TypeKeyword* N) { + void visitEachChildImpl(TypeKeyword* N) { } - void visitEachChild(ReturnKeyword* N) { + void visitEachChildImpl(ReturnKeyword* N) { } - void visitEachChild(ModKeyword* N) { + void visitEachChildImpl(ModKeyword* N) { } - void visitEachChild(StructKeyword* N) { + void visitEachChildImpl(StructKeyword* N) { } - void visitEachChild(EnumKeyword* N) { + void visitEachChildImpl(EnumKeyword* N) { } - void visitEachChild(ClassKeyword* N) { + void visitEachChildImpl(FnKeyword* N) { } - void visitEachChild(InstanceKeyword* N) { + void visitEachChildImpl(ClassKeyword* N) { } - void visitEachChild(ElifKeyword* N) { + void visitEachChildImpl(InstanceKeyword* N) { } - void visitEachChild(IfKeyword* N) { + void visitEachChildImpl(ElifKeyword* N) { } - void visitEachChild(ElseKeyword* N) { + void visitEachChildImpl(IfKeyword* N) { } - void visitEachChild(MatchKeyword* N) { + void visitEachChildImpl(ElseKeyword* N) { } - void visitEachChild(Invalid* N) { + void visitEachChildImpl(MatchKeyword* N) { } - void visitEachChild(EndOfFile* N) { + void visitEachChildImpl(Invalid* N) { } - void visitEachChild(BlockStart* N) { + void visitEachChildImpl(EndOfFile* N) { } - void visitEachChild(BlockEnd* N) { + void visitEachChildImpl(BlockStart* N) { } - void visitEachChild(LineFoldEnd* N) { + void visitEachChildImpl(BlockEnd* N) { } - void visitEachChild(CustomOperator* N) { + void visitEachChildImpl(LineFoldEnd* N) { } - void visitEachChild(Assignment* N) { + void visitEachChildImpl(CustomOperator* N) { } - void visitEachChild(Identifier* N) { + void visitEachChildImpl(Assignment* N) { } - void visitEachChild(IdentifierAlt* N) { + void visitEachChildImpl(Identifier* N) { } - void visitEachChild(StringLiteral* N) { + void visitEachChildImpl(IdentifierAlt* N) { } - void visitEachChild(IntegerLiteral* N) { + void visitEachChildImpl(StringLiteral* N) { } - void visitEachChild(WrappedOperator* N) { + void visitEachChildImpl(IntegerLiteral* N) { + } + + void visitEachChildImpl(WrappedOperator* N) { BOLT_VISIT(N->LParen); BOLT_VISIT_OPERATOR(N->Op); BOLT_VISIT(N->RParen); } - void visitEachChild(ExpressionAnnotation* N) { + void visitEachChildImpl(ExpressionAnnotation* N) { BOLT_VISIT(N->At); BOLT_VISIT(N->Expression); } - void visitEachChild(TypeAssertAnnotation* N) { + void visitEachChildImpl(TypeAssertAnnotation* N) { BOLT_VISIT(N->At); BOLT_VISIT(N->Colon); BOLT_VISIT(N->TE); } - void visitEachChild(TypeclassConstraintExpression* N) { + void visitEachChildImpl(TypeclassConstraintExpression* N) { BOLT_VISIT(N->Name); for (auto TE: N->TEs) { BOLT_VISIT(TE); } } - void visitEachChild(EqualityConstraintExpression* N) { + void visitEachChildImpl(EqualityConstraintExpression* N) { BOLT_VISIT(N->Left); BOLT_VISIT(N->Tilde); BOLT_VISIT(N->Right); } - void visitEachChild(RecordTypeExpressionField* N) { + void visitEachChildImpl(RecordTypeExpressionField* N) { BOLT_VISIT(N->Name); BOLT_VISIT(N->Colon); BOLT_VISIT(N->TE); } - void visitEachChild(RecordTypeExpression* N) { + void visitEachChildImpl(RecordTypeExpression* N) { BOLT_VISIT(N->LBrace); for (auto [Field, Comma]: N->Fields) { BOLT_VISIT(Field); @@ -883,7 +892,7 @@ public: BOLT_VISIT(N->RBrace); } - void visitEachChild(QualifiedTypeExpression* N) { + void visitEachChildImpl(QualifiedTypeExpression* N) { for (auto [CE, Comma]: N->Constraints) { BOLT_VISIT(CE); if (Comma) { @@ -894,7 +903,7 @@ public: BOLT_VISIT(N->TE); } - void visitEachChild(ReferenceTypeExpression* N) { + void visitEachChildImpl(ReferenceTypeExpression* N) { for (auto [Name, Dot]: N->ModulePath) { BOLT_VISIT(Name); BOLT_VISIT(Dot); @@ -902,31 +911,31 @@ public: BOLT_VISIT(N->Name); } - void visitEachChild(ArrowTypeExpression* N) { + void visitEachChildImpl(ArrowTypeExpression* N) { for (auto PT: N->ParamTypes) { BOLT_VISIT(PT); } BOLT_VISIT(N->ReturnType); } - void visitEachChild(AppTypeExpression* N) { + void visitEachChildImpl(AppTypeExpression* N) { BOLT_VISIT(N->Op); for (auto Arg: N->Args) { BOLT_VISIT(Arg); } } - void visitEachChild(VarTypeExpression* N) { + void visitEachChildImpl(VarTypeExpression* N) { BOLT_VISIT(N->Name); } - void visitEachChild(NestedTypeExpression* N) { + void visitEachChildImpl(NestedTypeExpression* N) { BOLT_VISIT(N->LParen); BOLT_VISIT(N->TE); BOLT_VISIT(N->RParen); } - void visitEachChild(TupleTypeExpression* N) { + void visitEachChildImpl(TupleTypeExpression* N) { BOLT_VISIT(N->LParen); for (auto [TE, Comma]: N->Elements) { if (Comma) { @@ -937,15 +946,15 @@ public: BOLT_VISIT(N->RParen); } - void visitEachChild(BindPattern* N) { + void visitEachChildImpl(BindPattern* N) { BOLT_VISIT(N->Name); } - void visitEachChild(LiteralPattern* N) { + void visitEachChildImpl(LiteralPattern* N) { BOLT_VISIT(N->Literal); } - void visitEachChild(RecordPatternField* N) { + void visitEachChildImpl(RecordPatternField* N) { if (N->DotDot) { BOLT_VISIT(N->DotDot); } @@ -960,7 +969,7 @@ public: } } - void visitEachChild(RecordPattern* N) { + void visitEachChildImpl(RecordPattern* N) { BOLT_VISIT(N->LBrace); for (auto [Field, Comma]: N->Fields) { BOLT_VISIT(Field); @@ -971,7 +980,7 @@ public: BOLT_VISIT(N->RBrace); } - void visitEachChild(NamedRecordPattern* N) { + void visitEachChildImpl(NamedRecordPattern* N) { for (auto [Name, Dot]: N->ModulePath) { BOLT_VISIT(Name); if (Dot) { @@ -990,14 +999,14 @@ public: BOLT_VISIT(N->RBrace); } - void visitEachChild(NamedTuplePattern* N) { + void visitEachChildImpl(NamedTuplePattern* N) { BOLT_VISIT(N->Name); for (auto P: N->Patterns) { BOLT_VISIT(P); } } - void visitEachChild(TuplePattern* N) { + void visitEachChildImpl(TuplePattern* N) { BOLT_VISIT(N->LParen); for (auto [P, Comma]: N->Elements) { BOLT_VISIT(P); @@ -1008,13 +1017,13 @@ public: BOLT_VISIT(N->RParen); } - void visitEachChild(NestedPattern* N) { + void visitEachChildImpl(NestedPattern* N) { BOLT_VISIT(N->LParen); BOLT_VISIT(N->P); BOLT_VISIT(N->RParen); } - void visitEachChild(ListPattern* N) { + void visitEachChildImpl(ListPattern* N) { BOLT_VISIT(N->LBracket); for (auto [Element, Separator]: N->Elements) { BOLT_VISIT(Element); @@ -1025,7 +1034,7 @@ public: BOLT_VISIT(N->RBracket); } - void visitEachChild(ReferenceExpression* N) { + void visitEachChildImpl(ReferenceExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1036,13 +1045,13 @@ public: BOLT_VISIT_SYMBOL(N->Name); } - void visitEachChild(MatchCase* N) { + void visitEachChildImpl(MatchCase* N) { BOLT_VISIT(N->Pattern); BOLT_VISIT(N->RArrowAlt); BOLT_VISIT(N->Expression); } - void visitEachChild(MatchExpression* N) { + void visitEachChildImpl(MatchExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1056,7 +1065,7 @@ public: } } - void visitEachChild(BlockExpression* N) { + void visitEachChildImpl(BlockExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1067,7 +1076,7 @@ public: } } - void visitEachChild(MemberExpression* N) { + void visitEachChildImpl(MemberExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1076,7 +1085,7 @@ public: BOLT_VISIT(N->Name); } - void visitEachChild(TupleExpression* N) { + void visitEachChildImpl(TupleExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1090,7 +1099,7 @@ public: BOLT_VISIT(N->RParen); } - void visitEachChild(NestedExpression* N) { + void visitEachChildImpl(NestedExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1099,14 +1108,14 @@ public: BOLT_VISIT(N->RParen); } - void visitEachChild(LiteralExpression* N) { + void visitEachChildImpl(LiteralExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } BOLT_VISIT(N->Token); } - void visitEachChild(CallExpression* N) { + void visitEachChildImpl(CallExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1116,7 +1125,7 @@ public: } } - void visitEachChild(InfixExpression* N) { + void visitEachChildImpl(InfixExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1125,7 +1134,7 @@ public: BOLT_VISIT(N->Right); } - void visitEachChild(PrefixExpression* N) { + void visitEachChildImpl(PrefixExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1133,13 +1142,13 @@ public: BOLT_VISIT(N->Argument); } - void visitEachChild(RecordExpressionField* N) { + void visitEachChildImpl(RecordExpressionField* N) { BOLT_VISIT(N->Name); BOLT_VISIT(N->Equals); BOLT_VISIT(N->E); } - void visitEachChild(RecordExpression* N) { + void visitEachChildImpl(RecordExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1153,7 +1162,7 @@ public: BOLT_VISIT(N->RBrace); } - void visitEachChild(ReturnExpression* N) { + void visitEachChildImpl(ReturnExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1161,13 +1170,13 @@ public: BOLT_VISIT(N->E); } - void visitEachChild(IfExpression* N) { + void visitEachChildImpl(IfExpression* N) { for (auto Part: N->Parts) { BOLT_VISIT(Part); } } - void visitEachChild(IfExpressionPart* N) { + void visitEachChildImpl(IfExpressionPart* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1181,31 +1190,31 @@ public: } } - void visitEachChild(TypeAssert* N) { + void visitEachChildImpl(TypeAssert* N) { BOLT_VISIT(N->Colon); BOLT_VISIT(N->TypeExpression); } - void visitEachChild(Parameter* N) { + void visitEachChildImpl(Parameter* N) { BOLT_VISIT(N->Pattern); if (N->TypeAssert != nullptr) { BOLT_VISIT(N->TypeAssert); } } - void visitEachChild(LetBlockBody* N) { + void visitEachChildImpl(LetBlockBody* N) { BOLT_VISIT(N->BlockStart); for (auto Element: N->Elements) { BOLT_VISIT(Element); } } - void visitEachChild(LetExprBody* N) { + void visitEachChildImpl(LetExprBody* N) { BOLT_VISIT(N->Equals); BOLT_VISIT(N->Expression); } - void visitEachChild(PrefixFunctionDeclaration* N) { + void visitEachChildImpl(PrefixFunctionDeclaration* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1215,7 +1224,7 @@ public: if (N->ForeignKeyword) { BOLT_VISIT(N->ForeignKeyword); } - BOLT_VISIT(N->LetKeyword); + BOLT_VISIT(N->FnKeyword); BOLT_VISIT(N->Param); BOLT_VISIT_OPERATOR(N->Name); if (N->TypeAssert) { @@ -1226,7 +1235,7 @@ public: } } - void visitEachChild(InfixFunctionDeclaration* N) { + void visitEachChildImpl(InfixFunctionDeclaration* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1236,7 +1245,7 @@ public: if (N->ForeignKeyword) { BOLT_VISIT(N->ForeignKeyword); } - BOLT_VISIT(N->LetKeyword); + BOLT_VISIT(N->FnKeyword); BOLT_VISIT(N->Left); BOLT_VISIT_OPERATOR(N->Name); BOLT_VISIT(N->Right); @@ -1248,7 +1257,7 @@ public: } } - void visitEachChild(SuffixFunctionDeclaration* N) { + void visitEachChildImpl(SuffixFunctionDeclaration* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1258,7 +1267,7 @@ public: if (N->ForeignKeyword) { BOLT_VISIT(N->ForeignKeyword); } - BOLT_VISIT(N->LetKeyword); + BOLT_VISIT(N->FnKeyword); BOLT_VISIT_OPERATOR(N->Name); BOLT_VISIT(N->Param); if (N->TypeAssert) { @@ -1269,7 +1278,7 @@ public: } } - void visitEachChild(NamedFunctionDeclaration* N) { + void visitEachChildImpl(NamedFunctionDeclaration* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1279,7 +1288,7 @@ public: if (N->ForeignKeyword) { BOLT_VISIT(N->ForeignKeyword); } - BOLT_VISIT(N->LetKeyword); + BOLT_VISIT(N->FnKeyword); BOLT_VISIT_SYMBOL(N->Name); for (auto Param: N->Params) { BOLT_VISIT(Param); @@ -1292,24 +1301,18 @@ public: } } - void visitEachChild(VariableDeclaration* N) { + void visitEachChildImpl(VariableDeclaration* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } if (N->PubKeyword) { BOLT_VISIT(N->PubKeyword); } - if (N->ForeignKeyword) { - BOLT_VISIT(N->ForeignKeyword); - } BOLT_VISIT(N->LetKeyword); if (N->MutKeyword) { BOLT_VISIT(N->MutKeyword); } BOLT_VISIT(N->Pattern); - for (auto Param: N->Params) { - BOLT_VISIT(Param); - } if (N->TypeAssert) { BOLT_VISIT(N->TypeAssert); } @@ -1318,13 +1321,13 @@ public: } } - void visitEachChild(RecordDeclarationField* N) { + void visitEachChildImpl(RecordDeclarationField* N) { BOLT_VISIT(N->Name); BOLT_VISIT(N->Colon); BOLT_VISIT(N->TypeExpression); } - void visitEachChild(RecordDeclaration* N) { + void visitEachChildImpl(RecordDeclaration* N) { if (N->PubKeyword) { BOLT_VISIT(N->PubKeyword); } @@ -1336,7 +1339,7 @@ public: } } - void visitEachChild(VariantDeclaration* N) { + void visitEachChildImpl(VariantDeclaration* N) { if (N->PubKeyword) { BOLT_VISIT(N->PubKeyword); } @@ -1351,14 +1354,14 @@ public: } } - void visitEachChild(TupleVariantDeclarationMember* N) { + void visitEachChildImpl(TupleVariantDeclarationMember* N) { BOLT_VISIT(N->Name); for (auto Element: N->Elements) { BOLT_VISIT(Element); } } - void visitEachChild(RecordVariantDeclarationMember* N) { + void visitEachChildImpl(RecordVariantDeclarationMember* N) { BOLT_VISIT(N->Name); BOLT_VISIT(N->BlockStart); for (auto Field: N->Fields) { @@ -1366,7 +1369,7 @@ public: } } - void visitEachChild(ClassDeclaration* N) { + void visitEachChildImpl(ClassDeclaration* N) { if (N->PubKeyword) { BOLT_VISIT(N->PubKeyword); } @@ -1381,7 +1384,7 @@ public: } } - void visitEachChild(InstanceDeclaration* N) { + void visitEachChildImpl(InstanceDeclaration* N) { BOLT_VISIT(N->InstanceKeyword); BOLT_VISIT(N->Name); for (auto TE: N->TypeExps) { @@ -1393,7 +1396,7 @@ public: } } - void visitEachChild(SourceFile* N) { + void visitEachChildImpl(SourceFile* N) { for (auto Element: N->Elements) { BOLT_VISIT(Element); } diff --git a/include/bolt/Checker.hpp b/include/bolt/Checker.hpp index d2a73e403..4d59b0069 100644 --- a/include/bolt/Checker.hpp +++ b/include/bolt/Checker.hpp @@ -123,7 +123,7 @@ public: ConstraintSet inferFunctionDeclaration(TypeEnv& Env, FunctionDeclaration* D); - ConstraintSet inferVariableDeclaration(TypeEnv& Env, VariableDeclaration* Decl); + ConstraintSet inferVariableDeclaration(TypeEnv& Env, VariableDeclaration* Decl, Type* RetTy); ConstraintSet inferMany(TypeEnv& Env, std::vector& N, Type* RetTy); diff --git a/include/bolt/Parser.hpp b/include/bolt/Parser.hpp index 5adc3791d..29884e868 100644 --- a/include/bolt/Parser.hpp +++ b/include/bolt/Parser.hpp @@ -125,7 +125,8 @@ public: Node* parseLetBodyElement(); - Node* parseLetDeclaration(); + FunctionDeclaration* parseFunctionDeclaration(); + VariableDeclaration* parseVariableDeclaration(); Node* parseClassElement(); diff --git a/src/CST.cc b/src/CST.cc index f8fc9db60..919fdf5f1 100644 --- a/src/CST.cc +++ b/src/CST.cc @@ -585,7 +585,7 @@ Token* PrefixFunctionDeclaration::getFirstToken() const { if (ForeignKeyword) { return ForeignKeyword; } - return LetKeyword; + return FnKeyword; } Token* PrefixFunctionDeclaration::getLastToken() const { @@ -605,7 +605,7 @@ Token* InfixFunctionDeclaration::getFirstToken() const { if (ForeignKeyword) { return ForeignKeyword; } - return LetKeyword; + return FnKeyword; } Token* InfixFunctionDeclaration::getLastToken() const { @@ -625,7 +625,7 @@ Token* SuffixFunctionDeclaration::getFirstToken() const { if (ForeignKeyword) { return ForeignKeyword; } - return LetKeyword; + return FnKeyword; } Token* SuffixFunctionDeclaration::getLastToken() const { @@ -645,7 +645,7 @@ Token* NamedFunctionDeclaration::getFirstToken() const { if (ForeignKeyword) { return ForeignKeyword; } - return LetKeyword; + return FnKeyword; } Token* NamedFunctionDeclaration::getLastToken() const { @@ -665,9 +665,6 @@ Token* VariableDeclaration::getFirstToken() const { if (PubKeyword) { return PubKeyword; } - if (ForeignKeyword) { - return ForeignKeyword; - } return LetKeyword; } @@ -882,6 +879,10 @@ std::string EnumKeyword::getText() const { return "enum"; } +std::string FnKeyword::getText() const { + return "fn"; +} + std::string Invalid::getText() const { return ""; } diff --git a/src/Checker.cc b/src/Checker.cc index 28298060e..f917e6fc4 100644 --- a/src/Checker.cc +++ b/src/Checker.cc @@ -305,9 +305,33 @@ ConstraintSet Checker::inferFunctionDeclaration(TypeEnv& Env, FunctionDeclaratio return Out; } -ConstraintSet Checker::inferVariableDeclaration(TypeEnv& Env, VariableDeclaration* Decl) { +ConstraintSet Checker::inferVariableDeclaration(TypeEnv& Env, VariableDeclaration* Decl, Type* RetTy) { + ConstraintSet Out; - // TODO + + Type* Ty = nullptr; + + if (Decl->TypeAssert != nullptr) { + auto [AssertOut, AssertTy] = inferTypeExpr(Env, Decl->TypeAssert->TypeExpression); + mergeTo(Out, AssertOut); + Ty = AssertTy; + } + + if (Decl->Body != nullptr) { + // TODO elminate BlockBody and replace with BlockExpr + ZEN_ASSERT(Decl->Body->getKind() == NodeKind::LetExprBody); + auto [BodyOut, BodyTy] = inferExpr(Env, cast(Decl->Body)->Expression, RetTy); + mergeTo(Out, BodyOut); + if (Ty == nullptr) { + Ty = BodyTy; + } else { + Out.push_back(new CTypesEqual(Ty, BodyTy, Decl->Body)); + } + } + + // Currently we don't perform generalisation on variable declarations + Env.add(Decl->getNameAsString(), Ty, SymbolKind::Var); + return Out; } @@ -415,7 +439,7 @@ ConstraintSet Checker::inferMany(TypeEnv& Env, std::vector& Elements, Typ if (isa(N)) { mergeTo(Out, inferFunctionDeclaration(Env, static_cast(N))); } else if (isa(N)) { - mergeTo(Out, inferVariableDeclaration(Env, static_cast(N))); + mergeTo(Out, inferVariableDeclaration(Env, static_cast(N), RetTy)); } else { ZEN_UNREACHABLE } diff --git a/src/Parser.cc b/src/Parser.cc index 83e8ceb71..af0007160 100644 --- a/src/Parser.cc +++ b/src/Parser.cc @@ -1186,21 +1186,20 @@ IfExpression* Parser::parseIfExpression() { return new IfExpression(Parts); } -enum class LetMode { +enum class FnMode { Prefix, Infix, Suffix, Wrapped, - VarOrNamed, + Named, }; -Node* Parser::parseLetDeclaration() { +FunctionDeclaration* Parser::parseFunctionDeclaration() { auto Annotations = parseAnnotations(); PubKeyword* Pub = nullptr; ForeignKeyword* Foreign = nullptr; - LetKeyword* Let; - MutKeyword* Mut = nullptr; + FnKeyword* Fn; Operator Op; Symbol Sym; Pattern* Name; @@ -1210,7 +1209,7 @@ Node* Parser::parseLetDeclaration() { std::vector Params; TypeAssert* TA = nullptr; LetBody* Body = nullptr; - LetMode Mode; + FnMode Mode; auto T0 = Tokens.get(); if (T0->getKind() == NodeKind::PubKeyword) { @@ -1221,8 +1220,8 @@ Node* Parser::parseLetDeclaration() { Foreign = static_cast(T0); T0 = Tokens.get(); } - if (T0->getKind() != NodeKind::LetKeyword) { - DE.add(File, T0, std::vector { NodeKind::LetKeyword }); + if (T0->getKind() != NodeKind::FnKeyword) { + DE.add(File, T0, std::vector { NodeKind::FnKeyword }); if (Pub) { Pub->unref(); } @@ -1232,12 +1231,7 @@ Node* Parser::parseLetDeclaration() { skipPastLineFoldEnd(); return nullptr; } - Let = static_cast(T0); - auto T1 = Tokens.peek(); - if (T1->getKind() == NodeKind::MutKeyword) { - Tokens.get(); - Mut = static_cast(T1); - } + Fn = static_cast(T0); auto T2 = Tokens.peek(0); auto T3 = Tokens.peek(1); @@ -1248,7 +1242,7 @@ Node* Parser::parseLetDeclaration() { auto P1 = parseNarrowPattern(); Param = new Parameter(P1, nullptr); Op = Operator::from_raw_node(T2); - Mode = LetMode::Prefix; + Mode = FnMode::Prefix; goto after_params; } else if (isa(T3) && (T4->getKind() == NodeKind::Colon || T4->getKind() == NodeKind::Equals || T4->getKind() == NodeKind::BlockStart || T4->getKind() == NodeKind::LineFoldEnd)) { // Sufffix function declaration @@ -1256,7 +1250,7 @@ Node* Parser::parseLetDeclaration() { Param = new Parameter(P1, nullptr); Tokens.get(); Op = Operator::from_raw_node(T3); - Mode = LetMode::Suffix; + Mode = FnMode::Suffix; goto after_params; } else if (T2->getKind() == NodeKind::LParen && isa(T3) && T4->getKind() == NodeKind::RParen) { // Wrapped operator function declaration @@ -1268,7 +1262,7 @@ Node* Parser::parseLetDeclaration() { Operator::from_raw_node(T3), static_cast(T3) ); - Mode = LetMode::Wrapped; + Mode = FnMode::Wrapped; } else if (isa(T3)) { // Infix function declaration auto P1 = parseNarrowPattern(); @@ -1277,11 +1271,11 @@ Node* Parser::parseLetDeclaration() { auto P2 = parseNarrowPattern(); Right = new Parameter(P2, nullptr); Op = Operator::from_raw_node(T3); - Mode = LetMode::Infix; + Mode = FnMode::Infix; goto after_params; } else { // Variable declaration or named function declaration - Mode = LetMode::VarOrNamed; + Mode = FnMode::Named; Name = parseNarrowPattern(); if (!Name) { if (Pub) { @@ -1290,10 +1284,7 @@ Node* Parser::parseLetDeclaration() { if (Foreign) { Foreign->unref(); } - Let->unref(); - if (Mut) { - Mut->unref(); - } + Fn->unref(); skipPastLineFoldEnd(); return nullptr; } @@ -1381,70 +1372,57 @@ after_params: finish: switch (Mode) { - case LetMode::Prefix: + case FnMode::Prefix: return new PrefixFunctionDeclaration( Annotations, Pub, Foreign, - Let, + Fn, Op, Param, TA, Body ); - case LetMode::Suffix: + case FnMode::Suffix: return new SuffixFunctionDeclaration( Annotations, Pub, Foreign, - Let, + Fn, Param, Op, TA, Body ); - case LetMode::Infix: + case FnMode::Infix: return new InfixFunctionDeclaration( Annotations, Pub, Foreign, - Let, + Fn, Left, Op, Right, TA, Body ); - case LetMode::Wrapped: + case FnMode::Wrapped: return new NamedFunctionDeclaration( Annotations, Pub, Foreign, - Let, + Fn, Sym, Params, TA, Body ); - case LetMode::VarOrNamed: - if (Name->getKind() != NodeKind::BindPattern || Mut) { - // TODO assert Params is empty - return new VariableDeclaration( - Annotations, - Pub, - Foreign, - Let, - Mut, - Name, - TA, - Body - ); - } + case FnMode::Named: return new NamedFunctionDeclaration( Annotations, Pub, Foreign, - Let, + Fn, cast(Name)->Name, Params, TA, @@ -1453,11 +1431,134 @@ finish: } } + +VariableDeclaration* Parser::parseVariableDeclaration() { + + auto Annotations = parseAnnotations(); + PubKeyword* Pub = nullptr; + LetKeyword* Let; + MutKeyword* Mut = nullptr; + Operator Op; + Symbol Sym; + Pattern* Name; + TypeAssert* TA = nullptr; + LetBody* Body = nullptr; + + auto T0 = Tokens.get(); + if (T0->getKind() == NodeKind::PubKeyword) { + Pub = static_cast(T0); + T0 = Tokens.get(); + } + if (T0->getKind() != NodeKind::LetKeyword) { + DE.add(File, T0, std::vector { NodeKind::LetKeyword }); + if (Pub) { + Pub->unref(); + } + skipPastLineFoldEnd(); + return nullptr; + } + Let = static_cast(T0); + auto T1 = Tokens.peek(); + if (T1->getKind() == NodeKind::MutKeyword) { + Tokens.get(); + Mut = static_cast(T1); + } + + auto T2 = Tokens.peek(0); + auto T3 = Tokens.peek(1); + auto T4 = Tokens.peek(2); + Name = parseNarrowPattern(); + if (!Name) { + if (Pub) { + Pub->unref(); + } + Let->unref(); + if (Mut) { + Mut->unref(); + } + skipPastLineFoldEnd(); + return nullptr; + } + + auto T5 = Tokens.peek(); + + if (T5->getKind() == NodeKind::Colon) { + Tokens.get(); + auto TE = parseTypeExpression(); + if (TE) { + TA = new TypeAssert(static_cast(T5), TE); + } else { + skipPastLineFoldEnd(); + goto finish; + } + T5 = Tokens.peek(); + } + + switch (T5->getKind()) { + case NodeKind::BlockStart: + { + Tokens.get(); + std::vector Elements; + for (;;) { + auto T6 = Tokens.peek(); + if (T6->getKind() == NodeKind::BlockEnd) { + break; + } + auto Element = parseLetBodyElement(); + if (Element) { + Elements.push_back(Element); + } + } + Tokens.get()->unref(); // Always a BlockEnd + Body = new LetBlockBody(static_cast(T5), Elements); + break; + } + case NodeKind::Equals: + { + Tokens.get(); + auto E = parseExpression(); + if (!E) { + skipPastLineFoldEnd(); + goto finish; + } + Body = new LetExprBody(static_cast(T5), E); + break; + } + case NodeKind::LineFoldEnd: + break; + default: + std::vector Expected { NodeKind::BlockStart, NodeKind::LineFoldEnd, NodeKind::Equals }; + if (TA == nullptr) { + // First tokens of TypeAssert + Expected.push_back(NodeKind::Colon); + // First tokens of Pattern + Expected.push_back(NodeKind::Identifier); + } + DE.add(File, T5, Expected); + } + + checkLineFoldEnd(); + +finish: + + return new VariableDeclaration( + Annotations, + Pub, + Let, + Mut, + Name, + TA, + Body + ); +} + Node* Parser::parseLetBodyElement() { auto T0 = peekFirstTokenAfterAnnotationsAndModifiers(); switch (T0->getKind()) { case NodeKind::LetKeyword: - return parseLetDeclaration(); + return parseVariableDeclaration(); + case NodeKind::FnKeyword: + return parseFunctionDeclaration(); default: return parseExpressionStatement(); } @@ -1858,7 +1959,7 @@ Node* Parser::parseClassElement() { auto T0 = Tokens.peek(); switch (T0->getKind()) { case NodeKind::LetKeyword: - return parseLetDeclaration(); + return parseVariableDeclaration(); case NodeKind::TypeKeyword: // TODO default: @@ -1872,7 +1973,9 @@ Node* Parser::parseSourceElement() { auto T0 = peekFirstTokenAfterAnnotationsAndModifiers(); switch (T0->getKind()) { case NodeKind::LetKeyword: - return parseLetDeclaration(); + return parseVariableDeclaration(); + case NodeKind::FnKeyword: + return parseFunctionDeclaration(); case NodeKind::ClassKeyword: return parseClassDeclaration(); case NodeKind::InstanceKeyword: diff --git a/src/Scanner.cc b/src/Scanner.cc index 3407f29fc..1c6d58003 100644 --- a/src/Scanner.cc +++ b/src/Scanner.cc @@ -69,6 +69,7 @@ std::unordered_map Keywords = { { "elif", NodeKind::ElifKeyword }, { "else", NodeKind::ElseKeyword }, { "enum", NodeKind::EnumKeyword }, + { "fn", NodeKind::FnKeyword }, { "foreign", NodeKind::ForeignKeyword }, { "if", NodeKind::IfKeyword }, { "instance", NodeKind::InstanceKeyword }, @@ -293,6 +294,8 @@ digit_finish: return new EnumKeyword(StartLoc); case NodeKind::DoKeyword: return new DoKeyword(StartLoc); + case NodeKind::FnKeyword: + return new FnKeyword(StartLoc); default: ZEN_UNREACHABLE }