Setup for making script options non global if desired
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
bbda668b3e
commit
2f912afe92
|
@ -325,7 +325,7 @@ namespace Porygon::Evaluation {
|
|||
arr[i] = parameters[i].Get();
|
||||
}
|
||||
delete function;
|
||||
return scriptOption -> Call(arr, parameters.size());
|
||||
return scriptOption -> Call(this -> _scriptOptions, arr, parameters.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "EvalValues/ScriptFunctionEvalValue.hpp"
|
||||
#include "EvaluationScope/EvaluationScope.hpp"
|
||||
#include "EvalValuePointer.hpp"
|
||||
#include "../ScriptOptions.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -21,7 +22,7 @@ namespace Porygon::Evaluation{
|
|||
bool _hasReturned;
|
||||
bool _hasBroken;
|
||||
|
||||
//Porygon::Script* _scriptData;
|
||||
const Porygon::ScriptOptions* _scriptOptions;
|
||||
shared_ptr<EvaluationScope> _evaluationScope;
|
||||
|
||||
void EvaluateStatement(const BoundStatement* statement);
|
||||
|
@ -48,9 +49,9 @@ namespace Porygon::Evaluation{
|
|||
|
||||
EvalValuePointer GetVariable(const BoundVariableExpression *expression);
|
||||
public:
|
||||
explicit Evaluator(map<Utilities::HashedString, EvalValuePointer>* scriptVariables)
|
||||
explicit Evaluator(map<Utilities::HashedString, EvalValuePointer>* scriptVariables, const ScriptOptions* options)
|
||||
: _scriptVariables(scriptVariables), _hasReturned(false), _hasBroken(false), _returnValue(nullptr),
|
||||
_evaluationScope(nullptr){
|
||||
_evaluationScope(nullptr), _scriptOptions(options){
|
||||
}
|
||||
|
||||
const EvalValue* Evaluate(const BoundScriptStatement* statement);
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "GlobalScriptOptions.hpp"
|
||||
#include "Utilities/StringUtils.hpp"
|
||||
|
||||
std::streambuf* Porygon::GlobalScriptOptions::_printBuffer = std::cout.rdbuf();
|
||||
std::ostream* Porygon::GlobalScriptOptions::_printStream = new std::ostream(Porygon::GlobalScriptOptions::_printBuffer);
|
||||
|
||||
static void DefaultPrint(const char16_t* s){
|
||||
Porygon::GlobalScriptOptions::GetPrintStream() << Porygon::Utilities::StringUtils::FromUTF8(s) << std::endl;
|
||||
}
|
||||
|
||||
void (*Porygon::GlobalScriptOptions::_print)(const char16_t*) = DefaultPrint;
|
||||
|
||||
extern "C"{
|
||||
void SetPrintFunc(void (*func)(const char16_t*)){
|
||||
Porygon::GlobalScriptOptions::SetPrintFunc(func);
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef PORYGONLANG_GLOBALSCRIPTOPTIONS_HPP
|
||||
#define PORYGONLANG_GLOBALSCRIPTOPTIONS_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Porygon{
|
||||
class GlobalScriptOptions{
|
||||
static void (*_print)(const char16_t* s);
|
||||
static std::streambuf* _printBuffer;
|
||||
static std::ostream* _printStream;
|
||||
public:
|
||||
inline static void Print(const char16_t* s){
|
||||
GlobalScriptOptions::_print(s);
|
||||
}
|
||||
|
||||
static void SetPrintFunc(void (*print)(const char16_t *)){
|
||||
GlobalScriptOptions::_print = print;
|
||||
}
|
||||
|
||||
static std::ostream& GetPrintStream(){
|
||||
return *GlobalScriptOptions::_printStream;
|
||||
}
|
||||
|
||||
static void SetPrintStream(std::ostream* stream){
|
||||
delete GlobalScriptOptions::_printStream;
|
||||
GlobalScriptOptions::_printStream = stream;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PORYGONLANG_GLOBALSCRIPTOPTIONS_HPP
|
|
@ -25,9 +25,10 @@ Porygon::Script *Porygon::Script::Create(const string &script) {
|
|||
Porygon::Script::Script(const u16string& s)
|
||||
: Diagnostics(make_shared<Diagnostics::DiagnosticsHolder>(s)),
|
||||
_boundScript(nullptr),
|
||||
_scriptVariables(new map<Utilities::HashedString, EvalValuePointer>())
|
||||
_scriptVariables(new map<Utilities::HashedString, EvalValuePointer>()),
|
||||
_scriptOptions(nullptr)
|
||||
{
|
||||
_evaluator = new Evaluator(this -> _scriptVariables);
|
||||
_evaluator = new Evaluator(this -> _scriptVariables, this -> GetScriptOptions());
|
||||
this -> Parse(s);
|
||||
}
|
||||
|
||||
|
@ -99,9 +100,10 @@ Porygon::Script::Script(shared_ptr<BoundScriptStatement> boundScript,
|
|||
shared_ptr<Porygon::Diagnostics::DiagnosticsHolder> diagnostics)
|
||||
: _boundScript(std::move(boundScript)),
|
||||
Diagnostics(std::move(diagnostics)),
|
||||
_scriptVariables(new map<Utilities::HashedString, EvalValuePointer>())
|
||||
_scriptVariables(new map<Utilities::HashedString, EvalValuePointer>()),
|
||||
_scriptOptions(nullptr)
|
||||
{
|
||||
_evaluator = new Evaluator(_scriptVariables);
|
||||
_evaluator = new Evaluator(_scriptVariables, this -> GetScriptOptions());
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "Evaluator/Evaluator.hpp"
|
||||
#include "Evaluator/EvalValues/EvalValue.hpp"
|
||||
#include "Utilities/HashedString.hpp"
|
||||
#include "ScriptOptions.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Porygon::Evaluation;
|
||||
|
@ -20,6 +21,7 @@ namespace Porygon{
|
|||
map<Utilities::HashedString, EvalValuePointer>* _scriptVariables;
|
||||
shared_ptr<Binder::BoundScriptStatement> _boundScript;
|
||||
shared_ptr<const ScriptType> _returnType;
|
||||
ScriptOptions* _scriptOptions;
|
||||
|
||||
explicit Script(const u16string&);
|
||||
Script(shared_ptr<BoundScriptStatement> boundScript, shared_ptr<Diagnostics::DiagnosticsHolder> diagnostics);
|
||||
|
@ -41,6 +43,13 @@ namespace Porygon{
|
|||
_returnType = t;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline const ScriptOptions* GetScriptOptions() const{
|
||||
if (_scriptOptions == nullptr){
|
||||
return ScriptOptions::GetDefaultScriptOptions();
|
||||
}
|
||||
return _scriptOptions;
|
||||
}
|
||||
|
||||
EvalValuePointer Evaluate();
|
||||
|
||||
const EvalValue* GetVariable(const u16string& key);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#include <iostream>
|
||||
#include "ScriptOptions.hpp"
|
||||
#include "Utilities/StringUtils.hpp"
|
||||
|
||||
Porygon::ScriptOptions Porygon::ScriptOptions::DefaultScriptOptions;
|
||||
|
||||
std::streambuf* Porygon::ScriptOptions::_printBuffer = std::cout.rdbuf();
|
||||
std::ostream* Porygon::ScriptOptions::_printStream = new std::ostream(Porygon::ScriptOptions::_printBuffer);
|
||||
|
||||
static void DefaultPrint(const char16_t* s){
|
||||
Porygon::ScriptOptions::GetDefaultScriptOptions()->GetPrintStream() << Porygon::Utilities::StringUtils::FromUTF8(s) << std::endl;
|
||||
}
|
||||
|
||||
void (*Porygon::ScriptOptions::_print)(const char16_t*) = DefaultPrint;
|
||||
|
||||
|
||||
extern "C"{
|
||||
void SetDefaultPrintFunc(void (*func)(const char16_t*)){
|
||||
Porygon::ScriptOptions::GetDefaultScriptOptions()->SetPrintFunc(func);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef PORYGONLANG_SCRIPTOPTIONS_HPP
|
||||
#define PORYGONLANG_SCRIPTOPTIONS_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Porygon{
|
||||
class ScriptOptions{
|
||||
static Porygon::ScriptOptions DefaultScriptOptions;
|
||||
static void (*_print)(const char16_t* s);
|
||||
static std::streambuf* _printBuffer;
|
||||
static std::ostream* _printStream;
|
||||
public:
|
||||
static Porygon::ScriptOptions* GetDefaultScriptOptions(){
|
||||
return &DefaultScriptOptions;
|
||||
}
|
||||
|
||||
inline void Print(const char16_t* s) const{
|
||||
ScriptOptions::_print(s);
|
||||
}
|
||||
|
||||
void SetPrintFunc(void (*print)(const char16_t *)){
|
||||
ScriptOptions::_print = print;
|
||||
}
|
||||
|
||||
std::ostream& GetPrintStream(){
|
||||
return *ScriptOptions::_printStream;
|
||||
}
|
||||
|
||||
void SetPrintStream(std::ostream* stream){
|
||||
delete ScriptOptions::_printStream;
|
||||
ScriptOptions::_printStream = stream;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PORYGONLANG_SCRIPTOPTIONS_HPP
|
|
@ -8,20 +8,21 @@
|
|||
#include "../Evaluator/EvalValues/NumericEvalValue.hpp"
|
||||
#include "../Evaluator/EvalValues/NilEvalValue.hpp"
|
||||
#include "../Utilities/StringUtils.hpp"
|
||||
#include "../Utilities/Random.hpp"
|
||||
#include "../Binder/BoundVariables/BoundVariable.hpp"
|
||||
#include "../UserData/UserDataFunction.hpp"
|
||||
#include "../UserData/UserDataFunctionType.hpp"
|
||||
#include "../GlobalScriptOptions.hpp"
|
||||
#include "../ScriptOptions.hpp"
|
||||
|
||||
namespace Porygon::StandardLibraries{
|
||||
class BasicLibrary{
|
||||
static const Evaluation::EvalValue* _error(void*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
static const Evaluation::EvalValue* _error(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
auto message = parameters[0]->EvaluateString();
|
||||
auto conv = Utilities::StringUtils::FromUTF8(message);
|
||||
throw Evaluation::EvaluationException(conv);
|
||||
}
|
||||
|
||||
static const Evaluation::EvalValue* _assert(void*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
static const Evaluation::EvalValue* _assert(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
auto assertion = parameters[0]->EvaluateBool();
|
||||
if (!assertion){
|
||||
if (parameterCount >= 2){
|
||||
|
@ -34,13 +35,13 @@ namespace Porygon::StandardLibraries{
|
|||
return new Evaluation::BooleanEvalValue(true);
|
||||
}
|
||||
|
||||
static const Evaluation::EvalValue* _print(void*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
static const Evaluation::EvalValue* _print(void*, const ScriptOptions* options, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
auto message = parameters[0]->EvaluateString();
|
||||
GlobalScriptOptions::Print(message.c_str());
|
||||
options->Print(message.c_str());
|
||||
return new Evaluation::NilEvalValue();
|
||||
}
|
||||
|
||||
static const Evaluation::EvalValue* _toInt(void*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
static const Evaluation::EvalValue* _toInt(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
|
||||
auto parameter = parameters[0]->EvaluateString();
|
||||
auto parsed = Utilities::StringUtils::ParseInteger(parameter);
|
||||
return new Evaluation::IntegerEvalValue(parsed);
|
||||
|
@ -75,9 +76,10 @@ namespace Porygon::StandardLibraries{
|
|||
|
||||
|
||||
static Evaluation::EvalValue* GetFuncEvalValue(
|
||||
const Evaluation::EvalValue* (*func)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount),
|
||||
const Evaluation::EvalValue* (*func)(void* obj, const ScriptOptions*,
|
||||
const Evaluation::EvalValue* parameters[], int parameterCount),
|
||||
const shared_ptr<GenericFunctionScriptType>& type, size_t optionLength){
|
||||
auto f = new Evaluation::GenericFunctionEvalValue(type, rand());
|
||||
auto f = new Evaluation::GenericFunctionEvalValue(type, Utilities::Random::Get());
|
||||
for (size_t i = 0; i < optionLength; i++){
|
||||
auto funcOption = new UserData::UserDataFunction(func, nullptr);
|
||||
f->RegisterOption(funcOption);
|
||||
|
|
|
@ -5,7 +5,8 @@ using namespace Porygon::Evaluation;
|
|||
|
||||
namespace Porygon::UserData{
|
||||
extern "C" {
|
||||
const EvalValue * CreateFunctionEvalValue(const Evaluation::EvalValue* (*func)(void* , const EvalValue* [], int ), void* obj) {
|
||||
const EvalValue * CreateFunctionEvalValue(const Evaluation::EvalValue* (*func)(void*, const ScriptOptions*,
|
||||
const EvalValue* [], int ), void* obj) {
|
||||
auto opt = new UserDataFunction(func, obj);
|
||||
auto t = new GenericFunctionEvalValue(make_shared<GenericFunctionScriptType>(), rand());
|
||||
t->RegisterOption(opt);
|
||||
|
|
|
@ -4,19 +4,23 @@
|
|||
#include "../Evaluator/EvalValues/ScriptFunctionEvalValue.hpp"
|
||||
#include "UserDataFunctionType.hpp"
|
||||
#include "../ScriptTypes/FunctionScriptType.hpp"
|
||||
#include "../ScriptOptions.hpp"
|
||||
|
||||
namespace Porygon::UserData{
|
||||
class UserDataFunction : public Evaluation::GenericFunctionOption {
|
||||
const Evaluation::EvalValue* (*_call)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount);
|
||||
const Evaluation::EvalValue* (*_call)(void* obj, const ScriptOptions*, const Evaluation::EvalValue* parameters[],
|
||||
int parameterCount);
|
||||
void *_obj;
|
||||
|
||||
UserDataFunction(const Evaluation::EvalValue* (*call)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount), void* obj,
|
||||
UserDataFunction(const Evaluation::EvalValue* (*call)(void* obj, const ScriptOptions*,
|
||||
const Evaluation::EvalValue* parameters[], int parameterCount), void* obj,
|
||||
const shared_ptr<GenericFunctionScriptType>& type, size_t hash) : GenericFunctionOption(){
|
||||
_call = call;
|
||||
_obj = obj;
|
||||
}
|
||||
public:
|
||||
UserDataFunction(const Evaluation::EvalValue* (*call)(void* obj, const Evaluation::EvalValue* parameters[], int parameterCount), void* obj) :
|
||||
UserDataFunction(const Evaluation::EvalValue* (*call)(void* obj, const ScriptOptions*,
|
||||
const Evaluation::EvalValue* parameters[], int parameterCount), void* obj) :
|
||||
GenericFunctionOption(){
|
||||
_call = call;
|
||||
_obj = obj;
|
||||
|
@ -25,8 +29,9 @@ namespace Porygon::UserData{
|
|||
~UserDataFunction() final = default;
|
||||
|
||||
[[nodiscard]]
|
||||
inline const Evaluation::EvalValue* Call(const Evaluation::EvalValue* parameters[], int parameterCount) const{
|
||||
return _call(_obj, parameters, parameterCount);
|
||||
inline const Evaluation::EvalValue* Call(const ScriptOptions* script,
|
||||
const Evaluation::EvalValue* parameters[], int parameterCount) const{
|
||||
return _call(_obj, script, parameters, parameterCount);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -102,8 +102,8 @@
|
|||
auto t = new Porygon::Evaluation::GenericFunctionEvalValue(make_shared<GenericFunctionScriptType>(), \
|
||||
Porygon::Utilities::Random::Get()); \
|
||||
t->RegisterOption(new Porygon::UserData::UserDataFunction( \
|
||||
[](void* obj, const Porygon::Evaluation::EvalValue* par[], int parameterCount) \
|
||||
-> const Porygon::Evaluation::EvalValue*{return ((const T_USERDATA*)obj)->invoke__##fieldName(obj, par, parameterCount);}, \
|
||||
[](void* obj, const ScriptOptions* opts, const Porygon::Evaluation::EvalValue* par[], int parameterCount) \
|
||||
-> const Porygon::Evaluation::EvalValue*{return ((const T_USERDATA*)obj)->invoke__##fieldName(obj, opts, par, parameterCount);}, \
|
||||
obj)); \
|
||||
return t;}, \
|
||||
nullptr) \
|
||||
|
@ -123,7 +123,8 @@
|
|||
\returns An invokable function.
|
||||
*/
|
||||
#define PORYGON_PREPARE_FUNCTION(userDataTypeName, fieldName, returnType, ...) \
|
||||
static const Porygon::Evaluation::EvalValue* invoke__##fieldName(void* obj, const Porygon::Evaluation::EvalValue* par[], int parameterCount){ \
|
||||
static const Porygon::Evaluation::EvalValue* invoke__##fieldName(void* obj, const ScriptOptions* opts, \
|
||||
const Porygon::Evaluation::EvalValue* par[], int parameterCount){ \
|
||||
return Porygon::Evaluation::EvalValueHelper::Create(((userDataTypeName*)obj)->fieldName( \
|
||||
__VA_ARGS__ \
|
||||
));}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifdef TESTS_BUILD
|
||||
#include <catch.hpp>
|
||||
#include "../src/Script.hpp"
|
||||
#include "../../src/GlobalScriptOptions.hpp"
|
||||
#include "../../src/ScriptOptions.hpp"
|
||||
#include <cstring>
|
||||
|
||||
using namespace Porygon;
|
||||
|
@ -56,7 +56,7 @@ TEST_CASE( "Print func works", "[integration]" ) {
|
|||
Script* script = Script::Create(u"print('foobar')");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
auto stream = new std::stringstream();
|
||||
GlobalScriptOptions::SetPrintStream(stream);
|
||||
ScriptOptions::GetDefaultScriptOptions()->SetPrintStream(stream);
|
||||
script->Evaluate();
|
||||
auto printVal = stream->str();
|
||||
REQUIRE(printVal == "foobar\n");
|
||||
|
|
Loading…
Reference in New Issue