diff options
Diffstat (limited to '2.3-1/macros/CCodeGeneration/C_Funcall.sci')
-rw-r--r-- | 2.3-1/macros/CCodeGeneration/C_Funcall.sci | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/2.3-1/macros/CCodeGeneration/C_Funcall.sci b/2.3-1/macros/CCodeGeneration/C_Funcall.sci new file mode 100644 index 00000000..450ad088 --- /dev/null +++ b/2.3-1/macros/CCodeGeneration/C_Funcall.sci @@ -0,0 +1,467 @@ +function SharedInfo = C_Funcall(FunInfo,FileInfo,SharedInfo,FlagCall) +// function SharedInfo = C_Funcall(FunInfo,FileInfo,SharedInfo,FlagCall) +// ----------------------------------------------------------------- +// Get function for a generic SCI2C table. +// +// Input data: +// //NUT: add description here +// +// Output data: +// //NUT: add description here +// +// Status: +// 27-Oct-2007 -- Raffaele Nutricato: Author. +// +// Copyright 2007 Raffaele Nutricato. +// Contact: raffaele.nutricato@tiscali.it +// ----------------------------------------------------------------- + +// ------------------------------ +// --- Check input arguments. --- +// ------------------------------ +SCI2CNInArgCheck(argn(2),4,4); + +// ----------------------- +// --- Initialization. --- +// ----------------------- +nxtscifunname = SharedInfo.NextSCIFunName; +nxtscifunnumber = SharedInfo.NextSCIFunNumber; + +ReportFileName = FileInfo.Funct(nxtscifunnumber).ReportFileName; +CPass1FileName = FileInfo.Funct(nxtscifunnumber).CPass1FileName; +CPass1FreeFileName = FileInfo.Funct(nxtscifunnumber).CPass1FreeFileName; +HeaderFileName = FileInfo.Funct(nxtscifunnumber).Pass1HeaderFileName; +CDeclarationFileName = FileInfo.Funct(nxtscifunnumber).CDeclarationFileName; +CInitVarsFileName = FileInfo.Funct(nxtscifunnumber).CInitVarsFileName; +IndentLevel = SharedInfo.NIndent; +CCall = ''; +Target = SharedInfo.Target; +// --- Extract Function Info. --- +FunctionName = FunInfo.SCIFunctionName; +CFunName = FunInfo.CFunctionName; +InArg = FunInfo.InArg; +NInArg = FunInfo.NInArg; +OutArg = FunInfo.OutArg; +NOutArg = FunInfo.NOutArg; +PosFirstOutScalar = FunInfo.PosFirstOutScalar; + +// #RNU_RES_B +PrintStringInfo(' ',ReportFileName,'file','y'); +PrintStringInfo('***Generating C code***',ReportFileName,'file','y'); +// #RNU_RES_E +// --------------------------- +// --- End Initialization. --- +// --------------------------- + + +// -------------------------------------------------- +// --- Manage anticipated exit from the function. --- +// -------------------------------------------------- +if (SharedInfo.SkipNextFun > 0) + SharedInfo.SkipNextFun = SharedInfo.SkipNextFun - 1; + return; +end + +// #RNU_RES_B +// Exit if the function is a precision specifier and the corresponding flag is 1. +// #RNU_RES_E +if ((sum(mtlb_strcmp(FunctionName,SharedInfo.Annotations.DataPrec)) > 0) & ... + (SharedInfo.SkipNextPrec == 1)) + // #RNU_RES_B + PrintStringInfo(' Skipping code generating because already generated in the previous function.',ReportFileName,'file','y'); + // #RNU_RES_E + SharedInfo.SkipNextPrec = SharedInfo.SkipNextPrec - 1; + return; +end + +// #RNU_RES_B +// Exit if the function is OpEqual and the corresponding skip flag is enabled. +// #RNU_RES_E +if ((mtlb_strcmp(FunctionName,'OpEqual')) & ... + (SharedInfo.SkipNextEqual == 1)) + // #RNU_RES_B + PrintStringInfo(' Skipping code generating because already generated in the previous function.',ReportFileName,'file','y'); + // #RNU_RES_E + SharedInfo.SkipNextEqual = SharedInfo.SkipNextEqual - 1; + return; +end + +// #BJ +// size should be managed as other functions +// otherwise size(4) will lead to a C variable __4Size reference +// wich will never exists + +// #RNU_RES_B +// Exit if the function is size. +// #RNU_RES_E +// if ((mtlb_strcmp(FunctionName,'size'))) +// // #RNU_RES_B +// PrintStringInfo(' Anticipated exit for the size function.',ReportFileName,'file','y'); +// // #RNU_RES_E +// CCall =''; +// if (NInArg == 1) +// if (NOutArg == 1) +// CCall = CCall+OutArg(1).Name+'[0] = __'+InArg(1).Name+'Size[0];'; +// // #RNU_RES_B +// PrintStringInfo(' '+CCall,ReportFileName,'file','y'); +// // #RNU_RES_E +// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y'); + +// CCall =''; +// CCall = CCall+OutArg(1).Name+'[1] = __'+InArg(1).Name+'Size[1];'; +// // #RNU_RES_B +// PrintStringInfo(' '+CCall,ReportFileName,'file','y'); +// // #RNU_RES_E +// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y'); +// elseif (NOutArg == 2) +// CCall = CCall+OutArg(1).Name+' = __'+InArg(1).Name+'Size[0];'; +// // #RNU_RES_B +// PrintStringInfo(' '+CCall,ReportFileName,'file','y'); +// // #RNU_RES_E +// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y'); + +// CCall =''; +// CCall = CCall+OutArg(2).Name+' = __'+InArg(1).Name+'Size[1];'; +// // #RNU_RES_B +// PrintStringInfo(' '+CCall,ReportFileName,'file','y'); +// // #RNU_RES_E +// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y'); +// else +// SCI2Cerror('Don''t know how to manage size function with number of output args different from 1 and 2.'); +// end +// elseif (NInArg == 2) +// if (NOutArg == 1) +// if (InArg(2).Value == 1) +// CCall = CCall+OutArg(1).Name+' = __'+InArg(1).Name+'Size[0];'; +// // #RNU_RES_B +// PrintStringInfo(' '+CCall,ReportFileName,'file','y'); +// // #RNU_RES_E +// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y'); +// elseif (InArg(2).Value == 2) +// CCall = CCall+OutArg(1).Name+' = __'+InArg(1).Name+'Size[1];'; +// // #RNU_RES_B +// PrintStringInfo(' '+CCall,ReportFileName,'file','y'); +// // #RNU_RES_E +// PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y'); +// else +// SCI2Cerror('Not known the value of the second input arg for the size function.'); +// end +// else +// SCI2Cerror('Don''t know how to manage size function with number of output args different from 1.'); +// end +// else +// SCI2Cerror('Don''t know how to manage size function with number of input args different from 1 and 2.'); +// end +// return; +// end +// ------------------------------------------------------ +// --- End Manage anticipated exit from the function. --- +// ------------------------------------------------------ + +// #RNU_RES_B +// ------------------------------------------------------------ +// --- Allocate memory and size array for output arguments. --- +// ------------------------------------------------------------ +// #RNU_RES_E +if (FlagCall == 1) +// #RNU_RES_B +//RNU qui va tolto tutto una volta sicuri che la memallocout puo' essere fatta dentro la st_insoutarg +// C_MemAllocOutTempVars(OutArg,NOutArg,CPass1FileName,CPass1FreeFileName,IndentLevel,ReportFileName); +// #RNU_RES_E +end + +// ---------------------------- +// --- Generate the C call. --- +// ---------------------------- +CCall =''; +if(mtlb_strcmp(part(CFunName,1:9),'PI_thread') == %T) +//Functions that are to be ru in separate thread in case of RPi target, +//need to have specific name which is PI_THREAD(functionname) + +CCall = CCall + 'PI_THREAD('+CFunName+')' +else + + if (FunInfo.CFunctionName == SharedInfo.CMainFunName) + if (FlagCall == 1) + error(9999, 'main function called in a source code!'); + else + CCall =CCall+'int '; + end + elseif ((mtlb_strcmp(part(CFunName,1:5),'odefn') == %T)) + //Return type of function containing ODEs must be int. + CCall = CCall + 'int '; + else + if (PosFirstOutScalar >= 1) + if (FlagCall == 1) + CCall = CCall+OutArg(PosFirstOutScalar).Name+' = '; + else + CCall = CCall+C_Type(OutArg(PosFirstOutScalar).Type)+' '; + end + else + if (FlagCall == 0) + CCall = CCall+'void '; + end + end + end + + + // FIXME : Wrap library function call with prefixed name + + //if CFunName == "main" + CCall = CCall + CFunName + "("; + //else + // CCall = CCall+"SCI2C("+CFunName+")("; + //end + + // #RNU_RES_B + PrintStringInfo(' C call after output scalar args check: '+CCall,ReportFileName,'file','y'); + // #RNU_RES_E + clear counterin + if(mtlb_strcmp(part(CFunName,1:5),'odefn') == %F) + for counterin = 1:NInArg + + if (InArg(counterin).Type == 'g' & InArg(counterin).Scope == 'String') + TmpInArgName = '""'+InArg(counterin).Name+'""'; + elseif (InArg(counterin).Type == 'z' & (InArg(counterin).Scope == 'Number')) + TmpInArgName = 'DoubleComplex('+SCI2Cstring(real(InArg(counterin).Value))+','+SCI2Cstring(imag(InArg(counterin).Value))+')'; + elseif (InArg(counterin).Type == 'c' & (InArg(counterin).Scope == 'Number')) + TmpInArgName = 'FloatComplex('+SCI2Cstring(real(InArg(counterin).Value))+','+SCI2Cstring(imag(InArg(counterin).Value))+')'; + else + TmpInArgName = InArg(counterin).Name; + end + TmpInArgType = C_Type(InArg(counterin).Type); + + //if (FunctionName == 'OpEqual') + // TmpInArgSizeVar = '__'+OutArg(counterin).Name+'Size'; + // else + TmpInArgSizeVar = '__'+InArg(counterin).Name+'Size'; + //end + + if (InArg(counterin).Dimension == 0) + if (FlagCall == 0) + CCall = CCall+TmpInArgType+' '; + end + CCall = CCall+TmpInArgName+','; + else + if (FlagCall == 0) + CCall = CCall+TmpInArgType+'* '+TmpInArgName+', int* __'+TmpInArgName+'Size,'; + else + CCall = CCall+TmpInArgName+', '+TmpInArgSizeVar+','; + end + end + end + else + //If current function contains 'odefn' at the beginning, then it contains + //differnetial equations and its function call need to be differnt than + //other function call. GSL library being used for solving ODEs, requires + //function containing odes in specific format which is differnt than generated + //above. + for counterin = 1:NInArg + + //if((NInArg == 4 & counterin <> 3) | (NInArg == 5 & counterin <> 4)) //Skip third argument + if (InArg(counterin).Type == 'g' & InArg(counterin).Scope == 'String') + TmpInArgName = '""'+InArg(counterin).Name+'""'; + elseif (InArg(counterin).Type == 'z' & (InArg(counterin).Scope == 'Number')) + TmpInArgName = 'DoubleComplex('+SCI2Cstring(real(InArg(counterin).Value))+','+SCI2Cstring(imag(InArg(counterin).Value))+')'; + elseif (InArg(counterin).Type == 'c' & (InArg(counterin).Scope == 'Number')) + TmpInArgName = 'FloatComplex('+SCI2Cstring(real(InArg(counterin).Value))+','+SCI2Cstring(imag(InArg(counterin).Value))+')'; + else + TmpInArgName = InArg(counterin).Name; + end + + TmpInArgType = C_Type(InArg(counterin).Type); + + //if (FunctionName == 'OpEqual') + // TmpInArgSizeVar = '__'+OutArg(counterin).Name+'Size'; + // else + TmpInArgSizeVar = '__'+InArg(counterin).Name+'Size'; + //end + + if (InArg(counterin).Dimension == 0) + if (FlagCall == 0) + CCall = CCall+TmpInArgType+' '; + end + CCall = CCall+TmpInArgName+','; + else + if (FlagCall == 0) + CCall = CCall+TmpInArgType+'* '+TmpInArgName+', ';//int* __'+TmpInArgName+'Size,'; + else + CCall = CCall+TmpInArgName+', ';//+TmpInArgSizeVar+','; + end + end + //end + end + + end + + // #RNU_RES_B + PrintStringInfo(' C call after input args analysis: '+CCall,ReportFileName,'file','y'); + // #RNU_RES_E + for counterout = 1:NOutArg + TmpOutArgName = OutArg(counterout).Name; + TmpOutArgType = C_Type(OutArg(counterout).Type); + if (counterout == PosFirstOutScalar) + if (FlagCall == 0) + // #RNU_RES_B + // --- Write in the declaration file the returned output scalar (if any). --- + // #RNU_RES_E + outscalardeclaration = TmpOutArgType+' '+TmpOutArgName+';'; + // #RNU_RES_B + PrintStringInfo(outscalardeclaration,ReportFileName,'file','y'); + // #RNU_RES_E + PrintStringInfo(C_IndentBlanks(1)+outscalardeclaration,CDeclarationFileName,'file','y'); + PrintStringInfo(' ',CDeclarationFileName,'file','y'); + end + else + if (OutArg(counterout).Dimension == 0) + if (FlagCall == 0) + // --- Write in the declaration file the returned output scalar (if any). --- + outscalardeclaration = TmpOutArgType+' '+TmpOutArgName+';'; + PrintStringInfo(outscalardeclaration,ReportFileName,'file','y'); + PrintStringInfo(C_IndentBlanks(1)+outscalardeclaration,CDeclarationFileName,'file','y'); + PrintStringInfo(' ',CDeclarationFileName,'file','y'); + CCall = CCall+TmpOutArgType+'* __ptr'+TmpOutArgName+', '; + else + CCall = CCall+'&'+TmpOutArgName+', ';//NUT: verifica se ci vuole l'& + end + else + if (FlagCall == 0) + CCall = CCall+TmpOutArgType+'* '+TmpOutArgName+','; + if (OutArg(counterout).FindLike == 1) + CCall = CCall+'int* __'+TmpOutArgName+'Size'+','; + end + // #RNU_RES_B + //NUT prova a sostituire le variabili strutture con variabili dichiarate all'inizio del codice. + // --- Declare the size of the output arguments. --- + // #RNU_RES_E + outscalardeclaration = 'int __'+TmpOutArgName+'Size[2];'; + PrintStringInfo(outscalardeclaration,ReportFileName,'file','y'); + PrintStringInfo(C_IndentBlanks(1)+outscalardeclaration,CDeclarationFileName,'file','y'); + outscalardeclaration = '__'+TmpOutArgName+'Size[0] = '+(OutArg(counterout).Size(1))+';'; + PrintStringInfo(outscalardeclaration,ReportFileName,'file','y'); + PrintStringInfo(C_IndentBlanks(1)+outscalardeclaration,CInitVarsFileName,'file','y'); + outscalardeclaration = '__'+TmpOutArgName+'Size[1] = '+(OutArg(counterout).Size(2))+';'; + PrintStringInfo(outscalardeclaration,ReportFileName,'file','y'); + PrintStringInfo(C_IndentBlanks(1)+outscalardeclaration,CInitVarsFileName,'file','y'); + PrintStringInfo(' ',CInitVarsFileName,'file','y'); + else + CCall = CCall+OutArg(counterout).Name+','; + if (OutArg(counterout).FindLike == 1) + CCall = CCall+'(int* ) __'+TmpOutArgName+'Size'+','; + end + end + end + end + end + PrintStringInfo(' C call after output args analysis: '+CCall,ReportFileName,'file','y'); + // Remove the last " " and "," + if (part(CCall,length(CCall):length(CCall)) == ' ') + CCall = part(CCall,1:length(CCall)-1); + end + if (part(CCall,length(CCall):length(CCall)) == ',') + CCall = part(CCall,1:length(CCall)-1); + end + + //__ysize is added to input arguments at last to comply with form required by GSL + if(mtlb_strcmp(part(CFunName,1:5),'odefn') == %T) + CCall = CCall + ', int* '+TmpInArgSizeVar; + end + + CCall = CCall+')'; + if (FlagCall == 1) + CCall = CCall+';'; + end + +end +//NUT: la parte di generazione della C call va inserita in una funzione a parte. +//NUT: tale funzione deve avere anche uno switch che consenta di generare differenti versioni +//NUT: delle chiamate C in accordo con la libreria disponibile, fermo restando che +//NUT: e' sempre possibile fornire la lista delle macro. +if mtlb_strcmp(FunctionName,'return') + // Here I introduce the pointer assignment for output scalar arguments. + for cntout = 1:SharedInfo.CurrentFunInfo.NOutArg + if (cntout ~= SharedInfo.CurrentFunInfo.PosFirstOutScalar & ... + SharedInfo.CurrentFunInfo.OutArg(cntout).Dimension == 0) + CCall = ''; + CCall = CCall+'*__ptr'+SharedInfo.CurrentFunInfo.OutArg(cntout).Name+' = '+... + SharedInfo.CurrentFunInfo.OutArg(cntout).Name+';'; + PrintStringInfo(' '+CCall,ReportFileName,'file','y'); + PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y'); + end + end + // --- Then I free the memory dinamically allocated. --- + // ---------------------------- + // --- Handle Free section. --- + // ---------------------------- + PrintStringInfo(C_IndentBlanks(1)+'/*',CPass1FreeFileName,'file','y'); + PrintStringInfo(C_IndentBlanks(1)+'** ------------------------- ',CPass1FreeFileName,'file','y'); + PrintStringInfo(C_IndentBlanks(1)+'** --- End Free Section. --- ',CPass1FreeFileName,'file','y'); + PrintStringInfo(C_IndentBlanks(1)+'** ------------------------- ',CPass1FreeFileName,'file','y'); + PrintStringInfo(C_IndentBlanks(1)+'*/',CPass1FreeFileName,'file','y'); + PrintStringInfo(' ',CPass1FreeFileName,'file','y'); + SCI2Ccopyfile(CPass1FreeFileName,... + CPass1FileName,'append'); + // -------------------------------- + // --- End Handle Free section. --- + // -------------------------------- + + // --- Then I introduce the return to the first scalar output arguments. --- + CCall = ''; + // #RNU_RES_B + //NUT: non capisco questo skip a questo punto. + //NUT: perche' la return finale la sto gestendo nella AST_HandleEndProgram. + PrintStringInfo(' return function of the AST is skipped.',ReportFileName,'file','y'); + //RN provo a non skippare e a mettere la return. + // #RNU_RES_E + + if (SharedInfo.CurrentFunInfo.CFunctionName == SharedInfo.CMainFunName) + CCall = CCall+'return(0);'; + elseif (mtlb_strcmp(part(SharedInfo.CurrentFunInfo.CFunctionName,1:5),'odefn') == %T) + //For GSL library, function containing ODEs must return GSL_SUCCESS + CCall = CCall + 'return GSL_SUCCESS;' + else + if (SharedInfo.CurrentFunInfo.PosFirstOutScalar > 0) + CCall = CCall+'return('+SharedInfo.CurrentFunInfo.OutArg(SharedInfo.CurrentFunInfo.PosFirstOutScalar).Name+');' + end + end + // #RNU_RES_B + PrintStringInfo(' '+CCall,ReportFileName,'file','y'); + // #RNU_RES_E + PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y'); +else + // #RNU_RES_B + PrintStringInfo(' '+CCall,ReportFileName,'file','y'); + // #RNU_RES_E + PrintStringInfo(C_IndentBlanks(IndentLevel)+CCall,CPass1FileName,'file','y'); + if (FlagCall == 0) + // Add prototype to the header file + + C_InitHeader(CCall+';',HeaderFileName,SharedInfo.Sci2CLibMainHeaderFName,Target,SharedInfo.OpenCVUsed); + + // Add { at the beginning of the function. + PrintStringInfo(' {',ReportFileName,'file','y'); + PrintStringInfo(C_IndentBlanks(IndentLevel)+'{',CPass1FileName,'file','y'); + + end +end + +// #RNU_RES_B +// Add in the C code the new size of the output argument when SCI2Cresize function is called. +// #RNU_RES_E +if (FunctionName == 'SCI2Cresize') + // #RNU_RES_B + PrintStringInfo(' Found SCI2Cresize -> Changing the size of the output argument.',ReportFileName,'file','y'); + // #RNU_RES_E + OutArgName = OutArg(counterout).Name; + tmpcode = '__'+OutArgName+'Size[0]='+OutArg(counterout).Size(1)+';'; + PrintStringInfo(C_IndentBlanks(IndentLevel)+tmpcode,CPass1FileName,'file','y'); + // #RNU_RES_B + PrintStringInfo(' '+tmpcode,ReportFileName,'file','y'); + // #RNU_RES_E + tmpcode = '__'+OutArgName+'Size[1]='+OutArg(counterout).Size(2)+';'; + PrintStringInfo(C_IndentBlanks(IndentLevel)+tmpcode,CPass1FileName,'file','y'); + // #RNU_RES_B + PrintStringInfo(' '+tmpcode,ReportFileName,'file','y'); + // #RNU_RES_E +end +endfunction |