From 9b332137958b633b2c0a22f1afc12be039334a94 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 10 Jan 2025 16:41:31 +0100 Subject: [PATCH 01/26] feat: added bytecode buffer struct & win64 header --- src/compiler/compiler.h | 11 +++++++++++ src/compiler/win64.h | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/compiler/win64.h diff --git a/src/compiler/compiler.h b/src/compiler/compiler.h index c0e36ea..746f65c 100644 --- a/src/compiler/compiler.h +++ b/src/compiler/compiler.h @@ -5,6 +5,17 @@ #ifndef COMPILER_H #define COMPILER_H +/** + * A bytecode buffer, is used to transmit byte codes around. + */ +typedef struct BYTECODE_BUFFER { + + uint8_t* buff; + int size; + int allocSize; + +} BYTECODE_BUFFER; + /** * Compiles the Context tree to an executable named the provided name. * @param ctx the IR context. diff --git a/src/compiler/win64.h b/src/compiler/win64.h new file mode 100644 index 0000000..80e0a21 --- /dev/null +++ b/src/compiler/win64.h @@ -0,0 +1,20 @@ +/** + * The Win-x64 support for the Quickfall compiler. + */ + +#include "../ir/structs.h" +#include "../ir/instructions.h" + +#include "./compiler.h" + +#ifndef COMPILER_WIN_64_H +#define COMPILER_WIN_64_H + +/** + * Compiles an QAsm / IR instruction to the Win-x64 bytecode. + * @param buff the bytecode buffer. + * @param instruction the instruction to convert. + */ +void compileInstruction(BYTECODE_BUFFER* buff, IR_INSTRUCTION* instruction); + +#endif \ No newline at end of file From ed5432bdf03719c36de245bb4733c5d8480852a3 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 10 Jan 2025 17:05:19 +0100 Subject: [PATCH 02/26] feat: added new stack instructions --- src/ir/instructions.h | 13 ++++++++++++- src/qasm/writer/writer.c | 3 +-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ir/instructions.h b/src/ir/instructions.h index 0286b9d..3f0fbf9 100644 --- a/src/ir/instructions.h +++ b/src/ir/instructions.h @@ -131,7 +131,18 @@ typedef enum IR_INSTRUCTION_CODE { /** * Returns from a function. */ - RET + RET, + + /** + * Saves the stack. + */ + STACK_SAVE, + + + /** + * Loads the stack back. + */ + STACK_LOAD } IR_INSTRUCTION_CODE; diff --git a/src/qasm/writer/writer.c b/src/qasm/writer/writer.c index 29fd6bd..d8f5c97 100644 --- a/src/qasm/writer/writer.c +++ b/src/qasm/writer/writer.c @@ -9,7 +9,7 @@ #include "../../ir/instructions.h" #include "../../ir/structs.h" -const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_set", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret"}; +const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_set", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load"}; /** * Writes some standart QuickAssembly code equivalent to the parsed IR. @@ -62,7 +62,6 @@ void writeQASM(FILE* fptr, IR_OUTPUT* output) { case RET_PUSH: writeVarName(fptr, instruction->params, 0); break; - } } From 45f175a4db4d77f370cd99071a89b52c959ae6bb Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 10 Jan 2025 17:09:12 +0100 Subject: [PATCH 03/26] feat: started working on qasm -> win64 --- src/compiler/compiler.h | 11 ---------- src/compiler/structs.h | 35 +++++++++++++++++++++++++++++++ src/compiler/win64.c | 46 +++++++++++++++++++++++++++++++++++++++++ src/compiler/win64.h | 7 +++++-- 4 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 src/compiler/structs.h create mode 100644 src/compiler/win64.c diff --git a/src/compiler/compiler.h b/src/compiler/compiler.h index 746f65c..c0e36ea 100644 --- a/src/compiler/compiler.h +++ b/src/compiler/compiler.h @@ -5,17 +5,6 @@ #ifndef COMPILER_H #define COMPILER_H -/** - * A bytecode buffer, is used to transmit byte codes around. - */ -typedef struct BYTECODE_BUFFER { - - uint8_t* buff; - int size; - int allocSize; - -} BYTECODE_BUFFER; - /** * Compiles the Context tree to an executable named the provided name. * @param ctx the IR context. diff --git a/src/compiler/structs.h b/src/compiler/structs.h new file mode 100644 index 0000000..945985e --- /dev/null +++ b/src/compiler/structs.h @@ -0,0 +1,35 @@ +/** + * Structures used by the Quickfall compiler. + */ + +#include "../utils/hashmap.h" + +#include + +#ifndef COMPILER_STRUCTS_H +#define COMPILER_STRUCTS_H + +/** + * A bytecode buffer, is used to transmit byte codes around. + */ +typedef struct BYTECODE_BUFFER { + + uint8_t* buff; + int size; + int allocSize; + +} BYTECODE_BUFFER; + +/** + * A structure holding all of the necessary information during the compiling process. + * For example, value pointers + */ +typedef struct COMPILER_CONTEXT { + + struct Hashmap map; + int stackSize; + +} COMPILER_CONTEXT; + + +#endif \ No newline at end of file diff --git a/src/compiler/win64.c b/src/compiler/win64.c new file mode 100644 index 0000000..b17624c --- /dev/null +++ b/src/compiler/win64.c @@ -0,0 +1,46 @@ +/** + * The Win-x64 support for the Quickfall compiler. + */ + +#include "../ir/structs.h" +#include "../ir/instructions.h" + +#include "./structs.h" + +/** + * Compiles an QAsm / IR instruction to the Win-x64 bytecode. + * @param buff the bytecode buffer. + * @param ctx the compiler context. + * @param instruction the instruction to convert. + */ +void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUCTION* instruction) { + switch(instruction->opCode) { + case RET: + buff->buff[buff->size] = 0xC3; + buff->size++; + break; + + case STACK_SAVE: + buff->buff[buff->size] = 0x55; + + buff->buff[buff->size++] = 0x48; + buff->buff[buff->size++] = 0x89; + buff->buff[buff->size++] = 0xE5; + break; + + case STACK_LOAD: + buff->buff[buff->size] = 0x5D; + break; + + case S_ALLOC: + buff->buff[buff->size] = 0x48; + buff->buff[buff->size++] = 0x83; + buff->buff[buff->size++] = 0xEC; + + int i = (((unsigned char*)instruction->params[0])[0] << 24) | (((unsigned char*)instruction->params[0])[1] << 16) | (((unsigned char*)instruction->params[0])[2] << 8) | ((unsigned char*)instruction->params[0])[3]; + + buff->buff[buff->size++] = i; + break; + + } +} \ No newline at end of file diff --git a/src/compiler/win64.h b/src/compiler/win64.h index 80e0a21..9cf00a4 100644 --- a/src/compiler/win64.h +++ b/src/compiler/win64.h @@ -2,10 +2,12 @@ * The Win-x64 support for the Quickfall compiler. */ +#include + #include "../ir/structs.h" #include "../ir/instructions.h" -#include "./compiler.h" +#include "./structs.h" #ifndef COMPILER_WIN_64_H #define COMPILER_WIN_64_H @@ -13,8 +15,9 @@ /** * Compiles an QAsm / IR instruction to the Win-x64 bytecode. * @param buff the bytecode buffer. + * @param ctx the compiler context. * @param instruction the instruction to convert. */ -void compileInstruction(BYTECODE_BUFFER* buff, IR_INSTRUCTION* instruction); +void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUCTION* instruction); #endif \ No newline at end of file From 0a6f95296e411281ee9c9e8bd247b6a694d446ca Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 10 Jan 2025 17:20:59 +0100 Subject: [PATCH 04/26] feat: finished adding basic win64 bytecodes --- src/compiler/structs.h | 4 ++-- src/compiler/win64.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/compiler/structs.h b/src/compiler/structs.h index 945985e..6fa05b7 100644 --- a/src/compiler/structs.h +++ b/src/compiler/structs.h @@ -26,9 +26,9 @@ typedef struct BYTECODE_BUFFER { */ typedef struct COMPILER_CONTEXT { - struct Hashmap map; + struct Hashmap* map; int stackSize; - + } COMPILER_CONTEXT; diff --git a/src/compiler/win64.c b/src/compiler/win64.c index b17624c..b20cc40 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -7,6 +7,9 @@ #include "./structs.h" +#include "../utils/hashmap.h" +#include "../utils/hash.h" + /** * Compiles an QAsm / IR instruction to the Win-x64 bytecode. * @param buff the bytecode buffer. @@ -39,8 +42,24 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC int i = (((unsigned char*)instruction->params[0])[0] << 24) | (((unsigned char*)instruction->params[0])[1] << 16) | (((unsigned char*)instruction->params[0])[2] << 8) | ((unsigned char*)instruction->params[0])[3]; + ctx->stackSize += i; + hashPut(ctx->map, hashstr(instruction->params[1]), ctx->stackSize); + buff->buff[buff->size++] = i; break; + case PTR_SET: //dword + buff->buff[buff->size] = 0xC7; + buff->buff[buff->size++] = 0x45; + + buff->buff[buff->size++] = (uint8_t) hashGet(ctx->map, hashstr(instruction->params[1])); + + buff->buff[buff->size++] = ((unsigned char*)instruction->params[0])[0]; + buff->buff[buff->size++] = ((unsigned char*)instruction->params[0])[1]; + buff->buff[buff->size++] = ((unsigned char*)instruction->params[0])[2]; + buff->buff[buff->size++] = ((unsigned char*)instruction->params[0])[3]; + break; + + } } \ No newline at end of file From e333eb869109ba94b3b7e249607447e5ce8daa4f Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 10 Jan 2025 18:10:44 +0100 Subject: [PATCH 05/26] feat: added support for basic instructions --- src/cli/main.c | 14 +++++++++-- src/compiler/compiler.c | 32 +++++++++++++++++++++---- src/compiler/compiler.h | 11 +++++---- src/compiler/pe/pe.c | 7 +++--- src/compiler/pe/pe.h | 4 +++- src/compiler/structs.h | 1 + src/compiler/win64.c | 52 ++++++++++++++++++++++++++++++---------- src/ir/instructions.h | 7 +++++- src/ir/irs/functions.c | 5 ++++ src/ir/irs/variables.c | 2 ++ src/qasm/writer/writer.c | 2 +- src/utils/hash.c | 6 +++++ 12 files changed, 113 insertions(+), 30 deletions(-) diff --git a/src/cli/main.c b/src/cli/main.c index 301e54c..4a22ecf 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -24,6 +24,8 @@ #include "../qasm/writer/writer.h" +#include "../compiler/structs.h" + #include "../utils/logging.c" // Version @@ -128,8 +130,16 @@ int main(int argc, char* argv[]) { fptr = fopen(outputFile, "w"); - writeQASM(fptr, irOut); // experimental: ir -> QASM - + BYTECODE_BUFFER* buffer = compile(irOut); + + for(int i = 0; i < buffer->size; ++i) { + printf("0x%x ", buffer->buff[i]); + } + + compilePE(fptr, buffer); + + fclose(fptr); + break; case 'v': if(strlen(argv[1]) > 1 && strcmp(argv[1], "version") != 0) { diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 0ffd2b5..42bc67b 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -6,14 +6,36 @@ #include #include +#include "../ir/ir.h" +#include "../ir/instructions.h" + #include "./compiler.h" +#include "./win64.h" + #include "./pe/pe.h" /** - * Compiles the Context tree to an executable named the provided file name. - * @param ctx the IR context. - * @param out the output file. + * Compiles the IR into actual bytecode. + * @param out the IR output. */ -void compile(FILE* out) { -} +BYTECODE_BUFFER* compile(IR_OUTPUT* out) { + BYTECODE_BUFFER* buff = malloc(sizeof(BYTECODE_BUFFER)); + + buff->allocSize = 1024; + buff->size = 0; + buff->buff = malloc(sizeof(uint8_t) * 1024); + + COMPILER_CONTEXT* ctx = malloc(sizeof(COMPILER_CONTEXT)); + ctx->stackSize = 0; + ctx->currStack = 0; + ctx->map = createHashmap(200,512); + + // todo: add multi block handling. + + for(int i = 0; i < out->blocks[0]->instructionCount; ++i) { + compileInstruction(buff, ctx, out->blocks[0]->instructions[i]); + } + + return buff; +} \ No newline at end of file diff --git a/src/compiler/compiler.h b/src/compiler/compiler.h index c0e36ea..526ccb6 100644 --- a/src/compiler/compiler.h +++ b/src/compiler/compiler.h @@ -2,14 +2,17 @@ * The compiler of Quickfall. */ +#include "../ir/structs.h" + +#include "./structs.h" + #ifndef COMPILER_H #define COMPILER_H /** - * Compiles the Context tree to an executable named the provided name. - * @param ctx the IR context. - * @param char the output file. + * Compiles the IR into actual bytecode. + * @param out the IR output. */ -void compile(FILE* outputFileName); +BYTECODE_BUFFER* compile(IR_OUTPUT* out); #endif diff --git a/src/compiler/pe/pe.c b/src/compiler/pe/pe.c index a9f3b33..8a80bcf 100644 --- a/src/compiler/pe/pe.c +++ b/src/compiler/pe/pe.c @@ -7,11 +7,12 @@ #include #include "./format.h" +#include "../structs.h" /** * Compiles into PE format. */ -void compilePE(FILE* fptr, uint8_t program[], int programSize) { +void compilePE(FILE* fptr, BYTECODE_BUFFER* buff) { PE_DOS_HEADER dos_header = {0}; dos_header.e_magic = 0x5A4D; // "MZ" dos_header.e_lfanew = sizeof(PE_DOS_HEADER); @@ -55,7 +56,7 @@ void compilePE(FILE* fptr, uint8_t program[], int programSize) { memcpy(section_header.Name, ".text", 5); section_header.Misc.VirtualSize = 0x1000; section_header.VirtualAddress = 0x1000; - section_header.SizeOfRawData = programSize; + section_header.SizeOfRawData = buff->size; section_header.PointerToRawData = 0x200; section_header.Characteristics = 0x60000020; // Code | Execute | Read @@ -65,7 +66,7 @@ void compilePE(FILE* fptr, uint8_t program[], int programSize) { uint8_t padding[256] = {0}; fwrite(padding, 1, 0x200 - (sizeof(PE_DOS_HEADER) + sizeof(PE_NT_HEADERS) + sizeof(PE_OPTIONAL_HEADER) + sizeof(PE_SECTION_HEADER)), fptr); - fwrite(program, 1, programSize, fptr); + fwrite(buff->buff, 1, buff->size, fptr); fclose(fptr); } diff --git a/src/compiler/pe/pe.h b/src/compiler/pe/pe.h index a94aa18..a1e2cc3 100644 --- a/src/compiler/pe/pe.h +++ b/src/compiler/pe/pe.h @@ -5,12 +5,14 @@ #include #include +#include "../structs.h" + #ifndef COMPILER_PE #define COMPILER_PE /** * Compiles into PE format. */ -void compilePE(FILE* fptr, uint8_t program[], int programSize); +void compilePE(FILE* fptr, BYTECODE_BUFFER* buff); #endif diff --git a/src/compiler/structs.h b/src/compiler/structs.h index 6fa05b7..93039ed 100644 --- a/src/compiler/structs.h +++ b/src/compiler/structs.h @@ -28,6 +28,7 @@ typedef struct COMPILER_CONTEXT { struct Hashmap* map; int stackSize; + int currStack; } COMPILER_CONTEXT; diff --git a/src/compiler/win64.c b/src/compiler/win64.c index b20cc40..232e269 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -2,6 +2,9 @@ * The Win-x64 support for the Quickfall compiler. */ +#include +#include + #include "../ir/structs.h" #include "../ir/instructions.h" @@ -26,40 +29,63 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC case STACK_SAVE: buff->buff[buff->size] = 0x55; - buff->buff[buff->size++] = 0x48; - buff->buff[buff->size++] = 0x89; - buff->buff[buff->size++] = 0xE5; + buff->buff[buff->size + 1] = 0x48; + buff->buff[buff->size + 2] = 0x89; + buff->buff[buff->size + 3] = 0xE5; + + buff->size += 4; break; case STACK_LOAD: buff->buff[buff->size] = 0x5D; + buff->size++; break; case S_ALLOC: buff->buff[buff->size] = 0x48; - buff->buff[buff->size++] = 0x83; - buff->buff[buff->size++] = 0xEC; + buff->buff[buff->size + 1] = 0x83; + buff->buff[buff->size + 2] = 0xEC; int i = (((unsigned char*)instruction->params[0])[0] << 24) | (((unsigned char*)instruction->params[0])[1] << 16) | (((unsigned char*)instruction->params[0])[2] << 8) | ((unsigned char*)instruction->params[0])[3]; + ctx->currStack += i; ctx->stackSize += i; - hashPut(ctx->map, hashstr(instruction->params[1]), ctx->stackSize); - buff->buff[buff->size++] = i; + int* ptr = malloc(sizeof(int)); + *ptr = ctx->stackSize; + + hashPut(ctx->map, hashstr(instruction->params[1]), ptr); + + buff->buff[buff->size + 3] = i; + + buff->size += 4; break; case PTR_SET: //dword buff->buff[buff->size] = 0xC7; - buff->buff[buff->size++] = 0x45; + buff->buff[buff->size + 1] = 0x45; + + int* ii = hashGet(ctx->map, hashstr(instruction->params[0])); - buff->buff[buff->size++] = (uint8_t) hashGet(ctx->map, hashstr(instruction->params[1])); + buff->buff[buff->size + 2] = (uint8_t) *ii; - buff->buff[buff->size++] = ((unsigned char*)instruction->params[0])[0]; - buff->buff[buff->size++] = ((unsigned char*)instruction->params[0])[1]; - buff->buff[buff->size++] = ((unsigned char*)instruction->params[0])[2]; - buff->buff[buff->size++] = ((unsigned char*)instruction->params[0])[3]; + buff->buff[buff->size + 3] = ((unsigned char*)instruction->params[1])[3]; + buff->buff[buff->size + 4] = ((unsigned char*)instruction->params[1])[2]; + buff->buff[buff->size + 5] = ((unsigned char*)instruction->params[1])[1]; + buff->buff[buff->size + 6] = ((unsigned char*)instruction->params[1])[0]; + + buff->size += 7; break; + case STACK_FREE_FUNC: + buff->buff[buff->size] = 0x48; + buff->buff[buff->size + 1] = 0x83; + buff->buff[buff->size + 2] = 0xC4; + buff->buff[buff->size + 3] = (uint8_t) ctx->currStack; + + buff->size += 4; + break; + } } \ No newline at end of file diff --git a/src/ir/instructions.h b/src/ir/instructions.h index 3f0fbf9..c6a7ec3 100644 --- a/src/ir/instructions.h +++ b/src/ir/instructions.h @@ -142,7 +142,12 @@ typedef enum IR_INSTRUCTION_CODE { /** * Loads the stack back. */ - STACK_LOAD + STACK_LOAD, + + /** + * Frees all of the stack used by the function. + */ + STACK_FREE_FUNC } IR_INSTRUCTION_CODE; diff --git a/src/ir/irs/functions.c b/src/ir/irs/functions.c index 1a98b3b..c38c5e7 100644 --- a/src/ir/irs/functions.c +++ b/src/ir/irs/functions.c @@ -62,6 +62,11 @@ void parseFunction(IR_OUTPUT* out, AST_FUNCTION_DEC* node) { break; } } + + appendInstruction(out->blocks[out->blockCount], STACK_FREE_FUNC, NULL, 0); + appendInstruction(out->blocks[out->blockCount], STACK_LOAD, NULL, 0); + + appendInstruction(out->blocks[out->blockCount], RET, NULL, 0); } /** diff --git a/src/ir/irs/variables.c b/src/ir/irs/variables.c index c35e6d5..ccd6c18 100644 --- a/src/ir/irs/variables.c +++ b/src/ir/irs/variables.c @@ -53,6 +53,8 @@ void parseVariableDeclaration(IR_BASIC_BLOCK* block, AST_VARIABLE_DEC* node) { params[1] = node->name; + appendInstruction(block, STACK_SAVE, NULL, 0); + appendInstruction(block, S_ALLOC, params, 2); if(node->value != NULL) { diff --git a/src/qasm/writer/writer.c b/src/qasm/writer/writer.c index d8f5c97..5bf1bc4 100644 --- a/src/qasm/writer/writer.c +++ b/src/qasm/writer/writer.c @@ -9,7 +9,7 @@ #include "../../ir/instructions.h" #include "../../ir/structs.h" -const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_set", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load"}; +const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_set", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load", "st_freef"}; /** * Writes some standart QuickAssembly code equivalent to the parsed IR. diff --git a/src/utils/hash.c b/src/utils/hash.c index 6f5e5d9..3fa2d8d 100644 --- a/src/utils/hash.c +++ b/src/utils/hash.c @@ -8,10 +8,16 @@ unsigned int hashstr(char* str) { unsigned int result = 0; unsigned char* p = (unsigned char*) str; + printf("str: %s -> ", str); + while(*p != '\0') { + printf("0x%x ", *p); + result = ((*p - 97) << 5) + result + 1; ++p; } + printf("\n"); + return result; } From a60c07a8530158e66ad1a9ab07561f6aa889b6e4 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 10 Jan 2025 18:17:51 +0100 Subject: [PATCH 06/26] feat: added qd_set qasm instruction and changed ptr_set to singleton byte --- src/compiler/win64.c | 15 ++++++++++++++- src/ir/instructions.h | 26 ++++++++++++++++++-------- src/qasm/writer/writer.c | 2 +- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/compiler/win64.c b/src/compiler/win64.c index 232e269..f186381 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -61,7 +61,20 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC buff->size += 4; break; - case PTR_SET: //dword + case PTR_SET: + buff->buff[buff->size] = 0xC6; + buff->buff[buff->size + 1] = 0x45; + + int* ii = hashGet(ctx->map, hashstr(instruction->params[0])); + + buff->buff[buff->size + 2] = (uint8_t) *ii; + + buff->buff[buff->size + 3] = ((unsigned char*)instruction->params[1])[3]; + + buff->size += 4; + break; + + case QUAD_SET: //dword buff->buff[buff->size] = 0xC7; buff->buff[buff->size + 1] = 0x45; diff --git a/src/ir/instructions.h b/src/ir/instructions.h index c6a7ec3..e276f10 100644 --- a/src/ir/instructions.h +++ b/src/ir/instructions.h @@ -38,13 +38,6 @@ typedef enum IR_INSTRUCTION_CODE { */ S_ALLOC, - /** - * Sets the value of the pointer's address to the provided element. - * @param val the new value (an integer for now). - * @param ptr the pointer containing the target address. - */ - PTR_SET, - /** * Loads the values of a specific address into a variable. * @param var the output variable. @@ -147,7 +140,24 @@ typedef enum IR_INSTRUCTION_CODE { /** * Frees all of the stack used by the function. */ - STACK_FREE_FUNC + STACK_FREE_FUNC, + + + /** + * Sets the byte located at the pointer. + * @param ptr the pointer containing the target address. + * @param val the new value (an integer for now). + */ + PTR_SET, + + /** + * Sets 32 bits located at the pointer. + * @param ptr the pointer containing the target address. + * @param val the new integer value. + */ + QUAD_SET, + + } IR_INSTRUCTION_CODE; diff --git a/src/qasm/writer/writer.c b/src/qasm/writer/writer.c index 5bf1bc4..6b3d621 100644 --- a/src/qasm/writer/writer.c +++ b/src/qasm/writer/writer.c @@ -9,7 +9,7 @@ #include "../../ir/instructions.h" #include "../../ir/structs.h" -const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_set", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load", "st_freef"}; +const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load", "st_freef", "ptr_set", "qd_set"}; /** * Writes some standart QuickAssembly code equivalent to the parsed IR. From 321e3bb36327b01297ac9ea699e9e5d11b6ac494 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 10 Jan 2025 18:34:12 +0100 Subject: [PATCH 07/26] feat: added dd_set and od_set --- src/compiler/win64.c | 36 +++++++++++++++++++++++++++++++++++- src/ir/instructions.h | 12 ++++++++++++ src/ir/irs/variables.c | 25 ++++++++++++++++++++----- src/qasm/writer/writer.c | 2 +- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/compiler/win64.c b/src/compiler/win64.c index f186381..32a3a13 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -74,11 +74,24 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC buff->size += 4; break; + case DUO_SET: + buff->buff[buff->size] = 0x66; + buff->buff[buff->size + 1] = 0x45; + + ii = hashGet(ctx->map, hashstr(instruction->params[0])); + + buff->buff[buff->size + 2] = (uint8_t) *ii; + + buff->buff[buff->size + 3] = ((unsigned char*)instruction->params[1])[3]; + buff->buff[buff->size + 4] = ((unsigned char*)instruction->params[1])[2]; + + buff->size += 5; + case QUAD_SET: //dword buff->buff[buff->size] = 0xC7; buff->buff[buff->size + 1] = 0x45; - int* ii = hashGet(ctx->map, hashstr(instruction->params[0])); + ii = hashGet(ctx->map, hashstr(instruction->params[0])); buff->buff[buff->size + 2] = (uint8_t) *ii; @@ -90,6 +103,27 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC buff->size += 7; break; + case OCT_SET: //qword + buff->buff[buff->size] = 0x48; + buff->buff[buff->size + 1] = 0xC7; + buff->buff[buff->size + 2] = 0x45; + + ii = hashGet(ctx->map, hashstr(instruction->params[0])); + + buff->buff[buff->size + 3] = (uint8_t) *ii; + + buff->buff[buff->size + 4] = ((unsigned char*)instruction->params[1])[7]; + buff->buff[buff->size + 5] = ((unsigned char*)instruction->params[1])[6]; + buff->buff[buff->size + 6] = ((unsigned char*)instruction->params[1])[5]; + buff->buff[buff->size + 7] = ((unsigned char*)instruction->params[1])[4]; + buff->buff[buff->size + 8] = ((unsigned char*)instruction->params[1])[3]; + buff->buff[buff->size + 9] = ((unsigned char*)instruction->params[1])[2]; + buff->buff[buff->size + 10] = ((unsigned char*)instruction->params[1])[1]; + buff->buff[buff->size + 11] = ((unsigned char*)instruction->params[1])[0]; + + buff->size += 12; + break; + case STACK_FREE_FUNC: buff->buff[buff->size] = 0x48; buff->buff[buff->size + 1] = 0x83; diff --git a/src/ir/instructions.h b/src/ir/instructions.h index e276f10..b572bce 100644 --- a/src/ir/instructions.h +++ b/src/ir/instructions.h @@ -157,7 +157,19 @@ typedef enum IR_INSTRUCTION_CODE { */ QUAD_SET, + /** + * Sets 16 bits located at the pointer. + * @param ptr the pointer containing the target address. + * @param val the new integer value. + */ + DUO_SET, + /** + * Sets 64 bits located at the pointer. + * @param ptr the pointer containing the target address. + * @param val the new integer value. + */ + OCT_SET } IR_INSTRUCTION_CODE; diff --git a/src/ir/irs/variables.c b/src/ir/irs/variables.c index ccd6c18..cdd9539 100644 --- a/src/ir/irs/variables.c +++ b/src/ir/irs/variables.c @@ -58,12 +58,27 @@ void parseVariableDeclaration(IR_BASIC_BLOCK* block, AST_VARIABLE_DEC* node) { appendInstruction(block, S_ALLOC, params, 2); if(node->value != NULL) { - params = malloc(sizeof(void*) * 2); - params[0] = node->name; + if(allocSize == 32) { // if allocates 32 bits, use qd_set + params = malloc(sizeof(void*) * 2); + params[0] = node->name; - parseValue(params, 1, node->value); - - appendInstruction(block, PTR_SET, params, 2); + parseValue(params, 1, node->value); + + appendInstruction(block, QUAD_SET, params, 2); + } + else { + void** buff = malloc(sizeof(void*) * allocSize / 8); + parseValue(buff, 0, node->value); + + for(int i = 0; i < allocSize / 8; ++i) { + params = malloc(sizeof(void*) * 2); + params[0] = node->name; + + params[1] = malloc(1); + ((unsigned char*)params[1])[0] = ((unsigned char*)buff[0])[i]; + appendInstruction(block, PTR_SET, params, 2); + } + } } } diff --git a/src/qasm/writer/writer.c b/src/qasm/writer/writer.c index 6b3d621..34fc83e 100644 --- a/src/qasm/writer/writer.c +++ b/src/qasm/writer/writer.c @@ -9,7 +9,7 @@ #include "../../ir/instructions.h" #include "../../ir/structs.h" -const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load", "st_freef", "ptr_set", "qd_set"}; +const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load", "st_freef", "ptr_set", "qd_set", "dd_set", "od_set"}; /** * Writes some standart QuickAssembly code equivalent to the parsed IR. From 77aeca0e683e5e6c01ab2b0142cc50e355f2e2c7 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 10 Jan 2025 18:53:51 +0100 Subject: [PATCH 08/26] feat: added ptr_dec instruction --- src/compiler/win64.c | 8 ++++++++ src/ir/instructions.h | 10 +++++++++- src/ir/irs/values.c | 31 +++++++++++++++++++++++++++++++ src/ir/irs/values.h | 6 ++++++ src/ir/irs/variables.c | 14 ++++++-------- src/qasm/writer/writer.c | 2 +- 6 files changed, 61 insertions(+), 10 deletions(-) diff --git a/src/compiler/win64.c b/src/compiler/win64.c index 32a3a13..0c2f544 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -133,6 +133,14 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC buff->size += 4; break; + + case PTR_DEC: + int* ii = malloc(sizeof(int)); + + *ii = (((unsigned char*)instruction->params[1])[0] << 24) | (((unsigned char*)instruction->params[1])[1] << 16) | (((unsigned char*)instruction->params[1])[2] << 8) | ((unsigned char*)instruction->params[1])[3]; + + hashPut(ctx->map, hashstr(instruction->params[0]), ii); + break; } } \ No newline at end of file diff --git a/src/ir/instructions.h b/src/ir/instructions.h index b572bce..f9f85fa 100644 --- a/src/ir/instructions.h +++ b/src/ir/instructions.h @@ -169,7 +169,15 @@ typedef enum IR_INSTRUCTION_CODE { * @param ptr the pointer containing the target address. * @param val the new integer value. */ - OCT_SET + OCT_SET, + + + /** + * Declares a pointer at the specified address. + * @param ptr the new pointer. + * @param addr the address + */ + PTR_DEC } IR_INSTRUCTION_CODE; diff --git a/src/ir/irs/values.c b/src/ir/irs/values.c index 950ad58..bb233c5 100644 --- a/src/ir/irs/values.c +++ b/src/ir/irs/values.c @@ -3,6 +3,7 @@ */ #include +#include #include "../../parser/ast.h" @@ -61,6 +62,36 @@ void parseValue(void** buff, int index, void* value) { } } +/** + * Gets the byte equivalent. + * @param value the value. + */ +unsigned char* getByteEquivalent(void* value) { + if(((AST_TREE_BRANCH*)value)->type == AST_TYPE_VALUE) { + AST_VALUE* val = (AST_VALUE*)value; + + switch(*val->valueType) { + case INT32: + case INT24: + case INT16: + case INT8: + + int num = atoi(val->value); + + printf("%d", num); + + unsigned char* buff = malloc(4); + + buff[0] = (num >> 24) & 0xFF; + buff[1] = (num >> 16) & 0xFF; + buff[2] = (num >> 8) & 0xFF; + buff[3] = num & 0xFF; + + return buff; + } + } +} + /** * Gets the value size for a certain type for a parameter. * @param type the type's byte indentifier. diff --git a/src/ir/irs/values.h b/src/ir/irs/values.h index 018b3ad..900f873 100644 --- a/src/ir/irs/values.h +++ b/src/ir/irs/values.h @@ -13,6 +13,12 @@ */ void parseValue(void** buff, int index, void* value); +/** + * Gets the byte equivalent. + * @param value the value. + */ +unsigned char* getByteEquivalent(void* value); + /** * Gets the value size for a certain type for a parameter. * @param type the type's byte indentifier. diff --git a/src/ir/irs/variables.c b/src/ir/irs/variables.c index cdd9539..8a9b36c 100644 --- a/src/ir/irs/variables.c +++ b/src/ir/irs/variables.c @@ -67,16 +67,14 @@ void parseVariableDeclaration(IR_BASIC_BLOCK* block, AST_VARIABLE_DEC* node) { appendInstruction(block, QUAD_SET, params, 2); } else { - void** buff = malloc(sizeof(void*) * allocSize / 8); - parseValue(buff, 0, node->value); + unsigned char* equiv = getByteEquivalent(node->value); - for(int i = 0; i < allocSize / 8; ++i) { - params = malloc(sizeof(void*) * 2); - params[0] = node->name; + for(int i = 4; i > (4 - allocSize / 8); --i) { + printf("i: %d\n", i); + printf("0x%x ", equiv[i - 1]); + + appendInstruction(block, PTR_SET) - params[1] = malloc(1); - ((unsigned char*)params[1])[0] = ((unsigned char*)buff[0])[i]; - appendInstruction(block, PTR_SET, params, 2); } } } diff --git a/src/qasm/writer/writer.c b/src/qasm/writer/writer.c index 34fc83e..7ab7283 100644 --- a/src/qasm/writer/writer.c +++ b/src/qasm/writer/writer.c @@ -9,7 +9,7 @@ #include "../../ir/instructions.h" #include "../../ir/structs.h" -const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load", "st_freef", "ptr_set", "qd_set", "dd_set", "od_set"}; +const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load", "st_freef", "ptr_set", "qd_set", "dd_set", "od_set", "ptr_dec"}; /** * Writes some standart QuickAssembly code equivalent to the parsed IR. From d2feda97d3b13cc9d0b015fd5d071d97a3e7da65 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 10 Jan 2025 19:13:51 +0100 Subject: [PATCH 09/26] feat: added support for int8, int16 and int24 --- src/cli/main.c | 4 ---- src/compiler/win64.c | 16 +++++++++++++--- src/ir/instructions.h | 10 +++++++++- src/ir/irs/variables.c | 30 +++++++++++++++++++++++++----- src/qasm/writer/writer.c | 2 +- src/utils/hash.c | 8 -------- 6 files changed, 48 insertions(+), 22 deletions(-) diff --git a/src/cli/main.c b/src/cli/main.c index 4a22ecf..3ad8067 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -132,10 +132,6 @@ int main(int argc, char* argv[]) { BYTECODE_BUFFER* buffer = compile(irOut); - for(int i = 0; i < buffer->size; ++i) { - printf("0x%x ", buffer->buff[i]); - } - compilePE(fptr, buffer); fclose(fptr); diff --git a/src/compiler/win64.c b/src/compiler/win64.c index 0c2f544..cb9c95d 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -69,7 +69,7 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC buff->buff[buff->size + 2] = (uint8_t) *ii; - buff->buff[buff->size + 3] = ((unsigned char*)instruction->params[1])[3]; + buff->buff[buff->size + 3] = ((unsigned char*)instruction->params[1])[0]; buff->size += 4; break; @@ -135,12 +135,22 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC break; case PTR_DEC: - int* ii = malloc(sizeof(int)); - + ii = malloc(sizeof(int)); *ii = (((unsigned char*)instruction->params[1])[0] << 24) | (((unsigned char*)instruction->params[1])[1] << 16) | (((unsigned char*)instruction->params[1])[2] << 8) | ((unsigned char*)instruction->params[1])[3]; hashPut(ctx->map, hashstr(instruction->params[0]), ii); break; + + case PTR_DEC_OFF: + ii = malloc(sizeof(int)); + *ii = (((unsigned char*)instruction->params[2])[0] << 24) | (((unsigned char*)instruction->params[2])[1] << 16) | (((unsigned char*)instruction->params[2])[2] << 8) | ((unsigned char*)instruction->params[2])[3]; + + int* o = hashGet(ctx->map, hashstr(instruction->params[1])); + + *ii += *o; + + hashPut(ctx->map, hashstr(instruction->params[0]), ii); + break; } } \ No newline at end of file diff --git a/src/ir/instructions.h b/src/ir/instructions.h index f9f85fa..6991056 100644 --- a/src/ir/instructions.h +++ b/src/ir/instructions.h @@ -177,7 +177,15 @@ typedef enum IR_INSTRUCTION_CODE { * @param ptr the new pointer. * @param addr the address */ - PTR_DEC + PTR_DEC, + + /** + * Declares a pointer that is an offset of another pointer. + * @param ptr the new pointer. + * @param p the old pointer. + * @param off the offset. + */ + PTR_DEC_OFF } IR_INSTRUCTION_CODE; diff --git a/src/ir/irs/variables.c b/src/ir/irs/variables.c index 8a9b36c..7957939 100644 --- a/src/ir/irs/variables.c +++ b/src/ir/irs/variables.c @@ -70,11 +70,31 @@ void parseVariableDeclaration(IR_BASIC_BLOCK* block, AST_VARIABLE_DEC* node) { unsigned char* equiv = getByteEquivalent(node->value); for(int i = 4; i > (4 - allocSize / 8); --i) { - printf("i: %d\n", i); - printf("0x%x ", equiv[i - 1]); - - appendInstruction(block, PTR_SET) - + int size = strlen(node->name) + 2; + char* ptrName = malloc(size); + ptrName[size] = '\0'; + ptrName[size - 1] = (char) i + 97; + + params = malloc(sizeof(void*) * 3); + params[0] = ptrName; + params[1] = node->name; + + params[2] = malloc(4); + unsigned char* buff = (unsigned char*) params[2]; + + buff[0] = ((i - 4) * 8 - 1 >> 24) & 0xFF; + buff[1] = ((i - 4) * 8 - 1 >> 16) & 0xFF; + buff[2] = ((i - 4) * 8 - 1 >> 8) & 0xFF; + buff[3] = (i - 4) * 8 - 1 & 0xFF; + + appendInstruction(block, PTR_DEC_OFF, params, 3); + + params = malloc(sizeof(void*) * 2); + params[0] = ptrName; + params[1] = malloc(1); + ((unsigned char*)params[1])[0] = equiv[i - 1]; + + appendInstruction(block, PTR_SET, params, 2); } } } diff --git a/src/qasm/writer/writer.c b/src/qasm/writer/writer.c index 7ab7283..64b6af5 100644 --- a/src/qasm/writer/writer.c +++ b/src/qasm/writer/writer.c @@ -9,7 +9,7 @@ #include "../../ir/instructions.h" #include "../../ir/structs.h" -const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load", "st_freef", "ptr_set", "qd_set", "dd_set", "od_set", "ptr_dec"}; +const char* formatedInstructions[] = {"blck_swap", "cblk_swap", "lblck_swap", "salloc", "ptr_load", "iadd", "isub", "imul", "idiv", "icmp", "icmp_h", "icmp_l", "prm_push", "ret_push", "call", "ret", "st_push", "st_load", "st_freef", "ptr_set", "qd_set", "dd_set", "od_set", "ptr_dec", "optr_dec"}; /** * Writes some standart QuickAssembly code equivalent to the parsed IR. diff --git a/src/utils/hash.c b/src/utils/hash.c index 3fa2d8d..a74b33d 100644 --- a/src/utils/hash.c +++ b/src/utils/hash.c @@ -2,22 +2,14 @@ * Hashing related utilities. */ -#include - unsigned int hashstr(char* str) { unsigned int result = 0; unsigned char* p = (unsigned char*) str; - printf("str: %s -> ", str); - while(*p != '\0') { - printf("0x%x ", *p); - result = ((*p - 97) << 5) + result + 1; ++p; } - printf("\n"); - return result; } From dc6759ad73662a6e7c6904aa13ccc5cb3e480958 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 10 Jan 2025 19:48:48 +0100 Subject: [PATCH 10/26] feat: added BLOCK_SWAP win support --- src/cli/main.c | 4 ++++ src/compiler/compiler.c | 4 ++++ src/compiler/structs.h | 2 ++ src/compiler/win64.c | 17 ++++++++++++++++- src/ir/irs/functions.c | 7 +++++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/cli/main.c b/src/cli/main.c index 3ad8067..8e37b37 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -132,6 +132,10 @@ int main(int argc, char* argv[]) { BYTECODE_BUFFER* buffer = compile(irOut); + for(int i = 0; i < buffer->size; ++i) { + printf("0x%x ",buffer->buff[i]); + } + compilePE(fptr, buffer); fclose(fptr); diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 42bc67b..390b320 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -31,8 +31,12 @@ BYTECODE_BUFFER* compile(IR_OUTPUT* out) { ctx->currStack = 0; ctx->map = createHashmap(200,512); + ctx->blockOffsets = malloc(sizeof(int) * out->blockCount); + // todo: add multi block handling. + ctx->blockOffsets[0] = 0; + for(int i = 0; i < out->blocks[0]->instructionCount; ++i) { compileInstruction(buff, ctx, out->blocks[0]->instructions[i]); } diff --git a/src/compiler/structs.h b/src/compiler/structs.h index 93039ed..d90b1d6 100644 --- a/src/compiler/structs.h +++ b/src/compiler/structs.h @@ -29,6 +29,8 @@ typedef struct COMPILER_CONTEXT { struct Hashmap* map; int stackSize; int currStack; + + int* blockOffsets; } COMPILER_CONTEXT; diff --git a/src/compiler/win64.c b/src/compiler/win64.c index cb9c95d..2fe2e6d 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -151,6 +151,21 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC hashPut(ctx->map, hashstr(instruction->params[0]), ii); break; - + + case BLOCK_SWAP: + buff->buff[buff->size] = 0xE9; + + i = (((unsigned char*)instruction->params[0])[0] << 24) | (((unsigned char*)instruction->params[0])[1] << 16) | (((unsigned char*)instruction->params[0])[2] << 8) | ((unsigned char*)instruction->params[0])[3]; + + int off = ctx->blockOffsets[i] - buff->size; + + buff->buff[buff->size + 1] = off & 0xFF; + buff->buff[buff->size + 2] = (off >> 8) & 0xFF; + buff->buff[buff->size + 3] = (off >> 16) & 0xFF; + buff->buff[buff->size + 4] = (off >> 24) & 0xFF; + + buff->size += 5; + break; + } } \ No newline at end of file diff --git a/src/ir/irs/functions.c b/src/ir/irs/functions.c index c38c5e7..0d97bea 100644 --- a/src/ir/irs/functions.c +++ b/src/ir/irs/functions.c @@ -63,6 +63,13 @@ void parseFunction(IR_OUTPUT* out, AST_FUNCTION_DEC* node) { } } + void** params = malloc(sizeof(void*)); + params[0] = malloc(sizeof(int)); + int* p = (params[0]); + *p = 0; + + appendInstruction(out->blocks[out->blockCount], BLOCK_SWAP, params, 1); + appendInstruction(out->blocks[out->blockCount], STACK_FREE_FUNC, NULL, 0); appendInstruction(out->blocks[out->blockCount], STACK_LOAD, NULL, 0); From 099eabe649c6e3707321d2cdf8cefbb09e4773fb Mon Sep 17 00:00:00 2001 From: Zffu Date: Sat, 11 Jan 2025 14:02:20 +0100 Subject: [PATCH 11/26] feat: added bit/boolean type in lexer --- src/lexer/lexer.c | 3 +++ src/lexer/tokens.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 72fac0d..4bf520f 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -121,6 +121,9 @@ LEXER_RESULT runLexer(char* string, int size) { else if(strcmp(buff, "int8") == 0) { pushToken(&result, TYPE_INT8); } + else if(strcmp(buff, "bit") == 0) { + pushToken(&result, TYPE_BIT); + } else { pushToken(&result, KEYWORD); result.tokens[result.size - 1].value = buff; diff --git a/src/lexer/tokens.h b/src/lexer/tokens.h index 15391f6..68b20ab 100644 --- a/src/lexer/tokens.h +++ b/src/lexer/tokens.h @@ -27,7 +27,8 @@ typedef enum { TYPE_INT32, TYPE_INT24, TYPE_INT16, - TYPE_INT8 + TYPE_INT8, + TYPE_BIT } TOKEN_TYPE; /** From fc27181553ecc0f9852775eab2e37850ab366d57 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sat, 11 Jan 2025 14:11:07 +0100 Subject: [PATCH 12/26] feat: added ir support for boolean/bit variables --- src/compiler/win64.c | 17 +++++++++++++++++ src/ir/irs/functions.c | 12 +++++++++--- src/ir/irs/variables.c | 14 +++++++++++++- src/lib/types.h | 3 ++- src/parser/parser.c | 1 + 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/compiler/win64.c b/src/compiler/win64.c index 2fe2e6d..c9cac7d 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -167,5 +167,22 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC buff->size += 5; break; + case COND_BLOCK_SWAP: + buff->buff[buff->size] = 0x80; + buff->buff[buff->size + 1] = 0x7d; + + i = (((unsigned char*)instruction->params[0])[0] << 24) | (((unsigned char*)instruction->params[0])[1] << 16) | (((unsigned char*)instruction->params[0])[2] << 8) | ((unsigned char*)instruction->params[0])[3]; + + off = ctx->blockOffsets[i] - buff->size; + + ii = hashGet(ctx->map, hashstr(instruction->params[1])); + + + buff->buff[buff->size + 2] = *ii & 0xFF; + buff->buff[buff->size + 3] = 0x01; + + buff->buff[buff->size + 4] = 0x74; + buff->buff[buff->size + 4] = off & 0xFF; + break; } } \ No newline at end of file diff --git a/src/ir/irs/functions.c b/src/ir/irs/functions.c index 0d97bea..19726a1 100644 --- a/src/ir/irs/functions.c +++ b/src/ir/irs/functions.c @@ -64,11 +64,17 @@ void parseFunction(IR_OUTPUT* out, AST_FUNCTION_DEC* node) { } void** params = malloc(sizeof(void*)); - params[0] = malloc(sizeof(int)); - int* p = (params[0]); + params[0] = malloc(3); + ((unsigned char*)params[0])[0] = '%'; + ((unsigned char*)params[0])[1] = 'a'; + ((unsigned char*)params[0])[2] = 'b'; + + + params[1] = malloc(sizeof(int)); + int* p = (params[1]); *p = 0; - appendInstruction(out->blocks[out->blockCount], BLOCK_SWAP, params, 1); + appendInstruction(out->blocks[out->blockCount], COND_BLOCK_SWAP, params, 2); appendInstruction(out->blocks[out->blockCount], STACK_FREE_FUNC, NULL, 0); appendInstruction(out->blocks[out->blockCount], STACK_LOAD, NULL, 0); diff --git a/src/ir/irs/variables.c b/src/ir/irs/variables.c index 7957939..cf83f74 100644 --- a/src/ir/irs/variables.c +++ b/src/ir/irs/variables.c @@ -7,6 +7,7 @@ #include #include "../../parser/structs/variables.h" +#include "../../parser/structs/values.h" #include "./values.h" @@ -32,6 +33,7 @@ void parseVariableDeclaration(IR_BASIC_BLOCK* block, AST_VARIABLE_DEC* node) { case INT16: allocSize = 16; break; + case BIT: // bit is 8 for now, only for now case INT8: allocSize = 8; break; @@ -58,7 +60,17 @@ void parseVariableDeclaration(IR_BASIC_BLOCK* block, AST_VARIABLE_DEC* node) { appendInstruction(block, S_ALLOC, params, 2); if(node->value != NULL) { - if(allocSize == 32) { // if allocates 32 bits, use qd_set + AST_VALUE* val = (AST_VALUE*) node->value; + if(node->type[0] == BIT && val->valueType == BIT) { + params = malloc(sizeof(void*) * 2); + params[0] = node->name; + + params[1] = malloc(1); + ((unsigned char*)params[1])[0] = strcmp(val->value, "true") == 0; + + pushInstruction(block, PTR_SET, params, 2); + } + else if(allocSize == 32) { // if allocates 32 bits, use qd_set params = malloc(sizeof(void*) * 2); params[0] = node->name; diff --git a/src/lib/types.h b/src/lib/types.h index 24b0ad0..3063a03 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -13,7 +13,8 @@ typedef enum LIB_TYPES { INT32 = 0x01, INT24 = 0x02, INT16 = 0x03, - INT8 = 0x04 + INT8 = 0x04, + BIT = 0x05 } LIB_TYPES; diff --git a/src/parser/parser.c b/src/parser/parser.c index 533f1fa..9cae156 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -38,6 +38,7 @@ void* parseRoot(LEXER_RESULT result, int startingIndex, AST_TYPE type) { case TYPE_INT24: case TYPE_INT16: case TYPE_INT8: + case TYPE_BIT: case VAR: void* node = parseASTVariableDeclaration(result, i); if(node != NULL) { From 29d17e23ecee3e81301b893a4f4d7a38cc5a4cc4 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sat, 11 Jan 2025 14:12:12 +0100 Subject: [PATCH 13/26] feat: added parsing support for bit type --- src/parser/asts/values.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/parser/asts/values.c b/src/parser/asts/values.c index 26ab697..a1c9f93 100644 --- a/src/parser/asts/values.c +++ b/src/parser/asts/values.c @@ -36,6 +36,15 @@ AST_VALUE* parseASTValue(LEXER_RESULT result, int index, LIB_TYPES exceptedType) value->valueType = malloc(1); value->valueType[0] = exceptedType; break; + case BIT: + if(result.tokens[index].type != BOOLEAN_VALUE) { + printf("Excepted boolean as bit value!\n"); + return NULL; + } + + value->valueType = malloc(1); + value->valueType[0] = BIT; + break; } value->endingIndex = index + 1; From dcef7022f70738a6a027ad1098b9a1f72dfd33a2 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sat, 11 Jan 2025 14:13:07 +0100 Subject: [PATCH 14/26] fix: fixed wrong func name --- src/ir/irs/variables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ir/irs/variables.c b/src/ir/irs/variables.c index cf83f74..75863b4 100644 --- a/src/ir/irs/variables.c +++ b/src/ir/irs/variables.c @@ -68,7 +68,7 @@ void parseVariableDeclaration(IR_BASIC_BLOCK* block, AST_VARIABLE_DEC* node) { params[1] = malloc(1); ((unsigned char*)params[1])[0] = strcmp(val->value, "true") == 0; - pushInstruction(block, PTR_SET, params, 2); + appendInstruction(block, PTR_SET, params, 2); } else if(allocSize == 32) { // if allocates 32 bits, use qd_set params = malloc(sizeof(void*) * 2); From b0548846449c669c93f2c2dc3a4d8216492d62ee Mon Sep 17 00:00:00 2001 From: Zffu Date: Sat, 11 Jan 2025 14:16:15 +0100 Subject: [PATCH 15/26] feat: misc fixes and removed debugging instructions --- src/ir/irs/functions.c | 13 ------------- src/ir/irs/variables.c | 2 +- src/parser/asts/values.c | 4 ++++ src/parser/asts/variables.c | 1 + 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/ir/irs/functions.c b/src/ir/irs/functions.c index 19726a1..c38c5e7 100644 --- a/src/ir/irs/functions.c +++ b/src/ir/irs/functions.c @@ -63,19 +63,6 @@ void parseFunction(IR_OUTPUT* out, AST_FUNCTION_DEC* node) { } } - void** params = malloc(sizeof(void*)); - params[0] = malloc(3); - ((unsigned char*)params[0])[0] = '%'; - ((unsigned char*)params[0])[1] = 'a'; - ((unsigned char*)params[0])[2] = 'b'; - - - params[1] = malloc(sizeof(int)); - int* p = (params[1]); - *p = 0; - - appendInstruction(out->blocks[out->blockCount], COND_BLOCK_SWAP, params, 2); - appendInstruction(out->blocks[out->blockCount], STACK_FREE_FUNC, NULL, 0); appendInstruction(out->blocks[out->blockCount], STACK_LOAD, NULL, 0); diff --git a/src/ir/irs/variables.c b/src/ir/irs/variables.c index 75863b4..596f70c 100644 --- a/src/ir/irs/variables.c +++ b/src/ir/irs/variables.c @@ -61,7 +61,7 @@ void parseVariableDeclaration(IR_BASIC_BLOCK* block, AST_VARIABLE_DEC* node) { if(node->value != NULL) { AST_VALUE* val = (AST_VALUE*) node->value; - if(node->type[0] == BIT && val->valueType == BIT) { + if(node->type[0] == BIT) { params = malloc(sizeof(void*) * 2); params[0] = node->name; diff --git a/src/parser/asts/values.c b/src/parser/asts/values.c index a1c9f93..80a6d35 100644 --- a/src/parser/asts/values.c +++ b/src/parser/asts/values.c @@ -68,6 +68,10 @@ void* parseValueGroup(LEXER_RESULT result, int index, LIB_TYPES exceptedType) { return parseASTValue(result, index, exceptedType); break; + + case BOOLEAN_VALUE: + return parseASTValue(result, index, exceptedType); + default: printf("Error: couldn't parse value token group!\n"); return NULL; diff --git a/src/parser/asts/variables.c b/src/parser/asts/variables.c index edc5e0a..2da8e6e 100644 --- a/src/parser/asts/variables.c +++ b/src/parser/asts/variables.c @@ -29,6 +29,7 @@ AST_VARIABLE_DEC* parseASTVariableDeclaration(LEXER_RESULT result, int index) { case TYPE_INT24: case TYPE_INT16: case TYPE_INT8: + case TYPE_BIT: var->type[0] = (result.tokens[index].type - TYPE_INT32) + 0x01; break; From afa06aaab217f3857d8209406d8a6ae017201961 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sat, 11 Jan 2025 14:17:58 +0100 Subject: [PATCH 16/26] feat: added multi blocks support --- src/compiler/compiler.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 390b320..5d6991e 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -32,13 +32,13 @@ BYTECODE_BUFFER* compile(IR_OUTPUT* out) { ctx->map = createHashmap(200,512); ctx->blockOffsets = malloc(sizeof(int) * out->blockCount); + + for(int blockIndex = 0; blockIndex < out->blockCount; ++blockIndex) { + ctx->blockOffsets[blockIndex] = buff->size; - // todo: add multi block handling. - - ctx->blockOffsets[0] = 0; - - for(int i = 0; i < out->blocks[0]->instructionCount; ++i) { - compileInstruction(buff, ctx, out->blocks[0]->instructions[i]); + for(int i = 0; i < out->blocks[blockIndex]->instructionCount; ++i) { + compileInstruction(buff, ctx, out->blocks[blockIndex]->instructions[i]); + } } return buff; From dfd3db022d21f96b287577156e6cfd3bbf3b6301 Mon Sep 17 00:00:00 2001 From: Zffu Date: Mon, 13 Jan 2025 09:13:09 +0100 Subject: [PATCH 17/26] fix: fixed incorrect index offset during buff modification --- src/compiler/win64.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/win64.c b/src/compiler/win64.c index c9cac7d..1a590ea 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -182,7 +182,9 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC buff->buff[buff->size + 3] = 0x01; buff->buff[buff->size + 4] = 0x74; - buff->buff[buff->size + 4] = off & 0xFF; + buff->buff[buff->size + 5] = off & 0xFF; + + buff->size += 6; break; } } \ No newline at end of file From 686c3f9cc2a66a13bf6728c0fbcf55f80d5b549e Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 17 Jan 2025 13:11:34 +0100 Subject: [PATCH 18/26] feat: dropped old unused function --- src/compiler/win64.c | 30 ++++++++++++++++++++++++++++++ src/utils/hashes.c | 12 ------------ src/utils/hashes.h | 10 ---------- 3 files changed, 30 insertions(+), 22 deletions(-) delete mode 100644 src/utils/hashes.c delete mode 100644 src/utils/hashes.h diff --git a/src/compiler/win64.c b/src/compiler/win64.c index 1a590ea..cfd40e2 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -186,5 +186,35 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC buff->size += 6; break; + case LOGICAL_BLOCK_SWAP: + int trueBlockId = (((unsigned char*)instruction->params[0])[0] << 24) | (((unsigned char*)instruction->params[0])[1] << 16) | (((unsigned char*)instruction->params[0])[2] << 8) | ((unsigned char*)instruction->params[0])[3]; + int falseBlockId = (((unsigned char*)instruction->params[1])[0] << 24) | (((unsigned char*)instruction->params[1])[1] << 16) | (((unsigned char*)instruction->params[1])[2] << 8) | ((unsigned char*)instruction->params[1])[3]; + + int* trueBlockPtr = ctx->blockOffsets[trueBlockId]; + int* falseBlockPtr = ctx->blockOffsets[falseBlockId]; + + + // Instead of doing if else, just jump to the block if true and continue if not + + ii = hashGet(ctx->map, hashstr(instruction->params[2])); + + buff->buff[buff->size] = 0x80; + buff->buff[buff->size + 1] = 0x7d; + + buff->buff[buff->size + 2] = *ii & 0xFF; + buff->buff[buff->size + 3] = 0x01; + + buff->buff[buff->size + 4] = 0x74; + buff->buff[buff->size + 5] = (*trueBlockPtr - buff->size) & 0xFF; + + // else + off = *falseBlockPtr - buff->size; + + buff->buff[buff->size + 6] = off & 0xFF; + buff->buff[buff->size + 7] = (off >> 8) & 0xFF; + buff->buff[buff->size + 8] = (off >> 16) & 0xFF; + buff->buff[buff->size + 9] = (off >> 24) & 0xFF; + + buff->size += 10; } } \ No newline at end of file diff --git a/src/utils/hashes.c b/src/utils/hashes.c deleted file mode 100644 index e04cde9..0000000 --- a/src/utils/hashes.c +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Hashmap related utilities for Quickfall. - */ - -#include - -/** - * Generates a hash for a lexar token. Currently compromisable - */ -int tokenHash(char* token) { - return strlen(token); -} \ No newline at end of file diff --git a/src/utils/hashes.h b/src/utils/hashes.h deleted file mode 100644 index 93d6d12..0000000 --- a/src/utils/hashes.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef HASHES_H -#define HASHES_H - -/** - * Calculates a hash value for a string. - * Uses a simple but fast hashing algorithm. - */ -int tokenHash(const char* str); - -#endif \ No newline at end of file From 46c699c55ed1af17b374d4633d0854c02ae86964 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 17 Jan 2025 13:15:30 +0100 Subject: [PATCH 19/26] feat: [experimental] changed hash algorithm to remove collissions --- src/utils/hash.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/utils/hash.c b/src/utils/hash.c index a74b33d..9572982 100644 --- a/src/utils/hash.c +++ b/src/utils/hash.c @@ -3,13 +3,19 @@ */ unsigned int hashstr(char* str) { - unsigned int result = 0; - unsigned char* p = (unsigned char*) str; - - while(*p != '\0') { - result = ((*p - 97) << 5) + result + 1; - ++p; - } - - return result; + unsigned int hash = 2166136261u; // FNV offset basis + unsigned char *p = (unsigned char *)str; + + while (*p) { + hash ^= *p++; + hash *= 16777619u; // FNV prime + hash &= 0x0FFF; // Keep only 12 bits to maintain smaller values + } + + // Final mixing for better distribution in small range + hash ^= hash >> 6; + hash *= 0x9E3779B1; // Golden ratio prime + hash &= 0x0FFF; // Final mask to 12 bits + + return hash; } From 505a342608edf049ac89c625a64ea85b421d65dc Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 17 Jan 2025 13:25:25 +0100 Subject: [PATCH 20/26] feat: [experimental] changed hashes for new algorithm and added new instructions to parser --- src/lexer/lexer.c | 1 - src/qasm/parser/parser.c | 128 +++++++++++++++++++++++++++++++++------ 2 files changed, 109 insertions(+), 20 deletions(-) diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 4bf520f..59ac382 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -10,7 +10,6 @@ #include "./lexer.h" #include "./tokens.h" -#include "../utils/hashes.h" /** * Sets the token type of the currently selected token in the LexerResult with the provided token type. diff --git a/src/qasm/parser/parser.c b/src/qasm/parser/parser.c index 6ffccf5..67c2545 100644 --- a/src/qasm/parser/parser.c +++ b/src/qasm/parser/parser.c @@ -80,7 +80,7 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { // Determines the instruction type based on the string hash. switch(instructionHash) { - case 2985: + case 1648: instruction->opCode = BLOCK_SWAP; b = malloc(sizeof(void*)); parseInt32(b, 0, buff[1]); @@ -88,7 +88,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 1; break; - case 2987: + + case 842: instruction->opCode = COND_BLOCK_SWAP; b = malloc(sizeof(void*) * 2); @@ -98,7 +99,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 2; break; - case 3275: + + case 1891: instruction->opCode = LOGICAL_BLOCK_SWAP; b = malloc(sizeof(int*) * 3); @@ -109,7 +111,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 3; break; - case 1798: + + case 275: instruction->opCode = S_ALLOC; b = malloc(sizeof(void*) * 2); @@ -119,17 +122,19 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 2; break; - case 2887: + + case 2133: instruction->opCode = PTR_SET; b = malloc(sizeof(void*) * 2); - parseInt32(b, 0, buff[1]); - parseVariableName(b, 1, buff[2]); + parseVariableName(b, 0, buff[1]); + parseInt32(b, 1, buff[2]); instruction->params = b; instruction->paramCount = 2; break; - case 2472: + + case 2059: instruction->opCode = PTR_LOAD; b = malloc(sizeof(void*) * 2); @@ -139,7 +144,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 2; break; - case 452: + + case 3257: instruction->opCode = IADD; b = malloc(sizeof(void*) * 3); @@ -150,7 +156,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 3; break; - case 1508: + + case 1305: instruction->opCode = ISUB; b = malloc(sizeof(void*) * 3); @@ -161,7 +168,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 3; break; - case 1636: + + case 386: instruction->opCode = IMUL; b = malloc(sizeof(void*) * 3); @@ -172,7 +180,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 3; break; - case 1284: + + case 780: instruction->opCode = IDIV; b = malloc(sizeof(void*) * 3); @@ -183,7 +192,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 3; break; - case 1188: + + case 3858: instruction->opCode = ICMP; b = malloc(sizeof(void*) * 3); @@ -194,7 +204,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 3; break; - case 1350: + + case 3409: instruction->opCode = ICMP_H; b = malloc(sizeof(void*) * 3); @@ -205,7 +216,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 3; break; - case 1478: + + case 118: instruction->opCode = ICMP_L; b = malloc(sizeof(void*) * 3); @@ -216,7 +228,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 3; break; - case 3272: + + case 2745: instruction->opCode = PRM_PUSH; b = malloc(sizeof(void*) * 2); @@ -226,7 +239,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 2; break; - case 3144: + + case 3108: instruction->opCode = RET_PUSH; b = malloc(sizeof(void*)); @@ -235,7 +249,8 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 1; break; - case 772: + + case 2123: instruction->opCode = CALL; b = malloc(sizeof(void*)); @@ -244,11 +259,86 @@ IR_INSTRUCTION* parseInstruction(char** buff, int bufferSize) { instruction->params = b; instruction->paramCount = 1; break; - case 1283: + + case 1042: instruction->opCode = RET; instruction->params = NULL; instruction->paramCount = 0; break; + + case 865: + instruction->opCode = STACK_SAVE; + instruction->params = NULL; + instruction->paramCount = 0; + break; + + case 572: + instruction->opCode = STACK_LOAD; + instruction->params = NULL; + instruction->paramCount = 0; + break; + + case 3237: + instruction->opCode = STACK_FREE_FUNC; + instruction->params = NULL; + instruction->paramCount = 0; + break; + + case 745: + instruction->opCode = QUAD_SET; + b = malloc(sizeof(void*) * 2); + + parseVariableName(b, 0, buff[1]); + parseInt32(b, 1, buff[2]); + + instruction->params = b; + instruction->paramCount = 2; + break; + + case 2397: + instruction->opCode = DUO_SET; + b = malloc(sizeof(void*) * 2); + + parseVariableName(b, 0, buff[1]); + parseInt32(b, 1, buff[2]); + + instruction->params = b; + instruction->paramCount = 2; + break; + + case 3398: + instruction->opCode = OCT_SET; + b = malloc(sizeof(void*) * 2); + + parseVariableName(b, 0, buff[1]); + parseInt32(b, 1, buff[2]); + + instruction->params = b; + instruction->paramCount = 2; + + case 2087: + instruction->opCode = PTR_DEC; + b = malloc(sizeof(void*) * 2); + + parseVariableName(b, 0, buff[1]); + parseInt32(b, 1, buff[2]); + + instruction->params = b; + instruction->paramCount = 2; + break; + + case 2137: + instruction->opCode = PTR_DEC_OFF; + b = malloc(sizeof(void*) * 3); + + parseVariableName(b, 0, buff[1]); + parseVariableName(b, 1, buff[2]); + parseVariableName(b, 2, buff[3]); + + instruction->params = b; + instruction->paramCount = 3; + break; + default: printf("Error: Unknown instruction %s!\n", buff[0]); return NULL; From 2a6ac97088061cc9f397c86f1233f60e7e594210 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 17 Jan 2025 13:34:52 +0100 Subject: [PATCH 21/26] feat: added fast_strcat --- src/parser/asts/functions.c | 23 ++++++++++++++++++++++- src/utils/string.c | 23 +++++++++++++++++++++++ src/utils/string.h | 17 +++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/utils/string.c create mode 100644 src/utils/string.h diff --git a/src/parser/asts/functions.c b/src/parser/asts/functions.c index 662f83f..d545e3c 100644 --- a/src/parser/asts/functions.c +++ b/src/parser/asts/functions.c @@ -98,11 +98,32 @@ AST_ASM_FUNCTION_DEC* parseASMFunctionDeclaration(LEXER_RESULT result, int index index = func->endingIndex; - if(result.tokens[index + 1].type != BRACKETS_OPEN || result.tokens[index + 2].type != STRING || result.tokens[index + 3].type != BRACKETS_CLOSE) { + if(result.tokens[index + 1].type != BRACKETS_OPEN) { printf("Error: Badly made ASM function body!\n"); return NULL; } + + int allocated = 1024; + + index += 2; + for(; index < result.size; ++index) { + TOKEN t = result.tokens[index]; + + if(t.type == BRACKETS_CLOSE) { + func->buffIndex = strlen(func->buff); + return func; + } + else if(t.type == STRING) { + + } + else { + printf("Error: disallowed token in ASM function! Only string are allowed in body!\n"); + return NULL; + } + + } + func->buff = result.tokens[index + 2].value; func->buffIndex = strlen(func->buff); diff --git a/src/utils/string.c b/src/utils/string.c new file mode 100644 index 0000000..2f29174 --- /dev/null +++ b/src/utils/string.c @@ -0,0 +1,23 @@ +/** + * String related utilities. + */ + +/** + * Adds a char array (string) into another one. + * @param output the output string. + * @param input the input string. + * @param index the starting index. + * @return the last index. + */ +int fast_strcat(char* output, char* input, int index) { + char c; + while(c = *input++) { + output[index] = c; + + if(c == '\0') return index; + + index++; + } + + return index; +} \ No newline at end of file diff --git a/src/utils/string.h b/src/utils/string.h new file mode 100644 index 0000000..0c39e29 --- /dev/null +++ b/src/utils/string.h @@ -0,0 +1,17 @@ +/** + * String related utilities. + */ + +#ifndef STRING_UTILS_H +#define STRING_UTILS_H + +/** + * Adds a char array (string) into another one. + * @param output the output string. + * @param input the input string. + * @param index the starting index. + * @return the last index. + */ +int fast_strcat(char* output, char* input, int index); + +#endif \ No newline at end of file From afb1ea2a797914e2a23dff7c9d9e81643ea269be Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 17 Jan 2025 13:37:56 +0100 Subject: [PATCH 22/26] feat: changed how ast parses ASM functions --- src/parser/asts/functions.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/parser/asts/functions.c b/src/parser/asts/functions.c index d545e3c..8a83bfc 100644 --- a/src/parser/asts/functions.c +++ b/src/parser/asts/functions.c @@ -15,6 +15,8 @@ #include "../../lexer/lexer.h" +#include "../../utils/string.h" + /** * Parses a function declaration into AST. * @param result the Lexer result. @@ -104,18 +106,26 @@ AST_ASM_FUNCTION_DEC* parseASMFunctionDeclaration(LEXER_RESULT result, int index } - int allocated = 1024; + int allocatedBuff = 512; + + func->buff = malloc(allocatedBuff); + func->buffIndex = 0; index += 2; for(; index < result.size; ++index) { TOKEN t = result.tokens[index]; if(t.type == BRACKETS_CLOSE) { - func->buffIndex = strlen(func->buff); return func; } else if(t.type == STRING) { - + func->buffIndex = fast_strcat(func->buff, t.value, func->buffIndex); + + if(func->buffIndex >= allocatedBuff) { + allocatedBuff *= 1.5; + func->buff = realloc(func->buff, allocatedBuff); + } + } else { printf("Error: disallowed token in ASM function! Only string are allowed in body!\n"); @@ -124,9 +134,6 @@ AST_ASM_FUNCTION_DEC* parseASMFunctionDeclaration(LEXER_RESULT result, int index } - func->buff = result.tokens[index + 2].value; - func->buffIndex = strlen(func->buff); - return func; } From 2e8b21ca87dc3e19d63ac494be7af882da238c16 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 17 Jan 2025 13:41:12 +0100 Subject: [PATCH 23/26] feat: seperated the instructions in asm func parsing --- src/parser/asts/functions.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/parser/asts/functions.c b/src/parser/asts/functions.c index 8a83bfc..db14f75 100644 --- a/src/parser/asts/functions.c +++ b/src/parser/asts/functions.c @@ -119,7 +119,8 @@ AST_ASM_FUNCTION_DEC* parseASMFunctionDeclaration(LEXER_RESULT result, int index return func; } else if(t.type == STRING) { - func->buffIndex = fast_strcat(func->buff, t.value, func->buffIndex); + func->buffIndex = fast_strcat(func->buff, t.value, func->buffIndex) + 1; // Adds one to the index to keep the seperator. + func->buff[func->buffIndex - 1] = '\n'; if(func->buffIndex >= allocatedBuff) { allocatedBuff *= 1.5; From f344aefc46000f1c82f9260e8ac91e866ecb9ef1 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 17 Jan 2025 16:42:16 +0100 Subject: [PATCH 24/26] feat: fixed a few things --- src/cli/main.c | 4 ---- src/compiler/win64.c | 9 +++------ src/ir/irs/functions.c | 5 +++++ src/lexer/lexer.c | 10 ++++++++-- src/parser/asts/functions.c | 5 ++++- src/qasm/parser/parser.c | 6 ++++++ src/qasm/parser/values.c | 6 +++++- src/utils/hash.c | 5 ++++- src/utils/hash.h | 1 + 9 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/cli/main.c b/src/cli/main.c index 8e37b37..3ad8067 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -132,10 +132,6 @@ int main(int argc, char* argv[]) { BYTECODE_BUFFER* buffer = compile(irOut); - for(int i = 0; i < buffer->size; ++i) { - printf("0x%x ",buffer->buff[i]); - } - compilePE(fptr, buffer); fclose(fptr); diff --git a/src/compiler/win64.c b/src/compiler/win64.c index cfd40e2..06df782 100644 --- a/src/compiler/win64.c +++ b/src/compiler/win64.c @@ -20,6 +20,7 @@ * @param instruction the instruction to convert. */ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUCTION* instruction) { + switch(instruction->opCode) { case RET: buff->buff[buff->size] = 0xC3; @@ -189,10 +190,6 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC case LOGICAL_BLOCK_SWAP: int trueBlockId = (((unsigned char*)instruction->params[0])[0] << 24) | (((unsigned char*)instruction->params[0])[1] << 16) | (((unsigned char*)instruction->params[0])[2] << 8) | ((unsigned char*)instruction->params[0])[3]; int falseBlockId = (((unsigned char*)instruction->params[1])[0] << 24) | (((unsigned char*)instruction->params[1])[1] << 16) | (((unsigned char*)instruction->params[1])[2] << 8) | ((unsigned char*)instruction->params[1])[3]; - - int* trueBlockPtr = ctx->blockOffsets[trueBlockId]; - int* falseBlockPtr = ctx->blockOffsets[falseBlockId]; - // Instead of doing if else, just jump to the block if true and continue if not @@ -205,10 +202,10 @@ void compileInstruction(BYTECODE_BUFFER* buff, COMPILER_CONTEXT* ctx, IR_INSTRUC buff->buff[buff->size + 3] = 0x01; buff->buff[buff->size + 4] = 0x74; - buff->buff[buff->size + 5] = (*trueBlockPtr - buff->size) & 0xFF; + buff->buff[buff->size + 5] = (ctx->blockOffsets[trueBlockId] - buff->size) & 0xFF; // else - off = *falseBlockPtr - buff->size; + off = ctx->blockOffsets[falseBlockId] - buff->size; buff->buff[buff->size + 6] = off & 0xFF; buff->buff[buff->size + 7] = (off >> 8) & 0xFF; diff --git a/src/ir/irs/functions.c b/src/ir/irs/functions.c index c38c5e7..dab3f69 100644 --- a/src/ir/irs/functions.c +++ b/src/ir/irs/functions.c @@ -67,6 +67,8 @@ void parseFunction(IR_OUTPUT* out, AST_FUNCTION_DEC* node) { appendInstruction(out->blocks[out->blockCount], STACK_LOAD, NULL, 0); appendInstruction(out->blocks[out->blockCount], RET, NULL, 0); + + out->blockCount++; } /** @@ -86,6 +88,9 @@ void parseASMFunction(IR_OUTPUT* out, AST_ASM_FUNCTION_DEC* node) { out->blocks[out->blockCount] = malloc(sizeof(IR_BASIC_BLOCK)); out->blocks[out->blockCount]->instructions = NULL; out->blocks[out->blockCount]->instructionCount = 0; + out->blocks[out->blockCount]->allocatedSize = 0; parseQAsmInstructions(out->blocks[out->blockCount], node->buff, node->buffIndex); + + out->blockCount++; } \ No newline at end of file diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 59ac382..4d75f5f 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -63,13 +63,19 @@ LEXER_RESULT runLexer(char* string, int size) { } else if (c == '\"') { int strLen = 0; - while(c != '\"') { + ++i; + c = string[i]; + + while(c != '\"' && c != '\0') { buff[strLen] = c; strLen++; ++i; c = string[i]; - } + } + + buff[strLen] = '\0'; + ++i; pushToken(&result, STRING); result.tokens[result.size - 1].value = buff; diff --git a/src/parser/asts/functions.c b/src/parser/asts/functions.c index db14f75..5fb68d6 100644 --- a/src/parser/asts/functions.c +++ b/src/parser/asts/functions.c @@ -116,6 +116,7 @@ AST_ASM_FUNCTION_DEC* parseASMFunctionDeclaration(LEXER_RESULT result, int index TOKEN t = result.tokens[index]; if(t.type == BRACKETS_CLOSE) { + func->endingIndex = index; return func; } else if(t.type == STRING) { @@ -129,12 +130,14 @@ AST_ASM_FUNCTION_DEC* parseASMFunctionDeclaration(LEXER_RESULT result, int index } else { - printf("Error: disallowed token in ASM function! Only string are allowed in body!\n"); + printf("Error: disallowed token %d in ASM function! Only string are allowed in body!\n", t.type); + printf("%s", t.value); return NULL; } } + func->endingIndex = index; return func; } diff --git a/src/qasm/parser/parser.c b/src/qasm/parser/parser.c index 67c2545..ef6354e 100644 --- a/src/qasm/parser/parser.c +++ b/src/qasm/parser/parser.c @@ -38,6 +38,12 @@ void parseQAsmInstructions(IR_BASIC_BLOCK* block, char* buffer, int size) { if(c == '\0') return; if(c == '\n') { + if(secIndex != 0) { + ((char*)buff[buffIndex])[secIndex] = '\0'; + secIndex = 0; + buffIndex++; + } + IR_INSTRUCTION* instruction = parseInstruction(buff, buffIndex); if(instruction == NULL) { diff --git a/src/qasm/parser/values.c b/src/qasm/parser/values.c index 48b3e9f..56c2cd4 100644 --- a/src/qasm/parser/values.c +++ b/src/qasm/parser/values.c @@ -36,5 +36,9 @@ void parseVariableName(void** buff, int index, char* str) { return; } - buff[index] = (str + 1); + int size = strlen(str); + buff[index] = malloc(size); + + memccpy(buff[index], str, 1, size); + ((char*)buff[index])[size] = '\0'; } \ No newline at end of file diff --git a/src/utils/hash.c b/src/utils/hash.c index 9572982..db6857f 100644 --- a/src/utils/hash.c +++ b/src/utils/hash.c @@ -7,7 +7,10 @@ unsigned int hashstr(char* str) { unsigned char *p = (unsigned char *)str; while (*p) { - hash ^= *p++; + char c = *p++; + if(c == '\0') break; + + hash ^= c; hash *= 16777619u; // FNV prime hash &= 0x0FFF; // Keep only 12 bits to maintain smaller values } diff --git a/src/utils/hash.h b/src/utils/hash.h index 50e1340..4278472 100644 --- a/src/utils/hash.h +++ b/src/utils/hash.h @@ -1,6 +1,7 @@ #ifndef HASH_UTILS #define HASH_UTILS + /** * Hashes the string. */ From 117cbe825910ee5882471d0b115913b62f372545 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 17 Jan 2025 19:50:18 +0100 Subject: [PATCH 25/26] feat: final touches before merge --- src/ir/irs/values.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ir/irs/values.c b/src/ir/irs/values.c index bb233c5..58ea9fb 100644 --- a/src/ir/irs/values.c +++ b/src/ir/irs/values.c @@ -78,8 +78,6 @@ unsigned char* getByteEquivalent(void* value) { int num = atoi(val->value); - printf("%d", num); - unsigned char* buff = malloc(4); buff[0] = (num >> 24) & 0xFF; From 5271207c752fd8c7713adce8fc6bb82140f0753d Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 17 Jan 2025 20:17:51 +0100 Subject: [PATCH 26/26] fix: benchmarks --- benchmarks/main.c | 116 ++++++++++++++++++++++++++------------------- src/lexer/lexer.c | 3 +- src/lexer/lexer.h | 42 +++++++++++++++- src/lexer/tokens.h | 43 ----------------- 4 files changed, 107 insertions(+), 97 deletions(-) delete mode 100644 src/lexer/tokens.h diff --git a/benchmarks/main.c b/benchmarks/main.c index 0de2352..0a31a77 100644 --- a/benchmarks/main.c +++ b/benchmarks/main.c @@ -8,10 +8,17 @@ #include #include -#include "../src/lexer/lexer.h" +#include "../src/compiler/compiler.h" +#include "../src/compiler/structs.h" +#include "../src/compiler/pe/pe.h" + +#include "../src/ir/ir.h" +#include "../src/ir/instructions.h" +#include "../src/ir/structs.h" + #include "../src/parser/parser.h" +#include "../src/parser/structs/tree.h" #include "../src/parser/ast.h" -#include "../src/compiler/compiler.h" #include "../src/utils/logging.c" // Benchmark Settings @@ -91,18 +98,18 @@ void main(int argc, char* argv[]) { runs = atoi(argv[2]); } - char* c[5] = {"File IO (Open)", "Lexer", "Parser", "Compiler", "File IO (Close)"}; + char* c[6] = {"File IO (Open)", "Lexer", "AST", "IR", "Compiler", "Artifact Generator"}; categories = c; - for(int i = 0; i < 5; ++i) { - stats[i].total = 0; - stats[i].max = 0; - stats[i].low = 1000000; - stats[i].runs = malloc(sizeof(double) * runs); + for(int i = 0; i < 6; ++i) { + stats[i].total = 0; + stats[i].max = 0; + stats[i].low = 1000000; + stats[i].runs = malloc(sizeof(double) * runs); - for(int ii = 0; ii < runs; ++ii) { - stats[i].runs[ii] = 0; - } + for(int ii = 0; ii < runs; ++ii) { + stats[i].runs[ii] = 0; + } } for(int i = 0; i < runs; ++i) { @@ -117,7 +124,7 @@ void main(int argc, char* argv[]) { char* buff = (char*)malloc(size + 1); fread(buff, 1, size, fptr); - buff[size] = '\0'; + buff[size] = '\0'; fclose(fptr); endTimer(i, 0); @@ -125,68 +132,77 @@ void main(int argc, char* argv[]) { LEXER_RESULT result = runLexer(buff, size); - free(buff); + free(buff); endTimer(i, 1); startTimer(); - AST_NODE* node = parseNodes(result, 0, AST_ROOT); + void* node = parseRoot(result, 0, AST_TYPE_ROOT); endTimer(i, 2); startTimer(); - fptr = fopen("output.txt", "w"); + IR_OUTPUT* out = parseIR((AST_TREE_BRANCH*)node); - IR_CTX* ctx = makeContext(node); - compile(ctx, fptr); + endTimer(i, 3); + startTimer(); - fclose(fptr); + BYTECODE_BUFFER* b = compile(out); - endTimer(i, 3); + endTimer(i, 4); + startTimer(); + + fptr = fopen("output.exe", "w"); + compilePE(fptr, b); + + fclose(fptr); + + endTimer(i, 5); } printf("========= Benchmarking Results =========\n"); printf("Total time taken: %.3f micros, Average time per run: %.3f\n micros\n\n", totalTimeTaken, totalTimeTaken / runs); - for(int i = 0; i < 5; ++i) { - printf("Benchmarking Results of %s:\n", categories[i]); - printf(" Total time duration: %s%.2fus%s (%s%.1f%%%s over total running time)\n", TEXT_HCYAN, stats[i].total, RESET, TEXT_CYAN, (stats[i].total / totalTimeTaken) * 100, RESET); - printf(" Average: %s%.2fus%s\n", TEXT_HCYAN, stats[i].total / runs, RESET); - printf(" Range (%sFastest%s, %sLowest%s): %s%0.fus%s ... %s%.2fus%s\n\n", TEXT_HGREEN, RESET, TEXT_HRED, RESET, TEXT_HGREEN, stats[i].low, RESET, TEXT_HRED, stats[i].max, RESET); + + for(int i = 0; i < 6; ++i) { + printf("Benchmarking Results of %s:\n", categories[i]); + printf(" Total time duration: %s%.2fus%s (%s%.1f%%%s over total running time)\n", TEXT_HCYAN, stats[i].total, RESET, TEXT_CYAN, (stats[i].total / totalTimeTaken) * 100, RESET); + printf(" Average: %s%.2fus%s\n", TEXT_HCYAN, stats[i].total / runs, RESET); + printf(" Range (%sFastest%s, %sLowest%s): %s%0.fus%s ... %s%.2fus%s\n\n", TEXT_HGREEN, RESET, TEXT_HRED, RESET, TEXT_HGREEN, stats[i].low, RESET, TEXT_HRED, stats[i].max, RESET); - double averages[10]; - double highestAverage = 0; + double averages[10]; + double highestAverage = 0; - for(int ii = 0; ii < 10; ++ii) { - averages[ii] = 0; - } + for(int ii = 0; ii < 10; ++ii) { + averages[ii] = 0; + } - for(int ii = 0; ii < runs; ++ii) { - averages[ii / 10] += stats[i].runs[ii] / 10; - } + for(int ii = 0; ii < runs; ++ii) { + averages[ii / 10] += stats[i].runs[ii] / 10; + } - for(int ii = 0; ii < 10; ++ii) { - if(averages[ii] > highestAverage) highestAverage = averages[ii]; - } + for(int ii = 0; ii < 10; ++ii) { + if(averages[ii] > highestAverage) highestAverage = averages[ii]; + } - char spacing[3]; + char spacing[3]; - for(int ii = 0; ii < 10; ++ii) { - spacing[0] = '\0'; - if(ii == 0) strcat(spacing, " \0"); - else if(ii != 9) strcat(spacing, " \0"); + for(int ii = 0; ii < 10; ++ii) { + spacing[0] = '\0'; + if(ii == 0) strcat(spacing, " \0"); + else if(ii != 9) strcat(spacing, " \0"); - int clean = (averages[ii] / highestAverage) * BENCH_BAR_LENGTH; + int clean = (averages[ii] / highestAverage) * BENCH_BAR_LENGTH; - printf(" %d%% to %d%% Percentile:%s%s ", ii * 10, (ii + 1) * 10, spacing, TEXT_GRAY); - for(int c = 0; c < clean; ++c) { - printf("#"); - } - printf("%s (%s%.2fus%s average)\n", RESET, TEXT_HCYAN, averages[ii], RESET); - } + printf(" %d%% to %d%% Percentile:%s%s ", ii * 10, (ii + 1) * 10, spacing, TEXT_GRAY); + for(int c = 0; c < clean; ++c) { + printf("#"); + } + printf("%s (%s%.2fus%s average)\n", RESET, TEXT_HCYAN, averages[ii], RESET); + } - double timeWithoutHighest = stats[i].total - highestAverage * 10; - printf("\n Total time duration without highest avg: %s%.1fus%s (%s%.1f%%%s over total running time)", TEXT_HCYAN, timeWithoutHighest, RESET, TEXT_CYAN, (timeWithoutHighest / totalTimeTaken) * 100, RESET); - printf("\n Average without highest avg: %s%.2fus%s\n\n", TEXT_HCYAN, (timeWithoutHighest / runs), RESET); + double timeWithoutHighest = stats[i].total - highestAverage * 10; + printf("\n Total time duration without highest avg: %s%.1fus%s (%s%.1f%%%s over total running time)", TEXT_HCYAN, timeWithoutHighest, RESET, TEXT_CYAN, (timeWithoutHighest / totalTimeTaken) * 100, RESET); + printf("\n Average without highest avg: %s%.2fus%s\n\n", TEXT_HCYAN, (timeWithoutHighest / runs), RESET); } } diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 4d75f5f..ce915a7 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -8,13 +8,12 @@ #include #include "./lexer.h" -#include "./tokens.h" /** * Sets the token type of the currently selected token in the LexerResult with the provided token type. */ -void pushToken(LEXER_RESULT* result, TOKEN_TYPE type) { +void pushToken(LEXER_RESULT* result, LEXER_TOKEN_TYPE type) { result->tokens[result->size].type = type; result->size++; } diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index 61bb123..959c297 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -2,7 +2,45 @@ #define LEXER_H #include -#include "./tokens.h" + +typedef enum { + ASM_FUNCTION, + FUNCTION, + RETURN, + VAR, + BRACKETS_OPEN, + BRACKETS_CLOSE, + PAREN_OPEN, + PAREN_CLOSE, + ARRAY_OPEN, + ARRAY_CLOSE, + NUMBER, + STRING, + BOOLEAN_VALUE, + NU, + KEYWORD, + SEMICOLON, + COMMA, + DECLARE, + USE, + NONE, + MATH_OP, + + TYPE_INT32, + TYPE_INT24, + TYPE_INT16, + TYPE_INT8, + TYPE_BIT +} LEXER_TOKEN_TYPE; + +/** + * An lexer token generated by the Lexer. + */ +typedef struct { + LEXER_TOKEN_TYPE type; + char* value; +} TOKEN; + /** * Contains the results of lexical analysis @@ -23,6 +61,6 @@ LEXER_RESULT runLexer(char* input, int size); * @param result The LexerResult to add the token to * @param type The type of the token to add */ -void pushToken(LEXER_RESULT* result, TOKEN_TYPE type); +void pushToken(LEXER_RESULT* result, LEXER_TOKEN_TYPE type); #endif diff --git a/src/lexer/tokens.h b/src/lexer/tokens.h deleted file mode 100644 index 68b20ab..0000000 --- a/src/lexer/tokens.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef TOKENS_H -#define TOKENS_H - -typedef enum { - ASM_FUNCTION, - FUNCTION, - RETURN, - VAR, - BRACKETS_OPEN, - BRACKETS_CLOSE, - PAREN_OPEN, - PAREN_CLOSE, - ARRAY_OPEN, - ARRAY_CLOSE, - NUMBER, - STRING, - BOOLEAN_VALUE, - NU, - KEYWORD, - SEMICOLON, - COMMA, - DECLARE, - USE, - NONE, - MATH_OP, - - TYPE_INT32, - TYPE_INT24, - TYPE_INT16, - TYPE_INT8, - TYPE_BIT -} TOKEN_TYPE; - -/** - * An lexer token generated by the Lexer. - */ -typedef struct { - TOKEN_TYPE type; - char* value; -} TOKEN; - - -#endif