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);
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);
// ============================ //

View File

@@ -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, "):");
@@ -22,3 +52,4 @@ char* gravityBlockToCStr(GravityBlock block) {
return buff.data;
}

View File

@@ -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

View File

@@ -32,7 +32,7 @@ GravityBuilder gravityCreateBuilder(void) {
return newBuilder;
}
void gravityPositionBuilderAtEnd(GravityBuilder builder, GravityBlock block) {
void gravityBuilderSwitchToBlock(GravityBuilder builder, GravityBlock 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
#define __GRAVITY__BUILDER_H
#include "value.h"
#include "block.h"
#include "instruction.h"
#include <stdlib.h>
#include <assert.h>
@@ -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

View File

@@ -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, "}");

View File

@@ -5,6 +5,7 @@
#include "block.h"
#include "list.h"
#include "strb.h"
#include "instruction.h"
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
@@ -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

View File

@@ -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";
}
}

View File

@@ -4,19 +4,23 @@
#include "value.h"
#include <stddef.h>
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);

View File

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

View File

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

View File

@@ -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) {
switch (value->kind) {
case GravityLocalValueKind:
StringBuffer buff;
initStringBuff(&buff);
return strdup(value->name);
switch (value->kind) {
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) {
@@ -94,3 +120,37 @@ GravityValue gravityNewIntConstant(GravityType intType, int64_t 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);
}

View File

@@ -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

37
test.c
View File

@@ -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));