brik64 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- brik64-2.0.0/PKG-INFO +44 -0
- brik64-2.0.0/README.md +26 -0
- brik64-2.0.0/pyproject.toml +29 -0
- brik64-2.0.0/src/brik64/__init__.py +5 -0
- brik64-2.0.0/src/brik64/eva/__init__.py +50 -0
- brik64-2.0.0/src/brik64/mc/__init__.py +4 -0
- brik64-2.0.0/src/brik64/mc/arithmetic.py +49 -0
- brik64-2.0.0/src/brik64/mc/control.py +45 -0
- brik64-2.0.0/src/brik64/mc/crypto.py +48 -0
- brik64-2.0.0/src/brik64/mc/io.py +63 -0
- brik64-2.0.0/src/brik64/mc/logic.py +45 -0
- brik64-2.0.0/src/brik64/mc/memory.py +52 -0
- brik64-2.0.0/src/brik64/mc/string.py +45 -0
- brik64-2.0.0/src/brik64/mc/system.py +44 -0
- brik64-2.0.0/tests/test_arithmetic.py +22 -0
brik64-2.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: brik64
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: BRIK-64 Digital Circuitality — 64 formally verified monomers for Python
|
|
5
|
+
Project-URL: Homepage, https://brik64.dev
|
|
6
|
+
Project-URL: Repository, https://github.com/brik64/brik64-lib-python
|
|
7
|
+
Project-URL: Documentation, https://docs.brik64.dev
|
|
8
|
+
Author-email: "BRIK-64 Inc." <admin@brik64.dev>
|
|
9
|
+
License: Proprietary
|
|
10
|
+
Keywords: brik64,digital-circuitality,formal-methods,monomers,verified
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# brik64 — Digital Circuitality for Python
|
|
20
|
+
|
|
21
|
+
64 formally verified atomic operations (monomers) implementing the BRIK-64 Digital Circuitality architecture.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install brik64
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from brik64 import mc, eva
|
|
33
|
+
|
|
34
|
+
# Arithmetic
|
|
35
|
+
result = mc.arithmetic.add8(200, 100) # saturating: 255
|
|
36
|
+
q, r = mc.arithmetic.div8(17, 5) # (3, 2)
|
|
37
|
+
|
|
38
|
+
# EVA algebra
|
|
39
|
+
pipeline = eva.seq(mc.arithmetic.add8, lambda x: x * 2)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
Proprietary — © 2026 BRIK-64 Inc.
|
brik64-2.0.0/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# brik64 — Digital Circuitality for Python
|
|
2
|
+
|
|
3
|
+
64 formally verified atomic operations (monomers) implementing the BRIK-64 Digital Circuitality architecture.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install brik64
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from brik64 import mc, eva
|
|
15
|
+
|
|
16
|
+
# Arithmetic
|
|
17
|
+
result = mc.arithmetic.add8(200, 100) # saturating: 255
|
|
18
|
+
q, r = mc.arithmetic.div8(17, 5) # (3, 2)
|
|
19
|
+
|
|
20
|
+
# EVA algebra
|
|
21
|
+
pipeline = eva.seq(mc.arithmetic.add8, lambda x: x * 2)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## License
|
|
25
|
+
|
|
26
|
+
Proprietary — © 2026 BRIK-64 Inc.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "brik64"
|
|
7
|
+
version = "2.0.0"
|
|
8
|
+
description = "BRIK-64 Digital Circuitality — 64 formally verified monomers for Python"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "Proprietary" }
|
|
12
|
+
authors = [{ name = "BRIK-64 Inc.", email = "admin@brik64.dev" }]
|
|
13
|
+
keywords = ["brik64", "digital-circuitality", "verified", "formal-methods", "monomers"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3.10",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Topic :: Software Development :: Libraries",
|
|
20
|
+
]
|
|
21
|
+
dependencies = []
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://brik64.dev"
|
|
25
|
+
Repository = "https://github.com/brik64/brik64-lib-python"
|
|
26
|
+
Documentation = "https://docs.brik64.dev"
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel]
|
|
29
|
+
packages = ["src/brik64"]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""EVA algebra — composition operators for BRIK-64 monomers."""
|
|
2
|
+
from typing import Any, Callable, TypeVar
|
|
3
|
+
|
|
4
|
+
A = TypeVar("A")
|
|
5
|
+
B = TypeVar("B")
|
|
6
|
+
C = TypeVar("C")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def seq(f: Callable[[A], B], g: Callable[[B], C]) -> Callable[[A], C]:
|
|
10
|
+
"""⊗ Sequential composition: g(f(x))."""
|
|
11
|
+
def composed(x: A) -> C:
|
|
12
|
+
return g(f(x))
|
|
13
|
+
return composed
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def par(f: Callable, g: Callable) -> Callable:
|
|
17
|
+
"""∥ Parallel composition: (f(a), g(b))."""
|
|
18
|
+
def composed(a: Any, b: Any) -> tuple:
|
|
19
|
+
return (f(a), g(b))
|
|
20
|
+
return composed
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def cond(pred: Callable[[Any], bool], then_f: Callable, else_f: Callable) -> Callable:
|
|
24
|
+
"""⊕ Conditional composition: pred(x) ? then_f(x) : else_f(x)."""
|
|
25
|
+
def composed(x: Any) -> Any:
|
|
26
|
+
return then_f(x) if pred(x) else else_f(x)
|
|
27
|
+
return composed
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def pipeline(*fns: Callable) -> Callable:
|
|
31
|
+
"""Chain multiple functions sequentially."""
|
|
32
|
+
def composed(x: Any) -> Any:
|
|
33
|
+
result = x
|
|
34
|
+
for f in fns:
|
|
35
|
+
result = f(result)
|
|
36
|
+
return result
|
|
37
|
+
return composed
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def compose(*fns: Callable) -> Callable:
|
|
41
|
+
"""Compose functions right-to-left (mathematical convention)."""
|
|
42
|
+
def composed(x: Any) -> Any:
|
|
43
|
+
result = x
|
|
44
|
+
for f in reversed(fns):
|
|
45
|
+
result = f(result)
|
|
46
|
+
return result
|
|
47
|
+
return composed
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
__all__ = ["seq", "par", "cond", "pipeline", "compose"]
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""F0 — Arithmetic monomers (MC_00–MC_07)."""
|
|
2
|
+
|
|
3
|
+
_U8_MAX = 255
|
|
4
|
+
_I64_MIN = -(2**63)
|
|
5
|
+
_I64_MAX = 2**63 - 1
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def add8(a: int, b: int) -> int:
|
|
9
|
+
"""MC_00: saturating u8 addition."""
|
|
10
|
+
return min(a + b, _U8_MAX)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def sub8(a: int, b: int) -> int:
|
|
14
|
+
"""MC_01: saturating u8 subtraction."""
|
|
15
|
+
return max(a - b, 0)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def mul8(a: int, b: int) -> int:
|
|
19
|
+
"""MC_02: saturating u8 multiplication."""
|
|
20
|
+
return min(a * b, _U8_MAX)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def div8(a: int, b: int) -> tuple[int, int]:
|
|
24
|
+
"""MC_03: u8 division → (quotient, remainder). div-by-zero → (0, 0)."""
|
|
25
|
+
if b == 0:
|
|
26
|
+
return (0, 0)
|
|
27
|
+
return (a // b, a % b)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def mod8(a: int, b: int) -> int:
|
|
31
|
+
"""MC_04: u8 modulo. mod-by-zero → 0."""
|
|
32
|
+
if b == 0:
|
|
33
|
+
return 0
|
|
34
|
+
return a % b
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def abs64(a: int) -> int:
|
|
38
|
+
"""MC_05: i64 absolute value."""
|
|
39
|
+
return abs(a)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def neg64(a: int) -> int:
|
|
43
|
+
"""MC_06: i64 negation, clamped to i64 range."""
|
|
44
|
+
return max(_I64_MIN, -a)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def clamp(val: int, lo: int, hi: int) -> int:
|
|
48
|
+
"""MC_07: clamp value to [lo, hi]."""
|
|
49
|
+
return max(lo, min(val, hi))
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""F3 — Control monomers (MC_24–MC_31)."""
|
|
2
|
+
from typing import Any, Callable
|
|
3
|
+
|
|
4
|
+
_MAX_LOOPS = 1_000_000
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def mc_if(cond: bool, then_val: Any, else_val: Any) -> Any:
|
|
8
|
+
"""MC_24: conditional select."""
|
|
9
|
+
return then_val if cond else else_val
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def mc_loop(n: int, f: Callable[[int], None]) -> None:
|
|
13
|
+
"""MC_25: bounded loop (capped at 1,000,000 iterations)."""
|
|
14
|
+
for i in range(min(n, _MAX_LOOPS)):
|
|
15
|
+
f(i)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def nop() -> None:
|
|
19
|
+
"""MC_26: no operation."""
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def halt(code: int = 0) -> int:
|
|
24
|
+
"""MC_27: return exit code."""
|
|
25
|
+
return code
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def cmp_eq(a: Any, b: Any) -> bool:
|
|
29
|
+
"""MC_28: equality comparison."""
|
|
30
|
+
return a == b
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def cmp_lt(a: Any, b: Any) -> bool:
|
|
34
|
+
"""MC_29: less-than comparison."""
|
|
35
|
+
return a < b
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def cmp_gt(a: Any, b: Any) -> bool:
|
|
39
|
+
"""MC_30: greater-than comparison."""
|
|
40
|
+
return a > b
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def mc_call(f: Callable, *args: Any) -> Any:
|
|
44
|
+
"""MC_31: call a function."""
|
|
45
|
+
return f(*args)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""F6 — Crypto monomers (MC_48–MC_55)."""
|
|
2
|
+
import hashlib
|
|
3
|
+
import hmac as _hmac
|
|
4
|
+
import secrets
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def hash_sha256(data: bytes) -> bytes:
|
|
8
|
+
"""MC_48: SHA-256 hash."""
|
|
9
|
+
return hashlib.sha256(data).digest()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def hash_hex(data: bytes) -> str:
|
|
13
|
+
"""MC_49: SHA-256 hex digest."""
|
|
14
|
+
return hashlib.sha256(data).hexdigest()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def xor_bytes(a: bytes, b: bytes) -> bytes:
|
|
18
|
+
"""MC_50: XOR two byte sequences (truncates to shorter length)."""
|
|
19
|
+
return bytes(x ^ y for x, y in zip(a, b))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def rotate_left(val: int, shift: int, bits: int = 32) -> int:
|
|
23
|
+
"""MC_51: rotate left."""
|
|
24
|
+
shift %= bits
|
|
25
|
+
mask = (1 << bits) - 1
|
|
26
|
+
return ((val << shift) | (val >> (bits - shift))) & mask
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def rotate_right(val: int, shift: int, bits: int = 32) -> int:
|
|
30
|
+
"""MC_52: rotate right."""
|
|
31
|
+
shift %= bits
|
|
32
|
+
mask = (1 << bits) - 1
|
|
33
|
+
return ((val >> shift) | (val << (bits - shift))) & mask
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def constant_eq(a: bytes, b: bytes) -> bool:
|
|
37
|
+
"""MC_53: timing-safe equality comparison."""
|
|
38
|
+
return _hmac.compare_digest(a, b)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def zero_bytes(n: int) -> bytes:
|
|
42
|
+
"""MC_54: generate n zero bytes."""
|
|
43
|
+
return bytes(n)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def bytes_to_hex(data: bytes) -> str:
|
|
47
|
+
"""MC_55: bytes to hex string."""
|
|
48
|
+
return data.hex()
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""F4 — I/O monomers (MC_32–MC_39)."""
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def read_file(path: str) -> str | None:
|
|
7
|
+
"""MC_32: read file contents."""
|
|
8
|
+
try:
|
|
9
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
10
|
+
return f.read()
|
|
11
|
+
except OSError:
|
|
12
|
+
return None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def write_file(path: str, content: str) -> bool:
|
|
16
|
+
"""MC_33: write file contents."""
|
|
17
|
+
try:
|
|
18
|
+
with open(path, "w", encoding="utf-8") as f:
|
|
19
|
+
f.write(content)
|
|
20
|
+
return True
|
|
21
|
+
except OSError:
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def append_file(path: str, content: str) -> bool:
|
|
26
|
+
"""MC_34: append to file."""
|
|
27
|
+
try:
|
|
28
|
+
with open(path, "a", encoding="utf-8") as f:
|
|
29
|
+
f.write(content)
|
|
30
|
+
return True
|
|
31
|
+
except OSError:
|
|
32
|
+
return False
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def read_str() -> str:
|
|
36
|
+
"""MC_35: read line from stdin."""
|
|
37
|
+
try:
|
|
38
|
+
return input()
|
|
39
|
+
except EOFError:
|
|
40
|
+
return ""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def write_stdout(s: str) -> None:
|
|
44
|
+
"""MC_36: write to stdout."""
|
|
45
|
+
sys.stdout.write(s)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def write_stderr(s: str) -> None:
|
|
49
|
+
"""MC_37: write to stderr."""
|
|
50
|
+
sys.stderr.write(s)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def file_exists(path: str) -> bool:
|
|
54
|
+
"""MC_38: check if file exists."""
|
|
55
|
+
return os.path.exists(path)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def file_size(path: str) -> int:
|
|
59
|
+
"""MC_39: get file size in bytes. Returns -1 on error."""
|
|
60
|
+
try:
|
|
61
|
+
return os.path.getsize(path)
|
|
62
|
+
except OSError:
|
|
63
|
+
return -1
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""F1 — Logic monomers (MC_08–MC_15)."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def and8(a: int, b: int) -> int:
|
|
5
|
+
"""MC_08: bitwise AND."""
|
|
6
|
+
return a & b & 0xFF
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def or8(a: int, b: int) -> int:
|
|
10
|
+
"""MC_09: bitwise OR."""
|
|
11
|
+
return (a | b) & 0xFF
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def xor8(a: int, b: int) -> int:
|
|
15
|
+
"""MC_10: bitwise XOR."""
|
|
16
|
+
return (a ^ b) & 0xFF
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def not8(a: int) -> int:
|
|
20
|
+
"""MC_11: bitwise NOT."""
|
|
21
|
+
return (~a) & 0xFF
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def shl8(a: int, shift: int) -> int:
|
|
25
|
+
"""MC_12: left shift. shift >= 8 → 0."""
|
|
26
|
+
if shift >= 8:
|
|
27
|
+
return 0
|
|
28
|
+
return (a << shift) & 0xFF
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def shr8(a: int, shift: int) -> int:
|
|
32
|
+
"""MC_13: right shift. shift >= 8 → 0."""
|
|
33
|
+
if shift >= 8:
|
|
34
|
+
return 0
|
|
35
|
+
return (a >> shift) & 0xFF
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def bool_and(a: bool, b: bool) -> bool:
|
|
39
|
+
"""MC_14: logical AND."""
|
|
40
|
+
return a and b
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def bool_or(a: bool, b: bool) -> bool:
|
|
44
|
+
"""MC_15: logical OR."""
|
|
45
|
+
return a or b
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""F2 — Memory monomers (MC_16–MC_23)."""
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
_MAX_ALLOC = 65536
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def load(mem: dict, key: Any) -> Any | None:
|
|
8
|
+
"""MC_16: load from memory map."""
|
|
9
|
+
return mem.get(key)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def store(mem: dict, key: Any, value: Any) -> bool:
|
|
13
|
+
"""MC_17: store into memory map."""
|
|
14
|
+
mem[key] = value
|
|
15
|
+
return True
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def push(stack: list, value: Any) -> list:
|
|
19
|
+
"""MC_18: push onto stack."""
|
|
20
|
+
stack.append(value)
|
|
21
|
+
return stack
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def pop(stack: list) -> tuple[Any | None, list]:
|
|
25
|
+
"""MC_19: pop from stack → (value, stack)."""
|
|
26
|
+
if not stack:
|
|
27
|
+
return (None, stack)
|
|
28
|
+
val = stack.pop()
|
|
29
|
+
return (val, stack)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def peek(stack: list) -> Any | None:
|
|
33
|
+
"""MC_20: peek top of stack."""
|
|
34
|
+
return stack[-1] if stack else None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def alloc(size: int) -> list:
|
|
38
|
+
"""MC_21: allocate list of given size (capped at 65536)."""
|
|
39
|
+
return [None] * min(size, _MAX_ALLOC)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def free(mem: dict, key: Any) -> bool:
|
|
43
|
+
"""MC_22: free key from memory map."""
|
|
44
|
+
if key in mem:
|
|
45
|
+
del mem[key]
|
|
46
|
+
return True
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def len_mem(mem: dict | list) -> int:
|
|
51
|
+
"""MC_23: length of memory structure."""
|
|
52
|
+
return len(mem)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""F5 — String monomers (MC_40–MC_47)."""
|
|
2
|
+
|
|
3
|
+
_MAX_STR_LEN = 4096
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def concat(a: str, b: str) -> str:
|
|
7
|
+
"""MC_40: concatenate strings (capped at 4096 chars)."""
|
|
8
|
+
return (a + b)[:_MAX_STR_LEN]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def substr(s: str, start: int, end: int) -> str:
|
|
12
|
+
"""MC_41: substring [start, end)."""
|
|
13
|
+
return s[start:end]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def trim(s: str) -> str:
|
|
17
|
+
"""MC_42: trim whitespace."""
|
|
18
|
+
return s.strip()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def length(s: str) -> int:
|
|
22
|
+
"""MC_43: string length."""
|
|
23
|
+
return len(s)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def contains(s: str, sub: str) -> bool:
|
|
27
|
+
"""MC_44: check if s contains sub."""
|
|
28
|
+
return sub in s
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def starts_with(s: str, prefix: str) -> bool:
|
|
32
|
+
"""MC_45: check prefix."""
|
|
33
|
+
return s.startswith(prefix)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def ends_with(s: str, suffix: str) -> bool:
|
|
37
|
+
"""MC_46: check suffix."""
|
|
38
|
+
return s.endswith(suffix)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def char_at(s: str, idx: int) -> str | None:
|
|
42
|
+
"""MC_47: character at index. Returns None if out of bounds."""
|
|
43
|
+
if idx < 0 or idx >= len(s):
|
|
44
|
+
return None
|
|
45
|
+
return s[idx]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""F7 — System monomers (MC_56–MC_63)."""
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def time_unix() -> int:
|
|
8
|
+
"""MC_56: Unix timestamp in seconds."""
|
|
9
|
+
return int(time.time())
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def time_ms() -> int:
|
|
13
|
+
"""MC_57: Unix timestamp in milliseconds."""
|
|
14
|
+
return int(time.time() * 1000)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def env_get(key: str) -> str | None:
|
|
18
|
+
"""MC_58: get environment variable."""
|
|
19
|
+
return os.environ.get(key)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def env_set(key: str, value: str) -> None:
|
|
23
|
+
"""MC_59: set environment variable."""
|
|
24
|
+
os.environ[key] = value
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def pid() -> int:
|
|
28
|
+
"""MC_60: current process ID."""
|
|
29
|
+
return os.getpid()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def args() -> list[str]:
|
|
33
|
+
"""MC_61: command-line arguments."""
|
|
34
|
+
return sys.argv[:]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def exit_code(code: int) -> int:
|
|
38
|
+
"""MC_62: return exit code (does not exit)."""
|
|
39
|
+
return code
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def sleep_ms(ms: int) -> None:
|
|
43
|
+
"""MC_63: sleep for ms milliseconds (capped at 60,000ms)."""
|
|
44
|
+
time.sleep(min(ms, 60_000) / 1000.0)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from brik64.mc.arithmetic import add8, sub8, mul8, div8, mod8, abs64, neg64, clamp
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_add8_saturating():
|
|
5
|
+
assert add8(200, 100) == 255
|
|
6
|
+
assert add8(1, 2) == 3
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_sub8_saturating():
|
|
10
|
+
assert sub8(5, 10) == 0
|
|
11
|
+
assert sub8(10, 3) == 7
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_div8_zero():
|
|
15
|
+
assert div8(10, 0) == (0, 0)
|
|
16
|
+
assert div8(17, 5) == (3, 2)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_clamp():
|
|
20
|
+
assert clamp(10, 0, 5) == 5
|
|
21
|
+
assert clamp(-1, 0, 10) == 0
|
|
22
|
+
assert clamp(5, 0, 10) == 5
|