Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

wurstscript / WurstScript / 1005

21 Mar 2019 - 22:31 coverage decreased (-0.09%) to 61.245%
1005

Pull #822

travis-ci

9181eb84f9c35729a3bad740fb7f9d93?size=18&default=identiconweb-flow
more new bug fixes
Pull Request #822: WIP: support for persisting objects in compiletime expressions

14931 of 24379 relevant lines covered (61.25%)

0.61 hits per line

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

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

3
import com.google.common.collect.Lists;
4
import de.peeeq.wurstio.jassinterpreter.InterpreterException;
5
import de.peeeq.wurstscript.WLogger;
6
import de.peeeq.wurstscript.WurstOperator;
7
import de.peeeq.wurstscript.ast.PackageOrGlobal;
8
import de.peeeq.wurstscript.ast.VarDef;
9
import de.peeeq.wurstscript.ast.WPackage;
10
import de.peeeq.wurstscript.intermediatelang.*;
11
import de.peeeq.wurstscript.jassIm.*;
12
import de.peeeq.wurstscript.translation.imtranslation.EliminateGenerics;
13
import de.peeeq.wurstscript.translation.imtranslation.ImPrinter;
14
import de.peeeq.wurstscript.types.TypesHelper;
15
import org.eclipse.jdt.annotation.Nullable;
16

17
import java.util.ArrayList;
18
import java.util.Collections;
19
import java.util.List;
20
import java.util.concurrent.atomic.AtomicReference;
21
import java.util.stream.Collectors;
22
import java.util.stream.Stream;
23

UNCOV
24
public class EvaluateExpr {
!
25

26
    public static ILconst eval(ImBoolVal e, ProgramState globalState, LocalState localState) {
27
        return ILconstBool.instance(e.getValB());
1×
28
    }
29

30
    public static ILconst eval(ImFuncRef e, ProgramState globalState, LocalState localState) {
31
        return new ILconstFuncRef(e.getFunc());
1×
32
    }
33

34
    public static @Nullable ILconst eval(ImFunctionCall e, ProgramState globalState, LocalState localState) {
35
        ImFunction f = e.getFunc();
1×
36
        ImExprs arguments = e.getArguments();
1×
37
        return evaluateFunc(globalState, localState, f, arguments, e);
1×
38
    }
39

40
    public static @Nullable ILconst evaluateFunc(ProgramState globalState,
41
                                                 LocalState localState, ImFunction f, List<ImExpr> args2, Element trace) {
42
        ILconst[] args = new ILconst[args2.size()];
1×
43
        for (int i = 0; i < args2.size(); i++) {
1×
44
            args[i] = args2.get(i).evaluate(globalState, localState);
1×
45
        }
46
        return evaluateFunc(globalState, f, trace, args);
1×
47
    }
48

49
    @Nullable
50
    private static ILconst evaluateFunc(ProgramState globalState, ImFunction f, Element trace, ILconst[] args) {
51
        LocalState r = ILInterpreter.runFunc(globalState, f, trace, args);
1×
52
        return r.getReturnVal();
1×
53
    }
54

55
    public static ILconst eval(ImIntVal e, ProgramState globalState, LocalState localState) {
56
        return new ILconstInt(e.getValI());
1×
57
    }
58

59
    public static ILconst eval(ImNull e, ProgramState globalState, LocalState localState) {
60
        return ILconstNull.instance();
1×
61
    }
62

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

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

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

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

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

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

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

113
    }
114

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

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

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

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

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

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

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

182
        globalState.assertAllocated(receiver, mc.attrTrace());
1×
183

184

185
        List<ImExpr> args = mc.getArguments();
1×
186

187

188
        ImMethod mostPrecise = mc.getMethod();
1×
189

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

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

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

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

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

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

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

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

249

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

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

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

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

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

288

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

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

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

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

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

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

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

366

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

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

393

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

399
    public static ILconst eval(ImCast imCast, ProgramState globalState, LocalState localState) {
400
        ILconst res = imCast.getExpr().evaluate(globalState, localState);
1×
401
        if (TypesHelper.isIntType(imCast.getToType())) {
1×
402
            if (res instanceof ILconstObject) {
1×
403
                return ILconstInt.create(((ILconstObject) res).getObjectId());
1×
404
            }
405
        }
406
        if (imCast.getToType() instanceof ImClassType) {
1×
407
            if (res instanceof ILconstInt) {
1×
408
                return globalState.getObjectByIndex(((ILconstInt) res).getVal());
1×
409
            }
410
        }
411
        return res;
1×
412
    }
413
}
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2022 Coveralls, Inc