-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4d802fa
commit 2e819dd
Showing
5 changed files
with
122 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
LibParseCharIsMaskTest:testIsMaskPastEnd(uint256,uint256,uint256) (runs: 256, μ: 16949, ~: 19250) | ||
LibParseCharIsMaskTest:testIsMaskReference(string,uint256,uint256) (runs: 256, μ: 8346, ~: 8396) | ||
LibParseCharIsMaskTest:testIsMaskPastEnd(uint256,uint256,uint256) (runs: 257, μ: 16977, ~: 19628) | ||
LibParseCharIsMaskTest:testIsMaskReference(string,uint256,uint256) (runs: 257, μ: 8346, ~: 8396) | ||
LibParseCharSkipMaskTest:testSkipMaskPastEnd(uint256,uint256,uint256) (runs: 257, μ: 17219, ~: 19710) | ||
LibParseCharSkipMaskTest:testSkipMaskReference(string,uint256,uint256) (runs: 257, μ: 8587, ~: 8461) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,61 @@ | ||
# rain.string | ||
|
||
Tools for working with strings that we've found useful to build Rainlang. | ||
|
||
More specialised and complex parsing logic exists in other Rainlang repos, but | ||
this stuff is broadly applicable and low level enough to be gas efficient enough | ||
to do what needs to be done. | ||
|
||
Generally parsing in rainlang works like a bloom filter on individual characters. | ||
We read characters from memory one byte at a time then bit shift to compare it | ||
against a bitmap mask that represents characters of interest. For example we | ||
might need to know if a character is numeric `0-9` or alphanumeric `a-zA-Z0-9`, | ||
and we cannot rely on regexes, in memory sets, or even loops, that might be | ||
easily at hand for similar tasks in other languages. | ||
|
||
Luckily, EVM values are 32 bytes and so we can fit all posssible ASCII characters | ||
in a single value as a bloom without any ambiguity. | ||
|
||
## Dev stuff | ||
|
||
### Local environment & CI | ||
|
||
Uses nixos. | ||
|
||
Install `nix develop` - https://nixos.org/download.html. | ||
|
||
Run `nix develop` in this repo to drop into the shell. Please ONLY use the nix | ||
version of `foundry` for development, to ensure versions are all compatible. | ||
|
||
Read the `flake.nix` file to find some additional commands included for dev and | ||
CI usage. | ||
|
||
## Legal stuff | ||
|
||
Everything is under DecentraLicense 1.0 (DCL-1.0) which can be found in `LICENSES/`. | ||
|
||
This is basically `CAL-1.0` which is an open source license | ||
https://opensource.org/license/cal-1-0 | ||
|
||
The non-legal summary of DCL-1.0 is that the source is open, as expected, but | ||
also user data in the systems that this code runs on must also be made available | ||
to those users as relevant, and that private keys remain private. | ||
|
||
Roughly it's "not your keys, not your coins" aware, as close as we could get in | ||
legalese. | ||
|
||
This is the default situation on permissionless blockchains, so shouldn't require | ||
any additional effort by dev-users to adhere to the license terms. | ||
|
||
This repo is REUSE 3.2 compliant https://reuse.software/spec-3.2/ and compatible | ||
with `reuse` tooling (also available in the nix shell here). | ||
|
||
``` | ||
nix develop -c rainix-sol-legal | ||
``` | ||
|
||
## Contributions | ||
|
||
Contributions are welcome **under the same license** as above. | ||
|
||
Contributors agree and warrant that their contributions are compliant. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// SPDX-License-Identifier: LicenseRef-DCL-1.0 | ||
// SPDX-FileCopyrightText: Copyright (c) 2020 thedavidmeister | ||
pragma solidity =0.8.25; | ||
|
||
import {Test} from "forge-std/Test.sol"; | ||
|
||
import {LibParseChar} from "src/lib/parse/LibParseChar.sol"; | ||
import {LibPointer, Pointer} from "rain.solmem/lib/LibPointer.sol"; | ||
import {LibBytes} from "rain.solmem/lib/LibBytes.sol"; | ||
import {LibParseCharSlow} from "test/lib/parse/LibParseCharSlow.sol"; | ||
|
||
/// @title LibParseCharSkipMaskTest | ||
/// @notice Tests that the isMask function works correctly. | ||
contract LibParseCharSkipMaskTest is Test { | ||
using LibBytes for bytes; | ||
|
||
/// Test that cursor at or past end is always the end for skipMask. | ||
function testSkipMaskPastEnd(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(LibParseChar.skipMask(cursor, end, mask), cursor); | ||
} | ||
|
||
/// Test that skipMask matches a reference implementation. | ||
function testSkipMaskReference(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(LibParseChar.skipMask(cursor, end, mask), LibParseCharSlow.skipMaskSlow(cursor, end, mask)); | ||
} | ||
} |