GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
pt-colon.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2013 John W. Eaton
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
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
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
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include "error.h"
28 #include "oct-obj.h"
29 #include "pager.h"
30 #include "ov.h"
31 #include "pt-bp.h"
32 #include "pt-colon.h"
33 #include "pt-walk.h"
34 
35 // Colon expressions.
36 
39 {
40  tree_colon_expression *retval = 0;
41 
42  if (op_base)
43  {
44  if (op_limit)
45  {
46  if (op_increment)
47  ::error ("invalid colon expression");
48  else
49  {
50  // Stupid syntax:
51  //
52  // base : limit
53  // base : increment : limit
54 
56  op_limit = t;
57  }
58  }
59  else
60  op_limit = t;
61 
62  retval = this;
63  }
64  else
65  ::error ("invalid colon expression");
66 
67  return retval;
68 }
69 
72 {
73  octave_value_list retval;
74 
75  if (nargout > 1)
76  error ("invalid number of output arguments for colon expression");
77  else
78  retval = rvalue1 (nargout);
79 
80  return retval;
81 }
82 
85  const Matrix& m_limit,
86  const Matrix& m_increment,
87  bool result_is_str, bool dq_str) const
88 {
89  octave_value retval;
90 
91  bool base_empty = m_base.is_empty ();
92  bool limit_empty = m_limit.is_empty ();
93  bool increment_empty = m_increment.is_empty ();
94 
95  if (base_empty || limit_empty || increment_empty)
96  retval = Range ();
97  else
98  {
99  retval = Range (m_base(0), m_limit(0), m_increment(0));
100 
101  if (result_is_str)
102  retval = retval.convert_to_str (false, true, dq_str ? '"' : '\'');
103  }
104 
105  return retval;
106 }
107 
110  const octave_value& ov_limit,
111  const octave_value& ov_increment) const
112 {
113  octave_value retval;
114 
115  if (ov_base.is_object () || ov_limit.is_object () ||
116  ov_increment.is_object ())
117  {
118  octave_value_list tmp1;
119  tmp1(2) = ov_limit;
120  tmp1(1) = ov_increment;
121  tmp1(0) = ov_base;
122 
123  octave_value fcn = symbol_table::find_function ("colon", tmp1);
124 
125  if (fcn.is_defined ())
126  {
127  octave_value_list tmp2 = fcn.do_multi_index_op (1, tmp1);
128 
129  if (! error_state)
130  retval = tmp2 (0);
131  }
132  else
133  ::error ("can not find overloaded colon function");
134  }
135  else
136  {
137  bool result_is_str = (ov_base.is_string () && ov_limit.is_string ());
138  bool dq_str = (ov_base.is_dq_string () || ov_limit.is_dq_string ());
139 
140  Matrix m_base = ov_base.matrix_value (true);
141 
142  if (error_state)
143  eval_error ("invalid base value in colon expression");
144  else
145  {
146  Matrix m_limit = ov_limit.matrix_value (true);
147 
148  if (error_state)
149  eval_error ("invalid limit value in colon expression");
150  else
151  {
152  Matrix m_increment = ov_increment.matrix_value (true);
153 
154  if (error_state)
155  eval_error ("invalid increment value in colon expression");
156  else
157  retval = make_range (m_base, m_limit, m_increment,
158  result_is_str, dq_str);
159  }
160  }
161  }
162 
163  return retval;
164 }
165 
168 {
169  octave_value retval;
170 
171  if (error_state || ! op_base || ! op_limit)
172  return retval;
173 
174  octave_value ov_base = op_base->rvalue1 ();
175 
176  if (error_state || ov_base.is_undefined ())
177  eval_error ("invalid base value in colon expression");
178  else
179  {
180  octave_value ov_limit = op_limit->rvalue1 ();
181 
182  if (error_state || ov_limit.is_undefined ())
183  eval_error ("invalid limit value in colon expression");
184  else if (ov_base.is_object () || ov_limit.is_object ())
185  {
186  octave_value_list tmp1;
187 
188  if (op_increment)
189  {
190  octave_value ov_increment = op_increment->rvalue1 ();
191 
192  if (error_state || ov_increment.is_undefined ())
193  eval_error ("invalid increment value in colon expression");
194  else
195  {
196  tmp1(2) = ov_limit;
197  tmp1(1) = ov_increment;
198  tmp1(0) = ov_base;
199  }
200  }
201  else
202  {
203  tmp1(1) = ov_limit;
204  tmp1(0) = ov_base;
205  }
206 
207  if (!error_state)
208  {
209  octave_value fcn = symbol_table::find_function ("colon", tmp1);
210 
211  if (fcn.is_defined ())
212  {
213  octave_value_list tmp2 = fcn.do_multi_index_op (1, tmp1);
214 
215  if (! error_state)
216  retval = tmp2 (0);
217  }
218  else
219  ::error ("can not find overloaded colon function");
220  }
221  }
222  else
223  {
224  octave_value ov_increment = 1.0;
225 
226  if (op_increment)
227  {
228  ov_increment = op_increment->rvalue1 ();
229 
230  if (error_state || ov_increment.is_undefined ())
231  eval_error ("invalid increment value in colon expression");
232  }
233 
234  if (! error_state)
235  retval = make_range (ov_base, ov_limit, ov_increment);
236  }
237  }
238 
239  return retval;
240 }
241 
242 void
243 tree_colon_expression::eval_error (const std::string& s) const
244 {
245  ::error ("%s", s.c_str ());
246 }
247 
248 int
250 {
251  return (op_base ? op_base->line ()
253  : (op_limit ? op_limit->line ()
254  : -1)));
255 }
256 
257 int
259 {
260  return (op_base ? op_base->column ()
262  : (op_limit ? op_limit->column ()
263  : -1)));
264 }
265 
269 {
270  tree_colon_expression *new_ce = new
271  tree_colon_expression (op_base ? op_base->dup (scope, context) : 0,
272  op_limit ? op_limit->dup (scope, context) : 0,
273  op_increment ? op_increment->dup (scope, context)
274  : 0,
275  line (), column ());
276 
277  new_ce->copy_base (*new_ce);
278 
279  return new_ce;
280 }
281 
282 void
284 {
285  tw.visit_colon_expression (*this);
286 }