This commit is contained in:
2025-07-08 21:53:08 +03:00
parent 7433808320
commit 23d7e86c2c
7 changed files with 162 additions and 97 deletions

View File

@@ -1,6 +1,7 @@
#include "argparse.h"
#include "dynarray.h"
#include "logger.h"
#include "parser/ast.h"
#include "token.h"
#include <stdio.h>
@@ -8,9 +9,13 @@
typedef struct comp_state_s {
char** strings;
size_t if_id;
size_t while_id;
} comp_state_t;
int write_op(ast_op_t* aop, FILE* f, comp_state_t state) {
int write_if_stat(ast_if_stat_t* if_stat, FILE* f, comp_state_t* state);
int write_op(ast_op_t* aop, FILE* f, comp_state_t* state) {
switch (aop->type) {
case (AOT_OP): {
@@ -23,17 +28,17 @@ int write_op(ast_op_t* aop, FILE* f, comp_state_t state) {
}; break;
case (TT_PUSH_STR): {
fprintf(f, " ; -- PUSH_STR --\n");
fprintf(f, " mov rax, morph_str_%zu\n", dynarray_length(state.strings));
fprintf(f, " mov rax, morph_str_%zu\n", dynarray_length(state->strings));
fprintf(f, " push rax\n");
fprintf(f, " mov rax, %zu\n", strlen(op.str_v));
fprintf(f, " push rax\n");
dynarray_push(state.strings, op.str_v);
dynarray_push(state->strings, op.str_v);
}; break;
case (TT_PUSH_CSTR): {
fprintf(f, " ; -- PUSH_CSTR --\n");
fprintf(f, " mov rax, morph_str_%zu\n", dynarray_length(state.strings));
fprintf(f, " mov rax, morph_str_%zu\n", dynarray_length(state->strings));
fprintf(f, " push rax\n");
dynarray_push(state.strings, op.str_v);
dynarray_push(state->strings, op.str_v);
}; break;
case (TT_PUSH_BOOL): {
fprintf(f, " ; -- PUSH_BOOL --\n");
@@ -51,6 +56,13 @@ int write_op(ast_op_t* aop, FILE* f, comp_state_t state) {
}; break;
case (TT_OP): {
switch (op.op_type) {
case (OP_CAST_BOOL):
case (OP_CAST_INT):
case (OP_CAST_PTR):
case (OP_COUNT__):
case (OP_NONE):
break;
case (OP_ADD): {
fprintf(f, " ; -- OP_ADD --\n");
fprintf(f, " pop rax\n");
@@ -366,11 +378,11 @@ int write_op(ast_op_t* aop, FILE* f, comp_state_t state) {
case (OP_HERE): {
char* pos = malloc(1024 * 2);
snprintf(pos, 2048, "%s:%d:%d", op.loc.file, op.loc.line, op.loc.col);
fprintf(f, " mov rax, str_%zu\n", dynarray_length(state.strings));
fprintf(f, " mov rax, str_%zu\n", dynarray_length(state->strings));
fprintf(f, " push rax\n");
fprintf(f, " mov rax, %zu\n", strlen(op.str_v));
fprintf(f, " push rax\n");
dynarray_push(state.strings, op.str_v);
dynarray_push(state->strings, op.str_v);
}; break;
case (OP_PRINT): {
}; break;
@@ -378,17 +390,42 @@ int write_op(ast_op_t* aop, FILE* f, comp_state_t state) {
}; break;
case (TT_KW):
case (TT_IDENT): {
log_warn(&op.loc, "Found a KW or IDENT where it shouldnt exists (compiler): %s", get_tok_str_dbg(&op));
// unreachable
} break;
}
}
case (AOT_IF): {
write_if_stat(&aop->if_stat, f, state);
}; break;
case (AOT_WHILE): {
size_t id = state->while_id++;
fprintf(f, " ;; -- OP_WHILE -- \n");
fprintf(f, "morph_while_%zu_cond:\n", id);
for (int i = 0; i < dynarray_length(aop->while_stat.condition); i++) {
write_op(&aop->while_stat.condition[i], f, state);
}
fprintf(f, " pop rax\n");
fprintf(f, " test rax, rax\n");
fprintf(f, " jz morph_while_%zu_end\n", id);
fprintf(f, " pop rax\n");
fprintf(f, "morph_while_%zu_start:\n", id);
for (int i = 0; i < dynarray_length(aop->while_stat.body); i++) {
write_op(&aop->while_stat.body[i], f, state);
}
fprintf(f, " jmp morph_while_%zu_cond:\n", id);
fprintf(f, "morph_while_%zu_end:\n", id);
}; break;
case (AOT_USE_CONST): {
fprintf(f, " ;; -- OP_USE_CONST -- \n");
fprintf(f, " mov rax, [morph_const_%zu]\n", aop->id);
fprintf(f, " push rax\n");
}; break;
case (AOT_USE_MEMORY): {
fprintf(f, " ;; -- OP_USE_MEMORY -- \n");
fprintf(f, " mov rax, morph_memory_%zu\n", aop->id);
fprintf(f, " push rax\n");
}; break;
case (AOT_CALL_FUNC): {
@@ -397,6 +434,35 @@ int write_op(ast_op_t* aop, FILE* f, comp_state_t state) {
return 0;
}
int write_if_stat(ast_if_stat_t* if_stat, FILE* f, comp_state_t* state) {
size_t id = state->if_id++;
fprintf(f, " ; -- OP_IF \n");
for (int i = 0; i < dynarray_length(if_stat->condition); i++) {
write_op(&if_stat->condition[i], f, state);
}
fprintf(f, " pop rax\n");
fprintf(f, " test rax, rax\n");
fprintf(f, " jz morph_if_%zu_cond_false\n", id);
fprintf(f, " pop rax\n");
fprintf(f, "morph_if_%zu_cond_true:\n", id);
for (int i = 0; i < dynarray_length(if_stat->body); i++) {
write_op(&if_stat->body[i], f, state);
}
fprintf(f, " jmp morph_if_%zu_end\n", id);
fprintf(f, "morph_if_%zu_cond_false:\n", id);
if (if_stat->else_body) {
for (int i = 0; i < dynarray_length(if_stat->body); i++) {
write_op(&if_stat->body[i], f, state);
}
} else if (if_stat->is_elseif) {
write_if_stat(if_stat->elseif, f, state);
}
fprintf(f, "morph_if_%zu_end:\n", id);
return 0;
}
int compile_x86_64_linux_nasm(args_t* args, program_t* prog) {
FILE* f = fopen(args->asm_file, "w");
comp_state_t state = {0};
@@ -406,18 +472,22 @@ int compile_x86_64_linux_nasm(args_t* args, program_t* prog) {
fprintf(f, "section .text\n");
fprintf(f, "global _start\n");
fprintf(f, "_start:\n");
fprintf(f, " mov rax, [rsp]\n");
fprintf(f, " mov [morph_i_argc], rax\n");
fprintf(f, " mov rax, [rsp+8]\n");
fprintf(f, " mov [morph_i_argv], rax\n");
fprintf(f, " call morph_f_main\n");
fprintf(f, " mov rax, 60\n");
fprintf(f, " mov rdi, 0\n");
fprintf(f, " syscall\n");
for (int i = 0; i < dynarray_length(prog->funcs); i++) {
size_t fn_len = dynarray_length(prog->funcs);
for (int i = 0; i < fn_len; i++) {
function_t func = prog->funcs[i];
fprintf(f, "morph_f_%s:\n", func.name);
for (int y = 0; y < dynarray_length(func.body); y++) {
ast_op_t aop = func.body[y];
if (write_op(&aop, f, state)) {
if (write_op(&aop, f, &state)) {
return 1;
}
}
@@ -425,6 +495,8 @@ int compile_x86_64_linux_nasm(args_t* args, program_t* prog) {
}
fprintf(f, "section .bss\n");
fprintf(f, "morph_i_argc: resb 8\n");
fprintf(f, "morph_i_argv: resb 8\n");
for (int i = 0; i < dynarray_length(prog->memories); i++) {
memory_t mem = prog->memories[i];
fprintf(f, "morph_memory_%d: resb %zu ; Memory %s\n", i, mem.size, mem.name);
@@ -443,7 +515,7 @@ int compile_x86_64_linux_nasm(args_t* args, program_t* prog) {
}; break;
case (TT_PUSH_CSTR):
case (TT_PUSH_STR): {
fprintf(f, "db %s\n", v->val.str_v);
fprintf(f, "db \"%s\"\n", v->val.str_v);
}; break;
case (TT_PUSH_CHAR):
fprintf(f, "db %c\n", v->val.char_v);