crerhs.c

Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include "intersci-n.h"
00003 #include "crerhs.h"
00004 
00005 /*****************************************************************
00006  * For each possible data type we have here a function 
00007  * which generate the code for <<Creating>> a variable 
00008  * and checking some properties 
00009  *     if needed check if the variable is square 
00010  *     if needed check if some dimensions must be of fixed sizes
00011  * All the possible Getfunction are stored in a function table 
00012  ******************************************************************/
00013 
00014 /**************************************************
00015  * A FINIR : 
00016  * le code qui est ici est utilise a deux fins 
00017  * Creer des objets ds le stack Scilab 
00018  * et construire en meme temps 
00019  * la sequence d'appel pour 
00020  * le Fortran 
00021  * Il faudrait sans doute couper cela en deux 
00022  * et surtout voir si l'on ne peux pas simplifier 
00023  * le tout : 
00024  *   i.e associer a une variable 
00025  *   des formats qui indiquent comment 
00026  *   on accede aux champs importants pour elle 
00027  *   + un numero unique de variable 
00028  *   un numero ds le stacl etc......
00029  **************************************************/
00030 
00031 /******************************************************
00032  * the functions in the following table must follow  the 
00033  * order given by the type list defined in  intersci-n.h 
00034  * The correct ordering is checked when using this table.
00035  * (see intersci.c) 
00036  ********************************************************/
00037 
00038 CreRhsTab CRERHSTAB[] = {
00039   {DIMFOREXT,CreDIMFOREXT},
00040   {COLUMN,CreCOLUMN},
00041   {LIST,CreANY},
00042   {TLIST,CreANY},
00043   {MATRIX,CreMATRIX},
00044   {POLYNOM,CreVECTOR},
00045   {ROW,CreVECTOR},
00046   {SCALAR,CreSCALAR},
00047   {SEQUENCE,CreANY},
00048   {STRING,CreSTRING},
00049   {WORK,CreVECTOR},
00050   {EMPTY,CreANY},
00051   {ANY,CreANY},
00052   {VECTOR,CreVECTOR},
00053   {STRINGMAT,CreSTRINGMAT},
00054   {SCIMPOINTER,CrePOINTER},
00055   {IMATRIX,CreIMATRIX},
00056   {SCISMPOINTER,CrePOINTER},
00057   {SCILPOINTER,CrePOINTER},
00058   {BMATRIX,CreBMATRIX},
00059   {SCIBPOINTER,CrePOINTER},
00060   {SCIOPOINTER,CrePOINTER},
00061   {SPARSE,CreSPARSE}
00062 };
00063 
00064 
00065 
00066 extern  int indent ; /* incremental counter for code indentation */
00067 extern  int pass;  /* flag for couting pass on code generation */
00068 
00069 static  char str[MAXNAM];
00070 static char str1[MAXNAM];
00071 static char str2[MAXNAM];
00072 static char str3[MAXNAM];
00073 static char str4[MAXNAM];
00074 
00075 /***********************************************
00076  * Matrix  XXXXX OK 
00077  ***********************************************/
00078 
00079 void CreMATRIX(f,var)
00080      FILE *f;
00081      VARPTR var;
00082 {
00083   WriteCallRestCheck(f,var,"mm",1,0) ;
00084   GetDim(str3,var->el[1]);
00085   WriteCallRestCheck(f,var,"nn",0,0) ;
00086   GetDim(str4,var->el[0]);
00087   if ( str3[0] == '&' || str3[0] == '(') 
00088     sprintf(str2,"%s",str3);
00089   else 
00090     sprintf(str2,"&%s",str3);
00091   if ( str4[0] == '&' || str4[0] == '(') 
00092     sprintf(str1,"%s",str4);
00093   else 
00094     sprintf(str1,"&%s",str4);
00095   CreCommon(f,var);
00096 }
00097 
00098 void CreCommon(f,var)
00099      FILE *f;
00100      VARPTR var;
00101 {
00102   if (var->for_type == EXTERNAL ) 
00103     {
00104       Fprintf(f,indent,"/* external variable named %s (xxe%d) */\n",var->name,var->stack_position);
00105       AddDeclare1(DEC_INT,"me%d",var->stack_position);
00106       AddDeclare1(DEC_INT,"ne%d",var->stack_position);
00107        if ( strncmp(var->fexternal,"cintf",4)==0 ) 
00108          AddDeclare1(DEC_IPTR,"le%d",var->stack_position);
00109        else if ( strncmp(var->fexternal,"cboolf",5)==0 ) 
00110          AddDeclare1(DEC_IPTR,"le%d",var->stack_position);
00111        else if ( strncmp(var->fexternal,"cdoublef",7)==0 ) 
00112          AddDeclare1(DEC_DPTR,"le%d",var->stack_position);
00113        else if (strncmp(var->fexternal,"ccharf",5)==0) 
00114          AddDeclare1(DEC_CPTR,"le%d",var->stack_position);
00115        else if (strncmp(var->fexternal,"cfloatf",6)==0 ) 
00116          AddDeclare1(DEC_RPTR,"le%d",var->stack_position);
00117        else 
00118          AddDeclare1(DEC_UL,"le%d",var->stack_position);
00119        ChangeForName2(var,"&le%d",var->stack_position);
00121     } 
00122    else 
00123      {
00124        char *lstr1,*lstr2;
00125        if ( strncmp(str1,"&istk(",6)==0 || strncmp(str1,"&cstk(",6)==0 || strncmp(str1,"&rstk(",6)==0 
00126             || strncmp(str1,"&stk(",5)==0 ) lstr1 = str1+1;
00127        else
00128          lstr1=str1;
00129        if ( strncmp(str2,"&istk(",6)==0 || strncmp(str2,"&cstk(",6)==0 || strncmp(str2,"&rstk(",6)==0 
00130             || strncmp(str2,"&stk(",5)==0 ) lstr2 = str2+1;
00131        else
00132          lstr2=str2;
00133 
00134        Fprintf(f,indent,"CreateVar(%d,\"%s\",%s,%s,&l%d);/* named: %s */\n",
00135                var->stack_position,
00136                SGetForTypeAbrev(var),
00137                lstr1,lstr2,var->stack_position,
00138                var->name);
00139        AddDeclare1(DEC_INT,"l%d",var->stack_position);
00140        ChangeForName2(var,"%s(l%d)",SGetForTypeStack(var),
00141                       var->stack_position);
00142      }
00143 }
00144 
00145 /***********************************************
00146  * String   XXXXX OK 
00147  ***********************************************/
00148 
00149 void CreSTRING(f,var)
00150      FILE *f;
00151      VARPTR var;
00152 {
00153   if (var->for_type != CHAR && var->for_type != EXTERNAL ) 
00154     {
00155       printf("incompatibility between the type %s and FORTRAN type %s for variable \"%s\"\n",
00156              SGetSciType(STRING),SGetForType(var->for_type),var->name);
00157       exit(1);
00158     }
00159   AddDeclare1(DEC_INT,"n%d",var->stack_position);
00160   AddDeclare1(DEC_INIT,"n%d=1",var->stack_position);
00161   sprintf(str2,"&n%d",var->stack_position);
00162   WriteCallRestCheck(f,var,"nn",0,0) ;
00163   GetDim(str1,var->el[0]);
00164   CreCommon(f,var);
00165 }
00166 
00167 
00168 
00169 /***********************************************
00170  * Boolean matrix  XXXXX OK 
00171  ***********************************************/
00172 
00173 void CreBMATRIX(f,var)
00174      FILE *f;
00175      VARPTR var;
00176 {
00177   if (var->for_type == INT ) var->for_type = BOOLEAN;
00178   if (var->for_type != BOOLEAN && var->for_type != EXTERNAL )
00179     {
00180       printf("incompatibility between the type %s and FORTRAN type %s for variable \"%s\"\n",
00181              SGetSciType(var->type),SGetForType(var->for_type),var->name);
00182       exit(1);
00183     }
00184   CreMATRIX(f,var);
00185 }
00186 
00187 /***********************************************
00188  * variable which are dimensions 
00189  * (of Scilab variables or external)
00190  ***********************************************/
00191 
00192 void CreDIMFOREXT(f,var)
00193      FILE *f;
00194      VARPTR var;
00195 {
00196   if (var->nfor_name == 0 && var->for_type != PREDEF) 
00197     {
00198       printf("dimension variable \"%s\" is not defined\n",var->name);
00199       exit(1);
00200     }
00201   switch (var->for_type) 
00202     {
00203     case PREDEF:
00204     case 'C':
00205       if ( strcmp(var->name,"rhs") == 0) 
00206         {
00207           AddDeclare(DEC_INT,"rhs");
00208           Fprintf(f,indent,"rhs=Rhs;\n");
00209           sprintf(str,"&rhs");
00210         }
00211       else 
00212         {
00213           sprintf(str,"&%s",var->name);
00214         }
00215       ChangeForName1(var,str);
00216       break;
00217     case 0:
00218     case INT:
00219       sprintf(str,"&%s",var->for_name[0]);
00220       if ( ~isdigit(str[1])) 
00221         {
00222           ChangeForName1(var,str);
00223         }
00224       else 
00225         {
00226           Fprintf(f,indent,"loc%s= (int) %s;\n",
00227                   var->for_name[0],var->for_name[0]);
00228           sprintf(str,"loc%s",var->for_name[0]);
00229           AddDeclare(DEC_INT,str);
00230           sprintf(str,"&loc%s",var->for_name[0]);
00231           ChangeForName1(var,str);
00232         }
00233       break;
00234     case DOUBLE:
00235       Fprintf(f,indent,"loc%s= (double) %s;\n",
00236               var->for_name[0],var->for_name[0]);
00237       sprintf(str,"loc%s",var->for_name[0]);
00238       AddDeclare(DEC_DOUBLE,str);
00239       sprintf(str,"&loc%s",var->for_name[0]);
00240       ChangeForName1(var,str);
00241       break;
00242     case REAL:
00243       Fprintf(f,indent,"loc%s= (float) %s;\n",var->for_name[0],var->for_name[0]);
00244       sprintf(str,"loc%s",var->for_name[0]);
00245       AddDeclare(DEC_REAL,str);
00246       sprintf(str,"&loc%s",var->for_name[0]);
00247       ChangeForName1(var,str);
00248       break;
00249     case CHAR:
00250     case CSTRINGV:
00251       printf("a dimension variable cannot have FORTRAN type \"%s\"\n",
00252              SGetForType(var->for_type));
00253       exit(1);
00254       break;
00255     }
00256 }
00257 
00258 /***********************************************
00259  * Common code for COLUMN, ROW, WORK,POLYNOM,VECTOR
00260  ***********************************************/
00261 
00262 void CreVECTOR(f,var)
00263      FILE *f;
00264      VARPTR var;
00265 {
00266   char *lstr1 ;
00267   WriteCallRestCheck(f,var,"nn",0,0) ;
00268   GetDim(str1,var->el[0]);
00269   AddDeclare1(DEC_INT,"un=1");
00270   AddDeclare1(DEC_INT,"mn%d",var->stack_position);
00271   lstr1 = ( str1[0]== '&' )? str1+1: str1;
00273   if ( strncmp(lstr1,"stk",3) ==0 || strncmp(lstr1,"istk",4)==0 
00274        || strncmp(lstr1,"rstk",4)==0 || strncmp(lstr1,"cstk",4)==0 )
00275     sprintf(str2,"(mn%d=*%s,&mn%d)",var->stack_position,
00276             lstr1,var->stack_position);
00277   else
00278     sprintf(str2,"(mn%d=%s,&mn%d)",var->stack_position,
00279             lstr1,var->stack_position);
00280   strcpy(str1,"(un=1,&un)");
00281   CreCommon(f,var);
00282 }
00283 
00284 void CreCOLUMN(f,var)
00285      FILE *f;
00286      VARPTR var;
00287 {
00288   char *lstr1 ;
00289   WriteCallRestCheck(f,var,"nn",0,0) ;
00290   GetDim(str1,var->el[0]);
00291   AddDeclare1(DEC_INT,"un=1");
00292   AddDeclare1(DEC_INT,"mn%d",var->stack_position);
00293   lstr1 = ( str1[0]== '&' )? str1+1: str1;
00295   if ( strncmp(lstr1,"stk",3) ==0 || strncmp(lstr1,"istk",4)==0 
00296        || strncmp(lstr1,"rstk",4)==0 || strncmp(lstr1,"cstk",4)==0 )
00297     sprintf(str2,"(mn%d=*%s,&mn%d)",var->stack_position,
00298             lstr1,var->stack_position);
00299   else
00300     sprintf(str2,"(mn%d=%s,&mn%d)",var->stack_position,
00301             lstr1,var->stack_position);
00302   strcpy(str1,str2);
00303   strcpy(str2,"(un=1,&un)");
00304   CreCommon(f,var);
00305 }
00306 
00307 
00308 /***********************************************
00309  * Sparse OK
00310  ***********************************************/
00311 
00312 void CreSPARSE(f,var)
00313      FILE *f;
00314      VARPTR var;
00315 {
00316   WriteCallRestCheck(f,var,"mm",1,0) ;
00317   GetDim(str2,var->el[1]);
00318   WriteCallRestCheck(f,var,"nn",0,0) ;
00319   GetDim(str1,var->el[0]);
00320   if (var->for_type == EXTERNAL) 
00321     {
00322       AddDeclare1(DEC_SPARSEPTR,"S%d",var->stack_position);
00323       ChangeForName2(var,"&S%d",var->stack_position);
00325     } 
00326   else 
00327     {
00328       VARPTR m,n;
00329       int origm,orign;
00330       m= variables[var->el[0]-1];
00331       n= variables[var->el[1]-1];
00332       /* here we must create a sparse variable 
00333        * but str1 and str2 is not enough to create the matrix 
00334        * we copy the argument which gives the size 
00335        */
00336       origm = ( m->nfor_name == 0)? -1 : m->for_name_orig[0];
00337       orign = ( n->nfor_name == 0)? -1 : n->for_name_orig[0];
00338       if ( origm != orign ) 
00339         {
00340           fprintf(stderr,"A local sparse matrix can only be built as a copy of a sparse entry\n");
00341           exit(1);
00342         }
00343       AddDeclare1(DEC_SPARSE,"S%d",var->stack_position);
00344       Fprintf(f,indent,"CreateVarFromPtr(%d,\"s\",&%s,&%s,&S%d);\n",
00345               var->stack_position,
00346               str1,str2,origm);
00347       Fprintf(f,indent,"GetRhsVar(%d,\"s\",&%s,&%s,&S%d);\n",
00348               var->stack_position,
00349               str1,str2,var->stack_position);
00350       ChangeForName2(var,"&S%d",var->stack_position);
00351     }
00352 }
00353 
00354 
00355 /***********************************************
00356  * Complex Matrix OK 
00357  ***********************************************/
00358 
00359 void CreIMATRIX(f,var)
00360      FILE *f;
00361      VARPTR var;
00362 {
00363   WriteCallRestCheck(f,var,"it",2,0) ;
00364   GetDim(str3,var->el[2]);
00365   WriteCallRestCheck(f,var,"mm",1,0) ;
00366   GetDim(str2,var->el[1]);
00367   WriteCallRestCheck(f,var,"nn",0,0) ;
00368   GetDim(str1,var->el[0]);
00369   if (var->for_type == EXTERNAL) 
00370     {
00371       AddDeclare1(DEC_UL,"ler%d",var->stack_position);
00372       AddDeclare1(DEC_UL,"lec%d",var->stack_position);
00373       AddDeclare1(DEC_INT,"ite%d",var->stack_position);
00374       ChangeForName2(var,"&ler%d,&lec%d,&ite%d",var->stack_position,var->stack_position,var->stack_position);
00376     } 
00377   else 
00378     {
00379       Fprintf(f,indent,"CreateCVar(%d,\"%s\",&%s,&%s,&%s,&lr%d,&lc%d);\n",
00380               var->stack_position,SGetForTypeAbrev(var),
00381               str3,str1,str2,var->stack_position,var->stack_position);
00382       AddDeclare1(DEC_INT,"lr%d",var->stack_position);
00383       AddDeclare1(DEC_INT,"lc%d",var->stack_position);
00384       AddDeclare1(DEC_INT,"it%d",var->stack_position);
00385       ChangeForName2(var,"%s(lr%d),%s(lc%d),&it%d",
00386                      SGetForTypeStack(var),
00387                      var->stack_position, 
00388                      SGetForTypeStack(var),
00389                      var->stack_position,var->stack_position);
00390     }
00391 }
00392 
00393 
00394 /***********************************************
00395  * Pointers 
00396  ***********************************************/
00397 
00398 void CrePOINTER(f,var)
00399      FILE *f;
00400      VARPTR var;
00401 {
00402   if (var->for_type == EXTERNAL) 
00403     {
00404       AddDeclare1(DEC_UL,"le%d",var->stack_position);
00405       ChangeForName2(var,"&le%d",var->stack_position);
00407     } 
00408   else 
00409     {
00410       Fprintf(f,indent,"CreateOpointer(%d,&lr%d);\n",
00411               var->stack_position,var->stack_position);
00412       AddDeclare1(DEC_INT,"lr%d",var->stack_position);
00413       ChangeForName2(var,"stk(lr%d)",
00414                      var->stack_position);
00415     }
00416 }
00417 
00418 
00419 /***********************************************
00420  * STRINGMAT
00421  ***********************************************/
00422 
00423 void CreSTRINGMAT(f,var)
00424      FILE *f;
00425      VARPTR var;
00426 {
00427   if (var->for_type == EXTERNAL || var->for_type == CSTRINGV )
00428     {
00429       /* for external or cstringv parameters, unknown formal dimensions 
00430          can be used */
00431       WriteCallRestCheck(f,var,"nsmm",0,1) ;
00432       WriteCallRestCheck(f,var,"nsnn",1,1) ;
00433       sprintf(str,"nsmm%d",var->stack_position);
00434       AddForName1(var->el[0],str,NULL,var->stack_position);
00435       sprintf(str,"nsnn%d",var->stack_position);
00436       AddForName1(var->el[1],str,NULL,var->stack_position);
00437       AddDeclare1(DEC_SMAT,"Str%d",var->stack_position);
00438       AddDeclare1(DEC_INT,"nsmm%d",var->stack_position);
00439       AddDeclare1(DEC_INT,"nsnn%d",var->stack_position);
00440       sprintf(str,"&Str%d",var->stack_position);
00441       ChangeForName1(var,str);
00442     }
00443   else 
00444     {
00446       fprintf(stderr,"WARNING : your code contains a specification \n");
00447       fprintf(stderr," not fully implemented in intersci \n");
00448       WriteCallRestCheck(f,var,"mm",0,0) ;
00449       WriteCallRestCheck(f,var,"nn",1,0) ;
00450       AddDeclare(DEC_LOGICAL,"cresmatafaire");
00451       Fprintf(f,indent,"if(.not.cresmatafaire(fname,top-rhs+%d,lr%d)) return\n",var->stack_position,var->stack_position);
00452       sprintf(str,"stk(lr%d)",var->stack_position);
00453       ChangeForName1(var,str);
00454     }
00455 }
00456 
00457 
00458 /***********************************************
00459  * Scalar 
00460  ***********************************************/
00461 
00462 void CreSCALAR(f,var)
00463      FILE *f;
00464      VARPTR var;
00465 {
00466   strcpy(str1,"&un");
00467   strcpy(str2,"&un");
00468   AddDeclare(DEC_INT,"un=1");
00469   CreCommon(f,var);
00470 }
00471 
00472 /***********************************************
00473  ** Common code for LIST TLIST SEQUENCE ANY **
00474  ***********************************************/
00475 
00476 void CreANY(f,var)
00477      FILE *f;
00478      VARPTR var;
00479 {
00480   printf("work or output FORTRAN argument cannot have\n");
00481   printf("  type \"ANY\", \"LIST\", \"TLIST\" or \"SEQUENCE\"\n");
00482   exit(1);
00483 }
00484 
00485 /***********************************************
00486  * Utility function for WriteCallRest 
00487  * when flag==1 we acccept undefined dimensions 
00488  * this is used with stringmat/Cstringv 
00489  * where dimensions and space are allocated inside 
00490  * the interfaced function and returned 
00491  * to the interface 
00492  *******************************************/
00493 
00494 void WriteCallRestCheck(FILE *f,VARPTR var,char *name,int iel,int flag) 
00495 {
00496   char sdim[MAXNAM]; 
00497   char lstr[MAXNAM];
00498   if (variables[var->el[iel]-1]->nfor_name == 0) 
00499     {
00500       strcpy(lstr,variables[var->el[iel]-1]->name);
00501       if (isdigit(lstr[0]) == 0) 
00502         {
00503           if ( variables[var->el[iel]-1]->is_sciarg == 1) 
00504             {
00505               /* dimension of FORTRAN argument is a SCILAB argument */
00506               sprintf(sdim,"%s%d",name,var->stack_position);
00507               Fprintf(f,indent,"%s= (int) *stk(lr%d));\n",sdim,
00508                       variables[var->el[iel]-1]->stack_position);
00509               AddForName1(var->el[iel],sdim,NULL,var->stack_position);
00510             }
00511           else if ( flag != 1) 
00512             {
00513               printf("dimension variable \"%s\" is not defined\n",
00514                      variables[var->el[iel]-1]->name);
00515               exit(1);
00516             }
00517         } 
00518       else 
00519         {
00520           sprintf(sdim,"%s%d",name,var->stack_position);
00521           Fprintf(f,indent,"%s=%s;\n",sdim,lstr);
00522           AddForName1(var->el[iel],sdim,NULL,var->stack_position);
00523         }
00524     }
00525 }
00526 
00529 void GetDim(char *lstr,IVAR ivar) 
00530 {
00531   char *s;
00532   s=Forname2Int(variables[ivar-1],0);
00533   if ( strncmp(s,"stk",3)==0 || strncmp(s,"istk",4)==0
00534        || strncmp(s,"sstk",4)==0 || strncmp(s,"stk",3)==0 || 
00535        strncmp(s,"cstk",4)==0 )
00536     {
00537       sprintf(lstr,"%s",s);
00538       return ;
00539     }
00540   else 
00541     {
00542       AddDeclare1(DEC_INT,s);
00543       sprintf(lstr,"%s",s);
00544     }
00545 }
00546 
00547 

Generated on Sun Mar 4 15:03:57 2007 for Scilab [trunk] by  doxygen 1.5.1