Skip to content

Commit

Permalink
Merge pull request #39 from Quickfall/comp
Browse files Browse the repository at this point in the history
Compiler V3
  • Loading branch information
Zffu authored Dec 23, 2024
2 parents 9cee137 + f99bc8a commit 25d1634
Show file tree
Hide file tree
Showing 20 changed files with 519 additions and 41 deletions.
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,13 @@ prepare_build:
@echo [INFO] Using "${COMPILER}" as a compiler!
@echo [INFO] Detected current operating system as ${DETECTED_OS}
$(CHECK_COMMANDS)
@echo [INFO] Clearing old builds
@echo [INFO] Starting building logic

clean:
$(RM) build
$(RM) $(TARGET)
$(RM) $(TEST_TARGET)
$(RM) $(BENCH_TARGET)
@echo [INFO] Starting building logic

$(TARGET):
$(COMPILER) $(FLAGS) $(SOURCES) src/cli/main.c -o $(TARGET)
Expand Down
18 changes: 6 additions & 12 deletions benchmarks/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ void main(int argc, char* argv[]) {
endTimer(i, 0);
startTimer();

struct LexerResult result = runLexer(buff);
struct LexerResult result = runLexer(buff, size);

free(buff);

Expand All @@ -136,20 +136,14 @@ void main(int argc, char* argv[]) {
endTimer(i, 2);
startTimer();

struct Context ctx = parseContext(node);
char* compiled = compileV2(ctx);
fptr = fopen("output.txt", "w");

endTimer(i, 3);

startTimer();

fptr = fopen("output.txt", "w");
fprintf(fptr, compiled);
fclose(fptr);
IR_CTX* ctx = makeContext(node);
compile(ctx, fptr);

endTimer(i, 4);
fclose(fptr);

free(compiled);
endTimer(i, 3);
}

printf("========= Benchmarking Results =========\n");
Expand Down
14 changes: 11 additions & 3 deletions src/cli/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,25 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "../lexer/lexer.h"

#include "../parser/ast.h"
#include "../parser/parser.h"

#include "../compiler/compiler.h"
#include "../compiler/pe/pe.h"
#include "../compiler/ir.h"

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

// Version
#define VERSION "0.1.0"

uint8_t code_section[6] = {
0xB8, 0x4C, 0x00, 0x00, 0x00, 0xC3
};

void showCommandEntry(char* commandName, char* description, int argumentCount, char* argumentNames[], char* argumentDescriptions[]) {
printf("\n > %s\n\n %s%sDescription%s: %s\n", commandName, STYLE_BOLD, STYLE_UNDERLINE, RESET, description);
Expand Down Expand Up @@ -108,11 +113,11 @@ int main(int argc, char* argv[]) {

char* buff = malloc(size + 1); // Allocates one more byte for the \0 char.

fread(buff, 1, size, fptr);
size = fread(buff, 1, size, fptr);
buff[size] = '\0';
fclose(fptr);

struct LexerResult result = runLexer(buff);
struct LexerResult result = runLexer(buff, size);
struct ASTNode* root = parseNodes(result, 0, AST_ROOT);

IR_CTX* ctx = makeContext(root);
Expand All @@ -122,7 +127,10 @@ int main(int argc, char* argv[]) {
return -1;
}

compile(ctx, outputFile);
fptr = fopen(outputFile, "w");
compile(ctx, fptr);

//compilePE(fptr, code_section, sizeof(code_section));

break;
case 'v':
Expand Down
68 changes: 60 additions & 8 deletions src/compiler/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* The compiler of Quickfall.
*/

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

Expand All @@ -13,6 +14,8 @@
#include "../utils/hash.h"
#include "../utils/hashmap.h"

#include "./pe/pe.h"

/**
* Parses the AST tree into a context.
* @param tree the AST tree.
Expand All @@ -26,9 +29,7 @@ IR_CTX* makeContext(AST_NODE* tree) {
ctx->nodeIndex = 0;
ctx->nodeMap = createHashmap(512,200);

while(tree->next != NULL) {
tree = tree->next;

while(tree != NULL) {
switch(tree->type) {
case AST_VARIABLE_DECLARATION:

Expand Down Expand Up @@ -59,10 +60,10 @@ IR_CTX* makeContext(AST_NODE* tree) {

case AST_FUNCTION_DECLARATION:

hash = hashstr(tree->left->value);
hash = hashstr(tree->left->right->value);

if(hashGet(ctx->nodeMap, hash) != NULL) {
printf("Function %s was already declared!\n", tree->left->value);
printf("Function %s was already declared!\n", tree->left->right->value);
return NULL;
}

Expand All @@ -77,18 +78,20 @@ IR_CTX* makeContext(AST_NODE* tree) {
node->variables[node->variableIndex] = var;
node->variableIndex++;

hashPut(node->variableMap, hashstr(tree->right->value), var);
hashPut(node->variableMap, hashstr(tree->left->left->right->value), var);

tree->left->left = tree->left->left->next;
}

node->tree = tree->right;

ctx->nodes[ctx->nodeIndex] = node;
ctx->nodeIndex++;

hashPut(ctx->nodeMap, hash, node);
break;

case AST_ASM_FUNCTION_DECLARATION:

hash = hashstr(tree->left->right->value);

if(hashGet(ctx->nodeMap, hash) != NULL) {
Expand All @@ -99,6 +102,7 @@ IR_CTX* makeContext(AST_NODE* tree) {
node = createIRNode(IR_ASM_FUNCTION, tree->left->right->value);

node->value = tree->value;
node->valueSize = tree->valueSize;

while(tree->left->left->next != NULL) {

Expand All @@ -121,6 +125,8 @@ IR_CTX* makeContext(AST_NODE* tree) {
break;

}

tree = tree->next;
}

return ctx;
Expand All @@ -131,6 +137,52 @@ IR_CTX* makeContext(AST_NODE* tree) {
* @param ctx the IR context.
* @param char the output file name.
*/
void compile(IR_CTX* ctx, char* outputFileName) {
void compile(IR_CTX* ctx, FILE* out) {

uint8_t* buff = malloc(sizeof(uint8_t) * 512);
int i = 0;

int h = hashstr("main");

if(hashGet(ctx->nodeMap, h) == NULL) {
printf("Error: the main function wasn't defined!\n");
return;
}

IR_NODE* node = hashGet(ctx->nodeMap, h);

if(node->nodeType != IR_FUNCTION) {
printf("Error: main must be a function!\n");
return;
}

while(node->tree != NULL) {

if(node->tree->type == AST_FUNCTION_INVOKE) {

int hash = hashstr(node->tree->value);

IR_NODE* wa = hashGet(ctx->nodeMap, hash);

if(wa == NULL) {
printf("Error: The %s function doesn't exist!\n", node->tree->value);
return;
}

if(wa->nodeType == IR_ASM_FUNCTION) {
unsigned char b;
unsigned char* ptr = (unsigned char*) wa->value;

for(int ii = 0; ii < wa->valueSize; ++ii) {
buff[i] = ptr[ii];
++i;
}
}
}

node->tree = node->tree->next;
}

//todo: change format based on user
compilePE(out, buff, i);
}
4 changes: 2 additions & 2 deletions src/compiler/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ IR_CTX* makeContext(AST_NODE* tree);
/**
* Compiles the Context tree to an executable named the provided name.
* @param ctx the IR context.
* @param char the output file name.
* @param char the output file.
*/
void compile(IR_CTX* ctx, char* outputFileName);
void compile(IR_CTX* ctx, FILE* outputFileName);

#endif
6 changes: 5 additions & 1 deletion src/compiler/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ struct IRNode {
char* type;

// Variable Properties
char* value;
void* value;
int valueSize;

// Function Properties
struct IRNode** variables;
Expand All @@ -49,6 +50,9 @@ struct IRContext {
int nodeIndex;

struct Hashmap* nodeMap;

IR_NODE* mainFunc;

};

typedef struct IRContext IR_CTX;
Expand Down
110 changes: 110 additions & 0 deletions src/compiler/pe/format.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**
* Quickfall PE Format Defintion.
*/

#include "../units.h"

#ifndef PE_FORMAT
#define PE_FORMAT

/**
* Constants.
*/

#define PE_HEADER_SIGNATURE 0x00004550
#define PE_DOS_HDR_SZ 0x40

/**
* Structures.
*/

#pragma pack(push, 1)

typedef struct {
uint16_t e_magic;
uint16_t e_cblp;
uint16_t e_cp;
uint16_t e_crlc;
uint16_t e_cparhdr;
uint16_t e_minalloc;
uint16_t e_maxalloc;
uint16_t e_ss;
uint16_t e_sp;
uint16_t e_csum;
uint16_t e_ip;
uint16_t e_cs;
uint16_t e_lfarlc;
uint16_t e_ovno;
uint16_t e_res[4];
uint16_t e_oemid;
uint16_t e_oeminfo;
uint16_t e_res2[10];
uint32_t e_lfanew;
} PE_DOS_HEADER;

typedef struct {
uint32_t Signature;
uint16_t Machine;
uint16_t NumberOfSections;
uint32_t TimeDateStamp;
uint32_t PointerToSymbolTable;
uint32_t NumberOfSymbols;
uint16_t SizeOfOptionalHeader;
uint16_t Characteristics;
} PE_NT_HEADERS;

typedef struct {
uint16_t Magic;
uint8_t MajorLinkerVersion;
uint8_t MinorLinkerVersion;
uint32_t SizeOfCode;
uint32_t SizeOfInitializedData;
uint32_t SizeOfUninitializedData;
uint32_t AddressOfEntryPoint;
uint32_t BaseOfCode;
uint64_t ImageBase;
uint32_t SectionAlignment;
uint32_t FileAlignment;
uint16_t MajorOperatingSystemVersion;
uint16_t MinorOperatingSystemVersion;
uint16_t MajorImageVersion;
uint16_t MinorImageVersion;
uint16_t MajorSubsystemVersion;
uint16_t MinorSubsystemVersion;
uint32_t Win32VersionValue;
uint32_t SizeOfImage;
uint32_t SizeOfHeaders;
uint32_t CheckSum;
uint16_t Subsystem;
uint16_t DllCharacteristics;
uint64_t SizeOfStackReserve;
uint64_t SizeOfStackCommit;
uint64_t SizeOfHeapReserve;
uint64_t SizeOfHeapCommit;
uint32_t LoaderFlags;
uint32_t NumberOfRvaAndSizes;
struct {
uint32_t VirtualAddress;
uint32_t Size;
} DataDirectory[16];
} PE_OPTIONAL_HEADER;

typedef struct {
uint8_t Name[8];
union {
uint32_t PhysicalAddress;
uint32_t VirtualSize;
} Misc;
uint32_t VirtualAddress;
uint32_t SizeOfRawData;
uint32_t PointerToRawData;
uint32_t PointerToRelocations;
uint32_t PointerToLinenumbers;
uint16_t NumberOfRelocations;
uint16_t NumberOfLinenumbers;
uint32_t Characteristics;
} PE_SECTION_HEADER;

#pragma pack(pop)

#endif
Loading

0 comments on commit 25d1634

Please sign in to comment.