Add more methods to bolt::Node and improve diagnostics
This commit is contained in:
parent
a4a2b4cca5
commit
fb69ab745c
10 changed files with 814 additions and 83 deletions
|
@ -1,6 +1,7 @@
|
|||
#ifndef BOLT_CST_HPP
|
||||
#define BOLT_CST_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include "bolt/Text.hpp"
|
||||
|
@ -57,29 +58,41 @@ namespace bolt {
|
|||
SourceFile,
|
||||
};
|
||||
|
||||
class Token;
|
||||
class SourceFile;
|
||||
|
||||
class Node {
|
||||
|
||||
unsigned refcount = 0;
|
||||
unsigned RefCount = 0;
|
||||
|
||||
public:
|
||||
|
||||
Node* Parent = nullptr;
|
||||
|
||||
inline void ref() {
|
||||
++refcount;
|
||||
++RefCount;
|
||||
}
|
||||
|
||||
inline void unref() {
|
||||
--refcount;
|
||||
if (refcount == 0) {
|
||||
--RefCount;
|
||||
if (RefCount == 0) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void setParents() = 0;
|
||||
|
||||
virtual Token* getFirstToken() = 0;
|
||||
virtual Token* getLastToken() = 0;
|
||||
|
||||
TextRange getRange();
|
||||
|
||||
const NodeType Type;
|
||||
|
||||
inline Node(NodeType Type):
|
||||
Type(Type) {}
|
||||
|
||||
SourceFile* getSourceFile();
|
||||
|
||||
virtual ~Node();
|
||||
|
||||
|
@ -95,6 +108,16 @@ namespace bolt {
|
|||
|
||||
virtual std::string getText() const = 0;
|
||||
|
||||
void setParents() override;
|
||||
|
||||
inline Token* getFirstToken() override {
|
||||
return this;
|
||||
}
|
||||
|
||||
inline Token* getLastToken() override {
|
||||
return this;
|
||||
}
|
||||
|
||||
inline TextLoc getStartLoc() {
|
||||
return StartLoc;
|
||||
}
|
||||
|
@ -128,7 +151,8 @@ namespace bolt {
|
|||
class Equals : public Token {
|
||||
public:
|
||||
|
||||
Equals(TextLoc StartLoc): Token(NodeType::Equals, StartLoc) {}
|
||||
Equals(TextLoc StartLoc):
|
||||
Token(NodeType::Equals, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -139,7 +163,8 @@ namespace bolt {
|
|||
class Colon : public Token {
|
||||
public:
|
||||
|
||||
Colon(TextLoc StartLoc): Token(NodeType::Colon, StartLoc) {}
|
||||
Colon(TextLoc StartLoc):
|
||||
Token(NodeType::Colon, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -150,7 +175,8 @@ namespace bolt {
|
|||
class Dot : public Token {
|
||||
public:
|
||||
|
||||
Dot(TextLoc StartLoc): Token(NodeType::Dot, StartLoc) {}
|
||||
Dot(TextLoc StartLoc):
|
||||
Token(NodeType::Dot, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -161,7 +187,8 @@ namespace bolt {
|
|||
class DotDot : public Token {
|
||||
public:
|
||||
|
||||
DotDot(TextLoc StartLoc): Token(NodeType::DotDot, StartLoc) {}
|
||||
DotDot(TextLoc StartLoc):
|
||||
Token(NodeType::DotDot, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -172,7 +199,8 @@ namespace bolt {
|
|||
class LParen : public Token {
|
||||
public:
|
||||
|
||||
LParen(TextLoc StartLoc): Token(NodeType::LParen, StartLoc) {}
|
||||
LParen(TextLoc StartLoc):
|
||||
Token(NodeType::LParen, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -183,7 +211,8 @@ namespace bolt {
|
|||
class RParen : public Token {
|
||||
public:
|
||||
|
||||
RParen(TextLoc StartLoc): Token(NodeType::RParen, StartLoc) {}
|
||||
RParen(TextLoc StartLoc):
|
||||
Token(NodeType::RParen, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -194,7 +223,8 @@ namespace bolt {
|
|||
class LBracket : public Token {
|
||||
public:
|
||||
|
||||
LBracket(TextLoc StartLoc): Token(NodeType::LBracket, StartLoc) {}
|
||||
LBracket(TextLoc StartLoc):
|
||||
Token(NodeType::LBracket, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -205,7 +235,8 @@ namespace bolt {
|
|||
class RBracket : public Token {
|
||||
public:
|
||||
|
||||
RBracket(TextLoc StartLoc): Token(NodeType::RBracket, StartLoc) {}
|
||||
RBracket(TextLoc StartLoc):
|
||||
Token(NodeType::RBracket, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -216,7 +247,8 @@ namespace bolt {
|
|||
class LBrace : public Token {
|
||||
public:
|
||||
|
||||
LBrace(TextLoc StartLoc): Token(NodeType::LBrace, StartLoc) {}
|
||||
LBrace(TextLoc StartLoc):
|
||||
Token(NodeType::LBrace, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -227,7 +259,8 @@ namespace bolt {
|
|||
class RBrace : public Token {
|
||||
public:
|
||||
|
||||
RBrace(TextLoc StartLoc): Token(NodeType::RBrace, StartLoc) {}
|
||||
RBrace(TextLoc StartLoc):
|
||||
Token(NodeType::RBrace, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -238,7 +271,8 @@ namespace bolt {
|
|||
class LetKeyword : public Token {
|
||||
public:
|
||||
|
||||
LetKeyword(TextLoc StartLoc): Token(NodeType::LetKeyword, StartLoc) {}
|
||||
LetKeyword(TextLoc StartLoc):
|
||||
Token(NodeType::LetKeyword, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -249,7 +283,8 @@ namespace bolt {
|
|||
class MutKeyword : public Token {
|
||||
public:
|
||||
|
||||
MutKeyword(TextLoc StartLoc): Token(NodeType::MutKeyword, StartLoc) {}
|
||||
MutKeyword(TextLoc StartLoc):
|
||||
Token(NodeType::MutKeyword, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -260,7 +295,8 @@ namespace bolt {
|
|||
class PubKeyword : public Token {
|
||||
public:
|
||||
|
||||
PubKeyword(TextLoc StartLoc): Token(NodeType::PubKeyword, StartLoc) {}
|
||||
PubKeyword(TextLoc StartLoc):
|
||||
Token(NodeType::PubKeyword, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -271,7 +307,8 @@ namespace bolt {
|
|||
class TypeKeyword : public Token {
|
||||
public:
|
||||
|
||||
TypeKeyword(TextLoc StartLoc): Token(NodeType::TypeKeyword, StartLoc) {}
|
||||
TypeKeyword(TextLoc StartLoc):
|
||||
Token(NodeType::TypeKeyword, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -282,7 +319,8 @@ namespace bolt {
|
|||
class ReturnKeyword : public Token {
|
||||
public:
|
||||
|
||||
ReturnKeyword(TextLoc StartLoc): Token(NodeType::ReturnKeyword, StartLoc) {}
|
||||
ReturnKeyword(TextLoc StartLoc):
|
||||
Token(NodeType::ReturnKeyword, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -293,7 +331,8 @@ namespace bolt {
|
|||
class ModKeyword : public Token {
|
||||
public:
|
||||
|
||||
ModKeyword(TextLoc StartLoc): Token(NodeType::ModKeyword, StartLoc) {}
|
||||
ModKeyword(TextLoc StartLoc):
|
||||
Token(NodeType::ModKeyword, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -304,7 +343,8 @@ namespace bolt {
|
|||
class StructKeyword : public Token {
|
||||
public:
|
||||
|
||||
StructKeyword(TextLoc StartLoc): Token(NodeType::StructKeyword, StartLoc) {}
|
||||
StructKeyword(TextLoc StartLoc):
|
||||
Token(NodeType::StructKeyword, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -315,7 +355,8 @@ namespace bolt {
|
|||
class Invalid : public Token {
|
||||
public:
|
||||
|
||||
Invalid(TextLoc StartLoc): Token(NodeType::Invalid, StartLoc) {}
|
||||
Invalid(TextLoc StartLoc):
|
||||
Token(NodeType::Invalid, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -326,7 +367,8 @@ namespace bolt {
|
|||
class EndOfFile : public Token {
|
||||
public:
|
||||
|
||||
EndOfFile(TextLoc StartLoc): Token(NodeType::EndOfFile, StartLoc) {}
|
||||
EndOfFile(TextLoc StartLoc):
|
||||
Token(NodeType::EndOfFile, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -337,7 +379,8 @@ namespace bolt {
|
|||
class BlockStart : public Token {
|
||||
public:
|
||||
|
||||
BlockStart(TextLoc StartLoc): Token(NodeType::BlockStart, StartLoc) {}
|
||||
BlockStart(TextLoc StartLoc):
|
||||
Token(NodeType::BlockStart, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -348,7 +391,8 @@ namespace bolt {
|
|||
class BlockEnd : public Token {
|
||||
public:
|
||||
|
||||
BlockEnd(TextLoc StartLoc): Token(NodeType::BlockEnd, StartLoc) {}
|
||||
BlockEnd(TextLoc StartLoc):
|
||||
Token(NodeType::BlockEnd, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -359,7 +403,8 @@ namespace bolt {
|
|||
class LineFoldEnd : public Token {
|
||||
public:
|
||||
|
||||
LineFoldEnd(TextLoc StartLoc): Token(NodeType::LineFoldEnd, StartLoc) {}
|
||||
LineFoldEnd(TextLoc StartLoc):
|
||||
Token(NodeType::LineFoldEnd, StartLoc) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -372,7 +417,8 @@ namespace bolt {
|
|||
|
||||
ByteString Text;
|
||||
|
||||
CustomOperator(ByteString Text, TextLoc StartLoc): Token(NodeType::CustomOperator, StartLoc), Text(Text) {}
|
||||
CustomOperator(ByteString Text, TextLoc StartLoc):
|
||||
Token(NodeType::CustomOperator, StartLoc), Text(Text) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -385,7 +431,8 @@ namespace bolt {
|
|||
|
||||
ByteString Text;
|
||||
|
||||
Assignment(ByteString Text, TextLoc StartLoc): Token(NodeType::Assignment, StartLoc), Text(Text) {}
|
||||
Assignment(ByteString Text, TextLoc StartLoc):
|
||||
Token(NodeType::Assignment, StartLoc), Text(Text) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -398,7 +445,8 @@ namespace bolt {
|
|||
|
||||
ByteString Text;
|
||||
|
||||
Identifier(ByteString Text, TextLoc StartLoc): Token(NodeType::Identifier, StartLoc), Text(Text) {}
|
||||
Identifier(ByteString Text, TextLoc StartLoc):
|
||||
Token(NodeType::Identifier, StartLoc), Text(Text) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -411,7 +459,8 @@ namespace bolt {
|
|||
|
||||
ByteString Text;
|
||||
|
||||
StringLiteral(ByteString Text, TextLoc StartLoc): Token(NodeType::StringLiteral, StartLoc), Text(Text) {}
|
||||
StringLiteral(ByteString Text, TextLoc StartLoc):
|
||||
Token(NodeType::StringLiteral, StartLoc), Text(Text) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -424,7 +473,8 @@ namespace bolt {
|
|||
|
||||
Integer Value;
|
||||
|
||||
IntegerLiteral(Integer Value, TextLoc StartLoc): Token(NodeType::IntegerLiteral, StartLoc), Value(Value) {}
|
||||
IntegerLiteral(Integer Value, TextLoc StartLoc):
|
||||
Token(NodeType::IntegerLiteral, StartLoc), Value(Value) {}
|
||||
|
||||
std::string getText() const override;
|
||||
|
||||
|
@ -445,6 +495,11 @@ namespace bolt {
|
|||
ModulePath(ModulePath),
|
||||
Name(Name) {}
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
void setParents() override;
|
||||
|
||||
~QualifiedName();
|
||||
|
||||
};
|
||||
|
@ -468,6 +523,11 @@ namespace bolt {
|
|||
): TypeExpression(NodeType::ReferenceTypeExpression),
|
||||
Name(Name) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~ReferenceTypeExpression();
|
||||
|
||||
};
|
||||
|
@ -491,6 +551,11 @@ namespace bolt {
|
|||
): Pattern(NodeType::BindPattern),
|
||||
Name(Name) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~BindPattern();
|
||||
|
||||
};
|
||||
|
@ -507,13 +572,18 @@ namespace bolt {
|
|||
class ReferenceExpression : public Expression {
|
||||
public:
|
||||
|
||||
Identifier* Name;
|
||||
QualifiedName* Name;
|
||||
|
||||
ReferenceExpression(
|
||||
Identifier* Name
|
||||
QualifiedName* Name
|
||||
): Expression(NodeType::ReferenceExpression),
|
||||
Name(Name) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~ReferenceExpression();
|
||||
|
||||
};
|
||||
|
@ -528,6 +598,11 @@ namespace bolt {
|
|||
): Expression(NodeType::ConstantExpression),
|
||||
Token(Token) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
class Token* getFirstToken() override;
|
||||
class Token* getLastToken() override;
|
||||
|
||||
~ConstantExpression();
|
||||
|
||||
};
|
||||
|
@ -535,11 +610,21 @@ namespace bolt {
|
|||
class CallExpression : public Expression {
|
||||
public:
|
||||
|
||||
CallExpression(Expression* Function, std::vector<Expression*> Args): Expression(NodeType::CallExpression), Function(Function), Args(Args) {}
|
||||
|
||||
Expression* Function;
|
||||
std::vector<Expression*> Args;
|
||||
|
||||
CallExpression(
|
||||
Expression* Function,
|
||||
std::vector<Expression*> Args
|
||||
): Expression(NodeType::CallExpression),
|
||||
Function(Function),
|
||||
Args(Args) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~CallExpression();
|
||||
|
||||
};
|
||||
|
@ -557,6 +642,11 @@ namespace bolt {
|
|||
Operator(Operator),
|
||||
RHS(RHS) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~InfixExpression();
|
||||
|
||||
};
|
||||
|
@ -574,6 +664,11 @@ namespace bolt {
|
|||
Operator(Operator),
|
||||
Argument(Argument) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~UnaryExpression();
|
||||
|
||||
};
|
||||
|
@ -590,10 +685,15 @@ namespace bolt {
|
|||
class ExpressionStatement : public Statement {
|
||||
public:
|
||||
|
||||
ExpressionStatement(Expression* Expression):
|
||||
Expression* Expression;
|
||||
|
||||
ExpressionStatement(class Expression* Expression):
|
||||
Statement(NodeType::ExpressionStatement), Expression(Expression) {}
|
||||
|
||||
Expression* Expression;
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~ExpressionStatement();
|
||||
|
||||
|
@ -602,24 +702,43 @@ namespace bolt {
|
|||
class ReturnStatement : public Statement {
|
||||
public:
|
||||
|
||||
ReturnStatement(ReturnKeyword* ReturnKeyword, Expression* Expression): Statement(NodeType::ReturnStatement), ReturnKeyword(ReturnKeyword), Expression(Expression) {}
|
||||
|
||||
ReturnKeyword* ReturnKeyword;
|
||||
Expression* Expression;
|
||||
|
||||
ReturnStatement(
|
||||
class ReturnKeyword* ReturnKeyword,
|
||||
class Expression* Expression
|
||||
): Statement(NodeType::ReturnStatement),
|
||||
ReturnKeyword(ReturnKeyword),
|
||||
Expression(Expression) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~ReturnStatement();
|
||||
|
||||
};
|
||||
|
||||
class TypeAssert : public Node {
|
||||
|
||||
public:
|
||||
|
||||
TypeAssert(Colon* Colon, TypeExpression* TypeExpression): Node(NodeType::TypeAssert), Colon(Colon), TypeExpression(TypeExpression) {}
|
||||
public:
|
||||
|
||||
Colon* Colon;
|
||||
TypeExpression* TypeExpression;
|
||||
|
||||
TypeAssert(
|
||||
class Colon* Colon,
|
||||
class TypeExpression* TypeExpression
|
||||
): Node(NodeType::TypeAssert),
|
||||
Colon(Colon),
|
||||
TypeExpression(TypeExpression) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~TypeAssert();
|
||||
|
||||
};
|
||||
|
@ -632,6 +751,11 @@ namespace bolt {
|
|||
Pattern* Pattern;
|
||||
TypeAssert* TypeAssert;
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~Param();
|
||||
|
||||
};
|
||||
|
@ -648,15 +772,20 @@ namespace bolt {
|
|||
class LetBlockBody : public LetBody {
|
||||
public:
|
||||
|
||||
BlockStart* BlockStart;
|
||||
std::vector<Node*> Elements;
|
||||
|
||||
LetBlockBody(
|
||||
BlockStart* BlockStart,
|
||||
class BlockStart* BlockStart,
|
||||
std::vector<Node*> Elements
|
||||
): LetBody(NodeType::LetBlockBody),
|
||||
BlockStart(BlockStart),
|
||||
Elements(Elements) {}
|
||||
|
||||
BlockStart* BlockStart;
|
||||
std::vector<Node*> Elements;
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~LetBlockBody();
|
||||
|
||||
|
@ -675,6 +804,11 @@ namespace bolt {
|
|||
Equals(Equals),
|
||||
Expression(Expression) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~LetExprBody();
|
||||
|
||||
};
|
||||
|
@ -683,7 +817,7 @@ namespace bolt {
|
|||
public:
|
||||
|
||||
PubKeyword* PubKeyword;
|
||||
LetKeyword* LetKeywod;
|
||||
LetKeyword* LetKeyword;
|
||||
MutKeyword* MutKeyword;
|
||||
Pattern* Pattern;
|
||||
std::vector<Param*> Params;
|
||||
|
@ -700,13 +834,18 @@ namespace bolt {
|
|||
LetBody* Body
|
||||
): Node(NodeType::LetDeclaration),
|
||||
PubKeyword(PubKeyword),
|
||||
LetKeywod(LetKeywod),
|
||||
LetKeyword(LetKeywod),
|
||||
MutKeyword(MutKeyword),
|
||||
Pattern(Pattern),
|
||||
Params(Params),
|
||||
TypeAssert(TypeAssert),
|
||||
Body(Body) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~LetDeclaration();
|
||||
|
||||
};
|
||||
|
@ -727,6 +866,11 @@ namespace bolt {
|
|||
Colon* Colon;
|
||||
TypeExpression* TypeExpression;
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~StructDeclField();
|
||||
|
||||
};
|
||||
|
@ -734,35 +878,53 @@ namespace bolt {
|
|||
class StructDecl : public Node {
|
||||
public:
|
||||
|
||||
StructDecl(
|
||||
StructKeyword* StructKeyword,
|
||||
Identifier* Name,
|
||||
Dot* Dot,
|
||||
std::vector<StructDeclField*> Fields
|
||||
): Node(NodeType::StructDecl),
|
||||
StructKeyword(StructKeyword),
|
||||
Name(Name),
|
||||
Dot(Dot),
|
||||
Fields(Fields) {}
|
||||
|
||||
PubKeyword* PubKeyword;
|
||||
StructKeyword* StructKeyword;
|
||||
Identifier* Name;
|
||||
Dot* Dot;
|
||||
BlockStart* BlockStart;
|
||||
std::vector<StructDeclField*> Fields;
|
||||
|
||||
StructDecl(
|
||||
class PubKeyword* PubKeyword,
|
||||
class StructKeyword* StructKeyword,
|
||||
Identifier* Name,
|
||||
class BlockStart* BlockStart,
|
||||
std::vector<StructDeclField*> Fields
|
||||
): Node(NodeType::StructDecl),
|
||||
PubKeyword(PubKeyword),
|
||||
StructKeyword(StructKeyword),
|
||||
Name(Name),
|
||||
BlockStart(BlockStart),
|
||||
Fields(Fields) {}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~StructDecl();
|
||||
|
||||
};
|
||||
|
||||
class SourceFile : public Node {
|
||||
|
||||
public:
|
||||
|
||||
SourceFile(std::vector<Node*> Elements):
|
||||
Node(NodeType::SourceFile), Elements(Elements) {}
|
||||
public:
|
||||
|
||||
TextFile& File;
|
||||
|
||||
std::vector<Node*> Elements;
|
||||
|
||||
SourceFile(TextFile& File, std::vector<Node*> Elements):
|
||||
Node(NodeType::SourceFile), File(File), Elements(Elements) {}
|
||||
|
||||
inline TextFile& getTextFile() {
|
||||
return File;
|
||||
}
|
||||
|
||||
void setParents() override;
|
||||
|
||||
Token* getFirstToken() override;
|
||||
Token* getLastToken() override;
|
||||
|
||||
~SourceFile();
|
||||
|
||||
};
|
||||
|
|
|
@ -98,12 +98,55 @@ namespace bolt {
|
|||
|
||||
};
|
||||
|
||||
enum class Color {
|
||||
None,
|
||||
Black,
|
||||
White,
|
||||
Red,
|
||||
Yellow,
|
||||
Green,
|
||||
Blue,
|
||||
Cyan,
|
||||
Magenta,
|
||||
};
|
||||
|
||||
class ConsoleDiagnostics : public DiagnosticEngine {
|
||||
|
||||
std::ostream& Out;
|
||||
|
||||
void setForegroundColor(Color C);
|
||||
void setBackgroundColor(Color C);
|
||||
void resetStyles();
|
||||
|
||||
void writeGutter(
|
||||
std::size_t GutterWidth,
|
||||
std::size_t Line
|
||||
);
|
||||
|
||||
void writeHighlight(
|
||||
std::size_t GutterWidth,
|
||||
TextRange Range,
|
||||
Color HighlightColor,
|
||||
std::size_t Line,
|
||||
std::size_t LineLength
|
||||
);
|
||||
|
||||
void writeExcerpt(
|
||||
TextFile& File,
|
||||
TextRange ToPrint,
|
||||
TextRange ToHighlight,
|
||||
Color HighlightColor
|
||||
);
|
||||
|
||||
public:
|
||||
|
||||
unsigned ExcerptLinesPre = 2;
|
||||
unsigned ExcerptLinesPost = 2;
|
||||
std::size_t MaxTypeSubsitutionCount = 0;
|
||||
bool PrintFilePosition = true;
|
||||
bool PrintExcerpts = true;
|
||||
bool EnableColors = true;
|
||||
|
||||
void addDiagnostic(const Diagnostic& Diagnostic) override;
|
||||
|
||||
ConsoleDiagnostics(std::ostream& Out = std::cerr);
|
||||
|
|
|
@ -60,6 +60,8 @@ namespace bolt {
|
|||
|
||||
class Parser {
|
||||
|
||||
TextFile& File;
|
||||
|
||||
Stream<Token*>& Tokens;
|
||||
|
||||
OperatorTable ExprOperators;
|
||||
|
@ -70,7 +72,7 @@ namespace bolt {
|
|||
|
||||
public:
|
||||
|
||||
Parser(Stream<Token*>& S);
|
||||
Parser(TextFile& File, Stream<Token*>& S);
|
||||
|
||||
QualifiedName* parseQualifiedName();
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "bolt/ByteString.hpp"
|
||||
#include "bolt/String.hpp"
|
||||
|
||||
namespace bolt {
|
||||
|
||||
|
@ -38,21 +39,23 @@ namespace bolt {
|
|||
class TextFile {
|
||||
|
||||
ByteString Path;
|
||||
ByteString Text;
|
||||
String Text;
|
||||
|
||||
std::vector<size_t> LineOffsets;
|
||||
|
||||
public:
|
||||
|
||||
TextFile(ByteString Path, ByteString Text);
|
||||
TextFile(ByteString Path, String Text);
|
||||
|
||||
size_t getLine(size_t Offset);
|
||||
size_t getColumn(size_t Offset);
|
||||
size_t getStartOffset(size_t Line);
|
||||
|
||||
size_t getLineCount() const;
|
||||
|
||||
ByteString getPath() const;
|
||||
|
||||
ByteString getText() const;
|
||||
String getText() const;
|
||||
|
||||
};
|
||||
|
||||
|
|
348
src/CST.cc
348
src/CST.cc
|
@ -1,9 +1,168 @@
|
|||
|
||||
#include "zen/config.hpp"
|
||||
|
||||
#include "bolt/CST.hpp"
|
||||
|
||||
namespace bolt {
|
||||
|
||||
Node::~Node() { }
|
||||
SourceFile* Node::getSourceFile() {
|
||||
auto CurrNode = this;
|
||||
for (;;) {
|
||||
if (CurrNode->Type == NodeType::SourceFile) {
|
||||
return static_cast<SourceFile*>(this);
|
||||
}
|
||||
CurrNode = CurrNode->Parent;
|
||||
ZEN_ASSERT(CurrNode != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
TextRange Node::getRange() {
|
||||
return TextRange {
|
||||
getFirstToken()->getStartLoc(),
|
||||
getLastToken()->getEndLoc(),
|
||||
};
|
||||
}
|
||||
|
||||
void Token::setParents() {
|
||||
}
|
||||
|
||||
void QualifiedName::setParents() {
|
||||
for (auto Name: ModulePath) {
|
||||
Name->Parent = this;
|
||||
}
|
||||
Name->Parent = this;
|
||||
}
|
||||
|
||||
void ReferenceTypeExpression::setParents() {
|
||||
Name->Parent = this;
|
||||
Name->setParents();
|
||||
}
|
||||
|
||||
void BindPattern::setParents() {
|
||||
Name->Parent = this;
|
||||
}
|
||||
|
||||
void ReferenceExpression::setParents() {
|
||||
Name->Parent = this;
|
||||
}
|
||||
|
||||
void ConstantExpression::setParents() {
|
||||
Token->Parent = this;
|
||||
}
|
||||
|
||||
void CallExpression::setParents() {
|
||||
Function->Parent = this;
|
||||
Function->setParents();
|
||||
for (auto Arg: Args) {
|
||||
Arg->Parent = this;
|
||||
Arg->setParents();
|
||||
}
|
||||
}
|
||||
|
||||
void InfixExpression::setParents() {
|
||||
LHS->Parent = this;
|
||||
LHS->setParents();
|
||||
Operator->Parent = this;
|
||||
RHS->Parent = this;
|
||||
RHS->setParents();
|
||||
}
|
||||
|
||||
void UnaryExpression::setParents() {
|
||||
Operator->Parent = this;
|
||||
Argument->Parent = this;
|
||||
Argument->setParents();
|
||||
}
|
||||
|
||||
void ExpressionStatement::setParents() {
|
||||
Expression->Parent = this;
|
||||
Expression->setParents();
|
||||
}
|
||||
|
||||
void ReturnStatement::setParents() {
|
||||
ReturnKeyword->Parent = this;
|
||||
Expression->Parent = this;
|
||||
Expression->setParents();
|
||||
}
|
||||
|
||||
void TypeAssert::setParents() {
|
||||
Colon->Parent = this;
|
||||
TypeExpression->Parent = this;
|
||||
TypeExpression->setParents();
|
||||
}
|
||||
|
||||
void LetBlockBody::setParents() {
|
||||
BlockStart->Parent = this;
|
||||
for (auto Element: Elements) {
|
||||
Element->Parent = this;
|
||||
Element->setParents();
|
||||
}
|
||||
}
|
||||
|
||||
void LetExprBody::setParents() {
|
||||
Equals->Parent = this;
|
||||
Expression->Parent = this;
|
||||
Expression->setParents();
|
||||
}
|
||||
|
||||
void Param::setParents() {
|
||||
Pattern->Parent = this;
|
||||
Pattern->setParents();
|
||||
if (TypeAssert) {
|
||||
TypeAssert->Parent = this;
|
||||
TypeAssert->setParents();
|
||||
}
|
||||
}
|
||||
|
||||
void LetDeclaration::setParents() {
|
||||
if (PubKeyword) {
|
||||
PubKeyword->Parent = this;
|
||||
}
|
||||
LetKeyword->Parent = this;
|
||||
if (MutKeyword) {
|
||||
MutKeyword->Parent = this;
|
||||
}
|
||||
Pattern->Parent = this;
|
||||
Pattern->setParents();
|
||||
for (auto Param: Params) {
|
||||
Param->Parent = this;
|
||||
Param->setParents();
|
||||
}
|
||||
if (TypeAssert) {
|
||||
TypeAssert->Parent = this;
|
||||
TypeAssert->setParents();
|
||||
}
|
||||
if (Body) {
|
||||
Body->Parent = this;
|
||||
Body->setParents();
|
||||
}
|
||||
}
|
||||
|
||||
void StructDeclField::setParents() {
|
||||
Name->Parent = this;
|
||||
Colon->Parent = this;
|
||||
TypeExpression->Parent = this;
|
||||
TypeExpression->setParents();
|
||||
}
|
||||
|
||||
void StructDecl::setParents() {
|
||||
StructKeyword->Parent = this;
|
||||
Name->Parent = this;
|
||||
BlockStart->Parent = this;
|
||||
for (auto Field: Fields) {
|
||||
Field->Parent = this;
|
||||
Field->setParents();
|
||||
}
|
||||
}
|
||||
|
||||
void SourceFile::setParents() {
|
||||
for (auto Element: Elements) {
|
||||
Element->Parent = this;
|
||||
Element->setParents();
|
||||
}
|
||||
}
|
||||
|
||||
Node::~Node() {
|
||||
}
|
||||
|
||||
Token::~Token() {
|
||||
}
|
||||
|
@ -180,7 +339,7 @@ namespace bolt {
|
|||
if (PubKeyword) {
|
||||
PubKeyword->unref();
|
||||
}
|
||||
LetKeywod->unref();
|
||||
LetKeyword->unref();
|
||||
if (MutKeyword) {
|
||||
MutKeyword->unref();
|
||||
}
|
||||
|
@ -205,7 +364,7 @@ namespace bolt {
|
|||
StructDecl::~StructDecl() {
|
||||
StructKeyword->unref();
|
||||
Name->unref();
|
||||
Dot->unref();
|
||||
BlockStart->unref();
|
||||
for (auto& Element: Fields){
|
||||
Element->unref();
|
||||
}
|
||||
|
@ -217,6 +376,189 @@ namespace bolt {
|
|||
}
|
||||
}
|
||||
|
||||
Token* QualifiedName::getFirstToken() {
|
||||
if (ModulePath.size()) {
|
||||
return ModulePath.front();
|
||||
}
|
||||
return Name;
|
||||
}
|
||||
|
||||
Token* QualifiedName::getLastToken() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
Token* ReferenceTypeExpression::getFirstToken() {
|
||||
return Name->getFirstToken();
|
||||
}
|
||||
|
||||
Token* ReferenceTypeExpression::getLastToken() {
|
||||
return Name->getFirstToken();
|
||||
}
|
||||
|
||||
Token* BindPattern::getFirstToken() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
Token* BindPattern::getLastToken() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
Token* ReferenceExpression::getFirstToken() {
|
||||
return Name->getFirstToken();
|
||||
}
|
||||
|
||||
Token* ReferenceExpression::getLastToken() {
|
||||
return Name->getLastToken();
|
||||
}
|
||||
|
||||
Token* ConstantExpression::getFirstToken() {
|
||||
return Token;
|
||||
}
|
||||
|
||||
Token* ConstantExpression::getLastToken() {
|
||||
return Token;
|
||||
}
|
||||
|
||||
Token* CallExpression::getFirstToken() {
|
||||
return Function->getFirstToken();
|
||||
}
|
||||
|
||||
Token* CallExpression::getLastToken() {
|
||||
if (Args.size()) {
|
||||
return Args.back()->getLastToken();
|
||||
}
|
||||
return Function->getLastToken();
|
||||
}
|
||||
|
||||
Token* InfixExpression::getFirstToken() {
|
||||
return LHS->getFirstToken();
|
||||
}
|
||||
|
||||
Token* InfixExpression::getLastToken() {
|
||||
return RHS->getLastToken();
|
||||
}
|
||||
|
||||
Token* UnaryExpression::getFirstToken() {
|
||||
return Operator;
|
||||
}
|
||||
|
||||
Token* UnaryExpression::getLastToken() {
|
||||
return Argument->getLastToken();
|
||||
}
|
||||
|
||||
Token* ExpressionStatement::getFirstToken() {
|
||||
return Expression->getFirstToken();
|
||||
}
|
||||
|
||||
Token* ExpressionStatement::getLastToken() {
|
||||
return Expression->getLastToken();
|
||||
}
|
||||
|
||||
Token* ReturnStatement::getFirstToken() {
|
||||
return ReturnKeyword;
|
||||
}
|
||||
|
||||
Token* ReturnStatement::getLastToken() {
|
||||
if (Expression) {
|
||||
return Expression->getLastToken();
|
||||
}
|
||||
return ReturnKeyword;
|
||||
}
|
||||
|
||||
Token* TypeAssert::getFirstToken() {
|
||||
return Colon;
|
||||
}
|
||||
|
||||
Token* TypeAssert::getLastToken() {
|
||||
return TypeExpression->getLastToken();
|
||||
}
|
||||
|
||||
Token* Param::getFirstToken() {
|
||||
return Pattern->getFirstToken();
|
||||
}
|
||||
|
||||
Token* Param::getLastToken() {
|
||||
if (TypeAssert) {
|
||||
return TypeAssert->getLastToken();
|
||||
}
|
||||
return Pattern->getLastToken();
|
||||
}
|
||||
|
||||
Token* LetBlockBody::getFirstToken() {
|
||||
return BlockStart;
|
||||
}
|
||||
|
||||
Token* LetBlockBody::getLastToken() {
|
||||
if (Elements.size()) {
|
||||
return Elements.back()->getLastToken();
|
||||
}
|
||||
return BlockStart;
|
||||
}
|
||||
|
||||
Token* LetExprBody::getFirstToken() {
|
||||
return Equals;
|
||||
}
|
||||
|
||||
Token* LetExprBody::getLastToken() {
|
||||
return Expression->getLastToken();
|
||||
}
|
||||
|
||||
Token* LetDeclaration::getFirstToken() {
|
||||
if (PubKeyword) {
|
||||
return PubKeyword;
|
||||
}
|
||||
return LetKeyword;
|
||||
}
|
||||
|
||||
Token* LetDeclaration::getLastToken() {
|
||||
if (Body) {
|
||||
return Body->getLastToken();
|
||||
}
|
||||
if (TypeAssert) {
|
||||
return TypeAssert->getLastToken();
|
||||
}
|
||||
if (Params.size()) {
|
||||
return Params.back()->getLastToken();
|
||||
}
|
||||
return Pattern->getLastToken();
|
||||
}
|
||||
|
||||
Token* StructDeclField::getFirstToken() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
Token* StructDeclField::getLastToken() {
|
||||
return TypeExpression->getLastToken();
|
||||
}
|
||||
|
||||
Token* StructDecl::getFirstToken() {
|
||||
if (PubKeyword) {
|
||||
return PubKeyword;
|
||||
}
|
||||
return StructKeyword;
|
||||
}
|
||||
|
||||
Token* StructDecl::getLastToken() {
|
||||
if (Fields.size()) {
|
||||
Fields.back()->getLastToken();
|
||||
}
|
||||
return BlockStart;
|
||||
}
|
||||
|
||||
Token* SourceFile::getFirstToken() {
|
||||
if (Elements.size()) {
|
||||
return Elements.front()->getFirstToken();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Token* SourceFile::getLastToken() {
|
||||
if (Elements.size()) {
|
||||
return Elements.back()->getLastToken();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string Equals::getText() const {
|
||||
return "=";
|
||||
}
|
||||
|
|
|
@ -181,9 +181,10 @@ namespace bolt {
|
|||
case NodeType::ReferenceExpression:
|
||||
{
|
||||
auto Y = static_cast<ReferenceExpression*>(X);
|
||||
auto Scm = Ctx.Env.lookup(Y->Name->Text);
|
||||
ZEN_ASSERT(Y->Name->ModulePath.empty());
|
||||
auto Scm = Ctx.Env.lookup(Y->Name->Name->Text);
|
||||
if (Scm == nullptr) {
|
||||
DE.add<BindingNotFoundDiagnostic>(Y->Name->Text, Y->Name);
|
||||
DE.add<BindingNotFoundDiagnostic>(Y->Name->Name->Text, Y->Name);
|
||||
return new TAny();
|
||||
}
|
||||
return instantiate(*Scm);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
#include <sstream>
|
||||
#include <cmath>
|
||||
|
||||
#include "zen/config.hpp"
|
||||
|
||||
|
@ -31,6 +32,14 @@
|
|||
|
||||
namespace bolt {
|
||||
|
||||
template<typename T>
|
||||
T countDigits(T number) {
|
||||
if (number == 0) {
|
||||
return 1;
|
||||
}
|
||||
return std::ceil(std::log10(number+1));
|
||||
}
|
||||
|
||||
Diagnostic::Diagnostic(DiagnosticKind Kind):
|
||||
std::runtime_error("a compiler error occurred without being caught"), Kind(Kind) {}
|
||||
|
||||
|
@ -122,10 +131,169 @@ namespace bolt {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ConsoleDiagnostics::ConsoleDiagnostics(std::ostream& Out):
|
||||
Out(Out) {}
|
||||
|
||||
void ConsoleDiagnostics::setForegroundColor(Color C) {
|
||||
if (EnableColors) {
|
||||
switch (C) {
|
||||
case Color::None:
|
||||
break;
|
||||
case Color::Black:
|
||||
Out << ANSI_FG_BLACK;
|
||||
break;
|
||||
case Color::White:
|
||||
Out << ANSI_FG_WHITE;
|
||||
break;
|
||||
case Color::Red:
|
||||
Out << ANSI_FG_RED;
|
||||
break;
|
||||
case Color::Yellow:
|
||||
Out << ANSI_FG_YELLOW;
|
||||
break;
|
||||
case Color::Green:
|
||||
Out << ANSI_FG_GREEN;
|
||||
break;
|
||||
case Color::Blue:
|
||||
Out << ANSI_FG_BLUE;
|
||||
break;
|
||||
case Color::Cyan:
|
||||
Out << ANSI_FG_CYAN;
|
||||
break;
|
||||
case Color::Magenta:
|
||||
Out << ANSI_FG_MAGENTA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConsoleDiagnostics::setBackgroundColor(Color C) {
|
||||
if (EnableColors) {
|
||||
switch (C) {
|
||||
case Color::None:
|
||||
break;
|
||||
case Color::Black:
|
||||
Out << ANSI_BG_BLACK;
|
||||
break;
|
||||
case Color::White:
|
||||
Out << ANSI_BG_WHITE;
|
||||
break;
|
||||
case Color::Red:
|
||||
Out << ANSI_BG_RED;
|
||||
break;
|
||||
case Color::Yellow:
|
||||
Out << ANSI_BG_YELLOW;
|
||||
break;
|
||||
case Color::Green:
|
||||
Out << ANSI_BG_GREEN;
|
||||
break;
|
||||
case Color::Blue:
|
||||
Out << ANSI_BG_BLUE;
|
||||
break;
|
||||
case Color::Cyan:
|
||||
Out << ANSI_BG_CYAN;
|
||||
break;
|
||||
case Color::Magenta:
|
||||
Out << ANSI_BG_MAGENTA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleDiagnostics::resetStyles() {
|
||||
if (EnableColors) {
|
||||
Out << ANSI_RESET;
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleDiagnostics::writeGutter(
|
||||
std::size_t GutterWidth,
|
||||
std::size_t Line
|
||||
) {
|
||||
auto LineNumberDigitCount = countDigits(Line);
|
||||
auto LeadingSpaces = GutterWidth - LineNumberDigitCount;
|
||||
Out << " ";
|
||||
setForegroundColor(Color::Black);
|
||||
setBackgroundColor(Color::White);
|
||||
for (std::size_t i = 0; i < LeadingSpaces; i++) {
|
||||
Out << ' ';
|
||||
}
|
||||
Out << Line;
|
||||
resetStyles();
|
||||
Out << " ";
|
||||
}
|
||||
|
||||
void ConsoleDiagnostics::writeHighlight(
|
||||
std::size_t GutterWidth,
|
||||
TextRange Range,
|
||||
Color HighlightColor,
|
||||
std::size_t Line,
|
||||
std::size_t LineLength
|
||||
) {
|
||||
if (Line < Range.Start.Line || Range.End.Line < Line) {
|
||||
return;
|
||||
}
|
||||
Out << " ";
|
||||
setBackgroundColor(Color::White);
|
||||
for (std::size_t i = 0; i < GutterWidth; i++) {
|
||||
Out << ' ';
|
||||
}
|
||||
resetStyles();
|
||||
Out << ' ';
|
||||
std::size_t start_column = Range.Start.Line == Line ? Range.Start.Column : 1;
|
||||
std::size_t end_column = Range.End.Line == Line ? Range.End.Column : LineLength+1;
|
||||
for (std::size_t i = 1; i < start_column; i++) {
|
||||
Out << ' ';
|
||||
}
|
||||
setForegroundColor(HighlightColor);
|
||||
for (std::size_t i = start_column; i < end_column; i++) {
|
||||
Out << '~';
|
||||
}
|
||||
resetStyles();
|
||||
Out << '\n';
|
||||
}
|
||||
|
||||
void ConsoleDiagnostics::writeExcerpt(
|
||||
TextFile& File,
|
||||
TextRange ToPrint,
|
||||
TextRange ToHighlight,
|
||||
Color HighlightColor
|
||||
) {
|
||||
|
||||
auto Text = File.getText();
|
||||
auto StartPos = ToPrint.Start;
|
||||
auto EndPos = ToPrint.End;
|
||||
auto StartLine = StartPos.Line-1 > ExcerptLinesPre ? StartPos.Line - ExcerptLinesPost : 1;
|
||||
auto StartOffset = File.getStartOffset(StartLine);
|
||||
auto EndLine = std::min(File.getLineCount(), EndPos.Line + ExcerptLinesPost);
|
||||
auto EndOffset = File.getStartOffset(EndLine+1);
|
||||
auto GutterWidth = std::max<std::size_t>(2, countDigits(EndLine+1));
|
||||
auto HighlightStart = ToHighlight.Start;
|
||||
auto HighlightEnd = ToHighlight.End;
|
||||
auto HighlightRange = TextRange { HighlightStart, HighlightEnd };
|
||||
|
||||
std::size_t CurrColumn = 1;
|
||||
std::size_t CurrLine = StartLine;
|
||||
writeGutter(GutterWidth, CurrLine);
|
||||
for (std::size_t i = StartOffset; i < EndOffset; i++) {
|
||||
auto C = Text[i];
|
||||
Out << C;
|
||||
if (C == '\n') {
|
||||
writeHighlight(GutterWidth, HighlightRange, HighlightColor, CurrLine, CurrColumn);
|
||||
if (CurrLine == EndLine && C == '\n') {
|
||||
break;
|
||||
}
|
||||
CurrLine++;
|
||||
writeGutter(GutterWidth, CurrLine);
|
||||
CurrColumn = 1;
|
||||
} else {
|
||||
CurrColumn++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ConsoleDiagnostics::addDiagnostic(const Diagnostic& D) {
|
||||
|
||||
switch (D.getKind()) {
|
||||
|
@ -163,6 +331,7 @@ namespace bolt {
|
|||
break;
|
||||
}
|
||||
Out << " but instead got '" << E.Actual->getText() << "'\n";
|
||||
writeExcerpt(E.Actual->getSourceFile()->getTextFile(), E.Actual->getRange(), E.Actual->getRange(), Color::Red);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ namespace bolt {
|
|||
Mapping.emplace(Name, OperatorInfo { Precedence, Flags });
|
||||
}
|
||||
|
||||
Parser::Parser(Stream<Token*>& S):
|
||||
Tokens(S) {
|
||||
Parser::Parser(TextFile& File, Stream<Token*>& S):
|
||||
File(File), Tokens(S) {
|
||||
ExprOperators.add("**", OperatorFlags_InfixR, 10);
|
||||
ExprOperators.add("*", OperatorFlags_InfixL, 5);
|
||||
ExprOperators.add("/", OperatorFlags_InfixL, 5);
|
||||
|
@ -120,8 +120,10 @@ namespace bolt {
|
|||
auto T0 = Tokens.peek();
|
||||
switch (T0->Type) {
|
||||
case NodeType::Identifier:
|
||||
Tokens.get();
|
||||
return new ReferenceExpression(static_cast<Identifier*>(T0));
|
||||
{
|
||||
auto Name = parseQualifiedName();
|
||||
return new ReferenceExpression(Name);
|
||||
}
|
||||
case NodeType::IntegerLiteral:
|
||||
case NodeType::StringLiteral:
|
||||
Tokens.get();
|
||||
|
@ -320,7 +322,7 @@ after_params:
|
|||
}
|
||||
Elements.push_back(parseSourceElement());
|
||||
}
|
||||
return new SourceFile(Elements);
|
||||
return new SourceFile(File, Elements);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace bolt {
|
||||
|
||||
TextFile::TextFile(ByteString Path, ByteString Text):
|
||||
TextFile::TextFile(ByteString Path, String Text):
|
||||
Path(Path), Text(Text) {
|
||||
LineOffsets.push_back(0);
|
||||
for (size_t I = 0; I < Text.size(); I++) {
|
||||
|
@ -18,6 +18,10 @@ namespace bolt {
|
|||
LineOffsets.push_back(Text.size());
|
||||
}
|
||||
|
||||
size_t TextFile::getLineCount() const {
|
||||
return LineOffsets.size();
|
||||
}
|
||||
|
||||
size_t TextFile::getStartOffset(size_t Line) {
|
||||
return LineOffsets[Line-1];
|
||||
}
|
||||
|
@ -42,7 +46,7 @@ namespace bolt {
|
|||
return Path;
|
||||
}
|
||||
|
||||
ByteString TextFile::getText() const {
|
||||
String TextFile::getText() const {
|
||||
return Text;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,11 @@ int main(int argc, const char* argv[]) {
|
|||
ConsoleDiagnostics DE;
|
||||
|
||||
auto Text = readFile(argv[1]);
|
||||
TextFile File { argv[1], Text };
|
||||
VectorStream<String> Chars(Text, EOF);
|
||||
Scanner S(Chars);
|
||||
Punctuator PT(S);
|
||||
Parser P(PT);
|
||||
Parser P(File, PT);
|
||||
|
||||
SourceFile* SF;
|
||||
|
||||
|
@ -56,6 +57,8 @@ int main(int argc, const char* argv[]) {
|
|||
SF = P.parseSourceFile();
|
||||
#endif
|
||||
|
||||
SF->setParents();
|
||||
|
||||
Checker TheChecker { DE };
|
||||
TheChecker.check(SF);
|
||||
|
||||
|
|
Loading…
Reference in a new issue