Mercurial > hg > octave-avbm
comparison src/symtab.cc @ 7972:5bf4e2c13ed8
make superiorto and inferiorto work
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 25 Jul 2008 14:25:35 -0400 |
parents | 0d607e8dbbfa |
children | a2ab20ba78f7 |
comparison
equal
deleted
inserted
replaced
7971:dd5cc5016487 | 7972:5bf4e2c13ed8 |
---|---|
50 std::map<symbol_table::scope_id, symbol_table*> symbol_table::all_instances; | 50 std::map<symbol_table::scope_id, symbol_table*> symbol_table::all_instances; |
51 | 51 |
52 std::map<std::string, octave_value> symbol_table::global_table; | 52 std::map<std::string, octave_value> symbol_table::global_table; |
53 | 53 |
54 std::map<std::string, symbol_table::fcn_info> symbol_table::fcn_table; | 54 std::map<std::string, symbol_table::fcn_info> symbol_table::fcn_table; |
55 | |
56 std::map<std::string, std::set<std::string> > symbol_table::class_precedence_table; | |
55 | 57 |
56 const symbol_table::scope_id symbol_table::xglobal_scope = 0; | 58 const symbol_table::scope_id symbol_table::xglobal_scope = 0; |
57 const symbol_table::scope_id symbol_table::xtop_scope = 1; | 59 const symbol_table::scope_id symbol_table::xtop_scope = 1; |
58 | 60 |
59 symbol_table::scope_id symbol_table::xcurrent_scope = 1; | 61 symbol_table::scope_id symbol_table::xcurrent_scope = 1; |
355 p != dispatch_map.end (); p++) | 357 p != dispatch_map.end (); p++) |
356 retval += " " + p->second + " (" + p->first + ", ...)\n\n"; | 358 retval += " " + p->second + " (" + p->first + ", ...)\n\n"; |
357 } | 359 } |
358 | 360 |
359 return retval; | 361 return retval; |
362 } | |
363 | |
364 static std::string | |
365 get_dispatch_type (const octave_value_list& evaluated_args) | |
366 { | |
367 std::string dispatch_type; | |
368 | |
369 int n = evaluated_args.length (); | |
370 | |
371 if (n > 0) | |
372 { | |
373 // Find first object, if any. | |
374 | |
375 int i; | |
376 | |
377 for (i = 0; i < n; i++) | |
378 { | |
379 octave_value arg = evaluated_args(i); | |
380 | |
381 if (arg.is_object ()) | |
382 { | |
383 dispatch_type = arg.class_name (); | |
384 break; | |
385 } | |
386 } | |
387 | |
388 for (int j = i+1; j < n; j++) | |
389 { | |
390 octave_value arg = evaluated_args(j); | |
391 | |
392 if (arg.is_object ()) | |
393 { | |
394 std::string cname = arg.class_name (); | |
395 | |
396 // Only switch to type of ARG if it is marked superior | |
397 // to the current DISPATCH_TYPE. | |
398 if (! symbol_table::is_superiorto (dispatch_type, cname) | |
399 && symbol_table::is_superiorto (cname, dispatch_type)) | |
400 dispatch_type = cname; | |
401 } | |
402 } | |
403 | |
404 if (dispatch_type.empty ()) | |
405 { | |
406 // No object found, so use class of first argument. | |
407 | |
408 dispatch_type = evaluated_args(0).class_name (); | |
409 } | |
410 } | |
411 | |
412 return dispatch_type; | |
360 } | 413 } |
361 | 414 |
362 // Find the definition of NAME according to the following precedence | 415 // Find the definition of NAME according to the following precedence |
363 // list: | 416 // list: |
364 // | 417 // |
517 if (n > 0 && ! args_evaluated) | 570 if (n > 0 && ! args_evaluated) |
518 evaluated_args.stash_name_tags (arg_names); | 571 evaluated_args.stash_name_tags (arg_names); |
519 | 572 |
520 args_evaluated = true; | 573 args_evaluated = true; |
521 | 574 |
522 // FIXME -- need to handle precedence. | 575 if (n > 0) |
523 | |
524 std::string dispatch_type = evaluated_args(0).class_name (); | |
525 | |
526 for (int i = 1; i < n; i++) | |
527 { | 576 { |
528 octave_value arg = evaluated_args(i); | 577 std::string dispatch_type = get_dispatch_type (evaluated_args); |
529 | 578 |
530 if (arg.is_object ()) | 579 octave_value fcn = find_method (dispatch_type); |
531 { | 580 |
532 dispatch_type = arg.class_name (); | 581 if (fcn.is_defined ()) |
533 break; | 582 return fcn; |
534 } | |
535 } | 583 } |
536 | |
537 octave_value fcn = find_method (dispatch_type); | |
538 | |
539 if (fcn.is_defined ()) | |
540 return fcn; | |
541 } | 584 } |
542 else | 585 else |
543 return octave_value (); | 586 return octave_value (); |
544 } | 587 } |
545 | 588 |
702 function_on_path = octave_value (fcn); | 745 function_on_path = octave_value (fcn); |
703 } | 746 } |
704 } | 747 } |
705 | 748 |
706 return function_on_path; | 749 return function_on_path; |
750 } | |
751 | |
752 // Insert INF_CLASS in the set of class names that are considered | |
753 // inferior to SUP_CLASS. Return FALSE if INF_CLASS is currently | |
754 // marked as superior to SUP_CLASS. | |
755 | |
756 bool | |
757 symbol_table::set_class_relationship (const std::string& sup_class, | |
758 const std::string& inf_class) | |
759 { | |
760 class_precedence_table_const_iterator p | |
761 = class_precedence_table.find (inf_class); | |
762 | |
763 if (p != class_precedence_table.end ()) | |
764 { | |
765 const std::set<std::string>& inferior_classes = p->second; | |
766 | |
767 std::set<std::string>::const_iterator q | |
768 = inferior_classes.find (sup_class); | |
769 | |
770 if (q != inferior_classes.end ()) | |
771 return false; | |
772 } | |
773 | |
774 class_precedence_table[sup_class].insert (inf_class); | |
775 | |
776 return true; | |
777 } | |
778 | |
779 // Has class A been marked as superior to class B? Also returns | |
780 // TRUE if B has been marked as inferior to A, since we only keep | |
781 // one table, and convert inferiort information to a superiorto | |
782 // relationship. Two calls are required to determine whether there | |
783 // is no relationship between two classes: | |
784 // | |
785 // if (symbol_table::is_superiorto (a, b)) | |
786 // // A is superior to B, or B has been marked inferior to A. | |
787 // else if (symbol_table::is_superiorto (b, a)) | |
788 // // B is superior to A, or A has been marked inferior to B. | |
789 // else | |
790 // // No relation. | |
791 | |
792 bool | |
793 symbol_table::is_superiorto (const std::string& a, const std::string& b) | |
794 { | |
795 bool retval = false; | |
796 | |
797 class_precedence_table_const_iterator p = class_precedence_table.find (a); | |
798 | |
799 if (p != class_precedence_table.end ()) | |
800 { | |
801 const std::set<std::string>& inferior_classes = p->second; | |
802 std::set<std::string>::const_iterator q = inferior_classes.find (b); | |
803 | |
804 if (q != inferior_classes.end ()) | |
805 retval = true; | |
806 } | |
807 | |
808 return retval; | |
707 } | 809 } |
708 | 810 |
709 static std::string | 811 static std::string |
710 fcn_file_name (const octave_value& fcn) | 812 fcn_file_name (const octave_value& fcn) |
711 { | 813 { |