Skip to content

Commit

Permalink
add string literals as an optional feature,
Browse files Browse the repository at this point in the history
add tests for usage of string literals,
add snapshot test cases for string literals,
improved handling of strings for directives
  • Loading branch information
douira committed Jul 11, 2024
1 parent 25851e0 commit fc657b0
Show file tree
Hide file tree
Showing 18 changed files with 472 additions and 26 deletions.
14 changes: 10 additions & 4 deletions glsl-transformer/src/main/antlr/GLSLLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,8 @@ NR_LINE:
NR: '#' -> pushMode(NR_Mode);
IDENTIFIER: IDENTIFIER_frag;

STRING_START: '"' {enableStrings}? -> pushMode(StringLiteral);

fragment LINE_COMMENT_frag: '//' NO_NEWLINE*;

//performance testing suggests that using the .*? here is fine, alternatives were slower
Expand Down Expand Up @@ -418,12 +420,16 @@ NR_EOL: NEWLINE -> popMode;
NR_WS: WS_frag -> channel(WHITESPACE);

mode String;
S_CONTENT: ~["\r\n]+;
S_STRING_END: '"' -> popMode;
NR_S_CONTENT: ~["\r\n]+;
NR_S_STRING_END: '"' -> popMode;
mode StringLiteral;
SL_CONTENT: ~["]+;
SL_STRING_END: '"' -> popMode;
mode StringAngle;
S_CONTENT_ANGLE: ~[>\r\n]+;
S_STRING_END_ANGLE: '>' -> popMode;
NR_SA_CONTENT: ~[>\r\n]+;
NR_SA_STRING_END: '>' -> popMode;
mode CustomDirective;
C_LINE_COMMENT: LINE_COMMENT_frag -> channel(COMMENTS);
Expand Down
5 changes: 3 additions & 2 deletions glsl-transformer/src/main/antlr/GLSLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ customDirective: NR NR_CUSTOM content = C_CONTENT? C_EOL;

includeDirective:
NR NR_INCLUDE (
NR_STRING_START content = S_CONTENT? S_STRING_END
| angleStart = NR_STRING_START_ANGLE content = S_CONTENT_ANGLE? S_STRING_END_ANGLE
NR_STRING_START content = NR_S_CONTENT? NR_S_STRING_END
| angleStart = NR_STRING_START_ANGLE content = NR_SA_CONTENT? NR_SA_STRING_END
) NR_EOL;

layoutDefaults:
Expand All @@ -112,6 +112,7 @@ finiteExpression:
| FLOAT32CONSTANT
| FLOAT64CONSTANT
| BOOLCONSTANT
| STRING_START SL_CONTENT* SL_STRING_END
) # literalExpression
//only the grouping expression allows the sequence expression since the sequence expression
//has the lowest precendence and not putting it in parentheses would simply create a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class LiteralExpression extends TerminalExpression {
private long integerValue;
private IntegerFormat integerFormat;
private double floatingValue;
private String stringValue;

public enum IntegerFormat {
DECIMAL(10),
Expand All @@ -28,17 +29,23 @@ public enum IntegerFormat {

private LiteralExpression(
Type literalType,
String stringValue,
boolean booleanValue,
long integerValue,
IntegerFormat integerFormat,
double floatingValue) {
this.literalType = literalType;
this.stringValue = stringValue;
this.booleanValue = booleanValue;
this.integerValue = integerValue;
this.integerFormat = integerFormat;
this.floatingValue = floatingValue;
}

public LiteralExpression(String stringValue) {
setString(stringValue);
}

public LiteralExpression(boolean booleanValue) {
setBoolean(booleanValue);
}
Expand Down Expand Up @@ -101,6 +108,31 @@ public Type.NumberType getNumberType() {
return literalType.getNumberType();
}

public String getString() {
return stringValue;
}

public void setString(String stringValue) {
if (stringValue == null) {
throw new IllegalArgumentException("String value cannot be null!");
}
this.stringValue = stringValue;
this.booleanValue = false;
this.integerValue = 0;
this.floatingValue = 0;
this.literalType = Type.STRING;
}

public void changeString(String stringValue) {
if (!isString()) {
throw new IllegalStateException("Literal type must be a string!");
}
if (stringValue == null) {
throw new IllegalArgumentException("String value cannot be null!");
}
this.stringValue = stringValue;
}

public boolean getBoolean() {
return booleanValue;
}
Expand Down Expand Up @@ -195,6 +227,10 @@ public void changeFloating(double floatingValue) {
this.floatingValue = floatingValue;
}

public boolean isString() {
return literalType == Type.STRING;
}

public boolean isBoolean() {
return getNumberType() == NumberType.BOOLEAN;
}
Expand Down Expand Up @@ -278,7 +314,7 @@ public void exitNode(ASTListener listener) {

@Override
public LiteralExpression clone() {
return new LiteralExpression(literalType, booleanValue, integerValue, integerFormat, floatingValue);
return new LiteralExpression(literalType, stringValue, booleanValue, integerValue, integerFormat, floatingValue);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public Void visitIncludeDirective(IncludeDirective node) {
if (content != null) {
emitLiteral(content);
}
emitType(node.isAngleBrackets ? GLSLLexer.S_STRING_END_ANGLE : GLSLLexer.S_STRING_END);
emitType(node.isAngleBrackets ? GLSLLexer.NR_SA_STRING_END : GLSLLexer.NR_S_STRING_END);
emitExactNewline();
return null;
}
Expand Down Expand Up @@ -327,6 +327,11 @@ public Void visitLiteralExpression(LiteralExpression node) {
// expression
var numberType = node.getNumberType();
switch (numberType) {
case STRING:
emitType(GLSLLexer.STRING_START);
emitLiteral(node.getString());
emitType(GLSLLexer.SL_STRING_END);
break;
case BOOLEAN:
emitLiteral(node.getBoolean() ? "true" : "false");
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ public class ParserToken extends PrintToken {
put(GLSLLexer.NR_COLON, ":");
put(GLSLLexer.NR_STRING_START, "\"");
put(GLSLLexer.NR_STRING_START_ANGLE, "<");
put(GLSLLexer.S_STRING_END, "\"");
put(GLSLLexer.S_STRING_END_ANGLE, ">");
put(GLSLLexer.STRING_START, "\"");
put(GLSLLexer.SL_STRING_END, "\"");
put(GLSLLexer.NR_S_STRING_END, "\"");
put(GLSLLexer.NR_SA_STRING_END, ">");
put(GLSLLexer.GT_OP, ">");
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,27 @@ public UnaryExpression visitPrefixExpression(PrefixExpressionContext ctx) {
public LiteralExpression visitLiteralExpression(LiteralExpressionContext ctx) {
// start and end token are the same as there is one token in this rule
var content = ctx.getStart();

// special case for string type
if (content.getType() == GLSLLexer.STRING_START) {
if (ctx.children.size() == 2) {
return new LiteralExpression("");
}

if (ctx.children.size() == 3) {
return new LiteralExpression(ctx.SL_CONTENT(0).getText());
}

// multi-part string
var builder = new StringBuilder();
for (var child : ctx.children) {
if (child instanceof TerminalNode terminal && terminal.getSymbol().getType() == GLSLLexer.SL_CONTENT) {
builder.append(child.getText());
}
}
return new LiteralExpression(builder.toString());
}

var literalType = Type.ofLiteralTokenType(content.getType());
var tokenContent = content.getText();
var numberType = literalType.getNumberType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ default R visitReferenceExpression(ReferenceExpression node) {

default R visitLiteralExpression(LiteralExpression node) {
var result = visitData(node.getType());
result = visitData(result, node.getNumber());
result = visitData(result, node.isString() ? node.getString() : node.getNumber());
return node.isInteger() ? visitData(result, node.getIntegerFormat()) : result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public abstract class VersionedGLSLLexer extends Lexer {
public Version version = Version.latest;
public boolean enableCustomDirective = false;
public boolean enableIncludeDirective = false;
public boolean enableStrings = false;
// public Profile profile;
// public EnumSet<Extension> extensions;
// public boolean vulkan = true;
Expand All @@ -30,4 +31,10 @@ public VersionedGLSLLexer() {
protected boolean isAfter(int atLeast) {
return version.number >= atLeast;
}

public void enableAllFlags() {
enableCustomDirective = true;
enableIncludeDirective = true;
enableStrings = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import io.github.douira.glsl_transformer.ast.data.TokenTyped;

/**
* This enum represents the type of a value in GLSL and contains easily accessible
* This enum represents the type of a value in GLSL and contains easily
* accessible
* data about each of them.
*
* The shape is an array of up to three integers describing how big this
Expand All @@ -17,6 +18,8 @@
* the tensor.
*/
public enum Type implements TokenTyped {
STRING(NumberType.STRING, "string", "string"),

BOOL(GLSLLexer.BOOL, GLSLLexer.BOOLCONSTANT, NumberType.BOOLEAN, "bool", "bool", 1),
BVEC2(GLSLLexer.BVEC2, NumberType.BOOLEAN, "bvec2", "bvec2", 1, 2),
BVEC3(GLSLLexer.BVEC3, NumberType.BOOLEAN, "bvec3", "bvec3", 1, 3),
Expand Down Expand Up @@ -104,6 +107,8 @@ public enum Type implements TokenTyped {
* The different ways bits in a tensor can be interpreted.
*/
public enum NumberType {
STRING(0),

/**
* boolean bit usage
*/
Expand Down Expand Up @@ -226,6 +231,16 @@ public EnumSet<Type> getRegisteredTypes() {
this.explicitName = explicitName;
}

Type(NumberType numberType, String compactName, String explicitName) {
this.tokenType = Token.INVALID_TYPE;
this.literalTokenType = Token.INVALID_TYPE;
this.numberType = numberType;
this.dimensions = new int[] {};
this.bitDepth = 0;
this.compactName = compactName;
this.explicitName = explicitName;
}

/**
* Returns the token type in the parser.
*
Expand Down Expand Up @@ -367,6 +382,7 @@ public EnumSet<Type> getImplicitCasts() {
t1.implicitCastTypes = implicitCastTypes;
for (Type t2 : values()) {
boolean canCast = t1.equals(t2) || (Arrays.equals(t1.dimensions, t2.dimensions) && switch (t1.numberType) {
case STRING -> false;
case BOOLEAN -> false;
case SIGNED_INTEGER -> switch (t2.numberType) {
case UNSIGNED_INTEGER, SIGNED_INTEGER, FLOATING_POINT -> t2.bitDepth >= t1.bitDepth;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ void flushOutput() {
@Disabled
void testDebugTree() {
var parser = new EnhancedParser();
parser.getLexer().enableCustomDirective = true;
parser.getLexer().enableIncludeDirective = true;
parser.getLexer().enableAllFlags();
var walker = new ParseTreeWalker();

Stream.of(
Expand Down
Loading

0 comments on commit fc657b0

Please sign in to comment.