home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / SOURCE / INIT.NEW < prev    next >
Encoding:
Text File  |  1996-08-05  |  15.9 KB  |  652 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. extern int inclass;
  36. extern char *ewclass;
  37. extern int skm_closepa[];
  38.  
  39. static SYM *locsp;
  40. static short cursize;
  41. static short startbit,bits;
  42. static long totbits;
  43. static int allocated;
  44. static ENODE *cpprefhead;
  45. static ENODE *8cppreftail;
  46. static int baseoffs = 0;
  47. void initini(void)
  48. {
  49.     cpprefhead = 0;
  50. }
  51. void initrundown(void)
  52. {
  53.     if (cpprefhead) {
  54.         int lbl = nextlabel++;
  55.         SNODE stmt;
  56.         currentfunc = xalloc(sizeof(SYM));
  57.         currentfunc->tp = maketype(bt_func,0);
  58.         currentfunc->tp->btp = maketype(bt_void,0);
  59.         currentfunc->tp->lst.head = 0;
  60.         currentfunc->intflag = 0;
  61.         stmt.stype = st_expr;
  62.         stmt.next = 0;
  63.         stmt.exp = cpprefhead;
  64.         lc_maxauto = lc_auto = 0;
  65.         cseg();
  66.         gen_label(lbl);
  67.         genfunc(&stmt);
  68.         flush_peep();
  69.         cppseg();
  70.         gen_labref(lbl);
  71.         currentfunc = 0;
  72.         cpprefhead = 0;
  73.     }
  74. }
  75. void cppinitinsert(ENODE *node)
  76. {
  77.     if (!cpprefhead)
  78.         cpprefhead = node;
  79.         cppreftail = &cpprefhead;
  80.     else {
  81.         *cppreftail = makenode(en_void,*cppreftail,node);
  82.         cppreftail = & cppreftail->v.ep2;
  83.     }
  84. }
  85. void doinit(SYM *sp)
  86. /*
  87.  * Handle static variable initialize
  88.  */
  89. {
  90.                 sp->tp->uflags |= UF_DEFINED;
  91.                 allocated = FALSE;
  92.                 baseoffs = 0;
  93.                 totbits = 0;
  94.                 cursize = -1;
  95.                 bits = -1;
  96.                 locsp = sp;
  97.                 if (!sp->absflag) {
  98.                     char buf[100];
  99.                     if (inclass & PF_CLASSDEF)
  100.                         sprintf(buf,"@%s@",newclass);
  101.                     strcat(buf,sp->name);
  102.              gen_strlab(buf);
  103.                 }
  104.                 if (sp->tp->type == bt_iclass) {
  105.                     if (lastst == openpa || lastst == semicolon) {
  106.                         if (sp->tp->type != bt_iclass) {
  107.                             gensymerror(ERR_NOTACLASS,sp->name);
  108.                             expskim(skm_closepa);
  109.                         }
  110.                         else {
  111.                             classinit(sp->tp->sname,sp->tp,1,0);
  112.                         }
  113.                     }
  114.                 }
  115.         else if( lastst != assign) {
  116.                 genstorage(sp->tp->size);
  117.                 }
  118.         else    {
  119.                                 if (sp->absflag) {
  120.                                     generror(ERR_NOINIT,0,skm_declend);
  121.                           return;
  122.                                 }
  123.                 getsym();
  124.                 inittype(sp->tp);
  125.                 }
  126.                 if (sp->tp->size == 0 && !allocated)
  127.                     gensymerror(ERR_ZEROSTORAGE,sp->name);
  128.         endinit();
  129. }
  130.  
  131. int     inittype(TYP *tp)
  132. /*
  133.  * Init for basic types
  134.  */
  135. {       int     nbytes;
  136.         switch(tp->type) {
  137.  
  138.                                 case bt_float:
  139.                                                 nbytes = initfloat();
  140.                                                 break;
  141.                                 case bt_longdouble:
  142.                                                 nbytes = initlongdouble();
  143.                                                 break;
  144.                                 case bt_double:
  145.                                                 nbytes = initdouble();
  146.                                                 break;
  147.                 case bt_char:
  148.                 case bt_unsignedchar:
  149.                         nbytes = initchar();
  150.                         break;
  151.                 case bt_short:
  152.                 case bt_unsignedshort:
  153.                 case bt_enum:
  154.                         nbytes = initshort();
  155.                         break;
  156.                 case bt_ptrfunc:
  157.                         nbytes = initpointerfunc();
  158.                         break;
  159.                                 case bt_iclass:
  160.                                                 nbytes = classinit(0,sp->tp,1,baseoffs);
  161.                                                 break;
  162.                 case bt_pointer:
  163.                         if( tp->val_flag)
  164.                                 nbytes = initarray(tp);
  165.                         else
  166.                                 nbytes = initpointer();
  167.                         break;
  168.                                 case bt_ref:
  169.                                                 nbytes = initref(tp->btp);
  170.                                                 break;
  171.                 case bt_long:
  172.                 case bt_matchall:
  173.                 case bt_unsigned:
  174.                         nbytes = initlong();
  175.                         break;
  176.                 case bt_struct:
  177.                         nbytes = initstruct(tp);
  178.                         break;
  179.                 default:
  180.                                               gensymerror(ERR_NOINIT,locsp->name);
  181.                         nbytes = 0;
  182.                 }
  183.                 baseoffs+=nbytes;
  184.         return nbytes;
  185. }
  186.  
  187. int initarray(TYP *tp)
  188. /*
  189.  * Init for arrays
  190.  */
  191. {       int     nbytes;
  192.         char    *p;
  193.                 int needend = FALSE;
  194.         nbytes = 0;
  195.         if( lastst == begin) {
  196.                 getsym();               /* skip past the brace */
  197.                                 needend = TRUE;
  198.                                 if (tp->btp->type == bt_char && lastst == sconst)
  199.                                     goto grabchar;
  200.                 while(lastst != end) {
  201.                         nbytes += inittype(tp->btp);
  202.                         if( lastst == comma)
  203.                                 getsym();
  204.                         else if( lastst != end) {
  205.                                 expecttoken(end,0);
  206.                                                                 break;
  207.                                                 }
  208.                         }
  209.                 getsym();               /* skip closing brace */
  210.                 }
  211.         else { 
  212. grabchar:        
  213.                         allocated = TRUE;
  214.                         if( lastst == sconst && tp->btp->type == bt_char) {
  215.                 nbytes = strlen(laststr) + 1;
  216.                 p = laststr;
  217.                 while( *p )
  218.                         genbyte(*p++);
  219.                 genbyte(0);
  220.                 getsym();
  221.                                 if (needend)
  222.                                     needpunc(end,skm_declend);
  223.                 }
  224.             else generror(ERR_PUNCT,semicolon,0);
  225.                 }
  226.         if( nbytes < tp->size) {
  227.                                 nl();
  228.                                 if (tp->btp->type == bt_iclass) {
  229.                                     classinit(tp->btp->sname,tp->btp,tp->size-nbytes/tp->btp->size,nbytes/tp->btp->size+baseoffs);
  230.                                 }
  231.                 genstorage( tp->size - nbytes);
  232.                 nbytes = tp->size;
  233.                 }
  234.         else if( tp->size != 0 && nbytes > tp->size)
  235.                 generror(ERR_INITSIZE,0,0);    /* too many initializers */
  236.         return nbytes;
  237. }
  238.  
  239. int initstruct(TYP *tp)
  240. /*
  241.  * Init for structures
  242.  */
  243. {       SYM     *sp;
  244.         int     nbytes;
  245.         needpunc(begin,0);
  246.         nbytes = 0;
  247.         sp = tp->lst.head;      /* start at top of symbol table */
  248.         while(sp != 0) {
  249.                                 startbit = sp->tp->startbit;
  250.                                 bits = sp->tp->bits;
  251.                 while(nbytes < sp->value.i) {     /* align properly */ 
  252.                         nbytes++;
  253.                                               genbyte(0);
  254.                                 }
  255.                 nbytes += inittype(sp->tp);
  256.                 if( lastst == comma)
  257.                         getsym();
  258.                 else if(lastst == end)
  259.                         break;
  260.                 else
  261.                         expecttoken(end,0);
  262.                 sp = sp->next;
  263.                 }
  264.                 nbytes += agbits(-1,0);
  265.         if( nbytes < tp->size) {
  266.                     genstorage(tp->size - nbytes);
  267.                     while (sp) {
  268.                         TYP *tp = sp->tp;
  269.                         while (tp == bt_pointer && tp->val_flag)
  270.                         if (tp->type == bt_iclass) {
  271.                              nbytes+=classinitarray(sp->tp->sname,sp->tp,baseofs+nbytes);
  272.                         else
  273.                             nbytes += tp->size;
  274.                     }
  275.                 }
  276.         needpunc(end,skm_declend);
  277.         return tp->size;
  278. }
  279.  
  280. int agflush(int size, long val)
  281. {
  282.     switch (size) {
  283.         case 1:
  284.             genbyte(val);
  285.             return 1;
  286.         case 2:
  287.             genword(val);
  288.             return 2;
  289.         case 4:
  290.             genlong(val);
  291.             return 4;
  292.         default:
  293.             return 0;
  294.     }
  295. }
  296. /* Aggregate bits */
  297. int agbits(int size, long value)
  298. {
  299.     long rv = 0;
  300.     if (cursize != -1 && (size != cursize || bits == -1 || (bits != -1 &&startbit==0)))
  301.         rv = agflush(cursize,totbits);
  302.     if (bits != -1) {
  303.         totbits |= (value & bittab[bits-1]) << startbit;
  304.         cursize = size;
  305.     }
  306.     else {
  307.         rv+= agflush(size,value);
  308.         cursize = -1;
  309.         totbits = 0;
  310.     }
  311.     startbit = -1;
  312.     return(rv);
  313. }
  314. /* Basic type subroutines */
  315. int initfloat(void)
  316. {
  317.             allocated = TRUE;
  318.             genfloat(floatexpr());
  319.             return(4);
  320. }
  321. int initlongdouble(void)
  322. {
  323.             allocated = TRUE;
  324.             genlongdouble(floatexpr());
  325.             return(8);
  326. }
  327. int initdouble(void)
  328. {
  329.             allocated = TRUE;
  330.             gendouble(floatexpr());
  331.             return(8);
  332. }
  333. int initchar(void)
  334. {       
  335.             allocated = TRUE;
  336.             return agbits(1,intexpr(0));
  337. }
  338. int initshort(void)
  339. {   
  340.             allocated = TRUE;
  341.             return    agbits(2,intexpr(0));
  342. }
  343. int initlong(void)
  344. {
  345.             allocated = TRUE;
  346.                 return agbits(4,intexpr(0));
  347. }
  348. void getreflvalue(ENODE **node, TYP **tp,int pointer)
  349. {
  350.     SYM *sp;
  351.     ENODE *pnode=0;
  352.     sp = 0;
  353.     while (lastst == star) {
  354.         getsym();
  355.         getreflvalue(&pnode,tp,pointer);
  356.         if ((*tp)->type == bt_pointer) {
  357.             *tp = (*tp)->btp;
  358.             pnode = makenode(en_l_ref,pnode,0);
  359.         }
  360.         else {
  361.             generror(ERR_DEREF,0,0);
  362.         }
  363.         *node = pnode;
  364.         return;
  365.     }
  366.     if (lastst == and && pointer) {
  367.         getsym();
  368.         getreflvalue(&pnode,tp,pointer);
  369.         if (!((*tp)->type == bt_ifunc) && !((*tp)->type == bt_func)) {
  370.             TYP *tp1 = maketype(bt_pointer,4);
  371.             tp1->btp = *tp;
  372.             *tp = tp1;
  373.             pnode = pnode->v.p[0];
  374.         }
  375.         *node = pnode;
  376.         return;
  377.     }
  378.     if (lastst != id) {
  379.         long temp;
  380.         getsym();
  381.         temp = intexpr(tp);
  382.         (*node) = makenode(en_icon,(char *)temp,0);
  383.         return;
  384.     }
  385.     if ((sp = search(lastid,&gsyms)) == 0) {
  386.         gensymerror(ERR_UNDEFINED,lastid);
  387.         return;
  388.     }
  389.     pnode = makenode(en_nacon,(char *)sp->name,0);
  390.     if (pointer)
  391.         pnode = makenode(en_l_ref,pnode,0);
  392.     *tp = sp->tp;
  393.     getsym();
  394.     while (TRUE) {
  395.         long temp;
  396.         switch(lastst) {
  397.         case openbr:    /* build a subscript reference */
  398.                 getsym();
  399.                 temp = intexpr(0);
  400.           if( (*tp)->type != bt_pointer )
  401.             generrorexp(ERR_NOPOINTER,0,skm_closebr);
  402.           else {
  403.             (*tp) = (*tp)->btp;
  404.                     pnode = makenode(en_add,pnode,makenode(en_icon,(char *)(temp*(*tp)->size),0));
  405.                 }
  406.           needpuncexp(closebr,skm_closebr);
  407.           break;
  408.       case pointsto:
  409.         if( (*tp)->type != bt_pointer ) {
  410.             generror(ERR_NOPOINTER,0,0);
  411.                     while (lastst == pointsto || lastst == dot) {
  412.                         getsym();
  413.                         getsym();
  414.                     }
  415.                     break;
  416.                 }
  417.         else {
  418.             (*tp) = (*tp)->btp;
  419.                     pnode = makenode(en_l_ref,pnode,0);
  420.                 }
  421. /*
  422.  *      fall through to dot operation
  423.  */
  424.       case dot:
  425.         getsym();       /* past -> or . */
  426.           if( lastst != id )
  427.             generror(ERR_IDEXPECT,0,0);
  428.           else    {
  429.             sp = search(lastid,&(*tp)->lst);
  430.             if( sp == 0 ) {
  431.                         (*tp) = &stdmatch;
  432.               gensymerror(ERR_UNDEFINED,lastid);
  433.                         getsym();
  434.                         while (lastst == pointsto || lastst == dot) {
  435.                             getsym();
  436.                             getsym();
  437.                         }
  438.                     }
  439.             else    {
  440.                         pnode = makenode(en_add,pnode,makenode(en_icon,(char *)sp->value.i,0));
  441.               (*tp) = sp->tp;
  442.               getsym();       /* past id */
  443.             }
  444.             break;
  445.  
  446.                 }
  447.             case plus:
  448.                 getsym();
  449.                 pnode = makenode(en_add,pnode,makenode(en_icon,(char *)intexpr(0),0));
  450.                 break;
  451.             case minus:
  452.                 getsym();
  453.                 pnode = makenode(en_add,pnode,makenode(en_icon,(char *)(-intexpr(0)),0));
  454.                 break;
  455.             default:
  456.                 *node =pnode;
  457.                 return;
  458.         }
  459.     }
  460. }
  461. int checkrefeval(ENODE *node)
  462. {
  463.     switch(node->nodetype) {
  464.         case en_add:
  465.             return(checkrefeval(node->v.p[0]) || checkrefeval(node->v.p[1]));
  466.         case en_l_ref:
  467.             return 1;
  468.         case en_nacon:
  469.         case en_icon:
  470.             return 0;
  471.         default:
  472.             return 1;
  473.     }
  474. }
  475. int refeval(ENODE *one, ENODE **two)
  476. {
  477.     while (1) {
  478.         switch (one->nodetype) {
  479.             case en_add:
  480.                 return(refeval(one->v.p[0],two) + refeval(one->v.p[1],two));
  481.             case en_icon:
  482.                 return(one->v.i);
  483.             case en_nacon:
  484.                 *two = one;
  485.                 return 0;
  486.             default:
  487.                 return 0;
  488.         }
  489.     }
  490. }
  491. int initref(TYP *tp)
  492. {
  493.     SYM *sp;
  494.     TYP *tp1;
  495.     ENODE *node=0,*node1;
  496.     int ofs;
  497.     allocated = TRUE;
  498.     getreflvalue(&node,&tp1,0);
  499.     if (!node || !checktype(tp,tp1)) {
  500.         genlong(0);
  501.         generror(ERR_REFLVALUE,0,0);
  502.     }
  503.     else {
  504.         if (!checkrefeval(node)) {
  505.             ofs = refeval(node,&node1);
  506.             sp = search(node1->v.sp,&gsyms);
  507.             genref(sp,ofs);
  508.             sp->tp->uflags |= UF_USED;
  509.         }
  510.         else  {
  511.             node1 = makenode(en_l_ref,makenode(en_nacon,locsp->name,0),0);
  512.             node1 = makenode(en_assign,node1,node);
  513.             cppinitinsert(node1);
  514.             genlong(0);
  515.         }
  516.     }
  517.     endinit();
  518.     return 4;
  519. }
  520. int initpointer(void)
  521. {       SYM     *sp;
  522.                 ENODE *node=0,*node1;
  523.                 TYP *tp1;
  524.                 allocated = TRUE;
  525.            if(lastst == sconst) {
  526.                 gen_labref(stringlit(laststr));
  527.                 getsym();
  528.                 }
  529.                 else if (lastst == iconst) {
  530.                                 int temp;
  531.                                 TYP *tp;
  532.                 genlong(temp = intexpr(&tp));
  533.                                 if (temp || (tp->type != bt_pointer && tp->type != bt_ptrfunc))
  534.                                     generror(ERR_NONPORT,0,0);
  535.                 }
  536.                 else {
  537.                     getreflvalue(&node,&tp1,1);
  538.                     if (!node || (tp1->type != bt_pointer && tp1->type != bt_func && tp1->type != bt_ifunc))
  539.                         gensymerror(ERR_NOINIT,locsp->name);
  540.                     else {
  541.                         if (!checkrefeval(node)) {
  542.                             int ofs = refeval(node,&node1);
  543.                             sp = search(node1->v.sp,&gsyms);
  544.                             if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc)
  545.                   genpcref(sp,ofs);
  546.                             else
  547.                   genref(sp,ofs);
  548.                             sp->tp->uflags |= UF_USED;
  549.                         }
  550.                         else  {
  551.                             if (!prm_cplusplus) 
  552.                                 gensymerror(ERR_NOINIT,locsp->name);
  553.                             else {
  554.                                 node1 = makenode(en_l_ref,makenode(en_nacon,locsp->name,0),0);
  555.                                 node1 = makenode(en_assign,node1,node);
  556.                                 cppinitinsert(node1);
  557.                             }
  558.                             genlong(0);
  559.                         }
  560.                      }
  561.                 }
  562.         endinit();
  563.         return 4;       /* pointers are 4 bytes long */
  564. }
  565. int classinit(char *name,TYP *tp,int elms,int offs)
  566. {
  567.     char buf[100];
  568.     TYPE *tp1;
  569.     SYM *sp;
  570.     ENODE *pnode;
  571.     if (!name) {
  572.         if (lastst == id) {
  573.             name = lastid;
  574.             getsym();
  575.         }              
  576.     }
  577.     if (lastst == openpa) {
  578.         tp1 = gatherparms(&pnode);
  579.     }
  580.     else {
  581.         pnode = 0;
  582.         tp1 = maketype(bt_func,0);
  583.         tp1->btp = &stdint;
  584.         tp1->lst.head = -1;;
  585.         tp1->bits = -1;
  586.         tp1->startbit = -1;
  587.         tp1->uflags = UF_DEFINED | UF_USED;
  588.     }
  589.     sp = funcovermatch(buf,newclass,tp1);
  590.     if (!sp) {
  591.         if (tp->lst.head != -1)
  592.             gensymerror(ERR_PREDEFSTRUCT,name);
  593.     }
  594.     else {
  595.         buf[0] = '@';
  596.         strcpy(buf+1,newclass);
  597.         strcat(buf,sp->name);
  598.         cppinitinsert(callctr(makenode(en_nacon,locsp->name,0),buf,pnode,elms));
  599.     }
  600. }
  601. int classinitarray(char *name,TYP *tp,int offs)
  602. {
  603.     if (tp->type == bt_iclass)
  604.         classinit(tp,1,offs);
  605.     else {
  606.         int sz = tp->size;
  607.         while (tp->type == bt_pointer)
  608.             tp=tp->btp;
  609.         sz = sz/tp->size;
  610.         classinit(tp,sz,offs);
  611.     }
  612. }
  613.  
  614. int initpointerfunc(void)
  615. {       SYM     *sp;
  616.                 char *nm;
  617.                 allocated = TRUE;
  618.         if(lastst == and)     /* address of a variable */
  619.                 getsym();
  620.         if(lastst != id) {
  621.                                 int temp;
  622.                                 TYP *tp;
  623.                 genlong(temp = intexpr(&tp));
  624.                                 if (temp || (tp->type != bt_pointer && tp->type != bt_ptrfunc))
  625.                                     generror(ERR_NONPORT,0,0);
  626.                             endinit();
  627.                             return(4);
  628.                      }
  629.         else  {
  630.                     if (prm_cplusplus)
  631.                         nm = cppmangle(lastid,newclass,locsp->tp);
  632.                     else
  633.                         nm = lastid;
  634.                     if( (sp = gsearch(nm)) == 0)
  635.                          gensymerror(ERR_UNDEFINED,nm);
  636.             else
  637.               getsym();
  638.                 }
  639.         genpcref(sp,0);
  640.                 if (sp)
  641.                     sp->tp->uflags |= UF_USED;
  642.         endinit();
  643.         return 4;       /* pointers are 4 bytes long */
  644. }
  645. /* Finish init */
  646. void endinit(void)
  647. {       if( lastst != comma && lastst != semicolon && lastst != end) {
  648.                 expecttoken(end,0);
  649.                 while( lastst != comma && lastst != semicolon && lastst != end)
  650.                         getsym();
  651.                 }
  652. }