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 / tc-rep-idx.cc < prev    next >
C/C++ Source or Header  |  1995-02-22  |  31KB  |  1,582 lines

  1. // tc-rep-idx.cc                                        -*- 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. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27.  
  28. #include <ctype.h>
  29. #include <string.h>
  30. #include <fstream.h>
  31. #include <iostream.h>
  32. #include <strstream.h>
  33.  
  34. #include "mx-base.h"
  35. #include "Range.h"
  36.  
  37. #include "arith-ops.h"
  38. #include "variables.h"
  39. #include "sysdep.h"
  40. #include "error.h"
  41. #include "gripes.h"
  42. #include "user-prefs.h"
  43. #include "utils.h"
  44. #include "pager.h"
  45. #include "pr-output.h"
  46. #include "tree-const.h"
  47. #include "idx-vector.h"
  48. #include "oct-map.h"
  49.  
  50. #include "tc-inlines.h"
  51.  
  52. // Indexing functions.
  53.  
  54. // This is the top-level indexing function.
  55.  
  56. tree_constant
  57. TC_REP::do_index (const Octave_object& args)
  58. {
  59.   tree_constant retval;
  60.  
  61.   if (error_state)
  62.     return retval;
  63.  
  64.   if (rows () == 0 || columns () == 0)
  65.     {
  66.       switch (args.length ())
  67.     {
  68.     case 2:
  69.       if (! args(1).is_magic_colon ()
  70.           && args(1).rows () != 0 && args(1).columns () != 0)
  71.         goto index_error;
  72.  
  73.     case 1:
  74.       if (! args(0).is_magic_colon ()
  75.           && args(0).rows () != 0 && args(0).columns () != 0)
  76.         goto index_error;
  77.  
  78.       return Matrix ();
  79.  
  80.     default:
  81.     index_error:
  82.       ::error ("attempt to index empty matrix");
  83.       return retval;
  84.     }
  85.     }
  86.  
  87.   switch (type_tag)
  88.     {
  89.     case complex_scalar_constant:
  90.     case scalar_constant:
  91.       retval = do_scalar_index (args);
  92.       break;
  93.  
  94.     case complex_matrix_constant:
  95.     case matrix_constant:
  96.       retval = do_matrix_index (args);
  97.       break;
  98.  
  99.     case string_constant:
  100.       gripe_string_invalid ();
  101. //      retval = do_string_index (args);
  102.       break;
  103.  
  104.     default:
  105.  
  106. // This isn\'t great, but it\'s easier than implementing a lot of
  107. // other special indexing functions.
  108.  
  109.       force_numeric ();
  110.  
  111.       if (! error_state && is_numeric_type ())
  112.     retval = do_index (args);
  113.  
  114.       break;
  115.     }
  116.  
  117.   return retval;
  118. }
  119.  
  120. tree_constant
  121. TC_REP::do_scalar_index (const Octave_object& args) const
  122. {
  123.   tree_constant retval;
  124.  
  125.   if (valid_scalar_indices (args))
  126.     {
  127.       if (type_tag == scalar_constant)
  128.     retval = scalar;
  129.       else if (type_tag == complex_scalar_constant)
  130.     retval = *complex_scalar;
  131.       else
  132.     panic_impossible ();
  133.  
  134.       return retval;
  135.     }
  136.   else
  137.     {
  138.       int rows = -1;
  139.       int cols = -1;
  140.  
  141.       int nargin = args.length ();
  142.  
  143.       switch (nargin)
  144.     {
  145.     case 2:
  146.       {
  147.         tree_constant arg = args(1);
  148.  
  149.         if (arg.is_matrix_type ())
  150.           {
  151.         Matrix mj = arg.matrix_value ();
  152.  
  153.         idx_vector j (mj, user_pref.do_fortran_indexing, "", 1);
  154.         if (! j)
  155.           return retval;
  156.  
  157.         int jmax = j.max ();
  158.         int len = j.length ();
  159.         if (len == j.ones_count ())
  160.           cols = len;
  161.         else if (jmax > 0)
  162.           {
  163.             error ("invalid scalar index = %d", jmax+1);
  164.             return retval;
  165.           }
  166.           }
  167.         else if (arg.const_type () == magic_colon)
  168.           {
  169.         cols = 1;
  170.           }
  171.         else if (arg.is_scalar_type ())
  172.           {
  173.         double dval = arg.double_value ();
  174.         if (! xisnan (dval))
  175.           {
  176.             int ival = NINT (dval);
  177.             if (ival == 1)
  178.               cols = 1;
  179.             else if (ival == 0)
  180.               cols = 0;
  181.             else
  182.               break;;
  183.           }
  184.         else
  185.           break;
  186.           }
  187.         else
  188.           break;
  189.       }
  190.  
  191. // Fall through...
  192.  
  193.     case 1:
  194.       {
  195.         tree_constant arg = args(0);
  196.  
  197.         if (arg.is_matrix_type ())
  198.           {
  199.         Matrix mi = arg.matrix_value ();
  200.  
  201.         idx_vector i (mi, user_pref.do_fortran_indexing, "", 1);
  202.         if (! i)
  203.           return retval;
  204.  
  205.         int imax = i.max ();
  206.         int len = i.length ();
  207.         if (len == i.ones_count ())
  208.           rows = len;
  209.         else if (imax > 0)
  210.           {
  211.             error ("invalid scalar index = %d", imax+1);
  212.             return retval;
  213.           }
  214.           }
  215.         else if (arg.const_type () == magic_colon)
  216.           {
  217.         rows = 1;
  218.           }
  219.         else if (arg.is_scalar_type ())
  220.           {
  221.         double dval = arg.double_value ();
  222.  
  223.         if (! xisnan (dval))
  224.           {
  225.             int ival = NINT (dval);
  226.             if (ival == 1)
  227.               rows = 1;
  228.             else if (ival == 0)
  229.               rows = 0;
  230.             else
  231.               break;
  232.           }
  233.         else
  234.           break;
  235.           }
  236.         else
  237.           break;
  238.  
  239. // If only one index, cols will not be set, so we set it.
  240. // If single index is [], rows will be zero, and we should set cols to
  241. // zero too.
  242.  
  243.         if (cols < 0)
  244.           {
  245.         if (rows == 0)
  246.           cols = 0;
  247.         else
  248.           {
  249.             if (user_pref.prefer_column_vectors)
  250.               cols = 1;
  251.             else
  252.               {
  253.             cols = rows;
  254.             rows = 1;
  255.               }
  256.           }
  257.           }
  258.  
  259.         if (type_tag == scalar_constant)
  260.           {
  261.         return Matrix (rows, cols, scalar);
  262.           }
  263.         else if (type_tag == complex_scalar_constant)
  264.           {
  265.         return ComplexMatrix (rows, cols, *complex_scalar);
  266.           }
  267.         else
  268.           panic_impossible ();
  269.       }
  270.       break;
  271.  
  272.     default:
  273.       ::error ("invalid number of arguments for scalar type");
  274.       return tree_constant ();
  275.       break;
  276.     }
  277.     }
  278.  
  279.   ::error ("index invalid or out of range for scalar type");
  280.   return tree_constant ();
  281. }
  282.  
  283. tree_constant
  284. TC_REP::do_matrix_index (const Octave_object& args) const
  285. {
  286.   tree_constant retval;
  287.  
  288.   int nargin = args.length ();
  289.  
  290.   switch (nargin)
  291.     {
  292.     case 1:
  293.       {
  294.     tree_constant arg = args(0);
  295.  
  296.     if (arg.is_undefined ())
  297.       ::error ("matrix index is a null expression");
  298.     else
  299.       retval = do_matrix_index (arg);
  300.       }
  301.       break;
  302.  
  303.     case 2:
  304.       {
  305.     tree_constant arg_a = args(0);
  306.     tree_constant arg_b = args(1);
  307.  
  308.     if (arg_a.is_undefined ())
  309.     ::error ("first matrix index is a null expression");
  310.     else if (arg_b.is_undefined ())
  311.       ::error ("second matrix index is a null expression");
  312.     else
  313.       retval = do_matrix_index (arg_a, arg_b);
  314.       }
  315.       break;
  316.  
  317.     default:
  318.       if (nargin == 0)
  319.     ::error ("matrix indices expected, but none provided");
  320.       else
  321.     ::error ("too many indices for matrix expression");
  322.       break;
  323.     }
  324.  
  325.   return  retval;
  326. }
  327.  
  328. tree_constant
  329. TC_REP::do_matrix_index (const tree_constant& i_arg) const
  330. {
  331.   tree_constant retval;
  332.  
  333.   int nr = rows ();
  334.   int nc = columns ();
  335.  
  336.   if (user_pref.do_fortran_indexing)
  337.     retval = fortran_style_matrix_index (i_arg);
  338.   else if (nr <= 1 || nc <= 1)
  339.     retval = do_vector_index (i_arg);
  340.   else
  341.     ::error ("single index only valid for row or column vector");
  342.  
  343.   return retval;
  344. }
  345.  
  346. tree_constant
  347. TC_REP::do_matrix_index (const tree_constant& i_arg,
  348.              const tree_constant& j_arg) const
  349. {
  350.   tree_constant retval;
  351.  
  352.   tree_constant tmp_i = i_arg.make_numeric_or_range_or_magic ();
  353.  
  354.   if (error_state)
  355.     return retval;
  356.  
  357.   TC_REP::constant_type itype = tmp_i.const_type ();
  358.  
  359.   switch (itype)
  360.     {
  361.     case complex_scalar_constant:
  362.     case scalar_constant:
  363.       {
  364.         int i = tree_to_mat_idx (tmp_i.double_value ());
  365.     retval = do_matrix_index (i, j_arg);
  366.       }
  367.       break;
  368.  
  369.     case complex_matrix_constant:
  370.     case matrix_constant:
  371.       {
  372.     Matrix mi = tmp_i.matrix_value ();
  373.     idx_vector iv (mi, user_pref.do_fortran_indexing, "row", rows ());
  374.     if (! iv)
  375.       return tree_constant ();
  376.  
  377.     if (iv.length () == 0)
  378.       {
  379.         Matrix mtmp;
  380.         retval = tree_constant (mtmp);
  381.       }
  382.     else
  383.       retval = do_matrix_index (iv, j_arg);
  384.       }
  385.       break;
  386.  
  387.     case string_constant:
  388.       gripe_string_invalid ();
  389.       break;
  390.  
  391.     case range_constant:
  392.       {
  393.     Range ri = tmp_i.range_value ();
  394.     int nr = rows ();
  395.     if (nr == 2 && is_zero_one (ri))
  396.       {
  397.         retval = do_matrix_index (1, j_arg);
  398.       }
  399.     else if (nr == 2 && is_one_zero (ri))
  400.       {
  401.         retval = do_matrix_index (0, j_arg);
  402.       }
  403.     else
  404.       {
  405.         if (index_check (ri, "row") < 0)
  406.           return tree_constant ();
  407.         retval = do_matrix_index (ri, j_arg);
  408.       }
  409.       }
  410.       break;
  411.  
  412.     case magic_colon:
  413.       retval = do_matrix_index (magic_colon, j_arg);
  414.       break;
  415.  
  416.     default:
  417.       panic_impossible ();
  418.       break;
  419.     }
  420.  
  421.   return retval;
  422. }
  423.  
  424. tree_constant
  425. TC_REP::do_matrix_index (TC_REP::constant_type mci) const
  426. {
  427.   assert (mci == magic_colon);
  428.  
  429.   tree_constant retval;
  430.   int nr =  rows ();
  431.   int nc =  columns ();
  432.   int size = nr * nc;
  433.   if (size > 0)
  434.     {
  435.       CRMATRIX (m, cm, size, 1);
  436.       int idx = 0;
  437.       for (int j = 0; j < nc; j++)
  438.     for (int i = 0; i < nr; i++)
  439.       {
  440.         CRMATRIX_ASSIGN_REP_ELEM (m, cm, idx, 0, i, j);
  441.         idx++;
  442.       }
  443.       ASSIGN_CRMATRIX_TO (retval, m, cm);
  444.     }
  445.   return retval;
  446. }
  447.  
  448. tree_constant
  449. TC_REP::fortran_style_matrix_index (const tree_constant& i_arg) const
  450. {
  451.   tree_constant retval;
  452.  
  453.   tree_constant tmp_i = i_arg.make_numeric_or_magic ();
  454.  
  455.   if (error_state)
  456.     return retval;
  457.  
  458.   TC_REP::constant_type itype = tmp_i.const_type ();
  459.  
  460.   int nr = rows ();
  461.   int nc = columns ();
  462.  
  463.   switch (itype)
  464.     {
  465.     case complex_scalar_constant:
  466.     case scalar_constant:
  467.       {
  468.     double dval = tmp_i.double_value ();
  469.  
  470.     if (xisnan (dval))
  471.       {
  472.         ::error ("NaN is invalid as a matrix index");
  473.         return tree_constant ();
  474.       }
  475.     else
  476.       {
  477.         int i = NINT (dval);
  478.         int ii = fortran_row (i, nr) - 1;
  479.         int jj = fortran_column (i, nr) - 1;
  480.         if (index_check (i-1, "") < 0)
  481.           return tree_constant ();
  482.         if (range_max_check (i-1, nr * nc) < 0)
  483.           return tree_constant ();
  484.         retval = do_matrix_index (ii, jj);
  485.       }
  486.       }
  487.       break;
  488.  
  489.     case complex_matrix_constant:
  490.     case matrix_constant:
  491.       {
  492.     Matrix mi = tmp_i.matrix_value ();
  493.     if (mi.rows () == 0 || mi.columns () == 0)
  494.       {
  495.         Matrix mtmp;
  496.         retval = tree_constant (mtmp);
  497.       }
  498.     else
  499.       {
  500. // Yes, we really do want to call this with mi.
  501.         retval = fortran_style_matrix_index (mi);
  502.       }
  503.       }
  504.       break;
  505.  
  506.     case string_constant:
  507.       gripe_string_invalid ();
  508.       break;
  509.  
  510.     case range_constant:
  511.       gripe_range_invalid ();
  512.       break;
  513.  
  514.     case magic_colon:
  515.       retval = do_matrix_index (magic_colon);
  516.       break;
  517.  
  518.     default:
  519.       panic_impossible ();
  520.       break;
  521.     }
  522.  
  523.   return retval;
  524. }
  525.  
  526. tree_constant
  527. TC_REP::fortran_style_matrix_index (const Matrix& mi) const
  528. {
  529.   assert (is_matrix_type ());
  530.  
  531.   tree_constant retval;
  532.  
  533.   int nr = rows ();
  534.   int nc = columns ();
  535.  
  536.   int len = nr * nc;
  537.  
  538.   int index_nr = mi.rows ();
  539.   int index_nc = mi.columns ();
  540.  
  541.   if (index_nr >= 1 && index_nc >= 1)
  542.     {
  543.       const double *cop_out = 0;
  544.       const Complex *c_cop_out = 0;
  545.       int real_type = type_tag == matrix_constant;
  546.       if (real_type)
  547.     cop_out = matrix->data ();
  548.       else
  549.     c_cop_out = complex_matrix->data ();
  550.  
  551.       const double *cop_out_index = mi.data ();
  552.  
  553.       idx_vector iv (mi, 1, "", len);
  554.       if (! iv || range_max_check (iv.max (), len) < 0)
  555.     return retval;
  556.  
  557.       int result_size = iv.length ();
  558.  
  559. // XXX FIXME XXX -- there is way too much duplicate code here...
  560.  
  561.       if (iv.one_zero_only ())
  562.     {
  563.       if (iv.ones_count () == 0)
  564.         {
  565.           retval = Matrix ();
  566.         }
  567.       else
  568.         {
  569.           if (nr == 1)
  570.         {
  571.           CRMATRIX (m, cm, 1, result_size);
  572.  
  573.           for (int i = 0; i < result_size; i++)
  574.             {
  575.               int idx = iv.elem (i);
  576.               CRMATRIX_ASSIGN_ELEM (m, cm, 0, i, cop_out [idx],
  577.                         c_cop_out [idx], real_type);
  578.             }
  579.  
  580.           ASSIGN_CRMATRIX_TO (retval, m, cm);
  581.         }
  582.           else
  583.         {
  584.           CRMATRIX (m, cm, result_size, 1);
  585.  
  586.           for (int i = 0; i < result_size; i++)
  587.             {
  588.               int idx = iv.elem (i);
  589.               CRMATRIX_ASSIGN_ELEM (m, cm, i, 0, cop_out [idx],
  590.                         c_cop_out [idx], real_type);
  591.             }
  592.  
  593.           ASSIGN_CRMATRIX_TO (retval, m, cm);
  594.         }
  595.         }
  596.     }
  597.       else if (nc == 1)
  598.     {
  599.       CRMATRIX (m, cm, result_size, 1);
  600.  
  601.       for (int i = 0; i < result_size; i++)
  602.         {
  603.           int idx = iv.elem (i);
  604.           CRMATRIX_ASSIGN_ELEM (m, cm, i, 0, cop_out [idx],
  605.                     c_cop_out [idx], real_type);
  606.         }
  607.  
  608.       ASSIGN_CRMATRIX_TO (retval, m, cm);
  609.     }
  610.       else if (nr == 1)
  611.     {
  612.       CRMATRIX (m, cm, 1, result_size);
  613.  
  614.       for (int i = 0; i < result_size; i++)
  615.         {
  616.           int idx = iv.elem (i);
  617.           CRMATRIX_ASSIGN_ELEM (m, cm, 0, i, cop_out [idx],
  618.                     c_cop_out [idx], real_type);
  619.         }
  620.  
  621.       ASSIGN_CRMATRIX_TO (retval, m, cm);
  622.     }
  623.       else
  624.     {
  625.       CRMATRIX (m, cm, index_nr, index_nc);
  626.  
  627.       for (int j = 0; j < index_nc; j++)
  628.         for (int i = 0; i < index_nr; i++)
  629.           {
  630.         double tmp = *cop_out_index++;
  631.         int idx = tree_to_mat_idx (tmp);
  632.         CRMATRIX_ASSIGN_ELEM (m, cm, i, j, cop_out [idx],
  633.                       c_cop_out [idx], real_type);
  634.           }
  635.  
  636.       ASSIGN_CRMATRIX_TO (retval, m, cm);
  637.     }
  638.     }
  639.   else
  640.     {
  641.       if (index_nr == 0 || index_nc == 0)
  642.     ::error ("empty matrix invalid as index");
  643.       else
  644.     ::error ("invalid matrix index");
  645.       return tree_constant ();
  646.     }
  647.  
  648.   return retval;
  649. }
  650.  
  651. tree_constant
  652. TC_REP::do_vector_index (const tree_constant& i_arg) const
  653. {
  654.   tree_constant retval;
  655.  
  656.   tree_constant tmp_i = i_arg.make_numeric_or_range_or_magic ();
  657.  
  658.   if (error_state)
  659.     return retval;
  660.  
  661.   TC_REP::constant_type itype = tmp_i.const_type ();
  662.  
  663.   int nr = rows ();
  664.   int nc = columns ();
  665.  
  666.   int len = MAX (nr, nc);
  667.  
  668.   assert ((nr == 1 || nc == 1) && ! user_pref.do_fortran_indexing);
  669.  
  670.   int swap_indices = (nr == 1);
  671.  
  672.   switch (itype)
  673.     {
  674.     case complex_scalar_constant:
  675.     case scalar_constant:
  676.       {
  677.         int i = tree_to_mat_idx (tmp_i.double_value ());
  678.         if (index_check (i, "") < 0)
  679.       return tree_constant ();
  680.         if (swap_indices)
  681.           {
  682.         if (range_max_check (i, nc) < 0)
  683.           return tree_constant ();
  684.         retval = do_matrix_index (0, i);
  685.           }
  686.         else
  687.           {
  688.         if (range_max_check (i, nr) < 0)
  689.           return tree_constant ();
  690.         retval = do_matrix_index (i, 0);
  691.           }
  692.       }
  693.       break;
  694.  
  695.     case complex_matrix_constant:
  696.     case matrix_constant:
  697.       {
  698.         Matrix mi = tmp_i.matrix_value ();
  699.     if (mi.rows () == 0 || mi.columns () == 0)
  700.       {
  701.         Matrix mtmp;
  702.         retval = tree_constant (mtmp);
  703.       }
  704.     else
  705.       {
  706.         idx_vector iv (mi, user_pref.do_fortran_indexing, "", len);
  707.         if (! iv)
  708.           return tree_constant ();
  709.  
  710.         if (swap_indices)
  711.           {
  712.         if (range_max_check (iv.max (), nc) < 0)
  713.           return tree_constant ();
  714.         retval = do_matrix_index (0, iv);
  715.           }
  716.         else
  717.           {
  718.         if (range_max_check (iv.max (), nr) < 0)
  719.           return tree_constant ();
  720.         retval = do_matrix_index (iv, 0);
  721.           }
  722.       }
  723.       }
  724.       break;
  725.  
  726.     case string_constant:
  727.       gripe_string_invalid ();
  728.       break;
  729.  
  730.     case range_constant:
  731.       {
  732.         Range ri = tmp_i.range_value ();
  733.     if (len == 2 && is_zero_one (ri))
  734.       {
  735.         if (swap_indices)
  736.           retval = do_matrix_index (0, 1);
  737.         else
  738.           retval = do_matrix_index (1, 0);
  739.       }
  740.     else if (len == 2 && is_one_zero (ri))
  741.       {
  742.         retval = do_matrix_index (0, 0);
  743.       }
  744.     else
  745.       {
  746.         if (index_check (ri, "") < 0)
  747.           return tree_constant ();
  748.         if (swap_indices)
  749.           {
  750.         if (range_max_check (tree_to_mat_idx (ri.max ()), nc) < 0)
  751.           return tree_constant ();
  752.         retval = do_matrix_index (0, ri);
  753.           }
  754.         else
  755.           {
  756.         if (range_max_check (tree_to_mat_idx (ri.max ()), nr) < 0)
  757.           return tree_constant ();
  758.         retval = do_matrix_index (ri, 0);
  759.           }
  760.       }
  761.       }
  762.       break;
  763.  
  764.     case magic_colon:
  765.       if (swap_indices)
  766.         retval = do_matrix_index (0, magic_colon);
  767.       else
  768.         retval = do_matrix_index (magic_colon, 0);
  769.       break;
  770.  
  771.     default:
  772.       panic_impossible ();
  773.       break;
  774.     }
  775.  
  776.   return retval;
  777. }
  778.  
  779. tree_constant
  780. TC_REP::do_matrix_index (int i, const tree_constant& j_arg) const
  781. {
  782.   tree_constant retval;
  783.  
  784.   tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
  785.  
  786.   if (error_state)
  787.     return retval;
  788.  
  789.   TC_REP::constant_type jtype = tmp_j.const_type ();
  790.  
  791.   int nr = rows ();
  792.   int nc = columns ();
  793.  
  794.   switch (jtype)
  795.     {
  796.     case complex_scalar_constant:
  797.     case scalar_constant:
  798.       {
  799.     if (index_check (i, "row") < 0)
  800.       return tree_constant ();
  801.     int j = tree_to_mat_idx (tmp_j.double_value ());
  802.     if (index_check (j, "column") < 0)
  803.       return tree_constant ();
  804.     if (range_max_check (i, j, nr, nc) < 0)
  805.       return tree_constant ();
  806.     retval = do_matrix_index (i, j);
  807.       }
  808.       break;
  809.  
  810.     case complex_matrix_constant:
  811.     case matrix_constant:
  812.       {
  813.     if (index_check (i, "row") < 0)
  814.       return tree_constant ();
  815.     Matrix mj = tmp_j.matrix_value ();
  816.     idx_vector jv (mj, user_pref.do_fortran_indexing, "column", nc);
  817.     if (! jv)
  818.       return tree_constant ();
  819.  
  820.     if (jv.length () == 0)
  821.       {
  822.         Matrix mtmp;
  823.         retval = tree_constant (mtmp);
  824.       }
  825.     else
  826.       {
  827.         if (range_max_check (i, jv.max (), nr, nc) < 0)
  828.           return tree_constant ();
  829.         retval = do_matrix_index (i, jv);
  830.       }
  831.       }
  832.       break;
  833.  
  834.     case string_constant:
  835.       gripe_string_invalid ();
  836.       break;
  837.  
  838.     case range_constant:
  839.       {
  840.     if (index_check (i, "row") < 0)
  841.       return tree_constant ();
  842.     Range rj = tmp_j.range_value ();
  843.     if (nc == 2 && is_zero_one (rj))
  844.       {
  845.         retval = do_matrix_index (i, 1);
  846.       }
  847.     else if (nc == 2 && is_one_zero (rj))
  848.       {
  849.         retval = do_matrix_index (i, 0);
  850.       }
  851.     else
  852.       {
  853.         if (index_check (rj, "column") < 0)
  854.           return tree_constant ();
  855.         if (range_max_check (i, tree_to_mat_idx (rj.max ()), nr, nc) < 0)
  856.           return tree_constant ();
  857.         retval = do_matrix_index (i, rj);
  858.       }
  859.       }
  860.       break;
  861.  
  862.     case magic_colon:
  863.       if (i == -1 && nr == 1)
  864.     return Matrix ();
  865.       if (index_check (i, "row") < 0
  866.       || range_max_check (i, 0, nr, nc) < 0)
  867.     return tree_constant ();
  868.       retval = do_matrix_index (i, magic_colon);
  869.       break;
  870.  
  871.     default:
  872.       panic_impossible ();
  873.       break;
  874.     }
  875.  
  876.   return retval;
  877. }
  878.  
  879. tree_constant
  880. TC_REP::do_matrix_index (const idx_vector& iv,
  881.              const tree_constant& j_arg) const
  882. {
  883.   tree_constant retval;
  884.  
  885.   tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
  886.  
  887.   if (error_state)
  888.     return retval;
  889.  
  890.   TC_REP::constant_type jtype = tmp_j.const_type ();
  891.  
  892.   int nr = rows ();
  893.   int nc = columns ();
  894.  
  895.   switch (jtype)
  896.     {
  897.     case complex_scalar_constant:
  898.     case scalar_constant:
  899.       {
  900.     int j = tree_to_mat_idx (tmp_j.double_value ());
  901.     if (index_check (j, "column") < 0)
  902.       return tree_constant ();
  903.     if (range_max_check (iv.max (), j, nr, nc) < 0)
  904.       return tree_constant ();
  905.     retval = do_matrix_index (iv, j);
  906.       }
  907.       break;
  908.  
  909.     case complex_matrix_constant:
  910.     case matrix_constant:
  911.       {
  912.     Matrix mj = tmp_j.matrix_value ();
  913.     idx_vector jv (mj, user_pref.do_fortran_indexing, "column", nc);
  914.     if (! jv)
  915.       return tree_constant ();
  916.  
  917.     if (jv.length () == 0)
  918.       {
  919.         Matrix mtmp;
  920.         retval = tree_constant (mtmp);
  921.       }
  922.     else
  923.       {
  924.         if (range_max_check (iv.max (), jv.max (), nr, nc) < 0)
  925.           return tree_constant ();
  926.         retval = do_matrix_index (iv, jv);
  927.       }
  928.       }
  929.       break;
  930.  
  931.     case string_constant:
  932.       gripe_string_invalid ();
  933.       break;
  934.  
  935.     case range_constant:
  936.       {
  937.     Range rj = tmp_j.range_value ();
  938.     if (nc == 2 && is_zero_one (rj))
  939.       {
  940.         retval = do_matrix_index (iv, 1);
  941.       }
  942.     else if (nc == 2 && is_one_zero (rj))
  943.       {
  944.         retval = do_matrix_index (iv, 0);
  945.       }
  946.     else
  947.       {
  948.         if (index_check (rj, "column") < 0)
  949.           return tree_constant ();
  950.         if (range_max_check (iv.max (), tree_to_mat_idx (rj.max ()),
  951.                  nr, nc) < 0)
  952.           return tree_constant ();
  953.         retval = do_matrix_index (iv, rj);
  954.       }
  955.       }
  956.       break;
  957.  
  958.     case magic_colon:
  959.       if (range_max_check (iv.max (), 0, nr, nc) < 0)
  960.     return tree_constant ();
  961.       retval = do_matrix_index (iv, magic_colon);
  962.       break;
  963.  
  964.     default:
  965.       panic_impossible ();
  966.       break;
  967.     }
  968.  
  969.   return retval;
  970. }
  971.  
  972. tree_constant
  973. TC_REP::do_matrix_index (const Range& ri,
  974.              const tree_constant& j_arg) const
  975. {
  976.   tree_constant retval;
  977.  
  978.   tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
  979.  
  980.   if (error_state)
  981.     return retval;
  982.  
  983.   TC_REP::constant_type jtype = tmp_j.const_type ();
  984.  
  985.   int nr = rows ();
  986.   int nc = columns ();
  987.  
  988.   switch (jtype)
  989.     {
  990.     case complex_scalar_constant:
  991.     case scalar_constant:
  992.       {
  993.     int j = tree_to_mat_idx (tmp_j.double_value ());
  994.     if (index_check (j, "column") < 0)
  995.       return tree_constant ();
  996.     if (range_max_check (tree_to_mat_idx (ri.max ()), j, nr, nc) < 0)
  997.       return tree_constant ();
  998.     retval = do_matrix_index (ri, j);
  999.       }
  1000.       break;
  1001.  
  1002.     case complex_matrix_constant:
  1003.     case matrix_constant:
  1004.       {
  1005.     Matrix mj = tmp_j.matrix_value ();
  1006.     idx_vector jv (mj, user_pref.do_fortran_indexing, "column", nc);
  1007.     if (! jv)
  1008.       return tree_constant ();
  1009.  
  1010.     if (jv.length () == 0)
  1011.       {
  1012.         Matrix mtmp;
  1013.         retval = tree_constant (mtmp);
  1014.       }
  1015.     else
  1016.       {
  1017.         if (range_max_check (tree_to_mat_idx (ri.max ()),
  1018.                  jv.max (), nr, nc) < 0)
  1019.           return tree_constant ();
  1020.         retval = do_matrix_index (ri, jv);
  1021.       }
  1022.       }
  1023.       break;
  1024.  
  1025.     case string_constant:
  1026.       gripe_string_invalid ();
  1027.       break;
  1028.  
  1029.     case range_constant:
  1030.       {
  1031.     Range rj = tmp_j.range_value ();
  1032.     if (nc == 2 && is_zero_one (rj))
  1033.       {
  1034.         retval = do_matrix_index (ri, 1);
  1035.       }
  1036.     else if (nc == 2 && is_one_zero (rj))
  1037.       {
  1038.         retval = do_matrix_index (ri, 0);
  1039.       }
  1040.     else
  1041.       {
  1042.         if (index_check (rj, "column") < 0)
  1043.           return tree_constant ();
  1044.         if (range_max_check (tree_to_mat_idx (ri.max ()),
  1045.                  tree_to_mat_idx (rj.max ()), nr, nc) < 0)
  1046.           return tree_constant ();
  1047.         retval = do_matrix_index (ri, rj);
  1048.       }
  1049.       }
  1050.       break;
  1051.  
  1052.     case magic_colon:
  1053.       {
  1054.     if (index_check (ri, "row") < 0)
  1055.       return tree_constant ();
  1056.     if (range_max_check (tree_to_mat_idx (ri.max ()), 0, nr, nc) < 0)
  1057.       return tree_constant ();
  1058.     retval = do_matrix_index (ri, magic_colon);
  1059.       }
  1060.       break;
  1061.  
  1062.     default:
  1063.       panic_impossible ();
  1064.       break;
  1065.     }
  1066.  
  1067.   return retval;
  1068. }
  1069.  
  1070. tree_constant
  1071. TC_REP::do_matrix_index (TC_REP::constant_type mci,
  1072.              const tree_constant& j_arg) const
  1073. {
  1074.   tree_constant retval;
  1075.  
  1076.   tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
  1077.  
  1078.   if (error_state)
  1079.     return retval;
  1080.  
  1081.   TC_REP::constant_type jtype = tmp_j.const_type ();
  1082.  
  1083.   int nr = rows ();
  1084.   int nc = columns ();
  1085.  
  1086.   switch (jtype)
  1087.     {
  1088.     case complex_scalar_constant:
  1089.     case scalar_constant:
  1090.       {
  1091.     int j = tree_to_mat_idx (tmp_j.double_value ());
  1092.     if (j == -1 && nc == 1)
  1093.       return Matrix ();
  1094.     if (index_check (j, "column") < 0)
  1095.       return tree_constant ();
  1096.     if (range_max_check (0, j, nr, nc) < 0)
  1097.       return tree_constant ();
  1098.     retval = do_matrix_index (magic_colon, j);
  1099.       }
  1100.       break;
  1101.  
  1102.     case complex_matrix_constant:
  1103.     case matrix_constant:
  1104.       {
  1105.     Matrix mj = tmp_j.matrix_value ();
  1106.     idx_vector jv (mj, user_pref.do_fortran_indexing, "column", nc);
  1107.     if (! jv)
  1108.       return tree_constant ();
  1109.  
  1110.     if (jv.length () == 0)
  1111.       {
  1112.         Matrix mtmp;
  1113.         retval = tree_constant (mtmp);
  1114.       }
  1115.     else
  1116.       {
  1117.         if (range_max_check (0, jv.max (), nr, nc) < 0)
  1118.           return tree_constant ();
  1119.         retval = do_matrix_index (magic_colon, jv);
  1120.       }
  1121.       }
  1122.       break;
  1123.  
  1124.     case string_constant:
  1125.       gripe_string_invalid ();
  1126.       break;
  1127.  
  1128.     case range_constant:
  1129.       {
  1130.     Range rj = tmp_j.range_value ();
  1131.     if (nc == 2 && is_zero_one (rj))
  1132.       {
  1133.         retval = do_matrix_index (magic_colon, 1);
  1134.       }
  1135.     else if (nc == 2 && is_one_zero (rj))
  1136.       {
  1137.         retval = do_matrix_index (magic_colon, 0);
  1138.       }
  1139.     else
  1140.       {
  1141.         if (index_check (rj, "column") < 0)
  1142.           return tree_constant ();
  1143.         if (range_max_check (0, tree_to_mat_idx (rj.max ()), nr, nc) < 0)
  1144.           return tree_constant ();
  1145.         retval = do_matrix_index (magic_colon, rj);
  1146.       }
  1147.       }
  1148.       break;
  1149.  
  1150.     case magic_colon:
  1151.       retval = do_matrix_index (magic_colon, magic_colon);
  1152.       break;
  1153.  
  1154.     default:
  1155.       panic_impossible ();
  1156.       break;
  1157.     }
  1158.  
  1159.   return retval;
  1160. }
  1161.  
  1162. tree_constant
  1163. TC_REP::do_matrix_index (int i, int j) const
  1164. {
  1165.   tree_constant retval;
  1166.  
  1167.   if (type_tag == matrix_constant)
  1168.     retval = tree_constant (matrix->elem (i, j));
  1169.   else
  1170.     retval = tree_constant (complex_matrix->elem (i, j));
  1171.  
  1172.   return retval;
  1173. }
  1174.  
  1175. tree_constant
  1176. TC_REP::do_matrix_index (int i, const idx_vector& jv) const
  1177. {
  1178.   tree_constant retval;
  1179.  
  1180.   int jlen = jv.capacity ();
  1181.  
  1182.   CRMATRIX (m, cm, 1, jlen);
  1183.  
  1184.   for (int j = 0; j < jlen; j++)
  1185.     {
  1186.       int col = jv.elem (j);
  1187.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, 0, j, i, col);
  1188.     }
  1189.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1190.  
  1191.   return retval;
  1192. }
  1193.  
  1194. tree_constant
  1195. TC_REP::do_matrix_index (int i, const Range& rj) const
  1196. {
  1197.   tree_constant retval;
  1198.  
  1199.   int jlen = rj.nelem ();
  1200.  
  1201.   CRMATRIX (m, cm, 1, jlen);
  1202.  
  1203.   double b = rj.base ();
  1204.   double increment = rj.inc ();
  1205.   for (int j = 0; j < jlen; j++)
  1206.     {
  1207.       double tmp = b + j * increment;
  1208.       int col = tree_to_mat_idx (tmp);
  1209.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, 0, j, i, col);
  1210.     }
  1211.  
  1212.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1213.  
  1214.   return retval;
  1215. }
  1216.  
  1217. tree_constant
  1218. TC_REP::do_matrix_index (int i, TC_REP::constant_type mcj) const
  1219. {
  1220.   assert (mcj == magic_colon);
  1221.  
  1222.   tree_constant retval;
  1223.  
  1224.   int nc = columns ();
  1225.  
  1226.   CRMATRIX (m, cm, 1, nc);
  1227.  
  1228.   for (int j = 0; j < nc; j++)
  1229.     {
  1230.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, 0, j, i, j);
  1231.     }
  1232.  
  1233.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1234.  
  1235.   return retval;
  1236. }
  1237.  
  1238. tree_constant
  1239. TC_REP::do_matrix_index (const idx_vector& iv, int j) const
  1240. {
  1241.   tree_constant retval;
  1242.  
  1243.   int ilen = iv.capacity ();
  1244.  
  1245.   CRMATRIX (m, cm, ilen, 1);
  1246.  
  1247.   for (int i = 0; i < ilen; i++)
  1248.     {
  1249.       int row = iv.elem (i);
  1250.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, 0, row, j);
  1251.     }
  1252.  
  1253.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1254.  
  1255.   return retval;
  1256. }
  1257.  
  1258. tree_constant
  1259. TC_REP::do_matrix_index (const idx_vector& iv, const idx_vector& jv) const
  1260. {
  1261.   tree_constant retval;
  1262.  
  1263.   int ilen = iv.capacity ();
  1264.   int jlen = jv.capacity ();
  1265.  
  1266.   CRMATRIX (m, cm, ilen, jlen);
  1267.  
  1268.   for (int i = 0; i < ilen; i++)
  1269.     {
  1270.       int row = iv.elem (i);
  1271.       for (int j = 0; j < jlen; j++)
  1272.     {
  1273.       int col = jv.elem (j);
  1274.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, col);
  1275.     }
  1276.     }
  1277.  
  1278.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1279.  
  1280.   return retval;
  1281. }
  1282.  
  1283. tree_constant
  1284. TC_REP::do_matrix_index (const idx_vector& iv, const Range& rj) const
  1285. {
  1286.   tree_constant retval;
  1287.  
  1288.   int ilen = iv.capacity ();
  1289.   int jlen = rj.nelem ();
  1290.  
  1291.   CRMATRIX (m, cm, ilen, jlen);
  1292.  
  1293.   double b = rj.base ();
  1294.   double increment = rj.inc ();
  1295.  
  1296.   for (int i = 0; i < ilen; i++)
  1297.     {
  1298.       int row = iv.elem (i);
  1299.       for (int j = 0; j < jlen; j++)
  1300.     {
  1301.       double tmp = b + j * increment;
  1302.       int col = tree_to_mat_idx (tmp);
  1303.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, col);
  1304.     }
  1305.     }
  1306.  
  1307.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1308.  
  1309.   return retval;
  1310. }
  1311.  
  1312. tree_constant
  1313. TC_REP::do_matrix_index (const idx_vector& iv,
  1314.              TC_REP::constant_type mcj) const
  1315. {
  1316.   assert (mcj == magic_colon);
  1317.  
  1318.   tree_constant retval;
  1319.  
  1320.   int nc = columns ();
  1321.   int ilen = iv.capacity ();
  1322.  
  1323.   CRMATRIX (m, cm, ilen, nc);
  1324.  
  1325.   for (int j = 0; j < nc; j++)
  1326.     {
  1327.       for (int i = 0; i < ilen; i++)
  1328.     {
  1329.       int row = iv.elem (i);
  1330.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, j);
  1331.     }
  1332.     }
  1333.  
  1334.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1335.  
  1336.   return retval;
  1337. }
  1338.  
  1339. tree_constant
  1340. TC_REP::do_matrix_index (const Range& ri, int j) const
  1341. {
  1342.   tree_constant retval;
  1343.  
  1344.   int ilen = ri.nelem ();
  1345.  
  1346.   CRMATRIX (m, cm, ilen, 1);
  1347.  
  1348.   double b = ri.base ();
  1349.   double increment = ri.inc ();
  1350.   for (int i = 0; i < ilen; i++)
  1351.     {
  1352.       double tmp = b + i * increment;
  1353.       int row = tree_to_mat_idx (tmp);
  1354.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, 0, row, j);
  1355.     }
  1356.  
  1357.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1358.  
  1359.   return retval;
  1360. }
  1361.  
  1362. tree_constant
  1363. TC_REP::do_matrix_index (const Range& ri,
  1364.              const idx_vector& jv) const
  1365. {
  1366.   tree_constant retval;
  1367.  
  1368.   int ilen = ri.nelem ();
  1369.   int jlen = jv.capacity ();
  1370.  
  1371.   CRMATRIX (m, cm, ilen, jlen);
  1372.  
  1373.   double b = ri.base ();
  1374.   double increment = ri.inc ();
  1375.   for (int i = 0; i < ilen; i++)
  1376.     {
  1377.       double tmp = b + i * increment;
  1378.       int row = tree_to_mat_idx (tmp);
  1379.       for (int j = 0; j < jlen; j++)
  1380.     {
  1381.       int col = jv.elem (j);
  1382.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, col);
  1383.     }
  1384.     }
  1385.  
  1386.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1387.  
  1388.   return retval;
  1389. }
  1390.  
  1391. tree_constant
  1392. TC_REP::do_matrix_index (const Range& ri, const Range& rj) const
  1393. {
  1394.   tree_constant retval;
  1395.  
  1396.   int ilen = ri.nelem ();
  1397.   int jlen = rj.nelem ();
  1398.  
  1399.   CRMATRIX (m, cm, ilen, jlen);
  1400.  
  1401.   double ib = ri.base ();
  1402.   double iinc = ri.inc ();
  1403.   double jb = rj.base ();
  1404.   double jinc = rj.inc ();
  1405.  
  1406.   for (int i = 0; i < ilen; i++)
  1407.     {
  1408.       double itmp = ib + i * iinc;
  1409.       int row = tree_to_mat_idx (itmp);
  1410.       for (int j = 0; j < jlen; j++)
  1411.     {
  1412.       double jtmp = jb + j * jinc;
  1413.       int col = tree_to_mat_idx (jtmp);
  1414.  
  1415.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, col);
  1416.     }
  1417.     }
  1418.  
  1419.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1420.  
  1421.   return retval;
  1422. }
  1423.  
  1424. tree_constant
  1425. TC_REP::do_matrix_index (const Range& ri, TC_REP::constant_type mcj) const
  1426. {
  1427.   assert (mcj == magic_colon);
  1428.  
  1429.   tree_constant retval;
  1430.  
  1431.   int nc = columns ();
  1432.  
  1433.   int ilen = ri.nelem ();
  1434.  
  1435.   CRMATRIX (m, cm, ilen, nc);
  1436.  
  1437.   double ib = ri.base ();
  1438.   double iinc = ri.inc ();
  1439.  
  1440.   for (int i = 0; i < ilen; i++)
  1441.     {
  1442.       double itmp = ib + i * iinc;
  1443.       int row = tree_to_mat_idx (itmp);
  1444.       for (int j = 0; j < nc; j++)
  1445.     {
  1446.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, j);
  1447.     }
  1448.     }
  1449.  
  1450.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1451.  
  1452.   return retval;
  1453. }
  1454.  
  1455. tree_constant
  1456. TC_REP::do_matrix_index (TC_REP::constant_type mci, int j) const
  1457. {
  1458.   assert (mci == magic_colon);
  1459.  
  1460.   tree_constant retval;
  1461.  
  1462.   int nr = rows ();
  1463.  
  1464.   CRMATRIX (m, cm, nr, 1);
  1465.  
  1466.   for (int i = 0; i < nr; i++)
  1467.     {
  1468.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, 0, i, j);
  1469.     }
  1470.  
  1471.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1472.  
  1473.   return retval;
  1474. }
  1475.  
  1476. tree_constant
  1477. TC_REP::do_matrix_index (TC_REP::constant_type mci,
  1478.              const idx_vector& jv) const
  1479. {
  1480.   assert (mci == magic_colon);
  1481.  
  1482.   tree_constant retval;
  1483.  
  1484.   int nr = rows ();
  1485.   int jlen = jv.capacity ();
  1486.  
  1487.   CRMATRIX (m, cm, nr, jlen);
  1488.  
  1489.   for (int i = 0; i < nr; i++)
  1490.     {
  1491.       for (int j = 0; j < jlen; j++)
  1492.     {
  1493.       int col = jv.elem (j);
  1494.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, i, col);
  1495.     }
  1496.     }
  1497.  
  1498.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1499.  
  1500.   return retval;
  1501. }
  1502.  
  1503. tree_constant
  1504. TC_REP::do_matrix_index (TC_REP::constant_type mci, const Range& rj) const
  1505. {
  1506.   assert (mci == magic_colon);
  1507.  
  1508.   tree_constant retval;
  1509.  
  1510.   int nr = rows ();
  1511.   int jlen = rj.nelem ();
  1512.  
  1513.   CRMATRIX (m, cm, nr, jlen);
  1514.  
  1515.   double jb = rj.base ();
  1516.   double jinc = rj.inc ();
  1517.  
  1518.   for (int j = 0; j < jlen; j++)
  1519.     {
  1520.       double jtmp = jb + j * jinc;
  1521.       int col = tree_to_mat_idx (jtmp);
  1522.       for (int i = 0; i < nr; i++)
  1523.     {
  1524.       CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, i, col);
  1525.     }
  1526.     }
  1527.  
  1528.   ASSIGN_CRMATRIX_TO (retval, m, cm);
  1529.  
  1530.   return retval;
  1531. }
  1532.  
  1533. tree_constant
  1534. TC_REP::do_matrix_index (TC_REP::constant_type mci,
  1535.              TC_REP::constant_type mcj) const
  1536. {
  1537.   tree_constant retval;
  1538.  
  1539.   assert (mci == magic_colon && mcj == magic_colon);
  1540.  
  1541.   switch (type_tag)
  1542.     {
  1543.     case complex_scalar_constant:
  1544.       retval = *complex_scalar;
  1545.       break;
  1546.  
  1547.     case scalar_constant:
  1548.       retval = scalar;
  1549.       break;
  1550.  
  1551.     case complex_matrix_constant:
  1552.       retval = *complex_matrix;
  1553.       break;
  1554.  
  1555.     case matrix_constant:
  1556.       retval = *matrix;
  1557.       break;
  1558.  
  1559.     case range_constant:
  1560.       retval = *range;
  1561.       break;
  1562.  
  1563.     case string_constant:
  1564.       retval = string;
  1565.       break;
  1566.  
  1567.     case magic_colon:
  1568.     default:
  1569.       panic_impossible ();
  1570.       break;
  1571.     }
  1572.  
  1573.   return retval;
  1574. }
  1575.  
  1576. /*
  1577. ;;; Local Variables: ***
  1578. ;;; mode: C++ ***
  1579. ;;; page-delimiter: "^/\\*" ***
  1580. ;;; End: ***
  1581. */
  1582.