diff --git a/ext/miniscript/src/miniscript/miniscript/ApplicationMethods.cpp b/ext/miniscript/src/miniscript/miniscript/ApplicationMethods.cpp index c51c90d46..e6a137e0b 100644 --- a/ext/miniscript/src/miniscript/miniscript/ApplicationMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/ApplicationMethods.cpp @@ -20,6 +20,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; using _StringTools = miniscript::utilities::StringTools; +void ApplicationMethods::registerConstants(MiniScript* miniScript) { +} + const string ApplicationMethods::execute(const string& command) { // see: https://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-output-of-command-within-c-using-posix array buffer; diff --git a/ext/miniscript/src/miniscript/miniscript/ApplicationMethods.h b/ext/miniscript/src/miniscript/miniscript/ApplicationMethods.h index 2180c6329..9ff3c6795 100644 --- a/ext/miniscript/src/miniscript/miniscript/ApplicationMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/ApplicationMethods.h @@ -15,6 +15,12 @@ using std::string; */ class miniscript::miniscript::ApplicationMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/ArrayMethods.cpp b/ext/miniscript/src/miniscript/miniscript/ArrayMethods.cpp index 81a11b6f9..a97417a48 100644 --- a/ext/miniscript/src/miniscript/miniscript/ArrayMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/ArrayMethods.cpp @@ -13,6 +13,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; +void ArrayMethods::registerConstants(MiniScript* miniScript) { +} + void ArrayMethods::registerMethods(MiniScript* miniScript) { // array methods { diff --git a/ext/miniscript/src/miniscript/miniscript/ArrayMethods.h b/ext/miniscript/src/miniscript/miniscript/ArrayMethods.h index bba248ddf..55ac852e5 100644 --- a/ext/miniscript/src/miniscript/miniscript/ArrayMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/ArrayMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::ArrayMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/BaseMethods.cpp b/ext/miniscript/src/miniscript/miniscript/BaseMethods.cpp index a8679246f..722f47c5e 100644 --- a/ext/miniscript/src/miniscript/miniscript/BaseMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/BaseMethods.cpp @@ -15,6 +15,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; using _Time = miniscript::utilities::Time; +void BaseMethods::registerConstants(MiniScript* miniScript) { +} + void BaseMethods::registerMethods(MiniScript* miniScript) { // base methods { diff --git a/ext/miniscript/src/miniscript/miniscript/BaseMethods.h b/ext/miniscript/src/miniscript/miniscript/BaseMethods.h index 4af2b76c7..47f5426c7 100644 --- a/ext/miniscript/src/miniscript/miniscript/BaseMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/BaseMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::BaseMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/ByteArrayMethods.cpp b/ext/miniscript/src/miniscript/miniscript/ByteArrayMethods.cpp index 16a94f2f2..3b79d781d 100644 --- a/ext/miniscript/src/miniscript/miniscript/ByteArrayMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/ByteArrayMethods.cpp @@ -13,6 +13,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; +void ByteArrayMethods::registerConstants(MiniScript* miniScript) { +} + void ByteArrayMethods::registerMethods(MiniScript* miniScript) { // array methods { diff --git a/ext/miniscript/src/miniscript/miniscript/ByteArrayMethods.h b/ext/miniscript/src/miniscript/miniscript/ByteArrayMethods.h index 3fb975305..92c0e2bc0 100644 --- a/ext/miniscript/src/miniscript/miniscript/ByteArrayMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/ByteArrayMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::ByteArrayMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/ConsoleMethods.cpp b/ext/miniscript/src/miniscript/miniscript/ConsoleMethods.cpp index 6fe808121..202732517 100644 --- a/ext/miniscript/src/miniscript/miniscript/ConsoleMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/ConsoleMethods.cpp @@ -13,6 +13,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; +void ConsoleMethods::registerConstants(MiniScript* miniScript) { +} + void ConsoleMethods::registerMethods(MiniScript* miniScript) { // console { diff --git a/ext/miniscript/src/miniscript/miniscript/ConsoleMethods.h b/ext/miniscript/src/miniscript/miniscript/ConsoleMethods.h index fdfc42f6e..5b3e2de06 100644 --- a/ext/miniscript/src/miniscript/miniscript/ConsoleMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/ConsoleMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::ConsoleMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/ContextMethods.cpp b/ext/miniscript/src/miniscript/miniscript/ContextMethods.cpp index 27958e772..9ff7227ce 100644 --- a/ext/miniscript/src/miniscript/miniscript/ContextMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/ContextMethods.cpp @@ -16,6 +16,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; +void ContextMethods::registerConstants(MiniScript* miniScript) { +} + void ContextMethods::registerMethods(MiniScript* miniScript) { if (miniScript->getContext() == nullptr) return; { diff --git a/ext/miniscript/src/miniscript/miniscript/ContextMethods.h b/ext/miniscript/src/miniscript/miniscript/ContextMethods.h index 767b6ed1f..8a15279c4 100644 --- a/ext/miniscript/src/miniscript/miniscript/ContextMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/ContextMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::ContextMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/CryptographyMethods.cpp b/ext/miniscript/src/miniscript/miniscript/CryptographyMethods.cpp index c155cc60a..08cbe069c 100644 --- a/ext/miniscript/src/miniscript/miniscript/CryptographyMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/CryptographyMethods.cpp @@ -19,6 +19,9 @@ using _Console = miniscript::utilities::Console; using _SHA256 = miniscript::utilities::SHA256; using _StringTools = miniscript::utilities::StringTools; +void CryptographyMethods::registerConstants(MiniScript* miniScript) { +} + void CryptographyMethods::registerMethods(MiniScript* miniScript) { // base64 { diff --git a/ext/miniscript/src/miniscript/miniscript/CryptographyMethods.h b/ext/miniscript/src/miniscript/miniscript/CryptographyMethods.h index b1e04138d..5f5c761b6 100644 --- a/ext/miniscript/src/miniscript/miniscript/CryptographyMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/CryptographyMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::CryptographyMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/Documentation.cpp b/ext/miniscript/src/miniscript/miniscript/Documentation.cpp index e91b15f3e..0f1230589 100644 --- a/ext/miniscript/src/miniscript/miniscript/Documentation.cpp +++ b/ext/miniscript/src/miniscript/miniscript/Documentation.cpp @@ -279,10 +279,41 @@ const string Documentation::generateOperatorsDocumentation( // string result; result+= string() + "\n"; - result+= string() + "# 10. Operators" + "\n"; + result+= string() + "# " + to_string(mainHeadingIdx) + ". " + heading + "\n"; result+= string() + "\n"; result+= string() + "| Op | Method |" + "\n"; result+= string() + "|----|---------------------------------------------------------------------------------------------|" + "\n"; for (const auto& method: operators) result+= string() + method + "\n"; return result; } + +const string Documentation::generateVariablesDocumentation( + const string& heading, + int mainHeadingIdx, + MiniScript* miniScript +) { + // + vector variables; + for (const auto& [variableName, variable]: miniScript->getRootScriptState().variables) { + string variableString; + variableString = "| "; + variableString+= variableName; + while (variableString.size() < 62) variableString+= " "; + variableString+= "| "; + auto idx = variableString.size(); + variableString+= variable->getValueAsString(); + while (variableString.size() - idx < 35) variableString+= " "; + variableString+= "|"; + variables.push_back(variableString); + } + sort(variables.begin(), variables.end()); + // + string result; + result+= string() + "\n"; + result+= string() + "# " + to_string(mainHeadingIdx) + ". " + heading + "\n"; + result+= string() + "\n"; + result+= string() + "| Name | Value |" + "\n"; + result+= string() + "|-------------------------------------------------------------|------------------------------------|" + "\n"; + for (const auto& method: variables) result+= string() + method + "\n"; + return result; +} diff --git a/ext/miniscript/src/miniscript/miniscript/Documentation.h b/ext/miniscript/src/miniscript/miniscript/Documentation.h index 827393771..8409b78eb 100644 --- a/ext/miniscript/src/miniscript/miniscript/Documentation.h +++ b/ext/miniscript/src/miniscript/miniscript/Documentation.h @@ -91,4 +91,18 @@ class miniscript::miniscript::Documentation { int mainHeadingIdx, MiniScript* miniScript ); + + /** + * Generate variables documentation + * @param heading heading + * @param mainHeadingIdx main heading index + * @param miniScript MiniScript script instance + * @return documentation + */ + static const string generateVariablesDocumentation( + const string& heading, + int mainHeadingIdx, + MiniScript* miniScript + ); + }; diff --git a/ext/miniscript/src/miniscript/miniscript/FileSystemMethods.cpp b/ext/miniscript/src/miniscript/miniscript/FileSystemMethods.cpp index 7de09fbcf..3574a4202 100644 --- a/ext/miniscript/src/miniscript/miniscript/FileSystemMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/FileSystemMethods.cpp @@ -19,6 +19,9 @@ using _Console = miniscript::utilities::Console; using _Exception = miniscript::utilities::Exception; using _ExceptionBase = miniscript::utilities::ExceptionBase; +void FileSystemMethods::registerConstants(MiniScript* miniScript) { +} + void FileSystemMethods::registerMethods(MiniScript* miniScript) { // file system methods { diff --git a/ext/miniscript/src/miniscript/miniscript/FileSystemMethods.h b/ext/miniscript/src/miniscript/miniscript/FileSystemMethods.h index c25196ae2..1b5a94301 100644 --- a/ext/miniscript/src/miniscript/miniscript/FileSystemMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/FileSystemMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::FileSystemMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/JSONMethods.cpp b/ext/miniscript/src/miniscript/miniscript/JSONMethods.cpp index 51889da67..0c934bdef 100644 --- a/ext/miniscript/src/miniscript/miniscript/JSONMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/JSONMethods.cpp @@ -15,6 +15,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; using _StringTools = miniscript::utilities::StringTools; +void JSONMethods::registerConstants(MiniScript* miniScript) { +} + void JSONMethods::registerMethods(MiniScript* miniScript) { // json { diff --git a/ext/miniscript/src/miniscript/miniscript/JSONMethods.h b/ext/miniscript/src/miniscript/miniscript/JSONMethods.h index 58352efc9..a1f4028f0 100644 --- a/ext/miniscript/src/miniscript/miniscript/JSONMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/JSONMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::JSONMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/MapMethods.cpp b/ext/miniscript/src/miniscript/miniscript/MapMethods.cpp index d9d85269a..ba002e76e 100644 --- a/ext/miniscript/src/miniscript/miniscript/MapMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/MapMethods.cpp @@ -13,6 +13,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; +void MapMethods::registerConstants(MiniScript* miniScript) { +} + void MapMethods::registerMethods(MiniScript* miniScript) { // map { diff --git a/ext/miniscript/src/miniscript/miniscript/MapMethods.h b/ext/miniscript/src/miniscript/miniscript/MapMethods.h index 2a305e8e8..d6cb30ee6 100644 --- a/ext/miniscript/src/miniscript/miniscript/MapMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/MapMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::MapMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/MathMethods.cpp b/ext/miniscript/src/miniscript/miniscript/MathMethods.cpp index 4f04e39be..deceb18da 100644 --- a/ext/miniscript/src/miniscript/miniscript/MathMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/MathMethods.cpp @@ -19,6 +19,9 @@ void MathMethods::registerDataType(MiniScript::DataType* dataType) { dataTypes.push_back(dataType); } +void MathMethods::registerConstants() { +} + void MathMethods::registerMethods() { // operator methods { diff --git a/ext/miniscript/src/miniscript/miniscript/MathMethods.h b/ext/miniscript/src/miniscript/miniscript/MathMethods.h index df45135c6..550cb4669 100644 --- a/ext/miniscript/src/miniscript/miniscript/MathMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/MathMethods.h @@ -27,6 +27,11 @@ class miniscript::miniscript::MathMethods { */ void registerDataType(MiniScript::DataType* dataType); + /** + * Register constants + */ + void registerConstants(); + /** * Register methods */ diff --git a/ext/miniscript/src/miniscript/miniscript/MiniScript.cpp b/ext/miniscript/src/miniscript/miniscript/MiniScript.cpp index dfa820f42..aa4321200 100644 --- a/ext/miniscript/src/miniscript/miniscript/MiniScript.cpp +++ b/ext/miniscript/src/miniscript/miniscript/MiniScript.cpp @@ -106,7 +106,7 @@ const string MiniScript::METHOD_DISABLENAMEDCONDITION = "script.disableNamedCond const string MiniScript::Variable::TYPENAME_NONE = ""; const string MiniScript::Variable::TYPENAME_NULL = "Null"; const string MiniScript::Variable::TYPENAME_BOOLEAN = "Boolean"; -const string MiniScript::Variable::TYPENAME_INTEGER = "_Integer"; +const string MiniScript::Variable::TYPENAME_INTEGER = "Integer"; const string MiniScript::Variable::TYPENAME_FLOAT = "Float"; const string MiniScript::Variable::TYPENAME_FUNCTION = "Function"; const string MiniScript::Variable::TYPENAME_NUMBER = "Number"; @@ -2870,7 +2870,65 @@ void MiniScript::registerMethods() { } void MiniScript::registerVariables() { + // for (const auto& [variableName, variable]: getRootScriptState().variables) delete variable; + getRootScriptState().variables.clear(); + + // + miniScriptMath->registerConstants(); + + // base script methods + // register base methods + BaseMethods::registerConstants(this); + + // register string methods + StringMethods::registerConstants(this); + + // register byte array methods + ByteArrayMethods::registerConstants(this); + + // register array methods + ArrayMethods::registerConstants(this); + + // register map methods + MapMethods::registerConstants(this); + + // register set methods + SetMethods::registerConstants(this); + + // register script methods + ScriptMethods::registerConstants(this); + + // additional script methods + // register application methods + ApplicationMethods::registerConstants(this); + + // register console methods + ConsoleMethods::registerConstants(this); + + // register context methods + ContextMethods::registerConstants(this); + + // register cryptography methods + CryptographyMethods::registerConstants(this); + + // register file system methods + FileSystemMethods::registerConstants(this); + + // register JSON methods + JSONMethods::registerConstants(this); + + // register network methods + NetworkMethods::registerConstants(this); + + // register time methods + TimeMethods::registerConstants(this); + + // register XML methods + XMLMethods::registerConstants(this); + + // + for (const auto dataType: dataTypes) dataType->registerConstants(this); } void MiniScript::createLamdaFunction(Variable& variable, const vector& arguments, const string_view& functionScriptCode, bool populateThis, const Statement& statement) { @@ -3427,16 +3485,7 @@ void MiniScript::Variable::setFunctionCallStatement(const string& initializerSta } } -inline MiniScript::Variable* MiniScript::getVariableIntern(const string& name, const string& callerMethod, Variable*& parentVariable, int64_t& arrayIdx, string& key, int& setAccessBool, const Statement* statement, bool expectVariable, bool global) { - // - if (isVariableAccess(name) == false) { - if (statement != nullptr) { - _Console::println(getStatementInformation(*statement) + ": variable: " + name + ": variable names must start with an $"); - } else { - _Console::println(scriptFileName + ": variable: " + name + ": variable names must start with an $"); - } - return nullptr; - } +inline MiniScript::Variable* MiniScript::evaluateVariableAccessIntern(MiniScript::Variable* variablePtr, const string& variableStatement, const string& callerMethod, Variable*& parentVariable, int64_t& arrayIdx, string& key, int& setAccessBool, const Statement* statement, bool expectVariable) { // get root variable key.clear(); // no array idx by default @@ -3444,55 +3493,16 @@ inline MiniScript::Variable* MiniScript::getVariableIntern(const string& name, c // determine left and right access operator position if there are any auto accessOperatorLeftIdx = string::npos; auto accessOperatorRightIdx = string::npos; - if (getVariableAccessOperatorLeftRightIndices(name, callerMethod, accessOperatorLeftIdx, accessOperatorRightIdx, statement) == false) { + if (getVariableAccessOperatorLeftRightIndices(variableStatement, callerMethod, accessOperatorLeftIdx, accessOperatorRightIdx, statement) == false) { return nullptr; } // access operator, if we have any, evaluate the array index auto haveAccessOperator = accessOperatorLeftIdx != string::npos && accessOperatorRightIdx != string::npos; - auto extractedVariableName = haveAccessOperator == true?_StringTools::substring(name, 0, accessOperatorLeftIdx):string(); if (haveAccessOperator == true && - evaluateAccess(name, callerMethod, accessOperatorLeftIdx, accessOperatorRightIdx, arrayIdx, key, statement) == false) { + evaluateAccess(variableStatement, callerMethod, accessOperatorLeftIdx, accessOperatorRightIdx, arrayIdx, key, statement) == false) { return nullptr; } - // retrieve variable from function script state - Variable* variablePtr = nullptr; - if (global == false) { - const auto& scriptState = getScriptState(); - auto variableIt = scriptState.variables.find(extractedVariableName.empty() == false?extractedVariableName:name); - if (variableIt == scriptState.variables.end()) { - if (isFunctionRunning() == false) { - if (expectVariable == true) { - if (statement != nullptr) { - _Console::println(getStatementInformation(*statement) + ": variable: " + name + " does not exist"); - } else { - _Console::println(scriptFileName + ": variable: " + name + " does not exist"); - } - } - return nullptr; - } - } else { - variablePtr = variableIt->second; - } - } - // if no success try to retrieve variable from root script state, but only when expecting variable aka reading variable - if (global == true || (expectVariable == true && variablePtr == nullptr)) { - const auto& scriptState = getRootScriptState(); - auto variableIt = scriptState.variables.find(extractedVariableName.empty() == false?extractedVariableName:name); - if (variableIt == scriptState.variables.end()) { - if (expectVariable == true) { - if (statement != nullptr) { - _Console::println(getStatementInformation(*statement) + ": variable: " + name + " does not exist"); - } else { - _Console::println(scriptFileName + ": variable: " + name + " does not exist"); - } - } - return nullptr; - } else { - variablePtr = variableIt->second; - } - } // - if (variablePtr == nullptr) return nullptr; // get pointer to children variable if (haveAccessOperator == false) { // @@ -3515,9 +3525,9 @@ inline MiniScript::Variable* MiniScript::getVariableIntern(const string& name, c } else { if (expectVariable == true) { if (statement != nullptr) { - _Console::println(getStatementInformation(*statement) + ": variable: " + name + ": key not found: '" + key + "'"); + _Console::println(getStatementInformation(*statement) + ": variable: " + variableStatement + ": key not found: '" + key + "'"); } else { - _Console::println(scriptFileName + "': variable: " + name + ": key not found: '" + key + "'"); + _Console::println(scriptFileName + "': variable: " + variableStatement + ": key not found: '" + key + "'"); } } // we have our parent @@ -3546,9 +3556,9 @@ inline MiniScript::Variable* MiniScript::getVariableIntern(const string& name, c } } else { if (statement != nullptr) { - _Console::println(getStatementInformation(*statement) + ": variable: " + name + ": map/set access operator, but variable is not of type map/set"); + _Console::println(getStatementInformation(*statement) + ": variable: " + variableStatement + ": map/set access operator, but variable is not of type map/set"); } else { - _Console::println(scriptFileName + ": variable: " + name + ": map/set access operator, but variable is not of type map/set"); + _Console::println(scriptFileName + ": variable: " + variableStatement + ": map/set access operator, but variable is not of type map/set"); } return nullptr; } @@ -3568,9 +3578,9 @@ inline MiniScript::Variable* MiniScript::getVariableIntern(const string& name, c return nullptr; } else { if (statement != nullptr) { - _Console::println(getStatementInformation(*statement) + ": variable: " + name + ": index out of bounds: 0 <= " + to_string(arrayIdx) + " < " + to_string(variablePtr->getByteArrayValueReference().size())); + _Console::println(getStatementInformation(*statement) + ": variable: " + variableStatement + ": index out of bounds: 0 <= " + to_string(arrayIdx) + " < " + to_string(variablePtr->getByteArrayValueReference().size())); } else { - _Console::println(scriptFileName + ": variable: " + name + ": index out of bounds: 0 <= " + to_string(arrayIdx) + " <= " + to_string(variablePtr->getByteArrayValueReference().size())); + _Console::println(scriptFileName + ": variable: " + variableStatement + ": index out of bounds: 0 <= " + to_string(arrayIdx) + " <= " + to_string(variablePtr->getByteArrayValueReference().size())); } return nullptr; } @@ -3590,17 +3600,17 @@ inline MiniScript::Variable* MiniScript::getVariableIntern(const string& name, c variablePtr = variablePtr->getArrayValueReference()[arrayIdx]; } else { if (statement != nullptr) { - _Console::println(getStatementInformation(*statement) + ": variable: " + name + ": index out of bounds: 0 <= " + to_string(arrayIdx) + " < " + to_string(variablePtr->getArrayValueReference().size())); + _Console::println(getStatementInformation(*statement) + ": variable: " + variableStatement + ": index out of bounds: 0 <= " + to_string(arrayIdx) + " < " + to_string(variablePtr->getArrayValueReference().size())); } else { - _Console::println(scriptFileName + ": variable: " + name + ": index out of bounds: 0 <= " + to_string(arrayIdx) + " <= " + to_string(variablePtr->getArrayValueReference().size())); + _Console::println(scriptFileName + ": variable: " + variableStatement + ": index out of bounds: 0 <= " + to_string(arrayIdx) + " <= " + to_string(variablePtr->getArrayValueReference().size())); } return nullptr; } } else { if (statement != nullptr) { - _Console::println(getStatementInformation(*statement) + ": variable: " + name + ": (byte) array access operator, expected (byte) array, but got: " + variablePtr->getValueAsString()); + _Console::println(getStatementInformation(*statement) + ": variable: " + variableStatement + ": (byte) array access operator, expected (byte) array, but got: " + variablePtr->getValueAsString()); } else { - _Console::println(scriptFileName + ": variable: " + name + ": (byte) array access operator, expected (byte) array, but got: " + variablePtr->getValueAsString()); + _Console::println(scriptFileName + ": variable: " + variableStatement + ": (byte) array access operator, expected (byte) array, but got: " + variablePtr->getValueAsString()); } return nullptr; } @@ -3610,7 +3620,7 @@ inline MiniScript::Variable* MiniScript::getVariableIntern(const string& name, c auto accessOperatorStartIdx = accessOperatorRightIdx; accessOperatorLeftIdx = string::npos; accessOperatorRightIdx = string::npos; - if (getVariableAccessOperatorLeftRightIndices(name, callerMethod, accessOperatorLeftIdx, accessOperatorRightIdx, statement, accessOperatorStartIdx) == false) { + if (getVariableAccessOperatorLeftRightIndices(variableStatement, callerMethod, accessOperatorLeftIdx, accessOperatorRightIdx, statement, accessOperatorStartIdx) == false) { // fail return nullptr; } @@ -3621,7 +3631,7 @@ inline MiniScript::Variable* MiniScript::getVariableIntern(const string& name, c return variablePtr; } else { // yep, evaluate it - if (evaluateAccess(name, callerMethod, accessOperatorLeftIdx, accessOperatorRightIdx, arrayIdx, key, statement) == false) { + if (evaluateAccess(variableStatement, callerMethod, accessOperatorLeftIdx, accessOperatorRightIdx, arrayIdx, key, statement) == false) { return nullptr; } } @@ -3631,6 +3641,185 @@ inline MiniScript::Variable* MiniScript::getVariableIntern(const string& name, c } } +inline MiniScript::Variable* MiniScript::getVariableIntern(const string& variableStatement, const string& callerMethod, string& variableName, Variable*& parentVariable, int64_t& arrayIdx, string& key, int& setAccessBool, const Statement* statement, bool expectVariable, bool global) { + // + if (isVariableAccess(variableStatement) == false) { + if (statement != nullptr) { + _Console::println(getStatementInformation(*statement) + ": variable: " + variableStatement + ": variable names must start with an $"); + } else { + _Console::println(scriptFileName + ": variable: " + variableStatement + ": variable names must start with an $"); + } + return nullptr; + } + // determine variable name + { + auto dotIdx = _StringTools::indexOf(variableStatement, "."); + if (dotIdx == string::npos) dotIdx = variableStatement.size(); + auto squareBracketIdx = _StringTools::indexOf(variableStatement, "["); + if (squareBracketIdx == string::npos) squareBracketIdx = variableStatement.size(); + variableName = _StringTools::substring(variableStatement, 0, dotIdx < squareBracketIdx?dotIdx:squareBracketIdx); + } + // retrieve variable from function script state + Variable* variablePtr = nullptr; + if (global == false) { + const auto& scriptState = getScriptState(); + auto variableIt = scriptState.variables.find(variableName); + if (variableIt == scriptState.variables.end()) { + if (isFunctionRunning() == false) { + if (expectVariable == true) { + if (statement != nullptr) { + _Console::println(getStatementInformation(*statement) + ": variable: " + variableStatement + " does not exist"); + } else { + _Console::println(scriptFileName + ": variable: " + variableStatement + " does not exist"); + } + } + return nullptr; + } + } else { + variablePtr = variableIt->second; + } + } + // if no success try to retrieve variable from root script state, but only when expecting variable aka reading variable + if (global == true || (expectVariable == true && variablePtr == nullptr)) { + const auto& scriptState = getRootScriptState(); + auto variableIt = scriptState.variables.find(variableName); + if (variableIt == scriptState.variables.end()) { + if (expectVariable == true) { + if (statement != nullptr) { + _Console::println(getStatementInformation(*statement) + ": variable: " + variableStatement + " does not exist"); + } else { + _Console::println(scriptFileName + ": variable: " + variableStatement + " does not exist"); + } + } + return nullptr; + } else { + variablePtr = variableIt->second; + } + } + // + if (variablePtr == nullptr) return nullptr; + // + return evaluateVariableAccessIntern(variablePtr, variableStatement, callerMethod, parentVariable, arrayIdx, key, setAccessBool, statement, expectVariable); +} + +inline void MiniScript::setVariableInternal(const string& variableStatement, Variable* parentVariable, Variable* variablePtr, int64_t arrayIdx, const string& key, const Variable& variable, const Statement* statement, bool createReference) { + // common case + if (variablePtr != nullptr) { + if (variablePtr->isConstant() == false) { + *variablePtr = variable; + } else { + _Console::println(getStatementInformation(*statement) + ": constant: " + variableStatement + ": Assignment of constant is not allowed"); + } + return; + } else + // array add operator + if (key.empty() == false) { + if (parentVariable == nullptr) { + string callerMethod = __FUNCTION__; + if (statement != nullptr) { + _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + variableStatement + ": map access operator without map: '" + key + "'"); + } else { + _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + variableStatement + ": map access operator without map: '" + key + "'"); + } + } else + // all checks passed, push to map + if (parentVariable->getType() == MiniScript::TYPE_MAP) { + // check if our parent is not a const variable + if (parentVariable->isConstant() == false) { + parentVariable->setMapEntry(key, createReference == false?Variable::createNonReferenceVariable(&variable):Variable::createReferenceVariable(&variable)); + } else { + _Console::println(getStatementInformation(*statement) + ": constant: " + variableStatement + ": Assignment of constant is not allowed"); + } + } else + if (parentVariable->getType() == MiniScript::TYPE_SET) { + // check if our parent is not a const variable + if (parentVariable->isConstant() == false) { + bool booleanValue; + if (variable.getBooleanValue(booleanValue, false) == true) { + if (booleanValue == true) { + parentVariable->insertSetKey(key); + } else { + parentVariable->removeSetKey(key); + } + } else { + string callerMethod = __FUNCTION__; + _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + variableStatement + ": set access operator: expected boolean variable to remove/insert key in set, but got " + variable.getTypeAsString()); + } + } else { + _Console::println(getStatementInformation(*statement) + ": constant: " + variableStatement + ": Assignment of constant is not allowed"); + } + } else { + string callerMethod = __FUNCTION__; + if (statement != nullptr) { + _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + variableStatement + ": map/set access operator: expected map/set, but got " + parentVariable->getTypeAsString() + ": '" + key + "'"); + } else { + _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + variableStatement + ": map/set access operator: expected map/set, but got " + parentVariable->getTypeAsString() + ": '" + key + "'"); + } + } + // + return; + } else + if (arrayIdx == ARRAYIDX_ADD) { + if (parentVariable == nullptr) { + string callerMethod = __FUNCTION__; + if (statement != nullptr) { + _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + variableStatement + ": [] array push operator without array"); + } else { + _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + variableStatement + ": [] array push operator without array"); + } + } else + if (parentVariable->getType() == MiniScript::TYPE_BYTEARRAY) { + // check if our parent is not a const variable + if (parentVariable->isConstant() == false) { + // all checks passed, push variable to array + uint8_t value; + if (variable.getByteValue(this, value, statement) == true) { + parentVariable->pushByteArrayEntry(value); + } + } else { + _Console::println(getStatementInformation(*statement) + ": constant: " + variableStatement + ": Assignment of constant is not allowed"); + } + } else + if (parentVariable->getType() == MiniScript::TYPE_ARRAY) { + // check if our parent is not a const variable + if (parentVariable->isConstant() == false) { + // all checks passed, push variable to array + parentVariable->pushArrayEntry(createReference == false?Variable::createNonReferenceVariable(&variable):Variable::createReferenceVariable(&variable)); + } else { + _Console::println(getStatementInformation(*statement) + ": constant: " + variableStatement + ": Assignment of constant is not allowed"); + } + } else { + string callerMethod = __FUNCTION__; + if (statement != nullptr) { + _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + variableStatement + ": [] array push operator: expected byte array or array, but got " + parentVariable->getTypeAsString()); + } else { + _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + variableStatement + ": [] array push operator: expected byte array or array, but got " + parentVariable->getTypeAsString()); + } + } + // + return; + } else + // special case for accessing byte array entries at given array index + if (arrayIdx >= ARRAYIDX_FIRST && parentVariable != nullptr && parentVariable->getType() == TYPE_BYTEARRAY) { + // check if our parent is not a const variable + if (parentVariable->isConstant() == false) { + uint8_t value; + if (variable.getByteValue(this, value, statement) == true) { + parentVariable->pushByteArrayEntry(value); + } else { + string callerMethod = __FUNCTION__; + if (statement != nullptr) { + _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + variableStatement + ": [] byte array push operator: expected byte integer value (0 <= byte <= 255), but got " + variable.getTypeAsString()); + } else { + _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + variableStatement + ": [] byte array push operator: expected byte integer value (0 <= byte <= 255), but got " + variable.getTypeAsString()); + } + } + } else { + _Console::println(getStatementInformation(*statement) + ": constant: " + variableStatement + ": Assignment of constant is not allowed"); + } + } +} + inline bool MiniScript::evaluateInternal(const string& statement, const string& executableStatement, Variable& returnValue, bool pushOwnScriptState) { Statement evaluateStatement( LINE_NONE, @@ -3719,18 +3908,18 @@ inline bool MiniScript::viewIsKey(const string_view& candidate) { return true; } -inline bool MiniScript::getVariableAccessOperatorLeftRightIndices(const string& name, const string& callerMethod, string::size_type& accessOperatorLeftIdx, string::size_type& accessOperatorRightIdx, const Statement* statement, int startIdx) { +inline bool MiniScript::getVariableAccessOperatorLeftRightIndices(const string& variableStatement, const string& callerMethod, string::size_type& accessOperatorLeftIdx, string::size_type& accessOperatorRightIdx, const Statement* statement, int startIdx) { accessOperatorLeftIdx = string::npos; accessOperatorRightIdx = string::npos; auto haveKey = false; auto squareBracketsCount = 0; // improve me! if (startIdx > 0) { - haveKey = name[startIdx - 1] == '.'; + haveKey = variableStatement[startIdx - 1] == '.'; if (haveKey == true) accessOperatorLeftIdx = startIdx - 1; } - for (auto i = startIdx; i < name.length(); i++) { - auto c = name[i]; + for (auto i = startIdx; i < variableStatement.length(); i++) { + auto c = variableStatement[i]; if (haveKey == true) { if (c == '.') { // @@ -3746,9 +3935,9 @@ inline bool MiniScript::getVariableAccessOperatorLeftRightIndices(const string& } if (c == ']') { if (statement != nullptr) { - _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + name + ": unexpected char: ']'"); + _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + variableStatement + ": unexpected char: ']'"); } else { - _Console::println("MiniScript::" + callerMethod + "(): " + scriptFileName + ": variable: " + name + ": variable: " + name + ": unexpected char: ']'"); + _Console::println("MiniScript::" + callerMethod + "(): " + scriptFileName + ": variable: " + variableStatement + ": variable: " + variableStatement + ": unexpected char: ']'"); } return false; } @@ -3771,30 +3960,30 @@ inline bool MiniScript::getVariableAccessOperatorLeftRightIndices(const string& } else if (squareBracketsCount < 0) { if (statement != nullptr) { - _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + name + ": unexpected char: ']'"); + _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + variableStatement + ": unexpected char: ']'"); } else { - _Console::println("MiniScript::" + callerMethod + "(): " + scriptFileName + ": variable: " + name + ": variable: " + name + ": unexpected char: ']'"); + _Console::println("MiniScript::" + callerMethod + "(): " + scriptFileName + ": variable: " + variableStatement + ": variable: " + variableStatement + ": unexpected char: ']'"); } return false; } } } // - if (haveKey == true) accessOperatorRightIdx = name.size(); + if (haveKey == true) accessOperatorRightIdx = variableStatement.size(); // return true; } -inline bool MiniScript::evaluateAccess(const string& name, const string& callerMethod, string::size_type& arrayAccessOperatorLeftIdx, string::size_type& arrayAccessOperatorRightIdx, int64_t& arrayIdx, string& key, const Statement* statement) { +inline bool MiniScript::evaluateAccess(const string& variableStatement, const string& callerMethod, string::size_type& arrayAccessOperatorLeftIdx, string::size_type& arrayAccessOperatorRightIdx, int64_t& arrayIdx, string& key, const Statement* statement) { key.clear(); arrayIdx = ARRAYIDX_NONE; // check for dot access - if (name.data()[arrayAccessOperatorLeftIdx] == '.') { - key = string(_StringTools::viewTrim(string_view(&name.data()[arrayAccessOperatorLeftIdx + 1], arrayAccessOperatorRightIdx - arrayAccessOperatorLeftIdx - 1))); + if (variableStatement.data()[arrayAccessOperatorLeftIdx] == '.') { + key = string(_StringTools::viewTrim(string_view(&variableStatement.data()[arrayAccessOperatorLeftIdx + 1], arrayAccessOperatorRightIdx - arrayAccessOperatorLeftIdx - 1))); return true; } // evaluate array index - auto arrayIdxExpressionStringView = _StringTools::viewTrim(string_view(&name.data()[arrayAccessOperatorLeftIdx + 1], arrayAccessOperatorRightIdx - arrayAccessOperatorLeftIdx - 2)); + auto arrayIdxExpressionStringView = _StringTools::viewTrim(string_view(&variableStatement.data()[arrayAccessOperatorLeftIdx + 1], arrayAccessOperatorRightIdx - arrayAccessOperatorLeftIdx - 2)); if (arrayIdxExpressionStringView.empty() == false) { // integer first for performance if (_Integer::viewIs(arrayIdxExpressionStringView) == true) { @@ -3805,9 +3994,9 @@ inline bool MiniScript::evaluateAccess(const string& name, const string& callerM auto evaluateStatement = string(arrayIdxExpressionStringView); if (evaluateInternal(evaluateStatement, evaluateStatement, statementReturnValue, false) == false || statementReturnValue.getIntegerValue(arrayIdx, false) == false) { if (statement != nullptr) { - _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + name + ": failed to evaluate expression: '" + string(arrayIdxExpressionStringView) + "'"); + _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + variableStatement + ": failed to evaluate expression: '" + string(arrayIdxExpressionStringView) + "'"); } else { - _Console::println("MiniScript::" + callerMethod + "(): " + scriptFileName + ": variable: " + name + ": failed to evaluate expression: '" + string(arrayIdxExpressionStringView) + "'"); + _Console::println("MiniScript::" + callerMethod + "(): " + scriptFileName + ": variable: " + variableStatement + ": failed to evaluate expression: '" + string(arrayIdxExpressionStringView) + "'"); } // return false; diff --git a/ext/miniscript/src/miniscript/miniscript/MiniScript.h b/ext/miniscript/src/miniscript/miniscript/MiniScript.h index 5beb1b1d3..13e43a9fb 100644 --- a/ext/miniscript/src/miniscript/miniscript/MiniScript.h +++ b/ext/miniscript/src/miniscript/miniscript/MiniScript.h @@ -183,6 +183,12 @@ class miniscript::miniscript::MiniScript { return mathDataType; } + /** + * Register constants + * @param miniScript MiniScript instance + */ + virtual void registerConstants(MiniScript* miniScript) const = 0; + /** * Register methods * @param miniScript MiniScript instance @@ -671,6 +677,17 @@ class miniscript::miniscript::MiniScript { MINISCRIPT_STATIC_DLL_IMPEXT static const string TYPENAME_MAP; MINISCRIPT_STATIC_DLL_IMPEXT static const string TYPENAME_SET; + /** + * Unset variable + */ + inline void unset() { + if (isReference() == true) { + ir.reference->releaseReference(); + unsetReference(); + } + setType(TYPE_NULL); + } + /** * Create reference variable * @param variable variable @@ -699,6 +716,38 @@ class miniscript::miniscript::MiniScript { return referenceVariable; } + /** + * Create none reference variable + * @param variable variable + * @returns reference variable + */ + inline static Variable createNonReferenceVariable(const Variable* variable) { + // copy a non reference variable is cheap + if (variable->isReference() == false) return *variable; + // otherwise do the copy + Variable nonReferenceVariable; + // + copyVariable(nonReferenceVariable, *variable); + // + return nonReferenceVariable; + } + + /** + * Create none reference variable pointer + * @param variable variable + * @returns reference variable + */ + inline static Variable* createNonReferenceVariablePointer(const Variable* variable) { + // copy a non reference variable is cheap + if (variable->isReference() == false) return new Variable(*variable); + // otherwise do the copy + Variable* nonReferenceVariable = new Variable(); + // + copyVariable(*nonReferenceVariable, *variable); + // + return nonReferenceVariable; + } + /** * Copy variable * @param from from @@ -771,38 +820,6 @@ class miniscript::miniscript::MiniScript { if (from.isConstant() == true) to.setConstant(); } - /** - * Create none reference variable - * @param variable variable - * @returns reference variable - */ - inline static Variable createNonReferenceVariable(const Variable* variable) { - // copy a non reference variable is cheap - if (variable->isReference() == false) return *variable; - // otherwise do the copy - Variable nonReferenceVariable; - // - copyVariable(nonReferenceVariable, *variable); - // - return nonReferenceVariable; - } - - /** - * Create none reference variable pointer - * @param variable variable - * @returns reference variable - */ - inline static Variable* createNonReferenceVariablePointer(const Variable* variable) { - // copy a non reference variable is cheap - if (variable->isReference() == false) return new Variable(*variable); - // otherwise do the copy - Variable* nonReferenceVariable = new Variable(); - // - copyVariable(*nonReferenceVariable, *variable); - // - return nonReferenceVariable; - } - /** * Copy constructor * @param variable variable to copy @@ -2606,8 +2623,9 @@ class miniscript::miniscript::MiniScript { */ inline void popScriptState() { if (scriptStateStack.empty() == true) return; - const auto& scriptState = getScriptState(); + auto& scriptState = getScriptState(); for (const auto& [variableName, variable]: scriptState.variables) delete variable; + scriptState.variables.clear(); scriptStateStack.erase(scriptStateStack.begin() + scriptStateStack.size() - 1); } @@ -2780,18 +2798,18 @@ class miniscript::miniscript::MiniScript { /** * Get access operator left and right indices - * @param name name + * @param variableStatement variable statement * @param callerMethod caller method * @param accessOperatorLeftIdx access operator left idx * @param accessOperatorRightIdx access operator right idx * @param statement statement * @param startIdx startIdx */ - bool getVariableAccessOperatorLeftRightIndices(const string& name, const string& callerMethod, string::size_type& accessOperatorLeftIdx, string::size_type& accessOperatorRightIdx, const Statement* statement = nullptr, int startIdx = 0); + bool getVariableAccessOperatorLeftRightIndices(const string& variableStatement, const string& callerMethod, string::size_type& accessOperatorLeftIdx, string::size_type& accessOperatorRightIdx, const Statement* statement = nullptr, int startIdx = 0); /** * Evaluate access - * @param name name + * @param variableStatement variable statement * @param callerMethod caller method * @param arrayAccessOperatorLeftIdx array access operator left idx * @param arrayAccessOperatorRightIdx array access operator right idx @@ -2799,11 +2817,12 @@ class miniscript::miniscript::MiniScript { * @param key map key * @param statement statement */ - bool evaluateAccess(const string& name, const string& callerMethod, string::size_type& arrayAccessOperatorLeftIdx, string::size_type& arrayAccessOperatorRightIdx, int64_t& arrayIdx, string& key, const Statement* statement = nullptr); + bool evaluateAccess(const string& variableStatement, const string& callerMethod, string::size_type& arrayAccessOperatorLeftIdx, string::size_type& arrayAccessOperatorRightIdx, int64_t& arrayIdx, string& key, const Statement* statement = nullptr); /** * Returns pointer of variable with given name or nullptr - * @param name name + * @param variablePtr pointer to variable + * @param variableStatement variable statement * @param callerMethod caller method * @param parentVariable parent variable * @param arrayIdx array index whereas there is ARRAYIDX_ADD for [] or ARRAYIDX_NONE for no array access @@ -2811,10 +2830,38 @@ class miniscript::miniscript::MiniScript { * @param setAccessBool set access bool which returns one of SETACCESSBOOL_NONE, *_TRUE, *_FALSE * @param statement optional statement the variable is read in * @param expectVariable expect variable which controls verbosity + * @return pointer to variable + */ + Variable* evaluateVariableAccessIntern(Variable* variablePtr, const string& variableStatement, const string& callerMethod, Variable*& parentVariable, int64_t& arrayIdx, string& key, int& setAccessBool, const Statement* statement = nullptr, bool expectVariable = true); + + /** + * Returns pointer of variable with given name or nullptr + * @param variableStatement variable statement + * @param callerMethod caller method + * @param variableName variable name + * @param parentVariable parent variable + * @param arrayIdx array index whereas there is ARRAYIDX_ADD for [] or ARRAYIDX_NONE for no array access + * @param key key + * @param setAccessBool set access bool which returns one of SETACCESSBOOL_NONE, *_TRUE, *_FALSE + * @param statement optional statement the variable is read in + * @param expectVariable expect variable which controls verbosity * @param global use global context instead of current context * @return pointer to variable */ - Variable* getVariableIntern(const string& name, const string& callerMethod, Variable*& parentVariable, int64_t& arrayIdx, string& key, int& setAccessBool, const Statement* statement = nullptr, bool expectVariable = true, bool global = false); + Variable* getVariableIntern(const string& variableStatement, const string& callerMethod, string& variableName, Variable*& parentVariable, int64_t& arrayIdx, string& key, int& setAccessBool, const Statement* statement = nullptr, bool expectVariable = true, bool global = false); + + /** + * Set variable internal + * @param variableStatement variable statement + * @param parentVariable parent variable + * @param variablePtr variable pointer + * @param arrayIdx array index + * @param key key + * @param variable variable + * @param statement optional statement the variable is written in + * @param createReference optional flag for creating variable references + */ + void setVariableInternal(const string& variableStatement, Variable* parentVariable, Variable* variablePtr, int64_t arrayIdx, const string& key, const Variable& variable, const Statement* statement = nullptr, bool createReference = false); /** * Evaluate given statement without executing preprocessor run @@ -3058,7 +3105,7 @@ class miniscript::miniscript::MiniScript { if (c == ']') { squareBracketCount--; } else - if (squareBracketCount == 0 && _Character::isAlphaNumeric(c) == false && c != '_' && c != '.') { + if (squareBracketCount == 0 && _Character::isAlphaNumeric(c) == false && c != '_' && c != '.' && c != ':') { return false; } } @@ -3440,7 +3487,7 @@ class miniscript::miniscript::MiniScript { if (c == ']') { squareBracketCount--; } else - if (squareBracketCount == 0 && _Character::isAlphaNumeric(c) == false && c != '_' && c != '.') { + if (squareBracketCount == 0 && _Character::isAlphaNumeric(c) == false && c != '_' && c != '.' && c != ':') { return false; } } @@ -3448,25 +3495,102 @@ class miniscript::miniscript::MiniScript { } /** - * Returns variable with given name + * Returns if variable with given name exists * @param name name * @param statement optional statement the variable is read in + * @return variable exists + */ + inline bool hasVariable(const string& name, const Statement* statement = nullptr) { + // + string variableName; + // global accessor + string globalVariableStatement; + if (_StringTools::startsWith(name, "$GLOBAL.") == true) { + globalVariableStatement = "$" + _StringTools::substring(name, 8); + } + + // + Variable* parentVariable = nullptr; + string key; + int64_t arrayIdx = ARRAYIDX_NONE; + int setAccessBool = SETACCESSBOOL_NONE; + auto variablePtr = getVariableIntern(globalVariableStatement.empty() == true?name:globalVariableStatement, __FUNCTION__, variableName, parentVariable, arrayIdx, key, setAccessBool, statement, false, globalVariableStatement.empty() == false); + // set '.' operator + if (setAccessBool != SETACCESSBOOL_NONE) { + return true; + } else + // we have a pointer to a ordinary variable + if (variablePtr != nullptr) { + return true; + } else { + // special case for accessing byte array entries at given array index + if (parentVariable != nullptr && parentVariable->getType() == TYPE_BYTEARRAY && arrayIdx >= ARRAYIDX_FIRST) { + return true; + } else { + // nothing to return + return false; + } + } + } + + /** + * Returns variable with given name + * @param variableStatement variable statement + * @param statement optional statement the variable is read in * @param createReference optional flag for creating variable references * @return variable */ - inline const Variable getVariable(const string& name, const Statement* statement = nullptr, bool createReference = false) { + inline const Variable getVariable(const string& variableStatement, const Statement* statement = nullptr, bool createReference = false) { + // + string variableName; // global accessor - string globalVariableName; - if (_StringTools::startsWith(name, "$GLOBAL.") == true) { - globalVariableName = "$" + _StringTools::trim(_StringTools::substring(name, 8)); + string globalVariableStatement; + if (_StringTools::startsWith(variableStatement, "$GLOBAL.") == true) { + globalVariableStatement = "$" + _StringTools::substring(variableStatement, 8); + } + + // + Variable* parentVariable = nullptr; + string key; + int64_t arrayIdx = ARRAYIDX_NONE; + int setAccessBool = SETACCESSBOOL_NONE; + auto variablePtr = getVariableIntern(globalVariableStatement.empty() == true?variableStatement:globalVariableStatement, __FUNCTION__, variableName, parentVariable, arrayIdx, key, setAccessBool, statement, true, globalVariableStatement.empty() == false); + // set '.' operator + if (setAccessBool != SETACCESSBOOL_NONE) { + return Variable(setAccessBool == SETACCESSBOOL_TRUE); + } else + // we have a pointer to a ordinary variable + if (variablePtr != nullptr) { + // if we return any variable we can safely remove the constness, a reference can of course keep its constness + auto variable = createReference == false?*variablePtr:Variable::createReferenceVariable(variablePtr); + variable.unsetConstant(); + return variable; + } else { + // special case for accessing byte array entries at given array index + if (parentVariable != nullptr && parentVariable->getType() == TYPE_BYTEARRAY && arrayIdx >= ARRAYIDX_FIRST) { + return Variable(static_cast(parentVariable->getByteArrayEntry(arrayIdx))); + } else { + // nothing to return + return Variable(); + } } + } + /** + * Returns variable with given name + * @param variablePtr variable pointer + * @param variableStatement variable statement + * @param statement optional statement the variable is read in + * @param createReference optional flag for creating variable references + * @return variable + */ + inline const Variable getVariable(Variable* variablePtr, const string& variableStatement, const Statement* statement = nullptr, bool createReference = false) { // Variable* parentVariable = nullptr; string key; int64_t arrayIdx = ARRAYIDX_NONE; int setAccessBool = SETACCESSBOOL_NONE; - auto variablePtr = getVariableIntern(globalVariableName.empty() == true?name:globalVariableName, __FUNCTION__, parentVariable, arrayIdx, key, setAccessBool, statement, true, globalVariableName.empty() == false); + variablePtr = evaluateVariableAccessIntern(variablePtr, variableStatement, __FUNCTION__, parentVariable, arrayIdx, key, setAccessBool, statement, true); // set '.' operator if (setAccessBool != SETACCESSBOOL_NONE) { return Variable(setAccessBool == SETACCESSBOOL_TRUE); @@ -3488,18 +3612,30 @@ class miniscript::miniscript::MiniScript { } } + /** + * Set constant + * @param variableStatement variable statement + * @param variable variable + */ + inline void setConstant(const string& variableStatement, const Variable& variable) { + auto constVariable = variable; + setConstant(constVariable); + setVariable(variableStatement, constVariable); + } + /** * Set variable - * @param name name + * @param variableStatement variable statement * @param variable variable * @param statement optional statement the variable is written in * @param createReference optional flag for creating variable references */ - inline void setVariable(const string& name, const Variable& variable, const Statement* statement = nullptr, bool createReference = false) { + inline void setVariable(const string& variableStatement, const Variable& variable, const Statement* statement = nullptr, bool createReference = false) { + string variableName; // global accessor - string globalVariableName; - if (_StringTools::startsWith(name, "$GLOBAL.") == true) { - globalVariableName = "$" + _StringTools::trim(_StringTools::substring(name, 8)); + string globalVariableStatement; + if (_StringTools::startsWith(variableStatement, "$GLOBAL.") == true) { + globalVariableStatement = "$" + _StringTools::substring(variableStatement, 8); } // @@ -3507,140 +3643,57 @@ class miniscript::miniscript::MiniScript { string key; int64_t arrayIdx = ARRAYIDX_NONE; int setAccessBool = SETACCESSBOOL_NONE; - auto variablePtr = getVariableIntern(globalVariableName.empty() == true?name:globalVariableName, __FUNCTION__, parentVariable, arrayIdx, key, setAccessBool, statement, false, globalVariableName.empty() == false); - // common case - if (variablePtr != nullptr) { - if (variablePtr->isConstant() == false) { - *variablePtr = variable; - } else { - _Console::println(getStatementInformation(*statement) + ": constant: " + name + ": Assignment of constant is not allowed"); - } - return; - } else - // array add operator - if (key.empty() == false) { - if (parentVariable == nullptr) { - string callerMethod = __FUNCTION__; - if (statement != nullptr) { - _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + name + ": map access operator without map: '" + key + "'"); + auto variablePtr = getVariableIntern(globalVariableStatement.empty() == true?variableStatement:globalVariableStatement, __FUNCTION__, variableName, parentVariable, arrayIdx, key, setAccessBool, statement, false, globalVariableStatement.empty() == false); + + // set variable if not yet done + if (variablePtr == nullptr && parentVariable == nullptr) { + // default + auto& scriptState = globalVariableStatement.empty() == true?getScriptState():getRootScriptState(); + auto variableIt = scriptState.variables.find(globalVariableStatement.empty() == true?variableStatement:globalVariableStatement); + if (variableIt != scriptState.variables.end()) { + auto& existingVariable = variableIt->second; + if (existingVariable->isConstant() == false) { + // if we set a variable in variable scope that did exist before, we can safely remove the constness + *existingVariable = variable; } else { - _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + name + ": map access operator without map: '" + key + "'"); - } - } else - // all checks passed, push to map - if (parentVariable->getType() == MiniScript::TYPE_MAP) { - // check if our parent is not a const variable - if (parentVariable->isConstant() == false) { - parentVariable->setMapEntry(key, createReference == false?Variable::createNonReferenceVariable(&variable):Variable::createReferenceVariable(&variable)); - } else { - _Console::println(getStatementInformation(*statement) + ": constant: " + name + ": Assignment of constant is not allowed"); - } - } else - if (parentVariable->getType() == MiniScript::TYPE_SET) { - // check if our parent is not a const variable - if (parentVariable->isConstant() == false) { - bool booleanValue; - if (variable.getBooleanValue(booleanValue, false) == true) { - if (booleanValue == true) { - parentVariable->insertSetKey(key); - } else { - parentVariable->removeSetKey(key); - } - } else { - string callerMethod = __FUNCTION__; - _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + name + ": set access operator: expected boolean variable to remove/insert key in set, but got " + variable.getTypeAsString()); - } - } else { - _Console::println(getStatementInformation(*statement) + ": constant: " + name + ": Assignment of constant is not allowed"); - } - } else { - string callerMethod = __FUNCTION__; - if (statement != nullptr) { - _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + name + ": map/set access operator: expected map/set, but got " + parentVariable->getTypeAsString() + ": '" + key + "'"); - } else { - _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + name + ": map/set access operator: expected map/set, but got " + parentVariable->getTypeAsString() + ": '" + key + "'"); - } - } - // - return; - } else - if (arrayIdx == ARRAYIDX_ADD) { - if (parentVariable == nullptr) { - string callerMethod = __FUNCTION__; - if (statement != nullptr) { - _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + name + ": [] array push operator without array"); - } else { - _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + name + ": [] array push operator without array"); - } - } else - if (parentVariable->getType() == MiniScript::TYPE_BYTEARRAY) { - // check if our parent is not a const variable - if (parentVariable->isConstant() == false) { - // all checks passed, push variable to array - uint8_t value; - if (variable.getByteValue(this, value, statement) == true) { - parentVariable->pushByteArrayEntry(value); - } - } else { - _Console::println(getStatementInformation(*statement) + ": constant: " + name + ": Assignment of constant is not allowed"); - } - } else - if (parentVariable->getType() == MiniScript::TYPE_ARRAY) { - // check if our parent is not a const variable - if (parentVariable->isConstant() == false) { - // all checks passed, push variable to array - parentVariable->pushArrayEntry(createReference == false?Variable::createNonReferenceVariable(&variable):Variable::createReferenceVariable(&variable)); - } else { - _Console::println(getStatementInformation(*statement) + ": constant: " + name + ": Assignment of constant is not allowed"); - } - } else { - string callerMethod = __FUNCTION__; - if (statement != nullptr) { - _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + name + ": [] array push operator: expected byte array or array, but got " + parentVariable->getTypeAsString()); - } else { - _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + name + ": [] array push operator: expected byte array or array, but got " + parentVariable->getTypeAsString()); - } - } - // - return; - } else - // special case for accessing byte array entries at given array index - if (arrayIdx >= ARRAYIDX_FIRST && parentVariable != nullptr && parentVariable->getType() == TYPE_BYTEARRAY) { - // check if our parent is not a const variable - if (parentVariable->isConstant() == false) { - uint8_t value; - if (variable.getByteValue(this, value, statement) == true) { - parentVariable->pushByteArrayEntry(value); - } else { - string callerMethod = __FUNCTION__; - if (statement != nullptr) { - _Console::println("MiniScript::" + callerMethod + "(): " + getStatementInformation(*statement) + ": variable: " + name + ": [] byte array push operator: expected byte integer value (0 <= byte <= 255), but got " + variable.getTypeAsString()); - } else { - _Console::println("MiniScript::" + callerMethod + "(): '" + scriptFileName + "': variable: " + name + ": [] byte array push operator: expected byte integer value (0 <= byte <= 255), but got " + variable.getTypeAsString()); - } + _Console::println(getStatementInformation(*statement) + ": constant: " + variableStatement + ": Assignment of constant is not allowed"); } + return; } else { - _Console::println(getStatementInformation(*statement) + ": constant: " + name + ": Assignment of constant is not allowed"); + // if we set a variable in variable scope that did not exist before, we keep things as they are regarding constness + scriptState.variables[globalVariableStatement.empty() == true?variableStatement:globalVariableStatement] = + createReference == false?Variable::createNonReferenceVariablePointer(&variable):Variable::createReferenceVariablePointer(&variable); } + } else { + setVariableInternal(variableStatement, parentVariable, variablePtr, arrayIdx, key, variable, statement, createReference); } + } - // default - auto& scriptState = globalVariableName.empty() == true?getScriptState():getRootScriptState(); - auto variableIt = scriptState.variables.find(globalVariableName.empty() == true?name:globalVariableName); - if (variableIt != scriptState.variables.end()) { - auto& existingVariable = variableIt->second; - if (existingVariable->isConstant() == false) { - // if we set a variable in variable scope that did exist before, we can safely remove the constness - *existingVariable = variable; - } else { - _Console::println(getStatementInformation(*statement) + ": constant: " + name + ": Assignment of constant is not allowed"); - } - return; - } else { - // if we set a variable in variable scope that did not exist before, we keep things as they are regarding constness - scriptState.variables[globalVariableName.empty() == true?name:globalVariableName] = - createReference == false?Variable::createNonReferenceVariablePointer(&variable):Variable::createReferenceVariablePointer(&variable); + /** + * Set variable + * @param variablePtr variable pointer + * @param variableStatement variable statement + * @param variable variable + * @param statement optional statement the variable is written in + * @param createReference optional flag for creating variable references + */ + inline void setVariable(Variable* variablePtr, const string& variableStatement, const Variable& variable, const Statement* statement = nullptr, bool createReference = false) { + string variableName; + // global accessor + string globalVariableStatement; + if (_StringTools::startsWith(variableStatement, "$GLOBAL.") == true) { + globalVariableStatement = "$" + _StringTools::substring(variableStatement, 8); } + + // + Variable* parentVariable = nullptr; + string key; + int64_t arrayIdx = ARRAYIDX_NONE; + int setAccessBool = SETACCESSBOOL_NONE; + variablePtr = evaluateVariableAccessIntern(variablePtr, globalVariableStatement.empty() == true?variableStatement:globalVariableStatement, __FUNCTION__, parentVariable, arrayIdx, key, setAccessBool, statement, false); + + // set variable if not yet done + setVariableInternal(variableStatement, parentVariable, variablePtr, arrayIdx, key, variable, statement, createReference); } /** diff --git a/ext/miniscript/src/miniscript/miniscript/NetworkMethods.cpp b/ext/miniscript/src/miniscript/miniscript/NetworkMethods.cpp index c649031b2..e231f906b 100644 --- a/ext/miniscript/src/miniscript/miniscript/NetworkMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/NetworkMethods.cpp @@ -20,6 +20,74 @@ using _Console = miniscript::utilities::Console; using _Exception = miniscript::utilities::Exception; using _HTTPClient = miniscript::network::httpclient::HTTPClient; +void NetworkMethods::registerConstants(MiniScript* miniScript) { + miniScript->setConstant("$HTTPClient::HTTP_STATUS_CONTINUE", static_cast(_HTTPClient::HTTP_STATUS_CONTINUE)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_SWITCHINGPROTOCOLS", static_cast(_HTTPClient::HTTP_STATUS_SWITCHINGPROTOCOLS)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_PROCESSING", static_cast(_HTTPClient::HTTP_STATUS_PROCESSING)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_EARLYHINTS", static_cast(_HTTPClient::HTTP_STATUS_EARLYHINTS)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_OK", static_cast(_HTTPClient::HTTP_STATUS_OK)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_CREATED", static_cast(_HTTPClient::HTTP_STATUS_CREATED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_ACCEPTED", static_cast(_HTTPClient::HTTP_STATUS_ACCEPTED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_NONAUTHORITATIVEINFORMATION", static_cast(_HTTPClient::HTTP_STATUS_NONAUTHORITATIVEINFORMATION)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_NOCONTENT", static_cast(_HTTPClient::HTTP_STATUS_NOCONTENT)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_RESETCONTENT", static_cast(_HTTPClient::HTTP_STATUS_RESETCONTENT)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_PARTIALCONTENT", static_cast(_HTTPClient::HTTP_STATUS_PARTIALCONTENT)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_MULTISTATUS", static_cast(_HTTPClient::HTTP_STATUS_MULTISTATUS)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_ALREADYREPORTED", static_cast(_HTTPClient::HTTP_STATUS_ALREADYREPORTED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_IMUSED", static_cast(_HTTPClient::HTTP_STATUS_IMUSED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_MULTIPLECHOICES", static_cast(_HTTPClient::HTTP_STATUS_MULTIPLECHOICES)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_MOVEDPERMANENTLY", static_cast(_HTTPClient::HTTP_STATUS_MOVEDPERMANENTLY)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_FOUND", static_cast(_HTTPClient::HTTP_STATUS_FOUND)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_SEEOTHER", static_cast(_HTTPClient::HTTP_STATUS_SEEOTHER)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_NOTMODIFIED", static_cast(_HTTPClient::HTTP_STATUS_NOTMODIFIED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_USEPROXY", static_cast(_HTTPClient::HTTP_STATUS_USEPROXY)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_TEMPORARYREDIRECT", static_cast(_HTTPClient::HTTP_STATUS_TEMPORARYREDIRECT)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_PERMANENTREDIRECT", static_cast(_HTTPClient::HTTP_STATUS_PERMANENTREDIRECT)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_BADREQUEST", static_cast(_HTTPClient::HTTP_STATUS_BADREQUEST)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_UNAUTHORIZED", static_cast(_HTTPClient::HTTP_STATUS_UNAUTHORIZED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_PAYMENTREQUIRED", static_cast(_HTTPClient::HTTP_STATUS_PAYMENTREQUIRED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_FORBIDDEN", static_cast(_HTTPClient::HTTP_STATUS_FORBIDDEN)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_NOTFOUND", static_cast(_HTTPClient::HTTP_STATUS_NOTFOUND)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_METHODNOTALLOWED", static_cast(_HTTPClient::HTTP_STATUS_METHODNOTALLOWED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_NOTACCEPTABLE", static_cast(_HTTPClient::HTTP_STATUS_NOTACCEPTABLE)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_PROXYAUTHENTICATIONREQUIRED", static_cast(_HTTPClient::HTTP_STATUS_PROXYAUTHENTICATIONREQUIRED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_REQUESTTIMEOUT", static_cast(_HTTPClient::HTTP_STATUS_REQUESTTIMEOUT)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_CONFLICT", static_cast(_HTTPClient::HTTP_STATUS_CONFLICT)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_GONE", static_cast(_HTTPClient::HTTP_STATUS_GONE)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_LENGTHREQUIRED", static_cast(_HTTPClient::HTTP_STATUS_LENGTHREQUIRED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_PRECONDITIONFAILED", static_cast(_HTTPClient::HTTP_STATUS_PRECONDITIONFAILED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_CONTENTTOOLARGE", static_cast(_HTTPClient::HTTP_STATUS_CONTENTTOOLARGE)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_PAYLOADTOOLARGE", static_cast(_HTTPClient::HTTP_STATUS_PAYLOADTOOLARGE)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_URITOOLONG", static_cast(_HTTPClient::HTTP_STATUS_URITOOLONG)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_UNSUPPORTEDMEDIATYPE", static_cast(_HTTPClient::HTTP_STATUS_UNSUPPORTEDMEDIATYPE)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_RANGENOTSATISFIABLE", static_cast(_HTTPClient::HTTP_STATUS_RANGENOTSATISFIABLE)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_EXPECTATIONFAILED", static_cast(_HTTPClient::HTTP_STATUS_EXPECTATIONFAILED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_IMATEAPOT", static_cast(_HTTPClient::HTTP_STATUS_IMATEAPOT)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_MISDIRECTEDREQUEST", static_cast(_HTTPClient::HTTP_STATUS_MISDIRECTEDREQUEST)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_UNPROCESSABLECONTENT", static_cast(_HTTPClient::HTTP_STATUS_UNPROCESSABLECONTENT)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_UNPROCESSABLEENTITY", static_cast(_HTTPClient::HTTP_STATUS_UNPROCESSABLEENTITY)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_LOCKED", static_cast(_HTTPClient::HTTP_STATUS_LOCKED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_FAILEDDEPENDENCY", static_cast(_HTTPClient::HTTP_STATUS_FAILEDDEPENDENCY)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_TOOEARLY", static_cast(_HTTPClient::HTTP_STATUS_TOOEARLY)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_UPGRADEREQUIRED", static_cast(_HTTPClient::HTTP_STATUS_UPGRADEREQUIRED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_PRECONDITIONREQUIRED", static_cast(_HTTPClient::HTTP_STATUS_PRECONDITIONREQUIRED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_TOOMANYREQUESTS", static_cast(_HTTPClient::HTTP_STATUS_TOOMANYREQUESTS)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_REQUESTHEADERFIELDSTOOLARGE", static_cast(_HTTPClient::HTTP_STATUS_REQUESTHEADERFIELDSTOOLARGE)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_UNAVAILABLEFORLEGALREASONS", static_cast(_HTTPClient::HTTP_STATUS_UNAVAILABLEFORLEGALREASONS)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_INTERNALSERVERERROR", static_cast(_HTTPClient::HTTP_STATUS_INTERNALSERVERERROR)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_NOTIMPLEMENTED", static_cast(_HTTPClient::HTTP_STATUS_NOTIMPLEMENTED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_BADGATEWAY", static_cast(_HTTPClient::HTTP_STATUS_BADGATEWAY)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_SERVICEUNAVAILABLE", static_cast(_HTTPClient::HTTP_STATUS_SERVICEUNAVAILABLE)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_GATEWAYTIMEOUT", static_cast(_HTTPClient::HTTP_STATUS_GATEWAYTIMEOUT)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_HTTPVERSIONNOTSUPPORTED", static_cast(_HTTPClient::HTTP_STATUS_HTTPVERSIONNOTSUPPORTED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_VARIANTALSONEGOTIATES", static_cast(_HTTPClient::HTTP_STATUS_VARIANTALSONEGOTIATES)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_INSUFFICIENTSTORAGE", static_cast(_HTTPClient::HTTP_STATUS_INSUFFICIENTSTORAGE)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_LOOPDETECTED", static_cast(_HTTPClient::HTTP_STATUS_LOOPDETECTED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_NOTEXTENDED", static_cast(_HTTPClient::HTTP_STATUS_NOTEXTENDED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_NETWORKAUTHENTICATIONREQUIRED", static_cast(_HTTPClient::HTTP_STATUS_NETWORKAUTHENTICATIONREQUIRED)); + miniScript->setConstant("$HTTPClient::HTTP_STATUS_MAX", static_cast(_HTTPClient::HTTP_STATUS_MAX)); +} + void NetworkMethods::registerMethods(MiniScript* miniScript) { // network { diff --git a/ext/miniscript/src/miniscript/miniscript/NetworkMethods.h b/ext/miniscript/src/miniscript/miniscript/NetworkMethods.h index 824cc04a1..67ceda6b4 100644 --- a/ext/miniscript/src/miniscript/miniscript/NetworkMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/NetworkMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::NetworkMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/ScriptMethods.cpp b/ext/miniscript/src/miniscript/miniscript/ScriptMethods.cpp index 24302df46..8f27f760b 100644 --- a/ext/miniscript/src/miniscript/miniscript/ScriptMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/ScriptMethods.cpp @@ -18,6 +18,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; using _Time = miniscript::utilities::Time; +void ScriptMethods::registerConstants(MiniScript* miniScript) { +} + void ScriptMethods::registerMethods(MiniScript* miniScript) { // script methods { diff --git a/ext/miniscript/src/miniscript/miniscript/ScriptMethods.h b/ext/miniscript/src/miniscript/miniscript/ScriptMethods.h index 7c84d18f0..05eb7edd5 100644 --- a/ext/miniscript/src/miniscript/miniscript/ScriptMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/ScriptMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::ScriptMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/SetMethods.cpp b/ext/miniscript/src/miniscript/miniscript/SetMethods.cpp index 69ae49398..c13b4b493 100644 --- a/ext/miniscript/src/miniscript/miniscript/SetMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/SetMethods.cpp @@ -14,6 +14,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; +void SetMethods::registerConstants(MiniScript* miniScript) { +} + void SetMethods::registerMethods(MiniScript* miniScript) { // sets { diff --git a/ext/miniscript/src/miniscript/miniscript/SetMethods.h b/ext/miniscript/src/miniscript/miniscript/SetMethods.h index 75e4c8ceb..281997091 100644 --- a/ext/miniscript/src/miniscript/miniscript/SetMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/SetMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::SetMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/StringMethods.cpp b/ext/miniscript/src/miniscript/miniscript/StringMethods.cpp index 5fc09a159..737bae432 100644 --- a/ext/miniscript/src/miniscript/miniscript/StringMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/StringMethods.cpp @@ -26,6 +26,9 @@ using _Integer = miniscript::utilities::Integer; using _UTF8StringTools = miniscript::utilities::UTF8StringTools; using _UTF8CharacterIterator = miniscript::utilities::UTF8CharacterIterator; +void StringMethods::registerConstants(MiniScript* miniScript) { +} + void StringMethods::registerMethods(MiniScript* miniScript) { // string functions { diff --git a/ext/miniscript/src/miniscript/miniscript/StringMethods.h b/ext/miniscript/src/miniscript/miniscript/StringMethods.h index 44e27b19e..e05cd2241 100644 --- a/ext/miniscript/src/miniscript/miniscript/StringMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/StringMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::StringMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/TimeMethods.cpp b/ext/miniscript/src/miniscript/miniscript/TimeMethods.cpp index 368685caa..d22de8cfd 100644 --- a/ext/miniscript/src/miniscript/miniscript/TimeMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/TimeMethods.cpp @@ -15,6 +15,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; using _Time = miniscript::utilities::Time; +void TimeMethods::registerConstants(MiniScript* miniScript) { +} + void TimeMethods::registerMethods(MiniScript* miniScript) { // time { diff --git a/ext/miniscript/src/miniscript/miniscript/TimeMethods.h b/ext/miniscript/src/miniscript/miniscript/TimeMethods.h index ad6907319..7aba5ca2b 100644 --- a/ext/miniscript/src/miniscript/miniscript/TimeMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/TimeMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::TimeMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/miniscript/Transpiler.cpp b/ext/miniscript/src/miniscript/miniscript/Transpiler.cpp index c6f0028dc..742a6c944 100644 --- a/ext/miniscript/src/miniscript/miniscript/Transpiler.cpp +++ b/ext/miniscript/src/miniscript/miniscript/Transpiler.cpp @@ -44,6 +44,7 @@ using miniscript::utilities::StringTools; void Transpiler::transpile(MiniScript* miniScript, const string& transpilationFileName, const vector& miniScriptExtensionFileNames) { auto scriptFileName = miniScript->getScriptPathName() + "/" + miniScript->getScriptFileName(); + // Console::println(scriptFileName + ": Processing script"); // auto compare_includes = [](const string& lhs, const string& rhs) -> bool { @@ -154,10 +155,17 @@ void Transpiler::transpile(MiniScript* miniScript, const string& transpilationFi // Console::println(miniScript->getInformation()); + // + const auto& scripts = miniScript->getScripts(); + + // determine variables + unordered_set globalVariables; + vector> localVariables(scripts.size()); + determineVariables(miniScript, globalVariables, localVariables); + // string headerIndent = "\t"; string methodCodeIndent = "\t"; - const auto& scripts = miniScript->getScripts(); string generatedExecuteCode; { auto scriptIdx = 0; @@ -205,18 +213,34 @@ void Transpiler::transpile(MiniScript* miniScript, const string& transpilationFi // string miniScriptClassName = FileSystem::getFileName(transpilationFileName); string generatedDeclarations = "\n"; - generatedDeclarations+= string() + "public:" + "\n"; + generatedDeclarations+= headerIndent + "inline ~" + miniScriptClassName + "() {" + "\n"; + for (const auto& variable: globalVariables) { + generatedDeclarations+= headerIndent + "\t" + createGlobalVariableName(variable) + ".unset();" + "\n"; + } + generatedDeclarations+= headerIndent + "}" + "\n"; + generatedDeclarations+= "\n"; generatedDeclarations+= headerIndent + "// overridden methods" + "\n"; generatedDeclarations+= headerIndent + "void registerMethods() override;" + "\n"; + generatedDeclarations+= headerIndent + "inline void registerVariables() override {" + "\n"; + if (globalVariables.empty() == false) { + for (const auto& variable: globalVariables) { + generatedDeclarations+= headerIndent + "\t" + createGlobalVariableName(variable) + ".unset();" + "\n"; + } + generatedDeclarations+= headerIndent + "\t" + "//" + "\n"; + } + generatedDeclarations+= headerIndent + "\t" + miniScript->getBaseClass() + "::registerVariables();" + "\n"; + generatedDeclarations+= headerIndent + "\t" + "// global script variables" + "\n"; + for (const auto& variable: globalVariables) { + generatedDeclarations+= headerIndent + "\t" + "if (hasVariable(\"" + variable + "\") == false) setVariable(\"" + variable + "\", Variable())" + ";" + "\n"; + generatedDeclarations+= headerIndent + "\t" + createGlobalVariableName(variable) + " = getVariable(\"" + variable + "\", nullptr, true);" + "\n"; + } + generatedDeclarations+= headerIndent + "}" + "\n"; generatedDeclarations+= headerIndent + "void emit(const string& condition) override;" + "\n"; generatedDeclarations+= headerIndent + "inline void startScript() override {" + "\n"; generatedDeclarations+= headerIndent + "\t" + "if (native == false) {" + "\n"; generatedDeclarations+= headerIndent + "\t" + "\t" + miniScript->getBaseClass() + "::startScript();" + "\n"; generatedDeclarations+= headerIndent + "\t" + "\t" + "return;" + "\n"; generatedDeclarations+= headerIndent + "\t" + "}" + "\n"; - generatedDeclarations+= headerIndent + "\t" + "auto& scriptState = getScriptState();" + "\n"; - generatedDeclarations+= headerIndent + "\t" + "for (const auto& [scriptVariableName, scriptVariable]: scriptState.variables) delete scriptVariable;" + "\n"; - generatedDeclarations+= headerIndent + "\t" + "scriptState.variables.clear();" + "\n"; generatedDeclarations+= headerIndent + "\t" + "getScriptState().running = true;" + "\n"; generatedDeclarations+= headerIndent + "\t" + "registerVariables();" + "\n"; generatedDeclarations+= headerIndent + "\t" + "resetScriptExecutationState(" + to_string(initializeScriptIdx) + ", STATEMACHINESTATE_NEXT_STATEMENT);" + "\n"; @@ -342,7 +366,9 @@ void Transpiler::transpile(MiniScript* miniScript, const string& transpilationFi string generatedDetermineScriptIdxToStartDefinition = "\n"; generatedDetermineScriptIdxToStartDefinition+= "int " + miniScriptClassName + "::determineScriptIdxToStart() {" + "\n"; generatedDetermineScriptIdxToStartDefinition+= string() + "\t" + "if (native == false) return MiniScript::determineScriptIdxToStart();" + "\n"; + generatedDetermineScriptIdxToStartDefinition+= string() + "\t" + "// MiniScript setup" + "\n"; generatedDetermineScriptIdxToStartDefinition+= string() + "\t" + "auto miniScript = this;" + "\n"; + generatedDetermineScriptIdxToStartDefinition+= string() + "\t" + "//" + "\n"; string generatedDetermineNamedScriptIdxToStartDefinition = "\n"; generatedDetermineNamedScriptIdxToStartDefinition+= "int " + miniScriptClassName + "::determineNamedScriptIdxToStart() {" + "\n"; generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\t" + "if (native == false) return MiniScript::determineNamedScriptIdxToStart();" + "\n"; @@ -391,6 +417,72 @@ void Transpiler::transpile(MiniScript* miniScript, const string& transpilationFi // transpile definition generatedDefinitions+= "void " + miniScriptClassName + "::" + methodName + "(int miniScriptGotoStatementIdx) {" + "\n"; string generatedSubCode; + + // + if (localVariables[scriptIdx].empty() == false) { + generatedDefinitions+= string() + "\t" + "// local script variables" + "\n"; + for (const auto& variable: localVariables[scriptIdx]) { + generatedDefinitions+= string() + "\t" + "if (hasVariable(\"" + variable + "\") == false) setVariable(\"" + variable + "\", Variable())" + "; auto " + createLocalVariableName(variable) + " = getVariable(\"" + variable + "\", nullptr, true);" + "\n"; + } + // + generatedDefinitions+= string() + "\t" + "//" + "\n"; + generatedDefinitions+= string() + "\t" + "class VariableRAII {" + "\n"; + generatedDefinitions+= string() + "\t" + "private:" + "\n"; + generatedDefinitions+= string() + "\t" + "\t" + "Variable& variable;" + "\n"; + generatedDefinitions+= string() + "\t" + "public:" + "\n"; + generatedDefinitions+= string() + "\t" + "\t" + "VariableRAII(Variable& variable): variable(variable) {}" + "\n"; + generatedDefinitions+= string() + "\t" + "\t" + "~VariableRAII() { variable.unset(); }" + "\n"; + generatedDefinitions+= string() + "\t" + "};" + "\n"; + generatedDefinitions+= string() + "\t" + "//" + "\n"; + for (const auto& variable: localVariables[scriptIdx]) { + generatedDefinitions+= string() + "\t" + "VariableRAII " + "variableRAII" + createLocalVariableName(variable) + "(" + createLocalVariableName(variable) + ");" + "\n"; + } + } + + // transpile array access operator and map/set initializer + string arrayAccessMethodsDefinitions; + string arrayMapSetInitializerDefinitions; + + // + for (auto statementIdx = 0; statementIdx < script.statements.size(); statementIdx++) { + string statementArrayMapSetInitializerDefinitions; + // + Transpiler::generateArrayMapSetInitializer( + miniScript, + statementArrayMapSetInitializerDefinitions, + miniScriptClassName, + methodName, + script.syntaxTree[statementIdx], + script.statements[statementIdx], + methodCodeMap, + allMethods, + false, + {}, + 1 + ); + if (statementArrayMapSetInitializerDefinitions.empty() == false) statementArrayMapSetInitializerDefinitions+= "\n"; + arrayMapSetInitializerDefinitions+= statementArrayMapSetInitializerDefinitions; + // + Transpiler::generateArrayAccessMethods( + miniScript, + arrayAccessMethodsDefinitions, + miniScriptClassName, + methodName, + script.syntaxTree[statementIdx], + script.statements[statementIdx], + methodCodeMap, + allMethods, + false, + {}, + 1 + ); + } + + // + generatedDefinitions+= arrayMapSetInitializerDefinitions; + generatedDefinitions+= arrayAccessMethodsDefinitions; + + // Transpiler::transpile(miniScript, generatedSubCode, scriptIdx, methodCodeMap, allMethods); generatedDefinitions+= generatedSubCode; generatedDefinitions+= string() + "}" + "\n\n"; @@ -400,8 +492,51 @@ void Transpiler::transpile(MiniScript* miniScript, const string& transpilationFi if (script.scriptType == MiniScript::Script::SCRIPTTYPE_ONENABLED) { generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\n"; generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\t" + "\t" + "// next statements belong to tested enabled named condition with name \"" + script.name + "\"" + "\n"; - generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\t" + "\t" + "if (enabledNamedCondition == \"" + script.name + "\")" + "\n"; + generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\t" + "\t" + "if (enabledNamedCondition == \"" + script.name + "\") {" + "\n"; + } else { + generatedDetermineScriptIdxToStartDefinition+= string() + "\t" + "{" + "\n"; } + // + string arrayMapSetInitializerDefinitions; + string arrayAccessMethodsDefinitions; + // + Transpiler::generateArrayMapSetInitializer( + miniScript, + arrayMapSetInitializerDefinitions, + miniScriptClassName, + methodName, + script.conditionSyntaxTree, + script.conditionStatement, + methodCodeMap, + allMethods, + true, + {}, + script.scriptType == MiniScript::Script::SCRIPTTYPE_ONENABLED?3:2 + ); + if (arrayMapSetInitializerDefinitions.empty() == false) arrayMapSetInitializerDefinitions+= "\n"; + // + Transpiler::generateArrayAccessMethods( + miniScript, + arrayAccessMethodsDefinitions, + miniScriptClassName, + methodName, + script.conditionSyntaxTree, + script.conditionStatement, + methodCodeMap, + allMethods, + true, + {}, + script.scriptType == MiniScript::Script::SCRIPTTYPE_ONENABLED?3:2 + ); + // + if (script.scriptType == MiniScript::Script::SCRIPTTYPE_ON) { + generatedDetermineScriptIdxToStartDefinition+= arrayMapSetInitializerDefinitions; + generatedDetermineScriptIdxToStartDefinition+= arrayAccessMethodsDefinitions; + } else { + generatedDetermineNamedScriptIdxToStartDefinition+= arrayMapSetInitializerDefinitions; + generatedDetermineNamedScriptIdxToStartDefinition+= arrayAccessMethodsDefinitions; + } + // Transpiler::transpileScriptCondition( miniScript, script.scriptType == MiniScript::Script::SCRIPTTYPE_ON?generatedDetermineScriptIdxToStartDefinition:generatedDetermineNamedScriptIdxToStartDefinition, @@ -412,6 +547,12 @@ void Transpiler::transpile(MiniScript* miniScript, const string& transpilationFi "bool returnValueBool; returnValue.getBooleanValue(returnValueBool); if (returnValueBool == true) return " + to_string(scriptIdx) + ";", script.scriptType == MiniScript::Script::SCRIPTTYPE_ONENABLED?1:0 ); + // + if (script.scriptType == MiniScript::Script::SCRIPTTYPE_ONENABLED) { + generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\t" + "\t" + "}" + "\n"; + } else { + generatedDetermineScriptIdxToStartDefinition+= string() + "\t" + "}" + "\n"; + } } // @@ -440,87 +581,14 @@ void Transpiler::transpile(MiniScript* miniScript, const string& transpilationFi emitDefinition+= string() + "}" + "\n"; } - // transpile array access operator - string arrayAccessMethodsDeclarations; - string arrayAccessMethodsDefinitions; // - string arrayMapSetInitializerDeclarations; - string arrayMapSetInitializerDefinitions; - - { - auto scriptIdx = 0; - for (const auto& script: scripts) { - // method name - string methodName = - (script.scriptType == MiniScript::Script::SCRIPTTYPE_FUNCTION? - "": - (script.scriptType == MiniScript::Script::SCRIPTTYPE_ON?"on_":"on_enabled_") - ) + - (script.name.empty() == false?script.name:( - StringTools::regexMatch(script.condition, "[a-zA-Z0-9_]+") == true? - script.condition: - to_string(scriptIdx) - ) - ); - Transpiler::generateArrayMapSetInitializer( - miniScript, - arrayMapSetInitializerDeclarations, - arrayMapSetInitializerDefinitions, - miniScriptClassName, - methodName, - script.conditionSyntaxTree, - script.conditionStatement, - methodCodeMap, - allMethods, - true - ); - Transpiler::generateArrayAccessMethods( - miniScript, - arrayAccessMethodsDeclarations, - arrayAccessMethodsDefinitions, - miniScriptClassName, - methodName, - script.conditionSyntaxTree, - script.conditionStatement, - methodCodeMap, - allMethods, - true - ); - for (auto statementIdx = 0; statementIdx < script.statements.size(); statementIdx++) { - Transpiler::generateArrayMapSetInitializer( - miniScript, - arrayMapSetInitializerDeclarations, - arrayMapSetInitializerDefinitions, - miniScriptClassName, - methodName, - script.syntaxTree[statementIdx], - script.statements[statementIdx], - methodCodeMap, - allMethods, - false - ); - Transpiler::generateArrayAccessMethods( - miniScript, - arrayAccessMethodsDeclarations, - arrayAccessMethodsDefinitions, - miniScriptClassName, - methodName, - script.syntaxTree[statementIdx], - script.statements[statementIdx], - methodCodeMap, - allMethods, - false - ); - } - scriptIdx++; + if (globalVariables.empty() == false) { + generatedDeclarations+= headerIndent + "// global script variables" + "\n"; + for (const auto& variable: globalVariables) { + generatedDeclarations+= headerIndent + "Variable " + createGlobalVariableName(variable) + ";" + "\n"; } } - // inject array access method declarations into declarations - generatedDeclarations+= arrayAccessMethodsDeclarations; - // inject array/map/set initializer declarations into declarations - generatedDeclarations+= arrayMapSetInitializerDeclarations; - // sum up definitions generatedDefinitions = string("\n#define __MINISCRIPT_TRANSPILATION__\n\n") + @@ -529,9 +597,7 @@ void Transpiler::transpile(MiniScript* miniScript, const string& transpilationFi generatedDetermineScriptIdxToStartDefinition + generatedDetermineNamedScriptIdxToStartDefinition + "\n" + emitDefinition + - generatedDefinitions + - arrayAccessMethodsDefinitions + - arrayMapSetInitializerDefinitions; + generatedDefinitions; // inject C++ definition code { @@ -827,6 +893,85 @@ const unordered_map> Transpiler::getClassesMethodNames(Mi return methodByClasses; } +void Transpiler::determineVariables(MiniScript* miniScript, unordered_set& globalVariables, vector>& localVariables) { + // TODO: + // Problem: Variables can be set before read or read before set + // we allow to read from GLOBAL variable also if local variable has not been found + // One fix would be to: Dont look variable up in parent context, but rather also need a $GLOBAL accessor + // + const auto& scripts = miniScript->getScripts(); + // + { + auto scriptIdx = 0; + for (const auto& script: scripts) { + // + determineVariables(MiniScript::SCRIPTIDX_NONE, script.conditionSyntaxTree, globalVariables, localVariables); + // + for (auto statementIdx = 0; statementIdx < script.statements.size(); statementIdx++) { + determineVariables( + script.scriptType == MiniScript::Script::SCRIPTTYPE_FUNCTION?scriptIdx:MiniScript::SCRIPTIDX_NONE, + script.syntaxTree[statementIdx], + globalVariables, + localVariables + ); + } + // + scriptIdx++; + } + } +} + +void Transpiler::determineVariables(int scriptIdx, const MiniScript::SyntaxTreeNode& syntaxTreeNode, unordered_set& globalVariables, vector>& localVariables) { + // + switch (syntaxTreeNode.type) { + case MiniScript::SyntaxTreeNode::SCRIPTSYNTAXTREENODE_LITERAL: + { + break; + } + case MiniScript::SyntaxTreeNode::SCRIPTSYNTAXTREENODE_EXECUTE_FUNCTION: + { + for (const auto& argument: syntaxTreeNode.arguments) determineVariables(scriptIdx, argument, globalVariables, localVariables); + // + break; + } + case MiniScript::SyntaxTreeNode::SCRIPTSYNTAXTREENODE_EXECUTE_METHOD: + + { + if ((syntaxTreeNode.value.getValueAsString() == "getVariable" || + syntaxTreeNode.value.getValueAsString() == "getVariableReference" || + syntaxTreeNode.value.getValueAsString() == "setVariable" || + syntaxTreeNode.value.getValueAsString() == "setConstant") && + syntaxTreeNode.arguments.empty() == false && + syntaxTreeNode.arguments[0].type == MiniScript::SyntaxTreeNode::SCRIPTSYNTAXTREENODE_LITERAL) { + // + const auto variableStatement = syntaxTreeNode.arguments[0].value.getValueAsString(); + // + if (variableStatement != "$GLOBAL") { + // + if (scriptIdx == MiniScript::SCRIPTIDX_NONE || StringTools::startsWith(variableStatement, "$GLOBAL.") == true) { + if (StringTools::startsWith(variableStatement, "$GLOBAL.") == true) { + const auto variableName = createVariableName("$" + StringTools::substring(variableStatement, string_view("$GLOBAL.").size())); + globalVariables.insert(variableName); + } else { + const auto variableName = createVariableName(variableStatement); + globalVariables.insert(variableName); + } + } else { + const auto variableName = createVariableName(variableStatement); + localVariables[scriptIdx].insert(variableName); + } + } + } + // + for (const auto& argument: syntaxTreeNode.arguments) determineVariables(scriptIdx, argument, globalVariables, localVariables); + // + break; + } + default: + break; + } +} + void Transpiler::gatherMethodCode( const vector& miniScriptExtensionsCode, const string& className, @@ -976,7 +1121,6 @@ void Transpiler::gatherMethodCode( void Transpiler::generateArrayAccessMethods( MiniScript* miniScript, - string& generatedDeclarations, string& generatedDefinitions, const string& miniScriptClassName, const string& methodName, @@ -988,9 +1132,6 @@ void Transpiler::generateArrayAccessMethods( const vector& argumentIndices, int depth ) { - // - string headerIndent = "\t"; - // switch (syntaxTree.type) { case MiniScript::SyntaxTreeNode::SCRIPTSYNTAXTREENODE_LITERAL: @@ -1001,7 +1142,10 @@ void Transpiler::generateArrayAccessMethods( { if (syntaxTree.value.getValueAsString() == "getVariable" || syntaxTree.value.getValueAsString() == "getVariableReference" || - syntaxTree.value.getValueAsString() == "setVariable") { + syntaxTree.value.getValueAsString() == "setVariable" || + syntaxTree.value.getValueAsString() == "setConstant") { + // + auto lamdaIndent = StringTools::indent(string(), "\t", depth); // for (auto argumentIdx = 0; argumentIdx < syntaxTree.arguments.size(); argumentIdx++) { auto argumentString = StringTools::replace(StringTools::replace(syntaxTree.arguments[argumentIdx].value.getValueAsString(), "\\", "\\\\"), "\"", "\\\""); @@ -1056,14 +1200,10 @@ void Transpiler::generateArrayAccessMethods( { bool booleanValue; if (arrayAccessStatementAsScriptVariable.getBooleanValue(booleanValue) == true) { - generatedDeclarations+= headerIndent + "/**\n"; - generatedDeclarations+= headerIndent + " * Miniscript transpilation for a " + (condition == true?"condition":"statement") + " array access statement for method '" + methodName + "', statement index " + to_string(statement.statementIdx) + ", argument indices " + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, ", ") + ", array access statement index " + to_string(arrayAccessStatementIdx) + "\n"; - generatedDeclarations+= headerIndent + " * @param statement statement" + "\n"; - generatedDeclarations+= headerIndent + " * @return array index" + "\n"; - generatedDeclarations+= headerIndent + " */" + "\n"; - generatedDeclarations+= headerIndent + "inline Variable " + methodName + "_array_access_statement_" + (condition == true?"c":"s") + "_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx) + "(const Statement& statement) {" + "\n"; - generatedDeclarations+= headerIndent + " return Variable(" + (booleanValue == true?"true":"false") + ");" + "\n"; - generatedDeclarations+= headerIndent + "}" + "\n\n"; + generatedDefinitions+= lamdaIndent + "// Miniscript transpilation for a " + (condition == true?"condition":"statement") + " array access statement, statement index " + to_string(statement.statementIdx) + ", argument indices " + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, ", ") + ", array access statement index " + to_string(arrayAccessStatementIdx) + "\n"; + generatedDefinitions+= lamdaIndent + "auto array_access_statement_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx) + " = [&](const Statement& statement) -> Variable {" + "\n"; + generatedDefinitions+= lamdaIndent + " return Variable(" + (booleanValue == true?"true":"false") + ");" + "\n"; + generatedDefinitions+= lamdaIndent + "};" + "\n"; } // literals arrayAccessStatementIdx++; @@ -1074,14 +1214,10 @@ void Transpiler::generateArrayAccessMethods( { int64_t integerValue; if (arrayAccessStatementAsScriptVariable.getIntegerValue(integerValue) == true) { - generatedDeclarations+= headerIndent + "/**\n"; - generatedDeclarations+= headerIndent + " * Miniscript transpilation for a " + (condition == true?"condition":"statement") + " array access statement for method '" + methodName + "', statement index " + to_string(statement.statementIdx) + ", argument indices " + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, ", ") + ", array access statement index " + to_string(arrayAccessStatementIdx) + "\n"; - generatedDeclarations+= headerIndent + " * @param statement statement" + "\n"; - generatedDeclarations+= headerIndent + " * @return array index" + "\n"; - generatedDeclarations+= headerIndent + " */" + "\n"; - generatedDeclarations+= headerIndent + "inline Variable " + methodName + "_array_access_statement_" + (condition == true?"c":"s") + "_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx) + "(const Statement& statement) {" + "\n"; - generatedDeclarations+= headerIndent + " return Variable(static_cast(" + to_string(integerValue) + "ll));" + "\n"; - generatedDeclarations+= headerIndent + "}" + "\n\n"; + generatedDefinitions+= lamdaIndent + "// Miniscript transpilation for a " + (condition == true?"condition":"statement") + " array access statement, statement index " + to_string(statement.statementIdx) + ", argument indices " + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, ", ") + ", array access statement index " + to_string(arrayAccessStatementIdx) + "\n"; + generatedDefinitions+= lamdaIndent + "auto array_access_statement_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx) + " = [&](const Statement& statement) -> Variable {" + "\n"; + generatedDefinitions+= lamdaIndent + " return Variable(static_cast(" + to_string(integerValue) + "ll));" + "\n"; + generatedDefinitions+= lamdaIndent + "};" + "\n"; } // literals arrayAccessStatementIdx++; @@ -1092,14 +1228,10 @@ void Transpiler::generateArrayAccessMethods( { float floatValue; if (arrayAccessStatementAsScriptVariable.getFloatValue(floatValue) == true) { - generatedDeclarations+= headerIndent + "/**\n"; - generatedDeclarations+= headerIndent + " * Miniscript transpilation for a " + (condition == true?"condition":"statement") + " array access statement for method '" + methodName + "', statement index " + to_string(statement.statementIdx) + ", argument indices " + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, ", ") + ", array access statement index " + to_string(arrayAccessStatementIdx) + "\n"; - generatedDeclarations+= headerIndent + " * @param statement statement" + "\n"; - generatedDeclarations+= headerIndent + " * @return array index" + "\n"; - generatedDeclarations+= headerIndent + " */" + "\n"; - generatedDeclarations+= headerIndent + "inline Variable " + methodName + "_array_access_statement_" + (condition == true?"c":"s") + "_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx) + "(const Statement& statement) {" + "\n"; - generatedDeclarations+= headerIndent + " return Variable(static_cast(" + to_string(static_cast(floatValue)) + "ll));" + "\n"; - generatedDeclarations+= headerIndent + "}" + "\n\n"; + generatedDefinitions+= lamdaIndent + "// Miniscript transpilation for a " + (condition == true?"condition":"statement") + " array access statement, statement index " + to_string(statement.statementIdx) + ", argument indices " + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, ", ") + ", array access statement index " + to_string(arrayAccessStatementIdx) + "\n"; + generatedDefinitions+= lamdaIndent + "auto array_access_statement_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx) + " = [&](const Statement& statement) -> Variable {" + "\n"; + generatedDefinitions+= lamdaIndent + " return Variable(static_cast(" + to_string(static_cast(floatValue)) + "ll));" + "\n"; + "\n"; + generatedDefinitions+= lamdaIndent + "};" + "\n"; } // literals arrayAccessStatementIdx++; @@ -1155,20 +1287,15 @@ void Transpiler::generateArrayAccessMethods( 0, {}, "Variable()", - "return returnValue;" + "return returnValue;", + 1 ); - generatedDeclarations+= headerIndent + "/**\n"; - generatedDeclarations+= headerIndent + " * Miniscript transpilation for a " + (condition == true?"condition":"statement") + " array access statement for method '" + methodName + "', statement index " + to_string(statement.statementIdx) + ", argument indices " + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, ", ") + ", array access statement index " + to_string(arrayAccessStatementIdx) + "\n"; - generatedDeclarations+= headerIndent + " * @param statement statement" + "\n"; - generatedDeclarations+= headerIndent + " * @return array index" + "\n"; - generatedDeclarations+= headerIndent + " */" + "\n"; - generatedDeclarations+= headerIndent + "Variable " + methodName + "_array_access_statement_" + (condition == true?"c":"s") + "_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx) + "(const Statement& statement);" + "\n\n"; - generatedDefinitions+= string() + "inline MiniScript::Variable " + miniScriptClassName + "::" + methodName + "_array_access_statement_" + (condition == true?"c":"s") + "_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx) + "(const Statement& statement) {" + "\n"; - generatedDefinitions+= string() + " // Miniscript setup" + "\n"; - generatedDefinitions+= string() + " auto miniScript = this;" + "\n"; - generatedDefinitions+= string() + " //" + "\n";; + generatedDefinitions+= lamdaIndent + "// Miniscript transpilation for array access statement, statement index " + to_string(statement.statementIdx) + ", argument indices " + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, ", ") + ", array access statement index " + to_string(arrayAccessStatementIdx) + "\n"; + generatedDefinitions+= lamdaIndent + "auto array_access_statement_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx) + " = [&](const Statement& statement) -> Variable {" + "\n"; + generatedDefinitions+= lamdaIndent + "\t" + "// MiniScript setup" + "\n"; + generatedDefinitions+= lamdaIndent + "\t" + "auto miniScript = this;" + "\n"; generatedDefinitions+= transpiledCode; - generatedDefinitions+= string() + "}" + "\n\n"; + generatedDefinitions+= lamdaIndent + "};" + "\n"; // arrayAccessStatementIdx++; } @@ -1185,7 +1312,6 @@ void Transpiler::generateArrayAccessMethods( // generateArrayAccessMethods( miniScript, - generatedDeclarations, generatedDefinitions, miniScriptClassName, methodName, @@ -1195,7 +1321,7 @@ void Transpiler::generateArrayAccessMethods( allMethods, condition, nextArgumentIndices, - depth + 1 + depth ); // argumentIdx++; @@ -1212,7 +1338,6 @@ void Transpiler::generateArrayAccessMethods( // generateArrayAccessMethods( miniScript, - generatedDeclarations, generatedDefinitions, miniScriptClassName, methodName, @@ -1222,7 +1347,7 @@ void Transpiler::generateArrayAccessMethods( allMethods, condition, nextArgumentIndices, - depth + 1 + depth ); // argumentIdx++; @@ -1287,7 +1412,6 @@ void Transpiler::generateArrayMapSetVariable( const string& methodName, bool condition, const string& miniScriptClassName, - string& generatedDeclarations, string& generatedDefinitions, int depth, int initializerDepth, @@ -1295,7 +1419,7 @@ void Transpiler::generateArrayMapSetVariable( ) { // string headerIndent = "\t"; - auto indent = StringTools::indent(string(), "\t", initializerDepth + 1); + auto indent = StringTools::indent(string(), "\t", initializerDepth + depth); switch (variable.getType()) { case MiniScript::TYPE_NULL: { @@ -1392,7 +1516,14 @@ void Transpiler::generateArrayMapSetVariable( break; case MiniScript::TYPE_ARRAY: { - generatedDefinitions+= indent + "{" + "\n"; + if (initializerDepth == 0) { + generatedDefinitions+= string() + "{" + "\n"; + generatedDefinitions+= indent + "\t" + "// MiniScript setup" + "\n"; + generatedDefinitions+= indent + "\t" + "auto miniScript = this;" + "\n"; + generatedDefinitions+= indent + "\t" + "//" + "\n"; + } else { + generatedDefinitions+= indent + "{" + "\n"; + } generatedDefinitions+= indent + "\t" + "Variable variableD" + to_string(initializerDepth) + ";" + "\n"; generatedDefinitions+= indent + "\t" + "variableD" + to_string(initializerDepth) + ".setType(TYPE_ARRAY);" + "\n"; const auto arrayValue = variable.getArrayPointer(); @@ -1405,7 +1536,6 @@ void Transpiler::generateArrayMapSetVariable( methodName, condition, miniScriptClassName, - generatedDeclarations, generatedDefinitions, depth, initializerDepth + 1, @@ -1413,12 +1543,20 @@ void Transpiler::generateArrayMapSetVariable( ); } generatedDefinitions+= indent + "\t" + postStatement + "\n"; - generatedDefinitions+= indent + "}" + "\n"; + generatedDefinitions+= indent + "}"; + generatedDefinitions+= initializerDepth == 0?";":"\n"; } break; case MiniScript::TYPE_MAP: { - generatedDefinitions+= indent + "{" + "\n"; + if (initializerDepth == 0) { + generatedDefinitions+= string() + "{" + "\n"; + generatedDefinitions+= indent + "\t" + "// MiniScript setup" + "\n"; + generatedDefinitions+= indent + "\t" + "auto miniScript = this;" + "\n"; + generatedDefinitions+= indent + "\t" + "//" + "\n"; + } else { + generatedDefinitions+= indent + "{" + "\n"; + } generatedDefinitions+= indent + "\t" + "Variable variableD" + to_string(initializerDepth) + ";" + "\n"; generatedDefinitions+= indent + "\t" + "variableD" + to_string(initializerDepth) + ".setType(TYPE_MAP);" + "\n"; const auto mapValue = variable.getMapPointer(); @@ -1432,7 +1570,6 @@ void Transpiler::generateArrayMapSetVariable( methodName, condition, miniScriptClassName, - generatedDeclarations, generatedDefinitions, depth, initializerDepth + 1, @@ -1440,12 +1577,20 @@ void Transpiler::generateArrayMapSetVariable( ); } generatedDefinitions+= indent + "\t" + postStatement + "\n"; - generatedDefinitions+= indent + "}" + "\n"; + generatedDefinitions+= indent + "}"; + generatedDefinitions+= initializerDepth == 0?";":"\n"; } break; case MiniScript::TYPE_SET: { - generatedDefinitions+= indent + "{" + "\n"; + if (initializerDepth == 0) { + generatedDefinitions+= string() + "{" + "\n"; + generatedDefinitions+= indent + "\t" + "// MiniScript setup" + "\n"; + generatedDefinitions+= indent + "\t" + "auto miniScript = this;" + "\n"; + generatedDefinitions+= indent + "\t" + "//" + "\n"; + } else { + generatedDefinitions+= indent + "{" + "\n"; + } generatedDefinitions+= indent + "\t" + "Variable variableD" + to_string(initializerDepth) + ";" + "\n"; generatedDefinitions+= indent + "\t" + "variableD" + to_string(initializerDepth) + ".setType(TYPE_SET);" + "\n"; const auto setValue = variable.getSetPointer(); @@ -1453,7 +1598,8 @@ void Transpiler::generateArrayMapSetVariable( generatedDefinitions+= indent + "\t" + "variableD" + to_string(initializerDepth) + ".insertSetKey(\"" + key + "\");" + "\n"; } generatedDefinitions+= indent + "\t" + postStatement + "\n"; - generatedDefinitions+= indent + "}" + "\n"; + generatedDefinitions+= indent + "}"; + generatedDefinitions+= initializerDepth == 0?";":"\n"; } break; default: break; @@ -1462,7 +1608,6 @@ void Transpiler::generateArrayMapSetVariable( void Transpiler::generateArrayMapSetInitializer( MiniScript* miniScript, - string& generatedDeclarations, string& generatedDefinitions, const string& miniScriptClassName, const string& methodName, @@ -1475,8 +1620,7 @@ void Transpiler::generateArrayMapSetInitializer( int depth ) { // - string headerIndent = "\t"; - + auto indent = StringTools::indent(string(), "\t", depth); // switch (syntaxTree.type) { case MiniScript::SyntaxTreeNode::SCRIPTSYNTAXTREENODE_LITERAL: @@ -1486,14 +1630,7 @@ void Transpiler::generateArrayMapSetInitializer( case MiniScript::TYPE_MAP: case MiniScript::TYPE_SET: { - generatedDeclarations+= headerIndent + "/**\n"; - generatedDeclarations+= headerIndent + " * Miniscript transpilation for a " + (condition == true?"condition":"statement") + " array/map/set initializer for method '" + methodName + "', statement index " + to_string(statement.statementIdx) + ", argument indices " + MiniScript::getArgumentIndicesAsString(argumentIndices, ", ") + "\n"; - generatedDeclarations+= headerIndent + " * @param statement statement" + "\n"; - generatedDeclarations+= headerIndent + " * @return initialized variable" + "\n"; - generatedDeclarations+= headerIndent + " */" + "\n"; - generatedDeclarations+= headerIndent + "Variable " + methodName + "_initializer_" + (condition == true?"c":"s") + "_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(argumentIndices, "_") + "(const Statement& statement);" + "\n\n"; // - string generatedInitializerDeclarations; string generatedInitializerDefinitions; // generateArrayMapSetVariable( @@ -1504,20 +1641,15 @@ void Transpiler::generateArrayMapSetInitializer( methodName, condition, miniScriptClassName, - generatedInitializerDeclarations, generatedInitializerDefinitions, depth, 0, "return variableD0;" ); // - generatedDefinitions+= "\n"; - generatedDefinitions+= string() + "inline MiniScript::Variable " + miniScriptClassName + "::" + methodName + "_initializer_" + (condition == true?"c":"s") + "_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(argumentIndices, "_") + "(const Statement& statement) {" + "\n"; - generatedDefinitions+= string() + " // Miniscript setup" + "\n"; - generatedDefinitions+= string() + " auto miniScript = this;" + "\n"; - generatedDefinitions+= string() + " //" + "\n";; + generatedDefinitions+= indent + "// Miniscript transpilation for array/map/set initializer, statement index " + to_string(statement.statementIdx) + ", argument indices " + MiniScript::getArgumentIndicesAsString(argumentIndices, ", ") + "\n"; + generatedDefinitions+= indent + "auto initializer_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(argumentIndices, "_") + " = [&](const Statement& statement) -> Variable "; generatedDefinitions+= generatedInitializerDefinitions; - generatedDefinitions+= string() + "}" + "\n"; // break; } @@ -1536,7 +1668,6 @@ void Transpiler::generateArrayMapSetInitializer( // generateArrayMapSetInitializer( miniScript, - generatedDeclarations, generatedDefinitions, miniScriptClassName, methodName, @@ -1546,7 +1677,7 @@ void Transpiler::generateArrayMapSetInitializer( allMethods, condition, nextArgumentIndices, - depth + 1 + depth ); // argumentIdx++; @@ -1563,7 +1694,6 @@ void Transpiler::generateArrayMapSetInitializer( // generateArrayMapSetInitializer( miniScript, - generatedDeclarations, generatedDefinitions, miniScriptClassName, methodName, @@ -1573,7 +1703,7 @@ void Transpiler::generateArrayMapSetInitializer( allMethods, condition, nextArgumentIndices, - depth + 1 + depth ); // argumentIdx++; @@ -1698,7 +1828,8 @@ bool Transpiler::transpileScriptStatement( scriptIdx != MiniScript::SCRIPTIDX_NONE) && (syntaxTree.value.getValueAsString() == "getVariable" || syntaxTree.value.getValueAsString() == "getVariableReference" || - syntaxTree.value.getValueAsString() == "setVariable")) { + syntaxTree.value.getValueAsString() == "setVariable" || + syntaxTree.value.getValueAsString() == "setConstant")) { // for (auto argumentIdx = 0; argumentIdx < syntaxTree.arguments.size(); argumentIdx++) { // @@ -1742,19 +1873,8 @@ bool Transpiler::transpileScriptStatement( } // const auto& script = miniScript->getScripts()[scriptConditionIdx != MiniScript::SCRIPTIDX_NONE?scriptConditionIdx:scriptIdx]; - string methodName = - (script.scriptType == MiniScript::Script::SCRIPTTYPE_FUNCTION? - "": - (script.scriptType == MiniScript::Script::SCRIPTTYPE_ON?"on_":"on_enabled_") - ) + - (script.name.empty() == false?script.name:( - StringTools::regexMatch(script.condition, "[a-zA-Z0-9_]+") == true? - script.condition: - to_string(scriptIdx) - ) - ); // - auto arrayAccessStatementMethod = methodName + "_array_access_statement_" + (scriptConditionIdx != MiniScript::SCRIPTIDX_NONE?"c":"s") + "_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx); + auto arrayAccessStatementMethod = string() + "array_access_statement_" + to_string(statement.statementIdx) + "_" + MiniScript::getArgumentIndicesAsString(nextArgumentIndices, "_") + "_" + to_string(arrayAccessStatementIdx); // generatedCode+= minIndentString + depthIndentString + "// we will use " + arrayAccessStatementMethod + "() to determine array access index"+ "\n"; // @@ -1912,7 +2032,7 @@ bool Transpiler::transpileScriptStatement( ) ); // - auto initializerMethod = methodName + "_initializer_" + (scriptConditionIdx != MiniScript::SCRIPTIDX_NONE?"c":"s") + "_" + to_string(statement.statementIdx) + "_" + miniScript->getArgumentIndicesAsString(nextArgumentIndices, "_"); + auto initializerMethod = string() + "initializer_" + to_string(statement.statementIdx) + "_" + miniScript->getArgumentIndicesAsString(nextArgumentIndices, "_"); argumentsCode.push_back(string() + "\t" + initializerMethod + "(statement)" + (lastArgument == false?",":"")); } break; @@ -2014,7 +2134,9 @@ bool Transpiler::transpileScriptStatement( enabledNamedConditions, depth + 1, nextArgumentIndices, - returnValue + returnValue, + string(), + additionalIndent ) == false) { Console::println("Transpiler::transpileScriptStatement(): transpileScriptStatement(): " + miniScript->getStatementInformation(statement) + ": '" + syntaxTree.value.getValueAsString() + "(" + miniScript->getArgumentsAsString(syntaxTree.arguments) + ")" + "': transpile error"); } @@ -2038,46 +2160,147 @@ bool Transpiler::transpileScriptStatement( } } - // generate code - generatedCode+= minIndentString + depthIndentString + "\t" + "// method code: " + string(method) + "\n"; - for (auto codeLine: methodCode) { - codeLine = StringTools::replace(codeLine, "getMethodName()", "string(\"" + string(method) + "\")"); - // replace returns with gotos - if (StringTools::regexMatch(codeLine, "[\\ \\t]*return[\\ \\t]*;.*") == true) { - Console::println("Transpiler::transpileScriptStatement(): method '" + string(method) + "': return statement not supported!"); - return false; - } else - if (StringTools::regexMatch(codeLine, "[\\ \\t]*miniScript[\\ \\t]*->gotoStatementGoto[\\ \\t]*\\([\\ \\t]*statement[\\ \\t]*\\)[\\ \\t]*;[\\ \\t]*") == true) { - if (statement.gotoStatementIdx != MiniScript::STATEMENTIDX_NONE) { - // find indent - int indent = 0; - for (auto i = 0; i < codeLine.size(); i++) { - auto c = codeLine[i]; - if (c == '\t') { - indent++; + // do we have a variable look up or setting a variable? + // transfer to use local method and global class variables + if (syntaxTree.type == MiniScript::SyntaxTreeNode::SCRIPTSYNTAXTREENODE_EXECUTE_METHOD && + (syntaxTree.value.getValueAsString() == "getVariable" || + syntaxTree.value.getValueAsString() == "getVariableReference" || + syntaxTree.value.getValueAsString() == "setVariable" || + syntaxTree.value.getValueAsString() == "setConstant") && + syntaxTree.arguments.empty() == false && + syntaxTree.arguments[0].type == MiniScript::SyntaxTreeNode::SCRIPTSYNTAXTREENODE_LITERAL) { + // + generatedCode+= minIndentString + depthIndentString + "\t" + "// variable access using " + syntaxTree.value.getValueAsString() + "\n"; + // + auto haveFunction = false; + auto haveScript = (scriptConditionIdx != MiniScript::SCRIPTIDX_NONE || scriptIdx != MiniScript::SCRIPTIDX_NONE); + if (haveScript == true) { + const auto& script = miniScript->getScripts()[scriptConditionIdx != MiniScript::SCRIPTIDX_NONE?scriptConditionIdx:scriptIdx]; + haveFunction = script.scriptType == MiniScript::Script::SCRIPTTYPE_FUNCTION; + } + // + auto getVariable = syntaxTree.value.getValueAsString() == "getVariable"; + auto getVariableReference = syntaxTree.value.getValueAsString() == "getVariableReference"; + auto setVariable = syntaxTree.value.getValueAsString() == "setVariable" || syntaxTree.value.getValueAsString() == "setConstant"; + // + const auto variable = syntaxTree.arguments[0].value.getValueAsString(); + auto haveVariableStatement = variableHasStatement(variable); + if (haveFunction == true || StringTools::startsWith(variable, "$GLOBAL.") == true) { + // + if (StringTools::startsWith(variable, "$GLOBAL.") == true) { + const auto globalVariable = "$" + StringTools::substring(variable, string_view("$GLOBAL.").size()); + const auto globalVariableStatement = StringTools::replace(StringTools::replace(globalVariable, "\\", "\\\\"), "\"", "\\\""); + if (getVariable == true) { + if (haveVariableStatement == true) { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = getVariable(&" + createGlobalVariableName(globalVariable) + ", \"" + globalVariableStatement + "\", &statement, false);" + "\n"; } else { - break; + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = Variable::createNonReferenceVariable(&" + createGlobalVariableName(globalVariable) + ");" + "\n"; + } + } else + if (getVariableReference == true) { + if (haveVariableStatement == true) { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = getVariable(&" + createGlobalVariableName(globalVariable) + ", \"" + globalVariableStatement + "\", &statement, true);" + "\n"; + } else { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = Variable::createReferenceVariable(&" + createGlobalVariableName(globalVariable) + ");" + "\n"; + } + } else + if (setVariable == true) { + if (haveVariableStatement == true) { + generatedCode+= minIndentString + depthIndentString + "\t" + "setVariable(&" + createGlobalVariableName(globalVariable) + ", \"" + globalVariableStatement + "\", arguments[1], &statement); returnValue = arguments[1];" + "\n"; + } else { + generatedCode+= minIndentString + depthIndentString + "\t" + createGlobalVariableName(globalVariable) + " = arguments[1]; returnValue = arguments[1];" + "\n"; + } + } + } else { + const auto& localVariable = variable; + if (getVariable == true) { + if (haveVariableStatement == true) { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = getVariable(&" + createLocalVariableName(localVariable) + ", arguments[0].getValueAsString(), &statement, false);" + "\n"; + } else { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = Variable::createNonReferenceVariable(&" + createLocalVariableName(localVariable) + ");" + "\n"; + } + } else + if (getVariableReference == true) { + if (haveVariableStatement == true) { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = getVariable(&" + createLocalVariableName(localVariable) + ", arguments[0].getValueAsString(), &statement, true);" + "\n"; + } else { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = Variable::createReferenceVariable(&" + createLocalVariableName(localVariable) + ");" + "\n"; + } + } else + if (setVariable == true) { + if (haveVariableStatement == true) { + generatedCode+= minIndentString + depthIndentString + "\t" + "setVariable(&" + createLocalVariableName(localVariable) + ", arguments[0].getValueAsString(), arguments[1], &statement); returnValue = arguments[1];" + "\n"; + } else { + generatedCode+= minIndentString + depthIndentString + "\t" + createLocalVariableName(localVariable) + " = arguments[1]; returnValue = arguments[1];" + "\n"; } } - string indentString; - for (auto i = 0; i < indent; i++) indentString+= "\t"; - generatedCode+= minIndentString + indentString + depthIndentString + "\t" + "goto miniscript_statement_" + to_string(statement.gotoStatementIdx) + ";\n"; } - } else - if (StringTools::regexMatch(codeLine, "[\\ \\t]*miniScript[\\ \\t]*->startErrorScript[\\ \\t]*\\([\\ \\t]*\\)[\\ \\t]*;[\\ \\t]*") == true || - StringTools::regexMatch(codeLine, "[\\ \\t]*miniScript[\\ \\t]*->emit[\\ \\t]*\\([\\ \\t]*[a-zA-Z0-9]*[\\ \\t]*\\)[\\ \\t]*;[\\ \\t]*") == true) { - generatedCode+= minIndentString + depthIndentString + "\t" + codeLine + " return" + (returnValue.empty() == false?" " + returnValue:"") + ";\n"; } else { - if (StringTools::regexMatch(codeLine, ".*[\\ \\t]*miniScript[\\ \\t]*->[\\ \\t]*setScriptStateState[\\ \\t]*\\([\\ \\t]*.+[\\ \\t]*\\);.*") == true) { - scriptStateChanged = true; + const auto& globalVariable = variable; + if (getVariable == true) { + if (haveVariableStatement == true) { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = getVariable(&" + createGlobalVariableName(globalVariable) + ", arguments[0].getValueAsString(), &statement, false);" + "\n"; + } else { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = Variable::createNonReferenceVariable(&" + createGlobalVariableName(globalVariable) + ");" + "\n"; + } + } else + if (getVariableReference == true) { + if (haveVariableStatement == true) { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = getVariable(&" + createGlobalVariableName(globalVariable) + ", arguments[0].getValueAsString(), &statement, true);" + "\n"; + } else { + generatedCode+= minIndentString + depthIndentString + "\t" + "returnValue = Variable::createReferenceVariable(&" + createGlobalVariableName(globalVariable) + ");" + "\n"; + } + } else + if (setVariable == true) { + if (haveVariableStatement == true) { + generatedCode+= minIndentString + depthIndentString + "\t" + "setVariable(&" + createGlobalVariableName(globalVariable) + ", arguments[0].getValueAsString(), arguments[1], &statement); returnValue = arguments[1];" + "\n"; + } else { + generatedCode+= minIndentString + depthIndentString + "\t" + createGlobalVariableName(globalVariable) + " = arguments[1]; returnValue = arguments[1];" + "\n"; + } } - if (StringTools::regexMatch(codeLine, ".*[\\ \\t]*miniScript[\\ \\t]*->[\\ \\t]*stopScriptExecutation[\\ \\t]*\\([\\ \\t]*\\);.*") == true) { - scriptStopped = true; + } + } else { + // generate code + generatedCode+= minIndentString + depthIndentString + "\t" + "// method code: " + string(method) + "\n"; + for (auto codeLine: methodCode) { + codeLine = StringTools::replace(codeLine, "getMethodName()", "string(\"" + string(method) + "\")"); + // replace returns with gotos + if (StringTools::regexMatch(codeLine, "[\\ \\t]*return[\\ \\t]*;.*") == true) { + Console::println("Transpiler::transpileScriptStatement(): method '" + string(method) + "': return statement not supported!"); + return false; + } else + if (StringTools::regexMatch(codeLine, "[\\ \\t]*miniScript[\\ \\t]*->gotoStatementGoto[\\ \\t]*\\([\\ \\t]*statement[\\ \\t]*\\)[\\ \\t]*;[\\ \\t]*") == true) { + if (statement.gotoStatementIdx != MiniScript::STATEMENTIDX_NONE) { + // find indent + int indent = 0; + for (auto i = 0; i < codeLine.size(); i++) { + auto c = codeLine[i]; + if (c == '\t') { + indent++; + } else { + break; + } + } + string indentString; + for (auto i = 0; i < indent; i++) indentString+= "\t"; + generatedCode+= minIndentString + indentString + depthIndentString + "\t" + "goto miniscript_statement_" + to_string(statement.gotoStatementIdx) + ";\n"; + } } else - if (StringTools::regexMatch(codeLine, ".*[\\ \\t]*miniScript[\\ \\t]*->[\\ \\t]*stopRunning[\\ \\t]*\\([\\ \\t]*\\);.*") == true) { - scriptStopped = true; + if (StringTools::regexMatch(codeLine, "[\\ \\t]*miniScript[\\ \\t]*->startErrorScript[\\ \\t]*\\([\\ \\t]*\\)[\\ \\t]*;[\\ \\t]*") == true || + StringTools::regexMatch(codeLine, "[\\ \\t]*miniScript[\\ \\t]*->emit[\\ \\t]*\\([\\ \\t]*[a-zA-Z0-9]*[\\ \\t]*\\)[\\ \\t]*;[\\ \\t]*") == true) { + generatedCode+= minIndentString + depthIndentString + "\t" + codeLine + " return" + (returnValue.empty() == false?" " + returnValue:"") + ";\n"; + } else { + if (StringTools::regexMatch(codeLine, ".*[\\ \\t]*miniScript[\\ \\t]*->[\\ \\t]*setScriptStateState[\\ \\t]*\\([\\ \\t]*.+[\\ \\t]*\\);.*") == true) { + scriptStateChanged = true; + } + if (StringTools::regexMatch(codeLine, ".*[\\ \\t]*miniScript[\\ \\t]*->[\\ \\t]*stopScriptExecutation[\\ \\t]*\\([\\ \\t]*\\);.*") == true) { + scriptStopped = true; + } else + if (StringTools::regexMatch(codeLine, ".*[\\ \\t]*miniScript[\\ \\t]*->[\\ \\t]*stopRunning[\\ \\t]*\\([\\ \\t]*\\);.*") == true) { + scriptStopped = true; + } + generatedCode+= minIndentString + depthIndentString + "\t" + codeLine + "\n"; } - generatedCode+= minIndentString + depthIndentString + "\t" + codeLine + "\n"; } } @@ -2166,7 +2389,7 @@ bool Transpiler::transpile(MiniScript* miniScript, string& generatedCode, int sc generatedCode+= methodIndent + "\t" + "auto scriptIdxToStart = determineNamedScriptIdxToStart();" + "\n"; generatedCode+= methodIndent + "\t" + "if (scriptIdxToStart != SCRIPTIDX_NONE && scriptIdxToStart != getScriptState().scriptIdx) {" + "\n"; generatedCode+= methodIndent + "\t" + "resetScriptExecutationState(scriptIdxToStart, STATEMACHINESTATE_NEXT_STATEMENT);" + "\n"; - generatedCode+= methodIndent + "\t" + "timeEnabledConditionsCheckLast = Time::getCurrentMillis();" + "\n"; + generatedCode+= methodIndent + "\t" + "timeEnabledConditionsCheckLast = _Time::getCurrentMillis();" + "\n"; generatedCode+= methodIndent + "\t" + "return;" + "\n"; generatedCode+= methodIndent + "\t" + "}" + "\n"; generatedCode+= methodIndent + "}" + "\n"; diff --git a/ext/miniscript/src/miniscript/miniscript/Transpiler.h b/ext/miniscript/src/miniscript/miniscript/Transpiler.h index 700803953..81d057720 100644 --- a/ext/miniscript/src/miniscript/miniscript/Transpiler.h +++ b/ext/miniscript/src/miniscript/miniscript/Transpiler.h @@ -7,6 +7,7 @@ #include #include +#include using std::string; using std::unordered_map; @@ -14,6 +15,7 @@ using std::unordered_set; using std::vector; using miniscript::miniscript::MiniScript; +using miniscript::utilities::StringTools; /** * MiniScript transpiler @@ -37,6 +39,65 @@ class miniscript::miniscript::Transpiler { static void untranspile(const string& scriptFileName, const string& transpilationFileName); private: + /** + * Check if variable has access statement + * @param variableStatement variable statement + * @return variable has statement + */ + inline static bool variableHasStatement(const string& variableStatement) { + auto dotIdx = StringTools::indexOf(variableStatement, "."); + if (dotIdx != string::npos) return true; + auto squareBracketIdx = StringTools::indexOf(variableStatement, "["); + if (squareBracketIdx != string::npos) return true; + return false; + } + + /** + * Create variable name + * @param variableStatement variable statement + * @return variable name + */ + inline static const string createVariableName(const string& variableStatement) { + auto dotIdx = StringTools::indexOf(variableStatement, "."); + if (dotIdx == string::npos) dotIdx = variableStatement.size(); + auto squareBracketIdx = StringTools::indexOf(variableStatement, "["); + if (squareBracketIdx == string::npos) squareBracketIdx = variableStatement.size(); + auto cppVariableName = StringTools::substring(variableStatement, 0, dotIdx < squareBracketIdx?dotIdx:squareBracketIdx); + return cppVariableName; + } + + /** + * Create global variable name + * @param variableStatement variable statement + * @return global CPP variable name + */ + inline static const string createGlobalVariableName(const string& variableStatement) { + auto dotIdx = StringTools::indexOf(variableStatement, "."); + if (dotIdx == string::npos) dotIdx = variableStatement.size(); + auto squareBracketIdx = StringTools::indexOf(variableStatement, "["); + if (squareBracketIdx == string::npos) squareBracketIdx = variableStatement.size(); + auto cppVariableName = "_G" + StringTools::substring(variableStatement, 0, dotIdx < squareBracketIdx?dotIdx:squareBracketIdx); + cppVariableName = StringTools::replace(cppVariableName, "$", "_"); + cppVariableName = StringTools::replace(cppVariableName, ":", "_"); + return cppVariableName; + } + + /** + * Create local variable name + * @param variableStatement variable statement + * @return local CPP variable name + */ + inline static const string createLocalVariableName(const string& variableStatement) { + auto dotIdx = StringTools::indexOf(variableStatement, "."); + if (dotIdx == string::npos) dotIdx = variableStatement.size(); + auto squareBracketIdx = StringTools::indexOf(variableStatement, "["); + if (squareBracketIdx == string::npos) squareBracketIdx = variableStatement.size(); + auto cppVariableName = "_L" + StringTools::substring(variableStatement, 0, dotIdx < squareBracketIdx?dotIdx:squareBracketIdx); + cppVariableName = StringTools::replace(cppVariableName, "$", "_"); + cppVariableName = StringTools::replace(cppVariableName, ":", "_"); + return cppVariableName; + } + /** * Get all classes method names * @param miniScript MiniScript instance @@ -58,6 +119,23 @@ class miniscript::miniscript::Transpiler { */ static const unordered_map> getClassesMethodNames(MiniScript* miniScript); + /** + * Determine variables + * @param miniScript MiniScript script instance + * @param globalVariables global variables + * @param localVariables local variables per script index + */ + static void determineVariables(MiniScript* miniScript, unordered_set& globalVariables, vector>& localVariables); + + /** + * Determine variables within syntax tree + * @param scriptIdx script index + * @param syntaxTreeNode syntax tree node + * @param globalVariables global variables + * @param localVariables local variables per script index + */ + static void determineVariables(int scriptIdx, const MiniScript::SyntaxTreeNode& syntaxTreeNode, unordered_set& globalVariables, vector>& localVariables); + /** * Gather method code * @param miniScriptExtensionsCode MiniScript extensions code @@ -75,7 +153,6 @@ class miniscript::miniscript::Transpiler { /** * Generate array access methods * @param miniScript MiniScript instance - * @param generatedDeclarations generated declarations * @param generatedDefinitions generated definitions * @param miniScriptClassName MiniScript class name * @param methodName method name @@ -89,7 +166,6 @@ class miniscript::miniscript::Transpiler { */ static void generateArrayAccessMethods( MiniScript* miniScript, - string& generatedDeclarations, string& generatedDefinitions, const string& miniScriptClassName, const string& methodName, @@ -123,7 +199,6 @@ class miniscript::miniscript::Transpiler { * @param methodName method name * @param condition condition * @param miniScriptClassName MiniScript class name - * @param generatedDeclarations generated declarations * @param generatedDefinitions generated definitions * @param depth depth * @param initializerDepth initializer depth @@ -137,7 +212,6 @@ class miniscript::miniscript::Transpiler { const string& methodName, bool condition, const string& miniScriptClassName, - string& generatedDeclarations, string& generatedDefinitions, int depth = 0, int initializerDepth = 0, @@ -147,7 +221,6 @@ class miniscript::miniscript::Transpiler { /** * Generate array/map/set variable * @param miniScript MiniScript instance - * @param generatedDeclarations generated declarations * @param generatedDefinitions generated definitions * @param miniScriptClassName MiniScript class name * @param methodName method name @@ -161,7 +234,6 @@ class miniscript::miniscript::Transpiler { */ static void generateArrayMapSetInitializer( MiniScript* miniScript, - string& generatedDeclarations, string& generatedDefinitions, const string& miniScriptClassName, const string& methodName, diff --git a/ext/miniscript/src/miniscript/miniscript/Version.cpp b/ext/miniscript/src/miniscript/miniscript/Version.cpp index a9614c840..417ffdb8f 100644 --- a/ext/miniscript/src/miniscript/miniscript/Version.cpp +++ b/ext/miniscript/src/miniscript/miniscript/Version.cpp @@ -9,7 +9,7 @@ using std::string; using miniscript::miniscript::Version; string Version::getVersion() { - return "0.9.15 PRE-BETA"; + return "0.9.16 PRE-BETA"; } string Version::getCopyright() { diff --git a/ext/miniscript/src/miniscript/miniscript/XMLMethods.cpp b/ext/miniscript/src/miniscript/miniscript/XMLMethods.cpp index e54b8913b..ae71ca49b 100644 --- a/ext/miniscript/src/miniscript/miniscript/XMLMethods.cpp +++ b/ext/miniscript/src/miniscript/miniscript/XMLMethods.cpp @@ -15,6 +15,9 @@ using miniscript::miniscript::MiniScript; using _Console = miniscript::utilities::Console; using _StringTools = miniscript::utilities::StringTools; +void XMLMethods::registerConstants(MiniScript* miniScript) { +} + void XMLMethods::registerMethods(MiniScript* miniScript) { // xml { diff --git a/ext/miniscript/src/miniscript/miniscript/XMLMethods.h b/ext/miniscript/src/miniscript/miniscript/XMLMethods.h index 5b623a44f..148e5887d 100644 --- a/ext/miniscript/src/miniscript/miniscript/XMLMethods.h +++ b/ext/miniscript/src/miniscript/miniscript/XMLMethods.h @@ -11,6 +11,12 @@ using miniscript::miniscript::MiniScript; */ class miniscript::miniscript::XMLMethods { public: + /** + * Register constants + * @param miniScript miniScript + */ + static void registerConstants(MiniScript* miniScript); + /** * Register methods * @param miniScript miniScript diff --git a/ext/miniscript/src/miniscript/os/network/SecureTCPSocket.cpp b/ext/miniscript/src/miniscript/os/network/SecureTCPSocket.cpp index af7944171..3c6df78f0 100644 --- a/ext/miniscript/src/miniscript/os/network/SecureTCPSocket.cpp +++ b/ext/miniscript/src/miniscript/os/network/SecureTCPSocket.cpp @@ -144,15 +144,19 @@ void SecureTCPSocket::connect(const string& hostname, const unsigned int port) { void SecureTCPSocket::shutdown() { if (bio != nullptr) BIO_free_all(bio); + if (out != nullptr) BIO_free_all(out); if (ctx != nullptr) SSL_CTX_free(ctx); bio = nullptr; + out = nullptr; ctx = nullptr; } void SecureTCPSocket::close() { if (bio != nullptr) BIO_free_all(bio); + if (out != nullptr) BIO_free_all(out); if (ctx != nullptr) SSL_CTX_free(ctx); bio = nullptr; + out = nullptr; ctx = nullptr; } diff --git a/ext/miniscript/src/miniscript/tools/miniscriptdocumentation-main.cpp b/ext/miniscript/src/miniscript/tools/miniscriptdocumentation-main.cpp index 1da2ecb67..663923bc6 100644 --- a/ext/miniscript/src/miniscript/tools/miniscriptdocumentation-main.cpp +++ b/ext/miniscript/src/miniscript/tools/miniscriptdocumentation-main.cpp @@ -54,17 +54,20 @@ int main(int argc, char** argv) auto miniScript = make_unique(); miniScript->setContext(context.get()); miniScript->registerMethods(); + miniScript->registerVariables(); // auto allClassMethods = Documentation::getAllClassMethods(miniScript.get()); // auto baseMethodCategories = Documentation::getMethodsCategories(miniScript.get(), allClassMethods); // classes - auto classesDocumentation = Documentation::generateClassesDocumentation("MiniScript Classes", 6, miniScript.get(), descriptions, "miniscript.basemethod.", allClassMethods); + auto classesDocumentation = Documentation::generateClassesDocumentation("Classes", 6, miniScript.get(), descriptions, "miniscript.basemethod.", allClassMethods); // base methods - auto methodsDocumentation = Documentation::generateMethodsDocumentation("MiniScript Methods", 7, miniScript.get(), descriptions, "miniscript.basemethod.", allClassMethods); - // base methods - auto operatorsDocumentation = Documentation::generateOperatorsDocumentation("MiniScript Operators", 10, miniScript.get()); + auto methodsDocumentation = Documentation::generateMethodsDocumentation("Methods", 7, miniScript.get(), descriptions, "miniscript.basemethod.", allClassMethods); + // variables + auto variablesDocumentation = Documentation::generateVariablesDocumentation("Constants", 8, miniScript.get()); + // operators + auto operatorsDocumentation = Documentation::generateOperatorsDocumentation("Operators", 9, miniScript.get()); // Console::println("Classes"); @@ -76,6 +79,11 @@ int main(int argc, char** argv) Console::println("---------"); Console::println(methodsDocumentation); + // + Console::println("Variables"); + Console::println("-----------"); + Console::println(variablesDocumentation); + // Console::println("Operators"); Console::println("-----------"); diff --git a/src/tdme/miniscript/MiniScriptMatrix3x3.cpp b/src/tdme/miniscript/MiniScriptMatrix3x3.cpp index 8b6172fe4..7b8db0b90 100644 --- a/src/tdme/miniscript/MiniScriptMatrix3x3.cpp +++ b/src/tdme/miniscript/MiniScriptMatrix3x3.cpp @@ -35,6 +35,9 @@ void MiniScriptMatrix3x3::initialize() { TYPE_VECTOR2 = static_cast(MiniScript::getDataTypeByClassName("Vector2")->getType()); } +void MiniScriptMatrix3x3::registerConstants(MiniScript* miniScript) const { +} + void MiniScriptMatrix3x3::registerMethods(MiniScript* miniScript) const { // { diff --git a/src/tdme/miniscript/MiniScriptMatrix3x3.h b/src/tdme/miniscript/MiniScriptMatrix3x3.h index d18001c14..3289a567f 100644 --- a/src/tdme/miniscript/MiniScriptMatrix3x3.h +++ b/src/tdme/miniscript/MiniScriptMatrix3x3.h @@ -21,6 +21,7 @@ using tdme::math::Matrix3x3; class tdme::miniscript::MiniScriptMatrix3x3 final: public MiniScript::DataType { private: // overridden methods + void registerConstants(MiniScript* miniScript) const override; void registerMethods(MiniScript* miniScript) const override; void unsetVariableValue(MiniScript::Variable& variable) const override; void setVariableValue(MiniScript::Variable& variable) const override; diff --git a/src/tdme/miniscript/MiniScriptMatrix4x4.cpp b/src/tdme/miniscript/MiniScriptMatrix4x4.cpp index 58d7f5b1f..9817a1160 100644 --- a/src/tdme/miniscript/MiniScriptMatrix4x4.cpp +++ b/src/tdme/miniscript/MiniScriptMatrix4x4.cpp @@ -37,6 +37,9 @@ void MiniScriptMatrix4x4::initialize() { TYPE_VECTOR4 = static_cast(MiniScript::getDataTypeByClassName("Vector4")->getType()); } +void MiniScriptMatrix4x4::registerConstants(MiniScript* miniScript) const { +} + void MiniScriptMatrix4x4::registerMethods(MiniScript* miniScript) const { // { diff --git a/src/tdme/miniscript/MiniScriptMatrix4x4.h b/src/tdme/miniscript/MiniScriptMatrix4x4.h index d316272c2..2cfd25097 100644 --- a/src/tdme/miniscript/MiniScriptMatrix4x4.h +++ b/src/tdme/miniscript/MiniScriptMatrix4x4.h @@ -21,6 +21,7 @@ using tdme::math::Matrix4x4; class tdme::miniscript::MiniScriptMatrix4x4 final: public MiniScript::DataType { private: // overridden methods + void registerConstants(MiniScript* miniScript) const override; void registerMethods(MiniScript* miniScript) const override; void unsetVariableValue(MiniScript::Variable& variable) const override; void setVariableValue(MiniScript::Variable& variable) const override; diff --git a/src/tdme/miniscript/MiniScriptQuaternion.cpp b/src/tdme/miniscript/MiniScriptQuaternion.cpp index 75795482b..65594ca17 100644 --- a/src/tdme/miniscript/MiniScriptQuaternion.cpp +++ b/src/tdme/miniscript/MiniScriptQuaternion.cpp @@ -37,6 +37,9 @@ void MiniScriptQuaternion::initialize() { TYPE_VECTOR3 = static_cast(MiniScript::getDataTypeByClassName("Vector3")->getType()); } +void MiniScriptQuaternion::registerConstants(MiniScript* miniScript) const { +} + void MiniScriptQuaternion::registerMethods(MiniScript* miniScript) const { { // diff --git a/src/tdme/miniscript/MiniScriptQuaternion.h b/src/tdme/miniscript/MiniScriptQuaternion.h index fbd31d519..0ea6ae56f 100644 --- a/src/tdme/miniscript/MiniScriptQuaternion.h +++ b/src/tdme/miniscript/MiniScriptQuaternion.h @@ -23,6 +23,7 @@ using tdme::math::Quaternion; class tdme::miniscript::MiniScriptQuaternion final: public MiniScript::DataType { private: // overridden methods + void registerConstants(MiniScript* miniScript) const override; void registerMethods(MiniScript* miniScript) const override; void unsetVariableValue(MiniScript::Variable& variable) const override; void setVariableValue(MiniScript::Variable& variable) const override; diff --git a/src/tdme/miniscript/MiniScriptTransform.cpp b/src/tdme/miniscript/MiniScriptTransform.cpp index c828fe5ac..ec9e835c8 100644 --- a/src/tdme/miniscript/MiniScriptTransform.cpp +++ b/src/tdme/miniscript/MiniScriptTransform.cpp @@ -41,6 +41,9 @@ void MiniScriptTransform::initialize() { TYPE_VECTOR3 = static_cast(MiniScript::getDataTypeByClassName("Vector3")->getType()); } +void MiniScriptTransform::registerConstants(MiniScript* miniScript) const { +} + void MiniScriptTransform::registerMethods(MiniScript* miniScript) const { // { diff --git a/src/tdme/miniscript/MiniScriptTransform.h b/src/tdme/miniscript/MiniScriptTransform.h index d4cafc753..060916aa2 100644 --- a/src/tdme/miniscript/MiniScriptTransform.h +++ b/src/tdme/miniscript/MiniScriptTransform.h @@ -21,6 +21,7 @@ using tdme::engine::Transform; class tdme::miniscript::MiniScriptTransform final: public MiniScript::DataType { private: // overridden methods + void registerConstants(MiniScript* miniScript) const override; void registerMethods(MiniScript* miniScript) const override; void unsetVariableValue(MiniScript::Variable& variable) const override; void setVariableValue(MiniScript::Variable& variable) const override; diff --git a/src/tdme/miniscript/MiniScriptVector2.cpp b/src/tdme/miniscript/MiniScriptVector2.cpp index d0739df2d..ae713d270 100644 --- a/src/tdme/miniscript/MiniScriptVector2.cpp +++ b/src/tdme/miniscript/MiniScriptVector2.cpp @@ -27,6 +27,9 @@ void MiniScriptVector2::initialize() { TYPE_VECTOR2 = static_cast(MiniScript::getDataTypeByClassName("Vector2")->getType()); } +void MiniScriptVector2::registerConstants(MiniScript* miniScript) const { +} + void MiniScriptVector2::registerMethods(MiniScript* miniScript) const { { // diff --git a/src/tdme/miniscript/MiniScriptVector2.h b/src/tdme/miniscript/MiniScriptVector2.h index 2edb61a2a..c761c2736 100644 --- a/src/tdme/miniscript/MiniScriptVector2.h +++ b/src/tdme/miniscript/MiniScriptVector2.h @@ -21,6 +21,7 @@ using tdme::math::Vector2; class tdme::miniscript::MiniScriptVector2 final: public MiniScript::DataType { private: // overridden methods + void registerConstants(MiniScript* miniScript) const override; void registerMethods(MiniScript* miniScript) const override; void unsetVariableValue(MiniScript::Variable& variable) const override; void setVariableValue(MiniScript::Variable& variable) const override; diff --git a/src/tdme/miniscript/MiniScriptVector3.cpp b/src/tdme/miniscript/MiniScriptVector3.cpp index fcdd8a4d7..54a15a47e 100644 --- a/src/tdme/miniscript/MiniScriptVector3.cpp +++ b/src/tdme/miniscript/MiniScriptVector3.cpp @@ -27,6 +27,9 @@ void MiniScriptVector3::initialize() { TYPE_VECTOR3 = static_cast(MiniScript::getDataTypeByClassName("Vector3")->getType()); } +void MiniScriptVector3::registerConstants(MiniScript* miniScript) const { +} + void MiniScriptVector3::registerMethods(MiniScript* miniScript) const { { // diff --git a/src/tdme/miniscript/MiniScriptVector3.h b/src/tdme/miniscript/MiniScriptVector3.h index e556c9f8b..f76ca04cf 100644 --- a/src/tdme/miniscript/MiniScriptVector3.h +++ b/src/tdme/miniscript/MiniScriptVector3.h @@ -21,6 +21,7 @@ using tdme::math::Vector3; class tdme::miniscript::MiniScriptVector3 final: public MiniScript::DataType { private: // overridden methods + void registerConstants(MiniScript* miniScript) const override; void registerMethods(MiniScript* miniScript) const override; void unsetVariableValue(MiniScript::Variable& variable) const override; void setVariableValue(MiniScript::Variable& variable) const override; diff --git a/src/tdme/miniscript/MiniScriptVector4.cpp b/src/tdme/miniscript/MiniScriptVector4.cpp index 705b417b3..9cb8080e0 100644 --- a/src/tdme/miniscript/MiniScriptVector4.cpp +++ b/src/tdme/miniscript/MiniScriptVector4.cpp @@ -27,6 +27,9 @@ void MiniScriptVector4::initialize() { TYPE_VECTOR4 = static_cast(MiniScript::getDataTypeByClassName("Vector4")->getType()); } +void MiniScriptVector4::registerConstants(MiniScript* miniScript) const { +} + void MiniScriptVector4::registerMethods(MiniScript* miniScript) const { { // diff --git a/src/tdme/miniscript/MiniScriptVector4.h b/src/tdme/miniscript/MiniScriptVector4.h index 99fab2f71..ae434b9a9 100644 --- a/src/tdme/miniscript/MiniScriptVector4.h +++ b/src/tdme/miniscript/MiniScriptVector4.h @@ -21,6 +21,7 @@ using tdme::math::Vector4; class tdme::miniscript::MiniScriptVector4 final: public MiniScript::DataType { private: // overridden methods + void registerConstants(MiniScript* miniScript) const override; void registerMethods(MiniScript* miniScript) const override; void unsetVariableValue(MiniScript::Variable& variable) const override; void setVariableValue(MiniScript::Variable& variable) const override;