diff --git a/Slang/CMakeLists.txt b/Slang/CMakeLists.txt new file mode 100644 index 0000000..8116449 --- /dev/null +++ b/Slang/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.10) + +# set the project name +project(Slang) + +# add the executable +#add_executable(Main.cpp) + +target_include_directories(Slang PUBLIC + "${PROJECT_BINARY_DIR}" + ) \ No newline at end of file diff --git a/Slang/Main.cpp b/Slang/Main.cpp index 968dbb7..143160f 100644 --- a/Slang/Main.cpp +++ b/Slang/Main.cpp @@ -6,196 +6,105 @@ #include #include #include +#include +#include +#include + #include "eval.h" #include "strops.h" #include "builtin.h" #include "main.h" +#include "anyops.h" using namespace std; +using namespace boost; -vector globalVariables; -vector globalVariableValues; -vector functions; -vector> functionValues; +unordered_map globalVariableValues; +unordered_map>> functionValues; -bool isNumber(const string& str) +boost::any GetVariableValue(const string& varName, const unordered_map& variableValues) { - for (char const& c : str) { - if (isdigit(c) == 0 && c != '.') return false; - } - return true; -} - -string StringRaw(string str) -{ - str = trim(str); - - if (str.size() < 3) - return str; - - string withoutQuotes; - - if (str[0] != '\"') - withoutQuotes += str[0]; - - for (int ch = 1; ch < (int)str.size() - 1; ch++) - withoutQuotes += str[ch]; - - if (str[str.size() - 1] != '\"') - withoutQuotes += str[str.size() - 1]; - - return withoutQuotes; -} - -string Quoted(string str) -{ - str = trim(str); - - string withQuotes; - - if (str[0] != '\"') - withQuotes += '\"'; - - withQuotes += str; - - if (str[str.size() - 1] != '\"') - withQuotes += '\"'; - - return withQuotes; -} - -string RMParenthesis(string str) -{ - str = trim(str); - string withoutParenthesis; - - if (str[0] != '(') - withoutParenthesis += str[0]; - - for (int ch = 1; ch < (int)str.size() - 1; ch++) - withoutParenthesis += str[ch]; - - if (str[str.size() - 1] != ')') - withoutParenthesis += str[str.size() - 1]; - - return withoutParenthesis; -} - -string GetVariableValue(string varName, vector& variables, vector& variableVals) -{ - string typ = "string"; - bool isVar = false; - - if (count(varName, '\"') == 0) + auto iA = variableValues.find(varName); + if (iA != variableValues.end()) { - // Checks against global vars - for (int v = 0; v < (int)globalVariables.size(); v++) - if (varName == split(globalVariables[v], ' ')[1]) - { - typ = split(globalVariables[v], ' ')[0]; - isVar = true; - } - // Checks against local vars - for (int v = 0; v < (int)variables.size(); v++) - if (varName == split(variables[v], ' ')[1]) - { - typ = split(variables[v], ' ')[0]; - isVar = true; - } + return iA->second; } - - // If it is a var - if (isVar) + else { - // Checks against global vars - for (int v = 0; v < (int)globalVariables.size(); v++) - if (varName == split(globalVariables[v], ' ')[1]) - { - return globalVariableValues[v]; - } - // Checks against local vars - for (int v = 0; v < (int)variables.size(); v++) - if (varName == split(variables[v], ' ')[1]) - { - return variableVals[v]; - } + auto iB = globalVariableValues.find(varName); + if (iB != globalVariableValues.end()) + { + return iB->second; + } + else + { + return varName; + } } - - return varName; } -vector VarValues(vector varNames, vector& variables, vector& variableVals) +bool IsVar(const string& varName, const unordered_map& variableValues) { - vector realValues; + if (variableValues.find(varName) != variableValues.end()) + return true; + else + return false; +} + +vector VarValues(const vector& varNames, const unordered_map& variableValues) +{ + vector realValues; for (int varIndex = 0; varIndex < varNames.size(); varIndex++) { - varNames[varIndex] = trim(varNames[varIndex]); + string varName = trim(varNames[varIndex]); + //cout << varName << endl; - string typ = "string"; - bool isVar = false; - - if (count(varNames[varIndex], '\"') == 0) + auto iA = variableValues.find(varName); + if (iA != variableValues.end()) { - // Checks against global vars - for (int v = 0; v < (int)globalVariables.size(); v++) - if (varNames[varIndex] == split(globalVariables[v], ' ')[1]) - { - typ = split(globalVariables[v], ' ')[0]; - isVar = true; - } - // Checks against local vars - for (int v = 0; v < (int)variables.size(); v++) - if (varNames[varIndex] == split(variables[v], ' ')[1]) - { - typ = split(variables[v], ' ')[0]; - isVar = true; - } - } - - // If it is a var - if (isVar) - { - // Checks against global vars - for (int v = 0; v < (int)globalVariables.size(); v++) - if (varNames[varIndex] == split(globalVariables[v], ' ')[1]) - { - realValues.push_back(globalVariableValues[v]); - } - // Checks against local vars - for (int v = 0; v < (int)variables.size(); v++) - if (varNames[varIndex] == split(variables[v], ' ')[1]) - { - realValues.push_back(variableVals[v]); - } + realValues.push_back(iA->second); } else - realValues.push_back(varNames[varIndex]); + { + auto iB = globalVariableValues.find(varName); + if (iB != globalVariableValues.end()) + realValues.push_back(iB->second); + else + realValues.push_back(varName); + } } return realValues; } -int IsFunction(string funcName) +bool IsFunction(const string& funcName) { - // Iterate through all functions - for (int t = 0; t < (int)functions.size(); t++) - if (trim(funcName) == split(functions[t], ' ')[0]) - return t; - - return -1; + if (functionValues.find(funcName) != functionValues.end()) + return true; + else + return false; +} +bool IsCPPFunction(const string& funcName) +{ + if (funcName[0] == 'C' && funcName[1] == 'P' && funcName[2] == 'P' && funcName[2] == '.') + return true; + else + return false; } -string EvalExpression(string expression, vector& variables, vector& variableVals) +boost::any EvalExpression(const string& ex, unordered_map& variableValues) { - expression = trim(expression); + string expression = trim(ex); bool inQuotes = false; + CompilerLog("OLDEXPRESSION: |" + expression + "|"); + // If no operations are applied, then return self if ((count(expression, '+') == 0 && count(expression, '-') == 0 && count(expression, '*') == 0 && count(expression, '/') == 0 && count(expression, '(') == 0 && count(expression, '^') == 0) || split(expression, '.')[0] == "CPP") { - int funcIndex = IsFunction(split(expression, '(')[0]); - if (funcIndex != -1 && !inQuotes) + bool isFunc = IsFunction(split(expression, '(')[0]); + if (isFunc && !inQuotes) { //cout << split(expression, '(')[0] << endl; string argContents = ""; @@ -206,9 +115,8 @@ string EvalExpression(string expression, vector& variables, vector& variables, vector& variables, vector& variables, vector& variables, vector& variables, vector& variables, vector& variables, vector=") - return floatval(valARealValue) >= floatval(valBRealValue); - if (determinant == "<=") - return floatval(valARealValue) <= floatval(valBRealValue); - if (determinant == ">") - return floatval(valARealValue) > floatval(valBRealValue); - if (determinant == "<") - return floatval(valARealValue) < floatval(valBRealValue); + return AnyAsString(valARealValue) == AnyAsString(valBRealValue); + else if (determinant == "!=") + return AnyAsString(valARealValue) != AnyAsString(valBRealValue); + else if (determinant == ">=") + return AnyAsFloat(valARealValue) >= AnyAsFloat(valBRealValue); + else if (determinant == "<=") + return AnyAsFloat(valARealValue) <= AnyAsFloat(valBRealValue); + else if (determinant == ">") + return AnyAsFloat(valARealValue) > AnyAsFloat(valBRealValue); + else if (determinant == "<") + return AnyAsFloat(valARealValue) < AnyAsFloat(valBRealValue); + else + LogWarning("unrecognized determinant \'" + determinant + "\'"); return false; } -int evalEqu(vector str, vector& variables, vector& variableValues) +int varOperation(const vector& str, unordered_map& variableValues) { - // Iterate all existing local variable names - for (int v = 0; v < (int)variables.size(); v++) + if (IsVar(str[0], variableValues)) { - if (str[0] == split(variables[v], ' ')[1]) - { - if (str[1] == "=") - variableValues[v] = EvalExpression(unWrapVec(vector(str.begin() + 2, str.end())), variables, variableValues); - else if (str[1] == "+=") - variableValues[v] = EvalExpression(variableValues[v] + "+(" + unWrapVec(vector(str.begin() + 2, str.end())) + ")", variables, variableValues); - else if (str[1] == "-=") - variableValues[v] = EvalExpression(variableValues[v] + "-(" + unWrapVec(vector(str.begin() + 2, str.end())) + ")", variables, variableValues); - else if (str[1] == "*=") - variableValues[v] = EvalExpression(variableValues[v] + "*(" + unWrapVec(vector(str.begin() + 2, str.end())) + ")", variables, variableValues); - else if (str[1] == "/=") - variableValues[v] = EvalExpression(variableValues[v] + "/(" + unWrapVec(vector(str.begin() + 2, str.end())) + ")", variables, variableValues); - - //cout << variables[v] << " is " << variableValues[v] << endl; - return 0; - } + if (str[1] == "=") + variableValues[str[0]] = EvalExpression(unWrapVec(vector(str.begin() + 2, str.end())), variableValues); + else if (str[1] == "+=") + variableValues[str[0]] = EvalExpression(str[0] + "+(" + unWrapVec(vector(str.begin() + 2, str.end())) + ")", variableValues); + else if (str[1] == "-=") + variableValues[str[0]] = AnyAsFloat(variableValues[str[0]]) - AnyAsFloat(EvalExpression(unWrapVec(vector(str.begin() + 2, str.end())), variableValues)); + else if (str[1] == "*=") + variableValues[str[0]] = AnyAsFloat(variableValues[str[0]]) * AnyAsFloat(EvalExpression(unWrapVec(vector(str.begin() + 2, str.end())), variableValues)); + else if (str[1] == "/=") + variableValues[str[0]] = AnyAsFloat(variableValues[str[0]]) / AnyAsFloat(EvalExpression(unWrapVec(vector(str.begin() + 2, str.end())), variableValues)); + else + LogWarning("unrecognized operator \'" + str[1] + "\'"); + //cout << variables[v] << " is " << variableValues[v] << endl; + return 0; } - // Iterate all existing global variable names - for (int v = 0; v < (int)globalVariables.size(); v++) + else if (IsVar(str[0], globalVariableValues)) { - if (str[0] == split(globalVariables[v], ' ')[1]) - { - if (str[1] == "=") - globalVariableValues[v] = EvalExpression(unWrapVec(vector(str.begin() + 2, str.end())), variables, variableValues); - else if (str[1] == "+=") - globalVariableValues[v] = EvalExpression(variableValues[v] + "+(" + unWrapVec(vector(str.begin() + 2, str.end())) + ")", variables, variableValues); - else if (str[1] == "-=") - globalVariableValues[v] = EvalExpression(variableValues[v] + "-(" + unWrapVec(vector(str.begin() + 2, str.end())) + ")", variables, variableValues); - else if (str[1] == "*=") - globalVariableValues[v] = EvalExpression(variableValues[v] + "*(" + unWrapVec(vector(str.begin() + 2, str.end())) + ")", variables, variableValues); - else if (str[1] == "/=") - globalVariableValues[v] = EvalExpression(variableValues[v] + "/(" + unWrapVec(vector(str.begin() + 2, str.end())) + ")", variables, variableValues); - - //cout << variables[v] << " is " << variableValues[v] << endl; - return 0; - } + if (str[1] == "=") + globalVariableValues[str[0]] = EvalExpression(unWrapVec(vector(str.begin() + 2, str.end())), variableValues); + else if (str[1] == "+=") + globalVariableValues[str[0]] = EvalExpression(str[0] + "+(" + unWrapVec(vector(str.begin() + 2, str.end())) + ")", variableValues); + else if (str[1] == "-=") + globalVariableValues[str[0]] = AnyAsFloat(variableValues[str[0]]) - AnyAsFloat(EvalExpression(unWrapVec(vector(str.begin() + 2, str.end())), variableValues)); + else if (str[1] == "*=") + globalVariableValues[str[0]] = AnyAsFloat(variableValues[str[0]]) * AnyAsFloat(EvalExpression(unWrapVec(vector(str.begin() + 2, str.end())), variableValues)); + else if (str[1] == "/=") + globalVariableValues[str[0]] = AnyAsFloat(variableValues[str[0]]) / AnyAsFloat(EvalExpression(unWrapVec(vector(str.begin() + 2, str.end())), variableValues)); + else + LogWarning("unrecognized operator \'" + str[1] + "\'"); + //cout << variables[v] << " is " << variableValues[v] << endl; + return 0; } + LogWarning("uninitialized variable or typo in \'" + str[0] + "\'"); + return 1; } -string ProcessLine(vector> words, int lineNum, vector& variables, vector& variableValues) +boost::any ProcessLine(const vector>& words, int lineNum, unordered_map& variableValues) { + CompilerLog(unWrapVec(words[lineNum])); + CompilerLog(AnyAsString(GetVariableValue("out", variableValues))); + if (words[lineNum][0][0] == '/' && words[lineNum][0][1] == '/') - return ""; + return nullType; - if (words[lineNum][0] == "print") + // If print statement (deprecated, now use CPP.System.Print() function) + else if (words[lineNum][0] == "print") { - cout << StringRaw(EvalExpression(unWrapVec(vector(words[lineNum].begin() + 1, words[lineNum].end())), variables, variableValues)) << endl; - return ""; + cout << AnyAsString(EvalExpression(unWrapVec(vector(words[lineNum].begin() + 1, words[lineNum].end())), variableValues)) << endl; + return nullType; } - if (words[lineNum][0] == "return") { - //cout << StringRaw(unWrapVec(vector(words[lineNum].begin() + 1, words[lineNum].end()))) << endl; - return EvalExpression(unWrapVec(vector(words[lineNum].begin() + 1, words[lineNum].end())), variables, variableValues); - } + // Check if function return + else if (words[lineNum][0] == "return") + return EvalExpression(unWrapVec(vector(words[lineNum].begin() + 1, words[lineNum].end())), variableValues); - if (split(words[lineNum][0], '.')[0] == "CPP") + // Check if it is CPP Builtin function + else if (words[lineNum][0][0] == 'C' && words[lineNum][0][1] == 'P' && words[lineNum][0][2] == 'P' && words[lineNum][0][3] == '.') + return EvalExpression(unWrapVec(words[lineNum]), variableValues); + + // Check if it is function + else if (IsFunction(trim(split(words[lineNum][0], '(')[0]))) { - string output = EvalExpression(unWrapVec(words[lineNum]), variables, variableValues); - return output; + ExecuteFunction(trim(split(words[lineNum][0], '(')[0]), VarValues(split(RMParenthesis(replace(unWrapVec(words[lineNum]), trim(split(words[lineNum][0], '(')[0]), "")), ','), variableValues)); + return nullType; } - // Iterate through all functions - for (int t = 0; t < (int)functions.size(); t++) + // Iterate through all types to see if line inits or + // re-inits a variable then store it with it's value + else if (countInVector(types, trim(words[lineNum][0])) > 0) { - if (split(words[lineNum][0], '(')[0] == split(functions[t], ' ')[0]) - { - ExecuteFunction(split(functions[t], ' ')[0], VarValues(split(RMParenthesis(replace(unWrapVec(words[lineNum]), split(functions[t], ' ')[0], "")), ','), variables, variableValues), t); - return ""; - } + variableValues[words[lineNum][1]] = EvalExpression(unWrapVec(slice(words[lineNum], 3, -1)), variableValues); + CompilerLog("new var :: " + words[lineNum][1] + " = " + AnyAsString(variableValues[words[lineNum][1]])); + return nullType; } - // First iterate through all types to see if line - // inits a variable then store it with it's value - for (int t = 0; t < (int)types.size(); t++) + // Check existing variables: If matches, then it means + // the variables value is getting changed with an operator + else if (IsVar(words[lineNum][0], variableValues) || IsVar(words[lineNum][0], globalVariableValues)) { - if (words[lineNum][0] == types[t]) - { - //Checks if it is a re-init of an existing variable - for (int v = 0; v < (int)variables.size(); v++) - { - if (words[lineNum][1] == split(variables[v], ' ')[1]) - { - evalEqu(vector(words[lineNum].begin() + 1, words[lineNum].end()), variables, variableValues); - - return ""; - } - } - - //Checks if it is variable - variables.push_back(words[lineNum][0] + " " + words[lineNum][1]); - variableValues.push_back(EvalExpression(unWrapVec(vector(words[lineNum].begin() + 3, words[lineNum].end())), variables, variableValues)); - //cout << variables[(int)variables.size() - 1] << " is " << variableValues[(int)variableValues.size() - 1] << endl; - return ""; - } + // Evaluates what the operator (ex. '=', '+=') does to the value on the left by the value on the right + varOperation(vector(words[lineNum].begin(), words[lineNum].end()), variableValues); + return nullType; } - // Second, iterate all existing variable names - for (int v = 0; v < (int)variables.size(); v++) - { - if (words[lineNum][0] == split(variables[v], ' ')[1]) - { - evalEqu(vector(words[lineNum].begin(), words[lineNum].end()), variables, variableValues); - return ""; - } - } // Gathers while loop contents - if (words[lineNum][0] == "while") + else if (words[lineNum][0] == "while") { vector whileContents; vector whileParameters; @@ -482,20 +370,21 @@ string ProcessLine(vector> words, int lineNum, vector& va for (int i = 0; i < (int)whileContents.size(); i++) innerWords.push_back(split(whileContents[i], ' ')); - while (BooleanLogic(whileParameters[0], whileParameters[1], whileParameters[2], variables, variableValues)) + while (BooleanLogic(whileParameters[0], whileParameters[1], whileParameters[2], variableValues)) { //Iterate through all lines in while loop for (int lineNum = 0; lineNum < (int)whileContents.size(); lineNum++) { - string returnVal = ProcessLine(innerWords, lineNum, variables, variableValues); - if (returnVal != "") + boost::any returnVal = ProcessLine(innerWords, lineNum, variableValues); + if (!returnVal.empty()) return returnVal; } } - return ""; + return nullType; } + // Gathers if statement contents - if (words[lineNum][0] == "if") + else if (words[lineNum][0] == "if") { vector ifContents; vector ifParameters; @@ -523,13 +412,13 @@ string ProcessLine(vector> words, int lineNum, vector& va for (int i = 0; i < (int)ifContents.size(); i++) innerWords.push_back(split(ifContents[i], ' ')); - if (BooleanLogic(ifParameters[0], ifParameters[1], ifParameters[2], variables, variableValues)) + if (BooleanLogic(ifParameters[0], ifParameters[1], ifParameters[2], variableValues)) { //Iterate through all lines in if statement for (int l = 0; l < (int)ifContents.size(); l++) { - string returnVal = ProcessLine(innerWords, l, variables, variableValues); - if (returnVal != "") + boost::any returnVal = ProcessLine(innerWords, l, variableValues); + if (!returnVal.empty()) return returnVal; } } @@ -557,16 +446,16 @@ string ProcessLine(vector> words, int lineNum, vector& va vector> innerWords; for (int i = 0; i < (int)elseContents.size(); i++) - words.push_back(split(elseContents[i], ' ')); + innerWords.push_back(split(elseContents[i], ' ')); //Iterate through all lines in else statement for (int lineNum = 0; lineNum < (int)elseContents.size(); lineNum++) { - ProcessLine(innerWords, lineNum, variables, variableValues); + ProcessLine(innerWords, lineNum, variableValues); } - return ""; + return nullType; } - return ""; + return nullType; } //// Gathers else statement contents //if (words[lineNum][0] == "else") @@ -574,57 +463,38 @@ string ProcessLine(vector> words, int lineNum, vector& va // //} - return ""; + return nullType; } -string ExecuteFunction(string functionName, vector inputVarVals, int functionIndex) +boost::any ExecuteFunction(const string& functionName, const vector& inputVarVals) { - //vector inputVarVals = split(replace(inVals, " ", ""), ','); - vector functionLines; - //Get index of function - if (functionIndex == -1) - { - for (int f = 0; f < (int)functions.size(); f++) - if (split(functions[f], ' ')[0] == functionName) - { - functionLines = functionValues[f]; - functionIndex = f; - break; - } - } - else - functionLines = functionValues[functionIndex]; + // Get contents of function + vector> words = functionValues[functionName]; - vector variables; - vector variableValues; - vector functionNameParts = split(replace(functions[functionIndex], functionName + " ", ""), ','); - for (int i = 0; i < (int)inputVarVals.size(); i++) - { - variables.push_back(trim(functionNameParts[i])); - variableValues.push_back(EvalExpression(inputVarVals[i], variables, variableValues)); - //cout << variables[(int)variables.size() - 1] << " is " << variableValues[(int)variableValues.size() - 1] << endl; + unordered_map variableValues = {}; + vector args = words[0]; + for (int i = 0; i < (int)inputVarVals.size(); i++) { + + variableValues[args[i]] = inputVarVals[i]; + //cout << "\x1B[33m" << args[i] << " == " << AnyAsString(inputVarVals[i]) << "\033[0m\t\t" << endl; } - vector> words; - for (int i = 0; i < (int)functionLines.size(); i++) - words.push_back(split(functionLines[i], ' ')); //Iterate through all lines in function - for (int lineNum = 0; lineNum < (int)functionLines.size(); lineNum++) + for (int lineNum = 1; lineNum < (int)words.size(); lineNum++) { - string returnVal = ""; + boost::any returnVal = 0; try { - returnVal = ProcessLine(words, lineNum, variables, variableValues); + returnVal = ProcessLine(words, lineNum, variableValues); } catch (const std::exception&) { - cout << "\x1B[31mERROR: \'" << unWrapVec(words[lineNum]) << "\'\nIn function: " << functionName << "\nLine: " << lineNum << "\033[0m\t\t" << endl; - exit(1); + LogCriticalError("\'" + unWrapVec(words[lineNum]) + "\'\nIn function: " + functionName + "\nLine: " + to_string(lineNum)); } - if (returnVal != "") + if (!returnVal.empty()) return returnVal; } - return ""; + return nullType; } int parseSlang(string script) @@ -634,77 +504,74 @@ int parseSlang(string script) vector lines = split(script, '\n'); vector> words; for (int i = 0; i < (int)lines.size(); i++) - { words.push_back(split(lines[i], ' ')); - } // First go through entire script and iterate through all types to see if line is a variable // or function declaration, then store it with it's value for (int lineNum = 0; lineNum < (int)words.size(); lineNum++) - for (int t = 0; t < (int)types.size(); t++) - if (words[lineNum][0] == types[t]) + { + //Checks if it is function + if (words[lineNum][0] == "func") + { + vector> functionContents; + + string functName = split(words[lineNum][1], '(')[0]; + + string args = ""; + for (int w = 1; w < (int)words[lineNum].size(); w++) // Get all words from the instantiation line: these are the args { - //Checks if it is function - if (words[lineNum][(int)words[lineNum].size() - 1][(int)words[lineNum][(int)words[lineNum].size() - 1].size() - 1] == ')') - { - vector functionContents; - - string functName; - for (int w = 1; w < (int)words[lineNum].size(); w++) { - if (w < (int)words[lineNum].size() - 1) - { - functName += replace(replace(words[lineNum][w], "(", " "), ")", "") + " "; - } - else - { - functName += replace(replace(words[lineNum][w], "(", " "), ")", ""); - } - } - - int numOfBrackets = 1; - for (int p = lineNum + 2; p < (int)words.size(); p++) - { - numOfBrackets += countInVector(words[p], "{") - countInVector(words[p], "}"); - if (numOfBrackets == 0) - break; - functionContents.push_back(""); - for (int w = 0; w < (int)words[p].size(); w++) - { - functionContents[(int)functionContents.size() - 1] += words[p][w] + " "; - } - } - functionContents = removeTabs(functionContents, 1); - functions.push_back(functName); - functionValues.push_back(functionContents); - //cout << functName << " is \n" << Vec2Str(functionContents) << endl << endl; - } - //Checks if it is variable - else - { - globalVariables.push_back(words[lineNum][0] + " " + words[lineNum][1]); - globalVariableValues.push_back((string)words[lineNum][3]); - //cout << words[lineNum][1] << " is " << words[lineNum][3] << endl; - } + args += replace(replace(words[lineNum][w], "(", " "), ")", ""); } + args = replace(args, functName + " ", ""); + CompilerLog(args); + functionContents.push_back(split(args, ',')); + + int numOfBrackets = 1; + for (int p = lineNum + 2; p < (int)words.size(); p++) + { + numOfBrackets += countInVector(words[p], "{") - countInVector(words[p], "}"); + if (numOfBrackets == 0) + break; + functionContents.push_back(removeTabs(words[p], 1)); + } + functionValues[functName] = functionContents; + //cout << functName << " is \n" << Vec2Str(functionContents) << endl << endl; + } + else + { + if (words[lineNum][0] == "string") + globalVariableValues[words[lineNum][1]] = StringRaw(words[lineNum][3]); + else if (words[lineNum][0] == "int") + globalVariableValues[words[lineNum][1]] = stoi(words[lineNum][3]); + else if (words[lineNum][0] == "float") + globalVariableValues[words[lineNum][1]] = stof(words[lineNum][3]); + else if (words[lineNum][0] == "bool") + globalVariableValues[words[lineNum][1]] = stob(words[lineNum][3]); + //else + // LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + to_string(lineNum)); + } + } + // Executes main, which is the starting function - ExecuteFunction("Main", vector {"\"hi\"", "0"}, -1); + ExecuteFunction("Main", vector {"hi", 0}); return 0; } int main(int argc, char* argv[]) { + // Get builtin script contents ifstream builtin("../Slang/builtin.slg"); stringstream builtinString; builtinString << builtin.rdbuf(); + // Gathers builtin functions and variables GetBuiltins(builtinString.str()); - functions = builtinFunctions; functionValues = builtinFunctionValues; - globalVariables = builtinVars; globalVariableValues = builtinVarVals; + // Get default script contents ifstream script("../Slang/script.slg"); stringstream scriptString; scriptString << script.rdbuf(); @@ -716,4 +583,4 @@ int main(int argc, char* argv[]) parseSlang(scriptString.str()); return 0; -} \ No newline at end of file +} diff --git a/Slang/Slang.vcxproj b/Slang/Slang.vcxproj index 23400e3..43f7cc2 100644 --- a/Slang/Slang.vcxproj +++ b/Slang/Slang.vcxproj @@ -65,9 +65,11 @@ + + @@ -89,10 +91,12 @@ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true OldStyle + D:\Code\boost\libs;%(AdditionalIncludeDirectories) Console true + D:\Code\boost\stage\lib @@ -156,6 +160,9 @@ + + + diff --git a/Slang/Slang.vcxproj.filters b/Slang/Slang.vcxproj.filters index 6b7d44e..0800299 100644 --- a/Slang/Slang.vcxproj.filters +++ b/Slang/Slang.vcxproj.filters @@ -49,4 +49,7 @@ + + + \ No newline at end of file diff --git a/Slang/anyops.h b/Slang/anyops.h new file mode 100644 index 0000000..77d9fac --- /dev/null +++ b/Slang/anyops.h @@ -0,0 +1,216 @@ + +#ifndef ANYOPS_H +#define ANYOPS_H + +#include "builtin.h" +#include + +using namespace boost; +using namespace std; + +int LogWarning(const string& warningText); + +// Will convert type 'any' val to a bool +bool AnyAsBool(const boost::any& val) +{ + try // Try converting to bool + { + return any_cast(val); + } + catch (boost::bad_any_cast) + { + try // Try converting to string + { + return any_cast(val) == "true"; + } + catch (boost::bad_any_cast) + { + try // Try converting to float + { + return any_cast(val) == 1.0f; + } + catch (boost::bad_any_cast) // Try converting to int + { + try + { + return any_cast(val) == 1; + } + catch (boost::bad_any_cast) // Does not convert, return + { + LogWarning("invalid conversion to type \'bool\'"); + return false; + } + } + } + } +} + +// Will convert type 'any' val to a string +string AnyAsString(const boost::any& val) +{ + try // Try converting to string + { + return any_cast(val); + } + catch (boost::bad_any_cast) + { + try // Try converting to int + { + return to_string(any_cast(val)); + } + catch (boost::bad_any_cast) + { + try // Try converting to float + { + return to_string(any_cast(val)); + } + catch (boost::bad_any_cast) // Try converting to bool + { + try + { + string i = "false"; + if (any_cast(val) == true) i = "true"; + return i; + } + catch (boost::bad_any_cast) // Does not convert, return + { + LogWarning("invalid conversion to type \'string\'"); + return ""; + } + } + } + } +} + +// Will convert type 'any' val to a float +float AnyAsFloat(const boost::any& val) +{ + try // Try converting to float + { + return any_cast(val); + } + catch (boost::bad_any_cast) + { + try // Try converting to int + { + return (float)any_cast(val); + } + catch (boost::bad_any_cast) + { + try // Try converting to string, then converting it to float + { + return stof(any_cast(val)); + } + catch (boost::bad_any_cast) // Try converting to bool + { + try + { + float i = 0; + if (any_cast(val) == true) i = 1; + return i; + } + catch (boost::bad_any_cast) // Does not convert, return + { + LogWarning("invalid conversion to type \'float\'"); + return 0; + } + } + } + } +} + +// Will convert type 'any' val to an integer +int AnyAsInt(const boost::any& val) +{ + try // Try converting to int + { + return any_cast(val); + } + catch (boost::bad_any_cast) + { + try // Try converting to float + { + return (int)any_cast(val); + } + catch (boost::bad_any_cast) + { + try // Try converting to string, then converting it to int + { + return stoi(any_cast(val)); + } + catch (boost::bad_any_cast) // Try converting to bool + { + try + { + int i = 0; + if (any_cast(val) == true) i = 1; + return i; + } + catch (boost::bad_any_cast) // Does not convert, return + { + LogWarning("invalid conversion to type \'int\'"); + return 0; + } + } + } + } +} + +// Gets type of 'any' val +// 0 -> int; 1 -> float; 2 -> bool; 3 -> string; +int any_type(const boost::any& val) +{ + try // Try converting to int + { + int i = any_cast(val); + return 0; + } + catch (boost::bad_any_cast) + { + try // Try converting to float + { + float f = any_cast(val); + return 1; + } + catch (boost::bad_any_cast) + { + try // Try converting to bool + { + bool b = any_cast(val); + return 2; + } + catch (boost::bad_any_cast) // Try converting to string + { + try + { + string s = any_cast(val); + return 3; + } + catch (boost::bad_any_cast) // Does not convert, return + { + LogWarning("variable has no type"); + return -1; + } + } + } + } +} + +// Gets if any is NullType +bool any_null(const boost::any& val) +{ + /*if (val.type() == typeid(NullType)) + return true;*/ + return false; + //try // Try converting to Null + //{ + // NullType n = any_cast(val); + // return true; + //} + //catch (boost::bad_any_cast) + //{ + // return false; + //} +} + +#endif diff --git a/Slang/boost_x64_release.props b/Slang/boost_x64_release.props new file mode 100644 index 0000000..e7b305b --- /dev/null +++ b/Slang/boost_x64_release.props @@ -0,0 +1,17 @@ + + + + + + <_PropertySheetDisplayName>boost_x64_release + + + + D:\Code\boost;%(AdditionalIncludeDirectories) + + + D:\Code\boost\stage\lib;%(AdditionalLibraryDirectories) + + + + \ No newline at end of file diff --git a/Slang/builtin.h b/Slang/builtin.h index 06bcab3..1f58471 100644 --- a/Slang/builtin.h +++ b/Slang/builtin.h @@ -7,23 +7,52 @@ #include #include #include +#include #include "strops.h" #include "graphics.h" +#include "anyops.h" +#include using namespace std; +using namespace boost; vector types = { "int", "float", "string", "bool", "void", "null" }; -vector builtinFunctions; -vector> builtinFunctionValues; -vector builtinVars; -vector builtinVarVals; +unordered_map>> builtinFunctionValues; +unordered_map builtinVarVals; Parser mainWindow; -int GetBuiltins(string script) +class NullType { +public: + string type = "NULL"; +}; + +boost::any nullType; + +int LogWarning(const string& warningText) { - script = replace(script, " ", "\t"); + cerr << "\x1B[33mWARNING: " << warningText << "\033[0m\t\t" << endl; + return 1; +} + +int CompilerLog(const string& logText) +{ + cerr << "\x1B[32mclog: " << logText << "\033[0m\t\t" << endl; + return 1; +} + +int LogCriticalError(const string& errorText) +{ + cerr << "\x1B[31mERROR: " << errorText << "\033[0m\t\t" << endl; + exit(EXIT_FAILURE); + return 2; +} + +// Initial script processing, which loads variables and functions from builtin +int GetBuiltins(const string& s) +{ + string script = replace(s, " ", "\t"); vector lines = split(script, '\n'); vector> words; @@ -35,74 +64,80 @@ int GetBuiltins(string script) // Go through entire script and iterate through all types to see if line is a // function declaration, then store it with it's value for (int lineNum = 0; lineNum < (int)words.size(); lineNum++) - for (int t = 0; t < (int)types.size(); t++) - if (words[lineNum][0] == types[t]) + { + //Checks if it is function + if (words[lineNum][0] == "func") + { + vector> functionContents; + + string functName = split(words[lineNum][1], '(')[0]; + + string args = ""; + for (int w = 1; w < (int)words[lineNum].size(); w++) // Get all words from the instantiation line: these are the args { - //Checks if it is function - if (words[lineNum][(int)words[lineNum].size() - 1][(int)words[lineNum][(int)words[lineNum].size() - 1].size() - 1] == ')') - { - vector functionContents; - - string functName; - for (int w = 1; w < (int)words[lineNum].size(); w++) { - if (w < (int)words[lineNum].size() - 1) - { - functName += replace(replace(words[lineNum][w], "(", " "), ")", "") + " "; - } - else - { - functName += replace(replace(words[lineNum][w], "(", " "), ")", ""); - } - } - - int numOfBrackets = 1; - for (int p = lineNum + 2; p < (int)words.size(); p++) - { - numOfBrackets += countInVector(words[p], "{") - countInVector(words[p], "}"); - if (numOfBrackets == 0) - break; - functionContents.push_back(""); - for (int w = 0; w < (int)words[p].size(); w++) - { - functionContents[(int)functionContents.size() - 1] += words[p][w] + " "; - } - } - functionContents = removeTabs(functionContents, 1); - builtinFunctions.push_back(functName); - builtinFunctionValues.push_back(functionContents); - } - //Checks if it is variable - else - { - builtinVars.push_back(words[lineNum][0] + " " + words[lineNum][1]); - builtinVarVals.push_back((string)words[lineNum][3]); - //cout << words[lineNum][1] << " is " << words[lineNum][3] << endl; - } + args += replace(replace(words[lineNum][w], "(", " "), ")", ""); } + args = replace(args, functName + " ", ""); + CompilerLog(args); + functionContents.push_back(split(args, ',')); + + int numOfBrackets = 1; + for (int p = lineNum + 2; p < (int)words.size(); p++) + { + numOfBrackets += countInVector(words[p], "{") - countInVector(words[p], "}"); + if (numOfBrackets == 0) + break; + functionContents.push_back(removeTabs(words[p], 1)); + } + builtinFunctionValues[functName] = functionContents; + //cout << functName << " is \n" << Vec2Str(functionContents) << endl << endl; + } + else + { + if (words[lineNum][0] == "string") + builtinVarVals[words[lineNum][1]] = StringRaw(words[lineNum][3]); + else if (words[lineNum][0] == "int") + builtinVarVals[words[lineNum][1]] = stoi(words[lineNum][3]); + else if (words[lineNum][0] == "float") + builtinVarVals[words[lineNum][1]] = stof(words[lineNum][3]); + else if (words[lineNum][0] == "bool") + builtinVarVals[words[lineNum][1]] = stob(words[lineNum][3]); + //else + // LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + to_string(lineNum)); + } + } + return 0; } -string CPPFunction(string name, vector args) +// Executes +boost::any CPPFunction(const string& name, const vector& args) { if (name == "CPP.Math.Sin") - return to_string(sin(stof(args[0]))); + return sin(AnyAsFloat(args[0])); else if (name == "CPP.Math.Cos") - return to_string(cos(stof(args[0]))); + return cos(AnyAsFloat(args[0])); else if (name == "CPP.Math.Tan") - return to_string(tan(stof(args[0]))); + return tan(AnyAsFloat(args[0])); else if (name == "CPP.Math.Round") - return to_string(round(stof(args[0]))); + return AnyAsInt(args[0]); else if (name == "CPP.Graphics.Init") { cout << "\x1B[32mInit graphics\033[0m\t\t" << endl; - if (mainWindow.Construct(stoi(args[0]), stoi(args[1]), stoi(args[2]), stoi(args[2]))) + if (mainWindow.Construct(AnyAsInt(args[0]), AnyAsInt(args[1]), AnyAsInt(args[2]), AnyAsInt(args[2]))) mainWindow.Start(); } else if (name == "CPP.Graphics.SetPixel") - mainWindow.Draw(stoi(args[0]), stoi(args[1]), olc::Pixel(stoi(args[2]), stoi(args[3]), stoi(args[4]))); + mainWindow.Draw(AnyAsInt(args[0]), AnyAsInt(args[1]), olc::Pixel(AnyAsInt(args[2]), AnyAsInt(args[3]), AnyAsInt(args[4]))); + else if (name == "CPP.System.Print") + cout << AnyAsString(args[0]); + else if (name == "CPP.System.PrintLine") + cout << AnyAsString(args[0]) << endl; + else + LogWarning("CPP function \'" + name + "\' does not exist."); - return ""; + return 0; } -#endif \ No newline at end of file +#endif diff --git a/Slang/builtin.slg b/Slang/builtin.slg index 8cb78e8..cc542cf 100644 --- a/Slang/builtin.slg +++ b/Slang/builtin.slg @@ -1,44 +1,52 @@ -float PI = 3.14159265358979 +// Default variables, can be overwritten +// if re-initialized or changed +float PI = 3.14159265358979323846264338 float EulersNumber = 2.71828183 -float Sin(float input) +// Trigonometric function Sin +func Sin(input) { - print input float out = CPP.Math.Sin(input) return out } -float Cos(float input) +// Trigonometric function Cos +func Cos(input) { float out = CPP.Math.Cos(input) return out } -float Tan(float input) +// Trigonometric function Tan +func Tan(input) { float out = CPP.Math.Tan(input) return out } -float Sigmoid(float input) +// Sigmoid activation function +func Sigmoid(input) { float out = 1 / (1+EulersNumber^-input) return out } -float Tanh(float input) +// Hyperbolic tangent activation function +func Tanh(input) { float out = ((EulersNumber^input)-(EulersNumber^-input))/((EulersNumber^input)+(EulersNumber^-input)) return out } -float Round(float input) +// Rounds input to nearest integer value +func Round(input) { float out = CPP.Math.Round(input) return out } -float Clamp(float input, float min, float max) +// Clamps input between min and max +func Clamp(input, min, max) { if input < min { @@ -52,8 +60,20 @@ float Clamp(float input, float min, float max) } // Sets color of pixel to RGB value -float SetPixel(int x, int y, int r, int g, int b) +func SetPixel(x, y, r, g, b) { string out = CPP.Graphics.SetPixel(x, y, r, g, b) return out -} \ No newline at end of file +} + +// Prints input value to console +func Print(in) +{ + CPP.System.Print(in) +} + +// Prints input value to console with appended newline '\n' +func Printl(in) +{ + CPP.System.PrintLine(in) +} diff --git a/Slang/eval.cpp b/Slang/eval.cpp index 873f073..1d2d422 100644 --- a/Slang/eval.cpp +++ b/Slang/eval.cpp @@ -7,9 +7,10 @@ #include #include "eval.h" #include "strops.h" +// #include "builtin.h" using namespace std; -float precedence(char op) { +float precedence(const char& op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/') @@ -19,7 +20,7 @@ float precedence(char op) { return 0; } -float applyOp(float a, float b, char op) { +float applyOp(const float& a, const float& b, const char& op) { switch (op) { case '+': return a + b; case '-': return a - b; @@ -27,12 +28,15 @@ float applyOp(float a, float b, char op) { case '/': return a / b; case '^': return pow(a, b); } + string s(1, op); + //LogWarning("operator \'" + s + "\' does not exist"); + return 0; } // Function that returns value of // expression after evaluation. -float evaluate(string tokens) { - tokens = replace(tokens, " ", ""); +float evaluate(const string& t) { + string tokens = replace(t, " ", ""); float i; diff --git a/Slang/eval.h b/Slang/eval.h index 8650d41..51ac197 100644 --- a/Slang/eval.h +++ b/Slang/eval.h @@ -1,6 +1,6 @@ #ifndef EVAL_H #define EVAL_H -float evaluate(std::string tokens); +float evaluate(const std::string& t); #endif \ No newline at end of file diff --git a/Slang/graphics.h b/Slang/graphics.h index 0030841..389efe0 100644 --- a/Slang/graphics.h +++ b/Slang/graphics.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "strops.h" #include "builtin.h" #include "main.h" @@ -34,7 +35,7 @@ public: bool OnUserUpdate(float fElapsedTime) override { - ExecuteFunction("Update", vector {""}, -1); + ExecuteFunction("Update", vector {}); // Called once per frame //for (int x = 0; x < ScreenWidth(); x++) diff --git a/Slang/main.h b/Slang/main.h index cf8006c..afcb5e1 100644 --- a/Slang/main.h +++ b/Slang/main.h @@ -4,6 +4,6 @@ using namespace std; -string ExecuteFunction(string functionName, vector inputVarVals, int functionIndex); +boost::any ExecuteFunction(const string& functionName, const vector& inputVarVals); -#endif \ No newline at end of file +#endif diff --git a/Slang/script.slg b/Slang/script.slg index 3543223..d34dec2 100644 --- a/Slang/script.slg +++ b/Slang/script.slg @@ -1,7 +1,8 @@ -void Main(string input, int in) +func Main(input, in) { + print "PI is: " + PI int x = 1 print x @@ -12,16 +13,17 @@ void Main(string input, int in) print x float s = Sin(x) print s - int k = Sigmoid(s) + k = Sigmoid(s) print k x += 1 } - CPP.Graphics.Init(64, 64, 4) + //CPP.Graphics.Init(64, 64, 4) + return 0 } -void Update(string input) +func Update(input) { int x = 0 int y = 0 @@ -36,4 +38,4 @@ void Update(string input) x += 1 } print "updating" -} \ No newline at end of file +} diff --git a/Slang/strops.cpp b/Slang/strops.cpp index 1cd112c..3cc700d 100644 --- a/Slang/strops.cpp +++ b/Slang/strops.cpp @@ -3,11 +3,81 @@ #include #include #include +#include #include "strops.h" +//#include "builtin.h" using namespace std; const string WHITESPACE = " \n\r\t\f\v"; + +bool isNumber(const string& str) +{ + for (char const& c : str) { + if (isdigit(c) == 0 && c != '.') return false; + } + return true; +} + +bool stob(const string& str) +{ + bool b = trim(str) == "true"; + return b; +} + +string StringRaw(const string& s) +{ + string str = trim(s); + + if (str.size() < 3) + return str; + + string withoutQuotes; + + if (str[0] != '\"') + withoutQuotes += str[0]; + + withoutQuotes += str.substr(1, str.size() - 2); + + if (str[str.size() - 1] != '\"') + withoutQuotes += str[str.size() - 1]; + + return withoutQuotes; +} + +string Quoted(const string& s) +{ + string str = trim(s); + + string withQuotes; + + if (str[0] != '\"') + withQuotes += '\"'; + + withQuotes += str; + + if (str[str.size() - 1] != '\"') + withQuotes += '\"'; + + return withQuotes; +} + +string RMParenthesis(const string& s) +{ + string str = trim(s); + string withoutParenthesis; + + if (str[0] != '(') + withoutParenthesis += str[0]; + + withoutParenthesis += str.substr(1, str.size() - 2); + + if (str[str.size() - 1] != ')') + withoutParenthesis += str[str.size() - 1]; + + return withoutParenthesis; +} + string ltrim(const string& s) { size_t start = s.find_first_not_of(WHITESPACE); @@ -24,7 +94,7 @@ string trim(const string& s) { return rtrim(ltrim(s)); } -vector split(string str, char del) { +vector split(const string& str, const char& del) { if (count(str, del) == 0) return vector{str}; @@ -51,7 +121,7 @@ vector split(string str, char del) { return splitWords; } -int count(string str, char ch) { +int count(const string& str, const char& ch) { int cnt = 0; for (int i = 0; i < (int)str.size(); i++) @@ -61,7 +131,7 @@ int count(string str, char ch) { return cnt; } -int countNoOverlap(string str, char ch1, char ch2) { +int countNoOverlap(const string& str, const char& ch1, const char& ch2) { int cnt = 0; bool waitingForClose = false; @@ -80,7 +150,7 @@ int countNoOverlap(string str, char ch1, char ch2) { return cnt; } -int indexInStr(string str, char ch) { +int indexInStr(const string& str, const char& ch) { for (int i = 0; i < (int)str.size(); i++) if (str[i] == ch) @@ -89,7 +159,7 @@ int indexInStr(string str, char ch) { return -1; } -int charIndexInVec(vector str, char ch) { +int charIndexInVec(const vector& str, const char& ch) { for (int i = 0; i < (int)str.size(); i++) for (int w = 0; w < (int)str[i].size(); w++) @@ -99,7 +169,7 @@ int charIndexInVec(vector str, char ch) { return -1; } -int countInVector(vector str, string ch) { +int countInVector(const vector& str, const string& ch) { int cnt = 0; for (int i = 0; i < (int)str.size(); i++) @@ -109,7 +179,7 @@ int countInVector(vector str, string ch) { return cnt; } -string Vec2Str(vector str) { +string Vec2Str(const vector& str) { string outStr; for (int i = 0; i < (int)str.size(); i++) @@ -118,7 +188,7 @@ string Vec2Str(vector str) { return outStr; } -vector removeTabs(vector str, int amnt) { +vector removeTabs(const vector& str, const int& amnt) { vector newStr; for (int i = 0; i < (int)str.size(); i++) @@ -135,7 +205,7 @@ vector removeTabs(vector str, int amnt) { return newStr; } -vector rangeInVec(vector str, int min, int max) { +vector rangeInVec(const vector& str, const int& min, int max) { if (max == -1) max = (int)str.size(); @@ -147,7 +217,19 @@ vector rangeInVec(vector str, int min, int max) { return newStr; } -string rangeInStr(string str, int min, int max) { +vector slice(vector const& v, int min, int max) +{ + if (max == -1) + max = (int)v.size() - 1; + + auto first = v.cbegin() + min; + auto last = v.cbegin() + max + 1; + + vector vec(first, last); + return vec; +} + +string rangeInStr(const string& str, const int& min, int max) { if (max == -1) max = (int)str.size(); @@ -159,7 +241,7 @@ string rangeInStr(string str, int min, int max) { return newStr; } -string unWrapVec(vector vec) { +string unWrapVec(const vector& vec) { string newStr; for (int i = 0; i < (int)vec.size(); i++) @@ -172,7 +254,7 @@ string unWrapVec(vector vec) { return newStr; } -float floatval(string s) +float floatval(const string& s) { float outfloat; @@ -188,7 +270,7 @@ float floatval(string s) return outfloat; } -string replace(string str, string strToReplace, string replaceWith) { +string replace(const string& str, const string& strToReplace, const string& replaceWith) { string newStr; string savedLetters; diff --git a/Slang/strops.h b/Slang/strops.h index 79910c4..b34fbf0 100644 --- a/Slang/strops.h +++ b/Slang/strops.h @@ -1,38 +1,52 @@ #ifndef STROPS_H #define STROPS_H +#include + using namespace std; +bool isNumber(const string& str); + +bool stob(const string& str); + +string StringRaw(const string& s); + +string Quoted(const string& s); + +string RMParenthesis(const string& s); + string ltrim(const string& s); string rtrim(const string& s); string trim(const string& s); -vector split(string str, char del); +vector split(const string& str, const char& del); -int count(string str, char ch); +int count(const string& str, const char& ch); -int countNoOverlap(string str, char ch1, char ch2); +int countNoOverlap(const string& str, const char& ch1, const char& ch2); -int indexInStr(string str, char ch); +int indexInStr(const string& str, const char& ch); -int charIndexInVec(vector str, char ch); +int charIndexInVec(const vector& str, const char& ch); -int countInVector(vector str, string ch); +int countInVector(const vector& str, const string& ch); -string Vec2Str(vector str); +string Vec2Str(const vector& str); -vector removeTabs(vector str, int amnt); +vector removeTabs(const vector& str, const int& amnt); -vector rangeInVec(vector str, int min, int max); +vector rangeInVec(const vector& str, const int& min, const int& max); -string rangeInStr(string str, int min, int max); +vector slice(vector const& v, int min, int max); -string unWrapVec(vector vec); +string rangeInStr(const string& str, const int& min, const int& max); -float floatval(string s); +string unWrapVec(const vector& vec); -string replace(string str, string strToReplace, string replaceWith); +float floatval(const string& s); -#endif \ No newline at end of file +string replace(const string& str, const string& strToReplace, const string& replaceWith); + +#endif