/* * AUTHOR * N. Nielsen * * VERSION * 2.1.2b * * LICENSE * This software is in the public domain. * * The software is provided "as is", without warranty of any kind, * express or implied, including but not limited to the warranties * of merchantability, fitness for a particular purpose, and * noninfringement. In no event shall the author(s) be liable for any * claim, damages, or other liability, whether in an action of * contract, tort, or otherwise, arising from, out of, or in connection * with the software or the use or other dealings in the software. * * SUPPORT * Send bug reports to: */ #ifndef __OPS_H__20000616 #define __OPS_H__20000616 /* ---------------------------------------------------------------------- Op Arguments The first two bits of an op argument are it's type. 00 = value type (4 bytes) 01 = memory type (4 bytes) 10 = register type (1 byte) */ #define ARG_VAL_TYPE 0x00 #define ARG_MEM_TYPE 0x01 #define ARG_REG_TYPE 0x02 #define ARG_STACK_TYPE 0x03 #define ARG_MAKE_STACK(v) ((((v) << 2) | ARG_STACK_TYPE)) #define ARG_MAKE_MEMORY(v) ((((v) << 2) | ARG_MEM_TYPE)) #define ARG_MAKE_VALUE(v) ((uint)((v) << 2)) #define ARG_MAKE_REGISTER(v) ((byte)(((v) << 2) | ARG_REG_TYPE)) #define ARG_GET_MEMORY(v) ((uint)((v) >> 2)) #define ARG_GET_VALUE(v) ((uint)((v) >> 2)) #define ARG_GET_REGISTER(v) ((byte)((v) >> 2)) #define ARG_GET_STACK(v) ((uint)((v) >> 2)) #define ARG_TYPE(v) ((v) & 0x03) #define ARG_SIZE(v) ((ARG_TYPE(v) == ARG_REG_TYPE) ? 1 : 4) #define INC_ARGUMENT(op) ((op) += ARG_SIZE(*(op))) /* ---------------------------------------------------------------------- Registers (with 0x10 set) */ /* General purpose flag gets set by cmp, on equal, match on success, check on success gets read by je and jne for jump conditions */ #define r_fe ((byte)ARG_MAKE_REGISTER(0x00)) /* const byte fe = ARG_MAKE_REGISTER(0x00); */ /* Greater and less than flags gets set by cmp */ #define r_fg ((byte)ARG_MAKE_REGISTER(0x01)) /* const byte fg = ARG_MAKE_REGISTER(0x01); */ #define r_fl ((byte)ARG_MAKE_REGISTER(0x02)) /* const byte fl = ARG_MAKE_REGISTER(0x02); */ /* Action flag // gets set by match on success */ #define r_ac ((byte)ARG_MAKE_REGISTER(0x03)) /* const byte ac = ARG_MAKE_REGISTER(0x03); */ /* Stack pointer */ #define r_sp ((byte)ARG_MAKE_REGISTER(0x0A)) /* const byte sp = ARG_MAKE_REGISTER(0x0A); */ /* Base pointer */ #define r_bp ((byte)ARG_MAKE_REGISTER(0x0B)) /* const byte bp = ARG_MAKE_REGISTER(0x0B); */ /* Beginning and end registers // gets set by match */ #define r_b0 ((byte)ARG_MAKE_REGISTER(0x10)) /* const byte b0 = ARG_MAKE_REGISTER(0x10); */ #define r_b1 ((byte)ARG_MAKE_REGISTER(0x11)) /* const byte b1 = ARG_MAKE_REGISTER(0x11); */ #define r_b2 ((byte)ARG_MAKE_REGISTER(0x12)) /* const byte b2 = ARG_MAKE_REGISTER(0x12); */ #define r_b3 ((byte)ARG_MAKE_REGISTER(0x13)) /* const byte b3 = ARG_MAKE_REGISTER(0x13); */ #define r_b4 ((byte)ARG_MAKE_REGISTER(0x14)) /* const byte b4 = ARG_MAKE_REGISTER(0x14); */ #define r_b5 ((byte)ARG_MAKE_REGISTER(0x15)) /* const byte b5 = ARG_MAKE_REGISTER(0x15); */ #define r_b6 ((byte)ARG_MAKE_REGISTER(0x16)) /* const byte b6 = ARG_MAKE_REGISTER(0x16); */ #define r_b7 ((byte)ARG_MAKE_REGISTER(0x17)) /* const byte b7 = ARG_MAKE_REGISTER(0x17); */ #define r_b8 ((byte)ARG_MAKE_REGISTER(0x18)) /* const byte b8 = ARG_MAKE_REGISTER(0x18); */ #define r_b9 ((byte)ARG_MAKE_REGISTER(0x19)) /* const byte b9 = ARG_MAKE_REGISTER(0x19); */ #define r_e0 ((byte)ARG_MAKE_REGISTER(0x1B)) /* const byte e0 = ARG_MAKE_REGISTER(0x1B); */ #define r_e1 ((byte)ARG_MAKE_REGISTER(0x1C)) /* const byte e1 = ARG_MAKE_REGISTER(0x1C); */ #define r_e2 ((byte)ARG_MAKE_REGISTER(0x1D)) /* const byte e2 = ARG_MAKE_REGISTER(0x1D); */ #define r_e3 ((byte)ARG_MAKE_REGISTER(0x1E)) /* const byte e3 = ARG_MAKE_REGISTER(0x1E); */ #define r_e4 ((byte)ARG_MAKE_REGISTER(0x1F)) /* const byte e4 = ARG_MAKE_REGISTER(0x1F); */ #define r_e5 ((byte)ARG_MAKE_REGISTER(0x20)) /* const byte e5 = ARG_MAKE_REGISTER(0x20); */ #define r_e6 ((byte)ARG_MAKE_REGISTER(0x21)) /* const byte e6 = ARG_MAKE_REGISTER(0x21); */ #define r_e7 ((byte)ARG_MAKE_REGISTER(0x22)) /* const byte e7 = ARG_MAKE_REGISTER(0x22); */ #define r_e8 ((byte)ARG_MAKE_REGISTER(0x23)) /* const byte e8 = ARG_MAKE_REGISTER(0x23); */ #define r_e9 ((byte)ARG_MAKE_REGISTER(0x24)) /* const byte e9 = ARG_MAKE_REGISTER(0x24); */ /* The count of groups matched */ #define r_cg ((byte)ARG_MAKE_REGISTER(0x25)) /* const byte cg = ARG_MAKE_REGISTER(0x25); */ /* General purpose registers */ #define r_x0 ((byte)ARG_MAKE_REGISTER(0x30)) /* const byte x0 = ARG_MAKE_REGISTER(0x30); */ #define r_x1 ((byte)ARG_MAKE_REGISTER(0x31)) /* const byte x1 = ARG_MAKE_REGISTER(0x31); */ #define r_x2 ((byte)ARG_MAKE_REGISTER(0x32)) /* const byte x2 = ARG_MAKE_REGISTER(0x32); */ #define r_x3 ((byte)ARG_MAKE_REGISTER(0x33)) /* const byte x3 = ARG_MAKE_REGISTER(0x33); */ #define r_x4 ((byte)ARG_MAKE_REGISTER(0x34)) /* const byte x4 = ARG_MAKE_REGISTER(0x34); */ #define r_x5 ((byte)ARG_MAKE_REGISTER(0x35)) /* const byte x5 = ARG_MAKE_REGISTER(0x35); */ #define r_x6 ((byte)ARG_MAKE_REGISTER(0x36)) /* const byte x6 = ARG_MAKE_REGISTER(0x36); */ #define r_x7 ((byte)ARG_MAKE_REGISTER(0x37)) /* const byte x7 = ARG_MAKE_REGISTER(0x37); */ #define r_y0 ((byte)ARG_MAKE_REGISTER(0x38)) /* const byte y0 = ARG_MAKE_REGISTER(0x38); */ #define r_y1 ((byte)ARG_MAKE_REGISTER(0x39)) /* const byte y1 = ARG_MAKE_REGISTER(0x39); */ #define r_y2 ((byte)ARG_MAKE_REGISTER(0x3A)) /* const byte y2 = ARG_MAKE_REGISTER(0x3A); */ #define r_y3 ((byte)ARG_MAKE_REGISTER(0x3B)) /* const byte y3 = ARG_MAKE_REGISTER(0x3B); */ #define r_y4 ((byte)ARG_MAKE_REGISTER(0x3C)) /* const byte y4 = ARG_MAKE_REGISTER(0x3C); */ #define r_y5 ((byte)ARG_MAKE_REGISTER(0x3D)) /* const byte y5 = ARG_MAKE_REGISTER(0x3D); */ #define r_y6 ((byte)ARG_MAKE_REGISTER(0x3E)) /* const byte y6 = ARG_MAKE_REGISTER(0x3E); */ #define r_y7 ((byte)ARG_MAKE_REGISTER(0x3F)) /* const byte y7 = ARG_MAKE_REGISTER(0x3F); */ /* Well almost all of the above are general purpose // x1 and y1 are generally used for the limits // x0 and y0 are generally used for selecting areas */ #define NUM_REGISTERS 0x40 typedef unsigned char vmop_t; /* ---------------------------------------------------------------------- OP CODES: */ /* END: end of instructions! */ #define o_end ((vmop_t)(0x00)) /* const vmop_t end = 0x00; */ /* NOP: Blank / space filler */ #define o_nop ((vmop_t)(0xD1)) /* const vmop_t nop = 0xD1; */ /* PUSH: (1 value param) Copy new context and execute */ #define o_push ((vmop_t)(0xD2)) /* const vmop_t push = 0xD2; */ /* POP: (1 value param) Remove current context and execute previous */ #define o_pop ((vmop_t)(0xD4)) /* const vmop_t pop = 0xD4; */ /* LOCK: (2 value params) Lock data between the parameters */ #define o_lock ((vmop_t)(0xE0)) /* const vmop_t lock = 0xE0; */ /* CHECK: (2 value params) Check data between parameters against locks */ #define o_check ((vmop_t)(0xE1)) /* const vmop_t check = 0xE1; */ /* MATCH: (2 value params, plus match structure) Match the regexp against string between the limited beg and end */ #define o_match ((vmop_t)(0xC0)) /* const vmop_t match = 0xC0; */ /* SETVAR: (2 value params, plus variable name) Add text between selected registers to a variable */ #define o_setvar ((vmop_t)(0xC2)) /* const vmop_t setvar = 0xC2; */ /* CLRVAR: (2 value params, plus variable name) Clear a variable */ #define o_clrvar ((vmop_t)(0xC3)) /* const vmop_t clrvar = 0xC3; */ /* JMP: (1 address param) Jump to the specified address */ #define o_jmp ((vmop_t)(0xD6)) /* const vmop_t jmp = 0xD6; */ /* JE: (1 address param) Jump if fe flag is set */ #define o_je ((vmop_t)(0xD7)) /* const vmop_t je = 0xD7; */ /* JNE: (1 address param) Jump if fe flag is not set */ #define o_jne ((vmop_t)(0xD8)) /* const vmop_t jne = 0xD8; */ /* REPL: (2 value params, plus repl sizeof(text_op)) Perform a replacement operation with current registers and string*/ #define o_repl ((vmop_t)(0xC4)) /* const vmop_t repl = 0xC4; */ /* STOP: (1 value param denoting error or not) Plus an optional message */ #define o_stop ((vmop_t)(0x02)) /* const vmop_t stop = 0x02; */ /* CMP: (2 value params) Compare the two values */ #define o_cmp ((vmop_t)(0xE9)) /* const vmop_t cmp = 0xE9; */ #define o_test ((vmop_t)(0xEA)) /* const vmop_t test = 0xEA; */ /* MOV: (2 value params) set first value to be equal to second */ #define o_mov ((vmop_t)(0xD9)) /* const vmop_t mov = 0xD9; */ /* CALL: (1 address param) Call function at address */ #define o_call ((vmop_t)(0xDA)) /* const vmop_t call = 0xDA; */ /* RET: Return control to previous function */ #define o_ret ((vmop_t)(0xDB)) /* const vmop_t ret = 0xDB; */ /* ADD: (2 value params) add second value to first */ #define o_add ((vmop_t)(0xDC)) /* const vmop_t add = 0xDC; */ /* SUB: (2 value params) subtract second value from first */ #define o_sub ((vmop_t)(0xDD)) /* const vmop_t sub = 0xDD; */ /* TEXT: (text block) put text in the data buffer */ #define o_text ((vmop_t)(0xDE)) /* MESSAGE: output data buffer as a message */ #define o_msg ((vmop_t)(0xDF)) /* ---------------------------------------------------------------------- OP STRUCTURES: for large ops structures to ease access */ #ifdef _WIN32 #pragma pack(push, ops) #endif #pragma pack(1) typedef struct _match_op { short len; /* Length of structure */ byte type; /* Match type */ } match_op; /* Or these two values for type above */ static const byte kMatchPcre = 0x01; typedef struct _match_op_pcre { match_op header; short options; char pattern[1]; } match_op_pcre; #define match_op_size(op) (sizeof(byte) * (op).len) typedef struct _text_op { short len; /* Length of string */ byte string[1]; /* Text to put in buffer */ } text_op; #define text_op_size(op) (sizeof(text_op) + (sizeof(char) * (op).len)) typedef struct _var_op { short len; /* Length of entire structure */ byte name[1]; /* Variable name */ } var_op; #define var_op_size(op) (sizeof(var_op) + (sizeof(char) * (op).len)) #pragma pack() #ifdef _WIN32 #pragma pack(pop, ops) #endif #endif /* __OPS_H__20000616 */