C:/Users/Dennis/src/lang/Life_start/Life/life-1.02/source/modules.c

Go to the documentation of this file.
00001 /******************************** MODULES ************************************/
00002 /*  RM: Jan  7 1993
00003 
00004     This file implements a variation of the LIFE module system as specified by
00005     Dinesh Katiyar.
00006 
00007     */
00008 /*      $Id: modules.c,v 1.3 1994/12/15 22:05:39 duchier Exp $   */
00009 
00010 #ifndef lint
00011 static char vcid[] = "$Id: modules.c,v 1.3 1994/12/15 22:05:39 duchier Exp $";
00012 #endif /* lint */
00013 
00014 
00015 #include "extern.h"
00016 #include "modules.h"
00017 #include "trees.h"
00018 #include "copy.h"
00019 #include "token.h"
00020 #ifndef OS2_PORT
00021 #include "built_ins.h"
00022 #else
00023 #include "built_in.h"
00024 #endif
00025 
00026 ptr_node module_table=NULL;        /* The table of modules */
00027 ptr_module current_module=NULL;    /* The current module for the tokenizer */
00028 
00029 string module_buffer;              /* Temporary storage place for strings */
00030 
00031 ptr_module no_module=NULL;
00032 ptr_module bi_module=NULL;
00033 ptr_module user_module;
00034 ptr_module syntax_module=NULL;
00035 ptr_module x_module;
00036 ptr_module sys_module=NULL;
00037 
00038 long display_modules=TRUE;   /* Should really default to FALSE */
00039 
00040 extern ptr_goal resid_aim;
00041 
00042 
00043 
00044 /******** INIT_MODULES()
00045   Initialize the module system.
00046   */
00047 
00048 void init_modules()
00049 {
00050   bi_module=create_module("built_ins");
00051   no_module=create_module("no_module");
00052   x_module=create_module("x");
00053   syntax_module=create_module("syntax");
00054   user_module=create_module("user"); /*  RM: Jan 27 1993  */
00055   sys_module=create_module("sys");
00056   
00057   set_current_module(syntax_module);
00058 }
00059 
00060 
00061 
00062 /******** FIND_MODULE(module)
00063   Return a module if it exists.
00064   */
00065 
00066 ptr_module find_module(module)
00067 
00068      char *module;
00069 {
00070   ptr_node nodule;
00071 
00072   nodule=find(strcmp,module,module_table);
00073   if(nodule)
00074     return (ptr_module)(nodule->data);
00075   else
00076     return NULL;
00077 }
00078 
00079 
00080 
00081 /******** CREATE_MODULE(module)
00082   Create a new module.
00083   */
00084 
00085 ptr_module create_module(module)
00086 
00087      char *module;
00088 {
00089   ptr_module new;
00090 
00091 
00092   new=find_module(module);
00093   if(!new) {
00094     new=HEAP_ALLOC(struct wl_module);
00095     new->module_name=heap_copy_string(module);
00096     new->source_file=heap_copy_string(input_file_name);
00097     new->open_modules=NULL;
00098     new->inherited_modules=NULL;
00099     new->symbol_table=hash_create(16); /*  RM: Feb  3 1993  */
00100 
00101     heap_insert(strcmp,new->module_name,&module_table,new);
00102 
00103     /* printf("*** New module: '%s' from file %s\n",input_file_name); */
00104   }
00105   return new;
00106 }
00107 
00108 
00109 
00110 /******** SET_CURRENT_MODULE(module)
00111   Set the current module to a given string.
00112   */
00113 
00114 ptr_module set_current_module(module)
00115 
00116      ptr_module module;
00117 {
00118   current_module=module;
00119   /* printf("*** Current module: '%s'\n",current_module->module_name); */
00120   return current_module;
00121 }
00122 
00123 
00124 
00125 /******** EXTRACT_MODULE_FROM_NAME
00126   Return the module corresponding to "module#symbol".
00127   Return NULL if only "#symbol".
00128   */
00129 
00130 ptr_module extract_module_from_name(str)
00131 
00132      char *str;
00133 {
00134   char *s;
00135   ptr_module result=NULL;
00136 
00137   s=str;
00138   while(legal_in_name(*s))
00139     s++;
00140   if(s!=str && *s=='#' /* && *(s+1)!=0 */) {
00141     *s=0;
00142     result=create_module(str);
00143     *s='#';
00144     /*
00145     printf("Extracted module name '%s' from '%s'\n",result->module_name,str);
00146     */
00147   }
00148   
00149   return result;
00150 }
00151 
00152 
00153 
00154 /******** STRIP_MODULE_NAME(symbol)
00155   Return the sub-string of symbol without the module prefix.
00156   */
00157 
00158 char *strip_module_name(str)
00159 
00160      char *str;
00161 {
00162   char *s=str;
00163 
00164   while(legal_in_name(*s))
00165     s++;
00166   if(s!=str && *s=='#' /* && *(s+1)!=0 */) {
00167     s++;
00168     /* printf("Stripped module from '%s' yielding '%s'\n",str,s); */
00169     return s;
00170   }
00171   else
00172     return str;
00173 }
00174 
00175 
00176 
00177 /******** STRING_VAL(term)
00178   Return a string defined by a term, that is:
00179   if term is a string, return the value,
00180   otherwise return the symbol for that term.
00181   */
00182 
00183 char *string_val(term)
00184 
00185      ptr_psi_term term;
00186 {
00187   deref_ptr(term);
00188   if(term->value && term->type==quoted_string)
00189     return (char *)term->value;
00190   else
00191     return term->type->keyword->symbol;
00192 }
00193 
00194 
00195 
00196 /******** MAKE_MODULE_TOKEN(module,string)
00197   Write 'module#string' in module_buffer.
00198   If string is a qualified reference to a given module, then modify the calling
00199   module variable to reflect this.
00200 
00201   The result must be immediately stored in a newly allocated string.
00202   */
00203 
00204 char *make_module_token(module,str)
00205 
00206      ptr_module module;
00207      char *str;
00208 {
00209   ptr_module explicit;
00210 
00211 
00212   /* Check if the string already contains a module */
00213   explicit=extract_module_from_name(str);
00214   if(explicit)
00215     strcpy(module_buffer,str);
00216   else
00217     if(module!=no_module) {
00218       strcpy(module_buffer,module->module_name);
00219       strcat(module_buffer,"#");
00220       strcat(module_buffer,str);
00221     }
00222     else
00223       strcpy(module_buffer,str);
00224   
00225   return module_buffer;
00226 }
00227 
00228 
00229 
00230 /******** NEW_DEFINITION(key)
00231   Create a definition for a key.
00232   */
00233 
00234 ptr_definition new_definition(key)    /*  RM: Feb 22 1993  */
00235 
00236      ptr_keyword key;
00237 {
00238   ptr_definition result;
00239 
00240   
00241   /* printf("*** New definition: %s\n",key->combined_name); */
00242   
00243   /* Create a new definition */
00244   result=HEAP_ALLOC(struct wl_definition);
00245   
00246   /*  RM: Feb  3 1993  */
00247   result->next=first_definition; /* Linked list of all definitions */
00248   first_definition=result;
00249             
00250   result->keyword=key;
00251   result->rule=NULL;
00252   result->properties=NULL;
00253   result->date=0;
00254   result->type=undef;
00255   result->always_check=TRUE;
00256   result->protected=TRUE;
00257   result->evaluate_args=TRUE;
00258   result->already_loaded=FALSE;
00259   result->children=NULL;
00260   result->parents=NULL;
00261   result->code=NOT_CODED;
00262   result->op_data=NULL;
00263   result->global_value=NULL; /*  RM: Feb  8 1993  */
00264   result->init_value=NULL;   /*  RM: Mar 23 1993  */
00265   key->definition=result;
00266 
00267   return result;
00268 }
00269 
00270   
00271 
00272 /******** UPDATE_SYMBOL(m,s)
00273   S is a string of characters encountered during parsing, M is the module it
00274   belongs too.
00275 
00276   if M is NULL then extract the module name from S. If that fails then use the
00277   current module.
00278   
00279   Then, retrieve the keyword for 'module#symbol'. Then find the correct
00280   definition by scanning the opened modules.
00281   */
00282 
00283 ptr_definition update_symbol(module,symbol)   /*  RM: Jan  8 1993  */
00284      ptr_module module;
00285      char *symbol;
00286 {
00287   ptr_keyword key;
00288   ptr_definition result=NULL;
00289   ptr_int_list opens;
00290   ptr_module opened;
00291   ptr_keyword openkey;
00292   ptr_keyword tempkey;
00293   
00294   /* First clean up the arguments and find out which module to use */
00295 
00296   if(!module) {
00297     module=extract_module_from_name(symbol);
00298     if(!module)
00299       module=current_module;
00300     symbol=strip_module_name(symbol);
00301   }
00302   
00303   /* printf("looking up %s#%s\n",module->module_name,symbol); */
00304   
00305   /* Now look up 'module#symbol' in the symbol table */
00306   key=hash_lookup(module->symbol_table,symbol);
00307   
00308   if(key)
00309     if(key->public || module==current_module)
00310       result=key->definition;
00311     else {
00312       Errorline("qualified call to private symbol '%s'\n",
00313                 key->combined_name);
00314       
00315       result=error_psi_term->type;
00316     }
00317   else
00318     if(module!=current_module) {
00319       Errorline("qualified call to undefined symbol '%s#%s'\n",
00320                 module->module_name,symbol);
00321       result=error_psi_term->type;
00322     }
00323     else
00324       {
00325         /* Add 'module#symbol' to the symbol table */
00326         key=HEAP_ALLOC(struct wl_keyword);
00327         key->module=module;
00328         key->symbol=heap_copy_string(symbol);
00329         key->combined_name=heap_copy_string(make_module_token(module,symbol));
00330         key->public=FALSE;
00331         key->private_feature=FALSE; /*  RM: Mar 11 1993  */
00332         key->definition=NULL;
00333         
00334         hash_insert(module->symbol_table,key->symbol,key);
00335         
00336         
00337         /* Search the open modules of 'module' for 'symbol' */
00338         opens=module->open_modules;
00339         openkey=NULL;
00340         while(opens) {
00341           opened=(ptr_module)(opens->value);
00342           if(opened!=module) {
00343             
00344             tempkey=hash_lookup(opened->symbol_table,symbol);
00345             
00346             if(tempkey)
00347               if(openkey && openkey->public && tempkey->public) {
00348                 if(openkey->definition==tempkey->definition) {
00349                   Warningline("benign module name clash: %s and %s\n",
00350                               openkey->combined_name,
00351                               tempkey->combined_name);
00352                 }
00353                 else {
00354                   Errorline("serious module name clash: \"%s\" and \"%s\"\n",
00355                             openkey->combined_name,
00356                             tempkey->combined_name);
00357                   
00358                   result=error_psi_term->type;
00359                 }
00360               }
00361               else
00362                 if(!openkey || !openkey->public)
00363                   openkey=tempkey;
00364           }
00365           
00366           opens=opens->next;
00367         }
00368         
00369         if(!result) { /*  RM: Feb  1 1993  */
00370           
00371           if(openkey && openkey->public) {
00372             /* Found the symbol in an open module */
00373             
00374             if(!openkey->public)
00375               Warningline("implicit reference to non-public symbol: %s\n",
00376                           openkey->combined_name);
00377             
00378             result=openkey->definition;
00379             key->definition=result;
00380             
00381             /*
00382               printf("*** Aliasing %s#%s to %s#%s\n",
00383               key->module->module_name,
00384               key->symbol,
00385               openkey->module->module_name,
00386               openkey->symbol);
00387               */
00388             
00389           }
00390           else { /* Didn't find it */
00391             result=new_definition(key);
00392           }
00393         }
00394       }
00395   
00396   return result;
00397 }
00398 
00399 
00400 
00401 /******** GET_FUNCTION_VALUE(module,symbol)
00402   Return the value of a function without arguments. This returns a psi-term on
00403   the heap which may not be bound etc...
00404   
00405   This routine allows C variables to be stored as LIFE functions.
00406   */
00407 
00444 /******** PRINT_SYMBOL(k)
00445   Returns the string to be used to display keyword K.
00446   */
00447 
00448 char *print_symbol(k)
00449      
00450      ptr_keyword k;
00451      
00452 {
00453   k=k->definition->keyword;
00454   if(display_modules)
00455     return k->combined_name;
00456   else
00457     return k->symbol;
00458 }
00459 
00460 
00461 /******** PRETTY_SYMBOL(k)
00462   Prints the string to be used to display keyword K.
00463   */
00464 
00465 void pretty_symbol(k)
00466      
00467      ptr_keyword k;
00468 {
00469   k=k->definition->keyword;
00470   if(display_modules) {
00471     prettyf(k->module->module_name);
00472     prettyf("#");
00473   }
00474   prettyf(k->symbol);
00475 }
00476 
00477 
00478 
00479 /******** PRETTY_QUOTE_SYMBOL(k)
00480   Prints the string to be used to display keyword K, with quotes if required.
00481   */
00482 
00483 void pretty_quote_symbol(k)
00484      
00485      ptr_keyword k;
00486 {
00487   k=k->definition->keyword;
00488   if(display_modules) {
00489     prettyf(k->module->module_name);
00490     prettyf("#");
00491   }
00492   prettyf_quote(k->symbol);
00493 }
00494 
00495 
00496 
00497 /******** C_SET_MODULE()
00498   This routine retrieves the necessary psi-term to determine the current
00499   state of the module mechanism from the heap.
00500   */
00501 
00502 long c_set_module()
00503      
00504 {
00505   ptr_psi_term arg1,arg2;
00506   ptr_psi_term call;
00507   
00508   call=aim->a;
00509   deref_ptr(call);
00510   get_two_args(call->attr_list,&arg1,&arg2);
00511   
00512   if(arg1) {
00513     set_current_module(create_module(string_val(arg1)));
00514     return TRUE;
00515   }
00516   else {
00517     Errorline("argument missing in '%P'\n",call);
00518     return FALSE;
00519   }
00520 }
00521 
00522 
00523 
00524 /******** C_OPEN_MODULE()
00525   Open one or more modules, that is, alias all the public words
00526   in the current module to the definitions in the argument.
00527   An error message is printed for each module that is not successfully
00528   opened.
00529   If at least one module was not successfully opened, the routine
00530   fails.
00531 */
00532 
00533 long c_open_module()
00534      
00535 {
00536   ptr_psi_term call;
00537   int onefailed=FALSE;
00538   
00539   call=aim->a;
00540   deref_ptr(call);
00541   if (call->attr_list) {
00542     open_module_tree(call->attr_list, &onefailed);
00543   }
00544   else {
00545     Errorline("argument missing in '%P'\n",call);
00546   }
00547   
00548   return !onefailed;
00549 }
00550 
00551 
00552 
00553 open_module_tree(n, onefailed)
00554 ptr_node n;
00555 int *onefailed;
00556 {
00557   if (n) {
00558     ptr_psi_term t;
00559     open_module_tree(n->left,onefailed);
00560 
00561     t=(ptr_psi_term)n->data;
00562     open_module_one(t,onefailed);
00563 
00564     open_module_tree(n->right,onefailed);
00565   }
00566 }
00567 
00568 
00569 
00570 open_module_one(t, onefailed)
00571 ptr_psi_term t;
00572 int *onefailed;
00573 {
00574   ptr_module open_module;
00575   ptr_int_list opens;
00576   ptr_keyword key1,key2;
00577   int i;
00578   int found=FALSE;
00579 
00580   open_module=find_module(string_val(t));
00581   if (open_module) {
00582     
00583     for (opens=current_module->open_modules;opens;opens=opens->next)
00584         if (opens->value==(GENERIC)open_module) {
00585           /* Warningline("module \"%s\" is already open\n",
00586              open_module->module_name); */ /*  RM: Jan 27 1993  */
00587           found=TRUE;
00588         }
00589     
00590     if (!found) {
00591         opens=HEAP_ALLOC(struct wl_int_list);
00592         opens->value=(GENERIC)open_module;
00593         opens->next=current_module->open_modules;
00594         current_module->open_modules=opens;
00595 
00596         /* Check for name conflicts */
00597         /*  RM: Feb 23 1993  */
00598         for (i=0;i<open_module->symbol_table->size;i++)
00599           if ((key1=open_module->symbol_table->data[i]) && key1->public) {
00600             key2=hash_lookup(current_module->symbol_table,key1->symbol);
00601             if (key2 && key1->definition!=key2->definition)
00602               Errorline("symbol clash '%s' and '%s'\n",
00603                         key1->combined_name,
00604                         key2->combined_name);
00605           }
00606     }
00607   }
00608   else {
00609     Errorline("module \"%s\" not found\n",string_val(t));
00610     *onefailed=TRUE;
00611   }
00612 }
00613 
00614 
00615 
00616 /******** MAKE_PUBLIC(term,bool)
00617   Make a term public.
00618   */
00619 
00620 long make_public(term,bool)   /*  RM: Feb 22 1993  Modified */
00621      
00622      ptr_psi_term term;
00623      long bool;
00624 {
00625   int ok=TRUE;
00626   ptr_keyword key;
00627   ptr_definition def;
00628   
00629   deref_ptr(term);
00630 
00631   key=hash_lookup(current_module->symbol_table,term->type->keyword->symbol);
00632   if(key) {
00633     
00634     if(key->definition->keyword->module!=current_module && !bool) {
00635       Warningline("local definition of '%s' overrides '%s'\n",
00636                key->definition->keyword->symbol,
00637                key->definition->keyword->combined_name);
00638       
00639       new_definition(key);
00640     }
00641     
00642     key->public=bool;
00643   }
00644   else {
00645     def=update_symbol(current_module,term->type->keyword->symbol);
00646     def->keyword->public=bool;
00647   }
00648   
00649   return ok;
00650 }
00651 
00652 
00653 #define MAKE_PUBLIC          1
00654 #define MAKE_PRIVATE         2
00655 #define MAKE_FEATURE_PRIVATE 3
00656 
00657 /* Do for all arguments, for the built-ins
00658    c_public, c_private, and c_private_feature.
00659 */
00660 traverse_tree(n,flag)
00661 ptr_node n;
00662 int flag;
00663 {
00664   if (n) {
00665     ptr_psi_term t;
00666     traverse_tree(n->left,flag);
00667 
00668     t=(ptr_psi_term)n->data;
00669     deref_ptr(t);
00670     switch (flag) {
00671     case MAKE_PUBLIC:
00672       make_public(t,TRUE);
00673       break;
00674     case MAKE_PRIVATE:
00675       make_public(t,FALSE);
00676       break;
00677     case MAKE_FEATURE_PRIVATE:
00678       make_feature_private(t);
00679       break;
00680     }
00681     traverse_tree(n->right,flag);
00682   }
00683 }
00684 
00685 
00686 /******** C_PUBLIC()
00687   The argument(s) are symbols.
00688   Make them public in the current module if they belong to it.
00689   */
00690 
00691 long c_public()
00692      
00693 {
00694   ptr_psi_term arg1,arg2;
00695   ptr_psi_term call;
00696   int success;
00697   
00698   call=aim->a;
00699   deref_ptr(call);
00700   if (call->attr_list) {
00701     traverse_tree(call->attr_list,MAKE_PUBLIC);
00702     success=TRUE;
00703   } else {
00704     Errorline("argument missing in '%P'\n",call);
00705     success=FALSE;
00706   }
00707   
00708   return success;
00709 }
00710 
00711 
00712 /******** C_PRIVATE()
00713   The argument is a single symbol or a list of symbols.
00714   Make them private in the current module if they belong to it.
00715   */
00716 
00717 long c_private()
00718      
00719 {
00720   ptr_psi_term arg1,arg2;
00721   ptr_psi_term call;
00722   int success;
00723   
00724   call=aim->a;
00725   deref_ptr(call);
00726   if (call->attr_list) {
00727     traverse_tree(call->attr_list,MAKE_PRIVATE);
00728     success=TRUE;
00729   } else {
00730     Errorline("argument missing in '%P'\n",call);
00731     success=FALSE;
00732   }
00733   
00734   return success;
00735 }
00736 
00737 
00738 
00739 /******** C_DISPLAY_MODULES();
00740   Set the display modules switch.
00741   */
00742 
00743 long c_display_modules()
00744      
00745 {
00746   ptr_psi_term arg1,arg2;
00747   ptr_psi_term call;
00748   int success=TRUE;
00749   
00750   
00751   call=aim->a;
00752   deref_ptr(call);
00753   get_two_args(call->attr_list,&arg1,&arg2);
00754   
00755   if(arg1) {
00756     deref_ptr(arg1);
00757     if(arg1->type==true)
00758       display_modules=TRUE;
00759     else
00760       if(arg1->type==false)
00761         display_modules=FALSE;
00762       else {
00763         Errorline("argument should be boolean in '%P'\n",call);
00764         success=FALSE;
00765       }
00766   }
00767   else /* No argument: toggle */
00768     display_modules= !display_modules;
00769   
00770   return success;
00771 }
00772 
00773 
00774 
00775 /******** C_DISPLAY_PERSISTENT();
00776   Set the display persistent switch.
00777   */
00778 
00779 long c_display_persistent()       /*  RM: Feb 12 1993  */
00780      
00781 {
00782   ptr_psi_term arg1,arg2;
00783   ptr_psi_term call;
00784   int success=TRUE;
00785   
00786   
00787   call=aim->a;
00788   deref_ptr(call);
00789   get_two_args(call->attr_list,&arg1,&arg2);
00790   
00791   if(arg1) {
00792     deref_ptr(arg1);
00793     if(arg1->type==true)
00794       display_persistent=TRUE;
00795     else
00796       if(arg1->type==false)
00797         display_persistent=FALSE;
00798       else {
00799         Errorline("argument should be boolean in '%P'\n",call);
00800         success=FALSE;
00801       }
00802   }
00803   else /* No argument: toggle */
00804     display_persistent= !display_persistent;
00805   
00806   return success;
00807 }
00808 
00809 
00810 
00811 /******** C_TRACE_INPUT();
00812   Set the trace_input switch.
00813   */
00814 
00815 long c_trace_input()
00816      
00817 {
00818   ptr_psi_term arg1,arg2;
00819   ptr_psi_term call;
00820   int success=TRUE;
00821   
00822   
00823   call=aim->a;
00824   deref_ptr(call);
00825   get_two_args(call->attr_list,&arg1,&arg2);
00826   
00827   if(arg1) {
00828     deref_ptr(arg1);
00829     if(arg1->type==true)
00830       trace_input=TRUE;
00831     else
00832       if(arg1->type==false)
00833         trace_input=FALSE;
00834       else {
00835         Errorline("argument should be boolean in '%P'\n",call);
00836         success=FALSE;
00837       }
00838   }
00839   else /* No argument: toggle */
00840     trace_input= !trace_input;
00841   
00842   return success;
00843 }
00844 
00845 
00846 
00847 /******** REPLACE(old,new,term)
00848   Replace all occurrences of type OLD with NEW in TERM.
00849   */
00850 
00851 void rec_replace();
00852 void replace_attr();
00853 
00854 int replace(old,new,term)
00855      
00856      ptr_definition old;
00857      ptr_definition new;
00858      ptr_psi_term term;
00859 {
00860   clear_copy();
00861   rec_replace(old,new,term);
00862 }
00863 
00864 
00865 
00866 void rec_replace(old,new,term)
00867      
00868      ptr_definition old;
00869      ptr_definition new;
00870      ptr_psi_term term;
00871 {
00872   ptr_psi_term done;
00873   long info;
00874   ptr_node old_attr;
00875   
00876   deref_ptr(term);
00877   done=translate(term,&info);
00878   if(!done) {
00879     insert_translation(term,term,0);
00880     
00881     if(term->type==old && !term->value) {
00882       push_ptr_value(def_ptr,&(term->type));
00883       term->type=new;
00884     }
00885     old_attr=term->attr_list;
00886     if(old_attr) {
00887       push_ptr_value(int_ptr,&(term->attr_list));
00888       term->attr_list=NULL;
00889       replace_attr(old_attr,term,old,new);
00890     }
00891   }
00892 }
00893 
00894 
00895 void replace_attr(old_attr,term,old,new)
00896      ptr_node old_attr;
00897      ptr_psi_term term;
00898      ptr_definition old;
00899      ptr_definition new;
00900      
00901 {
00902   ptr_psi_term value;
00903   char *oldlabel; /*  RM: Mar 12 1993  */
00904   char *newlabel;
00905   
00906   if(old_attr->left)
00907     replace_attr(old_attr->left,term,old,new);
00908   
00909   value=(ptr_psi_term)old_attr->data;
00910   rec_replace(old,new,value);
00911   
00912   if(old->keyword->private_feature)  /*  RM: Mar 12 1993  */
00913     oldlabel=old->keyword->combined_name;
00914   else
00915     oldlabel=old->keyword->symbol;
00916   
00917   if(new->keyword->private_feature)  /*  RM: Mar 12 1993  */
00918     newlabel=new->keyword->combined_name;
00919   else
00920     newlabel=new->keyword->symbol;
00921   
00922   if(!strcmp(old_attr->key,oldlabel))
00923     stack_insert(featcmp,newlabel,&(term->attr_list),value);
00924   else
00925     stack_insert(featcmp,old_attr->key,&(term->attr_list),value);
00926   
00927   if(old_attr->right)
00928     replace_attr(old_attr->right,term,old,new);
00929 }
00930 
00931 
00932 
00933 /******** C_REPLACE()
00934   Replace all occurrences of type ARG1 with ARG2 in ARG3.
00935   */
00936 
00937 long c_replace()
00938      
00939 {
00940   ptr_psi_term arg1=NULL;
00941   ptr_psi_term arg2=NULL;
00942   ptr_psi_term arg3=NULL;
00943   ptr_psi_term call;
00944   int success=FALSE;
00945   ptr_node n;
00946   
00947   call=aim->a;
00948   deref_ptr(call);
00949   
00950   get_two_args(call->attr_list,&arg1,&arg2);
00951   n=find(featcmp,three,call->attr_list);
00952   if (n)
00953     arg3=(ptr_psi_term)n->data;
00954   
00955   if(arg1 && arg2 && arg3) {
00956     deref_ptr(arg1);
00957     deref_ptr(arg2);
00958     deref_ptr(arg3);
00959     replace(arg1->type,arg2->type,arg3);
00960     success=TRUE;
00961   }
00962   else {
00963     Errorline("argument missing in '%P'\n",call);
00964   }
00965   
00966   return success;
00967 }
00968 
00969 
00970 
00971 
00972 /******** C_CURRENT_MODULE
00973   Return the current module.
00974   */
00975 
00976 long c_current_module()
00977      
00978 {
00979   long success=TRUE;
00980   ptr_psi_term result,g,other;
00981   
00982   
00983   g=aim->a;
00984   deref_ptr(g);
00985   result=aim->b;
00986   deref_ptr(result);
00987   
00988   
00989   other=stack_psi_term(4);
00990   /* PVR 24.1.94 */
00991   other->type=quoted_string;
00992   other->value=(GENERIC)heap_copy_string(current_module->module_name);
00993   /*
00994     update_symbol(current_module,
00995     current_module->module_name)
00996     ->keyword->symbol
00997     );
00998 */ /* RM: 2/15/1994 */
00999   /* other->type=update_symbol(current_module,current_module->module_name); */
01000   resid_aim=NULL;
01001   push_goal(unify,result,other,NULL);
01002   
01003   return success;
01004 }
01005 
01006 
01007 
01008 
01009 /******** C_MODULE_ACCESS
01010   Return the psi-term Module#Symbol
01011   */
01012 
01013 long c_module_access()
01014      
01015 {
01016   long success=FALSE;
01017   ptr_psi_term result,module,symbol,call,other;
01018   
01019   
01020   call=aim->a;
01021   deref_ptr(call);
01022   
01023   /*
01024     result=aim->b;
01025     deref_ptr(result);
01026     get_two_args(call,&module,&symbol);
01027     
01028     if(module && symbol) {
01029     other=stack_psi_term(4);
01030     other->type=update_symbol(module_access,module_access->module_name);
01031     resid_aim=NULL;
01032     push_goal(unify,result,other,NULL);
01033     
01034     }
01035     */
01036   
01037   Warningline("%P not implemented yet...\n",call);
01038   
01039   return success;
01040 }
01041 
01042 
01043 
01044 /******** GLOBAL_UNIFY(u,v)
01045   Unify two psi-terms, where it is known that V is on the heap (a persistent
01046   variable).
01047   
01048   This routine really matches U and V, it will only succeed if V is more
01049   general than U. U will then be bound to V.
01050   */
01051 
01052 int global_unify_attr();   /*  RM: Feb  9 1993  */
01053 
01054 int global_unify(u,v)      /*  RM: Feb 11 1993  */
01055      
01056      ptr_psi_term u;
01057      ptr_psi_term v;
01058 {
01059   int success=TRUE;
01060   int compare;
01061   ptr_definition new_type;
01062   ptr_int_list new_code;
01063 
01064   deref_ptr(u);
01065   deref_ptr(v);
01066 
01067   Traceline("match persistent %P with %P\n",u,v);
01068 
01069   /* printf("u=%ld, v=%ld, heap_pointer=%ld\n",u,v,heap_pointer);*/
01070 
01071   /* printf("u=%s, v=%s\n",
01072      u->type->keyword->symbol,
01073      v->type->keyword->symbol); */
01074   
01075   if((GENERIC)u>=heap_pointer) {
01076     Errorline("cannot unify persistent values\n");
01077     return c_abort();
01078   }
01079   
01080   /**** U is on the stack, V is on the heap ****/
01081   
01082   /**** Calculate their Greatest Lower Bound and compare them ****/
01083   compare=glb(u->type,v->type,&new_type,&new_code);
01084   
01085   /* printf("compare=%d\n",compare); */
01086   
01087   if (compare==1 || compare==3) { /* Match only */
01088     
01089     /**** Check for values ****/
01090     if(v->value) {
01091       if(u->value) {
01092         if(u->value!=v->value) { /* One never knows */
01093           if (overlap_type(v->type,real))
01094             success=(*((REAL *)u->value)==(*((REAL *)v->value)));
01095           else if (overlap_type(v->type,quoted_string))
01096             success=(strcmp((char *)u->value,(char *)v->value)==0);
01097           else
01098             return FALSE; /* Don't unify CUTs and STREAMs and things */
01099         }
01100       }
01101     }
01102     else
01103       if(u->value)
01104         return FALSE;
01105     
01106     if(success) {
01107       /**** Bind the two psi-terms ****/
01108       push_psi_ptr_value(u,&(u->coref));
01109       u->coref=v;
01110       
01111       /**** Match the attributes ****/
01112       success=global_unify_attr(u->attr_list,v->attr_list);
01113 
01114       /*
01115         if(!success)
01116         Warningline("attributes don't unify in %P and %P\n",u,v);
01117         */
01118       
01119       if(success && u->resid)
01120         release_resid(u);
01121     }
01122   }
01123   else
01124     success=FALSE;
01125   
01126   return success;
01127 }
01128 
01129 
01130 
01131 /******** GLOBAL_UNIFY_ATTR(u,v)
01132   Unify the attributes of two terms, one on the heap, one on the stack.
01133   This is really matching, so all features of U must appear in V.
01134   */
01135 
01136 int global_unify_attr(u,v)    /*  RM: Feb  9 1993  */
01137 
01138      ptr_node u;
01139      ptr_node v;
01140 {
01141   int success=TRUE;
01142   ptr_node temp;
01143   long cmp;
01144 
01145   if(u)
01146     if(v) {
01147       /*  RM: Feb 16 1993  Avoid C optimiser bug */
01148       dummy_printf("%s %s\n",u->key,v->key);
01149       
01150       cmp=featcmp(u->key,v->key);
01151       if(cmp<0) {
01152         temp=u->right;
01153         u->right=NULL;
01154         success=global_unify_attr(u,v->left) && global_unify_attr(temp,v);
01155         u->right=temp;
01156       }
01157       else
01158         if(cmp>0) {
01159           temp=u->left;
01160           u->left=NULL;
01161           success=global_unify_attr(u,v->right) && global_unify_attr(temp,v);
01162           u->left=temp;
01163         }
01164         else {
01165           success=
01166             global_unify_attr(u->left,v->left) &&
01167               global_unify_attr(u->right,v->right) &&
01168                 global_unify(u->data,v->data);
01169         }
01170     }
01171     else
01172       success=FALSE;
01173   
01174   return success;
01175 }
01176 
01177 
01178 
01179 /******** C_ALIAS
01180   Alias one keyword to another.
01181   */
01182 
01183 long c_alias()
01184 {
01185   long success=TRUE;
01186   ptr_psi_term arg1,arg2,g;
01187   ptr_keyword key;
01188 
01189   g=aim->a;
01190 
01191   deref_ptr(g);
01192   get_two_args(g->attr_list,&arg1,&arg2);
01193   if (arg1 && arg2) {
01194     deref_ptr(arg1);
01195     deref_ptr(arg2);
01196     
01197     key=hash_lookup(current_module->symbol_table,arg1->type->keyword->symbol);
01198     if(key) {
01199       if(key->definition!=arg2->type) {
01200         Warningline("alias: '%s' has now been overwritten by '%s'\n",
01201                  key->combined_name,
01202                  arg2->type->keyword->combined_name);
01203         
01204         key->definition=arg2->type;
01205       }
01206     }
01207     else
01208       Errorline("module violation: cannot alias '%s' from module \"%s\"\n",
01209                 key->combined_name,
01210                 current_module->module_name);
01211   }
01212   else {
01213     success=FALSE;
01214     Errorline("argument(s) missing in '%P'\n",g);
01215   }
01216   
01217   return success;
01218 }
01219 
01220 
01221 
01222 /******** GET_MODULE(psi,module,resid)
01223   Convert a psi-term to a module. The psi-term must be a string.
01224   */
01225 
01226 int get_module(psi,module)
01227 
01228      ptr_psi_term psi;
01229      ptr_module *module;
01230 {
01231   int success=TRUE;
01232   char *s;
01233   
01234   *module=NULL;
01235   
01236   deref_ptr(psi);
01237   if(overlap_type(psi->type,quoted_string) && psi->value)
01238     s=(char *)psi->value;
01239   else
01240     s=psi->type->keyword->symbol;
01241   
01242   *module=find_module(s);
01243   if(!(*module)) {
01244     Errorline("undefined module \"%s\"\n",s);
01245     success=FALSE;
01246   }
01247   
01248   return success;
01249 }
01250 
01251 
01252 
01253 
01254 /******** MAKE_FEATURE_PRIVATE(feature)
01255   Make a feature private.
01256   */
01257 
01258 int make_feature_private(term)  /*  RM: Mar 11 1993  */
01259      
01260      ptr_psi_term term;
01261 {
01262   int ok=TRUE;
01263   ptr_keyword key;
01264   ptr_definition def;
01265 
01266   deref_ptr(term);
01267 
01268   key=hash_lookup(current_module->symbol_table,term->type->keyword->symbol);
01269   
01270   if(key) {
01271     /*
01272       if(key->definition->keyword->module!=current_module) {
01273       Warningline("local definition of '%s' overrides '%s'\n",
01274       key->definition->keyword->symbol,
01275       key->definition->keyword->combined_name);
01276       
01277       new_definition(key);
01278       }
01279     */
01280     
01281     key->private_feature=TRUE;
01282     def=key->definition;
01283   }
01284   else {
01285     def=update_symbol(current_module,term->type->keyword->symbol);
01286     def->keyword->private_feature=TRUE;
01287   }
01288 
01289   
01290   if(ok && def->keyword->public) {
01291     Warningline("feature '%s' is now private, but was also declared public\n",
01292                 def->keyword->combined_name);
01293   }
01294   
01295   return ok;
01296 }
01297 
01298 
01299 
01300 
01301 
01302 /******** C_PRIVATE_FEATURE()
01303   The argument is a single symbol or a list of symbols.
01304   Make this feature private to the current module.
01305   */
01306 
01307 long c_private_feature()    /*  RM: Mar 11 1993  */
01308      
01309 {
01310   ptr_psi_term arg1,arg2;
01311   ptr_psi_term call;
01312   int success;
01313   
01314   call=aim->a;
01315   deref_ptr(call);
01316   if (call->attr_list) {
01317     traverse_tree(call->attr_list,MAKE_FEATURE_PRIVATE);
01318     success=TRUE;
01319   } else {
01320     Errorline("argument missing in '%P'\n",call);
01321     success=FALSE;
01322   }
01323   
01324   return success;
01325 }
01326 
01327 
01328 
01329 /********* UPDATE_FEATURE(module,feature)
01330   Look up a FEATURE.
01331   May return NULL if the FEATURE is not visible from MODULE.
01332   */
01333 
01334 ptr_definition update_feature(module,feature)
01335 
01336      ptr_module module;
01337      char *feature;
01338 {
01339   ptr_keyword key;
01340   ptr_module explicit;
01341 
01342   /* Check if the feature already contains a module name */
01343 
01344   if(!module)
01345     module=current_module;
01346   
01347   explicit=extract_module_from_name(feature);
01348   if(explicit)
01349     if(explicit!=module)
01350       return NULL; /* Feature isn't visible */
01351     else
01352       return update_symbol(NULL,feature);
01353 
01354   /* Now we have a simple feature to look up */
01355   key=hash_lookup(module->symbol_table,feature);
01356   if(key && key->private_feature)
01357     return key->definition;
01358   else
01359     return update_symbol(module,feature);
01360 }
01361 
01362 
01363 
01364 /******** ALL_PUBLIC_SYMBOLS
01365   Returns all public symbols from all modules or a specific module.
01366   */
01367 
01368 int all_public_symbols()
01369 {
01370   ptr_psi_term arg1,arg2,funct,result;
01371   ptr_psi_term list;
01372   ptr_psi_term car;
01373   ptr_module module=NULL;
01374   ptr_definition d;
01375   
01376   funct=aim->a;
01377   deref_ptr(funct);
01378   result=aim->b;
01379   get_two_args(funct->attr_list,&arg1,&arg2);
01380   
01381   if(arg1) {
01382     deref_ptr(arg1);
01383     (void)get_module(arg1,&module);
01384   }
01385   else
01386     module=NULL;
01387   
01388   list=stack_nil();
01389   
01390   for(d=first_definition;d;d=d->next)
01391     if(d->keyword->public && (!module || d->keyword->module==module)) {
01392       car=stack_psi_term(4);
01393       car->type=d;
01394       list=stack_cons(car,list);
01395     }
01396   
01397   push_goal(unify,result,list,NULL);
01398   
01399   return TRUE;
01400 }

Generated on Sat Jan 26 08:48:07 2008 for WildLife by  doxygen 1.5.4