aboutsummaryrefslogtreecommitdiff
path: root/src/as_codegen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/as_codegen.c')
-rw-r--r--src/as_codegen.c185
1 files changed, 0 insertions, 185 deletions
diff --git a/src/as_codegen.c b/src/as_codegen.c
deleted file mode 100644
index 678733f..0000000
--- a/src/as_codegen.c
+++ /dev/null
@@ -1,185 +0,0 @@
-#include "as_codegen.h"
-
-#include <string.h>
-
-#include "as_analyzer.h"
-#include "as_op.h"
-#include "fvm.h"
-#include "utils.h"
-
-bytearray *new_bytearray(allocator *alct) {
- bytearray* arr = allocate(alct, sizeof(bytearray));
- arr->len = 0;
- arr->cap = 16;
- arr->buf = allocate(alct, 16);
- arr->alct = alct;
- return arr;
-}
-
-void bytearray_emit8(bytearray *arr, int8_t data) {
- if (arr->len == arr->cap) {
- void* oldbuf = arr->buf;
- arr->buf = allocate(arr->alct, 2 * arr->cap);
- memcpy(arr->buf, oldbuf, arr->cap);
- arr->cap = arr->cap * 2;
- }
- arr->buf[arr->len] = data;
- arr->len++;
-}
-
-void bytearray_emit64(bytearray *self, int64_t data) {
- int8_t* ptr = (int8_t*)&data;
- for (int i = 0; i < 8; i++) {
- bytearray_emit8(self, ptr[i]);
- }
-}
-
-
-int8_t op_bytecode(op op) {
- if (op == OP_SSP) return (int8_t)FVM_OP_SSP;
- if (op == OP_SP) return (int8_t)FVM_OP_SP;
- if (op == OP_SBP) return (int8_t)FVM_OP_SBP;
- if (op == OP_BP) return (int8_t)FVM_OP_BP;
- if (op == OP_PC) return (int8_t)FVM_OP_PC;
- if (op == OP_RV) return (int8_t)FVM_OP_RV;
- if (op == OP_SRV) return (int8_t)FVM_OP_SRV;
-
- if (op == OP_DUP) return (int8_t)FVM_OP_DUP;
- if (op == OP_POP) return (int8_t)FVM_OP_POP;
- if (op == OP_SWAP) return (int8_t)FVM_OP_SWAP;
- if (op == OP_OVER) return (int8_t)FVM_OP_OVER;
- if (op == OP_ROT) return (int8_t)FVM_OP_ROT;
-
- if (op == OP_ADD) return (int8_t)FVM_OP_ADD;
- if (op == OP_SUB) return (int8_t)FVM_OP_SUB;
- if (op == OP_DIV) return (int8_t)FVM_OP_DIV;
- if (op == OP_MUL) return (int8_t)FVM_OP_MUL;
- if (op == OP_MOD) return (int8_t)FVM_OP_MOD;
-
- if (op == OP_SHR) return (int8_t)FVM_OP_SHR;
- if (op == OP_SHL) return (int8_t)FVM_OP_SHL;
- if (op == OP_SAR) return (int8_t)FVM_OP_SAR;
-
- if (op == OP_AND) return (int8_t)FVM_OP_AND;
- if (op == OP_OR) return (int8_t)FVM_OP_OR;
- if (op == OP_NOT) return (int8_t)FVM_OP_NOT;
-
- if (op == OP_BITAND) return (int8_t)FVM_OP_BITAND;
- if (op == OP_BITOR) return (int8_t)FVM_OP_BITOR;
- if (op == OP_XOR) return (int8_t)FVM_OP_XOR;
- if (op == OP_INVERT) return (int8_t)FVM_OP_INVERT;
-
- if (op == OP_JNZ) return (int8_t)FVM_OP_JNZ;
- if (op == OP_JZ) return (int8_t)FVM_OP_JZ;
- if (op == OP_JMP) return (int8_t)FVM_OP_JMP;
- if (op == OP_CALL) return (int8_t)FVM_OP_CALL;
- if (op == OP_SYSCALL) return (int8_t)FVM_OP_SYSCALL;
-
- if (op == OP_GT) return (int8_t)FVM_OP_GT;
- if (op == OP_LT) return (int8_t)FVM_OP_LT;
- if (op == OP_GE) return (int8_t)FVM_OP_GE;
- if (op == OP_LE) return (int8_t)FVM_OP_LE;
- if (op == OP_EQ) return (int8_t)FVM_OP_EQ;
- if (op == OP_NEQ) return (int8_t)FVM_OP_NEQ;
-
- if (op == OP_RET) return (int8_t)FVM_OP_RET;
-
- if (op == OP_FADD) return (int8_t)FVM_OP_FADD;
- if (op == OP_FSUB) return (int8_t)FVM_OP_FSUB;
- if (op == OP_FDIV) return (int8_t)FVM_OP_FDIV;
- if (op == OP_FMUL) return (int8_t)FVM_OP_FMUL;
-
- if (op == OP_FGT) return (int8_t)FVM_OP_FGT;
- if (op == OP_FLT) return (int8_t)FVM_OP_FLT;
- if (op == OP_FGE) return (int8_t)FVM_OP_FGE;
- if (op == OP_FLE) return (int8_t)FVM_OP_FLE;
- if (op == OP_FEQ) return (int8_t)FVM_OP_FEQ;
- if (op == OP_FNEQ) return (int8_t)FVM_OP_FNEQ;
-
- if (op == OP_FTI) return (int8_t)FVM_OP_FTI;
- if (op == OP_ITF) return (int8_t)FVM_OP_ITF;
-
- if (op == OP_EXIT) return (int8_t)FVM_OP_EXIT;
-
- return (int8_t)-1;
-}
-
-result codegen(allocator* alct, prog* prog, sym_table tbl) {
- stmt** stmts = prog->stmts->stmts;
- size_t offset = 0;
- bytearray* output = new_bytearray(alct);
- for (int i = 0; ; i++) {
- if (stmts[i] == NULL) {
- break;
- }
- instr* instr = stmts[i]->instr;
- op op = instr->op;
- if (op_size(op) == 1) {
- int8_t code = op_bytecode(op);
- bytearray_emit8(output, code);
- offset += 1;
- } else if (op == OP_IMM) {
- if (instr->tag_name != NULL || instr->arg == NULL) {
- return err(safe_sprintf(alct, "line %d: invalid instruction format. (imm)\n", instr->lineno));
- }
- bytearray_emit8(output, FVM_OP_IMM);
- bytearray_emit64(output, instr->arg->ival);
- offset += 9;
- } else if (op == OP_REL) {
- if (instr->tag_name == NULL || instr->arg != NULL) {
- return err(safe_sprintf(alct, "line %d: invalid instruction format. (rel)\n", instr->lineno));
- }
- bytearray_emit8(output, FVM_OP_IMM);
- int target_offset = sym_table_lookup(&tbl, instr->tag_name);
- if (target_offset == -1) {
- return err(safe_sprintf(alct, "line %d: unknown tag: %s", instr->lineno, instr->tag_name));
- }
- bytearray_emit64(output, target_offset - (offset + 9));
- bytearray_emit8(output, FVM_OP_PC);
- bytearray_emit8(output, FVM_OP_ADD);
- offset += 11;
- } else if (op == OP_LDARG) {
- if (instr->tag_name != NULL || instr->arg == NULL) {
- return err(safe_sprintf(alct, "line %d: invalid instruction format. (ldarg)\n", instr->lineno));
- }
- bytearray_emit8(output, FVM_OP_IMM);
- bytearray_emit64(output, 8 * (instr->arg->ival + 2));
- bytearray_emit8(output, FVM_OP_BP);
- bytearray_emit8(output, FVM_OP_ADD);
- bytearray_emit8(output, FVM_OP_LD);
- offset += 12;
- } else if (op == OP_STARG) {
- if (instr->tag_name != NULL || instr->arg == NULL) {
- return err(safe_sprintf(alct, "line %d: invalid instruction format. (starg)\n", instr->lineno));
- }
- bytearray_emit8(output, FVM_OP_IMM);
- bytearray_emit64(output, 8 * (instr->arg->ival + 2));
- bytearray_emit8(output, FVM_OP_BP);
- bytearray_emit8(output, FVM_OP_ADD);
- bytearray_emit8(output, FVM_OP_ST);
- offset += 12;
- } else if (op == OP_LDVAR) {
- if (instr->tag_name != NULL || instr->arg == NULL) {
- return err(safe_sprintf(alct, "line %d: invalid instruction format. (ldvar)\n", instr->lineno));
- }
- bytearray_emit8(output, FVM_OP_IMM);
- bytearray_emit64(output, 8 * (-instr->arg->ival - 1));
- bytearray_emit8(output, FVM_OP_BP);
- bytearray_emit8(output, FVM_OP_ADD);
- bytearray_emit8(output, FVM_OP_LD);
- offset += 12;
- } else if (op == OP_STVAR) {
- if (instr->tag_name != NULL || instr->arg == NULL) {
- return err(safe_sprintf(alct, "line %d: invalid instruction format. (stvar)\n", instr->lineno));
- }
- bytearray_emit8(output, FVM_OP_IMM);
- bytearray_emit64(output, 8 * (-instr->arg->ival - 2));
- bytearray_emit8(output, FVM_OP_BP);
- bytearray_emit8(output, FVM_OP_ADD);
- bytearray_emit8(output, FVM_OP_ST);
- offset += 12;
- }
- }
- return ok(output);
-}
-