Skip to content

Commit eb7ad07

Browse files
committed
Allow swizzles to begin with a constant value.
1 parent 7eaabf0 commit eb7ad07

File tree

10 files changed

+58
-5
lines changed

10 files changed

+58
-5
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ TESTSUITE ( and-or-not-synonyms aastep arithmetic array array-derivs array-range
270270
oslc-err-noreturn oslc-err-notfunc
271271
oslc-err-outputparamvararray oslc-err-paramdefault
272272
oslc-err-struct-array-init oslc-err-struct-ctr
273-
oslc-err-struct-dup
273+
oslc-err-struct-dup oslc-err-swizzle
274274
oslc-warn-commainit
275275
oslc-variadic-macro
276276
oslc-version

src/liboslcomp/ast.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -779,9 +779,9 @@ ASTswizzle::print (std::ostream &out, int indentlevel) const
779779

780780

781781
ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
782-
ustring field)
782+
ustring field, bool swizzle)
783783
{
784-
if (expr->typespec().is_structure_based())
784+
if (!swizzle && expr->typespec().is_structure_based())
785785
return new ASTstructselect (comp, expr, field);
786786

787787
const TypeSpec &type = expr->nodetype() != structselect_node ? expr->typespec() :
@@ -797,13 +797,16 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
797797
int indexes[3];
798798
switch (ASTswizzle::indices (field, indexes, 3, true)) {
799799
case 1: {
800+
// c.0 && c.1 not allowed
801+
ASSERT (indexes[0] >= 0);
800802
if (!index)
801803
return new ASTindex (comp, expr, new ASTliteral (comp, indexes[0]));
802804
index->extend(new ASTliteral (comp, indexes[0]));
803805
return index;
804806
}
805807

806808
case 3: {
809+
bool allconst = true;
807810
// Don't leak soon to be unused expr node
808811
std::unique_ptr<ASTNode> cleanup(index);
809812
ASTNode* index0 = nullptr;
@@ -815,6 +818,7 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
815818
ASTNode *args[3];
816819
for (int i = 0; i < 3; ++i) {
817820
if (indexes[i] >= 0) {
821+
allconst = false;
818822
args[i] = new ASTliteral (comp, indexes[i]);
819823
if (i == 0 && index) {
820824
// Re-use expr by extending the ASTindex.
@@ -832,6 +836,14 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
832836
}
833837
args[0]->append (args[1]);
834838
args[1]->append (args[2]);
839+
840+
if (allconst) {
841+
// return a type constructor instead of a swizzle
842+
ASSERT (!cleanup);
843+
// initial expression will be unused
844+
cleanup.reset (expr);
845+
return new ASTtype_constructor (comp, type, args[0]);
846+
}
835847
return new ASTswizzle (comp, args[0], field);
836848
}
837849

src/liboslcomp/ast.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,8 @@ class ASTfieldselect : public ASTNode
605605
ustring m_fullname; ///< Full name of variable and field
606606

607607
public:
608-
static ASTNode* create (OSLCompilerImpl *comp, ASTNode *expr, ustring field);
608+
static ASTNode* create (OSLCompilerImpl *comp, ASTNode *expr, ustring field,
609+
bool swizzle = false);
609610

610611
ustring field () const { return m_field; }
611612
ustring fullname () const { return m_fullname; }

src/liboslcomp/oslgram.y

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ static std::stack<TypeSpec> typespec_stack; // just for function_declaration
8383

8484

8585
// Define the terminal symbols.
86-
%token <s> IDENTIFIER STRING_LITERAL
86+
%token <s> IDENTIFIER STRING_LITERAL SWIZZLE_IDENTIFIER
8787
%token <i> INT_LITERAL
8888
%token <f> FLOAT_LITERAL
8989
%token <i> COLORTYPE FLOATTYPE INTTYPE MATRIXTYPE
@@ -769,6 +769,10 @@ id_or_field
769769
{
770770
$$ = new ASTvariable_ref (oslcompiler, ustring($1));
771771
}
772+
| variable_lvalue SWIZZLE_IDENTIFIER
773+
{
774+
$$ = ASTfieldselect::create (oslcompiler, $1, ustring($2));
775+
}
772776
| variable_lvalue '.' IDENTIFIER
773777
{
774778
$$ = ASTfieldselect::create (oslcompiler, $1, ustring($3));

src/liboslcomp/osllex.l

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ STR \"(\\.|[^\\"\n])*\"
8080
/* " This extra quote fixes emacs syntax highlighting on this file */
8181
/* Identifier: alphanumeric, may contain digits after the first character */
8282
IDENT ({ALPHA}|[_])({ALPHA}|{DIGIT}|[_])*
83+
/* Swizzle that starts with a constant value
84+
Needs to include the . selector to take precedence over FLT */
85+
SWIZZLE (\.[01][01rgbxyz]{2})
86+
87+
8388
/* C preprocessor (cpp) directives */
8489
CPP ^[ \t]*#.*\n
8590
CPLUSCOMMENT \/\/.*\n
@@ -196,6 +201,11 @@ void preprocess (const char *yytext);
196201
SETLINE;
197202
return IDENTIFIER;
198203
}
204+
{SWIZZLE} {
205+
yylval.s = ustring(yytext+1).c_str();
206+
SETLINE;
207+
return SWIZZLE_IDENTIFIER;
208+
}
199209

200210
/* Literal values */
201211
{INTEGER} {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
test.osl:7: error: Can't assign via = to something that isn't an lvalue
2+
test.osl:8: error: Can't assign via = to something that isn't an lvalue
3+
FAILED test.osl

testsuite/oslc-err-swizzle/run.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env python
2+
3+
# command = oslc("test.osl")
4+
# don't even need that -- it's automatic
5+
failureok = 1 # this test is expected to have oslc errors

testsuite/oslc-err-swizzle/test.osl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Error on invalid swizzle operations
2+
3+
shader test ()
4+
{
5+
color c;
6+
7+
c.rg0 = color(1);
8+
c.01r = color(1);
9+
// c.0;
10+
}

testsuite/swizzle/ref/out.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ c.r00: 1 0 0
66
c.g01: 2 0 1
77
c.b11: 3 1 1
88
c.bg1: 3 2 1
9+
c.01g: 0 1 2
10+
c.101: 1 0 1
911
c.rgb = c.brg: 3 1 2
1012
c.rgb = c.brg: 2 3 1
1113
c.rgb = c.brg: 1 2 3

testsuite/swizzle/swizzle.osl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
shader swizzle ()
66
{
7+
// Make sure floats don't generate a swizzle operation.
8+
float noswizzle = 1.101;
9+
noswizzle = 1.001;
10+
711
color c = color(1,2,3);
812
printf("c: %g\n", c);
913

@@ -19,6 +23,8 @@ shader swizzle ()
1923
printf("c.g01: %g\n", c.g01);
2024
printf("c.b11: %g\n", c.b11);
2125
printf("c.bg1: %g\n", c.bg1);
26+
printf("c.01g: %g\n", c.01g);
27+
printf("c.101: %g\n", c.101);
2228

2329
c = c.brg;
2430
printf("c.rgb = c.brg: %g\n", c);

0 commit comments

Comments
 (0)