diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-01-30 08:54:18 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-01-30 08:54:18 +0330 |
commit | 9f2b1bdcfbbc084876c3ab7cc2cb8c15ffb88184 (patch) | |
tree | cf46656b50fa3d868a7bed4821667f6a31ea922c /src/compiler/code-generator.c | |
parent | d32d148cee5b3aec5e8943738aa30139d442478c (diff) |
added assign operator
Diffstat (limited to 'src/compiler/code-generator.c')
-rw-r--r-- | src/compiler/code-generator.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/compiler/code-generator.c b/src/compiler/code-generator.c index b52c5d3..4ddfe94 100644 --- a/src/compiler/code-generator.c +++ b/src/compiler/code-generator.c @@ -25,6 +25,13 @@ void codeGeneratorDelete(CodeGeneratorCodes *code) { free(metadata); } continue; + case CODE_GENERATOR_INSTRUCTION_MOV_U64: { + CodeGeneratorDoubleOperand *metadata = current.metadata; + free(metadata->op0.value); + free(metadata->op1.value); + free(metadata); + } + continue; } printLog("Bad instruction %d", current.instruction); exit(1); @@ -42,6 +49,43 @@ CodeGeneratorOperand *newCodeGeneratorOperand(char *value, bool isReference) { return result; } +CodeGeneratorOperand *makeCodeGeneratorOperand(AstTree tree) { + switch (tree.token) { + case AST_TREE_TOKEN_VALUE_U64: + return newCodeGeneratorOperand(u64ToString((AstTreeU64)tree.metadata), + false); + case AST_TREE_TOKEN_VARIABLE: { + AstTreeVariable *variable = tree.metadata; + if (!typeIsEqual(variable->type, &AST_TREE_U64_TYPE)) { + UNREACHABLE; + } + if (variable->isConst) { + return newCodeGeneratorOperand( + u64ToString((AstTreeU64)variable->value->metadata), false); + } else { + char *name = a404m_malloc( + (variable->name_end - variable->name_begin + 1) * sizeof(*name)); + strncpy(name, variable->name_begin, + variable->name_end - variable->name_begin); + name[variable->name_end - variable->name_begin] = '\0'; + + return newCodeGeneratorOperand(name, true); + } + } + case AST_TREE_TOKEN_FUNCTION: + case AST_TREE_TOKEN_KEYWORD_PRINT_U64: + case AST_TREE_TOKEN_TYPE_TYPE: + case AST_TREE_TOKEN_TYPE_FUNCTION: + case AST_TREE_TOKEN_TYPE_VOID: + case AST_TREE_TOKEN_TYPE_U64: + case AST_TREE_TOKEN_FUNCTION_CALL: + case AST_TREE_TOKEN_VARIABLE_DEFINE: + case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_NONE: + } + UNREACHABLE; +} + CodeGeneratorCode createGenerateCode(char *label_begin, char *label_end, CodeGeneratorInstruction instruction, void *metadata) { @@ -183,6 +227,31 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end, } } goto OK; + case AST_TREE_TOKEN_OPERATOR_ASSIGN: { + AstTreeInfix *infix = tree.metadata; + + if (infix->left.token != AST_TREE_TOKEN_VARIABLE) { + printLog("Not implemented yet"); + exit(1); + } else if (infix->leftType.token != AST_TREE_TOKEN_TYPE_U64) { + printLog("Not implemented yet"); + exit(1); + } + + CodeGeneratorDoubleOperand *operands = a404m_malloc(sizeof(*operands)); + CodeGeneratorOperand *op0 = makeCodeGeneratorOperand(infix->left); + CodeGeneratorOperand *op1 = makeCodeGeneratorOperand(infix->right); + operands->op0 = *op0; + operands->op1 = *op1; + free(op0); + free(op1); + + generateCodePushCode( + codes, + createGenerateCode(label_begin, label_end, + CODE_GENERATOR_INSTRUCTION_MOV_U64, operands)); + } + goto OK; case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_VARIABLE: @@ -288,6 +357,27 @@ char *codeGeneratorToFlatASM(const CodeGeneratorCodes *codes) { free(inst); } continue; + case CODE_GENERATOR_INSTRUCTION_MOV_U64: { + CodeGeneratorDoubleOperand *metadata = code.metadata; + char *inst; + if (metadata->op1.isReference) { + asprintf(&inst, "mov rax, [%s]\n", metadata->op1.value); + } else { + asprintf(&inst, "mov rax, %s\n", metadata->op1.value); + } + codeGeneratorAppendFlatASMCommand(&fasm, &fasm_size, &fasm_inserted, inst, + strlen(inst)); + free(inst); + if (metadata->op0.isReference) { + asprintf(&inst, "mov [%s], rax\n", metadata->op0.value); + } else { + UNREACHABLE; + } + codeGeneratorAppendFlatASMCommand(&fasm, &fasm_size, &fasm_inserted, inst, + strlen(inst)); + free(inst); + } + continue; } printLog("Bad instruction %d", code.instruction); } |