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

wurstscript / WurstScript / 228

29 Nov 2023 05:00PM UTC coverage: 62.48% (-0.09%) from 62.574%
228

push

circleci

web-flow
Show dialog for choosing game path, cleanup (#1083)

* show dialog for choosing game path

* cleanup code

* remove logs and refactor

* remove confusing mpq error, make some mpq loads readonly

17295 of 27681 relevant lines covered (62.48%)

0.62 hits per line

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

80.65
de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/interpreter/EvaluateExpr.java
1
package de.peeeq.wurstscript.intermediatelang.interpreter;
2

3
import de.peeeq.wurstio.jassinterpreter.InterpreterException;
4
import de.peeeq.wurstscript.WLogger;
5
import de.peeeq.wurstscript.WurstOperator;
6
import de.peeeq.wurstscript.ast.PackageOrGlobal;
7
import de.peeeq.wurstscript.ast.VarDef;
8
import de.peeeq.wurstscript.ast.WPackage;
9
import de.peeeq.wurstscript.intermediatelang.*;
10
import de.peeeq.wurstscript.jassIm.*;
11
import de.peeeq.wurstscript.types.TypesHelper;
12
import org.eclipse.jdt.annotation.Nullable;
13

14
import java.util.ArrayList;
15
import java.util.List;
16
import java.util.concurrent.atomic.AtomicReference;
17
import java.util.stream.Collectors;
18

19
public class EvaluateExpr {
×
20

21
    public static ILconst eval(ImBoolVal e, ProgramState globalState, LocalState localState) {
22
        return ILconstBool.instance(e.getValB());
1✔
23
    }
24

25
    public static ILconst eval(ImFuncRef e, ProgramState globalState, LocalState localState) {
26
        return new ILconstFuncRef(e.getFunc());
1✔
27
    }
28

29
    public static @Nullable ILconst eval(ImFunctionCall e, ProgramState globalState, LocalState localState) {
30
        ImFunction f = e.getFunc();
1✔
31
        ImExprs arguments = e.getArguments();
1✔
32
        return evaluateFunc(globalState, localState, f, arguments, e);
1✔
33
    }
34

35
    public static @Nullable ILconst evaluateFunc(ProgramState globalState,
36
                                                 LocalState localState, ImFunction f, List<ImExpr> args2, Element trace) {
37
        ILconst[] args = new ILconst[args2.size()];
1✔
38
        for (int i = 0; i < args2.size(); i++) {
1✔
39
            args[i] = args2.get(i).evaluate(globalState, localState);
1✔
40
        }
41
        return evaluateFunc(globalState, f, trace, args);
1✔
42
    }
43

44
    @Nullable
45
    private static ILconst evaluateFunc(ProgramState globalState, ImFunction f, Element trace, ILconst[] args) {
46
        LocalState r = ILInterpreter.runFunc(globalState, f, trace, args);
1✔
47
        return r.getReturnVal();
1✔
48
    }
49

50
    public static ILconst eval(ImIntVal e, ProgramState globalState, LocalState localState) {
51
        return new ILconstInt(e.getValI());
1✔
52
    }
53

54
    public static ILconst eval(ImNull e, ProgramState globalState, LocalState localState) {
55
        if (e.getType() instanceof ImAnyType
1✔
56
            || e.getType() instanceof ImClassType
1✔
57
            || e.getType() instanceof ImTypeVarRef
1✔
58
            || TypesHelper.isIntType(e.getType())) {
1✔
59
            return ILconstInt.create(0);
1✔
60
        }
61
        return ILconstNull.instance();
1✔
62
    }
63

64
    public static ILconst eval(ImOperatorCall e, final ProgramState globalState, final LocalState localState) {
65
        final ImExprs arguments = e.getArguments();
1✔
66
        WurstOperator op = e.getOp();
1✔
67
        if (arguments.size() == 2 && op.isBinaryOp()) {
1✔
68
            return op.evaluateBinaryOperator(arguments.get(0).evaluate(globalState, localState), () -> arguments.get(1).evaluate(globalState, localState));
1✔
69
        } else if (arguments.size() == 1 && op.isUnaryOp()) {
1✔
70
            return op.evaluateUnaryOperator(arguments.get(0).evaluate(globalState, localState));
1✔
71
        } else {
72
            throw new Error();
×
73
        }
74
    }
75

76
    public static ILconst eval(ImRealVal e, ProgramState globalState, LocalState localState) {
77
        return new ILconstReal(e.getValR());
1✔
78
    }
79

80
    public static ILconst eval(ImStatementExpr e, ProgramState globalState, LocalState localState) {
81
        e.getStatements().runStatements(globalState, localState);
1✔
82
        return e.getExpr().evaluate(globalState, localState);
1✔
83
    }
84

85
    public static ILaddress evaluateLvalue(ImStatementExpr e, ProgramState globalState, LocalState localState) {
86
        e.getStatements().runStatements(globalState, localState);
×
87
        return ((ImLExpr) e.getExpr()).evaluateLvalue(globalState, localState);
×
88
    }
89

90
    public static ILconst eval(ImStringVal e, ProgramState globalState, LocalState localState) {
91
        return new ILconstString(e.getValS());
1✔
92
    }
93

94
    public static ILconst eval(ImTupleExpr e, ProgramState globalState, LocalState localState) {
95
        ILconst[] values = new ILconst[e.getExprs().size()];
1✔
96
        for (int i = 0; i < e.getExprs().size(); i++) {
1✔
97
            values[i] = e.getExprs().get(i).evaluate(globalState, localState);
1✔
98
        }
99
        return new ILconstTuple(values);
1✔
100
    }
101

102
    public static ILconst eval(ImTupleSelection e, ProgramState globalState, LocalState localState) {
103
        ILconst tupleE = e.getTupleExpr().evaluate(globalState, localState);
1✔
104
        if (tupleE instanceof ILconstTuple) {
1✔
105
            ILconstTuple t = (ILconstTuple) tupleE;
1✔
106
            if (e.getTupleIndex() >= t.values().size()) {
1✔
107
                throw new InterpreterException(globalState, "Trying to get element " + e.getTupleIndex() + " of tuple value " + t);
×
108
            }
109
            return t.getValue(e.getTupleIndex());
1✔
110
        } else {
111
            throw new InterpreterException(globalState, "Tuple " + e + " evaluated to " + tupleE);
×
112
        }
113

114
    }
115

116
    public static ILconst eval(ImVarAccess e, ProgramState globalState, LocalState localState) {
117
        ImVar var = e.getVar();
1✔
118
        if (var.isGlobal()) {
1✔
119
            if (isMagicCompiletimeConstant(var)) {
1✔
120
                return ILconstBool.instance(globalState.isCompiletime());
1✔
121
            }
122

123
            ILconst r = globalState.getVal(var);
1✔
124
            if (r == null) {
1✔
125
                List<ImSet> initExpr = globalState.getProg().getGlobalInits().get(var);
1✔
126
                if (initExpr != null) {
1✔
127
                    r = initExpr.get(0).getRight().evaluate(globalState, localState);
1✔
128
                } else {
129
                    throw new InterpreterException(globalState, "Variable " + var.getName() + " is not initialized.");
×
130
                }
131
                globalState.setVal(var, r);
1✔
132
            }
133
            return r;
1✔
134
        } else {
135
            return notNull(localState.getVal(var), var.getType(), "Local variable " + var + " is null.", true);
1✔
136
        }
137
    }
138

139
    private static boolean isMagicCompiletimeConstant(ImVar var) {
140
        if (var.getTrace() instanceof VarDef) {
1✔
141
            VarDef varDef = (VarDef) var.getTrace();
1✔
142
            if (varDef.getName().equals("compiletime")) {
1✔
143
                PackageOrGlobal nearestPackage = varDef.attrNearestPackage();
1✔
144
                if (nearestPackage instanceof WPackage) {
1✔
145
                    WPackage p = (WPackage) nearestPackage;
1✔
146
                    return p.getName().equals("MagicFunctions");
1✔
147
                }
148
            }
149
        }
150
        return false;
1✔
151
    }
152

153
    private static ILconst notNull(@Nullable ILconst val, ImType imType, String msg, boolean failOnErr) {
154
        if (val == null) {
1✔
155
            if (failOnErr) {
×
156
                throw new InterpreterException(msg);
×
157
            } else {
158
                WLogger.warning(msg);
×
159
                return imType.defaultValue();
×
160
            }
161
        }
162
        return val;
1✔
163
    }
164

165
    public static ILconst eval(ImVarArrayAccess e, ProgramState globalState, LocalState localState) {
166
        List<Integer> indexes = e.getIndexes().stream()
1✔
167
            .map(ie -> ((ILconstInt) ie.evaluate(globalState, localState)).getVal())
1✔
168
            .collect(Collectors.toList());
1✔
169

170
        if (e.getVar().isGlobal()) {
1✔
171
            return notNull(globalState.getArrayVal(e.getVar(), indexes), e.getVar().getType(), "Variable " + e.getVar().getName() + " is null.", false);
1✔
172
        } else {
173
            return notNull(localState.getArrayVal(e.getVar(), indexes), e.getVar().getType(), "Variable " + e.getVar().getName() + " is null.", false);
1✔
174
        }
175
    }
176

177
    public static @Nullable ILconst eval(ImMethodCall mc,
178
                                         ProgramState globalState, LocalState localState) {
179
        ILconstObject receiver = globalState.toObject(mc.getReceiver().evaluate(globalState, localState));
1✔
180

181
        globalState.assertAllocated(receiver, mc.attrTrace());
1✔
182

183

184
        List<ImExpr> args = mc.getArguments();
1✔
185

186

187
        ImMethod mostPrecise = mc.getMethod();
1✔
188

189
        // find correct implementation:
190
        for (ImMethod m : mc.getMethod().getSubMethods()) {
1✔
191

192
            if (m.attrClass().isSubclassOf(mostPrecise.attrClass())) {
1✔
193
                if (globalState.isInstanceOf(receiver, m.attrClass(), mc.attrTrace())) {
1✔
194
                    // found more precise method
195
                    mostPrecise = m;
1✔
196
                }
197
            }
198
        }
1✔
199
        // execute most precise method
200
        ILconst[] eargs = new ILconst[args.size() + 1];
1✔
201
        eargs[0] = receiver;
1✔
202
        for (int i = 0; i < args.size(); i++) {
1✔
203
            eargs[i + 1] = args.get(i).evaluate(globalState, localState);
1✔
204
        }
205
        return evaluateFunc(globalState, mostPrecise.getImplementation(), mc, eargs);
1✔
206
    }
207

208
    public static ILconst eval(ImMemberAccess ma, ProgramState globalState, LocalState localState) {
209
        ILconstObject receiver = globalState.toObject(ma.getReceiver().evaluate(globalState, localState));
1✔
210
        if (receiver == null) {
1✔
211
            throw new InterpreterException(ma.getTrace(), "Null pointer dereference");
×
212
        }
213
        List<Integer> indexes = ma.getIndexes().stream()
1✔
214
            .map(i -> ((ILconstInt) i.evaluate(globalState, localState)).getVal())
1✔
215
            .collect(Collectors.toList());
1✔
216
        return receiver.get(ma.getVar(), indexes).orElseGet(() -> ma.attrTyp().defaultValue());
1✔
217
    }
218

219
    public static ILconst eval(ImAlloc imAlloc, ProgramState globalState,
220
                               LocalState localState) {
221
        return globalState.allocate(imAlloc.getClazz(), imAlloc.attrTrace());
1✔
222
    }
223

224
    public static ILconst eval(ImDealloc imDealloc, ProgramState globalState,
225
                               LocalState localState) {
226
        ILconstObject obj = globalState.toObject(imDealloc.getObj().evaluate(globalState, localState));
1✔
227
        globalState.deallocate(obj, imDealloc.getClazz().getClassDef(), imDealloc.attrTrace());
1✔
228
        return ILconstNull.instance();
1✔
229
    }
230

231
    public static ILconst eval(ImInstanceof e, ProgramState globalState,
232
                               LocalState localState) {
233
        ILconstObject obj = globalState.toObject(e.getObj().evaluate(globalState, localState));
1✔
234
        return ILconstBool.instance(globalState.isInstanceOf(obj, e.getClazz().getClassDef(), e.attrTrace()));
1✔
235
    }
236

237
    public static ILconst eval(ImTypeIdOfClass e,
238
                               ProgramState globalState, LocalState localState) {
239
        return new ILconstInt(e.getClazz().getClassDef().attrTypeId());
1✔
240
    }
241

242
    public static ILconst eval(ImTypeIdOfObj e,
243
                               ProgramState globalState, LocalState localState) {
244
        ILconstObject obj = globalState.toObject(e.getObj().evaluate(globalState, localState));
1✔
245
        return new ILconstInt(globalState.getTypeId(obj, e.attrTrace()));
1✔
246
    }
247

248

249
    public static ILconst eval(ImGetStackTrace e, ProgramState globalState,
250
                               LocalState localState) {
251
        StringBuilder sb = new StringBuilder();
1✔
252
        globalState.getStackFrames().appendTo(sb);
1✔
253
        return new ILconstString(sb.toString());
1✔
254
    }
255

256
    public static ILconst eval(ImCompiletimeExpr expr, ProgramState globalState, LocalState localState) {
257
        // make sure that compiletime expression is only evaluated once
258
        ILconst res = expr.evaluationResult().get();
1✔
259
        if (res == null) {
1✔
260
            res = expr.getExpr().evaluate(globalState, localState);
1✔
261
            expr.evaluationResult().set(res);
1✔
262
        }
263
        return res;
1✔
264
    }
265

266
    public static AtomicReference<ILconst> compiletimeEvaluationResult(ImCompiletimeExpr imCompiletimeExpr) {
267
        return new AtomicReference<>();
1✔
268
    }
269

270
    public static ILaddress evaluateLvalue(ImVarAccess va, ProgramState globalState, LocalState localState) {
271
        ImVar v = va.getVar();
1✔
272
        State state;
273
        state = v.isGlobal() ? globalState : localState;
1✔
274
        return new ILaddress() {
1✔
275
            @Override
276
            public void set(ILconst value) {
277
                state.setVal(v, value);
1✔
278
            }
1✔
279

280
            @Override
281
            public ILconst get() {
282
                return state.getVal(v);
1✔
283
            }
284
        };
285
    }
286

287

288
    public static ILaddress evaluateLvalue(ImVarArrayAccess va, ProgramState globalState, LocalState localState) {
289
        ImVar v = va.getVar();
1✔
290
        State state;
291
        state = v.isGlobal() ? globalState : localState;
1✔
292
        List<Integer> indexes = va.getIndexes().stream()
1✔
293
            .map(ie -> ((ILconstInt) ie.evaluate(globalState, localState)).getVal())
1✔
294
            .collect(Collectors.toList());
1✔
295
        return new ILaddress() {
1✔
296
            @Override
297
            public void set(ILconst value) {
298
                state.setArrayVal(v, indexes, value);
1✔
299
            }
1✔
300

301
            @Override
302
            public ILconst get() {
303
                return state.getArrayVal(v, indexes);
×
304
            }
305
        };
306
    }
307

308
    public static ILaddress evaluateLvalue(ImTupleSelection ts, ProgramState globalState, LocalState localState) {
309
        ImExpr tupleExpr = ts.getTupleExpr();
1✔
310
        int tupleIndex = ts.getTupleIndex();
1✔
311
        if (tupleExpr instanceof ImLExpr) {
1✔
312
            ILaddress addr = ((ImLExpr) tupleExpr).evaluateLvalue(globalState, localState);
1✔
313
            return new ILaddress() {
1✔
314
                @Override
315
                public void set(ILconst value) {
316
                    ILconst val = addr.get();
1✔
317
                    ILconstTuple tuple = (ILconstTuple) val;
1✔
318
                    ILconstTuple updated = tuple.updated(tupleIndex, value);
1✔
319
                    addr.set(updated);
1✔
320
                }
1✔
321

322
                @Override
323
                public ILconst get() {
324
                    ILconstTuple tuple = (ILconstTuple) addr.get();
1✔
325
                    return tuple.getValue(tupleIndex);
1✔
326
                }
327
            };
328
        } else {
329
            ILconstTuple tupleValue = (ILconstTuple) tupleExpr.evaluate(globalState, localState);
×
330
            return new ILaddress() {
×
331
                @Override
332
                public void set(ILconst value) {
333
                    throw new InterpreterException(ts.attrTrace(), "Not a valid L-value in tuple-selection");
×
334
                }
335

336
                @Override
337
                public ILconst get() {
338
                    return tupleValue.getValue(tupleIndex);
×
339
                }
340
            };
341
        }
342
    }
343

344
    public static ILaddress evaluateLvalue(ImMemberAccess va, ProgramState globalState, LocalState localState) {
345
        ImVar v = va.getVar();
1✔
346
        ILconstObject receiver = globalState.toObject(va.getReceiver().evaluate(globalState, localState));
1✔
347
        List<Integer> indexes =
1✔
348
            va.getIndexes().stream()
1✔
349
                .map(ie -> ((ILconstInt) ie.evaluate(globalState, localState)).getVal())
1✔
350
                .collect(Collectors.toList());
1✔
351
        return new ILaddress() {
1✔
352
            @Override
353
            public void set(ILconst value) {
354
                receiver.set(v, indexes, value);
1✔
355
            }
1✔
356

357
            @Override
358
            public ILconst get() {
359
                return receiver.get(v, indexes)
1✔
360
                    .orElseGet(() -> va.attrTyp().defaultValue());
1✔
361
            }
362
        };
363
    }
364

365

366
    public static ILaddress evaluateLvalue(ImTupleExpr e, ProgramState globalState, LocalState localState) {
367
        List<ILaddress> addresses = new ArrayList<>();
×
368
        for (ImExpr lexpr : e.getExprs()) {
×
369
            ILaddress addr = ((ImLExpr) lexpr).evaluateLvalue(globalState, localState);
×
370
            addresses.add(addr);
×
371
        }
×
372
        return new ILaddress() {
×
373
            @Override
374
            public void set(ILconst value) {
375
                if (value instanceof ILconstTuple) {
×
376
                    ILconstTuple te = (ILconstTuple) value;
×
377
                    for (int i = 0; i < addresses.size(); i++) {
×
378
                        addresses.get(i).set(te.getValue(i));
×
379
                    }
380
                }
381
            }
×
382

383
            @Override
384
            public ILconst get() {
385
                return new ILconstTuple(addresses.stream()
×
386
                    .map(ILaddress::get)
×
387
                    .toArray(ILconst[]::new));
×
388
            }
389
        };
390
    }
391

392

393
    public static ILconst eval(ImTypeVarDispatch e, ProgramState globalState, LocalState localState) {
394
        // TODO store type arguments in localState with the required dispatch functions
395
        throw new InterpreterException(e.attrTrace(), "Cannot evaluate " + e);
×
396
    }
397

398
    public static ILconst eval(ImCast imCast, ProgramState globalState, LocalState localState) {
399
        ILconst res = imCast.getExpr().evaluate(globalState, localState);
1✔
400
        if (TypesHelper.isIntType(imCast.getToType())) {
1✔
401
            if (res instanceof ILconstObject) {
1✔
402
                return ILconstInt.create(((ILconstObject) res).getObjectId());
1✔
403
            }
404
            if (res instanceof IlConstHandle) {
1✔
405
                int id = globalState.getHandleMap().size() + 1;
×
406
                globalState.getHandleMap().put(id, (IlConstHandle) res);
×
407
                return ILconstInt.create(id);
×
408
            }
409
        }
410
        if (res instanceof ILconstInt) {
1✔
411
            if (imCast.getToType() instanceof ImClassType) {
1✔
412
                return globalState.getObjectByIndex(((ILconstInt) res).getVal());
1✔
413
            }
414
            if (imCast.getToType() instanceof IlConstHandle) {
1✔
415
                return globalState.getHandleByIndex(((ILconstInt) res).getVal());
×
416
            }
417
        }
418
        return res;
1✔
419
    }
420
}
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