Skip to content

Commit cfc2606

Browse files
committed
add lua binaries, fix outstanding lua issues
1 parent 009be45 commit cfc2606

8 files changed

Lines changed: 187 additions & 11 deletions

File tree

.github/workflows/build.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ jobs:
8484
shell: bash
8585
run: ./gradlew packageSlimCompilerDist --no-daemon --stacktrace
8686

87+
- name: Prepare bundled Lua runtime (Linux)
88+
if: runner.os == 'Linux'
89+
shell: bash
90+
run: |
91+
if [[ -f src/test/resources/lua53 ]]; then
92+
chmod +x src/test/resources/lua53
93+
fi
94+
8795
- name: Run tests
8896
shell: bash
8997
run: ./gradlew test --no-daemon --stacktrace

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/lua/translation/LuaNatives.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ public class LuaNatives {
5050

5151
addNative(Collections.singletonList("S2I"), f -> {
5252
f.getParams().add(LuaAst.LuaVariable("x", LuaAst.LuaNoExpr()));
53-
f.getBody().add(LuaAst.LuaLiteral("return tonumber(x)"));
53+
f.getBody().add(LuaAst.LuaLiteral("local m = string.match(tostring(x), \"^[%+%-]?%d+\")"));
54+
f.getBody().add(LuaAst.LuaLiteral("if m then return tonumber(m) else return 0 end"));
5455
});
5556

5657
addNative("Player", f -> {
@@ -63,7 +64,11 @@ public class LuaNatives {
6364
f.getBody().add(LuaAst.LuaLiteral("return x.id"));
6465
});
6566

66-
addNative("GetRandomReal", f -> f.getBody().add(LuaAst.LuaLiteral("return math.random")));
67+
addNative("GetRandomReal", f -> {
68+
f.getParams().add(LuaAst.LuaVariable("l", LuaAst.LuaNoExpr()));
69+
f.getParams().add(LuaAst.LuaVariable("h", LuaAst.LuaNoExpr()));
70+
f.getBody().add(LuaAst.LuaLiteral("return l + math.random() * (h - l)"));
71+
});
6772

6873
addNative("GetRandomInt", f -> {
6974
f.getParams().add(LuaAst.LuaVariable("l", LuaAst.LuaNoExpr()));
@@ -90,11 +95,12 @@ public class LuaNatives {
9095
addNative("TriggerEvaluate", f -> {
9196
f.getParams().add(LuaAst.LuaVariable("t", LuaAst.LuaNoExpr()));
9297
f.getBody().add(LuaAst.LuaLiteral("for i,a in ipairs(t.actions) do a() end"));
98+
f.getBody().add(LuaAst.LuaLiteral("return true"));
9399
});
94100

95101
addNative("R2I", f -> {
96102
f.getParams().add(LuaAst.LuaVariable("x", LuaAst.LuaNoExpr()));
97-
f.getBody().add(LuaAst.LuaLiteral("return math.floor(x)"));
103+
f.getBody().add(LuaAst.LuaLiteral("return math.modf(x)"));
98104
});
99105

100106
addNative("InitHashtable", f -> f.getBody().add(LuaAst.LuaLiteral("return {}")));
@@ -114,6 +120,25 @@ public class LuaNatives {
114120
f.getBody().add(LuaAst.LuaLiteral("if not h[p] then return nil end return h[p][c]"));
115121
});
116122

123+
addNative("typeIdToTypeName", f -> {
124+
f.getParams().add(LuaAst.LuaVariable("typeId", LuaAst.LuaNoExpr()));
125+
f.getBody().add(LuaAst.LuaLiteral("return \"\""));
126+
});
127+
128+
addNative("maxTypeId", f -> {
129+
f.getBody().add(LuaAst.LuaLiteral("return 0"));
130+
});
131+
132+
addNative("instanceCount", f -> {
133+
f.getParams().add(LuaAst.LuaVariable("typeId", LuaAst.LuaNoExpr()));
134+
f.getBody().add(LuaAst.LuaLiteral("return 0"));
135+
});
136+
137+
addNative("maxInstanceCount", f -> {
138+
f.getParams().add(LuaAst.LuaVariable("typeId", LuaAst.LuaNoExpr()));
139+
f.getBody().add(LuaAst.LuaLiteral("return 0"));
140+
});
141+
117142
}
118143

119144
private static void addNative(String name, Consumer<LuaFunction> g) {

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/lua/translation/LuaTranslator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ public LuaMethod initFor(ImClass a) {
126126

127127
LuaFunction stringConcatFunction = LuaAst.LuaFunction(uniqueName("stringConcat"), LuaAst.LuaParams(), LuaAst.LuaStatements());
128128

129-
LuaFunction toIndexFunction = LuaAst.LuaFunction(uniqueName("objectToIndex"), LuaAst.LuaParams(), LuaAst.LuaStatements());
129+
LuaFunction toIndexFunction = LuaAst.LuaFunction(uniqueName("__wurst_objectToIndex"), LuaAst.LuaParams(), LuaAst.LuaStatements());
130130

131-
LuaFunction fromIndexFunction = LuaAst.LuaFunction(uniqueName("objectFromIndex"), LuaAst.LuaParams(), LuaAst.LuaStatements());
131+
LuaFunction fromIndexFunction = LuaAst.LuaFunction(uniqueName("__wurst_objectFromIndex"), LuaAst.LuaParams(), LuaAst.LuaStatements());
132132

133133
LuaFunction instanceOfFunction = LuaAst.LuaFunction(uniqueName("isInstanceOf"), LuaAst.LuaParams(), LuaAst.LuaStatements());
134134

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/lua/translation/StmtTranslation.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ public static void translate(ImSet s, List<LuaStatement> res, LuaTranslator tr)
5050
public static void translate(ImVarargLoop loop, List<LuaStatement> res, LuaTranslator tr) {
5151
LuaVariable loopVar = tr.luaVar.getFor(loop.getLoopVar());
5252
// res.add(loopVar);
53+
String argsName = tr.uniqueName("__args");
5354
LuaVariable i = LuaAst.LuaVariable(tr.uniqueName("i"), LuaAst.LuaExprIntVal("0"));
54-
res.add(LuaAst.LuaLiteral("local __args = table.pack(...)"));
55-
res.add(LuaAst.LuaLiteral("for " + i.getName() + "=1,__args.n do"));
56-
res.add(LuaAst.LuaAssignment(LuaAst.LuaExprVarAccess(loopVar), LuaAst.LuaExprArrayAccess(LuaAst.LuaLiteral("__args"), LuaAst.LuaExprlist(LuaAst.LuaExprVarAccess(i)))));
55+
res.add(LuaAst.LuaLiteral("local " + argsName + " = table.pack(...)"));
56+
res.add(LuaAst.LuaLiteral("for " + i.getName() + "=1," + argsName + ".n do"));
57+
res.add(LuaAst.LuaAssignment(LuaAst.LuaExprVarAccess(loopVar), LuaAst.LuaExprArrayAccess(LuaAst.LuaLiteral(argsName), LuaAst.LuaExprlist(LuaAst.LuaExprVarAccess(i)))));
5758
tr.translateStatements(res, loop.getBody());
5859
res.add(LuaAst.LuaLiteral("end"));
5960
}

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/LuaTranslationTests.java

Lines changed: 131 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,138 @@ public void intCasting() throws IOException {
271271
assertFunctionBodyContains(compiled, "testEnum", "zeroInt = zeroEnum", true);
272272
assertFunctionBodyContains(compiled, "testEnum", "zeroEnum2 = zeroInt", true);
273273
// classes are cast with objectToIndex and objectFromIndex in lua
274-
assertFunctionBodyContains(compiled, "testClass", "objectToIndex", true);
275-
assertFunctionBodyContains(compiled, "testClass", "objectFromIndex", true);
274+
assertFunctionBodyContains(compiled, "testClass", "__wurst_objectToIndex", true);
275+
assertFunctionBodyContains(compiled, "testClass", "__wurst_objectFromIndex", true);
276276
assertFunctionBodyContains(compiled, "testClass", "cInt = cObj", false);
277277
assertFunctionBodyContains(compiled, "testClass", "cObj2 = cInt", false);
278278
}
279+
280+
@Test
281+
public void configEntrypointNotRenamedWhenUserHasConfigFunction() throws IOException {
282+
test().testLua(true).lines(
283+
"package Test",
284+
"function config()",
285+
" skip",
286+
"init",
287+
" config()"
288+
);
289+
String compiled = Files.toString(new File("test-output/lua/LuaTranslationTests_configEntrypointNotRenamedWhenUserHasConfigFunction.lua"), Charsets.UTF_8);
290+
assertTrue(compiled.contains("function config("));
291+
assertFalse(compiled.contains("function config2("));
292+
assertTrue(compiled.contains("function config1("));
293+
assertTrue(compiled.contains("config1()"));
294+
}
295+
296+
@Test
297+
public void objectIndexFunctionsDoNotCollideWithUserFunctions() throws IOException {
298+
test().testLua(true).lines(
299+
"package Test",
300+
"function objectToIndex(int i) returns int",
301+
" return i + 1",
302+
"function objectFromIndex(int i) returns int",
303+
" return i - 1",
304+
"native takesInt(int i)",
305+
"class C",
306+
"function testClass()",
307+
" let cObj = new C()",
308+
" let cInt = cObj castTo int",
309+
" let cObj2 = cInt castTo C",
310+
" takesInt(objectToIndex(3))",
311+
" takesInt(objectFromIndex(5))",
312+
" if cObj2 == null",
313+
" skip",
314+
"init",
315+
" testClass()"
316+
);
317+
String compiled = Files.toString(new File("test-output/lua/LuaTranslationTests_objectIndexFunctionsDoNotCollideWithUserFunctions.lua"), Charsets.UTF_8);
318+
assertTrue(compiled.contains("function objectToIndex("));
319+
assertTrue(compiled.contains("function objectFromIndex("));
320+
assertFunctionBodyContains(compiled, "testClass", "__wurst_objectToIndex", true);
321+
assertFunctionBodyContains(compiled, "testClass", "__wurst_objectFromIndex", true);
322+
}
323+
324+
@Test
325+
public void reflectionNativesStubbedForLua() throws IOException {
326+
test().testLua(true).lines(
327+
"package Test",
328+
"native typeIdToTypeName(int typeId) returns string",
329+
"native maxTypeId() returns int",
330+
"native instanceCount(int typeId) returns int",
331+
"native maxInstanceCount(int typeId) returns int",
332+
"class A",
333+
"init",
334+
" let name = typeIdToTypeName(A.typeId)",
335+
" let m = maxTypeId()",
336+
" let c = instanceCount(A.typeId)",
337+
" let mc = maxInstanceCount(A.typeId)"
338+
);
339+
String compiled = Files.toString(new File("test-output/lua/LuaTranslationTests_reflectionNativesStubbedForLua.lua"), Charsets.UTF_8);
340+
assertFalse(compiled.contains("The native 'typeIdToTypeName' is not implemented."));
341+
assertFalse(compiled.contains("The native 'maxTypeId' is not implemented."));
342+
assertFalse(compiled.contains("The native 'instanceCount' is not implemented."));
343+
assertFalse(compiled.contains("The native 'maxInstanceCount' is not implemented."));
344+
assertTrue(compiled.contains("typeIdToTypeName = function"));
345+
assertTrue(compiled.contains("maxTypeId = function"));
346+
assertTrue(compiled.contains("instanceCount = function"));
347+
assertTrue(compiled.contains("maxInstanceCount = function"));
348+
}
349+
350+
@Test
351+
public void reflectionNativeStubBodiesReturnDefaults() throws IOException {
352+
test().testLua(true).lines(
353+
"package Test",
354+
"native typeIdToTypeName(int typeId) returns string",
355+
"native maxTypeId() returns int",
356+
"native instanceCount(int typeId) returns int",
357+
"native maxInstanceCount(int typeId) returns int",
358+
"class A",
359+
"init",
360+
" let _n = typeIdToTypeName(A.typeId)",
361+
" let _m = maxTypeId()",
362+
" let _c = instanceCount(A.typeId)",
363+
" let _mc = maxInstanceCount(A.typeId)"
364+
);
365+
String compiled = Files.toString(new File("test-output/lua/LuaTranslationTests_reflectionNativeStubBodiesReturnDefaults.lua"), Charsets.UTF_8);
366+
assertTrue(compiled.contains("typeIdToTypeName = function"));
367+
assertTrue(compiled.contains("return \"\""));
368+
assertTrue(compiled.contains("maxTypeId = function"));
369+
assertTrue(compiled.contains("instanceCount = function"));
370+
assertTrue(compiled.contains("maxInstanceCount = function"));
371+
assertTrue(compiled.contains("return 0"));
372+
}
373+
374+
@Test
375+
public void reflectionNativeStubsAreGuardedByExistingDefinitions() throws IOException {
376+
test().testLua(true).lines(
377+
"package Test",
378+
"native typeIdToTypeName(int typeId) returns string",
379+
"native maxTypeId() returns int",
380+
"native instanceCount(int typeId) returns int",
381+
"native maxInstanceCount(int typeId) returns int",
382+
"class A",
383+
"init",
384+
" let _n = typeIdToTypeName(A.typeId)",
385+
" let _m = maxTypeId()",
386+
" let _c = instanceCount(A.typeId)",
387+
" let _mc = maxInstanceCount(A.typeId)"
388+
);
389+
String compiled = Files.toString(new File("test-output/lua/LuaTranslationTests_reflectionNativeStubsAreGuardedByExistingDefinitions.lua"), Charsets.UTF_8);
390+
assertTrue(compiled.contains("if typeIdToTypeName then"));
391+
assertTrue(compiled.contains("if maxTypeId then"));
392+
assertTrue(compiled.contains("if instanceCount then"));
393+
assertTrue(compiled.contains("if maxInstanceCount then"));
394+
}
395+
396+
@Test
397+
public void stdLibInitUsesTriggerEvaluateGuardInMain() throws IOException {
398+
test().testLua(true).withStdLib().lines(
399+
"package Test",
400+
"init",
401+
" skip"
402+
);
403+
String compiled = Files.toString(new File("test-output/lua/LuaTranslationTests_stdLibInitUsesTriggerEvaluateGuardInMain.lua"), Charsets.UTF_8);
404+
assertTrue(compiled.contains("if not(TriggerEvaluate("));
405+
assertTrue(compiled.contains("TriggerClearConditions"));
406+
}
407+
279408
}

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/WurstScriptTest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,9 @@ private void translateAndTestLua(String name, boolean executeProg, WurstGui gui,
476476

477477
if (executeProg) {
478478
String line;
479+
String luaExecutable = getLuaExecutable();
479480
String[] args = {
480-
"lua",
481+
luaExecutable,
481482
"-l", luaFile.getPath().replace(".lua", ""),
482483
"-e", "main()"
483484
};
@@ -519,6 +520,18 @@ private void translateAndTestLua(String name, boolean executeProg, WurstGui gui,
519520

520521
}
521522

523+
private String getLuaExecutable() {
524+
File bundledLuaWin = new File("src/test/resources/lua53.exe");
525+
if (bundledLuaWin.exists()) {
526+
return bundledLuaWin.getPath();
527+
}
528+
File bundledLuaUnix = new File("src/test/resources/lua53");
529+
if (bundledLuaUnix.exists()) {
530+
return bundledLuaUnix.getPath();
531+
}
532+
return "lua";
533+
}
534+
522535
private void translateAndTest(String name, boolean executeProg,
523536
boolean executeTests, WurstGui gui, WurstCompilerJassImpl compiler,
524537
WurstModel model, boolean executeProgOnlyAfterTransforms) throws Error {
166 KB
Binary file not shown.
161 KB
Binary file not shown.

0 commit comments

Comments
 (0)