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 >
C/C++ Source or Header  |  1990-01-06  |  8KB  |  380 lines

  1. /*
  2.  ap.c -- amiga assembler preprocessor
  3.  (c) 1989, Risto Paasivirta
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <ctype.h>
  8.  
  9. #define COPYRIGHT    "AP V0.2 -- (c) 1989, Risto Paasivirta\n"
  10.  
  11. #define MAXW 200    /* maximim number of stored words */
  12. #define WLEN 32        /* max lenght of word */
  13. #define MAXS 20        /* max entries in control structure stack */
  14.  
  15. int debug=0;        /* debug mode flag */
  16. int verbose=0;        /* verbose mode flag */
  17.  
  18. #define OPNO 36        /* number of operands */
  19.  
  20. char *ops[]={" ",    /* operand memnonics */
  21.     "}",".","+","-","*","/","*/","=",
  22.     ";","&","|","^","~","%","0=","==",
  23.     "ifeq","ifne","ifgt","iflt","ifge","ifle","then",
  24.     "else","begin","until","while","repeat","<?",
  25.     "<^","<0","<1",":=:","!","<<",">>" };
  26.  
  27.  
  28. char *brs[]={        /* branch opcodes for if-constucts */
  29.     "bne","beq","ble","bge","blt","bgt" };
  30.  
  31. char *bop[]={        /* bit opcodes */
  32.     "btst","bchg","bclr","bset" };
  33.  
  34. char line[200];        /* line buffer */
  35. int linenum=0;        /* line to compile */
  36.  
  37. char tmps[32];        /* temp string */
  38. int tmpn=0;        /* count for label generation */
  39.  
  40. char wrd[MAXW][WLEN];    /* storage for scanned words */ 
  41. int wrdp=0;        /* index for next free word storage */
  42.  
  43. char stk[MAXS][WLEN];    /* stack for control structures */
  44. int stkp=0;        /* index of next free stack entry */
  45.  
  46. main(argc,argv)
  47. int argc;
  48. char **argv;
  49. {
  50.     while(--argc)    /* loop through options */
  51.     switch(**++argv)
  52.     {    
  53.     case 'd':    /* option debug, set debug mode */
  54.         debug=1;
  55.     break;
  56.  
  57.     case 'v':    /* option v, set verbose mode */
  58.         verbose=1;
  59.     break;
  60.  
  61.     default:    /* unnown option, print usage */
  62.         fprintf(stderr,"usage: ap [<inputfile] [>outputfile] [d] [v]");
  63.         exit(1);
  64.     break;
  65.     }
  66.  
  67.     if(verbose)fprintf(stderr,COPYRIGHT);
  68.  
  69.  
  70.     while(gets(line)) /* parse source */
  71.     {
  72.         linenum++; /* count lines */
  73.         if(verbose)fprintf(stderr,"line %3d: asm\r",linenum);
  74.         if(*line!='{') puts(line); /* copy stuff to assembler */
  75.         else while(gets(line))    /* compile stuff */    
  76.         {
  77.             linenum++; /* count lines */
  78.             if(verbose)fprintf(stderr,"line %3d: ap \r",linenum);
  79.             if(parse())break; /* compile until end of ap-block */
  80.         }
  81.         if(feof(stdin)) break; /* break if eof */
  82.     }
  83.     if(wrdp>1) /* warn if expression not closed with '.' */
  84.     {
  85.         fprintf(stderr,"eof while expression open\n");
  86.     } 
  87.  
  88.     if(stkp) /* warn if missing then, until or repeat */
  89.     {
  90.         fprintf(stderr,"eof while control structures open!\n");
  91.         exit(1);
  92.     }
  93.     if(verbose)fprintf(stderr,"%d lines compiled ok.\n",linenum);
  94.     exit(0);
  95. }
  96.  
  97. /* need(x) -- check if there are enough stuff to compile */ 
  98.  
  99. void
  100. need(x) 
  101. {
  102.     if(wrdp<x)
  103.     {
  104.         fprintf(stderr,"line %d out of labels\n",linenum);
  105.         exit(1); /* no recovery */
  106.     }
  107. }
  108.  
  109. #define arg1 wrd[wrdp-1]     /* arguments to pass to assembler code */
  110. #define arg2 wrd[wrdp-2]
  111. #define arg3 wrd[wrdp-3]
  112.  
  113. /* parse() -- compile line, return 1 if end of apl block */
  114.  
  115. int
  116. parse()
  117. {
  118.     char *ln,*s;
  119.     int i;
  120.  
  121.     ln=line; /* set ptr to start of line buffer */
  122.  
  123.     while(*ln) /* while there are any chars */
  124.     {
  125.         while(isspace(*ln))ln++;    /* skip spaces */
  126.  
  127.         s=wrd[wrdp];             /* get word */
  128.         for(i=WLEN-1;!isspace(*ln)&& i && *ln;i--)*s++ = *ln++;
  129.         *s=0; /* ending zero */
  130.  
  131.         if(i==WLEN-1) break;         /* end of line */
  132.  
  133.         while(!isspace(*ln)&&*ln)ln++;    /* skip rest of word */
  134.  
  135.                         /* search word */
  136.         for(i=OPNO;i>0;i--)if(strcmp(ops[i],wrd[wrdp])==0)break;
  137.  
  138.         switch(i) /* switch by operand, 0=label/assembler expression */
  139.         {
  140.         case 0: /* label */
  141.             if(++wrdp>=MAXW) /* leave label in storage */
  142.             {
  143.                 fprintf(stderr,"out of space!\n");
  144.                 exit(1);
  145.             }
  146.         break;
  147.  
  148.         case 1: /* } end of code */
  149.             return 1;
  150.         break;
  151.  
  152.         case 2: /* . (end of expression) */
  153.             if(wrdp>1) /* check if there are extra labels */
  154.             {
  155.                 fprintf(stderr,"line %d: too much stuff: ",
  156.                     linenum);
  157.                 for(;--wrdp;)fprintf(stderr,"%s ",
  158.                     wrd[wrdp-1]);
  159.                 fprintf(stderr,"\n");
  160.             }
  161.             wrdp=0; /* clean storage */
  162.         break;
  163.  
  164.         case 3: /* + */
  165.             need(2);    
  166.             printf("\tadd.w %s,%s\n",arg1,arg2);
  167.             wrdp-=1;
  168.         break;    
  169.  
  170.         case 4: /* - */
  171.             need(2);    
  172.             printf("\tsub.w %s,%s\n",arg1,arg2);
  173.             wrdp-=1;
  174.         break;    
  175.         
  176.         case 5: /* * */
  177.             need(2);    
  178.             printf("\tmuls.w %s,%s\n",arg1,arg2);
  179.             wrdp-=1;
  180.         break;    
  181.  
  182.         case 6: /* / */
  183.             need(2);
  184.             printf("\text.l %s\n\tdivs.w %s,%s\n",arg2,arg1,arg2);
  185.             wrdp-=1;
  186.         break;
  187.  
  188.         case 7: /* muldiv */
  189.             need(3);
  190.             printf("\tmuls.w %s,%s\n\tdivs.w %s,%s\n"
  191.                 ,arg2,arg3,arg1,arg3);
  192.             wrdp-=2;
  193.         break;
  194.  
  195.         case 8: /* = move */
  196.             need(2);    
  197.             printf("\tmove.w %s,%s\n",arg1,arg2);
  198.             wrdp-=1;
  199.         break;
  200.  
  201.         case 9: /* ; comment */
  202.             if(debug)printf("; %03d: %s\n",linenum,line);
  203.             else printf("\t; %s\n",ln);
  204.             return 0;
  205.         break;
  206.  
  207.  
  208.         case 10: /* & and */
  209.             need(2);    
  210.             printf("\tand.w %s,%s\n",arg1,arg2);
  211.             wrdp-=1;
  212.         break;    
  213.  
  214.         case 11: /* | or */
  215.             need(2);    
  216.             printf("\tor.w %s,%s\n",arg1,arg2);
  217.             wrdp-=1;
  218.         break;    
  219.  
  220.         case 12: /* ^ eor */
  221.             need(2);    
  222.             printf("\teor.w %s,%s\n",arg1,arg2);
  223.             wrdp-=1;
  224.         break;    
  225.  
  226.         case 13: /* ~ not */
  227.             need(1);    
  228.             printf("\tnot.w %s\n",arg1);
  229.         break;    
  230.  
  231.         case 14: /* % swap/mod */
  232.             need(1);    
  233.             printf("\tswap %s\n",arg1);
  234.         break;    
  235.  
  236.         case 15: /* 0= */
  237.             need(1);    
  238.             printf("\ttst.w %s\n",arg1);
  239.         break;
  240.  
  241.         case 16: /* == */
  242.             need(2);    
  243.             printf("\tcmp.w %s,%s\n",arg1,arg2);
  244.             wrdp-=1;
  245.         break;
  246.  
  247.         case 17: case 18: case 19: case 20: case 21: case 22: /* if */
  248.             if(stkp>=MAXS)
  249.             {
  250.                 fprintf(stderr,"line %d stack full\n",
  251.                 linenum);
  252.                 exit(1);
  253.             }
  254.             sprintf(tmps,"%03d",tmpn++); /* create label */
  255.             strcpy(stk[stkp++],tmps); /* copy label in stack */
  256.             /* compile 'bcc label' */    
  257.             printf("\t%s if.%s\n",brs[i-17],tmps);
  258.         break;
  259.  
  260.         case 23: /* then */
  261.             if(stkp<1)
  262.             {
  263.                 fprintf(stderr,"line %d then without if\n",
  264.                 linenum);
  265.                 exit(1);
  266.             }
  267.             printf("if.%s\n",stk[--stkp]); /* copy label there */
  268.         break;
  269.             
  270.         case 24: /* else */
  271.             if(stkp<1)
  272.             {
  273.                 fprintf(stderr,"line %d else without if\n",
  274.                 linenum);
  275.                 exit(1);
  276.             }
  277.             sprintf(tmps,"%03d",tmpn++); /* create label */
  278.             /* compile 'bra newlabel \noldlablel' */
  279.             printf("\tbra if.%s\nif.%s\n",tmps,stk[--stkp]);
  280.             strcpy(stk[stkp++],tmps); /* push new label */
  281.         break;
  282.  
  283.         case 25: /* begin */
  284.             if(stkp>=MAXS)
  285.             {
  286.                 fprintf(stderr,"line %d stack full\n",
  287.                 linenum);
  288.                 exit(1);
  289.             }
  290.             sprintf(tmps,"%03d",tmpn++); /* create label */
  291.             strcpy(stk[stkp++],tmps); /* push label */
  292.             printf("beg.%s\n",tmps); /* compile label */
  293.         break;
  294.  
  295.         case 26: /* until */
  296.             if(stkp<1)
  297.             {
  298.                 fprintf(stderr,"line %d until without begin\n",
  299.                 linenum);
  300.                 exit(1);
  301.             }
  302.             printf("\tbeq beg.%s\n",stk[--stkp]); /* beq label */
  303.         break;
  304.  
  305.         case 27: /* while */
  306.             if(stkp<1)
  307.             {
  308.                 fprintf(stderr,"line %d while without begin\n",
  309.                 linenum);
  310.                 exit(1);
  311.             }
  312.  
  313.             if(stkp>=MAXS)
  314.             {
  315.                 fprintf(stderr,"line %d stack full\n",
  316.                 linenum);
  317.                 exit(1);
  318.             }
  319.  
  320.             sprintf(tmps,"%03d",tmpn++); /* create label */
  321.             printf("\tbeq whl.%s\n",tmps); /* beq label */
  322.             strcpy(stk[stkp++],tmps); /* push label */
  323.         break;
  324.  
  325.         case 28: /* repeat */
  326.             if(stkp<2)
  327.             {
  328.                 fprintf(stderr,"line %d repeat without while\n",
  329.                 linenum);
  330.                 exit(1);
  331.             }
  332.  
  333.             /* compile 'bra label2\nlabel1' */
  334.  
  335.             printf("\tbra beg.%s\nwhl.%s\n",
  336.                 stk[stkp-2],stk[stkp-1]);
  337.             stkp-=2;
  338.         break;
  339.  
  340.  
  341.         case 29: case 30: case 31: case 32: /* bit opers */
  342.             need(2);
  343.             printf("\t%s %s,%s\n",bop[i-29],arg1,arg2);
  344.             wrdp-=1;
  345.         break;
  346.  
  347.         case 33: /* :=: exhange */
  348.             need(2);    
  349.             printf("\texg %s,%s\n",arg1,arg2);
  350.             wrdp-=1;
  351.         break;
  352.  
  353.         case 34: /* ! logical not */
  354.             printf("\teor #4,CCR\n");
  355.         break;
  356.  
  357.         case 35: /* << shift right */
  358.             need(2);    
  359.             printf("\tlsr.w %s,%s\n",arg1,arg2);
  360.             wrdp-=1;
  361.         break;
  362.  
  363.         case 36: /* >> arithmetic shift left */
  364.             need(2);    
  365.             printf("\tasl.w %s,%s\n",arg1,arg2);
  366.             wrdp-=1;
  367.         break;
  368.  
  369.         default: /* this never happens */
  370.             fprintf(stderr,"%s not yet supported\n",ops[i]);
  371.         break;
  372.         }
  373.  
  374.     }
  375.     /* if debug mode copy source as comment to output */
  376.     if(debug)printf("; %03d: %s\n",linenum,line);
  377.     return 0;
  378. }
  379.  
  380.