Allow including other .ZS files in order to import other functions and variables

This commit is contained in:
sam-astro 2022-05-22 13:06:02 -04:00
parent 575195930b
commit cefbbd140b
5 changed files with 99 additions and 44 deletions

View File

@ -139,7 +139,7 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
// If no operations are applied, then return self
if ((countOutsideParenthesis(expression, '+') == 0 && countOutsideParenthesis(expression, '-') == 0 && countOutsideParenthesis(expression, '*') == 0 && countOutsideParenthesis(expression, '/') == 0 && countOutsideParenthesis(expression, '^') == 0) || split(expression, '.')[0] == "ZS")
{
bool isFunc = IsFunction(split(expression, '(')[0]);
//bool isFunc = IsFunction(split(expression, '(')[0]);
if (isFunc && !inQuotes)
{
//cout << split(expression, '(')[0] << endl;
@ -148,12 +148,11 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
while (y < expression.size() && expression[y] != ')')
{
argContents += expression[y];
y++;
}
return ExecuteFunction(split(expression, '(')[0], VarValues(split(argContents, ','), variableValues));
}
else if (split(expression, '.')[0] == "ZS" && !inQuotes)
else if (isZS && !inQuotes)
{
string argContents = "";
int y = indexInStr(expression, '(') + 1;
@ -177,11 +176,11 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
if (expression[i] == '\"' && !isEscaped(newExpression, i))
inQuotes = !inQuotes;
if (isalpha(expression[i]))
if (isalpha(expression[i]) || expression[i] == '_')
{
string name = "";
while (i < expression.size() && (isalpha(expression[i]) || expression[i] == '.'))
while (i < expression.size() && (isalpha(expression[i]) || expression[i] == '.' || expression[i] == '_'))
{
name += expression[i];
i++;
@ -426,7 +425,7 @@ boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unorder
return nullType;
}
// Check existing variables: To see if accessign class sub component
// Check existing variables: To see if accessing class sub component
else if (count(words.at(lineNum).at(0), '.') > 0 && IsVar(split(words.at(lineNum).at(0), '.')[0], variableValues) || IsVar(split(words.at(lineNum).at(0), '.')[0], globalVariableValues))
{
if (IsVar(split(words.at(lineNum).at(0), '.')[0], variableValues))
@ -582,7 +581,7 @@ boost::any ExecuteFunction(const string& functionName, const vector<boost::any>&
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
#if DEVELOPER_MESSAGES
InterpreterLog("Contents:\n" + script);
#endif
@ -631,7 +630,37 @@ int parseZSharp(string script)
}
else
{
if (words.at(lineNum).at(0) == "string") {
if (words.at(lineNum).at(0) == "include")
{
string scriptPath = StringRaw(words.at(lineNum).at(1));
string scriptTextContents;
#if DEVELOPER_MESSAGES == true
InterpreterLog("Including from " + words.at(lineNum).at(1) + "...");
#endif
#if UNIX
// Get script contents as single string
auto ss = ostringstream{};
ifstream input_file(scriptPath);
ss << input_file.rdbuf();
scriptTextContents = ss.str();
#if DEVELOPER_MESSAGES
InterpreterLog("Gather script contents...");
#endif
#elif WINDOWS
// Get script contents as single string
ifstream script(scriptPath);
stringstream scriptString;
scriptString << script.rdbuf();
scriptTextContents = scriptString.str();
#if DEVELOPER_MESSAGES
InterpreterLog("Gather script contents...");
#endif
#endif
parseZSharp(scriptTextContents);
}
else if (words.at(lineNum).at(0) == "string") {
globalVariableValues[words.at(lineNum).at(1)] = StringRaw(words.at(lineNum).at(3));
#if DEVELOPER_MESSAGES == true
InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "...");
@ -660,12 +689,6 @@ int parseZSharp(string script)
}
}
#if DEVELOPER_MESSAGES
InterpreterLog("Start Main()");
#endif
// Executes main, which is the entry point function
ExecuteFunction("Main", vector<boost::any> {});
return 0;
}
@ -703,8 +726,8 @@ int main(int argc, char* argv[])
scriptTextContents = ss.str();
#if DEVELOPER_MESSAGES
InterpreterLog("Gather script contents...");
#endif
#endif
// Change the current working directory to that of the script
chdir(projectDirectory.c_str());
#if DEVELOPER_MESSAGES
@ -722,8 +745,8 @@ int main(int argc, char* argv[])
scriptTextContents = scriptString.str();
#if DEVELOPER_MESSAGES
InterpreterLog("Gather script contents...");
#endif
#endif
// Change the current working directory to that of the script
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wide = converter.from_bytes(projectDirectory);
@ -742,30 +765,41 @@ int main(int argc, char* argv[])
exit(1);
}
#if DEVELOPER_MESSAGES
#if DEVELOPER_MESSAGES
InterpreterLog("Parsing...");
#endif
// Start running the script
#endif
// Parse the script
parseZSharp(scriptTextContents);
#if DEVELOPER_MESSAGES
InterpreterLog("Start Main()");
#endif
try
{
// Executes main, which is the entry point function
ExecuteFunction("Main", vector<boost::any> {});
}
catch (const std::exception&)
{
//Failed with error
}
// Entire script has been run, exit.
#if DEVELOPER_MESSAGES // If built with developer messages, then verify exit
cout << "Press Enter to Continue";
cin.ignore();
exit(1);
#else
if(argc > 2)
if (argc > 2)
{
string a = argv[2];
std::transform(a.begin(), a.end(), a.begin(),
[](unsigned char c){ return std::tolower(c); });
if(a == "-ve") // If the '-ve' (verify exit) option is used, ask for verification on exit
[](unsigned char c) { return std::tolower(c); });
if (a == "-ve") // If the '-ve' (verify exit) option is used, ask for verification on exit
{
cout << "Press Enter to Continue";
cin.ignore();
exit(1);
exit(1);
}
}
#endif // Else exit automatically

Binary file not shown.

View File

@ -0,0 +1,5 @@
func TestInclude()
{
print "Hello World!"
}

View File

@ -1,11 +1,17 @@
int g_screenw = 900
int g_screenh = 600
float g_playerMoveSpeed = 400
float g_playerWalkSpeed = 400
float g_playerRunSpeed = 700
float g_jumpHeight = 20
float g_currPlayerSpeed = 400
bool g_running = false
float g_gravitySpeed = -86
include "./extra-include.zs"
func Main()
{
// Immediately creates the window, then Start(), then the game loop. The game loop calls Update() every frame
@ -18,11 +24,11 @@ func Start()
float centerY = g_screenh / 2
global Vec2 g_screencenter = NVec2(centerX, centerY)
Vec2 playerPos = NVec2(0, 0)
Vec2 playerScale = NVec2(16, 16)
Vec2 playerPos = g_screencenter
Vec2 playerScale = NVec2(40, 40)
global Sprite g_playerSprite = ZS.Graphics.Sprite("./square.png", playerPos, playerScale, 0)
Vec2 groundPos = NVec2(0, -17)
Vec2 groundPos = NVec2(g_screencenter.x, 500)
Vec2 groundScale = NVec2(256, 16)
global Sprite g_groundSprite = ZS.Graphics.Sprite("./square.png", groundPos, groundScale, 0)
@ -36,42 +42,52 @@ func Update(deltaTime)
{
float fps = 1 / deltaTime
print "FPS: " + fps
TestInclude()
// Test automatic conversion from bool to int
int c = 0 + GetKey("A")
print "Test: " + 0 + c
//// 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
{
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_playerMoveSpeed * deltaTime
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_playerMoveSpeed * deltaTime
float newX = g_playerTargetPosition.x + g_currPlayerSpeed * deltaTime
g_playerTargetPosition = NVec2(newX, newY)
}
// Lerps from old position to destination smoothly
float oldX = g_playerSprite.position.x
float newX = g_playerTargetPosition.x
float stopSpeed = deltaTime * lerpSpeed
float stopSpeed = deltaTime * 7
float lerpedX = Lerp(oldX, newX, stopSpeed)
g_playerSprite.position = NVec2(lerpedX, newY)
// Finally draws all of the sprites
ZS.Graphics.Draw(playerSprite)
ZS.Graphics.Draw(groundSprite)
ZS.Graphics.Draw(g_playerSprite)
ZS.Graphics.Draw(g_groundSprite)
ZS.Graphics.DrawText(instructionsText)
HandleBallBounce()
ZS.Graphics.DrawText(g_instructionsText)
}
func Colliding(a, b)

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 B