Merge pull request #25 from sam-astro/dev

Features and bug fix v2.1.1-alpha
This commit is contained in:
sam-astro 2022-05-27 20:26:10 -04:00 committed by GitHub
commit 304093386a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 700 additions and 298 deletions

View File

@ -85,7 +85,7 @@ func Main()
if s == "r" if s == "r"
{ {
print s + " is r" Printl(s + " is r")
} }
int functionNumber = ExampleFunction("A", s) int functionNumber = ExampleFunction("A", s)
@ -99,8 +99,8 @@ func Main()
/// be assigned at all on execute and can be left blank /// be assigned at all on execute and can be left blank
func ExampleFunction(inputA, inputB) func ExampleFunction(inputA, inputB)
{ {
print "In A is: " + inputA Printl("In A is: " + inputA)
print "In B is: " + inputB Printl("In B is: " + inputB)
// Return a value to the valling location // Return a value to the valling location
return 4 return 4

View File

@ -2,9 +2,10 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
//bool DEVELOPER_MESSAGES = true;
#define DEVELOPER_MESSAGES false #define DEVELOPER_MESSAGES false
#define EXAMPLE_PROJECT false #define EXAMPLE_PROJECT false
#define NAMEVERSION "ZSharp v2.1.0-alpha" #define NAMEVERSION "ZSharp v2.1.1-alpha"
#if defined(__unix__) #if defined(__unix__)
#define UNIX true #define UNIX true
@ -77,10 +78,13 @@ boost::any GetVariableValue(const string& varName, const unordered_map<string, b
// Check if there is a variable with the specified name // Check if there is a variable with the specified name
bool IsVar(const string& varName, const unordered_map<string, boost::any>& variableValues) bool IsVar(const string& varName, const unordered_map<string, boost::any>& variableValues)
{ {
if (variableValues.find(split(varName, '.')[0]) != variableValues.end() && split(varName, '.')[0] != "ZS") if(split(varName, '.')[0] == "ZS")
return true;
else
return false; 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 // Return a vector of values that correspond to a vector of input variable names
@ -111,6 +115,20 @@ vector<boost::any> VarValues(const vector<string>& varNames, unordered_map<strin
return realValues; return realValues;
} }
void printVarValues(const vector<string>& vec, unordered_map<string, boost::any>& 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) bool IsFunction(const string& funcName)
{ {
if (functionValues.find(funcName) != functionValues.end()) if (functionValues.find(funcName) != functionValues.end())
@ -120,10 +138,7 @@ bool IsFunction(const string& funcName)
} }
bool IsZSFunction(const string& funcName) bool IsZSFunction(const string& funcName)
{ {
if (funcName[0] == 'Z' && funcName[1] == 'S' && funcName[2] == '.') return startsWith(funcName, "ZS.");
return true;
else
return false;
} }
boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& variableValues) boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& variableValues)
@ -146,30 +161,26 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
// start -> FuncCall(0, x, OtherFunc(a)) // start -> FuncCall(0, x, OtherFunc(a))
// changeto -> 0, x, OtherFunc(a) // changeto -> 0, x, OtherFunc(a)
string insideFunArgs = betweenChars(expression, '(', ')'); string insideFunArgs = betweenChars(expression, '(', ')');
#if DEVELOPER_MESSAGES == true
cout << insideFunArgs << endl;
#endif
vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')'); vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')');
#if DEVELOPER_MESSAGES == true #if DEVELOPER_MESSAGES == true
cout << "[" << unWrapVec(argList) << "]" << endl; cout << "[" << unWrapVec(argList) << "]" << endl;
printVarValues(argList, variableValues);
#endif #endif
vector<boost::any> funcArgs = VarValues(argList, variableValues); vector<boost::any> funcArgs = VarValues(argList, variableValues);
return ExecuteFunction(trim(split(expression, '(')[0]), funcArgs); return ExecuteFunction(split(expression, '(')[0], funcArgs);
} }
else if (isZS && !inQuotes) else if (isZS && !inQuotes)
{ {
// start -> FuncCall(0, x, OtherFunc(a)) // start -> FuncCall(0, x, OtherFunc(a))
// changeto -> 0, x, OtherFunc(a) // changeto -> 0, x, OtherFunc(a)
string insideFunArgs = betweenChars(expression, '(', ')'); string insideFunArgs = betweenChars(expression, '(', ')');
#if DEVELOPER_MESSAGES == true
cout << insideFunArgs << endl;
#endif
vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')'); vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')');
#if DEVELOPER_MESSAGES == true #if DEVELOPER_MESSAGES == true
cout << "[" << unWrapVec(argList) << "]" << endl; cout << split(expression, '(')[0]<< " [" << unWrapVec(argList) << "]" << endl;
printVarValues(argList, variableValues);
#endif #endif
vector<boost::any> funcArgs = VarValues(argList, variableValues); vector<boost::any> funcArgs = VarValues(argList, variableValues);
return ZSFunction(trim(split(expression, '(')[0]), funcArgs); return ZSFunction(split(expression, '(')[0], funcArgs);
} }
else else
return GetVariableValue(expression, variableValues); return GetVariableValue(expression, variableValues);
@ -200,15 +211,13 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
// start -> FuncCall(0, x, OtherFunc(a)) // start -> FuncCall(0, x, OtherFunc(a))
// changeto -> 0, x, OtherFunc(a) // changeto -> 0, x, OtherFunc(a)
string insideFunArgs = betweenChars(expression, '(', ')'); string insideFunArgs = betweenChars(expression, '(', ')');
#if DEVELOPER_MESSAGES == true
cout << insideFunArgs << endl;
#endif
vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')'); vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')');
#if DEVELOPER_MESSAGES == true #if DEVELOPER_MESSAGES == true
cout << unWrapVec(argList) << endl; cout << "[" << unWrapVec(argList) << "]" << endl;
printVarValues(argList, variableValues);
#endif #endif
vector<boost::any> funcArgs = VarValues(argList, variableValues); vector<boost::any> funcArgs = VarValues(argList, variableValues);
string returnVal = AnyAsString(ExecuteFunction(trim(split(expression, '(')[0]), funcArgs)); string returnVal = AnyAsString(ExecuteFunction(split(expression, '(')[0], funcArgs));
newExpression += returnVal; newExpression += returnVal;
} }
else if (split(name, '.')[0] == "ZS" && !inQuotes) else if (split(name, '.')[0] == "ZS" && !inQuotes)
@ -216,15 +225,13 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
// start -> FuncCall(0, x, OtherFunc(a)) // start -> FuncCall(0, x, OtherFunc(a))
// changeto -> 0, x, OtherFunc(a) // changeto -> 0, x, OtherFunc(a)
string insideFunArgs = betweenChars(expression, '(', ')'); string insideFunArgs = betweenChars(expression, '(', ')');
#if DEVELOPER_MESSAGES == true
cout << insideFunArgs << endl;
#endif
vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')'); vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')');
#if DEVELOPER_MESSAGES == true #if DEVELOPER_MESSAGES == true
cout << unWrapVec(argList) << endl; cout << "[" << unWrapVec(argList) << "]" << endl;
printVarValues(argList, variableValues);
#endif #endif
vector<boost::any> funcArgs = VarValues(argList, variableValues); vector<boost::any> funcArgs = VarValues(argList, variableValues);
string returnVal = AnyAsString(ExecuteFunction(trim(split(expression, '(')[0]), funcArgs)); string returnVal = AnyAsString(ZSFunction(split(expression, '(')[0], funcArgs));
newExpression += returnVal; newExpression += returnVal;
} }
else else
@ -277,27 +284,33 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
return evaluate(newExpression); return evaluate(newExpression);
} }
bool BooleanLogic(const string& valA, const string& determinant, const string& valB, unordered_map<string, boost::any>& variableValues) bool BooleanLogic(const string& valA, const string& comparer, const string& valB, unordered_map<string, boost::any>& variableValues)
{ {
boost::any valARealValue = EvalExpression(valA, variableValues); boost::any valARealValue;
boost::any valBRealValue = EvalExpression(valB, variableValues); boost::any valBRealValue;
if(valA != "")
valARealValue = EvalExpression(valA, variableValues);
if(valB != "")
valBRealValue = EvalExpression(valB, variableValues);
#if DEVELOPER_MESSAGES == true #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 #endif
if (determinant == "==") if (comparer == "==")
return any_compare(valARealValue, valBRealValue); return any_compare(valARealValue, valBRealValue);
else if (determinant == "!=") else if (comparer == "!=")
return !any_compare(valARealValue, valBRealValue); return !any_compare(valARealValue, valBRealValue);
else if (determinant == ">=") else if (comparer == ">=")
return AnyAsFloat(valARealValue) >= AnyAsFloat(valBRealValue); return AnyAsFloat(valARealValue) >= AnyAsFloat(valBRealValue);
else if (determinant == "<=") else if (comparer == "<=")
return AnyAsFloat(valARealValue) <= AnyAsFloat(valBRealValue); return AnyAsFloat(valARealValue) <= AnyAsFloat(valBRealValue);
else if (determinant == ">") else if (comparer == ">")
return AnyAsFloat(valARealValue) > AnyAsFloat(valBRealValue); return AnyAsFloat(valARealValue) > AnyAsFloat(valBRealValue);
else if (determinant == "<") else if (comparer == "<")
return AnyAsFloat(valARealValue) < AnyAsFloat(valBRealValue); return AnyAsFloat(valARealValue) < AnyAsFloat(valBRealValue);
else if (comparer == "")
return AnyAsBool(valARealValue) == true;
else else
LogWarning("unrecognized determinant \'" + determinant + "\'"); LogWarning("unrecognized comparer \'" + comparer + "\'");
return false; return false;
} }
@ -384,12 +397,12 @@ int varOperation(const vector<string>& str, unordered_map<string, boost::any>& v
boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unordered_map<string, boost::any>& variableValues) boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unordered_map<string, boost::any>& variableValues)
{ {
// Check if the first two chars are '//', which would make it a comment //// 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] == '/') //if (startsWith(words.at(lineNum).at(0), "//"))
return nullType; // return nullType;
// If print statement (deprecated, now use ZS.System.Print() function) // 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<string>(words.at(lineNum).begin() + 1, words.at(lineNum).end())), variableValues))) << endl; cout << StringRaw(AnyAsString(EvalExpression(unWrapVec(vector<string>(words.at(lineNum).begin() + 1, words.at(lineNum).end())), variableValues))) << endl;
return nullType; return nullType;
@ -399,24 +412,28 @@ boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unorde
else if (words.at(lineNum).at(0) == "return") else if (words.at(lineNum).at(0) == "return")
return EvalExpression(unWrapVec(vector<string>(words.at(lineNum).begin() + 1, words.at(lineNum).end())), variableValues); return EvalExpression(unWrapVec(vector<string>(words.at(lineNum).begin() + 1, words.at(lineNum).end())), variableValues);
// Check if it is ZS Builtin function // Check if it is ZS Builtin function call
else if (words.at(lineNum).at(0)[0] == 'Z' && words.at(lineNum).at(0)[1] == 'S' && words.at(lineNum).at(0)[2] == '.') else if (startsWith(words.at(lineNum).at(0), "ZS."))
return EvalExpression(unWrapVec(words.at(lineNum)), variableValues); return EvalExpression(unWrapVec(words.at(lineNum)), variableValues);
// Check if it is function // Check if it is function call
else if (IsFunction(trim(split(words.at(lineNum).at(0), '(')[0]))) else if (IsFunction(split(words.at(lineNum).at(0), '(')[0]))
{ {
// No args provided // No args provided
if (count(words.at(lineNum).at(0), '(') > 0 && count(words.at(lineNum).at(0), ')') > 0) if (indexInStr(words.at(lineNum).at(0), ')') - indexInStr(words.at(lineNum).at(0), '(')<=1)
ExecuteFunction(trim(split(words.at(lineNum).at(0), '(')[0]), vector<boost::any>()); ExecuteFunction(split(words.at(lineNum).at(0), '(')[0], vector<boost::any>());
else else
{ // Args provided, parse them first { // Args provided, parse them first
// start -> FuncCall(0, x, OtherFunc(a)) // start -> FuncCall(0, x, OtherFunc(a))
// changeto -> 0, x, OtherFunc(a) // changeto -> 0, x, OtherFunc(a)
string insideFunArgs = betweenChars(unWrapVec(words.at(lineNum)), '(', ')'); string insideFunArgs = betweenChars(unWrapVec(words.at(lineNum)), '(', ')');
vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')'); vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')');
#if DEVELOPER_MESSAGES == true
cout << unWrapVec(argList) << endl;
printVarValues(argList, variableValues);
#endif
vector<boost::any> funcArgs = VarValues(argList, variableValues); vector<boost::any> 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; return nullType;
} }
@ -424,7 +441,7 @@ boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unorde
// Check if it is a SplitThread call // Check if it is a SplitThread call
else if (startsWith(words.at(lineNum).at(0), "SplitThread")) else if (startsWith(words.at(lineNum).at(0), "SplitThread"))
{ {
vector<string> lineContents = removeTabs(words.at(lineNum), 10); vector<string> lineContents = words.at(lineNum);
cout << "New Thread: " << words.at(lineNum).at(0) << endl; cout << "New Thread: " << words.at(lineNum).at(0) << endl;
//lineContents.at(0) = betweenChars(lineContents.at(0), '(', ')'); //lineContents.at(0) = betweenChars(lineContents.at(0), '(', ')');
@ -438,18 +455,31 @@ boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unorde
} }
// Check if global variable declaration // 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; return nullType;
} }
// Iterate through all types to see if line inits or // Iterate through all types to see if line inits or
// re-inits a variable then store it with it's value // 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; try
variableValues[words.at(lineNum).at(1)] = EvalExpression(unWrapVec(slice(words.at(lineNum), 3, -1)), variableValues); {
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; return nullType;
} }
@ -478,6 +508,7 @@ boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unorde
vector<vector<string>> whileContents; vector<vector<string>> whileContents;
vector<string> whileParameters; vector<string> whileParameters;
// Gather the parameters that must be == true for the loop to run
int numOfBrackets = 0; int numOfBrackets = 0;
for (int w = 1; w < (int)words.at(lineNum).size(); w++) { for (int w = 1; w < (int)words.at(lineNum).size(); w++) {
if (count(words.at(lineNum).at(w), '{') == 0) if (count(words.at(lineNum).at(w), '{') == 0)
@ -489,8 +520,22 @@ boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unorde
break; 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()) while (lineNum < (int)words.size())
{ {
numOfBrackets += countInVector(words.at(lineNum), "{") - countInVector(words.at(lineNum), "}"); numOfBrackets += countInVector(words.at(lineNum), "{") - countInVector(words.at(lineNum), "}");
@ -500,16 +545,30 @@ boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unorde
lineNum++; lineNum++;
} }
whileContents = removeTabsWdArry(whileContents, 1); //whileContents = removeTabsWdArry(whileContents, 1);
// Loop while true
while (BooleanLogic(whileParameters.at(0), whileParameters.at(1), whileParameters.at(2), variableValues)) while (BooleanLogic(whileParameters.at(0), whileParameters.at(1), whileParameters.at(2), variableValues))
{ {
//Iterate through all lines in while loop //Iterate through all lines in while loop
for (int lineNum = 0; lineNum < (int)whileContents.size(); lineNum++) 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); boost::any returnVal = ProcessLine(whileContents, lineNum, variableValues);
if (!returnVal.empty()) if (!returnVal.empty()) {
return returnVal; try
{
BREAK t = any_cast<BREAK>(returnVal);
return nullType;
}
catch (boost::bad_any_cast)
{
return returnVal;
}
}
} }
} }
return nullType; return nullType;
@ -521,6 +580,7 @@ boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unorde
vector<vector<string>> ifContents; vector<vector<string>> ifContents;
vector<string> ifParameters; vector<string> ifParameters;
// Gather the parameters that must be == true for the loop to run
int numOfBrackets = 0; int numOfBrackets = 0;
for (int w = 1; w < (int)words.at(lineNum).size(); w++) { for (int w = 1; w < (int)words.at(lineNum).size(); w++) {
if (count(words.at(lineNum).at(w), '{') == 0) if (count(words.at(lineNum).at(w), '{') == 0)
@ -533,6 +593,20 @@ boost::any ProcessLine(const vector<vector<string>>& 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++; lineNum++;
while (lineNum < (int)words.size()) while (lineNum < (int)words.size())
{ {
@ -542,22 +616,24 @@ boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unorde
ifContents.push_back(words.at(lineNum)); ifContents.push_back(words.at(lineNum));
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)) if (BooleanLogic(ifParameters.at(0), ifParameters.at(1), ifParameters.at(2), variableValues))
{ {
//Iterate through all lines in if statement //Iterate through all lines in if statement
for (int l = 0; l < (int)ifContents.size(); l++) 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); boost::any returnVal = ProcessLine(ifContents, l, variableValues);
if (!returnVal.empty()) if (!returnVal.empty())
return returnVal; 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<vector<string>> elseContents; vector<vector<string>> elseContents;
vector<string> elseParameters; vector<string> elseParameters;
@ -581,9 +657,9 @@ boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unorde
lineNum++; 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++) for (int l = 0; l < (int)elseContents.size(); l++)
{ {
boost::any returnVal = ProcessLine(elseContents, l, variableValues); boost::any returnVal = ProcessLine(elseContents, l, variableValues);
@ -595,12 +671,6 @@ boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unorde
} }
return nullType; return nullType;
} }
//// Gathers else statement contents
//if (words[lineNum][0] == "else")
//{
//
//}
return nullType; return nullType;
} }
@ -619,7 +689,7 @@ boost::any ExecuteFunction(const string& functionName, const vector<boost::any>&
{ {
variableValues[funcArgs[i]] = inputVarVals[i]; variableValues[funcArgs[i]] = inputVarVals[i];
#if DEVELOPER_MESSAGES == true #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 #endif
} }
} }
@ -635,6 +705,7 @@ boost::any ExecuteFunction(const string& functionName, const vector<boost::any>&
} }
catch (const std::exception&) catch (const std::exception&)
{ {
LogCriticalError("Error at line: " + to_string(lineNum) + ", " + unWrapVec(words.at(lineNum)));
} }
} }
return nullType; return nullType;
@ -642,21 +713,33 @@ boost::any ExecuteFunction(const string& functionName, const vector<boost::any>&
int parseZSharp(string script) int parseZSharp(string script)
{ {
script = replace(script, " ", "\t"); // Replace spaces with tabs (not really required, and will break purposefull whitespace in strings etc.) //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 // Split the script by newline, signifying a line ending
vector<string> lines = split(script, '\n'); vector<string> beforeProcessLines = split(script, '\n');
vector<string> 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<vector<string>> words; vector<vector<string>> words;
for (int i = 0; i < (int)lines.size(); i++) // Then split said lines into indiviual words for (int i = 0; i < (int)lines.size(); i++) // Then split said lines into indiviual words
{
words.push_back(split(lines.at(i), ' ')); words.push_back(split(lines.at(i), ' '));
#if DEVELOPER_MESSAGES
cout << unWrapVec(words.at(i)) << endl;
#endif
}
#if DEVELOPER_MESSAGES #if DEVELOPER_MESSAGES
InterpreterLog("Gather variables & functions..."); InterpreterLog("Gather variables & functions...");
#endif #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 // or function declaration, then store it with it's value
for (int lineNum = 0; lineNum < (int)words.size(); lineNum++) for (int lineNum = 0; lineNum < (int)words.size(); lineNum++)
{ {
@ -670,18 +753,35 @@ int parseZSharp(string script)
InterpreterLog("Load script function " + functName + "..."); InterpreterLog("Load script function " + functName + "...");
#endif #endif
string args = ""; //string args = "";
if (indexInStr(unWrapVec(words.at(lineNum)), ')') - indexInStr(unWrapVec(words.at(lineNum)), '(') > 1) //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 // 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) // if (count(words.at(lineNum).at(w), '{') == 0)
args += replace(replace(words.at(lineNum).at(w), "(", " "), ")", ""); // args += replace(replace(words.at(lineNum).at(w), "(", " "), ")", "");
} // }
string args = betweenChars(unWrapVec(words.at(lineNum)), '(', ')');
//cout << functName << "<" << args << ">" << endl;
args = trim(replace(args, functName + " ", "")); //args = trim(replace(args, functName, ""));
functionContents.push_back(split(args, ',')); 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++) { for (int w = 1; w < (int)words.at(lineNum).size(); w++) {
if (count(words.at(lineNum).at(w), '{') != 0) { if (count(words.at(lineNum).at(w), '{') != 0) {
numOfBrackets = 1; numOfBrackets = 1;
@ -695,7 +795,7 @@ int parseZSharp(string script)
if (numOfBrackets == 0) if (numOfBrackets == 0)
break; break;
functionContents.push_back(removeTabs(words.at(p), 1)); functionContents.push_back(removeTabs(words.at(p), 1));
} }*/
functionValues[functName] = functionContents; functionValues[functName] = functionContents;
} }
else else
@ -736,26 +836,34 @@ int parseZSharp(string script)
InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "...");
#endif #endif
} }
else if (words.at(lineNum).at(0) == "int") {
globalVariableValues[words.at(lineNum).at(1)] = stoi(words.at(lineNum).at(3)); // Iterate through all types to see if line inits or
#if DEVELOPER_MESSAGES == true // re-inits a variable then store it with it's value
InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); else if (countInVector(types, trim(words.at(lineNum).at(0))) > 0)
#endif {
//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") { // else if (words.at(lineNum).at(0) == "int") {
globalVariableValues[words.at(lineNum).at(1)] = stof(words.at(lineNum).at(3)); // globalVariableValues[words.at(lineNum).at(1)] = stoi(words.at(lineNum).at(3));
#if DEVELOPER_MESSAGES == true //#if DEVELOPER_MESSAGES == true
InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); // InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "...");
#endif //#endif
} // }
else if (words.at(lineNum).at(0) == "bool") { // else if (words.at(lineNum).at(0) == "float") {
globalVariableValues[words.at(lineNum).at(1)] = stob(words.at(lineNum).at(3)); // globalVariableValues[words.at(lineNum).at(1)] = stof(words.at(lineNum).at(3));
#if DEVELOPER_MESSAGES == true //#if DEVELOPER_MESSAGES == true
InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "..."); // InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "...");
#endif //#endif
} // }
/*else // else if (words.at(lineNum).at(0) == "bool") {
LogWarning("unrecognized type \'" + words.at(lineNum).at(0) + "\' on line: " + to_string(lineNum));*/ // 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; cout << endl << endl;
// Gathers builtin functions and variables // Gathers builtin functions and variables
GetBuiltins(ZSContents); parseZSharp(ZSContents);
functionValues = builtinFunctionValues; //functionValues = builtinFunctionValues;
globalVariableValues = builtinVarVals; //globalVariableValues = builtinVarVals;
std::string scriptTextContents; std::string scriptTextContents;
@ -780,7 +888,7 @@ int main(int argc, char* argv[])
{ {
std::string scriptPath; std::string scriptPath;
if (EXAMPLE_PROJECT) 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 else
scriptPath = argv[1]; scriptPath = argv[1];
#if DEVELOPER_MESSAGES #if DEVELOPER_MESSAGES
@ -804,12 +912,11 @@ int main(int argc, char* argv[])
int chErr = chdir(projectDirectory.c_str()); int chErr = chdir(projectDirectory.c_str());
if (chErr < 0) if (chErr < 0)
LogCriticalError("Failed to change directory to: \"" + projectDirectory + "\", error num: " + to_string(chErr)); LogCriticalError("Failed to change directory to: \"" + projectDirectory + "\", error num: " + to_string(chErr));
#if DEVELOPER_MESSAGES #if DEVELOPER_MESSAGES
InterpreterLog("Changed directory to " + projectDirectory + "..."); InterpreterLog("Changed directory to " + projectDirectory + "...");
#endif #endif
#if DEVELOPER_MESSAGES
string newPath = filesystem::current_path();
#endif
#elif WINDOWS #elif WINDOWS
// Get script contents as single string // Get script contents as single string
ifstream script(scriptPath); ifstream script(scriptPath);
@ -831,9 +938,9 @@ int main(int argc, char* argv[])
#endif #endif
} }
else 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."); 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(); cin.ignore();
exit(1); exit(1);
} }
@ -858,7 +965,7 @@ int main(int argc, char* argv[])
// Entire script has been run, exit. // Entire script has been run, exit.
#if DEVELOPER_MESSAGES // If built with developer messages, then verify exit #if DEVELOPER_MESSAGES // If built with developer messages, then verify exit
cout << "Press Enter to Continue"; InterpreterLog("Press Enter to Exit...");
cin.ignore(); cin.ignore();
exit(1); exit(1);
#else #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 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(); cin.ignore();
exit(1); exit(1);
} }
} }
else if (AnyAsBool(GetVariableValue("EXIT_WHEN_DONE", globalVariableValues)) == false)
{
InterpreterLog("Press Enter to Exit...");
cin.ignore();
exit(1);
}
#endif // Else exit automatically #endif // Else exit automatically
return 0; return 0;
} }

View File

@ -3,11 +3,18 @@
using namespace std; using namespace std;
std::string ZSContents = R"( std::string ZSContents = R"(
////////////////////////////////////////////////////////////////////////////////
// BUILTIN
////////////////////////////////////////////////////////////////////////////////
// Default variables, can be overwritten // Default variables, can be overwritten
// if re-initialized or changed // if re-initialized or changed
float PI = 3.14159265358979323846264338 float PI = 3.14159265358979323846264338
float EulersNumber = 2.71828183 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 // Trigonometric function Sin
func Sin(input) func Sin(input)
{ {
@ -100,15 +107,15 @@ func SetPixel(x, y, r, g, b)
} }
// Prints input value to console // 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' // 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 // Creates new sprite class
@ -138,9 +145,73 @@ func GetKey(keyName)
return b return b
} }
// WIP
//func SplitThread(function) //func SplitThread(function)
//{ //{
// ZS.System.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)
}
)" )"
; ;

View File

@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "Z-Sharp" #define MyAppName "Z-Sharp"
#define MyAppVersion "2.1.0-alpha" #define MyAppVersion "2.1.1-alpha"
#define MyAppPublisher "AstroSam" #define MyAppPublisher "AstroSam"
#define MyAppURL "https://github.com/sam-astro/Z-Sharp" #define MyAppURL "https://github.com/sam-astro/Z-Sharp"
#define MyAppExeName "ZSharp.exe" #define MyAppExeName "ZSharp.exe"

View File

@ -28,8 +28,8 @@ using namespace boost;
vector<string> types = { "int", "float", "string", "bool", "void", "null", "Sprite", "Vec2", "Text" }; vector<string> types = { "int", "float", "string", "bool", "void", "null", "Sprite", "Vec2", "Text" };
unordered_map<string, vector<vector<string>>> builtinFunctionValues; //unordered_map<string, vector<vector<string>>> builtinFunctionValues;
unordered_map<string, boost::any> builtinVarVals; //unordered_map<string, boost::any> builtinVarVals;
// Foreground colors // Foreground colors
const std::string blackFGColor = "\x1B[30m"; const std::string blackFGColor = "\x1B[30m";
@ -72,8 +72,13 @@ class NullType {
public: public:
string type = "NULL"; string type = "NULL";
}; };
class BREAK {
public:
string type = "BREAK";
};
boost::any nullType; boost::any nullType;
boost::any breakReOp;
float clamp(float v, float min, float max) 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) int LogWarning(const string& warningText)
{ {
PrintColored("WARNING: ", yellowFGColor, "", true); PrintColored("WARNING: ", yellowFGColor, "", true);
PrintColored(warningText, yellowFGColor, "", true); PrintColored(escaped(warningText), yellowFGColor, "", true);
cerr << std::endl; cerr << std::endl;
//cout << "\x1B[33mWARNING: " << warningText << "\033[0m\t\t" << endl; //cout << "\x1B[33mWARNING: " << warningText << "\033[0m\t\t" << endl;
return 1; return 1;
@ -157,7 +162,15 @@ int InterpreterLog(const string& logText)
tm bt{}; tm bt{};
#if UNIX #if UNIX
//localtime_r(&timer, &bt); time_t currentTime;
struct tm* localTime;
time(&currentTime); // Get the current time
localTime = localtime(&currentTime); // Convert the current time to the local time
Hour = localTime->tm_hour;
Min = localTime->tm_min;
Sec = localTime->tm_sec;
#elif WINDOWS #elif WINDOWS
localtime_s(&bt, &timer); localtime_s(&bt, &timer);
Hour = bt.tm_hour; 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("[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] ", blueFGColor, "", true);
PrintColored("ZSharp: ", yellowFGColor, "", true); PrintColored("ZSharp: ", yellowFGColor, "", true);
PrintColored(logText, greenFGColor, "", true); PrintColored(escaped(logText), greenFGColor, "", true);
cout << std::endl; 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; //cout << "\x1B[34m[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] \x1B[33mZSharp: \x1B[32m" << logText << "\033[0m\t\t" << endl;
return 1; return 1;
@ -185,9 +198,17 @@ int LogCriticalError(const string& errorText)
time_t timer = time(0); time_t timer = time(0);
tm bt{}; tm bt{};
#if defined(__unix__) #if UNIX
//localtime_r(&timer, &bt); time_t currentTime;
#elif defined(_MSC_VER) struct tm* localTime;
time(&currentTime); // Get the current time
localTime = localtime(&currentTime); // 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); localtime_s(&bt, &timer);
Hour = bt.tm_hour; Hour = bt.tm_hour;
Min = bt.tm_min; 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("[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] ", blueFGColor, "", true);
PrintColored("ZSharp: ", yellowFGColor, "", true); PrintColored("ZSharp: ", yellowFGColor, "", true);
PrintColored(errorText, redFGColor, "", true); PrintColored(escaped(errorText), redFGColor, "", true);
cerr << std::endl; cerr << std::endl;
cout << "Press Enter to Continue"; InterpreterLog("Press Enter to Exit...");
cin.ignore(); cin.ignore();
exit(1); exit(1);
//cerr << "\x1B[34m[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] \x1B[33mZSharp: \x1B[31mERROR: " << errorText << "\033[0m\t\t" << endl; //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; return collisionX && collisionY;
} }
// Initial script processing, which loads variables and functions from builtin //// Initial script processing, which loads variables and functions from builtin
int GetBuiltins(std::string s) //int GetBuiltins(std::string s)
{ //{
std::string script = replace(s, " ", "\t"); // std::string script = replace(s, " ", "\t");
//
vector<string> lines = split(script, '\n'); // vector<string> lines = split(script, '\n');
vector<vector<string>> words; // vector<vector<string>> words;
for (int i = 0; i < (int)lines.size(); i++) // for (int i = 0; i < (int)lines.size(); i++)
{ // {
words.push_back(split(lines.at(i), ' ')); // words.push_back(split(lines.at(i), ' '));
} // }
//
// Go through entire script and iterate through all types to see if line is a // // Go through entire script and iterate through all types to see if line is a
// function declaration, then store it with it's value // // function declaration, then store it with it's value
for (int lineNum = 0; lineNum < (int)words.size(); lineNum++) // for (int lineNum = 0; lineNum < (int)words.size(); lineNum++)
{ // {
//Checks if it is function // //Checks if it is function
if (words.at(lineNum).at(0) == "func") // if (words.at(lineNum).at(0) == "func")
{ // {
vector<vector<string>> functionContents; // vector<vector<string>> functionContents;
//
string functName = split(words.at(lineNum).at(1), '(')[0]; // string functName = split(words.at(lineNum).at(1), '(')[0];
//
#if DEVELOPER_MESSAGES == true //#if DEVELOPER_MESSAGES == true
InterpreterLog("Load builtin function " + functName + "..."); // InterpreterLog("Load builtin function " + functName + "...");
#endif //#endif
//
string args = ""; // string args = "";
for (int w = 1; w < (int)words.at(lineNum).size(); w++) // Get all words from the instantiation line: these are the 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(replace(words.at(lineNum).at(w), "(", " "), ")", "");
} // }
//
args = replace(args, functName + " ", ""); // args = replace(args, functName + " ", "");
functionContents.push_back(split(args, ',')); // functionContents.push_back(split(args, ','));
//
int numOfBrackets = 1; // int numOfBrackets = 1;
for (int p = lineNum + 2; p < (int)words.size(); p++) // for (int p = lineNum + 2; p < (int)words.size(); p++)
{ // {
numOfBrackets += countInVector(words.at(p), "{") - countInVector(words.at(p), "}"); // numOfBrackets += countInVector(words.at(p), "{") - countInVector(words.at(p), "}");
if (numOfBrackets == 0) // if (numOfBrackets == 0)
break; // break;
functionContents.push_back(removeTabs(words.at(p), 1)); // functionContents.push_back(removeTabs(words.at(p), 1));
} // }
builtinFunctionValues[functName] = functionContents; // builtinFunctionValues[functName] = functionContents;
//cout << functName << " is \n" << Vec2Str(functionContents) << endl << endl; // //cout << functName << " is \n" << Vec2Str(functionContents) << endl << endl;
} // }
else // else
{ // {
if (words.at(lineNum).at(0) == "string") // if (words.at(lineNum).at(0) == "string")
{ // {
builtinVarVals[words.at(lineNum).at(1)] = StringRaw(words.at(lineNum).at(3)); // builtinVarVals[words.at(lineNum).at(1)] = StringRaw(words.at(lineNum).at(3));
#if DEVELOPER_MESSAGES == true //#if DEVELOPER_MESSAGES == true
InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); // InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "...");
#endif //#endif
} // }
else if (words.at(lineNum).at(0) == "int") // else if (words.at(lineNum).at(0) == "int")
{ // {
builtinVarVals[words.at(lineNum).at(1)] = stoi(words.at(lineNum).at(3)); // builtinVarVals[words.at(lineNum).at(1)] = stoi(words.at(lineNum).at(3));
#if DEVELOPER_MESSAGES == true //#if DEVELOPER_MESSAGES == true
InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); // InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "...");
#endif //#endif
} // }
else if (words.at(lineNum).at(0) == "float") // else if (words.at(lineNum).at(0) == "float")
{ // {
builtinVarVals[words.at(lineNum).at(1)] = stof(words.at(lineNum).at(3)); // builtinVarVals[words.at(lineNum).at(1)] = stof(words.at(lineNum).at(3));
#if DEVELOPER_MESSAGES == true //#if DEVELOPER_MESSAGES == true
InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); // InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "...");
#endif //#endif
} // }
else if (words.at(lineNum).at(0) == "bool") // else if (words.at(lineNum).at(0) == "bool")
{ // {
builtinVarVals[words.at(lineNum).at(1)] = stob(words.at(lineNum).at(3)); // builtinVarVals[words.at(lineNum).at(1)] = stob(words.at(lineNum).at(3));
#if DEVELOPER_MESSAGES == true //#if DEVELOPER_MESSAGES == true
InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); // InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "...");
#endif //#endif
} // }
//else // //else
// LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + to_string(lineNum)); // // LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + to_string(lineNum));
} // }
} // }
//
return 0; // return 0;
} //}
// Executes // Executes
boost::any ZSFunction(const string& name, const vector<boost::any>& args) boost::any ZSFunction(const string& name, const vector<boost::any>& args)
@ -403,8 +424,16 @@ boost::any ZSFunction(const string& name, const vector<boost::any>& args)
if (!fileExists(StringRaw(AnyAsString(args.at(1))))) if (!fileExists(StringRaw(AnyAsString(args.at(1)))))
LogCriticalError("Failed to create 'Text' object: \"" + 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<Vec2>(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))); if (args.size() <= 8)
return t; {
Text t(StringRaw(AnyAsString(args.at(0))), StringRaw(AnyAsString(args.at(1))), any_cast<Vec2>(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<Vec2>(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") else if (name == "ZS.Graphics.DrawText")
any_cast<Text>(args.at(0)).Draw(); any_cast<Text>(args.at(0)).Draw();
@ -417,9 +446,9 @@ boost::any ZSFunction(const string& name, const vector<boost::any>& args)
else if (name == "ZS.Input.GetKey") else if (name == "ZS.Input.GetKey")
return KEYS[StringRaw(any_cast<string>(args.at(0)))] == 1; return KEYS[StringRaw(any_cast<string>(args.at(0)))] == 1;
else if (name == "ZS.System.Print") 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") 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") else if (name == "ZS.System.Vec2")
{ {
Vec2 v(AnyAsFloat(args.at(0)), AnyAsFloat(args.at(1))); Vec2 v(AnyAsFloat(args.at(0)), AnyAsFloat(args.at(1)));

View File

@ -523,8 +523,8 @@ public:
class Text class Text
{ {
public: public:
Text(std::string content, std::string pathToFont, Vec2 position, float fontSize, double angle, Uint8 r, Uint8 g, Uint8 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) : position(position), angle(angle), content(content), pathToFont(pathToFont), fontSize(fontSize), r(r), g(g), b(b), antialias(antialias)
{ {
rect.x = position.x; rect.x = position.x;
rect.y = position.y; rect.y = position.y;
@ -538,8 +538,12 @@ public:
{ {
SDL_Color color = { r, g, b }; 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); texture = SDL_CreateTextureFromSurface(gRenderer, surface);
TTF_SizeText(font, content.c_str(), &rect.w, &rect.h); TTF_SizeText(font, content.c_str(), &rect.w, &rect.h);
@ -559,7 +563,11 @@ public:
{ {
SDL_Color color = { r, g, b }; 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); SDL_DestroyTexture(texture);
texture = SDL_CreateTextureFromSurface(gRenderer, surface); texture = SDL_CreateTextureFromSurface(gRenderer, surface);
@ -604,6 +612,8 @@ public:
return content; return content;
if (componentName == "pathToFont") if (componentName == "pathToFont")
return pathToFont; return pathToFont;
if (componentName == "antialias")
return antialias;
return 0; return 0;
} }
@ -711,12 +721,19 @@ public:
else if (oper == "+=") else if (oper == "+=")
content += AnyAsString(otherVal); content += AnyAsString(otherVal);
} }
else if (componentName == "antialias")
{
if (oper == "=")
antialias = AnyAsBool(otherVal);
}
// Updates changes to text // Updates changes to text
Update(); Update();
return *this; return *this;
} }
bool antialias = true;
Vec2 position; Vec2 position;
Vec2 scale; Vec2 scale;
float fontSize; float fontSize;

View File

@ -8,7 +8,8 @@
//#include "builtin.h" //#include "builtin.h"
using namespace std; 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) bool isNumber(const string& str)
@ -25,6 +26,51 @@ bool stob(const string& str)
return b; 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 StringRaw(const string& s)
{ {
string str = trim(s); string str = trim(s);
@ -42,7 +88,7 @@ string StringRaw(const string& s)
if (str[str.size() - 1] != '\"') if (str[str.size() - 1] != '\"')
withoutQuotes += str[str.size() - 1]; withoutQuotes += str[str.size() - 1];
return withoutQuotes; return unescape(withoutQuotes);
} }
string Quoted(const string& s) string Quoted(const string& s)
@ -190,20 +236,25 @@ string betweenChars(const string& str, const char& openChar, const char& closeCh
{ {
string content = ""; string content = "";
int waitingForClose = 0; int startPos = 0;
int endPos = (int)str.size();
for (int i = 0; i < (int)str.size(); i++) for (int i = 0; i < (int)str.size(); i++)
{ {
if (waitingForClose > 0 && !(str[i] == closeChar && waitingForClose == 1)) if (str[i] == openChar){
content += str[i]; startPos = i+1;
break;
if (str[i] == openChar) }
waitingForClose++; }
else if (str[i] == closeChar) for (int i = (int)str.size()-1; i >=0; i--)
waitingForClose--; {
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) bool startsWith(const string& str, const string& lookFor)
@ -420,4 +471,4 @@ bool isEscaped(const string& str, int curChar)
return true; return true;
return false; return false;
} }

View File

@ -69,4 +69,6 @@ bool isEscaped(const string& str, int curChar);
bool startsWith(const string& str, const string& lookFor); bool startsWith(const string& str, const string& lookFor);
std::string escaped(const std::string& input);
#endif #endif

View File

@ -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() func TestInclude()
{ {
print "Hello World!" 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

View File

@ -2,108 +2,127 @@ int g_screenw = 256
int g_screenh = 224 int g_screenh = 224
int g_resolutionScale = 3 int g_resolutionScale = 3
float g_playerWalkSpeed = 400 float g_playerWalkSpeed = 150
float g_playerRunSpeed = 700 float g_playerRunSpeed = 210
float g_jumpHeight = 20 float g_jumpHeight = 200
float g_currPlayerSpeed = 400 float g_currPlayerSpeed = 400
bool g_running = false 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() func Main()
{ {
//SplitThread(ThreadedFunction()) //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) ZS.Graphics.Init("Platformer game", g_screenw, g_screenh, g_resolutionScale)
} }
func ThreadedFunction() func ThreadedFunction()
{ {
print "threaded:" Printl("threaded:")
} }
func Start() func Start()
{ {
float centerX = g_screenw / 2 float centerX = g_screenw / 2
float centerY = g_screenh / 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 global Sprite g_playerSprite = ZS.Graphics.Sprite("./mariostill.png", g_screencenter, NVec2(16, 16), 0)
Vec2 playerScale = NVec2(16, 16)
global Sprite g_playerSprite = ZS.Graphics.Sprite("./mariostill.png", playerPos, playerScale, 0)
Vec2 groundPos = NVec2(g_screencenter.x, 192) global Sprite g_groundSprite = ZS.Graphics.Sprite("./square.png", NVec2(g_screencenter.x, 192), NVec2(256, 16), 0)
Vec2 groundScale = NVec2(256, 16)
global Sprite g_groundSprite = ZS.Graphics.Sprite("./square.png", groundPos, groundScale, 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", NVec2(g_screencenter.x, g_screencenter.y), 8, 0, 255, 255, 255)
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) g_instructionsText.antialias = false
global Vec2 g_playerTargetPosition = playerPos global Vec2 g_playerTargetPosition = g_screencenter
int i = 0
while i < 10 {
i += 1
print "while iter : " + i
}
} }
func Update(deltaTime) { func Update(deltaTime)
{
float fps = 1 / deltaTime float fps = 1 / deltaTime
print "FPS: " + fps g_jumpingTime += deltaTime
Printl("FPS: " + fps)
//TestInclude() //TestInclude()
//// Test automatic conversion from bool to int
//int c = GetKey("A")
//print "Test: " + c
// Shift key lets you sprint // Shift key lets you sprint
g_running = GetKey("SHIFT_L") g_running = GetKey("SHIFT_L")
if g_running == true{ if g_running == true
{
g_currPlayerSpeed = g_playerRunSpeed g_currPlayerSpeed = g_playerRunSpeed
} }
if g_running == false if g_running == false
{ {
g_currPlayerSpeed = g_playerWalkSpeed g_currPlayerSpeed = g_playerWalkSpeed
} }
// Move Left And Right // 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 if GetKey("D") == true
{ {
float newY = g_playerSprite.position.y g_playerTargetPosition.x += g_currPlayerSpeed * deltaTime
}
float newX = g_playerTargetPosition.x + g_currPlayerSpeed * deltaTime if GetKey("A") == true
g_playerTargetPosition = NVec2(newX, newY) {
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 // Finally draws all of the sprites
ZS.Graphics.Draw(g_playerSprite) ZS.Graphics.Draw(g_playerSprite)
ZS.Graphics.Draw(g_groundSprite) ZS.Graphics.Draw(g_groundSprite)
// Draw the text
ZS.Graphics.DrawText(g_instructionsText) ZS.Graphics.DrawText(g_instructionsText)
} }
func Colliding(a, b) func Colliding(a, b)
{ {
bool b = ZS.Physics.AxisAlignedCollision(a, b) bool bo = ZS.Physics.AxisAlignedCollision(a, b)
return b return bo
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

View File

@ -16,6 +16,8 @@ bool aiOn = false
// so if you never call ZS.Graphics.Init, then Start won't run // so if you never call ZS.Graphics.Init, then Start won't run
func Main() func Main()
{ {
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 Start(), then the game loop. The game loop calls Update() every frame
ZS.Graphics.Init("This is a pong game", SCREENW, SCREENH) ZS.Graphics.Init("This is a pong game", SCREENW, SCREENH)
} }
@ -39,7 +41,7 @@ func Start()
Vec2 rPaddlePosition = NVec2(rOffset, yPosPaddle) Vec2 rPaddlePosition = NVec2(rOffset, yPosPaddle)
global Vec2 rPaddleTargetPosition = 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 lPaddle = ZS.Graphics.Sprite("./square.png", lPaddlePosition, paddleScale, 0)
global Sprite rPaddle = ZS.Graphics.Sprite("./square.png", rPaddlePosition, paddleScale, 0) global Sprite rPaddle = ZS.Graphics.Sprite("./square.png", rPaddlePosition, paddleScale, 0)
@ -62,7 +64,7 @@ func Start()
func Update(deltaTime) func Update(deltaTime)
{ {
//float FPS = 1 / deltaTime //float FPS = 1 / deltaTime
//print "FPS: " + FPS //Printl("FPS: " + FPS)
// Handles Left Paddle Movement // Handles Left Paddle Movement
// //
@ -237,7 +239,7 @@ func HandleBallBounce()
difference -= ballY difference -= ballY
float paddleHeight = rPaddle.scale.y float paddleHeight = rPaddle.scale.y
float normalizedRelativeIntersectionY = difference / (paddleHeight / 2) float normalizedRelativeIntersectionY = difference / (paddleHeight / 2)
float bounceAngle = normalizedRelativeIntersectionY * 0.523599 float bounceAngle = normalizedRelativeIntersectionY * -0.523599
float ballVx = ballSpeed float ballVx = ballSpeed
ballVx *= Cos(bounceAngle) ballVx *= Cos(bounceAngle)
ballVx *= -1 ballVx *= -1