Skip to content

Commit

Permalink
Merge pull request #15 from brwhale/feature/EarlyReturn
Browse files Browse the repository at this point in the history
Fix bug with if with no else clause eating the rest of the function a…
  • Loading branch information
brwhale authored May 2, 2023
2 parents 02242ef + ad94097 commit b8224e6
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/Library/KataScript.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ namespace KataScript {
bool lastStatementClosedScope = false;
bool lastStatementWasElse = false;
bool lastTokenEndCurlBraket = false;
bool lastStatementWasIf = false;
uint64_t currentLine = 0;
ParseState prevState = ParseState::beginExpression;
ModulePrivilegeFlags allowedModulePrivileges;
Expand Down
19 changes: 16 additions & 3 deletions src/Library/parsing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,11 +530,22 @@ namespace KataScript {
auto tempState = parseState;
switch (parseState) {
case ParseState::beginExpression:
{
{
if (lastTokenEndCurlBraket && lastStatementWasIf) {
if (token != ";" && token != "}" && token != "else") {
lastStatementWasIf = false;
parse(";");
parse(token);
return;
}
}

bool wasElse = false;
bool closedScope = false;
bool closedExpr = false;
bool isEndCurlBracket = false;
lastStatementWasIf = false;

if (token == "fn" || token == "func" || token == "function") {
parseState = ParseState::defineFunc;
} else if (token == "var") {
Expand Down Expand Up @@ -576,10 +587,11 @@ namespace KataScript {
clearParseStacks();
} else if (token == "}") {
wasElse = !currentExpression || currentExpression->type != ExpressionType::IfElse;
lastStatementWasIf = currentExpression && currentExpression->type == ExpressionType::IfElse;
bool wasFreefunc = !currentExpression || (currentExpression->type == ExpressionType::FunctionDef
&& get<FunctionExpression>(currentExpression->expression).function->getFunction()->type == FunctionType::free);
closedExpr = closeCurrentExpression();
if (!closedExpr && wasFreefunc || parseScope->name == "__anon") {
if (!closedExpr && (wasFreefunc || parseScope->name == "__anon")) {
closeScope(parseScope);
}
closedScope = true;
Expand All @@ -598,8 +610,9 @@ namespace KataScript {
}
if (!closedExpr && (closedScope && lastStatementClosedScope || (!lastStatementWasElse && !wasElse && lastTokenEndCurlBraket))) {
bool wasIfExpr = currentExpression && currentExpression->type == ExpressionType::IfElse;
auto oldExpr = &currentExpression;
closeDanglingIfExpression();
if (closedScope && wasIfExpr && currentExpression->type != ExpressionType::IfElse) {
if (closedScope && wasIfExpr && &currentExpression == oldExpr) {
closeCurrentExpression();
closedScope = false;
}
Expand Down
17 changes: 17 additions & 0 deletions src/Tests/KataScriptTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1909,6 +1909,23 @@ namespace KataScriptTests {
Assert::AreEqual(KataScript::Type::Int, val->getType());
Assert::AreEqual(KataScript::Int(2), val->getInt());
}

TEST_METHOD(CatchUnElsedIfBeforeForeach) {
interpreter.evaluate(
"var statsDict = dictionary();"s +
"fn testfunc(Name) {" +
"statsDict[Name] = 3;" +
"var allComplete = true;" +
"if (allComplete) { statsDict[Name] = 4; }" +
"foreach (stat; statsDict) { if (stat > 3) {allComplete = false; } }" +
"if (allComplete) { return 7; } else { return 8; }" +
"} var j = testfunc(\"test\");"s
);

auto val = interpreter.resolveVariable("j"s);
Assert::AreEqual(KataScript::Type::Int, val->getType());
Assert::AreEqual(KataScript::Int(8), val->getInt());
}

// todo add more tests

Expand Down

0 comments on commit b8224e6

Please sign in to comment.