Warning: session_start(): open(/var/lib/php/sessions/sess_r7ag68n5ciec94en8ntkft0269, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!include once #1034831 // Gazelle 22 Function Include for Testing
set flag PingV3.
scope test_leftArrowScript
sclass #ClassA {}
sclass #ClassB extends ClassA {}
sclass #ClassC extends ClassB {}
sclass #InheritanceDispatchTest {
static S f(ClassA a) { ret "a"; }
static S f(ClassB a) { ret "b"; }
}
sclass #Tester {
O value = "123";
sO myStaticField = "ok";
}
sclass #Sub1 {
sclass X { static int value = 1; }
}
sclass #Sub2 {
sclass X { static int value = 2; }
}
svoid test_leftArrowScript() {
test_leftArrowScript_pinging();
embedded S countLoop(int n) {
ret [[ i <- 0; while lessThan i ]] + n + [[ { i <- plus i 1 }; i ]];
}
S ifThenElseScript = [[
if lessThan a b { joinWithSpace "It's" "less" }
else if greaterThan a b { joinWithSpace "It's" "greater" }
else { joinWithSpace "They're" "equal" }
]];
testFunctionValues(script -> leftArrowVerbose((S) script),
// int primitive
[[ 5 ]], 5,
[[ -5 ]], -5,
// function definition & call
[[
def double x {
Math multiplyExact x 2
}
double 10
]], 20,
// new object with constructor arguments
[[ new Pair "hello" "world" ]], pair("hello", "world"),
// double constant
[[ str 1.5e2 ]], "150.0",
// float constant
[[ 1.5e2f ]], 150f,
// long constant
[[ 0L ]], 0L,
// hex constant
[[ 0x80 ]], 0x80,
// binary constant
[[ 0B101 ]], 0B101,
// character constant
[[ '\t' ]], '\t',
// [not implemented, too complicated]
// last = result of last statement
// [[ plus 1 2; Math addExact 5 last ]], 8,
// get static field
[[ Color black ]], Color.black,
// get instance field,
[[ tester <- new test_leftArrowScript_Tester; tester value ]], "123",
// while loop
countLoop(5), 5,
// if statement
[[ if lessThan 0 1 { "ok" } ]], "ok",
[[ if lessThan 1 0 { "ok" } ]], null,
// for each
[[ l <- ll 2 3
sum <- 0
for number in l { sum <- plus sum number }
sum
]], 5,
// for each is also map()
[[ for i in ll 2 3 { plus i 1 }
]], ll(3, 4),
// for each as nested expression
[[ joinWithSpace (for i in ll 2 3 { i }) ]], "2 3",
// for i to n
[[ for i to 2 { i }
]], ll(0, 1),
// for with byte array
[[ for b in litbytearray (toByte 5) (toByte 7) { b } ]], ll((byte) 5, (byte) 7),
// some bug
[[
img <- newImage 10 10
r <- randomRect img 10 10
]], rect(0, 0, 10, 10),
// another bug
[[
a <- 1
b <- a
a
]], 1,
// null bug
[[
a <- 1
a <- null
a
]], null,
// return at the end
[[
return 17
]], 17,
// two returns (first wins)
[[
return 13
return 22
]], 13,
// same with "ret" for "return"
[[
ret 13
ret 22
]], 13,
// conditional return
[[
if true { return "so true" }
return "oops"
]], "so true",
[[
if false { return "not true" }
return "but this"
]], "but this",
// if-then-else
[[ a <- 1; b <- 2; ]] + ifThenElseScript, "It's less",
[[ a <- 6; b <- 2; ]] + ifThenElseScript, "It's greater",
[[ a <- 5.0; b <- 5.0; ]] + ifThenElseScript, "They're equal",
// if-then-else with "then" keyword but without curly braces
[[ if true then "ok" else "not ok" ]], "ok",
[[ if false then "ok" else "not ok" ]], "not ok",
// nested expressions
[[ plus (plus 1 2) 4 ]], 7,
[[ (plus 5 6) toString ]], "11",
// nested expressions over 2 lines (it's ok to split an expression
// over multiple lines if you at least parenthesis is still open)
[[ (plus 1
(plus 2 3)) ]], 6,
// another case for nested expressions
[[ str (Color black) ]], str(Color.black),
// bug with nested for + new + linebreak + for (phew)
[[ (for y in ll 1 {
new Pair 1 2
for x in null {}
}); 0 ]], 0,
// param declares a variable
[[ param x; x ]], null,
// same with type
[[ param x : int; x ]], null,
// return with assignment
[[ return x <- 1 ]], 1,
// for pair
[[ for pair a b in ll (pair 1 2) (pair 3 4) {
plus a b
} ]], ll(3, 7),
// for key, value (map)
[[ for a, b in litorderedmap 1 2 3 4 {
plus a b
} ]], ll(3, 7),
// for index, value (list)
[[ for index i, a in ll "a" "b" {
concatStrings i a
} ]], ll("0a", "1b"),
// automatically convert int to long for method call
[[ longPlus 1 2 ]], 3L,
// same for constructors
[[ new Ratio 1 ]], Ratio(1),
// call a function from another function
[[ def f1 { 1 }
def f2 { plus (f1) 2 }
f2 ]], 3,
// return out of for loop
[[ for x in iota 2 { return x } ]], 1,
// continue loop
[[ for x in iota 2 {
if eq x 1 { continue }
return "ok"
} ]], "ok",
// new without new
[[ Pair (neg 1) (neg 2) ]], pair(-1, -2),
// variable doesn't come into scope until it's initialized
[[ neg <- neg 1; neg ]], -1,
// repeat x { ... } construct
[[ x <- 0
repeat plus 1 2 { x <- plus x 1 }
x ]], 3,
// update outer variable from function
[[ x <- 0
def incIt { outer x <- plus x 1 }
incIt
x ]], 1,
// return directly followed by }
[[ if true { return } ]], null,
// return from lambda (exits only the lambda, just like in Java)
[[ repF 2 (IF0 -> { return 1; null }) ]], ll(1, 1),
// "temp" (like in JavaX)
[[ list <- new ArrayList
{
temp tempAdd list 5
assertContains list 5
}
list
]], ll(),
// "temp" test 2 (assure it handles exceptions properly)
[[ list <- new ArrayList
pcallF (Runnable -> {
temp tempAdd list 5
fail
})
list
]], ll(),
// "temp" combined with variable declaration
[[ list <- new ArrayList
{
temp x <- tempAdd list 5
assertInstanceOf x AutoCloseable
assertContains list 5
}
list
]], ll(),
// reference to functionContainer class itself
[[ main ]], mc(),
// referencing class with full package name
[[ java.util.Arrays sort (newFloatArray 1) ]], null,
[[ new java.util.ArrayList ]], ll(),
// call method on literal
[[ "" length ]], 0,
// L or List to make a new list
[[ new List ]], ll(),
[[ new L ]], ll(),
// Map to make a new HashMap
[[ new Map ]], new Map,
// new with a variable containing a class
[[ c <- ArrayList; new c ]], ll(),
[[ new Var, getClass ]], Var.class,
shortName(InheritanceDispatchTest) + " f (new " + shortName(ClassC) + ")", "b",
[[
sleepSeconds 0
sleepSeconds 0
]], null,
// variable declaration with type
[[ a : S <- "s"; a ]], "s",
// try/finally
[[
a <- 0
try {
try { a <- plus a 1 } finally { a <- plus a 2 }
try { fail } finally { a <- plus a 3 }
} catch e {}
a
]], 6,
// function definition with explicit parameter type
[[
def f x: int {
plus x 1
}
f 5
]], 6,
// param with nested parameterized type
[[
param x : L>
]], null,
// +id shortcut
[[ x <- 5; ll +x ]], ll(x := 5),
// unclosed multi-line string
"splitAtSpace [[a b", ll("a", "b"),
"splitAtSpace [=[c d", ll("c", "d"),
// list { }
[[ list {
plus 1 2
minus 8 4
} ]], ll(3, 4),
// same in one line with semicolons
[[ list { plus 1 2; minus 8 4 } ]], ll(3, 4),
// parsing bug
[[ for x in ll
1 { x } ]], ll(1),
// will return
[[ data <- new Var
will return data get
data set 1 ]], 1,
// recursive script-defined function
[[ def myFactorial n {
if n lessThan 2
{ 1 }
else { myFactorial (n minus 1), mul n }
}
myFactorial 5
]], 120,
// add simple tests here
);
// get reference to current var context with _context
new GazelleV_LeftArrowScriptParser parser;
enableScaffolding(parser);
parser.allowTheWorld();
new FlexibleVarContext ctx;
assertSame(ctx, parser.parse("_context").get(ctx));
test_leftArrowScriptParseErrors();
test_leftArrowScript_lambdas();
test_leftArrowScript_binaryOperators();
test_leftArrowScriptCompileErrors();
// get static field in functionContainer
parser = new GazelleV_LeftArrowScriptParser;
parser.allowTheWorld(Tester, mc());
assertEqualsVerbose("ok", parser.parse("myStaticField")!);
assertEqualsVerbose("ko", parser.parse("reversed myStaticField")!);
assertEqualsVerbose(2, parser.parse("myStaticField length")!);
test_leftArrowScript_classDefs();
test_leftArrowScript_forIterator();
var exception = leftArrowVerbose([[
try { throw new RuntimeException } catch e { e }
]]);
assertEqualsVerbose(exception.getClass(), RuntimeException.class);
// trying to get non-existant field/method on object
assertFailVerbose(-> leftArrowVerbose([[ "" lengthX ]]));
// make sure fields local to function are not visible outside
assertFailVerbose(-> leftArrowParse([[ def x { y <- 1 } y ]]));
test_leftArrowScript_comma();
test_leftArrowScript_antiComma();
// test priority of class resolution
parser = new GazelleV_LeftArrowScriptParser;
enableScaffolding(parser);
parser.allowTheWorld(Sub1.class, Sub2.class);
assertEqualsVerbose(1, parser.parse("X value")!);
parser = new GazelleV_LeftArrowScriptParser;
enableScaffolding(parser);
parser.allowTheWorld(Sub2.class, Sub1.class);
assertEqualsVerbose(2, parser.parse("X value")!);
test_leftArrowScript_returnValueNotNeededOptimization();
// test addClassAlias
parser = new GazelleV_LeftArrowScriptParser;
parser.allowTheWorld();
parser.addClassAlias("Paar", "Pair");
assertEqualsVerbose(pair(1, 2), parser.parse("new Paar 1 2")!);
// test that params are stored in parsed script
var script = leftArrowParseVerbose("param x : int");
assertEqualsVerbose(1, l(script.params));
assertEqualsVerbose("x", firstKey(script.params));
assertEqualsVerbose(int.class, firstValue(script.params).javaClass());
// +id shortcut doesn't work with a space
assertFailVerbose(-> leftArrowParseVerbose([[ x <- 5; ll + x ]]));
test_leftArrowScript_magicSwitch();
test_leftArrowScript_tilde();
test_leftArrowScript_then();
assertInstanceOf IF0(leftArrowVerbose([[ abcd <- IF0 {}; abcd ]]));
// add tests here
print("All left-arrow script tests OK!");
}