Mercurial > hg > octave-nkf
annotate libinterp/parse-tree/pt-assign.cc @ 20458:011a364b4d78
improve compatibility of indexed assignment (bug #43813)
* oct-lvalue.h, oct-lvalue.cc (octave_lvalue::index_type,
octave_lvalue::index_is_empty): New functions.
* pt-assign.cc (tree_multi_assignment::rvalue): For expressions like
[lhs{:}] = fcn (args) with LHS undefined, and in which FCN produces an
output given nargout equal to zero, convert LHS to a one-element cell
array indexed by 1.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 05 Jun 2015 15:51:04 -0400 |
parents | 4197fc428c7d |
children | dd6345fd8a97 |
rev | line source |
---|---|
2980 | 1 /* |
2 | |
19898
4197fc428c7d
maint: Update copyright notices for 2015.
John W. Eaton <jwe@octave.org>
parents:
17787
diff
changeset
|
3 Copyright (C) 1996-2015 John W. Eaton |
2980 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
2980 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
2980 | 20 |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
3503 | 27 #include <iostream> |
6253 | 28 #include <set> |
2980 | 29 |
30 #include "defun.h" | |
31 #include "error.h" | |
10030
83bb2a78c07d
improve simple assignments error checks and messages
Jaroslav Hajek <highegg@gmail.com>
parents:
9782
diff
changeset
|
32 #include "gripes.h" |
2980 | 33 #include "input.h" |
34 #include "oct-obj.h" | |
35 #include "oct-lvalue.h" | |
36 #include "pager.h" | |
37 #include "ov.h" | |
2982 | 38 #include "pt-arg-list.h" |
3770 | 39 #include "pt-bp.h" |
2980 | 40 #include "pt-assign.h" |
15606
fb9dffe5fbfb
The silent_functions flag no longer modifies the parse tree
Max Brister <max@2bass.com>
parents:
15195
diff
changeset
|
41 #include "pt-eval.h" |
2980 | 42 #include "pt-walk.h" |
43 #include "utils.h" | |
5794 | 44 #include "variables.h" |
2980 | 45 |
46 // Simple assignment expressions. | |
47 | |
6253 | 48 tree_simple_assignment::tree_simple_assignment |
49 (tree_expression *le, tree_expression *re, | |
50 bool plhs, int l, int c, octave_value::assign_op t) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
51 : tree_expression (l, c), lhs (le), rhs (re), preserve (plhs), etype (t) |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
52 { } |
6253 | 53 |
2980 | 54 tree_simple_assignment::~tree_simple_assignment (void) |
55 { | |
56 if (! preserve) | |
57 delete lhs; | |
58 | |
59 delete rhs; | |
60 } | |
61 | |
62 octave_value_list | |
63 tree_simple_assignment::rvalue (int nargout) | |
64 { | |
65 octave_value_list retval; | |
66 | |
67 if (nargout > 1) | |
68 error ("invalid number of output arguments for expression X = RHS"); | |
69 else | |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
8580
diff
changeset
|
70 retval = rvalue1 (nargout); |
2980 | 71 |
72 return retval; | |
73 } | |
74 | |
75 octave_value | |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
8580
diff
changeset
|
76 tree_simple_assignment::rvalue1 (int) |
2980 | 77 { |
3208 | 78 octave_value retval; |
2980 | 79 |
80 if (error_state) | |
3208 | 81 return retval; |
2980 | 82 |
83 if (rhs) | |
84 { | |
8905
24dd61b36591
assign rvalue1 result to octave_value object, not octave_value_list object
John W. Eaton <jwe@octave.org>
parents:
8658
diff
changeset
|
85 octave_value rhs_val = rhs->rvalue1 (); |
2980 | 86 |
8905
24dd61b36591
assign rvalue1 result to octave_value object, not octave_value_list object
John W. Eaton <jwe@octave.org>
parents:
8658
diff
changeset
|
87 if (! error_state) |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
88 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
89 if (rhs_val.is_undefined ()) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
90 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
91 error ("value on right hand side of assignment is undefined"); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
92 return retval; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
93 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
94 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
95 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
96 if (rhs_val.is_cs_list ()) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
97 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
98 const octave_value_list lst = rhs_val.list_value (); |
7389 | 99 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
100 if (! lst.empty ()) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
101 rhs_val = lst(0); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
102 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
103 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
104 error ("invalid number of elements on RHS of assignment"); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
105 return retval; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
106 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
107 } |
7389 | 108 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
109 octave_lvalue ult = lhs->lvalue (); |
2980 | 110 |
10030
83bb2a78c07d
improve simple assignments error checks and messages
Jaroslav Hajek <highegg@gmail.com>
parents:
9782
diff
changeset
|
111 if (ult.numel () != 1) |
83bb2a78c07d
improve simple assignments error checks and messages
Jaroslav Hajek <highegg@gmail.com>
parents:
9782
diff
changeset
|
112 gripe_nonbraced_cs_list_assignment (); |
83bb2a78c07d
improve simple assignments error checks and messages
Jaroslav Hajek <highegg@gmail.com>
parents:
9782
diff
changeset
|
113 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
114 if (! error_state) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
115 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
116 ult.assign (etype, rhs_val); |
2980 | 117 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
118 if (! error_state) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
119 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
120 if (etype == octave_value::op_asn_eq) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
121 retval = rhs_val; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
122 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
123 retval = ult.value (); |
2984 | 124 |
15606
fb9dffe5fbfb
The silent_functions flag no longer modifies the parse tree
Max Brister <max@2bass.com>
parents:
15195
diff
changeset
|
125 if (print_result () |
fb9dffe5fbfb
The silent_functions flag no longer modifies the parse tree
Max Brister <max@2bass.com>
parents:
15195
diff
changeset
|
126 && tree_evaluator::statement_printing_enabled ()) |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
127 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
128 // We clear any index here so that we can |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
129 // get the new value of the referenced |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
130 // object below, instead of the indexed |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
131 // value (which should be the same as the |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
132 // right hand side value). |
2980 | 133 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
134 ult.clear_index (); |
3208 | 135 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
136 octave_value lhs_val = ult.value (); |
3208 | 137 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
138 if (! error_state) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
139 lhs_val.print_with_name (octave_stdout, |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
140 lhs->name ()); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
141 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
142 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
143 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
144 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
145 } |
2980 | 146 } |
147 | |
3208 | 148 return retval; |
2980 | 149 } |
150 | |
3536 | 151 std::string |
2980 | 152 tree_simple_assignment::oper (void) const |
153 { | |
154 return octave_value::assign_op_as_string (etype); | |
155 } | |
156 | |
5861 | 157 tree_expression * |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7389
diff
changeset
|
158 tree_simple_assignment::dup (symbol_table::scope_id scope, |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
159 symbol_table::context_id context) const |
5861 | 160 { |
161 tree_simple_assignment *new_sa | |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7389
diff
changeset
|
162 = new tree_simple_assignment (lhs ? lhs->dup (scope, context) : 0, |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
163 rhs ? rhs->dup (scope, context) : 0, |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
164 preserve, etype); |
5861 | 165 |
166 new_sa->copy_base (*this); | |
167 | |
168 return new_sa; | |
169 } | |
170 | |
2980 | 171 void |
172 tree_simple_assignment::accept (tree_walker& tw) | |
173 { | |
174 tw.visit_simple_assignment (*this); | |
175 } | |
176 | |
177 // Multi-valued assignment expressions. | |
178 | |
6253 | 179 tree_multi_assignment::tree_multi_assignment |
180 (tree_argument_list *lst, tree_expression *r, | |
10230
0a5a769b8fc0
disallow computed multiple assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
10227
diff
changeset
|
181 bool plhs, int l, int c) |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
182 : tree_expression (l, c), lhs (lst), rhs (r), preserve (plhs) |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
183 { } |
6253 | 184 |
2980 | 185 tree_multi_assignment::~tree_multi_assignment (void) |
186 { | |
187 if (! preserve) | |
188 delete lhs; | |
189 | |
190 delete rhs; | |
191 } | |
192 | |
193 octave_value | |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
8580
diff
changeset
|
194 tree_multi_assignment::rvalue1 (int nargout) |
2980 | 195 { |
196 octave_value retval; | |
197 | |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
8580
diff
changeset
|
198 const octave_value_list tmp = rvalue (nargout); |
2980 | 199 |
200 if (! tmp.empty ()) | |
201 retval = tmp(0); | |
202 | |
203 return retval; | |
204 } | |
205 | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
206 // FIXME: this works, but it would look a little better if |
2984 | 207 // it were broken up into a couple of separate functions. |
208 | |
2980 | 209 octave_value_list |
210 tree_multi_assignment::rvalue (int) | |
211 { | |
3208 | 212 octave_value_list retval; |
2980 | 213 |
214 if (error_state) | |
3208 | 215 return retval; |
2980 | 216 |
217 if (rhs) | |
218 { | |
5846 | 219 std::list<octave_lvalue> lvalue_list = lhs->lvalue_list (); |
3977 | 220 |
221 if (error_state) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
222 return retval; |
2980 | 223 |
10832
1b2fcd122c6a
allow user detect ignored outputs in m-functions
Jaroslav Hajek <highegg@gmail.com>
parents:
10315
diff
changeset
|
224 octave_idx_type n_out = 0; |
5846 | 225 |
226 for (std::list<octave_lvalue>::const_iterator p = lvalue_list.begin (); | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
227 p != lvalue_list.end (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
228 p++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
229 n_out += p->numel (); |
5846 | 230 |
8580
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8313
diff
changeset
|
231 // The following trick is used to keep rhs_val constant. |
10832
1b2fcd122c6a
allow user detect ignored outputs in m-functions
Jaroslav Hajek <highegg@gmail.com>
parents:
10315
diff
changeset
|
232 const octave_value_list rhs_val1 = rhs->rvalue (n_out, &lvalue_list); |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
233 const octave_value_list rhs_val = (rhs_val1.length () == 1 |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
234 && rhs_val1(0).is_cs_list () |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
235 ? rhs_val1(0).list_value () |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
236 : rhs_val1); |
2980 | 237 |
3977 | 238 if (error_state) |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
239 return retval; |
2980 | 240 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
241 octave_idx_type k = 0; |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
242 |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
243 octave_idx_type n = rhs_val.length (); |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
244 |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
245 // To avoid copying per elements and possible optimizations, we |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
246 // postpone joining the final values. |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
247 std::list<octave_value_list> retval_list; |
2980 | 248 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
249 tree_argument_list::iterator q = lhs->begin (); |
2980 | 250 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
251 for (std::list<octave_lvalue>::iterator p = lvalue_list.begin (); |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
252 p != lvalue_list.end (); |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
253 p++) |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
254 { |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
255 tree_expression *lhs_elt = *q++; |
5846 | 256 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
257 octave_lvalue ult = *p; |
5846 | 258 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
259 octave_idx_type nel = ult.numel (); |
3977 | 260 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
261 if (nel != 1) |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
262 { |
20458
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
263 // Huge kluge so that wrapper scripts with lines like |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
264 // |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
265 // [varargout{1:nargout}] = fcn (args); |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
266 // |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
267 // Will work the same as calling fcn directly when nargout |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
268 // is 0 and fcn produces more than one output even when |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
269 // nargout is 0. This only works if varargout has not yet |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
270 // been defined. See also bug #43813. |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
271 |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
272 if (lvalue_list.size () == 1 && nel == 0 && n > 0 |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
273 && ! ult.is_black_hole () && ult.is_undefined () |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
274 && ult.index_type () == "{" && ult.index_is_empty ()) |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
275 { |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
276 // Convert undefined lvalue with empty index to a cell |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
277 // array with a single value and indexed by 1 to |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
278 // handle a single output. |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
279 |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
280 nel = 1; |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
281 |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
282 ult.define (Cell (1, 1)); |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
283 |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
284 ult.clear_index (); |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
285 std::list<octave_value_list> idx; |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
286 idx.push_back (octave_value_list (octave_value (1))); |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
287 ult.set_index ("{", idx); |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
288 } |
011a364b4d78
improve compatibility of indexed assignment (bug #43813)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
289 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
290 if (k + nel <= n) |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
291 { |
10230
0a5a769b8fc0
disallow computed multiple assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
10227
diff
changeset
|
292 // This won't do a copy. |
0a5a769b8fc0
disallow computed multiple assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
10227
diff
changeset
|
293 octave_value_list ovl = rhs_val.slice (k, nel); |
5846 | 294 |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
295 ult.assign (octave_value::op_asn_eq, |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
296 octave_value (ovl, true)); |
2980 | 297 |
10230
0a5a769b8fc0
disallow computed multiple assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
10227
diff
changeset
|
298 if (! error_state) |
0a5a769b8fc0
disallow computed multiple assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
10227
diff
changeset
|
299 { |
0a5a769b8fc0
disallow computed multiple assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
10227
diff
changeset
|
300 retval_list.push_back (ovl); |
5846 | 301 |
10230
0a5a769b8fc0
disallow computed multiple assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
10227
diff
changeset
|
302 k += nel; |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
303 } |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
304 } |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
305 else |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
306 error ("some elements undefined in return list"); |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
307 } |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
308 else |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
309 { |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
310 if (k < n) |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
311 { |
10230
0a5a769b8fc0
disallow computed multiple assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
10227
diff
changeset
|
312 ult.assign (octave_value::op_asn_eq, rhs_val(k)); |
3977 | 313 |
10227
d3fc22c3071c
omit ~ values from multi-assignment return lists
Jaroslav Hajek <highegg@gmail.com>
parents:
10160
diff
changeset
|
314 if (ult.is_black_hole ()) |
d3fc22c3071c
omit ~ values from multi-assignment return lists
Jaroslav Hajek <highegg@gmail.com>
parents:
10160
diff
changeset
|
315 { |
d3fc22c3071c
omit ~ values from multi-assignment return lists
Jaroslav Hajek <highegg@gmail.com>
parents:
10160
diff
changeset
|
316 k++; |
d3fc22c3071c
omit ~ values from multi-assignment return lists
Jaroslav Hajek <highegg@gmail.com>
parents:
10160
diff
changeset
|
317 continue; |
d3fc22c3071c
omit ~ values from multi-assignment return lists
Jaroslav Hajek <highegg@gmail.com>
parents:
10160
diff
changeset
|
318 } |
d3fc22c3071c
omit ~ values from multi-assignment return lists
Jaroslav Hajek <highegg@gmail.com>
parents:
10160
diff
changeset
|
319 else if (! error_state) |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
320 { |
10230
0a5a769b8fc0
disallow computed multiple assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
10227
diff
changeset
|
321 retval_list.push_back (rhs_val(k)); |
5846 | 322 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
323 k++; |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
324 } |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
325 } |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
326 else |
14572
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
327 { |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
328 // This can happen for a function like |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
329 // |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
330 // function varargout = f () |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
331 // varargout{1} = nargout; |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
332 // endfunction |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
333 // |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
334 // called with |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
335 // |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
336 // [a, ~] = f (); |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
337 // |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
338 // Then the list of of RHS values will contain one |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
339 // element but we are iterating over the list of all |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
340 // RHS values. We shouldn't complain that a value we |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
341 // don't need is missing from the list. |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
342 |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
343 if (ult.is_black_hole ()) |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
344 { |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
345 k++; |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
346 continue; |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
347 } |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
348 else |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
349 error ("element number %d undefined in return list", k+1); |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
350 } |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
351 } |
2980 | 352 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
353 if (error_state) |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
354 break; |
15606
fb9dffe5fbfb
The silent_functions flag no longer modifies the parse tree
Max Brister <max@2bass.com>
parents:
15195
diff
changeset
|
355 else if (print_result () |
fb9dffe5fbfb
The silent_functions flag no longer modifies the parse tree
Max Brister <max@2bass.com>
parents:
15195
diff
changeset
|
356 && tree_evaluator::statement_printing_enabled ()) |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
357 { |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
358 // We clear any index here so that we can get |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
359 // the new value of the referenced object below, |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
360 // instead of the indexed value (which should be |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
361 // the same as the right hand side value). |
3977 | 362 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
363 ult.clear_index (); |
3208 | 364 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
365 octave_value lhs_val = ult.value (); |
3977 | 366 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
367 if (! error_state) |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
368 lhs_val.print_with_name (octave_stdout, |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
369 lhs_elt->name ()); |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
370 } |
3977 | 371 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
372 if (error_state) |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
373 break; |
3977 | 374 |
9782
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
375 } |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
376 |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
377 // Concatenate return values. |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
378 retval = retval_list; |
eead00a7df05
don't skip empty multi-assignments to allow side effects
Jaroslav Hajek <highegg@gmail.com>
parents:
9421
diff
changeset
|
379 |
2980 | 380 } |
381 | |
3208 | 382 return retval; |
2980 | 383 } |
384 | |
14572
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
385 /* |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
386 %!function varargout = f () |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
387 %! varargout{1} = nargout; |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
388 %!endfunction |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
389 %! |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
390 %!test |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
391 %! [a, ~] = f (); |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
392 %! assert (a, 2); |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
393 %!test |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
394 %! [a, ~, ~, ~, ~] = f (); |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
395 %! assert (a, 5); |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
396 */ |
000cd393f3c1
avoid error for calls to functions returning varargout that ignore final outputs (bug #36221)
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
397 |
3536 | 398 std::string |
3208 | 399 tree_multi_assignment::oper (void) const |
400 { | |
10230
0a5a769b8fc0
disallow computed multiple assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
10227
diff
changeset
|
401 return octave_value::assign_op_as_string (op_type ()); |
3208 | 402 } |
403 | |
5861 | 404 tree_expression * |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7389
diff
changeset
|
405 tree_multi_assignment::dup (symbol_table::scope_id scope, |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
406 symbol_table::context_id context) const |
5861 | 407 { |
408 tree_multi_assignment *new_ma | |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7389
diff
changeset
|
409 = new tree_multi_assignment (lhs ? lhs->dup (scope, context) : 0, |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
410 rhs ? rhs->dup (scope, context) : 0, |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10230
diff
changeset
|
411 preserve); |
5861 | 412 |
413 new_ma->copy_base (*this); | |
414 | |
415 return new_ma; | |
416 } | |
417 | |
2980 | 418 void |
419 tree_multi_assignment::accept (tree_walker& tw) | |
420 { | |
421 tw.visit_multi_assignment (*this); | |
422 } |