-
Notifications
You must be signed in to change notification settings - Fork 333
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make functions a compile time construct on
@strict
(#2789)
* Don't allow overriding functions with `@strict` * Add nested function warning * Lower base op cost 5 ops on `@strict`, 8 without * Remove extra 4 ops * Add tests and fix methods
- Loading branch information
Showing
4 changed files
with
268 additions
and
13 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
data/expression2/tests/compiler/compiler/restrictions/fn_override_strict.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
## SHOULD_FAIL:COMPILE | ||
|
||
@strict | ||
|
||
function test() {} | ||
|
||
function test() {} # ERROR! |
117 changes: 117 additions & 0 deletions
117
data/expression2/tests/runtime/base/userfunctions/functions_const.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
## SHOULD_PASS:EXECUTE | ||
|
||
@strict | ||
|
||
# Ensure functions get called in the first place | ||
|
||
Called = 0 | ||
function myfunction() { | ||
Called = 1 | ||
} | ||
|
||
myfunction() | ||
|
||
assert(Called) | ||
|
||
|
||
local X = 500 | ||
local Y = 1000 | ||
local Z = 5000 | ||
|
||
# Ensure function scoping doesn't affect outer scope | ||
|
||
function test(X, Y, Z) { | ||
assert(X == 1) | ||
assert(Y == 2) | ||
assert(Z == 3) | ||
} | ||
|
||
test(1, 2, 3) | ||
|
||
assert(X == 500) | ||
assert(Y == 1000) | ||
assert(Z == 5000) | ||
|
||
# Ensure functions return properly | ||
|
||
function number returning() { | ||
return 5 | ||
} | ||
|
||
assert(returning() == 5) | ||
|
||
function number returning2(X:array) { | ||
return X[1, number] + 5 | ||
} | ||
|
||
assert(returning2(array(5)) == 10) | ||
assert(returning2(array()) == 5) | ||
|
||
function array returningref(X:array) { | ||
return X | ||
} | ||
|
||
local A = array() | ||
assert(returningref(A):id() == A:id()) | ||
|
||
function returnvoid() { | ||
if (1) { return } | ||
error("unreachable") | ||
} | ||
|
||
returnvoid() | ||
|
||
function void returnvoid2() { | ||
return | ||
} | ||
|
||
returnvoid2() | ||
|
||
function returnvoid3() { | ||
return void | ||
} | ||
|
||
returnvoid3() | ||
|
||
# Test recursion | ||
|
||
function number recurse(N:number) { | ||
if (N == 1) { | ||
return 5 | ||
} else { | ||
return recurse(N - 1) + 1 | ||
} | ||
} | ||
|
||
assert(recurse(10) == 14, recurse(10):toString()) | ||
|
||
Sentinel = -1 | ||
function recursevoid() { | ||
Sentinel++ | ||
if (Sentinel == 0) { | ||
recursevoid() | ||
} | ||
} | ||
|
||
recursevoid() | ||
|
||
assert(Sentinel == 1) | ||
|
||
function number nilInput(X, Y:ranger, Z:vector) { | ||
assert(Z == vec(1, 2, 3)) | ||
return 5 | ||
} | ||
|
||
assert( nilInput(1, noranger(), vec(1, 2, 3)) == 5 ) | ||
|
||
Ran = 0 | ||
|
||
if (0) { | ||
function constant() { | ||
Ran = 1 | ||
} | ||
} | ||
|
||
constant() | ||
|
||
assert(Ran) |
120 changes: 120 additions & 0 deletions
120
data/expression2/tests/runtime/base/userfunctions/methods_const.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
## SHOULD_PASS:EXECUTE | ||
|
||
@strict | ||
|
||
# Ensure methods get called in the first place | ||
|
||
Called = 0 | ||
function number:mymethod() { | ||
Called = 1 | ||
} | ||
|
||
1:mymethod() | ||
|
||
assert(Called) | ||
|
||
local This = 10 | ||
local X = 500 | ||
local Y = 1000 | ||
local Z = 5000 | ||
|
||
# Ensure function scoping doesn't affect outer scope | ||
|
||
function number number:method(X, Y, Z) { | ||
assert(This == 500) | ||
assert(X == 1) | ||
assert(Y == 2) | ||
assert(Z == 4) | ||
|
||
return 5 | ||
} | ||
|
||
assert( 500:method(1, 2, 4) == 5 ) | ||
|
||
assert(This == 10) | ||
assert(X == 500) | ||
assert(Y == 1000) | ||
assert(Z == 5000) | ||
|
||
# Ensure functions return properly | ||
|
||
function number number:returning() { | ||
return 5 | ||
} | ||
|
||
assert(1:returning() == 5) | ||
|
||
function number number:returning2(X:array) { | ||
return X[1, number] + 5 | ||
} | ||
|
||
assert(1:returning2(array(5)) == 10) | ||
assert(1:returning2(array()) == 5) | ||
|
||
function array number:returningref(X:array) { | ||
return X | ||
} | ||
|
||
local A = array() | ||
assert(1:returningref(A):id() == A:id()) | ||
|
||
function number:returnvoid() { | ||
if (1) { return } | ||
} | ||
|
||
1:returnvoid() | ||
|
||
function void number:returnvoid2() { | ||
return | ||
} | ||
|
||
1:returnvoid2() | ||
|
||
function number:returnvoid3() { | ||
return void | ||
} | ||
|
||
1:returnvoid3() | ||
|
||
# Test recursion | ||
|
||
function number number:recurse(N:number) { | ||
if (N == 1) { | ||
return 5 | ||
} else { | ||
return This:recurse(N - 1) + 1 | ||
} | ||
} | ||
|
||
assert(1:recurse(10) == 14, 1:recurse(10):toString()) | ||
|
||
Sentinel = -1 | ||
function number:recursevoid() { | ||
Sentinel++ | ||
if (Sentinel == 0) { | ||
This:recursevoid() | ||
} | ||
} | ||
|
||
1:recursevoid() | ||
|
||
assert(Sentinel == 1) | ||
|
||
function number number:nilInput(X, Y:ranger, Z:vector) { | ||
assert(Z == vec(1, 2, 3)) | ||
return 5 | ||
} | ||
|
||
assert( 1:nilInput(1, noranger(), vec(1, 2, 3)) == 5 ) | ||
|
||
Ran = 0 | ||
|
||
if (0) { | ||
function number:constant() { | ||
Ran = 1 | ||
} | ||
} | ||
|
||
1:constant() | ||
|
||
assert(Ran) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters