Mercurial > octave
diff libinterp/parse-tree/pt-colon.cc @ 27371:fcaecdbc8d8a
don't use visitor pattern for expression evaluation (bug #56752)
Although it is desirable to have all parse tree evaluation functions
grouped together in a single file, using the visitor pattern can be
inefficient, especially when the visitor function is small and the
extra levels of indirection and virtual function resolution can take
more time than the evaluation function itself (evaluation of
constants, for example).
For all classes derived from tree_expression, introduce new evaluate
and evaluate_n methods. Use those instead of visit_CLASS functions to
perform expression evaluation. Results are now returned directly from
the evaluation functions instead of storing them in the tree_evaluator
object.
Files affected:
cdef-class.cc, oct-parse.yy, pt-assign.cc, pt-assign.h, pt-binop.cc,
pt-binop.h, pt-cbinop.cc, pt-cbinop.h, pt-cell.cc, pt-cell.h,
pt-classdef.cc, pt-classdef.h, pt-colon.cc, pt-colon.h, pt-const.h,
pt-eval.cc, pt-eval.h, pt-exp.h, pt-fcn-handle.cc, pt-fcn-handle.h,
pt-id.cc, pt-id.h, pt-idx.cc, pt-idx.h, pt-loop.cc, pt-mat.cc,
pt-mat.h, pt-select.cc, pt-tm-const.cc, pt-unop.cc, and pt-unop.h.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 30 Aug 2019 15:02:14 -0400 |
parents | 00f796120a6d |
children | d171d356767b |
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-colon.cc Wed Aug 28 21:38:34 2019 -0400 +++ b/libinterp/parse-tree/pt-colon.cc Fri Aug 30 15:02:14 2019 -0400 @@ -24,7 +24,10 @@ # include "config.h" #endif +#include "interpreter.h" +#include "parse.h" #include "pt-colon.h" +#include "pt-eval.h" namespace octave { @@ -43,4 +46,60 @@ return new_ce; } + + octave_value tree_colon_expression::evaluate (tree_evaluator& tw, int) + { + octave_value val; + + if (! m_base || ! m_limit) + return val; + + octave_value ov_base = std::move (m_base->evaluate (tw)); + + octave_value ov_limit = std::move (m_limit->evaluate (tw)); + + if (ov_base.isobject () || ov_limit.isobject ()) + { + octave_value_list tmp1; + + if (m_increment) + { + octave_value ov_increment = std::move (m_increment->evaluate (tw)); + + tmp1(2) = ov_limit; + tmp1(1) = ov_increment; + tmp1(0) = ov_base; + } + else + { + tmp1(1) = ov_limit; + tmp1(0) = ov_base; + } + + interpreter& interp = tw.get_interpreter (); + + symbol_table& symtab = interp.get_symbol_table (); + + octave_value fcn = symtab.find_function ("colon", tmp1); + + if (! fcn.is_defined ()) + error ("can not find overloaded colon function"); + + octave_value_list tmp2 = feval (fcn, tmp1, 1); + + val = tmp2 (0); + } + else + { + octave_value ov_increment = 1.0; + + if (m_increment) + ov_increment = std::move (m_increment->evaluate (tw)); + + val = do_colon_op (ov_base, ov_increment, ov_limit, + is_for_cmd_expr ()); + } + + return val; + } }