Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Now the comment that claims function scope is
only global at file scope is actually telling the truth!

(The code contained a comment that described the correct
behaviour, but the code itself didn't actually implement
what the comment said it was doing.)
  • Loading branch information
Dunbaratu committed Dec 28, 2017
1 parent f4b9a89 commit 3ab9230
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 5 deletions.
14 changes: 14 additions & 0 deletions kerboscript_tests/user_functions/functest29.ks
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
print "Testing default function scoping rules".

run once "functest29_lib.ks".

print "Should say Func1: " + func1().
if (func1() <> "Func1") print "!!!!!!!!!! ERROR ERROR ERROR !!!!!!!!!!!" + char(7) + char(7).
local f2 is getfunc2().
print "Should say Func2: " + f2().
if (f2() <> "Func2") print "!!!!!!!!!! ERROR ERROR ERROR !!!!!!!!!!!" + char(7) + char(7).

local f3 is getfunc3().
print "Should say Func3: " + f3().
if (f3() <> "Func3") print "!!!!!!!!!! ERROR ERROR ERROR !!!!!!!!!!!" + char(7) + char(7).

17 changes: 17 additions & 0 deletions kerboscript_tests/user_functions/functest29_lib.ks
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
function func1 {
return "Func1".
}

function getfunc2 {
function sameName { // <--------+--- These two innner functions have the same name
return "Func2". // <-----+--|--- But have different effects when called.
} // | |
return sameName@. // <--+--|--|--- These should return the 2 different versions.
} // | | |
// | | |
function getfunc3 { // | | |
function sameName { // <--|--|--'
return "Func3". // <--|--'
} // |
return sameName@. // <--'
} //
17 changes: 17 additions & 0 deletions kerboscript_tests/user_functions/functest30.ks
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
print "Testing explicit function scope keywords override.".

run once "functest30_lib.ks".
local del is outer().

print "Should say global1: " + global1().
if (global1() <> "global1") print "!!!!!!!!!! ERROR ERRROR !!!!!!!!!!" + char(7) + char (7).
print "Should say global2: " + global2().
if (global2() <> "global2") print "!!!!!!!!!! ERROR ERRROR !!!!!!!!!!" + char(7) + char (7).
print "Should say global3: " + global3().
if (global3() <> "global3") print "!!!!!!!!!! ERROR ERRROR !!!!!!!!!!" + char(7) + char (7).
print "Should say local2: " + del().
if (del() <> "local2") print "!!!!!!!!!! ERROR ERRROR !!!!!!!!!!" + char(7) + char (7).

print " ".
print "PROGRAM SHOULD NOW FAIL WITH 'local1' NOT FOUND.".
print local1().
11 changes: 11 additions & 0 deletions kerboscript_tests/user_functions/functest30_lib.ks
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
global function global1 { return "global1". }
function global2 { return "global2". }
local function local1 { return "local1". }

function outer {
function local2 { return "local2". } // local by default
global function global3 { return "global3". } // explicit global keyword despite being nested
function local1 { return local2(). } // Note this local1 should mask the outer local1

return local1@. // via this delegate, it actually will call local2().
}
16 changes: 11 additions & 5 deletions src/kOS.Safe/Compilation/KS/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2775,14 +2775,21 @@ private StorageModifier GetStorageModifierForDeclare(ParseNode node)
ParseNode lastSubNode = node.Nodes[node.Nodes.Count-1];

// Default varies depending on which kind of statement it is.
// locks are default global, and functions declared at file
// scope are default global, while everything else is default local:
StorageModifier modifier = StorageModifier.LOCAL;
if (lastSubNode.Token.Type == TokenType.declare_lock_clause ||
lastSubNode.Token.Type == TokenType.declare_function_clause)
// locks are default global:
if (lastSubNode.Token.Type == TokenType.declare_lock_clause)
{
modifier = StorageModifier.GLOBAL;
}
// functions declared at file scope are default global. inner functions are default local:
else if (lastSubNode.Token.Type == TokenType.declare_function_clause)
{
ParseNode containingNode = GetContainingBlockNode(node);
if (containingNode != null && containingNode.Token.Type == TokenType.Start) // file scope
modifier = StorageModifier.GLOBAL;
else
modifier = StorageModifier.LOCAL;
}

bool storageKeywordMissing = true;

Expand Down Expand Up @@ -2817,7 +2824,6 @@ private StorageModifier GetStorageModifierForDeclare(ParseNode node)
LineCol location = GetLineCol(node);
throw new KOSCommandInvalidHereException(location, "GLOBAL", "in a parameter declaration", "in a variable declaration");
}

return modifier;
}

Expand Down

0 comments on commit 3ab9230

Please sign in to comment.