NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
procedurevarfactory.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2017 Erik Haenel et al.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17******************************************************************************/
18
19
21#include "procedure.hpp"
22#include "../../kernel.hpp"
23
24using namespace std;
25
37static bool containsFreeOperators(const string& sString)
38{
39 size_t nQuotes = 0;
40 static string sOperators = "+-*/&|?!^<>=";
41
42 for (size_t i = 0; i < sString.length(); i++)
43 {
44 if (sString[i] == '"' && (!i || sString[i-1] != '\\'))
45 nQuotes++;
46
47 if (nQuotes % 2)
48 continue;
49
50 if (sString[i] == '(' || sString[i] == '[' || sString[i] == '{')
51 {
52 size_t nMatch;
53
54 if ((nMatch = getMatchingParenthesis(sString.substr(i))) != string::npos)
55 i += nMatch;
56 }
57 else if (sOperators.find(sString[i]) != string::npos)
58 return true;
59 }
60
61 return false;
62}
63
64
69{
70 init();
71}
72
73
84ProcedureVarFactory::ProcedureVarFactory(Procedure* _procedure, const string& sProc, unsigned int currentProc, bool _inliningMode)
85{
86 init();
87 _currentProcedure = _procedure;
88
89 sProcName = sProc;
90 nth_procedure = currentProc;
91 inliningMode = _inliningMode;
92}
93
94
99{
100 reset();
101}
102
103
112{
113 _currentProcedure = nullptr;
114
115 // Get the addresses of the kernel objects
123
124 sProcName = "";
125 nth_procedure = 0;
126
127 inliningMode = false;
128 sInlineVarDef.clear();
129 sInlineStringDef.clear();
130}
131
132
145{
146 // Clear the local copies of the arguments
147 if (mLocalArgs.size())
148 {
149 for (auto iter : mLocalArgs)
150 {
151 if (iter.second == NUMTYPE)
152 _parserRef->RemoveVar(iter.first);
153 else if (iter.second == STRINGTYPE)
155 else if (iter.second == CLUSTERTYPE)
156 _dataRef->removeCluster(iter.first.substr(0, iter.first.find('{')));
157 else if (iter.second == TABLETYPE)
158 _dataRef->deleteTable(iter.first.substr(0, iter.first.find('(')));
159 }
160
161 mLocalArgs.clear();
162 }
163
164 if (mLocalVars.size())
165 {
166 for (auto iter : mLocalVars)
167 {
168 if (_parserRef)
169 _parserRef->RemoveVar(iter.second.first);
170
171 // Deleting a nullptr is harmless
172 delete iter.second.second;
173 }
174
175 mLocalVars.clear();
176 }
177
178 if (mLocalStrings.size())
179 {
180 for (auto iter : mLocalStrings)
182
183 mLocalStrings.clear();
184 }
185
186 if (mLocalTables.size())
187 {
188 for (auto iter : mLocalTables)
189 _dataRef->deleteTable(iter.second);
190
191 mLocalTables.clear();
192 }
193
194 if (mLocalClusters.size())
195 {
196 for (auto iter : mLocalClusters)
197 _dataRef->removeCluster(iter.second);
198
199 mLocalClusters.clear();
200 }
201
202 sInlineVarDef.clear();
203 sInlineStringDef.clear();
204 vInlineArgDef.clear();
205
206 mArguments.clear();
207}
208
209
221bool ProcedureVarFactory::delayDeletionOfReturnedTable(const std::string& sTableName)
222{
223 // Search for a corresponding local table
224 for (auto iter = mLocalTables.begin(); iter != mLocalTables.end(); ++iter)
225 {
226 if (iter->second == sTableName)
227 {
228 mLocalTables.erase(iter);
229 return true;
230 }
231 }
232
233 // Sarch for a corresponding local argument table
234 auto iter = mLocalArgs.find(sTableName);
235
236 if (iter != mLocalArgs.end() && iter->second == TABLETYPE)
237 {
238 mLocalArgs.erase(iter);
239 return true;
240 }
241
242 return false;
243}
244
245
255bool ProcedureVarFactory::isReference(const std::string& sArgName) const
256{
257 return mLocalArgs.find(sArgName) == mLocalArgs.end();
258}
259
260
270string ProcedureVarFactory::replaceProcedureName(string sProcedureName) const
271{
272 for (size_t i = 0; i < sProcedureName.length(); i++)
273 {
274 if (sProcedureName[i] == ':' || sProcedureName[i] == '\\' || sProcedureName[i] == '/' || sProcedureName[i] == ' ')
275 sProcedureName[i] = '_';
276 }
277
278 return sProcedureName;
279}
280
281
289std::string ProcedureVarFactory::createMangledArgName(const std::string& sDefinedName) const
290{
291 return "_~"+sProcName+"_~A_"+toString((int)nth_procedure)+"_"+sDefinedName;
292}
293
294
302std::string ProcedureVarFactory::createMangledVarName(const std::string& sDefinedName) const
303{
304 return "_~"+sProcName+"_"+toString((int)nth_procedure)+"_"+sDefinedName;
305}
306
307
319unsigned int ProcedureVarFactory::countVarListElements(const string& sVarList)
320{
321 int nParenthesis = 0;
322 unsigned int nElements = 1;
323
324 // Count every comma, which is not part of a parenthesis and
325 // also not between two quotation marks
326 for (unsigned int i = 0; i < sVarList.length(); i++)
327 {
328 if ((sVarList[i] == '(' || sVarList[i] == '{') && !isInQuotes(sVarList, i))
329 nParenthesis++;
330
331 if ((sVarList[i] == ')' || sVarList[i] == '}') && !isInQuotes(sVarList, i))
332 nParenthesis--;
333
334 if (sVarList[i] == ',' && !nParenthesis && !isInQuotes(sVarList, i))
335 nElements++;
336 }
337
338 return nElements;
339}
340
341
355void ProcedureVarFactory::checkArgument(const string& sArgument, const string& sArgumentList, unsigned int nCurrentIndex)
356{
357 string sCommand = findCommand(sArgument).sString;
358
359 // Was a keyword used as a argument?
360 if (sCommand == "var" || sCommand == "tab" || sCommand == "str" || sCommand == "cst")
361 {
362 // Free up memory
363 mArguments.clear();
364
366 // Gather all information in the debugger and throw
367 // the exception
369 _debugger.throwException(SyntaxError(SyntaxError::WRONG_ARG_NAME, "$" + sProcName + "(" + sArgumentList + ")", SyntaxError::invalid_position, sCommand));
370 }
371
372 // Copy the argument to avoid an segmentation violation due to the deletion
373 sCommand = sArgument.substr(0, sArgument.find('='));
374
375 // Check for invalid argument names
376 if (!checkSymbolName(sCommand))
377 {
378 // Free up memory
379 mArguments.clear();
380
382 // Gather all information in the debugger and throw
383 // the exception
385 _debugger.throwException(SyntaxError(SyntaxError::INVALID_SYM_NAME, "$" + sProcName + "(" + sArgumentList + ")", SyntaxError::invalid_position, sCommand));
386 }
387}
388
389
402void ProcedureVarFactory::checkArgumentValue(const string& sArgument, const string& sArgumentList, unsigned int nCurrentIndex)
403{
404 string sCommand = findCommand(sArgument).sString;
405
406 // Was a keyword used as a argument?
407 if (sCommand == "var" || sCommand == "tab" || sCommand == "str")
408 {
409 // Free up memory
410 mArguments.clear();
411
413 // Gather all information in the debugger and throw
414 // the exception
416 _debugger.throwException(SyntaxError(SyntaxError::WRONG_ARG_NAME, "$" + sProcName + "(" + sArgumentList + ")", SyntaxError::invalid_position, sCommand));
417 }
418}
419
420
429bool ProcedureVarFactory::checkSymbolName(const std::string& sSymbolName) const
430{
431 return sSymbolName.length() && !isdigit(sSymbolName[0]) && toLowerCase(sSymbolName).find_first_not_of(" abcdefghijklmnopqrstuvwxyz1234567890_(){}&") == std::string::npos;
432}
433
434
446{
448
449 // Get the number of declared variables
450 size_t nLocalVarMapSize = countVarListElements(sVarList);
451
452 // Create a new temporary cluster
453 string sTempCluster = _dataRef->createTemporaryCluster("var");
454 sInlineVarDef = sTempCluster + " = {";
455
456 sTempCluster.erase(sTempCluster.length()-2);
457
458 // Get a reference to the temporary cluster
459 NumeRe::Cluster& tempCluster = _dataRef->getCluster(sTempCluster);
460
461 // Decode the variable list
462 for (unsigned int i = 0; i < nLocalVarMapSize; i++)
463 {
464 std::string currentDef = getNextArgument(sVarList, true);
465
466 // Fill in the value of the variable by either
467 // using the default or the explicit passed value
468 if (currentDef.find('=') != string::npos)
469 {
470 string sVarValue = currentDef.substr(currentDef.find('=')+1);
471 sInlineVarDef += sVarValue + ",";
472
473 if (sVarValue.find('$') != string::npos && sVarValue.find('(') != string::npos)
474 {
477 }
478
479 try
480 {
481 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sVarValue))
482 {
483 string sTemp;
484 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sVarList, sTemp, true);
485 }
486
487 if (_dataRef->containsTablesOrClusters(sVarValue))
488 {
490 }
491
492 sVarValue = resolveLocalVars(sVarValue, i);
493
494 _parserRef->SetExpr(sVarValue);
495 currentDef.erase(currentDef.find('='));
496 tempCluster.setDouble(i, _parserRef->Eval());
497 }
498 catch (...)
499 {
501 _debugger.showError(current_exception());
502 throw;
503 }
504 }
505 else
506 {
507 tempCluster.setDouble(i, 0.0);
508 sInlineVarDef += "0,";
509 }
510
511 StripSpaces(currentDef);
512 std::string currentVar = sTempCluster + "{" + toString(i+1) + "}";
513
514 mLocalVars[currentDef] = std::make_pair(currentVar, nullptr);
515 }
516
517 sInlineVarDef.back() = '}';
518}
519
520
533{
535
536 // Get the number of declared variables
537 size_t nLocalStrMapSize = countVarListElements(sStringList);
538
539 // Create a new temporary cluster
540 string sTempCluster = _dataRef->createTemporaryCluster("str");
541 sInlineStringDef = sTempCluster + " = {";
542 sTempCluster.erase(sTempCluster.length()-2);
543
544 // Get a reference to the temporary cluster
545 NumeRe::Cluster& tempCluster = _dataRef->getCluster(sTempCluster);
546
547 // Decode the variable list
548 for (unsigned int i = 0; i < nLocalStrMapSize; i++)
549 {
550 std::string currentDef = getNextArgument(sStringList, true);
551 std::string sVarValue;
552
553 // Fill in the value of the variable by either
554 // using the default or the explicit passed value
555 if (currentDef.find('=') != string::npos)
556 {
557 sVarValue = currentDef.substr(currentDef.find('=')+1);
558 sInlineStringDef += sVarValue + ",";
559
560 if (sVarValue.find('$') != string::npos && sVarValue.find('(') != string::npos)
561 {
563
564 mLocalStrings.clear();
565 nLocalStrMapSize = 0;
566
568 }
569
570 try
571 {
572 sVarValue = resolveLocalStrings(sVarValue, i);
573
574 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sVarValue))
575 {
576 string sTemp;
577 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sVarValue, sTemp, true);
578 }
579
580 currentDef.erase(currentDef.find('='));
581 tempCluster.setString(i, toInternalString(sVarValue));
582 }
583 catch (...)
584 {
586
587 mLocalStrings.clear();
588 nLocalStrMapSize = 0;
589
590 _debugger.showError(current_exception());
591 throw;
592 }
593 }
594 else
595 {
596 tempCluster.setString(i, "");
597 sInlineStringDef += "\"\",";
598 }
599
600 StripSpaces(currentDef);
601 mLocalStrings[currentDef] = std::make_pair(sTempCluster + "{" + toString(i+1) + "}", sVarValue);
602 }
603
604 sInlineStringDef.back() = '}';
605}
606
607
617map<string,string> ProcedureVarFactory::createProcedureArguments(string sArgumentList, string sArgumentValues)
618{
619 map<string,string> mVarMap;
621
622 if (!sArgumentList.length() && sArgumentValues.length())
623 {
624 if (_optionRef->useDebugger())
625 _debugger.popStackItem();
626
628 }
629 else if (!sArgumentList.length())
630 return mVarMap;
631
632 if (!validateParenthesisNumber(sArgumentList))
633 {
636 }
637
638 // Get the number of argument of this procedure
639 size_t nArgumentMapSize = countVarListElements(sArgumentList);
640
641 std::string sArgListBack = sArgumentList;
642
643 // Decode the argument list
644 for (unsigned int i = 0; i < nArgumentMapSize; i++)
645 {
646 std::string currentArg = getNextArgument(sArgumentList);
647 StripSpaces(currentArg);
648
649 checkArgument(currentArg, sArgListBack, i);
650
651 // Fill in the value of the argument by either
652 // using the default value or the passed value
653 std::string currentValue = getNextArgument(sArgumentValues);
654 StripSpaces(currentValue);
655
656 checkArgumentValue(currentValue, sArgListBack, i);
657
658 if (currentValue.length() && currentArg.find('=') != string::npos)
659 {
660 currentArg.erase(currentArg.find('='));
661 StripSpaces(currentArg);
662 }
663 else if (!currentValue.length() && currentArg.find('=') != string::npos)
664 {
665 currentValue = currentArg.substr(currentArg.find('=')+1);
666 currentArg.erase(currentArg.find('='));
667 StripSpaces(currentArg);
668 StripSpaces(currentValue);
669 }
670 else if (!currentValue.length() && currentArg.find('=') == string::npos)
671 {
672 string sErrorToken = currentArg;
673 nArgumentMapSize = 0;
674
675 if (_optionRef->useDebugger())
676 _debugger.popStackItem();
677
679 }
680
681 if (containsFreeOperators(currentValue))
682 currentValue = "(" + currentValue + ")";
683
684 // Evaluate procedure calls and the parentheses of the
685 // passed tables and clusters
686 evaluateProcedureArguments(currentArg, currentValue, sArgListBack);
687 }
688
689
690 mVarMap.insert(mArguments.begin(), mArguments.end());
691 return mVarMap;
692}
693
694
705static bool isCompleteCluster(StringView sArgumentValue, MemoryManager* _dataRef)
706{
707 size_t pos = sArgumentValue.find('{');
708
709 return _dataRef->isCluster(sArgumentValue) && (sArgumentValue.subview(pos, 2) == "{}" || sArgumentValue.subview(pos, 3) == "{:}");
710}
711
712
723static bool isCompleteTable(StringView sArgumentValue, MemoryManager* _dataRef)
724{
725 size_t pos = sArgumentValue.find('(');
726
727 return _dataRef->isTable(sArgumentValue.to_string()) && (sArgumentValue.subview(pos, 2) == "()"
728 || sArgumentValue.subview(pos, 3) == "(:)"
729 || sArgumentValue.subview(pos, 5) == "(:,:)");
730}
731
732
744void ProcedureVarFactory::evaluateProcedureArguments(std::string& currentArg, std::string& currentValue, const std::string& sArgumentList)
745{
750
751 // Evaluate procedure calls first (but not for tables)
752 if (currentValue.find('$') != string::npos
753 && currentValue.find('(') != string::npos
754 && currentArg.substr(currentArg.length()-2) != "()")
755 {
757 {
760 }
761
763
764 if (nReturn == FlowCtrl::INTERFACE_ERROR)
765 {
768 }
769 else if (nReturn == FlowCtrl::INTERFACE_EMPTY)
770 currentValue = "false";
771 }
772
773 bool isRef = currentArg.front() == '&' || currentArg.back() == '&';
774
775 // Determine, if this is a reference (and
776 // remove the ampersand in this case)
777 if (isRef)
778 {
779 currentArg.erase(currentArg.find('&'), 1);
780 StripSpaces(currentArg);
781 }
782
783 if (currentArg.length() > 2 && currentArg.substr(currentArg.length()-2) == "()")
784 {
785 currentArg.pop_back();
786
787#warning TODO (numere#1#02/27/22): This behavior will be deprecated with v1.1.5
789 {
790 isRef = true;
792 + ": " + _lang.get("PROCEDURE_WARN_TABLE_REFERENCE"));
793 }
794
795 if (isRef)
796 {
797 if (!isCompleteTable(currentValue, _dataRef))
798 {
800 _debugger.throwException(SyntaxError(SyntaxError::CANNOT_PASS_LITERAL_PER_REFERENCE, currentValue, "", currentArg + ")"));
801 }
802
803 if (currentValue.find('(') != string::npos)
804 currentValue.erase(currentValue.find('('));
805 }
806 else if (!isRef && !isMacro) // Macros do the old copy-paste logic
807 {
808#warning TODO (numere#1#02/27/22): This behavior will be deprecated with v1.1.5
811 throw SyntaxError(SyntaxError::INLINE_PROCEDURE_NEEDS_TABLE_REFERENCES, currentValue, "", currentArg + ")");
812
813 // Create a local variable
814 std::string sNewArgName = "_~"+sProcName+"_~A_"+toString((int)nth_procedure)+"_"+currentArg.substr(0, currentArg.length()-1);
815
816 // Evaluate procedure calls first
817 if (currentValue.find('$') != string::npos
818 && currentValue.find('(') != string::npos)
819 {
821 {
824 }
825
826 currentValue.insert(0, sNewArgName + "() = ");
828
829 if (nReturn == FlowCtrl::INTERFACE_ERROR)
830 {
833 }
834 else if (nReturn == FlowCtrl::INTERFACE_EMPTY)
835 currentValue = "false";
836 else
837 {
838 if (currentValue.substr(0, sNewArgName.length()+5) != sNewArgName+"() = ")
839 {
840 currentValue = sNewArgName;
841 mLocalArgs[sNewArgName] = TABLETYPE;
842 mArguments[currentArg] = currentValue;
843 return;
844 }
845 else
846 currentValue.erase(0, sNewArgName.length()+5);
847 }
848 }
849
850 if (isCompleteTable(currentValue, _dataRef))
851 _dataRef->copyTable(currentValue.substr(0, currentValue.find('(')), sNewArgName);
852 else
853 {
854 // Evaluate the expression and create a new
855 // table
856 try
857 {
858 std::string sCurrentValue = currentValue;
859 _dataRef->addTable(sNewArgName, *_optionRef);
860
861 if (_dataRef->containsTablesOrClusters(sCurrentValue))
862 getDataElements(sCurrentValue, *_parserRef, *_dataRef, *_optionRef, false);
863
864 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sCurrentValue))
865 {
866 std::string sTable = sNewArgName + "(:,1)";
867 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sCurrentValue, sTable, true);
868 }
869 else
870 {
871 mu::value_type* v = nullptr;
872 int nResults;
873 _parserRef->SetExpr(sCurrentValue);
874 v = _parserRef->Eval(nResults);
875 Indices _idx;
877 _idx.col = VectorIndex(0);
878 _dataRef->writeToTable(_idx, sNewArgName, v, nResults);
879 }
880 }
881 catch (...)
882 {
884 _debugger.showError(current_exception());
885
886 if (_dataRef->isTable(sNewArgName))
887 _dataRef->deleteTable(sNewArgName);
888
889 throw;
890 }
891 }
892
893 // Tables have to be stored as names without
894 // their braces
895 currentValue = sNewArgName;
896 mLocalArgs[sNewArgName] = TABLETYPE;
897 }
898 else if (inliningMode) // Only for checking, whether the table is a reference
899 {
900 #warning TODO (numere#1#02/27/22): This behavior will be deprecated with v1.1.5
902 throw SyntaxError(SyntaxError::INLINE_PROCEDURE_NEEDS_TABLE_REFERENCES, currentValue, "", currentArg + ")");
903 }
904 }
905 else if (currentArg.length() > 2 && currentArg.substr(currentArg.length()-2) == "{}")
906 {
907 currentArg.pop_back();
908
909 if (isRef && !isCompleteCluster(currentValue, _dataRef))
910 {
912 _debugger.throwException(SyntaxError(SyntaxError::CANNOT_PASS_LITERAL_PER_REFERENCE, currentValue, "", currentArg));
913 }
914 else if (!isRef && !isMacro) // Macros do the old copy-paste logic
915 {
916 // Create a local variable
917 std::string sNewArgName = "_~"+sProcName+"_~A_"+toString((int)nth_procedure)+"_"+currentArg.substr(0, currentArg.length()-1);
918 NumeRe::Cluster& newCluster = _dataRef->newCluster(sNewArgName);
919
920 // Copy, if it is already a (complete!) cluster
921 if (isCompleteCluster(currentValue, _dataRef))
922 newCluster = _dataRef->getCluster(currentValue.substr(0, currentValue.find('{')));
923 else
924 {
925 // Evaluate the expression and create a new
926 // cluster
927 try
928 {
929 std::string sCurrentValue = currentValue;
930
931 if (_dataRef->containsTablesOrClusters(sCurrentValue))
932 getDataElements(sCurrentValue, *_parserRef, *_dataRef, *_optionRef, false);
933
934 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sCurrentValue))
935 {
936 std::string sCluster = sNewArgName + "{}";
937 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sCurrentValue, sCluster, true);
938 }
939 else
940 {
941 mu::value_type* v = nullptr;
942 int nResults;
943 _parserRef->SetExpr(sCurrentValue);
944 v = _parserRef->Eval(nResults);
945 newCluster.setDoubleArray(nResults, v);
946 }
947 }
948 catch (...)
949 {
951 _debugger.showError(current_exception());
952 _dataRef->removeCluster(sNewArgName);
953 throw;
954 }
955 }
956
957 // Clusters have to be stored as names without
958 // their braces
959 currentValue = sNewArgName;
960 mLocalArgs[sNewArgName] = CLUSTERTYPE;
961 }
962 else if (inliningMode && (currentValue.length() < 3 || currentValue.substr(currentValue.length()-2) != "{}"))
963 {
964 std::string sTempCluster = _dataRef->createTemporaryCluster(currentArg.substr(0, currentArg.find('{')));
965 vInlineArgDef.push_back(sTempCluster + " = " + currentValue + ";");
966 currentValue = sTempCluster;
967 }
968
969 if (currentValue.find('{') != string::npos)
970 currentValue.erase(currentValue.find('{'));
971 }
972 else
973 {
974 if (isRef)
975 {
976 const auto& varMap = _parserRef->GetVar();
977 const auto& stringMap = _stringParser.getStringVars();
978
979 // Reference
980 if (varMap.find(currentValue) == varMap.end()
981 && stringMap.find(currentValue) == stringMap.end()
982 && !(isTemplate && _dataRef->isCluster(currentValue))
983 && !(isTemplate && currentValue.substr(0, 7) == "string(")
984 && !(isTemplate && _dataRef->isTable(currentValue)))
985 {
987 _debugger.throwException(SyntaxError(SyntaxError::CANNOT_PASS_LITERAL_PER_REFERENCE, currentValue, "", currentArg));
988 }
989 }
990 else if (!isMacro) // macros do the old copy-paste logic
991 {
992 // Create a local variable
993 std::string sNewArgName = createMangledArgName(currentArg);
994
995 if (!_functionRef->call(currentValue))
996 {
999 }
1000
1001 try
1002 {
1003 // Templates allow also other types
1004 if (isTemplate)
1005 {
1006 StripSpaces(currentValue);
1007
1008 if (currentValue.find("()") != std::string::npos && _dataRef->isTable(currentValue))
1009 {
1010 mArguments[currentArg] = currentValue; // Tables are always references
1011 return;
1012 }
1013 else if (currentValue.find("{}") != std::string::npos && _dataRef->isCluster(currentValue))
1014 {
1015 // Copy clusters
1016 NumeRe::Cluster& newCluster = _dataRef->newCluster(sNewArgName);
1017 newCluster = _dataRef->getCluster(currentValue.substr(0, currentValue.find('{')));
1018
1019 currentValue = sNewArgName + "{}";
1020 mLocalArgs[sNewArgName + "{}"] = CLUSTERTYPE;
1021 mArguments[currentArg] = currentValue;
1022 return;
1023 }
1024
1025 // Get data, if necessary
1026 if (_dataRef->containsTablesOrClusters(currentValue))
1027 getDataElements(currentValue, *_parserRef, *_dataRef, *_optionRef);
1028
1029 // Evaluate strings
1030 if (_stringParser.isStringExpression(currentValue))
1031 {
1032 NumeRe::Cluster& newCluster = _dataRef->newCluster(sNewArgName);
1033 std::string sCluster = sNewArgName + "{}";
1034 NumeRe::StringParser::StringParserRetVal ret = _stringParser.evalAndFormat(currentValue, sCluster, true);
1035
1037 {
1038 if (newCluster.size() == 1)
1039 {
1040 _stringParser.setStringValue(sNewArgName, newCluster.getParserString(0));
1041 _dataRef->removeCluster(sNewArgName);
1042 currentValue = sNewArgName;
1043 mLocalArgs[sNewArgName] = STRINGTYPE;
1044 }
1045 else
1046 {
1047 currentValue = sNewArgName + "{}";
1048 mLocalArgs[sNewArgName + "{}"] = CLUSTERTYPE;
1049 }
1050
1051 mArguments[currentArg] = currentValue;
1052 return;
1053 }
1054 }
1055
1056 // Evaluate numerical expressions
1057 _parserRef->SetExpr(currentValue);
1058 int nRes = 0;
1059 mu::value_type* v = _parserRef->Eval(nRes);
1060
1061 if (nRes > 1)
1062 {
1063 NumeRe::Cluster& newCluster = _dataRef->newCluster(sNewArgName);
1064 newCluster.setDoubleArray(nRes, v);
1065 currentValue = sNewArgName + "{}";
1066 mLocalArgs[sNewArgName + "{}"] = CLUSTERTYPE;
1067 }
1068 else
1069 {
1070 mu::value_type* newVar = new mu::value_type;
1071 *newVar = v[0];
1072 _parserRef->m_lDataStorage.push_back(newVar);
1073 _parserRef->DefineVar(sNewArgName, newVar);
1074 currentValue = sNewArgName;
1075 mLocalArgs[sNewArgName] = NUMTYPE;
1076 }
1077
1078 mArguments[currentArg] = currentValue;
1079 return;
1080 }
1081 else
1082 {
1083 // Get data, if necessary
1084 if (_dataRef->containsTablesOrClusters(currentValue))
1085 getDataElements(currentValue, *_parserRef, *_dataRef, *_optionRef);
1086
1087 // Evaluate strings
1088 if (_stringParser.isStringExpression(currentValue))
1089 {
1090 std::string dummy;
1091 NumeRe::StringParser::StringParserRetVal ret = _stringParser.evalAndFormat(currentValue, dummy, true);
1092
1094 {
1095 _stringParser.setStringValue(sNewArgName, getNextArgument(currentValue));
1096 currentValue = sNewArgName;
1097 mLocalArgs[sNewArgName] = STRINGTYPE;
1098 mArguments[currentArg] = currentValue;
1099 return;
1100 }
1101 }
1102
1103 // Evaluate numerical expressions
1104 _parserRef->SetExpr(sNewArgName + " = " + currentValue);
1105 _parserRef->Eval();
1106 }
1107 }
1108 catch (...)
1109 {
1111 _debugger.showError(current_exception());
1112 throw;
1113 }
1114
1115 currentValue = sNewArgName;
1116 mLocalArgs[sNewArgName] = NUMTYPE;
1117 }
1118 }
1119
1120 mArguments[currentArg] = currentValue;
1121}
1122
1123
1134{
1135 if (!_currentProcedure)
1136 return;
1137
1138 if (inliningMode)
1139 {
1140 createLocalInlineVars(sVarList);
1141 return;
1142 }
1143
1145
1146 // Get the number of declared variables
1147 size_t nLocalVarMapSize = countVarListElements(sVarList);
1148
1149 // Decode the variable list
1150 for (unsigned int i = 0; i < nLocalVarMapSize; i++)
1151 {
1152 std::string currentDef = getNextArgument(sVarList, true);
1153 mu::value_type currentVal = 0;
1154
1155 std::string sSymbol = currentDef.substr(0, currentDef.find('='));
1156
1157 if (!checkSymbolName(sSymbol))
1158 {
1161 }
1162
1163 // Fill in the value of the variable by either
1164 // using the default or the explicit passed value
1165 if (currentDef.find('=') != string::npos)
1166 {
1167 std::string sVarValue = currentDef.substr(currentDef.find('=')+1);
1168
1169 if (sVarValue.find('$') != string::npos && sVarValue.find('(') != string::npos)
1170 {
1172 {
1175 }
1176
1177 try
1178 {
1180
1181 if (nReturn == FlowCtrl::INTERFACE_ERROR)
1183 else if (nReturn == FlowCtrl::INTERFACE_EMPTY)
1184 sVarValue = "false";
1185 }
1186 catch (...)
1187 {
1189 _debugger.showError(current_exception());
1190 throw;
1191 }
1192 }
1193
1194 try
1195 {
1196 sVarValue = resolveLocalVars(sVarValue+" ", i); // Needs a terminating separator
1197
1198 if (!NumeReKernel::getInstance()->getStringParser().isStringExpression(sVarValue) && _dataRef->containsTablesOrClusters(sVarValue))
1199 {
1201 }
1202
1203 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sVarValue))
1204 {
1205 string sTemp;
1206 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sVarValue, sTemp, true);
1207 }
1208
1209 _parserRef->SetExpr(sVarValue);
1210 currentDef.erase(currentDef.find('='));
1211 currentVal = _parserRef->Eval();
1212 }
1213 catch (...)
1214 {
1216 _debugger.showError(current_exception());
1217 throw;
1218 }
1219 }
1220
1221 StripSpaces(currentDef);
1222 std::string currentVar = createMangledVarName(currentDef);
1223
1224 mLocalVars[currentDef] = std::make_pair(currentVar, new mu::value_type);
1225 *mLocalVars[currentDef].second = currentVal;
1226
1227 _parserRef->DefineVar(currentVar, mLocalVars[currentDef].second);
1228 }
1229}
1230
1231
1242{
1243 if (!_currentProcedure)
1244 return;
1245
1246 if (inliningMode)
1247 {
1248 createLocalInlineStrings(sStringList);
1249 return;
1250 }
1251
1253
1254 // Get the number of declared variables
1255 size_t nLocalStrMapSize = countVarListElements(sStringList);
1256
1257 // Decode the variable list
1258 for (unsigned int i = 0; i < nLocalStrMapSize; i++)
1259 {
1260 std::string currentDef = getNextArgument(sStringList, true);
1261 std::string sVarValue;
1262
1263 std::string sSymbol = currentDef.substr(0, currentDef.find('='));
1264
1265 if (!checkSymbolName(sSymbol))
1266 {
1269 }
1270 // Fill in the value of the variable by either
1271 // using the default or the explicit passed value
1272 if (currentDef.find('=') != string::npos)
1273 {
1274 sVarValue = currentDef.substr(currentDef.find('=')+1);
1275
1276 if (sVarValue.find('$') != string::npos && sVarValue.find('(') != string::npos)
1277 {
1279 {
1282 }
1283
1284 try
1285 {
1287
1288 if (nReturn == FlowCtrl::INTERFACE_ERROR)
1290 else if (nReturn == FlowCtrl::INTERFACE_EMPTY)
1291 sVarValue = "false";
1292 }
1293 catch (...)
1294 {
1296 _debugger.showError(current_exception());
1297 throw;
1298 }
1299 }
1300
1301 sVarValue = resolveLocalStrings(sVarValue + " ", i); // Needs a terminating separator
1302
1303 if (_dataRef->containsTablesOrClusters(sVarValue))
1305
1306 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sVarValue))
1307 {
1308 string sTemp;
1309 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sVarValue, sTemp, true);
1310 }
1311
1312 currentDef.erase(currentDef.find('='));
1313 }
1314
1315 StripSpaces(currentDef);
1316 std::string currentVar = createMangledVarName(currentDef);
1317
1318 try
1319 {
1320 NumeReKernel::getInstance()->getStringParser().setStringValue(currentVar, sVarValue);
1321 }
1322 catch (...)
1323 {
1325 _debugger.showError(current_exception());
1326 throw;
1327 }
1328
1329 mLocalStrings[currentDef] = std::make_pair(currentVar, sVarValue);
1330 }
1331}
1332
1333
1343{
1344 if (!_currentProcedure)
1345 return;
1346
1347 if (inliningMode)
1348 return;
1349
1350 // Get the number of declared variables
1351 size_t nLocalTableSize = countVarListElements(sTableList);
1352
1353 // Decode the variable list
1354 for (unsigned int i = 0; i < nLocalTableSize; i++)
1355 {
1356 std::string currentDef = getNextArgument(sTableList, true);
1357 std::string sCurrentValue;
1358 std::string sSymbol = currentDef.substr(0, currentDef.find('='));
1359
1360 if (!checkSymbolName(sSymbol))
1361 {
1364 }
1365
1366 if (currentDef.find('=') != string::npos)
1367 sCurrentValue = currentDef.substr(currentDef.find('=')+1);
1368
1369 if (currentDef.find('(') != string::npos)
1370 currentDef.erase(currentDef.find('('));
1371
1372 StripSpaces(currentDef);
1373 StripSpaces(sCurrentValue);
1374 std::string currentVar = createMangledVarName(currentDef);
1375
1376 try
1377 {
1378 _dataRef->addTable(currentVar, *_optionRef);
1379
1380 if (sCurrentValue.length())
1381 {
1382 sCurrentValue = resolveLocalTables(sCurrentValue, i);
1383
1384 if (sCurrentValue.find('$') != string::npos && sCurrentValue.find('(', sCurrentValue.find('$')+1))
1385 {
1387 {
1389 }
1390
1391 sCurrentValue.insert(0, currentVar + "() = ");
1392
1394
1395 if (nReturn == FlowCtrl::INTERFACE_ERROR)
1397 else if (nReturn == FlowCtrl::INTERFACE_EMPTY)
1398 sCurrentValue = "false";
1399 else
1400 {
1401 if (sCurrentValue.substr(0, currentVar.length()+5) == currentVar + "() = ")
1402 currentVar.erase(0, currentVar.length()+5);
1403 else
1404 {
1405 mLocalTables[currentDef] = currentVar;
1406 continue;
1407 }
1408 }
1409 }
1410
1411 if (isCompleteTable(sCurrentValue, _dataRef))
1412 _dataRef->copyTable(sCurrentValue.substr(0, sCurrentValue.find('(')), currentVar);
1413 else
1414 {
1415 if (_dataRef->containsTablesOrClusters(sCurrentValue))
1416 getDataElements(sCurrentValue, *_parserRef, *_dataRef, *_optionRef, false);
1417
1418 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sCurrentValue))
1419 {
1420 std::string sTable = currentVar + "(:,1)";
1421 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sCurrentValue, sTable, true);
1422 }
1423 else
1424 {
1425 mu::value_type* v = nullptr;
1426 int nResults;
1427 _parserRef->SetExpr(sCurrentValue);
1428 v = _parserRef->Eval(nResults);
1429 Indices _idx;
1431 _idx.col = VectorIndex(0);
1432 _dataRef->writeToTable(_idx, currentVar, v, nResults);
1433 }
1434 }
1435 }
1436 }
1437 catch (...)
1438 {
1440 NumeReKernel::getInstance()->getDebugger().showError(current_exception());
1441
1442 if (_dataRef->isTable(currentVar))
1443 _dataRef->deleteTable(currentVar);
1444
1445 throw;
1446 }
1447
1448 mLocalTables[currentDef] = currentVar;
1449 }
1450}
1451
1452
1462{
1463 if (!_currentProcedure)
1464 return;
1465
1466 if (inliningMode)
1467 return;
1468
1469 // Get the number of declared variables
1470 size_t nLocalClusterSize = countVarListElements(sClusterList);
1471
1472 // Decode the variable list
1473 for (unsigned int i = 0; i < nLocalClusterSize; i++)
1474 {
1475 std::string currentDef = getNextArgument(sClusterList, true);
1476 std::string sCurrentValue;
1477 std::string sSymbol = currentDef.substr(0, currentDef.find('='));
1478
1479 if (!checkSymbolName(sSymbol))
1480 {
1483 }
1484
1485 if (currentDef.find('=') != string::npos)
1486 sCurrentValue = currentDef.substr(currentDef.find('=')+1);
1487
1488 if (currentDef.find('{') != string::npos)
1489 currentDef.erase(currentDef.find('{'));
1490
1491 StripSpaces(sCurrentValue);
1492 StripSpaces(currentDef);
1493 std::string currentVar = createMangledVarName(currentDef);
1494
1495 try
1496 {
1497 NumeRe::Cluster& cluster = _dataRef->newCluster(currentVar);
1498
1499 if (sCurrentValue.length())
1500 {
1501 sCurrentValue = resolveLocalClusters(sCurrentValue, i);
1502
1503 if (sCurrentValue.find('$') != string::npos && sCurrentValue.find('(', sCurrentValue.find('$')+1))
1504 {
1506 {
1508 }
1509
1511
1512 if (nReturn == FlowCtrl::INTERFACE_ERROR)
1514 else if (nReturn == FlowCtrl::INTERFACE_EMPTY)
1515 sCurrentValue = "false";
1516 }
1517
1518 if (isCompleteCluster(sCurrentValue, _dataRef))
1519 cluster = _dataRef->getCluster(sCurrentValue.substr(0, sCurrentValue.find('{')));
1520 else
1521 {
1522 if (_dataRef->containsTablesOrClusters(sCurrentValue))
1523 getDataElements(sCurrentValue, *_parserRef, *_dataRef, *_optionRef, false);
1524
1525 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sCurrentValue))
1526 {
1527 string sCluster = currentVar + "{}";
1528 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sCurrentValue, sCluster, true);
1529 }
1530 else
1531 {
1532 value_type* v = nullptr;
1533 int nResults;
1534 _parserRef->SetExpr(sCurrentValue);
1535 v = _parserRef->Eval(nResults);
1536 cluster.setDoubleArray(nResults, v);
1537 }
1538 }
1539 }
1540 }
1541 catch (...)
1542 {
1544 NumeReKernel::getInstance()->getDebugger().showError(current_exception());
1545
1546 if (_dataRef->isCluster(currentVar))
1547 _dataRef->removeCluster(currentVar);
1548
1549 throw;
1550 }
1551
1552 mLocalClusters[currentDef] = currentVar;
1553 }
1554}
1555
1556
1565{
1566 const std::string currentDef = "TESTINFO";
1567 std::string currentVar = createMangledVarName(currentDef);
1568 NumeRe::Cluster& testCluster = _dataRef->newCluster(currentVar);
1569
1570 testCluster.setString(0, "tests");
1571 testCluster.setDouble(1, 0);
1572 testCluster.setString(2, "successes");
1573 testCluster.setDouble(3, 0);
1574 testCluster.setString(4, "fails");
1575 testCluster.setDouble(5, 0);
1576
1577 mLocalClusters[currentDef] = currentVar;
1578
1579 return currentVar;
1580}
1581
1582
1593string ProcedureVarFactory::resolveArguments(string sProcedureCommandLine, size_t nMapSize)
1594{
1595 if (!nMapSize)
1596 return sProcedureCommandLine;
1597
1598 for (const auto& iter : mArguments)
1599 {
1600 unsigned int nPos = 0;
1601 size_t nArgumentBaseLength = iter.first.length();
1602
1603 if (iter.first.back() == '(' || iter.first.back() == '{')
1604 nArgumentBaseLength--;
1605
1606 while ((nPos = sProcedureCommandLine.find(iter.first.substr(0, nArgumentBaseLength), nPos)) != string::npos)
1607 {
1608 if ((sProcedureCommandLine[nPos-1] == '~' && sProcedureCommandLine[sProcedureCommandLine.find_last_not_of('~',nPos-1)] != '#')
1609 || (iter.first.back() != '(' && sProcedureCommandLine[nPos+nArgumentBaseLength] == '(')
1610 || (iter.first.back() != '{' && sProcedureCommandLine[nPos+nArgumentBaseLength] == '{'))
1611 {
1612 nPos += iter.first.length();
1613 continue;
1614 }
1615
1616 if (checkDelimiter(sProcedureCommandLine.substr(nPos-1, nArgumentBaseLength+2), true)
1617 && (!isInQuotes(sProcedureCommandLine, nPos, true)
1618 || isToCmd(sProcedureCommandLine, nPos)))
1619 {
1620 if ((iter.second.front() == '{' || iter.second.back() == ')') && iter.first.back() == '{')
1621 sProcedureCommandLine.replace(nPos, getMatchingParenthesis(sProcedureCommandLine.substr(nPos))+1, iter.second);
1622 else
1623 sProcedureCommandLine.replace(nPos, nArgumentBaseLength, iter.second);
1624
1625 nPos += iter.second.length();
1626 }
1627 else
1628 nPos += nArgumentBaseLength;
1629 }
1630 }
1631
1632 return sProcedureCommandLine;
1633}
1634
1635
1646string ProcedureVarFactory::resolveLocalVars(string sProcedureCommandLine, size_t nMapSize)
1647{
1648 if (!nMapSize)
1649 return sProcedureCommandLine;
1650
1651 for (const auto& iter : mLocalVars)
1652 {
1653 size_t nPos = 0;
1654 size_t nDelimCheck = 0;
1655
1656 while ((nPos = sProcedureCommandLine.find(iter.first, nPos)) != string::npos)
1657 {
1658 if ((sProcedureCommandLine[nPos-1] == '~' && sProcedureCommandLine[sProcedureCommandLine.find_last_not_of('~', nPos-1)] != '#')
1659 || sProcedureCommandLine[nPos+iter.first.length()] == '(')
1660 {
1661 nPos += iter.first.length();
1662 continue;
1663 }
1664
1665 nDelimCheck = nPos-1;
1666
1667 if ((sProcedureCommandLine[nDelimCheck] == '~' && sProcedureCommandLine[sProcedureCommandLine.find_last_not_of('~', nDelimCheck)] == '#'))
1668 nDelimCheck = sProcedureCommandLine.find_last_not_of('~', nDelimCheck);
1669
1670 if (checkDelimiter(sProcedureCommandLine.substr(nDelimCheck, iter.first.length() + 1 + nPos - nDelimCheck))
1671 && (!isInQuotes(sProcedureCommandLine, nPos, true)
1672 || isToCmd(sProcedureCommandLine, nPos)))
1673 {
1674 sProcedureCommandLine.replace(nPos, iter.first.length(), iter.second.first);
1675 nPos += iter.second.first.length();
1676 }
1677 else
1678 nPos += iter.first.length();
1679 }
1680 }
1681
1682 return sProcedureCommandLine;
1683}
1684
1685
1696string ProcedureVarFactory::resolveLocalStrings(string sProcedureCommandLine, size_t nMapSize)
1697{
1698 if (!nMapSize)
1699 return sProcedureCommandLine;
1700
1701 for (const auto& iter : mLocalStrings)
1702 {
1703 size_t nPos = 0;
1704 size_t nDelimCheck = 0;
1705
1706 while ((nPos = sProcedureCommandLine.find(iter.first, nPos)) != string::npos)
1707 {
1708 if ((sProcedureCommandLine[nPos-1] == '~' && sProcedureCommandLine[sProcedureCommandLine.find_last_not_of('~', nPos-1)] != '#')
1709 || sProcedureCommandLine[nPos+iter.first.length()] == '(')
1710 {
1711 nPos += iter.first.length();
1712 continue;
1713 }
1714
1715 nDelimCheck = nPos-1;
1716
1717 if ((sProcedureCommandLine[nDelimCheck] == '~' && sProcedureCommandLine[sProcedureCommandLine.find_last_not_of('~', nDelimCheck)] == '#'))
1718 nDelimCheck = sProcedureCommandLine.find_last_not_of('~', nDelimCheck);
1719
1720 if (checkDelimiter(sProcedureCommandLine.substr(nDelimCheck, iter.first.length() + 1 + nPos - nDelimCheck), true)
1721 && (!isInQuotes(sProcedureCommandLine, nPos, true) || isToCmd(sProcedureCommandLine, nPos)))
1722 {
1723 if (inliningMode)
1724 replaceStringMethod(sProcedureCommandLine, nPos, iter.first.length(), iter.second.first);
1725 else
1726 sProcedureCommandLine.replace(nPos, iter.first.length(), iter.second.first);
1727
1728 nPos += iter.second.first.length();
1729 }
1730 else
1731 nPos += iter.first.length();
1732 }
1733 }
1734
1735 return sProcedureCommandLine;
1736}
1737
1738
1749string ProcedureVarFactory::resolveLocalTables(string sProcedureCommandLine, size_t nMapSize)
1750{
1751 if (!nMapSize)
1752 return sProcedureCommandLine;
1753
1754 for (const auto& iter : mLocalTables)
1755 {
1756 size_t nPos = 0;
1757 size_t nDelimCheck = 0;
1758
1759 while ((nPos = sProcedureCommandLine.find(iter.first + "(", nPos)) != string::npos)
1760 {
1761 if ((sProcedureCommandLine[nPos-1] == '~' && sProcedureCommandLine[sProcedureCommandLine.find_last_not_of('~', nPos-1)] != '#')
1762 || sProcedureCommandLine[nPos-1] == '$')
1763 {
1764 nPos += iter.first.length();
1765 continue;
1766 }
1767
1768 nDelimCheck = nPos-1;
1769
1770 if ((sProcedureCommandLine[nDelimCheck] == '~' && sProcedureCommandLine[sProcedureCommandLine.find_last_not_of('~', nDelimCheck)] == '#'))
1771 nDelimCheck = sProcedureCommandLine.find_last_not_of('~', nDelimCheck);
1772
1773 if (checkDelimiter(sProcedureCommandLine.substr(nDelimCheck, iter.first.length() + 1 + nPos - nDelimCheck), true)
1774 && (!isInQuotes(sProcedureCommandLine, nPos, true) || isToCmd(sProcedureCommandLine, nPos)))
1775 {
1776 sProcedureCommandLine.replace(nPos, iter.first.length(), iter.second);
1777 nPos += iter.second.length();
1778 }
1779 else
1780 nPos += iter.first.length();
1781 }
1782 }
1783
1784 return sProcedureCommandLine;
1785}
1786
1787
1798string ProcedureVarFactory::resolveLocalClusters(string sProcedureCommandLine, size_t nMapSize)
1799{
1800 if (!nMapSize)
1801 return sProcedureCommandLine;
1802
1803 for (const auto& iter : mLocalClusters)
1804 {
1805 size_t nPos = 0;
1806 size_t nDelimCheck = 0;
1807
1808 while ((nPos = sProcedureCommandLine.find(iter.first + "{", nPos)) != string::npos)
1809 {
1810 if ((sProcedureCommandLine[nPos-1] == '~' && sProcedureCommandLine[sProcedureCommandLine.find_last_not_of('~', nPos-1)] != '#'))
1811 {
1812 nPos += iter.first.length();
1813 continue;
1814 }
1815
1816 nDelimCheck = nPos-1;
1817
1818 if ((sProcedureCommandLine[nDelimCheck] == '~' && sProcedureCommandLine[sProcedureCommandLine.find_last_not_of('~', nDelimCheck)] == '#'))
1819 nDelimCheck = sProcedureCommandLine.find_last_not_of('~', nDelimCheck);
1820
1821 if (checkDelimiter(sProcedureCommandLine.substr(nDelimCheck, iter.first.length() + 1 + nPos - nDelimCheck), true)
1822 && (!isInQuotes(sProcedureCommandLine, nPos, true) || isToCmd(sProcedureCommandLine, nPos)))
1823 {
1824 sProcedureCommandLine.replace(nPos, iter.first.length(), iter.second);
1825 nPos += iter.second.length();
1826 }
1827 else
1828 nPos += iter.first.length();
1829 }
1830 }
1831
1832 return sProcedureCommandLine;
1833}
1834
1835
std::string toLowerCase(const std::string &)
Converts uppercase to lowercase letters.
ProcedureInterfaceRetVal
Definition: flowctrl.hpp:85
@ INTERFACE_EMPTY
Definition: flowctrl.hpp:86
@ INTERFACE_ERROR
Definition: flowctrl.hpp:87
bool call(std::string &sExpr, int nRecursion=0)
This function searches for known custom definitions in the passed expression and replaces them with t...
Definition: define.cpp:801
std::string get(const std::string &sMessage, const std::vector< std::string > &vTokens) const
This member function returns the language string for the passed language identifier and replaces all ...
Definition: language.cpp:292
This class represents the central memory managing instance. It will handle all tables and clusters,...
void copyTable(const std::string &source, const std::string &target)
Copy one table to another one (and create the missing table automatically, if needed).
bool isTable(const std::string &sTable) const
This member function returns, whether the passed table name corresponds to a known table.
bool deleteTable(const std::string &sCache)
This member function removes the selected table.
bool addTable(const std::string &sCache, const Settings &_option)
This member function creates a new table. It is checked, whether its name is valid and not already us...
bool containsTablesOrClusters(const std::string &sCmdLine)
This member function evaluates, whether the passed command line contains tables or clusters.
void writeToTable(int _nLine, int _nCol, const std::string &_sCache, const mu::value_type &_dData)
This class represents a whole cluster. The single items are stored as pointers to the abstract cluste...
Definition: cluster.hpp:325
size_t size() const
This member function returns the size of the internal memory buffer as items.
Definition: cluster.cpp:356
std::string getParserString(size_t i) const
This member function returns the data of the i-th cluster item in memory as a parser string.
Definition: cluster.cpp:781
void setDouble(size_t i, const mu::value_type &value)
This member function assigns a value as data for the i-th cluster item in memory. The type of the i-t...
Definition: cluster.cpp:561
void setString(size_t i, const std::string &strval)
This member function assigns a string as data for the i-th cluster item in memory....
Definition: cluster.cpp:801
void setDoubleArray(const std::vector< mu::value_type > &vVals)
This member function assigns values as data for the all cluster items in memory. The type of the clus...
Definition: cluster.cpp:648
void removeCluster(const std::string &sCluster)
This member function removes the cluster from memory, which corresponds to the passed cluster identif...
Definition: cluster.cpp:2173
Cluster & getCluster(StringView sCluster)
This member function returns a reference to the cluster indicated by the passed cluster identifier.
Definition: cluster.cpp:2077
Cluster & newCluster(const std::string &sCluster)
This member function creates a new cluster from the passed cluster identifier and returns a reference...
Definition: cluster.cpp:2139
bool isCluster(StringView sCluster) const
This member function returns true, if the passed cluster identifier can be found in the internal map.
Definition: cluster.cpp:2041
std::string createTemporaryCluster(const std::string &suffix="")
This member function creates a temporary cluster with a unique name and returns this name to the call...
Definition: cluster.cpp:2191
This class is the central string expression parser. It is designed as being a singleton with a persis...
virtual bool isStringExpression(const std::string &sExpression) override
Returns true, if the passed expression is an expression containing strings, string variables or strin...
StringParserRetVal evalAndFormat(std::string &sLine, std::string &sCache, bool bSilent=false, bool bCheckAssertions=false)
This public member function evaluates the passed string expression and formats the results for the co...
void setStringValue(const std::string &sVar, const std::string &sValue)
This public member function creates or updates a string variable and fills it with the passed value.
const std::map< std::string, std::string > & getStringVars() const
void removeStringVar(const std::string &sVar)
This public member function removes the selected string variable from memory.
void throwException(SyntaxError error)
This member function shows the debugger with the corresponding error message obtained by the passed S...
Definition: debugger.cpp:120
void gatherInformations(ProcedureVarFactory *_varFactory, const std::string &_sErraticCommand, const std::string &_sErraticModule, unsigned int _nLineNumber)
This member function gathers all information from the current workspace and stores them internally to...
Definition: debugger.cpp:516
void popStackItem()
This member function removes the last item from the stack.
Definition: debugger.cpp:489
void showError(const std::string &sTitle)
This member function shows the debugger with the passed error message.
Definition: debugger.cpp:96
static NumeReKernel * getInstance()
This static member function returns a a pointer to the singleton instance of the kernel.
Definition: kernel.hpp:221
NumeRe::StringParser & getStringParser()
Definition: kernel.hpp:286
Script & getScript()
Definition: kernel.hpp:311
PlotData & getPlottingData()
Definition: kernel.hpp:301
Output & getOutput()
Definition: kernel.hpp:306
mu::Parser & getParser()
Definition: kernel.hpp:281
NumeReDebugger & getDebugger()
Definition: kernel.hpp:326
MemoryManager & getMemoryManager()
Definition: kernel.hpp:263
FunctionDefinitionManager & getDefinitions()
Definition: kernel.hpp:291
static void issueWarning(std::string sWarningMessage)
This static function may be used to issue a warning to the user. The warning will be printed by the t...
Definition: kernel.cpp:2833
Settings & getSettings()
Definition: kernel.hpp:296
This class implements the logic to evaluate complex procedures, which may be called recursively.
Definition: procedure.hpp:56
virtual FlowCtrl::ProcedureInterfaceRetVal procedureInterface(std::string &sLine, mu::Parser &_parser, FunctionDefinitionManager &_functions, MemoryManager &_data, Output &_out, PlotData &_pData, Script &_script, Settings &_option, int nth_command=0) override
This member function handles the calls for procedures and plugins, resolves them and executes the cal...
Definition: procedure.cpp:1250
int getProcedureFlags() const
Definition: procedure.hpp:120
unsigned int GetCurrentLine() const
This member function will return the current line number depending on whether a flow control statemen...
Definition: procedure.cpp:2563
std::string getCurrentProcedureName() const
Definition: procedure.hpp:113
std::string resolveLocalStrings(std::string sProcedureCommandLine, size_t nMapSize=std::string::npos)
This private member function will resolve the calls to string variables in the passed procedure comma...
std::map< std::string, std::string > createProcedureArguments(std::string sArgumentList, std::string sArgumentValues)
This member function will create the procedure arguments for the current procedure.
std::string resolveLocalTables(std::string sProcedureCommandLine, size_t nMapSize=std::string::npos)
This private member function will resolve the calls to local tables in the passed procedure command l...
std::map< std::string, VarType > mLocalArgs
std::map< std::string, std::string > mLocalClusters
void createLocalTables(std::string sTableList)
This member function will create the local tables for the current procedure.
void evaluateProcedureArguments(std::string &currentArg, std::string &currentValue, const std::string &sArgumentList)
This memberfunction will evaluate the passed procedure arguments and convert them to local variables ...
std::string resolveLocalVars(std::string sProcedureCommandLine, size_t nMapSize=std::string::npos)
This private member function will resolve the calls to numerical variables in the passed procedure co...
void createLocalStrings(std::string sStringList)
This member function will create the local string variables for the current procedure.
std::string replaceProcedureName(std::string sProcedureName) const
Replaces path characters and whitespaces to create variable names fitting for an non- relative proced...
void reset()
Resets the object.
void checkArgument(const std::string &sArgument, const std::string &sArgumentList, unsigned int nCurrentIndex)
This private member function checks, whether the keywords "var", "str" or "tab" are used in the curre...
std::map< std::string, std::string > mArguments
void createLocalInlineStrings(std::string sVarList)
This private member function creates the local string variables for inlined procedures.
FunctionDefinitionManager * _functionRef
std::map< std::string, std::pair< std::string, std::string > > mLocalStrings
std::string resolveLocalClusters(std::string sProcedureCommandLine, size_t nMapSize=std::string::npos)
This private member function will resolve the calls to local clusters in the passed procedure command...
ProcedureVarFactory()
Constructor.
std::string createMangledArgName(const std::string &sDefinedName) const
Creates a mangled name for an argument.
~ProcedureVarFactory()
Destructor.
bool checkSymbolName(const std::string &sSymbolName) const
Checks for invalid characters or similar.
unsigned int countVarListElements(const std::string &sVarList)
This private memebr function counts the number of elements in the passed string list.
std::string resolveArguments(std::string sProcedureCommandLine, size_t nMapSize=std::string::npos)
This private member function will resolve the calls to arguments in the passed procedure command line...
bool delayDeletionOfReturnedTable(const std::string &sTableName)
Searches for a local table or a local table in the arguments with the corresponding identifier,...
std::vector< std::string > vInlineArgDef
void createLocalClusters(std::string sClusterList)
This member function will create the local clusters for the current procedure.
void checkArgumentValue(const std::string &sArgument, const std::string &sArgumentList, unsigned int nCurrentIndex)
This private member function checks, whether the keywords "var", "str" or "tab" are used in the curre...
void createLocalInlineVars(std::string sVarList)
This private member function creates the local variables for inlined procedures.
std::map< std::string, std::string > mLocalTables
std::string createMangledVarName(const std::string &sDefinedName) const
Creates a mangled name for a variable.
std::string createTestStatsCluster()
Creates a special cluster containing the test statistics.
bool isReference(const std::string &sArgName) const
Returns whether the passed argument representation (i.e. local variable name) is actually a reference...
void init()
This member function is the initializer function.
void createLocalVars(std::string sVarList)
This member function will create the local numerical variables for the current procedure.
std::map< std::string, std::pair< std::string, mu::value_type * > > mLocalVars
SettingsValue & getSetting(const std::string &value)
Returns a reference to the setting value, which corresponds to the passed string. Throws an exception...
Definition: settings.hpp:711
bool useDebugger() const
Returns, whether the debugger is currently active.
Definition: settings.hpp:1150
bool & active()
Returns a reference to a boolean value type setting.
Definition: settings.hpp:556
std::string to_string() const
This member function returns a copy of the viewed section of the string (via std::string::substr)....
size_t find(const std::string &findstr, size_t pos=0) const
Wrapper member function for std::string::find()
This class is the immutable (const) version of a string view. It can be constructed from a MutableStr...
StringView subview(size_t pos=0, size_t len=std::string::npos) const
This member function creates a new StringView class instance using the selected position and length a...
Common exception class for all exceptions thrown in NumeRe.
Definition: error.hpp:32
@ INLINE_PROCEDURE_IS_NOT_INLINE
Definition: error.hpp:119
@ INVALID_SYM_NAME
Definition: error.hpp:142
@ MISSING_DEFAULT_VALUE
Definition: error.hpp:157
@ FUNCTION_ERROR
Definition: error.hpp:110
@ UNMATCHED_PARENTHESIS
Definition: error.hpp:224
@ WRONG_ARG_NAME
Definition: error.hpp:226
@ INLINE_PROCEDURE_NEEDS_TABLE_REFERENCES
Definition: error.hpp:120
@ PROCEDURE_ERROR
Definition: error.hpp:197
@ CANNOT_PASS_LITERAL_PER_REFERENCE
Definition: error.hpp:87
@ TOO_MANY_ARGS
Definition: error.hpp:218
static size_t invalid_position
Definition: error.hpp:235
This class abstracts all the index logics, i.e. the logical differences between single indices and in...
Definition: structures.hpp:42
void SetExpr(StringView a_sExpr)
Set the expression. Triggers first time calculation thus the creation of the bytecode and scanning of...
value_type Eval()
Single-value wrapper around the vectorized overload of this member function.
const varmap_type & GetVar() const
Return a map containing the used variables only.
void DefineVar(const string_type &a_sName, value_type *a_fVar)
Add a user defined variable.
void RemoveVar(const string_type &a_strVarName)
Remove a variable from internal storage.
std::list< mu::value_type * > m_lDataStorage
Definition: muParserBase.h:99
string getDataElements(string &sLine, Parser &_parser, MemoryManager &_data, const Settings &_option, int options)
Searches the passed string for calls to any table or cluster and replaces them with internal vectors ...
Definition: dataaccess.cpp:276
Language _lang
Definition: kernel.cpp:39
string sErrorToken
unsigned int getMatchingParenthesis(const StringView &)
Returns the position of the closing parenthesis.
Definition: tools.cpp:414
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:251
static bool isCompleteCluster(StringView sArgumentValue, MemoryManager *_dataRef)
Determines, whether the user has passed a complete cluster or a cluster with some indices.
static bool isCompleteTable(StringView sArgumentValue, MemoryManager *_dataRef)
Determines, whether the user has passed a complete table or a table with some indices.
static bool containsFreeOperators(const string &sString)
Static helper function to detect free operators in a procedure argument. Those arguments need to be s...
void StripSpaces(std::string &)
Removes leading and trailing white spaces and tabulator characters.
#define SETTING_B_TABLEREFS
Definition: settings.hpp:45
std::string toInternalString(std::string sStr)
Converts a string literal to the internal representation in tables and clusters.
std::string getNextArgument(std::string &sArgList, bool bCut)
Definition: tools.cpp:2294
This structure is central for managing the indices of a table or cluster read or write data access....
VectorIndex col
VectorIndex row
std::string sString
std::string toString(int)
Converts an integer to a string without the Settings bloat.
void replaceStringMethod(string &sLine, size_t nPos, size_t nLength, const string &sReplacement)
This function searches the indicated string variable occurence for possible string methods and replac...
Definition: tools.cpp:3875
Match findCommand(StringView sCmd, const std::string &sCommand)
This function is very important for the command handler.
Definition: tools.cpp:1275
bool isInQuotes(StringView sExpr, unsigned int nPos, bool bIgnoreVarParser)
Checks, whether the position in the passed expression is part of a string literal.
Definition: tools.cpp:1672
bool checkDelimiter(const string &sString, bool stringdelim)
Checks, whether the first and the last character in the passed string is a delimiter character.
Definition: tools.cpp:1982
bool validateParenthesisNumber(const string &sCmd)
This function is used to validate the number of parentheses, i.e. whether there's a closing parenthes...
Definition: tools.cpp:3512
bool isToCmd(const string &sCmd, unsigned int nPos)
This function evaluates, whether the desired position is part of the argument of a to_cmd() function.
Definition: tools.cpp:3675