summaryrefslogtreecommitdiff
path: root/lib/ops.h
blob: 86bc017aee51b4d8a3a4dab83953948a48f488a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
/*
 * 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: <nielsen@memberwebs.com>
 */

#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 */