aboutsummaryrefslogtreecommitdiff
path: root/include/ir/ir.h
blob: f7aa4a7633abd540df0ceda712dad4c4de0c9e9b (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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#ifndef AMALGAM_IR_H
#define AMALGAM_IR_H

#include "../std/buffer.h"
#include "../std/hash_map.h"
#include "../std/defs.h"
#include "../defs.h"

#include <setjmp.h>

#define IR_ERR_EXTERN_FUNC_SIG_MISMATCH -20

/* Important: The number of fields in this enum can't exceed 255 */
typedef enum {
    IR_ASSIGN_INTER,
    IR_ASSIGN_STRING,
    IR_ASSIGN_REG,
    IR_ADD,
    IR_SUB,
    IR_IMUL,
    IR_MUL,
    IR_IDIV,
    IR_DIV,
    IR_EQUALS,
    IR_NOT_EQUAL,
    IR_AND,
    IR_ILT,
    IR_ILE,
    IR_IGT,
    IR_IGE,
    IR_LT,
    IR_LE,
    IR_GT,
    IR_GE,
    IR_FUNC_START,
    IR_FUNC_END,
    IR_PUSH,
    IR_PUSH_RET,
    IR_CALL_START,
    IR_CALL,
    IR_CALL_EXTERN,
    IR_JUMP_ZERO,
    IR_JUMP,
    IR_RET,
    IR_LABEL
} IrInstruction;

typedef enum {
    IR_NUMBER_TYPE_INTEGER,
    IR_NUMBER_TYPE_FLOAT
} IrNumberType;

typedef struct {
    union {
        i64 integer;
        f64 floating;
    } value;
    IrNumberType type;
} IrNumber;

typedef struct {
    FunctionSignature *func_sig;
    BufferView name;
} IrExternFunc;

typedef struct {
    FunctionSignature *func_sig;
    BufferView name;
} IrExportFunc;

typedef struct {
    FunctionSignature *func_sig;
} IrFunc;

typedef i16 JumpOffset;
typedef i16 IrRegister;
typedef u16 IrIntermediateIndex;
typedef u16 IrStringIndex;
typedef u16 IrExternFuncIndex;
typedef u16 IrExportFuncIndex;
typedef u16 IrFuncIndex;
typedef u16 IrLabelIndex;

typedef struct {
    Buffer/*instruction data*/ instructions;
    HashMapType(IrNumber, IrIntermediateIndex) intermediates_map;
    Buffer/*IrNumber*/ intermediates;
    HashMapType(BufferView, IrStringIndex) strings_map;
    Buffer/*BufferView*/ strings;
    HashMapType(BufferView, IrExternFuncIndex) extern_funcs_map;
    Buffer/*IrExternFunc*/ extern_funcs;
    Buffer/*IrExportFunc*/ export_funcs;
    Buffer/*IrFunc*/ funcs;

    IrIntermediateIndex intermediate_counter;
    IrStringIndex string_counter;
    IrExternFuncIndex extern_func_counter;
    IrExportFuncIndex export_func_counter;
    IrFuncIndex func_counter;
    IrRegister reg_counter;
    IrRegister param_counter;
    IrLabelIndex label_counter;
    Parser *parser; /* Borrowed */
} Ir;

typedef struct {
    IrRegister lhs;
    u16 rhs;
} IrInsForm1;

typedef struct {
    IrRegister result;
    IrRegister lhs;
    IrRegister rhs;
} IrInsForm2;

typedef struct {
    u8 flags;
    u16 num_local_vars_regs;
} IrInsFuncStart;

typedef struct {
    FunctionDecl *func_decl;
    u8 import_index;
} IrInsFuncCall;

typedef struct {
    LhsExpr *func_decl_lhs;
    int import_index;
} IrInsFuncCallExtern;

typedef struct {
    u8 num_args;
} IrInsCallStart;

typedef struct {
    IrRegister condition_reg;
    IrLabelIndex target_label;
} IrInsJumpZero;

typedef struct {
    IrLabelIndex target_label;
} IrInsJump;

/* None of these functions are thread-safe */
IrNumber create_ir_integer(i64 value);
IrNumber create_ir_float(f64 value);

IrNumber ir_get_intermediate(Ir *self, IrIntermediateIndex index);
BufferView ir_get_string(Ir *self, IrStringIndex index);

CHECK_RESULT int ir_init(Ir *self, Parser *parser);

typedef struct {
    jmp_buf env;
    Ir *ir;
    amal_compiler *compiler;
    /* 0 if the current scope belongs to the file, otherwise ParserFileScopeReference's import_index (the import file that contains the scope) */
    u8 import_index;
} IrCompilerContext;

/* longjump to context->env on failure */
void scope_generate_ir(Scope *self, IrCompilerContext *context);

#endif