home *** CD-ROM | disk | FTP | other *** search
- /*
- 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;
- }
-
-