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 / VSLLib.h < prev    next >
C/C++ Source or Header  |  1998-03-25  |  9KB  |  330 lines

  1. // $Id: VSLLib.h,v 1.12 1998/03/25 12:45:02 zeller Exp $ 
  2. // The VSL Library
  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. #ifndef _DDD_VSLLib_h
  30. #define _DDD_VSLLib_h
  31.  
  32. #ifdef __GNUG__
  33. #pragma interface
  34. #endif
  35.  
  36.  
  37. #include <iostream.h>
  38. #include "strclass.h"
  39.  
  40. #include "bool.h"
  41. #include "VSEFlags.h"
  42. #include "TypeInfo.h"
  43. #include "StringBox.h"
  44. #include "ListBox.h"
  45. #include "TagBox.h"
  46. #include "PrimitiveB.h"
  47.  
  48. class VSLDef;
  49. class VSLDefList;
  50. class VSLNode;
  51.  
  52. class VSLLib;
  53.  
  54. // Custom eval() arguments
  55. // This is just a wrapper around a Box pointer with a few fancy conversions.
  56. class VSLArg {
  57. private:
  58.     Box *_box;
  59.  
  60. public:
  61.     Box *box() const { return _box; }
  62.  
  63.     VSLArg()
  64.     :_box(0)
  65.     {}
  66.  
  67.     VSLArg(char *s)
  68.     :_box(new StringBox(s))
  69.     {}
  70.     
  71.     VSLArg(const string& s)
  72.     :_box(new StringBox(s))
  73.     {}
  74.     
  75.     VSLArg(int n)
  76.     :_box(new SquareBox(n))
  77.     {}
  78.  
  79.     VSLArg(unsigned n)
  80.     :_box(new SquareBox(n))
  81.     {}
  82.  
  83.     // When we are assigned a box, we take control over it
  84.     VSLArg(Box *box)
  85.     :_box(box)
  86.     {}
  87.  
  88.     // When we are assigned a VSLArg, we establish another link...
  89.     VSLArg(const VSLArg& arg)
  90.     :_box(arg.box() ? arg.box()->link() : 0)
  91.     {}
  92.  
  93.     // ...since it will be destroyed when we leave.
  94.     ~VSLArg()
  95.     {
  96.     if (_box)
  97.         _box->unlink();
  98.     }
  99.  
  100.     // Assignment: just the same.
  101.     VSLArg& operator = (Box *box)
  102.     {
  103.     if (box != _box)
  104.     {
  105.         if (_box)
  106.         _box->unlink();
  107.         _box = box;
  108.     }
  109.     return *this;
  110.     }
  111.  
  112.     VSLArg& operator = (const VSLArg& arg)
  113.     {
  114.     if (arg.box() != _box)
  115.     {
  116.         if (_box)
  117.         _box->unlink();
  118.  
  119.         _box = arg.box() ? arg.box()->link() : 0;
  120.     }
  121.     return *this;
  122.     }
  123. };
  124.  
  125.  
  126. // Custom tagging function using VSLArgs
  127. inline VSLArg tag(const VSLArg& arg, Data *data = 0, DataLink *link = 0)
  128. {
  129.     // Prevent double unlink: from Box::tag() and ~VSLArg()
  130.     arg.box()->link();
  131.  
  132.     // Tag the box
  133.     return arg.box()->tag(data, link);
  134. }
  135.  
  136.  
  137.  
  138. // Size of hash table (should be prime)
  139. const int hashSize = 4001;
  140.  
  141. // Flags for optimizing (used internally)
  142. const unsigned _ResolveDefs             = (1 << 4);
  143. const unsigned _ResolveSynonyms         = (1 << 5);
  144. const unsigned _FoldOps                 = (1 << 6);
  145. const unsigned _FoldConsts              = (1 << 7);
  146. const unsigned _InlineFuncs             = (1 << 8);
  147. const unsigned _CountSelfReferences     = (1 << 9);
  148. const unsigned _Cleanup                 = (1 << 10);
  149.  
  150. // Public flags for optimizing
  151. const unsigned ResolveDefs          = _ResolveDefs;
  152. const unsigned ResolveSynonyms      = _ResolveDefs | _ResolveSynonyms;
  153. const unsigned FoldOps              = _ResolveSynonyms | _FoldOps;
  154. const unsigned FoldConsts           = _FoldConsts;
  155. const unsigned InlineFuncs          = _ResolveDefs | _InlineFuncs;
  156. const unsigned CountSelfReferences  = _CountSelfReferences;
  157. const unsigned Cleanup              = _CountSelfReferences | _Cleanup;
  158.  
  159. // Mask for building #iterations
  160. const unsigned loopMask         = (1 << 0 | 1 << 1 | 1 << 2 | 1 << 3);
  161. const unsigned allOpts          = ((unsigned)-1) & ~loopMask;
  162. const unsigned stdOpt           = allOpts | 2;
  163.  
  164.  
  165. // The VSL library
  166. class VSLLib {
  167.     friend class VSLDefList;  // for VSLDefList::replace()
  168.  
  169. public:
  170.     DECLARE_TYPE_INFO
  171.  
  172. private:
  173.     string _lib_name;               // library name
  174.     VSLDefList *defs[hashSize];     // hash table containing definitions
  175.     VSLDef *_first;                 // linked list over definitions
  176.     VSLDef *_last;                  // last def in list
  177.  
  178.     void initHash();
  179.  
  180.     // Optimizing and post-processing
  181.     int bind();                     // bind internal functions to references
  182.     int resolveNames();             // bind names to variables
  183.     int compilePatterns();          // compile call patterns
  184.     int resolveDefs();              // resolve unambiguous function calls
  185.     int resolveSynonyms();          // resolve synonyms
  186.     int foldOps();                  // fold associative operators
  187.     int foldConsts();               // evaluate constants
  188.     int inlineFuncs();              // perform function inlining
  189.     int countSelfReferences();      // count references internal to functions
  190.     int cleanup();                  // remove unreferenced functions
  191.  
  192.     // Front-end for optimizing functions
  193.     void process(unsigned mode = stdOpt);
  194.  
  195.     // Build function call with arglist as argument
  196.     VSLNode *_call(const string& func_name, VSLNode *arglist);
  197.  
  198.     // Build function call with given args
  199.     VSLNode *call(const string& func_name);
  200.     VSLNode *call(const string& func_name, 
  201.           VSLNode *arg1);
  202.     VSLNode *call(const string& func_name, 
  203.           VSLNode *arg1, 
  204.           VSLNode *arg2);
  205.     VSLNode *call(const string& func_name, 
  206.           VSLNode *arg1, 
  207.           VSLNode *arg2, 
  208.           VSLNode *arg3);
  209.  
  210.     // same, but with char *
  211.     VSLNode *call(char *func_name) 
  212.     { 
  213.     return call(string(func_name)); 
  214.     }
  215.     VSLNode *call(char *func_name, 
  216.           VSLNode *arg1)
  217.     { 
  218.     return call(string(func_name), arg1); 
  219.     }
  220.     VSLNode *call(char *func_name, 
  221.           VSLNode *arg1,
  222.           VSLNode *arg2)
  223.     { 
  224.     return call(string(func_name), arg1, arg2);
  225.     }
  226.     VSLNode *call(char *func_name, 
  227.           VSLNode *arg1,
  228.           VSLNode *arg2,
  229.           VSLNode *arg3)
  230.     { 
  231.     return call(string(func_name), arg1, arg2, arg3);
  232.     }
  233.  
  234.     // Add a new function
  235.     VSLDef *add(const string& func_name, 
  236.         VSLNode *pattern, 
  237.         VSLNode *expr = 0,
  238.         bool global = false, 
  239.         const string& filename = "builtin", 
  240.         int lineno = 0);
  241.  
  242.     // Rename function
  243.     int override(const string& func_name);
  244.  
  245.     // Remove definition
  246.     int replace(const string& func_name);
  247.  
  248.     // Find function
  249.     VSLDefList *deflist(const string& func_name) const;
  250.     VSLDef *def(const string& func_name, Box *arg) const;
  251.  
  252.     // The parse function generated by YACC -- this cannot be a C++ name
  253.     friend int VSLLib_parse();
  254.  
  255.     VSLLib(const VSLLib&): _lib_name(), _first(0), _last(0) { assert(0); }
  256.     VSLLib& operator = (const VSLLib&)   { assert(0); return *this; }
  257.  
  258. public:
  259.     // Build
  260.     VSLLib();
  261.     VSLLib(const string& lib_name, unsigned optimize = stdOpt);
  262.     VSLLib(istream& s, unsigned optimize = stdOpt);
  263.  
  264.     // Read
  265.     VSLLib& read(const string& lib_name, unsigned optimize = stdOpt);
  266.     VSLLib& read(istream& s, unsigned optimize = stdOpt);
  267.     static int parse();
  268.  
  269.     // Check if function is present
  270.     bool has(const string& func_name)
  271.     {
  272.     return deflist(func_name) != 0;
  273.     }
  274.  
  275.     // Evaluate function with given argument list
  276.     const Box *eval(const string& func_name, ListBox *arg) const;
  277.     
  278.     // Custom functions
  279.     const Box *eval(const string& func_name, VSLArg args[]) const;
  280.     const Box *eval(const string& func_name, 
  281.             VSLArg arg0 = (Box *)0,
  282.             VSLArg arg1 = (Box *)0,
  283.             VSLArg arg2 = (Box *)0,
  284.             VSLArg arg3 = (Box *)0,
  285.             VSLArg arg4 = (Box *)0,
  286.             VSLArg arg5 = (Box *)0,
  287.             VSLArg arg6 = (Box *)0,
  288.             VSLArg arg7 = (Box *)0,
  289.             VSLArg arg8 = (Box *)0,
  290.             VSLArg arg9 = (Box *)0) const;
  291.  
  292.     // Perform __output() function on arg if present
  293.     void output(Box *&arg);
  294.  
  295.     // Destroy
  296.     virtual ~VSLLib();
  297.  
  298.     // Message handling
  299.     static void echo(const string& s);
  300.  
  301.     // Parsing messages
  302.     static void parse_echo(const string& s);
  303.     static void parse_error(const string& s);
  304.     static void parse_warning(const string& s);
  305.  
  306.     // Evaluation messages
  307.     static void eval_echo(const string& s, const VSLDef *def = 0);
  308.     static void eval_error(const string& s, const VSLDef *def = 0);
  309.     static void eval_warning(const string& s, const VSLDef *def = 0);
  310.  
  311.     // Debugging
  312.     friend ostream& operator << (ostream& s, const VSLLib& lib);
  313.     void dumpTree(ostream& s) const;
  314.     VSLDef *lastdef()  { return _last; }
  315.     VSLDef *firstdef() { return _first; }
  316.  
  317.     // Background processing
  318.     static void (*background)();
  319.  
  320.     // Representation invariant
  321.     virtual bool OK() const;
  322. };
  323.  
  324. inline int VSLLib::parse()
  325. {
  326.     return VSLLib_parse();
  327. }
  328.  
  329. #endif
  330.