This commit is contained in:
Duncan Ogilvie 2020-07-20 13:34:20 +02:00
parent ff1d5bd565
commit f3d360400b
4 changed files with 40 additions and 15 deletions

View File

@ -34,8 +34,8 @@ static bool RegisterEasy(const String & name, duint(*cbFunction)(Ts...))
{
return callFunc(argv, cbFunction, typename gens<sizeof...(Ts)>::type());
};
if(!ExpressionFunctions::Register(aliases[0], sizeof...(Ts), tempFunc))
return false;
/*if(!ExpressionFunctions::Register(aliases[0], sizeof...(Ts), tempFunc))
return false;*/
for(size_t i = 1; i < aliases.size(); i++)
ExpressionFunctions::RegisterAlias(aliases[0], aliases[i]);
return true;
@ -186,7 +186,7 @@ bool ExpressionFunctions::Unregister(const String & name)
return true;
}
bool ExpressionFunctions::Call(const String & name, std::vector<duint> & argv, duint & result)
bool ExpressionFunctions::Call(const String & name, ExpressionValue & result, std::vector<ExpressionValue> & argv)
{
SHARED_ACQUIRE(LockExpressionFunctions);
auto found = mFunctions.find(name);
@ -195,8 +195,8 @@ bool ExpressionFunctions::Call(const String & name, std::vector<duint> & argv, d
const auto & f = found->second;
if(f.argc != int(argv.size()))
return false;
result = f.cbFunction(f.argc, argv.data(), f.userdata);
return true;
// TODO: check return value?
return f.cbFunction(&result, f.argc, argv.data(), f.userdata);
}
bool ExpressionFunctions::GetArgc(const String & name, int & argc)

View File

@ -3,16 +3,36 @@
#include "_global.h"
#include <functional>
typedef enum
{
ValueTypeNumber,
ValueTypeString,
} ValueType;
typedef struct
{
const char* ptr;
bool isOwner;
} StringValue;
typedef struct
{
ValueType type;
duint number;
StringValue string;
} ExpressionValue;
class ExpressionFunctions
{
public:
using CBEXPRESSIONFUNCTION = std::function<duint(int argc, duint* argv, void* userdata)>;
// TODO: also register the argument types
using CBEXPRESSIONFUNCTION = std::function<bool(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata)>;
static void Init();
static bool Register(const String & name, int argc, const CBEXPRESSIONFUNCTION & cbFunction, void* userdata = nullptr);
static bool RegisterAlias(const String & name, const String & alias);
static bool Unregister(const String & name);
static bool Call(const String & name, std::vector<duint> & argv, duint & result);
static bool Call(const String & name, ExpressionValue & result, std::vector<ExpressionValue> & argv);
static bool GetArgc(const String & name, int & argc);
private:

View File

@ -878,20 +878,24 @@ bool ExpressionParser::Calculate(duint & value, bool signedcalc, bool allowassig
return false;
if(int(stack.size()) < argc)
return false;
std::vector<duint> argv;
std::vector<ExpressionValue> argv;
argv.resize(argc);
for(auto i = 0; i < argc; i++)
{
duint arg;
/*duint arg;
if(!stack[stack.size() - 1].DoEvaluate(arg, silent, baseonly))
return false;
return false;*/
// TODO: put in EvalValue -> ExpressionValue
stack.pop_back();
ExpressionValue arg = { ValueTypeNumber, 0 };
argv[argc - i - 1] = arg;
}
duint result;
if(!ExpressionFunctions::Call(name, argv, result))
ExpressionValue result = { ValueTypeNumber, 0 };
if(!ExpressionFunctions::Call(name, result, argv))
return false;
stack.push_back(EvalValue(result));
// TODO: put back in EvalValue
EvalValue result2(0);
stack.push_back(result2);
}
else
stack.push_back(EvalValue(token.data()));

View File

@ -991,11 +991,12 @@ bool pluginexprfuncregister(int pluginHandle, const char* name, int argc, CBPLUG
PLUG_EXPRFUNCTION plugExprfunction;
plugExprfunction.pluginHandle = pluginHandle;
strcpy_s(plugExprfunction.name, name);
if(!ExpressionFunctions::Register(name, argc, cbFunction, userdata))
// TODO: backport plugin interface
/*if(!ExpressionFunctions::Register(name, argc, cbFunction, userdata))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN, %s] Expression function \"%s\" failed to register...\n"), plugName.c_str(), name);
return false;
}
}*/
EXCLUSIVE_ACQUIRE(LockPluginExprfunctionList);
pluginExprfunctionList.push_back(plugExprfunction);
EXCLUSIVE_RELEASE();