Stuff
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user