More fun parsing stuff

- Start loading things via ShaderSources
 - More Span functionality
 - Parse function arguments
This commit is contained in:
Jozsef 2021-06-30 11:42:33 -07:00
parent 5b63d36ab0
commit 70b58c2838
10 changed files with 161 additions and 37 deletions

View file

@ -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<ResourceLocation, String> shaderSource = new HashMap<>();
private final Map<ResourceLocation, SourceFile> 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) {
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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<Variable> 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 + ")";
}
}

View file

@ -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<StructField> fields = new ArrayList<>(4);
Map<String, String> 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));

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.pipeline;
package com.jozufozu.flywheel.backend.pipeline.parse;
import com.jozufozu.flywheel.backend.loading.LayoutTag;

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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());
}
}

View file

@ -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;
}
}