-
Notifications
You must be signed in to change notification settings - Fork 2
[feat] Better IR #37
[feat] Better IR #37
Changes from all commits
dcfdfd2
b7257c2
88039ae
78d0536
652d73d
c0e7cef
cbdbe43
51a8277
4c2831d
1022438
3a1b8b7
0ba2005
d6190fd
d0a66cb
68e75ff
2d60aa2
83e8a26
807a5a9
072fa1c
6cee74d
57b170c
87aa308
1ae7ae4
63367eb
c4d6e4e
6dbe507
1c6caa4
f13a3a0
cf380dc
7243e55
54fdd1b
f7259f7
7e9d3e5
a162879
31babd8
226eac8
f05f4dd
f7c72d6
cca7592
3636726
ed58bfe
a0fd9b9
f9dfc86
47f55b4
d050573
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,136 +2,135 @@ | |||||||||||||||||||||||||||||||||
| * The compiler of Quickfall. | ||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| #include <stdlib.h> | ||||||||||||||||||||||||||||||||||
| #include <stdio.h> | ||||||||||||||||||||||||||||||||||
| #include <string.h> | ||||||||||||||||||||||||||||||||||
| #include <stdlib.h> | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| #include "./compiler.h" | ||||||||||||||||||||||||||||||||||
| #include "./objects.h" | ||||||||||||||||||||||||||||||||||
| #include "../parser/ast.h" | ||||||||||||||||||||||||||||||||||
| #include "../utils/logging.c" | ||||||||||||||||||||||||||||||||||
| #include "./ir.h" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| #include "./att/att-win.h" | ||||||||||||||||||||||||||||||||||
| #include "./att/att-linux.h" | ||||||||||||||||||||||||||||||||||
| #include "../parser/ast.h" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| #include "../utils/hashmap.h" | ||||||||||||||||||||||||||||||||||
| #include "../utils/hash.h" | ||||||||||||||||||||||||||||||||||
| #include "../utils/hashmap.h" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||
| * Assembly format defintions. Will be changed by the architure. | ||||||||||||||||||||||||||||||||||
| * Parses the AST tree into a context. | ||||||||||||||||||||||||||||||||||
| * @param tree the AST tree. | ||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||
| char** ARGUMENT_REGISTRIES = NULL; | ||||||||||||||||||||||||||||||||||
| char** SECTION_TYPES = NULL; | ||||||||||||||||||||||||||||||||||
| IR_CTX* makeContext(AST_NODE* tree) { | ||||||||||||||||||||||||||||||||||
| IR_CTX* ctx = malloc(sizeof(IR_CTX)); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||
| * The maximum hash the hashmaps can store. | ||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||
| #define MAX_HASH_CAPACITY 256000 | ||||||||||||||||||||||||||||||||||
| int buffSize = 32; | ||||||||||||||||||||||||||||||||||
| ctx->nodes = malloc(sizeof(IR_NODE) * 32); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| struct Context parseContext(struct ASTNode* node) { | ||||||||||||||||||||||||||||||||||
| struct Context ctx = {0}; | ||||||||||||||||||||||||||||||||||
| ctx->nodeIndex = 0; | ||||||||||||||||||||||||||||||||||
| ctx->nodeMap = createHashmap(512,200); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ctx.variables = malloc(sizeof(struct Variable*) * 50); | ||||||||||||||||||||||||||||||||||
| ctx.functions = malloc(sizeof(struct Function*) * 50); | ||||||||||||||||||||||||||||||||||
| while(tree->next != NULL) { | ||||||||||||||||||||||||||||||||||
| tree = tree->next; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ctx.variableHashMap = createHashmap(512, 500); | ||||||||||||||||||||||||||||||||||
| ctx.functionHashMap = createHashmap(512, 500); | ||||||||||||||||||||||||||||||||||
| switch(tree->type) { | ||||||||||||||||||||||||||||||||||
| case AST_VARIABLE_DECLARATION: | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ctx.variableCount = 0; | ||||||||||||||||||||||||||||||||||
| ctx.functionCount = 0; | ||||||||||||||||||||||||||||||||||
| int hash = hashstr(tree->left->value); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return ctx; | ||||||||||||||||||||||||||||||||||
| if(hashGet(ctx->nodeMap, hash) != NULL) { | ||||||||||||||||||||||||||||||||||
| printf("Variable %s is already declared!\n", tree->left->value); | ||||||||||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| IR_NODE* node = createIRNode(IR_VARIABLE, tree->left->value); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||
| * Compiles the context down to assembly. | ||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||
| char* compileV2(struct Context context) { | ||||||||||||||||||||||||||||||||||
| char* firstSection = malloc(1024); | ||||||||||||||||||||||||||||||||||
| char* sections = malloc(1024); | ||||||||||||||||||||||||||||||||||
| char* main = malloc(1024); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| firstSection[0] = '\0'; | ||||||||||||||||||||||||||||||||||
| sections[0] = '\0'; | ||||||||||||||||||||||||||||||||||
| main[0] = '\0'; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| int sectionIndex = 0; | ||||||||||||||||||||||||||||||||||
| int stackSize = 0; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Platform def | ||||||||||||||||||||||||||||||||||
| ARGUMENT_REGISTRIES = ATTWIN_ARGUMENT_REGISTRIES; | ||||||||||||||||||||||||||||||||||
| SECTION_TYPES = ATTWIN_SECTION_TYPES; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| strcat(firstSection, ".LC0:\n .globl main"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| for(int i = 0; i < context.variableCount; ++i) { | ||||||||||||||||||||||||||||||||||
| if(context.variables[i]->type[0] == 's') { | ||||||||||||||||||||||||||||||||||
| if(sectionIndex == 0) { | ||||||||||||||||||||||||||||||||||
| strcat(firstSection, "\n "); | ||||||||||||||||||||||||||||||||||
| strcat(firstSection, SECTION_TYPES[0]); | ||||||||||||||||||||||||||||||||||
| strcat(firstSection, " "); | ||||||||||||||||||||||||||||||||||
| strcat(firstSection, "\""); | ||||||||||||||||||||||||||||||||||
| strcat(firstSection, context.variables[i]->value); | ||||||||||||||||||||||||||||||||||
| strcat(firstSection, "\""); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||
| strcat(sections, ".LC"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| char secI[5]; | ||||||||||||||||||||||||||||||||||
| snprintf(secI, 5, "%d", sectionIndex); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| strcat(sections, secI); | ||||||||||||||||||||||||||||||||||
| strcat(sections, ":\n "); | ||||||||||||||||||||||||||||||||||
| strcat(sections, SECTION_TYPES[0]); | ||||||||||||||||||||||||||||||||||
| strcat(sections, " "); | ||||||||||||||||||||||||||||||||||
| strcat(sections, "\""); | ||||||||||||||||||||||||||||||||||
| strcat(sections, context.variables[i]->value); | ||||||||||||||||||||||||||||||||||
| strcat(sections, "\""); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| sectionIndex++; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| else if(context.variables[i]->type[0] == 'n') { | ||||||||||||||||||||||||||||||||||
| stackSize += 4; | ||||||||||||||||||||||||||||||||||
| node->type = tree->value; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| strcat(main, "\n movq $"); | ||||||||||||||||||||||||||||||||||
| strcat(main, context.variables[i]->value); | ||||||||||||||||||||||||||||||||||
| strcat(main, ", -"); | ||||||||||||||||||||||||||||||||||
| if(tree->right != NULL && tree->right->value) node->value = tree->right->value; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| char sI[5]; | ||||||||||||||||||||||||||||||||||
| snprintf(sI, 5, "%d", stackSize); | ||||||||||||||||||||||||||||||||||
| ctx->nodes[ctx->nodeIndex] = node; | ||||||||||||||||||||||||||||||||||
| ctx->nodeIndex++; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| strcat(main, sI); | ||||||||||||||||||||||||||||||||||
| strcat(main, "(%rsp)"); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| hashPut(ctx->nodeMap, hash, node); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| char* buff = malloc(1024); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| buff[0] = '\0'; | ||||||||||||||||||||||||||||||||||
| if(ctx->nodeIndex > buffSize) { | ||||||||||||||||||||||||||||||||||
| buffSize = buffSize * 1.5; | ||||||||||||||||||||||||||||||||||
| ctx->nodes = realloc(ctx->nodes, buffSize); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+53
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dynamic array resizing. - ctx->nodes = realloc(ctx->nodes, buffSize);
+ ctx->nodes = realloc(ctx->nodes, sizeof(IR_NODE) * buffSize);📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| strcat(buff, firstSection); | ||||||||||||||||||||||||||||||||||
| strcat(buff, sections); | ||||||||||||||||||||||||||||||||||
| strcat(buff, "\n\nmain:"); | ||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| char size[5]; | ||||||||||||||||||||||||||||||||||
| snprintf(size, 5, "%d", stackSize); | ||||||||||||||||||||||||||||||||||
| case AST_FUNCTION_DECLARATION: | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| hash = hashstr(tree->left->value); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if(stackSize > 0) { | ||||||||||||||||||||||||||||||||||
| strcat(buff, "\n subq $"); | ||||||||||||||||||||||||||||||||||
| strcat(buff, size); | ||||||||||||||||||||||||||||||||||
| strcat(buff, ", %rsp"); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| if(hashGet(ctx->nodeMap, hash) != NULL) { | ||||||||||||||||||||||||||||||||||
| printf("Function %s was already declared!\n", tree->left->value); | ||||||||||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| node = createIRNode(IR_FUNCTION, tree->left->right->value); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| node->type = tree->left->value; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| while(tree->left->left->next != NULL) { | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| IR_NODE* var = createIRNode(IR_FUNCTION_ARGUMENT, tree->right->value); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| node->variables[node->variableIndex] = var; | ||||||||||||||||||||||||||||||||||
| node->variableIndex++; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| hashPut(node->variableMap, hashstr(tree->right->value), var); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| tree->left->left = tree->left->left->next; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ctx->nodes[ctx->nodeIndex] = node; | ||||||||||||||||||||||||||||||||||
| ctx->nodeIndex++; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| strcat(buff, main); | ||||||||||||||||||||||||||||||||||
| hashPut(ctx->nodeMap, hash, node); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if(stackSize > 0) { | ||||||||||||||||||||||||||||||||||
| strcat(buff, "\n addq $"); | ||||||||||||||||||||||||||||||||||
| strcat(buff, size); | ||||||||||||||||||||||||||||||||||
| strcat(buff, ", %rsp"); | ||||||||||||||||||||||||||||||||||
| case AST_ASM_FUNCTION_DECLARATION: | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| hash = hashstr(tree->left->right->value); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if(hashGet(ctx->nodeMap, hash) != NULL) { | ||||||||||||||||||||||||||||||||||
| printf("Assembly function %s is already defined!\n"); | ||||||||||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+90
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing parameter for printf. - printf("Assembly function %s is already defined!\n");
+ printf("Assembly function %s is already defined!\n", tree->left->right->value);📝 Committable suggestion
Suggested change
🧰 Tools🪛 cppcheck (2.10-2)[error] 95-95: printf format string requires 1 parameter but only 0 are given. (wrongPrintfScanfArgNum) |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| node = createIRNode(IR_ASM_FUNCTION, tree->left->right->value); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| node->value = tree->value; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| while(tree->left->left->next != NULL) { | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| IR_NODE* var = createIRNode(IR_FUNCTION_ARGUMENT, tree->left->left->right->value); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| node->variables[node->variableIndex] = var; | ||||||||||||||||||||||||||||||||||
| node->variableIndex++; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| hashPut(node->variableMap, hashstr(tree->left->left->right->value), var); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| tree->left->left = tree->left->left->next; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ctx->nodes[ctx->nodeIndex] = node; | ||||||||||||||||||||||||||||||||||
| ctx->nodeIndex++; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| hashPut(ctx->nodeMap, hash, node); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return buff; | ||||||||||||||||||||||||||||||||||
| return ctx; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||
| * Compiles the Context tree to an executable named the provided file name. | ||||||||||||||||||||||||||||||||||
| * @param ctx the IR context. | ||||||||||||||||||||||||||||||||||
| * @param char the output file name. | ||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||
| void compile(IR_CTX* ctx, char* outputFileName) { | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Memory leak risk detected: Missing hashmap cleanup
The codebase shows that
nodeMapis initialized usingcreateHashmap()but there are no corresponding cleanup/destruction calls found. This poses a potential memory leak risk. Specific findings:nodeMapis created incompiler.cusingcreateHashmap(512,200)hashPutandhashGetoperations are performed🔗 Analysis chain
Hashmap usage alignment.
Hashmap is used to check variable/function redeclarations. Make sure its initialization and destruction are carefully handled to avoid memory leaks.
Let me search for the hashmap cleanup/destruction to complete the verification.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 1585
Script:
Length of output: 112