Mercurial > octave
diff libinterp/parse-tree/pt-idx.cc @ 23075:4e3d47dc7e25
move parse tree classes inside octave namespace
* lex.h, lex.ll, oct-parse.in.yy, parse.h, pt-all.h, pt-arg-list.cc,
pt-arg-list.h, pt-array-list.cc, pt-array-list.h, pt-assign.cc,
pt-assign.h, pt-binop.cc, pt-binop.h, pt-bp.cc, pt-bp.h, pt-cbinop.cc,
pt-cbinop.h, pt.cc, pt-cell.cc, pt-cell.h, pt-check.cc, pt-check.h,
pt-classdef.cc, pt-classdef.h, pt-cmd.cc, pt-cmd.h, pt-colon.cc,
pt-colon.h, pt-const.cc, pt-const.h, pt-decl.cc, pt-decl.h,
pt-eval.cc, pt-eval.h, pt-except.cc, pt-except.h, pt-exp.cc, pt-exp.h,
pt-fcn-handle.cc, pt-fcn-handle.h, pt-funcall.cc, pt-funcall.h, pt.h,
pt-id.cc, pt-id.h, pt-idx.cc, pt-idx.h, pt-jump.cc, pt-jump.h,
pt-loop.cc, pt-loop.h, pt-mat.cc, pt-mat.h, pt-misc.cc, pt-misc.h,
pt-pr-code.cc, pt-pr-code.h, pt-select.cc, pt-select.h, pt-stmt.cc,
pt-stmt.h, pt-unop.cc, pt-unop.h, pt-walk.h, token.cc, token.h:
Move classes and most functions inside octave namespace.
Change all uses.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 19 Jan 2017 23:41:54 -0500 |
parents | dcbd2ceadff1 |
children | ef4d915df748 |
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-idx.cc Thu Jan 19 14:47:19 2017 -0500 +++ b/libinterp/parse-tree/pt-idx.cc Thu Jan 19 23:41:54 2017 -0500 @@ -40,111 +40,114 @@ #include "variables.h" #include "errwarn.h" -// Index expressions. - -tree_index_expression::tree_index_expression (int l, int c) - : tree_expression (l, c), expr (0), args (0), type (), - arg_nm (), dyn_field () { } - -tree_index_expression::tree_index_expression (tree_expression *e, - tree_argument_list *lst, - int l, int c, char t) - : tree_expression (l, c), expr (e), args (0), type (), - arg_nm (), dyn_field () -{ - append (lst, t); -} - -tree_index_expression::tree_index_expression (tree_expression *e, - const std::string& n, - int l, int c) - : tree_expression (l, c), expr (e), args (0), type (), - arg_nm (), dyn_field () -{ - append (n); -} - -tree_index_expression::tree_index_expression (tree_expression *e, - tree_expression *df, - int l, int c) - : tree_expression (l, c), expr (e), args (0), type (), - arg_nm (), dyn_field () -{ - append (df); -} - -void -tree_index_expression::append (tree_argument_list *lst, char t) -{ - args.push_back (lst); - type.append (1, t); - arg_nm.push_back (lst ? lst->get_arg_names () : string_vector ()); - dyn_field.push_back (static_cast<tree_expression *> (0)); - - if (lst && lst->has_magic_tilde ()) - error ("invalid use of empty argument (~) in index expression"); -} - -void -tree_index_expression::append (const std::string& n) +namespace octave { - args.push_back (static_cast<tree_argument_list *> (0)); - type.append ("."); - arg_nm.push_back (n); - dyn_field.push_back (static_cast<tree_expression *> (0)); -} + // Index expressions. + + tree_index_expression::tree_index_expression (int l, int c) + : tree_expression (l, c), expr (0), args (0), type (), + arg_nm (), dyn_field () { } + + tree_index_expression::tree_index_expression (tree_expression *e, + tree_argument_list *lst, + int l, int c, char t) + : tree_expression (l, c), expr (e), args (0), type (), + arg_nm (), dyn_field () + { + append (lst, t); + } -void -tree_index_expression::append (tree_expression *df) -{ - args.push_back (static_cast<tree_argument_list *> (0)); - type.append ("."); - arg_nm.push_back (""); - dyn_field.push_back (df); -} + tree_index_expression::tree_index_expression (tree_expression *e, + const std::string& n, + int l, int c) + : tree_expression (l, c), expr (e), args (0), type (), + arg_nm (), dyn_field () + { + append (n); + } -tree_index_expression::~tree_index_expression (void) -{ - delete expr; + tree_index_expression::tree_index_expression (tree_expression *e, + tree_expression *df, + int l, int c) + : tree_expression (l, c), expr (e), args (0), type (), + arg_nm (), dyn_field () + { + append (df); + } - while (! args.empty ()) - { - std::list<tree_argument_list *>::iterator p = args.begin (); - delete *p; - args.erase (p); - } + void + tree_index_expression::append (tree_argument_list *lst, char t) + { + args.push_back (lst); + type.append (1, t); + arg_nm.push_back (lst ? lst->get_arg_names () : string_vector ()); + dyn_field.push_back (static_cast<tree_expression *> (0)); + + if (lst && lst->has_magic_tilde ()) + error ("invalid use of empty argument (~) in index expression"); + } - while (! dyn_field.empty ()) - { - std::list<tree_expression *>::iterator p = dyn_field.begin (); - delete *p; - dyn_field.erase (p); - } -} + void + tree_index_expression::append (const std::string& n) + { + args.push_back (static_cast<tree_argument_list *> (0)); + type.append ("."); + arg_nm.push_back (n); + dyn_field.push_back (static_cast<tree_expression *> (0)); + } + + void + tree_index_expression::append (tree_expression *df) + { + args.push_back (static_cast<tree_argument_list *> (0)); + type.append ("."); + arg_nm.push_back (""); + dyn_field.push_back (df); + } + + tree_index_expression::~tree_index_expression (void) + { + delete expr; + + while (! args.empty ()) + { + std::list<tree_argument_list *>::iterator p = args.begin (); + delete *p; + args.erase (p); + } -bool -tree_index_expression::has_magic_end (void) const -{ - for (const tree_argument_list* elt : args) - { - if (elt && elt->has_magic_end ()) - return true; - } + while (! dyn_field.empty ()) + { + std::list<tree_expression *>::iterator p = dyn_field.begin (); + delete *p; + dyn_field.erase (p); + } + } - return false; -} + bool + tree_index_expression::has_magic_end (void) const + { + for (const tree_argument_list* elt : args) + { + if (elt && elt->has_magic_end ()) + return true; + } -// This is useful for printing the name of the variable in an indexed -// assignment. + return false; + } + + // This is useful for printing the name of the variable in an indexed + // assignment. -std::string -tree_index_expression::name (void) const -{ - return expr->name (); + std::string + tree_index_expression::name (void) const + { + return expr->name (); + } } static Cell -make_subs_cell (tree_argument_list *args, const string_vector& arg_nm) +make_subs_cell (octave::tree_argument_list *args, const string_vector& arg_nm) { Cell retval; @@ -169,7 +172,7 @@ } static inline octave_value_list -make_value_list (tree_argument_list *args, const string_vector& arg_nm, +make_value_list (octave::tree_argument_list *args, const string_vector& arg_nm, const octave_value *object, bool rvalue = true) { octave_value_list retval; @@ -190,79 +193,82 @@ return retval; } -std::string -tree_index_expression::get_struct_index +namespace octave +{ + std::string + tree_index_expression::get_struct_index (std::list<string_vector>::const_iterator p_arg_nm, std::list<tree_expression *>::const_iterator p_dyn_field) const -{ - std::string fn = (*p_arg_nm)(0); + { + std::string fn = (*p_arg_nm)(0); - if (fn.empty ()) - { - tree_expression *df = *p_dyn_field; + if (fn.empty ()) + { + tree_expression *df = *p_dyn_field; - if (df) - { - octave_value t = df->rvalue1 (); + if (df) + { + octave_value t = df->rvalue1 (); - fn = t.xstring_value ("dynamic structure field names must be strings"); - } - else - panic_impossible (); - } + fn = t.xstring_value ("dynamic structure field names must be strings"); + } + else + panic_impossible (); + } - return fn; -} + return fn; + } -octave_map -tree_index_expression::make_arg_struct (void) const -{ - int n = args.size (); + octave_map + tree_index_expression::make_arg_struct (void) const + { + int n = args.size (); - Cell type_field (n, 1); - Cell subs_field (n, 1); + Cell type_field (n, 1); + Cell subs_field (n, 1); - std::list<tree_argument_list *>::const_iterator p_args = args.begin (); - std::list<string_vector>::const_iterator p_arg_nm = arg_nm.begin (); - std::list<tree_expression *>::const_iterator p_dyn_field = dyn_field.begin (); + std::list<tree_argument_list *>::const_iterator p_args = args.begin (); + std::list<string_vector>::const_iterator p_arg_nm = arg_nm.begin (); + std::list<tree_expression *>::const_iterator p_dyn_field = dyn_field.begin (); - octave_map m; + octave_map m; - for (int i = 0; i < n; i++) - { - switch (type[i]) - { - case '(': - subs_field(i) = make_subs_cell (*p_args, *p_arg_nm); - break; + for (int i = 0; i < n; i++) + { + switch (type[i]) + { + case '(': + subs_field(i) = make_subs_cell (*p_args, *p_arg_nm); + break; - case '{': - subs_field(i) = make_subs_cell (*p_args, *p_arg_nm); - break; + case '{': + subs_field(i) = make_subs_cell (*p_args, *p_arg_nm); + break; - case '.': - subs_field(i) = get_struct_index (p_arg_nm, p_dyn_field); - break; + case '.': + subs_field(i) = get_struct_index (p_arg_nm, p_dyn_field); + break; - default: - panic_impossible (); - } + default: + panic_impossible (); + } - p_args++; - p_arg_nm++; - p_dyn_field++; - } + p_args++; + p_arg_nm++; + p_dyn_field++; + } - m.assign ("type", type_field); - m.assign ("subs", subs_field); + m.assign ("type", type_field); + m.assign ("subs", subs_field); + + return m; + } - return m; -} - -octave_value_list -tree_index_expression::rvalue (int nargout) -{ - return tree_index_expression::rvalue (nargout, 0); + octave_value_list + tree_index_expression::rvalue (int nargout) + { + return tree_index_expression::rvalue (nargout, 0); + } } // Final step of processing an indexing error. Add the name of the @@ -270,12 +276,13 @@ // be needed by pt-lvalue, which calls subsref?) static void -final_index_error (octave::index_exception& e, const tree_expression *expr) +final_index_error (octave::index_exception& e, + const octave::tree_expression *expr) { std::string extra_message; if (expr->is_identifier () - && dynamic_cast<const tree_identifier *> (expr)->is_variable ()) + && dynamic_cast<const octave::tree_identifier *> (expr)->is_variable ()) { std::string var = expr->name (); @@ -297,338 +304,379 @@ error_with_id (e.err_id (), msg.c_str ()); } -octave_value_list -tree_index_expression::rvalue (int nargout, - const std::list<octave_lvalue> *lvalue_list) +namespace octave { - octave_value_list retval; + octave_value_list + tree_index_expression::rvalue (int nargout, + const std::list<octave_lvalue> *lvalue_list) + { + octave_value_list retval; + + octave_value first_expr_val; + + octave_value_list first_args; - octave_value first_expr_val; + bool have_args = false; + + if (expr->is_identifier () && type[0] == '(') + { + tree_identifier *id = dynamic_cast<tree_identifier *> (expr); - octave_value_list first_args; + if (! (id->is_variable () || args.empty ())) + { + tree_argument_list *al = *(args.begin ()); + + size_t n = al ? al->length () : 0; - bool have_args = false; + if (n > 0) + { + string_vector anm = *(arg_nm.begin ()); + have_args = true; + first_args = al -> convert_to_const_vector (); + first_args.stash_name_tags (anm); - if (expr->is_identifier () && type[0] == '(') - { - tree_identifier *id = dynamic_cast<tree_identifier *> (expr); + first_expr_val = id->do_lookup (first_args); + } + } + } - if (! (id->is_variable () || args.empty ())) - { - tree_argument_list *al = *(args.begin ()); + if (first_expr_val.is_undefined ()) + first_expr_val = expr->rvalue1 (); + + octave_value tmp = first_expr_val; + octave_idx_type tmpi = 0; - size_t n = al ? al->length () : 0; + std::list<octave_value_list> idx; + + int n = args.size (); + + std::list<tree_argument_list *>::iterator p_args = args.begin (); + std::list<string_vector>::iterator p_arg_nm = arg_nm.begin (); + std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin (); - if (n > 0) - { - string_vector anm = *(arg_nm.begin ()); - have_args = true; - first_args = al -> convert_to_const_vector (); - first_args.stash_name_tags (anm); + for (int i = 0; i < n; i++) + { + if (i > 0) + { + tree_argument_list *al = *p_args; + + // In Matlab, () can only be followed by '.'. In Octave, we do not + // enforce this for rvalue expressions, but we'll split the + // evaluation at this point. This will, hopefully, allow Octave's + // looser rules apply smoothly for Matlab overloaded subsref + // codes. + bool force_split = type[i-1] == '(' && type[i] != '.'; - first_expr_val = id->do_lookup (first_args); - } - } - } + if (force_split || (al && al->has_magic_end ())) + { + // (we have force_split, or) we have an expression like + // + // x{end}.a(end) + // + // and we are looking at the argument list that + // contains the second (or third, etc.) "end" token, + // so we must evaluate everything up to the point of + // that argument list so we can pass the appropriate + // value to the built-in end function. + + try + { + octave_value_list tmp_list + =tmp.subsref (type.substr (tmpi, i-tmpi), idx, nargout); - if (first_expr_val.is_undefined ()) - first_expr_val = expr->rvalue1 (); + tmp = tmp_list.length () ? tmp_list(0) : octave_value (); + tmpi = i; + idx.clear (); + + if (tmp.is_cs_list ()) + err_indexed_cs_list (); - octave_value tmp = first_expr_val; - octave_idx_type tmpi = 0; + if (tmp.is_function ()) + { + octave_function *fcn = tmp.function_value (true); + + if (fcn && ! fcn->is_postfix_index_handled (type[i])) + { + octave_value_list empty_args; - std::list<octave_value_list> idx; - - int n = args.size (); + tmp_list = tmp.do_multi_index_op (1, empty_args); + tmp = (tmp_list.length () + ? tmp_list(0) : octave_value ()); - std::list<tree_argument_list *>::iterator p_args = args.begin (); - std::list<string_vector>::iterator p_arg_nm = arg_nm.begin (); - std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin (); + if (tmp.is_cs_list ()) + err_indexed_cs_list (); + } + } + } + catch (octave::index_exception& e) // problems with index range, type etc. + { + final_index_error (e, expr); + } + } + } - for (int i = 0; i < n; i++) - { - if (i > 0) - { - tree_argument_list *al = *p_args; + switch (type[i]) + { + case '(': + if (have_args) + { + idx.push_back (first_args); + have_args = false; + } + else + idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); + break; + + case '{': + idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); + break; + + case '.': + idx.push_back (octave_value (get_struct_index (p_arg_nm, + p_dyn_field))); + break; + + default: + panic_impossible (); + } + + p_args++; + p_arg_nm++; + p_dyn_field++; + } - // In Matlab, () can only be followed by '.'. In Octave, we do not - // enforce this for rvalue expressions, but we'll split the - // evaluation at this point. This will, hopefully, allow Octave's - // looser rules apply smoothly for Matlab overloaded subsref - // codes. - bool force_split = type[i-1] == '(' && type[i] != '.'; + try + { + retval = tmp.subsref (type.substr (tmpi, n - tmpi), idx, nargout, + lvalue_list); + } + catch (octave::index_exception& e) // range problems, bad index type, etc. + { + final_index_error (e, expr); + } + + octave_value val = retval.length () ? retval(0) : octave_value (); + + if (val.is_function ()) + { + octave_function *fcn = val.function_value (true); + + if (fcn) + { + octave_value_list empty_args; + + retval = (lvalue_list + ? val.do_multi_index_op (nargout, empty_args, + lvalue_list) + : val.do_multi_index_op (nargout, empty_args)); + } + } + + return retval; + } - if (force_split || (al && al->has_magic_end ())) + octave_value + tree_index_expression::rvalue1 (int nargout) + { + octave_value retval; + + const octave_value_list tmp = rvalue (nargout); + + if (! tmp.empty ()) + retval = tmp(0); + + return retval; + } + + octave_lvalue + tree_index_expression::lvalue (void) + { + octave_lvalue retval; + + std::list<octave_value_list> idx; + std::string tmp_type; + + int n = args.size (); + + std::list<tree_argument_list *>::iterator p_args = args.begin (); + std::list<string_vector>::iterator p_arg_nm = arg_nm.begin (); + std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin (); + + retval = expr->lvalue (); + + octave_value tmp = retval.value (); + + octave_idx_type tmpi = 0; + std::list<octave_value_list> tmpidx; + + for (int i = 0; i < n; i++) + { + if (retval.numel () != 1) + err_indexed_cs_list (); + + if (tmpi < i) + { + try + { + tmp = tmp.subsref (type.substr (tmpi, i-tmpi), tmpidx, true); + } + catch (octave::index_exception& e) // problems with range, invalid type etc. + { + final_index_error (e, expr); + } + + tmpidx.clear (); + } + + switch (type[i]) + { + case '(': { - // (we have force_split, or) we have an expression like - // - // x{end}.a(end) - // - // and we are looking at the argument list that - // contains the second (or third, etc.) "end" token, - // so we must evaluate everything up to the point of - // that argument list so we can pass the appropriate - // value to the built-in end function. + octave_value_list tidx + = make_value_list (*p_args, *p_arg_nm, &tmp, false); - try + idx.push_back (tidx); + + if (i < n - 1) { - octave_value_list tmp_list - =tmp.subsref (type.substr (tmpi, i-tmpi), idx, nargout); - - tmp = tmp_list.length () ? tmp_list(0) : octave_value (); - tmpi = i; - idx.clear (); - - if (tmp.is_cs_list ()) - err_indexed_cs_list (); - - if (tmp.is_function ()) - { - octave_function *fcn = tmp.function_value (true); + if (type[i+1] != '.') + error ("() must be followed by . or close the index chain"); - if (fcn && ! fcn->is_postfix_index_handled (type[i])) - { - octave_value_list empty_args; - - tmp_list = tmp.do_multi_index_op (1, empty_args); - tmp = (tmp_list.length () - ? tmp_list(0) : octave_value ()); - - if (tmp.is_cs_list ()) - err_indexed_cs_list (); - } - } - } - catch (octave::index_exception& e) // problems with index range, type etc. - { - final_index_error (e, expr); + tmpidx.push_back (tidx); + tmpi = i+1; } } - } + break; - switch (type[i]) - { - case '(': - if (have_args) + case '{': { - idx.push_back (first_args); - have_args = false; - } - else - idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); - break; - - case '{': - idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp)); - break; - - case '.': - idx.push_back (octave_value (get_struct_index (p_arg_nm, - p_dyn_field))); - break; + octave_value_list tidx + = make_value_list (*p_args, *p_arg_nm, &tmp, false); - default: - panic_impossible (); - } - - p_args++; - p_arg_nm++; - p_dyn_field++; - } + if (tmp.is_undefined ()) + { + if (tidx.has_magic_colon ()) + err_invalid_inquiry_subscript (); - try - { - retval = tmp.subsref (type.substr (tmpi, n - tmpi), idx, nargout, - lvalue_list); - } - catch (octave::index_exception& e) // range problems, bad index type, etc. - { - final_index_error (e, expr); - } + tmp = Cell (); + } + else if (tmp.is_zero_by_zero () + && (tmp.is_matrix_type () || tmp.is_string ())) + { + tmp = Cell (); + } - octave_value val = retval.length () ? retval(0) : octave_value (); - - if (val.is_function ()) - { - octave_function *fcn = val.function_value (true); - - if (fcn) - { - octave_value_list empty_args; + retval.numel (tmp.numel (tidx)); - retval = (lvalue_list - ? val.do_multi_index_op (nargout, empty_args, - lvalue_list) - : val.do_multi_index_op (nargout, empty_args)); - } - } - - return retval; -} + idx.push_back (tidx); + tmpidx.push_back (tidx); + tmpi = i; + } + break; -octave_value -tree_index_expression::rvalue1 (int nargout) -{ - octave_value retval; - - const octave_value_list tmp = rvalue (nargout); + case '.': + { + octave_value tidx = get_struct_index (p_arg_nm, p_dyn_field); - if (! tmp.empty ()) - retval = tmp(0); - - return retval; -} - -octave_lvalue -tree_index_expression::lvalue (void) -{ - octave_lvalue retval; + bool autoconv = (tmp.is_zero_by_zero () + && (tmp.is_matrix_type () || tmp.is_string () + || tmp.is_cell ())); - std::list<octave_value_list> idx; - std::string tmp_type; - - int n = args.size (); - - std::list<tree_argument_list *>::iterator p_args = args.begin (); - std::list<string_vector>::iterator p_arg_nm = arg_nm.begin (); - std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin (); - - retval = expr->lvalue (); - - octave_value tmp = retval.value (); - - octave_idx_type tmpi = 0; - std::list<octave_value_list> tmpidx; + if (i > 0 && type[i-1] == '(') + { + octave_value_list pidx = idx.back (); - for (int i = 0; i < n; i++) - { - if (retval.numel () != 1) - err_indexed_cs_list (); + // Use octave_map, not octave_scalar_map so that the + // dimensions are 0x0, not 1x1. + if (tmp.is_undefined ()) + { + if (pidx.has_magic_colon ()) + err_invalid_inquiry_subscript (); - if (tmpi < i) - { - try - { - tmp = tmp.subsref (type.substr (tmpi, i-tmpi), tmpidx, true); - } - catch (octave::index_exception& e) // problems with range, invalid type etc. - { - final_index_error (e, expr); - } + tmp = octave_map (); + } + else if (autoconv) + tmp = octave_map (); + + retval.numel (tmp.numel (pidx)); - tmpidx.clear (); - } - - switch (type[i]) - { - case '(': - { - octave_value_list tidx - = make_value_list (*p_args, *p_arg_nm, &tmp, false); - - idx.push_back (tidx); - - if (i < n - 1) - { - if (type[i+1] != '.') - error ("() must be followed by . or close the index chain"); - - tmpidx.push_back (tidx); - tmpi = i+1; - } - } - break; - - case '{': - { - octave_value_list tidx - = make_value_list (*p_args, *p_arg_nm, &tmp, false); + tmpi = i-1; + tmpidx.push_back (tidx); + } + else + { + if (tmp.is_undefined () || autoconv) + { + tmpi = i+1; + tmp = octave_value (); + } + else + { + retval.numel (tmp.numel (octave_value_list ())); - if (tmp.is_undefined ()) - { - if (tidx.has_magic_colon ()) - err_invalid_inquiry_subscript (); + tmpi = i; + tmpidx.push_back (tidx); + } + } - tmp = Cell (); - } - else if (tmp.is_zero_by_zero () - && (tmp.is_matrix_type () || tmp.is_string ())) - { - tmp = Cell (); - } + idx.push_back (tidx); + } + break; - retval.numel (tmp.numel (tidx)); + default: + panic_impossible (); + } - idx.push_back (tidx); - tmpidx.push_back (tidx); - tmpi = i; - } - break; + if (idx.back ().empty ()) + error ("invalid empty index list"); - case '.': - { - octave_value tidx = get_struct_index (p_arg_nm, p_dyn_field); + p_args++; + p_arg_nm++; + p_dyn_field++; + } - bool autoconv = (tmp.is_zero_by_zero () - && (tmp.is_matrix_type () || tmp.is_string () - || tmp.is_cell ())); + retval.set_index (type, idx); - if (i > 0 && type[i-1] == '(') - { - octave_value_list pidx = idx.back (); + return retval; + } - // Use octave_map, not octave_scalar_map so that the - // dimensions are 0x0, not 1x1. - if (tmp.is_undefined ()) - { - if (pidx.has_magic_colon ()) - err_invalid_inquiry_subscript (); + tree_index_expression * + tree_index_expression::dup (symbol_table::scope_id scope, + symbol_table::context_id context) const + { + tree_index_expression *new_idx_expr + = new tree_index_expression (line (), column ()); - tmp = octave_map (); - } - else if (autoconv) - tmp = octave_map (); + new_idx_expr->expr = expr ? expr->dup (scope, context) : 0; + + std::list<tree_argument_list *> new_args; - retval.numel (tmp.numel (pidx)); + for (const tree_argument_list* elt : args) + new_args.push_back (elt ? elt->dup (scope, context) : 0); + + new_idx_expr->args = new_args; - tmpi = i-1; - tmpidx.push_back (tidx); - } - else - { - if (tmp.is_undefined () || autoconv) - { - tmpi = i+1; - tmp = octave_value (); - } - else - { - retval.numel (tmp.numel (octave_value_list ())); + new_idx_expr->type = type; + + new_idx_expr->arg_nm = arg_nm; - tmpi = i; - tmpidx.push_back (tidx); - } - } + std::list<tree_expression *> new_dyn_field; + + for (const tree_expression* elt : dyn_field) + new_dyn_field.push_back (elt ? elt->dup (scope, context) : 0); + + new_idx_expr->dyn_field = new_dyn_field; - idx.push_back (tidx); - } - break; + new_idx_expr->copy_base (*this); - default: - panic_impossible (); - } + return new_idx_expr; + } - if (idx.back ().empty ()) - error ("invalid empty index list"); - - p_args++; - p_arg_nm++; - p_dyn_field++; - } - - retval.set_index (type, idx); - - return retval; + void + tree_index_expression::accept (tree_walker& tw) + { + tw.visit_index_expression (*this); + } } /* @@ -667,42 +715,3 @@ %! x(2).b = 1; %! assert (x(2).b == 1); */ - -tree_index_expression * -tree_index_expression::dup (symbol_table::scope_id scope, - symbol_table::context_id context) const -{ - tree_index_expression *new_idx_expr - = new tree_index_expression (line (), column ()); - - new_idx_expr->expr = expr ? expr->dup (scope, context) : 0; - - std::list<tree_argument_list *> new_args; - - for (const tree_argument_list* elt : args) - new_args.push_back (elt ? elt->dup (scope, context) : 0); - - new_idx_expr->args = new_args; - - new_idx_expr->type = type; - - new_idx_expr->arg_nm = arg_nm; - - std::list<tree_expression *> new_dyn_field; - - for (const tree_expression* elt : dyn_field) - new_dyn_field.push_back (elt ? elt->dup (scope, context) : 0); - - new_idx_expr->dyn_field = new_dyn_field; - - new_idx_expr->copy_base (*this); - - return new_idx_expr; -} - -void -tree_index_expression::accept (tree_walker& tw) -{ - tw.visit_index_expression (*this); -} -