Sort diangostics by node and refactor ConsoleDiagnostics
This commit is contained in:
parent
5ac162cd72
commit
6967f9a060
10 changed files with 468 additions and 257 deletions
|
@ -131,8 +131,13 @@ namespace bolt {
|
||||||
|
|
||||||
void setParents();
|
void setParents();
|
||||||
|
|
||||||
virtual Token* getFirstToken() = 0;
|
virtual Token* getFirstToken() const = 0;
|
||||||
virtual Token* getLastToken() = 0;
|
virtual Token* getLastToken() const = 0;
|
||||||
|
|
||||||
|
virtual std::size_t getStartLine() const;
|
||||||
|
virtual std::size_t getStartColumn() const;
|
||||||
|
virtual std::size_t getEndLine() const;
|
||||||
|
virtual std::size_t getEndColumn() const;
|
||||||
|
|
||||||
inline NodeKind getKind() const noexcept {
|
inline NodeKind getKind() const noexcept {
|
||||||
return Kind;
|
return Kind;
|
||||||
|
@ -159,11 +164,12 @@ namespace bolt {
|
||||||
return static_cast<T*>(this);
|
return static_cast<T*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextRange getRange();
|
TextRange getRange() const;
|
||||||
|
|
||||||
inline Node(NodeKind Type):
|
inline Node(NodeKind Type):
|
||||||
Kind(Type) {}
|
Kind(Type) {}
|
||||||
|
|
||||||
|
const SourceFile* getSourceFile() const;
|
||||||
SourceFile* getSourceFile();
|
SourceFile* getSourceFile();
|
||||||
|
|
||||||
virtual Scope* getScope();
|
virtual Scope* getScope();
|
||||||
|
@ -223,12 +229,12 @@ namespace bolt {
|
||||||
|
|
||||||
virtual std::string getText() const = 0;
|
virtual std::string getText() const = 0;
|
||||||
|
|
||||||
inline Token* getFirstToken() override {
|
inline Token* getFirstToken() const override {
|
||||||
return this;
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Token* getLastToken() override {
|
inline Token* getLastToken() const override {
|
||||||
return this;
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
inline TextLoc getStartLoc() {
|
inline TextLoc getStartLoc() {
|
||||||
|
@ -897,8 +903,8 @@ namespace bolt {
|
||||||
Name(Name),
|
Name(Name),
|
||||||
TEs(TEs) {}
|
TEs(TEs) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
static bool classof(const Node* N) {
|
static bool classof(const Node* N) {
|
||||||
return N->getKind() == NodeKind::TypeclassConstraintExpression;
|
return N->getKind() == NodeKind::TypeclassConstraintExpression;
|
||||||
|
@ -922,8 +928,8 @@ namespace bolt {
|
||||||
Tilde(Tilde),
|
Tilde(Tilde),
|
||||||
Right(Right) {}
|
Right(Right) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
static bool classof(const Node* N) {
|
static bool classof(const Node* N) {
|
||||||
return N->getKind() == NodeKind::EqualityConstraintExpression;
|
return N->getKind() == NodeKind::EqualityConstraintExpression;
|
||||||
|
@ -947,8 +953,8 @@ namespace bolt {
|
||||||
RArrowAlt(RArrowAlt),
|
RArrowAlt(RArrowAlt),
|
||||||
TE(TE) {}
|
TE(TE) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
static bool classof(const Node* N) {
|
static bool classof(const Node* N) {
|
||||||
return N->getKind() == NodeKind::QualifiedTypeExpression;
|
return N->getKind() == NodeKind::QualifiedTypeExpression;
|
||||||
|
@ -969,8 +975,8 @@ namespace bolt {
|
||||||
ModulePath(ModulePath),
|
ModulePath(ModulePath),
|
||||||
Name(Name) {}
|
Name(Name) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
SymbolPath getSymbolPath() const;
|
SymbolPath getSymbolPath() const;
|
||||||
|
|
||||||
|
@ -989,8 +995,8 @@ namespace bolt {
|
||||||
ParamTypes(ParamTypes),
|
ParamTypes(ParamTypes),
|
||||||
ReturnType(ReturnType) {}
|
ReturnType(ReturnType) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1002,8 +1008,8 @@ namespace bolt {
|
||||||
inline VarTypeExpression(Identifier* Name):
|
inline VarTypeExpression(Identifier* Name):
|
||||||
TypeExpression(NodeKind::VarTypeExpression), Name(Name) {}
|
TypeExpression(NodeKind::VarTypeExpression), Name(Name) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1023,8 +1029,8 @@ namespace bolt {
|
||||||
TE(TE),
|
TE(TE),
|
||||||
RParen(RParen) {}
|
RParen(RParen) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1044,8 +1050,8 @@ namespace bolt {
|
||||||
Elements(Elements),
|
Elements(Elements),
|
||||||
RParen(RParen) {}
|
RParen(RParen) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1067,8 +1073,8 @@ namespace bolt {
|
||||||
): Pattern(NodeKind::BindPattern),
|
): Pattern(NodeKind::BindPattern),
|
||||||
Name(Name) {}
|
Name(Name) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
static bool classof(const Node* N) {
|
static bool classof(const Node* N) {
|
||||||
return N->getKind() == NodeKind::BindPattern;
|
return N->getKind() == NodeKind::BindPattern;
|
||||||
|
@ -1085,8 +1091,8 @@ namespace bolt {
|
||||||
Pattern(NodeKind::LiteralPattern),
|
Pattern(NodeKind::LiteralPattern),
|
||||||
Literal(Literal) {}
|
Literal(Literal) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
static bool classof(const Node* N) {
|
static bool classof(const Node* N) {
|
||||||
return N->getKind() == NodeKind::LiteralPattern;
|
return N->getKind() == NodeKind::LiteralPattern;
|
||||||
|
@ -1115,8 +1121,8 @@ namespace bolt {
|
||||||
ModulePath(ModulePath),
|
ModulePath(ModulePath),
|
||||||
Name(Name) {}
|
Name(Name) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
SymbolPath getSymbolPath() const;
|
SymbolPath getSymbolPath() const;
|
||||||
|
|
||||||
|
@ -1138,8 +1144,8 @@ namespace bolt {
|
||||||
RArrowAlt(RArrowAlt),
|
RArrowAlt(RArrowAlt),
|
||||||
Expression(Expression) {}
|
Expression(Expression) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1162,8 +1168,8 @@ namespace bolt {
|
||||||
BlockStart(BlockStart),
|
BlockStart(BlockStart),
|
||||||
Cases(Cases) {}
|
Cases(Cases) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1183,8 +1189,8 @@ namespace bolt {
|
||||||
Dot(Dot),
|
Dot(Dot),
|
||||||
Name(Name) {}
|
Name(Name) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
inline Expression* getExpression() const {
|
inline Expression* getExpression() const {
|
||||||
return E;
|
return E;
|
||||||
|
@ -1208,8 +1214,8 @@ namespace bolt {
|
||||||
Elements(Elements),
|
Elements(Elements),
|
||||||
RParen(RParen) {}
|
RParen(RParen) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1229,8 +1235,8 @@ namespace bolt {
|
||||||
Inner(Inner),
|
Inner(Inner),
|
||||||
RParen(RParen) {}
|
RParen(RParen) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1244,8 +1250,8 @@ namespace bolt {
|
||||||
): Expression(NodeKind::ConstantExpression),
|
): Expression(NodeKind::ConstantExpression),
|
||||||
Token(Token) {}
|
Token(Token) {}
|
||||||
|
|
||||||
class Token* getFirstToken() override;
|
class Token* getFirstToken() const override;
|
||||||
class Token* getLastToken() override;
|
class Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1262,8 +1268,8 @@ namespace bolt {
|
||||||
Function(Function),
|
Function(Function),
|
||||||
Args(Args) {}
|
Args(Args) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1280,8 +1286,8 @@ namespace bolt {
|
||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
RHS(RHS) {}
|
RHS(RHS) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1298,8 +1304,8 @@ namespace bolt {
|
||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
Argument(Argument) {}
|
Argument(Argument) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1319,8 +1325,8 @@ namespace bolt {
|
||||||
ExpressionStatement(class Expression* Expression):
|
ExpressionStatement(class Expression* Expression):
|
||||||
Statement(NodeKind::ExpressionStatement), Expression(Expression) {}
|
Statement(NodeKind::ExpressionStatement), Expression(Expression) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1343,8 +1349,8 @@ namespace bolt {
|
||||||
BlockStart(BlockStart),
|
BlockStart(BlockStart),
|
||||||
Elements(Elements) {}
|
Elements(Elements) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1356,8 +1362,8 @@ namespace bolt {
|
||||||
inline IfStatement(std::vector<IfStatementPart*> Parts):
|
inline IfStatement(std::vector<IfStatementPart*> Parts):
|
||||||
Statement(NodeKind::IfStatement), Parts(Parts) {}
|
Statement(NodeKind::IfStatement), Parts(Parts) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1374,8 +1380,8 @@ namespace bolt {
|
||||||
ReturnKeyword(ReturnKeyword),
|
ReturnKeyword(ReturnKeyword),
|
||||||
Expression(Expression) {}
|
Expression(Expression) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1392,8 +1398,8 @@ namespace bolt {
|
||||||
Colon(Colon),
|
Colon(Colon),
|
||||||
TypeExpression(TypeExpression) {}
|
TypeExpression(TypeExpression) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1410,8 +1416,8 @@ namespace bolt {
|
||||||
class Pattern* Pattern;
|
class Pattern* Pattern;
|
||||||
class TypeAssert* TypeAssert;
|
class TypeAssert* TypeAssert;
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1435,8 +1441,8 @@ namespace bolt {
|
||||||
BlockStart(BlockStart),
|
BlockStart(BlockStart),
|
||||||
Elements(Elements) {}
|
Elements(Elements) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1453,8 +1459,8 @@ namespace bolt {
|
||||||
Equals(Equals),
|
Equals(Equals),
|
||||||
Expression(Expression) {}
|
Expression(Expression) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1502,8 +1508,8 @@ namespace bolt {
|
||||||
return TheScope;
|
return TheScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
static bool classof(const Node* N) {
|
static bool classof(const Node* N) {
|
||||||
return N->getKind() == NodeKind::LetDeclaration;
|
return N->getKind() == NodeKind::LetDeclaration;
|
||||||
|
@ -1533,8 +1539,8 @@ namespace bolt {
|
||||||
BlockStart(BlockStart),
|
BlockStart(BlockStart),
|
||||||
Elements(Elements) {}
|
Elements(Elements) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
static bool classof(const Node* N) {
|
static bool classof(const Node* N) {
|
||||||
return N->getKind() == NodeKind::InstanceDeclaration;
|
return N->getKind() == NodeKind::InstanceDeclaration;
|
||||||
|
@ -1567,8 +1573,8 @@ namespace bolt {
|
||||||
BlockStart(BlockStart),
|
BlockStart(BlockStart),
|
||||||
Elements(Elements) {}
|
Elements(Elements) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
static bool classof(const Node* N) {
|
static bool classof(const Node* N) {
|
||||||
return N->getKind() == NodeKind::ClassDeclaration;
|
return N->getKind() == NodeKind::ClassDeclaration;
|
||||||
|
@ -1592,8 +1598,8 @@ namespace bolt {
|
||||||
class Colon* Colon;
|
class Colon* Colon;
|
||||||
class TypeExpression* TypeExpression;
|
class TypeExpression* TypeExpression;
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1619,8 +1625,8 @@ namespace bolt {
|
||||||
BlockStart(BlockStart),
|
BlockStart(BlockStart),
|
||||||
Fields(Fields) {}
|
Fields(Fields) {}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
Token* getFirstToken() const override;
|
||||||
Token* getLastToken() override;
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1641,8 +1647,12 @@ namespace bolt {
|
||||||
return File;
|
return File;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* getFirstToken() override;
|
inline const TextFile& getTextFile() const {
|
||||||
Token* getLastToken() override;
|
return File;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token* getFirstToken() const override;
|
||||||
|
Token* getLastToken() const override;
|
||||||
|
|
||||||
inline Scope* getScope() override {
|
inline Scope* getScope() override {
|
||||||
if (TheScope == nullptr) {
|
if (TheScope == nullptr) {
|
||||||
|
|
|
@ -39,6 +39,11 @@ namespace bolt {
|
||||||
return Kind;
|
return Kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Node* getNode() const {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnexpectedTokenDiagnostic : public Diagnostic {
|
class UnexpectedTokenDiagnostic : public Diagnostic {
|
||||||
|
@ -74,6 +79,10 @@ namespace bolt {
|
||||||
inline BindingNotFoundDiagnostic(ByteString Name, Node* Initiator):
|
inline BindingNotFoundDiagnostic(ByteString Name, Node* Initiator):
|
||||||
Diagnostic(DiagnosticKind::BindingNotFound), Name(Name), Initiator(Initiator) {}
|
Diagnostic(DiagnosticKind::BindingNotFound), Name(Name), Initiator(Initiator) {}
|
||||||
|
|
||||||
|
inline Node* getNode() const override {
|
||||||
|
return Initiator;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnificationErrorDiagnostic : public Diagnostic {
|
class UnificationErrorDiagnostic : public Diagnostic {
|
||||||
|
@ -88,6 +97,10 @@ namespace bolt {
|
||||||
inline UnificationErrorDiagnostic(Type* Left, Type* Right, TypePath LeftPath, TypePath RightPath, Node* Source):
|
inline UnificationErrorDiagnostic(Type* Left, Type* Right, TypePath LeftPath, TypePath RightPath, Node* Source):
|
||||||
Diagnostic(DiagnosticKind::UnificationError), Left(Left), Right(Right), LeftPath(LeftPath), RightPath(RightPath), Source(Source) {}
|
Diagnostic(DiagnosticKind::UnificationError), Left(Left), Right(Right), LeftPath(LeftPath), RightPath(RightPath), Source(Source) {}
|
||||||
|
|
||||||
|
inline Node* getNode() const override {
|
||||||
|
return Source;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeclassMissingDiagnostic : public Diagnostic {
|
class TypeclassMissingDiagnostic : public Diagnostic {
|
||||||
|
@ -99,6 +112,10 @@ namespace bolt {
|
||||||
inline TypeclassMissingDiagnostic(TypeclassSignature Sig, LetDeclaration* Decl):
|
inline TypeclassMissingDiagnostic(TypeclassSignature Sig, LetDeclaration* Decl):
|
||||||
Diagnostic(DiagnosticKind::TypeclassMissing), Sig(Sig), Decl(Decl) {}
|
Diagnostic(DiagnosticKind::TypeclassMissing), Sig(Sig), Decl(Decl) {}
|
||||||
|
|
||||||
|
inline Node* getNode() const override {
|
||||||
|
return Decl;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class InstanceNotFoundDiagnostic : public Diagnostic {
|
class InstanceNotFoundDiagnostic : public Diagnostic {
|
||||||
|
@ -111,6 +128,10 @@ namespace bolt {
|
||||||
inline InstanceNotFoundDiagnostic(ByteString TypeclassName, TCon* Ty, Node* Source):
|
inline InstanceNotFoundDiagnostic(ByteString TypeclassName, TCon* Ty, Node* Source):
|
||||||
Diagnostic(DiagnosticKind::InstanceNotFound), TypeclassName(TypeclassName), Ty(Ty), Source(Source) {}
|
Diagnostic(DiagnosticKind::InstanceNotFound), TypeclassName(TypeclassName), Ty(Ty), Source(Source) {}
|
||||||
|
|
||||||
|
inline Node* getNode() const override {
|
||||||
|
return Source;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ClassNotFoundDiagnostic : public Diagnostic {
|
class ClassNotFoundDiagnostic : public Diagnostic {
|
||||||
|
@ -138,29 +159,56 @@ namespace bolt {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Type* Actual;
|
Type* Actual;
|
||||||
|
std::vector<TypeclassId> Classes;
|
||||||
|
Node* Source;
|
||||||
|
|
||||||
inline InvalidTypeToTypeclassDiagnostic(Type* Actual):
|
inline InvalidTypeToTypeclassDiagnostic(Type* Actual, std::vector<TypeclassId> Classes, Node* Source):
|
||||||
Diagnostic(DiagnosticKind::InvalidTypeToTypeclass) {}
|
Diagnostic(DiagnosticKind::InvalidTypeToTypeclass), Actual(Actual), Classes(Classes), Source(Source) {}
|
||||||
|
|
||||||
|
inline Node* getNode() const override {
|
||||||
|
return Source;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiagnosticEngine {
|
class DiagnosticEngine {
|
||||||
protected:
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual void addDiagnostic(const Diagnostic& Diagnostic) = 0;
|
virtual void addDiagnostic(Diagnostic* Diagnostic) = 0;
|
||||||
|
|
||||||
template<typename D, typename ...Ts>
|
template<typename D, typename ...Ts>
|
||||||
void add(Ts&&... Args) {
|
void add(Ts&&... Args) {
|
||||||
D Diag { std::forward<Ts>(Args)... };
|
addDiagnostic(new D { std::forward<Ts>(Args)... });
|
||||||
addDiagnostic(Diag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~DiagnosticEngine() {}
|
virtual ~DiagnosticEngine() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps diagnostics alive in-memory until a seperate procedure processes them.
|
||||||
|
*/
|
||||||
|
class DiagnosticStore : public DiagnosticEngine {
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::vector<Diagnostic*> Diagnostics;
|
||||||
|
|
||||||
|
void addDiagnostic(Diagnostic* Diagnostic) {
|
||||||
|
Diagnostics.push_back(Diagnostic);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
Diagnostics.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
~DiagnosticStore() {
|
||||||
|
for (auto D: Diagnostics) {
|
||||||
|
delete D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
enum class Color {
|
enum class Color {
|
||||||
None,
|
None,
|
||||||
Black,
|
Black,
|
||||||
|
@ -198,12 +246,25 @@ namespace bolt {
|
||||||
);
|
);
|
||||||
|
|
||||||
void writeExcerpt(
|
void writeExcerpt(
|
||||||
TextFile& File,
|
const TextFile& File,
|
||||||
TextRange ToPrint,
|
TextRange ToPrint,
|
||||||
TextRange ToHighlight,
|
TextRange ToHighlight,
|
||||||
Color HighlightColor
|
Color HighlightColor
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void writeNode(const Node* N);
|
||||||
|
|
||||||
|
void writePrefix(const Diagnostic& D);
|
||||||
|
void writeBinding(const ByteString& Name);
|
||||||
|
void writeType(std::size_t I);
|
||||||
|
void writeType(const Type* Ty);
|
||||||
|
void writeLoc(const TextFile& File, const TextLoc& Loc);
|
||||||
|
void writeTypeclassName(const ByteString& Name);
|
||||||
|
void writeTypeclassSignature(const TypeclassSignature& Sig);
|
||||||
|
|
||||||
|
void write(const std::string_view& S);
|
||||||
|
void write(std::size_t N);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
unsigned ExcerptLinesPre = 2;
|
unsigned ExcerptLinesPre = 2;
|
||||||
|
@ -213,9 +274,10 @@ namespace bolt {
|
||||||
bool PrintExcerpts = true;
|
bool PrintExcerpts = true;
|
||||||
bool EnableColors = true;
|
bool EnableColors = true;
|
||||||
|
|
||||||
void addDiagnostic(const Diagnostic& Diagnostic) override;
|
|
||||||
|
|
||||||
ConsoleDiagnostics(std::ostream& Out = std::cerr);
|
ConsoleDiagnostics(std::ostream& Out = std::cerr);
|
||||||
|
|
||||||
|
void addDiagnostic(Diagnostic* Diagnostic) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
|
class DiagnosticEngine;
|
||||||
class Scanner;
|
class Scanner;
|
||||||
|
|
||||||
enum OperatorFlags {
|
enum OperatorFlags {
|
||||||
|
@ -62,6 +63,7 @@ namespace bolt {
|
||||||
class Parser {
|
class Parser {
|
||||||
|
|
||||||
TextFile& File;
|
TextFile& File;
|
||||||
|
DiagnosticEngine& DE;
|
||||||
|
|
||||||
Stream<Token*>& Tokens;
|
Stream<Token*>& Tokens;
|
||||||
|
|
||||||
|
@ -90,7 +92,7 @@ namespace bolt {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Parser(TextFile& File, Stream<Token*>& S);
|
Parser(TextFile& File, Stream<Token*>& S, DiagnosticEngine& DE);
|
||||||
|
|
||||||
TypeExpression* parseTypeExpression();
|
TypeExpression* parseTypeExpression();
|
||||||
|
|
||||||
|
|
|
@ -52,9 +52,9 @@ namespace bolt {
|
||||||
|
|
||||||
TextFile(ByteString Path, ByteString Text);
|
TextFile(ByteString Path, ByteString Text);
|
||||||
|
|
||||||
size_t getLine(size_t Offset);
|
size_t getLine(size_t Offset) const;
|
||||||
size_t getColumn(size_t Offset);
|
size_t getColumn(size_t Offset) const;
|
||||||
size_t getStartOffset(size_t Line);
|
size_t getStartOffset(size_t Line) const;
|
||||||
|
|
||||||
size_t getLineCount() const;
|
size_t getLineCount() const;
|
||||||
|
|
||||||
|
|
168
src/CST.cc
168
src/CST.cc
|
@ -92,18 +92,44 @@ namespace bolt {
|
||||||
return Source->Parent->getScope();
|
return Source->Parent->getScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SourceFile* Node::getSourceFile() const {
|
||||||
|
const Node* CurrNode = this;
|
||||||
|
for (;;) {
|
||||||
|
if (CurrNode->Kind == NodeKind::SourceFile) {
|
||||||
|
return static_cast<const SourceFile*>(CurrNode);
|
||||||
|
}
|
||||||
|
CurrNode = CurrNode->Parent;
|
||||||
|
ZEN_ASSERT(CurrNode != nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
SourceFile* Node::getSourceFile() {
|
SourceFile* Node::getSourceFile() {
|
||||||
auto CurrNode = this;
|
Node* CurrNode = this;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (CurrNode->Kind == NodeKind::SourceFile) {
|
if (CurrNode->Kind == NodeKind::SourceFile) {
|
||||||
return static_cast<SourceFile*>(CurrNode);
|
return static_cast<SourceFile*>(CurrNode);
|
||||||
}
|
}
|
||||||
CurrNode = CurrNode->Parent;
|
CurrNode = CurrNode->Parent;
|
||||||
ZEN_ASSERT(CurrNode != nullptr);
|
ZEN_ASSERT(CurrNode != nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextRange Node::getRange() {
|
std::size_t Node::getStartLine() const {
|
||||||
|
return getFirstToken()->getStartLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t Node::getStartColumn() const {
|
||||||
|
return getFirstToken()->getStartColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t Node::getEndLine() const {
|
||||||
|
return getLastToken()->getEndLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t Node::getEndColumn() const {
|
||||||
|
return getLastToken()->getEndColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
TextRange Node::getRange() const {
|
||||||
return TextRange {
|
return TextRange {
|
||||||
getFirstToken()->getStartLoc(),
|
getFirstToken()->getStartLoc(),
|
||||||
getLastToken()->getEndLoc(),
|
getLastToken()->getEndLoc(),
|
||||||
|
@ -169,273 +195,273 @@ namespace bolt {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* TypeclassConstraintExpression::getFirstToken() {
|
Token* TypeclassConstraintExpression::getFirstToken() const {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* TypeclassConstraintExpression::getLastToken() {
|
Token* TypeclassConstraintExpression::getLastToken() const {
|
||||||
if (!TEs.empty()) {
|
if (!TEs.empty()) {
|
||||||
return TEs.back()->getLastToken();
|
return TEs.back()->getLastToken();
|
||||||
}
|
}
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* EqualityConstraintExpression::getFirstToken() {
|
Token* EqualityConstraintExpression::getFirstToken() const {
|
||||||
return Left->getFirstToken();
|
return Left->getFirstToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* EqualityConstraintExpression::getLastToken() {
|
Token* EqualityConstraintExpression::getLastToken() const {
|
||||||
return Left->getLastToken();
|
return Left->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* QualifiedTypeExpression::getFirstToken() {
|
Token* QualifiedTypeExpression::getFirstToken() const {
|
||||||
if (!Constraints.empty()) {
|
if (!Constraints.empty()) {
|
||||||
return std::get<0>(Constraints.front())->getFirstToken();
|
return std::get<0>(Constraints.front())->getFirstToken();
|
||||||
}
|
}
|
||||||
return TE->getFirstToken();
|
return TE->getFirstToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* QualifiedTypeExpression::getLastToken() {
|
Token* QualifiedTypeExpression::getLastToken() const {
|
||||||
return TE->getLastToken();
|
return TE->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ReferenceTypeExpression::getFirstToken() {
|
Token* ReferenceTypeExpression::getFirstToken() const {
|
||||||
if (!ModulePath.empty()) {
|
if (!ModulePath.empty()) {
|
||||||
return std::get<0>(ModulePath.front());
|
return std::get<0>(ModulePath.front());
|
||||||
}
|
}
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ReferenceTypeExpression::getLastToken() {
|
Token* ReferenceTypeExpression::getLastToken() const {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ArrowTypeExpression::getFirstToken() {
|
Token* ArrowTypeExpression::getFirstToken() const {
|
||||||
if (ParamTypes.size()) {
|
if (ParamTypes.size()) {
|
||||||
return ParamTypes.front()->getFirstToken();
|
return ParamTypes.front()->getFirstToken();
|
||||||
}
|
}
|
||||||
return ReturnType->getFirstToken();
|
return ReturnType->getFirstToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ArrowTypeExpression::getLastToken() {
|
Token* ArrowTypeExpression::getLastToken() const {
|
||||||
return ReturnType->getLastToken();
|
return ReturnType->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* VarTypeExpression::getLastToken() {
|
Token* VarTypeExpression::getLastToken() const {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* VarTypeExpression::getFirstToken() {
|
Token* VarTypeExpression::getFirstToken() const {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* NestedTypeExpression::getLastToken() {
|
Token* NestedTypeExpression::getLastToken() const {
|
||||||
return LParen;
|
return LParen;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* NestedTypeExpression::getFirstToken() {
|
Token* NestedTypeExpression::getFirstToken() const {
|
||||||
return RParen;
|
return RParen;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* TupleTypeExpression::getLastToken() {
|
Token* TupleTypeExpression::getLastToken() const {
|
||||||
return LParen;
|
return LParen;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* TupleTypeExpression::getFirstToken() {
|
Token* TupleTypeExpression::getFirstToken() const {
|
||||||
return RParen;
|
return RParen;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* BindPattern::getFirstToken() {
|
Token* BindPattern::getFirstToken() const {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* BindPattern::getLastToken() {
|
Token* BindPattern::getLastToken() const {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* LiteralPattern::getFirstToken() {
|
Token* LiteralPattern::getFirstToken() const {
|
||||||
return Literal;
|
return Literal;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* LiteralPattern::getLastToken() {
|
Token* LiteralPattern::getLastToken() const {
|
||||||
return Literal;
|
return Literal;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ReferenceExpression::getFirstToken() {
|
Token* ReferenceExpression::getFirstToken() const {
|
||||||
if (!ModulePath.empty()) {
|
if (!ModulePath.empty()) {
|
||||||
return std::get<0>(ModulePath.front());
|
return std::get<0>(ModulePath.front());
|
||||||
}
|
}
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ReferenceExpression::getLastToken() {
|
Token* ReferenceExpression::getLastToken() const {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* MatchCase::getFirstToken() {
|
Token* MatchCase::getFirstToken() const {
|
||||||
return Pattern->getFirstToken();
|
return Pattern->getFirstToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* MatchCase::getLastToken() {
|
Token* MatchCase::getLastToken() const {
|
||||||
return Expression->getLastToken();
|
return Expression->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* MatchExpression::getFirstToken() {
|
Token* MatchExpression::getFirstToken() const {
|
||||||
return MatchKeyword;
|
return MatchKeyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* MatchExpression::getLastToken() {
|
Token* MatchExpression::getLastToken() const {
|
||||||
if (!Cases.empty()) {
|
if (!Cases.empty()) {
|
||||||
return Cases.back()->getLastToken();
|
return Cases.back()->getLastToken();
|
||||||
}
|
}
|
||||||
return BlockStart;
|
return BlockStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* MemberExpression::getFirstToken() {
|
Token* MemberExpression::getFirstToken() const {
|
||||||
return E->getFirstToken();
|
return E->getFirstToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* MemberExpression::getLastToken() {
|
Token* MemberExpression::getLastToken() const {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* TupleExpression::getFirstToken() {
|
Token* TupleExpression::getFirstToken() const {
|
||||||
return LParen;
|
return LParen;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* TupleExpression::getLastToken() {
|
Token* TupleExpression::getLastToken() const {
|
||||||
return RParen;
|
return RParen;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* NestedExpression::getFirstToken() {
|
Token* NestedExpression::getFirstToken() const {
|
||||||
return LParen;
|
return LParen;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* NestedExpression::getLastToken() {
|
Token* NestedExpression::getLastToken() const {
|
||||||
return RParen;
|
return RParen;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ConstantExpression::getFirstToken() {
|
Token* ConstantExpression::getFirstToken() const {
|
||||||
return Token;
|
return Token;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ConstantExpression::getLastToken() {
|
Token* ConstantExpression::getLastToken() const {
|
||||||
return Token;
|
return Token;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* CallExpression::getFirstToken() {
|
Token* CallExpression::getFirstToken() const {
|
||||||
return Function->getFirstToken();
|
return Function->getFirstToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* CallExpression::getLastToken() {
|
Token* CallExpression::getLastToken() const {
|
||||||
if (Args.size()) {
|
if (Args.size()) {
|
||||||
return Args.back()->getLastToken();
|
return Args.back()->getLastToken();
|
||||||
}
|
}
|
||||||
return Function->getLastToken();
|
return Function->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* InfixExpression::getFirstToken() {
|
Token* InfixExpression::getFirstToken() const {
|
||||||
return LHS->getFirstToken();
|
return LHS->getFirstToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* InfixExpression::getLastToken() {
|
Token* InfixExpression::getLastToken() const {
|
||||||
return RHS->getLastToken();
|
return RHS->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* PrefixExpression::getFirstToken() {
|
Token* PrefixExpression::getFirstToken() const {
|
||||||
return Operator;
|
return Operator;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* PrefixExpression::getLastToken() {
|
Token* PrefixExpression::getLastToken() const {
|
||||||
return Argument->getLastToken();
|
return Argument->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ExpressionStatement::getFirstToken() {
|
Token* ExpressionStatement::getFirstToken() const {
|
||||||
return Expression->getFirstToken();
|
return Expression->getFirstToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ExpressionStatement::getLastToken() {
|
Token* ExpressionStatement::getLastToken() const {
|
||||||
return Expression->getLastToken();
|
return Expression->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ReturnStatement::getFirstToken() {
|
Token* ReturnStatement::getFirstToken() const {
|
||||||
return ReturnKeyword;
|
return ReturnKeyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ReturnStatement::getLastToken() {
|
Token* ReturnStatement::getLastToken() const {
|
||||||
if (Expression) {
|
if (Expression) {
|
||||||
return Expression->getLastToken();
|
return Expression->getLastToken();
|
||||||
}
|
}
|
||||||
return ReturnKeyword;
|
return ReturnKeyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* IfStatementPart::getFirstToken() {
|
Token* IfStatementPart::getFirstToken() const {
|
||||||
return Keyword;
|
return Keyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* IfStatementPart::getLastToken() {
|
Token* IfStatementPart::getLastToken() const {
|
||||||
if (Elements.size()) {
|
if (Elements.size()) {
|
||||||
return Elements.back()->getLastToken();
|
return Elements.back()->getLastToken();
|
||||||
}
|
}
|
||||||
return BlockStart;
|
return BlockStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* IfStatement::getFirstToken() {
|
Token* IfStatement::getFirstToken() const {
|
||||||
ZEN_ASSERT(Parts.size());
|
ZEN_ASSERT(Parts.size());
|
||||||
return Parts.front()->getFirstToken();
|
return Parts.front()->getFirstToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* IfStatement::getLastToken() {
|
Token* IfStatement::getLastToken() const {
|
||||||
ZEN_ASSERT(Parts.size());
|
ZEN_ASSERT(Parts.size());
|
||||||
return Parts.back()->getLastToken();
|
return Parts.back()->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* TypeAssert::getFirstToken() {
|
Token* TypeAssert::getFirstToken() const {
|
||||||
return Colon;
|
return Colon;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* TypeAssert::getLastToken() {
|
Token* TypeAssert::getLastToken() const {
|
||||||
return TypeExpression->getLastToken();
|
return TypeExpression->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* Parameter::getFirstToken() {
|
Token* Parameter::getFirstToken() const {
|
||||||
return Pattern->getFirstToken();
|
return Pattern->getFirstToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* Parameter::getLastToken() {
|
Token* Parameter::getLastToken() const {
|
||||||
if (TypeAssert) {
|
if (TypeAssert) {
|
||||||
return TypeAssert->getLastToken();
|
return TypeAssert->getLastToken();
|
||||||
}
|
}
|
||||||
return Pattern->getLastToken();
|
return Pattern->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* LetBlockBody::getFirstToken() {
|
Token* LetBlockBody::getFirstToken() const {
|
||||||
return BlockStart;
|
return BlockStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* LetBlockBody::getLastToken() {
|
Token* LetBlockBody::getLastToken() const {
|
||||||
if (Elements.size()) {
|
if (Elements.size()) {
|
||||||
return Elements.back()->getLastToken();
|
return Elements.back()->getLastToken();
|
||||||
}
|
}
|
||||||
return BlockStart;
|
return BlockStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* LetExprBody::getFirstToken() {
|
Token* LetExprBody::getFirstToken() const {
|
||||||
return Equals;
|
return Equals;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* LetExprBody::getLastToken() {
|
Token* LetExprBody::getLastToken() const {
|
||||||
return Expression->getLastToken();
|
return Expression->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* LetDeclaration::getFirstToken() {
|
Token* LetDeclaration::getFirstToken() const {
|
||||||
if (PubKeyword) {
|
if (PubKeyword) {
|
||||||
return PubKeyword;
|
return PubKeyword;
|
||||||
}
|
}
|
||||||
return LetKeyword;
|
return LetKeyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* LetDeclaration::getLastToken() {
|
Token* LetDeclaration::getLastToken() const {
|
||||||
if (Body) {
|
if (Body) {
|
||||||
return Body->getLastToken();
|
return Body->getLastToken();
|
||||||
}
|
}
|
||||||
|
@ -448,61 +474,61 @@ namespace bolt {
|
||||||
return Pattern->getLastToken();
|
return Pattern->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* StructDeclarationField::getFirstToken() {
|
Token* StructDeclarationField::getFirstToken() const {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* StructDeclarationField::getLastToken() {
|
Token* StructDeclarationField::getLastToken() const {
|
||||||
return TypeExpression->getLastToken();
|
return TypeExpression->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* StructDeclaration::getFirstToken() {
|
Token* StructDeclaration::getFirstToken() const {
|
||||||
if (PubKeyword) {
|
if (PubKeyword) {
|
||||||
return PubKeyword;
|
return PubKeyword;
|
||||||
}
|
}
|
||||||
return StructKeyword;
|
return StructKeyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* StructDeclaration::getLastToken() {
|
Token* StructDeclaration::getLastToken() const {
|
||||||
if (Fields.size()) {
|
if (Fields.size()) {
|
||||||
Fields.back()->getLastToken();
|
Fields.back()->getLastToken();
|
||||||
}
|
}
|
||||||
return BlockStart;
|
return BlockStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* InstanceDeclaration::getFirstToken() {
|
Token* InstanceDeclaration::getFirstToken() const {
|
||||||
return InstanceKeyword;
|
return InstanceKeyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* InstanceDeclaration::getLastToken() {
|
Token* InstanceDeclaration::getLastToken() const {
|
||||||
if (!Elements.empty()) {
|
if (!Elements.empty()) {
|
||||||
return Elements.back()->getLastToken();
|
return Elements.back()->getLastToken();
|
||||||
}
|
}
|
||||||
return BlockStart;
|
return BlockStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ClassDeclaration::getFirstToken() {
|
Token* ClassDeclaration::getFirstToken() const {
|
||||||
if (PubKeyword != nullptr) {
|
if (PubKeyword != nullptr) {
|
||||||
return PubKeyword;
|
return PubKeyword;
|
||||||
}
|
}
|
||||||
return ClassKeyword;
|
return ClassKeyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* ClassDeclaration::getLastToken() {
|
Token* ClassDeclaration::getLastToken() const {
|
||||||
if (!Elements.empty()) {
|
if (!Elements.empty()) {
|
||||||
return Elements.back()->getLastToken();
|
return Elements.back()->getLastToken();
|
||||||
}
|
}
|
||||||
return BlockStart;
|
return BlockStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* SourceFile::getFirstToken() {
|
Token* SourceFile::getFirstToken() const {
|
||||||
if (Elements.size()) {
|
if (Elements.size()) {
|
||||||
return Elements.front()->getFirstToken();
|
return Elements.front()->getFirstToken();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* SourceFile::getLastToken() {
|
Token* SourceFile::getLastToken() const {
|
||||||
if (Elements.size()) {
|
if (Elements.size()) {
|
||||||
return Elements.back()->getLastToken();
|
return Elements.back()->getLastToken();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1064,7 +1064,7 @@ namespace bolt {
|
||||||
propagateClassTycon(Class, llvm::cast<TCon>(Ty));
|
propagateClassTycon(Class, llvm::cast<TCon>(Ty));
|
||||||
}
|
}
|
||||||
} else if (!Classes.empty()) {
|
} else if (!Classes.empty()) {
|
||||||
DE.add<InvalidTypeToTypeclassDiagnostic>(Ty);
|
DE.add<InvalidTypeToTypeclassDiagnostic>(Ty, std::vector(Classes.begin(), Classes.end()), Source);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "bolt/CST.hpp"
|
|
||||||
#include "zen/config.hpp"
|
#include "zen/config.hpp"
|
||||||
|
|
||||||
|
#include "bolt/CST.hpp"
|
||||||
|
#include "bolt/Type.hpp"
|
||||||
#include "bolt/Diagnostics.hpp"
|
#include "bolt/Diagnostics.hpp"
|
||||||
#include "bolt/Checker.hpp"
|
|
||||||
|
|
||||||
#define ANSI_RESET "\u001b[0m"
|
#define ANSI_RESET "\u001b[0m"
|
||||||
#define ANSI_BOLD "\u001b[1m"
|
#define ANSI_BOLD "\u001b[1m"
|
||||||
|
@ -314,7 +314,7 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDiagnostics::writeExcerpt(
|
void ConsoleDiagnostics::writeExcerpt(
|
||||||
TextFile& File,
|
const TextFile& File,
|
||||||
TextRange ToPrint,
|
TextRange ToPrint,
|
||||||
TextRange ToHighlight,
|
TextRange ToHighlight,
|
||||||
Color HighlightColor
|
Color HighlightColor
|
||||||
|
@ -353,166 +353,259 @@ namespace bolt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDiagnostics::addDiagnostic(const Diagnostic& D) {
|
void ConsoleDiagnostics::write(const std::string_view& S) {
|
||||||
|
Out << S;
|
||||||
|
}
|
||||||
|
|
||||||
switch (D.getKind()) {
|
void ConsoleDiagnostics::write(std::size_t I) {
|
||||||
|
Out << I;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleDiagnostics::writeBinding(const ByteString& Name) {
|
||||||
|
write("'");
|
||||||
|
write(Name);
|
||||||
|
write("'");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleDiagnostics::writeType(const Type* Ty) {
|
||||||
|
setForegroundColor(Color::Green);
|
||||||
|
write(describe(Ty));
|
||||||
|
resetStyles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleDiagnostics::writeType(std::size_t I) {
|
||||||
|
setForegroundColor(Color::Green);
|
||||||
|
write(I);
|
||||||
|
resetStyles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleDiagnostics::writeNode(const Node* N) {
|
||||||
|
auto Range = N->getRange();
|
||||||
|
writeExcerpt(N->getSourceFile()->getTextFile(), Range, Range, Color::Red);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleDiagnostics::writeLoc(const TextFile& File, const TextLoc& Loc) {
|
||||||
|
setForegroundColor(Color::Yellow);
|
||||||
|
write(File.getPath());
|
||||||
|
write(":");
|
||||||
|
write(Loc.Line);
|
||||||
|
write(":");
|
||||||
|
write(Loc.Column);
|
||||||
|
write(":");
|
||||||
|
resetStyles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleDiagnostics::writePrefix(const Diagnostic& D) {
|
||||||
|
setForegroundColor(Color::Red);
|
||||||
|
setBold(true);
|
||||||
|
write("error: ");
|
||||||
|
resetStyles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleDiagnostics::writeTypeclassName(const ByteString& Name) {
|
||||||
|
setForegroundColor(Color::Magenta);
|
||||||
|
write(Name);
|
||||||
|
resetStyles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleDiagnostics::writeTypeclassSignature(const TypeclassSignature& Sig) {
|
||||||
|
setForegroundColor(Color::Magenta);
|
||||||
|
write(Sig.Id);
|
||||||
|
for (auto TV: Sig.Params) {
|
||||||
|
write(" ");
|
||||||
|
write(describe(TV));
|
||||||
|
}
|
||||||
|
resetStyles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleDiagnostics::addDiagnostic(Diagnostic* D) {
|
||||||
|
|
||||||
|
switch (D->getKind()) {
|
||||||
|
|
||||||
case DiagnosticKind::BindingNotFound:
|
case DiagnosticKind::BindingNotFound:
|
||||||
{
|
{
|
||||||
auto E = static_cast<const BindingNotFoundDiagnostic&>(D);
|
auto E = static_cast<const BindingNotFoundDiagnostic&>(*D);
|
||||||
Out << ANSI_BOLD ANSI_FG_RED "error: " ANSI_RESET "binding '" << E.Name << "' was not found\n\n";
|
writePrefix(E);
|
||||||
|
write("binding '");
|
||||||
|
writeBinding(E.Name);
|
||||||
|
write(" was not found\n\n");
|
||||||
if (E.Initiator != nullptr) {
|
if (E.Initiator != nullptr) {
|
||||||
auto Range = E.Initiator->getRange();
|
auto Range = E.Initiator->getRange();
|
||||||
//std::cerr << Range.Start.Line << ":" << Range.Start.Column << "-" << Range.End.Line << ":" << Range.End.Column << "\n";
|
//std::cerr << Range.Start.Line << ":" << Range.Start.Column << "-" << Range.End.Line << ":" << Range.End.Column << "\n";
|
||||||
writeExcerpt(E.Initiator->getSourceFile()->getTextFile(), Range, Range, Color::Red);
|
writeExcerpt(E.Initiator->getSourceFile()->getTextFile(), Range, Range, Color::Red);
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
}
|
}
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DiagnosticKind::UnexpectedToken:
|
case DiagnosticKind::UnexpectedToken:
|
||||||
{
|
{
|
||||||
auto E = static_cast<const UnexpectedTokenDiagnostic&>(D);
|
auto E = static_cast<const UnexpectedTokenDiagnostic&>(*D);
|
||||||
setForegroundColor(Color::Red);
|
writePrefix(E);
|
||||||
setBold(true);
|
writeLoc(E.File, E.Actual->getStartLoc());
|
||||||
Out << "error: ";
|
write(" expected ");
|
||||||
resetStyles();
|
|
||||||
setForegroundColor(Color::Yellow);
|
|
||||||
Out << E.File.getPath() << ":" << E.Actual->getStartLine() << ":" << E.Actual->getStartColumn() << ":";
|
|
||||||
resetStyles();
|
|
||||||
Out << " expected ";
|
|
||||||
switch (E.Expected.size()) {
|
switch (E.Expected.size()) {
|
||||||
case 0:
|
case 0:
|
||||||
Out << "nothing";
|
write("nothing");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
Out << describe(E.Expected[0]);
|
write(describe(E.Expected[0]));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
auto Iter = E.Expected.begin();
|
auto Iter = E.Expected.begin();
|
||||||
Out << describe(*Iter++);
|
Out << describe(*Iter++);
|
||||||
NodeKind Prev = *Iter++;
|
NodeKind Prev = *Iter++;
|
||||||
while (Iter != E.Expected.end()) {
|
while (Iter != E.Expected.end()) {
|
||||||
Out << ", " << describe(Prev);
|
write(", ");
|
||||||
|
write(describe(Prev));
|
||||||
Prev = *Iter++;
|
Prev = *Iter++;
|
||||||
}
|
}
|
||||||
Out << " or " << describe(Prev);
|
write(" or ");
|
||||||
|
write(describe(Prev));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Out << " but instead got '" << E.Actual->getText() << "'\n\n";
|
write(" but instead got '");
|
||||||
|
write(E.Actual->getText());
|
||||||
|
write("'\n\n");
|
||||||
writeExcerpt(E.File, E.Actual->getRange(), E.Actual->getRange(), Color::Red);
|
writeExcerpt(E.File, E.Actual->getRange(), E.Actual->getRange(), Color::Red);
|
||||||
Out << "\n";
|
write("\n");
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DiagnosticKind::UnexpectedString:
|
case DiagnosticKind::UnexpectedString:
|
||||||
{
|
{
|
||||||
auto E = static_cast<const UnexpectedStringDiagnostic&>(D);
|
auto E = static_cast<const UnexpectedStringDiagnostic&>(*D);
|
||||||
setForegroundColor(Color::Red);
|
writePrefix(E);
|
||||||
setBold(true);
|
writeLoc(E.File, E.Location);
|
||||||
Out << "error: ";
|
write(" unexpected '");
|
||||||
resetStyles();
|
|
||||||
Out << E.File.getPath() << ":" << E.Location.Line << ":" << E.Location.Column << ": unexpected '";
|
|
||||||
for (auto Chr: E.Actual) {
|
for (auto Chr: E.Actual) {
|
||||||
switch (Chr) {
|
switch (Chr) {
|
||||||
case '\\':
|
case '\\':
|
||||||
Out << "\\\\";
|
write("\\\\");
|
||||||
break;
|
break;
|
||||||
case '\'':
|
case '\'':
|
||||||
Out << "\\'";
|
write("\\'");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Out << Chr;
|
write(Chr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Out << "'\n\n";
|
write("'\n\n");
|
||||||
TextRange Range { E.Location, E.Location + E.Actual };
|
TextRange Range { E.Location, E.Location + E.Actual };
|
||||||
writeExcerpt(E.File, Range, Range, Color::Red);
|
writeExcerpt(E.File, Range, Range, Color::Red);
|
||||||
Out << "\n";
|
write("\n");
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DiagnosticKind::UnificationError:
|
case DiagnosticKind::UnificationError:
|
||||||
{
|
{
|
||||||
auto E = static_cast<const UnificationErrorDiagnostic&>(D);
|
auto E = static_cast<const UnificationErrorDiagnostic&>(*D);
|
||||||
setForegroundColor(Color::Red);
|
writePrefix(E);
|
||||||
setBold(true);
|
|
||||||
Out << "error: ";
|
|
||||||
resetStyles();
|
|
||||||
auto Left = E.Left->resolve(E.LeftPath);
|
auto Left = E.Left->resolve(E.LeftPath);
|
||||||
auto Right = E.Right->resolve(E.RightPath);
|
auto Right = E.Right->resolve(E.RightPath);
|
||||||
Out << "the types " << ANSI_FG_GREEN << describe(Left) << ANSI_RESET
|
write("the types ");
|
||||||
<< " and " << ANSI_FG_GREEN << describe(Right) << ANSI_RESET << " failed to match\n\n";
|
writeType(Left);
|
||||||
|
write(" and ");
|
||||||
|
writeType(Right);
|
||||||
|
write(" failed to match\n\n");
|
||||||
if (E.Source) {
|
if (E.Source) {
|
||||||
auto Range = E.Source->getRange();
|
writeNode(E.Source);
|
||||||
writeExcerpt(E.Source->getSourceFile()->getTextFile(), Range, Range, Color::Red);
|
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
}
|
}
|
||||||
if (!E.LeftPath.empty()) {
|
if (!E.LeftPath.empty()) {
|
||||||
setForegroundColor(Color::Yellow);
|
setForegroundColor(Color::Yellow);
|
||||||
setBold(true);
|
setBold(true);
|
||||||
Out << " info: ";
|
write(" info: ");
|
||||||
resetStyles();
|
resetStyles();
|
||||||
Out << "type " << ANSI_FG_GREEN << describe(Left) << ANSI_RESET << " occurs in the full type " << ANSI_FG_GREEN << describe(E.Left) << ANSI_RESET << "\n\n";
|
write("the type ");
|
||||||
|
writeType(Left);
|
||||||
|
write(" occurs in the full type ");
|
||||||
|
writeType(E.Left);
|
||||||
|
write("\n\n");
|
||||||
}
|
}
|
||||||
if (!E.RightPath.empty()) {
|
if (!E.RightPath.empty()) {
|
||||||
setForegroundColor(Color::Yellow);
|
setForegroundColor(Color::Yellow);
|
||||||
setBold(true);
|
setBold(true);
|
||||||
Out << " info: ";
|
write(" info: ");
|
||||||
resetStyles();
|
resetStyles();
|
||||||
Out << "type " << ANSI_FG_GREEN << describe(Right) << ANSI_RESET << " occurs in the full type " << ANSI_FG_GREEN << describe(E.Right) << ANSI_RESET << "\n\n";
|
write("the type ");
|
||||||
|
writeType(Right);
|
||||||
|
write(" occurs in the full type ");
|
||||||
|
writeType(E.Right);
|
||||||
|
write("\n\n");
|
||||||
}
|
}
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DiagnosticKind::TypeclassMissing:
|
case DiagnosticKind::TypeclassMissing:
|
||||||
{
|
{
|
||||||
auto E = static_cast<const TypeclassMissingDiagnostic&>(D);
|
auto E = static_cast<const TypeclassMissingDiagnostic&>(*D);
|
||||||
setForegroundColor(Color::Red);
|
writePrefix(E);
|
||||||
setBold(true);
|
write("the type class ");
|
||||||
Out << "error: ";
|
writeTypeclassSignature(E.Sig);
|
||||||
resetStyles();
|
write(" is missing from the declaration's type signature\n\n");
|
||||||
Out << "the type class " << ANSI_FG_YELLOW << E.Sig.Id;
|
writeNode(E.Decl);
|
||||||
for (auto TV: E.Sig.Params) {
|
write("\n\n");
|
||||||
Out << " " << describe(TV);
|
break;
|
||||||
}
|
|
||||||
Out << ANSI_RESET << " is missing from the declaration's type signature\n\n";
|
|
||||||
auto Range = E.Decl->getRange();
|
|
||||||
writeExcerpt(E.Decl->getSourceFile()->getTextFile(), Range, Range, Color::Yellow);
|
|
||||||
Out << "\n\n";
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case DiagnosticKind::InstanceNotFound:
|
case DiagnosticKind::InstanceNotFound:
|
||||||
{
|
{
|
||||||
auto E = static_cast<const InstanceNotFoundDiagnostic&>(D);
|
auto E = static_cast<const InstanceNotFoundDiagnostic&>(*D);
|
||||||
setForegroundColor(Color::Red);
|
writePrefix(E);
|
||||||
setBold(true);
|
write("a type class instance ");
|
||||||
Out << "error: ";
|
writeTypeclassName(E.TypeclassName);
|
||||||
resetStyles();
|
writeType(E.Ty);
|
||||||
Out << "a type class instance " << ANSI_FG_YELLOW << E.TypeclassName << " " << describe(E.Ty) << ANSI_RESET " was not found.\n\n";
|
write(" was not found.\n\n");
|
||||||
auto Range = E.Source->getRange();
|
writeNode(E.Source);
|
||||||
//std::cerr << Range.Start.Line << ":" << Range.Start.Column << "-" << Range.End.Line << ":" << Range.End.Column << "\n";
|
write("\n");
|
||||||
writeExcerpt(E.Source->getSourceFile()->getTextFile(), Range, Range, Color::Red);
|
break;
|
||||||
Out << "\n";
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case DiagnosticKind::ClassNotFound:
|
case DiagnosticKind::ClassNotFound:
|
||||||
{
|
{
|
||||||
auto E = static_cast<const ClassNotFoundDiagnostic&>(D);
|
auto E = static_cast<const ClassNotFoundDiagnostic&>(*D);
|
||||||
setForegroundColor(Color::Red);
|
writePrefix(E);
|
||||||
setBold(true);
|
write("the type class ");
|
||||||
Out << "error: ";
|
writeTypeclassName(E.Name);
|
||||||
resetStyles();
|
write(" was not found.\n\n");
|
||||||
Out << "the type class " << ANSI_FG_YELLOW << E.Name << ANSI_RESET " was not found.\n\n";
|
break;
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
case DiagnosticKind::TupleIndexOutOfRange:
|
||||||
|
{
|
||||||
|
auto E = static_cast<const TupleIndexOutOfRangeDiagnostic&>(*D);
|
||||||
|
writePrefix(E);
|
||||||
|
write("the index ");
|
||||||
|
writeType(E.I);
|
||||||
|
write(" is out of range for tuple ");
|
||||||
|
writeType(E.Tuple);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DiagnosticKind::InvalidTypeToTypeclass:
|
||||||
|
{
|
||||||
|
auto E = static_cast<const InvalidTypeToTypeclassDiagnostic&>(*D);
|
||||||
|
writePrefix(E);
|
||||||
|
write("the type ");
|
||||||
|
writeType(E.Actual);
|
||||||
|
write(" was applied to type class names ");
|
||||||
|
bool First = true;
|
||||||
|
for (auto Class: E.Classes) {
|
||||||
|
if (First) First = false;
|
||||||
|
else write(", ");
|
||||||
|
writeTypeclassName(Class);
|
||||||
|
}
|
||||||
|
write(" but this is invalid\n\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZEN_UNREACHABLE
|
// Since this DiagnosticEngine is expected to own the diagnostic, we simply
|
||||||
|
// destroy the processed diagnostic so that there are no memory leaks.
|
||||||
|
delete D;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,8 @@ namespace bolt {
|
||||||
Mapping.emplace(Name, OperatorInfo { Precedence, Flags });
|
Mapping.emplace(Name, OperatorInfo { Precedence, Flags });
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::Parser(TextFile& File, Stream<Token*>& S):
|
Parser::Parser(TextFile& File, Stream<Token*>& S, DiagnosticEngine& DE):
|
||||||
File(File), Tokens(S) {
|
File(File), Tokens(S), DE(DE) {
|
||||||
ExprOperators.add("**", OperatorFlags_InfixR, 10);
|
ExprOperators.add("**", OperatorFlags_InfixR, 10);
|
||||||
ExprOperators.add("*", OperatorFlags_InfixL, 5);
|
ExprOperators.add("*", OperatorFlags_InfixL, 5);
|
||||||
ExprOperators.add("/", OperatorFlags_InfixL, 5);
|
ExprOperators.add("/", OperatorFlags_InfixL, 5);
|
||||||
|
|
|
@ -22,11 +22,11 @@ namespace bolt {
|
||||||
return LineOffsets.size();
|
return LineOffsets.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TextFile::getStartOffset(size_t Line) {
|
size_t TextFile::getStartOffset(size_t Line) const {
|
||||||
return LineOffsets[Line-1];
|
return LineOffsets[Line-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TextFile::getLine(size_t Offset) {
|
size_t TextFile::getLine(size_t Offset) const {
|
||||||
ZEN_ASSERT(Offset < Text.size());
|
ZEN_ASSERT(Offset < Text.size());
|
||||||
for (size_t I = 0; I < LineOffsets.size(); ++I) {
|
for (size_t I = 0; I < LineOffsets.size(); ++I) {
|
||||||
if (LineOffsets[I] > Offset) {
|
if (LineOffsets[I] > Offset) {
|
||||||
|
@ -36,7 +36,7 @@ namespace bolt {
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TextFile::getColumn(size_t Offset) {
|
size_t TextFile::getColumn(size_t Offset) const {
|
||||||
auto Line = getLine(Offset);
|
auto Line = getLine(Offset);
|
||||||
auto StartOffset = getStartOffset(Line);
|
auto StartOffset = getStartOffset(Line);
|
||||||
return Offset - StartOffset + 1 ;
|
return Offset - StartOffset + 1 ;
|
||||||
|
|
34
src/main.cc
34
src/main.cc
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "zen/config.hpp"
|
#include "zen/config.hpp"
|
||||||
|
|
||||||
|
@ -44,22 +45,39 @@ int main(int argc, const char* argv[]) {
|
||||||
VectorStream<ByteString, Char> Chars(Text, EOF);
|
VectorStream<ByteString, Char> Chars(Text, EOF);
|
||||||
Scanner S(File, Chars);
|
Scanner S(File, Chars);
|
||||||
Punctuator PT(S);
|
Punctuator PT(S);
|
||||||
Parser P(File, PT);
|
Parser P(File, PT, DE);
|
||||||
|
|
||||||
SourceFile* SF;
|
auto SF = P.parseSourceFile();
|
||||||
|
if (SF == nullptr) {
|
||||||
try {
|
|
||||||
SF = P.parseSourceFile();
|
|
||||||
} catch (Diagnostic& D) {
|
|
||||||
DE.addDiagnostic(D);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SF->setParents();
|
SF->setParents();
|
||||||
|
|
||||||
Checker TheChecker { Config, DE };
|
DiagnosticStore DS;
|
||||||
|
Checker TheChecker { Config, DS };
|
||||||
TheChecker.check(SF);
|
TheChecker.check(SF);
|
||||||
|
|
||||||
|
auto LT = [](const Diagnostic* L, const Diagnostic* R) {
|
||||||
|
auto N1 = L->getNode();
|
||||||
|
auto N2 = R->getNode();
|
||||||
|
if (N1 == nullptr && N2 == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (N1 == nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (N2 == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return N1->getStartLine() < N2->getStartLine() || N1->getStartColumn() < N2->getStartColumn();
|
||||||
|
};
|
||||||
|
std::sort(DS.Diagnostics.begin(), DS.Diagnostics.end(), LT);
|
||||||
|
|
||||||
|
for (auto D: DS.Diagnostics) {
|
||||||
|
DE.addDiagnostic(D);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue