diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..8e70209 --- /dev/null +++ b/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + Add: [-Wall, -Wextra, -pedantic, -O3] \ No newline at end of file diff --git a/Makefile b/Makefile index 7c3c257..ee939bf 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ SRC=src OBJ=obj CC=gcc -CFLAGS=-Wall -Wextra -pedantic -std=c99 -pedantic-errors +CFLAGS=-Wall -Wextra -O3 TARGET=libgravity.so TEST_TARGET=testapp @@ -17,7 +17,7 @@ $(OBJ)/%.o: $(SRC)/%.c $(CC) $(CFLAGS) -c $< -o $@ $(TEST_TARGET): test.c $(TARGET) - $(CC) test.c -lgravity -L. -o $(TEST_TARGET) + $(CC) $(CFLAGS) test.c -lgravity -L. -o $(TEST_TARGET) test: $(TEST_TARGET) diff --git a/include/gravity/core.h b/include/gravity/core.h index 7c2455f..7f47cd3 100644 --- a/include/gravity/core.h +++ b/include/gravity/core.h @@ -1,12 +1,35 @@ -#ifndef __GRAVITY_CORE_H -#define __GRAVITY_CORE_H +#ifndef __GRAVITY__CORE_H +#define __GRAVITY__CORE_H -// === STRUCT DEFINITIONS === // +#include +#include + +// === TYPE DEFINITIONS === // typedef struct GravityOpaqueModule* GravityModule; + +typedef struct GravityOpaqueValue* GravityValue; + +typedef struct GravityOpaqueBuilder* GravityBuilder; + +typedef struct GravityOpaqueFunction* GravityFunction; + +typedef struct GravityOpaqueType* GravityType; +typedef enum { + GravityIntTypeKind = 0, + GravityFloatTypeKind, + GravityPointerTypeKind, + GravityFunctionTypeKind, +} GravityTypeKind; // ========================== // // === FUNCTION DEFINITIONS === // -GravityModule gravityCreateModule(); +GravityModule gravityCreateModule(void); +GravityBuilder gravityCreateBuilder(void); + +GravityFunction gravityNewFunction(GravityModule module, const char* name, GravityType functionType); + +GravityType gravityCreateFunctionType(int numArgs, GravityType* argTypes, GravityType returnType); +GravityType gravityCreateIntegerType(uint8_t width, bool isSigned); // ============================ // #endif \ No newline at end of file diff --git a/src/block.h b/src/block.h new file mode 100644 index 0000000..05d3c71 --- /dev/null +++ b/src/block.h @@ -0,0 +1,13 @@ +#ifndef __GRAVITY__BLOCK_H +#define __GRAVITY__BLOCK_H + +#include "list.h" +#include "instruction.h" + +UseList(GravityInstruction); + +typedef struct { + List(GravityInstruction) instructions; +} GravityBlock; + +#endif \ No newline at end of file diff --git a/src/builder.c b/src/builder.c new file mode 100644 index 0000000..d5ac4a3 --- /dev/null +++ b/src/builder.c @@ -0,0 +1,8 @@ +#include "builder.h" + +GravityBuilder* gravityCreateBuilder(void) { + GravityBuilder* newBuilder = malloc(sizeof(GravityBuilder)); + if (newBuilder == NULL) return newBuilder; + + return newBuilder; +} \ No newline at end of file diff --git a/src/builder.h b/src/builder.h new file mode 100644 index 0000000..de414c5 --- /dev/null +++ b/src/builder.h @@ -0,0 +1,15 @@ +#ifndef __GRAVITY__BUILDER_H +#define __GRAVITY__BUILDER_H + +#include "block.h" +#include + +typedef struct GravityOpaqueBuilder* GravityBuilder; + +struct { + GravityBlock currentBlock; +} GravityOpaqueBuilder; + +GravityBuilder gravityCreateBuilder(void); + +#endif \ No newline at end of file diff --git a/src/function.h b/src/function.h index 8c4cd8b..7efa1ac 100644 --- a/src/function.h +++ b/src/function.h @@ -1,8 +1,18 @@ -#ifndef __GRAVITY_FUNCTION_H -#define __GRAVITY_FUNCTION_H +#ifndef __GRAVITY__FUNCTION_H +#define __GRAVITY__FUNCTION_H -typedef struct { +#include "type.h" +#include "block.h" +#include "list.h" +#include -} GravityIRFunction; +UseList(GravityBlock); + +typedef struct GravityOpaqueFunction* GravityFunction; + +struct GravityOpaqueFunction { + GravityFunctionType functionType; + List(GravityBlock) blocks; +}; #endif \ No newline at end of file diff --git a/src/instruction.h b/src/instruction.h new file mode 100644 index 0000000..9425f17 --- /dev/null +++ b/src/instruction.h @@ -0,0 +1,17 @@ +#ifndef __GRAVITY__INSTRUCTION_H +#define __GRAVITY__INSTRUCTION_H + +#include "value.h" +#include + +typedef enum { + GravityOpcodeAdd = 0 +} GravityOpcode; + +typedef struct { + GravityOpcode opcode; + GravityValue* operands; + size_t numOperands; +} GravityInstruction; + +#endif \ No newline at end of file diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..e97f666 --- /dev/null +++ b/src/list.h @@ -0,0 +1,71 @@ +// list.h - create a list of any kind in C +// append, pop, safely retrieve +// licenced to you under the MIT license +// example: +// +// #include "list.h" +// +// UseList(int); +// +// int main() { +// List(int) myList = newList(int); +// append(myList, 32); +// printf("%d\n", *get(myList, 0)); +// pop(myList); +// destroy(myList); +// } +// +#ifndef LIST_H +#define LIST_H + +#include +#include + +#define LIST_H_INIT_CAPACITY 32 + +#define UseList(type) struct __List_##type { type* pointer; size_t count; size_t capacity; size_t itemsize; } +#define List(type) struct __List_##type + +#define newList(type) ({ \ + List(type) __list_tmp = { .pointer = malloc(sizeof(type) * LIST_H_INIT_CAPACITY), .count = 0, .capacity = LIST_H_INIT_CAPACITY, .itemsize = sizeof(type) };\ + if (__list_tmp.pointer == NULL) { \ + printf("list.h:32 (newList(type)) - failed to allocate memory"); exit(1);\ + }\ + __list_tmp;\ +}) + +#define append(list, item) {\ + if (list.pointer == NULL) {\ + printf("list.h:39 (append(list, item)) - list pointer is null (perhaps you accidently destroyed the list?)"); exit(1);\ + }\ + if (list.capacity < list.count + 1) {\ + list.capacity *= 2;\ + void* __tmp_ptr = realloc(list.pointer, list.capacity * list.itemsize);\ + if (__tmp_ptr == NULL) {\ + printf("list.h:45 (append(list, item)) - failed to allocate memory"); exit(1);\ + }\ + list.pointer = __tmp_ptr;\ + }\ + list.pointer[list.count] = item;\ + list.count++;\ +} + +#define get(list, idx) ({\ + if (list.pointer == NULL) {\ + printf("list.h:55 (get(list, idx)) - list pointer is null (perhaps you accidently destroyed the list?)"); exit(1);\ + }\ + (idx >= list.count) ? NULL : &list.pointer[idx];\ +}) + +#define pop(list) {\ + if (list.pointer == NULL) {\ + printf("list.h:65 (pop(list)) - list pointer is null (perhaps you accidently destroyed the list?)"); exit(1);\ + }\ + if (list.count > 0) list.count--;\ +} + +#define destroy(list) if (list.pointer != NULL) {\ + free(list.pointer); list.pointer = NULL; \ +} + +#endif \ No newline at end of file diff --git a/src/module.c b/src/module.c index 3d2cee9..5bb0629 100644 --- a/src/module.c +++ b/src/module.c @@ -1,10 +1,24 @@ #include "module.h" -GravityOpaqueModule* gravityCreateModule() { - GravityOpaqueModule* newModule = malloc(sizeof(GravityOpaqueModule)); +GravityModule gravityCreateModule(void) { + GravityModule newModule = malloc(sizeof(struct GravityOpaqueModule)); if (newModule == NULL) return NULL; - + newModule->functions = newList(GravityFunction); return newModule; +} + +GravityFunction gravityNewFunction(GravityModule module, const char* name, GravityType functionType) { + assert(functionType->typeKind != GravityFunctionTypeKind); + + GravityFunction newFunc = malloc(sizeof(struct GravityOpaqueFunction)); + if (newFunc == NULL) return newFunc; + + newFunc->blocks = newList(GravityBlock); + newFunc->functionType = functionType->function; + + append(module->functions, newFunc); + + return newFunc; } \ No newline at end of file diff --git a/src/module.h b/src/module.h index 363d371..25a6b68 100644 --- a/src/module.h +++ b/src/module.h @@ -1,12 +1,20 @@ -#ifndef __GRAVITY_MODULE_H -#define __GRAVITY_MODULE_H +#ifndef __GRAVITY__MODULE_H +#define __GRAVITY__MODULE_H +#include "function.h" +#include "list.h" #include -typedef struct { - int hi; -} GravityOpaqueModule; +typedef struct GravityOpaqueModule* GravityModule; -GravityOpaqueModule* gravityCreateModule(); +UseList(GravityFunction); + +struct GravityOpaqueModule { + List(GravityFunction) functions; +}; + +GravityModule gravityCreateModule(void); + +GravityFunction gravityNewFunction(GravityModule module, const char* name, GravityType functionType); #endif \ No newline at end of file diff --git a/src/type.c b/src/type.c new file mode 100644 index 0000000..6649eec --- /dev/null +++ b/src/type.c @@ -0,0 +1,27 @@ +#include "type.h" + +GravityType gravityCreateType(void) { + GravityType type = malloc(sizeof(struct GravityOpaqueType)); + return type; +} + +GravityType gravityCreateFunctionType(int numArgs, GravityType* argTypes, GravityType returnType) { + GravityType type = gravityCreateType(); + if (type == NULL) return type; + + type->function.numArgs = numArgs; + type->function.argTypes = argTypes; + type->function.returnType = returnType; + + return type; +} + +GravityType gravityCreateIntegerType(uint8_t width, bool isSigned) { + GravityType type = gravityCreateType(); + if (type == NULL) return type; + + type->integer.width = width; + type->integer.isSigned = isSigned; + + return type; +} \ No newline at end of file diff --git a/src/type.h b/src/type.h new file mode 100644 index 0000000..c8325e5 --- /dev/null +++ b/src/type.h @@ -0,0 +1,41 @@ +#ifndef __GRAVITY__TYPE_H +#define __GRAVITY__TYPE_H + +#include "list.h" +#include +#include +#include + +typedef struct GravityOpaqueType* GravityType; + +typedef enum { + GravityIntTypeKind = 0, + GravityFloatTypeKind, + GravityPointerTypeKind, + GravityFunctionTypeKind, +} GravityTypeKind; + +typedef struct { + GravityType* argTypes; + size_t numArgs; + GravityType returnType; +} GravityFunctionType; + +typedef struct { + uint8_t width; + bool isSigned; +} GravityIntType; + +struct GravityOpaqueType { + GravityTypeKind typeKind; + union { + GravityFunctionType function; + GravityIntType integer; + }; +}; + +GravityType gravityCreateFunctionType(int numArgs, GravityType* argTypes, GravityType returnType); +GravityType gravityCreateIntegerType(uint8_t width, bool isSigned); +GravityType gravityCreateType(void); + +#endif \ No newline at end of file diff --git a/src/value.h b/src/value.h new file mode 100644 index 0000000..0c66768 --- /dev/null +++ b/src/value.h @@ -0,0 +1,11 @@ +#ifndef __GRAVITY__VALUE_H +#define __GRAVITY__VALUE_H + +#include "type.h" + +typedef struct { + GravityType type; + const char* name; +} GravityValue; + +#endif \ No newline at end of file diff --git a/test.c b/test.c index 5df481d..5891221 100644 --- a/test.c +++ b/test.c @@ -1,9 +1,14 @@ #include "include/gravity/core.h" #include -int main() { +int main(void) { GravityModule module = gravityCreateModule(); - printf("module: %p\n", module); + GravityBuilder builder = gravityCreateBuilder(); + + GravityType charType = gravityCreateIntegerType(1, false); + + GravityType mainFuncType = gravityCreateFunctionType(0, NULL, charType); + GravityFunction mainFunc = gravityNewFunction(module, "main", mainFuncType); return 0; } \ No newline at end of file