---
source: src/main.rs
expression: compiled
input_file: test-data/lua5.2-tests/code.lua
---
if T == nil {
(Message || print)('\a\n >>> testC not active: skipping opcode tests <<<\n\a');
return
}
print("testing code generation and optimizations");
{
local fn f(a) {
for k, v, w with a {
}
}
}
global fn check(f, ...) {
local arg = {
...
}
local c = T.listcode(f)
for i = 1, #arg {
assert(string.find(c[(i)], '- ' .. arg[(i)] .. ' *%d'));
}
assert(c[(#arg + 2)] == nil);
}
global fn checkequal(a, b) {
a = T.listcode(a)
b = T.listcode(b)
for i = 1, #a {
a[(i)] = string.gsub(a[(i)], '%b()', '')
b[(i)] = string.gsub(b[(i)], '%b()', '')
assert(a[(i)] == b[(i)]);
}
}
check(fn () {
(fn () {
})({
f()
});
}, 'CLOSURE', 'NEWTABLE', 'GETTABUP', 'CALL', 'SETLIST', 'CALL', 'RETURN');
check(fn () {
local a, b, c
local d
local e
local f, g, h
d = nil
d = nil
b = nil
a = nil
c = nil
}, 'LOADNIL', 'RETURN');
check(fn () {
local a, b, c, d = 1, 1, 1, 1
d = nil
c = nil
b = nil
a = nil
}, 'LOADK', 'LOADK', 'LOADK', 'LOADK', 'LOADNIL', 'RETURN');
{
local a, b, c, d = 1, 1, 1, 1
d = nil
c = nil
b = nil
a = nil
assert(a == nil && b == nil && c == nil && d == nil);
}
check(fn (a, b, c) {
return a
}, 'RETURN');
check(fn () {
while true {
local a = -1
}
}, 'LOADK', 'JMP', 'RETURN');
check(fn () {
while 1 {
local a = -1
}
}, 'LOADK', 'JMP', 'RETURN');
check(fn () {
loop {
local x = 1
} until true
}, 'LOADK', 'RETURN');
check(fn (a, b, c, d) {
return a .. b .. c .. d
}, 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN');
check(fn () {
return !!nil
}, 'LOADBOOL', 'RETURN');
check(fn () {
return !!false
}, 'LOADBOOL', 'RETURN');
check(fn () {
return !!true
}, 'LOADBOOL', 'RETURN');
check(fn () {
return !!1
}, 'LOADBOOL', 'RETURN');
check(fn () {
local a, b, c, d
a = b * 2
c[(4)], a[(b)] = -((a + d / -20.5 - a[(b)]) ^ a.x), b
}, 'LOADNIL', 'MUL', 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW', 'UNM', 'SETTABLE', 'SETTABLE', 'RETURN');
check(fn () {
local a, b
a.x = 0
a.x = b
a[(b)] = 'y'
a = 1 - a
b = 1 / a
b = 5 + 4
a[(true)] = false
}, 'LOADNIL', 'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK', 'SETTABLE', 'RETURN');
local fn f() {
return -((2 ^ 8 + -(-1)) % 8) / 2 * 4 - 3
}
check(f, 'LOADK', 'RETURN');
assert(f() == -5);
check(fn () {
return -nil
}, 'LOADNIL', 'UNM', 'RETURN');
check(fn () {
local a, b, c
b[(c)], a = c, b
b[(a)], a = c, b
a, b = c, a
a = a
}, 'LOADNIL', 'MOVE', 'MOVE', 'SETTABLE', 'MOVE', 'MOVE', 'MOVE', 'SETTABLE', 'MOVE', 'MOVE', 'MOVE', 'RETURN');
checkequal(fn () {
if (a == nil) {
a = 1
}
if a != nil {
a = 1
}
}, fn () {
if (a == 9) {
a = 1
}
if a != 9 {
a = 1
}
});
check(fn () {
if a == nil {
a = 1
}
}, 'GETTABUP', 'EQ', 'JMP', 'SETTABUP', 'RETURN');
checkequal(fn () {
local a
if !(a || b) {
b = a
}
}, fn () {
local a
if (!a && !b) {
b = a
}
});
checkequal(fn (l) {
local a
return 0 <= a && a <= l
}, fn (l) {
local a
return !(!(a >= 0) || !(a <= l))
});
check(fn (a) {
if a == 1 {
} elseif if a == 2 {
} elseif if a == 3 {
} else {
if a == 4 {
} else {
}
}
}, 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'JMP', 'RETURN');
checkequal(fn (a) {
while a < 10 {
a = a + 1
}
}, fn (a) {
if !(a < 10) {
}
a = a + 1
});
checkequal(fn (a) {
while a < 10 {
a = a + 1
}
}, fn (a) {
while true {
if !(a < 10) {
break
}
a = a + 1
}
});
print('OK');