Skip to content

Commit 085bbb9

Browse files
authored
Refactoring tuple and array translation (#741)
With the rewrite it is finally possible to use tuples in multi-dimensional arrays. This should fix #739 #572 #364.
1 parent 499fee4 commit 085bbb9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1876
-1772
lines changed

de.peeeq.wurstscript/parserspec/jass_im.parseq

Lines changed: 39 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ ImVar(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImType type
1616

1717
ImType =
1818
ImSimpleType(String typename)
19-
| ImArrayType(String typename)
20-
| ImArrayTypeMulti(String typename, java.util.List<Integer> arraySize)
19+
| ImArrayType(ref ImType entryType)
20+
| ImArrayTypeMulti(ref ImType entryType, java.util.List<Integer> arraySize)
2121
| ImTupleType(java.util.List<ImType> types, java.util.List<String> names)
22-
| ImTupleArrayType(java.util.List<ImType> types, java.util.List<String> names)
2322
| ImVoid()
2423

2524
ImFunction(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace,
@@ -52,11 +51,7 @@ ImStmt =
5251
| ImLoop(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImStmts body)
5352
| ImExitwhen(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExpr condition)
5453
| ImReturn(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExprOpt returnValue)
55-
| ImSet(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImVar left, ImExpr right)
56-
| ImSetTuple(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImVar left, int tupleIndex, ImExpr right)
57-
| ImSetArray(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImVar left, ImExpr index, ImExpr right)
58-
| ImSetArrayMulti(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImVar left, ImExprs indices, ImExpr right)
59-
| ImSetArrayTuple(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImVar left, ImExpr index, int tupleIndex, ImExpr right)
54+
| ImSet(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImLExpr left, ImExpr right)
6055
| ImExpr
6156
| ImVarargLoop(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImStmts body, ref ImVar loopVar)
6257

@@ -72,26 +67,29 @@ ImFlatExprOpt =
7267
ImExprs * ImExpr
7368

7469
ImExpr =
75-
ImStatementExpr(ImStmts statements, ImExpr expr)
76-
| ImFlatExpr
77-
78-
ImFlatExpr =
7970
ImCall
80-
| ImVarAccess(ref ImVar var)
81-
| ImVarArrayAccess(ref ImVar var, ImExpr index)
82-
| ImVarArrayMultiAccess(ref ImVar var, ImExpr index1, ImExpr index2)
83-
| ImTupleExpr(ImExprs exprs)
84-
| ImTupleSelection(ImExpr tupleExpr, int tupleIndex)
8571
| ImClassRelatedExpr
8672
| ImConst
8773
| ImGetStackTrace()
8874
| ImCompiletimeExpr(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExpr expr, int executionOrderIndex)
89-
75+
| ImLExpr
76+
77+
// an expression which can be used on the left hand side of an assignment
78+
ImLExpr =
79+
ImVarAccess(ref ImVar var)
80+
| ImVarArrayAccess(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImVar var, ImExprs indexes)
81+
| ImTupleSelection(ImExpr tupleExpr, int tupleIndex) // can only be used as L-value if tupleExpr is l-exprs
82+
| ImMemberAccess
83+
| ImTupleExpr(ImExprs exprs) // can only be used as L-value if exprs only contains l-exprs
84+
| ImStatementExpr(ImStmts statements, ImExpr expr) // can only be used as L-value if expr only contains l-exprs
85+
86+
87+
9088
ImClassRelatedExpr =
9189
ImMethodCall(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImMethod method, ImExpr receiver, ImExprs arguments, boolean tuplesEliminated)
9290
| ImAlloc(ref ImClass clazz)
9391
| ImDealloc(ref ImClass clazz, ImExpr obj)
94-
| ImMemberAccess(ImExpr receiver, ref ImVar var)
92+
| ImMemberAccess(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExpr receiver, ref ImVar var)
9593
| ImInstanceof(ImExpr obj, ref ImClass clazz)
9694
| ImTypeIdOfObj(ImExpr obj, ref ImClass clazz)
9795
| ImTypeIdOfClass(ref ImClass clazz)
@@ -117,12 +115,10 @@ JassImElementWithName = ImVar | ImFunction | ImClass | ImMethod
117115

118116
ElementWithTrace = ImVar | ImFunction | ImClass | ImMethod | ImIf | ImLoop | ImExitwhen | ImReturn
119117
| ImSet | ImSetTuple | ImSetArray | ImSetArrayMulti | ImSetArrayTuple
120-
| ImMethodCall | ImFunctionCall | ImCompiletimeExpr
118+
| ImMethodCall | ImFunctionCall | ImCompiletimeExpr | ImVarArrayAccess | ImMemberAccess
121119

122120
ElementWithTypes = ImTupleType | ImTupleArrayType
123121

124-
ElementWithLeft = ImSet| ImSetTuple| ImSetArray| ImSetArrayMulti| ImSetArrayTuple
125-
126122
ElementWithVar = ImVarAccess | ImVarArrayAccess | ImVarArrayMultiAccess | ImMemberAccess
127123

128124

@@ -160,41 +156,18 @@ ImStmt.flatten(
160156
)
161157
returns de.peeeq.wurstscript.translation.imtranslation.Flatten.Result
162158
implemented by de.peeeq.wurstscript.translation.imtranslation.Flatten.flatten
163-
164-
ImStmt.attrPurity
159+
160+
ImLExpr.flattenL(
161+
de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator,
162+
de.peeeq.wurstscript.jassIm.ImFunction f
163+
)
164+
returns de.peeeq.wurstscript.translation.imtranslation.Flatten.ResultL
165+
implemented by de.peeeq.wurstscript.translation.imtranslation.Flatten.flattenL
166+
167+
ImStmt.attrPurity()
165168
returns de.peeeq.wurstscript.translation.imtranslation.purity.PurityLevel
166169
implemented by de.peeeq.wurstscript.translation.imtranslation.purity.PurityLevels.calculate
167170

168-
ImProg.eliminateTuples(de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator)
169-
returns void
170-
implemented by de.peeeq.wurstscript.translation.imtranslation.EliminateTuples.eliminateTuplesProg
171-
172-
ImFunction.eliminateTuples(de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator)
173-
returns void
174-
implemented by de.peeeq.wurstscript.translation.imtranslation.EliminateTuples.eliminateTuplesFunc
175-
176-
ImStmt.eliminateTuples(
177-
de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator,
178-
de.peeeq.wurstscript.jassIm.ImFunction f
179-
)
180-
returns ImStmt
181-
implemented by de.peeeq.wurstscript.translation.imtranslation.EliminateTuples.eliminateTuples
182-
183-
ImExpr.eliminateTuplesExpr(
184-
de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator,
185-
de.peeeq.wurstscript.jassIm.ImFunction f
186-
)
187-
returns ImExpr
188-
implemented by de.peeeq.wurstscript.translation.imtranslation.EliminateTuples.eliminateTuplesExpr
189-
190-
ImExprOpt.eliminateTuplesExprOpt(
191-
de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator,
192-
de.peeeq.wurstscript.jassIm.ImFunction f
193-
)
194-
returns ImExprOpt
195-
implemented by de.peeeq.wurstscript.translation.imtranslation.EliminateTuples.eliminateTuplesExpr
196-
197-
198171
ImStmts.translate(
199172
java.util.List<de.peeeq.wurstscript.jassAst.JassStatement> stmts,
200173
de.peeeq.wurstscript.jassAst.JassFunction f,
@@ -221,7 +194,7 @@ ImConst.equalValue(ImConst other)
221194
returns boolean
222195
implemented by de.peeeq.wurstscript.translation.imtojass.Equality.equalValue
223196

224-
ImExpr.attrTyp
197+
ImExpr.attrTyp()
225198
returns ImType
226199
implemented by de.peeeq.wurstscript.translation.imtojass.ImAttrType.getType
227200

@@ -237,7 +210,7 @@ ImType.translateType()
237210
returns String
238211
implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.translateType
239212

240-
ImVar.isGlobal
213+
ImVar.isGlobal()
241214
returns boolean
242215
implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.isGlobal
243216

@@ -267,6 +240,13 @@ ImExpr.evaluate(de.peeeq.wurstscript.intermediatelang.interpreter.ProgramState g
267240
returns de.peeeq.wurstscript.intermediatelang.ILconst
268241
implemented by de.peeeq.wurstscript.intermediatelang.interpreter.EvaluateExpr.eval
269242

243+
ImLExpr.evaluateLvalue(de.peeeq.wurstscript.intermediatelang.interpreter.ProgramState globalState
244+
, de.peeeq.wurstscript.intermediatelang.interpreter.LocalState localState)
245+
returns de.peeeq.wurstscript.intermediatelang.ILaddress
246+
implemented by de.peeeq.wurstscript.intermediatelang.interpreter.EvaluateExpr.evaluateLvalue
247+
248+
249+
270250
ImCompiletimeExpr.evaluationResult
271251
returns java.util.concurrent.atomic.AtomicReference<de.peeeq.wurstscript.intermediatelang.ILconst>
272252
implemented by de.peeeq.wurstscript.intermediatelang.interpreter.EvaluateExpr.compiletimeEvaluationResult
@@ -352,5 +332,7 @@ ImProg.attrSubclasses
352332
returns com.google.common.collect.Multimap<ImClass, ImClass>
353333
implemented by de.peeeq.wurstscript.translation.imtranslation.Subclasses.calculate
354334

355-
335+
ImLExpr.isUsedAsLValue()
336+
returns boolean
337+
implemented by de.peeeq.wurstscript.translation.imtranslation.LValues.isUsedAsLValue
356338

de.peeeq.wurstscript/parserspec/wurstscript.parseq

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ WStatement = ActionStatement | ControlflowStatement | EndFunctionStatement(de.pe
129129
ActionStatement =
130130
StmtSkip(de.peeeq.wurstscript.parser.WPos source)
131131
| LocalVarDef
132-
| StmtSet(de.peeeq.wurstscript.parser.WPos source, NameRef updatedExpr, Expr right)
132+
| StmtSet(de.peeeq.wurstscript.parser.WPos source, LExpr updatedExpr, Expr right)
133133
| StmtCall
134134
| StmtErr(de.peeeq.wurstscript.parser.WPos source)
135135
| ExprMemberVar
@@ -166,7 +166,7 @@ StmtForRange =
166166
| StmtForRangeDown(de.peeeq.wurstscript.parser.WPos source, LocalVarDef loopVar, Expr to, Expr step, WStatements body)
167167

168168
Expr =
169-
NameRef
169+
LExpr
170170
| FunctionCall
171171
| ExprBinary(de.peeeq.wurstscript.parser.WPos source, Expr left, de.peeeq.wurstscript.WurstOperator op, Expr right)
172172
| ExprUnary(de.peeeq.wurstscript.parser.WPos source, de.peeeq.wurstscript.WurstOperator opU, Expr right)
@@ -232,6 +232,9 @@ IdentifierWithTypeParamDefs(de.peeeq.wurstscript.parser.WPos source, Identifier
232232
// a reference to a variable, needs a varName:String attribute
233233
NameRef = ExprVarArrayAccess | ExprVarAccess | ExprMemberVar | ExprMemberArrayVar
234234

235+
// an expression that can be used on the left-hand side of an assignment
236+
LExpr = NameRef
237+
235238
VarDef =
236239
GlobalOrLocalVarDef
237240
| WParameter
@@ -433,7 +436,7 @@ FunctionCall.attrImplicitParameter
433436
returns OptExpr
434437
implemented by de.peeeq.wurstscript.attributes.AttrImplicitParameter.getImplicitParameter
435438

436-
NameRef.attrImplicitParameter
439+
LExpr.attrImplicitParameter
437440
returns OptExpr
438441
implemented by de.peeeq.wurstscript.attributes.AttrImplicitParameter.getImplicitParameter
439442

@@ -712,6 +715,13 @@ StmtForEach.attrCloseFunc
712715
returns void
713716
implemented by de.peeeq.wurstscript.translation.imtranslation.TLDTranslation.translate
714717

718+
LExpr.imTranslateExprLvalue(
719+
de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator,
720+
de.peeeq.wurstscript.jassIm.ImFunction f
721+
)
722+
returns de.peeeq.wurstscript.jassIm.ImLExpr
723+
implemented by de.peeeq.wurstscript.translation.imtranslation.ExprTranslation.translateLvalue
724+
715725
Expr.imTranslateExpr(
716726
de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator,
717727
de.peeeq.wurstscript.jassIm.ImFunction f
@@ -763,11 +773,11 @@ FunctionLike.attrHasEmptyBody()
763773

764774
// Naming:
765775

766-
NameRef.attrNameLink
776+
LExpr.attrNameLink
767777
returns de.peeeq.wurstscript.attributes.names.NameLink
768778
implemented by de.peeeq.wurstscript.attributes.AttrNameDef.calculate
769779

770-
NameRef.attrNameDef
780+
LExpr.attrNameDef
771781
returns NameDef
772782
implemented by de.peeeq.wurstscript.attributes.AttrNameDef.calculateDef
773783

@@ -1017,7 +1027,7 @@ ExprNewObject.getTypeName()
10171027
returns String
10181028
implemented by de.peeeq.wurstscript.attributes.SmallHelpers.getTypeName
10191029

1020-
NameRef.getVarName()
1030+
LExpr.getVarName()
10211031
returns String
10221032
implemented by de.peeeq.wurstscript.attributes.SmallHelpers.getVarName
10231033

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/CompiletimeFunctionRunner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ private ImExpr constantToExprHashtable(ImCompiletimeExpr cte, Element trace, Arr
255255
WPos errorPos = trace.attrErrorPos();
256256
ImFunction initHashtable = findNative("InitHashtable", errorPos);
257257
ImStmts stmts = JassIm.ImStmts(
258-
JassIm.ImSet(trace, htVar, JassIm.ImFunctionCall(trace, initHashtable, JassIm.ImExprs(), false, CallType.NORMAL))
258+
JassIm.ImSet(trace, JassIm.ImVarAccess(htVar), JassIm.ImFunctionCall(trace, initHashtable, JassIm.ImExprs(), false, CallType.NORMAL))
259259
);
260260

261261
// we have to collect all values after all compiletime functions have run, so use delayedActions

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/WurstCompilerJassImpl.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,6 @@ public void checkProg(WurstModel model, List<CompilationUnit> toCheck) {
394394
new EliminateClasses(imTranslator2, imProg2, !runArgs.isUncheckedDispatch()).eliminateClasses();
395395
imTranslator2.assertProperties();
396396
printDebugImProg("./test-output/im " + stage++ + "_classesEliminated.im");
397-
new MultiArrayEliminator(imProg2, imTranslator2).run();
398-
imTranslator2.assertProperties();
399397

400398
new VarargEliminator(imProg2).run();
401399
printDebugImProg("./test-output/im " + stage++ + "_varargEliminated.im");
@@ -426,11 +424,15 @@ public void checkProg(WurstModel model, List<CompilationUnit> toCheck) {
426424
// eliminate tuples
427425
beginPhase(6, "eliminate tuples");
428426
getImProg().flatten(imTranslator2);
429-
getImProg().eliminateTuples(imTranslator2);
427+
EliminateTuples.eliminateTuplesProg(getImProg(), imTranslator2);
430428
getImTranslator().assertProperties(AssertProperty.NOTUPLES);
431429

432430
printDebugImProg("./test-output/im " + stage++ + "_withouttuples.im");
433431

432+
new MultiArrayEliminator(imProg2, imTranslator2).run();
433+
printDebugImProg("./test-output/im " + stage++ + "_withoutmultiarrays.im");
434+
imTranslator2.assertProperties();
435+
434436
beginPhase(7, "remove func refs");
435437
new FuncRefRemover(imProg2, imTranslator2).run();
436438

@@ -469,10 +471,12 @@ public void checkProg(WurstModel model, List<CompilationUnit> toCheck) {
469471
beginPhase(12, "froptimize");
470472
optimizer.optimize();
471473

474+
optimizer.removeGarbage();
475+
imProg.flatten(imTranslator);
472476
printDebugImProg("./test-output/im " + stage++ + "_afteroptimize.im");
473477
}
474478

475-
optimizer.removeGarbage();
479+
476480

477481
// translate flattened intermediate lang to jass:
478482

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package de.peeeq.wurstscript.intermediatelang;
2+
3+
/**
4+
*
5+
*/
6+
public interface ILaddress {
7+
void set(ILconst value);
8+
ILconst get();
9+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package de.peeeq.wurstscript.intermediatelang;
2+
3+
import de.peeeq.wurstscript.types.WurstType;
4+
import de.peeeq.wurstscript.types.WurstTypeString;
5+
6+
import java.util.Map;
7+
import java.util.TreeMap;
8+
import java.util.function.Supplier;
9+
10+
public class ILconstArray extends ILconstAbstract {
11+
12+
private final Map<Integer, ILconst> values = new TreeMap<>(); // including the quotes
13+
private final Supplier<ILconst> defaultValue;
14+
15+
public ILconstArray(Supplier<ILconst> defaultValue) {
16+
this.defaultValue = defaultValue;
17+
}
18+
19+
@Override
20+
public String print() {
21+
StringBuilder s = new StringBuilder();
22+
s.append("[");
23+
for (Map.Entry<Integer, ILconst> e : values.entrySet()) {
24+
if (s.length() > 1) {
25+
s.append(", ");
26+
}
27+
s.append(e.getKey());
28+
s.append(": ");
29+
s.append(e.getValue());
30+
}
31+
s.append("]");
32+
return s.toString();
33+
}
34+
35+
36+
@Override
37+
public boolean isEqualTo(ILconst other) {
38+
return other == this;
39+
}
40+
41+
public void set(int index, ILconst value) {
42+
values.put(index, value);
43+
}
44+
45+
public ILconst get(int index) {
46+
return values.computeIfAbsent(index, i -> defaultValue.get());
47+
}
48+
49+
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/ILconstTuple.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,7 @@ public class ILconstTuple extends ILconstAbstract {
1313
private final ILconst[] values;
1414

1515
public ILconstTuple(ILconst... values) {
16-
this.values = Arrays.stream(values)
17-
.flatMap(c -> {
18-
if (c instanceof ILconstTuple) {
19-
return Arrays.stream(((ILconstTuple) c).values);
20-
} else {
21-
return Stream.of(c);
22-
}
23-
}).toArray(ILconst[]::new);
16+
this.values = values;
2417
}
2518

2619

0 commit comments

Comments
 (0)