home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples1.exe / smc / tree.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  11.9 KB  |  482 lines

  1. /*****************************************************************************/
  2.  
  3. #include "smcPCH.h"
  4. #pragma hdrstop
  5.  
  6. #include "parser.h"
  7. #include "treeops.h"
  8.  
  9. /*****************************************************************************
  10.  *
  11.  *  The low-level tree node allocation routines.
  12.  */
  13.  
  14. #ifndef FAST
  15.  
  16. Tree                parser::parseAllocNode()
  17. {
  18.     Tree            node;
  19.  
  20.     node = (Tree)parseAllocPriv.nraAlloc(sizeof(*node));
  21.  
  22. #ifdef  DEBUG
  23.     node->tnLineNo = -1;
  24. //  node->tnColumn = -1;
  25. #endif
  26.  
  27.     return  node;
  28. }
  29.  
  30. #endif
  31.  
  32. /*****************************************************************************
  33.  *
  34.  *  Allocate a parse tree node with the given operator.
  35.  */
  36.  
  37. Tree                parser::parseCreateNode(treeOps op)
  38. {
  39.     Tree            tree = parseAllocNode();
  40.  
  41. #ifndef NDEBUG
  42.     memset(tree, 0xDD, sizeof(*tree));
  43. #endif
  44.  
  45.     tree->tnOper   = op;
  46.     tree->tnFlags  = 0;
  47.  
  48.     tree->tnLineNo = parseScan->scanGetTokenLno();
  49. //  tree->tnColumn = parseScan->scanGetTokenCol();
  50.  
  51.     return  tree;
  52. }
  53.  
  54. /*****************************************************************************/
  55.  
  56. Tree                parser::parseCreateBconNode(int     val)
  57. {
  58.     Tree            node = parseCreateNode(TN_CNS_INT);
  59.  
  60.     node->tnVtyp             = TYP_BOOL;
  61.     node->tnIntCon.tnIconVal = val;
  62.  
  63.     return  node;
  64. }
  65.  
  66. Tree                parser::parseCreateIconNode(__int32 ival, var_types typ)
  67. {
  68.     Tree            node = parseCreateNode(TN_CNS_INT);
  69.  
  70.     node->tnVtyp             = typ;
  71.     node->tnIntCon.tnIconVal = ival;
  72.  
  73.     if  (typ != TYP_UNDEF)
  74.         return  node;
  75.  
  76.     node->tnOper = TN_ERROR;
  77.     node->tnType = parseStab->stIntrinsicType(typ);
  78.  
  79.     return  node;
  80. }
  81.  
  82. Tree                parser::parseCreateLconNode(__int64 lval, var_types typ)
  83. {
  84.     Tree            node = parseCreateNode(TN_CNS_LNG);
  85.  
  86.     assert(typ == TYP_LONG || typ == TYP_ULONG);
  87.  
  88.     node->tnVtyp             = typ;
  89.     node->tnLngCon.tnLconVal = lval;
  90.  
  91.     return  node;
  92. }
  93.  
  94. Tree                parser::parseCreateFconNode(float fval)
  95. {
  96.     Tree            node = parseCreateNode(TN_CNS_FLT);
  97.  
  98.     node->tnVtyp             = TYP_FLOAT;
  99.     node->tnFltCon.tnFconVal = fval;
  100.  
  101.     return  node;
  102. }
  103.  
  104. Tree                parser::parseCreateDconNode(double dval)
  105. {
  106.     Tree            node = parseCreateNode(TN_CNS_DBL);
  107.  
  108.     node->tnVtyp             = TYP_DOUBLE;
  109.     node->tnDblCon.tnDconVal = dval;
  110.  
  111.     return  node;
  112. }
  113.  
  114. Tree                parser::parseCreateSconNode(stringBuff  sval,
  115.                                                 size_t      slen,
  116.                                                 unsigned    type,
  117.                                                 int         wide,
  118.                                                 Tree        addx)
  119. {
  120.     Tree            node;
  121.     size_t          olen;
  122.     size_t          tlen;
  123.     stringBuff      buff;
  124.     unsigned        flag;
  125.  
  126.     static
  127.     unsigned        tpfl[] =
  128.     {
  129.         0,
  130.         TNF_STR_ASCII,
  131.         TNF_STR_WIDE,
  132.         TNF_STR_STR,
  133.     };
  134.  
  135.     assert(type < arraylen(tpfl));
  136.  
  137.     flag = tpfl[type];
  138.  
  139.     if  (addx)
  140.     {
  141.         unsigned        oldf = addx->tnFlags & (TNF_STR_ASCII|TNF_STR_WIDE|TNF_STR_STR);
  142.  
  143.         assert(addx->tnOper == TN_CNS_STR);
  144.  
  145.         if  (flag != oldf)
  146.         {
  147.             if  (tpfl)
  148.                 parseComp->cmpError(ERRsyntax);
  149.             else
  150.                 flag = oldf;
  151.         }
  152.  
  153.         node = addx;
  154.         olen = addx->tnStrCon.tnSconLen;
  155.         tlen = slen + olen;
  156.     }
  157.     else
  158.     {
  159.         node = parseCreateNode(TN_CNS_STR);
  160.         tlen = slen;
  161.     }
  162.  
  163. #if MGDDATA
  164.  
  165.     UNIMPL(!"save str");
  166.  
  167. #else
  168.  
  169.     stringBuff      dest;
  170.  
  171.     buff = dest = (char *)parseAllocPriv.nraAlloc(roundUp(tlen + 1));
  172.  
  173.     if  (addx)
  174.     {
  175.         memcpy(dest, node->tnStrCon.tnSconVal, olen);
  176.                dest               +=           olen;
  177.     }
  178.  
  179.     memcpy(dest, sval, slen + 1);
  180.  
  181. #endif
  182.  
  183.     node->tnVtyp             = TYP_REF;
  184.     node->tnStrCon.tnSconVal = buff;
  185.     node->tnStrCon.tnSconLen = tlen;
  186.     node->tnStrCon.tnSconLCH = wide;
  187.  
  188.     node->tnFlags |= flag;
  189.  
  190.     return  node;
  191. }
  192.  
  193. Tree                 parser::parseCreateErrNode(unsigned errNum)
  194. {
  195.     Tree            node = parseCreateNode(TN_ERROR);
  196.  
  197.     if  (errNum != ERRnone) parseComp->cmpError(errNum);
  198.  
  199.     node->tnVtyp = TYP_UNDEF;
  200.     node->tnType = parseStab->stIntrinsicType(TYP_UNDEF);
  201.  
  202.     return  node;
  203. }
  204.  
  205. /*****************************************************************************/
  206. #ifdef  DEBUG
  207. /*****************************************************************************/
  208.  
  209. #ifndef __SMC__
  210. const   char    *   treeNodeName(treeOps op);   // moved into macros.cpp
  211. #endif
  212.  
  213. inline
  214. void                treeNodeIndent(unsigned level)
  215. {
  216.     printf("%*c", 1+level*3, ' ');
  217. }
  218.  
  219. void                parser::parseDispTreeNode(Tree tree, unsigned indent, const char *name)
  220. {
  221.     treeNodeIndent(indent);
  222.     printf("[%08X] ", tree);
  223.  
  224.     if  (tree && tree->tnType
  225.               && (NatUns)tree->tnType != 0xCCCCCCCC
  226.               && (NatUns)tree->tnType != 0xDDDDDDDD
  227.               && tree->tnOper != TN_LIST)
  228.     {
  229.         printf("(type=%s)", parseStab->stTypeName(tree->tnType, NULL));
  230.     }
  231.  
  232.     assert(tree || name);
  233.  
  234.     if  (!name)
  235.     {
  236.         name = (tree->tnOper < TN_COUNT) ? treeNodeName(tree->tnOperGet())
  237.                                          : "<ERROR>";
  238.     }
  239.  
  240.     printf("%12s ", name);
  241.  
  242.     assert(tree == 0 || tree->tnOper < TN_COUNT);
  243. }
  244.  
  245. void                parser::parseDispTree(Tree tree, unsigned indent)
  246. {
  247.     unsigned        kind;
  248.  
  249.     if  (tree == NULL)
  250.     {
  251.         treeNodeIndent(indent);
  252.         printf("[%08X] <NULL>\n", tree);
  253.         return;
  254.     }
  255.  
  256.     assert((int)tree != 0xDDDDDDDD);    /* Value used to initalize nodes */
  257.  
  258.     /* Make sure we're not stuck in a recursive tree */
  259.  
  260.     assert(indent < 32);
  261.  
  262.     if  (tree->tnOper >= TN_COUNT)
  263.     {
  264.         parseDispTreeNode(tree, indent); NO_WAY(!"bogus operator");
  265.     }
  266.  
  267.     kind = tree->tnOperKind();
  268.  
  269.     /* Is this a constant node? */
  270.  
  271.     if  (kind & TNK_CONST)
  272.     {
  273.         parseDispTreeNode(tree, indent);
  274.  
  275.         switch  (tree->tnOper)
  276.         {
  277.         case TN_CNS_INT: printf(" %ld" , tree->tnIntCon.tnIconVal); break;
  278.         case TN_CNS_LNG: printf(" %Ld" , tree->tnLngCon.tnLconVal); break;
  279.         case TN_CNS_FLT: printf(" %f"  , tree->tnFltCon.tnFconVal); break;
  280.         case TN_CNS_DBL: printf(" %lf" , tree->tnDblCon.tnDconVal); break;
  281.         case TN_CNS_STR: printf(" '%s'", tree->tnStrCon.tnSconVal); break;
  282.         }
  283.  
  284.         printf("\n");
  285.         return;
  286.     }
  287.  
  288.     /* Is this a leaf node? */
  289.  
  290.     if  (kind & TNK_LEAF)
  291.     {
  292.         parseDispTreeNode(tree, indent);
  293.  
  294.         switch  (tree->tnOper)
  295.         {
  296.         case TN_NAME:
  297.             printf("'%s'", tree->tnName.tnNameId->idSpelling());
  298.             break;
  299.  
  300.         case TN_THIS:
  301.         case TN_NULL:
  302.         case TN_BASE:
  303.         case TN_DBGBRK:
  304.             break;
  305.  
  306.         default:
  307.             NO_WAY(!"don't know how to display this leaf node");
  308.         }
  309.  
  310.         printf("\n");
  311.         return;
  312.     }
  313.  
  314.     /* Is it a 'simple' unary/binary operator? */
  315.  
  316.     if  (kind & TNK_SMPOP)
  317.     {
  318.         if  (tree->tnOp.tnOp2)
  319.             parseDispTree(tree->tnOp.tnOp2, indent + 1);
  320.  
  321.         parseDispTreeNode(tree, indent);
  322.  
  323.         /* Check for a few special cases */
  324.  
  325.         switch (tree->tnOper)
  326.         {
  327.         case TN_NEW:
  328.         case TN_CAST:
  329.             if  (!(tree->tnFlags & TNF_BOUND))
  330.                 printf(" type='%s'", parseStab->stTypeName(tree->tnType, NULL));
  331.             break;
  332.  
  333.         default:
  334.             break;
  335.         }
  336.  
  337.         printf("\n");
  338.  
  339.         if  (tree->tnOp.tnOp1)
  340.             parseDispTree(tree->tnOp.tnOp1, indent + 1);
  341.  
  342.         return;
  343.     }
  344.  
  345.     /* See what kind of a special operator we have here */
  346.  
  347.     switch  (tree->tnOper)
  348.     {
  349.         Tree            name;
  350.         Tree            init;
  351.  
  352.     case TN_BLOCK:
  353.  
  354.         if  (tree->tnBlock.tnBlkDecl)
  355.             parseDispTree(tree->tnBlock.tnBlkDecl, indent + 1);
  356.  
  357.         parseDispTreeNode(tree, indent);
  358.         printf(" parent=[%08X]", tree->tnBlock.tnBlkParent);
  359.         printf( " decls=[%08X]", tree->tnBlock.tnBlkDecl  );
  360.         printf("\n");
  361.  
  362.         if  (tree->tnBlock.tnBlkStmt)
  363.             parseDispTree(tree->tnBlock.tnBlkStmt, indent + 1);
  364.  
  365.         break;
  366.  
  367.     case TN_VAR_DECL:
  368.  
  369.         init = NULL;
  370.         name = tree->tnDcl.tnDclInfo;
  371.  
  372.         parseDispTreeNode(tree, indent);
  373.         printf(" next=[%08X] ", tree->tnDcl.tnDclNext);
  374.  
  375.         if  (name)
  376.         {
  377.             if  (name->tnOper == TN_LIST)
  378.             {
  379.                 init = name->tnOp.tnOp2;
  380.                 name = name->tnOp.tnOp1;
  381.             }
  382.  
  383.             assert(name && name->tnOper == TN_NAME);
  384.  
  385.             printf("'%s'\n", name->tnName.tnNameId->idSpelling());
  386.  
  387.             if  (init)
  388.                 parseDispTree(init, indent + 1);
  389.         }
  390.         else
  391.         {
  392.             SymDef          vsym = tree->tnDcl.tnDclSym;
  393.  
  394.             assert(vsym && vsym->sdSymKind == SYM_VAR);
  395.  
  396.             printf("[sym=%08X] '%s'\n", vsym, vsym->sdSpelling());
  397.         }
  398.  
  399.         break;
  400.  
  401.     case TN_FNC_SYM:
  402.     case TN_FNC_PTR:
  403.  
  404.         if  (tree->tnFncSym.tnFncObj)
  405.             parseDispTree(tree->tnFncSym.tnFncObj, indent + 1);
  406.  
  407.         parseDispTreeNode(tree, indent);
  408.         printf("'%s'\n", tree->tnFncSym.tnFncSym->sdSpelling());
  409.  
  410.         if  (tree->tnFncSym.tnFncArgs)
  411.             parseDispTree(tree->tnFncSym.tnFncArgs, indent + 1);
  412.         return;
  413.  
  414.     case TN_LCL_SYM:
  415.  
  416.         parseDispTreeNode(tree, indent);
  417.         if  (tree->tnLclSym.tnLclSym->sdIsImplicit)
  418.             printf(" TEMP(%d)\n", tree->tnLclSym.tnLclSym->sdVar.sdvILindex);
  419.         else
  420.             printf(" sym='%s'\n", parseStab->stTypeName(NULL, tree->tnLclSym.tnLclSym, NULL, NULL, true));
  421.         break;
  422.  
  423.     case TN_VAR_SYM:
  424.     case TN_PROPERTY:
  425.  
  426.         if  (tree->tnVarSym.tnVarObj)
  427.             parseDispTree(tree->tnVarSym.tnVarObj, indent + 1);
  428.  
  429.         parseDispTreeNode(tree, indent);
  430.         printf(" sym='%s'\n", parseStab->stTypeName(NULL, tree->tnVarSym.tnVarSym, NULL, NULL, true));
  431.         break;
  432.  
  433.     case TN_BFM_SYM:
  434.  
  435.         if  (tree->tnBitFld.tnBFinst)
  436.             parseDispTree(tree->tnBitFld.tnBFinst, indent + 1);
  437.  
  438.         parseDispTreeNode(tree, indent);
  439.         printf(" offs=%04X BF=[%u/%u] sym='%s'\n", tree->tnBitFld.tnBFoffs,
  440.                                                    tree->tnBitFld.tnBFlen,
  441.                                                    tree->tnBitFld.tnBFpos,
  442.                                                    parseStab->stTypeName(NULL, tree->tnBitFld.tnBFmsym, NULL, NULL, true));
  443.         break;
  444.  
  445.     case TN_ANY_SYM:
  446.  
  447.         parseDispTreeNode(tree, indent);
  448.         printf(" sym='%s'\n", parseStab->stTypeName(NULL, tree->tnSym.tnSym, NULL, NULL, true));
  449.         break;
  450.  
  451.     case TN_ERROR:
  452.  
  453.         parseDispTreeNode(tree, indent);
  454.         printf("\n");
  455.         break;
  456.  
  457.     case TN_SLV_INIT:
  458.         parseDispTreeNode(tree, indent);
  459.         printf(" at line #%u [offs=%04X]\n", tree->tnInit.tniSrcPos.dsdSrcLno,
  460.                                              tree->tnInit.tniSrcPos.dsdBegPos);
  461.         break;
  462.  
  463.     case TN_NONE:
  464.         parseDispTreeNode(tree, indent);
  465.         if  (tree->tnType)
  466.             printf(" type='%s'", parseStab->stTypeName(tree->tnType, NULL));
  467.         printf("\n");
  468.         break;
  469.  
  470.     default:
  471.         parseDispTreeNode(tree, indent);
  472.  
  473.         printf("<DON'T KNOW HOW TO DISPLAY THIS NODE>\n");
  474.         return;
  475.     }
  476. }
  477.  
  478. /*****************************************************************************/
  479. #endif//DEBUG
  480. /*****************************************************************************/
  481. /*****************************************************************************/
  482.