ack/lang/basic/src.old/graph.c
1987-03-09 15:15:03 +00:00

299 lines
5.8 KiB
C

/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#include "bem.h"
#ifndef NORSCID
static char rcs_id[] = "$Header$" ;
#endif
List *forwardlabel=0;
Linerecord *firstline,
*currline,
*lastline;
List *newlist()
{
List *l;
/*NOSTRICT*/ l= (List *) salloc(sizeof(List));
return(l);
}
/* Line management is handled here */
Linerecord *srchline(nr)
int nr;
{
Linerecord *l;
for(l=firstline;l && l->linenr<=nr;l= l->nextline)
if( l->linenr== nr) return(l);
return(0);
}
List *srchforward(nr)
int nr;
{
List *l;
for(l=forwardlabel;l ;l=l->nextlist)
if( l->linenr== nr) return(l);
return(0);
}
linewarnings()
{
List *l;
extern int errorcnt;
l= forwardlabel;
while(l)
{
if( !srchline(l->linenr))
{
fprintf(stderr,"ERROR: line %d not defined\n",l->linenr);
errorcnt++;
}
l=l->nextlist;
}
}
newblock(nr)
int nr;
{
Linerecord *l;
List *frwrd;
if( debug) printf("newblock at %d\n",nr);
if( nr>0 && currline && currline->linenr>= nr)
{
if( debug) printf("old line:%d\n",currline->linenr);
error("Lines out of sequence");
}
frwrd=srchforward(nr);
if( frwrd && debug) printf("forward found %d\n",frwrd->emlabel);
l= srchline(nr);
if( l)
{
error("Line redefined");
nr= -genlabel();
}
/* make new EM block structure */
/*NOSTRICT*/ l= (Linerecord *) salloc(sizeof(*l));
l->emlabel= frwrd? frwrd->emlabel: genlabel();
l->linenr= nr;
/* save offset into Tmpfile too */
l->offset = (long) ftell(Tmpfile);
l->codelines= emlinecount;
/* insert this record */
if( firstline)
{
currline->nextline=l;
l->prevline= currline;
lastline= currline=l;
} else
firstline = lastline =currline=l;
}
gotolabel(nr)
int nr;
{
/* simulate a goto statement in the line record table */
Linerecord *l1;
List *ll;
if(debug) printf("goto label %d\n",nr);
/* update currline */
ll= newlist();
ll-> linenr=nr;
ll-> nextlist= currline->gotos;
currline->gotos= ll;
/* try to generate code */
l1= srchline(nr);
if( (ll=srchforward(nr))!=0)
nr= ll->emlabel;
else
if( l1==0)
{
/* declare forward label */
if(debug) printf("declare forward %d\n",nr);
ll= newlist();
ll->emlabel= genlabel();
ll-> linenr=nr;
ll->nextlist= forwardlabel;
forwardlabel= ll;
nr= ll->emlabel;
} else
nr= l1->emlabel;
return(nr);
}
gotostmt(nr)
int nr;
{
emcode("bra",instrlabel(gotolabel(nr)));
}
/* GOSUB-return, assume that proper entries are made to subroutines
only. The return statement is triggered by a fake constant label */
List *gosubhead, *gotail;
int gosubcnt=1;
List *gosublabel()
{
List *l;
l= newlist();
l->nextlist=0;
l->emlabel=genlabel();
if( gotail){
gotail->nextlist=l;
gotail=l;
} else gotail= gosubhead=l;
gosubcnt++;
return(l);
}
gosubstmt(lab)
int lab;
{
List *l;
int nr,n;
n=gosubcnt;
l= gosublabel();
nr=gotolabel(lab);
emcode("loc",itoa(n)); /*return index */
emcode("cal","$_gosub"); /* administer legal return */
emcode("asp",EMINTSIZE);
emcode("bra",instrlabel(nr));
fprintf(Tmpfile,"%d\n",l->emlabel);
emlinecount++;
}
genreturns()
{
int nr;
nr= genlabel();
fprintf(emfile,"returns\n");
fprintf(emfile," rom *%d,1,%d\n",nr,gosubcnt-1);
while( gosubhead)
{
fprintf(emfile," rom *%d\n",gosubhead->emlabel);
gosubhead= gosubhead->nextlist;
}
fprintf(emfile,"%d\n",nr);
fprintf(emfile," loc 1\n");
fprintf(emfile," cal $error\n");
}
returnstmt()
{
emcode("cal","$_retstmt"); /* ensure legal return*/
emcode("lfr",EMINTSIZE);
fprintf(Tmpfile," lae returns\n");
emlinecount++;
emcode("csa",EMINTSIZE);
}
/* compound goto-gosub statements */
List *jumphead,*jumptail;
int jumpcnt;
jumpelm(nr)
int nr;
{
List *l;
l= newlist();
l->emlabel= gotolabel(nr);
l->nextlist=0;
if( jumphead==0) jumphead= jumptail= l;
else {
jumptail->nextlist=l;
jumptail=l;
}
jumpcnt++;
}
ongotostmt(type)
int type;
{
/* generate the code itself, index in on top of the stack */
/* blurh, store the number of entries in the descriptor */
int firstlabel;
int descr;
List *l;
/* create descriptor first */
descr= genlabel();
firstlabel=genlabel();
fprintf(Tmpfile,"l%d\n",descr); emlinecount++;
fprintf(Tmpfile," rom *%d,1,%d\n",firstlabel,jumpcnt-1); emlinecount++;
l= jumphead;
while( l)
{
fprintf(Tmpfile," rom *%d\n",l->emlabel); emlinecount++;
l= l->nextlist;
}
jumphead= jumptail=0; jumpcnt=0;
if(debug) printf("ongotst:%d labels\n", jumpcnt);
conversion(type,INTTYPE);
emcode("lae",datalabel(descr));
emcode("csa",EMINTSIZE);
fprintf(Tmpfile,"%d\n",firstlabel); emlinecount++;
}
ongosubstmt(type)
int type;
{
List *l;
int firstlabel;
int descr;
/* create descriptor first */
descr= genlabel();
firstlabel=genlabel();
fprintf(Tmpfile,"l%d\n",descr); emlinecount++;
fprintf(Tmpfile," rom *%d,1,%d\n",firstlabel,jumpcnt-1); emlinecount++;
l= jumphead;
while( l)
{
fprintf(Tmpfile," rom *%d\n",l->emlabel); emlinecount++;
l= l->nextlist;
}
jumphead= jumptail=0; jumpcnt=0;
l= newlist();
l->nextlist=0;
l->emlabel=firstlabel;
if( gotail){
gotail->nextlist=l;
gotail=l;
} else gotail= gosubhead=l;
/* save the return point of the gosub */
emcode("loc",itoa(gosubcnt));
emcode("cal","$_gosub");
emcode("asp",EMINTSIZE);
gosubcnt++;
/* generate gosub */
conversion(type,INTTYPE);
emcode("lae",datalabel(descr));
emcode("csa",EMINTSIZE);
fprintf(Tmpfile,"%d\n",firstlabel);
emlinecount++;
}
/* REGION ANALYSIS and FINAL VERSION GENERATION */
simpleprogram()
{
char buf[512];
int length;
/* a small EM programs has been found */
prologcode();
prolog2();
(void) fclose(Tmpfile);
Tmpfile= fopen(tmpfname,"r");
if( Tmpfile==NULL)
fatal("tmp file disappeared");
while( (length=fread(buf,1,512,Tmpfile)) != 0)
(void) fwrite(buf,1,length,emfile);
epilogcode();
(void) unlink(tmpfname);
}