brik64 0.1.0b5__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-0.1.0b5/LICENSE +3 -0
- brik64-0.1.0b5/PKG-INFO +71 -0
- brik64-0.1.0b5/README.md +54 -0
- brik64-0.1.0b5/brik64/__init__.py +7 -0
- brik64-0.1.0b5/brik64/eva/__init__.py +59 -0
- brik64-0.1.0b5/brik64/mc/__init__.py +31 -0
- brik64-0.1.0b5/brik64/mc/arithmetic.py +41 -0
- brik64-0.1.0b5/brik64/mc/audio.py +35 -0
- brik64-0.1.0b5/brik64/mc/concurrency.py +37 -0
- brik64-0.1.0b5/brik64/mc/control.py +37 -0
- brik64-0.1.0b5/brik64/mc/crypto.py +39 -0
- brik64-0.1.0b5/brik64/mc/filesystem.py +35 -0
- brik64-0.1.0b5/brik64/mc/float64.py +37 -0
- brik64-0.1.0b5/brik64/mc/graphics.py +35 -0
- brik64-0.1.0b5/brik64/mc/interop.py +38 -0
- brik64-0.1.0b5/brik64/mc/io.py +35 -0
- brik64-0.1.0b5/brik64/mc/logic.py +35 -0
- brik64-0.1.0b5/brik64/mc/math_ops.py +35 -0
- brik64-0.1.0b5/brik64/mc/memory.py +35 -0
- brik64-0.1.0b5/brik64/mc/network.py +35 -0
- brik64-0.1.0b5/brik64/mc/string.py +35 -0
- brik64-0.1.0b5/brik64/mc/system.py +38 -0
- brik64-0.1.0b5/brik64.egg-info/PKG-INFO +71 -0
- brik64-0.1.0b5/brik64.egg-info/SOURCES.txt +28 -0
- brik64-0.1.0b5/brik64.egg-info/dependency_links.txt +1 -0
- brik64-0.1.0b5/brik64.egg-info/top_level.txt +1 -0
- brik64-0.1.0b5/pyproject.toml +20 -0
- brik64-0.1.0b5/setup.cfg +4 -0
- brik64-0.1.0b5/tests/test_arithmetic.py +41 -0
- brik64-0.1.0b5/tests/test_eva.py +30 -0
brik64-0.1.0b5/LICENSE
ADDED
brik64-0.1.0b5/PKG-INFO
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: brik64
|
|
3
|
+
Version: 0.1.0b5
|
|
4
|
+
Summary: BRIK64 Python SDK beta for monomer helpers and EVA composition patterns aligned with CLI 0.1.0-beta.5.
|
|
5
|
+
Author-email: BRIK64 INC <info@brik64.com>
|
|
6
|
+
License: Apache License, Version 2.0
|
|
7
|
+
Copyright 2026 BRIK-64 Inc.
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Project-URL: Homepage, https://brik64.com
|
|
11
|
+
Project-URL: Repository, https://github.com/brik64/brik64-lib-python
|
|
12
|
+
Keywords: brik64,digital-circuitality,monomers,pcd,sdk
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
# brik64
|
|
19
|
+
|
|
20
|
+
Python SDK beta for BRIK64 monomer helpers and EVA composition patterns.
|
|
21
|
+
|
|
22
|
+
Current SDK beta: `0.1.0b5`
|
|
23
|
+
Aligned CLI beta: `0.1.0-beta.5`
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install brik64==0.1.0b5
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The BRIK64 CLI is distributed separately in beta5:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
curl -fsSL https://brik64.com/cli/install.sh | bash
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from brik64.mc.arithmetic import add8, mul8
|
|
41
|
+
from brik64.eva import seq
|
|
42
|
+
|
|
43
|
+
double_then_triple = seq(lambda x: x + x, lambda x: x * 3)
|
|
44
|
+
print(double_then_triple(5)) # 30
|
|
45
|
+
print(add8(200, 100)) # 44 (wrapping)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Beta Boundary
|
|
49
|
+
|
|
50
|
+
This package is a beta SDK surface for Python projects. It is useful for
|
|
51
|
+
examples, local integration, and working with BRIK64-style monomer and EVA
|
|
52
|
+
concepts in application code.
|
|
53
|
+
|
|
54
|
+
It does not by itself establish formal certification, N5/L5+N5 status,
|
|
55
|
+
self-hosting, fixpoint, production approval, or CLI installation.
|
|
56
|
+
|
|
57
|
+
## Public References
|
|
58
|
+
|
|
59
|
+
- Website: https://brik64.com
|
|
60
|
+
- Docs: https://docs.brik64.com
|
|
61
|
+
- CLI release: https://github.com/brik64/brik64-cli/releases/tag/v0.1.0-beta.5
|
|
62
|
+
|
|
63
|
+
## Beta5 Release Boundary
|
|
64
|
+
|
|
65
|
+
This repository is aligned to the beta5 CLI contract, but marketplace
|
|
66
|
+
publication is blocked until the beta5 release surface gate authorizes SDK
|
|
67
|
+
publication.
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
See [LICENSE](LICENSE).
|
brik64-0.1.0b5/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# brik64
|
|
2
|
+
|
|
3
|
+
Python SDK beta for BRIK64 monomer helpers and EVA composition patterns.
|
|
4
|
+
|
|
5
|
+
Current SDK beta: `0.1.0b5`
|
|
6
|
+
Aligned CLI beta: `0.1.0-beta.5`
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pip install brik64==0.1.0b5
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The BRIK64 CLI is distributed separately in beta5:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
curl -fsSL https://brik64.com/cli/install.sh | bash
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from brik64.mc.arithmetic import add8, mul8
|
|
24
|
+
from brik64.eva import seq
|
|
25
|
+
|
|
26
|
+
double_then_triple = seq(lambda x: x + x, lambda x: x * 3)
|
|
27
|
+
print(double_then_triple(5)) # 30
|
|
28
|
+
print(add8(200, 100)) # 44 (wrapping)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Beta Boundary
|
|
32
|
+
|
|
33
|
+
This package is a beta SDK surface for Python projects. It is useful for
|
|
34
|
+
examples, local integration, and working with BRIK64-style monomer and EVA
|
|
35
|
+
concepts in application code.
|
|
36
|
+
|
|
37
|
+
It does not by itself establish formal certification, N5/L5+N5 status,
|
|
38
|
+
self-hosting, fixpoint, production approval, or CLI installation.
|
|
39
|
+
|
|
40
|
+
## Public References
|
|
41
|
+
|
|
42
|
+
- Website: https://brik64.com
|
|
43
|
+
- Docs: https://docs.brik64.com
|
|
44
|
+
- CLI release: https://github.com/brik64/brik64-cli/releases/tag/v0.1.0-beta.5
|
|
45
|
+
|
|
46
|
+
## Beta5 Release Boundary
|
|
47
|
+
|
|
48
|
+
This repository is aligned to the beta5 CLI contract, but marketplace
|
|
49
|
+
publication is blocked until the beta5 release surface gate authorizes SDK
|
|
50
|
+
publication.
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""EVA Algebra — composition operators for monomers."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable
|
|
4
|
+
|
|
5
|
+
F = Callable[..., Any]
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def seq(f: F, g: F) -> F:
|
|
9
|
+
"""Sequential composition: g(f(x))."""
|
|
10
|
+
def _seq(*args: Any, **kwargs: Any) -> Any:
|
|
11
|
+
return g(f(*args, **kwargs))
|
|
12
|
+
return _seq
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def par(f: F, g: F) -> Callable[[Any, Any], tuple[Any, Any]]:
|
|
16
|
+
"""Parallel composition: (f(a), g(b))."""
|
|
17
|
+
def _apply(fn: F, value: Any) -> Any:
|
|
18
|
+
if isinstance(value, (tuple, list)):
|
|
19
|
+
return fn(*value)
|
|
20
|
+
return fn(value)
|
|
21
|
+
|
|
22
|
+
def _par(a: Any, b: Any) -> tuple[Any, Any]:
|
|
23
|
+
return (_apply(f, a), _apply(g, b))
|
|
24
|
+
return _par
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def cond(predicate: Callable[[Any], bool], then_fn: F, else_fn: F) -> F:
|
|
28
|
+
"""Conditional composition: then_fn(x) if predicate(x) else else_fn(x)."""
|
|
29
|
+
def _cond(*args: Any, **kwargs: Any) -> Any:
|
|
30
|
+
if predicate(*args, **kwargs):
|
|
31
|
+
return then_fn(*args, **kwargs)
|
|
32
|
+
return else_fn(*args, **kwargs)
|
|
33
|
+
return _cond
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def pipeline(*args: Any) -> Any:
|
|
37
|
+
"""Chain functions sequentially.
|
|
38
|
+
|
|
39
|
+
Supports both `pipeline(f1, f2)(value)` and `pipeline(value, [f1, f2])`.
|
|
40
|
+
"""
|
|
41
|
+
if len(args) == 2 and isinstance(args[1], list):
|
|
42
|
+
result = args[0]
|
|
43
|
+
for fn in args[1]:
|
|
44
|
+
result = fn(result)
|
|
45
|
+
return result
|
|
46
|
+
|
|
47
|
+
fns = args
|
|
48
|
+
|
|
49
|
+
def _pipeline(*args: Any, **kwargs: Any) -> Any:
|
|
50
|
+
result = fns[0](*args, **kwargs)
|
|
51
|
+
for fn in fns[1:]:
|
|
52
|
+
result = fn(result)
|
|
53
|
+
return result
|
|
54
|
+
return _pipeline
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def compose(*fns: F) -> F:
|
|
58
|
+
"""Reverse pipeline: f1(f2(...fN(x)))."""
|
|
59
|
+
return pipeline(*reversed(fns))
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Monomer Catalog — all 8 core + 8 extended families."""
|
|
2
|
+
|
|
3
|
+
from brik64.mc import (
|
|
4
|
+
arithmetic,
|
|
5
|
+
logic,
|
|
6
|
+
memory,
|
|
7
|
+
control,
|
|
8
|
+
io,
|
|
9
|
+
string,
|
|
10
|
+
crypto,
|
|
11
|
+
system,
|
|
12
|
+
float64,
|
|
13
|
+
math_ops,
|
|
14
|
+
network,
|
|
15
|
+
graphics,
|
|
16
|
+
audio,
|
|
17
|
+
filesystem,
|
|
18
|
+
concurrency,
|
|
19
|
+
interop,
|
|
20
|
+
)
|
|
21
|
+
from brik64.mc.arithmetic import abs8, add8, clamp, dec, div8, inc, mod8, mul8, sub8
|
|
22
|
+
from brik64.mc.logic import and8, not8, or8, rol, ror, shl, shr, xor8
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"arithmetic", "logic", "memory", "control",
|
|
26
|
+
"io", "string", "crypto", "system",
|
|
27
|
+
"float64", "math_ops", "network", "graphics",
|
|
28
|
+
"audio", "filesystem", "concurrency", "interop",
|
|
29
|
+
"abs8", "add8", "clamp", "dec", "div8", "inc", "mod8", "mul8", "sub8",
|
|
30
|
+
"and8", "not8", "or8", "rol", "ror", "shl", "shr", "xor8",
|
|
31
|
+
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Arithmetic monomers — wrapping 8-bit unsigned."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def add8(a: int, b: int) -> int:
|
|
5
|
+
return (a + b) & 0xFF
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def sub8(a: int, b: int) -> int:
|
|
9
|
+
return (a - b) & 0xFF
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def mul8(a: int, b: int) -> int:
|
|
13
|
+
return (a * b) & 0xFF
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def div8(a: int, b: int) -> tuple[int, int]:
|
|
17
|
+
if b == 0:
|
|
18
|
+
raise ZeroDivisionError("div8: division by zero")
|
|
19
|
+
return (a // b, a % b)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def mod8(a: int, b: int) -> int:
|
|
23
|
+
if b == 0:
|
|
24
|
+
raise ZeroDivisionError("mod8: division by zero")
|
|
25
|
+
return (a % b) & 0xFF
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def inc(a: int) -> int:
|
|
29
|
+
return (a + 1) & 0xFF
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def dec(a: int) -> int:
|
|
33
|
+
return (a - 1) & 0xFF
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def abs8(a: int) -> int:
|
|
37
|
+
return a & 0xFF
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def clamp(value: int, minimum: int, maximum: int) -> int:
|
|
41
|
+
return max(minimum, min(maximum, value))
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Audio monomers — stubs."""
|
|
2
|
+
|
|
3
|
+
_STUB = "Extended monomer stub"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def aud_create(sample_rate: int, channels: int) -> int:
|
|
7
|
+
raise NotImplementedError(_STUB)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def aud_play(buf: int) -> None:
|
|
11
|
+
raise NotImplementedError(_STUB)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def aud_stop(buf: int) -> None:
|
|
15
|
+
raise NotImplementedError(_STUB)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def aud_write(buf: int, data: bytes) -> int:
|
|
19
|
+
raise NotImplementedError(_STUB)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def aud_read(buf: int, size: int) -> bytes:
|
|
23
|
+
raise NotImplementedError(_STUB)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def aud_volume(buf: int, level: float) -> None:
|
|
27
|
+
raise NotImplementedError(_STUB)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def aud_rate(buf: int) -> int:
|
|
31
|
+
raise NotImplementedError(_STUB)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def aud_chans(buf: int) -> int:
|
|
35
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Concurrency monomers — stubs."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
_STUB = "Extended monomer stub"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def spawn(fn: Any) -> int:
|
|
9
|
+
raise NotImplementedError(_STUB)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def join(tid: int) -> Any:
|
|
13
|
+
raise NotImplementedError(_STUB)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def chan_new() -> int:
|
|
17
|
+
raise NotImplementedError(_STUB)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def chan_send(ch: int, val: Any) -> None:
|
|
21
|
+
raise NotImplementedError(_STUB)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def chan_recv(ch: int) -> Any:
|
|
25
|
+
raise NotImplementedError(_STUB)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def mutex_new() -> int:
|
|
29
|
+
raise NotImplementedError(_STUB)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def mutex_lock(m: int) -> None:
|
|
33
|
+
raise NotImplementedError(_STUB)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def mutex_unlock(m: int) -> None:
|
|
37
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Control monomers — stubs."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable
|
|
4
|
+
|
|
5
|
+
_STUB = "Extended monomer stub"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def if_then(cond: bool, then_fn: Callable[[], Any]) -> Any | None:
|
|
9
|
+
raise NotImplementedError(_STUB)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def loop_n(n: int, body: Callable[[int], Any]) -> None:
|
|
13
|
+
raise NotImplementedError(_STUB)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def call(fn: Callable[..., Any], *args: Any) -> Any:
|
|
17
|
+
raise NotImplementedError(_STUB)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def ret(val: Any) -> Any:
|
|
21
|
+
raise NotImplementedError(_STUB)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def break_op() -> None:
|
|
25
|
+
raise NotImplementedError(_STUB)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def continue_op() -> None:
|
|
29
|
+
raise NotImplementedError(_STUB)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def nop() -> None:
|
|
33
|
+
raise NotImplementedError(_STUB)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def exit_op(code: int = 0) -> None:
|
|
37
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Crypto monomers — hash_sha256 real, rest stubs."""
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
|
|
5
|
+
_STUB = "Extended monomer stub"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def hash_sha256(data: bytes | str) -> str:
|
|
9
|
+
if isinstance(data, str):
|
|
10
|
+
data = data.encode("utf-8")
|
|
11
|
+
return hashlib.sha256(data).hexdigest()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def encrypt(data: bytes, key: bytes) -> bytes:
|
|
15
|
+
raise NotImplementedError(_STUB)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def decrypt(data: bytes, key: bytes) -> bytes:
|
|
19
|
+
raise NotImplementedError(_STUB)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def sign(data: bytes, key: bytes) -> bytes:
|
|
23
|
+
raise NotImplementedError(_STUB)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def verify(data: bytes, signature: bytes, key: bytes) -> bool:
|
|
27
|
+
raise NotImplementedError(_STUB)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def rng(n: int) -> bytes:
|
|
31
|
+
raise NotImplementedError(_STUB)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def derive(key: bytes, salt: bytes) -> bytes:
|
|
35
|
+
raise NotImplementedError(_STUB)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def seal(data: bytes, key: bytes) -> bytes:
|
|
39
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Filesystem monomers — stubs."""
|
|
2
|
+
|
|
3
|
+
_STUB = "Extended monomer stub"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def fs_stat(path: str) -> dict[str, int]:
|
|
7
|
+
raise NotImplementedError(_STUB)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def fs_mkdir(path: str) -> None:
|
|
11
|
+
raise NotImplementedError(_STUB)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def fs_rmdir(path: str) -> None:
|
|
15
|
+
raise NotImplementedError(_STUB)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def fs_list(path: str) -> list[str]:
|
|
19
|
+
raise NotImplementedError(_STUB)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def fs_rename(src: str, dst: str) -> None:
|
|
23
|
+
raise NotImplementedError(_STUB)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def fs_remove(path: str) -> None:
|
|
27
|
+
raise NotImplementedError(_STUB)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def fs_exists(path: str) -> bool:
|
|
31
|
+
raise NotImplementedError(_STUB)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def fs_copy(src: str, dst: str) -> None:
|
|
35
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Float64 monomers — real f64 math."""
|
|
2
|
+
|
|
3
|
+
import math
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def fadd(a: float, b: float) -> float:
|
|
7
|
+
return a + b
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def fsub(a: float, b: float) -> float:
|
|
11
|
+
return a - b
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def fmul(a: float, b: float) -> float:
|
|
15
|
+
return a * b
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def fdiv(a: float, b: float) -> float:
|
|
19
|
+
if b == 0.0:
|
|
20
|
+
raise ZeroDivisionError("fdiv: division by zero")
|
|
21
|
+
return a / b
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def fabs(a: float) -> float:
|
|
25
|
+
return abs(a)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def fneg(a: float) -> float:
|
|
29
|
+
return -a
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def fsqrt(a: float) -> float:
|
|
33
|
+
return math.sqrt(a)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def fmod_op(a: float, b: float) -> float:
|
|
37
|
+
return math.fmod(a, b)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Graphics monomers — stubs."""
|
|
2
|
+
|
|
3
|
+
_STUB = "Extended monomer stub"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def fb_create(width: int, height: int) -> int:
|
|
7
|
+
raise NotImplementedError(_STUB)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def fb_pixel(fb: int, x: int, y: int, color: int) -> None:
|
|
11
|
+
raise NotImplementedError(_STUB)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def fb_line(fb: int, x0: int, y0: int, x1: int, y1: int, color: int) -> None:
|
|
15
|
+
raise NotImplementedError(_STUB)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def fb_rect(fb: int, x: int, y: int, w: int, h: int, color: int) -> None:
|
|
19
|
+
raise NotImplementedError(_STUB)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def fb_clear(fb: int, color: int) -> None:
|
|
23
|
+
raise NotImplementedError(_STUB)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def fb_blit(fb: int) -> None:
|
|
27
|
+
raise NotImplementedError(_STUB)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def fb_read(fb: int, x: int, y: int) -> int:
|
|
31
|
+
raise NotImplementedError(_STUB)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def fb_dims(fb: int) -> tuple[int, int]:
|
|
35
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Interop monomers — json real, rest stubs."""
|
|
2
|
+
|
|
3
|
+
import json as _json
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
_STUB = "Extended monomer stub"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def json_encode(obj: Any) -> str:
|
|
10
|
+
return _json.dumps(obj)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def json_decode(s: str) -> Any:
|
|
14
|
+
return _json.loads(s)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def ffi_call(lib: str, fn: str, *args: Any) -> Any:
|
|
18
|
+
raise NotImplementedError(_STUB)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def ffi_load(lib: str) -> int:
|
|
22
|
+
raise NotImplementedError(_STUB)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def ffi_free(handle: int) -> None:
|
|
26
|
+
raise NotImplementedError(_STUB)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def wasm_load(path: str) -> int:
|
|
30
|
+
raise NotImplementedError(_STUB)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def wasm_call(module: int, fn: str, *args: Any) -> Any:
|
|
34
|
+
raise NotImplementedError(_STUB)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def wasm_free(module: int) -> None:
|
|
38
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""I/O monomers — stubs."""
|
|
2
|
+
|
|
3
|
+
_STUB = "Extended monomer stub"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def read(fd: int, size: int) -> bytes:
|
|
7
|
+
raise NotImplementedError(_STUB)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def write(fd: int, data: bytes) -> int:
|
|
11
|
+
raise NotImplementedError(_STUB)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def open_file(path: str, mode: str = "r") -> int:
|
|
15
|
+
raise NotImplementedError(_STUB)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def close_file(fd: int) -> None:
|
|
19
|
+
raise NotImplementedError(_STUB)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def seek(fd: int, offset: int) -> None:
|
|
23
|
+
raise NotImplementedError(_STUB)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def flush(fd: int) -> None:
|
|
27
|
+
raise NotImplementedError(_STUB)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def eof(fd: int) -> bool:
|
|
31
|
+
raise NotImplementedError(_STUB)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def err(fd: int) -> bool:
|
|
35
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Logic monomers — 8-bit bitwise operations."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def and8(a: int, b: int) -> int:
|
|
5
|
+
return (a & b) & 0xFF
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def or8(a: int, b: int) -> int:
|
|
9
|
+
return (a | b) & 0xFF
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def xor8(a: int, b: int) -> int:
|
|
13
|
+
return (a ^ b) & 0xFF
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def not8(a: int) -> int:
|
|
17
|
+
return (~a) & 0xFF
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def shl(a: int, n: int) -> int:
|
|
21
|
+
return (a << n) & 0xFF
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def shr(a: int, n: int) -> int:
|
|
25
|
+
return (a >> n) & 0xFF
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def rol(a: int, n: int) -> int:
|
|
29
|
+
n = n % 8
|
|
30
|
+
return ((a << n) | (a >> (8 - n))) & 0xFF
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def ror(a: int, n: int) -> int:
|
|
34
|
+
n = n % 8
|
|
35
|
+
return ((a >> n) | (a << (8 - n))) & 0xFF
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Math monomers — real math.* wrappers."""
|
|
2
|
+
|
|
3
|
+
import math
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def sin(x: float) -> float:
|
|
7
|
+
return math.sin(x)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def cos(x: float) -> float:
|
|
11
|
+
return math.cos(x)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def tan(x: float) -> float:
|
|
15
|
+
return math.tan(x)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def exp(x: float) -> float:
|
|
19
|
+
return math.exp(x)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def ln(x: float) -> float:
|
|
23
|
+
return math.log(x)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def log2(x: float) -> float:
|
|
27
|
+
return math.log2(x)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def pow_op(base: float, exponent: float) -> float:
|
|
31
|
+
return math.pow(base, exponent)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def ceil(x: float) -> int:
|
|
35
|
+
return math.ceil(x)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Memory monomers — stubs."""
|
|
2
|
+
|
|
3
|
+
_STUB = "Extended monomer stub"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def load(addr: int) -> int:
|
|
7
|
+
raise NotImplementedError(_STUB)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def store(addr: int, val: int) -> None:
|
|
11
|
+
raise NotImplementedError(_STUB)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def push(val: int) -> None:
|
|
15
|
+
raise NotImplementedError(_STUB)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def pop() -> int:
|
|
19
|
+
raise NotImplementedError(_STUB)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def peek() -> int:
|
|
23
|
+
raise NotImplementedError(_STUB)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def dup() -> None:
|
|
27
|
+
raise NotImplementedError(_STUB)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def drop() -> None:
|
|
31
|
+
raise NotImplementedError(_STUB)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def swap() -> None:
|
|
35
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Network monomers — stubs."""
|
|
2
|
+
|
|
3
|
+
_STUB = "Extended monomer stub"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def tcp_conn(host: str, port: int) -> int:
|
|
7
|
+
raise NotImplementedError(_STUB)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def tcp_send(fd: int, data: bytes) -> int:
|
|
11
|
+
raise NotImplementedError(_STUB)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def tcp_recv(fd: int, size: int) -> bytes:
|
|
15
|
+
raise NotImplementedError(_STUB)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def tcp_close(fd: int) -> None:
|
|
19
|
+
raise NotImplementedError(_STUB)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def udp_send(host: str, port: int, data: bytes) -> int:
|
|
23
|
+
raise NotImplementedError(_STUB)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def udp_recv(fd: int, size: int) -> bytes:
|
|
27
|
+
raise NotImplementedError(_STUB)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def dns_resolve(hostname: str) -> str:
|
|
31
|
+
raise NotImplementedError(_STUB)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def http_req(url: str, method: str = "GET") -> str:
|
|
35
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""String monomers — real implementations."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def concat(a: str, b: str) -> str:
|
|
7
|
+
return a + b
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def split(s: str, sep: str) -> list[str]:
|
|
11
|
+
return s.split(sep)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def substr(s: str, start: int, length: int) -> str:
|
|
15
|
+
return s[start:start + length]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def len_str(s: str) -> int:
|
|
19
|
+
return len(s)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def upper(s: str) -> str:
|
|
23
|
+
return s.upper()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def lower(s: str) -> str:
|
|
27
|
+
return s.lower()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def trim(s: str) -> str:
|
|
31
|
+
return s.strip()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def match_str(s: str, pattern: str) -> bool:
|
|
35
|
+
return bool(re.search(pattern, s))
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""System monomers — time_unix, pid, env_get real, rest stubs."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
_STUB = "Extended monomer stub"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def time_unix() -> int:
|
|
10
|
+
return int(time.time())
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def cpu() -> float:
|
|
14
|
+
raise NotImplementedError(_STUB)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def disk() -> dict[str, int]:
|
|
18
|
+
raise NotImplementedError(_STUB)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def net() -> dict[str, int]:
|
|
22
|
+
raise NotImplementedError(_STUB)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def env_get(key: str, default: str | None = None) -> str | None:
|
|
26
|
+
return os.environ.get(key, default)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def pid() -> int:
|
|
30
|
+
return os.getpid()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def thread() -> int:
|
|
34
|
+
raise NotImplementedError(_STUB)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def exec_cmd(cmd: str) -> str:
|
|
38
|
+
raise NotImplementedError(_STUB)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: brik64
|
|
3
|
+
Version: 0.1.0b5
|
|
4
|
+
Summary: BRIK64 Python SDK beta for monomer helpers and EVA composition patterns aligned with CLI 0.1.0-beta.5.
|
|
5
|
+
Author-email: BRIK64 INC <info@brik64.com>
|
|
6
|
+
License: Apache License, Version 2.0
|
|
7
|
+
Copyright 2026 BRIK-64 Inc.
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Project-URL: Homepage, https://brik64.com
|
|
11
|
+
Project-URL: Repository, https://github.com/brik64/brik64-lib-python
|
|
12
|
+
Keywords: brik64,digital-circuitality,monomers,pcd,sdk
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
# brik64
|
|
19
|
+
|
|
20
|
+
Python SDK beta for BRIK64 monomer helpers and EVA composition patterns.
|
|
21
|
+
|
|
22
|
+
Current SDK beta: `0.1.0b5`
|
|
23
|
+
Aligned CLI beta: `0.1.0-beta.5`
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install brik64==0.1.0b5
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The BRIK64 CLI is distributed separately in beta5:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
curl -fsSL https://brik64.com/cli/install.sh | bash
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from brik64.mc.arithmetic import add8, mul8
|
|
41
|
+
from brik64.eva import seq
|
|
42
|
+
|
|
43
|
+
double_then_triple = seq(lambda x: x + x, lambda x: x * 3)
|
|
44
|
+
print(double_then_triple(5)) # 30
|
|
45
|
+
print(add8(200, 100)) # 44 (wrapping)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Beta Boundary
|
|
49
|
+
|
|
50
|
+
This package is a beta SDK surface for Python projects. It is useful for
|
|
51
|
+
examples, local integration, and working with BRIK64-style monomer and EVA
|
|
52
|
+
concepts in application code.
|
|
53
|
+
|
|
54
|
+
It does not by itself establish formal certification, N5/L5+N5 status,
|
|
55
|
+
self-hosting, fixpoint, production approval, or CLI installation.
|
|
56
|
+
|
|
57
|
+
## Public References
|
|
58
|
+
|
|
59
|
+
- Website: https://brik64.com
|
|
60
|
+
- Docs: https://docs.brik64.com
|
|
61
|
+
- CLI release: https://github.com/brik64/brik64-cli/releases/tag/v0.1.0-beta.5
|
|
62
|
+
|
|
63
|
+
## Beta5 Release Boundary
|
|
64
|
+
|
|
65
|
+
This repository is aligned to the beta5 CLI contract, but marketplace
|
|
66
|
+
publication is blocked until the beta5 release surface gate authorizes SDK
|
|
67
|
+
publication.
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
brik64/__init__.py
|
|
5
|
+
brik64.egg-info/PKG-INFO
|
|
6
|
+
brik64.egg-info/SOURCES.txt
|
|
7
|
+
brik64.egg-info/dependency_links.txt
|
|
8
|
+
brik64.egg-info/top_level.txt
|
|
9
|
+
brik64/eva/__init__.py
|
|
10
|
+
brik64/mc/__init__.py
|
|
11
|
+
brik64/mc/arithmetic.py
|
|
12
|
+
brik64/mc/audio.py
|
|
13
|
+
brik64/mc/concurrency.py
|
|
14
|
+
brik64/mc/control.py
|
|
15
|
+
brik64/mc/crypto.py
|
|
16
|
+
brik64/mc/filesystem.py
|
|
17
|
+
brik64/mc/float64.py
|
|
18
|
+
brik64/mc/graphics.py
|
|
19
|
+
brik64/mc/interop.py
|
|
20
|
+
brik64/mc/io.py
|
|
21
|
+
brik64/mc/logic.py
|
|
22
|
+
brik64/mc/math_ops.py
|
|
23
|
+
brik64/mc/memory.py
|
|
24
|
+
brik64/mc/network.py
|
|
25
|
+
brik64/mc/string.py
|
|
26
|
+
brik64/mc/system.py
|
|
27
|
+
tests/test_arithmetic.py
|
|
28
|
+
tests/test_eva.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
brik64
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "brik64"
|
|
7
|
+
version = "0.1.0b5"
|
|
8
|
+
description = "BRIK64 Python SDK beta for monomer helpers and EVA composition patterns aligned with CLI 0.1.0-beta.5."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {file = "LICENSE"}
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{ name = "BRIK64 INC", email = "info@brik64.com" }]
|
|
13
|
+
keywords = ["brik64", "digital-circuitality", "monomers", "pcd", "sdk"]
|
|
14
|
+
|
|
15
|
+
[tool.setuptools.packages.find]
|
|
16
|
+
include = ["brik64*"]
|
|
17
|
+
|
|
18
|
+
[project.urls]
|
|
19
|
+
Homepage = "https://brik64.com"
|
|
20
|
+
Repository = "https://github.com/brik64/brik64-lib-python"
|
brik64-0.1.0b5/setup.cfg
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from brik64 import mc
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_add8_wraps():
|
|
5
|
+
assert mc.add8(200, 100) == 44
|
|
6
|
+
assert mc.add8(10, 20) == 30
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_sub8_wraps():
|
|
10
|
+
assert mc.sub8(5, 10) == 251
|
|
11
|
+
assert mc.sub8(20, 5) == 15
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_div8_returns_quotient_remainder():
|
|
15
|
+
assert mc.div8(17, 5) == (3, 2)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_div8_fails_closed_on_zero():
|
|
19
|
+
try:
|
|
20
|
+
mc.div8(10, 0)
|
|
21
|
+
except ZeroDivisionError:
|
|
22
|
+
return
|
|
23
|
+
raise AssertionError("div8 must fail closed on division by zero")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_clamp():
|
|
27
|
+
assert mc.clamp(300, 0, 255) == 255
|
|
28
|
+
assert mc.clamp(-5, 0, 100) == 0
|
|
29
|
+
assert mc.clamp(50, 0, 100) == 50
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_mod8_returns_remainder():
|
|
33
|
+
assert mc.mod8(17, 5) == 2
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_mod8_fails_closed_on_zero():
|
|
37
|
+
try:
|
|
38
|
+
mc.mod8(10, 0)
|
|
39
|
+
except ZeroDivisionError:
|
|
40
|
+
return
|
|
41
|
+
raise AssertionError("mod8 must fail closed on division by zero")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from brik64 import mc, eva
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_seq_pipeline():
|
|
5
|
+
p = eva.seq(
|
|
6
|
+
lambda pair: mc.add8(pair[0], pair[1]),
|
|
7
|
+
lambda s: mc.mod8(s, 10),
|
|
8
|
+
)
|
|
9
|
+
assert p((7, 8)) == 5 # add8(7,8)=15 -> mod8(15,10)=5
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_par_composition():
|
|
13
|
+
dual = eva.par(mc.add8, mc.xor8)
|
|
14
|
+
result = dual((10, 5), (0b1100, 0b1010))
|
|
15
|
+
assert result == (15, 0b0110)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_cond_branching():
|
|
19
|
+
transform = eva.cond(
|
|
20
|
+
lambda x: x % 2 == 0,
|
|
21
|
+
lambda x: x * 2,
|
|
22
|
+
lambda x: x // 2,
|
|
23
|
+
)
|
|
24
|
+
assert transform(4) == 8
|
|
25
|
+
assert transform(5) == 2
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_pipeline_chain():
|
|
29
|
+
result = eva.pipeline(5, [lambda x: x + 1, lambda x: x * 2, lambda x: x - 3])
|
|
30
|
+
assert result == 9
|