/* EPC Imp to C Translation Release 4 Version Apr 95 */ #include "imptoc.h" /*!This version of ECCE, derived from a paper copy believed to */ /*!date from 1975, removes PDP9/15 machine code, and other */ /*!IMP9/15 system dependencies, and I'm hopeful that as a result */ /*!it might well work if compiled with a generic Imp compiler. */ /*!RWT Feb 2002 */ main () { /* edit15: ecce for pdp9/15 */ static int in = 1; /* current input stream */ #define min 1 /* main input stream */ #define mout 1 /* main output stream */ #define sin 2 /* secondary input stream */ #define sextra 122 /* extra buff for sin */ #define size 30000 /* of edit buffer (bytes) */ static int mon = 0; /* monitor indic */ static int print1 = 0; static int print2 = 0; /* print indicators */ #define stop (-5000) /* loop stop (const) */ int i, j, k, pp1, sym; int code; /* command code letter */ int text; /* text pointer */ int num; /* repetition number */ int *mainfp; /* == fp or mfp (for sin) */ #define cbase 1 #define tbase 120 static int c[tbase - (cbase) + 1]; /* command -> <- text */ /* each command unit -- letter, parenthesis or comma -- is */ /* represented by a trio: code(+lim) text num */ /* in the case of parentheses and commas 'text' is a pointer */ /* to another command unit (not to a text string) */ int ci; /* command index (ad) */ int ti; /* text index (ad) */ static int cmax = 0; /* command max (ad) */ int stored[192 + 1]; /* defs of x,y,z */ static int pos1 = 0; static int pos2 = 0; static int pos3 = 0; unsigned char byte[size + 1]; int top = 2; /* top of buff (index) */ int bot = size - sextra; /* bottom of buff (index) */ int lbeg; /* line start (index) */ int pp; /* previous pointer (index) */ static int fp = 0; /* file pointer (index) */ int lend; /* line end (index) */ static int fend; /* end of file in buff (index) */ static int ms = 0; /* match start (index) */ static int ml = 0; /* match limit (index) */ /* significance of file pointers: */ /* [nl] o n e nl t w . . . o nl n e x t nl . . nl l a s t nl [nl] */ /* ! ! ! ! ! ! */ /* t l p f l f */ /* o b p p e e */ /* p e n n */ /* g d d */ int type, chain; /* command input vars */ static int pend = 0; /* ditto */ int t_value; int t_line; char *t_file; int s_value; int s_line; char *s_file; static void loadpp (int k) { /* !!also increments pp */ byte[pp] = k; pp++; } static void loadfp (int k) { byte[fp] = k; } static void leftstar () { for (;;) { if (pp == lbeg) return; fp--; pp--; loadfp (byte[pp]); } } static void rightstar () { for (;;) { if (fp == lend) return; loadpp (byte[fp]); fp++; } } static int symtype[95 - 32] = {64, 3, 3, 3, 2, 3, 3, 11, 9, 64, 3, 12, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 3, 3, 64, 3, 2, 10, 18, 5, 8, 52, 10, 2, 6, 10, 10, 10, 56, 2, 2, 10, 50, 10, 22, 5, 5, 6, 2, 32, 32, 32, 3, 10, 3, 3, 3}; /* ! " # $ % & ' ( ) * + , - . / */ /* 0 1 2 3 4 5 6 7 8 9 : < = > ? */ /* @ A B C D E F G H I J K L M N O */ /* P Q R S T U V W X Y Z [ \ ] ^ _ */ static void readsym () { if (pend != 0) { sym = pend; pend = 0; } else { while (pos3 != 0) { sym = stored[pos3]; pos3++; if (sym != nl) return; pos3 = pos2; pos2 = pos1; pos1 = 0; } sym = fgetc (in_file); } } static void readitem () { type = 1; for (;;) { do readsym (); while (sym == ' '); if (sym < 32) return; /* nl */ if (sym >= 96) sym -= 32; /* ensure upper case */ type = symtype[sym - 33]; if ((type & 15) != 0) return; if (type != 32) break; pos1 = pos2; pos2 = pos3; pos3 = ((sym - 'X') << 6) + 1; } if (type == 0) { num = sym - '0'; for (;;) { pend = fgetc (in_file); if (('0' > pend) || (pend > '9')) break; num = ((((num << 2) + num) << 1) - '0') + pend; } } else { type = 0; num = 0; if (sym == '*') return; num = stop + 1; if (sym == '?') return; num = stop; /* '!' */ } } static void unchain () { do { text = chain; if (text == 0) return; chain = c[text + 1 - (cbase)]; c[text + 1 - (cbase)] = ci; } while (c[text - (cbase)] != 'X'); } static void stack (int v) { c[ci - (cbase)] = v; ci++; } static void makespace () { int k, p1, p2; if (((*mainfp - pp) - 240) > 0) return; selectoutput (mout); p1 = top; p2 = (unsigned) (p1 + lbeg) >> 1; /* ouptut about half */ if (code == 'C') p2 = lbeg; /* but all if closing */ if (p2 == top) assert (_IMP_MONITOR_); /* 20 *//* !!logical error */ do { k = byte[p1]; fprintf (out_file, "%c", k); p1++; } while (k != nl || (p1 - p2) < 0); selectoutput (0); lbeg = (top + lbeg) - p1; p2 = pp; pp = top; for (;;) { if (p1 == p2) return; loadpp (byte[p1]); p1++; } } static void readline () { int k; if (0) { /* beginning of onevent block */ goto eof; /* end of onevent block */ } if (fp != fend) { lend = fp; while (byte[lend] != nl) lend++; return; } ms = 0; print1 = 0; print2 = 0; selectinput (in); fp = (bot - sextra) + 1; do { if (fp != bot) k = fgetc (in_file); else k = nl; if (k < 0) goto eof; loadfp (k); fp++; } while (k != nl); fend = fp; lend = fend - 1; fp = (bot - sextra) + 1; selectinput (0); return; eof: fp = bot; lend = fp; fend = lend; loadfp (nl); selectinput (0); } static void switchinputs () { static int mfp; static int mlend; static int mend; static int sfp; static int send; if (in == min) { leftstar (); in = sin; mfp = fp; mlend = lend; mend = fend; mainfp = &mfp; bot += sextra; fp = sfp; fend = send; readline (); } else { pp = lbeg; in = min; bot -= sextra; sfp = fp; send = fend; fp = mfp; lend = mlend; fend = mend; mainfp = &fp; } } static void printline () { int p; print1 = lend; print2 = fp + pp; p = lbeg; for (;;) { if (p == pp) { if (p != lbeg && num == 0) fprintf (out_file, "%c", '^'); p = fp; } if (p == lend) break; fprintf (out_file, "%c", byte[p]); p++; } if (p == fend) fprintf (out_file, "%s", "**END**"); fprintf (out_file, "%s", "\n"); } static int matched () { int i, j, k, l, t1, fp1, lim; lim = c[ci - 3 - (cbase)] & (~127); t1 = c[text - (cbase)]; l1: pp1 = pp; fp1 = fp; if (fp != ms || (code != 'F' && code != 'U')) goto l3; k = byte[fp]; l2: loadpp (k); fp++; l3: if (fp == lend) goto l10; k = byte[fp]; if (k != t1) goto l2; i = fp; j = text; l6: i++; j--; l = c[j - (cbase)]; if (byte[i] == l) goto l6; if (l != 0) goto l2; ms = fp; ml = i; return 1; l10: lim -= 128; if (lim != 0 && fp != fend) { if (code != 'U') { loadpp (nl); lbeg = pp; } else pp = pp1; fp++; makespace (); readline (); goto l1; } pp = pp1; fp = fp1; return 0; } if (0) { /* beginning of onevent block */ goto eof; /* end of onevent block */ } /*initialise */ pp = top - 1; loadpp (nl); /* for bouncing off */ lbeg = pp; mainfp = &fp; stored[1] = nl; stored[65] = nl; stored[129] = nl; selectoutput (0); fprintf (out_file, "%s", "EDIT\n"); readline (); /*read command line */ l1: fprintf (out_file, ">"); fflush (out_file); readitem (); if (sym < 0) goto eof; if (type == 1) goto l1; ci = cbase; ti = tbase; chain = 0; if (type == 0 && cmax != 0) { c[cmax + 2 - (cbase)] = num; readitem (); if (type != 1) goto er2; goto go; } if (sym == '%') { readsym (); if (sym >= 96) sym -= 32; code = sym; if (code <= 32) goto er5; readitem (); { t_value = (unsigned) symtype[code - 33] >> 4; t_line = __LINE__; t_file = __FILE__; goto t_despatch; } } l2: i = type & 15; if (i < 4) goto er2; code = sym; text = 0; num = 1; /* default values */ readitem (); { t_value = i; t_line = __LINE__; t_file = __FILE__; goto t_despatch; } t_2: /* %X, %Y, %Z */ if (sym != '=') goto er1; i = (code - 'X') << 6; for (;;) { readsym (); i++; stored[i] = sym; if (sym == nl) goto l1; } t_3: /* %M, %F, %Q */ mon = 'M' - code; goto l1; t_4: /* find */ if (type != 0) num = 0; t_5: /* +del,trav,uncover */ code += num << 7; num = 1; if (type == 0) readitem (); t_6: /* +insert,subst,verify */ if (type != 3) goto er4; text = ti; i = sym; l61: readsym (); if (sym != nl) { if (sym != i) { if (ti <= ci) goto er6; c[ti - (cbase)] = sym; ti--; goto l61; } } else { pend = sym; if (code != 'S' && code != 'I') goto er4; } if (ti == text && code != 'S') goto er4; c[ti - (cbase)] = 0; ti--; goto l81; t_8: /* move,erase */ if (sym != '-') goto l100; code += 10; l81: readitem (); goto l101; t_9: /* close bracket */ unchain (); if (text == 0) goto er3; code = 'Z'; c[text + 2 - (cbase)] = num; text += 3; t_10: /* +get,kill,etc. */ l100: if (type == 3) goto er1; l101: if (type == 0) readitem (); goto put; t_11: /* open bracket */ code = 'X'; goto l121; t_12: /* comma */ code = 'Y'; if (type == 1) readitem (); l121: text = chain; chain = ci; num = 0; put: stack (code); stack (text); stack (num); if ((ci + 4) >= ti) goto er6; if (type != 1) goto l2; unchain (); if (text != 0) goto er3; cmax = ci; stack ('Z'); stack (cbase); stack (1); /* extra close b */ stack (0); goto go; /*command input error reports */ er1: fprintf (out_file, "%s", " "); fprintf (out_file, "%c", code); er2: code = sym; goto er5; er3: fprintf (out_file, "%s", " ()"); goto er7; er4: fprintf (out_file, "%s", " TEXT FOR"); t_0: er5: fprintf (out_file, "%s", " "); fprintf (out_file, "%c", code & 127); goto er7; er6: fprintf (out_file, "%s", " SIZE"); er7: fprintf (out_file, "%c", '?'); fprintf (out_file, "%s", "\n"); if (ci != cbase) cmax = 0; l10: if (sym < 32) goto l1; readsym (); goto l10; /*execute command line */ go: ci = cbase; get: code = c[ci - (cbase)] & 127; if (code == 0) goto l99; text = c[ci + 1 - (cbase)]; num = c[ci + 2 - (cbase)]; ci += 3; rep: num--; { s_value = code; s_line = __LINE__; s_file = __FILE__; goto s_despatch; } ok: if (num != 0 && num != stop) goto rep; goto get; s_92: /* invert */ no: if (num < 0) goto get; if (c[ci - (cbase)] == '\\') { ci += 3; goto get; } skp: i = c[ci - (cbase)]; if (i == 'X') ci = c[ci + 1 - (cbase)]; ci += 3; if (i > 'X') { num = c[ci - 1 - (cbase)] - 1; goto no; } if (i != 0) goto skp; /*execution error report */ fprintf (out_file, "%s", "FAILURE: "); if (code == 'O' || code == 'W') { fprintf (out_file, "%c", code - 10); code = '-'; } fprintf (out_file, "%c", code); if (text != 0) { fprintf (out_file, "%c", '\''); while (c[text - (cbase)] != 0) { fprintf (out_file, "%c", c[text - (cbase)]); text--; } fprintf (out_file, "%c", '\''); } fprintf (out_file, "%s", "\n"); print1 = 0; /*end of command line */ l99: if (sym != nl) goto l1; if ((mon < 0 || print1 == lend) && (mon <= 0 || print2 == (fp + pp))) goto l1; num = 0; printline (); goto l1; /*individual commands */ s_88: /* open bracket */ c[text + 2 - (cbase)] = num + 1; goto get; s_90: /* close bracket */ if (num == 0 || num == stop) goto get; c[ci - 1 - (cbase)] = num; s_89: /* +comma */ ci = text; goto get; s_82: /* right shift */ if (fp == lend) goto no; loadpp (byte[fp]); fp++; goto ok; s_76: /* left shift */ if (in == sin || pp == lbeg) goto no; fp--; pp--; loadfp (byte[pp]); ms = 0; goto ok; s_69: /* erase */ if (fp == lend) goto no; fp++; goto ok; s_79: /* erase back */ if (pp == lbeg) goto no; pp--; goto ok; s_86: /* verify */ i = fp - 1; j = text + 1; v1: i++; j--; k = c[j - (cbase)]; if (byte[i] == k) goto v1; if (k != 0) goto no; ms = fp; ml = i; goto ok; s_70: /* find */ if (matched () == 0) goto no; goto ok; s_85: /* uncover */ if (matched () == 0) goto no; pp = pp1; goto ok; s_68: /* delete */ if (matched () == 0) goto no; fp = ml; goto ok; s_84: /* traverse */ if (matched () == 0) goto no; s_83: /* +substitute */ if (fp == ms) fp = ml; s_73: /* +insert */ makespace (); /*! ->no %IF pp-lbeg+lend-fp > 80 */ i = text; i1: if (c[i - (cbase)] == 0) goto ok; loadpp (c[i - (cbase)]); i--; goto i1; s_71: /* get (line from tt) */ fprintf (out_file, ":"); fflush (out_file); /*! make space */ i = fgetc (in_file); if (i == ':') goto no; leftstar (); while (i != nl) { loadpp (i); i = fgetc (in_file); } s_66: /* +break (insert newline) */ makespace (); loadpp (nl); lbeg = pp; goto ok; s_80: /* print */ printline (); if (num == 0) goto get; s_77: /* +move */ rightstar (); if (fp == fend) goto no; loadpp (nl); lbeg = pp; m1: fp++; makespace (); readline (); goto ok; s_75: /* kill (line) */ pp = lbeg; fp = lend; k1: if (fp == fend) goto no; goto m1; s_74: /* join (delete newline) */ rightstar (); /*! ->no %IF pp-lbeg > 80 */ goto k1; s_87: /* move back */ if (in == sin) goto no; makespace (); if (lbeg == top) goto no; lend = ((fp - pp) + lbeg) - 1; w1: k = byte[pp - 1]; if (k == nl && pp != lbeg) goto w2; fp--; pp--; loadfp (k); goto w1; w2: lbeg = pp; ms = 0; goto ok; t_1: /* %S, %C */ if (code == 'C') goto eof; switchinputs (); goto l99; eof: code = 'C'; /* +eof on command stream */ if (in == sin) switchinputs (); for (;;) { rightstar (); if (fp == fend) break; loadpp (nl); lbeg = pp; fp++; makespace (); readline (); } selectoutput (mout); while (top != pp) { fprintf (out_file, "%c", byte[top]); top++; } exit (0); goto s_skip; s_despatch: switch (s_value) { case '\\': goto s_92; case 'X': goto s_88; case 'Z': goto s_90; case 'Y': goto s_89; case 'R': goto s_82; case 'L': goto s_76; case 'E': goto s_69; case 'O': goto s_79; case 'V': goto s_86; case 'F': goto s_70; case 'U': goto s_85; case 'D': goto s_68; case 'T': goto s_84; case 'S': goto s_83; case 'I': goto s_73; case 'G': goto s_71; case 'B': goto s_66; case 'P': goto s_80; case 'M': goto s_77; case 'K': goto s_75; case 'J': goto s_74; case 'W': goto s_87; default: BADSWITCH (s_value, s_line, s_file); } s_skip:; goto t_skip; t_despatch: switch (t_value) { case 2: goto t_2; case 3: goto t_3; case 4: goto t_4; case 5: goto t_5; case 6: goto t_6; case 8: goto t_8; case 9: goto t_9; case 10: goto t_10; case 11: goto t_11; case 12: goto t_12; case 0: goto t_0; case 1: goto t_1; default: BADSWITCH (t_value, t_line, t_file); } t_skip:; } /* end of automatic translation */