Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "error.h"
00028 #include "oct-obj.h"
00029 #include "pager.h"
00030 #include "ov.h"
00031 #include "pt-bp.h"
00032 #include "pt-colon.h"
00033 #include "pt-walk.h"
00034
00035
00036
00037 tree_colon_expression *
00038 tree_colon_expression::append (tree_expression *t)
00039 {
00040 tree_colon_expression *retval = 0;
00041
00042 if (op_base)
00043 {
00044 if (op_limit)
00045 {
00046 if (op_increment)
00047 ::error ("invalid colon expression");
00048 else
00049 {
00050
00051
00052
00053
00054
00055 op_increment = op_limit;
00056 op_limit = t;
00057 }
00058 }
00059 else
00060 op_limit = t;
00061
00062 retval = this;
00063 }
00064 else
00065 ::error ("invalid colon expression");
00066
00067 return retval;
00068 }
00069
00070 octave_value_list
00071 tree_colon_expression::rvalue (int nargout)
00072 {
00073 octave_value_list retval;
00074
00075 if (nargout > 1)
00076 error ("invalid number of output arguments for colon expression");
00077 else
00078 retval = rvalue1 (nargout);
00079
00080 return retval;
00081 }
00082
00083 octave_value
00084 tree_colon_expression::make_range (const Matrix& m_base,
00085 const Matrix& m_limit,
00086 const Matrix& m_increment,
00087 bool result_is_str, bool dq_str) const
00088 {
00089 octave_value retval;
00090
00091 bool base_empty = m_base.is_empty ();
00092 bool limit_empty = m_limit.is_empty ();
00093 bool increment_empty = m_increment.is_empty ();
00094
00095 if (base_empty || limit_empty || increment_empty)
00096 retval = Range ();
00097 else
00098 {
00099 retval = Range (m_base(0), m_limit(0), m_increment(0));
00100
00101 if (result_is_str)
00102 retval = retval.convert_to_str (false, true, dq_str ? '"' : '\'');
00103 }
00104
00105 return retval;
00106 }
00107
00108 octave_value
00109 tree_colon_expression::make_range (const octave_value& ov_base,
00110 const octave_value& ov_limit,
00111 const octave_value& ov_increment) const
00112 {
00113 octave_value retval;
00114
00115 if (ov_base.is_object () || ov_limit.is_object () ||
00116 ov_increment.is_object ())
00117 {
00118 octave_value_list tmp1;
00119 tmp1(2) = ov_limit;
00120 tmp1(1) = ov_increment;
00121 tmp1(0) = ov_base;
00122
00123 octave_value fcn = symbol_table::find_function ("colon", tmp1);
00124
00125 if (fcn.is_defined ())
00126 {
00127 octave_value_list tmp2 = fcn.do_multi_index_op (1, tmp1);
00128
00129 if (! error_state)
00130 retval = tmp2 (0);
00131 }
00132 else
00133 ::error ("can not find overloaded colon function");
00134 }
00135 else
00136 {
00137 bool result_is_str = (ov_base.is_string () && ov_limit.is_string ());
00138 bool dq_str = (ov_base.is_dq_string () || ov_limit.is_dq_string ());
00139
00140 Matrix m_base = ov_base.matrix_value (true);
00141
00142 if (error_state)
00143 eval_error ("invalid base value in colon expression");
00144 else
00145 {
00146 Matrix m_limit = ov_limit.matrix_value (true);
00147
00148 if (error_state)
00149 eval_error ("invalid limit value in colon expression");
00150 else
00151 {
00152 Matrix m_increment = ov_increment.matrix_value (true);
00153
00154 if (error_state)
00155 eval_error ("invalid increment value in colon expression");
00156 else
00157 retval = make_range (m_base, m_limit, m_increment,
00158 result_is_str, dq_str);
00159 }
00160 }
00161 }
00162
00163 return retval;
00164 }
00165
00166 octave_value
00167 tree_colon_expression::rvalue1 (int)
00168 {
00169 octave_value retval;
00170
00171 if (error_state || ! op_base || ! op_limit)
00172 return retval;
00173
00174 octave_value ov_base = op_base->rvalue1 ();
00175
00176 if (error_state || ov_base.is_undefined ())
00177 eval_error ("invalid base value in colon expression");
00178 else
00179 {
00180 octave_value ov_limit = op_limit->rvalue1 ();
00181
00182 if (error_state || ov_limit.is_undefined ())
00183 eval_error ("invalid limit value in colon expression");
00184 else if (ov_base.is_object () || ov_limit.is_object ())
00185 {
00186 octave_value_list tmp1;
00187
00188 if (op_increment)
00189 {
00190 octave_value ov_increment = op_increment->rvalue1 ();
00191
00192 if (error_state || ov_increment.is_undefined ())
00193 eval_error ("invalid increment value in colon expression");
00194 else
00195 {
00196 tmp1(2) = ov_limit;
00197 tmp1(1) = ov_increment;
00198 tmp1(0) = ov_base;
00199 }
00200 }
00201 else
00202 {
00203 tmp1(1) = ov_limit;
00204 tmp1(0) = ov_base;
00205 }
00206
00207 if (!error_state)
00208 {
00209 octave_value fcn = symbol_table::find_function ("colon", tmp1);
00210
00211 if (fcn.is_defined ())
00212 {
00213 octave_value_list tmp2 = fcn.do_multi_index_op (1, tmp1);
00214
00215 if (! error_state)
00216 retval = tmp2 (0);
00217 }
00218 else
00219 ::error ("can not find overloaded colon function");
00220 }
00221 }
00222 else
00223 {
00224 octave_value ov_increment = 1.0;
00225
00226 if (op_increment)
00227 {
00228 ov_increment = op_increment->rvalue1 ();
00229
00230 if (error_state || ov_increment.is_undefined ())
00231 eval_error ("invalid increment value in colon expression");
00232 }
00233
00234 if (! error_state)
00235 retval = make_range (ov_base, ov_limit, ov_increment);
00236 }
00237 }
00238
00239 return retval;
00240 }
00241
00242 void
00243 tree_colon_expression::eval_error (const std::string& s) const
00244 {
00245 ::error ("%s", s.c_str ());
00246 }
00247
00248 int
00249 tree_colon_expression::line (void) const
00250 {
00251 return (op_base ? op_base->line ()
00252 : (op_increment ? op_increment->line ()
00253 : (op_limit ? op_limit->line ()
00254 : -1)));
00255 }
00256
00257 int
00258 tree_colon_expression::column (void) const
00259 {
00260 return (op_base ? op_base->column ()
00261 : (op_increment ? op_increment->column ()
00262 : (op_limit ? op_limit->column ()
00263 : -1)));
00264 }
00265
00266 tree_expression *
00267 tree_colon_expression::dup (symbol_table::scope_id scope,
00268 symbol_table::context_id context) const
00269 {
00270 tree_colon_expression *new_ce = new
00271 tree_colon_expression (op_base ? op_base->dup (scope, context) : 0,
00272 op_limit ? op_limit->dup (scope, context) : 0,
00273 op_increment ? op_increment->dup (scope, context) : 0,
00274 line (), column ());
00275
00276 new_ce->copy_base (*new_ce);
00277
00278 return new_ce;
00279 }
00280
00281 void
00282 tree_colon_expression::accept (tree_walker& tw)
00283 {
00284 tw.visit_colon_expression (*this);
00285 }