comparison libinterp/parse-tree/pt-colon.cc @ 15195:2fc554ffbc28

split libinterp from src * libinterp: New directory. Move all files from src directory here except Makefile.am, main.cc, main-cli.cc, mkoctfile.in.cc, mkoctfilr.in.sh, octave-config.in.cc, octave-config.in.sh. * libinterp/Makefile.am: New file, extracted from src/Makefile.am. * src/Makefile.am: Delete everything except targets and definitions needed to build and link main and utility programs. * Makefile.am (SUBDIRS): Include libinterp in the list. * autogen.sh: Run config-module.sh in libinterp/dldfcn directory, not src/dldfcn directory. * configure.ac (AC_CONFIG_SRCDIR): Use libinterp/octave.cc, not src/octave.cc. (DL_LDFLAGS, LIBOCTINTERP): Use libinterp, not src. (AC_CONFIG_FILES): Include libinterp/Makefile in the list. * find-docstring-files.sh: Look in libinterp, not src. * gui/src/Makefile.am (liboctgui_la_CPPFLAGS): Find header files in libinterp, not src.
author John W. Eaton <jwe@octave.org>
date Sat, 18 Aug 2012 16:23:39 -0400
parents src/parse-tree/pt-colon.cc@46b19589b593
children d63878346099
comparison
equal deleted inserted replaced
15194:0f0b795044c3 15195:2fc554ffbc28
1 /*
2
3 Copyright (C) 1996-2012 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
37 tree_colon_expression *
38 tree_colon_expression::append (tree_expression *t)
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
55 op_increment = op_limit;
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
70 octave_value_list
71 tree_colon_expression::rvalue (int nargout)
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
83 octave_value
84 tree_colon_expression::make_range (const Matrix& m_base,
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
108 octave_value
109 tree_colon_expression::make_range (const octave_value& ov_base,
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
166 octave_value
167 tree_colon_expression::rvalue1 (int)
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
249 tree_colon_expression::line (void) const
250 {
251 return (op_base ? op_base->line ()
252 : (op_increment ? op_increment->line ()
253 : (op_limit ? op_limit->line ()
254 : -1)));
255 }
256
257 int
258 tree_colon_expression::column (void) const
259 {
260 return (op_base ? op_base->column ()
261 : (op_increment ? op_increment->column ()
262 : (op_limit ? op_limit->column ()
263 : -1)));
264 }
265
266 tree_expression *
267 tree_colon_expression::dup (symbol_table::scope_id scope,
268 symbol_table::context_id context) const
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) : 0,
274 line (), column ());
275
276 new_ce->copy_base (*new_ce);
277
278 return new_ce;
279 }
280
281 void
282 tree_colon_expression::accept (tree_walker& tw)
283 {
284 tw.visit_colon_expression (*this);
285 }