home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / TestNode.C < prev    next >
C/C++ Source or Header  |  1998-11-23  |  5KB  |  202 lines

  1. // $Id: TestNode.C,v 1.8 1998/11/23 17:43:35 zeller Exp $
  2. // VSL if..then..else..fi construct
  3.  
  4. // Copyright (C) 1995 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ddd/',
  27. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  28.  
  29. char TestNode_rcsid[] = 
  30.     "$Id: TestNode.C,v 1.8 1998/11/23 17:43:35 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "assert.h"
  37. #include <iostream.h>
  38.  
  39. #include "VSLLib.h"
  40.  
  41. #include "VSLNode.h"
  42. #include "CallNode.h"
  43. #include "TestNode.h"
  44. #include "VSLDef.h"
  45.  
  46. DEFINE_TYPE_INFO_1(TestNode, CallNode)
  47.  
  48.  
  49. // TestNode
  50.  
  51. // Dump
  52. void TestNode::dump(ostream& s) const
  53. {
  54.     s << "if "    << *test()
  55.       << " then " << *thetrue()
  56.       << " else " << *thefalse()
  57.       << " fi";
  58. }
  59.  
  60. // ...as tree
  61. void TestNode::_dumpTree(ostream& s) const
  62. {
  63.     test()->dumpTree(s);
  64.     s << ", ";
  65.     thetrue()->dumpTree(s);
  66.     s << ", ";
  67.     thefalse()->dumpTree(s);
  68. }
  69.  
  70. // Evaluate
  71. const Box *TestNode::_eval(ListBox *arglist) const
  72. {
  73.     // Evaluate tester
  74.     const Box *flagBox = test()->eval(arglist);
  75.     if (flagBox == 0)
  76.     return 0;
  77.  
  78.     BoxSize size = flagBox->size();
  79.     ((Box *)flagBox)->unlink();
  80.  
  81.     if (!size.isValid())
  82.     {
  83.     VSLLib::eval_error("invalid if argument");
  84.     return 0;
  85.     }
  86.  
  87.     // Alternative
  88.     if (size != 0)
  89.     return thetrue()->eval(arglist);
  90.     else
  91.     return thefalse()->eval(arglist);
  92. }
  93.  
  94.  
  95. // Optimization
  96.  
  97. // foldConsts: Evaluate function with constant args
  98.  
  99. int TestNode::foldConsts(VSLDef *cdef, VSLNode **node)
  100. {
  101.     int changes = 0;
  102.  
  103.     // Apply to args
  104.     // (CallNode::foldConsts() would destroy the list structure)
  105.     changes += test()->foldConsts(cdef, &test());
  106.     changes += thetrue()->foldConsts(cdef, &thetrue());
  107.     changes += thefalse()->foldConsts(cdef, &thefalse());
  108.  
  109.     // Is test constant?  If not, we're done
  110.     if (!test()->isConst())
  111.     return changes;
  112.  
  113.     // Otherwise: Depending on result, replace by first or second
  114.     // alternative.
  115.  
  116.     // Evaluate tester
  117.  
  118.     sideEffectsProhibited = true;
  119.     sideEffectsOccured = false;
  120.  
  121.     const Box *flagBox = test()->eval(0);
  122.  
  123.     if (flagBox)
  124.     {
  125.     assert(!sideEffectsOccured);
  126.  
  127.     BoxSize size = flagBox->size();
  128.     ((Box *)flagBox)->unlink();
  129.  
  130.     if (size.isValid())
  131.     {
  132.         if (VSEFlags::show_optimize)
  133.         {
  134.         cout << "\n" << cdef->longname() << ": foldConsts: replacing\n" 
  135.             << *this << '\n';
  136.         cout.flush();
  137.         }
  138.  
  139.         // Replace TestNode by first or second alternative
  140.         if (size != 0)
  141.         *node = thetrue(), thetrue() = 0;
  142.         else
  143.         *node = thefalse(), thefalse() = 0;
  144.  
  145.  
  146.         if (VSEFlags::show_optimize)
  147.         {
  148.         cout << "by " << **node << "\n";
  149.         cout.flush();
  150.         }
  151.         
  152.         changes++;
  153.  
  154.         // Delete TestNode and its subtree
  155.         delete this;
  156.     }
  157.     else
  158.         VSLLib::eval_error("invalid if argument", cdef);
  159.     }
  160.  
  161.     sideEffectsProhibited = false;
  162.  
  163.     return changes;
  164. }
  165.  
  166.  
  167. // resolveDefs: below a TestNode, don't complain about endless recursion
  168. int TestNode::resolveDefs(VSLDef *cdef, bool complain_recursive)
  169. {
  170.     int changes = 0;
  171.  
  172.     changes += test()->resolveDefs(cdef, complain_recursive);
  173.     changes += thetrue()->resolveDefs(cdef, false);
  174.     changes += thefalse()->resolveDefs(cdef, false);
  175.  
  176.     return changes;
  177. }
  178.  
  179.  
  180. // Debugging
  181.  
  182. // Representation invariant
  183. bool TestNode::OK() const
  184. {
  185.     EmptyListNode empty;
  186.  
  187.     assert (CallNode::OK());
  188.  
  189.     // Check if argument is 3-element list
  190.     assert (arg() && arg()->isListNode());
  191.     assert (_test() && _test()->tail() && _test()->tail()->isListNode());
  192.     assert (_true() && _true()->tail() && _true()->tail()->isListNode());
  193.     assert (_false() && _false()->tail() && *(_false()->tail()) == empty);
  194.  
  195.     // Check if list elements exist
  196.     assert (test());
  197.     assert (thetrue());
  198.     assert (thefalse());
  199.  
  200.     return true;
  201. }
  202.