From 79b1b7102d2400dcb2f0322e2067fe34aaf2b8d7 Mon Sep 17 00:00:00 2001 From: sam-astro <77079540+sam-astro@users.noreply.github.com> Date: Wed, 5 Jan 2022 15:51:44 -0500 Subject: [PATCH] Fixed most errors, moved things around --- Slang/Main.cpp | 166 +++++++++++++---------------------------------- Slang/anyops.h | 14 ++-- Slang/builtin.h | 108 ++++++++++++++++-------------- Slang/eval.cpp | 6 +- Slang/graphics.h | 2 +- Slang/main.h | 3 +- Slang/strops.cpp | 98 ++++++++++++++++++++++++---- Slang/strops.h | 10 +++ 8 files changed, 216 insertions(+), 191 deletions(-) diff --git a/Slang/Main.cpp b/Slang/Main.cpp index b364309..bc08690 100644 --- a/Slang/Main.cpp +++ b/Slang/Main.cpp @@ -22,76 +22,6 @@ using namespace boost; unordered_map globalVariableValues; unordered_map>> functionValues; - -bool isNumber(const string& str) -{ - for (char const& c : str) { - if (isdigit(c) == 0 && c != '.') return false; - } - return true; -} - -bool stob(string str) { - transform(str.begin(), str.end(), str.begin(), ::tolower); - istringstream is(str); - bool b; - is >> boolalpha >> b; - 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; -} - any GetVariableValue(const string& varName, const unordered_map& variableVals) { auto iA = variableVals.find(varName); @@ -155,19 +85,6 @@ bool IsFunction(const string& funcName) return false; } -int LogWarning(const string& warningText) -{ - cerr << "\x1B[33mWARNING: " << warningText << "\033[0m\t\t" << endl; - return 1; -} - -int CriticalError(const string& errorText) -{ - cerr << "\x1B[31mERROR: " << errorText << "\033[0m\t\t" << endl; - exit(EXIT_FAILURE); - return 2; -} - any EvalExpression(const string& ex, const unordered_map& variableVals) { string expression = trim(ex); @@ -311,17 +228,19 @@ bool BooleanLogic(const string& valA, const string& determinant, const string& v if (determinant == "==") return AnyAsString(valARealValue) == AnyAsString(valBRealValue); - if (determinant == "!=") + else if (determinant == "!=") return AnyAsString(valARealValue) != AnyAsString(valBRealValue); - if (determinant == ">=") + else if (determinant == ">=") return AnyAsFloat(valARealValue) >= AnyAsFloat(valBRealValue); - if (determinant == "<=") + else if (determinant == "<=") return AnyAsFloat(valARealValue) <= AnyAsFloat(valBRealValue); - if (determinant == ">") + else if (determinant == ">") return AnyAsFloat(valARealValue) > AnyAsFloat(valBRealValue); - if (determinant == "<") + else if (determinant == "<") return AnyAsFloat(valARealValue) < AnyAsFloat(valBRealValue); - + else + LogWarning("unrecognized determinant \'" + determinant + "\'"); + return false; } @@ -339,7 +258,8 @@ int varOperation(const vector& str, unordered_map& variable 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; } @@ -355,24 +275,25 @@ int varOperation(const vector& str, unordered_map& variable 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] << "\'"); + LogWarning("uninitialized variable or typo in \'" + str[0] + "\'"); return 1; } -any ProcessLine(const vector>& words, const int lineNum, unordered_map& variableValues) +any ProcessLine(const vector>& words, int lineNum, unordered_map& variableValues) { if (words[lineNum][0][0] == '/' && words[lineNum][0][1] == '/') - return; + return any{}; // If print statement (deprecated, now use CPP.System.Print() function) else if (words[lineNum][0] == "print") { cout << AnyAsString(EvalExpression(unWrapVec(vector(words[lineNum].begin() + 1, words[lineNum].end())), variableValues)) << endl; - return; + return any{}; } // Check if function return @@ -387,26 +308,26 @@ any ProcessLine(const vector>& words, const int lineNum, unordere else if (IsFunction(trim(split(words[lineNum][0], '(')[0]))) { ExecuteFunction(trim(split(words[lineNum][0], '(')[0]), VarValues(split(RMParenthesis(replace(unWrapVec(words[lineNum]), trim(split(words[lineNum][0], '(')[0]), "")), ','), variableValues)); - return; + return any{}; } - + // 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, words[lineNum][0]) > 0) { variableValues[words[lineNum][1]] = EvalExpression(unWrapVec(vector(words[lineNum].begin() + 3, words[lineNum].end())), variableValues); - return; + return any{}; } - + // Check existing variables: If matches, then it means // the variables value is getting changed with an operator else if (IsVar(words[lineNum][0], variableValues)) { // 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; + return any{}; } - + // Gathers while loop contents else if (words[lineNum][0] == "while") { @@ -444,9 +365,9 @@ any ProcessLine(const vector>& words, const int lineNum, unordere return returnVal; } } - return; + return any{}; } - + // Gathers if statement contents else if (words[lineNum][0] == "if") { @@ -481,8 +402,8 @@ any ProcessLine(const vector>& words, const int lineNum, unordere //Iterate through all lines in if statement for (int l = 0; l < (int)ifContents.size(); l++) { - string returnVal = ProcessLine(innerWords, l, variableValues); - if (returnVal != 0) + any returnVal = ProcessLine(innerWords, l, variableValues); + if (!returnVal.empty()) return returnVal; } } @@ -510,16 +431,16 @@ any ProcessLine(const vector>& words, const int lineNum, unordere 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, variableValues); } - return; + return any{}; } - return; + return any{}; } //// Gathers else statement contents //if (words[lineNum][0] == "else") @@ -527,7 +448,7 @@ any ProcessLine(const vector>& words, const int lineNum, unordere // //} - return; + return any{}; } any ExecuteFunction(const string functionName, const vector inputVarVals) @@ -536,10 +457,10 @@ any ExecuteFunction(const string functionName, const vector inputVarVals) vector> words = functionValues[functionName]; unordered_map variableValues; - vector args = split(replace(functionValues[functionName][0][0], ','); + vector args = split(functionValues[functionName][0][0], ','); for (int i = 0; i < (int)inputVarVals.size(); i++) { - variableValues[trim(args[i])] = EvalExpression(inputVarVals[i], variables, variableValues); + variableValues[trim(args[i])] = EvalExpression(AnyAsString(inputVarVals[i]), variableValues); } //Iterate through all lines in function @@ -548,16 +469,16 @@ any ExecuteFunction(const string functionName, const vector inputVarVals) any returnVal = 0; try { - returnVal = ProcessLine(words, lineNum, variables, variableValues); + returnVal = ProcessLine(words, lineNum, variableValues); } catch (const std::exception&) { - CriticalError("\'" << unWrapVec(words[lineNum]) << "\'\nIn function: " << functionName << "\nLine: " << lineNum); + LogCriticalError("\'" + unWrapVec(words[lineNum]) + "\'\nIn function: " + functionName + "\nLine: " + to_string(lineNum)); } if (!returnVal.empty()) return returnVal; } - return; + return any{}; } int parseSlang(string script) @@ -578,8 +499,8 @@ int parseSlang(string script) { vector> functionContents; - string functName = split(words[lineNum][1], "(")[0]; - + string functName = split(words[lineNum][1], '(')[0]; + string args = ""; for (int w = 1; w < (int)words[lineNum].size(); w++) { if (w < (int)words[lineNum].size() - 1) @@ -591,7 +512,7 @@ int parseSlang(string script) args += replace(replace(words[lineNum][w], "(", " "), ")", ""); } } - + args = replace(args, functName + ",", ""); functionContents.push_back(vector{args}); @@ -608,15 +529,16 @@ int parseSlang(string script) } else { - if(words[lineNum][0] == "string") + if (words[lineNum][0] == "string") globalVariableValues[words[lineNum][1]] = StringRaw(words[lineNum][3]); - else if(words[lineNum][0] == "int") + else if (words[lineNum][0] == "int") globalVariableValues[words[lineNum][1]] = stoi(words[lineNum][3]); - else if(words[lineNum][0] == "float") + else if (words[lineNum][0] == "float") globalVariableValues[words[lineNum][1]] = stof(words[lineNum][3]); - else if(words[lineNum][0] == "bool") + else if (words[lineNum][0] == "bool") globalVariableValues[words[lineNum][1]] = stob(words[lineNum][3]); - LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + lineNum); + else + LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + to_string(lineNum)); } } diff --git a/Slang/anyops.h b/Slang/anyops.h index a95ca54..4430214 100644 --- a/Slang/anyops.h +++ b/Slang/anyops.h @@ -2,7 +2,11 @@ #ifndef ANYOPS_H #define ANYOPS_H +#include "builtin.h" +#include + using namespace boost; +using namespace std; // Will convert type 'any' val to a bool bool AnyAsBool(const any& val) @@ -31,7 +35,7 @@ bool AnyAsBool(const any& val) } catch (boost::bad_any_cast &e) // Does not convert, return { - LogWarning("invalid conversion to type \'bool\'") + LogWarning("invalid conversion to type \'bool\'"); return false; } } @@ -68,7 +72,7 @@ string AnyAsString(const any& val) } catch (boost::bad_any_cast &e) // Does not convert, return { - LogWarning("invalid conversion to type \'string\'") + LogWarning("invalid conversion to type \'string\'"); return ""; } } @@ -105,7 +109,7 @@ float AnyAsFloat(const any& val) } catch (boost::bad_any_cast &e) // Does not convert, return { - LogWarning("invalid conversion to type \'float\'") + LogWarning("invalid conversion to type \'float\'"); return 0; } } @@ -142,7 +146,7 @@ int AnyAsInt(const any& val) } catch (boost::bad_any_cast &e) // Does not convert, return { - LogWarning("invalid conversion to type \'int\'") + LogWarning("invalid conversion to type \'int\'"); return 0; } } @@ -182,7 +186,7 @@ int any_type(const any& val) } catch (boost::bad_any_cast &e) // Does not convert, return { - LogWarning("variable has no type") + LogWarning("variable has no type"); return -1; } } diff --git a/Slang/builtin.h b/Slang/builtin.h index 0c5421b..da283d2 100644 --- a/Slang/builtin.h +++ b/Slang/builtin.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "strops.h" #include "graphics.h" #include "anyops.h" @@ -16,15 +17,29 @@ using namespace std; vector types = { "int", "float", "string", "bool", "void", "null" }; -unordered_map> builtinFunctionValues; -unordered_map& builtinVarVals; +unordered_map>> builtinFunctionValues; +unordered_map builtinVarVals; Parser mainWindow; + +int LogWarning(const string& warningText) +{ + cerr << "\x1B[33mWARNING: " << warningText << "\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) { - script = replace(s, " ", "\t"); + string script = replace(s, " ", "\t"); vector lines = split(script, '\n'); vector> words; @@ -36,56 +51,55 @@ int GetBuiltins(const string& s) // 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][(int)words[lineNum].size() - 1][(int)words[lineNum][(int)words[lineNum].size() - 1].size() - 1] == ')') + { + //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++) { + if (w < (int)words[lineNum].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); - builtinFunctionValues[functName] = functionContents; + args += replace(replace(words[lineNum][w], "(", " "), ")", "") + ","; } - //Checks if it is variable else { - if(words[lineNum][0] == "string") - builtinVarVals[words[lineNum][1]] = 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]); - //cout << words[lineNum][1] << " is " << words[lineNum][3] << endl; + args += replace(replace(words[lineNum][w], "(", " "), ")", ""); } } + args = replace(args, functName + ",", ""); + functionContents.push_back(vector{args}); + + int numOfBrackets = 1; + for (int p = lineNum + 3; 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; } @@ -113,7 +127,7 @@ any CPPFunction(const string& name, const vector& args) else if (name == "CPP.System.PrintLine") cout << AnyAsString(args[0]) << endl; else - LogWarning("CPP function \'" + name + "\' does not exist.") + LogWarning("CPP function \'" + name + "\' does not exist."); return 0; } diff --git a/Slang/eval.cpp b/Slang/eval.cpp index 9fd9af6..4373a00 100644 --- a/Slang/eval.cpp +++ b/Slang/eval.cpp @@ -7,6 +7,7 @@ #include #include "eval.h" #include "strops.h" +#include "builtin.h" using namespace std; float precedence(const char& op) { @@ -26,15 +27,16 @@ float applyOp(const float& a, const float& b, const char& op) { case '*': return a * b; case '/': return a / b; case '^': return pow(a, b); - default: LogWarning("operator \'" << op << "\' does not exist"); } + string s(1, op); + LogWarning("operator \'" + s + "\' does not exist"); return 0; } // Function that returns value of // expression after evaluation. float evaluate(const string& t) { - tokens = replace(t, " ", ""); + string tokens = replace(t, " ", ""); float i; diff --git a/Slang/graphics.h b/Slang/graphics.h index 0030841..918aba2 100644 --- a/Slang/graphics.h +++ b/Slang/graphics.h @@ -34,7 +34,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 1e85a82..25cbe2d 100644 --- a/Slang/main.h +++ b/Slang/main.h @@ -3,7 +3,8 @@ #define MAIN_H using namespace std; +using namespace boost; -any ExecuteFunction(const string functionName, const vector inputVarVals) +any ExecuteFunction(const string functionName, const vector inputVarVals); #endif diff --git a/Slang/strops.cpp b/Slang/strops.cpp index 1cd112c..83b42de 100644 --- a/Slang/strops.cpp +++ b/Slang/strops.cpp @@ -4,10 +4,82 @@ #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(string str) +{ + transform(str.begin(), str.end(), str.begin(), ::tolower); + istringstream is(str); + bool b; + is >> boolalpha >> b; + 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 +96,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 +123,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 +133,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 +152,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 +161,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 +171,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 +181,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 +190,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 +207,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 +219,7 @@ vector rangeInVec(vector str, int min, int max) { return newStr; } -string rangeInStr(string str, int min, int max) { +string rangeInStr(const string& str, const int& min, int max) { if (max == -1) max = (int)str.size(); @@ -159,7 +231,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 +244,7 @@ string unWrapVec(vector vec) { return newStr; } -float floatval(string s) +float floatval(const string& s) { float outfloat; @@ -188,7 +260,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 47d4d41..6ead244 100644 --- a/Slang/strops.h +++ b/Slang/strops.h @@ -3,6 +3,16 @@ using namespace std; +bool isNumber(const string& str); + +bool stob(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);