Skip to content
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

Fix ternary tests and optimize TERNARY macro #97

Merged
merged 4 commits into from
Feb 20, 2023
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
30 changes: 16 additions & 14 deletions src/utils/Ternary.huff
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,43 @@


/// @notice Not Ternary
/// @notice In shorthand, this is `!condition ? x : y`, where the input stack is [!condition, x, y]
/// @notice In shorthand, this is `!condition ? x : y`, where the input stack is [condition, x, y]
#define macro NOT_TERNARY() = takes(3) returns(1) {
// Input Stack: [!condition, x, y]
// Output Stack: [!condition ? x : y]
// Input Stack: [condition, x, y]

// If the condition is true, jump and pop
__Utils_Misc__ternaryNoSwap jumpi
swap1
swap1 // [y, x]
__Utils_Misc__ternaryNoSwap:
// Stack: condition ? [x, y] : [y, x]
pop

// Output Stack: [condition ? y : x]
}

/// @notice Ternary
/// @notice In shorthand, this is `condition ? x : y`, where the input stack is [condition, x, y]
/// @dev ((x ^ y) * condition) ^ y
#define macro TERNARY() = takes(3) returns(1) {
// Input Stack: [condition, x, y]
swap1 // [x, condition, y]
dup3 // [y, x, condition, y]
xor mul xor // [((x ^ y) * condition) ^ y]
devtooligan marked this conversation as resolved.
Show resolved Hide resolved
// Output Stack: [condition ? x : y]

// If the condition is false, jump and pop
__Utils_Misc__ternaryNoSwap iszero jumpi
swap1
__Utils_Misc__ternaryNoSwap:
pop
}

// TESTS

/// @notice Tests the NOT_TERNARY() macro
#define test TEST_NOT_TERNARY() = {
// Test false should return the first element
0x00 0x01 0x02 NOT_TERNARY()
0x02 0x01 0x00 NOT_TERNARY()
0x01 eq worked jumpi
0x00 0x00 revert
worked:

// Test true should return the second element
0x01 0x01 0x02 NOT_TERNARY()
0x02 0x01 0x01 NOT_TERNARY()
0x02 eq worked_again jumpi
0x00 0x00 revert
worked_again:
Expand All @@ -50,13 +50,15 @@
/// @notice Tests the TERNARY() macro
#define test TEST_TERNARY() = {
// Test true should return the first element
0x01 0x01 0x02 NOT_TERNARY()
// 1 ? 1 : 2 == 1
0x02 0x01 0x01 TERNARY()
0x01 eq worked jumpi
0x00 0x00 revert
worked:

// Test false should return the second element
0x00 0x01 0x02 NOT_TERNARY()
// 0 ? 1 : 2 == 2
0x02 0x01 0x00 TERNARY()
0x02 eq worked_again jumpi
0x00 0x00 revert
worked_again:
Expand Down