diff options
Diffstat (limited to 'include/ir')
-rw-r--r-- | include/ir/ir.h | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/include/ir/ir.h b/include/ir/ir.h new file mode 100644 index 0000000..f7aa4a7 --- /dev/null +++ b/include/ir/ir.h @@ -0,0 +1,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 |