block parameters working i think
This commit is contained in:
@@ -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);
|
||||
|
||||
// ============================ //
|
||||
|
||||
|
||||
39
src/block.c
39
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, "):");
|
||||
@@ -22,3 +52,4 @@ char* gravityBlockToCStr(GravityBlock block) {
|
||||
|
||||
return buff.data;
|
||||
}
|
||||
|
||||
|
||||
16
src/block.h
16
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
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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, "}");
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -52,7 +52,7 @@ char* gravityTypeToCStr(GravityType type) {
|
||||
}
|
||||
|
||||
case GravityPointerTypeKind: {
|
||||
sbAppend(&buff, "pointer");
|
||||
sbAppend(&buff, "ptr");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ typedef enum {
|
||||
GravityFloatTypeKind,
|
||||
GravityPointerTypeKind,
|
||||
GravityFunctionTypeKind,
|
||||
GravityTypeTypeKind, // type name
|
||||
GravityTypeTypeKind,
|
||||
GravityBlockTypeKind
|
||||
} GravityTypeKind;
|
||||
|
||||
typedef struct {
|
||||
|
||||
76
src/value.c
76
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) {
|
||||
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);
|
||||
}
|
||||
18
src/value.h
18
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
|
||||
37
test.c
37
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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user