GNU Octave  4.0.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
symtab.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2015 John W. Eaton
4 Copyright (C) 2009 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if !defined (octave_symtab_h)
25 #define octave_symtab_h 1
26 
27 #include <deque>
28 #include <list>
29 #include <map>
30 #include <set>
31 #include <string>
32 
33 #include "glob-match.h"
34 #include "lo-regexp.h"
35 
36 class tree_argument_list;
38 
39 #include "oct-obj.h"
40 #include "workspace-element.h"
41 #include "oct-refcount.h"
42 #include "ov.h"
43 
44 class
47 {
48 public:
49 
50  typedef int scope_id;
51  typedef size_t context_id;
52 
53  class
55  {
56  protected:
57 
58  typedef std::set<scope_id>::iterator set_iterator;
59  typedef std::set<scope_id>::const_iterator set_const_iterator;
60 
61  // We start with 2 because we allocate 0 for the global symbols
62  // and 1 for the top-level workspace.
63 
64  scope_id_cache (void) : next_available (2), in_use (), free_list () { }
65 
66  public:
67 
68  ~scope_id_cache (void) { }
69 
70  static scope_id alloc (void)
71  {
72  return instance_ok () ? instance->do_alloc () : -1;
73  }
74 
75  static void free (scope_id scope)
76  {
77  if (instance_ok ())
78  return instance->do_free (scope);
79  }
80 
81  static std::list<scope_id> scopes (void)
82  {
83  return instance_ok () ? instance->do_scopes () : std::list<scope_id> ();
84  }
85 
86  static void create_instance (void);
87 
88  static bool instance_ok (void)
89  {
90  bool retval = true;
91 
92  if (! instance)
93  create_instance ();
94 
95  if (! instance)
96  {
97  ::error ("unable to create scope_id_cache object!");
98 
99  retval = false;
100  }
101 
102  return retval;
103  }
104 
105  private:
106 
107  // No copying!
108 
110 
112 
114 
115  static void cleanup_instance (void) { delete instance; instance = 0; }
116 
117  // The next available scope not in the free list.
118  scope_id next_available;
119 
120  // The set of scope IDs that are currently allocated.
121  std::set<scope_id> in_use;
122 
123  // The set of scope IDs that are currently available.
124  std::set<scope_id> free_list;
125 
126  scope_id do_alloc (void)
127  {
128  scope_id retval;
129 
130  set_iterator p = free_list.begin ();
131 
132  if (p != free_list.end ())
133  {
134  retval = *p;
135  free_list.erase (p);
136  }
137  else
138  retval = next_available++;
139 
140  in_use.insert (retval);
141 
142  return retval;
143  }
144 
145  void do_free (scope_id scope)
146  {
147  set_iterator p = in_use.find (scope);
148 
149  if (p != in_use.end ())
150  {
151  in_use.erase (p);
152  free_list.insert (scope);
153  }
154  else
155  error ("free_scope: scope %d not found!", scope);
156  }
157 
158  std::list<scope_id> do_scopes (void) const
159  {
160  std::list<scope_id> retval;
161 
162  for (set_const_iterator p = in_use.begin (); p != in_use.end (); p++)
163  retval.push_back (*p);
164 
165  retval.sort ();
166 
167  return retval;
168  }
169  };
170 
171  class fcn_info;
172 
173  class
175  {
176  public:
177 
178  // generic variable
179  static const unsigned int local = 1;
180 
181  // varargin, argn, .nargin., .nargout.
182  // (FIXME -- is this really used now?)
183  static const unsigned int automatic = 2;
184 
185  // formal parameter
186  static const unsigned int formal = 4;
187 
188  // not listed or cleared (.nargin., .nargout.)
189  static const unsigned int hidden = 8;
190 
191  // inherited from parent scope; not cleared at function exit
192  static const unsigned int inherited = 16;
193 
194  // global (redirects to global scope)
195  static const unsigned int global = 32;
196 
197  // not cleared at function exit
198  static const unsigned int persistent = 64;
199 
200  // this symbol may NOT become a variable.
201  // (symbol added to a static workspace)
202  static const unsigned int added_static = 128;
203 
204  private:
205 
206  class
208  {
209  public:
210 
211  symbol_record_rep (scope_id s, const std::string& nm,
212  const octave_value& v, unsigned int sc)
213  : decl_scope (s), curr_fcn (0), name (nm), value_stack (),
214  storage_class (sc), finfo (), valid (true), count (1)
215  {
216  value_stack.push_back (v);
217  }
218 
219  void assign (const octave_value& value,
220  context_id context = xdefault_context)
221  {
222  varref (context) = value;
223  }
224 
226  const std::string& type,
227  const std::list<octave_value_list>& idx,
228  const octave_value& value,
229  context_id context = xdefault_context)
230  {
231  varref(context).assign (op, type, idx, value);
232  }
233 
235  context_id context = xdefault_context)
236  {
237  varref(context).assign (op, value);
238  }
239 
241  context_id context = xdefault_context)
242  {
243  varref(context).do_non_const_unary_op (op);
244  }
245 
247  const std::string& type,
248  const std::list<octave_value_list>& idx,
249  context_id context = xdefault_context)
250  {
251  varref(context).do_non_const_unary_op (op, type, idx);
252  }
253 
254  octave_value& varref (context_id context = xdefault_context)
255  {
256  // We duplicate global_varref and persistent_varref here to
257  // avoid calling deprecated functions.
258 
259  if (is_global ())
260  {
262  = symbol_table::global_table.find (name);
263 
264  return (p == symbol_table::global_table.end ())
265  ? symbol_table::global_table[name] : p->second;
266  }
267  else if (is_persistent ())
268  {
269  static octave_value foobar;
270 
271  symbol_table *inst
273 
274  return inst ? inst->do_persistent_varref (name) : foobar;
275  }
276  else
277  {
278  if (context == xdefault_context)
279  context = active_context ();
280 
281  context_id n = value_stack.size ();
282  while (n++ <= context)
283  value_stack.push_back (octave_value ());
284 
285  return value_stack[context];
286  }
287  }
288 
289  octave_value varval (context_id context = xdefault_context) const
290  {
291  if (is_global ())
292  return symbol_table::global_varval (name);
293  else if (is_persistent ())
294  return symbol_table::persistent_varval (name);
295  else
296  {
297  if (context == xdefault_context)
298  context = active_context ();
299 
300  if (context < value_stack.size ())
301  return value_stack[context];
302  else
303  return octave_value ();
304  }
305  }
306 
307  void push_context (scope_id s)
308  {
309  if (! (is_persistent () || is_global ())
310  && s == scope ())
311  value_stack.push_back (octave_value ());
312  }
313 
314  // If pop_context returns 0, we are out of values and this element
315  // of the symbol table should be deleted. This can happen for
316  // functions like
317  //
318  // function foo (n)
319  // if (n > 0)
320  // foo (n-1);
321  // else
322  // eval ("x = 1");
323  // endif
324  // endfunction
325  //
326  // Here, X should only exist in the final stack frame.
327 
328  size_t pop_context (scope_id s)
329  {
330  size_t retval = 1;
331 
332  if (! (is_persistent () || is_global ())
333  && s == scope ())
334  {
335  value_stack.pop_back ();
336  retval = value_stack.size ();
337  }
338 
339  return retval;
340  }
341 
342  void clear (void) { clear (scope ()); }
343 
344  void clear (scope_id s)
345  {
346  if (! (is_hidden () || is_inherited ())
347  && s == scope ())
348  {
349  if (is_global ())
350  unmark_global ();
351 
352  if (is_persistent ())
353  {
354  symbol_table::persistent_assign (name, varval ());
355 
356  unmark_persistent ();
357  }
358 
359  assign (octave_value ());
360  }
361  }
362 
363  bool is_defined (context_id context = xdefault_context) const
364  {
365  if (context == xdefault_context)
366  context = active_context ();
367 
368  return varval (context).is_defined ();
369  }
370 
371  bool is_valid (void) const
372  {
373  return valid;
374  }
375 
376  bool is_variable (context_id context) const
377  {
378  if (context == xdefault_context)
379  context = active_context ();
380 
381  return (! is_local () || is_defined (context));
382  }
383 
384  bool is_local (void) const { return storage_class & local; }
385  bool is_automatic (void) const { return storage_class & automatic; }
386  bool is_formal (void) const { return storage_class & formal; }
387  bool is_hidden (void) const { return storage_class & hidden; }
388  bool is_inherited (void) const { return storage_class & inherited; }
389  bool is_global (void) const { return storage_class & global; }
390  bool is_persistent (void) const { return storage_class & persistent; }
391  bool is_added_static (void) const {return storage_class & added_static; }
392 
393  void mark_local (void) { storage_class |= local; }
394  void mark_automatic (void) { storage_class |= automatic; }
395  void mark_formal (void) { storage_class |= formal; }
396  void mark_hidden (void) { storage_class |= hidden; }
397  void mark_inherited (void) { storage_class |= inherited; }
398  void mark_global (void)
399  {
400  if (is_persistent ())
401  error ("can't make persistent variable %s global", name.c_str ());
402  else
403  storage_class |= global;
404  }
405  void mark_persistent (void)
406  {
407  if (is_global ())
408  error ("can't make global variable %s persistent", name.c_str ());
409  else
410  storage_class |= persistent;
411  }
412  void mark_added_static (void) { storage_class |= added_static; }
413 
414  void unmark_local (void) { storage_class &= ~local; }
415  void unmark_automatic (void) { storage_class &= ~automatic; }
416  void unmark_formal (void) { storage_class &= ~formal; }
417  void unmark_hidden (void) { storage_class &= ~hidden; }
418  void unmark_inherited (void) { storage_class &= ~inherited; }
419  void unmark_global (void) { storage_class &= ~global; }
420  void unmark_persistent (void) { storage_class &= ~persistent; }
421  void unmark_added_static (void) { storage_class &= ~added_static; }
422 
423  void init_persistent (void)
424  {
425  if (! is_defined ())
426  {
427  mark_persistent ();
428 
429  assign (symbol_table::persistent_varval (name));
430  }
431  // FIXME: this causes trouble with recursive calls.
432  // else
433  // error ("unable to declare existing variable persistent");
434  }
435 
436  void invalidate (void)
437  {
438  valid = false;
439  }
440 
441  void erase_persistent (void)
442  {
443  unmark_persistent ();
445  }
446 
447  OCTINTERP_API context_id active_context (void) const;
448 
449  scope_id scope (void) const { return decl_scope; }
450 
452  {
453  curr_fcn = fcn;
454  }
455 
456  symbol_record_rep *dup (scope_id new_scope) const
457  {
458  return new symbol_record_rep (new_scope, name, varval (),
459  storage_class);
460  }
461 
462  void dump (std::ostream& os, const std::string& prefix) const;
463 
464  scope_id decl_scope;
465 
467 
468  std::string name;
469 
470  std::deque<octave_value> value_stack;
471 
472  unsigned int storage_class;
473 
475 
476  bool valid;
477 
479 
480  private:
481 
482  // No copying!
483 
485 
486  symbol_record_rep& operator = (const symbol_record_rep&);
487  };
488 
489  public:
490 
491  symbol_record (scope_id s = xcurrent_scope,
492  const std::string& nm = std::string (),
493  const octave_value& v = octave_value (),
494  unsigned int sc = local)
495  : rep (new symbol_record_rep (s, nm, v, sc)) { }
496 
498  : rep (sr.rep)
499  {
500  rep->count++;
501  }
502 
503  symbol_record& operator = (const symbol_record& sr)
504  {
505  if (this != &sr)
506  {
507  if (--rep->count == 0)
508  delete rep;
509 
510  rep = sr.rep;
511  rep->count++;
512  }
513 
514  return *this;
515  }
516 
518  {
519  if (--rep->count == 0)
520  delete rep;
521  }
522 
523  symbol_record dup (scope_id new_scope) const
524  {
525  return symbol_record (rep->dup (new_scope));
526  }
527 
528  const std::string& name (void) const { return rep->name; }
529 
530  void rename (const std::string& new_name) { rep->name = new_name; }
531 
533  find (const octave_value_list& args = octave_value_list ()) const;
534 
535  void assign (const octave_value& value,
536  context_id context = xdefault_context)
537  {
538  rep->assign (value, context);
539  }
540 
542  const std::string& type,
543  const std::list<octave_value_list>& idx,
544  const octave_value& value,
545  context_id context = xdefault_context)
546  {
547  rep->assign (op, type, idx, value, context);
548  }
549 
551  context_id context = xdefault_context)
552  {
553  rep->assign (op, value, context);
554  }
555 
557  {
558  rep->do_non_const_unary_op (op);
559  }
560 
562  const std::string& type,
563  const std::list<octave_value_list>& idx)
564  {
565  rep->do_non_const_unary_op (op, type, idx);
566  }
567 
568  // Delete when deprecated varref functions are removed.
569  octave_value& varref (context_id context = xdefault_context)
570  {
571  return rep->varref (context);
572  }
573 
574  octave_value varval (context_id context = xdefault_context) const
575  {
576  return rep->varval (context);
577  }
578 
579  void push_context (scope_id s) { rep->push_context (s); }
580 
581  size_t pop_context (scope_id s) { return rep->pop_context (s); }
582 
583  void clear (void) { rep->clear (); }
584 
585  void clear (scope_id s) { rep->clear (s); }
586 
587  bool is_defined (context_id context = xdefault_context) const
588  {
589  return rep->is_defined (context);
590  }
591 
592  bool is_undefined (context_id context = xdefault_context) const
593  {
594  return ! rep->is_defined (context);
595  }
596 
597  bool is_valid (void) const
598  {
599  return rep->is_valid ();
600  }
601 
602  bool is_variable (context_id context = xdefault_context) const
603  {
604  return rep->is_variable (context);
605  }
606 
607  bool is_local (void) const { return rep->is_local (); }
608  bool is_automatic (void) const { return rep->is_automatic (); }
609  bool is_formal (void) const { return rep->is_formal (); }
610  bool is_global (void) const { return rep->is_global (); }
611  bool is_hidden (void) const { return rep->is_hidden (); }
612  bool is_inherited (void) const { return rep->is_inherited (); }
613  bool is_persistent (void) const { return rep->is_persistent (); }
614  bool is_added_static (void) const { return rep->is_added_static (); }
615 
616  void mark_local (void) { rep->mark_local (); }
617  void mark_automatic (void) { rep->mark_automatic (); }
618  void mark_formal (void) { rep->mark_formal (); }
619  void mark_hidden (void) { rep->mark_hidden (); }
620  void mark_inherited (void) { rep->mark_inherited (); }
621  void mark_global (void) { rep->mark_global (); }
622  void mark_persistent (void) { rep->mark_persistent (); }
623  void mark_added_static (void) { rep->mark_added_static (); }
624 
625  void unmark_local (void) { rep->unmark_local (); }
626  void unmark_automatic (void) { rep->unmark_automatic (); }
627  void unmark_formal (void) { rep->unmark_formal (); }
628  void unmark_hidden (void) { rep->unmark_hidden (); }
629  void unmark_inherited (void) { rep->unmark_inherited (); }
630  void unmark_global (void) { rep->unmark_global (); }
631  void unmark_persistent (void) { rep->unmark_persistent (); }
632  void unmark_added_static (void) { rep->unmark_added_static (); }
633 
634  void init_persistent (void) { rep->init_persistent (); }
635 
636  void erase_persistent (void) { rep->erase_persistent (); }
637 
638  void invalidate (void) { rep->invalidate (); }
639 
640  context_id active_context (void) const { return rep->active_context (); }
641 
642  scope_id scope (void) const { return rep->scope (); }
643 
644  unsigned int xstorage_class (void) const { return rep->storage_class; }
645 
646  void set_curr_fcn (octave_user_function *fcn) { rep->set_curr_fcn (fcn); }
647 
648  void
649  dump (std::ostream& os, const std::string& prefix = std::string ()) const
650  {
651  rep->dump (os, prefix);
652  }
653 
654  private:
655 
657 
658  symbol_record (symbol_record_rep *new_rep) : rep (new_rep) { }
659  };
660 
661  // Always access a symbol from the current scope.
662  // Useful for scripts, as they may be executed in more than one scope.
663  class
665  {
666  public:
667 
668  symbol_reference (void) : scope (-1) { }
669 
671  scope_id curr_scope = symbol_table::current_scope ())
672  : scope (curr_scope), sym (record)
673  { }
674 
676  : scope (ref.scope), sym (ref.sym)
677  { }
678 
679  symbol_reference& operator = (const symbol_reference& ref)
680  {
681  if (this != &ref)
682  {
683  scope = ref.scope;
684  sym = ref.sym;
685  }
686  return *this;
687  }
688 
689  bool is_black_hole (void) const { return scope < 0; }
690 
691  // The name is the same regardless of scope.
692  const std::string& name (void) const { return sym.name (); }
693 
694  symbol_record *operator-> (void)
695  {
696  update ();
697  return &sym;
698  }
699 
700  symbol_record *operator-> (void) const
701  {
702  update ();
703  return &sym;
704  }
705 
706  // can be used to place symbol_reference in maps, we don't overload < as
707  // it doesn't make any sense for symbol_reference
708  struct comparator
709  {
710  bool operator ()(const symbol_reference& lhs,
711  const symbol_reference& rhs) const
712  {
713  return lhs.name () < rhs.name ();
714  }
715  };
716  private:
717 
718  void update (void) const
719  {
720  scope_id curr_scope = symbol_table::current_scope ();
721 
722  if (scope != curr_scope || ! sym.is_valid ())
723  {
724  scope = curr_scope;
725  sym = symbol_table::insert (sym.name ());
726  }
727  }
728 
729  mutable scope_id scope;
731  };
732 
733  class
734  fcn_info
735  {
736  public:
737 
738  typedef std::map<std::string, std::string> dispatch_map_type;
739 
740  typedef std::map<scope_id, octave_value>::const_iterator
742  typedef std::map<scope_id, octave_value>::iterator scope_val_iterator;
743 
744  typedef std::map<std::string, octave_value>::const_iterator
746  typedef std::map<std::string, octave_value>::iterator str_val_iterator;
747 
748  typedef dispatch_map_type::const_iterator dispatch_map_const_iterator;
749  typedef dispatch_map_type::iterator dispatch_map_iterator;
750 
751  private:
752 
753  class
755  {
756  public:
757 
758  fcn_info_rep (const std::string& nm)
759  : name (nm), package_name (), subfunctions (), private_functions (),
760  class_constructors (), class_methods (), dispatch_map (),
761  cmdline_function (), autoload_function (), function_on_path (),
762  built_in_function (), count (1)
763  {
764  size_t pos = name.rfind ('.');
765 
766  if (pos != std::string::npos)
767  {
768  package_name = name.substr (0, pos);
769  name = name.substr (pos+1);
770  }
771  }
772 
773  octave_value load_private_function (const std::string& dir_name);
774 
775  octave_value load_class_constructor (void);
776 
777  octave_value load_class_method (const std::string& dispatch_type);
778 
779  octave_value find (const octave_value_list& args, bool local_funcs);
780 
781  octave_value builtin_find (void);
782 
783  octave_value find_method (const std::string& dispatch_type);
784 
785  octave_value find_autoload (void);
786 
787  octave_value find_package (void);
788 
789  octave_value find_user_function (void);
790 
791  bool is_user_function_defined (void) const
792  {
793  return function_on_path.is_defined ();
794  }
795 
797  bool local_funcs)
798  {
799  return find (args, local_funcs);
800  }
801 
802  void lock_subfunction (scope_id scope)
803  {
804  scope_val_iterator p = subfunctions.find (scope);
805 
806  if (p != subfunctions.end ())
807  p->second.lock ();
808  }
809 
810  void unlock_subfunction (scope_id scope)
811  {
812  scope_val_iterator p = subfunctions.find (scope);
813 
814  if (p != subfunctions.end ())
815  p->second.unlock ();
816  }
817 
818  std::pair<std::string, octave_value>
819  subfunction_defined_in_scope (scope_id scope) const
820  {
821  scope_val_const_iterator p = subfunctions.find (scope);
822 
823  return p == subfunctions.end ()
824  ? std::pair<std::string, octave_value> ()
825  : std::pair<std::string, octave_value> (name, p->second);
826  }
827 
828  void erase_subfunction (scope_id scope)
829  {
830  scope_val_iterator p = subfunctions.find (scope);
831 
832  if (p != subfunctions.end ())
833  subfunctions.erase (p);
834  }
835 
836  void mark_subfunction_in_scope_as_private (scope_id scope,
837  const std::string& class_name);
838 
840  {
841  cmdline_function = f;
842  }
843 
844  void install_subfunction (const octave_value& f, scope_id scope)
845  {
846  subfunctions[scope] = f;
847  }
848 
850  {
851  function_on_path = f;
852  }
853 
855  {
856  built_in_function = f;
857  }
858 
859  template <class T>
860  void
861  clear_map (std::map<T, octave_value>& map, bool force = false)
862  {
863  typename std::map<T, octave_value>::iterator p = map.begin ();
864 
865  while (p != map.end ())
866  {
867  if (force || ! p->second.islocked ())
868  map.erase (p++);
869  else
870  p++;
871  }
872  }
873 
874  void clear_autoload_function (bool force = false)
875  {
876  if (force || ! autoload_function.islocked ())
877  autoload_function = octave_value ();
878  }
879 
880  // We also clear command line functions here, as these are both
881  // "user defined"
882  void clear_user_function (bool force = false)
883  {
884  if (force || ! function_on_path.islocked ())
885  function_on_path = octave_value ();
886 
887  if (force || ! cmdline_function.islocked ())
888  cmdline_function = octave_value ();
889  }
890 
891  void clear_mex_function (void)
892  {
893  if (function_on_path.is_mex_function ())
894  clear_user_function ();
895  }
896 
897  void clear_package (void)
898  {
899  package = octave_value ();
900  }
901 
902  void clear (bool force = false)
903  {
904  clear_map (subfunctions, force);
905  clear_map (private_functions, force);
906  clear_map (class_constructors, force);
907  clear_map (class_methods, force);
908 
909  clear_autoload_function (force);
910  clear_user_function (force);
911  clear_package ();
912  }
913 
914  void add_dispatch (const std::string& type, const std::string& fname)
915  {
916  dispatch_map[type] = fname;
917  }
918 
919  void clear_dispatch (const std::string& type)
920  {
921  dispatch_map_iterator p = dispatch_map.find (type);
922 
923  if (p != dispatch_map.end ())
924  dispatch_map.erase (p);
925  }
926 
927  void print_dispatch (std::ostream& os) const;
928 
929  std::string help_for_dispatch (void) const;
930 
931  dispatch_map_type get_dispatch (void) const { return dispatch_map; }
932 
933  void dump (std::ostream& os, const std::string& prefix) const;
934 
935  std::string full_name (void) const
936  {
937  if (package_name.empty ())
938  return name;
939  else
940  return package_name + "." + name;
941  }
942 
943  std::string name;
944 
945  std::string package_name;
946 
947  // Scope id to function object.
948  std::map<scope_id, octave_value> subfunctions;
949 
950  // Directory name to function object.
951  std::map<std::string, octave_value> private_functions;
952 
953  // Class name to function object.
954  std::map<std::string, octave_value> class_constructors;
955 
956  // Dispatch type to function object.
957  std::map<std::string, octave_value> class_methods;
958 
959  // Legacy dispatch map (dispatch type name to function name).
960  dispatch_map_type dispatch_map;
961 
963 
965 
967 
969 
971 
973 
974  private:
975 
976  octave_value xfind (const octave_value_list& args, bool local_funcs);
977 
978  octave_value x_builtin_find (void);
979 
980  // No copying!
981 
982  fcn_info_rep (const fcn_info_rep&);
983 
984  fcn_info_rep& operator = (const fcn_info_rep&);
985  };
986 
987  public:
988 
989  fcn_info (const std::string& nm = std::string ())
990  : rep (new fcn_info_rep (nm)) { }
991 
992  fcn_info (const fcn_info& fi) : rep (fi.rep)
993  {
994  rep->count++;
995  }
996 
997  fcn_info& operator = (const fcn_info& fi)
998  {
999  if (this != &fi)
1000  {
1001  if (--rep->count == 0)
1002  delete rep;
1003 
1004  rep = fi.rep;
1005  rep->count++;
1006  }
1007 
1008  return *this;
1009  }
1010 
1011  ~fcn_info (void)
1012  {
1013  if (--rep->count == 0)
1014  delete rep;
1015  }
1016 
1018  bool local_funcs = true)
1019  {
1020  return rep->find (args, local_funcs);
1021  }
1022 
1024  {
1025  return rep->builtin_find ();
1026  }
1027 
1028  octave_value find_method (const std::string& dispatch_type) const
1029  {
1030  return rep->find_method (dispatch_type);
1031  }
1032 
1034  {
1035  return rep->built_in_function;
1036  }
1037 
1039  {
1040  return rep->cmdline_function;
1041  }
1042 
1044  {
1045  return rep->find_autoload ();
1046  }
1047 
1049  {
1050  return rep->find_user_function ();
1051  }
1052 
1053  bool is_user_function_defined (void) const
1054  {
1055  return rep->is_user_function_defined ();
1056  }
1057 
1059  = octave_value_list (),
1060  bool local_funcs = true)
1061  {
1062  return rep->find_function (args, local_funcs);
1063  }
1064 
1065  void lock_subfunction (scope_id scope)
1066  {
1067  rep->lock_subfunction (scope);
1068  }
1069 
1070  void unlock_subfunction (scope_id scope)
1071  {
1072  rep->unlock_subfunction (scope);
1073  }
1074 
1075  std::pair<std::string, octave_value>
1076  subfunction_defined_in_scope (scope_id scope = xcurrent_scope) const
1077  {
1078  return rep->subfunction_defined_in_scope (scope);
1079  }
1080 
1081  void erase_subfunction (scope_id scope)
1082  {
1083  rep->erase_subfunction (scope);
1084  }
1085 
1087  const std::string& class_name)
1088  {
1089  rep->mark_subfunction_in_scope_as_private (scope, class_name);
1090  }
1091 
1093  {
1094  rep->install_cmdline_function (f);
1095  }
1096 
1097  void install_subfunction (const octave_value& f, scope_id scope)
1098  {
1099  rep->install_subfunction (f, scope);
1100  }
1101 
1103  {
1104  rep->install_user_function (f);
1105  }
1106 
1108  {
1109  rep->install_built_in_function (f);
1110  }
1111 
1112  void clear (bool force = false) { rep->clear (force); }
1113 
1114  void clear_user_function (bool force = false)
1115  {
1116  rep->clear_user_function (force);
1117  }
1118 
1119  void clear_autoload_function (bool force = false)
1120  {
1121  rep->clear_autoload_function (force);
1122  }
1123 
1124  void clear_mex_function (void) { rep->clear_mex_function (); }
1125 
1126  void add_dispatch (const std::string& type, const std::string& fname)
1127  {
1128  rep->add_dispatch (type, fname);
1129  }
1130 
1131  void clear_dispatch (const std::string& type)
1132  {
1133  rep->clear_dispatch (type);
1134  }
1135 
1136  void print_dispatch (std::ostream& os) const
1137  {
1138  rep->print_dispatch (os);
1139  }
1140 
1141  std::string help_for_dispatch (void) const
1142  { return rep->help_for_dispatch (); }
1143 
1144  dispatch_map_type get_dispatch (void) const
1145  {
1146  return rep->get_dispatch ();
1147  }
1148 
1149  void
1150  dump (std::ostream& os, const std::string& prefix = std::string ()) const
1151  {
1152  rep->dump (os, prefix);
1153  }
1154 
1155  private:
1156 
1158  };
1159 
1160  static scope_id global_scope (void) { return xglobal_scope; }
1161  static scope_id top_scope (void) { return xtop_scope; }
1162 
1163  static scope_id current_scope (void) { return xcurrent_scope; }
1164 
1165  static context_id current_context (void) { return xcurrent_context; }
1166 
1167  static scope_id alloc_scope (void) { return scope_id_cache::alloc (); }
1168 
1169  static void set_scope (scope_id scope)
1170  {
1171  if (scope == xglobal_scope)
1172  error ("can't set scope to global");
1173  else if (scope != xcurrent_scope)
1174  {
1175  all_instances_iterator p = all_instances.find (scope);
1176 
1177  if (p == all_instances.end ())
1178  {
1179  symbol_table *inst = new symbol_table (scope);
1180 
1181  if (inst)
1182  all_instances[scope] = instance = inst;
1183  }
1184  else
1185  instance = p->second;
1186 
1187  xcurrent_scope = scope;
1188  xcurrent_context = 0;
1189  }
1190  }
1191 
1192  static void set_scope_and_context (scope_id scope, context_id context)
1193  {
1194  if (scope == xglobal_scope)
1195  error ("can't set scope to global");
1196  else
1197  {
1198  if (scope != xcurrent_scope)
1199  {
1200  all_instances_iterator p = all_instances.find (scope);
1201 
1202  if (p == all_instances.end ())
1203  error ("scope not found!");
1204  else
1205  {
1206  instance = p->second;
1207 
1208  xcurrent_scope = scope;
1209 
1210  xcurrent_context = context;
1211  }
1212  }
1213  else
1214  xcurrent_context = context;
1215  }
1216  }
1217 
1218  static void erase_scope (scope_id scope)
1219  {
1220  assert (scope != xglobal_scope);
1221 
1222  erase_subfunctions_in_scope (scope);
1223 
1224  all_instances_iterator p = all_instances.find (scope);
1225 
1226  if (p != all_instances.end ())
1227  {
1228  delete p->second;
1229 
1230  all_instances.erase (p);
1231 
1232  free_scope (scope);
1233  }
1234  }
1235 
1236  static void erase_subfunctions_in_scope (scope_id scope)
1237  {
1238  for (fcn_table_iterator q = fcn_table.begin (); q != fcn_table.end (); q++)
1239  q->second.erase_subfunction (scope);
1240  }
1241 
1242  static void
1244  const std::string& class_name)
1245  {
1246  for (fcn_table_iterator q = fcn_table.begin (); q != fcn_table.end (); q++)
1247  q->second.mark_subfunction_in_scope_as_private (scope, class_name);
1248  }
1249 
1250  static scope_id dup_scope (scope_id scope)
1251  {
1252  scope_id retval = -1;
1253 
1254  symbol_table *inst = get_instance (scope);
1255 
1256  if (inst)
1257  {
1258  scope_id new_scope = alloc_scope ();
1259 
1260  symbol_table *new_symbol_table = new symbol_table (scope);
1261 
1262  if (new_symbol_table)
1263  {
1264  all_instances[new_scope] = new_symbol_table;
1265 
1266  inst->do_dup_scope (*new_symbol_table);
1267 
1268  retval = new_scope;
1269  }
1270  }
1271 
1272  return retval;
1273  }
1274 
1275  static std::list<scope_id> scopes (void)
1276  {
1277  return scope_id_cache::scopes ();
1278  }
1279 
1280  static symbol_record
1281  find_symbol (const std::string& name, scope_id scope = xcurrent_scope)
1282  {
1283  symbol_table *inst = get_instance (scope);
1284 
1285  return inst ? inst->do_find_symbol (name) :
1286  symbol_record (scope);
1287  }
1288 
1289  static void
1290  inherit (scope_id scope, scope_id donor_scope, context_id donor_context)
1291  {
1292  symbol_table *inst = get_instance (scope);
1293 
1294  if (inst)
1295  {
1296  symbol_table *donor_symbol_table = get_instance (donor_scope);
1297 
1298  if (donor_symbol_table)
1299  inst->do_inherit (*donor_symbol_table, donor_context);
1300  }
1301  }
1302 
1303  static bool at_top_level (void) { return xcurrent_scope == xtop_scope; }
1304 
1305  // Find a value corresponding to the given name in the table.
1306  static octave_value
1307  find (const std::string& name,
1308  const octave_value_list& args = octave_value_list (),
1309  bool skip_variables = false,
1310  bool local_funcs = true);
1311 
1312  static octave_value builtin_find (const std::string& name);
1313 
1314  // Insert a new name in the table.
1315  static symbol_record& insert (const std::string& name,
1316  scope_id scope = xcurrent_scope)
1317  {
1318  static symbol_record foobar;
1319 
1320  symbol_table *inst = get_instance (scope);
1321 
1322  return inst ? inst->do_insert (name) : foobar;
1323  }
1324 
1325  static void rename (const std::string& old_name,
1326  const std::string& new_name,
1327  scope_id scope = xcurrent_scope)
1328  {
1329  symbol_table *inst = get_instance (scope);
1330 
1331  if (inst)
1332  inst->do_rename (old_name, new_name);
1333  }
1334 
1335  static void assign (const std::string& name,
1336  const octave_value& value = octave_value (),
1337  scope_id scope = xcurrent_scope,
1338  context_id context = xdefault_context,
1339  bool force_add = false)
1340  {
1341  static octave_value foobar;
1342 
1343  symbol_table *inst = get_instance (scope);
1344 
1345  if (inst)
1346  inst->do_assign (name, value, context, force_add);
1347  }
1348 
1349  // Use assign (name, value, scope, context, force_add) instead.
1350  static octave_value&
1351  varref (const std::string& name, scope_id scope = xcurrent_scope,
1352  context_id context = xdefault_context, bool force_add = false)
1353  GCC_ATTR_DEPRECATED
1354  {
1355  static octave_value foobar;
1356 
1357  symbol_table *inst = get_instance (scope);
1358 
1359  return inst ? inst->do_varref (name, context, force_add) : foobar;
1360  }
1361 
1362  // Convenience function to simplify
1363  // octave_user_function::bind_automatic_vars
1364 
1365  static void force_assign (const std::string& name,
1366  const octave_value& value = octave_value (),
1367  scope_id scope = xcurrent_scope,
1368  context_id context = xdefault_context)
1369  {
1370  assign (name, value, scope, context, true);
1371  }
1372 
1373  // Use force_assign (name, value, scope, context) instead.
1374  static octave_value&
1375  force_varref (const std::string& name, scope_id scope = xcurrent_scope,
1376  context_id context = xdefault_context) GCC_ATTR_DEPRECATED
1377  {
1378  static octave_value foobar;
1379 
1380  symbol_table *inst = get_instance (scope);
1381 
1382  return inst ? inst->do_varref (name, context, true) : foobar;
1383  }
1384 
1385  static octave_value varval (const std::string& name,
1386  scope_id scope = xcurrent_scope,
1387  context_id context = xdefault_context)
1388  {
1389  symbol_table *inst = get_instance (scope);
1390 
1391  return inst ? inst->do_varval (name, context) : octave_value ();
1392  }
1393 
1394  static void
1395  global_assign (const std::string& name,
1396  const octave_value& value = octave_value ())
1397 
1398  {
1399  global_table_iterator p = global_table.find (name);
1400 
1401  if (p == global_table.end ())
1402  global_table[name] = value;
1403  else
1404  p->second = value;
1405  }
1406 
1407  // Use global_assign (name, value) instead.
1408  static octave_value&
1409  global_varref (const std::string& name) GCC_ATTR_DEPRECATED
1410 
1411  {
1412  global_table_iterator p = global_table.find (name);
1413 
1414  return (p == global_table.end ()) ? global_table[name] : p->second;
1415  }
1416 
1417  static octave_value
1418  global_varval (const std::string& name)
1419  {
1420  global_table_const_iterator p = global_table.find (name);
1421 
1422  return (p != global_table.end ()) ? p->second : octave_value ();
1423  }
1424 
1425  static void
1426  top_level_assign (const std::string& name,
1427  const octave_value& value = octave_value ())
1428  {
1429  assign (name, value, top_scope (), 0);
1430  }
1431 
1432  // Use top_level_assign (name, value) instead.
1433  static octave_value&
1434  top_level_varref (const std::string& name) GCC_ATTR_DEPRECATED
1435  {
1436  static octave_value foobar;
1437 
1438  symbol_table *inst = get_instance (top_scope ());
1439 
1440  return inst ? inst->do_varref (name, 0, true) : foobar;
1441  }
1442 
1443  static octave_value
1444  top_level_varval (const std::string& name)
1445  {
1446  return varval (name, top_scope (), 0);
1447  }
1448 
1449  static void
1450  persistent_assign (const std::string& name,
1451  const octave_value& value = octave_value ())
1452  {
1453  symbol_table *inst = get_instance (xcurrent_scope);
1454 
1455  if (inst)
1456  inst->do_persistent_assign (name, value);
1457  }
1458 
1459  // Use persistent_assign (name, value) instead.
1460  static octave_value& persistent_varref (const std::string& name)
1461  GCC_ATTR_DEPRECATED
1462  {
1463  static octave_value foobar;
1464 
1465  symbol_table *inst = get_instance (xcurrent_scope);
1466 
1467  return inst ? inst->do_persistent_varref (name) : foobar;
1468  }
1469 
1470  static octave_value persistent_varval (const std::string& name)
1471  {
1472  symbol_table *inst = get_instance (xcurrent_scope);
1473 
1474  return inst ? inst->do_persistent_varval (name) : octave_value ();
1475  }
1476 
1477  static void erase_persistent (const std::string& name)
1478  {
1479  symbol_table *inst = get_instance (xcurrent_scope);
1480 
1481  if (inst)
1482  inst->do_erase_persistent (name);
1483  }
1484 
1485  static bool is_variable (const std::string& name)
1486  {
1487  symbol_table *inst = get_instance (xcurrent_scope);
1488 
1489  return inst ? inst->do_is_variable (name) : false;
1490  }
1491 
1492  static bool
1493  is_built_in_function_name (const std::string& name)
1494  {
1495  octave_value val = find_built_in_function (name);
1496 
1497  return val.is_defined ();
1498  }
1499 
1500  static octave_value
1501  find_method (const std::string& name, const std::string& dispatch_type)
1502  {
1503  fcn_table_const_iterator p = fcn_table.find (name);
1504 
1505  if (p != fcn_table.end ())
1506  return p->second.find_method (dispatch_type);
1507  else
1508  {
1509  fcn_info finfo (name);
1510 
1511  octave_value fcn = finfo.find_method (dispatch_type);
1512 
1513  if (fcn.is_defined ())
1514  fcn_table[name] = finfo;
1515 
1516  return fcn;
1517  }
1518  }
1519 
1520  static octave_value
1521  find_built_in_function (const std::string& name)
1522  {
1523  fcn_table_const_iterator p = fcn_table.find (name);
1524 
1525  return (p != fcn_table.end ())
1526  ? p->second.find_built_in_function () : octave_value ();
1527  }
1528 
1529  static octave_value
1530  find_autoload (const std::string& name)
1531  {
1532  fcn_table_iterator p = fcn_table.find (name);
1533 
1534  return (p != fcn_table.end ())
1535  ? p->second.find_autoload () : octave_value ();
1536  }
1537 
1538  static octave_value
1539  find_function (const std::string& name,
1540  const octave_value_list& args = octave_value_list (),
1541  bool local_funcs = true);
1542 
1543  static octave_value find_user_function (const std::string& name)
1544  {
1545  fcn_table_iterator p = fcn_table.find (name);
1546 
1547  return (p != fcn_table.end ())
1548  ? p->second.find_user_function () : octave_value ();
1549  }
1550 
1551  static void install_cmdline_function (const std::string& name,
1552  const octave_value& fcn)
1553  {
1554  fcn_table_iterator p = fcn_table.find (name);
1555 
1556  if (p != fcn_table.end ())
1557  {
1558  fcn_info& finfo = p->second;
1559 
1560  finfo.install_cmdline_function (fcn);
1561  }
1562  else
1563  {
1564  fcn_info finfo (name);
1565 
1566  finfo.install_cmdline_function (fcn);
1567 
1568  fcn_table[name] = finfo;
1569  }
1570  }
1571 
1572  // Install subfunction FCN named NAME. SCOPE is the scope of the
1573  // primary function corresponding to this subfunction.
1574 
1575  static void install_subfunction (const std::string& name,
1576  const octave_value& fcn,
1577  scope_id scope)
1578  {
1579  fcn_table_iterator p = fcn_table.find (name);
1580 
1581  if (p != fcn_table.end ())
1582  {
1583  fcn_info& finfo = p->second;
1584 
1585  finfo.install_subfunction (fcn, scope);
1586  }
1587  else
1588  {
1589  fcn_info finfo (name);
1590 
1591  finfo.install_subfunction (fcn, scope);
1592 
1593  fcn_table[name] = finfo;
1594  }
1595  }
1596 
1597  static void install_nestfunction (const std::string& name,
1598  const octave_value& fcn,
1599  scope_id parent_scope);
1600 
1601  static void update_nest (scope_id scope)
1602  {
1603  symbol_table *inst = get_instance (scope);
1604  if (inst)
1605  inst->do_update_nest ();
1606  }
1607 
1608  static void install_user_function (const std::string& name,
1609  const octave_value& fcn)
1610  {
1611  fcn_table_iterator p = fcn_table.find (name);
1612 
1613  if (p != fcn_table.end ())
1614  {
1615  fcn_info& finfo = p->second;
1616 
1617  finfo.install_user_function (fcn);
1618  }
1619  else
1620  {
1621  fcn_info finfo (name);
1622 
1623  finfo.install_user_function (fcn);
1624 
1625  fcn_table[name] = finfo;
1626  }
1627  }
1628 
1629  static void install_built_in_function (const std::string& name,
1630  const octave_value& fcn)
1631  {
1632  fcn_table_iterator p = fcn_table.find (name);
1633 
1634  if (p != fcn_table.end ())
1635  {
1636  fcn_info& finfo = p->second;
1637 
1638  finfo.install_built_in_function (fcn);
1639  }
1640  else
1641  {
1642  fcn_info finfo (name);
1643 
1644  finfo.install_built_in_function (fcn);
1645 
1646  fcn_table[name] = finfo;
1647  }
1648  }
1649 
1650  static void clear (const std::string& name)
1651  {
1652  clear_variable (name);
1653  }
1654 
1655  static void clear_all (bool force = false)
1656  {
1657  clear_variables ();
1658 
1659  clear_global_pattern ("*");
1660 
1661  clear_functions (force);
1662  }
1663 
1664  static void clear_variables (scope_id scope)
1665  {
1666  symbol_table *inst = get_instance (scope);
1667 
1668  if (inst)
1669  inst->do_clear_variables ();
1670  }
1671 
1672  // This is split for unwind_protect.
1673  static void clear_variables (void)
1674  {
1675  clear_variables (xcurrent_scope);
1676  }
1677 
1678  static void clear_objects (scope_id scope = xcurrent_scope)
1679  {
1680  symbol_table *inst = get_instance (scope);
1681 
1682  if (inst)
1683  inst->do_clear_objects ();
1684  }
1685 
1686  static void clear_functions (bool force = false)
1687  {
1688  for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++)
1689  p->second.clear (force);
1690  }
1691 
1692  static void clear_function (const std::string& name)
1693  {
1694  clear_user_function (name);
1695  }
1696 
1697  static void clear_global (const std::string& name)
1698  {
1699  symbol_table *inst = get_instance (xcurrent_scope);
1700 
1701  if (inst)
1702  inst->do_clear_global (name);
1703  }
1704 
1705  static void clear_variable (const std::string& name)
1706  {
1707  symbol_table *inst = get_instance (xcurrent_scope);
1708 
1709  if (inst)
1710  inst->do_clear_variable (name);
1711  }
1712 
1713  static void clear_symbol (const std::string& name)
1714  {
1715  // FIXME: are we supposed to do both here?
1716 
1717  clear_variable (name);
1718  clear_function (name);
1719  }
1720 
1721  static void clear_function_pattern (const std::string& pat)
1722  {
1723  glob_match pattern (pat);
1724 
1725  for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++)
1726  {
1727  if (pattern.match (p->first))
1728  p->second.clear_user_function ();
1729  }
1730  }
1731 
1732  static void clear_global_pattern (const std::string& pat)
1733  {
1734  symbol_table *inst = get_instance (xcurrent_scope);
1735 
1736  if (inst)
1737  inst->do_clear_global_pattern (pat);
1738  }
1739 
1740  static void clear_variable_pattern (const std::string& pat)
1741  {
1742  symbol_table *inst = get_instance (xcurrent_scope);
1743 
1744  if (inst)
1745  inst->do_clear_variable_pattern (pat);
1746  }
1747 
1748  static void clear_variable_regexp (const std::string& pat)
1749  {
1750  symbol_table *inst = get_instance (xcurrent_scope);
1751 
1752  if (inst)
1753  inst->do_clear_variable_regexp (pat);
1754  }
1755 
1756  static void clear_symbol_pattern (const std::string& pat)
1757  {
1758  // FIXME: are we supposed to do both here?
1759 
1760  clear_variable_pattern (pat);
1761  clear_function_pattern (pat);
1762  }
1763 
1764  static void clear_user_function (const std::string& name)
1765  {
1766  fcn_table_iterator p = fcn_table.find (name);
1767 
1768  if (p != fcn_table.end ())
1769  {
1770  fcn_info& finfo = p->second;
1771 
1772  finfo.clear_user_function ();
1773  }
1774  // FIXME: is this necessary, or even useful?
1775  // else
1776  // error ("clear: no such function '%s'", name.c_str ());
1777  }
1778 
1779  // This clears oct and mex files, incl. autoloads.
1780  static void clear_dld_function (const std::string& name)
1781  {
1782  fcn_table_iterator p = fcn_table.find (name);
1783 
1784  if (p != fcn_table.end ())
1785  {
1786  fcn_info& finfo = p->second;
1787 
1788  finfo.clear_autoload_function ();
1789  finfo.clear_user_function ();
1790  }
1791  }
1792 
1793  static void clear_mex_functions (void)
1794  {
1795  for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++)
1796  {
1797  fcn_info& finfo = p->second;
1798 
1799  finfo.clear_mex_function ();
1800  }
1801  }
1802 
1803  static bool set_class_relationship (const std::string& sup_class,
1804  const std::string& inf_class);
1805 
1806  static bool is_superiorto (const std::string& a, const std::string& b);
1807 
1808  static void alias_built_in_function (const std::string& alias,
1809  const std::string& name)
1810  {
1811  octave_value fcn = find_built_in_function (name);
1812 
1813  if (fcn.is_defined ())
1814  {
1815  fcn_info finfo (alias);
1816 
1817  finfo.install_built_in_function (fcn);
1818 
1819  fcn_table[alias] = finfo;
1820  }
1821  else
1822  panic ("alias: '%s' is undefined", name.c_str ());
1823  }
1824 
1825  static void add_dispatch (const std::string& name, const std::string& type,
1826  const std::string& fname)
1827  {
1828  fcn_table_iterator p = fcn_table.find (name);
1829 
1830  if (p != fcn_table.end ())
1831  {
1832  fcn_info& finfo = p->second;
1833 
1834  finfo.add_dispatch (type, fname);
1835  }
1836  else
1837  {
1838  fcn_info finfo (name);
1839 
1840  finfo.add_dispatch (type, fname);
1841 
1842  fcn_table[name] = finfo;
1843  }
1844  }
1845 
1846  static void clear_dispatch (const std::string& name, const std::string& type)
1847  {
1848  fcn_table_iterator p = fcn_table.find (name);
1849 
1850  if (p != fcn_table.end ())
1851  {
1852  fcn_info& finfo = p->second;
1853 
1854  finfo.clear_dispatch (type);
1855  }
1856  }
1857 
1858  static void print_dispatch (std::ostream& os, const std::string& name)
1859  {
1860  fcn_table_iterator p = fcn_table.find (name);
1861 
1862  if (p != fcn_table.end ())
1863  {
1864  fcn_info& finfo = p->second;
1865 
1866  finfo.print_dispatch (os);
1867  }
1868  }
1869 
1870  static fcn_info::dispatch_map_type get_dispatch (const std::string& name)
1871  {
1873 
1874  fcn_table_iterator p = fcn_table.find (name);
1875 
1876  if (p != fcn_table.end ())
1877  {
1878  fcn_info& finfo = p->second;
1879 
1880  retval = finfo.get_dispatch ();
1881  }
1882 
1883  return retval;
1884  }
1885 
1886  static std::string help_for_dispatch (const std::string& name)
1887  {
1888  std::string retval;
1889 
1890  fcn_table_iterator p = fcn_table.find (name);
1891 
1892  if (p != fcn_table.end ())
1893  {
1894  fcn_info& finfo = p->second;
1895 
1896  retval = finfo.help_for_dispatch ();
1897  }
1898 
1899  return retval;
1900  }
1901 
1902  static void push_context (void)
1903  {
1904  if (xcurrent_scope == xglobal_scope || xcurrent_scope == xtop_scope)
1905  error ("invalid call to xymtab::push_context");
1906  else
1907  {
1908  symbol_table *inst = get_instance (xcurrent_scope);
1909 
1910  if (inst)
1911  inst->do_push_context ();
1912  }
1913  }
1914 
1915  static void pop_context (void)
1916  {
1917  if (xcurrent_scope == xglobal_scope || xcurrent_scope == xtop_scope)
1918  error ("invalid call to xymtab::pop_context");
1919  else
1920  {
1921  symbol_table *inst = get_instance (xcurrent_scope);
1922 
1923  if (inst)
1924  inst->do_pop_context ();
1925  }
1926  }
1927 
1928  // For unwind_protect.
1929  static void pop_context (void *) { pop_context (); }
1930 
1931  static void mark_automatic (const std::string& name)
1932  {
1933  symbol_table *inst = get_instance (xcurrent_scope);
1934 
1935  if (inst)
1936  inst->do_mark_automatic (name);
1937  }
1938 
1939  static void mark_hidden (const std::string& name)
1940  {
1941  symbol_table *inst = get_instance (xcurrent_scope);
1942 
1943  if (inst)
1944  inst->do_mark_hidden (name);
1945  }
1946 
1947  static void mark_global (const std::string& name)
1948  {
1949  symbol_table *inst = get_instance (xcurrent_scope);
1950 
1951  if (inst)
1952  inst->do_mark_global (name);
1953  }
1954 
1955  // exclude: Storage classes to exclude, you can OR them together
1956  static std::list<symbol_record>
1957  all_variables (scope_id scope = xcurrent_scope,
1958  context_id context = xdefault_context,
1959  bool defined_only = true,
1960  unsigned int exclude = symbol_record::hidden)
1961  {
1962  symbol_table *inst = get_instance (scope);
1963 
1964  return inst
1965  ? inst->do_all_variables (context, defined_only, exclude)
1966  : std::list<symbol_record> ();
1967  }
1968 
1969  static std::list<symbol_record> glob (const std::string& pattern)
1970  {
1971  symbol_table *inst = get_instance (xcurrent_scope);
1972 
1973  return inst ? inst->do_glob (pattern) : std::list<symbol_record> ();
1974  }
1975 
1976  static std::list<symbol_record> regexp (const std::string& pattern)
1977  {
1978  symbol_table *inst = get_instance (xcurrent_scope);
1979 
1980  return inst ? inst->do_regexp (pattern) : std::list<symbol_record> ();
1981  }
1982 
1983  static std::list<symbol_record> glob_variables (const std::string& pattern)
1984  {
1985  symbol_table *inst = get_instance (xcurrent_scope);
1986 
1987  return inst ? inst->do_glob (pattern, true) : std::list<symbol_record> ();
1988  }
1989 
1990  static std::list<symbol_record> regexp_variables (const std::string& pattern)
1991  {
1992  symbol_table *inst = get_instance (xcurrent_scope);
1993 
1994  return inst ? inst->do_regexp (pattern, true) : std::list<symbol_record> ();
1995  }
1996 
1997  static std::list<symbol_record>
1998  glob_global_variables (const std::string& pattern)
1999  {
2000  std::list<symbol_record> retval;
2001 
2002  glob_match pat (pattern);
2003 
2004  for (global_table_const_iterator p = global_table.begin ();
2005  p != global_table.end (); p++)
2006  {
2007  // We generate a list of symbol_record objects so that
2008  // the results from glob_variables and glob_global_variables
2009  // may be handled the same way.
2010 
2011  if (pat.match (p->first))
2012  retval.push_back (symbol_record (xglobal_scope,
2013  p->first, p->second,
2014  symbol_record::global));
2015  }
2016 
2017  return retval;
2018  }
2019 
2020  static std::list<symbol_record>
2021  regexp_global_variables (const std::string& pattern)
2022  {
2023  std::list<symbol_record> retval;
2024 
2025  ::regexp pat (pattern);
2026 
2027  for (global_table_const_iterator p = global_table.begin ();
2028  p != global_table.end (); p++)
2029  {
2030  // We generate a list of symbol_record objects so that
2031  // the results from regexp_variables and regexp_global_variables
2032  // may be handled the same way.
2033 
2034  if (pat.is_match (p->first))
2035  retval.push_back (symbol_record (xglobal_scope,
2036  p->first, p->second,
2037  symbol_record::global));
2038  }
2039 
2040  return retval;
2041  }
2042 
2043  static std::list<symbol_record> glob_variables (const string_vector& patterns)
2044  {
2045  std::list<symbol_record> retval;
2046 
2047  size_t len = patterns.length ();
2048 
2049  for (size_t i = 0; i < len; i++)
2050  {
2051  std::list<symbol_record> tmp = glob_variables (patterns[i]);
2052 
2053  retval.insert (retval.begin (), tmp.begin (), tmp.end ());
2054  }
2055 
2056  return retval;
2057  }
2058 
2059  static std::list<symbol_record> regexp_variables
2060  (const string_vector& patterns)
2061  {
2062  std::list<symbol_record> retval;
2063 
2064  size_t len = patterns.length ();
2065 
2066  for (size_t i = 0; i < len; i++)
2067  {
2068  std::list<symbol_record> tmp = regexp_variables (patterns[i]);
2069 
2070  retval.insert (retval.begin (), tmp.begin (), tmp.end ());
2071  }
2072 
2073  return retval;
2074  }
2075 
2076  static std::list<std::string> user_function_names (void)
2077  {
2078  std::list<std::string> retval;
2079 
2080  for (fcn_table_iterator p = fcn_table.begin ();
2081  p != fcn_table.end (); p++)
2082  {
2083  if (p->second.is_user_function_defined ())
2084  retval.push_back (p->first);
2085  }
2086 
2087  if (! retval.empty ())
2088  retval.sort ();
2089 
2090  return retval;
2091  }
2092 
2093  static std::list<std::string> global_variable_names (void)
2094  {
2095  std::list<std::string> retval;
2096 
2097  for (global_table_const_iterator p = global_table.begin ();
2098  p != global_table.end (); p++)
2099  retval.push_back (p->first);
2100 
2101  retval.sort ();
2102 
2103  return retval;
2104  }
2105 
2106  static std::list<std::string> top_level_variable_names (void)
2107  {
2108  symbol_table *inst = get_instance (xtop_scope);
2109 
2110  return inst ? inst->do_variable_names () : std::list<std::string> ();
2111  }
2112 
2113  static std::list<std::string> variable_names (void)
2114  {
2115  symbol_table *inst = get_instance (xcurrent_scope);
2116 
2117  return inst ? inst->do_variable_names () : std::list<std::string> ();
2118  }
2119 
2120  static std::list<std::string> built_in_function_names (void)
2121  {
2122  std::list<std::string> retval;
2123 
2124  for (fcn_table_const_iterator p = fcn_table.begin ();
2125  p != fcn_table.end (); p++)
2126  {
2127  octave_value fcn = p->second.find_built_in_function ();
2128 
2129  if (fcn.is_defined ())
2130  retval.push_back (p->first);
2131  }
2132 
2133  if (! retval.empty ())
2134  retval.sort ();
2135 
2136  return retval;
2137  }
2138 
2139  static std::list<std::string> cmdline_function_names (void)
2140  {
2141  std::list<std::string> retval;
2142 
2143  for (fcn_table_const_iterator p = fcn_table.begin ();
2144  p != fcn_table.end (); p++)
2145  {
2146  octave_value fcn = p->second.find_cmdline_function ();
2147 
2148  if (fcn.is_defined ())
2149  retval.push_back (p->first);
2150  }
2151 
2152  if (! retval.empty ())
2153  retval.sort ();
2154 
2155  return retval;
2156  }
2157 
2158  static bool is_local_variable (const std::string& name)
2159  {
2160  if (xcurrent_scope == xglobal_scope)
2161  return false;
2162  else
2163  {
2164  symbol_table *inst = get_instance (xcurrent_scope);
2165 
2166  return inst ? inst->do_is_local_variable (name) : false;
2167  }
2168  }
2169 
2170  static bool is_global (const std::string& name)
2171  {
2172  if (xcurrent_scope == xglobal_scope)
2173  return true;
2174  else
2175  {
2176  symbol_table *inst = get_instance (xcurrent_scope);
2177 
2178  return inst ? inst->do_is_global (name) : false;
2179  }
2180  }
2181 
2182  static std::list<workspace_element> workspace_info (void)
2183  {
2184  symbol_table *inst = get_instance (xcurrent_scope);
2185 
2186  return inst
2187  ? inst->do_workspace_info () : std::list<workspace_element> ();
2188  }
2189 
2190  static void dump (std::ostream& os, scope_id scope = xcurrent_scope);
2191 
2192  static void dump_global (std::ostream& os);
2193 
2194  static void dump_functions (std::ostream& os);
2195 
2196  static void cache_name (scope_id scope, const std::string& name)
2197  {
2198  symbol_table *inst = get_instance (scope, false);
2199 
2200  if (inst)
2201  inst->do_cache_name (name);
2202  }
2203 
2204  static void lock_subfunctions (scope_id scope = xcurrent_scope)
2205  {
2206  for (fcn_table_iterator p = fcn_table.begin ();
2207  p != fcn_table.end (); p++)
2208  p->second.lock_subfunction (scope);
2209  }
2210 
2211  static void unlock_subfunctions (scope_id scope = xcurrent_scope)
2212  {
2213  for (fcn_table_iterator p = fcn_table.begin ();
2214  p != fcn_table.end (); p++)
2215  p->second.unlock_subfunction (scope);
2216  }
2217 
2218  static std::map<std::string, octave_value>
2219  subfunctions_defined_in_scope (scope_id scope = xcurrent_scope)
2220  {
2221  std::map<std::string, octave_value> retval;
2222 
2223  for (fcn_table_const_iterator p = fcn_table.begin ();
2224  p != fcn_table.end (); p++)
2225  {
2226  std::pair<std::string, octave_value> tmp
2227  = p->second.subfunction_defined_in_scope (scope);
2228 
2229  std::string nm = tmp.first;
2230 
2231  if (! nm.empty ())
2232  retval[nm] = tmp.second;
2233  }
2234 
2235  return retval;
2236  }
2237 
2238  static void free_scope (scope_id scope)
2239  {
2240  if (scope == xglobal_scope || scope == xtop_scope)
2241  error ("can't free global or top-level scopes!");
2242  else
2244  }
2245 
2246  static void stash_dir_name_for_subfunctions (scope_id scope,
2247  const std::string& dir_name);
2248 
2249  static void add_to_parent_map (const std::string& classname,
2250  const std::list<std::string>& parent_list)
2251  {
2252  parent_map[classname] = parent_list;
2253  }
2254 
2255  static std::list<std::string>
2256  parent_classes (const std::string& dispatch_type)
2257  {
2258  std::list<std::string> retval;
2259 
2260  const_parent_map_iterator it = parent_map.find (dispatch_type);
2261 
2262  if (it != parent_map.end ())
2263  retval = it->second;
2264 
2265  for (std::list<std::string>::const_iterator lit = retval.begin ();
2266  lit != retval.end (); lit++)
2267  {
2268  // Search for parents of parents and append them to the list.
2269 
2270  // FIXME: should we worry about a circular inheritance graph?
2271 
2272  std::list<std::string> parents = parent_classes (*lit);
2273 
2274  if (! parents.empty ())
2275  retval.insert (retval.end (), parents.begin (), parents.end ());
2276  }
2277 
2278  return retval;
2279  }
2280 
2281  static octave_user_function *get_curr_fcn (scope_id scope = xcurrent_scope)
2282  {
2283  symbol_table *inst = get_instance (scope);
2284  return inst->curr_fcn;
2285  }
2286 
2287  static void set_curr_fcn (octave_user_function *curr_fcn,
2288  scope_id scope = xcurrent_scope)
2289  {
2290  assert (scope != xtop_scope && scope != xglobal_scope);
2291  symbol_table *inst = get_instance (scope);
2292  // FIXME: normally, functions should not usurp each other's scope.
2293  // If for any incredible reason this is needed, call
2294  // set_user_function (0, scope) first. This may cause problems with
2295  // nested functions, as the curr_fcn of symbol_records must be updated.
2296  assert (inst->curr_fcn == 0 || curr_fcn == 0);
2297  inst->curr_fcn = curr_fcn;
2298  }
2299 
2300  static void cleanup (void);
2301 
2302 private:
2303 
2304  // No copying!
2305 
2306  symbol_table (const symbol_table&);
2307 
2308  symbol_table& operator = (const symbol_table&);
2309 
2310  typedef std::map<std::string, symbol_record>::const_iterator
2312  typedef std::map<std::string, symbol_record>::iterator
2314 
2315  typedef std::map<std::string, octave_value>::const_iterator
2317  typedef std::map<std::string, octave_value>::iterator
2319 
2320  typedef std::map<std::string, octave_value>::const_iterator
2322  typedef std::map<std::string, octave_value>::iterator
2324 
2325  typedef std::map<scope_id, symbol_table*>::const_iterator
2327  typedef std::map<scope_id, symbol_table*>::iterator
2329 
2330  typedef std::map<std::string, fcn_info>::const_iterator
2332  typedef std::map<std::string, fcn_info>::iterator
2334 
2335  // The scope of this symbol table.
2336  scope_id my_scope;
2337 
2338  // Name for this table (usually the file name of the function
2339  // corresponding to the scope);
2340  std::string table_name;
2341 
2342  // Map from symbol names to symbol info.
2343  std::map<std::string, symbol_record> table;
2344 
2345  // Child nested functions.
2346  std::vector<symbol_table*> nest_children;
2347 
2348  // Parent nested function (may be null).
2350 
2351  // The associated user code (may be null).
2353 
2354  // If true then no variables can be added.
2356 
2357  // Map from names of global variables to values.
2358  static std::map<std::string, octave_value> global_table;
2359 
2360  // Map from names of persistent variables to values.
2361  std::map<std::string, octave_value> persistent_table;
2362 
2363  // Pointer to symbol table for current scope (variables only).
2365 
2366  // Map from scope id to symbol table instances.
2367  static std::map<scope_id, symbol_table*> all_instances;
2368 
2369  // Map from function names to function info (subfunctions, private
2370  // functions, class constructors, class methods, etc.)
2371  static std::map<std::string, fcn_info> fcn_table;
2372 
2373  // Mape from class names to set of classes that have lower
2374  // precedence.
2375  static std::map<std::string, std::set<std::string> > class_precedence_table;
2376 
2377  typedef std::map<std::string, std::set<std::string> >::const_iterator
2379  typedef std::map<std::string, std::set<std::string> >::iterator
2381 
2382  // Map from class names to parent class names.
2383  static std::map<std::string, std::list<std::string> > parent_map;
2384 
2385  typedef std::map<std::string, std::list<std::string> >::const_iterator
2387  typedef std::map<std::string, std::list<std::string> >::iterator
2389 
2390  static const scope_id xglobal_scope;
2391  static const scope_id xtop_scope;
2392 
2393  static scope_id xcurrent_scope;
2394 
2395  static context_id xcurrent_context;
2396 
2397  static const context_id xdefault_context = static_cast<context_id> (-1);
2398 
2399  symbol_table (scope_id scope)
2400  : my_scope (scope), table_name (), table (), nest_children (),
2401  nest_parent (0), curr_fcn (0), static_workspace (false),
2402  persistent_table () { }
2403 
2404  ~symbol_table (void) { }
2405 
2406  static symbol_table *get_instance (scope_id scope, bool create = true)
2407  {
2408  symbol_table *retval = 0;
2409 
2410  bool ok = true;
2411 
2412  if (scope != xglobal_scope)
2413  {
2414  if (scope == xcurrent_scope)
2415  {
2416  if (! instance && create)
2417  {
2418  symbol_table *inst = new symbol_table (scope);
2419 
2420  if (inst)
2421  {
2422  all_instances[scope] = instance = inst;
2423 
2424  if (scope == xtop_scope)
2425  instance->do_cache_name ("top-level");
2426  }
2427  }
2428 
2429  if (! instance)
2430  ok = false;
2431 
2432  retval = instance;
2433  }
2434  else
2435  {
2436  all_instances_iterator p = all_instances.find (scope);
2437 
2438  if (p == all_instances.end ())
2439  {
2440  if (create)
2441  {
2442  retval = new symbol_table (scope);
2443 
2444  if (retval)
2445  all_instances[scope] = retval;
2446  else
2447  ok = false;
2448  }
2449  else
2450  ok = false;
2451  }
2452  else
2453  retval = p->second;
2454  }
2455  }
2456 
2457  if (! ok)
2458  error ("unable to %s symbol_table object for scope %d!",
2459  create ? "create" : "find", scope);
2460 
2461  return retval;
2462  }
2463 
2465  {
2466  assert (!st.nest_parent);
2467  nest_children.push_back (&st);
2468  st.nest_parent = this;
2469  }
2470 
2472  {
2473  table[sr.name ()] = sr;
2474  }
2475 
2476  void
2477  do_dup_scope (symbol_table& new_symbol_table) const
2478  {
2479  for (table_const_iterator p = table.begin (); p != table.end (); p++)
2480  new_symbol_table.insert_symbol_record (p->second.dup (new_symbol_table
2481  .my_scope));
2482  }
2483 
2484  symbol_record do_find_symbol (const std::string& name)
2485  {
2486  table_iterator p = table.find (name);
2487 
2488  if (p == table.end ())
2489  return do_insert (name);
2490  else
2491  return p->second;
2492  }
2493 
2494  void do_inherit (symbol_table& donor_table, context_id donor_context)
2495  {
2496  for (table_iterator p = table.begin (); p != table.end (); p++)
2497  {
2498  symbol_record& sr = p->second;
2499 
2500  if (! (sr.is_automatic () || sr.is_formal ()))
2501  {
2502  std::string nm = sr.name ();
2503 
2504  if (nm != "__retval__")
2505  {
2506  octave_value val = donor_table.do_varval (nm, donor_context);
2507 
2508  if (val.is_defined ())
2509  {
2510  sr.assign (val, 0);
2511 
2512  sr.mark_inherited ();
2513  }
2514  }
2515  }
2516  }
2517  }
2518 
2519  static fcn_info *get_fcn_info (const std::string& name)
2520  {
2521  fcn_table_iterator p = fcn_table.find (name);
2522  return p != fcn_table.end () ? &p->second : 0;
2523  }
2524 
2525  octave_value
2526  do_find (const std::string& name, const octave_value_list& args,
2527  bool skip_variables, bool local_funcs);
2528 
2529  octave_value do_builtin_find (const std::string& name);
2530 
2531  symbol_record& do_insert (const std::string& name, bool force_add = false)
2532  {
2533  table_iterator p = table.find (name);
2534 
2535  if (p == table.end ())
2536  {
2537  symbol_record ret (my_scope, name);
2538 
2539  if (nest_parent && nest_parent->look_nonlocal (name, ret))
2540  return table[name] = ret;
2541  else
2542  {
2543  if (static_workspace && ! force_add)
2544  ret.mark_added_static ();
2545 
2546  return table[name] = ret;
2547  }
2548  }
2549  else
2550  return p->second;
2551  }
2552 
2553  void do_rename (const std::string& old_name, const std::string& new_name)
2554  {
2555  table_iterator p = table.find (old_name);
2556 
2557  if (p != table.end ())
2558  {
2559  symbol_record sr = p->second;
2560 
2561  sr.rename (new_name);
2562 
2563  table.erase (p);
2564 
2565  table[new_name] = sr;
2566  }
2567  }
2568 
2569  void do_assign (const std::string& name, const octave_value& value,
2570  context_id context, bool force_add)
2571  {
2572  table_iterator p = table.find (name);
2573 
2574  if (p == table.end ())
2575  {
2576  symbol_record& sr = do_insert (name, force_add);
2577 
2578  sr.assign (value, context);
2579  }
2580  else
2581  p->second.assign (value, context);
2582  }
2583 
2584  // Use do_assign (name, value, context, force_add) instead.
2585  // Delete when deprecated varref functions are removed.
2586  octave_value& do_varref (const std::string& name, context_id context,
2587  bool force_add)
2588  {
2589  table_iterator p = table.find (name);
2590 
2591  if (p == table.end ())
2592  {
2593  symbol_record& sr = do_insert (name, force_add);
2594 
2595  return sr.varref (context);
2596  }
2597  else
2598  return p->second.varref (context);
2599  }
2600 
2601  octave_value do_varval (const std::string& name, context_id context) const
2602  {
2603  table_const_iterator p = table.find (name);
2604 
2605  return (p != table.end ()) ? p->second.varval (context) : octave_value ();
2606  }
2607 
2608  void do_persistent_assign (const std::string& name, const octave_value& value)
2609  {
2610  persistent_table_iterator p = persistent_table.find (name);
2611 
2612  if (p == persistent_table.end ())
2613  persistent_table[name] = value;
2614  else
2615  p->second = value;
2616  }
2617 
2618  // Use do_persistent_assign (name, value) instead.
2619  // Delete when deprecated varref functions are removed.
2620  octave_value& do_persistent_varref (const std::string& name)
2621  {
2622  persistent_table_iterator p = persistent_table.find (name);
2623 
2624  return (p == persistent_table.end ())
2625  ? persistent_table[name] : p->second;
2626  }
2627 
2628  octave_value do_persistent_varval (const std::string& name)
2629  {
2630  persistent_table_const_iterator p = persistent_table.find (name);
2631 
2632  return (p != persistent_table.end ()) ? p->second : octave_value ();
2633  }
2634 
2635  void do_erase_persistent (const std::string& name)
2636  {
2637  persistent_table_iterator p = persistent_table.find (name);
2638 
2639  if (p != persistent_table.end ())
2640  persistent_table.erase (p);
2641  }
2642 
2643  bool do_is_variable (const std::string& name) const
2644  {
2645  bool retval = false;
2646 
2647  table_const_iterator p = table.find (name);
2648 
2649  if (p != table.end ())
2650  {
2651  const symbol_record& sr = p->second;
2652 
2653  retval = sr.is_variable ();
2654  }
2655 
2656  return retval;
2657  }
2658 
2659  void do_push_context (void)
2660  {
2661  for (table_iterator p = table.begin (); p != table.end (); p++)
2662  p->second.push_context (my_scope);
2663  }
2664 
2665  void do_pop_context (void)
2666  {
2667  table_iterator p = table.begin ();
2668 
2669  while (p != table.end ())
2670  {
2671  if (p->second.pop_context (my_scope) == 0)
2672  table.erase (p++);
2673  else
2674  p++;
2675  }
2676  }
2677 
2679  {
2680  for (table_iterator p = table.begin (); p != table.end (); p++)
2681  p->second.clear (my_scope);
2682  }
2683 
2684  void do_clear_objects (void)
2685  {
2686  for (table_iterator p = table.begin (); p != table.end (); p++)
2687  {
2688  symbol_record& sr = p->second;
2689  octave_value val = sr.varval ();
2690  if (val.is_object ())
2691  p->second.clear (my_scope);
2692  }
2693  }
2694 
2695  void do_clear_global (const std::string& name)
2696  {
2697  table_iterator p = table.find (name);
2698 
2699  if (p != table.end ())
2700  {
2701  symbol_record& sr = p->second;
2702 
2703  if (sr.is_global ())
2704  sr.unmark_global ();
2705  }
2706 
2707  global_table_iterator q = global_table.find (name);
2708 
2709  if (q != global_table.end ())
2710  global_table.erase (q);
2711 
2712  }
2713 
2714  void do_clear_variable (const std::string& name)
2715  {
2716  table_iterator p = table.find (name);
2717 
2718  if (p != table.end ())
2719  p->second.clear (my_scope);
2720  }
2721 
2722  void do_clear_global_pattern (const std::string& pat)
2723  {
2724  glob_match pattern (pat);
2725 
2726  for (table_iterator p = table.begin (); p != table.end (); p++)
2727  {
2728  symbol_record& sr = p->second;
2729 
2730  if (sr.is_global () && pattern.match (sr.name ()))
2731  sr.unmark_global ();
2732  }
2733 
2734  global_table_iterator q = global_table.begin ();
2735 
2736  while (q != global_table.end ())
2737  {
2738  if (pattern.match (q->first))
2739  global_table.erase (q++);
2740  else
2741  q++;
2742  }
2743 
2744 
2745  }
2746 
2747  void do_clear_variable_pattern (const std::string& pat)
2748  {
2749  glob_match pattern (pat);
2750 
2751  for (table_iterator p = table.begin (); p != table.end (); p++)
2752  {
2753  symbol_record& sr = p->second;
2754 
2755  if (sr.is_defined () || sr.is_global ())
2756  {
2757  if (pattern.match (sr.name ()))
2758  sr.clear (my_scope);
2759  }
2760  }
2761  }
2762 
2763  void do_clear_variable_regexp (const std::string& pat)
2764  {
2765  ::regexp pattern (pat);
2766 
2767  for (table_iterator p = table.begin (); p != table.end (); p++)
2768  {
2769  symbol_record& sr = p->second;
2770 
2771  if (sr.is_defined () || sr.is_global ())
2772  {
2773  if (pattern.is_match (sr.name ()))
2774  sr.clear (my_scope);
2775  }
2776  }
2777  }
2778 
2779  void do_mark_automatic (const std::string& name)
2780  {
2781  do_insert (name).mark_automatic ();
2782  }
2783 
2784  void do_mark_hidden (const std::string& name)
2785  {
2786  do_insert (name).mark_hidden ();
2787  }
2788 
2789  void do_mark_global (const std::string& name)
2790  {
2791  do_insert (name).mark_global ();
2792  }
2793 
2794  std::list<symbol_record>
2795  do_all_variables (context_id context, bool defined_only,
2796  unsigned int exclude) const
2797  {
2798  std::list<symbol_record> retval;
2799 
2800  for (table_const_iterator p = table.begin (); p != table.end (); p++)
2801  {
2802  const symbol_record& sr = p->second;
2803 
2804  if ((defined_only && ! sr.is_defined (context))
2805  || (sr.xstorage_class () & exclude))
2806  continue;
2807 
2808  retval.push_back (sr);
2809  }
2810 
2811  return retval;
2812  }
2813 
2814  std::list<symbol_record> do_glob (const std::string& pattern,
2815  bool vars_only = false) const
2816  {
2817  std::list<symbol_record> retval;
2818 
2819  glob_match pat (pattern);
2820 
2821  for (table_const_iterator p = table.begin (); p != table.end (); p++)
2822  {
2823  if (pat.match (p->first))
2824  {
2825  const symbol_record& sr = p->second;
2826 
2827  if (vars_only && ! sr.is_variable ())
2828  continue;
2829 
2830  retval.push_back (sr);
2831  }
2832  }
2833 
2834  return retval;
2835  }
2836 
2837  std::list<symbol_record> do_regexp (const std::string& pattern,
2838  bool vars_only = false) const
2839  {
2840  std::list<symbol_record> retval;
2841 
2842  ::regexp pat (pattern);
2843 
2844  for (table_const_iterator p = table.begin (); p != table.end (); p++)
2845  {
2846  if (pat.is_match (p->first))
2847  {
2848  const symbol_record& sr = p->second;
2849 
2850  if (vars_only && ! sr.is_variable ())
2851  continue;
2852 
2853  retval.push_back (sr);
2854  }
2855  }
2856 
2857  return retval;
2858  }
2859 
2860  std::list<std::string> do_variable_names (void)
2861  {
2862  std::list<std::string> retval;
2863 
2864  for (table_const_iterator p = table.begin (); p != table.end (); p++)
2865  {
2866  if (p->second.is_variable ())
2867  retval.push_back (p->first);
2868  }
2869 
2870  retval.sort ();
2871 
2872  return retval;
2873  }
2874 
2875  bool do_is_local_variable (const std::string& name) const
2876  {
2877  table_const_iterator p = table.find (name);
2878 
2879  return (p != table.end ()
2880  && ! p->second.is_global ()
2881  && p->second.is_defined ());
2882  }
2883 
2884  bool do_is_global (const std::string& name) const
2885  {
2886  table_const_iterator p = table.find (name);
2887 
2888  return p != table.end () && p->second.is_global ();
2889  }
2890 
2891  std::list<workspace_element> do_workspace_info (void) const;
2892 
2893  void do_dump (std::ostream& os);
2894 
2895  void do_cache_name (const std::string& name) { table_name = name; }
2896 
2897  void do_update_nest (void);
2898 
2899  bool look_nonlocal (const std::string& name, symbol_record& result)
2900  {
2901  table_iterator p = table.find (name);
2902  if (p == table.end ())
2903  {
2904  if (nest_parent)
2905  return nest_parent->look_nonlocal (name, result);
2906  }
2907  else if (! p->second.is_automatic ())
2908  {
2909  result = p->second;
2910  return true;
2911  }
2912 
2913  return false;
2914  }
2915 };
2916 
2917 extern bool out_of_date_check (octave_value& function,
2918  const std::string& dispatch_type = std::string (),
2919  bool check_relative = true);
2920 
2921 extern OCTINTERP_API std::string
2922 get_dispatch_type (const octave_value_list& args);
2923 extern OCTINTERP_API std::string
2924 get_dispatch_type (const octave_value_list& args, builtin_type_t& builtin_type);
2925 
2926 #endif
void unlock_subfunction(scope_id scope)
Definition: symtab.h:810
static std::list< symbol_record > glob_variables(const string_vector &patterns)
Definition: symtab.h:2043
std::list< symbol_record > do_all_variables(context_id context, bool defined_only, unsigned int exclude) const
Definition: symtab.h:2795
fcn_info(const std::string &nm=std::string())
Definition: symtab.h:989
octave_value find_function(const octave_value_list &args, bool local_funcs)
Definition: symtab.h:796
void unmark_hidden(void)
Definition: symtab.h:628
dispatch_map_type::iterator dispatch_map_iterator
Definition: symtab.h:749
static void clear_objects(scope_id scope=xcurrent_scope)
Definition: symtab.h:1678
static void clear_global_pattern(const std::string &pat)
Definition: symtab.h:1732
void panic(const char *fmt,...)
Definition: error.cc:744
bool is_object(void) const
Definition: ov.h:577
static void install_built_in_function(const std::string &name, const octave_value &fcn)
Definition: symtab.h:1629
static void pop_context(void *)
Definition: symtab.h:1929
void do_clear_variable(const std::string &name)
Definition: symtab.h:2714
std::map< std::string, std::set< std::string > >::iterator class_precedence_table_iterator
Definition: symtab.h:2380
static void free_scope(scope_id scope)
Definition: symtab.h:2238
void do_dup_scope(symbol_table &new_symbol_table) const
Definition: symtab.h:2477
static scope_id dup_scope(scope_id scope)
Definition: symtab.h:1250
static void install_subfunction(const std::string &name, const octave_value &fcn, scope_id scope)
Definition: symtab.h:1575
const std::string & name(void) const
Definition: symtab.h:692
static void mark_hidden(const std::string &name)
Definition: symtab.h:1939
void set_curr_fcn(octave_user_function *fcn)
Definition: symtab.h:451
octave_user_function * curr_fcn
Definition: symtab.h:2352
static void clear_functions(bool force=false)
Definition: symtab.h:1686
assign_op
Definition: ov.h:131
static void rename(const std::string &old_name, const std::string &new_name, scope_id scope=xcurrent_scope)
Definition: symtab.h:1325
static void clear_variable_pattern(const std::string &pat)
Definition: symtab.h:1740
scope_id my_scope
Definition: symtab.h:2336
static bool at_top_level(void)
Definition: symtab.h:1303
octave_value varval(context_id context=xdefault_context) const
Definition: symtab.h:289
static scope_id alloc(void)
Definition: symtab.h:70
std::list< workspace_element > do_workspace_info(void) const
Definition: symtab.cc:1496
void clear_user_function(bool force=false)
Definition: symtab.h:1114
symbol_record & do_insert(const std::string &name, bool force_add=false)
Definition: symtab.h:2531
static std::list< std::string > cmdline_function_names(void)
Definition: symtab.h:2139
scope_id scope(void) const
Definition: symtab.h:642
std::set< scope_id > in_use
Definition: symtab.h:121
void clear_dispatch(const std::string &type)
Definition: symtab.h:919
~symbol_table(void)
Definition: symtab.h:2404
octave_value find_function(const octave_value_list &args=octave_value_list(), bool local_funcs=true)
Definition: symtab.h:1058
octave_refcount< size_t > count
Definition: symtab.h:972
octave_value find_cmdline_function(void) const
Definition: symtab.h:1038
void mark_subfunction_in_scope_as_private(scope_id scope, const std::string &class_name)
Definition: symtab.h:1086
void do_pop_context(void)
Definition: symtab.h:2665
octave_value & varref(context_id context=xdefault_context)
Definition: symtab.h:254
symbol_table * nest_parent
Definition: symtab.h:2349
std::map< std::string, octave_value > class_methods
Definition: symtab.h:957
std::map< std::string, octave_value >::const_iterator global_table_const_iterator
Definition: symtab.h:2316
static octave_value find_method(const std::string &name, const std::string &dispatch_type)
Definition: symtab.h:1501
static void install_user_function(const std::string &name, const octave_value &fcn)
Definition: symtab.h:1608
static void clear_dispatch(const std::string &name, const std::string &type)
Definition: symtab.h:1846
static void clear_global(const std::string &name)
Definition: symtab.h:1697
void do_update_nest(void)
Definition: symtab.cc:1607
static void mark_automatic(const std::string &name)
Definition: symtab.h:1931
void install_subfunction(const octave_value &f, scope_id scope)
Definition: symtab.h:844
symbol_table(scope_id scope)
Definition: symtab.h:2399
static octave_value persistent_varval(const std::string &name)
Definition: symtab.h:1470
static symbol_table * get_instance(scope_id scope, bool create=true)
Definition: symtab.h:2406
static std::list< symbol_record > all_variables(scope_id scope=xcurrent_scope, context_id context=xdefault_context, bool defined_only=true, unsigned int exclude=symbol_record::hidden)
Definition: symtab.h:1957
void push_context(scope_id s)
Definition: symtab.h:579
dispatch_map_type get_dispatch(void) const
Definition: symtab.h:1144
void clear(scope_id s)
Definition: symtab.h:585
bool is_defined(void) const
Definition: ov.h:520
bool is_automatic(void) const
Definition: symtab.h:608
static void set_scope(scope_id scope)
Definition: symtab.h:1169
static std::map< std::string, fcn_info > fcn_table
Definition: symtab.h:2371
void update(void) const
Definition: symtab.h:718
std::map< std::string, std::list< std::string > >::const_iterator const_parent_map_iterator
Definition: symtab.h:2386
bool look_nonlocal(const std::string &name, symbol_record &result)
Definition: symtab.h:2899
void install_built_in_function(const octave_value &f)
Definition: symtab.h:854
bool is_variable(context_id context=xdefault_context) const
Definition: symtab.h:602
static void clear_variables(scope_id scope)
Definition: symtab.h:1664
std::set< scope_id >::iterator set_iterator
Definition: symtab.h:58
static void clear_variable(const std::string &name)
Definition: symtab.h:1705
static std::list< symbol_record > glob_variables(const std::string &pattern)
Definition: symtab.h:1983
static void add_to_parent_map(const std::string &classname, const std::list< std::string > &parent_list)
Definition: symtab.h:2249
void error(const char *fmt,...)
Definition: error.cc:476
symbol_table::scope_id scope(void)
Definition: ov-usr-fcn.h:248
std::string table_name
Definition: symtab.h:2340
symbol_reference(const symbol_reference &ref)
Definition: symtab.h:675
octave_value varval(context_id context=xdefault_context) const
Definition: symtab.h:574
static std::list< scope_id > scopes(void)
Definition: symtab.h:81
void erase_subfunction(scope_id scope)
Definition: symtab.h:828
static octave_value find_built_in_function(const std::string &name)
Definition: symtab.h:1521
void assign(octave_value::assign_op op, const std::string &type, const std::list< octave_value_list > &idx, const octave_value &value, context_id context=xdefault_context)
Definition: symtab.h:225
bool static_workspace
Definition: symtab.h:2355
static void cleanup_instance(void)
Definition: symtab.h:115
static scope_id alloc_scope(void)
Definition: symtab.h:1167
bool is_user_function_defined(void) const
Definition: symtab.h:791
OCTINTERP_API std::string get_dispatch_type(const octave_value_list &args)
Definition: symtab.cc:669
static symbol_record & insert(const std::string &name, scope_id scope=xcurrent_scope)
Definition: symtab.h:1315
static void clear_mex_functions(void)
Definition: symtab.h:1793
std::map< std::string, octave_value > class_constructors
Definition: symtab.h:954
bool do_is_global(const std::string &name) const
Definition: symtab.h:2884
static void clear_dld_function(const std::string &name)
Definition: symtab.h:1780
static void lock_subfunctions(scope_id scope=xcurrent_scope)
Definition: symtab.h:2204
static std::map< std::string, octave_value > global_table
Definition: symtab.h:2358
static void mark_global(const std::string &name)
Definition: symtab.h:1947
static std::list< symbol_record > regexp(const std::string &pattern)
Definition: symtab.h:1976
static std::list< symbol_record > glob(const std::string &pattern)
Definition: symtab.h:1969
static void clear(const std::string &name)
Definition: symtab.h:1650
void do_clear_global(const std::string &name)
Definition: symtab.h:2695
std::set< scope_id > free_list
Definition: symtab.h:124
std::map< scope_id, octave_value >::iterator scope_val_iterator
Definition: symtab.h:742
builtin_type_t
Definition: ov-base.h:59
bool is_local(void) const
Definition: symtab.h:607
void clear_dispatch(const std::string &type)
Definition: symtab.h:1131
bool is_added_static(void) const
Definition: symtab.h:614
std::map< std::string, octave_value >::iterator persistent_table_iterator
Definition: symtab.h:2323
bool is_formal(void) const
Definition: symtab.h:609
static octave_value varval(const std::string &name, scope_id scope=xcurrent_scope, context_id context=xdefault_context)
Definition: symtab.h:1385
static void clear_variables(void)
Definition: symtab.h:1673
void do_non_const_unary_op(octave_value::unary_op op, const std::string &type, const std::list< octave_value_list > &idx, context_id context=xdefault_context)
Definition: symtab.h:246
octave_user_function & operator=(const octave_user_function &fn)
static void cache_name(scope_id scope, const std::string &name)
Definition: symtab.h:2196
void do_persistent_assign(const std::string &name, const octave_value &value)
Definition: symtab.h:2608
void install_user_function(const octave_value &f)
Definition: symtab.h:1102
static scope_id global_scope(void)
Definition: symtab.h:1160
std::string help_for_dispatch(void) const
Definition: symtab.h:1141
std::map< std::string, symbol_record >::iterator table_iterator
Definition: symtab.h:2313
octave_value find_user_function(void)
Definition: symtab.h:1048
static void set_curr_fcn(octave_user_function *curr_fcn, scope_id scope=xcurrent_scope)
Definition: symtab.h:2287
static scope_id top_scope(void)
Definition: symtab.h:1161
static symbol_record find_symbol(const std::string &name, scope_id scope=xcurrent_scope)
Definition: symtab.h:1281
void clear_function(const std::string &nm)
Definition: variables.cc:77
static context_id current_context(void)
Definition: symtab.h:1165
symbol_record(symbol_record_rep *new_rep)
Definition: symtab.h:658
dispatch_map_type::const_iterator dispatch_map_const_iterator
Definition: symtab.h:748
static void clear_user_function(const std::string &name)
Definition: symtab.h:1764
static octave_value global_varval(const std::string &name)
Definition: symtab.h:1418
void clear(bool force=false)
Definition: symtab.h:1112
static void mark_subfunctions_in_scope_as_private(scope_id scope, const std::string &class_name)
Definition: symtab.h:1243
static std::list< std::string > global_variable_names(void)
Definition: symtab.h:2093
static void persistent_assign(const std::string &name, const octave_value &value=octave_value())
Definition: symtab.h:1450
void unlock_subfunction(scope_id scope)
Definition: symtab.h:1070
std::map< std::string, fcn_info >::iterator fcn_table_iterator
Definition: symtab.h:2333
std::map< std::string, octave_value > private_functions
Definition: symtab.h:951
bool do_is_local_variable(const std::string &name) const
Definition: symtab.h:2875
static scope_id_cache * instance
Definition: symtab.h:113
static context_id xcurrent_context
Definition: symtab.h:2395
static std::map< std::string, std::list< std::string > > parent_map
Definition: symtab.h:2383
static void clear_symbol(const std::string &name)
Definition: symtab.h:1713
symbol_record_rep(scope_id s, const std::string &nm, const octave_value &v, unsigned int sc)
Definition: symtab.h:211
void do_assign(const std::string &name, const octave_value &value, context_id context, bool force_add)
Definition: symtab.h:2569
std::map< std::string, octave_value >::iterator global_table_iterator
Definition: symtab.h:2318
std::pair< std::string, octave_value > subfunction_defined_in_scope(scope_id scope=xcurrent_scope) const
Definition: symtab.h:1076
void do_clear_objects(void)
Definition: symtab.h:2684
dispatch_map_type dispatch_map
Definition: symtab.h:960
bool out_of_date_check(octave_value &function, const std::string &dispatch_type=std::string(), bool check_relative=true)
Definition: symtab.cc:208
fcn_info(const fcn_info &fi)
Definition: symtab.h:992
F77_RET_T const double const double * f
std::map< std::string, octave_value >::const_iterator str_val_const_iterator
Definition: symtab.h:745
#define OCTINTERP_API
Definition: mexproto.h:66
bool is_persistent(void) const
Definition: symtab.h:613
void unmark_formal(void)
Definition: symtab.h:627
void init_persistent(void)
Definition: symtab.h:634
void clear_variable(const std::string &nm)
Definition: variables.cc:83
void do_clear_variables(void)
Definition: symtab.h:2678
void install_cmdline_function(const octave_value &f)
Definition: symtab.h:839
std::map< std::string, octave_value >::const_iterator persistent_table_const_iterator
Definition: symtab.h:2321
static std::list< symbol_record > regexp_global_variables(const std::string &pattern)
Definition: symtab.h:2021
static llvm::LLVMContext & context
Definition: jit-typeinfo.cc:76
octave_value do_varval(const std::string &name, context_id context) const
Definition: symtab.h:2601
bool is_global(void) const
Definition: symtab.h:610
void dump(std::ostream &os, const std::string &prefix=std::string()) const
Definition: symtab.h:649
std::set< scope_id >::const_iterator set_const_iterator
Definition: symtab.h:59
fcn_info_rep * rep
Definition: symtab.h:1157
bool is_variable(context_id context) const
Definition: symtab.h:376
static bool is_global(const std::string &name)
Definition: symtab.h:2170
static std::list< symbol_record > regexp_variables(const std::string &pattern)
Definition: symtab.h:1990
static void push_context(void)
Definition: symtab.h:1902
bool is_defined(context_id context=xdefault_context) const
Definition: symtab.h:587
void unmark_global(void)
Definition: symtab.h:630
static std::list< workspace_element > workspace_info(void)
Definition: symtab.h:2182
void print_dispatch(std::ostream &os) const
Definition: symtab.h:1136
void lock_subfunction(scope_id scope)
Definition: symtab.h:1065
static void erase_subfunctions_in_scope(scope_id scope)
Definition: symtab.h:1236
static void force_assign(const std::string &name, const octave_value &value=octave_value(), scope_id scope=xcurrent_scope, context_id context=xdefault_context)
Definition: symtab.h:1365
static void global_assign(const std::string &name, const octave_value &value=octave_value())
Definition: symtab.h:1395
static bool is_variable(const std::string &name)
Definition: symtab.h:1485
static void pop_context(void)
Definition: symtab.h:1915
octave_value find_autoload(void)
Definition: symtab.h:1043
void do_non_const_unary_op(octave_value::unary_op op, context_id context=xdefault_context)
Definition: symtab.h:240
static void add_dispatch(const std::string &name, const std::string &type, const std::string &fname)
Definition: symtab.h:1825
static void install_cmdline_function(const std::string &name, const octave_value &fcn)
Definition: symtab.h:1551
std::map< std::string, symbol_record > table
Definition: symtab.h:2343
void install_built_in_function(const octave_value &f)
Definition: symtab.h:1107
bool is_black_hole(void) const
Definition: symtab.h:689
void clear_user_function(bool force=false)
Definition: symtab.h:882
bool match(const std::string &str) const
Definition: glob-match.cc:33
void assign(const octave_value &value, context_id context=xdefault_context)
Definition: symtab.h:219
void do_push_context(void)
Definition: symtab.h:2659
static fcn_info::dispatch_map_type get_dispatch(const std::string &name)
Definition: symtab.h:1870
static void assign(const std::string &name, const octave_value &value=octave_value(), scope_id scope=xcurrent_scope, context_id context=xdefault_context, bool force_add=false)
Definition: symtab.h:1335
void add_dispatch(const std::string &type, const std::string &fname)
Definition: symtab.h:1126
void do_non_const_unary_op(octave_value::unary_op op)
Definition: symtab.h:556
std::map< std::string, std::list< std::string > >::iterator parent_map_iterator
Definition: symtab.h:2388
octave_value builtin_find(void)
Definition: symtab.h:1023
void mark_added_static(void)
Definition: symtab.h:623
void unmark_added_static(void)
Definition: symtab.h:632
static std::list< std::string > parent_classes(const std::string &dispatch_type)
Definition: symtab.h:2256
std::list< scope_id > do_scopes(void) const
Definition: symtab.h:158
std::deque< octave_value > value_stack
Definition: symtab.h:470
symbol_record_rep * dup(scope_id new_scope) const
Definition: symtab.h:456
unsigned int xstorage_class(void) const
Definition: symtab.h:644
void clear_map(std::map< T, octave_value > &map, bool force=false)
Definition: symtab.h:861
void install_user_function(const octave_value &f)
Definition: symtab.h:849
octave_value find_method(const std::string &dispatch_type) const
Definition: symtab.h:1028
static scope_id xcurrent_scope
Definition: symtab.h:2393
void assign(octave_value::assign_op op, const std::string &type, const std::list< octave_value_list > &idx, const octave_value &value, context_id context=xdefault_context)
Definition: symtab.h:541
static octave_value find_autoload(const std::string &name)
Definition: symtab.h:1530
void erase_persistent(void)
Definition: symtab.h:636
static octave_user_function * get_curr_fcn(scope_id scope=xcurrent_scope)
Definition: symtab.h:2281
std::map< std::string, std::string > dispatch_map_type
Definition: symtab.h:738
octave_value do_persistent_varval(const std::string &name)
Definition: symtab.h:2628
std::list< symbol_record > do_glob(const std::string &pattern, bool vars_only=false) const
Definition: symtab.h:2814
octave_value find_built_in_function(void) const
Definition: symtab.h:1033
void mark_automatic(void)
Definition: symtab.h:617
void assign(const octave_value &value, context_id context=xdefault_context)
Definition: symtab.h:535
static void erase_persistent(const std::string &name)
Definition: symtab.h:1477
static std::map< scope_id, symbol_table * > all_instances
Definition: symtab.h:2367
void insert_symbol_record(const symbol_record &sr)
Definition: symtab.h:2471
static std::map< std::string, std::set< std::string > > class_precedence_table
Definition: symtab.h:2375
static octave_idx_type find(octave_idx_type i, octave_idx_type *pp)
Definition: colamd.cc:111
std::map< scope_id, symbol_table * >::const_iterator all_instances_const_iterator
Definition: symtab.h:2326
static std::list< std::string > variable_names(void)
Definition: symtab.h:2113
void unmark_automatic(void)
Definition: symtab.h:626
static octave_value & global_varref(const std::string &name) GCC_ATTR_DEPRECATED
Definition: symtab.h:1409
std::map< scope_id, symbol_table * >::iterator all_instances_iterator
Definition: symtab.h:2328
context_id active_context(void) const
Definition: symtab.h:640
static void clear_all(bool force=false)
Definition: symtab.h:1655
static std::list< std::string > user_function_names(void)
Definition: symtab.h:2076
static std::string help_for_dispatch(const std::string &name)
Definition: symtab.h:1886
void do_clear_variable_regexp(const std::string &pat)
Definition: symtab.h:2763
void erase_subfunction(scope_id scope)
Definition: symtab.h:1081
void rename(const std::string &new_name)
Definition: symtab.h:530
octave_idx_type length(void) const
Number of elements in the array.
Definition: Array.h:267
static void alias_built_in_function(const std::string &alias, const std::string &name)
Definition: symtab.h:1808
void do_non_const_unary_op(octave_value::unary_op op, const std::string &type, const std::list< octave_value_list > &idx)
Definition: symtab.h:561
void do_cache_name(const std::string &name)
Definition: symtab.h:2895
std::map< std::string, symbol_record >::const_iterator table_const_iterator
Definition: symtab.h:2311
void do_clear_global_pattern(const std::string &pat)
Definition: symtab.h:2722
dispatch_map_type get_dispatch(void) const
Definition: symtab.h:931
static bool is_local_variable(const std::string &name)
Definition: symtab.h:2158
symbol_record_rep * rep
Definition: symtab.h:656
std::map< std::string, octave_value >::iterator str_val_iterator
Definition: symtab.h:746
fcn_info_rep(const std::string &nm)
Definition: symtab.h:758
static symbol_table * instance
Definition: symtab.h:2364
std::list< std::string > do_variable_names(void)
Definition: symtab.h:2860
static const scope_id xtop_scope
Definition: symtab.h:2391
static std::list< scope_id > scopes(void)
Definition: symtab.h:1275
bool is_valid(void) const
Definition: symtab.h:597
void do_mark_hidden(const std::string &name)
Definition: symtab.h:2784
bool is_user_function_defined(void) const
Definition: symtab.h:1053
void unmark_inherited(void)
Definition: symtab.h:629
bool is_defined(context_id context=xdefault_context) const
Definition: symtab.h:363
static void free(scope_id scope)
Definition: symtab.h:75
void clear_mex_function(void)
Definition: symtab.h:1124
static double fi[256]
Definition: randmtzig.c:443
symbol_reference(const symbol_record &record, scope_id curr_scope=symbol_table::current_scope())
Definition: symtab.h:670
void do_free(scope_id scope)
Definition: symtab.h:145
static std::list< std::string > top_level_variable_names(void)
Definition: symtab.h:2106
void install_cmdline_function(const octave_value &f)
Definition: symtab.h:1092
std::map< std::string, octave_value > persistent_table
Definition: symtab.h:2361
static std::list< symbol_record > glob_global_variables(const std::string &pattern)
Definition: symtab.h:1998
void clear(bool force=false)
Definition: symtab.h:902
symbol_record(scope_id s=xcurrent_scope, const std::string &nm=std::string(), const octave_value &v=octave_value(), unsigned int sc=local)
Definition: symtab.h:491
void add_nest_child(symbol_table &st)
Definition: symtab.h:2464
void do_rename(const std::string &old_name, const std::string &new_name)
Definition: symtab.h:2553
std::pair< std::string, octave_value > subfunction_defined_in_scope(scope_id scope) const
Definition: symtab.h:819
static const scope_id xglobal_scope
Definition: symtab.h:2390
scope_id do_alloc(void)
Definition: symtab.h:126
int scope_id
Definition: symtab.h:50
void lock_subfunction(scope_id scope)
Definition: symtab.h:802
octave_value & varref(context_id context=xdefault_context)
Definition: symtab.h:569
std::list< symbol_record > do_regexp(const std::string &pattern, bool vars_only=false) const
Definition: symtab.h:2837
bool is_undefined(context_id context=xdefault_context) const
Definition: symtab.h:592
octave_value & do_persistent_varref(const std::string &name)
Definition: symtab.h:2620
static void inherit(scope_id scope, scope_id donor_scope, context_id donor_context)
Definition: symtab.h:1290
void clear_autoload_function(bool force=false)
Definition: symtab.h:874
std::map< std::string, std::set< std::string > >::const_iterator class_precedence_table_const_iterator
Definition: symtab.h:2378
void set_curr_fcn(octave_user_function *fcn)
Definition: symtab.h:646
void do_erase_persistent(const std::string &name)
Definition: symtab.h:2635
void assign(octave_value::assign_op op, const octave_value &value, context_id context=xdefault_context)
Definition: symtab.h:550
void do_inherit(symbol_table &donor_table, context_id donor_context)
Definition: symtab.h:2494
static bool instance_ok(void)
Definition: symtab.h:88
void mark_inherited(void)
Definition: symtab.h:620
void dump(std::ostream &os, const std::string &prefix=std::string()) const
Definition: symtab.h:1150
static fcn_info * get_fcn_info(const std::string &name)
Definition: symtab.h:2519
symbol_record dup(scope_id new_scope) const
Definition: symtab.h:523
static bool is_built_in_function_name(const std::string &name)
Definition: symtab.h:1493
static void unlock_subfunctions(scope_id scope=xcurrent_scope)
Definition: symtab.h:2211
static void clear_symbol_pattern(const std::string &pat)
Definition: symtab.h:1756
static void clear_variable_regexp(const std::string &pat)
Definition: symtab.h:1748
static void update_nest(scope_id scope)
Definition: symtab.h:1601
size_t context_id
Definition: symtab.h:51
bool is_inherited(void) const
Definition: symtab.h:612
void do_mark_global(const std::string &name)
Definition: symtab.h:2789
std::vector< symbol_table * > nest_children
Definition: symtab.h:2346
std::string full_name(void) const
Definition: symtab.h:935
static octave_value & force_varref(const std::string &name, scope_id scope=xcurrent_scope, context_id context=xdefault_context) GCC_ATTR_DEPRECATED
Definition: symtab.h:1375
std::map< std::string, fcn_info >::const_iterator fcn_table_const_iterator
Definition: symtab.h:2331
void install_subfunction(const octave_value &f, scope_id scope)
Definition: symtab.h:1097
void mark_persistent(void)
Definition: symtab.h:622
bool do_is_variable(const std::string &name) const
Definition: symtab.h:2643
static octave_value find_user_function(const std::string &name)
Definition: symtab.h:1543
static std::map< std::string, octave_value > subfunctions_defined_in_scope(scope_id scope=xcurrent_scope)
Definition: symtab.h:2219
unary_op
Definition: ov.h:74
void assign(octave_value::assign_op op, const octave_value &value, context_id context=xdefault_context)
Definition: symtab.h:234
static void print_dispatch(std::ostream &os, const std::string &name)
Definition: symtab.h:1858
static octave_value & top_level_varref(const std::string &name) GCC_ATTR_DEPRECATED
Definition: symtab.h:1434
symbol_record(const symbol_record &sr)
Definition: symtab.h:497
static octave_value & varref(const std::string &name, scope_id scope=xcurrent_scope, context_id context=xdefault_context, bool force_add=false) GCC_ATTR_DEPRECATED
Definition: symtab.h:1351
static std::list< std::string > built_in_function_names(void)
Definition: symtab.h:2120
static void clear_function(const std::string &name)
Definition: symtab.h:1692
std::map< scope_id, octave_value > subfunctions
Definition: symtab.h:948
static void clear_function_pattern(const std::string &pat)
Definition: symtab.h:1721
octave_value find(const octave_value_list &args=octave_value_list(), bool local_funcs=true)
Definition: symtab.h:1017
bool is_match(const std::string &buffer)
Definition: lo-regexp.cc:427
static void set_scope_and_context(scope_id scope, context_id context)
Definition: symtab.h:1192
size_t pop_context(scope_id s)
Definition: symtab.h:581
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
void unmark_persistent(void)
Definition: symtab.h:631
static octave_value & persistent_varref(const std::string &name) GCC_ATTR_DEPRECATED
Definition: symtab.h:1460
static void erase_scope(scope_id scope)
Definition: symtab.h:1218
std::map< scope_id, octave_value >::const_iterator scope_val_const_iterator
Definition: symtab.h:741
static void top_level_assign(const std::string &name, const octave_value &value=octave_value())
Definition: symtab.h:1426
bool is_hidden(void) const
Definition: symtab.h:611
void do_clear_variable_pattern(const std::string &pat)
Definition: symtab.h:2747
static scope_id current_scope(void)
Definition: symtab.h:1163
octave_value & do_varref(const std::string &name, context_id context, bool force_add)
Definition: symtab.h:2586
void clear_autoload_function(bool force=false)
Definition: symtab.h:1119
static octave_value top_level_varval(const std::string &name)
Definition: symtab.h:1444
symbol_record do_find_symbol(const std::string &name)
Definition: symtab.h:2484
void do_mark_automatic(const std::string &name)
Definition: symtab.h:2779
void add_dispatch(const std::string &type, const std::string &fname)
Definition: symtab.h:914
const std::string & name(void) const
Definition: symtab.h:528