10 #include <unordered_map>
11 #include <unordered_set>
32 using std::make_unique;
40 using std::string_view;
42 using std::unique_ptr;
43 using std::unordered_map;
44 using std::unordered_set;
59 #define MINITSCRIPT_METHODUSAGE_COMPLAIN(methodName) { minitScript->complain(methodName, subStatement); minitScript->startErrorScript(); }
60 #define MINITSCRIPT_METHODUSAGE_COMPLAINM(methodName, message) { minitScript->complain(methodName, subStatement, message); minitScript->startErrorScript(); }
61 #define MINITSCRIPT_METHODUSAGE_COMPLAINO(methodName, operatorString) { minitScript->complainOperator(methodName, operatorString, subStatement); minitScript->startErrorScript(); }
62 #define MINITSCRIPT_METHODUSAGE_COMPLAINOM(methodName, operatorString, message) { minitScript->complainOperator(methodName, operatorString, subStatement, message); minitScript->startErrorScript(); }
209 class SyntaxTreeNode;
916 auto createReference =
false;
926 createReference =
true;
944 return nonConstVariable;
955 return referenceVariable;
964 auto referenceVariable =
new Variable();
965 referenceVariable->setReference((
Variable*)variable);
966 return referenceVariable;
979 return nonReferenceVariable;
988 auto nonReferenceVariable =
new Variable();
992 return nonReferenceVariable;
1071 _Console::printLine(
"ScriptVariable::copyScriptVariable(): unknown data type with id " + to_string(dataTypeIdx));
1077 if (properties ==
true) {
1092 std::swap(_a.typeBits, _b.typeBits);
1093 std::swap(_a.valuePtr, _b.valuePtr);
1094 std::swap(_a.initializerReferenceUnion, _b.initializerReferenceUnion);
1095 std::swap(_a.referenceCounter, _b.referenceCounter);
1120 variable.initializerReferenceUnion.initializer =
nullptr;
1147 std::swap(
typeBits, variable.typeBits);
1148 std::swap(
valuePtr, variable.valuePtr);
1238 inline Variable(
const unordered_map<string, Variable*>& value) {
1254 if (
getType() == newType)
return;
1288 for (
const auto& [mapEntryName, mapEntryValue]:
getMapValueReference()) mapEntryValue->releaseReference();
1302 _Console::printLine(
"ScriptVariable::setType(): unknown data type with id " + to_string(dataTypeIdx));
1312 static_cast<uint32_t
>(newType) |
1318 static_cast<uint32_t
>(newType) |
1365 _Console::printLine(
"ScriptVariable::setType(): unknown data type with id " + to_string(dataTypeIdx));
1395 this->valuePtr = (uint64_t)
valuePtr;
1420 if (lowerCaseString !=
"false" && lowerCaseString !=
"true" && lowerCaseString !=
"1" && lowerCaseString !=
"0")
return optional;
1421 value = lowerCaseString ==
"true" || lowerCaseString ==
"1";
1489 if (
_Float::is(stringValue) ==
false)
return optional;
1511 function = functionValue.name;
1512 scriptIdx = functionValue.scriptIdx;
1533 stacklet = functionValue.name;
1534 scriptIdx = functionValue.scriptIdx;
1578 if (
getIntegerValue(intValue,
false) ==
true && value >= 0 && value <= 255) {
1582 if (statement !=
nullptr) {
1666 for (
const auto arrayEntry: value) {
1667 byteArrayValue.push_back(arrayEntry);
1678 for (
const auto arrayEntry: value) {
1679 arrayValue.push_back(
new Variable(*arrayEntry));
1687 inline void setValue(
const unordered_map<string, Variable*>& value) {
1690 for (
const auto& [mapEntryName, mapEntryValue]: value) {
1691 mapValue[mapEntryName] =
new Variable(*mapEntryValue);
1699 inline void setValue(
const unordered_set<string>& value) {
1712 _Console::printLine(
"ScriptVariable::setValue(): unknown data type with id " + to_string(dataTypeIdx));
1724 return &byteArrayValue;
1733 return &byteArrayValue;
1789 if (idx >= 0 && idx < byteArrayValue.size())
return byteArrayValue[idx];
1799 if (idx < 0)
return;
1802 byteArrayValue[idx] = value;
1822 if (idx >= 0 && idx < byteArrayValue.size()) {
1823 byteArrayValue.erase(byteArrayValue.begin() + idx, byteArrayValue.begin() + idx + size);
1833 byteArrayValue.clear();
1871 if (idx >= 0 && idx < arrayValue.size())
return *arrayValue[idx];
1881 if (idx < 0)
return;
1884 arrayValue[idx]->releaseReference();
1885 arrayValue[idx] =
new Variable(value);
1904 if (idx >= 0 && idx < arrayValue.size()) {
1905 arrayValue[idx]->releaseReference();
1906 arrayValue.erase(arrayValue.begin() + idx);
1917 for (
auto i = 0; i < arrayValue.size(); i++) arrayValue[i]->
releaseReference();
1955 auto it = mapValue.find(key);
1956 if (it != mapValue.end())
return true;
1968 auto it = mapValue.find(key);
1969 if (it != mapValue.end())
return *it->second;
1981 auto it = mapValue.find(key);
1982 if (it != mapValue.end())
return it->second;
1997 auto variablePtr =
new Variable(value);
1998 if (_private ==
true) variablePtr->setPrivate();
2009 auto mapValueIt = mapValue.find(key);
2010 if (mapValueIt != mapValue.end()) {
2011 mapValueIt->second->releaseReference();
2012 mapValue.erase(mapValueIt);
2021 vector<string> keys;
2024 for (
const auto& [mapEntryName, mapEntryValue]: mapValue) {
2025 keys.push_back(mapEntryName);
2035 vector<Variable*> values;
2038 for (
const auto& [mapEntryKey, mapEntryValue]: mapValue) {
2039 values.push_back(mapEntryValue);
2050 for (
const auto& [mapEntryName, mapEntryValue]: mapValue) {
2051 mapEntryValue->releaseReference();
2091 if (it !=
setValue.end())
return true;
2122 vector<string> keys;
2126 keys.push_back(key);
2157 functionValue.name =
function;
2158 functionValue.scriptIdx = scriptIdx;
2169 functionValue.name = stacklet;
2170 functionValue.scriptIdx = scriptIdx;
2193 auto viewIsFunctionAssignment = [](
const string_view& candidate, string_view&
function) ->
bool {
2194 if (candidate.size() == 0)
return false;
2198 if (candidate[i++] !=
'(')
return false;
2200 if (i >= candidate.size())
return false;
2202 if (candidate[i++] !=
')')
return false;
2205 if (i >= candidate.size())
return false;
2207 if (candidate[i++] !=
'-')
return false;
2209 if (i >= candidate.size())
return false;
2211 if (candidate[i++] !=
'>')
return false;
2214 if (i >= candidate.size())
return false;
2216 auto functionStartIdx = i;
2217 for (; i < candidate.size(); i++) {
2218 auto c = candidate[i];
2224 function = string_view(&candidate[functionStartIdx], i - functionStartIdx);
2229 auto viewIsStackletAssignment = [](
const string_view& candidate, string_view& stacklet) ->
bool {
2230 if (candidate.size() == 0)
return false;
2235 if (i >= candidate.size())
return false;
2237 if (candidate[i++] !=
'-')
return false;
2239 if (i >= candidate.size())
return false;
2241 if (candidate[i++] !=
'>')
return false;
2244 if (i >= candidate.size())
return false;
2246 auto stackletStartIdx = i;
2247 for (; i < candidate.size(); i++) {
2248 auto c = candidate[i];
2254 stacklet = string_view(&candidate[stackletStartIdx], i - stackletStartIdx);
2259 string_view functionOrStacklet;
2261 if (value ==
"null") {
2264 if (value ==
"true") {
2267 if (value ==
"false") {
2287 if (viewIsFunctionAssignment(value, functionOrStacklet) ==
true) {
2290 if (viewIsStackletAssignment(value, functionOrStacklet) ==
true) {
2310 if (type == expectedType)
return true;
2311 switch(expectedType) {
2404 inline const string getValueAsString(
bool formatted =
false,
bool jsonCompatible =
false,
int depth = 0)
const {
2405 auto escapeString = [](
const string& str) ->
const string {
2406 const array<char, 11> escapeSequences = {
'0',
'a',
'b',
'f',
'n',
'r',
't',
'v',
'U',
'"'};
2423 for (
auto i = 0; i < result.size(); i++) {
2426 auto nc = i < result.size() - 1?result[i + 1]:
'\0';
2427 if (c ==
'\\' && lc !=
'\\' && nc !=
'\\' && find(escapeSequences.begin(), escapeSequences.end(), nc) == escapeSequences.end()) {
2460 result+=
"() -> " + functionValue.name +
"(" + to_string(functionValue.scriptIdx) +
")";
2466 result+=
"-> " + functionValue.name +
"(" + to_string(functionValue.scriptIdx) +
")";
2481 vector<string> values;
2482 for (
const auto arrayEntry: byteArrayValue) {
2483 values.push_back(to_string(arrayEntry));
2486 for (
const auto& valueString: values) {
2487 result+= valueString;
2488 if (i != values.size() - 1) result+=
", ";
2492 "ByteArray([" + result +
"], " +
2493 "size: " + to_string(byteArrayValue.size()) +
2494 ", capacity: " + to_string(byteArrayValue.capacity()) +
2503 vector<string> values;
2504 for (
const auto arrayEntry: arrayValue) {
2506 values.push_back(
"\"" +
escapeString(arrayEntry->getValueAsString(formatted, jsonCompatible, depth + 1)) +
"\"");
2508 values.push_back(arrayEntry->getValueAsString(formatted, jsonCompatible, depth + 1));
2511 if (formatted ==
true) {
2513 for (
auto& value: values) {
2514 if (i != values.size() - 1) value+=
",";
2517 for (
const auto& valueString: values) {
2525 for (
const auto& valueString: values) {
2526 result+= valueString;
2527 if (i != values.size() - 1) result+=
", ";
2530 result =
"[" + result +
"]";
2537 vector<string> values;
2538 for (
const auto& [mapEntryName, mapEntryValue]: mapValue) {
2543 value+=
escapeString(mapEntryValue->getValueAsString(formatted, jsonCompatible, depth + 1));
2546 value+= mapEntryValue->getValueAsString(formatted, jsonCompatible, depth + 1);
2548 values.push_back(value);
2550 sort(values.begin(), values.end());
2551 if (formatted ==
true) {
2553 for (
auto& value: values) {
2554 if (i != values.size() - 1) value+=
",";
2557 for (
const auto& valueString: values) {
2565 for (
const auto& valueString: values) {
2566 result+= valueString;
2567 if (i != values.size() - 1) result+=
", ";
2570 result =
"{" + result +
"}";
2577 vector<string> values;
2582 if (jsonCompatible ==
true) {
2583 values.back() +=
": true";
2586 sort(values.begin(), values.end());
2587 if (formatted ==
true) {
2589 for (
auto& value: values) {
2590 if (i != values.size() - 1) value+=
",";
2593 for (
const auto& valueString: values) {
2601 for (
const auto& valueString: values) {
2602 result+= valueString;
2603 if (i != values.size() - 1) result+=
", ";
2606 result =
"{" + result +
"}";
2614 _Console::printLine(
"ScriptVariable::getValueAsString(): unknown data type with id " + to_string(dataTypeIdx));
2723 auto optionalArgumentCount = 0;
2724 auto argumentIdx = 0;
2726 string argumentResult;
2727 if (argumentType.optional ==
true) {
2729 optionalArgumentCount++;
2731 if (argumentIdx > beginIdx) result+=
", ";
2732 if (optionalArgumentCount > 0 || argumentIdx >= beginIdx) {
2733 if (argumentType.reference ==
true) {
2736 result+=
"$" + argumentType.name +
": " + (argumentType.nullable ==
true?
"?":
"") +
Variable::getTypeAsString(argumentType.type);
2741 if (argumentIdx > beginIdx) result+=
", ";
2744 for (
auto i = 0; i < optionalArgumentCount; i++) result+=
"]";
2832 const vector<SyntaxTreeNode>&
arguments,
2853 const vector<SyntaxTreeNode>&
arguments,
3007 string argumentsString;
3008 for (
const auto& argument: arguments) {
3009 switch (argument.type) {
3011 switch(argument.value.getType()) {
3014 argumentsString+= (argumentsString.empty() ==
false?
", ":
"") +
string(
"<Null>");
3021 argumentsString+= (argumentsString.empty() ==
false?
", ":
"") + argument.value.getValueAsString();
3026 argumentsString+= (argumentsString.empty() ==
false?
", ":
"") +
string(
"\"") +
escapeString(argument.value.getValueAsString()) + string(
"\"");
3031 argumentsString+= (argumentsString.empty() ==
false?
", ":
"") +
string(
"<COMPLEX DATATYPE>");
3038 argumentsString+= (argumentsString.empty() ==
false?
", ":
"") + argument.value.getValueAsString() + string(
"(") +
getArgumentsAsString(argument.arguments) + string(
")");
3044 return argumentsString;
3150 const array<char, 11> escapeSequences = {
'0',
'a',
'b',
'f',
'n',
'r',
't',
'v',
'U',
'"'};
3151 for (
const auto c: escapeSequences) {
3168 for (
auto i = 0; i < result.size(); i++) {
3171 auto nc = i < result.size() - 1?result[i + 1]:
'\0';
3172 if (c ==
'\\' && lc !=
'\\' && nc !=
'\\' && find(escapeSequences.begin(), escapeSequences.end(), nc) == escapeSequences.end()) {
3192 static const string decodeOperator(
const span<MinitScript::Variable>& arguments,
int operatorValueIdx,
const string& defaultOperatorString) {
3194 int64_t operatorValue;
3198 auto c1 = (operatorValue & 255);
3199 auto c2 = ((operatorValue >> 8) & 255);
3200 if (c1 != 0ll) result+= (char)c1;
3201 if (c2 != 0ll) result+= (char)c2;
3285 void dumpScriptState(ScriptState& scriptState,
const string& message =
string());
3301 unordered_set<string> deletedVariables;
3302 for (
const auto& [variableName, variable]: scriptState.variables) {
3303 if (variable->isReference() ==
false)
continue;
3304 deletedVariables.insert(variableName);
3308 for (
const auto& [variableName, variable]: scriptState.variables) {
3309 if (deletedVariables.contains(variableName) ==
true)
continue;
3312 scriptState.variables.clear();
3338 scriptState.forTimeStarted.clear();
3339 scriptState.blockStack.clear();
3341 scriptState.blockStack.emplace_back(
3351 scriptState.blockStack.emplace_back(
3359 scriptState.scriptIdx = scriptIdx;
3363 scriptState.timeWaitTime = 0LL;
3364 scriptState.returnValue.setNullValue();
3375 scriptState.blockStack.emplace_back(
3382 scriptState.scriptIdx = scriptIdx;
3385 scriptState.returnValue.setNullValue();
3406 scriptState.running =
false;
3418 scriptState.state = state;
3420 scriptState.lastStateMachineState =
nullptr;
3445 void createLamdaFunction(Variable& variable,
const vector<string_view>& arguments,
const string_view& functionScriptCode,
int lineIdx,
bool populateThis,
const Statement& statement,
const string& nameHint =
string());
3456 void createStacklet(Variable& variable,
const string& scopeName,
const vector<string_view>& arguments,
const string_view& stackletScriptCode,
int lineIdx,
const Statement& statement);
3466 static const Variable
initializeArray(
const string_view& initializerString,
MinitScript* minitScript,
int scriptIdx,
const Statement& statement);
3476 static const Variable
initializeMapSet(
const string_view& initializerString,
MinitScript* minitScript,
int scriptIdx,
const Statement& statement);
3514 for (
const auto dataType:
dataTypes)
delete dataType;
3613 bool getNextStatement(
const string& scriptCode,
int& i,
int& line,
string& statement);
3624 bool parseStatement(
const string_view& executableStatement, string_view& methodName, vector<ParserArgument>& arguments,
const Statement& statement,
string& accessObjectMemberStatement);
3756 bool getObjectMemberAccess(
const string_view& executableStatement, string_view&
object, string_view& method,
int& methodStartIdx,
const Statement& statement);
3767 bool getVariableAccessOperatorLeftRightIndices(
const string& variableStatement,
const string& callerMethod, string::size_type& accessOperatorLeftIdx, string::size_type& accessOperatorRightIdx,
const SubStatement* subStatement =
nullptr,
int startIdx = 0);
3779 bool evaluateAccess(
const string& variableStatement,
const string& callerMethod, string::size_type& arrayAccessOperatorLeftIdx, string::size_type& arrayAccessOperatorRightIdx, int64_t& arrayIdx,
string& key,
const SubStatement* subStatement =
nullptr);
3794 Variable*
evaluateVariableAccessIntern(Variable* variablePtr,
const string& variableStatement,
const string& callerMethod, Variable*& parentVariable, int64_t& arrayIdx,
string& key,
int& setAccessBool,
const SubStatement* subStatement =
nullptr,
bool expectVariable =
true);
3810 inline Variable*
getVariableIntern(
const string& variableStatement,
const string& callerMethod,
string& variableName,
Variable*& parentVariable, int64_t& arrayIdx,
string& key,
int& setAccessBool,
const SubStatement* subStatement =
nullptr,
bool expectVariable =
true,
bool global =
false) {
3813 auto dotIdx = string::npos;
3814 auto squareBracketIdx = string::npos;
3816 for (
auto i = 0; i < variableStatement.size(); i++) {
3817 auto c = variableStatement[i];
3819 if (dotIdx == string::npos) dotIdx = i;
3822 if (squareBracketIdx == string::npos) squareBracketIdx = i;
3824 if (lc ==
':' && c ==
':') {
3825 dotIdx = string::npos;
3826 squareBracketIdx = string::npos;
3831 if (dotIdx == string::npos) dotIdx = variableStatement.size();
3832 if (squareBracketIdx == string::npos) squareBracketIdx = variableStatement.size();
3836 dotIdx < squareBracketIdx?
3844 auto variableIt = scriptState.variables.find(variableName);
3845 if (variableIt == scriptState.variables.end()) {
3846 if (expectVariable ==
true) {
3851 variablePtr = variableIt->second;
3854 return evaluateVariableAccessIntern(variablePtr, variableStatement, callerMethod, parentVariable, arrayIdx, key, setAccessBool, subStatement, expectVariable);
3868 void setVariableInternal(
const string& variableStatement, Variable* parentVariable, Variable* variablePtr, int64_t arrayIdx,
const string& key,
const Variable& variable,
const SubStatement* subStatement =
nullptr,
bool createReference =
false);
3888 bool call(
int scriptIdx, span<Variable>& arguments, Variable& returnValue,
bool pushScriptState);
3900 auto functionIt =
functions.find(
function);
3905 auto scriptIdx = functionIt->second;
3924 string deescapedStr;
3926 for (
auto i = 0; i < str.size(); i++) {
3928 if (c !=
'\\' || lc ==
'\\') {
3932 if (lc ==
'\\' && c ==
'0') deescapedStr+=
'\0';
else
3934 if (lc ==
'\\' && c ==
'a') deescapedStr+=
'\a';
else
3936 if (lc ==
'\\' && c ==
'b') deescapedStr+=
'\b';
else
3938 if (lc ==
'\\' && c ==
'f') deescapedStr+=
'\f';
else
3940 if (lc ==
'\\' && c ==
'n') deescapedStr+=
'\n';
else
3942 if (lc ==
'\\' && c ==
'r') deescapedStr+=
'\r';
else
3944 if (lc ==
'\\' && c ==
't') deescapedStr+=
'\t';
else
3946 if (lc ==
'\\' && c ==
'v') deescapedStr+=
'\v';
else
3948 if (lc ==
'\\' && c ==
'U') {
3949 string unicodeHexadecimalSequence;
3952 for (i++; i < str.size() && j < 8; i++ && j++) {
3954 unicodeHexadecimalSequence+= c;
3955 if (((c >=
'0' && c <=
'9') || (c >=
'a' && c <=
'f') || (c >=
'A' && c <=
'F')) ==
false)
break;
3958 if (valid ==
false || j != 8) {
3971 return deescapedStr;
3982 inline static bool viewIsLamdaFunction(
const string_view& candidate, vector<string_view>& arguments, string_view& functionScriptCode,
int& lineIdx) {
3983 if (candidate.size() == 0)
return false;
3987 if (candidate[i++] !=
'(')
return false;
3990 if (i >= candidate.size())
return false;
3992 auto argumentStartIdx = string::npos;
3993 auto argumentEndIdx = string::npos;
3995 for (; i < candidate.size(); i++) {
3996 auto c = candidate[i];
3998 if (argumentStartIdx == string::npos) {
3999 argumentStartIdx = i;
4005 if (argumentStartIdx == string::npos) {
4006 argumentStartIdx = i;
4008 if (argumentStartIdx == i - 1 && candidate[argumentStartIdx] ==
'&') {
4014 if (c ==
',' || c ==
')') {
4015 if (argumentEndIdx == string::npos) {
4016 if (argumentStartIdx != string::npos) {
4018 arguments.push_back(string_view(&candidate[argumentStartIdx], argumentEndIdx - argumentStartIdx));
4021 argumentStartIdx = string::npos;
4022 argumentEndIdx = string::npos;
4036 if (i >= candidate.size())
return false;
4039 if (i >= candidate.size())
return false;
4041 if (candidate[i++] !=
'-')
return false;
4043 if (i >= candidate.size())
return false;
4045 if (candidate[i++] !=
'>')
return false;
4048 if (i >= candidate.size())
return false;
4050 if (candidate[i++] !=
'{')
return false;
4052 for (
auto j = 0; j < i - 1; j++) {
4053 if (candidate[j] ==
'\n') lineIdx++;
4056 auto scriptCodeStartIdx = i;
4057 auto scriptCodeEndIdx = string::npos;
4059 for (
auto j = candidate.size() - 1; j > i; j--) {
4060 if (candidate[j] ==
'}') {
4061 scriptCodeEndIdx = j;
4069 if (scriptCodeEndIdx == string::npos)
return false;
4071 functionScriptCode = string_view(&candidate[scriptCodeStartIdx], scriptCodeEndIdx - scriptCodeStartIdx);
4084 inline static bool viewIsStacklet(
const string_view& candidate, vector<string_view>& arguments, string_view& stackletScriptCode,
int& lineIdx) {
4085 if (candidate.size() == 0)
return false;
4090 if (i >= candidate.size())
return false;
4092 if (candidate[i++] !=
'-')
return false;
4094 if (i >= candidate.size())
return false;
4096 if (candidate[i++] !=
'>')
return false;
4099 if (i >= candidate.size())
return false;
4101 if (candidate[i++] !=
'{')
return false;
4103 for (
auto j = 0; j < i - 1; j++) {
4104 if (candidate[j] ==
'\n') lineIdx++;
4107 auto scriptCodeStartIdx = i;
4108 auto scriptCodeEndIdx = string::npos;
4110 for (
auto j = candidate.size() - 1; j > i; j--) {
4111 if (candidate[j] ==
'}') {
4112 scriptCodeEndIdx = j;
4120 if (scriptCodeEndIdx == string::npos)
return false;
4122 stackletScriptCode = string_view(&candidate[scriptCodeStartIdx], scriptCodeEndIdx - scriptCodeStartIdx);
4133 if (candidate.size() < 2)
return false;
4135 if (candidate[i++] !=
'$')
return false;
4136 if (candidate[i] ==
'$') i++;
4137 auto squareBracketCount = 0;
4138 for (; i < candidate.size(); i++) {
4139 auto c = candidate[i];
4141 squareBracketCount++;
4144 squareBracketCount--;
4158 static bool viewIsKey(
const string_view& candidate);
4181 if (candidate.size() < 2)
return false;
4184 if (candidate[i] !=
'"' && candidate[i] !=
'\'')
return false;
4186 auto quote = candidate[i++];
4188 if (candidate[candidate.size() - 1] != quote)
return false;
4191 for (; i < candidate.size() - 1; i++) {
4192 auto c = candidate[i];
4193 if (c == quote && lc !=
'\\')
return false;
4205 inline static string_view
dequote(
const string_view& str) {
4228 auto leftBracketIdx = candidate.find(
'(');
4229 auto rightBracketIdx = candidate.rfind(
')');
4230 return leftBracketIdx > 0 && rightBracketIdx > leftBracketIdx;
4277 return garbageCollectionScriptContextsByDataTypeIt->second;
4320 for (
const auto argumentIdx: argumentIndices) {
4321 if (result.empty() ==
false) result+= delimiter;
4322 result+= to_string(argumentIdx);
4346 void complain(
const string& methodName,
const SubStatement& subStatement);
4354 void complain(
const string& methodName,
const SubStatement& subStatement,
const string& message);
4362 void complainOperator(
const string& methodName,
const string& operatorString,
const SubStatement& subStatement);
4371 void complainOperator(
const string& methodName,
const string& operatorString,
const SubStatement& subStatement,
const string& message);
4387 if (dataType->getTypeAsString() == className)
return dataType;
4543 auto subLineIdx = 0;
4544 for (
auto i = 0; i < statement.size() && i <= idx; i++) {
4545 if (statement[i] ==
'\n') subLineIdx++;
4558 auto statementCode = statement.
statement;
4559 auto statementLine = statement.
line;
4560 if (subLineIdx != -1) {
4562 if (subLineIdx >= 0 && subLineIdx < statementCodeLines.size()) {
4563 statementCode = statementCodeLines[subLineIdx];
4564 statementLine+= subLineIdx;
4568 return scriptFileName +
":" + to_string(statementLine) +
": " + statementCode;
4586 auto scriptMethod =
getMethod(methodName);
4587 if (scriptMethod ==
nullptr) {
4588 _Console::printLine(
"MinitScript::getArgumentInformation(): method not found: " + methodName);
4589 return "No information available";
4591 return scriptMethod->getArgumentsInformation();
4626 default:
return "INVALID";
4649 for (
const auto& argument: arguments)
if (argument.getType() == type)
return true;
4660 for (
auto i = 0; i < arguments.size() - (arguments.size() == 3?1:0); i++) {
4661 if (arguments[i].getType() == type)
return true;
4674 inline static bool getBooleanValue(
const span<Variable>& arguments,
int idx,
bool& value,
bool optional =
false) {
4675 if (idx >= arguments.size())
return optional;
4676 const auto& argument = arguments[idx];
4677 return argument.getBooleanValue(value, optional);
4688 inline static bool getIntegerValue(
const span<Variable>& arguments,
int idx, int64_t& value,
bool optional =
false) {
4689 if (idx >= arguments.size())
return optional;
4690 const auto& argument = arguments[idx];
4691 return argument.getIntegerValue(value, optional);
4702 inline static bool getFloatValue(
const span<Variable>& arguments,
int idx,
float& value,
bool optional =
false) {
4703 if (idx >= arguments.size())
return optional;
4704 const auto& argument = arguments[idx];
4705 return argument.getFloatValue(value, optional);
4717 inline static bool getFunctionValue(
const span<Variable>& arguments,
int idx,
string&
function,
int& scriptIdx,
bool optional =
false) {
4718 if (idx >= arguments.size())
return optional;
4719 const auto& argument = arguments[idx];
4720 return argument.getFunctionValue(
function, scriptIdx, optional);
4732 inline static bool getStackletValue(
const span<Variable>& arguments,
int idx,
string& stacklet,
int& scriptIdx,
bool optional =
false) {
4733 if (idx >= arguments.size())
return optional;
4734 const auto& argument = arguments[idx];
4735 return argument.getStackletValue(stacklet, scriptIdx, optional);
4746 inline static bool getStringValue(
const span<Variable>& arguments,
int idx,
string& value,
bool optional =
false) {
4747 if (idx >= arguments.size())
return optional;
4748 const auto& argument = arguments[idx];
4749 return argument.getStringValue(value, optional);
4771 if (candidate.size() < 2) {
4776 if (candidate[i++] !=
'$') {
4780 if (candidate[i] ==
'$') i++;
4782 auto squareBracketCount = 0;
4783 for (; i < candidate.size(); i++) {
4784 auto c = candidate[i];
4786 squareBracketCount++;
4789 squareBracketCount--;
4796 if (candidate.size() == 2 && string_view(candidate) == string_view(
"$$", 2)) {
4800 if (candidate.size() == 7 && string_view(candidate) == string_view(
"$GLOBAL", 7)) {
4815 string variableName;
4817 string globalVariableStatement;
4825 Variable* parentVariable =
nullptr;
4829 auto variablePtr =
getVariableIntern(globalVariableStatement.empty() ==
true?variableStatement:globalVariableStatement, __FUNCTION__, variableName, parentVariable, arrayIdx, key, setAccessBool, subStatement,
false, globalVariableStatement.empty() ==
false);
4835 if (variablePtr !=
nullptr) {
4852 string variableName;
4854 string globalVariableStatement;
4863 Variable* parentVariable =
nullptr;
4867 auto variablePtr =
getVariableIntern(globalVariableStatement.empty() ==
true?variableStatement:globalVariableStatement, __FUNCTION__, variableName, parentVariable, arrayIdx, key, setAccessBool, subStatement,
true, globalVariableStatement.empty() ==
false);
4873 if (variablePtr !=
nullptr) {
4876 if (variable.isReference() ==
false) variable.unsetConstant();
4895 Variable* parentVariable =
nullptr;
4899 variablePtr =
evaluateVariableAccessIntern(variablePtr, variableStatement, __FUNCTION__, parentVariable, arrayIdx, key, setAccessBool, subStatement,
true);
4905 if (variablePtr !=
nullptr) {
4908 if (variable.isReference() ==
false) variable.unsetConstant();
4927 string variableName;
4929 string globalVariableStatement;
4938 Variable* parentVariable =
nullptr;
4942 auto variablePtr =
getVariableIntern(globalVariableStatement.empty() ==
true?variableStatement:globalVariableStatement, __FUNCTION__, variableName, parentVariable, arrayIdx, key, setAccessBool, subStatement,
true, globalVariableStatement.empty() ==
false);
4948 if (variablePtr !=
nullptr) {
4951 if (createReference ==
false) variable.unsetConstant();
4971 Variable* parentVariable =
nullptr;
4975 variablePtr =
evaluateVariableAccessIntern(variablePtr, variableStatement, __FUNCTION__, parentVariable, arrayIdx, key, setAccessBool, subStatement,
true);
4981 if (variablePtr !=
nullptr) {
4984 if (createReference ==
false) variable.unsetConstant();
5004 Variable* parentVariable =
nullptr;
5008 variablePtr =
evaluateVariableAccessIntern(variablePtr, variableStatement, __FUNCTION__, parentVariable, arrayIdx, key, setAccessBool, subStatement,
true);
5014 if (variablePtr !=
nullptr) {
5016 variablePtr->
unset();
5029 string variableName;
5031 string globalVariableStatement;
5040 Variable* parentVariable =
nullptr;
5044 auto variablePtr =
getVariableIntern(globalVariableStatement.empty() ==
true?variableStatement:globalVariableStatement, __FUNCTION__, variableName, parentVariable, arrayIdx, key, setAccessBool, subStatement,
true, globalVariableStatement.empty() ==
false);
5050 if (variablePtr !=
nullptr) {
5051 variablePtr->unset();
5061 auto constVariable = variable;
5077 string variableName;
5079 string globalVariableStatement;
5088 Variable* parentVariable =
nullptr;
5092 auto variablePtr =
getVariableIntern(globalVariableStatement.empty() ==
true?variableStatement:globalVariableStatement, __FUNCTION__, variableName, parentVariable, arrayIdx, key, setAccessBool, subStatement,
false, globalVariableStatement.empty() ==
false);
5095 if (variablePtr ==
nullptr && parentVariable ==
nullptr) {
5098 auto variableIt = scriptState.variables.find(globalVariableStatement.empty() ==
true?variableStatement:globalVariableStatement);
5099 if (variableIt != scriptState.variables.end()) {
5100 auto& existingVariable = variableIt->second;
5101 if (existingVariable->isConstant() ==
false) {
5103 if (createReference ==
true) {
5104 existingVariable->setReference(&variable);
5106 existingVariable->setValue(variable);
5114 scriptState.variables[globalVariableStatement.empty() ==
true?variableStatement:globalVariableStatement] =
5118 setVariableInternal(variableStatement, parentVariable, variablePtr, arrayIdx, key, variable, subStatement, createReference);
5134 string variableName;
5136 string globalVariableStatement;
5145 Variable* parentVariable =
nullptr;
5149 variablePtr =
evaluateVariableAccessIntern(variablePtr, globalVariableStatement.empty() ==
true?variableStatement:globalVariableStatement, __FUNCTION__, parentVariable, arrayIdx, key, setAccessBool, subStatement,
false);
5152 setVariableInternal(variableStatement, parentVariable, variablePtr, arrayIdx, key, variable, subStatement, createReference);
5161 void parseScript(
const string& pathName,
const string& fileName,
bool nativeOnly =
false);
5175 for (
const auto& script:
scripts) {
5179 if (script.emitCondition ==
true && script.condition == condition) {
5192 virtual void emit(
const string& condition);
5206 auto functionIt =
functions.find(
function);
5211 auto scriptIdx = functionIt->second;
5223 inline bool call(
int scriptIdx, span<Variable>& arguments,
Variable& returnValue) {
5224 return call(scriptIdx, arguments, returnValue,
true);
5234 inline bool call(
const string&
function, span<Variable>& arguments,
Variable& returnValue) {
5235 return call(
function, arguments, returnValue,
true);
5246 return call(scriptIdx, arguments, returnValue,
false);
5257 return call(stacklet, arguments, returnValue,
false);
5290 auto methodIt =
methods.find(methodName);
5291 if (methodIt !=
methods.end()) {
5292 return methodIt->second;
5309 auto methodIt =
operators.find(operator_);
5311 return methodIt->second;
minitscript::utilities::Exception _Exception
MinitScript script application methods.
MinitScript script base methods.
MinitScript script JSON methods.
MinitScript math methods.
virtual ~ScriptContext()
Destructor.
MinitScript * minitScript
ScriptContext()
Constructor.
void setIndex(int index)
Set garbage collection type index.
void setRequiresGarbageCollection()
Set requires garbage collection.
void setMinitScript(MinitScript *minitScript)
Set MinitScript instance.
void unsetRequiresGarbageCollection()
Unset requires garbage collection.
virtual void setVariableValue(Variable &variable, const void *value) const =0
Set variable value.
virtual void setVariableValue(Variable &variable) const =0
Set variable value.
bool isRequiringGarbageCollection()
virtual bool add(MinitScript *minitScript, const span< MinitScript::Variable > &arguments, MinitScript::Variable &returnValue, const MinitScript::SubStatement &subStatement) const =0
Addition.
bool requiresGarbageCollection
virtual void copyVariable(Variable &to, const Variable &from) const =0
Copy variable.
void setType(MinitScript::VariableType type)
Set type.
virtual ScriptContext * createScriptContext() const =0
Create script context.
virtual const string getValueAsString(const Variable &variable) const =0
Returns value as string.
virtual bool mul(MinitScript *minitScript, const span< MinitScript::Variable > &arguments, MinitScript::Variable &returnValue, const MinitScript::SubStatement &subStatement) const =0
Multiply.
virtual const string & getTypeAsString() const =0
MinitScript::VariableType getType() const
virtual bool div(MinitScript *minitScript, const span< MinitScript::Variable > &arguments, MinitScript::Variable &returnValue, const MinitScript::SubStatement &subStatement) const =0
Division.
virtual bool sub(MinitScript *minitScript, const span< MinitScript::Variable > &arguments, MinitScript::Variable &returnValue, const MinitScript::SubStatement &subStatement) const =0
Subtraction.
virtual void registerMethods(MinitScript *minitScript) const =0
Register methods.
virtual void unsetVariableValue(Variable &variable) const =0
Unset variable value.
virtual void registerConstants(MinitScript *minitScript) const =0
Register constants.
virtual void deleteScriptContext(ScriptContext *context) const =0
Delete script context.
MinitScript::VariableType type
virtual void garbageCollection(ScriptContext *context) const =0
Issue garbage collection.
virtual Operator getOperator() const
virtual const vector< string > & getContextFunctions()
virtual void executeMethod(span< Variable > &arguments, Variable &returnValue, const SubStatement &subStatement)=0
Execute method.
bool isReturnValueNullable() const
virtual bool isVariadic() const
const string getArgumentsInformation(int beginIdx=0) const
Get arguments information.
virtual bool isPrivate() const
const VariableType & getReturnValueType() const
virtual ~Method()
Destructor.
const vector< ArgumentType > & getArgumentTypes() const
virtual const string getMethodName()=0
VariableType returnValueType
vector< ArgumentType > argumentTypes
static MINITSCRIPT_STATIC_DLL_IMPEXT const vector< string > CONTEXTFUNCTIONS_ALL
vector< DataType * > & dataTypes
~ShutdownRAII()
Destructor.
ShutdownRAII(vector< DataType * > &dataTypes)
Constructor.
virtual ~StateMachineState()
Destructor.
virtual void execute()=0
Execute state machine state.
virtual const string getName()=0
const Statement & getStatement() const
Initializer()
Constructor.
Initializer(const string &initializerString, const Statement &statement, SyntaxTreeNode *syntaxTree)
Constructor.
const SyntaxTreeNode * getSyntaxTree() const
~Initializer()
Destructor.
void copy(Initializer *initializer)
Copy from initializer.
SyntaxTreeNode * syntaxTree
const string & getInitializerString() const
const _UTF8CharacterIterator::UTF8PositionCache & getCache() const
const string & getValue() const
void setValue(const string &value)
Set value.
StringValue(const string &value)
Constructor.
_UTF8CharacterIterator::UTF8PositionCache & getCache()
_UTF8CharacterIterator::UTF8PositionCache cache
StringValue()
Constructor.
void setCache(const _UTF8CharacterIterator::UTF8PositionCache &cache)
Set cache.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_NUMBER
static const string getReturnTypeAsString(VariableType type, bool nullable)
Returns given return value variable type string representation.
const vector< string > getMapKeys() const
Get map keys.
int64_t getMapSize() const
Get map size.
const string getReturnTypeAsString(bool nullable) const
Returns given return value variable type string representation.
static void copyVariable(Variable &to, const Variable &from, bool properties)
Copy variable.
StringValue & getStringValueReference()
bool isPrivateScope() const
const string getTypeAsString() const
void unsetConstant()
Unset constant.
InitializerReferenceUnion initializerReferenceUnion
unordered_set< string > * getSetPointer()
bool getIntegerValue(int64_t &value, bool optional=false) const
Get integer value from given variable.
static Variable * createReferenceVariablePointer(const Variable *variable)
Create reference variable pointer.
int64_t getByteArraySize() const
Get byte array size.
void setPrivate()
Set private.
void clearMap()
Clear array.
Variable & operator=(const Variable &variable)
Assignment operator.
static constexpr uint32_t CONSTANT_BIT_VALUE
void setImplicitTypedValueFromStringView(const string_view &value, MinitScript *minitScript, int scriptIdx, const Statement &statement)
Set implicit typed value given by value string.
const FunctionValue & getFunctionValueReference() const
void setValue(const string &value)
Set string value from given value into variable.
int64_t getSetSize() const
Get set size.
Variable(const vector< Variable * > &value)
Constructor.
static void swap(Variable &a, Variable &b)
Swap variables.
static Variable createNonReferenceVariable(const Variable *variable)
Create none reference variable.
void clearArray()
Clear array.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_SET
void setValue(const vector< uint8_t > &value)
Set array value from given value into variable.
static constexpr uint32_t TYPE_BITS_VALUE
void setValue(const vector< Variable * > &value)
Set array value from given value into variable.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_NULL
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_BYTEARRAY
void setConstant()
Set constant.
bool getStackletValue(string &stacklet, int &scriptIdx, bool optional=false) const
Get stacklet values from given variable.
const string getAsString() const
ByteArrayValue & getByteArrayValueReference()
Variable(float value)
Constructor.
VariableType getType() const
static Variable createMethodArgumentVariable(const Variable *variable)
Create variable optimized for method argument usage.
_UTF8CharacterIterator::UTF8PositionCache * getStringValueCache()
Get string value UTF8 position cache from given variable.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_ARRAY
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_FUNCTION
void setFunctionCallStatement(const string &initializerStatement, MinitScript *minitScript, int scriptIdx, const Statement &statement)
Set array/map values initializer function call statement.
bool getStringValue(string &value, bool optional=false) const
Get string value from given variable.
const StringValue & getStringValueReference() const
const Variable getArrayEntry(int64_t idx) const
Get entry from array with given index.
void setFunctionAssignment(const string &function, int scriptIdx=MinitScript::SCRIPTIDX_NONE)
Set function assignment from given value into variable.
void pushByteArrayEntry(uint8_t value)
Push entry to byte array.
bool hasMapEntry(const string &key) const
Map has entry with given key.
const unordered_map< string, Variable * > * getMapPointer() const
const vector< Variable * > getMapValues() const
Get map values.
void setValue(float value)
Set float value from given value into variable.
static constexpr uint32_t PRIVATE_BIT_VALUE
static const string & getTypeAsString(VariableType type)
Returns given variable type as string.
unordered_map< string, Variable * > & getMapValueReference()
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_STACKLET
const ByteArrayValue & getByteArrayValueReference() const
void setMapEntry(const string &key, const Variable &value, bool _private=false)
Set entry in map with given key.
Variable(Variable &&variable)
Move constructor.
const bool & getBooleanValueReference() const
void setValue(const void *value)
Set value for custom data types.
void * getValuePtr() const
const int64_t * getByteArrayReadPointer() const
Get const byte array read pointer.
int64_t & getIntegerValueReference()
void clearSet()
Clear set.
static Variable createNonConstVariable(const Variable *variable)
Create non const/reference variable.
void releaseReference()
Release reference.
static constexpr uint32_t PRIVATESCOPE_BIT_VALUE
vector< uint8_t > * getByteArrayPointer()
bool hasSetKey(const string &key) const
Set has given key.
bool getByteValue(MinitScript *minitScript, uint8_t &value, const Statement *statement=nullptr) const
Get byte value from given variable.
vector< Variable * > & getArrayValueReference()
uint64_t & getValuePtrReference()
Return value pointer.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_NONE
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_FLOAT
void insertSetKey(const string &key)
Insert given key in set.
Variable(const Variable &variable)
Copy constructor.
void pushArrayEntry(const Variable &value)
Push entry to array.
const Variable * getMapEntryPtr(const string &key) const
Get entry pointer from map with given key.
void setPrivateScope()
Set private scope.
static constexpr uint32_t REFERENCE_BIT_VALUE
static Variable * createNonReferenceVariablePointer(const Variable *variable)
Create none reference variable pointer.
unordered_map< string, Variable * > * getMapPointer()
vector< Variable * > * getArrayPointer()
const vector< string > getSetKeys() const
Get set keys.
void setValue(int64_t value)
Set integer value from given value into variable.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_MAP
void setStackletAssignment(const string &stacklet, int scriptIdx=MinitScript::SCRIPTIDX_NONE)
Set stacklet assignment from given value into variable.
const unordered_set< string > * getSetPointer() const
void setValue(const unordered_map< string, Variable * > &value)
Set map value from given value into variable.
unordered_set< string > & getSetValueReference()
const vector< Variable * > * getArrayPointer() const
bool getFloatValue(float &value, bool optional=false) const
Get float value from given variable.
bool getBooleanValue(bool &value, bool optional=false) const
Get boolean value from given variable.
void setValue(const unordered_set< string > &value)
Set set value from given value into variable.
bool & getBooleanValueReference()
float & getFloatValueReference()
void removeMapEntry(const string &key)
Remove entry in map with given key.
void setArrayEntry(int64_t idx, const Variable &value)
Set entry in array with given index.
void setValuePtr(void *valuePtr)
Set value pointer.
int64_t * getByteArrayWritePointer()
Get byte array write pointer.
const vector< uint8_t > * getByteArrayPointer() const
void clearByteArray()
Clear byte array.
int64_t getArraySize() const
Get array size.
void removeByteArray(int64_t idx, int64_t size)
Remove byte array entries at given index and size.
FunctionValue & getFunctionValueReference()
Variable(VariableType type, const string &value, int scriptIdx=SCRIPTIDX_NONE)
Constructor.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_STRING
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_INTEGER
static Variable createReferenceVariable(const Variable *variable)
Create reference variable.
const uint8_t getByteArrayEntry(int64_t idx) const
Get entry from byte array with given index.
static bool isExpectedType(VariableType type, VariableType expectedType)
Check if given variable type does match expected variable type.
const unordered_set< string > & getSetValueReference() const
const unordered_map< string, Variable * > & getMapValueReference() const
Initializer * getInitializer() const
Return initializer.
const int64_t & getIntegerValueReference() const
const string getValueAsString(bool formatted=false, bool jsonCompatible=false, int depth=0) const
Print string representation of variable.
Variable(const string &value)
Constructor.
void setReference(const Variable *variable)
Set reference.
void setType(VariableType newType)
Set type.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_MIXED
Variable(bool value)
Constructor.
void removeArrayEntry(int64_t idx)
Remove array entry at given index.
void setNullValue()
Set boolean value from given value into variable.
int64_t * getByteArrayReadPointer()
Get byte array read pointer.
void unset()
Unset variable.
void removeSetKey(const string &key)
Remove key in set with given key.
void setImplicitTypedValue(const string &value, MinitScript *minitScript, int scriptIdx, const Statement &statement)
Set implicit typed value given by value string.
void setByteArrayEntry(int64_t idx, uint8_t value)
Set entry in byte array with given index.
Variable(const unordered_map< string, Variable * > &value)
Constructor.
bool getFunctionValue(string &function, int &scriptIdx, bool optional=false) const
Get function values from given variable.
Variable(int64_t value)
Constructor.
Initializer *& getInitializerReference()
Return initializer.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string TYPENAME_BOOLEAN
const vector< Variable * > & getArrayValueReference() const
void setValue(const Variable &variable)
Set value from given variable into variable.
void setValue(bool value)
Set boolean value from given value into variable.
const uint64_t & getValuePtrReference() const
Return const value pointer.
void unsetPrivateScope()
Unset private scope.
const float & getFloatValueReference() const
Variable & operator=(Variable &&variable)
Move operator.
const Variable getMapEntry(const string &key) const
Get entry from map with given key.
const int64_t * getByteArrayWritePointer() const
Get const byte array write pointer.
void acquireReference()
Acquire reference.
static constexpr int SCRIPTIDX_NONE
unordered_set< int > garbageCollectionDataTypesIndices
static bool viewIsStringLiteral(const string_view &candidate)
Returns if a given string is a string literal.
static bool viewIsVariableAccess(const string_view &candidate)
Returns if a given string is a variable name.
const string & getScriptPathName()
static MINITSCRIPT_STATIC_DLL_IMPEXT const string METHOD_SCRIPTCALLSTACKLETBYINDEX
static MINITSCRIPT_STATIC_DLL_IMPEXT const string METHOD_SCRIPTCALLSTACKLET
static constexpr int ARRAYIDX_ADD
bool parseStatement(const string_view &executableStatement, string_view &methodName, vector< ParserArgument > &arguments, const Statement &statement, string &accessObjectMemberStatement)
Parse a statement.
bool callStacklet(const string &stacklet, span< Variable > &arguments, Variable &returnValue)
Call stacklet.
const string getArgumentsInformation(const string &methodName)
Get arguments information.
unordered_map< string, Method * > methods
const SubStatement & getErrorSubStatement()
static constexpr int STATE_NONE
SubStatement errorSubStatement
static constexpr int LINE_NONE
int getStatementSubLineIdx(const string &statement, int idx)
Get statement sub line index.
MathMethods * getMathMethods()
static constexpr int ARRAYIDX_FIRST
static const string_view viewGetPrivateKey(const string_view &candidate)
Returns private key.
void unsetVariable(const string &variableStatement, const SubStatement *subStatement=nullptr)
Unsets variable determined by given variable statement.
bool parseScriptInternal(const string &scriptCode, int lineIdxOffset=0)
Parse script code into this MinitScript instance.
static string_view dequote(const string_view &str)
Dequote a string.
static void initialize()
Initialize.
bool call(const string &function, span< Variable > &arguments, Variable &returnValue, bool pushScriptState)
Call function.
DataType::ScriptContext * getDataTypeScriptContext(VariableType type)
Return data type script context.
const vector< string > & getParseErrors()
virtual const string getBaseClassHeader()
virtual const string getBaseClass()
void registerMethod(Method *method)
Register method.
void setContext(_Context *context)
Set context.
void setLibrary(_Library *library)
Set library.
unordered_map< uint8_t, Method * > operators
bool call(int scriptIdx, span< Variable > &arguments, Variable &returnValue)
Call function.
static constexpr int SETACCESSBOOL_FALSE
void registerStateMachineState(StateMachineState *state)
Register state machine state.
static MINITSCRIPT_STATIC_DLL_IMPEXT vector< DataType * > dataTypes
int getFunctionScriptIdx(const string &function)
Return function script index by function name.
void setVariable(Variable *variablePtr, const string &variableStatement, const Variable &variable, const SubStatement *subStatement=nullptr, bool createReference=false)
Set variable by given variable pointer, variable statement and variable.
void setScriptStateState(int state)
Set script state machine state.
bool getObjectMemberAccess(const string_view &executableStatement, string_view &object, string_view &method, int &methodStartIdx, const Statement &statement)
Returns if statement has a object member access.
void popScriptState()
Pop script state.
static const Variable initializeArray(const string_view &initializerString, MinitScript *minitScript, int scriptIdx, const Statement &statement)
Initialize array by initializer string.
void gotoStatementGoto(const Statement &statement)
Go to statement goto from given statement.
virtual void startScript()
Start script.
bool validateStacklets(int scriptIdx)
Validate stacklets.
const string getStatementInformation(const Statement &statement, int subLineIdx=-1)
Return statement information.
unordered_map< VariableType, DataType::ScriptContext * > garbageCollectionScriptContextsByDataType
static constexpr int64_t TIME_NONE
bool call(int scriptIdx, span< Variable > &arguments, Variable &returnValue, bool pushScriptState)
Call function.
void stopScriptExecution()
Stop script execution.
void resetStackletScriptExecutationState(int scriptIdx, StateMachineStateId stateMachineState)
Reset stacklet script execution state.
static bool getBooleanValue(const span< Variable > &arguments, int idx, bool &value, bool optional=false)
Get boolean value from given variable.
static void setConstant(Variable &variable)
Set variable recursively to be a constant.
Variable * getVariableIntern(const string &variableStatement, const string &callerMethod, string &variableName, Variable *&parentVariable, int64_t &arrayIdx, string &key, int &setAccessBool, const SubStatement *subStatement=nullptr, bool expectVariable=true, bool global=false)
Returns pointer of variable with given name or nullptr.
MinitScript()
Default constructor.
static bool viewIsKeyPrivate(const string_view &candidate)
Returns if a given key candidate is marked as private by head '-'.
static bool viewIsLamdaFunction(const string_view &candidate, vector< string_view > &arguments, string_view &functionScriptCode, int &lineIdx)
Returns if a given string is a lambda function.
void pushScriptState()
Push a new script state.
static bool getFloatValue(const span< Variable > &arguments, int idx, float &value, bool optional=false)
Get float value from given variable.
static bool isOperator(const string &candidate)
Is given candidate a operator string.
static bool viewIsStacklet(const string_view &candidate, vector< string_view > &arguments, string_view &stackletScriptCode, int &lineIdx)
Returns if a given string is a stacklet.
virtual void execute()
Execute.
static constexpr int64_t GARBAGE_COLLECTION_INTERVAL
bool validateCallable(const string &function)
Validate callabe.
const string doStatementPreProcessing(const string &processedStatement, const Statement &statement)
Do statement pre processing, 1) replace operators with corresponding methods.
ScriptState & getRootScriptState()
bool hasFunction(const string &functionName)
Returns if function with given name does exist.
static MINITSCRIPT_STATIC_DLL_IMPEXT ShutdownRAII shutdownRAII
bool callStacklet(int scriptIdx, span< Variable > &arguments, Variable &returnValue)
Call stacklet.
void tryGarbageCollection()
Try garbage collection.
void parseScript(const string &pathName, const string &fileName, bool nativeOnly=false)
Parse script.
virtual void registerStateMachineStates()
Register state machine states.
virtual void initializeNative()
Initialize native mini script.
static constexpr bool VALIDATION
void complain(const string &methodName, const SubStatement &subStatement)
Complain about method usage.
virtual ~MinitScript()
Destructor.
static string getOperatorAsString(Operator operator_)
Get operator as string.
static constexpr int STATEMENTIDX_FIRST
virtual void registerVariables()
Register variables.
bool call(const string &function, span< Variable > &arguments, Variable &returnValue)
Call function.
@ OPERATOR_PREFIX_DECREMENT
@ OPERATOR_PREFIX_INCREMENT
@ OPERATOR_POSTFIX_INCREMENT
@ OPERATOR_POSTFIX_DECREMENT
@ OPERATOR_MULTIPLICATION
vector< pair< int, string > > deferredInlineScriptCodes
void setNativeHash(const string &nativeHash)
Set native hash.
static constexpr bool VERBOSE
bool hasVariable(const string &variableStatement, const SubStatement *subStatement=nullptr)
Returns if variable determined by given variable statement exists.
void setNativeFunctions(const unordered_map< string, int > &nativeFunctions)
Set native functions.
static const vector< DataType * > & getDataTypes()
const string & getNativeHash()
void createLamdaFunction(Variable &variable, const vector< string_view > &arguments, const string_view &functionScriptCode, int lineIdx, bool populateThis, const Statement &statement, const string &nameHint=string())
const Variable getMethodArgumentVariable(const string &variableStatement, const SubStatement *subStatement=nullptr)
Returns variable determined by given variable statement optimized for method argument usage.
vector< GarbageCollectionDataType > garbageCollectionDataTypes
virtual void registerMethods()
Register methods.
bool evaluateAccess(const string &variableStatement, const string &callerMethod, string::size_type &arrayAccessOperatorLeftIdx, string::size_type &arrayAccessOperatorRightIdx, int64_t &arrayIdx, string &key, const SubStatement *subStatement=nullptr)
Evaluate access.
virtual void emit(const string &condition)
Emit.
static constexpr int ARRAYIDX_NONE
static bool getStringValue(const span< Variable > &arguments, int idx, string &value, bool optional=false)
Get string value from given variable.
const Variable getVariable(Variable *variablePtr, const string &variableStatement, const SubStatement *subStatement=nullptr, bool createReference=false)
Returns variable determined by given variable statement and variable pointer.
bool getNextStatement(const string &scriptCode, int &i, int &line, string &statement)
Get next statement from script code.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string METHOD_SCRIPTCALLBYINDEX
int getStackletScopeScriptIdx(int scriptIdx)
Return stacklet scope script index.
static constexpr int OPERATORIDX_NONE
static const bool isOperatorChar(char c)
Returns if char is operator char.
const string & getErrorMessage()
static void registerDataType(DataType *dataType)
Register data type.
bool getVariableAccessOperatorLeftRightIndices(const string &variableStatement, const string &callerMethod, string::size_type &accessOperatorLeftIdx, string::size_type &accessOperatorRightIdx, const SubStatement *subStatement=nullptr, int startIdx=0)
Get access operator left and right indices.
const string getSubStatementInformation(const SubStatement &subStatement)
Return sub statement information.
static const string getArgumentIndicesAsString(const vector< int > &argumentIndices, const string &delimiter)
Returns string representation of given argument indices.
static const Variable initializeMapSet(const string_view &initializerString, MinitScript *minitScript, int scriptIdx, const Statement &statement)
Initialize map/set by initializer string.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string OPERATOR_CHARS
void garbageCollection()
Issue garbage collection.
static void setConstantInternal(Variable &variable)
Set variable recursively to be a constant.
bool hasCondition(const string &condition)
Check if condition with given name exists.
Method * getOperatorMethod(Operator operator_)
Get method by operator.
vector< string > enabledNamedConditions
void setNative(bool native)
Set native.
const string & getScriptFileName()
void setNativeScripts(const vector< Script > &nativeScripts)
Set native scripts.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string METHOD_DISABLENAMEDCONDITION
Variable * evaluateVariableAccessIntern(Variable *variablePtr, const string &variableStatement, const string &callerMethod, Variable *&parentVariable, int64_t &arrayIdx, string &key, int &setAccessBool, const SubStatement *subStatement=nullptr, bool expectVariable=true)
Returns pointer of variable with given name or nullptr.
void unsetVariable(Variable *variablePtr, const string &variableStatement, const SubStatement *subStatement=nullptr)
Unsets variable determined by given variable statement and variable pointer.
static bool viewIsKey(const string_view &candidate)
Returns if a given string is a valid map key name.
const Variable getMethodArgumentVariable(Variable *variablePtr, const string &variableStatement, const SubStatement *subStatement=nullptr)
Returns variable determined by given variable statement and variable pointer optimized for method arg...
int64_t timeEnabledConditionsCheckLast
void dumpScriptState(ScriptState &scriptState, const string &message=string())
Dump script state.
bool hasMethod(const string &methodName)
Returns if method with given name does exist.
virtual const vector< string > getTranspilationUnits()
unordered_map< string, int > functions
static const string escapeString(const string &str)
Escape string variable.
const string getInformation()
Get MinitScript instance information.
const Variable getVariable(const string &variableStatement, const SubStatement *subStatement=nullptr, bool createReference=false)
Returns variable determined by given variable statement.
static constexpr int ARGUMENTIDX_NONE
vector< Script > getNativeScripts()
static bool viewIsInitializer(const string_view &candidate)
Returns if a given string is a array/map/set initializer.
Method * getMethod(const string &methodName)
Get method by method name.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string METHOD_SCRIPTCALL
unique_ptr< MathMethods > minitScriptMath
void gotoStatement(const Statement &statement)
Go to statement.
unordered_map< int, StateMachineState * > stateMachineStates
vector< string > parseErrors
const string getArgumentsAsString(const vector< SyntaxTreeNode > &arguments)
Returns arguments as string.
void createStacklet(Variable &variable, const string &scopeName, const vector< string_view > &arguments, const string_view &stackletScriptCode, int lineIdx, const Statement &statement)
const vector< Method * > getMethods()
void stopRunning()
Set running flag to false.
@ TYPE_STACKLET_ASSIGNMENT
@ TYPE_PSEUDO_CUSTOM_DATATYPES
@ TYPE_HTTPDOWNLOADCLIENT
@ TYPE_FUNCTION_ASSIGNMENT
const string getScriptInformation(int scriptIdx, bool includeStatements=true)
Get script information for a specific script index.
bool isVariableAccess(const string &candidate, const SubStatement *subStatement=nullptr)
Returns if a given string is a variable name.
bool evaluateInternal(const string &statement, const string &executableStatement, Variable &returnValue, bool pushScriptState=true)
Evaluate given statement without executing preprocessor run.
void setVariable(const string &variableStatement, const Variable &variable, const SubStatement *subStatement=nullptr, bool createReference=false)
Set variable by given variable statement and variable.
static bool getFunctionValue(const span< Variable > &arguments, int idx, string &function, int &scriptIdx, bool optional=false)
Get function value from given variable.
void startErrorScript()
Start error script.
static DataType * getDataTypeByClassName(const string &className)
Returns data type by class name or nullptr.
bool validateContextFunctions(const string &function, vector< string > &functionStack)
Validate context functions.
void executeStateMachine()
Execute state machine.
const vector< Method * > getOperatorMethods()
static bool hasType(const span< Variable > &arguments, VariableType type)
Check if arguments contain argument with given type.
static void unsetConstant(Variable &variable)
Set variable recursively to be a non constant.
vector< Script > nativeScripts
static const string decodeOperator(const span< MinitScript::Variable > &arguments, int operatorValueIdx, const string &defaultOperatorString)
Decode operator.
static void unsetConstantInternal(Variable &variable)
Set variable recursively to be a non constant.
void complainOperator(const string &methodName, const string &operatorString, const SubStatement &subStatement)
Complain about operator usage.
void resetScriptExecutationState(int scriptIdx, StateMachineStateId stateMachineState)
Reset script execution state.
void setVariableInternal(const string &variableStatement, Variable *parentVariable, Variable *variablePtr, int64_t arrayIdx, const string &key, const Variable &variable, const SubStatement *subStatement=nullptr, bool createReference=false)
Set variable internal.
ScriptState & getScriptState()
static bool getStackletValue(const span< Variable > &arguments, int idx, string &stacklet, int &scriptIdx, bool optional=false)
Get stacklet value from given variable.
bool setupFunctionAndStackletScriptIndices(int scriptIdx)
Setup function and stacket script indices.
static bool viewIsCall(const string_view &candidate)
Returns if a given string is a method/function call.
static constexpr int SETACCESSBOOL_TRUE
virtual int determineNamedScriptIdxToStart()
Determine named script index to start.
@ STATEMACHINESTATE_NEXT_STATEMENT
@ STATEMACHINESTATE_WAIT_FOR_CONDITION
const vector< Script > & getScripts()
const Variable initializeVariable(const Variable &variable)
Initialize variable.
static constexpr int STATEMENTIDX_NONE
Variable executeStatement(const SyntaxTreeNode &syntaxTree, const Statement &statement)
Execute a statement.
bool createStatementSyntaxTree(int scriptIdx, const string_view &methodName, const vector< ParserArgument > &arguments, const Statement &statement, SyntaxTreeNode &syntaxTree, int subLineIdx=0)
Create statement syntax tree.
static constexpr int LINE_FIRST
void setConstant(const string &variableStatement, const Variable &variable)
Set constant by given variable statement and variable.
vector< unique_ptr< ScriptState > > scriptStateStack
static bool hasTypeForOperatorArguments(const span< Variable > &arguments, VariableType type)
Checks if left and right operator arguments have given type.
static bool getIntegerValue(const span< Variable > &arguments, int idx, int64_t &value, bool optional=false)
Get integer value from given variable.
const string deescape(const string_view &str, const Statement &statement)
Deescape string.
virtual int determineScriptIdxToStart()
Determine script index to start.
bool evaluate(const string &evaluateStatement, Variable &returnValue)
Evaluate statement.
static MINITSCRIPT_STATIC_DLL_IMPEXT const string METHOD_ENABLENAMEDCONDITION
static constexpr int SETACCESSBOOL_NONE
void executeNextStatement()
Execute next statement.
MinitScript script script methods.
static bool isSpace(uint32_t character)
Returns if character is a white space.
static void appendToString(string &string, uint32_t character)
Appends a character / code point to given string.
static bool isAlphaNumeric(uint32_t character)
Returns if character is alpha numeric.
static void printLine()
Print newline to console.
static bool viewIs(const string_view &str)
Check if given string is a float string.
static float viewParse(const string_view &str)
Parse float.
static float parse(const string &str)
Parse float.
static bool is(const string &str)
Check if given string is a float string.
Integer to hex string conversion utility class.
static uint64_t decodeInt(const string &encodedString)
Decodes a hex string representation to an 64 bit unsigned integer.
static bool viewIs(const string_view &str)
Check if given string is a integer string.
static int parse(const string &str)
Parse integer.
static int viewParse(const string_view &str)
Parse integer.
static bool is(const string &str)
Check if given string is a integer string.
static int64_t getCurrentMillis()
Retrieve current time in milliseconds.
void removeCache()
Remove cache.
UTF8 string character iterator.
#define MINITSCRIPT_STATIC_DLL_IMPEXT
#define _FORBID_CLASS_COPY(CLASS)
std::exception Exception
Exception base class.
Garbage collection data type.
GarbageCollectionDataType(DataType *dataType, DataType::ScriptContext *context)
Constructor.
DataType::ScriptContext * context
ParserArgument(const string_view &argument, int subLineIdx)
Constructor.
Block(Type type, bool match, const Statement *continueStatement, const Statement *breakStatement, const Variable ¶meter)
Constructor.
const Statement * breakStatement
const Statement * continueStatement
unordered_map< string, Variable * > variables
vector< Block > blockStack
unordered_map< int, int64_t > forTimeStarted
StateMachineState * lastStateMachineState
Argument(const string &name, bool reference, bool privateScope)
Constructor.
vector< SyntaxTreeNode > syntaxTree
SyntaxTreeNode conditionSyntaxTree
Script(Type type, int line, const string &condition, const string &executableCondition, Statement conditionStatement, SyntaxTreeNode conditionSyntaxTree, const string &name, bool emitCondition, const vector< Statement > &statements, const vector< SyntaxTreeNode > &syntaxTree, bool callable, const vector< Argument > &arguments)
Constructor.
vector< Statement > statements
string executableCondition
vector< Argument > arguments
Statement conditionStatement
string executableStatement
Statement(int line, int statementIdx, const string &statement, const string &executableStatement, int gotoStatementIdx)
Constructor.
const Statement * statement
SubStatement()
Sub statement.
SubStatement(const Statement &statement, int subLineIdx)
Sub statement.
Method * getMethod() const
vector< SyntaxTreeNode > arguments
void setMethod(Method *method)
Set method.
@ SCRIPTSYNTAXTREENODE_NONE
@ SCRIPTSYNTAXTREENODE_EXECUTE_STACKLET
@ SCRIPTSYNTAXTREENODE_EXECUTE_FUNCTION
@ SCRIPTSYNTAXTREENODE_EXECUTE_METHOD
@ SCRIPTSYNTAXTREENODE_LITERAL
SyntaxTreeNode(Type type, const Variable &value, uint64_t scriptIdx, const vector< SyntaxTreeNode > &arguments, int subLineIdx)
Constructor.
int64_t getScriptIdx() const
void setScriptIdx(uint64_t scriptIdx)
Set function/stacklet script index.
SyntaxTreeNode(Type type, const Variable &value, Method *method, const vector< SyntaxTreeNode > &arguments, int subLineIdx)
Constructor.
SyntaxTreeNode()
Constructor.
Initializer * initializer