home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
332.lha
/
AmigaAsmPreprocessor_v0.2
/
ap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-06
|
8KB
|
380 lines
/*
ap.c -- amiga assembler preprocessor
(c) 1989, Risto Paasivirta
*/
#include <stdio.h>
#include <ctype.h>
#define COPYRIGHT "AP V0.2 -- (c) 1989, Risto Paasivirta\n"
#define MAXW 200 /* maximim number of stored words */
#define WLEN 32 /* max lenght of word */
#define MAXS 20 /* max entries in control structure stack */
int debug=0; /* debug mode flag */
int verbose=0; /* verbose mode flag */
#define OPNO 36 /* number of operands */
char *ops[]={" ", /* operand memnonics */
"}",".","+","-","*","/","*/","=",
";","&","|","^","~","%","0=","==",
"ifeq","ifne","ifgt","iflt","ifge","ifle","then",
"else","begin","until","while","repeat","<?",
"<^","<0","<1",":=:","!","<<",">>" };
char *brs[]={ /* branch opcodes for if-constucts */
"bne","beq","ble","bge","blt","bgt" };
char *bop[]={ /* bit opcodes */
"btst","bchg","bclr","bset" };
char line[200]; /* line buffer */
int linenum=0; /* line to compile */
char tmps[32]; /* temp string */
int tmpn=0; /* count for label generation */
char wrd[MAXW][WLEN]; /* storage for scanned words */
int wrdp=0; /* index for next free word storage */
char stk[MAXS][WLEN]; /* stack for control structures */
int stkp=0; /* index of next free stack entry */
main(argc,argv)
int argc;
char **argv;
{
while(--argc) /* loop through options */
switch(**++argv)
{
case 'd': /* option debug, set debug mode */
debug=1;
break;
case 'v': /* option v, set verbose mode */
verbose=1;
break;
default: /* unnown option, print usage */
fprintf(stderr,"usage: ap [<inputfile] [>outputfile] [d] [v]");
exit(1);
break;
}
if(verbose)fprintf(stderr,COPYRIGHT);
while(gets(line)) /* parse source */
{
linenum++; /* count lines */
if(verbose)fprintf(stderr,"line %3d: asm\r",linenum);
if(*line!='{') puts(line); /* copy stuff to assembler */
else while(gets(line)) /* compile stuff */
{
linenum++; /* count lines */
if(verbose)fprintf(stderr,"line %3d: ap \r",linenum);
if(parse())break; /* compile until end of ap-block */
}
if(feof(stdin)) break; /* break if eof */
}
if(wrdp>1) /* warn if expression not closed with '.' */
{
fprintf(stderr,"eof while expression open\n");
}
if(stkp) /* warn if missing then, until or repeat */
{
fprintf(stderr,"eof while control structures open!\n");
exit(1);
}
if(verbose)fprintf(stderr,"%d lines compiled ok.\n",linenum);
exit(0);
}
/* need(x) -- check if there are enough stuff to compile */
void
need(x)
{
if(wrdp<x)
{
fprintf(stderr,"line %d out of labels\n",linenum);
exit(1); /* no recovery */
}
}
#define arg1 wrd[wrdp-1] /* arguments to pass to assembler code */
#define arg2 wrd[wrdp-2]
#define arg3 wrd[wrdp-3]
/* parse() -- compile line, return 1 if end of apl block */
int
parse()
{
char *ln,*s;
int i;
ln=line; /* set ptr to start of line buffer */
while(*ln) /* while there are any chars */
{
while(isspace(*ln))ln++; /* skip spaces */
s=wrd[wrdp]; /* get word */
for(i=WLEN-1;!isspace(*ln)&& i && *ln;i--)*s++ = *ln++;
*s=0; /* ending zero */
if(i==WLEN-1) break; /* end of line */
while(!isspace(*ln)&&*ln)ln++; /* skip rest of word */
/* search word */
for(i=OPNO;i>0;i--)if(strcmp(ops[i],wrd[wrdp])==0)break;
switch(i) /* switch by operand, 0=label/assembler expression */
{
case 0: /* label */
if(++wrdp>=MAXW) /* leave label in storage */
{
fprintf(stderr,"out of space!\n");
exit(1);
}
break;
case 1: /* } end of code */
return 1;
break;
case 2: /* . (end of expression) */
if(wrdp>1) /* check if there are extra labels */
{
fprintf(stderr,"line %d: too much stuff: ",
linenum);
for(;--wrdp;)fprintf(stderr,"%s ",
wrd[wrdp-1]);
fprintf(stderr,"\n");
}
wrdp=0; /* clean storage */
break;
case 3: /* + */
need(2);
printf("\tadd.w %s,%s\n",arg1,arg2);
wrdp-=1;
break;
case 4: /* - */
need(2);
printf("\tsub.w %s,%s\n",arg1,arg2);
wrdp-=1;
break;
case 5: /* * */
need(2);
printf("\tmuls.w %s,%s\n",arg1,arg2);
wrdp-=1;
break;
case 6: /* / */
need(2);
printf("\text.l %s\n\tdivs.w %s,%s\n",arg2,arg1,arg2);
wrdp-=1;
break;
case 7: /* muldiv */
need(3);
printf("\tmuls.w %s,%s\n\tdivs.w %s,%s\n"
,arg2,arg3,arg1,arg3);
wrdp-=2;
break;
case 8: /* = move */
need(2);
printf("\tmove.w %s,%s\n",arg1,arg2);
wrdp-=1;
break;
case 9: /* ; comment */
if(debug)printf("; %03d: %s\n",linenum,line);
else printf("\t; %s\n",ln);
return 0;
break;
case 10: /* & and */
need(2);
printf("\tand.w %s,%s\n",arg1,arg2);
wrdp-=1;
break;
case 11: /* | or */
need(2);
printf("\tor.w %s,%s\n",arg1,arg2);
wrdp-=1;
break;
case 12: /* ^ eor */
need(2);
printf("\teor.w %s,%s\n",arg1,arg2);
wrdp-=1;
break;
case 13: /* ~ not */
need(1);
printf("\tnot.w %s\n",arg1);
break;
case 14: /* % swap/mod */
need(1);
printf("\tswap %s\n",arg1);
break;
case 15: /* 0= */
need(1);
printf("\ttst.w %s\n",arg1);
break;
case 16: /* == */
need(2);
printf("\tcmp.w %s,%s\n",arg1,arg2);
wrdp-=1;
break;
case 17: case 18: case 19: case 20: case 21: case 22: /* if */
if(stkp>=MAXS)
{
fprintf(stderr,"line %d stack full\n",
linenum);
exit(1);
}
sprintf(tmps,"%03d",tmpn++); /* create label */
strcpy(stk[stkp++],tmps); /* copy label in stack */
/* compile 'bcc label' */
printf("\t%s if.%s\n",brs[i-17],tmps);
break;
case 23: /* then */
if(stkp<1)
{
fprintf(stderr,"line %d then without if\n",
linenum);
exit(1);
}
printf("if.%s\n",stk[--stkp]); /* copy label there */
break;
case 24: /* else */
if(stkp<1)
{
fprintf(stderr,"line %d else without if\n",
linenum);
exit(1);
}
sprintf(tmps,"%03d",tmpn++); /* create label */
/* compile 'bra newlabel \noldlablel' */
printf("\tbra if.%s\nif.%s\n",tmps,stk[--stkp]);
strcpy(stk[stkp++],tmps); /* push new label */
break;
case 25: /* begin */
if(stkp>=MAXS)
{
fprintf(stderr,"line %d stack full\n",
linenum);
exit(1);
}
sprintf(tmps,"%03d",tmpn++); /* create label */
strcpy(stk[stkp++],tmps); /* push label */
printf("beg.%s\n",tmps); /* compile label */
break;
case 26: /* until */
if(stkp<1)
{
fprintf(stderr,"line %d until without begin\n",
linenum);
exit(1);
}
printf("\tbeq beg.%s\n",stk[--stkp]); /* beq label */
break;
case 27: /* while */
if(stkp<1)
{
fprintf(stderr,"line %d while without begin\n",
linenum);
exit(1);
}
if(stkp>=MAXS)
{
fprintf(stderr,"line %d stack full\n",
linenum);
exit(1);
}
sprintf(tmps,"%03d",tmpn++); /* create label */
printf("\tbeq whl.%s\n",tmps); /* beq label */
strcpy(stk[stkp++],tmps); /* push label */
break;
case 28: /* repeat */
if(stkp<2)
{
fprintf(stderr,"line %d repeat without while\n",
linenum);
exit(1);
}
/* compile 'bra label2\nlabel1' */
printf("\tbra beg.%s\nwhl.%s\n",
stk[stkp-2],stk[stkp-1]);
stkp-=2;
break;
case 29: case 30: case 31: case 32: /* bit opers */
need(2);
printf("\t%s %s,%s\n",bop[i-29],arg1,arg2);
wrdp-=1;
break;
case 33: /* :=: exhange */
need(2);
printf("\texg %s,%s\n",arg1,arg2);
wrdp-=1;
break;
case 34: /* ! logical not */
printf("\teor #4,CCR\n");
break;
case 35: /* << shift right */
need(2);
printf("\tlsr.w %s,%s\n",arg1,arg2);
wrdp-=1;
break;
case 36: /* >> arithmetic shift left */
need(2);
printf("\tasl.w %s,%s\n",arg1,arg2);
wrdp-=1;
break;
default: /* this never happens */
fprintf(stderr,"%s not yet supported\n",ops[i]);
break;
}
}
/* if debug mode copy source as comment to output */
if(debug)printf("; %03d: %s\n",linenum,line);
return 0;
}