Mercurial > octave
view libinterp/parse-tree/pt-idx.cc @ 23696:08036a7f3660
remove octave:: namespace tag from symbols used inside octave namespace
* octave-gui.cc, dynamic-ld.h, ft-text-renderer.cc, gl-render.cc,
gl-render.h, gl2ps-print.cc, input.cc, input.h, interpreter.cc,
load-path.cc, load-path.h, oct-stream.cc, sighandlers.cc, symtab.cc,
symtab.h, __ode15__.cc, gzip.cc, octave.cc, lex.ll, oct-parse.in.yy,
parse.h, pt-arg-list.cc, pt-arg-list.h, pt-array-list.h,
pt-classdef.h, pt-decl.h, pt-eval.cc, pt-eval.h, pt-exp.h,
pt-fcn-handle.cc, pt-idx.cc, pt-misc.h, pt-select.h, pt-stmt.h,
pt-tm-const.cc, pt-tm-const.h, pt.cc, aepbalance.cc, chol.cc,
gepbalance.cc, gsvd.cc, hess.cc, lo-mappers.h, lo-specfun.cc, lu.cc,
qr.cc, qrp.cc, schur.cc, sparse-chol.cc, sparse-lu.cc, sparse-qr.cc,
svd.cc, child-list.cc, dir-ops.cc, file-ops.cc, file-stat.cc,
file-stat.h, lo-sysdep.cc, oct-env.cc, oct-syscalls.cc, cmd-edit.cc,
cmd-hist.cc, oct-glob.cc, oct-locbuf.cc, oct-mutex.cc, oct-mutex.h,
oct-shlib.cc, oct-shlib.h, pathsearch.cc, url-transfer.cc,
url-transfer.h: Remove octave:: namespace tag from symbols used
inside octave namespace.
* oct-conf-post.in.h (OCTAVE_USE_DEPRECATED_FUNCTIONS): Don't define.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 26 Jun 2017 09:05:37 -0400 |
parents | b9378eff6d13 |
children | 980f39c3ab90 |
line wrap: on
line source
/* Copyright (C) 1996-2017 John W. Eaton This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #if defined (HAVE_CONFIG_H) # include "config.h" #endif #include "Cell.h" #include "error.h" #include "interpreter-private.h" #include "oct-map.h" #include "ovl.h" #include "oct-lvalue.h" #include "ov.h" #include "pt-arg-list.h" #include "pt-eval.h" #include "pt-id.h" #include "pt-idx.h" #include "utils.h" #include "variables.h" #include "errwarn.h" namespace octave { // 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) { 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); } while (! dyn_field.empty ()) { std::list<tree_expression *>::iterator p = dyn_field.begin (); delete *p; dyn_field.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; } 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 (); } } static inline octave_value_list make_value_list (octave::tree_evaluator *tw, octave::tree_argument_list *args, const string_vector& arg_nm, const octave_value *object, bool rvalue = true) { octave_value_list retval; if (args) { if (rvalue && object && args->has_magic_end () && object->is_undefined ()) err_invalid_inquiry_subscript (); retval = args->convert_to_const_vector (tw, object); } octave_idx_type n = retval.length (); if (n > 0) retval.stash_name_tags (arg_nm); return retval; } namespace octave { std::string tree_index_expression::get_struct_index (tree_evaluator *tw, 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); if (fn.empty ()) { tree_expression *df = *p_dyn_field; if (df) { octave_value t = tw->evaluate (df); fn = t.xstring_value ("dynamic structure field names must be strings"); } else panic_impossible (); } return fn; } } // Final step of processing an indexing error. Add the name of the // variable being indexed, if any, then issue an error. (Will this also // be needed by pt-lvalue, which calls subsref?) static void final_index_error (octave::index_exception& e, const octave::tree_expression *expr) { std::string extra_message; if (expr->is_identifier () && dynamic_cast<const octave::tree_identifier *> (expr)->is_variable ()) { std::string var = expr->name (); e.set_var (var); octave::symbol_table& symtab = octave::__get_symbol_table__ ("final_index_error"); octave_value fcn = symtab.find_function (var); if (fcn.is_function ()) { octave_function *fp = fcn.function_value (); if (fp && fp->name () == var) extra_message = " (note: variable '" + var + "' shadows function)"; } } std::string msg = e.message () + extra_message; error_with_id (e.err_id (), msg.c_str ()); } namespace octave { octave_lvalue tree_index_expression::lvalue (tree_evaluator *tw) { 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 (tw); 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 (index_exception& e) // problems with range, invalid type etc. { final_index_error (e, expr); } tmpidx.clear (); } switch (type[i]) { case '(': { octave_value_list tidx = make_value_list (tw, *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 (tw, *p_args, *p_arg_nm, &tmp, false); if (tmp.is_undefined ()) { if (tidx.has_magic_colon ()) err_invalid_inquiry_subscript (); tmp = Cell (); } else if (tmp.is_zero_by_zero () && (tmp.is_matrix_type () || tmp.is_string ())) { tmp = Cell (); } retval.numel (tmp.numel (tidx)); idx.push_back (tidx); tmpidx.push_back (tidx); tmpi = i; } break; case '.': { octave_value tidx = get_struct_index (tw, p_arg_nm, p_dyn_field); bool autoconv = (tmp.is_zero_by_zero () && (tmp.is_matrix_type () || tmp.is_string () || tmp.iscell ())); if (i > 0 && type[i-1] == '(') { octave_value_list pidx = idx.back (); // 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 (); tmp = octave_map (); } else if (autoconv) tmp = octave_map (); retval.numel (tmp.numel (pidx)); 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 ())); tmpi = i; tmpidx.push_back (tidx); } } idx.push_back (tidx); } break; default: panic_impossible (); } if (idx.back ().empty ()) error ("invalid empty index list"); p_args++; p_arg_nm++; p_dyn_field++; } retval.set_index (type, idx); return retval; } tree_index_expression * tree_index_expression::dup (symbol_table::scope& scope) const { tree_index_expression *new_idx_expr = new tree_index_expression (line (), column ()); new_idx_expr->expr = (expr ? expr->dup (scope) : 0); std::list<tree_argument_list *> new_args; for (const tree_argument_list *elt : args) new_args.push_back (elt ? elt->dup (scope) : 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) : 0); new_idx_expr->dyn_field = new_dyn_field; new_idx_expr->copy_base (*this); return new_idx_expr; } } /* %!test %! clear x; %! clear y; %! y = 3; %! x(y(end)) = 1; %! assert (x, [0, 0, 1]); %! clear x; %! clear y; %! y = {3}; %! x(y{end}) = 1; %! assert (x, [0, 0, 1]); %!test %! x = {1, 2, 3}; %! [x{:}] = deal (4, 5, 6); %! assert (x, {4, 5, 6}); %!test %! [x.a, x.b.c] = deal (1, 2); %! assert (x.a == 1 && x.b.c == 2); %!test %! [x.a, x(2).b] = deal (1, 2); %! assert (x(1).a == 1 && isempty (x(2).a) && isempty (x(1).b) && x(2).b == 2); %!test %! x = struct (zeros (0, 1), {"a", "b"}); %! x(2).b = 1; %! assert (x(2).b == 1); %!test %! x = struct (zeros (0, 1), {"a", "b"}); %! x(2).b = 1; %! assert (x(2).b == 1); */