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

View file

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

View file

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

View file

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