• R/O
  • SSH
  • HTTPS

jpl: Commit


Commit MetaInfo

Revision488 (tree)
Time2019-03-12 09:51:23
Authorjakobthomsen

Log Message

rewrite callstack

Change Summary

Incremental Difference

--- trunk/experimental2/compiler.compiled.c (revision 487)
+++ trunk/experimental2/compiler.compiled.c (revision 488)
@@ -503,18 +503,96 @@
503503 return &memory[stack_elem_addr(stack, index)].value;
504504 }
505505
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+
506583 int main()
507584 {
508- uint64_t tmpaddr = 0; // assign temporary addresses highest first (pre-decrement)
509585 mem_init();
510- uint64_t result = 0; struct stack callstack = stack_alloc(0);
511- stack_push(&callstack, 0); // end marker
512- uint64_t stackframe = tuple2_alloc(/*main*/1835100526LLU, 0/*arg*/);
513- while(memory[tuple2_access0(stackframe)].value)
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)
514592 {
515- switch(memory[tuple2_access0(stackframe)].value)
593+ switch(state.addr)
516594 {
517- case /*intro*/452824691311LLU:
595+ case 0x929BEDA80000000LLU:
518596 {
519597
520598 /////////////////////////////////////////////////////////////////////////////
@@ -1027,37 +1105,118 @@
10271105 printf(" return &memory[stack_elem_addr(stack, index)].value;\n");
10281106 printf("}\n");
10291107 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");
10301187 printf("int main()\n");
10311188 printf("{\n");
1032- printf(" uint64_t tmpaddr = 0; // assign temporary addresses highest first (pre-decrement)\n");
10331189 printf(" mem_init();\n");
1034- printf(" uint64_t result = 0;");
1035- printf(" struct stack callstack = stack_alloc(0);\n");
1036- printf(" stack_push(&callstack, 0); // end marker\n");
1037- printf(" uint64_t stackframe = tuple2_alloc(/*main*/1835100526LLU, 0/*arg*/);\n");
1038- printf(" while(memory[tuple2_access0(stackframe)].value)\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");
10391196 printf(" {\n");
1040- printf(" switch(memory[tuple2_access0(stackframe)].value)\n");
1197+ printf(" switch(state.addr)\n");
10411198 printf(" {\n");
1042- tuple2_free(stackframe);
1043- stackframe = stack_pop(&callstack);
1044- stack_push(&callstack, result);
1045-
1199+
1200+ complete(&state);
10461201 break;
10471202 }
1048- case /*outro*/478711935599LLU:
1203+ case 0xAB0BEDA80000000LLU:
10491204 {
10501205
1206+ // outro
10511207 printf(" default:\n");
1052- printf(" fprintf(stderr, \"no such stackframe %%d\\n\", (int)memory[tuple2_access0(stackframe)].value);\n");
1053- printf(" return (int)memory[tuple2_access0(stackframe)].value;\n");
1054- printf(" // exit((int)memory[tuple2_access0(stackframe)].value);\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");
10551211 printf(" }\n");
10561212 printf(" }\n");
10571213 printf("\n");
1058- printf(" tuple2_free(stackframe);\n");
1059- printf(" result = stack_pop(&callstack);\n");
1060- printf(" stack_free(&callstack);\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");
10611220 printf(" mem_show();\n");
10621221 printf(" mem_check();\n");
10631222 printf("\n");
@@ -1064,229 +1223,176 @@
10641223 printf(" return (int)result;\n");
10651224 printf("}\n");
10661225 printf("\n");
1067- tuple2_free(stackframe);
1068- stackframe = stack_pop(&callstack);
1069- stack_push(&callstack, result);
1070-
1226+
1227+ complete(&state);
10711228 break;
10721229 }
1073- case /*parseid*/31632341581785444LLU:
1230+ case 0xAA97A372D000000LLU:
10741231 {
10751232
1076- result = 0;
1077- while(isalpha(ungetc(getchar(), stdin)))
1233+ uint32_t c = (uint32_t)*par_ref(&state, 0);
1234+ //fprintf(stderr, "%c", (char)c);
1235+ if(!isspace(c)) // skip WS
10781236 {
1079- result <<= 8;
1080- result |= (uint64_t)((uint8_t)getchar());
1081- }
1082- tuple2_free(stackframe);
1083- stackframe = stack_pop(&callstack);
1084- stack_push(&callstack, result);
1085-
1086- break;
1087- }
1088- case /*onchar*/122519904870770LLU:
1089- {
1090-
1091- uint32_t c = (uint32_t)memory[tuple2_access1(stackframe)].value;
1092-
1093- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
1094- if((unsigned int)c > 255)
1095- {
1096- memory[tuple2_access0(stackframe)].value = 0;
1097- break;
1098- }
1099- printf(" case ");
1100- if(isalpha(c))
1101- {
1102- printf("/*");
1103- uint64_t tmp = 0;
1104- while(isalpha(c))
1237+ printf(" case ");
1238+ if(isalpha(c))
11051239 {
1106- printf("%c", (char)c);
1107- tmp <<= 8;
1108- tmp |= (uint64_t)(c & 255);
1109- c = (uint32_t)getchar();
1240+ ungetc(c, stdin);
1241+ printf("0x%0llXLLU", (long long unsigned)parseid());
1242+ c = getchar();
11101243 }
1111- printf("*/");
1112- printf("%lluLLU", (unsigned long long)tmp);
1113- }
1114- printf(":\n");
1115-
1116- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
1117-
1118- if(123 != c) // match brace open
1119- {
1120- fprintf(stderr, "missing '{', unexpected char '%c'\n", c);
1121- exit(-1);
1122- }
1123- printf(" {\n");
1124- bool in_c_code = false;
1125- for(c = (uint32_t)getchar(); c <= 255; c = (uint32_t)getchar())
1126- {
1127- if(96 == c)
1244+ else
11281245 {
1129- in_c_code = !in_c_code;
1130- continue;
1246+ fprintf(stderr, "unexpected char '%c'\n", c);
1247+ exit(-1);
11311248 }
11321249
1133- if(in_c_code)
1250+ printf(":\n");
1251+ while(isspace(c)) c = (uint32_t)getchar(); // skip WS
1252+
1253+ if(123 == c)
11341254 {
1135- putchar((int)c);
1136- if(10 == c)
1137- printf(" ");
1255+ // match brace open
11381256 }
11391257 else
11401258 {
1141- if(125 == c)
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)
11421267 {
1143- printf("tuple2_free(stackframe);\n");
1144- printf(" stackframe = stack_pop(&callstack);\n");
1145- printf(" stack_push(&callstack, result);\n");
1146- break;
1268+ in_c_code = !in_c_code;
1269+ continue;
11471270 }
1148- else if(isalpha(c))
1271+
1272+ if(in_c_code)
11491273 {
1150- printf("/*");
1151- uint64_t id = 0;
1152- while(isalpha(c))
1274+ putchar((int)c);
1275+ if(10 == c)
1276+ printf(" ");
1277+ }
1278+ else
1279+ {
1280+ if(125 == c)
11531281 {
1154- printf("%c", (char)c);
1155- id <<= 8;
1156- id |= (uint64_t)(c & 255);
1157- c = (uint32_t)getchar();
1282+ printf("\n");
1283+ printf(" complete(&state);");
1284+ break;
11581285 }
1159- printf("*/");
1160-
1161- if(31365121518368116LLU == id)
1286+ else if(isalpha(c))
11621287 {
1163- uint64_t dest = --tmpaddr;
1164- printf("\n stack_push(&callstack, 0);"); // push unit to be popped returning from called function
1165- printf("\n memory[tuple2_access0(stackframe)].value = %lluLLU;", (long long)dest); // use negative to display numbers concisely
1166- printf("\n break;");
1167- printf("\n }");
1168- printf("\n case %lluLLU:", (long long)dest); // use negative to display numbers concisely
1169- printf("\n {");
1170- printf("\n /*unit*/(void)stack_pop(&callstack);");
1171- printf("\n if((unsigned int)ungetc(getchar(), stdin) <= 255)");
1172- printf("\n {");
1288+ ungetc(c, stdin);
1289+ uint64_t dest = parseid();
1290+ c = getchar();
1291+ uint64_t return_here = --state.tmpaddr;
11731292
11741293 while(isspace(c)) c = (uint32_t)getchar(); // skip WS
1175- if(isalpha(c))
1294+ if('(' != c)
11761295 {
1177- printf("/*");
1178- id = 0;
1179- while(isalpha(c))
1180- {
1181- printf("%c", (char)c);
1182- id <<= 8;
1183- id |= (uint64_t)(c & 255);
1184- c = (uint32_t)getchar();
1185- }
1186- printf("*/");
1296+ fprintf(stderr, "missing '(' in call\n");
1297+ exit(-1);
11871298 }
11881299
1189- printf("\n memory[tuple2_access0(stackframe)].value = %lluLLU;", (long long)dest); // use negative to display numbers concisely
1190- printf("\n stack_push(&callstack, stackframe);");
1191- printf("\n stackframe = tuple2_alloc(%lluLLU, (uint64_t)getchar());", (unsigned long long)id); // echo label
1192- printf("\n result = 0;");
1193- printf("\n break;");
1194- printf("\n }");
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+
11951308 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");
11961314 }
1197- else
1315+ else if('@' == c)
11981316 {
1199- uint64_t dest = --tmpaddr;
1200- printf("memory[tuple2_access0(stackframe)].value = %lluLLU;\n", (long long)dest); // use negative to display numbers concisely
1201- printf(" stack_push(&callstack, stackframe);\n");
1202- printf(" stackframe = tuple2_alloc(%lluLLU, 0);\n", (unsigned long long)id); // echo label
1203- printf(" result = 0;\n");
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);
12041328 printf(" break;\n");
12051329 printf(" }\n");
1206- //printf(" case %lluLLU:\n", (unsigned long long)--tmpaddr);
1207- printf(" case %lluLLU:\n", (long long)dest); // use negative to display numbers concisely
1330+ printf(" case 0x%0llXLLU:\n", (unsigned long long)loop);
12081331 printf(" {\n");
1209- printf(" result = stack_pop(&callstack);\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");
12101338 }
1339+ else if(!isspace(c))
1340+ {
1341+ fprintf(stderr, "unexpected char '%c'\n", c);
1342+ exit(-1);
1343+ }
12111344 }
1212- else if(64 == c)
1213- {
1214- printf(" result = ");
1215- while(isspace(ungetc(getchar(), stdin))) (void)getchar(); // skip WS
1216- while(isdigit(ungetc(getchar(), stdin))) putchar(getchar()); // echo number
1217- printf(";\n");
1218- }
1219- else if(!isspace(c))
1220- {
1221- fprintf(stderr, "unexpected char '%c'\n", c);
1222- exit(-1);
1223- }
12241345 }
1346+ printf("\n");
1347+ printf(" break;\n");
1348+ printf(" }\n");
12251349 }
1226- printf("\n");
1227- printf(" break;\n");
1228- printf(" }\n");
1229-
1230- c = (uint32_t)getchar();
1231- tuple2_free(stackframe);
1232- stackframe = stack_pop(&callstack);
1233- stack_push(&callstack, result);
1234-
1350+
1351+ complete(&state);
12351352 break;
12361353 }
1237- case /*main*/1835100526LLU:
1354+ case 0xA1C929000000000LLU:
12381355 {
1239-/*intro*/memory[tuple2_access0(stackframe)].value = 18446744073709551615LLU;
1240- stack_push(&callstack, stackframe);
1241- stackframe = tuple2_alloc(452824691311LLU, 0);
1242- result = 0;
1356+
1357+ callbegin(&state, 1/*resultsize*/, 0xFFFFFFFFFFFFFFFFLLU, 0x929BEDA80000000LLU);
12431358 break;
12441359 }
1245- case 18446744073709551615LLU:
1360+ case 0xFFFFFFFFFFFFFFFFLLU:
12461361 {
1247- result = stack_pop(&callstack);
1248-/*oninput*/
1249- stack_push(&callstack, 0);
1250- memory[tuple2_access0(stackframe)].value = 18446744073709551614LLU;
1362+
1363+ state.addr = 0xFFFFFFFFFFFFFFFELLU;
12511364 break;
12521365 }
1253- case 18446744073709551614LLU:
1366+ case 0xFFFFFFFFFFFFFFFELLU:
12541367 {
1255- /*unit*/(void)stack_pop(&callstack);
1256- if((unsigned int)ungetc(getchar(), stdin) <= 255)
1257- {/*onchar*/
1258- memory[tuple2_access0(stackframe)].value = 18446744073709551614LLU;
1259- stack_push(&callstack, stackframe);
1260- stackframe = tuple2_alloc(122519904870770LLU, (uint64_t)getchar());
1261- result = 0;
1368+ if((uint32_t)ungetc(getchar(), stdin) < 256)
1369+ {
1370+ callbegin(&state, 0/*NO result!*/, 0xFFFFFFFFFFFFFFFELLU, 0xAA97A372D000000LLU);
1371+ arg_push(&state, (uint64_t)getchar());
12621372 break;
12631373 }
1264-/*outro*/memory[tuple2_access0(stackframe)].value = 18446744073709551613LLU;
1265- stack_push(&callstack, stackframe);
1266- stackframe = tuple2_alloc(478711935599LLU, 0);
1267- result = 0;
1374+
1375+ callbegin(&state, 1/*resultsize*/, 0xFFFFFFFFFFFFFFFDLLU, 0xAB0BEDA80000000LLU);
12681376 break;
12691377 }
1270- case 18446744073709551613LLU:
1378+ case 0xFFFFFFFFFFFFFFFDLLU:
12711379 {
1272- result = stack_pop(&callstack);
1273- result = 0;
1274-tuple2_free(stackframe);
1275- stackframe = stack_pop(&callstack);
1276- stack_push(&callstack, result);
12771380
1381+ complete(&state);
12781382 break;
12791383 }
12801384 default:
1281- fprintf(stderr, "no such stackframe %d\n", (int)memory[tuple2_access0(stackframe)].value);
1282- return (int)memory[tuple2_access0(stackframe)].value;
1283- // exit((int)memory[tuple2_access0(stackframe)].value);
1385+ fprintf(stderr, "no such state %d\n", (int)state.addr);
1386+ //return (int)state.addr;
1387+ exit(-1);
12841388 }
12851389 }
12861390
1287- tuple2_free(stackframe);
1288- result = stack_pop(&callstack);
1289- stack_free(&callstack);
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);
12901396 mem_show();
12911397 mem_check();
12921398
--- trunk/experimental2/compiler.source.c (revision 487)
+++ trunk/experimental2/compiler.source.c (revision 488)
@@ -511,34 +511,118 @@
511511 printf(" return &memory[stack_elem_addr(stack, index)].value;\n");
512512 printf("}\n");
513513 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");
514593 printf("int main()\n");
515594 printf("{\n");
516- printf(" uint64_t tmpaddr = 0; // assign temporary addresses highest first (pre-decrement)\n");
517595 printf(" mem_init();\n");
518- printf(" uint64_t result = 0;");
519- printf(" struct stack callstack = stack_alloc(0);\n");
520- printf(" stack_push(&callstack, 0); // end marker\n");
521- printf(" uint64_t stackframe = tuple2_alloc(/*main*/1835100526LLU, 0/*arg*/);\n");
522- printf(" while(memory[tuple2_access0(stackframe)].value)\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");
523602 printf(" {\n");
524- printf(" switch(memory[tuple2_access0(stackframe)].value)\n");
603+ printf(" switch(state.addr)\n");
525604 printf(" {\n");
526- `
605+`
606+
527607 }
528608
529609 outro
530610 {
531611 `
612+ // outro
532613 printf(" default:\n");
533- printf(" fprintf(stderr, \"no such stackframe %%d\\n\", (int)memory[tuple2_access0(stackframe)].value);\n");
534- printf(" return (int)memory[tuple2_access0(stackframe)].value;\n");
535- printf(" // exit((int)memory[tuple2_access0(stackframe)].value);\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");
536617 printf(" }\n");
537618 printf(" }\n");
538619 printf("\n");
539- printf(" tuple2_free(stackframe);\n");
540- printf(" result = stack_pop(&callstack);\n");
541- printf(" stack_free(&callstack);\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");
542626 printf(" mem_show();\n");
543627 printf(" mem_check();\n");
544628 printf("\n");
@@ -548,171 +632,135 @@
548632 `
549633 }
550634
551-parseid
552-{
553- `
554- result = 0;
555- while(isalpha(ungetc(getchar(), stdin)))
556- {
557- result <<= 8;
558- result |= (uint64_t)((uint8_t)getchar());
559- }
560- `
561-}
562-
563635 onchar
564636 {
565637 `
566- uint32_t c = (uint32_t)memory[tuple2_access1(stackframe)].value;
567-
568- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
569- if((unsigned int)c > 255)
638+ uint32_t c = (uint32_t)*par_ref(&state, 0);
639+ //fprintf(stderr, "%c", (char)c);
640+ if(!isspace(c)) // skip WS
570641 {
571- memory[tuple2_access0(stackframe)].value = 0;
572- break;
573- }
574- printf(" case ");
575- if(isalpha(c))
576- {
577- printf("/*");
578- uint64_t tmp = 0;
579- while(isalpha(c))
642+ printf(" case ");
643+ if(isalpha(c))
580644 {
581- printf("%c", (char)c);
582- tmp <<= 8;
583- tmp |= (uint64_t)(c & 255);
584- c = (uint32_t)getchar();
645+ ungetc(c, stdin);
646+ printf("0x%0llXLLU", (long long unsigned)parseid());
647+ c = getchar();
585648 }
586- printf("*/");
587- printf("%lluLLU", (unsigned long long)tmp);
588- }
589- printf(":\n");
590-
591- while(isspace(c)) c = (uint32_t)getchar(); // skip WS
592-
593- if(123 != c) // match brace open
594- {
595- fprintf(stderr, "missing '{', unexpected char '%c'\n", c);
596- exit(-1);
597- }
598- printf(" {\n");
599- bool in_c_code = false;
600- for(c = (uint32_t)getchar(); c <= 255; c = (uint32_t)getchar())
601- {
602- if(96 == c)
649+ else
603650 {
604- in_c_code = !in_c_code;
605- continue;
651+ fprintf(stderr, "unexpected char '%c'\n", c);
652+ exit(-1);
606653 }
607654
608- if(in_c_code)
655+ printf(":\n");
656+ while(isspace(c)) c = (uint32_t)getchar(); // skip WS
657+
658+ if(123 == c)
609659 {
610- putchar((int)c);
611- if(10 == c)
612- printf(" ");
660+ // match brace open
613661 }
614662 else
615663 {
616- if(125 == c)
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)
617672 {
618- printf("tuple2_free(stackframe);\n");
619- printf(" stackframe = stack_pop(&callstack);\n");
620- printf(" stack_push(&callstack, result);\n");
621- break;
673+ in_c_code = !in_c_code;
674+ continue;
622675 }
623- else if(isalpha(c))
676+
677+ if(in_c_code)
624678 {
625- printf("/*");
626- uint64_t id = 0;
627- while(isalpha(c))
679+ putchar((int)c);
680+ if(10 == c)
681+ printf(" ");
682+ }
683+ else
684+ {
685+ if(125 == c)
628686 {
629- printf("%c", (char)c);
630- id <<= 8;
631- id |= (uint64_t)(c & 255);
632- c = (uint32_t)getchar();
687+ printf("\n");
688+ printf(" complete(&state);");
689+ break;
633690 }
634- printf("*/");
635-
636- if(31365121518368116LLU == id)
691+ else if(isalpha(c))
637692 {
638- uint64_t dest = --tmpaddr;
639- printf("\n stack_push(&callstack, 0);"); // push unit to be popped returning from called function
640- printf("\n memory[tuple2_access0(stackframe)].value = %lluLLU;", (long long)dest); // use negative to display numbers concisely
641- printf("\n break;");
642- printf("\n }");
643- printf("\n case %lluLLU:", (long long)dest); // use negative to display numbers concisely
644- printf("\n {");
645- printf("\n /*unit*/(void)stack_pop(&callstack);");
646- printf("\n if((unsigned int)ungetc(getchar(), stdin) <= 255)");
647- printf("\n {");
693+ ungetc(c, stdin);
694+ uint64_t dest = parseid();
695+ c = getchar();
696+ uint64_t return_here = --state.tmpaddr;
648697
649698 while(isspace(c)) c = (uint32_t)getchar(); // skip WS
650- if(isalpha(c))
699+ if('(' != c)
651700 {
652- printf("/*");
653- id = 0;
654- while(isalpha(c))
655- {
656- printf("%c", (char)c);
657- id <<= 8;
658- id |= (uint64_t)(c & 255);
659- c = (uint32_t)getchar();
660- }
661- printf("*/");
701+ fprintf(stderr, "missing '(' in call\n");
702+ exit(-1);
662703 }
663704
664- printf("\n memory[tuple2_access0(stackframe)].value = %lluLLU;", (long long)dest); // use negative to display numbers concisely
665- printf("\n stack_push(&callstack, stackframe);");
666- printf("\n stackframe = tuple2_alloc(%lluLLU, (uint64_t)getchar());", (unsigned long long)id); // echo label
667- printf("\n result = 0;");
668- printf("\n break;");
669- printf("\n }");
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+
670713 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");
671719 }
672- else
720+ else if('@' == c)
673721 {
674- uint64_t dest = --tmpaddr;
675- printf("memory[tuple2_access0(stackframe)].value = %lluLLU;\n", (long long)dest); // use negative to display numbers concisely
676- printf(" stack_push(&callstack, stackframe);\n");
677- printf(" stackframe = tuple2_alloc(%lluLLU, 0);\n", (unsigned long long)id); // echo label
678- printf(" result = 0;\n");
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);
679733 printf(" break;\n");
680734 printf(" }\n");
681- //printf(" case %lluLLU:\n", (unsigned long long)--tmpaddr);
682- printf(" case %lluLLU:\n", (long long)dest); // use negative to display numbers concisely
735+ printf(" case 0x%0llXLLU:\n", (unsigned long long)loop);
683736 printf(" {\n");
684- printf(" result = stack_pop(&callstack);\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");
685743 }
744+ else if(!isspace(c))
745+ {
746+ fprintf(stderr, "unexpected char '%c'\n", c);
747+ exit(-1);
748+ }
686749 }
687- else if(64 == c)
688- {
689- printf(" result = ");
690- while(isspace(ungetc(getchar(), stdin))) (void)getchar(); // skip WS
691- while(isdigit(ungetc(getchar(), stdin))) putchar(getchar()); // echo number
692- printf(";\n");
693- }
694- else if(!isspace(c))
695- {
696- fprintf(stderr, "unexpected char '%c'\n", c);
697- exit(-1);
698- }
699750 }
751+ printf("\n");
752+ printf(" break;\n");
753+ printf(" }\n");
700754 }
701- printf("\n");
702- printf(" break;\n");
703- printf(" }\n");
704-
705- c = (uint32_t)getchar();
706755 `
707756 }
708757
709758 main
710759 {
711- intro
760+ intro()
712761
713- oninput onchar
762+ @ onchar
714763
715- outro
764+ outro()
765+}
716766
717- @ 0
718-}
Show on old repository browser