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