home *** CD-ROM | disk | FTP | other *** search
/ ftptest.leeds.ac.uk / 2015.02.ftptest.leeds.ac.uk.tar / ftptest.leeds.ac.uk / bionet / CAE-GROUP / SCL-WIN3x / FED_PLUS.EXE / SCOPE.C < prev    next >
C/C++ Source or Header  |  1994-07-23  |  12KB  |  463 lines

  1. static char rcsid[] = "$Id: scope.c,v 1.6 1993/10/15 18:48:48 libes Exp $";
  2.  
  3. /************************************************************************
  4. ** Module:    Scope
  5. ** Description:    This module implements a hierarchical (i.e., scoped)
  6. **    symbol table.  The symbol table can store definitions of entities,
  7. **    types, algorithms, and variables, as well as containing a list
  8. **    of subscopes.
  9. ** Constants:
  10. **    SCOPE_NULL    - the null scope
  11. **
  12. ************************************************************************/
  13.  
  14. /*
  15.  * This software was developed by U.S. Government employees as part of
  16.  * their official duties and is not subject to copyright.
  17.  *
  18.  * $Log: scope.c,v $
  19.  * Revision 1.6  1993/10/15  18:48:48  libes
  20.  * CADDETC certified
  21.  *
  22.  * Revision 1.5  1993/01/19  22:16:43  libes
  23.  * *** empty log message ***
  24.  *
  25.  * Revision 1.4  1992/08/18  17:13:43  libes
  26.  * rm'd extraneous error messages
  27.  *
  28.  * Revision 1.3  1992/06/08  18:06:57  libes
  29.  * prettied up interface to print_objects_when_running
  30.  */
  31.  
  32. #define SCOPE_C
  33. #include "scope.h"
  34. #include "resolve.h"
  35.  
  36. Symbol *
  37. SCOPE_get_symbol(Generic s)
  38. {
  39.     return(&((Scope)s)->symbol);
  40. }
  41.  
  42. void
  43. SCOPEinitialize(void)
  44. {
  45.     OBJcreate(OBJ_SCHEMA,SCOPE_get_symbol,"schema",OBJ_SCHEMA_BITS);
  46.     MEMinitialize(&SCOPE_fl,sizeof(struct Scope),100,50);
  47. }
  48.  
  49. /*
  50. ** Procedure:    SCOPEget_entities
  51. ** Parameters:    Scope       scope    - scope to examine
  52. ** Returns:    Linked_List of Entity    - entities defined locally
  53. ** Description:    Retrieve a list of the entities defined locally in a scope.
  54. **
  55. ** Notes:    This function is considerably faster than
  56. **    SCOPEget_entities_superclass_order(), and should be used whenever
  57. **    the order of the entities on the list is not important.
  58. */
  59.  
  60. void
  61. SCOPE_get_entities(Scope scope,Linked_List result)
  62. {
  63.     DictionaryEntry de;
  64.     Generic x;
  65.  
  66.     DICTdo_type_init(scope->symbol_table,&de,OBJ_ENTITY);
  67.     while (0 != (x = DICTdo(&de))) {
  68.         LISTadd_last(result,x);
  69.     }
  70. }
  71.  
  72. Linked_List
  73. SCOPEget_entities(Scope scope)
  74. {
  75.     Linked_List result = LISTcreate();
  76.     SCOPE_get_entities(scope,result);
  77.     return(result);
  78. }
  79.  
  80. /*
  81. ** Procedure:    SCOPEget_entities_superclass_order
  82. ** Parameters:    Scope       scope    - scope to examine
  83. ** Returns:    Linked_List of Entity    - entities defined locally
  84. ** Description:    Retrieve a list of the entities defined locally in a scope.
  85. **
  86. ** Notes:    The list returned is ordered such that an entity appears
  87. **    before all of its subtypes.
  88. */
  89.  
  90. void
  91. SCOPE_dfs(Dictionary symbols, Entity root, Linked_List result)
  92. {
  93.     Entity ent;
  94.  
  95.     if ((ENTITYget_mark(root) != ENTITY_MARK)) {
  96.     ENTITYput_mark(root, ENTITY_MARK);
  97.     LISTdo(ENTITYget_supertypes(root), super, Entity)
  98.         /* if super explicitly defined in scope, recurse. */
  99.         /* this chops out USEd and REFd entities */
  100.         if ((ent = (Entity)DICTlookup(symbols, ENTITYget_name(super))) != ENTITY_NULL)
  101.             SCOPE_dfs(symbols, ent, result);
  102.     LISTod
  103.     LISTadd_last(result, (Generic)root);
  104.     }
  105. }
  106.  
  107. Linked_List
  108. SCOPEget_entities_superclass_order(Scope scope)
  109. {
  110.     Linked_List result;
  111.     DictionaryEntry    de;
  112.  
  113.     result = LISTcreate();
  114.     ++ENTITY_MARK;
  115.     SCOPEdo_entities(scope,e,de)
  116.         SCOPE_dfs(scope->symbol_table, e, result);
  117.     SCOPEod;
  118.     return result;
  119. }
  120.  
  121. #if 0
  122.  
  123. /*
  124. ** Procedure:    SCOPEget_types
  125. ** Parameters:    Scope       scope    - scope to examine
  126. ** Returns:    Linked_List of Typedef    - local type definitions
  127. ** Description:    Retrieve a list of the types defined locally in a scope.
  128. */
  129.  
  130. Linked_List
  131. SCOPEget_types(Scope scope)
  132. {
  133.     struct Scope*    data;
  134.     Linked_List        list;
  135.     Error        errc;
  136.     Symbol s;
  137.     DictionaryEntry    de;
  138.  
  139.     list = OBJcreate(Class_Linked_List, &errc);
  140.     DICTdo_init(scope->symbol_table,&de);
  141.     while (s = DICTdo(&de)) {
  142.     if (OBJis_kind_of(s, Class_Type))
  143.         LISTadd_last(list, (Generic)s);
  144.     }
  145.     return list;
  146. }
  147.  
  148. /*
  149. ** Procedure:    SCOPEget_variables
  150. ** Parameters:    Scope       scope    - scope to examine
  151. ** Returns:    Linked_List of Variable    - variables defined locally
  152. ** Description:    Retrieve a list of the variables defined locally in a scope.
  153. */
  154.  
  155. Linked_List
  156. SCOPEget_variables(Scope scope)
  157. {
  158.     struct Scope*    data;
  159.     Linked_List        list;
  160.     Error        errc;
  161.     Symbol s;
  162.     DictionaryEntry    de;
  163.  
  164.     list = OBJcreate(Class_Linked_List, &errc);
  165.     data = (struct Scope*)OBJget_data(scope, Class_Scope, &errc);
  166.     DICTdo_init(data->symbol_table,&de);
  167.     while (s = DICTdo(&de)) {
  168.     if (OBJis_kind_of(s, Class_Variable))
  169.         LISTadd_last(list, (Generic)s);
  170.     }
  171.     return list;
  172. }
  173.  
  174. /*
  175. ** Procedure:    SCOPEget_algorithms
  176. ** Parameters:    Scope       scope        - scope to examine
  177. ** Returns:    Linked_List of Algorithm    - algorithms defined locally
  178. ** Description:    Retrieve a list of the algorithms defined locally in a scope.
  179. */
  180.  
  181. Linked_List
  182. SCOPEget_algorithms(Scope scope)
  183. {
  184.     struct Scope*    data;
  185.     Linked_List        list;
  186.     Error        errc;
  187.     Symbol s;
  188.     DictionaryEntry    de;
  189.  
  190.     list = OBJcreate(Class_Linked_List, &errc);
  191.     data = (struct Scope*)OBJget_data(scope, Class_Scope, &errc);
  192.     DICTdo_init(data->symbol_table,&de);
  193.     while (s = DICTdo(&de)) {
  194.     if (OBJis_kind_of(s, Class_Algorithm))
  195.         LISTadd_last(list, (Generic)s);
  196.     }
  197.     return list;
  198. }
  199.  
  200. /*
  201. ** Procedure:    SCOPEget_constants
  202. ** Parameters:    Scope       scope    - scope to examine
  203. ** Returns:    Linked_List of Constant    - constants defined locally
  204. ** Description:    Retrieve a list of the constants defined locally in a scope.
  205. */
  206.  
  207. Linked_List
  208. SCOPEget_constants(Scope scope)
  209. {
  210.     struct Scope*    data;
  211.     Linked_List        list;
  212.     Error        errc;
  213.     Symbol s;
  214.     DictionaryEntry    de;
  215.  
  216.     list = OBJcreate(Class_Linked_List, &errc);
  217.     data = (struct Scope*)OBJget_data(scope, Class_Scope, &errc);
  218.     DICTdo_init(data->symbol_table,&de);
  219.     while (s = DICTdo(&de)) {
  220.     if (OBJis_kind_of(s, Class_Constant))
  221.         LISTadd_last(list, (Generic)s);
  222.     }
  223.     return list;
  224. }
  225.  
  226. /*
  227. ** Procedure:   SCOPEget_references
  228. ** Parameters:  Scope       scope                       - scope to examine
  229. ** Returns:     Dictionary of Symbols REFERENCE'd by a schema
  230. ** Description: Retrieve a Dictionary of Symbols REFERENCE'd by a schema
  231. */
  232.  
  233. Dictionary
  234. SCOPEget_references(Scope scope)
  235. {
  236.     struct Scope*       data;
  237.     Error               errc;
  238.  
  239.     data = (struct Scope*)OBJget_data(scope, Class_Scope, &errc);
  240.     return OBJcopy(data->references, &errc);
  241. }
  242.  
  243. /*
  244. ** Procedure:    SCOPEput_resolved
  245. ** Parameters:    Scope scope    - scope to modify
  246. ** Returns:    void
  247. ** Description:    Set the 'resolved' flag for a scope.
  248. **
  249. ** Notes:    This should be called only when the scope has indeed
  250. **        been resolved.
  251. */
  252.  
  253. void
  254. SCOPEput_resolved(Scope scope)
  255. {
  256.     struct Scope*    data;
  257.     Error        errc;
  258.  
  259.     data = (struct Scope*)OBJget_data(scope, Class_Scope, &errc);
  260.     data->resolved = true;
  261. }
  262.  
  263. /*
  264. ** Procedure:    SCOPEget_resolved
  265. ** Parameters:    Scope scope    - scope to examine
  266. ** Returns:    Boolean        - has scope been resolved?
  267. ** Description:    Checks whether references within a scope have been resolved.
  268. */
  269.  
  270. Boolean
  271. SCOPEget_resolved(Scope scope)
  272. {
  273.     struct Scope*    data;
  274.     Error        errc;
  275.  
  276.     data = (struct Scope*)OBJget_data(scope, Class_Scope, &errc);
  277.     return data->resolved;
  278. }
  279.  
  280. /*
  281. ** Procedure:    SCOPEdump
  282. ** Parameters:    Scope scope    - scope to dump
  283. **        FILE* file    - file stream to dump to
  284. ** Returns:    void
  285. ** Description:    Dump a schema to a file.
  286. **
  287. ** Notes:    This function is provided for debugging purposes.
  288. */
  289.  
  290. void
  291. SCOPEdump(Scope scope, FILE* file)
  292. {
  293.     Dictionary    dict;
  294.     Linked_List    list, exp_list,ref;
  295.     Error    errc;
  296.     Symbol s;
  297.     DictionaryEntry    de;
  298.  
  299.     fprintf(file, "definitions:\n");
  300.     dict = ((struct Scope*)OBJget_data(scope, Class_Scope, &errc))->symbol_table;
  301.     DICTdo_init(dict,&de);
  302.     while (s = DICTdo(&de)) {
  303.     fprintf(file, "%s %s\n", SYMBOLget_name(s), CLASSget_name(OBJget_class(s)));
  304.     }
  305.  
  306.     fprintf(file, "Used symbols:\n");
  307.     list = ((struct Scope*)OBJget_data(scope, Class_Scope, &errc))->use;
  308.     LISTdo(list, use, Linked_List)
  309.     fprintf(file, "From schema %s\n", SYMBOLget_name(LISTget_first(use)));
  310.         exp_list = LISTget_second(use);
  311.         LISTdo(exp_list,exp, Expression);
  312.             fprintf(file, "   %s AS %s\n",
  313.                     SYMBOLget_name((Symbol)BIN_EXPget_first_operand(exp)),
  314.                     SYMBOLget_name(BIN_EXPget_second_operand(exp)));
  315.         LISTod; /* exp */
  316.     LISTod; 
  317.  
  318.     fprintf(file, "References:\n");
  319.     dict = ((struct Scope*)OBJget_data(scope, Class_Scope, &errc))->references;
  320.     DICTdo_init(dict,&de);
  321.     while (ref = DICTdo(&de)) {
  322.     fprintf(file, "From schema %s\n", SYMBOLget_name(LISTget_first(ref)));
  323.         exp_list = LISTget_second(ref);
  324.         LISTdo(exp_list,exp, Expression);
  325.             fprintf(file, "   %s AS %s\n",
  326.                     SYMBOLget_name((Symbol)BIN_EXPget_first_operand(exp)),
  327.                     SYMBOLget_name(BIN_EXPget_second_operand(exp)));
  328.         LISTod; /* exp */ 
  329.     }; /* while */
  330.  
  331. /* N14 Nested schemas are obsolete 
  332.     list = SCOPEget_schemata(scope);
  333.     LISTdo(list, s, Schema)
  334.     SCHEMAdump(s, file);
  335.     LISTod;
  336.     OBJfree(list, &errc); */
  337.  
  338. }
  339. /*
  340. ** Procedure:    SCOPE_get_ref_name
  341. ** Parameters:    Linked_List ref_entry    - Reference dictionary entry
  342. ** Returns:    char *            - Local name or schema name
  343. ** Description:    Naming function for Reference dictionary
  344. **
  345. */
  346.  
  347. char * SCOPE_get_ref_name(Linked_List ref_entry) 
  348. {
  349.     if (LISTget_second(ref_entry) == LIST_NULL) 
  350.       {  return SYMBOLget_name(LISTget_first(ref_entry));
  351.      
  352.      }
  353.     else return SYMBOLget_name(LISTget_second(ref_entry));
  354. }
  355.  
  356. void
  357. SCOPEprint(Scope scope)
  358. {
  359.     Error errc;
  360.     struct Scope *data;
  361.  
  362.     print_force(scope_print);
  363.  
  364.     data = OBJget_data(scope,Class_Scope,&errc);
  365.     SCOPE_print(data);
  366.  
  367.     print_unforce(scope_print);
  368. }
  369. #endif
  370.  
  371. /* find an entity type, return without resolving it */
  372. /* note that object found is not actually checked, only because */
  373. /* caller is in a better position to describe the error with context */
  374. Generic
  375. SCOPEfind(Scope scope, char *name,int type)
  376. {
  377.     extern Generic SCOPE_find(Scope , char *,int);
  378.     extern Dictionary EXPRESSbuiltins;    /* procedures/functions */
  379.     Generic x;
  380.  
  381.     __SCOPE_search_id++;
  382.  
  383.     x = SCOPE_find(scope,name,type);
  384.     if (x) return x;
  385.  
  386.     if (type & (SCOPE_FIND_FUNCTION | SCOPE_FIND_PROCEDURE)) {
  387.         x = DICTlookup(EXPRESSbuiltins,name);
  388.     }
  389.     return x;
  390. }
  391.  
  392.  
  393. /* look up types, functions, etc.  anything not inherited through */
  394. /* the supertype/subtype hierarchy */
  395. /* EH???  -> lookup an object when the current scope is not a schema */
  396. Generic
  397. SCOPE_find(Scope scope,char *name,int type)
  398. {
  399.     Generic result;
  400.     Rename *rename;
  401.  
  402.     if (scope->search_id == __SCOPE_search_id) return 0;
  403.     scope->search_id = __SCOPE_search_id;
  404.  
  405.     /* go up the superscopes, looking for object */
  406.     while (1) {
  407.         /* first look up locally */
  408.         result = DICTlookup(scope->symbol_table,name);
  409.         if (result && OBJtype_is_oneof(DICT_type,type)) {
  410.             return result;
  411.         }
  412.         if (scope->type == OBJ_SCHEMA) break;
  413.  
  414.         scope = scope->superscope;
  415.     }
  416.  
  417.     if (type & SCOPE_FIND_ENTITY) {
  418.         /* Occurs in a fully USE'd schema? */
  419.         LISTdo(scope->u.schema->uselist,schema,Schema)
  420.             /* follow chain'd USEs */
  421.             if (schema == 0) continue;
  422.             result = SCOPE_find(schema,name,type);
  423.             if (result) return(result);
  424.         LISTod;
  425.  
  426.         /* Occurs in a partially USE'd schema? */
  427.         rename = (Rename *)DICTlookup(scope->u.schema->usedict,name);
  428.         if (rename) {
  429.             DICT_type = rename->type;
  430.             return(rename->object);
  431.         }
  432.     }
  433.  
  434.     /* Occurs in a fully REF'd schema? */
  435.     LISTdo(scope->u.schema->reflist,schema,Schema)
  436.         if (schema == 0) continue;
  437.         result = DICTlookup(schema->symbol_table,name);
  438.         if (result) return result;
  439.         else continue;    /* try another schema */
  440.     LISTod;
  441.  
  442.     /* Occurs in a partially REF'd schema? */
  443.     rename = (Rename *)DICTlookup(scope->u.schema->refdict,name);
  444.     if (rename) {
  445.         DICT_type = rename->type;
  446.         return(rename->object);
  447.     }
  448.  
  449.     return 0;
  450. }
  451.  
  452. #if 0
  453. /* useful for extracting true ref of SELF when you're inside of a tiny scope */
  454. Entity
  455. SCOPEget_nearest_enclosing_entity(Scope s)
  456. {
  457.     for (;s;s = s->superscope) {
  458.         if (s->type == OBJ_ENTITY) break;
  459.     }
  460.     return (s);
  461. }
  462. #endif
  463.