Skip to content
This repository was archived by the owner on Jul 19, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9b33213
feat: added bytecode buffer struct & win64 header
Zffu Jan 10, 2025
ed5432b
feat: added new stack instructions
Zffu Jan 10, 2025
45f175a
feat: started working on qasm -> win64
Zffu Jan 10, 2025
0a6f952
feat: finished adding basic win64 bytecodes
Zffu Jan 10, 2025
e333eb8
feat: added support for basic instructions
Zffu Jan 10, 2025
a60c07a
feat: added qd_set qasm instruction and changed ptr_set to singleton …
Zffu Jan 10, 2025
321e3bb
feat: added dd_set and od_set
Zffu Jan 10, 2025
77aeca0
feat: added ptr_dec instruction
Zffu Jan 10, 2025
d2feda9
feat: added support for int8, int16 and int24
Zffu Jan 10, 2025
dc6759a
feat: added BLOCK_SWAP win support
Zffu Jan 10, 2025
099eabe
feat: added bit/boolean type in lexer
Zffu Jan 11, 2025
fc27181
feat: added ir support for boolean/bit variables
Zffu Jan 11, 2025
29d17e2
feat: added parsing support for bit type
Zffu Jan 11, 2025
dcef702
fix: fixed wrong func name
Zffu Jan 11, 2025
b054884
feat: misc fixes and removed debugging instructions
Zffu Jan 11, 2025
afa06aa
feat: added multi blocks support
Zffu Jan 11, 2025
dfd3db0
fix: fixed incorrect index offset during buff modification
Zffu Jan 13, 2025
686c3f9
feat: dropped old unused function
Zffu Jan 17, 2025
46c699c
feat: [experimental] changed hash algorithm to remove collissions
Zffu Jan 17, 2025
505a342
feat: [experimental] changed hashes for new algorithm and added new i…
Zffu Jan 17, 2025
2a6ac97
feat: added fast_strcat
Zffu Jan 17, 2025
afb1ea2
feat: changed how ast parses ASM functions
Zffu Jan 17, 2025
2e8b21c
feat: seperated the instructions in asm func parsing
Zffu Jan 17, 2025
f344aef
feat: fixed a few things
Zffu Jan 17, 2025
117cbe8
feat: final touches before merge
Zffu Jan 17, 2025
5271207
fix: benchmarks
Zffu Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 66 additions & 50 deletions benchmarks/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@
#include <windows.h>
#include <math.h>

#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
Expand Down Expand Up @@ -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) {
Expand All @@ -117,76 +124,85 @@ 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);
startTimer();

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);
}
}
10 changes: 8 additions & 2 deletions src/cli/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

#include "../qasm/writer/writer.h"

#include "../compiler/structs.h"

#include "../utils/logging.c"

// Version
Expand Down Expand Up @@ -128,8 +130,12 @@ int main(int argc, char* argv[]) {

fptr = fopen(outputFile, "w");

writeQASM(fptr, irOut); // experimental: ir -> QASM

BYTECODE_BUFFER* buffer = compile(irOut);

compilePE(fptr, buffer);

fclose(fptr);

break;
case 'v':
if(strlen(argv[1]) > 1 && strcmp(argv[1], "version") != 0) {
Expand Down
36 changes: 31 additions & 5 deletions src/compiler/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,40 @@
#include <stdio.h>
#include <stdlib.h>

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

ctx->blockOffsets = malloc(sizeof(int) * out->blockCount);

for(int blockIndex = 0; blockIndex < out->blockCount; ++blockIndex) {
ctx->blockOffsets[blockIndex] = buff->size;

for(int i = 0; i < out->blocks[blockIndex]->instructionCount; ++i) {
compileInstruction(buff, ctx, out->blocks[blockIndex]->instructions[i]);
}
}

return buff;
}
11 changes: 7 additions & 4 deletions src/compiler/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 4 additions & 3 deletions src/compiler/pe/pe.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
#include <stdint.h>

#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);
Expand Down Expand Up @@ -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

Expand All @@ -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);
}
4 changes: 3 additions & 1 deletion src/compiler/pe/pe.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
#include <stdio.h>
#include <stdint.h>

#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
38 changes: 38 additions & 0 deletions src/compiler/structs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Structures used by the Quickfall compiler.
*/

#include "../utils/hashmap.h"

#include <stdint.h>

#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;
int currStack;

int* blockOffsets;

} COMPILER_CONTEXT;


#endif
Loading
Loading