diff --git a/src/main/java/com/jozufozu/flywheel/backend/ShaderSources.java b/src/main/java/com/jozufozu/flywheel/backend/ShaderSources.java index d4af509c9..0a847d23c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/ShaderSources.java +++ b/src/main/java/com/jozufozu/flywheel/backend/ShaderSources.java @@ -20,6 +20,7 @@ import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.backend.pipeline.SourceFile; import com.jozufozu.flywheel.event.ForgeEvents; import net.minecraft.client.Minecraft; @@ -61,6 +62,7 @@ public class ShaderSources implements ISelectiveResourceReloadListener { private static final Gson GSON = new GsonBuilder().create(); private final Map shaderSource = new HashMap<>(); + private final Map shaderSources = new HashMap<>(); private boolean shouldCrash; private final Backend backend; @@ -161,11 +163,12 @@ public class ShaderSources implements ISelectiveResourceReloadListener { try { IResource resource = manager.getResource(location); - String file = readToString(resource.getInputStream()); + String source = readToString(resource.getInputStream()); ResourceLocation name = ResourceUtil.removePrefixUnchecked(location, SHADER_DIR); - shaderSource.put(name, file); + shaderSource.put(name, source); + shaderSources.put(name, new SourceFile(this, name, source)); } catch (IOException e) { } diff --git a/src/main/java/com/jozufozu/flywheel/backend/pipeline/ShaderFunction.java b/src/main/java/com/jozufozu/flywheel/backend/pipeline/ShaderFunction.java deleted file mode 100644 index d9ca0564c..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/pipeline/ShaderFunction.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.jozufozu.flywheel.backend.pipeline; - -import com.jozufozu.flywheel.backend.pipeline.span.Span; - -import java.util.regex.Pattern; - -public class ShaderFunction { - - public static final Pattern assignment = Pattern.compile("(\\w+)\\s*="); - - private final Span returnType; - private final Span name; - private final Span body; - - public ShaderFunction(Span self, Span returnType, Span name, Span body) { - this.returnType = returnType; - this.name = name; - this.body = body; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/pipeline/SourceFile.java b/src/main/java/com/jozufozu/flywheel/backend/pipeline/SourceFile.java index 9d998c9f2..9f3863068 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/pipeline/SourceFile.java +++ b/src/main/java/com/jozufozu/flywheel/backend/pipeline/SourceFile.java @@ -10,6 +10,7 @@ import java.util.stream.Stream; import com.jozufozu.flywheel.backend.ShaderSources; +import com.jozufozu.flywheel.backend.pipeline.parse.ShaderFunction; import com.jozufozu.flywheel.backend.pipeline.span.ErrorSpan; import com.jozufozu.flywheel.backend.pipeline.span.Span; @@ -48,8 +49,9 @@ public class SourceFile { Matcher matcher = functionDeclaration.matcher(source); while (matcher.find()) { - Span type = Span.fromMatcherGroup(this, matcher, 1); - Span name = Span.fromMatcherGroup(this, matcher, 2); + Span type = Span.fromMatcher(this, matcher, 1); + Span name = Span.fromMatcher(this, matcher, 2); + Span args = Span.fromMatcher(this, matcher, 3); int blockStart = matcher.end(); int blockEnd = findEndOfBlock(blockStart); @@ -57,16 +59,16 @@ public class SourceFile { Span self; Span body; if (blockEnd > blockStart) { - self = new StringSpan(this, matcher.start(), blockEnd); + self = new StringSpan(this, matcher.start(), blockEnd + 1); body = new StringSpan(this, blockStart, blockEnd); } else { self = new ErrorSpan(this, matcher.start(), matcher.end()); body = new ErrorSpan(this, blockStart); } - ShaderFunction function = new ShaderFunction(self, type, name, body); + ShaderFunction function = new ShaderFunction(self, type, name, args, body); - functions.put(name.getValue(), function); + functions.put(name.get(), function); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/ShaderFunction.java b/src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/ShaderFunction.java new file mode 100644 index 000000000..c4b8c22a0 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/ShaderFunction.java @@ -0,0 +1,64 @@ +package com.jozufozu.flywheel.backend.pipeline.parse; + +import com.jozufozu.flywheel.backend.pipeline.span.Span; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class ShaderFunction { + + public static final Pattern argument = Pattern.compile("(\\w+)\\s+(\\w+)"); + public static final Pattern assignment = Pattern.compile("(\\w+)\\s*="); + + private final Span type; + private final Span name; + private final Span args; + private final Span body; + private final Span self; + + private final List parameters; + + public ShaderFunction(Span self, Span type, Span name, Span args, Span body) { + this.type = type; + this.name = name; + this.args = args; + this.body = body; + this.self = self; + + this.parameters = new ArrayList<>(); + + parseArguments(); + } + + public String call(String... args) { + return name + "(" + String.join(", ", args) + ");"; + } + + protected void parseArguments() { + if (args.isErr() || args.isEmpty()) return; + + Matcher arguments = argument.matcher(args.get()); + + while (arguments.find()) { + Span self = Span.fromMatcher(args, arguments); + Span type = Span.fromMatcher(args, arguments, 1); + Span name = Span.fromMatcher(args, arguments, 2); + + parameters.add(new Variable(self, type, name)); + } + } + + @Override + public String toString() { + + String p = parameters.stream() + .map(Variable::getType) + .map(Span::get) + .collect(Collectors.joining(",")); + + return name + "(" + p + ")"; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/pipeline/ShaderStruct.java b/src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/ShaderStruct.java similarity index 77% rename from src/main/java/com/jozufozu/flywheel/backend/pipeline/ShaderStruct.java rename to src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/ShaderStruct.java index 7f7f12fa6..682475986 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/pipeline/ShaderStruct.java +++ b/src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/ShaderStruct.java @@ -1,7 +1,6 @@ -package com.jozufozu.flywheel.backend.pipeline; +package com.jozufozu.flywheel.backend.pipeline.parse; import com.jozufozu.flywheel.backend.loading.Program; -import com.jozufozu.flywheel.backend.loading.TaggedField; import com.jozufozu.flywheel.backend.loading.TypeHelper; import com.jozufozu.flywheel.backend.pipeline.span.Span; @@ -17,14 +16,22 @@ public class ShaderStruct { // https://regexr.com/5t207 public static final Pattern struct = Pattern.compile("struct\\s+([\\w\\d]*)\\s*\\{([\\w\\d \\t#\\[\\](),;\\n]*)}\\s*;"); - public Span name; - public Span body; + public final Span self; + public final Span name; + public final Span body; List fields = new ArrayList<>(4); Map fields2Types = new HashMap<>(); public ShaderStruct(Span self, Span name, Span body) { - Matcher fielder = StructField.fieldPattern.matcher(body.getValue()); + this.self = self; + this.name = name; + this.body = body; + parseFields(); + } + + private void parseFields() { + Matcher fielder = StructField.fieldPattern.matcher(body.get()); while (fielder.find()) { fields.add(new StructField(fielder)); diff --git a/src/main/java/com/jozufozu/flywheel/backend/pipeline/StructField.java b/src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/StructField.java similarity index 92% rename from src/main/java/com/jozufozu/flywheel/backend/pipeline/StructField.java rename to src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/StructField.java index 180f7470a..e5643941c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/pipeline/StructField.java +++ b/src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/StructField.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.pipeline; +package com.jozufozu.flywheel.backend.pipeline.parse; import com.jozufozu.flywheel.backend.loading.LayoutTag; diff --git a/src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/Variable.java b/src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/Variable.java new file mode 100644 index 000000000..d0bcd343c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/pipeline/parse/Variable.java @@ -0,0 +1,24 @@ +package com.jozufozu.flywheel.backend.pipeline.parse; + +import com.jozufozu.flywheel.backend.pipeline.span.Span; + +public class Variable { + + private final Span self; + private final Span type; + private final Span name; + + public Variable(Span self, Span type, Span name) { + this.self = self; + this.type = type; + this.name = name; + } + + public Span getType() { + return type; + } + + public Span getName() { + return name; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/ErrorSpan.java b/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/ErrorSpan.java index 227328e50..aaa4ee143 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/ErrorSpan.java +++ b/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/ErrorSpan.java @@ -12,7 +12,17 @@ public class ErrorSpan extends Span { } @Override - public String getValue() { + public Span subSpan(int from, int to) { + return new ErrorSpan(in, start, end); // the sub-span of an error is an error in the same location + } + + @Override + public String get() { return ""; } + + @Override + public boolean isErr() { + return true; + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/Span.java b/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/Span.java index f3f06c658..bac622972 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/Span.java +++ b/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/Span.java @@ -4,6 +4,9 @@ import com.jozufozu.flywheel.backend.pipeline.SourceFile; import java.util.regex.Matcher; +/** + * A span of code in a {@link SourceFile}. + */ public abstract class Span { protected final SourceFile in; @@ -28,13 +31,34 @@ public abstract class Span { return end; } - public abstract String getValue(); + public boolean isEmpty() { + return start == end; + } - public static Span fromMatcherGroup(SourceFile src, Matcher m, int group) { + public abstract Span subSpan(int from, int to); + + public abstract String get(); + + public abstract boolean isErr(); + + @Override + public String toString() { + return get(); + } + + public static Span fromMatcher(SourceFile src, Matcher m, int group) { return new StringSpan(src, m.start(group), m.end(group)); } + public static Span fromMatcher(Span superSpan, Matcher m, int group) { + return superSpan.subSpan(m.start(group), m.end(group)); + } + public static Span fromMatcher(SourceFile src, Matcher m) { return new StringSpan(src, m.start(), m.end()); } + + public static Span fromMatcher(Span superSpan, Matcher m) { + return superSpan.subSpan(m.start(), m.end()); + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/StringSpan.java b/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/StringSpan.java index 434f0f649..3c09ef87f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/StringSpan.java +++ b/src/main/java/com/jozufozu/flywheel/backend/pipeline/span/StringSpan.java @@ -9,7 +9,17 @@ public class StringSpan extends Span { } @Override - public String getValue() { + public Span subSpan(int from, int to) { + return new StringSpan(in, start + from, start + to); + } + + @Override + public String get() { return in.getSource().substring(start, end); } + + @Override + public boolean isErr() { + return false; + } }