Files
SoLUSH-3/onchain/src/Push3IntAdapter.sol
T

161 lines
5.1 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/console.sol";
import {Push3Interpreter} from "../src/Push3Interpreter.sol";
/**
* @title Push3IntAdapter
* @dev An adapter contract for our Push3Interpreter that provides
* various integer-only I/O function overloads. We now create
* a SUBLIST descriptor for the entire code array, placing it
* on the EXEC stack. We ignore finalCodeStack/finalExecStack
* to avoid compiler warnings.
*/
contract Push3IntAdapter {
Push3Interpreter public interpreter;
constructor(address _interpreter) {
interpreter = Push3Interpreter(_interpreter);
}
/**
* @notice Utility function to build a single sublist descriptor
* covering the entire `code` array, offset=0, length=code.length.
*/
function _makeFullSublistDescriptor(bytes calldata code)
internal
view
returns (uint256)
{
// CodeTag.SUBLIST is typically enum = 4, but
// let's fetch it via
// (uint8)Push3Interpreter.CodeTag.SUBLIST
// or we can directly pass 3 if we know the numeric value.
// We'll do:
return interpreter.makeDescriptor(
Push3Interpreter.CodeTag.SUBLIST, // the tag
0, // offset
uint32(code.length), // length of entire code array
0 // leftover bits=0
);
}
/**
* @notice Single int input, single int output.
* 1) Build a sublist descriptor for the entire code,
* 2) Place that descriptor in the EXEC stack,
* 3) Preload `in1` on the integer stack,
* 4) Run the interpreter,
* 5) Return top of final int stack.
*/
function run1In1Out(bytes calldata code, int256 in1)
external
view
returns (int256 out1)
{
// 1) Build the sublist descriptor
uint256 fullDesc = _makeFullSublistDescriptor(code);
// 2) EXEC stack of size 1
uint256[] memory initExecStack = new uint256[](1);
initExecStack[0] = fullDesc;
// No code stack
uint256[] memory initCodeStack = new uint256[](0);
// 3) Preload int stack
int256[] memory initIntStack = new int256[](1);
initIntStack[0] = in1;
// No bool stack
bool[] memory initBoolStack = new bool[](0);
// 4) Run
(, , int256[] memory finalIntStack,) =
interpreter.runInterpreter(code, initCodeStack, initExecStack, initIntStack, initBoolStack);
// 5) Return top of final int stack
require(finalIntStack.length > 0, "No integer output produced");
out1 = finalIntStack[finalIntStack.length - 1];
}
/**
* @notice Two ints input, single int output
*/
function run2In1Out(bytes calldata code, int256 in1, int256 in2)
external
view
returns (int256 out1)
{
uint256 fullDesc = _makeFullSublistDescriptor(code);
uint256[] memory initExecStack = new uint256[](1);
initExecStack[0] = fullDesc;
uint256[] memory initCodeStack = new uint256[](0);
int256[] memory initIntStack = new int256[](2);
initIntStack[0] = in1;
initIntStack[1] = in2;
bool[] memory initBoolStack = new bool[](0);
(, , int256[] memory finalIntStack,) =
interpreter.runInterpreter(code, initCodeStack, initExecStack, initIntStack, initBoolStack);
require(finalIntStack.length > 0, "No integer output");
out1 = finalIntStack[finalIntStack.length - 1];
}
/**
* @notice Single int input, two int outputs
*/
function run1In2Out(bytes calldata code, int256 in1)
external
view
returns (int256 out1, int256 out2)
{
uint256 fullDesc = _makeFullSublistDescriptor(code);
uint256[] memory initExecStack = new uint256[](1);
initExecStack[0] = fullDesc;
uint256[] memory initCodeStack = new uint256[](0);
int256[] memory initIntStack = new int256[](1);
initIntStack[0] = in1;
bool[] memory initBoolStack = new bool[](0);
(, , int256[] memory finalIntStack,) =
interpreter.runInterpreter(code, initCodeStack, initExecStack, initIntStack, initBoolStack);
require(finalIntStack.length >= 2, "Not enough outputs");
out1 = finalIntStack[finalIntStack.length - 1];
out2 = finalIntStack[finalIntStack.length - 2];
}
/**
* @notice Zero int input, returns entire final int stack
*/
function run0InNOut(bytes calldata code)
external
view
returns (int256[] memory)
{
uint256 fullDesc = _makeFullSublistDescriptor(code);
uint256[] memory initExecStack = new uint256[](1);
initExecStack[0] = fullDesc;
uint256[] memory initCodeStack = new uint256[](0);
int256[] memory initIntStack = new int256[](0);
bool[] memory initBoolStack = new bool[](0);
(, , int256[] memory finalIntStack,) =
interpreter.runInterpreter(code, initCodeStack, initExecStack, initIntStack, initBoolStack);
return finalIntStack;
}
}