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