summaryrefslogtreecommitdiff
path: root/src/compiler/code-generator.c
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-01-27 01:25:24 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-01-27 01:25:24 +0330
commit64331c144518b8ab1c3cf08473771e0d3f14f67b (patch)
treec378fccbddcc4e0972a7a426b4bf464efc1129bf /src/compiler/code-generator.c
parentbb87887ec288f341256d324f271bac6267fc83f4 (diff)
add print_u64 to be able to print u64 numbers
Diffstat (limited to 'src/compiler/code-generator.c')
-rw-r--r--src/compiler/code-generator.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/src/compiler/code-generator.c b/src/compiler/code-generator.c
index d9fc05d..fb843d0 100644
--- a/src/compiler/code-generator.c
+++ b/src/compiler/code-generator.c
@@ -3,6 +3,7 @@
#include "utils/log.h"
#include "utils/memory.h"
#include <assert.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -12,6 +13,7 @@ void codeGeneratorDelete(CodeGeneratorCodes *code) {
CodeGeneratorCode current = code->codes[i];
switch (current.instruction) {
case CODE_GENERATOR_INSTRUCTION_PRINT:
+ case CODE_GENERATOR_INSTRUCTION_PRINT_U64:
case CODE_GENERATOR_INSTRUCTION_RET:
continue;
case CODE_GENERATOR_INSTRUCTION_CALL: {
@@ -122,6 +124,21 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end,
callMetadata));
}
goto OK;
+ case AST_TREE_TOKEN_KEYWORD_PRINT_U64: {
+ AstTreeSingleChild *metadata = tree.metadata;
+ if (metadata->token == AST_TREE_TOKEN_VALUE_U64) {
+ CodeGeneratorOperandU64 value = (AstTreeU64)metadata->metadata;
+ generateCodePushCode(
+ codes, createGenerateCode(label_begin, label_end,
+ CODE_GENERATOR_INSTRUCTION_PRINT_U64,
+ (void *)value));
+ } else {
+ printLog("Not implemented yet");
+ exit(1);
+ }
+ }
+ goto OK;
+ case AST_TREE_TOKEN_VALUE_U64:
case AST_TREE_TOKEN_IDENTIFIER:
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_TYPE_FUNCTION:
@@ -143,13 +160,16 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end,
}
static const char TEMPLATE[] =
- "format ELF64 executable 3\nSYS_exit = 60\nSYS_write = 1\nSTDOUT = "
- "1\nsegment readable writable\nhello: db \"Hello, "
- "World!\",0xa\nhello_len = $-hello\nsegment readable executable\nentry "
- "_start\nprint:\nmov rax, SYS_write\nmov rdi, STDOUT\nmov rsi, "
- "hello\nmov rdx, hello_len\nsyscall\nret\n_start:\ncall main\nmov rax, "
- "SYS_exit\nxor "
- "rdi,rdi\nsyscall\n";
+ "format ELF64 executable 3\n\nSYS_exit = 60\nSYS_write = 1\nSTDOUT = "
+ "1\n\nsegment readable writable\nhello: db \"Hello, "
+ "World!\",0xa\nhello_len = $-hello\n\nsegment readable executable\nentry "
+ "_start\n\nprint:\nmov rax, SYS_write\nmov rdi, STDOUT\nmov rsi, "
+ "hello\nmov rdx, hello_len\nsyscall\nret\n\n; rdi = the "
+ "number\nprint_u64:\nmov rcx, rsp\nmov rax, rdi\nmov rbx, 10\n\n.L:\nxor "
+ "rdx, rdx\ndiv rbx\nadd dl, '0'\ndec rcx\nmov [rcx],dl\ncmp rax, 0\njnz "
+ ".L\n\nmov rax, SYS_write\nmov rdi, STDOUT\nmov rsi, rcx\n\nmov rdx, "
+ "rsp\nsub rdx, rcx\n\nsyscall\nret\n\n_start:\ncall main\nmov rax, "
+ "SYS_exit\nxor rdi,rdi\nsyscall\n";
static const size_t TEMPLATE_LEN =
sizeof(TEMPLATE) / sizeof(*TEMPLATE) - sizeof(*TEMPLATE);
@@ -191,6 +211,15 @@ char *codeGeneratorToFlatASM(const CodeGeneratorCodes *codes) {
strlen(INST));
}
continue;
+ case CODE_GENERATOR_INSTRUCTION_PRINT_U64: {
+ CodeGeneratorOperandU64 metadata = (CodeGeneratorOperandU64)code.metadata;
+ char *inst;
+ asprintf(&inst, "mov rdi,%lu\ncall print_u64\n", (uint64_t)metadata);
+ codeGeneratorAppendFlatASMCommand(&fasm, &fasm_size, &fasm_inserted, inst,
+ strlen(inst));
+ free(inst);
+ }
+ continue;
case CODE_GENERATOR_INSTRUCTION_CALL: {
CodeGeneratorCall *metadata = code.metadata;
constexpr char CALL_INST[] = "call ";