aboutsummaryrefslogtreecommitdiff
path: root/include/ir
diff options
context:
space:
mode:
Diffstat (limited to 'include/ir')
-rw-r--r--include/ir/ir.h165
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