#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 #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_ASSIGN_FUNC, 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_CALLR, 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); /* longjump to context->env on failure */ void scope_generate_function_ids(Scope *self, IrCompilerContext *context); /* longjump to context->env on failure */ void scope_generate_functions_ir(Scope *self, IrCompilerContext *context); #endif