Clean up some code and introduce IdentifierAlt

This commit is contained in:
Sam Vervaeck 2023-05-21 00:25:01 +02:00
parent db26fd3b18
commit 66d7b90f82
Signed by: samvv
SSH key fingerprint: SHA256:dIg0ywU1OP+ZYifrYxy8c5esO72cIKB+4/9wkZj1VaY
10 changed files with 179 additions and 207 deletions

View file

@ -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<Identifier*> ModulePath;
Identifier* Name;
QualifiedName(
std::vector<Identifier*> 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<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
IdentifierAlt* Name;
ReferenceTypeExpression(
QualifiedName* Name
std::vector<std::tuple<IdentifierAlt*, Dot*>> 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<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
Identifier* Name;
ReferenceExpression(
QualifiedName* Name
std::vector<std::tuple<IdentifierAlt*, Dot*>> 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<TypeExpression*> TypeExps;
class BlockStart* BlockStart;
std::vector<Node*> Elements;
InstanceDeclaration(
class InstanceKeyword* InstanceKeyword,
Identifier* Name,
IdentifierAlt* Name,
std::vector<TypeExpression*> TypeExps,
class BlockStart* BlockStart,
std::vector<Node*> Elements
@ -1292,7 +1299,7 @@ namespace bolt {
class PubKeyword* PubKeyword;
class ClassKeyword* ClassKeyword;
Identifier* Name;
IdentifierAlt* Name;
std::vector<VarTypeExpression*> TypeVars;
class BlockStart* BlockStart;
std::vector<Node*> Elements;
@ -1300,7 +1307,7 @@ namespace bolt {
ClassDeclaration(
class PubKeyword* PubKeyword,
class ClassKeyword* ClassKeyword,
Identifier* Name,
IdentifierAlt* Name,
std::vector<VarTypeExpression*> TypeVars,
class BlockStart* BlockStart,
std::vector<Node*> Elements
@ -1431,9 +1438,9 @@ namespace bolt {
template<> inline NodeKind getNodeType<CustomOperator>() { return NodeKind::CustomOperator; }
template<> inline NodeKind getNodeType<Assignment>() { return NodeKind::Assignment; }
template<> inline NodeKind getNodeType<Identifier>() { return NodeKind::Identifier; }
template<> inline NodeKind getNodeType<IdentifierAlt>() { return NodeKind::IdentifierAlt; }
template<> inline NodeKind getNodeType<StringLiteral>() { return NodeKind::StringLiteral; }
template<> inline NodeKind getNodeType<IntegerLiteral>() { return NodeKind::IntegerLiteral; }
template<> inline NodeKind getNodeType<QualifiedName>() { return NodeKind::QualifiedName; }
template<> inline NodeKind getNodeType<QualifiedTypeExpression>() { return NodeKind::QualifiedTypeExpression; }
template<> inline NodeKind getNodeType<ReferenceTypeExpression>() { return NodeKind::ReferenceTypeExpression; }
template<> inline NodeKind getNodeType<ArrowTypeExpression>() { return NodeKind::ArrowTypeExpression; }

View file

@ -79,12 +79,12 @@ namespace bolt {
return static_cast<D*>(this)->visitAssignment(static_cast<Assignment*>(N));
case NodeKind::Identifier:
return static_cast<D*>(this)->visitIdentifier(static_cast<Identifier*>(N));
case NodeKind::IdentifierAlt:
return static_cast<D*>(this)->visitIdentifierAlt(static_cast<IdentifierAlt*>(N));
case NodeKind::StringLiteral:
return static_cast<D*>(this)->visitStringLiteral(static_cast<StringLiteral*>(N));
case NodeKind::IntegerLiteral:
return static_cast<D*>(this)->visitIntegerLiteral(static_cast<IntegerLiteral*>(N));
case NodeKind::QualifiedName:
return static_cast<D*>(this)->visitQualifiedName(static_cast<QualifiedName*>(N));
case NodeKind::TypeclassConstraintExpression:
return static_cast<D*>(this)->visitTypeclassConstraintExpression(static_cast<TypeclassConstraintExpression*>(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<Identifier*>(N));
break;
case NodeKind::IdentifierAlt:
visitEachChild(static_cast<IdentifierAlt*>(N));
break;
case NodeKind::StringLiteral:
visitEachChild(static_cast<StringLiteral*>(N));
break;
case NodeKind::IntegerLiteral:
visitEachChild(static_cast<IntegerLiteral*>(N));
break;
case NodeKind::QualifiedName:
visitEachChild(static_cast<QualifiedName*>(N));
break;
case NodeKind::TypeclassConstraintExpression:
visitEachChild(static_cast<TypeclassConstraintExpression*>(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);
}

View file

@ -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<typename T> */
/* T& as(); */
/* template<> */
/* Forall& as<Forall>() { */
/* ZEN_ASSERT(Kind == SchemeKind::Forall); */
/* return F; */
/* } */
/* ~Scheme() { */
/* switch (Kind) { */
/* case SchemeKind::Forall: */
/* F.~Forall(); */
/* break; */
/* } */
/* } */
/* }; */
using TypeEnv = std::unordered_map<ByteString, Scheme*>;
enum class ConstraintKind {
@ -420,11 +346,6 @@ namespace bolt {
std::vector<InferContext*> Contexts;
/**
* Holds the current inferred type class contexts in a given LetDeclaration body.
*/
// std::vector<TypeclassContext*> 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<TypeclassContext>& Contexts); */
std::unordered_map<ByteString, std::vector<InstanceDeclaration*>> InstanceMap;
std::vector<TypeclassContext> findInstanceContext(TCon* Ty, TypeclassId& Class, Node* Source);
void propagateClasses(TypeclassContext& Classes, Type* Ty, Node* Source);

30
include/bolt/Common.hpp Normal file
View file

@ -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;
}
};
}

View file

@ -91,8 +91,6 @@ namespace bolt {
Parser(TextFile& File, Stream<Token*>& S);
QualifiedName* parseQualifiedName();
TypeExpression* parseTypeExpression();
Pattern* parsePattern();

View file

@ -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<ByteString> 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 };
}

View file

@ -636,10 +636,10 @@ namespace bolt {
case NodeKind::ReferenceTypeExpression:
{
auto RefTE = static_cast<ReferenceTypeExpression*>(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<BindingNotFoundDiagnostic>(RefTE->Name->Name->Text, RefTE->Name->Name);
if (Config.typeVarsRequireForall()) {
DE.add<BindingNotFoundDiagnostic>(RefTE->Name->Text, RefTE->Name);
}
Ty = createTypeVar();
}
@ -718,16 +718,16 @@ namespace bolt {
case NodeKind::ReferenceExpression:
{
auto Ref = static_cast<ReferenceExpression*>(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<BindingNotFoundDiagnostic>(Ref->Name->Name->Text, Ref->Name);
DE.add<BindingNotFoundDiagnostic>(Ref->Name->Text, Ref->Name);
return createTypeVar();
}
auto Ty = instantiate(Scm, X);
@ -795,8 +795,7 @@ namespace bolt {
break;
}
default
:
default:
ZEN_UNREACHABLE
}

View file

@ -75,7 +75,7 @@ namespace bolt {
case NodeKind::ReferenceExpression:
{
auto Y = static_cast<ReferenceExpression*>(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);

View file

@ -97,24 +97,6 @@ namespace bolt {
}
}
QualifiedName* Parser::parseQualifiedName() {
std::vector<Identifier*> ModulePath;
auto Name = expectToken(NodeKind::Identifier);
for (;;) {
auto T1 = Tokens.peek();
if (T1->getKind() != NodeKind::Dot) {
break;
}
Tokens.get();
ModulePath.push_back(static_cast<Identifier*>(Name));
Name = Tokens.get();
if (Name->getKind() != NodeKind::Identifier) {
throw UnexpectedTokenDiagnostic(File, Name, std::vector { NodeKind::Identifier });
}
}
return new QualifiedName(ModulePath, static_cast<Identifier*>(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<Identifier*>(T0)->isTypeVar()) {
return parseVarTypeExpression();
case NodeKind::IdentifierAlt:
{
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
auto Name = expectToken<IdentifierAlt>();
for (;;) {
auto T1 = Tokens.peek();
if (T1->getKind() != NodeKind::Dot) {
break;
}
Tokens.get();
ModulePath.push_back(std::make_tuple(static_cast<IdentifierAlt*>(Name), static_cast<Dot*>(T1)));
Name = expectToken<IdentifierAlt>();
}
return new ReferenceTypeExpression(parseQualifiedName());
return new ReferenceTypeExpression(ModulePath, static_cast<IdentifierAlt*>(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<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
for (;;) {
auto T1 = Tokens.peek();
if (T1->getKind() != NodeKind::IdentifierAlt) {
break;
}
Tokens.get();
auto Dot = expectToken<class Dot>();
ModulePath.push_back(std::make_tuple(static_cast<IdentifierAlt*>(T1), Dot));
}
return new ReferenceExpression(ModulePath, expectToken<Identifier>());
}
case NodeKind::LParen:
{
@ -510,7 +513,7 @@ after_vars:
InstanceDeclaration* Parser::parseInstanceDeclaration() {
auto InstanceKeyword = expectToken<class InstanceKeyword>();
auto Name = expectToken<Identifier>();
auto Name = expectToken<IdentifierAlt>();
std::vector<TypeExpression*> TypeExps;
for (;;) {
auto T1 = Tokens.peek();
@ -547,7 +550,7 @@ after_vars:
PubKeyword = static_cast<class PubKeyword*>(T0);
}
auto ClassKeyword = expectToken<class ClassKeyword>();
auto Name = expectToken<Identifier>();
auto Name = expectToken<IdentifierAlt>();
std::vector<VarTypeExpression*> TypeVars;
for (;;) {
auto T2 = Tokens.peek();

View file

@ -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<char>(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<char>(C0) };