Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
cdced5d
decent improvements
Frotty Sep 24, 2025
1881f29
some more good ones
Frotty Sep 24, 2025
84fb523
restore determinism, fix tests
Frotty Sep 29, 2025
bed57ac
Optimize imports
Frotty Sep 29, 2025
343c032
Update de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/valida…
Frotty Sep 29, 2025
a513c86
Improve SCC processing, run all tests and fix them
Frotty Sep 29, 2025
b96882c
Merge branch 'perf-improvements' of https://github.com/wurstscript/Wu…
Frotty Sep 29, 2025
94c4f32
add RealRealMixed rewrites and tests
Frotty Sep 29, 2025
8c88fa7
Update de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/transl…
Frotty Sep 29, 2025
f1e094a
Update SimpleRewrites.java
Frotty Sep 29, 2025
fb48177
Merge branch 'perf-improvements' of https://github.com/wurstscript/Wu…
Frotty Sep 29, 2025
cc35acf
enable caching per default
Frotty Sep 29, 2025
16ac13c
enable compression for BuildMap command
Frotty Sep 29, 2025
5bf62d7
remove graph test logging and clear subtype cache
Frotty Sep 29, 2025
2d73659
A bunch more fixes. All tests passing
Frotty Oct 1, 2025
7be3107
Update config.yml
Frotty Oct 1, 2025
10aebe0
Update config.yml
Frotty Oct 1, 2025
672c7fd
remove debug prints
Frotty Oct 1, 2025
228f778
Update de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/transl…
Frotty Oct 1, 2025
73925cc
decent state
Frotty Oct 1, 2025
a8bfb86
some more good progress
Frotty Oct 1, 2025
52d96b6
some caching
Frotty Oct 1, 2025
af896df
Update NameLinks.java
Frotty Oct 1, 2025
0f2730b
dont use direct buffers, make test heap settings context aware
Frotty Oct 2, 2025
951d455
fix pipeline, remove parallel streams
Frotty Oct 2, 2025
1212d99
better vscode logging, fix caching
Frotty Oct 2, 2025
571d222
Update WLoggerDefault.java
Frotty Oct 2, 2025
7e0bedc
Update de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/interm…
Frotty Oct 2, 2025
b40dde4
Update de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/transl…
Frotty Oct 2, 2025
7bbf0cc
Update GetCompletions.java
Frotty Oct 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 0 additions & 104 deletions de.peeeq.wurstscript/META-INF/MANIFEST.MF

This file was deleted.

12 changes: 6 additions & 6 deletions de.peeeq.wurstscript/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ dependencies {
antlr "org.antlr:antlr4:4.13.1"

// tool for generating AST-classes
compileOnly 'com.github.peterzeller:abstractsyntaxgen:062a7ff178'
compileOnly 'com.github.peterzeller:abstractsyntaxgen:f4723157ec'

// JUnit for testing
testImplementation group: 'org.testng', name: 'testng', version: '7.8.0'
Expand Down Expand Up @@ -115,10 +115,10 @@ dependencies {
implementation 'com.github.albfernandez:juniversalchardet:2.4.0'

// Crigges' jmpq
implementation group: 'com.github.inwc3', name: 'jmpq3', version: '264c54cfc8'
implementation group: 'com.github.inwc3', name: 'jmpq3', version: '3183dd7680'

// Water's wc3 libs
implementation 'com.github.inwc3:wc3libs:00a29ccefd'
implementation 'com.github.inwc3:wc3libs:c3f131a0e5'

// The setup tool for wurst.build handling
implementation 'com.github.wurstscript:wurstsetup:475cc7fae8'
Expand All @@ -129,6 +129,8 @@ dependencies {
implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '6.7.0.202309050840-r'
implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit.ssh.apache', version: '6.7.0.202309050840-r'

implementation 'it.unimi.dsi:fastutil:8.5.16'

// Smallcheck testing library:
testImplementation group: 'com.github.peterzeller', name: 'java-smallcheck', version: '3f6a178ba7'
}
Expand Down Expand Up @@ -221,9 +223,7 @@ test {
// set minimal heap size required to run tests:
jvmArgs = ['-Xms256m']

useTestNG() {
suites 'src/test/resources/AllTestsSuite.xml'
}
useTestNG()
}

// delete the generated sources on clean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import de.peeeq.wurstscript.utils.Utils;
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
import org.eclipse.jdt.annotation.Nullable;

import java.util.*;
Expand All @@ -29,7 +30,6 @@ public TopsortResult<T> topSort(List<T> nodes) {
return new TopsortResult<>(false, result);
}


private @Nullable TopsortResult<T> topSort_add(List<T> result, Set<T> seen, List<T> seenStack, T n) {
for (int i = seenStack.size() - 1; i >= 0; i--) {
if (seenStack.get(i) == n) {
Expand All @@ -52,7 +52,6 @@ public TopsortResult<T> topSort(List<T> nodes) {
return null;
}


public static class TopsortResult<T> {
private final boolean isCycle;
private final List<T> result;
Expand All @@ -69,80 +68,89 @@ public boolean isCycle() {
public List<T> getResult() {
return result;
}


}


/**
* Like topsort, but will find bigger cycles
* Like topsort, but will find bigger cycles.
* This is an iterative implementation of the path-based strong component algorithm
* to prevent StackOverflowErrors on deep graphs.
* <p>
* See https://en.wikipedia.org/wiki/Path-based_strong_component_algorithm
*/
public Set<Set<T>> findStronglyConnectedComponents(List<T> nodes) {
// Stack S contains all the vertices that have not yet been assigned to a strongly connected component, in the order in which the depth-first search reaches the vertices.
Deque<T> s = new ArrayDeque<>();
// Stack P contains vertices that have not yet been determined to belong to different strongly connected components from each other
Deque<T> p = new ArrayDeque<>();
// It also uses a counter C of the number of vertices reached so far, which it uses to compute the preorder numbers of the vertices.
AtomicInteger c = new AtomicInteger();
AtomicInteger componentCount = new AtomicInteger();
Map<T, Integer> preorderNumber = new LinkedHashMap<>();
Map<T, Integer> component = new LinkedHashMap<>();

for (T v : nodes) {
if (!preorderNumber.containsKey(v)) {
findStronglyConnectedComponentsRec(v, s, p, c, preorderNumber, component, componentCount);
}
}
return ImmutableSet.copyOf(Utils.inverseMapToSet(component).values());
}
public List<List<T>> findStronglyConnectedComponents(List<T> nodes) {
Deque<T> s = new ArrayDeque<>(); // S stack
Deque<T> p = new ArrayDeque<>(); // P stack

int preorderCounter = 0;
int componentCounter = 0;

Object2IntLinkedOpenHashMap<T> preorder = new Object2IntLinkedOpenHashMap<>();
preorder.defaultReturnValue(-1);
Object2IntLinkedOpenHashMap<T> compId = new Object2IntLinkedOpenHashMap<>();
compId.defaultReturnValue(-1);

Deque<T> frameStack = new ArrayDeque<>(); // simulated recursion
Map<T, Iterator<T>> childIters = new HashMap<>(); // per-node child iterators

private void findStronglyConnectedComponentsRec(T v, Deque<T> s, Deque<T> p, AtomicInteger c, Map<T, Integer> preorderNumber, Map<T, Integer> component, AtomicInteger componentCount) {
List<List<T>> sccs = new ArrayList<>();

for (T start : nodes) {
if (preorder.getInt(start) != -1) continue;

// When the depth-first search reaches a vertex v, the algorithm performs the following steps:
// 1. Set the preorder number of v to C, and increment C.
preorderNumber.put(v, c.getAndIncrement());
frameStack.push(start);
while (!frameStack.isEmpty()) {
T v = frameStack.peek();

// 2. Push v onto S and also onto P.
s.push(v);
p.push(v);
// First time at v
if (preorder.getInt(v) == -1) {
preorder.put(v, preorderCounter++);
s.push(v);
p.push(v);
childIters.put(v, getIncidentNodes(v).iterator());
}

// 3. For each edge from v to a neighboring vertex w:
for (T w : getIncidentNodes(v)) {
if (!preorderNumber.containsKey(w)) {
// If the preorder number of w has not yet been assigned, recursively search w;
findStronglyConnectedComponentsRec(w, s, p, c, preorderNumber, component, componentCount);
} else {
// Otherwise, if w has not yet been assigned to a strongly connected component:
if (!component.containsKey(w)) {
// Repeatedly pop vertices from P until the top element of P has a preorder number less than or equal to the preorder number of w.
while (!p.isEmpty()
&& preorderNumber.getOrDefault(p.peek(), -1) > preorderNumber.get(w)) {
p.pop();
boolean descended = false;
Iterator<T> it = childIters.get(v);

while (it.hasNext()) {
T w = it.next();
int preW = preorder.getInt(w);
if (preW == -1) {
frameStack.push(w);
descended = true;
break;
} else if (compId.getInt(w) == -1) {
// w discovered but not assigned; shrink P
while (!p.isEmpty() && preorder.getInt(p.peek()) > preW) {
p.pop();
}
}
}
}
}
// 4. If v is the top element of P:
if (!p.isEmpty() && p.peek() == v) {
// Pop vertices from S until v has been popped, and assign the popped vertices to a new component.
Integer newComponent = componentCount.incrementAndGet();
while (true) {
T popped = s.pop();
component.put(popped, newComponent);
if (popped == v) {
break;

if (descended) continue;

// Post-order for v
frameStack.pop();
childIters.remove(v);

if (!p.isEmpty() && p.peek() == v) {
int newCid = componentCounter++;
ArrayList<T> cur = new ArrayList<>();
while (true) {
T x = s.pop();
compId.put(x, newCid);
cur.add(x);
if (x == v) break;
}
p.pop();

// Gabow emits SCCs in reverse-topological order
sccs.add(cur);
}
}
// Pop v from P.
T popped = p.pop();
assert popped == v;
}


return sccs;
}

public String generateDotFile(List<T> nodes) {
Expand All @@ -166,5 +174,4 @@ public String generateDotFile(List<T> nodes) {
sb.append("}\n");
return sb.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public abstract class ImmutableList<T> implements Iterable<T> {
abstract public ImmutableList<T> appFront(T elem);

/**
* adds an other ImmutableList to the end
* adds another ImmutableList to the end
*/
abstract public <R extends T> ImmutableList<T> cons(ImmutableList<R> other);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import de.peeeq.wurstio.utils.FileReading;
import de.peeeq.wurstio.utils.FileUtils;
import de.peeeq.wurstscript.*;
import de.peeeq.wurstscript.ast.Element;
import de.peeeq.wurstscript.ast.*;
import de.peeeq.wurstscript.ast.Element;
import de.peeeq.wurstscript.attributes.CompilationUnitInfo;
import de.peeeq.wurstscript.attributes.CompileError;
import de.peeeq.wurstscript.attributes.ErrorHandler;
Expand Down Expand Up @@ -49,7 +49,6 @@
import static de.peeeq.wurstio.CompiletimeFunctionRunner.FunctionFlagToRun.CompiletimeFunctions;
import static de.peeeq.wurstscript.WurstOperator.PLUS;
import static de.peeeq.wurstscript.translation.imtranslation.FunctionFlagEnum.IS_EXTERN;
import static de.peeeq.wurstscript.translation.imtranslation.FunctionFlagEnum.IS_NATIVE;

public class WurstCompilerJassImpl implements WurstCompiler {

Expand Down Expand Up @@ -472,8 +471,13 @@ public JassProg transformProgToJass() {

// eliminate tuples
beginPhase(6, "eliminate tuples");
timeTaker.measure("flatten", () -> getImProg().flatten(imTranslator2));
timeTaker.measure("kill tuples", () -> EliminateTuples.eliminateTuplesProg(getImProg(), imTranslator2));
timeTaker.beginPhase("flatten");
getImProg().flatten(imTranslator2);
timeTaker.endPhase();
timeTaker.beginPhase("kill tuples");
EliminateTuples.eliminateTuplesProg(getImProg(), imTranslator2);
timeTaker.endPhase();

getImTranslator().assertProperties(AssertProperty.NOTUPLES);

printDebugImProg("./test-output/im " + stage++ + "_withouttuples.im");
Expand Down
Loading