home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / SOURCE / EXPR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-08  |  71.2 KB  |  2,035 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. #include                "list.h"
  27. /* Default types */
  28. TYP             stdint = { bt_long, 0, UF_DEFINED | UF_USED,0, 0,-1, -1, 4, {0, 0}, 0, 0,0 };
  29. TYP             stdfloat = { bt_float, 0, UF_DEFINED | UF_USED,0, 0,-1, -1, 8, {0, 0}, 0, 0,0 };
  30. TYP             stddouble = { bt_double, 0, 0,0,0, -1, -1, 8, {0, 0}, 0, 0,0 };
  31. TYP             stduns = { bt_unsigned, 0, 0,0, 0,-1, -1, 4, {0, 0}, 0, 0,0 };
  32. TYP             stdvoid = { bt_matchall, 0, 0 ,0, 0,-1, -1, 4, {0, 0}, 0, 0,0 };
  33. TYP             stdmatch = { bt_matchall, 0, UF_DEFINED | UF_USED,0, 0,-1, -1, 4, {0, 0}, &stdvoid, 0,0 };
  34. TYP             stdchar = {bt_char, 0, 0,0,0,-1, -1, 1, {0, 0}, 0, 0,0 };
  35. TYP             stdstring = {bt_pointer, 0, 0,0,0,-1, -1, 4, {0, 0}, &stdchar, 0,0};
  36. TYP             stdfunc = {bt_func, 1, UF_DEFINED | UF_USED,0,0,-1, -1, 0, {0, 0}, &stdint, 0,0};
  37. TYP                            stdlongdouble = {bt_longdouble,0,0,0,0,-1,-1,LDBLSIZE,{0,0},0,0,0 };
  38. extern TYP      *head;          /* shared with decl */
  39. extern TABLE    tagtable;
  40. extern char declid[100];
  41. extern int goodcode;
  42. extern int prm_cplusplus;
  43.  
  44. int skm_closepa[] = { closepa, comma, semicolon, end, 0 };
  45. int skm_closebr[] = { closebr, comma, openbr, semicolon, end, 0 };
  46. static SYM *lastsym;
  47. static int globaldref = 0;
  48. static char regname[] = "processor reg" ;
  49. static char *nm = 0;
  50. static char undefname[] = { "UNDEFGEN" } ;
  51. static TYP *asntyp = 0;
  52. /*
  53.  *      expression evaluation
  54.  *
  55.  *      this set of routines builds a parse tree for an expression.
  56.  *      no code is generated for the expressions during the build,
  57.  *      this is the job of the codegen module. for most purposes
  58.  *      expression() is the routine to call. it will allow all of
  59.  *      the C operators. for the case where the comma operator is
  60.  *      not valid (function parameters for instance) call exprnc().
  61.  *
  62.  *      each of the routines returns a pointer to a describing type
  63.  *      structure. each routine also takes one parameter which is a
  64.  *      pointer to an expression node by reference (address of pointer).
  65.  *      the completed expression is returned in this pointer. all
  66.  *      routines return either a pointer to a valid type or NULL if
  67.  *      the hierarchy of the next operator is too low or the next
  68.  *      symbol is not part of an expression.
  69.  */
  70.  
  71. void exprini(void)
  72. {
  73.     globaldref = 0;
  74.     asntyp = 0;
  75. }
  76. ENODE    *makenode(enum e_node nt, char *v1, char *v2)
  77. /*
  78.  *      build an expression node with a node type of nt and values
  79.  *      v1 and v2.
  80.  */
  81. {       ENODE    *ep;
  82.         ep = xalloc(sizeof(ENODE));
  83.         ep->nodetype = nt;
  84.                 ep->cflags = 0;
  85.         ep->v.p[0] = v1;
  86.         ep->v.p[1] = v2;
  87.         return ep;
  88. }
  89.  
  90. TYP *deref(ENODE **node, TYP *tp)
  91. /*
  92.  *      build the proper dereference operation for a node using the
  93.  *      type pointer tp.
  94.  */
  95. {
  96.                 ENODE *onode = *node;
  97.                 switch( tp->type ) {
  98.                                 case bt_double:
  99.                         *node = makenode(en_doubleref,*node,0);
  100.                         break;
  101.                                 case bt_longdouble:
  102.                         *node = makenode(en_longdoubleref,*node,0);
  103.                         break;
  104.                                 case bt_float:
  105.                         *node = makenode(en_floatref,*node,0);
  106.                         break;
  107.                                 case bt_unsignedchar:
  108.                         *node = makenode(en_ub_ref,*node,0);
  109.                         break;
  110.                                 case bt_unsignedshort:
  111.                         *node = makenode(en_uw_ref,*node,0);
  112.                         break;
  113.                 case bt_char:
  114.                         *node = makenode(en_b_ref,*node,0);
  115.                         break;
  116.                 case bt_short:
  117.                 case bt_enum:
  118.                         *node = makenode(en_w_ref,*node,0);
  119.                         break;
  120.                 case bt_unsigned:
  121.                         *node = makenode(en_ul_ref,*node,0);
  122.                                                 break;
  123.                 case bt_long:
  124.                 case bt_matchall:
  125.                 case bt_pointer:
  126.                                 case bt_ptrfunc:
  127.                                 case bt_ref:
  128.                         *node = makenode(en_l_ref,*node,0);
  129.                         break;
  130.                 default:
  131.                         generror(ERR_DEREF,0,0);
  132.                         break;
  133.                 }
  134.                 (*node)->cflags = onode->cflags;
  135.         return tp;
  136. }
  137.  
  138. TYP     *nameref(ENODE **node)
  139. /*
  140.  *      nameref will build an expression tree that references an
  141.  *      identifier. if the identifier is not in the global or
  142.  *      local symbol table then a look-ahead to the next character
  143.  *      is done and if it indicates a function call the identifier
  144.  *      is coerced to an external function name. non-value references
  145.  *      generate an additional level of indirection.
  146.  *
  147.  *            nameref now handles primary function parameter gathering
  148.  *            primary will still do it as well, in case the function name is
  149.  *            put in parenthesis...
  150.  */
  151. {       SYM             *sp;
  152.         TYP             *tp,*tp1;
  153.                 ENODE *pnode=0;
  154.                 int fn = FALSE;
  155.                 char buf[100];
  156.                 strcpy(buf,lastid);
  157.                 getsym();
  158.                 if (lastst == openpa) {
  159.                     fn = TRUE;
  160.                     getsym();
  161.                     tp1 = gatherparms(&pnode);
  162.                     sp = funcovermatch(buf,tp1);
  163.                     if (sp)
  164.                         tp1->sname = nm = sp->name;
  165.                     else
  166.                         if (prm_cplusplus)
  167.                             tp1->sname = nm = cppmangle(buf,tp1);
  168.                         else
  169.                             tp1->sname = nm = litlate(buf);
  170.                 }
  171.                 else {
  172.                     nm = litlate(buf);
  173.                     sp = gsearch(nm);
  174.                 }
  175.         if( sp == 0 ) {
  176.                 if (fn) {
  177.                                                 if (prm_cplusplus) 
  178.                                                     gensymerror(ERR_NOFUNCMATCH,nm);
  179.                                                 else
  180.                                                     gensymerror(ERR_NOPROTO,nm);
  181.                         ++global_flag;
  182.                                                 sp = xalloc(sizeof(SYM));
  183.                                 sp->name = litlate(nm);
  184.                                                 sp->tp = &stdfunc;
  185. #ifdef i386
  186.                         sp->storage_class = sc_externalfunc;
  187. #else
  188.                         sp->storage_class = sc_external;
  189. #endif
  190.                                                 sp->extflag = TRUE;
  191.                         insert(sp,&gsyms);
  192.                         --global_flag;
  193.                         *node = makenode(en_nacon,sp->name,0);
  194.                                                 parmlist(&pnode,tp1,0);
  195.                         tp = &stdint;
  196.                           *node = makenode(en_fcall,*node,pnode);
  197.                                                 goodcode |= GF_ASSIGN;
  198.                         }
  199.                 else    {
  200.                                                 if (prm_cplusplus && asntyp && asntyp->type == bt_ptrfunc) {
  201.                                                     sp = funcovermatch(lastid,asntyp);
  202.                                                     if (sp)
  203.                                                         goto foundsp;
  204.                                                 }
  205.                                                 sp = xalloc(sizeof(SYM));
  206.                                 sp->name = nm;
  207.                         sp->tp = tp = &stdmatch;
  208.                                                 sp->storage_class = sc_external;
  209.                                                 insert(sp,&lsyms);
  210.                                                 *node = makenode(en_nacon,undefname,0);
  211.                                                 gensymerror(ERR_UNDEFINED,nm);
  212.                         tp = deref(node,tp);
  213.                         }
  214.                 }
  215.         else    {
  216. foundsp:
  217.                                 sp->tp->uflags |= UF_USED;
  218.                 if( (tp = sp->tp) == 0 ) {
  219.                         tp = &stdmatch;
  220.                                                 *node = makenode(en_nacon,undefname,0);
  221.                                                 gensymerror(ERR_UNDEFINED,nm);
  222.                         tp = deref(node,tp);
  223.                         return tp;       /* guard against untyped entries */
  224.                         }
  225.                 switch( sp->storage_class ) {
  226.                         case sc_static:
  227.                         case sc_global:
  228.                         case sc_external:
  229.                         case sc_externalfunc:
  230.                                                 case sc_abs:
  231.                                                                 sp->extflag = TRUE;
  232.                                                                 if (fn) {
  233.                                                                     if (sp->tp->type == bt_ptrfunc)
  234.                                         *node = makenode(en_nacon,sp->name,0);
  235.                                                                     else
  236.                                         *node = makenode(en_napccon,sp->name,0);
  237. isfunc:
  238.                                                                     if (sp->tp->type != bt_ptrfunc && sp->tp->type != bt_func && sp->tp->type != bt_ifunc)
  239.                                                                         generror(ERR_MISMATCH,0,0);
  240.                                                                     if (sp->tp->type == bt_ptrfunc)
  241.                                                                         tp = deref(node,tp);
  242.                                                                     if (prm_cplusplus && !strcmp(buf,"main"))
  243.                                                                         generror(ERR_NOMAIN,0,0);
  244.                                                                     parmlist(&pnode,tp1,sp->tp);
  245.                                   tp = tp->btp;
  246.                                                                     if (sp->intflag)
  247.                                         *node = makenode(en_intcall,*node,pnode);
  248.                                                                     else
  249.                                                                     if (tp->type == bt_union || tp->type == bt_struct) {
  250.                                           *node = makenode(en_fcallb,*node,pnode);
  251.                                                                         (*node)->size = tp->size;
  252.                                                                     }
  253.                                                                     else
  254.                                           *node = makenode(en_fcall,*node,pnode);
  255.                                                                     if (tp)
  256.                                                                         (*node)->cflags = tp->cflags;
  257.                                                                     goodcode |= GF_ASSIGN;
  258.                                                                 }
  259.                                                                 else
  260.                                                                     if (sp->absflag)
  261.                                         *node = makenode(en_absacon,(char *)sp->addr,0);
  262.                                                                     else
  263.                                                                         if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc) {
  264.                                                                             fn = TRUE;
  265.                                             *node = makenode(en_napccon,sp->name,0);
  266.                                                                         }
  267.                                                                         else
  268.                                             *node = makenode(en_nacon,sp->name,0);
  269.                                 break;
  270.                         case sc_const:
  271.                                 *node = makenode(en_icon,(char *)sp->value.i,0);
  272.                                 break;
  273.                         default:        /* auto and any errors */
  274.                                 if( sp->storage_class != sc_auto && sp->storage_class != sc_autoreg) {
  275.                                         gensymerror(ERR_ILLCLASS2,sp->name);
  276.                                                                                 tp = 0;
  277.                                                                 }
  278.                                                                 else {
  279.                                                                      if (sp->storage_class == sc_auto)
  280.                                         *node = makenode(en_autocon,(char *)sp->value.i,0);
  281.                                                                     else if (sp->storage_class == sc_autoreg)
  282.                                         *node = makenode(en_autoreg,(char *)sp->value.i,0);
  283.                                                                     if (fn)
  284.                                                                         goto isfunc;
  285.                                                                 }
  286.                                 break;
  287.                         }
  288.                                 (*node)->cflags = tp->cflags;
  289.                   if(!fn && tp && tp->val_flag == 0)
  290.                            tp = deref(node,tp);
  291.                                 if (tp->type == bt_ref) {
  292.                                                 tp = tp->btp;
  293.                                                 tp = deref(node,tp);
  294.                                 }
  295.                                                 
  296.                 }
  297.                 lastsym = sp;
  298.         return tp;
  299. }
  300.  
  301. void promote_type(TYP *typ, ENODE **node)
  302. /*
  303.  * Type promotion for casts and function args 
  304.  */
  305. {
  306.         switch (typ->type) {
  307.             case bt_char:
  308.                     *node = makenode(en_cb,*node,0);
  309.                             break;
  310.             case bt_unsignedchar:
  311.                     *node = makenode(en_cub,*node,0);
  312.                     break;
  313.             case bt_enum:
  314.             case bt_short:
  315.                   *node = makenode(en_cw,*node,0);
  316.                   break;
  317.             case bt_unsignedshort:
  318.                   *node = makenode(en_cuw,*node,0);
  319.                     break;
  320.           case bt_long:
  321.                 *node = makenode(en_cl,*node,0);
  322.                     break;
  323.             case bt_unsigned:
  324.                     *node = makenode(en_cul,*node,0);
  325.                   break;
  326.             case bt_float:
  327.                   *node = makenode(en_cf,*node,0);
  328.                     break;
  329.             case bt_double:
  330.                     *node = makenode(en_cd,*node,0);
  331.                     break;
  332.             case bt_longdouble:
  333.                     *node = makenode(en_cld,*node,0);
  334.                     break;
  335.             default:
  336.                     *node = makenode(en_cp,*node,0);
  337.                     break;
  338.         }
  339.     (*node)->cflags = typ->cflags;
  340. }
  341. TYP *gatherparms( ENODE **node)
  342. {
  343.     ENODE *ep1 = 0,*ep2=0,**ep3 = &ep1;
  344.     TABLE tbl;
  345.     SYM **t = &tbl.head,*newt;
  346.     TYP *tp;
  347.     int ogc = goodcode;
  348.     tbl.tail = tbl.head = 0;
  349.     goodcode |= DF_FUNCPARMS;
  350.     if (lastst == closepa) {
  351.         if (prm_cplusplus)
  352.             tbl.head=tbl.tail=(SYM *)-1;
  353.         else
  354.             tbl.head=tbl.tail = 0;
  355.     }
  356.     else if (lastst == kw_void)
  357.         tbl.head = tbl.tail = (SYM *)-1;
  358.     else
  359.       while (lastst != closepa) {
  360.             tp = exprnc(&ep2);
  361.             if (!tp) {
  362.                 generror(ERR_EXPREXPECT,0,0);
  363.                 break;
  364.             }
  365.             ep2->cflags = tp->cflags;
  366.             newt = xalloc(sizeof(SYM));
  367.             newt->tp = tp;
  368.             newt->next = 0;
  369.             newt->name = 0;
  370.             *t = newt;
  371.             t = &newt->next;
  372.             tbl.tail = newt;
  373.             *ep3 = makenode(en_void,ep2,0);
  374.             ep3 = &(*ep3)->v.p[1];
  375.             if (lastst == comma)
  376.                 getsym();
  377.         }
  378.     needpunc(closepa,skm_closepa);
  379.     tp = maketype(bt_func,0);
  380.     tp->btp = &stdint;
  381.     tp->lst = tbl;
  382.     tp->bits = -1;
  383.     tp->startbit = -1;
  384.     tp->uflags = UF_DEFINED | UF_USED;
  385.     goodcode = ogc;
  386.     *node = ep1;
  387.     return tp;
  388. }
  389. void checkparmconst(TYP *tp, TYP *tpi)
  390. {
  391.     if (tpi->type != bt_pointer && tpi->type != bt_ref)
  392.         return;
  393.     while ((tp->type == bt_pointer || tp->type == bt_ref)&& !tp->val_flag && (!tpi || tpi->type == bt_pointer || tpi->type == bt_ref)) {
  394.         if ((tp->cflags & DF_CONST) && (!tpi || !(tpi->cflags & DF_CONST)))
  395.             generror(ERR_MODCONS,0,0);
  396.         tp = tp->btp;
  397.         tpi = tpi->btp;
  398.     }
  399.     if ((tp->cflags & DF_CONST) && (!tpi || !(tpi->cflags & DF_CONST)))
  400.         generror(ERR_MODCONS,0,0);
  401. }
  402. void parmlist(ENODE **node, TYP *tpi, TYP *tp)
  403. /*
  404.  *      parmlist will build a list of parameter expressions in
  405.  *      a function call and return a pointer to the last expression
  406.  *      parsed. since parameters are generally pushed from right
  407.  *      to left we get just what we asked for...  parmlist also checks
  408.  *            types if there was a prototype and sticks the result type as the
  409.  *             first element of the paramter list
  410.  */
  411. {       ENODE    *ep1=0,*ep2=0,*ep3=*node;
  412.                 SYM *spi=tpi->lst.head,*sp=0;
  413.                 TYP *tp2;
  414.                 int matching = FALSE;
  415.                 if (tp)
  416.                     sp=tp->lst.head;
  417.                 if (tp && !sp)
  418.                     gensymerror(ERR_NOPROTO,tpi->sname);
  419.                 
  420.                     if (!prm_cplusplus && sp && sp->tp->type != bt_ellipse)
  421.                             matching = TRUE;
  422.                     while (TRUE) {
  423.                             ep2 = ep3->v.p[0];
  424.                             ep3 = ep3->v.p[1];
  425.                             if (!spi || spi == (SYM *)-1){
  426.                                 if (sp == (SYM *) -1)
  427.                                     break;
  428.                                 if (sp && sp->tp->type != bt_ellipse) 
  429.                                     if (!sp->defalt) 
  430.                                         genfuncerror(ERR_CALLLENSHORT,tpi->sname,0);
  431.                                     else
  432.                                         while (sp) {
  433.                                             if (sp->tp->val_flag && (sp->tp->type == bt_struct || sp->tp->type == bt_union)) {
  434.                                                 ep1 = makenode(en_stackblock,sp->defalt,ep1);
  435.                                                 sp->defalt->size = sp->tp->size;
  436.                                             }
  437.                                             else
  438.                                        ep1 = makenode(en_void,sp->defalt,ep1);
  439.                                             sp = sp->next;
  440.                                         }
  441.                                 break;
  442.                             }
  443.                             else if (matching) {
  444.                                 if (!sp || sp == (SYM *)-1) {
  445.                                     genfuncerror(ERR_CALLLENLONG,tpi->sname,0);
  446.                                     break;
  447.                                 }
  448.                                 else {
  449.                                     checkparmconst(spi->tp,sp->tp);
  450.                                     if (!checktype(spi->tp,sp->tp))
  451.                                       if (isscalar(sp->tp) && isscalar(spi->tp))
  452.                                             promote_type(sp->tp,&ep2);
  453.                                         else
  454.                                             if (sp->tp->type == bt_pointer) {
  455.                                                 if (ep2->nodetype == en_icon) {
  456.                                                     if (ep2->v.i != 0)
  457.                                                         generror(ERR_NONPORT,0,0);
  458.                                                 }
  459.                                                 else if (spi->tp->type != bt_pointer)
  460.                                                         genfuncerror(ERR_CALLMISMATCH,tpi->sname,sp->name);
  461.                                              }
  462.                                             else genfuncerror(ERR_CALLMISMATCH,tpi->sname,sp->name);
  463.                                 }
  464.                             }
  465.                             if (sp && sp->tp->type == bt_ref) {
  466.                                 if (lvalue(ep2)) {
  467.                                     while (castvalue(ep2))
  468.                                         ep2 = ep2->v.p[0];
  469.                                     ep2 = ep2->v.p[0];
  470.                                 }
  471.                                 else {
  472.                                     ENODE *x;
  473.                                     tp2 = sp->tp->btp;
  474.                                     genfuncerror(ERR_TEMPUSED,tpi->sname,sp->name);
  475.                                     lc_auto += tp2->size+3;
  476.                                     lc_auto &= 0xfffffffcL;
  477.                      x = makenode(en_autocon,(char *)-lc_auto,0);
  478.                                     ep2 = makenode(en_refassign,x,ep2);
  479.                                 }
  480.                                 }
  481.                             spi = spi->next;
  482.                              if (sp) {
  483.                                 sp = sp->next;
  484.                                  if (sp->tp->type == bt_ellipse)
  485.                                     matching = FALSE;
  486.                             }
  487.                             if (sp && sp->tp->val_flag && (sp->tp->type == bt_struct || tp->type == bt_union)) {
  488.                                 ep1 = makenode(en_stackblock,ep2,ep1);
  489.                                 ep2->size = tp->size;
  490.                             }
  491.                             else
  492.                        ep1 = makenode(en_void,ep2,ep1);
  493.                     }
  494.                 if (tp)
  495.                     promote_type(tp->btp,&ep1);
  496.                 else
  497.                     promote_type(tpi->btp,&ep1);
  498.                 *node = ep1;
  499. }
  500.  
  501. int floatrecurse(ENODE *node)
  502. /*
  503.  * Go through a node and see if it will be promoted to type FLOAT
  504.  */
  505. {
  506.     if (!node)
  507.         return 0;
  508.     switch (node->nodetype) {
  509.                                 case en_rcon:
  510.                                 case en_doubleref:
  511.                                 case en_longdoubleref:
  512.                                 case en_floatref:
  513.                                 case en_cld:
  514.                                 case en_cd:
  515.                                 case en_cf:
  516.                                                 return 1;
  517.                 case en_labcon: case en_nalabcon: case en_trapcall: 
  518.                 case en_nacon:  case en_autocon:  case en_autoreg:
  519.                 case en_l_ref:  case en_tempref: case en_napccon: case en_absacon:
  520.                                 case en_cl: case en_regref:
  521.                 case en_ul_ref:
  522.                                 case en_cul:
  523.                                 case en_cp:
  524.                 case en_icon:
  525.                                 case en_bits:
  526.                 case en_ub_ref:
  527.                                 case en_cub:
  528.                 case en_b_ref:
  529.                                 case en_cb:
  530.                 case en_uw_ref:
  531.                                 case en_cuw:
  532.                 case en_cw:
  533.                 case en_w_ref:
  534.                 case en_eq:     case en_ne:
  535.                 case en_lt:     case en_le:
  536.                 case en_gt:     case en_ge:
  537.                                 case en_ugt: case en_uge: case en_ult: case en_ule:
  538.                         return 0;
  539.                                 case en_fcall:
  540.                                 case en_fcallb:
  541.                                 case en_callblock:
  542.                                                 return(floatrecurse(node->v.p[1]));
  543.                 case en_not:    case en_compl:
  544.                 case en_uminus: 
  545.                 case en_ainc:   case en_adec:
  546.                                 case en_moveblock: case en_stackblock:
  547.                         return floatrecurse(node->v.p[0]);
  548.                                 case en_refassign: case en_assign:
  549.                 case en_add:    case en_sub:
  550.                                 case en_umul:        case en_udiv:    case en_umod: case en_pmul:
  551.                 case en_mul:    case en_div:
  552.                 case en_mod:    case en_and:
  553.                 case en_or:     case en_xor:
  554.                                 case en_asalsh: case en_asarsh: case en_alsh: case en_arsh:
  555.                 case en_lsh:    case en_rsh:
  556.                 case en_land:   case en_lor:
  557.                 case en_asadd:  case en_assub:
  558.                 case en_asmul:  case en_asdiv:
  559.                 case en_asmod:  case en_asand:
  560.                                 case en_asumod: case en_asudiv: case en_asumul:
  561.                 case en_asor:   case en_aslsh:
  562.                 case en_asrsh:
  563.                         return(floatrecurse(node->v.p[0]) || floatrecurse(node->v.p[1]));
  564.                 case en_void:   case en_cond:
  565.                         return floatrecurse(node->v.p[1]);
  566.     }
  567.     return(0);
  568. }
  569. void floatcheck(ENODE *node)
  570. /*
  571.  * Error if node will be promoted to type float
  572.  */
  573. {
  574.     if (floatrecurse(node))
  575.         generror(ERR_INVFLOAT,0,0);
  576. }
  577. int     castbegin(int st)
  578. /*
  579.  *      return 1 if st in set of [ kw_char, kw_short, kw_long, kw_int,
  580.  *      kw_float, kw_double, kw_struct, kw_union, kw_float, or is typedef ]
  581.  */
  582. {      
  583.     SYM *sp;
  584.     switch(st) {
  585.         case kw_void:
  586.         case kw_char: case kw_short: case kw_int: case kw_long:
  587.         case kw_float: case kw_double:    
  588.         case kw_struct:    case kw_union:
  589.         case kw_unsigned:    case kw_volatile:    case kw_const:
  590.             return 1;
  591.         default:
  592.             if (st != id)
  593.                 return 0;
  594.     } 
  595.     nm = lastid;
  596.     sp = gsearch(lastid);
  597.     if (!sp)
  598.         sp = search(lastid,&lsyms);
  599.     if (sp && sp->storage_class == sc_type)
  600.         return 1 ;
  601.     return 0;
  602. }
  603.  
  604. TYP     *primary(ENODE **node)
  605. /*
  606.  *      primary will parse a primary expression and set the node pointer
  607.  *      returning the type of the expression parsed. primary expressions
  608.  *      are any of:
  609.  *                      id
  610.  *                      constant
  611.  *                      string
  612.  *                      ( expression )
  613.  *                      primary[ expression ]
  614.  *                      primary.id
  615.  *                      primary->id
  616.  *                      primary( parameter list )
  617.  *                                            (* expression)( parameter list )
  618.  *                      (typecast)primary
  619.  *                      (typecast)(unary)
  620.  */
  621. {       ENODE    *pnode, *qnode, *rnode;
  622.         SYM             *sp;
  623.         TYP             *tptr,*tp1,*tp2;
  624.                 int flag = 0;
  625.                 int gcode,gdf;
  626.         switch( lastst ) {
  627. /* This trap thing should be in stmt.c */
  628.                         case kw__trap:    
  629.                                     getsym();
  630.                                     if (needpunc(openpa,0)) {
  631.                                         long num = intexpr(0);
  632.                                         if (num > 15 || num < 0)
  633.                                             generror(ERR_INVTRAP,0,0);
  634.                                         if (lastst == comma) 
  635.                                             getsym();
  636.                                         tptr = gatherparms(&pnode);
  637.                                         parmlist(&pnode,tptr,0);
  638.                                         pnode = makenode(en_trapcall,makenode(en_icon,(char *)num,0),pnode);
  639.                                     }
  640.                                     *node = pnode;
  641.                                     return &stdint;
  642.  
  643. #ifdef    i386
  644.                         case kw__EAX:
  645.                         case kw__EDX:
  646.                         case kw__ECX:
  647.                         case kw__EBX:
  648.                         case kw__ESP:
  649.                         case kw__EBP:
  650.                         case kw__ESI:
  651.                         case kw__EDI:
  652.                                                 tptr = xalloc(sizeof(TYP));
  653.                                                 *tptr = stduns;
  654.                                                 tptr->sname = regname;
  655.                                                 pnode = makenode(en_regref,(char *)(1024+lastst-kw__EAX),0);
  656.                                                 pnode = makenode(en_ul_ref,pnode,0);
  657.                                                 *node = pnode;
  658.                                                 getsym();
  659.                                                 return tptr;
  660. #else
  661.                         case kw__D0:
  662.                         case kw__D1:
  663.                         case kw__D2:
  664.                         case kw__D3:
  665.                         case kw__D4:
  666.                         case kw__D5:
  667.                         case kw__D6:
  668.                         case kw__D7:
  669.                         case kw__A0:
  670.                         case kw__A1:
  671.                         case kw__A2:
  672.                         case kw__A3:
  673.                         case kw__A4:
  674.                         case kw__A5:
  675.                         case kw__A6:
  676.                         case kw__A7:
  677.                                                 tptr = xalloc(sizeof(TYP));
  678.                                                 *tptr = stduns;
  679.                                                 tptr->sname = regname;
  680.                                                 pnode = makenode(en_regref,(char *)(1024+lastst-kw__D0),0);
  681.                                                 pnode = makenode(en_ul_ref,pnode,0);
  682.                                                 *node = pnode;
  683.                                                 getsym();
  684.                                                 return tptr;
  685.                         case kw__FP0:
  686.                         case kw__FP1:
  687.                         case kw__FP2:
  688.                         case kw__FP3:
  689.                         case kw__FP4:
  690.                         case kw__FP5:
  691.                         case kw__FP6:
  692.                         case kw__FP7:
  693.                                                 tptr = xalloc(sizeof(TYP));
  694.                                                 *tptr = stdlongdouble;
  695.                                                 tptr->sname = regname;
  696.                                                 pnode = makenode(en_regref,(char *)(2560+lastst-kw__D0),0);
  697.                                                 pnode = makenode(en_longdoubleref,pnode,0);
  698.                                                 *node = pnode;
  699.                                                 getsym();
  700.                                                 return tptr;
  701. #endif
  702.             case id:  
  703.                         tptr = nameref(&pnode);
  704.                         break;
  705.                 case iconst:
  706.                         tptr = &stdint;
  707.                         pnode = makenode(en_icon,(char *)ival,0);
  708.                         getsym();
  709.                                                 *node = pnode;
  710.                                                 return tptr;
  711.                                 case rconst:
  712.                                                 tptr = &stddouble;
  713.                                         pnode = xalloc(sizeof(ENODE));
  714.                                         pnode->nodetype = en_rcon;
  715.                                                 pnode->cflags = 0;
  716.                                                 pnode->v.f = rval;
  717.                                                 getsym();
  718.                                                 *node = pnode;
  719.                                                 return tptr;
  720.                 case sconst:
  721.                         tptr = &stdstring;
  722.                         pnode = makenode(en_labcon,(char *)stringlit(laststr),0);
  723.                         getsym();
  724.                                                 *node = pnode;
  725.                                                 return tptr;
  726.                 case openpa:
  727.                         getsym();
  728.                                                 if (lastst == star) {
  729.                                                                 gcode = goodcode;
  730.                                                                 goodcode &= ~(GF_AND | GF_SUPERAND);
  731.                                 getsym();
  732.                                                                 gdf = globaldref;
  733.                                                                 globaldref = 1;
  734.                                                                 tptr = expression(&pnode);
  735.                                                                 globaldref = gdf;
  736.                                                                 goodcode = gcode;
  737.                                                                 if (needpunc(closepa, skm_closepa)) {
  738.                                                                     if (tptr->type == bt_ptrfunc) {
  739.                                                                         if (needpunc(openpa,skm_closepa)) {
  740.                                                                             goodcode |= GF_ASSIGN;
  741.                                                                             tp1 = gatherparms(&qnode);
  742.                                                                             tp1->sname = tptr->sname;
  743.                                                                             parmlist(&qnode,tp1,tptr);
  744.                                                                             if (tptr->cflags & DF_INT)
  745.                                                   pnode = makenode(en_intcall,pnode,qnode);
  746.                                                                             else
  747.                                                                                 if (tptr->type == bt_union || tptr->type == bt_struct) {
  748.                                                       pnode = makenode(en_fcallb,pnode,qnode);
  749.                                                                                     pnode->size = tptr->size;
  750.                                                                                 }
  751.                                                                                 else
  752.                                                       pnode = makenode(en_fcall,pnode,qnode);
  753.                                                                             pnode->cflags = tptr->btp->cflags;
  754.                                                                             tptr = tptr->btp;
  755.                                                                             break;
  756.                                                                         }
  757.                                                                     }
  758.                                                                     else {
  759.                                                    break;
  760.                                                                      }
  761.                                                                 }
  762.                                                                 goodcode |= GF_ASSIGN;
  763.                                                                 *node = pnode;
  764.                                                                 return tptr;
  765.                                                 }
  766.                                                 else
  767. castcont:
  768.                           if( !castbegin(lastst) ) {
  769.                                                                 gcode = goodcode;
  770.                                                                 goodcode &= ~(GF_AND | GF_SUPERAND);
  771.                                                                 gdf = globaldref;
  772.                                                                 globaldref = 0;
  773.                                                                 tptr = expression(&pnode);
  774.                                                                 globaldref = gdf;
  775.                                                                 goodcode = gcode & ~GF_ASSIGN;
  776.                                 needpuncexp(closepa,skm_closepa);
  777.                                                                 goto contfor;
  778.                                 }
  779.                           else    {       /* cast operator */
  780.                                                                 int flags = 0;
  781.                                                                 while (lastst == kw_const || lastst == kw_volatile) {
  782.                                                                     if (lastst == kw_const)
  783.                                                                         flags |= DF_CONST;
  784.                                                                     else
  785.                                                                         flags |= DF_VOL;
  786.                                                                     getsym();
  787.                                                                 }
  788.                                                                 declid[0] = 0;
  789.                                 decl(0,flags); /* do cast declaration */
  790.                                 decl1();
  791.                                 tptr = head;
  792.                                 if (needpunc(closepa, 0)) {
  793.                                                                     gcode = goodcode;
  794.                                                                     goodcode &= ~(GF_AND | GF_SUPERAND);
  795.                                                                     gdf = globaldref;
  796.                                                                     globaldref = 0;
  797.                                     if( (unary(&pnode)) == 0 ) {
  798.                                         generror(ERR_IDEXPECT,0,0);
  799.                                         tptr = 0;
  800.                                     }
  801.                                                                     globaldref = gdf;
  802.                                                                     goodcode = gcode;
  803.                                                                     pnode->cflags = tptr->cflags;
  804.                                                                     if (tptr) {
  805.                                                                         promote_type(tptr, &pnode);
  806.                                                                     }
  807.                                                                 }
  808.                                                                 else
  809.                                                                     return(0);
  810.                                                     }
  811.                                                 *node = pnode;
  812.                                                 return tptr;
  813.                 default:
  814.                         return 0;
  815.                 }
  816. contfor:
  817.         for(;;) {
  818.                 switch( lastst ) {
  819.                         case openbr:    /* build a subscript reference */
  820.                                                                 flag = 1;
  821.                                 if( tptr->type != bt_pointer )
  822.                                         generrorexp(ERR_NOPOINTER,0,skm_closebr);
  823.                                 else
  824.                                         tptr = tptr->btp;
  825.                                 getsym();
  826.                                 qnode = makenode(en_icon,(char *)tptr->size,0);
  827.                                                                 gcode = goodcode;
  828.                                                                 goodcode &= ~(GF_AND | GF_SUPERAND);
  829.                                                                 gdf = globaldref;
  830.                                                                 globaldref = 0;
  831.                                                                 tp2 = expression(&rnode);
  832.                                                                 globaldref = gdf;
  833.                                                                 goodcode = gcode & ~GF_ASSIGN;
  834.                                                                 if (!isscalar(tp2) || tp2->type == bt_float || tp2->type == bt_double || tp2->type == bt_longdouble)
  835.                                   generror(ERR_ARRAYMISMATCH,0,0);
  836.                                 qnode = makenode(en_pmul,qnode,rnode);
  837.                                 pnode = makenode(en_add,qnode,pnode);
  838.                                                                 pnode->cflags = tptr->cflags;
  839.                                 if( tptr->val_flag == 0 )
  840.                                         tptr = deref(&pnode,tptr);
  841.                                 needpuncexp(closebr,skm_closebr);
  842.                                     break;
  843.                         case pointsto:
  844.                                 if( tptr->type != bt_pointer ) {
  845.                                         generror(ERR_NOPOINTER,0,0);
  846.                                                                                 while (lastst == pointsto || lastst == dot) {
  847.                                                                                     getsym();
  848.                                                                                     getsym();
  849.                                                                                 }
  850.                                                                                 break;
  851.                                                                 }
  852.                                 else
  853.                                         tptr = tptr->btp;
  854.                                                                 pnode->cflags = tptr->cflags;
  855.                                 if( tptr->val_flag == 0 ) {
  856.                                         pnode = makenode(en_l_ref,pnode,0);
  857.                                                                                 pnode->cflags = tptr->cflags;
  858.                                                                 }
  859.                                                                 
  860. /*
  861.  *      fall through to dot operation
  862.  */
  863.                         case dot:
  864.                                 getsym();       /* past -> or . */
  865.                                 if( lastst != id )
  866.                                         generror(ERR_IDEXPECT,0,0);
  867.                                 else    {
  868.                                         sp = search(nm=litlate(lastid),&tptr->lst);
  869.                                         if( sp == 0 ) {
  870.                                                                         tptr = &stdmatch;
  871.                                                                                                 pnode = makenode(en_nacon,undefname,0);
  872.                                                 gensymerror(ERR_UNDEFINED,nm);
  873.                                                                                                 getsym();
  874.                                                                                                 while (lastst == pointsto || lastst == dot) {
  875.                                                                                                     getsym();
  876.                                                                                                     getsym();
  877.                                                                                                 }
  878.                                                                                 }
  879.                                         else    {
  880.                                                                                                     
  881.                                                 tp2 = sp->tp;
  882.                                                                                                 if (pnode->nodetype == en_fcallb) {
  883.                                                                                                     lc_auto+=pnode->size+3;
  884.                                                                                                     lc_auto &= 0xfffffffcL;
  885.                                                                                                     qnode = makenode(en_autocon,(char *)-lc_auto,0);
  886.                                                                                                     pnode = makenode(en_callblock,qnode,pnode);
  887.                                                                                                 }
  888.                                                 qnode = makenode(en_icon,(char *)sp->value.i,0);
  889.                                                 pnode = makenode(en_add,pnode,qnode);
  890.                                                                                                 pnode->cflags = tptr->cflags | pnode->v.p[0]->cflags;
  891.                                                                                                 tp2->uflags |= tptr->uflags;
  892.                                                                                                 tptr = tp2; 
  893.                                                 if( tptr->val_flag == 0 )
  894.                                                     tptr = deref(&pnode,tptr);
  895.                                                                                                 if (tp2->bits != -1) {
  896.                                                                                                     qnode = pnode;
  897.                                                                                                     pnode = makenode(en_bits,qnode,0);
  898.                                                                                                     pnode->bits = tp2->bits;
  899.                                                                                                     pnode->startbit = tp2->startbit;
  900.                                                                                                     pnode->cflags = tptr->cflags | pnode->v.p[0]->cflags;
  901.                                                                                                 }
  902.                                         }
  903.                                         getsym();       /* past id */
  904.                                 }
  905.                                 break;
  906.                         case openpa:    /* function reference */
  907.                                                                 flag = 1;
  908.                                 if( tptr->type != bt_func &&
  909.                                         tptr->type != bt_ifunc && tptr->type != bt_ptrfunc) {
  910.                                         gensymerrorexp(ERR_NOFUNC,nm);
  911.                                                                                 expskim(skm_closepa);
  912.                                                                 }
  913.                                 else {
  914.                                                                                 if (prm_cplusplus && !strcmp(nm,"main"))
  915.                                                                                     generror(ERR_NOMAIN,0,0);
  916.                                                                                 sp=gsearch(tptr->sname);
  917.                                                 getsym();
  918.                                                                                 tp1 =gatherparms(&qnode);
  919.                                                                                 parmlist(&qnode,tp1,tptr);
  920.                                         tptr = tptr->btp;
  921.                                                                                 if (sp->intflag)
  922.                                                     pnode = makenode(en_intcall,pnode,qnode);
  923.                                                                                 else
  924.                                                                                 if (tptr->type == bt_union || tptr->type == bt_struct) {
  925.                                                       pnode = makenode(en_fcallb,pnode,qnode);
  926.                                                                                     pnode->size = tptr->size;
  927.                                                                                 }
  928.                                                                                 else
  929.                                                       pnode = makenode(en_fcall,pnode,qnode);
  930.                                                                                 if (tptr)
  931.                                                                                     pnode->cflags = tptr->cflags;
  932.                                                                 }
  933.                                                                 goodcode |= GF_ASSIGN;
  934.                                 break;
  935.                         default:
  936.                                 goto fini;
  937.                         }
  938.                 }
  939. fini:   *node = pnode;
  940.                 if (!flag && !(goodcode & GF_AND) && lastsym && tptr->type != bt_func && tptr->type != bt_ifunc
  941.                             &&!tptr->val_flag && lastsym->storage_class != sc_type 
  942.                             && lastsym->storage_class != sc_static && lastsym->storage_class != sc_global
  943.                             && lastsym->storage_class != sc_external) {
  944.                     if (!(lastsym->tp->uflags & UF_DEFINED) && lastst != assign
  945.                         &&lastst != asplus && lastst != asminus && lastst != astimes
  946.                         && lastst!= asdivide && lastst != asmodop && lastst != asrshift
  947.                         && lastst != aslshift && lastst != asor && lastst != asand) {
  948.                             gensymerror(ERR_SYMUNDEF,lastsym->name);
  949.                             lastsym->tp->uflags |= UF_DEFINED;
  950.                     }
  951.                     lastsym->tp->uflags &=  ~UF_ASSIGNED;
  952.                 }
  953.         return tptr;
  954. }
  955.  
  956. int            castvalue(ENODE *node)
  957. {
  958.                 switch(node->nodetype) {
  959.                                 case en_cb: case en_cub: case en_bits:
  960.                                 case en_cw: case en_cuw:
  961.                                 case en_cl: case en_cul:
  962.                                 case en_cf: case en_cd: case en_cp: case en_cld:
  963.                         return 1;
  964.                 }
  965.         return 0;
  966. }
  967. int     lvalue(ENODE *node)
  968. /*
  969.  *      this function returns true if the node passed is an lvalue.
  970.  *      this can be qualified by the fact that an lvalue must have
  971.  *      one of the dereference operators as it's top node.
  972.  */
  973. {       
  974.                 if (!prm_cplusplus) {
  975.                     while (castvalue(node))
  976.                         node = node->v.p[0];
  977.                 }
  978.                 switch( node->nodetype ) {
  979.                 case en_b_ref:
  980.                 case en_w_ref:
  981.                 case en_l_ref:
  982.                 case en_ub_ref:
  983.                 case en_uw_ref:
  984.                 case en_ul_ref:
  985.                                 case en_floatref:
  986.                                 case en_doubleref:
  987.                                 case en_longdoubleref:
  988.                         return 1;
  989.                                 case en_bits:
  990.                         return lvalue(node->v.p[0]);
  991.                 }
  992.         return 0;
  993. }
  994.  
  995. TYP     *unary(ENODE **node)
  996. /*
  997.  *      unary evaluates unary expressions and returns the type of the
  998.  *      expression evaluated. unary expressions are any of:
  999.  *
  1000.  *                      primary
  1001.  *                      primary++
  1002.  *                      primary--
  1003.  *                      !unary
  1004.  *                      ~unary
  1005.  *                      &unary
  1006.  *                      ++unary
  1007.  *                      --unary
  1008.  *                      -unary
  1009.  *                      *unary
  1010.  *                      sizeof(typecast)
  1011.  *
  1012.  */
  1013. {       TYP             *tp,*tp1;
  1014.         ENODE    *ep1, *ep2;
  1015.         int             flag, i,gdf;
  1016.         flag = 0;
  1017.         switch( lastst ) {
  1018.                 case autodec:
  1019.                         flag = 1;
  1020.                 /* fall through to common increment */
  1021.                 case autoinc:
  1022.                         getsym();
  1023.                                                 gdf = globaldref;
  1024.                                                 globaldref = 0;
  1025.                         tp = unary(&ep1);
  1026.                                                 globaldref = gdf;
  1027.                         if( tp == 0 ) {
  1028.                                 generror(ERR_IDEXPECT,0,0);
  1029.                                 return 0;
  1030.                                 }
  1031.                                                 goodcode |= GF_ASSIGN;
  1032.                         if( lvalue(ep1)) {
  1033.                                 if( tp->type == bt_pointer ) {
  1034.                                                                                 if (tp->btp->size == 0)
  1035.                                                                                     generror(ERR_ZEROPTR,0,0);
  1036.                                         ep2 = makenode(en_icon,(char *)tp->btp->size,0);
  1037.                                                                 }
  1038.                                 else
  1039.                                         ep2 = makenode(en_icon,(char *)1,0);
  1040.                                                                 if (ep1->cflags & DF_CONST)
  1041.                                                                     generror(ERR_MODCONS,0,0);
  1042.                                 ep1 = makenode(flag ? en_assub : en_asadd,ep1,ep2);
  1043.                                 }
  1044.                         else {
  1045.                                 generror(ERR_LVALUE,0,0);
  1046.                                                                 return(0);
  1047.                                                 }
  1048.                         break;
  1049.                 case minus:
  1050.                         getsym();
  1051.                                                 gdf = globaldref;
  1052.                                                 globaldref = 0;
  1053.                         tp = unary(&ep1);
  1054.                                                 globaldref = gdf;
  1055.                                                 goodcode &= ~GF_ASSIGN;
  1056.                         if( tp == 0 ) {
  1057.                                 generror(ERR_IDEXPECT,0,0);
  1058.                                 return 0;
  1059.                                 }
  1060.                         ep1 = makenode(en_uminus,ep1,0);
  1061.                         break;
  1062.                 case not:
  1063.                         getsym();
  1064.                                                 gdf = globaldref;
  1065.                                                 globaldref = 0;
  1066.                         tp = unary(&ep1);
  1067.                                                 globaldref = gdf;
  1068.                                                 goodcode &= ~GF_ASSIGN;
  1069.                         if( tp == 0 ) {
  1070.                                 generror(ERR_IDEXPECT,0,0);
  1071.                                 return 0;
  1072.                                 }
  1073.                         ep1 = makenode(en_not,ep1,0);
  1074.                         break;
  1075.                 case compl:
  1076.                         getsym();
  1077.                                                 gdf = globaldref;
  1078.                                                 globaldref = 0;
  1079.                         tp = unary(&ep1);
  1080.                                                 globaldref = gdf;
  1081.                                                 goodcode &= ~GF_ASSIGN;
  1082.                         if( tp == 0 ) {
  1083.                                 generror(ERR_IDEXPECT,0,0);
  1084.                                 return 0;
  1085.                                 }
  1086.                                                 floatcheck(ep1);
  1087.                         ep1 = makenode(en_compl,ep1,0);
  1088.                         break;
  1089.                 case star:
  1090.                         getsym();
  1091.                                                 gdf = globaldref;
  1092.                                                 globaldref = 0;
  1093.                         tp = unary(&ep1);
  1094.                                                 globaldref = gdf;
  1095.                                                 goodcode &= ~GF_ASSIGN;
  1096.                         if( tp == 0 ) {
  1097.                                 generror(ERR_IDEXPECT,0,0);
  1098.                                 return 0;
  1099.                                 }
  1100.                         if( tp->btp == 0 ) {
  1101.                                 generror(ERR_DEREF,0,0);
  1102.                                                 }
  1103.                         else
  1104.                                                         if (tp->btp->type != bt_void)
  1105.                                 tp = tp->btp;
  1106.                                                 ep1->cflags = tp->cflags;
  1107.                         if( tp->val_flag == 0 )
  1108.                                 tp = deref(&ep1,tp);
  1109.                         break;
  1110.                 case and:
  1111.                         getsym();
  1112.                                                 if (!(goodcode & GF_INFUNCPARMS))
  1113.                                                     goodcode |= GF_AND;
  1114.                                                 gdf = globaldref;
  1115.                                                 globaldref = 0;
  1116.                         tp = unary(&ep1);
  1117.                                                 globaldref = gdf;
  1118.                                                 goodcode &= ~GF_AND;
  1119.                                                 goodcode &= ~GF_ASSIGN;
  1120.                         if( tp == 0 ) {
  1121.                                 generror(ERR_IDEXPECT,0,0);
  1122.                                 return 0;
  1123.                                 }
  1124.                                                 else 
  1125.                                                     if (tp->startbit != -1) 
  1126.                                                         generror(ERR_BFADDR,0,0);
  1127.                                                     else if (tp->cflags & DF_AUTOREG)
  1128.                                                         gensymerror(ERR_NOANDREG,tp->sname);
  1129.                                                     else if (tp->type == bt_pointer && tp->val_flag && !(goodcode & GF_SUPERAND))
  1130.                                                         generror(ERR_SUPERAND,0,0);
  1131.  
  1132.                         if( lvalue(ep1)) {
  1133.                                 ep1 = ep1->v.p[0];
  1134.                                                                  if (ep1->nodetype == en_regref)
  1135.                                                                     gensymerror(ERR_NOANDREG,tp->sname);
  1136.                                                 }
  1137.                         tp1 = xalloc(sizeof(TYP));
  1138.                         tp1->size = 4;
  1139.                         tp1->type = bt_pointer;
  1140.                         tp1->btp = tp;
  1141.                         tp1->val_flag = 0;
  1142.                         tp1->lst.head = 0;
  1143.                         tp1->sname = 0;
  1144.                                                 tp = tp1;
  1145.                                                 break;
  1146.                 case kw_sizeof:
  1147.                         getsym();
  1148.                         needpunc(openpa,0);
  1149.                                                 if (castbegin(lastst))
  1150.                                                 {
  1151.                                                     int flags = 0;
  1152.                                                     while (lastst == kw_const || lastst == kw_volatile) {
  1153.                                                         if (lastst == kw_const)
  1154.                                                             flags |= DF_CONST;
  1155.                                                         else
  1156.                                                             flags |= DF_VOL;
  1157.                                                         getsym();
  1158.                                                     }
  1159.                             decl(0,flags);
  1160.                                                     decl1();
  1161.                                                 }
  1162.                                                 else {
  1163.                                                     SYM *sp;
  1164.                                                     if (lastst == id) {
  1165.                                                         ENODE *node = 0;
  1166.                                                         if ((sp = search(nm,&tagtable)) != 0) {
  1167.                                                             head = sp->tp;
  1168.                                                             getsym();
  1169.                                                         }
  1170.                                                         else
  1171.                                                             head = primary(&node);
  1172.                                                     }
  1173.                                                     else {
  1174.                                                         if (lastst == kw_enum) {
  1175.                                                             getsym();
  1176.                                                             if (lastst == id) {
  1177.                                                                 if ((sp = search(nm,&tagtable)) != 0) {
  1178.                                                                     head = sp->tp;
  1179.                                                                     getsym();
  1180.                                                                     goto sizeofnorm;
  1181.                                                                 }
  1182.                                                             }
  1183.                                                         }
  1184.                                                         generror(ERR_SZTYPE,0,skm_closepa);
  1185.                                                         ep1 = makenode(en_icon,(char *) 1, 0);
  1186.                                 tp = &stdint;
  1187.                                                          break;
  1188.                                                     }
  1189.                                                 }
  1190. sizeofnorm:                
  1191.                         if( head != 0 ) {
  1192.                                 ep1 = makenode(en_icon,(char *)head->size,0);
  1193.                                                 }
  1194.                         else    {
  1195.                                 generror(ERR_IDEXPECT,0,0);
  1196.                                 ep1 = makenode(en_icon,(char *)1,0);
  1197.                                 }
  1198.                                                 goodcode &= ~GF_ASSIGN;
  1199.                         tp = &stdint;
  1200.                         needpunc(closepa,0);
  1201.                         break;
  1202.                 default:
  1203.                         tp = primary(&ep1);
  1204.                         if( tp != 0 ) {
  1205.                                 if( tp->type == bt_pointer )
  1206.                                         i = tp->btp->size;
  1207.                                 else
  1208.                                         i = 1;
  1209.                                 if( lastst == autoinc) {
  1210.                                                                                 if (i == 0)
  1211.                                                                                     generror(ERR_ZEROPTR,0,0);
  1212.                                         if( lvalue(ep1) ) {
  1213.                                                                                     if (ep1->cflags & DF_CONST)
  1214.                                                                                         generror(ERR_MODCONS,0,0);
  1215.                                           ep1 = makenode(en_ainc,ep1,(char *)i);
  1216.                                                                                     goodcode |= GF_ASSIGN;
  1217.                                                                                 }
  1218.                                         else
  1219.                                                 generror(ERR_LVALUE,0,0);
  1220.                                         getsym();
  1221.                                         }
  1222.                                 else if( lastst == autodec ) {
  1223.                                                                                 if (i == 0)
  1224.                                                                                     generror(ERR_ZEROPTR,0,0);
  1225.                                         if( lvalue(ep1) ) {
  1226.                                                                                     if (ep1->cflags & DF_CONST)
  1227.                                                                                         generror(ERR_MODCONS,0,0);
  1228.                                           ep1 = makenode(en_adec,ep1,(char *)i);
  1229.                                                                                     goodcode |= GF_ASSIGN;
  1230.                                                                                 }
  1231.                                         else
  1232.                                                 generror(ERR_LVALUE,0,0);
  1233.                                         getsym();
  1234.                                         }
  1235.                                 }
  1236.                         break;
  1237.                 }
  1238.                 if (globaldref) {
  1239.                     globaldref = 0;
  1240.                     if (tp->type != bt_ptrfunc) {
  1241.                          if( tp == 0 ) {
  1242.                generror(ERR_IDEXPECT,0,0);
  1243.                        return 0;
  1244.                 }
  1245.                         if( tp->btp == 0 ) {
  1246.                           generror(ERR_DEREF,0,0);
  1247.                         }
  1248.                         else
  1249.                             if (tp->btp->type != bt_void)
  1250.                          tp = tp->btp;
  1251.                         ep1->cflags = tp->cflags;
  1252.                 if( tp->val_flag == 0 )
  1253.                 tp = deref(&ep1,tp);
  1254.                     }
  1255.                 }
  1256.         *node = ep1;
  1257.         return tp;
  1258. }
  1259. TYP *maxsize(TYP *tp1, TYP *tp2)
  1260. {
  1261.     if (tp1->type > tp2->type)
  1262.         return tp1;
  1263.     return tp2;
  1264. }
  1265. TYP     *forcefit(ENODE **node1,TYP *tp1,ENODE **node2,TYP *tp2, int max)
  1266. /*
  1267.  *      forcefit will coerce the nodes passed into compatable
  1268.  *      types and return the type of the resulting expression.
  1269.  */
  1270. {                int error = ERR_MISMATCH;
  1271.                 TYP *tp3;
  1272.            switch( tp1->type ) {
  1273.                 case bt_long:
  1274.                                                 if ((*node1)->nodetype == en_icon) {
  1275.                                                     if (isscalar(tp2) || (!prm_cplusplus && tp2->type == bt_pointer))
  1276.                                                         return tp2;
  1277.                                                     if (tp2->type != bt_matchall)
  1278.                                                         break;
  1279.                                                 }
  1280.                 case bt_matchall:
  1281.                         if( tp2->type == bt_matchall)
  1282.                                                     return(&stdint);
  1283.                         else if( tp2->type == bt_pointer)
  1284.                           return tp2;
  1285.                                                 else if (isscalar(tp2))
  1286.                                                     if (max)
  1287.                                                         return(maxsize(tp1,tp2));
  1288.                                                     else
  1289.                                                         return(tp1);
  1290.                         break;
  1291.                 case bt_pointer:
  1292.                                                 if (!prm_cplusplus && !max && (tp2->type == bt_short || tp2->type == bt_unsignedshort
  1293.                                                     || tp2->type == bt_char || tp2->type == bt_unsignedchar)) {
  1294.                                                         error = ERR_SHORTPOINTER;
  1295.                                                         break;
  1296.                                                 }
  1297.                         if( tp2->type == bt_pointer)
  1298.                                 return tp1;
  1299.                                                 if (!prm_cplusplus && isscalar(tp2))
  1300.                                                     if (max)
  1301.                                                         return(maxsize(tp1,tp2));
  1302.                                                     else
  1303.                                                         return(tp1);
  1304.                         break;
  1305.                 case bt_unsignedshort:
  1306.                 case bt_short:
  1307.                                                 if ((*node2)->nodetype == en_icon) {
  1308.                                                     if (!max && ((*node2)->v.i < -65536L || ((*node2)->v.i > 65535L))) {
  1309.                                                         error = ERR_LOSTCONV;
  1310.                                                         break;
  1311.                                                     }
  1312.                                                     return tp1;
  1313.                                                 }
  1314.                                                 else
  1315.                                                      if (!max && (tp2->type == bt_long || tp2->type == bt_unsigned || (!prm_cplusplus && tp2->type == bt_pointer))) {
  1316.                                                          error = ERR_LOSTCONV;
  1317.                                                           break;
  1318.                                                     }
  1319.                                                 if (isscalar(tp2))
  1320.                                                     if (max)
  1321.                                                         return(maxsize(tp1,tp2));
  1322.                                                     else
  1323.                                                         return(tp1);
  1324.                                                 break;
  1325.                 case bt_char:
  1326.                 case bt_unsignedchar:
  1327.                                                 if ((*node2)->nodetype == en_icon) {
  1328.                                                     if (!max && ((*node2)->v.i < -256 || ((*node2)->v.i > 255))) {
  1329.                                                         error = ERR_LOSTCONV;
  1330.                                                         break;
  1331.                                                     }
  1332.                                                     return tp1;
  1333.                                                 }
  1334.                                                 else
  1335.                                                      if (!max && (tp2->type == bt_long || tp2->type == bt_unsigned || ( !prm_cplusplus && tp2->type == bt_pointer)
  1336.                                                              || tp2->type == bt_short || tp2->type == bt_unsignedshort)) {
  1337.                                                          error = ERR_LOSTCONV;
  1338.                                                           break;
  1339.                                                     }
  1340.                                                 if (isscalar(tp2))
  1341.                                                     if (max)
  1342.                                                         return(maxsize(tp1,tp2));
  1343.                                                     else
  1344.                                                         return(tp1);
  1345.                                                 break;
  1346.                                 case bt_float:
  1347.                                 case bt_double:
  1348.                                 case bt_longdouble:
  1349.                                                 if (isscalar(tp2))
  1350.                                                     return(tp1);
  1351.                                                 break;
  1352.                 case bt_unsigned:
  1353.                                                 if ((*node1)->nodetype == en_icon) {
  1354.                                                     if (isscalar(tp2) || (!prm_cplusplus && tp2->type == bt_pointer))
  1355.                                                         return tp2;
  1356.                                                     break;
  1357.                                                 }
  1358.                         if( !prm_cplusplus && tp2->type == bt_pointer )
  1359.                                 return tp2;
  1360.                                                 if (isscalar(tp2))
  1361.                                                     return(tp1);
  1362.                         break;
  1363.                                 case bt_ptrfunc:
  1364.                                                 if (!prm_cplusplus && (tp2->type == bt_short || tp2->type == bt_unsignedshort
  1365.                                                     || tp2->type == bt_char || tp2->type == bt_unsignedchar)) {
  1366.                                                         error = ERR_SHORTPOINTER;
  1367.                                                         break;
  1368.                                                 }
  1369.                                                 if (tp2->type == bt_pointer)
  1370.                                                     tp3 = tp2->btp;
  1371.                                                 else
  1372.                                                     tp3 = tp2;
  1373.                                                 if (tp3->type == bt_func || tp3->type == bt_ifunc || tp3->type == bt_ptrfunc
  1374.                                                             || (!prm_cplusplus && tp2->type == bt_pointer))
  1375.                                                     return(tp1);
  1376.                                                 break;
  1377.                                 case bt_func:
  1378.                                 case bt_ifunc:
  1379.                                                 if (tp2->type == bt_func || tp2->type == bt_ifunc)
  1380.                                                     return tp1;
  1381.                                                 break;
  1382.                 }
  1383.                 if (error == ERR_MISMATCH && prm_cplusplus)
  1384.                     genmismatcherror(tp2,tp1);
  1385.                 else
  1386.             generror( error,0,0 );
  1387.         return tp1;
  1388. }
  1389.  
  1390. int     isscalar(TYP *tp)
  1391. /*
  1392.  *      this function returns true when the type of the argument is
  1393.  *      one of char, short, unsigned, or long.  Also float or double
  1394.  *            ( so much for scalar! )
  1395.  */
  1396. {       return  tp->type == bt_char ||  tp->type == bt_unsignedchar ||
  1397.                 tp->type == bt_short || tp->type == bt_unsignedshort ||
  1398.                 tp->type == bt_long || tp->type == bt_unsigned || tp->type == bt_enum
  1399.                                 || tp->type == bt_float || tp->type == bt_double || tp->type == bt_longdouble;
  1400. }
  1401. void checknp(TYP *tp1,TYP*tp2,ENODE *ep1, ENODE *ep2)
  1402. {
  1403.  
  1404.     if (prm_cplusplus)
  1405.         return;
  1406.     if (tp1->type == bt_pointer || tp2->type == bt_pointer)
  1407.         if (tp1->type != tp2->type) 
  1408.             if ((ep1->nodetype != en_icon || ep1->v.i != 0) && (ep2->nodetype != en_icon || ep2->v.i != 0))
  1409.                 generror(ERR_NONPORT,0,0);
  1410. }
  1411. TYP     *multops(ENODE **node)
  1412. /*
  1413.  *      multops parses the multiply priority operators. the syntax of
  1414.  *      this group is:
  1415.  *
  1416.  *              unary
  1417.  *              multop * unary
  1418.  *              multop / unary
  1419.  *              multop % unary
  1420.  */
  1421. {       ENODE    *ep1, *ep2;
  1422.         TYP             *tp1, *tp2;
  1423.         int              oper;
  1424.         tp1 = unary(&ep1);
  1425.         if( tp1 == 0 )
  1426.                 return 0;
  1427.         while( lastst == star || lastst == divide || lastst == modop ) {
  1428.                 oper = lastst;
  1429.                 getsym();       /* move on to next unary op */
  1430.                 tp2 = unary(&ep2);
  1431.                                 goodcode &= ~GF_ASSIGN;
  1432.                 if( tp2 == 0 ) {
  1433.                         generror(ERR_IDEXPECT,0,0);
  1434.                         *node = ep1;
  1435.                         return tp1;
  1436.                         }
  1437.                 tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE);
  1438.                 switch( oper ) {
  1439.                         case star:
  1440.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1441.                                         ep1 = makenode(en_umul,ep1,ep2);
  1442.                                 else
  1443.                                         ep1 = makenode(en_mul,ep1,ep2);
  1444.                                 break;
  1445.                         case divide:
  1446.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1447.                                         ep1 = makenode(en_udiv,ep1,ep2);
  1448.                                 else
  1449.                                         ep1 = makenode(en_div,ep1,ep2);
  1450.                                 break;
  1451.                         case modop:
  1452.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1453.                                         ep1 = makenode(en_umod,ep1,ep2);
  1454.                                 else
  1455.                                         ep1 = makenode(en_mod,ep1,ep2);
  1456.                                                                 floatcheck(ep1);
  1457.                                 break;
  1458.                         }
  1459.                 }
  1460.         *node = ep1;
  1461.         return tp1;
  1462. }
  1463.  
  1464. TYP     *addops(ENODE **node)
  1465. /*
  1466.  *      addops handles the addition and subtraction operators.
  1467.  */
  1468. {       ENODE    *ep1, *ep2, *ep3;
  1469.         TYP             *tp1, *tp2;
  1470.         int             oper;
  1471.         tp1 = multops(&ep1);
  1472.         if( tp1 == 0 )
  1473.                 return 0;
  1474.         while( lastst == plus || lastst == minus ) {
  1475.                 oper = (lastst == plus);
  1476.                 getsym();
  1477.                 tp2 = multops(&ep2);
  1478.                                 goodcode &= ~GF_ASSIGN;
  1479.                 if( tp2 == 0 ) {
  1480.                         generror(ERR_IDEXPECT,0,0);
  1481.                         *node = ep1;
  1482.                         return tp1;
  1483.                         }
  1484.                 if( tp1->type == bt_pointer ) {
  1485.                                         if (tp2->type == bt_pointer) {
  1486.                             forcefit(&ep1,tp1,&ep2,tp2,TRUE);
  1487.                             ep1 = makenode( oper ? en_add : en_sub,ep1,ep2);
  1488.                                             ep1->cflags = ep1->v.p[0]->cflags | ep2->cflags;
  1489.                                             if (!checktypeassign(tp1,tp2))
  1490.                                                 generror(ERR_MISMATCH,0,0);
  1491.                                             else
  1492.                                                 if (tp1->btp->size == 0)
  1493.                                                     generror(ERR_ZEROPTR,0,0);
  1494.                                                 else
  1495.                                                     if (tp1->btp->size > 1)
  1496.                                                         ep1 = makenode(en_pdiv,ep1,makenode(en_icon,(char *)tp1->btp->size,0));
  1497.                                             ep1->cflags = ep1->v.p[0]->cflags;
  1498.                                            tp1 = &stdint;
  1499.                                             goto exit;
  1500.                                         }
  1501.                                         else {
  1502.                         tp2 = forcefit(0,&stdint,&ep2,tp2,TRUE);
  1503.                                                 if (tp1->btp->size == 0)
  1504.                                                     generror(ERR_ZEROPTR,0,0);
  1505.                         ep3 = makenode(en_icon,(char *)tp1->btp->size,0);
  1506.                         ep2 = makenode(en_pmul,ep3,ep2);
  1507.                                                 ep2->cflags = ep2->v.p[1]->cflags;
  1508.                         }
  1509.                                 }
  1510.                 else if( tp2->type == bt_pointer ) {
  1511.                         tp1 = forcefit(0,&stdint,&ep1,tp1,TRUE);
  1512.                                                 if (tp2->btp->size == 0)
  1513.                                                     generror(ERR_ZEROPTR,0,0);
  1514.                         ep3 = makenode(en_icon,(char *)tp2->btp->size,0);
  1515.                         ep1 = makenode(en_pmul,ep3,ep1);
  1516.                                                 ep1->cflags = ep1->v.p[1]->cflags;
  1517.                         }
  1518.                 tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE);
  1519.                 ep1 = makenode( oper ? en_add : en_sub,ep1,ep2);
  1520.                                 ep1->cflags = ep1->v.p[1]->cflags | ep2->cflags;
  1521.                 }
  1522. exit:
  1523.         *node = ep1;
  1524.         return tp1;
  1525. }
  1526.  
  1527. TYP     *shiftop(ENODE **node)
  1528. /*
  1529.  *      shiftop handles the shift operators << and >>.
  1530.  */
  1531. {       ENODE    *ep1, *ep2;
  1532.         TYP             *tp1, *tp2;
  1533.         int             oper;
  1534.         tp1 = addops(&ep1);
  1535.         if( tp1 == 0)
  1536.                 return 0;
  1537.         while( lastst == lshift || lastst == rshift) {
  1538.                 oper = (lastst == lshift);
  1539.                 getsym();
  1540.                 tp2 = addops(&ep2);
  1541.                                 goodcode &= ~GF_ASSIGN;
  1542.                 if( tp2 == 0 )
  1543.                         generror(ERR_IDEXPECT,0,0);
  1544.                 else    {
  1545.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE);
  1546.                                                 if (tp1->type == bt_unsigned ||
  1547.                                                         tp1->type == bt_unsignedchar ||
  1548.                                                         tp1->type == bt_unsignedshort)
  1549.                             ep1 = makenode(oper ? en_lsh : en_rsh,ep1,ep2);
  1550.                                                 else
  1551.                             ep1 = makenode(oper ? en_alsh : en_arsh,ep1,ep2);
  1552.                         }
  1553.                                 floatcheck(ep1);
  1554.                 }
  1555.         *node = ep1;
  1556.         return tp1;
  1557. }
  1558.  
  1559. TYP     *relation(ENODE **node)
  1560. /*
  1561.  *      relation handles the relational operators < <= > and >=.
  1562.  */
  1563. {       ENODE    *ep1, *ep2;
  1564.         TYP             *tp1, *tp2;
  1565.         int             nt;
  1566.         tp1 = shiftop(&ep1);
  1567.         if( tp1 == 0 )
  1568.                 return 0;
  1569.         for(;;) {
  1570.                 switch( lastst ) {
  1571.  
  1572.                         case lt:
  1573.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1574.                                         nt = en_ult;
  1575.                                 else
  1576.                                         nt = en_lt;
  1577.                                 break;
  1578.                         case gt:
  1579.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1580.                                         nt = en_ugt;
  1581.                                 else
  1582.                                         nt = en_gt;
  1583.                                 break;
  1584.                         case leq:
  1585.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1586.                                         nt = en_ule;
  1587.                                 else
  1588.                                         nt = en_le;
  1589.                                 break;
  1590.                         case geq:
  1591.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1592.                                         nt = en_uge;
  1593.                                 else
  1594.                                         nt = en_ge;
  1595.                                 break;
  1596.                         default:
  1597.                                 goto fini;
  1598.                         }
  1599.                 getsym();
  1600.                 tp2 = shiftop(&ep2);
  1601.                                 goodcode &= ~GF_ASSIGN;
  1602.                 if( tp2 == 0 )
  1603.                         generror(ERR_IDEXPECT,0,0);
  1604.                 else    {
  1605.                                                 checknp(tp1,tp2,ep1,ep2);
  1606.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE);
  1607.                         ep1 = makenode(nt,ep1,ep2);
  1608.                         }
  1609.                 }
  1610. fini:   *node = ep1;
  1611.         return tp1;
  1612. }
  1613.  
  1614. TYP     *equalops(ENODE **node)
  1615. /*
  1616.  *      equalops handles the equality and inequality operators.
  1617.  */
  1618. {       ENODE    *ep1, *ep2;
  1619.         TYP             *tp1, *tp2;
  1620.         int             oper;
  1621.         tp1 = relation(&ep1);
  1622.         if( tp1 == 0 )
  1623.                 return 0;
  1624.         while( lastst == eq || lastst == neq ) {
  1625.                 oper = (lastst == eq);
  1626.                 getsym();
  1627.                 tp2 = relation(&ep2);
  1628.                                 goodcode &= ~GF_ASSIGN;
  1629.                                 checknp(tp1,tp2,ep1,ep2);
  1630.                 if( tp2 == 0 )
  1631.                         generror(ERR_IDEXPECT,0,0);
  1632.                 else    {
  1633.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE);
  1634.                         ep1 = makenode( oper ? en_eq : en_ne,ep1,ep2);
  1635.                         }
  1636.                 }
  1637.         *node = ep1;
  1638.         return tp1;
  1639. }
  1640.  
  1641. TYP     *binop(ENODE **node,TYP *(*xfunc)(),int nt,int sy)
  1642. /*
  1643.  *      binop is a common routine to handle all of the legwork and
  1644.  *      error checking for bitand, bitor, bitxor, andop, and orop.
  1645.  */
  1646. {       ENODE    *ep1, *ep2;
  1647.         TYP             *tp1, *tp2;
  1648.         tp1 = (*xfunc)(&ep1);
  1649.         if( tp1 == 0 )
  1650.                 return 0;
  1651.         while( lastst == sy ) {
  1652.                 getsym();
  1653.                 tp2 = (*xfunc)(&ep2);
  1654.                                 goodcode &= ~GF_ASSIGN;
  1655.                 if( tp2 == 0 )
  1656.                         generror(ERR_IDEXPECT,0,0);
  1657.                 else    {
  1658.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE);
  1659.                         ep1 = makenode(nt,ep1,ep2);
  1660.                         }
  1661.                                 floatcheck(ep1);
  1662.                 }
  1663.         *node = ep1;
  1664.         return tp1;
  1665. }
  1666.  
  1667. TYP     *bitand(ENODE **node)
  1668. /*
  1669.  *      the bitwise and operator...
  1670.  */
  1671. {       return binop(node,equalops,en_and,and);
  1672. }
  1673.  
  1674. TYP     *bitxor(ENODE **node)
  1675. {       return binop(node,bitand,en_xor,uparrow);
  1676. }
  1677.  
  1678. TYP     *bitor(ENODE **node)
  1679. {       return binop(node,bitxor,en_or,or);
  1680. }
  1681.  
  1682. TYP     *andop(ENODE **node)
  1683. {       return binop(node,bitor,en_land,land);
  1684. }
  1685.  
  1686. TYP     *orop(ENODE **node)
  1687. {       return binop(node,andop,en_lor,lor);
  1688. }
  1689.  
  1690. TYP     *conditional(ENODE **node)
  1691. /*
  1692.  *      this routine processes the hook operator.
  1693.  */
  1694. {       TYP             *tp1, *tp2, *tp3;
  1695.         ENODE    *ep1, *ep2, *ep3;
  1696.         tp1 = orop(&ep1);       /* get condition */
  1697.         if( tp1 == 0 )
  1698.                 return 0;
  1699.         if( lastst == hook ) {
  1700.                 getsym();
  1701.                 if( (tp2 = conditional(&ep2)) == 0) {
  1702.                         generror(ERR_IDEXPECT,0,0);
  1703.                                                 goodcode &= ~GF_ASSIGN;
  1704.                         goto cexit;
  1705.                         }
  1706.                 needpunc(colon,0);
  1707.                 if( (tp3 = conditional(&ep3)) == 0) {
  1708.                         generror(ERR_IDEXPECT,0,0);
  1709.                                                 goodcode &= ~GF_ASSIGN;
  1710.                         goto cexit;
  1711.                         }
  1712.                                 goodcode &= ~GF_ASSIGN;
  1713.                 tp1 = forcefit(&ep2,tp2,&ep3,tp3,TRUE);
  1714.                 ep2 = makenode(en_void,ep2,ep3);
  1715.                 ep1 = makenode(en_cond,ep1,ep2);
  1716.                 }
  1717. cexit:  *node = ep1;
  1718.         return tp1;
  1719. }
  1720. TYP            *autoasnop(ENODE **node, SYM *sp)
  1721. /*
  1722.  *             Handle assignment operators during auto init of local vars
  1723.  */
  1724. {       ENODE    *ep1, *ep2;
  1725.         TYP             *tp1, *tp2;
  1726.  
  1727.         if( (tp1 = sp->tp) == 0 ) {
  1728.                     tp1 = &stdmatch;
  1729.                     *node = makenode(en_nacon,undefname,0);
  1730.                     gensymerror(ERR_UNDEFINED,nm);
  1731.           tp1 = deref(&ep1,tp1);
  1732.           return tp1;       /* guard against untyped entries */
  1733.         }
  1734.         if( sp->storage_class != sc_auto && sp->storage_class != sc_autoreg)
  1735.           gensymerror(ERR_ILLCLASS2,sp->name);
  1736.                 if (sp->storage_class == sc_auto)
  1737.             ep1 = makenode(en_autocon,(char *)sp->value.i,0);
  1738.                 else if (sp->storage_class == sc_autoreg)
  1739.             ep1 = makenode(en_autoreg,(char *)sp->value.i,0);
  1740.                 if (tp1) {
  1741.                     tp1->uflags |= UF_DEFINED | UF_USED;
  1742.                 }
  1743.                 if ((tp1->uflags & UF_CANASSIGN) && !(goodcode & GF_INLOOP))
  1744.                     tp1->uflags |=  UF_ASSIGNED;
  1745.         if( tp1->val_flag == 0)
  1746.           tp1 = deref(&ep1,tp1);
  1747.         if( tp1 == 0 )
  1748.                 return 0;
  1749.         tp2 = asnop(&ep2,tp1);
  1750.         if( tp2 == 0)
  1751.           generror(ERR_LVALUE,0,0);
  1752.         else    {
  1753.                     if (!lvalue(ep1)) {
  1754.                         if (!checktypeassign(tp1,tp2))
  1755.                  generror(ERR_LVALUE,0,0);
  1756.                         else {
  1757.                             checknp(tp1,tp2,ep1,ep2);
  1758.                             if (ep2->nodetype == en_fcallb)
  1759.                                 ep1 = makenode(en_callblock,ep1,ep2);
  1760.                             else
  1761.                                 ep1 = makenode(en_moveblock,ep1,ep2);
  1762.                             ep1->size = tp1->size;
  1763.                             *node = ep1;
  1764.                         }
  1765.                     }
  1766.           else    {
  1767.                         if (tp1->type == bt_ref) {
  1768.                             if (lvalue(ep2)) {
  1769.                                  while (castvalue(ep2))
  1770.                                      ep2 = ep2->v.p[0];
  1771.                                 ep2 = ep2->v.p[0];
  1772.                                 tp1 = tp1->btp;
  1773.                             }
  1774.                             else {
  1775.                                 ENODE *x;
  1776.                                 int q = (tp1->size+3) & 0xfffffffcL;
  1777.                                 tp1 = tp1->btp;
  1778.                                 gensymerror(ERR_TEMPINIT,sp->name);
  1779.                                 lc_auto += q;
  1780.                 x = makenode(en_autocon,(char *)(sp->value.i-q),0);
  1781.                                 ep2 = makenode(en_refassign,x,ep2);
  1782.                             }
  1783.                         }
  1784.                         checknp(tp1,tp2,ep1,ep2);
  1785.               tp1 = forcefit(&ep1,tp1,&ep2,tp2,FALSE);
  1786.               *node = makenode(en_assign,ep1,ep2);
  1787.                     }
  1788.         }
  1789.                 return(tp1);
  1790. }
  1791. void asncombine(ENODE **node)
  1792. {
  1793.     ENODE *var = (*node)->v.p[0];
  1794.     ENODE *exp = (*node)->v.p[1];
  1795.   ENODE *var2 = exp->v.p[0];
  1796.     if (equalnode(var,var2)) {
  1797.         int op = 0;
  1798.         switch(exp->nodetype) {
  1799.             case en_add:
  1800.                     op = en_asadd;
  1801.                     break;
  1802.             case en_sub:
  1803.                     op = en_assub;
  1804.                     break;
  1805.             case en_mul:
  1806.                     op = en_asmul;
  1807.                     break;
  1808.             case en_umul:
  1809.                     op = en_asumul;
  1810.                     break;
  1811.             case en_div:
  1812.                     op = en_asdiv;
  1813.                     break;
  1814.             case en_udiv:
  1815.                     op = en_asudiv;
  1816.                     break;
  1817.             case en_mod:
  1818.                     op = en_asmod;
  1819.                     break;
  1820.             case en_umod:
  1821.                     op = en_asumod;
  1822.                     break;
  1823.             case en_lsh:
  1824.                     op = en_aslsh;
  1825.                     break;
  1826.             case en_alsh:
  1827.                     op = en_asalsh;
  1828.                     break;
  1829.             case en_rsh:
  1830.                     op = en_asrsh;
  1831.                     break;
  1832.             case en_arsh:
  1833.                     op = en_asarsh;
  1834.                     break;
  1835.             case en_and:
  1836.                     op = en_asand;
  1837.                     break;
  1838.             case en_or:
  1839.                     op = en_asor;
  1840.                     break;
  1841.             default:
  1842.                     return;
  1843.         }
  1844.         exp->nodetype = op;
  1845.         (*node) = exp;
  1846.     }    
  1847. }
  1848. TYP     *asnop(ENODE **node,TYP *tptr)
  1849. /*
  1850.  *      asnop handles the assignment operators.
  1851.  */
  1852. {       ENODE    *ep1, *ep2, *ep3;
  1853.         TYP             *tp1, *tp2,*oldastyp;
  1854.         int             op;
  1855.                 oldastyp = asntyp;
  1856.                 if (tptr) 
  1857.                     asntyp = tptr;
  1858.                 else
  1859.                     asntyp = 0;
  1860.         tp1 = conditional(&ep1);
  1861.                 if (!tptr)
  1862.                     asntyp = tp1;
  1863.         if( tp1 == 0 )
  1864.                 return 0;
  1865.         for(;;) {
  1866.                 switch( lastst ) {
  1867.                         case assign:
  1868.                                 op = en_assign;
  1869. ascomm:                         getsym();
  1870.                                 tp2 = asnop(&ep2,asntyp);
  1871. ascomm2:                        ep3 = ep1;
  1872.                                                                 if (tp1) {
  1873.                                                                     tp1->uflags |= UF_DEFINED;
  1874.                                                                 }
  1875.                                                                 goodcode |= GF_ASSIGN;
  1876.                                                                 if ((tp1->uflags & UF_CANASSIGN) && !(goodcode & GF_INLOOP))
  1877.                                                                     tp1->uflags |=  UF_ASSIGNED;
  1878.                                                                 if( tp2 == 0 || tp1 == 0)
  1879.                                         generror(ERR_LVALUE,0,0);
  1880.                                                                 else {
  1881.                                                                         if (!lvalue(ep1)) {
  1882.                                                                                 if (!checktypeassign(tp1,tp2)) {
  1883.                                             generror(ERR_LVALUE,0,0);
  1884.                                                                                 }
  1885.                                                                                 else {
  1886.                                                                                     if (op != en_asadd && op != en_assub)
  1887.                                                                                         checknp(tp1,tp2,ep1,ep2);
  1888.                                                                                     if (ep2->nodetype == en_fcallb)
  1889.                                                                                         ep1 = makenode(en_callblock,ep1,ep2);
  1890.                                                                                     else
  1891.                                                                                         ep1 = makenode(en_moveblock,ep1,ep2);
  1892.                                                                                     ep1->size = tp1->size;
  1893.                                                                                 }
  1894.                                                                         }
  1895.                                   else    {
  1896.                                                                                 if (op != en_asadd && op != en_assub)
  1897.                                                                                     checknp(tp1,tp2,ep1,ep2);
  1898.                                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,FALSE);
  1899.                                         ep1 = makenode(op,ep1,ep2);
  1900.                                         }
  1901.                                                                 }
  1902.                                                               if (ep3->cflags & DF_CONST)
  1903.                                                                   generror(ERR_MODCONS,0,0);
  1904.                                                               if (op == en_assign)
  1905.                                                                   asncombine(&ep1);
  1906.                                                               else if (op == en_asmod || op == en_asumod ||
  1907.                                                                               op ==en_aslsh || op== en_asrsh ||
  1908.                                                                               op == en_asalsh || op== en_asarsh ||
  1909.                                                                               op == en_asand || op== en_asor)
  1910.                                                                   floatcheck(ep1);
  1911.                                 break;
  1912.                         case asplus:
  1913.                                 op = en_asadd;
  1914.         
  1915. ascomm3:                                                getsym();
  1916.                                                                 tp2 = asnop(&ep2,asntyp);
  1917.                                 if( tp1->type == bt_pointer ) {
  1918.                                                                                 if (tp1->btp->size == 0)
  1919.                                                                                     generror(ERR_ZEROPTR,0,0);
  1920.                                         ep3 = makenode(en_icon,(char *)tp1->btp->size,0);
  1921.                                         ep2 = makenode(en_pmul,ep2,ep3);
  1922.                                                                                 tp2 = tp1;
  1923.                                         }
  1924.                                 goto ascomm2;
  1925.                         case asminus:
  1926.                                 op = en_assub;
  1927.                                 goto ascomm3;
  1928.                         case astimes:
  1929.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1930.                                         op = en_asumul;
  1931.                                 else
  1932.                                         op =en_asmul;
  1933.                                 goto ascomm;
  1934.                         case asdivide:
  1935.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1936.                                         op = en_asudiv;
  1937.                                 else
  1938.                                         op =en_asdiv;
  1939.                                 goto ascomm;
  1940.                         case asmodop:
  1941.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1942.                                         op = en_asumod;
  1943.                                 else
  1944.                                         op =en_asmod;
  1945.                                 goto ascomm;
  1946.                         case aslshift:
  1947.                                                         if (tp1->type == bt_unsigned ||
  1948.                                                                 tp1->type == bt_unsignedchar ||
  1949.                                                                 tp1->type == bt_unsignedshort)
  1950.                                                             op = en_aslsh;
  1951.                                                         else
  1952.                               op = en_asalsh;
  1953.                                 goto ascomm;
  1954.                         case asrshift:
  1955.                                                         if (tp1->type == bt_unsigned ||
  1956.                                                                 tp1->type == bt_unsignedchar ||
  1957.                                                                 tp1->type == bt_unsignedshort)
  1958.                                                             op = en_asrsh;
  1959.                                                         else
  1960.                               op = en_asarsh;
  1961.                                 goto ascomm;
  1962.                         case asand:
  1963.                                 op = en_asand;
  1964.                                 goto ascomm;
  1965.                         case asor:
  1966.                                 op = en_asor;
  1967.                                 goto ascomm;
  1968.                         default:
  1969.                                 goto asexit;
  1970.                         }
  1971.                 }
  1972. asexit: *node = ep1;
  1973.                 asntyp = oldastyp;
  1974.         return tp1;
  1975. }
  1976.  
  1977. TYP     *exprnc(ENODE **node)
  1978. /*
  1979.  *      evaluate an expression where the comma operator is not legal.
  1980.  */
  1981. {       TYP     *tp;
  1982.         tp = asnop(node,0);
  1983.         if( tp == 0 )
  1984.                 *node = 0;
  1985.                 else if ((*node)->nodetype == en_fcallb) {
  1986.                         ENODE *ep1;
  1987.                         lc_auto+=tp->size+3;
  1988.                         lc_auto &= 0xfffffffcL;
  1989.                         ep1 = makenode(en_autocon,(char *)-lc_auto,0);
  1990.                         (*node) = makenode(en_callblock,ep1,(*node));
  1991.                 }
  1992.         return tp;
  1993. }
  1994.  
  1995. TYP     *commaop(ENODE **node)
  1996. /*
  1997.  *      evaluate the comma operator. comma operators are kept as
  1998.  *      void nodes.
  1999.  */
  2000. {       TYP             *tp1;
  2001.         ENODE    *ep1, *ep2;
  2002.         tp1 = asnop(&ep1,0);
  2003.         if( tp1 == 0 )
  2004.                 return 0;
  2005.         if( lastst == comma ) {
  2006.                                 getsym();
  2007.                 tp1 = commaop(&ep2);
  2008.                                 goodcode &= ~GF_ASSIGN;
  2009.                 if( tp1 == 0 ) {
  2010.                         generror(ERR_IDEXPECT,0,0);
  2011.                         goto coexit;
  2012.                         }
  2013.                 ep1 = makenode(en_void,ep1,ep2);
  2014.                 }
  2015. coexit: *node = ep1;
  2016.         return tp1;
  2017. }
  2018.  
  2019. TYP     *expression(ENODE **node)
  2020. /*
  2021.  *      evaluate an expression where all operators are legal.
  2022.  */
  2023. {       TYP     *tp;
  2024.         tp = commaop(node);
  2025.         if( tp == 0 )
  2026.                 *node = 0;
  2027.                 else if ((*node)->nodetype == en_fcallb) {
  2028.                         ENODE *ep1;
  2029.                         lc_auto+=tp->size+3;
  2030.                         lc_auto &= 0xfffffffcL;
  2031.                         ep1 = makenode(en_autocon,(char *)-lc_auto,0);
  2032.                         (*node) = makenode(en_callblock,ep1,(*node));
  2033.                 }
  2034.         return tp;
  2035. }