• R/O
  • SSH
  • HTTPS

jpl: Commit


Commit MetaInfo

Revision537 (tree)
Time2019-03-26 01:49:34
Authorjakobthomsen

Log Message

remove test

Change Summary

  • delete: trunk/experimental_memflex/makefile
  • delete: trunk/experimental_memflex/compiler.compiled.c
  • delete: trunk/experimental_memflex/compiler.source.c
  • delete: trunk/experimental_memflex

Incremental Difference

--- trunk/experimental_memflex/compiler.source.c (revision 536)
+++ trunk/experimental_memflex/compiler.source.c (nonexistent)
@@ -1,766 +0,0 @@
1-intro
2-{
3- `
4- /////////////////////////////////////////////////////////////////////////////
5- // Another attempt writing a self-hosting compiler with own memory-management
6- // for a Total Imperative Programming Language. (c) 8.3.2019 by Jakob Thomsen
7- /////////////////////////////////////////////////////////////////////////////
8-
9- printf("#include <ctype.h>\n");
10- printf("#include <stdbool.h>\n");
11- printf("#include <stdint.h>\n");
12- printf("#include <stdio.h>\n");
13- printf("#include <stdlib.h>\n");
14- printf("#include <string.h>\n");
15- printf("\n");
16- printf("struct memory_pair\n");
17- printf("{\n");
18- printf(" uint64_t elem0;\n");
19- printf(" uint64_t elem1;\n");
20- printf("};\n");
21- printf("\n");
22- printf("// If all memory is allocated in one value of size n 2 (almost) all n values will be needed (one pair remaining)\n");
23- printf("struct memory_value\n");
24- printf("{\n");
25- printf(" struct memory_pair pair;\n");
26- printf(" uint64_t value;\n");
27- printf("};\n");
28- printf("\n");
29- printf("#define LAST_INDEX 511\n");
30- printf("\n");
31- printf("// NOTE: memory[0] never used (reserved to mark invalid address)\n");
32- printf("// NOTE: NEVER copy whole memory-element, e.g. memory[i] = memory[j], this indicates an error!\n");
33- printf("// NOTE: pairs & values are only stored in a struct to compile-time prove same amount of both.\n");
34- printf("struct memory_value memory[LAST_INDEX + 1];\n");
35- printf("uint64_t value_avail_max = LAST_INDEX;\n");
36- printf("uint64_t value_avail_addr = LAST_INDEX;\n");
37- printf("uint64_t pair_avail_max = LAST_INDEX;\n");
38- printf("uint64_t pair_avail_addr = LAST_INDEX;\n");
39- printf("\n");
40- printf("void mem_show()\n");
41- printf("{\n");
42- printf(" fprintf(stderr, \"CURRENT MEMORY ALLOCATION: %%d values, %%d pairs of %%d\\n\", (int)(LAST_INDEX - value_avail_max), (int)(LAST_INDEX - pair_avail_max), (int)LAST_INDEX);\n");
43- printf("}\n");
44- printf("\n");
45- printf("void mem_check()\n");
46- printf("{\n");
47- printf(" if(value_avail_max > LAST_INDEX || pair_avail_max > LAST_INDEX)\n");
48- printf(" {\n");
49- printf(" fprintf(stderr, \"MEMORY ERROR\\n\");\n");
50- printf(" mem_show();\n");
51- printf(" exit(-1);\n");
52- printf(" }\n");
53- printf("\n");
54- printf(" if(value_avail_max < LAST_INDEX || pair_avail_max < LAST_INDEX)\n");
55- printf(" {\n");
56- printf(" fprintf(stderr, \"MEMORY LEAK\\n\");\n");
57- printf(" mem_show();\n");
58- printf(" exit(-1);\n");
59- printf(" }\n");
60- printf("\n");
61- printf(" for(;pair_avail_max > 1; --pair_avail_max)\n");
62- printf(" {\n");
63- printf(" //fprintf(stderr, \"%%d\\n\", (int)pair_avail_max);\n");
64- printf(" if(!memory[pair_avail_addr].pair.elem0)\n");
65- printf(" {\n");
66- printf(" fprintf(stderr, \"PAIR FREE-LIST TRUNCATED\\n\");\n");
67- printf(" exit(-1);\n");
68- printf(" }\n");
69- printf("\n");
70- printf(" uint64_t next = memory[pair_avail_addr].pair.elem0;\n");
71- printf(" memory[pair_avail_addr].pair.elem0 = 0;\n");
72- printf(" pair_avail_addr = next;\n");
73- printf(" }\n");
74- printf("\n");
75- printf(" if(memory[pair_avail_addr].pair.elem0)\n");
76- printf(" {\n");
77- printf(" fprintf(stderr, \"PAIR FREE-LIST INCOMPLETE\\n\");\n");
78- printf(" exit(-1);\n");
79- printf(" }\n");
80- printf("\n");
81- printf(" for(;value_avail_max > 1; --value_avail_max)\n");
82- printf(" {\n");
83- printf(" //fprintf(stderr, \"%%d\\n\", (int)value_avail_max);\n");
84- printf(" if(!memory[value_avail_addr].value)\n");
85- printf(" {\n");
86- printf(" fprintf(stderr, \"VALUE FREE-LIST TRUNCATED\\n\");\n");
87- printf(" exit(-1);\n");
88- printf(" }\n");
89- printf("\n");
90- printf(" uint64_t next = memory[value_avail_addr].value;\n");
91- printf(" memory[value_avail_addr].value = 0;\n");
92- printf(" value_avail_addr = next;\n");
93- printf(" }\n");
94- printf("\n");
95- printf(" if(memory[value_avail_addr].value)\n");
96- printf(" {\n");
97- printf(" fprintf(stderr, \"VALUE FREE-LIST INCOMPLETE\\n\");\n");
98- printf(" exit(-1);\n");
99- printf(" }\n");
100- printf("\n");
101- printf(" fprintf(stderr, \"ALL MEMORY RELEASED CORRECTLY\\n\");\n");
102- printf("}\n");
103- printf("\n");
104- printf("// initialize free-lists\n");
105- printf("void mem_init() // NOTE: as a welcome side-effect initialization should prevent memory-overcommit\n");
106- printf("{\n");
107- printf(" for(uint64_t i = LAST_INDEX; i > 0; --i)\n");
108- printf(" {\n");
109- printf(" memory[i].value = i - 1;\n");
110- printf(" memory[i].pair.elem0 = i - 1;\n");
111- printf(" memory[i].pair.elem1 = ~0; // should be ignored\n");
112- printf(" }\n");
113- printf("}\n");
114- printf("\n");
115- printf("uint64_t value_alloc()\n");
116- printf("{\n");
117- printf(" if(!value_avail_max)\n");
118- printf(" {\n");
119- printf(" fprintf(stderr, \"value_alloc: OUT OF MEMORY\\\\n\");\n");
120- printf(" exit(-1);\n");
121- printf(" }\n");
122- printf(" --value_avail_max;\n");
123- printf(" uint64_t new_addr = value_avail_addr;\n");
124- printf(" value_avail_addr = memory[new_addr].value;\n");
125- printf(" //fprintf(stderr, \"allocated value at addr %%d, remaining size %%d\\\\n\", (int)new_addr, (int)value_avail_max + 1);\n");
126- printf(" return new_addr;\n");
127- printf("}\n");
128- printf("\n");
129- printf("void value_free(uint64_t addr)\n");
130- printf("{\n");
131- printf(" if(!addr)\n");
132- printf(" return;\n");
133- printf("\n");
134- printf(" value_avail_max++;\n");
135- printf(" memory[addr].value = value_avail_addr;\n");
136- printf(" value_avail_addr = addr;\n");
137- printf(" //fprintf(stderr, \"freed value at addr %%d, remaining size %%d\\\\n\", (int)addr, (int)value_avail_max + 1);\n");
138- printf("}\n");
139- printf("\n");
140- printf("uint64_t value_alloc_and_set(uint64_t value)\n");
141- printf("{\n");
142- printf(" uint64_t addr = value_alloc();\n");
143- printf(" memory[addr].value = value;\n");
144- printf(" return addr;\n");
145- printf("}\n");
146- printf("\n");
147- printf("uint64_t value_free_and_get(uint64_t addr)\n");
148- printf("{\n");
149- printf(" uint64_t value = memory[addr].value;\n");
150- printf(" value_free(addr);\n");
151- printf(" return value;\n");
152- printf("}\n");
153- printf("\n");
154- printf("uint64_t pair_alloc()\n");
155- printf("{\n");
156- printf(" if(!pair_avail_max)\n");
157- printf(" {\n");
158- printf(" fprintf(stderr, \"pair_alloc: OUT OF MEMORY\\\\n\");\n");
159- printf(" exit(-1);\n");
160- printf(" }\n");
161- printf(" --pair_avail_max;\n");
162- printf(" uint64_t new_addr = pair_avail_addr;\n");
163- printf(" pair_avail_addr = memory[new_addr].pair.elem0;\n");
164- printf(" //fprintf(stderr, \"allocated pair at addr %%d, remaining size %%d\\\\n\", (int)new_addr, (int)pair_avail_max + 1);\n");
165- printf(" return new_addr;\n");
166- printf("}\n");
167- printf("\n");
168- printf("void pair_free(uint64_t addr)\n");
169- printf("{\n");
170- printf(" if(!addr)\n");
171- printf(" return;\n");
172- printf("\n");
173- printf(" pair_avail_max++;\n");
174- printf(" memory[addr].pair.elem0 = pair_avail_addr;\n");
175- printf(" pair_avail_addr = addr;\n");
176- printf(" //fprintf(stderr, \"freed pair at addr %%d, remaining size %%d\\\\n\", (int)addr, (int)pair_avail_max + 1);\n");
177- printf("}\n");
178- printf("\n");
179- printf("uint64_t pair_alloc_and_set(struct memory_pair pair)\n");
180- printf("{\n");
181- printf(" uint64_t addr = pair_alloc();\n");
182- printf(" memory[addr].pair = pair;\n");
183- printf(" return addr;\n");
184- printf("}\n");
185- printf("\n");
186- printf("struct memory_pair pair_free_and_get(uint64_t addr)\n");
187- printf("{\n");
188- printf(" struct memory_pair pair = memory[addr].pair;\n");
189- printf(" pair_free(addr);\n");
190- printf(" return pair;\n");
191- printf("}\n");
192- printf("\n");
193- printf("struct memory_pair pair(uint64_t elem0, uint64_t elem1)\n");
194- printf("{\n");
195- printf(" struct memory_pair pair;\n");
196- printf(" pair.elem0 = elem0;\n");
197- printf(" pair.elem1 = elem1;\n");
198- printf(" return pair;\n");
199- printf("}\n");
200- printf("\n");
201- printf("uint64_t tuple2_alloc(uint64_t elem0, uint64_t elem1)\n");
202- printf("{\n");
203- printf(" return pair_alloc_and_set(pair(value_alloc_and_set(elem0), value_alloc_and_set(elem1)));\n");
204- printf("}\n");
205- printf("\n");
206- printf("void tuple2_free(uint64_t root)\n");
207- printf("{\n");
208- printf(" struct memory_pair pair = pair_free_and_get(root);\n");
209- printf(" value_free(pair.elem0);\n");
210- printf(" value_free(pair.elem1);\n");
211- printf("}\n");
212- printf("\n");
213- printf("uint64_t tuple2_access0(uint64_t root)\n");
214- printf("{\n");
215- printf(" struct memory_pair pair = memory[root].pair;\n");
216- printf(" return pair.elem0;\n");
217- printf("}\n");
218- printf("\n");
219- printf("uint64_t tuple2_access1(uint64_t root)\n");
220- printf("{\n");
221- printf(" struct memory_pair pair = memory[root].pair;\n");
222- printf(" return pair.elem1;\n");
223- printf("}\n");
224- printf("\n");
225- printf("uint64_t full_tree_alloc(uint64_t height)\n");
226- printf("{\n");
227- printf(" if(!height)\n");
228- printf(" return value_alloc();\n");
229- printf("\n");
230- printf(" --height;\n");
231- printf(" return pair_alloc_and_set(pair(full_tree_alloc(height), full_tree_alloc(height)));\n");
232- printf("}\n");
233- printf("\n");
234- printf("void full_tree_free(uint64_t height, uint64_t root)\n");
235- printf("{\n");
236- printf(" if(!height)\n");
237- printf(" {\n");
238- printf(" value_free(root);\n");
239- printf(" return;\n");
240- printf(" }\n");
241- printf("\n");
242- printf(" --height;\n");
243- printf(" struct memory_pair pair = pair_free_and_get(root);\n");
244- printf(" full_tree_free(height, pair.elem0);\n");
245- printf(" full_tree_free(height, pair.elem1);\n");
246- printf("}\n");
247- printf("\n");
248- printf("uint64_t full_tree_access(uint64_t height, uint64_t root, uint64_t index)\n");
249- printf("{\n");
250- printf(" if(!height)\n");
251- printf(" {\n");
252- printf(" //fprintf(stderr, \"ACCESS at addr %%d\\\\n\", (int)root);\n");
253- printf(" return root;\n");
254- printf(" }\n");
255- printf("\n");
256- printf(" --height;\n");
257- printf(" struct memory_pair pair = memory[root].pair;\n");
258- printf(" bool bit = (index >> height) & 1;\n");
259- printf(" return full_tree_access(height, bit ? pair.elem1 : pair.elem0, index);\n");
260- printf("}\n");
261- printf("\n");
262- printf("uint64_t full_tree_dup(uint64_t height, uint64_t root)\n");
263- printf("{\n");
264- printf(" return pair_alloc_and_set(pair(root, full_tree_alloc(height + 1)));\n");
265- printf("}\n");
266- printf("\n");
267- printf("uint64_t full_tree_half(uint64_t height, uint64_t root)\n");
268- printf("{\n");
269- printf(" if(!height)\n");
270- printf(" return 0;\n");
271- printf("\n");
272- printf(" full_tree_free(height - 1, memory[root].pair.elem1);\n");
273- printf(" return pair_free_and_get(root).elem0;\n");
274- printf("}\n");
275- printf("\n");
276- printf("struct full_tree_with_height\n");
277- printf("{\n");
278- printf(" uint64_t height;\n");
279- printf(" uint64_t root;\n");
280- printf("};\n");
281- printf("\n");
282- printf("struct full_tree_with_height full_tree_with_height_alloc(uint64_t height)\n");
283- printf("{\n");
284- printf(" //fprintf(stderr, \"ALLOC HEIGHT %%d\\\\n\", (int)height);\n");
285- printf(" struct full_tree_with_height tree;\n");
286- printf(" tree.height = height;\n");
287- printf(" tree.root = full_tree_alloc(height);\n");
288- printf(" return tree;\n");
289- printf("}\n");
290- printf("\n");
291- printf("void full_tree_with_height_free(struct full_tree_with_height *const tree)\n");
292- printf("{\n");
293- printf(" //fprintf(stderr, \"FREE HEIGHT %%d\\\\n\", (int)tree->height);\n");
294- printf(" full_tree_free(tree->height, tree->root);\n");
295- printf(" tree->height = 0;\n");
296- printf(" tree->root = 0;\n");
297- printf("}\n");
298- printf("\n");
299- printf("uint64_t full_tree_with_height_access(struct full_tree_with_height tree, uint64_t index)\n");
300- printf("{\n");
301- printf(" return full_tree_access(tree.height, tree.root, index);\n");
302- printf("}\n");
303- printf("\n");
304- printf("void full_tree_with_height_dup(struct full_tree_with_height *const tree)\n");
305- printf("{\n");
306- printf(" tree->root = pair_alloc_and_set(pair(tree->root, full_tree_alloc(tree->height)));\n");
307- printf(" ++tree->height;\n");
308- printf("}\n");
309- printf("\n");
310- printf("void full_tree_with_height_half(struct full_tree_with_height *const tree)\n");
311- printf("{\n");
312- printf(" if(!tree->height)\n");
313- printf(" {\n");
314- printf(" fprintf(stderr, \"ERROR: full_tree_with_height_half UNDERFLOW\\n\");\n");
315- printf(" exit(-1);\n");
316- printf(" }\n");
317- printf(" else\n");
318- printf(" {\n");
319- printf(" --tree->height;\n");
320- printf(" full_tree_free(tree->height, memory[tree->root].pair.elem1);\n");
321- printf(" tree->root = pair_free_and_get(tree->root).elem0;\n");
322- printf(" }\n");
323- printf("}\n");
324- printf("\n");
325- printf("struct stack\n");
326- printf("{\n");
327- printf(" uint64_t root;\n");
328- printf(" uint64_t size;\n");
329- printf("};\n");
330- printf("\n");
331- printf("struct stack stack_alloc(uint64_t size)\n");
332- printf("{\n");
333- printf(" struct stack stack;\n");
334- printf(" stack.root = 0;\n");
335- printf(" stack.size = size;\n");
336- printf(" uint64_t height = 0;\n");
337- printf(" if(size)\n");
338- printf(" {\n");
339- printf(" while(!(size & 1))\n");
340- printf(" {\n");
341- printf(" height++;\n");
342- printf(" size >>= 1;\n");
343- printf(" }\n");
344- printf("\n");
345- printf(" stack.root = full_tree_alloc(height);\n");
346- printf("\n");
347- printf(" size >>= 1;\n");
348- printf(" height++;\n");
349- printf("\n");
350- printf(" while(size)\n");
351- printf(" {\n");
352- printf(" if(size & 1)\n");
353- printf(" {\n");
354- printf(" stack.root = pair_alloc_and_set(pair(full_tree_alloc(height), stack.root));\n");
355- printf(" }\n");
356- printf("\n");
357- printf(" height++;\n");
358- printf(" size >>= 1;\n");
359- printf(" }\n");
360- printf(" }\n");
361- printf("\n");
362- printf(" return stack;\n");
363- printf("}\n");
364- printf("\n");
365- printf("void stack_free(struct stack *const stack)\n");
366- printf("{\n");
367- printf(" if(stack->size)\n");
368- printf(" {\n");
369- printf(" uint64_t height = 64;\n");
370- printf(" while(height > 0)\n");
371- printf(" {\n");
372- printf(" height--;\n");
373- printf("\n");
374- printf(" uint64_t mask = 1llu << height;\n");
375- printf(" if(stack->size & mask)\n");
376- printf(" {\n");
377- printf(" stack->size &= ~mask;\n");
378- printf(" if(!stack->size)\n");
379- printf(" break;\n");
380- printf("\n");
381- printf(" full_tree_free(height, memory[stack->root].pair.elem0);\n");
382- printf(" stack->root = pair_free_and_get(stack->root).elem1;\n");
383- printf(" }\n");
384- printf(" }\n");
385- printf("\n");
386- printf(" full_tree_free(height, stack->root);\n");
387- printf(" }\n");
388- printf("}\n");
389- printf("\n");
390- printf("uint64_t count_ones(uint64_t size)\n");
391- printf("{\n");
392- printf(" uint64_t spine = 0;\n");
393- printf(" while(size) // count ones\n");
394- printf(" {\n");
395- printf(" while(!(size & 1)) // skip zeroes\n");
396- printf(" {\n");
397- printf(" size >>= 1; // zero\n");
398- printf(" }\n");
399- printf("\n");
400- printf(" size >>= 1; // one\n");
401- printf(" spine++;\n");
402- printf(" }\n");
403- printf("\n");
404- printf(" return spine;\n");
405- printf("}\n");
406- printf("\n");
407- printf("void stack_push(struct stack *const stack, uint64_t value)\n");
408- printf("{\n");
409- printf(" uint64_t *ptr = &stack->root;\n");
410- printf(" uint64_t spine = count_ones(stack->size++);\n");
411- printf("\n");
412- printf(" if(!spine)\n");
413- printf(" {\n");
414- printf(" stack->root = value_alloc_and_set(value);\n");
415- printf(" return;\n");
416- printf(" }\n");
417- printf("\n");
418- printf(" while(spine > 1)\n");
419- printf(" {\n");
420- printf(" --spine;\n");
421- printf(" ptr = &memory[*ptr].pair.elem1;\n");
422- printf(" }\n");
423- printf("\n");
424- printf(" *ptr = pair_alloc_and_set(pair(*ptr, value_alloc_and_set(value)));\n");
425- printf("}\n");
426- printf("\n");
427- printf("uint64_t stack_pop(struct stack *const stack)\n");
428- printf("{\n");
429- printf(" if(!stack->size)\n");
430- printf(" {\n");
431- printf(" fprintf(stderr, \"pop: ERROR, stack empty!\\n\");\n");
432- printf(" exit(-1);\n");
433- printf(" }\n");
434- printf("\n");
435- printf(" uint64_t *ptr = &stack->root;\n");
436- printf(" uint64_t spine = count_ones(--stack->size);\n");
437- printf("\n");
438- printf(" if(!spine)\n");
439- printf(" return value_free_and_get(*ptr);\n");
440- printf("\n");
441- printf(" while(spine > 1)\n");
442- printf(" {\n");
443- printf(" --spine;\n");
444- printf(" ptr = &memory[*ptr].pair.elem1;\n");
445- printf(" }\n");
446- printf("\n");
447- printf(" uint64_t result = value_free_and_get(memory[*ptr].pair.elem1);\n");
448- printf(" uint64_t sub = memory[*ptr].pair.elem0;\n");
449- printf(" pair_free(*ptr);\n");
450- printf(" *ptr = sub;\n");
451- printf("\n");
452- printf(" return result;\n");
453- printf("}\n");
454- printf("\n");
455- printf("uint64_t stack_elem_addr(struct stack stack, uint64_t index)\n");
456- printf("{\n");
457- printf(" uint64_t node = stack.root;\n");
458- printf("\n");
459- printf(" if(index < stack.size) // NOTE: this implies stack.size > 0\n");
460- printf(" {\n");
461- printf(" uint64_t last = stack.size - 1;\n");
462- printf(" uint64_t height = 64;\n");
463- printf("\n");
464- printf(" // select full tree\n");
465- printf(" while(height > 0)\n");
466- printf(" {\n");
467- printf(" height--;\n");
468- printf(" uint64_t mask = 1llu << height;\n");
469- printf("\n");
470- printf(" if(last & mask)\n");
471- printf(" {\n");
472- printf(" if(index & mask)\n");
473- printf(" {\n");
474- printf(" node = memory[node].pair.elem1;\n");
475- printf(" }\n");
476- printf(" else\n");
477- printf(" {\n");
478- printf(" node = memory[node].pair.elem0;\n");
479- printf(" break;\n");
480- printf(" }\n");
481- printf(" }\n");
482- printf(" }\n");
483- printf("\n");
484- printf(" // select leaf in full tree\n");
485- printf(" while(height > 0)\n");
486- printf(" {\n");
487- printf(" height--;\n");
488- printf("\n");
489- printf(" uint64_t mask = 1llu << height;\n");
490- printf(" if(index & mask)\n");
491- printf(" {\n");
492- printf(" node = memory[node].pair.elem1;\n");
493- printf(" }\n");
494- printf(" else\n");
495- printf(" {\n");
496- printf(" node = memory[node].pair.elem0;\n");
497- printf(" }\n");
498- printf(" }\n");
499- printf(" }\n");
500- printf(" else\n");
501- printf(" {\n");
502- printf(" fprintf(stderr, \"index %%d out of range 0..%%d\\n\", (int)index, (int)stack.size);\n");
503- printf(" exit(-1);\n");
504- printf(" }\n");
505- printf("\n");
506- printf(" return node;\n");
507- printf("}\n");
508- printf("\n");
509- printf("uint64_t *stack_elem_ref(struct stack stack, uint64_t index)\n");
510- printf("{\n");
511- printf(" return &memory[stack_elem_addr(stack, index)].value;\n");
512- printf("}\n");
513- printf("\n");
514- printf("struct state\n");
515- printf("{\n");
516- printf(" uint64_t stackbase;\n");
517- printf(" struct stack callstack;\n");
518- printf(" uint64_t addr;\n");
519- printf(" uint64_t tmpaddr;\n");
520- printf("};\n");
521- printf("\n");
522- printf("void complete(struct state *const state)\n");
523- printf("{\n");
524- printf(" while(state->callstack.size > state->stackbase) (void)stack_pop(&state->callstack);\n");
525- printf(" state->addr = stack_pop(&state->callstack);");
526- printf(" state->stackbase = stack_pop(&state->callstack);");
527- printf("}\n");
528- printf("\n");
529- printf("void callbegin(struct state *const state, uint64_t resultsize, uint64_t returnaddr, uint64_t dest)\n");
530- printf("{\n");
531- printf(" while(resultsize)\n");
532- printf(" {\n");
533- printf(" --resultsize;\n");
534- printf(" stack_push(&state->callstack, 0); // reserve space for result\n");
535- printf(" }\n");
536- printf(" stack_push(&state->callstack, state->stackbase);\n");
537- printf(" stack_push(&state->callstack, returnaddr);\n");
538- printf(" state->stackbase = state->callstack.size;\n");
539- printf(" state->addr = dest;\n");
540- printf("}\n");
541- printf("\n");
542- printf("void arg_push(struct state *const state, uint64_t value)\n");
543- printf("{\n");
544- printf(" stack_push(&state->callstack, value);\n");
545- printf("}\n");
546- printf("\n");
547- printf("uint64_t *par_ref(const struct state *const state, uint64_t offset)\n");
548- printf("{\n");
549- printf(" return stack_elem_ref(state->callstack, state->stackbase + offset);\n");
550- printf("}\n");
551- printf("\n");
552- printf("uint64_t parsenr()\n");
553- printf("{\n");
554- printf(" uint64_t nr = 0;\n");
555- printf(" while(isdigit(ungetc(getchar(), stdin)))\n");
556- printf(" {\n");
557- printf(" nr = 10 * nr + ((uint64_t)getchar() - '0');\n");
558- printf(" }\n");
559- printf(" return nr;\n");
560- printf("}\n");
561- printf("\n");
562- printf("uint64_t parseid()\n");
563- printf("{\n");
564- printf(" uint64_t id = 0;\n");
565- printf(" uint64_t n = 10;\n");
566- printf(" uint32_t c = 0;\n");
567- printf(" while(true)\n");
568- printf(" {\n");
569- printf(" c = (uint32_t)getchar();\n");
570- printf(" if(n > 0)\n");
571- printf(" {\n");
572- printf(" --n;\n");
573- printf(" if('_' == c) id |= ((uint64_t)c - '_' + 0) << (n * 6);\n");
574- printf(" else if(isupper(c)) id |= ((uint64_t)c - 'A' + 1) << (n * 6);\n");
575- printf(" else if('$' == c) id |= ((uint64_t)c - '$' + 27) << (n * 6);\n");
576- printf(" else if(islower(c)) id |= ((uint64_t)c - 'a' + 28) << (n * 6);\n");
577- printf(" else if(isdigit(c)) id |= ((uint64_t)c - '0' + 54) << (n * 6);\n");
578- printf(" else\n");
579- printf(" {\n");
580- printf(" ungetc((int)c, stdin);\n");
581- printf(" break;\n");
582- printf(" }\n");
583- printf(" }\n");
584- printf(" else\n");
585- printf(" {\n");
586- printf(" ungetc((int)c, stdin);\n");
587- printf(" break;\n");
588- printf(" }\n");
589- printf(" }\n");
590- printf(" return id;\n");
591- printf("}\n");
592- printf("\n");
593- printf("int main()\n");
594- printf("{\n");
595- printf(" mem_init();\n");
596- printf(" struct state state;\n");
597- printf(" state.tmpaddr = 0; // assign temporary addresses highest first (pre-decrement)\n");
598- printf(" state.callstack = stack_alloc(0);\n");
599- printf(" state.stackbase = 0;\n");
600- printf(" callbegin(&state, 1/*resultsize*/, 0/*end marker*/, 0xA1C929000000000LLU/*main*/);\n");
601- printf(" while(state.addr)\n");
602- printf(" {\n");
603- printf(" switch(state.addr)\n");
604- printf(" {\n");
605-`
606-
607-}
608-
609-outro
610-{
611- `
612- // outro
613- printf(" default:\n");
614- printf(" fprintf(stderr, \"no such state %%d\\n\", (int)state.addr);\n");
615- printf(" //return (int)state.addr;\n");
616- printf(" exit(-1);\n");
617- printf(" }\n");
618- printf(" }\n");
619- printf("\n");
620- printf(" uint64_t result = stack_pop(&state.callstack);");
621- printf(" if(state.callstack.size)\n");
622- printf(" {\n");
623- printf(" fprintf(stderr, \"callstack not empty (%%llu)\\n\", (unsigned long long)state.callstack.size);\n");
624- printf(" }\n");
625- printf(" stack_free(&state.callstack);\n");
626- printf(" mem_show();\n");
627- printf(" mem_check();\n");
628- printf("\n");
629- printf(" return (int)result;\n");
630- printf("}\n");
631- printf("\n");
632- `
633-}
634-
635-onchar
636-{
637- `
638- uint32_t c = (uint32_t)*par_ref(&state, 0);
639- //fprintf(stderr, "%c", (char)c);
640- if(!isspace(c)) // skip WS
641- {
642- printf(" case ");
643- if(isalpha(c))
644- {
645- ungetc(c, stdin);
646- printf("0x%0llXLLU", (long long unsigned)parseid());
647- c = getchar();
648- }
649- else
650- {
651- fprintf(stderr, "unexpected char '%c'\n", c);
652- exit(-1);
653- }
654-
655- printf(":\n");
656- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
657-
658- if(123 == c)
659- {
660- // match brace open
661- }
662- else
663- {
664- fprintf(stderr, "missing '{', unexpected char '%c'\n", c);
665- exit(-1);
666- }
667- printf(" {\n");
668- bool in_c_code = false;
669- for(c = (uint32_t)getchar(); c <= 255; c = (uint32_t)getchar())
670- {
671- if(96 == c)
672- {
673- in_c_code = !in_c_code;
674- continue;
675- }
676-
677- if(in_c_code)
678- {
679- putchar((int)c);
680- if(10 == c)
681- printf(" ");
682- }
683- else
684- {
685- if(125 == c)
686- {
687- printf("\n");
688- printf(" complete(&state);");
689- break;
690- }
691- else if(isalpha(c))
692- {
693- ungetc(c, stdin);
694- uint64_t dest = parseid();
695- c = getchar();
696- uint64_t return_here = --state.tmpaddr;
697-
698- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
699- if('(' != c)
700- {
701- fprintf(stderr, "missing '(' in call\n");
702- exit(-1);
703- }
704-
705- c = (uint32_t)getchar();
706- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
707- if(')' != c)
708- {
709- fprintf(stderr, "missing ')' in call\n");
710- exit(-1);
711- }
712-
713- printf("\n");
714- printf(" callbegin(&state, 1/*resultsize*/, 0x%0llXLLU, 0x%0llXLLU);\n", (unsigned long long)return_here, (unsigned long long)dest);
715- printf(" break;\n");
716- printf(" }\n");
717- printf(" case 0x%0llXLLU:\n", (unsigned long long)return_here);
718- printf(" {\n");
719- }
720- else if('@' == c)
721- {
722- c = (uint32_t)getchar();
723- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
724-
725- ungetc(c, stdin);
726- uint64_t fn = parseid();
727- c = getchar();
728-
729- uint64_t loop = --state.tmpaddr;
730-
731- printf("\n");
732- printf(" state.addr = 0x%0llXLLU;\n", (unsigned long long)loop);
733- printf(" break;\n");
734- printf(" }\n");
735- printf(" case 0x%0llXLLU:\n", (unsigned long long)loop);
736- printf(" {\n");
737- printf(" if((uint32_t)ungetc(getchar(), stdin) < 256)\n");
738- printf(" {\n");
739- printf(" callbegin(&state, 0/*NO result!*/, 0x%0llXLLU, 0x%0llXLLU);\n", (unsigned long long)loop, (unsigned long long)fn);
740- printf(" arg_push(&state, (uint64_t)getchar());\n");
741- printf(" break;\n");
742- printf(" }\n");
743- }
744- else if(!isspace(c))
745- {
746- fprintf(stderr, "unexpected char '%c'\n", c);
747- exit(-1);
748- }
749- }
750- }
751- printf("\n");
752- printf(" break;\n");
753- printf(" }\n");
754- }
755- `
756-}
757-
758-main
759-{
760- intro()
761-
762- @ onchar
763-
764- outro()
765-}
766-
--- trunk/experimental_memflex/compiler.compiled.c (revision 536)
+++ trunk/experimental_memflex/compiler.compiled.c (nonexistent)
@@ -1,1401 +0,0 @@
1-#include <ctype.h>
2-#include <stdbool.h>
3-#include <stdint.h>
4-#include <stdio.h>
5-#include <stdlib.h>
6-#include <string.h>
7-
8-struct memory_pair
9-{
10- uint64_t elem0;
11- uint64_t elem1;
12-};
13-
14-// If all memory is allocated in one value of size n 2 (almost) all n values will be needed (one pair remaining)
15-struct memory_value
16-{
17- struct memory_pair pair;
18- uint64_t value;
19-};
20-
21-#define LAST_INDEX 511
22-
23-// NOTE: memory[0] never used (reserved to mark invalid address)
24-// NOTE: NEVER copy whole memory-element, e.g. memory[i] = memory[j], this indicates an error!
25-// NOTE: pairs & values are only stored in a struct to compile-time prove same amount of both.
26-struct memory_value memory[LAST_INDEX + 1];
27-uint64_t value_avail_max = LAST_INDEX;
28-uint64_t value_avail_addr = LAST_INDEX;
29-uint64_t pair_avail_max = LAST_INDEX;
30-uint64_t pair_avail_addr = LAST_INDEX;
31-
32-void mem_show()
33-{
34- fprintf(stderr, "CURRENT MEMORY ALLOCATION: %d values, %d pairs of %d\n", (int)(LAST_INDEX - value_avail_max), (int)(LAST_INDEX - pair_avail_max), (int)LAST_INDEX);
35-}
36-
37-void mem_check()
38-{
39- if(value_avail_max > LAST_INDEX || pair_avail_max > LAST_INDEX)
40- {
41- fprintf(stderr, "MEMORY ERROR\n");
42- mem_show();
43- exit(-1);
44- }
45-
46- if(value_avail_max < LAST_INDEX || pair_avail_max < LAST_INDEX)
47- {
48- fprintf(stderr, "MEMORY LEAK\n");
49- mem_show();
50- exit(-1);
51- }
52-
53- for(;pair_avail_max > 1; --pair_avail_max)
54- {
55- //fprintf(stderr, "%d\n", (int)pair_avail_max);
56- if(!memory[pair_avail_addr].pair.elem0)
57- {
58- fprintf(stderr, "PAIR FREE-LIST TRUNCATED\n");
59- exit(-1);
60- }
61-
62- uint64_t next = memory[pair_avail_addr].pair.elem0;
63- memory[pair_avail_addr].pair.elem0 = 0;
64- pair_avail_addr = next;
65- }
66-
67- if(memory[pair_avail_addr].pair.elem0)
68- {
69- fprintf(stderr, "PAIR FREE-LIST INCOMPLETE\n");
70- exit(-1);
71- }
72-
73- for(;value_avail_max > 1; --value_avail_max)
74- {
75- //fprintf(stderr, "%d\n", (int)value_avail_max);
76- if(!memory[value_avail_addr].value)
77- {
78- fprintf(stderr, "VALUE FREE-LIST TRUNCATED\n");
79- exit(-1);
80- }
81-
82- uint64_t next = memory[value_avail_addr].value;
83- memory[value_avail_addr].value = 0;
84- value_avail_addr = next;
85- }
86-
87- if(memory[value_avail_addr].value)
88- {
89- fprintf(stderr, "VALUE FREE-LIST INCOMPLETE\n");
90- exit(-1);
91- }
92-
93- fprintf(stderr, "ALL MEMORY RELEASED CORRECTLY\n");
94-}
95-
96-// initialize free-lists
97-void mem_init() // NOTE: as a welcome side-effect initialization should prevent memory-overcommit
98-{
99- for(uint64_t i = LAST_INDEX; i > 0; --i)
100- {
101- memory[i].value = i - 1;
102- memory[i].pair.elem0 = i - 1;
103- memory[i].pair.elem1 = ~0; // should be ignored
104- }
105-}
106-
107-uint64_t value_alloc()
108-{
109- if(!value_avail_max)
110- {
111- fprintf(stderr, "value_alloc: OUT OF MEMORY\\n");
112- exit(-1);
113- }
114- --value_avail_max;
115- uint64_t new_addr = value_avail_addr;
116- value_avail_addr = memory[new_addr].value;
117- //fprintf(stderr, "allocated value at addr %d, remaining size %d\\n", (int)new_addr, (int)value_avail_max + 1);
118- return new_addr;
119-}
120-
121-void value_free(uint64_t addr)
122-{
123- if(!addr)
124- return;
125-
126- value_avail_max++;
127- memory[addr].value = value_avail_addr;
128- value_avail_addr = addr;
129- //fprintf(stderr, "freed value at addr %d, remaining size %d\\n", (int)addr, (int)value_avail_max + 1);
130-}
131-
132-uint64_t value_alloc_and_set(uint64_t value)
133-{
134- uint64_t addr = value_alloc();
135- memory[addr].value = value;
136- return addr;
137-}
138-
139-uint64_t value_free_and_get(uint64_t addr)
140-{
141- uint64_t value = memory[addr].value;
142- value_free(addr);
143- return value;
144-}
145-
146-uint64_t pair_alloc()
147-{
148- if(!pair_avail_max)
149- {
150- fprintf(stderr, "pair_alloc: OUT OF MEMORY\\n");
151- exit(-1);
152- }
153- --pair_avail_max;
154- uint64_t new_addr = pair_avail_addr;
155- pair_avail_addr = memory[new_addr].pair.elem0;
156- //fprintf(stderr, "allocated pair at addr %d, remaining size %d\\n", (int)new_addr, (int)pair_avail_max + 1);
157- return new_addr;
158-}
159-
160-void pair_free(uint64_t addr)
161-{
162- if(!addr)
163- return;
164-
165- pair_avail_max++;
166- memory[addr].pair.elem0 = pair_avail_addr;
167- pair_avail_addr = addr;
168- //fprintf(stderr, "freed pair at addr %d, remaining size %d\\n", (int)addr, (int)pair_avail_max + 1);
169-}
170-
171-uint64_t pair_alloc_and_set(struct memory_pair pair)
172-{
173- uint64_t addr = pair_alloc();
174- memory[addr].pair = pair;
175- return addr;
176-}
177-
178-struct memory_pair pair_free_and_get(uint64_t addr)
179-{
180- struct memory_pair pair = memory[addr].pair;
181- pair_free(addr);
182- return pair;
183-}
184-
185-struct memory_pair pair(uint64_t elem0, uint64_t elem1)
186-{
187- struct memory_pair pair;
188- pair.elem0 = elem0;
189- pair.elem1 = elem1;
190- return pair;
191-}
192-
193-uint64_t tuple2_alloc(uint64_t elem0, uint64_t elem1)
194-{
195- return pair_alloc_and_set(pair(value_alloc_and_set(elem0), value_alloc_and_set(elem1)));
196-}
197-
198-void tuple2_free(uint64_t root)
199-{
200- struct memory_pair pair = pair_free_and_get(root);
201- value_free(pair.elem0);
202- value_free(pair.elem1);
203-}
204-
205-uint64_t tuple2_access0(uint64_t root)
206-{
207- struct memory_pair pair = memory[root].pair;
208- return pair.elem0;
209-}
210-
211-uint64_t tuple2_access1(uint64_t root)
212-{
213- struct memory_pair pair = memory[root].pair;
214- return pair.elem1;
215-}
216-
217-uint64_t full_tree_alloc(uint64_t height)
218-{
219- if(!height)
220- return value_alloc();
221-
222- --height;
223- return pair_alloc_and_set(pair(full_tree_alloc(height), full_tree_alloc(height)));
224-}
225-
226-void full_tree_free(uint64_t height, uint64_t root)
227-{
228- if(!height)
229- {
230- value_free(root);
231- return;
232- }
233-
234- --height;
235- struct memory_pair pair = pair_free_and_get(root);
236- full_tree_free(height, pair.elem0);
237- full_tree_free(height, pair.elem1);
238-}
239-
240-uint64_t full_tree_access(uint64_t height, uint64_t root, uint64_t index)
241-{
242- if(!height)
243- {
244- //fprintf(stderr, "ACCESS at addr %d\\n", (int)root);
245- return root;
246- }
247-
248- --height;
249- struct memory_pair pair = memory[root].pair;
250- bool bit = (index >> height) & 1;
251- return full_tree_access(height, bit ? pair.elem1 : pair.elem0, index);
252-}
253-
254-uint64_t full_tree_dup(uint64_t height, uint64_t root)
255-{
256- return pair_alloc_and_set(pair(root, full_tree_alloc(height + 1)));
257-}
258-
259-uint64_t full_tree_half(uint64_t height, uint64_t root)
260-{
261- if(!height)
262- return 0;
263-
264- full_tree_free(height - 1, memory[root].pair.elem1);
265- return pair_free_and_get(root).elem0;
266-}
267-
268-struct full_tree_with_height
269-{
270- uint64_t height;
271- uint64_t root;
272-};
273-
274-struct full_tree_with_height full_tree_with_height_alloc(uint64_t height)
275-{
276- //fprintf(stderr, "ALLOC HEIGHT %d\\n", (int)height);
277- struct full_tree_with_height tree;
278- tree.height = height;
279- tree.root = full_tree_alloc(height);
280- return tree;
281-}
282-
283-void full_tree_with_height_free(struct full_tree_with_height *const tree)
284-{
285- //fprintf(stderr, "FREE HEIGHT %d\\n", (int)tree->height);
286- full_tree_free(tree->height, tree->root);
287- tree->height = 0;
288- tree->root = 0;
289-}
290-
291-uint64_t full_tree_with_height_access(struct full_tree_with_height tree, uint64_t index)
292-{
293- return full_tree_access(tree.height, tree.root, index);
294-}
295-
296-void full_tree_with_height_dup(struct full_tree_with_height *const tree)
297-{
298- tree->root = pair_alloc_and_set(pair(tree->root, full_tree_alloc(tree->height)));
299- ++tree->height;
300-}
301-
302-void full_tree_with_height_half(struct full_tree_with_height *const tree)
303-{
304- if(!tree->height)
305- {
306- fprintf(stderr, "ERROR: full_tree_with_height_half UNDERFLOW\n");
307- exit(-1);
308- }
309- else
310- {
311- --tree->height;
312- full_tree_free(tree->height, memory[tree->root].pair.elem1);
313- tree->root = pair_free_and_get(tree->root).elem0;
314- }
315-}
316-
317-struct stack
318-{
319- uint64_t root;
320- uint64_t size;
321-};
322-
323-struct stack stack_alloc(uint64_t size)
324-{
325- struct stack stack;
326- stack.root = 0;
327- stack.size = size;
328- uint64_t height = 0;
329- if(size)
330- {
331- while(!(size & 1))
332- {
333- height++;
334- size >>= 1;
335- }
336-
337- stack.root = full_tree_alloc(height);
338-
339- size >>= 1;
340- height++;
341-
342- while(size)
343- {
344- if(size & 1)
345- {
346- stack.root = pair_alloc_and_set(pair(full_tree_alloc(height), stack.root));
347- }
348-
349- height++;
350- size >>= 1;
351- }
352- }
353-
354- return stack;
355-}
356-
357-void stack_free(struct stack *const stack)
358-{
359- if(stack->size)
360- {
361- uint64_t height = 64;
362- while(height > 0)
363- {
364- height--;
365-
366- uint64_t mask = 1llu << height;
367- if(stack->size & mask)
368- {
369- stack->size &= ~mask;
370- if(!stack->size)
371- break;
372-
373- full_tree_free(height, memory[stack->root].pair.elem0);
374- stack->root = pair_free_and_get(stack->root).elem1;
375- }
376- }
377-
378- full_tree_free(height, stack->root);
379- }
380-}
381-
382-uint64_t count_ones(uint64_t size)
383-{
384- uint64_t spine = 0;
385- while(size) // count ones
386- {
387- while(!(size & 1)) // skip zeroes
388- {
389- size >>= 1; // zero
390- }
391-
392- size >>= 1; // one
393- spine++;
394- }
395-
396- return spine;
397-}
398-
399-void stack_push(struct stack *const stack, uint64_t value)
400-{
401- uint64_t *ptr = &stack->root;
402- uint64_t spine = count_ones(stack->size++);
403-
404- if(!spine)
405- {
406- stack->root = value_alloc_and_set(value);
407- return;
408- }
409-
410- while(spine > 1)
411- {
412- --spine;
413- ptr = &memory[*ptr].pair.elem1;
414- }
415-
416- *ptr = pair_alloc_and_set(pair(*ptr, value_alloc_and_set(value)));
417-}
418-
419-uint64_t stack_pop(struct stack *const stack)
420-{
421- if(!stack->size)
422- {
423- fprintf(stderr, "pop: ERROR, stack empty!\n");
424- exit(-1);
425- }
426-
427- uint64_t *ptr = &stack->root;
428- uint64_t spine = count_ones(--stack->size);
429-
430- if(!spine)
431- return value_free_and_get(*ptr);
432-
433- while(spine > 1)
434- {
435- --spine;
436- ptr = &memory[*ptr].pair.elem1;
437- }
438-
439- uint64_t result = value_free_and_get(memory[*ptr].pair.elem1);
440- uint64_t sub = memory[*ptr].pair.elem0;
441- pair_free(*ptr);
442- *ptr = sub;
443-
444- return result;
445-}
446-
447-uint64_t stack_elem_addr(struct stack stack, uint64_t index)
448-{
449- uint64_t node = stack.root;
450-
451- if(index < stack.size) // NOTE: this implies stack.size > 0
452- {
453- uint64_t last = stack.size - 1;
454- uint64_t height = 64;
455-
456- // select full tree
457- while(height > 0)
458- {
459- height--;
460- uint64_t mask = 1llu << height;
461-
462- if(last & mask)
463- {
464- if(index & mask)
465- {
466- node = memory[node].pair.elem1;
467- }
468- else
469- {
470- node = memory[node].pair.elem0;
471- break;
472- }
473- }
474- }
475-
476- // select leaf in full tree
477- while(height > 0)
478- {
479- height--;
480-
481- uint64_t mask = 1llu << height;
482- if(index & mask)
483- {
484- node = memory[node].pair.elem1;
485- }
486- else
487- {
488- node = memory[node].pair.elem0;
489- }
490- }
491- }
492- else
493- {
494- fprintf(stderr, "index %d out of range 0..%d\n", (int)index, (int)stack.size);
495- exit(-1);
496- }
497-
498- return node;
499-}
500-
501-uint64_t *stack_elem_ref(struct stack stack, uint64_t index)
502-{
503- return &memory[stack_elem_addr(stack, index)].value;
504-}
505-
506-struct state
507-{
508- uint64_t stackbase;
509- struct stack callstack;
510- uint64_t addr;
511- uint64_t tmpaddr;
512-};
513-
514-void complete(struct state *const state)
515-{
516- while(state->callstack.size > state->stackbase) (void)stack_pop(&state->callstack);
517- state->addr = stack_pop(&state->callstack); state->stackbase = stack_pop(&state->callstack);}
518-
519-void callbegin(struct state *const state, uint64_t resultsize, uint64_t returnaddr, uint64_t dest)
520-{
521- while(resultsize)
522- {
523- --resultsize;
524- stack_push(&state->callstack, 0); // reserve space for result
525- }
526- stack_push(&state->callstack, state->stackbase);
527- stack_push(&state->callstack, returnaddr);
528- state->stackbase = state->callstack.size;
529- state->addr = dest;
530-}
531-
532-void arg_push(struct state *const state, uint64_t value)
533-{
534- stack_push(&state->callstack, value);
535-}
536-
537-uint64_t *par_ref(const struct state *const state, uint64_t offset)
538-{
539- return stack_elem_ref(state->callstack, state->stackbase + offset);
540-}
541-
542-uint64_t parsenr()
543-{
544- uint64_t nr = 0;
545- while(isdigit(ungetc(getchar(), stdin)))
546- {
547- nr = 10 * nr + ((uint64_t)getchar() - '0');
548- }
549- return nr;
550-}
551-
552-uint64_t parseid()
553-{
554- uint64_t id = 0;
555- uint64_t n = 10;
556- uint32_t c = 0;
557- while(true)
558- {
559- c = (uint32_t)getchar();
560- if(n > 0)
561- {
562- --n;
563- if('_' == c) id |= ((uint64_t)c - '_' + 0) << (n * 6);
564- else if(isupper(c)) id |= ((uint64_t)c - 'A' + 1) << (n * 6);
565- else if('$' == c) id |= ((uint64_t)c - '$' + 27) << (n * 6);
566- else if(islower(c)) id |= ((uint64_t)c - 'a' + 28) << (n * 6);
567- else if(isdigit(c)) id |= ((uint64_t)c - '0' + 54) << (n * 6);
568- else
569- {
570- ungetc((int)c, stdin);
571- break;
572- }
573- }
574- else
575- {
576- ungetc((int)c, stdin);
577- break;
578- }
579- }
580- return id;
581-}
582-
583-int main()
584-{
585- mem_init();
586- struct state state;
587- state.tmpaddr = 0; // assign temporary addresses highest first (pre-decrement)
588- state.callstack = stack_alloc(0);
589- state.stackbase = 0;
590- callbegin(&state, 1/*resultsize*/, 0/*end marker*/, 0xA1C929000000000LLU/*main*/);
591- while(state.addr)
592- {
593- switch(state.addr)
594- {
595- case 0x929BEDA80000000LLU:
596- {
597-
598- /////////////////////////////////////////////////////////////////////////////
599- // Another attempt writing a self-hosting compiler with own memory-management
600- // for a Total Imperative Programming Language. (c) 8.3.2019 by Jakob Thomsen
601- /////////////////////////////////////////////////////////////////////////////
602-
603- printf("#include <ctype.h>\n");
604- printf("#include <stdbool.h>\n");
605- printf("#include <stdint.h>\n");
606- printf("#include <stdio.h>\n");
607- printf("#include <stdlib.h>\n");
608- printf("#include <string.h>\n");
609- printf("\n");
610- printf("struct memory_pair\n");
611- printf("{\n");
612- printf(" uint64_t elem0;\n");
613- printf(" uint64_t elem1;\n");
614- printf("};\n");
615- printf("\n");
616- printf("// If all memory is allocated in one value of size n 2 (almost) all n values will be needed (one pair remaining)\n");
617- printf("struct memory_value\n");
618- printf("{\n");
619- printf(" struct memory_pair pair;\n");
620- printf(" uint64_t value;\n");
621- printf("};\n");
622- printf("\n");
623- printf("#define LAST_INDEX 511\n");
624- printf("\n");
625- printf("// NOTE: memory[0] never used (reserved to mark invalid address)\n");
626- printf("// NOTE: NEVER copy whole memory-element, e.g. memory[i] = memory[j], this indicates an error!\n");
627- printf("// NOTE: pairs & values are only stored in a struct to compile-time prove same amount of both.\n");
628- printf("struct memory_value memory[LAST_INDEX + 1];\n");
629- printf("uint64_t value_avail_max = LAST_INDEX;\n");
630- printf("uint64_t value_avail_addr = LAST_INDEX;\n");
631- printf("uint64_t pair_avail_max = LAST_INDEX;\n");
632- printf("uint64_t pair_avail_addr = LAST_INDEX;\n");
633- printf("\n");
634- printf("void mem_show()\n");
635- printf("{\n");
636- printf(" fprintf(stderr, \"CURRENT MEMORY ALLOCATION: %%d values, %%d pairs of %%d\\n\", (int)(LAST_INDEX - value_avail_max), (int)(LAST_INDEX - pair_avail_max), (int)LAST_INDEX);\n");
637- printf("}\n");
638- printf("\n");
639- printf("void mem_check()\n");
640- printf("{\n");
641- printf(" if(value_avail_max > LAST_INDEX || pair_avail_max > LAST_INDEX)\n");
642- printf(" {\n");
643- printf(" fprintf(stderr, \"MEMORY ERROR\\n\");\n");
644- printf(" mem_show();\n");
645- printf(" exit(-1);\n");
646- printf(" }\n");
647- printf("\n");
648- printf(" if(value_avail_max < LAST_INDEX || pair_avail_max < LAST_INDEX)\n");
649- printf(" {\n");
650- printf(" fprintf(stderr, \"MEMORY LEAK\\n\");\n");
651- printf(" mem_show();\n");
652- printf(" exit(-1);\n");
653- printf(" }\n");
654- printf("\n");
655- printf(" for(;pair_avail_max > 1; --pair_avail_max)\n");
656- printf(" {\n");
657- printf(" //fprintf(stderr, \"%%d\\n\", (int)pair_avail_max);\n");
658- printf(" if(!memory[pair_avail_addr].pair.elem0)\n");
659- printf(" {\n");
660- printf(" fprintf(stderr, \"PAIR FREE-LIST TRUNCATED\\n\");\n");
661- printf(" exit(-1);\n");
662- printf(" }\n");
663- printf("\n");
664- printf(" uint64_t next = memory[pair_avail_addr].pair.elem0;\n");
665- printf(" memory[pair_avail_addr].pair.elem0 = 0;\n");
666- printf(" pair_avail_addr = next;\n");
667- printf(" }\n");
668- printf("\n");
669- printf(" if(memory[pair_avail_addr].pair.elem0)\n");
670- printf(" {\n");
671- printf(" fprintf(stderr, \"PAIR FREE-LIST INCOMPLETE\\n\");\n");
672- printf(" exit(-1);\n");
673- printf(" }\n");
674- printf("\n");
675- printf(" for(;value_avail_max > 1; --value_avail_max)\n");
676- printf(" {\n");
677- printf(" //fprintf(stderr, \"%%d\\n\", (int)value_avail_max);\n");
678- printf(" if(!memory[value_avail_addr].value)\n");
679- printf(" {\n");
680- printf(" fprintf(stderr, \"VALUE FREE-LIST TRUNCATED\\n\");\n");
681- printf(" exit(-1);\n");
682- printf(" }\n");
683- printf("\n");
684- printf(" uint64_t next = memory[value_avail_addr].value;\n");
685- printf(" memory[value_avail_addr].value = 0;\n");
686- printf(" value_avail_addr = next;\n");
687- printf(" }\n");
688- printf("\n");
689- printf(" if(memory[value_avail_addr].value)\n");
690- printf(" {\n");
691- printf(" fprintf(stderr, \"VALUE FREE-LIST INCOMPLETE\\n\");\n");
692- printf(" exit(-1);\n");
693- printf(" }\n");
694- printf("\n");
695- printf(" fprintf(stderr, \"ALL MEMORY RELEASED CORRECTLY\\n\");\n");
696- printf("}\n");
697- printf("\n");
698- printf("// initialize free-lists\n");
699- printf("void mem_init() // NOTE: as a welcome side-effect initialization should prevent memory-overcommit\n");
700- printf("{\n");
701- printf(" for(uint64_t i = LAST_INDEX; i > 0; --i)\n");
702- printf(" {\n");
703- printf(" memory[i].value = i - 1;\n");
704- printf(" memory[i].pair.elem0 = i - 1;\n");
705- printf(" memory[i].pair.elem1 = ~0; // should be ignored\n");
706- printf(" }\n");
707- printf("}\n");
708- printf("\n");
709- printf("uint64_t value_alloc()\n");
710- printf("{\n");
711- printf(" if(!value_avail_max)\n");
712- printf(" {\n");
713- printf(" fprintf(stderr, \"value_alloc: OUT OF MEMORY\\\\n\");\n");
714- printf(" exit(-1);\n");
715- printf(" }\n");
716- printf(" --value_avail_max;\n");
717- printf(" uint64_t new_addr = value_avail_addr;\n");
718- printf(" value_avail_addr = memory[new_addr].value;\n");
719- printf(" //fprintf(stderr, \"allocated value at addr %%d, remaining size %%d\\\\n\", (int)new_addr, (int)value_avail_max + 1);\n");
720- printf(" return new_addr;\n");
721- printf("}\n");
722- printf("\n");
723- printf("void value_free(uint64_t addr)\n");
724- printf("{\n");
725- printf(" if(!addr)\n");
726- printf(" return;\n");
727- printf("\n");
728- printf(" value_avail_max++;\n");
729- printf(" memory[addr].value = value_avail_addr;\n");
730- printf(" value_avail_addr = addr;\n");
731- printf(" //fprintf(stderr, \"freed value at addr %%d, remaining size %%d\\\\n\", (int)addr, (int)value_avail_max + 1);\n");
732- printf("}\n");
733- printf("\n");
734- printf("uint64_t value_alloc_and_set(uint64_t value)\n");
735- printf("{\n");
736- printf(" uint64_t addr = value_alloc();\n");
737- printf(" memory[addr].value = value;\n");
738- printf(" return addr;\n");
739- printf("}\n");
740- printf("\n");
741- printf("uint64_t value_free_and_get(uint64_t addr)\n");
742- printf("{\n");
743- printf(" uint64_t value = memory[addr].value;\n");
744- printf(" value_free(addr);\n");
745- printf(" return value;\n");
746- printf("}\n");
747- printf("\n");
748- printf("uint64_t pair_alloc()\n");
749- printf("{\n");
750- printf(" if(!pair_avail_max)\n");
751- printf(" {\n");
752- printf(" fprintf(stderr, \"pair_alloc: OUT OF MEMORY\\\\n\");\n");
753- printf(" exit(-1);\n");
754- printf(" }\n");
755- printf(" --pair_avail_max;\n");
756- printf(" uint64_t new_addr = pair_avail_addr;\n");
757- printf(" pair_avail_addr = memory[new_addr].pair.elem0;\n");
758- printf(" //fprintf(stderr, \"allocated pair at addr %%d, remaining size %%d\\\\n\", (int)new_addr, (int)pair_avail_max + 1);\n");
759- printf(" return new_addr;\n");
760- printf("}\n");
761- printf("\n");
762- printf("void pair_free(uint64_t addr)\n");
763- printf("{\n");
764- printf(" if(!addr)\n");
765- printf(" return;\n");
766- printf("\n");
767- printf(" pair_avail_max++;\n");
768- printf(" memory[addr].pair.elem0 = pair_avail_addr;\n");
769- printf(" pair_avail_addr = addr;\n");
770- printf(" //fprintf(stderr, \"freed pair at addr %%d, remaining size %%d\\\\n\", (int)addr, (int)pair_avail_max + 1);\n");
771- printf("}\n");
772- printf("\n");
773- printf("uint64_t pair_alloc_and_set(struct memory_pair pair)\n");
774- printf("{\n");
775- printf(" uint64_t addr = pair_alloc();\n");
776- printf(" memory[addr].pair = pair;\n");
777- printf(" return addr;\n");
778- printf("}\n");
779- printf("\n");
780- printf("struct memory_pair pair_free_and_get(uint64_t addr)\n");
781- printf("{\n");
782- printf(" struct memory_pair pair = memory[addr].pair;\n");
783- printf(" pair_free(addr);\n");
784- printf(" return pair;\n");
785- printf("}\n");
786- printf("\n");
787- printf("struct memory_pair pair(uint64_t elem0, uint64_t elem1)\n");
788- printf("{\n");
789- printf(" struct memory_pair pair;\n");
790- printf(" pair.elem0 = elem0;\n");
791- printf(" pair.elem1 = elem1;\n");
792- printf(" return pair;\n");
793- printf("}\n");
794- printf("\n");
795- printf("uint64_t tuple2_alloc(uint64_t elem0, uint64_t elem1)\n");
796- printf("{\n");
797- printf(" return pair_alloc_and_set(pair(value_alloc_and_set(elem0), value_alloc_and_set(elem1)));\n");
798- printf("}\n");
799- printf("\n");
800- printf("void tuple2_free(uint64_t root)\n");
801- printf("{\n");
802- printf(" struct memory_pair pair = pair_free_and_get(root);\n");
803- printf(" value_free(pair.elem0);\n");
804- printf(" value_free(pair.elem1);\n");
805- printf("}\n");
806- printf("\n");
807- printf("uint64_t tuple2_access0(uint64_t root)\n");
808- printf("{\n");
809- printf(" struct memory_pair pair = memory[root].pair;\n");
810- printf(" return pair.elem0;\n");
811- printf("}\n");
812- printf("\n");
813- printf("uint64_t tuple2_access1(uint64_t root)\n");
814- printf("{\n");
815- printf(" struct memory_pair pair = memory[root].pair;\n");
816- printf(" return pair.elem1;\n");
817- printf("}\n");
818- printf("\n");
819- printf("uint64_t full_tree_alloc(uint64_t height)\n");
820- printf("{\n");
821- printf(" if(!height)\n");
822- printf(" return value_alloc();\n");
823- printf("\n");
824- printf(" --height;\n");
825- printf(" return pair_alloc_and_set(pair(full_tree_alloc(height), full_tree_alloc(height)));\n");
826- printf("}\n");
827- printf("\n");
828- printf("void full_tree_free(uint64_t height, uint64_t root)\n");
829- printf("{\n");
830- printf(" if(!height)\n");
831- printf(" {\n");
832- printf(" value_free(root);\n");
833- printf(" return;\n");
834- printf(" }\n");
835- printf("\n");
836- printf(" --height;\n");
837- printf(" struct memory_pair pair = pair_free_and_get(root);\n");
838- printf(" full_tree_free(height, pair.elem0);\n");
839- printf(" full_tree_free(height, pair.elem1);\n");
840- printf("}\n");
841- printf("\n");
842- printf("uint64_t full_tree_access(uint64_t height, uint64_t root, uint64_t index)\n");
843- printf("{\n");
844- printf(" if(!height)\n");
845- printf(" {\n");
846- printf(" //fprintf(stderr, \"ACCESS at addr %%d\\\\n\", (int)root);\n");
847- printf(" return root;\n");
848- printf(" }\n");
849- printf("\n");
850- printf(" --height;\n");
851- printf(" struct memory_pair pair = memory[root].pair;\n");
852- printf(" bool bit = (index >> height) & 1;\n");
853- printf(" return full_tree_access(height, bit ? pair.elem1 : pair.elem0, index);\n");
854- printf("}\n");
855- printf("\n");
856- printf("uint64_t full_tree_dup(uint64_t height, uint64_t root)\n");
857- printf("{\n");
858- printf(" return pair_alloc_and_set(pair(root, full_tree_alloc(height + 1)));\n");
859- printf("}\n");
860- printf("\n");
861- printf("uint64_t full_tree_half(uint64_t height, uint64_t root)\n");
862- printf("{\n");
863- printf(" if(!height)\n");
864- printf(" return 0;\n");
865- printf("\n");
866- printf(" full_tree_free(height - 1, memory[root].pair.elem1);\n");
867- printf(" return pair_free_and_get(root).elem0;\n");
868- printf("}\n");
869- printf("\n");
870- printf("struct full_tree_with_height\n");
871- printf("{\n");
872- printf(" uint64_t height;\n");
873- printf(" uint64_t root;\n");
874- printf("};\n");
875- printf("\n");
876- printf("struct full_tree_with_height full_tree_with_height_alloc(uint64_t height)\n");
877- printf("{\n");
878- printf(" //fprintf(stderr, \"ALLOC HEIGHT %%d\\\\n\", (int)height);\n");
879- printf(" struct full_tree_with_height tree;\n");
880- printf(" tree.height = height;\n");
881- printf(" tree.root = full_tree_alloc(height);\n");
882- printf(" return tree;\n");
883- printf("}\n");
884- printf("\n");
885- printf("void full_tree_with_height_free(struct full_tree_with_height *const tree)\n");
886- printf("{\n");
887- printf(" //fprintf(stderr, \"FREE HEIGHT %%d\\\\n\", (int)tree->height);\n");
888- printf(" full_tree_free(tree->height, tree->root);\n");
889- printf(" tree->height = 0;\n");
890- printf(" tree->root = 0;\n");
891- printf("}\n");
892- printf("\n");
893- printf("uint64_t full_tree_with_height_access(struct full_tree_with_height tree, uint64_t index)\n");
894- printf("{\n");
895- printf(" return full_tree_access(tree.height, tree.root, index);\n");
896- printf("}\n");
897- printf("\n");
898- printf("void full_tree_with_height_dup(struct full_tree_with_height *const tree)\n");
899- printf("{\n");
900- printf(" tree->root = pair_alloc_and_set(pair(tree->root, full_tree_alloc(tree->height)));\n");
901- printf(" ++tree->height;\n");
902- printf("}\n");
903- printf("\n");
904- printf("void full_tree_with_height_half(struct full_tree_with_height *const tree)\n");
905- printf("{\n");
906- printf(" if(!tree->height)\n");
907- printf(" {\n");
908- printf(" fprintf(stderr, \"ERROR: full_tree_with_height_half UNDERFLOW\\n\");\n");
909- printf(" exit(-1);\n");
910- printf(" }\n");
911- printf(" else\n");
912- printf(" {\n");
913- printf(" --tree->height;\n");
914- printf(" full_tree_free(tree->height, memory[tree->root].pair.elem1);\n");
915- printf(" tree->root = pair_free_and_get(tree->root).elem0;\n");
916- printf(" }\n");
917- printf("}\n");
918- printf("\n");
919- printf("struct stack\n");
920- printf("{\n");
921- printf(" uint64_t root;\n");
922- printf(" uint64_t size;\n");
923- printf("};\n");
924- printf("\n");
925- printf("struct stack stack_alloc(uint64_t size)\n");
926- printf("{\n");
927- printf(" struct stack stack;\n");
928- printf(" stack.root = 0;\n");
929- printf(" stack.size = size;\n");
930- printf(" uint64_t height = 0;\n");
931- printf(" if(size)\n");
932- printf(" {\n");
933- printf(" while(!(size & 1))\n");
934- printf(" {\n");
935- printf(" height++;\n");
936- printf(" size >>= 1;\n");
937- printf(" }\n");
938- printf("\n");
939- printf(" stack.root = full_tree_alloc(height);\n");
940- printf("\n");
941- printf(" size >>= 1;\n");
942- printf(" height++;\n");
943- printf("\n");
944- printf(" while(size)\n");
945- printf(" {\n");
946- printf(" if(size & 1)\n");
947- printf(" {\n");
948- printf(" stack.root = pair_alloc_and_set(pair(full_tree_alloc(height), stack.root));\n");
949- printf(" }\n");
950- printf("\n");
951- printf(" height++;\n");
952- printf(" size >>= 1;\n");
953- printf(" }\n");
954- printf(" }\n");
955- printf("\n");
956- printf(" return stack;\n");
957- printf("}\n");
958- printf("\n");
959- printf("void stack_free(struct stack *const stack)\n");
960- printf("{\n");
961- printf(" if(stack->size)\n");
962- printf(" {\n");
963- printf(" uint64_t height = 64;\n");
964- printf(" while(height > 0)\n");
965- printf(" {\n");
966- printf(" height--;\n");
967- printf("\n");
968- printf(" uint64_t mask = 1llu << height;\n");
969- printf(" if(stack->size & mask)\n");
970- printf(" {\n");
971- printf(" stack->size &= ~mask;\n");
972- printf(" if(!stack->size)\n");
973- printf(" break;\n");
974- printf("\n");
975- printf(" full_tree_free(height, memory[stack->root].pair.elem0);\n");
976- printf(" stack->root = pair_free_and_get(stack->root).elem1;\n");
977- printf(" }\n");
978- printf(" }\n");
979- printf("\n");
980- printf(" full_tree_free(height, stack->root);\n");
981- printf(" }\n");
982- printf("}\n");
983- printf("\n");
984- printf("uint64_t count_ones(uint64_t size)\n");
985- printf("{\n");
986- printf(" uint64_t spine = 0;\n");
987- printf(" while(size) // count ones\n");
988- printf(" {\n");
989- printf(" while(!(size & 1)) // skip zeroes\n");
990- printf(" {\n");
991- printf(" size >>= 1; // zero\n");
992- printf(" }\n");
993- printf("\n");
994- printf(" size >>= 1; // one\n");
995- printf(" spine++;\n");
996- printf(" }\n");
997- printf("\n");
998- printf(" return spine;\n");
999- printf("}\n");
1000- printf("\n");
1001- printf("void stack_push(struct stack *const stack, uint64_t value)\n");
1002- printf("{\n");
1003- printf(" uint64_t *ptr = &stack->root;\n");
1004- printf(" uint64_t spine = count_ones(stack->size++);\n");
1005- printf("\n");
1006- printf(" if(!spine)\n");
1007- printf(" {\n");
1008- printf(" stack->root = value_alloc_and_set(value);\n");
1009- printf(" return;\n");
1010- printf(" }\n");
1011- printf("\n");
1012- printf(" while(spine > 1)\n");
1013- printf(" {\n");
1014- printf(" --spine;\n");
1015- printf(" ptr = &memory[*ptr].pair.elem1;\n");
1016- printf(" }\n");
1017- printf("\n");
1018- printf(" *ptr = pair_alloc_and_set(pair(*ptr, value_alloc_and_set(value)));\n");
1019- printf("}\n");
1020- printf("\n");
1021- printf("uint64_t stack_pop(struct stack *const stack)\n");
1022- printf("{\n");
1023- printf(" if(!stack->size)\n");
1024- printf(" {\n");
1025- printf(" fprintf(stderr, \"pop: ERROR, stack empty!\\n\");\n");
1026- printf(" exit(-1);\n");
1027- printf(" }\n");
1028- printf("\n");
1029- printf(" uint64_t *ptr = &stack->root;\n");
1030- printf(" uint64_t spine = count_ones(--stack->size);\n");
1031- printf("\n");
1032- printf(" if(!spine)\n");
1033- printf(" return value_free_and_get(*ptr);\n");
1034- printf("\n");
1035- printf(" while(spine > 1)\n");
1036- printf(" {\n");
1037- printf(" --spine;\n");
1038- printf(" ptr = &memory[*ptr].pair.elem1;\n");
1039- printf(" }\n");
1040- printf("\n");
1041- printf(" uint64_t result = value_free_and_get(memory[*ptr].pair.elem1);\n");
1042- printf(" uint64_t sub = memory[*ptr].pair.elem0;\n");
1043- printf(" pair_free(*ptr);\n");
1044- printf(" *ptr = sub;\n");
1045- printf("\n");
1046- printf(" return result;\n");
1047- printf("}\n");
1048- printf("\n");
1049- printf("uint64_t stack_elem_addr(struct stack stack, uint64_t index)\n");
1050- printf("{\n");
1051- printf(" uint64_t node = stack.root;\n");
1052- printf("\n");
1053- printf(" if(index < stack.size) // NOTE: this implies stack.size > 0\n");
1054- printf(" {\n");
1055- printf(" uint64_t last = stack.size - 1;\n");
1056- printf(" uint64_t height = 64;\n");
1057- printf("\n");
1058- printf(" // select full tree\n");
1059- printf(" while(height > 0)\n");
1060- printf(" {\n");
1061- printf(" height--;\n");
1062- printf(" uint64_t mask = 1llu << height;\n");
1063- printf("\n");
1064- printf(" if(last & mask)\n");
1065- printf(" {\n");
1066- printf(" if(index & mask)\n");
1067- printf(" {\n");
1068- printf(" node = memory[node].pair.elem1;\n");
1069- printf(" }\n");
1070- printf(" else\n");
1071- printf(" {\n");
1072- printf(" node = memory[node].pair.elem0;\n");
1073- printf(" break;\n");
1074- printf(" }\n");
1075- printf(" }\n");
1076- printf(" }\n");
1077- printf("\n");
1078- printf(" // select leaf in full tree\n");
1079- printf(" while(height > 0)\n");
1080- printf(" {\n");
1081- printf(" height--;\n");
1082- printf("\n");
1083- printf(" uint64_t mask = 1llu << height;\n");
1084- printf(" if(index & mask)\n");
1085- printf(" {\n");
1086- printf(" node = memory[node].pair.elem1;\n");
1087- printf(" }\n");
1088- printf(" else\n");
1089- printf(" {\n");
1090- printf(" node = memory[node].pair.elem0;\n");
1091- printf(" }\n");
1092- printf(" }\n");
1093- printf(" }\n");
1094- printf(" else\n");
1095- printf(" {\n");
1096- printf(" fprintf(stderr, \"index %%d out of range 0..%%d\\n\", (int)index, (int)stack.size);\n");
1097- printf(" exit(-1);\n");
1098- printf(" }\n");
1099- printf("\n");
1100- printf(" return node;\n");
1101- printf("}\n");
1102- printf("\n");
1103- printf("uint64_t *stack_elem_ref(struct stack stack, uint64_t index)\n");
1104- printf("{\n");
1105- printf(" return &memory[stack_elem_addr(stack, index)].value;\n");
1106- printf("}\n");
1107- printf("\n");
1108- printf("struct state\n");
1109- printf("{\n");
1110- printf(" uint64_t stackbase;\n");
1111- printf(" struct stack callstack;\n");
1112- printf(" uint64_t addr;\n");
1113- printf(" uint64_t tmpaddr;\n");
1114- printf("};\n");
1115- printf("\n");
1116- printf("void complete(struct state *const state)\n");
1117- printf("{\n");
1118- printf(" while(state->callstack.size > state->stackbase) (void)stack_pop(&state->callstack);\n");
1119- printf(" state->addr = stack_pop(&state->callstack);");
1120- printf(" state->stackbase = stack_pop(&state->callstack);");
1121- printf("}\n");
1122- printf("\n");
1123- printf("void callbegin(struct state *const state, uint64_t resultsize, uint64_t returnaddr, uint64_t dest)\n");
1124- printf("{\n");
1125- printf(" while(resultsize)\n");
1126- printf(" {\n");
1127- printf(" --resultsize;\n");
1128- printf(" stack_push(&state->callstack, 0); // reserve space for result\n");
1129- printf(" }\n");
1130- printf(" stack_push(&state->callstack, state->stackbase);\n");
1131- printf(" stack_push(&state->callstack, returnaddr);\n");
1132- printf(" state->stackbase = state->callstack.size;\n");
1133- printf(" state->addr = dest;\n");
1134- printf("}\n");
1135- printf("\n");
1136- printf("void arg_push(struct state *const state, uint64_t value)\n");
1137- printf("{\n");
1138- printf(" stack_push(&state->callstack, value);\n");
1139- printf("}\n");
1140- printf("\n");
1141- printf("uint64_t *par_ref(const struct state *const state, uint64_t offset)\n");
1142- printf("{\n");
1143- printf(" return stack_elem_ref(state->callstack, state->stackbase + offset);\n");
1144- printf("}\n");
1145- printf("\n");
1146- printf("uint64_t parsenr()\n");
1147- printf("{\n");
1148- printf(" uint64_t nr = 0;\n");
1149- printf(" while(isdigit(ungetc(getchar(), stdin)))\n");
1150- printf(" {\n");
1151- printf(" nr = 10 * nr + ((uint64_t)getchar() - '0');\n");
1152- printf(" }\n");
1153- printf(" return nr;\n");
1154- printf("}\n");
1155- printf("\n");
1156- printf("uint64_t parseid()\n");
1157- printf("{\n");
1158- printf(" uint64_t id = 0;\n");
1159- printf(" uint64_t n = 10;\n");
1160- printf(" uint32_t c = 0;\n");
1161- printf(" while(true)\n");
1162- printf(" {\n");
1163- printf(" c = (uint32_t)getchar();\n");
1164- printf(" if(n > 0)\n");
1165- printf(" {\n");
1166- printf(" --n;\n");
1167- printf(" if('_' == c) id |= ((uint64_t)c - '_' + 0) << (n * 6);\n");
1168- printf(" else if(isupper(c)) id |= ((uint64_t)c - 'A' + 1) << (n * 6);\n");
1169- printf(" else if('$' == c) id |= ((uint64_t)c - '$' + 27) << (n * 6);\n");
1170- printf(" else if(islower(c)) id |= ((uint64_t)c - 'a' + 28) << (n * 6);\n");
1171- printf(" else if(isdigit(c)) id |= ((uint64_t)c - '0' + 54) << (n * 6);\n");
1172- printf(" else\n");
1173- printf(" {\n");
1174- printf(" ungetc((int)c, stdin);\n");
1175- printf(" break;\n");
1176- printf(" }\n");
1177- printf(" }\n");
1178- printf(" else\n");
1179- printf(" {\n");
1180- printf(" ungetc((int)c, stdin);\n");
1181- printf(" break;\n");
1182- printf(" }\n");
1183- printf(" }\n");
1184- printf(" return id;\n");
1185- printf("}\n");
1186- printf("\n");
1187- printf("int main()\n");
1188- printf("{\n");
1189- printf(" mem_init();\n");
1190- printf(" struct state state;\n");
1191- printf(" state.tmpaddr = 0; // assign temporary addresses highest first (pre-decrement)\n");
1192- printf(" state.callstack = stack_alloc(0);\n");
1193- printf(" state.stackbase = 0;\n");
1194- printf(" callbegin(&state, 1/*resultsize*/, 0/*end marker*/, 0xA1C929000000000LLU/*main*/);\n");
1195- printf(" while(state.addr)\n");
1196- printf(" {\n");
1197- printf(" switch(state.addr)\n");
1198- printf(" {\n");
1199-
1200- complete(&state);
1201- break;
1202- }
1203- case 0xAB0BEDA80000000LLU:
1204- {
1205-
1206- // outro
1207- printf(" default:\n");
1208- printf(" fprintf(stderr, \"no such state %%d\\n\", (int)state.addr);\n");
1209- printf(" //return (int)state.addr;\n");
1210- printf(" exit(-1);\n");
1211- printf(" }\n");
1212- printf(" }\n");
1213- printf("\n");
1214- printf(" uint64_t result = stack_pop(&state.callstack);");
1215- printf(" if(state.callstack.size)\n");
1216- printf(" {\n");
1217- printf(" fprintf(stderr, \"callstack not empty (%%llu)\\n\", (unsigned long long)state.callstack.size);\n");
1218- printf(" }\n");
1219- printf(" stack_free(&state.callstack);\n");
1220- printf(" mem_show();\n");
1221- printf(" mem_check();\n");
1222- printf("\n");
1223- printf(" return (int)result;\n");
1224- printf("}\n");
1225- printf("\n");
1226-
1227- complete(&state);
1228- break;
1229- }
1230- case 0xAA97A372D000000LLU:
1231- {
1232-
1233- uint32_t c = (uint32_t)*par_ref(&state, 0);
1234- //fprintf(stderr, "%c", (char)c);
1235- if(!isspace(c)) // skip WS
1236- {
1237- printf(" case ");
1238- if(isalpha(c))
1239- {
1240- ungetc(c, stdin);
1241- printf("0x%0llXLLU", (long long unsigned)parseid());
1242- c = getchar();
1243- }
1244- else
1245- {
1246- fprintf(stderr, "unexpected char '%c'\n", c);
1247- exit(-1);
1248- }
1249-
1250- printf(":\n");
1251- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
1252-
1253- if(123 == c)
1254- {
1255- // match brace open
1256- }
1257- else
1258- {
1259- fprintf(stderr, "missing '{', unexpected char '%c'\n", c);
1260- exit(-1);
1261- }
1262- printf(" {\n");
1263- bool in_c_code = false;
1264- for(c = (uint32_t)getchar(); c <= 255; c = (uint32_t)getchar())
1265- {
1266- if(96 == c)
1267- {
1268- in_c_code = !in_c_code;
1269- continue;
1270- }
1271-
1272- if(in_c_code)
1273- {
1274- putchar((int)c);
1275- if(10 == c)
1276- printf(" ");
1277- }
1278- else
1279- {
1280- if(125 == c)
1281- {
1282- printf("\n");
1283- printf(" complete(&state);");
1284- break;
1285- }
1286- else if(isalpha(c))
1287- {
1288- ungetc(c, stdin);
1289- uint64_t dest = parseid();
1290- c = getchar();
1291- uint64_t return_here = --state.tmpaddr;
1292-
1293- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
1294- if('(' != c)
1295- {
1296- fprintf(stderr, "missing '(' in call\n");
1297- exit(-1);
1298- }
1299-
1300- c = (uint32_t)getchar();
1301- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
1302- if(')' != c)
1303- {
1304- fprintf(stderr, "missing ')' in call\n");
1305- exit(-1);
1306- }
1307-
1308- printf("\n");
1309- printf(" callbegin(&state, 1/*resultsize*/, 0x%0llXLLU, 0x%0llXLLU);\n", (unsigned long long)return_here, (unsigned long long)dest);
1310- printf(" break;\n");
1311- printf(" }\n");
1312- printf(" case 0x%0llXLLU:\n", (unsigned long long)return_here);
1313- printf(" {\n");
1314- }
1315- else if('@' == c)
1316- {
1317- c = (uint32_t)getchar();
1318- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
1319-
1320- ungetc(c, stdin);
1321- uint64_t fn = parseid();
1322- c = getchar();
1323-
1324- uint64_t loop = --state.tmpaddr;
1325-
1326- printf("\n");
1327- printf(" state.addr = 0x%0llXLLU;\n", (unsigned long long)loop);
1328- printf(" break;\n");
1329- printf(" }\n");
1330- printf(" case 0x%0llXLLU:\n", (unsigned long long)loop);
1331- printf(" {\n");
1332- printf(" if((uint32_t)ungetc(getchar(), stdin) < 256)\n");
1333- printf(" {\n");
1334- printf(" callbegin(&state, 0/*NO result!*/, 0x%0llXLLU, 0x%0llXLLU);\n", (unsigned long long)loop, (unsigned long long)fn);
1335- printf(" arg_push(&state, (uint64_t)getchar());\n");
1336- printf(" break;\n");
1337- printf(" }\n");
1338- }
1339- else if(!isspace(c))
1340- {
1341- fprintf(stderr, "unexpected char '%c'\n", c);
1342- exit(-1);
1343- }
1344- }
1345- }
1346- printf("\n");
1347- printf(" break;\n");
1348- printf(" }\n");
1349- }
1350-
1351- complete(&state);
1352- break;
1353- }
1354- case 0xA1C929000000000LLU:
1355- {
1356-
1357- callbegin(&state, 1/*resultsize*/, 0xFFFFFFFFFFFFFFFFLLU, 0x929BEDA80000000LLU);
1358- break;
1359- }
1360- case 0xFFFFFFFFFFFFFFFFLLU:
1361- {
1362-
1363- state.addr = 0xFFFFFFFFFFFFFFFELLU;
1364- break;
1365- }
1366- case 0xFFFFFFFFFFFFFFFELLU:
1367- {
1368- if((uint32_t)ungetc(getchar(), stdin) < 256)
1369- {
1370- callbegin(&state, 0/*NO result!*/, 0xFFFFFFFFFFFFFFFELLU, 0xAA97A372D000000LLU);
1371- arg_push(&state, (uint64_t)getchar());
1372- break;
1373- }
1374-
1375- callbegin(&state, 1/*resultsize*/, 0xFFFFFFFFFFFFFFFDLLU, 0xAB0BEDA80000000LLU);
1376- break;
1377- }
1378- case 0xFFFFFFFFFFFFFFFDLLU:
1379- {
1380-
1381- complete(&state);
1382- break;
1383- }
1384- default:
1385- fprintf(stderr, "no such state %d\n", (int)state.addr);
1386- //return (int)state.addr;
1387- exit(-1);
1388- }
1389- }
1390-
1391- uint64_t result = stack_pop(&state.callstack); if(state.callstack.size)
1392- {
1393- fprintf(stderr, "callstack not empty (%llu)\n", (unsigned long long)state.callstack.size);
1394- }
1395- stack_free(&state.callstack);
1396- mem_show();
1397- mem_check();
1398-
1399- return (int)result;
1400-}
1401-
Show on old repository browser