Remove hard dependency on LLVM in code

This commit is contained in:
Sam Vervaeck 2024-01-15 11:53:44 +01:00
parent b08bdbc6f7
commit 7c1a929e9a
Signed by: samvv
SSH key fingerprint: SHA256:dIg0ywU1OP+ZYifrYxy8c5esO72cIKB+4/9wkZj1VaY
5 changed files with 66 additions and 55 deletions

View file

@ -32,4 +32,21 @@ namespace bolt {
}; };
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) {
ZEN_ASSERT(D::classof(base));
return static_cast<const D*>(base);
}
template<typename D, typename T>
bool isa(const T* value) {
return D::classof(value);
}
} }

View file

@ -4,8 +4,6 @@
#include <stack> #include <stack>
#include <map> #include <map>
#include "llvm/Support/Casting.h"
#include "bolt/Type.hpp" #include "bolt/Type.hpp"
#include "zen/config.hpp" #include "zen/config.hpp"
#include "zen/range.hpp" #include "zen/range.hpp"
@ -484,8 +482,8 @@ namespace bolt {
if (Let->isInstance()) { if (Let->isInstance()) {
auto Instance = static_cast<InstanceDeclaration*>(Let->Parent); auto Instance = static_cast<InstanceDeclaration*>(Let->Parent);
auto Class = llvm::cast<ClassDeclaration>(Instance->getScope()->lookup({ {}, Instance->Name->getCanonicalText() }, SymbolKind::Class)); auto Class = cast<ClassDeclaration>(Instance->getScope()->lookup({ {}, Instance->Name->getCanonicalText() }, SymbolKind::Class));
auto SigLet = llvm::cast<LetDeclaration>(Class->getScope()->lookupDirect({ {}, Let->getNameAsString() }, SymbolKind::Var)); auto SigLet = cast<LetDeclaration>(Class->getScope()->lookupDirect({ {}, Let->getNameAsString() }, SymbolKind::Var));
auto Params = addClassVars(Class, false); auto Params = addClassVars(Class, false);
@ -498,7 +496,7 @@ namespace bolt {
// TVSub Sub; // TVSub Sub;
// for (auto TE: Class->TypeVars) { // for (auto TE: Class->TypeVars) {
// auto TV = createTypeVar(); // auto TV = createTypeVar();
// Sub.emplace(llvm::cast<TVar>(TE->getType()), TV); // Sub.emplace(cast<TVar>(TE->getType()), TV);
// Params.push_back(TV); // Params.push_back(TV);
// } // }
@ -1283,9 +1281,9 @@ namespace bolt {
} }
bool assignableTo(Type* A, Type* B) { bool assignableTo(Type* A, Type* B) {
if (llvm::isa<TCon>(A) && llvm::isa<TCon>(B)) { if (isa<TCon>(A) && isa<TCon>(B)) {
auto Con1 = llvm::cast<TCon>(A); auto Con1 = cast<TCon>(A);
auto Con2 = llvm::cast<TCon>(B); auto Con2 = cast<TCon>(B);
if (Con1->Id != Con2-> Id) { if (Con1->Id != Con2-> Id) {
return false; return false;
} }
@ -1325,7 +1323,7 @@ namespace bolt {
continue; continue;
} }
Ty = Arrow->resolve(Index); Ty = Arrow->resolve(Index);
if (llvm::isa<TArrow>(Ty)) { if (isa<TArrow>(Ty)) {
auto NewIndex = Arrow->getStartIndex(); auto NewIndex = Arrow->getStartIndex();
Stack.push({ static_cast<TArrow*>(Ty), true }); Stack.push({ static_cast<TArrow*>(Ty), true });
Path.push_back(NewIndex); Path.push_back(NewIndex);
@ -1412,8 +1410,8 @@ namespace bolt {
} }
void propagateClasses(std::unordered_set<TypeclassId>& Classes, Type* Ty) { void propagateClasses(std::unordered_set<TypeclassId>& Classes, Type* Ty) {
if (llvm::isa<TVar>(Ty)) { if (isa<TVar>(Ty)) {
auto TV = llvm::cast<TVar>(Ty); auto TV = cast<TVar>(Ty);
for (auto Class: Classes) { for (auto Class: Classes) {
TV->Contexts.emplace(Class); TV->Contexts.emplace(Class);
} }
@ -1425,7 +1423,7 @@ namespace bolt {
} }
} }
} }
} else if (llvm::isa<TCon>(Ty) || llvm::isa<TApp>(Ty)) { } else if (isa<TCon>(Ty) || isa<TApp>(Ty)) {
auto Sig = getTypeSig(Ty); auto Sig = getTypeSig(Ty);
for (auto Class: Classes) { for (auto Class: Classes) {
propagateClassTycon(Class, Sig); propagateClassTycon(Class, Sig);
@ -1482,14 +1480,14 @@ namespace bolt {
}; };
bool Unifier::unifyField(Type* A, Type* B, bool DidSwap) { bool Unifier::unifyField(Type* A, Type* B, bool DidSwap) {
if (llvm::isa<TAbsent>(A) && llvm::isa<TAbsent>(B)) { if (isa<TAbsent>(A) && isa<TAbsent>(B)) {
return true; return true;
} }
if (llvm::isa<TAbsent>(B)) { if (isa<TAbsent>(B)) {
std::swap(A, B); std::swap(A, B);
DidSwap = !DidSwap; DidSwap = !DidSwap;
} }
if (llvm::isa<TAbsent>(A)) { if (isa<TAbsent>(A)) {
auto Present = static_cast<TPresent*>(B); auto Present = static_cast<TPresent*>(B);
C.DE.add<FieldNotFoundDiagnostic>(CurrentFieldName, C.simplifyType(getLeft()), LeftPath, getSource()); C.DE.add<FieldNotFoundDiagnostic>(CurrentFieldName, C.simplifyType(getLeft()), LeftPath, getSource());
return false; return false;
@ -1551,7 +1549,7 @@ namespace bolt {
DidSwap = !DidSwap; DidSwap = !DidSwap;
}; };
if (llvm::isa<TVar>(A) && llvm::isa<TVar>(B)) { if (isa<TVar>(A) && isa<TVar>(B)) {
auto Var1 = static_cast<TVar*>(A); auto Var1 = static_cast<TVar*>(A);
auto Var2 = static_cast<TVar*>(B); auto Var2 = static_cast<TVar*>(B);
if (Var1->getVarKind() == VarKind::Rigid && Var2->getVarKind() == VarKind::Rigid) { if (Var1->getVarKind() == VarKind::Rigid && Var2->getVarKind() == VarKind::Rigid) {
@ -1578,11 +1576,11 @@ namespace bolt {
return true; return true;
} }
if (llvm::isa<TVar>(B)) { if (isa<TVar>(B)) {
swap(); swap();
} }
if (llvm::isa<TVar>(A)) { if (isa<TVar>(A)) {
auto TV = static_cast<TVar*>(A); auto TV = static_cast<TVar*>(A);
@ -1607,7 +1605,7 @@ namespace bolt {
return true; return true;
} }
if (llvm::isa<TArrow>(A) && llvm::isa<TArrow>(B)) { if (isa<TArrow>(A) && isa<TArrow>(B)) {
auto Arrow1 = static_cast<TArrow*>(A); auto Arrow1 = static_cast<TArrow*>(A);
auto Arrow2 = static_cast<TArrow*>(B); auto Arrow2 = static_cast<TArrow*>(B);
bool Success = true; bool Success = true;
@ -1628,7 +1626,7 @@ namespace bolt {
return Success; return Success;
} }
if (llvm::isa<TApp>(A) && llvm::isa<TApp>(B)) { if (isa<TApp>(A) && isa<TApp>(B)) {
auto App1 = static_cast<TApp*>(A); auto App1 = static_cast<TApp*>(A);
auto App2 = static_cast<TApp*>(B); auto App2 = static_cast<TApp*>(B);
bool Success = true; bool Success = true;
@ -1649,7 +1647,7 @@ namespace bolt {
return Success; return Success;
} }
if (llvm::isa<TTuple>(A) && llvm::isa<TTuple>(B)) { if (isa<TTuple>(A) && isa<TTuple>(B)) {
auto Tuple1 = static_cast<TTuple*>(A); auto Tuple1 = static_cast<TTuple*>(A);
auto Tuple2 = static_cast<TTuple*>(B); auto Tuple2 = static_cast<TTuple*>(B);
if (Tuple1->ElementTypes.size() != Tuple2->ElementTypes.size()) { if (Tuple1->ElementTypes.size() != Tuple2->ElementTypes.size()) {
@ -1670,20 +1668,20 @@ namespace bolt {
return Success; return Success;
} }
if (llvm::isa<TTupleIndex>(A) || llvm::isa<TTupleIndex>(B)) { if (isa<TTupleIndex>(A) || isa<TTupleIndex>(B)) {
// Type(s) could not be simplified at the beginning of this function, // Type(s) could not be simplified at the beginning of this function,
// so we have to re-visit the constraint when there is more information. // so we have to re-visit the constraint when there is more information.
C.Queue.push_back(Constraint); C.Queue.push_back(Constraint);
return true; return true;
} }
// if (llvm::isa<TTupleIndex>(A) && llvm::isa<TTupleIndex>(B)) { // if (isa<TTupleIndex>(A) && isa<TTupleIndex>(B)) {
// auto Index1 = static_cast<TTupleIndex*>(A); // auto Index1 = static_cast<TTupleIndex*>(A);
// auto Index2 = static_cast<TTupleIndex*>(B); // auto Index2 = static_cast<TTupleIndex*>(B);
// return unify(Index1->Ty, Index2->Ty, Source); // return unify(Index1->Ty, Index2->Ty, Source);
// } // }
if (llvm::isa<TCon>(A) && llvm::isa<TCon>(B)) { if (isa<TCon>(A) && isa<TCon>(B)) {
auto Con1 = static_cast<TCon*>(A); auto Con1 = static_cast<TCon*>(A);
auto Con2 = static_cast<TCon*>(B); auto Con2 = static_cast<TCon*>(B);
if (Con1->Id != Con2->Id) { if (Con1->Id != Con2->Id) {
@ -1693,11 +1691,11 @@ namespace bolt {
return true; return true;
} }
if (llvm::isa<TNil>(A) && llvm::isa<TNil>(B)) { if (isa<TNil>(A) && isa<TNil>(B)) {
return true; return true;
} }
if (llvm::isa<TField>(A) && llvm::isa<TField>(B)) { if (isa<TField>(A) && isa<TField>(B)) {
auto Field1 = static_cast<TField*>(A); auto Field1 = static_cast<TField*>(A);
auto Field2 = static_cast<TField*>(B); auto Field2 = static_cast<TField*>(B);
bool Success = true; bool Success = true;
@ -1733,11 +1731,11 @@ namespace bolt {
return Success; return Success;
} }
if (llvm::isa<TNil>(A) && llvm::isa<TField>(B)) { if (isa<TNil>(A) && isa<TField>(B)) {
swap(); swap();
} }
if (llvm::isa<TField>(A) && llvm::isa<TNil>(B)) { if (isa<TField>(A) && isa<TNil>(B)) {
auto Field = static_cast<TField*>(A); auto Field = static_cast<TField*>(A);
bool Success = true; bool Success = true;
pushLeft(TypeIndex::forFieldType()); pushLeft(TypeIndex::forFieldType());

View file

@ -1,11 +1,9 @@
// TODO check for memory leaks everywhere a nullptr is returned // TODO check for memory leaks everywhere a nullptr is returned
#include <exception>
#include <vector> #include <vector>
#include "llvm/Support/Casting.h" #include "bolt/Common.hpp"
#include "bolt/CST.hpp" #include "bolt/CST.hpp"
#include "bolt/Scanner.hpp" #include "bolt/Scanner.hpp"
#include "bolt/Parser.hpp" #include "bolt/Parser.hpp"
@ -268,7 +266,7 @@ finish:
TypeExpression* Parser::parseQualifiedTypeExpression() { TypeExpression* Parser::parseQualifiedTypeExpression() {
bool HasConstraints = false; bool HasConstraints = false;
auto T0 = Tokens.peek(); auto T0 = Tokens.peek();
if (llvm::isa<LParen>(T0)) { if (isa<LParen>(T0)) {
std::size_t I = 1; std::size_t I = 1;
for (;;) { for (;;) {
auto T0 = Tokens.peek(I++); auto T0 = Tokens.peek(I++);
@ -363,7 +361,7 @@ after_constraints:
RParen* RParen; RParen* RParen;
for (;;) { for (;;) {
auto T1 = Tokens.peek(); auto T1 = Tokens.peek();
if (llvm::isa<class RParen>(T1)) { if (isa<class RParen>(T1)) {
Tokens.get(); Tokens.get();
RParen = static_cast<class RParen*>(T1); RParen = static_cast<class RParen*>(T1);
break; break;
@ -499,7 +497,7 @@ after_tuple_element:
auto T1 = Tokens.peek(); auto T1 = Tokens.peek();
Expression* Value; Expression* Value;
BlockStart* BlockStart; BlockStart* BlockStart;
if (llvm::isa<class BlockStart>(T1)) { if (isa<class BlockStart>(T1)) {
Value = nullptr; Value = nullptr;
BlockStart = static_cast<class BlockStart*>(T1); BlockStart = static_cast<class BlockStart*>(T1);
Tokens.get(); Tokens.get();
@ -519,7 +517,7 @@ after_tuple_element:
std::vector<MatchCase*> Cases; std::vector<MatchCase*> Cases;
for (;;) { for (;;) {
auto T2 = Tokens.peek(); auto T2 = Tokens.peek();
if (llvm::isa<BlockEnd>(T2)) { if (isa<BlockEnd>(T2)) {
Tokens.get()->unref(); Tokens.get()->unref();
break; break;
} }
@ -627,7 +625,7 @@ after_tuple_element:
for (;;) { for (;;) {
auto T1 = Tokens.peek(0); auto T1 = Tokens.peek(0);
auto T2 = Tokens.peek(1); auto T2 = Tokens.peek(1);
if (!llvm::isa<IdentifierAlt>(T1) || !llvm::isa<Dot>(T2)) { if (!isa<IdentifierAlt>(T1) || !isa<Dot>(T2)) {
break; break;
} }
Tokens.get(); Tokens.get();
@ -635,7 +633,7 @@ after_tuple_element:
ModulePath.push_back(std::make_tuple(static_cast<IdentifierAlt*>(T1), static_cast<class Dot*>(T2))); ModulePath.push_back(std::make_tuple(static_cast<IdentifierAlt*>(T1), static_cast<class Dot*>(T2)));
} }
auto T3 = Tokens.get(); auto T3 = Tokens.get();
if (!llvm::isa<Symbol>(T3)) { if (!isa<Symbol>(T3)) {
for (auto [Name, Dot]: ModulePath) { for (auto [Name, Dot]: ModulePath) {
Name->unref(); Name->unref();
Dot->unref(); Dot->unref();
@ -652,7 +650,7 @@ after_tuple_element:
auto LParen = static_cast<class LParen*>(T0); auto LParen = static_cast<class LParen*>(T0);
RParen* RParen; RParen* RParen;
auto T1 = Tokens.peek(); auto T1 = Tokens.peek();
if (llvm::isa<class RParen>(T1)) { if (isa<class RParen>(T1)) {
Tokens.get(); Tokens.get();
RParen = static_cast<class RParen*>(T1); RParen = static_cast<class RParen*>(T1);
goto after_tuple_elements; goto after_tuple_elements;
@ -731,7 +729,7 @@ after_tuple_elements:
for (;;) { for (;;) {
auto T1 = Tokens.peek(0); auto T1 = Tokens.peek(0);
auto T2 = Tokens.peek(1); auto T2 = Tokens.peek(1);
if (!llvm::isa<Dot>(T1)) { if (!isa<Dot>(T1)) {
break; break;
} }
switch (T2->getKind()) { switch (T2->getKind()) {

View file

@ -3,8 +3,7 @@
#include "zen/config.hpp" #include "zen/config.hpp"
#include "llvm/Support/Casting.h" #include "bolt/Common.hpp"
#include "bolt/Text.hpp" #include "bolt/Text.hpp"
#include "bolt/Integer.hpp" #include "bolt/Integer.hpp"
#include "bolt/CST.hpp" #include "bolt/CST.hpp"
@ -475,7 +474,7 @@ after_string_contents:
Locations.pop(); Locations.pop();
return new LineFoldEnd(T0->getStartLoc()); return new LineFoldEnd(T0->getStartLoc());
} }
if (llvm::isa<Dot>(T0)) { if (isa<Dot>(T0)) {
auto T1 = Tokens.peek(1); auto T1 = Tokens.peek(1);
if (T1->getStartLine() > T0->getEndLine()) { if (T1->getStartLine() > T0->getEndLine()) {
Tokens.get(); Tokens.get();

View file

@ -1,9 +1,8 @@
#include "llvm/Support/Casting.h"
#include "zen/config.hpp" #include "zen/config.hpp"
#include "zen/range.hpp" #include "zen/range.hpp"
#include "bolt/Common.hpp"
#include "bolt/Type.hpp" #include "bolt/Type.hpp"
namespace bolt { namespace bolt {
@ -58,7 +57,7 @@ namespace bolt {
case TypeIndexKind::AppArgType: case TypeIndexKind::AppArgType:
case TypeIndexKind::TupleElement: case TypeIndexKind::TupleElement:
{ {
auto Tuple = llvm::cast<TTuple>(Ty); auto Tuple = cast<TTuple>(Ty);
if (I+1 < Tuple->ElementTypes.size()) { if (I+1 < Tuple->ElementTypes.size()) {
++I; ++I;
} else { } else {
@ -271,7 +270,7 @@ namespace bolt {
Type* Type::substitute(const TVSub &Sub) { Type* Type::substitute(const TVSub &Sub) {
return rewrite([&](auto Ty) { return rewrite([&](auto Ty) {
if (llvm::isa<TVar>(Ty)) { if (isa<TVar>(Ty)) {
auto TV = static_cast<TVar*>(Ty); auto TV = static_cast<TVar*>(Ty);
auto Match = Sub.find(TV); auto Match = Sub.find(TV);
return Match != Sub.end() ? Match->second->substitute(Sub) : Ty; return Match != Sub.end() ? Match->second->substitute(Sub) : Ty;
@ -283,23 +282,23 @@ namespace bolt {
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 llvm::cast<TPresent>(this)->Ty; return cast<TPresent>(this)->Ty;
case TypeIndexKind::AppOpType: case TypeIndexKind::AppOpType:
return llvm::cast<TApp>(this)->Op; return cast<TApp>(this)->Op;
case TypeIndexKind::AppArgType: case TypeIndexKind::AppArgType:
return llvm::cast<TApp>(this)->Arg; return cast<TApp>(this)->Arg;
case TypeIndexKind::TupleIndexType: case TypeIndexKind::TupleIndexType:
return llvm::cast<TTupleIndex>(this)->Ty; return cast<TTupleIndex>(this)->Ty;
case TypeIndexKind::TupleElement: case TypeIndexKind::TupleElement:
return llvm::cast<TTuple>(this)->ElementTypes[Index.I]; return cast<TTuple>(this)->ElementTypes[Index.I];
case TypeIndexKind::ArrowParamType: case TypeIndexKind::ArrowParamType:
return llvm::cast<TArrow>(this)->ParamType; return cast<TArrow>(this)->ParamType;
case TypeIndexKind::ArrowReturnType: case TypeIndexKind::ArrowReturnType:
return llvm::cast<TArrow>(this)->ReturnType; return cast<TArrow>(this)->ReturnType;
case TypeIndexKind::FieldType: case TypeIndexKind::FieldType:
return llvm::cast<TField>(this)->Ty; return cast<TField>(this)->Ty;
case TypeIndexKind::FieldRestType: case TypeIndexKind::FieldRestType:
return llvm::cast<TField>(this)->RestTy; return cast<TField>(this)->RestTy;
case TypeIndexKind::End: case TypeIndexKind::End:
ZEN_UNREACHABLE ZEN_UNREACHABLE
} }