ack/lang/basic/src/graph.c
2006-02-04 00:57:05 +00:00

341 lines
5.4 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[] = "$Id$" ;
#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))
{
fprint(STDERR, "ERROR: line %d not defined\n",l->linenr);
errorcnt++;
}
l=l->nextlist;
}
}
newblock(nr)
int nr;
{
Linerecord *l;
List *frwrd;
if ( debug) print("newblock at %d\n",nr);
if ( nr>0 && currline && currline->linenr>= nr)
{
if ( debug) print("old line:%d\n",currline->linenr);
error("Lines out of sequence");
}
frwrd=srchforward(nr);
if ( frwrd && debug) print("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;
/* 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) print("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) print("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;
{
C_bra((label) 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);
/*return index */
C_loc((arith) n);
/* administer legal return */
C_cal("_gosub");
C_asp((arith) BEMINTSIZE);
C_bra((label) nr);
C_df_ilb((label)l->emlabel);
}
genreturns()
{
int nr;
nr= genlabel();
C_df_dnam("returns");
C_rom_ilb((label) nr);
C_rom_cst((arith)1);
C_rom_cst((arith) (gosubcnt-1));
while ( gosubhead)
{
C_rom_ilb((label) gosubhead->emlabel);
gosubhead= gosubhead->nextlist;
}
C_df_ilb((label) nr);
C_loc((arith) 1);
C_cal("error");
}
returnstmt()
{
C_cal("_retstmt");
C_lfr((arith) BEMINTSIZE);
C_lae_dnam("returns",(arith)0);
C_csa((arith) BEMINTSIZE);
}
/* 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();
C_df_dlb((label)descr);
C_rom_ilb((label)firstlabel);
C_rom_cst((arith) 1);
C_rom_cst((arith)(jumpcnt-1));
l= jumphead;
while (l)
{
C_rom_ilb((label)l->emlabel);
l= l->nextlist;
}
jumphead= jumptail=0; jumpcnt=0;
if (debug) print("ongotst:%d labels\n", jumpcnt);
conversion(type,INTTYPE);
C_dup((arith) BEMINTSIZE);
C_zlt(err_goto_label);
C_lae_dlb((label) descr,(arith) 0);
C_csa((arith) BEMINTSIZE);
C_df_ilb((label)firstlabel);
}
ongosubstmt(type)
int type;
{
List *l;
int firstlabel;
int descr;
/* create descriptor first */
descr= genlabel();
firstlabel=genlabel();
C_df_dlb((label)descr);
C_rom_ilb((label)firstlabel);
C_rom_cst((arith)1);
C_rom_cst((arith)(jumpcnt-1));
l= jumphead;
while (l)
{
C_rom_ilb((label)l->emlabel);
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 */
C_loc((arith) gosubcnt);
C_cal("_gosub");
C_asp((arith) BEMINTSIZE);
gosubcnt++;
/* generate gosub */
conversion(type,INTTYPE);
C_dup((arith) BEMINTSIZE);
C_zlt(err_goto_label);
C_lae_dlb((label) descr,(arith) 0);
C_csa((arith) BEMINTSIZE);
C_df_ilb((label)firstlabel);
}
/* REGION ANALYSIS and FINAL VERSION GENERATION */