Mercurial > hg > octave-lyh
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 +++ b/ChangeLog @@ -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 +++ b/configure.in @@ -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 +++ b/src/Makefile.in @@ -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 +++ b/src/TEMPLATE-INST/Array-tc.cc @@ -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 +++ b/src/lex.h @@ -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 +++ b/src/lex.l @@ -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 +++ b/src/ov-base.cc @@ -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 +++ b/src/ov-base.h @@ -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 +++ b/src/ov.cc @@ -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 +++ b/src/ov.h @@ -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 +++ b/src/parse.y @@ -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 +++ b/src/pt-all.h @@ -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 +++ b/src/pt-pr-code.cc @@ -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 +++ b/src/pt-pr-code.h @@ -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 +++ b/src/pt-walk.h @@ -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