From c75ba20ff6913b80b677d2af5566a5bb75f8c903 Mon Sep 17 00:00:00 2001 From: sam-astro <77079540+sam-astro@users.noreply.github.com> Date: Thu, 19 May 2022 08:40:49 -0400 Subject: [PATCH 1/2] Update Main.cpp --- ZSharp/Main.cpp | 57 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/ZSharp/Main.cpp b/ZSharp/Main.cpp index 7f829ff..fd0410b 100644 --- a/ZSharp/Main.cpp +++ b/ZSharp/Main.cpp @@ -371,6 +371,7 @@ int varOperation(const vector& str, unordered_map& v boost::any ProcessLine(const vector>& words, int lineNum, unordered_map& variableValues) { + // Check if the first two chars are '//', which would make it a comment if (words.at(lineNum).at(0)[0] == '/' && words.at(lineNum).at(0)[1] == '/') return nullType; @@ -381,7 +382,7 @@ boost::any ProcessLine(const vector>& words, int lineNum, unorder return nullType; } - // Check if function return + // Check if it is a function return else if (words.at(lineNum).at(0) == "return") return EvalExpression(unWrapVec(vector(words.at(lineNum).begin() + 1, words.at(lineNum).end())), variableValues); @@ -423,7 +424,7 @@ boost::any ProcessLine(const vector>& words, int lineNum, unorder return nullType; } - // Check existing variables: To see if class sub component matches + // Check existing variables: To see if accessign class sub component else if (count(words.at(lineNum).at(0), '.') > 0 && IsVar(split(words.at(lineNum).at(0), '.')[0], variableValues) || IsVar(split(words.at(lineNum).at(0), '.')[0], globalVariableValues)) { if (IsVar(split(words.at(lineNum).at(0), '.')[0], variableValues)) @@ -433,7 +434,7 @@ boost::any ProcessLine(const vector>& words, int lineNum, unorder return nullType; } - // Gathers while loop contents + // If declaring a while loop, loop until false else if (words.at(lineNum).at(0) == "while") { vector> whileContents; @@ -465,7 +466,7 @@ boost::any ProcessLine(const vector>& words, int lineNum, unorder return nullType; } - // Gathers if statement contents + // If declaring an if statement, only execute if true else if (words.at(lineNum).at(0) == "if") { vector> ifContents; @@ -542,13 +543,13 @@ boost::any ProcessLine(const vector>& words, int lineNum, unorder boost::any ExecuteFunction(const string& functionName, const vector& inputVarVals) { - // Get contents of function + // Get contents of function from global function map std::vector> words = functionValues[functionName]; unordered_map variableValues = {}; std::vector funcArgs = words.at(0); - + // Set function variables equal to whatever inputs were provided for (int i = 0; i < (int)inputVarVals.size(); i++) { if(i < funcArgs.size()) @@ -578,14 +579,15 @@ boost::any ExecuteFunction(const string& functionName, const vector& int parseZSharp(string script) { - script = replace(script, " ", "\t"); + script = replace(script, " ", "\t"); // Replace spaces with tabs (not really required, and will break purposefull whitespace in strings etc.) #if DEVELOPER_MESSAGES InterpreterLog("Contents:\n" + script); #endif + // Split the script by ;, signifying a line ending vector lines = split(script, ';'); vector> words; - for (int i = 0; i < (int)lines.size(); i++) + for (int i = 0; i < (int)lines.size(); i++) // Then split said lines into indiviual words words.push_back(split(lines.at(i), ' ')); #if DEVELOPER_MESSAGES @@ -659,7 +661,7 @@ int parseZSharp(string script) #if DEVELOPER_MESSAGES InterpreterLog("Start Main()"); #endif - // Executes main, which is the starting function + // Executes main, which is the entry point function ExecuteFunction("Main", vector {}); return 0; @@ -667,6 +669,7 @@ int parseZSharp(string script) int main(int argc, char* argv[]) { + // Print the name of the interpreter and it's version in inverted black on white text PrintColored(NAMEVERSION, blackFGColor, whiteBGColor, false); cout << endl << endl; @@ -677,7 +680,7 @@ int main(int argc, char* argv[]) std::string scriptTextContents; - // If scriptname is supplied and not in developer mode + // If scriptname is supplied if (argc > 1) { std::string scriptPath = argv[1]; @@ -687,7 +690,7 @@ int main(int argc, char* argv[]) std::string projectDirectory = scriptPath.substr(0, scriptPath.find_last_of("/\\")); #if UNIX - // Get script contents + // Get script contents as single string auto ss = ostringstream{}; ifstream input_file(scriptPath); ss << input_file.rdbuf(); @@ -696,6 +699,7 @@ int main(int argc, char* argv[]) InterpreterLog("Gather script contents..."); #endif + // Change the current working directory to that of the script chdir(projectDirectory.c_str()); #if DEVELOPER_MESSAGES InterpreterLog("Change directory to " + projectDirectory + "..."); @@ -705,7 +709,7 @@ int main(int argc, char* argv[]) InterpreterLog("Current working directory is " + newPath); #endif #elif WINDOWS - // Get script contents + // Get script contents as single string ifstream script(scriptPath); stringstream scriptString; scriptString << script.rdbuf(); @@ -714,6 +718,7 @@ int main(int argc, char* argv[]) InterpreterLog("Gather script contents..."); #endif + // Change the current working directory to that of the script std::wstring_convert> converter; std::wstring wide = converter.from_bytes(projectDirectory); LPCWSTR s = wide.c_str(); @@ -724,25 +729,39 @@ int main(int argc, char* argv[]) #endif } else - { + { // If no script is provided as an argument then throw error LogWarning("No script provided! Please drag and drop .ZS file over interpreter executable file, or provide it's path as a command-line argument."); cout << "Press Enter to Continue"; cin.ignore(); exit(1); } - //system("pause"); - #if DEVELOPER_MESSAGES InterpreterLog("Parsing..."); #endif + // Start running the script parseZSharp(scriptTextContents); - - -#if DEVELOPER_MESSAGES + + // Entire script has been run, exit. + +#if DEVELOPER_MESSAGES // If built with developer messages, then verify exit cout << "Press Enter to Continue"; cin.ignore(); exit(1); -#endif +#else + if(argc > 2) + { + string a = argv[2]; + std::transform(a.begin(), a.end(), a.begin(), + [](unsigned char c){ return std::tolower(c); }); + + if(a == "-ve") // If the '-ve' (verify exit) option is used, ask for verification on exit + { + cout << "Press Enter to Continue"; + cin.ignore(); + exit(1); + } + } +#endif // Else exit automatically return 0; } From 90dad7998fdf5eba9ae577d5f5af3224e8695f6f Mon Sep 17 00:00:00 2001 From: sam-astro <77079540+sam-astro@users.noreply.github.com> Date: Thu, 19 May 2022 09:11:17 -0400 Subject: [PATCH 2/2] Update README.md --- README.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 136027c..47aec97 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,18 @@ ## Introduction -Z-Sharp is a custom programming language I made because I don't like c++ very much (Z-Sharp's interpreter is written in c++ though). It used to be called Slang, standing for "Stupid Lang", but another programming language called Slang already exists :(. Z-Sharp scripts have the file extension .zs. The base syntax and formatting I would say is quite similar to C#, but differs as task complexity increases. It has support for graphics using SDL2, and by default is not enabled. +Z-Sharp is a custom programming language I made because I don't like c++ very much (Z-Sharp's interpreter is written in c++ though). It used to be called Slang, standing for "Stupid Lang", but another programming language called Slang already exists :(. Z-Sharp scripts have the file extension .zs. The base syntax and formatting I would say is quite similar to C#, but differs as task complexity increases. It has support for graphics using SDL2. +If you are thinking about using this language, then you may wish to reconsider. It is quite bare-bones, and doesn't have a lot of features. Also the syntax must be very exact and even a space, a missing space, or using spaces instead of tabs could throw an error. ## Installation -Downloading or installing is very simple. I recommend the regular version if you are just exploring, and not the installer, because then you don't need to find the executable in your program files. If you plan on developing for a long time though, then you should use the installer and I'll guide you through that after. +Downloading or installing is very simple, and you don't need to build it yourself. I recommend the regular version if you are just exploring, and not the installer, because then you don't need to find the executable in your program files. If you plan on developing for a long time though, then you should use the installer and I'll guide you through that after. ### ZSharp Windows x64 1. Navigate to [the most recent release](https://github.com/sam-astro/Z-Sharp/releases) and download `ZSharp-Win-x64.zip`. 2. Unzip `ZSharp-Win-x64.zip` and open the unzipped folder. 3. You will see many files. The Z# interpreter is `ZSharp.exe` and has a Z# icon. Any time you want to execute a script, this is the program that will be used. There are a few ways to use it: * Drag and drop any .ZS script directly onto the executable. - * Use command line, providing path to executable and then to script like so: - `> ./ZSharp.exe ./Pong-Example-Project/script.zs` + * Use a command line, providing path to executable and then to script like so: + `> .\ZSharp.exe .\Pong-Example-Project\script.zs` * Right-click on your .ZS script file, then select `'Open with...'`. Click `'More Apps'`, scroll down, and select `'Look for another app on this PC'`. Navigate to the `ZSharp.exe` executable and select it. Now whenever you double-click any .ZS file, it will automatically open with the interpreter. 4. Feel free to use and edit the included `Pong-Example-Project`. It is a single script called `script.zs`, and you can open it with any of the methods above. ### ZSharp Linux @@ -37,29 +38,35 @@ Downloading or installing is very simple. I recommend the regular version if you ```c++ // Comments are indicated by two forward slashes // They can only be on their own line -// int j = 4 // <- This is invalid comment placement +int j = 4 // <- This is invalid comment placement, and will throw an error // All programs start with a main function func Main() { + // Initialize variable by stating it's type, then name, then "=" and it's value int i = 0 string s = "r" + // These operators will change the variable by the value on the right i += 2 i -= 1 i /= 3 i *= 2 + // Repeat until i >= 10 while i < 10 { i += 1 } + // Check if the variable s contains the value "r" if s == "r" { print s + " is r" } + // Call function called "ExampleFunction" with two inputs, both as different types, + // then get the return value and store it in the new variable "functionNumber" int functionNumber = ExampleFunction("A", s) ExampleFunction(1, 3) @@ -67,8 +74,8 @@ func Main() } // Declare new function with 'func', then it's name, and the names of any input variables. -// The input variables don't need type, as those are automatic. Also, they don't need to -/// be assigned at all on execute and can be left blank +// The input variables don't need types, as those are automatic. Also, they don't need to +/// be assigned at all on execute and can be left blank by the caller func ExampleFunction(inputA, inputB) { print "In A is: " + inputA