yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
c3557978c
master
Note: This document is a work in progress. It is both incomplete and, in many cases, inaccurate.
Statements
Statements are used to define the bodies of functions and determine order of evaluation and control flow for an entire program. Statements are distinct from expressions in that statements do not yield results and do not have types.
This section lists the kinds of statements supported by Slang.
Expression Statement
An expression statement consists of an expression followed by a semicolon:
doSomething (); a [ 10 ] = b + 1 ;
An implementation may warn on an expression statement that has to effect on the results of execution.
Declaration Statement
A declaration may be used as a statement:
let x = 10 ; var y = x + 1 ; int z = y - x ;
Note: Currently only variable declarations are allowed in statement contexts, but other kinds of declarations may be enabled in the future.
Block Statement
A block statement consists of zero or more statements wrapped in curly braces {}:
{ int x = 10 ; doSomething ( x ); }
A block statement provides local scoping to declarations. Declarations in a block are visible to later statements in the same block, but not to statements or expressions outside of the block.
Empty Statement
A single semicolon (;) may be used as an empty statement equivalent to an empty block statement {}.
Conditional Statements
If Statement
An if statement consists of the if keyword and a conditional expression in parentheses, followed by a statement to execute if the condition is true:
if ( somethingShouldHappen ) doSomething ();
An if statement may optionally include an else clause consisting of the keyword else followed by a statement to execute if the condition is false:
if ( somethingShouldHappen ) doSomething (); else doNothing ();
Switch Statement
A switch statement consists of the switch keyword followed by an expression wrapped in parentheses and a body statement:
switch ( someValue ) { ...}
The body of a switch statement must be a block statement, and its body must consist of switch case clauses. A switch case clause consists of one or more case labels or default labels, followed by one or more statements:
// this is a switch case clause case 0 : case 1 : doBasicThing (); break ; // this is another switch case clause default : doAnotherThing (); break ;
A case label consists of the keyword case followed by an expressions and a colon (:).
The expression must evaluate to a compile-time constant integer.
A default label consists of the keyword default followed by a colon (:).
It is an error for a case label or default label to appear anywhere other than the body of a switch statement.
It is an error for a statement to appear inside the body of a switch statement that is no part of a switch case clause.
Each switch case clause must exit the switch statement via a break or other control transfer statement.
"Fall-through" from one switch case clause to another is not allowed.
Loop Statements
For Statement
A for statement uses the following form:
for ( < initial statement > ; < condition expression > ; < side effect expression > ) < body statement >
The initial statement is optional, but may declare a variable whose scope is limited to the for statement.
The condition expression is optional. If present it must be an expression that can be coerced to type bool. If absent, a true value is used as the condition.
The side effect expression is optional. If present it will executed for its effects before each testing the condition for every loop iteration after the first.
The body statement is a statement that will be executed for each iteration of the loop.
While Statement
A while statement uses the following form:
while ( < condition expression > ) < body statement >
and is equivalent to a for loop of the form:
for ( ; < condition expression > ; ) < body statement >
Do-While Statement
A do-while statement uses the following form:
do < body statement > while ( < condition expression > )
and is equivalent to a for loop of the form:
for (;;) { < body statement > if ( < condition expression > ) continue ; else break ; }
Control Transfer Statements
Break Statement
A break statement transfers control to after the end of the closest lexically enclosing switch statement or loop statement:
break ;
Continue Statement
A continue statement transfers control to the start of the next iteration of a loop statement.
In a for statement with a side effect expression, the side effect expression is evaluated when continue is used:
break ;
Return Statement
A return statement transfers control out of the current function.
In the body of a function with a void result type, the return keyword may be followed immediately by a semicolon:
return ;
Otherwise, the return keyword must be followed by an expression to use as the value to return to the caller:
return someValue ;
The value returned must be able to coerce to the result type of the lexically enclosing function.
Discard Statement
A discard statement can only be used in the context of a fragment shader, in which case it causes the current invocation to terminate and the graphics system to discard the corresponding fragment so that it does not get combined with the framebuffer pixel at its coordinates.
Operations with side effects that were executed by the invocation before a discard will still be performed and their results will become visible according to the rules of the platform.
Compile-Time For Statement
A compile-time for statement is used as an alternative to preprocessor techniques for loop unrolling. It looks like:
$for ( < name > in Range ( < initial - value > , < upper - bound > )) < body statement >
The initial value and upper bound expressions must be compile-time constant integers. The semantics of a compile-time for statement are as if it were expanded into:
{ let < name > = < initial - value > ; < body statement > } { let < name > = < initial - value > + 1 ; < body statement > } ...{ let < name > = < upper - bound > - 1 ; < body statement > }
1> Note: This document is a work in progress. It is both incomplete and, in many cases, inaccurate. 2 3Statements 4========== 5 6Statements are used to define the bodies of functions and determine order of evaluation and control flow for an entire program. 7Statements are distinct from expressions in that statements do not yield results and do not have types. 8 9This section lists the kinds of statements supported by Slang. 10 11Expression Statement 12-------------------- 13 14An expression statement consists of an expression followed by a semicolon: 15 16``` hlsl 17doSomething(); 18a[ 10 ] = b + 1 ; 19``` 20 21An implementation may warn on an expression statement that has to effect on the results of execution. 22 23Declaration Statement 24--------------------- 25 26A declaration may be used as a statement: 27 28``` hlsl 29let x = 10 ; 30var y = x + 1 ; 31int z = y - x ; 32``` 33 34> Note: Currently only variable declarations are allowed in statement contexts, but other kinds of declarations may be enabled in the future. 35 36Block Statement 37--------------- 38 39A block statement consists of zero or more statements wrapped in curly braces `{}`: 40 41``` hlsl 42{ 43int x = 10 ; 44doSomething ( x ); 45} 46``` 47 48A block statement provides local scoping to declarations. 49Declarations in a block are visible to later statements in the same block, but not to statements or expressions outside of the block. 50 51Empty Statement 52--------------- 53 54A single semicolon (`;`) may be used as an empty statement equivalent to an empty block statement `{}`. 55 56Conditional Statements 57---------------------- 58 59### If Statement 60 61An _if statement_ consists of the `if` keyword and a conditional expression in parentheses, followed by a statement to execute if the condition is true: 62 63``` hlsl 64if( somethingShouldHappen ) 65doSomething (); 66``` 67 68An if statement may optionally include an _else clause_ consisting of the keyword `else` followed by a statement to execute if the condition is false: 69 70``` hlsl 71if( somethingShouldHappen ) 72doSomething (); 73else 74doNothing (); 75``` 76 77### Switch Statement 78 79A _switch statement_ consists of the `switch` keyword followed by an expression wrapped in parentheses and a _body statement_: 80 81``` hlsl 82switch( someValue ) 83{ 84... 85} 86``` 87 88The body of a switch statement must be a block statement, and its body must consist of switch case clauses. 89A _switch case clause_ consists of one or more case labels or default labels, followed by one or more statements: 90 91``` hlsl 92// this is a switch case clause 93case 0 : 94case 1 : 95doBasicThing (); 96break ; 97 98// this is another switch case clause 99default : 100doAnotherThing (); 101break ; 102``` 103 104A _case label_ consists of the keyword `case` followed by an expressions and a colon (`:`). 105The expression must evaluate to a compile-time constant integer. 106 107A _default label_ consists of the keyword `default` followed by a colon (`:`). 108 109It is an error for a case label or default label to appear anywhere other than the body of a `switch` statement. 110It is an error for a statement to appear inside the body of a `switch` statement that is no part of a switch case clause. 111 112Each switch case clause must exit the `switch` statement via a `break` or other control transfer statement. 113"Fall-through" from one switch case clause to another is not allowed. 114 115Loop Statements 116--------------- 117 118### For Statement 119 120A _for statement_ uses the following form: 121 122``` hlsl 123for( < initial statement > ; < condition expression > ; < side effect expression > ) < body statement > 124``` 125 126The _initial statement_ is optional, but may declare a variable whose scope is limited to the for statement. 127 128The _condition expression_ is optional. If present it must be an expression that can be coerced to type `bool`. If absent, a true value is used as the condition. 129 130The _side effect expression_ is optional. If present it will executed for its effects before each testing the condition for every loop iteration after the first. 131 132The _body statement_ is a statement that will be executed for each iteration of the loop. 133 134### While Statement 135 136A _while statement_ uses the following form: 137 138``` hlsl 139while( < condition expression > ) < body statement > 140``` 141 142and is equivalent to a `for` loop of the form: 143 144``` hlsl 145for( ; < condition expression > ; ) < body statement > 146``` 147 148### Do-While Statement 149 150A _do-while statement_ uses the following form: 151 152``` hlsl 153do < body statement > while ( < condition expression > ) 154``` 155 156and is equivalent to a `for` loop of the form: 157 158``` hlsl 159for(;;) 160{ 161< body statement > 162if ( < condition expression > ) continue ; else break ; 163} 164``` 165 166Control Transfer Statements 167--------------------------- 168 169### Break Statement 170 171A `break` statement transfers control to after the end of the closest lexically enclosing switch statement or loop statement: 172 173``` hlsl 174break; 175``` 176 177### Continue Statement 178 179A `continue` statement transfers control to the start of the next iteration of a loop statement. 180In a for statement with a side effect expression, the side effect expression is evaluated when `continue` is used: 181 182``` hlsl 183break; 184``` 185 186### Return Statement 187 188A `return` statement transfers control out of the current function. 189 190In the body of a function with a `void` result type, the `return` keyword may be followed immediately by a semicolon: 191 192``` hlsl 193return; 194``` 195 196Otherwise, the `return` keyword must be followed by an expression to use as the value to return to the caller: 197 198``` hlsl 199return someValue ; 200``` 201 202The value returned must be able to coerce to the result type of the lexically enclosing function. 203 204### Discard Statement 205 206A `discard` statement can only be used in the context of a fragment shader, in which case it causes the current invocation to terminate and the graphics system to discard the corresponding fragment so that it does not get combined with the framebuffer pixel at its coordinates. 207 208Operations with side effects that were executed by the invocation before a `discard` will still be performed and their results will become visible according to the rules of the platform. 209 210Compile-Time For Statement 211-------------------------- 212 213A _compile-time for statement_ is used as an alternative to preprocessor techniques for loop unrolling. 214It looks like: 215 216``` hlsl 217$for( < name > in Range ( <initial - value > , < upper - bound > )) < body statement > 218``` 219 220The _initial value_ and _upper bound_ expressions must be compile-time constant integers. 221The semantics of a compile-time for statement are as if it were expanded into: 222 223``` hlsl 224{ 225let < name > = < initial - value > ; 226< body statement > 227} 228{ 229let < name > = < initial - value > + 1 ; 230< body statement > 231} 232... 233{ 234let < name > = < upper - bound > - 1 ; 235< body statement > 236} 237```