aboutsummaryrefslogtreecommitdiff
path: root/src/as_codegen.c
blob: 5c1d60e80b46ef21ce1ae1b453b16dd5219a6ebf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#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);
}