home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-base.tgz / octave-1.1.1p1-base.tar / fsf / octave / src / tree-const.h < prev    next >
C/C++ Source or Header  |  1996-09-27  |  12KB  |  452 lines

  1. // tree-const.h                                        -*- C++ -*-
  2. /*
  3.  
  4. Copyright (C) 1992, 1993, 1994, 1995 John W. Eaton
  5.  
  6. This file is part of Octave.
  7.  
  8. Octave is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. Octave is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Octave; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. */
  23.  
  24. #if !defined (octave_tree_const_h)
  25. #define octave_tree_const_h 1
  26.  
  27. #include <iostream.h>
  28.  
  29. #include <stdlib.h>
  30.  
  31. #include "mx-base.h"
  32. #include "Range.h"
  33.  
  34. #include "tree-base.h"
  35. #include "tree-expr.h"
  36. #include "oct-obj.h"
  37.  
  38. class idx_vector;
  39. class Octave_map;
  40.  
  41. struct Mapper_fcn;
  42.  
  43. // Constants.
  44.  
  45. class
  46. tree_constant : public tree_fvc
  47. {
  48. private:
  49.  
  50. #include "tc-rep.h"
  51.  
  52. // The real representation of a constant, declared in tc-rep.h
  53.  
  54.   tree_constant_rep *rep;
  55.  
  56. public:
  57.  
  58.   enum magic_colon { magic_colon_t };
  59.   enum all_va_args { all_va_args_t };
  60.  
  61. // Constructors.  It is possible to create the following types of
  62. // constants:
  63. //
  64. // constant type    constructor arguments
  65. // -------------    ---------------------
  66. // unknown          none
  67. // real scalar      double
  68. // real matrix      Matrix
  69. //                  DiagMatrix
  70. //                  RowVector
  71. //                  ColumnVector
  72. // complex scalar   Complex
  73. // complex matrix   ComplexMatrix
  74. //                  ComplexDiagMatrix
  75. //                  ComplexRowVector
  76. //                  ComplexColumnVector
  77. // string           char* (null terminated)
  78. // range            double, double, dobule
  79. //                  Range
  80. // magic colon      tree_constant::magic_colon
  81. // all_va_args      tree_constant::all_va_args
  82.  
  83.   tree_constant (void) : tree_fvc ()
  84.     { rep = new tree_constant_rep (); rep->count = 1; }
  85.  
  86.   tree_constant (double d) : tree_fvc ()
  87.     { rep = new tree_constant_rep (d); rep->count = 1; }
  88.  
  89.   tree_constant (const Matrix& m) : tree_fvc ()
  90.     { rep = new tree_constant_rep (m); rep->count = 1; }
  91.  
  92.   tree_constant (const DiagMatrix& d) : tree_fvc ()
  93.     { rep = new tree_constant_rep (d); rep->count = 1; }
  94.  
  95.   tree_constant (const RowVector& v, int pcv = -1) : tree_fvc ()
  96.     { rep = new tree_constant_rep (v, pcv); rep->count = 1; }
  97.  
  98.   tree_constant (const ColumnVector& v, int pcv = -1) : tree_fvc ()
  99.     { rep = new tree_constant_rep (v, pcv); rep->count = 1; }
  100.  
  101.   tree_constant (const Complex& c) : tree_fvc ()
  102.     { rep = new tree_constant_rep (c); rep->count = 1; }
  103.  
  104.   tree_constant (const ComplexMatrix& m) : tree_fvc ()
  105.     { rep = new tree_constant_rep (m); rep->count = 1; }
  106.  
  107.   tree_constant (const ComplexDiagMatrix& d) : tree_fvc ()
  108.     { rep = new tree_constant_rep (d); rep->count = 1; }
  109.  
  110.   tree_constant (const ComplexRowVector& v, int pcv = -1) : tree_fvc ()
  111.       { rep = new tree_constant_rep (v, pcv); rep->count = 1; }
  112.  
  113.   tree_constant (const ComplexColumnVector& v, int pcv = -1) : tree_fvc () 
  114.       { rep = new tree_constant_rep (v, pcv); rep->count = 1; }
  115.  
  116.   tree_constant (const char *s) : tree_fvc ()
  117.     { rep = new tree_constant_rep (s); rep->count = 1; }
  118.  
  119.   tree_constant (double base, double limit, double inc) : tree_fvc ()
  120.     { rep = new tree_constant_rep (base, limit, inc); rep->count = 1; }
  121.  
  122.   tree_constant (const Range& r) : tree_fvc ()
  123.     { rep = new tree_constant_rep (r); rep->count = 1; }
  124.  
  125.   tree_constant (const Octave_map& m) : tree_fvc ()
  126.     { rep = new tree_constant_rep (m); rep->count = 1; }
  127.  
  128.   tree_constant (tree_constant::magic_colon t) : tree_fvc ()
  129.     {
  130.       tree_constant_rep::constant_type tmp;
  131.       tmp = tree_constant_rep::magic_colon;
  132.       rep = new tree_constant_rep (tmp);
  133.       rep->count = 1;
  134.     }
  135.  
  136.   tree_constant (tree_constant::all_va_args t) : tree_fvc ()
  137.     {
  138.       tree_constant_rep::constant_type tmp;
  139.       tmp = tree_constant_rep::all_va_args;
  140.       rep = new tree_constant_rep (tmp);
  141.       rep->count = 1;
  142.     }
  143.  
  144. // Copy constructor.
  145.  
  146.   tree_constant (const tree_constant& a) : tree_fvc ()
  147.     { rep = a.rep; rep->count++; }
  148.  
  149. // Delete the representation of this constant if the count drops to
  150. // zero.
  151.  
  152.   ~tree_constant (void);
  153.  
  154. #if defined (MDEBUG)
  155.   void *operator new (size_t size);
  156.   void operator delete (void *p, size_t size);
  157. #endif
  158.  
  159. // Simple assignment.
  160.  
  161.   tree_constant operator = (const tree_constant& a);
  162.  
  163. // Indexed assignment.
  164.  
  165.   tree_constant assign (tree_constant& rhs, const Octave_object& args)
  166.     {
  167.       if (rep->count > 1)
  168.     {
  169.       --rep->count;
  170.       rep = new tree_constant_rep (*rep);
  171.       rep->count = 1;
  172.     }
  173.  
  174.       rep->assign (rhs, args);
  175.  
  176.       return *this;
  177.     }
  178.  
  179. // Simple structure assignment.
  180.  
  181.   tree_constant assign_map_element (SLList<char*>& list,
  182.                     tree_constant& rhs);
  183.  
  184. // Indexed structure assignment.
  185.  
  186.   tree_constant assign_map_element (SLList<char*>& list,
  187.                     tree_constant& rhs,
  188.                     const Octave_object& args);
  189.  
  190. // Type.  It would be nice to eliminate the need for this.
  191.  
  192.   int is_constant (void) const { return 1; }
  193.  
  194. // Size.
  195.  
  196.   int rows (void) const { return rep->rows (); }
  197.   int columns (void) const { return rep->columns (); }
  198.  
  199. // Does this constant have a type?  Both of these are provided since
  200. // it is sometimes more natural to write is_undefined() instead of
  201. // ! is_defined().
  202.  
  203.   int is_defined (void) const { return rep->is_defined (); }
  204.   int is_undefined (void) const { return rep->is_undefined (); }
  205.  
  206. // What type is this constant?
  207.  
  208.   int is_unknown (void) const { return rep->is_unknown (); }
  209.   int is_real_scalar (void) const { return rep->is_real_scalar (); }
  210.   int is_real_matrix (void) const { return rep->is_real_matrix (); }
  211.   int is_complex_scalar (void) const { return rep->is_complex_scalar (); }
  212.   int is_complex_matrix (void) const { return rep->is_complex_matrix (); }
  213.   int is_string (void) const { return rep->is_string (); }
  214.   int is_range (void) const { return rep->is_range (); }
  215.   int is_map (void) const { return rep->is_map (); }
  216.   int is_magic_colon (void) const { return rep->is_magic_colon (); }
  217.   int is_all_va_args (void) const { return rep->is_all_va_args (); }
  218.  
  219. // Are any or all of the elements in this constant nonzero?
  220.  
  221.   tree_constant all (void) const { return rep->all (); }
  222.   tree_constant any (void) const { return rep->any (); }
  223.  
  224.   int is_real_type (void) const { return rep->is_real_type (); }
  225.  
  226.   int is_complex_type (void) const { return rep->is_complex_type (); }
  227.  
  228. // Would be nice to get rid of the next four functions:
  229.  
  230.   int is_scalar_type (void) const { return rep->is_scalar_type (); }
  231.   int is_matrix_type (void) const { return rep->is_matrix_type (); }
  232.  
  233.   int is_numeric_type (void) const
  234.     { return rep->is_numeric_type (); }
  235.  
  236.   int is_numeric_or_range_type (void) const
  237.     { return rep->is_numeric_or_range_type (); }
  238.  
  239. // Is this constant valid as a scalar index?
  240.  
  241.   int valid_as_scalar_index (void) const
  242.     { return rep->valid_as_scalar_index (); }
  243.  
  244. // Is this constant valid as a zero scalar index?
  245.  
  246.   int valid_as_zero_index (void) const
  247.     { return rep->valid_as_zero_index (); }
  248.  
  249. // Does this constant correspond to a truth value?
  250.  
  251.   int is_true (void) const { return rep->is_true (); }
  252.  
  253. // Is at least one of the dimensions of this constant zero?
  254.  
  255.   int is_empty (void) const
  256.     {
  257.       return ((! (is_magic_colon () || is_all_va_args () || is_unknown ()))
  258.           && (rows () == 0 || columns () == 0));
  259.     }
  260.  
  261. // Are the dimensions of this constant zero by zero?
  262.  
  263.   int is_zero_by_zero (void) const
  264.     {
  265.       return ((! (is_magic_colon () || is_all_va_args () || is_unknown ()))
  266.           && rows () == 0 && columns () == 0);
  267.     } 
  268.  
  269. // Values.
  270.  
  271.   double double_value (int force_string_conversion = 0) const
  272.     { return rep->double_value (force_string_conversion); }
  273.  
  274.   Matrix matrix_value (int force_string_conversion = 0) const
  275.     { return rep->matrix_value (force_string_conversion); }
  276.  
  277.   Complex complex_value (int force_string_conversion = 0) const
  278.     { return rep->complex_value (force_string_conversion); }
  279.  
  280.   ComplexMatrix complex_matrix_value (int force_string_conversion = 0) const
  281.     { return rep->complex_matrix_value (force_string_conversion); }
  282.  
  283.   char *string_value (void) const
  284.     { return rep->string_value (); }
  285.  
  286.   Range range_value (void) const
  287.     { return rep->range_value (); }
  288.  
  289.   Octave_map map_value (void) const;
  290.  
  291.   tree_constant lookup_map_element (SLList<char*>& list);
  292.  
  293.   ColumnVector vector_value (int force_string_conversion = 0,
  294.                  int force_vector_conversion = 0) const 
  295.     { return rep->vector_value (); }
  296.  
  297.   ComplexColumnVector complex_vector_value (int force_string_conv = 0,
  298.                         int force_vec_conv = 0) const
  299.     { return rep->complex_vector_value (); }
  300.  
  301. // Binary and unary operations.
  302.  
  303.   friend tree_constant do_binary_op (tree_constant& a, tree_constant& b,
  304.                      tree_expression::type t);
  305.  
  306.   friend tree_constant do_unary_op (tree_constant& a,
  307.                     tree_expression::type t);
  308.  
  309. // Conversions.  These should probably be private.  If a user of this
  310. // class wants a certain kind of constant, he should simply ask for
  311. // it, and we should convert it if possible.
  312.  
  313.   tree_constant convert_to_str (void)
  314.     { return rep->convert_to_str (); }
  315.  
  316.   void convert_to_row_or_column_vector (void)
  317.     { rep->convert_to_row_or_column_vector (); }
  318.  
  319. // Increment or decrement this constant.
  320.  
  321.   void bump_value (tree_expression::type et)
  322.     {
  323.       if (rep->count > 1)
  324.     {
  325.       --rep->count;
  326.       rep = new tree_constant_rep (*rep);
  327.       rep->count = 1;
  328.     }
  329.  
  330.       rep->bump_value (et);
  331.     }
  332.  
  333. // Evaluate this constant, possibly converting complex to real, or
  334. // matrix to scalar, etc.
  335.  
  336.   tree_constant eval (int print)
  337.     {
  338.       if (! is_scalar_type ())
  339.     rep->maybe_mutate ();
  340.  
  341.       if (print)
  342.     rep->print ();
  343.  
  344.       return *this;
  345.     }
  346.  
  347.   Octave_object eval (int print, int nargout, const Octave_object& args)
  348.     {
  349.       Octave_object retval;
  350.  
  351. // XXX FIXME XXX -- make it safe to call do_index() with
  352. // args.length () == 0
  353.  
  354.       if (args.length () > 0)
  355.     retval(0) = rep->do_index (args);
  356.       else
  357.     retval(0) = *this;
  358.  
  359.       if (retval(0).is_defined ())
  360.     retval(0).eval (print);
  361.  
  362.       return retval;
  363.     }
  364.  
  365. // Store the original text corresponding to this constant for later
  366. // pretty printing.
  367.  
  368.   void stash_original_text (char *s)
  369.     { rep->stash_original_text (s); }
  370.  
  371. // Pretty print this constant.
  372.  
  373.   void print_code (ostream& os);
  374.  
  375.   char *type_as_string (void) const
  376.     { return rep->type_as_string (); }
  377.  
  378. // We really do need this, and it should be private:
  379.  
  380. private:
  381.  
  382.   void make_unique (void);
  383.  
  384.   tree_constant_rep *make_unique_map (void);
  385.  
  386. public:
  387.  
  388. // -------------------------------------------------------------------
  389.  
  390. // We want to eliminate this, or at least make it private.
  391.  
  392.   tree_constant_rep::constant_type const_type (void) const
  393.     { return rep->const_type (); }
  394.  
  395. private:
  396.  
  397. // Can we make these go away?
  398.  
  399. // These need better names, since a range really is a numeric type.
  400.  
  401.   void force_numeric (int force_str_conv = 0)
  402.     { rep->force_numeric (force_str_conv); }
  403.  
  404.   tree_constant make_numeric (int force_str_conv = 0) const
  405.     {
  406.       if (is_numeric_type ())
  407.     return *this;
  408.       else
  409.     return rep->make_numeric (force_str_conv);
  410.     }
  411.  
  412. #if 0
  413.   tree_constant make_numeric_or_range (void) const
  414.     {
  415.       if (is_numeric_type () || is_range ())
  416.     return *this;
  417.       else
  418.     return rep->make_numeric ();
  419.     }
  420. #endif
  421.  
  422.   tree_constant make_numeric_or_magic (void) const
  423.     {
  424.       if (is_numeric_type () || is_all_va_args () || is_magic_colon ())
  425.     return *this;
  426.       else
  427.     return rep->make_numeric ();
  428.     }
  429.  
  430.   tree_constant make_numeric_or_range_or_magic (void) const
  431.     {
  432.       if (is_numeric_type () || is_range () || is_all_va_args ()
  433.       || is_magic_colon ())
  434.     return *this;
  435.       else
  436.     return rep->make_numeric ();
  437.     }
  438. };
  439.  
  440. // XXX FIXME XXX -- this is not used very much now.  Perhaps it can be
  441. // eliminated.
  442. extern Octave_object vector_of_empties (int nargout, const char *fcn_name);
  443.  
  444. #endif
  445.  
  446. /*
  447. ;;; Local Variables: ***
  448. ;;; mode: C++ ***
  449. ;;; page-delimiter: "^/\\*" ***
  450. ;;; End: ***
  451. */
  452.