aboutsummaryrefslogtreecommitdiffstats
path: root/src/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir.c')
-rw-r--r--src/ir.c82
1 files changed, 74 insertions, 8 deletions
diff --git a/src/ir.c b/src/ir.c
index 4c85792..4eeb07b 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -47,23 +47,24 @@ typedef enum OperandType {
47 OP_TYPE_LABEL, 47 OP_TYPE_LABEL,
48} OperandType; 48} OperandType;
49 49
50static size_t reg_gen_id = 0;
51
52#define NEW_REG() (Operand){ .type = OP_TYPE_REG, .id = reg_gen_id++ }
53#define NEW_S64(C) (Operand){ .type = OP_TYPE_CONST, .constant.sval = (C) }
54
50typedef struct Operand { 55typedef struct Operand {
51 OperandType type; 56 OperandType type;
52 union { 57 union {
53 struct { 58 // REG/LABEL
54 size_t num; 59 size_t id;
55 } reg;
56
57 struct {
58 size_t num;
59 } label;
60 60
61 // s64 constant;
61 struct { 62 struct {
62 union { 63 union {
63 u64 uval; 64 u64 uval;
64 s64 sval; 65 s64 sval;
65 }; 66 };
66 } const; 67 } constant;
67 }; 68 };
68} Operand; 69} Operand;
69 70
@@ -83,3 +84,68 @@ typedef struct ProgramBASM {
83 Instruction *inst; 84 Instruction *inst;
84 LineInfo *lines; 85 LineInfo *lines;
85} ProgramBASM; 86} ProgramBASM;
87
88Operand
89emit_basm(ProgramBASM *program, Node *node) {
90 switch (node->type) {
91 case NODE_NUMBER: {
92 // TODO: ldX depending on type of number.
93 Instruction inst = (Instruction){
94 .op = OP_LD64,
95 .dst = NEW_REG(),
96 .src_a = NEW_S64(node->number.integral),
97 };
98 LineInfo line = (LineInfo){.line = node->line, .col = node->col};
99 array_push(program->inst, inst);
100 array_push(program->lines, line);
101 return inst.dst;
102 } break;
103 case NODE_BUILTIN: {
104 Operator op;
105 switch (node->builtin.type) {
106 case TOKEN_ADD: { op = OP_ADD; } break;
107 case TOKEN_SUB: { op = OP_SUB; } break;
108 case TOKEN_MUL: { op = OP_MUL; } break;
109 case TOKEN_DIV: { op = OP_DIV; } break;
110 case TOKEN_MOD: { op = OP_MOD; } break;
111 default: break;
112 }
113 Operand reg_a = emit_basm(program, node->builtin.args[0]);
114 Operand reg_b;
115 for (size_t i = 1; i < array_size(node->builtin.args); ++i) {
116 Node *arg = node->builtin.args[i];
117 reg_b = emit_basm(program, arg);
118 Instruction inst = (Instruction){
119 .op = op,
120 .dst = NEW_REG(),
121 .src_a = reg_a,
122 .src_b = reg_b,
123 };
124 reg_a = inst.dst;
125 LineInfo line = (LineInfo){
126 .line = node->line,
127 .col = node->col,
128 };
129 array_push(program->inst, inst);
130 array_push(program->lines, line);
131 }
132 return reg_a;
133 } break;
134 default: {
135 printf("UNIMPLEMENTED\n");
136 return (Operand){0};
137 } break;
138 }
139}
140
141ProgramBASM *
142generate_basm(ParseTree *parse_tree) {
143 ProgramBASM *program = malloc(sizeof(ProgramBASM));
144 array_init(program->inst, 0);
145 array_init(program->lines, 0);
146 for (size_t i = 0; i < array_size(parse_tree->roots); ++i) {
147 Node *root = parse_tree->roots[i];
148 emit_basm(program, root);
149 }
150 return program;
151}