INHERITANCE IS SOMEWHAT WORKING

This commit is contained in:
2026-05-10 20:33:33 +10:00
parent c570d09dac
commit efd629b17d
3 changed files with 110 additions and 28 deletions

View File

@@ -89,18 +89,59 @@ ResultType(LLVMTypeRef, charptr) getType(CometCompiler* compiler, char* typeName
return Error(LLVMTypeRef, charptr, errMsg.str);
}
LLVMValueRef getStructMethod(CometCompiler* compiler, StructInfo* structInfo, char* funcName) {
LLVMValueRef function = NULL;
// struct doesn't inherit from anything
if (!structInfo->parent) {
Estr structFuncName = CREATE_ESTR(structInfo->name);
APPEND_ESTR(structFuncName, "_");
APPEND_ESTR(structFuncName, funcName);
function = LLVMGetNamedFunction(compiler->module, structFuncName.str);
DESTROY_ESTR(structFuncName);
} else {
StructInfo* currentParent = structInfo->parent;
// struct inherits from something, climb the parent tree until we find it
while (true) {
Estr structFuncName = CREATE_ESTR(currentParent->name);
APPEND_ESTR(structFuncName, "_");
APPEND_ESTR(structFuncName, funcName);
function = LLVMGetNamedFunction(compiler->module, structFuncName.str);
if (function != NULL) {
break;
}
DESTROY_ESTR(structFuncName);
if (currentParent->parent)
currentParent = currentParent->parent;
else
return NULL;
}
}
return function;
}
ResultType(CometValue, charptr) resolveValue(CometCompiler* compiler, CometASTNode* node);
ResultType(CometValue, charptr) callStructMethod(CometCompiler* compiler, LLVMValueRef self, StructInfo* structInfo, StructField* fieldInfo, struct AST_FUNC_CALL funcCall) {
char* funcName = funcCall.ident->data.AST_IDENTIFIER.ident;
Estr structFuncName = CREATE_ESTR(structInfo->name);
APPEND_ESTR(structFuncName, "_");
APPEND_ESTR(structFuncName, funcName);
printf("%s\n", structFuncName.str);
LLVMTypeRef funcType = fieldInfo->llvmType;
LLVMValueRef function = LLVMGetNamedFunction(compiler->module, structFuncName.str);
DESTROY_ESTR(structFuncName);
LLVMValueRef function = getStructMethod(compiler, structInfo, funcName);
if (!function) {
Estr errMsg = CREATE_ESTR("Failed to find method \"");
APPEND_ESTR(errMsg, funcName);
APPEND_ESTR(errMsg, "\" of struct \"");
APPEND_ESTR(errMsg, structInfo->name);
APPEND_ESTR(errMsg, "\"");
return Error(CometValue, charptr, errMsg.str);
}
List(LLVMValueRef) argValues = newList(LLVMValueRef);
append(argValues, self);
@@ -415,25 +456,8 @@ ResultType(CometValue, charptr) resolvePointerValue(CometCompiler* compiler, Com
ptrName.str
);
/*Estr valueName = CREATE_ESTR(fieldName);
APPEND_ESTR(valueName, "_field");
LLVMValueRef value = LLVMBuildLoad2(
compiler->builder,
fieldInfo->llvmType,
ptr,
valueName.str
);*/
//printf("%s is struct = %d\n", fieldName, LLVMGetTypeKind(fieldInfo->llvmType) == LLVMStructTypeKind);
bool isPointer = LLVMGetTypeKind(fieldInfo->llvmType) == LLVMStructTypeKind;
//Estr tempName = CREATE_ESTR(fieldName);
//APPEND_ESTR(tempName, "_tmp");
//LLVMValueRef temp = LLVMBuildAlloca(compiler->builder, fieldInfo->llvmType, tempName.str);
//LLVMBuildStore(compiler->builder, value, temp);
CometValue result = (CometValue){
.pointer = ptr,
.type = fieldInfo->llvmType,
@@ -673,6 +697,7 @@ ResultType(int, charptr) visitAssignStatement(CometCompiler* compiler, CometASTN
return Error(int, charptr, varAssignType.as.error);
printf("%s\n", LLVMPrintTypeToString(varAssignType.as.success));
LLVMValueRef ptr = LLVMBuildAlloca(compiler->builder, varAssignType.as.success, name);
if (value) { // if we set an actual value or didnt assign one
@@ -1250,8 +1275,15 @@ ResultType(structInfoPtr, charptr) handleInheritance(CometCompiler* compiler, st
// append fields from parent to child
for (size_t i = 0; i < parentStructInfo->fields.count; i++) {
append((*fields), *get((parentStructInfo->fields), i));
append(fieldTypes, (*get(parentStructInfo->fields, i)).llvmType);
StructField parentField = *get((parentStructInfo->fields), i);
append((*fields), parentField);
if (LLVMGetTypeKind(parentField.llvmType) == LLVMFunctionTypeKind)
continue;
append((*fieldTypes), parentField.llvmType);
}
return Success(structInfoPtr, charptr, parentStructInfo);
@@ -1270,9 +1302,10 @@ ResultType(int, charptr) visitStructDefStatement(CometCompiler* compiler, CometA
bool inherits = structDef.parentName != NULL;
StructInfo* parentStructInfo = NULL;
if (inherits) {
ResultType(structInfoPtr, charptr) inheritanceResult = handleInheritance(compiler, structDef, &structInfoFields, fieldTypes);
ResultType(structInfoPtr, charptr) inheritanceResult = handleInheritance(compiler, structDef, &structInfoFields, &fieldTypes);
if (inheritanceResult.error)
return Error(int, charptr, inheritanceResult.as.error);
parentStructInfo = inheritanceResult.as.success;
}
for (size_t i = 0; i < structDef.fieldDefs.count; i++) {

View File

@@ -44,7 +44,7 @@ UseList(LLVMValueRef);
UseList(CometLLVMTypePair);
typedef List(LLVMTypeRef) argTypeList;
typedef List(LLVMTypeRef) fieldTypeList;
typedef List(LLVMTypeRef)* fieldTypeList;
typedef struct {
CometEnvironment* env;
@@ -64,6 +64,7 @@ Result(LLVMTypeRef, charptr);
Result(LLVMValueRef, charptr);
Result(cometCompilerPtr, charptr);
Result(argTypeList, charptr);
Result(LLVMValueRef, Nothing);
typedef StructInfo* structInfoPtr;
Result(structInfoPtr, charptr);

48
test.ll Normal file
View File

@@ -0,0 +1,48 @@
; ModuleID = 'main'
source_filename = "main"
%Animal = type { i32 }
%Dog = type { i32 }
@str = private constant [5 x i8] c"...\0A\00"
declare i32 @printf(ptr, ...)
define void @Animal_speak(ptr %0) {
Animal_speak_entry:
%print = call i32 (ptr, ...) @printf(ptr @str)
ret void
}
define void @Animal_CONSTRUCTOR(ptr %0) {
Animal_CONSTRUCTOR_entry:
%age_default = getelementptr %Animal, ptr %0, i32 0, i32 0
store i32 0, ptr %age_default, align 4
ret void
}
define void @Dog_CONSTRUCTOR(ptr %0) {
Dog_CONSTRUCTOR_entry:
%age_default = getelementptr %Dog, ptr %0, i32 0, i32 0
store i32 0, ptr %age_default, align 4
ret void
}
define i32 @main() {
main_entry:
%myAnimal = alloca %Animal, align 8
%selfTmp = alloca %Animal, align 8
call void @Animal_CONSTRUCTOR(ptr %selfTmp)
%selfVal = load %Animal, ptr %selfTmp, align 4
store %Animal %selfVal, ptr %myAnimal, align 4
%myAnimal1 = load %Animal, ptr %myAnimal, align 4
call void @Animal_speak(ptr %myAnimal)
%myDog = alloca %Dog, align 8
%selfTmp2 = alloca %Dog, align 8
call void @Dog_CONSTRUCTOR(ptr %selfTmp2)
%selfVal3 = load %Dog, ptr %selfTmp2, align 4
store %Dog %selfVal3, ptr %myDog, align 4
%myDog4 = load %Dog, ptr %myDog, align 4
call void @Animal_speak(ptr %myDog)
ret i32 0
}