Initial support for require statements
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
2f912afe92
commit
c39f3a0884
|
@ -4,6 +4,7 @@
|
||||||
#include "../ScriptTypes/TableScriptType.hpp"
|
#include "../ScriptTypes/TableScriptType.hpp"
|
||||||
#include "BoundExpressions/BoundTableExpression.hpp"
|
#include "BoundExpressions/BoundTableExpression.hpp"
|
||||||
#include "BoundExpressions/BoundFunctionCallExpression.hpp"
|
#include "BoundExpressions/BoundFunctionCallExpression.hpp"
|
||||||
|
#include "BoundExpressions/BoundRequireExpression.hpp"
|
||||||
#include "../UserData/UserDataScriptType.hpp"
|
#include "../UserData/UserDataScriptType.hpp"
|
||||||
|
|
||||||
using namespace Porygon::Parser;
|
using namespace Porygon::Parser;
|
||||||
|
@ -16,7 +17,7 @@ namespace Porygon::Binder {
|
||||||
binder._scope = scriptScope;
|
binder._scope = scriptScope;
|
||||||
auto statements = s->GetStatements();
|
auto statements = s->GetStatements();
|
||||||
vector<const BoundStatement *> boundStatements(statements->size());
|
vector<const BoundStatement *> boundStatements(statements->size());
|
||||||
for (int i = 0; i < statements->size(); i++) {
|
for (size_t i = 0; i < statements->size(); i++) {
|
||||||
boundStatements[i] = binder.BindStatement(statements->at(i));
|
boundStatements[i] = binder.BindStatement(statements->at(i));
|
||||||
}
|
}
|
||||||
return new BoundScriptStatement(boundStatements, scriptScope->GetLocalVariableCount());
|
return new BoundScriptStatement(boundStatements, scriptScope->GetLocalVariableCount());
|
||||||
|
@ -63,7 +64,7 @@ namespace Porygon::Binder {
|
||||||
auto statements = ((ParsedBlockStatement *) statement)->GetStatements();
|
auto statements = ((ParsedBlockStatement *) statement)->GetStatements();
|
||||||
vector<const BoundStatement *> boundStatements(statements->size());
|
vector<const BoundStatement *> boundStatements(statements->size());
|
||||||
this->_scope->GoInnerScope();
|
this->_scope->GoInnerScope();
|
||||||
for (int i = 0; i < statements->size(); i++) {
|
for (size_t i = 0; i < statements->size(); i++) {
|
||||||
boundStatements[i] = this->BindStatement(statements->at(i));
|
boundStatements[i] = this->BindStatement(statements->at(i));
|
||||||
}
|
}
|
||||||
this->_scope->GoOuterScope();
|
this->_scope->GoOuterScope();
|
||||||
|
@ -137,7 +138,7 @@ namespace Porygon::Binder {
|
||||||
auto parameterKeys = vector<shared_ptr<const BoundVariableKey>>(parameters->size());
|
auto parameterKeys = vector<shared_ptr<const BoundVariableKey>>(parameters->size());
|
||||||
|
|
||||||
this->_scope->GoInnerScope();
|
this->_scope->GoInnerScope();
|
||||||
for (long i = 0; i < parameters->size(); i++) {
|
for (size_t i = 0; i < parameters->size(); i++) {
|
||||||
auto var = parameters->at(i);
|
auto var = parameters->at(i);
|
||||||
auto parsedType = ParseTypeIdentifier(var->GetType());
|
auto parsedType = ParseTypeIdentifier(var->GetType());
|
||||||
if (parsedType == nullptr) {
|
if (parsedType == nullptr) {
|
||||||
|
@ -567,7 +568,14 @@ namespace Porygon::Binder {
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundExpression *Binder::BindFunctionCall(const FunctionCallExpression *expression) {
|
BoundExpression *Binder::BindFunctionCall(const FunctionCallExpression *expression) {
|
||||||
auto functionExpression = BindExpression(expression->GetFunction());
|
auto func = expression->GetFunction();
|
||||||
|
if (func->GetKind() == ParsedExpressionKind::Variable){
|
||||||
|
auto variable = dynamic_cast<const VariableExpression*>(func);
|
||||||
|
if (variable->GetValue().GetHash() == HashedString::ConstHash("require")){
|
||||||
|
return this->BindRequire(expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto functionExpression = BindExpression(func);
|
||||||
auto type = functionExpression->GetType();
|
auto type = functionExpression->GetType();
|
||||||
if (type->GetClass() != TypeClass::Function) {
|
if (type->GetClass() != TypeClass::Function) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ExpressionIsNotAFunction,
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ExpressionIsNotAFunction,
|
||||||
|
@ -579,7 +587,7 @@ namespace Porygon::Binder {
|
||||||
auto givenParameters = expression->GetParameters();
|
auto givenParameters = expression->GetParameters();
|
||||||
auto givenParameterTypes = vector<shared_ptr<const ScriptType>>(givenParameters->size());
|
auto givenParameterTypes = vector<shared_ptr<const ScriptType>>(givenParameters->size());
|
||||||
vector<BoundExpression *> boundParameters = vector<BoundExpression *>(givenParameters->size());
|
vector<BoundExpression *> boundParameters = vector<BoundExpression *>(givenParameters->size());
|
||||||
for (long i = 0; i < givenParameters->size(); i++){
|
for (size_t i = 0; i < givenParameters->size(); i++){
|
||||||
boundParameters[i] = this -> BindExpression(givenParameters->at(i));
|
boundParameters[i] = this -> BindExpression(givenParameters->at(i));
|
||||||
givenParameterTypes[i] = boundParameters[i]->GetType();
|
givenParameterTypes[i] = boundParameters[i]->GetType();
|
||||||
}
|
}
|
||||||
|
@ -596,6 +604,44 @@ namespace Porygon::Binder {
|
||||||
expression->GetStartPosition(), expression->GetLength());
|
expression->GetStartPosition(), expression->GetLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoundExpression *Binder::BindRequire(const FunctionCallExpression* exp){
|
||||||
|
auto parameters = exp->GetParameters();
|
||||||
|
if (parameters->size() != 1){
|
||||||
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidFunctionParameters,
|
||||||
|
exp->GetStartPosition(),
|
||||||
|
exp->GetLength());
|
||||||
|
return new BoundBadExpression(exp->GetStartPosition(), exp ->GetLength());
|
||||||
|
}
|
||||||
|
auto parameter = parameters->at(0);
|
||||||
|
auto boundParameter = this -> BindExpression(parameter);
|
||||||
|
if (boundParameter->GetKind() != BoundExpressionKind::LiteralString){
|
||||||
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidFunctionParameters,
|
||||||
|
exp->GetStartPosition(),
|
||||||
|
exp->GetLength());
|
||||||
|
return new BoundBadExpression(exp->GetStartPosition(), exp ->GetLength());
|
||||||
|
}
|
||||||
|
auto key = *dynamic_cast<BoundLiteralStringExpression*>(boundParameter)->GetValue();
|
||||||
|
auto opt = this->_scriptData->GetScriptOptions();
|
||||||
|
auto transformedKey = Utilities::StringUtils::FromUTF8(key);
|
||||||
|
delete boundParameter;
|
||||||
|
if (!opt->DoesModuleExist(transformedKey)){
|
||||||
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ModuleDoesntExist,
|
||||||
|
exp->GetStartPosition(),
|
||||||
|
exp->GetLength());
|
||||||
|
return new BoundBadExpression(exp->GetStartPosition(), exp ->GetLength());
|
||||||
|
}
|
||||||
|
auto module = opt->ResolveModule(transformedKey);
|
||||||
|
if (module -> GetReturnType() == nullptr){
|
||||||
|
for (const auto& v: *module->GetScriptVariables()){
|
||||||
|
//TODO: Currently a hack, will always make all variables nil
|
||||||
|
auto type = make_shared<const ScriptType>(TypeClass::Nil);
|
||||||
|
this -> _scope -> AssignVariable(v.first, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return new BoundRequireExpression(module, exp->GetStartPosition(), exp ->GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
BoundExpression *Binder::BindIndexExpression(const IndexExpression *expression, bool setter) {
|
BoundExpression *Binder::BindIndexExpression(const IndexExpression *expression, bool setter) {
|
||||||
auto indexer = this->BindExpression(expression->GetIndexer());
|
auto indexer = this->BindExpression(expression->GetIndexer());
|
||||||
auto index = this->BindExpression(expression->GetIndex());
|
auto index = this->BindExpression(expression->GetIndex());
|
||||||
|
@ -672,7 +718,7 @@ namespace Porygon::Binder {
|
||||||
if (!boundExpressions.empty()) {
|
if (!boundExpressions.empty()) {
|
||||||
boundExpressions[0] = this->BindExpression(expressions->at(0));
|
boundExpressions[0] = this->BindExpression(expressions->at(0));
|
||||||
valueType = boundExpressions[0]->GetType();
|
valueType = boundExpressions[0]->GetType();
|
||||||
for (long i = 1; i < expressions->size(); i++) {
|
for (size_t i = 1; i < expressions->size(); i++) {
|
||||||
boundExpressions[i] = this->BindExpression(expressions->at(i));
|
boundExpressions[i] = this->BindExpression(expressions->at(i));
|
||||||
if (boundExpressions[i]->GetType().get()->operator!=(valueType.get())) {
|
if (boundExpressions[i]->GetType().get()->operator!=(valueType.get())) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidTableValueType,
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidTableValueType,
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "BoundVariables/BoundScope.hpp"
|
#include "BoundVariables/BoundScope.hpp"
|
||||||
#include "../Parser/ParsedExpressions/ParsedTableExpression.hpp"
|
#include "../Parser/ParsedExpressions/ParsedTableExpression.hpp"
|
||||||
#include "../ScriptTypes/FunctionScriptType.hpp"
|
#include "../ScriptTypes/FunctionScriptType.hpp"
|
||||||
|
#include "BoundExpressions/BoundFunctionCallExpression.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Porygon::Parser;
|
using namespace Porygon::Parser;
|
||||||
|
@ -40,6 +41,7 @@ namespace Porygon::Binder {
|
||||||
BoundExpression *BindBinaryOperator(const BinaryExpression *expression);
|
BoundExpression *BindBinaryOperator(const BinaryExpression *expression);
|
||||||
BoundExpression *BindUnaryOperator(const UnaryExpression *expression);
|
BoundExpression *BindUnaryOperator(const UnaryExpression *expression);
|
||||||
BoundExpression *BindFunctionCall(const FunctionCallExpression *expression);
|
BoundExpression *BindFunctionCall(const FunctionCallExpression *expression);
|
||||||
|
BoundExpression *BindRequire(const FunctionCallExpression *exp);
|
||||||
BoundExpression *BindIndexExpression(const IndexExpression *expression, bool setter);
|
BoundExpression *BindIndexExpression(const IndexExpression *expression, bool setter);
|
||||||
BoundExpression *BindNumericalTableExpression(const ParsedNumericalTableExpression *expression);
|
BoundExpression *BindNumericalTableExpression(const ParsedNumericalTableExpression *expression);
|
||||||
BoundExpression *BindTableExpression(const ParsedTableExpression *expression);
|
BoundExpression *BindTableExpression(const ParsedTableExpression *expression);
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace Porygon::Binder {
|
||||||
PeriodIndex,
|
PeriodIndex,
|
||||||
NumericalTable,
|
NumericalTable,
|
||||||
Table,
|
Table,
|
||||||
|
Require,
|
||||||
};
|
};
|
||||||
|
|
||||||
class BoundExpression {
|
class BoundExpression {
|
||||||
|
@ -331,6 +332,7 @@ namespace Porygon::Binder {
|
||||||
return &_expressions;
|
return &_expressions;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //PORYGONLANG_BOUNDEXPRESSION_HPP
|
#endif //PORYGONLANG_BOUNDEXPRESSION_HPP
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef PORYGONLANG_BOUNDREQUIREEXPRESSION_HPP
|
||||||
|
#define PORYGONLANG_BOUNDREQUIREEXPRESSION_HPP
|
||||||
|
|
||||||
|
#include "BoundExpression.hpp"
|
||||||
|
#include "../../Script.hpp"
|
||||||
|
|
||||||
|
namespace Porygon::Binder {
|
||||||
|
class BoundRequireExpression : public BoundExpression {
|
||||||
|
Script* _module;
|
||||||
|
public:
|
||||||
|
BoundRequireExpression(Script* script, unsigned int start,
|
||||||
|
unsigned int length)
|
||||||
|
: BoundExpression(start, length, script->GetReturnType()),
|
||||||
|
_module(script){}
|
||||||
|
|
||||||
|
~BoundRequireExpression() final{
|
||||||
|
delete _module;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
inline Script* GetModule() const{
|
||||||
|
return _module;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
inline BoundExpressionKind GetKind() const final {
|
||||||
|
return BoundExpressionKind::Require;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //PORYGONLANG_BOUNDREQUIREEXPRESSION_HPP
|
|
@ -26,7 +26,8 @@ namespace Porygon::Diagnostics {
|
||||||
UserDataFieldNoSetter,
|
UserDataFieldNoSetter,
|
||||||
NumericalForArgumentNotANumber,
|
NumericalForArgumentNotANumber,
|
||||||
CantIterateExpression,
|
CantIterateExpression,
|
||||||
InvalidFunctionParameters
|
InvalidFunctionParameters,
|
||||||
|
ModuleDoesntExist
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif //PORYGONLANG_DIAGNOSTICCODE_HPP
|
#endif //PORYGONLANG_DIAGNOSTICCODE_HPP
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "EvalValues/TableEvalValue.hpp"
|
#include "EvalValues/TableEvalValue.hpp"
|
||||||
#include "../Binder/BoundExpressions/BoundTableExpression.hpp"
|
#include "../Binder/BoundExpressions/BoundTableExpression.hpp"
|
||||||
#include "../Binder/BoundExpressions/BoundFunctionCallExpression.hpp"
|
#include "../Binder/BoundExpressions/BoundFunctionCallExpression.hpp"
|
||||||
|
#include "../Binder/BoundExpressions/BoundRequireExpression.hpp"
|
||||||
#include "../ScriptTypes/TableScriptType.hpp"
|
#include "../ScriptTypes/TableScriptType.hpp"
|
||||||
#include "../UserData/UserDataFunction.hpp"
|
#include "../UserData/UserDataFunction.hpp"
|
||||||
#include "EvalValues/NumericalTableEvalValue.hpp"
|
#include "EvalValues/NumericalTableEvalValue.hpp"
|
||||||
|
@ -254,6 +255,8 @@ namespace Porygon::Evaluation {
|
||||||
return this->EvaluateNumericTableExpression(expression);
|
return this->EvaluateNumericTableExpression(expression);
|
||||||
case BoundExpressionKind::Table:
|
case BoundExpressionKind::Table:
|
||||||
return this->EvaluateComplexTableExpression(expression);
|
return this->EvaluateComplexTableExpression(expression);
|
||||||
|
case BoundExpressionKind::Require:
|
||||||
|
return this -> EvaluateRequireExpression(expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,4 +399,16 @@ namespace Porygon::Evaluation {
|
||||||
this->_evaluationScope = currentEvaluator;
|
this->_evaluationScope = currentEvaluator;
|
||||||
return new TableEvalValue(variables);
|
return new TableEvalValue(variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EvalValuePointer Evaluator::EvaluateRequireExpression(const BoundExpression* expression) {
|
||||||
|
auto module = dynamic_cast<const BoundRequireExpression*>(expression)->GetModule();
|
||||||
|
if (module ->GetReturnType() == nullptr){
|
||||||
|
for (const auto& v: *module->GetScriptVariables()){
|
||||||
|
this->_scriptVariables->insert({v.first, v.second.Clone()});
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
} else{
|
||||||
|
return module -> Evaluate().Take();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -47,6 +47,8 @@ namespace Porygon::Evaluation{
|
||||||
EvalValuePointer EvaluateNumericTableExpression(const BoundExpression *expression);
|
EvalValuePointer EvaluateNumericTableExpression(const BoundExpression *expression);
|
||||||
EvalValuePointer EvaluateComplexTableExpression(const BoundExpression *expression);
|
EvalValuePointer EvaluateComplexTableExpression(const BoundExpression *expression);
|
||||||
|
|
||||||
|
EvalValuePointer EvaluateRequireExpression(const BoundExpression* expression);
|
||||||
|
|
||||||
EvalValuePointer GetVariable(const BoundVariableExpression *expression);
|
EvalValuePointer GetVariable(const BoundVariableExpression *expression);
|
||||||
public:
|
public:
|
||||||
explicit Evaluator(map<Utilities::HashedString, EvalValuePointer>* scriptVariables, const ScriptOptions* options)
|
explicit Evaluator(map<Utilities::HashedString, EvalValuePointer>* scriptVariables, const ScriptOptions* options)
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace Porygon{
|
||||||
Evaluator* _evaluator;
|
Evaluator* _evaluator;
|
||||||
map<Utilities::HashedString, EvalValuePointer>* _scriptVariables;
|
map<Utilities::HashedString, EvalValuePointer>* _scriptVariables;
|
||||||
shared_ptr<Binder::BoundScriptStatement> _boundScript;
|
shared_ptr<Binder::BoundScriptStatement> _boundScript;
|
||||||
shared_ptr<const ScriptType> _returnType;
|
shared_ptr<const ScriptType> _returnType = nullptr;
|
||||||
ScriptOptions* _scriptOptions;
|
ScriptOptions* _scriptOptions;
|
||||||
|
|
||||||
explicit Script(const u16string&);
|
explicit Script(const u16string&);
|
||||||
|
@ -57,6 +57,10 @@ namespace Porygon{
|
||||||
|
|
||||||
const EvalValue* CallFunction(const u16string& key, const vector<EvalValue*>& variables);
|
const EvalValue* CallFunction(const u16string& key, const vector<EvalValue*>& variables);
|
||||||
bool HasFunction(const u16string& key);
|
bool HasFunction(const u16string& key);
|
||||||
|
|
||||||
|
const map<Utilities::HashedString, EvalValuePointer>* GetScriptVariables(){
|
||||||
|
return _scriptVariables;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,30 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
#include "ScriptOptions.hpp"
|
#include "ScriptOptions.hpp"
|
||||||
#include "Utilities/StringUtils.hpp"
|
#include "Utilities/StringUtils.hpp"
|
||||||
|
#include "Script.hpp"
|
||||||
|
|
||||||
Porygon::ScriptOptions Porygon::ScriptOptions::DefaultScriptOptions;
|
Porygon::ScriptOptions Porygon::ScriptOptions::DefaultScriptOptions;
|
||||||
|
|
||||||
std::streambuf* Porygon::ScriptOptions::_printBuffer = std::cout.rdbuf();
|
std::streambuf* Porygon::ScriptOptions::_printBuffer = std::cout.rdbuf();
|
||||||
std::ostream* Porygon::ScriptOptions::_printStream = new std::ostream(Porygon::ScriptOptions::_printBuffer);
|
std::ostream* Porygon::ScriptOptions::_printStream = new std::ostream(Porygon::ScriptOptions::_printBuffer);
|
||||||
|
|
||||||
static void DefaultPrint(const char16_t* s){
|
void Porygon::ScriptOptions::DefaultPrint(const char16_t *s) {
|
||||||
Porygon::ScriptOptions::GetDefaultScriptOptions()->GetPrintStream() << Porygon::Utilities::StringUtils::FromUTF8(s) << std::endl;
|
Porygon::ScriptOptions::GetDefaultScriptOptions()->GetPrintStream() << Porygon::Utilities::StringUtils::FromUTF8(s) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*Porygon::ScriptOptions::_print)(const char16_t*) = DefaultPrint;
|
bool Porygon::ScriptOptions::DefaultModuleExists(const std::string& moduleName) {
|
||||||
|
return std::filesystem::exists(moduleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Porygon::Script *Porygon::ScriptOptions::DefaultResolveModule(const std::string& moduleName) {
|
||||||
|
auto stream = std::ifstream(moduleName);
|
||||||
|
std::basic_stringstream<char16_t> stringStream;
|
||||||
|
stringStream << stream.rdbuf();
|
||||||
|
auto str = std::u16string(stringStream.str());
|
||||||
|
return Porygon::Script::Create(str);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"{
|
extern "C"{
|
||||||
void SetDefaultPrintFunc(void (*func)(const char16_t*)){
|
void SetDefaultPrintFunc(void (*func)(const char16_t*)){
|
||||||
|
|
|
@ -2,28 +2,54 @@
|
||||||
#define PORYGONLANG_SCRIPTOPTIONS_HPP
|
#define PORYGONLANG_SCRIPTOPTIONS_HPP
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
namespace Porygon{
|
namespace Porygon{
|
||||||
|
class Script;
|
||||||
|
|
||||||
class ScriptOptions{
|
class ScriptOptions{
|
||||||
static Porygon::ScriptOptions DefaultScriptOptions;
|
static Porygon::ScriptOptions DefaultScriptOptions;
|
||||||
static void (*_print)(const char16_t* s);
|
static void DefaultPrint(const char16_t* s);
|
||||||
|
static bool DefaultModuleExists(const std::string& moduleName);
|
||||||
|
static Script* DefaultResolveModule(const std::string& moduleName);
|
||||||
|
|
||||||
|
void (*_print)(const char16_t* s) = DefaultPrint;
|
||||||
|
bool (*_doesModuleExist)(const std::string& moduleName) = DefaultModuleExists;
|
||||||
|
Script* (*_resolveModule)(const std::string& moduleName) = DefaultResolveModule;
|
||||||
static std::streambuf* _printBuffer;
|
static std::streambuf* _printBuffer;
|
||||||
static std::ostream* _printStream;
|
static std::ostream* _printStream;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Porygon::ScriptOptions* GetDefaultScriptOptions(){
|
static Porygon::ScriptOptions* GetDefaultScriptOptions(){
|
||||||
return &DefaultScriptOptions;
|
return &DefaultScriptOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Print(const char16_t* s) const{
|
inline void Print(const char16_t* s) const{
|
||||||
ScriptOptions::_print(s);
|
this -> _print(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool DoesModuleExist(std::string moduleName) const{
|
||||||
|
return _doesModuleExist(std::move(moduleName));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Script* ResolveModule(std::string moduleName) const{
|
||||||
|
return _resolveModule(std::move(moduleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPrintFunc(void (*print)(const char16_t *)){
|
void SetPrintFunc(void (*print)(const char16_t *)){
|
||||||
ScriptOptions::_print = print;
|
this -> _print = print;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetModuleExistsFunc(bool (*doesModuleExist)(const std::string& moduleName)){
|
||||||
|
this ->_doesModuleExist = doesModuleExist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetResolveModuleFunc(Script* (*resolveModule)(const std::string& moduleName)){
|
||||||
|
this ->_resolveModule = resolveModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& GetPrintStream(){
|
std::ostream& GetPrintStream(){
|
||||||
return *ScriptOptions::_printStream;
|
return *Porygon::ScriptOptions::_printStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPrintStream(std::ostream* stream){
|
void SetPrintStream(std::ostream* stream){
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifdef TESTS_BUILD
|
||||||
|
#include <catch.hpp>
|
||||||
|
#include "../src/Script.hpp"
|
||||||
|
using namespace Porygon;
|
||||||
|
|
||||||
|
class ModuleHandler{
|
||||||
|
static unordered_map<string, Script*> MODULES;
|
||||||
|
|
||||||
|
~ModuleHandler(){
|
||||||
|
for (auto v: MODULES){
|
||||||
|
delete v.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static bool DoesModuleExist(const string& moduleName){
|
||||||
|
return MODULES.find(moduleName) != MODULES.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static Script* ResolveModule(const string& moduleName){
|
||||||
|
return MODULES[moduleName];
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void Initialize(){
|
||||||
|
ScriptOptions::GetDefaultScriptOptions()->SetModuleExistsFunc(DoesModuleExist);
|
||||||
|
ScriptOptions::GetDefaultScriptOptions()->SetResolveModuleFunc(ResolveModule);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
unordered_map<string, Script*> ModuleHandler::MODULES = unordered_map<string, Script*>{
|
||||||
|
{"simple_return", Script::Create(u"return 500")}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE( "Require simple return script", "[integration]" ) {
|
||||||
|
ModuleHandler::Initialize();
|
||||||
|
auto script = Script::Create(uR"(
|
||||||
|
return require("simple_return")
|
||||||
|
)");
|
||||||
|
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||||
|
auto var = script->Evaluate();
|
||||||
|
REQUIRE(var->EvaluateInteger() == 500);
|
||||||
|
delete script;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue