home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dosdisas.zip / dccsrcoo.zip / ast.cpp next >
C/C++ Source or Header  |  1997-04-09  |  35KB  |  1,054 lines

  1. /*
  2.  *$Log:    ast.c,v $
  3.  * Revision 1.10  94/03/14  08:54:05  cifuente
  4.  * flags changed to flags32
  5.  * 
  6.  * Revision 1.9  94/02/22  15:18:58  cifuente
  7.  * Routines to support trees, including pre and post increment/decrement
  8.  * 
  9.  * Revision 1.8  93/12/13  14:06:16  cifuente
  10.  * Interprocedural live analysis finished.
  11.  * 
  12.  * Revision 1.7  93/11/10  16:41:18  cifuente
  13.  * Expressions
  14.  * 
  15.  * Revision 1.6  93/11/01  15:03:16  cifuente
  16.  * Finds byte and integer expressions
  17.  * 
  18.  * Revision 1.5  93/10/29  13:32:08  cifuente
  19.  * IM_SRC use
  20.  * 
  21.  * Revision 1.4  93/10/25  10:57:32  cifuente
  22.  * newExp SYNTHETIC instructions for d/u analysis.
  23.  * 
  24.  * Revision 1.3  93/10/22  07:41:40  cifuente
  25.  * newLongRegId changed function prototype
  26.  * 
  27.  * Revision 1.2  93/10/11  11:33:13  cifuente
  28.  * First walk through HIGH_LEVEL icodes.
  29.  * 
  30.  * Revision 1.1  93/09/29  14:12:09  cifuente
  31.  * Initial revision
  32.  * 
  33.  * File: ast.c
  34.  * Purpose: Support module for abstract syntax trees.
  35.  * Date: September 1993
  36.  */
  37.  
  38. #if __BORLAND__
  39. #include <alloc.h>
  40. #else
  41. #include <malloc.h>        /* For free() */
  42. #endif
  43. #include <string.h>
  44. #include "dcc.h"
  45.  
  46. /* Index registers **** temp solution */
  47. static char *idxReg[8] = {"bx+si", "bx+di", "bp+si", "bp+di", 
  48.                           "si", "di", "bp", "bx" };
  49. /* Conditional operator symbols in C.  Index by condOp enumeration type */
  50. static char *condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
  51.                              " & ", " | ", " ^ ", " ~ ",
  52.                              " + ", " - ", " * ", " / ", 
  53.                              " >> ", " << ", " % ", " && ", " || " };
  54.  
  55. #define EXP_SIZE 200        /* Size of the expression buffer */
  56.  
  57. /* Local expression stack */
  58. typedef struct _EXP_STK {
  59.     COND_EXPR       *exp;
  60.     struct _EXP_STK *next;
  61. } EXP_STK;
  62.  
  63. static EXP_STK *expStk = NULL;      /* local expression stack */
  64.  
  65.  
  66. static char *hexStr (Int i)
  67. /* Returns the integer i in C hexadecimal format */
  68. { static char buf[10];
  69.  
  70.     i &= 0xFFFF;
  71.     sprintf (buf, "%s%lX", (i > 9) ? "0x" : "", i);
  72.     return (buf);
  73. }
  74.  
  75.  
  76. void setRegDU (PICODE pIcode, byte regi, operDu du)
  77. /* Sets the du record for registers according to the du flag    */
  78. {
  79.     switch (du) {
  80.       case DEF:     pIcode->du.def |= duReg[regi];
  81.                     pIcode->du1.numRegsDef++;
  82.                     break;
  83.       case USE:     pIcode->du.use |= duReg[regi];
  84.                     break;
  85.       case USE_DEF: pIcode->du.def |= duReg[regi];
  86.                     pIcode->du1.numRegsDef++;
  87.                     pIcode->du.use |= duReg[regi];
  88.                     break;
  89.       case NONE:    /* do nothing */
  90.                     break;
  91.     }
  92. }
  93.  
  94.  
  95. void copyDU (PICODE pIcode, PICODE duIcode, operDu du, operDu duDu)
  96. /* Copies the def, use, or def and use fields of duIcode into pIcode */
  97. {
  98.     switch (du) {
  99.       case DEF:     
  100.             if (duDu == DEF)
  101.                 memcpy (&pIcode->du.def, &duIcode->du.def, sizeof(dword));
  102.             else
  103.                 memcpy (&pIcode->du.def, &duIcode->du.use, sizeof(dword));
  104.             break;
  105.       case USE: 
  106.             if (duDu == DEF)
  107.                 memcpy (&pIcode->du.use, &duIcode->du.def, sizeof(dword));
  108.             else
  109.                 memcpy (&pIcode->du.use, &duIcode->du.use, sizeof(dword));
  110.             break;
  111.       case USE_DEF: 
  112.             memcpy (&pIcode->du, &duIcode->du, sizeof(DU_ICODE));
  113.             break;
  114.     }
  115. }
  116.  
  117.  
  118. static COND_EXPR *newCondExp (condNodeType t)
  119. /* Creates a newExp conditional expression node of type t and returns it */
  120. { COND_EXPR *newExp;
  121.     
  122.     newExp = allocStruc(COND_EXPR); 
  123.     memset(newExp, 0, sizeof(COND_EXPR));
  124.     newExp->type = t;
  125.     return (newExp);
  126. }
  127.  
  128.  
  129. COND_EXPR *boolCondExp (COND_EXPR *lhs, COND_EXPR *rhs, condOp op)
  130. /* Creates a conditional boolean expression and returns it */
  131. { COND_EXPR *newExp;
  132.  
  133.     newExp = newCondExp (BOOLEAN_OP);
  134.     newExp->expr.boolExpr.op = op;
  135.     newExp->expr.boolExpr.lhs = lhs;
  136.     newExp->expr.boolExpr.rhs = rhs;
  137.     return (newExp);
  138. }
  139.  
  140.  
  141. COND_EXPR *unaryCondExp (condNodeType t, COND_EXPR *exp)
  142. /* Returns a unary conditional expression node.  This procedure should 
  143.  * only be used with the following conditional node types: NEGATION,
  144.  * ADDRESSOF, DEREFERENCE, POST_INC, POST_DEC, PRE_INC, PRE_DEC    */
  145. { COND_EXPR *newExp;
  146.  
  147.     newExp = newCondExp (t);
  148.     newExp->expr.unaryExp = exp;
  149.     return (newExp);
  150. }
  151.  
  152.  
  153. COND_EXPR *idCondExpGlob (int16 segValue, int16 off)
  154. /* Returns an identifier conditional expression node of type GLOB_VAR */
  155. { COND_EXPR *newExp;
  156.   dword adr;
  157.   Int i;
  158.  
  159.     newExp = newCondExp (IDENTIFIER);
  160.     newExp->expr.ident.idType = GLOB_VAR;
  161.     adr = opAdr(segValue, off);
  162.     for (i = 0; i < symtab.csym; i++)
  163.         if (symtab.sym[i].label == adr)
  164.             break;
  165. if (i == symtab.csym)
  166. printf ("Error, glob var not found in symtab\n");
  167.     newExp->expr.ident.idNode.globIdx = i;
  168.     return (newExp);
  169. }
  170.  
  171.  
  172. COND_EXPR *idCondExpReg (byte regi, flags32 icodeFlg, LOCAL_ID *locsym)
  173. /* Returns an identifier conditional expression node of type REGISTER */
  174. { COND_EXPR *newExp;
  175.  
  176.     newExp = newCondExp (IDENTIFIER);
  177.     newExp->expr.ident.idType = REGISTER;
  178.     if ((icodeFlg & B) || (icodeFlg & SRC_B))
  179.     {
  180.         newExp->expr.ident.idNode.regiIdx = newByteWordRegId (locsym, 
  181.                                                         TYPE_BYTE_SIGN, regi);
  182.         newExp->expr.ident.regiType = BYTE_REG;
  183.     }
  184.     else    /* word */
  185.     {
  186.         newExp->expr.ident.idNode.regiIdx = newByteWordRegId (locsym, 
  187.                                                         TYPE_WORD_SIGN, regi);
  188.         newExp->expr.ident.regiType = WORD_REG;
  189.     }
  190.     return (newExp);
  191. }
  192.  
  193.  
  194. COND_EXPR *idCondExpRegIdx (Int idx, regType type)
  195. /* Returns an identifier conditional expression node of type REGISTER */
  196. { COND_EXPR *newExp;
  197.  
  198.     newExp = newCondExp (IDENTIFIER);
  199.     newExp->expr.ident.idType = REGISTER;
  200.     newExp->expr.ident.regiType = type;
  201.     newExp->expr.ident.idNode.regiIdx = idx;
  202.     return (newExp);
  203. }
  204.  
  205.  
  206. COND_EXPR *idCondExpLoc (Int off, LOCAL_ID *localId)
  207. /* Returns an identifier conditional expression node of type LOCAL_VAR */ 
  208. { COND_EXPR *newExp;
  209.   Int i;
  210.  
  211.     newExp = newCondExp (IDENTIFIER);
  212.     newExp->expr.ident.idType = LOCAL_VAR;
  213.     for (i = 0; i < localId->csym; i++)
  214.         if ((localId->id[i].id.bwId.off == off) &&
  215.             (localId->id[i].id.bwId.regOff == 0))
  216.             break;
  217. if (i == localId->csym) printf ("Error, cannot find local var\n");
  218.     newExp->expr.ident.idNode.localIdx = i;
  219.     sprintf (localId->id[i].name, "loc%ld", i);
  220.     return (newExp);
  221. }
  222.  
  223.  
  224. COND_EXPR *idCondExpParam (Int off, PSTKFRAME argSymtab)
  225. /* Returns an identifier conditional expression node of type PARAM */ 
  226. { COND_EXPR *newExp;
  227.   Int i;
  228.  
  229.     newExp = newCondExp (IDENTIFIER);
  230.     newExp->expr.ident.idType = PARAM;
  231.     for (i = 0; i < argSymtab->csym; i++)
  232.         if (argSymtab->sym[i].off == off)
  233.             break;
  234. if (i == argSymtab->csym) printf ("Error, cannot find argument var\n");
  235.     newExp->expr.ident.idNode.localIdx = i;
  236.     return (newExp);
  237. }
  238.  
  239.  
  240. COND_EXPR *idCondExpIdxGlob (int16 segValue, int16 off, byte regi, 
  241.                               LOCAL_ID *locSym)
  242. /* Returns an identifier conditional expression node of type GLOB_VAR_IDX.
  243.  * This global variable is indexed by regi.     */
  244. { COND_EXPR *newExp;
  245.   Int i;
  246.  
  247.     newExp = newCondExp (IDENTIFIER);
  248.     newExp->expr.ident.idType = GLOB_VAR_IDX;
  249.     for (i = 0; i < locSym->csym; i++)
  250.         if ((locSym->id[i].id.bwGlb.seg == segValue) &&
  251.             (locSym->id[i].id.bwGlb.off == off) &&
  252.             (locSym->id[i].id.bwGlb.regi == regi))
  253.             break;
  254. if (i == locSym->csym) 
  255. printf ("Error, indexed-glob var not found in local id table\n");
  256.     newExp->expr.ident.idNode.idxGlbIdx = i;
  257.     return (newExp);
  258. }
  259.  
  260.  
  261. COND_EXPR *idCondExpKte (dword kte, byte size)
  262. /* Returns an identifier conditional expression node of type CONSTANT */
  263. { COND_EXPR *newExp;
  264.  
  265.     newExp = newCondExp (IDENTIFIER);
  266.     newExp->expr.ident.idType = CONSTANT;
  267.     newExp->expr.ident.idNode.kte.kte = kte;
  268.     newExp->expr.ident.idNode.kte.size = size;
  269.     return (newExp);
  270. }
  271.  
  272.  
  273. COND_EXPR *idCondExpLongIdx (Int idx)
  274. /* Returns an identifier conditional expression node of type LONG_VAR,
  275.  * that points to the given index idx.  */
  276. { COND_EXPR *newExp;
  277.     
  278.     newExp = newCondExp (IDENTIFIER);
  279.     newExp->expr.ident.idType = LONG_VAR;
  280.     newExp->expr.ident.idNode.longIdx = idx;
  281.     return (newExp);
  282. }
  283.  
  284.  
  285. COND_EXPR *idCondExpLong (LOCAL_ID *localId, opLoc sd, PICODE pIcode, 
  286.                           hlFirst f, Int ix, operDu du, Int off)
  287. /* Returns an identifier conditional expression node of type LONG_VAR */
  288. { COND_EXPR *newExp;
  289.   Int idx;
  290.  
  291.     newExp = newCondExp (IDENTIFIER);
  292.  
  293.     /* Check for long constant and save it as a constant expression */
  294.     if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I))  /* constant */
  295.     {
  296.         newExp->expr.ident.idType = CONSTANT;
  297.         if (f == HIGH_FIRST)
  298.             newExp->expr.ident.idNode.kte.kte = (pIcode->ic.ll.immed.op << 16) +
  299.                                          (pIcode+off)->ic.ll.immed.op;
  300.         else        /* LOW_FIRST */
  301.             newExp->expr.ident.idNode.kte.kte = 
  302.                 ((pIcode+off)->ic.ll.immed.op << 16)+ pIcode->ic.ll.immed.op;
  303.         newExp->expr.ident.idNode.kte.size = 4;
  304.     }
  305.     /* Save it as a long expression (reg, stack or glob) */
  306.     else
  307.     {
  308.         idx = newLongId (localId, sd, pIcode, f, ix, du, off);
  309.         newExp->expr.ident.idType = LONG_VAR;
  310.         newExp->expr.ident.idNode.longIdx = idx;
  311.     }
  312.     return (newExp);
  313. }
  314.  
  315.  
  316. COND_EXPR *idCondExpFunc (PPROC pproc, PSTKFRAME args)
  317. /* Returns an identifier conditional expression node of type FUNCTION */
  318. { COND_EXPR *newExp;
  319.  
  320.     newExp = newCondExp (IDENTIFIER);
  321.     newExp->expr.ident.idType = FUNCTION;
  322.     newExp->expr.ident.idNode.call.proc = pproc;
  323.     newExp->expr.ident.idNode.call.args = args;
  324.     return (newExp);
  325. }
  326.  
  327.  
  328. COND_EXPR *idCondExpOther (byte seg, byte regi, int16 off)
  329. /* Returns an identifier conditional expression node of type OTHER. 
  330.  * Temporary solution, should really be encoded as an indexed type (eg.
  331.  * arrays). */
  332. { COND_EXPR *newExp;
  333.  
  334.     newExp = newCondExp (IDENTIFIER);
  335.     newExp->expr.ident.idType = OTHER;
  336.     newExp->expr.ident.idNode.other.seg = seg;
  337.     newExp->expr.ident.idNode.other.regi = regi;
  338.     newExp->expr.ident.idNode.other.off = off;
  339.     return (newExp);
  340. }
  341.  
  342.  
  343. COND_EXPR *idCondExpID (ID *retVal, LOCAL_ID *locsym, Int ix)
  344. /* Returns an identifier conditional expression node of type TYPE_LONG or
  345.  * TYPE_WORD_SIGN    */
  346. { COND_EXPR *newExp;
  347.   Int idx;
  348.  
  349.     newExp = newCondExp (IDENTIFIER);
  350.     if (retVal->type == TYPE_LONG_SIGN)
  351.     {
  352.         idx = newLongRegId (locsym, TYPE_LONG_SIGN, retVal->id.longId.h,
  353.                             retVal->id.longId.l, ix);
  354.         newExp->expr.ident.idType = LONG_VAR;
  355.         newExp->expr.ident.idNode.longIdx = idx;
  356.     }
  357.     else if (retVal->type == TYPE_WORD_SIGN)
  358.     {
  359.         newExp->expr.ident.idType = REGISTER;
  360.         newExp->expr.ident.idNode.regiIdx = newByteWordRegId (locsym, 
  361.                                          TYPE_WORD_SIGN, retVal->id.regi);
  362.         newExp->expr.ident.regiType = WORD_REG;
  363.     }
  364.     return (newExp);
  365. }
  366.  
  367.  
  368. COND_EXPR *idCondExp (PICODE pIcode, opLoc sd, PPROC pProc, Int i, 
  369.                       PICODE duIcode, operDu du)
  370. /* Returns an identifier conditional expression node, according to the given
  371.  * type.
  372.  * Arguments: i : index into the icode array, used for newLongRegId only. 
  373.  *            duIcode: icode instruction that needs the du set.
  374.  *            du: operand is defined or used in current instruction.    */
  375. { COND_EXPR *newExp;
  376.   PMEM pm;
  377.   Int idx;          /* idx into pIcode->localId table */
  378.  
  379.     pm = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst;
  380.  
  381.     if (((sd == DST) && (pIcode->ic.ll.flg & IM_DST) == IM_DST) ||
  382.         ((sd == SRC) && (pIcode->ic.ll.flg & IM_SRC)) ||
  383.         (sd == LHS_OP))             /* for MUL lhs */
  384.     {                                                   /* implicit dx:ax */
  385.         idx = newLongRegId (&pProc->localId, TYPE_LONG_SIGN, rDX, rAX, i);
  386.         newExp = idCondExpLongIdx (idx);
  387.         setRegDU (duIcode, rDX, du); 
  388.         setRegDU (duIcode, rAX, du);
  389.     }
  390.  
  391.     else if ((sd == DST) && (pIcode->ic.ll.flg & IM_TMP_DST) == IM_TMP_DST)
  392.     {                                                   /* implicit tmp */
  393.         newExp = idCondExpReg (rTMP, 0, &pProc->localId);
  394.         setRegDU (duIcode, rTMP, (operDu)USE);
  395.     }
  396.  
  397.     else if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I)) /* constant */
  398.         newExp = idCondExpKte (pIcode->ic.ll.immed.op, 2);
  399.  
  400.     else if (pm->regi == 0)                             /* global variable */
  401.         newExp = idCondExpGlob (pm->segValue, pm->off);
  402.  
  403.     else if (pm->regi < INDEXBASE)                      /* register */
  404.     {
  405.         newExp = idCondExpReg (pm->regi, (sd == SRC) ? pIcode->ic.ll.flg :
  406.                             pIcode->ic.ll.flg & NO_SRC_B, &pProc->localId);
  407.         setRegDU (duIcode, pm->regi, du);
  408.     }
  409.  
  410.     else if (pm->off)                                   /* offset */
  411.     {
  412.         if ((pm->seg == rSS) && (pm->regi == INDEXBASE + 6)) /* idx on bp */
  413.         {
  414.             if (pm->off >= 0)                           /* argument */
  415.                 newExp = idCondExpParam (pm->off, &pProc->args);
  416.             else                                        /* local variable */
  417.                 newExp = idCondExpLoc (pm->off, &pProc->localId); 
  418.         }
  419.         else if ((pm->seg == rDS) && (pm->regi == INDEXBASE + 7)) /* bx */
  420.         {
  421.             if (pm->off > 0)        /* global variable */
  422.                 newExp = idCondExpIdxGlob (pm->segValue, pm->off, rBX,
  423.                                         &pProc->localId);
  424.             else
  425.                 newExp = idCondExpOther (pm->seg, pm->regi, pm->off);
  426.             setRegDU (duIcode, rBX, (operDu)USE);
  427.         }
  428.         else                                            /* idx <> bp, bx */
  429.             newExp = idCondExpOther (pm->seg, pm->regi, pm->off);
  430.             /**** check long ops, indexed global var *****/
  431.     }
  432.  
  433.     else  /* (pm->regi >= INDEXBASE && pm->off = 0) => indexed && no off */ 
  434.     {
  435.         if ((pm->seg == rDS) && (pm->regi > INDEXBASE + 3)) /* dereference */
  436.         {
  437.             switch (pm->regi) {
  438.               case INDEXBASE + 4:   newExp = idCondExpReg(rSI, 0, &pProc->localId);
  439.                                     setRegDU (duIcode, rSI, du);
  440.                                     break;
  441.               case INDEXBASE + 5:   newExp = idCondExpReg(rDI, 0, &pProc->localId);
  442.                                     setRegDU (duIcode, rDI, du);
  443.                                     break;
  444.               case INDEXBASE + 6:   newExp = idCondExpReg(rBP, 0, &pProc->localId);
  445.                                     break;
  446.               case INDEXBASE + 7:   newExp = idCondExpReg(rBX, 0, &pProc->localId);
  447.                                     setRegDU (duIcode, rBX, du);
  448.                                     break;
  449.             }
  450.             newExp = unaryCondExp (DEREFERENCE, newExp);
  451.         }
  452.         else
  453.             newExp = idCondExpOther (pm->seg, pm->regi, 0);
  454.     }
  455.  
  456.     return (newExp);
  457. }
  458.  
  459.  
  460. condId idType (PICODE pIcode, opLoc sd)
  461. /* Returns the identifier type */
  462. { PMEM pm;
  463.  
  464.     pm = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst;
  465.  
  466.     if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I))
  467.         return (CONSTANT);
  468.     else if (pm->regi == 0)
  469.         return (GLOB_VAR);
  470.     else if (pm->regi < INDEXBASE)
  471.         return (REGISTER);
  472.     else if ((pm->seg == rSS) && (pm->regi == INDEXBASE))
  473.     {
  474.         if (pm->off >= 0)
  475.             return (PARAM);
  476.         else
  477.             return (LOCAL_VAR);
  478.     }
  479.     else
  480.         return (OTHER);
  481. }
  482.  
  483.  
  484. /* Size of hl types */
  485. Int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4};
  486.  
  487.  
  488. Int hlTypeSize (COND_EXPR *exp, PPROC pproc)
  489. /* Returns the type of the expression */
  490. { Int first, second;
  491.  
  492.     if (exp == NULL)
  493.         return (2);        /* for TYPE_UNKNOWN */
  494.  
  495.     switch (exp->type) {
  496.       case BOOLEAN_OP:     first = hlTypeSize (exp->expr.boolExpr.lhs, pproc);
  497.                         second = hlTypeSize (exp->expr.boolExpr.rhs, pproc);
  498.                         if (first > second)
  499.                             return (first);
  500.                         else
  501.                             return (second);
  502.                     
  503.       case NEGATION:    case ADDRESSOF:    
  504.       case POST_INC:    case POST_DEC:
  505.       case PRE_INC:        case PRE_DEC:
  506.       case DEREFERENCE:    return (hlTypeSize (exp->expr.unaryExp, pproc));
  507.                         
  508.       case IDENTIFIER:
  509.             switch (exp->expr.ident.idType) {
  510.               case GLOB_VAR:
  511.                     return (symtab.sym[exp->expr.ident.idNode.globIdx].size);
  512.               case REGISTER:
  513.                     if (exp->expr.ident.regiType == BYTE_REG)
  514.                         return (1);
  515.                     else
  516.                         return (2);
  517.               case LOCAL_VAR:
  518.                     return (hlSize[pproc->localId.id[exp->expr.ident.idNode.localIdx].type]);
  519.               case PARAM:
  520.                     return (hlSize[pproc->args.sym[exp->expr.ident.idNode.paramIdx].type]);
  521.               case GLOB_VAR_IDX:
  522.                     return (hlSize[pproc->localId.id[exp->expr.ident.idNode.idxGlbIdx].type]);
  523.               case CONSTANT:
  524.                     return (exp->expr.ident.idNode.kte.size);
  525.               case STRING:
  526.                     return (2);
  527.               case LONG_VAR:
  528.                     return (4);
  529.               case FUNCTION:
  530.                     return (hlSize[exp->expr.ident.idNode.call.proc->retVal.type]);
  531.               case OTHER:
  532.                     return (2);
  533.             } /* eos */
  534.             break;
  535.     }
  536.     return 2;            // CC: is this correct?
  537. }
  538.  
  539.  
  540. hlType expType (COND_EXPR *exp, PPROC pproc)
  541. /* Returns the type of the expression */
  542. { hlType first, second;
  543.  
  544.     if (exp == NULL)
  545.         return (TYPE_UNKNOWN);
  546.  
  547.     switch (exp->type) {
  548.       case BOOLEAN_OP:     first = expType (exp->expr.boolExpr.lhs, pproc);
  549.                         second = expType (exp->expr.boolExpr.rhs, pproc);
  550.                         if (first != second)
  551.                         {
  552.                             if (hlTypeSize (exp->expr.boolExpr.lhs, pproc) > 
  553.                                 hlTypeSize (exp->expr.boolExpr.rhs, pproc))
  554.                                 return (first);
  555.                             else
  556.                                 return (second);
  557.                         }
  558.                         else
  559.                             return (first);
  560.  
  561.       case POST_INC: case POST_DEC:
  562.       case PRE_INC:  case PRE_DEC:
  563.       case NEGATION:    return (expType (exp->expr.unaryExp, pproc));
  564.  
  565.       case ADDRESSOF:    return (TYPE_PTR);        /***????****/
  566.       case DEREFERENCE:    return (TYPE_PTR);
  567.       case IDENTIFIER:
  568.             switch (exp->expr.ident.idType) {
  569.               case GLOB_VAR:
  570.                     return (symtab.sym[exp->expr.ident.idNode.globIdx].type);
  571.               case REGISTER:
  572.                     if (exp->expr.ident.regiType == BYTE_REG)
  573.                         return (TYPE_BYTE_SIGN);
  574.                     else
  575.                         return (TYPE_WORD_SIGN);
  576.               case LOCAL_VAR:
  577.                     return (pproc->localId.id[exp->expr.ident.idNode.localIdx].type);
  578.               case PARAM:
  579.                     return (pproc->args.sym[exp->expr.ident.idNode.paramIdx].type);
  580.               case GLOB_VAR_IDX:
  581.                     return (pproc->localId.id[exp->expr.ident.idNode.idxGlbIdx].type);
  582.               case CONSTANT:
  583.                     return (TYPE_CONST);
  584.               case STRING:
  585.                     return (TYPE_STR);
  586.               case LONG_VAR:
  587.                     return (pproc->localId.id[exp->expr.ident.idNode.longIdx].type);
  588.               case FUNCTION:
  589.                     return (exp->expr.ident.idNode.call.proc->retVal.type);
  590.               case OTHER:
  591.                     return (TYPE_UNKNOWN);
  592.             } /* eos */
  593.     }
  594.     return TYPE_UNKNOWN;        // CC: Correct?
  595. }
  596.  
  597.  
  598. void removeRegFromLong (byte regi, LOCAL_ID *locId, COND_EXPR *tree)
  599. /* Removes the register from the tree.  If the register was part of a long
  600.  * register (eg. dx:ax), the node gets transformed into an integer register
  601.  * node.        */
  602. {
  603.     IDENTTYPE* ident;         /* ptr to an identifier */
  604.     byte otherRegi;         /* high or low part of long register */
  605.  
  606.     switch (tree->type) {
  607.       case BOOLEAN_OP:
  608.                         break;
  609.       case POST_INC: case POST_DEC:
  610.       case PRE_INC: case PRE_DEC:
  611.       case NEGATION: case ADDRESSOF:
  612.       case DEREFERENCE:
  613.                         break;
  614.       case IDENTIFIER:
  615.             ident = &tree->expr.ident;
  616.             if (ident->idType == LONG_VAR)
  617.             {
  618.                 otherRegi = otherLongRegi (regi, ident->idNode.longIdx, locId);
  619.                 ident->idType = REGISTER;
  620.                 ident->regiType = WORD_REG;
  621.                 ident->idNode.regiIdx = newByteWordRegId (locId, TYPE_WORD_SIGN,
  622.                                                       otherRegi); 
  623.             }
  624.             break;
  625.     }
  626. }
  627.  
  628.  
  629. static char *getString (Int offset)
  630. /* Returns the string located in image, formatted in C format. */
  631. { char *o;
  632.   Int strLen, i;
  633.  
  634.     strLen = strSize (&prog.Image[offset], '\0');
  635.     o = (char *) allocMem((strLen*2+1) * sizeof(char));
  636.     o[0] = '"';
  637.     o[1] = '\0';
  638.     for (i = 0; i < strLen; i++)
  639.         strcat (o, cChar(prog.Image[offset+i]));
  640.     strcat (o, "\"\0");
  641.     return (o);
  642. }
  643.  
  644.  
  645. char *walkCondExpr (COND_EXPR* exp, PPROC pProc, Int* numLoc)
  646. /* Walks the conditional expression tree and returns the result on a string */
  647. { int16 off;                /* temporal - for OTHER */
  648.   ID* id;                   /* Pointer to local identifier table */
  649.   char* o;                  /* Operand string pointer */
  650.   boolT needBracket;        /* Determine whether parenthesis is needed */
  651.   BWGLB_TYPE* bwGlb;         /* Ptr to BWGLB_TYPE (global indexed var) */
  652.   PSTKSYM psym;                /* Pointer to argument in the stack */
  653.   char* condExp, *e;        /* Return and intermediate expressions */
  654.  
  655.     condExp = (char*) allocMem (EXP_SIZE * sizeof(char));
  656.     condExp[0] = '\0';
  657.  
  658.     if (exp == NULL)
  659.         return (condExp);
  660.  
  661.     needBracket = TRUE;
  662.     switch (exp->type)
  663.     {
  664.       case BOOLEAN_OP:    strcat (condExp, "(");
  665.                         e = walkCondExpr(exp->expr.boolExpr.lhs, pProc, numLoc);
  666.                         strcat (condExp, e);
  667.                         strcat (condExp, condOpSym[exp->expr.boolExpr.op]);
  668.                         e = walkCondExpr(exp->expr.boolExpr.rhs, pProc, numLoc);
  669.                         strcat (condExp, e);
  670.                         strcat (condExp, ")");
  671.                         break;
  672.  
  673.       case NEGATION:    if (exp->expr.unaryExp->type == IDENTIFIER)
  674.                         {
  675.                             needBracket = FALSE;
  676.                             strcat (condExp, "!");
  677.                         }
  678.                         else
  679.                             strcat (condExp, "! (");
  680.                         e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  681.                         strcat (condExp, e);
  682.                         if (needBracket == TRUE)
  683.                             strcat (condExp, ")");
  684.                         break;
  685.  
  686.       case ADDRESSOF:   if (exp->expr.unaryExp->type == IDENTIFIER)
  687.                         {
  688.                             needBracket = FALSE;
  689.                             strcat (condExp, "&");
  690.                         }
  691.                         else
  692.                             strcat (condExp, "&(");
  693.                         e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  694.                         strcat (condExp, e);
  695.                         if (needBracket == TRUE)
  696.                             strcat (condExp, ")");
  697.                         break;
  698.  
  699.       case DEREFERENCE: if (exp->expr.unaryExp->type == IDENTIFIER)
  700.                         {
  701.                             needBracket = FALSE;
  702.                             strcat (condExp, "*");
  703.                         }
  704.                         else
  705.                             strcat (condExp, "*(");
  706.                         e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  707.                         strcat (condExp, e);
  708.                         if (needBracket == TRUE)
  709.                             strcat (condExp, ")");
  710.                         break;
  711.  
  712.       case POST_INC:    e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  713.                         strcat (condExp, e);
  714.                         strcat (condExp, "++");
  715.                         break;
  716.  
  717.       case POST_DEC:    e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  718.                         strcat (condExp, e);
  719.                         strcat (condExp, "--");
  720.                         break;
  721.  
  722.       case PRE_INC:     strcat (condExp, "++");
  723.                         e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  724.                         strcat (condExp, e);
  725.                         break;
  726.  
  727.       case PRE_DEC:     strcat (condExp, "--");
  728.                         e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
  729.                         strcat (condExp, e);
  730.                         break;
  731.  
  732.       case IDENTIFIER:
  733.                           o = (char*) allocMem (operandSize);
  734.                         switch (exp->expr.ident.idType) {
  735.                           case GLOB_VAR:    sprintf (o, "%s",
  736.                             symtab.sym[exp->expr.ident.idNode.globIdx].name);
  737.                                             break;
  738.                           case REGISTER:    
  739.                             id = &pProc->localId.id[exp->expr.ident.idNode.regiIdx];
  740.                             if (id->name[0] == '\0')    /* no name */
  741.                             {
  742.                                 sprintf (id->name, "loc%ld", ++(*numLoc));
  743.                                 if (id->id.regi < rAL)
  744.                                     appendStrTab (&cCode.decl, 
  745.                                               "%s %s; /* %s */\n",
  746.                                               hlTypes[id->type], id->name,
  747.                                               wordReg[id->id.regi - rAX]);
  748.                                 else
  749.                                     appendStrTab (&cCode.decl, 
  750.                                               "%s %s; /* %s */\n",
  751.                                               hlTypes[id->type], id->name,
  752.                                               byteReg[id->id.regi - rAL]);
  753.                             }
  754.                             if (id->hasMacro)
  755.                                 sprintf (o, "%s(%s)", id->macro, id->name);
  756.                             else
  757.                                 sprintf (o, "%s", id->name);
  758.                             break;
  759.  
  760.                           case LOCAL_VAR:   
  761.                             sprintf (o, "%s",
  762.                                      pProc->localId.id[exp->expr.ident.idNode.localIdx].name);
  763.                             break;
  764.  
  765.                           case PARAM:
  766.                             psym = &pProc->args.sym[exp->expr.ident.idNode.paramIdx];
  767.                             if (psym->hasMacro)
  768.                                 sprintf (o, "%s(%s)", psym->macro, psym->name);
  769.                             else
  770.                                 sprintf (o, "%s", psym->name);
  771.                             break;
  772.  
  773.                           case GLOB_VAR_IDX:
  774.                             bwGlb = &pProc->localId.id[exp->expr.ident.idNode.idxGlbIdx].id.bwGlb;
  775.                           
  776.                             sprintf (o, "%d[%s]", (bwGlb->seg << 4) +
  777.                                      bwGlb->off, wordReg[bwGlb->regi - rAX]);
  778.                             break;
  779.  
  780.                           case CONSTANT:       
  781.                             if (exp->expr.ident.idNode.kte.kte < 1000)
  782.                                sprintf (o,"%d",exp->expr.ident.idNode.kte.kte);
  783.                             else
  784.                                sprintf(o,"0x%X",exp->expr.ident.idNode.kte.kte);
  785.                             break;
  786.  
  787.                           case STRING:
  788.                             o = getString (exp->expr.ident.idNode.strIdx);
  789.                             break;
  790.  
  791.                           case LONG_VAR:    
  792.                             id = &pProc->localId.id[exp->expr.ident.idNode.longIdx];
  793.                             if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/
  794.                                 sprintf (o, "%s", id->name);
  795.                             else if (id->loc == REG_FRAME)
  796.                             {
  797.                                 sprintf (id->name, "loc%ld", ++(*numLoc));
  798.                                 appendStrTab (&cCode.decl, 
  799.                                               "%s %s; /* %s:%s */\n",
  800.                                               hlTypes[id->type], id->name,
  801.                                               wordReg[id->id.longId.h - rAX],
  802.                                               wordReg[id->id.longId.l - rAX]);
  803.                                 sprintf (o, "%s", id->name);
  804.                                 propLongId (&pProc->localId, id->id.longId.l,
  805.                                             id->id.longId.h, id->name); 
  806.                             }
  807.                             else    /* GLB_FRAME */
  808.                             {
  809.                                 if (id->id.longGlb.regi == 0)  /* not indexed */
  810.                                     sprintf (o, "[%ld]", (id->id.longGlb.seg<<4)
  811.                                              + id->id.longGlb.offH);
  812.                                 else if (id->id.longGlb.regi == rBX)
  813.                                     sprintf (o, "[%ld][bx]", 
  814.                                              (id->id.longGlb.seg<<4) + 
  815.                                              id->id.longGlb.offH);
  816.                             }
  817.                             break;
  818.  
  819.                           case FUNCTION:
  820.                             o = writeCall (exp->expr.ident.idNode.call.proc,
  821.                                            exp->expr.ident.idNode.call.args, 
  822.                                            pProc, numLoc);
  823.                             break;
  824.  
  825.                           case OTHER:       
  826.                             off = exp->expr.ident.idNode.other.off; 
  827.                             if (off == 0)   
  828.                                 sprintf (o, "%s[%s]", 
  829.                                 wordReg[exp->expr.ident.idNode.other.seg - rAX],
  830.                                 idxReg[exp->expr.ident.idNode.other.regi - INDEXBASE]);
  831.                             else if (off < 0)
  832.                                 sprintf (o, "%s[%s-%s]",
  833.                                 wordReg[exp->expr.ident.idNode.other.seg - rAX],
  834.                                 idxReg[exp->expr.ident.idNode.other.regi - INDEXBASE],
  835.                                 hexStr (-off));
  836.                             else
  837.                                 sprintf (o, "%s[%s+%s]",
  838.                                 wordReg[exp->expr.ident.idNode.other.seg - rAX],
  839.                                 idxReg[exp->expr.ident.idNode.other.regi - INDEXBASE],
  840.                                 hexStr (off));
  841.                         } /* eos */
  842.                         strcat (condExp, o);
  843.                         break;
  844.     }
  845.  
  846.     return (condExp);
  847. }
  848.  
  849.  
  850. COND_EXPR *copyCondExp (COND_EXPR *exp)
  851. /* Makes a copy of the given expression.  Allocates newExp storage for each
  852.  * node.  Returns the copy. */
  853. {
  854.     COND_EXPR* newExp;        /* Expression node copy */
  855.  
  856.     switch (exp->type) {
  857.       case BOOLEAN_OP:     
  858.             newExp = allocStruc(COND_EXPR);
  859.             memcpy(newExp, exp, sizeof(COND_EXPR));
  860.             newExp->expr.boolExpr.lhs = copyCondExp (exp->expr.boolExpr.lhs);
  861.             newExp->expr.boolExpr.rhs = copyCondExp (exp->expr.boolExpr.rhs);
  862.             break;
  863.  
  864.       case NEGATION:    
  865.       case ADDRESSOF:
  866.       case DEREFERENCE:
  867.             newExp = allocStruc(COND_EXPR);
  868.             memcpy(newExp, exp, sizeof(COND_EXPR));
  869.             newExp->expr.unaryExp = copyCondExp (exp->expr.unaryExp);
  870.             break;
  871.  
  872.       case IDENTIFIER:  
  873.             newExp = allocStruc(COND_EXPR);
  874.             memcpy(newExp, exp, sizeof(COND_EXPR));
  875.     }
  876.     return (newExp);
  877. }
  878.  
  879.  
  880. void changeBoolCondExpOp (COND_EXPR *exp, condOp newOp)
  881. /* Changes the boolean conditional operator at the root of this expression */
  882. {
  883.     exp->expr.boolExpr.op = newOp;
  884. }
  885.  
  886.  
  887. boolT insertSubTreeReg (COND_EXPR *exp, COND_EXPR **tree, byte regi,
  888.                         LOCAL_ID *locsym)
  889. /* Inserts the expression exp into the tree at the location specified by the
  890.  * register regi */
  891. { byte treeReg;
  892.  
  893.     if (*tree == NULL)
  894.         return FALSE;
  895.  
  896.     switch ((*tree)->type) {
  897.       case IDENTIFIER:  
  898.         if ((*tree)->expr.ident.idType == REGISTER)
  899.         {
  900.             treeReg = locsym->id[(*tree)->expr.ident.idNode.regiIdx].id.regi;
  901.             if (treeReg == regi)                        /* word reg */
  902.             {
  903.                 *tree = exp;
  904.                 return TRUE;
  905.             }
  906.             else if ((regi >= rAX) && (regi <= rBX))    /* word/byte reg */
  907.             {
  908.                 if ((treeReg == (regi + rAL-1)) || (treeReg == (regi + rAH-1)))
  909.                 {
  910.                     *tree = exp;
  911.                     return TRUE;
  912.                 }
  913.             }
  914.         }
  915.         return FALSE;
  916.  
  917.       case BOOLEAN_OP:     
  918.             if (insertSubTreeReg (exp, &(*tree)->expr.boolExpr.lhs, regi,
  919.                                   locsym))
  920.                 return TRUE;
  921.             if (insertSubTreeReg (exp, &(*tree)->expr.boolExpr.rhs, regi,
  922.                                   locsym))
  923.                 return TRUE;
  924.             return FALSE;
  925.  
  926.       case NEGATION:
  927.       case ADDRESSOF:
  928.       case DEREFERENCE: 
  929.             if (insertSubTreeReg(exp, &(*tree)->expr.unaryExp,regi, locsym))
  930.                 return TRUE;
  931.             return FALSE;
  932.     }
  933.     return FALSE;
  934. }
  935.  
  936.  
  937. boolT insertSubTreeLongReg (COND_EXPR *exp, COND_EXPR **tree, Int longIdx)
  938. /* Inserts the expression exp into the tree at the location specified by the
  939.  * long register index longIdx*/
  940. {
  941.     switch ((*tree)->type) {
  942.       case IDENTIFIER:  if ((*tree)->expr.ident.idNode.longIdx == longIdx)
  943.                         {
  944.                             *tree = exp;
  945.                             return TRUE;
  946.                         }
  947.                         return FALSE;
  948.                         
  949.       case BOOLEAN_OP:    if (insertSubTreeLongReg (exp, 
  950.                                     &(*tree)->expr.boolExpr.lhs, longIdx))
  951.                             return TRUE;
  952.                         if (insertSubTreeLongReg (exp, 
  953.                                     &(*tree)->expr.boolExpr.rhs, longIdx))
  954.                             return TRUE;
  955.                         return FALSE;
  956.                         
  957.       case NEGATION:
  958.       case ADDRESSOF:
  959.       case DEREFERENCE: if (insertSubTreeLongReg (exp, 
  960.                                         &(*tree)->expr.unaryExp, longIdx))
  961.                             return TRUE;
  962.                         return FALSE;
  963.     }
  964.     return FALSE;
  965. }
  966.                         
  967.  
  968. void freeCondExpr (COND_EXPR *exp)
  969. /* Recursively deallocates the abstract syntax tree rooted at *exp */
  970. {
  971.     switch (exp->type) {
  972.       case BOOLEAN_OP:     freeCondExpr (exp->expr.boolExpr.lhs);
  973.                         freeCondExpr (exp->expr.boolExpr.rhs);
  974.                         break;
  975.       case NEGATION:
  976.       case ADDRESSOF:
  977.       case DEREFERENCE: freeCondExpr (exp->expr.unaryExp);
  978.                         break;
  979.     }
  980.     free (exp);
  981. }
  982.  
  983.  
  984. /***************************************************************************
  985.  * Expression stack functions
  986.  **************************************************************************/
  987.  
  988. void initExpStk()
  989. /* Reinitalizes the expression stack (expStk) to NULL, by freeing all the
  990.  * space allocated (if any).        */
  991. { EXP_STK *top;
  992.  
  993.     while (expStk != NULL)
  994.     {
  995.         top = expStk;
  996.         expStk = expStk->next;
  997.         free (top);
  998.     }
  999. }
  1000.  
  1001.  
  1002. void pushExpStk (COND_EXPR *exp)
  1003. /* Pushes the given expression onto the local stack (expStk). */
  1004. { EXP_STK *newExp;
  1005.  
  1006.     newExp = allocStruc(EXP_STK);
  1007.     newExp->exp = exp;
  1008.     newExp->next = expStk;
  1009.     expStk = newExp;
  1010. }
  1011.  
  1012.  
  1013. COND_EXPR *popExpStk()
  1014. /* Returns the element on the top of the local expression stack (expStk),
  1015.  * and deallocates the space allocated by this node.
  1016.  * If there are no elements on the stack, returns NULL. */
  1017. { EXP_STK *top;
  1018.   COND_EXPR *topExp;
  1019.  
  1020.     if (expStk != NULL)
  1021.     {
  1022.         topExp = expStk->exp;
  1023.         top = expStk;
  1024.         expStk = expStk->next;
  1025.         free (top);
  1026.         return (topExp);
  1027.     }
  1028.     else
  1029.         return (NULL);
  1030. }
  1031.  
  1032. Int numElemExpStk()
  1033. /* Returns the number of elements available in the expression stack */
  1034. { EXP_STK *top;
  1035.   Int num;
  1036.  
  1037.     num = 0; 
  1038.     top = expStk;
  1039.     while (top)
  1040.     {
  1041.         top = top->next;
  1042.         num++;
  1043.     }
  1044.     return (num);
  1045. }
  1046.  
  1047. boolT emptyExpStk()
  1048. /* Returns whether the expression stack is empty or not */
  1049. {
  1050.     if (expStk == NULL)
  1051.         return TRUE;
  1052.     return FALSE;
  1053. }
  1054.