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
|
#ifndef BOLT_CST_HPP
|
||||||
#define BOLT_CST_HPP
|
#define BOLT_CST_HPP
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "bolt/Text.hpp"
|
#include "bolt/Text.hpp"
|
||||||
|
@ -57,29 +58,41 @@ namespace bolt {
|
||||||
SourceFile,
|
SourceFile,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Token;
|
||||||
|
class SourceFile;
|
||||||
|
|
||||||
class Node {
|
class Node {
|
||||||
|
|
||||||
unsigned refcount = 0;
|
unsigned RefCount = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
Node* Parent = nullptr;
|
||||||
|
|
||||||
inline void ref() {
|
inline void ref() {
|
||||||
++refcount;
|
++RefCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unref() {
|
inline void unref() {
|
||||||
--refcount;
|
--RefCount;
|
||||||
if (refcount == 0) {
|
if (RefCount == 0) {
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void setParents() = 0;
|
||||||
|
|
||||||
|
virtual Token* getFirstToken() = 0;
|
||||||
|
virtual Token* getLastToken() = 0;
|
||||||
|
|
||||||
|
TextRange getRange();
|
||||||
|
|
||||||
const NodeType Type;
|
const NodeType Type;
|
||||||
|
|
||||||
inline Node(NodeType Type):
|
inline Node(NodeType Type):
|
||||||
Type(Type) {}
|
Type(Type) {}
|
||||||
|
|
||||||
|
SourceFile* getSourceFile();
|
||||||
|
|
||||||
virtual ~Node();
|
virtual ~Node();
|
||||||
|
|
||||||
|
@ -95,6 +108,16 @@ namespace bolt {
|
||||||
|
|
||||||
virtual std::string getText() const = 0;
|
virtual std::string getText() const = 0;
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
inline Token* getFirstToken() override {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Token* getLastToken() override {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
inline TextLoc getStartLoc() {
|
inline TextLoc getStartLoc() {
|
||||||
return StartLoc;
|
return StartLoc;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +151,8 @@ namespace bolt {
|
||||||
class Equals : public Token {
|
class Equals : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Equals(TextLoc StartLoc): Token(NodeType::Equals, StartLoc) {}
|
Equals(TextLoc StartLoc):
|
||||||
|
Token(NodeType::Equals, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -139,7 +163,8 @@ namespace bolt {
|
||||||
class Colon : public Token {
|
class Colon : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Colon(TextLoc StartLoc): Token(NodeType::Colon, StartLoc) {}
|
Colon(TextLoc StartLoc):
|
||||||
|
Token(NodeType::Colon, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -150,7 +175,8 @@ namespace bolt {
|
||||||
class Dot : public Token {
|
class Dot : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Dot(TextLoc StartLoc): Token(NodeType::Dot, StartLoc) {}
|
Dot(TextLoc StartLoc):
|
||||||
|
Token(NodeType::Dot, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -161,7 +187,8 @@ namespace bolt {
|
||||||
class DotDot : public Token {
|
class DotDot : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DotDot(TextLoc StartLoc): Token(NodeType::DotDot, StartLoc) {}
|
DotDot(TextLoc StartLoc):
|
||||||
|
Token(NodeType::DotDot, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -172,7 +199,8 @@ namespace bolt {
|
||||||
class LParen : public Token {
|
class LParen : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LParen(TextLoc StartLoc): Token(NodeType::LParen, StartLoc) {}
|
LParen(TextLoc StartLoc):
|
||||||
|
Token(NodeType::LParen, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -183,7 +211,8 @@ namespace bolt {
|
||||||
class RParen : public Token {
|
class RParen : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RParen(TextLoc StartLoc): Token(NodeType::RParen, StartLoc) {}
|
RParen(TextLoc StartLoc):
|
||||||
|
Token(NodeType::RParen, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -194,7 +223,8 @@ namespace bolt {
|
||||||
class LBracket : public Token {
|
class LBracket : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LBracket(TextLoc StartLoc): Token(NodeType::LBracket, StartLoc) {}
|
LBracket(TextLoc StartLoc):
|
||||||
|
Token(NodeType::LBracket, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -205,7 +235,8 @@ namespace bolt {
|
||||||
class RBracket : public Token {
|
class RBracket : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RBracket(TextLoc StartLoc): Token(NodeType::RBracket, StartLoc) {}
|
RBracket(TextLoc StartLoc):
|
||||||
|
Token(NodeType::RBracket, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -216,7 +247,8 @@ namespace bolt {
|
||||||
class LBrace : public Token {
|
class LBrace : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LBrace(TextLoc StartLoc): Token(NodeType::LBrace, StartLoc) {}
|
LBrace(TextLoc StartLoc):
|
||||||
|
Token(NodeType::LBrace, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -227,7 +259,8 @@ namespace bolt {
|
||||||
class RBrace : public Token {
|
class RBrace : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RBrace(TextLoc StartLoc): Token(NodeType::RBrace, StartLoc) {}
|
RBrace(TextLoc StartLoc):
|
||||||
|
Token(NodeType::RBrace, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -238,7 +271,8 @@ namespace bolt {
|
||||||
class LetKeyword : public Token {
|
class LetKeyword : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LetKeyword(TextLoc StartLoc): Token(NodeType::LetKeyword, StartLoc) {}
|
LetKeyword(TextLoc StartLoc):
|
||||||
|
Token(NodeType::LetKeyword, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -249,7 +283,8 @@ namespace bolt {
|
||||||
class MutKeyword : public Token {
|
class MutKeyword : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MutKeyword(TextLoc StartLoc): Token(NodeType::MutKeyword, StartLoc) {}
|
MutKeyword(TextLoc StartLoc):
|
||||||
|
Token(NodeType::MutKeyword, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -260,7 +295,8 @@ namespace bolt {
|
||||||
class PubKeyword : public Token {
|
class PubKeyword : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PubKeyword(TextLoc StartLoc): Token(NodeType::PubKeyword, StartLoc) {}
|
PubKeyword(TextLoc StartLoc):
|
||||||
|
Token(NodeType::PubKeyword, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -271,7 +307,8 @@ namespace bolt {
|
||||||
class TypeKeyword : public Token {
|
class TypeKeyword : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TypeKeyword(TextLoc StartLoc): Token(NodeType::TypeKeyword, StartLoc) {}
|
TypeKeyword(TextLoc StartLoc):
|
||||||
|
Token(NodeType::TypeKeyword, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -282,7 +319,8 @@ namespace bolt {
|
||||||
class ReturnKeyword : public Token {
|
class ReturnKeyword : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ReturnKeyword(TextLoc StartLoc): Token(NodeType::ReturnKeyword, StartLoc) {}
|
ReturnKeyword(TextLoc StartLoc):
|
||||||
|
Token(NodeType::ReturnKeyword, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -293,7 +331,8 @@ namespace bolt {
|
||||||
class ModKeyword : public Token {
|
class ModKeyword : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ModKeyword(TextLoc StartLoc): Token(NodeType::ModKeyword, StartLoc) {}
|
ModKeyword(TextLoc StartLoc):
|
||||||
|
Token(NodeType::ModKeyword, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -304,7 +343,8 @@ namespace bolt {
|
||||||
class StructKeyword : public Token {
|
class StructKeyword : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
StructKeyword(TextLoc StartLoc): Token(NodeType::StructKeyword, StartLoc) {}
|
StructKeyword(TextLoc StartLoc):
|
||||||
|
Token(NodeType::StructKeyword, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -315,7 +355,8 @@ namespace bolt {
|
||||||
class Invalid : public Token {
|
class Invalid : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Invalid(TextLoc StartLoc): Token(NodeType::Invalid, StartLoc) {}
|
Invalid(TextLoc StartLoc):
|
||||||
|
Token(NodeType::Invalid, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -326,7 +367,8 @@ namespace bolt {
|
||||||
class EndOfFile : public Token {
|
class EndOfFile : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EndOfFile(TextLoc StartLoc): Token(NodeType::EndOfFile, StartLoc) {}
|
EndOfFile(TextLoc StartLoc):
|
||||||
|
Token(NodeType::EndOfFile, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -337,7 +379,8 @@ namespace bolt {
|
||||||
class BlockStart : public Token {
|
class BlockStart : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BlockStart(TextLoc StartLoc): Token(NodeType::BlockStart, StartLoc) {}
|
BlockStart(TextLoc StartLoc):
|
||||||
|
Token(NodeType::BlockStart, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -348,7 +391,8 @@ namespace bolt {
|
||||||
class BlockEnd : public Token {
|
class BlockEnd : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BlockEnd(TextLoc StartLoc): Token(NodeType::BlockEnd, StartLoc) {}
|
BlockEnd(TextLoc StartLoc):
|
||||||
|
Token(NodeType::BlockEnd, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -359,7 +403,8 @@ namespace bolt {
|
||||||
class LineFoldEnd : public Token {
|
class LineFoldEnd : public Token {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LineFoldEnd(TextLoc StartLoc): Token(NodeType::LineFoldEnd, StartLoc) {}
|
LineFoldEnd(TextLoc StartLoc):
|
||||||
|
Token(NodeType::LineFoldEnd, StartLoc) {}
|
||||||
|
|
||||||
std::string getText() const override;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -372,7 +417,8 @@ namespace bolt {
|
||||||
|
|
||||||
ByteString Text;
|
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;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -385,7 +431,8 @@ namespace bolt {
|
||||||
|
|
||||||
ByteString Text;
|
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;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -398,7 +445,8 @@ namespace bolt {
|
||||||
|
|
||||||
ByteString Text;
|
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;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -411,7 +459,8 @@ namespace bolt {
|
||||||
|
|
||||||
ByteString Text;
|
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;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -424,7 +473,8 @@ namespace bolt {
|
||||||
|
|
||||||
Integer Value;
|
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;
|
std::string getText() const override;
|
||||||
|
|
||||||
|
@ -445,6 +495,11 @@ namespace bolt {
|
||||||
ModulePath(ModulePath),
|
ModulePath(ModulePath),
|
||||||
Name(Name) {}
|
Name(Name) {}
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
~QualifiedName();
|
~QualifiedName();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -468,6 +523,11 @@ namespace bolt {
|
||||||
): TypeExpression(NodeType::ReferenceTypeExpression),
|
): TypeExpression(NodeType::ReferenceTypeExpression),
|
||||||
Name(Name) {}
|
Name(Name) {}
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~ReferenceTypeExpression();
|
~ReferenceTypeExpression();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -491,6 +551,11 @@ namespace bolt {
|
||||||
): Pattern(NodeType::BindPattern),
|
): Pattern(NodeType::BindPattern),
|
||||||
Name(Name) {}
|
Name(Name) {}
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~BindPattern();
|
~BindPattern();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -507,13 +572,18 @@ namespace bolt {
|
||||||
class ReferenceExpression : public Expression {
|
class ReferenceExpression : public Expression {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Identifier* Name;
|
QualifiedName* Name;
|
||||||
|
|
||||||
ReferenceExpression(
|
ReferenceExpression(
|
||||||
Identifier* Name
|
QualifiedName* Name
|
||||||
): Expression(NodeType::ReferenceExpression),
|
): Expression(NodeType::ReferenceExpression),
|
||||||
Name(Name) {}
|
Name(Name) {}
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~ReferenceExpression();
|
~ReferenceExpression();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -528,6 +598,11 @@ namespace bolt {
|
||||||
): Expression(NodeType::ConstantExpression),
|
): Expression(NodeType::ConstantExpression),
|
||||||
Token(Token) {}
|
Token(Token) {}
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
class Token* getFirstToken() override;
|
||||||
|
class Token* getLastToken() override;
|
||||||
|
|
||||||
~ConstantExpression();
|
~ConstantExpression();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -535,11 +610,21 @@ namespace bolt {
|
||||||
class CallExpression : public Expression {
|
class CallExpression : public Expression {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CallExpression(Expression* Function, std::vector<Expression*> Args): Expression(NodeType::CallExpression), Function(Function), Args(Args) {}
|
|
||||||
|
|
||||||
Expression* Function;
|
Expression* Function;
|
||||||
std::vector<Expression*> Args;
|
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();
|
~CallExpression();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -557,6 +642,11 @@ namespace bolt {
|
||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
RHS(RHS) {}
|
RHS(RHS) {}
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~InfixExpression();
|
~InfixExpression();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -574,6 +664,11 @@ namespace bolt {
|
||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
Argument(Argument) {}
|
Argument(Argument) {}
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~UnaryExpression();
|
~UnaryExpression();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -590,10 +685,15 @@ namespace bolt {
|
||||||
class ExpressionStatement : public Statement {
|
class ExpressionStatement : public Statement {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ExpressionStatement(Expression* Expression):
|
Expression* Expression;
|
||||||
|
|
||||||
|
ExpressionStatement(class Expression* Expression):
|
||||||
Statement(NodeType::ExpressionStatement), Expression(Expression) {}
|
Statement(NodeType::ExpressionStatement), Expression(Expression) {}
|
||||||
|
|
||||||
Expression* Expression;
|
void setParents() override;
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~ExpressionStatement();
|
~ExpressionStatement();
|
||||||
|
|
||||||
|
@ -602,24 +702,43 @@ namespace bolt {
|
||||||
class ReturnStatement : public Statement {
|
class ReturnStatement : public Statement {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ReturnStatement(ReturnKeyword* ReturnKeyword, Expression* Expression): Statement(NodeType::ReturnStatement), ReturnKeyword(ReturnKeyword), Expression(Expression) {}
|
|
||||||
|
|
||||||
ReturnKeyword* ReturnKeyword;
|
ReturnKeyword* ReturnKeyword;
|
||||||
Expression* Expression;
|
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();
|
~ReturnStatement();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeAssert : public Node {
|
class TypeAssert : public Node {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TypeAssert(Colon* Colon, TypeExpression* TypeExpression): Node(NodeType::TypeAssert), Colon(Colon), TypeExpression(TypeExpression) {}
|
|
||||||
|
|
||||||
Colon* Colon;
|
Colon* Colon;
|
||||||
TypeExpression* TypeExpression;
|
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();
|
~TypeAssert();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -632,6 +751,11 @@ namespace bolt {
|
||||||
Pattern* Pattern;
|
Pattern* Pattern;
|
||||||
TypeAssert* TypeAssert;
|
TypeAssert* TypeAssert;
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~Param();
|
~Param();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -648,15 +772,20 @@ namespace bolt {
|
||||||
class LetBlockBody : public LetBody {
|
class LetBlockBody : public LetBody {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
BlockStart* BlockStart;
|
||||||
|
std::vector<Node*> Elements;
|
||||||
|
|
||||||
LetBlockBody(
|
LetBlockBody(
|
||||||
BlockStart* BlockStart,
|
class BlockStart* BlockStart,
|
||||||
std::vector<Node*> Elements
|
std::vector<Node*> Elements
|
||||||
): LetBody(NodeType::LetBlockBody),
|
): LetBody(NodeType::LetBlockBody),
|
||||||
BlockStart(BlockStart),
|
BlockStart(BlockStart),
|
||||||
Elements(Elements) {}
|
Elements(Elements) {}
|
||||||
|
|
||||||
BlockStart* BlockStart;
|
void setParents() override;
|
||||||
std::vector<Node*> Elements;
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~LetBlockBody();
|
~LetBlockBody();
|
||||||
|
|
||||||
|
@ -675,6 +804,11 @@ namespace bolt {
|
||||||
Equals(Equals),
|
Equals(Equals),
|
||||||
Expression(Expression) {}
|
Expression(Expression) {}
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~LetExprBody();
|
~LetExprBody();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -683,7 +817,7 @@ namespace bolt {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PubKeyword* PubKeyword;
|
PubKeyword* PubKeyword;
|
||||||
LetKeyword* LetKeywod;
|
LetKeyword* LetKeyword;
|
||||||
MutKeyword* MutKeyword;
|
MutKeyword* MutKeyword;
|
||||||
Pattern* Pattern;
|
Pattern* Pattern;
|
||||||
std::vector<Param*> Params;
|
std::vector<Param*> Params;
|
||||||
|
@ -700,13 +834,18 @@ namespace bolt {
|
||||||
LetBody* Body
|
LetBody* Body
|
||||||
): Node(NodeType::LetDeclaration),
|
): Node(NodeType::LetDeclaration),
|
||||||
PubKeyword(PubKeyword),
|
PubKeyword(PubKeyword),
|
||||||
LetKeywod(LetKeywod),
|
LetKeyword(LetKeywod),
|
||||||
MutKeyword(MutKeyword),
|
MutKeyword(MutKeyword),
|
||||||
Pattern(Pattern),
|
Pattern(Pattern),
|
||||||
Params(Params),
|
Params(Params),
|
||||||
TypeAssert(TypeAssert),
|
TypeAssert(TypeAssert),
|
||||||
Body(Body) {}
|
Body(Body) {}
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~LetDeclaration();
|
~LetDeclaration();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -727,6 +866,11 @@ namespace bolt {
|
||||||
Colon* Colon;
|
Colon* Colon;
|
||||||
TypeExpression* TypeExpression;
|
TypeExpression* TypeExpression;
|
||||||
|
|
||||||
|
void setParents() override;
|
||||||
|
|
||||||
|
Token* getFirstToken() override;
|
||||||
|
Token* getLastToken() override;
|
||||||
|
|
||||||
~StructDeclField();
|
~StructDeclField();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -734,35 +878,53 @@ namespace bolt {
|
||||||
class StructDecl : public Node {
|
class StructDecl : public Node {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
StructDecl(
|
PubKeyword* PubKeyword;
|
||||||
StructKeyword* StructKeyword,
|
|
||||||
Identifier* Name,
|
|
||||||
Dot* Dot,
|
|
||||||
std::vector<StructDeclField*> Fields
|
|
||||||
): Node(NodeType::StructDecl),
|
|
||||||
StructKeyword(StructKeyword),
|
|
||||||
Name(Name),
|
|
||||||
Dot(Dot),
|
|
||||||
Fields(Fields) {}
|
|
||||||
|
|
||||||
StructKeyword* StructKeyword;
|
StructKeyword* StructKeyword;
|
||||||
Identifier* Name;
|
Identifier* Name;
|
||||||
Dot* Dot;
|
BlockStart* BlockStart;
|
||||||
std::vector<StructDeclField*> Fields;
|
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();
|
~StructDecl();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SourceFile : public Node {
|
class SourceFile : public Node {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SourceFile(std::vector<Node*> Elements):
|
TextFile& File;
|
||||||
Node(NodeType::SourceFile), Elements(Elements) {}
|
|
||||||
|
|
||||||
std::vector<Node*> Elements;
|
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();
|
~SourceFile();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -98,12 +98,55 @@ namespace bolt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Color {
|
||||||
|
None,
|
||||||
|
Black,
|
||||||
|
White,
|
||||||
|
Red,
|
||||||
|
Yellow,
|
||||||
|
Green,
|
||||||
|
Blue,
|
||||||
|
Cyan,
|
||||||
|
Magenta,
|
||||||
|
};
|
||||||
|
|
||||||
class ConsoleDiagnostics : public DiagnosticEngine {
|
class ConsoleDiagnostics : public DiagnosticEngine {
|
||||||
|
|
||||||
std::ostream& Out;
|
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:
|
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;
|
void addDiagnostic(const Diagnostic& Diagnostic) override;
|
||||||
|
|
||||||
ConsoleDiagnostics(std::ostream& Out = std::cerr);
|
ConsoleDiagnostics(std::ostream& Out = std::cerr);
|
||||||
|
|
|
@ -60,6 +60,8 @@ namespace bolt {
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
|
|
||||||
|
TextFile& File;
|
||||||
|
|
||||||
Stream<Token*>& Tokens;
|
Stream<Token*>& Tokens;
|
||||||
|
|
||||||
OperatorTable ExprOperators;
|
OperatorTable ExprOperators;
|
||||||
|
@ -70,7 +72,7 @@ namespace bolt {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Parser(Stream<Token*>& S);
|
Parser(TextFile& File, Stream<Token*>& S);
|
||||||
|
|
||||||
QualifiedName* parseQualifiedName();
|
QualifiedName* parseQualifiedName();
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "bolt/ByteString.hpp"
|
#include "bolt/ByteString.hpp"
|
||||||
|
#include "bolt/String.hpp"
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
|
@ -38,21 +39,23 @@ namespace bolt {
|
||||||
class TextFile {
|
class TextFile {
|
||||||
|
|
||||||
ByteString Path;
|
ByteString Path;
|
||||||
ByteString Text;
|
String Text;
|
||||||
|
|
||||||
std::vector<size_t> LineOffsets;
|
std::vector<size_t> LineOffsets;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TextFile(ByteString Path, ByteString Text);
|
TextFile(ByteString Path, String Text);
|
||||||
|
|
||||||
size_t getLine(size_t Offset);
|
size_t getLine(size_t Offset);
|
||||||
size_t getColumn(size_t Offset);
|
size_t getColumn(size_t Offset);
|
||||||
size_t getStartOffset(size_t Line);
|
size_t getStartOffset(size_t Line);
|
||||||
|
|
||||||
|
size_t getLineCount() const;
|
||||||
|
|
||||||
ByteString getPath() 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"
|
#include "bolt/CST.hpp"
|
||||||
|
|
||||||
namespace bolt {
|
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() {
|
Token::~Token() {
|
||||||
}
|
}
|
||||||
|
@ -180,7 +339,7 @@ namespace bolt {
|
||||||
if (PubKeyword) {
|
if (PubKeyword) {
|
||||||
PubKeyword->unref();
|
PubKeyword->unref();
|
||||||
}
|
}
|
||||||
LetKeywod->unref();
|
LetKeyword->unref();
|
||||||
if (MutKeyword) {
|
if (MutKeyword) {
|
||||||
MutKeyword->unref();
|
MutKeyword->unref();
|
||||||
}
|
}
|
||||||
|
@ -205,7 +364,7 @@ namespace bolt {
|
||||||
StructDecl::~StructDecl() {
|
StructDecl::~StructDecl() {
|
||||||
StructKeyword->unref();
|
StructKeyword->unref();
|
||||||
Name->unref();
|
Name->unref();
|
||||||
Dot->unref();
|
BlockStart->unref();
|
||||||
for (auto& Element: Fields){
|
for (auto& Element: Fields){
|
||||||
Element->unref();
|
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 {
|
std::string Equals::getText() const {
|
||||||
return "=";
|
return "=";
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,9 +181,10 @@ namespace bolt {
|
||||||
case NodeType::ReferenceExpression:
|
case NodeType::ReferenceExpression:
|
||||||
{
|
{
|
||||||
auto Y = static_cast<ReferenceExpression*>(X);
|
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) {
|
if (Scm == nullptr) {
|
||||||
DE.add<BindingNotFoundDiagnostic>(Y->Name->Text, Y->Name);
|
DE.add<BindingNotFoundDiagnostic>(Y->Name->Name->Text, Y->Name);
|
||||||
return new TAny();
|
return new TAny();
|
||||||
}
|
}
|
||||||
return instantiate(*Scm);
|
return instantiate(*Scm);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "zen/config.hpp"
|
#include "zen/config.hpp"
|
||||||
|
|
||||||
|
@ -31,6 +32,14 @@
|
||||||
|
|
||||||
namespace bolt {
|
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):
|
Diagnostic::Diagnostic(DiagnosticKind Kind):
|
||||||
std::runtime_error("a compiler error occurred without being caught"), Kind(Kind) {}
|
std::runtime_error("a compiler error occurred without being caught"), Kind(Kind) {}
|
||||||
|
|
||||||
|
@ -122,10 +131,169 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ConsoleDiagnostics::ConsoleDiagnostics(std::ostream& Out):
|
ConsoleDiagnostics::ConsoleDiagnostics(std::ostream& Out):
|
||||||
Out(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) {
|
void ConsoleDiagnostics::addDiagnostic(const Diagnostic& D) {
|
||||||
|
|
||||||
switch (D.getKind()) {
|
switch (D.getKind()) {
|
||||||
|
@ -163,6 +331,7 @@ namespace bolt {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Out << " but instead got '" << E.Actual->getText() << "'\n";
|
Out << " but instead got '" << E.Actual->getText() << "'\n";
|
||||||
|
writeExcerpt(E.Actual->getSourceFile()->getTextFile(), E.Actual->getRange(), E.Actual->getRange(), Color::Red);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ namespace bolt {
|
||||||
Mapping.emplace(Name, OperatorInfo { Precedence, Flags });
|
Mapping.emplace(Name, OperatorInfo { Precedence, Flags });
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::Parser(Stream<Token*>& S):
|
Parser::Parser(TextFile& File, Stream<Token*>& S):
|
||||||
Tokens(S) {
|
File(File), Tokens(S) {
|
||||||
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);
|
||||||
|
@ -120,8 +120,10 @@ namespace bolt {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
switch (T0->Type) {
|
switch (T0->Type) {
|
||||||
case NodeType::Identifier:
|
case NodeType::Identifier:
|
||||||
Tokens.get();
|
{
|
||||||
return new ReferenceExpression(static_cast<Identifier*>(T0));
|
auto Name = parseQualifiedName();
|
||||||
|
return new ReferenceExpression(Name);
|
||||||
|
}
|
||||||
case NodeType::IntegerLiteral:
|
case NodeType::IntegerLiteral:
|
||||||
case NodeType::StringLiteral:
|
case NodeType::StringLiteral:
|
||||||
Tokens.get();
|
Tokens.get();
|
||||||
|
@ -320,7 +322,7 @@ after_params:
|
||||||
}
|
}
|
||||||
Elements.push_back(parseSourceElement());
|
Elements.push_back(parseSourceElement());
|
||||||
}
|
}
|
||||||
return new SourceFile(Elements);
|
return new SourceFile(File, Elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
TextFile::TextFile(ByteString Path, ByteString Text):
|
TextFile::TextFile(ByteString Path, String Text):
|
||||||
Path(Path), Text(Text) {
|
Path(Path), Text(Text) {
|
||||||
LineOffsets.push_back(0);
|
LineOffsets.push_back(0);
|
||||||
for (size_t I = 0; I < Text.size(); I++) {
|
for (size_t I = 0; I < Text.size(); I++) {
|
||||||
|
@ -18,6 +18,10 @@ namespace bolt {
|
||||||
LineOffsets.push_back(Text.size());
|
LineOffsets.push_back(Text.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t TextFile::getLineCount() const {
|
||||||
|
return LineOffsets.size();
|
||||||
|
}
|
||||||
|
|
||||||
size_t TextFile::getStartOffset(size_t Line) {
|
size_t TextFile::getStartOffset(size_t Line) {
|
||||||
return LineOffsets[Line-1];
|
return LineOffsets[Line-1];
|
||||||
}
|
}
|
||||||
|
@ -42,7 +46,7 @@ namespace bolt {
|
||||||
return Path;
|
return Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteString TextFile::getText() const {
|
String TextFile::getText() const {
|
||||||
return Text;
|
return Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,11 @@ int main(int argc, const char* argv[]) {
|
||||||
ConsoleDiagnostics DE;
|
ConsoleDiagnostics DE;
|
||||||
|
|
||||||
auto Text = readFile(argv[1]);
|
auto Text = readFile(argv[1]);
|
||||||
|
TextFile File { argv[1], Text };
|
||||||
VectorStream<String> Chars(Text, EOF);
|
VectorStream<String> Chars(Text, EOF);
|
||||||
Scanner S(Chars);
|
Scanner S(Chars);
|
||||||
Punctuator PT(S);
|
Punctuator PT(S);
|
||||||
Parser P(PT);
|
Parser P(File, PT);
|
||||||
|
|
||||||
SourceFile* SF;
|
SourceFile* SF;
|
||||||
|
|
||||||
|
@ -56,6 +57,8 @@ int main(int argc, const char* argv[]) {
|
||||||
SF = P.parseSourceFile();
|
SF = P.parseSourceFile();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
SF->setParents();
|
||||||
|
|
||||||
Checker TheChecker { DE };
|
Checker TheChecker { DE };
|
||||||
TheChecker.check(SF);
|
TheChecker.check(SF);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue