block parameters working i think

This commit is contained in:
2026-08-04 09:50:48 +10:00
parent a452c323e1
commit f0ee7263ec
14 changed files with 211 additions and 66 deletions

View File

@@ -25,19 +25,22 @@ GravityModule gravityCreateModule(void);
GravityBuilder gravityCreateBuilder(void); GravityBuilder gravityCreateBuilder(void);
GravityFunction gravityNewFunction(GravityModule module, const char* name, GravityType functionType); 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); GravityValue newIntConstant(GravityType intType, int64_t value);
GravityType gravityCreateFunctionType(int numArgs, GravityType* argTypes, GravityType returnType); GravityType gravityCreateFunctionType(int numArgs, GravityType* argTypes, GravityType returnType);
GravityType gravityCreateIntegerType(uint8_t width, bool isSigned); GravityType gravityCreateIntegerType(uint8_t width, bool isSigned);
GravityType gravityCreatePointerType(void);
char* gravityModuleToCStr(GravityModule module); char* gravityModuleToCStr(GravityModule module);
char* gravityTypeToCStr(GravityType type); char* gravityTypeToCStr(GravityType type);
char* gravityFunctionToCStr(GravityFunction function); char* gravityFunctionToCStr(GravityFunction function);
char* gravityValueToCStr(GravityValue value); 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); 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); void gravityBuildStore(GravityBuilder builder, GravityValue pointer, GravityValue value);
GravityValue gravityBuildLoad(GravityBuilder builder, GravityValue pointer, const char* name); GravityValue gravityBuildLoad(GravityBuilder builder, GravityValue pointer, const char* name);
void gravityBuildRet(GravityBuilder builder, GravityValue returnValue); 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);
// ============================ // // ============================ //

View File

@@ -1,16 +1,46 @@
#include "block.h" #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) { char* gravityBlockToCStr(GravityBlock block) {
StringBuffer buff; StringBuffer buff;
initStringBuff(&buff); initStringBuff(&buff);
// print block header // print block header
sbAppend(&buff, "%s (", block->name); sbAppend(&buff, "%s (", block->name);
for (unsigned int i = 0; i < block->numParams; i++) { for (unsigned int i = 0; i < block->params.count; i++) {
if (i < block->numParams - 1) { GravityBlockParam param = *get(block->params, i);
sbAppend(&buff, "%s, ", gravityTypeToCStr(block->paramTypes[i]));
if (i < block->params.count - 1) {
sbAppend(&buff, "%s %s, ", gravityTypeToCStr(param.type), gravityValueToCStr(param.value));
} else { } else {
sbAppend(&buff, "%s", gravityTypeToCStr(block->paramTypes[i])); sbAppend(&buff, "%s %s", gravityTypeToCStr(param.type), gravityValueToCStr(param.value));
} }
} }
sbAppend(&buff, "):"); sbAppend(&buff, "):");
@@ -22,3 +52,4 @@ char* gravityBlockToCStr(GravityBlock block) {
return buff.data; return buff.data;
} }

View File

@@ -2,21 +2,29 @@
#define __GRAVITY__BLOCK_H #define __GRAVITY__BLOCK_H
#include "list.h" #include "list.h"
#include "instruction.h"
#include "type.h" #include "type.h"
#include "instruction.h"
typedef struct GravityOpaqueBlock* GravityBlock; typedef struct GravityOpaqueBlock* GravityBlock;
typedef struct {
GravityValue value;
GravityType type;
} GravityBlockParam;
UseList(GravityBlockParam);
UseList(GravityInstruction); UseList(GravityInstruction);
struct GravityOpaqueBlock { struct GravityOpaqueBlock {
const char* name; const char* name;
GravityType* paramTypes; List(GravityBlockParam) params;
uint16_t numParams; List(GravityValue) values;
List(GravityInstruction) instructions; List(GravityInstruction) instructions;
}; };
char* gravityBlockToCStr(GravityBlock block); char* gravityBlockToCStr(GravityBlock block);
void gravityAppendBlockArgument(GravityBlock block, GravityType type);
GravityValue gravityGetBlockArg(GravityBlock block, unsigned int index);
GravityBlock gravityNewBlock(const char* name);
#endif #endif

View File

@@ -32,7 +32,7 @@ GravityBuilder gravityCreateBuilder(void) {
return newBuilder; return newBuilder;
} }
void gravityPositionBuilderAtEnd(GravityBuilder builder, GravityBlock block) { void gravityBuilderSwitchToBlock(GravityBuilder builder, GravityBlock block) {
builder->currentBlock = block; builder->currentBlock = block;
} }
@@ -92,3 +92,28 @@ void gravityBuildRet(GravityBuilder builder, GravityValue returnValue) {
); );
} }
} }
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
);
}

View File

@@ -1,7 +1,9 @@
#ifndef __GRAVITY__BUILDER_H #ifndef __GRAVITY__BUILDER_H
#define __GRAVITY__BUILDER_H #define __GRAVITY__BUILDER_H
#include "value.h"
#include "block.h" #include "block.h"
#include "instruction.h"
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
@@ -13,11 +15,13 @@ struct GravityOpaqueBuilder {
GravityBuilder gravityCreateBuilder(void); GravityBuilder gravityCreateBuilder(void);
void gravityPositionBuilderAtEnd(GravityBuilder builder, GravityBlock block); void gravityBuilderSwitchToBlock(GravityBuilder builder, GravityBlock block);
GravityValue gravityBuildAlloc(GravityBuilder builder, GravityType type, const char* name); GravityValue gravityBuildAlloc(GravityBuilder builder, GravityType type, const char* name);
void gravityBuildStore(GravityBuilder builder, GravityValue pointer, GravityValue value); void gravityBuildStore(GravityBuilder builder, GravityValue pointer, GravityValue value);
GravityValue gravityBuildLoad(GravityBuilder builder, GravityValue pointer, const char* name); GravityValue gravityBuildLoad(GravityBuilder builder, GravityValue pointer, const char* name);
void gravityBuildRet(GravityBuilder builder, GravityValue returnValue); 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 #endif

View File

@@ -1,28 +1,9 @@
#include "function.h" #include "function.h"
GravityBlock gravityStartBlock(const char* name, GravityFunction function, uint16_t numBlockParams, ...) { GravityBlock gravityStartBlock(const char* name, GravityFunction function) {
GravityBlock newBlock = malloc(sizeof(struct GravityOpaqueBlock)); GravityBlock newBlock = gravityNewBlock(name);
if (newBlock == NULL) return newBlock; 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); append(function->blocks, newBlock);
return newBlock; return newBlock;
@@ -37,11 +18,9 @@ char* gravityFunctionToCStr(GravityFunction function) {
for (unsigned int i = 0; i < function->functionType.numArgs; i++) { for (unsigned int i = 0; i < function->functionType.numArgs; i++) {
if (i < function->functionType.numArgs) { if (i < function->functionType.numArgs) {
sbAppend(&buff, "%s, ", gravityTypeToCStr(function->functionType.argTypes[i])); sbAppend(&buff, "%s, ", gravityTypeToCStr(function->functionType.argTypes[i]));
} else { } else {
sbAppend(&buff, "%s", gravityTypeToCStr(function->functionType.argTypes[i])); sbAppend(&buff, "%s", gravityTypeToCStr(function->functionType.argTypes[i]));
} }
break; break;
} }
@@ -49,7 +28,7 @@ char* gravityFunctionToCStr(GravityFunction function) {
sbAppend(&buff, ") %s {\n", gravityTypeToCStr(function->functionType.returnType)); sbAppend(&buff, ") %s {\n", gravityTypeToCStr(function->functionType.returnType));
for (unsigned int i = 0; i < function->blocks.count; i++) { for (unsigned int i = 0; i < function->blocks.count; i++) {
GravityBlock block = *get(function->blocks, i); GravityBlock block = *get(function->blocks, i);
sbAppend(&buff, "%s\n", gravityBlockToCStr(block)); sbAppend(&buff, "%s\n\n", gravityBlockToCStr(block));
} }
sbAppend(&buff, "}"); sbAppend(&buff, "}");

View File

@@ -5,6 +5,7 @@
#include "block.h" #include "block.h"
#include "list.h" #include "list.h"
#include "strb.h" #include "strb.h"
#include "instruction.h"
#include <stdint.h> #include <stdint.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
@@ -19,7 +20,7 @@ struct GravityOpaqueFunction {
const char* name; const char* name;
}; };
GravityBlock gravityStartBlock(const char* name, GravityFunction function, uint16_t numBlockParams, ...); GravityBlock gravityStartBlock(const char* name, GravityFunction function);
char* gravityFunctionToCStr(GravityFunction function); char* gravityFunctionToCStr(GravityFunction function);
#endif #endif

View File

@@ -6,6 +6,8 @@ char* gravityOpcodeToCStr(GravityOpcode opcode) {
case GravityOpcodeStore: return "store"; case GravityOpcodeStore: return "store";
case GravityOpcodeLoad: return "load"; case GravityOpcodeLoad: return "load";
case GravityOpcodeRet: return "ret"; case GravityOpcodeRet: return "ret";
case GravityOpcodeBranch: return "br";
case GravityOpcodeJump: return "jmp";
default: return "fixme"; default: return "fixme";
} }
} }

View File

@@ -4,19 +4,23 @@
#include "value.h" #include "value.h"
#include <stddef.h> #include <stddef.h>
typedef struct GravityInstruction GravityInstruction;
typedef enum { typedef enum {
GravityOpcodeAlloc = 0, GravityOpcodeAlloc = 0,
GravityOpcodeStore, GravityOpcodeStore,
GravityOpcodeLoad, GravityOpcodeLoad,
GravityOpcodeRet GravityOpcodeRet,
GravityOpcodeBranch,
GravityOpcodeJump
} GravityOpcode; } GravityOpcode;
typedef struct { struct GravityInstruction {
GravityOpcode opcode; GravityOpcode opcode;
GravityValue* operands; GravityValue* operands;
size_t numOperands; size_t numOperands;
GravityValue result; GravityValue result;
} GravityInstruction; };
char* gravityInstructionToCStr(GravityInstruction inst); char* gravityInstructionToCStr(GravityInstruction inst);
char* gravityOpcodeToCStr(GravityOpcode opcode); char* gravityOpcodeToCStr(GravityOpcode opcode);

View File

@@ -52,7 +52,7 @@ char* gravityTypeToCStr(GravityType type) {
} }
case GravityPointerTypeKind: { case GravityPointerTypeKind: {
sbAppend(&buff, "pointer"); sbAppend(&buff, "ptr");
break; break;
} }

View File

@@ -15,7 +15,8 @@ typedef enum {
GravityFloatTypeKind, GravityFloatTypeKind,
GravityPointerTypeKind, GravityPointerTypeKind,
GravityFunctionTypeKind, GravityFunctionTypeKind,
GravityTypeTypeKind, // type name GravityTypeTypeKind,
GravityBlockTypeKind
} GravityTypeKind; } GravityTypeKind;
typedef struct { typedef struct {

View File

@@ -1,4 +1,5 @@
#include "value.h" #include "value.h"
#include "block.h"
uint32_t globalValueIncrementer = 0; uint32_t globalValueIncrementer = 0;
@@ -6,7 +7,7 @@ char* getIncrementedName(void) {
char* buffer = malloc(32); char* buffer = malloc(32);
if (buffer == NULL) return buffer; if (buffer == NULL) return buffer;
snprintf(buffer, 32, "%%%d", globalValueIncrementer); snprintf(buffer, 32, "%d", globalValueIncrementer);
globalValueIncrementer++; globalValueIncrementer++;
@@ -43,15 +44,18 @@ GravityValue gravityTypeToTypeValue(GravityType type) {
} }
char* gravityValueToCStr(GravityValue value) { char* gravityValueToCStr(GravityValue value) {
switch (value->kind) {
case GravityLocalValueKind:
return strdup(value->name);
case GravityConstantValueKind: {
StringBuffer buff; StringBuffer buff;
initStringBuff(&buff); initStringBuff(&buff);
switch (value->kind) {
case GravityLocalValueKind: {
sbAppend(&buff, "%%%s", value->name);
break;
}
case GravityConstantValueKind: {
switch (value->type->typeKind) { switch (value->type->typeKind) {
case GravityIntTypeKind: { case GravityIntTypeKind: {
sbAppend(&buff, "%ld", value->constant.intValue); sbAppend(&buff, "%ld", value->constant.intValue);
@@ -63,16 +67,38 @@ char* gravityValueToCStr(GravityValue value) {
break; 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);
}
break;
}
default: assert(false); default: assert(false);
} }
return buff.data; return buff.data;
} }
default: assert(false);
}
}
GravityValue gravityNewConstant(GravityType type) { GravityValue gravityNewConstant(GravityType type) {
GravityValue newValue = malloc(sizeof(struct GravityOpaqueValue)); GravityValue newValue = malloc(sizeof(struct GravityOpaqueValue));
if (newValue == NULL) return newValue; if (newValue == NULL) return newValue;
@@ -94,3 +120,37 @@ GravityValue gravityNewIntConstant(GravityType intType, int64_t value) {
return newValue; 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);
}

View File

@@ -6,13 +6,18 @@
extern uint32_t globalValueIncrementer; extern uint32_t globalValueIncrementer;
typedef struct GravityOpaqueValue* GravityValue; typedef struct GravityOpaqueValue* GravityValue;
typedef struct GravityOpaqueConstant* GravityConstant; UseList(GravityValue);
typedef enum { typedef enum {
GravityLocalValueKind, GravityLocalValueKind,
GravityConstantValueKind GravityConstantValueKind
} GravityValueKind; } GravityValueKind;
typedef struct {
void* block;
GravityValue* params;
} GravityBlockReference;
struct GravityOpaqueValue { struct GravityOpaqueValue {
GravityValueKind kind; GravityValueKind kind;
GravityType type; GravityType type;
@@ -20,21 +25,18 @@ struct GravityOpaqueValue {
union { union {
int64_t intValue; int64_t intValue;
GravityBlockReference blockValue;
} constant; } constant;
}; };
struct GravityOpaqueConstant {
GravityType type;
union {
int64_t intValue;
};
};
GravityValue gravityNewValue(const char* name, GravityType type); GravityValue gravityNewValue(const char* name, GravityType type);
GravityValue gravityTypeToTypeValue(GravityType type); GravityValue gravityTypeToTypeValue(GravityType type);
char* gravityValueToCStr(GravityValue value); char* gravityValueToCStr(GravityValue value);
GravityValue gravityNewConstant(GravityType type); GravityValue gravityNewConstant(GravityType type);
GravityValue gravityNewIntConstant(GravityType intType, int64_t value); GravityValue gravityNewIntConstant(GravityType intType, int64_t value);
GravityValue gravityNewBlockReference(void* block, GravityValue* passedParams);
void gravityFreeValue(GravityValue value);
#endif #endif

37
test.c
View File

@@ -6,19 +6,42 @@ int main(void) {
GravityBuilder builder = gravityCreateBuilder(); GravityBuilder builder = gravityCreateBuilder();
GravityType charType = gravityCreateIntegerType(8, false); GravityType charType = gravityCreateIntegerType(8, false);
GravityType ptrType = gravityCreatePointerType();
GravityType mainFuncType = gravityCreateFunctionType(0, NULL, charType); GravityType mainFuncType = gravityCreateFunctionType(0, NULL, charType);
GravityFunction mainFunc = gravityNewFunction(module, "main", mainFuncType); GravityFunction mainFunc = gravityNewFunction(module, "main", mainFuncType);
GravityBlock entryBlock = gravityStartBlock("entry", mainFunc, 0); GravityBlock entryBlock = gravityStartBlock("entry", mainFunc);
gravityPositionBuilderAtEnd(builder, entryBlock); // define blocks
GravityValue someVar = gravityBuildAlloc(builder, charType, NULL); GravityBlock thenBlock = gravityStartBlock("then", mainFunc);
gravityAppendBlockArgument(thenBlock, ptrType);
GravityValue someConstant = gravityNewIntConstant(charType, 123); GravityBlock elseBlock = gravityStartBlock("else", mainFunc);
gravityBuildStore(builder, someVar, someConstant); gravityAppendBlockArgument(elseBlock, ptrType);
GravityValue output = gravityBuildLoad(builder, someVar, NULL); GravityBlock mergeBlock = gravityStartBlock("merge", mainFunc);
gravityBuildRet(builder, output);
// 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)); printf("%s\n", gravityFunctionToCStr(mainFunc));