From f0ee7263ec73c48df586891252adb672de7cdfcf Mon Sep 17 00:00:00 2001 From: SpookyDervish Date: Tue, 4 Aug 2026 09:50:48 +1000 Subject: [PATCH] block parameters working i think --- include/gravity/core.h | 9 +++-- src/block.c | 41 ++++++++++++++++++++--- src/block.h | 16 ++++++--- src/builder.c | 27 ++++++++++++++- src/builder.h | 6 +++- src/function.c | 27 ++------------- src/function.h | 3 +- src/instruction.c | 2 ++ src/instruction.h | 10 ++++-- src/type.c | 2 +- src/type.h | 3 +- src/value.c | 76 +++++++++++++++++++++++++++++++++++++----- src/value.h | 18 +++++----- test.c | 37 ++++++++++++++++---- 14 files changed, 211 insertions(+), 66 deletions(-) diff --git a/include/gravity/core.h b/include/gravity/core.h index f66115e..46bf591 100644 --- a/include/gravity/core.h +++ b/include/gravity/core.h @@ -25,19 +25,22 @@ GravityModule gravityCreateModule(void); GravityBuilder gravityCreateBuilder(void); GravityFunction gravityNewFunction(GravityModule module, const char* name, GravityType functionType); -GravityBlock gravityStartBlock(const char* name, GravityFunction function, uint16_t numBlockParams, ...); +GravityBlock gravityStartBlock(const char* name, GravityFunction function); GravityValue newIntConstant(GravityType intType, int64_t value); GravityType gravityCreateFunctionType(int numArgs, GravityType* argTypes, GravityType returnType); GravityType gravityCreateIntegerType(uint8_t width, bool isSigned); +GravityType gravityCreatePointerType(void); char* gravityModuleToCStr(GravityModule module); char* gravityTypeToCStr(GravityType type); char* gravityFunctionToCStr(GravityFunction function); char* gravityValueToCStr(GravityValue value); -void gravityPositionBuilderAtEnd(GravityBuilder builder, GravityBlock block); +void gravityBuilderSwitchToBlock(GravityBuilder builder, GravityBlock block); +void gravityAppendBlockArgument(GravityBlock block, GravityType type); +GravityValue gravityGetBlockArg(GravityBlock block, unsigned int index); GravityValue gravityNewIntConstant(GravityType intType, int64_t value); @@ -46,6 +49,8 @@ GravityValue gravityBuildAlloc(GravityBuilder builder, GravityType type, const c void gravityBuildStore(GravityBuilder builder, GravityValue pointer, GravityValue value); GravityValue gravityBuildLoad(GravityBuilder builder, GravityValue pointer, const char* name); void gravityBuildRet(GravityBuilder builder, GravityValue returnValue); +void gravityBuildBr(GravityBuilder builder, GravityValue condition, GravityBlock thenBranch, GravityValue* thenParams, GravityBlock elseBranch, GravityValue* elseParams); +void gravityBuildJump(GravityBuilder builder, GravityBlock block, GravityValue* params); // ============================ // diff --git a/src/block.c b/src/block.c index b744ba8..94f5d23 100644 --- a/src/block.c +++ b/src/block.c @@ -1,16 +1,46 @@ #include "block.h" +GravityBlock gravityNewBlock(const char* name) { + GravityBlock newBlock = malloc(sizeof(struct GravityOpaqueBlock)); + if (newBlock == NULL) return newBlock; + + newBlock->name = strdup(name); + + newBlock->params = newList(GravityBlockParam); + newBlock->instructions = newList(GravityInstruction); + + return newBlock; +} + +void gravityAppendBlockArgument(GravityBlock block, GravityType type) { + GravityBlockParam param = { + .type = type, + .value = gravityNewValue(NULL, type) + }; + + append(block->params, param); +} + +GravityValue gravityGetBlockArg(GravityBlock block, unsigned int index) { + GravityBlockParam* param = get(block->params, index); + if (param == NULL) return NULL; + + return param->value; +} + char* gravityBlockToCStr(GravityBlock block) { StringBuffer buff; initStringBuff(&buff); // print block header sbAppend(&buff, "%s (", block->name); - for (unsigned int i = 0; i < block->numParams; i++) { - if (i < block->numParams - 1) { - sbAppend(&buff, "%s, ", gravityTypeToCStr(block->paramTypes[i])); + for (unsigned int i = 0; i < block->params.count; i++) { + GravityBlockParam param = *get(block->params, i); + + if (i < block->params.count - 1) { + sbAppend(&buff, "%s %s, ", gravityTypeToCStr(param.type), gravityValueToCStr(param.value)); } else { - sbAppend(&buff, "%s", gravityTypeToCStr(block->paramTypes[i])); + sbAppend(&buff, "%s %s", gravityTypeToCStr(param.type), gravityValueToCStr(param.value)); } } sbAppend(&buff, "):"); @@ -21,4 +51,5 @@ char* gravityBlockToCStr(GravityBlock block) { } return buff.data; -} \ No newline at end of file +} + diff --git a/src/block.h b/src/block.h index 0f4f73a..0b900b6 100644 --- a/src/block.h +++ b/src/block.h @@ -2,21 +2,29 @@ #define __GRAVITY__BLOCK_H #include "list.h" -#include "instruction.h" #include "type.h" +#include "instruction.h" typedef struct GravityOpaqueBlock* GravityBlock; +typedef struct { + GravityValue value; + GravityType type; +} GravityBlockParam; + +UseList(GravityBlockParam); UseList(GravityInstruction); struct GravityOpaqueBlock { const char* name; - GravityType* paramTypes; - uint16_t numParams; - + List(GravityBlockParam) params; + List(GravityValue) values; List(GravityInstruction) instructions; }; char* gravityBlockToCStr(GravityBlock block); +void gravityAppendBlockArgument(GravityBlock block, GravityType type); +GravityValue gravityGetBlockArg(GravityBlock block, unsigned int index); +GravityBlock gravityNewBlock(const char* name); #endif \ No newline at end of file diff --git a/src/builder.c b/src/builder.c index ab94092..5a40c95 100644 --- a/src/builder.c +++ b/src/builder.c @@ -32,7 +32,7 @@ GravityBuilder gravityCreateBuilder(void) { return newBuilder; } -void gravityPositionBuilderAtEnd(GravityBuilder builder, GravityBlock block) { +void gravityBuilderSwitchToBlock(GravityBuilder builder, GravityBlock block) { builder->currentBlock = block; } @@ -91,4 +91,29 @@ void gravityBuildRet(GravityBuilder builder, GravityValue returnValue) { NULL ); } +} + +void gravityBuildBr(GravityBuilder builder, GravityValue condition, GravityBlock thenBranch, GravityValue* thenParams, GravityBlock elseBranch, GravityValue* elseParams) { + GravityValue thenValue = gravityNewBlockReference(thenBranch, thenParams); + GravityValue elseValue = gravityNewBlockReference(elseBranch, elseParams); + + gravityBuildInstruction( + builder, + GravityOpcodeBranch, + (GravityValue[]){condition, thenValue, elseValue}, + 3, + NULL + ); +} + +void gravityBuildJump(GravityBuilder builder, GravityBlock block, GravityValue* params) { + GravityValue blockValue = gravityNewBlockReference(block, params); + + gravityBuildInstruction( + builder, + GravityOpcodeJump, + (GravityValue[]){blockValue}, + 1, + NULL + ); } \ No newline at end of file diff --git a/src/builder.h b/src/builder.h index 4fee13a..a3cbfcf 100644 --- a/src/builder.h +++ b/src/builder.h @@ -1,7 +1,9 @@ #ifndef __GRAVITY__BUILDER_H #define __GRAVITY__BUILDER_H +#include "value.h" #include "block.h" +#include "instruction.h" #include #include @@ -13,11 +15,13 @@ struct GravityOpaqueBuilder { GravityBuilder gravityCreateBuilder(void); -void gravityPositionBuilderAtEnd(GravityBuilder builder, GravityBlock block); +void gravityBuilderSwitchToBlock(GravityBuilder builder, GravityBlock block); GravityValue gravityBuildAlloc(GravityBuilder builder, GravityType type, const char* name); void gravityBuildStore(GravityBuilder builder, GravityValue pointer, GravityValue value); GravityValue gravityBuildLoad(GravityBuilder builder, GravityValue pointer, const char* name); void gravityBuildRet(GravityBuilder builder, GravityValue returnValue); +void gravityBuildBr(GravityBuilder builder, GravityValue condition, GravityBlock thenBranch, GravityValue* thenParams, GravityBlock elseBranch, GravityValue* elseParams); +void gravityBuildJump(GravityBuilder builder, GravityBlock block, GravityValue* params); #endif \ No newline at end of file diff --git a/src/function.c b/src/function.c index 5b7d0f2..5e1d78a 100644 --- a/src/function.c +++ b/src/function.c @@ -1,28 +1,9 @@ #include "function.h" -GravityBlock gravityStartBlock(const char* name, GravityFunction function, uint16_t numBlockParams, ...) { - GravityBlock newBlock = malloc(sizeof(struct GravityOpaqueBlock)); +GravityBlock gravityStartBlock(const char* name, GravityFunction function) { + GravityBlock newBlock = gravityNewBlock(name); if (newBlock == NULL) return newBlock; - newBlock->name = strdup(name); - - GravityType* paramTypes = calloc(numBlockParams, sizeof(GravityType)); - if (paramTypes == NULL) { - free(newBlock); - return NULL; - } - - va_list vargs; - va_start(vargs, numBlockParams); - - for (unsigned int i = 0; i < numBlockParams; i++) { - paramTypes[i] = va_arg(vargs, GravityType); - } - - newBlock->numParams = numBlockParams; - newBlock->paramTypes = paramTypes; - newBlock->instructions = newList(GravityInstruction); - append(function->blocks, newBlock); return newBlock; @@ -37,11 +18,9 @@ char* gravityFunctionToCStr(GravityFunction function) { for (unsigned int i = 0; i < function->functionType.numArgs; i++) { if (i < function->functionType.numArgs) { sbAppend(&buff, "%s, ", gravityTypeToCStr(function->functionType.argTypes[i])); - } else { sbAppend(&buff, "%s", gravityTypeToCStr(function->functionType.argTypes[i])); } - break; } @@ -49,7 +28,7 @@ char* gravityFunctionToCStr(GravityFunction function) { sbAppend(&buff, ") %s {\n", gravityTypeToCStr(function->functionType.returnType)); for (unsigned int i = 0; i < function->blocks.count; i++) { GravityBlock block = *get(function->blocks, i); - sbAppend(&buff, "%s\n", gravityBlockToCStr(block)); + sbAppend(&buff, "%s\n\n", gravityBlockToCStr(block)); } sbAppend(&buff, "}"); diff --git a/src/function.h b/src/function.h index 837736f..941f8bc 100644 --- a/src/function.h +++ b/src/function.h @@ -5,6 +5,7 @@ #include "block.h" #include "list.h" #include "strb.h" +#include "instruction.h" #include #include #include @@ -19,7 +20,7 @@ struct GravityOpaqueFunction { const char* name; }; -GravityBlock gravityStartBlock(const char* name, GravityFunction function, uint16_t numBlockParams, ...); +GravityBlock gravityStartBlock(const char* name, GravityFunction function); char* gravityFunctionToCStr(GravityFunction function); #endif \ No newline at end of file diff --git a/src/instruction.c b/src/instruction.c index 744c74f..1ad7974 100644 --- a/src/instruction.c +++ b/src/instruction.c @@ -6,6 +6,8 @@ char* gravityOpcodeToCStr(GravityOpcode opcode) { case GravityOpcodeStore: return "store"; case GravityOpcodeLoad: return "load"; case GravityOpcodeRet: return "ret"; + case GravityOpcodeBranch: return "br"; + case GravityOpcodeJump: return "jmp"; default: return "fixme"; } } diff --git a/src/instruction.h b/src/instruction.h index e78e2a0..5ade036 100644 --- a/src/instruction.h +++ b/src/instruction.h @@ -4,19 +4,23 @@ #include "value.h" #include +typedef struct GravityInstruction GravityInstruction; + typedef enum { GravityOpcodeAlloc = 0, GravityOpcodeStore, GravityOpcodeLoad, - GravityOpcodeRet + GravityOpcodeRet, + GravityOpcodeBranch, + GravityOpcodeJump } GravityOpcode; -typedef struct { +struct GravityInstruction { GravityOpcode opcode; GravityValue* operands; size_t numOperands; GravityValue result; -} GravityInstruction; +}; char* gravityInstructionToCStr(GravityInstruction inst); char* gravityOpcodeToCStr(GravityOpcode opcode); diff --git a/src/type.c b/src/type.c index 071197f..97ff886 100644 --- a/src/type.c +++ b/src/type.c @@ -52,7 +52,7 @@ char* gravityTypeToCStr(GravityType type) { } case GravityPointerTypeKind: { - sbAppend(&buff, "pointer"); + sbAppend(&buff, "ptr"); break; } diff --git a/src/type.h b/src/type.h index 7933926..3af9433 100644 --- a/src/type.h +++ b/src/type.h @@ -15,7 +15,8 @@ typedef enum { GravityFloatTypeKind, GravityPointerTypeKind, GravityFunctionTypeKind, - GravityTypeTypeKind, // type name + GravityTypeTypeKind, + GravityBlockTypeKind } GravityTypeKind; typedef struct { diff --git a/src/value.c b/src/value.c index dab4ad3..8d9ebff 100644 --- a/src/value.c +++ b/src/value.c @@ -1,4 +1,5 @@ #include "value.h" +#include "block.h" uint32_t globalValueIncrementer = 0; @@ -6,7 +7,7 @@ char* getIncrementedName(void) { char* buffer = malloc(32); if (buffer == NULL) return buffer; - snprintf(buffer, 32, "%%%d", globalValueIncrementer); + snprintf(buffer, 32, "%d", globalValueIncrementer); globalValueIncrementer++; @@ -43,14 +44,17 @@ GravityValue gravityTypeToTypeValue(GravityType type) { } char* gravityValueToCStr(GravityValue value) { + StringBuffer buff; + initStringBuff(&buff); + switch (value->kind) { - case GravityLocalValueKind: - - return strdup(value->name); + case GravityLocalValueKind: { + sbAppend(&buff, "%%%s", value->name); + break; + } case GravityConstantValueKind: { - StringBuffer buff; - initStringBuff(&buff); + switch (value->type->typeKind) { case GravityIntTypeKind: { @@ -63,14 +67,36 @@ char* gravityValueToCStr(GravityValue value) { break; } + case GravityBlockTypeKind: { + GravityBlock actualBlock = ((GravityBlock)value->constant.blockValue.block); + sbAppend(&buff, "%s(", actualBlock->name); + + GravityValue* blockParams = value->constant.blockValue.params; + + for (unsigned int i = 0; i < actualBlock->params.count; i++) { + GravityValue paramValue = blockParams[i]; + + if (i < actualBlock->params.count - 1) { + sbAppend(&buff, "%s, ", gravityValueToCStr(paramValue)); + } else { + sbAppend(&buff, "%s", gravityValueToCStr(paramValue)); + } + } + + sbAppend(&buff, ")"); + + break; + } + default: assert(false); } - - return buff.data; + break; } default: assert(false); } + + return buff.data; } GravityValue gravityNewConstant(GravityType type) { @@ -93,4 +119,38 @@ GravityValue gravityNewIntConstant(GravityType intType, int64_t value) { newValue->constant.intValue = value; return newValue; +} + +GravityValue gravityNewBlockReference(void* block, GravityValue* passedParams) { + GravityType blockType = gravityCreateType(); + blockType->typeKind = GravityBlockTypeKind; + + GravityValue newValue = gravityNewConstant(blockType); + if (newValue == NULL) return newValue; + + // create copy so we don't have issues with stack lifetimes + size_t numParams = ((GravityBlock)block)->params.count; + + if (numParams == 0) { + newValue->constant.blockValue.params = NULL; + } else { + GravityValue* passedParamsCopy = calloc(numParams, sizeof(GravityValue)); + + if (passedParamsCopy == NULL) { + gravityFreeValue(newValue); + return NULL; + } + + memcpy(passedParamsCopy, passedParams, sizeof(GravityValue) * numParams); + newValue->constant.blockValue.params = passedParamsCopy; + } + + // fill in values + newValue->constant.blockValue.block = block; + + return newValue; +} + +void gravityFreeValue(GravityValue value) { + free(value); } \ No newline at end of file diff --git a/src/value.h b/src/value.h index 458f0c0..9913c9a 100644 --- a/src/value.h +++ b/src/value.h @@ -6,13 +6,18 @@ extern uint32_t globalValueIncrementer; typedef struct GravityOpaqueValue* GravityValue; -typedef struct GravityOpaqueConstant* GravityConstant; +UseList(GravityValue); typedef enum { GravityLocalValueKind, GravityConstantValueKind } GravityValueKind; +typedef struct { + void* block; + GravityValue* params; +} GravityBlockReference; + struct GravityOpaqueValue { GravityValueKind kind; GravityType type; @@ -20,21 +25,18 @@ struct GravityOpaqueValue { union { int64_t intValue; + GravityBlockReference blockValue; } constant; }; -struct GravityOpaqueConstant { - GravityType type; - union { - int64_t intValue; - }; -}; - GravityValue gravityNewValue(const char* name, GravityType type); GravityValue gravityTypeToTypeValue(GravityType type); char* gravityValueToCStr(GravityValue value); GravityValue gravityNewConstant(GravityType type); GravityValue gravityNewIntConstant(GravityType intType, int64_t value); +GravityValue gravityNewBlockReference(void* block, GravityValue* passedParams); + +void gravityFreeValue(GravityValue value); #endif \ No newline at end of file diff --git a/test.c b/test.c index a95f7ae..76ba47e 100644 --- a/test.c +++ b/test.c @@ -6,19 +6,42 @@ int main(void) { GravityBuilder builder = gravityCreateBuilder(); GravityType charType = gravityCreateIntegerType(8, false); + GravityType ptrType = gravityCreatePointerType(); GravityType mainFuncType = gravityCreateFunctionType(0, NULL, charType); GravityFunction mainFunc = gravityNewFunction(module, "main", mainFuncType); - GravityBlock entryBlock = gravityStartBlock("entry", mainFunc, 0); + GravityBlock entryBlock = gravityStartBlock("entry", mainFunc); - gravityPositionBuilderAtEnd(builder, entryBlock); - GravityValue someVar = gravityBuildAlloc(builder, charType, NULL); + // define blocks + GravityBlock thenBlock = gravityStartBlock("then", mainFunc); + gravityAppendBlockArgument(thenBlock, ptrType); - GravityValue someConstant = gravityNewIntConstant(charType, 123); - gravityBuildStore(builder, someVar, someConstant); + GravityBlock elseBlock = gravityStartBlock("else", mainFunc); + gravityAppendBlockArgument(elseBlock, ptrType); - GravityValue output = gravityBuildLoad(builder, someVar, NULL); - gravityBuildRet(builder, output); + GravityBlock mergeBlock = gravityStartBlock("merge", mainFunc); + + // write entry + gravityBuilderSwitchToBlock(builder, entryBlock); + GravityValue x = gravityBuildAlloc(builder, charType, "x"); + + gravityBuildBr(builder, gravityNewIntConstant(charType, 1), thenBlock, (GravityValue[]){x}, elseBlock, (GravityValue[]){x}); + + // then block + gravityBuilderSwitchToBlock(builder, thenBlock); + GravityValue thenValue = gravityGetBlockArg(thenBlock, 0); + gravityBuildStore(builder, thenValue, gravityNewIntConstant(charType, 5)); + gravityBuildJump(builder, mergeBlock, NULL); + + // else block + gravityBuilderSwitchToBlock(builder, elseBlock); + GravityValue elseValue = gravityGetBlockArg(elseBlock, 0); + gravityBuildStore(builder, elseValue, gravityNewIntConstant(charType, 10)); + gravityBuildJump(builder, mergeBlock, NULL); + + gravityBuilderSwitchToBlock(builder, mergeBlock); + GravityValue xValue = gravityBuildLoad(builder, x, "xValue"); + gravityBuildRet(builder, xValue); printf("%s\n", gravityFunctionToCStr(mainFunc));