Remove indentation in namespaces
This commit is contained in:
parent
60f1e4519e
commit
800a72f041
25 changed files with 11626 additions and 11624 deletions
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
using ByteString = std::string;
|
using ByteString = std::string;
|
||||||
|
|
||||||
using ByteStringView = std::string_view;
|
using ByteStringView = std::string_view;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
template<typename D, typename R = void>
|
template<typename D, typename R = void>
|
||||||
class CSTVisitor {
|
class CSTVisitor {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void visit(Node* N) {
|
void visit(Node* N) {
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void visitNode(Node* N) {
|
void visitNode(Node* N) {
|
||||||
visitEachChild(N);
|
visitEachChild(N);
|
||||||
|
@ -534,7 +534,7 @@ namespace bolt {
|
||||||
static_cast<D*>(this)->visitNode(N);
|
static_cast<D*>(this)->visitNode(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void visitEachChild(Node* N) {
|
void visitEachChild(Node* N) {
|
||||||
|
|
||||||
|
@ -1244,6 +1244,6 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,33 +16,33 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
std::string describe(const Type* Ty); // For debugging only
|
std::string describe(const Type* Ty); // For debugging only
|
||||||
|
|
||||||
enum class SymKind {
|
enum class SymKind {
|
||||||
Type,
|
Type,
|
||||||
Var,
|
Var,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiagnosticEngine;
|
class DiagnosticEngine;
|
||||||
|
|
||||||
class Constraint;
|
class Constraint;
|
||||||
|
|
||||||
using ConstraintSet = std::vector<Constraint*>;
|
using ConstraintSet = std::vector<Constraint*>;
|
||||||
|
|
||||||
enum class SchemeKind : unsigned char {
|
enum class SchemeKind : unsigned char {
|
||||||
Forall,
|
Forall,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Scheme {
|
class Scheme {
|
||||||
|
|
||||||
const SchemeKind Kind;
|
const SchemeKind Kind;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
inline Scheme(SchemeKind Kind):
|
inline Scheme(SchemeKind Kind):
|
||||||
Kind(Kind) {}
|
Kind(Kind) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline SchemeKind getKind() const noexcept {
|
inline SchemeKind getKind() const noexcept {
|
||||||
return Kind;
|
return Kind;
|
||||||
|
@ -50,10 +50,10 @@ namespace bolt {
|
||||||
|
|
||||||
virtual ~Scheme() {}
|
virtual ~Scheme() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Forall : public Scheme {
|
class Forall : public Scheme {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TVSet* TVs;
|
TVSet* TVs;
|
||||||
ConstraintSet* Constraints;
|
ConstraintSet* Constraints;
|
||||||
|
@ -75,13 +75,13 @@ namespace bolt {
|
||||||
return Scm->getKind() == SchemeKind::Forall;
|
return Scm->getKind() == SchemeKind::Forall;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeEnv {
|
class TypeEnv {
|
||||||
|
|
||||||
std::unordered_map<std::tuple<ByteString, SymKind>, Scheme*> Mapping;
|
std::unordered_map<std::tuple<ByteString, SymKind>, Scheme*> Mapping;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Scheme* lookup(ByteString Name, SymKind Kind) {
|
Scheme* lookup(ByteString Name, SymKind Kind) {
|
||||||
auto Key = std::make_tuple(Name, Kind);
|
auto Key = std::make_tuple(Name, Kind);
|
||||||
|
@ -104,21 +104,21 @@ namespace bolt {
|
||||||
Mapping.emplace(Key, Scm);
|
Mapping.emplace(Key, Scm);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum class ConstraintKind {
|
enum class ConstraintKind {
|
||||||
Equal,
|
Equal,
|
||||||
Field,
|
Field,
|
||||||
Many,
|
Many,
|
||||||
Empty,
|
Empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Constraint {
|
class Constraint {
|
||||||
|
|
||||||
const ConstraintKind Kind;
|
const ConstraintKind Kind;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline Constraint(ConstraintKind Kind):
|
inline Constraint(ConstraintKind Kind):
|
||||||
Kind(Kind) {}
|
Kind(Kind) {}
|
||||||
|
@ -131,10 +131,10 @@ namespace bolt {
|
||||||
|
|
||||||
virtual ~Constraint() {}
|
virtual ~Constraint() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CEqual : public Constraint {
|
class CEqual : public Constraint {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Type* Left;
|
Type* Left;
|
||||||
Type* Right;
|
Type* Right;
|
||||||
|
@ -143,10 +143,10 @@ namespace bolt {
|
||||||
inline CEqual(Type* Left, Type* Right, Node* Source = nullptr):
|
inline CEqual(Type* Left, Type* Right, Node* Source = nullptr):
|
||||||
Constraint(ConstraintKind::Equal), Left(Left), Right(Right), Source(Source) {}
|
Constraint(ConstraintKind::Equal), Left(Left), Right(Right), Source(Source) {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CField : public Constraint {
|
class CField : public Constraint {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Type* TupleTy;
|
Type* TupleTy;
|
||||||
size_t I;
|
size_t I;
|
||||||
|
@ -156,30 +156,30 @@ namespace bolt {
|
||||||
inline CField(Type* TupleTy, size_t I, Type* FieldTy, Node* Source = nullptr):
|
inline CField(Type* TupleTy, size_t I, Type* FieldTy, Node* Source = nullptr):
|
||||||
Constraint(ConstraintKind::Field), TupleTy(TupleTy), I(I), FieldTy(FieldTy), Source(Source) {}
|
Constraint(ConstraintKind::Field), TupleTy(TupleTy), I(I), FieldTy(FieldTy), Source(Source) {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMany : public Constraint {
|
class CMany : public Constraint {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ConstraintSet& Elements;
|
ConstraintSet& Elements;
|
||||||
|
|
||||||
inline CMany(ConstraintSet& Elements):
|
inline CMany(ConstraintSet& Elements):
|
||||||
Constraint(ConstraintKind::Many), Elements(Elements) {}
|
Constraint(ConstraintKind::Many), Elements(Elements) {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CEmpty : public Constraint {
|
class CEmpty : public Constraint {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline CEmpty():
|
inline CEmpty():
|
||||||
Constraint(ConstraintKind::Empty) {}
|
Constraint(ConstraintKind::Empty) {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using InferContextFlagsMask = unsigned;
|
using InferContextFlagsMask = unsigned;
|
||||||
|
|
||||||
class InferContext {
|
class InferContext {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A heap-allocated list of type variables that eventually will become part of a Forall scheme.
|
* A heap-allocated list of type variables that eventually will become part of a Forall scheme.
|
||||||
|
@ -197,9 +197,9 @@ namespace bolt {
|
||||||
|
|
||||||
InferContext* Parent = nullptr;
|
InferContext* Parent = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Checker {
|
class Checker {
|
||||||
|
|
||||||
friend class Unifier;
|
friend class Unifier;
|
||||||
friend class UnificationFrame;
|
friend class UnificationFrame;
|
||||||
|
@ -313,7 +313,7 @@ namespace bolt {
|
||||||
|
|
||||||
void initialize(Node* N);
|
void initialize(Node* N);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Checker(const LanguageConfig& Config, DiagnosticEngine& DE);
|
Checker(const LanguageConfig& Config, DiagnosticEngine& DE);
|
||||||
|
|
||||||
|
@ -338,6 +338,6 @@ namespace bolt {
|
||||||
|
|
||||||
Type* getType(TypedNode* Node);
|
Type* getType(TypedNode* Node);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
class LanguageConfig {
|
class LanguageConfig {
|
||||||
|
|
||||||
enum ConfigFlags {
|
enum ConfigFlags {
|
||||||
ConfigFlags_TypeVarsRequireForall = 1 << 0,
|
ConfigFlags_TypeVarsRequireForall = 1 << 0,
|
||||||
|
@ -11,7 +11,7 @@ namespace bolt {
|
||||||
|
|
||||||
unsigned Flags = 0;
|
unsigned Flags = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void setTypeVarsRequireForall(bool Enable) {
|
void setTypeVarsRequireForall(bool Enable) {
|
||||||
if (Enable) {
|
if (Enable) {
|
||||||
|
@ -30,23 +30,23 @@ namespace bolt {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename D, typename B>
|
template<typename D, typename B>
|
||||||
D* cast(B* base) {
|
D* cast(B* base) {
|
||||||
ZEN_ASSERT(D::classof(base));
|
ZEN_ASSERT(D::classof(base));
|
||||||
return static_cast<D*>(base);
|
return static_cast<D*>(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename D, typename B>
|
template<typename D, typename B>
|
||||||
const D* cast(const B* base) {
|
const D* cast(const B* base) {
|
||||||
ZEN_ASSERT(D::classof(base));
|
ZEN_ASSERT(D::classof(base));
|
||||||
return static_cast<const D*>(base);
|
return static_cast<const D*>(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename D, typename T>
|
template<typename D, typename T>
|
||||||
bool isa(const T* value) {
|
bool isa(const T* value) {
|
||||||
return D::classof(value);
|
return D::classof(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
class Node;
|
class Node;
|
||||||
class Type;
|
class Type;
|
||||||
class TypeclassSignature;
|
class TypeclassSignature;
|
||||||
class Diagnostic;
|
class Diagnostic;
|
||||||
|
|
||||||
enum class Color {
|
enum class Color {
|
||||||
None,
|
None,
|
||||||
Black,
|
Black,
|
||||||
White,
|
White,
|
||||||
|
@ -24,23 +24,23 @@ namespace bolt {
|
||||||
Blue,
|
Blue,
|
||||||
Cyan,
|
Cyan,
|
||||||
Magenta,
|
Magenta,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum StyleFlags : unsigned {
|
enum StyleFlags : unsigned {
|
||||||
StyleFlags_None = 0,
|
StyleFlags_None = 0,
|
||||||
StyleFlags_Bold = 1 << 0,
|
StyleFlags_Bold = 1 << 0,
|
||||||
StyleFlags_Underline = 1 << 1,
|
StyleFlags_Underline = 1 << 1,
|
||||||
StyleFlags_Italic = 1 << 2,
|
StyleFlags_Italic = 1 << 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Style {
|
class Style {
|
||||||
|
|
||||||
unsigned Flags = StyleFlags_None;
|
unsigned Flags = StyleFlags_None;
|
||||||
|
|
||||||
Color FgColor = Color::None;
|
Color FgColor = Color::None;
|
||||||
Color BgColor = Color::None;
|
Color BgColor = Color::None;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Color getForegroundColor() const noexcept {
|
Color getForegroundColor() const noexcept {
|
||||||
return FgColor;
|
return FgColor;
|
||||||
|
@ -116,12 +116,12 @@ namespace bolt {
|
||||||
Flags = 0;
|
Flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints any diagnostic message that was added to it to the console.
|
* Prints any diagnostic message that was added to it to the console.
|
||||||
*/
|
*/
|
||||||
class ConsolePrinter {
|
class ConsolePrinter {
|
||||||
|
|
||||||
std::ostream& Out;
|
std::ostream& Out;
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ namespace bolt {
|
||||||
void write(std::size_t N);
|
void write(std::size_t N);
|
||||||
void write(char C);
|
void write(char C);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
unsigned ExcerptLinesPre = 2;
|
unsigned ExcerptLinesPre = 2;
|
||||||
unsigned ExcerptLinesPost = 2;
|
unsigned ExcerptLinesPost = 2;
|
||||||
|
@ -184,6 +184,6 @@ namespace bolt {
|
||||||
|
|
||||||
void writeDiagnostic(const Diagnostic& D);
|
void writeDiagnostic(const Diagnostic& D);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,20 +7,20 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
class ConsolePrinter;
|
class ConsolePrinter;
|
||||||
class Diagnostic;
|
class Diagnostic;
|
||||||
class TypeclassSignature;
|
class TypeclassSignature;
|
||||||
class Type;
|
class Type;
|
||||||
class Node;
|
class Node;
|
||||||
|
|
||||||
class DiagnosticEngine {
|
class DiagnosticEngine {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool HasError = false;
|
bool HasError = false;
|
||||||
|
|
||||||
virtual void addDiagnostic(Diagnostic* Diagnostic) = 0;
|
virtual void addDiagnostic(Diagnostic* Diagnostic) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool FailOnError = false;
|
bool FailOnError = false;
|
||||||
|
|
||||||
|
@ -39,13 +39,13 @@ namespace bolt {
|
||||||
|
|
||||||
virtual ~DiagnosticEngine() {}
|
virtual ~DiagnosticEngine() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps diagnostics alive in-memory until a seperate procedure processes them.
|
* Keeps diagnostics alive in-memory until a seperate procedure processes them.
|
||||||
*/
|
*/
|
||||||
class DiagnosticStore : public DiagnosticEngine {
|
class DiagnosticStore : public DiagnosticEngine {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::vector<Diagnostic*> Diagnostics;
|
std::vector<Diagnostic*> Diagnostics;
|
||||||
|
|
||||||
|
@ -65,20 +65,20 @@ namespace bolt {
|
||||||
|
|
||||||
~DiagnosticStore();
|
~DiagnosticStore();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConsoleDiagnostics : public DiagnosticEngine {
|
class ConsoleDiagnostics : public DiagnosticEngine {
|
||||||
|
|
||||||
ConsolePrinter& ThePrinter;
|
ConsolePrinter& ThePrinter;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void addDiagnostic(Diagnostic* Diagnostic) override;
|
void addDiagnostic(Diagnostic* Diagnostic) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ConsoleDiagnostics(ConsolePrinter& ThePrinter);
|
ConsoleDiagnostics(ConsolePrinter& ThePrinter);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
enum class DiagnosticKind : unsigned char {
|
enum class DiagnosticKind : unsigned char {
|
||||||
BindingNotFound,
|
BindingNotFound,
|
||||||
FieldNotFound,
|
FieldNotFound,
|
||||||
InstanceNotFound,
|
InstanceNotFound,
|
||||||
|
@ -21,17 +21,17 @@ namespace bolt {
|
||||||
UnexpectedString,
|
UnexpectedString,
|
||||||
UnexpectedToken,
|
UnexpectedToken,
|
||||||
UnificationError,
|
UnificationError,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Diagnostic {
|
class Diagnostic {
|
||||||
|
|
||||||
const DiagnosticKind Kind;
|
const DiagnosticKind Kind;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Diagnostic(DiagnosticKind Kind);
|
Diagnostic(DiagnosticKind Kind);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline DiagnosticKind getKind() const noexcept {
|
inline DiagnosticKind getKind() const noexcept {
|
||||||
return Kind;
|
return Kind;
|
||||||
|
@ -45,10 +45,10 @@ namespace bolt {
|
||||||
|
|
||||||
virtual ~Diagnostic() {}
|
virtual ~Diagnostic() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnexpectedStringDiagnostic : public Diagnostic {
|
class UnexpectedStringDiagnostic : public Diagnostic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TextFile& File;
|
TextFile& File;
|
||||||
TextLoc Location;
|
TextLoc Location;
|
||||||
|
@ -61,10 +61,10 @@ namespace bolt {
|
||||||
return 1001;
|
return 1001;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnexpectedTokenDiagnostic : public Diagnostic {
|
class UnexpectedTokenDiagnostic : public Diagnostic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TextFile& File;
|
TextFile& File;
|
||||||
Token* Actual;
|
Token* Actual;
|
||||||
|
@ -77,10 +77,10 @@ namespace bolt {
|
||||||
return 1101;
|
return 1101;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BindingNotFoundDiagnostic : public Diagnostic {
|
class BindingNotFoundDiagnostic : public Diagnostic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ByteString Name;
|
ByteString Name;
|
||||||
Node* Initiator;
|
Node* Initiator;
|
||||||
|
@ -96,10 +96,10 @@ namespace bolt {
|
||||||
return 2005;
|
return 2005;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnificationErrorDiagnostic : public Diagnostic {
|
class UnificationErrorDiagnostic : public Diagnostic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Type* OrigLeft;
|
Type* OrigLeft;
|
||||||
Type* OrigRight;
|
Type* OrigRight;
|
||||||
|
@ -126,10 +126,10 @@ namespace bolt {
|
||||||
return 2010;
|
return 2010;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeclassMissingDiagnostic : public Diagnostic {
|
class TypeclassMissingDiagnostic : public Diagnostic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TypeclassSignature Sig;
|
TypeclassSignature Sig;
|
||||||
Node* Decl;
|
Node* Decl;
|
||||||
|
@ -145,10 +145,10 @@ namespace bolt {
|
||||||
return 2201;
|
return 2201;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class InstanceNotFoundDiagnostic : public Diagnostic {
|
class InstanceNotFoundDiagnostic : public Diagnostic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ByteString TypeclassName;
|
ByteString TypeclassName;
|
||||||
Type* Ty;
|
Type* Ty;
|
||||||
|
@ -165,10 +165,10 @@ namespace bolt {
|
||||||
return 2251;
|
return 2251;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TupleIndexOutOfRangeDiagnostic : public Diagnostic {
|
class TupleIndexOutOfRangeDiagnostic : public Diagnostic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Type* Tuple;
|
Type* Tuple;
|
||||||
std::size_t I;
|
std::size_t I;
|
||||||
|
@ -185,10 +185,10 @@ namespace bolt {
|
||||||
return 2015;
|
return 2015;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class InvalidTypeToTypeclassDiagnostic : public Diagnostic {
|
class InvalidTypeToTypeclassDiagnostic : public Diagnostic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Type* Actual;
|
Type* Actual;
|
||||||
std::vector<TypeclassId> Classes;
|
std::vector<TypeclassId> Classes;
|
||||||
|
@ -205,10 +205,10 @@ namespace bolt {
|
||||||
return 2060;
|
return 2060;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FieldNotFoundDiagnostic : public Diagnostic {
|
class FieldNotFoundDiagnostic : public Diagnostic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ByteString Name;
|
ByteString Name;
|
||||||
Type* Ty;
|
Type* Ty;
|
||||||
|
@ -222,10 +222,10 @@ namespace bolt {
|
||||||
return 2017;
|
return 2017;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class NotATupleDiagnostic : public Diagnostic {
|
class NotATupleDiagnostic : public Diagnostic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Type* Ty;
|
Type* Ty;
|
||||||
Node* Source;
|
Node* Source;
|
||||||
|
@ -241,6 +241,6 @@ namespace bolt {
|
||||||
return 2016;
|
return 2016;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,16 +9,16 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
enum class ValueKind {
|
enum class ValueKind {
|
||||||
Empty,
|
Empty,
|
||||||
String,
|
String,
|
||||||
Integer,
|
Integer,
|
||||||
Tuple,
|
Tuple,
|
||||||
SourceFunction,
|
SourceFunction,
|
||||||
NativeFunction,
|
NativeFunction,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Value {
|
class Value {
|
||||||
|
|
||||||
using NativeFunction = std::function<Value(std::vector<Value>)>;
|
using NativeFunction = std::function<Value(std::vector<Value>)>;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace bolt {
|
||||||
Tuple T;
|
Tuple T;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Value():
|
Value():
|
||||||
Kind(ValueKind::Empty) {}
|
Kind(ValueKind::Empty) {}
|
||||||
|
@ -151,13 +151,13 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Env {
|
class Env {
|
||||||
|
|
||||||
std::unordered_map<ByteString, Value> Bindings;
|
std::unordered_map<ByteString, Value> Bindings;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void add(const ByteString& Name, Value V) {
|
void add(const ByteString& Name, Value V) {
|
||||||
Bindings.emplace(Name, V);
|
Bindings.emplace(Name, V);
|
||||||
|
@ -169,11 +169,11 @@ namespace bolt {
|
||||||
return Match->second;
|
return Match->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Evaluator {
|
class Evaluator {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void assignPattern(Pattern* P, Value& V, Env& E);
|
void assignPattern(Pattern* P, Value& V, Env& E);
|
||||||
|
|
||||||
|
@ -183,5 +183,6 @@ namespace bolt {
|
||||||
|
|
||||||
void evaluate(Node* N, Env& E);
|
void evaluate(Node* N, Env& E);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
using Integer = long long;
|
using Integer = long long;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,17 +9,17 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
class DiagnosticEngine;
|
class DiagnosticEngine;
|
||||||
class Scanner;
|
class Scanner;
|
||||||
|
|
||||||
enum OperatorFlags {
|
enum OperatorFlags {
|
||||||
OperatorFlags_Prefix = 1,
|
OperatorFlags_Prefix = 1,
|
||||||
OperatorFlags_Suffix = 2,
|
OperatorFlags_Suffix = 2,
|
||||||
OperatorFlags_InfixL = 4,
|
OperatorFlags_InfixL = 4,
|
||||||
OperatorFlags_InfixR = 8,
|
OperatorFlags_InfixR = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OperatorInfo {
|
struct OperatorInfo {
|
||||||
|
|
||||||
int Precedence;
|
int Precedence;
|
||||||
unsigned Flags;
|
unsigned Flags;
|
||||||
|
@ -40,13 +40,13 @@ namespace bolt {
|
||||||
return Flags & OperatorFlags_InfixR;
|
return Flags & OperatorFlags_InfixR;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class OperatorTable {
|
class OperatorTable {
|
||||||
|
|
||||||
std::unordered_map<std::string, OperatorInfo> Mapping;
|
std::unordered_map<std::string, OperatorInfo> Mapping;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void add(std::string Name, unsigned Flags, int Precedence);
|
void add(std::string Name, unsigned Flags, int Precedence);
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@ namespace bolt {
|
||||||
bool isPrefix(Token* T);
|
bool isPrefix(Token* T);
|
||||||
bool isSuffix(Token* T);
|
bool isSuffix(Token* T);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
|
|
||||||
TextFile& File;
|
TextFile& File;
|
||||||
DiagnosticEngine& DE;
|
DiagnosticEngine& DE;
|
||||||
|
@ -101,7 +101,7 @@ namespace bolt {
|
||||||
void skipPastLineFoldEnd();
|
void skipPastLineFoldEnd();
|
||||||
void skipToRBrace();
|
void skipToRBrace();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Parser(TextFile& File, Stream<Token*>& S, DiagnosticEngine& DE);
|
Parser(TextFile& File, Stream<Token*>& S, DiagnosticEngine& DE);
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ namespace bolt {
|
||||||
|
|
||||||
SourceFile* parseSourceFile();
|
SourceFile* parseSourceFile();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
class Token;
|
class Token;
|
||||||
class DiagnosticEngine;
|
class DiagnosticEngine;
|
||||||
|
|
||||||
class Scanner : public BufferedStream<Token*> {
|
class Scanner : public BufferedStream<Token*> {
|
||||||
|
|
||||||
DiagnosticEngine& DE;
|
DiagnosticEngine& DE;
|
||||||
|
|
||||||
|
@ -48,37 +48,37 @@ namespace bolt {
|
||||||
|
|
||||||
Token* readNullable();
|
Token* readNullable();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Token* read() override;
|
Token* read() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Scanner(DiagnosticEngine& DE, TextFile& File, Stream<Char>& Chars);
|
Scanner(DiagnosticEngine& DE, TextFile& File, Stream<Char>& Chars);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class FrameType {
|
enum class FrameType {
|
||||||
Block,
|
Block,
|
||||||
LineFold,
|
LineFold,
|
||||||
Fallthrough,
|
Fallthrough,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Punctuator : public BufferedStream<Token*> {
|
class Punctuator : public BufferedStream<Token*> {
|
||||||
|
|
||||||
Stream<Token*>& Tokens;
|
Stream<Token*>& Tokens;
|
||||||
|
|
||||||
std::stack<FrameType> Frames;
|
std::stack<FrameType> Frames;
|
||||||
std::stack<TextLoc> Locations;
|
std::stack<TextLoc> Locations;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual Token* read() override;
|
virtual Token* read() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Punctuator(Stream<Token*>& Tokens);
|
Punctuator(Stream<Token*>& Tokens);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,20 +8,20 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class Stream {
|
class Stream {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual T get() = 0;
|
virtual T get() = 0;
|
||||||
virtual T peek(std::size_t Offset = 0) = 0;
|
virtual T peek(std::size_t Offset = 0) = 0;
|
||||||
|
|
||||||
virtual ~Stream() {}
|
virtual ~Stream() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ContainerT, typename T = typename ContainerT::value_type>
|
template<typename ContainerT, typename T = typename ContainerT::value_type>
|
||||||
class VectorStream : public Stream<T> {
|
class VectorStream : public Stream<T> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
|
|
||||||
|
@ -41,18 +41,18 @@ namespace bolt {
|
||||||
return I < Data.size() ? Data[I] : Sentry;
|
return I < Data.size() ? Data[I] : Sentry;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class BufferedStream : public Stream<T> {
|
class BufferedStream : public Stream<T> {
|
||||||
|
|
||||||
std::deque<T> Buffer;
|
std::deque<T> Buffer;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual T read() = 0;
|
virtual T read() = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
|
|
||||||
|
@ -76,6 +76,6 @@ namespace bolt {
|
||||||
return Buffer[Offset];
|
return Buffer[Offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
using Char = char;
|
using Char = char;
|
||||||
|
|
||||||
using String = std::basic_string<Char>;
|
using String = std::basic_string<Char>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,13 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
template<typename V>
|
template<typename V>
|
||||||
class Graph {
|
class Graph {
|
||||||
|
|
||||||
std::unordered_set<V> Vertices;
|
std::unordered_set<V> Vertices;
|
||||||
std::unordered_multimap<V, V> Edges;
|
std::unordered_multimap<V, V> Edges;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void addVertex(V Vert) {
|
void addVertex(V Vert) {
|
||||||
Vertices.emplace(Vert);
|
Vertices.emplace(Vert);
|
||||||
|
@ -57,7 +57,7 @@ namespace bolt {
|
||||||
return zen::make_iterator_range(Vertices);
|
return zen::make_iterator_range(Vertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct TarjanVertexData {
|
struct TarjanVertexData {
|
||||||
std::optional<std::size_t> Index;
|
std::optional<std::size_t> Index;
|
||||||
|
@ -132,7 +132,7 @@ namespace bolt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::vector<std::vector<V>> strongconnect() const {
|
std::vector<std::vector<V>> strongconnect() const {
|
||||||
TarjanSolver S { *this };
|
TarjanSolver S { *this };
|
||||||
|
@ -140,6 +140,7 @@ namespace bolt {
|
||||||
return S.SCCs;
|
return S.SCCs;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,14 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
class Type;
|
class Type;
|
||||||
class TCon;
|
class TCon;
|
||||||
|
|
||||||
using TypeclassId = ByteString;
|
using TypeclassId = ByteString;
|
||||||
|
|
||||||
using TypeclassContext = std::unordered_set<TypeclassId>;
|
using TypeclassContext = std::unordered_set<TypeclassId>;
|
||||||
|
|
||||||
struct TypeclassSignature {
|
struct TypeclassSignature {
|
||||||
|
|
||||||
using TypeclassId = ByteString;
|
using TypeclassId = ByteString;
|
||||||
TypeclassId Id;
|
TypeclassId Id;
|
||||||
|
@ -31,15 +31,15 @@ namespace bolt {
|
||||||
bool operator<(const TypeclassSignature& Other) const;
|
bool operator<(const TypeclassSignature& Other) const;
|
||||||
bool operator==(const TypeclassSignature& Other) const;
|
bool operator==(const TypeclassSignature& Other) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeSig {
|
struct TypeSig {
|
||||||
Type* Orig;
|
Type* Orig;
|
||||||
Type* Op;
|
Type* Op;
|
||||||
std::vector<Type*> Args;
|
std::vector<Type*> Args;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class TypeIndexKind {
|
enum class TypeIndexKind {
|
||||||
AppOpType,
|
AppOpType,
|
||||||
AppArgType,
|
AppArgType,
|
||||||
ArrowParamType,
|
ArrowParamType,
|
||||||
|
@ -49,10 +49,10 @@ namespace bolt {
|
||||||
FieldRestType,
|
FieldRestType,
|
||||||
PresentType,
|
PresentType,
|
||||||
End,
|
End,
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeIndex {
|
class TypeIndex {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
friend class Type;
|
friend class Type;
|
||||||
friend class TypeIterator;
|
friend class TypeIterator;
|
||||||
|
@ -69,7 +69,7 @@ namespace bolt {
|
||||||
TypeIndex(TypeIndexKind Kind, std::size_t I):
|
TypeIndex(TypeIndexKind Kind, std::size_t I):
|
||||||
Kind(Kind), I(I) {}
|
Kind(Kind), I(I) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool operator==(const TypeIndex& Other) const noexcept;
|
bool operator==(const TypeIndex& Other) const noexcept;
|
||||||
|
|
||||||
|
@ -107,9 +107,9 @@ namespace bolt {
|
||||||
return { TypeIndexKind::PresentType };
|
return { TypeIndexKind::PresentType };
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeIterator {
|
class TypeIterator {
|
||||||
|
|
||||||
friend class Type;
|
friend class Type;
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ namespace bolt {
|
||||||
TypeIterator(Type* Ty, TypeIndex Index):
|
TypeIterator(Type* Ty, TypeIndex Index):
|
||||||
Ty(Ty), Index(Index) {}
|
Ty(Ty), Index(Index) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TypeIterator& operator++() noexcept {
|
TypeIterator& operator++() noexcept {
|
||||||
Index.advance(Ty);
|
Index.advance(Ty);
|
||||||
|
@ -138,14 +138,14 @@ namespace bolt {
|
||||||
return Index;
|
return Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using TypePath = std::vector<TypeIndex>;
|
using TypePath = std::vector<TypeIndex>;
|
||||||
|
|
||||||
using TVSub = std::unordered_map<Type*, Type*>;
|
using TVSub = std::unordered_map<Type*, Type*>;
|
||||||
using TVSet = std::unordered_set<Type*>;
|
using TVSet = std::unordered_set<Type*>;
|
||||||
|
|
||||||
enum class TypeKind : unsigned char {
|
enum class TypeKind : unsigned char {
|
||||||
Var,
|
Var,
|
||||||
Con,
|
Con,
|
||||||
App,
|
App,
|
||||||
|
@ -155,32 +155,32 @@ namespace bolt {
|
||||||
Nil,
|
Nil,
|
||||||
Absent,
|
Absent,
|
||||||
Present,
|
Present,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Type;
|
class Type;
|
||||||
|
|
||||||
struct TCon {
|
struct TCon {
|
||||||
size_t Id;
|
size_t Id;
|
||||||
ByteString DisplayName;
|
ByteString DisplayName;
|
||||||
|
|
||||||
bool operator==(const TCon& Other) const;
|
bool operator==(const TCon& Other) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TApp {
|
struct TApp {
|
||||||
Type* Op;
|
Type* Op;
|
||||||
Type* Arg;
|
Type* Arg;
|
||||||
|
|
||||||
bool operator==(const TApp& Other) const;
|
bool operator==(const TApp& Other) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class VarKind {
|
enum class VarKind {
|
||||||
Rigid,
|
Rigid,
|
||||||
Unification,
|
Unification,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TVar {
|
struct TVar {
|
||||||
VarKind VK;
|
VarKind VK;
|
||||||
size_t Id;
|
size_t Id;
|
||||||
TypeclassContext Context;
|
TypeclassContext Context;
|
||||||
|
@ -201,44 +201,44 @@ namespace bolt {
|
||||||
|
|
||||||
bool operator==(const TVar& Other) const;
|
bool operator==(const TVar& Other) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TArrow {
|
struct TArrow {
|
||||||
Type* ParamType;
|
Type* ParamType;
|
||||||
Type* ReturnType;
|
Type* ReturnType;
|
||||||
|
|
||||||
bool operator==(const TArrow& Other) const;
|
bool operator==(const TArrow& Other) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TTuple {
|
struct TTuple {
|
||||||
std::vector<Type*> ElementTypes;
|
std::vector<Type*> ElementTypes;
|
||||||
|
|
||||||
bool operator==(const TTuple& Other) const;
|
bool operator==(const TTuple& Other) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TNil {
|
struct TNil {
|
||||||
bool operator==(const TNil& Other) const;
|
bool operator==(const TNil& Other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TField {
|
struct TField {
|
||||||
ByteString Name;
|
ByteString Name;
|
||||||
Type* Ty;
|
Type* Ty;
|
||||||
Type* RestTy;
|
Type* RestTy;
|
||||||
bool operator==(const TField& Other) const;
|
bool operator==(const TField& Other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TAbsent {
|
struct TAbsent {
|
||||||
bool operator==(const TAbsent& Other) const;
|
bool operator==(const TAbsent& Other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TPresent {
|
struct TPresent {
|
||||||
Type* Ty;
|
Type* Ty;
|
||||||
bool operator==(const TPresent& Other) const;
|
bool operator==(const TPresent& Other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Type {
|
struct Type {
|
||||||
|
|
||||||
TypeKind Kind;
|
TypeKind Kind;
|
||||||
|
|
||||||
|
@ -607,11 +607,11 @@ namespace bolt {
|
||||||
return Curr;
|
return Curr;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<bool IsConst>
|
template<bool IsConst>
|
||||||
class TypeVisitorBase {
|
class TypeVisitorBase {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using C = std::conditional<IsConst, const T, T>::type;
|
using C = std::conditional<IsConst, const T, T>::type;
|
||||||
|
@ -660,7 +660,7 @@ namespace bolt {
|
||||||
virtual void visitNilType(C<TNil>& Ty) {
|
virtual void visitNilType(C<TNil>& Ty) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void visitEachChild(C<Type>* Ty) {
|
void visitEachChild(C<Type>* Ty) {
|
||||||
switch (Ty->getKind()) {
|
switch (Ty->getKind()) {
|
||||||
|
@ -747,9 +747,9 @@ namespace bolt {
|
||||||
|
|
||||||
virtual ~TypeVisitorBase() {}
|
virtual ~TypeVisitorBase() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using TypeVisitor = TypeVisitorBase<false>;
|
using TypeVisitor = TypeVisitorBase<false>;
|
||||||
using ConstTypeVisitor = TypeVisitorBase<true>;
|
using ConstTypeVisitor = TypeVisitorBase<true>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
Constraint* Constraint::substitute(const TVSub &Sub) {
|
Constraint* Constraint::substitute(const TVSub &Sub) {
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case ConstraintKind::Equal:
|
case ConstraintKind::Equal:
|
||||||
{
|
{
|
||||||
|
@ -41,13 +41,13 @@ namespace bolt {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::solveType(Type* Ty) {
|
Type* Checker::solveType(Type* Ty) {
|
||||||
return Ty->rewrite([this](auto Ty) { return Ty->find(); }, true);
|
return Ty->rewrite([this](auto Ty) { return Ty->find(); }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Checker::Checker(const LanguageConfig& Config, DiagnosticEngine& DE):
|
Checker::Checker(const LanguageConfig& Config, DiagnosticEngine& DE):
|
||||||
Config(Config), DE(DE) {
|
Config(Config), DE(DE) {
|
||||||
BoolType = createConType("Bool");
|
BoolType = createConType("Bool");
|
||||||
IntType = createConType("Int");
|
IntType = createConType("Int");
|
||||||
|
@ -56,7 +56,7 @@ namespace bolt {
|
||||||
UnitType = new Type(TTuple({}));
|
UnitType = new Type(TTuple({}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheme* Checker::lookup(ByteString Name, SymKind Kind) {
|
Scheme* Checker::lookup(ByteString Name, SymKind Kind) {
|
||||||
auto Curr = &getContext();
|
auto Curr = &getContext();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto Match = Curr->Env.lookup(Name, Kind);
|
auto Match = Curr->Env.lookup(Name, Kind);
|
||||||
|
@ -69,9 +69,9 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::lookupMono(ByteString Name, SymKind Kind) {
|
Type* Checker::lookupMono(ByteString Name, SymKind Kind) {
|
||||||
auto Scm = lookup(Name, Kind);
|
auto Scm = lookup(Name, Kind);
|
||||||
if (Scm == nullptr) {
|
if (Scm == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -79,46 +79,46 @@ namespace bolt {
|
||||||
auto F = static_cast<Forall*>(Scm);
|
auto F = static_cast<Forall*>(Scm);
|
||||||
ZEN_ASSERT(F->TVs == nullptr || F->TVs->empty());
|
ZEN_ASSERT(F->TVs == nullptr || F->TVs->empty());
|
||||||
return F->Type;
|
return F->Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::addBinding(ByteString Name, Scheme* Scm, SymKind Kind) {
|
void Checker::addBinding(ByteString Name, Scheme* Scm, SymKind Kind) {
|
||||||
getContext().Env.add(Name, Scm, Kind);
|
getContext().Env.add(Name, Scm, Kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::getReturnType() {
|
Type* Checker::getReturnType() {
|
||||||
auto Ty = getContext().ReturnType;
|
auto Ty = getContext().ReturnType;
|
||||||
ZEN_ASSERT(Ty != nullptr);
|
ZEN_ASSERT(Ty != nullptr);
|
||||||
return Ty;
|
return Ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasTypeVar(TVSet& Set, Type* Type) {
|
static bool hasTypeVar(TVSet& Set, Type* Type) {
|
||||||
for (auto TV: Type->getTypeVars()) {
|
for (auto TV: Type->getTypeVars()) {
|
||||||
if (Set.count(TV)) {
|
if (Set.count(TV)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::setContext(InferContext* Ctx) {
|
void Checker::setContext(InferContext* Ctx) {
|
||||||
ActiveContext = Ctx;
|
ActiveContext = Ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::popContext() {
|
void Checker::popContext() {
|
||||||
ZEN_ASSERT(ActiveContext);
|
ZEN_ASSERT(ActiveContext);
|
||||||
ActiveContext = ActiveContext->Parent;
|
ActiveContext = ActiveContext->Parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
InferContext& Checker::getContext() {
|
InferContext& Checker::getContext() {
|
||||||
ZEN_ASSERT(ActiveContext);
|
ZEN_ASSERT(ActiveContext);
|
||||||
return *ActiveContext;
|
return *ActiveContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::makeEqual(Type* A, Type* B, Node* Source) {
|
void Checker::makeEqual(Type* A, Type* B, Node* Source) {
|
||||||
addConstraint(new CEqual(A, B, Source));
|
addConstraint(new CEqual(A, B, Source));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::addConstraint(Constraint* C) {
|
void Checker::addConstraint(Constraint* C) {
|
||||||
|
|
||||||
switch (C->getKind()) {
|
switch (C->getKind()) {
|
||||||
|
|
||||||
|
@ -208,9 +208,9 @@ namespace bolt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::forwardDeclare(Node* X) {
|
void Checker::forwardDeclare(Node* X) {
|
||||||
|
|
||||||
switch (X->getKind()) {
|
switch (X->getKind()) {
|
||||||
|
|
||||||
|
@ -399,9 +399,9 @@ namespace bolt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::initialize(Node* N) {
|
void Checker::initialize(Node* N) {
|
||||||
|
|
||||||
struct Init : public CSTVisitor<Init> {
|
struct Init : public CSTVisitor<Init> {
|
||||||
|
|
||||||
|
@ -454,9 +454,9 @@ namespace bolt {
|
||||||
Init I { {}, *this };
|
Init I { {}, *this };
|
||||||
I.visit(N);
|
I.visit(N);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::forwardDeclareFunctionDeclaration(LetDeclaration* Let, TVSet* TVs, ConstraintSet* Constraints) {
|
void Checker::forwardDeclareFunctionDeclaration(LetDeclaration* Let, TVSet* TVs, ConstraintSet* Constraints) {
|
||||||
|
|
||||||
if (!Let->isFunction()) {
|
if (!Let->isFunction()) {
|
||||||
return;
|
return;
|
||||||
|
@ -568,9 +568,9 @@ namespace bolt {
|
||||||
Let->Ctx->Parent->Env.add(Let->getNameAsString(), new Forall(Let->Ctx->TVs, Let->Ctx->Constraints, Ty), SymKind::Var);
|
Let->Ctx->Parent->Env.add(Let->getNameAsString(), new Forall(Let->Ctx->TVs, Let->Ctx->Constraints, Ty), SymKind::Var);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::inferFunctionDeclaration(LetDeclaration* Decl) {
|
void Checker::inferFunctionDeclaration(LetDeclaration* Decl) {
|
||||||
|
|
||||||
if (!Decl->isFunction()) {
|
if (!Decl->isFunction()) {
|
||||||
return;
|
return;
|
||||||
|
@ -615,9 +615,9 @@ namespace bolt {
|
||||||
makeEqual(Decl->getType(), Type::buildArrow(ParamTypes, RetType), Decl);
|
makeEqual(Decl->getType(), Type::buildArrow(ParamTypes, RetType), Decl);
|
||||||
|
|
||||||
setContext(OldCtx);
|
setContext(OldCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::infer(Node* N) {
|
void Checker::infer(Node* N) {
|
||||||
|
|
||||||
switch (N->getKind()) {
|
switch (N->getKind()) {
|
||||||
|
|
||||||
|
@ -718,33 +718,33 @@ namespace bolt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::createConType(ByteString Name) {
|
Type* Checker::createConType(ByteString Name) {
|
||||||
return new Type(TCon(NextConTypeId++, Name));
|
return new Type(TCon(NextConTypeId++, Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::createRigidVar(ByteString Name) {
|
Type* Checker::createRigidVar(ByteString Name) {
|
||||||
auto TV = new Type(TVar(VarKind::Rigid, NextTypeVarId++, {}, Name, {{}}));
|
auto TV = new Type(TVar(VarKind::Rigid, NextTypeVarId++, {}, Name, {{}}));
|
||||||
getContext().TVs->emplace(TV);
|
getContext().TVs->emplace(TV);
|
||||||
return TV;
|
return TV;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::createTypeVar() {
|
Type* Checker::createTypeVar() {
|
||||||
auto TV = new Type(TVar(VarKind::Unification, NextTypeVarId++, {}));
|
auto TV = new Type(TVar(VarKind::Unification, NextTypeVarId++, {}));
|
||||||
getContext().TVs->emplace(TV);
|
getContext().TVs->emplace(TV);
|
||||||
return TV;
|
return TV;
|
||||||
}
|
}
|
||||||
|
|
||||||
InferContext* Checker::createInferContext(InferContext* Parent, TVSet* TVs, ConstraintSet* Constraints) {
|
InferContext* Checker::createInferContext(InferContext* Parent, TVSet* TVs, ConstraintSet* Constraints) {
|
||||||
auto Ctx = new InferContext;
|
auto Ctx = new InferContext;
|
||||||
Ctx->Parent = Parent;
|
Ctx->Parent = Parent;
|
||||||
Ctx->TVs = new TVSet;
|
Ctx->TVs = new TVSet;
|
||||||
Ctx->Constraints = new ConstraintSet;
|
Ctx->Constraints = new ConstraintSet;
|
||||||
return Ctx;
|
return Ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::instantiate(Scheme* Scm, Node* Source) {
|
Type* Checker::instantiate(Scheme* Scm, Node* Source) {
|
||||||
|
|
||||||
switch (Scm->getKind()) {
|
switch (Scm->getKind()) {
|
||||||
|
|
||||||
|
@ -791,9 +791,9 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
|
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::inferConstraintExpression(ConstraintExpression* C) {
|
void Checker::inferConstraintExpression(ConstraintExpression* C) {
|
||||||
switch (C->getKind()) {
|
switch (C->getKind()) {
|
||||||
case NodeKind::TypeclassConstraintExpression:
|
case NodeKind::TypeclassConstraintExpression:
|
||||||
{
|
{
|
||||||
|
@ -815,9 +815,9 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::inferTypeExpression(TypeExpression* N, bool AutoVars) {
|
Type* Checker::inferTypeExpression(TypeExpression* N, bool AutoVars) {
|
||||||
|
|
||||||
switch (N->getKind()) {
|
switch (N->getKind()) {
|
||||||
|
|
||||||
|
@ -922,9 +922,9 @@ namespace bolt {
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* sortRow(Type* Ty) {
|
Type* sortRow(Type* Ty) {
|
||||||
std::map<ByteString, Type*> Fields;
|
std::map<ByteString, Type*> Fields;
|
||||||
while (Ty->isField()) {
|
while (Ty->isField()) {
|
||||||
auto& Field = Ty->asField();
|
auto& Field = Ty->asField();
|
||||||
|
@ -935,9 +935,9 @@ namespace bolt {
|
||||||
Ty = new Type(TField(Name, Field->asField().Ty, Ty));
|
Ty = new Type(TField(Name, Field->asField().Ty, Ty));
|
||||||
}
|
}
|
||||||
return Ty;
|
return Ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::inferExpression(Expression* X) {
|
Type* Checker::inferExpression(Expression* X) {
|
||||||
|
|
||||||
Type* Ty;
|
Type* Ty;
|
||||||
|
|
||||||
|
@ -1115,22 +1115,22 @@ namespace bolt {
|
||||||
// Ty = find(Ty);
|
// Ty = find(Ty);
|
||||||
X->setType(Ty);
|
X->setType(Ty);
|
||||||
return Ty;
|
return Ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordPatternField* getRestField(std::vector<std::tuple<RecordPatternField*, Comma*>> Fields) {
|
RecordPatternField* getRestField(std::vector<std::tuple<RecordPatternField*, Comma*>> Fields) {
|
||||||
for (auto [Field, Comma]: Fields) {
|
for (auto [Field, Comma]: Fields) {
|
||||||
if (Field->DotDot) {
|
if (Field->DotDot) {
|
||||||
return Field;
|
return Field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::inferPattern(
|
Type* Checker::inferPattern(
|
||||||
Pattern* Pattern,
|
Pattern* Pattern,
|
||||||
ConstraintSet* Constraints,
|
ConstraintSet* Constraints,
|
||||||
TVSet* TVs
|
TVSet* TVs
|
||||||
) {
|
) {
|
||||||
|
|
||||||
switch (Pattern->getKind()) {
|
switch (Pattern->getKind()) {
|
||||||
|
|
||||||
|
@ -1261,9 +1261,9 @@ namespace bolt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::inferLiteral(Literal* L) {
|
Type* Checker::inferLiteral(Literal* L) {
|
||||||
Type* Ty;
|
Type* Ty;
|
||||||
switch (L->getKind()) {
|
switch (L->getKind()) {
|
||||||
case NodeKind::IntegerLiteral:
|
case NodeKind::IntegerLiteral:
|
||||||
|
@ -1277,9 +1277,9 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
ZEN_ASSERT(Ty != nullptr);
|
ZEN_ASSERT(Ty != nullptr);
|
||||||
return Ty;
|
return Ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::populate(SourceFile* SF) {
|
void Checker::populate(SourceFile* SF) {
|
||||||
|
|
||||||
struct Visitor : public CSTVisitor<Visitor> {
|
struct Visitor : public CSTVisitor<Visitor> {
|
||||||
|
|
||||||
|
@ -1318,9 +1318,9 @@ namespace bolt {
|
||||||
Visitor V { {}, RefGraph };
|
Visitor V { {}, RefGraph };
|
||||||
V.visit(SF);
|
V.visit(SF);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Checker::getType(TypedNode *Node) {
|
Type* Checker::getType(TypedNode *Node) {
|
||||||
auto Ty = Node->getType();
|
auto Ty = Node->getType();
|
||||||
if (Node->Flags & NodeFlags_TypeIsSolved) {
|
if (Node->Flags & NodeFlags_TypeIsSolved) {
|
||||||
return Ty;
|
return Ty;
|
||||||
|
@ -1329,9 +1329,9 @@ namespace bolt {
|
||||||
Node->setType(Ty);
|
Node->setType(Ty);
|
||||||
Node->Flags |= NodeFlags_TypeIsSolved;
|
Node->Flags |= NodeFlags_TypeIsSolved;
|
||||||
return Ty;
|
return Ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::check(SourceFile *SF) {
|
void Checker::check(SourceFile *SF) {
|
||||||
initialize(SF);
|
initialize(SF);
|
||||||
setContext(SF->Ctx);
|
setContext(SF->Ctx);
|
||||||
addBinding("String", new Forall(StringType), SymKind::Type);
|
addBinding("String", new Forall(StringType), SymKind::Type);
|
||||||
|
@ -1388,9 +1388,9 @@ namespace bolt {
|
||||||
} V(*this);
|
} V(*this);
|
||||||
|
|
||||||
V.visit(SF);
|
V.visit(SF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checker::solve(Constraint* Constraint) {
|
void Checker::solve(Constraint* Constraint) {
|
||||||
|
|
||||||
Queue.push_back(Constraint);
|
Queue.push_back(Constraint);
|
||||||
bool DidJoin = false;
|
bool DidJoin = false;
|
||||||
|
@ -1456,9 +1456,9 @@ namespace bolt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool assignableTo(Type* A, Type* B) {
|
bool assignableTo(Type* A, Type* B) {
|
||||||
if (A->isCon() && B->isCon()) {
|
if (A->isCon() && B->isCon()) {
|
||||||
auto& Con1 = A->asCon();
|
auto& Con1 = A->asCon();
|
||||||
auto& Con2 = B->asCon();
|
auto& Con2 = B->asCon();
|
||||||
|
@ -1469,9 +1469,9 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
// TODO must handle a TApp
|
// TODO must handle a TApp
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArrowCursor {
|
class ArrowCursor {
|
||||||
|
|
||||||
/// Types on this stack are guaranteed to be arrow types.
|
/// Types on this stack are guaranteed to be arrow types.
|
||||||
std::stack<std::tuple<Type*, bool>> Stack;
|
std::stack<std::tuple<Type*, bool>> Stack;
|
||||||
|
@ -1479,7 +1479,7 @@ namespace bolt {
|
||||||
TypePath& Path;
|
TypePath& Path;
|
||||||
std::size_t I;
|
std::size_t I;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ArrowCursor(Type* Arr, TypePath& Path):
|
ArrowCursor(Type* Arr, TypePath& Path):
|
||||||
Path(Path) {
|
Path(Path) {
|
||||||
|
@ -1514,9 +1514,9 @@ namespace bolt {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Unifier {
|
struct Unifier {
|
||||||
|
|
||||||
Checker& C;
|
Checker& C;
|
||||||
// CEqual* Constraint;
|
// CEqual* Constraint;
|
||||||
|
@ -1659,9 +1659,9 @@ namespace bolt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Unifier::unifyField(Type* A, Type* B, bool DidSwap) {
|
bool Unifier::unifyField(Type* A, Type* B, bool DidSwap) {
|
||||||
if (A->isAbsent() && B->isAbsent()) {
|
if (A->isAbsent() && B->isAbsent()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1677,9 +1677,9 @@ namespace bolt {
|
||||||
auto& Present1 = A->asPresent();
|
auto& Present1 = A->asPresent();
|
||||||
auto& Present2 = B->asPresent();
|
auto& Present2 = B->asPresent();
|
||||||
return unify(Present1.Ty, Present2.Ty, DidSwap);
|
return unify(Present1.Ty, Present2.Ty, DidSwap);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Unifier::unify(Type* A, Type* B, bool DidSwap) {
|
bool Unifier::unify(Type* A, Type* B, bool DidSwap) {
|
||||||
|
|
||||||
A = A->find();
|
A = A->find();
|
||||||
B = B->find();
|
B = B->find();
|
||||||
|
@ -1937,14 +1937,14 @@ namespace bolt {
|
||||||
|
|
||||||
unifyError();
|
unifyError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Checker::unify(Type* Left, Type* Right, Node* Source) {
|
bool Checker::unify(Type* Left, Type* Right, Node* Source) {
|
||||||
// std::cerr << describe(C->Left) << " ~ " << describe(C->Right) << std::endl;
|
// std::cerr << describe(C->Left) << " ~ " << describe(C->Right) << std::endl;
|
||||||
Unifier A { *this, Left, Right, Source };
|
Unifier A { *this, Left, Right, Source };
|
||||||
A.unify();
|
A.unify();
|
||||||
return A.DidJoin;
|
return A.DidJoin;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,15 +37,15 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T countDigits(T number) {
|
T countDigits(T number) {
|
||||||
if (number == 0) {
|
if (number == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return std::ceil(std::log10(number+1));
|
return std::ceil(std::log10(number+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string describe(NodeKind Type) {
|
static std::string describe(NodeKind Type) {
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
case NodeKind::Identifier:
|
case NodeKind::Identifier:
|
||||||
return "an identifier starting with a lowercase letter";
|
return "an identifier starting with a lowercase letter";
|
||||||
|
@ -180,9 +180,9 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string describe(Token* T) {
|
static std::string describe(Token* T) {
|
||||||
switch (T->getKind()) {
|
switch (T->getKind()) {
|
||||||
case NodeKind::LineFoldEnd:
|
case NodeKind::LineFoldEnd:
|
||||||
case NodeKind::BlockStart:
|
case NodeKind::BlockStart:
|
||||||
|
@ -192,9 +192,9 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
return "'" + T->getText() + "'";
|
return "'" + T->getText() + "'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string describe(const Type* Ty) {
|
std::string describe(const Type* Ty) {
|
||||||
Ty = Ty->find();
|
Ty = Ty->find();
|
||||||
switch (Ty->getKind()) {
|
switch (Ty->getKind()) {
|
||||||
case TypeKind::Var:
|
case TypeKind::Var:
|
||||||
|
@ -265,9 +265,9 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeForegroundANSI(Color C, std::ostream& Out) {
|
void writeForegroundANSI(Color C, std::ostream& Out) {
|
||||||
switch (C) {
|
switch (C) {
|
||||||
case Color::None:
|
case Color::None:
|
||||||
break;
|
break;
|
||||||
|
@ -296,9 +296,9 @@ namespace bolt {
|
||||||
Out << ANSI_FG_MAGENTA;
|
Out << ANSI_FG_MAGENTA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeBackgroundANSI(Color C, std::ostream& Out) {
|
void writeBackgroundANSI(Color C, std::ostream& Out) {
|
||||||
switch (C) {
|
switch (C) {
|
||||||
case Color::None:
|
case Color::None:
|
||||||
break;
|
break;
|
||||||
|
@ -327,20 +327,20 @@ namespace bolt {
|
||||||
Out << ANSI_BG_MAGENTA;
|
Out << ANSI_BG_MAGENTA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsolePrinter::ConsolePrinter(std::ostream& Out):
|
ConsolePrinter::ConsolePrinter(std::ostream& Out):
|
||||||
Out(Out) {}
|
Out(Out) {}
|
||||||
|
|
||||||
void ConsolePrinter::setForegroundColor(Color C) {
|
void ConsolePrinter::setForegroundColor(Color C) {
|
||||||
ActiveStyle.setForegroundColor(C);
|
ActiveStyle.setForegroundColor(C);
|
||||||
if (!EnableColors) {
|
if (!EnableColors) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
writeForegroundANSI(C, Out);
|
writeForegroundANSI(C, Out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::setBackgroundColor(Color C) {
|
void ConsolePrinter::setBackgroundColor(Color C) {
|
||||||
ActiveStyle.setBackgroundColor(C);
|
ActiveStyle.setBackgroundColor(C);
|
||||||
if (!EnableColors) {
|
if (!EnableColors) {
|
||||||
return;
|
return;
|
||||||
|
@ -350,9 +350,9 @@ namespace bolt {
|
||||||
applyStyles();
|
applyStyles();
|
||||||
}
|
}
|
||||||
writeBackgroundANSI(C, Out);
|
writeBackgroundANSI(C, Out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::applyStyles() {
|
void ConsolePrinter::applyStyles() {
|
||||||
if (ActiveStyle.isBold()) {
|
if (ActiveStyle.isBold()) {
|
||||||
Out << ANSI_BOLD;
|
Out << ANSI_BOLD;
|
||||||
}
|
}
|
||||||
|
@ -368,9 +368,9 @@ namespace bolt {
|
||||||
if (ActiveStyle.hasForegroundColor()) {
|
if (ActiveStyle.hasForegroundColor()) {
|
||||||
setForegroundColor(ActiveStyle.getForegroundColor());
|
setForegroundColor(ActiveStyle.getForegroundColor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::setBold(bool Enable) {
|
void ConsolePrinter::setBold(bool Enable) {
|
||||||
ActiveStyle.setBold(Enable);
|
ActiveStyle.setBold(Enable);
|
||||||
if (!EnableColors) {
|
if (!EnableColors) {
|
||||||
return;
|
return;
|
||||||
|
@ -381,9 +381,9 @@ namespace bolt {
|
||||||
Out << ANSI_RESET;
|
Out << ANSI_RESET;
|
||||||
applyStyles();
|
applyStyles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::setItalic(bool Enable) {
|
void ConsolePrinter::setItalic(bool Enable) {
|
||||||
ActiveStyle.setItalic(Enable);
|
ActiveStyle.setItalic(Enable);
|
||||||
if (!EnableColors) {
|
if (!EnableColors) {
|
||||||
return;
|
return;
|
||||||
|
@ -394,9 +394,9 @@ namespace bolt {
|
||||||
Out << ANSI_RESET;
|
Out << ANSI_RESET;
|
||||||
applyStyles();
|
applyStyles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::setUnderline(bool Enable) {
|
void ConsolePrinter::setUnderline(bool Enable) {
|
||||||
ActiveStyle.setItalic(Enable);
|
ActiveStyle.setItalic(Enable);
|
||||||
if (!EnableColors) {
|
if (!EnableColors) {
|
||||||
return;
|
return;
|
||||||
|
@ -407,19 +407,19 @@ namespace bolt {
|
||||||
Out << ANSI_RESET;
|
Out << ANSI_RESET;
|
||||||
applyStyles();
|
applyStyles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::resetStyles() {
|
void ConsolePrinter::resetStyles() {
|
||||||
ActiveStyle.reset();
|
ActiveStyle.reset();
|
||||||
if (EnableColors) {
|
if (EnableColors) {
|
||||||
Out << ANSI_RESET;
|
Out << ANSI_RESET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeGutter(
|
void ConsolePrinter::writeGutter(
|
||||||
std::size_t GutterWidth,
|
std::size_t GutterWidth,
|
||||||
std::string Text
|
std::string Text
|
||||||
) {
|
) {
|
||||||
ZEN_ASSERT(Text.size() <= GutterWidth);
|
ZEN_ASSERT(Text.size() <= GutterWidth);
|
||||||
auto LeadingSpaces = GutterWidth - Text.size();
|
auto LeadingSpaces = GutterWidth - Text.size();
|
||||||
Out << " ";
|
Out << " ";
|
||||||
|
@ -431,15 +431,15 @@ namespace bolt {
|
||||||
Out << Text;
|
Out << Text;
|
||||||
resetStyles();
|
resetStyles();
|
||||||
Out << " ";
|
Out << " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeHighlight(
|
void ConsolePrinter::writeHighlight(
|
||||||
std::size_t GutterWidth,
|
std::size_t GutterWidth,
|
||||||
TextRange Range,
|
TextRange Range,
|
||||||
Color HighlightColor,
|
Color HighlightColor,
|
||||||
std::size_t Line,
|
std::size_t Line,
|
||||||
std::size_t LineLength
|
std::size_t LineLength
|
||||||
) {
|
) {
|
||||||
if (Line < Range.Start.Line || Range.End.Line < Line) {
|
if (Line < Range.Start.Line || Range.End.Line < Line) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -465,14 +465,14 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
resetStyles();
|
resetStyles();
|
||||||
Out << '\n';
|
Out << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeExcerpt(
|
void ConsolePrinter::writeExcerpt(
|
||||||
const TextFile& File,
|
const TextFile& File,
|
||||||
TextRange ToPrint,
|
TextRange ToPrint,
|
||||||
TextRange ToHighlight,
|
TextRange ToHighlight,
|
||||||
Color HighlightColor
|
Color HighlightColor
|
||||||
) {
|
) {
|
||||||
|
|
||||||
auto LineCount = File.getLineCount();
|
auto LineCount = File.getLineCount();
|
||||||
auto Text = File.getText();
|
auto Text = File.getText();
|
||||||
|
@ -508,32 +508,32 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::write(const std::string_view& S) {
|
void ConsolePrinter::write(const std::string_view& S) {
|
||||||
Out << S;
|
Out << S;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::write(char C) {
|
void ConsolePrinter::write(char C) {
|
||||||
Out << C;
|
Out << C;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::write(std::size_t I) {
|
void ConsolePrinter::write(std::size_t I) {
|
||||||
Out << I;
|
Out << I;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeBinding(const ByteString& Name) {
|
void ConsolePrinter::writeBinding(const ByteString& Name) {
|
||||||
write("'");
|
write("'");
|
||||||
write(Name);
|
write(Name);
|
||||||
write("'");
|
write("'");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeType(const Type* Ty) {
|
void ConsolePrinter::writeType(const Type* Ty) {
|
||||||
TypePath Path;
|
TypePath Path;
|
||||||
writeType(Ty, Path);
|
writeType(Ty, Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeType(const Type* Ty, const TypePath& Underline) {
|
void ConsolePrinter::writeType(const Type* Ty, const TypePath& Underline) {
|
||||||
|
|
||||||
setForegroundColor(Color::Green);
|
setForegroundColor(Color::Green);
|
||||||
|
|
||||||
|
@ -667,20 +667,20 @@ namespace bolt {
|
||||||
P.visit(Ty);
|
P.visit(Ty);
|
||||||
|
|
||||||
resetStyles();
|
resetStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeType(std::size_t I) {
|
void ConsolePrinter::writeType(std::size_t I) {
|
||||||
setForegroundColor(Color::Green);
|
setForegroundColor(Color::Green);
|
||||||
write(I);
|
write(I);
|
||||||
resetStyles();
|
resetStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeNode(const Node* N) {
|
void ConsolePrinter::writeNode(const Node* N) {
|
||||||
auto Range = N->getRange();
|
auto Range = N->getRange();
|
||||||
writeExcerpt(N->getSourceFile()->getTextFile(), Range, Range, Color::Red);
|
writeExcerpt(N->getSourceFile()->getTextFile(), Range, Range, Color::Red);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeLoc(const TextFile& File, const TextLoc& Loc) {
|
void ConsolePrinter::writeLoc(const TextFile& File, const TextLoc& Loc) {
|
||||||
setForegroundColor(Color::Yellow);
|
setForegroundColor(Color::Yellow);
|
||||||
write(File.getPath());
|
write(File.getPath());
|
||||||
write(":");
|
write(":");
|
||||||
|
@ -689,22 +689,22 @@ namespace bolt {
|
||||||
write(Loc.Column);
|
write(Loc.Column);
|
||||||
write(":");
|
write(":");
|
||||||
resetStyles();
|
resetStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writePrefix(const Diagnostic& D) {
|
void ConsolePrinter::writePrefix(const Diagnostic& D) {
|
||||||
setForegroundColor(Color::Red);
|
setForegroundColor(Color::Red);
|
||||||
setBold(true);
|
setBold(true);
|
||||||
write("error: ");
|
write("error: ");
|
||||||
resetStyles();
|
resetStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeTypeclassName(const ByteString& Name) {
|
void ConsolePrinter::writeTypeclassName(const ByteString& Name) {
|
||||||
setForegroundColor(Color::Magenta);
|
setForegroundColor(Color::Magenta);
|
||||||
write(Name);
|
write(Name);
|
||||||
resetStyles();
|
resetStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeTypeclassSignature(const TypeclassSignature& Sig) {
|
void ConsolePrinter::writeTypeclassSignature(const TypeclassSignature& Sig) {
|
||||||
setForegroundColor(Color::Magenta);
|
setForegroundColor(Color::Magenta);
|
||||||
write(Sig.Id);
|
write(Sig.Id);
|
||||||
for (auto TV: Sig.Params) {
|
for (auto TV: Sig.Params) {
|
||||||
|
@ -712,9 +712,9 @@ namespace bolt {
|
||||||
write(describe(TV));
|
write(describe(TV));
|
||||||
}
|
}
|
||||||
resetStyles();
|
resetStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsolePrinter::writeDiagnostic(const Diagnostic& D) {
|
void ConsolePrinter::writeDiagnostic(const Diagnostic& D) {
|
||||||
|
|
||||||
switch (D.getKind()) {
|
switch (D.getKind()) {
|
||||||
|
|
||||||
|
@ -930,6 +930,6 @@ namespace bolt {
|
||||||
|
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,10 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
Diagnostic::Diagnostic(DiagnosticKind Kind):
|
Diagnostic::Diagnostic(DiagnosticKind Kind):
|
||||||
Kind(Kind) {}
|
Kind(Kind) {}
|
||||||
|
|
||||||
bool sourceLocLessThan(const Diagnostic* L, const Diagnostic* R) {
|
bool sourceLocLessThan(const Diagnostic* L, const Diagnostic* R) {
|
||||||
auto N1 = L->getNode();
|
auto N1 = L->getNode();
|
||||||
auto N2 = R->getNode();
|
auto N2 = R->getNode();
|
||||||
if (N1 == nullptr && N2 == nullptr) {
|
if (N1 == nullptr && N2 == nullptr) {
|
||||||
|
@ -54,28 +54,28 @@ namespace bolt {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return N1->getStartLine() < N2->getStartLine() || N1->getStartColumn() < N2->getStartColumn();
|
return N1->getStartLine() < N2->getStartLine() || N1->getStartColumn() < N2->getStartColumn();
|
||||||
};
|
};
|
||||||
|
|
||||||
void DiagnosticStore::sort() {
|
void DiagnosticStore::sort() {
|
||||||
std::sort(Diagnostics.begin(), Diagnostics.end(), sourceLocLessThan);
|
std::sort(Diagnostics.begin(), Diagnostics.end(), sourceLocLessThan);
|
||||||
}
|
}
|
||||||
|
|
||||||
DiagnosticStore::~DiagnosticStore() {
|
DiagnosticStore::~DiagnosticStore() {
|
||||||
for (auto D: Diagnostics) {
|
for (auto D: Diagnostics) {
|
||||||
delete D;
|
delete D;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleDiagnostics::ConsoleDiagnostics(ConsolePrinter& P):
|
ConsoleDiagnostics::ConsoleDiagnostics(ConsolePrinter& P):
|
||||||
ThePrinter(P) {}
|
ThePrinter(P) {}
|
||||||
|
|
||||||
void ConsoleDiagnostics::addDiagnostic(Diagnostic* D) {
|
void ConsoleDiagnostics::addDiagnostic(Diagnostic* D) {
|
||||||
|
|
||||||
ThePrinter.writeDiagnostic(*D);
|
ThePrinter.writeDiagnostic(*D);
|
||||||
|
|
||||||
// Since this DiagnosticEngine is expected to own the diagnostic, we simply
|
// Since this DiagnosticEngine is expected to own the diagnostic, we simply
|
||||||
// destroy the processed diagnostic so that there are no memory leaks.
|
// destroy the processed diagnostic so that there are no memory leaks.
|
||||||
delete D;
|
delete D;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
Value Evaluator::evaluateExpression(Expression* X, Env& Env) {
|
Value Evaluator::evaluateExpression(Expression* X, Env& Env) {
|
||||||
switch (X->getKind()) {
|
switch (X->getKind()) {
|
||||||
case NodeKind::ReferenceExpression:
|
case NodeKind::ReferenceExpression:
|
||||||
{
|
{
|
||||||
|
@ -41,9 +41,9 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Evaluator::assignPattern(Pattern* P, Value& V, Env& E) {
|
void Evaluator::assignPattern(Pattern* P, Value& V, Env& E) {
|
||||||
switch (P->getKind()) {
|
switch (P->getKind()) {
|
||||||
case NodeKind::BindPattern:
|
case NodeKind::BindPattern:
|
||||||
{
|
{
|
||||||
|
@ -54,9 +54,9 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Evaluator::apply(Value Op, std::vector<Value> Args) {
|
Value Evaluator::apply(Value Op, std::vector<Value> Args) {
|
||||||
switch (Op.getKind()) {
|
switch (Op.getKind()) {
|
||||||
case ValueKind::SourceFunction:
|
case ValueKind::SourceFunction:
|
||||||
{
|
{
|
||||||
|
@ -80,9 +80,9 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Evaluator::evaluate(Node* N, Env& E) {
|
void Evaluator::evaluate(Node* N, Env& E) {
|
||||||
switch (N->getKind()) {
|
switch (N->getKind()) {
|
||||||
case NodeKind::SourceFile:
|
case NodeKind::SourceFile:
|
||||||
{
|
{
|
||||||
|
@ -122,6 +122,6 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
bool isOperator(Token* T) {
|
bool isOperator(Token* T) {
|
||||||
switch (T->getKind()) {
|
switch (T->getKind()) {
|
||||||
case NodeKind::VBar:
|
case NodeKind::VBar:
|
||||||
case NodeKind::CustomOperator:
|
case NodeKind::CustomOperator:
|
||||||
|
@ -40,36 +40,36 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<OperatorInfo> OperatorTable::getInfix(Token* T) {
|
std::optional<OperatorInfo> OperatorTable::getInfix(Token* T) {
|
||||||
auto Match = Mapping.find(T->getText());
|
auto Match = Mapping.find(T->getText());
|
||||||
if (Match == Mapping.end() || !Match->second.isInfix()) {
|
if (Match == Mapping.end() || !Match->second.isInfix()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return Match->second;
|
return Match->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OperatorTable::isInfix(Token* T) {
|
bool OperatorTable::isInfix(Token* T) {
|
||||||
auto Match = Mapping.find(T->getText());
|
auto Match = Mapping.find(T->getText());
|
||||||
return Match != Mapping.end() && Match->second.isInfix();
|
return Match != Mapping.end() && Match->second.isInfix();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OperatorTable::isPrefix(Token* T) {
|
bool OperatorTable::isPrefix(Token* T) {
|
||||||
auto Match = Mapping.find(T->getText());
|
auto Match = Mapping.find(T->getText());
|
||||||
return Match != Mapping.end() && Match->second.isPrefix();
|
return Match != Mapping.end() && Match->second.isPrefix();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OperatorTable::isSuffix(Token* T) {
|
bool OperatorTable::isSuffix(Token* T) {
|
||||||
auto Match = Mapping.find(T->getText());
|
auto Match = Mapping.find(T->getText());
|
||||||
return Match != Mapping.end() && Match->second.isSuffix();
|
return Match != Mapping.end() && Match->second.isSuffix();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OperatorTable::add(std::string Name, unsigned Flags, int Precedence) {
|
void OperatorTable::add(std::string Name, unsigned Flags, int Precedence) {
|
||||||
Mapping.emplace(Name, OperatorInfo { Precedence, Flags });
|
Mapping.emplace(Name, OperatorInfo { Precedence, Flags });
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::Parser(TextFile& File, Stream<Token*>& S, DiagnosticEngine& DE):
|
Parser::Parser(TextFile& File, Stream<Token*>& S, DiagnosticEngine& DE):
|
||||||
File(File), Tokens(S), DE(DE) {
|
File(File), Tokens(S), DE(DE) {
|
||||||
ExprOperators.add("**", OperatorFlags_InfixR, 10);
|
ExprOperators.add("**", OperatorFlags_InfixR, 10);
|
||||||
ExprOperators.add("*", OperatorFlags_InfixL, 5);
|
ExprOperators.add("*", OperatorFlags_InfixL, 5);
|
||||||
|
@ -87,7 +87,7 @@ namespace bolt {
|
||||||
ExprOperators.add("$", OperatorFlags_InfixR, 0);
|
ExprOperators.add("$", OperatorFlags_InfixR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* Parser::peekFirstTokenAfterAnnotationsAndModifiers() {
|
Token* Parser::peekFirstTokenAfterAnnotationsAndModifiers() {
|
||||||
std::size_t I = 0;
|
std::size_t I = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T0 = Tokens.peek(I++);
|
auto T0 = Tokens.peek(I++);
|
||||||
|
@ -107,9 +107,9 @@ namespace bolt {
|
||||||
return T0;
|
return T0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* Parser::expectToken(NodeKind Kind) {
|
Token* Parser::expectToken(NodeKind Kind) {
|
||||||
auto T = Tokens.peek();
|
auto T = Tokens.peek();
|
||||||
if (T->getKind() != Kind) {
|
if (T->getKind() != Kind) {
|
||||||
DE.add<UnexpectedTokenDiagnostic>(File, T, std::vector<NodeKind> { Kind });
|
DE.add<UnexpectedTokenDiagnostic>(File, T, std::vector<NodeKind> { Kind });
|
||||||
|
@ -117,9 +117,9 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
Tokens.get();
|
Tokens.get();
|
||||||
return T;
|
return T;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListPattern* Parser::parseListPattern() {
|
ListPattern* Parser::parseListPattern() {
|
||||||
auto LBracket = expectToken<class LBracket>();
|
auto LBracket = expectToken<class LBracket>();
|
||||||
if (!LBracket) {
|
if (!LBracket) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -159,9 +159,9 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
finish:
|
finish:
|
||||||
return new ListPattern { LBracket, Elements, RBracket };
|
return new ListPattern { LBracket, Elements, RBracket };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::vector<std::tuple<RecordPatternField*, Comma*>>> Parser::parseRecordPatternFields() {
|
std::optional<std::vector<std::tuple<RecordPatternField*, Comma*>>> Parser::parseRecordPatternFields() {
|
||||||
std::vector<std::tuple<RecordPatternField*, Comma*>> Fields;
|
std::vector<std::tuple<RecordPatternField*, Comma*>> Fields;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
|
@ -209,9 +209,9 @@ finish:
|
||||||
Fields.push_back(std::make_tuple(Field, Comma));
|
Fields.push_back(std::make_tuple(Field, Comma));
|
||||||
}
|
}
|
||||||
return Fields;
|
return Fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pattern* Parser::parsePrimitivePattern(bool IsNarrow) {
|
Pattern* Parser::parsePrimitivePattern(bool IsNarrow) {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
switch (T0->getKind()) {
|
switch (T0->getKind()) {
|
||||||
case NodeKind::StringLiteral:
|
case NodeKind::StringLiteral:
|
||||||
|
@ -336,21 +336,21 @@ finish:
|
||||||
});
|
});
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pattern* Parser::parseWidePattern() {
|
Pattern* Parser::parseWidePattern() {
|
||||||
return parsePrimitivePattern(false);
|
return parsePrimitivePattern(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pattern* Parser::parseNarrowPattern() {
|
Pattern* Parser::parseNarrowPattern() {
|
||||||
return parsePrimitivePattern(true);
|
return parsePrimitivePattern(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeExpression* Parser::parseTypeExpression() {
|
TypeExpression* Parser::parseTypeExpression() {
|
||||||
return parseQualifiedTypeExpression();
|
return parseQualifiedTypeExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeExpression* Parser::parseQualifiedTypeExpression() {
|
TypeExpression* Parser::parseQualifiedTypeExpression() {
|
||||||
bool HasConstraints = false;
|
bool HasConstraints = false;
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
if (isa<LParen>(T0)) {
|
if (isa<LParen>(T0)) {
|
||||||
|
@ -436,9 +436,9 @@ after_constraints:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return new QualifiedTypeExpression(Constraints, RArrowAlt, TE);
|
return new QualifiedTypeExpression(Constraints, RArrowAlt, TE);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeExpression* Parser::parsePrimitiveTypeExpression() {
|
TypeExpression* Parser::parsePrimitiveTypeExpression() {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
switch (T0->getKind()) {
|
switch (T0->getKind()) {
|
||||||
case NodeKind::Identifier:
|
case NodeKind::Identifier:
|
||||||
|
@ -585,9 +585,9 @@ after_tuple_element:
|
||||||
DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector { NodeKind::Identifier, NodeKind::IdentifierAlt, NodeKind::LParen });
|
DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector { NodeKind::Identifier, NodeKind::IdentifierAlt, NodeKind::LParen });
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReferenceTypeExpression* Parser::parseReferenceTypeExpression() {
|
ReferenceTypeExpression* Parser::parseReferenceTypeExpression() {
|
||||||
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
|
std::vector<std::tuple<IdentifierAlt*, Dot*>> ModulePath;
|
||||||
auto Name = expectToken<IdentifierAlt>();
|
auto Name = expectToken<IdentifierAlt>();
|
||||||
if (!Name) {
|
if (!Name) {
|
||||||
|
@ -610,9 +610,9 @@ after_tuple_element:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ReferenceTypeExpression(ModulePath, static_cast<IdentifierAlt*>(Name));
|
return new ReferenceTypeExpression(ModulePath, static_cast<IdentifierAlt*>(Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeExpression* Parser::parseAppTypeExpression() {
|
TypeExpression* Parser::parseAppTypeExpression() {
|
||||||
auto OpTy = parsePrimitiveTypeExpression();
|
auto OpTy = parsePrimitiveTypeExpression();
|
||||||
if (!OpTy) {
|
if (!OpTy) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -647,9 +647,9 @@ after_tuple_element:
|
||||||
return OpTy;
|
return OpTy;
|
||||||
}
|
}
|
||||||
return new AppTypeExpression { OpTy, ArgTys };
|
return new AppTypeExpression { OpTy, ArgTys };
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeExpression* Parser::parseArrowTypeExpression() {
|
TypeExpression* Parser::parseArrowTypeExpression() {
|
||||||
auto RetType = parseAppTypeExpression();
|
auto RetType = parseAppTypeExpression();
|
||||||
if (RetType == nullptr) {
|
if (RetType == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -674,9 +674,9 @@ after_tuple_element:
|
||||||
return new ArrowTypeExpression(ParamTypes, RetType);
|
return new ArrowTypeExpression(ParamTypes, RetType);
|
||||||
}
|
}
|
||||||
return RetType;
|
return RetType;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchExpression* Parser::parseMatchExpression() {
|
MatchExpression* Parser::parseMatchExpression() {
|
||||||
auto T0 = expectToken<MatchKeyword>();
|
auto T0 = expectToken<MatchKeyword>();
|
||||||
if (!T0) {
|
if (!T0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -730,9 +730,9 @@ after_tuple_element:
|
||||||
Cases.push_back(new MatchCase { Pattern, RArrowAlt, Expression });
|
Cases.push_back(new MatchCase { Pattern, RArrowAlt, Expression });
|
||||||
}
|
}
|
||||||
return new MatchExpression(static_cast<MatchKeyword*>(T0), Value, BlockStart, Cases);
|
return new MatchExpression(static_cast<MatchKeyword*>(T0), Value, BlockStart, Cases);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordExpression* Parser::parseRecordExpression() {
|
RecordExpression* Parser::parseRecordExpression() {
|
||||||
auto LBrace = expectToken<class LBrace>();
|
auto LBrace = expectToken<class LBrace>();
|
||||||
if (!LBrace) {
|
if (!LBrace) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -799,9 +799,9 @@ after_tuple_element:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new RecordExpression { LBrace, Fields, RBrace };
|
return new RecordExpression { LBrace, Fields, RBrace };
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* Parser::parsePrimitiveExpression() {
|
Expression* Parser::parsePrimitiveExpression() {
|
||||||
auto Annotations = parseAnnotations();
|
auto Annotations = parseAnnotations();
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
switch (T0->getKind()) {
|
switch (T0->getKind()) {
|
||||||
|
@ -906,9 +906,9 @@ after_tuple_elements:
|
||||||
});
|
});
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* Parser::parseMemberExpression() {
|
Expression* Parser::parseMemberExpression() {
|
||||||
auto E = parsePrimitiveExpression();
|
auto E = parsePrimitiveExpression();
|
||||||
if (!E) {
|
if (!E) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -936,9 +936,9 @@ after_tuple_elements:
|
||||||
}
|
}
|
||||||
finish:
|
finish:
|
||||||
return E;
|
return E;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* Parser::parseCallExpression() {
|
Expression* Parser::parseCallExpression() {
|
||||||
auto Operator = parseMemberExpression();
|
auto Operator = parseMemberExpression();
|
||||||
if (!Operator) {
|
if (!Operator) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -971,9 +971,9 @@ finish:
|
||||||
auto Annotations = Operator->Annotations;
|
auto Annotations = Operator->Annotations;
|
||||||
Operator->Annotations = {};
|
Operator->Annotations = {};
|
||||||
return new CallExpression(Annotations, Operator, Args);
|
return new CallExpression(Annotations, Operator, Args);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* Parser::parseUnaryExpression() {
|
Expression* Parser::parseUnaryExpression() {
|
||||||
std::vector<Token*> Prefix;
|
std::vector<Token*> Prefix;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
|
@ -994,9 +994,9 @@ finish:
|
||||||
E = new PrefixExpression(*Iter, E);
|
E = new PrefixExpression(*Iter, E);
|
||||||
}
|
}
|
||||||
return E;
|
return E;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* Parser::parseInfixOperatorAfterExpression(Expression* Left, int MinPrecedence) {
|
Expression* Parser::parseInfixOperatorAfterExpression(Expression* Left, int MinPrecedence) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
auto Info0 = ExprOperators.getInfix(T0);
|
auto Info0 = ExprOperators.getInfix(T0);
|
||||||
|
@ -1028,17 +1028,17 @@ finish:
|
||||||
Left = new InfixExpression(Left, T0, Right);
|
Left = new InfixExpression(Left, T0, Right);
|
||||||
}
|
}
|
||||||
return Left;
|
return Left;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* Parser::parseExpression() {
|
Expression* Parser::parseExpression() {
|
||||||
auto Left = parseUnaryExpression();
|
auto Left = parseUnaryExpression();
|
||||||
if (!Left) {
|
if (!Left) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return parseInfixOperatorAfterExpression(Left, 0);
|
return parseInfixOperatorAfterExpression(Left, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpressionStatement* Parser::parseExpressionStatement() {
|
ExpressionStatement* Parser::parseExpressionStatement() {
|
||||||
auto E = parseExpression();
|
auto E = parseExpression();
|
||||||
if (!E) {
|
if (!E) {
|
||||||
skipPastLineFoldEnd();
|
skipPastLineFoldEnd();
|
||||||
|
@ -1046,9 +1046,9 @@ finish:
|
||||||
}
|
}
|
||||||
checkLineFoldEnd();
|
checkLineFoldEnd();
|
||||||
return new ExpressionStatement(E);
|
return new ExpressionStatement(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnStatement* Parser::parseReturnStatement() {
|
ReturnStatement* Parser::parseReturnStatement() {
|
||||||
auto Annotations = parseAnnotations();
|
auto Annotations = parseAnnotations();
|
||||||
auto ReturnKeyword = expectToken<class ReturnKeyword>();
|
auto ReturnKeyword = expectToken<class ReturnKeyword>();
|
||||||
if (!ReturnKeyword) {
|
if (!ReturnKeyword) {
|
||||||
|
@ -1069,9 +1069,9 @@ finish:
|
||||||
checkLineFoldEnd();
|
checkLineFoldEnd();
|
||||||
}
|
}
|
||||||
return new ReturnStatement(Annotations, ReturnKeyword, Expression);
|
return new ReturnStatement(Annotations, ReturnKeyword, Expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
IfStatement* Parser::parseIfStatement() {
|
IfStatement* Parser::parseIfStatement() {
|
||||||
std::vector<IfStatementPart*> Parts;
|
std::vector<IfStatementPart*> Parts;
|
||||||
auto Annotations = parseAnnotations();
|
auto Annotations = parseAnnotations();
|
||||||
auto IfKeyword = expectToken<class IfKeyword>();
|
auto IfKeyword = expectToken<class IfKeyword>();
|
||||||
|
@ -1139,9 +1139,9 @@ finish:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new IfStatement(Parts);
|
return new IfStatement(Parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
LetDeclaration* Parser::parseLetDeclaration() {
|
LetDeclaration* Parser::parseLetDeclaration() {
|
||||||
|
|
||||||
auto Annotations = parseAnnotations();
|
auto Annotations = parseAnnotations();
|
||||||
PubKeyword* Pub = nullptr;
|
PubKeyword* Pub = nullptr;
|
||||||
|
@ -1324,9 +1324,9 @@ finish:
|
||||||
TA,
|
TA,
|
||||||
Body
|
Body
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* Parser::parseLetBodyElement() {
|
Node* Parser::parseLetBodyElement() {
|
||||||
auto T0 = peekFirstTokenAfterAnnotationsAndModifiers();
|
auto T0 = peekFirstTokenAfterAnnotationsAndModifiers();
|
||||||
switch (T0->getKind()) {
|
switch (T0->getKind()) {
|
||||||
case NodeKind::LetKeyword:
|
case NodeKind::LetKeyword:
|
||||||
|
@ -1338,9 +1338,9 @@ finish:
|
||||||
default:
|
default:
|
||||||
return parseExpressionStatement();
|
return parseExpressionStatement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstraintExpression* Parser::parseConstraintExpression() {
|
ConstraintExpression* Parser::parseConstraintExpression() {
|
||||||
bool HasTilde = false;
|
bool HasTilde = false;
|
||||||
for (std::size_t I = 0; ; I++) {
|
for (std::size_t I = 0; ; I++) {
|
||||||
auto Tok = Tokens.peek(I);
|
auto Tok = Tokens.peek(I);
|
||||||
|
@ -1400,9 +1400,9 @@ after_lookahead:
|
||||||
}
|
}
|
||||||
after_vars:
|
after_vars:
|
||||||
return new TypeclassConstraintExpression { Name, TEs };
|
return new TypeclassConstraintExpression { Name, TEs };
|
||||||
}
|
}
|
||||||
|
|
||||||
VarTypeExpression* Parser::parseVarTypeExpression() {
|
VarTypeExpression* Parser::parseVarTypeExpression() {
|
||||||
auto Name = expectToken<Identifier>();
|
auto Name = expectToken<Identifier>();
|
||||||
if (!Name) {
|
if (!Name) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1416,9 +1416,9 @@ after_vars:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new VarTypeExpression { Name };
|
return new VarTypeExpression { Name };
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceDeclaration* Parser::parseInstanceDeclaration() {
|
InstanceDeclaration* Parser::parseInstanceDeclaration() {
|
||||||
auto InstanceKeyword = expectToken<class InstanceKeyword>();
|
auto InstanceKeyword = expectToken<class InstanceKeyword>();
|
||||||
if (!InstanceKeyword) {
|
if (!InstanceKeyword) {
|
||||||
skipPastLineFoldEnd();
|
skipPastLineFoldEnd();
|
||||||
|
@ -1478,9 +1478,9 @@ after_vars:
|
||||||
BlockStart,
|
BlockStart,
|
||||||
Elements
|
Elements
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassDeclaration* Parser::parseClassDeclaration() {
|
ClassDeclaration* Parser::parseClassDeclaration() {
|
||||||
PubKeyword* PubKeyword = nullptr;
|
PubKeyword* PubKeyword = nullptr;
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
if (T0->getKind() == NodeKind::PubKeyword) {
|
if (T0->getKind() == NodeKind::PubKeyword) {
|
||||||
|
@ -1557,9 +1557,9 @@ after_vars:
|
||||||
BlockStart,
|
BlockStart,
|
||||||
Elements
|
Elements
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<RecordDeclarationField*> Parser::parseRecordDeclarationFields() {
|
std::vector<RecordDeclarationField*> Parser::parseRecordDeclarationFields() {
|
||||||
std::vector<RecordDeclarationField*> Fields;
|
std::vector<RecordDeclarationField*> Fields;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T1 = Tokens.peek();
|
auto T1 = Tokens.peek();
|
||||||
|
@ -1589,9 +1589,9 @@ after_vars:
|
||||||
Fields.push_back(new RecordDeclarationField { Name, Colon, TE });
|
Fields.push_back(new RecordDeclarationField { Name, Colon, TE });
|
||||||
}
|
}
|
||||||
return Fields;
|
return Fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordDeclaration* Parser::parseRecordDeclaration() {
|
RecordDeclaration* Parser::parseRecordDeclaration() {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
PubKeyword* Pub = nullptr;
|
PubKeyword* Pub = nullptr;
|
||||||
if (T0->getKind() == NodeKind::MutKeyword) {
|
if (T0->getKind() == NodeKind::MutKeyword) {
|
||||||
|
@ -1639,9 +1639,9 @@ after_vars:
|
||||||
auto Fields = parseRecordDeclarationFields();
|
auto Fields = parseRecordDeclarationFields();
|
||||||
Tokens.get()->unref(); // Always a LineFoldEnd
|
Tokens.get()->unref(); // Always a LineFoldEnd
|
||||||
return new RecordDeclaration { Pub, Struct, Name, Vars, BS, Fields };
|
return new RecordDeclaration { Pub, Struct, Name, Vars, BS, Fields };
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantDeclaration* Parser::parseVariantDeclaration() {
|
VariantDeclaration* Parser::parseVariantDeclaration() {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
PubKeyword* Pub = nullptr;
|
PubKeyword* Pub = nullptr;
|
||||||
if (T0->getKind() == NodeKind::MutKeyword) {
|
if (T0->getKind() == NodeKind::MutKeyword) {
|
||||||
|
@ -1729,9 +1729,9 @@ next_member:
|
||||||
}
|
}
|
||||||
checkLineFoldEnd();
|
checkLineFoldEnd();
|
||||||
return new VariantDeclaration { Pub, Enum, Name, TVs, BS, Members };
|
return new VariantDeclaration { Pub, Enum, Name, TVs, BS, Members };
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* Parser::parseClassElement() {
|
Node* Parser::parseClassElement() {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
switch (T0->getKind()) {
|
switch (T0->getKind()) {
|
||||||
case NodeKind::LetKeyword:
|
case NodeKind::LetKeyword:
|
||||||
|
@ -1743,9 +1743,9 @@ next_member:
|
||||||
skipPastLineFoldEnd();
|
skipPastLineFoldEnd();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* Parser::parseSourceElement() {
|
Node* Parser::parseSourceElement() {
|
||||||
auto T0 = peekFirstTokenAfterAnnotationsAndModifiers();
|
auto T0 = peekFirstTokenAfterAnnotationsAndModifiers();
|
||||||
switch (T0->getKind()) {
|
switch (T0->getKind()) {
|
||||||
case NodeKind::LetKeyword:
|
case NodeKind::LetKeyword:
|
||||||
|
@ -1763,9 +1763,9 @@ next_member:
|
||||||
default:
|
default:
|
||||||
return parseExpressionStatement();
|
return parseExpressionStatement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceFile* Parser::parseSourceFile() {
|
SourceFile* Parser::parseSourceFile() {
|
||||||
std::vector<Node*> Elements;
|
std::vector<Node*> Elements;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
|
@ -1778,9 +1778,9 @@ next_member:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new SourceFile(File, Elements);
|
return new SourceFile(File, Elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Annotation*> Parser::parseAnnotations() {
|
std::vector<Annotation*> Parser::parseAnnotations() {
|
||||||
std::vector<Annotation*> Annotations;
|
std::vector<Annotation*> Annotations;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
|
@ -1826,9 +1826,9 @@ next_member:
|
||||||
next_annotation:;
|
next_annotation:;
|
||||||
}
|
}
|
||||||
return Annotations;
|
return Annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::skipToRBrace() {
|
void Parser::skipToRBrace() {
|
||||||
unsigned ParenLevel = 0;
|
unsigned ParenLevel = 0;
|
||||||
unsigned BracketLevel = 0;
|
unsigned BracketLevel = 0;
|
||||||
unsigned BraceLevel = 0;
|
unsigned BraceLevel = 0;
|
||||||
|
@ -1884,9 +1884,9 @@ next_annotation:;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::skipPastLineFoldEnd() {
|
void Parser::skipPastLineFoldEnd() {
|
||||||
unsigned ParenLevel = 0;
|
unsigned ParenLevel = 0;
|
||||||
unsigned BracketLevel = 0;
|
unsigned BracketLevel = 0;
|
||||||
unsigned BraceLevel = 0;
|
unsigned BraceLevel = 0;
|
||||||
|
@ -1939,9 +1939,9 @@ next_annotation:;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::checkLineFoldEnd() {
|
void Parser::checkLineFoldEnd() {
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
if (T0->getKind() == NodeKind::LineFoldEnd) {
|
if (T0->getKind() == NodeKind::LineFoldEnd) {
|
||||||
Tokens.get()->unref();
|
Tokens.get()->unref();
|
||||||
|
@ -1949,7 +1949,7 @@ next_annotation:;
|
||||||
DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector { NodeKind::LineFoldEnd });
|
DE.add<UnexpectedTokenDiagnostic>(File, T0, std::vector { NodeKind::LineFoldEnd });
|
||||||
skipPastLineFoldEnd();
|
skipPastLineFoldEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
static inline bool isWhiteSpace(Char Chr) {
|
static inline bool isWhiteSpace(Char Chr) {
|
||||||
switch (Chr) {
|
switch (Chr) {
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\n':
|
case '\n':
|
||||||
|
@ -23,9 +23,9 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool isOperatorPart(Char Chr) {
|
static inline bool isOperatorPart(Char Chr) {
|
||||||
switch (Chr) {
|
switch (Chr) {
|
||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
|
@ -45,27 +45,27 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isDirectiveIdentifierStart(Char Chr) {
|
static bool isDirectiveIdentifierStart(Char Chr) {
|
||||||
return (Chr >= 65 && Chr <= 90) // Uppercase letter
|
return (Chr >= 65 && Chr <= 90) // Uppercase letter
|
||||||
|| (Chr >= 96 && Chr <= 122) // Lowercase letter
|
|| (Chr >= 96 && Chr <= 122) // Lowercase letter
|
||||||
|| Chr == '_';
|
|| Chr == '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isIdentifierPart(Char Chr) {
|
static bool isIdentifierPart(Char Chr) {
|
||||||
return (Chr >= 65 && Chr <= 90) // Uppercase letter
|
return (Chr >= 65 && Chr <= 90) // Uppercase letter
|
||||||
|| (Chr >= 96 && Chr <= 122) // Lowercase letter
|
|| (Chr >= 96 && Chr <= 122) // Lowercase letter
|
||||||
|| (Chr >= 48 && Chr <= 57) // Digit
|
|| (Chr >= 48 && Chr <= 57) // Digit
|
||||||
|| Chr == '_';
|
|| Chr == '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int toDigit(Char Chr) {
|
static int toDigit(Char Chr) {
|
||||||
ZEN_ASSERT(Chr >= 48 && Chr <= 57);
|
ZEN_ASSERT(Chr >= 48 && Chr <= 57);
|
||||||
return Chr - 48;
|
return Chr - 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<ByteString, NodeKind> Keywords = {
|
std::unordered_map<ByteString, NodeKind> Keywords = {
|
||||||
{ "pub", NodeKind::PubKeyword },
|
{ "pub", NodeKind::PubKeyword },
|
||||||
{ "let", NodeKind::LetKeyword },
|
{ "let", NodeKind::LetKeyword },
|
||||||
{ "foreign", NodeKind::ForeignKeyword },
|
{ "foreign", NodeKind::ForeignKeyword },
|
||||||
|
@ -81,12 +81,12 @@ namespace bolt {
|
||||||
{ "instance", NodeKind::InstanceKeyword },
|
{ "instance", NodeKind::InstanceKeyword },
|
||||||
{ "struct", NodeKind::StructKeyword },
|
{ "struct", NodeKind::StructKeyword },
|
||||||
{ "enum", NodeKind::EnumKeyword },
|
{ "enum", NodeKind::EnumKeyword },
|
||||||
};
|
};
|
||||||
|
|
||||||
Scanner::Scanner(DiagnosticEngine& DE, TextFile& File, Stream<Char>& Chars):
|
Scanner::Scanner(DiagnosticEngine& DE, TextFile& File, Stream<Char>& Chars):
|
||||||
DE(DE), File(File), Chars(Chars) {}
|
DE(DE), File(File), Chars(Chars) {}
|
||||||
|
|
||||||
std::string Scanner::scanIdentifier() {
|
std::string Scanner::scanIdentifier() {
|
||||||
auto Loc = getCurrentLoc();
|
auto Loc = getCurrentLoc();
|
||||||
auto C0 = getChar();
|
auto C0 = getChar();
|
||||||
if (!isDirectiveIdentifierStart(C0)) {
|
if (!isDirectiveIdentifierStart(C0)) {
|
||||||
|
@ -105,7 +105,7 @@ namespace bolt {
|
||||||
return Text;
|
return Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* Scanner::readNullable() {
|
Token* Scanner::readNullable() {
|
||||||
|
|
||||||
TextLoc StartLoc;
|
TextLoc StartLoc;
|
||||||
Char C0;
|
Char C0;
|
||||||
|
@ -412,9 +412,9 @@ after_string_contents:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* Scanner::read() {
|
Token* Scanner::read() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto T0 = readNullable();
|
auto T0 = readNullable();
|
||||||
if (T0) {
|
if (T0) {
|
||||||
|
@ -422,15 +422,15 @@ after_string_contents:
|
||||||
return T0;
|
return T0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Punctuator::Punctuator(Stream<Token*>& Tokens):
|
Punctuator::Punctuator(Stream<Token*>& Tokens):
|
||||||
Tokens(Tokens) {
|
Tokens(Tokens) {
|
||||||
Frames.push(FrameType::Block);
|
Frames.push(FrameType::Block);
|
||||||
Locations.push(TextLoc { 0, 0 });
|
Locations.push(TextLoc { 0, 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* Punctuator::read() {
|
Token* Punctuator::read() {
|
||||||
|
|
||||||
auto T0 = Tokens.peek();
|
auto T0 = Tokens.peek();
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ after_string_contents:
|
||||||
}
|
}
|
||||||
|
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
TextFile::TextFile(ByteString Path, ByteString Text):
|
TextFile::TextFile(ByteString Path, ByteString 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,15 +18,15 @@ namespace bolt {
|
||||||
LineOffsets.push_back(Text.size());
|
LineOffsets.push_back(Text.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TextFile::getLineCount() const {
|
size_t TextFile::getLineCount() const {
|
||||||
return LineOffsets.size();
|
return LineOffsets.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TextFile::getStartOffset(size_t Line) const {
|
size_t TextFile::getStartOffset(size_t Line) const {
|
||||||
return LineOffsets[Line-1];
|
return LineOffsets[Line-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TextFile::getLine(size_t Offset) const {
|
size_t TextFile::getLine(size_t Offset) const {
|
||||||
ZEN_ASSERT(Offset < Text.size());
|
ZEN_ASSERT(Offset < Text.size());
|
||||||
for (size_t I = 0; I < LineOffsets.size(); ++I) {
|
for (size_t I = 0; I < LineOffsets.size(); ++I) {
|
||||||
if (LineOffsets[I] > Offset) {
|
if (LineOffsets[I] > Offset) {
|
||||||
|
@ -34,20 +34,20 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TextFile::getColumn(size_t Offset) const {
|
size_t TextFile::getColumn(size_t Offset) const {
|
||||||
auto Line = getLine(Offset);
|
auto Line = getLine(Offset);
|
||||||
auto StartOffset = getStartOffset(Line);
|
auto StartOffset = getStartOffset(Line);
|
||||||
return Offset - StartOffset + 1 ;
|
return Offset - StartOffset + 1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteString TextFile::getPath() const {
|
ByteString TextFile::getPath() const {
|
||||||
return Path;
|
return Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteString TextFile::getText() const {
|
ByteString TextFile::getText() const {
|
||||||
return Text;
|
return Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,22 @@
|
||||||
|
|
||||||
namespace bolt {
|
namespace bolt {
|
||||||
|
|
||||||
bool TypeclassSignature::operator<(const TypeclassSignature& Other) const {
|
bool TypeclassSignature::operator<(const TypeclassSignature& Other) const {
|
||||||
if (Id < Other.Id) {
|
if (Id < Other.Id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ZEN_ASSERT(Params.size() == 1);
|
ZEN_ASSERT(Params.size() == 1);
|
||||||
ZEN_ASSERT(Other.Params.size() == 1);
|
ZEN_ASSERT(Other.Params.size() == 1);
|
||||||
return Params[0]->asCon().Id < Other.Params[0]->asCon().Id;
|
return Params[0]->asCon().Id < Other.Params[0]->asCon().Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeclassSignature::operator==(const TypeclassSignature& Other) const {
|
bool TypeclassSignature::operator==(const TypeclassSignature& Other) const {
|
||||||
ZEN_ASSERT(Params.size() == 1);
|
ZEN_ASSERT(Params.size() == 1);
|
||||||
ZEN_ASSERT(Other.Params.size() == 1);
|
ZEN_ASSERT(Other.Params.size() == 1);
|
||||||
return Id == Other.Id && Params[0]->asCon().Id == Other.Params[0]->asCon().Id;
|
return Id == Other.Id && Params[0]->asCon().Id == Other.Params[0]->asCon().Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeIndex::operator==(const TypeIndex& Other) const noexcept {
|
bool TypeIndex::operator==(const TypeIndex& Other) const noexcept {
|
||||||
if (Kind != Other.Kind) {
|
if (Kind != Other.Kind) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -34,51 +34,51 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCon::operator==(const TCon& Other) const {
|
bool TCon::operator==(const TCon& Other) const {
|
||||||
return Id == Other.Id;
|
return Id == Other.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TApp::operator==(const TApp& Other) const {
|
bool TApp::operator==(const TApp& Other) const {
|
||||||
return *Op == *Other.Op && *Arg == *Other.Arg;
|
return *Op == *Other.Op && *Arg == *Other.Arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TVar::operator==(const TVar& Other) const {
|
bool TVar::operator==(const TVar& Other) const {
|
||||||
return Id == Other.Id;
|
return Id == Other.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TArrow::operator==(const TArrow& Other) const {
|
bool TArrow::operator==(const TArrow& Other) const {
|
||||||
return *ParamType == *Other.ParamType
|
return *ParamType == *Other.ParamType
|
||||||
&& *ReturnType == *Other.ReturnType;
|
&& *ReturnType == *Other.ReturnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TTuple::operator==(const TTuple& Other) const {
|
bool TTuple::operator==(const TTuple& Other) const {
|
||||||
for (auto [T1, T2]: zen::zip(ElementTypes, Other.ElementTypes)) {
|
for (auto [T1, T2]: zen::zip(ElementTypes, Other.ElementTypes)) {
|
||||||
if (*T1 != *T2) {
|
if (*T1 != *T2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TNil::operator==(const TNil& Other) const {
|
bool TNil::operator==(const TNil& Other) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TField::operator==(const TField& Other) const {
|
bool TField::operator==(const TField& Other) const {
|
||||||
return Name == Other.Name && *Ty == *Other.Ty && *RestTy == *Other.RestTy;
|
return Name == Other.Name && *Ty == *Other.Ty && *RestTy == *Other.RestTy;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TAbsent::operator==(const TAbsent& Other) const {
|
bool TAbsent::operator==(const TAbsent& Other) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TPresent::operator==(const TPresent& Other) const {
|
bool TPresent::operator==(const TPresent& Other) const {
|
||||||
return *Ty == *Other.Ty;
|
return *Ty == *Other.Ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Type::operator==(const Type& Other) const {
|
bool Type::operator==(const Type& Other) const {
|
||||||
if (Kind != Other.Kind) {
|
if (Kind != Other.Kind) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -103,9 +103,9 @@ namespace bolt {
|
||||||
return App == Other.App;
|
return App == Other.App;
|
||||||
}
|
}
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
void Type::visitEachChild(std::function<void(Type*)> Proc) {
|
void Type::visitEachChild(std::function<void(Type*)> Proc) {
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case TypeKind::Var:
|
case TypeKind::Var:
|
||||||
case TypeKind::Absent:
|
case TypeKind::Absent:
|
||||||
|
@ -143,9 +143,9 @@ namespace bolt {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Type::rewrite(std::function<Type*(Type*)> Fn, bool Recursive) {
|
Type* Type::rewrite(std::function<Type*(Type*)> Fn, bool Recursive) {
|
||||||
auto Ty2 = Fn(this);
|
auto Ty2 = Fn(this);
|
||||||
if (this != Ty2) {
|
if (this != Ty2) {
|
||||||
if (Recursive) {
|
if (Recursive) {
|
||||||
|
@ -225,9 +225,9 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Type::substitute(const TVSub &Sub) {
|
Type* Type::substitute(const TVSub &Sub) {
|
||||||
return rewrite([&](auto Ty) {
|
return rewrite([&](auto Ty) {
|
||||||
if (Ty->isVar()) {
|
if (Ty->isVar()) {
|
||||||
auto Match = Sub.find(Ty);
|
auto Match = Sub.find(Ty);
|
||||||
|
@ -235,9 +235,9 @@ namespace bolt {
|
||||||
}
|
}
|
||||||
return Ty;
|
return Ty;
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* Type::resolve(const TypeIndex& Index) const noexcept {
|
Type* Type::resolve(const TypeIndex& Index) const noexcept {
|
||||||
switch (Index.Kind) {
|
switch (Index.Kind) {
|
||||||
case TypeIndexKind::PresentType:
|
case TypeIndexKind::PresentType:
|
||||||
return this->asPresent().Ty;
|
return this->asPresent().Ty;
|
||||||
|
@ -259,9 +259,9 @@ namespace bolt {
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
TVSet Type::getTypeVars() {
|
TVSet Type::getTypeVars() {
|
||||||
TVSet Out;
|
TVSet Out;
|
||||||
std::function<void(Type*)> visit = [&](Type* Ty) {
|
std::function<void(Type*)> visit = [&](Type* Ty) {
|
||||||
if (Ty->isVar()) {
|
if (Ty->isVar()) {
|
||||||
|
@ -272,17 +272,17 @@ namespace bolt {
|
||||||
};
|
};
|
||||||
visit(this);
|
visit(this);
|
||||||
return Out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIterator Type::begin() {
|
TypeIterator Type::begin() {
|
||||||
return TypeIterator { this, getStartIndex() };
|
return TypeIterator { this, getStartIndex() };
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIterator Type::end() {
|
TypeIterator Type::end() {
|
||||||
return TypeIterator { this, getEndIndex() };
|
return TypeIterator { this, getEndIndex() };
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIndex Type::getStartIndex() const {
|
TypeIndex Type::getStartIndex() const {
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case TypeKind::Arrow:
|
case TypeKind::Arrow:
|
||||||
return TypeIndex::forArrowParamType();
|
return TypeIndex::forArrowParamType();
|
||||||
|
@ -298,13 +298,13 @@ namespace bolt {
|
||||||
default:
|
default:
|
||||||
return TypeIndex(TypeIndexKind::End);
|
return TypeIndex(TypeIndexKind::End);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIndex Type::getEndIndex() const {
|
TypeIndex Type::getEndIndex() const {
|
||||||
return TypeIndex(TypeIndexKind::End);
|
return TypeIndex(TypeIndexKind::End);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Type::hasTypeVar(Type* TV) const {
|
bool Type::hasTypeVar(Type* TV) const {
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case TypeKind::Var:
|
case TypeKind::Var:
|
||||||
return Var.Id == TV->asVar().Id;
|
return Var.Id == TV->asVar().Id;
|
||||||
|
@ -329,7 +329,7 @@ namespace bolt {
|
||||||
return Present.Ty->hasTypeVar(TV);
|
return Present.Ty->hasTypeVar(TV);
|
||||||
}
|
}
|
||||||
ZEN_UNREACHABLE
|
ZEN_UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue