Skip to content

Commit

Permalink
Allow swizzles to begin with a constant value.
Browse files Browse the repository at this point in the history
  • Loading branch information
marsupial committed Dec 19, 2017
1 parent 6349430 commit 27929a9
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 5 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ TESTSUITE ( and-or-not-synonyms aastep arithmetic array array-derivs array-range
oslc-err-noreturn oslc-err-notfunc
oslc-err-outputparamvararray oslc-err-paramdefault
oslc-err-struct-array-init oslc-err-struct-ctr
oslc-err-struct-dup
oslc-err-struct-dup oslc-err-swizzle
oslc-warn-commainit
oslc-variadic-macro
oslc-version
Expand Down
16 changes: 14 additions & 2 deletions src/liboslcomp/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,9 +779,9 @@ ASTswizzle::print (std::ostream &out, int indentlevel) const


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

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

case 3: {
bool allconst = true;
// Don't leak soon to be unused expr node
std::unique_ptr<ASTNode> cleanup(index);
ASTNode* index0 = nullptr;
Expand All @@ -815,6 +818,7 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
ASTNode *args[3];
for (int i = 0; i < 3; ++i) {
if (indexes[i] >= 0) {
allconst = false;
args[i] = new ASTliteral (comp, indexes[i]);
if (i == 0 && index) {
// Re-use expr by extending the ASTindex.
Expand All @@ -832,6 +836,14 @@ ASTNode* ASTfieldselect::create (OSLCompilerImpl *comp, ASTNode *expr,
}
args[0]->append (args[1]);
args[1]->append (args[2]);

if (allconst) {
// return a type constructor instead of a swizzle
ASSERT (!cleanup);
// initial expression will be unused
cleanup.reset (expr);
return new ASTtype_constructor (comp, type, args[0]);
}
return new ASTswizzle (comp, args[0], field);
}

Expand Down
3 changes: 2 additions & 1 deletion src/liboslcomp/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,8 @@ class ASTfieldselect : public ASTNode
ustring m_fullname; ///< Full name of variable and field

public:
static ASTNode* create (OSLCompilerImpl *comp, ASTNode *expr, ustring field);
static ASTNode* create (OSLCompilerImpl *comp, ASTNode *expr, ustring field,
bool swizzle = false);

ustring field () const { return m_field; }
ustring fullname () const { return m_fullname; }
Expand Down
6 changes: 5 additions & 1 deletion src/liboslcomp/oslgram.y
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ static std::stack<TypeSpec> typespec_stack; // just for function_declaration


// Define the terminal symbols.
%token <s> IDENTIFIER STRING_LITERAL
%token <s> IDENTIFIER STRING_LITERAL SWIZZLE_IDENTIFIER
%token <i> INT_LITERAL
%token <f> FLOAT_LITERAL
%token <i> COLORTYPE FLOATTYPE INTTYPE MATRIXTYPE
Expand Down Expand Up @@ -769,6 +769,10 @@ id_or_field
{
$$ = new ASTvariable_ref (oslcompiler, ustring($1));
}
| variable_lvalue SWIZZLE_IDENTIFIER
{
$$ = ASTfieldselect::create (oslcompiler, $1, ustring($2));
}
| variable_lvalue '.' IDENTIFIER
{
$$ = ASTfieldselect::create (oslcompiler, $1, ustring($3));
Expand Down
10 changes: 10 additions & 0 deletions src/liboslcomp/osllex.l
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ STR \"(\\.|[^\\"\n])*\"
/* " This extra quote fixes emacs syntax highlighting on this file */
/* Identifier: alphanumeric, may contain digits after the first character */
IDENT ({ALPHA}|[_])({ALPHA}|{DIGIT}|[_])*
/* Swizzle that starts with a constant value
Needs to include the . selector to take precedence over FLT */
SWIZZLE (\.[01][01rgbxyz]{2})


/* C preprocessor (cpp) directives */
CPP ^[ \t]*#.*\n
CPLUSCOMMENT \/\/.*\n
Expand Down Expand Up @@ -196,6 +201,11 @@ void preprocess (const char *yytext);
SETLINE;
return IDENTIFIER;
}
{SWIZZLE} {
yylval.s = ustring(yytext+1).c_str();
SETLINE;
return SWIZZLE_IDENTIFIER;
}

/* Literal values */
{INTEGER} {
Expand Down
3 changes: 3 additions & 0 deletions testsuite/oslc-err-swizzle/ref/out.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
test.osl:7: error: Can't assign via = to something that isn't an lvalue
test.osl:8: error: Can't assign via = to something that isn't an lvalue
FAILED test.osl
5 changes: 5 additions & 0 deletions testsuite/oslc-err-swizzle/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env python

# command = oslc("test.osl")
# don't even need that -- it's automatic
failureok = 1 # this test is expected to have oslc errors
10 changes: 10 additions & 0 deletions testsuite/oslc-err-swizzle/test.osl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Error on invalid swizzle operations

shader test ()
{
color c;

c.rg0 = color(1);
c.01r = color(1);
// c.0;
}
2 changes: 2 additions & 0 deletions testsuite/swizzle/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ c.r00: 1 0 0
c.g01: 2 0 1
c.b11: 3 1 1
c.bg1: 3 2 1
c.01g: 0 1 2
c.101: 1 0 1
c.rgb = c.brg: 3 1 2
c.rgb = c.brg: 2 3 1
c.rgb = c.brg: 1 2 3
Expand Down
6 changes: 6 additions & 0 deletions testsuite/swizzle/swizzle.osl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

shader swizzle ()
{
// Make sure floats don't generate a swizzle operation.
float noswizzle = 1.101;
noswizzle = 1.001;

color c = color(1,2,3);
printf("c: %g\n", c);

Expand All @@ -19,6 +23,8 @@ shader swizzle ()
printf("c.g01: %g\n", c.g01);
printf("c.b11: %g\n", c.b11);
printf("c.bg1: %g\n", c.bg1);
printf("c.01g: %g\n", c.01g);
printf("c.101: %g\n", c.101);

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

0 comments on commit 27929a9

Please sign in to comment.