diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | src/as_analyzer.h | 8 | ||||
| -rw-r--r-- | src/as_codegen.c | 35 |
3 files changed, 31 insertions, 14 deletions
@@ -11,7 +11,7 @@ obj = $(src:.c=.o) tests=$(shell find tests/ -name '*.c') tests_bin=$(tests:.c=.bin) -all: $(target) fvm-as +all: $(target) # fvm-as fvm-as: $(obj) src/as_main.c $(cc) $(cflags) $(ldflags) $^ -o $@ diff --git a/src/as_analyzer.h b/src/as_analyzer.h index b59fe3c..58a9203 100644 --- a/src/as_analyzer.h +++ b/src/as_analyzer.h @@ -8,16 +8,18 @@ struct sym_table_entry { const char * name; size_t offset; }; +typedef struct sym_table_entry sym_table_entry; struct sym_table { int size; int cap; struct sym_table_entry *buf; }; +typedef struct sym_table sym_table; -struct sym_table new_sym_table(struct allocator * alct); -void sym_table_add(struct allocator * alct, struct sym_table* tbl, const char* name, int pos); +sym_table new_sym_table(allocator* alct); +void sym_table_add(allocator* alct, sym_table* tbl, const char* name, int pos); -struct sym_table analyze_prog(struct allocator * alct, struct prog * prog); +sym_table analyze_prog(allocator* alct, prog* prog); #endif // FVM_AS_ANALYZER_H_ 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); } + |
