#include "as_codegen.h" #include "as_analyzer.h" #include "as_op.h" #include "fvm.h" #include "utils.h" bytearray *new_bytearray(allocator *alct); void bytearray_emit8(bytearray *self, int8_t data); void bytearray_emit64(bytearray *self, int64_t data); 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_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_size(op) == 9) { 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); } } else if (op_size(op) == 10) { } } return ok(output); }