--- source: src/main.rs assertion_line: 136 expression: compiled input_file: test-data/lua5.4-tests/constructs.lua --- print("testing syntax"); local debug = require("debug") local fn checkload(s, msg) { assert(string.find(select(2, load(s)), msg)); } { } { a = 3 assert(a == 3); } if false { a = 3 /_ 0 a = 0 % 0 } assert(2 ^ 3 ^ 2 == 2 ^ (3 ^ 2)); assert(2 ^ 3 * 4 == (2 ^ 3) * 4); assert(2.0 ^ -2 == 1 / 4 && -2 ^ - - 2 == - - -4); assert(!nil && 2 && !(2 > 3 || 3 < 2)); assert(-3 - 1 - 5 == 0 + 0 - 9); assert(-2 ^ 2 == -4 && (-2) ^ 2 == 4 && 2 * 2 - 3 - 1 == 0); assert(-3 % 5 == 2 && -3 + 5 == 2); assert(2 * 1 + 3 / 3 == 3 && 1 + 2 .. 3 * 1 == "33"); assert(!(2 + 1 > 3 * 1) && "a" .. "b" > "a"); assert(0xF0 | 0xCC ^^ 0xAA & 0xFD == 0xF4); assert(0xFD & 0xAA ^^ 0xCC | 0xF0 == 0xF4); assert(0xF0 & 0x0F + 1 == 0x10); assert(3 ^ 4 /_ 2 ^ 3 /_ 5 == 2); assert(-3 + 4 * 5 /_ 2 ^ 3 ^ 2 /_ 9 + 4 % 10 / 3 == (-3) + (((4 * 5) /_ (2 ^ (3 ^ 2))) /_ 9) + ((4 % 10) / 3)); assert(!((true || false) && nil)); assert(true || false && nil); assert((((1 || false) && true) || false) == true); assert((((nil && true) || false) && true) == false); local a, b = 1, nil assert(-(1 || 2) == -1 && (1 && 2) + (-1.25 || -4) == 0.75); x = ((b || a) + 1 == 2 && (10 || a) + 1 == 11) assert(x); x = (((2 < 3) || 1) == true && (2 < 3 && 4) == 4) assert(x); x, y = 1, 2 assert((x > y) && x || y == 2); x, y = 2, 1 assert((x > y) && x || y == 2); assert(1234567890 == tonumber('1234567890') && 1234567890 + 1 == 1234567891); { local operand = { 3, 100, 5.0, -10, -5.0, 10000, -10000 } local operator = { "+", "-", "*", "/", "//", "%", "^", "&", "|", "^", "<<", ">>", "==", "~=", "<", ">", "<=", ">=" } for _, op with ipairs(operator) { local f = assert(load(string.format(`return function (x,y) return x %s y end`, op)))() for _, o1 with ipairs(operand) { for _, o2 with ipairs(operand) { local gab = f(o1, o2) _ENV.XX = o1 code = string.format("return XX %s %s", op, o2) res = assert(load(code))() assert(res == gab); _ENV.XX = o2 local code = string.format("return (%s) %s XX", o1, op) local res = assert(load(code))() assert(res == gab); code = string.format("return (%s) %s %s", o1, op, o2) res = assert(load(code))() assert(res == gab); } } } } loop { } until 1 loop { } until true while false { } while nil { } { local a global fn f(x) { x = { a = 1 } x = { x = 1 } x = { G = 1 } } } global fn f(i) { if type(i) != 'number' { return i, 'jojo' } if i > 0 { return i, f(i - 1) } } x = { f(3), f(5), f(10) } assert(x[(1)] == 3 && x[(2)] == 5 && x[(3)] == 10 && x[(4)] == 9 && x[(12)] == 1); assert(x[(nil)] == nil); x = { f('alo'), f('xixi'), nil } assert(x[(1)] == 'alo' && x[(2)] == 'xixi' && x[(3)] == nil); x = { f('alo') .. 'xixi' } assert(x[(1)] == 'aloxixi'); x = { f({}) } assert(x[(2)] == 'jojo' && type(x[(1)]) == 'table'); local f = fn (i) { if i < 10 { return 'a' } elseif if i < 20 { return 'b' } elseif if i < 30 { return 'c' } } assert(f(3) == 'a' && f(12) == 'b' && f(26) == 'c' && f(100) == nil); for i = 1, 1000 { break } n = 100 i = 3 t = {} a = nil while !a { a = 0 for i = 1, n { for i = i, 1, -1 { a = a + 1 t[(i)] = 1 } } } assert(a == n * (n + 1) / 2 && i == 3); assert(t[(1)] && t[(n)] && !t[(0)] && !t[(n + 1)]); global fn f(b) { local x = 1 loop { local a if b == 1 { local b = 1 x = 10 break } elseif if b == 2 { x = 20 break } elseif if b == 3 { x = 30 } else { local a, b, c, d = math.sin(1) x = x + 1 } } until x >= 12 return x } assert(f(1) == 10 && f(2) == 20 && f(3) == 30 && f(4) == 12); local f = fn (i) { if i < 10 { return 'a' } elseif if i < 20 { return 'b' } elseif if i < 30 { return 'c' } else { return 8 } } assert(f(3) == 'a' && f(12) == 'b' && f(26) == 'c' && f(100) == 8); local a, b = nil, 23 x = { f(100) * 2 + 3 || a, a || b + 2 } assert(x[(1)] == 19 && x[(2)] == 25); x = { f = 2 + 3 || a, a = b + 2 } assert(x.f == 5 && x.a == 25); a = { y = 1 } x = { a.y } assert(x[(1)] == 1); global fn f(i) { while 1 { if i > 0 { i = i - 1 } else { return } } } global fn g(i) { while 1 { if i > 0 { i = i - 1 } else { return } } } f(10); g(10); { global fn f() { return 1, 2, 3 } local a, b, c = f() assert(a == 1 && b == 2 && c == 3); a, b, c = (f()) assert(a == 1 && b == nil && c == nil); } local a, b = 3 && f() assert(a == 1 && b == nil); global fn g() { f(); return } assert(g() == nil); global fn g() { return nil || f() } a, b = g() assert(a == 1 && b == nil); print('+'); { local prog = `local x = 10` checkload(prog, "unknown attribute 'XXX'"); checkload(`local xxx = 20; xxx = 10`, ":1: attempt to assign to const variable 'xxx'"); checkload(` local xx; local xxx = 20; local yyy; local function foo () local abc = xx + yyy + xxx; return function () return function () xxx = yyy end end end `, ":6: attempt to assign to const variable 'xxx'"); checkload(` local x = nil x = io.open() `, ":2: attempt to assign to const variable 'x'"); } f = ` return function ( a , b , c , d , e ) local x = a >= b or c or ( d and e ) or nil return x end , { a = 1 , b = 2 >= 1 , } or { 1 }; ` f = string.gsub(f, "%s+", "\n") f, a = load(f)() assert(a.a == 1 && a.b); global fn g(a, b, c, d, e) { if !(a >= b || c || d && e || nil) { return 0 } else { return 1 } } global fn h(a, b, c, d, e) { while (a >= b || c || (d && e) || nil) { return 1 } return 0 } assert(f(2, 1) == true && g(2, 1) == 1 && h(2, 1) == 1); assert(f(1, 2, 'a') == 'a' && g(1, 2, 'a') == 1 && h(1, 2, 'a') == 1); assert(f(1, 2, 'a') != nil, ""); assert(f(1, 2, 'a') == 'a' && g(1, 2, 'a') == 1 && h(1, 2, 'a') == 1); assert(f(1, 2, nil, 1, 'x') == 'x' && g(1, 2, nil, 1, 'x') == 1 && h(1, 2, nil, 1, 'x') == 1); assert(f(1, 2, nil, nil, 'x') == nil && g(1, 2, nil, nil, 'x') == 0 && h(1, 2, nil, nil, 'x') == 0); assert(f(1, 2, nil, 1, nil) == nil && g(1, 2, nil, 1, nil) == 0 && h(1, 2, nil, 1, nil) == 0); assert(1 && 2 < 3 == true && 2 < 3 && 'a' < 'b' == true); x = 2 < 3 && !3 assert(x == false); x = 2 < 1 || (2 > 1 && 'a') assert(x == 'a'); { local a if nil { a = 1 } else { a = 2 } assert(a == 2); } global fn F(a) { assert(debug.getinfo(1, "n").name == 'F'); return a, 2, 3 } a, b = F(1) != nil assert(a == true && b == nil); a, b = F(nil) == nil assert(a == true && b == nil); _ENV.GLOB1 = math.random(0, 1) local basiccases = { { "nil", nil }, { "false", false }, { "true", true }, { "10", 10 }, { "(0==_ENV.GLOB1)", 0 == _ENV.GLOB1 } } local prog if _ENV.GLOB1 == 0 { basiccases[(2)][(1)] = "F" prog = ` local F = false if %s then IX = true end return %s ` } else { basiccases[(4)][(1)] = "k10" prog = ` local k10 = 10 if %s then IX = true end return %s ` } print('testing short-circuit optimizations (' .. _ENV.GLOB1 .. ')'); local binops = { { " and ", fn (a, b) { if !a { return a } else { return b } } }, { " or ", fn (a, b) { if a { return a } else { return b } } } } local cases = {} local fn createcases(n) { local res = {} for i = 1, n - 1 { for _, v1 with ipairs(cases[(i)]) { for _, v2 with ipairs(cases[(n - i)]) { for _, op with ipairs(binops) { local t = { "(" .. v1[(1)] .. op[(1)] .. v2[(1)] .. ")", op[(2)](v1[(2)], v2[(2)]) } res[(#res + 1)] = t res[(#res + 1)] = { "not" .. t[(1)], !t[(2)] } } } } } return res } local level = _soft && 3 || 4 cases[(1)] = basiccases for i = 2, level { cases[(i)] = createcases(i) } print("+"); local i = 0 for n = 1, level { for _, v with pairs(cases[(n)]) { local s = v[(1)] local p = load(string.format(prog, s, s), "") IX = false assert(p() == v[(2)] && IX == !!v[(2)]); i = i + 1 if i % 60000 == 0 { print('+'); } } } checkload("for x do", "expected"); checkload("x:call", "expected"); print('OK');