GNU Octave  6.2.0
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-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <cctype>
31 
32 #include <iostream>
33 #include <list>
34 #include <string>
35 
36 #include "cmd-edit.h"
37 #include "file-ops.h"
38 #include "file-stat.h"
39 #include "lo-array-errwarn.h"
40 #include "lo-ieee.h"
41 #include "oct-env.h"
42 
43 #include "bp-table.h"
44 #include "call-stack.h"
45 #include "cdef-manager.h"
46 #include "defun.h"
47 #include "error.h"
48 #include "errwarn.h"
49 #include "event-manager.h"
50 #include "input.h"
51 #include "interpreter-private.h"
52 #include "interpreter.h"
53 #include "octave.h"
54 #include "ov-classdef.h"
55 #include "ov-fcn-handle.h"
56 #include "ov-usr-fcn.h"
57 #include "ov-re-sparse.h"
58 #include "ov-cx-sparse.h"
59 #include "parse.h"
60 #include "profiler.h"
61 #include "pt-all.h"
62 #include "pt-anon-scopes.h"
63 #include "pt-eval.h"
64 #include "pt-tm-const.h"
65 #include "stack-frame.h"
66 #include "symtab.h"
67 #include "unwind-prot.h"
68 #include "utils.h"
69 #include "variables.h"
70 
71 //FIXME: This should be part of tree_evaluator
72 #include "pt-jit.h"
73 
74 namespace octave
75 {
76  // Normal evaluator.
77 
79  {
80  public:
81 
82  quit_debug_exception (bool all = false) : m_all (all) { }
83 
85 
87 
88  ~quit_debug_exception (void) = default;
89 
90  bool all (void) const { return m_all; }
91 
92  private:
93 
94  bool m_all;
95  };
96 
97  class debugger
98  {
99  public:
100 
102  {
105  EX_QUIT = 2,
106  EX_QUIT_ALL = 3
107  };
108 
109  debugger (interpreter& interp, size_t level)
110  : m_interpreter (interp), m_level (level), m_debug_frame (0),
112  { }
113 
114  void repl (const std::string& prompt = "debug> ");
115 
116  bool in_debug_repl (void) const { return m_in_debug_repl; }
117 
118  void dbcont (void)
119  {
121  }
122 
123  void dbquit (bool all = false)
124  {
125  if (all)
127  else
129  }
130 
131  bool quitting_debugger (void) const;
132 
133  private:
134 
136 
137  size_t m_level;
141  };
142 
143  void debugger::repl (const std::string& prompt_arg)
144  {
145  unwind_protect frame;
146 
149 
150  m_in_debug_repl = true;
151 
153 
154  bool silent = tw.quiet_breakpoint_flag (false);
155 
158 
159  tw.goto_frame (tw.debug_frame ());
160 
161  octave_user_code *caller = tw.current_user_code ();
162  std::string fcn_file_nm, fcn_nm;
163 
164  if (caller)
165  {
166  fcn_file_nm = caller->fcn_file_name ();
167  fcn_nm = fcn_file_nm.empty () ? caller->name () : fcn_file_nm;
168  }
169 
170  int curr_debug_line = tw.current_line ();
171 
172  std::ostringstream buf;
173 
175 
176  if (! fcn_nm.empty ())
177  {
178  if (input_sys.gud_mode ())
179  {
180  static char ctrl_z = 'Z' & 0x1f;
181 
182  buf << ctrl_z << ctrl_z << fcn_nm << ':' << curr_debug_line;
183  }
184  else
185  {
186  // FIXME: we should come up with a clean way to detect
187  // that we are stopped on the no-op command that marks the
188  // end of a function or script.
189 
190  if (! silent)
191  {
192  std::shared_ptr<stack_frame> frm = tw.current_user_frame ();
193 
194  frm->display_stopped_in_message (buf);
195  }
196 
198 
199  evmgr.enter_debugger_event (fcn_nm, fcn_file_nm, curr_debug_line);
200 
201  evmgr.set_workspace ();
202 
203  frame.add ([&evmgr, fcn_nm, curr_debug_line] (void) {
204  evmgr.execute_in_debugger_event (fcn_nm,
205  curr_debug_line);
206  });
207 
208  if (! silent)
209  {
210  std::string line_buf;
211 
212  if (caller)
213  line_buf = caller->get_code_line (curr_debug_line);
214 
215  if (! line_buf.empty ())
216  buf << curr_debug_line << ": " << line_buf;
217  }
218  }
219  }
220 
221  if (silent)
223 
224  std::string stopped_in_msg = buf.str ();
225 
226  if (! stopped_in_msg.empty ())
227  std::cerr << stopped_in_msg << std::endl;
228 
229  std::string tmp_prompt = prompt_arg;
230  if (m_level > 0)
231  tmp_prompt = "[" + std::to_string (m_level) + "]" + prompt_arg;
232 
233  frame.add_method (input_sys, &input_system::set_PS1, input_sys.PS1 ());
234  input_sys.PS1 (tmp_prompt);
235 
236  if (! m_interpreter.interactive ())
237  {
238 
241 
242  m_interpreter.interactive (true);
243 
244  // FIXME: should debugging be possible in an embedded
245  // interpreter?
246 
247  application *app = application::app ();
248 
249  if (app)
250  {
252  app->forced_interactive ());
253 
254  app->forced_interactive (true);
255  }
256  }
257 
258 #if defined (OCTAVE_ENABLE_COMMAND_LINE_PUSH_PARSER)
259 
260  input_reader reader (m_interpreter);
261 
262  push_parser debug_parser (m_interpreter);
263 
264 #else
265 
266  parser debug_parser (m_interpreter);
267 
268 #endif
269 
271 
272  while (m_in_debug_repl)
273  {
274  if (m_execution_mode == EX_CONTINUE || tw.dbstep_flag ())
275  break;
276 
277  if (quitting_debugger ())
278  break;
279 
280  try
281  {
282  debug_parser.reset ();
283 
284 #if defined (OCTAVE_ENABLE_COMMAND_LINE_PUSH_PARSER)
285 
286  int retval = 0;
287 
288  std::string prompt
290 
291  do
292  {
293  bool eof = false;
294  std::string input_line = reader.get_input (prompt, eof);
295 
296  if (eof)
297  {
298  retval = EOF;
299  break;
300  }
301 
302  retval = debug_parser.run (input_line, false);
303 
304  prompt = command_editor::decode_prompt_string (input_sys.PS2 ());
305  }
306  while (retval < 0);
307 
308 #else
309 
310  int retval = debug_parser.run ();
311 
312 #endif
313  if (command_editor::interrupt (false))
314  {
315  // Break regardless of m_execution_mode value.
316 
318 
319  break;
320  }
321  else
322  {
323  if (retval == 0)
324  {
325  std::shared_ptr<tree_statement_list> stmt_list
326  = debug_parser.statement_list ();
327 
328  if (stmt_list)
329  stmt_list->accept (tw);
330 
333 
334  // FIXME: the following statement is here because
335  // the last command may have been a dbup, dbdown, or
336  // dbstep command that changed the current debug
337  // frame. If so, we need to reset the current frame
338  // for the call stack. But is this right way to do
339  // this job? What if the statement list was
340  // something like "dbup; dbstack"? Will the call to
341  // dbstack use the right frame? If not, how can we
342  // fix this problem?
343  tw.goto_frame (tw.debug_frame ());
344  }
345 
346  octave_quit ();
347  }
348  }
349  catch (const execution_exception& ee)
350  {
351  es.save_exception (ee);
352  es.display_exception (ee, std::cerr);
353 
354  // Ignore errors when in debugging mode;
356  }
357  catch (const quit_debug_exception& qde)
358  {
359  if (qde.all ())
360  throw;
361 
362  // Continue in this debug level.
363  }
364  }
365  }
366 
367  bool debugger::quitting_debugger (void) const
368  {
369  if (m_execution_mode == EX_QUIT)
370  {
371  // If there is no enclosing debug level or the top-level
372  // repl is not active, handle dbquit the same as dbcont.
373 
375  throw quit_debug_exception ();
376  else
377  return true;
378  }
379 
381  {
382  // If the top-level repl is not active, handle "dbquit all"
383  // the same as dbcont.
384 
386  throw quit_debug_exception (true);
387  else
388  return true;
389  }
390 
391  return false;
392  }
393 
395  {
396  return m_call_stack.at_top_level ();
397  }
398 
399  void tree_evaluator::eval (std::shared_ptr<tree_statement_list>& stmt_list,
400  bool interactive)
401  {
402  try
403  {
404  stmt_list->accept (*this);
405 
406  octave_quit ();
407 
408  if (! interactive)
409  {
410  bool quit = (m_returning || m_breaking);
411 
412  if (m_returning)
413  m_returning = 0;
414 
415  if (m_breaking)
416  m_breaking--;
417 
418  if (quit)
419  return;
420  }
421 
424  }
425  catch (const quit_debug_exception&)
426  {
428  }
429  }
430 
431  std::string
432  tree_evaluator::mfilename (const std::string& opt) const
433  {
434  std::string fname;
435 
437 
438  if (fcn)
439  {
440  fname = fcn->fcn_file_name ();
441 
442  if (fname.empty ())
443  fname = fcn->name ();
444  }
445 
446  if (opt == "fullpathext")
447  return fname;
448 
449  size_t dpos = fname.rfind (sys::file_ops::dir_sep_char ());
450  size_t epos = fname.rfind ('.');
451 
452  if (epos <= dpos+1)
453  epos = std::string::npos;
454 
455  if (epos != std::string::npos)
456  fname = fname.substr (0, epos);
457 
458  if (opt == "fullpath")
459  return fname;
460 
461  if (dpos != std::string::npos)
462  fname = fname.substr (dpos+1);
463 
464  return fname;
465  }
466 
468  tree_evaluator::eval_string (const std::string& eval_str, bool silent,
469  int& parse_status, int nargout)
470  {
472 
473  parser eval_parser (eval_str, m_interpreter);
474 
475  do
476  {
477  eval_parser.reset ();
478 
479  // If we are looking at
480  //
481  // val = eval ("code");
482  //
483  // then don't allow code to be parsed as a command.
484 
485  if (nargout > 0)
486  eval_parser.disallow_command_syntax ();
487 
488  parse_status = eval_parser.run ();
489 
490  if (parse_status == 0)
491  {
492  std::shared_ptr<tree_statement_list> stmt_list
493  = eval_parser.statement_list ();
494 
495  if (stmt_list)
496  {
497  tree_statement *stmt = nullptr;
498 
499  if (stmt_list->length () == 1
500  && (stmt = stmt_list->front ())
501  && stmt->is_expression ())
502  {
503  tree_expression *expr = stmt->expression ();
504 
505  if (silent)
506  expr->set_print_flag (false);
507 
508  retval = expr->evaluate_n (*this, nargout);
509 
510  bool do_bind_ans = false;
511 
512  if (expr->is_identifier ())
513  do_bind_ans = ! is_variable (expr);
514  else
515  do_bind_ans = ! expr->is_assignment_expression ();
516 
517  if (do_bind_ans && ! retval.empty ())
518  bind_ans (retval(0), expr->print_result ());
519 
520  if (nargout == 0)
522  }
523  else if (nargout == 0)
524  stmt_list->accept (*this);
525  else
526  error ("eval: invalid use of statement list");
527 
528  if (returning () || breaking () || continuing ())
529  break;
530  }
531  else if (eval_parser.at_end_of_input ())
532  break;
533  }
534  }
535  while (parse_status == 0);
536 
537  return retval;
538  }
539 
540  octave_value tree_evaluator::eval_string (const std::string& eval_str,
541  bool silent, int& parse_status)
542  {
544 
545  octave_value_list tmp = eval_string (eval_str, silent, parse_status, 1);
546 
547  if (! tmp.empty ())
548  retval = tmp(0);
549 
550  return retval;
551  }
552 
554  bool silent, int& parse_status,
555  int nargout)
556  {
557  std::string s = arg.xstring_value ("eval: expecting string argument");
558 
559  return eval_string (s, silent, parse_status, nargout);
560  }
561 
562  octave_value_list tree_evaluator::eval (const std::string& try_code,
563  int nargout)
564  {
565  int parse_status = 0;
566 
567  return eval_string (try_code, nargout > 0, parse_status, nargout);
568  }
569 
570  octave_value_list tree_evaluator::eval (const std::string& try_code,
571  const std::string& catch_code,
572  int nargout)
573  {
575 
577 
578  int parse_status = 0;
579 
580  bool execution_error = false;
581 
582  octave_value_list tmp;
583 
584  try
585  {
586  tmp = eval_string (try_code, nargout > 0, parse_status, nargout);
587  }
588  catch (const execution_exception& ee)
589  {
590  es.save_exception (ee);
592 
593  execution_error = true;
594  }
595 
596  if (parse_status != 0 || execution_error)
597  {
598  tmp = eval_string (catch_code, nargout > 0, parse_status, nargout);
599 
600  retval = (nargout > 0) ? tmp : octave_value_list ();
601  }
602  else
603  {
604  if (nargout > 0)
605  retval = tmp;
606 
607  // FIXME: we should really be rethrowing whatever
608  // exception occurred, not just throwing an
609  // execution exception.
610  if (execution_error)
611  throw execution_exception ();
612  }
613 
614  return retval;
615  }
616 
618  const std::string& try_code,
619  int nargout)
620  {
621  unwind_action act ([this] (size_t frm)
622  {
625 
626  if (context == "caller")
628  else if (context == "base")
630  else
631  error ("evalin: CONTEXT must be \"caller\" or \"base\"");
632 
633  int parse_status = 0;
634 
635  return eval_string (try_code, nargout > 0, parse_status, nargout);
636  }
637 
639  const std::string& try_code,
640  const std::string& catch_code,
641  int nargout)
642  {
644 
645  unwind_action act1 ([this] (size_t frm)
646  {
649 
650  if (context == "caller")
652  else if (context == "base")
654  else
655  error ("evalin: CONTEXT must be \"caller\" or \"base\"");
656 
658 
659  int parse_status = 0;
660 
661  bool execution_error = false;
662 
663  octave_value_list tmp;
664 
665  try
666  {
667  tmp = eval_string (try_code, nargout > 0, parse_status, nargout);
668  }
669  catch (const execution_exception& ee)
670  {
671  es.save_exception (ee);
673 
674  execution_error = true;
675  }
676 
677  if (parse_status != 0 || execution_error)
678  {
679  tmp = eval_string (catch_code, nargout > 0, parse_status, nargout);
680 
681  retval = (nargout > 0) ? tmp : octave_value_list ();
682  }
683  else
684  {
685  if (nargout > 0)
686  retval = tmp;
687 
688  // FIXME: we should really be rethrowing whatever
689  // exception occurred, not just throwing an
690  // execution exception.
691  if (execution_error)
692  throw execution_exception ();
693  }
694 
695  return retval;
696  }
697 
698  void
700  {
701  panic_impossible ();
702  }
703 
704  void
706  {
707  panic_impossible ();
708  }
709 
710  void
712  {
713  panic_impossible ();
714  }
715 
716  void
718  {
719  panic_impossible ();
720  }
721 
722  void
724  {
725  panic_impossible ();
726  }
727 
728  void
730  {
731  if (m_echo_state)
732  {
733  size_t line = cmd.line ();
734  echo_code (line);
735  m_echo_file_pos = line + 1;
736  }
737 
738  if (m_debug_mode)
739  do_breakpoint (cmd.is_active_breakpoint (*this));
740 
741  if (m_in_loop_command)
742  m_breaking = 1;
743  else
744  error ("break must appear in a loop in the same file as loop command");
745  }
746 
747  void
749  {
750  panic_impossible ();
751  }
752 
753  void
755  {
756  if (m_echo_state)
757  {
758  size_t line = cmd.line ();
759  echo_code (line);
760  m_echo_file_pos = line + 1;
761  }
762 
763  if (m_debug_mode)
764  do_breakpoint (cmd.is_active_breakpoint (*this));
765 
766  if (m_in_loop_command)
767  m_continuing = 1;
768  }
769 
770  bool
772  {
775  }
776 
777  void
779  {
781  || in_debug_repl ());
782  }
783 
784  void
786  {
787  m_debug_mode = mode;
788  }
789 
790  void
791  tree_evaluator::enter_debugger (const std::string& prompt)
792  {
793  unwind_protect frame;
794 
797 
799 
802 
803  // Don't allow errors or warnings at the debug prompt to push us
804  // into deeper levels of debugging.
805 
807 
809  es.debug_on_error ());
810 
812  es.debug_on_warning ());
813 
814  es.debug_on_error (false);
815  es.debug_on_warning (false);
816 
817  // Go up to the nearest user code frame.
818 
820 
821  // FIXME: probably we just want to print one line, not the
822  // entire statement, which might span many lines...
823  //
824  // tree_print_code tpc (octave_stdout);
825  // stmt.accept (tpc);
826 
827  debugger *dbgr = new debugger (m_interpreter, m_debugger_stack.size ());
828 
829  m_debugger_stack.push (dbgr);
830 
831  frame.add ([this] (void)
832  {
833  delete m_debugger_stack.top ();
834  m_debugger_stack.pop ();
835  });
836 
837  dbgr->repl (prompt);
838  }
839 
840  void
841  tree_evaluator::keyboard (const std::string& prompt)
842  {
843  enter_debugger (prompt);
844  }
845 
846  void
847  tree_evaluator::dbupdown (int n, bool verbose)
848  {
849  m_debug_frame = m_call_stack.dbupdown (n, verbose);
850  }
851 
852  Matrix
854  {
855  Matrix retval;
856 
857  const std::list<octave_lvalue> *lvalues = m_lvalue_list;
858 
859  if (! lvalues)
860  return retval;
861 
862  octave_idx_type nbh = 0;
863 
864  for (const auto& lval : *lvalues)
865  nbh += lval.is_black_hole ();
866 
867  if (nbh > 0)
868  {
869  retval.resize (1, nbh);
870 
871  octave_idx_type k = 0;
872  octave_idx_type l = 0;
873 
874  for (const auto& lval : *lvalues)
875  {
876  if (lval.is_black_hole ())
877  retval(l++) = k+1;
878 
879  k += lval.numel ();
880  }
881  }
882 
883  return retval;
884  }
885 
886  // If NAME is an operator (like "+", "-", ...), convert it to the
887  // corresponding function name ("plus", "minus", ...).
888 
889  static std::string
890  get_operator_function_name (const std::string& name)
891  {
892  // Bow to the god of compatibility.
893 
894  // FIXME: it seems ugly to put this here, but there is no single
895  // function in the parser that converts from the operator name to
896  // the corresponding function name. At least try to do it without N
897  // string compares.
898 
899  size_t len = name.length ();
900 
901  if (len == 3 && name == ".**")
902  return "power";
903  else if (len == 2)
904  {
905  if (name[0] == '.')
906  {
907  switch (name[1])
908  {
909  case '\'':
910  return "transpose";
911 
912  case '+':
913  return "plus";
914 
915  case '-':
916  return "minus";
917 
918  case '*':
919  return "times";
920 
921  case '/':
922  return "rdivide";
923 
924  case '^':
925  return "power";
926 
927  case '\\':
928  return "ldivide";
929 
930  default:
931  break;
932  }
933  }
934  else if (name[1] == '=')
935  {
936  switch (name[0])
937  {
938  case '<':
939  return "le";
940 
941  case '=':
942  return "eq";
943 
944  case '>':
945  return "ge";
946 
947  case '~':
948  case '!':
949  return "ne";
950 
951  default:
952  break;
953  }
954  }
955  else if (name == "**")
956  return "mpower";
957  }
958  else if (len == 1)
959  {
960  switch (name[0])
961  {
962  case '~':
963  case '!':
964  return "not";
965 
966  case '\'':
967  return "ctranspose";
968 
969  case '+':
970  return "plus";
971 
972  case '-':
973  return "minus";
974 
975  case '*':
976  return "mtimes";
977 
978  case '/':
979  return "mrdivide";
980 
981  case '^':
982  return "mpower";
983 
984  case '\\':
985  return "mldivide";
986 
987  case '<':
988  return "lt";
989 
990  case '>':
991  return "gt";
992 
993  case '&':
994  return "and";
995 
996  case '|':
997  return "or";
998 
999  default:
1000  break;
1001  }
1002  }
1003 
1004  return name;
1005  }
1006 
1007  // Creates a function handle that takes into account the context,
1008  // finding local, nested, private, or sub functions.
1009 
1010  octave_value
1012  {
1014 
1015  // The str2func function can create a function handle with the name
1016  // of an operator (for example, "+"). If so, it is converted to the
1017  // name of the corresponding function ("+" -> "plus") and we create
1018  // a simple function handle using that name.
1019 
1020  std::string fcn_name = get_operator_function_name (name);
1021 
1022  // If FCN_NAME is different from NAME, then NAME is an operator. As
1023  // of version 2020a, Matlab apparently uses the function name
1024  // corresponding to the operator to search for private and local
1025  // functions in the current scope but not(!) nested functions.
1026 
1027  bool name_is_operator = fcn_name != name;
1028 
1029  size_t pos = fcn_name.find ('.');
1030 
1031  if (pos != std::string::npos)
1032  {
1033  // Recognize (some of? which ones?) the following cases
1034  // and create something other than a simple function handle?
1035  // Should we just be checking for the last two when the first
1036  // element of the dot-separated list is an object? If so, then
1037  // should this syntax be limited to a dot-separated list with
1038  // exactly two elements?
1039  //
1040  // object . method
1041  // object . static-method
1042  //
1043  // Code to do that duplicates some of simple_fcn_handle::call.
1044 
1045  // Only accept expressions that contain one '.' separator.
1046 
1047  // FIXME: The logic here is a bit complicated. Is there a good
1048  // way to simplify it?
1049 
1050  std::string meth_nm = fcn_name.substr (pos+1);
1051 
1052  if (meth_nm.find ('.') == std::string::npos)
1053  {
1054  std::string obj_nm = fcn_name.substr (0, pos);
1055 
1056  // If obj_nm is an object in the current scope with a
1057  // method named meth_nm, create a classsimple handle.
1058 
1059  octave_value object = varval (obj_nm);
1060 
1061  if (object.is_defined () && object.is_classdef_object ())
1062  {
1063  octave_classdef *cdef = object.classdef_object_value ();
1064 
1065  if (cdef)
1066  {
1067  std::string class_nm = cdef->class_name ();
1068 
1069  cdef_object cdef_obj = cdef->get_object ();
1070 
1071  cdef_class cls = cdef_obj.get_class ();
1072 
1073  cdef_method meth = cls.find_method (meth_nm);
1074 
1075  if (meth.ok ())
1076  {
1077  // If the method we found is static, create a
1078  // new function name from the class name and
1079  // method name and create a simple function
1080  // handle below. Otherwise, create a class
1081  // simple function handle.
1082 
1083  if (meth.is_static ())
1084  fcn_name = class_nm + '.' + meth_nm;
1085  else
1086  {
1087  octave_value meth_fcn = meth.get_function ();
1088 
1089  octave_fcn_handle *fh
1090  = new octave_fcn_handle (object, meth_fcn,
1091  class_nm, meth_nm);
1092 
1093  return octave_value (fh);
1094  }
1095  }
1096  }
1097  }
1098  }
1099 
1100  // We didn't match anything above, so create handle to SIMPLE
1101  // package function or static class method. Function resolution
1102  // is performed when the handle is used.
1103 
1104  return octave_value (new octave_fcn_handle (fcn_name));
1105  }
1106 
1107  // If the function name refers to a sub/local/private function or a
1108  // class method/constructor, create scoped function handle that is
1109  // bound to that function. Use the same precedence list as
1110  // fcn_info::find but limit search to the following types of
1111  // functions:
1112  //
1113  // nested functions (and subfunctions)
1114  // local functions in the current file
1115  // private function
1116  // class method
1117  //
1118  // For anything else we create a simple function handle that will be
1119  // resolved dynamically in the scope where it is evaluated.
1120 
1121  symbol_scope curr_scope = get_current_scope ();
1122 
1124 
1125  if (curr_scope)
1126  {
1127  octave_value ov_fcn
1128  = symtab.find_scoped_function (fcn_name, curr_scope);
1129 
1130  if (ov_fcn.is_defined ())
1131  {
1132  octave_function *fcn = ov_fcn.function_value ();
1133 
1134  if (fcn->is_nested_function ())
1135  {
1136  if (! name_is_operator)
1137  {
1138  // Get current stack frame and return handle to nested
1139  // function.
1140 
1141  std::shared_ptr<stack_frame> frame
1143 
1144  octave_fcn_handle *fh
1145  = new octave_fcn_handle (ov_fcn, fcn_name, frame);
1146 
1147  return octave_value (fh);
1148  }
1149  }
1150  else if (fcn->is_subfunction ()
1151  /* || fcn->is_localfunction () */
1152  || fcn->is_private_function ())
1153  {
1154  // Create handle to SCOPED function (sub/local function
1155  // or private function).
1156 
1157  std::list<std::string> parentage = fcn->parent_fcn_names ();
1158 
1159  octave_fcn_handle *fh
1160  = new octave_fcn_handle (ov_fcn, fcn_name, parentage);
1161 
1162  return octave_value (fh);
1163  }
1164  }
1165 
1166  // If name is operator, we are in Fstr2func, so skip the stack
1167  // frame for that function.
1168 
1169  bool skip_first = name_is_operator;
1170  octave_function *curr_fcn = current_function (skip_first);
1171 
1172  if (curr_fcn && (curr_fcn->is_class_method ()
1173  || curr_fcn->is_class_constructor ()))
1174  {
1175  std::string dispatch_class = curr_fcn->dispatch_class ();
1176 
1177  octave_value ov_meth
1178  = symtab.find_method (fcn_name, dispatch_class);
1179 
1180  if (ov_meth.is_defined ())
1181  {
1182  octave_function *fcn = ov_meth.function_value ();
1183 
1184  // FIXME: do we need to check that it is a method of
1185  // dispatch_class, or is it sufficient to just check
1186  // that it is a method?
1187 
1188  if (fcn->is_class_method ())
1189  {
1190  // Create CLASSSIMPLE handle to method but don't
1191  // bind to the method. Lookup will be done later.
1192 
1193  octave_fcn_handle *fh
1194  = new octave_fcn_handle (dispatch_class, fcn_name);
1195 
1196  return octave_value (fh);
1197  }
1198  }
1199  }
1200  }
1201 
1202  octave_value ov_fcn = symtab.find_user_function (fcn_name);
1203 
1204  // Create handle to SIMPLE function. If the function is not found
1205  // now, then we will look for it again when the handle is used.
1206 
1207  return octave_value (new octave_fcn_handle (ov_fcn, fcn_name));
1208  }
1209 
1210 /*
1211 %!test
1212 %! x = {".**", "power";
1213 %! ".'", "transpose";
1214 %! ".+", "plus";
1215 %! ".-", "minus";
1216 %! ".*", "times";
1217 %! "./", "rdivide";
1218 %! ".^", "power";
1219 %! ".\\", "ldivide";
1220 %! "<=", "le";
1221 %! "==", "eq";
1222 %! ">=", "ge";
1223 %! "!=", "ne";
1224 %! "~=", "ne";
1225 %! "**", "mpower";
1226 %! "~", "not";
1227 %! "!", "not";
1228 %! "\'", "ctranspose";
1229 %! "+", "plus";
1230 %! "-", "minus";
1231 %! "*", "mtimes";
1232 %! "/", "mrdivide";
1233 %! "^", "mpower";
1234 %! "\\", "mldivide";
1235 %! "<", "lt";
1236 %! ">", "gt";
1237 %! "&", "and";
1238 %! "|", "or"};
1239 %! for i = 1:rows (x)
1240 %! assert (functions (str2func (x{i,1})).function, x{i,2});
1241 %! endfor
1242 */
1243 
1244  octave_value
1246  {
1247  // Do not allow functions to return null values.
1248 
1249  tree_identifier *id = elt->ident ();
1250 
1251  return id ? id->evaluate (*this).storable_value () : octave_value ();
1252  }
1253 
1254  bool
1255  tree_evaluator::is_variable (const std::string& name) const
1256  {
1257  std::shared_ptr<stack_frame> frame
1259 
1260  return frame->is_variable (name);
1261  }
1262 
1263  bool
1264  tree_evaluator::is_local_variable (const std::string& name) const
1265  {
1266  std::shared_ptr<stack_frame> frame
1268 
1269  return frame->is_local_variable (name);
1270  }
1271 
1272  bool
1274  {
1275  if (expr->is_identifier ())
1276  {
1277  const tree_identifier *id
1278  = dynamic_cast<const tree_identifier *> (expr);
1279 
1280  if (id->is_black_hole ())
1281  return false;
1282 
1283  return is_variable (id->symbol ());
1284  }
1285 
1286  return false;
1287  }
1288 
1289  bool
1291  {
1292  if (expr->is_identifier ())
1293  {
1294  const tree_identifier *id
1295  = dynamic_cast<const tree_identifier *> (expr);
1296 
1297  return is_defined (id->symbol ());
1298  }
1299 
1300  return false;
1301  }
1302 
1303  bool
1305  {
1306  std::shared_ptr<stack_frame> frame
1308 
1309  return frame->is_variable (sym);
1310  }
1311 
1312  bool
1314  {
1315  std::shared_ptr<stack_frame> frame
1317 
1318  return frame->is_defined (sym);
1319  }
1320 
1321  bool tree_evaluator::is_global (const std::string& name) const
1322  {
1323  std::shared_ptr<stack_frame> frame
1325 
1326  return frame->is_global (name);
1327  }
1328 
1329  octave_value
1331  {
1332  std::shared_ptr<stack_frame> frame
1334 
1335  return frame->varval (sym);
1336  }
1337 
1338  octave_value
1339  tree_evaluator::varval (const std::string& name) const
1340  {
1341  std::shared_ptr<stack_frame> frame
1343 
1344  return frame->varval (name);
1345  }
1346 
1347  void tree_evaluator::install_variable (const std::string& name,
1348  const octave_value& value,
1349  bool global)
1350  {
1351  std::shared_ptr<stack_frame> frame
1353 
1354  return frame->install_variable (name, value, global);
1355  }
1356 
1357  octave_value
1358  tree_evaluator::global_varval (const std::string& name) const
1359  {
1360  return m_call_stack.global_varval (name);
1361  }
1362 
1363  octave_value&
1365  {
1366  return m_call_stack.global_varref (name);
1367  }
1368 
1369  void
1371  const octave_value& val)
1372  {
1374  }
1375 
1376  octave_value
1377  tree_evaluator::top_level_varval (const std::string& name) const
1378  {
1380  }
1381 
1382  void
1384  const octave_value& val)
1385  {
1387  }
1388 
1389  void
1390  tree_evaluator::assign (const std::string& name, const octave_value& val)
1391  {
1392  std::shared_ptr<stack_frame> frame
1394 
1395  frame->assign (name, val);
1396  }
1397 
1398  void
1399  tree_evaluator::assignin (const std::string& context,
1400  const std::string& name, const octave_value& val)
1401  {
1402  // FIXME: Can this be done without an unwind-protect frame, simply
1403  // by getting a reference to the caller or base stack frame and
1404  // calling assign on that?
1405 
1406  unwind_action act ([this] (size_t frm)
1407  {
1409  }, m_call_stack.current_frame ());
1410 
1411  if (context == "caller")
1413  else if (context == "base")
1415  else
1416  error ("assignin: CONTEXT must be \"caller\" or \"base\"");
1417 
1418  if (valid_identifier (name))
1419  {
1420  // Put the check here so that we don't slow down assignments
1421  // generally. Any that go through Octave's parser should have
1422  // already been checked.
1423 
1424  if (iskeyword (name))
1425  error ("assignin: invalid assignment to keyword '%s'",
1426  name.c_str ());
1427 
1428  assign (name, val);
1429  }
1430  else
1431  error ("assignin: invalid variable name '%s'", name.c_str ());
1432  }
1433 
1434  void
1435  tree_evaluator::source_file (const std::string& file_name,
1436  const std::string& context,
1437  bool verbose, bool require_file)
1438  {
1439  // Map from absolute name of script file to recursion level. We
1440  // use a map instead of simply placing a limit on recursion in the
1441  // source_file function so that two mutually recursive scripts
1442  // written as
1443  //
1444  // foo1.m:
1445  // ------
1446  // foo2
1447  //
1448  // foo2.m:
1449  // ------
1450  // foo1
1451  //
1452  // and called with
1453  //
1454  // foo1
1455  //
1456  // (for example) will behave the same if they are written as
1457  //
1458  // foo1.m:
1459  // ------
1460  // source ("foo2.m")
1461  //
1462  // foo2.m:
1463  // ------
1464  // source ("foo1.m")
1465  //
1466  // and called with
1467  //
1468  // source ("foo1.m")
1469  //
1470  // (for example).
1471 
1472  static std::map<std::string, int> source_call_depth;
1473 
1474  std::string file_full_name
1475  = sys::file_ops::tilde_expand (file_name);
1476 
1477  size_t pos
1478  = file_full_name.find_last_of (sys::file_ops::dir_sep_str ());
1479 
1480  std::string dir_name = file_full_name.substr (0, pos);
1481 
1482  file_full_name = sys::env::make_absolute (file_full_name);
1483 
1484  unwind_protect frame;
1485 
1486  if (source_call_depth.find (file_full_name) == source_call_depth.end ())
1487  source_call_depth[file_full_name] = -1;
1488 
1489  frame.protect_var (source_call_depth[file_full_name]);
1490 
1491  source_call_depth[file_full_name]++;
1492 
1493  if (source_call_depth[file_full_name] >= max_recursion_depth ())
1494  error ("max_recursion_depth exceeded");
1495 
1496  if (! context.empty ())
1497  {
1500 
1501  if (context == "caller")
1503  else if (context == "base")
1505  else
1506  error ("source: context must be \"caller\" or \"base\"");
1507  }
1508 
1509  // Find symbol name that would be in symbol_table, if it were loaded.
1510  size_t dir_end
1511  = file_name.find_last_of (sys::file_ops::dir_sep_chars ());
1512  dir_end = (dir_end == std::string::npos) ? 0 : dir_end + 1;
1513 
1514  size_t extension = file_name.find_last_of ('.');
1515  if (extension == std::string::npos)
1516  extension = file_name.length ();
1517 
1518  std::string symbol = file_name.substr (dir_end, extension - dir_end);
1519  std::string full_name = sys::canonicalize_file_name (file_name);
1520 
1521  // Check if this file is already loaded (or in the path)
1523  octave_value ov_code = symtab.fcn_table_find (symbol);
1524 
1525  // For compatibility with Matlab, accept both scripts and
1526  // functions.
1527 
1528  if (ov_code.is_user_code ())
1529  {
1530  octave_user_code *code = ov_code.user_code_value ();
1531 
1532  if (! code
1534  != full_name))
1535  {
1536  // Wrong file, so load it below.
1537  ov_code = octave_value ();
1538  }
1539  }
1540  else
1541  {
1542  // Not a script, so load it below.
1543  ov_code = octave_value ();
1544  }
1545 
1546  // If no symbol of this name, or the symbol is for a different
1547  // file, load.
1548 
1549  if (ov_code.is_undefined ())
1550  {
1551  try
1552  {
1553  ov_code = parse_fcn_file (m_interpreter, file_full_name,
1554  file_name, dir_name, "", "",
1555  require_file, true, false, false);
1556  }
1557  catch (execution_exception& e)
1558  {
1559  error (e, "source: error sourcing file '%s'",
1560  file_full_name.c_str ());
1561  }
1562  }
1563 
1564  // Return or error if we don't have a valid script or function.
1565 
1566  if (ov_code.is_undefined ())
1567  return;
1568 
1569  if (! ov_code.is_user_code ())
1570  error ("source: %s is not a script", full_name.c_str ());
1571 
1572  if (verbose)
1573  {
1574  octave_stdout << "executing commands from " << full_name << " ... ";
1575  octave_stdout.flush ();
1576  }
1577 
1578  octave_user_code *code = ov_code.user_code_value ();
1579 
1580  code->call (*this, 0, octave_value_list ());
1581 
1582  if (verbose)
1583  octave_stdout << "done." << std::endl;
1584  }
1585 
1586  void
1588  const octave_value& val)
1589  {
1590  m_call_stack.set_auto_fcn_var (avt, val);
1591  }
1592 
1593  octave_value
1595  {
1596  return m_call_stack.get_auto_fcn_var (avt);
1597  }
1598 
1599  void
1601  (tree_parameter_list *param_list, const octave_value_list& args)
1602  {
1603  int i = -1;
1604 
1605  for (tree_decl_elt *elt : *param_list)
1606  {
1607  i++;
1608 
1609  octave_lvalue ref = elt->lvalue (*this);
1610 
1611  if (i < args.length ())
1612  {
1613  if (args(i).is_defined () && args(i).is_magic_colon ())
1614  {
1615  if (! eval_decl_elt (elt))
1616  error ("no default value for argument %d", i+1);
1617  }
1618  else
1619  ref.define (args(i));
1620  }
1621  else
1622  eval_decl_elt (elt);
1623  }
1624  }
1625 
1626  void
1628  {
1629  for (tree_decl_elt *elt : *param_list)
1630  {
1631  octave_lvalue ref = elt->lvalue (*this);
1632 
1634  }
1635  }
1636 }
1637 
1638 // END is documented in op-kw-docs.
1639 DEFCONSTMETHOD (end, interp, args, ,
1640  doc: /* -*- texinfo -*-
1641 @deftypefn {} {} end
1642 Last element of an array or the end of any @code{for}, @code{parfor},
1643 @code{if}, @code{do}, @code{while}, @code{function}, @code{switch},
1644 @code{try}, or @code{unwind_protect} block.
1645 
1646 As an index of an array, the magic index @qcode{"end"} refers to the
1647 last valid entry in an indexing operation.
1648 
1649 Example:
1650 
1651 @example
1652 @group
1653 @var{x} = [ 1 2 3; 4 5 6 ];
1654 @var{x}(1,end)
1655  @result{} 3
1656 @var{x}(end,1)
1657  @result{} 4
1658 @var{x}(end,end)
1659  @result{} 6
1660 @end group
1661 @end example
1662 @seealso{for, parfor, if, do, while, function, switch, try, unwind_protect}
1663 @end deftypefn */)
1664 {
1665  octave::tree_evaluator& tw = interp.get_evaluator ();
1666 
1667  return tw.evaluate_end_expression (args);
1668 }
1669 
1670 /*
1671 %!test <*58830>
1672 %! fail ("__undef_sym__ (end)",
1673 %! "invalid use of 'end': may only be used to index existing value");
1674 
1675 %!test <58953>
1676 %! x = 1:10;
1677 %! assert (x(end), 10);
1678 %! assert (x(minus (end, 1)), 9);
1679 %! assert (x(minus (minus (end, 1), 1)), 8);
1680 */
1681 
1682 namespace octave
1683 {
1686  {
1687  std::list<octave_value> arg_vals;
1688 
1689  for (auto elt : *args)
1690  {
1691  // FIXME: is it possible for elt to be invalid?
1692 
1693  if (! elt)
1694  break;
1695 
1696  octave_value tmp = elt->evaluate (*this);
1697 
1698  if (tmp.is_cs_list ())
1699  {
1700  octave_value_list tmp_ovl = tmp.list_value ();
1701 
1702  for (octave_idx_type i = 0; i < tmp_ovl.length (); i++)
1703  arg_vals.push_back (tmp_ovl(i));
1704  }
1705  else if (tmp.is_defined ())
1706  arg_vals.push_back (tmp);
1707  }
1708 
1709  return octave_value_list (arg_vals);
1710  }
1711 
1714  (tree_parameter_list *ret_list, int nargout, const Matrix& ignored_outputs,
1715  const Cell& varargout)
1716  {
1717  octave_idx_type vlen = varargout.numel ();
1718  int len = ret_list->length ();
1719 
1720  // Special case. Will do a shallow copy.
1721  if (len == 0)
1722  return varargout;
1723  else
1724  {
1725  int i = 0;
1726  int k = 0;
1727  int num_ignored = ignored_outputs.numel ();
1728  int ignored = num_ignored > 0 ? ignored_outputs(k) - 1 : -1;
1729 
1730  if (nargout <= len)
1731  {
1732  int nout = nargout > 0 ? nargout : 1;
1733  octave_value_list retval (nout);
1734 
1735  for (tree_decl_elt *elt : *ret_list)
1736  {
1737  if (nargout == 0 && ! is_defined (elt->ident ()))
1738  break;
1739 
1740  if (ignored >= 0 && i == ignored)
1741  {
1742  i++;
1743  k++;
1744  ignored = k < num_ignored ? ignored_outputs(k) - 1 : -1;
1745  }
1746  else
1747  retval(i++) = evaluate (elt);
1748 
1749  if (i == nout)
1750  break;
1751  }
1752 
1753  return retval;
1754  }
1755  else
1756  {
1757  octave_value_list retval (len + vlen);
1758 
1759  for (tree_decl_elt *elt : *ret_list)
1760  {
1761  if (ignored >= 0 && i == ignored)
1762  {
1763  i++;
1764  k++;
1765  ignored = k < num_ignored ? ignored_outputs(k) - 1 : -1;
1766  }
1767  else
1768  retval(i++) = evaluate (elt);
1769  }
1770 
1771  for (octave_idx_type j = 0; j < vlen; j++)
1772  retval(i++) = varargout(j);
1773 
1774  return retval;
1775  }
1776  }
1777  }
1778 
1779  bool
1781  {
1782  bool retval = false;
1783 
1784  tree_identifier *id = elt->ident ();
1785  tree_expression *expr = elt->expression ();
1786 
1787  if (id && expr)
1788  {
1789  octave_lvalue ult = id->lvalue (*this);
1790 
1791  octave_value init_val = expr->evaluate (*this);
1792 
1793  ult.assign (octave_value::op_asn_eq, init_val);
1794 
1795  retval = true;
1796  }
1797 
1798  return retval;
1799  }
1800 
1801  bool
1803  const octave_value& val)
1804  {
1805  tree_expression *label = expr->case_label ();
1806 
1807  octave_value label_value = label->evaluate (*this);
1808 
1809  if (label_value.is_defined ())
1810  {
1811  if (label_value.iscell ())
1812  {
1813  Cell cell (label_value.cell_value ());
1814 
1815  for (octave_idx_type i = 0; i < cell.rows (); i++)
1816  {
1817  for (octave_idx_type j = 0; j < cell.columns (); j++)
1818  {
1819  bool match = val.is_equal (cell(i,j));
1820 
1821  if (match)
1822  return true;
1823  }
1824  }
1825  }
1826  else
1827  return val.is_equal (label_value);
1828  }
1829 
1830  return false;
1831  }
1832 
1834  {
1835  m_call_stack.push (scope);
1836  }
1837 
1839  const std::shared_ptr<stack_frame>& closure_frames)
1840  {
1841  m_call_stack.push (fcn, closure_frames);
1842  }
1843 
1845  const stack_frame::local_vars_map& local_vars)
1846  {
1847  m_call_stack.push (fcn, local_vars);
1848  }
1849 
1851  {
1852  m_call_stack.push (script);
1853  }
1854 
1856  {
1857  m_call_stack.push (fcn);
1858  }
1859 
1861  {
1862  m_call_stack.pop ();
1863  }
1864 
1866  {
1867  return m_call_stack.current_line ();
1868  }
1869 
1871  {
1872  return m_call_stack.current_column ();
1873  }
1874 
1876  {
1878  }
1879 
1881  {
1883  }
1884 
1885  void tree_evaluator::debug_where (std::ostream& os) const
1886  {
1887  std::shared_ptr<stack_frame> frm = m_call_stack.current_user_frame ();
1888 
1889  frm->display_stopped_in_message (os);
1890  }
1891 
1893  {
1894  return m_call_stack.current_user_code ();
1895  }
1896 
1898  {
1900  }
1901 
1903  {
1904  return m_call_stack.debug_user_code ();
1905  }
1906 
1908  {
1909  return m_call_stack.current_function (skip_first);
1910  }
1911 
1913  {
1914  return m_call_stack.current_function (true);
1915  }
1916 
1917  bool tree_evaluator::goto_frame (size_t n, bool verbose)
1918  {
1919  return m_call_stack.goto_frame (n, verbose);
1920  }
1921 
1923  {
1925  }
1926 
1928  {
1930  }
1931 
1933  {
1934  return m_call_stack.restore_frame (n);
1935  }
1936 
1937  std::string tree_evaluator::get_dispatch_class (void) const
1938  {
1939  return m_call_stack.get_dispatch_class ();
1940  }
1941 
1942  void tree_evaluator::set_dispatch_class (const std::string& class_name)
1943  {
1944  m_call_stack.set_dispatch_class (class_name);
1945  }
1946 
1947  bool
1948  tree_evaluator::is_class_method_executing (std::string& dclass) const
1949  {
1950  return m_call_stack.is_class_method_executing (dclass);
1951  }
1952 
1953  bool
1955  {
1957  }
1958 
1959  std::list<std::shared_ptr<stack_frame>>
1961  {
1962  return m_call_stack.backtrace_frames (curr_user_frame);
1963  }
1964 
1965  std::list<std::shared_ptr<stack_frame>>
1967  {
1968  return m_call_stack.backtrace_frames ();
1969  }
1970 
1971  std::list<frame_info>
1973  bool print_subfn) const
1974  {
1975  return m_call_stack.backtrace_info (curr_user_frame, print_subfn);
1976  }
1977 
1978  std::list<frame_info> tree_evaluator::backtrace_info (void) const
1979  {
1980  return m_call_stack.backtrace_info ();
1981  }
1982 
1983  octave_map
1985  bool print_subfn) const
1986  {
1987  return m_call_stack.backtrace (curr_user_frame, print_subfn);
1988  }
1989 
1991  {
1992  return m_call_stack.backtrace ();
1993  }
1994 
1996  {
1997  return m_call_stack.empty_backtrace ();
1998  }
1999 
2000  std::string tree_evaluator::backtrace_message (void) const
2001  {
2002  std::list<frame_info> frames = backtrace_info ();
2003 
2004  std::ostringstream buf;
2005 
2006  for (const auto& frm : frames)
2007  {
2008  buf << " " << frm.fcn_name ();
2009 
2010  int line = frm.line ();
2011 
2012  if (line > 0)
2013  {
2014  buf << " at line " << line;
2015 
2016  int column = frm.column ();
2017 
2018  if (column > 0)
2019  buf << " column " << column;
2020 
2021  buf << "\n";
2022  }
2023  }
2024 
2025  return buf.str ();
2026  }
2027 
2028  void tree_evaluator::push_dummy_scope (const std::string& name)
2029  {
2030  symbol_scope dummy_scope (name + "$dummy");
2031 
2032  m_call_stack.push (dummy_scope);
2033  }
2034 
2036  {
2037  m_call_stack.pop ();
2038  }
2039 
2041  {
2042  return m_call_stack.top_scope ();
2043  }
2044 
2046  {
2047  return m_call_stack.current_scope ();
2048  }
2049 
2050  void tree_evaluator::mlock (bool skip_first) const
2051  {
2052  octave_function *fcn = m_call_stack.current_function (skip_first);
2053 
2054  if (! fcn)
2055  error ("mlock: invalid use outside a function");
2056 
2057  if (fcn->is_builtin_function ())
2058  {
2059  warning ("mlock: locking built-in function has no effect");
2060  return;
2061  }
2062 
2063  fcn->lock ();
2064  }
2065 
2066  void tree_evaluator::munlock (bool skip_first) const
2067  {
2068  octave_function *fcn = m_call_stack.current_function (skip_first);
2069 
2070  if (! fcn)
2071  error ("munlock: invalid use outside a function");
2072 
2073  if (fcn->is_builtin_function ())
2074  {
2075  warning ("munlock: unlocking built-in function has no effect");
2076  return;
2077  }
2078 
2079  fcn->unlock ();
2080  }
2081 
2082  bool tree_evaluator::mislocked (bool skip_first) const
2083  {
2084  octave_function *fcn = m_call_stack.current_function (skip_first);
2085 
2086  if (! fcn)
2087  error ("mislocked: invalid use outside a function");
2088 
2089  return fcn->islocked ();
2090  }
2091 
2092  octave_value
2094  {
2095  return m_call_stack.max_stack_depth (args, nargout);
2096  }
2097 
2099  {
2100  m_call_stack.display ();
2101  }
2102 
2104  {
2105  std::shared_ptr<stack_frame> frame
2107 
2108  octave_value val = frame->varval (name);
2109 
2110  if (val.is_defined ())
2111  return val;
2112 
2113  // Subfunction. I think it only makes sense to check for
2114  // subfunctions if we are currently executing a function defined
2115  // from a .m file.
2116 
2117  octave_value fcn = frame->find_subfunction (name);
2118 
2119  if (fcn.is_defined ())
2120  return fcn;
2121 
2123 
2124  return symtab.fcn_table_find (name, ovl ());
2125  }
2126 
2128  {
2129  std::shared_ptr<stack_frame> frame
2131 
2132  frame->clear_objects ();
2133  }
2134 
2135  void tree_evaluator::clear_variable (const std::string& name)
2136  {
2137  std::shared_ptr<stack_frame> frame
2139 
2140  frame->clear_variable (name);
2141  }
2142 
2143  void tree_evaluator::clear_variable_pattern (const std::string& pattern)
2144  {
2145  std::shared_ptr<stack_frame> frame
2147 
2148  frame->clear_variable_pattern (pattern);
2149  }
2150 
2151  void tree_evaluator::clear_variable_regexp (const std::string& pattern)
2152  {
2153  std::shared_ptr<stack_frame> frame
2155 
2156  frame->clear_variable_regexp (pattern);
2157  }
2158 
2160  {
2161  std::shared_ptr<stack_frame> frame
2163 
2164  frame->clear_variables ();
2165  }
2166 
2168  {
2170  }
2171 
2172  void
2174  {
2176  }
2177 
2178  void tree_evaluator::clear_global_variable_regexp(const std::string& pattern)
2179  {
2181  }
2182 
2184  {
2186  }
2187 
2188  void tree_evaluator::clear_all (bool force)
2189  {
2190  // FIXME: should this also clear objects?
2191 
2192  clear_variables ();
2194 
2196 
2197  symtab.clear_functions (force);
2198  }
2199 
2200  void tree_evaluator::clear_symbol (const std::string& name)
2201  {
2202  // FIXME: are we supposed to do both here?
2203 
2204  clear_variable (name);
2205 
2207 
2208  symtab.clear_function (name);
2209  }
2210 
2211  void tree_evaluator::clear_symbol_pattern (const std::string& pattern)
2212  {
2213  // FIXME: are we supposed to do both here?
2214 
2215  clear_variable_pattern (pattern);
2216 
2218 
2219  symtab.clear_function_pattern (pattern);
2220  }
2221 
2222  void tree_evaluator::clear_symbol_regexp (const std::string& pattern)
2223  {
2224  // FIXME: are we supposed to do both here?
2225 
2226  clear_variable_regexp (pattern);
2227 
2229 
2230  symtab.clear_function_regexp (pattern);
2231  }
2232 
2233  std::list<std::string> tree_evaluator::global_variable_names (void) const
2234  {
2236  }
2237 
2238  std::list<std::string> tree_evaluator::top_level_variable_names (void) const
2239  {
2241  }
2242 
2243  std::list<std::string> tree_evaluator::variable_names (void) const
2244  {
2245  return m_call_stack.variable_names ();
2246  }
2247 
2248  // Return a pointer to the user-defined function FNAME. If FNAME is empty,
2249  // search backward for the first user-defined function in the
2250  // current call stack.
2251 
2253  tree_evaluator::get_user_code (const std::string& fname,
2254  const std::string& class_name)
2255  {
2256  octave_user_code *user_code = nullptr;
2257 
2258  if (fname.empty ())
2259  user_code = m_call_stack.debug_user_code ();
2260  else
2261  {
2262  std::string name = fname;
2263 
2264  if (sys::file_ops::dir_sep_char () != '/' && name[0] == '@')
2265  {
2266  auto beg = name.begin () + 2; // never have @/method
2267  auto end = name.end () - 1; // never have trailing '/'
2268  std::replace (beg, end, '/', sys::file_ops::dir_sep_char ());
2269  }
2270 
2271  size_t name_len = name.length ();
2272 
2273  if (name_len > 2 && name.substr (name_len-2) == ".m")
2274  name = name.substr (0, name_len-2);
2275 
2276  if (name.empty ())
2277  return nullptr;
2278 
2280 
2281  octave_value fcn;
2282  size_t p2 = std::string::npos;
2283 
2284  if (name[0] == '@')
2285  {
2286  size_t p1 = name.find (sys::file_ops::dir_sep_char (), 1);
2287 
2288  if (p1 == std::string::npos)
2289  return nullptr;
2290 
2291  std::string dispatch_type = name.substr (1, p1-1);
2292 
2293  p2 = name.find ('>', p1);
2294 
2295  std::string method = name.substr (p1+1, p2-1);
2296 
2297  fcn = symtab.find_method (method, dispatch_type);
2298  }
2299  else if (! class_name.empty ())
2300  {
2302 
2303  fcn = cdm.find_method (class_name, name);
2304 
2305  // If there is no classdef method, then try legacy classes.
2306  if (fcn.is_undefined ())
2307  fcn = symtab.find_method (name, class_name);
2308  }
2309  else
2310  {
2311  p2 = name.find ('>');
2312 
2313  std::string main_fcn = name.substr (0, p2);
2314 
2315  fcn = symtab.find_function (main_fcn);
2316  }
2317 
2318  // List of function names sub1>sub2>...
2319  std::string subfuns;
2320 
2321  if (p2 != std::string::npos)
2322  subfuns = name.substr (p2+1);
2323 
2324  if (fcn.is_defined () && fcn.is_user_code ())
2325  user_code = fcn.user_code_value ();
2326 
2327  if (! user_code || subfuns.empty ())
2328  return user_code;
2329 
2330  fcn = user_code->find_subfunction (subfuns);
2331 
2332  if (fcn.is_undefined ())
2333  return nullptr;
2334 
2335  user_code = fcn.user_code_value ();
2336  }
2337 
2338  return user_code;
2339  }
2340 
2341  std::string
2343  {
2344  octave_function *curfcn = m_call_stack.current_function (skip_first);
2345 
2346  if (curfcn)
2347  return curfcn->name ();
2348 
2349  return "";
2350  }
2351 
2352  bool
2354  {
2355  return m_call_stack.current_user_code () != nullptr;
2356  }
2357 
2358  void
2360  {
2361  if (m_echo_state)
2362  {
2363  size_t line = cmd.line ();
2364  echo_code (line);
2365  m_echo_file_pos = line + 1;
2366  }
2367 
2368  if (m_debug_mode)
2369  do_breakpoint (cmd.is_active_breakpoint (*this));
2370 
2371  // FIXME: tree_decl_init_list is not derived from tree, so should it
2372  // really have an accept method?
2373 
2374  tree_decl_init_list *init_list = cmd.initializer_list ();
2375 
2376  if (init_list)
2377  init_list->accept (*this);
2378  }
2379 
2380  void
2382  {
2383  tree_identifier *id = elt.ident ();
2384 
2385  if (id)
2386  {
2387  if (elt.is_global ())
2388  m_call_stack.make_global (id->symbol ());
2389  else if (elt.is_persistent ())
2391  else
2392  error ("declaration list element not global or persistent");
2393 
2394  octave_lvalue ult = id->lvalue (*this);
2395 
2396  if (ult.is_undefined ())
2397  {
2398  tree_expression *expr = elt.expression ();
2399 
2400  octave_value init_val;
2401 
2402  if (expr)
2403  init_val = expr->evaluate (*this);
2404  else
2405  init_val = Matrix ();
2406 
2407  ult.assign (octave_value::op_asn_eq, init_val);
2408  }
2409  }
2410  }
2411 
2412  void
2414  {
2415  size_t line = cmd.line ();
2416 
2417  if (m_echo_state)
2418  {
2419  echo_code (line);
2420  line++;
2421  }
2422 
2423  if (m_debug_mode)
2424  do_breakpoint (cmd.is_active_breakpoint (*this));
2425 
2426  // FIXME: need to handle PARFOR loops here using cmd.in_parallel ()
2427  // and cmd.maxproc_expr ();
2428 
2430 
2431  tree_expression *expr = cmd.control_expr ();
2432 
2433  octave_value rhs = expr->evaluate (*this);
2434 
2435 #if defined (HAVE_LLVM)
2436  if (tree_jit::execute (cmd, rhs))
2437  return;
2438 #endif
2439 
2440  if (rhs.is_undefined ())
2441  return;
2442 
2443  tree_expression *lhs = cmd.left_hand_side ();
2444 
2445  octave_lvalue ult = lhs->lvalue (*this);
2446 
2447  tree_statement_list *loop_body = cmd.body ();
2448 
2449  if (rhs.is_range ())
2450  {
2451  Range rng = rhs.range_value ();
2452 
2453  octave_idx_type steps = rng.numel ();
2454 
2455  for (octave_idx_type i = 0; i < steps; i++)
2456  {
2457  if (m_echo_state)
2459 
2460  octave_value val (rng.elem (i));
2461 
2462  ult.assign (octave_value::op_asn_eq, val);
2463 
2464  if (loop_body)
2465  loop_body->accept (*this);
2466 
2467  if (quit_loop_now ())
2468  break;
2469  }
2470  }
2471  else if (rhs.is_scalar_type ())
2472  {
2473  if (m_echo_state)
2475 
2476  ult.assign (octave_value::op_asn_eq, rhs);
2477 
2478  if (loop_body)
2479  loop_body->accept (*this);
2480 
2481  // Maybe decrement break and continue states.
2482  quit_loop_now ();
2483  }
2484  else if (rhs.is_matrix_type () || rhs.iscell () || rhs.is_string ()
2485  || rhs.isstruct ())
2486  {
2487  // A matrix or cell is reshaped to 2 dimensions and iterated by
2488  // columns.
2489 
2490  dim_vector dv = rhs.dims ().redim (2);
2491 
2492  octave_idx_type nrows = dv(0);
2493  octave_idx_type steps = dv(1);
2494 
2495  octave_value arg = rhs;
2496  if (rhs.ndims () > 2)
2497  arg = arg.reshape (dv);
2498 
2499  if (nrows > 0 && steps > 0)
2500  {
2501  octave_value_list idx;
2502  octave_idx_type iidx;
2503 
2504  // for row vectors, use single index to speed things up.
2505  if (nrows == 1)
2506  {
2507  idx.resize (1);
2508  iidx = 0;
2509  }
2510  else
2511  {
2512  idx.resize (2);
2513  idx(0) = octave_value::magic_colon_t;
2514  iidx = 1;
2515  }
2516 
2517  for (octave_idx_type i = 1; i <= steps; i++)
2518  {
2519  if (m_echo_state)
2521 
2522  // do_index_op expects one-based indices.
2523  idx(iidx) = i;
2524  octave_value val = arg.do_index_op (idx);
2525 
2526  ult.assign (octave_value::op_asn_eq, val);
2527 
2528  if (loop_body)
2529  loop_body->accept (*this);
2530 
2531  if (quit_loop_now ())
2532  break;
2533  }
2534  }
2535  else
2536  {
2537  // Handle empty cases, while still assigning to loop var.
2538  ult.assign (octave_value::op_asn_eq, arg);
2539  }
2540  }
2541  else
2542  error ("invalid type in for loop expression near line %d, column %d",
2543  cmd.line (), cmd.column ());
2544  }
2545 
2546  void
2548  {
2549  size_t line = cmd.line ();
2550 
2551  if (m_echo_state)
2552  {
2553  echo_code (line);
2554  line++;
2555  }
2556 
2557  if (m_debug_mode)
2558  do_breakpoint (cmd.is_active_breakpoint (*this));
2559 
2561 
2562  tree_expression *expr = cmd.control_expr ();
2563 
2564  octave_value rhs = expr->evaluate (*this);
2565 
2566  if (rhs.is_undefined ())
2567  return;
2568 
2569  if (! rhs.isstruct ())
2570  error ("in statement 'for [X, Y] = VAL', VAL must be a structure");
2571 
2572  // Cycle through structure elements. First element of id_list
2573  // is set to value and the second is set to the name of the
2574  // structure element.
2575 
2576  tree_argument_list *lhs = cmd.left_hand_side ();
2577 
2578  auto p = lhs->begin ();
2579 
2580  tree_expression *elt = *p++;
2581 
2582  octave_lvalue val_ref = elt->lvalue (*this);
2583 
2584  elt = *p;
2585 
2586  octave_lvalue key_ref = elt->lvalue (*this);
2587 
2588  const octave_map tmp_val = rhs.map_value ();
2589 
2590  tree_statement_list *loop_body = cmd.body ();
2591 
2592  string_vector keys = tmp_val.keys ();
2593 
2594  octave_idx_type nel = keys.numel ();
2595 
2596  for (octave_idx_type i = 0; i < nel; i++)
2597  {
2598  if (m_echo_state)
2600 
2601  std::string key = keys[i];
2602 
2603  const Cell val_lst = tmp_val.contents (key);
2604 
2605  octave_idx_type n = val_lst.numel ();
2606 
2607  octave_value val = (n == 1) ? val_lst(0) : octave_value (val_lst);
2608 
2609  val_ref.assign (octave_value::op_asn_eq, val);
2610  key_ref.assign (octave_value::op_asn_eq, key);
2611 
2612  if (loop_body)
2613  loop_body->accept (*this);
2614 
2615  if (quit_loop_now ())
2616  break;
2617  }
2618  }
2619 
2620  void
2622  {
2623  // ??
2624  panic_impossible ();
2625  }
2626 
2629  int nargout,
2630  const octave_value_list& args)
2631  {
2633 
2634  std::string file_name = user_script.fcn_file_name ();
2635 
2636  if (args.length () != 0 || nargout != 0)
2637  error ("invalid call to script %s", file_name.c_str ());
2638 
2639  tree_statement_list *cmd_list = user_script.body ();
2640 
2641  if (! cmd_list)
2642  return retval;
2643 
2644  if (m_call_stack.size () >= static_cast<size_t> (m_max_recursion_depth))
2645  error ("max_recursion_depth exceeded");
2646 
2648 
2649  profiler::enter<octave_user_script> block (m_profiler, user_script);
2650 
2651  if (echo ())
2653 
2654  cmd_list->accept (*this);
2655 
2656  if (m_returning)
2657  m_returning = 0;
2658 
2659  if (m_breaking)
2660  m_breaking--;
2661 
2662  return retval;
2663  }
2664 
2665  void
2667  {
2668  // ??
2669  panic_impossible ();
2670  }
2671 
2674  int nargout,
2675  const octave_value_list& xargs)
2676  {
2678 
2679  tree_statement_list *cmd_list = user_function.body ();
2680 
2681  if (! cmd_list)
2682  return retval;
2683 
2684  // If this function is a classdef constructor, extract the first input
2685  // argument, which must be the partially constructed object instance.
2686 
2687  octave_value_list args (xargs);
2688  octave_value_list ret_args;
2689 
2690  if (user_function.is_classdef_constructor ())
2691  {
2692  if (args.length () > 0)
2693  {
2694  ret_args = args.slice (0, 1, true);
2695  args = args.slice (1, args.length () - 1, true);
2696  }
2697  else
2698  panic_impossible ();
2699  }
2700 
2701 #if defined (HAVE_LLVM)
2702  if (user_function.is_special_expr ()
2704  return retval;
2705 #endif
2706 
2707  if (m_call_stack.size () >= static_cast<size_t> (m_max_recursion_depth))
2708  error ("max_recursion_depth exceeded");
2709 
2710  Matrix ignored_outputs = ignored_fcn_outputs ();
2711 
2712  bind_auto_fcn_vars (xargs.name_tags (), ignored_outputs, args.length (),
2713  nargout, user_function.takes_varargs (),
2714  user_function.all_va_args (args));
2715 
2716  tree_parameter_list *param_list = user_function.parameter_list ();
2717 
2718  if (param_list && ! param_list->varargs_only ())
2719  define_parameter_list_from_arg_vector (param_list, args);
2720 
2721  // For classdef constructor, pre-populate the output arguments
2722  // with the pre-initialized object instance, extracted above.
2723 
2724  tree_parameter_list *ret_list = user_function.return_list ();
2725 
2726  if (user_function.is_classdef_constructor ())
2727  {
2728  if (! ret_list)
2729  error ("%s: invalid classdef constructor, no output argument defined",
2730  user_function.dispatch_class ().c_str ());
2731 
2732  define_parameter_list_from_arg_vector (ret_list, ret_args);
2733  }
2734 
2735  unwind_action act2 ([&user_function] () {
2736  user_function.restore_warning_states ();
2737  });
2738 
2739  // Evaluate the commands that make up the function.
2740 
2742 
2743  unwind_action act1 ([] (std::shared_ptr<stack_frame> frame)
2744  {
2745  frame->clear_values ();
2747 
2748  {
2750 
2751  if (echo ())
2753  user_function.fcn_file_name ());
2754 
2755  if (user_function.is_special_expr ())
2756  {
2757  assert (cmd_list->length () == 1);
2758 
2759  tree_statement *stmt = cmd_list->front ();
2760 
2761  tree_expression *expr = stmt->expression ();
2762 
2763  if (expr)
2764  {
2765  m_call_stack.set_location (stmt->line (), stmt->column ());
2766 
2767  retval = expr->evaluate_n (*this, nargout);
2768  }
2769  }
2770  else
2771  cmd_list->accept (*this);
2772  }
2773 
2774  if (m_returning)
2775  m_returning = 0;
2776 
2777  if (m_breaking)
2778  m_breaking--;
2779 
2780  // Copy return values out.
2781 
2782  if (ret_list && ! user_function.is_special_expr ())
2783  {
2784  Cell varargout;
2785 
2786  if (ret_list->takes_varargs ())
2787  {
2788  octave_value varargout_varval = varval ("varargout");
2789 
2790  if (varargout_varval.is_defined ())
2791  varargout = varargout_varval.xcell_value ("varargout must be a cell array object");
2792  }
2793 
2794  retval = convert_return_list_to_const_vector (ret_list, nargout,
2795  ignored_outputs,
2796  varargout);
2797  }
2798 
2799  return retval;
2800  }
2801 
2802  void
2804  {
2805  panic_impossible ();
2806  }
2807 
2808  void
2810  {
2811  panic_impossible ();
2812  }
2813 
2814  void
2816  {
2817  octave_value fcn = cmd.function ();
2818 
2819  octave_function *f = fcn.function_value ();
2820 
2821  if (f)
2822  {
2823  std::string nm = f->name ();
2824 
2826 
2827  symtab.install_cmdline_function (nm, fcn);
2828 
2829  // Make sure that any variable with the same name as the new
2830  // function is cleared.
2831 
2832  assign (nm);
2833  }
2834  }
2835 
2836  void
2838  {
2839  panic_impossible ();
2840  }
2841 
2842  void
2844  {
2845  panic_impossible ();
2846  }
2847 
2848  void
2850  {
2851  if (m_echo_state)
2852  {
2853  size_t line = cmd.line ();
2854  echo_code (line);
2855  m_echo_file_pos = line + 1;
2856  }
2857 
2858  // FIXME: tree_if_command_list is not derived from tree, so should it
2859  // really have an accept method?
2860 
2861  tree_if_command_list *lst = cmd.cmd_list ();
2862 
2863  if (lst)
2864  lst->accept (*this);
2865  }
2866 
2867  void
2869  {
2870  for (tree_if_clause *tic : lst)
2871  {
2872  tree_expression *expr = tic->condition ();
2873 
2874  if (! (in_debug_repl ()
2876  m_call_stack.set_location (tic->line (), tic->column ());
2877 
2878  if (m_debug_mode && ! tic->is_else_clause ())
2879  do_breakpoint (tic->is_active_breakpoint (*this));
2880 
2881  if (tic->is_else_clause () || is_logically_true (expr, "if"))
2882  {
2883  tree_statement_list *stmt_lst = tic->commands ();
2884 
2885  if (stmt_lst)
2886  stmt_lst->accept (*this);
2887 
2888  break;
2889  }
2890  }
2891  }
2892 
2893  void
2895  {
2896  panic_impossible ();
2897  }
2898 
2899  void
2901  {
2902  panic_impossible ();
2903  }
2904 
2905  void
2907  {
2908  panic_impossible ();
2909  }
2910 
2911  void
2913  {
2914  panic_impossible ();
2915  }
2916 
2917  void
2919  {
2920  if (m_echo_state)
2921  {
2922  size_t line = cmd.line ();
2923  echo_code (line);
2924  m_echo_file_pos = line + 1;
2925  }
2926 
2927  if (m_debug_mode && cmd.is_end_of_fcn_or_script ())
2928  do_breakpoint (cmd.is_active_breakpoint (*this), true);
2929  }
2930 
2931  void
2933  {
2934  panic_impossible ();
2935  }
2936 
2937  void
2939  {
2940  panic_impossible ();
2941  }
2942 
2943  void
2945  {
2946  panic_impossible ();
2947  }
2948 
2949  void
2951  {
2952  panic_impossible ();
2953  }
2954 
2955  void
2957  {
2958  panic_impossible ();
2959  }
2960 
2961  void
2963  {
2964  if (m_echo_state)
2965  {
2966  size_t line = cmd.line ();
2967  echo_code (line);
2968  m_echo_file_pos = line + 1;
2969  }
2970 
2971  if (m_debug_mode)
2972  do_breakpoint (cmd.is_active_breakpoint (*this));
2973 
2974  // Act like dbcont.
2975 
2977  dbcont ();
2978  else if (m_statement_context == SC_FUNCTION
2980  || m_in_loop_command)
2981  m_returning = 1;
2982  }
2983 
2984  void
2986  {
2987  panic_impossible ();
2988  }
2989 
2990  void
2992  {
2993  tree_command *cmd = stmt.command ();
2994  tree_expression *expr = stmt.expression ();
2995 
2996  if (cmd || expr)
2997  {
2998  if (! (in_debug_repl ()
3000  m_call_stack.set_location (stmt.line (), stmt.column ());
3001 
3002  try
3003  {
3004  if (cmd)
3005  {
3007  upv (m_lvalue_list, nullptr);
3008 
3009  cmd->accept (*this);
3010  }
3011  else
3012  {
3013  if (m_echo_state)
3014  {
3015  size_t line = stmt.line ();
3016  echo_code (line);
3017  m_echo_file_pos = line + 1;
3018  }
3019 
3020  if (m_debug_mode)
3021  do_breakpoint (expr->is_active_breakpoint (*this));
3022 
3023  // FIXME: maybe all of this should be packaged in
3024  // one virtual function that returns a flag saying whether
3025  // or not the expression will take care of binding ans and
3026  // printing the result.
3027 
3028  // FIXME: it seems that we should just have to
3029  // evaluate the expression and that should take care of
3030  // everything, binding ans as necessary?
3031 
3032  octave_value tmp_result = expr->evaluate (*this, 0);
3033 
3034  if (tmp_result.is_defined ())
3035  {
3036  bool do_bind_ans = false;
3037 
3038  if (expr->is_identifier ())
3039  do_bind_ans = ! is_variable (expr);
3040  else
3041  do_bind_ans = ! expr->is_assignment_expression ();
3042 
3043  if (do_bind_ans)
3044  bind_ans (tmp_result, expr->print_result ()
3046  }
3047  }
3048  }
3049  catch (const std::bad_alloc&)
3050  {
3051  // FIXME: We want to use error_with_id here so that give users
3052  // control over this error message but error_with_id will
3053  // require some memory allocations. Is there anything we can
3054  // do to make those more likely to succeed?
3055 
3056  error_with_id ("Octave:bad-alloc",
3057  "out of memory or dimension too large for Octave's index type");
3058  }
3059  catch (const interrupt_exception&)
3060  {
3061  // If we are debugging, then continue with next statement.
3062  // Otherwise, jump out of here.
3063 
3064  if (m_debug_mode)
3066  else
3067  throw;
3068  }
3069  catch (const execution_exception& ee)
3070  {
3072 
3073  if ((m_interpreter.interactive ()
3075  && ((es.debug_on_error ()
3077  || (es.debug_on_caught ()
3079  && in_user_code ())
3080  {
3081  es.save_exception (ee);
3082  es.display_exception (ee, std::cerr);
3083 
3084  enter_debugger ();
3085 
3086  // It doesn't make sense to continue execution after an
3087  // error occurs so force the debugger to quit all debug
3088  // levels and return the the top prompt.
3089 
3090  throw quit_debug_exception (true);
3091  }
3092  else
3093  throw;
3094  }
3095  }
3096  }
3097 
3098  void
3100  {
3101  // FIXME: commented out along with else clause below.
3102  // static octave_value_list empty_list;
3103 
3104  auto p = lst.begin ();
3105 
3106  if (p != lst.end ())
3107  {
3108  while (true)
3109  {
3110  tree_statement *elt = *p++;
3111 
3112  if (! elt)
3113  error ("invalid statement found in statement list!");
3114 
3115  octave_quit ();
3116 
3117  elt->accept (*this);
3118 
3119  if (m_breaking || m_continuing)
3120  break;
3121 
3122  if (m_returning)
3123  break;
3124 
3125  if (p == lst.end ())
3126  break;
3127  else
3128  {
3129  // Clear previous values before next statement is
3130  // evaluated so that we aren't holding an extra
3131  // reference to a value that may be used next. For
3132  // example, in code like this:
3133  //
3134  // X = rand (N); # refcount for X should be 1
3135  // # after this statement
3136  //
3137  // X(idx) = val; # no extra copy of X should be
3138  // # needed, but we will be faked
3139  // # out if retval is not cleared
3140  // # between statements here
3141 
3142  // result_values = empty_list;
3143  }
3144  }
3145  }
3146  }
3147 
3148  void
3150  {
3151  panic_impossible ();
3152  }
3153 
3154  void
3156  {
3157  panic_impossible ();
3158  }
3159 
3160  void
3162  {
3163  if (m_echo_state)
3164  {
3165  size_t line = cmd.line ();
3166  echo_code (line);
3167  m_echo_file_pos = line + 1;
3168  }
3169 
3170  if (m_debug_mode)
3171  do_breakpoint (cmd.is_active_breakpoint (*this));
3172 
3173  tree_expression *expr = cmd.switch_value ();
3174 
3175  if (! expr)
3176  error ("missing value in switch command near line %d, column %d",
3177  cmd.line (), cmd.column ());
3178 
3179  octave_value val = expr->evaluate (*this);
3180 
3181  tree_switch_case_list *lst = cmd.case_list ();
3182 
3183  if (lst)
3184  {
3185  for (tree_switch_case *t : *lst)
3186  {
3187  if (t->is_default_case () || switch_case_label_matches (t, val))
3188  {
3189  tree_statement_list *stmt_lst = t->commands ();
3190 
3191  if (stmt_lst)
3192  stmt_lst->accept (*this);
3193 
3194  break;
3195  }
3196  }
3197  }
3198  }
3199 
3200  void
3202  {
3203  if (m_echo_state)
3204  {
3205  size_t line = cmd.line ();
3206  echo_code (line);
3207  m_echo_file_pos = line + 1;
3208  }
3209 
3210  bool execution_error = false;
3211  octave_scalar_map err_map;
3212 
3213  tree_statement_list *try_code = cmd.body ();
3214 
3215  if (try_code)
3216  {
3217  // unwind frame before catch block
3218 
3219  unwind_protect frame;
3220 
3221  interpreter_try (frame);
3222 
3223  // The catch code is *not* added to unwind_protect stack; it
3224  // doesn't need to be run on interrupts.
3225 
3226  try
3227  {
3228  try_code->accept (*this);
3229  }
3230  catch (const execution_exception& ee)
3231  {
3232  execution_error = true;
3233 
3235 
3236  es.save_exception (ee);
3237 
3238  err_map.assign ("message", es.last_error_message ());
3239  err_map.assign ("identifier", es.last_error_id ());
3240  err_map.assign ("stack", es.last_error_stack ());
3241 
3243  }
3244 
3245  // Actions attached to unwind_protect frame will run here, prior
3246  // to executing the catch block.
3247  }
3248 
3249  if (execution_error)
3250  {
3251  tree_statement_list *catch_code = cmd.cleanup ();
3252 
3253  if (catch_code)
3254  {
3255  tree_identifier *expr_id = cmd.identifier ();
3256 
3257  if (expr_id)
3258  {
3259  octave_lvalue ult = expr_id->lvalue (*this);
3260 
3261  ult.assign (octave_value::op_asn_eq, err_map);
3262  }
3263 
3264  // perform actual "catch" block
3265  catch_code->accept (*this);
3266  }
3267  }
3268  }
3269 
3270  void
3272  {
3273  unwind_protect frame;
3274 
3277 
3278  // We want to preserve the last location info for possible
3279  // backtracking.
3280 
3285 
3286  // Similarly, if we have seen a return or break statement, allow all
3287  // the cleanup code to run before returning or handling the break.
3288  // We don't have to worry about continue statements because they can
3289  // only occur in loops.
3290 
3291  frame.protect_var (m_returning);
3292  m_returning = 0;
3293 
3294  frame.protect_var (m_breaking);
3295  m_breaking = 0;
3296 
3297  try
3298  {
3299  if (list)
3300  list->accept (*this);
3301  }
3302  catch (const execution_exception& ee)
3303  {
3305 
3306  es.save_exception (ee);
3308 
3309  if (m_breaking || m_returning)
3310  frame.discard (2);
3311  else
3312  frame.run (2);
3313 
3314  frame.discard (2);
3315 
3316  throw;
3317  }
3318 
3319  // The unwind_protects are popped off the stack in the reverse of
3320  // the order they are pushed on.
3321 
3322  // FIXME: these statements say that if we see a break or
3323  // return statement in the cleanup block, that we want to use the
3324  // new value of the breaking or returning flag instead of restoring
3325  // the previous value. Is that the right thing to do? I think so.
3326  // Consider the case of
3327  //
3328  // function foo ()
3329  // unwind_protect
3330  // fprintf (stderr, "1: this should always be executed\n");
3331  // break;
3332  // fprintf (stderr, "1: this should never be executed\n");
3333  // unwind_protect_cleanup
3334  // fprintf (stderr, "2: this should always be executed\n");
3335  // return;
3336  // fprintf (stderr, "2: this should never be executed\n");
3337  // end_unwind_protect
3338  // endfunction
3339  //
3340  // If we reset the value of the breaking flag, both the returning
3341  // flag and the breaking flag will be set, and we shouldn't have
3342  // both. So, use the most recent one. If there is no return or
3343  // break in the cleanup block, the values should be reset to
3344  // whatever they were when the cleanup block was entered.
3345 
3346  if (m_breaking || m_returning)
3347  frame.discard (2);
3348  else
3349  frame.run (2);
3350  }
3351 
3352  void
3354  {
3355  if (m_echo_state)
3356  {
3357  size_t line = cmd.line ();
3358  echo_code (line);
3359  m_echo_file_pos = line + 1;
3360  }
3361 
3362  tree_statement_list *cleanup_code = cmd.cleanup ();
3363 
3364  tree_statement_list *unwind_protect_code = cmd.body ();
3365 
3366  if (unwind_protect_code)
3367  {
3368  try
3369  {
3370  unwind_protect_code->accept (*this);
3371  }
3372  catch (const execution_exception& ee)
3373  {
3375 
3376  // FIXME: Maybe we should be able to temporarily set the
3377  // interpreter's exception handling state to something "safe"
3378  // while the cleanup block runs instead of just resetting it
3379  // here?
3380  es.save_exception (ee);
3382 
3383  // Run the cleanup code on exceptions, so that it is run even
3384  // in case of interrupt or out-of-memory.
3385  do_unwind_protect_cleanup_code (cleanup_code);
3386 
3387  // If an error occurs inside the cleanup code, a new
3388  // exception will be thrown instead of the original.
3389  throw;
3390  }
3391  catch (const interrupt_exception&)
3392  {
3393  // The comments above apply here as well.
3395  do_unwind_protect_cleanup_code (cleanup_code);
3396  throw;
3397  }
3398 
3399  // Also execute the unwind_protect_cleanump code if the
3400  // unwind_protect block runs without error.
3401  do_unwind_protect_cleanup_code (cleanup_code);
3402  }
3403  }
3404 
3405  void
3407  {
3408  size_t line = cmd.line ();
3409 
3410  if (m_echo_state)
3411  {
3412  echo_code (line);
3413  line++;
3414  }
3415 
3416 #if defined (HAVE_LLVM)
3417  if (tree_jit::execute (cmd))
3418  return;
3419 #endif
3420 
3422 
3423  tree_expression *expr = cmd.condition ();
3424 
3425  if (! expr)
3426  panic_impossible ();
3427 
3428  for (;;)
3429  {
3430  if (m_echo_state)
3432 
3433  if (m_debug_mode)
3434  do_breakpoint (cmd.is_active_breakpoint (*this));
3435 
3436  if (is_logically_true (expr, "while"))
3437  {
3438  tree_statement_list *loop_body = cmd.body ();
3439 
3440  if (loop_body)
3441  loop_body->accept (*this);
3442 
3443  if (quit_loop_now ())
3444  break;
3445  }
3446  else
3447  break;
3448  }
3449  }
3450 
3451  void
3453  {
3454  size_t line = cmd.line ();
3455 
3456  if (m_echo_state)
3457  {
3458  echo_code (line);
3459  line++;
3460  }
3461 
3462 #if defined (HAVE_LLVM)
3463  if (tree_jit::execute (cmd))
3464  return;
3465 #endif
3466 
3468 
3469  tree_expression *expr = cmd.condition ();
3470  int until_line = cmd.line ();
3471  int until_column = cmd.column ();
3472 
3473  if (! expr)
3474  panic_impossible ();
3475 
3476  for (;;)
3477  {
3478  if (m_echo_state)
3480 
3481  tree_statement_list *loop_body = cmd.body ();
3482 
3483  if (loop_body)
3484  loop_body->accept (*this);
3485 
3486  if (quit_loop_now ())
3487  break;
3488 
3489  if (m_debug_mode)
3490  do_breakpoint (cmd.is_active_breakpoint (*this));
3491 
3492  m_call_stack.set_location (until_line, until_column);
3493 
3494  if (is_logically_true (expr, "do-until"))
3495  break;
3496  }
3497  }
3498 
3499  void
3501  {
3502  panic_impossible ();
3503  }
3504 
3505  void
3507  {
3508  panic_impossible ();
3509  }
3510 
3511  void tree_evaluator::bind_ans (const octave_value& val, bool print)
3512  {
3513  static std::string ans = "ans";
3514 
3515  if (val.is_defined ())
3516  {
3517  if (val.is_cs_list ())
3518  {
3519  octave_value_list lst = val.list_value ();
3520 
3521  for (octave_idx_type i = 0; i < lst.length (); i++)
3522  bind_ans (lst(i), print);
3523  }
3524  else
3525  {
3526  assign (ans, val);
3527 
3528  if (print)
3529  {
3530  octave_value_list args = ovl (val);
3531  args.stash_name_tags (string_vector (ans));
3532  feval ("display", args);
3533  }
3534  }
3535  }
3536  }
3537 
3538  void
3540  {
3541  do_breakpoint (stmt.is_active_breakpoint (*this),
3542  stmt.is_end_of_fcn_or_script ());
3543  }
3544 
3545  void
3546  tree_evaluator::do_breakpoint (bool is_breakpoint,
3547  bool is_end_of_fcn_or_script)
3548  {
3549  bool break_on_this_statement = false;
3550 
3551  if (is_breakpoint)
3552  break_on_this_statement = true;
3553  else if (m_dbstep_flag > 0)
3554  {
3556  {
3557  if (m_dbstep_flag == 1 || is_end_of_fcn_or_script)
3558  {
3559  // We get here if we are doing a "dbstep" or a "dbstep N" and the
3560  // count has reached 1 so that we must stop and return to debug
3561  // prompt. Alternatively, "dbstep N" has been used but the end
3562  // of the frame has been reached so we stop at the last line and
3563  // return to prompt.
3564 
3565  break_on_this_statement = true;
3566  }
3567  else
3568  {
3569  // Executing "dbstep N". Decrease N by one and continue.
3570 
3571  m_dbstep_flag--;
3572  }
3573 
3574  }
3575  else if (m_dbstep_flag == 1
3577  {
3578  // We stepped out from the end of a function.
3579 
3581 
3582  break_on_this_statement = true;
3583  }
3584  }
3585  else if (m_dbstep_flag == -1)
3586  {
3587  // We get here if we are doing a "dbstep in".
3588 
3589  break_on_this_statement = true;
3590 
3592  }
3593  else if (m_dbstep_flag == -2)
3594  {
3595  // We get here if we are doing a "dbstep out". Check for end of
3596  // function and whether the current frame is the same as the
3597  // cached value because we want to step out from the frame where
3598  // "dbstep out" was evaluated, not from any functions called from
3599  // that frame.
3600 
3601  if (is_end_of_fcn_or_script
3603  m_dbstep_flag = -1;
3604  }
3605 
3606  if (break_on_this_statement)
3607  {
3608  m_dbstep_flag = 0;
3609 
3610  enter_debugger ();
3611  }
3612  }
3613 
3614  bool
3616  const char *warn_for)
3617  {
3618  bool expr_value = false;
3619 
3620  octave_value t1 = expr->evaluate (*this);
3621 
3622  if (t1.is_defined ())
3623  return t1.is_true ();
3624  else
3625  error ("%s: undefined value used in conditional expression", warn_for);
3626 
3627  return expr_value;
3628  }
3629 
3630  octave_value
3632  int nargout)
3633  {
3634  return set_internal_variable (m_max_recursion_depth, args, nargout,
3635  "max_recursion_depth", 0);
3636  }
3637 
3639  tree_evaluator::glob_symbol_info (const std::string& pattern) const
3640  {
3641  return m_call_stack.glob_symbol_info (pattern);
3642  }
3643 
3645  tree_evaluator::regexp_symbol_info (const std::string& pattern) const
3646  {
3647  return m_call_stack.regexp_symbol_info (pattern);
3648  }
3649 
3652  {
3653  return m_call_stack.get_symbol_info ();
3654  }
3655 
3658  {
3660  }
3661 
3663  {
3664  Cell func_names (dim_vector (m_autoload_map.size (), 1));
3665  Cell file_names (dim_vector (m_autoload_map.size (), 1));
3666 
3667  octave_idx_type i = 0;
3668  for (const auto& fcn_fname : m_autoload_map)
3669  {
3670  func_names(i) = fcn_fname.first;
3671  file_names(i) = fcn_fname.second;
3672 
3673  i++;
3674  }
3675 
3676  octave_map m;
3677 
3678  m.assign ("function", func_names);
3679  m.assign ("file", file_names);
3680 
3681  return m;
3682  }
3683 
3684  std::string tree_evaluator::lookup_autoload (const std::string& nm) const
3685  {
3686  std::string retval;
3687 
3688  auto p = m_autoload_map.find (nm);
3689 
3690  if (p != m_autoload_map.end ())
3691  {
3693 
3694  retval = lp.find_file (p->second);
3695  }
3696 
3697  return retval;
3698  }
3699 
3700  std::list<std::string> tree_evaluator::autoloaded_functions (void) const
3701  {
3702  std::list<std::string> names;
3703 
3704  for (const auto& fcn_fname : m_autoload_map)
3705  names.push_back (fcn_fname.first);
3706 
3707  return names;
3708  }
3709 
3710  std::list<std::string>
3711  tree_evaluator::reverse_lookup_autoload (const std::string& nm) const
3712  {
3713  std::list<std::string> names;
3714 
3715  for (const auto& fcn_fname : m_autoload_map)
3716  if (nm == fcn_fname.second)
3717  names.push_back (fcn_fname.first);
3718 
3719  return names;
3720  }
3721 
3722  void tree_evaluator::add_autoload (const std::string& fcn,
3723  const std::string& nm)
3724  {
3725  std::string file_name = check_autoload_file (nm);
3726 
3727  m_autoload_map[fcn] = file_name;
3728  }
3729 
3730  void tree_evaluator::remove_autoload (const std::string& fcn,
3731  const std::string& nm)
3732  {
3733  check_autoload_file (nm);
3734 
3735  // Remove function from symbol table and autoload map.
3737 
3738  symtab.clear_dld_function (fcn);
3739 
3740  m_autoload_map.erase (fcn);
3741  }
3742 
3743  octave_value
3745  {
3746  return set_internal_variable (m_whos_line_format, args, nargout,
3747  "whos_line_format");
3748  }
3749 
3750  octave_value
3752  {
3753  return set_internal_variable (m_silent_functions, args, nargout,
3754  "silent_functions");
3755  }
3756 
3757  octave_value
3759  {
3760  return set_internal_variable (m_string_fill_char, args, nargout,
3761  "string_fill_char");
3762  }
3763 
3764  // Final step of processing an indexing error. Add the name of the
3765  // variable being indexed, if any, then issue an error. (Will this also
3766  // be needed by pt-lvalue, which calls subsref?)
3767 
3769  const tree_expression *expr)
3770  {
3771  std::string extra_message;
3772 
3773  if (is_variable (expr))
3774  {
3775  std::string var = expr->name ();
3776 
3777  e.set_var (var);
3778 
3780 
3781  octave_value fcn = symtab.find_function (var);
3782 
3783  if (fcn.is_function ())
3784  {
3785  octave_function *fp = fcn.function_value ();
3786 
3787  if (fp && fp->name () == var)
3788  extra_message
3789  = " (note: variable '" + var + "' shadows function)";
3790  }
3791  }
3792 
3793  std::string msg = e.message () + extra_message;
3794 
3795  error_with_id (e.err_id (), "%s", msg.c_str ());
3796  }
3797 
3798  octave_value
3799  tree_evaluator::do_who (int argc, const string_vector& argv,
3800  bool return_list, bool verbose)
3801  {
3802  return m_call_stack.do_who (argc, argv, return_list, verbose);
3803  }
3804 
3807  const string_vector& arg_nm)
3808  {
3810 
3811  if (args)
3812  {
3814  upv (m_lvalue_list, nullptr);
3815 
3816  int len = args->length ();
3817 
3820 
3821  m_num_indices = len;
3822 
3823  std::list<octave_value> arg_vals;
3824 
3825  int k = 0;
3826 
3827  for (auto elt : *args)
3828  {
3829  // FIXME: is it possible for elt to be invalid?
3830 
3831  if (! elt)
3832  break;
3833 
3834  m_index_position = k++;
3835 
3836  octave_value tmp = elt->evaluate (*this);
3837 
3838  if (tmp.is_cs_list ())
3839  {
3840  octave_value_list tmp_ovl = tmp.list_value ();
3841 
3842  for (octave_idx_type i = 0; i < tmp_ovl.length (); i++)
3843  arg_vals.push_back (tmp_ovl(i));
3844  }
3845  else if (tmp.is_defined ())
3846  arg_vals.push_back (tmp);
3847  }
3848 
3849  retval = octave_value_list (arg_vals);
3850  }
3851 
3852  octave_idx_type n = retval.length ();
3853 
3854  if (n > 0)
3855  retval.stash_name_tags (arg_nm);
3856 
3857  return retval;
3858  }
3859 
3860  std::list<octave_lvalue>
3862  {
3863  std::list<octave_lvalue> retval;
3864 
3865  for (tree_expression *elt : *lhs)
3866  retval.push_back (elt->lvalue (*this));
3867 
3868  return retval;
3869  }
3870 
3871  void
3872  tree_evaluator::push_echo_state (int type, const std::string& file_name,
3873  size_t pos)
3874  {
3876 
3877  if (frame)
3878  {
3879  push_echo_state_cleanup (*frame);
3880 
3881  set_echo_state (type, file_name, pos);
3882  }
3883  }
3884 
3885  void
3886  tree_evaluator::set_echo_state (int type, const std::string& file_name,
3887  size_t pos)
3888  {
3889  m_echo_state = echo_this_file (file_name, type);
3890  m_echo_file_name = file_name;
3891  m_echo_file_pos = pos;
3892  }
3893 
3894  void
3895  tree_evaluator::uwp_set_echo_state (bool state, const std::string& file_name,
3896  size_t pos)
3897  {
3898  m_echo_state = state;
3899  m_echo_file_name = file_name;
3900  m_echo_file_pos = pos;
3901  }
3902 
3903  void
3905  {
3906  octave_function *caller = caller_function ();
3907 
3908  if (caller && caller->is_user_code ())
3909  {
3910  octave_user_code *fcn = dynamic_cast<octave_user_code *> (caller);
3911 
3913 
3914  std::string file_name = fcn->fcn_file_name ();
3915 
3916  size_t pos = m_call_stack.current_line ();
3917 
3918  set_echo_state (type, file_name, pos);
3919  }
3920  }
3921 
3922  void
3924  {
3927  }
3928 
3930  {
3931  // This function is expected to be called from ECHO, which would be
3932  // the top of the call stack. If the caller of ECHO is a
3933  // user-defined function or script, then set up unwind-protect
3934  // elements to restore echo state.
3935 
3937 
3938  if (frame)
3939  {
3940  push_echo_state_cleanup (*frame);
3941  return true;
3942  }
3943 
3944  return false;
3945  }
3946 
3947 
3948  octave_value
3950  {
3951  bool cleanup_pushed = maybe_push_echo_state_cleanup ();
3952 
3953  string_vector argv = args.make_argv ();
3954 
3955  switch (args.length ())
3956  {
3957  case 0:
3958  if ((m_echo & ECHO_SCRIPTS) || (m_echo & ECHO_FUNCTIONS))
3959  {
3960  m_echo = ECHO_OFF;
3961  m_echo_files.clear ();
3962  }
3963  else
3964  m_echo = ECHO_SCRIPTS;
3965  break;
3966 
3967  case 1:
3968  {
3969  std::string arg0 = argv[0];
3970 
3971  if (arg0 == "on")
3972  m_echo = ECHO_SCRIPTS;
3973  else if (arg0 == "off")
3974  m_echo = ECHO_OFF;
3975  else
3976  {
3977  std::string file = fcn_file_in_path (arg0);
3978  file = sys::env::make_absolute (file);
3979 
3980  if (file.empty ())
3981  error ("echo: no such file %s", arg0.c_str ());
3982 
3983  if (m_echo & ECHO_ALL)
3984  {
3985  // Echo is enabled for all functions, so turn it off
3986  // for this one.
3987 
3988  m_echo_files[file] = false;
3989  }
3990  else
3991  {
3992  // Echo may be enabled for specific functions.
3993 
3994  auto p = m_echo_files.find (file);
3995 
3996  if (p == m_echo_files.end ())
3997  {
3998  // Not this one, so enable it.
3999 
4001  m_echo_files[file] = true;
4002  }
4003  else
4004  {
4005  // This one is already in the list. Flip the
4006  // status for it.
4007 
4008  p->second = ! p->second;
4009  }
4010  }
4011  }
4012  }
4013  break;
4014 
4015  case 2:
4016  {
4017  std::string arg0 = argv[0];
4018  std::string arg1 = argv[1];
4019 
4020  if (arg1 == "on" || arg1 == "off")
4021  std::swap (arg0, arg1);
4022 
4023  if (arg0 == "on")
4024  {
4025  if (arg1 == "all")
4026  {
4028  m_echo_files.clear ();
4029  }
4030  else
4031  {
4032  std::string file = fcn_file_in_path (arg1);
4033  file = sys::env::make_absolute (file);
4034 
4035  if (file.empty ())
4036  error ("echo: no such file %s", arg1.c_str ());
4037 
4039  m_echo_files[file] = true;
4040  }
4041  }
4042  else if (arg0 == "off")
4043  {
4044  if (arg1 == "all")
4045  {
4046  m_echo = ECHO_OFF;
4047  m_echo_files.clear ();
4048  }
4049  else
4050  {
4051  std::string file = fcn_file_in_path (arg1);
4052  file = sys::env::make_absolute (file);
4053 
4054  if (file.empty ())
4055  error ("echo: no such file %s", arg1.c_str ());
4056 
4057  m_echo_files[file] = false;
4058  }
4059  }
4060  else
4061  print_usage ();
4062  }
4063  break;
4064 
4065  default:
4066  print_usage ();
4067  break;
4068  }
4069 
4070  if (cleanup_pushed)
4072 
4073  return octave_value ();
4074  }
4075 
4077  {
4078  return (m_debugger_stack.empty ()
4079  ? false : m_debugger_stack.top()->in_debug_repl ());
4080  }
4081 
4083  {
4084  if (! m_debugger_stack.empty ())
4085  m_debugger_stack.top()->dbcont ();
4086  }
4087 
4088  void tree_evaluator::dbquit (bool all)
4089  {
4090  if (! m_debugger_stack.empty ())
4091  m_debugger_stack.top()->dbquit (all);
4092  }
4093 
4094  static octave_value end_value (const octave_value& value,
4095  octave_idx_type index_position,
4096  octave_idx_type num_indices)
4097  {
4098  dim_vector dv = value.dims ();
4099  int ndims = dv.ndims ();
4100 
4101  if (num_indices < ndims)
4102  {
4103  for (int i = num_indices; i < ndims; i++)
4104  dv(num_indices-1) *= dv(i);
4105 
4106  if (num_indices == 1)
4107  {
4108  ndims = 2;
4109  dv.resize (ndims);
4110  dv(1) = 1;
4111  }
4112  else
4113  {
4114  ndims = num_indices;
4115  dv.resize (ndims);
4116  }
4117  }
4118 
4119  return (index_position < ndims
4120  ? octave_value (dv(index_position)) : octave_value (1.0));
4121  }
4122 
4125  {
4126  int nargin = args.length ();
4127 
4128  if (nargin != 0 && nargin != 3)
4129  print_usage ();
4130 
4131  if (nargin == 3)
4132  {
4134  = args(1).xidx_type_value ("end: K must be integer value");
4135 
4136  if (index_position < 1)
4137  error ("end: K must be greater than zero");
4138 
4140  = args(2).xidx_type_value ("end: N must be integer value");
4141 
4142  if (num_indices < 1)
4143  error ("end: N must be greater than zero");
4144 
4145  return end_value (args(0), index_position-1, num_indices);
4146  }
4147 
4148  // If m_indexed_object is undefined, then this use of 'end' is
4149  // either appearing in a function call argument list or in an
4150  // attempt to index an undefined symbol. There seems to be no
4151  // reasonable way to provide a better error message. So just fail
4152  // with an invalid use message. See bug #58830.
4153 
4155  error ("invalid use of 'end': may only be used to index existing value");
4156 
4157  octave_value expr_result;
4158 
4159  if (m_index_list.empty ())
4160  expr_result = m_indexed_object;
4161  else
4162  {
4163  try
4164  {
4165  // When evaluating "end" with no arguments, we should have
4166  // been called from the built-in Fend function that appears
4167  // in the context of an argument list. Fend will be
4168  // evaluated in its own stack frame. But we need to
4169  // evaluate the partial expression that the special "end"
4170  // token applies to in the calling stack frame.
4171 
4172  unwind_action act ([this] (size_t frm)
4173  {
4175  }, m_call_stack.current_frame ());
4176 
4179 
4180  // End is only valid inside argument lists used for
4181  // indexing. The dispatch class is set by the function that
4182  // evaluates the argument list.
4183 
4184  // Silently ignore extra output values.
4185 
4186  octave_value_list tmp
4188 
4189  expr_result = tmp.length () ? tmp(0) : octave_value ();
4190 
4191  if (expr_result.is_cs_list ())
4193  }
4194  catch (index_exception&)
4195  {
4196  error ("error evaluating partial expression for END");
4197  }
4198  }
4199 
4200  if (expr_result.isobject ())
4201  {
4202  // FIXME: is there a better way to lookup and execute a method
4203  // that handles all the details like setting the dispatch class
4204  // appropriately?
4205 
4206  std::string dispatch_class = expr_result.class_name ();
4207 
4209 
4210  octave_value meth = symtab.find_method ("end", dispatch_class);
4211 
4212  if (meth.is_defined ())
4213  return m_interpreter.feval
4214  (meth, ovl (expr_result, m_index_position+1, m_num_indices), 1);
4215  }
4216 
4217  return end_value (expr_result, m_index_position, m_num_indices);
4218  }
4219 
4220  octave_value
4221  tree_evaluator::PS4 (const octave_value_list& args, int nargout)
4222  {
4223  return set_internal_variable (m_PS4, args, nargout, "PS4");
4224  }
4225 
4226  bool tree_evaluator::echo_this_file (const std::string& file, int type) const
4227  {
4228  if ((type & m_echo) == ECHO_SCRIPTS)
4229  {
4230  // Asking about scripts and echo is enabled for them.
4231  return true;
4232  }
4233 
4234  if ((type & m_echo) == ECHO_FUNCTIONS)
4235  {
4236  // Asking about functions and echo is enabled for functions.
4237  // Now, which ones?
4238 
4239  auto p = m_echo_files.find (file);
4240 
4241  if (m_echo & ECHO_ALL)
4242  {
4243  // Return true ulness echo was turned off for a specific
4244  // file.
4245 
4246  return (p == m_echo_files.end () || p->second);
4247  }
4248  else
4249  {
4250  // Return true if echo is specifically enabled for this file.
4251 
4252  return p != m_echo_files.end () && p->second;
4253  }
4254  }
4255 
4256  return false;
4257  }
4258 
4260  {
4261  std::string prefix = command_editor::decode_prompt_string (m_PS4);
4262 
4264 
4265  if (curr_fcn && curr_fcn->is_user_code ())
4266  {
4267  octave_user_code *code = dynamic_cast<octave_user_code *> (curr_fcn);
4268 
4269  size_t num_lines = line - m_echo_file_pos + 1;
4270 
4271  std::deque<std::string> lines
4272  = code->get_code_lines (m_echo_file_pos, num_lines);
4273 
4274  for (auto& elt : lines)
4275  octave_stdout << prefix << elt << std::endl;
4276  }
4277  }
4278 
4279  // Decide if it's time to quit a for or while loop.
4281  {
4282  octave_quit ();
4283 
4284  // Maybe handle 'continue N' someday...
4285 
4286  if (m_continuing)
4287  m_continuing--;
4288 
4289  bool quit = (m_returning || m_breaking || m_continuing);
4290 
4291  if (m_breaking)
4292  m_breaking--;
4293 
4294  return quit;
4295  }
4296 
4298  const Matrix& ignored_outputs,
4299  int nargin, int nargout,
4300  bool takes_varargs,
4301  const octave_value_list& va_args)
4302  {
4304  set_auto_fcn_var (stack_frame::IGNORED, ignored_outputs);
4308 
4309  if (takes_varargs)
4310  assign ("varargin", va_args.cell_value ());
4311  }
4312 
4313  std::string
4314  tree_evaluator::check_autoload_file (const std::string& nm) const
4315  {
4316  if (sys::env::absolute_pathname (nm))
4317  return nm;
4318 
4319  std::string full_name = nm;
4320 
4322 
4323  bool found = false;
4324 
4325  if (fcn)
4326  {
4327  std::string fname = fcn->fcn_file_name ();
4328 
4329  if (! fname.empty ())
4330  {
4331  fname = sys::env::make_absolute (fname);
4332  fname = fname.substr (0, fname.find_last_of (sys::file_ops::dir_sep_str ()) + 1);
4333 
4334  sys::file_stat fs (fname + nm);
4335 
4336  if (fs.exists ())
4337  {
4338  full_name = fname + nm;
4339  found = true;
4340  }
4341  }
4342  }
4343 
4344  if (! found)
4345  warning_with_id ("Octave:autoload-relative-file-name",
4346  "autoload: '%s' is not an absolute filename",
4347  nm.c_str ());
4348 
4349  return full_name;
4350  }
4351 }
4352 
4353 DEFMETHOD (max_recursion_depth, interp, args, nargout,
4354  doc: /* -*- texinfo -*-
4355 @deftypefn {} {@var{val} =} max_recursion_depth ()
4356 @deftypefnx {} {@var{old_val} =} max_recursion_depth (@var{new_val})
4357 @deftypefnx {} {} max_recursion_depth (@var{new_val}, "local")
4358 Query or set the internal limit on the number of times a function may
4359 be called recursively.
4360 
4361 If the limit is exceeded, an error message is printed and control returns to
4362 the top level.
4363 
4364 When called from inside a function with the @qcode{"local"} option, the
4365 variable is changed locally for the function and any subroutines it calls.
4366 The original variable value is restored when exiting the function.
4367 
4368 @seealso{max_stack_depth}
4369 @end deftypefn */)
4370 {
4371  octave::tree_evaluator& tw = interp.get_evaluator ();
4372 
4373  return tw.max_recursion_depth (args, nargout);
4374 }
4375 
4376 /*
4377 %!test
4378 %! orig_val = max_recursion_depth ();
4379 %! old_val = max_recursion_depth (2*orig_val);
4380 %! assert (orig_val, old_val);
4381 %! assert (max_recursion_depth (), 2*orig_val);
4382 %! max_recursion_depth (orig_val);
4383 %! assert (max_recursion_depth (), orig_val);
4384 
4385 %!error (max_recursion_depth (1, 2))
4386 */
4387 
4388 DEFMETHOD (whos_line_format, interp, args, nargout,
4389  doc: /* -*- texinfo -*-
4390 @deftypefn {} {@var{val} =} whos_line_format ()
4391 @deftypefnx {} {@var{old_val} =} whos_line_format (@var{new_val})
4392 @deftypefnx {} {} whos_line_format (@var{new_val}, "local")
4393 Query or set the format string used by the command @code{whos}.
4394 
4395 A full format string is:
4396 @c Set example in small font to prevent overfull line
4397 
4398 @smallexample
4399 %[modifier]<command>[:width[:left-min[:balance]]];
4400 @end smallexample
4401 
4402 The following command sequences are available:
4403 
4404 @table @code
4405 @item %a
4406 Prints attributes of variables (g=global, p=persistent, f=formal parameter).
4407 
4408 @item %b
4409 Prints number of bytes occupied by variables.
4410 
4411 @item %c
4412 Prints class names of variables.
4413 
4414 @item %e
4415 Prints elements held by variables.
4416 
4417 @item %n
4418 Prints variable names.
4419 
4420 @item %s
4421 Prints dimensions of variables.
4422 
4423 @item %t
4424 Prints type names of variables.
4425 @end table
4426 
4427 Every command may also have an alignment modifier:
4428 
4429 @table @code
4430 @item l
4431 Left alignment.
4432 
4433 @item r
4434 Right alignment (default).
4435 
4436 @item c
4437 Column-aligned (only applicable to command %s).
4438 @end table
4439 
4440 The @code{width} parameter is a positive integer specifying the minimum
4441 number of columns used for printing. No maximum is needed as the field will
4442 auto-expand as required.
4443 
4444 The parameters @code{left-min} and @code{balance} are only available when
4445 the column-aligned modifier is used with the command @samp{%s}.
4446 @code{balance} specifies the column number within the field width which
4447 will be aligned between entries. Numbering starts from 0 which indicates
4448 the leftmost column. @code{left-min} specifies the minimum field width to
4449 the left of the specified balance column.
4450 
4451 The default format is:
4452 
4453 @qcode{" %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:-1;@xbackslashchar{}n"}
4454 
4455 When called from inside a function with the @qcode{"local"} option, the
4456 variable is changed locally for the function and any subroutines it calls.
4457 The original variable value is restored when exiting the function.
4458 @seealso{whos}
4459 @end deftypefn */)
4460 {
4461  octave::tree_evaluator& tw = interp.get_evaluator ();
4462 
4463  return tw.whos_line_format (args, nargout);
4464 }
4465 
4466 DEFMETHOD (silent_functions, interp, args, nargout,
4467  doc: /* -*- texinfo -*-
4468 @deftypefn {} {@var{val} =} silent_functions ()
4469 @deftypefnx {} {@var{old_val} =} silent_functions (@var{new_val})
4470 @deftypefnx {} {} silent_functions (@var{new_val}, "local")
4471 Query or set the internal variable that controls whether internal
4472 output from a function is suppressed.
4473 
4474 If this option is disabled, Octave will display the results produced by
4475 evaluating expressions within a function body that are not terminated with
4476 a semicolon.
4477 
4478 When called from inside a function with the @qcode{"local"} option, the
4479 variable is changed locally for the function and any subroutines it calls.
4480 The original variable value is restored when exiting the function.
4481 @end deftypefn */)
4482 {
4483  octave::tree_evaluator& tw = interp.get_evaluator ();
4484 
4485  return tw.silent_functions (args, nargout);
4486 }
4487 
4488 /*
4489 %!test
4490 %! orig_val = silent_functions ();
4491 %! old_val = silent_functions (! orig_val);
4492 %! assert (orig_val, old_val);
4493 %! assert (silent_functions (), ! orig_val);
4494 %! silent_functions (orig_val);
4495 %! assert (silent_functions (), orig_val);
4496 
4497 %!error (silent_functions (1, 2))
4498 */
4499 
4500 DEFMETHOD (string_fill_char, interp, args, nargout,
4501  doc: /* -*- texinfo -*-
4502 @deftypefn {} {@var{val} =} string_fill_char ()
4503 @deftypefnx {} {@var{old_val} =} string_fill_char (@var{new_val})
4504 @deftypefnx {} {} string_fill_char (@var{new_val}, "local")
4505 Query or set the internal variable used to pad all rows of a character
4506 matrix to the same length.
4507 
4508 The value must be a single character and the default is @qcode{" "} (a
4509 single space). For example:
4510 
4511 @example
4512 @group
4513 string_fill_char ("X");
4514 [ "these"; "are"; "strings" ]
4515  @result{} "theseXX"
4516  "areXXXX"
4517  "strings"
4518 @end group
4519 @end example
4520 
4521 When called from inside a function with the @qcode{"local"} option, the
4522 variable is changed locally for the function and any subroutines it calls.
4523 The original variable value is restored when exiting the function.
4524 @end deftypefn */)
4525 {
4526  octave::tree_evaluator& tw = interp.get_evaluator ();
4527 
4528  return tw.string_fill_char (args, nargout);
4529 }
4530 
4531 /*
4532 ## string_fill_char() function call must be outside of %!test block
4533 ## due to the way a %!test block is wrapped inside a function
4534 %!shared orig_val, old_val
4535 %! orig_val = string_fill_char ();
4536 %! old_val = string_fill_char ("X");
4537 %!test
4538 %! assert (orig_val, old_val);
4539 %! assert (string_fill_char (), "X");
4540 %! assert (["these"; "are"; "strings"], ["theseXX"; "areXXXX"; "strings"]);
4541 %! string_fill_char (orig_val);
4542 %! assert (string_fill_char (), orig_val);
4543 
4544 %!assert ( [ [], {1} ], {1} )
4545 
4546 %!error (string_fill_char (1, 2))
4547 */
4548 
4549 DEFMETHOD (PS4, interp, args, nargout,
4550  doc: /* -*- texinfo -*-
4551 @deftypefn {} {@var{val} =} PS4 ()
4552 @deftypefnx {} {@var{old_val} =} PS4 (@var{new_val})
4553 @deftypefnx {} {} PS4 (@var{new_val}, "local")
4554 Query or set the character string used to prefix output produced
4555 when echoing commands is enabled.
4556 
4557 The default value is @qcode{"+ "}.
4558 @xref{Diary and Echo Commands}, for a description of echoing commands.
4559 
4560 When called from inside a function with the @qcode{"local"} option, the
4561 variable is changed locally for the function and any subroutines it calls.
4562 The original variable value is restored when exiting the function.
4563 @seealso{echo, PS1, PS2}
4564 @end deftypefn */)
4565 {
4566  octave::tree_evaluator& tw = interp.get_evaluator ();
4567 
4568  return tw.PS4 (args, nargout);
4569 }
4570 
4571 DEFMETHOD (echo, interp, args, nargout,
4572  doc: /* -*- texinfo -*-
4573 @deftypefn {} {} echo
4574 @deftypefnx {} {} echo on
4575 @deftypefnx {} {} echo off
4576 @deftypefnx {} {} echo on all
4577 @deftypefnx {} {} echo off all
4578 @deftypefnx {} {} echo @var{function} on
4579 @deftypefnx {} {} echo @var{function} off
4580 Control whether commands are displayed as they are executed.
4581 
4582 Valid options are:
4583 
4584 @table @code
4585 @item on
4586 Enable echoing of commands as they are executed in script files.
4587 
4588 @item off
4589 Disable echoing of commands as they are executed in script files.
4590 
4591 @item on all
4592 Enable echoing of commands as they are executed in script files and
4593 functions.
4594 
4595 @item off all
4596 Disable echoing of commands as they are executed in script files and
4597 functions.
4598 
4599 @item @var{function} on
4600 Enable echoing of commands as they are executed in the named function.
4601 
4602 @item @var{function} off
4603 Disable echoing of commands as they are executed in the named function.
4604 @end table
4605 
4606 @noindent
4607 With no arguments, @code{echo} toggles the current echo state.
4608 
4609 @seealso{PS4}
4610 @end deftypefn */)
4611 {
4612  octave::tree_evaluator& tw = interp.get_evaluator ();
4613 
4614  return tw.echo (args, nargout);
4615 }
4616 
4617 /*
4618 %!error echo ([])
4619 %!error echo (0)
4620 %!error echo ("")
4621 %!error echo ("Octave")
4622 %!error echo ("off", "invalid")
4623 %!error echo ("on", "invalid")
4624 %!error echo ("on", "all", "all")
4625 */
F77_RET_T const F77_DBLE const F77_DBLE const F77_INT const F77_DBLE const F77_DBLE const F77_DBLE F77_DBLE F77_DBLE F77_INT F77_INT const F77_INT const F77_INT F77_INT F77_INT F77_DBLE *F77_RET_T const F77_DBLE const F77_INT const F77_DBLE const F77_DBLE F77_DBLE F77_DBLE F77_INT F77_INT const F77_INT const F77_INT F77_INT F77_INT F77_DBLE *F77_RET_T const F77_REAL const F77_REAL const F77_INT const F77_REAL const F77_REAL const F77_REAL F77_REAL F77_REAL F77_INT F77_INT const F77_INT const F77_INT F77_INT F77_INT F77_REAL *F77_RET_T const F77_REAL const F77_INT const F77_REAL const F77_REAL F77_REAL F77_REAL F77_INT F77_INT const F77_INT const F77_INT F77_INT F77_INT F77_REAL *static F77_INT user_function(const double &x, int &, double &result)
Definition: Quad.cc:80
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Definition: Array.cc:1011
octave_idx_type columns(void) const
Definition: Array.h:424
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:377
octave_idx_type rows(void) const
Definition: Array.h:415
Definition: Cell.h:43
Definition: dMatrix.h:42
Definition: Range.h:40
double elem(octave_idx_type i) const
Definition: Range.cc:137
octave_idx_type numel(void) const
Definition: Range.h:87
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:95
void resize(int n, int fill_value=0)
Definition: dim-vector.h:349
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:334
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
Definition: dim-vector.cc:245
line(const graphics_handle &mh, const graphics_handle &p)
Definition: graphics.in.h:4318
void add_method(T *obj, void(T::*method)(Params...), Args &&... args)
void add_fcn(void(*fcn)(Params...), Args &&... args)
void add(F &&fcn, Args &&... args)
static bool forced_interactive(void)
Definition: octave.cc:280
void forced_interactive(bool arg)
Definition: octave.h:284
static application * app(void)
Definition: octave.h:286
size_t length(void) const
Definition: base-list.h:53
elt_type & front(void)
Definition: base-list.h:79
iterator begin(void)
Definition: base-list.h:65
iterator end(void)
Definition: base-list.h:68
void disallow_command_syntax(void)
Definition: oct-parse.cc:8866
bool at_end_of_input(void) const
Definition: parse.h:168
void statement_list(std::shared_ptr< tree_statement_list > &lst)
Definition: oct-parse.cc:6703
bool have_breakpoints(void)
Definition: bp-table.h:100
bool debug_on_err(const std::string &id)
Definition: bp-table.h:103
bool debug_on_caught(const std::string &id)
Definition: bp-table.h:109
size_t size(void) const
Definition: call-stack.h:89
bool at_top_level(void) const
Definition: call-stack.h:108
symbol_info_list glob_symbol_info(const std::string &pattern) const
Definition: call-stack.cc:843
void clear_global_variables(void)
Definition: call-stack.cc:836
std::string get_dispatch_class(void) const
Definition: call-stack.cc:288
octave_value global_varval(const std::string &name) const
Definition: call-stack.cc:881
bool goto_frame(size_t n=0, bool verbose=false)
Definition: call-stack.cc:466
bool is_class_constructor_executing(std::string &dispatch_class) const
Definition: call-stack.cc:312
void push(const symbol_scope &scope)
Definition: call-stack.cc:378
std::list< frame_info > backtrace_info(octave_idx_type &curr_user_frame, bool print_subfn=true) const
Definition: call-stack.cc:678
octave_user_code * current_user_code(void) const
Definition: call-stack.cc:117
size_t current_frame(void) const
Definition: call-stack.h:87
void goto_base_frame(void)
Definition: call-stack.cc:629
size_t dbupdown(size_t start, int n, bool verbose)
Definition: call-stack.cc:515
void set_top_level_value(const std::string &name, const octave_value &value)
Definition: call-stack.cc:898
void make_persistent(const symbol_record &sym)
Definition: call-stack.cc:871
int current_line(void) const
Definition: call-stack.cc:91
std::list< std::string > global_variable_names(void) const
Definition: call-stack.cc:781
void set_line(int l)
Definition: call-stack.h:179
octave_value get_auto_fcn_var(stack_frame::auto_var_type avt) const
Definition: call-stack.cc:1128
std::list< std::string > top_level_variable_names(void) const
Definition: call-stack.cc:796
symbol_info_list top_scope_symbol_info(void) const
Definition: call-stack.cc:859
void set_dispatch_class(const std::string &class_name)
Definition: call-stack.cc:293
octave_map backtrace(octave_idx_type &curr_user_frame, bool print_subfn=true) const
Definition: call-stack.cc:707
void goto_caller_frame(void)
Definition: call-stack.cc:617
void restore_frame(size_t n)
Definition: call-stack.h:201
symbol_info_list regexp_symbol_info(const std::string &pattern) const
Definition: call-stack.cc:849
std::list< std::shared_ptr< stack_frame > > backtrace_frames(octave_idx_type &curr_user_frame) const
Definition: call-stack.cc:636
void set_auto_fcn_var(stack_frame::auto_var_type avt, const octave_value &val)
Definition: call-stack.cc:1122
std::shared_ptr< stack_frame > current_user_frame(void) const
Definition: call-stack.cc:504
octave_value & global_varref(const std::string &name)
Definition: call-stack.cc:888
octave_user_code * debug_user_code(void) const
Definition: call-stack.cc:203
void set_location(int l, int c)
Definition: call-stack.h:168
void display(void) const
Definition: call-stack.cc:1108
void make_global(const symbol_record &sym)
Definition: call-stack.cc:876
unwind_protect * curr_fcn_unwind_protect_frame(void)
Definition: call-stack.cc:184
octave_value get_top_level_value(const std::string &name) const
Definition: call-stack.cc:893
symbol_info_list get_symbol_info(void)
Definition: call-stack.cc:854
octave_value do_who(int argc, const string_vector &argv, bool return_list, bool verbose=false)
Definition: call-stack.cc:904
bool is_class_method_executing(std::string &dispatch_class) const
Definition: call-stack.cc:298
octave_map empty_backtrace(void) const
Definition: call-stack.cc:748
std::list< std::string > variable_names(void) const
Definition: call-stack.cc:801
void clear_global_variable(const std::string &name)
Definition: call-stack.cc:806
void clear_global_variable_regexp(const std::string &pattern)
Definition: call-stack.cc:825
octave_value max_stack_depth(const octave_value_list &args, int nargout)
Definition: call-stack.cc:864
void clear_global_variable_pattern(const std::string &pattern)
Definition: call-stack.cc:814
int debug_user_code_column(void) const
Definition: call-stack.cc:258
symbol_scope top_scope(void) const
Definition: call-stack.h:96
int debug_user_code_line(void) const
Definition: call-stack.cc:229
octave_function * current_function(bool skip_first=false) const
Definition: call-stack.cc:66
size_t find_current_user_frame(void) const
Definition: call-stack.cc:487
void set_column(int c)
Definition: call-stack.h:189
int current_column(void) const
Definition: call-stack.cc:104
std::shared_ptr< stack_frame > get_current_stack_frame(void) const
Definition: call-stack.h:91
symbol_scope current_scope(void) const
Definition: call-stack.h:101
cdef_method find_method(const std::string &nm, bool local=false)
Definition: cdef-class.h:438
octave_value find_method(const std::string &class_name, const std::string &name) const
bool is_static(void) const
Definition: cdef-method.h:183
octave_value get_function(void) const
Definition: cdef-method.h:190
bool ok(void) const
Definition: cdef-object.h:300
cdef_class get_class(void) const
Definition: cdef-object.cc:183
static bool interrupt(bool=true)
Definition: cmd-edit.cc:1616
static std::string decode_prompt_string(const std::string &s)
Definition: cmd-edit.cc:1269
static bool erase_empty_line(bool flag)
Definition: cmd-edit.cc:1309
static void ignore_entries(bool=true)
Definition: cmd-hist.cc:592
static bool ignoring_entries(void)
Definition: cmd-hist.cc:599
size_t m_level
Definition: pt-eval.cc:137
void repl(const std::string &prompt="debug> ")
Definition: pt-eval.cc:143
debugger(interpreter &interp, size_t level)
Definition: pt-eval.cc:109
bool in_debug_repl(void) const
Definition: pt-eval.cc:116
void dbquit(bool all=false)
Definition: pt-eval.cc:123
interpreter & m_interpreter
Definition: pt-eval.cc:135
execution_mode m_execution_mode
Definition: pt-eval.cc:139
bool m_in_debug_repl
Definition: pt-eval.cc:140
bool quitting_debugger(void) const
Definition: pt-eval.cc:367
size_t m_debug_frame
Definition: pt-eval.cc:138
void dbcont(void)
Definition: pt-eval.cc:118
octave_value last_error_message(const octave_value_list &args, int nargout)
Definition: error.cc:335
void save_exception(const execution_exception &e)
Definition: error.cc:899
void set_debug_on_warning(bool flag)
Definition: error.h:87
octave_value debug_on_error(const octave_value_list &args, int nargout)
Definition: error.cc:277
void display_exception(const execution_exception &e, std::ostream &os) const
Definition: error.cc:910
octave_value debug_on_caught(const octave_value_list &args, int nargout)
Definition: error.cc:284
octave_value last_error_id(const octave_value_list &args, int nargout)
Definition: error.cc:357
void set_debug_on_error(bool flag)
Definition: error.h:61
octave_map last_error_stack(void) const
Definition: error.h:232
octave_value debug_on_warning(const octave_value_list &args, int nargout)
Definition: error.cc:291
Provides threadsafe access to octave.
void enter_debugger_event(const std::string &fcn_name, const std::string &fcn_file_name, int line)
void execute_in_debugger_event(const std::string &file, int line)
virtual const char * err_id(void) const =0
void set_var(const std::string &var_arg="")
std::string get_input(const std::string &prompt, bool &eof)
Definition: input.h:270
octave_value PS1(const octave_value_list &args, int nargout)
void set_PS1(const std::string &s)
Definition: input.h:80
octave_value PS2(const octave_value_list &args, int nargout)
octave_value gud_mode(const octave_value_list &args, int nargout)
octave_value_list feval(const char *name, const octave_value_list &args=octave_value_list(), int nargout=0)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
input_system & get_input_system(void)
Definition: interpreter.h:223
bool in_top_level_repl(void) const
Definition: interpreter.h:188
load_path & get_load_path(void)
Definition: interpreter.h:243
void recover_from_exception(void)
cdef_manager & get_cdef_manager(void)
Definition: interpreter.h:280
bool interactive(void) const
Definition: interpreter.h:158
symbol_table & get_symbol_table(void)
Definition: interpreter.h:258
error_system & get_error_system(void)
Definition: interpreter.h:213
event_manager & get_event_manager(void)
Definition: interpreter.h:290
tree_evaluator & get_evaluator(void)
std::string find_file(const std::string &file) const
Definition: load-path.cc:538
void assign(octave_value::assign_op, const octave_value &)
Definition: oct-lvalue.cc:55
void define(const octave_value &v)
Definition: oct-lvalue.cc:50
bool is_undefined(void) const
Definition: oct-lvalue.cc:45
int run(void)
Definition: oct-parse.cc:8970
quit_debug_exception(bool all=false)
Definition: pt-eval.cc:82
~quit_debug_exception(void)=default
bool all(void) const
Definition: pt-eval.cc:90
quit_debug_exception & operator=(const quit_debug_exception &)=default
quit_debug_exception(const quit_debug_exception &)=default
std::map< std::string, octave_value > local_vars_map
Definition: stack-frame.h:112
octave_value find_user_function(const std::string &name)
Definition: symtab.cc:288
octave_value find_function(const std::string &name, const symbol_scope &search_scope=symbol_scope())
Definition: symtab.cc:249
void clear_function(const std::string &name)
Definition: symtab.cc:434
void install_cmdline_function(const std::string &name, const octave_value &fcn)
Definition: symtab.cc:332
octave_value fcn_table_find(const std::string &name, const octave_value_list &args=ovl(), const symbol_scope &search_scope=symbol_scope())
Definition: symtab.cc:219
void clear_function_pattern(const std::string &pat)
Definition: symtab.cc:439
void clear_dld_function(const std::string &name)
Definition: symtab.cc:485
void clear_functions(bool force=false)
Definition: symtab.cc:426
octave_value find_method(const std::string &name, const std::string &dispatch_type)
Definition: symtab.cc:125
void clear_function_regexp(const std::string &pat)
Definition: symtab.cc:454
octave_value find_scoped_function(const std::string &name, const symbol_scope &search_scope)
Definition: symtab.cc:75
bool exists(void) const
Definition: file-stat.h:147
static bool absolute_pathname(const std::string &s)
Definition: oct-env.cc:112
static std::string make_absolute(const std::string &s, const std::string &dot_path=get_current_directory())
Definition: oct-env.cc:133
tree_expression * control_expr(void)
Definition: pt-loop.h:296
tree_statement_list * body(void)
Definition: pt-loop.h:298
tree_argument_list * left_hand_side(void)
Definition: pt-loop.h:294
tree_decl_init_list * initializer_list(void)
Definition: pt-decl.h:201
bool is_global(void) const
Definition: pt-decl.h:83
tree_expression * expression(void)
Definition: pt-decl.h:92
tree_identifier * ident(void)
Definition: pt-decl.h:88
bool is_persistent(void) const
Definition: pt-decl.h:86
void accept(tree_walker &tw)
Definition: pt-decl.h:163
octave_user_code * get_user_code(const std::string &fname="", const std::string &class_name="")
Definition: pt-eval.cc:2253
symbol_scope get_top_scope(void) const
Definition: pt-eval.cc:2040
void clear_symbol_pattern(const std::string &pattern)
Definition: pt-eval.cc:2211
bool is_class_method_executing(std::string &dispatch_class) const
Definition: pt-eval.cc:1948
void visit_octave_user_function_header(octave_user_function &)
Definition: pt-eval.cc:2803
octave_function * caller_function(void) const
Definition: pt-eval.cc:1912
octave_user_code * current_user_code(void) const
Definition: pt-eval.cc:1892
bool at_top_level(void) const
Definition: pt-eval.cc:394
void remove_autoload(const std::string &fcn, const std::string &nm)
Definition: pt-eval.cc:3730
void clear_global_variables(void)
Definition: pt-eval.cc:2183
octave_map backtrace(void) const
Definition: pt-eval.cc:1990
size_t current_call_stack_frame_number(void) const
Definition: pt-eval.h:584
void visit_prefix_expression(tree_prefix_expression &)
Definition: pt-eval.cc:2956
octave_value evaluate(tree_decl_elt *)
Definition: pt-eval.cc:1245
void visit_statement_list(tree_statement_list &)
Definition: pt-eval.cc:3099
void visit_multi_assignment(tree_multi_assignment &)
Definition: pt-eval.cc:2912
void clear_objects(void)
Definition: pt-eval.cc:2127
std::string m_index_type
Definition: pt-eval.h:870
void set_auto_fcn_var(stack_frame::auto_var_type avt, const octave_value &val=octave_value())
Definition: pt-eval.cc:1587
bool mislocked(bool skip_first=false) const
Definition: pt-eval.cc:2082
int debug_user_code_line(void) const
Definition: pt-eval.cc:1875
octave_value global_varval(const std::string &name) const
Definition: pt-eval.cc:1358
std::list< octave_value_list > m_index_list
Definition: pt-eval.h:869
octave_value varval(const symbol_record &sym) const
Definition: pt-eval.cc:1330
std::list< std::string > autoloaded_functions(void) const
Definition: pt-eval.cc:3700
void visit_decl_command(tree_decl_command &)
Definition: pt-eval.cc:2359
bool in_debug_repl(void) const
Definition: pt-eval.cc:4076
void visit_boolean_expression(tree_boolean_expression &)
Definition: pt-eval.cc:717
bool is_defined(const tree_expression *expr) const
Definition: pt-eval.cc:1290
void visit_binary_expression(tree_binary_expression &)
Definition: pt-eval.cc:711
bool is_variable(const std::string &name) const
Definition: pt-eval.cc:1255
std::list< std::string > global_variable_names(void) const
Definition: pt-eval.cc:2233
void set_echo_state(int type, const std::string &file_name, size_t pos)
Definition: pt-eval.cc:3886
bool is_global(const std::string &name) const
Definition: pt-eval.cc:1321
octave_value make_fcn_handle(const std::string &nm)
Definition: pt-eval.cc:1011
octave_value & global_varref(const std::string &name)
Definition: pt-eval.cc:1364
symbol_info_list glob_symbol_info(const std::string &pattern) const
Definition: pt-eval.cc:3639
bool quiet_breakpoint_flag(void) const
Definition: pt-eval.h:589
void visit_cell(tree_cell &)
Definition: pt-eval.cc:2906
int dbstep_flag(void) const
Definition: pt-eval.h:710
int continuing(void) const
Definition: pt-eval.h:692
std::map< std::string, std::string > m_autoload_map
Definition: pt-eval.h:790
void clear_variables(void)
Definition: pt-eval.cc:2159
symbol_info_list top_scope_symbol_info(void) const
Definition: pt-eval.cc:3657
octave_value do_who(int argc, const string_vector &argv, bool return_list, bool verbose=false)
Definition: pt-eval.cc:3799
bool maybe_push_echo_state_cleanup(void)
Definition: pt-eval.cc:3929
void install_variable(const std::string &name, const octave_value &value, bool global)
Definition: pt-eval.cc:1347
std::string PS4(void) const
Definition: pt-eval.h:619
void clear_symbol_regexp(const std::string &pattern)
Definition: pt-eval.cc:2222
void visit_simple_for_command(tree_simple_for_command &)
Definition: pt-eval.cc:2413
void maybe_set_echo_state(void)
Definition: pt-eval.cc:3904
void visit_octave_user_function_trailer(octave_user_function &)
Definition: pt-eval.cc:2809
void clear_global_variable_pattern(const std::string &pattern)
Definition: pt-eval.cc:2173
void clear_global_variable_regexp(const std::string &pattern)
Definition: pt-eval.cc:2178
std::list< octave_lvalue > make_lvalue_list(tree_argument_list *)
Definition: pt-eval.cc:3861
octave_value m_indexed_object
Definition: pt-eval.h:868
bool switch_case_label_matches(tree_switch_case *expr, const octave_value &val)
Definition: pt-eval.cc:1802
std::string mfilename(const std::string &opt="") const
Definition: pt-eval.cc:432
std::list< frame_info > backtrace_info(void) const
Definition: pt-eval.cc:1978
void visit_parameter_list(tree_parameter_list &)
Definition: pt-eval.cc:2944
std::stack< debugger * > m_debugger_stack
Definition: pt-eval.h:810
bool silent_functions(void) const
Definition: pt-eval.h:552
const std::list< octave_lvalue > * m_lvalue_list
Definition: pt-eval.h:787
void visit_switch_command(tree_switch_command &)
Definition: pt-eval.cc:3161
void visit_decl_elt(tree_decl_elt &)
Definition: pt-eval.cc:2381
void visit_simple_assignment(tree_simple_assignment &)
Definition: pt-eval.cc:2985
octave_value_list execute_user_script(octave_user_script &user_script, int nargout, const octave_value_list &args)
Definition: pt-eval.cc:2628
void final_index_error(index_exception &e, const tree_expression *expr)
Definition: pt-eval.cc:3768
void restore_frame(size_t n)
Definition: pt-eval.cc:1932
void mlock(bool skip_first=false) const
Definition: pt-eval.cc:2050
void visit_do_until_command(tree_do_until_command &)
Definition: pt-eval.cc:3452
void undefine_parameter_list(tree_parameter_list *param_list)
Definition: pt-eval.cc:1627
void visit_if_command(tree_if_command &)
Definition: pt-eval.cc:2849
std::string m_echo_file_name
Definition: pt-eval.h:847
void visit_break_command(tree_break_command &)
Definition: pt-eval.cc:729
std::map< std::string, bool > m_echo_files
Definition: pt-eval.h:852
void bind_ans(const octave_value &val, bool print)
Definition: pt-eval.cc:3511
std::string current_function_name(bool skip_first=false) const
Definition: pt-eval.cc:2342
octave_value top_level_varval(const std::string &name) const
Definition: pt-eval.cc:1377
void visit_postfix_expression(tree_postfix_expression &)
Definition: pt-eval.cc:2950
std::string m_whos_line_format
Definition: pt-eval.h:817
octave_value_list execute_user_function(octave_user_function &user_function, int nargout, const octave_value_list &args)
Definition: pt-eval.cc:2673
int current_line(void) const
Definition: pt-eval.cc:1865
void goto_base_frame(void)
Definition: pt-eval.cc:1927
int breaking(void) const
Definition: pt-eval.h:683
octave_user_code * debug_user_code(void) const
Definition: pt-eval.cc:1902
std::list< std::string > variable_names(void) const
Definition: pt-eval.cc:2243
int debug_user_code_column(void) const
Definition: pt-eval.cc:1880
void pop_stack_frame(void)
Definition: pt-eval.cc:1860
void visit_if_clause(tree_if_clause &)
Definition: pt-eval.cc:2843
octave_value get_auto_fcn_var(stack_frame::auto_var_type avt) const
Definition: pt-eval.cc:1594
std::string backtrace_message(void) const
Definition: pt-eval.cc:2000
void visit_compound_binary_expression(tree_compound_binary_expression &)
Definition: pt-eval.cc:723
octave_function * current_function(bool skip_first=false) const
Definition: pt-eval.cc:1907
int num_indices(void) const
Definition: pt-eval.h:669
void visit_statement(tree_statement &)
Definition: pt-eval.cc:2991
int max_recursion_depth(void) const
Definition: pt-eval.h:540
void assignin(const std::string &context, const std::string &name, const octave_value &val=octave_value())
Definition: pt-eval.cc:1399
int echo(void) const
Definition: pt-eval.h:723
octave_map get_autoload_map(void) const
Definition: pt-eval.cc:3662
octave_value_list evalin(const std::string &context, const std::string &try_code, int nargout)
Definition: pt-eval.cc:617
void top_level_assign(const std::string &name, const octave_value &val=octave_value())
Definition: pt-eval.cc:1383
void visit_anon_fcn_handle(tree_anon_fcn_handle &)
Definition: pt-eval.cc:699
void source_file(const std::string &file_name, const std::string &context="", bool verbose=false, bool require_file=true)
Definition: pt-eval.cc:1435
std::string whos_line_format(void) const
Definition: pt-eval.h:563
std::string lookup_autoload(const std::string &nm) const
Definition: pt-eval.cc:3684
void clear_variable(const std::string &name)
Definition: pt-eval.cc:2135
bool goto_frame(size_t n=0, bool verbose=false)
Definition: pt-eval.cc:1917
bool is_class_constructor_executing(std::string &dispatch_class) const
Definition: pt-eval.cc:1954
void visit_index_expression(tree_index_expression &)
Definition: pt-eval.cc:2894
Matrix ignored_fcn_outputs(void) const
Definition: pt-eval.cc:853
void define_parameter_list_from_arg_vector(tree_parameter_list *param_list, const octave_value_list &args)
Definition: pt-eval.cc:1601
void uwp_set_echo_state(bool state, const std::string &file_name, size_t pos)
Definition: pt-eval.cc:3895
void clear_variable_pattern(const std::string &pattern)
Definition: pt-eval.cc:2143
void pop_scope(void)
Definition: pt-eval.cc:2035
void visit_return_command(tree_return_command &)
Definition: pt-eval.cc:2962
void clear_all(bool force=false)
Definition: pt-eval.cc:2188
std::string get_dispatch_class(void) const
Definition: pt-eval.cc:1937
void visit_octave_user_function(octave_user_function &)
Definition: pt-eval.cc:2666
octave_value find(const std::string &name)
Definition: pt-eval.cc:2103
void visit_if_command_list(tree_if_command_list &)
Definition: pt-eval.cc:2868
unwind_protect * curr_fcn_unwind_protect_frame(void)
Definition: pt-eval.cc:1897
bool in_user_code(void) const
Definition: pt-eval.cc:2353
octave_value_list evaluate_end_expression(const octave_value_list &args)
Definition: pt-eval.cc:4124
bool eval_decl_elt(tree_decl_elt *elt)
Definition: pt-eval.cc:1780
interpreter & m_interpreter
Definition: pt-eval.h:782
symbol_info_list regexp_symbol_info(const std::string &pattern) const
Definition: pt-eval.cc:3645
octave_value max_stack_depth(const octave_value_list &args, int nargout)
Definition: pt-eval.cc:2093
void assign(const std::string &name, const octave_value &val=octave_value())
Definition: pt-eval.cc:1390
void set_dispatch_class(const std::string &class_name)
Definition: pt-eval.cc:1942
void display_call_stack(void) const
Definition: pt-eval.cc:2098
bool is_logically_true(tree_expression *expr, const char *warn_for)
Definition: pt-eval.cc:3615
void clear_global_variable(const std::string &name)
Definition: pt-eval.cc:2167
octave_value PS4(const octave_value_list &args, int nargout)
Definition: pt-eval.cc:4221
symbol_info_list get_symbol_info(void)
Definition: pt-eval.cc:3651
void push_dummy_scope(const std::string &name)
Definition: pt-eval.cc:2028
octave_value whos_line_format(const octave_value_list &args, int nargout)
Definition: pt-eval.cc:3744
bool statement_printing_enabled(void)
Definition: pt-eval.cc:771
void push_echo_state(int type, const std::string &file_name, size_t pos=1)
Definition: pt-eval.cc:3872
void keyboard(const std::string &prompt="keyboard> ")
Definition: pt-eval.cc:841
int returning(void) const
Definition: pt-eval.h:701
void visit_identifier(tree_identifier &)
Definition: pt-eval.cc:2837
void visit_while_command(tree_while_command &)
Definition: pt-eval.cc:3406
octave_map empty_backtrace(void) const
Definition: pt-eval.cc:1995
void visit_complex_for_command(tree_complex_for_command &)
Definition: pt-eval.cc:2547
void dbquit(bool all=false)
Definition: pt-eval.cc:4088
void bind_auto_fcn_vars(const string_vector &arg_names, const Matrix &ignored_outputs, int nargin, int nargout, bool takes_varargs, const octave_value_list &va_args)
Definition: pt-eval.cc:4297
call_stack m_call_stack
Definition: pt-eval.h:794
size_t debug_frame(void) const
Definition: pt-eval.h:575
octave_value_list convert_to_const_vector(tree_argument_list *arg_list)
Definition: pt-eval.cc:1685
std::list< std::shared_ptr< stack_frame > > backtrace_frames() const
Definition: pt-eval.cc:1966
stmt_list_type m_statement_context
Definition: pt-eval.h:785
std::string m_PS4
Definition: pt-eval.h:827
bool echo_this_file(const std::string &file, int type) const
Definition: pt-eval.cc:4226
void visit_constant(tree_constant &)
Definition: pt-eval.cc:2932
void dbupdown(int n, bool verbose=false)
Definition: pt-eval.cc:847
std::list< std::string > reverse_lookup_autoload(const std::string &nm) const
Definition: pt-eval.cc:3711
void add_autoload(const std::string &fcn, const std::string &nm)
Definition: pt-eval.cc:3722
std::string check_autoload_file(const std::string &nm) const
Definition: pt-eval.cc:4314
char string_fill_char(void) const
Definition: pt-eval.h:598
octave_value_list make_value_list(tree_argument_list *args, const string_vector &arg_nm)
Definition: pt-eval.cc:3806
void do_unwind_protect_cleanup_code(tree_statement_list *list)
Definition: pt-eval.cc:3271
void do_breakpoint(tree_statement &stmt)
Definition: pt-eval.cc:3539
void visit_switch_case_list(tree_switch_case_list &)
Definition: pt-eval.cc:3155
void eval(std::shared_ptr< tree_statement_list > &stmt_list, bool interactive)
Definition: pt-eval.cc:399
void goto_caller_frame(void)
Definition: pt-eval.cc:1922
void visit_switch_case(tree_switch_case &)
Definition: pt-eval.cc:3149
void visit_try_catch_command(tree_try_catch_command &)
Definition: pt-eval.cc:3201
std::shared_ptr< stack_frame > current_user_frame(void) const
Definition: pt-eval.h:397
void visit_octave_user_script(octave_user_script &)
Definition: pt-eval.cc:2621
void visit_matrix(tree_matrix &)
Definition: pt-eval.cc:2900
void clear_symbol(const std::string &name)
Definition: pt-eval.cc:2200
void reset_debug_state(void)
Definition: pt-eval.cc:778
void visit_continue_command(tree_continue_command &)
Definition: pt-eval.cc:754
void visit_function_def(tree_function_def &)
Definition: pt-eval.cc:2815
void visit_argument_list(tree_argument_list &)
Definition: pt-eval.cc:705
void debug_where(std::ostream &os) const
Definition: pt-eval.cc:1885
void visit_unwind_protect_command(tree_unwind_protect_command &)
Definition: pt-eval.cc:3353
octave_value_list eval_string(const std::string &eval_str, bool silent, int &parse_status, int nargout)
Definition: pt-eval.cc:468
void munlock(bool skip_first=false) const
Definition: pt-eval.cc:2066
void enter_debugger(const std::string &prompt="debug> ")
Definition: pt-eval.cc:791
void push_echo_state_cleanup(unwind_protect &frame)
Definition: pt-eval.cc:3923
void visit_metaclass_query(tree_metaclass_query &)
Definition: pt-eval.cc:3506
void global_assign(const std::string &name, const octave_value &val=octave_value())
Definition: pt-eval.cc:1370
int current_column(void) const
Definition: pt-eval.cc:1870
void push_stack_frame(const symbol_scope &scope)
Definition: pt-eval.cc:1833
void clear_variable_regexp(const std::string &pattern)
Definition: pt-eval.cc:2151
void echo_code(size_t line)
Definition: pt-eval.cc:4259
bool is_local_variable(const std::string &name) const
Definition: pt-eval.cc:1264
std::list< std::string > top_level_variable_names(void) const
Definition: pt-eval.cc:2238
void visit_colon_expression(tree_colon_expression &)
Definition: pt-eval.cc:748
void visit_superclass_ref(tree_superclass_ref &)
Definition: pt-eval.cc:3500
bool quit_loop_now(void)
Definition: pt-eval.cc:4280
octave_value echo(const octave_value_list &args, int nargout)
Definition: pt-eval.cc:3949
symbol_scope get_current_scope(void) const
Definition: pt-eval.cc:2045
int index_position(void) const
Definition: pt-eval.h:667
void visit_fcn_handle(tree_fcn_handle &)
Definition: pt-eval.cc:2938
octave_value_list convert_return_list_to_const_vector(tree_parameter_list *ret_list, int nargout, const Matrix &ignored_outputs, const Cell &varargout)
Definition: pt-eval.cc:1714
void visit_no_op_command(tree_no_op_command &)
Definition: pt-eval.cc:2918
virtual bool is_identifier(void) const
Definition: pt-exp.h:70
virtual octave_value_list evaluate_n(tree_evaluator &tw, int nargout=1)=0
virtual octave_lvalue lvalue(tree_evaluator &)
Definition: pt-exp.cc:43
virtual std::string name(void) const
Definition: pt-exp.h:103
virtual octave_value evaluate(tree_evaluator &tw, int nargout=1)=0
virtual bool is_assignment_expression(void) const
Definition: pt-exp.h:74
tree_expression * set_print_flag(bool print)
Definition: pt-exp.h:125
bool print_result(void) const
Definition: pt-exp.h:99
octave_value function(void)
Definition: pt-cmd.h:119
octave_value evaluate(tree_evaluator &tw, int nargout=1)
Definition: pt-id.h:96
octave_lvalue lvalue(tree_evaluator &tw)
Definition: pt-id.cc:69
symbol_record symbol(void) const
Definition: pt-id.h:110
virtual bool is_black_hole(void) const
Definition: pt-id.h:75
void accept(tree_walker &tw)
Definition: pt-select.h:116
tree_if_command_list * cmd_list(void)
Definition: pt-select.h:143
static bool execute(tree_simple_for_command &cmd, const octave_value &bounds)
Definition: pt-jit.h:486
bool is_end_of_fcn_or_script(void) const
Definition: pt-cmd.h:81
bool takes_varargs(void) const
Definition: pt-misc.h:85
tree_expression * control_expr(void)
Definition: pt-loop.h:210
tree_expression * left_hand_side(void)
Definition: pt-loop.h:208
tree_statement_list * body(void)
Definition: pt-loop.h:214
void accept(tree_walker &tw)
Definition: pt-stmt.h:199
bool is_end_of_fcn_or_script(void) const
Definition: pt-stmt.cc:150
bool is_active_breakpoint(tree_evaluator &tw) const
Definition: pt-stmt.cc:102
int column(void) const
Definition: pt-stmt.cc:125
int line(void) const
Definition: pt-stmt.cc:117
bool is_expression(void) const
Definition: pt-stmt.h:80
tree_expression * expression(void)
Definition: pt-stmt.h:101
void accept(tree_walker &tw)
Definition: pt-stmt.h:122
tree_command * command(void)
Definition: pt-stmt.h:99
tree_expression * case_label(void)
Definition: pt-select.h:194
tree_switch_case_list * case_list(void)
Definition: pt-select.h:271
tree_expression * switch_value(void)
Definition: pt-select.h:269
tree_statement_list * cleanup(void)
Definition: pt-except.h:74
tree_identifier * identifier(void)
Definition: pt-except.h:70
tree_statement_list * body(void)
Definition: pt-except.h:72
tree_statement_list * cleanup(void)
Definition: pt-except.h:141
tree_statement_list * body(void)
Definition: pt-except.h:139
tree_statement_list * body(void)
Definition: pt-loop.h:90
tree_expression * condition(void)
Definition: pt-loop.h:88
virtual int column(void) const
Definition: pt.h:62
bool is_active_breakpoint(tree_evaluator &tw) const
Definition: pt.h:99
virtual void accept(tree_walker &tw)=0
virtual int line(void) const
Definition: pt.h:60
virtual bool is_user_code(void) const
Definition: ov-base.h:473
virtual bool is_user_function(void) const
Definition: ov-base.h:471
virtual bool is_builtin_function(void) const
Definition: ov-base.h:475
octave::cdef_object get_object(void) const
Definition: ov-classdef.h:74
octave_classdef * classdef_object_value(bool=false)
Definition: ov-classdef.h:72
std::string class_name(void) const
Definition: ov-classdef.h:147
std::string dispatch_class(void) const
Definition: ov-fcn.h:151
bool is_private_function(void) const
Definition: ov-fcn.h:164
bool is_class_method(const std::string &cname="") const
Definition: ov-fcn.h:118
bool is_class_constructor(const std::string &cname="") const
Definition: ov-fcn.h:113
virtual bool is_subfunction(void) const
Definition: ov-fcn.h:111
void unlock(void)
Definition: ov-fcn.h:183
virtual std::list< std::string > parent_fcn_names(void) const
Definition: ov-fcn.h:90
bool islocked(void) const
Definition: ov-fcn.h:189
virtual octave_value_list call(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
Definition: ov-fcn.cc:50
void lock(void)
Definition: ov-fcn.h:177
std::string name(void) const
Definition: ov-fcn.h:214
virtual bool is_nested_function(void) const
Definition: ov-fcn.h:107
string_vector keys(void) const
Definition: oct-map.h:356
const Cell & contents(const_iterator p) const
Definition: oct-map.h:331
void assign(const std::string &k, const octave_value &val)
Definition: oct-map.h:238
std::string get_code_line(size_t line)
Definition: ov-usr-fcn.cc:101
std::string fcn_file_name(void) const
Definition: ov-usr-fcn.h:110
octave::tree_statement_list * body(void)
Definition: ov-usr-fcn.h:123
virtual octave_value find_subfunction(const std::string &) const
Definition: ov-usr-fcn.h:116
std::deque< std::string > get_code_lines(size_t line, size_t num_lines)
Definition: ov-usr-fcn.cc:110
Cell cell_value(void) const
Definition: ovl.h:105
bool empty(void) const
Definition: ovl.h:115
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:117
void stash_name_tags(const string_vector &nm)
Definition: ovl.h:165
octave_idx_type length(void) const
Definition: ovl.h:113
string_vector name_tags(void) const
Definition: ovl.h:167
octave_value_list slice(octave_idx_type offset, octave_idx_type len, bool tags=false) const
Definition: ovl.h:131
string_vector make_argv(const std::string &="") const
Definition: ovl.cc:227
bool is_function(void) const
Definition: ov.h:730
bool iscell(void) const
Definition: ov.h:560
Cell xcell_value(const char *fmt,...) const
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition: ov.h:449
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Definition: ov.h:475
bool is_true(void) const
Definition: ov.h:711
bool is_scalar_type(void) const
Definition: ov.h:697
Range range_value(void) const
Definition: ov.h:938
bool is_cs_list(void) const
Definition: ov.h:626
bool is_string(void) const
Definition: ov.h:593
octave_user_code * user_code_value(bool silent=false) const
bool is_user_code(void) const
Definition: ov.h:739
bool is_defined(void) const
Definition: ov.h:551
Cell cell_value(void) const
bool is_equal(const octave_value &) const
std::string class_name(void) const
Definition: ov.h:1256
@ op_asn_eq
Definition: ov.h:139
int ndims(void) const
Definition: ov.h:510
octave_function * function_value(bool silent=false) const
bool isstruct(void) const
Definition: ov.h:605
octave_value reshape(const dim_vector &dv) const
Definition: ov.h:530
@ magic_colon_t
Definition: ov.h:173
bool is_matrix_type(void) const
Definition: ov.h:700
octave_value storable_value(void) const
bool is_range(void) const
Definition: ov.h:602
octave_value_list list_value(void) const
bool isobject(void) const
Definition: ov.h:620
std::string xstring_value(const char *fmt,...) const
octave_map map_value(void) const
bool is_undefined(void) const
Definition: ov.h:554
dim_vector dims(void) const
Definition: ov.h:500
octave_idx_type numel(void) const
Definition: str-vec.h:100
OCTINTERP_API void print_usage(void)
Definition: defun.cc:53
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:138
#define DEFCONSTMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method that cannot be hidden by a variable.
Definition: defun.h:202
void error_with_id(const char *id, const char *fmt,...)
Definition: error.cc:1013
void warning(const char *fmt,...)
Definition: error.cc:1050
void interpreter_try(octave::unwind_protect &frame)
Definition: error.cc:2182
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:1065
void error(const char *fmt,...)
Definition: error.cc:968
#define panic_impossible()
Definition: error.h:380
void err_indexed_cs_list(void)
Definition: errwarn.cc:65
QString name
bool octave_completion_matches_called
Definition: input.cc:86
T octave_idx_type m
Definition: mx-inlines.cc:773
octave_idx_type n
Definition: mx-inlines.cc:753
char dir_sep_char(void)
Definition: file-ops.cc:234
std::string dir_sep_str(void)
Definition: file-ops.cc:243
std::string tilde_expand(const std::string &name)
Definition: file-ops.cc:286
std::string dir_sep_chars(void)
Definition: file-ops.cc:252
std::string canonicalize_file_name(const std::string &name)
Definition: file-ops.cc:693
octave_value parse_fcn_file(interpreter &interp, const std::string &full_file, const std::string &file, const std::string &dir_name, const std::string &dispatch_type, const std::string &package_name, bool require_file, bool force_script, bool autoload, bool relative_lookup)
Definition: oct-parse.cc:9127
static uint32_t state[624]
Definition: randmtzig.cc:190
bool valid_identifier(const char *s)
Definition: utils.cc:77
static double f(double k, double l_nu, double c_pm)
Definition: randpoisson.cc:118
static llvm::LLVMContext & context
Definition: jit-typeinfo.cc:80
bool iskeyword(const std::string &s)
Definition: lex.cc:1283
static std::string get_operator_function_name(const std::string &name)
Definition: pt-eval.cc:890
std::string fcn_file_in_path(const std::string &name)
Definition: utils.cc:592
static octave_value end_value(const octave_value &value, octave_idx_type index_position, octave_idx_type num_indices)
Definition: pt-eval.cc:4094
octave_value_list feval(const char *name, const octave_value_list &args, int nargout)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
Definition: oct-parse.cc:9580
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
#define octave_stdout
Definition: pager.h:313
sig_atomic_t octave_interrupt_state
Definition: quit.cc:38
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)
Definition: variables.cc:608
F77_RET_T len
Definition: xerbla.cc:61