Skip to content

Commit

Permalink
MiniScript: some initial WIP on map inline/lambda functions (3), star…
Browse files Browse the repository at this point in the history
…ts to woooork \o/
  • Loading branch information
andreasdr committed Oct 25, 2023
1 parent f52774a commit 73af4f6
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 12 deletions.
10 changes: 8 additions & 2 deletions resources/tests/scripts/class-test.tscript
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,22 @@ on: nothing
# member methods
increment: () -> increment,
printABC: () -> printABC,
printABCD: ($e) ->
printABCD: ($d) ->
{
console.log("xxx: " + $this.a * $this.b * $this.c * $e)
console.log("xxx: " + $this.a * $this.b * $this.c * $d)
},
printABCDE: ($d, $e) ->
{
console.log("yyy: " + $this.a * $this.b * $this.c * $d * $e)
}
};
console.dump($class)
#
$i = 0
forCondition($i < 5)
$class->printABC()
$class->printABCD($i)
$class->printABCDE($i, 2)
$class->increment()
++$i
end
Expand Down
45 changes: 41 additions & 4 deletions src/tdme/utilities/MiniScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7995,6 +7995,8 @@ const MiniScript::ScriptVariable MiniScript::initializeMapSet(const string_view&
enum ParseMode { PARSEMODE_KEY, PARSEMODE_VALUE };
auto parseMode = PARSEMODE_KEY;
auto hasValues = false;
auto inlineFunctionSignatureStart = string::npos;

//
auto insertMapKeyValuePair = [&]() -> void {
//
Expand Down Expand Up @@ -8064,6 +8066,8 @@ const MiniScript::ScriptVariable MiniScript::initializeMapSet(const string_view&
quotedMapValueEnd = string::npos;
mapValueStart = string::npos;
mapValueEnd = string::npos;
inlineFunctionSignatureStart = string::npos;

//
parseMode = PARSEMODE_KEY;
};
Expand Down Expand Up @@ -8130,11 +8134,15 @@ const MiniScript::ScriptVariable MiniScript::initializeMapSet(const string_view&
if (c == '(') {
//
bracketCount++;
//
if (bracketCount == 1) inlineFunctionSignatureStart = i;
} else
if (c == ')') {
bracketCount--;
// function assignment
if (lc == '(' && bracketCount == 0 && mapValueStart == string::npos) mapValueStart = i - 1;
if (inlineFunctionSignatureStart != string::npos && bracketCount == 0 && mapValueStart == string::npos) mapValueStart = inlineFunctionSignatureStart;
//
inlineFunctionSignatureStart = string::npos;
} else
// map/set initializer
if (c == '{' && squareBracketCount == 0 && bracketCount == 0) {
Expand All @@ -8145,7 +8153,7 @@ const MiniScript::ScriptVariable MiniScript::initializeMapSet(const string_view&
mapKeyStart = i + 1;
} else
if (curlyBracketCount == 2) {
mapValueStart = i;
if (mapValueStart == string::npos) mapValueStart = i;
}
} else
// end of map/set initializer
Expand Down Expand Up @@ -8189,15 +8197,42 @@ const MiniScript::ScriptVariable MiniScript::initializeMapSet(const string_view&
quotedMapKeyEnd = string::npos;
mapKeyStart = string::npos;
mapKeyEnd = string::npos;
inlineFunctionSignatureStart = string::npos;

// map value
if (mapValueStart != string::npos) {
mapValueEnd = i;
auto mapValueLength = mapValueEnd - mapValueStart + 1;
if (mapValueLength > 0) {
auto mapValueStringView = StringTools::viewTrim(string_view(&initializerString[mapValueStart], mapValueLength));
if (mapValueStringView.empty() == false) {
auto mapValue = initializeMapSet(mapValueStringView, miniScript, statement);
variable.setMapValue(string(mapKey), mapValue);
//
vector<string_view> arguments;
string_view functionScriptCode;
if (viewIsInlineFunction(mapValueStringView, arguments, functionScriptCode) == true) {
string functionScriptCodeString;
auto functionName = string() + "map_inline_function_" + to_string(miniScript->inlineFunctionIdx++);
functionScriptCodeString = "function: " + functionName + "(=$this";
auto argumentIdx = 0;
for (const auto& argument: arguments) {
functionScriptCodeString+= ",";
functionScriptCodeString+= argument;
argumentIdx++;
}
functionScriptCodeString+= string() + ")" + "\n";
functionScriptCodeString+= functionScriptCode;
functionScriptCodeString+= "\n";
functionScriptCodeString+= string() + "end" + "\n";
//
miniScript->parseScriptInternal(functionScriptCodeString);
//
ScriptVariable mapValue;
mapValue.setFunctionAssignment(functionName);
variable.setMapValue(string(mapKey), mapValue);
} else {
auto mapValue = initializeMapSet(mapValueStringView, miniScript, statement);
variable.setMapValue(string(mapKey), mapValue);
}
}
}
//
Expand Down Expand Up @@ -8244,6 +8279,8 @@ const MiniScript::ScriptVariable MiniScript::initializeMapSet(const string_view&
quotedMapKeyEnd = string::npos;
mapKeyStart = string::npos;
mapKeyEnd = string::npos;
inlineFunctionSignatureStart = string::npos;

// map value
if (mapValueStart != string::npos) {
mapValueEnd = i;
Expand Down
97 changes: 91 additions & 6 deletions src/tdme/utilities/MiniScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -1570,7 +1570,7 @@ class tdme::utilities::MiniScript {
* @param statement statement
*/
inline void setImplicitTypedValueFromStringView(const string_view& value, MiniScript* miniScript, const ScriptStatement& statement) {
string function;
string_view function;
//
if (value == "null") {
setNullValue();
Expand All @@ -1596,7 +1596,7 @@ class tdme::utilities::MiniScript {
*this = initializeArray(value, miniScript, statement);
} else
if (viewIsFunctionAssignment(value, function) == true) {
setFunctionAssignment(function);
setFunctionAssignment(string(function));
} else
// function call
if (value.find('(') != string::npos &&
Expand Down Expand Up @@ -2352,6 +2352,8 @@ class tdme::utilities::MiniScript {

vector<string> parseErrors;

int inlineFunctionIdx { 0 };

/**
* Initialize native mini script
*/
Expand Down Expand Up @@ -2738,7 +2740,7 @@ class tdme::utilities::MiniScript {
* @param function function
* @return if candidate is a function assignment
*/
inline static bool viewIsFunctionAssignment(const string_view& candidate, string& function) {
inline static bool viewIsFunctionAssignment(const string_view& candidate, string_view& function) {
if (candidate.size() == 0) return false;
//
auto i = 0;
Expand All @@ -2759,16 +2761,99 @@ class tdme::utilities::MiniScript {
// spaces
for (; i < candidate.size() && Character::isSpace(candidate[i]) == true; i++); if (i >= candidate.size()) return false;
//
string _function;
auto functionStartIdx = i;
for (; i < candidate.size(); i++) {
auto c = candidate[i];
if (Character::isAlphaNumeric(c) == false && c != '_') {
return false;
}
_function+= c;
}
//
function = _function;
function = string_view(&candidate[functionStartIdx], i - functionStartIdx);
//
return true;
}

/**
* Returns if a given string is a inline function
* @param candidate candidate
* @param arguments arguments
* @param functionScriptCode function script code
* @return if candidate is a inline function
*/
inline static bool viewIsInlineFunction(const string_view& candidate, vector<string_view>& arguments, string_view& functionScriptCode) {
if (candidate.size() == 0) return false;
//
auto i = 0;
// (
if (candidate[i++] != '(') return false;
// spaces
for (; i < candidate.size() && Character::isSpace(candidate[i]) == true; i++); if (i >= candidate.size()) return false;
//
auto argumentStartIdx = string::npos;
auto argumentEndIdx = string::npos;
//
for (; i < candidate.size(); i++) {
auto c = candidate[i];
if (c == '$') {
if (argumentStartIdx == string::npos) {
argumentStartIdx = i;
} else {
return false;
}
} else
if (c == ',' || c == ')') {
if (argumentEndIdx == string::npos) {
if (argumentStartIdx != string::npos) {
argumentEndIdx = i;
arguments.push_back(string_view(&candidate[argumentStartIdx], argumentEndIdx - argumentStartIdx));
}
//
argumentStartIdx = string::npos;
argumentEndIdx = string::npos;
} else {
return false;
}
if (c == ')') {
i++;
break;
}
} else
if (argumentStartIdx != string::npos && Character::isAlphaNumeric(candidate[i]) == false && c != '_') {
return false;
}
}
//
if (i >= candidate.size()) return false;
// spaces
for (; i < candidate.size() && Character::isSpace(candidate[i]) == true; i++); if (i >= candidate.size()) return false;
// -
if (candidate[i++] != '-') return false;
//
if (i >= candidate.size()) return false;
// >
if (candidate[i++] != '>') return false;
// spaces
for (; i < candidate.size() && Character::isSpace(candidate[i]) == true; i++); if (i >= candidate.size()) return false;
//
if (candidate[i++] != '{') return false;
//
auto scriptCodeStartIdx = i;
auto scriptCodeEndIdx = string::npos;
//
for (auto j = candidate.size() - 1; j > i; j--) {
if (candidate[j] == '}') {
scriptCodeEndIdx = j;
break;
} else
if (Character::isSpace(candidate[j]) == false) {
return false;
}
}
//
if (scriptCodeEndIdx == string::npos) return false;
//
functionScriptCode = string_view(&candidate[scriptCodeStartIdx], scriptCodeEndIdx - scriptCodeStartIdx);
//
return true;
}
Expand Down

0 comments on commit 73af4f6

Please sign in to comment.