8#include <unordered_map>
9#include <unordered_set>
38using std::string_view;
40using std::unordered_map;
41using std::unordered_set;
63string MiniScript::OPERATOR_CHARS =
"!*/%+-<>&|=";
65MiniScript::MiniScript() {
70 for (
auto& scriptMethodIt:
scriptMethods)
delete scriptMethodIt.second;
99 if (script.statements.empty() ==
true)
return;
111 vector<string_view> arguments;
115 Console::println(
"MiniScript::executeScriptLine(): '" +
scriptFileName +
"': @" + to_string(statement.line) +
": '" + statement.statement +
"': parse error");
122 auto bracketCount = 0;
124 auto methodStart = string::npos;
125 auto methodEnd = string::npos;
126 auto argumentStart = string::npos;
127 auto argumentEnd = string::npos;
128 auto quotedArgumentStart = string::npos;
129 auto quotedArgumentEnd = string::npos;
130 for (
auto i = 0; i < statement.size(); i++) {
131 auto c = statement[i];
133 if (bracketCount == 1) {
134 if (quote ==
false) {
135 quotedArgumentStart = i;
137 quotedArgumentEnd = i;
140 if (quote ==
false) {
141 if (argumentStart == string::npos) {
148 quote = quote ==
false?
true:
false;
151 if (bracketCount == 1) {
152 quotedArgumentEnd = i;
154 if (argumentStart == string::npos) {
161 if (quote ==
false) {
164 if (bracketCount > 1) {
165 if (argumentStart == string::npos) {
166 argumentStart = i + 1;
174 if (bracketCount == 0) {
175 if (quotedArgumentStart != string::npos) {
176 if (quotedArgumentEnd == string::npos) quotedArgumentEnd = i - 1;
177 auto argumentLength = quotedArgumentEnd - quotedArgumentStart + 1;
178 if (argumentLength > 0) arguments.push_back(
StringTools::viewTrim(string_view(&statement[quotedArgumentStart], argumentLength)));
179 quotedArgumentStart = string::npos;
180 quotedArgumentEnd = string::npos;
182 if (argumentStart != string::npos) {
183 if (argumentEnd == string::npos) argumentEnd = i - 1;
184 auto argumentLength = argumentEnd - argumentStart + 1;
185 if (argumentLength > 0) arguments.push_back(
StringTools::viewTrim(string_view(&statement[argumentStart], argumentLength)));
186 argumentStart = string::npos;
187 argumentEnd = string::npos;
190 if (argumentStart == string::npos) {
191 argumentStart = i + 1;
198 if (bracketCount == 1) {
199 if (quotedArgumentStart != string::npos) {
200 if (quotedArgumentEnd == string::npos) quotedArgumentEnd = i - 1;
201 auto argumentLength = quotedArgumentEnd - quotedArgumentStart + 1;
202 if (argumentLength > 0) arguments.push_back(
StringTools::viewTrim(string_view(&statement[quotedArgumentStart], argumentLength)));
203 quotedArgumentStart = string::npos;
204 quotedArgumentEnd = string::npos;
206 if (argumentStart != string::npos) {
207 if (argumentEnd == string::npos) argumentEnd = i - 1;
208 auto argumentLength = argumentEnd - argumentStart + 1;
209 if (argumentLength > 0) arguments.push_back(
StringTools::viewTrim(string_view(&statement[argumentStart], argumentEnd - argumentStart + 1)));
210 argumentStart = string::npos;
211 argumentEnd = string::npos;
214 if (argumentStart == string::npos) {
215 argumentStart = i + 1;
221 if (bracketCount == 0) {
222 if (methodStart == string::npos) methodStart = i;
else methodEnd = i;
224 if (argumentStart == string::npos) {
234 if (methodStart != string::npos && methodEnd != string::npos) {
240 for (
auto& argument: arguments) {
247 if (bracketCount > 0) {
248 Console::println(
"MiniScript::parseScriptStatement(): '" +
scriptFileName +
"': '" +
string(statement) +
"': unbalanced bracket count: " + to_string(bracketCount) +
" still open");
256 vector<ScriptVariable> argumentValues;
259 for (
auto& argument: arguments) {
260 if (argument.empty() ==
false &&
263 argument.find(
'(') != string::npos &&
264 argument.find(
')') != string::npos) {
266 string_view subMethod;
267 vector<string_view> subArguments;
270 argumentValues.push_back(argumentValue);
272 Console::println(
"MiniScript::executeScriptStatement(): parseScriptStatement(): '" +
scriptFileName +
"': @" + to_string(statement.
line) +
": '" + statement.
statement +
"': '" +
string(argument) +
"': parse error");
280 Console::println(
"MiniScript::executeScriptStatement(): '" +
scriptFileName +
"': @" + to_string(statement.
line) +
": '" + statement.
statement +
"': " +
string(method) +
"(" +
string(argument) +
"): variable: '" +
string(argument) +
"' does not exist");
283 auto argumentValue = *variableIt->second;
284 argumentValues.push_back(argumentValue);
295 argumentValues.push_back(argumentValue);
299 string argumentValuesString;
300 for (
auto& argumentValue: argumentValues) argumentValuesString+= (argumentValuesString.empty() ==
false?
",":
"") + argumentValue.getAsString();
305 auto scriptMethod = scriptMethodsIt->second;
306 auto argumentIdx = 0;
307 if (scriptMethod->isVariadic() ==
false) {
308 for (
auto& argumentType: scriptMethod->getArgumentTypes()) {
309 auto argumentOk =
true;
310 switch(argumentType.type) {
316 argumentOk =
getBooleanValue(argumentValues, argumentIdx, booleanValue, argumentType.optional);
321 int64_t integerValue;
322 argumentOk =
getIntegerValue(argumentValues, argumentIdx, integerValue, argumentType.optional);
328 argumentOk =
getFloatValue(argumentValues, argumentIdx, floatValue, argumentType.optional);
334 argumentOk =
getStringValue(argumentValues, argumentIdx, stringValue, argumentType.optional);
340 argumentOk =
getVector3Value(argumentValues, argumentIdx, vector3Value, argumentType.optional);
346 argumentOk =
getTransformationsValue(argumentValues, argumentIdx, transformationsValue, argumentType.optional);
350 if (argumentOk ==
false) {
352 string(
"MiniScript::executeScriptStatement(): ") +
354 "@" + to_string(statement.
line) +
356 ": method '" +
string(method) +
"'" +
357 ": argument value @ " + to_string(argumentIdx) +
": expected " +
ScriptVariable::getTypeAsString(argumentType.type) +
", but got: " + (argumentIdx < argumentValues.size()?argumentValues[argumentIdx].getAsString():
"nothing"));
361 if (argumentValues.size() > scriptMethod->getArgumentTypes().size()) {
363 string(
"MiniScript::executeScriptStatement(): ") +
365 "@" + to_string(statement.
line) +
367 ": method '" +
string(method) +
"'" +
368 ": too many arguments: expected: " + to_string(scriptMethod->getArgumentTypes().size()) +
", got " + to_string(argumentValues.size()));
371 scriptMethod->executeMethod(argumentValues, returnValue, statement);
372 if (scriptMethod->isMixedReturnValue() ==
false && returnValue.
getType() != scriptMethod->getReturnValueType()) {
374 string(
"MiniScript::executeScriptStatement(): ") +
376 "@" + to_string(statement.
line) +
378 ": method '" +
string(method) +
"'" +
391 auto scriptIdxToStart = 0;
393 auto conditionMet =
true;
394 if (script.name.empty() ==
false && script.name == condition) {
397 if (script.condition == condition) {
403 if (scriptIdxToStart ==
scripts.size()) {
404 scriptIdxToStart = -1;
417 while (
true ==
true) {
488 for (
auto& scriptMethodIt:
scriptMethods)
delete scriptMethodIt.second;
502 vector<string> scriptLines;
504 FileSystem::getInstance()->getContentAsStringArray(pathName, fileName, scriptLines);
506 Console::println(
"MiniScript::loadScript(): " + pathName +
"/" + fileName +
": an error occurred: " + fse.what());
511 string scriptAsString;
512 for (
auto& scriptLine: scriptLines) scriptAsString+= scriptLine +
"\n";
515 if (scriptHash ==
hash) {
521 Console::println(
"MiniScript::loadScript(): " + pathName +
"/" + fileName +
": Script has changed. Script will be run in interpreted mode. Retranspile and recompile your script if you want to run it natively.");
533 auto haveCondition =
false;
535 auto statementIdx = 1;
536 enum GotoStatementType { GOTOSTATEMENTTYPE_FOR, GOTOSTATEMENTTYPE_IF, GOTOSTATEMENTTYPE_ELSE, GOTOSTATEMENTTYPE_ELSEIF };
537 struct GotoStatementStruct {
538 GotoStatementType type;
541 stack<GotoStatementStruct> gotoStatementStack;
542 for (
auto scriptLine: scriptLines) {
548 if (haveCondition ==
false) {
550 haveCondition =
true;
557 auto scriptLineNameSeparatorIdx = scriptLine.rfind(
":=");
558 if (scriptLineNameSeparatorIdx != string::npos) {
567 .conditionType = conditionType,
569 .condition = condition,
571 .emitCondition = emitCondition,
576 Console::println(
"MiniScript::MiniScript(): '" +
scriptFileName +
"': @" + to_string(line) +
": expecting 'on:' or 'on-enabled:' script condition");
584 if (scriptLine ==
"end") {
585 if (gotoStatementStack.empty() ==
false) {
586 auto gotoStatementStackElement = gotoStatementStack.top();
587 gotoStatementStack.pop();
588 switch(gotoStatementStackElement.type) {
589 case GOTOSTATEMENTTYPE_FOR:
591 scripts[
scripts.size() - 1].statements.push_back({ .line = line, .statementIdx = statementIdx, .statement = scriptLine, .gotoStatementIdx = gotoStatementStackElement.statementIdx });
592 scripts[
scripts.size() - 1].statements[gotoStatementStackElement.statementIdx].gotoStatementIdx =
scripts[
scripts.size() - 1].statements.size();
595 case GOTOSTATEMENTTYPE_IF:
597 scripts[
scripts.size() - 1].statements[gotoStatementStackElement.statementIdx].gotoStatementIdx =
scripts[
scripts.size() - 1].statements.size();
598 scripts[
scripts.size() - 1].statements.push_back({ .line = line, .statementIdx = statementIdx, .statement = scriptLine, .gotoStatementIdx = -1 });
601 case GOTOSTATEMENTTYPE_ELSE:
603 scripts[
scripts.size() - 1].statements[gotoStatementStackElement.statementIdx].gotoStatementIdx =
scripts[
scripts.size() - 1].statements.size();
604 scripts[
scripts.size() - 1].statements.push_back({ .line = line, .statementIdx = statementIdx, .statement = scriptLine, .gotoStatementIdx = -1 });
607 case GOTOSTATEMENTTYPE_ELSEIF:
609 scripts[
scripts.size() - 1].statements[gotoStatementStackElement.statementIdx].gotoStatementIdx =
scripts[
scripts.size() - 1].statements.size();
610 scripts[
scripts.size() - 1].statements.push_back({ .line = line, .statementIdx = statementIdx, .statement = scriptLine, .gotoStatementIdx = -1 });
615 scripts[
scripts.size() - 1].statements.push_back({ .line = line, .statementIdx = statementIdx, .statement =
"end", .gotoStatementIdx = -1 });
616 haveCondition =
false;
619 if (scriptLine ==
"else") {
620 if (gotoStatementStack.empty() ==
false) {
621 auto gotoStatementStackElement = gotoStatementStack.top();
622 gotoStatementStack.pop();
623 switch(gotoStatementStackElement.type) {
624 case GOTOSTATEMENTTYPE_IF:
626 scripts[
scripts.size() - 1].statements[gotoStatementStackElement.statementIdx].gotoStatementIdx =
scripts[
scripts.size() - 1].statements.size();
627 scripts[
scripts.size() - 1].statements.push_back({ .line = line, .statementIdx = statementIdx, .statement = scriptLine, .gotoStatementIdx = -1 });
630 case GOTOSTATEMENTTYPE_ELSEIF:
632 scripts[
scripts.size() - 1].statements[gotoStatementStackElement.statementIdx].gotoStatementIdx =
scripts[
scripts.size() - 1].statements.size();
633 scripts[
scripts.size() - 1].statements.push_back({ .line = line, .statementIdx = statementIdx, .statement = scriptLine, .gotoStatementIdx = -1 });
641 gotoStatementStack.push(
643 .type = GOTOSTATEMENTTYPE_ELSE,
644 .statementIdx = statementIdx
654 if (gotoStatementStack.empty() ==
false) {
655 auto gotoStatementStackElement = gotoStatementStack.top();
656 gotoStatementStack.pop();
657 switch(gotoStatementStackElement.type) {
658 case GOTOSTATEMENTTYPE_IF:
660 scripts[
scripts.size() - 1].statements[gotoStatementStackElement.statementIdx].gotoStatementIdx =
scripts[
scripts.size() - 1].statements.size();
661 scripts[
scripts.size() - 1].statements.push_back({ .line = line, .statementIdx = statementIdx, .statement = scriptLine, .gotoStatementIdx = -1 });
664 case GOTOSTATEMENTTYPE_ELSEIF:
666 scripts[
scripts.size() - 1].statements[gotoStatementStackElement.statementIdx].gotoStatementIdx =
scripts[
scripts.size() - 1].statements.size();
667 scripts[
scripts.size() - 1].statements.push_back({ .line = line, .statementIdx = statementIdx, .statement = scriptLine, .gotoStatementIdx = -1 });
675 gotoStatementStack.push(
677 .type = GOTOSTATEMENTTYPE_ELSEIF,
678 .statementIdx = statementIdx
688 gotoStatementStack.push(
690 .type = GOTOSTATEMENTTYPE_FOR,
691 .statementIdx = statementIdx
696 gotoStatementStack.push(
698 .type = GOTOSTATEMENTTYPE_IF,
699 .statementIdx = statementIdx
703 scripts[
scripts.size() - 1].statements.push_back({ .line = line, .statementIdx = statementIdx, .statement = scriptLine, .gotoStatementIdx = -1 });
711 if (
scriptValid ==
true && gotoStatementStack.empty() ==
false) {
719 auto haveInitializeScript =
false;
720 auto haveErrorScript =
false;
725 if (script.condition ==
"initialize") {
726 haveInitializeScript =
true;
728 if (script.condition ==
"error") {
729 haveErrorScript =
true;
732 if (haveInitializeScript ==
false || haveErrorScript ==
false) {
759 auto nothingScriptIdx = -1;
765 if (script.emitCondition ==
true && script.condition ==
"nothing") {
766 nothingScriptIdx = scriptIdx;
769 if (script.emitCondition ==
true) {
772 auto conditionMet =
true;
773 auto& condition = script.condition;
775 vector<string_view> arguments;
783 .statement = condition,
784 .gotoStatementIdx = -1
787 auto returnValueBoolValue =
false;
788 if (returnValue.getBooleanValue(returnValueBoolValue,
false) ==
false) {
789 Console::println(
"MiniScript::determineScriptIdxToStart(): '" + condition +
"': expecting boolean return value, but got: " + returnValue.getAsString());
790 conditionMet =
false;
792 if (returnValueBoolValue ==
false) {
793 conditionMet =
false;
796 Console::println(
"MiniScript::determineScriptIdxToStart(): '" +
scriptFileName +
"': @" + to_string(script.line) +
": '" + condition +
"': parse error");
798 if (conditionMet ==
false) {
800 Console::print(
"MiniScript::determineScriptIdxToStart(): " + condition +
": FAILED");
804 Console::print(
"MiniScript::determineScriptIdxToStart(): " + condition +
": OK");
813 return nothingScriptIdx;
824 script.name != enabledConditionName) {
827 auto conditionMet =
true;
828 auto& condition = script.condition;
830 vector<string_view> arguments;
838 .statement = condition,
839 .gotoStatementIdx = -1
842 auto returnValueBoolValue =
false;
843 if (returnValue.getBooleanValue(returnValueBoolValue,
false) ==
false) {
844 Console::println(
"MiniScript::determineNamedScriptIdxToStart(): '" + condition +
"': expecting boolean return value, but got: " + returnValue.getAsString());
845 conditionMet =
false;
847 if (returnValueBoolValue ==
false) {
848 conditionMet =
false;
851 Console::println(
"MiniScript::determineNamedScriptIdxToStart(): '" +
scriptFileName +
"': @" + to_string(script.line) +
": '" + condition +
"': parse error");
853 if (conditionMet ==
false) {
855 Console::print(
"MiniScript::determineNamedScriptIdxToStart(): " + condition +
": FAILED");
859 Console::print(
"MiniScript::determineNamedScriptIdxToStart(): " + condition +
": OK");
874 auto bracketCount = 0;
876 for (
auto i = 0; i < statement.size(); i++) {
877 auto c = statement[i];
879 quote = quote ==
false?
true:
false;
881 if (quote ==
false) {
890 string operatorCandidate;
892 if (operatorString.size() == 1) operatorCandidate+= statement[i];
893 if (operatorString.size() == 2 && i + 1 < statement.size()) {
894 operatorCandidate+= statement[i];
895 operatorCandidate+= statement[i + 1];
897 if (operatorString == operatorCandidate && (nextOperator.
idx == -1 || priorizedOperator > nextOperator.
scriptOperator)) {
901 if (operatorString.size() == 2 && i + 2 < statement.size() &&
isOperatorChar(statement[i + 2]) ==
true) {
904 if (operatorString.size() == 1 && i + 1 < statement.size() &&
isOperatorChar(statement[i + 1]) ==
true) {
908 auto leftArgumentLeft = 0;
910 if (leftArgument.length() == 0)
continue;
912 nextOperator.
idx = i;
921 if (bracketCount > 0) {
922 Console::println(
"MiniScript::getNextStatementOperator(): '" +
scriptFileName +
"': '" + statement +
"': unbalanced bracket count: " + to_string(bracketCount) +
" still open");
926 return nextOperator.
idx != -1;
934 return processedArgument;
939 auto bracketCount = 0;
943 for (
auto i = position; i < statement.size(); i++) {
944 auto c = statement[i];
946 quote = quote ==
false?
true:
false;
949 if (quote ==
false) {
976 auto bracketCount = 0;
980 for (
int i = position; i >= 0; i--) {
981 auto c = statement[i];
983 quote = quote ==
false?
true:
false;
984 argument = c + argument;
986 if (quote ==
false) {
989 argument = c + argument;
994 argument = c + argument;
998 argument = c + argument;
1000 argument = c + argument;
1003 if (quote ==
true) {
1004 argument = c + argument;
1012 auto preprocessedStatement = statement;
1017 Console::println(
"MiniScript::doStatementPreProcessing(): operator found in: '" + preprocessedStatement +
"'@" + to_string(nextOperators.
idx) +
": no method found");
1019 return preprocessedStatement;
1021 auto method = methodIt->second;
1022 if (method->getArgumentTypes().size() == 1) {
1025 int rightArgumentLength = 0;
1026 auto rightArgument =
findRightArgument(preprocessedStatement, nextOperators.
idx + operatorString.size(), rightArgumentLength);
1028 preprocessedStatement =
1030 method->getMethodName() +
"(" + rightArgument +
")" +
1031 StringTools::substring(preprocessedStatement, nextOperators.
idx + operatorString.size() + rightArgumentLength, preprocessedStatement.size());
1033 if (method->isVariadic() ==
true ||
1034 method->getArgumentTypes().size() == 2) {
1037 int leftArgumentLength = 0;
1038 auto leftArgument =
findLeftArgument(preprocessedStatement, nextOperators.
idx - 1, leftArgumentLength);
1040 int rightArgumentLength = 0;
1041 auto rightArgument =
findRightArgument(preprocessedStatement, nextOperators.
idx + operatorString.size(), rightArgumentLength);
1044 leftArgument =
"\"" + leftArgument +
"\"";
1047 preprocessedStatement =
1049 method->getMethodName() +
"(" + leftArgument +
", " + rightArgument +
")" +
1050 StringTools::substring(preprocessedStatement, nextOperators.
idx + operatorString.size() + rightArgumentLength, preprocessedStatement.size());
1054 return preprocessedStatement;
1061 switch(script.conditionType) {
1065 if (script.condition.empty() ==
false)
1066 result+= script.condition +
"; ";
1067 if (script.name.empty() ==
false) {
1068 result+=
"name = '" + script.name +
"';\n";
1072 for (
auto& scriptStatement: script.statements) {
1073 result+=
"\t" + to_string(scriptStatement.statementIdx) +
": " + scriptStatement.statement + (scriptStatement.gotoStatementIdx != -1?
" (gotoStatement " + to_string(scriptStatement.gotoStatementIdx) +
")":
"") +
"\n";
1079 result+=
"State Machine States:\n";
1081 vector<string> states;
1084 state = scriptStateMachineStateIt.second->getName() +
"(" + to_string(scriptStateMachineStateIt.second->getId()) +
")";
1085 states.push_back(state);
1087 sort(states.begin(), states.end());
1088 for (
auto& state: states) result+= state+
"\n";
1095 result+=
"Methods:\n";
1097 vector<string> methods;
1099 auto scriptMethod = scriptMethodIt.second;
1101 method+= scriptMethod->getMethodName();
1103 auto argumentIdx = 0;
1104 if (scriptMethod->isVariadic() ==
true) {
1107 for (
auto& argumentType: scriptMethod->getArgumentTypes()) {
1108 if (argumentIdx > 0) method+=
", ";
1110 if (argumentType.optional ==
true) {
1111 method+=
"(OPTIONAL)";
1118 methods.push_back(method);
1120 sort(methods.begin(), methods.end());
1121 for (
auto& method: methods) result+= method +
"\n";
1126 result+=
"Operators:\n";
1128 vector<string> operators;
1130 auto method = scriptOperatorIt.second;
1131 string operatorString;
1133 operatorString+=
" --> ";
1134 operatorString+= method->getMethodName();
1135 operatorString+=
"(";
1136 auto argumentIdx = 0;
1137 if (method->isVariadic() ==
true) {
1138 operatorString+=
"...";
1140 for (
auto& argumentType: method->getArgumentTypes()) {
1141 if (argumentIdx > 0) operatorString+=
", ";
1143 if (argumentType.optional ==
true) {
1144 operatorString+=
"(OPTIONAL)";
1149 operatorString+=
"): ";
1151 operators.push_back(operatorString);
1153 sort(operators.begin(), operators.end());
1154 for (
auto& method: operators) result+= method +
"\n";
1158 result+=
"Methods:\n\trunning natively\n\n";
1159 result+=
"Operators:\n\trunning natively\n\n";
1163 result+=
"Variables:\n";
1165 vector<string> variables;
1168 auto& scriptVariable = *scriptVariableIt.second;
1169 variable+= scriptVariableIt.first +
" = " + scriptVariable.getAsString();
1170 variables.push_back(variable);
1172 sort(variables.begin(), variables.end());
1173 for (
auto& variable: variables) result+= variable +
"\n";
1189 virtual const string getName()
override {
1190 return "STATE_NEXT_STATEMENT";
1192 virtual int getId()
override {
1195 virtual void execute()
override {
1214 virtual const string getName()
override {
1215 return "STATE_WAIT";
1217 virtual int getId()
override {
1220 virtual void execute()
override {
1236 virtual const string getName()
override {
1237 return "STATE_WAIT_FOR_CONDITION";
1239 virtual int getId()
override {
1242 virtual void execute()
override {
1248 if (scriptIdxToStart == -1) {
1269 const string getMethodName()
override {
1275 Console::println(
"ScriptMethodEnd::executeMethod(): end without forXXX/if");
1307 {.type = ScriptVariableType::TYPE_INTEGER, .name =
"time", .optional =
false }
1310 miniScript(miniScript) {}
1311 const string getMethodName()
override {
1317 Console::println(
"ScriptMethodForTime::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: integer expected");
1322 auto timeWaitStarted = now;
1327 timeWaitStarted = forTimeStartedIt->second;
1348 ScriptMethodForCondition(
MiniScript* miniScript):
1351 {.type = ScriptVariableType::TYPE_BOOLEAN, .name =
"condition", .optional =
false }
1354 miniScript(miniScript) {}
1355 const string getMethodName()
override {
1356 return "forCondition";
1360 if (miniScript->
getBooleanValue(argumentValues, 0, booleanValue,
false) ==
false) {
1361 Console::println(
"ScriptMethodForCondition::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: boolean expected");
1366 if (booleanValue ==
false) {
1383 ScriptMethodIfCondition(
MiniScript* miniScript):
1386 {.type = ScriptVariableType::TYPE_BOOLEAN, .name =
"condition", .optional =
false }
1389 miniScript(miniScript) {}
1390 const string getMethodName()
override {
1395 if (miniScript->
getBooleanValue(argumentValues, 0, booleanValue,
false) ==
false) {
1396 Console::println(
"ScriptMethodIfCondition::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: boolean expected");
1403 if (booleanValue ==
false) {
1414 class ScriptMethodElseIfCondition:
public ScriptMethod {
1418 ScriptMethodElseIfCondition(
MiniScript* miniScript):
1421 {.type = ScriptVariableType::TYPE_BOOLEAN, .name =
"condition", .optional =
false }
1424 miniScript(miniScript) {}
1425 const string getMethodName()
override {
1430 if (miniScript->
getBooleanValue(argumentValues, 0, booleanValue,
false) ==
false) {
1431 Console::println(
"ScriptMethodElseIfCondition::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: boolean expected");
1435 Console::println(
"ScriptMethodElseIfCondition::executeMethod(): elseif without if");
1440 if (conditionStackElement ==
false) {
1444 if (conditionStackElement ==
true || booleanValue ==
false) {
1460 const string getMethodName()
override {
1469 if (conditionStackElement ==
true) {
1480 class ScriptMethodScriptWaitForCondition:
public ScriptMethod {
1484 ScriptMethodScriptWaitForCondition(
MiniScript* miniScript): miniScript(miniScript) {}
1485 const string getMethodName()
override {
1486 return "script.waitForCondition";
1503 ScriptMethodScriptWait(
MiniScript* miniScript):
1505 {.type = ScriptVariableType::TYPE_INTEGER, .name =
"time", .optional =
false }
1507 miniScript(miniScript) {}
1508 const string getMethodName()
override {
1509 return "script.wait";
1518 Console::println(
"ScriptMethodScriptWait::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: integer expected");
1530 ScriptMethodScriptEmit(
MiniScript* miniScript):
1533 {.type = ScriptVariableType::TYPE_STRING, .name =
"condition", .optional =
false }
1536 miniScript(miniScript) {}
1537 const string getMethodName()
override {
1538 return "script.emit";
1543 miniScript->
emit(condition);
1545 Console::println(
"ScriptMethodScriptWait::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: string expected");
1554 class ScriptMethodScriptEnableNamedCondition:
public ScriptMethod {
1558 ScriptMethodScriptEnableNamedCondition(
MiniScript* miniScript):
1561 {.type = ScriptVariableType::TYPE_STRING, .name =
"name", .optional =
false }
1564 miniScript(miniScript) {}
1565 const string getMethodName()
override {
1566 return "script.enableNamedCondition";
1581 Console::println(
"ScriptMethodScriptWait::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: string expected");
1586 registerMethod(
new ScriptMethodScriptEnableNamedCondition(
this));
1590 class ScriptMethodScriptDisableNamedCondition:
public ScriptMethod {
1594 ScriptMethodScriptDisableNamedCondition(
MiniScript* miniScript):
1597 {.type = ScriptVariableType::TYPE_STRING, .name =
"name", .optional =
false }
1600 miniScript(miniScript) {}
1601 const string getMethodName()
override {
1602 return "script.disableNamedCondition";
1616 Console::println(
"ScriptMethodScriptWait::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: string expected");
1621 registerMethod(
new ScriptMethodScriptDisableNamedCondition(
this));
1625 class ScriptMethodScriptGetNamedConditions:
public ScriptMethod {
1629 ScriptMethodScriptGetNamedConditions(
MiniScript* miniScript):
1631 miniScript(miniScript) {}
1632 const string getMethodName()
override {
1633 return "script.getNamedConditions";
1638 result+= result.empty() ==
false?
",":namedCondition;
1652 const string getMethodName()
override {
1653 return "console.log";
1656 for (
auto& argumentValue: argumentValues) {
1661 bool isVariadic()
override {
1674 const string getMethodName()
override {
1675 return "script.stop";
1691 ScriptMethodEquals(
MiniScript* miniScript):
ScriptMethod({}, ScriptVariableType::TYPE_BOOLEAN), miniScript(miniScript) {}
1692 const string getMethodName()
override {
1697 for (
auto i = 1; i < argumentValues.size(); i++) {
1698 if (argumentValues[0].getValueString() != argumentValues[i].getValueString()) {
1704 bool isVariadic()
override {
1719 ScriptMethodNotEqual(
MiniScript* miniScript):
ScriptMethod({}, ScriptVariableType::TYPE_BOOLEAN), miniScript(miniScript) {}
1720 const string getMethodName()
override {
1725 for (
auto i = 1; i < argumentValues.size(); i++) {
1726 if (argumentValues[0].getValueString() == argumentValues[i].getValueString()) {
1732 bool isVariadic()
override {
1751 {.type = ScriptVariableType::TYPE_INTEGER, .name =
"int", .optional =
false }
1753 ScriptVariableType::TYPE_INTEGER
1755 miniScript(miniScript) {}
1756 const string getMethodName()
override {
1760 int64_t integerValue;
1762 returnValue.
setValue(integerValue);
1764 Console::println(
"ScriptMethodInt::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: integer expected");
1781 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"float", .optional =
false }
1783 ScriptVariableType::TYPE_FLOAT
1785 miniScript(miniScript) {}
1786 const string getMethodName()
override {
1794 Console::println(
"ScriptMethodFloat::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: float expected");
1811 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"a", .optional =
false },
1812 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"b", .optional =
false }
1814 ScriptVariableType::TYPE_BOOLEAN),
1815 miniScript(miniScript) {}
1816 const string getMethodName()
override {
1824 returnValue.
setValue(floatValueA > floatValueB);
1826 Console::println(
"ScriptMethodFGreater::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: float expected, @ argument 1: float expected");
1842 ScriptMethodGreaterEquals(
MiniScript* miniScript):
1845 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"a", .optional =
false },
1846 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"b", .optional =
false }
1848 ScriptVariableType::TYPE_BOOLEAN),
1849 miniScript(miniScript) {}
1850 const string getMethodName()
override {
1851 return "greaterequals";
1858 returnValue.
setValue(floatValueA >= floatValueB);
1860 Console::println(
"ScriptMethodFGreater::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: float expected, @ argument 1: float expected");
1879 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"a", .optional =
false },
1880 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"b", .optional =
false }
1882 ScriptVariableType::TYPE_BOOLEAN),
1883 miniScript(miniScript) {}
1884 const string getMethodName()
override {
1892 returnValue.
setValue(floatValueA < floatValueB);
1894 Console::println(
"ScriptMethodFLesser::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: float expected, @ argument 1: float expected");
1910 ScriptMethodLesserEquals(
MiniScript* miniScript):
1913 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"a", .optional =
false },
1914 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"b", .optional =
false }
1916 ScriptVariableType::TYPE_BOOLEAN),
1917 miniScript(miniScript) {}
1918 const string getMethodName()
override {
1919 return "lesserequals";
1926 returnValue.
setValue(floatValueA <= floatValueB);
1928 Console::println(
"ScriptMethodFLesser::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: float expected, @ argument 1: float expected");
1944 ScriptMethodAdd(
MiniScript* miniScript):
ScriptMethod({}, ScriptVariableType::TYPE_VOID), miniScript(miniScript) {}
1945 const string getMethodName()
override {
1951 for (
auto i = 0; i < argumentValues.size(); i++) {
1954 result+= stringValue;
1956 Console::println(
"ScriptMethodAdd::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": string expected");
1964 for (
auto i = 0; i < argumentValues.size(); i++) {
1970 Console::println(
"ScriptMethodAdd::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": vector3 expected");
1976 result+=
Vector3(floatValue, floatValue, floatValue);
1978 Console::println(
"ScriptMethodAdd::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": float expected");
1986 float result = 0.0f;
1987 for (
auto i = 0; i < argumentValues.size(); i++) {
1990 result+= floatValue;
1992 Console::println(
"ScriptMethodAdd::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": float expected");
1998 int64_t result = 0.0f;
1999 for (
auto i = 0; i < argumentValues.size(); i++) {
2004 Console::println(
"ScriptMethodAdd::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": integer expected");
2011 bool isVariadic()
override {
2014 bool isMixedReturnValue()
override {
2029 ScriptMethodSub(
MiniScript* miniScript):
ScriptMethod({}, ScriptVariableType::TYPE_VOID), miniScript(miniScript) {}
2030 const string getMethodName()
override {
2041 Console::println(
"ScriptMethodSub::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": vector3 expected");
2047 result =
Vector3(floatValue, floatValue, floatValue);
2049 Console::println(
"ScriptMethodSub::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": float expected");
2053 for (
auto i = 1; i < argumentValues.size(); i++) {
2059 Console::println(
"ScriptMethodSub::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": vector3 expected");
2066 result-=
Vector3(floatValue, floatValue, floatValue);
2068 Console::println(
"ScriptMethodSub::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": float expected");
2078 float result = 0.0f;
2082 result = floatValue;
2084 Console::println(
"ScriptMethodSub::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": float expected");
2089 if (valid ==
true) {
2090 for (
auto i = 1; i < argumentValues.size(); i++) {
2093 result-= floatValue;
2095 Console::println(
"ScriptMethodSub::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": float expected");
2104 int64_t result = 0LL;
2110 Console::println(
"ScriptMethodSub::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": integer expected");
2115 if (valid ==
true) {
2116 for (
auto i = 1; i < argumentValues.size(); i++) {
2121 Console::println(
"ScriptMethodSub::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": integer expected");
2130 bool isVariadic()
override {
2133 bool isMixedReturnValue()
override {
2148 ScriptMethodMul(
MiniScript* miniScript):
ScriptMethod({}, ScriptVariableType::TYPE_VOID), miniScript(miniScript) {}
2149 const string getMethodName()
override {
2161 Console::println(
"ScriptMethodMul::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": vector3 expected");
2168 result =
Vector3(floatValue, floatValue, floatValue);
2170 Console::println(
"ScriptMethodMul::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": float expected");
2175 if (valid ==
true) {
2176 for (
auto i = 1; i < argumentValues.size(); i++) {
2182 Console::println(
"ScriptMethodMul::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": vector3 expected");
2189 result*=
Vector3(floatValue, floatValue, floatValue);
2191 Console::println(
"ScriptMethodMul::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": float expected");
2202 float result = 0.0f;
2206 result = floatValue;
2208 Console::println(
"ScriptMethodMul::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": float expected");
2213 if (valid ==
true) {
2214 for (
auto i = 1; i < argumentValues.size(); i++) {
2217 result*= floatValue;
2219 Console::println(
"ScriptMethodMul::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": float expected");
2228 int64_t result = 0LL;
2234 Console::println(
"ScriptMethodMul::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": integer expected");
2239 if (valid ==
true) {
2240 for (
auto i = 1; i < argumentValues.size(); i++) {
2245 Console::println(
"ScriptMethodMul::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": integer expected");
2254 bool isVariadic()
override {
2257 bool isMixedReturnValue()
override {
2272 ScriptMethodDiv(
MiniScript* miniScript):
ScriptMethod({}, ScriptVariableType::TYPE_VOID), miniScript(miniScript) {}
2273 const string getMethodName()
override {
2285 Console::println(
"ScriptMethodDiv::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": vector3 expected");
2292 result =
Vector3(floatValue, floatValue, floatValue);
2294 Console::println(
"ScriptMethodDiv::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": float expected");
2299 if (valid ==
true) {
2300 for (
auto i = 1; i < argumentValues.size(); i++) {
2306 Console::println(
"ScriptMethodDiv::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": vector3 expected");
2313 result/=
Vector3(floatValue, floatValue, floatValue);
2315 Console::println(
"ScriptMethodDiv::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": float expected");
2326 float result = 0.0f;
2330 result = floatValue;
2332 Console::println(
"ScriptMethodDiv::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": float expected");
2337 if (valid ==
true) {
2338 for (
auto i = 1; i < argumentValues.size(); i++) {
2341 result/= floatValue;
2343 Console::println(
"ScriptMethodDiv::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": float expected");
2352 int64_t result = 0LL;
2358 Console::println(
"ScriptMethodDiv::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(0) +
": integer expected");
2363 if (valid ==
true) {
2364 for (
auto i = 1; i < argumentValues.size(); i++) {
2369 Console::println(
"ScriptMethodDiv::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": integer expected");
2378 bool isVariadic()
override {
2381 bool isMixedReturnValue()
override {
2400 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"x", .optional =
false },
2401 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"y", .optional =
false },
2402 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"z", .optional =
false }
2404 ScriptVariableType::TYPE_VECTOR3
2406 miniScript(miniScript) {}
2407 const string getMethodName()
override {
2420 Console::println(
"ScriptMethodVec3::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: float expected, @ argument 1: float expected, @ argument 2: float expected");
2429 class ScriptMethodVec3ComputeLength:
public ScriptMethod {
2433 ScriptMethodVec3ComputeLength(
MiniScript* miniScript):
2436 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"vec3", .optional =
false }
2438 ScriptVariableType::TYPE_FLOAT),
2439 miniScript(miniScript) {}
2440 const string getMethodName()
override {
2441 return "vec3.computeLength";
2448 Console::println(
"ScriptMethodVec3ComputeLength::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: vector3 expected");
2457 class ScriptMethodVec3ComputeLengthSquared:
public ScriptMethod {
2461 ScriptMethodVec3ComputeLengthSquared(
MiniScript* miniScript):
2464 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"vec3", .optional =
false }
2466 ScriptVariableType::TYPE_FLOAT),
2467 miniScript(miniScript) {}
2468 const string getMethodName()
override {
2469 return "vec3.computeLengthSquared";
2476 Console::println(
"ScriptMethodVec3ComputeLengthSquared::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: vector3 expected");
2485 class ScriptMethodVec3ComputeDotProduct:
public ScriptMethod {
2489 ScriptMethodVec3ComputeDotProduct(
MiniScript* miniScript):
2492 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"a", .optional =
false },
2493 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"b", .optional =
false }
2495 ScriptVariableType::TYPE_FLOAT),
2496 miniScript(miniScript) {}
2497 const string getMethodName()
override {
2498 return "vec3.computeDotProduct";
2505 returnValue.
setValue(Vector3::computeDotProduct(a, b));
2507 Console::println(
"ScriptMethodVec3ComputeDotProduct::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: vector3 expected, @ argument 1: vector3 expected");
2516 class ScriptMethodVec3ComputeCrossProduct:
public ScriptMethod {
2520 ScriptMethodVec3ComputeCrossProduct(
MiniScript* miniScript):
2523 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"a", .optional =
false },
2524 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"b", .optional =
false }
2526 ScriptVariableType::TYPE_VECTOR3),
2527 miniScript(miniScript) {}
2528 const string getMethodName()
override {
2529 return "vec3.computeCrossProduct";
2536 returnValue.
setValue(Vector3::computeCrossProduct(a, b));
2538 Console::println(
"ScriptMethodVec3ComputeCrossProduct::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: vector3 expected, @ argument 1: vector3 expected");
2551 ScriptMethodVec3Normalize(
MiniScript* miniScript):
2554 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"vec3", .optional =
false },
2556 ScriptVariableType::TYPE_VECTOR3),
2557 miniScript(miniScript) {}
2558 const string getMethodName()
override {
2559 return "vec3.normalize";
2566 Console::println(
"ScriptMethodVec3Normalize::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: vector3 expected");
2575 class ScriptMethodVec3ComputeAngle:
public ScriptMethod {
2579 ScriptMethodVec3ComputeAngle(
MiniScript* miniScript):
2582 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"a", .optional =
false },
2583 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"b", .optional =
false },
2584 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"n", .optional =
false },
2586 ScriptVariableType::TYPE_FLOAT),
2587 miniScript(miniScript) {}
2588 const string getMethodName()
override {
2589 return "vec3.computeAngle";
2598 returnValue.
setValue(Vector3::computeAngle(a, b, n));
2600 Console::println(
"ScriptMethodVec3ComputeAngle::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: vector3 expected, @ argument 1: vector3 expected @ argument 2: vector3 expected");
2613 ScriptMethodVec3GetX(
MiniScript* miniScript):
2616 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"vec3", .optional =
false },
2618 ScriptVariableType::TYPE_FLOAT),
2619 miniScript(miniScript) {}
2620 const string getMethodName()
override {
2628 Console::println(
"ScriptMethodVec3GetX::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: vector3 expected");
2641 ScriptMethodVec3GetY(
MiniScript* miniScript):
2644 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"vec3", .optional =
false },
2646 ScriptVariableType::TYPE_FLOAT),
2647 miniScript(miniScript) {}
2648 const string getMethodName()
override {
2656 Console::println(
"ScriptMethodVec3GetY::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: vector3 expected");
2669 ScriptMethodVec3GetZ(
MiniScript* miniScript):
2672 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"vec3", .optional =
false },
2674 ScriptVariableType::TYPE_FLOAT),
2675 miniScript(miniScript) {}
2676 const string getMethodName()
override {
2684 Console::println(
"ScriptMethodVec3GetZ::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: vector3 expected");
2694 class ScriptMethodTransformations:
public ScriptMethod {
2698 ScriptMethodTransformations(
MiniScript* miniScript):
2702 ScriptVariableType::TYPE_TRANSFORMATIONS),
2703 miniScript(miniScript) {}
2704 const string getMethodName()
override {
2705 return "transformations";
2710 if (argumentValues.size() >= 1) {
2714 Console::println(
"ScriptMethodTransformations::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: vector3 expected");
2718 if (argumentValues.size() >= 2) {
2720 transformations.
setScale(vec3Value);
2722 Console::println(
"ScriptMethodTransformations::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 1: vector3 expected");
2726 for (
auto i = 2; i < argumentValues.size(); i++) {
2730 Console::println(
"ScriptMethodTransformations::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": vector3 expected");
2734 transformations.
update();
2735 returnValue.
setValue(transformations);
2737 bool isVariadic()
override {
2745 class ScriptMethodTransformationsGetTranslation:
public ScriptMethod {
2749 ScriptMethodTransformationsGetTranslation(
MiniScript* miniScript):
2752 {.type = ScriptVariableType::TYPE_TRANSFORMATIONS, .name =
"transformations", .optional =
false },
2754 ScriptVariableType::TYPE_VECTOR3),
2755 miniScript(miniScript) {}
2756 const string getMethodName()
override {
2757 return "transformations.getTranslation";
2764 Console::println(
"ScriptMethodTransformationsGetTranslation::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: transformations expected");
2769 registerMethod(
new ScriptMethodTransformationsGetTranslation(
this));
2773 class ScriptMethodTransformationsSetTranslation:
public ScriptMethod {
2777 ScriptMethodTransformationsSetTranslation(
MiniScript* miniScript):
2780 {.type = ScriptVariableType::TYPE_TRANSFORMATIONS, .name =
"transformations", .optional =
false },
2781 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"translation", .optional =
false },
2783 ScriptVariableType::TYPE_TRANSFORMATIONS),
2784 miniScript(miniScript) {}
2785 const string getMethodName()
override {
2786 return "transformations.setTranslation";
2794 transformations.
update();
2795 returnValue.
setValue(transformations);
2797 Console::println(
"ScriptMethodTransformationsSetTranslation::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: transformations expected, @ argument 1: vector3 expected");
2802 registerMethod(
new ScriptMethodTransformationsSetTranslation(
this));
2806 class ScriptMethodTransformationsGetScale:
public ScriptMethod {
2810 ScriptMethodTransformationsGetScale(
MiniScript* miniScript):
2813 {.type = ScriptVariableType::TYPE_TRANSFORMATIONS, .name =
"transformations", .optional =
false },
2815 ScriptVariableType::TYPE_VECTOR3),
2816 miniScript(miniScript) {}
2817 const string getMethodName()
override {
2818 return "transformations.getScale";
2825 Console::println(
"ScriptMethodTransformationsGetScale::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: transformations expected");
2834 class ScriptMethodTransformationsSetScale:
public ScriptMethod {
2838 ScriptMethodTransformationsSetScale(
MiniScript* miniScript):
2841 {.type = ScriptVariableType::TYPE_TRANSFORMATIONS, .name =
"transformations", .optional =
false },
2842 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"scale", .optional =
false },
2844 ScriptVariableType::TYPE_TRANSFORMATIONS),
2845 miniScript(miniScript) {}
2846 const string getMethodName()
override {
2847 return "transformations.setScale";
2855 transformations.
update();
2856 returnValue.
setValue(transformations);
2858 Console::println(
"ScriptMethodTransformationsSetScale::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: transformations expected, @ argument 1: vector3 expected");
2867 class ScriptMethodTransformationsGetRotationAxis:
public ScriptMethod {
2871 ScriptMethodTransformationsGetRotationAxis(
MiniScript* miniScript):
2874 {.type = ScriptVariableType::TYPE_TRANSFORMATIONS, .name =
"transformations", .optional =
false },
2875 {.type = ScriptVariableType::TYPE_INTEGER, .name =
"idx", .optional =
false },
2877 ScriptVariableType::TYPE_VECTOR3),
2878 miniScript(miniScript) {}
2879 const string getMethodName()
override {
2880 return "transformations.getRotationAxis";
2890 Console::println(
"ScriptMethodTransformationsGetRotationAxis::executeMethod(): " + getMethodName() +
"(): rotation index invalid: " + to_string(idx) +
" / " + to_string(transformations.
getRotationCount()));
2894 Console::println(
"ScriptMethodTransformationsGetRotationAxis::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: transformations expected, @ argument 1: integer expected");
2899 registerMethod(
new ScriptMethodTransformationsGetRotationAxis(
this));
2903 class ScriptMethodTransformationsGetRotationAngle:
public ScriptMethod {
2907 ScriptMethodTransformationsGetRotationAngle(
MiniScript* miniScript):
2910 {.type = ScriptVariableType::TYPE_TRANSFORMATIONS, .name =
"transformations", .optional =
false },
2911 {.type = ScriptVariableType::TYPE_INTEGER, .name =
"idx", .optional =
false },
2913 ScriptVariableType::TYPE_FLOAT),
2914 miniScript(miniScript) {}
2915 const string getMethodName()
override {
2916 return "transformations.getRotationAngle";
2926 Console::println(
"ScriptMethodTransformationsGetRotationAngle::executeMethod(): " + getMethodName() +
"(): rotation index invalid: " + to_string(idx) +
" / " + to_string(transformations.
getRotationCount()));
2930 Console::println(
"ScriptMethodTransformationsGetRotationAngle::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: transformations expected, @ argument 1: integer expected");
2935 registerMethod(
new ScriptMethodTransformationsGetRotationAngle(
this));
2939 class ScriptMethodTransformationsSetRotationAngle:
public ScriptMethod {
2943 ScriptMethodTransformationsSetRotationAngle(
MiniScript* miniScript):
2946 {.type = ScriptVariableType::TYPE_TRANSFORMATIONS, .name =
"transformations", .optional =
false },
2947 {.type = ScriptVariableType::TYPE_INTEGER, .name =
"idx", .optional =
false },
2948 {.type = ScriptVariableType::TYPE_FLOAT, .name =
"angle", .optional =
false },
2950 ScriptVariableType::TYPE_TRANSFORMATIONS),
2951 miniScript(miniScript) {}
2952 const string getMethodName()
override {
2953 return "transformations.setRotationAngle";
2964 transformations.
update();
2965 returnValue.
setValue(transformations);
2967 Console::println(
"ScriptMethodTransformationsSetRotationAngle::executeMethod(): " + getMethodName() +
"(): rotation index invalid: " + to_string(idx) +
" / " + to_string(transformations.
getRotationCount()));
2971 Console::println(
"ScriptMethodTransformationsSetRotationAngle::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: transformations expected, @ argument 1: integer expected, @ argument 2: float expected");
2976 registerMethod(
new ScriptMethodTransformationsSetRotationAngle(
this));
2980 class ScriptMethodTransformationsMultiply:
public ScriptMethod {
2984 ScriptMethodTransformationsMultiply(
MiniScript* miniScript):
2987 {.type = ScriptVariableType::TYPE_TRANSFORMATIONS, .name =
"transformations", .optional =
false },
2988 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"vec3", .optional =
false },
2990 ScriptVariableType::TYPE_VECTOR3),
2991 miniScript(miniScript) {}
2992 const string getMethodName()
override {
2993 return "transformations.multiply";
3002 Console::println(
"ScriptMethodTransformationsSetScale::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: transformations expected, @ argument 1: vector3 expected");
3011 class ScriptMethodTransformationsRotate:
public ScriptMethod {
3015 ScriptMethodTransformationsRotate(
MiniScript* miniScript):
3018 {.type = ScriptVariableType::TYPE_TRANSFORMATIONS, .name =
"transformations", .optional =
false },
3019 {.type = ScriptVariableType::TYPE_VECTOR3, .name =
"vec3", .optional =
false },
3021 ScriptVariableType::TYPE_VECTOR3),
3022 miniScript(miniScript) {}
3023 const string getMethodName()
override {
3024 return "transformations.rotate";
3033 Console::println(
"ScriptMethodTransformationsSetScale::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: transformations expected, @ argument 1: vector3 expected");
3050 {.type = ScriptVariableType::TYPE_BOOLEAN, .name =
"bool", .optional =
false }
3052 ScriptVariableType::TYPE_BOOLEAN
3054 miniScript(miniScript) {}
3055 const string getMethodName()
override {
3063 Console::println(
"ScriptMethodBool::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: boolean expected");
3080 {.type = ScriptVariableType::TYPE_BOOLEAN, .name =
"bool", .optional =
false }
3082 ScriptVariableType::TYPE_BOOLEAN), miniScript(miniScript) {}
3083 const string getMethodName()
override {
3087 bool booleanValue =
false;
3089 returnValue.
setValue(!booleanValue);
3091 Console::println(
"ScriptMethodNot::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: boolean expected");
3108 ScriptMethodAnd(
MiniScript* miniScript):
ScriptMethod({}, ScriptVariableType::TYPE_BOOLEAN), miniScript(miniScript) {}
3109 const string getMethodName()
override {
3114 for (
auto i = 0; i < argumentValues.size(); i++) {
3117 Console::println(
"ScriptMethodAnd::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": boolean expected");
3120 if (booleanValue ==
false) {
3126 bool isVariadic()
override {
3141 ScriptMethodOr(
MiniScript* miniScript):
ScriptMethod({}, ScriptVariableType::TYPE_BOOLEAN), miniScript(miniScript) {}
3142 const string getMethodName()
override {
3147 for (
auto i = 0; i < argumentValues.size(); i++) {
3150 Console::println(
"ScriptMethodOr::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument " + to_string(i) +
": boolean expected");
3153 if (booleanValue ==
true) {
3159 bool isVariadic()
override {
3178 {.type = ScriptVariableType::TYPE_STRING, .name =
"string", .optional =
false }
3180 ScriptVariableType::TYPE_STRING
3182 miniScript(miniScript) {}
3183 const string getMethodName()
override {
3191 Console::println(
"ScriptMethodString::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: string expected");
3207 {.type = ScriptVariableType::TYPE_INTEGER, .name =
"spaces", .optional =
true }
3209 ScriptVariableType::TYPE_STRING
3211 miniScript(miniScript) {}
3212 const string getMethodName()
override {
3218 Console::println(
"ScriptMethodSpace::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: integer expected");
3221 string spacesString;
3222 for (
auto i = 0; i < spaces; i++) spacesString+=
" ";
3223 returnValue.
setValue(spacesString);
3235 ScriptMethodConcatenate(
MiniScript* miniScript):
ScriptMethod({}, ScriptVariableType::TYPE_STRING), miniScript(miniScript) {}
3236 const string getMethodName()
override {
3237 return "concatenate";
3241 for (
auto& argumentValue: argumentValues) {
3242 result+= argumentValue.getValueString();
3246 bool isVariadic()
override {
3258 ScriptMethodToUpperCase(
MiniScript* miniScript):
3261 {.type = ScriptVariableType::TYPE_STRING, .name =
"string", .optional =
false }
3263 ScriptVariableType::TYPE_STRING
3265 miniScript(miniScript) {}
3266 const string getMethodName()
override {
3267 return "toUpperCase";
3274 Console::println(
"ScriptMethodToUpperCase::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: string expected");
3287 ScriptMethodToLowerCase(
MiniScript* miniScript):
3290 {.type = ScriptVariableType::TYPE_STRING, .name =
"string", .optional =
false }
3292 ScriptVariableType::TYPE_STRING
3294 miniScript(miniScript) {}
3295 const string getMethodName()
override {
3296 return "toLowerCase";
3303 Console::println(
"ScriptMethodToLowerCase::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: string expected");
3316 ScriptMethodGetVariable(
MiniScript* miniScript):
3319 {.type = ScriptVariableType::TYPE_STRING, .name =
"variable", .optional =
false }
3321 ScriptVariableType::TYPE_VOID
3323 miniScript(miniScript) {}
3324 const string getMethodName()
override {
3325 return "getVariable";
3332 Console::println(
"ScriptMethodGetVariable::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: string expected");
3336 bool isMixedReturnValue()
override {
3350 ScriptMethodSetVariable(
MiniScript* miniScript):
ScriptMethod({}, ScriptVariableType::TYPE_VOID), miniScript(miniScript) {}
3351 const string getMethodName()
override {
3352 return "setVariable";
3356 if (argumentValues.size() != 2 ||
3358 Console::println(
"ScriptMethodSetVariable::executeMethod(): " + getMethodName() +
"(): parameter type mismatch @ argument 0: string expected, @ argument 1: mixed expected");
3361 miniScript->
setVariable(variable, argumentValues[1]);
3362 returnValue = argumentValues[1];
3365 bool isVariadic()
override {
3368 bool isMixedReturnValue()
override {
3380 class ScriptMethodGetCurrentMillis:
public ScriptMethod {
3384 ScriptMethodGetCurrentMillis(
MiniScript* miniScript):
3386 miniScript(miniScript) {}
3387 const string getMethodName()
override {
3388 return "time.getCurrentMillis";
3398 auto method = methodIt.second;
3399 auto methodOperator = method->getOperator();
3402 auto scriptOperatorIt =
scriptOperators.find(
static_cast<uint8_t
>(methodOperator));
3404 Console::println(
"MiniScript::registerMethods(): operator '" + methodOperatorString +
"' already registered for method '" + method->getMethodName() +
"'");
3415bool MiniScript::transpileScriptStatement(
string& generatedCode,
const string_view& method,
const vector<string_view>& arguments,
const ScriptStatement& statement,
int scriptIdx,
int& statementIdx,
const unordered_map<
string, vector<string>>& methodCodeMap,
bool& scriptStateChanged,
bool& scriptStopped, vector<string>& enabledNamedConditions,
int depth,
int argumentIdx,
int parentArgumentIdx,
const string& returnValue,
const string& injectCode,
int additionalIndent) {
3418 auto currentStatementIdx = statementIdx;
3421 auto methodCodeMapIt = methodCodeMap.find(
string(method));
3422 if (methodCodeMapIt == methodCodeMap.end()) {
3423 Console::println(
"MiniScript::transpileScriptStatement(): method '" +
string(method) +
"' not found!");
3426 auto& methodCode = methodCodeMapIt->second;
3429 string minIndentString =
"\t";
3430 string depthIndentString;
3431 for (
auto i = 0; i < depth + additionalIndent; i++) depthIndentString+=
"\t";
3434 generatedCode+= minIndentString + depthIndentString;
3435 generatedCode+=
"// " + (depth > 0?
"depth = " + to_string(depth):
"") + (depth > 0 && argumentIdx != -1?
" / ":
"") + (argumentIdx != -1?
"argument index = " + to_string(argumentIdx):
"") + (depth > 0 || argumentIdx != -1?
": ":
"");
3436 generatedCode+= string(method) +
"(";
3437 auto subArgumentIdx = 0;
3438 for (
auto& argument: arguments) {
3439 if (subArgumentIdx > 0) generatedCode+=
", ";
3440 generatedCode+= string(argument);
3443 generatedCode+=
")";
3444 generatedCode+=
"\n";
3447 vector<string> argumentValuesCode;
3449 argumentValuesCode.push_back(
"ScriptVariable& returnValue = argumentValuesD" + to_string(depth - 1) + (parentArgumentIdx != -1?
"AIDX" + to_string(parentArgumentIdx):
"") +
"[" + to_string(argumentIdx) +
"];");
3451 argumentValuesCode.push_back(
"ScriptVariable returnValue;");
3453 argumentValuesCode.push_back(
"array<ScriptVariable, " + to_string(arguments.size()) +
"> argumentValues;");
3454 argumentValuesCode.push_back(
"array<ScriptVariable, " + to_string(arguments.size()) +
">& argumentValuesD" + to_string(depth) + (argumentIdx != -1?
"AIDX" + to_string(argumentIdx):
"") +
" = argumentValues;");
3457 generatedCode+= minIndentString + depthIndentString +
"{" +
"\n";
3460 if (scriptIdx == -1) {
3461 generatedCode+= minIndentString + depthIndentString +
"\t" +
"const ScriptStatement statement = {" +
"\n";
3462 generatedCode+= minIndentString + depthIndentString +
"\t\t" +
".line = " + to_string(statement.
line) +
"," +
"\n";
3463 generatedCode+= minIndentString + depthIndentString +
"\t\t" +
".statementIdx = " + to_string(statement.
statementIdx) +
"," +
"\n";
3464 generatedCode+= minIndentString + depthIndentString +
"\t\t" +
".statement = \"<unavailable>\"," +
"\n";
3465 generatedCode+= minIndentString + depthIndentString +
"\t\t" +
".gotoStatementIdx = " + to_string(statement.
gotoStatementIdx) +
"\n";
3466 generatedCode+= minIndentString + depthIndentString +
"\t};" +
"\n";
3468 generatedCode+= minIndentString + depthIndentString +
"\t" +
"const ScriptStatement& statement = scripts[" + to_string(scriptIdx) +
"].statements[" + to_string(statement.
statementIdx) +
"];" +
"\n";
3471 generatedCode+= minIndentString + depthIndentString +
"\t" +
"miniScript->scriptState.statementIdx = statement.statementIdx;" +
"\n";
3473 generatedCode+= minIndentString + depthIndentString +
"\t" +
"// required method code arguments" +
"\n";
3475 for (
auto& codeLine: argumentValuesCode) {
3476 generatedCode+= minIndentString + depthIndentString +
"\t" + codeLine +
"\n";
3478 argumentValuesCode.clear();
3482 auto subArgumentIdx = 0;
3483 for (
auto& argument: arguments) {
3484 if (argument.empty() ==
false &&
3487 argument.find(
'(') != string::npos &&
3488 argument.find(
')') != string::npos) {
3489 argumentValuesCode.push_back(
"// argumentValues[" + to_string(subArgumentIdx) +
"] --> returnValue of " +
string(argument));
3494 string generatedStatement =
"getVariable(\"" + string(argument) +
"\")";
3495 argumentValuesCode.push_back(
"// argumentValues[" + to_string(subArgumentIdx) +
"] --> returnValue of " +
string(generatedStatement));
3501 argumentValuesCode.push_back(
"argumentValues[" + to_string(subArgumentIdx) +
"].setValue(string(\"" +
string(
StringTools::viewSubstring(argument, 1, argument.size() - 1)) +
"\"));");
3505 switch (argumentValue.
getType()) {
3512 argumentValuesCode.push_back(
string() +
"argumentValues[" + to_string(subArgumentIdx) +
"].setValue(" + (value ==
true?
"true":
"false") +
");");
3519 argumentValuesCode.push_back(
"argumentValues[" + to_string(subArgumentIdx) +
"].setValue(static_cast<int64_t>(" + to_string(value) +
"));");
3526 argumentValuesCode.push_back(
"argumentValues[" + to_string(subArgumentIdx) +
"].setValue(" + to_string(value) +
"f);");
3533 argumentValuesCode.push_back(
"argumentValues[" + to_string(subArgumentIdx) +
"].setValue(string(\"" + value +
"\"));");
3549 for (
auto& codeLine: argumentValuesCode) {
3550 generatedCode+= minIndentString + depthIndentString +
"\t" + codeLine +
"\n";
3552 argumentValuesCode.clear();
3555 if (method ==
"script.enableNamedCondition" && arguments.size()) {
3556 if (arguments.size() != 1) {
3557 Console::println(
"MiniScript::transpileScriptStatement(): '" +
scriptFileName +
"': @" + to_string(statement.
line) +
": '" + statement.
statement +
"': script.enableNamedCondition(): expected string argument @ 0");
3559 string name = string(arguments[0]);
3560 enabledNamedConditions.erase(
3562 enabledNamedConditions.begin(),
3563 enabledNamedConditions.end(),
3566 enabledNamedConditions.end()
3568 enabledNamedConditions.push_back(name);
3571 if (method ==
"script.disableNamedCondition") {
3572 if (arguments.size() != 1) {
3573 Console::println(
"MiniScript::transpileScriptStatement(): '" +
scriptFileName +
"': @" + to_string(statement.
line) +
": '" + statement.
statement +
"': script.disableNamedCondition(): expected string argument @ 0");
3575 string name = string(arguments[0]);
3576 enabledNamedConditions.erase(
3578 enabledNamedConditions.begin(),
3579 enabledNamedConditions.end(),
3582 enabledNamedConditions.end()
3589 auto subArgumentIdx = 0;
3590 for (
auto& argument: arguments) {
3591 if (argument.empty() ==
false &&
3594 argument.find(
'(') != string::npos &&
3595 argument.find(
')') != string::npos) {
3597 string_view subMethod;
3598 vector<string_view> subArguments;
3600 if (
transpileScriptStatement(generatedCode, subMethod, subArguments, statement, scriptIdx, statementIdx, methodCodeMap, scriptStateChanged, scriptStopped, enabledNamedConditions, depth + 1, subArgumentIdx, argumentIdx, returnValue) ==
false) {
3601 Console::println(
"MiniScript::transpileScriptStatement(): transpileScriptStatement(): '" +
scriptFileName +
"': @" + to_string(statement.
line) +
": '" + statement.
statement +
"': '" +
string(argument) +
"': parse error");
3604 Console::println(
"MiniScript::transpileScriptStatement(): parseScriptStatement(): '" +
scriptFileName +
"': @" + to_string(statement.
line) +
": '" + statement.
statement +
"': '" +
string(argument) +
"': parse error");
3611 string generatedStatement =
"getVariable(\"" + string(argument) +
"\")";
3612 string_view subMethod;
3613 vector<string_view> subArguments;
3615 if (
transpileScriptStatement(generatedCode, subMethod, subArguments, statement, scriptIdx, statementIdx, methodCodeMap, scriptStateChanged, scriptStopped, enabledNamedConditions, depth + 1, subArgumentIdx, argumentIdx, returnValue) ==
false) {
3616 Console::println(
"MiniScript::transpileScriptStatement(): transpileScriptStatement(): '" +
scriptFileName +
"': @" + to_string(statement.
line) +
": '" + statement.
statement +
"': '" +
string(argument) +
"' --> '" + generatedStatement +
"': parse error");
3619 Console::println(
"MiniScript::transpileScriptStatement(): parseScriptStatement(): '" +
scriptFileName +
"': @" + to_string(statement.
line) +
": '" + statement.
statement +
"': '" +
string(argument) +
"' --> '" + generatedStatement +
"': parse error");
3630 generatedCode+= minIndentString + depthIndentString +
"\t" +
"// method code: " + string(method) +
"\n";
3631 for (
auto codeLine: methodCode) {
3632 codeLine =
StringTools::replace(codeLine,
"getMethodName()",
"string(\"" +
string(method) +
"\")");
3635 Console::println(
"MiniScript::transpileScriptStatement(): method '" +
string(method) +
"': return statement not supported!");
3638 if (
StringTools::regexMatch(codeLine,
"[\\ \\t]*miniScript[\\ \\t]*->gotoStatementGoto[\\ \\t]*\\([\\ \\t]*statement[\\ \\t]*\\)[\\ \\t]*;[\\ \\t]*") ==
true) {
3642 for (
auto i = 0; i < codeLine.size(); i++) {
3643 auto c = codeLine[i];
3650 string indentString;
3651 for (
auto i = 0; i < indent; i++) indentString+=
"\t";
3652 generatedCode+= minIndentString + indentString + depthIndentString +
"\t" +
"goto miniscript_statement_" + to_string(statement.
gotoStatementIdx) +
";\n";
3655 if (
StringTools::regexMatch(codeLine,
"[\\ \\t]*miniScript[\\ \\t]*->startErrorScript[\\ \\t]*\\([\\ \\t]*\\)[\\ \\t]*;[\\ \\t]*") ==
true) {
3656 generatedCode+= minIndentString + depthIndentString +
"\t" + codeLine +
" return" + (returnValue.empty() ==
false?
" " + returnValue:
"") +
";\n";
3658 if (
StringTools::regexMatch(codeLine,
"[\\ \\t]*miniScript[\\ \\t]*->emit[\\ \\t]*\\([\\ \\t]*[a-zA-Z0-9]*[\\ \\t]*\\)[\\ \\t]*;[\\ \\t]*") ==
true) {
3659 generatedCode+= minIndentString + depthIndentString +
"\t" + codeLine +
" return" + (returnValue.empty() ==
false?
" " + returnValue:
"") +
";\n";
3661 if (
StringTools::regexMatch(codeLine,
".*[\\ \\t]*miniScript[\\ \\t]*->[\\ \\t]*setScriptState[\\ \\t]*\\([\\ \\t]*.+[\\ \\t]*\\);.*") ==
true) {
3662 scriptStateChanged =
true;
3664 if (
StringTools::regexMatch(codeLine,
".*[\\ \\t]*miniScript[\\ \\t]*->[\\ \\t]*stopScriptExecutation[\\ \\t]*\\([\\ \\t]*\\);.*") ==
true) {
3665 scriptStopped =
true;
3667 generatedCode+= minIndentString + depthIndentString +
"\t" + codeLine +
"\n";
3672 if (injectCode.empty() ==
false) {
3673 generatedCode+= minIndentString + depthIndentString +
"\t" + injectCode +
"\n";
3677 generatedCode+= minIndentString + depthIndentString +
"}" +
"\n";
3683bool MiniScript::transpile(
string& generatedCode,
int scriptIdx,
const unordered_map<
string, vector<string>>& methodCodeMap) {
3684 if (scriptIdx < 0 || scriptIdx >=
scripts.size()) {
3690 auto& script =
scripts[scriptIdx];
3693 Console::println(
"MiniScript::transpile(): transpiling code for condition = '" + script.condition +
"', with name '" + script.name +
"'");
3694 auto statementIdx = 0;
3695 string methodIndent =
"\t";
3696 string generatedCodeHeader;
3699 generatedCodeHeader+= methodIndent +
"// -1 means complete method call" +
"\n";
3700 generatedCodeHeader+= methodIndent +
"if (miniScriptGotoStatementIdx == -1) {" +
"\n";
3701 generatedCodeHeader+= methodIndent +
"\t" +
"resetScriptExecutationState(" + to_string(scriptIdx) +
", STATE_NEXT_STATEMENT);" +
"\n";
3702 generatedCodeHeader+= methodIndent +
"}" +
"\n";
3704 generatedCodeHeader+= methodIndent +
"auto miniScript = this;" +
"\n";
3705 generatedCodeHeader+= methodIndent +
"miniScript->scriptState.scriptIdx = " + to_string(scriptIdx) +
";" +
"\n";
3710 (script.name.empty() ==
false?script.name:(
3713 to_string(scriptIdx)
3718 unordered_set<int> gotoStatementIdxSet;
3719 for (
auto scriptStatement: script.statements) gotoStatementIdxSet.insert(scriptStatement.gotoStatementIdx);
3722 vector<string> enabledNamedConditions;
3723 auto scriptStateChanged =
false;
3724 for (
auto scriptStatement: script.statements) {
3727 vector<string_view> arguments;
3729 Console::println(
"MiniScript::transpileScriptStatement(): '" +
scriptFileName +
"': " + scriptStatement.statement +
"@" + to_string(scriptStatement.line) +
": failed to parse statement");
3733 if (scriptStateChanged ==
true) {
3734 generatedCodeHeader+= methodIndent +
"if (miniScriptGotoStatementIdx == " + to_string(scriptStatement.statementIdx) +
") goto miniscript_statement_" + to_string(scriptStatement.statementIdx) +
"; else" +
"\n";
3738 if (enabledNamedConditions.empty() ==
false) {
3739 generatedCode+=
"\n";
3740 generatedCode+= methodIndent +
"// enabled named conditions" +
"\n";
3741 generatedCode+= methodIndent +
"{" +
"\n";
3742 generatedCode+= methodIndent +
"\t" +
"auto scriptIdxToStart = determineNamedScriptIdxToStart();" +
"\n";
3743 generatedCode+= methodIndent +
"\t" +
"if (scriptIdxToStart != -1 && scriptIdxToStart != scriptState.scriptIdx) {" +
"\n";
3744 generatedCode+= methodIndent +
"\t" +
"resetScriptExecutationState(scriptIdxToStart, STATE_NEXT_STATEMENT);" +
"\n";
3745 generatedCode+= methodIndent +
"\t" +
"scriptState.timeEnabledConditionsCheckLast = Time::getCurrentMillis();" +
"\n";
3746 generatedCode+= methodIndent +
"\t" +
"return;" +
"\n";
3747 generatedCode+= methodIndent +
"\t" +
"}" +
"\n";
3748 generatedCode+= methodIndent +
"}" +
"\n";
3752 generatedCode+=
"\n";
3753 generatedCode+= methodIndent +
"// Statement: " + to_string(scriptStatement.statementIdx) +
"\n";
3754 if (scriptStateChanged ==
true || gotoStatementIdxSet.find(scriptStatement.statementIdx) != gotoStatementIdxSet.end()) {
3755 generatedCode+= methodIndent +
"miniscript_statement_" + to_string(scriptStatement.statementIdx) +
":" +
"\n";
3757 scriptStateChanged =
false;
3758 auto scriptStopped =
false;
3759 transpileScriptStatement(generatedCode, method, arguments, scriptStatement, scriptIdx, statementIdx, methodCodeMap, scriptStateChanged, scriptStopped, enabledNamedConditions);
3760 if (scriptStopped ==
true) {
3761 generatedCode+= methodIndent +
"if (scriptState.running == false) {" +
"\n";
3762 generatedCode+= methodIndent +
"\t" +
"return;" +
"\n";
3763 generatedCode+= methodIndent +
"}" +
"\n";
3765 if (scriptStateChanged ==
true) {
3766 generatedCode+= methodIndent +
"if (scriptState.state.state != STATE_NEXT_STATEMENT) {" +
"\n";
3767 generatedCode+= methodIndent +
"\t" +
"miniScript->scriptState.statementIdx++;" +
"\n";
3768 generatedCode+= methodIndent +
"\t" +
"return;" +
"\n";
3769 generatedCode+= methodIndent +
"}" +
"\n";
3772 generatedCode+= methodIndent +
"scriptState.scriptIdx = -1;" +
"\n";
3773 generatedCode+= methodIndent +
"scriptState.statementIdx = -1;" +
"\n";
3774 generatedCode+= methodIndent +
"setScriptState(STATE_WAIT_FOR_CONDITION);" +
"\n";
3777 generatedCodeHeader+= methodIndent +
"if (miniScriptGotoStatementIdx != -1 && miniScriptGotoStatementIdx != 0) Console::println(\"MiniScript::" + methodName +
"(): Can not go to statement \" + to_string(miniScriptGotoStatementIdx));" +
"\n";
3779 generatedCode = generatedCodeHeader + generatedCode;
3783bool MiniScript::transpileScriptCondition(
string& generatedCode,
int scriptIdx,
const unordered_map<
string, vector<string>>& methodCodeMap,
const string& returnValue,
const string& injectCode,
int depth) {
3784 if (scriptIdx < 0 || scriptIdx >=
scripts.size()) {
3790 Console::println(
"MiniScript::transpile(): transpiling code condition for condition = '" +
scripts[scriptIdx].condition +
"', with name '" +
scripts[scriptIdx].name +
"'");
3791 auto statementIdx = 0;
3792 string methodIndent =
"\t";
3797 .statement =
scripts[scriptIdx].condition,
3798 .gotoStatementIdx = -1
3803 vector<string_view> arguments;
3810 auto scriptStateChanged =
false;
3811 auto scriptStopped =
false;
3812 vector<string >enabledNamedConditions;
3813 transpileScriptStatement(generatedCode, method, arguments, scriptStatement, -1, statementIdx, methodCodeMap, scriptStateChanged, scriptStopped, enabledNamedConditions, 0, -1, -1, returnValue, injectCode, depth + 1);
3816 generatedCode+= methodIndent +
"\n";
Dynamic rigid/static rigid/collision body class.
Dynamic physics world class.
Bounding volume interface.
Prototype bounding volume definition.
float computeLength() const
Vector3 & normalize()
Normalize the vector.
float computeLengthSquared() const
File system singleton class.
static bool isSpace(char character)
Returns if character is a white space.
static void println()
Print new line to console.
static void print(const string &str)
Print given string.
virtual const string getMethodName()=0
Script State Machine State.
virtual void execute()=0
Execute script state machine state.
virtual const string getName()=0
static const string getTypeAsString(ScriptVariableType type)
bool getIntegerValue(int64_t &value, bool optional=false) const
Get integer value from given variable.
bool getStringValue(string &value, bool optional=false) const
Get string value from given variable.
ScriptVariableType getType() const
const string getTypeAsString()
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 setImplicitTypedValueFromStringView(const string_view &value)
Set implicit typed value given by value string.
void setValue(bool value)
Set boolean value from given value into variable.
bool transpile(string &generatedCode, int scriptIdx, const unordered_map< string, vector< string > > &methodCodeMap)
Transpile a script statement.
void resetScriptExecutationState(int scriptIdx, StateMachineState stateMachineState)
Reset script execution state.
static bool getBooleanValue(const vector< ScriptVariable > &arguments, int idx, bool &value, bool optional=false)
Get boolean value from given variable.
static bool getVector3Value(const vector< ScriptVariable > &arguments, int idx, Vector3 &value, bool optional=false)
Get vector3 value from given variable.
void loadScript(const string &pathName, const string &fileName)
Load script.
void registerStateMachineState(ScriptStateMachineState *state)
Register script state machine state.
static string getOperatorAsString(ScriptOperator scriptOperator)
Get operator as string.
unordered_map< int, ScriptStateMachineState * > scriptStateMachineStates
virtual void startScript()
Start script.
const string findLeftArgument(const string statement, int position, int &length)
Find left argument in statement beginning from position.
static bool getFloatValue(const vector< ScriptVariable > &arguments, int idx, float &value, bool optional=false)
Get float value from given variable.
unordered_map< string, ScriptMethod * > scriptMethods
ScriptVariable executeScriptStatement(const string_view &method, const vector< string_view > &arguments, const ScriptStatement &statement)
Execute a script statement.
@ OPERATOR_MULTIPLICATION
virtual void execute()
Execute.
virtual void registerStateMachineStates()
Register state machine states.
virtual void initializeNative()
Initialize native mini script.
void setVariable(const string &name, const ScriptVariable &variable)
Set script variable.
virtual void registerVariables()
Register variables.
static constexpr bool VERBOSE
bool transpileScriptStatement(string &generatedCode, const string_view &method, const vector< string_view > &arguments, const ScriptStatement &statement, int scriptIdx, int &statementIdx, const unordered_map< string, vector< string > > &methodCodeMap, bool &scriptStateChanged, bool &scriptStopped, vector< string > &enabledNamedConditions, int depth=0, int argumentIdx=-1, int parentArgumentIdx=-1, const string &returnValue=string(), const string &injectCode=string(), int additionalIndent=0)
Transpile script statement.
virtual void registerMethods()
Register methods.
virtual void emit(const string &condition)
Emit.
static bool getIntegerValue(const vector< ScriptVariable > &arguments, int idx, int64_t &value, bool optional=false)
Get integer value from given variable.
static const bool isOperatorChar(char c)
Returns if char is operator char.
static bool hasType(const vector< ScriptVariable > &arguments, ScriptVariableType type)
Check if arguments contain argument with given type.
virtual ~MiniScript()
Destructor.
bool getNextStatementOperator(const string &statement, ScriptStatementOperator &nextOperator)
Determine next not substituted operator in statement.
bool transpileScriptCondition(string &generatedCode, int scriptIdx, const unordered_map< string, vector< string > > &methodCodeMap, const string &returnValue, const string &injectCode, int depth=0)
Transpile a script condition.
void stopScriptExecutation()
Stop script execution.
void setNative(bool native)
Set native.
const string getInformation()
Get miniscript instance information.
const string getArgumentsAsString(const vector< string_view > &arguments)
Returns arguments as string placed in a vector of string_views.
const string doStatementPreProcessing(const string &statement)
Do statement pre processing, 1) replace operators with corresponding methods.
static bool getTransformationsValue(const vector< ScriptVariable > &arguments, int idx, Transformations &value, bool optional=false)
Get transformations value from given variable.
const ScriptVariable getVariable(const string &name)
Returns variable with given name.
void startErrorScript()
Start error script.
const string trimArgument(const string &argument)
Trim argument and remove unnessessary parenthesis.
void executeStateMachine()
Execute state machine.
void registerMethod(ScriptMethod *method)
Register script method.
@ STATE_WAIT_FOR_CONDITION
vector< Script > nativeScripts
const string findRightArgument(const string statement, int position, int &length)
Find right argument in statement beginning from position.
bool parseScriptStatement(const string_view &statement, string_view &method, vector< string_view > &arguments)
Parse a script statement.
virtual int determineNamedScriptIdxToStart()
Determine named script index to start.
void gotoStatementGoto(const ScriptStatement &statement)
Goto statement from given statements goto statement.
static bool getStringValue(const vector< ScriptVariable > &arguments, int idx, string &value, bool optional=false)
Get string value from given variable.
virtual int determineScriptIdxToStart()
Determine script index to start.
void setScriptState(int state)
Set script state machine state.
unordered_map< uint8_t, ScriptMethod * > scriptOperators
void executeScriptLine()
Execute a single script line.
static const string encode(const string &decodedString)
Encodes an string to SHA256 string.
static int64_t getCurrentMillis()
Retrieve current time in milliseconds.
ScriptStateMachineState * lastStateMachineState
stack< bool > conditionStack
unordered_map< string, ScriptVariable * > variables
unordered_map< int, int64_t > forTimeStarted
stack< EndType > endTypeStack
vector< string > enabledNamedConditions
int64_t timeEnabledConditionsCheckLast
ScriptOperator scriptOperator
@ CONDITIONTYPE_ONENABLED