diff --git a/README.md b/README.md index 3a8d766..9b52781 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ func Main() if s == "r" { - print s + " is r" + Printl(s + " is r") } int functionNumber = ExampleFunction("A", s) @@ -99,8 +99,8 @@ func Main() /// be assigned at all on execute and can be left blank func ExampleFunction(inputA, inputB) { - print "In A is: " + inputA - print "In B is: " + inputB + Printl("In A is: " + inputA) + Printl("In B is: " + inputB) // Return a value to the valling location return 4 diff --git a/ZSharp/Main.cpp b/ZSharp/Main.cpp index 95cba74..a526e79 100644 --- a/ZSharp/Main.cpp +++ b/ZSharp/Main.cpp @@ -2,9 +2,10 @@ #include #include #include +//bool DEVELOPER_MESSAGES = true; #define DEVELOPER_MESSAGES false #define EXAMPLE_PROJECT false -#define NAMEVERSION "ZSharp v2.1.0-alpha" +#define NAMEVERSION "ZSharp v2.1.1-alpha" #if defined(__unix__) #define UNIX true @@ -77,10 +78,13 @@ boost::any GetVariableValue(const string& varName, const unordered_map& variableValues) { - if (variableValues.find(split(varName, '.')[0]) != variableValues.end() && split(varName, '.')[0] != "ZS") - return true; - else + if(split(varName, '.')[0] == "ZS") return false; + + if (variableValues.find(split(varName, '.')[0]) != variableValues.end()) + return true; + + return false; } // Return a vector of values that correspond to a vector of input variable names @@ -111,6 +115,20 @@ vector VarValues(const vector& varNames, unordered_map& vec, unordered_map& variableValues) +{ + cout << "<"; + for (int i = 0; i < vec.size(); i++) + { + cout << AnyAsString(GetVariableValue(vec.at(i), globalVariableValues)); + cout << AnyAsString(GetVariableValue(vec.at(i), variableValues)); + cout << " | "; + } + cout << ">"; + cout << endl; +} + + bool IsFunction(const string& funcName) { if (functionValues.find(funcName) != functionValues.end()) @@ -120,10 +138,7 @@ bool IsFunction(const string& funcName) } bool IsZSFunction(const string& funcName) { - if (funcName[0] == 'Z' && funcName[1] == 'S' && funcName[2] == '.') - return true; - else - return false; + return startsWith(funcName, "ZS."); } boost::any EvalExpression(const string& ex, unordered_map& variableValues) @@ -146,30 +161,26 @@ boost::any EvalExpression(const string& ex, unordered_map& v // start -> FuncCall(0, x, OtherFunc(a)) // changeto -> 0, x, OtherFunc(a) string insideFunArgs = betweenChars(expression, '(', ')'); -#if DEVELOPER_MESSAGES == true - cout << insideFunArgs << endl; -#endif vector argList = splitNoOverlap(insideFunArgs, ',', '(', ')'); #if DEVELOPER_MESSAGES == true cout << "[" << unWrapVec(argList) << "]" << endl; + printVarValues(argList, variableValues); #endif vector funcArgs = VarValues(argList, variableValues); - return ExecuteFunction(trim(split(expression, '(')[0]), funcArgs); + return ExecuteFunction(split(expression, '(')[0], funcArgs); } else if (isZS && !inQuotes) { // start -> FuncCall(0, x, OtherFunc(a)) // changeto -> 0, x, OtherFunc(a) string insideFunArgs = betweenChars(expression, '(', ')'); -#if DEVELOPER_MESSAGES == true - cout << insideFunArgs << endl; -#endif vector argList = splitNoOverlap(insideFunArgs, ',', '(', ')'); #if DEVELOPER_MESSAGES == true - cout << "[" << unWrapVec(argList) << "]" << endl; + cout << split(expression, '(')[0]<< " [" << unWrapVec(argList) << "]" << endl; + printVarValues(argList, variableValues); #endif vector funcArgs = VarValues(argList, variableValues); - return ZSFunction(trim(split(expression, '(')[0]), funcArgs); + return ZSFunction(split(expression, '(')[0], funcArgs); } else return GetVariableValue(expression, variableValues); @@ -200,15 +211,13 @@ boost::any EvalExpression(const string& ex, unordered_map& v // start -> FuncCall(0, x, OtherFunc(a)) // changeto -> 0, x, OtherFunc(a) string insideFunArgs = betweenChars(expression, '(', ')'); -#if DEVELOPER_MESSAGES == true - cout << insideFunArgs << endl; -#endif vector argList = splitNoOverlap(insideFunArgs, ',', '(', ')'); #if DEVELOPER_MESSAGES == true - cout << unWrapVec(argList) << endl; + cout << "[" << unWrapVec(argList) << "]" << endl; + printVarValues(argList, variableValues); #endif vector funcArgs = VarValues(argList, variableValues); - string returnVal = AnyAsString(ExecuteFunction(trim(split(expression, '(')[0]), funcArgs)); + string returnVal = AnyAsString(ExecuteFunction(split(expression, '(')[0], funcArgs)); newExpression += returnVal; } else if (split(name, '.')[0] == "ZS" && !inQuotes) @@ -216,15 +225,13 @@ boost::any EvalExpression(const string& ex, unordered_map& v // start -> FuncCall(0, x, OtherFunc(a)) // changeto -> 0, x, OtherFunc(a) string insideFunArgs = betweenChars(expression, '(', ')'); -#if DEVELOPER_MESSAGES == true - cout << insideFunArgs << endl; -#endif vector argList = splitNoOverlap(insideFunArgs, ',', '(', ')'); #if DEVELOPER_MESSAGES == true - cout << unWrapVec(argList) << endl; + cout << "[" << unWrapVec(argList) << "]" << endl; + printVarValues(argList, variableValues); #endif vector funcArgs = VarValues(argList, variableValues); - string returnVal = AnyAsString(ExecuteFunction(trim(split(expression, '(')[0]), funcArgs)); + string returnVal = AnyAsString(ZSFunction(split(expression, '(')[0], funcArgs)); newExpression += returnVal; } else @@ -277,27 +284,33 @@ boost::any EvalExpression(const string& ex, unordered_map& v return evaluate(newExpression); } -bool BooleanLogic(const string& valA, const string& determinant, const string& valB, unordered_map& variableValues) +bool BooleanLogic(const string& valA, const string& comparer, const string& valB, unordered_map& variableValues) { - boost::any valARealValue = EvalExpression(valA, variableValues); - boost::any valBRealValue = EvalExpression(valB, variableValues); + boost::any valARealValue; + boost::any valBRealValue; + if(valA != "") + valARealValue = EvalExpression(valA, variableValues); + if(valB != "") + valBRealValue = EvalExpression(valB, variableValues); #if DEVELOPER_MESSAGES == true - InterpreterLog(AnyAsString(valARealValue) + " " + determinant + " " + AnyAsString(valBRealValue) + " : " + AnyAsString(valA) + " " + determinant + " " + AnyAsString(valB) + " : " + to_string(AnyAsString(valARealValue) == AnyAsString(valBRealValue))); + InterpreterLog(AnyAsString(valARealValue) + " " + comparer + " " + AnyAsString(valBRealValue) + " : " + AnyAsString(valA) + " " + comparer + " " + AnyAsString(valB) + " : " + to_string(AnyAsString(valARealValue) == AnyAsString(valBRealValue))); #endif - if (determinant == "==") + if (comparer == "==") return any_compare(valARealValue, valBRealValue); - else if (determinant == "!=") + else if (comparer == "!=") return !any_compare(valARealValue, valBRealValue); - else if (determinant == ">=") + else if (comparer == ">=") return AnyAsFloat(valARealValue) >= AnyAsFloat(valBRealValue); - else if (determinant == "<=") + else if (comparer == "<=") return AnyAsFloat(valARealValue) <= AnyAsFloat(valBRealValue); - else if (determinant == ">") + else if (comparer == ">") return AnyAsFloat(valARealValue) > AnyAsFloat(valBRealValue); - else if (determinant == "<") + else if (comparer == "<") return AnyAsFloat(valARealValue) < AnyAsFloat(valBRealValue); + else if (comparer == "") + return AnyAsBool(valARealValue) == true; else - LogWarning("unrecognized determinant \'" + determinant + "\'"); + LogWarning("unrecognized comparer \'" + comparer + "\'"); return false; } @@ -384,12 +397,12 @@ 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; + //// Check if the first two chars are '//', which would make it a comment + //if (startsWith(words.at(lineNum).at(0), "//")) + // return nullType; // If print statement (deprecated, now use ZS.System.Print() function) - else if (words.at(lineNum).at(0) == "print") + if (words.at(lineNum).at(0) == "print") { cout << StringRaw(AnyAsString(EvalExpression(unWrapVec(vector(words.at(lineNum).begin() + 1, words.at(lineNum).end())), variableValues))) << endl; return nullType; @@ -399,24 +412,28 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde else if (words.at(lineNum).at(0) == "return") return EvalExpression(unWrapVec(vector(words.at(lineNum).begin() + 1, words.at(lineNum).end())), variableValues); - // Check if it is ZS Builtin function - else if (words.at(lineNum).at(0)[0] == 'Z' && words.at(lineNum).at(0)[1] == 'S' && words.at(lineNum).at(0)[2] == '.') + // Check if it is ZS Builtin function call + else if (startsWith(words.at(lineNum).at(0), "ZS.")) return EvalExpression(unWrapVec(words.at(lineNum)), variableValues); - // Check if it is function - else if (IsFunction(trim(split(words.at(lineNum).at(0), '(')[0]))) + // Check if it is function call + else if (IsFunction(split(words.at(lineNum).at(0), '(')[0])) { // No args provided - if (count(words.at(lineNum).at(0), '(') > 0 && count(words.at(lineNum).at(0), ')') > 0) - ExecuteFunction(trim(split(words.at(lineNum).at(0), '(')[0]), vector()); + if (indexInStr(words.at(lineNum).at(0), ')') - indexInStr(words.at(lineNum).at(0), '(')<=1) + ExecuteFunction(split(words.at(lineNum).at(0), '(')[0], vector()); else { // Args provided, parse them first // start -> FuncCall(0, x, OtherFunc(a)) // changeto -> 0, x, OtherFunc(a) string insideFunArgs = betweenChars(unWrapVec(words.at(lineNum)), '(', ')'); vector argList = splitNoOverlap(insideFunArgs, ',', '(', ')'); +#if DEVELOPER_MESSAGES == true + cout << unWrapVec(argList) << endl; + printVarValues(argList, variableValues); +#endif vector funcArgs = VarValues(argList, variableValues); - ExecuteFunction(trim(split(words.at(lineNum).at(0), '(')[0]), funcArgs); + ExecuteFunction(split(words.at(lineNum).at(0), '(')[0], funcArgs); } return nullType; } @@ -424,7 +441,7 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde // Check if it is a SplitThread call else if (startsWith(words.at(lineNum).at(0), "SplitThread")) { - vector lineContents = removeTabs(words.at(lineNum), 10); + vector lineContents = words.at(lineNum); cout << "New Thread: " << words.at(lineNum).at(0) << endl; //lineContents.at(0) = betweenChars(lineContents.at(0), '(', ')'); @@ -438,18 +455,31 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde } // Check if global variable declaration - else if (trim(words.at(lineNum).at(0)) == "global") + else if (words.at(lineNum).at(0) == "global") { - globalVariableValues[words.at(lineNum).at(2)] = EvalExpression(unWrapVec(slice(words.at(lineNum), 4, -1)), variableValues); + try + { + globalVariableValues[words.at(lineNum).at(2)] = EvalExpression(unWrapVec(slice(words.at(lineNum), 4, -1)), variableValues); + } + catch (const std::exception&) + { + LogCriticalError("Error at line: " + to_string(lineNum) + ", " + unWrapVec(words.at(lineNum)) + ", couldn't initialize variable."); + } return nullType; } // 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.at(lineNum).at(0))) > 0) + else if (countInVector(types, words.at(lineNum).at(0)) > 0) { - //cout << words.at(lineNum).at(1) << "=" << unWrapVec(slice(words.at(lineNum), 3, -1)) << "=" << AnyAsString(EvalExpression(unWrapVec(slice(words.at(lineNum), 3, -1)), variableValues)) << endl; - variableValues[words.at(lineNum).at(1)] = EvalExpression(unWrapVec(slice(words.at(lineNum), 3, -1)), variableValues); + try + { + variableValues[words.at(lineNum).at(1)] = EvalExpression(unWrapVec(slice(words.at(lineNum), 3, -1)), variableValues); + } + catch (const std::exception&) + { + LogCriticalError("Error at line: " + to_string(lineNum) + ", " + unWrapVec(words.at(lineNum)) + ", couldn't initialize variable."); + } return nullType; } @@ -478,6 +508,7 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde vector> whileContents; vector whileParameters; + // Gather the parameters that must be == true for the loop to run int numOfBrackets = 0; for (int w = 1; w < (int)words.at(lineNum).size(); w++) { if (count(words.at(lineNum).at(w), '{') == 0) @@ -489,8 +520,22 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde break; } } + + // If the statement is already false, don't bother gathering the contents + if(BooleanLogic(whileParameters.at(0), whileParameters.at(1), whileParameters.at(2), variableValues) == false){ + lineNum++; + while (lineNum < (int)words.size()) + { + numOfBrackets += countInVector(words.at(lineNum), "{") - countInVector(words.at(lineNum), "}"); + if (numOfBrackets == 0) + break; + lineNum++; + } + return nullType; + } - lineNum += 1; + // Gather the contents + lineNum++; while (lineNum < (int)words.size()) { numOfBrackets += countInVector(words.at(lineNum), "{") - countInVector(words.at(lineNum), "}"); @@ -500,16 +545,30 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde lineNum++; } - whileContents = removeTabsWdArry(whileContents, 1); + //whileContents = removeTabsWdArry(whileContents, 1); + // Loop while true while (BooleanLogic(whileParameters.at(0), whileParameters.at(1), whileParameters.at(2), variableValues)) { //Iterate through all lines in while loop for (int lineNum = 0; lineNum < (int)whileContents.size(); lineNum++) { + if(whileContents.at(lineNum).at(0)== "continue") + break; // Stops iterating through lines and return to beginning + if(whileContents.at(lineNum).at(0)== "break") + return nullType; // Stops iterating through lines and leave while loop boost::any returnVal = ProcessLine(whileContents, lineNum, variableValues); - if (!returnVal.empty()) - return returnVal; + if (!returnVal.empty()) { + try + { + BREAK t = any_cast(returnVal); + return nullType; + } + catch (boost::bad_any_cast) + { + return returnVal; + } + } } } return nullType; @@ -521,6 +580,7 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde vector> ifContents; vector ifParameters; + // Gather the parameters that must be == true for the loop to run int numOfBrackets = 0; for (int w = 1; w < (int)words.at(lineNum).size(); w++) { if (count(words.at(lineNum).at(w), '{') == 0) @@ -533,6 +593,20 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde } } + // If the statement is already false, don't bother gathering the contents + if(BooleanLogic(ifParameters.at(0), ifParameters.at(1), ifParameters.at(2), variableValues) == false){ + lineNum++; + while (lineNum < (int)words.size()) + { + numOfBrackets += countInVector(words.at(lineNum), "{") - countInVector(words.at(lineNum), "}"); + if (numOfBrackets == 0) + break; + lineNum++; + } + return nullType; + } + + // Gather the contents lineNum++; while (lineNum < (int)words.size()) { @@ -542,22 +616,24 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde ifContents.push_back(words.at(lineNum)); lineNum++; } + //ifContents = removeTabsWdArry(ifContents, 1); - ifContents = removeTabsWdArry(ifContents, 1); - + // Execute if true if (BooleanLogic(ifParameters.at(0), ifParameters.at(1), ifParameters.at(2), variableValues)) { //Iterate through all lines in if statement for (int l = 0; l < (int)ifContents.size(); l++) { + if(ifContents.at(l).at(0)== "break") + return breakReOp; // Stops iterating through lines and leave while loop boost::any returnVal = ProcessLine(ifContents, l, variableValues); if (!returnVal.empty()) return returnVal; } } - else if (words.size() > lineNum + 1) + else if (words.size() > lineNum) { - if (words[lineNum + 1].at(0) == "else") + if (words[lineNum].at(0) == "else") { vector> elseContents; vector elseParameters; @@ -581,9 +657,9 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde lineNum++; } - elseContents = removeTabsWdArry(elseContents, 1); + //elseContents = removeTabsWdArry(elseContents, 1); - //Iterate through all lines in if statement + //Iterate through all lines in else statement for (int l = 0; l < (int)elseContents.size(); l++) { boost::any returnVal = ProcessLine(elseContents, l, variableValues); @@ -595,12 +671,6 @@ boost::any ProcessLine(const vector>& words, int& lineNum, unorde } return nullType; } - //// Gathers else statement contents - //if (words[lineNum][0] == "else") - //{ - // - //} - return nullType; } @@ -619,7 +689,7 @@ boost::any ExecuteFunction(const string& functionName, const vector& { variableValues[funcArgs[i]] = inputVarVals[i]; #if DEVELOPER_MESSAGES == true - cout << functionName + " \x1B[33m" << funcArgs[i] << " == " << AnyAsString(inputVarVals[i]) << "\033[0m\t\t" << endl; + cout << "in " << functionName + " " << funcArgs[i] << " == " << AnyAsString(inputVarVals[i]) << endl; #endif } } @@ -635,6 +705,7 @@ boost::any ExecuteFunction(const string& functionName, const vector& } catch (const std::exception&) { + LogCriticalError("Error at line: " + to_string(lineNum) + ", " + unWrapVec(words.at(lineNum))); } } return nullType; @@ -642,21 +713,33 @@ boost::any ExecuteFunction(const string& functionName, const vector& int parseZSharp(string script) { - 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 + //script = replace(script, " ", "\t"); // Replace spaces with tabs (not really required, and will break purposefull whitespace in strings etc.) - // Split the script by ;, signifying a line ending - vector lines = split(script, '\n'); + // Split the script by newline, signifying a line ending + vector beforeProcessLines = split(script, '\n'); + vector lines; + for (int i = 0; i < (int)beforeProcessLines.size(); i++){ // Then split said lines into indiviual words + if(!startsWith(trim(beforeProcessLines.at(i)), "//") && trim(beforeProcessLines.at(i)) != "") + { // dont include line if it is a comment or if it is blank + lines.push_back(trim(beforeProcessLines.at(i))); + } + } +#if DEVELOPER_MESSAGES + InterpreterLog("Contents:\n"); +#endif vector> words; 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 + cout << unWrapVec(words.at(i)) << endl; +#endif + } #if DEVELOPER_MESSAGES InterpreterLog("Gather variables & functions..."); #endif - // First go through entire script and iterate through all types to see if line is a variable + // 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++) { @@ -670,18 +753,35 @@ int parseZSharp(string script) InterpreterLog("Load script function " + functName + "..."); #endif - string args = ""; - if (indexInStr(unWrapVec(words.at(lineNum)), ')') - indexInStr(unWrapVec(words.at(lineNum)), '(') > 1) - for (int w = 1; w < (int)words.at(lineNum).size(); w++) // Get all words from the instantiation line: these are the args - { - if (count(words.at(lineNum).at(w), '{') == 0) - args += replace(replace(words.at(lineNum).at(w), "(", " "), ")", ""); - } + //string args = ""; + //if (indexInStr(unWrapVec(words.at(lineNum)), ')') - indexInStr(unWrapVec(words.at(lineNum)), '(') > 1) + // for (int w = 0; w < (int)words.at(lineNum).size(); w++) // Get all words from the instantiation line: these are the args + // { + // if (count(words.at(lineNum).at(w), '{') == 0) + // args += replace(replace(words.at(lineNum).at(w), "(", " "), ")", ""); + // } + string args = betweenChars(unWrapVec(words.at(lineNum)), '(', ')'); + //cout << functName << "<" << args << ">" << endl; - args = trim(replace(args, functName + " ", "")); - functionContents.push_back(split(args, ',')); + //args = trim(replace(args, functName, "")); + functionContents.push_back(split(replace(args, " ", ""), ',')); - int numOfBrackets = 0; + + int numOfBrackets = countInVector(words.at(lineNum), "{") - countInVector(words.at(lineNum), "}"); + // Gather the contents + lineNum++; + while (lineNum < (int)words.size()) + { + numOfBrackets += countInVector(words.at(lineNum), "{") - countInVector(words.at(lineNum), "}"); + if (numOfBrackets == 0) + break; + functionContents.push_back(words.at(lineNum)); + //cout << functName << "<" << args << ">" << endl; + lineNum++; + } + //functionContents = removeTabsWdArry(functionContents, 1); + + /*int numOfBrackets = 0; for (int w = 1; w < (int)words.at(lineNum).size(); w++) { if (count(words.at(lineNum).at(w), '{') != 0) { numOfBrackets = 1; @@ -695,7 +795,7 @@ int parseZSharp(string script) if (numOfBrackets == 0) break; functionContents.push_back(removeTabs(words.at(p), 1)); - } + }*/ functionValues[functName] = functionContents; } else @@ -736,26 +836,34 @@ int parseZSharp(string script) InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); #endif } - else if (words.at(lineNum).at(0) == "int") { - globalVariableValues[words.at(lineNum).at(1)] = stoi(words.at(lineNum).at(3)); -#if DEVELOPER_MESSAGES == true - InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); -#endif + + // 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.at(lineNum).at(0))) > 0) + { + //cout << words.at(lineNum).at(1) << "=" << unWrapVec(slice(words.at(lineNum), 3, -1)) << "=" << AnyAsString(EvalExpression(unWrapVec(slice(words.at(lineNum), 3, -1)), variableValues)) << endl; + globalVariableValues[words.at(lineNum).at(1)] = EvalExpression(unWrapVec(slice(words.at(lineNum), 3, -1)), globalVariableValues); } - else if (words.at(lineNum).at(0) == "float") { - globalVariableValues[words.at(lineNum).at(1)] = stof(words.at(lineNum).at(3)); -#if DEVELOPER_MESSAGES == true - InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); -#endif - } - else if (words.at(lineNum).at(0) == "bool") { - globalVariableValues[words.at(lineNum).at(1)] = stob(words.at(lineNum).at(3)); -#if DEVELOPER_MESSAGES == true - InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); -#endif - } - /*else - LogWarning("unrecognized type \'" + words.at(lineNum).at(0) + "\' on line: " + to_string(lineNum));*/ +// else if (words.at(lineNum).at(0) == "int") { +// globalVariableValues[words.at(lineNum).at(1)] = stoi(words.at(lineNum).at(3)); +//#if DEVELOPER_MESSAGES == true +// InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); +//#endif +// } +// else if (words.at(lineNum).at(0) == "float") { +// globalVariableValues[words.at(lineNum).at(1)] = stof(words.at(lineNum).at(3)); +//#if DEVELOPER_MESSAGES == true +// InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); +//#endif +// } +// else if (words.at(lineNum).at(0) == "bool") { +// globalVariableValues[words.at(lineNum).at(1)] = stob(words.at(lineNum).at(3)); +//#if DEVELOPER_MESSAGES == true +// InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); +//#endif +// } + else + LogWarning("unrecognized type \'" + words.at(lineNum).at(0) + "\' on line: " + to_string(lineNum)); } } @@ -769,9 +877,9 @@ int main(int argc, char* argv[]) cout << endl << endl; // Gathers builtin functions and variables - GetBuiltins(ZSContents); - functionValues = builtinFunctionValues; - globalVariableValues = builtinVarVals; + parseZSharp(ZSContents); + //functionValues = builtinFunctionValues; + //globalVariableValues = builtinVarVals; std::string scriptTextContents; @@ -780,7 +888,7 @@ int main(int argc, char* argv[]) { std::string scriptPath; if (EXAMPLE_PROJECT) - scriptPath = "D:\\Code\\Z-Sharp\\Releases\\ZS-Win-x64-Base\\Pong-Example-Project\\script.zs"; + scriptPath = "D:\\Code\\Z-Sharp\\examples\\Platformer\\script.zs"; else scriptPath = argv[1]; #if DEVELOPER_MESSAGES @@ -804,12 +912,11 @@ int main(int argc, char* argv[]) int chErr = chdir(projectDirectory.c_str()); if (chErr < 0) LogCriticalError("Failed to change directory to: \"" + projectDirectory + "\", error num: " + to_string(chErr)); + #if DEVELOPER_MESSAGES InterpreterLog("Changed directory to " + projectDirectory + "..."); #endif -#if DEVELOPER_MESSAGES - string newPath = filesystem::current_path(); -#endif + #elif WINDOWS // Get script contents as single string ifstream script(scriptPath); @@ -831,9 +938,9 @@ int main(int argc, char* argv[]) #endif } else - { // If no script is provided as an argument then throw error + { // If no script is provided as an argument 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"; + InterpreterLog("Press Enter to Exit..."); cin.ignore(); exit(1); } @@ -858,7 +965,7 @@ int main(int argc, char* argv[]) // Entire script has been run, exit. #if DEVELOPER_MESSAGES // If built with developer messages, then verify exit - cout << "Press Enter to Continue"; + InterpreterLog("Press Enter to Exit..."); cin.ignore(); exit(1); #else @@ -870,11 +977,17 @@ int main(int argc, char* argv[]) if (a == "-ve") // If the '-ve' (verify exit) option is used, ask for verification on exit { - cout << "Press Enter to Continue"; + InterpreterLog("Press Enter to Exit..."); cin.ignore(); exit(1); } } + else if (AnyAsBool(GetVariableValue("EXIT_WHEN_DONE", globalVariableValues)) == false) + { + InterpreterLog("Press Enter to Exit..."); + cin.ignore(); + exit(1); + } #endif // Else exit automatically return 0; } diff --git a/ZSharp/ZS.h b/ZSharp/ZS.h index 175beef..0e1b68b 100644 --- a/ZSharp/ZS.h +++ b/ZSharp/ZS.h @@ -3,11 +3,18 @@ using namespace std; std::string ZSContents = R"( +//////////////////////////////////////////////////////////////////////////////// +// BUILTIN +//////////////////////////////////////////////////////////////////////////////// + // Default variables, can be overwritten // if re-initialized or changed float PI = 3.14159265358979323846264338 float EulersNumber = 2.71828183 +// This variable tells the interpreter if it should close the console window when the program has finished running. +bool EXIT_WHEN_DONE = true + // Trigonometric function Sin func Sin(input) { @@ -100,15 +107,15 @@ func SetPixel(x, y, r, g, b) } // Prints input value to console -func Print(in) +func Print(strToPrint) { - ZS.System.Print(in) + ZS.System.Print(strToPrint) } // Prints input value to console with appended newline '\n' -func Printl(in) +func Printl(strToPrint) { - ZS.System.PrintLine(in) + ZS.System.PrintLine(strToPrint) } // Creates new sprite class @@ -138,9 +145,73 @@ func GetKey(keyName) return b } +// WIP //func SplitThread(function) //{ // ZS.System.SplitThread(function) //} + + + +//////////////////////////// +// ↓ MADE BY KAPUTCHINO ↓ // +//////////////////////////// + +// Return the number of combinations +func Comb(n, r) +{ + return Perm(n, r) / Fac(r) +} + +// Return the factorial of a number +func Fac(x) +{ + int r = 1 + while x > 1 + { + r = r * x + x = x - 1 + } + return r +} + +// Return exp(x) by using the taylor method, not extremly accurate +func TaylorExp(x) +{ + float sum = 0 + float term = 1 + int i = 1 + float sumterm = 1 + while sum != sumterm + { + sum = sumterm + term = term * x / i + i = i + 1 + sumterm = sumterm + term + } + return sum +} + +// Return the number of permutations +func Perm(n, r) +{ + if n < 0 + { + ZS.System.PrintLine("n must be superior or equal to 0") + return -1 + } + if r < 0 + { + ZS.System.PrintLine("r must be superior or equal to 0") + return -1 + } + if r > n + { + ZS.System.PrintLine("r must be inferior or equal to n") + return -1 + } + return Fac(n) / Fac(n - r) +} + )" -; \ No newline at end of file +; diff --git a/ZSharp/ZSharpInstallerMakerInnoSetup.iss b/ZSharp/ZSharpInstallerMakerInnoSetup.iss index 729149a..f3befbb 100644 --- a/ZSharp/ZSharpInstallerMakerInnoSetup.iss +++ b/ZSharp/ZSharpInstallerMakerInnoSetup.iss @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "Z-Sharp" -#define MyAppVersion "2.1.0-alpha" +#define MyAppVersion "2.1.1-alpha" #define MyAppPublisher "AstroSam" #define MyAppURL "https://github.com/sam-astro/Z-Sharp" #define MyAppExeName "ZSharp.exe" diff --git a/ZSharp/builtin.h b/ZSharp/builtin.h index c7e65ca..d27fd36 100644 --- a/ZSharp/builtin.h +++ b/ZSharp/builtin.h @@ -28,8 +28,8 @@ using namespace boost; vector types = { "int", "float", "string", "bool", "void", "null", "Sprite", "Vec2", "Text" }; -unordered_map>> builtinFunctionValues; -unordered_map builtinVarVals; +//unordered_map>> builtinFunctionValues; +//unordered_map builtinVarVals; // Foreground colors const std::string blackFGColor = "\x1B[30m"; @@ -72,8 +72,13 @@ class NullType { public: string type = "NULL"; }; +class BREAK { +public: + string type = "BREAK"; +}; boost::any nullType; +boost::any breakReOp; float clamp(float v, float min, float max) { @@ -141,7 +146,7 @@ void PrintColored(std::string text, std::string fgColor, std::string bgColor, bo int LogWarning(const string& warningText) { PrintColored("WARNING: ", yellowFGColor, "", true); - PrintColored(warningText, yellowFGColor, "", true); + PrintColored(escaped(warningText), yellowFGColor, "", true); cerr << std::endl; //cout << "\x1B[33mWARNING: " << warningText << "\033[0m\t\t" << endl; return 1; @@ -157,7 +162,15 @@ int InterpreterLog(const string& logText) tm bt{}; #if UNIX - //localtime_r(&timer, &bt); + time_t currentTime; + struct tm* localTime; + + time(¤tTime); // Get the current time + localTime = localtime(¤tTime); // Convert the current time to the local time + + Hour = localTime->tm_hour; + Min = localTime->tm_min; + Sec = localTime->tm_sec; #elif WINDOWS localtime_s(&bt, &timer); Hour = bt.tm_hour; @@ -171,7 +184,7 @@ int InterpreterLog(const string& logText) PrintColored("[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] ", blueFGColor, "", true); PrintColored("ZSharp: ", yellowFGColor, "", true); - PrintColored(logText, greenFGColor, "", true); + PrintColored(escaped(logText), greenFGColor, "", true); cout << std::endl; //cout << "\x1B[34m[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] \x1B[33mZSharp: \x1B[32m" << logText << "\033[0m\t\t" << endl; return 1; @@ -185,9 +198,17 @@ int LogCriticalError(const string& errorText) time_t timer = time(0); tm bt{}; -#if defined(__unix__) - //localtime_r(&timer, &bt); -#elif defined(_MSC_VER) +#if UNIX + time_t currentTime; + struct tm* localTime; + + time(¤tTime); // Get the current time + localTime = localtime(¤tTime); // Convert the current time to the local time + + Hour = localTime->tm_hour; + Min = localTime->tm_min; + Sec = localTime->tm_sec; +#elif WINDOWS localtime_s(&bt, &timer); Hour = bt.tm_hour; Min = bt.tm_min; @@ -200,9 +221,9 @@ int LogCriticalError(const string& errorText) PrintColored("[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] ", blueFGColor, "", true); PrintColored("ZSharp: ", yellowFGColor, "", true); - PrintColored(errorText, redFGColor, "", true); + PrintColored(escaped(errorText), redFGColor, "", true); cerr << std::endl; - cout << "Press Enter to Continue"; + InterpreterLog("Press Enter to Exit..."); cin.ignore(); exit(1); //cerr << "\x1B[34m[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] \x1B[33mZSharp: \x1B[31mERROR: " << errorText << "\033[0m\t\t" << endl; @@ -276,90 +297,90 @@ bool AxisAlignedCollision(const Sprite& a, const Sprite& b) // AABB - AABB colli return collisionX && collisionY; } -// Initial script processing, which loads variables and functions from builtin -int GetBuiltins(std::string s) -{ - std::string script = replace(s, " ", "\t"); - - vector lines = split(script, '\n'); - vector> words; - for (int i = 0; i < (int)lines.size(); i++) - { - words.push_back(split(lines.at(i), ' ')); - } - - // 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++) - { - //Checks if it is function - if (words.at(lineNum).at(0) == "func") - { - vector> functionContents; - - string functName = split(words.at(lineNum).at(1), '(')[0]; - -#if DEVELOPER_MESSAGES == true - InterpreterLog("Load builtin function " + functName + "..."); -#endif - - string args = ""; - for (int w = 1; w < (int)words.at(lineNum).size(); w++) // Get all words from the instantiation line: these are the args - { - args += replace(replace(words.at(lineNum).at(w), "(", " "), ")", ""); - } - - args = replace(args, functName + " ", ""); - functionContents.push_back(split(args, ',')); - - int numOfBrackets = 1; - for (int p = lineNum + 2; p < (int)words.size(); p++) - { - numOfBrackets += countInVector(words.at(p), "{") - countInVector(words.at(p), "}"); - if (numOfBrackets == 0) - break; - functionContents.push_back(removeTabs(words.at(p), 1)); - } - builtinFunctionValues[functName] = functionContents; - //cout << functName << " is \n" << Vec2Str(functionContents) << endl << endl; - } - else - { - if (words.at(lineNum).at(0) == "string") - { - builtinVarVals[words.at(lineNum).at(1)] = StringRaw(words.at(lineNum).at(3)); -#if DEVELOPER_MESSAGES == true - InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); -#endif - } - else if (words.at(lineNum).at(0) == "int") - { - builtinVarVals[words.at(lineNum).at(1)] = stoi(words.at(lineNum).at(3)); -#if DEVELOPER_MESSAGES == true - InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); -#endif - } - else if (words.at(lineNum).at(0) == "float") - { - builtinVarVals[words.at(lineNum).at(1)] = stof(words.at(lineNum).at(3)); -#if DEVELOPER_MESSAGES == true - InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); -#endif - } - else if (words.at(lineNum).at(0) == "bool") - { - builtinVarVals[words.at(lineNum).at(1)] = stob(words.at(lineNum).at(3)); -#if DEVELOPER_MESSAGES == true - InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); -#endif - } - //else - // LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + to_string(lineNum)); - } - } - - return 0; -} +//// Initial script processing, which loads variables and functions from builtin +//int GetBuiltins(std::string s) +//{ +// std::string script = replace(s, " ", "\t"); +// +// vector lines = split(script, '\n'); +// vector> words; +// for (int i = 0; i < (int)lines.size(); i++) +// { +// words.push_back(split(lines.at(i), ' ')); +// } +// +// // 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++) +// { +// //Checks if it is function +// if (words.at(lineNum).at(0) == "func") +// { +// vector> functionContents; +// +// string functName = split(words.at(lineNum).at(1), '(')[0]; +// +//#if DEVELOPER_MESSAGES == true +// InterpreterLog("Load builtin function " + functName + "..."); +//#endif +// +// string args = ""; +// for (int w = 1; w < (int)words.at(lineNum).size(); w++) // Get all words from the instantiation line: these are the args +// { +// args += replace(replace(words.at(lineNum).at(w), "(", " "), ")", ""); +// } +// +// args = replace(args, functName + " ", ""); +// functionContents.push_back(split(args, ',')); +// +// int numOfBrackets = 1; +// for (int p = lineNum + 2; p < (int)words.size(); p++) +// { +// numOfBrackets += countInVector(words.at(p), "{") - countInVector(words.at(p), "}"); +// if (numOfBrackets == 0) +// break; +// functionContents.push_back(removeTabs(words.at(p), 1)); +// } +// builtinFunctionValues[functName] = functionContents; +// //cout << functName << " is \n" << Vec2Str(functionContents) << endl << endl; +// } +// else +// { +// if (words.at(lineNum).at(0) == "string") +// { +// builtinVarVals[words.at(lineNum).at(1)] = StringRaw(words.at(lineNum).at(3)); +//#if DEVELOPER_MESSAGES == true +// InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); +//#endif +// } +// else if (words.at(lineNum).at(0) == "int") +// { +// builtinVarVals[words.at(lineNum).at(1)] = stoi(words.at(lineNum).at(3)); +//#if DEVELOPER_MESSAGES == true +// InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); +//#endif +// } +// else if (words.at(lineNum).at(0) == "float") +// { +// builtinVarVals[words.at(lineNum).at(1)] = stof(words.at(lineNum).at(3)); +//#if DEVELOPER_MESSAGES == true +// InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); +//#endif +// } +// else if (words.at(lineNum).at(0) == "bool") +// { +// builtinVarVals[words.at(lineNum).at(1)] = stob(words.at(lineNum).at(3)); +//#if DEVELOPER_MESSAGES == true +// InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); +//#endif +// } +// //else +// // LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + to_string(lineNum)); +// } +// } +// +// return 0; +//} // Executes boost::any ZSFunction(const string& name, const vector& args) @@ -403,8 +424,16 @@ boost::any ZSFunction(const string& name, const vector& args) if (!fileExists(StringRaw(AnyAsString(args.at(1))))) LogCriticalError("Failed to create 'Text' object: \"" + StringRaw(AnyAsString(args.at(1))) + "\""); - Text t(StringRaw(AnyAsString(args.at(0))), StringRaw(AnyAsString(args.at(1))), any_cast(args.at(2)), AnyAsFloat(args.at(3)), AnyAsFloat(args.at(4)), (Uint8)AnyAsFloat(args.at(5)), (Uint8)AnyAsFloat(args.at(6)), (Uint8)AnyAsFloat(args.at(7))); - return t; + if (args.size() <= 8) + { + Text t(StringRaw(AnyAsString(args.at(0))), StringRaw(AnyAsString(args.at(1))), any_cast(args.at(2)), AnyAsFloat(args.at(3)), AnyAsFloat(args.at(4)), (Uint8)AnyAsFloat(args.at(5)), (Uint8)AnyAsFloat(args.at(6)), (Uint8)AnyAsFloat(args.at(7)), true); + return t; + } + else + { + Text t(StringRaw(AnyAsString(args.at(0))), StringRaw(AnyAsString(args.at(1))), any_cast(args.at(2)), AnyAsFloat(args.at(3)), AnyAsFloat(args.at(4)), (Uint8)AnyAsFloat(args.at(5)), (Uint8)AnyAsFloat(args.at(6)), (Uint8)AnyAsFloat(args.at(7)), AnyAsBool(args.at(8))); + return t; + } } else if (name == "ZS.Graphics.DrawText") any_cast(args.at(0)).Draw(); @@ -417,9 +446,9 @@ boost::any ZSFunction(const string& name, const vector& args) else if (name == "ZS.Input.GetKey") return KEYS[StringRaw(any_cast(args.at(0)))] == 1; else if (name == "ZS.System.Print") - cout << StringRaw(AnyAsString(args.at(0))); + cout << StringRaw(AnyAsString(args.at(0))) << StringRaw(AnyAsString(args.at(0))).length(); else if (name == "ZS.System.PrintLine") - cout << StringRaw(AnyAsString(args.at(0))) << endl; + cout << StringRaw(AnyAsString(args.at(0))) << StringRaw(AnyAsString(args.at(0))).length() << endl; else if (name == "ZS.System.Vec2") { Vec2 v(AnyAsFloat(args.at(0)), AnyAsFloat(args.at(1))); diff --git a/ZSharp/graphics.h b/ZSharp/graphics.h index a1a650c..5986d63 100644 --- a/ZSharp/graphics.h +++ b/ZSharp/graphics.h @@ -523,8 +523,8 @@ public: class Text { public: - Text(std::string content, std::string pathToFont, Vec2 position, float fontSize, double angle, Uint8 r, Uint8 g, Uint8 b) - : position(position), angle(angle), content(content), pathToFont(pathToFont), fontSize(fontSize), r(r), g(g), b(b) + Text(std::string content, std::string pathToFont, Vec2 position, float fontSize, double angle, Uint8 r, Uint8 g, Uint8 b, bool antialias) + : position(position), angle(angle), content(content), pathToFont(pathToFont), fontSize(fontSize), r(r), g(g), b(b), antialias(antialias) { rect.x = position.x; rect.y = position.y; @@ -538,8 +538,12 @@ public: { SDL_Color color = { r, g, b }; - SDL_Surface* surface = TTF_RenderText_Blended(font, content.c_str(), color); - + SDL_Surface* surface; + if (antialias) + surface = TTF_RenderText_Blended(font, content.c_str(), color); + else + surface = TTF_RenderText_Solid(font, content.c_str(), color); + texture = SDL_CreateTextureFromSurface(gRenderer, surface); TTF_SizeText(font, content.c_str(), &rect.w, &rect.h); @@ -559,7 +563,11 @@ public: { SDL_Color color = { r, g, b }; - SDL_Surface* surface = TTF_RenderText_Blended(font, content.c_str(), color); + SDL_Surface* surface; + if (antialias) + surface = TTF_RenderText_Blended(font, content.c_str(), color); + else + surface = TTF_RenderText_Solid(font, content.c_str(), color); SDL_DestroyTexture(texture); texture = SDL_CreateTextureFromSurface(gRenderer, surface); @@ -604,6 +612,8 @@ public: return content; if (componentName == "pathToFont") return pathToFont; + if (componentName == "antialias") + return antialias; return 0; } @@ -711,12 +721,19 @@ public: else if (oper == "+=") content += AnyAsString(otherVal); } + else if (componentName == "antialias") + { + if (oper == "=") + antialias = AnyAsBool(otherVal); + } // Updates changes to text Update(); return *this; } + bool antialias = true; + Vec2 position; Vec2 scale; float fontSize; diff --git a/ZSharp/strops.cpp b/ZSharp/strops.cpp index f3ae7ad..5cfe884 100644 --- a/ZSharp/strops.cpp +++ b/ZSharp/strops.cpp @@ -8,7 +8,8 @@ //#include "builtin.h" using namespace std; -const string WHITESPACE = " \n\r\t\f\v"; +const string WHITESPACE = " \t\f"; +//const string WHITESPACE = " \n\r\t\f\v"; bool isNumber(const string& str) @@ -25,6 +26,51 @@ bool stob(const string& str) return b; } +string unescape(const string& s) +{ + string res; + string::const_iterator it = s.begin(); + while (it != s.end()) + { + char c = *it++; + if (c == '\\' && it != s.end()) + { + switch (*it++) { + case '\\': c = '\\'; break; + case 'n': c = '\n'; break; + case 't': c = '\t'; break; + // all other escapes + default: + // invalid escape sequence - skip it. alternatively you can copy it as is, throw an exception... + continue; + } + } + res += c; + } + + return res; +} + +std::string escaped(const std::string& input) +{ + std::string output; + output.reserve(input.size()); + for (const char c : input) { + switch (c) { + case '\a': output += "\\a"; break; + case '\b': output += "\\b"; break; + case '\f': output += "\\f"; break; + case '\n': output += "\\n"; break; + case '\r': output += "\\r"; break; + case '\t': output += "\\t"; break; + case '\v': output += "\\v"; break; + default: output += c; break; + } + } + + return output; +} + string StringRaw(const string& s) { string str = trim(s); @@ -42,7 +88,7 @@ string StringRaw(const string& s) if (str[str.size() - 1] != '\"') withoutQuotes += str[str.size() - 1]; - return withoutQuotes; + return unescape(withoutQuotes); } string Quoted(const string& s) @@ -190,20 +236,25 @@ string betweenChars(const string& str, const char& openChar, const char& closeCh { string content = ""; - int waitingForClose = 0; + int startPos = 0; + int endPos = (int)str.size(); for (int i = 0; i < (int)str.size(); i++) { - if (waitingForClose > 0 && !(str[i] == closeChar && waitingForClose == 1)) - content += str[i]; - - if (str[i] == openChar) - waitingForClose++; - else if (str[i] == closeChar) - waitingForClose--; + if (str[i] == openChar){ + startPos = i+1; + break; + } + } + for (int i = (int)str.size()-1; i >=0; i--) + { + if (str[i] == closeChar){ + endPos = i-(startPos); // or startPos-1 idk I cant do math right now + break; + } } - return content; + return str.substr(startPos, endPos); } bool startsWith(const string& str, const string& lookFor) @@ -420,4 +471,4 @@ bool isEscaped(const string& str, int curChar) return true; return false; -} +} \ No newline at end of file diff --git a/ZSharp/strops.h b/ZSharp/strops.h index 24a171d..31ae45e 100644 --- a/ZSharp/strops.h +++ b/ZSharp/strops.h @@ -69,4 +69,6 @@ bool isEscaped(const string& str, int curChar); bool startsWith(const string& str, const string& lookFor); +std::string escaped(const std::string& input); + #endif diff --git a/examples/Platformer/extra-include.zs b/examples/Platformer/extra-include.zs index 29ef010..4ae0e42 100644 --- a/examples/Platformer/extra-include.zs +++ b/examples/Platformer/extra-include.zs @@ -1,5 +1,103 @@ +// This is an "included" ZS file, which can keep your main script +// tidier and more organized or easily share the same functions +// across multiple programs. + func TestInclude() { - print "Hello World!" -} \ No newline at end of file + Printl("Hello World!") +} +////////////////////////////////////////////////////////////////////////////// +// Benchmark, to check if performance suffers from too many functions/variables +////////////////////////////////////////////////////////////////////////////// +func b1() +{ + Printl("Hello World!") +} +func b2() +{ + Printl("Hello World!") +} +func b3() +{ + Printl("Hello World!") +} +func b4() +{ + Printl("Hello World!") +} +func b5() +{ + Printl("Hello World!") +} +func b6() +{ + Printl("Hello World!") +} +func b7() +{ + Printl("Hello World!") +} +func b8() +{ + Printl("Hello World!") +} +func b9() +{ + Printl("Hello World!") +} +func b10() +{ + Printl("Hello World!") +} +func b11() +{ + Printl("Hello World!") +} +func b12() +{ + Printl("Hello World!") +} +func b13() +{ + Printl("Hello World!") +} +func b14() +{ + Printl("Hello World!") +} +func b15() +{ + Printl("Hello World!") +} +func b16() +{ + Printl("Hello World!") +} + +int a = 4 +int b = 4 +int c = 4 +int d = 4 +int e = 4 +int f = 4 +int g = 4 +int h = 4 +int i = 4 +int j = 4 +int k = 4 +int l = 4 +int m = 4 +int n = 4 +int o = 4 +int p = 4 +int q = 4 +int r = 4 +int s = 4 +int t = 4 +int u = 4 +int v = 4 +int w = 4 +int x = 4 +int y = 4 +int z = 4 diff --git a/examples/Platformer/script.zs b/examples/Platformer/script.zs index 34cbbb6..8b08b97 100644 --- a/examples/Platformer/script.zs +++ b/examples/Platformer/script.zs @@ -2,108 +2,127 @@ int g_screenw = 256 int g_screenh = 224 int g_resolutionScale = 3 -float g_playerWalkSpeed = 400 -float g_playerRunSpeed = 700 -float g_jumpHeight = 20 +float g_playerWalkSpeed = 150 +float g_playerRunSpeed = 210 +float g_jumpHeight = 200 float g_currPlayerSpeed = 400 bool g_running = false +bool g_colliding = false -float g_gravitySpeed = -86 +float g_gravitySpeed = 86 -include "./extra-include.zs" +bool g_jumping = false +float g_jumpingTime = 0 + +//include "./extra-include.zs" func Main() { //SplitThread(ThreadedFunction()) + EXIT_WHEN_DONE = false - // Immediately creates the window, then Start(), then the game loop. The game loop calls Update() every frame + // Immediately creates the window, then runs Start(), then the game loop. The game loop calls Update() every frame ZS.Graphics.Init("Platformer game", g_screenw, g_screenh, g_resolutionScale) } func ThreadedFunction() { - print "threaded:" + Printl("threaded:") } func Start() { float centerX = g_screenw / 2 float centerY = g_screenh / 2 - global Vec2 g_screencenter = NVec2(centerX, centerY) + global Vec2 g_screencenter = NVec2(g_screenw / 2, g_screenh / 2) - Vec2 playerPos = g_screencenter - Vec2 playerScale = NVec2(16, 16) - global Sprite g_playerSprite = ZS.Graphics.Sprite("./mariostill.png", playerPos, playerScale, 0) + global Sprite g_playerSprite = ZS.Graphics.Sprite("./mariostill.png", g_screencenter, NVec2(16, 16), 0) - Vec2 groundPos = NVec2(g_screencenter.x, 192) - Vec2 groundScale = NVec2(256, 16) - global Sprite g_groundSprite = ZS.Graphics.Sprite("./square.png", groundPos, groundScale, 0) + global Sprite g_groundSprite = ZS.Graphics.Sprite("./square.png", NVec2(g_screencenter.x, 192), NVec2(256, 16), 0) - Vec2 instructionsPos = NVec2(centerOfScreen.x, centerOfScreen.y) - global Text g_instructionsText = ZS.Graphics.Text("Use Arrow Keys or WASD to Move, and Spacebar to Jump", "./arial.ttf", instructionsPos, 20, 0, 255, 255, 255) + global Text g_instructionsText = ZS.Graphics.Text("Use Arrow Keys or WASD to Move and Spacebar to Jump", "./arial.ttf", NVec2(g_screencenter.x, g_screencenter.y), 8, 0, 255, 255, 255) + g_instructionsText.antialias = false - global Vec2 g_playerTargetPosition = playerPos - - int i = 0 - while i < 10 { - i += 1 - print "while iter : " + i - } + global Vec2 g_playerTargetPosition = g_screencenter } -func Update(deltaTime) { +func Update(deltaTime) +{ float fps = 1 / deltaTime - print "FPS: " + fps + g_jumpingTime += deltaTime + Printl("FPS: " + fps) //TestInclude() - - //// Test automatic conversion from bool to int - //int c = GetKey("A") - //print "Test: " + c // Shift key lets you sprint g_running = GetKey("SHIFT_L") - if g_running == true{ + if g_running == true + { g_currPlayerSpeed = g_playerRunSpeed } + if g_running == false { g_currPlayerSpeed = g_playerWalkSpeed } // Move Left And Right - if GetKey("A") == true - { - float newY = g_playerSprite.position.y - - float newX = g_playerTargetPosition.x - g_currPlayerSpeed * deltaTime - g_playerTargetPosition = NVec2(newX, newY) - } if GetKey("D") == true { - float newY = g_playerSprite.position.y - - float newX = g_playerTargetPosition.x + g_currPlayerSpeed * deltaTime - g_playerTargetPosition = NVec2(newX, newY) + g_playerTargetPosition.x += g_currPlayerSpeed * deltaTime + } + if GetKey("A") == true + { + g_playerTargetPosition.x -= g_currPlayerSpeed * deltaTime } - // Lerps from old position to destination smoothly - float oldX = g_playerSprite.position.x - float newX = g_playerTargetPosition.x - float stopSpeed = deltaTime * 7 - float lerpedX = Lerp(oldX, newX, stopSpeed) - g_playerSprite.position = NVec2(lerpedX, newY) + // Apply gravity + g_colliding = Colliding(g_playerSprite, g_groundSprite) + if g_colliding == false + { + if g_jumping == false + { + g_playerTargetPosition.y += deltaTime * g_gravitySpeed + } + if g_jumping == true + { + g_playerTargetPosition.y -= (g_jumpHeight * deltaTime) + (deltaTime * g_gravitySpeed * -g_jumpingTime * 5) + } + } + if g_colliding == true + { + if GetKey("SPACE") == false + { + if g_jumpingTime > 1 + { + g_jumping = false + } + } + if GetKey("SPACE") == true + { + g_jumping = true + g_jumpingTime = 0 + g_playerTargetPosition.y -= 2 + } + } + + // Lerps from old position to destination smoothly + float stopSpeed = deltaTime * 15 + float lerpedX = Lerp(g_playerSprite.position.x, g_playerTargetPosition.x, stopSpeed) + g_playerSprite.position = NVec2(lerpedX, g_playerTargetPosition.y) + // Finally draws all of the sprites ZS.Graphics.Draw(g_playerSprite) ZS.Graphics.Draw(g_groundSprite) + // Draw the text ZS.Graphics.DrawText(g_instructionsText) } func Colliding(a, b) { - bool b = ZS.Physics.AxisAlignedCollision(a, b) - return b + bool bo = ZS.Physics.AxisAlignedCollision(a, b) + return bo } diff --git a/examples/Pong-Example-Project/ball.png b/examples/Pong-Example-Project/ball.png new file mode 100644 index 0000000..54ee51d Binary files /dev/null and b/examples/Pong-Example-Project/ball.png differ diff --git a/examples/Pong-Example-Project/script.zs b/examples/Pong-Example-Project/script.zs index 7f75a3c..932b113 100644 --- a/examples/Pong-Example-Project/script.zs +++ b/examples/Pong-Example-Project/script.zs @@ -16,6 +16,8 @@ bool aiOn = false // so if you never call ZS.Graphics.Init, then Start won't run func Main() { + EXIT_WHEN_DONE = false + // Immediately creates the window, then Start(), then the game loop. The game loop calls Update() every frame ZS.Graphics.Init("This is a pong game", SCREENW, SCREENH) } @@ -39,7 +41,7 @@ func Start() Vec2 rPaddlePosition = NVec2(rOffset, yPosPaddle) global Vec2 rPaddleTargetPosition = NVec2(rOffset, yPosPaddle) - global Sprite ballSpr = ZS.Graphics.Sprite("./square.png", ballPos, ballScale, 0) + global Sprite ballSpr = ZS.Graphics.Sprite("./ball.png", ballPos, ballScale, 0) global Sprite lPaddle = ZS.Graphics.Sprite("./square.png", lPaddlePosition, paddleScale, 0) global Sprite rPaddle = ZS.Graphics.Sprite("./square.png", rPaddlePosition, paddleScale, 0) @@ -62,7 +64,7 @@ func Start() func Update(deltaTime) { //float FPS = 1 / deltaTime - //print "FPS: " + FPS + //Printl("FPS: " + FPS) // Handles Left Paddle Movement // @@ -237,7 +239,7 @@ func HandleBallBounce() difference -= ballY float paddleHeight = rPaddle.scale.y float normalizedRelativeIntersectionY = difference / (paddleHeight / 2) - float bounceAngle = normalizedRelativeIntersectionY * 0.523599 + float bounceAngle = normalizedRelativeIntersectionY * -0.523599 float ballVx = ballSpeed ballVx *= Cos(bounceAngle) ballVx *= -1