diff options
Diffstat (limited to 'src/as_codegen.c')
| -rw-r--r-- | src/as_codegen.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/src/as_codegen.c b/src/as_codegen.c index 98092d7..5c1d60e 100644 --- a/src/as_codegen.c +++ b/src/as_codegen.c @@ -1,13 +1,15 @@ #include "as_codegen.h" +#include "as_analyzer.h" #include "as_op.h" #include "fvm.h" +#include "utils.h" -struct bytearray *new_bytearray(struct allocator *alct); -void bytearray_emit8(struct bytearray *self, int8_t data); -void bytearray_emit64(struct bytearray *self, int64_t data); +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(enum op op) { +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; @@ -70,25 +72,38 @@ int8_t op_bytecode(enum op op) { return (int8_t)-1; } -struct result codegen(struct allocator *alct, struct prog *prog, struct sym_table tbl) { - struct stmt ** stmts = prog->stmts->stmts; +result codegen(allocator* alct, prog* prog, sym_table tbl) { + stmt** stmts = prog->stmts->stmts; size_t offset = 0; - struct bytearray* output = new_bytearray(alct); + bytearray* output = new_bytearray(alct); for (int i = 0; ; i++) { if (stmts[i] == NULL) { break; } - struct instr *instruction = stmts[i]->instr; - enum op op = instruction->op; + 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); } + |
