#pragma once #include "wrapper.h" #include #include class TLuaEval { public: TLuaEval(); template inline TLuaEval& SetVars(const C& container) { for (auto& [k, v] : container) { SetVariable(k, v); } return *this; } inline TLuaEval& Parse(TStringBuf chunk) { ParseChunk(chunk); return *this; } void SetVariable(TZtStringBuf name, const NJson::TJsonValue& value); template void SetUserdata(TZtStringBuf name, T&& userdata) { LuaState_.push_userdata(std::forward(userdata)); LuaState_.set_global(name.c_str()); } TString EvalExpression(TStringBuf expression); TString EvalRaw(TStringBuf code); void ParseChunk(TStringBuf code); TString Preprocess(TStringBuf line); TString PreprocessOne(TStringBuf line); bool CheckEmptyStack(); struct TExpression { TString Name; }; TExpression Compile(TStringBuf expression); TExpression CompileFunction(TStringBuf expression); TExpression CompileRaw(TStringBuf body, const TString& name); TString DumpStack(); TString EvalCompiled(const TExpression& compiled); void EvalCompiledRaw(const TExpression& compiled); bool EvalCompiledCondition(const TExpression& compiled); template TNumber EvalCompiledNumeric(const TExpression& compiled) { TGuard guard(LuaMutex_); RunExpressionLocked(guard, compiled); return LuaState_.pop_number(); } private: TString GenerateName(); TString Evaluate(const TString& name, const TString& body); void RunExpressionLocked(const TGuard& lock, const TExpression& compiled); TLuaStateHolder LuaState_; ui64 FunctionNameCounter_; TMutex LuaMutex_; };