Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
vajexal committed May 10, 2024
1 parent 02c71b4 commit a679b53
Show file tree
Hide file tree
Showing 25 changed files with 203 additions and 178 deletions.
2 changes: 2 additions & 0 deletions src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ namespace X {
case NodeKind::Decl:
globals.push_back(llvm::cast<DeclNode>(node));
break;
default:
break;
}

StatementListNode::add(node);
Expand Down
38 changes: 19 additions & 19 deletions src/codegen/class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace X::Codegen {
llvm::Value *Codegen::gen(ClassNode *node) {
auto &name = node->getName();
const auto &mangledName = Mangler::mangleClass(name);
const auto &mangledName = mangler->mangleClass(name);

self = &classes[name];

Expand All @@ -20,7 +20,7 @@ namespace X::Codegen {

auto fn = method->getFnDef();
currentFnRetType = method->getFnDef()->getReturnType();
const auto &fnName = Mangler::mangleMethod(mangledName, fn->getName());
const auto &fnName = mangler->mangleMethod(mangledName, fn->getName());
genFn(fnName, fn->getArgs(), currentFnRetType, fn->getBody(), method->getIsStatic() ? nullptr : &self->type);
}

Expand Down Expand Up @@ -90,7 +90,7 @@ namespace X::Codegen {

initVtable(obj, classDecl);

auto initFnName = Mangler::mangleHiddenMethod(Mangler::mangleClass(classDecl.name), INIT_FN_NAME);
auto initFnName = mangler->mangleHiddenMethod(mangler->mangleClass(classDecl.name), INIT_FN_NAME);
if (auto initFn = module.getFunction(initFnName)) {
builder.CreateCall(initFn, {obj});
}
Expand Down Expand Up @@ -206,22 +206,22 @@ namespace X::Codegen {
GC::Metadata *Codegen::genTypeGCMeta(const Type &type) {
switch (type.getTypeID()) {
case Type::TypeID::STRING:
return gc.addMeta(GC::NodeType::CLASS, {});
return gc->addMeta(GC::NodeType::CLASS, {});
case Type::TypeID::ARRAY: {
GC::PointerList pointerList;
auto containedMeta = getTypeGCMeta(*type.getSubtype());
if (containedMeta) {
pointerList.emplace_back(0, containedMeta);
}
return gc.addMeta(GC::NodeType::ARRAY, std::move(pointerList));
return gc->addMeta(GC::NodeType::ARRAY, std::move(pointerList));
}
case Type::TypeID::CLASS: {
if (type.getClassName() == Runtime::Range::CLASS_NAME) {
return gc.addMeta(GC::NodeType::CLASS, {});
return gc->addMeta(GC::NodeType::CLASS, {});
}

if (isInterfaceType(type)) {
return gc.addMeta(GC::NodeType::INTERFACE, {});
return gc->addMeta(GC::NodeType::INTERFACE, {});
}

auto &classDecl = getClassDecl(type.getClassName());
Expand Down Expand Up @@ -263,9 +263,9 @@ namespace X::Codegen {
}

llvm::StructType *Codegen::genVtable(ClassNode *classNode, ClassDecl &classDecl) {
const auto &classMangledName = Mangler::mangleClass(classNode->getName());
const auto &classMangledName = mangler->mangleClass(classNode->getName());
auto &classMethods = classNode->getMethods();
const auto &virtualMethods = compilerRuntime.virtualMethods.at(classNode->getName());
const auto &virtualMethods = compilerRuntime->virtualMethods.at(classNode->getName());
std::vector<llvm::Type *> vtableProps;
vtableProps.reserve(virtualMethods.size());
uint64_t vtablePos = 0;
Expand All @@ -281,8 +281,8 @@ namespace X::Codegen {
}

llvm::StructType *Codegen::genVtable(InterfaceNode *node, InterfaceDecl &interfaceDecl) {
const auto &interfaceMangledName = Mangler::mangleInterface(node->getName());
auto &interfaceMethods = compilerRuntime.interfaceMethods.at(node->getName());
const auto &interfaceMangledName = mangler->mangleInterface(node->getName());
auto &interfaceMethods = compilerRuntime->interfaceMethods.at(node->getName());
std::vector<llvm::Type *> vtableProps;
vtableProps.reserve(interfaceMethods.size());
uint64_t vtablePos = 0;
Expand Down Expand Up @@ -356,7 +356,7 @@ namespace X::Codegen {
}

llvm::Function *Codegen::getInternalConstructor(const std::string &mangledClassName) const {
return module.getFunction(Mangler::mangleInternalMethod(mangledClassName, CONSTRUCTOR_FN_NAME));
return module.getFunction(mangler->mangleInternalMethod(mangledClassName, CONSTRUCTOR_FN_NAME));
}

llvm::Value *Codegen::callMethod(llvm::Value *obj, const Type &objType, const std::string &methodName, const ExprList &args) {
Expand Down Expand Up @@ -406,10 +406,10 @@ namespace X::Codegen {

std::tuple<llvm::FunctionCallee, FnType *> Codegen::findMethod(llvm::Value *obj, const Type &objType, const std::string &methodName) {
if (objType.isOneOf(Type::TypeID::STRING, Type::TypeID::ARRAY)) {
const auto &name = Mangler::mangleInternalMethod(getClassName(objType), methodName);
const auto &name = mangler->mangleInternalMethod(getClassName(objType), methodName);
auto fn = module.getFunction(name);
auto &className = objType.is(Type::TypeID::STRING) ? Runtime::String::CLASS_NAME : Runtime::ArrayRuntime::CLASS_NAME;
return {llvm::FunctionCallee(fn->getFunctionType(), fn), &compilerRuntime.classMethodTypes.at(className).at(methodName)};
return {llvm::FunctionCallee(fn->getFunctionType(), fn), &compilerRuntime->classMethodTypes.at(className).at(methodName)};
}

auto interfaceDecl = findInterfaceDecl(objType.getClassName());
Expand All @@ -424,7 +424,7 @@ namespace X::Codegen {
auto methodType = interfaceDecl->vtableType->getElementType(methodIt->second.vtablePos);
auto method = builder.CreateLoad(methodType, methodPtr);

return {llvm::FunctionCallee(methodIt->second.type, method), &compilerRuntime.classMethodTypes.at(interfaceDecl->name).at(methodName)};
return {llvm::FunctionCallee(methodIt->second.type, method), &compilerRuntime->classMethodTypes.at(interfaceDecl->name).at(methodName)};
}
}

Expand All @@ -447,12 +447,12 @@ namespace X::Codegen {
auto methodPtr = builder.CreateStructGEP(currentClassDecl->vtableType, vtable, methodIt->second.vtablePos);
auto methodType = currentClassDecl->vtableType->getElementType(methodIt->second.vtablePos);
auto method = builder.CreateLoad(methodType, methodPtr);
return {llvm::FunctionCallee(methodIt->second.type, method), &compilerRuntime.classMethodTypes.at(currentClassDecl->name).at(methodName)};
return {llvm::FunctionCallee(methodIt->second.type, method), &compilerRuntime->classMethodTypes.at(currentClassDecl->name).at(methodName)};
}

auto fn = module.getFunction(Mangler::mangleMethod(currentClassDecl->llvmType->getName().str(), methodName));
auto fn = module.getFunction(mangler->mangleMethod(currentClassDecl->llvmType->getName().str(), methodName));
if (fn) {
return {llvm::FunctionCallee(fn->getFunctionType(), fn), &compilerRuntime.classMethodTypes.at(currentClassDecl->name).at(methodName)};
return {llvm::FunctionCallee(fn->getFunctionType(), fn), &compilerRuntime->classMethodTypes.at(currentClassDecl->name).at(methodName)};
}
}

Expand All @@ -466,7 +466,7 @@ namespace X::Codegen {
auto currentClassDecl = &classDecl;
while (currentClassDecl) {
const auto &className = currentClassDecl->llvmType->getName().str();
auto fn = module.getFunction(Mangler::mangleMethod(className, methodName));
auto fn = module.getFunction(mangler->mangleMethod(className, methodName));
if (fn) {
return fn;
}
Expand Down
16 changes: 8 additions & 8 deletions src/codegen/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace X::Codegen {
case Type::TypeID::BOOL:
return builder.getFalse();
case Type::TypeID::STRING:
return builder.CreateCall(module.getFunction(Mangler::mangleInternalFunction("createEmptyString")));
return builder.CreateCall(module.getFunction(mangler->mangleInternalFunction("createEmptyString")));
case Type::TypeID::ARRAY: {
auto arrType = getArrayForType(type);
auto arr = newObj(arrType);
Expand Down Expand Up @@ -179,14 +179,14 @@ namespace X::Codegen {
case Type::TypeID::BOOL:
return value;
case Type::TypeID::STRING: {
const auto &stringIsEmptyFnName = Mangler::mangleInternalMethod(Runtime::String::CLASS_NAME, "isEmpty");
const auto &stringIsEmptyFnName = mangler->mangleInternalMethod(Runtime::String::CLASS_NAME, "isEmpty");
auto stringIsEmptyFn = module.getFunction(stringIsEmptyFnName);
auto val = builder.CreateCall(stringIsEmptyFn, {value});
return negate(val);
}
case Type::TypeID::ARRAY: {
const auto &arrayClassName = Runtime::ArrayRuntime::getClassName(type);
const auto &arrayIsEmptyFnName = Mangler::mangleInternalMethod(arrayClassName, "isEmpty");
const auto &arrayIsEmptyFnName = mangler->mangleInternalMethod(arrayClassName, "isEmpty");
auto arrayIsEmptyFn = module.getFunction(arrayIsEmptyFnName);
auto val = builder.CreateCall(arrayIsEmptyFn, {value});
return negate(val);
Expand All @@ -200,11 +200,11 @@ namespace X::Codegen {
auto &currentClassDecl = getClassDecl(instanceType.getClassName());
auto expectedInterfaceDecl = findInterfaceDecl(type.getClassName());
if (expectedInterfaceDecl) {
return compilerRuntime.implementedInterfaces[currentClassDecl.name].contains(expectedInterfaceDecl->name);
return compilerRuntime->implementedInterfaces[currentClassDecl.name].contains(expectedInterfaceDecl->name);
}

auto &expectedClassDecl = getClassDecl(type.getClassName());
return compilerRuntime.extendedClasses[currentClassDecl.name].contains(expectedClassDecl.name);
return compilerRuntime->extendedClasses[currentClassDecl.name].contains(expectedClassDecl.name);
}

llvm::Value *Codegen::castTo(llvm::Value *value, const Type &type, const Type &expectedType) {
Expand Down Expand Up @@ -244,7 +244,7 @@ namespace X::Codegen {
}

llvm::Value *Codegen::compareStrings(llvm::Value *first, llvm::Value *second) const {
auto compareStringsFn = module.getFunction(Mangler::mangleInternalFunction("compareStrings"));
auto compareStringsFn = module.getFunction(mangler->mangleInternalFunction("compareStrings"));
return builder.CreateCall(compareStringsFn, {first, second});
}

Expand All @@ -267,14 +267,14 @@ namespace X::Codegen {
auto arrayType = llvm::StructType::getTypeByName(context, arrayClassName);
if (!arrayType) {
// gen array subtype
return arrayRuntime.add(arrType, mapType(subtype));
return arrayRuntime->add(arrType, mapType(subtype));
}
return arrayType;
}

void Codegen::fillArray(llvm::Value *arr, const Type &type, const std::vector<llvm::Value *> &values) {
const auto &arrayClassName = Runtime::ArrayRuntime::getClassName(type);
auto arrSetFn = module.getFunction(Mangler::mangleInternalMethod(arrayClassName, "set[]"));
auto arrSetFn = module.getFunction(mangler->mangleInternalMethod(arrayClassName, "set[]"));
if (!arrSetFn) {
throw InvalidArrayAccessException();
}
Expand Down
18 changes: 12 additions & 6 deletions src/codegen/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,10 @@ namespace X::Codegen {
llvm::LLVMContext &context;
llvm::IRBuilder<> &builder;
llvm::Module &module;
CompilerRuntime &compilerRuntime;
Runtime::ArrayRuntime arrayRuntime;
GC::GC &gc;
std::shared_ptr<CompilerRuntime> compilerRuntime;
std::unique_ptr<Runtime::ArrayRuntime> arrayRuntime;
std::shared_ptr<GC::GC> gc;
std::shared_ptr<Mangler> mangler;

std::deque<std::unordered_map<std::string, Value>> varScopes;
std::stack<Loop> loops;
Expand All @@ -105,9 +106,14 @@ namespace X::Codegen {
static inline const std::string MAIN_FN_NAME = "main";
static inline const std::string INIT_FN_NAME = "init";

Codegen(llvm::LLVMContext &context, llvm::IRBuilder<> &builder, llvm::Module &module, CompilerRuntime &compilerRuntime, GC::GC &gc) :
context(context), builder(builder), module(module), compilerRuntime(compilerRuntime), arrayRuntime(Runtime::ArrayRuntime(context, module)),
gc(gc) {}
Codegen(llvm::LLVMContext &context,
llvm::IRBuilder<> &builder,
llvm::Module &module,
std::shared_ptr<CompilerRuntime> compilerRuntime,
std::unique_ptr<Runtime::ArrayRuntime> arrayRuntime,
std::shared_ptr<GC::GC> gc,
std::shared_ptr<Mangler> mangler) : context(context), builder(builder), module(module), compilerRuntime(std::move(compilerRuntime)),
arrayRuntime(std::move(arrayRuntime)), gc(std::move(gc)), mangler(std::move(mangler)) {}

void genProgram(TopStatementListNode *node);

Expand Down
30 changes: 15 additions & 15 deletions src/codegen/decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace X::Codegen {
for (auto interfaceNode: node->getInterfaces()) {
auto &name = interfaceNode->getName();
addSymbol(name);
const auto &mangledName = Mangler::mangleInterface(name);
const auto &mangledName = mangler->mangleInterface(name);

auto interface = llvm::StructType::create(context, mangledName);

Expand All @@ -28,7 +28,7 @@ namespace X::Codegen {

addSymbol(name);

auto klass = llvm::StructType::create(context, Mangler::mangleClass(name));
auto klass = llvm::StructType::create(context, mangler->mangleClass(name));

classes[name] = {
.name = name,
Expand All @@ -42,7 +42,7 @@ namespace X::Codegen {
void Codegen::declProps(TopStatementListNode *node) {
for (auto klassNode: node->getClasses()) {
auto &name = klassNode->getName();
const auto &mangledName = Mangler::mangleClass(name);
const auto &mangledName = mangler->mangleClass(name);
auto &classDecl = classes[name];
auto klass = classDecl.llvmType;
GC::PointerList pointerList;
Expand All @@ -60,8 +60,8 @@ namespace X::Codegen {
classDecl.needInit = parentClassDecl.needInit;
}

auto it = compilerRuntime.virtualMethods.find(name);
if (it != compilerRuntime.virtualMethods.cend() && !it->second.empty()) {
auto it = compilerRuntime->virtualMethods.find(name);
if (it != compilerRuntime->virtualMethods.cend() && !it->second.empty()) {
auto vtableType = genVtable(klassNode, classDecl);
props.push_back(builder.getPtrTy());
propPos++;
Expand All @@ -79,7 +79,7 @@ namespace X::Codegen {
if (classDecl.staticProps.contains(propName)) {
throw PropAlreadyDeclaredException(name, propName);
}
const auto &mangledPropName = Mangler::mangleStaticProp(mangledName, propName);
const auto &mangledPropName = mangler->mangleStaticProp(mangledName, propName);
auto global = llvm::cast<llvm::GlobalVariable>(module.getOrInsertGlobal(mangledPropName, llvmType));
classDecl.staticProps[propName] = {global, type, prop->getAccessModifier()};
} else {
Expand Down Expand Up @@ -107,7 +107,7 @@ namespace X::Codegen {
}
}

classDecl.meta = gc.addMeta(GC::NodeType::CLASS, std::move(pointerList));
classDecl.meta = gc->addMeta(GC::NodeType::CLASS, std::move(pointerList));

if (classDecl.needInit) {
genClassInit(klassNode, classDecl);
Expand All @@ -117,7 +117,7 @@ namespace X::Codegen {

void Codegen::declMethods(TopStatementListNode *node) {
for (auto klass: node->getClasses()) {
const auto &mangledName = Mangler::mangleClass(klass->getName());
const auto &mangledName = mangler->mangleClass(klass->getName());
auto classDecl = &classes[klass->getName()];

// default constructor
Expand All @@ -133,7 +133,7 @@ namespace X::Codegen {
}

auto fnDef = methodDef->getFnDef();
const auto &fnName = Mangler::mangleMethod(mangledName, fnDef->getName());
const auto &fnName = mangler->mangleMethod(mangledName, fnDef->getName());
auto fnType = genFnType(fnDef->getArgs(), fnDef->getReturnType(), methodDef->getIsStatic() ? nullptr : &classDecl->type);
llvm::Function::Create(fnType, llvm::Function::ExternalLinkage, fnName, module);
classDecl->methods[methodName] = {methodDef->getAccessModifier(), fnType, false};
Expand Down Expand Up @@ -163,7 +163,7 @@ namespace X::Codegen {
auto initFn = llvm::Function::Create(
llvm::FunctionType::get(builder.getVoidTy(), {}, false),
llvm::Function::ExternalLinkage,
Mangler::mangleInternalFunction(INIT_FN_NAME),
mangler->mangleInternalFunction(INIT_FN_NAME),
module
);
auto bb = llvm::BasicBlock::Create(context, "entry", initFn);
Expand Down Expand Up @@ -227,8 +227,8 @@ namespace X::Codegen {
auto decl = prop->getDecl();
auto &type = decl->getType();
auto llvmType = mapType(decl->getType());
auto mangledClassName = Mangler::mangleClass(klass->getName());
auto mangledPropName = Mangler::mangleStaticProp(mangledClassName, decl->getName());
auto mangledClassName = mangler->mangleClass(klass->getName());
auto mangledPropName = mangler->mangleStaticProp(mangledClassName, decl->getName());
auto global = llvm::cast<llvm::GlobalVariable>(module.getOrInsertGlobal(mangledPropName, llvmType));

auto value = decl->getExpr() ?
Expand All @@ -246,21 +246,21 @@ namespace X::Codegen {
}

void Codegen::genClassInit(ClassNode *node, const ClassDecl &classDecl) {
auto mangledName = Mangler::mangleClass(classDecl.name);
auto mangledName = mangler->mangleClass(classDecl.name);

// create init function
auto initFn = llvm::Function::Create(
llvm::FunctionType::get(builder.getVoidTy(), {builder.getPtrTy()}, false),
llvm::Function::ExternalLinkage,
Mangler::mangleHiddenMethod(mangledName, INIT_FN_NAME),
mangler->mangleHiddenMethod(mangledName, INIT_FN_NAME),
module
);
builder.SetInsertPoint(llvm::BasicBlock::Create(context, "entry", initFn));

auto initFnThis = initFn->getArg(0);

if (classDecl.parent) {
if (auto parentInitFn = module.getFunction(Mangler::mangleHiddenMethod(Mangler::mangleClass(classDecl.parent->name), INIT_FN_NAME))) {
if (auto parentInitFn = module.getFunction(mangler->mangleHiddenMethod(mangler->mangleClass(classDecl.parent->name), INIT_FN_NAME))) {
builder.CreateCall(parentInitFn, {initFnThis});
}
}
Expand Down
Loading

0 comments on commit a679b53

Please sign in to comment.