TDME2 1.9.121
miniscripttranspiler-main.cpp
Go to the documentation of this file.
1#include <set>
2#include <string>
3#include <unordered_map>
4#include <vector>
5
6#include <tdme/tdme.h>
17
18using std::set;
19using std::string;
20using std::unordered_map;
21using std::vector;
22
33
34void gatherMethodCode(const vector<string>& miniScriptExtensionsCode, const string& className, int registerLine, unordered_map<string, vector<string>>& methodCodeMap) {
35 // TODO: this is a bit ugly and can be improved a lot, lets see and get this to work first
36 auto classDefinitionLine = -1;
37 // get class definition start line
38 for (auto i = registerLine; i >= 0; i--) {
39 auto& line = miniScriptExtensionsCode[i];
40 auto trimmedLine = StringTools::trim(line);
41 if (StringTools::regexMatch(trimmedLine, "class[\\ \\t]+" + className + "[\\ \\t]*:.*") == true) {
42 classDefinitionLine = i;
43 break;
44 }
45 }
46 // nope
47 if (classDefinitionLine == -1) {
48 Console::println("gatherMethodCode(): did not found '" + className + "' definition");
49 return;
50 }
51 //
52 auto curlyBracketCount = 0;
53 auto finished = false;
54 auto haveExecuteMethodDeclaration = false;
55 auto executeMethodCurlyBracketStart = -1;
56 auto haveGetMethodNameDeclaration = false;
57 auto getMethodNameCurlyBracketStart = -1;
58 vector<string> executeMethodCode;
59 string getMethodNameCode;
60 for (auto i = classDefinitionLine; finished == false && i < miniScriptExtensionsCode.size(); i++) {
61 auto& line = miniScriptExtensionsCode[i];
62 auto trimmedLine = StringTools::trim(line);
63 // have getMethodName declaration, with following body
64 if (StringTools::regexMatch(trimmedLine, "const[\\ \\t]+string[\\ \\t]+getMethodName()[\\ \\t]*\\(.*") == true) {
65 haveGetMethodNameDeclaration = true;
66 }
67 // have executeMethod declaration, with following body
68 if (StringTools::regexMatch(trimmedLine, "void[\\ \\t]+executeMethod[\\ \\t]*\\(.*") == true) {
69 haveExecuteMethodDeclaration = true;
70 }
71 //
72 for (auto j = 0; j < trimmedLine.size(); j++) {
73 auto c = trimmedLine[j];
74 if (c == '{') {
75 curlyBracketCount++;
76 // new code block,
77 // if we have the declaration mark this curly bracket as executeMethod implementation start curly bracket
78 if (haveExecuteMethodDeclaration == true) {
79 executeMethodCurlyBracketStart = curlyBracketCount;
80 }
81 // if we have the declaration mark this curly bracket as getMethodName implementation start curly bracket
82 if (haveGetMethodNameDeclaration == true) {
83 getMethodNameCurlyBracketStart = curlyBracketCount;
84 }
85 } else
86 if (c == '}') {
87 // do we just leave our getMethodName implementation?
88 if (getMethodNameCurlyBracketStart != -1 && curlyBracketCount == getMethodNameCurlyBracketStart) {
89 // yup
90 getMethodNameCurlyBracketStart = -1;
91 }
92 // do we just leave our executeMethod implementation?
93 if (executeMethodCurlyBracketStart != -1 && curlyBracketCount == executeMethodCurlyBracketStart) {
94 // yup
95 executeMethodCurlyBracketStart = -1;
96 }
97 //
98 curlyBracketCount--;
99 // get out of here :D
100 if (curlyBracketCount <= 0) {
101 finished = true;
102 break;
103 }
104 }
105 }
106 // is this getMethodName code?
107 if (haveGetMethodNameDeclaration == false && getMethodNameCurlyBracketStart != -1 && curlyBracketCount >= getMethodNameCurlyBracketStart) {
108 getMethodNameCode+= trimmedLine;
109 }
110 // is this executeMethod code?
111 if (haveExecuteMethodDeclaration == false && executeMethodCurlyBracketStart != -1 && curlyBracketCount >= executeMethodCurlyBracketStart) {
112 executeMethodCode.push_back(line);
113 }
114 // do we still process getMethodName declaration
115 if (haveGetMethodNameDeclaration == true) {
116 // ok unset
117 haveGetMethodNameDeclaration = false;
118 }
119 // do we still process executeMethod declaration
120 if (haveExecuteMethodDeclaration == true) {
121 // ok unset
122 haveExecuteMethodDeclaration = false;
123 }
124 }
125
126 // determine method name
127 string methodName;
128 {
129 auto haveMethodName = false;
130 for (auto i = 0; i < getMethodNameCode.size(); i++) {
131 auto c = getMethodNameCode[i];
132 if (c == '"') {
133 if (haveMethodName == false) haveMethodName = true; else
134 break;
135 } else
136 if (haveMethodName == true) {
137 methodName+= c;
138 }
139 }
140 }
141
142 // find min indent from method code and depth indent
143 int minIndent = Integer::MAX_VALUE;
144 for (auto& codeLine: executeMethodCode) {
145 auto indent = 0;
146 for (auto i = 0; i < codeLine.size(); i++) {
147 auto c = codeLine[i];
148 if (c == '\t') {
149 indent++;
150 } else {
151 break;
152 }
153 }
154 minIndent = Math::min(minIndent, indent);
155 }
156
157 // remove indent
158 for (auto& codeLine: executeMethodCode) {
159 codeLine = StringTools::substring(codeLine, minIndent);
160 }
161
162 //
163 auto methodCodeMapIt = methodCodeMap.find(methodName);
164 if (methodCodeMapIt != methodCodeMap.end()) {
165 Console::println("gatherMethodCode(): Not registering method with methodName: '" + methodName + "': method already registered");
166 return;
167 }
168
169 //
170 Console::println("gatherMethodCode(): registering method with methodName: '" + methodName + "'");
171
172 //
173 methodCodeMap[methodName] = executeMethodCode;
174}
175
176void processFile(const string& scriptFileName, const string& miniscriptTranspilationFileName, const vector<string>& miniScriptExtensionFileNames) {
177 Console::println("Processing script: " + scriptFileName);
178
179 //
180 unordered_map<string, vector<string>> methodCodeMap;
181
182 //
183 vector<string> _miniScriptExtensionFileNames;
184 _miniScriptExtensionFileNames.push_back("src/tdme/utilities/MiniScript.cpp");
185 for (auto& miniScriptExtensionFileName: miniScriptExtensionFileNames) _miniScriptExtensionFileNames.push_back(miniScriptExtensionFileName);
186 for (auto& miniScriptExtensionFileName: _miniScriptExtensionFileNames) {
187 vector<string> miniScriptExtensionsCode;
188 FileSystem::getInstance()->getContentAsStringArray(Tools::getPathName(miniScriptExtensionFileName), Tools::getFileName(miniScriptExtensionFileName), miniScriptExtensionsCode);
189 for (auto i = 0; i < miniScriptExtensionsCode.size(); i++) {
190 auto& line = miniScriptExtensionsCode[i];
191 auto trimmedLine = StringTools::trim(line);
192 if (StringTools::startsWith(trimmedLine, "registerMethod") == true) {
193 auto bracketCount = 0;
194 string className;
195 auto classNameStartIdx = StringTools::firstIndexOf(StringTools::substring(trimmedLine, 14), "new");
196 if (classNameStartIdx == string::npos) {
197 Console::println("src/tdme/utilities/MiniScript.cpp: registerMethod @ " + to_string(i) + ": '" + trimmedLine + "': unable to determine class name");
198 } else {
199 classNameStartIdx+= 14 + 3;
200 for (auto j = classNameStartIdx; j < trimmedLine.size(); j++) {
201 auto c = trimmedLine[j];
202 if (c == '(') break;
203 if (c == ' ') continue;
204 className+= c;
205 }
206 gatherMethodCode(miniScriptExtensionsCode, className, i, methodCodeMap);
207 }
208 }
209 }
210 }
211
212 //
213 MiniScript* scriptInstance = new MiniScript();
214 scriptInstance->loadScript(Tools::getPathName(scriptFileName), Tools::getFileName(scriptFileName));
215 Console::println(scriptInstance->getInformation());
216
217 //
218 string headerIndent = "\t";
219 string methodCodeIndent = "\t";
220 auto scripts = scriptInstance->getScripts();
221 string generatedExecuteCode;
222 {
223 auto scriptIdx = 0;
224 for (auto& script: scripts) {
225 // method name
226 string methodName =
227 (script.conditionType == MiniScript::Script::CONDITIONTYPE_ON?"on_":"on_enabled_") +
228 (script.name.empty() == false?script.name:(
229 StringTools::regexMatch(script.condition, "[a-zA-Z0-9]+") == true?
230 script.condition:
231 to_string(scriptIdx)
232 )
233 );
234 //
235 generatedExecuteCode+= headerIndent + "\t\t" + "if (scriptState.scriptIdx == " + to_string(scriptIdx) + ") " + methodName + "(scriptState.statementIdx);" + (scriptIdx < scripts.size() - 1?" else":"") + "\n";
236 scriptIdx++;
237 }
238 }
239
240 // determine "initialize" and "nothing" script indices
241 auto initializeScriptIdx = -1;
242 auto nothingScriptIdx = -1;
243 {
244 auto scriptIdx = 0;
245 for (auto& script: scripts) {
246 //
247 if (StringTools::regexMatch(script.condition, "[a-zA-Z0-9]+") == true) {
248 if (script.condition == "nothing") nothingScriptIdx = scriptIdx;
249 if (script.condition == "initialize") initializeScriptIdx = scriptIdx;
250 }
251 //
252 scriptIdx++;
253 }
254 }
255
256 //
257 string miniScriptClassName = Tools::removeFileEnding(Tools::getFileName(miniscriptTranspilationFileName));
258 string generatedDeclarations = "\n";
259 generatedDeclarations+= string() + "public:" + "\n";
260 generatedDeclarations+= headerIndent + "// overridden methods" + "\n";
261 generatedDeclarations+= headerIndent + "void emit(const string& condition) override;" + "\n";
262 generatedDeclarations+= headerIndent + "inline void startScript() override {" + "\n";
263 generatedDeclarations+= headerIndent + "\t" + "if (native == false) {" + "\n";
264 generatedDeclarations+= headerIndent + "\t" + "\t" + "MiniScript::startScript();" + "\n";
265 generatedDeclarations+= headerIndent + "\t" + "\t" + "return;" + "\n";
266 generatedDeclarations+= headerIndent + "\t" + "}" + "\n";
267 generatedDeclarations+= headerIndent + "\t" + "for (auto& scriptVariableIt: scriptState.variables) delete scriptVariableIt.second;" + "\n";
268 generatedDeclarations+= headerIndent + "\t" + "scriptState.variables.clear();" + "\n";
269 generatedDeclarations+= headerIndent + "\t" + "scriptState.running = true;" + "\n";
270 generatedDeclarations+= headerIndent + "\t" + "registerVariables();" + "\n";
271 generatedDeclarations+= headerIndent + "\t" + "resetScriptExecutationState(" + to_string(initializeScriptIdx) + ", STATE_NEXT_STATEMENT);" + "\n";
272 generatedDeclarations+= headerIndent + "}" + "\n";
273 generatedDeclarations+= headerIndent + "inline void execute() override {" + "\n";
274 generatedDeclarations+= headerIndent + "\t" + "if (native == false) {" + "\n";
275 generatedDeclarations+= headerIndent + "\t" + "\t" + "MiniScript::execute();" + "\n";
276 generatedDeclarations+= headerIndent + "\t" + "\t" + "return;" + "\n";
277 generatedDeclarations+= headerIndent + "\t" + "}" + "\n";
278 generatedDeclarations+= headerIndent + "\t" + "if (scriptState.running == false) return;" + "\n";
279 generatedDeclarations+= headerIndent + "\t" + "// execute while having statements to be processed" + "\n";
280 generatedDeclarations+= headerIndent + "\t" + "if (scriptState.state.state == STATE_NEXT_STATEMENT) {" + "\n";
281 generatedDeclarations+= generatedExecuteCode;
282 generatedDeclarations+= headerIndent + "\t" + "}" + "\n";
283 generatedDeclarations+= headerIndent + "\t" + "if (scriptState.running == false) return;" + "\n";
284 generatedDeclarations+= headerIndent + "\t" + "executeStateMachine();" + "\n";
285 generatedDeclarations+= headerIndent + "};" + "\n";
286 generatedDeclarations+= "\n";
287 generatedDeclarations+= string() + "protected:" + "\n";
288 generatedDeclarations+= headerIndent + "// overridden methods" + "\n";
289 generatedDeclarations+= headerIndent + "void initializeNative() override;" + "\n";
290 generatedDeclarations+= headerIndent + "int determineScriptIdxToStart() override;" + "\n";
291 generatedDeclarations+= headerIndent + "int determineNamedScriptIdxToStart() override;" + "\n";
292 generatedDeclarations+= "\n";
293
294 //
295 string emitDefinition;
296 emitDefinition+= "void " + miniScriptClassName + "::emit(const string& condition) {" + "\n";
297 emitDefinition+= methodCodeIndent + "if (native == false) {" + "\n";
298 emitDefinition+= methodCodeIndent + "\t" + "MiniScript::emit(condition);" + "\n";
299 emitDefinition+= methodCodeIndent + "\t" + "return;" + "\n";
300 emitDefinition+= methodCodeIndent + "}" + "\n";
301 string generatedDefinitions = "\n";
302 string initializeNativeDefinition;
303 initializeNativeDefinition+= "void " + miniScriptClassName + "::initializeNative() {" + "\n";
304 initializeNativeDefinition+= methodCodeIndent + "setNative(true);" + "\n";
305 initializeNativeDefinition+= methodCodeIndent + "setHash(\"" + scriptInstance->getHash() + "\");" + "\n";
306 initializeNativeDefinition+= methodCodeIndent + "setNativeScripts(" + "\n";
307 initializeNativeDefinition+= methodCodeIndent + "\t" + "{" + "\n";
308 {
309 auto scriptIdx = 0;
310 for (auto& script: scripts) {
311 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "{" + "\n";
312 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + ".conditionType = " + (script.conditionType == MiniScript::Script::CONDITIONTYPE_ON?"Script::CONDITIONTYPE_ON":"Script::CONDITIONTYPE_ONENABLED") + "," + "\n";
313 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + ".line = " + to_string(script.line) + "," + "\n";
314 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + ".condition = \"" + StringTools::replace(script.condition, "\"", "\\\"") + "\"," + "\n";
315 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + ".name = \"" + script.name + "\"," + "\n";
316 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + ".emitCondition = " + (script.emitCondition == true?"true":"false") + "," + "\n";
317 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + ".statements = {" + "\n";
318 auto statementIdx = 0;
319 for (auto& statement: script.statements) {
320 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + "\t" + "{" + "\n";
321 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + "\t" + "\t" + ".line = " + to_string(statement.line) + "," + "\n";
322 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + "\t" + "\t" + ".statementIdx = " + to_string(statement.statementIdx) + "," + "\n";
323 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + "\t" + "\t" + ".statement = \"" + StringTools::replace(statement.statement, "\"", "\\\"") + "\"," + "\n";
324 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + "\t" + "\t" + ".gotoStatementIdx = " + to_string(statement.gotoStatementIdx) + "\n";
325 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + "\t" + "}" + (statementIdx < script.statements.size() - 1?",":"") + "\n";
326 statementIdx++;
327 }
328 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "\t" + "}" + "\n";
329 initializeNativeDefinition+= methodCodeIndent + "\t" + "\t" + "}" + (scriptIdx < scripts.size() - 1?",":"") + "\n";
330 scriptIdx++;
331 }
332 }
333 initializeNativeDefinition+= methodCodeIndent + "\t" + "}" + "\n";
334 initializeNativeDefinition+= methodCodeIndent + ");" + "\n";
335 initializeNativeDefinition+= string() + "}" + "\n";
336
337 //
338 string generatedDetermineScriptIdxToStartDefinition = "\n";
339 generatedDetermineScriptIdxToStartDefinition+= "int " + miniScriptClassName + "::determineScriptIdxToStart() {" + "\n";
340 generatedDetermineScriptIdxToStartDefinition+= string() + "\t" + "if (native == false) return MiniScript::determineScriptIdxToStart();" + "\n";
341 generatedDetermineScriptIdxToStartDefinition+= string() + "\t" + "auto miniScript = this;" + "\n";
342 string generatedDetermineNamedScriptIdxToStartDefinition = "\n";
343 generatedDetermineNamedScriptIdxToStartDefinition+= "int " + miniScriptClassName + "::determineNamedScriptIdxToStart() {" + "\n";
344 generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\t" + "if (native == false) return MiniScript::determineNamedScriptIdxToStart();" + "\n";
345 generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\t" + "auto miniScript = this;" + "\n";
346 generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\t" + "for (auto& enabledNamedCondition: scriptState.enabledNamedConditions) {" + "\n";
347 {
348 auto scriptIdx = 0;
349 for (auto& script: scripts) {
350 // method name
351 string methodName =
352 (script.conditionType == MiniScript::Script::CONDITIONTYPE_ON?"on_":"on_enabled_") +
353 (script.name.empty() == false?script.name:(
354 StringTools::regexMatch(script.condition, "[a-zA-Z0-9]+") == true?
355 script.condition:
356 to_string(scriptIdx)
357 )
358 );
359
360 string emitName =
361 (script.name.empty() == false?script.name:(
362 StringTools::regexMatch(script.condition, "[a-zA-Z0-9]+") == true?
363 script.condition:
364 to_string(scriptIdx)
365 )
366 );
367
368 // emit code
369 if (script.conditionType == MiniScript::Script::CONDITIONTYPE_ON && StringTools::regexMatch(script.condition, "[a-zA-Z0-9]+") == true) {
370 string emitDefinitionIndent = "\t";
371 emitDefinition+= emitDefinitionIndent + "if (condition == \"" + emitName + "\") {" + "\n";
372 emitDefinition+= emitDefinitionIndent + "\t" + methodName + "(-1);" + "\n";
373 emitDefinition+= emitDefinitionIndent + "\t" + "return;" + "\n";
374 emitDefinition+= emitDefinitionIndent + "}" + "\n";
375 }
376
377 // declaration
378 generatedDeclarations+= headerIndent + "/**" + "\n";
379 generatedDeclarations+= headerIndent + " * Miniscript transpilation of: " + (script.conditionType == MiniScript::Script::CONDITIONTYPE_ON?"ON":"ON-ENABLED") + ": " + script.condition + (script.name.empty() == false?" (" + script.name + ")":"") + "\n";
380 generatedDeclarations+= headerIndent + " * @param miniScriptGotoStatementIdx MiniScript goto statement index" + "\n";
381 generatedDeclarations+= headerIndent + " */" + "\n";
382 generatedDeclarations+= headerIndent + "void " + methodName + "(int miniScriptGotoStatementIdx);" + "\n";
383 generatedDeclarations+= "\n";
384
385 // transpile definition
386 generatedDefinitions+= "void " + miniScriptClassName + "::" + methodName + "(int miniScriptGotoStatementIdx) {" + "\n";
387 string generatedSubCode;
388 scriptInstance->transpile(generatedSubCode, scriptIdx, methodCodeMap);
389 generatedDefinitions+= generatedSubCode;
390 generatedDefinitions+= string() + "}" + "\n\n";
391
392 //
393 if (StringTools::regexMatch(script.condition, "[a-zA-Z0-9]+") == false) {
394 if (script.conditionType == MiniScript::Script::CONDITIONTYPE_ONENABLED) {
395 generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\n";
396 generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\t" + "\t" + "// next statements belong to tested enabled named condition with name \"" + script.name + "\"" + "\n";
397 generatedDetermineNamedScriptIdxToStartDefinition+= string() + "\t" + "\t" + "if (enabledNamedCondition == \"" + script.name + "\")" + "\n";
398 }
399 scriptInstance->transpileScriptCondition(
400 script.conditionType == MiniScript::Script::CONDITIONTYPE_ON?generatedDetermineScriptIdxToStartDefinition:generatedDetermineNamedScriptIdxToStartDefinition,
401 scriptIdx,
402 methodCodeMap,
403 "-1",
404 "bool returnValueBool; returnValue.getBooleanValue(returnValueBool); if (returnValueBool == true) return " + to_string(scriptIdx) + ";",
405 script.conditionType == MiniScript::Script::CONDITIONTYPE_ONENABLED?1:0
406 );
407 }
408
409 //
410 scriptIdx++;
411 }
412 }
413
414 //
415 generatedDetermineScriptIdxToStartDefinition+= "\n";
416 generatedDetermineScriptIdxToStartDefinition+= methodCodeIndent + "//" + "\n";
417 generatedDetermineScriptIdxToStartDefinition+= methodCodeIndent + "return " + to_string(nothingScriptIdx) + ";" + "\n";
418 generatedDetermineScriptIdxToStartDefinition+= string() + "}" + "\n";
419 //
420 generatedDetermineNamedScriptIdxToStartDefinition+= methodCodeIndent + "}" + "\n";
421 generatedDetermineNamedScriptIdxToStartDefinition+= "\n";
422 generatedDetermineNamedScriptIdxToStartDefinition+= methodCodeIndent + "//" + "\n";
423 generatedDetermineNamedScriptIdxToStartDefinition+= methodCodeIndent + "return -1;" + "\n";
424 generatedDetermineNamedScriptIdxToStartDefinition+= string() + "}" + "\n";
425
426 //
427 emitDefinition+= string() + "}" + "\n";
428
429 // add emit code
430 generatedDefinitions = initializeNativeDefinition + generatedDetermineScriptIdxToStartDefinition + generatedDetermineNamedScriptIdxToStartDefinition + "\n" + emitDefinition + generatedDefinitions;
431
432 // inject C++ definition code
433 {
434 vector<string> miniScriptClass;
435 vector<string> miniScriptClassNew;
436 FileSystem::getInstance()->getContentAsStringArray(Tools::getPathName(miniscriptTranspilationFileName), Tools::getFileName(miniscriptTranspilationFileName), miniScriptClass);
437 auto reject = false;
438 auto injectedGeneratedCode = false;
439 for (auto i = 0; i < miniScriptClass.size(); i++) {
440 auto& line = miniScriptClass[i];
441 auto trimmedLine = StringTools::trim(line);
442 if (StringTools::startsWith(trimmedLine, "//") == true) {
443 if (reject == false) miniScriptClassNew.push_back(line);
444 continue;
445 }
446 if (trimmedLine == "/*__MINISCRIPT_TRANSPILEDMINISCRIPTCODE_DEFINITIONS_START__*/") {
447 reject = true;
448 miniScriptClassNew.push_back(line);
449 } else
450 if (trimmedLine == "/*__MINISCRIPT_TRANSPILEDMINISCRIPTCODE_DEFINITIONS_END__*/") {
451 reject = false;
452 injectedGeneratedCode = true;
453 miniScriptClassNew.push_back(generatedDefinitions);
454 miniScriptClassNew.push_back(line);
455 } else {
456 if (reject == false) miniScriptClassNew.push_back(line);
457 }
458 }
459
460 //
461 if (injectedGeneratedCode == false) {
462 Console::println(scriptFileName + ": Could not inject generated C++ code, are you missing the /*__MINISCRIPT_TRANSPILEDMINISCRIPTCODE_DEFINITIONS_START__*/ and /*__MINISCRIPT_TRANSPILEDMINISCRIPTCODE_DEFINITIONS_END__*/ markers in file " + miniscriptTranspilationFileName + "?");
463 } else {
464 //
465 FileSystem::getInstance()->setContentFromStringArray(
466 Tools::getPathName(miniscriptTranspilationFileName),
467 Tools::getFileName(miniscriptTranspilationFileName),
468 miniScriptClassNew
469 );
470 //
471 Console::println(scriptFileName + ": Injected generated C++ code in file " + miniscriptTranspilationFileName + ". Dont forget to rebuild your sources.");
472 }
473 }
474
475 //
476 // inject C++ declaration code / header
477 {
478 vector<string> miniScriptClassHeader;
479 vector<string> miniScriptClassHeaderNew;
480 auto miniscriptTranspilationHeaderFileName = Tools::getPathName(miniscriptTranspilationFileName) + "/" + Tools::removeFileEnding(Tools::getFileName(miniscriptTranspilationFileName)) + ".h";
481 FileSystem::getInstance()->getContentAsStringArray(Tools::getPathName(miniscriptTranspilationHeaderFileName), Tools::getFileName(miniscriptTranspilationHeaderFileName), miniScriptClassHeader);
482 auto reject = false;
483 auto injectedGeneratedCode = false;
484 for (auto i = 0; i < miniScriptClassHeader.size(); i++) {
485 auto& line = miniScriptClassHeader[i];
486 auto trimmedLine = StringTools::trim(line);
487 if (StringTools::startsWith(trimmedLine, "//") == true) {
488 if (reject == false) miniScriptClassHeaderNew.push_back(line);
489 continue;
490 }
491 if (trimmedLine == "/*__MINISCRIPT_TRANSPILEDMINISCRIPTCODE_DECLARATIONS_START__*/") {
492 reject = true;
493 miniScriptClassHeaderNew.push_back(line);
494 } else
495 if (trimmedLine == "/*__MINISCRIPT_TRANSPILEDMINISCRIPTCODE_DECLARATIONS_END__*/") {
496 reject = false;
497 injectedGeneratedCode = true;
498 miniScriptClassHeaderNew.push_back(generatedDeclarations);
499 miniScriptClassHeaderNew.push_back(line);
500 } else {
501 if (reject == false) miniScriptClassHeaderNew.push_back(line);
502 }
503 }
504
505 //
506 if (injectedGeneratedCode == false) {
507 Console::println(scriptFileName + ": Could not inject generated C++ code, are you missing the /*__MINISCRIPT_TRANSPILEDMINISCRIPTCODE_DECLARATIONS_START__*/ and /*__MINISCRIPT_TRANSPILEDMINISCRIPTCODE_DECLARATIONS_END__*/ markers in file " + miniscriptTranspilationFileName + "?");
508 } else {
509 //
510 FileSystem::getInstance()->setContentFromStringArray(
511 Tools::getPathName(miniscriptTranspilationHeaderFileName),
512 Tools::getFileName(miniscriptTranspilationHeaderFileName),
513 miniScriptClassHeaderNew
514 );
515 //
516 Console::println(scriptFileName + ": Injected generated C++ code in header file " + miniscriptTranspilationHeaderFileName + ". Dont forget to rebuild your sources.");
517 }
518 }
519}
520
521int main(int argc, char** argv)
522{
523 Console::println(string("miniscripttranspiler ") + Version::getVersion());
524 Console::println(Version::getCopyright());
525 Console::println();
526
527 //
528 if (argc < 3) {
529 Console::println("Usage: miniscripttranspiler path_to_script_file path_to_cpp_miniscript_transpilation_file [path_to_cpp_miniscript_extension_file1] [path_to_cpp_miniscript_extension_fileN]");
530 Application::exit(1);
531 }
532
533 vector<string> miniScriptExtensionFileNames;
534 for (auto i = 3; i < argc; i++) miniScriptExtensionFileNames.push_back(argv[i]);
535
536 //
537 processFile(argv[1], argv[2], miniScriptExtensionFileNames);
538}
Application base class, please make sure to allocate application on heap to have correct application ...
Definition: Application.h:37
File system singleton class.
Definition: FileSystem.h:14
Console class.
Definition: Console.h:26
Integer class.
Definition: Integer.h:26
bool transpile(string &generatedCode, int scriptIdx, const unordered_map< string, vector< string > > &methodCodeMap)
Transpile a script statement.
void loadScript(const string &pathName, const string &fileName)
Load script.
Definition: MiniScript.cpp:481
const string & getHash()
Definition: MiniScript.h:955
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.
const string getInformation()
Get miniscript instance information.
const vector< Script > & getScripts()
Definition: MiniScript.h:962
String tools class.
Definition: StringTools.h:20
int main(int argc, char **argv)
void gatherMethodCode(const vector< string > &miniScriptExtensionsCode, const string &className, int registerLine, unordered_map< string, vector< string > > &methodCodeMap)
void processFile(const string &scriptFileName, const string &miniscriptTranspilationFileName, const vector< string > &miniScriptExtensionFileNames)
std::exception Exception
Exception base class.
Definition: Exception.h:19