use luaify::luaify; #[test] fn raw_ident() { assert_eq!(luaify!(r#ref), r#"ref"#); assert_eq!(luaify!(x.r#ref), r#"x.ref"#); assert_eq!(luaify!(r#mut::r#ref), r#"mut.ref"#); assert_eq!(luaify!(x.r#ref()), r#"x:ref()"#); assert_eq!(luaify!(r#mut.r#ref()), r#"mut:ref()"#); assert_eq!(luaify!(r#mut::r#ref()), r#"mut.ref()"#); } #[test] fn indexing() { assert_eq!(luaify!(table.0), r#"table[0]"#); assert_eq!(luaify!(table[0]), r#"table[0]"#); assert_eq!(luaify!(table["0"]), r#"table["0"]"#); assert_eq!(luaify!(table.field), r#"table.field"#); assert_eq!(luaify!(table.field.nested), r#"table.field.nested"#); assert_eq!(luaify!(table::field.nested), r#"table.field.nested"#); assert_eq!(luaify!(table::field::nested), r#"table.field.nested"#); assert_eq!(luaify!(table::field["nested"]), r#"table.field["nested"]"#); assert_eq!(luaify!(table.0.nested), r#"table[0].nested"#); assert_eq!(luaify!(table.0["nested"]), r#"table[0]["nested"]"#); assert_eq!(luaify!(table[0].nested), r#"table[0].nested"#); assert_eq!(luaify!(table[0]["nested"]), r#"table[0]["nested"]"#); assert_eq!(luaify!(table["field"].nested), r#"table["field"].nested"#); assert_eq!(luaify!(table[field]), r#"table[field]"#); assert_eq!(luaify!(table[x.y]), r#"table[x.y]"#); assert_eq!(luaify!(table[x.1.y.2]), r#"table[x[1].y[2]]"#); assert_eq!(luaify!(table[x.1.y[2]]), r#"table[x[1].y[2]]"#); assert_eq!(luaify!(table[x[1].y.2]), r#"table[x[1].y[2]]"#); assert_eq!(luaify!(table[x[1].y[2]]), r#"table[x[1].y[2]]"#); assert_eq!(luaify!((x.y)[z.w]), r#"(x.y)[z.w]"#); assert_eq!(luaify!((x[y])[z.w]), r#"(x[y])[z.w]"#); assert_eq!(luaify!((x["y"])[z.w]), r#"(x["y"])[z.w]"#); } #[test] fn locals() { assert_eq!( luaify!(|| { let x = 30; }), r#"function()local x=30;end"# ); assert_eq!( luaify!(|| { let (x, y, z) = (1, 2, 3); }), r#"function()local x,y,z=1,2,3;end"# ); assert_eq!( luaify!(|| { let (a, b, c) = (1, call(), call2(), 4); return (a, b, c); }), r#"function()local a,b,c=1,call(),call2(),4;return a,b,c;end"# ); } #[test] fn local_fn() { assert_eq!( luaify!(|a, b| { fn inner(c: _, d: _) {} inner }), r#"function(a,b)local function inner(c,d)end;return inner;end"# ); assert_eq!( luaify!(|| { fn check(self: string, arg: number) {} inner }), r#"function()local function check(self,arg)do if type(self)=="number"then self=tostring(self);elseif type(self)~="string"then return error("string expected in \'self\', got "..type(self));end;end;do local _arg=arg;arg=tonumber(arg);if arg==nil then return error("number expected in \'arg\', got "..type(_arg));end;end;end;return inner;end"# ); } #[test] fn call() { assert_eq!(luaify!(table.field()), r#"table:field()"#); assert_eq!(luaify!(table::field()), r#"table.field()"#); assert_eq!(luaify!(table[field]()), r#"table[field]()"#); assert_eq!(luaify!(a::b.c.field()), r#"a.b.c:field()"#); assert_eq!(luaify!(a::b::c.field()), r#"a.b.c:field()"#); assert_eq!(luaify!(a::b::c::field()), r#"a.b.c.field()"#); assert_eq!( luaify!(coroutine::r#yield("string")), r#"coroutine.yield("string")"# ); assert_eq!(luaify!(call(a(), (b)(), c.d())), r#"call(a(),(b)(),c:d())"#); } #[test] fn closure() { assert_eq!(luaify!(|| hello), r#"function()return hello;end"#); assert_eq!(luaify!(|| { hello }), r#"function()return hello;end"#); assert_eq!( luaify!(|| { return hello; }), r#"function()return hello;end"# ); assert_eq!( luaify!(|| { { hello } }), r#"function()do return hello;end;end"# ); assert_eq!( luaify!(|a, b| |c, d| hello), r#"function(a,b)return function(c,d)return hello;end;end"# ); } #[test] fn labels() { assert_eq!( luaify!(|| { 'label: { break 'label; a(); b() } }), r#"function()do goto label_brk;a();return b();::label_cnt::end::label_brk::;end"# ); assert_eq!( luaify!(|| { 'label: { continue 'label; a(); b() } }), r#"function()do goto label_cnt;a();return b();::label_cnt::end::label_brk::;end"# ); } #[test] fn loops() { assert_eq!( luaify!(|| { loop { break; } }), r#"function()while true do break;end;end"# ); assert_eq!( luaify!(|| { 'label: loop { break; break 'label; continue 'label; a(); b() } }), r#"function()while true do break;goto label_brk;goto label_cnt;a();b();::label_cnt::end::label_brk::;end"# ); assert_eq!( luaify!(|| { while cond {} }), r#"function()while cond do end;end"# ); assert_eq!( luaify!(|| { 'label: while cond { continue 'label; break 'label; a(); b() } }), r#"function()while cond do goto label_cnt;goto label_brk;a();b();::label_cnt::end::label_brk::;end"# ); assert_eq!( luaify!(|| { for (k, v) in pairs(table) { print(k, v); a(); b() } }), r#"function()for k,v in pairs(table)do print(k,v);a();b();end;end"# ); assert_eq!( luaify!(|| { for i in 0..=5 { print(i) } for i in ..10 { print(i) } }), r#"function()for i=0,5 do print(i);end;for i=0,10-1 do print(i);end;end"# ); } #[test] fn type_checks() { assert_eq!(luaify!(|s| {}), r#"function(s)end"#); assert_eq!( luaify!(|s: table| {}), r#"function(s)do if type(s)~="table"then return error("table expected in \'s\', got "..type(s));end;end;end"# ); assert_eq!( luaify!(|s| { s as string }), r#"function(s)do if type(s)=="number"then s=tostring(s);elseif type(s)~="string"then return error("string expected in \'s\', got "..type(s));end;end;end"# ); assert_eq!( luaify!(|s| { s as number }), r#"function(s)do local _s=s;s=tonumber(s);if s==nil then return error("number expected in \'s\', got "..type(_s));end;end;end"# ); assert_eq!( luaify!(|s| { s as nil }), r#"function(s)do if s~=nil then return error("nil expected in \'s\', got "..type(s));end;end;end"# ); assert_eq!(luaify!(|s| { s as any }), r#"function(s)do end;end"#); assert_eq!( luaify!(|s| { let (ok, res) = coroutine::r#yield(thread); ok as boolean; res as nil; }), r#"function(s)local ok,res=coroutine.yield(thread);do if type(ok)~="boolean"then return error("boolean expected in \'ok\', got "..type(ok));end;end;do if res~=nil then return error("nil expected in \'res\', got "..type(res));end;end;end"# ); } #[test] fn concat() { assert_eq!(luaify!(concat!(a)), r#"a"#); assert_eq!(luaify!(concat!(a, b)), r#"a..b"#); assert_eq!(luaify!(concat!(a, b, c)), r#"a..b..c"#); assert_eq!( luaify!(|a, b, c| concat!(a, b, c)), r#"function(a,b,c)return a..b..c;end"# ); } #[test] fn blocks() { assert_eq!( luaify!(|| { { "result" } }), r#"function()do return"result";end;end"# ); assert_eq!( luaify!(|| { {} { "result" } }), r#"function()do end;do return"result";end;end"# ); assert_eq!( luaify!(|| { { { { "result" } } } }), r#"function()do do do return"result";end;end;end;end"# ); } #[test] fn ops() { assert_eq!(luaify!(|| a = b), r#"function()a=b;end"#); assert_eq!(luaify!(|| a + b), r#"function()return a+b;end"#); assert_eq!(luaify!(|| a += b), r#"function()a=a+b;end"#); assert_eq!(luaify!(|| a - b), r#"function()return a-b;end"#); assert_eq!(luaify!(|| a -= b), r#"function()a=a-b;end"#); assert_eq!(luaify!(|| a * b), r#"function()return a*b;end"#); assert_eq!(luaify!(|| a *= b), r#"function()a=a*b;end"#); assert_eq!(luaify!(|| a / b), r#"function()return a/b;end"#); assert_eq!(luaify!(|| a /= b), r#"function()a=a/b;end"#); assert_eq!(luaify!(|| a = b % c), r#"function()a=math.fmod(b,c);end"#); assert_eq!(luaify!(|| a = b << c), r#"function()a=bit.lshift(b,c);end"#); assert_eq!( luaify!(|| a <<= b << c), r#"function()a=bit.lshift(a,bit.lshift(b,c));end"# ); assert_eq!( luaify!(|| a = b >> c), r#"function()a=bit.arshift(b,c);end"# ); assert_eq!( luaify!(|| a >>= b >> c), r#"function()a=bit.arshift(a,bit.arshift(b,c));end"# ); assert_eq!(luaify!(|| a && b), r#"function()return a and b;end"#); assert_eq!(luaify!(|| a || b), r#"function()return a or b;end"#); assert_eq!( luaify!(|| (a && b) || c), r#"function()return(a and b)or c;end"# ); assert_eq!( luaify!(|| (a || b) && c), r#"function()return(a or b)and c;end"# ); assert_eq!( luaify!(|| a && (b || c)), r#"function()return a and(b or c);end"# ); assert_eq!( luaify!(|| a || (b && c)), r#"function()return a or(b and c);end"# ); assert_eq!( luaify!(|| -a || !--b && c >> d), r#"function()return-a or not-(-b)and bit.arshift(c,d);end"# ); assert_eq!( luaify!(|| -a || !(--b && c) >> d), r#"function()return-a or bit.arshift(not(-(-b)and c),d);end"# ); assert_eq!( luaify!(|| a >> b << c >> d), r#"function()return bit.arshift(bit.lshift(bit.arshift(a,b),c),d);end"# ); } #[test] fn ifs() { assert_eq!( luaify!(|| { if a == b { c } }), r#"function()if a==b then return c;end;end"# ); assert_eq!( luaify!(|| { if a == b { c } else { d } }), r#"function()if a==b then return c;else return d;end;end"# ); assert_eq!( luaify!(|| { if a == b { c() } else if b == c { a() } else { d() }; }), r#"function()if a==b then c();elseif b==c then a();else d();end;end"# ); assert_eq!( luaify!(|| { if a == b { c() } else if b == c { a() } else { d() } }), r#"function()if a==b then return c();elseif b==c then return a();else return d();end;end"# ); assert_eq!( luaify!(|| { if a == b { c(); } else if b == c { a() } else { d(); } }), r#"function()if a==b then c();elseif b==c then return a();else d();end;end"# ); }