-
Notifications
You must be signed in to change notification settings - Fork 386
Add type rules for binary operators #772
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1afb319
f67a3c0
4db97b3
db8a37d
be0e472
bf66713
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,9 @@ thead { | |
| background-color: #f0f0f0; | ||
| font-weight: bold; | ||
| } | ||
| .nowrap { | ||
| white-space:nowrap; | ||
| } | ||
| </style> | ||
|
|
||
| # Introduction # {#intro} | ||
|
|
@@ -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><< | ||
| <tr><td>`MOD`<td>% | ||
| <tr><td>`MODULO`<td>% | ||
| <tr><td>`MINUS`<td>- | ||
| <tr><td>`NAMESPACE`<td>:: | ||
| <tr><td>`PERIOD`<td>. | ||
|
|
@@ -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 | ||
|
|
@@ -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> | ||
|
|
@@ -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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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*<f32> | ||
| <td>`e1 * e2` : *T*<br> | ||
| `e2 * e1` : *T* | ||
| <td>Multiplication of a matrix and a scalar (OpMatrixTimesScalar) | ||
| <tr><td>*e1* : vec*M*<f32><br> | ||
| *e2* : mat*N*x*M*<f32> | ||
| <td>`e1 * e2` : vec*N*<f32><br> | ||
| <td>Vector times matrix (OpVectorTimesMatrix) | ||
| <tr><td>*e1* : mat*N*x*M*<f32><br> | ||
| *e2* : vec*N*<f32> | ||
| <td>`e1 * e2` : vec*M*<f32><br> | ||
| <td>Matrix times vector (OpMatrixTimesVector) | ||
| <tr><td>*e1* : mat*K*x*N*<f32><br> | ||
| *e2* : mat*M*x*K*<f32><br> | ||
| <td>`e1 * e2` : mat*M*x*N*<f32><br> | ||
| <td>Matrix times matrix (OpMatrixTimesMatrix) | ||
| </table> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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*<u32> | ||
| <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*<i32> | ||
| <td class="nowrap">`e1 >> e2` : *T* | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I've lost the context now.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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*<i32> | ||
| <td class="nowrap">`e1 == e2` : vec*N*<bool> | ||
| <td>Component-wise equality (OpIEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<i32> | ||
| <td class="nowrap">`e1 != e2` : vec*N*<bool> | ||
| <td>Component-wise inequality (OpINotEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<i32> | ||
| <td class="nowrap">`e1 < e2` : vec*N*<bool> | ||
| <td>Component-wise less than (OpSLessThan) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<i32> | ||
| <td class="nowrap">`e1 <= e2` : vec*N*<bool> | ||
| <td>Component-wise less than or equal (OpSLessThanEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<i32> | ||
| <td class="nowrap">`e1 >= e2` : vec*N*<bool> | ||
| <td>Component-wise greater than or equal (OpSGreaterThanEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<i32> | ||
| <td class="nowrap">`e1 > e2` : vec*N*<bool> | ||
| <td>Component-wise greater than or equal (OpSGreaterThan) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<u32> | ||
| <td class="nowrap">`e1 == e2` : vec*N*<bool> | ||
| <td>Component-wise equality (OpIEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<u32> | ||
| <td class="nowrap">`e1 != e2` : vec*N*<bool> | ||
| <td>Component-wise inequality (OpINotEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<u32> | ||
| <td class="nowrap">`e1 < e2` : vec*N*<bool> | ||
| <td>Component-wise less than (OpULessThan) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<u32> | ||
| <td class="nowrap">`e1 <= e2` : vec*N*<bool> | ||
| <td>Component-wise less than or equal (OpULessThanEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<u32> | ||
| <td class="nowrap">`e1 >= e2` : vec*N*<bool> | ||
| <td>Component-wise greater than or equal (OpUGreaterThanEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<u32> | ||
| <td class="nowrap">`e1 > e2` : vec*N*<bool> | ||
| <td>Component-wise greater than or equal (OpUGreaterThan) | ||
| *T* is vec*N*<u32> | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<f32> | ||
| <td class="nowrap">`e1 == e2` : vec*N*<bool> | ||
| <td>Component-wise equality (OpFOrdEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<f32> | ||
| <td class="nowrap">`e1 != e2` : vec*N*<bool> | ||
| <td>Component-wise inequality (OpFOrdNotEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<f32> | ||
| <td class="nowrap">`e1 < e2` : vec*N*<bool> | ||
| <td>Component-wise less than (OpFOrdLessThan) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<f32> | ||
| <td class="nowrap">`e1 <= e2` : vec*N*<bool> | ||
| <td>Component-wise less than or equal (OpFOrdLessThanEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<f32> | ||
| <td class="nowrap">`e1 >= e2` : vec*N*<bool> | ||
| <td>Component-wise greater than or equal (OpFOrdGreaterThanEqual) | ||
| <tr><td>*e1* : *T*<br> | ||
| *e2* : *T*<br> | ||
| *T* is vec*N*<f32> | ||
| <td class="nowrap">`e1 > e2` : vec*N*<bool> | ||
| <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'> | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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.