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.c35
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);
}
+