diff --git a/bin/microwavebasic b/bin/microwavebasic new file mode 100644 index 0000000..ef6d1eb Binary files /dev/null and b/bin/microwavebasic differ diff --git a/commands.txt b/commands.txt new file mode 100644 index 0000000..08a417c --- /dev/null +++ b/commands.txt @@ -0,0 +1,62 @@ +MicrowaveBASIC Commands + +* The ID are the variables that can contain integers +* The ID$ are the variables that can contain strings + +[ P ] Print a string expression + 10 P "Hello, World!" + // Prints "Hello, World!" + +[ p ] Same as P but without line return + 10 p "Hello, " + 20 P "World!" + // Prints "Hello, " without linebreak then prints "World!" with a linebreak + // Showing "Hello, World!" on one line. + +[ ?<*/$> ] Asks for number (*) or string ($) + 10 p "What's your name? " + 20 ?$ A + 30 P "Hello, " + A + +[ * ] Displays a math expression + 10 p "First number : " + 20 ?* A + 30 p "Second number : " + 40 ?* B + 50 * A + 60 p " + " + 70 * B + 80 p " = " + 90 * A + B + // Example output + // First number : 4 + // Second number : 8 + // 4 + 8 = 12 + +[ =<*/$> ] Set integer (*) or a string <$> to a variable + 10 =* A 12+24 + 20 =* A A+1 + 30 =$ A "12+24+1=" + // String variables are separated from integer variables + 40 p A + 50 * A + 60 P "" + // Output : 12+24+1=37 + +[ G ] Go to a specified line + 10 P "S P A M S P A M S P A M S P A M" + 20 G 10 + // Do I need to explain how does this code works? + +[ I<$/*> : ] If condition + 10 p "Enter loop : " + 20 ?$ A + 30 I$ A="loop" : G 50 + 40 G 80 + 50 * A + 60 =* A A+1 + 70 I* A<10 G 50 + // Example Output + // Enter loop : loop + // 0123456789 + \ No newline at end of file diff --git a/compile.sh b/compile.sh new file mode 100644 index 0000000..5019c37 --- /dev/null +++ b/compile.sh @@ -0,0 +1,3 @@ +echo "Compiling MicrowaveBASIC Interpreter..." +g++ *.cpp libs/*.cpp -o bin/microwavebasic +echo "Done!" diff --git a/engine.cpp b/engine.cpp new file mode 100644 index 0000000..6563820 --- /dev/null +++ b/engine.cpp @@ -0,0 +1,182 @@ +#include +#include +#include +#include +#include + +#include "engine.h" +#include "utils.h" +#include "libs/stringadd.h" +#include "libs/stringop.h" +#include "libs/stringcond.h" +using namespace std; + +// This cpp file contains the whole engine to run code. +// Version of the software +string VERSION = "0.1.0-alpha"; +string* stringvars = new string[128]; +int* intvars = new int[128]; + +//Boot screen. Displays useless info +void BootScreen() { + cout<<"MicrowaveBASIC " << VERSION << " by h34ting4ppliance \nCopyright (C) Microwave Micro-computers Co."<= 1) + i = o - 1; + + o = 0; + } +} + +//Will execute only a single line. +int ExecuteLine(std::string line, int pptr) { + if (boost::starts_with(line, "P ")) { // " PRINT command + string o = line.erase(0, 2); + if (o == "") { + cout << "!SYNTAX ERROR" << endl; + return -1; + } + else + cout << evalStringAddition(o, stringvars) << endl; + + return 0; + } else if (boost::starts_with(line, "//")) // Comment + return 0; + else if (boost::starts_with(line, "p ")) { // ' PRINT command + string o = line.erase(0, 2); + if (o == "") { + cout << "!SYNTAX ERROR" << endl; + return -1; + } + else + cout << evalStringAddition(o, stringvars); + return 0; + } else if (boost::starts_with(line, "?* ")) { + string o = line.erase(0, 3); + string inp = ""; + if (o == "" || !isalpha(o.at(0))) { + cout << "!SYNTAX ERROR" << endl; + return -1; + } + else { + getline(cin, inp); + if (!is_number(inp)) { + cout << "!INPUT ERROR" << endl; + return -1; + } + intvars[toupper(o.at(0)) - 'A'] = evalString(inp, intvars, false); + } + return 0; + } else if (boost::starts_with(line, "?$ ")) { + string o = line.erase(0, 3); + string inp = ""; + + if (o == "" || !isalpha(o.at(0))) { + cout << "!SYNTAX ERROR" << endl; + return -1; + } else { + getline(cin, inp); + stringvars[toupper(o.at(0)) - 'A'] = inp; + } + + return 0; + } else if (boost::starts_with(line, "* ")) { + string o = line.erase(0, 2); + + if (o == "" || !isalpha(o.at(0))) { + cout << "!SYNTAX ERROR" << endl; + return -1; + } else { + cout << to_string(intvars[toupper(o.at(0)) - 'A']); + return 0; + } + } else if (boost::starts_with(line, "=* ")) { + string o = line.erase(0, 3); + string oa = line.erase(0, 1); + if (o == "" || !isalpha(o.at(0)) || oa == "") { + cout << "!SYNTAX ERROR" << endl; + return -1; + } else { + intvars[toupper(o.at(0)) - 'A'] = evalString(oa, intvars, false); + return 0; + } + } else if (boost::starts_with(line, "G ")) { + if (pptr == -1) { + cout << "!PROGRAM ERROR" << endl; + return -1; + } + string o = line.erase(0, 2); + if (!is_number(o)) { + cout << "!SYNTAX ERROR" << endl; + return -1; + } + pptr = evalString(o, intvars, false) - 1; + if (pptr <= 0) { + cout << "!SYNTAX ERROR" << endl; + return -1; + } + return pptr; + } else if (boost::starts_with(line, "I* ")) { + string o = line.erase(0, 3); + int sepPos = searchChar(':', o); + if (sepPos == -1) { // If sepPos = -1, that means not any separator has been detected + cout << "!SYNTAX ERROR" << endl; + return -1; + } + + string argA = trimString(o, 0, sepPos - 1); + string argB = trimString(o, sepPos + 1, line.size() - 1); + + bool condi = evalIntCondition(argA, intvars); + if (condi) { + int a = ExecuteLine(argB, pptr); + if (a == -1) + return -1; + else + return 0; + } else { + return -1; + } + } else if (boost::starts_with(line, "I$ ")) { + string o = line.erase(0, 3); + int sepPos = searchChar(':', o); + if (sepPos == -1) { // If sepPos = -1, that means not any separator has been detected + cout << "!SYNTAX ERROR" << endl; + return -1; + } + + string argA = trimString(o, 0, sepPos - 1); + string argB = trimString(o, sepPos + 1, line.size() - 1); + + bool condi = evalStrCondition(argA, stringvars); + if (condi) { + int a = ExecuteLine(argB, pptr); + if (a == -1) + return -1; + else + return a; + } else { + return 0; + } + } + + else if (line != "") { + cout << "!SYNTAX ERROR" << endl; + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/engine.h b/engine.h new file mode 100644 index 0000000..0f23503 --- /dev/null +++ b/engine.h @@ -0,0 +1,7 @@ +#ifndef ENGINE_H +#define ENGINE_H + +void BootScreen(); +void ExecuteCode(std::string*); +int ExecuteLine(std::string, int); +#endif \ No newline at end of file diff --git a/libs/stringadd.cpp b/libs/stringadd.cpp new file mode 100644 index 0000000..40c0066 --- /dev/null +++ b/libs/stringadd.cpp @@ -0,0 +1,82 @@ +#include +#include +#include +#include "stringadd.h" +using namespace std; +// This code allows to perform string addition + +std::string evalStringAddition(std::string o, const string* vars) { + string* strings = new string[50]; + string outputStr = ""; + + char c; // Current character + int previousType = 0; // Previous type + int ptr = 0; // Array pointer + int endline; // End of array. Variable for optimization purposes. + bool isInQuotes = false; + + for (int i = 0; i < o.size(); ++i) { + if (ptr > 48) { // To avoid out of range error + cout << "[stringadd.cpp] Syntax Error! (Pointer out of range)" << endl; + return 0; + } + c = o.at(i); + + if (isInQuotes == true) { + if (c == '\"') { + previousType = 1; + isInQuotes = false; + continue; + } else { + strings[ptr] += c; + continue; + } + + continue; + } + // The code isn't going further than that as long at there isn't another quote to close it. + if (previousType == 0 || previousType == 3) { + if (c == '\"') { + isInQuotes = true; + continue; + } else if (isalpha(c)) { + strings[ptr] = vars[toupper(c) - 'A']; + previousType = 2; + ++ptr; + continue; + } else if (c == '+') { + cout << "[stringadd.cpp] Syntax Error! (Misplaced operator)" << endl; + return "ERR"; + } else if (c == ' ') { + continue; + } else { + cout << "[stringadd.cpp] Syntax Error! (Unknown character)" << endl; + return "ERR"; + } + } else if (previousType == 1 || previousType == 2) { + if (c == '"') { + cout << "[stringadd.cpp] Syntax Error! (Misplaced quote)" << endl; + return "ERR"; + } else if (isalpha(c)) { + cout << "[stringadd.cpp] Syntax Error! (Misplaced variable)" << endl; + return "ERR"; + } else if (c == '+') { + previousType = 3; + ++ptr; + continue; + } else if (c == ' ') { + continue; + } else { + cout << "[stringadd.cpp] Syntax Error! (Unknown character)" << endl; + return "ERR"; + } + } + } + + endline = ptr + 1; + for (int i = 0; i < endline; ++i) { + outputStr += strings[i]; + } + + return outputStr; +} \ No newline at end of file diff --git a/libs/stringadd.h b/libs/stringadd.h new file mode 100644 index 0000000..74d16a0 --- /dev/null +++ b/libs/stringadd.h @@ -0,0 +1,5 @@ +#ifndef STRINGADD_H +#define STRINGADD_H + +std::string evalStringAddition(std::string, const std::string*); +#endif \ No newline at end of file diff --git a/libs/stringcond.cpp b/libs/stringcond.cpp new file mode 100644 index 0000000..5c5f5cd --- /dev/null +++ b/libs/stringcond.cpp @@ -0,0 +1,149 @@ +#include +#include +#include "stringadd.h" +#include "stringop.h" +#include "stringcond.h" +using namespace std; + +string trimStr(string s, int start, int end) { + string o = ""; + for (int i = start; i <= end; ++i) { + o += s.at(i); + } + + return o; +} + +// To eval strings +bool evalStrCondition(string condition, std::string* vars) { + char c; + int ops = 0; + int operatorPos = 0; + char op; + string expA, expB; + + if (condition == "TRUE") + return true; + else if (condition == "FALSE") + return false; + + // Those lines of code are there to control the number of operators + // (It must have only one) + for (int i = 0; i < condition.size(); ++i) { // Must check if there is only one operator + c = condition.at(i); + if (c == '=' || c == '!') + ++ops; + // Operator at the first character + if (i == 0 && ops == 1) { + cout << "[stringcond.cpp] Syntax Error! (Misplaced operator)" << endl; + return false; + } + + if (ops == 1 && operatorPos == 0) { + operatorPos = i; + op = c; + } + + // Too many operators + if (ops > 1) { + cout << "[stringcond.cpp] Syntax Error! (Too many operators)" << endl; + return false; + } + + // Operator at the end of the string + if (ops == 1 && operatorPos == condition.size() - 1) { + cout << "[stringcond.cpp] Syntax Error! (Misplaced operator)" << endl; + return false; + } + } + + // No operators + if (ops == 0) { + cout << "[stringcond.cpp] Syntax Error! (No operators)" << endl; + return false; + } + + expA = trimStr(condition, 0, operatorPos - 1); + expB = trimStr(condition, operatorPos + 1, condition.size() - 1); + + if (op == '=') { + if (evalStringAddition(expA, vars) == evalStringAddition(expB, vars)) + return true; + else + return false; + } else { + if (evalStringAddition(expA, vars) != evalStringAddition(expB, vars)) + return true; + else + return false; + } + + return false; +} + + +bool evalIntCondition(string condition, int* vars) { + char c; + int ops = 0; + int operatorPos = 0; + char op; + string expA, expB; + + if (condition == "TRUE") + return true; + else if (condition == "FALSE") + return false; + + // Those lines of code are there to control the number of operators + // (It must have only one) + for (int i = 0; i < condition.size(); ++i) { // Must check if there is only one operator + c = condition.at(i); + if (c == '=' || c == '!') + ++ops; + // Operator at the first character + if (i == 0 && ops == 1) { + cout << "[stringcond.cpp] Syntax Error! (Misplaced operator)" << endl; + return false; + } + + if (ops == 1 && operatorPos == 0) { + operatorPos = i; + op = c; + } + + // Too many operators + if (ops > 1) { + cout << "[stringcond.cpp] Syntax Error! (Too many operators)" << endl; + return false; + } + + // Operator at the end of the string + if (ops == 1 && operatorPos == condition.size() - 1) { + cout << "[stringcond.cpp] Syntax Error! (Misplaced operator)" << endl; + return false; + } + } + + // No operators + if (ops == 0) { + cout << "[stringcond.cpp] Syntax Error! (No operators)" << endl; + return false; + } + + expA = trimStr(condition, 0, operatorPos - 1); + expB = trimStr(condition, operatorPos + 1, condition.size() - 1); + + if (op == '=') { + if (evalString(expA, vars, false) == evalString(expB, vars, false)) + return true; + else + return false; + } else { + if (evalString(expA, vars, false) != evalString(expB, vars, false)) + return true; + else + return false; + } + + return false; +} \ No newline at end of file diff --git a/libs/stringcond.h b/libs/stringcond.h new file mode 100644 index 0000000..45b7950 --- /dev/null +++ b/libs/stringcond.h @@ -0,0 +1,6 @@ +#ifndef STRINGCOND_H +#define STRINGCOND_H + +bool evalStrCondition(std::string, std::string*); +bool evalIntCondition(std::string, int*); +#endif \ No newline at end of file diff --git a/libs/stringop.cpp b/libs/stringop.cpp new file mode 100644 index 0000000..8d4e953 --- /dev/null +++ b/libs/stringop.cpp @@ -0,0 +1,183 @@ +// Simple string arithmetic interpreter by h34 +// Originally designed for my MicrowaveBASIC interpreter + +#include +#include +#include +#include "stringop.h" +using namespace std; + +bool isoperator(char c) { + return ((c == '+') || (c == '-') || (c == '*') || (c == '/')); +} + +int* moveArrayLeft(int* arr, int start, int end) { + for (int i = start; i < end; ++i) { + arr[i - 1] = arr[i]; + } + + return arr; +} + +int evalString(std::string o, const int* vars, bool dev) { + /* the vars array is the array where variables are stored. + This has been made for being able to make arithmetics with + variables of the BASIC Interpreter. If you don't need that, + just put an empty array.*/ + + int* numbers = new int[100]; + int* ops = new int[99]; // 0 = Nothing | 1 = + | 2 = - | 3 = * | 4 = / + // Supported operators : * / + - + // Parentheses aren't supported. + char c; + int previousType = 0; // O = Nothing | 1 = Number | 2 = Operator | 3 = Variable + int ptr = 0; // Pointer + int endline; // Position of the array where it ends + + //Step 1 - Sorting out stuff and put them in arrays + for (int i = 0; i < o.size(); ++i) { + if (ptr > 98) { + cout << "[stringop.cpp] Syntax Error! (Pointer out of range)" << endl; + return 0; + } + c = o.at(i); + if (previousType == 0) { + if (isoperator(c)) { + cout << "[stringop.cpp] Syntax Error! (Misplaced operator)" << endl; + return 0; + } else if (isdigit(c)) { + previousType = 1; + numbers[ptr] = c - '0'; + continue; + } else if (isalpha(c)) { + previousType = 3; + numbers[ptr] = vars[toupper(c) - 'A']; + continue; + } else if (c == ' ') + continue; + else { + cout << "[stringop.cpp] Syntax Error! (Unknown character)" << endl; + return 0; + } + + } else if (previousType == 1) { + if (isoperator(c)) { + previousType = 2; + if (c == '+') + ops[ptr] = 1; + if (c == '-') + ops[ptr] = 2; + if (c == '*') + ops[ptr] = 3; + if (c == '/') + ops[ptr] = 4; + + ++ptr; + continue; + } else if (isdigit(c)) { + numbers[ptr] = numbers[ptr] * 10 + (c - '0'); + continue; // No need to change the previous type since it's still the same + } else if (isalpha(c)) { + cout << "[stringop.cpp] Syntax Error! (Misplaced variable)" << endl; + return 0; + } else if (c == ' ') + continue; + else { + cout << "[stringop.cpp] Syntax Error! (Unknown character)" << endl; + return 0; + } + } else if (previousType == 2) { + if (isoperator(c)) { + cout << "[stringop.cpp] Syntax Error! (Misplaced operator)" << endl; + return 0; + } else if (isdigit(c)) { + previousType = 1; + numbers[ptr] = c - '0'; + continue; + } else if (isalpha(c)) { + previousType = 3; + numbers[ptr] = vars[toupper(c) - 'A']; + continue; + } else if (c == ' ') + continue; + else { + cout << "[stringop.cpp] Syntax Error! (Unknown character)" << endl; + return 0; + } + } else if (previousType == 3) { + if (isoperator(c)) { + previousType = 2; + if (c == '+') + ops[ptr] = 1; + if (c == '-') + ops[ptr] = 2; + if (c == '*') + ops[ptr] = 3; + if (c == '/') + ops[ptr] = 4; + + ++ptr; + continue; + } else if (isalpha(c)) { + cout << "[stringop.cpp] Syntax Error! (Misplaced variable)" << endl; + return 0; + } else if (c == ' ') + continue; + else { + cout << "[stringop.cpp] Syntax Error! (Unknown character)" << endl; + return 0; + } + } + } + + endline = ptr + 1; + if (dev) { + cout << "Array variables data (from numbers and ops arrays)" << endl; + for (int i = 0; i < endline; ++i) { + cout << to_string(numbers[i]) << " "; + } + cout << endl; + for (int i = 0; i < endline - 1; ++i) { + cout << to_string(ops[i]); + } + cout << endl << endl; + } + + // Step 2 - Make the calculation + + // Priority 1 - * and / + for (int i = 0; i < endline - 1; ++i) { + if ((ops[i] == 3) || (ops[i] == 4)) { + if (ops[i] == 3) + numbers[i + 1] = numbers[i] * numbers[i + 1]; + else + numbers[i + 1] = numbers[i] / numbers[i + 1]; + + numbers = moveArrayLeft(numbers, i + 1, endline); + ops = moveArrayLeft(ops, i + 1, endline); + --i; + --endline; + continue; + } else + continue; + } + + // Priority 2 - + and - + for (int i = 0; i < endline - 1; ++i) { + if ((ops[i] == 1) || (ops[i] == 2)) { + if (ops[i] == 1) + numbers[i + 1] = numbers[i] + numbers[i + 1]; + else + numbers[i + 1] = numbers[i] - numbers[i + 1]; + + numbers = moveArrayLeft(numbers, i + 1, endline); + ops = moveArrayLeft(ops, i + 1, endline); + --i; + --endline; + continue; + } else + continue; + } + + return numbers[0]; +} diff --git a/libs/stringop.h b/libs/stringop.h new file mode 100644 index 0000000..6d09138 --- /dev/null +++ b/libs/stringop.h @@ -0,0 +1,5 @@ +#ifndef STRINGOP_H +#define STRINGOP_H + +int evalString(std::string, const int*, bool); +#endif \ No newline at end of file diff --git a/libs/tests/stringadd_test b/libs/tests/stringadd_test new file mode 100644 index 0000000..df7cd6e Binary files /dev/null and b/libs/tests/stringadd_test differ diff --git a/libs/tests/stringadd_test.cpp b/libs/tests/stringadd_test.cpp new file mode 100644 index 0000000..229672a --- /dev/null +++ b/libs/tests/stringadd_test.cpp @@ -0,0 +1,23 @@ +#include +#include +#include "../stringadd.h" +using namespace std; +//stringop.cpp string arithmetic evaluator test program +//This program is not meant to be compiled with the interpreter + +//Making an array +string* vars = new string[26]; + +int main() { + // Storing some test variables + vars[0] = "beanos"; // Variable A = "beanos" + vars[1] = "shrek"; // Variable B = "shrek" + string result; + + string ari; + getline(cin, ari); + result = evalStringAddition(ari, vars); + + cout << endl << "=========" << endl << "Result : \"" << result << "\"" << endl; + return 0; +} \ No newline at end of file diff --git a/libs/tests/stringcond_test.cpp b/libs/tests/stringcond_test.cpp new file mode 100644 index 0000000..6dbc1d1 --- /dev/null +++ b/libs/tests/stringcond_test.cpp @@ -0,0 +1,55 @@ +#include +#include +#include "../stringcond.h" +using namespace std; +//stringop.cpp string arithmetic evaluator test program +//This program is not meant to be compiled with the interpreter + +//Making an array +string* vars = new string[26]; +int* varsi = new int[26]; +string boolToStr(bool b) { + if (b) + return "true"; + else + return "false"; +} + +void eint() { + // Storing some test variables + varsi[0] = 22; // Variable A = 22 + varsi[1] = 48; // Variable B = 48 + int result; + + string ari; + getline(cin, ari); + result = evalIntCondition(ari, varsi); + + cout << endl << "=========" << endl << "Result : " << boolToStr(result) << endl; +} + +void estr() { + // Storing some test variables + vars[0] = "beanos"; // Variable A = "beanos" + vars[1] = "shrek"; // Variable B = "shrek" + bool result; + + string ari; + getline(cin, ari); + result = evalStrCondition(ari, vars); + + cout << endl << "=========" << endl << "Result : \"" << boolToStr(result) << "\"" << endl; +} + +int main() { + cout << "Type 'shrek' to get in int mode and 'beanos' to get in string mode"; + string choice; + getline(cin, choice); + + cout << endl << ">>"; + if (choice == "shrek") { + eint(); + } else if (choice == "beanos") { + estr(); + } +} \ No newline at end of file diff --git a/libs/tests/stringop_test.cpp b/libs/tests/stringop_test.cpp new file mode 100644 index 0000000..eaf67cb --- /dev/null +++ b/libs/tests/stringop_test.cpp @@ -0,0 +1,23 @@ +#include +#include +#include "../stringop.h" +using namespace std; +//stringop.cpp string arithmetic evaluator test program +//This program is not meant to be compiled with the interpreter + +//Making an array +int* vars = new int[26]; + +int main() { + // Storing some test variables + vars[0] = 22; // Variable A = 22 + vars[1] = 48; // Variable B = 48 + int result; + + string ari; + getline(cin, ari); + result = evalString(ari, vars, true); + + cout << endl << "=========" << endl << "Result : " << to_string(result) << endl; + return 0; +} \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..021a69e --- /dev/null +++ b/main.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include "engine.h" +#include "utils.h" +#include "libs/stringop.h" +using namespace std; + +/* +/=============================\ +| MicrowaveBASIC | +\=============================/ + +C++ version. Cus I want this shit to be cross-platform +and native. + +The purpose is to make a retro computer simulation of +those 80s micro-computers. It will work with BASIC and +will have some basic commands like PRINT, DIM, INPUT, etc. + +This is a very simple program not designed to make you a +developer. + */ + + string* PrgmMem = new string[999999]; + + int main() { + BootScreen(); + cout << endl; + string cmd; + int o; + int* dummylol = new int[26]; + while (true) { + getline(cin, cmd); + + string cmdu = cmd; + boost::to_upper(cmdu); + + if (cmdu == "EXIT") + break; + else if (is_number(trimString(cmd, 0, searchChar(' ', cmd) - 1))) { + string a = trimString(cmd, 0, searchChar(' ', cmd)); + int linnum = evalString(a, dummylol, false); // Lmao I can't code :D + PrgmMem[linnum] = cmd.erase(0, a.size()); + } else if (cmdu == "LIST") { + for (int i = 0; i < 999999; ++i) { + if (PrgmMem[i] != "") + cout << to_string(i) << " " << PrgmMem[i] << endl; + } + } else if (cmdu == "NEW") { + for (int i = 0; i > 999999; ++i) { + PrgmMem[i] = ""; + } + } else if (cmdu == "RUN") { + ExecuteCode(PrgmMem); + } + else + o = ExecuteLine(cmd, -1); + //Making it an endless loop + } + + return 0; + } \ No newline at end of file diff --git a/utils.cpp b/utils.cpp new file mode 100644 index 0000000..55bedc4 --- /dev/null +++ b/utils.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include "utils.h" + +using namespace std; +// This file contains many useful commands to be globally used which +// most of them come from Stack Overflow lol + +// To check if a string is a number +bool is_number(const std::string s) +{ + std::string::const_iterator it = s.begin(); + while (it != s.end() && std::isdigit(*it)) ++it; + return !s.empty() && it == s.end(); +} + +// search a specific character +int searchChar(char target, string s) { + for (int i = 0; i < s.size(); ++i) { + if (s.at(i) == target) + return i; + } + + return -1; // Returns -1 if nothing has been found +} + +// To split spaces and put every words into a string array +std::string* splitSpaces(std::string line) +{ + string* arr = new string[20]; + int i = 0; + stringstream ssin(line); + while (ssin.good() && i < 20){ + if (arr[i] == "") + break; + ssin >> arr[i]; + ++i; + } + + return arr; +} + +string trimString(string s, int start, int end) { + string o = ""; + for (int i = start; i <= end; ++i) { + o += s.at(i); + } + + return o; +} \ No newline at end of file diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..2472677 --- /dev/null +++ b/utils.h @@ -0,0 +1,8 @@ +#ifndef UTILS_H +#define UTILS_H + +bool is_number(const std::string); +std::string* splitSpaces(std::string line); +int searchChar(char, std::string); +std::string trimString(std::string, int, int); +#endif \ No newline at end of file