diff --git a/.github/workflows/rainix.yaml b/.github/workflows/rainix.yaml index 9124547c2..23e65ca7e 100644 --- a/.github/workflows/rainix.yaml +++ b/.github/workflows/rainix.yaml @@ -34,9 +34,9 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main - uses: DeterminateSystems/magic-nix-cache-action@main - - run: nix develop --command rainix-sol-prelude - - run: nix develop --command rainix-rs-prelude - - run: nix develop --command i9r-prelude + - run: nix develop -c rainix-sol-prelude + - run: nix develop -c rainix-rs-prelude + - run: nix develop -c i9r-prelude - name: Run ${{ matrix.task }} env: ETH_RPC_URL: ${{ secrets.CI_DEPLOY_SEPOLIA_RPC_URL || vars.CI_DEPLOY_SEPOLIA_RPC_URL }} @@ -47,4 +47,4 @@ jobs: CI_FORK_SEPOLIA_BLOCK_NUMBER: ${{ vars.CI_FORK_SEPOLIA_BLOCK_NUMBER }} CI_FORK_SEPOLIA_DEPLOYER_ADDRESS: ${{ vars.CI_FORK_SEPOLIA_DEPLOYER_ADDRESS }} CI_DEPLOY_SEPOLIA_RPC_URL: ${{ secrets.CI_DEPLOY_SEPOLIA_RPC_URL || vars.CI_DEPLOY_SEPOLIA_RPC_URL }} - run: nix develop --command ${{ matrix.task }} \ No newline at end of file + run: nix develop -c ${{ matrix.task }} \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 1a1991483..788dba803 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "lib/rain.math.float"] path = lib/rain.math.float url = https://github.com/rainlanguage/rain.math.float +[submodule "lib/rain.string"] + path = lib/rain.string + url = https://github.com/rainlanguage/rain.string diff --git a/lib/rain.string b/lib/rain.string new file mode 160000 index 000000000..ad06da8e2 --- /dev/null +++ b/lib/rain.string @@ -0,0 +1 @@ +Subproject commit ad06da8e228b88556f99aae1bd94c4980ccc955e diff --git a/src/abstract/BaseRainterpreterSubParserNPE2.sol b/src/abstract/BaseRainterpreterSubParserNPE2.sol index f8a4c2b31..e7b688d34 100644 --- a/src/abstract/BaseRainterpreterSubParserNPE2.sol +++ b/src/abstract/BaseRainterpreterSubParserNPE2.sol @@ -7,7 +7,7 @@ import {LibBytes, Pointer} from "rain.solmem/lib/LibBytes.sol"; import {ISubParserV3, AuthoringMetaV2} from "rain.interpreter.interface/interface/ISubParserV3.sol"; import {IncompatibleSubParser} from "../error/ErrSubParse.sol"; import {LibSubParse, ParseState, CURRENT_COMPATIBILITY} from "../lib/parse/LibSubParse.sol"; -import {CMASK_RHS_WORD_TAIL} from "../lib/parse/LibParseCMask.sol"; +import {CMASK_RHS_WORD_TAIL} from "rain.string/lib/parse/LibParseCMask.sol"; import {LibParse, Operand} from "../lib/parse/LibParse.sol"; import {LibParseMeta} from "rain.interpreter.interface/lib/parse/LibParseMeta.sol"; import {LibParseOperand} from "../lib/parse/LibParseOperand.sol"; diff --git a/src/lib/parse/LibParse.sol b/src/lib/parse/LibParse.sol index 85fe700ab..85e43150b 100644 --- a/src/lib/parse/LibParse.sol +++ b/src/lib/parse/LibParse.sol @@ -19,7 +19,8 @@ import { COMMENT_START_SEQUENCE, COMMENT_END_SEQUENCE, CMASK_IDENTIFIER_HEAD -} from "./LibParseCMask.sol"; +} from "rain.string/lib/parse/LibParseCMask.sol"; +import {LibParseChar} from "rain.string/lib/parse/LibParseChar.sol"; import {LibCtPop} from "rain.math.binary/lib/LibCtPop.sol"; import {LibParseMeta} from "rain.interpreter.interface/lib/parse/LibParseMeta.sol"; import {LibParseLiteral} from "./literal/LibParseLiteral.sol"; @@ -121,25 +122,6 @@ library LibParse { } } - /// Skip an unlimited number of chars until we find one that is not in the - /// mask. - function skipMask(uint256 cursor, uint256 end, uint256 mask) internal pure returns (uint256) { - assembly ("memory-safe") { - //slither-disable-next-line incorrect-shift - for {} and(lt(cursor, end), gt(and(shl(byte(0, mload(cursor)), 1), mask), 0)) { cursor := add(cursor, 1) } {} - } - return cursor; - } - - /// Checks if the cursor points at a char of the given mask, and is in range - /// of end. - function isMask(uint256 cursor, uint256 end, uint256 mask) internal pure returns (uint256 result) { - assembly ("memory-safe") { - //slither-disable-next-line incorrect-shift - result := and(lt(cursor, end), iszero(iszero(and(shl(byte(0, mload(cursor)), 1), mask)))) - } - } - function parseLHS(ParseState memory state, uint256 cursor, uint256 end) internal pure returns (uint256) { unchecked { while (cursor < end) { @@ -169,7 +151,7 @@ library LibParse { } // Anon stack item. else { - cursor = skipMask(cursor + 1, end, CMASK_LHS_STACK_TAIL); + cursor = LibParseChar.skipMask(cursor + 1, end, CMASK_LHS_STACK_TAIL); } // Bump the index regardless of whether the stack // item is named or not. @@ -179,7 +161,7 @@ library LibParse { // Set yang as we are now building a stack item. state.fsm |= FSM_YANG_MASK | FSM_ACTIVE_SOURCE_MASK; } else if (char & CMASK_WHITESPACE != 0) { - cursor = skipMask(cursor + 1, end, CMASK_WHITESPACE); + cursor = LibParseChar.skipMask(cursor + 1, end, CMASK_WHITESPACE); // Set ying as we now open to possibilities. state.fsm &= ~FSM_YANG_MASK; } else if (char & CMASK_LHS_RHS_DELIMITER != 0) { @@ -374,7 +356,7 @@ library LibParse { state.highwater(); cursor++; } else if (char & CMASK_WHITESPACE > 0) { - cursor = skipMask(cursor + 1, end, CMASK_WHITESPACE); + cursor = LibParseChar.skipMask(cursor + 1, end, CMASK_WHITESPACE); // Set yin as we now open to possibilities. state.fsm &= ~FSM_YANG_MASK; } diff --git a/src/lib/parse/LibParseCMask.sol b/src/lib/parse/LibParseCMask.sol deleted file mode 100644 index d5ce4f05e..000000000 --- a/src/lib/parse/LibParseCMask.sol +++ /dev/null @@ -1,518 +0,0 @@ -// SPDX-License-Identifier: CAL -pragma solidity ^0.8.18; - -/// @dev Workaround for https://github.com/foundry-rs/foundry/issues/6572 -contract LibParseCMask {} - -/// @dev ASCII null -uint128 constant CMASK_NULL = uint128(1) << uint128(uint8(bytes1("\x00"))); - -/// @dev ASCII start of heading -uint128 constant CMASK_START_OF_HEADING = uint128(1) << uint128(uint8(bytes1("\x01"))); - -/// @dev ASCII start of text -uint128 constant CMASK_START_OF_TEXT = uint128(1) << uint128(uint8(bytes1("\x02"))); - -/// @dev ASCII end of text -uint128 constant CMASK_END_OF_TEXT = uint128(1) << uint128(uint8(bytes1("\x03"))); - -/// @dev ASCII end of transmission -uint128 constant CMASK_END_OF_TRANSMISSION = uint128(1) << uint128(uint8(bytes1("\x04"))); - -/// @dev ASCII enquiry -uint128 constant CMASK_ENQUIRY = uint128(1) << uint128(uint8(bytes1("\x05"))); - -/// @dev ASCII acknowledge -uint128 constant CMASK_ACKNOWLEDGE = uint128(1) << uint128(uint8(bytes1("\x06"))); - -/// @dev ASCII bell -uint128 constant CMASK_BELL = uint128(1) << uint128(uint8(bytes1("\x07"))); - -/// @dev ASCII backspace -uint128 constant CMASK_BACKSPACE = uint128(1) << uint128(uint8(bytes1("\x08"))); - -/// @dev ASCII horizontal tab -uint128 constant CMASK_HORIZONTAL_TAB = uint128(1) << uint128(uint8(bytes1("\t"))); - -/// @dev ASCII line feed -uint128 constant CMASK_LINE_FEED = uint128(1) << uint128(uint8(bytes1("\n"))); - -/// @dev ASCII vertical tab -uint128 constant CMASK_VERTICAL_TAB = uint128(1) << uint128(uint8(bytes1("\x0B"))); - -/// @dev ASCII form feed -uint128 constant CMASK_FORM_FEED = uint128(1) << uint128(uint8(bytes1("\x0C"))); - -/// @dev ASCII carriage return -uint128 constant CMASK_CARRIAGE_RETURN = uint128(1) << uint128(uint8(bytes1("\r"))); - -/// @dev ASCII shift out -uint128 constant CMASK_SHIFT_OUT = uint128(1) << uint128(uint8(bytes1("\x0E"))); - -/// @dev ASCII shift in -uint128 constant CMASK_SHIFT_IN = uint128(1) << uint128(uint8(bytes1("\x0F"))); - -/// @dev ASCII data link escape -uint128 constant CMASK_DATA_LINK_ESCAPE = uint128(1) << uint128(uint8(bytes1("\x10"))); - -/// @dev ASCII device control 1 -uint128 constant CMASK_DEVICE_CONTROL_1 = uint128(1) << uint128(uint8(bytes1("\x11"))); - -/// @dev ASCII device control 2 -uint128 constant CMASK_DEVICE_CONTROL_2 = uint128(1) << uint128(uint8(bytes1("\x12"))); - -/// @dev ASCII device control 3 -uint128 constant CMASK_DEVICE_CONTROL_3 = uint128(1) << uint128(uint8(bytes1("\x13"))); - -/// @dev ASCII device control 4 -uint128 constant CMASK_DEVICE_CONTROL_4 = uint128(1) << uint128(uint8(bytes1("\x14"))); - -/// @dev ASCII negative acknowledge -uint128 constant CMASK_NEGATIVE_ACKNOWLEDGE = uint128(1) << uint128(uint8(bytes1("\x15"))); - -/// @dev ASCII synchronous idle -uint128 constant CMASK_SYNCHRONOUS_IDLE = uint128(1) << uint128(uint8(bytes1("\x16"))); - -/// @dev ASCII end of transmission block -uint128 constant CMASK_END_OF_TRANSMISSION_BLOCK = uint128(1) << uint128(uint8(bytes1("\x17"))); - -/// @dev ASCII cancel -uint128 constant CMASK_CANCEL = uint128(1) << uint128(uint8(bytes1("\x18"))); - -/// @dev ASCII end of medium -uint128 constant CMASK_END_OF_MEDIUM = uint128(1) << uint128(uint8(bytes1("\x19"))); - -/// @dev ASCII substitute -uint128 constant CMASK_SUBSTITUTE = uint128(1) << uint128(uint8(bytes1("\x1A"))); - -/// @dev ASCII escape -uint128 constant CMASK_ESCAPE = uint128(1) << uint128(uint8(bytes1("\x1B"))); - -/// @dev ASCII file separator -uint128 constant CMASK_FILE_SEPARATOR = uint128(1) << uint128(uint8(bytes1("\x1C"))); - -/// @dev ASCII group separator -uint128 constant CMASK_GROUP_SEPARATOR = uint128(1) << uint128(uint8(bytes1("\x1D"))); - -/// @dev ASCII record separator -uint128 constant CMASK_RECORD_SEPARATOR = uint128(1) << uint128(uint8(bytes1("\x1E"))); - -/// @dev ASCII unit separator -uint128 constant CMASK_UNIT_SEPARATOR = uint128(1) << uint128(uint8(bytes1("\x1F"))); - -/// @dev ASCII space -uint128 constant CMASK_SPACE = uint128(1) << uint128(uint8(bytes1(" "))); - -/// @dev ASCII ! -uint128 constant CMASK_EXCLAMATION_MARK = uint128(1) << uint128(uint8(bytes1("!"))); - -/// @dev ASCII " -uint128 constant CMASK_QUOTATION_MARK = uint128(1) << uint128(uint8(bytes1("\""))); - -/// @dev ASCII # -uint128 constant CMASK_NUMBER_SIGN = uint128(1) << uint128(uint8(bytes1("#"))); - -/// @dev ASCII $ -uint128 constant CMASK_DOLLAR_SIGN = uint128(1) << uint128(uint8(bytes1("$"))); - -/// @dev ASCII % -uint128 constant CMASK_PERCENT_SIGN = uint128(1) << uint128(uint8(bytes1("%"))); - -/// @dev ASCII & -uint128 constant CMASK_AMPERSAND = uint128(1) << uint128(uint8(bytes1("&"))); - -/// @dev ASCII ' -uint128 constant CMASK_APOSTROPHE = uint128(1) << uint128(uint8(bytes1("'"))); - -/// @dev ASCII ( -uint128 constant CMASK_LEFT_PAREN = uint128(1) << uint128(uint8(bytes1("("))); - -/// @dev ASCII ) -uint128 constant CMASK_RIGHT_PAREN = uint128(1) << uint128(uint8(bytes1(")"))); - -/// @dev ASCII * -uint128 constant CMASK_ASTERISK = uint128(1) << uint128(uint8(bytes1("*"))); - -/// @dev ASCII + -uint128 constant CMASK_PLUS_SIGN = uint128(1) << uint128(uint8(bytes1("+"))); - -/// @dev ASCII , -uint128 constant CMASK_COMMA = uint128(1) << uint128(uint8(bytes1(","))); - -/// @dev ASCII - -uint128 constant CMASK_DASH = uint128(1) << uint128(uint8(bytes1("-"))); - -/// @dev ASCII . -uint128 constant CMASK_FULL_STOP = uint128(1) << uint128(uint8(bytes1("."))); - -/// @dev ASCII / -uint128 constant CMASK_SLASH = uint128(1) << uint128(uint8(bytes1("/"))); - -/// @dev ASCII 0 -uint128 constant CMASK_ZERO = uint128(1) << uint128(uint8(bytes1("0"))); - -/// @dev ASCII 1 -uint128 constant CMASK_ONE = uint128(1) << uint128(uint8(bytes1("1"))); - -/// @dev ASCII 2 -uint128 constant CMASK_TWO = uint128(1) << uint128(uint8(bytes1("2"))); - -/// @dev ASCII 3 -uint128 constant CMASK_THREE = uint128(1) << uint128(uint8(bytes1("3"))); - -/// @dev ASCII 4 -uint128 constant CMASK_FOUR = uint128(1) << uint128(uint8(bytes1("4"))); - -/// @dev ASCII 5 -uint128 constant CMASK_FIVE = uint128(1) << uint128(uint8(bytes1("5"))); - -/// @dev ASCII 6 -uint128 constant CMASK_SIX = uint128(1) << uint128(uint8(bytes1("6"))); - -/// @dev ASCII 7 -uint128 constant CMASK_SEVEN = uint128(1) << uint128(uint8(bytes1("7"))); - -/// @dev ASCII 8 -uint128 constant CMASK_EIGHT = uint128(1) << uint128(uint8(bytes1("8"))); - -/// @dev ASCII 9 -uint128 constant CMASK_NINE = uint128(1) << uint128(uint8(bytes1("9"))); - -/// @dev ASCII : -uint128 constant CMASK_COLON = uint128(1) << uint128(uint8(bytes1(":"))); - -/// @dev ASCII ; -uint128 constant CMASK_SEMICOLON = uint128(1) << uint128(uint8(bytes1(";"))); - -/// @dev ASCII < -uint128 constant CMASK_LESS_THAN_SIGN = uint128(1) << uint128(uint8(bytes1("<"))); - -/// @dev ASCII = -uint128 constant CMASK_EQUALS_SIGN = uint128(1) << uint128(uint8(bytes1("="))); - -/// @dev ASCII > -uint128 constant CMASK_GREATER_THAN_SIGN = uint128(1) << uint128(uint8(bytes1(">"))); - -/// @dev ASCII ? -uint128 constant CMASK_QUESTION_MARK = uint128(1) << uint128(uint8(bytes1("?"))); - -/// @dev ASCII @ -uint128 constant CMASK_AT_SIGN = uint128(1) << uint128(uint8(bytes1("@"))); - -/// @dev ASCII A -uint128 constant CMASK_UPPER_A = uint128(1) << uint128(uint8(bytes1("A"))); - -/// @dev ASCII B -uint128 constant CMASK_UPPER_B = uint128(1) << uint128(uint8(bytes1("B"))); - -/// @dev ASCII C -uint128 constant CMASK_UPPER_C = uint128(1) << uint128(uint8(bytes1("C"))); - -/// @dev ASCII D -uint128 constant CMASK_UPPER_D = uint128(1) << uint128(uint8(bytes1("D"))); - -/// @dev ASCII E -uint128 constant CMASK_UPPER_E = uint128(1) << uint128(uint8(bytes1("E"))); - -/// @dev ASCII F -uint128 constant CMASK_UPPER_F = uint128(1) << uint128(uint8(bytes1("F"))); - -/// @dev ASCII G -uint128 constant CMASK_UPPER_G = uint128(1) << uint128(uint8(bytes1("G"))); - -/// @dev ASCII H -uint128 constant CMASK_UPPER_H = uint128(1) << uint128(uint8(bytes1("H"))); - -/// @dev ASCII I -uint128 constant CMASK_UPPER_I = uint128(1) << uint128(uint8(bytes1("I"))); - -/// @dev ASCII J -uint128 constant CMASK_UPPER_J = uint128(1) << uint128(uint8(bytes1("J"))); - -/// @dev ASCII K -uint128 constant CMASK_UPPER_K = uint128(1) << uint128(uint8(bytes1("K"))); - -/// @dev ASCII L -uint128 constant CMASK_UPPER_L = uint128(1) << uint128(uint8(bytes1("L"))); - -/// @dev ASCII M -uint128 constant CMASK_UPPER_M = uint128(1) << uint128(uint8(bytes1("M"))); - -/// @dev ASCII N -uint128 constant CMASK_UPPER_N = uint128(1) << uint128(uint8(bytes1("N"))); - -/// @dev ASCII O -uint128 constant CMASK_UPPER_O = uint128(1) << uint128(uint8(bytes1("O"))); - -/// @dev ASCII P -uint128 constant CMASK_UPPER_P = uint128(1) << uint128(uint8(bytes1("P"))); - -/// @dev ASCII Q -uint128 constant CMASK_UPPER_Q = uint128(1) << uint128(uint8(bytes1("Q"))); - -/// @dev ASCII R -uint128 constant CMASK_UPPER_R = uint128(1) << uint128(uint8(bytes1("R"))); - -/// @dev ASCII S -uint128 constant CMASK_UPPER_S = uint128(1) << uint128(uint8(bytes1("S"))); - -/// @dev ASCII T -uint128 constant CMASK_UPPER_T = uint128(1) << uint128(uint8(bytes1("T"))); - -/// @dev ASCII U -uint128 constant CMASK_UPPER_U = uint128(1) << uint128(uint8(bytes1("U"))); - -/// @dev ASCII V -uint128 constant CMASK_UPPER_V = uint128(1) << uint128(uint8(bytes1("V"))); - -/// @dev ASCII W -uint128 constant CMASK_UPPER_W = uint128(1) << uint128(uint8(bytes1("W"))); - -/// @dev ASCII X -uint128 constant CMASK_UPPER_X = uint128(1) << uint128(uint8(bytes1("X"))); - -/// @dev ASCII Y -uint128 constant CMASK_UPPER_Y = uint128(1) << uint128(uint8(bytes1("Y"))); - -/// @dev ASCII Z -uint128 constant CMASK_UPPER_Z = uint128(1) << uint128(uint8(bytes1("Z"))); - -/// @dev ASCII [ -uint128 constant CMASK_LEFT_SQUARE_BRACKET = uint128(1) << uint128(uint8(bytes1("["))); - -/// @dev ASCII \ -uint128 constant CMASK_BACKSLASH = uint128(1) << uint128(uint8(bytes1("\\"))); - -/// @dev ASCII ] -uint128 constant CMASK_RIGHT_SQUARE_BRACKET = uint128(1) << uint128(uint8(bytes1("]"))); - -/// @dev ASCII ^ -uint128 constant CMASK_CIRCUMFLEX_ACCENT = uint128(1) << uint128(uint8(bytes1("^"))); - -/// @dev ASCII _ -uint128 constant CMASK_UNDERSCORE = uint128(1) << uint128(uint8(bytes1("_"))); - -/// @dev ASCII ` -uint128 constant CMASK_GRAVE_ACCENT = uint128(1) << uint128(uint8(bytes1("`"))); - -/// @dev ASCII a -uint128 constant CMASK_LOWER_A = uint128(1) << uint128(uint8(bytes1("a"))); - -/// @dev ASCII b -uint128 constant CMASK_LOWER_B = uint128(1) << uint128(uint8(bytes1("b"))); - -/// @dev ASCII c -uint128 constant CMASK_LOWER_C = uint128(1) << uint128(uint8(bytes1("c"))); - -/// @dev ASCII d -uint128 constant CMASK_LOWER_D = uint128(1) << uint128(uint8(bytes1("d"))); - -/// @dev ASCII e -uint128 constant CMASK_LOWER_E = uint128(1) << uint128(uint8(bytes1("e"))); - -/// @dev ASCII f -uint128 constant CMASK_LOWER_F = uint128(1) << uint128(uint8(bytes1("f"))); - -/// @dev ASCII g -uint128 constant CMASK_LOWER_G = uint128(1) << uint128(uint8(bytes1("g"))); - -/// @dev ASCII h -uint128 constant CMASK_LOWER_H = uint128(1) << uint128(uint8(bytes1("h"))); - -/// @dev ASCII i -uint128 constant CMASK_LOWER_I = uint128(1) << uint128(uint8(bytes1("i"))); - -/// @dev ASCII j -uint128 constant CMASK_LOWER_J = uint128(1) << uint128(uint8(bytes1("j"))); - -/// @dev ASCII k -uint128 constant CMASK_LOWER_K = uint128(1) << uint128(uint8(bytes1("k"))); - -/// @dev ASCII l -uint128 constant CMASK_LOWER_L = uint128(1) << uint128(uint8(bytes1("l"))); - -/// @dev ASCII m -uint128 constant CMASK_LOWER_M = uint128(1) << uint128(uint8(bytes1("m"))); - -/// @dev ASCII n -uint128 constant CMASK_LOWER_N = uint128(1) << uint128(uint8(bytes1("n"))); - -/// @dev ASCII o -uint128 constant CMASK_LOWER_O = uint128(1) << uint128(uint8(bytes1("o"))); - -/// @dev ASCII p -uint128 constant CMASK_LOWER_P = uint128(1) << uint128(uint8(bytes1("p"))); - -/// @dev ASCII q -uint128 constant CMASK_LOWER_Q = uint128(1) << uint128(uint8(bytes1("q"))); - -/// @dev ASCII r -uint128 constant CMASK_LOWER_R = uint128(1) << uint128(uint8(bytes1("r"))); - -/// @dev ASCII s -uint128 constant CMASK_LOWER_S = uint128(1) << uint128(uint8(bytes1("s"))); - -/// @dev ASCII t -uint128 constant CMASK_LOWER_T = uint128(1) << uint128(uint8(bytes1("t"))); - -/// @dev ASCII u -uint128 constant CMASK_LOWER_U = uint128(1) << uint128(uint8(bytes1("u"))); - -/// @dev ASCII v -uint128 constant CMASK_LOWER_V = uint128(1) << uint128(uint8(bytes1("v"))); - -/// @dev ASCII w -uint128 constant CMASK_LOWER_W = uint128(1) << uint128(uint8(bytes1("w"))); - -/// @dev ASCII x -uint128 constant CMASK_LOWER_X = uint128(1) << uint128(uint8(bytes1("x"))); - -/// @dev ASCII y -uint128 constant CMASK_LOWER_Y = uint128(1) << uint128(uint8(bytes1("y"))); - -/// @dev ASCII z -uint128 constant CMASK_LOWER_Z = uint128(1) << uint128(uint8(bytes1("z"))); - -/// @dev ASCII { -uint128 constant CMASK_LEFT_CURLY_BRACKET = uint128(1) << uint128(uint8(bytes1("{"))); - -/// @dev ASCII | -uint128 constant CMASK_VERTICAL_BAR = uint128(1) << uint128(uint8(bytes1("|"))); - -/// @dev ASCII } -uint128 constant CMASK_RIGHT_CURLY_BRACKET = uint128(1) << uint128(uint8(bytes1("}"))); - -/// @dev ASCII ~ -uint128 constant CMASK_TILDE = uint128(1) << uint128(uint8(bytes1("~"))); - -/// @dev ASCII delete -uint128 constant CMASK_DELETE = uint128(1) << uint128(uint8(bytes1("\x7F"))); - -/// @dev ASCII printable characters is everything 0x20 and above, except 0x7F -uint128 constant CMASK_PRINTABLE = ~( - CMASK_NULL | CMASK_START_OF_HEADING | CMASK_START_OF_TEXT | CMASK_END_OF_TEXT | CMASK_END_OF_TRANSMISSION - | CMASK_ENQUIRY | CMASK_ACKNOWLEDGE | CMASK_BELL | CMASK_BACKSPACE | CMASK_HORIZONTAL_TAB | CMASK_LINE_FEED - | CMASK_VERTICAL_TAB | CMASK_FORM_FEED | CMASK_CARRIAGE_RETURN | CMASK_SHIFT_OUT | CMASK_SHIFT_IN - | CMASK_DATA_LINK_ESCAPE | CMASK_DEVICE_CONTROL_1 | CMASK_DEVICE_CONTROL_2 | CMASK_DEVICE_CONTROL_3 - | CMASK_DEVICE_CONTROL_4 | CMASK_NEGATIVE_ACKNOWLEDGE | CMASK_SYNCHRONOUS_IDLE | CMASK_END_OF_TRANSMISSION_BLOCK - | CMASK_CANCEL | CMASK_END_OF_MEDIUM | CMASK_SUBSTITUTE | CMASK_ESCAPE | CMASK_FILE_SEPARATOR - | CMASK_GROUP_SEPARATOR | CMASK_RECORD_SEPARATOR | CMASK_UNIT_SEPARATOR | CMASK_DELETE -); - -/// @dev numeric 0-9 -uint128 constant CMASK_NUMERIC_0_9 = CMASK_ZERO | CMASK_ONE | CMASK_TWO | CMASK_THREE | CMASK_FOUR | CMASK_FIVE - | CMASK_SIX | CMASK_SEVEN | CMASK_EIGHT | CMASK_NINE; - -/// @dev e notation eE -uint128 constant CMASK_E_NOTATION = CMASK_LOWER_E | CMASK_UPPER_E; - -/// @dev decimal point . -uint128 constant CMASK_DECIMAL_POINT = CMASK_FULL_STOP; - -/// @dev negative sign - -uint128 constant CMASK_NEGATIVE_SIGN = CMASK_DASH; - -/// @dev lower alpha a-z -uint128 constant CMASK_LOWER_ALPHA_A_Z = CMASK_LOWER_A | CMASK_LOWER_B | CMASK_LOWER_C | CMASK_LOWER_D | CMASK_LOWER_E - | CMASK_LOWER_F | CMASK_LOWER_G | CMASK_LOWER_H | CMASK_LOWER_I | CMASK_LOWER_J | CMASK_LOWER_K | CMASK_LOWER_L - | CMASK_LOWER_M | CMASK_LOWER_N | CMASK_LOWER_O | CMASK_LOWER_P | CMASK_LOWER_Q | CMASK_LOWER_R | CMASK_LOWER_S - | CMASK_LOWER_T | CMASK_LOWER_U | CMASK_LOWER_V | CMASK_LOWER_W | CMASK_LOWER_X | CMASK_LOWER_Y | CMASK_LOWER_Z; - -/// @dev upper alpha A-Z -uint128 constant CMASK_UPPER_ALPHA_A_Z = CMASK_UPPER_A | CMASK_UPPER_B | CMASK_UPPER_C | CMASK_UPPER_D | CMASK_UPPER_E - | CMASK_UPPER_F | CMASK_UPPER_G | CMASK_UPPER_H | CMASK_UPPER_I | CMASK_UPPER_J | CMASK_UPPER_K | CMASK_UPPER_L - | CMASK_UPPER_M | CMASK_UPPER_N | CMASK_UPPER_O | CMASK_UPPER_P | CMASK_UPPER_Q | CMASK_UPPER_R | CMASK_UPPER_S - | CMASK_UPPER_T | CMASK_UPPER_U | CMASK_UPPER_V | CMASK_UPPER_W | CMASK_UPPER_X | CMASK_UPPER_Y | CMASK_UPPER_Z; - -/// @dev lower alpha a-f (hex) -uint128 constant CMASK_LOWER_ALPHA_A_F = - CMASK_LOWER_A | CMASK_LOWER_B | CMASK_LOWER_C | CMASK_LOWER_D | CMASK_LOWER_E | CMASK_LOWER_F; - -/// @dev upper alpha A-F (hex) -uint128 constant CMASK_UPPER_ALPHA_A_F = - CMASK_UPPER_A | CMASK_UPPER_B | CMASK_UPPER_C | CMASK_UPPER_D | CMASK_UPPER_E | CMASK_UPPER_F; - -/// @dev hex 0-9 a-f A-F -uint128 constant CMASK_HEX = CMASK_NUMERIC_0_9 | CMASK_LOWER_ALPHA_A_F | CMASK_UPPER_ALPHA_A_F; - -/// @dev Rainlang end of line is , -uint128 constant CMASK_EOL = CMASK_COMMA; - -/// @dev Rainlang LHS/RHS delimiter is : -uint128 constant CMASK_LHS_RHS_DELIMITER = CMASK_COLON; - -/// @dev Rainlang end of source is ; -uint128 constant CMASK_EOS = CMASK_SEMICOLON; - -/// @dev Rainlang stack head is lower alpha and underscore a-z _ -uint128 constant CMASK_LHS_STACK_HEAD = CMASK_LOWER_ALPHA_A_Z | CMASK_UNDERSCORE; - -/// @dev Rainlang identifier head is lower alpha a-z -uint128 constant CMASK_IDENTIFIER_HEAD = CMASK_LOWER_ALPHA_A_Z; -uint128 constant CMASK_RHS_WORD_HEAD = CMASK_IDENTIFIER_HEAD; - -/// @dev Rainlang stack/identifier tail is lower alphanumeric kebab a-z 0-9 - -uint128 constant CMASK_IDENTIFIER_TAIL = CMASK_IDENTIFIER_HEAD | CMASK_NUMERIC_0_9 | CMASK_DASH; -uint128 constant CMASK_LHS_STACK_TAIL = CMASK_IDENTIFIER_TAIL; -uint128 constant CMASK_RHS_WORD_TAIL = CMASK_IDENTIFIER_TAIL; - -/// @dev Rainlang operand start is < -uint128 constant CMASK_OPERAND_START = CMASK_LESS_THAN_SIGN; - -/// @dev Rainlang operand end is > -uint128 constant CMASK_OPERAND_END = CMASK_GREATER_THAN_SIGN; - -/// @dev NOT lower alphanumeric kebab -uint128 constant CMASK_NOT_IDENTIFIER_TAIL = ~CMASK_IDENTIFIER_TAIL; - -/// @dev Rainlang whitespace is \n \r \t space -uint128 constant CMASK_WHITESPACE = CMASK_LINE_FEED | CMASK_CARRIAGE_RETURN | CMASK_HORIZONTAL_TAB | CMASK_SPACE; - -/// @dev Rainlang stack item delimiter is whitespace -uint128 constant CMASK_LHS_STACK_DELIMITER = CMASK_WHITESPACE; - -/// @dev Rainlang supports numeric literals as anything starting with 0-9 or - -uint128 constant CMASK_NUMERIC_LITERAL_HEAD = CMASK_NUMERIC_0_9 | CMASK_NEGATIVE_SIGN; - -/// @dev Rainlang supports string literals as anything starting with " -uint128 constant CMASK_STRING_LITERAL_HEAD = CMASK_QUOTATION_MARK; - -/// @dev Rainlang supports sub parseable literals as anything starting with [ -uint128 constant CMASK_SUB_PARSEABLE_LITERAL_HEAD = CMASK_LEFT_SQUARE_BRACKET; - -/// @dev Rainlang ends a sub parseable literal with ] -uint128 constant CMASK_SUB_PARSEABLE_LITERAL_END = CMASK_RIGHT_SQUARE_BRACKET; - -/// @dev Rainlang string end is " -uint128 constant CMASK_STRING_LITERAL_END = CMASK_QUOTATION_MARK; - -/// @dev Rainlang string tail is any printable ASCII except " which ends it. -uint128 constant CMASK_STRING_LITERAL_TAIL = ~CMASK_STRING_LITERAL_END & CMASK_PRINTABLE; - -/// @dev Rainlang literal head -uint128 constant CMASK_LITERAL_HEAD = - CMASK_NUMERIC_LITERAL_HEAD | CMASK_STRING_LITERAL_HEAD | CMASK_SUB_PARSEABLE_LITERAL_HEAD; - -/// @dev Rainlang comment head is / -uint128 constant CMASK_COMMENT_HEAD = CMASK_SLASH; - -/// @dev Rainlang interstitial head could be some whitespace or a comment head. -uint128 constant CMASK_INTERSTITIAL_HEAD = CMASK_WHITESPACE | CMASK_COMMENT_HEAD; - -/// @dev Rainlang comment starting sequence is /* -uint256 constant COMMENT_START_SEQUENCE = uint256(uint16(bytes2("/*"))); - -/// @dev Rainlang comment ending sequence is */ -uint256 constant COMMENT_END_SEQUENCE = uint256(uint16(bytes2("*/"))); - -/// @dev Rainlang comment end sequence end byte is / */ -uint256 constant CMASK_COMMENT_END_SEQUENCE_END = COMMENT_END_SEQUENCE & 0xFF; - -/// @dev Rainlang literal hexadecimal dispatch is 0x -/// We compare the head and dispatch together to avoid a second comparison. -/// This is safe because the head is prefiltered to be 0-9 due to the numeric -/// literal head, therefore the only possible match is 0x (not x0). -uint128 constant CMASK_LITERAL_HEX_DISPATCH = CMASK_ZERO | CMASK_LOWER_X; - -/// @dev We may want to match the exact start of a hex literal. -uint256 constant CMASK_LITERAL_HEX_DISPATCH_START = uint256(uint16(bytes2("0x"))); diff --git a/src/lib/parse/LibParseInterstitial.sol b/src/lib/parse/LibParseInterstitial.sol index e77bde855..a078f60f7 100644 --- a/src/lib/parse/LibParseInterstitial.sol +++ b/src/lib/parse/LibParseInterstitial.sol @@ -8,10 +8,11 @@ import { COMMENT_END_SEQUENCE, COMMENT_START_SEQUENCE, CMASK_COMMENT_END_SEQUENCE_END -} from "./LibParseCMask.sol"; +} from "rain.string/lib/parse/LibParseCMask.sol"; import {ParserOutOfBounds, MalformedCommentStart, UnclosedComment} from "../../error/ErrParse.sol"; import {LibParseError} from "./LibParseError.sol"; import {LibParse} from "./LibParse.sol"; +import {LibParseChar} from "rain.string/lib/parse/LibParseChar.sol"; library LibParseInterstitial { using LibParse for ParseState; @@ -90,7 +91,7 @@ library LibParseInterstitial { unchecked { // Set ying as we now open to possibilities. state.fsm &= ~FSM_YANG_MASK; - return LibParse.skipMask(cursor, end, CMASK_WHITESPACE); + return LibParseChar.skipMask(cursor, end, CMASK_WHITESPACE); } } diff --git a/src/lib/parse/LibParseOperand.sol b/src/lib/parse/LibParseOperand.sol index be2dfb569..6a56dff78 100644 --- a/src/lib/parse/LibParseOperand.sol +++ b/src/lib/parse/LibParseOperand.sol @@ -12,7 +12,7 @@ import { import {Operand} from "rain.interpreter.interface/interface/unstable/IInterpreterV4.sol"; import {LibParse} from "./LibParse.sol"; import {LibParseLiteral} from "./literal/LibParseLiteral.sol"; -import {CMASK_OPERAND_END, CMASK_WHITESPACE, CMASK_OPERAND_START} from "./LibParseCMask.sol"; +import {CMASK_OPERAND_END, CMASK_WHITESPACE, CMASK_OPERAND_START} from "rain.string/lib/parse/LibParseCMask.sol"; import {ParseState, OPERAND_VALUES_LENGTH, FSM_YANG_MASK} from "./LibParseState.sol"; import {LibParseError} from "./LibParseError.sol"; import {LibParseInterstitial} from "./LibParseInterstitial.sol"; diff --git a/src/lib/parse/LibParsePragma.sol b/src/lib/parse/LibParsePragma.sol index 5cf19a447..d162afe07 100644 --- a/src/lib/parse/LibParsePragma.sol +++ b/src/lib/parse/LibParsePragma.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.18; import {LibParseState, ParseState} from "./LibParseState.sol"; -import {CMASK_WHITESPACE, CMASK_LITERAL_HEX_DISPATCH_START} from "./LibParseCMask.sol"; +import {CMASK_WHITESPACE, CMASK_LITERAL_HEX_DISPATCH_START} from "rain.string/lib/parse/LibParseCMask.sol"; import {NoWhitespaceAfterUsingWordsFrom} from "../../error/ErrParse.sol"; import {LibParseError} from "./LibParseError.sol"; import {LibParseInterstitial} from "./LibParseInterstitial.sol"; diff --git a/src/lib/parse/literal/LibParseLiteral.sol b/src/lib/parse/literal/LibParseLiteral.sol index a470d30a8..17de8cae3 100644 --- a/src/lib/parse/literal/LibParseLiteral.sol +++ b/src/lib/parse/literal/LibParseLiteral.sol @@ -13,7 +13,7 @@ import { CMASK_SUB_PARSEABLE_LITERAL_HEAD, CMASK_SUB_PARSEABLE_LITERAL_END, CMASK_WHITESPACE -} from "../LibParseCMask.sol"; +} from "rain.string/lib/parse/LibParseCMask.sol"; import {LibParse} from "../LibParse.sol"; import { diff --git a/src/lib/parse/literal/LibParseLiteralDecimal.sol b/src/lib/parse/literal/LibParseLiteralDecimal.sol index 426e2e57f..e2d199a02 100644 --- a/src/lib/parse/literal/LibParseLiteralDecimal.sol +++ b/src/lib/parse/literal/LibParseLiteralDecimal.sol @@ -15,7 +15,8 @@ import { CMASK_DECIMAL_POINT, CMASK_NEGATIVE_SIGN, CMASK_ZERO -} from "../LibParseCMask.sol"; +} from "rain.string/lib/parse/LibParseCMask.sol"; +import {LibParseChar} from "rain.string/lib/parse/LibParseChar.sol"; import {LibParseError} from "../LibParseError.sol"; import {LibParse} from "../LibParse.sol"; import {LibDecimalFloatImplementation, LibDecimalFloat} from "rain.math.float/lib/LibDecimalFloat.sol"; @@ -97,7 +98,7 @@ library LibParseLiteralDecimal { function unsafeStrToSignedInt(ParseState memory state, uint256 start, uint256 end) internal pure returns (int256) { unchecked { uint256 cursor = start; - uint256 isNeg = LibParse.isMask(cursor, end, CMASK_NEGATIVE_SIGN); + uint256 isNeg = LibParseChar.isMask(cursor, end, CMASK_NEGATIVE_SIGN); cursor += isNeg; uint256 value = state.unsafeStrToInt(cursor, end); @@ -149,28 +150,28 @@ library LibParseLiteralDecimal { { unchecked { cursor = start; - cursor = LibParse.skipMask(cursor, end, CMASK_NEGATIVE_SIGN); + cursor = LibParseChar.skipMask(cursor, end, CMASK_NEGATIVE_SIGN); { uint256 intStart = cursor; - cursor = LibParse.skipMask(cursor, end, CMASK_NUMERIC_0_9); + cursor = LibParseChar.skipMask(cursor, end, CMASK_NUMERIC_0_9); if (cursor == intStart) { revert ZeroLengthDecimal(state.parseErrorOffset(start)); } } signedCoefficient = state.unsafeStrToSignedInt(start, cursor); - int256 fracValue = int256(LibParse.isMask(cursor, end, CMASK_DECIMAL_POINT)); + int256 fracValue = int256(LibParseChar.isMask(cursor, end, CMASK_DECIMAL_POINT)); if (fracValue != 0) { cursor++; uint256 fracStart = cursor; - cursor = LibParse.skipMask(cursor, end, CMASK_NUMERIC_0_9); + cursor = LibParseChar.skipMask(cursor, end, CMASK_NUMERIC_0_9); if (cursor == fracStart) { revert MalformedDecimalPoint(state.parseErrorOffset(fracStart)); } // Trailing zeros are allowed in fractional literals but should // not be counted in the precision. uint256 nonZeroCursor = cursor; - while (LibParse.isMask(nonZeroCursor - 1, end, CMASK_ZERO) == 1) { + while (LibParseChar.isMask(nonZeroCursor - 1, end, CMASK_ZERO) == 1) { nonZeroCursor--; } @@ -198,14 +199,14 @@ library LibParseLiteralDecimal { signedCoefficient = rescaledIntValue + fracValue; } - int256 eValue = int256(LibParse.isMask(cursor, end, CMASK_E_NOTATION)); + int256 eValue = int256(LibParseChar.isMask(cursor, end, CMASK_E_NOTATION)); if (eValue != 0) { cursor++; uint256 eStart = cursor; - cursor = LibParse.skipMask(cursor, end, CMASK_NEGATIVE_SIGN); + cursor = LibParseChar.skipMask(cursor, end, CMASK_NEGATIVE_SIGN); { uint256 digitsStart = cursor; - cursor = LibParse.skipMask(cursor, end, CMASK_NUMERIC_0_9); + cursor = LibParseChar.skipMask(cursor, end, CMASK_NUMERIC_0_9); if (cursor == digitsStart) { revert MalformedExponentDigits(state.parseErrorOffset(digitsStart)); } diff --git a/src/lib/parse/literal/LibParseLiteralHex.sol b/src/lib/parse/literal/LibParseLiteralHex.sol index 04a1be08d..e29c74c13 100644 --- a/src/lib/parse/literal/LibParseLiteralHex.sol +++ b/src/lib/parse/literal/LibParseLiteralHex.sol @@ -8,7 +8,12 @@ import { ZeroLengthHexLiteral, HexLiteralOverflow } from "../../../error/ErrParse.sol"; -import {CMASK_UPPER_ALPHA_A_F, CMASK_LOWER_ALPHA_A_F, CMASK_NUMERIC_0_9, CMASK_HEX} from "../LibParseCMask.sol"; +import { + CMASK_UPPER_ALPHA_A_F, + CMASK_LOWER_ALPHA_A_F, + CMASK_NUMERIC_0_9, + CMASK_HEX +} from "rain.string/lib/parse/LibParseCMask.sol"; import {LibParseError} from "../LibParseError.sol"; library LibParseLiteralHex { diff --git a/src/lib/parse/literal/LibParseLiteralString.sol b/src/lib/parse/literal/LibParseLiteralString.sol index 3e737e051..d93127bc6 100644 --- a/src/lib/parse/literal/LibParseLiteralString.sol +++ b/src/lib/parse/literal/LibParseLiteralString.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.18; import {ParseState} from "../LibParseState.sol"; import {IntOrAString, LibIntOrAString} from "rain.intorastring/src/lib/LibIntOrAString.sol"; import {UnclosedStringLiteral, StringTooLong} from "../../../error/ErrParse.sol"; -import {CMASK_STRING_LITERAL_END, CMASK_STRING_LITERAL_TAIL} from "../LibParseCMask.sol"; +import {CMASK_STRING_LITERAL_END, CMASK_STRING_LITERAL_TAIL} from "rain.string/lib/parse/LibParseCMask.sol"; import {LibParseError} from "../LibParseError.sol"; /// @title LibParseLiteralString diff --git a/src/lib/parse/literal/LibParseLiteralSubParseable.sol b/src/lib/parse/literal/LibParseLiteralSubParseable.sol index fddfb24e3..202f282d0 100644 --- a/src/lib/parse/literal/LibParseLiteralSubParseable.sol +++ b/src/lib/parse/literal/LibParseLiteralSubParseable.sol @@ -5,11 +5,14 @@ import {ParseState} from "../LibParseState.sol"; import {LibParse} from "../LibParse.sol"; import {UnclosedSubParseableLiteral, SubParseableMissingDispatch} from "../../../error/ErrParse.sol"; import { - CMASK_WHITESPACE, CMASK_SUB_PARSEABLE_LITERAL_HEAD, CMASK_SUB_PARSEABLE_LITERAL_END -} from "../LibParseCMask.sol"; + CMASK_WHITESPACE, + CMASK_SUB_PARSEABLE_LITERAL_HEAD, + CMASK_SUB_PARSEABLE_LITERAL_END +} from "rain.string/lib/parse/LibParseCMask.sol"; import {LibParseInterstitial} from "../LibParseInterstitial.sol"; import {LibParseError} from "../LibParseError.sol"; import {LibSubParse} from "../LibSubParse.sol"; +import {LibParseChar} from "rain.string/lib/parse/LibParseChar.sol"; library LibParseLiteralSubParseable { using LibParse for ParseState; @@ -41,7 +44,7 @@ library LibParseLiteralSubParseable { uint256 dispatchStart = cursor; // Skip all non-whitespace and non-bracket characters. - cursor = LibParse.skipMask(cursor, end, ~(CMASK_WHITESPACE | CMASK_SUB_PARSEABLE_LITERAL_END)); + cursor = LibParseChar.skipMask(cursor, end, ~(CMASK_WHITESPACE | CMASK_SUB_PARSEABLE_LITERAL_END)); uint256 dispatchEnd = cursor; if (dispatchEnd == dispatchStart) { @@ -57,7 +60,7 @@ library LibParseLiteralSubParseable { // Note that as multibyte is not supported, and the mask is 128 bits, // non-ascii chars MAY either fail to be skipped or will be treated // as a closing bracket. - cursor = LibParse.skipMask(cursor, end, ~CMASK_SUB_PARSEABLE_LITERAL_END); + cursor = LibParseChar.skipMask(cursor, end, ~CMASK_SUB_PARSEABLE_LITERAL_END); uint256 bodyEnd = cursor; { diff --git a/test/lib/literal/LibLiteralString.sol b/test/lib/literal/LibLiteralString.sol index b5f1902c0..e369979b9 100644 --- a/test/lib/literal/LibLiteralString.sol +++ b/test/lib/literal/LibLiteralString.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: CAL pragma solidity ^0.8.18; -import {CMASK_STRING_LITERAL_TAIL, CMASK_HEX, CMASK_WHITESPACE} from "src/lib/parse/LibParseCMask.sol"; +import {CMASK_STRING_LITERAL_TAIL, CMASK_HEX, CMASK_WHITESPACE} from "rain.string/lib/parse/LibParseCMask.sol"; library LibLiteralString { function conformStringToMask(string memory str, uint256 mask, uint256 max) internal pure { diff --git a/test/src/concrete/RainterpreterStoreNPE2.t.sol b/test/src/concrete/RainterpreterStoreNPE2.t.sol index fb41814d7..14bdb7348 100644 --- a/test/src/concrete/RainterpreterStoreNPE2.t.sol +++ b/test/src/concrete/RainterpreterStoreNPE2.t.sol @@ -119,6 +119,7 @@ contract RainterpreterStoreNPE2Test is Test { /// is that the fuzzer will generate some dupes just randomly, so there's /// no special logic to make that happen. /// forge-config: default.fuzz.runs = 100 + function testRainterpreterStoreNPE2SetGetDupes(Set11[] memory sets) external { vm.assume(sets.length < 20); diff --git a/test/src/lib/parse/LibParse.isMask.t.sol b/test/src/lib/parse/LibParse.isMask.t.sol deleted file mode 100644 index 093de9836..000000000 --- a/test/src/lib/parse/LibParse.isMask.t.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: CAL -pragma solidity =0.8.25; - -import {Test} from "forge-std/Test.sol"; - -import {LibParse} from "src/lib/parse/LibParse.sol"; -import {LibPointer, Pointer} from "rain.solmem/lib/LibPointer.sol"; -import {LibBytes} from "rain.solmem/lib/LibBytes.sol"; -import {LibParseSlow} from "test/src/lib/parse/LibParseSlow.sol"; - -/// @title LibParseIsMaskTest -/// @notice Tests that the isMask function works correctly. -contract LibParseIsMaskTest is Test { - using LibBytes for bytes; - - /// Test that cursor at or past end is always false for isMask. - function testIsMaskPastEnd(uint256 cursor, uint256 end, uint256 mask) external pure { - // Limit to 16-bit values to avoid OOM reads. - end = bound(end, 0, type(uint16).max); - cursor = bound(cursor, end, type(uint16).max); - assertEq(LibParse.isMask(cursor, end, mask), 0); - } - - /// Test that isMask matches a reference implementation. - function testIsMaskReference(string memory s, uint256 index, uint256 mask) external pure { - vm.assume(bytes(s).length > 0); - index = bound(index, 0, bytes(s).length - 1); - - uint256 cursor = Pointer.unwrap(bytes(s).dataPointer()) + index; - uint256 end = Pointer.unwrap(bytes(s).endDataPointer()); - - assertEq(LibParse.isMask(cursor, end, mask), LibParseSlow.isMaskSlow(cursor, end, mask)); - } -} diff --git a/test/src/lib/parse/LibParse.parseWord.t.sol b/test/src/lib/parse/LibParse.parseWord.t.sol index 68bb38c1b..6c19e45f4 100644 --- a/test/src/lib/parse/LibParse.parseWord.t.sol +++ b/test/src/lib/parse/LibParse.parseWord.t.sol @@ -5,7 +5,7 @@ import {Test} from "forge-std/Test.sol"; import {LibParse} from "src/lib/parse/LibParse.sol"; import {Pointer, LibBytes} from "rain.solmem/lib/LibBytes.sol"; import {LibParseSlow} from "./LibParseSlow.sol"; -import {CMASK_NUMERIC_0_9} from "src/lib/parse/LibParseCMask.sol"; +import {CMASK_NUMERIC_0_9} from "rain.string/lib/parse/LibParseCMask.sol"; import {WordSize} from "src/error/ErrParse.sol"; /// @title LibParseParseWordTest diff --git a/test/src/lib/parse/LibParse.unexpectedLHS.t.sol b/test/src/lib/parse/LibParse.unexpectedLHS.t.sol index 5e2e7d1ef..30047deab 100644 --- a/test/src/lib/parse/LibParse.unexpectedLHS.t.sol +++ b/test/src/lib/parse/LibParse.unexpectedLHS.t.sol @@ -8,7 +8,7 @@ import { CMASK_LHS_RHS_DELIMITER, CMASK_LHS_STACK_DELIMITER, CMASK_LHS_STACK_HEAD -} from "src/lib/parse/LibParseCMask.sol"; +} from "rain.string/lib/parse/LibParseCMask.sol"; import {LibParse, UnexpectedLHSChar} from "src/lib/parse/LibParse.sol"; import {LibMetaFixture} from "test/lib/parse/LibMetaFixture.sol"; import {ParseState} from "src/lib/parse/LibParseState.sol"; diff --git a/test/src/lib/parse/LibParse.unexpectedRHS.t.sol b/test/src/lib/parse/LibParse.unexpectedRHS.t.sol index daec97858..9ebc62000 100644 --- a/test/src/lib/parse/LibParse.unexpectedRHS.t.sol +++ b/test/src/lib/parse/LibParse.unexpectedRHS.t.sol @@ -14,7 +14,7 @@ import { CMASK_EOL, CMASK_EOS, CMASK_COMMENT_HEAD -} from "src/lib/parse/LibParseCMask.sol"; +} from "rain.string/lib/parse/LibParseCMask.sol"; import {ParseState} from "src/lib/parse/LibParseState.sol"; /// @title LibParseUnexpectedRHSTest diff --git a/test/src/lib/parse/LibParsePragma.keyword.t.sol b/test/src/lib/parse/LibParsePragma.keyword.t.sol index 493c492e2..67835ce62 100644 --- a/test/src/lib/parse/LibParsePragma.keyword.t.sol +++ b/test/src/lib/parse/LibParsePragma.keyword.t.sol @@ -11,7 +11,7 @@ import { CMASK_LITERAL_HEX_DISPATCH_START, CMASK_INTERSTITIAL_HEAD, CMASK_HEX -} from "src/lib/parse/LibParseCMask.sol"; +} from "rain.string/lib/parse/LibParseCMask.sol"; import {LibLiteralString} from "test/lib/literal/LibLiteralString.sol"; import {NoWhitespaceAfterUsingWordsFrom} from "src/error/ErrParse.sol"; import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol"; diff --git a/test/src/lib/parse/LibParseSlow.sol b/test/src/lib/parse/LibParseSlow.sol index 916492dfa..38277362c 100644 --- a/test/src/lib/parse/LibParseSlow.sol +++ b/test/src/lib/parse/LibParseSlow.sol @@ -12,16 +12,4 @@ library LibParseSlow { } return data.length; } - - function isMaskSlow(uint256 cursor, uint256 end, uint256 mask) internal pure returns (uint256) { - if (cursor < end) { - uint256 wordAtCursor; - assembly ("memory-safe") { - wordAtCursor := mload(cursor) - } - return (1 << uint256(wordAtCursor >> 0xF8)) & mask > 0 ? 1 : 0; - } else { - return 0; - } - } } diff --git a/test/src/lib/parse/literal/LibParseLiteralHex.boundHex.t.sol b/test/src/lib/parse/literal/LibParseLiteralHex.boundHex.t.sol index 42bbc15b9..c24d8e341 100644 --- a/test/src/lib/parse/literal/LibParseLiteralHex.boundHex.t.sol +++ b/test/src/lib/parse/literal/LibParseLiteralHex.boundHex.t.sol @@ -5,7 +5,7 @@ import {ParseLiteralTest} from "test/abstract/ParseLiteralTest.sol"; import {ParseState} from "src/lib/parse/LibParseState.sol"; import {LibParseLiteral} from "src/lib/parse/literal/LibParseLiteral.sol"; import {LibLiteralString} from "test/lib/literal/LibLiteralString.sol"; -import {CMASK_HEX} from "src/lib/parse/LibParseCMask.sol"; +import {CMASK_HEX} from "rain.string/lib/parse/LibParseCMask.sol"; import {LibParseLiteralHex} from "src/lib/parse/literal/LibParseLiteralHex.sol"; /// @title LibParseLiteralBoundLiteralHexTest diff --git a/test/src/lib/parse/literal/LibParseLiteralString.parseString.t.sol b/test/src/lib/parse/literal/LibParseLiteralString.parseString.t.sol index 0e824dea3..ddf6d47fa 100644 --- a/test/src/lib/parse/literal/LibParseLiteralString.parseString.t.sol +++ b/test/src/lib/parse/literal/LibParseLiteralString.parseString.t.sol @@ -7,7 +7,7 @@ import {LibBytes, Pointer} from "rain.solmem/lib/LibBytes.sol"; import {IntOrAString, LibIntOrAString} from "rain.intorastring/src/lib/LibIntOrAString.sol"; import {LibParseState, ParseState} from "src/lib/parse/LibParseState.sol"; import {LibAllStandardOpsNP} from "src/lib/op/LibAllStandardOpsNP.sol"; -import {CMASK_STRING_LITERAL_TAIL} from "src/lib/parse/LibParseCMask.sol"; +import {CMASK_STRING_LITERAL_TAIL} from "rain.string/lib/parse/LibParseCMask.sol"; import {LibLiteralString} from "test/lib/literal/LibLiteralString.sol"; import {UnclosedStringLiteral} from "src/error/ErrParse.sol"; diff --git a/test/src/lib/parse/literal/LibParseLiteralSubParseable.parseSubParseable.t.sol b/test/src/lib/parse/literal/LibParseLiteralSubParseable.parseSubParseable.t.sol index fbc6d5083..0d90bc4da 100644 --- a/test/src/lib/parse/literal/LibParseLiteralSubParseable.parseSubParseable.t.sol +++ b/test/src/lib/parse/literal/LibParseLiteralSubParseable.parseSubParseable.t.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.25; -import {Test, console2} from "forge-std/Test.sol"; +import {Test} from "forge-std/Test.sol"; import {ParseState, Pointer, LibParseState} from "src/lib/parse/LibParseState.sol"; import {LibBytes} from "rain.solmem/lib/LibBytes.sol"; import {LibParseLiteralSubParseable} from "src/lib/parse/literal/LibParseLiteralSubParseable.sol"; import {UnclosedSubParseableLiteral, SubParseableMissingDispatch} from "src/error/ErrParse.sol"; import {ISubParserV3} from "rain.interpreter.interface/interface/ISubParserV3.sol"; import {LibLiteralString} from "test/lib/literal/LibLiteralString.sol"; -import {CMASK_WHITESPACE, CMASK_SUB_PARSEABLE_LITERAL_END} from "src/lib/parse/LibParseCMask.sol"; +import {CMASK_WHITESPACE, CMASK_SUB_PARSEABLE_LITERAL_END} from "rain.string/lib/parse/LibParseCMask.sol"; import {CURRENT_COMPATIBILITY} from "src/lib/parse/LibSubParse.sol"; contract LibParseLiteralSubParseableTest is Test {