Skip to content

Commit f2e514e

Browse files
committed
Allow swizzles to begin with a constant value.
1 parent 71a38a8 commit f2e514e

File tree

10 files changed

+58
-4
lines changed

10 files changed

+58
-4
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ TESTSUITE ( aastep allowconnect-err and-or-not-synonyms arithmetic
276276
oslc-err-outputparamvararray oslc-err-paramdefault
277277
oslc-err-struct-array-init oslc-err-struct-ctr
278278
oslc-err-struct-dup oslc-err-struct-print
279+
oslc-err-swizzle
279280
oslc-warn-commainit
280281
oslc-variadic-macro
281282
oslc-version

src/liboslcomp/ast.cpp

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

866866

867867
ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
868-
ustring field)
868+
ustring field, bool swizzle)
869869
{
870-
if (expr->typespec().is_structure_based())
870+
if (!swizzle && expr->typespec().is_structure_based())
871871
return new ASTstructselect (comp, expr, field);
872872

873873
const TypeSpec &type = expr->nodetype() != structselect_node ? expr->typespec() :
@@ -883,13 +883,16 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
883883
int indexes[3];
884884
switch (ASTswizzle::indices (field, indexes, 3, true)) {
885885
case 1: {
886+
// c.0 && c.1 not allowed
887+
ASSERT (indexes[0] >= 0);
886888
if (!index)
887889
return new ASTindex (comp, expr, new ASTliteral (comp, indexes[0]));
888890
index->extend(new ASTliteral (comp, indexes[0]));
889891
return index;
890892
}
891893

892894
case 3: {
895+
bool allconst = true;
893896
// Don't leak soon to be unused expr node
894897
std::unique_ptr<ASTNode> cleanup(index);
895898
ASTNode* index0 = nullptr;
@@ -901,6 +904,7 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
901904
ASTNode *args[3];
902905
for (int i = 0; i < 3; ++i) {
903906
if (indexes[i] >= 0) {
907+
allconst = false;
904908
args[i] = new ASTliteral (comp, indexes[i]);
905909
if (i == 0 && index) {
906910
// Re-use expr by extending the ASTindex.
@@ -918,6 +922,14 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
918922
}
919923
args[0]->append (args[1]);
920924
args[1]->append (args[2]);
925+
926+
if (allconst) {
927+
// return a type constructor instead of a swizzle
928+
ASSERT (!cleanup);
929+
// initial expression will be unused
930+
cleanup.reset (expr);
931+
return new ASTtype_constructor (comp, type, args[0]);
932+
}
921933
return new ASTswizzle (comp, args[0], field);
922934
}
923935

src/liboslcomp/ast.h

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

608608
public:
609-
static ASTNode* create (OSLCompilerImpl *comp, ASTNode *expr, ustring field);
609+
static ASTNode* create (OSLCompilerImpl *comp, ASTNode *expr, ustring field,
610+
bool swizzle = false);
610611

611612
ustring field () const { return m_field; }
612613
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
@@ -778,6 +778,10 @@ id_or_field
778778
{
779779
$$ = new ASTvariable_ref (oslcompiler, ustring($1));
780780
}
781+
| variable_lvalue SWIZZLE_IDENTIFIER
782+
{
783+
$$ = ASTfieldselect::create (oslcompiler, $1, ustring($2));
784+
}
781785
| variable_lvalue '.' IDENTIFIER
782786
{
783787
$$ = 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)