#include "sno.h" /* * Snobol III */ int freesize; struct node *freespace &end; struct node *freelist 0; int *fault -1; mes(s) { sysput(strstr(s)); } init(s, t) { register struct node *a, *b; a = strstr(s); b = look(a); delete(a); b->typ = t; return(b); } main(argc, argv) char *argv[]; { extern fin, fout; register struct node *a, *b, *c; if(argc > 1) { fin = open(argv[1], 0); if(fin < 0) { mes("cannot open input"); exit(); } } fout = dup(1); lookf = init("f", 0); looks = init("s", 0); lookend = init("end", 0); lookstart = init("start", 0); lookdef = init("define", 0); lookret = init("return", 0); lookfret = init("freturn", 0); init("syspit", 3); init("syspot", 4); a = c = compile(); while (lookend->typ != 2) { a->p1 = b = compile(); a = b; } cfail = 1; a->p1 = 0; if (lookstart->typ == 2) c = lookstart->p2; while (c=execute(c)); flush(); } syspit() { extern fin; register struct node *b, *c, *d; int a; if ((a=getchar())=='\n') return(0); b = c = alloc(); while(a != '\n') { c->p1 = d = alloc(); c = d; l: c->ch = a; if(a == '\0') { if(fin) { close(fin); fin = 0; a = getchar(); goto l; } rfail = 1; break; } a = getchar(); } b->p2 = c; if(rfail) { delete(b); b = 0; } return(b); } syspot(string) struct node *string; { register struct node *a, *b, *s; s = string; if (s!=0) { a = s; b = s->p2; while(a != b) { a = a->p1; putchar(a->ch); } } putchar('\n'); } strstr(s) char s[]; { int c; register struct node *e, *f, *d; d = f = alloc(); while ((c = *s++)!='\0') { (e=alloc())->ch = c; f->p1 = e; f = e; } d->p2 = e; return(d); } class(c) { switch (c) { case ')': return(1); case '(': return(2); case '\t': case ' ': return(3); case '+': return(4); case '-': return(5); case '*': return(6); case '/': return(7); case '$': return(8); case '"': case '\'': return(9); case '=': return(10); case ',': return(11); } return(0); } alloc() { register struct node *f; register int i; extern fout; if (freelist==0) { if (--freesize < 20) { if ((i=sbrk(1200)) == -1) { flush(); write (fout, "Out of free space\n", 18); exit(); } freesize =+ 200; } return(freespace++); } f = freelist; freelist = freelist->p1; return(f); } free(pointer) struct node *pointer; { pointer->p1 = freelist; freelist = pointer; } nfree() { register int i; register struct node *a; i = freesize; a = freelist; while(a) { a = a->p1; i++; } return(i); } look(string) struct node *string; { register struct node *i, *j, *k; k = 0; i = namelist; while (i) { j = i->p1; if (equal(j->p1, string) == 0) return(j); i = (k=i)->p2; } i = alloc(); i->p2 = 0; if (k) k->p2 = i; else namelist = i; j = alloc(); i->p1 = j; j->p1 = copy(string); j->p2 = 0; j->typ = 0; return(j); } copy(string) struct node *string; { register struct node *j, *l, *m; struct node *i, *k; if (string == 0) return(0); i = l = alloc(); j = string; k = string->p2; while(j != k) { m = alloc(); m->ch = (j=j->p1)->ch; l->p1 = m; l = m; } i->p2 = l; return(i); } equal(string1, string2) struct node *string1, *string2; { register struct node *i, *j, *k; struct node *l; int n, m; if (string1==0) { if (string2==0) return(0); return(-1); } if (string2==0) return(1); i = string1; j = string1->p2; k = string2; l = string2->p2; for(;;) { m = (i=i->p1)->ch; n = (k=k->p1)->ch; if (m>n) return(1); if (mp1; q = s->p2; sign = 1; if (class(p->ch)==5) { /* minus */ sign = -1; if (p==q) return(0); p = p->p1; } loop: m = p->ch - '0'; if (m>9 | m<0) writes("bad integer string"); n = n * 10 + m; if (p==q) return(n*sign); p = p->p1; goto loop; } binstr(binary) { int n, sign; register struct node *m, *p, *q; n = binary; p = alloc(); q = alloc(); sign = 1; if (binary<0) { sign = -1; n = -binary; } p->p2 = q; loop: q->ch = n%10+'0'; n = n / 10; if (n==0) { if (sign<0) { m = alloc(); m->p1 = q; q = m; q->ch = '-'; } p->p1 = q; return(p); } m = alloc(); m->p1 = q; q = m; goto loop; } add(string1, string2) { return(binstr(strbin(string1) + strbin(string2))); } sub(string1, string2) { return(binstr(strbin(string1) - strbin(string2))); } mult(string1, string2) { return(binstr(strbin(string1) * strbin(string2))); } div(string1, string2) { return(binstr(strbin(string1) / strbin(string2))); } cat(string1, string2) struct node *string1, *string2; { register struct node *a, *b; if (string1==0) return(copy(string2)); if (string2==0) return(copy(string1)); a = copy(string1); b = copy(string2); a->p2->p1 = b->p1; a->p2 = b->p2; free(b); return(a); } dcat(a,b) struct node *a, *b; { register struct node *c; c = cat(a,b); delete(a); delete(b); return(c); } delete(string) struct node *string; { register struct node *a, *b, *c; if (string==0) return; a = string; b = string->p2; while(a != b) { c = a->p1; free(a); a = c; } free(a); } sysput(string) { syspot(string); delete(string); } dump() { dump1(namelist); } dump1(base) struct node *base; { register struct node *b, *c, *e; struct node *d; while (base) { b = base->p1; c = binstr(b->typ); d = strstr(" "); e = dcat(c, d); sysput(cat(e, b->p1)); delete(e); if (b->typ==1) { c = strstr(" "); sysput(cat(c, b->p2)); delete(c); } base = base->p2; } } writes(s) { sysput(dcat(binstr(lc),dcat(strstr("\t"),strstr(s)))); flush(); if (cfail) { dump(); flush(); exit(); } while(getc()); while (compile()); flush(); exit(); } getc() { register struct node *a; static struct node *line; static linflg; while (line==0) { line = syspit(); if(rfail) { cfail++; writes("eof on input"); } lc++; } if (linflg) { line = 0; linflg = 0; return(0); } a = line->p1; if (a==line->p2) { free(line); linflg++; } else line->p1 = a->p1; return(a); }