• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wurstscript / WurstScript / 271

29 Sep 2025 12:12PM UTC coverage: 64.649% (+2.4%) from 62.222%
271

Pull #1096

circleci

Frotty
Merge branch 'perf-improvements' of https://github.com/wurstscript/WurstScript into perf-improvements
Pull Request #1096: Perf improvements

18202 of 28155 relevant lines covered (64.65%)

0.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

48.02
de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/lua/translation/ExprTranslation.java
1
package de.peeeq.wurstscript.translation.lua.translation;
2

3
import de.peeeq.wurstscript.WurstOperator;
4
import de.peeeq.wurstscript.jassIm.*;
5
import de.peeeq.wurstscript.luaAst.*;
6
import de.peeeq.wurstscript.translation.imtranslation.ImTranslator;
7
import de.peeeq.wurstscript.types.TypesHelper;
8

9
import java.util.Optional;
10

11
public class ExprTranslation {
×
12

13
    public static final String TYPE_ID = "__typeId__";
14
    public static final String WURST_SUPERTYPES = "__wurst_supertypes";
15

16
    public static LuaExpr translate(ImAlloc e, LuaTranslator tr) {
17
        ImClass c = e.getClazz().getClassDef();
1✔
18
        LuaMethod m = tr.luaClassInitMethod.getFor(c);
1✔
19
        LuaVariable classVar = tr.luaClassVar.getFor(c);
1✔
20
        return LuaAst.LuaExprMethodCall(
1✔
21
            LuaAst.LuaExprVarAccess(classVar),
1✔
22
            m,
23
            LuaAst.LuaExprlist()
1✔
24
        );
25
    }
26

27
    public static LuaExpr translate(ImBoolVal e, LuaTranslator tr) {
28
        return LuaAst.LuaExprBoolVal(e.getValB());
1✔
29
    }
30

31
    public static LuaExpr translate(ImDealloc e, LuaTranslator tr) {
32
        return LuaAst.LuaExprNull(); // TODO maybe call some finalizer?
1✔
33
    }
34

35
    public static LuaExpr translate(ImFuncRef e, LuaTranslator tr) {
36
//        return LuaAst.LuaExprFuncRef(tr.luaFunc.getFor(e.getFunc()));
37
//         alternative: use xpcall to get stacktraces (did not work)
38
        LuaVariable dots = LuaAst.LuaVariable("...", LuaAst.LuaNoExpr());
1✔
39
        LuaVariable tempDots = LuaAst.LuaVariable("temp", LuaAst.LuaExprVarAccess(dots));
1✔
40
        LuaVariable tempRes = LuaAst.LuaVariable("tempRes", LuaAst.LuaExprNull());
1✔
41
        return LuaAst.LuaExprFunctionAbstraction(LuaAst.LuaParams(dots),
1✔
42
            LuaAst.LuaStatements(
1✔
43
                tempDots,
44
                tempRes,
45
                LuaAst.LuaExprFunctionCallByName("xpcall",
1✔
46
                    LuaAst.LuaExprlist(
1✔
47
                        LuaAst.LuaExprFunctionAbstraction(
1✔
48
                            LuaAst.LuaParams(),
1✔
49
                            LuaAst.LuaStatements(
1✔
50
                                LuaAst.LuaAssignment(LuaAst.LuaExprVarAccess(tempRes),
1✔
51
                                    LuaAst.LuaExprFunctionCall(tr.luaFunc.getFor(e.getFunc()), LuaAst.LuaExprlist(LuaAst.LuaExprVarAccess(tempDots)))))
1✔
52
                        ),
53
//                        LuaAst.LuaLiteral("function(err) " + errorFuncName(tr) + "(tostring(err)) end")
54
                        LuaAst.LuaLiteral("function(err) xpcall(function() " + callErrorFunc(tr, "tostring(err)") + " end, function(err2) BJDebugMsg(\"error reporting error: \" .. tostring(err2)) BJDebugMsg(\"while reporting: \" .. tostring(err))  end) end")
1✔
55
                        // unfortunately  BJDebugMsg(debug.traceback()) is not working
56
                    )
57
                ),
58
                LuaAst.LuaReturn(LuaAst.LuaExprVarAccess(tempRes))
1✔
59
            )
60
        );
61
    }
62

63
    private static String callErrorFunc(LuaTranslator tr, String msg) {
64
        LuaFunction ef = tr.getErrorFunc();
1✔
65
        if (ef != null) {
1✔
66
            if (ef.getParams().size() == 2) {
1✔
67
                return ef.getName() + "(" + msg + ", \"<lua error>\")";
×
68
            }
69
            return ef.getName() + "(" + msg + ")";
1✔
70
        }
71
        return "BJDebugMsg(" + msg + ")";
×
72
    }
73

74
    public static LuaExpr translate(ImFunctionCall e, LuaTranslator tr) {
75
        LuaFunction f = tr.luaFunc.getFor(e.getFunc());
1✔
76
        if (f.getName().equals(ImTranslator.$DEBUG_PRINT)) {
1✔
77
            f.setName("BJDebugMsg");
×
78
        } else if (f.getName().equals("I2S")) {
1✔
79
            f.setName("tostring");
1✔
80
        }
81
        return LuaAst.LuaExprFunctionCall(f, tr.translateExprList(e.getArguments()));
1✔
82
    }
83

84
    public static LuaExpr translate(ImInstanceof e, LuaTranslator tr) {
85
        return
×
86
            LuaAst.LuaExprFunctionCall(tr.instanceOfFunction, LuaAst.LuaExprlist(
×
87
                e.getObj().translateToLua(tr),
×
88
                LuaAst.LuaExprVarAccess(tr.luaClassVar.getFor(e.getClazz().getClassDef()))));
×
89
    }
90

91
    public static LuaExpr translate(ImIntVal e, LuaTranslator tr) {
92
        return LuaAst.LuaExprIntVal("" + e.getValI());
1✔
93
    }
94

95
    public static LuaExpr translate(ImMemberAccess e, LuaTranslator tr) {
96
        LuaExpr res = LuaAst.LuaExprFieldAccess(e.getReceiver().translateToLua(tr), e.getVar().getName());
1✔
97
        if (!e.getIndexes().isEmpty()) {
1✔
98
            LuaExprlist indexes = LuaAst.LuaExprlist();
×
99
            for (ImExpr index : e.getIndexes()) {
×
100
                indexes.add(index.translateToLua(tr));
×
101
            }
×
102
            res = LuaAst.LuaExprArrayAccess(res, indexes);
×
103
        }
104
        return res;
1✔
105
    }
106

107
    public static LuaExpr translate(ImMethodCall e, LuaTranslator tr) {
108
        return LuaAst.LuaExprMethodCall(e.getReceiver().translateToLua(tr), tr.luaMethod.getFor(e.getMethod()), tr.translateExprList(e.getArguments()));
1✔
109
    }
110

111
    public static LuaExpr translate(ImNull e, LuaTranslator tr) {
112
        return LuaAst.LuaExprNull();
1✔
113
    }
114

115
    public static LuaExpr translate(ImOperatorCall e, LuaTranslator tr) {
116
        if (e.getArguments().size() == 2) {
1✔
117
            ImExpr left = e.getArguments().get(0);
1✔
118
            ImExpr right = e.getArguments().get(1);
1✔
119
            if (e.getOp() == WurstOperator.EQ) {
1✔
120
                return translateEquals(left, right, tr);
1✔
121
            } else if (e.getOp() == WurstOperator.NOTEQ) {
1✔
122
                return LuaAst.LuaExprUnary(LuaAst.LuaOpNot(), translateEquals(left, right, tr));
×
123
            }
124
            LuaExpr leftExpr = left.translateToLua(tr);
1✔
125
            LuaExpr rightExpr = right.translateToLua(tr);
1✔
126
            LuaOpBinary op;
127
            if (e.getOp() == WurstOperator.MOD_INT) {
1✔
128
                op = LuaAst.LuaOpMod();
×
129

130
                return LuaAst.LuaExprFunctionCallE(LuaAst.LuaLiteral("math.floor"),
×
131
                    LuaAst.LuaExprlist(LuaAst.LuaExprBinary(leftExpr, op, rightExpr)));
×
132
            } else if (e.getOp() == WurstOperator.DIV_INT) {
1✔
133
                op = LuaAst.LuaOpFloorDiv();
1✔
134
                return LuaAst.LuaExprBinary(leftExpr, op, rightExpr);
1✔
135
            } else {
136
                // TODO special cases for integer division and modulo
137
                op = e.getOp().luaTranslateBinary();
1✔
138
            }
139

140
            return LuaAst.LuaExprBinary(leftExpr, op, rightExpr);
1✔
141
        } else if (e.getArguments().size() == 1) {
1✔
142
            ImExpr arg = e.getArguments().get(0);
1✔
143
            LuaExpr argT = arg.translateToLua(tr);
1✔
144
            LuaOpUnary op;
145
            switch (e.getOp()) {
1✔
146
                case NOT:
147
                    op = LuaAst.LuaOpNot();
1✔
148
                    break;
1✔
149
                case UNARY_MINUS:
150
                    op = LuaAst.LuaOpMinus();
×
151
                    break;
×
152
                default:
153
                    throw new Error("not implemented: unary operator " + e.getOp());
×
154
            }
155
            return LuaAst.LuaExprUnary(op, argT);
1✔
156

157
        }
158
        throw new Error("not implemented: " + e);
×
159
    }
160

161
    static class TupleFunc {
162
        final ImTupleType tupleType;
163
        final LuaFunction func;
164

165
        public TupleFunc(ImTupleType tupleType, LuaFunction func) {
×
166
            this.tupleType = tupleType;
×
167
            this.func = func;
×
168
        }
×
169
    }
170

171

172
    private static LuaFunction getTupleEqualsFunc(ImTupleType t, LuaTranslator tr) {
173
        Optional<TupleFunc> tfo = tr.tupleEqualsFuncs.stream()
×
174
            .filter(f -> f.tupleType.equalsType(t))
×
175
            .findFirst();
×
176
        TupleFunc tf;
177
        if (tfo.isPresent()) {
×
178
            tf = tfo.get();
×
179
        } else {
180
            LuaVariable t1 = LuaAst.LuaVariable("t1", LuaAst.LuaNoExpr());
×
181
            LuaVariable t2 = LuaAst.LuaVariable("t2", LuaAst.LuaNoExpr());
×
182
            LuaStatements body = LuaAst.LuaStatements();
×
183
            LuaFunction func = LuaAst.LuaFunction(tr.uniqueName("tupleEquals"), LuaAst.LuaParams(t1, t2), body);
×
184
            LuaExpr result = LuaAst.LuaExprBoolVal(true);
×
185

186
            for (int i = 0; i < t.getNames().size(); i++) {
×
187
                result = conjunction(result, translateEquals(
×
188
                    LuaAst.LuaExprArrayAccess(LuaAst.LuaExprVarAccess(t1),
×
189
                        LuaAst.LuaExprlist(LuaAst.LuaExprIntVal("" + i))),
×
190
                    LuaAst.LuaExprArrayAccess(LuaAst.LuaExprVarAccess(t2),
×
191
                        LuaAst.LuaExprlist(LuaAst.LuaExprIntVal("" + i))),
×
192
                    t.getTypes().get(i),
×
193
                    tr));
194
            }
195

196
            body.add(LuaAst.LuaReturn(result));
×
197
            tr.luaModel.add(func);
×
198
            tf = new TupleFunc(t, func);
×
199
            tr.tupleEqualsFuncs.add(tf);
×
200
        }
201
        return tf.func;
×
202
    }
203

204

205
    public static LuaFunction getTupleCopyFunc(ImTupleType t, LuaTranslator tr) {
206
        Optional<TupleFunc> tfo = tr.tupleCopyFuncs.stream()
×
207
            .filter(f -> f.tupleType.equalsType(t))
×
208
            .findFirst();
×
209
        TupleFunc tf;
210
        if (tfo.isPresent()) {
×
211
            tf = tfo.get();
×
212
        } else {
213
            LuaVariable t1 = LuaAst.LuaVariable("t", LuaAst.LuaNoExpr());
×
214
            LuaStatements body = LuaAst.LuaStatements();
×
215
            LuaFunction func = LuaAst.LuaFunction(tr.uniqueName("tupleCopy"), LuaAst.LuaParams(t1), body);
×
216
            LuaTableFields fields = LuaAst.LuaTableFields();
×
217
            LuaExpr result = LuaAst.LuaTableConstructor(fields);
×
218

219
            int i = 0;
×
220
            for (ImType type : t.getTypes()) {
×
221
                i++;
×
222
                LuaExpr v = LuaAst.LuaExprArrayAccess(
×
223
                    LuaAst.LuaExprVarAccess(t1),
×
224
                    LuaAst.LuaExprlist(LuaAst.LuaExprIntVal("" + i))
×
225
                );
226
                if (type instanceof ImTupleType) {
×
227
                    ImTupleType tt = (ImTupleType) type;
×
228
                    v = LuaAst.LuaExprFunctionCall(getTupleCopyFunc(tt, tr), LuaAst.LuaExprlist(v));
×
229
                }
230
                fields.add(LuaAst.LuaTableSingleField(v));
×
231
            }
×
232

233
            body.add(LuaAst.LuaReturn(result));
×
234
            tr.luaModel.add(func);
×
235
            tf = new TupleFunc(t, func);
×
236
            tr.tupleCopyFuncs.add(tf);
×
237
        }
238
        return tf.func;
×
239
    }
240

241
    private static LuaExpr conjunction(LuaExpr left, LuaExpr right) {
242
        if (left instanceof LuaExprBoolVal && ((LuaExprBoolVal) left).getValB()) {
×
243
            return right;
×
244
        } else if (right instanceof LuaExprBoolVal && ((LuaExprBoolVal) right).getValB()) {
×
245
            return left;
×
246
        }
247
        return LuaAst.LuaExprBinary(left, LuaAst.LuaOpAnd(), right);
×
248
    }
249

250
    private static LuaExpr translateEquals(ImExpr left, ImExpr right, LuaTranslator tr) {
251
        LuaExpr leftExpr = left.translateToLua(tr);
1✔
252
        LuaExpr rightExpr = right.translateToLua(tr);
1✔
253
        ImType t = left.attrTyp();
1✔
254
        return translateEquals(leftExpr, rightExpr, t, tr);
1✔
255
    }
256

257
    private static LuaExpr translateEquals(LuaExpr leftExpr, LuaExpr rightExpr, ImType t, LuaTranslator tr) {
258
        if (t instanceof ImTupleType) {
1✔
259
            ImTupleType tt = (ImTupleType) t;
×
260
            LuaFunction ef = getTupleEqualsFunc(tt, tr);
×
261
            return LuaAst.LuaExprFunctionCall(ef, LuaAst.LuaExprlist(leftExpr, rightExpr));
×
262
        }
263
        return LuaAst.LuaExprBinary(leftExpr, LuaAst.LuaOpEquals(), rightExpr);
1✔
264
    }
265

266
    public static LuaExpr translate(ImRealVal e, LuaTranslator tr) {
267
        return LuaAst.LuaExprRealVal(e.getValR());
1✔
268
    }
269

270
    public static LuaExpr translate(ImStatementExpr e, LuaTranslator tr) {
271
        LuaStatements body = tr.translateStatements(e.getStatements());
×
272
        body.add(LuaAst.LuaReturn(e.getExpr().translateToLua(tr)));
×
273
        return LuaAst.LuaExprFunctionCallE(
×
274
            LuaAst.LuaExprFunctionAbstraction(LuaAst.LuaParams(), body),
×
275
            LuaAst.LuaExprlist());
×
276
    }
277

278
    public static LuaExpr translate(ImStringVal e, LuaTranslator tr) {
279
        return LuaAst.LuaExprStringVal(e.getValS());
1✔
280
    }
281

282
    public static LuaExpr translate(ImTupleExpr e, LuaTranslator tr) {
283
        LuaTableFields tableFields = LuaAst.LuaTableFields();
1✔
284
        for (ImExpr te : e.getExprs()) {
1✔
285
            tableFields.add(LuaAst.LuaTableSingleField(te.translateToLua(tr)));
1✔
286
        }
1✔
287
        return LuaAst.LuaTableConstructor(tableFields);
1✔
288
    }
289

290
    public static LuaExpr translate(ImTupleSelection e, LuaTranslator tr) {
291
        return LuaAst.LuaExprArrayAccess(e.getTupleExpr().translateToLua(tr), LuaAst.LuaExprlist(LuaAst.LuaExprIntVal("" + (1 + e.getTupleIndex()))));
1✔
292
    }
293

294
    public static LuaExpr translate(ImTypeIdOfClass e, LuaTranslator tr) {
295
        int i = tr.getTypeId(e.getClazz().getClassDef());
×
296
        return LuaAst.LuaExprIntVal("" + i);
×
297
    }
298

299
    public static LuaExpr translate(ImTypeIdOfObj e, LuaTranslator tr) {
300
        return LuaAst.LuaExprFieldAccess(e.getObj().translateToLua(tr), TYPE_ID);
×
301
    }
302

303
    public static LuaExpr translate(ImVarAccess e, LuaTranslator tr) {
304
        return LuaAst.LuaExprVarAccess(tr.luaVar.getFor(e.getVar()));
1✔
305
    }
306

307
    public static LuaExpr translate(ImVarArrayAccess e, LuaTranslator tr) {
308
        LuaExprlist indexes = LuaAst.LuaExprlist();
1✔
309
        for (ImExpr ie : e.getIndexes()) {
1✔
310
            indexes.add(ie.translateToLua(tr));
1✔
311
        }
1✔
312
        return LuaAst.LuaExprArrayAccess(LuaAst.LuaExprVarAccess(tr.luaVar.getFor(e.getVar())), indexes);
1✔
313
    }
314

315
    public static LuaExpr translate(ImGetStackTrace e, LuaTranslator tr) {
316
//        return LuaAst.LuaLiteral("debug.traceback()");
317
        return LuaAst.LuaLiteral("\"$Stacktrace$\"");
1✔
318
    }
319

320
    public static LuaExpr translate(ImCompiletimeExpr imCompiletimeExpr, LuaTranslator tr) {
321
        throw new Error("not implemented");
×
322
    }
323

324
    public static LuaExpr translate(ImTypeVarDispatch imTypeVarDispatch, LuaTranslator tr) {
325
        throw new Error("not implemented");
×
326
    }
327

328
    public static LuaExpr translate(ImCast imCast, LuaTranslator tr) {
329
        LuaExpr translated = imCast.getExpr().translateToLua(tr);
1✔
330
        if (TypesHelper.isIntType(imCast.getToType())) {
1✔
331
            return LuaAst.LuaExprFunctionCall(tr.toIndexFunction, LuaAst.LuaExprlist(translated));
1✔
332
        } else if (imCast.getToType() instanceof ImClassType
1✔
333
            || imCast.getToType() instanceof ImAnyType) {
1✔
334
            return LuaAst.LuaExprFunctionCall(tr.fromIndexFunction, LuaAst.LuaExprlist(translated));
1✔
335
        } else {
336
            return translated;
×
337
        }
338
    }
339
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc