home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / SOURCE / INIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-08  |  14.1 KB  |  578 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1996, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and sources are distributed along with any executables derived from them.
  11.  *
  12.  * The author is not responsible for damages, either direct or consequential,
  13.  * that may arise from use of this software.
  14.  *
  15.  * v1.5 August 1996
  16.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  17.  *
  18.  * Credits to Mathew Brandt for original K&R C compiler
  19.  *
  20.  */
  21. #include        <stdio.h>
  22. #include        "expr.h"
  23. #include        "c.h"
  24. #include        "gen.h"
  25. #include        "cglbdec.h"
  26.  
  27. extern int skm_declend[];
  28. extern long bittab[];
  29. extern int nextlabel;
  30. extern TYP stdmatch;
  31. extern int skm_closebr[];
  32. extern int prm_cplusplus;
  33. extern SYM *currentfunc;
  34. extern long lc_maxauto,lc_auto;
  35.  
  36. static SYM *locsp;
  37. static short cursize;
  38. static short startbit,bits;
  39. static long totbits;
  40. static int allocated;
  41. static ENODE *cpprefhead;
  42. static ENODE **cppreftail;
  43. static int baseoffs = 0;
  44. void initini(void)
  45. {
  46.     cpprefhead = 0;
  47. }
  48. void initrundown(void)
  49. {
  50.     if (cpprefhead) {
  51.         int lbl = nextlabel++;
  52.         SNODE stmt;
  53.         currentfunc = xalloc(sizeof(SYM));
  54.         currentfunc->tp = maketype(bt_func,0);
  55.         currentfunc->tp->btp = maketype(bt_void,0);
  56.         currentfunc->tp->lst.head = 0;
  57.         currentfunc->intflag = 0;
  58.         stmt.stype = st_expr;
  59.         stmt.next = 0;
  60.         stmt.exp = cpprefhead;
  61.         lc_maxauto = lc_auto = 0;
  62.         cseg();
  63.         gen_label(lbl);
  64.         genfunc(&stmt);
  65.         flush_peep();
  66.         cppseg();
  67.         gen_labref(lbl);
  68.         currentfunc = 0;
  69.         cpprefhead = 0;
  70.     }
  71. }
  72. void cppinitinsert(ENODE *node)
  73. {
  74.     if (!cpprefhead) {
  75.         cpprefhead = node;
  76.         cppreftail = &cpprefhead;
  77.     }
  78.     else {
  79.         *cppreftail = makenode(en_void,*cppreftail,node);
  80.         cppreftail = & (*cppreftail)->v.p[1];
  81.     }
  82. }
  83. void doinit(SYM *sp)
  84. /*
  85.  * Handle static variable initialize
  86.  */
  87. {
  88.                 sp->tp->uflags |= UF_DEFINED;
  89.                 allocated = FALSE;
  90.                 baseoffs = 0;
  91.                 totbits = 0;
  92.                 cursize = -1;
  93.                 bits = -1;
  94.                 locsp = sp;
  95.                 if (!sp->absflag) {
  96.                     char buf[100];
  97.                     strcpy(buf,sp->name);
  98.              gen_strlab(buf);
  99.                 }
  100.         if( lastst != assign) {
  101.                 genstorage(sp->tp->size);
  102.                 }
  103.         else    {
  104.                                 if (sp->absflag) {
  105.                                     generror(ERR_NOINIT,0,skm_declend);
  106.                           return;
  107.                                 }
  108.                 getsym();
  109.                 inittype(sp->tp);
  110.                 }
  111.                 if (sp->tp->size == 0 && !allocated)
  112.                     gensymerror(ERR_ZEROSTORAGE,sp->name);
  113.         endinit();
  114. }
  115.  
  116. int     inittype(TYP *tp)
  117. /*
  118.  * Init for basic types
  119.  */
  120. {       int     nbytes;
  121.         switch(tp->type) {
  122.  
  123.                                 case bt_float:
  124.                                                 nbytes = initfloat();
  125.                                                 break;
  126.                                 case bt_longdouble:
  127.                                                 nbytes = initlongdouble();
  128.                                                 break;
  129.                                 case bt_double:
  130.                                                 nbytes = initdouble();
  131.                                                 break;
  132.                 case bt_char:
  133.                 case bt_unsignedchar:
  134.                         nbytes = initchar();
  135.                         break;
  136.                 case bt_short:
  137.                 case bt_unsignedshort:
  138.                 case bt_enum:
  139.                         nbytes = initshort();
  140.                         break;
  141.                 case bt_ptrfunc:
  142.                         nbytes = initpointerfunc();
  143.                         break;
  144.                 case bt_pointer:
  145.                         if( tp->val_flag)
  146.                                 nbytes = initarray(tp);
  147.                         else
  148.                                 nbytes = initpointer();
  149.                         break;
  150.                                 case bt_ref:
  151.                                                 nbytes = initref(tp->btp);
  152.                                                 break;
  153.                 case bt_long:
  154.                 case bt_matchall:
  155.                 case bt_unsigned:
  156.                         nbytes = initlong();
  157.                         break;
  158.                 case bt_struct:
  159.                         nbytes = initstruct(tp);
  160.                         break;
  161.                 default:
  162.                                               gensymerror(ERR_NOINIT,locsp->name);
  163.                         nbytes = 0;
  164.                 }
  165.                 baseoffs+=nbytes;
  166.         return nbytes;
  167. }
  168.  
  169. int initarray(TYP *tp)
  170. /*
  171.  * Init for arrays
  172.  */
  173. {       int     nbytes;
  174.         char    *p;
  175.                 int needend = FALSE;
  176.         nbytes = 0;
  177.         if( lastst == begin) {
  178.                 getsym();               /* skip past the brace */
  179.                                 needend = TRUE;
  180.                                 if (tp->btp->type == bt_char && lastst == sconst)
  181.                                     goto grabchar;
  182.                 while(lastst != end) {
  183.                         nbytes += inittype(tp->btp);
  184.                         if( lastst == comma)
  185.                                 getsym();
  186.                         else if( lastst != end) {
  187.                                 expecttoken(end,0);
  188.                                                                 break;
  189.                                                 }
  190.                         }
  191.                 getsym();               /* skip closing brace */
  192.                 }
  193.         else { 
  194. grabchar:        
  195.                         allocated = TRUE;
  196.                         if( lastst == sconst && tp->btp->type == bt_char) {
  197.                 nbytes = strlen(laststr) + 1;
  198.                 p = laststr;
  199.                 while( *p )
  200.                         genbyte(*p++);
  201.                 genbyte(0);
  202.                                 if (nbytes & 1) {
  203.                                     nbytes++;
  204.                                     genbyte(0);
  205.                                 }
  206.                 getsym();
  207.                                 if (needend)
  208.                                     needpunc(end,skm_declend);
  209.                 }
  210.             else generror(ERR_PUNCT,semicolon,0);
  211.                 }
  212.         if( nbytes < tp->size) {
  213.                                 nl();
  214.                 genstorage( tp->size - nbytes);
  215.                 nbytes = tp->size;
  216.                 }
  217.         else if( tp->size != 0 && nbytes > tp->size)
  218.                 generror(ERR_INITSIZE,0,0);    /* too many initializers */
  219.         return nbytes;
  220. }
  221.  
  222. int initstruct(TYP *tp)
  223. /*
  224.  * Init for structures
  225.  */
  226. {       SYM     *sp;
  227.         int     nbytes;
  228.         needpunc(begin,0);
  229.         nbytes = 0;
  230.         sp = tp->lst.head;      /* start at top of symbol table */
  231.         while(sp != 0) {
  232.                                 startbit = sp->tp->startbit;
  233.                                 bits = sp->tp->bits;
  234.                 while(nbytes < sp->value.i) {     /* align properly */ 
  235.                         nbytes++;
  236.                                               genbyte(0);
  237.                                 }
  238.                 nbytes += inittype(sp->tp);
  239.                 if( lastst == comma)
  240.                         getsym();
  241.                 else if(lastst == end)
  242.                         break;
  243.                 else
  244.                         expecttoken(end,0);
  245.                 sp = sp->next;
  246.                 }
  247.                 nbytes += agbits(-1,0);
  248.         if( nbytes < tp->size) {
  249.                     genstorage(tp->size - nbytes);
  250.                 }
  251.         needpunc(end,skm_declend);
  252.         return tp->size;
  253. }
  254.  
  255. int agflush(int size, long val)
  256. {
  257.     switch (size) {
  258.         case 1:
  259.             genbyte(val);
  260.             return 1;
  261.         case 2:
  262.             genword(val);
  263.             return 2;
  264.         case 4:
  265.             genlong(val);
  266.             return 4;
  267.         default:
  268.             return 0;
  269.     }
  270. }
  271. /* Aggregate bits */
  272. int agbits(int size, long value)
  273. {
  274.     long rv = 0;
  275.     if (cursize != -1 && (size != cursize || bits == -1 || (bits != -1 &&startbit==0)))
  276.         rv = agflush(cursize,totbits);
  277.     if (bits != -1) {
  278.         totbits |= (value & bittab[bits-1]) << startbit;
  279.         cursize = size;
  280.     }
  281.     else {
  282.         rv+= agflush(size,value);
  283.         cursize = -1;
  284.         totbits = 0;
  285.     }
  286.     startbit = -1;
  287.     return(rv);
  288. }
  289. /* Basic type subroutines */
  290. int initfloat(void)
  291. {
  292.             allocated = TRUE;
  293.             genfloat(floatexpr());
  294.             return(4);
  295. }
  296. int initlongdouble(void)
  297. {
  298.             allocated = TRUE;
  299.             genlongdouble(floatexpr());
  300.             return(8);
  301. }
  302. int initdouble(void)
  303. {
  304.             allocated = TRUE;
  305.             gendouble(floatexpr());
  306.             return(8);
  307. }
  308. int initchar(void)
  309. {       
  310.             allocated = TRUE;
  311.             return agbits(1,intexpr(0));
  312. }
  313. int initshort(void)
  314. {   
  315.             allocated = TRUE;
  316.             return    agbits(2,intexpr(0));
  317. }
  318. int initlong(void)
  319. {
  320.             allocated = TRUE;
  321.                 return agbits(4,intexpr(0));
  322. }
  323. void getreflvalue(ENODE **node, TYP **tp,int pointer)
  324. {
  325.     SYM *sp;
  326.     ENODE *pnode=0;
  327.     sp = 0;
  328.     while (lastst == star) {
  329.         getsym();
  330.         getreflvalue(&pnode,tp,pointer);
  331.         if ((*tp)->type == bt_pointer) {
  332.             *tp = (*tp)->btp;
  333.             pnode = makenode(en_l_ref,pnode,0);
  334.         }
  335.         else {
  336.             generror(ERR_DEREF,0,0);
  337.         }
  338.         *node = pnode;
  339.         return;
  340.     }
  341.     if (lastst == and && pointer) {
  342.         getsym();
  343.         getreflvalue(&pnode,tp,pointer);
  344.         if (!((*tp)->type == bt_ifunc) && !((*tp)->type == bt_func)) {
  345.             TYP *tp1 = maketype(bt_pointer,4);
  346.             tp1->btp = *tp;
  347.             *tp = tp1;
  348.             pnode = pnode->v.p[0];
  349.         }
  350.         *node = pnode;
  351.         return;
  352.     }
  353.     if (lastst != id) {
  354.         long temp;
  355.         getsym();
  356.         temp = intexpr(tp);
  357.         (*node) = makenode(en_icon,(char *)temp,0);
  358.         return;
  359.     }
  360.     if ((sp = search(lastid,&gsyms)) == 0) {
  361.         gensymerror(ERR_UNDEFINED,lastid);
  362.         return;
  363.     }
  364.     pnode = makenode(en_nacon,(char *)sp->name,0);
  365.     if (pointer)
  366.         pnode = makenode(en_l_ref,pnode,0);
  367.     *tp = sp->tp;
  368.     getsym();
  369.     while (TRUE) {
  370.         long temp;
  371.         switch(lastst) {
  372.         case openbr:    /* build a subscript reference */
  373.                 getsym();
  374.                 temp = intexpr(0);
  375.           if( (*tp)->type != bt_pointer )
  376.             generrorexp(ERR_NOPOINTER,0,skm_closebr);
  377.           else {
  378.             (*tp) = (*tp)->btp;
  379.                     pnode = makenode(en_add,pnode,makenode(en_icon,(char *)(temp*(*tp)->size),0));
  380.                 }
  381.           needpuncexp(closebr,skm_closebr);
  382.           break;
  383.       case pointsto:
  384.         if( (*tp)->type != bt_pointer ) {
  385.             generror(ERR_NOPOINTER,0,0);
  386.                     while (lastst == pointsto || lastst == dot) {
  387.                         getsym();
  388.                         getsym();
  389.                     }
  390.                     break;
  391.                 }
  392.         else {
  393.             (*tp) = (*tp)->btp;
  394.                     pnode = makenode(en_l_ref,pnode,0);
  395.                 }
  396. /*
  397.  *      fall through to dot operation
  398.  */
  399.       case dot:
  400.         getsym();       /* past -> or . */
  401.           if( lastst != id )
  402.             generror(ERR_IDEXPECT,0,0);
  403.           else    {
  404.             sp = search(lastid,&(*tp)->lst);
  405.             if( sp == 0 ) {
  406.                         (*tp) = &stdmatch;
  407.               gensymerror(ERR_UNDEFINED,lastid);
  408.                         getsym();
  409.                         while (lastst == pointsto || lastst == dot) {
  410.                             getsym();
  411.                             getsym();
  412.                         }
  413.                     }
  414.             else    {
  415.                         pnode = makenode(en_add,pnode,makenode(en_icon,(char *)sp->value.i,0));
  416.               (*tp) = sp->tp;
  417.               getsym();       /* past id */
  418.             }
  419.             break;
  420.  
  421.                 }
  422.             case plus:
  423.                 getsym();
  424.                 pnode = makenode(en_add,pnode,makenode(en_icon,(char *)intexpr(0),0));
  425.                 break;
  426.             case minus:
  427.                 getsym();
  428.                 pnode = makenode(en_add,pnode,makenode(en_icon,(char *)(-intexpr(0)),0));
  429.                 break;
  430.             default:
  431.                 *node =pnode;
  432.                 return;
  433.         }
  434.     }
  435. }
  436. int checkrefeval(ENODE *node)
  437. {
  438.     switch(node->nodetype) {
  439.         case en_add:
  440.             return(checkrefeval(node->v.p[0]) || checkrefeval(node->v.p[1]));
  441.         case en_l_ref:
  442.             return 1;
  443.         case en_nacon:
  444.         case en_icon:
  445.             return 0;
  446.         default:
  447.             return 1;
  448.     }
  449. }
  450. int refeval(ENODE *one, ENODE **two)
  451. {
  452.     while (1) {
  453.         switch (one->nodetype) {
  454.             case en_add:
  455.                 return(refeval(one->v.p[0],two) + refeval(one->v.p[1],two));
  456.             case en_icon:
  457.                 return(one->v.i);
  458.             case en_nacon:
  459.                 *two = one;
  460.                 return 0;
  461.             default:
  462.                 return 0;
  463.         }
  464.     }
  465. }
  466. int initref(TYP *tp)
  467. {
  468.     SYM *sp;
  469.     TYP *tp1;
  470.     ENODE *node=0,*node1;
  471.     int ofs;
  472.     allocated = TRUE;
  473.     getreflvalue(&node,&tp1,0);
  474.     if (!node || !checktype(tp,tp1)) {
  475.         genlong(0);
  476.         generror(ERR_REFLVALUE,0,0);
  477.     }
  478.     else {
  479.         if (!checkrefeval(node)) {
  480.             ofs = refeval(node,&node1);
  481.             sp = search(node1->v.sp,&gsyms);
  482.             genref(sp,ofs);
  483.             sp->tp->uflags |= UF_USED;
  484.         }
  485.         else  {
  486.             node1 = makenode(en_l_ref,makenode(en_nacon,locsp->name,0),0);
  487.             node1 = makenode(en_assign,node1,node);
  488.             cppinitinsert(node1);
  489.             genlong(0);
  490.         }
  491.     }
  492.     endinit();
  493.     return 4;
  494. }
  495. int initpointer(void)
  496. {       SYM     *sp;
  497.                 ENODE *node=0,*node1;
  498.                 TYP *tp1;
  499.                 allocated = TRUE;
  500.            if(lastst == sconst) {
  501.                 gen_labref(stringlit(laststr));
  502.                 getsym();
  503.                 }
  504.                 else if (lastst == iconst) {
  505.                                 int temp;
  506.                                 TYP *tp;
  507.                 genlong(temp = intexpr(&tp));
  508.                                 if (temp && (tp->type != bt_pointer && tp->type != bt_ptrfunc))
  509.                                     generror(ERR_NONPORT,0,0);
  510.                 }
  511.                 else {
  512.                     getreflvalue(&node,&tp1,1);
  513.                     if (!node || (tp1->type != bt_pointer && tp1->type != bt_func && tp1->type != bt_ifunc))
  514.                         gensymerror(ERR_NOINIT,locsp->name);
  515.                     else {
  516.                         if (!checkrefeval(node)) {
  517.                             int ofs = refeval(node,&node1);
  518.                             sp = search(node1->v.sp,&gsyms);
  519.                             if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc)
  520.                   genpcref(sp,ofs);
  521.                             else
  522.                   genref(sp,ofs);
  523.                             sp->tp->uflags |= UF_USED;
  524.                         }
  525.                         else  {
  526.                             if (!prm_cplusplus) 
  527.                                 gensymerror(ERR_NOINIT,locsp->name);
  528.                             else {
  529.                                 node1 = makenode(en_l_ref,makenode(en_nacon,locsp->name,0),0);
  530.                                 node1 = makenode(en_assign,node1,node);
  531.                                 cppinitinsert(node1);
  532.                             }
  533.                             genlong(0);
  534.                         }
  535.                      }
  536.                 }
  537.         endinit();
  538.         return 4;       /* pointers are 4 bytes long */
  539. }
  540. int initpointerfunc(void)
  541. {       SYM     *sp;
  542.                 char *nm;
  543.                 allocated = TRUE;
  544.         if(lastst == and)     /* address of a variable */
  545.                 getsym();
  546.         if(lastst != id) {
  547.                                 int temp;
  548.                                 TYP *tp;
  549.                 genlong(temp = intexpr(&tp));
  550.                                 if (temp && (tp->type != bt_pointer && tp->type != bt_ptrfunc))
  551.                                     generror(ERR_NONPORT,0,0);
  552.                             endinit();
  553.                             return(4);
  554.                      }
  555.         else  {
  556.                     if (prm_cplusplus)
  557.                         nm = cppmangle(lastid,locsp->tp);
  558.                     else
  559.                         nm = lastid;
  560.                     if( (sp = gsearch(nm)) == 0)
  561.                          gensymerror(ERR_UNDEFINED,nm);
  562.             else
  563.               getsym();
  564.                 }
  565.         genpcref(sp,0);
  566.                 if (sp)
  567.                     sp->tp->uflags |= UF_USED;
  568.         endinit();
  569.         return 4;       /* pointers are 4 bytes long */
  570. }
  571. /* Finish init */
  572. void endinit(void)
  573. {       if( lastst != comma && lastst != semicolon && lastst != end) {
  574.                 expecttoken(end,0);
  575.                 while( lastst != comma && lastst != semicolon && lastst != end)
  576.                         getsym();
  577.                 }
  578. }