mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-22 17:12:55 +08:00
339 lines
9.5 KiB
C
339 lines
9.5 KiB
C
|
#include "PikaObj.h"
|
||
|
#include "dataArgs.h"
|
||
|
#include "dataMemory.h"
|
||
|
#include "dataString.h"
|
||
|
#include "dataStrs.h"
|
||
|
#include <stdarg.h>
|
||
|
|
||
|
static int32_t loadArgByType(PikaObj *self,
|
||
|
char *definedName,
|
||
|
char *definedType,
|
||
|
char *sourceArgPath,
|
||
|
Args *args)
|
||
|
{
|
||
|
if (strEqu(definedType, "any"))
|
||
|
{
|
||
|
if (0 == obj_getAnyArg(self, definedName, sourceArgPath, args))
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
/* solve arg faild */
|
||
|
return 3;
|
||
|
}
|
||
|
if (strEqu(definedType, "str"))
|
||
|
{
|
||
|
/* solve the string type */
|
||
|
char *directStr = strsGetDirectStr(args, sourceArgPath);
|
||
|
if (NULL != directStr)
|
||
|
{
|
||
|
/* direct value */
|
||
|
args_setStr(args, definedName, directStr);
|
||
|
/* ok */
|
||
|
return 0;
|
||
|
}
|
||
|
/* reference value */
|
||
|
char *refStr = obj_getStr(self, sourceArgPath);
|
||
|
if (NULL == refStr)
|
||
|
{
|
||
|
/* faild */
|
||
|
return 1;
|
||
|
}
|
||
|
args_setStr(args, definedName, refStr);
|
||
|
/* succeed */
|
||
|
return 0;
|
||
|
}
|
||
|
if (strEqu(definedType, "int"))
|
||
|
{
|
||
|
/* solve the int32_t type */
|
||
|
args_setInt(args, definedName, 0);
|
||
|
if ((sourceArgPath[0] >= '0') && (sourceArgPath[0] <= '9'))
|
||
|
{
|
||
|
/* direct value */
|
||
|
args_set(args, definedName, sourceArgPath);
|
||
|
/* succeed */
|
||
|
return 0;
|
||
|
}
|
||
|
/* reference value */
|
||
|
if (!obj_isArgExist(self, sourceArgPath))
|
||
|
{
|
||
|
/* can not get reference */
|
||
|
return 3;
|
||
|
}
|
||
|
int32_t referenceVal = obj_getInt(self, sourceArgPath);
|
||
|
args_setInt(args, definedName, referenceVal);
|
||
|
/* succeed */
|
||
|
return 0;
|
||
|
}
|
||
|
if (strEqu(definedType, "float"))
|
||
|
{
|
||
|
/* solve the float type */
|
||
|
args_setFloat(args, definedName, 0);
|
||
|
if ((sourceArgPath[0] >= '0') && (sourceArgPath[0] <= '9'))
|
||
|
{
|
||
|
/* direct value */
|
||
|
args_set(args, definedName, sourceArgPath);
|
||
|
/* succeed */
|
||
|
return 0;
|
||
|
}
|
||
|
/* reference value */
|
||
|
if (!obj_isArgExist(self, sourceArgPath))
|
||
|
{
|
||
|
/* can not get reference */
|
||
|
return 3;
|
||
|
}
|
||
|
float referenceVal = obj_getFloat(self, sourceArgPath);
|
||
|
args_setFloat(args, definedName, referenceVal);
|
||
|
/* succeed */
|
||
|
return 0;
|
||
|
}
|
||
|
if (strEqu(definedType, "pointer"))
|
||
|
{
|
||
|
/* only support reference value */
|
||
|
if (!obj_isArgExist(self, sourceArgPath))
|
||
|
{
|
||
|
/* can not get reference */
|
||
|
return 3;
|
||
|
}
|
||
|
void *ptr = obj_getPtr(self, sourceArgPath);
|
||
|
args_setPtr(args, definedName, ptr);
|
||
|
return 0;
|
||
|
}
|
||
|
/* type match faild */
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
char *getTypeVal(Args *buffs, char *typeToken)
|
||
|
{
|
||
|
if (!strIsContain(typeToken, ':'))
|
||
|
{
|
||
|
return strsCopy(buffs, "");
|
||
|
}
|
||
|
return strsGetLastToken(buffs, typeToken, ':');
|
||
|
}
|
||
|
|
||
|
static Args *getArgsByNameMatch(PikaObj *self, char *typeList, char *argList)
|
||
|
{
|
||
|
Args *buffs = New_strBuff();
|
||
|
char *typeListBuff = strsCopy(buffs, typeList);
|
||
|
Args *args = New_args(NULL);
|
||
|
while (1)
|
||
|
{
|
||
|
char *typeToken = strsPopToken(buffs, typeListBuff, ',');
|
||
|
/* poped all type from typeList */
|
||
|
if (0 == typeToken[0])
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
char *typeName = strsGetFirstToken(buffs, typeToken, ':');
|
||
|
char *typeVal = getTypeVal(buffs, typeToken);
|
||
|
|
||
|
char *argListBuff = strsCopy(buffs, argList);
|
||
|
while (1)
|
||
|
{
|
||
|
char *argToken = strsPopToken(buffs, argListBuff, ',');
|
||
|
char *argName = strsGetFirstToken(buffs, argToken, '=');
|
||
|
char *argVal = strsGetLastToken(buffs, argToken, '=');
|
||
|
|
||
|
if (0 == argToken[0])
|
||
|
{
|
||
|
/* arg poped finised */
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (!strEqu(typeName, argName))
|
||
|
{
|
||
|
/* name not match */
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (0 != loadArgByType(self,
|
||
|
typeName,
|
||
|
typeVal,
|
||
|
argVal,
|
||
|
args))
|
||
|
{
|
||
|
args_deinit(args);
|
||
|
args_deinit(buffs);
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
args_deinit(buffs);
|
||
|
return args;
|
||
|
}
|
||
|
|
||
|
static Args *getArgsBySort(PikaObj *self, char *typeList, char *argList)
|
||
|
{
|
||
|
Args *buffs = New_strBuff();
|
||
|
char *typeListBuff = strsCopy(buffs, typeList);
|
||
|
char *argListBuff = strsCopy(buffs, argList);
|
||
|
Args *args = New_args(NULL);
|
||
|
while (1)
|
||
|
{
|
||
|
char *typeToken = strsPopToken(buffs, typeListBuff, ',');
|
||
|
char *argToken = strsPopToken(buffs, argListBuff, ',');
|
||
|
if ((0 == argToken[0]) || (0 == typeToken[0]))
|
||
|
{
|
||
|
/* arg or type poped finised */
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
char *typeName = strsGetFirstToken(buffs, typeToken, ':');
|
||
|
char *typeVal = getTypeVal(buffs, typeToken);
|
||
|
char *argPath = argToken;
|
||
|
|
||
|
if (0 != loadArgByType(self,
|
||
|
typeName,
|
||
|
typeVal,
|
||
|
argPath,
|
||
|
args))
|
||
|
{
|
||
|
args_deinit(args);
|
||
|
args_deinit(buffs);
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
args_deinit(buffs);
|
||
|
return args;
|
||
|
}
|
||
|
|
||
|
static Args *getArgsBySentence(PikaObj *self, char *typeList, char *argList)
|
||
|
{
|
||
|
if (strIsContain(argList, '='))
|
||
|
{
|
||
|
return getArgsByNameMatch(self, typeList, argList);
|
||
|
}
|
||
|
return getArgsBySort(self, typeList, argList);
|
||
|
}
|
||
|
|
||
|
static char *getMethodDeclearation(PikaObj *obj, char *methodName)
|
||
|
{
|
||
|
Args *buffs = New_strBuff();
|
||
|
char *methodDeclearationPath = strsAppend(buffs, "[md]", methodName);
|
||
|
char *res = obj_getStr(obj, methodDeclearationPath);
|
||
|
args_deinit(buffs);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
static void *getMethodPtr(PikaObj *methodHost, char *methodName)
|
||
|
{
|
||
|
Args *buffs = New_strBuff();
|
||
|
char *methodPtrPath = strsAppend(buffs, "[mp]", methodName);
|
||
|
void *res = obj_getPtr(methodHost, methodPtrPath);
|
||
|
args_deinit(buffs);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
Args *obj_invoke(PikaObj *self, char *cmd)
|
||
|
{
|
||
|
/* the Args returned need to be deinit */
|
||
|
Args *res = New_args(NULL);
|
||
|
args_setErrorCode(res, 0);
|
||
|
Args *buffs = New_strBuff();
|
||
|
char *methodToken = strsGetFirstToken(buffs, cmd, '(');
|
||
|
char *methodPath = methodToken;
|
||
|
Args *args = NULL;
|
||
|
|
||
|
PikaObj *methodHostObj = obj_getObj(self, methodPath, 1);
|
||
|
PikaObj *methodHostClass = NULL;
|
||
|
if (NULL == methodHostObj)
|
||
|
{
|
||
|
/* error, not found object */
|
||
|
args_setErrorCode(res, 1);
|
||
|
args_setSysOut(res, "[error] runner: object no found.");
|
||
|
goto exit;
|
||
|
}
|
||
|
char *methodName = strsGetLastToken(buffs, methodPath, '.');
|
||
|
|
||
|
void *classPtr = obj_getPtr(methodHostObj, "_clsptr");
|
||
|
char *methodHostClassName = strsAppend(buffs, "classObj-", obj_getName(methodHostObj));
|
||
|
methodHostClass = obj_getClassObjByNewFun(methodHostObj, methodHostClassName, classPtr);
|
||
|
/* get method Ptr */
|
||
|
void (*methodPtr)(PikaObj * self, Args * args) = getMethodPtr(methodHostClass, methodName);
|
||
|
char *methodDecInClass = getMethodDeclearation(methodHostClass, methodName);
|
||
|
/* assert method*/
|
||
|
if ((NULL == methodDecInClass) || (NULL == methodPtr))
|
||
|
{
|
||
|
/* error, method no found */
|
||
|
args_setErrorCode(res, 2);
|
||
|
args_setSysOut(res, "[error] runner: method no found.");
|
||
|
goto exit;
|
||
|
}
|
||
|
char *methodDec = strsCopy(buffs, methodDecInClass);
|
||
|
/* free method host class to save memory */
|
||
|
obj_deinit(methodHostClass);
|
||
|
methodHostClass = NULL;
|
||
|
|
||
|
/* get type list */
|
||
|
char *typeList = strsCut(buffs, methodDec, '(', ')');
|
||
|
if (typeList == NULL)
|
||
|
{
|
||
|
/* typeList no found */
|
||
|
args_setErrorCode(res, 3);
|
||
|
args_setSysOut(res, "[error] runner: type list no found.");
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
/* get arg list */
|
||
|
char *argList = strsCut(buffs, cmd, '(', ')');
|
||
|
{
|
||
|
if (argList == NULL)
|
||
|
{
|
||
|
/* argL List no found */
|
||
|
args_setErrorCode(res, 4);
|
||
|
args_setSysOut(res, "[error] runner: arg list no found.");
|
||
|
goto exit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* get return type */
|
||
|
char *returnType = strsGetLastToken(buffs, methodDec, ')');
|
||
|
|
||
|
/* get args */
|
||
|
args = getArgsBySentence(self, typeList, argList);
|
||
|
if (NULL == args)
|
||
|
{
|
||
|
/* get args faild */
|
||
|
args_setErrorCode(res, 5);
|
||
|
args_setSysOut(res, "[error] runner: solve arg faild.");
|
||
|
goto exit;
|
||
|
}
|
||
|
obj_setErrorCode(methodHostObj, 0);
|
||
|
obj_setSysOut(methodHostObj, "");
|
||
|
/* run method */
|
||
|
methodPtr(methodHostObj, args);
|
||
|
|
||
|
/* transfer return type */
|
||
|
args_setStr(res, "returnType", returnType);
|
||
|
/* transfer return */
|
||
|
args_copyArgByName(args, "return", res);
|
||
|
/* transfer sysOut */
|
||
|
char *sysOut = obj_getSysOut(methodHostObj);
|
||
|
if (NULL != sysOut)
|
||
|
{
|
||
|
args_setSysOut(res, sysOut);
|
||
|
}
|
||
|
/* transfer errCode */
|
||
|
if (0 != obj_getErrorCode(methodHostObj))
|
||
|
{
|
||
|
/* method error */
|
||
|
args_setErrorCode(res, 6);
|
||
|
}
|
||
|
goto exit;
|
||
|
exit:
|
||
|
if (NULL != buffs)
|
||
|
{
|
||
|
args_deinit(buffs);
|
||
|
}
|
||
|
if (NULL != methodHostClass)
|
||
|
{
|
||
|
obj_deinit(methodHostClass);
|
||
|
}
|
||
|
if (NULL != args)
|
||
|
{
|
||
|
args_deinit(args);
|
||
|
}
|
||
|
return res;
|
||
|
}
|