home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 309_01 / cc1.c < prev    next >
Text File  |  1990-03-20  |  12KB  |  452 lines

  1. /*
  2. HEADER:        Small-C compiler source part 1;
  3. VERSION:    2.3;
  4. FILENAME:    CC1.C;
  5. AUTHORS:    Dieter H. Flunkert;
  6. COMPILERS:Turbo C V2.0 Medium Memory Model;
  7. 29-oct-86  static declaration added. dhf
  8.  
  9. Modified to MSDOS supporting ASxxx assemblers by Brian Brown Nov 1989
  10.  
  11. */
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include "ccdef.c"
  15.  
  16. /*  Type definitions */
  17. char _char[] = "char";
  18. char _int[] = "int";
  19.  
  20. /* Now reserve some storage words  */
  21. char stattab[stattbsize]; /* static symbol table */
  22. char symtab[symtbsz]; /* symbol table */
  23. char *glbptr,*locptr,*statptr;  /* ptrs to next entries */
  24. char *endsearch;  /* compound start for searching locals */
  25. char *startcomp;  /* start of pointer in current compound */
  26. char swq[SWTABSZ];
  27. int argcs;
  28. char **argvs;
  29. int wq[wqtabsz];  /* while queue */
  30. int *wqptr;   /* ptr to next entry */
  31. char litq[litabsz];  /* literal pool */
  32. int litptr;   /* ptr to next entry */
  33. char macq[macqsize];  /* macro string buffer */
  34. int macptr;   /* and its index */
  35. int stdecl; /* greater 1 if static variable was declared */
  36. char stage[stagesize]; /* staging buffer */
  37. char *stagenext;  /* next adr in stage */
  38. char *stagelast;  /* last adr in stage */
  39. char line[linesize];  /* parsing buffer */
  40. char mline[linesize]; /* temp macro buffer */
  41. int lptr,mptr;  /* ptrs into each */
  42. /* Misc storage */
  43. int nxtlab,  /* next avail label # */
  44.  statlab,    /* next static label number */
  45.  stlab,      /* internal static label */
  46.  litlab,  /* label # assigned to literal pool */
  47.  constval[2], /* [0] = constant identifier */
  48.               /* [1] = constant value */
  49.  monitor,   /* monitor compile */
  50.  pause,   /* pause on error */
  51.  DEFDEBUG,  /* debug feature enabled */
  52.  first_func, /* 1 first function else 0 */
  53.  declared, /* local symbol decl counter */
  54.  stkp,  /* compiler relative stk ptr */
  55.  argstk,  /* function arg sp */
  56. #ifdef STGOTO
  57.  nogo,  /* > 0 disables goto statements */
  58.  noloc, /* > 0 disables block locals */
  59. #endif
  60.  ncmp,  /* # open compound statements */
  61.  swactive, /* true inside a switch */
  62.  swdefault, /* default label # else 0 */
  63.  *swnext, /* address of next entry */
  64.  *swend, /* address of last table entry */
  65.  errcnt,  /* # errors in compilation */
  66.  eof,  /* set non-zero on final input eof */
  67.  iflevel, /* depth of #ifdef */
  68.  skiplevel, /* zero, if no skip */
  69.  optimize, /* non-zero if user wants optimization */
  70.  ctext,  /* non-zero to intermix c-source */
  71.  cmode,  /* non-zero while parsing c-code */
  72.    /* zero when passing assembly code */
  73.  lastst;  /* last executed statement type */
  74. char quote[2]; /* literal string for '"' */
  75. char *cptr,  /* work ptr to any char buffer */
  76.  *cptr2;
  77. int *iptr;  /* work ptr to any int buffer */
  78.  
  79. /* following changes for MSDOS, Brian Brown */
  80. FILE *input,  /* iob # for input file */
  81.      *output,  /* iob # for output file (if any) */
  82.      *input2;  /* iob # for "include" file */
  83.  
  84. /* following change for supporting different assemblers, Brian Brown */
  85. int asmtype;
  86.  
  87. /*  external functions used */
  88. extern int addglb(), addloc(), addmac(), addstatic(), amatch(),
  89.   blanks(), cnl(), ch(), constexpr(),
  90.   defstorage(), doasm(), dumpzero(),
  91.   entry(), endst(), errrpt(), declexternal(),
  92.   findglb(), findloc(),
  93.   getint(), getlabel(),
  94.   header(), illname(),
  95.   kill(),
  96.   match(), multidef(),
  97.   needbrack(),needsub(), newfunc(), nl(), number(), ns(),
  98.   outbyte(), outdec(), outstr(),
  99.   pl(), point(), printlab(),
  100.   qstr(),
  101.   sout(), stowlit(), symname(),
  102.   trailer(),
  103.   upper();
  104.  
  105. /* Compiler begins execution here */
  106. main( argc, argv)
  107. int argc;
  108. char **argv;
  109. {
  110.   argcs = argc;
  111.   argvs = argv;
  112.   swnext = swq;
  113.   swend=swnext+SWTABSZ+SWSIZ;
  114.   first_func=1; /* first function */
  115.   declared = -1;
  116.   glbptr=startglb; /* clear global symbols */
  117.   glbptr=startglb+symsiz*5;
  118.   statptr=startstat;
  119.   startcomp=endsearch=locptr=startloc; /* clear local symbols */
  120.   stagelast=stage+stagesize-1; /* set to end of stageing buffer */
  121.   wqptr=wq;  /* clear while queue */
  122.   litptr=  /* clear literal pool */
  123.   stkp =  /* stack ptr (relative) */
  124.   errcnt=  /* no errrpts */
  125.   eof=  /* not eof yet */
  126.   input=  /* no input file */
  127.   input2=  /* or include file */
  128.   output=  /* no open units */
  129.   ncmp=  /* no open compound states */
  130.   lastst=  /* no last statement yet */
  131.   iflevel= /* no ifdef yet */
  132.   skiplevel= /* also no skip of course */
  133.   stagenext=
  134.   quote[1]= 0;  /*  ...all set to zero.... */
  135.   quote[0]='"';  /* fake a quote literal */
  136.   cmode= /* enable preprocessing */
  137.   macptr=  /* clear the macro pool */
  138.   1;
  139.  
  140.   asmtype = AS6809;  /*asxxx assembler output is default*/
  141.  
  142.   /* compiler body  */
  143.   ask();   /* get user options */
  144.   header();  /* intro code */
  145.   parse();   /* process ALL input */
  146.   trailer();  /* follow-up code */
  147.   closeout();  /* close the output (if any) */
  148.   errrptsummary();  /* summarize errrpts */
  149.   return; /* then exit to system */
  150. }
  151.  
  152. /* Process all input text  At this level, only static declarations, */
  153. /* defines, includes, and function definitions are legal... */
  154. parse()
  155.  {
  156.  int storclass;
  157.  while (eof==0)  /* do until no more input */
  158.   {
  159.   storclass = automatic;
  160.   if(amatch("extern",6)) storclass = EXTERNAL;
  161.   if(amatch("static",6)) storclass = statik;
  162.   if(amatch(_char,4)) {declglb(cchar, storclass);ns();}
  163.   else if(amatch(_int,3)){declglb(cint,storclass);ns();}
  164.  
  165.   /* these added by Brian Brown to support ASxxx .area directives */
  166.   else if(match("#data")) dodata();
  167.   else if(match("#const")) doconst();
  168.   else if(match("#code")) docode();
  169.  
  170.   else if(match("#asm")) doasm();
  171.   else if(match("#include")) doinclude();
  172.   else if(match("#define")) addmac();
  173.   else newfunc(storclass);
  174.   blanks(); /* force eof if pending */
  175.   }
  176. }
  177.  
  178. /* Dump the literal pool  */
  179. dumplits(siz) int siz;
  180. {
  181.  int j,k;
  182.  k=0;   /* init an index... */
  183.  while (k<litptr) /*  to loop with */
  184.   {
  185.     defstorage(siz); /* pseudo-op to define byte */
  186.     j=10;  /* max bytes per line */
  187.     while(j--)
  188.     {
  189.       outdec(getint(litq+k, siz));
  190.       k=k+siz;
  191.       if ((j==0) | (k>=litptr))
  192.       {
  193.         nl();  /* need <cr> */
  194.         break;
  195.       }
  196.       outbyte(','); /* separate bytes */
  197.      }
  198.   }
  199.   litptr=0;
  200.  }
  201.  
  202. /* Report errrpts for user  */
  203. errrptsummary()
  204. {
  205.   /* see if anything left hanging... */
  206.   if (ncmp) errrpt("missing closing bracket");
  207.   /* open compound statement ... */
  208.   output=stdout;
  209.   cnl();
  210.   outdec(errcnt); /* total # errrpts */
  211.   outstr(" error(s) in compilation.");
  212. }
  213.  
  214. myexit()
  215. {
  216.     printf("\nusage: cc infile.c outfile [-options]\n",stderr);
  217.     exit(1);
  218. }
  219.  
  220. ask()
  221. {
  222.   int i;
  223.   int tempcount;
  224.   char *argptr;
  225.   i=0;
  226.   nxtlab=0;
  227.   litlab=getlabel(); /* first label=literal pool */
  228.   kill();   /* erase line buffer */
  229.   clrscr();
  230.   printf(" Small-6809 C compiler for MSDOS systems V2.02\n");
  231.   printf(" Adapted to MSDOS and AS6809 by Brian Brown, Nov 1989\n\n");
  232.   output=stdout;
  233.   optimize=
  234.   monitor=pause=DEFDEBUG=
  235.   ctext=NO;
  236.   if(argcs == 1) {
  237.     myexit();
  238.   }
  239.   else
  240.   {
  241.      if((input=fopen(argvs[1],"r"))==NULL) {
  242.      errrpt("input file error");
  243.      myexit();
  244.      }
  245.      printf("Compiling Source file: %s\n", argvs[1] );
  246.      if((output=fopen(argvs[2],"w"))==NULL) {
  247.        output = stdout;
  248.        printf("No output file specified. Using console screen.\n");
  249.      }
  250.      else printf("Generating asm file: %s\n", argvs[2] );
  251.      tempcount = argcs;
  252.      tempcount = tempcount - 2; /* skip past main, source and dest args */
  253.      while( tempcount-- )
  254.      {
  255.         argptr = argvs[argcs - tempcount];
  256.         if(*argptr++ == '-')
  257.              if(upper(*argptr)=='C') {
  258.                ctext=YES;
  259.                printf("Inserting C text as comments in output file.\n");
  260.              }
  261.              else if(upper(*argptr)=='O') {
  262.                optimize=YES;
  263.                printf("Optimization is ON\n");
  264.              }
  265.              else if(upper(*argptr)=='M') {
  266.                monitor=YES;
  267.                printf("Monitor function is ON\n");
  268.              }
  269.              else if(upper(*argptr) == 'Z' ) {
  270.                 asmtype = AS9;
  271.                 printf("Assembler file is AS9 compatible\n");
  272.              }
  273.              else printf("Invalid option: %c\n", *argptr );
  274.      }
  275.   }
  276.   if(input==NULL) {
  277.     sout("\nno input file...\n",stderr);
  278.     myexit();
  279.   }
  280. }
  281.  
  282. /* Open an include file  */
  283. doinclude()
  284. {
  285.   blanks(); /* skip over to name */
  286.   printf("\n\n#include %s", line+lptr);
  287.   if((input2=fopen(line+lptr,"r"))==NULL)
  288.   {  input2=0;
  289.      errrpt("Open failure on include file");
  290.   }
  291.   kill();  /* clear rest of line */
  292.    /* so next read will come from */
  293.    /* new file (if open */
  294. }
  295.  
  296. /* Close the output file  */
  297. closeout()
  298. {
  299.    if( output == stdout )
  300.     return;
  301.    if(output)fclose(output); /* if open, close it */
  302.    output=0;  /* mark as closed */
  303. }
  304.  
  305. /* Declare a static variable (i.e. define for use)  makes an entry in the
  306.    symbol table so subsequent references can call symbol by name */
  307.  
  308. declglb(typ,class)  /* type is cchar or cint */
  309. int typ, class;
  310. {
  311.   int k,j;
  312.   char sname[namesize];
  313.   while(1)
  314.   {
  315.      if( endst() )  return; /* do line */
  316.      if(match("*")) { /* pointer ? */
  317.        j=pointer;
  318.        k=0;
  319.      }
  320.      else {
  321.       j=variable;
  322.       k=1;
  323.     }
  324.     if (symname(sname)==0) /* name ok? */
  325.        illname(); /* no... */
  326.     if( findglb(sname) ) /* already there? */
  327.       multidef(sname);
  328.     if(match("()"))  j = function;
  329.     else if (match("["))  /* array? */
  330.     {  k=needsub(); /* get size */
  331.        j=array; /* !0=array */
  332.     }
  333.    if(class==EXTERNAL) declexternal(sname);
  334.    else {
  335.      entry(sname, class);
  336.      j=initials(typ>>2, j, k);
  337.    }
  338.    addglb(sname,j,typ,k,class); /* add symbol */
  339.  
  340.    if(match(",")==0) return;  /* more? */
  341.   }
  342. }
  343.  
  344. /* declare local variables ** changed for static declaration
  345. ** dieter h. flunkert 29-oct-86 */
  346. declloc(typ, class)  int typ, class;  {
  347.   int k,j; char sname[namesize], numstring[namesize];
  348. #ifdef STGOTO
  349.   if(noloc) errrpt("not allowed with goto");
  350. #endif
  351.   if(declared < 0) errrpt("must declare first in block");
  352.   while(1) {
  353.     while(1) {
  354.       if(endst()) return;
  355.       if(match("*")) j=pointer;
  356.       else j = variable;
  357.       if (symname(sname)==0) illname();
  358.       endsearch=startcomp;
  359.       if(findloc(sname) != 0) multidef(sname);
  360.       endsearch=startloc;
  361.       k=2;
  362.       if (match("[")) {
  363.         k=needsub();
  364.         if(k || class == statik) {
  365.      j=array;
  366.            if(typ==cint)k=k+k;
  367.         }
  368.        else {j=pointer;
  369.              k=2;
  370.        }
  371.       }
  372.       else if(match("()")) j=function;
  373.       else if((typ==cchar)&&(j==variable)) k=1;
  374.       if(class == statik) {    /* dhf 29-oct-86 */
  375.     convert(statlab++, numstring);
  376.     entry(numstring, class);
  377.     if(typ==cint) k = k>>1;
  378.     j=initials(typ>>2, j, k); /*not*/
  379.     addstatic(sname, numstring, j, typ, k);
  380.     addloc(sname, j, typ, 0); /* making it known as local */
  381.       }
  382.       else {
  383.        declared = declared + k;
  384.        addloc(sname, j, typ, stkp - declared);
  385.       }
  386.       break;
  387.       }
  388.     if (match(",")==0) return;
  389.     }
  390.   }
  391.  
  392. convert(n,s)
  393. int n; char *s;
  394. {
  395.    char *c, ch;
  396.  
  397.    c=s;
  398.    do {
  399.     *s++ = n % 10 + '0';
  400.    } while((n /= 10) > 0);
  401.    *s-- = '\0';
  402.    while(c < s) {
  403.     ch = *c;
  404.     *c++ = *s;
  405.     *s-- = ch;
  406.    }
  407. }
  408.  
  409. /* initialize global objects */
  410. initials(siz, id, dim)
  411. int siz, id, dim;
  412. {
  413.   int savedim;
  414.   if(dim==0) dim = -1;
  415.   savedim=dim;
  416.   if(match("=")) {
  417.     if(match("{")) {
  418.       while(dim) {
  419.         init(siz, id, &dim);
  420.         if(match(",")==0) break;
  421.         }
  422.       needbrack("}");
  423.       }
  424.     else init(siz, id, &dim);
  425.     }
  426.   if((dim == -1)&&(dim==savedim)) {
  427.      stowlit(0, siz=2);
  428.     id=pointer;
  429.     }
  430.   dumplits(siz);
  431.   dumpzero(siz*dim);
  432.   return id;
  433. }
  434.  
  435. /* evaluate one initializer */
  436. init(siz, id, dim)
  437. int siz, id, *dim;
  438. {
  439.   int value;
  440.   if(qstr(&value)) {
  441.     if((id==variable)||(siz!=1))
  442.       errrpt("must assign to char pointer or array");
  443.     *dim = - (litptr - value) + *dim;
  444.     if(id==pointer) point();
  445.     }
  446.   else if(constexpr(&value)) {
  447.     if(id==pointer) errrpt("cannot assign to pointer");
  448.     stowlit(value, siz);
  449.     *dim = -1 + *dim;
  450.   }
  451. }
  452.