Add original unix v6
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
|
||||
struct {
|
||||
int word;
|
||||
};
|
||||
|
||||
struct { /*"put stack", currently gathering args*/
|
||||
int prev; /*previous frame ptr, self-relative*/
|
||||
int pan; /*argument number of arg being collected*/
|
||||
int pa0; /*self-relative ptr oo arg0*/
|
||||
#define pend 6
|
||||
};
|
||||
|
||||
struct { /*"get stack", currently expanding macros*/
|
||||
int prev; /* prev frame ptr, self-realtive*/
|
||||
int mframe; /* ptr to macro definition frame*/
|
||||
int mchar; /* next char relative to def. frame*/
|
||||
int marg; /* 0 or ptr to next arg char reltive to gf*/
|
||||
int ga0; /* arg0 ptr self-rel*/
|
||||
};
|
||||
|
||||
struct { /*"definition stack"*/
|
||||
int prev; /* prev frame ptr, self-relative*/
|
||||
int dswitch; /* builtin func code, neg for dead definition*/
|
||||
int dtext; /* definition text prt rel to df*/
|
||||
int dident; /* first char of identifier naming def*/
|
||||
#define dend 6
|
||||
};
|
||||
|
||||
char metas[];
|
||||
#define lquote metas[0]
|
||||
#define rquote metas[1]
|
||||
#define sharp metas[2]
|
||||
#define colon metas[3]
|
||||
#define semi metas[4]
|
||||
#define comma metas[5]
|
||||
#define dollar metas[6]
|
||||
#define NMETA 7
|
||||
|
||||
char one[];
|
||||
int rescan;
|
||||
int traceflag;
|
||||
int trashflag; /* nonzero when dead def'n exist*/
|
||||
|
||||
int lp; /* arg collection level (out level)*/
|
||||
int lg; /*input level (get level) */
|
||||
int lq; /*quote level*/
|
||||
int l9; /*apparent call level within arg 9*/
|
||||
|
||||
char c; /*current input character*/
|
||||
|
||||
char *pf; /*put stack frame ptr*/
|
||||
char *pe; /*put stack end*/
|
||||
char *pmax; /*top of put stack*/
|
||||
char p0[]; /*put stack*/
|
||||
|
||||
char *gf; /*get stack frame ptr*/
|
||||
char *ge; /*get stack end*/
|
||||
char *gmax; /*get stack limit*/
|
||||
char g0[]; /*get stack*/
|
||||
|
||||
char *df; /*definition stack frame ptr*/
|
||||
char *de; /*def stack end*/
|
||||
char *dmax; /*def stack limit*/
|
||||
char d0[]; /*def stack*/
|
||||
|
||||
char dummy[]; /*dummy empty macro*/
|
||||
@@ -0,0 +1,35 @@
|
||||
#
|
||||
|
||||
#include "m6.h"
|
||||
|
||||
main(argc,argv)
|
||||
char **argv;
|
||||
{
|
||||
extern fin;
|
||||
int t;
|
||||
gf = ge = g0;
|
||||
pf = pe = p0;
|
||||
t = g0;
|
||||
gmax =+ t-10;
|
||||
t = d0;
|
||||
dmax =+ t-10;
|
||||
t = p0;
|
||||
pmax =+ t-10;
|
||||
revptr(d0,d0+2,&df,&de);
|
||||
if(argc>1) {
|
||||
fin = open(argv[1],0);
|
||||
control();
|
||||
close(fin);
|
||||
}
|
||||
fin = dup(0);
|
||||
control();
|
||||
}
|
||||
|
||||
|
||||
diag(m) {
|
||||
printf("%s\n",m);
|
||||
iot();
|
||||
} /* abort */
|
||||
|
||||
int iot 4;
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#
|
||||
|
||||
#include "m6.h"
|
||||
|
||||
control() {
|
||||
|
||||
while(1) {
|
||||
get();
|
||||
if(c==0 && lg>0) {
|
||||
popget();
|
||||
trash();
|
||||
rescan = 1;
|
||||
}
|
||||
else {
|
||||
if(!rescan) put();
|
||||
else if(lq>0) {
|
||||
if(c==lquote) {
|
||||
lq++;
|
||||
put();
|
||||
}
|
||||
else if(c==rquote || c==0) {
|
||||
lq--;
|
||||
if(lq>0 || l9>0) put (rquote);
|
||||
}
|
||||
else put();
|
||||
}
|
||||
else if(l9>0)
|
||||
if(c==colon||c==0||c==semi)
|
||||
if(--l9<=0) endcall();
|
||||
else put();
|
||||
else {
|
||||
if(c==sharp) l9++;
|
||||
else if(c==lquote) lq++;
|
||||
put();
|
||||
}
|
||||
else {
|
||||
if(c==sharp) begincall();
|
||||
else if(c==lquote) lq++;
|
||||
else if(lp>0) {
|
||||
if(c==colon||c==0||c==semi) endcall();
|
||||
else if(c==comma) newarg();
|
||||
else put();
|
||||
}
|
||||
else if(c==0) return; /* lg=lp=lq=0 */
|
||||
else put();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endcall() {
|
||||
char *pt, *p;
|
||||
rescan = c!=semi;
|
||||
newarg();
|
||||
pushget();
|
||||
pt = &pf->pa0;
|
||||
ge = move(pt,&gf->ga0,pe-pt);
|
||||
if(ge>gmax) diag("Call stack overflow");
|
||||
if(traceflag) dotrace();
|
||||
p = finddef(0);
|
||||
setscan(p);
|
||||
popput();
|
||||
lp--;
|
||||
function(p->dswitch);
|
||||
}
|
||||
|
||||
begincall() {
|
||||
lp++;
|
||||
pushput();
|
||||
pe = pf+pend;
|
||||
pf->pan = pf->pa0 = 0;
|
||||
}
|
||||
|
||||
newarg() {
|
||||
char *p;
|
||||
if(++pf->pan>=9) if(c==comma) l9++;
|
||||
*pe++ = 0;
|
||||
pe = (pe+1)&0177776;
|
||||
p = &pf->pa0;
|
||||
while(p->word!=0) p =+ p->word;
|
||||
p->word = pe - p;
|
||||
*pe++ = *pe++ = 0;
|
||||
}
|
||||
|
||||
setscan(p)
|
||||
char *p;
|
||||
{
|
||||
gf->mchar = (gf->mframe = p)->dtext;
|
||||
gf->marg = 0;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#
|
||||
|
||||
#include "m6.h"
|
||||
|
||||
char *
|
||||
finddef(n) {
|
||||
char *p;
|
||||
if((p = lookup(arg(n)))==0)
|
||||
if((p = lookup(""))==0) diag("Software error");
|
||||
return(p);
|
||||
}
|
||||
|
||||
char *
|
||||
lookup(s) {
|
||||
char *dt;
|
||||
dt = df;
|
||||
while(dt>d0) {
|
||||
if(dt->dswitch>=0 && comp(s,&dt->dident)) return(dt);
|
||||
dt =+ dt->prev;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
comp(s,t)
|
||||
char *s, *t;
|
||||
{
|
||||
for(;*s++ == *t;t++)
|
||||
if(*t==0) return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
remove(n) {
|
||||
char *p;
|
||||
if(p = lookup(arg(n))) if(p>d0+2) {
|
||||
trashflag++;
|
||||
p->dswitch = -1;
|
||||
}
|
||||
}
|
||||
|
||||
trash() {
|
||||
char *p,*q,*r;
|
||||
if(lg>0) return;
|
||||
while(df->dswitch<0) {
|
||||
de = df;
|
||||
df =+ df->prev;
|
||||
trashflag--;
|
||||
}
|
||||
if(trashflag<=0) return;
|
||||
de = (de+1)&0177776;
|
||||
revptr(de,df,&p,&q);
|
||||
q = p;
|
||||
for(;p->word!=0;p=+r->word) {
|
||||
r = p;
|
||||
if(p->dswitch>=0) {
|
||||
r = q;
|
||||
q = move(p,q,p->word);
|
||||
}
|
||||
}
|
||||
q->word = 0;
|
||||
revptr(d0,d0+2,&df,&de);
|
||||
}
|
||||
|
||||
|
||||
revptr(p,q,np,nq)
|
||||
char *p, *q, **np, **nq;
|
||||
{
|
||||
int t;
|
||||
p->word = 0;
|
||||
while((t = q->word)!=0) {
|
||||
q->word = p-q;
|
||||
p = q;
|
||||
q =+ t;
|
||||
if(q<d0 || q>dmax) diag("Software error");
|
||||
}
|
||||
*np = p;
|
||||
*nq = q;
|
||||
}
|
||||
|
||||
char *
|
||||
move(from,to,count)
|
||||
char *from, *to;
|
||||
{
|
||||
while(count-->0) *to++ = *from++;
|
||||
return(to);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
#
|
||||
|
||||
#include "m6.h"
|
||||
|
||||
pushget() {
|
||||
ge = (ge+1)&0177776;
|
||||
ge->word = gf-ge;
|
||||
gf = ge;
|
||||
ge =+2;
|
||||
++lg;
|
||||
}
|
||||
|
||||
dotrace() {
|
||||
char *arg();
|
||||
int i,j;
|
||||
printf("\n%d %c%s",lg,sharp,arg(0));
|
||||
for(j=9;j>0&&*arg(j)==0;j--);
|
||||
for(i=1;i<=j;i++)
|
||||
printf("%c%c%s%c",comma,lquote,arg(i),rquote);
|
||||
printf("%c\n",c);
|
||||
}
|
||||
|
||||
popget() {
|
||||
ge = gf;
|
||||
gf =+ gf->word;
|
||||
--lg;
|
||||
if(gf<g0) diag("Software error");
|
||||
}
|
||||
|
||||
pushput() {
|
||||
if(pe&1) {
|
||||
pf->prev =| 1;
|
||||
pe++;
|
||||
}
|
||||
pe->word = pf-pe;
|
||||
pf = pe;
|
||||
pe =+2;
|
||||
}
|
||||
|
||||
popput() {
|
||||
pe = pf;
|
||||
pf =+ pf->word;
|
||||
if(pf->prev&1) {
|
||||
pe--;
|
||||
pf->prev =& 0177776;
|
||||
}
|
||||
if(pf<p0) diag("Software error");
|
||||
}
|
||||
|
||||
pushdef() {
|
||||
de = (de+1)&0177776;
|
||||
de->word = df-de;
|
||||
df = de;
|
||||
de =+2;
|
||||
}
|
||||
|
||||
put() {
|
||||
if(lp>0) {
|
||||
*pe++ = c;
|
||||
if(pe>pmax) diag("Arg collection overflow");
|
||||
}
|
||||
else putchar(c);
|
||||
}
|
||||
|
||||
get() {
|
||||
char *p;
|
||||
int n;
|
||||
if(lg==0)
|
||||
c = getchar();
|
||||
else while(1) {
|
||||
if(gf->marg!=0) {
|
||||
if((c = gf[gf->marg++])==0) gf->marg = 0;
|
||||
else return;
|
||||
}
|
||||
c = (p = gf->mframe)[gf->mchar++];
|
||||
if(c!=dollar) return;
|
||||
n = p[gf->mchar] - '0';
|
||||
if(n<0 || n>9) return;
|
||||
++gf->mchar;
|
||||
gf->marg = arg(n) - gf;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#
|
||||
|
||||
#include "m6.h"
|
||||
|
||||
define() {
|
||||
remove(1);
|
||||
newdef(decbin(3));
|
||||
setdef(arg(1),arg(2));
|
||||
}
|
||||
|
||||
newdef(n) {
|
||||
pushdef();
|
||||
de = &df[df->dtext = dend];
|
||||
if((df->dswitch = n)<0) trashflag++;
|
||||
}
|
||||
|
||||
setdef(s1,s2) {
|
||||
copydef(s1);
|
||||
df->dtext = de -df;
|
||||
copydef(s2);
|
||||
}
|
||||
|
||||
copydef(s)
|
||||
char *s;
|
||||
{
|
||||
while(*de++ = *s++)
|
||||
if(de>dmax) diag("Definition table overflow");
|
||||
}
|
||||
|
||||
char *
|
||||
arg(n) {
|
||||
char *p;
|
||||
p = &gf->ga0;
|
||||
while(--n>=0 && p->word!=0) p =+ p->word;
|
||||
return(p->word!=0?p+2:p);
|
||||
}
|
||||
|
||||
function(n) {
|
||||
if(n==0) ;
|
||||
else if(1<=n && n<=13) binop(n);
|
||||
else {
|
||||
switch(n) {
|
||||
case 20:
|
||||
doif();
|
||||
return;
|
||||
case 21:
|
||||
define();
|
||||
return;
|
||||
case 22:
|
||||
copy();
|
||||
return;
|
||||
case 23:
|
||||
meta();
|
||||
return;
|
||||
case 24:
|
||||
size();
|
||||
return;
|
||||
case 25:
|
||||
substr();
|
||||
return;
|
||||
case 26:
|
||||
case 27:
|
||||
go(n);
|
||||
return;
|
||||
case 28:
|
||||
remove(1);
|
||||
return;
|
||||
case 29:
|
||||
dnl();
|
||||
return;
|
||||
case 32:
|
||||
quote();
|
||||
return;
|
||||
case 33:
|
||||
result(finddef(1)->dswitch);
|
||||
return;
|
||||
case 34:
|
||||
list();
|
||||
return;
|
||||
case 35:
|
||||
traceflag = comp(arg(1),one);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
#
|
||||
|
||||
#include "m6.h"
|
||||
|
||||
|
||||
doif() {
|
||||
int i;
|
||||
int *p;
|
||||
char *arg();
|
||||
i = 1;
|
||||
while(!comp(arg(i),one)) if((i =+ 2)>8) return;
|
||||
p = arg(i+1) - 2;
|
||||
ge = move(p,&gf->ga0,p->word+1);
|
||||
setscan(dummy);
|
||||
}
|
||||
|
||||
bindec(n) {
|
||||
if(n == 0) return;
|
||||
bindec(n/10);
|
||||
*ge++ = (n%10) + '0';
|
||||
}
|
||||
|
||||
result(n) {
|
||||
char *p;
|
||||
setscan(dummy);
|
||||
ge = 2 + (p = &gf->ga0);
|
||||
if(n<0) {
|
||||
*ge++ = '-';
|
||||
n = -n;
|
||||
}
|
||||
if(n==0) *ge++ = '0';
|
||||
else bindec(n);
|
||||
*ge++ = 0;
|
||||
ge = (ge+1)&0177776;
|
||||
p->word = ge - p;
|
||||
*ge++ = *ge++ = 0;
|
||||
}
|
||||
|
||||
binop(code) {
|
||||
int r1,r2;
|
||||
int r,t;
|
||||
int arg1, arg2;
|
||||
arg1 = decbin(1);
|
||||
arg2 = decbin(2);
|
||||
if(code < 7) /* relationals */
|
||||
result((code & ((arg1<arg2)?4:(arg1==arg2)?2:1)) != 0);
|
||||
else if(code < 9) /* seq=7 sne=8 */
|
||||
result((code==7)==comp(arg(1),arg(2)));
|
||||
else switch (code) {
|
||||
case 9:
|
||||
result(arg1+arg2);
|
||||
return;
|
||||
case 10:
|
||||
result(arg1-arg2);
|
||||
return;
|
||||
case 11:
|
||||
result(arg1*arg2);
|
||||
return;
|
||||
case 12:
|
||||
result(arg1/arg2);
|
||||
if(arg2==0) gf->ga0 = 0;
|
||||
return;
|
||||
case 13: /* exp */
|
||||
r = 1;
|
||||
while(arg2-->0) r =* arg1;
|
||||
result(r);
|
||||
if(arg2<-1) gf->ga0 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
decbin(i) {
|
||||
char *s;
|
||||
char t;
|
||||
int n;
|
||||
if(t = (*(s = arg(i))=='-')) s++;
|
||||
n = 0;
|
||||
while(*s>='0' && *s<='9') n = 10*n + *s++ - '0';
|
||||
return(t?-n:n);
|
||||
}
|
||||
|
||||
dnl() {
|
||||
char d;
|
||||
d = 0;
|
||||
while(d=getchar()) if(d=='\n') return;
|
||||
}
|
||||
|
||||
quote() {
|
||||
char *p,*s;
|
||||
p = finddef(1);
|
||||
s = &p[p->dtext];
|
||||
while(c = *s++) put();
|
||||
}
|
||||
|
||||
list() {
|
||||
int n,i;
|
||||
char *p;
|
||||
if((n=decbin(1))<=0) return;
|
||||
p = df;
|
||||
for(i=1;;) {
|
||||
if(p<=d0) return;
|
||||
if(p->dswitch>=0)
|
||||
if(i++>=n) break;
|
||||
p =+ p->prev;
|
||||
}
|
||||
for(p = &p->dident;c = *p++;)
|
||||
put();
|
||||
}
|
||||
|
||||
copy() {
|
||||
char *p;
|
||||
p = finddef(1);
|
||||
remove(2);
|
||||
newdef(p->dswitch);
|
||||
setdef(arg(2),p+p->dtext);
|
||||
}
|
||||
|
||||
go(n) {
|
||||
if(comp(arg(1),one)) {
|
||||
popget();
|
||||
if(lg>0)
|
||||
if(n==26) popget();
|
||||
else setscan(gf->mframe); /* gobk=27 */
|
||||
}
|
||||
}
|
||||
|
||||
size() {
|
||||
int i;
|
||||
char *p;
|
||||
i = 0;
|
||||
p = arg(1);
|
||||
while(*p++ != 0) i++;
|
||||
result(i);
|
||||
}
|
||||
|
||||
meta() {
|
||||
char d;
|
||||
int i;
|
||||
char *arg();
|
||||
if((d = *arg(2))!=0) {
|
||||
for(i=0;i<NMETA;i++)
|
||||
if(metas[i]== *arg(1)) metas[i] = d;
|
||||
}
|
||||
}
|
||||
|
||||
substr() {
|
||||
char *s;
|
||||
int arg2,arg3;
|
||||
char *arg();
|
||||
newdef(-1);
|
||||
setscan(df);
|
||||
s = arg(1);
|
||||
arg2 = decbin(2);
|
||||
arg3 = *arg(3)==0?32767:decbin(3);
|
||||
if(arg2<1) {
|
||||
arg3 =+ arg2-1;
|
||||
arg2=1;
|
||||
}
|
||||
while(--arg2>0 && *s!=0) s++;
|
||||
while(arg3-->0) {
|
||||
if((*de++ = *s++)==0) return;
|
||||
if(de>dmax) diag("No room for substr");
|
||||
}
|
||||
*de++ = 0;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#define PSIZE 1000
|
||||
#define GSIZE 2000
|
||||
#define DSIZE 5000
|
||||
|
||||
int pmax PSIZE;
|
||||
char p0[PSIZE];
|
||||
|
||||
int gmax GSIZE;
|
||||
char g0[GSIZE];
|
||||
|
||||
int dmax DSIZE;
|
||||
char d0[DSIZE] {
|
||||
0,0,
|
||||
8,0, 0,0, 6,0, 0,0, /*null*/
|
||||
12,0, 35,0, 11,0, 't','r','a','c','e',0,
|
||||
12,0, 23,0, 10,0, 'w','a','r','n',0,0,
|
||||
12,0, 22,0, 10,0, 'c','o','p','y',0,0,
|
||||
12,0, 32,0, 11,0, 'q','u','o','t','e',0,
|
||||
14,0, 33,0, 12,0, 's','e','r','i','a','l',0,0,
|
||||
12,0, 34,0, 10,0, 'l','i','s','t',0,0,
|
||||
12,0, 24,0, 10,0, 's','i','z','e',0,0,
|
||||
14,0, 25,0, 12,0, 's','u','b','s','t','r',0,0,
|
||||
10,0, 26,0, 8,0, 'g','o',0,0,
|
||||
12,0, 27,0, 10,0, 'g','o','b','k',0,0,
|
||||
10,0, 28,0, 9,0, 'd','e','l',0,
|
||||
10,0, 29,0, 9,0, 'd','n','l',0,
|
||||
10,0, 7,0, 9,0, 's','e','q',0,
|
||||
10,0, 8,0, 9,0, 's','n','e',0,
|
||||
10,0, 9,0, 9,0, 'a','d','d',0,
|
||||
10,0, 10,0, 9,0, 's','u','b',0,
|
||||
10,0, 11,0, 9,0, 'm','p','y',0,
|
||||
10,0, 12,0, 9,0, 'd','i','v',0,
|
||||
10,0, 13,0, 9,0, 'e','x','p',0,
|
||||
10,0, 1,0, 8,0, 'g','t',0,0,
|
||||
10,0, 2,0, 8,0, 'e','q',0,0,
|
||||
10,0, 3,0, 8,0, 'g','e',0,0,
|
||||
10,0, 4,0, 8,0, 'l','t',0,0,
|
||||
10,0, 5,0, 8,0, 'n','e',0,0,
|
||||
10,0, 6,0, 8,0, 'l', 'e',0,0,
|
||||
10,0, 21,0, 9,0, 'd','e','f',0,
|
||||
10,0, 20,0, 8,0, 'i','f',0,
|
||||
0,0
|
||||
};
|
||||
|
||||
int dummy[] {
|
||||
0,
|
||||
0,
|
||||
6,
|
||||
'$0',
|
||||
0
|
||||
};
|
||||
char metas[] {
|
||||
'<',
|
||||
'>',
|
||||
'#',
|
||||
':',
|
||||
';',
|
||||
',',
|
||||
'$'
|
||||
};
|
||||
|
||||
int rescan 1;
|
||||
int traceflag 0;
|
||||
int trashflag 0;
|
||||
char one[] {
|
||||
'1',0 };
|
||||
@@ -0,0 +1,4 @@
|
||||
cc -s -O m6?.c
|
||||
cmp a.out /usr/bin/m6
|
||||
cp a.out /usr/bin/m6
|
||||
rm a.out *.o
|
||||
Reference in New Issue
Block a user