Skip to content

Commit

Permalink
Merge pull request #50 from Darkyenus/bitwise-ops
Browse files Browse the repository at this point in the history
Added support for bitwise operators
  • Loading branch information
Darkyenus committed May 4, 2015
2 parents 6404eb8 + b7b2e25 commit 1aa24bd
Show file tree
Hide file tree
Showing 9 changed files with 1,128 additions and 932 deletions.
11 changes: 6 additions & 5 deletions src/glslplugin/lang/elements/GLSLElementTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,15 @@ public class GLSLElementTypes {
// public static final IElementType UNARY_EXPRESSION = new GLSLElementType("UNARY_EXPRESSION");
public static final IElementType ASSIGNMENT_EXPRESSION = new GLSLElementType("ASSIGNMENT_EXPRESSION");
public static final IElementType CONDITIONAL_EXPRESSION = new GLSLElementType("CONDITIONAL_EXPRESSION");
public static final IElementType LOGICAL_OR_EXPRESSION = new GLSLElementType("LOGICAL_OR_EXPRESSION");
public static final IElementType LOGICAL_XOR_EXPRESSION = new GLSLElementType("LOGICAL_XOR_EXPRESSION");
public static final IElementType LOGICAL_AND_EXPRESSION = new GLSLElementType("LOGICAL_AND_EXPRESSION");
public static final IElementType INCLUSIVE_OR_EXPRESSION = new GLSLElementType("INCLUSIVE_OR_EXPRESSION");
public static final IElementType EXCLUSIVE_OR_EXPRESSION = new GLSLElementType("EXCLUSIVE_OR_EXPRESSION");
public static final IElementType AND_EXPRESSION = new GLSLElementType("AND_EXPRESSION");
public static final IElementType LOGICAL_XOR_EXPRESSION = new GLSLElementType("LOGICAL_XOR_EXPRESSION");
public static final IElementType LOGICAL_OR_EXPRESSION = new GLSLElementType("LOGICAL_OR_EXPRESSION");
public static final IElementType BINARY_AND_EXPRESSION = new GLSLElementType("BINARY_AND_EXPRESSION");
public static final IElementType BINARY_XOR_EXPRESSION = new GLSLElementType("BINARY_XOR_EXPRESSION");
public static final IElementType BINARY_OR_EXPRESSION = new GLSLElementType("BINARY_OR_EXPRESSION");
public static final IElementType EQUALITY_EXPRESSION = new GLSLElementType("EQUALITY_EXPRESSION");
public static final IElementType RELATIONAL_EXPRESSION = new GLSLElementType("RELATIONAL_EXPRESSION");
public static final IElementType BIT_SHIFT_EXPRESSION = new GLSLElementType("BIT_SHIFT_EXPRESSION");
public static final IElementType ADDITIVE_EXPRESSION = new GLSLElementType("ADDITIVE_EXPRESSION");
public static final IElementType MULTIPLICATIVE_EXPRESSION = new GLSLElementType("MULTIPLICATIVE_EXPRESSION");

Expand Down
50 changes: 37 additions & 13 deletions src/glslplugin/lang/elements/GLSLTokenTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

public class GLSLTokenTypes {
public static final IElementType IDENTIFIER = new GLSLElementType("IDENTIFIER");
// public static final IElementType FIELD_SELECTION = new GLSLElementType("FIELD_SELECTION");

public static final IElementType INTEGER_CONSTANT = new GLSLElementType("INTEGER_CONSTANT");
public static final IElementType UINT_CONSTANT = new GLSLElementType("UINT_CONSTANT");
Expand Down Expand Up @@ -140,16 +139,32 @@ public class GLSLTokenTypes {
public static final IElementType RIGHT_BRACKET = new GLSLElementType("RIGHT_BRACKET");

public static final IElementType EQUAL = new GLSLElementType("EQUAL");

public static final IElementType MUL_ASSIGN = new GLSLElementType("MUL_ASSIGN");
public static final IElementType STAR = new GLSLElementType("STAR");
public static final IElementType DIV_ASSIGN = new GLSLElementType("DIV_ASSIGN");
public static final IElementType SLASH = new GLSLElementType("SLASH");
public static final IElementType ADD_ASSIGN = new GLSLElementType("ADD_ASSIGN");
public static final IElementType PLUS = new GLSLElementType("PLUS");
public static final IElementType SUB_ASSIGN = new GLSLElementType("SUB_ASSIGN");
public static final IElementType PLUS = new GLSLElementType("UNARY_PLUS");
public static final IElementType DASH = new GLSLElementType("DASH");
public static final IElementType SLASH = new GLSLElementType("SLASH");
public static final IElementType STAR = new GLSLElementType("STAR");
public static final IElementType MOD_ASSIGN = new GLSLElementType("MOD_ASSIGN");
public static final IElementType PERCENT = new GLSLElementType("PERCENT");
public static final IElementType LEFT_ASSIGN = new GLSLElementType("LEFT_ASSIGN");
public static final IElementType LEFT_OP = new GLSLElementType("LEFT_OP");
public static final IElementType RIGHT_ASSIGN = new GLSLElementType("RIGHT_ASSIGN");
public static final IElementType RIGHT_OP = new GLSLElementType("RIGHT_OP");
public static final IElementType AND_ASSIGN = new GLSLElementType("AND_ASSIGN");
public static final IElementType AMPERSAND = new GLSLElementType("AMPERSAND");
public static final IElementType XOR_ASSIGN = new GLSLElementType("XOR_ASSIGN");
public static final IElementType CARET = new GLSLElementType("CARET");
public static final IElementType OR_ASSIGN = new GLSLElementType("OR_ASSIGN");
public static final IElementType VERTICAL_BAR = new GLSLElementType("VERTICAL_BAR");

public static final IElementType TILDE = new GLSLElementType("TILDE");
public static final IElementType DEC_OP = new GLSLElementType("DEC_OP");
public static final IElementType INC_OP = new GLSLElementType("INC_OP");

public static final IElementType EQ_OP = new GLSLElementType("EQ_OP");
public static final IElementType LEFT_ANGLE = new GLSLElementType("LEFT_ANGLE");
public static final IElementType RIGHT_ANGLE = new GLSLElementType("RIGHT_ANGLE");
Expand Down Expand Up @@ -285,21 +300,30 @@ public class GLSLTokenTypes {
public static final TokenSet SELECTION_KEYWORDS = TokenSet.create(IF_KEYWORD, ELSE_KEYWORD);
public static final TokenSet FLOW_KEYWORDS = merge(SELECTION_KEYWORDS, JUMP_KEYWORDS, ITERATION_KEYWORDS);

public static final TokenSet ASSIGNMENT_OPERATORS = TokenSet.create(EQUAL, MUL_ASSIGN, DIV_ASSIGN, ADD_ASSIGN, SUB_ASSIGN);
public static final TokenSet UNARY_OPERATORS = TokenSet.create(INC_OP, DEC_OP, PLUS, DASH, BANG);
public static final TokenSet EQUALITY_OPERATORS = TokenSet.create(EQ_OP, NE_OP);
public static final TokenSet RELATIONAL_OPERATORS = TokenSet.create(LEFT_ANGLE, RIGHT_ANGLE, LE_OP, GE_OP);
public static final TokenSet ADDITIVE_OPERATORS = TokenSet.create(PLUS, DASH);
//Operators in order of precedence (high to low) (Doesn't have to be here, but for clarity)
//(missing) postfix inc & dec
public static final TokenSet UNARY_OPERATORS = TokenSet.create(INC_OP, DEC_OP, PLUS, DASH, BANG, TILDE);
public static final TokenSet MULTIPLICATIVE_OPERATORS = TokenSet.create(STAR, SLASH);
public static final TokenSet LOGICAL_OPERATORS = TokenSet.create(AND_OP, OR_OP, XOR_OP);
public static final TokenSet OPERATORS = merge(ASSIGNMENT_OPERATORS, UNARY_OPERATORS, EQUALITY_OPERATORS,
RELATIONAL_OPERATORS, ADDITIVE_OPERATORS, MULTIPLICATIVE_OPERATORS, LOGICAL_OPERATORS);
public static final TokenSet ADDITIVE_OPERATORS = TokenSet.create(PLUS, DASH);
public static final TokenSet BIT_SHIFT_OPERATORS = TokenSet.create(LEFT_OP, RIGHT_OP);
public static final TokenSet RELATIONAL_OPERATORS = TokenSet.create(LEFT_ANGLE, RIGHT_ANGLE, LE_OP, GE_OP);
public static final TokenSet EQUALITY_OPERATORS = TokenSet.create(EQ_OP, NE_OP);
public static final TokenSet BIT_WISE_OPERATORS = TokenSet.create(AMPERSAND, CARET, VERTICAL_BAR);//In this order, separately
public static final TokenSet LOGICAL_OPERATORS = TokenSet.create(AND_OP, XOR_OP, OR_OP);//In this order, separately
//(missing) selection (? :)
public static final TokenSet ASSIGNMENT_OPERATORS = TokenSet.create(EQUAL, MUL_ASSIGN, DIV_ASSIGN, ADD_ASSIGN, SUB_ASSIGN, MOD_ASSIGN, LEFT_ASSIGN, RIGHT_ASSIGN, AND_ASSIGN, XOR_ASSIGN, OR_ASSIGN);

public static final TokenSet OPERATORS = merge(
UNARY_OPERATORS, MULTIPLICATIVE_OPERATORS, ADDITIVE_OPERATORS,
BIT_SHIFT_OPERATORS, RELATIONAL_OPERATORS, EQUALITY_OPERATORS,
BIT_WISE_OPERATORS, LOGICAL_OPERATORS, ASSIGNMENT_OPERATORS);

public static final TokenSet CONSTANT_TOKENS = TokenSet.create(
BOOL_CONSTANT, INTEGER_CONSTANT, UINT_CONSTANT, FLOAT_CONSTANT, DOUBLE_CONSTANT);

public static final TokenSet EXPRESSION_FIRST_SET = merge(TokenSet.create(
INTEGER_CONSTANT, FLOAT_CONSTANT, BOOL_CONSTANT, // constants
INC_OP, DEC_OP, PLUS, DASH, BANG, // unary operators
INC_OP, DEC_OP, PLUS, DASH, BANG, TILDE, // unary operators
IDENTIFIER, // function call, variable name, typename
LEFT_PAREN, // group
SEMICOLON // empty statement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public GLSLInitializer(@NotNull ASTNode astNode) {
}

GLSLExpression getInitializerExpression() {
return (GLSLExpression) getFirstChild();
return (GLSLExpression) getFirstChild();//TODO getFirstChild() may not be instanceof GLSLExpression
}

@Override
Expand Down
70 changes: 66 additions & 4 deletions src/glslplugin/lang/elements/expressions/GLSLOperator.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public enum GLSLOperator {
SUBTRACTION("-", getBasicArithmeticOperatorAlternatives("-")),
MULTIPLICATION("*", getMultiplicationOperatorAlternatives()),
DIVISION("/", getBasicArithmeticOperatorAlternatives("/")),
MODULO("%", getBinaryOperatorAlternatives("%")),

// Assignment operators
ASSIGN("=", new AssignmentTypeAlternativesDelegate()),
Expand All @@ -47,14 +48,24 @@ public enum GLSLOperator {
SUBTRACTION_ASSIGN("-=", getAssignmentTypeAlternatives("-=", getBasicArithmeticOperatorAlternatives("-"))),
MULTIPLICATION_ASSIGN("*=", getAssignmentTypeAlternatives("*=", getMultiplicationOperatorAlternatives())),
DIVISION_ASSIGN("/=", getAssignmentTypeAlternatives("/=", getBasicArithmeticOperatorAlternatives("/"))),
MODULO_ASSIGN("%=", getAssignmentTypeAlternatives("%=", getBasicArithmeticOperatorAlternatives("%"))),
LEFT_SHIFT_ASSIGN("<<=", getAssignmentTypeAlternatives("<<=", getBitShiftOperatorAlternatives("<<"))),
RIGHT_SHIFT_ASSIGN(">>=", getAssignmentTypeAlternatives(">>=", getBitShiftOperatorAlternatives(">>"))),
BINARY_AND_ASSIGN("&=", getAssignmentTypeAlternatives("&=", getBinaryOperatorAlternatives("&"))),
BINARY_XOR_ASSIGN("^=", getAssignmentTypeAlternatives("^=", getBinaryOperatorAlternatives("^"))),
BINARY_OR_ASSIGN("|=", getAssignmentTypeAlternatives("|=", getBinaryOperatorAlternatives("|"))),

// Logical operators
LOGIC_AND("&&", getLogicalOperatorAlternatives("&&")),
LOGIC_OR("||", getLogicalOperatorAlternatives("||")),
LOGIC_XOR("^^", getLogicalOperatorAlternatives("^^")),
// BINARY_AND,
// BINARY_OR,
// BINARY_XOR,

// Binary operators
BINARY_AND("&", getBinaryOperatorAlternatives("&")),
BINARY_XOR("^", getBinaryOperatorAlternatives("^")),
BINARY_OR("|", getBinaryOperatorAlternatives("|")),
BINARY_LEFT_SHIFT("<<", getBitShiftOperatorAlternatives("<<")),
BINARY_RIGHT_SHIFT(">>", getBitShiftOperatorAlternatives(">>")),

// Relational operators
GREATER(">", getComparisonOperatorAlternatives(">")),
Expand All @@ -72,7 +83,7 @@ public enum GLSLOperator {
INCREMENT("++", getIncrementOperatorAlternatives("++")),
DECREMENT("--", getIncrementOperatorAlternatives("--")),
LOGIC_NEGATION("!", new GLSLBasicFunctionType("!", GLSLTypes.BOOL, GLSLTypes.BOOL)),
// BINARY_NEGATION,
BINARY_NEGATION("~", getBinaryNegationOperatorAlternatives("~")),

MEMBER("."),;

Expand Down Expand Up @@ -193,6 +204,57 @@ private static GLSLFunctionType[] getIncrementOperatorAlternatives(String name)
};
}

private static GLSLFunctionType[] getBinaryNegationOperatorAlternatives(String name){
return new GLSLFunctionType[]{
new GLSLBasicFunctionType(name, GLSLTypes.INT, GLSLTypes.INT),
new GLSLBasicFunctionType(name, GLSLTypes.UINT, GLSLTypes.UINT),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC2, GLSLTypes.IVEC2),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC3, GLSLTypes.IVEC3),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC4, GLSLTypes.IVEC4),
new GLSLBasicFunctionType(name, GLSLTypes.UVEC2, GLSLTypes.UVEC2),
new GLSLBasicFunctionType(name, GLSLTypes.UVEC3, GLSLTypes.UVEC3),
new GLSLBasicFunctionType(name, GLSLTypes.UVEC4, GLSLTypes.UVEC4),
};
}

private static GLSLFunctionType[] getBinaryOperatorAlternatives(String name){
return new GLSLFunctionType[]{
new GLSLBasicFunctionType(name, GLSLTypes.INT, GLSLTypes.INT, GLSLTypes.INT),
new GLSLBasicFunctionType(name, GLSLTypes.UINT, GLSLTypes.UINT, GLSLTypes.UINT),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC2, GLSLTypes.IVEC2, GLSLTypes.IVEC2),//TODO Repeat this whole thing for UVEC
new GLSLBasicFunctionType(name, GLSLTypes.IVEC3, GLSLTypes.IVEC3, GLSLTypes.IVEC3),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC4, GLSLTypes.IVEC4, GLSLTypes.IVEC4),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC2, GLSLTypes.INT, GLSLTypes.IVEC2),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC3, GLSLTypes.INT, GLSLTypes.IVEC3),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC4, GLSLTypes.INT, GLSLTypes.IVEC4),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC2, GLSLTypes.UINT, GLSLTypes.IVEC2),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC3, GLSLTypes.UINT, GLSLTypes.IVEC3),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC4, GLSLTypes.UINT, GLSLTypes.IVEC4),
new GLSLBasicFunctionType(name, GLSLTypes.INT, GLSLTypes.IVEC2, GLSLTypes.IVEC2),
new GLSLBasicFunctionType(name, GLSLTypes.INT, GLSLTypes.IVEC3, GLSLTypes.IVEC3),
new GLSLBasicFunctionType(name, GLSLTypes.INT, GLSLTypes.IVEC4, GLSLTypes.IVEC4),
new GLSLBasicFunctionType(name, GLSLTypes.UINT,GLSLTypes.IVEC2, GLSLTypes.IVEC2),
new GLSLBasicFunctionType(name, GLSLTypes.UINT,GLSLTypes.IVEC3, GLSLTypes.IVEC3),
new GLSLBasicFunctionType(name, GLSLTypes.UINT,GLSLTypes.IVEC4, GLSLTypes.IVEC4),
};
}

private static GLSLFunctionType[] getBitShiftOperatorAlternatives(String name){
return new GLSLFunctionType[]{
new GLSLBasicFunctionType(name, GLSLTypes.INT, GLSLTypes.INT, GLSLTypes.INT),
new GLSLBasicFunctionType(name, GLSLTypes.UINT, GLSLTypes.UINT, GLSLTypes.UINT),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC2, GLSLTypes.IVEC2, GLSLTypes.IVEC2),//TODO Repeat this whole thing for UVEC
new GLSLBasicFunctionType(name, GLSLTypes.IVEC3, GLSLTypes.IVEC3, GLSLTypes.IVEC3),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC4, GLSLTypes.IVEC4, GLSLTypes.IVEC4),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC2, GLSLTypes.INT, GLSLTypes.IVEC2),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC3, GLSLTypes.INT, GLSLTypes.IVEC3),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC4, GLSLTypes.INT, GLSLTypes.IVEC4),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC2, GLSLTypes.UINT, GLSLTypes.IVEC2),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC3, GLSLTypes.UINT, GLSLTypes.IVEC3),
new GLSLBasicFunctionType(name, GLSLTypes.IVEC4, GLSLTypes.UINT, GLSLTypes.IVEC4),
};
}

/**
* Converts a set of alternatives of an operator to the set of the corresponding assignment operator.
* <p/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,40 @@ public GLSLOperator getOperator() {
}
}

protected GLSLOperator getOperatorFromType(IElementType type) {
@NotNull
protected GLSLOperator getOperatorFromType(final IElementType type) {
if (type == GLSLTokenTypes.INC_OP) return GLSLOperator.INCREMENT;
if (type == GLSLTokenTypes.DEC_OP) return GLSLOperator.DECREMENT;
if (type == GLSLTokenTypes.BANG) return GLSLOperator.LOGIC_NEGATION;
if (type == GLSLTokenTypes.TILDE) return GLSLOperator.BINARY_NEGATION;
if (type == GLSLTokenTypes.PLUS) return GLSLOperator.ADDITION;
if (type == GLSLTokenTypes.DASH) return GLSLOperator.SUBTRACTION;
if (type == GLSLTokenTypes.STAR) return GLSLOperator.MULTIPLICATION;
if (type == GLSLTokenTypes.SLASH) return GLSLOperator.DIVISION;
if (type == GLSLTokenTypes.PERCENT) return GLSLOperator.MODULO;

if (type == GLSLTokenTypes.EQUAL) return GLSLOperator.ASSIGN;
if (type == GLSLTokenTypes.ADD_ASSIGN) return GLSLOperator.ADDITION_ASSIGN;
if (type == GLSLTokenTypes.SUB_ASSIGN) return GLSLOperator.SUBTRACTION_ASSIGN;
if (type == GLSLTokenTypes.MUL_ASSIGN) return GLSLOperator.MULTIPLICATION_ASSIGN;
if (type == GLSLTokenTypes.DIV_ASSIGN) return GLSLOperator.DIVISION_ASSIGN;
if (type == GLSLTokenTypes.MOD_ASSIGN) return GLSLOperator.MODULO_ASSIGN;
if (type == GLSLTokenTypes.LEFT_ASSIGN) return GLSLOperator.LEFT_SHIFT_ASSIGN;
if (type == GLSLTokenTypes.RIGHT_ASSIGN) return GLSLOperator.RIGHT_SHIFT_ASSIGN;
if (type == GLSLTokenTypes.AND_ASSIGN) return GLSLOperator.BINARY_AND_ASSIGN;
if (type == GLSLTokenTypes.XOR_ASSIGN) return GLSLOperator.BINARY_XOR_ASSIGN;
if (type == GLSLTokenTypes.OR_ASSIGN) return GLSLOperator.BINARY_OR_ASSIGN;

if (type == GLSLTokenTypes.AND_OP) return GLSLOperator.LOGIC_AND;
if (type == GLSLTokenTypes.OR_OP) return GLSLOperator.LOGIC_OR;
if (type == GLSLTokenTypes.XOR_OP) return GLSLOperator.LOGIC_XOR;

if (type == GLSLTokenTypes.AMPERSAND) return GLSLOperator.BINARY_AND;
if (type == GLSLTokenTypes.CARET) return GLSLOperator.BINARY_XOR;
if (type == GLSLTokenTypes.VERTICAL_BAR) return GLSLOperator.BINARY_OR;
if (type == GLSLTokenTypes.LEFT_OP) return GLSLOperator.BINARY_LEFT_SHIFT;
if (type == GLSLTokenTypes.RIGHT_OP) return GLSLOperator.BINARY_RIGHT_SHIFT;

if (type == GLSLTokenTypes.EQ_OP) return GLSLOperator.EQUAL;
if (type == GLSLTokenTypes.NE_OP) return GLSLOperator.NOT_EQUAL;
if (type == GLSLTokenTypes.LEFT_ANGLE) return GLSLOperator.LESSER;
Expand Down
6 changes: 5 additions & 1 deletion src/glslplugin/lang/parser/GLSLParsing.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,17 @@ public class GLSLParsing {


// Traits of all binary operators.
// They must be listed in order of precedence.
// They must be listed in order of precedence. (low to high)
private OperatorLevelTraits[] operatorPrecedence = new OperatorLevelTraits[]{
new OperatorLevelTraits(TokenSet.create(OR_OP), "sub expression", LOGICAL_OR_EXPRESSION),
new OperatorLevelTraits(TokenSet.create(XOR_OP), "sub expression", LOGICAL_XOR_EXPRESSION),
new OperatorLevelTraits(TokenSet.create(AND_OP), "sub expression", LOGICAL_AND_EXPRESSION),
new OperatorLevelTraits(TokenSet.create(VERTICAL_BAR), "sub expression", BINARY_OR_EXPRESSION),
new OperatorLevelTraits(TokenSet.create(CARET), "sub expression", BINARY_XOR_EXPRESSION),
new OperatorLevelTraits(TokenSet.create(AMPERSAND), "sub expression", BINARY_AND_EXPRESSION),
new OperatorLevelTraits(EQUALITY_OPERATORS, "sub expression", EQUALITY_EXPRESSION),
new OperatorLevelTraits(RELATIONAL_OPERATORS, "sub expression", RELATIONAL_EXPRESSION),
new OperatorLevelTraits(BIT_SHIFT_OPERATORS, "sub expression", BIT_SHIFT_EXPRESSION),
new OperatorLevelTraits(ADDITIVE_OPERATORS, "part", ADDITIVE_EXPRESSION),
new OperatorLevelTraits(MULTIPLICATIVE_OPERATORS, "factor", MULTIPLICATIVE_EXPRESSION),
};
Expand Down
Loading

0 comments on commit 1aa24bd

Please sign in to comment.