#include // Stack-relative opcodes group const opcode_handler group_stack[] = { [1] = op_loadconst, [2] = op_call_builtin, [3] = op_pushnum, [4] = op_pushbool, }; // Context-relative opcodes group const opcode_handler group_ctx[] = { [1] = op_mk_envtable, [2] = op_rm_envtable, [3] = op_store, [4] = op_lookup_env, [5] = op_write, }; // Flow-relative opcodes group const opcode_handler group_flow[] = { [1] = op_jmp, [2] = op_jz, }; // Function-relative opcodes group const opcode_handler group_fn[] = { [1] = op_call, [2] = op_ret, }; // Object-relative opcodes group const opcode_handler group_obj[] = { [1] = op_alloc_object, [2] = op_get_field, [3] = op_set_field, [4] = op_escape_object, [5] = op_dereference, }; // Math-relative opcodes group const opcode_handler group_math[] = { [1] = op_add, [2] = op_sub, [3] = op_mul, [4] = op_div, [5] = op_pow, [6] = op_mod, [7] = op_neg, }; // String-relative opcodes group const opcode_handler group_str[] = { [1] = op_build_str, }; // Basic comparison const opcode_handler group_cmp[] = { [1] = op_cmp_eq, [2] = op_cmp_neq, [3] = op_cmp_lt, [4] = op_cmp_lteq, [5] = op_cmp_gt, [6] = op_cmp_gteq, }; // Strings comparison const opcode_handler group_strcmp[] = { [1] = op_cmp_eq_str, [2] = op_cmp_neq_str, }; // Object comparison const opcode_handler group_objcmp[] = { [1] = op_cmp_eq_obj, [2] = op_cmp_neq_obj, }; // AND / OR opcodes const opcode_handler group_and_or[] = { [1] = op_and, [2] = op_or, }; // NOT opcode const opcode_handler group_not[] = { [1] = op_not, }; // Master table const opcode_handler *const master_tbl[] = { [0xF0] = group_stack, [0xF1] = group_ctx, [0xF2] = group_flow, [0xF3] = group_fn, [0xFA] = group_obj, [0xA0] = group_math, [0xA1] = group_str, [0xB0] = group_cmp, [0xB1] = group_strcmp, [0xB2] = group_objcmp, [0xC0] = group_and_or, [0xD0] = group_not, };