GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
pt-eval.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2009-2018 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
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License 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 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <cctype>
28 
29 #include <iostream>
30 
31 #include <fstream>
32 #include <typeinfo>
33 
34 #include "cmd-edit.h"
35 #include "oct-env.h"
36 
37 #include "bp-table.h"
38 #include "call-stack.h"
39 #include "defun.h"
40 #include "error.h"
41 #include "errwarn.h"
42 #include "input.h"
43 #include "interpreter-private.h"
44 #include "interpreter.h"
45 #include "ov-fcn-handle.h"
46 #include "ov-usr-fcn.h"
47 #include "ov-re-sparse.h"
48 #include "ov-cx-sparse.h"
49 #include "profiler.h"
50 #include "pt-all.h"
51 #include "pt-eval.h"
52 #include "pt-tm-const.h"
53 #include "symtab.h"
54 #include "unwind-prot.h"
55 #include "utils.h"
56 #include "variables.h"
57 
58 //FIXME: This should be part of tree_evaluator
59 #include "pt-jit.h"
60 
61 namespace octave
62 {
64 
66 
67  bool tree_evaluator::debug_mode = false;
68 
70 
73 
75 
76  // Normal evaluator.
77 
78  void
80  {
84  m_lvalue_list_stack.clear ();
86  }
87 
88  void
90  {
91  // FIXME: should CMD_LIST be limited to a single expression?
92  // I think that is what Matlab does.
93 
94  tree_parameter_list *param_list = anon_fh.parameter_list ();
95  tree_expression *expr = anon_fh.expression ();
96 
97  symbol_scope af_scope = anon_fh.scope ();
98 
100 
101  symbol_scope af_parent_scope;
102  if (anon_fh.has_parent_scope ())
103  af_parent_scope = symtab.current_scope ();
104 
105  symbol_scope new_scope;
106  if (af_scope)
107  new_scope = af_scope.dup ();
108 
109  if (new_scope && af_parent_scope)
110  new_scope.inherit (af_parent_scope);
111 
112  tree_parameter_list *param_list_dup
113  = param_list ? param_list->dup (new_scope) : nullptr;
114 
115  tree_parameter_list *ret_list = nullptr;
116 
117  tree_statement_list *stmt_list = nullptr;
118 
119  if (expr)
120  {
121  tree_expression *expr_dup = expr->dup (new_scope);
122  tree_statement *stmt = new tree_statement (expr_dup, nullptr);
123  stmt_list = new tree_statement_list (stmt);
124  }
125 
127  = new octave_user_function (new_scope, param_list_dup, ret_list,
128  stmt_list);
129 
130  new_scope.set_parent (af_parent_scope);
131 
132  octave_function *curr_fcn = m_call_stack.current ();
133 
134  if (curr_fcn)
135  {
136  // FIXME: maybe it would be better to just stash curr_fcn
137  // instead of individual bits of info about it?
138 
139  af->stash_parent_fcn_name (curr_fcn->name ());
140  af->stash_dir_name (curr_fcn->dir_name ());
141 
142  if (curr_fcn->is_class_method () || curr_fcn->is_class_constructor ())
143  af->stash_dispatch_class (curr_fcn->dispatch_class ());
144  }
145 
147 
148  // FIXME: these should probably come from ANON_FH.
149  // af->stash_fcn_file_name (expr.file_name ());
150  // af->stash_fcn_location (expr.line (), expr.column ());
151 
152  octave_value ov_fcn (af);
153 
154  octave_value fh (octave_fcn_binder::maybe_binder (ov_fcn, this));
155 
156  push_result (fh);
157  }
158 
159  void
161  {
162  panic_impossible ();
163  }
164 
165  void
167  {
169 
170  tree_expression *op_lhs = expr.lhs ();
171  tree_expression *op_rhs = expr.rhs ();
172  octave_value::binary_op etype = expr.op_type ();
173 
175  {
176  if (op_lhs)
177  {
178  octave_value a = evaluate (op_lhs);
179 
180  if (a.ndims () == 2 && a.rows () == 1 && a.columns () == 1)
181  {
182  bool result = false;
183 
184  bool a_true = a.is_true ();
185 
186  if (a_true)
187  {
188  if (etype == octave_value::op_el_or)
189  {
191  push_result (octave_value (true));
192  return;
193  }
194  }
195  else
196  {
197  if (etype == octave_value::op_el_and)
198  {
200  push_result (octave_value (false));
201  return;
202  }
203  }
204 
205  if (op_rhs)
206  {
207  octave_value b = evaluate (op_rhs);
208 
209  result = b.is_true ();
210  }
211 
213  return;
214  }
215  }
216  }
217 
218  if (op_lhs)
219  {
220  octave_value a = evaluate (op_lhs);
221 
222  if (a.is_defined () && op_rhs)
223  {
224  octave_value b = evaluate (op_rhs);
225 
226  if (b.is_defined ())
227  {
229  block (m_profiler, expr);
230 
231  // Note: The profiler does not catch the braindead
232  // short-circuit evaluation code above, but that should be
233  // ok. The evaluation of operands and the operator itself
234  // is entangled and it's not clear where to start/stop
235  // timing the operator to make it reasonable.
236 
238 
239  val = ::do_binary_op (ti, etype, a, b);
240  }
241  }
242  }
243 
244  push_result (val);
245  }
246 
247  void
249  {
251 
252  bool result = false;
253 
254  // This evaluation is not caught by the profiler, since we can't find
255  // a reasonable place where to time. Note that we don't want to
256  // include evaluation of LHS or RHS into the timing, but this is
257  // entangled together with short-circuit evaluation here.
258 
259  tree_expression *op_lhs = expr.lhs ();
260 
261  if (op_lhs)
262  {
263  octave_value a = evaluate (op_lhs);
264 
265  bool a_true = a.is_true ();
266 
267  tree_boolean_expression::type etype = expr.op_type ();
268 
269  if (a_true)
270  {
272  {
273  push_result (octave_value (true));
274  return;
275  }
276  }
277  else
278  {
280  {
281  push_result (octave_value (false));
282  return;
283  }
284  }
285 
286  tree_expression *op_rhs = expr.rhs ();
287 
288  if (op_rhs)
289  {
290  octave_value b = evaluate (op_rhs);
291 
292  result = b.is_true ();
293  }
294 
295  val = octave_value (result);
296  }
297 
298  push_result (val);
299  }
300 
301  void
303  {
305 
306  tree_expression *op_lhs = expr.clhs ();
307 
308  if (op_lhs)
309  {
310  octave_value a = evaluate (op_lhs);
311 
312  tree_expression *op_rhs = expr.crhs ();
313 
314  if (a.is_defined () && op_rhs)
315  {
316  octave_value b = evaluate (op_rhs);
317 
318  if (b.is_defined ())
319  {
321 
323 
324  val = ::do_binary_op (ti, etype, a, b);
325  }
326  }
327  }
328 
329  push_result (val);
330  }
331 
332  void
334  {
335  if (m_echo_state)
336  {
337  size_t line = cmd.line ();
338  echo_code (line);
339  m_echo_file_pos = line + 1;
340  }
341 
342  if (debug_mode)
343  do_breakpoint (cmd.is_breakpoint (true));
344 
345  if (in_loop_command)
347  else
348  error ("break must appear in a loop in the same file as loop command");
349  }
350 
351  void
353  {
355 
356  tree_expression *op_base = expr.base ();
357  tree_expression *op_limit = expr.limit ();
358 
359  if (! op_base || ! op_limit)
360  {
362  return;
363  }
364 
365  octave_value ov_base = evaluate (op_base);
366 
367  octave_value ov_limit = evaluate (op_limit);
368 
369  tree_expression *op_increment = expr.increment ();
370 
371  if (ov_base.isobject () || ov_limit.isobject ())
372  {
373  octave_value_list tmp1;
374 
375  if (op_increment)
376  {
377  octave_value ov_increment = evaluate (op_increment);
378 
379  tmp1(2) = ov_limit;
380  tmp1(1) = ov_increment;
381  tmp1(0) = ov_base;
382  }
383  else
384  {
385  tmp1(1) = ov_limit;
386  tmp1(0) = ov_base;
387  }
388 
390 
391  octave_value fcn = symtab.find_function ("colon", tmp1);
392 
393  if (! fcn.is_defined ())
394  error ("can not find overloaded colon function");
395 
396  octave_value_list tmp2 = feval (fcn, tmp1, 1);
397 
398  val = tmp2 (0);
399  }
400  else
401  {
402  octave_value ov_increment = 1.0;
403 
404  if (op_increment)
405  ov_increment = evaluate (op_increment);
406 
407  val = do_colon_op (ov_base, ov_increment, ov_limit,
408  expr.is_for_cmd_expr ());
409  }
410 
411  push_result (val);
412  }
413 
414  void
416  {
417  if (m_echo_state)
418  {
419  size_t line = cmd.line ();
420  echo_code (line);
421  m_echo_file_pos = line + 1;
422  }
423 
424  if (debug_mode)
425  do_breakpoint (cmd.is_breakpoint (true));
426 
427  if (in_loop_command)
429  }
430 
431  bool
433  {
434  return ! (m_silent_functions && (statement_context == function
435  || statement_context == script));
436  }
437 
438  void
440  {
441  bp_table& bptab = __get_bp_table__ ("tree_evaluator::reset_debug_state");
442 
443  debug_mode = bptab.have_breakpoints () || Vdebugging;
444 
445  dbstep_flag = 0;
446  }
447 
448  Matrix
450  {
451  Matrix retval;
452 
453  const std::list<octave_lvalue> *lvalues = lvalue_list ();
454 
455  if (! lvalues)
456  return retval;
457 
458  octave_idx_type nbh = 0;
459 
460  for (const auto& lval : *lvalues)
461  nbh += lval.is_black_hole ();
462 
463  if (nbh > 0)
464  {
465  retval.resize (1, nbh);
466 
467  octave_idx_type k = 0;
468  octave_idx_type l = 0;
469 
470  for (const auto& lval : *lvalues)
471  {
472  if (lval.is_black_hole ())
473  retval(l++) = k+1;
474 
475  k += lval.numel ();
476  }
477  }
478 
479  return retval;
480  }
481 
482  bool
483  tree_evaluator::isargout (int nargout, int iout) const
484  {
485  const std::list<octave_lvalue> *lvalues = lvalue_list ();
486 
487  if (iout >= std::max (nargout, 1))
488  return false;
489  else if (lvalues)
490  {
491  int k = 0;
492  for (const auto& lval : *lvalues)
493  {
494  if (k == iout)
495  return ! lval.is_black_hole ();
496  k += lval.numel ();
497  if (k > iout)
498  break;
499  }
500 
501  return true;
502  }
503  else
504  return true;
505  }
506 
507  void
508  tree_evaluator::isargout (int nargout, int nout, bool *isargout) const
509  {
510  const std::list<octave_lvalue> *lvalues = lvalue_list ();
511 
512  if (lvalues)
513  {
514  int k = 0;
515  for (const auto& lval : *lvalues)
516  {
517  if (lval.is_black_hole ())
518  isargout[k++] = false;
519  else
520  {
521  int l = std::min (k + lval.numel (),
522  static_cast<octave_idx_type> (nout));
523  while (k < l)
524  isargout[k++] = true;
525  }
526  }
527  }
528  else
529  for (int i = 0; i < nout; i++)
530  isargout[i] = true;
531 
532  for (int i = std::max (nargout, 1); i < nout; i++)
533  isargout[i] = false;
534  }
535 
538  {
539  // Do not allow functions to return null values.
540 
541  tree_identifier *id = elt->ident ();
542 
543  return id ? evaluate (id).storable_value () : octave_value ();
544  }
545 
546  void
548  (tree_parameter_list *param_list, const octave_value_list& args)
549  {
550  int i = -1;
551 
552  for (tree_decl_elt *elt : *param_list)
553  {
554  i++;
555 
556  octave_lvalue ref = elt->lvalue (this);
557 
558  if (i < args.length ())
559  {
560  if (args(i).is_defined () && args(i).is_magic_colon ())
561  {
562  if (! eval_decl_elt (elt))
563  error ("no default value for argument %d", i+1);
564  }
565  else
566  ref.define (args(i));
567  }
568  else
569  eval_decl_elt (elt);
570  }
571  }
572 
573  void
575  {
576  for (tree_decl_elt *elt : *param_list)
577  {
578  octave_lvalue ref = elt->lvalue (this);
579 
581  }
582  }
583 
586  (tree_parameter_list *ret_list, int nargout, const Cell& varargout)
587  {
588  octave_idx_type vlen = varargout.numel ();
589  int len = ret_list->length ();
590 
591  // Special case. Will do a shallow copy.
592  if (len == 0)
593  return varargout;
594  else if (nargout <= len)
595  {
596  symbol_scope scope = get_current_scope ();
597 
599 
601 
602  int i = 0;
603 
604  for (tree_decl_elt *elt : *ret_list)
605  {
606  if (elt->is_defined (context))
607  {
608  octave_value tmp = evaluate (elt);
609  retval(i) = tmp;
610  }
611 
612  i++;
613  }
614 
615  return retval;
616  }
617  else
618  {
619  octave_value_list retval (len + vlen);
620 
621  int i = 0;
622 
623  for (tree_decl_elt *elt : *ret_list)
624  retval(i++) = evaluate (elt);
625 
626  for (octave_idx_type j = 0; j < vlen; j++)
627  retval(i++) = varargout(j);
628 
629  return retval;
630  }
631  }
632 
633  bool
635  {
636  bool retval = false;
637 
638  tree_identifier *id = elt->ident ();
639  tree_expression *expr = elt->expression ();
640 
641  if (id && expr)
642  {
643  octave_lvalue ult = id->lvalue (this);
644 
645  octave_value init_val = evaluate (expr);
646 
647  ult.assign (octave_value::op_asn_eq, init_val);
648 
649  retval = true;
650  }
651 
652  return retval;
653  }
654 
655  bool
657  const octave_value& val)
658  {
659  tree_expression *label = expr->case_label ();
660 
661  octave_value label_value = evaluate (label);
662 
663  if (label_value.is_defined ())
664  {
665  if (label_value.iscell ())
666  {
667  Cell cell (label_value.cell_value ());
668 
669  for (octave_idx_type i = 0; i < cell.rows (); i++)
670  {
671  for (octave_idx_type j = 0; j < cell.columns (); j++)
672  {
673  bool match = val.is_equal (cell(i,j));
674 
675  if (match)
676  return true;
677  }
678  }
679  }
680  else
681  return val.is_equal (label_value);
682  }
683 
684  return false;
685  }
686 
689  {
691 
692  return symtab.current_scope ();
693  }
694 
695  void
697  {
698  if (m_echo_state)
699  {
700  size_t line = cmd.line ();
701  echo_code (line);
702  m_echo_file_pos = line + 1;
703  }
704 
705  if (debug_mode)
706  do_breakpoint (cmd.is_breakpoint (true));
707 
708  tree_decl_init_list *init_list = cmd.initializer_list ();
709 
710  if (init_list)
711  init_list->accept (*this);
712  }
713 
714  void
716  {
717  for (tree_decl_elt *elt : lst)
718  elt->accept (*this);
719  }
720 
721  void
723  {
724  tree_identifier *id = elt.ident ();
725 
726  if (id)
727  {
728  if (elt.is_global ())
729  {
730  std::string name = id->name ();
731 
733 
734  symbol_scope global_scope = symtab.global_scope ();
735 
736  symbol_record global_sr = global_scope.find_symbol (name);
737 
738  // FIXME: Hmmm. Seems like this should happen automatically
739  // for symbols coming from the global scope...
740  global_sr.mark_global ();
741 
742  symbol_scope scope = symtab.current_scope ();
743 
744  if (! scope.is_global (name))
745  {
746  octave_value val = scope.varval (name);
747 
748  bool local_val_is_defined = val.is_defined ();
749 
750  if (local_val_is_defined)
751  {
752  warning_with_id ("Octave:global-local-conflict",
753  "global: '%s' is defined in the current scope.\n",
754  name.c_str ());
755  warning_with_id ("Octave:global-local-conflict",
756  "global: in a future version, global variables must be declared before use.\n");
757 
758  // If the symbol is defined in the local but not the
759  // global scope, then use the local value as the
760  // initial value. This value will also override any
761  // initializer in the global statement.
762  octave_value global_val = global_scope.varval (name);
763 
764  if (global_val.is_defined ())
765  {
766  warning_with_id ("Octave:global-local-conflict",
767  "global: global value overrides existing local value");
768  }
769  else
770  {
771  warning_with_id ("Octave:global-local-conflict",
772  "global: existing local value used to initialize global variable");
773 
774  global_scope.assign (name, val);
775  }
776  }
777 
778  id->link_to_global (global_scope, global_sr);
779  }
780  }
781  else if (elt.is_persistent ())
782  id->mark_persistent ();
783  else
784  error ("declaration list element not global or persistent");
785 
786  octave_lvalue ult = id->lvalue (this);
787 
788  if (ult.is_undefined ())
789  {
790  tree_expression *expr = elt.expression ();
791 
792  octave_value init_val;
793 
794  if (expr)
795  init_val = evaluate (expr);
796  else
797  init_val = Matrix ();
798 
799  ult.assign (octave_value::op_asn_eq, init_val);
800  }
801  }
802  }
803 
804  // Decide if it's time to quit a for or while loop.
805  static inline bool
807  {
808  octave_quit ();
809 
810  // Maybe handle 'continue N' someday...
811 
814 
818 
821 
822  return quit;
823  }
824 
825  void
827  {
828  size_t line = cmd.line ();
829 
830  if (m_echo_state)
831  {
832  echo_code (line);
833  line++;
834  }
835 
836  if (debug_mode)
837  do_breakpoint (cmd.is_breakpoint (true));
838 
839  // FIXME: need to handle PARFOR loops here using cmd.in_parallel ()
840  // and cmd.maxproc_expr ();
841 
843 
845 
846  in_loop_command = true;
847 
848  tree_expression *expr = cmd.control_expr ();
849 
850  octave_value rhs = evaluate (expr);
851 
852 #if defined (HAVE_LLVM)
853  if (tree_jit::execute (cmd, rhs))
854  return;
855 #endif
856 
857  if (rhs.is_undefined ())
858  return;
859 
860  tree_expression *lhs = cmd.left_hand_side ();
861 
862  octave_lvalue ult = lhs->lvalue (this);
863 
864  tree_statement_list *loop_body = cmd.body ();
865 
866  if (rhs.is_range ())
867  {
868  Range rng = rhs.range_value ();
869 
870  octave_idx_type steps = rng.numel ();
871 
872  for (octave_idx_type i = 0; i < steps; i++)
873  {
874  if (m_echo_state)
876 
877  octave_value val (rng.elem (i));
878 
880 
881  if (loop_body)
882  loop_body->accept (*this);
883 
884  if (quit_loop_now ())
885  break;
886  }
887  }
888  else if (rhs.is_scalar_type ())
889  {
890  if (m_echo_state)
892 
893  ult.assign (octave_value::op_asn_eq, rhs);
894 
895  if (loop_body)
896  loop_body->accept (*this);
897 
898  // Maybe decrement break and continue states.
899  quit_loop_now ();
900  }
901  else if (rhs.is_matrix_type () || rhs.iscell () || rhs.is_string ()
902  || rhs.isstruct ())
903  {
904  // A matrix or cell is reshaped to 2 dimensions and iterated by
905  // columns.
906 
907  dim_vector dv = rhs.dims ().redim (2);
908 
909  octave_idx_type nrows = dv(0);
910  octave_idx_type steps = dv(1);
911 
912  octave_value arg = rhs;
913  if (rhs.ndims () > 2)
914  arg = arg.reshape (dv);
915 
916  if (nrows > 0 && steps > 0)
917  {
918  octave_value_list idx;
919  octave_idx_type iidx;
920 
921  // for row vectors, use single index to speed things up.
922  if (nrows == 1)
923  {
924  idx.resize (1);
925  iidx = 0;
926  }
927  else
928  {
929  idx.resize (2);
931  iidx = 1;
932  }
933 
934  for (octave_idx_type i = 1; i <= steps; i++)
935  {
936  if (m_echo_state)
938 
939  // do_index_op expects one-based indices.
940  idx(iidx) = i;
942 
944 
945  if (loop_body)
946  loop_body->accept (*this);
947 
948  if (quit_loop_now ())
949  break;
950  }
951  }
952  else
953  {
954  // Handle empty cases, while still assigning to loop var.
956  }
957  }
958  else
959  error ("invalid type in for loop expression near line %d, column %d",
960  cmd.line (), cmd.column ());
961  }
962 
963  void
965  {
966  size_t line = cmd.line ();
967 
968  if (m_echo_state)
969  {
970  echo_code (line);
971  line++;
972  }
973 
974  if (debug_mode)
975  do_breakpoint (cmd.is_breakpoint (true));
976 
978 
980 
981  in_loop_command = true;
982 
983  tree_expression *expr = cmd.control_expr ();
984 
985  octave_value rhs = evaluate (expr);
986 
987  if (rhs.is_undefined ())
988  return;
989 
990  if (! rhs.isstruct ())
991  error ("in statement 'for [X, Y] = VAL', VAL must be a structure");
992 
993  // Cycle through structure elements. First element of id_list
994  // is set to value and the second is set to the name of the
995  // structure element.
996 
997  tree_argument_list *lhs = cmd.left_hand_side ();
998 
1000 
1001  tree_expression *elt = *p++;
1002 
1003  octave_lvalue val_ref = elt->lvalue (this);
1004 
1005  elt = *p;
1006 
1007  octave_lvalue key_ref = elt->lvalue (this);
1008 
1009  const octave_map tmp_val = rhs.map_value ();
1010 
1011  tree_statement_list *loop_body = cmd.body ();
1012 
1013  string_vector keys = tmp_val.keys ();
1014 
1015  octave_idx_type nel = keys.numel ();
1016 
1017  for (octave_idx_type i = 0; i < nel; i++)
1018  {
1019  if (m_echo_state)
1021 
1022  std::string key = keys[i];
1023 
1024  const Cell val_lst = tmp_val.contents (key);
1025 
1026  octave_idx_type n = val_lst.numel ();
1027 
1028  octave_value val = (n == 1) ? val_lst(0) : octave_value (val_lst);
1029 
1030  val_ref.assign (octave_value::op_asn_eq, val);
1031  key_ref.assign (octave_value::op_asn_eq, key);
1032 
1033  if (loop_body)
1034  loop_body->accept (*this);
1035 
1036  if (quit_loop_now ())
1037  break;
1038  }
1039  }
1040 
1041  void
1043  {
1044  // ??
1045  panic_impossible ();
1046  }
1047 
1048  void
1050  {
1051  // ??
1052  panic_impossible ();
1053  }
1054 
1055  void
1057  {
1058  panic_impossible ();
1059  }
1060 
1061  void
1063  {
1064  panic_impossible ();
1065  }
1066 
1067  void
1069  {
1070  octave_value fcn = cmd.function ();
1071 
1073 
1074  if (f)
1075  {
1076  std::string nm = f->name ();
1077 
1079 
1080  symtab.install_cmdline_function (nm, fcn);
1081 
1082  // Make sure that any variable with the same name as the new
1083  // function is cleared.
1084 
1085  symbol_scope scope = symtab.current_scope ();
1086 
1087  if (scope)
1088  scope.assign (nm);
1089  }
1090  }
1091 
1092  void
1094  {
1096 
1097  symbol_scope scope = get_current_scope ();
1098 
1100 
1101  symbol_record sym = expr.symbol ();
1102 
1103  octave_value val = sym.find (context);
1104 
1105  if (val.is_defined ())
1106  {
1107  // GAGME -- this would be cleaner if we required
1108  // parens to indicate function calls.
1109  //
1110  // If this identifier refers to a function, we need to know
1111  // whether it is indexed so that we can do the same thing
1112  // for 'f' and 'f()'. If the index is present and the function
1113  // object declares it can handle it, return the function object
1114  // and let tree_index_expression::rvalue handle indexing.
1115  // Otherwise, arrange to call the function here, so that we don't
1116  // return the function definition as a value.
1117 
1118  octave_function *fcn = nullptr;
1119 
1120  if (val.is_function ())
1121  fcn = val.function_value (true);
1122 
1123  int nargout = m_nargout_stack.top ();
1124 
1125  if (fcn && ! (expr.is_postfix_indexed ()
1126  && fcn->accepts_postfix_index (expr.postfix_index ())))
1127  {
1128  retval = fcn->call (*this, nargout);
1129  }
1130  else
1131  {
1132  if (expr.print_result () && nargout == 0
1134  {
1135  octave_value_list args = ovl (val);
1136  args.stash_name_tags (string_vector (expr.name ()));
1137  feval ("display", args);
1138  }
1139 
1140  push_result (val);
1141  return;
1142  }
1143  }
1144  else if (sym.is_added_static ())
1145  expr.static_workspace_error ();
1146  else
1147  expr.eval_undefined_error ();
1148 
1149  push_result (retval);
1150  }
1151 
1152  void
1154  {
1155  panic_impossible ();
1156  }
1157 
1158  void
1160  {
1161  if (m_echo_state)
1162  {
1163  size_t line = cmd.line ();
1164  echo_code (line);
1165  m_echo_file_pos = line + 1;
1166  }
1167 
1168  tree_if_command_list *lst = cmd.cmd_list ();
1169 
1170  if (lst)
1171  lst->accept (*this);
1172  }
1173 
1174  void
1176  {
1177  for (tree_if_clause *tic : lst)
1178  {
1179  tree_expression *expr = tic->condition ();
1180 
1181  if (statement_context == function || statement_context == script)
1182  m_call_stack.set_location (tic->line (), tic->column ());
1183 
1184  if (debug_mode && ! tic->is_else_clause ())
1185  do_breakpoint (tic->is_breakpoint (true));
1186 
1187  if (tic->is_else_clause () || is_logically_true (expr, "if"))
1188  {
1189  tree_statement_list *stmt_lst = tic->commands ();
1190 
1191  if (stmt_lst)
1192  stmt_lst->accept (*this);
1193 
1194  break;
1195  }
1196  }
1197  }
1198 
1199  // Final step of processing an indexing error. Add the name of the
1200  // variable being indexed, if any, then issue an error. (Will this also
1201  // be needed by pt-lvalue, which calls subsref?)
1202 
1203  static void
1205  const octave::tree_expression *expr)
1206  {
1207  std::string extra_message;
1208 
1209  // FIXME: make this a member function for direct access to symbol
1210  // table and scope?
1211 
1212  octave::symbol_scope scope
1213  = octave::__require_current_scope__ ("final_index_error");
1214 
1216 
1217  if (expr->is_identifier ()
1218  && dynamic_cast<const octave::tree_identifier *> (expr)->is_variable (context))
1219  {
1220  std::string var = expr->name ();
1221 
1222  e.set_var (var);
1223 
1224  octave::symbol_table& symtab =
1225  octave::__get_symbol_table__ ("final_index_error");
1226 
1227  octave_value fcn = symtab.find_function (var);
1228 
1229  if (fcn.is_function ())
1230  {
1232 
1233  if (fp && fp->name () == var)
1234  extra_message = " (note: variable '" + var + "' shadows function)";
1235  }
1236  }
1237 
1238  std::string msg = e.message () + extra_message;
1239 
1240  error_with_id (e.err_id (), msg.c_str ());
1241  }
1242 
1243  // Unlike Matlab, which does not allow the result of a function call
1244  // or array indexing expression to be further indexed, Octave attempts
1245  // to handle arbitrary index expressions. For example, Octave allows
1246  // expressions like
1247  //
1248  // svd (rand (10))(1:5)
1249  //
1250  // Although octave_value objects may contain function objects, no
1251  // indexing operation or function call is supposed to return them
1252  // directly. Instead, the language is supposed to only allow function
1253  // objects to be stored as function handles (named or anonymous) or as
1254  // inline functions. The only place a function object should appear
1255  // directly is if the symbol stored in a tree_identifier object
1256  // resolves to a function. This means that the only place we need to
1257  // look for functions is in the first element of the index
1258  // expression.
1259  //
1260  // Steps:
1261  //
1262  // * Obtain the initial value from the expression component of the
1263  // tree_index_expression object. If it is a tree_identifier object
1264  // indexed by '(args)' and the identifier is not a variable, then
1265  // peform a function call. Use the (optional) arguments to perform
1266  // the function lookup so we choose the correct function or class
1267  // method to call. Otherwise, evaluate the first expression
1268  // without any additional arguments.
1269  //
1270  // * Iterate over the remaining elements of the index expression and
1271  // call the octave_value::subsref method. If indexing a class or
1272  // classdef object, build up a list of indices for a call to the
1273  // subsref method for the object. Otherwise, use the result of
1274  // each temporary evaluation for the next index element.
1275  //
1276  // * If not indexing a class or classdef object and any partial
1277  // expression evaluation produces a class or classdef object, then
1278  // build up a complete argument list from that point on for a final
1279  // subsref call for that object.
1280  //
1281  // Multiple partial evaluations may be required. For example,
1282  // given a class or classdef object X, then for the expression
1283  //
1284  // x.a{end}(2:end).b
1285  //
1286  // we must evaluate x.a to obtain the size for the first {end}
1287  // expression, then we must evaluate x.a{end} to obtain the size
1288  // for the second (2:end) expression. Finally, the complete
1289  // expression may be evaluated.
1290  //
1291  // If X is a cell array in the above expression, and none of the
1292  // intermediate evaluations produces a class or classdef object,
1293  // then the evaluation is performed as the following series of
1294  // steps
1295  //
1296  // tmp = x.a
1297  // tmp = tmp{end}
1298  // tmp = tmp(2:end)
1299  // result = tmp.b
1300  //
1301  // If any of the partial evaluations produces a class or classdef
1302  // object, then the subsref method for that object is called as
1303  // described above. For example, suppose x.a produces a classdef
1304  // object. Then the evaluation is performed as the following
1305  // series of steps
1306  //
1307  // base_expr = tmp = x.a
1308  // tmp = base_expr{end}
1309  // base_expr{end}(2:end).b
1310  //
1311  // In the last two steps, the partial value computed in the
1312  // previous step is used to determine the value of END.
1313 
1314  void
1316  {
1318 
1319  int nargout = m_nargout_stack.top ();
1320 
1321  std::string type = idx_expr.type_tags ();
1322  std::list<tree_argument_list *> args = idx_expr.arg_lists ();
1323  std::list<string_vector> arg_nm = idx_expr.arg_names ();
1324  std::list<tree_expression *> dyn_field = idx_expr.dyn_fields ();
1325 
1326  assert (! args.empty ());
1327 
1328  std::list<tree_argument_list *>::iterator p_args = args.begin ();
1329  std::list<string_vector>::iterator p_arg_nm = arg_nm.begin ();
1330  std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin ();
1331 
1332  int n = args.size ();
1333  int beg = 0;
1334 
1335  octave_value base_expr_val;
1336 
1337  tree_expression *expr = idx_expr.expression ();
1338 
1339  if (expr->is_identifier () && type[beg] == '(')
1340  {
1341  tree_identifier *id = dynamic_cast<tree_identifier *> (expr);
1342 
1343  symbol_scope scope = get_current_scope ();
1344 
1346 
1347  if (! id->is_variable (context))
1348  {
1349  octave_value_list first_args;
1350 
1351  tree_argument_list *al = *p_args;
1352 
1353  if (al && al->length () > 0)
1354  {
1355  // Function calls inside an argument list can't have
1356  // ignored output arguments.
1357 
1359 
1360  m_lvalue_list_stack.push (nullptr);
1361 
1363  &value_stack<const std::list<octave_lvalue>*>::pop);
1364 
1365  string_vector anm = *p_arg_nm;
1366  first_args = al->convert_to_const_vector (this);
1367  first_args.stash_name_tags (anm);
1368  }
1369 
1370  octave_function *fcn = nullptr;
1371 
1372  octave_value val = id->do_lookup (context, first_args);
1373 
1374  if (val.is_function ())
1375  fcn = val.function_value (true);
1376 
1377  if (fcn)
1378  {
1379  try
1380  {
1381  retval = fcn->call (*this, nargout, first_args);
1382  }
1383  catch (index_exception& e)
1384  {
1385  final_index_error (e, expr);
1386  }
1387 
1388  beg++;
1389  p_args++;
1390  p_arg_nm++;
1391  p_dyn_field++;
1392 
1393  if (n > beg)
1394  {
1395  // More indices to follow. Silently ignore
1396  // extra output values.
1397 
1398  if (retval.length () == 0)
1399  error ("indexing undefined value");
1400  else
1401  base_expr_val = retval(0);
1402  }
1403  else
1404  {
1405  // No more indices, so we are done.
1406 
1407  push_result (retval);
1408  return;
1409  }
1410  }
1411  }
1412  }
1413 
1414  if (base_expr_val.is_undefined ())
1415  base_expr_val = evaluate (expr);
1416 
1417  // If we are indexing an object or looking at something like
1418  //
1419  // classname.static_function (args, ...);
1420  //
1421  // then we'll just build a complete index list for one big subsref
1422  // call. If the expression we are indexing is a classname then
1423  // base_expr_val will be an octave_classdef_meta object. If we have
1424  // files in a +packagename folder, they will also be an
1425  // octave_classdef_meta object, but we don't want to index them.
1426 
1427  bool indexing_object = (base_expr_val.isobject ()
1428  || base_expr_val.isjava ()
1429  || (base_expr_val.is_classdef_meta ()
1430  && ! base_expr_val.is_package ()));
1431 
1432  std::list<octave_value_list> idx;
1433 
1434  octave_value partial_expr_val = base_expr_val;
1435 
1436  for (int i = beg; i < n; i++)
1437  {
1438  if (i > beg)
1439  {
1440  tree_argument_list *al = *p_args;
1441 
1442  if (! indexing_object || (al && al->has_magic_end ()))
1443  {
1444  // Evaluate what we have so far to find the value to
1445  // pass to the END function.
1446 
1447  try
1448  {
1449  // Silently ignore extra output values.
1450 
1451  octave_value_list tmp_list
1452  = base_expr_val.subsref (type.substr (beg, i-beg),
1453  idx, nargout);
1454 
1455  partial_expr_val
1456  = tmp_list.length () ? tmp_list(0) : octave_value ();
1457 
1458  if (! indexing_object)
1459  {
1460  base_expr_val = partial_expr_val;
1461 
1462  if (partial_expr_val.is_cs_list ())
1464 
1465  retval = partial_expr_val;
1466 
1467  beg = i;
1468  idx.clear ();
1469 
1470  if (partial_expr_val.isobject ()
1471  || partial_expr_val.isjava ()
1472  || (partial_expr_val.is_classdef_meta ()
1473  && ! partial_expr_val.is_package ()))
1474  {
1475  // Found an object, so now we'll build up
1476  // complete index list for one big subsref
1477  // call from this point on.
1478 
1479  // FIXME: is is also possible to have a
1480  // static method call buried somewhere in
1481  // the depths of a complex indexing
1482  // expression so that we would also need to
1483  // check for an octave_classdef_meta object
1484  // here?
1485 
1486  indexing_object = true;
1487  }
1488  }
1489  }
1490  catch (index_exception& e)
1491  {
1492  final_index_error (e, expr);
1493  }
1494  }
1495  }
1496 
1497  switch (type[i])
1498  {
1499  case '(':
1500  idx.push_back (make_value_list (*p_args, *p_arg_nm, &partial_expr_val));
1501  break;
1502 
1503  case '{':
1504  idx.push_back (make_value_list (*p_args, *p_arg_nm, &partial_expr_val));
1505  break;
1506 
1507  case '.':
1508  idx.push_back (octave_value
1509  (idx_expr.get_struct_index (this, p_arg_nm, p_dyn_field)));
1510  break;
1511 
1512  default:
1513  panic_impossible ();
1514  }
1515 
1516  p_args++;
1517  p_arg_nm++;
1518  p_dyn_field++;
1519  }
1520 
1521 
1522  // If ! idx.empty () that means we still have stuff to index otherwise
1523  // they would have been dealt with and idx would have been emptied.
1524  if (! idx.empty ())
1525  {
1526  // This is for +package and other classdef_meta objects
1527  if (! base_expr_val.is_function ()
1528  || base_expr_val.is_classdef_meta ())
1529  {
1530  try
1531  {
1532  retval = base_expr_val.subsref (type.substr (beg, n-beg),
1533  idx, nargout);
1534  beg = n;
1535  idx.clear ();
1536  }
1537  catch (octave::index_exception& e)
1538  {
1539  final_index_error (e, expr);
1540  }
1541  }
1542  else
1543  {
1544  // FIXME: we want this to only be a superclass constructor
1545  // call Should we actually make a check for this or are all
1546  // other types of calls already dealt with?
1547 
1548  octave_function *fcn = base_expr_val.function_value ();
1549 
1550  if (fcn)
1551  {
1552  try
1553  {
1554  retval = fcn->call (*this, nargout, idx);
1555  }
1556  catch (octave::index_exception& e)
1557  {
1558  final_index_error (e, expr);
1559  }
1560  }
1561  }
1562  }
1563 
1564  // FIXME: when can the following happen? In what case does indexing
1565  // result in a value that is a function? Classdef method calls?
1566  // Something else?
1567 
1568  octave_value val = (retval.length () ? retval(0) : octave_value ());
1569 
1570  if (val.is_function ())
1571  {
1572  octave_function *fcn = val.function_value (true);
1573 
1574  if (fcn)
1575  {
1576  octave_value_list final_args;
1577 
1578  if (! idx.empty ())
1579  {
1580  if (n - beg != 1)
1581  error ("unexpected extra index at end of expression");
1582 
1583  if (type[beg] != '(')
1584  error ("invalid index type '%c' for function call",
1585  type[beg]);
1586 
1587  final_args = idx.front ();
1588  }
1589 
1590  retval = fcn->call (*this, nargout, final_args);
1591  }
1592  }
1593 
1594  push_result (retval);
1595  }
1596 
1597  void
1599  {
1600  octave_value retval = Matrix ();
1601 
1602  bool all_strings_p = false;
1603  bool all_sq_strings_p = false;
1604  bool all_dq_strings_p = false;
1605  bool all_empty_p = false;
1606  bool all_real_p = false;
1607  bool any_sparse_p = false;
1608  bool any_class_p = false;
1609  bool frc_str_conv = false;
1610 
1611  tm_const tmp (expr, this);
1612 
1613  if (tmp && ! tmp.empty ())
1614  {
1615  dim_vector dv = tmp.dims ();
1616  all_strings_p = tmp.all_strings_p ();
1617  all_sq_strings_p = tmp.all_sq_strings_p ();
1618  all_dq_strings_p = tmp.all_dq_strings_p ();
1619  all_empty_p = tmp.all_empty_p ();
1620  all_real_p = tmp.all_real_p ();
1621  any_sparse_p = tmp.any_sparse_p ();
1622  any_class_p = tmp.any_class_p ();
1623  frc_str_conv = tmp.some_strings_p ();
1624 
1625  // Try to speed up the common cases.
1626 
1627  std::string result_type = tmp.class_name ();
1628 
1629  if (any_class_p)
1630  {
1632  }
1633  else if (result_type == "double")
1634  {
1635  if (any_sparse_p)
1636  {
1637  if (all_real_p)
1638  retval = do_single_type_concat<SparseMatrix> (dv, tmp);
1639  else
1640  retval = do_single_type_concat<SparseComplexMatrix> (dv, tmp);
1641  }
1642  else
1643  {
1644  if (all_real_p)
1645  retval = do_single_type_concat<NDArray> (dv, tmp);
1646  else
1647  retval = do_single_type_concat<ComplexNDArray> (dv, tmp);
1648  }
1649  }
1650  else if (result_type == "single")
1651  {
1652  if (all_real_p)
1653  retval = do_single_type_concat<FloatNDArray> (dv, tmp);
1654  else
1655  retval = do_single_type_concat<FloatComplexNDArray> (dv, tmp);
1656  }
1657  else if (result_type == "char")
1658  {
1659  char type = (all_dq_strings_p ? '"' : '\'');
1660 
1661  if (! all_strings_p)
1662  warn_implicit_conversion ("Octave:num-to-str",
1663  "numeric", result_type);
1664  else
1665  maybe_warn_string_concat (all_dq_strings_p, all_sq_strings_p);
1666 
1668 
1669  single_type_concat<charNDArray> (result, tmp);
1670 
1672  }
1673  else if (result_type == "logical")
1674  {
1675  if (any_sparse_p)
1676  retval = do_single_type_concat<SparseBoolMatrix> (dv, tmp);
1677  else
1678  retval = do_single_type_concat<boolNDArray> (dv, tmp);
1679  }
1680  else if (result_type == "int8")
1681  retval = do_single_type_concat<int8NDArray> (dv, tmp);
1682  else if (result_type == "int16")
1683  retval = do_single_type_concat<int16NDArray> (dv, tmp);
1684  else if (result_type == "int32")
1685  retval = do_single_type_concat<int32NDArray> (dv, tmp);
1686  else if (result_type == "int64")
1687  retval = do_single_type_concat<int64NDArray> (dv, tmp);
1688  else if (result_type == "uint8")
1689  retval = do_single_type_concat<uint8NDArray> (dv, tmp);
1690  else if (result_type == "uint16")
1691  retval = do_single_type_concat<uint16NDArray> (dv, tmp);
1692  else if (result_type == "uint32")
1693  retval = do_single_type_concat<uint32NDArray> (dv, tmp);
1694  else if (result_type == "uint64")
1695  retval = do_single_type_concat<uint64NDArray> (dv, tmp);
1696  else if (result_type == "cell")
1697  retval = do_single_type_concat<Cell> (dv, tmp);
1698  else if (result_type == "struct")
1700  else
1701  {
1702  // The line below might seem crazy, since we take a copy of
1703  // the first argument, resize it to be empty and then resize
1704  // it to be full. This is done since it means that there is
1705  // no recopying of data, as would happen if we used a single
1706  // resize. It should be noted that resize operation is also
1707  // significantly slower than the do_cat_op function, so it
1708  // makes sense to have an empty matrix and copy all data.
1709  //
1710  // We might also start with a empty octave_value using
1711  //
1712  // ctmp = octave::type_info::lookup_type
1713  // (tmp.begin() -> begin() -> type_name());
1714  //
1715  // and then directly resize. However, for some types there
1716  // might be some additional setup needed, and so this should
1717  // be avoided.
1718 
1719  octave_value ctmp;
1720 
1721  // Find the first non-empty object
1722 
1723  if (any_sparse_p)
1724  {
1725  // Start with sparse matrix to avoid issues memory issues
1726  // with things like [ones(1,4),sprandn(1e8,4,1e-4)]
1727  if (all_real_p)
1728  ctmp = octave_sparse_matrix ().resize (dv);
1729  else
1731  }
1732  else
1733  {
1734  for (tm_row_const& row : tmp)
1735  {
1736  octave_quit ();
1737 
1738  for (auto& elt : row)
1739  {
1740  octave_quit ();
1741 
1742  ctmp = elt;
1743 
1744  if (! ctmp.all_zero_dims ())
1745  goto found_non_empty;
1746  }
1747  }
1748 
1749  ctmp = (*(tmp.begin () -> begin ()));
1750 
1751  found_non_empty:
1752 
1753  if (! all_empty_p)
1754  ctmp = ctmp.resize (dim_vector (0,0)).resize (dv);
1755  }
1756 
1757  // Now, extract the values from the individual elements and
1758  // insert them in the result matrix.
1759 
1761 
1762  int dv_len = dv.ndims ();
1763  octave_idx_type ntmp = (dv_len > 1 ? dv_len : 2);
1764  Array<octave_idx_type> ra_idx (dim_vector (ntmp, 1), 0);
1765 
1766  for (tm_row_const& row : tmp)
1767  {
1768  octave_quit ();
1769 
1770  for (auto& elt : row)
1771  {
1772  octave_quit ();
1773 
1774  if (elt.isempty ())
1775  continue;
1776 
1777  ctmp = do_cat_op (ti, ctmp, elt, ra_idx);
1778 
1779  ra_idx (1) += elt.columns ();
1780  }
1781 
1782  ra_idx (0) += row.rows ();
1783  ra_idx (1) = 0;
1784  }
1785 
1786  retval = ctmp;
1787 
1788  if (frc_str_conv && ! retval.is_string ())
1790  }
1791  }
1792 
1793  push_result (retval);
1794  }
1795 
1796  void
1798  {
1800 
1801  // Function calls inside an argument list can't have ignored
1802  // output arguments.
1803 
1805 
1806  m_lvalue_list_stack.push (nullptr);
1807 
1809  &value_stack<const std::list<octave_lvalue>*>::pop);
1810 
1811  octave_idx_type nr = expr.length ();
1812  octave_idx_type nc = -1;
1813 
1814  Cell val;
1815 
1816  octave_idx_type i = 0;
1817 
1818  for (tree_argument_list *elt : expr)
1819  {
1820  octave_value_list row = elt->convert_to_const_vector (this);
1821 
1822  if (nr == 1)
1823  // Optimize the single row case.
1824  val = row.cell_value ();
1825  else if (nc < 0)
1826  {
1827  nc = row.length ();
1828 
1829  val = Cell (nr, nc);
1830  }
1831  else
1832  {
1833  octave_idx_type this_nc = row.length ();
1834 
1835  if (this_nc != nc)
1836  {
1837  if (this_nc == 0)
1838  continue; // blank line
1839  else
1840  error ("number of columns must match");
1841  }
1842  }
1843 
1844  for (octave_idx_type j = 0; j < nc; j++)
1845  val(i,j) = row(j);
1846 
1847  i++;
1848  }
1849 
1850  if (i < nr)
1851  val.resize (dim_vector (i, nc)); // there were blank rows
1852 
1853  retval = val;
1854 
1855  push_result (retval);
1856  }
1857 
1858  void
1860  {
1862 
1863  tree_expression *rhs = expr.right_hand_side ();
1864 
1865  if (rhs)
1866  {
1868 
1869  tree_argument_list *lhs = expr.left_hand_side ();
1870 
1871  std::list<octave_lvalue> lvalue_list = make_lvalue_list (lhs);
1872 
1874 
1876  &value_stack<const std::list<octave_lvalue>*>::pop);
1877 
1878  octave_idx_type n_out = 0;
1879 
1880  for (const auto& lval : lvalue_list)
1881  n_out += lval.numel ();
1882 
1883  // The following trick is used to keep rhs_val constant.
1884  const octave_value_list rhs_val1 = evaluate_n (rhs, n_out);
1885  const octave_value_list rhs_val = (rhs_val1.length () == 1
1886  && rhs_val1(0).is_cs_list ()
1887  ? rhs_val1(0).list_value ()
1888  : rhs_val1);
1889 
1890  octave_idx_type k = 0;
1891 
1892  octave_idx_type n = rhs_val.length ();
1893 
1894  // To avoid copying per elements and possible optimizations, we
1895  // postpone joining the final values.
1896  std::list<octave_value_list> retval_list;
1897 
1898  tree_argument_list::iterator q = lhs->begin ();
1899 
1900  for (octave_lvalue ult : lvalue_list)
1901  {
1902  tree_expression *lhs_elt = *q++;
1903 
1904  octave_idx_type nel = ult.numel ();
1905 
1906  if (nel != 1)
1907  {
1908  // Huge kluge so that wrapper scripts with lines like
1909  //
1910  // [varargout{1:nargout}] = fcn (args);
1911  //
1912  // Will work the same as calling fcn directly when nargout
1913  // is 0 and fcn produces more than one output even when
1914  // nargout is 0. This only works if varargout has not yet
1915  // been defined. See also bug #43813.
1916 
1917  if (lvalue_list.size () == 1 && nel == 0 && n > 0
1918  && ! ult.is_black_hole () && ult.is_undefined ()
1919  && ult.index_type () == "{" && ult.index_is_empty ())
1920  {
1921  // Convert undefined lvalue with empty index to a cell
1922  // array with a single value and indexed by 1 to
1923  // handle a single output.
1924 
1925  nel = 1;
1926 
1927  ult.define (Cell (1, 1));
1928 
1929  ult.clear_index ();
1930  std::list<octave_value_list> idx;
1931  idx.push_back (octave_value_list (octave_value (1)));
1932  ult.set_index ("{", idx);
1933  }
1934 
1935  if (k + nel > n)
1936  error ("some elements undefined in return list");
1937 
1938  // This element of the return list expects a
1939  // comma-separated list of values. Slicing avoids
1940  // copying.
1941 
1942  octave_value_list ovl = rhs_val.slice (k, nel);
1943 
1944  ult.assign (octave_value::op_asn_eq, octave_value (ovl));
1945 
1946  retval_list.push_back (ovl);
1947 
1948  k += nel;
1949  }
1950  else
1951  {
1952  if (k < n)
1953  {
1954  if (ult.is_black_hole ())
1955  {
1956  k++;
1957  continue;
1958  }
1959  else
1960  {
1961  octave_value tmp = rhs_val(k);
1962 
1963  if (tmp.is_undefined ())
1964  error ("element number %d undefined in return list",
1965  k+1);
1966 
1967  ult.assign (octave_value::op_asn_eq, tmp);
1968 
1969  retval_list.push_back (tmp);
1970 
1971  k++;
1972  }
1973  }
1974  else
1975  {
1976  // This can happen for a function like
1977  //
1978  // function varargout = f ()
1979  // varargout{1} = nargout;
1980  // endfunction
1981  //
1982  // called with
1983  //
1984  // [a, ~] = f ();
1985  //
1986  // Then the list of of RHS values will contain one
1987  // element but we are iterating over the list of all
1988  // RHS values. We shouldn't complain that a value we
1989  // don't need is missing from the list.
1990 
1991  if (! ult.is_black_hole ())
1992  error ("element number %d undefined in return list", k+1);
1993 
1994  k++;
1995  continue;
1996  }
1997  }
1998 
1999  if (expr.print_result () && statement_printing_enabled ())
2000  {
2001  // We clear any index here so that we can get
2002  // the new value of the referenced object below,
2003  // instead of the indexed value (which should be
2004  // the same as the right hand side value).
2005 
2006  ult.clear_index ();
2007 
2008  octave_value lhs_val = ult.value ();
2009 
2010  octave_value_list args = ovl (lhs_val);
2011  args.stash_name_tags (string_vector (lhs_elt->name ()));
2012  feval ("display", args);
2013  }
2014  }
2015 
2016  // Concatenate return values.
2017  val = retval_list;
2018  }
2019 
2020  push_result (val);
2021  }
2022 
2023  void
2025  {
2026  if (m_echo_state)
2027  {
2028  size_t line = cmd.line ();
2029  echo_code (line);
2030  m_echo_file_pos = line + 1;
2031  }
2032 
2033  if (debug_mode && cmd.is_end_of_fcn_or_script ())
2034  do_breakpoint (cmd.is_breakpoint (true), true);
2035  }
2036 
2037  void
2039  {
2040  int nargout = m_nargout_stack.top ();
2041 
2042  if (nargout > 1)
2043  error ("invalid number of output arguments for constant expression");
2044 
2045  push_result (expr.value ());
2046  }
2047 
2048  void
2050  {
2051  std::string nm = expr.name ();
2052 
2054 
2055  push_result (fh);
2056  }
2057 
2058  void
2060  {
2062 
2063  octave_value fcn = expr.function ();
2064 
2065  octave_value_list args = expr.arguments ();
2066 
2067  int nargout = m_nargout_stack.top ();
2068 
2069  retval = feval (fcn.function_value (), args, nargout);
2070 
2071  if (retval.length () == 1 && retval(0).is_function ())
2072  {
2073  // The return object is a function. We may need to re-index it
2074  // using the same logic as for identifier. This is primarily
2075  // used for superclass references in classdef.
2076 
2077  octave_value val = retval(0);
2078  octave_function *f = val.function_value (true);
2079 
2080  if (f && ! (expr.is_postfix_indexed ()
2081  && f->accepts_postfix_index (expr.postfix_index ())))
2082  {
2083  retval = f->call (*this, nargout);
2084  }
2085  }
2086 
2087  push_result (retval);
2088  }
2089 
2090  void
2092  {
2093  panic_impossible ();
2094  }
2095 
2096  void
2098  {
2099  octave_value val;
2100 
2101  tree_expression *op = expr.operand ();
2102 
2103  if (op)
2104  {
2105  octave_value::unary_op etype = expr.op_type ();
2106 
2107  if (etype == octave_value::op_incr || etype == octave_value::op_decr)
2108  {
2109  octave_lvalue ref = op->lvalue (this);
2110 
2111  val = ref.value ();
2112 
2114 
2115  ref.do_unary_op (etype);
2116  }
2117  else
2118  {
2119  octave_value op_val = evaluate (op);
2120 
2121  if (op_val.is_defined ())
2122  {
2124  block (m_profiler, expr);
2125 
2127 
2128  val = ::do_unary_op (ti, etype, op_val);
2129  }
2130  }
2131  }
2132 
2133  push_result (val);
2134  }
2135 
2136  void
2138  {
2139  octave_value val;
2140 
2141  tree_expression *op = expr.operand ();
2142 
2143  if (op)
2144  {
2145  octave_value::unary_op etype = expr.op_type ();
2146 
2147  if (etype == octave_value::op_incr || etype == octave_value::op_decr)
2148  {
2149  octave_lvalue op_ref = op->lvalue (this);
2150 
2152 
2153  op_ref.do_unary_op (etype);
2154 
2155  val = op_ref.value ();
2156  }
2157  else
2158  {
2159  octave_value op_val = evaluate (op);
2160 
2161  if (op_val.is_defined ())
2162  {
2164  block (m_profiler, expr);
2165 
2166  // Attempt to do the operation in-place if it is unshared
2167  // (a temporary expression).
2168  if (op_val.get_count () == 1)
2169  val = op_val.do_non_const_unary_op (etype);
2170  else
2171  {
2173 
2174  val = ::do_unary_op (ti, etype, op_val);
2175  }
2176  }
2177  }
2178  }
2179 
2180  push_result (val);
2181  }
2182 
2183  void
2185  {
2186  if (m_echo_state)
2187  {
2188  size_t line = cmd.line ();
2189  echo_code (line);
2190  m_echo_file_pos = line + 1;
2191  }
2192 
2193  if (debug_mode)
2194  do_breakpoint (cmd.is_breakpoint (true));
2195 
2196  // Act like dbcont.
2197 
2199  {
2200  Vdebugging = false;
2201 
2202  reset_debug_state ();
2203  }
2204  else if (statement_context == function || statement_context == script
2205  || in_loop_command)
2207  }
2208 
2209  void
2211  {
2212  panic_impossible ();
2213  }
2214 
2215  void
2217  {
2218  octave_value val;
2219 
2220  tree_expression *rhs = expr.right_hand_side ();
2221 
2222  if (rhs)
2223  {
2224  octave_value rhs_val = evaluate (rhs);
2225 
2226  if (rhs_val.is_undefined ())
2227  error ("value on right hand side of assignment is undefined");
2228 
2229  if (rhs_val.is_cs_list ())
2230  {
2231  const octave_value_list lst = rhs_val.list_value ();
2232 
2233  if (lst.empty ())
2234  error ("invalid number of elements on RHS of assignment");
2235 
2236  rhs_val = lst(0);
2237  }
2238 
2239  tree_expression *lhs = expr.left_hand_side ();
2240 
2241  try
2242  {
2244 
2245  octave_lvalue ult = lhs->lvalue (this);
2246 
2247  std::list<octave_lvalue> lvalue_list;
2248  lvalue_list.push_back (ult);
2249 
2251 
2253  &value_stack<const std::list<octave_lvalue>*>::pop);
2254 
2255  if (ult.numel () != 1)
2257 
2258  octave_value::assign_op etype = expr.op_type ();
2259 
2260  ult.assign (etype, rhs_val);
2261 
2262  if (etype == octave_value::op_asn_eq)
2263  val = rhs_val;
2264  else
2265  val = ult.value ();
2266 
2267  if (expr.print_result () && statement_printing_enabled ())
2268  {
2269  // We clear any index here so that we can
2270  // get the new value of the referenced
2271  // object below, instead of the indexed
2272  // value (which should be the same as the
2273  // right hand side value).
2274 
2275  ult.clear_index ();
2276 
2277  octave_value lhs_val = ult.value ();
2278 
2279  octave_value_list args = ovl (lhs_val);
2280  args.stash_name_tags (string_vector (lhs->name ()));
2281  feval ("display", args);
2282  }
2283  }
2284  catch (index_exception& e)
2285  {
2286  e.set_var (lhs->name ());
2287  std::string msg = e.message ();
2288  error_with_id (e.err_id (), msg.c_str ());
2289  }
2290  }
2291 
2292  push_result (val);
2293  }
2294 
2295  void
2297  {
2298  tree_command *cmd = stmt.command ();
2299  tree_expression *expr = stmt.expression ();
2300 
2301  if (cmd || expr)
2302  {
2303  if (statement_context == function || statement_context == script)
2304  {
2305  // Skip commands issued at a debug> prompt to avoid disturbing
2306  // the state of the program we are debugging.
2307 
2308  if (Vtrack_line_num)
2309  m_call_stack.set_location (stmt.line (), stmt.column ());
2310  }
2311 
2312  try
2313  {
2314  if (cmd)
2315  cmd->accept (*this);
2316  else
2317  {
2318  if (m_echo_state)
2319  {
2320  size_t line = stmt.line ();
2321  echo_code (line);
2322  m_echo_file_pos = line + 1;
2323  }
2324 
2325  if (debug_mode)
2326  do_breakpoint (expr->is_breakpoint (true));
2327 
2328  // FIXME: maybe all of this should be packaged in
2329  // one virtual function that returns a flag saying whether
2330  // or not the expression will take care of binding ans and
2331  // printing the result.
2332 
2333  // FIXME: it seems that we should just have to
2334  // evaluate the expression and that should take care of
2335  // everything, binding ans as necessary?
2336 
2337  octave_value tmp_result = evaluate (expr, 0);
2338 
2339  if (tmp_result.is_defined ())
2340  {
2341  bool do_bind_ans = false;
2342 
2343  if (expr->is_identifier ())
2344  {
2345  symbol_scope scope = get_current_scope ();
2346 
2348  = scope.current_context ();
2349 
2350  tree_identifier *id
2351  = dynamic_cast<tree_identifier *> (expr);
2352 
2353  do_bind_ans = (! id->is_variable (context));
2354  }
2355  else
2356  do_bind_ans = (! expr->is_assignment_expression ());
2357 
2358  if (do_bind_ans)
2359  bind_ans (tmp_result, expr->print_result ()
2361  }
2362  }
2363  }
2364  catch (const std::bad_alloc&)
2365  {
2366  // FIXME: We want to use error_with_id here so that give users
2367  // control over this error message but error_with_id will
2368  // require some memory allocations. Is there anything we can
2369  // do to make those more likely to succeed?
2370 
2371  error_with_id ("Octave:bad-alloc",
2372  "out of memory or dimension too large for Octave's index type");
2373  }
2374  catch (const octave::interrupt_exception&)
2375  {
2376  // If we are debugging, then continue with next statement.
2377  // Otherwise, jump out of here.
2378 
2379  if (debug_mode)
2381  else
2382  throw;
2383  }
2384  }
2385  }
2386 
2387  void
2389  {
2390  // FIXME: commented out along with else clause below.
2391  // static octave_value_list empty_list;
2392 
2394 
2395  if (p != lst.end ())
2396  {
2397  while (true)
2398  {
2399  tree_statement *elt = *p++;
2400 
2401  if (! elt)
2402  error ("invalid statement found in statement list!");
2403 
2404  octave_quit ();
2405 
2406  elt->accept (*this);
2407 
2410  break;
2411 
2413  break;
2414 
2415  if (p == lst.end ())
2416  break;
2417  else
2418  {
2419  // Clear previous values before next statement is
2420  // evaluated so that we aren't holding an extra
2421  // reference to a value that may be used next. For
2422  // example, in code like this:
2423  //
2424  // X = rand (N); # refcount for X should be 1
2425  // # after this statement
2426  //
2427  // X(idx) = val; # no extra copy of X should be
2428  // # needed, but we will be faked
2429  // # out if retval is not cleared
2430  // # between statements here
2431 
2432  // result_values = empty_list;
2433  }
2434  }
2435  }
2436  }
2437 
2438  void
2440  {
2441  panic_impossible ();
2442  }
2443 
2444  void
2446  {
2447  panic_impossible ();
2448  }
2449 
2450  void
2452  {
2453  if (m_echo_state)
2454  {
2455  size_t line = cmd.line ();
2456  echo_code (line);
2457  m_echo_file_pos = line + 1;
2458  }
2459 
2460  if (debug_mode)
2461  do_breakpoint (cmd.is_breakpoint (true));
2462 
2463  tree_expression *expr = cmd.switch_value ();
2464 
2465  if (! expr)
2466  error ("missing value in switch command near line %d, column %d",
2467  cmd.line (), cmd.column ());
2468 
2469  octave_value val = evaluate (expr);
2470 
2471  tree_switch_case_list *lst = cmd.case_list ();
2472 
2473  if (lst)
2474  {
2475  for (tree_switch_case *t : *lst)
2476  {
2477  if (t->is_default_case () || switch_case_label_matches (t, val))
2478  {
2479  tree_statement_list *stmt_lst = t->commands ();
2480 
2481  if (stmt_lst)
2482  stmt_lst->accept (*this);
2483 
2484  break;
2485  }
2486  }
2487  }
2488  }
2489 
2490  void
2492  {
2493  if (m_echo_state)
2494  {
2495  size_t line = cmd.line ();
2496  echo_code (line);
2497  m_echo_file_pos = line + 1;
2498  }
2499 
2500  bool execution_error = false;
2501 
2502  {
2503  // unwind frame before catch block
2505 
2509 
2511  Vdebug_on_error = false;
2512  Vdebug_on_warning = false;
2513 
2514  // The catch code is *not* added to unwind_protect stack;
2515  // it doesn't need to be run on interrupts.
2516 
2517  tree_statement_list *try_code = cmd.body ();
2518 
2519  if (try_code)
2520  {
2521  try
2522  {
2523  in_try_catch++;
2524  try_code->accept (*this);
2525  in_try_catch--;
2526  }
2527  catch (const execution_exception&)
2528  {
2530 
2531  in_try_catch--; // must be restored before "catch" block
2532  execution_error = true;
2533  }
2534  }
2535  // Unwind to let the user print any messages from
2536  // errors that occurred in the body of the try_catch statement,
2537  // or throw further errors.
2538  }
2539 
2540  if (execution_error)
2541  {
2542  tree_statement_list *catch_code = cmd.cleanup ();
2543  if (catch_code)
2544  {
2545  tree_identifier *expr_id = cmd.identifier ();
2546 
2547  if (expr_id)
2548  {
2549  octave_lvalue ult = expr_id->lvalue (this);
2550 
2552 
2553  err.assign ("message", last_error_message ());
2554  err.assign ("identifier", last_error_id ());
2555  err.assign ("stack", last_error_stack ());
2556 
2558  }
2559 
2560  // perform actual "catch" block
2561  if (catch_code)
2562  catch_code->accept (*this);
2563  }
2564  }
2565  }
2566 
2567  void
2569  {
2571 
2574 
2575  // We want to preserve the last location info for possible
2576  // backtracking.
2577 
2582 
2583  // Similarly, if we have seen a return or break statement, allow all
2584  // the cleanup code to run before returning or handling the break.
2585  // We don't have to worry about continue statements because they can
2586  // only occur in loops.
2587 
2590 
2593 
2594  try
2595  {
2596  if (list)
2597  list->accept (*this);
2598  }
2599  catch (const execution_exception&)
2600  {
2602 
2604  frame.discard (2);
2605  else
2606  frame.run (2);
2607 
2608  frame.discard (2);
2609 
2610  throw;
2611  }
2612 
2613  // The unwind_protects are popped off the stack in the reverse of
2614  // the order they are pushed on.
2615 
2616  // FIXME: these statements say that if we see a break or
2617  // return statement in the cleanup block, that we want to use the
2618  // new value of the breaking or returning flag instead of restoring
2619  // the previous value. Is that the right thing to do? I think so.
2620  // Consider the case of
2621  //
2622  // function foo ()
2623  // unwind_protect
2624  // fprintf (stderr, "1: this should always be executed\n");
2625  // break;
2626  // fprintf (stderr, "1: this should never be executed\n");
2627  // unwind_protect_cleanup
2628  // fprintf (stderr, "2: this should always be executed\n");
2629  // return;
2630  // fprintf (stderr, "2: this should never be executed\n");
2631  // end_unwind_protect
2632  // endfunction
2633  //
2634  // If we reset the value of the breaking flag, both the returning
2635  // flag and the breaking flag will be set, and we shouldn't have
2636  // both. So, use the most recent one. If there is no return or
2637  // break in the cleanup block, the values should be reset to
2638  // whatever they were when the cleanup block was entered.
2639 
2641  frame.discard (2);
2642  else
2643  frame.run (2);
2644  }
2645 
2646  void
2648  {
2649  if (m_echo_state)
2650  {
2651  size_t line = cmd.line ();
2652  echo_code (line);
2653  m_echo_file_pos = line + 1;
2654  }
2655 
2656  tree_statement_list *cleanup_code = cmd.cleanup ();
2657 
2658  tree_statement_list *unwind_protect_code = cmd.body ();
2659 
2660  if (unwind_protect_code)
2661  {
2662  try
2663  {
2664  unwind_protect_code->accept (*this);
2665  }
2666  catch (const execution_exception&)
2667  {
2668  // FIXME: Maybe we should be able to temporarily set the
2669  // interpreter's exception handling state to something "safe"
2670  // while the cleanup block runs instead of just resetting it
2671  // here?
2673 
2674  // Run the cleanup code on exceptions, so that it is run even
2675  // in case of interrupt or out-of-memory.
2676  do_unwind_protect_cleanup_code (cleanup_code);
2677 
2678  // If an error occurs inside the cleanup code, a new
2679  // exception will be thrown instead of the original.
2680  throw;
2681  }
2682  catch (const interrupt_exception&)
2683  {
2684  // The comments above apply here as well.
2686  do_unwind_protect_cleanup_code (cleanup_code);
2687  throw;
2688  }
2689 
2690  // Also execute the unwind_protect_cleanump code if the
2691  // unwind_protect block runs without error.
2692  do_unwind_protect_cleanup_code (cleanup_code);
2693  }
2694  }
2695 
2696  void
2698  {
2699  size_t line = cmd.line ();
2700 
2701  if (m_echo_state)
2702  {
2703  echo_code (line);
2704  line++;
2705  }
2706 
2707 #if defined (HAVE_LLVM)
2708  if (tree_jit::execute (cmd))
2709  return;
2710 #endif
2711 
2713 
2715 
2716  in_loop_command = true;
2717 
2718  tree_expression *expr = cmd.condition ();
2719 
2720  if (! expr)
2721  panic_impossible ();
2722 
2723  for (;;)
2724  {
2725  if (m_echo_state)
2727 
2728  if (debug_mode)
2729  do_breakpoint (cmd.is_breakpoint (true));
2730 
2731  if (is_logically_true (expr, "while"))
2732  {
2733  tree_statement_list *loop_body = cmd.body ();
2734 
2735  if (loop_body)
2736  loop_body->accept (*this);
2737 
2738  if (quit_loop_now ())
2739  break;
2740  }
2741  else
2742  break;
2743  }
2744  }
2745 
2746  void
2748  {
2749  size_t line = cmd.line ();
2750 
2751  if (m_echo_state)
2752  {
2753  echo_code (line);
2754  line++;
2755  }
2756 
2757 #if defined (HAVE_LLVM)
2758  if (tree_jit::execute (cmd))
2759  return;
2760 #endif
2761 
2763 
2765 
2766  in_loop_command = true;
2767 
2768  tree_expression *expr = cmd.condition ();
2769  int until_line = cmd.line ();
2770  int until_column = cmd.column ();
2771 
2772  if (! expr)
2773  panic_impossible ();
2774 
2775  for (;;)
2776  {
2777  if (m_echo_state)
2779 
2780  tree_statement_list *loop_body = cmd.body ();
2781 
2782  if (loop_body)
2783  loop_body->accept (*this);
2784 
2785  if (quit_loop_now ())
2786  break;
2787 
2788  if (debug_mode)
2789  do_breakpoint (cmd.is_breakpoint (true));
2790 
2791  m_call_stack.set_location (until_line, until_column);
2792 
2793  if (is_logically_true (expr, "do-until"))
2794  break;
2795  }
2796  }
2797 
2798  void tree_evaluator::bind_ans (const octave_value& val, bool print)
2799  {
2800  static std::string ans = "ans";
2801 
2802  if (val.is_defined ())
2803  {
2804  if (val.is_cs_list ())
2805  {
2806  octave_value_list lst = val.list_value ();
2807 
2808  for (octave_idx_type i = 0; i < lst.length (); i++)
2809  bind_ans (lst(i), print);
2810  }
2811  else
2812  {
2813  symbol_scope scope = get_current_scope ();
2814 
2815  scope.force_assign (ans, val);
2816 
2817  if (print)
2818  {
2819  octave_value_list args = ovl (val);
2820  args.stash_name_tags (string_vector (ans));
2821  feval ("display", args);
2822  }
2823  }
2824  }
2825  }
2826 
2827  void
2829  {
2830  do_breakpoint (stmt.is_breakpoint (true), stmt.is_end_of_fcn_or_script ());
2831  }
2832 
2833  void
2834  tree_evaluator::do_breakpoint (bool is_breakpoint,
2835  bool is_end_of_fcn_or_script) const
2836  {
2837  bool break_on_this_statement = false;
2838 
2840  {
2841  break_on_this_statement = true;
2842 
2844 
2846  }
2847  else if (is_breakpoint)
2848  {
2849  break_on_this_statement = true;
2850 
2851  dbstep_flag = 0;
2852 
2854  }
2855  else if (dbstep_flag > 0)
2856  {
2858  {
2859  if (dbstep_flag == 1 || is_end_of_fcn_or_script)
2860  {
2861  // We get here if we are doing a "dbstep" or a "dbstep N" and the
2862  // count has reached 1 so that we must stop and return to debug
2863  // prompt. Alternatively, "dbstep N" has been used but the end
2864  // of the frame has been reached so we stop at the last line and
2865  // return to prompt.
2866 
2867  break_on_this_statement = true;
2868 
2869  dbstep_flag = 0;
2870  }
2871  else
2872  {
2873  // Executing "dbstep N". Decrease N by one and continue.
2874 
2875  dbstep_flag--;
2876  }
2877 
2878  }
2879  else if (dbstep_flag == 1
2881  {
2882  // We stepped out from the end of a function.
2883 
2885 
2886  break_on_this_statement = true;
2887 
2888  dbstep_flag = 0;
2889  }
2890  }
2891  else if (dbstep_flag == -1)
2892  {
2893  // We get here if we are doing a "dbstep in".
2894 
2895  break_on_this_statement = true;
2896 
2897  dbstep_flag = 0;
2898 
2900  }
2901  else if (dbstep_flag == -2)
2902  {
2903  // We get here if we are doing a "dbstep out". Check for end of
2904  // function and whether the current frame is the same as the
2905  // cached value because we want to step out from the frame where
2906  // "dbstep out" was evaluated, not from any functions called from
2907  // that frame.
2908 
2909  if (is_end_of_fcn_or_script
2911  dbstep_flag = -1;
2912  }
2913 
2914  if (break_on_this_statement)
2915  do_keyboard ();
2916 
2917  }
2918 
2919  // ARGS is currently unused, but since the do_keyboard function in
2920  // input.cc accepts an argument list, we preserve it here so that the
2921  // interface won't have to change if we decide to use it in the future.
2922 
2923  octave_value
2925  {
2926  return ::do_keyboard (args);
2927  }
2928 
2929  bool
2931  const char *warn_for)
2932  {
2933  bool expr_value = false;
2934 
2935  octave_value t1 = evaluate (expr);
2936 
2937  if (t1.is_defined ())
2938  return t1.is_true ();
2939  else
2940  error ("%s: undefined value used in conditional expression", warn_for);
2941 
2942  return expr_value;
2943  }
2944 
2947  const string_vector& arg_nm,
2948  const octave_value *object, bool rvalue)
2949  {
2951 
2952  if (args)
2953  {
2954  // Function calls inside an argument list can't have ignored
2955  // output arguments.
2956 
2958 
2959  m_lvalue_list_stack.push (nullptr);
2960 
2962  &value_stack<const std::list<octave_lvalue>*>::pop);
2963 
2964  if (rvalue && object && args->has_magic_end ()
2965  && object->is_undefined ())
2967 
2968  retval = args->convert_to_const_vector (this, object);
2969  }
2970 
2971  octave_idx_type n = retval.length ();
2972 
2973  if (n > 0)
2974  retval.stash_name_tags (arg_nm);
2975 
2976  return retval;
2977  }
2978 
2979  std::list<octave_lvalue>
2981  {
2982  std::list<octave_lvalue> retval;
2983 
2984  for (tree_expression *elt : *lhs)
2985  retval.push_back (elt->lvalue (this));
2986 
2987  return retval;
2988  }
2989 
2990  octave_value
2992  int nargout)
2993  {
2995  "max_recursion_depth", 0);
2996  }
2997 
2998  octave_value
3000  {
3002  "silent_functions");
3003  }
3004 
3005  octave_value
3007  {
3009  "string_fill_char");
3010  }
3011 
3012  void
3014  const std::string& file_name,
3015  size_t pos)
3016  {
3018 
3019  set_echo_state (type, file_name, pos);
3020  }
3021 
3022  void
3024  size_t pos)
3025  {
3026  m_echo_state = echo_this_file (file_name, type);
3027  m_echo_file_name = file_name;
3028  m_echo_file_pos = pos;
3029  }
3030 
3031  void
3033  {
3034  octave_function *caller = m_call_stack.caller ();
3035 
3036  if (caller && caller->is_user_code ())
3037  {
3038  octave_user_code *fcn = dynamic_cast<octave_user_code *> (caller);
3039 
3041 
3042  std::string file_name = fcn->fcn_file_name ();
3043 
3044  size_t pos = m_call_stack.current_line ();
3045 
3046  set_echo_state (type, file_name, pos);
3047  }
3048  }
3049 
3050  void
3052  {
3054  m_echo_state);
3055 
3058 
3060  m_echo_file_pos);
3061  }
3062 
3064  {
3065  // This function is expected to be called from ECHO, which would be
3066  // the top of the call stack. If the caller of ECHO is a
3067  // user-defined fucntion or script, then set up unwind-protect
3068  // elements to restore echo state.
3069 
3070  octave_function *caller = m_call_stack.caller ();
3071 
3072  if (caller && caller->is_user_code ())
3073  {
3074  octave_user_code *fcn = dynamic_cast<octave_user_code *> (caller);
3075 
3076  unwind_protect *frame = fcn->unwind_protect_frame ();
3077 
3078  if (frame)
3079  {
3081  return true;
3082  }
3083  }
3084 
3085  return false;
3086  }
3087 
3088 
3089  octave_value
3091  {
3092  bool cleanup_pushed = maybe_push_echo_state_cleanup ();
3093 
3094  string_vector argv = args.make_argv ();
3095 
3096  switch (args.length ())
3097  {
3098  case 0:
3099  if ((m_echo & ECHO_SCRIPTS) || (m_echo & ECHO_FUNCTIONS))
3100  {
3101  m_echo = ECHO_OFF;
3102  m_echo_files.clear ();
3103  }
3104  else
3105  m_echo = ECHO_SCRIPTS;
3106  break;
3107 
3108  case 1:
3109  {
3110  std::string arg0 = argv[0];
3111 
3112  if (arg0 == "on")
3113  m_echo = ECHO_SCRIPTS;
3114  else if (arg0 == "off")
3115  m_echo = ECHO_OFF;
3116  else
3117  {
3120 
3121  if (file.empty ())
3122  error ("echo: no such file %s", arg0.c_str ());
3123 
3124  if (m_echo & ECHO_ALL)
3125  {
3126  // Echo is enabled for all functions, so turn it off
3127  // for this one.
3128 
3129  m_echo_files[file] = false;
3130  }
3131  else
3132  {
3133  // Echo may be enabled for specific functions.
3134 
3135  auto p = m_echo_files.find (file);
3136 
3137  if (p == m_echo_files.end ())
3138  {
3139  // Not this one, so enable it.
3140 
3142  m_echo_files[file] = true;
3143  }
3144  else
3145  {
3146  // This one is already in the list. Flip the
3147  // status for it.
3148 
3149  p->second = ! p->second;
3150  }
3151  }
3152  }
3153  }
3154  break;
3155 
3156  case 2:
3157  {
3158  std::string arg0 = argv[0];
3159  std::string arg1 = argv[1];
3160 
3161  if (arg1 == "on" || arg1 == "off")
3162  std::swap (arg0, arg1);
3163 
3164  if (arg0 == "on")
3165  {
3166  if (arg1 == "all")
3167  {
3169  m_echo_files.clear ();
3170  }
3171  else
3172  {
3175 
3176  if (file.empty ())
3177  error ("echo: no such file %s", arg1.c_str ());
3178 
3180  m_echo_files[file] = true;
3181  }
3182  }
3183  else if (arg0 == "off")
3184  {
3185  if (arg1 == "all")
3186  {
3187  m_echo = ECHO_OFF;
3188  m_echo_files.clear ();
3189  }
3190  else
3191  {
3194 
3195  if (file.empty ())
3196  error ("echo: no such file %s", arg1.c_str ());
3197 
3198  m_echo_files[file] = false;
3199  }
3200  }
3201  else
3202  print_usage ();
3203  }
3204  break;
3205 
3206  default:
3207  print_usage ();
3208  break;
3209  }
3210 
3211  if (cleanup_pushed)
3213 
3214  return octave_value ();
3215  }
3216 
3217  octave_value
3219  {
3220  return set_internal_variable (m_PS4, args, nargout, "PS4");
3221  }
3222 
3224  {
3225  if ((type & m_echo) == ECHO_SCRIPTS)
3226  {
3227  // Asking about scripts and echo is enabled for them.
3228  return true;
3229  }
3230 
3231  if ((type & m_echo) == ECHO_FUNCTIONS)
3232  {
3233  // Asking about functions and echo is enabled for functions.
3234  // Now, which ones?
3235 
3236  auto p = m_echo_files.find (file);
3237 
3238  if (m_echo & ECHO_ALL)
3239  {
3240  // Return true ulness echo was turned off for a specific
3241  // file.
3242 
3243  return (p == m_echo_files.end () || p->second);
3244  }
3245  else
3246  {
3247  // Return true if echo is specifically enabled for this file.
3248 
3249  return p != m_echo_files.end () && p->second;
3250  }
3251  }
3252 
3253  return false;
3254  }
3255 
3257  {
3259 
3260  octave_function *curr_fcn = m_call_stack.current ();
3261 
3262  if (curr_fcn && curr_fcn->is_user_code ())
3263  {
3264  octave_user_code *code = dynamic_cast<octave_user_code *> (curr_fcn);
3265 
3266  size_t num_lines = line - m_echo_file_pos + 1;
3267 
3268  std::deque<std::string> lines
3269  = code->get_code_lines (m_echo_file_pos, num_lines);
3270 
3271  for (auto& elt : lines)
3272  octave_stdout << prefix << elt << std::endl;
3273  }
3274  }
3275 }
3276 
3277 DEFMETHOD (max_recursion_depth, interp, args, nargout,
3278  doc: /* -*- texinfo -*-
3279 @deftypefn {} {@var{val} =} max_recursion_depth ()
3280 @deftypefnx {} {@var{old_val} =} max_recursion_depth (@var{new_val})
3281 @deftypefnx {} {} max_recursion_depth (@var{new_val}, "local")
3282 Query or set the internal limit on the number of times a function may
3283 be called recursively.
3284 
3285 If the limit is exceeded, an error message is printed and control returns to
3286 the top level.
3287 
3288 When called from inside a function with the @qcode{"local"} option, the
3289 variable is changed locally for the function and any subroutines it calls.
3290 The original variable value is restored when exiting the function.
3291 
3292 @seealso{max_stack_depth}
3293 @end deftypefn */)
3294 {
3295  octave::tree_evaluator& tw = interp.get_evaluator ();
3296 
3297  return tw.max_recursion_depth (args, nargout);
3298 }
3299 
3300 /*
3301 %!test
3302 %! orig_val = max_recursion_depth ();
3303 %! old_val = max_recursion_depth (2*orig_val);
3304 %! assert (orig_val, old_val);
3305 %! assert (max_recursion_depth (), 2*orig_val);
3306 %! max_recursion_depth (orig_val);
3307 %! assert (max_recursion_depth (), orig_val);
3308 
3309 %!error (max_recursion_depth (1, 2))
3310 */
3311 
3312 DEFMETHOD (silent_functions, interp, args, nargout,
3313  doc: /* -*- texinfo -*-
3314 @deftypefn {} {@var{val} =} silent_functions ()
3315 @deftypefnx {} {@var{old_val} =} silent_functions (@var{new_val})
3316 @deftypefnx {} {} silent_functions (@var{new_val}, "local")
3317 Query or set the internal variable that controls whether internal
3318 output from a function is suppressed.
3319 
3320 If this option is disabled, Octave will display the results produced by
3321 evaluating expressions within a function body that are not terminated with
3322 a semicolon.
3323 
3324 When called from inside a function with the @qcode{"local"} option, the
3325 variable is changed locally for the function and any subroutines it calls.
3326 The original variable value is restored when exiting the function.
3327 @end deftypefn */)
3328 {
3329  octave::tree_evaluator& tw = interp.get_evaluator ();
3330 
3331  return tw.silent_functions (args, nargout);
3332 }
3333 
3334 /*
3335 %!test
3336 %! orig_val = silent_functions ();
3337 %! old_val = silent_functions (! orig_val);
3338 %! assert (orig_val, old_val);
3339 %! assert (silent_functions (), ! orig_val);
3340 %! silent_functions (orig_val);
3341 %! assert (silent_functions (), orig_val);
3342 
3343 %!error (silent_functions (1, 2))
3344 */
3345 
3346 DEFMETHOD (string_fill_char, interp, args, nargout,
3347  doc: /* -*- texinfo -*-
3348 @deftypefn {} {@var{val} =} string_fill_char ()
3349 @deftypefnx {} {@var{old_val} =} string_fill_char (@var{new_val})
3350 @deftypefnx {} {} string_fill_char (@var{new_val}, "local")
3351 Query or set the internal variable used to pad all rows of a character
3352 matrix to the same length.
3353 
3354 The value must be a single character and the default is @qcode{" "} (a
3355 single space). For example:
3356 
3357 @example
3358 @group
3359 string_fill_char ("X");
3360 [ "these"; "are"; "strings" ]
3361  @result{} "theseXX"
3362  "areXXXX"
3363  "strings"
3364 @end group
3365 @end example
3366 
3367 When called from inside a function with the @qcode{"local"} option, the
3368 variable is changed locally for the function and any subroutines it calls.
3369 The original variable value is restored when exiting the function.
3370 @end deftypefn */)
3371 {
3372  octave::tree_evaluator& tw = interp.get_evaluator ();
3373 
3374  return tw.string_fill_char (args, nargout);
3375 }
3376 
3377 /*
3378 ## string_fill_char() function call must be outside of %!test block
3379 ## due to the way a %!test block is wrapped inside a function
3380 %!shared orig_val, old_val
3381 %! orig_val = string_fill_char ();
3382 %! old_val = string_fill_char ("X");
3383 %!test
3384 %! assert (orig_val, old_val);
3385 %! assert (string_fill_char (), "X");
3386 %! assert (["these"; "are"; "strings"], ["theseXX"; "areXXXX"; "strings"]);
3387 %! string_fill_char (orig_val);
3388 %! assert (string_fill_char (), orig_val);
3389 
3390 %!assert ( [ [], {1} ], {1} )
3391 
3392 %!error (string_fill_char (1, 2))
3393 */
3394 
3395 DEFMETHOD (PS4, interp, args, nargout,
3396  doc: /* -*- texinfo -*-
3397 @deftypefn {} {@var{val} =} PS4 ()
3398 @deftypefnx {} {@var{old_val} =} PS4 (@var{new_val})
3399 @deftypefnx {} {} PS4 (@var{new_val}, "local")
3400 Query or set the character string used to prefix output produced
3401 when echoing commands is enabled.
3402 
3403 The default value is @qcode{"+ "}.
3404 @xref{Diary and Echo Commands}, for a description of echoing commands.
3405 
3406 When called from inside a function with the @qcode{"local"} option, the
3407 variable is changed locally for the function and any subroutines it calls.
3408 The original variable value is restored when exiting the function.
3409 @seealso{echo, PS1, PS2}
3410 @end deftypefn */)
3411 {
3412  octave::tree_evaluator& tw = interp.get_evaluator ();
3413 
3414  return tw.PS4 (args, nargout);
3415 }
3416 
3417 DEFMETHOD (echo, interp, args, nargout,
3418  doc: /* -*- texinfo -*-
3419 @deftypefn {} {} echo
3420 @deftypefnx {} {} echo on
3421 @deftypefnx {} {} echo off
3422 @deftypefnx {} {} echo on all
3423 @deftypefnx {} {} echo off all
3424 @deftypefnx {} {} echo @var{function} on
3425 @deftypefnx {} {} echo @var{function} off
3426 Control whether commands are displayed as they are executed.
3427 
3428 Valid options are:
3429 
3430 @table @code
3431 @item on
3432 Enable echoing of commands as they are executed in script files.
3433 
3434 @item off
3435 Disable echoing of commands as they are executed in script files.
3436 
3437 @item on all
3438 Enable echoing of commands as they are executed in script files and
3439 functions.
3440 
3441 @item off all
3442 Disable echoing of commands as they are executed in script files and
3443 functions.
3444 
3445 @item @var{function} on
3446 Enable echoing of commands as they are executed in the named function.
3447 
3448 @item @var{function} off
3449 Disable echoing of commands as they are executed in the named function.
3450 @end table
3451 
3452 @noindent
3453 With no arguments, @code{echo} toggles the current echo state.
3454 
3455 @seealso{PS4}
3456 @end deftypefn */)
3457 {
3458  octave::tree_evaluator& tw = interp.get_evaluator ();
3459 
3460  return tw.echo (args, nargout);
3461 }
3462 
3463 /*
3464 %!error echo ([])
3465 %!error echo (0)
3466 %!error echo ("")
3467 %!error echo ("Octave")
3468 %!error echo ("off", "invalid")
3469 %!error echo ("on", "invalid")
3470 %!error echo ("on", "all", "all")
3471 */
uint32_t id
Definition: graphics.cc:12193
bool Vdebug_on_error
Definition: error.cc:62
OCTINTERP_API octave_value_list feval(const std::string &name, const octave_value_list &args=octave_value_list(), int nargout=0)
virtual int line(void) const
Definition: pt.h:56
tree_expression * right_hand_side(void)
Definition: pt-assign.h:78
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:816
virtual std::string name(void) const
Definition: pt-exp.h:102
static void final_index_error(octave::index_exception &e, const octave::tree_expression *expr)
Definition: pt-eval.cc:1204
symbol_record symbol(void) const
Definition: pt-id.h:137
void set_echo_state(int type, const std::string &file_name, size_t pos)
Definition: pt-eval.cc:3023
octave_value find_function(const std::string &name, const octave_value_list &args=octave_value_list(), bool local_funcs=true)
Definition: symtab.cc:412
void visit_funcall(tree_funcall &)
Definition: pt-eval.cc:2059
void do_unary_op(octave_value::unary_op op)
Definition: oct-lvalue.cc:70
void undefine_parameter_list(tree_parameter_list *param_list)
Definition: pt-eval.cc:574
virtual bool is_user_function(void) const
Definition: ov-base.h:473
std::string PS4(void) const
Definition: pt-eval.h:412
octave_value::unary_op op_type(void) const
Definition: pt-unop.h:74
Definition: Cell.h:37
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:124
void visit_argument_list(tree_argument_list &)
Definition: pt-eval.cc:160
tree_parameter_list * dup(symbol_scope &scope) const
Definition: pt-misc.cc:80
bool maybe_push_echo_state_cleanup(void)
Definition: pt-eval.cc:3063
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:135
bool Vdebug_on_warning
Definition: error.cc:70
type op_type(void) const
Definition: pt-binop.h:172
Range range_value(void) const
Definition: ov.h:970
assign_op
Definition: ov.h:136
virtual octave_value_list call(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())=0
int line(void) const
Definition: pt-stmt.cc:107
octave_value::binary_op op_type(void) const
Definition: pt-binop.h:97
void mark_global(void)
Definition: symrec.h:677
void assign(const std::string &name, const octave_value &value, bool force_add)
Definition: symscope.h:707
virtual octave_value do_keyboard(const octave_value_list &args=octave_value_list()) const
Definition: pt-eval.cc:2924
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition: ov.h:418
bool is_persistent(void) const
Definition: pt-decl.h:96
static std::string decode_prompt_string(const std::string &s)
Definition: cmd-edit.cc:1267
void reset(void)
Definition: pt-eval.cc:79
void eval_undefined_error(void)
Definition: pt-id.cc:51
octave_value_list arguments(void) const
Definition: pt-funcall.h:73
tree_statement_list * cleanup(void)
Definition: pt-except.h:138
const octave_base_value const Array< octave_idx_type > & ra_idx
virtual int column(void) const
Definition: pt.h:58
void set_location(int l, int c)
Definition: call-stack.h:191
string_vector keys(void) const
Definition: oct-map.h:342
The value of lines which begin with a space character are not saved in the history list A value of all commands are saved on the history list
Definition: oct-hist.cc:734
bool is_end_of_fcn_or_script(void) const
Definition: pt-stmt.cc:140
void push_echo_state(unwind_protect &frame, int type, const std::string &file_name, size_t pos=1)
Definition: pt-eval.cc:3013
void inherit(const symbol_scope &donor_scope)
Definition: symscope.h:679
static void recover_from_exception(void)
void visit_parameter_list(tree_parameter_list &)
Definition: pt-eval.cc:2091
void visit_octave_user_script(octave_user_script &)
Definition: pt-eval.cc:1042
static int dbstep_flag
Definition: pt-eval.h:247
void visit_octave_user_function_header(octave_user_function &)
Definition: pt-eval.cc:1056
bool is_eligible_for_braindead_shortcircuit(void) const
Definition: pt-binop.h:102
symbol_scope global_scope(void)
Definition: symtab.h:74
octave_map map_value(void) const
bool is_undefined(void) const
Definition: oct-lvalue.h:64
OCTINTERP_API void print_usage(void)
Definition: defun.cc:54
void define(const octave_value &v)
Definition: oct-lvalue.h:71
virtual bool is_user_code(void) const
Definition: ov-base.h:475
tree_expression * base(void)
Definition: pt-colon.h:88
octave_value_list slice(octave_idx_type offset, octave_idx_type len, bool tags=false) const
Definition: ovl.h:114
void set_echo_file_pos(const size_t &file_pos)
Definition: pt-eval.h:475
void visit_if_command_list(tree_if_command_list &)
Definition: pt-eval.cc:1175
bool isargout(int nargout, int iout) const
Definition: pt-eval.cc:483
octave_value find(context_id context, const octave_value_list &args=octave_value_list()) const
Definition: symrec.h:581
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
static bool in_loop_command
Definition: pt-eval.h:268
interpreter & m_interpreter
Definition: pt-eval.h:484
symbol_scope scope(void) const
value_stack< const std::list< octave_lvalue > * > m_lvalue_list_stack
Definition: pt-eval.h:490
OCTINTERP_API std::string fcn_file_in_path(const std::string &)
symbol_scope current_scope(void)
Definition: symtab.h:77
symbol_record find_symbol(const std::string &name)
Definition: symscope.h:674
void visit_decl_command(tree_decl_command &)
Definition: pt-eval.cc:696
bool empty(void) const
Definition: ovl.h:98
void push_result(const octave_value &val)
Definition: pt-eval.h:282
bool all_zero_dims(void) const
Definition: ov.h:480
bool eval_decl_elt(tree_decl_elt *elt)
Definition: pt-eval.cc:634
for large enough k
Definition: lu.cc:617
bool is_cs_list(void) const
Definition: ov.h:622
symbol_scope dup(void) const
Definition: symscope.h:658
void do_breakpoint(tree_statement &stmt) const
Definition: pt-eval.cc:2828
Definition: Range.h:33
bool is_true(void) const
Definition: ov.h:739
binary_op
Definition: ov.h:94
virtual void accept(tree_walker &tw)=0
size_t length(void) const
Definition: base-list.h:50
void error(const char *fmt,...)
Definition: error.cc:578
static void reset_debug_state(void)
Definition: pt-eval.cc:439
void accept(tree_walker &tw)
Definition: pt-select.h:113
void visit_try_catch_command(tree_try_catch_command &)
Definition: pt-eval.cc:2491
void visit_boolean_expression(tree_boolean_expression &)
Definition: pt-eval.cc:248
octave_lvalue lvalue(tree_evaluator *)
Definition: pt-id.cc:68
tree_decl_init_list * initializer_list(void)
Definition: pt-decl.h:211
void visit_constant(tree_constant &)
Definition: pt-eval.cc:2038
tree_statement_list * body(void)
Definition: pt-loop.h:87
bool is_breakpoint(bool check_active=false) const
Definition: pt.h:90
void visit_simple_assignment(tree_simple_assignment &)
Definition: pt-eval.cc:2216
bool is_breakpoint(bool check_valid=false) const
Definition: pt-stmt.cc:92
std::list< tree_expression * >::iterator iterator
Definition: base-list.h:40
bool is_defined(void) const
Definition: ov.h:523
static llvm::LLVMContext & context
Definition: jit-typeinfo.cc:79
void visit_prefix_expression(tree_prefix_expression &)
Definition: pt-eval.cc:2137
call_stack m_call_stack
Definition: pt-eval.h:494
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
Definition: ov-usr-fcn.cc:997
octave_value function(void)
Definition: pt-cmd.h:116
std::list< string_vector > arg_names(void)
Definition: pt-idx.h:88
bool statement_printing_enabled(void)
Definition: pt-eval.cc:432
char postfix_index(void) const
Definition: pt-exp.h:93
int ndims(void) const
Definition: ov.h:478
octave_value value(void) const
Definition: oct-lvalue.cc:81
octave_value_list make_value_list(tree_argument_list *args, const string_vector &arg_nm, const octave_value *object, bool rvalue=true)
Definition: pt-eval.cc:2946
type_info & get_type_info(void)
Definition: interpreter.h:174
void visit_statement(tree_statement &)
Definition: pt-eval.cc:2296
bool isobject(void) const
Definition: ov.h:608
void stash_dir_name(const std::string &dir)
Definition: ov-fcn.h:146
i e
Definition: data.cc:2591
var
Definition: givens.cc:88
octave_value echo(const octave_value_list &args, int nargout)
Definition: pt-eval.cc:3090
virtual std::string fcn_file_name(void) const
Definition: ov-fcn.h:74
bool is_global(void) const
Definition: pt-decl.h:93
octave_value_list evaluate_n(tree_expression *expr, int nargout=1)
Definition: pt-eval.h:325
static bool quiet_breakpoint_flag
Definition: pt-eval.h:254
Matrix ignored_fcn_outputs(void) const
Definition: pt-eval.cc:449
octave_value arg
Definition: pr-output.cc:3244
void bind_ans(const octave_value &val, bool print)
Definition: pt-eval.cc:2798
octave_value & do_non_const_unary_op(unary_op op)
Definition: ov.cc:2681
octave_function * fcn
Definition: ov-class.cc:1754
void matlab_style_short_circuit_warning(const char *op)
Definition: pt-binop.cc:37
string_vector argv
Definition: load-save.cc:648
void visit_compound_binary_expression(tree_compound_binary_expression &)
Definition: pt-eval.cc:302
void visit_return_command(tree_return_command &)
Definition: pt-eval.cc:2184
octave_value resize(const dim_vector &dv, bool fill=false) const
Definition: ov.h:511
bool is_defined(void) const
Definition: ov-fcn.h:68
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:400
bool swap
Definition: load-save.cc:738
void err_indexed_cs_list(void)
Definition: errwarn.cc:62
bool isjava(void) const
Definition: ov.h:615
octave_value storable_value(void) const
static std::string make_absolute(const std::string &s, const std::string &dot_path=get_current_directory())
Definition: oct-env.cc:129
void accept(tree_walker &tw)
Definition: pt-decl.h:173
octave_value PS4(const octave_value_list &args, int nargout)
Definition: pt-eval.cc:3218
void visit_switch_command(tree_switch_command &)
Definition: pt-eval.cc:2451
symbol_table & __get_symbol_table__(const std::string &who)
int buffer_error_messages
Definition: error.cc:112
nd deftypefn *std::string name
Definition: sysdep.cc:647
void visit_postfix_expression(tree_postfix_expression &)
Definition: pt-eval.cc:2097
iterator end(void)
Definition: base-list.h:86
OCTAVE_EXPORT octave_value_list isdir nd deftypefn *std::string nm
Definition: utils.cc:975
octave_value resize(const dim_vector &dv, bool=false) const
tree_expression * expression(void)
Definition: pt-idx.h:82
tree_parameter_list * parameter_list(void) const
std::string m_echo_file_name
Definition: pt-eval.h:524
void maybe_warn_string_concat(bool all_dq_strings_p, bool all_sq_strings_p)
Definition: pt-mat.cc:117
octave_value do_unary_op(octave::type_info &ti, octave_value::unary_op op, const octave_value &v)
Definition: ov.cc:2615
int echo(void) const
Definition: pt-eval.h:423
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:997
std::string dispatch_class(void) const
Definition: ov-fcn.h:122
void visit_cell(tree_cell &)
Definition: pt-eval.cc:1797
void visit_identifier(tree_identifier &)
Definition: pt-eval.cc:1093
octave_function * caller(void) const
Definition: call-stack.h:118
bool Vtrack_line_num
Definition: input.cc:102
void assign(octave_value::assign_op, const octave_value &)
Definition: oct-lvalue.cc:34
void visit_if_command(tree_if_command &)
Definition: pt-eval.cc:1159
void visit_fcn_handle(tree_fcn_handle &)
Definition: pt-eval.cc:2049
symbol_record::context_id current_context(void) const
Definition: symscope.h:669
octave_value_list convert_return_list_to_const_vector(tree_parameter_list *ret_list, int nargout, const Cell &varargout)
Definition: pt-eval.cc:586
void error_with_id(const char *id, const char *fmt,...)
Definition: error.cc:623
octave_value function(void) const
Definition: pt-funcall.h:71
static size_t current_frame
Definition: pt-eval.h:250
OCTINTERP_API octave_value do_binary_op(octave::type_info &ti, octave_value::binary_op op, const octave_value &a, const octave_value &b)
bool have_breakpoints(void)
Definition: bp-table.h:94
std::list< tree_argument_list * > arg_lists(void)
Definition: pt-idx.h:84
void visit_if_clause(tree_if_clause &)
Definition: pt-eval.cc:1153
bool iscell(void) const
Definition: ov.h:536
void err_invalid_structure_assignment(void)
Definition: errwarn.cc:80
std::string type_tags(void)
Definition: pt-idx.h:86
tree_expression * control_expr(void)
Definition: pt-loop.h:293
tree_expression * control_expr(void)
Definition: pt-loop.h:207
int in_try_catch
Definition: error.cc:116
dim_vector dims(void) const
Definition: ov.h:469
std::map< std::string, bool > m_echo_files
Definition: pt-eval.h:529
OCTINTERP_API std::string last_error_id(void)
string_vector make_argv(const std::string &="") const
Definition: ovl.cc:212
tree_statement_list * cleanup(void)
Definition: pt-except.h:71
tree_expression * left_hand_side(void)
Definition: pt-assign.h:76
virtual bool is_class_method(const std::string &="") const
Definition: ov-fcn.h:105
bool is_function(void) const
Definition: ov-fcn.h:70
void accept(tree_walker &tw)
Definition: pt-stmt.h:188
octave_idx_type numel(void) const
Definition: Range.h:85
static bool is_variable(octave::symbol_table &symtab, const std::string &name)
Definition: variables.cc:201
double tmp
Definition: data.cc:6252
octave_value retval
Definition: data.cc:6246
octave_value do_single_type_concat< octave_map >(const dim_vector &dv, tm_const &tmp)
Definition: pt-tm-const.cc:368
void maybe_set_echo_state(void)
Definition: pt-eval.cc:3032
#define panic_impossible()
Definition: error.h:40
void visit_binary_expression(tree_binary_expression &)
Definition: pt-eval.cc:166
void set_echo_file_name(const std::string &file_name)
Definition: pt-eval.h:469
void do_unwind_protect_cleanup_code(tree_statement_list *list)
Definition: pt-eval.cc:2568
tree_expression * expression(void)
Definition: pt-decl.h:102
void visit_anon_fcn_handle(tree_anon_fcn_handle &)
Definition: pt-eval.cc:89
void visit_octave_user_function_trailer(octave_user_function &)
Definition: pt-eval.cc:1062
octave_function * function_value(bool silent=false) const
tree_expression * clhs(void)
Definition: pt-cbinop.h:58
const Cell & contents(const_iterator p) const
Definition: oct-map.h:317
sig_atomic_t octave_interrupt_state
Definition: cquit.c:32
do not permute tem code
Definition: balance.cc:90
void visit_break_command(tree_break_command &)
Definition: pt-eval.cc:333
virtual bool accepts_postfix_index(char type) const
Definition: ov-fcn.h:200
octave_value m_expr_result_value
Definition: pt-eval.h:487
idx type
Definition: ov.cc:3114
double elem(octave_idx_type i) const
Definition: Range.cc:131
Definition: dMatrix.h:36
bool is_function(void) const
Definition: ov.h:758
bool is_package(void) const
Definition: ov.h:605
tree_expression * increment(void)
Definition: pt-colon.h:92
bool isstruct(void) const
Definition: ov.h:589
result_type
Definition: pt-eval.h:49
bool octave_debug_on_interrupt_state
Definition: pt-bp.cc:35
std::string dir_name(void) const
Definition: ov-fcn.h:144
static bool debug_mode
Definition: pt-eval.h:252
tree_command * command(void)
Definition: pt-stmt.h:90
const std::list< octave_lvalue > * lvalue_list(void) const
Definition: pt-eval.h:276
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
Definition: dim-vector.cc:233
octave_idx_type get_count(void) const
Definition: ov.h:373
end deftypefn *return set_internal_variable(Vsvd_driver, args, nargout, "svd_driver", driver_names)
void numel(octave_idx_type n)
Definition: oct-lvalue.h:75
octave_value convert_to_str(bool pad=false, bool force=false, char type='\'') const
Definition: ov.h:1251
octave_value varval(const std::string &name) const
Definition: symscope.h:727
void visit_switch_case_list(tree_switch_case_list &)
Definition: pt-eval.cc:2445
With real return the complex result
Definition: data.cc:3260
void visit_while_command(tree_while_command &)
Definition: pt-eval.cc:2697
bool is_added_static(void) const
Definition: symrec.h:658
virtual bool is_identifier(void) const
Definition: pt-exp.h:69
symbol_table & get_symbol_table(void)
Definition: interpreter.h:169
octave_value::compound_binary_op cop_type(void) const
Definition: pt-cbinop.h:54
tree_expression * switch_value(void)
Definition: pt-select.h:266
tree_expression * right_hand_side(void)
Definition: pt-assign.h:147
void set_line(int l)
Definition: call-stack.h:202
bool has_parent_scope(void) const
octave_function * current(void) const
Definition: call-stack.h:97
void visit_decl_elt(tree_decl_elt &)
Definition: pt-eval.cc:722
octave_value reshape(const dim_vector &dv) const
Definition: ov.h:502
int max_recursion_depth(void) const
Definition: pt-eval.h:377
octave::unwind_protect frame
Definition: graphics.cc:12190
OCTINTERP_API std::string last_error_message(void)
std::string m_PS4
Definition: pt-eval.h:510
void visit_complex_for_command(tree_complex_for_command &)
Definition: pt-eval.cc:964
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:227
tree_statement_list * body(void)
Definition: pt-except.h:136
tree_statement_list * body(void)
Definition: pt-loop.h:211
octave_value_list list_value(void) const
std::list< octave_lvalue > make_lvalue_list(tree_argument_list *)
Definition: pt-eval.cc:2980
OCTINTERP_API octave_map last_error_stack(void)
virtual octave_lvalue lvalue(tree_evaluator *)
Definition: pt-exp.cc:41
#define octave_stdout
Definition: pager.h:174
void visit_simple_for_command(tree_simple_for_command &)
Definition: pt-eval.cc:826
void visit_statement_list(tree_statement_list &)
Definition: pt-eval.cc:2388
tree_expression * rhs(void)
Definition: pt-binop.h:100
OCTINTERP_API octave_value do_cat_op(octave::type_info &ti, const octave_value &a, const octave_value &b, const Array< octave_idx_type > &ra_idx)
bool is_undefined(void) const
Definition: ov.h:526
void push_echo_state_cleanup(unwind_protect &frame)
Definition: pt-eval.cc:3051
symbol_scope __require_current_scope__(const std::string &who)
octave_value do_keyboard(const octave_value_list &args=octave_value_list())
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
bool is_for_cmd_expr(void) const
Definition: pt-exp.h:110
octave_value do_class_concat(tm_const &tmc)
Definition: pt-tm-const.cc:381
int current_line(void) const
Definition: call-stack.cc:99
tree_statement_list * body(void)
Definition: pt-loop.h:295
bp_table & __get_bp_table__(const std::string &who)
tree_expression * left_hand_side(void)
Definition: pt-loop.h:205
std::string name(void) const
Definition: pt-fcn-handle.h:71
result_type m_result_type
Definition: pt-eval.h:486
virtual bool is_class_constructor(const std::string &="") const
Definition: ov-fcn.h:98
p
Definition: lu.cc:138
void force_assign(const std::string &name, const octave_value &value)
Definition: symscope.h:721
tree_expression * crhs(void)
Definition: pt-cbinop.h:59
void visit_function_def(tree_function_def &)
Definition: pt-eval.cc:1068
void visit_do_until_command(tree_do_until_command &)
Definition: pt-eval.cc:2747
static octave_value make_fcn_handle(octave_builtin::fcn ff, const std::string &nm)
Definition: ov-classdef.cc:129
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition: errwarn.cc:338
tree_expression * expression(void) const
compound_binary_op
Definition: ov.h:119
octave_idx_type length(void) const
Definition: ovl.h:96
bool is_logically_true(tree_expression *expr, const char *warn_for)
Definition: pt-eval.cc:2930
void stash_dispatch_class(const std::string &nm)
Definition: ov-fcn.h:120
static octave_fcn_handle * maybe_binder(const octave_value &f, octave::tree_evaluator *tw)
void visit_decl_init_list(tree_decl_init_list &)
Definition: pt-eval.cc:715
b
Definition: cellfun.cc:400
symbol_scope get_current_scope(void)
Definition: pt-eval.cc:688
void define_parameter_list_from_arg_vector(tree_parameter_list *param_list, const octave_value_list &args)
Definition: pt-eval.cc:548
void clear_index(void)
Definition: oct-lvalue.h:81
void set_column(int c)
Definition: call-stack.h:212
tree_argument_list * left_hand_side(void)
Definition: pt-assign.h:145
void err_invalid_inquiry_subscript(void)
Definition: errwarn.cc:74
void static_workspace_error(void)
Definition: pt-id.h:124
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:100
void add_method(T *obj, void(T::*method)(void))
tree_expression * lhs(void)
Definition: pt-binop.h:99
tree_expression * case_label(void)
Definition: pt-select.h:191
octave_value_list m_expr_result_value_list
Definition: pt-eval.h:488
void visit_continue_command(tree_continue_command &)
Definition: pt-eval.cc:415
int current_column(void) const
Definition: call-stack.cc:113
std::string name(void) const
Definition: pt-id.h:72
char string_fill_char(void) const
Definition: pt-eval.h:401
int column(void) const
Definition: pt-stmt.cc:115
bool is_postfix_indexed(void) const
Definition: pt-exp.h:91
void mark_as_anonymous_function(void)
Definition: ov-usr-fcn.h:330
octave_value evaluate(tree_expression *expr, int nargout=1)
Definition: pt-eval.h:294
for i
Definition: data.cc:5264
octave_value_list convert_to_const_vector(tree_evaluator *tw, const octave_value *object=nullptr)
octave_idx_type columns(void) const
Definition: ov-base.h:323
static bool execute(tree_simple_for_command &cmd, const octave_value &bounds)
Definition: pt-jit.h:490
bool is_string(void) const
Definition: ov.h:577
bool has_magic_end(void) const
Definition: pt-arg-list.cc:63
value_stack< int > m_nargout_stack
Definition: pt-eval.h:492
OCTAVE_EXPORT octave_value_list error nd deftypefn *const octave_scalar_map err
Definition: error.cc:1049
static stmt_list_type statement_context
Definition: pt-eval.h:265
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:295
bool is_classdef_meta(void) const
Definition: ov.h:596
bool echo_this_file(const std::string &file, int type) const
Definition: pt-eval.cc:3223
bool switch_case_label_matches(tree_switch_case *expr, const octave_value &val)
Definition: pt-eval.cc:656
virtual octave_function * function_value(bool silent=false)
Definition: ov-base.cc:871
void visit_switch_case(tree_switch_case &)
Definition: pt-eval.cc:2439
bool is_range(void) const
Definition: ov.h:586
tree_expression * operand(void)
Definition: pt-unop.h:70
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
octave_idx_type length(void) const
void visit_no_op_command(tree_no_op_command &)
Definition: pt-eval.cc:2024
void accept(tree_walker &tw)
Definition: pt-stmt.h:113
tree_identifier * ident(void)
Definition: pt-decl.h:98
void install_cmdline_function(const std::string &name, const octave_value &fcn)
Definition: symtab.h:278
void echo_code(size_t line)
Definition: pt-eval.cc:3256
void set_parent(const symbol_scope &p)
Definition: symscope.h:941
void stash_parent_fcn_name(const std::string &p)
Definition: ov-usr-fcn.h:261
static bool quit_loop_now(void)
Definition: pt-eval.cc:806
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
bool Vdebugging
Definition: input.cc:97
bool silent_functions(void) const
Definition: pt-eval.h:389
void visit_return_list(tree_return_list &)
Definition: pt-eval.cc:2210
std::string name(void) const
Definition: ov-fcn.h:182
void visit_octave_user_function(octave_user_function &)
Definition: pt-eval.cc:1049
unary_op
Definition: ov.h:81
tree_expression * condition(void)
Definition: pt-loop.h:85
virtual bool is_assignment_expression(void) const
Definition: pt-exp.h:73
bool is_global(const std::string &name) const
Definition: symscope.h:842
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
void visit_unwind_protect_command(tree_unwind_protect_command &)
Definition: pt-eval.cc:2647
void visit_colon_expression(tree_colon_expression &)
Definition: pt-eval.cc:352
dim_vector dv
Definition: sub2ind.cc:263
OCTINTERP_API octave_value do_colon_op(const octave_value &base, const octave_value &limit, bool is_for_cmd_expr=false)
Definition: ov.h:1315
void visit_index_expression(tree_index_expression &)
Definition: pt-eval.cc:1315
void visit_multi_assignment(tree_multi_assignment &)
Definition: pt-eval.cc:1859
bool is_scalar_type(void) const
Definition: ov.h:717
Cell cell_value(void) const
virtual tree_expression * dup(symbol_scope &scope) const =0
bool is_end_of_fcn_or_script(void) const
Definition: pt-cmd.h:78
tree_statement_list * body(void)
Definition: pt-except.h:69
bool is_matrix_type(void) const
Definition: ov.h:720
size_t current_frame(void) const
Definition: call-stack.h:123
where the brackets indicate optional arguments and and character or cell array For character arrays the conversion is repeated for every row
Definition: str2double.cc:342
iterator begin(void)
Definition: base-list.h:83
tree_switch_case_list * case_list(void)
Definition: pt-select.h:268
std::list< tree_expression * > dyn_fields(void)
Definition: pt-idx.h:90
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:204
octave_value::assign_op op_type(void) const
Definition: pt-assign.h:87
tree_argument_list * left_hand_side(void)
Definition: pt-loop.h:291
void visit_matrix(tree_matrix &)
Definition: pt-eval.cc:1598
octave_value value(void)
Definition: pt-const.h:83
tree_if_command_list * cmd_list(void)
Definition: pt-select.h:140
std::string get_struct_index(tree_evaluator *tw, std::list< string_vector >::const_iterator p_arg_nm, std::list< tree_expression *>::const_iterator p_dyn_field) const
Definition: pt-idx.cc:174
bool print_result(void) const
Definition: pt-exp.h:98
tree_identifier * identifier(void)
Definition: pt-except.h:67
tree_expression * limit(void)
Definition: pt-colon.h:90
tree_expression * expression(void)
Definition: pt-stmt.h:92
void stash_name_tags(const string_vector &nm)
Definition: ovl.h:144
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Definition: ov.h:444