1987-01-15 18:12:26 +00:00
|
|
|
#ifndef NORCSID
|
1987-07-07 16:31:16 +00:00
|
|
|
static char rcsidp5[] = "$Header$";
|
1987-01-15 18:12:26 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "parser.h"
|
|
|
|
#include "Lpars.h"
|
|
|
|
|
1987-07-07 16:31:16 +00:00
|
|
|
FILE *ofile;
|
1987-01-15 18:12:26 +00:00
|
|
|
|
|
|
|
outputnopt()
|
|
|
|
{
|
1987-07-09 09:02:41 +00:00
|
|
|
openofile("dfa.c");
|
1987-01-27 14:15:23 +00:00
|
|
|
outdfa();
|
1987-07-09 09:02:41 +00:00
|
|
|
installofile();
|
|
|
|
openofile("trans.c");
|
1987-01-27 14:15:23 +00:00
|
|
|
outdotrans();
|
1987-07-09 09:02:41 +00:00
|
|
|
installofile();
|
|
|
|
openofile("incalls.r");
|
1987-01-15 18:12:26 +00:00
|
|
|
outputincalls();
|
1987-07-09 09:02:41 +00:00
|
|
|
installofile();
|
|
|
|
}
|
|
|
|
|
|
|
|
static char ofilename[80];
|
|
|
|
static char ofiletemp[80];
|
|
|
|
|
|
|
|
PRIVATE
|
|
|
|
openofile(filename)
|
|
|
|
char *filename;
|
|
|
|
{
|
1987-07-09 15:04:03 +00:00
|
|
|
char *strcpy(), *strcat();
|
1987-07-09 09:02:41 +00:00
|
|
|
strcpy(ofilename,filename);
|
|
|
|
strcpy(ofiletemp,filename);
|
|
|
|
strcat(ofiletemp,".new");
|
|
|
|
if((ofile=fopen(ofiletemp,"w"))==NULL) {
|
|
|
|
fprintf(stderr,"Fatal Error: cannot open output file %s\n",ofiletemp);
|
|
|
|
sys_stop(S_EXIT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE
|
|
|
|
installofile()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* if contents of newly generated ofiletemp is different
|
|
|
|
* from that of ofilename then copy over old file else
|
|
|
|
* delete newly generated file
|
|
|
|
*/
|
|
|
|
register FILE *f1, *f2;
|
|
|
|
register int c1, c2;
|
|
|
|
fclose(ofile);
|
|
|
|
if((f1 = fopen(ofiletemp,"r")) == NULL) {
|
|
|
|
fprintf(stderr,"Fatal Error: cannont reopen file %s\n",ofiletemp);
|
|
|
|
sys_stop(S_EXIT);
|
|
|
|
}
|
|
|
|
if((f2 = fopen(ofilename,"r")) == NULL) {
|
|
|
|
fclose(f1);
|
|
|
|
RENAME(ofiletemp,ofilename);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
do {
|
|
|
|
c1 = getc(f1);
|
|
|
|
c2 = getc(f2);
|
|
|
|
} while (c1 == c2 && c1 != EOF);
|
|
|
|
fclose(f1);
|
|
|
|
fclose(f2);
|
|
|
|
if (c1 != c2) {
|
|
|
|
RENAME(ofiletemp,ofilename);
|
|
|
|
}
|
|
|
|
else UNLINK(ofiletemp);
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE
|
|
|
|
UNLINK(x)
|
|
|
|
char *x;
|
|
|
|
{
|
|
|
|
/* Must remove the file "x" */
|
|
|
|
unlink(x); /* systemcall to remove file */
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE
|
|
|
|
RENAME(x,y)
|
|
|
|
char *x, *y;
|
|
|
|
{
|
|
|
|
/* Must move the file "x" to the file "y" */
|
|
|
|
unlink(y);
|
|
|
|
if(link(x,y)!=0) {
|
|
|
|
fprintf(stderr,"Cannot link to %s",y);
|
|
|
|
sys_stop(S_EXIT);
|
|
|
|
}
|
|
|
|
unlink(x);
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
|
|
|
|
1987-07-28 09:37:09 +00:00
|
|
|
# define MAXOPCODE 255
|
|
|
|
# define EMPTY -1
|
|
|
|
|
|
|
|
int *next, *check, *base;
|
|
|
|
unsigned currsize; /* current size of next and check arrays */
|
|
|
|
int maxpos = 0; /* highest used position in these arrayes */
|
|
|
|
|
|
|
|
PRIVATE
|
|
|
|
increase_next(size)
|
|
|
|
int size;
|
|
|
|
{
|
|
|
|
/* realloc arrays next and check so they are at least
|
|
|
|
* of size 'size'
|
|
|
|
*/
|
|
|
|
char *Realloc();
|
|
|
|
unsigned newsize = currsize;
|
|
|
|
register int i;
|
|
|
|
do {
|
|
|
|
newsize *= 2;
|
|
|
|
} while (newsize<size);
|
1987-07-28 11:22:59 +00:00
|
|
|
printf("Note: Extending next/check arrays from %d to %d\n",currsize,newsize);
|
1987-07-28 09:37:09 +00:00
|
|
|
next = (int *)Realloc(next,newsize);
|
|
|
|
check = (int *)Realloc(check,newsize);
|
|
|
|
/* clear ends of new arrays */
|
|
|
|
for(i=currsize;i<newsize;i++)
|
|
|
|
next[i] = check[i] = EMPTY;
|
|
|
|
currsize = newsize;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE
|
|
|
|
store_row(state,row)
|
|
|
|
int state;
|
|
|
|
register int *row;
|
|
|
|
{
|
|
|
|
/* find a place to store row in arrays */
|
|
|
|
register b,i,o;
|
|
|
|
register int *n = next;
|
|
|
|
b=0;
|
|
|
|
for(;;) {
|
|
|
|
/* look for first possible place to store it */
|
|
|
|
for(i=0;i<MAXOPCODE;i++) {
|
|
|
|
if(row[i]) {
|
|
|
|
if((o = b+i)>currsize) increase_next(o);
|
|
|
|
if(n[o]!=EMPTY) goto nextpos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* found a place */
|
|
|
|
base[state]=b;
|
|
|
|
for(i=0;i<MAXOPCODE;i++)
|
|
|
|
if(row[i]) {
|
|
|
|
if((o=b+i) >maxpos) maxpos = o;
|
|
|
|
next[o] = row[i];
|
|
|
|
check[o] = state;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
nextpos:
|
|
|
|
++b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1987-01-15 18:12:26 +00:00
|
|
|
PRIVATE
|
1987-01-27 14:15:23 +00:00
|
|
|
outdfa()
|
1987-01-15 18:12:26 +00:00
|
|
|
{
|
1987-07-28 09:37:09 +00:00
|
|
|
register int s,i;
|
|
|
|
register struct state *p;
|
1987-07-13 15:03:27 +00:00
|
|
|
int nout, ncpy, ngto;
|
1987-07-28 09:37:09 +00:00
|
|
|
int row[MAXOPCODE];
|
|
|
|
int numinrow;
|
|
|
|
int numentries = 0;
|
|
|
|
|
1987-07-13 15:03:27 +00:00
|
|
|
fprintf(ofile,"#include \"nopt.h\"\n");
|
|
|
|
fprintf(ofile,"\n");
|
1987-07-21 13:23:09 +00:00
|
|
|
fprintf(ofile,"int OO_maxreplacement = %d;\n", maxreplacement);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"\n");
|
1987-07-28 09:37:09 +00:00
|
|
|
|
|
|
|
/* find how many entries in dfa */
|
|
|
|
for(s=0;s<=higheststate;s++)
|
|
|
|
for(p=states[s];p!=(struct state *)NULL;p=p->next)
|
|
|
|
numentries++;
|
|
|
|
/* start with next and check arrays twice this size */
|
|
|
|
currsize = 2 * numentries;
|
|
|
|
next = (int *)Malloc(currsize*sizeof(int));
|
|
|
|
check = (int *)Malloc(currsize*sizeof(int));
|
|
|
|
base = (int *)Malloc(((unsigned)(higheststate+1))*sizeof(int));
|
|
|
|
/* fill next array with EMPTY */
|
|
|
|
for(i=0;i<currsize;i++) check[i]=next[i]=EMPTY;
|
1987-07-13 15:03:27 +00:00
|
|
|
for(s=0;s<=higheststate;s++) {
|
1987-07-28 09:37:09 +00:00
|
|
|
/* empty row */
|
|
|
|
for(i=0;i<MAXOPCODE;i++) row[i]=0;
|
|
|
|
numinrow = 0;
|
|
|
|
/* fill in non zero entries */
|
|
|
|
for(p=states[s];p!=(struct state *)NULL;p=p->next) {
|
|
|
|
numinrow++;
|
|
|
|
row[p->op->id_opcode] = p->goto_state;
|
|
|
|
}
|
|
|
|
/* look for a place to store row */
|
|
|
|
if(numinrow)
|
|
|
|
store_row(s,row);
|
|
|
|
else
|
|
|
|
base[s] = EMPTY;
|
|
|
|
}
|
1987-07-28 11:22:59 +00:00
|
|
|
/* give some statistics on size of dfa */
|
|
|
|
printf("Number of patterns: %d\n", numpatterns);
|
|
|
|
printf("Longest pattern: %d\n", maxpattern);
|
|
|
|
printf("Longest replacement: %d\n", maxreplacement);
|
1987-07-29 16:10:27 +00:00
|
|
|
printf("Dfa contains %d states and %d distinct state/opcode pairs\n",
|
|
|
|
higheststate+1,numentries);
|
1987-07-28 11:22:59 +00:00
|
|
|
printf("Compacted using row displacement into %d entries\n",maxpos);
|
1987-07-28 09:37:09 +00:00
|
|
|
/* output the arrays */
|
|
|
|
fprintf(ofile,"struct dfa OO_checknext[] = {\n");
|
|
|
|
for(i=0;i<=maxpos;i++) {
|
|
|
|
fprintf(ofile,"\t/* %4d */\t",i);
|
|
|
|
fprintf(ofile,"{%4d,%4d},\n", check[i], next[i]);
|
1987-07-13 15:03:27 +00:00
|
|
|
}
|
1987-07-28 09:37:09 +00:00
|
|
|
fprintf(ofile,"};\n\n");
|
|
|
|
fprintf(ofile,"struct dfa *OO_base[] = {\n");
|
1987-07-13 15:03:27 +00:00
|
|
|
for(s=0;s<=higheststate;s++) {
|
1987-07-28 09:37:09 +00:00
|
|
|
fprintf(ofile,"\t/* %4d: ",s);
|
|
|
|
outmnems(patterns[s]);
|
|
|
|
fprintf(ofile,"*/\t");
|
|
|
|
if(base[s]==EMPTY)
|
|
|
|
fprintf(ofile,"0,\n");
|
|
|
|
else
|
|
|
|
fprintf(ofile,"&OO_checknext[%4d],\n", base[s]);
|
1987-07-13 15:03:27 +00:00
|
|
|
}
|
|
|
|
fprintf(ofile,"};\n\n");
|
1987-07-28 09:37:09 +00:00
|
|
|
fprintf(ofile,"struct dodefault OO_default[] = {\n");
|
1987-07-13 15:03:27 +00:00
|
|
|
for(s=0;s<=higheststate;s++) {
|
1987-07-28 09:37:09 +00:00
|
|
|
fprintf(ofile,"\t/* %4d: ",s);
|
1987-07-21 13:23:09 +00:00
|
|
|
outmnems(patterns[s]);
|
1987-07-28 09:37:09 +00:00
|
|
|
fprintf(ofile,"*/\t");
|
|
|
|
findfail(s,&nout,&ncpy,&ngto);
|
|
|
|
fprintf(ofile,"{%4d,%4d},\n", nout,ngto);
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
1987-07-28 09:37:09 +00:00
|
|
|
fprintf(ofile,"};\n\n");
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE
|
1987-01-27 14:15:23 +00:00
|
|
|
outmnems(l)
|
1987-01-15 18:12:26 +00:00
|
|
|
struct mnems l;
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i=1;i<=l.m_len;i++)
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"%s ",l.m_elems[i-1]->op_code->id_text);
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
|
|
|
|
1987-07-29 16:10:27 +00:00
|
|
|
PRIVATE int
|
|
|
|
sametest(s1,s2,e1,e2)
|
|
|
|
int s1,s2;
|
|
|
|
struct exp_node *e1,*e2;
|
|
|
|
{
|
1989-02-02 11:41:31 +00:00
|
|
|
/* return 1 if tests are identical */
|
1987-07-29 16:10:27 +00:00
|
|
|
if(e1) {
|
|
|
|
if(!e2) return 0;
|
|
|
|
if(e1->node_type!=e2->node_type) return 0;
|
|
|
|
switch(e1->node_type) {
|
|
|
|
case LOGAND:
|
|
|
|
case LOGOR:
|
|
|
|
case BITAND:
|
|
|
|
case BITOR:
|
|
|
|
case XOR:
|
|
|
|
case MINUS:
|
|
|
|
case PLUS:
|
|
|
|
case TIMES:
|
|
|
|
case DIV:
|
|
|
|
case MOD:
|
|
|
|
case EQ:
|
|
|
|
case NE:
|
|
|
|
case LT:
|
|
|
|
case LE:
|
|
|
|
case GT:
|
|
|
|
case GE:
|
|
|
|
case LSHIFT:
|
|
|
|
case RSHIFT:
|
|
|
|
case COMMA:
|
|
|
|
case SAMESIGN:
|
|
|
|
case SFIT:
|
|
|
|
case UFIT:
|
|
|
|
case ROTATE:
|
|
|
|
case SAMEEXT:
|
|
|
|
case SAMENAM:
|
1989-10-06 14:53:49 +00:00
|
|
|
return (sametest(s1,s2,e1->exp_left,e2->exp_left) &&
|
|
|
|
sametest(s1,s2,e1->exp_right,e2->exp_right));
|
1987-07-29 16:10:27 +00:00
|
|
|
case NOT:
|
|
|
|
case COMP:
|
|
|
|
case UPLUS:
|
|
|
|
case UMINUS:
|
1989-10-06 14:53:49 +00:00
|
|
|
return sametest(s1,s2,e1->exp_left,e2->exp_left);
|
1987-07-29 16:10:27 +00:00
|
|
|
case DEFINED:
|
|
|
|
case UNDEFINED:
|
|
|
|
case INT:
|
|
|
|
return (e1->leaf_val == e2->leaf_val);
|
|
|
|
case PATARG:
|
|
|
|
/* depends on pattern !! */
|
|
|
|
if (e1->leaf_val != e2->leaf_val) return 0;
|
|
|
|
return (patterns[s1].m_elems[e1->leaf_val-1]->
|
|
|
|
op_code->id_argfmt
|
1989-02-02 11:41:31 +00:00
|
|
|
== patterns[s2].m_elems[e2->leaf_val-1]->
|
1987-07-29 16:10:27 +00:00
|
|
|
op_code->id_argfmt);
|
|
|
|
case PSIZE:
|
|
|
|
case WSIZE:
|
1989-02-02 11:41:31 +00:00
|
|
|
case DWSIZE:
|
1987-07-29 16:10:27 +00:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
1989-02-02 11:41:31 +00:00
|
|
|
/*NOTREACHED*/
|
1987-07-29 16:10:27 +00:00
|
|
|
}
|
|
|
|
else return (e2==0);
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE int
|
|
|
|
samerepl(s1,s2,r1,r2)
|
|
|
|
int s1,s2;
|
|
|
|
struct mnems r1,r2;
|
|
|
|
{
|
|
|
|
/* return 1 if replacements are identical */
|
|
|
|
register int i;
|
|
|
|
register struct mnem_elem *m1,*m2;
|
|
|
|
if (r1.m_len != r2.m_len) return 0; /* different length */
|
|
|
|
for(i=0;i<r1.m_len;i++) {
|
|
|
|
m1=r1.m_elems[i];
|
|
|
|
m2=r2.m_elems[i];
|
|
|
|
if(m1->op_code!=m2->op_code) return 0;
|
|
|
|
if(!sametest(s1,s2,m1->arg,m2->arg)) return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE int
|
|
|
|
samecode(s1,s2)
|
|
|
|
int s1,s2;
|
|
|
|
{
|
|
|
|
/* return 1 if replacement code of state s1 and s2 are identical */
|
|
|
|
register struct action *a1,*a2;
|
|
|
|
if (patterns[s1].m_len != patterns[s2].m_len) return 0;
|
|
|
|
a1 = actions[s1];
|
|
|
|
a2 = actions[s2];
|
|
|
|
while(a1) {
|
|
|
|
if(!a2) return 0; /* a2 is shorter */
|
|
|
|
if(!samerepl(s1,s2,a1->replacement,a2->replacement)) return 0;
|
|
|
|
if(!sametest(s1,s2,a1->test,a2->test)) return 0;
|
|
|
|
a1 = a1->next;
|
|
|
|
a2 = a2->next;
|
|
|
|
}
|
|
|
|
if(a2) return 0; /* a2 is longer */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
1987-01-15 18:12:26 +00:00
|
|
|
PRIVATE
|
1987-01-27 14:15:23 +00:00
|
|
|
outdotrans()
|
1987-01-15 18:12:26 +00:00
|
|
|
{
|
1987-07-29 16:10:27 +00:00
|
|
|
register int s,t;
|
1987-01-15 18:12:26 +00:00
|
|
|
struct action *a;
|
|
|
|
int seennontested;
|
1987-07-29 16:10:27 +00:00
|
|
|
int *farray;
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"#include \"nopt.h\"\n\n");
|
1987-07-29 16:10:27 +00:00
|
|
|
/* keep track of which procedure used for each state */
|
|
|
|
farray = (int *)Malloc((unsigned)(higheststate+1)*sizeof(int));
|
|
|
|
for(s=0;s<=higheststate;s++) farray[s] = EMPTY;
|
|
|
|
/* output the functions avoiding duplicates */
|
1987-07-09 09:02:41 +00:00
|
|
|
for(s=0;s<=higheststate;s++) {
|
1987-01-15 18:12:26 +00:00
|
|
|
if(actions[s]!=(struct action *)NULL) {
|
1987-07-29 16:10:27 +00:00
|
|
|
/* first look for a previous identical function */
|
|
|
|
for(t=0;t<s;t++) {
|
|
|
|
if(actions[t]!=(struct action *)NULL &&
|
|
|
|
samecode(s,t)) {
|
|
|
|
/* use state 't' instead */
|
|
|
|
farray[s]=t;
|
|
|
|
goto next_func;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* no identical function so make new one */
|
|
|
|
farray[s] = s;
|
1987-07-28 09:37:09 +00:00
|
|
|
fprintf(ofile,"\nstatic do%dtrans() {\n",s);
|
1987-07-21 13:23:09 +00:00
|
|
|
fprintf(ofile,"\tregister p_instr patt = OO_patternqueue;\n");
|
1987-07-09 09:02:41 +00:00
|
|
|
fprintf(ofile,"\t/* ");
|
1987-01-27 14:15:23 +00:00
|
|
|
outmnems(patterns[s]);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile," */\n");
|
1987-07-21 13:23:09 +00:00
|
|
|
seennontested=0;
|
1987-01-15 18:12:26 +00:00
|
|
|
for(a=actions[s];a!=(struct action *)NULL;a=a->next) {
|
|
|
|
if(a->test!=(struct exp_node *)NULL) {
|
1987-07-09 09:02:41 +00:00
|
|
|
fprintf(ofile,"\tif(");
|
1987-01-27 14:15:23 +00:00
|
|
|
outexp(a->test,s);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,") {\n");
|
1987-01-27 14:15:23 +00:00
|
|
|
outoneaction(s,a);
|
1987-07-21 13:23:09 +00:00
|
|
|
fprintf(ofile,"\t\treturn;\n");
|
|
|
|
fprintf(ofile,"\t}\n");
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(seennontested) {
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(stderr,"parser: more than one untested action on state %d\n",s);
|
1987-01-15 18:12:26 +00:00
|
|
|
nerrors++;
|
|
|
|
}
|
|
|
|
seennontested++;
|
1987-01-27 14:15:23 +00:00
|
|
|
outoneaction(s,a);
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
|
|
|
}
|
1987-07-09 09:02:41 +00:00
|
|
|
fprintf(ofile,"}\n");
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
1987-07-29 16:10:27 +00:00
|
|
|
next_func:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* output the array itself */
|
|
|
|
fprintf(ofile,"\n\nint (*OO_ftrans[])()=\n{\n");
|
|
|
|
for(s=0;s<=higheststate;s++) {
|
|
|
|
if(farray[s]!=EMPTY)
|
|
|
|
fprintf(ofile,"\tdo%dtrans,\n",farray[s]);
|
|
|
|
else
|
|
|
|
fprintf(ofile,"\t0,\n");
|
1987-07-09 09:02:41 +00:00
|
|
|
}
|
1987-07-29 16:10:27 +00:00
|
|
|
fprintf(ofile,"};\n");
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE
|
1987-01-27 14:15:23 +00:00
|
|
|
outoneaction(s,a)
|
1987-01-15 18:12:26 +00:00
|
|
|
int s;
|
|
|
|
struct action *a;
|
|
|
|
{
|
1987-07-09 09:02:41 +00:00
|
|
|
fprintf(ofile,"\t\t/* -> ");
|
1987-01-27 14:15:23 +00:00
|
|
|
outmnems(a->replacement);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile," */\n");
|
|
|
|
fprintf(ofile,"#ifdef STATS\n");
|
1987-07-09 09:02:41 +00:00
|
|
|
fprintf(ofile,"\t\tif(OO_wrstats) fprintf(stderr,\"%d\\n\");\n",a->linenum);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"#endif\n");
|
1987-07-09 15:04:03 +00:00
|
|
|
outrepl(s,a->replacement);
|
1987-07-28 09:37:09 +00:00
|
|
|
findworst(patterns[s],a->replacement);
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE
|
1987-07-09 15:04:03 +00:00
|
|
|
outrepl(state,repl)
|
1987-01-15 18:12:26 +00:00
|
|
|
int state;
|
1987-07-09 15:04:03 +00:00
|
|
|
struct mnems repl;
|
1987-01-15 18:12:26 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
/* Contruct <repl>=r1 r2 ... rn and put on output queue.
|
|
|
|
*/
|
|
|
|
int n = repl.m_len;
|
1987-07-09 15:04:03 +00:00
|
|
|
int i;
|
1987-01-15 18:12:26 +00:00
|
|
|
for(i=1;i<=n;i++) {
|
|
|
|
struct mnem_elem *ri = repl.m_elems[i-1];
|
|
|
|
char *mnem = ri->op_code->id_text;
|
|
|
|
switch(ri->op_code->id_argfmt) {
|
|
|
|
case NOARG:
|
1989-02-02 11:41:31 +00:00
|
|
|
fprintf(ofile,"\t\tEM_Rop(op_%s);\n",mnem);
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case CST:
|
1989-02-02 11:41:31 +00:00
|
|
|
fprintf(ofile,"\t\tEM_Rcst(op_%s,",mnem);
|
1987-07-09 15:04:03 +00:00
|
|
|
fprintf(ofile,"(arith)");
|
1987-01-27 14:15:23 +00:00
|
|
|
outexp(ri->arg,state);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,");\n");
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
1987-07-21 13:23:09 +00:00
|
|
|
case CSTOPT:
|
|
|
|
if(ri->arg) {
|
1989-02-02 11:41:31 +00:00
|
|
|
fprintf(ofile,"\t\tEM_Rcst(op_%s,",mnem);
|
1987-07-21 13:23:09 +00:00
|
|
|
fprintf(ofile,"(arith)");
|
|
|
|
outexp(ri->arg,state);
|
|
|
|
}
|
|
|
|
else {
|
1989-02-02 11:41:31 +00:00
|
|
|
fprintf(ofile,"\t\tEM_Rnarg(op_%s);\n",mnem);
|
1987-07-21 13:23:09 +00:00
|
|
|
}
|
|
|
|
fprintf(ofile,");\n");
|
|
|
|
break;
|
1987-01-15 18:12:26 +00:00
|
|
|
case LAB:
|
1989-02-02 11:41:31 +00:00
|
|
|
fprintf(ofile,"\t\tEM_Rilb(op_%s,",mnem);
|
1987-01-27 14:15:23 +00:00
|
|
|
outexp(ri->arg,state);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,");\n");
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case DEFILB:
|
1989-02-02 11:41:31 +00:00
|
|
|
fprintf(ofile,"\t\tEM_Rdefilb(op_%s,",mnem);
|
1987-01-27 14:15:23 +00:00
|
|
|
outexp(ri->arg,state);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,");\n");
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case PNAM:
|
1989-02-02 11:41:31 +00:00
|
|
|
fprintf(ofile,"\t\tEM_Rpro(op_%s,",mnem);
|
1987-01-27 14:15:23 +00:00
|
|
|
outexp(ri->arg,state);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,");\n");
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case EXT:
|
1989-02-02 11:41:31 +00:00
|
|
|
fprintf(ofile,"\t\tOO_mkext(GETNXTREPL(), op_%s,",mnem);
|
1987-01-27 14:15:23 +00:00
|
|
|
outexp(ri->arg,state);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,");\n");
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE
|
1987-01-27 14:15:23 +00:00
|
|
|
outexp(e,state)
|
1987-01-15 18:12:26 +00:00
|
|
|
struct exp_node *e;
|
|
|
|
int state;
|
|
|
|
{
|
|
|
|
switch(e->node_type) {
|
|
|
|
case LOGAND:
|
|
|
|
case LOGOR:
|
|
|
|
case BITAND:
|
|
|
|
case BITOR:
|
|
|
|
case XOR:
|
|
|
|
case MINUS:
|
|
|
|
case PLUS:
|
|
|
|
case TIMES:
|
|
|
|
case DIV:
|
|
|
|
case MOD:
|
|
|
|
case EQ:
|
|
|
|
case NE:
|
|
|
|
case LT:
|
|
|
|
case LE:
|
|
|
|
case GT:
|
|
|
|
case GE:
|
|
|
|
case LSHIFT:
|
|
|
|
case RSHIFT:
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"(");
|
1987-01-27 14:15:23 +00:00
|
|
|
outexp(e->exp_left,state);
|
|
|
|
outop(e->node_type);
|
|
|
|
outexp(e->exp_right,state);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,")");
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case NOT:
|
|
|
|
case COMP:
|
|
|
|
case UPLUS:
|
|
|
|
case UMINUS:
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"(");
|
1987-01-27 14:15:23 +00:00
|
|
|
outop(e->node_type);
|
|
|
|
outexp(e->exp_left,state);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,")");
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case DEFINED:
|
1987-07-21 13:23:09 +00:00
|
|
|
fprintf(ofile,"DEFINED(patt[%d])",e->leaf_val-1);
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case UNDEFINED:
|
1987-07-21 13:23:09 +00:00
|
|
|
fprintf(ofile,"!DEFINED(patt[%d])",e->leaf_val-1);
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case COMMA:
|
|
|
|
outext(e->exp_left);
|
1987-07-09 15:04:03 +00:00
|
|
|
fprintf(ofile,",");
|
|
|
|
fprintf(ofile,"(arith)");
|
|
|
|
outexp(e->exp_right,state);
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case SAMESIGN:
|
|
|
|
case SFIT:
|
|
|
|
case UFIT:
|
|
|
|
case ROTATE:
|
1987-01-27 14:15:23 +00:00
|
|
|
outop(e->node_type);
|
1987-07-09 15:04:03 +00:00
|
|
|
fprintf(ofile,"(arith)");
|
1987-01-27 14:15:23 +00:00
|
|
|
outexp(e->exp_left,state);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,",");
|
1987-07-09 15:04:03 +00:00
|
|
|
fprintf(ofile,"(arith)");
|
1987-01-27 14:15:23 +00:00
|
|
|
outexp(e->exp_right,state);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,")");
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case SAMEEXT:
|
|
|
|
case SAMENAM:
|
1987-01-27 14:15:23 +00:00
|
|
|
outop(e->node_type);
|
1987-01-15 18:12:26 +00:00
|
|
|
outext(e->exp_left);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,",");
|
1987-07-09 15:04:03 +00:00
|
|
|
outext(e->exp_right);
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,")");
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case PATARG:
|
|
|
|
switch(patterns[state].m_elems[e->leaf_val-1]->op_code->id_argfmt) {
|
|
|
|
case NOARG:
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(stderr,"error: mnem %d has no argument\n",e->leaf_val);
|
1987-01-15 18:12:26 +00:00
|
|
|
nerrors++;
|
|
|
|
break;
|
|
|
|
case CST:
|
|
|
|
case CSTOPT:
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"CST(patt[%d])",e->leaf_val-1);
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case LAB:
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"LAB(patt[%d])",e->leaf_val-1);
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case DEFILB:
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"DEFILB(patt[%d])",e->leaf_val-1);
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case PNAM:
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"PNAM(patt[%d])",e->leaf_val-1);
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
case EXT:
|
1987-07-21 13:23:09 +00:00
|
|
|
fprintf(ofile,"OO_offset(patt+%d)",e->leaf_val-1);
|
1987-01-15 18:12:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PSIZE:
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"OO_PSIZE"); break;
|
1987-01-15 18:12:26 +00:00
|
|
|
case WSIZE:
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"OO_WSIZE"); break;
|
1989-02-02 11:41:31 +00:00
|
|
|
case DWSIZE:
|
|
|
|
fprintf(ofile,"OO_DWSIZE"); break;
|
1987-01-15 18:12:26 +00:00
|
|
|
case INT:
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(ofile,"%d",e->leaf_val); break;
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE
|
|
|
|
outext(e)
|
|
|
|
struct exp_node *e;
|
|
|
|
{
|
|
|
|
if(e->node_type!=PATARG) {
|
1987-07-07 16:31:16 +00:00
|
|
|
fprintf(stderr,"Internal error in outext of parser\n");
|
1987-01-15 18:12:26 +00:00
|
|
|
nerrors++;
|
|
|
|
}
|
1987-07-21 13:23:09 +00:00
|
|
|
fprintf(ofile,"patt+%d",e->leaf_val-1);
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PRIVATE
|
1987-01-27 14:15:23 +00:00
|
|
|
outop(op)
|
1987-01-15 18:12:26 +00:00
|
|
|
int op;
|
|
|
|
{
|
|
|
|
switch(op) {
|
1987-07-07 16:31:16 +00:00
|
|
|
case LOGAND: fprintf(ofile,"&&"); break;
|
|
|
|
case LOGOR: fprintf(ofile,"||"); break;
|
|
|
|
case BITAND: fprintf(ofile,"&"); break;
|
|
|
|
case BITOR: fprintf(ofile,"|"); break;
|
|
|
|
case XOR: fprintf(ofile,"^"); break;
|
|
|
|
case MINUS: fprintf(ofile,"-"); break;
|
|
|
|
case PLUS: fprintf(ofile,"+"); break;
|
|
|
|
case TIMES: fprintf(ofile,"*"); break;
|
|
|
|
case DIV: fprintf(ofile,"/"); break;
|
|
|
|
case MOD: fprintf(ofile,"%%"); break;
|
|
|
|
case EQ: fprintf(ofile,"=="); break;
|
|
|
|
case NE: fprintf(ofile,"!="); break;
|
|
|
|
case LT: fprintf(ofile,"<"); break;
|
|
|
|
case LE: fprintf(ofile,"<="); break;
|
|
|
|
case GT: fprintf(ofile,">"); break;
|
|
|
|
case GE: fprintf(ofile,">="); break;
|
|
|
|
case LSHIFT: fprintf(ofile,"<<"); break;
|
|
|
|
case RSHIFT: fprintf(ofile,">>"); break;
|
|
|
|
case NOT: fprintf(ofile,"!"); break;
|
|
|
|
case COMP: fprintf(ofile,"~"); break;
|
|
|
|
case UPLUS: fprintf(ofile,"+"); break;
|
|
|
|
case UMINUS: fprintf(ofile,"-"); break;
|
|
|
|
case SAMESIGN: fprintf(ofile,"OO_signsame("); break;
|
|
|
|
case SFIT: fprintf(ofile,"OO_sfit("); break;
|
|
|
|
case UFIT: fprintf(ofile,"OO_ufit("); break;
|
|
|
|
case ROTATE: fprintf(ofile,"OO_rotate("); break;
|
|
|
|
case SAMEEXT: fprintf(ofile,"OO_extsame("); break;
|
|
|
|
case SAMENAM: fprintf(ofile,"OO_namsame("); break;
|
1987-01-15 18:12:26 +00:00
|
|
|
}
|
|
|
|
}
|