Sitelet https://github.com/gpuweb/gpuweb/pull/772/files
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
337 changes: 329 additions & 8 deletions wgsl/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ thead {
background-color: #f0f0f0;
font-weight: bold;
}
.nowrap {
white-space:nowrap;
}
</style>

# Introduction # {#intro}
Expand Down Expand Up @@ -488,12 +491,11 @@ The following is a list of keywords which are reserved for future expansion.
<tr><td>`NOT_EQUAL`<td>!==
<tr><td>`GREATER_THAN`<td>>
<tr><td>`GREATER_THAN_EQUAL`<td>>=
<tr><td>`LOGICAL_SHIFT_RIGHT`<td>>>
<tr><td>`ARITH_SHIFT_RIGHT`<td>>>>
<tr><td>`SHIFT_RIGHT`<td>>>
<tr><td>`LESS_THAN`<td><
<tr><td>`LESS_THAN_EQUAL`<td><=
<tr><td>`SHIFT_LEFT`<td><<

@kainino0x kainino0x Jun 2, 2020 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: These should really (eventually) be escaped somehow to avoid weird html parsing issues. I'd just put them in code tags: `<<` etc.

<tr><td>`MOD`<td>%
<tr><td>`MODULO`<td>%
<tr><td>`MINUS`<td>-
<tr><td>`NAMESPACE`<td>::
<tr><td>`PERIOD`<td>.
Expand Down Expand Up @@ -1343,10 +1345,8 @@ shift_expression
: additive_expression
| shift_expression SHIFT_LEFT additive_expression
OpShiftLeftLogical
| shift_expression LOGICAL_SHIFT_RIGHT additive_expression
OpShiftRightLogical
| shift_expression ARITH_SHIFT_RIGHT additive_expression
OpShiftRightArithmetic
| shift_expression SHIFT_RIGHT additive_expression
OpShiftRightLogical or OpShiftRightArithmetic

relational_expression
: shift_expression
Expand Down Expand Up @@ -1532,7 +1532,7 @@ For convenience, we will use the following shorthands:

Issue: (dneto): Do we have to explicitly list the type environment Gamma? That's confusing to newcomers.

## Literal and unary expression type rules ## {#literal-and-unary}
## Literal and unary expression type rules ## {#literal-and-unary-type-rules}

<table class='data'>
<caption>Scalar literal type rules</caption>
Expand Down Expand Up @@ -1679,6 +1679,327 @@ Issue: (dneto): Do we have to explicitly list the type environment Gamma? That's

Issue: (dneto): remaining unary operators

Issue: (dneto): Bitwise-complement is under discussion. https://github.com/gpuweb/gpuweb/pull/727

## Binary expression type rules ## {#binary-type-rules}

<table class='data'>
<caption>Binary arithmetic expressions over scalars</caption>
<thead>
<tr><td>Precondition<td>Conclusion<td>Notes
</thead>
<tr><td>*e1* : u32<br> *e2* : u32<td class="nowrap">`e1 + e2` : u32<td>Integer addition, modulo 2<sup>32</sup> (OpIAdd)
<tr><td>*e1* : i32<br> *e2* : i32<td>`e1 + e2` : i32<td>Integer addition, modulo 2<sup>32</sup> (OpIAdd)
<tr><td>*e1* : f32<br> *e2* : f32<td>`e1 + e2` : f32<td>Floating point addition (OpFAdd)
<tr><td>*e1* : u32<br> *e2* : u32<td>`e1 - e2` : u32<td>Integer subtraction, modulo 2<sup>32</sup> (OpISub)
<tr><td>*e1* : i32<br> *e2* : i32<td>`e1 - e2` : i32<td>Integer subtraction, modulo 2<sup>32</sup> (OpISub)
<tr><td>*e1* : f32<br> *e2* : f32<td>`e1 - e2` : f32<td>Floating point subtraction (OpFSub)
<tr><td>*e1* : u32<br> *e2* : u32<td>`e1 * e2` : u32<td>Integer multiplication, modulo 2<sup>32</sup> (OpIMul)
<tr><td>*e1* : i32<br> *e2* : i32<td>`e1 * e2` : i32<td>Integer multiplication, modulo 2<sup>32</sup> (OpIMul)
<tr><td>*e1* : f32<br> *e2* : f32<td>`e1 * e2` : f32<td>Floating point multiplication (OpFMul)
<tr><td>*e1* : u32<br> *e2* : u32<td>`e1 / e2` : u32<td>Unsigned integer division (OpUDiv)
<tr><td>*e1* : i32<br> *e2* : i32<td>`e1 / e2` : i32<td>Signed integer division (OpSDiv)
<tr><td>*e1* : f32<br> *e2* : f32<td>`e1 / e2` : f32<td>Floating point division (OpFAdd)
<tr><td>*e1* : u32<br> *e2* : u32<td>`e1 % e2` : u32<td>Unsigned integer modulus (OpUMod)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it helpful to draw a distinction between modulus and remainder for an unsigned number? The difference concerns negative numbers. For clarity and consistency, could we not call them something different here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I would say these are the type rules, and are not a complete spec of how arithmetic works. I expect we'll need a whole other section to specify the behaviours of operations. We may end up migrating descriptions over to that new section. I am coming around to the need for a larger scale reorg of the spec.

<tr><td>*e1* : i32<br> *e2* : i32<td>`e1 % e2` : i32<td>Signed integer remainder, where sign of non-zero result matches sign of *e2* (OpSMod)
<tr><td>*e1* : f32<br> *e2* : f32<td>`e1 % e2` : f32<td>Floating point modulus, where sign of non-zero result matches sign of *e2* (OpFMod)
</table>

<table class='data'>
<caption>Binary arithmetic expressions over vectors</caption>
<thead>
<tr><td>Precondition<td>Conclusion<td>Notes
</thead>
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *IntVec*<td class="nowrap">`e1 + e2` : *T*<td>Component-wise integer addition (OpIAdd)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *FloatVec*<td class="nowrap">`e1 + e2` : *T*<td>Component-wise floating point addition (OpIAdd)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *IntVec*<td class="nowrap">`e1 - e2` : *T*<td>Component-wise integer subtraction (OpISub)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *FloatVec*<td>`e1 - e2` : *T*<td>Component-wise floating point subtraction (OpISub)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *IntVec*<td>`e1 * e2` : *T*<td>Component-wise integer multiplication (OpIMul)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *FloatVec*<td>`e1 * e2` : *T*<td>Component-wise floating point multiplication (OpIMul)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *IntVec* with unsigned component<td>`e1 / e2` : *T*<td>Component-wise unsigned integer division (OpUDiv)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *IntVec* with signed component<td>`e1 / e2` : *T*<td>Component-wise signed integer division (OpSDiv)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *FloatVec*<td>`e1 / e2` : *T*<td>Component-wise floating point division (OpFDiv)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *IntVec* with unsigned component<td>`e1 % e2` : *T*<td>Component-wise unsigned integer modulus (OpUMod)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *IntVec* with signed component<td>`e1 % e2` : *T*<td>Component-wise signed integer remainder (OpSMod)
<tr><td>*e1* : *T*<br> *e2* : *T*<br> *T* is *FloatVec*<td>`e1 % e2` : *T*<td>Component-wise floating point modulus (OpFMod)
</table>

<table class='data'>
<caption>Binary arithmetic expressions with mixed scalar, vector, and matrix operands</caption>
<thead>
<tr><td>Precondition<td>Conclusion<td>Notes
</thead>
<tr><td>*e1* : f32<br>
*e2* : *T*<br>
*T* is *FloatVec*
<td>`e1 * e2` : *T*<br>
`e2 * e1` : *T*
<td>Multiplication of a vector and a scalar (OpVectorTimesScalar)
<tr><td>*e1* : f32<br>
*e2* : *T*<br>
*T* is mat*N*x*M*&lt;f32&gt;
<td>`e1 * e2` : *T*<br>
`e2 * e1` : *T*
<td>Multiplication of a matrix and a scalar (OpMatrixTimesScalar)
<tr><td>*e1* : vec*M*&lt;f32&gt;<br>
*e2* : mat*N*x*M*&lt;f32&gt;
<td>`e1 * e2` : vec*N*&lt;f32&gt;<br>
<td>Vector times matrix (OpVectorTimesMatrix)
<tr><td>*e1* : mat*N*x*M*&lt;f32&gt;<br>
*e2* : vec*N*&lt;f32&gt;
<td>`e1 * e2` : vec*M*&lt;f32&gt;<br>
<td>Matrix times vector (OpMatrixTimesVector)
<tr><td>*e1* : mat*K*x*N*&lt;f32&gt;<br>
*e2* : mat*M*x*K*&lt;f32&gt;<br>
<td>`e1 * e2` : mat*M*x*N*&lt;f32&gt;<br>
<td>Matrix times matrix (OpMatrixTimesMatrix)
</table>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see matrix x matrix multiplication in here. I expect we follow the same rules we learned in trigonometry class, but it might be worth mentioning for completeness.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? Matrix times matrix is at line 1773-1776


<table class='data'>
<caption>Bit shift expressions</caption>
<thead>
<tr><td>Precondition<td>Conclusion<td>Notes
</thead>
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is *Int*
<td class="nowrap">`e1 << e2` : *T*
<td>Shift *e1* left by *e2* bits (OpShiftLeftLogical)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is *IntVec*
<td class="nowrap">`e1 << e2` : *T*
<td>Component-wise shift left (OpShiftLeftLogical)
<tr><td>*e1* : u32<br>
*e2* : u32<br>
<td class="nowrap">`e1 >> e2` : u32
<td>Logical shift *e1* right by *e2* bits, i.e. inserting zero at most significant bits (OpShiftRightLogical)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;u32&gt;
<td class="nowrap">`e1 >> e2` : *T*
<td>Component-wise logical shift right (OpShiftRightLogical)
<tr><td>*e1* : i32<br>
*e2* : i32<br>
<td class="nowrap">`e1 >> e2` : i32
<td>Arithmetic shift *e1* right by *e2* bits, i.e. replicating the sign bit of *e1* at most significant bits (OpShiftRightArithmetic)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;i32&gt;
<td class="nowrap">`e1 >> e2` : *T*

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I've lost the context now.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually it's a ditto to the comment above, so I'm guessing this is in reference to >> vs >>>?

<td>Component-wise arithmetic shift right (OpShiftRightArithmetic)
</table>

<table class='data'>
<caption>Binary bitwise operations</caption>
<thead>
<tr><td>Precondition<td>Conclusion<td>Notes
</thead>
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is *Integral*
<td class="nowrap">`e1 | e2` : *T*
<td>Bitwise-or (OpBitwiseOr)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is *Integral*
<td class="nowrap">`e1 & e2` : *T*
<td>Bitwise-and (OpBitwiseAnd)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is *Integral*
<td class="nowrap">`e1 ^ e2` : *T*
<td>Bitwise-exclusive-or (OpBitwiseXor)
</table>

<table class='data'>
<caption>Comparisons over scalars</caption>
<thead>
<tr><td>Precondition<td>Conclusion<td>Notes
</thead>
<tr><td>*e1* : i32<br>
*e2* : i32<br>
<td class="nowrap">`e1 == e2` : bool
<td>Equality (OpIEqual)
<tr><td>*e1* : i32<br>
*e2* : i32<br>
<td class="nowrap">`e1 != e2` : bool
<td>Inequality (OpINotEqual)
<tr><td>*e1* : i32<br>
*e2* : i32<br>
<td class="nowrap">`e1 < e2` : bool
<td>Less than (OpSLessThan)
<tr><td>*e1* : i32<br>
*e2* : i32<br>
<td class="nowrap">`e1 <= e2` : bool
<td>Less than or equal (OpSLessThanEqual)
<tr><td>*e1* : i32<br>
*e2* : i32<br>
<td class="nowrap">`e1 >= e2` : bool
<td>Greater than or equal (OpSGreaterThanEqual)
<tr><td>*e1* : i32<br>
*e2* : i32<br>
<td class="nowrap">`e1 > e2` : bool
<td>Greater than or equal (OpSGreaterThan)
<tr><td>*e1* : u32<br>
*e2* : u32<br>
<td class="nowrap">`e1 == e2` : bool
<td>Equality (OpIEqual)
<tr><td>*e1* : u32<br>
*e2* : u32<br>
<td class="nowrap">`e1 != e2` : bool
<td>Inequality (OpINotEqual)
<tr><td>*e1* : u32<br>
*e2* : u32<br>
<td class="nowrap">`e1 < e2` : bool
<td>Less than (OpULessThan)
<tr><td>*e1* : u32<br>
*e2* : u32<br>
<td class="nowrap">`e1 <= e2` : bool
<td>Less than or equal (OpULessThanEqual)
<tr><td>*e1* : u32<br>
*e2* : u32<br>
<td class="nowrap">`e1 >= e2` : bool
<td>Greater than or equal (OpUGreaterThanEqual)
<tr><td>*e1* : u32<br>
*e2* : u32<br>
<td class="nowrap">`e1 > e2` : bool
<td>Greater than or equal (OpUGreaterThan)
<tr><td>*e1* : f32<br>
*e2* : f32<br>
<td class="nowrap">`e1 == e2` : bool
<td>Equality (OpFOrdEqual)
<tr><td>*e1* : f32<br>
*e2* : f32<br>
<td class="nowrap">`e1 != e2` : bool
<td>Equality (OpFOrdNotEqual)
<tr><td>*e1* : f32<br>
*e2* : f32<br>
<td class="nowrap">`e1 < e2` : bool
<td>Less than (OpFOrdLessThan)
<tr><td>*e1* : f32<br>
*e2* : f32<br>
<td class="nowrap">`e1 <= e2` : bool
<td>Less than or equal (OpFOrdLessThanEqual)
<tr><td>*e1* : f32<br>
*e2* : f32<br>
<td class="nowrap">`e1 >= e2` : bool
<td>Greater than or equal (OpFOrdGreaterThanEqual)
<tr><td>*e1* : f32<br>
*e2* : f32<br>
<td class="nowrap">`e1 > e2` : bool
<td>Greater than or equal (OpFOrdGreaterThan)
</table>

<table class='data'>
<caption>Comparisons over vectors</caption>
<thead>
<tr><td>Precondition<td>Conclusion<td>Notes
</thead>
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;i32&gt;
<td class="nowrap">`e1 == e2` : vec*N*&lt;bool&gt;
<td>Component-wise equality (OpIEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;i32&gt;
<td class="nowrap">`e1 != e2` : vec*N*&lt;bool&gt;
<td>Component-wise inequality (OpINotEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;i32&gt;
<td class="nowrap">`e1 < e2` : vec*N*&lt;bool&gt;
<td>Component-wise less than (OpSLessThan)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;i32&gt;
<td class="nowrap">`e1 <= e2` : vec*N*&lt;bool&gt;
<td>Component-wise less than or equal (OpSLessThanEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;i32&gt;
<td class="nowrap">`e1 >= e2` : vec*N*&lt;bool&gt;
<td>Component-wise greater than or equal (OpSGreaterThanEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;i32&gt;
<td class="nowrap">`e1 > e2` : vec*N*&lt;bool&gt;
<td>Component-wise greater than or equal (OpSGreaterThan)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;u32&gt;
<td class="nowrap">`e1 == e2` : vec*N*&lt;bool&gt;
<td>Component-wise equality (OpIEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;u32&gt;
<td class="nowrap">`e1 != e2` : vec*N*&lt;bool&gt;
<td>Component-wise inequality (OpINotEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;u32&gt;
<td class="nowrap">`e1 < e2` : vec*N*&lt;bool&gt;
<td>Component-wise less than (OpULessThan)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;u32&gt;
<td class="nowrap">`e1 <= e2` : vec*N*&lt;bool&gt;
<td>Component-wise less than or equal (OpULessThanEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;u32&gt;
<td class="nowrap">`e1 >= e2` : vec*N*&lt;bool&gt;
<td>Component-wise greater than or equal (OpUGreaterThanEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;u32&gt;
<td class="nowrap">`e1 > e2` : vec*N*&lt;bool&gt;
<td>Component-wise greater than or equal (OpUGreaterThan)
*T* is vec*N*&lt;u32&gt;
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;f32&gt;
<td class="nowrap">`e1 == e2` : vec*N*&lt;bool&gt;
<td>Component-wise equality (OpFOrdEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;f32&gt;
<td class="nowrap">`e1 != e2` : vec*N*&lt;bool&gt;
<td>Component-wise inequality (OpFOrdNotEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;f32&gt;
<td class="nowrap">`e1 < e2` : vec*N*&lt;bool&gt;
<td>Component-wise less than (OpFOrdLessThan)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;f32&gt;
<td class="nowrap">`e1 <= e2` : vec*N*&lt;bool&gt;
<td>Component-wise less than or equal (OpFOrdLessThanEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;f32&gt;
<td class="nowrap">`e1 >= e2` : vec*N*&lt;bool&gt;
<td>Component-wise greater than or equal (OpFOrdGreaterThanEqual)
<tr><td>*e1* : *T*<br>
*e2* : *T*<br>
*T* is vec*N*&lt;f32&gt;
<td class="nowrap">`e1 > e2` : vec*N*&lt;bool&gt;
<td>Component-wise greater than or equal (OpFOrdGreaterThan)
</table>

<table class='data'>
<caption>Binary logical expressions</caption>
<thead>
<tr><td>Precondition<td>Conclusion<td>Notes
</thead>
<tr><td>*e1* : bool<br>*e2* : bool<td>`e1 || e2` : bool<td>Logical or (OpLogicalOr)
<tr><td>*e1* : bool<br>*e2* : bool<td>`e1 && e2` : bool<td>Logical and (OpLogicalAnd)
<tr><td>*e1* : *T*<br>*e2* : *T*<br>*T* is *BoolVec*<td>`e1 || e2` : *T*<td>Component-wise logical or (OpLogicalOr)
<tr><td>*e1* : *T*<br>*e2* : *T*<br>*T* is *BoolVec*<td>`e1 && e2` : *T*<td>Component-wise logical and (OpLogicalAnd)
</table>

# Glossary # {#glossary}

<table class='data'>
Expand Down