#include #include "logo.h" int errrec(); int ehand2(); int ehand3(); int leave(); extern int letflag, pflag, argno, yyline, rendflag, currtest; extern int traceflag, *stkbase, stkbi, yychar, endflag, topf; extern int pauselev, errpause, catching, flagquit; /* PAUSE */ extern int turtdes; extern char charib, *getbpt, *ibufptr; extern char titlebuf[]; extern struct lexstruct keywords[]; extern struct stkframe *fbr; extern struct plist *proclist; extern struct object *multarg; extern struct runblock *thisrun; #ifndef YYSTYPE #define YYSTYPE int #endif extern YYSTYPE yylval; int doprep = 0; int *newstk =NULL; int newsti =0; FILE *pbuf =0; struct plist *pcell =NULL; struct alist *locptr =NULL, *newloc =NULL; struct object *allocstk[MAXALLOC] ={0}; int memb(ch,str) register char ch,*str; { register char ch1; while (ch1 = *str++) if (ch == ch1) return(1); return(0); } char *token(str) register char *str; { static char output[20]; register char ch,*op; op = output; while((op < &output[19]) && (ch = *str++) && !memb(ch," \t\"[\r\n:")){ if (ch >= 'A' && ch <= 'Z') ch += 'a'-'A'; *op++ = ch; } *op = '\0'; return(output); } #ifdef DEBUG jfree(block) char *block; { if (memtrace) printf("Jfree loc=0%o\n",block); if (block==0) printf("Trying to jfree zero.\n"); else free(block); } #endif newproc(nameob) struct object *nameob; { register char *name; register struct stkframe *stemp; register struct lincell *ltemp; struct plist *pptr; int linlab; int itemp; char *temp,*tstr; struct object *title; char s[100]; int olp; int oldlet; char olc,c; int pc; extern struct plist *proclook(); name = nameob->obstr; stemp=(struct stkframe *)ckzmalloc(sizeof(*stemp)); stemp->prevframe=fbr; stemp->oldyyc= -2; stemp->oldline= -1; stemp->oldnewstk=newstk; newstk = NULL; stemp->oldnloc=newloc; newloc=NULL; stemp->argtord=argno; stemp->prevpcell=pcell; pcell = NULL; stemp->loclist = NULL; fbr=stemp; doprep++; argno=0; if (pptr=proclook(name)) { mfree(nameob); newstk=pptr->realbase; (pptr->recdepth)++; title=pptr->ptitle; pcell=pptr; } else { onintr(ehand2,&pbuf); cpystr (s,name,EXTEN,NULL); if (!(pbuf=fopen(s,"r"))) { cpystr(s,LOGOLIB,name,EXTEN,NULL); if (!(pbuf = fopen(s,"r"))) { onintr(errrec,1); printf("You haven't told me how to %s.\n",name); errhand(); } } pptr=(struct plist *)ckzmalloc(sizeof(*pptr)); pptr->plines=NULL; pptr->procname=globcopy(nameob); mfree(nameob); temp=s; while ((c=getc(pbuf))!='\n') *temp++=c; *temp++='\n'; *temp='\0'; title=globcopy(objcpstr(s)); pptr->after=proclist; pptr->recdepth=1; pptr->ptitle=title; pptr->before=NULL; if (proclist) proclist->before = pptr; proclist=pptr; pcell=pptr; } tstr = title->obstr; nextarg: while((c= *tstr++)!=':' && c!='\n') ; if (c==':') { temp=s; while ((c= *tstr++)!=' ' && c!='\n') *temp++=c; *temp='\0'; tstr--; loccreate(globcopy(objcpstr(s)),&newloc); argno++; goto nextarg; } if (pptr->recdepth!=1) return; olp=pflag; pflag=1; oldlet=letflag; letflag=0; olc=charib; charib=0; newstk=(int *)ckmalloc(PSTKSIZ*sizeof(int)); *newstk=0; newsti=1; *(newstk+newsti) = -1; /* BH 6/25/82 in case yylex blows up */ itemp = '\n'; while ((pc = yylex()) != -1) { if (pc==1) return; if ((itemp == '\n') && isuint(pc)) { linlab=((struct object *)yylval)->obint; ltemp=(struct lincell *)ckmalloc(sizeof(*ltemp)); ltemp->linenum=linlab; ltemp->base=newstk; ltemp->index=newsti; ltemp->nextline=pptr->plines; pptr->plines=ltemp; } *(newstk+newsti++)=pc; if (newsti==PSTKSIZ-1) newfr(); *(newstk+newsti++)=yylval; if (isstored(pc)) { yylval = (YYSTYPE)globcopy(yylval); mfree(yylval); } if (newsti==PSTKSIZ-1) newfr(); *(newstk+newsti) = -1; itemp = pc; } *(newstk+newsti)= -1; *(newstk+PSTKSIZ-1)=0; pflag=olp; letflag=oldlet; charib=olc; fclose(pbuf); onintr(errrec,1); while (*newstk!=0) newstk= (int *)*newstk; pptr->realbase=newstk; } procprep() { doprep=0; fbr->oldline=yyline; fbr->oldbpt=getbpt; getbpt=0; fbr->loclist=locptr; locptr=newloc; newloc=NULL; fbr->stk=stkbase; stkbase=newstk; newstk=NULL; fbr->ind=stkbi; stkbi=1; newsti=0; argno= -1; fbr->oldpfg = pflag; pflag=2; fbr->iftest = currtest; if (traceflag) intrace(); } frmpop(val) register struct object *val; { struct alist *atemp0,*atemp1,*atemp2; register struct stkframe *ftemp; struct lincell *ltemp,*ltemp2; register i; int *stemp; int stval; if (traceflag) outtrace(val); if (!pcell) goto nopcell; (pcell->recdepth)--; if (pcell->recdepth==0) { lfree(pcell->procname); lfree(pcell->ptitle); if (pcell->before) (pcell->before)->after=pcell->after; else proclist=pcell->after; if (pcell->after) (pcell->after)->before=pcell->before; for(ltemp=pcell->plines;ltemp;ltemp=ltemp2) { ltemp2=ltemp->nextline; JFREE(ltemp); } if ((stemp=stkbase) == 0) goto nostack; while (*stemp!=0) stemp= (int *)*stemp; for (i=1;;i++) { stval= *(stemp+i); if (isstored(stval)) { if (i==PSTKSIZ-2) { stkbase= (int *)*(stemp+PSTKSIZ-1); JFREE(stemp); stemp=stkbase; i=0; } lfree(*(stemp+ (++i))); } else if (stval== -1) { JFREE(stemp); break; } else { if (i==PSTKSIZ-2) { stkbase= (int *)*(stemp+PSTKSIZ-1); JFREE(stemp); stemp=stkbase; i=1; } else i++; } if (i==PSTKSIZ-2) { stkbase= (int *)*(stemp+PSTKSIZ-1); JFREE(stemp); stemp=stkbase; i=0; } } nostack: JFREE(pcell); } nopcell: ftemp=fbr; stkbase=ftemp->stk; stkbi=ftemp->ind; newstk=ftemp->oldnewstk; atemp0=newloc; /* BH 6/20/82 maybe never did procprep */ newloc=ftemp->oldnloc; pflag = fbr->oldpfg; atemp1=locptr; locptr=ftemp->loclist; argno=ftemp->argtord; pcell=ftemp->prevpcell; yychar=ftemp->oldyyc; yylval=ftemp->oldyyl; yyline=ftemp->oldline; getbpt=ftemp->oldbpt; currtest=ftemp->iftest; fbr=ftemp->prevframe; JFREE(ftemp); while (atemp1) { atemp2=atemp1->next; if (atemp1->name) lfree(atemp1->name); if (atemp1->val!=(struct object *)-1) /* BH 2/28/80 was NULL instead of -1 */ lfree(atemp1->val); JFREE(atemp1); atemp1=atemp2; } while (atemp0) { atemp2=atemp0->next; if (atemp0->name) lfree(atemp0->name); if (atemp0->val!=(struct object *)-1) lfree(atemp0->val); JFREE(atemp0); atemp0=atemp2; } } proccreate(nameob) register struct object *nameob; { register char *name; char temp[16]; register FILDES edfd; int pid; if (turtdes<0) textscreen(); name = token(nameob->obstr); if (strlen(name)>NAMELEN) { pf1("Procedure name must be no more than %d letters.",NAMELEN); errhand(); } cpystr(temp,name,EXTEN,NULL); if ((edfd=open(temp,READ,0))>=0) { close(edfd); nputs(name); puts(" is already defined."); errhand(); } if ((edfd = creat(temp,0666)) < 0) { printf("Can't write %s.\n",name); errhand(); } onintr(ehand3,edfd); mfree(nameob); write(edfd,titlebuf,strlen(titlebuf)); addlines(edfd); onintr(errrec,1); } help() { FILE *sbuf; sbuf=fopen("/usr/local/doc/logo/helpfile","r"); if (sbuf == NULL) { printf("? Help file missing, sorry.\n"); return; } onintr(ehand2,sbuf); while(putch(getc(sbuf))!=EOF) ; fclose(sbuf); onintr(errrec,1); } struct object *describe(arg) struct object *arg; { register char *argstr; register struct lexstruct *lexp; FILE *sbuf; char fname[30]; if (!stringp(arg)) ungood("Describe",arg); argstr = token(arg->obstr); for (lexp = keywords; lexp->word; lexp++) if (!strcmp(argstr,lexp->word) || !strcmp(argstr,lexp->abbr)) break; if (!lexp->word) { pf1("%p isn't a primitive.\n",arg); errhand(); } if (strlen(lexp->word) > 9) /* kludge for Eunice */ cpystr(fname,"/usr/local/doc/logo/",lexp->abbr,NULL); else cpystr(fname,"/usr/local/doc/logo/",lexp->word,NULL); if (!(sbuf=fopen(fname,"r"))) { printf("Sorry, I have no information about %s\n",lexp->word); errhand(); } else { onintr(ehand2,sbuf); while (putch(getc(sbuf))!=EOF) ; fclose(sbuf); } onintr(errrec,1); mfree(arg); return ((struct object *)(-1)); } errwhere() { register i =0; register struct object **astk; register struct plist *opc; cboff(); /* BH 12/13/81 */ ibufptr=NULL; if (doprep) { procprep(); frmpop(-1); } for (astk=allocstk;istr != (struct object *)(-1))) unrun(); */ if (!pflag && !getbpt) charib=0; dopause(); } else { opc = pcell; if (fbr && fbr->oldline==-1) { opc=fbr->prevpcell; } if (opc&&!topf) printf("You were at line %d in procedure %s\n", yyline,opc->procname->obstr); } } errzap() { while (thisrun) unrun(); while (fbr) frmpop(-1); charib=0; if(traceflag)traceflag=1; topf=0; yyline=0; letflag=0; pflag=0; endflag=0; rendflag=0; argno= -1; newstk=NULL; newsti=0; stkbase=NULL; stkbi=0; fbr=NULL; locptr=NULL; newloc=NULL; proclist=NULL; pcell=NULL; pauselev = 0; /* PAUSE */ } errrec() { /* Here on SIGQUIT */ if (catching) errhand(); flagquit++; /* We'll catch this later */ } ehand2(fle) register FILE *fle; { fclose(fle); errhand(); } ehand3(fle) register FILDES fle; { close(fle); errhand(); } intrace() { register struct alist *aptr; if (!pcell) return; indent(traceflag-1); nputs(pcell->procname->obstr); if (locptr && (locptr->val != (struct object *)-1)) { pf1(" of %l",locptr->val); /* BH locptr->val was inval */ for (aptr=locptr->next;aptr;aptr=aptr->next) { if (aptr->val == (struct object *)-1) break; pf1(" and %l",aptr->val); /* was inval */ } putchar('\n'); } else puts(" called."); traceflag++; } outtrace(retval) register struct object *retval; { if (!pcell) return; if (traceflag>1) traceflag--; indent(traceflag-1); nputs(pcell->procname->obstr); if (retval != (struct object *)-1) pf1(" outputs %l\n",retval); else puts(" stops."); } indent(no) register int no; { while (no--)putchar(' '); }