changeset 3351:8623649c967c

[project @ 1999-11-15 16:17:01 by jwe]
author jwe
date Mon, 15 Nov 1999 16:17:06 +0000
parents 729ad2b6a052
children 0ddc382c245c
files ChangeLog configure.in src/Makefile.in src/TEMPLATE-INST/Array-tc.cc src/lex.h src/lex.l src/ov-base.cc src/ov-base.h src/ov.cc src/ov.h src/parse.y src/pt-all.h src/pt-pr-code.cc src/pt-pr-code.h src/pt-walk.h
diffstat 15 files changed, 214 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Nov 12 16:18:17 1999 +0000
+++ b/ChangeLog	Mon Nov 15 16:17:06 1999 +0000
@@ -1,3 +1,8 @@
+1999-11-15  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* configure.in (XTRA_CXXFLAGS, XTRA_CFLAGS): Use -mminimal-toc on
+	AIX systems.
+
 1999-10-26  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* emacs/README: New file.
--- a/configure.in	Fri Nov 12 16:18:17 1999 +0000
+++ b/configure.in	Mon Nov 15 16:17:06 1999 +0000
@@ -21,7 +21,7 @@
 ### Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 ### 02111-1307, USA. 
 
-AC_REVISION($Revision: 1.319 $)
+AC_REVISION($Revision: 1.320 $)
 AC_PREREQ(2.9)
 AC_INIT(src/octave.cc)
 AC_CONFIG_HEADER(config.h)
@@ -256,11 +256,11 @@
       AC_MSG_RESULT([adding -mieee-with-inexact to XTRA_CXXFLAGS])])
   ;;
   *ibm-aix4*)
-    OCTAVE_CC_FLAG(-mno-fp-in-toc, [
-      XTRA_CFLAGS="$XTRA_CFLAGS -mno-fp-in-toc"])
+    OCTAVE_CC_FLAG(-mminimal-toc, [
+      XTRA_CFLAGS="$XTRA_CFLAGS -mminimal-toc"])
 
-    OCTAVE_CXX_FLAG(-mno-fp-in-toc, [
-      XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mno-fp-in-toc"])
+    OCTAVE_CXX_FLAG(-mminimal-toc, [
+      XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mminimal-toc"])
   ;;
 esac
 
--- a/src/Makefile.in	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/Makefile.in	Mon Nov 15 16:17:06 1999 +0000
@@ -73,19 +73,20 @@
 OV_INCLUDES := ov-re-mat.h ov-cx-mat.h ov-ch-mat.h ov-list.h \
 	ov-struct.h ov-scalar.h ov-range.h ov-complex.h ov-va-args.h \
 	ov-colon.h ov-base.h ov-base-mat.h ov-base-scalar.h \
-	ov-str-mat.h ov-bool-mat.h ov-bool.h ov-file.h ov.h \
+	ov-str-mat.h ov-bool-mat.h ov-bool.h ov-file.h ov-cell.h ov.h \
 	ov-fcn.h ov-builtin.h ov-dld-fcn.h ov-mapper.h ov-usr-fcn.h \
 	ov-typeinfo.h
 
 PT_INCLUDES := pt.h pt-all.h pt-arg-list.h pt-assign.h pt-binop.h \
-	pt-check.h pt-cmd.h pt-colon.h pt-const.h pt-decl.h \
+	pt-cell.h pt-check.h pt-cmd.h pt-colon.h pt-const.h pt-decl.h \
 	pt-except.h pt-exp.h pt-id.h pt-idx.h pt-indir.h \
 	pt-jump.h pt-loop.h pt-mat.h pt-misc.h pt-plot.h \
 	pt-pr-code.h pt-select.h pt-stmt.h pt-unop.h pt-walk.h
 
-INCLUDES := BaseSLList.h DLList.h Map.h Pix.h SLList.h SLStack.h Stack.h \
-	defun-dld.h defun-int.h defun.h dirfns.h dynamic-ld.h error.h \
-	file-io.h fn-cache.h gripes.h help.h input.h lex.h load-save.h \
+INCLUDES := BaseSLList.h Cell.h DLList.h Map.h Pix.h SLList.h \
+	SLStack.h Stack.h defun-dld.h defun-int.h defun.h \
+	dirfns.h dynamic-ld.h error.h file-io.h fn-cache.h \
+	gripes.h help.h input.h lex.h load-save.h \
 	oct-fstrm.h oct-hist.h oct-iostrm.h oct-map.h oct-obj.h \
 	oct-prcstrm.h oct-procbuf.h oct-stdstrm.h oct-stream.h \
 	oct-strstrm.h oct-lvalue.h oct.h ops.h pager.h parse.h \
@@ -114,27 +115,27 @@
 OV_SRC := ov-base.cc ov-base-mat.cc ov-base-scalar.cc ov-ch-mat.cc \
 	ov-list.cc ov-re-mat.cc ov-cx-mat.cc ov-range.cc ov-scalar.cc \
 	ov-complex.cc ov-str-mat.cc ov-struct.cc ov-va-args.cc \
-	ov-colon.cc ov-bool-mat.cc ov-bool.cc ov-file.cc ov.cc ov-fcn.cc \
-	ov-builtin.cc ov-dld-fcn.cc ov-mapper.cc ov-usr-fcn.cc \
-	ov-typeinfo.cc
+	ov-colon.cc ov-bool-mat.cc ov-bool.cc ov-file.cc ov-cell.cc \
+	ov.cc ov-fcn.cc ov-builtin.cc ov-dld-fcn.cc ov-mapper.cc \
+	ov-usr-fcn.cc ov-typeinfo.cc
 
-PT_SRC := pt.cc pt-arg-list.cc pt-assign.cc pt-binop.cc pt-check.cc \
-	pt-cmd.cc pt-colon.cc pt-const.cc pt-decl.cc pt-except.cc \
-	pt-exp.cc pt-id.cc pt-idx.cc pt-indir.cc pt-jump.cc \
+PT_SRC := pt.cc pt-arg-list.cc pt-assign.cc pt-binop.cc pt-cell.cc \
+	pt-check.cc pt-cmd.cc pt-colon.cc pt-const.cc pt-decl.cc \
+	pt-except.cc pt-exp.cc pt-id.cc pt-idx.cc pt-indir.cc pt-jump.cc \
 	pt-loop.cc pt-mat.cc pt-misc.cc pt-plot.cc pt-pr-code.cc \
 	pt-select.cc pt-stmt.cc pt-unop.cc
 
-DIST_SRC := BaseSLList.cc DLList.cc Map.cc SLList.cc SLStack.cc Stack.cc \
-	cutils.c data.cc defaults.cc defun.cc dirfns.cc dynamic-ld.cc \
-	error.cc file-io.cc fn-cache.cc gripes.cc help.cc input.cc \
-	lex.l load-save.cc mappers.cc matherr.c oct-fstrm.cc \
-	oct-hist.cc oct-iostrm.cc oct-map.cc oct-obj.cc oct-prcstrm.cc \
-	oct-procbuf.cc oct-stdstrm.cc oct-stream.cc oct-strstrm.cc \
-	oct-lvalue.cc pager.cc parse.y pr-output.cc procstream.cc \
-	sighandlers.cc strcasecmp.c strncase.c strfns.cc \
-	symtab.cc syscalls.cc sysdep.cc system.c token.cc \
-	toplev.cc unwind-prot.cc utils.cc variables.cc xdiv.cc \
-	xpow.cc $(OV_SRC) $(PT_SRC)
+DIST_SRC := BaseSLList.cc Cell.cc DLList.cc Map.cc SLList.cc \
+	SLStack.cc Stack.cc cutils.c data.cc defaults.cc defun.cc \
+	dirfns.cc dynamic-ld.cc error.cc file-io.cc fn-cache.cc \
+	gripes.cc help.cc input.cc lex.l load-save.cc mappers.cc \
+	matherr.c oct-fstrm.cc oct-hist.cc oct-iostrm.cc oct-map.cc \
+	oct-obj.cc oct-prcstrm.cc oct-procbuf.cc oct-stdstrm.cc \
+	oct-stream.cc oct-strstrm.cc oct-lvalue.cc pager.cc parse.y \
+	pr-output.cc procstream.cc sighandlers.cc strcasecmp.c \
+	strncase.c strfns.cc symtab.cc syscalls.cc sysdep.cc \
+	system.c token.cc toplev.cc unwind-prot.cc utils.cc \
+	variables.cc xdiv.cc xpow.cc $(OV_SRC) $(PT_SRC)
 
 SOURCES := $(DIST_SRC) $(OP_SRC) $(TI_SRC)
 
--- a/src/TEMPLATE-INST/Array-tc.cc	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/TEMPLATE-INST/Array-tc.cc	Mon Nov 15 16:17:06 1999 +0000
@@ -44,6 +44,7 @@
 extern template class DiagArray2<Complex>;
 
 template class Array<octave_value>;
+template class Array2<octave_value>;
 
 /*
 ;;; Local Variables: ***
--- a/src/lex.h	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/lex.h	Mon Nov 15 16:17:06 1999 +0000
@@ -122,8 +122,8 @@
 
   void init (void);
 
-  // Brace level count.
-  int braceflag;
+  // Square bracket level count.
+  int bracketflag;
 
   // TRUE means we're in the middle of defining a loop.
   int looping;
--- a/src/lex.l	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/lex.l	Mon Nov 15 16:17:06 1999 +0000
@@ -86,15 +86,18 @@
 const yum_yum ATE_SPACE_OR_TAB = 1;
 const yum_yum ATE_NEWLINE = 2;
 
-// Is the closest nesting level a square brace or a paren?
+// Is the closest nesting level a square bracket, squiggly brace or a paren?
 
-class brace_paren_nesting_level : public SLStack <int>
+class bracket_brace_paren_nesting_level : public SLStack <int>
 {
 public:
 
-  brace_paren_nesting_level (void) : SLStack<int> () { }
+  bracket_brace_paren_nesting_level (void) : SLStack<int> () { }
 
-  ~brace_paren_nesting_level (void) { }
+  ~bracket_brace_paren_nesting_level (void) { }
+
+  void bracket (void) { push (BRACKET); }
+  bool is_bracket (void) { return ! empty () && top () == BRACKET; }
 
   void brace (void) { push (BRACE); }
   bool is_brace (void) { return ! empty () && top () == BRACE; }
@@ -108,14 +111,15 @@
 
 private:
 
-  enum { BRACE = 1, PAREN = 2 };
+  enum { BRACKET = 1, BRACE = 2, PAREN = 3 };
 
-  brace_paren_nesting_level (const brace_paren_nesting_level&);
+  bracket_brace_paren_nesting_level (const bracket_brace_paren_nesting_level&);
 
-  brace_paren_nesting_level& operator = (const brace_paren_nesting_level&);
+  bracket_brace_paren_nesting_level&
+  operator = (const bracket_brace_paren_nesting_level&);
 };
 
-static brace_paren_nesting_level nesting_level;
+static bracket_brace_paren_nesting_level nesting_level;
 
 // Should whitespace in a literal matrix list be automatically
 // converted to commas and semicolons?
@@ -176,7 +180,7 @@
 static string strip_trailing_whitespace (char *s);
 static void handle_number (void);
 static int handle_string (char delim, int text_style = 0);
-static int handle_close_brace (int spc_gobbled);
+static int handle_close_bracket (int spc_gobbled);
 static int handle_identifier (const string& tok, int spc_gobbled);
 static bool have_continuation (bool trailing_comments_ok = true);
 static bool have_ellipsis_continuation (bool trailing_comments_ok = true);
@@ -262,7 +266,7 @@
     int c = yytext[yyleng-1];
     int cont_is_spc = eat_continuation ();
     int spc_gobbled = (cont_is_spc || c == ' ' || c == '\t');
-    return handle_close_brace (spc_gobbled);
+    return handle_close_bracket (spc_gobbled);
   }
 
 %{
@@ -299,7 +303,7 @@
 	int postfix_un_op = next_token_is_postfix_unary_op (true);
 
 	if (! (postfix_un_op || bin_op)
-	    && nesting_level.is_brace ()
+	    && nesting_level.is_bracket ()
 	    && lexer_flags.convert_spaces_to_comma)
 	  {
 	    lexer_flags.quote_is_transpose = false;
@@ -346,19 +350,19 @@
 	if (nesting_level.none ())
 	  return LEXICAL_ERROR;
 
-	if (nesting_level.is_brace ())
+	if (nesting_level.is_bracket ())
 	  return ';';
       }
   }
 
 %{
-// Open and close brace are handled differently if we are in the range
+// Open and close bracket are handled differently if we are in the range
 // part of a plot command.
 //
 %}
 
 \[{S}* {
-    nesting_level.brace ();
+    nesting_level.bracket ();
 
     current_input_column += yyleng;
     lexer_flags.quote_is_transpose = false;
@@ -375,7 +379,7 @@
       }
     else
       {
-	lexer_flags.braceflag++;
+	lexer_flags.bracketflag++;
 	BEGIN MATRIX;
 	return '[';
       }
@@ -477,7 +481,7 @@
     if (nesting_level.none ())
       return '\n';
 
-    if (nesting_level.is_brace ())
+    if (nesting_level.is_bracket ())
       return LEXICAL_ERROR;
   }
 
@@ -548,7 +552,7 @@
 
     if (nesting_level.none ())
       return '\n';
-    else if (nesting_level.is_brace ())
+    else if (nesting_level.is_bracket ())
       return ';';
   }
 
@@ -617,7 +621,7 @@
     current_input_column++;
     lexer_flags.cant_be_identifier = true;
     lexer_flags.quote_is_transpose = true;
-    lexer_flags.convert_spaces_to_comma = nesting_level.is_brace ();
+    lexer_flags.convert_spaces_to_comma = nesting_level.is_bracket ();
     do_comma_insert_check ();
     return ')';
   }
@@ -641,6 +645,24 @@
 "<<="	{ BIN_OP_RETURN (LSHIFT_EQ, false); }
 ">>="	{ BIN_OP_RETURN (RSHIFT_EQ, false); }
 
+"{" {
+    nesting_level.brace ();
+    promptflag--;
+    TOK_RETURN ('{');
+  }
+
+"}" {
+    nesting_level.remove ();
+
+    current_input_column++;
+    lexer_flags.cant_be_identifier = true;
+    lexer_flags.quote_is_transpose = true;
+    lexer_flags.convert_spaces_to_comma = nesting_level.is_bracket ();
+    do_comma_insert_check (); // Is this really necessary?
+
+    return '}';
+  }
+
 %{
 // Unrecognized input is a lexical error.
 %}
@@ -674,7 +696,7 @@
   if (spc_gobbled)
     unput (' ');
 
-  lexer_flags.do_comma_insert = (lexer_flags.braceflag && c == '[');
+  lexer_flags.do_comma_insert = (lexer_flags.bracketflag && c == '[');
 }
 
 // Fix things up for errors or interrupts.  The parser is never called
@@ -691,7 +713,7 @@
   // We do want a prompt by default.
   promptflag = 1;
 
-  // Error may have occurred inside some parentheses or braces.
+  // Error may have occurred inside some brackets, braces, or parentheses.
   nesting_level.clear ();
 
   // Clear out the stack of token info used to track line and column
@@ -1806,17 +1828,17 @@
 }
 
 static int
-handle_close_brace (int spc_gobbled)
+handle_close_bracket (int spc_gobbled)
 {
   int retval = ']';
 
   if (! nesting_level.none ())
     {
       nesting_level.remove ();
-      lexer_flags.braceflag--;
+      lexer_flags.bracketflag--;
     }
 
-  if (lexer_flags.braceflag == 0)
+  if (lexer_flags.bracketflag == 0)
     BEGIN 0;
 
   if (next_token_is_assign_op () && ! lexer_flags.looking_at_return_list)
@@ -1828,7 +1850,7 @@
       int c1 = yyinput ();
       unput (c1);
 
-      if (lexer_flags.braceflag && Vwhitespace_in_literal_matrix != 2)
+      if (lexer_flags.bracketflag && Vwhitespace_in_literal_matrix != 2)
 	{
 	  int bin_op = next_token_is_bin_op (spc_gobbled);
 
@@ -1837,7 +1859,7 @@
 	  int sep_op = next_token_is_sep_op ();
 
 	  if (! (postfix_un_op || bin_op || sep_op)
-	      && nesting_level.is_brace ()
+	      && nesting_level.is_bracket ()
 	      && lexer_flags.convert_spaces_to_comma)
 	    {
 	      unput (',');
@@ -1856,7 +1878,7 @@
 static void
 maybe_unput_comma (int spc_gobbled)
 {
-  if (Vwhitespace_in_literal_matrix != 2 && nesting_level.is_brace ())
+  if (Vwhitespace_in_literal_matrix != 2 && nesting_level.is_bracket ())
     {
       int bin_op = next_token_is_bin_op (spc_gobbled);
 
@@ -1950,7 +1972,7 @@
       if (! lexer_flags.in_plot_range)
 	lexer_flags.past_plot_range = true;
 
-      // Option keywords can't appear in parentheses or braces.
+      // Option keywords can't appear in brackets, braces, or parentheses.
 
       int plot_option_kw = 0;
 
@@ -2090,7 +2112,7 @@
 lexical_feedback::init (void)
 {
   // Not initially defining a matrix list.
-  braceflag = 0;
+  bracketflag = 0;
 
   // Not initially inside a loop or if statement.
   looping = 0;
--- a/src/ov-base.cc	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/ov-base.cc	Mon Nov 15 16:17:06 1999 +0000
@@ -32,6 +32,7 @@
 
 #include "lo-ieee.h"
 
+#include "Cell.h"
 #include "gripes.h"
 #include "oct-map.h"
 #include "oct-obj.h"
@@ -196,6 +197,14 @@
   return retval;
 }
 
+Cell
+octave_base_value::cell_value (bool) const
+{
+  Cell retval;
+  gripe_wrong_type_arg ("octave_base_value::cell_value()", type_name ());
+  return retval;
+}
+
 Matrix
 octave_base_value::matrix_value (bool) const
 {
--- a/src/ov-base.h	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/ov-base.h	Mon Nov 15 16:17:06 1999 +0000
@@ -40,6 +40,7 @@
 #include "ov.h"
 #include "ov-typeinfo.h"
 
+class Cell;
 class Octave_map;
 class octave_value_list;
 
@@ -92,6 +93,8 @@
 
   bool is_defined (void) const { return false; }
 
+  bool is_cell (void) const { return false; }
+
   bool is_real_scalar (void) const { return false; }
 
   bool is_real_matrix (void) const { return false; }
@@ -163,6 +166,8 @@
   double scalar_value (bool frc_str_conv = false) const
     { return double_value (frc_str_conv); }
 
+  Cell cell_value (bool = false) const;
+
   Matrix matrix_value (bool = false) const;
 
   Complex complex_value (bool = false) const;
--- a/src/ov.cc	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/ov.cc	Mon Nov 15 16:17:06 1999 +0000
@@ -37,6 +37,7 @@
 #include "ov-base.h"
 #include "ov-bool.h"
 #include "ov-bool-mat.h"
+#include "ov-cell.h"
 #include "ov-scalar.h"
 #include "ov-re-mat.h"
 #include "ov-complex.h"
@@ -334,6 +335,13 @@
   rep->count = 1;
 }
 
+octave_value::octave_value (const Cell& c)
+  : rep (new octave_cell (c))
+{
+  rep->count = 1;
+  maybe_mutate ();
+}
+
 octave_value::octave_value (const Matrix& m)
   : rep (new octave_matrix (m))
 {
@@ -709,6 +717,12 @@
   return octave_lvalue ();
 }
 
+Cell
+octave_value::cell_value (void) const
+{
+  return rep->cell_value ();
+}
+
 Octave_map
 octave_value::map_value (void) const
 {
--- a/src/ov.h	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/ov.h	Mon Nov 15 16:17:06 1999 +0000
@@ -39,6 +39,7 @@
 #include "oct-alloc.h"
 #include "str-vec.h"
 
+class Cell;
 class Octave_map;
 class octave_stream;
 class octave_function;
@@ -152,6 +153,7 @@
 
   octave_value (void);
   octave_value (double d);
+  octave_value (const Cell& m);
   octave_value (const Matrix& m);
   octave_value (const DiagMatrix& d);
   octave_value (const RowVector& v, int pcv = -1);
@@ -289,6 +291,9 @@
   bool is_undefined (void) const
     { return ! is_defined (); }
 
+  virtual bool is_cell (void) const
+    { return rep->is_cell (); }
+
   virtual bool is_real_scalar (void) const
     { return rep->is_real_scalar (); }
 
@@ -402,6 +407,8 @@
   virtual double scalar_value (bool frc_str_conv = false) const
     { return rep->scalar_value (frc_str_conv); }
 
+  virtual Cell cell_value (void) const;
+
   virtual Matrix matrix_value (bool frc_str_conv = false) const
     { return rep->matrix_value (frc_str_conv); }
 
--- a/src/parse.y	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/parse.y	Mon Nov 15 16:17:06 1999 +0000
@@ -266,6 +266,10 @@
 static tree_expression *
 finish_matrix (tree_matrix *m);
 
+// Finish building a cell list.
+static tree_expression *
+finish_cell (tree_cell *c);
+
 // Maybe print a warning.  Duh.
 static void
 maybe_warn_missing_semi (tree_statement_list *);
@@ -299,6 +303,7 @@
   char sep_type;
   tree *tree_type;
   tree_matrix *tree_matrix_type;
+  tree_cell *tree_cell_type;
   tree_expression *tree_expression_type;
   tree_constant *tree_constant_type;
   tree_identifier *tree_identifier_type;
@@ -363,15 +368,17 @@
 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep
 %type <tree_type> input
 %type <tree_constant_type> constant magic_colon
-%type <tree_matrix_type> rows rows1
-%type <tree_expression_type> title matrix
+%type <tree_matrix_type> matrix_rows matrix_rows1
+%type <tree_cell_type> cell_rows cell_rows1
+%type <tree_expression_type> title matrix cell
 %type <tree_expression_type> primary_expr postfix_expr prefix_expr binary_expr
 %type <tree_expression_type> simple_expr colon_expr assign_expr expression
 %type <tree_identifier_type> identifier
 %type <octave_user_function_type> function1 function2 function3
 %type <tree_index_expression_type> word_list_cmd
 %type <tree_colon_expression_type> colon_expr1
-%type <tree_argument_list_type> arg_list word_list assign_lhs matrix_row
+%type <tree_argument_list_type> arg_list word_list assign_lhs
+%type <tree_argument_list_type> cell_or_matrix_row
 %type <tree_parameter_list_type> param_list param_list1
 %type <tree_parameter_list_type> return_list return_list1
 %type <tree_command_type> command select_command loop_command
@@ -410,7 +417,7 @@
 %left QUOTE TRANSPOSE
 %left UNARY PLUS_PLUS MINUS_MINUS EXPR_NOT
 %right POW EPOW
-%left '(' '.'
+%left '(' '.' '{'
 
 // Where to start.
 %start input
@@ -532,29 +539,53 @@
 		  { $$ = new tree_constant (octave_value (Matrix ())); }
 		| '[' ';' ']'
 		  { $$ = new tree_constant (octave_value (Matrix ())); }
-		| '[' in_matrix_or_assign_lhs rows ']'
+		| '[' in_matrix_or_assign_lhs matrix_rows ']'
 		  {
 		    $$ = finish_matrix ($3);
 		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
 		  }
 		;
 
-rows		: rows1
+matrix_rows	: matrix_rows1
 		  { $$ = $1; }
-		| rows1 ';'	// Ignore trailing semicolon.
+		| matrix_rows1 ';'	// Ignore trailing semicolon.
 		  { $$ = $1; }
 		;
 
-rows1		: matrix_row
+matrix_rows1	: cell_or_matrix_row
 		  { $$ = new tree_matrix ($1); }
-		| rows1 ';' matrix_row
+		| matrix_rows1 ';' cell_or_matrix_row
 		  {
 		    $1->append ($3);
 		    $$ = $1;
 		  }
 		;
 
-matrix_row	: arg_list
+cell		: '{' '}'
+		  { $$ = new tree_constant (octave_value (Matrix ())); }
+		| '{' ';' '}'
+		  { $$ = new tree_constant (octave_value (Matrix ())); }
+		| '{' cell_rows '}'
+		  { $$ = finish_cell ($2); }
+		;
+
+cell_rows	: cell_rows1
+		  { $$ = $1; }
+		| cell_rows1 ';'	// Ignore trailing semicolon.
+		  { $$ = $1; }
+		;
+
+cell_rows1	: cell_or_matrix_row
+		  { $$ = new tree_cell ($1); }
+		| cell_rows1 ';' cell_or_matrix_row
+		  {
+		    $1->append ($3);
+		    $$ = $1;
+		  }
+		;
+
+cell_or_matrix_row
+		: arg_list
 		  { $$ = $1; }
 		| arg_list ','	// Ignore trailing comma.
 		  { $$ = $1; }
@@ -566,6 +597,8 @@
 		  { $$ = $1; }
 		| matrix
 		  { $$ = $1; }
+		| cell
+		  { $$ = $1; }
 		| '(' expression ')'
 		  { $$ = $2->mark_in_parens (); }
 		;
@@ -616,6 +649,8 @@
 		  { $$ = make_index_expression ($1, 0); }
 		| postfix_expr '(' arg_list ')'
 		  { $$ = make_index_expression ($1, $3); }
+		| postfix_expr '{' arg_list '}'
+		  { $$ = make_index_expression ($1, $3); }
 		| postfix_expr PLUS_PLUS
 		  { $$ = make_postfix_op (PLUS_PLUS, $1, $2); }
 		| postfix_expr MINUS_MINUS
@@ -2518,6 +2553,16 @@
   return retval;
 }
 
+// Finish building a cell list.
+
+static tree_expression *
+finish_cell (tree_cell *c)
+{
+  // For now, this doesn't do anything.
+
+  return c;
+}
+
 static void
 maybe_warn_missing_semi (tree_statement_list *t)
 {
--- a/src/pt-all.h	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/pt-all.h	Mon Nov 15 16:17:06 1999 +0000
@@ -40,6 +40,7 @@
 #include "pt-jump.h"
 #include "pt-loop.h"
 #include "pt-mat.h"
+#include "pt-cell.h"
 #include "pt-misc.h"
 #include "pt-plot.h"
 #include "pt-pr-code.h"
--- a/src/pt-pr-code.cc	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/pt-pr-code.cc	Mon Nov 15 16:17:06 1999 +0000
@@ -506,6 +506,37 @@
 }
 
 void
+tree_print_code::visit_cell (tree_cell& lst)
+{
+  indent ();
+
+  print_parens (lst, "(");
+
+  os << "{";
+
+  Pix p = lst.first ();
+
+  while (p)
+    {
+      tree_argument_list *elt = lst (p);
+
+      lst.next (p);
+
+      if (elt)
+	{
+	  elt->accept (*this);
+
+	  if (p)
+	    os << "; ";
+	}
+    }
+
+  os << "}";
+
+  print_parens (lst, ")");
+}
+
+void
 tree_print_code::visit_multi_assignment (tree_multi_assignment& expr)
 {
   indent ();
--- a/src/pt-pr-code.h	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/pt-pr-code.h	Mon Nov 15 16:17:06 1999 +0000
@@ -86,6 +86,8 @@
 
   void visit_matrix (tree_matrix&);
 
+  void visit_cell (tree_cell&);
+
   void visit_multi_assignment (tree_multi_assignment&);
 
   void visit_no_op_command (tree_no_op_command&);
--- a/src/pt-walk.h	Fri Nov 12 16:18:17 1999 +0000
+++ b/src/pt-walk.h	Mon Nov 15 16:17:06 1999 +0000
@@ -44,6 +44,7 @@
 class tree_index_expression;
 class tree_indirect_ref;
 class tree_matrix;
+class tree_cell;
 class tree_multi_assignment;
 class tree_no_op_command;
 class tree_constant;
@@ -136,6 +137,9 @@
   visit_matrix (tree_matrix&) = 0;
 
   virtual void
+  visit_cell (tree_cell&) = 0;
+
+  virtual void
   visit_multi_assignment (tree_multi_assignment&) = 0;
 
   virtual void