7618
|
1 /*
|
|
2 * This program is free software: you can redistribute it and/or modify
|
|
3 * it under the terms of the GNU General Public License as published by
|
|
4 * the Free Software Foundation, either version 3 of the License, or
|
|
5 * (at your option) any later version.
|
|
6 *
|
|
7 * This program is distributed in the hope that it will be useful,
|
|
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10 * GNU General Public License for more details.
|
|
11 *
|
|
12 * You should have received a copy of the GNU General Public License
|
7621
|
13 * aint with this program. If not, see <http://www.gnu.org/licenses/>.
|
7618
|
14 */
|
|
15
|
|
16 /*
|
|
17 * DaoLanguage / Daoyu Compiler and Interpreter.
|
|
18 * Kaynato - 2016
|
|
19 * See splash() for details.
|
|
20 */
|
|
21
|
7580
|
22 #include <stdio.h>
|
|
23 #include <stdlib.h>
|
|
24 #include <string.h>
|
7618
|
25 #include <ctype.h>
|
|
26
|
|
27 #define DEFAULT_INTERPRET_CELL_LENGTH 32
|
|
28 #define BITS_IN_BYTE 8
|
7621
|
29 #define BITS_IN_CELL (sizeof(unsigned int) * 8)
|
7618
|
30 #define BYTE_MASK 0xff
|
|
31 #define INPUT_DELIMITER '@'
|
|
32
|
|
33 typedef struct PATH
|
|
34 {
|
|
35 struct PATH* owner; /* OWNER PROGRAM */
|
|
36 struct PATH* child; /* CHILD PROGRAM */
|
7621
|
37 unsigned int* prg_data; /* DATA */
|
|
38 unsigned int prg_allocbits; /* OPEN DATA BITS*/
|
|
39 unsigned int prg_index; /* INSTRUCTION POINTER*/
|
7618
|
40 unsigned char prg_level; /* OPERATING LEVEL */
|
7621
|
41 unsigned int sel_length; /* LENGTH OF SELECTION*/
|
|
42 unsigned int sel_index; /* INDEX OF SELECTION*/
|
7618
|
43 unsigned int prg_floor; /* FLOOR OF PATH */
|
7621
|
44 unsigned int prg_start; /* START OF RUNNING */
|
7618
|
45 } Pathstrx;
|
|
46
|
|
47 typedef Pathstrx* Path;
|
|
48
|
|
49 static void interpret(char*);
|
|
50
|
|
51 static void swaps(Path), later(Path), merge(Path), sifts(Path), delev(Path), equal(Path), halve(Path);
|
|
52 static void uplev(Path), reads(Path), dealc(Path), split(Path), polar(Path), doalc(Path), input(Path), execs(Path, Path);
|
|
53
|
|
54 char getInput();
|
|
55 char algn(Path);
|
|
56 char getChar(unsigned char);
|
7621
|
57 char* bin(unsigned int);
|
7618
|
58 char* str_dup(char *s);
|
7621
|
59 char* l_to_str(unsigned int, unsigned char, unsigned char);
|
7618
|
60 static void skip();
|
7621
|
61 static void write_by_bit_index(Path, unsigned int, unsigned int, unsigned int);
|
7618
|
62 unsigned char getNybble(char);
|
7621
|
63 unsigned int read_by_bit_index(Path, unsigned int, unsigned int);
|
|
64 unsigned int mask(int);
|
|
65 unsigned int ptwo_round(unsigned int);
|
7618
|
66
|
|
67 static unsigned char command = 0;
|
|
68 static int doloop = 1;
|
|
69
|
|
70 typedef void(*PathFunc)(Path);
|
|
71
|
|
72 static PathFunc functions[16] = \
|
|
73 {NULL, swaps, later, merge, \
|
|
74 sifts, NULL , delev, equal, \
|
|
75 halve, uplev, reads, dealc, \
|
|
76 split, polar, doalc, input};
|
|
77
|
|
78 const struct PATH NEW_PATH = { NULL, NULL, NULL, 1, 0, 0, 1, 0, 0, 0 };
|
|
79
|
|
80 static Path P_RUNNING = NULL,
|
|
81 P_WRITTEN = NULL;
|
|
82
|
|
83 static const char* symbols = ".!/)%#>=(<:S[*$;";
|
|
84
|
|
85 static char* inputptr = NULL;
|
|
86
|
|
87 /* Run argv[0] as code. Input separated by '!' and once empty reads the null character. */
|
|
88 int main(int argc, char * argv[])
|
|
89 {
|
|
90 char* i = argv[1];
|
|
91
|
|
92 /* No argument(s)? */
|
|
93 if (argc < 2)
|
|
94 return 0;
|
|
95
|
|
96 /* Seek input until it either points to delimiter or NUL */
|
|
97 while (*i && *i != INPUT_DELIMITER) i++;
|
|
98
|
|
99 /* If it is the input delimiter then put the inputptr there*/
|
|
100 if (*i == INPUT_DELIMITER)
|
|
101 inputptr = ++i;
|
|
102
|
|
103 interpret(argv[1]);
|
|
104 return 0;
|
|
105 }
|
|
106
|
|
107 #define rc(r,c) case c: return r;
|
|
108
|
|
109 unsigned char getNybble(char ch)
|
|
110 {
|
|
111 switch (ch)
|
|
112 {
|
|
113 rc(0x0, '.') rc(0x1, '!') rc(0x2, '/') rc(0x3, ']': case ')')
|
|
114 rc(0x4, '%') rc(0x5, '#') rc(0x6, '>') rc(0x7, '=')
|
|
115 rc(0x8, '(') rc(0x9, '<') rc(0xA, ':') rc(0xB, 'S')
|
|
116 rc(0xC, '[') rc(0xD, '*') rc(0xE, '$') rc(0xF, ';')
|
|
117 default: return 0x0;
|
|
118 }
|
|
119 }
|
|
120
|
|
121 void interpret(char* input)
|
|
122 {
|
7621
|
123 unsigned int length = 0; /* How many bytes in input */
|
7618
|
124
|
|
125 /* Initialize path */
|
|
126 struct PATH newpath = NEW_PATH;
|
|
127 Path dao = &newpath;
|
|
128
|
|
129 /* Seek end of program input */
|
|
130 while (input[length] && input[length] != INPUT_DELIMITER) length++;
|
|
131
|
|
132 /* Terminate empty program */
|
|
133 if (length == 0) return;
|
|
134
|
|
135 /* Get necessary byte number from nybbles */
|
|
136 length = ptwo_round((length+1) / 2);
|
|
137
|
|
138 /* Set bit length of path */
|
|
139 (dao->prg_allocbits) = length * 8;
|
|
140
|
|
141 /* Prevent zero-sized allocation */
|
7621
|
142 if (length % sizeof(unsigned int) != 0)
|
|
143 length = sizeof(unsigned int);
|
7618
|
144
|
|
145 /* Allocate bytes for data array */
|
|
146 if (((dao->prg_data) = calloc(length, 1)) == NULL)
|
|
147 {
|
|
148 printf("Error allocating %d bytes: ", length);
|
|
149 perror("");
|
|
150 abort();
|
|
151 }
|
|
152
|
|
153 /* Copy over data */
|
|
154 for (length = 0; input[length] && input[length] != INPUT_DELIMITER; length++)
|
|
155 {
|
|
156 int hex = getNybble(input[length]);
|
|
157 write_by_bit_index(dao, 4*length, 4, hex);
|
|
158 }
|
|
159
|
|
160 P_RUNNING = dao; /* For the sake of levlim */
|
|
161
|
|
162 /***************************************************** EXECUTE ******************************************************/
|
|
163 execs(dao, NULL);
|
|
164 free((dao->prg_data));
|
|
165 (dao -> prg_data) = NULL;
|
|
166 /********************************************************************************************************************/
|
|
167
|
|
168 }
|
|
169
|
7621
|
170 unsigned int ptwo_round(unsigned int x)
|
7618
|
171 {
|
7621
|
172 unsigned int rounded = x; /* Initialize bytes_alloc with the file_size value. */
|
|
173 unsigned int shift = 0; /* Shift for first one of file size for rounding */
|
7618
|
174
|
|
175 while ((rounded >> 1) != 0) /* Determine leftmost '1' bit of file size. */
|
|
176 { /* */
|
|
177 rounded >>= 1; /* Shift right until the next shift zeroes it. */
|
|
178 shift++; /* Keep track of shifts. */
|
|
179 } /* */
|
|
180 rounded <<= shift; /* Unshift. */
|
|
181 if (x != rounded) /* If not a power of two, round up. */
|
|
182 rounded <<= 1;
|
|
183
|
|
184 return rounded;
|
|
185 }
|
|
186
|
|
187 char getInput()
|
|
188 {
|
|
189 /* if null return zero */
|
|
190 if (!inputptr)
|
|
191 return 0;
|
|
192
|
|
193 /* If not zero then return-advance */
|
|
194 if (*inputptr)
|
|
195 return *inputptr++;
|
|
196
|
|
197 inputptr = NULL;
|
|
198 return 0;
|
|
199 }
|
|
200
|
|
201 /***
|
|
202 * oooooooooooo ooooooooooooo .oooooo.
|
|
203 * `888' `8 8' 888 `8 d8P' `Y8b
|
|
204 * 888 888 888
|
|
205 * 888oooo8 888 888
|
|
206 * 888 " 888 888
|
|
207 * 888 o 888 `88b ooo
|
|
208 * o888ooooood8 o888o `Y8bood8P'
|
|
209 *
|
|
210 */
|
|
211
|
|
212 #define roc(o,v,c) case o:c=v; return &c;
|
|
213
|
|
214 char *str_dup (char *s) {
|
|
215 char *d = malloc (strlen (s) + 1); /*Allocate memory */
|
|
216 if (d != NULL) strcpy (d,s); /*Copy string if okay */
|
|
217 return d; /*Return new memory */
|
|
218 }
|
|
219
|
7621
|
220 char* bin(unsigned int val) { return l_to_str(val, 32, 2); }
|
7618
|
221
|
|
222 char getChar(unsigned char ch)
|
|
223 {
|
|
224 if (ch > 0xF) return '?';
|
|
225 return symbols[ch];
|
|
226 }
|
|
227
|
7621
|
228 char* l_to_str(unsigned int val, unsigned char len, unsigned char radix)
|
7618
|
229 {
|
|
230 static char buf[32] = { '0' };
|
|
231 int i = 33;
|
|
232 for (; val && i; --i, val /= radix)
|
|
233 buf[i] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"[val % radix];
|
|
234 for (; i; i--)
|
|
235 buf[i] = '0';
|
|
236 return &buf[2 + (32 - len)];
|
|
237 }
|
|
238
|
|
239 /***
|
|
240 * .oooooo..o oooooo oooo ooo ooooo oooooooooo. .oooooo. ooooo .oooooo..o
|
|
241 * d8P' `Y8 `888. .8' `88. .888' `888' `Y8b d8P' `Y8b `888' d8P' `Y8
|
|
242 * Y88bo. `888. .8' 888b d'888 888 888 888 888 888 Y88bo.
|
|
243 * `"Y8888o. `888.8' 8 Y88. .P 888 888oooo888' 888 888 888 `"Y8888o.
|
|
244 * `"Y88b `888' 8 `888' 888 888 `88b 888 888 888 `"Y88b
|
|
245 * oo .d8P 888 8 Y 888 888 .88P `88b d88' 888 o oo .d8P
|
|
246 * 8""88888P' o888o o8o o888o o888bood8P' `Y8bood8P' o888ooooood8 8""88888P'
|
|
247 *
|
|
248 */
|
|
249
|
|
250 #define levlim(l) if (PR_LEV >= l) return;
|
|
251 #define P_LEN (path -> sel_length)
|
|
252 #define P_IND (path -> sel_index)
|
|
253 #define P_ALC (path -> prg_allocbits)
|
|
254 #define P_LEV (path -> prg_level)
|
|
255 #define P_PIND (path -> prg_index)
|
|
256 #define P_DATA (path -> prg_data)
|
|
257 #define P_OWNER (path -> owner)
|
|
258 #define P_CHILD (path -> child)
|
|
259 #define PR_START (P_RUNNING -> prg_start)
|
|
260 #define PR_LEV (P_RUNNING -> prg_level)
|
|
261
|
|
262 static void swaps(Path path)
|
|
263 {
|
|
264 unsigned int i = 0;
|
7621
|
265 unsigned int report = 0;
|
7618
|
266 levlim(1)
|
|
267 if (P_LEN == 1) return;
|
|
268 if (P_LEN <= BITS_IN_CELL)
|
|
269 {
|
7621
|
270 unsigned int half_len = P_LEN / 2;
|
7618
|
271 write_by_bit_index(path, P_IND, P_LEN, read_by_bit_index(path, P_IND, half_len) | (read_by_bit_index(path, P_IND + half_len, half_len) << half_len));
|
|
272 return;
|
|
273 }
|
|
274 while (i < ((P_LEN / BITS_IN_CELL) / 2))
|
|
275 {
|
|
276 report = P_DATA[(P_IND / BITS_IN_CELL) + i];
|
|
277 P_DATA[(P_IND / BITS_IN_CELL) + i] = P_DATA[(P_IND / BITS_IN_CELL) + ((P_LEN / BITS_IN_CELL) / 2) + i];
|
|
278 P_DATA[(P_IND / BITS_IN_CELL) + ((P_LEN / BITS_IN_CELL) / 2) + i++] = report;
|
|
279 }
|
|
280 }
|
|
281
|
|
282 static void later(Path path)
|
|
283 {
|
|
284 if (algn(path) || (PR_LEV >= 4)) P_IND += P_LEN;
|
|
285 else merge(path);
|
|
286 }
|
|
287
|
|
288 static void merge(Path path)
|
|
289 {
|
|
290 levlim(7)
|
|
291 if (P_LEN < P_ALC)
|
|
292 {
|
|
293 if (!algn(path))
|
|
294 P_IND -= P_LEN;
|
|
295 P_LEN <<= 1;
|
|
296 return;
|
|
297 }
|
|
298 if (P_OWNER == NULL)
|
|
299 return;
|
|
300 P_WRITTEN = P_OWNER;
|
|
301 (P_WRITTEN->sel_length) = 1;
|
|
302 (P_WRITTEN->sel_index) = 1;
|
|
303 }
|
|
304
|
|
305 static void sifts(Path path)
|
|
306 {
|
7621
|
307 unsigned int write = P_IND;
|
|
308 unsigned int read = 0;
|
7618
|
309 levlim(5)
|
|
310 while(write<P_ALC)
|
|
311 {
|
|
312 while(!read_by_bit_index(path, write+read, 4))
|
|
313 read += 4;
|
|
314 if(read)
|
|
315 write_by_bit_index(path, write, 4, (write+read<P_ALC)?read_by_bit_index(path, write+read, 4):0);
|
|
316 write += 4;
|
|
317 read += 4;
|
|
318 }
|
|
319 }
|
|
320
|
|
321 static void execs(Path path, Path caller)
|
|
322 {
|
|
323 /***************************************************************EXECUTION LOOP***************************************************************/
|
7621
|
324 unsigned int tempNum1 = 0; /* Expedite calculation */
|
7618
|
325 levlim(8) /* Level operation checking */
|
|
326 P_RUNNING = path; /* Set running */
|
|
327
|
|
328 if (P_CHILD == NULL) /* If there is no child */
|
|
329 {
|
|
330 if ((P_CHILD = (calloc(1, sizeof(struct PATH)))) == NULL) /* Allocate memory space */
|
|
331 { /* Cover error case */
|
|
332 printf("FATAL ERROR: Unable to allocate memory.");
|
|
333 return;
|
|
334 }
|
|
335 memcpy(P_CHILD, &NEW_PATH, sizeof(struct PATH)); /* Copy over initialization data */
|
|
336 (*(*path).child).owner = path; /* Set owner of this new Path */
|
|
337 (*(*path).child).prg_floor = (path->prg_floor) + 1; /* Set floor of this new Path */
|
7621
|
338 (*(*path).child).prg_data = calloc(1, sizeof(unsigned int)); /* Set data of this new Path */
|
7618
|
339 }
|
|
340
|
|
341 P_WRITTEN = P_CHILD; /* Set this as written on */
|
|
342 P_PIND = (P_IND / 4); /* Set program pointer. Rounds down.x */
|
|
343 PR_START = P_PIND; /* Track start position */
|
|
344
|
|
345 for (; doloop && P_PIND < (P_ALC / 4) && path != NULL && P_WRITTEN != NULL ; P_PIND++) /* Execution Loop */
|
|
346 {
|
|
347 tempNum1 = (P_RUNNING->prg_index);
|
|
348 command = ((P_RUNNING->prg_data)[(tempNum1 * 4) / 32] >> (32 - ((tempNum1 * 4) % 32) - 4)) & mask(4); /* Calculate command */
|
|
349
|
|
350 if (command == 5)
|
|
351 execs(P_WRITTEN, path);
|
|
352 else if (command != 0)
|
|
353 functions[command](P_WRITTEN);
|
|
354 }
|
|
355 if (caller == NULL)
|
|
356 {
|
|
357 free(P_CHILD);
|
|
358 P_CHILD = NULL;
|
|
359 return;
|
|
360 }
|
|
361 if (!doloop)
|
|
362 {
|
|
363 free(P_CHILD);
|
|
364 P_CHILD = NULL;
|
|
365 doloop = 1;
|
|
366 }
|
|
367 P_RUNNING = caller;
|
|
368 P_WRITTEN = caller->child;
|
|
369 return;
|
|
370 }
|
|
371
|
|
372 static void delev(Path path)
|
|
373 {
|
|
374 if (PR_LEV > 0) PR_LEV--;
|
|
375 }
|
|
376
|
|
377 static void equal(Path path)
|
|
378 {
|
|
379 levlim(5)
|
|
380 if (read_by_bit_index(path, P_IND, 1) ^ read_by_bit_index(path, P_IND + P_LEN - 1, 1))
|
|
381 skip();
|
|
382 }
|
|
383
|
|
384 static void halve(Path path)
|
|
385 {
|
|
386 levlim(7)
|
|
387 if (P_LEN > 1)
|
|
388 {
|
|
389 P_LEN /= 2;
|
|
390 return;
|
|
391 }
|
|
392 if (P_CHILD == NULL)
|
|
393 return;
|
|
394 P_WRITTEN = P_CHILD;
|
|
395 (P_WRITTEN->sel_length) = (P_WRITTEN->prg_allocbits);
|
|
396 }
|
|
397
|
|
398 static void uplev(Path path)
|
|
399 {
|
|
400 levlim(9)
|
|
401 PR_LEV++;
|
|
402 (P_RUNNING->prg_index) = PR_START - 1;
|
|
403 }
|
|
404
|
|
405 static void reads(Path path)
|
|
406 {
|
7621
|
407 int pos = P_IND;
|
7618
|
408 levlim(6)
|
|
409 if (P_LEN < 8)
|
|
410 {
|
|
411 char* out = bin(read_by_bit_index(path, pos, P_LEN));
|
|
412 printf("%s", &out[strlen(out) - P_LEN]);
|
|
413 return;
|
|
414 }
|
|
415 for (; pos < (P_IND + P_LEN); pos += 8)
|
|
416 putchar(read_by_bit_index(path, pos, 8));
|
|
417 }
|
|
418
|
|
419 static void dealc(Path path)
|
|
420 {
|
|
421 levlim(2)
|
|
422 if (P_ALC == 1)
|
|
423 {
|
|
424 int report = read_by_bit_index(path, 0, 1);
|
|
425 if ((P_RUNNING->owner) != NULL)
|
|
426 {
|
7621
|
427 unsigned int ownind = ((P_RUNNING->owner)->prg_index);
|
7618
|
428 write_by_bit_index(P_RUNNING->owner, (ownind) * 4, 4, report);
|
|
429 }
|
|
430 free(P_DATA);
|
|
431 P_DATA = NULL;
|
|
432 doloop = 0;
|
|
433 return;
|
|
434 }
|
|
435 P_ALC >>= 1;
|
|
436 if (P_ALC <= 8)
|
|
437 realloc(P_DATA, 1);
|
|
438 else
|
|
439 realloc(P_DATA, P_ALC / 8);
|
|
440 if (P_LEN > 1)
|
|
441 halve(path);
|
|
442 if ((P_IND + P_LEN) > P_ALC)
|
|
443 P_IND -= P_ALC;
|
|
444 }
|
|
445
|
|
446 static void split(Path path)
|
|
447 {
|
|
448 if (PR_LEV < 1)
|
|
449 {
|
|
450 unsigned int len = P_LEN;
|
|
451 if (len == 1)
|
|
452 {
|
|
453 if (P_CHILD == NULL)
|
|
454 return;
|
|
455 P_WRITTEN = P_CHILD;
|
|
456 (P_WRITTEN->sel_length) = (P_WRITTEN->prg_allocbits);
|
|
457 split(P_WRITTEN);
|
|
458 halve(P_WRITTEN);
|
|
459 return;
|
|
460 }
|
|
461 if (len <= BITS_IN_CELL)
|
|
462 {
|
|
463 write_by_bit_index(path, P_IND, len >> 1, mask(len));
|
|
464 write_by_bit_index(path, P_IND + (len >> 1), len >> 1, ~mask(len));
|
|
465 }
|
|
466 else
|
|
467 {
|
|
468 unsigned int leftIndex = (P_IND / BITS_IN_CELL);
|
|
469 unsigned int rightIndex = leftIndex + (len / BITS_IN_CELL) - 1;
|
|
470 while (leftIndex < rightIndex)
|
|
471 {
|
|
472 P_DATA[leftIndex++] = 0xFFFFFFFF;
|
|
473 P_DATA[rightIndex--] = 0;
|
|
474 }
|
|
475 }
|
|
476 }
|
|
477 halve(path);
|
|
478 }
|
|
479
|
|
480 static void polar(Path path)
|
|
481 {
|
|
482 levlim(3)
|
|
483 if (!(read_by_bit_index(path, P_IND, 1) && !read_by_bit_index(path, P_IND + P_LEN - 1, 1)))
|
|
484 skip();
|
|
485 }
|
|
486
|
|
487 static void doalc(Path path)
|
|
488 {
|
7621
|
489 unsigned int new_cell_count = 0;
|
|
490 unsigned int* new_data_pointer = NULL;
|
7618
|
491 levlim(1)
|
|
492 P_ALC <<= 1;
|
|
493
|
|
494 if (P_ALC <= BITS_IN_CELL)
|
|
495 new_cell_count = BITS_IN_CELL / BITS_IN_BYTE;
|
|
496 else
|
|
497 new_cell_count = P_ALC / BITS_IN_BYTE;
|
|
498
|
7621
|
499 new_cell_count /= sizeof(unsigned int);
|
7618
|
500
|
7621
|
501 if ((new_data_pointer = calloc(new_cell_count, sizeof(unsigned int))) == NULL)
|
7618
|
502 {
|
7621
|
503 printf("Error allocating %d bytes: ", new_cell_count * sizeof(unsigned int));
|
7618
|
504 perror("");
|
|
505 abort();
|
|
506 }
|
|
507
|
|
508 if (new_cell_count > 1)
|
7621
|
509 memcpy(new_data_pointer, P_DATA, new_cell_count * sizeof(unsigned int) / 2);
|
7618
|
510 else
|
7621
|
511 memcpy(new_data_pointer, P_DATA, sizeof(unsigned int));
|
7618
|
512
|
|
513 P_DATA = new_data_pointer;
|
|
514
|
|
515 merge(path);
|
|
516 }
|
|
517
|
|
518 static void input(Path path)
|
|
519 {
|
|
520 int i = P_IND;
|
|
521 levlim(6)
|
|
522 if (P_LEN < 8)
|
|
523 {
|
|
524 write_by_bit_index(path, P_IND, P_LEN, getInput());
|
|
525 return;
|
|
526 }
|
|
527 for (; i < (P_IND + P_LEN); i += 8)
|
|
528 write_by_bit_index(path, i, 8, getInput());
|
|
529 }
|
|
530
|
|
531 /***
|
|
532 * oooooooooooo ooooooooooooo .oooooo.
|
|
533 * `888' `8 8' 888 `8 d8P' `Y8b
|
|
534 * 888 888 888
|
|
535 * 888oooo8 888 888
|
|
536 * 888 " 888 888
|
|
537 * 888 o 888 `88b ooo
|
|
538 * o888ooooood8 o888o `Y8bood8P'
|
|
539 */
|
|
540
|
|
541 char algn(Path path)
|
|
542 {
|
|
543 return P_IND % (P_LEN << 1) == 0;
|
|
544 }
|
|
545
|
7621
|
546 unsigned int mask(int length)
|
7618
|
547 {
|
|
548 if (length < BITS_IN_CELL) return ((int)1 << length) - 1;
|
|
549 else return 0xFFFFFFFF;
|
|
550 }
|
|
551
|
7621
|
552 unsigned int read_by_bit_index(Path path, unsigned int i, unsigned int len)
|
7618
|
553 {
|
|
554 return (P_DATA[i / BITS_IN_CELL] >> (BITS_IN_CELL - (i % BITS_IN_CELL) - len)) & mask(len);
|
|
555 }
|
|
556
|
7621
|
557 static void write_by_bit_index(Path path, unsigned int i, unsigned int len, unsigned int write)
|
7618
|
558 {
|
|
559 int shift = BITS_IN_CELL - (i % BITS_IN_CELL) - len;
|
|
560 if (len > BITS_IN_CELL) abort();
|
|
561 P_DATA[i / BITS_IN_CELL] &= ~(mask(len) << shift);
|
|
562 P_DATA[i / BITS_IN_CELL] |= ((write & mask(len)) << shift);
|
|
563 }
|
|
564
|
|
565 static void skip()
|
|
566 {
|
|
567 if (P_RUNNING == NULL) return;
|
|
568 (P_RUNNING->prg_index)++;
|
|
569 } |