aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-03-25 17:31:08 +0800
committerMistivia <i@mistivia.com>2025-03-25 17:31:08 +0800
commit39e2a605f6d8ebcc3cb454daae3d0a4298df2eb6 (patch)
tree9d0933cdcb0d4bb2d80316f106611a4aa9024dd4 /src
parentd1195499338ba4b6536f8a6a56564622eb07469f (diff)
add codegen
Diffstat (limited to 'src')
-rw-r--r--src/as_codegen.c94
-rw-r--r--src/as_codegen.h18
-rw-r--r--src/as_op.c21
-rw-r--r--src/as_op.h5
4 files changed, 120 insertions, 18 deletions
diff --git a/src/as_codegen.c b/src/as_codegen.c
new file mode 100644
index 0000000..98092d7
--- /dev/null
+++ b/src/as_codegen.c
@@ -0,0 +1,94 @@
+#include "as_codegen.h"
+#include "as_op.h"
+#include "fvm.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);
+
+
+int8_t op_bytecode(enum 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;
+}
+
+struct result codegen(struct allocator *alct, struct prog *prog, struct sym_table tbl) {
+ struct stmt ** stmts = prog->stmts->stmts;
+ size_t offset = 0;
+ struct 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;
+ if (op_size(op) == 1) {
+ int8_t code = op_bytecode(op);
+ bytearray_emit8(output, code);
+ offset += 1;
+ } else if (op_size(op) == 9) {
+
+ } else if (op_size(op) == 10) {
+
+ }
+ }
+ return ok(output);
+}
diff --git a/src/as_codegen.h b/src/as_codegen.h
new file mode 100644
index 0000000..17e6ca9
--- /dev/null
+++ b/src/as_codegen.h
@@ -0,0 +1,18 @@
+#ifndef FVM_AS_CODEGEN_H_
+#define FVM_AS_CODEGEN_H_
+
+#include "as_analyzer.h"
+#include <stdlib.h>
+
+struct bytearray {
+ size_t cap;
+ size_t len;
+ char* buf;
+};
+
+void bytearray_emit8(struct bytearray *self, int8_t data);
+void bytearray_emit64(struct bytearray *self, int64_t data);
+
+struct result codegen(struct allocator *alct, struct prog *prog, struct sym_table tbl);
+
+#endif // FVM_AS_CODEGEN_H_
diff --git a/src/as_op.c b/src/as_op.c
index 67c91ff..71ba0f3 100644
--- a/src/as_op.c
+++ b/src/as_op.c
@@ -19,6 +19,7 @@ struct op_table_entry op_table [] = {
{OP_SRV, "srv"},
// OP_IMM,
{OP_IMM, "imm"},
+ {OP_IMM, "rel"},
// OP_LD8, OP_LD16, OP_LD32, OP_LD,
{OP_LD8, "ld8"},
{OP_LD16, "ld16"},
@@ -93,7 +94,7 @@ struct op_table_entry op_table [] = {
};
int op_size(enum op op) {
- if (op == OP_IMM) {
+ if (op == OP_IMM || op == OP_REL) {
return 8 + 1;
}
if (op == OP_CALL
@@ -112,21 +113,11 @@ int op_size(enum op op) {
return 1;
}
-int is_ld_op(enum op op) {
- if (op == OP_LD
- || op == OP_LD8
- || op == OP_LD16
- || op == OP_LD32) {
+int is_pseudo_op(enum op op) {
+ if (op == OP_LDARG || op == OP_STARG) {
return 1;
}
- return 0;
-}
-
-int is_st_op(enum op op) {
- if (op == OP_ST
- || op == OP_ST8
- || op == OP_ST16
- || op == OP_ST32) {
+ if (op == OP_LDVAR || op == OP_STVAR) {
return 1;
}
return 0;
@@ -141,6 +132,6 @@ enum op str2op(const char* str) {
return OP_END;
}
-int isOp(const char *str) {
+int is_op(const char *str) {
return OP_END != str2op(str);
}
diff --git a/src/as_op.h b/src/as_op.h
index d02c29f..cb45fc1 100644
--- a/src/as_op.h
+++ b/src/as_op.h
@@ -3,7 +3,7 @@
enum op {
OP_SP, OP_SSP, OP_BP, OP_SBP, OP_PC, OP_RV, OP_SRV,
- OP_IMM,
+ OP_IMM, OP_REL,
OP_LD8, OP_LD16, OP_LD32, OP_LD,
OP_ST8, OP_ST16, OP_ST32, OP_ST,
OP_DUP, OP_POP, OP_SWAP, OP_OVER, OP_ROT,
@@ -24,8 +24,7 @@ enum op {
enum op str2op(const char *str);
int isOp(const char *str);
int op_size(enum op op);
-int is_ld_op(enum op);
-int is_st_op(enum op);
+int is_pseudo_op(enum op op);
#endif