/[ascend]/trunk/base/generic/compiler/extfunc.c
ViewVC logotype

Diff of /trunk/base/generic/compiler/extfunc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 709 by johnpye, Wed Jun 28 16:28:57 2006 UTC revision 710 by johnpye, Thu Jun 29 08:53:37 2006 UTC
# Line 36  Line 36 
36  #include "instance_io.h"  #include "instance_io.h"
37  #include "extfunc.h"  #include "extfunc.h"
38  #include "extcall.h"  #include "extcall.h"
39    #include "atomvalue.h"
40    
41  /*------------------------------------------------------------------------------  /*------------------------------------------------------------------------------
42    forward decls and typedefs etc    forward decls and typedefs etc
# Line 65  int CreateUserFunctionBlackBox(CONST cha Line 66  int CreateUserFunctionBlackBox(CONST cha
66      return 1;      return 1;
67    }    }
68    efunc = LookupExtFunc(name);    efunc = LookupExtFunc(name);
69    if (efunc != NULL) {    /* name was pre-loaded -- just update the info */    if (efunc != NULL) {
70        CONSOLE_DEBUG("Found efunc at %p",efunc);
71        /* name was pre-loaded -- just update the info */
72      isNew = 0;      isNew = 0;
73    } else {    }else{
74      isNew = 1;      isNew = 1;
75      efunc = ASC_NEW(struct ExternalFunc);      efunc = ASC_NEW(struct ExternalFunc);
76      asc_assert(efunc!=NULL);      asc_assert(efunc!=NULL);
77      efunc->help = NULL;      efunc->help = NULL;
78      efunc->name = ascstrdup(SCP(AddSymbol(name)));      efunc->name = ascstrdup(SCP(AddSymbol(name)));
79        CONSOLE_DEBUG("Created new efunc at %p",efunc);
80      /* add or find name in symbol table */      /* add or find name in symbol table */
81      /* the main symtab owns the string */      /* the main symtab owns the string */
82    }    }
# Line 93  int CreateUserFunctionBlackBox(CONST cha Line 97  int CreateUserFunctionBlackBox(CONST cha
97    }    }
98    
99    if (isNew) {    if (isNew) {
100        CONSOLE_DEBUG("NEW BLACKBOX EFUNC %p ('%s', %lu inputs, %lu outputs, type=%d)"
101            ,efunc, name, n_inputs, n_outputs, (int)efunc->etype
102        );
103      (void)AddExternalFunc(efunc,1);      (void)AddExternalFunc(efunc,1);
104    }    }
105    return 0;    return 0;
106  }  }
107    
 /**  
     This function is hacking. The correct approach is to go through the  
     ExtRelCache object, see rel.c.  
 */  
 double blackbox_evaluate_residual(struct relation *r){  
     struct ExtCallNode *ext;  
     struct ExternalFunc *efunc;  
     int i,n;  
     char *tmp;  
     struct Instance *inst;  
     double *in;  
     double *out;  
   
     CONSOLE_DEBUG("...");  
   
     n = NumberVariables(r);  
   
     asc_assert(r!=NULL);  
     asc_assert(r->share!=NULL);  
     asc_assert(r->share->bbox.ext!=NULL);  
     ext = r->share->bbox.ext;  
     efunc = ext->efunc;  
     asc_assert(efunc!=NULL);  
     ERROR_REPORTER_HERE(ASC_PROG_NOTE,"ABOUT TO EVALUATE %s",efunc->name);  
   
     asc_assert(efunc->etype==efunc_BlackBox);  
   
     ExtBBoxFunc *valfnptr = efunc->u.black.value;  
     asc_assert(valfnptr!=NULL);  
   
     CONSOLE_DEBUG("vars=%d, inputs=%d, outputs=%d",n  
         ,NumberInputArgs(efunc)  
         ,NumberOutputArgs(efunc)  
     );  
   
     /* list all the variables associated with this black box */  
     for(i=1;i <= n; ++i){  
         inst = RelationVariable(r,i);  
         tmp = WriteInstanceNameString(inst, NULL);  
         if(i<=NumberInputArgs(efunc)){  
             CONSOLE_DEBUG("Input %d: '%s' (at %p)", i, tmp, inst);  
         }else{  
             CONSOLE_DEBUG("Output %d: '%s'", i-NumberInputArgs(efunc), tmp);  
         }  
         ASC_FREE(tmp);  
     }  
   
     /* allocate space for the evaluation inputs and outputs */  
     in = ASC_NEW_ARRAY(double,NumberInputArgs(efunc));  
     out = ASC_NEW_ARRAY_CLEAR(double,NumberOutputArgs(efunc));  
   
     /* pull the current input values and place them in our 'in' array */  
     for(i=0; i < NumberInputArgs(efunc); ++i){  
         inst = RelationVariable(r,i+1);  
         tmp = WriteInstanceNameString(inst,NULL);  
         if(!AtomAssigned(inst)){  
             CONSOLE_DEBUG("Var %d ('%s') has not been assigned yet!",i+1,tmp);  
             in[i]=-1;  
         }else{  
             in[i] = RealAtomValue(inst);  
         }  
         CONSOLE_DEBUG("Set var %d ('%s') to '%f'",i+1,tmp,in[i]);  
         ASC_FREE(tmp);  
     }  
   
     /* call the evaluation function */  
       
   
     /* push the current output values back into the instance hierarchy */  
   
     ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Blackbox not implemented, returning -1");  
     return -1;  
 }  
   
108    
109  ExtBBoxInitFunc * GetInitFunc(struct ExternalFunc *efunc)  ExtBBoxInitFunc * GetInitFunc(struct ExternalFunc *efunc)
110  {  {
# Line 189  ExtBBoxInitFunc * GetFinalFunc(struct Ex Line 122  ExtBBoxInitFunc * GetFinalFunc(struct Ex
122  ExtBBoxFunc *GetValueFunc(struct ExternalFunc *efunc)  ExtBBoxFunc *GetValueFunc(struct ExternalFunc *efunc)
123  {  {
124    asc_assert(efunc!=NULL);    asc_assert(efunc!=NULL);
125      AssertMemory(efunc->etype);
126    
127      CONSOLE_DEBUG("GETVALUEFUNC efunc = %p, type = %d",efunc,(int)efunc->etype);
128    asc_assert(efunc->etype == efunc_BlackBox);    asc_assert(efunc->etype == efunc_BlackBox);
129    /* return (ExtBBoxFunc *)efunc->value; */    /* return (ExtBBoxFunc *)efunc->value; */
130    return efunc->u.black.value;    return efunc->u.black.value;
# Line 364  ExtMethodRun *GetExtMethodRun(struct Ext Line 300  ExtMethodRun *GetExtMethodRun(struct Ext
300    REGISTRATION AND LOOKUP FUNCTIONS    REGISTRATION AND LOOKUP FUNCTIONS
301  */  */
302    
303  void DestroyExternalFunc(struct ExternalFunc *efunc)  void DestroyExternalFunc(struct ExternalFunc *efunc){
 {  
304    struct ExternalFunc *tmp;    struct ExternalFunc *tmp;
305    if (efunc) {    if(efunc){
306        CONSOLE_DEBUG("DESTROYING EFUNC at %p",efunc);
307      tmp = efunc;      tmp = efunc;
308      if (tmp->name ) ascfree((char *)(tmp->name)); /* we own the string */      if (tmp->name ) ascfree((char *)(tmp->name)); /* we own the string */
309      if (tmp->help) ascfree((char *)(tmp->help)); /* we own the string */      if (tmp->help) ascfree((char *)(tmp->help)); /* we own the string */
310      tmp->name = NULL;      tmp->name = NULL;
311      tmp->help = NULL;      tmp->help = NULL;
312  /* might want to set null pointers here depending on etype. */      /* might want to set null pointers here depending on etype. */
313      tmp->etype = efunc_ERR;      tmp->etype = efunc_ERR;
314      ascfree((char *)tmp);      ascfree((char *)tmp);
315    }    }
# Line 397  unsigned long NumberOutputArgs(CONST str Line 333  unsigned long NumberOutputArgs(CONST str
333    return efunc->n_outputs;    return efunc->n_outputs;
334  }  }
335    
336  /*  /*------------------------------------------------------------------------------
337   * These are the table management routines.    EXTERNALFUNCLIBRARY TABLE-MANAGEMENT ROUTINES
338   */  */
339    
340  void InitExternalFuncLibrary(void)  void InitExternalFuncLibrary(void)
341  {  {
# Line 408  void InitExternalFuncLibrary(void) Line 344  void InitExternalFuncLibrary(void)
344    ExternalFuncLibrary = result;    ExternalFuncLibrary = result;
345  }  }
346    
 int AddExternalFunc(struct ExternalFunc *efunc, int force)  
 {  
347    
348    struct ExternalFunc *found, *tmp;  int AddExternalFunc(struct ExternalFunc *efunc, int force){
349    char *name;      struct ExternalFunc *found, *tmp;
350        char *name;
351    
352    asc_assert(efunc!=NULL);      CONSOLE_DEBUG("efunc = %p",efunc);
353    name = (char *)efunc->name;      asc_assert(efunc!=NULL);
354    found = (struct ExternalFunc *)LookupTableData(ExternalFuncLibrary,name);  
355    if (found) {      /* function name already exists */      name = (char *)efunc->name;
356      if (force==0) {      found = (struct ExternalFunc *)LookupTableData(ExternalFuncLibrary,name);
357        return 0;      if(found){
358      } else {        /* need to update information */          /* function with this name already exists in the ExternalFuncLibrary */
359        tmp = (struct ExternalFunc *)RemoveTableData(ExternalFuncLibrary,name);          if(!force){
360        DestroyExternalFunc(tmp);              CONSOLE_DEBUG("EFUNC found OK, not adding");
361        AddTableData(ExternalFuncLibrary,(void *)efunc,name);              return 0;
362        return 1;          }
363      }  
364    }          /* force!=0, so we're requested to update the entry in the table */
365    else{         /* need to add function to library */          CONSOLE_DEBUG("EFUNC found OK, update forced");
366      AddTableData(ExternalFuncLibrary,(void *)efunc,name);          tmp = (struct ExternalFunc *)RemoveTableData(ExternalFuncLibrary,name);
367      return 1;          DestroyExternalFunc(tmp);
368    }          AddTableData(ExternalFuncLibrary,(void *)efunc,name);
369            return 1;
370        }else{
371            /* need to add function to library */
372            CONSOLE_DEBUG("EFUNC not found, adding pointer %p for efunc to table under name '%s'.",efunc,name);
373            AddTableData(ExternalFuncLibrary,(void *)efunc,name);
374            return 1;
375        }
376  }  }
377    
378    
379  struct ExternalFunc *LookupExtFunc(CONST char *funcname)  struct ExternalFunc *LookupExtFunc(CONST char *funcname)
380  {  {
381    struct ExternalFunc *found;    struct ExternalFunc *found;
382    if (!funcname) {    if (!funcname) {
383      return NULL;      return NULL;
384    }    }
385    found = (struct ExternalFunc *)    found = (struct ExternalFunc *)LookupTableData(ExternalFuncLibrary,funcname);
     LookupTableData(ExternalFuncLibrary,funcname);  
386    if (found) {    if (found) {
387        CONSOLE_DEBUG("Found '%s' in ExternalFuncLibrary at %p",funcname,found);
388      return found;      return found;
389    } else {    } else {
390      return NULL; /* name not found */      return NULL; /* name not found */

Legend:
Removed from v.709  
changed lines
  Added in v.710

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22