// This is a severely mangled version of ecce which *might* translate // into javascript, so that it can be used in a web page. I already have // a working web text console that will handle simple text input & output. #include #include static char *prompt; static char *inp = NULL; void xprompt (char *s) { prompt = s; } int consoleget (void) { if ((inp == NULL) || (*inp == '\0')) { fprintf(stderr, "Assertion failed: inp\n"); exit(1); } return *inp++; } void psym (int c) { putchar(c); } int fileget (int stream) { return -1; } void putsym (int c) { } static int min; static int sin; static int stop; static int in; static int mon; static int casebit; static int print1; static int print2; static int sextra; static int pp1; static int sym; static int code; static int text; static int num; static int cbase; static int tbase; static int ci; static int ti; static int cmax; static int c[121]; static int stored[193]; static int pos1; static int pos2; static int pos3; static int bufmax; static int top; static int bot; static int a[510001]; static int lbeg; static int pp; static int fp; static int lend; static int fend; static int ms; static int ml; static int type; static int chain; static int pend; static int mfp; static int mlend; static int mend; static int sfp; static int send; const int symtype[96] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 18, 10, 26, 5, 8, 52, 10, 2, 6, 10, 10, 122, 56, 2, 2, 10, 50, 10, 22, 5, 117, 6, 2, 32, 32, 32, 3, 10, 3, 3, 3 }; static int i; static int j; static int k; static int nl; static int k; static int k; static int p1; static int p2; static int p; static int i; static int j; static int k; static int l; static int t1; static int fp1; static int lim; int mainfp (void) { if (in == min) return fp; return mfp; } void readsym (void) { if (pend != 0) { sym = pend; pend = 0; } else for (;;) { if (pos3 == 0) { sym = consoleget (); return; } sym = stored[pos3]; pos3 = pos3 + 1; if (sym != 0) return; pos3 = pos2; pos2 = pos1; pos1 = 0; } } int readitem (void) { do { type = 1; do { readsym (); if (sym < 0) return -1; } while (sym == ' '); if (sym < ' ') return 0; if (sym >= 96) sym = sym - 32; type = symtype[sym]; if ((type & 15) != 0) return 0; if (type == 32) { pos1 = pos2; pos2 = pos3; pos3 = (sym - 'X' << 6) + 1; } } while (type == 32); if (type == 0) { num = sym - '0'; for (;;) { readsym (); if (sym < 0) return 0; pend = sym; if (sym < '0') return 0; if (sym > '9') return 0; pend = 0; num = num * 10 - '0' + sym; } } else { type = 0; num = 0; if (sym == '*') return 0; num = stop + 1; if (sym == '?') return 0; num = stop; } return 0; } void unchain (void) { do { text = chain; if (text == 0) return; chain = c[text + 1]; c[text + 1] = ci; } while (c[text] != '('); } void stack (int v) { c[ci] = v; ci = ci + 1; } void readline (void) { static int k; if (fp != fend) { lend = fp; for (;;) { if (a[lend] == nl) return; lend = lend + 1; } } fp = bot - 1121; do { k = nl; if (fp != bot) k = fileget (in); if (k < 0) { fp = bot; lend = fp; fend = lend; a[fp] = nl; ms = 0; print1 = 0; print2 = 0; return; } a[fp] = k; fp = fp + 1; } while (k != nl); fend = fp; lend = fend - 1; fp = bot - 1121; ms = 0; print1 = 0; print2 = 0; } void breakline (void) { a[pp] = nl; pp = pp + 1; lbeg = pp; } void leftstar (void) { for (;;) { if (pp == lbeg) return; fp = fp - 1; pp = pp - 1; a[fp] = a[pp]; } } void rightstar (void) { for (;;) { if (fp == lend) return; a[pp] = a[fp]; pp = pp + 1; fp = fp + 1; } } void makespace (void) { static int k; static int p1; static int p2; if (mainfp () - pp > 240) return; p1 = top; p2 = p1 + lbeg >> 1; if (code == 'C') p2 = lbeg; // if (p2 == top) dosignal (15, p1, p2); do { k = a[p1]; putsym (k); p1 = p1 + 1; if (p1 < p2) k = 0; } while (k != nl); lbeg = top + lbeg - p1; p2 = pp; pp = top; for (;;) { if (p1 == p2) return; a[pp] = a[p1]; pp = pp + 1; p1 = p1 + 1; } } void refresh (void) { fp = fp + 1; makespace (); readline (); } void printline (void) { static int p; print1 = lend; print2 = fp + pp; p = lbeg; for (;;) { if (p == pp) { if (p != lbeg) if (num == 0) psym ('^'); p = fp; } if (p == lend) { if (p == fend) { psym ('*'); psym ('*'); psym ('E'); psym ('n'); psym ('d'); psym ('*'); psym ('*'); } psym (nl); return; } psym (a[p]); p = p + 1; } } int cased (int ch) { if (ch < 'a') return ch; if (ch > 'z') return ch; return ch & casebit; } int matched (void) { static int i; static int j; static int k; static int l; static int t1; static int fp1; static int lim; lim = c[ci - 3] >> 7; t1 = cased (c[text]); for (;;) { pp1 = pp; fp1 = fp; if (fp != lend) do { k = a[fp]; if (cased (k) == t1) { if (fp == ms) { if ((code == 'F') || (code == 'U')) { a[pp] = k; pp = pp + 1; fp = fp + 1; continue; } } i = fp; j = text; do { i = i + 1; j = j - 1; l = cased (c[j]); if (l == 0) { ms = fp; ml = i; return 1; } } while (cased (a[i]) == l); } if (code == 'V') return 0; a[pp] = k; pp = pp + 1; fp = fp + 1; } while (fp != lend); if (code == 'V') return 0; lim = lim - 1; if (fp == fend) lim = 0; if (lim == 0) { pp = pp1; fp = fp1; return 0; } if (code == 'U') pp = pp1; else breakline (); refresh (); } } void switchinputs (void) { if (in == min) { leftstar (); in = sin; mfp = fp; mlend = lend; mend = fend; bot = bot + sextra; fp = sfp; fend = send; readline (); } else { pp = lbeg; in = min; bot = bot - sextra; sfp = fp; send = fend; fp = mfp; lend = mlend; fend = mend; } } #define INIT 0 #define GETCOMMAND 1 #define GETDATA 2 #define readco 3 #define nextunit 4 #define eof 5 #define ri 6 #define nq 7 #define rn 8 #define put 9 #define er1 10 #define er2 11 #define er3 12 #define er4 13 #define er5 14 #define er6 15 #define er7 16 #define execute 17 #define get 18 #define rep 19 #define ok 20 #define no 21 #define skp 22 #define xer 23 #define monitor 24 #define xlb 25 #define xrb 26 #define xcomma 27 #define xc 28 #define xr 29 #define xl 30 #define xe 31 #define xo 32 #define xv 33 #define xu 34 #define xd 35 #define xf 36 #define xt 37 #define xs 38 #define xi 39 #define xg 40 #define xb 41 #define xp 42 #define xm 43 #define m1 44 #define xk 45 #define k1 46 #define xj 47 #define xw 48 int ecceinner(int state); int ecce(int state, char *input) { int next = state; inp = input; // new data to be returned by getchar for (;;) { next = ecceinner(next); if (next <= 2) return; } } int ecceinner(int state) { for (;;) { switch (state) { // co-routine labels: // if (state == 0) goto INIT; // if (state == 1) goto GETCOMMAND; // if (state == 2) goto GETDATA; case INIT: min = 1; sin = 2; stop = -5000; in = min; mon = 0; casebit = 95; print1 = 0; print2 = 0; sextra = 1122; cbase = 1; tbase = 120; cmax = 0; pos1 = 0; pos2 = 0; pos3 = 0; bufmax = 510000; top = 1; bot = 509878; fp = 0; lend = 0; fend = 0; ms = 0; ml = 0; pend = 0; mfp = 0; mlend = 0; mend = 0; sfp = 0; send = 0; nl = 10; psym ('E'); psym ('C'); psym ('C'); psym ('E'); psym (' '); psym ('0'); psym ('6'); psym ('/'); psym ('0'); psym ('1'); psym ('/'); psym ('8'); psym ('1'); psym (nl); pp = top - 1; breakline (); readline (); case readco: if (in == sin) xprompt (">>"); else xprompt (">"); return state = 1; case GETCOMMAND: { ci = cbase; ti = tbase; chain = 0; if (readitem () < 0) {state = eof; return state;} if (type == 1) return state = 1; } if (type == 0) if (cmax != 0) { c[cmax + 2] = num; if (readitem () < 0) {state = eof; return state;} if (type != 1) {state = er2; return state;} {state = execute; return state;} } if (sym == '%') { readsym (); if (sym < 0) {state = eof; return state;} if (sym >= 96) sym = sym - 32; code = sym; if (code < 'A') {state = er5; return state;} if (readitem () < 0) {state = eof; return state;} i = symtype[code] >> 4; } else { case nextunit: i = type & 15; if (i < 4) {state = er2; return state;} code = sym; text = 0; num = 1; if (readitem () < 0) {state = eof; return state;} } if (i == 0) {state = er5; return state;} if (i == 1) { // if (code == 'A') dosignal (0, 0, 0); if (code == 'S') { switchinputs (); {state = monitor; return state;} } case eof: code = 'C'; if (in == sin) switchinputs (); for (;;) { rightstar (); if (fp == fend) for (;;) { if (top == pp) exit(0); putsym (a[top]); top = top + 1; } breakline (); refresh (); } } if (i == 2) { i = (code - 'X' << 6) + 1; if (sym == '=') { do { readsym (); if (sym < 0) {state = eof; return state;} if (sym != nl) { stored[i] = sym; if ((i & 63) == 0) {state = er6; return state;} i = i + 1; } } while (sym != nl); stored[i] = 0; {state = readco; return state;} } for (;;) { sym = stored[i]; if (sym == 0) { psym (nl); {state = readco; return state;} } psym (sym); i = i + 1; } } if (i == 3) { mon = 'M' - code; {state = readco; return state;} } if (i == 4) if (type != 0) num = 0; if (i <= 5) { code = (num << 7) + code; num = 1; if (type == 0) if (readitem () < 0) {state = eof; return state;} } if (i <= 6) { if (type != 3) {state = er4; return state;} text = ti; i = sym; for (;;) { readsym (); if (sym < 0) {state = eof; return state;} if (sym == nl) { pend = sym; i = sym; } if (sym == i) { if (code != 'I') if (code != 'S') { if (sym == nl) {state = er4; return state;} if (ti == text) {state = er4; return state;} } c[ti] = 0; ti = ti - 1; {state = ri; return state;} } if (ti <= ci) {state = er6; return state;} c[ti] = sym; ti = ti - 1; } } if (i == 7) { casebit = 95; if (code == 'L') casebit = 127; {state = readco; return state;} } if (i == 8) { if (sym != '-') {state = nq; return state;} code = code + 10; case ri: if (readitem () < 0) {state = eof; return state;} {state = rn; return state;} } if (i == 9) { unchain (); if (text == 0) {state = er3; return state;} c[text + 2] = num; text = text + 3; } if (i <= 10) { case nq: if (type == 3) {state = er1; return state;} case rn: if (type == 0) if (readitem () < 0) {state = eof; return state;} {state = put; return state;} } if (i == 12) if (type == 1) if (readitem () < 0) {state = eof; return state;} if (i <= 12) { text = chain; chain = ci; num = 0; } // if (i > 12) dosignal (14, 1, i); case put: stack (code); stack (text); stack (num); if (ci + 4 >= ti) {state = er6; return state;} if (type != 1) {state = nextunit; return state;} unchain (); if (text != 0) {state = er3; return state;} cmax = ci; stack (')'); stack (cbase); stack (1); stack (0); {state = execute; return state;} case er1: psym (' '); psym (code); case er2: code = sym; {state = er5; return state;} case er3: psym (' '); psym ('('); psym (')'); {state = er7; return state;} case er4: psym (' '); psym ('T'); psym ('e'); psym ('x'); psym ('t'); psym (' '); psym ('f'); psym ('o'); psym ('r'); case er5: psym (' '); psym (code & 127); {state = er7; return state;} case er6: psym (' '); psym ('S'); psym ('i'); psym ('z'); psym ('e'); case er7: psym ('?'); psym (nl); if (ci != cbase) cmax = 0; for (;;) { if (sym == nl) {state = readco; return state;} readsym (); if (sym < 0) {state = eof; return state;} } case execute: ci = cbase; case get: code = c[ci] & 127; if (code == 0) {state = monitor; return state;} text = c[ci + 1]; num = c[ci + 2]; ci = ci + 3; case rep: num = num - 1; if (code == 'M') {state = xm; return state;} if (code == 'W') {state = xw; return state;} if (code == 'L') {state = xl; return state;} if (code == 'R') {state = xr; return state;} if (code == 'C') {state = xc; return state;} if (code == '(') {state = xlb; return state;} if (code == ',') {state = xcomma; return state;} if (code == ')') {state = xrb; return state;} if (code == '\\') {state = no; return state;} if (code == 'J') {state = xj; return state;} if (code == 'K') {state = xk; return state;} if (code == 'P') {state = xp; return state;} if (code == 'B') {state = xb; return state;} if (code == 'G') {state = xg; return state;} if (code == 'I') {state = xi; return state;} if (code == 'S') {state = xs; return state;} if (code == 'T') {state = xt; return state;} if (code == 'D') {state = xd; return state;} if (code == 'U') {state = xu; return state;} if (code == 'F') {state = xf; return state;} if (code == 'V') {state = xv; return state;} if (code == 'O') {state = xo; return state;} if (code == 'E') {state = xe; return state;} // dosignal (14, 2, code); case ok: if (num == 0) {state = get; return state;} if (num == stop) {state = get; return state;} {state = rep; return state;} case no: if (num < 0) {state = get; return state;} if (c[ci] == '\\') { ci = ci + 3; {state = get; return state;} } case skp: i = c[ci]; if (i == '(') ci = c[ci + 1]; ci = ci + 3; if (i != ',') if (i != ')') { if (i != 0) {state = skp; return state;} {state = xer; return state;} } num = c[ci - 1] - 1; {state = no; return state;} case xer: psym ('F'); psym ('a'); psym ('i'); psym ('l'); psym ('e'); psym ('d'); psym (' '); if (code == 'O') { psym ('E'); code = '-'; } else if (code == 'W') { psym ('M'); code = '-'; } psym (code); if (text != 0) { psym ('"'); do { i = c[text]; if (i != 0) psym (i); text = text - 1; } while (i != 0); psym ('"'); } psym (nl); print1 = 0; case monitor: if (sym != nl) {state = readco; return state;} if (mon < 0) {state = readco; return state;} if (print1 == lend) { if (mon == 0) {state = readco; return state;} if (print2 == fp + pp) {state = readco; return state;} } num = 0; printline (); {state = readco; return state;} case xlb: c[text + 2] = num + 1; {state = get; return state;} case xrb: if (num == 0) {state = get; return state;} if (num == stop) {state = get; return state;} c[ci - 1] = num; case xcomma: ci = text; {state = get; return state;} case xc: if (fp == lend) {state = no; return state;} i = a[fp]; if ((i & 95) >= 'A') if ((i & 95) <= 'Z') if ((i & 32) != 0) a[fp] = i - 32; else a[fp] = i + 32; case xr: if (fp == lend) {state = no; return state;} a[pp] = a[fp]; pp = pp + 1; fp = fp + 1; {state = ok; return state;} case xl: if (pp == lbeg) {state = no; return state;} if (in == sin) {state = no; return state;} fp = fp - 1; pp = pp - 1; a[fp] = a[pp]; ms = 0; {state = ok; return state;} case xe: if (fp == lend) {state = no; return state;} fp = fp + 1; {state = ok; return state;} case xo: if (pp == lbeg) {state = no; return state;} pp = pp - 1; {state = ok; return state;} case xv: case xu: case xd: case xf: if (matched () == 0) {state = no; return state;} if (code == 'U') pp = pp1; else if (code == 'D') fp = ml; {state = ok; return state;} case xt: if (matched () == 0) {state = no; return state;} do { a[pp] = a[fp]; pp = pp + 1; fp = fp + 1; } while (fp != ml); {state = ok; return state;} case xs: if (fp != ms) {state = no; return state;} fp = ml; case xi: makespace (); if (pp - lbeg + lend - fp > 80) {state = no; return state;} i = text; for (;;) { if (c[i] == 0) {state = ok; return state;} a[pp] = c[i]; pp = pp + 1; i = i - 1; } case xg: fflush (0); xprompt (":"); makespace (); return state = 2; // co-routine break case GETDATA: i = consoleget (); if (i < 0) {state = eof; return state;} if (i == ':') {state = no; return state;} leftstar (); if (i != nl) do { a[pp] = i; pp = pp + 1; i = consoleget (); if (i < 0) {state = eof; return state;} } while (i != nl); case xb: breakline (); {state = ok; return state;} case xp: printline (); if (num == 0) {state = get; return state;} case xm: rightstar (); if (fp == fend) {state = no; return state;} breakline (); case m1: refresh (); {state = ok; return state;} case xk: pp = lbeg; fp = lend; case k1: if (fp == fend) {state = no; return state;} {state = m1; return state;} case xj: rightstar (); if (pp - lbeg > 80) {state = no; return state;} {state = k1; return state;} case xw: if (in == sin) {state = no; return state;} makespace (); if (lbeg == top) {state = no; return state;} lend = fp - pp + lbeg - 1; for (;;) { k = a[pp - 1]; if (k == nl) if (pp != lbeg) { lbeg = pp; ms = 0; {state = ok; return state;} } fp = fp - 1; pp = pp - 1; a[fp] = k; } } // switch } // for loop around switch } static char lineBuffer[128]; int main (int argc, char **argv) { char *s; int next; lineBuffer[0] = '\0'; next = ecce(0, lineBuffer); // initialise for (;;) { fprintf(stderr, "%s", prompt); s = fgets(lineBuffer, 128, stdin); // fails if blank linr if (s == NULL) break; next = ecce(next, lineBuffer); } }