diff options
Diffstat (limited to 'src/as_codegen.c')
| -rw-r--r-- | src/as_codegen.c | 185 |
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); -} - |
