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