/* This is an automatic translation of GPM from Imp to C - it has not been tested and may require some hand editing. Please refer to the Imp version if in doubt. */ /* EPC Imp to C Translation Release 4 Version Apr 95 */ #include "imptoc.h" #define marker (0xFFFFC000) #define snl ("\n") static short int st[10000 + 1] = { -1, 4, 'd', 'e', 'f', -1, 0, 4, 'v', 'a', 'l', -2, 6, 7, 'u', 'p', 'd', 'a', 't', 'e', -3, 12, 4, 'b', 'i', 'n', -4, 21, 4, 'd', 'e', 'c', -5, 27, 4, 'b', 'a', 'r', -6, 0, /* Plus remaining entries are all 0 */ }; static int e = 33; static int s = 39; int a, w, w1, h, p, f, c, q, e0, f0, h0, r; char filename[64]; /*------------------------------------------------------------------------------*/ static void /*0x0 */ load () { if (h == 0) fprintf (out_file, "%c", a); else { st[s] = a; s++; } } /*------------------------------------------------------------------------------*/ static void /*0x0 */ nextch () { if (c == 0) a = fgetc (in_file); else { a = st[c]; c++; } } /*------------------------------------------------------------------------------*/ static void /*0x0 */ item (int x) { int k, l; if (st[x] == 0) l = (s - x) - 1; else l = st[x] - 1; if (l > 0) { for (k = 1; k <= l; k++) fprintf (out_file, "%c", st[x + k]); } if (st[x] == 0) fprintf (out_file, "%s", "... (incomplete)"); } static void /*0x0 */ monitor (int n) { int fault_value; int fault_line; char *fault_file; fprintf (out_file, "%s", imp_concat (snl, "Monitor : ")); { fault_value = n; fault_line = __LINE__; fault_file = __FILE__; goto fault_dispatch; } fault_1: fprintf (out_file, "%s", "Unmatched semicolon in definition of "); item (p + 2); goto end; fault_2: fprintf (out_file, "%s", "Unquoted # in argument list of "); item (f + 2); goto end; fault_3: fprintf (out_file, "%s", "Impossible argument number in definition of "); item (p + 2); goto end; fault_4: fprintf (out_file, "%s", "No argument "); fprintf (out_file, "%c", a); fprintf (out_file, "%s", " in call for "); item (p + 2); goto end; fault_5: fprintf (out_file, "%s", "Terminator in "); if (c == 0) { fprintf (out_file, "%s", "input stream; GPM error ?"); goto end; } fprintf (out_file, "%s", "argument list for "); item (f + 2); fprintf (out_file, "%s", imp_concat (snl, "probably due to semicolon missing from definition of ")); item (p + 2); goto end; fault_6: fprintf (out_file, "%s", "GPM error?"); goto end; fault_7: fprintf (out_file, "%s", "Undefined name "); item (w); goto end; fault_8: fprintf (out_file, "%s", "Unmatched >; GPM error ?"); goto end; fault_9: fprintf (out_file, "%s", "Update argument too long for "); item (p + 9); goto end; fault_10: fprintf (out_file, "%s", "Non-digit in number "); end: /* general monitor*/ w = 20; fprintf (out_file, "%s", imp_concat (snl, "Current macros are :")); while (p != 0 || f != 0) { if (p > f) { w1 = p + 2; p = st[p]; fprintf (out_file, "%s", imp_concat (snl, "already entered : ")); } else { w1 = f + 2; f = st[f]; fprintf (out_file, "%s", imp_concat (snl, "not yet entered : ")); } for (r = 1; r <= w; r++) { item (w1); if (st[w1] == 0) break; w1 += st[w1]; if (st[w1] == marker) break; if (!(w == 1)) { fprintf (out_file, "\n%s%1d%s", "arg", r, " : "); } } w = 1; } fprintf (out_file, "\n%s\n", "End of monitor printing"); exit (0); goto fault_skip; fault_dispatch: switch (fault_value) { case 1: goto fault_1; case 2: goto fault_2; case 3: goto fault_3; case 4: goto fault_4; case 5: goto fault_5; case 6: goto fault_6; case 7: goto fault_7; case 8: goto fault_8; case 9: goto fault_9; case 10: goto fault_10; default: BADSWITCH (fault_value, fault_line, fault_file); } fault_skip:; } static void /*0x0 */ find (int x) { a = e; w = x; again: for (r = 0; r <= st[w] - 1; r++) { if (st[w + r] != st[(a + r) + 1]) goto next; } w = (a + 1) + st[w]; return; next: a = st[a]; if (!(a < 0)) goto again; monitor (7); } /*------------------------------------------------------------------------------*/ int main () { int mcm_value; int mcm_line; char *mcm_file; /* %ON %EVENT 0, 9 %START*/ /* %IF event_event = 9 %THEN %START*/ /* select input(0)*/ /* ->start*/ /* %FINISH %ELSE print string(snl."GPM terminated".snl)*/ /* %STOP*/ /* %FINISH*/ a = 0; w = 0; w1 = 0; h = 0; p = 0; f = 0; c = 0; q = 1; start: nextch (); if (a == '@') { /* Call to %routine READ STRING(%stringname S) - please modify pass2.i to handle it */ ; openinput (1, filename); selectinput (1); goto start; } if (a == '/') { /* Call to %routine READ(%name NUMBER) - please modify pass2.i to handle it */ ; openoutput (1, filename); selectoutput (1); goto start; } if (a == '<') { q++; goto q2; } if (a == '$') goto fn; if (a == ',') goto nextitem; if (a == ';') goto apply; if (a == '#') goto loadarg; if (a == marker) goto endfn; if (a == '>') goto Exit; copy: load (); if (q == 1) goto start; q2: nextch (); if (a == '<') { q++; goto copy; } if (a != '>') goto copy; q--; if (q == 1) goto start; else goto copy; fn: st[s] = h; st[s + 1] = f; st[s + 2] = 0; st[s + 3] = 0; h = s + 3; f = s + 1; s += 4; goto start; nextitem: if (h == 0) goto copy; st[h] = (s - h) - st[h]; st[s] = 0; h = s; s++; goto start; apply: if (p > f) monitor (1); if (h == 0) goto copy; st[h] = s - h; st[s] = (*(short int *) (marker)); h0 = st[f - 1]; f0 = st[f]; st[f - 1] = (s - f) + 2; st[f] = p; st[f + 1] = c; p = f; f = f0; h = h0; s++; if (!(h == 0)) st[h] = st[h] + st[p - 1]; find (p + 2); if (st[w] < 0) { mcm_value = -st[w]; mcm_line = __LINE__; mcm_file = __FILE__; goto mcm_dispatch; } c = w + 1; goto start; loadarg: if (p == 0) { if (h == 0) goto copy; else monitor (2); } nextch (); w = p + 2; if (a < '0') monitor (3); if (a > '0') { for (r = 0; r <= (a - '0') - 1; r++) { w += st[w]; if (st[w] == marker) monitor (4); } } for (r = 1; r <= st[w] - 1; r++) { a = st[w + r]; load (); } goto start; endfn: if (f > p) monitor (5); st[s] = e; a = s; while (st[a] >= ((p - 1) + st[p - 1])) { e0 = st[a]; st[a] = e0 - st[p - 1]; a = e0; } w = st[a]; while (w > (p - 1)) w = st[w]; st[a] = w; e = st[s]; if (!(h == 0)) { if (h > p) h -= st[p - 1]; else st[h] = st[h] - st[p - 1]; } a = p - 1; w = a + st[p - 1]; c = st[p + 1]; s -= st[p - 1]; p = st[p]; while (a != s) { st[a] = st[w]; a++; w++; } goto start; Exit: if (!((c == h) && (h == 0))) monitor (8); exit (0); mcm_1: /* def */ if (!(h == 0)) st[h] = (st[h] - st[p - 1]) + 6; st[p - 1] = 6; st[p + 5] = e; e = p + 5; goto endfn; mcm_2: /* val */ find (p + 6); while (st[w + 1] != marker) { a = st[w + 1]; w++; load (); } goto endfn; mcm_3: /* update */ find (p + 9); a = (p + 9) + st[p + 9]; if (st[a] > st[w]) monitor (9); for (r = 1; r <= st[a]; r++) { st[w + r] = st[a + r]; } goto endfn; mcm_4: /* bin */ w = 0; if (st[p + 7] == '+' || st[p + 7] == '-') a = p + 8; else a = p + 7; while (st[a] != marker) { if (!((('0') <= (st[a])) && ((st[a]) <= ('9')))) monitor (10); w = ((10 * w) + st[a]) - '0'; a++; } if (st[p + 7] == '-') st[s] = -w; else st[s] = w; s++; goto endfn; mcm_5: /* dec */ w = st[p + 7]; if (w < 0) { w = -w; a = '-'; load (); } r = 1; while ((10 * r) <= w) r *= 10; while (r >= 1) { a = (w / r) + '0'; load (); w -= r * (a - '0'); r /= 10; } goto endfn; mcm_6: /* bar */ w = st[p + 9]; a = st[p + 11]; if (st[p + 7] == '+') a += w; if (st[p + 7] == '-') a = w - a; if (st[p + 7] == '*') a *= w; if (st[p + 7] == '/') a = w / a; if (st[p + 7] == 'r') a = w - ((w / a) * a); load (); goto endfn; goto mcm_skip; mcm_dispatch: switch (mcm_value) { case 1: goto mcm_1; case 2: goto mcm_2; case 3: goto mcm_3; case 4: goto mcm_4; case 5: goto mcm_5; case 6: goto mcm_6; default: BADSWITCH (mcm_value, mcm_line, mcm_file); } mcm_skip:; } /* end of automatic translation */