comparison src/symtab.h @ 10313:f3b65e1ae355

untabify src header files
author John W. Eaton <jwe@octave.org>
date Thu, 11 Feb 2010 12:16:43 -0500
parents cd96d29c5efa
children 97b4bd6f0925
comparison
equal deleted inserted replaced
10312:cbc402e64d83 10313:f3b65e1ae355
71 } 71 }
72 72
73 static void free (scope_id scope) 73 static void free (scope_id scope)
74 { 74 {
75 if (instance_ok ()) 75 if (instance_ok ())
76 return instance->do_free (scope); 76 return instance->do_free (scope);
77 } 77 }
78 78
79 static std::list<scope_id> scopes (void) 79 static std::list<scope_id> scopes (void)
80 { 80 {
81 return instance_ok () ? instance->do_scopes () : std::list<scope_id> (); 81 return instance_ok () ? instance->do_scopes () : std::list<scope_id> ();
84 static bool instance_ok (void) 84 static bool instance_ok (void)
85 { 85 {
86 bool retval = true; 86 bool retval = true;
87 87
88 if (! instance) 88 if (! instance)
89 instance = new scope_id_cache (); 89 instance = new scope_id_cache ();
90 90
91 if (! instance) 91 if (! instance)
92 { 92 {
93 ::error ("unable to create scope_id_cache object!"); 93 ::error ("unable to create scope_id_cache object!");
94 94
95 retval = false; 95 retval = false;
96 } 96 }
97 97
98 return retval; 98 return retval;
99 } 99 }
100 100
101 private: 101 private:
116 scope_id retval; 116 scope_id retval;
117 117
118 set_iterator p = free_list.begin (); 118 set_iterator p = free_list.begin ();
119 119
120 if (p != free_list.end ()) 120 if (p != free_list.end ())
121 { 121 {
122 retval = *p; 122 retval = *p;
123 free_list.erase (p); 123 free_list.erase (p);
124 } 124 }
125 else 125 else
126 retval = next_available++; 126 retval = next_available++;
127 127
128 in_use.insert (retval); 128 in_use.insert (retval);
129 129
130 return retval; 130 return retval;
131 } 131 }
133 void do_free (scope_id scope) 133 void do_free (scope_id scope)
134 { 134 {
135 set_iterator p = in_use.find (scope); 135 set_iterator p = in_use.find (scope);
136 136
137 if (p != in_use.end ()) 137 if (p != in_use.end ())
138 { 138 {
139 in_use.erase (p); 139 in_use.erase (p);
140 free_list.insert (scope); 140 free_list.insert (scope);
141 } 141 }
142 else 142 else
143 error ("free_scope: scope %d not found!", scope); 143 error ("free_scope: scope %d not found!", scope);
144 } 144 }
145 145
146 std::list<scope_id> do_scopes (void) const 146 std::list<scope_id> do_scopes (void) const
147 { 147 {
148 std::list<scope_id> retval; 148 std::list<scope_id> retval;
149 149
150 for (set_const_iterator p = in_use.begin (); p != in_use.end (); p++) 150 for (set_const_iterator p = in_use.begin (); p != in_use.end (); p++)
151 retval.push_back (*p); 151 retval.push_back (*p);
152 152
153 retval.sort (); 153 retval.sort ();
154 154
155 return retval; 155 return retval;
156 } 156 }
194 symbol_record_rep 194 symbol_record_rep
195 { 195 {
196 public: 196 public:
197 197
198 symbol_record_rep (const std::string& nm, const octave_value& v, 198 symbol_record_rep (const std::string& nm, const octave_value& v,
199 unsigned int sc) 199 unsigned int sc)
200 : name (nm), value_stack (), storage_class (sc), finfo (), count (1) 200 : name (nm), value_stack (), storage_class (sc), finfo (), count (1)
201 { 201 {
202 value_stack.push_back (v); 202 value_stack.push_back (v);
203 } 203 }
204 204
205 void force_variable (context_id context) 205 void force_variable (context_id context)
206 { 206 {
207 octave_value& val = varref (context); 207 octave_value& val = varref (context);
208 208
209 if (! val.is_defined ()) 209 if (! val.is_defined ())
210 mark_forced (); 210 mark_forced ();
211 } 211 }
212 212
213 octave_value& varref (context_id context) 213 octave_value& varref (context_id context)
214 { 214 {
215 if (is_global ()) 215 if (is_global ())
216 return symbol_table::global_varref (name); 216 return symbol_table::global_varref (name);
217 else if (is_persistent ()) 217 else if (is_persistent ())
218 return symbol_table::persistent_varref (name); 218 return symbol_table::persistent_varref (name);
219 else 219 else
220 { 220 {
221 context_id n = value_stack.size (); 221 context_id n = value_stack.size ();
222 while (n++ <= context) 222 while (n++ <= context)
223 value_stack.push_back (octave_value ()); 223 value_stack.push_back (octave_value ());
224 224
225 return value_stack[context]; 225 return value_stack[context];
226 } 226 }
227 } 227 }
228 228
229 octave_value varval (context_id context) const 229 octave_value varval (context_id context) const
230 { 230 {
231 if (is_global ()) 231 if (is_global ())
232 return symbol_table::global_varval (name); 232 return symbol_table::global_varval (name);
233 else if (is_persistent ()) 233 else if (is_persistent ())
234 return symbol_table::persistent_varval (name); 234 return symbol_table::persistent_varval (name);
235 else 235 else
236 { 236 {
237 if (context < value_stack.size ()) 237 if (context < value_stack.size ())
238 return value_stack[context]; 238 return value_stack[context];
239 else 239 else
240 return octave_value (); 240 return octave_value ();
241 } 241 }
242 } 242 }
243 243
244 void push_context (void) 244 void push_context (void)
245 { 245 {
246 if (! (is_persistent () || is_global ())) 246 if (! (is_persistent () || is_global ()))
247 value_stack.push_back (octave_value ()); 247 value_stack.push_back (octave_value ());
248 } 248 }
249 249
250 // If pop_context returns 0, we are out of values and this element 250 // If pop_context returns 0, we are out of values and this element
251 // of the symbol table should be deleted. This can happen for 251 // of the symbol table should be deleted. This can happen for
252 // functions like 252 // functions like
261 // 261 //
262 // Here, X should only exist in the final stack frame. 262 // Here, X should only exist in the final stack frame.
263 263
264 size_t pop_context (void) 264 size_t pop_context (void)
265 { 265 {
266 size_t retval = 1; 266 size_t retval = 1;
267 267
268 if (! (is_persistent () || is_global ())) 268 if (! (is_persistent () || is_global ()))
269 { 269 {
270 value_stack.pop_back (); 270 value_stack.pop_back ();
271 retval = value_stack.size (); 271 retval = value_stack.size ();
272 } 272 }
273 273
274 return retval; 274 return retval;
275 } 275 }
276 276
277 void clear (void) 277 void clear (void)
278 { 278 {
279 if (! (is_hidden () || is_inherited ())) 279 if (! (is_hidden () || is_inherited ()))
280 { 280 {
281 if (is_global ()) 281 if (is_global ())
282 unmark_global (); 282 unmark_global ();
283 283
284 if (is_persistent ()) 284 if (is_persistent ())
285 { 285 {
286 symbol_table::persistent_varref (name) 286 symbol_table::persistent_varref (name)
287 = varval (xcurrent_context); 287 = varval (xcurrent_context);
288 288
289 unmark_persistent (); 289 unmark_persistent ();
290 } 290 }
291 291
292 varref (xcurrent_context) = octave_value (); 292 varref (xcurrent_context) = octave_value ();
293 } 293 }
294 } 294 }
295 295
296 bool is_defined (context_id context) const 296 bool is_defined (context_id context) const
297 { 297 {
298 return varval (context).is_defined (); 298 return varval (context).is_defined ();
299 } 299 }
300 300
301 bool is_variable (context_id context) const 301 bool is_variable (context_id context) const
302 { 302 {
303 return (! is_local () || is_defined (context) || is_forced ()); 303 return (! is_local () || is_defined (context) || is_forced ());
304 } 304 }
305 305
306 bool is_local (void) const { return storage_class & local; } 306 bool is_local (void) const { return storage_class & local; }
307 bool is_automatic (void) const { return storage_class & automatic; } 307 bool is_automatic (void) const { return storage_class & automatic; }
308 bool is_formal (void) const { return storage_class & formal; } 308 bool is_formal (void) const { return storage_class & formal; }
317 void mark_formal (void) { storage_class |= formal; } 317 void mark_formal (void) { storage_class |= formal; }
318 void mark_hidden (void) { storage_class |= hidden; } 318 void mark_hidden (void) { storage_class |= hidden; }
319 void mark_inherited (void) { storage_class |= inherited; } 319 void mark_inherited (void) { storage_class |= inherited; }
320 void mark_global (void) 320 void mark_global (void)
321 { 321 {
322 if (is_persistent ()) 322 if (is_persistent ())
323 error ("can't make persistent variable %s global", name.c_str ()); 323 error ("can't make persistent variable %s global", name.c_str ());
324 else 324 else
325 storage_class |= global; 325 storage_class |= global;
326 } 326 }
327 void mark_persistent (void) 327 void mark_persistent (void)
328 { 328 {
329 if (is_global ()) 329 if (is_global ())
330 error ("can't make global variable %s persistent", name.c_str ()); 330 error ("can't make global variable %s persistent", name.c_str ());
331 else 331 else
332 storage_class |= persistent; 332 storage_class |= persistent;
333 } 333 }
334 void mark_forced (void) { storage_class |= forced; } 334 void mark_forced (void) { storage_class |= forced; }
335 335
336 void unmark_local (void) { storage_class &= ~local; } 336 void unmark_local (void) { storage_class &= ~local; }
337 void unmark_automatic (void) { storage_class &= ~automatic; } 337 void unmark_automatic (void) { storage_class &= ~automatic; }
342 void unmark_persistent (void) { storage_class &= ~persistent; } 342 void unmark_persistent (void) { storage_class &= ~persistent; }
343 void unmark_forced (void) { storage_class &= ~forced; } 343 void unmark_forced (void) { storage_class &= ~forced; }
344 344
345 void init_persistent (void) 345 void init_persistent (void)
346 { 346 {
347 if (! is_defined (xcurrent_context)) 347 if (! is_defined (xcurrent_context))
348 { 348 {
349 mark_persistent (); 349 mark_persistent ();
350 350
351 varref (xcurrent_context) = symbol_table::persistent_varval (name); 351 varref (xcurrent_context) = symbol_table::persistent_varval (name);
352 } 352 }
353 // FIXME -- this causes trouble with recursive calls. 353 // FIXME -- this causes trouble with recursive calls.
354 // else 354 // else
355 // error ("unable to declare existing variable persistent"); 355 // error ("unable to declare existing variable persistent");
356 } 356 }
357 357
358 void erase_persistent (void) 358 void erase_persistent (void)
359 { 359 {
360 unmark_persistent (); 360 unmark_persistent ();
361 symbol_table::erase_persistent (name); 361 symbol_table::erase_persistent (name);
362 } 362 }
363 363
364 symbol_record_rep *dup (void) const 364 symbol_record_rep *dup (void) const
365 { 365 {
366 return new symbol_record_rep (name, varval (xcurrent_context), 366 return new symbol_record_rep (name, varval (xcurrent_context),
367 storage_class); 367 storage_class);
368 } 368 }
369 369
370 void dump (std::ostream& os, const std::string& prefix) const; 370 void dump (std::ostream& os, const std::string& prefix) const;
371 371
372 std::string name; 372 std::string name;
389 }; 389 };
390 390
391 public: 391 public:
392 392
393 symbol_record (const std::string& nm = std::string (), 393 symbol_record (const std::string& nm = std::string (),
394 const octave_value& v = octave_value (), 394 const octave_value& v = octave_value (),
395 unsigned int sc = local) 395 unsigned int sc = local)
396 : rep (new symbol_record_rep (nm, v, sc)) { } 396 : rep (new symbol_record_rep (nm, v, sc)) { }
397 397
398 symbol_record (const symbol_record& sr) 398 symbol_record (const symbol_record& sr)
399 : rep (sr.rep) 399 : rep (sr.rep)
400 { 400 {
402 } 402 }
403 403
404 symbol_record& operator = (const symbol_record& sr) 404 symbol_record& operator = (const symbol_record& sr)
405 { 405 {
406 if (this != &sr) 406 if (this != &sr)
407 { 407 {
408 if (--rep->count == 0) 408 if (--rep->count == 0)
409 delete rep; 409 delete rep;
410 410
411 rep = sr.rep; 411 rep = sr.rep;
412 rep->count++; 412 rep->count++;
413 } 413 }
414 414
415 return *this; 415 return *this;
416 } 416 }
417 417
418 ~symbol_record (void) 418 ~symbol_record (void)
419 { 419 {
420 if (--rep->count == 0) 420 if (--rep->count == 0)
421 delete rep; 421 delete rep;
422 } 422 }
423 423
424 symbol_record dup (void) const { return symbol_record (rep->dup ()); } 424 symbol_record dup (void) const { return symbol_record (rep->dup ()); }
425 425
426 std::string name (void) const { return rep->name; } 426 std::string name (void) const { return rep->name; }
526 fcn_info_rep 526 fcn_info_rep
527 { 527 {
528 public: 528 public:
529 529
530 fcn_info_rep (const std::string& nm) 530 fcn_info_rep (const std::string& nm)
531 : name (nm), subfunctions (), private_functions (), 531 : name (nm), subfunctions (), private_functions (),
532 class_constructors (), class_methods (), cmdline_function (), 532 class_constructors (), class_methods (), cmdline_function (),
533 autoload_function (), function_on_path (), built_in_function (), 533 autoload_function (), function_on_path (), built_in_function (),
534 count (1) { } 534 count (1) { }
535 535
536 octave_value load_private_function (const std::string& dir_name); 536 octave_value load_private_function (const std::string& dir_name);
537 537
538 octave_value load_class_constructor (void); 538 octave_value load_class_constructor (void);
539 539
549 549
550 octave_value find_user_function (void); 550 octave_value find_user_function (void);
551 551
552 bool is_user_function_defined (void) const 552 bool is_user_function_defined (void) const
553 { 553 {
554 return function_on_path.is_defined (); 554 return function_on_path.is_defined ();
555 } 555 }
556 556
557 octave_value find_function (const octave_value_list& args, bool local_funcs) 557 octave_value find_function (const octave_value_list& args, bool local_funcs)
558 { 558 {
559 return find (args, local_funcs); 559 return find (args, local_funcs);
560 } 560 }
561 561
562 void lock_subfunction (scope_id scope) 562 void lock_subfunction (scope_id scope)
563 { 563 {
564 scope_val_iterator p = subfunctions.find (scope); 564 scope_val_iterator p = subfunctions.find (scope);
565 565
566 if (p != subfunctions.end ()) 566 if (p != subfunctions.end ())
567 p->second.lock (); 567 p->second.lock ();
568 } 568 }
569 569
570 void unlock_subfunction (scope_id scope) 570 void unlock_subfunction (scope_id scope)
571 { 571 {
572 scope_val_iterator p = subfunctions.find (scope); 572 scope_val_iterator p = subfunctions.find (scope);
573 573
574 if (p != subfunctions.end ()) 574 if (p != subfunctions.end ())
575 p->second.unlock (); 575 p->second.unlock ();
576 } 576 }
577 577
578 std::pair<std::string, octave_value> 578 std::pair<std::string, octave_value>
579 subfunction_defined_in_scope (scope_id scope) const 579 subfunction_defined_in_scope (scope_id scope) const
580 { 580 {
581 scope_val_const_iterator p = subfunctions.find (scope); 581 scope_val_const_iterator p = subfunctions.find (scope);
582 582
583 return p == subfunctions.end () 583 return p == subfunctions.end ()
584 ? std::pair<std::string, octave_value> () 584 ? std::pair<std::string, octave_value> ()
585 : std::pair<std::string, octave_value> (name, p->second); 585 : std::pair<std::string, octave_value> (name, p->second);
586 } 586 }
587 587
588 void erase_subfunction (scope_id scope) 588 void erase_subfunction (scope_id scope)
589 { 589 {
590 scope_val_iterator p = subfunctions.find (scope); 590 scope_val_iterator p = subfunctions.find (scope);
591 591
592 if (p != subfunctions.end ()) 592 if (p != subfunctions.end ())
593 subfunctions.erase (p); 593 subfunctions.erase (p);
594 } 594 }
595 595
596 void install_cmdline_function (const octave_value& f) 596 void install_cmdline_function (const octave_value& f)
597 { 597 {
598 cmdline_function = f; 598 cmdline_function = f;
599 } 599 }
600 600
601 void install_subfunction (const octave_value& f, scope_id scope) 601 void install_subfunction (const octave_value& f, scope_id scope)
602 { 602 {
603 subfunctions[scope] = f; 603 subfunctions[scope] = f;
604 } 604 }
605 605
606 void install_user_function (const octave_value& f) 606 void install_user_function (const octave_value& f)
607 { 607 {
608 function_on_path = f; 608 function_on_path = f;
609 } 609 }
610 610
611 void install_built_in_function (const octave_value& f) 611 void install_built_in_function (const octave_value& f)
612 { 612 {
613 built_in_function = f; 613 built_in_function = f;
614 } 614 }
615 615
616 template <class T> 616 template <class T>
617 void 617 void
618 clear_unlocked (std::map<T, octave_value>& map) 618 clear_unlocked (std::map<T, octave_value>& map)
619 { 619 {
620 typename std::map<T, octave_value>::iterator p = map.begin (); 620 typename std::map<T, octave_value>::iterator p = map.begin ();
621 621
622 while (p != map.end ()) 622 while (p != map.end ())
623 { 623 {
624 if (p->second.islocked ()) 624 if (p->second.islocked ())
625 p++; 625 p++;
626 else 626 else
627 map.erase (p++); 627 map.erase (p++);
628 } 628 }
629 } 629 }
630 630
631 void clear_cmdline_function (void) 631 void clear_cmdline_function (void)
632 { 632 {
633 if (! cmdline_function.islocked ()) 633 if (! cmdline_function.islocked ())
634 cmdline_function = octave_value (); 634 cmdline_function = octave_value ();
635 } 635 }
636 636
637 void clear_autoload_function (void) 637 void clear_autoload_function (void)
638 { 638 {
639 if (! autoload_function.islocked ()) 639 if (! autoload_function.islocked ())
640 autoload_function = octave_value (); 640 autoload_function = octave_value ();
641 } 641 }
642 642
643 // FIXME -- should this also clear the cmdline and other "user 643 // FIXME -- should this also clear the cmdline and other "user
644 // defined" functions? 644 // defined" functions?
645 void clear_user_function (void) 645 void clear_user_function (void)
646 { 646 {
647 if (! function_on_path.islocked ()) 647 if (! function_on_path.islocked ())
648 { 648 {
649 function_on_path.erase_subfunctions (); 649 function_on_path.erase_subfunctions ();
650 650
651 function_on_path = octave_value (); 651 function_on_path = octave_value ();
652 } 652 }
653 } 653 }
654 654
655 void clear_mex_function (void) 655 void clear_mex_function (void)
656 { 656 {
657 if (function_on_path.is_mex_function ()) 657 if (function_on_path.is_mex_function ())
658 clear_user_function (); 658 clear_user_function ();
659 } 659 }
660 660
661 void clear (void) 661 void clear (void)
662 { 662 {
663 clear_unlocked (subfunctions); 663 clear_unlocked (subfunctions);
664 clear_unlocked (private_functions); 664 clear_unlocked (private_functions);
665 clear_unlocked (class_constructors); 665 clear_unlocked (class_constructors);
666 clear_unlocked (class_methods); 666 clear_unlocked (class_methods);
667 clear_cmdline_function (); 667 clear_cmdline_function ();
668 clear_autoload_function (); 668 clear_autoload_function ();
669 clear_user_function (); 669 clear_user_function ();
670 } 670 }
671 671
672 void add_dispatch (const std::string& type, const std::string& fname) 672 void add_dispatch (const std::string& type, const std::string& fname)
673 { 673 {
674 dispatch_map[type] = fname; 674 dispatch_map[type] = fname;
675 } 675 }
676 676
677 void clear_dispatch (const std::string& type) 677 void clear_dispatch (const std::string& type)
678 { 678 {
679 dispatch_map_iterator p = dispatch_map.find (type); 679 dispatch_map_iterator p = dispatch_map.find (type);
680 680
681 if (p != dispatch_map.end ()) 681 if (p != dispatch_map.end ())
682 dispatch_map.erase (p); 682 dispatch_map.erase (p);
683 } 683 }
684 684
685 void print_dispatch (std::ostream& os) const; 685 void print_dispatch (std::ostream& os) const;
686 686
687 std::string help_for_dispatch (void) const; 687 std::string help_for_dispatch (void) const;
741 } 741 }
742 742
743 fcn_info& operator = (const fcn_info& fi) 743 fcn_info& operator = (const fcn_info& fi)
744 { 744 {
745 if (this != &fi) 745 if (this != &fi)
746 { 746 {
747 if (--rep->count == 0) 747 if (--rep->count == 0)
748 delete rep; 748 delete rep;
749 749
750 rep = fi.rep; 750 rep = fi.rep;
751 rep->count++; 751 rep->count++;
752 } 752 }
753 753
754 return *this; 754 return *this;
755 } 755 }
756 756
757 ~fcn_info (void) 757 ~fcn_info (void)
758 { 758 {
759 if (--rep->count == 0) 759 if (--rep->count == 0)
760 delete rep; 760 delete rep;
761 } 761 }
762 762
763 octave_value find (const octave_value_list& args = octave_value_list (), 763 octave_value find (const octave_value_list& args = octave_value_list (),
764 bool local_funcs = true) 764 bool local_funcs = true)
765 { 765 {
814 814
815 std::pair<std::string, octave_value> 815 std::pair<std::string, octave_value>
816 subfunction_defined_in_scope (scope_id scope = xcurrent_scope) const 816 subfunction_defined_in_scope (scope_id scope = xcurrent_scope) const
817 { 817 {
818 return rep->subfunction_defined_in_scope (scope); 818 return rep->subfunction_defined_in_scope (scope);
819 } 819 }
820 820
821 void erase_subfunction (scope_id scope) 821 void erase_subfunction (scope_id scope)
822 { 822 {
823 rep->erase_subfunction (scope); 823 rep->erase_subfunction (scope);
824 } 824 }
897 { 897 {
898 if (scope == xglobal_scope) 898 if (scope == xglobal_scope)
899 error ("can't set scope to global"); 899 error ("can't set scope to global");
900 else if (scope != xcurrent_scope) 900 else if (scope != xcurrent_scope)
901 { 901 {
902 all_instances_iterator p = all_instances.find (scope); 902 all_instances_iterator p = all_instances.find (scope);
903 903
904 if (p == all_instances.end ()) 904 if (p == all_instances.end ())
905 { 905 {
906 symbol_table *inst = new symbol_table (); 906 symbol_table *inst = new symbol_table ();
907 907
908 if (inst) 908 if (inst)
909 all_instances[scope] = instance = inst; 909 all_instances[scope] = instance = inst;
910 } 910 }
911 else 911 else
912 instance = p->second; 912 instance = p->second;
913 913
914 xcurrent_scope = scope; 914 xcurrent_scope = scope;
915 xcurrent_context = 0; 915 xcurrent_context = 0;
916 } 916 }
917 } 917 }
918 918
919 static void set_scope_and_context (scope_id scope, context_id context) 919 static void set_scope_and_context (scope_id scope, context_id context)
920 { 920 {
921 if (scope == xglobal_scope) 921 if (scope == xglobal_scope)
922 error ("can't set scope to global"); 922 error ("can't set scope to global");
923 else 923 else
924 { 924 {
925 if (scope != xcurrent_scope) 925 if (scope != xcurrent_scope)
926 { 926 {
927 all_instances_iterator p = all_instances.find (scope); 927 all_instances_iterator p = all_instances.find (scope);
928 928
929 if (p == all_instances.end ()) 929 if (p == all_instances.end ())
930 error ("scope not found!"); 930 error ("scope not found!");
931 else 931 else
932 { 932 {
933 instance = p->second; 933 instance = p->second;
934 934
935 xcurrent_scope = scope; 935 xcurrent_scope = scope;
936 936
937 xcurrent_context = context; 937 xcurrent_context = context;
938 } 938 }
939 } 939 }
940 else 940 else
941 xcurrent_context = context; 941 xcurrent_context = context;
942 } 942 }
943 } 943 }
944 944
948 948
949 all_instances_iterator p = all_instances.find (scope); 949 all_instances_iterator p = all_instances.find (scope);
950 950
951 if (p != all_instances.end ()) 951 if (p != all_instances.end ())
952 { 952 {
953 delete p->second; 953 delete p->second;
954 954
955 all_instances.erase (p); 955 all_instances.erase (p);
956 956
957 free_scope (scope); 957 free_scope (scope);
958 } 958 }
959 } 959 }
960 960
961 static void erase_subfunctions_in_scope (scope_id scope) 961 static void erase_subfunctions_in_scope (scope_id scope)
962 { 962 {
963 for (fcn_table_iterator q = fcn_table.begin (); 963 for (fcn_table_iterator q = fcn_table.begin ();
964 q != fcn_table.end (); q++) 964 q != fcn_table.end (); q++)
965 q->second.erase_subfunction (scope); 965 q->second.erase_subfunction (scope);
966 } 966 }
967 967
968 static scope_id dup_scope (scope_id scope) 968 static scope_id dup_scope (scope_id scope)
969 { 969 {
971 971
972 symbol_table *inst = get_instance (scope); 972 symbol_table *inst = get_instance (scope);
973 973
974 if (inst) 974 if (inst)
975 { 975 {
976 scope_id new_scope = alloc_scope (); 976 scope_id new_scope = alloc_scope ();
977 977
978 symbol_table *new_symbol_table = new symbol_table (); 978 symbol_table *new_symbol_table = new symbol_table ();
979 979
980 if (new_symbol_table) 980 if (new_symbol_table)
981 { 981 {
982 all_instances[new_scope] = new_symbol_table; 982 all_instances[new_scope] = new_symbol_table;
983 983
984 inst->do_dup_scope (*new_symbol_table); 984 inst->do_dup_scope (*new_symbol_table);
985 985
986 retval = new_scope; 986 retval = new_scope;
987 } 987 }
988 } 988 }
989 989
990 return retval; 990 return retval;
991 } 991 }
992 992
1008 { 1008 {
1009 symbol_table *inst = get_instance (scope); 1009 symbol_table *inst = get_instance (scope);
1010 1010
1011 if (inst) 1011 if (inst)
1012 { 1012 {
1013 symbol_table *donor_symbol_table = get_instance (donor_scope); 1013 symbol_table *donor_symbol_table = get_instance (donor_scope);
1014 1014
1015 if (donor_symbol_table) 1015 if (donor_symbol_table)
1016 inst->do_inherit (*donor_symbol_table, donor_context); 1016 inst->do_inherit (*donor_symbol_table, donor_context);
1017 } 1017 }
1018 } 1018 }
1019 1019
1020 static bool at_top_level (void) { return xcurrent_scope == xtop_scope; } 1020 static bool at_top_level (void) { return xcurrent_scope == xtop_scope; }
1021 1021
1022 // Find a value corresponding to the given name in the table. 1022 // Find a value corresponding to the given name in the table.
1023 static octave_value 1023 static octave_value
1024 find (const std::string& name, 1024 find (const std::string& name,
1025 const octave_value_list& args = octave_value_list (), 1025 const octave_value_list& args = octave_value_list (),
1026 bool skip_variables = false, 1026 bool skip_variables = false,
1027 bool local_funcs = true); 1027 bool local_funcs = true);
1028 1028
1029 static octave_value builtin_find (const std::string& name); 1029 static octave_value builtin_find (const std::string& name);
1030 1030
1031 // Insert a new name in the table. 1031 // Insert a new name in the table.
1037 1037
1038 return inst ? inst->do_insert (name) : foobar; 1038 return inst ? inst->do_insert (name) : foobar;
1039 } 1039 }
1040 1040
1041 static void force_variable (const std::string& name, 1041 static void force_variable (const std::string& name,
1042 scope_id scope = xcurrent_scope, 1042 scope_id scope = xcurrent_scope,
1043 context_id context = xcurrent_context) 1043 context_id context = xcurrent_context)
1044 { 1044 {
1045 symbol_table *inst = get_instance (scope); 1045 symbol_table *inst = get_instance (scope);
1046 1046
1047 if (inst) 1047 if (inst)
1048 inst->do_force_variable (name, context); 1048 inst->do_force_variable (name, context);
1049 } 1049 }
1050 1050
1051 static octave_value& varref (const std::string& name, 1051 static octave_value& varref (const std::string& name,
1052 scope_id scope = xcurrent_scope, 1052 scope_id scope = xcurrent_scope,
1053 context_id context = xcurrent_context) 1053 context_id context = xcurrent_context)
1054 { 1054 {
1055 static octave_value foobar; 1055 static octave_value foobar;
1056 1056
1057 symbol_table *inst = get_instance (scope); 1057 symbol_table *inst = get_instance (scope);
1058 1058
1059 return inst ? inst->do_varref (name, context) : foobar; 1059 return inst ? inst->do_varref (name, context) : foobar;
1060 } 1060 }
1061 1061
1062 static octave_value varval (const std::string& name, 1062 static octave_value varval (const std::string& name,
1063 scope_id scope = xcurrent_scope, 1063 scope_id scope = xcurrent_scope,
1064 context_id context = xcurrent_context) 1064 context_id context = xcurrent_context)
1065 { 1065 {
1066 symbol_table *inst = get_instance (scope); 1066 symbol_table *inst = get_instance (scope);
1067 1067
1068 return inst ? inst->do_varval (name, context) : octave_value (); 1068 return inst ? inst->do_varval (name, context) : octave_value ();
1069 } 1069 }
1142 1142
1143 if (p != fcn_table.end ()) 1143 if (p != fcn_table.end ())
1144 return p->second.find_method (dispatch_type); 1144 return p->second.find_method (dispatch_type);
1145 else 1145 else
1146 { 1146 {
1147 fcn_info finfo (name); 1147 fcn_info finfo (name);
1148 1148
1149 octave_value fcn = finfo.find_method (dispatch_type); 1149 octave_value fcn = finfo.find_method (dispatch_type);
1150 1150
1151 if (fcn.is_defined ()) 1151 if (fcn.is_defined ())
1152 fcn_table[name] = finfo; 1152 fcn_table[name] = finfo;
1153 1153
1154 return fcn; 1154 return fcn;
1155 } 1155 }
1156 } 1156 }
1157 1157
1158 static octave_value 1158 static octave_value
1159 find_built_in_function (const std::string& name) 1159 find_built_in_function (const std::string& name)
1185 return (p != fcn_table.end ()) 1185 return (p != fcn_table.end ())
1186 ? p->second.find_user_function () : octave_value (); 1186 ? p->second.find_user_function () : octave_value ();
1187 } 1187 }
1188 1188
1189 static void install_cmdline_function (const std::string& name, 1189 static void install_cmdline_function (const std::string& name,
1190 const octave_value& fcn) 1190 const octave_value& fcn)
1191 { 1191 {
1192 fcn_table_iterator p = fcn_table.find (name); 1192 fcn_table_iterator p = fcn_table.find (name);
1193 1193
1194 if (p != fcn_table.end ()) 1194 if (p != fcn_table.end ())
1195 { 1195 {
1196 fcn_info& finfo = p->second; 1196 fcn_info& finfo = p->second;
1197 1197
1198 finfo.install_cmdline_function (fcn); 1198 finfo.install_cmdline_function (fcn);
1199 } 1199 }
1200 else 1200 else
1201 { 1201 {
1202 fcn_info finfo (name); 1202 fcn_info finfo (name);
1203 1203
1204 finfo.install_cmdline_function (fcn); 1204 finfo.install_cmdline_function (fcn);
1205 1205
1206 fcn_table[name] = finfo; 1206 fcn_table[name] = finfo;
1207 } 1207 }
1208 } 1208 }
1209 1209
1210 static void install_subfunction (const std::string& name, 1210 static void install_subfunction (const std::string& name,
1211 const octave_value& fcn, 1211 const octave_value& fcn,
1212 scope_id scope) 1212 scope_id scope)
1213 { 1213 {
1214 fcn_table_iterator p = fcn_table.find (name); 1214 fcn_table_iterator p = fcn_table.find (name);
1215 1215
1216 if (p != fcn_table.end ()) 1216 if (p != fcn_table.end ())
1217 { 1217 {
1218 fcn_info& finfo = p->second; 1218 fcn_info& finfo = p->second;
1219 1219
1220 finfo.install_subfunction (fcn, scope); 1220 finfo.install_subfunction (fcn, scope);
1221 } 1221 }
1222 else 1222 else
1223 { 1223 {
1224 fcn_info finfo (name); 1224 fcn_info finfo (name);
1225 1225
1226 finfo.install_subfunction (fcn, scope); 1226 finfo.install_subfunction (fcn, scope);
1227 1227
1228 fcn_table[name] = finfo; 1228 fcn_table[name] = finfo;
1229 } 1229 }
1230 } 1230 }
1231 1231
1232 static void install_user_function (const std::string& name, 1232 static void install_user_function (const std::string& name,
1233 const octave_value& fcn) 1233 const octave_value& fcn)
1234 { 1234 {
1235 fcn_table_iterator p = fcn_table.find (name); 1235 fcn_table_iterator p = fcn_table.find (name);
1236 1236
1237 if (p != fcn_table.end ()) 1237 if (p != fcn_table.end ())
1238 { 1238 {
1239 fcn_info& finfo = p->second; 1239 fcn_info& finfo = p->second;
1240 1240
1241 finfo.install_user_function (fcn); 1241 finfo.install_user_function (fcn);
1242 } 1242 }
1243 else 1243 else
1244 { 1244 {
1245 fcn_info finfo (name); 1245 fcn_info finfo (name);
1246 1246
1247 finfo.install_user_function (fcn); 1247 finfo.install_user_function (fcn);
1248 1248
1249 fcn_table[name] = finfo; 1249 fcn_table[name] = finfo;
1250 } 1250 }
1251 } 1251 }
1252 1252
1253 static void install_built_in_function (const std::string& name, 1253 static void install_built_in_function (const std::string& name,
1254 const octave_value& fcn) 1254 const octave_value& fcn)
1255 { 1255 {
1256 fcn_table_iterator p = fcn_table.find (name); 1256 fcn_table_iterator p = fcn_table.find (name);
1257 1257
1258 if (p != fcn_table.end ()) 1258 if (p != fcn_table.end ())
1259 { 1259 {
1260 fcn_info& finfo = p->second; 1260 fcn_info& finfo = p->second;
1261 1261
1262 finfo.install_built_in_function (fcn); 1262 finfo.install_built_in_function (fcn);
1263 } 1263 }
1264 else 1264 else
1265 { 1265 {
1266 fcn_info finfo (name); 1266 fcn_info finfo (name);
1267 1267
1268 finfo.install_built_in_function (fcn); 1268 finfo.install_built_in_function (fcn);
1269 1269
1270 fcn_table[name] = finfo; 1270 fcn_table[name] = finfo;
1271 } 1271 }
1272 } 1272 }
1273 1273
1274 static void clear (const std::string& name) 1274 static void clear (const std::string& name)
1275 { 1275 {
1352 { 1352 {
1353 glob_match pattern (pat); 1353 glob_match pattern (pat);
1354 1354
1355 for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++) 1355 for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++)
1356 { 1356 {
1357 if (pattern.match (p->first)) 1357 if (pattern.match (p->first))
1358 p->second.clear_user_function (); 1358 p->second.clear_user_function ();
1359 } 1359 }
1360 } 1360 }
1361 1361
1362 static void clear_global_pattern (const std::string& pat) 1362 static void clear_global_pattern (const std::string& pat)
1363 { 1363 {
1395 { 1395 {
1396 fcn_table_iterator p = fcn_table.find (name); 1396 fcn_table_iterator p = fcn_table.find (name);
1397 1397
1398 if (p != fcn_table.end ()) 1398 if (p != fcn_table.end ())
1399 { 1399 {
1400 fcn_info& finfo = p->second; 1400 fcn_info& finfo = p->second;
1401 1401
1402 finfo.clear_user_function (); 1402 finfo.clear_user_function ();
1403 } 1403 }
1404 // FIXME -- is this necessary, or even useful? 1404 // FIXME -- is this necessary, or even useful?
1405 // else 1405 // else
1406 // error ("clear: no such function `%s'", name.c_str ()); 1406 // error ("clear: no such function `%s'", name.c_str ());
1407 } 1407 }
1411 { 1411 {
1412 fcn_table_iterator p = fcn_table.find (name); 1412 fcn_table_iterator p = fcn_table.find (name);
1413 1413
1414 if (p != fcn_table.end ()) 1414 if (p != fcn_table.end ())
1415 { 1415 {
1416 fcn_info& finfo = p->second; 1416 fcn_info& finfo = p->second;
1417 1417
1418 finfo.clear_autoload_function (); 1418 finfo.clear_autoload_function ();
1419 finfo.clear_user_function (); 1419 finfo.clear_user_function ();
1420 } 1420 }
1421 } 1421 }
1422 1422
1423 static void clear_mex_functions (void) 1423 static void clear_mex_functions (void)
1424 { 1424 {
1425 for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++) 1425 for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++)
1426 { 1426 {
1427 fcn_info& finfo = p->second; 1427 fcn_info& finfo = p->second;
1428 1428
1429 finfo.clear_mex_function (); 1429 finfo.clear_mex_function ();
1430 } 1430 }
1431 } 1431 }
1432 1432
1433 static bool set_class_relationship (const std::string& sup_class, 1433 static bool set_class_relationship (const std::string& sup_class,
1434 const std::string& inf_class); 1434 const std::string& inf_class);
1435 1435
1436 static bool is_superiorto (const std::string& a, const std::string& b); 1436 static bool is_superiorto (const std::string& a, const std::string& b);
1437 1437
1438 static void alias_built_in_function (const std::string& alias, 1438 static void alias_built_in_function (const std::string& alias,
1439 const std::string& name) 1439 const std::string& name)
1440 { 1440 {
1441 octave_value fcn = find_built_in_function (name); 1441 octave_value fcn = find_built_in_function (name);
1442 1442
1443 if (fcn.is_defined ()) 1443 if (fcn.is_defined ())
1444 { 1444 {
1445 fcn_info finfo (alias); 1445 fcn_info finfo (alias);
1446 1446
1447 finfo.install_built_in_function (fcn); 1447 finfo.install_built_in_function (fcn);
1448 1448
1449 fcn_table[alias] = finfo; 1449 fcn_table[alias] = finfo;
1450 } 1450 }
1451 else 1451 else
1452 panic ("alias: `%s' is undefined", name.c_str ()); 1452 panic ("alias: `%s' is undefined", name.c_str ());
1453 } 1453 }
1454 1454
1455 static void add_dispatch (const std::string& name, const std::string& type, 1455 static void add_dispatch (const std::string& name, const std::string& type,
1456 const std::string& fname) 1456 const std::string& fname)
1457 { 1457 {
1458 fcn_table_iterator p = fcn_table.find (name); 1458 fcn_table_iterator p = fcn_table.find (name);
1459 1459
1460 if (p != fcn_table.end ()) 1460 if (p != fcn_table.end ())
1461 { 1461 {
1462 fcn_info& finfo = p->second; 1462 fcn_info& finfo = p->second;
1463 1463
1464 finfo.add_dispatch (type, fname); 1464 finfo.add_dispatch (type, fname);
1465 } 1465 }
1466 else 1466 else
1467 { 1467 {
1468 fcn_info finfo (name); 1468 fcn_info finfo (name);
1469 1469
1470 finfo.add_dispatch (type, fname); 1470 finfo.add_dispatch (type, fname);
1471 1471
1472 fcn_table[name] = finfo; 1472 fcn_table[name] = finfo;
1473 } 1473 }
1474 } 1474 }
1475 1475
1476 static void clear_dispatch (const std::string& name, const std::string& type) 1476 static void clear_dispatch (const std::string& name, const std::string& type)
1477 { 1477 {
1478 fcn_table_iterator p = fcn_table.find (name); 1478 fcn_table_iterator p = fcn_table.find (name);
1479 1479
1480 if (p != fcn_table.end ()) 1480 if (p != fcn_table.end ())
1481 { 1481 {
1482 fcn_info& finfo = p->second; 1482 fcn_info& finfo = p->second;
1483 1483
1484 finfo.clear_dispatch (type); 1484 finfo.clear_dispatch (type);
1485 } 1485 }
1486 } 1486 }
1487 1487
1488 static void print_dispatch (std::ostream& os, const std::string& name) 1488 static void print_dispatch (std::ostream& os, const std::string& name)
1489 { 1489 {
1490 fcn_table_iterator p = fcn_table.find (name); 1490 fcn_table_iterator p = fcn_table.find (name);
1491 1491
1492 if (p != fcn_table.end ()) 1492 if (p != fcn_table.end ())
1493 { 1493 {
1494 fcn_info& finfo = p->second; 1494 fcn_info& finfo = p->second;
1495 1495
1496 finfo.print_dispatch (os); 1496 finfo.print_dispatch (os);
1497 } 1497 }
1498 } 1498 }
1499 1499
1500 static fcn_info::dispatch_map_type get_dispatch (const std::string& name) 1500 static fcn_info::dispatch_map_type get_dispatch (const std::string& name)
1501 { 1501 {
1503 1503
1504 fcn_table_iterator p = fcn_table.find (name); 1504 fcn_table_iterator p = fcn_table.find (name);
1505 1505
1506 if (p != fcn_table.end ()) 1506 if (p != fcn_table.end ())
1507 { 1507 {
1508 fcn_info& finfo = p->second; 1508 fcn_info& finfo = p->second;
1509 1509
1510 retval = finfo.get_dispatch (); 1510 retval = finfo.get_dispatch ();
1511 } 1511 }
1512 1512
1513 return retval; 1513 return retval;
1514 } 1514 }
1515 1515
1519 1519
1520 fcn_table_iterator p = fcn_table.find (name); 1520 fcn_table_iterator p = fcn_table.find (name);
1521 1521
1522 if (p != fcn_table.end ()) 1522 if (p != fcn_table.end ())
1523 { 1523 {
1524 fcn_info& finfo = p->second; 1524 fcn_info& finfo = p->second;
1525 1525
1526 retval = finfo.help_for_dispatch (); 1526 retval = finfo.help_for_dispatch ();
1527 } 1527 }
1528 1528
1529 return retval; 1529 return retval;
1530 } 1530 }
1531 1531
1533 { 1533 {
1534 if (xcurrent_scope == xglobal_scope || xcurrent_scope == xtop_scope) 1534 if (xcurrent_scope == xglobal_scope || xcurrent_scope == xtop_scope)
1535 error ("invalid call to xymtab::push_context"); 1535 error ("invalid call to xymtab::push_context");
1536 else 1536 else
1537 { 1537 {
1538 symbol_table *inst = get_instance (xcurrent_scope); 1538 symbol_table *inst = get_instance (xcurrent_scope);
1539 1539
1540 if (inst) 1540 if (inst)
1541 inst->do_push_context (); 1541 inst->do_push_context ();
1542 } 1542 }
1543 } 1543 }
1544 1544
1545 static void pop_context (void) 1545 static void pop_context (void)
1546 { 1546 {
1547 if (xcurrent_scope == xglobal_scope || xcurrent_scope == xtop_scope) 1547 if (xcurrent_scope == xglobal_scope || xcurrent_scope == xtop_scope)
1548 error ("invalid call to xymtab::pop_context"); 1548 error ("invalid call to xymtab::pop_context");
1549 else 1549 else
1550 { 1550 {
1551 symbol_table *inst = get_instance (xcurrent_scope); 1551 symbol_table *inst = get_instance (xcurrent_scope);
1552 1552
1553 if (inst) 1553 if (inst)
1554 inst->do_pop_context (); 1554 inst->do_pop_context ();
1555 } 1555 }
1556 } 1556 }
1557 1557
1558 // For unwind_protect. 1558 // For unwind_protect.
1559 static void pop_context (void *) { pop_context (); } 1559 static void pop_context (void *) { pop_context (); }
1574 inst->do_mark_global (name); 1574 inst->do_mark_global (name);
1575 } 1575 }
1576 1576
1577 static std::list<symbol_record> 1577 static std::list<symbol_record>
1578 all_variables (scope_id scope = xcurrent_scope, 1578 all_variables (scope_id scope = xcurrent_scope,
1579 context_id context = xcurrent_context, 1579 context_id context = xcurrent_context,
1580 bool defined_only = true) 1580 bool defined_only = true)
1581 { 1581 {
1582 symbol_table *inst = get_instance (scope); 1582 symbol_table *inst = get_instance (scope);
1583 1583
1584 return inst 1584 return inst
1585 ? inst->do_all_variables (context, defined_only) : std::list<symbol_record> (); 1585 ? inst->do_all_variables (context, defined_only) : std::list<symbol_record> ();
1619 std::list<symbol_record> retval; 1619 std::list<symbol_record> retval;
1620 1620
1621 glob_match pat (pattern); 1621 glob_match pat (pattern);
1622 1622
1623 for (global_table_const_iterator p = global_table.begin (); 1623 for (global_table_const_iterator p = global_table.begin ();
1624 p != global_table.end (); p++) 1624 p != global_table.end (); p++)
1625 { 1625 {
1626 // We generate a list of symbol_record objects so that 1626 // We generate a list of symbol_record objects so that
1627 // the results from glob_variables and glob_global_variables 1627 // the results from glob_variables and glob_global_variables
1628 // may be handled the same way. 1628 // may be handled the same way.
1629 1629
1630 if (pat.match (p->first)) 1630 if (pat.match (p->first))
1631 retval.push_back (symbol_record (p->first, p->second, 1631 retval.push_back (symbol_record (p->first, p->second,
1632 symbol_record::global)); 1632 symbol_record::global));
1633 } 1633 }
1634 1634
1635 return retval; 1635 return retval;
1636 } 1636 }
1637 1637
1641 std::list<symbol_record> retval; 1641 std::list<symbol_record> retval;
1642 1642
1643 regex_match pat (pattern); 1643 regex_match pat (pattern);
1644 1644
1645 for (global_table_const_iterator p = global_table.begin (); 1645 for (global_table_const_iterator p = global_table.begin ();
1646 p != global_table.end (); p++) 1646 p != global_table.end (); p++)
1647 { 1647 {
1648 // We generate a list of symbol_record objects so that 1648 // We generate a list of symbol_record objects so that
1649 // the results from regexp_variables and regexp_global_variables 1649 // the results from regexp_variables and regexp_global_variables
1650 // may be handled the same way. 1650 // may be handled the same way.
1651 1651
1652 if (pat.match (p->first)) 1652 if (pat.match (p->first))
1653 retval.push_back (symbol_record (p->first, p->second, 1653 retval.push_back (symbol_record (p->first, p->second,
1654 symbol_record::global)); 1654 symbol_record::global));
1655 } 1655 }
1656 1656
1657 return retval; 1657 return retval;
1658 } 1658 }
1659 1659
1663 1663
1664 size_t len = patterns.length (); 1664 size_t len = patterns.length ();
1665 1665
1666 for (size_t i = 0; i < len; i++) 1666 for (size_t i = 0; i < len; i++)
1667 { 1667 {
1668 std::list<symbol_record> tmp = glob_variables (patterns[i]); 1668 std::list<symbol_record> tmp = glob_variables (patterns[i]);
1669 1669
1670 retval.insert (retval.begin (), tmp.begin (), tmp.end ()); 1670 retval.insert (retval.begin (), tmp.begin (), tmp.end ());
1671 } 1671 }
1672 1672
1673 return retval; 1673 return retval;
1674 } 1674 }
1675 1675
1680 1680
1681 size_t len = patterns.length (); 1681 size_t len = patterns.length ();
1682 1682
1683 for (size_t i = 0; i < len; i++) 1683 for (size_t i = 0; i < len; i++)
1684 { 1684 {
1685 std::list<symbol_record> tmp = regexp_variables (patterns[i]); 1685 std::list<symbol_record> tmp = regexp_variables (patterns[i]);
1686 1686
1687 retval.insert (retval.begin (), tmp.begin (), tmp.end ()); 1687 retval.insert (retval.begin (), tmp.begin (), tmp.end ());
1688 } 1688 }
1689 1689
1690 return retval; 1690 return retval;
1691 } 1691 }
1692 1692
1693 static std::list<std::string> user_function_names (void) 1693 static std::list<std::string> user_function_names (void)
1694 { 1694 {
1695 std::list<std::string> retval; 1695 std::list<std::string> retval;
1696 1696
1697 for (fcn_table_iterator p = fcn_table.begin (); 1697 for (fcn_table_iterator p = fcn_table.begin ();
1698 p != fcn_table.end (); p++) 1698 p != fcn_table.end (); p++)
1699 { 1699 {
1700 if (p->second.is_user_function_defined ()) 1700 if (p->second.is_user_function_defined ())
1701 retval.push_back (p->first); 1701 retval.push_back (p->first);
1702 } 1702 }
1703 1703
1704 if (! retval.empty ()) 1704 if (! retval.empty ())
1705 retval.sort (); 1705 retval.sort ();
1706 1706
1710 static std::list<std::string> global_variable_names (void) 1710 static std::list<std::string> global_variable_names (void)
1711 { 1711 {
1712 std::list<std::string> retval; 1712 std::list<std::string> retval;
1713 1713
1714 for (global_table_const_iterator p = global_table.begin (); 1714 for (global_table_const_iterator p = global_table.begin ();
1715 p != global_table.end (); p++) 1715 p != global_table.end (); p++)
1716 retval.push_back (p->first); 1716 retval.push_back (p->first);
1717 1717
1718 retval.sort (); 1718 retval.sort ();
1719 1719
1720 return retval; 1720 return retval;
1737 static std::list<std::string> built_in_function_names (void) 1737 static std::list<std::string> built_in_function_names (void)
1738 { 1738 {
1739 std::list<std::string> retval; 1739 std::list<std::string> retval;
1740 1740
1741 for (fcn_table_const_iterator p = fcn_table.begin (); 1741 for (fcn_table_const_iterator p = fcn_table.begin ();
1742 p != fcn_table.end (); p++) 1742 p != fcn_table.end (); p++)
1743 { 1743 {
1744 octave_value fcn = p->second.find_built_in_function (); 1744 octave_value fcn = p->second.find_built_in_function ();
1745 1745
1746 if (fcn.is_defined ()) 1746 if (fcn.is_defined ())
1747 retval.push_back (p->first); 1747 retval.push_back (p->first);
1748 } 1748 }
1749 1749
1750 if (! retval.empty ()) 1750 if (! retval.empty ())
1751 retval.sort (); 1751 retval.sort ();
1752 1752
1757 { 1757 {
1758 if (xcurrent_scope == xglobal_scope) 1758 if (xcurrent_scope == xglobal_scope)
1759 return false; 1759 return false;
1760 else 1760 else
1761 { 1761 {
1762 symbol_table *inst = get_instance (xcurrent_scope); 1762 symbol_table *inst = get_instance (xcurrent_scope);
1763 1763
1764 return inst ? inst->do_is_local_variable (name) : false; 1764 return inst ? inst->do_is_local_variable (name) : false;
1765 } 1765 }
1766 } 1766 }
1767 1767
1768 static bool is_global (const std::string& name) 1768 static bool is_global (const std::string& name)
1769 { 1769 {
1770 if (xcurrent_scope == xglobal_scope) 1770 if (xcurrent_scope == xglobal_scope)
1771 return true; 1771 return true;
1772 else 1772 else
1773 { 1773 {
1774 symbol_table *inst = get_instance (xcurrent_scope); 1774 symbol_table *inst = get_instance (xcurrent_scope);
1775 1775
1776 return inst ? inst->do_is_global (name) : false; 1776 return inst ? inst->do_is_global (name) : false;
1777 } 1777 }
1778 } 1778 }
1779 1779
1780 static void dump (std::ostream& os, scope_id scope = xcurrent_scope); 1780 static void dump (std::ostream& os, scope_id scope = xcurrent_scope);
1781 1781
1792 } 1792 }
1793 1793
1794 static void lock_subfunctions (scope_id scope = xcurrent_scope) 1794 static void lock_subfunctions (scope_id scope = xcurrent_scope)
1795 { 1795 {
1796 for (fcn_table_iterator p = fcn_table.begin (); 1796 for (fcn_table_iterator p = fcn_table.begin ();
1797 p != fcn_table.end (); p++) 1797 p != fcn_table.end (); p++)
1798 p->second.lock_subfunction (scope); 1798 p->second.lock_subfunction (scope);
1799 } 1799 }
1800 1800
1801 static void unlock_subfunctions (scope_id scope = xcurrent_scope) 1801 static void unlock_subfunctions (scope_id scope = xcurrent_scope)
1802 { 1802 {
1803 for (fcn_table_iterator p = fcn_table.begin (); 1803 for (fcn_table_iterator p = fcn_table.begin ();
1804 p != fcn_table.end (); p++) 1804 p != fcn_table.end (); p++)
1805 p->second.unlock_subfunction (scope); 1805 p->second.unlock_subfunction (scope);
1806 } 1806 }
1807 1807
1808 static void free_scope (scope_id scope) 1808 static void free_scope (scope_id scope)
1809 { 1809 {
1812 else 1812 else
1813 symbol_table::scope_id_cache::free (scope); 1813 symbol_table::scope_id_cache::free (scope);
1814 } 1814 }
1815 1815
1816 static void stash_dir_name_for_subfunctions (scope_id scope, 1816 static void stash_dir_name_for_subfunctions (scope_id scope,
1817 const std::string& dir_name); 1817 const std::string& dir_name);
1818 1818
1819 static void add_to_parent_map (const std::string& classname, 1819 static void add_to_parent_map (const std::string& classname,
1820 const std::list<std::string>& parent_list) 1820 const std::list<std::string>& parent_list)
1821 { 1821 {
1822 parent_map[classname] = parent_list; 1822 parent_map[classname] = parent_list;
1823 } 1823 }
1824 1824
1825 static octave_user_function *get_curr_fcn (scope_id scope = xcurrent_scope) 1825 static octave_user_function *get_curr_fcn (scope_id scope = xcurrent_scope)
1916 1916
1917 bool ok = true; 1917 bool ok = true;
1918 1918
1919 if (scope != xglobal_scope) 1919 if (scope != xglobal_scope)
1920 { 1920 {
1921 if (scope == xcurrent_scope) 1921 if (scope == xcurrent_scope)
1922 { 1922 {
1923 if (! instance && create) 1923 if (! instance && create)
1924 { 1924 {
1925 symbol_table *inst = new symbol_table (); 1925 symbol_table *inst = new symbol_table ();
1926 1926
1927 if (inst) 1927 if (inst)
1928 { 1928 {
1929 all_instances[scope] = instance = inst; 1929 all_instances[scope] = instance = inst;
1930 1930
1931 if (scope == xtop_scope) 1931 if (scope == xtop_scope)
1932 instance->do_cache_name ("top-level"); 1932 instance->do_cache_name ("top-level");
1933 } 1933 }
1934 } 1934 }
1935 1935
1936 if (! instance) 1936 if (! instance)
1937 ok = false; 1937 ok = false;
1938 1938
1939 retval = instance; 1939 retval = instance;
1940 } 1940 }
1941 else 1941 else
1942 { 1942 {
1943 all_instances_iterator p = all_instances.find (scope); 1943 all_instances_iterator p = all_instances.find (scope);
1944 1944
1945 if (p == all_instances.end ()) 1945 if (p == all_instances.end ())
1946 { 1946 {
1947 if (create) 1947 if (create)
1948 { 1948 {
1949 retval = new symbol_table (); 1949 retval = new symbol_table ();
1950 1950
1951 if (retval) 1951 if (retval)
1952 all_instances[scope] = retval; 1952 all_instances[scope] = retval;
1953 else 1953 else
1954 ok = false; 1954 ok = false;
1955 } 1955 }
1956 else 1956 else
1957 ok = false; 1957 ok = false;
1958 } 1958 }
1959 else 1959 else
1960 retval = p->second; 1960 retval = p->second;
1961 } 1961 }
1962 } 1962 }
1963 1963
1964 if (! ok) 1964 if (! ok)
1965 error ("unable to %s symbol_table object for scope %d!", 1965 error ("unable to %s symbol_table object for scope %d!",
1966 create ? "create" : "find", scope); 1966 create ? "create" : "find", scope);
1967 1967
1968 return retval; 1968 return retval;
1969 } 1969 }
1970 1970
1971 void insert_symbol_record (const symbol_record& sr) 1971 void insert_symbol_record (const symbol_record& sr)
1992 1992
1993 void do_inherit (symbol_table& donor_table, context_id donor_context) 1993 void do_inherit (symbol_table& donor_table, context_id donor_context)
1994 { 1994 {
1995 for (table_iterator p = table.begin (); p != table.end (); p++) 1995 for (table_iterator p = table.begin (); p != table.end (); p++)
1996 { 1996 {
1997 symbol_record& sr = p->second; 1997 symbol_record& sr = p->second;
1998 1998
1999 if (! (sr.is_automatic () || sr.is_formal ())) 1999 if (! (sr.is_automatic () || sr.is_formal ()))
2000 { 2000 {
2001 std::string nm = sr.name (); 2001 std::string nm = sr.name ();
2002 2002
2003 if (nm != "__retval__") 2003 if (nm != "__retval__")
2004 { 2004 {
2005 octave_value val = donor_table.do_varval (nm, donor_context); 2005 octave_value val = donor_table.do_varval (nm, donor_context);
2006 2006
2007 if (val.is_defined ()) 2007 if (val.is_defined ())
2008 { 2008 {
2009 sr.varref (0) = val; 2009 sr.varref (0) = val;
2010 2010
2011 sr.mark_inherited (); 2011 sr.mark_inherited ();
2012 } 2012 }
2013 } 2013 }
2014 } 2014 }
2015 } 2015 }
2016 } 2016 }
2017 2017
2018 static fcn_info *get_fcn_info (const std::string& name) 2018 static fcn_info *get_fcn_info (const std::string& name)
2019 { 2019 {
2039 { 2039 {
2040 table_iterator p = table.find (name); 2040 table_iterator p = table.find (name);
2041 2041
2042 if (p == table.end ()) 2042 if (p == table.end ())
2043 { 2043 {
2044 symbol_record& sr = do_insert (name); 2044 symbol_record& sr = do_insert (name);
2045 2045
2046 sr.force_variable (context); 2046 sr.force_variable (context);
2047 } 2047 }
2048 else 2048 else
2049 p->second.force_variable (context); 2049 p->second.force_variable (context);
2050 } 2050 }
2051 2051
2053 { 2053 {
2054 table_iterator p = table.find (name); 2054 table_iterator p = table.find (name);
2055 2055
2056 if (p == table.end ()) 2056 if (p == table.end ())
2057 { 2057 {
2058 symbol_record& sr = do_insert (name); 2058 symbol_record& sr = do_insert (name);
2059 2059
2060 return sr.varref (context); 2060 return sr.varref (context);
2061 } 2061 }
2062 else 2062 else
2063 return p->second.varref (context); 2063 return p->second.varref (context);
2064 } 2064 }
2065 2065
2099 2099
2100 table_const_iterator p = table.find (name); 2100 table_const_iterator p = table.find (name);
2101 2101
2102 if (p != table.end ()) 2102 if (p != table.end ())
2103 { 2103 {
2104 const symbol_record& sr = p->second; 2104 const symbol_record& sr = p->second;
2105 2105
2106 retval = sr.is_variable (); 2106 retval = sr.is_variable ();
2107 } 2107 }
2108 2108
2109 return retval; 2109 return retval;
2110 } 2110 }
2111 2111
2117 2117
2118 void do_pop_context (void) 2118 void do_pop_context (void)
2119 { 2119 {
2120 for (table_iterator p = table.begin (); p != table.end (); ) 2120 for (table_iterator p = table.begin (); p != table.end (); )
2121 { 2121 {
2122 if (p->second.pop_context () == 0) 2122 if (p->second.pop_context () == 0)
2123 table.erase (p++); 2123 table.erase (p++);
2124 else 2124 else
2125 p++; 2125 p++;
2126 } 2126 }
2127 } 2127 }
2128 2128
2129 void do_clear_variables (void) 2129 void do_clear_variables (void)
2130 { 2130 {
2134 2134
2135 void do_clear_objects (void) 2135 void do_clear_objects (void)
2136 { 2136 {
2137 for (table_iterator p = table.begin (); p != table.end (); p++) 2137 for (table_iterator p = table.begin (); p != table.end (); p++)
2138 { 2138 {
2139 symbol_record& sr = p->second; 2139 symbol_record& sr = p->second;
2140 octave_value& val = sr.varref (); 2140 octave_value& val = sr.varref ();
2141 if (val.is_object()) 2141 if (val.is_object())
2142 p->second.clear (); 2142 p->second.clear ();
2143 } 2143 }
2144 } 2144 }
2145 2145
2146 void do_unmark_forced_variables (void) 2146 void do_unmark_forced_variables (void)
2147 { 2147 {
2153 { 2153 {
2154 table_iterator p = table.find (name); 2154 table_iterator p = table.find (name);
2155 2155
2156 if (p != table.end ()) 2156 if (p != table.end ())
2157 { 2157 {
2158 symbol_record& sr = p->second; 2158 symbol_record& sr = p->second;
2159 2159
2160 if (sr.is_global ()) 2160 if (sr.is_global ())
2161 sr.unmark_global (); 2161 sr.unmark_global ();
2162 } 2162 }
2163 2163
2164 global_table_iterator q = global_table.find (name); 2164 global_table_iterator q = global_table.find (name);
2165 2165
2180 { 2180 {
2181 glob_match pattern (pat); 2181 glob_match pattern (pat);
2182 2182
2183 for (table_iterator p = table.begin (); p != table.end (); p++) 2183 for (table_iterator p = table.begin (); p != table.end (); p++)
2184 { 2184 {
2185 symbol_record& sr = p->second; 2185 symbol_record& sr = p->second;
2186 2186
2187 if (sr.is_global () && pattern.match (sr.name ())) 2187 if (sr.is_global () && pattern.match (sr.name ()))
2188 sr.unmark_global (); 2188 sr.unmark_global ();
2189 } 2189 }
2190 2190
2191 for (global_table_iterator q = global_table.begin (); 2191 for (global_table_iterator q = global_table.begin ();
2192 q != global_table.end (); q++) 2192 q != global_table.end (); q++)
2193 { 2193 {
2194 if (pattern.match (q->first)) 2194 if (pattern.match (q->first))
2195 global_table.erase (q); 2195 global_table.erase (q);
2196 } 2196 }
2197 2197
2198 2198
2199 } 2199 }
2202 { 2202 {
2203 glob_match pattern (pat); 2203 glob_match pattern (pat);
2204 2204
2205 for (table_iterator p = table.begin (); p != table.end (); p++) 2205 for (table_iterator p = table.begin (); p != table.end (); p++)
2206 { 2206 {
2207 symbol_record& sr = p->second; 2207 symbol_record& sr = p->second;
2208 2208
2209 if (sr.is_defined () || sr.is_global ()) 2209 if (sr.is_defined () || sr.is_global ())
2210 { 2210 {
2211 if (pattern.match (sr.name ())) 2211 if (pattern.match (sr.name ()))
2212 sr.clear (); 2212 sr.clear ();
2213 } 2213 }
2214 } 2214 }
2215 } 2215 }
2216 2216
2217 void do_clear_variable_regexp (const std::string& pat) 2217 void do_clear_variable_regexp (const std::string& pat)
2218 { 2218 {
2219 regex_match pattern (pat); 2219 regex_match pattern (pat);
2220 2220
2221 for (table_iterator p = table.begin (); p != table.end (); p++) 2221 for (table_iterator p = table.begin (); p != table.end (); p++)
2222 { 2222 {
2223 symbol_record& sr = p->second; 2223 symbol_record& sr = p->second;
2224 2224
2225 if (sr.is_defined () || sr.is_global ()) 2225 if (sr.is_defined () || sr.is_global ())
2226 { 2226 {
2227 if (pattern.match (sr.name ())) 2227 if (pattern.match (sr.name ()))
2228 sr.clear (); 2228 sr.clear ();
2229 } 2229 }
2230 } 2230 }
2231 } 2231 }
2232 2232
2233 void do_mark_hidden (const std::string& name) 2233 void do_mark_hidden (const std::string& name)
2234 { 2234 {
2251 { 2251 {
2252 std::list<symbol_record> retval; 2252 std::list<symbol_record> retval;
2253 2253
2254 for (table_const_iterator p = table.begin (); p != table.end (); p++) 2254 for (table_const_iterator p = table.begin (); p != table.end (); p++)
2255 { 2255 {
2256 const symbol_record& sr = p->second; 2256 const symbol_record& sr = p->second;
2257 2257
2258 if (defined_only && ! sr.is_defined (context)) 2258 if (defined_only && ! sr.is_defined (context))
2259 continue; 2259 continue;
2260 2260
2261 retval.push_back (sr); 2261 retval.push_back (sr);
2262 } 2262 }
2263 2263
2264 return retval; 2264 return retval;
2265 } 2265 }
2266 2266
2267 std::list<symbol_record> do_glob (const std::string& pattern, 2267 std::list<symbol_record> do_glob (const std::string& pattern,
2268 bool vars_only = false) const 2268 bool vars_only = false) const
2269 { 2269 {
2270 std::list<symbol_record> retval; 2270 std::list<symbol_record> retval;
2271 2271
2272 glob_match pat (pattern); 2272 glob_match pat (pattern);
2273 2273
2274 for (table_const_iterator p = table.begin (); p != table.end (); p++) 2274 for (table_const_iterator p = table.begin (); p != table.end (); p++)
2275 { 2275 {
2276 if (pat.match (p->first)) 2276 if (pat.match (p->first))
2277 { 2277 {
2278 const symbol_record& sr = p->second; 2278 const symbol_record& sr = p->second;
2279 2279
2280 if (vars_only && ! sr.is_variable ()) 2280 if (vars_only && ! sr.is_variable ())
2281 continue; 2281 continue;
2282 2282
2283 retval.push_back (sr); 2283 retval.push_back (sr);
2284 } 2284 }
2285 } 2285 }
2286 2286
2287 return retval; 2287 return retval;
2288 } 2288 }
2289 2289
2290 std::list<symbol_record> do_regexp (const std::string& pattern, 2290 std::list<symbol_record> do_regexp (const std::string& pattern,
2291 bool vars_only = false) const 2291 bool vars_only = false) const
2292 { 2292 {
2293 std::list<symbol_record> retval; 2293 std::list<symbol_record> retval;
2294 2294
2295 regex_match pat (pattern); 2295 regex_match pat (pattern);
2296 2296
2297 for (table_const_iterator p = table.begin (); p != table.end (); p++) 2297 for (table_const_iterator p = table.begin (); p != table.end (); p++)
2298 { 2298 {
2299 if (pat.match (p->first)) 2299 if (pat.match (p->first))
2300 { 2300 {
2301 const symbol_record& sr = p->second; 2301 const symbol_record& sr = p->second;
2302 2302
2303 if (vars_only && ! sr.is_variable ()) 2303 if (vars_only && ! sr.is_variable ())
2304 continue; 2304 continue;
2305 2305
2306 retval.push_back (sr); 2306 retval.push_back (sr);
2307 } 2307 }
2308 } 2308 }
2309 2309
2310 return retval; 2310 return retval;
2311 } 2311 }
2312 2312
2314 { 2314 {
2315 std::list<std::string> retval; 2315 std::list<std::string> retval;
2316 2316
2317 for (table_const_iterator p = table.begin (); p != table.end (); p++) 2317 for (table_const_iterator p = table.begin (); p != table.end (); p++)
2318 { 2318 {
2319 if (p->second.is_variable ()) 2319 if (p->second.is_variable ())
2320 retval.push_back (p->first); 2320 retval.push_back (p->first);
2321 } 2321 }
2322 2322
2323 retval.sort (); 2323 retval.sort ();
2324 2324
2325 return retval; 2325 return retval;
2329 subfunctions_defined_in_scope (scope_id scope = xcurrent_scope) 2329 subfunctions_defined_in_scope (scope_id scope = xcurrent_scope)
2330 { 2330 {
2331 std::map<std::string, octave_value> retval; 2331 std::map<std::string, octave_value> retval;
2332 2332
2333 for (fcn_table_const_iterator p = fcn_table.begin (); 2333 for (fcn_table_const_iterator p = fcn_table.begin ();
2334 p != fcn_table.end (); p++) 2334 p != fcn_table.end (); p++)
2335 { 2335 {
2336 std::pair<std::string, octave_value> tmp 2336 std::pair<std::string, octave_value> tmp
2337 = p->second.subfunction_defined_in_scope (scope); 2337 = p->second.subfunction_defined_in_scope (scope);
2338 2338
2339 std::string nm = tmp.first; 2339 std::string nm = tmp.first;
2340 2340
2341 if (! nm.empty ()) 2341 if (! nm.empty ())
2342 retval[nm] = tmp.second; 2342 retval[nm] = tmp.second;
2343 } 2343 }
2344 2344
2345 return retval; 2345 return retval;
2346 } 2346 }
2347 2347
2348 bool do_is_local_variable (const std::string& name) const 2348 bool do_is_local_variable (const std::string& name) const
2349 { 2349 {
2350 table_const_iterator p = table.find (name); 2350 table_const_iterator p = table.find (name);
2351 2351
2352 return (p != table.end () 2352 return (p != table.end ()
2353 && ! p->second.is_global () 2353 && ! p->second.is_global ()
2354 && p->second.is_defined ()); 2354 && p->second.is_defined ());
2355 } 2355 }
2356 2356
2357 bool do_is_global (const std::string& name) const 2357 bool do_is_global (const std::string& name) const
2358 { 2358 {
2359 table_const_iterator p = table.find (name); 2359 table_const_iterator p = table.find (name);