tryna extend the extlib api a lot

This commit is contained in:
2026-06-24 20:07:35 +10:00
parent 56fedde3b5
commit 809bd39309
8 changed files with 174 additions and 45 deletions

View File

@@ -36,12 +36,11 @@ typedef struct {
UseList(CometSerializedFunc);
UseList(cometFuncPtr);
UseList(charptr);
UseList(StructField);
API_EXPORT CometStruct* cometGetExceptionStruct(CometEnvironment* env);
CometType createArrayType(CometType elem, uint8_t dimensions, bool isFixedSize[], uint64_t fixedSize[]);
CometType cometCreateArrayType(CometType elem, uint8_t dimensions, bool isFixedSize[], uint64_t fixedSize[]);
API_EXPORT CometSerializedFunc cometSerializeFunction(
CometVM* vm,
@@ -49,12 +48,12 @@ API_EXPORT CometSerializedFunc cometSerializeFunction(
externalLibFunc funcPtr
);
API_EXPORT CometOperand cometCreateObject(CometSerializedStruct* structType);
API_EXPORT CometObject* cometCreateObject(CometSerializedStruct* structType);
API_EXPORT CometOperand cometValue(CometValueTypeKind valueType, ...);
API_EXPORT int64_t serializeValue(CometOperand value);
API_EXPORT CometOperand deserializeValue(int64_t value, CometType type);
API_EXPORT int64_t cometSerializeValue(CometOperand value);
API_EXPORT CometOperand cometDeserializeValue(int64_t value, CometType type);
API_EXPORT void* cometArrayToCArray(CometOperand arrayValue, CometType elemType);
API_EXPORT CometOperand CArrayToCometArray(void* arrayValue, size_t length, CometType elemType);
@@ -76,9 +75,10 @@ API_EXPORT CometFunction* cometDefineMethod(
...
);
API_EXPORT void setStructFieldsAndMethods(CometStruct* cometStruct, List(StructField) fields, List(cometFuncPtr) methods);
API_EXPORT void cometSetStructFieldsAndMethods(CometStruct* cometStruct, List(StructField) fields, List(cometFuncPtr) methods);
API_EXPORT CometStruct* cometDefineStruct(CometEnvironment* env, char* name, CometStruct* parent);
API_EXPORT CometStruct* cometDefineStruct(CometEnvironment* env, char* name);
API_EXPORT void cometDefineConstructor(
CometEnvironment* env,
CometStruct* structType,
@@ -88,4 +88,8 @@ API_EXPORT void cometDefineConstructor(
);
API_EXPORT void cometSetField(CometObject* object, uint32_t index, int64_t value);
API_EXPORT CometSerializedStruct* cometVMGetStruct(CometVM* vm, char* structName);
API_EXPORT ResultType(int64_t, objectPtr) cometError(CometVM* vm, char* errorName, char* errorMessage);
#endif

View File

@@ -75,12 +75,14 @@ typedef struct {
} CometSerializedInst;
typedef struct {
char name[48];
uint32_t numFields;
uint32_t numMethods;
uint32_t* vtable;
} CometSerializedStruct;
typedef struct {
char name[48];
uint32_t numFields;
uint32_t numMethods;
} CometSerializedStructHeader;

View File

@@ -13,6 +13,8 @@
#include "debug.h"
#include <stdint.h>
typedef CometObject* objectPtr;
Result(int64_t, objectPtr);
Result(int, charptr);
typedef struct DebuggerBreakpoint DebuggerBreakpoint;
@@ -26,7 +28,7 @@ typedef struct {
} Frame;
typedef struct CometVM CometVM;
typedef int64_t (*externalLibFunc)(int64_t args[], CometVM* vm);
typedef ResultType(int64_t, objectPtr) (*externalLibFunc)(int64_t args[], CometVM* vm);
typedef struct {
uint64_t handlerIP;
@@ -93,4 +95,6 @@ Return from the function the VM is currently in.
*/
void returnFromFunc(CometVM* vm);
void vmThrow(CometVM* vm, char* errName, char* msg, CometObject* errPtr);
#endif

View File

@@ -8,6 +8,8 @@
#include <string.h>
#include <sys/types.h>
static CometStruct* exceptStruct = NULL;
static CometArrayType stringArray = {
.elem = &cometTypeSmall,
.isFixedSize = {false},
@@ -19,6 +21,31 @@ CometType const cometTypeString = {
.arrayType = &stringArray
};
int64_t Exception_INIT(int64_t* args, CometVM* vm) {
CometObject* exception = (CometObject*)args[0];
cometSetField(exception, 0, args[1]);
cometSetField(exception, 1, args[2]);
return (int64_t)exception;
}
CometStruct* cometGetExceptionStruct(CometEnvironment* env) {
if (exceptStruct != NULL)
return exceptStruct;
CometStruct* exceptStruct = cometDefineStruct(env, "Exception", NULL);
List(StructField) fields = newList(StructField);
StructField typeField = { .name = "type", .type = cometTypeString };
StructField msgField = { .name = "message", .type = cometTypeString };
List(cometFuncPtr) methods = newList(cometFuncPtr);
cometSetStructFieldsAndMethods(exceptStruct, fields, methods);
cometDefineConstructor(env, exceptStruct, 2, false, cometTypeString, cometTypeString);
return exceptStruct;
}
CometSerializedFunc cometSerializeFunction(
CometVM* vm,
CometFunction* func,
@@ -42,7 +69,7 @@ CometSerializedFunc cometSerializeFunction(
return serializedFunc;
}
int64_t serializeValue(CometOperand value) {
int64_t cometSerializeValue(CometOperand value) {
if (value.type == CO_SYMBOL) {
return value.symbolIdx;
}
@@ -65,7 +92,7 @@ int64_t serializeValue(CometOperand value) {
return 0;
for (size_t i = 0; i < capacity; i++) {
arr->data[i] = serializeValue(value.imm.arrayVal.data[i]);
arr->data[i] = cometSerializeValue(value.imm.arrayVal.data[i]);
}
arr->capacity = capacity;
arr->elemType = cometTypeBig;
@@ -86,7 +113,7 @@ int64_t serializeValue(CometOperand value) {
}
}
CometOperand deserializeValue(int64_t value, CometType type) {
CometOperand cometDeserializeValue(int64_t value, CometType type) {
switch (type.typeKind) {
case COMET_SMALL : return (CometOperand){ .type = CO_IMMEDIATE, .imm.typeKind = COMET_SMALL, .imm.smallVal = value };
case COMET_INT : return (CometOperand){ .type = CO_IMMEDIATE, .imm.typeKind = COMET_INT, .imm.intVal = value };
@@ -128,7 +155,7 @@ CometOperand deserializeValue(int64_t value, CometType type) {
int64_t* serializedData = array->data;
for (size_t i = 0; i < capacity; i++) {
deserializedData[i] = deserializeValue(serializedData[i], array->elemType);
deserializedData[i] = cometDeserializeValue(serializedData[i], array->elemType);
}
return deserializedValue;
@@ -198,19 +225,34 @@ API_EXPORT void* cometArrayToCArray(CometOperand arrayValue, CometType elemType)
return cArray;
}
void setStructFieldsAndMethods(CometStruct* cometStruct, List(StructField) fields, List(cometFuncPtr) methods) {
char** fieldNames = calloc(fields.count, sizeof(char*));
CometType* fieldTypes = calloc(fields.count, sizeof(CometType));
void cometSetStructFieldsAndMethods(CometStruct* cometStruct, List(StructField) fields, List(cometFuncPtr) methods) {
size_t fieldCount = cometStruct->parent == NULL ? fields.count : fields.count + cometStruct->parent->fieldCount;
size_t methodCount = cometStruct->parent == NULL ? methods.count : methods.count + cometStruct->parent->numMethods;
CometFunction** methodsArr = malloc(sizeof(CometFunction*) * methods.count);
for (size_t i = 0; i < methods.count; i++) {
methodsArr[i] = *get(methods, i);
char** fieldNames = calloc(fieldCount, sizeof(char*));
CometType* fieldTypes = calloc(fieldCount, sizeof(CometType));
CometFunction** methodsArr = calloc(methodCount, sizeof(CometFunction*));
size_t methodIdx = 0;
size_t fieldIdx = 0;
if (cometStruct->parent != NULL) {
memcpy(methodsArr, cometStruct->parent->vtable, sizeof(CometMethod*) * cometStruct->parent->numMethods);
memcpy(fieldNames, cometStruct->parent->fieldNames, sizeof(char*) * cometStruct->parent->fieldCount);
memcpy(fieldTypes, cometStruct->parent->fieldTypes, sizeof(CometType) * cometStruct->parent->fieldCount);
}
for (size_t i = 0; i < fields.count; i++) {
StructField field = *get(fields, i);
fieldNames[i] = strdup(field.name); // we strdup it or else it might go out of scope and become invalid
fieldTypes[i] = field.type;
for (methodIdx = methodIdx; methodIdx < methods.count; methodIdx++) {
methodsArr[methodIdx] = *get(methods, methodIdx);
}
for (fieldIdx = fieldIdx; fieldIdx < fields.count; fieldIdx++) {
StructField field = *get(fields, fieldIdx);
fieldNames[fieldIdx] = strdup(field.name); // we strdup it or else it might go out of scope and become invalid
fieldTypes[fieldIdx] = field.type;
}
cometStruct->fieldNames = fieldNames;
@@ -220,7 +262,7 @@ void setStructFieldsAndMethods(CometStruct* cometStruct, List(StructField) field
cometStruct->vtable = (CometMethod**)methodsArr;
}
CometStruct* cometDefineStruct(CometEnvironment* env, char* name) {
CometStruct* cometDefineStruct(CometEnvironment* env, char* name, CometStruct* parent) {
CometStruct* newStruct = malloc(sizeof(CometStruct));
@@ -236,7 +278,7 @@ CometStruct* cometDefineStruct(CometEnvironment* env, char* name) {
.fieldCount = 0,
.numMethods = 0,
.vtable = NULL,
.parent = NULL
.parent = parent
};
CometType structType = {
@@ -254,7 +296,8 @@ CometStruct* cometDefineStruct(CometEnvironment* env, char* name) {
.typeKind = COMET_TYPE,
};
defineVar(env, name, RECORD_LOCAL, structVal, typeType, false);
if (env)
defineVar(env, name, RECORD_LOCAL, structVal, typeType, false);
return newStruct;
}
@@ -301,7 +344,8 @@ CometFunction* cometDefineFunc(
va_end(args);
defineVar(env, name, RECORD_LOCAL, funcVal, type, false);
if (env)
defineVar(env, name, RECORD_LOCAL, funcVal, type, false);
return func;
}
@@ -349,7 +393,9 @@ CometFunction* cometDefineMethod(
func->argTypes = argTypes;
va_end(args);
defineVar(env, name, RECORD_LOCAL, funcVal, type, false);
if (env)
defineVar(env, name, RECORD_LOCAL, funcVal, type, false);
return func;
}
@@ -404,7 +450,8 @@ void cometDefineConstructor(
va_end(args);
defineVar(env, constructorName, RECORD_LOCAL, funcVal, type, false);
if (env)
defineVar(env, constructorName, RECORD_LOCAL, funcVal, type, false);
}
CometOperand cometValue(CometValueTypeKind valueType, ...) {
@@ -494,7 +541,7 @@ CometOperand cometValue(CometValueTypeKind valueType, ...) {
return newVal;
}
size_t GetCometTypeSize(CometType type) {
size_t getCometTypeSize(CometType type) {
switch (type.typeKind) {
case COMET_SMALL: case COMET_BOOL: return 1;
case COMET_INT: case COMET_FLOAT: return 4;
@@ -512,7 +559,7 @@ CometOperand CArrayToCometArray(void* arrayValue, size_t length, CometType elemT
if (!serializedData)
return (CometOperand){.type = CO_NONE};
size_t elemSize = GetCometTypeSize(elemType);
size_t elemSize = getCometTypeSize(elemType);
uint8_t* bytePtr = (uint8_t*)arrayValue;
@@ -528,7 +575,7 @@ CometOperand CArrayToCometArray(void* arrayValue, size_t length, CometType elemT
default: break;
}
serializedData[i] = deserializeValue(extractedValue, elemType);
serializedData[i] = cometDeserializeValue(extractedValue, elemType);
}
out.imm.typeKind = COMET_ARRAY;
@@ -540,7 +587,7 @@ CometOperand CArrayToCometArray(void* arrayValue, size_t length, CometType elemT
return out;
}
CometType createArrayType(CometType elem, uint8_t dimensions, bool isFixedSize[], uint64_t fixedSize[]) {
CometType cometCreateArrayType(CometType elem, uint8_t dimensions, bool isFixedSize[], uint64_t fixedSize[]) {
CometType* elemPtr = malloc(sizeof(CometType));
if (!elemPtr) return cometTypeVoid;
@@ -572,4 +619,33 @@ CometType createArrayType(CometType elem, uint8_t dimensions, bool isFixedSize[]
inline void cometSetField(CometObject* object, uint32_t index, int64_t value) {
object->fields[index] = value;
}
CometSerializedStruct* cometVMGetStruct(CometVM* vm, char* structName) {
for (size_t i = 0; i < vm->numStructs; i++) {
if (strcmp(vm->structs[i].name, structName) == 0) {
return &vm->structs[i];
}
}
return NULL;
}
API_EXPORT CometObject* cometCreateObject(CometSerializedStruct* structType) {
CometObject* obj = malloc(sizeof(CometObject));
obj->fields = calloc(structType->numFields, sizeof(int64_t));
obj->vtable = structType->vtable;
return obj;
}
ResultType(int64_t, objectPtr) cometError(CometVM* vm, char* errorName, char* errorMessage) {
CometSerializedStruct* exceptionStruct = cometVMGetStruct(vm, "Exception");
CometObject* exceptionObj = cometCreateObject(exceptionStruct);
exceptionObj->fields[0] = (int64_t)strdup(errorName);
exceptionObj->fields[1] = (int64_t)strdup(errorMessage);
return Error(int64_t, objectPtr, exceptionObj);
}

View File

@@ -14,6 +14,7 @@
#include <unistd.h>
#include <assert.h>
#include <dlfcn.h>
#include "../include/cometlib.h"
// -- HELPER METHODS -- //
@@ -3655,12 +3656,9 @@ ResultType(voidPtr, ErrorMessage) outputToFile(CometCompiler* c, const char* fil
CometStruct* structType = *get(c->structs, structIdx);
CometSerializedStruct* serializedStruct = serializeStruct(c->functions, structType);
CometSerializedStructHeader header = {
.numFields = serializedStruct->numFields,
.numMethods = serializedStruct->numMethods
};
fwrite(&header, sizeof(CometSerializedStructHeader), 1, file);
fwrite(serializedStruct->name, 1, 48, file);
fwrite(&serializedStruct->numFields, 1, sizeof(uint32_t), file);
fwrite(&serializedStruct->numMethods, 1, sizeof(uint32_t), file);
fwrite(serializedStruct->vtable, sizeof(uint32_t), serializedStruct->numMethods, file);
}
@@ -3697,6 +3695,30 @@ ResultType(voidPtr, ErrorMessage) outputToFile(CometCompiler* c, const char* fil
return Success(voidPtr, ErrorMessage, NULL);
}
ResultType(int64_t, objectPtr) impl_Exception_INIT(int64_t* args, CometVM* vm) {
CometObject* exception = (CometObject*)args[0];
exception->fields[0] = args[1];
exception->fields[1] = args[2];
return Success(int64_t, objectPtr, (int64_t)exception);
}
void createExceptionType(CometCompiler* c) {
List(StructField) fields = newList(StructField);
StructField nameField = { .name = "name", .type = cometTypeString };
StructField messageField = { .name = "message", .type = cometTypeString };
append(fields, nameField);
append(fields, messageField);
List(cometFuncPtr) methods = newList(cometFuncPtr);
CometStruct* exceptionType = cometDefineStruct(NULL, "Exception", NULL);
cometSetStructFieldsAndMethods(exceptionType, fields, methods);
cometDefineConstructor(NULL, exceptionType, 2, false, cometTypeString, cometTypeString);
append(c->structs, exceptionType);
}
ResultType(cometCompilerPtr, ErrorMessage) newCompiler(char* inputFilePath, char* sourceCode, bool debugSymbols) {
CometCompiler* newCompiler = calloc(1, sizeof(CometCompiler));
if (newCompiler == NULL) {
@@ -3759,6 +3781,8 @@ ResultType(cometCompilerPtr, ErrorMessage) newCompiler(char* inputFilePath, char
CometTypeMapEntry stringTypeEntry = { .name = "string", .type = stringType};
append(newCompiler->typeMap, stringTypeEntry);
createExceptionType(newCompiler);
// return new compiler
return Success(cometCompilerPtr, ErrorMessage, newCompiler);

View File

@@ -35,6 +35,9 @@ CometSerializedStruct* serializeStruct(CometFunction** compilerFuncs, CometStruc
.numMethods = structType->numMethods
};
size_t nameLen = strlen(structType->name) + 1;
memcpy(serialized->name, structType->name, nameLen < 48 ? nameLen : 48);
for (size_t i = 0; i < structType->numMethods; i++) {
CometMethod* method = structType->vtable[i];
serialized->vtable[i] = method->symbolIdx;

7
test.comet Normal file
View File

@@ -0,0 +1,7 @@
import io
func main() -> int {
io.File f = new io.File("test.txt", "w")
io.println("f.ptr = %n", f.ptr)
return 0
}

View File

@@ -101,9 +101,13 @@ void callFunction(CometVM* vm, CometSerializedFunc* function, uint8_t callArgs)
for (int8_t argIdx = numArgs; argIdx > 0; argIdx--) {
args[argIdx - 1] = popValue(vm);
}
int64_t returnValue = vm->externalFuncs[function->externFuncIndex](args, vm);
ResultType(int64_t, objectPtr) returnValue = vm->externalFuncs[function->externFuncIndex](args, vm);
if (returnValue.error) {
CometObject* obj = returnValue.as.error;
vmThrow(vm, (char*)obj->fields[0], (char*)obj->fields[1], obj);
}
pushValue(vm, returnValue);
pushValue(vm, returnValue.as.success);
return;
}
@@ -171,7 +175,7 @@ ResultType(voidPtr, charptr) invalidInstruction(CometSerializedInst inst) {
return Error(voidPtr, charptr, buffer);
}
void throw(CometVM* vm, char* errName, char* msg, CometObject* errPtr) {
void vmThrow(CometVM* vm, char* errName, char* msg, CometObject* errPtr) {
if (vm->currentExcept == 0) {
char* trace = stackTrace(vm);
@@ -365,7 +369,7 @@ ResultType(voidPtr, charptr) vmMainLoop(CometVM* vm) {
int64_t b = popValue(vm);
if (b == 0) {
throw(vm, "DivisionByZero", "Division by zero", NULL);
vmThrow(vm, "DivisionByZero", "Division by zero", NULL);
DISPATCH();
}
@@ -385,7 +389,7 @@ ResultType(voidPtr, charptr) vmMainLoop(CometVM* vm) {
memcpy(&bDouble, &b, sizeof(double));
if (bDouble == 0) {
throw(vm, "DivisionByZero", "Division by zero", NULL);
vmThrow(vm, "DivisionByZero", "Division by zero", NULL);
DISPATCH();
}
@@ -676,7 +680,7 @@ ResultType(voidPtr, charptr) vmMainLoop(CometVM* vm) {
exceptMsg[i] = exceptMsgArr->data[i];
}
throw(vm, exceptName, exceptMsg, exception);
vmThrow(vm, exceptName, exceptMsg, exception);
DISPATCH();
}
LIST_LENGTH: {
@@ -767,6 +771,10 @@ ResultType(vmPtr, charptr) newCometVM(char* filePath) {
for (uint32_t i = 0; i < loadedFile->numStructs; i++) {
uint32_t numFields;
uint32_t numMethods;
char name[48];
memcpy(name, cursor, 48);
cursor += 48;
memcpy(&numFields, cursor, sizeof(uint32_t));
cursor += sizeof(uint32_t);
@@ -776,6 +784,7 @@ ResultType(vmPtr, charptr) newCometVM(char* filePath) {
newVM->structs[i].numFields = numFields;
newVM->structs[i].numMethods = numMethods;
memcpy(newVM->structs[i].name, name, 48);
newVM->structs[i].vtable =
malloc(sizeof(uint32_t) * numMethods);