diff --git a/include/bolt/CST.hpp b/include/bolt/CST.hpp index e1c52b004..2911db023 100644 --- a/include/bolt/CST.hpp +++ b/include/bolt/CST.hpp @@ -59,9 +59,9 @@ namespace bolt { CustomOperator, Assignment, Identifier, + IdentifierAlt, StringLiteral, IntegerLiteral, - QualifiedName, TypeclassConstraintExpression, EqualityConstraintExpression, QualifiedTypeExpression, @@ -708,6 +708,22 @@ namespace bolt { }; + class IdentifierAlt : public Token { + public: + + ByteString Text; + + IdentifierAlt(ByteString Text, TextLoc StartLoc): + Token(NodeKind::IdentifierAlt, StartLoc), Text(Text) {} + + std::string getText() const override; + + static bool classof(const Node* N) { + return N->getKind() == NodeKind::IdentifierAlt; + } + + }; + class StringLiteral : public Token { public: @@ -738,25 +754,6 @@ namespace bolt { return N->getKind() == NodeKind::IntegerLiteral; } - }; - class QualifiedName : public Node { - public: - - std::vector ModulePath; - Identifier* Name; - - QualifiedName( - std::vector ModulePath, - Identifier* Name - ): Node(NodeKind::QualifiedName), - ModulePath(ModulePath), - Name(Name) {} - - Token* getFirstToken() override; - Token* getLastToken() override; - - SymbolPath getSymbolPath() const; - }; class TypedNode : public Node { @@ -873,16 +870,21 @@ namespace bolt { class ReferenceTypeExpression : public TypeExpression { public: - QualifiedName* Name; + std::vector> ModulePath; + IdentifierAlt* Name; ReferenceTypeExpression( - QualifiedName* Name + std::vector> ModulePath, + IdentifierAlt* Name ): TypeExpression(NodeKind::ReferenceTypeExpression), + ModulePath(ModulePath), Name(Name) {} Token* getFirstToken() override; Token* getLastToken() override; + SymbolPath getSymbolPath() const; + }; class ArrowTypeExpression : public TypeExpression { @@ -950,16 +952,21 @@ namespace bolt { class ReferenceExpression : public Expression { public: - QualifiedName* Name; + std::vector> ModulePath; + Identifier* Name; ReferenceExpression( - QualifiedName* Name + std::vector> ModulePath, + Identifier* Name ): Expression(NodeKind::ReferenceExpression), + ModulePath(ModulePath), Name(Name) {} Token* getFirstToken() override; Token* getLastToken() override; + SymbolPath getSymbolPath() const; + }; class NestedExpression : public Expression { @@ -1264,14 +1271,14 @@ namespace bolt { public: class InstanceKeyword* InstanceKeyword; - Identifier* Name; + IdentifierAlt* Name; std::vector TypeExps; class BlockStart* BlockStart; std::vector Elements; InstanceDeclaration( class InstanceKeyword* InstanceKeyword, - Identifier* Name, + IdentifierAlt* Name, std::vector TypeExps, class BlockStart* BlockStart, std::vector Elements @@ -1292,7 +1299,7 @@ namespace bolt { class PubKeyword* PubKeyword; class ClassKeyword* ClassKeyword; - Identifier* Name; + IdentifierAlt* Name; std::vector TypeVars; class BlockStart* BlockStart; std::vector Elements; @@ -1300,7 +1307,7 @@ namespace bolt { ClassDeclaration( class PubKeyword* PubKeyword, class ClassKeyword* ClassKeyword, - Identifier* Name, + IdentifierAlt* Name, std::vector TypeVars, class BlockStart* BlockStart, std::vector Elements @@ -1431,9 +1438,9 @@ namespace bolt { template<> inline NodeKind getNodeType() { return NodeKind::CustomOperator; } template<> inline NodeKind getNodeType() { return NodeKind::Assignment; } template<> inline NodeKind getNodeType() { return NodeKind::Identifier; } + template<> inline NodeKind getNodeType() { return NodeKind::IdentifierAlt; } template<> inline NodeKind getNodeType() { return NodeKind::StringLiteral; } template<> inline NodeKind getNodeType() { return NodeKind::IntegerLiteral; } - template<> inline NodeKind getNodeType() { return NodeKind::QualifiedName; } template<> inline NodeKind getNodeType() { return NodeKind::QualifiedTypeExpression; } template<> inline NodeKind getNodeType() { return NodeKind::ReferenceTypeExpression; } template<> inline NodeKind getNodeType() { return NodeKind::ArrowTypeExpression; } diff --git a/include/bolt/CSTVisitor.hpp b/include/bolt/CSTVisitor.hpp index a2b2c572b..26583f271 100644 --- a/include/bolt/CSTVisitor.hpp +++ b/include/bolt/CSTVisitor.hpp @@ -79,12 +79,12 @@ namespace bolt { return static_cast(this)->visitAssignment(static_cast(N)); case NodeKind::Identifier: return static_cast(this)->visitIdentifier(static_cast(N)); + case NodeKind::IdentifierAlt: + return static_cast(this)->visitIdentifierAlt(static_cast(N)); case NodeKind::StringLiteral: return static_cast(this)->visitStringLiteral(static_cast(N)); case NodeKind::IntegerLiteral: return static_cast(this)->visitIntegerLiteral(static_cast(N)); - case NodeKind::QualifiedName: - return static_cast(this)->visitQualifiedName(static_cast(N)); case NodeKind::TypeclassConstraintExpression: return static_cast(this)->visitTypeclassConstraintExpression(static_cast(N)); case NodeKind::EqualityConstraintExpression: @@ -288,6 +288,10 @@ namespace bolt { visitToken(N); } + void visitIdentifierAlt(IdentifierAlt* N) { + visitToken(N); + } + void visitStringLiteral(StringLiteral* N) { visitToken(N); } @@ -296,10 +300,6 @@ namespace bolt { visitToken(N); } - void visitQualifiedName(QualifiedName* N) { - visitNode(N); - } - void visitConstraintExpression(ConstraintExpression* N) { visitNode(N); } @@ -538,15 +538,15 @@ namespace bolt { case NodeKind::Identifier: visitEachChild(static_cast(N)); break; + case NodeKind::IdentifierAlt: + visitEachChild(static_cast(N)); + break; case NodeKind::StringLiteral: visitEachChild(static_cast(N)); break; case NodeKind::IntegerLiteral: visitEachChild(static_cast(N)); break; - case NodeKind::QualifiedName: - visitEachChild(static_cast(N)); - break; case NodeKind::TypeclassConstraintExpression: visitEachChild(static_cast(N)); break; @@ -737,19 +737,15 @@ namespace bolt { void visitEachChild(Identifier* N) { } + void visitEachChild(IdentifierAlt* N) { + } + void visitEachChild(StringLiteral* N) { } void visitEachChild(IntegerLiteral* N) { } - void visitEachChild(QualifiedName* N) { - for (auto Name: N->ModulePath) { - BOLT_VISIT(Name); - } - BOLT_VISIT(N->Name); - } - void visitEachChild(TypeclassConstraintExpression* N) { BOLT_VISIT(N->Name); for (auto TE: N->TEs) { @@ -775,6 +771,10 @@ namespace bolt { } void visitEachChild(ReferenceTypeExpression* N) { + for (auto [Name, Dot]: N->ModulePath) { + BOLT_VISIT(Name); + BOLT_VISIT(Dot); + } BOLT_VISIT(N->Name); } @@ -794,6 +794,10 @@ namespace bolt { } void visitEachChild(ReferenceExpression* N) { + for (auto [Name, Dot]: N->ModulePath) { + BOLT_VISIT(Name); + BOLT_VISIT(Dot); + } BOLT_VISIT(N->Name); } diff --git a/include/bolt/Checker.hpp b/include/bolt/Checker.hpp index 03c54f074..b96458e44 100644 --- a/include/bolt/Checker.hpp +++ b/include/bolt/Checker.hpp @@ -4,6 +4,7 @@ #include "zen/config.hpp" #include "bolt/ByteString.hpp" +#include "bolt/Common.hpp" #include "bolt/CST.hpp" #include "bolt/Diagnostics.hpp" @@ -15,30 +16,6 @@ namespace bolt { - class LanguageConfig { - - enum ConfigFlags { - ConfigFlags_TypeVarsRequireForall = 1 << 0, - }; - - unsigned Flags; - - public: - - void setTypeVarsRequireForall(bool Enable) { - if (Enable) { - Flags |= ConfigFlags_TypeVarsRequireForall; - } else { - Flags |= ~ConfigFlags_TypeVarsRequireForall; - } - } - - bool typeVarsRequireForall() const noexcept { - return Flags & ConfigFlags_TypeVarsRequireForall; - } - - }; - class DiagnosticEngine; class Node; @@ -230,57 +207,6 @@ namespace bolt { }; -/* class Scheme { */ - -/* const SchemeKind Kind; */ - -/* public: */ - -/* inline Scheme(Forall F): */ -/* Kind(SchemeKind::Forall), F(F) {} */ - -/* inline Scheme(const Scheme& Other): */ -/* Kind(Other.Kind) { */ -/* switch (Kind) { */ -/* case SchemeKind::Forall: */ -/* F = Other.F; */ -/* break; */ -/* } */ -/* } */ - - -/* inline Scheme(Scheme&& Other): */ -/* Kind(std::move(Other.Kind)) { */ -/* switch (Kind) { */ -/* case SchemeKind::Forall: */ -/* F = std::move(Other.F); */ -/* break; */ -/* } */ -/* } */ - -/* inline SchemeKind getKind() const noexcept { */ -/* return Kind; */ -/* } */ - -/* template */ -/* T& as(); */ - -/* template<> */ -/* Forall& as() { */ -/* ZEN_ASSERT(Kind == SchemeKind::Forall); */ -/* return F; */ -/* } */ - -/* ~Scheme() { */ -/* switch (Kind) { */ -/* case SchemeKind::Forall: */ -/* F.~Forall(); */ -/* break; */ -/* } */ -/* } */ - -/* }; */ - using TypeEnv = std::unordered_map; enum class ConstraintKind { @@ -420,11 +346,6 @@ namespace bolt { std::vector Contexts; - /** - * Holds the current inferred type class contexts in a given LetDeclaration body. - */ - // std::vector TCCs; - InferContext& getContext(); void addConstraint(Constraint* Constraint); @@ -474,8 +395,6 @@ namespace bolt { Type* instantiate(Scheme* S, Node* Source); - /* void addToTypeclassContexts(Node* N, std::vector& Contexts); */ - std::unordered_map> InstanceMap; std::vector findInstanceContext(TCon* Ty, TypeclassId& Class, Node* Source); void propagateClasses(TypeclassContext& Classes, Type* Ty, Node* Source); diff --git a/include/bolt/Common.hpp b/include/bolt/Common.hpp new file mode 100644 index 000000000..e9ca4e1db --- /dev/null +++ b/include/bolt/Common.hpp @@ -0,0 +1,30 @@ + +#pragma once + +namespace bolt { + + class LanguageConfig { + + enum ConfigFlags { + ConfigFlags_TypeVarsRequireForall = 1 << 0, + }; + + unsigned Flags; + + public: + + void setTypeVarsRequireForall(bool Enable) { + if (Enable) { + Flags |= ConfigFlags_TypeVarsRequireForall; + } else { + Flags |= ~ConfigFlags_TypeVarsRequireForall; + } + } + + bool typeVarsRequireForall() const noexcept { + return Flags & ConfigFlags_TypeVarsRequireForall; + } + + }; + +} diff --git a/include/bolt/Parser.hpp b/include/bolt/Parser.hpp index 2131a4e53..e42eb8071 100644 --- a/include/bolt/Parser.hpp +++ b/include/bolt/Parser.hpp @@ -91,8 +91,6 @@ namespace bolt { Parser(TextFile& File, Stream& S); - QualifiedName* parseQualifiedName(); - TypeExpression* parseTypeExpression(); Pattern* parsePattern(); diff --git a/src/CST.cc b/src/CST.cc index 2ba5e066a..42ce0bbe7 100644 --- a/src/CST.cc +++ b/src/CST.cc @@ -153,17 +153,6 @@ namespace bolt { return true; } - Token* QualifiedName::getFirstToken() { - if (ModulePath.size()) { - return ModulePath.front(); - } - return Name; - } - - Token* QualifiedName::getLastToken() { - return Name; - } - Token* TypeclassConstraintExpression::getFirstToken() { return Name; } @@ -195,11 +184,14 @@ namespace bolt { } Token* ReferenceTypeExpression::getFirstToken() { - return Name->getFirstToken(); + if (!ModulePath.empty()) { + return std::get<0>(ModulePath.front()); + } + return Name; } Token* ReferenceTypeExpression::getLastToken() { - return Name->getFirstToken(); + return Name; } Token* ArrowTypeExpression::getFirstToken() { @@ -230,11 +222,14 @@ namespace bolt { } Token* ReferenceExpression::getFirstToken() { - return Name->getFirstToken(); + if (!ModulePath.empty()) { + return std::get<0>(ModulePath.front()); + } + return Name; } Token* ReferenceExpression::getLastToken() { - return Name->getLastToken(); + return Name; } Token* NestedExpression::getFirstToken() { @@ -559,6 +554,10 @@ namespace bolt { return Text; } + std::string IdentifierAlt::getText() const { + return Text; + } + std::string StringLiteral::getText() const { return "\"" + Text + "\""; } @@ -583,10 +582,10 @@ namespace bolt { return "instance"; } - SymbolPath QualifiedName::getSymbolPath() const { + SymbolPath ReferenceExpression::getSymbolPath() const { std::vector ModuleNames; - for (auto Ident: ModulePath) { - ModuleNames.push_back(Ident->Text); + for (auto [Name, Dot]: ModulePath) { + ModuleNames.push_back(Name->Text); } return SymbolPath { ModuleNames, Name->Text }; } diff --git a/src/Checker.cc b/src/Checker.cc index c0266f880..a79931925 100644 --- a/src/Checker.cc +++ b/src/Checker.cc @@ -636,10 +636,10 @@ namespace bolt { case NodeKind::ReferenceTypeExpression: { auto RefTE = static_cast(N); - auto Ty = lookupMono(RefTE->Name->Name->Text); + auto Ty = lookupMono(RefTE->Name->Text); if (Ty == nullptr) { - if (!RefTE->Name->Name->isTypeVar() || Config.typeVarsRequireForall()) { - DE.add(RefTE->Name->Name->Text, RefTE->Name->Name); + if (Config.typeVarsRequireForall()) { + DE.add(RefTE->Name->Text, RefTE->Name); } Ty = createTypeVar(); } @@ -718,16 +718,16 @@ namespace bolt { case NodeKind::ReferenceExpression: { auto Ref = static_cast(X); - ZEN_ASSERT(Ref->Name->ModulePath.empty()); - auto Ctx = lookupCall(Ref, Ref->Name->getSymbolPath()); + ZEN_ASSERT(Ref->ModulePath.empty()); + auto Ctx = lookupCall(Ref, Ref->getSymbolPath()); if (Ctx) { /* std::cerr << "recursive call!\n"; */ ZEN_ASSERT(Ctx->ReturnType != nullptr); return Ctx->ReturnType; } - auto Scm = lookup(Ref->Name->Name->Text); + auto Scm = lookup(Ref->Name->Text); if (Scm == nullptr) { - DE.add(Ref->Name->Name->Text, Ref->Name); + DE.add(Ref->Name->Text, Ref->Name); return createTypeVar(); } auto Ty = instantiate(Scm, X); @@ -795,8 +795,7 @@ namespace bolt { break; } - default - : + default: ZEN_UNREACHABLE } diff --git a/src/IPRGraph.cc b/src/IPRGraph.cc index a494b2f47..41c28d778 100644 --- a/src/IPRGraph.cc +++ b/src/IPRGraph.cc @@ -75,7 +75,7 @@ namespace bolt { case NodeKind::ReferenceExpression: { auto Y = static_cast(X); - auto Def = Y->getScope()->lookup(Y->Name->getSymbolPath()); + auto Def = Y->getScope()->lookup(Y->getSymbolPath()); ZEN_ASSERT(Def != nullptr); if (Decl != nullptr) { Edges.emplace(Decl, Y); diff --git a/src/Parser.cc b/src/Parser.cc index ac4f71023..677e6cb6f 100644 --- a/src/Parser.cc +++ b/src/Parser.cc @@ -97,24 +97,6 @@ namespace bolt { } } - QualifiedName* Parser::parseQualifiedName() { - std::vector ModulePath; - auto Name = expectToken(NodeKind::Identifier); - for (;;) { - auto T1 = Tokens.peek(); - if (T1->getKind() != NodeKind::Dot) { - break; - } - Tokens.get(); - ModulePath.push_back(static_cast(Name)); - Name = Tokens.get(); - if (Name->getKind() != NodeKind::Identifier) { - throw UnexpectedTokenDiagnostic(File, Name, std::vector { NodeKind::Identifier }); - } - } - return new QualifiedName(ModulePath, static_cast(Name)); - } - TypeExpression* Parser::parseTypeExpression() { return parseQualifiedTypeExpression(); } @@ -186,10 +168,22 @@ after_constraints: auto T0 = Tokens.peek(); switch (T0->getKind()) { case NodeKind::Identifier: - if (static_cast(T0)->isTypeVar()) { return parseVarTypeExpression(); + case NodeKind::IdentifierAlt: + { + std::vector> ModulePath; + auto Name = expectToken(); + for (;;) { + auto T1 = Tokens.peek(); + if (T1->getKind() != NodeKind::Dot) { + break; + } + Tokens.get(); + ModulePath.push_back(std::make_tuple(static_cast(Name), static_cast(T1))); + Name = expectToken(); } - return new ReferenceTypeExpression(parseQualifiedName()); + return new ReferenceTypeExpression(ModulePath, static_cast(Name)); + } default: throw UnexpectedTokenDiagnostic(File, T0, std::vector { NodeKind::Identifier }); } @@ -218,8 +212,17 @@ after_constraints: switch (T0->getKind()) { case NodeKind::Identifier: { - auto Name = parseQualifiedName(); - return new ReferenceExpression(Name); + std::vector> ModulePath; + for (;;) { + auto T1 = Tokens.peek(); + if (T1->getKind() != NodeKind::IdentifierAlt) { + break; + } + Tokens.get(); + auto Dot = expectToken(); + ModulePath.push_back(std::make_tuple(static_cast(T1), Dot)); + } + return new ReferenceExpression(ModulePath, expectToken()); } case NodeKind::LParen: { @@ -510,7 +513,7 @@ after_vars: InstanceDeclaration* Parser::parseInstanceDeclaration() { auto InstanceKeyword = expectToken(); - auto Name = expectToken(); + auto Name = expectToken(); std::vector TypeExps; for (;;) { auto T1 = Tokens.peek(); @@ -547,7 +550,7 @@ after_vars: PubKeyword = static_cast(T0); } auto ClassKeyword = expectToken(); - auto Name = expectToken(); + auto Name = expectToken(); std::vector TypeVars; for (;;) { auto T2 = Tokens.peek(); diff --git a/src/Scanner.cc b/src/Scanner.cc index a1d5a6528..6e889b2c5 100644 --- a/src/Scanner.cc +++ b/src/Scanner.cc @@ -140,32 +140,6 @@ digit_finish: return new IntegerLiteral(I, StartLoc); } - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': case 'A': case 'B': case 'C': @@ -192,6 +166,45 @@ digit_finish: case 'X': case 'Y': case 'Z': + { + ByteString Text { static_cast(C0) }; + for (;;) { + auto C1 = peekChar(); + if (!isIdentifierPart(C1)) { + break; + } + Text.push_back(C1); + getChar(); + } + return new IdentifierAlt(Text, StartLoc); + } + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': case '_': { ByteString Text { static_cast(C0) };