astreum 0.2.32__py3-none-any.whl → 0.2.33__py3-none-any.whl
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.
Potentially problematic release.
This version of astreum might be problematic. Click here for more details.
- astreum/_node.py +84 -15
- {astreum-0.2.32.dist-info → astreum-0.2.33.dist-info}/METADATA +1 -1
- {astreum-0.2.32.dist-info → astreum-0.2.33.dist-info}/RECORD +6 -6
- {astreum-0.2.32.dist-info → astreum-0.2.33.dist-info}/WHEEL +0 -0
- {astreum-0.2.32.dist-info → astreum-0.2.33.dist-info}/licenses/LICENSE +0 -0
- {astreum-0.2.32.dist-info → astreum-0.2.33.dist-info}/top_level.txt +0 -0
astreum/_node.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from typing import Dict, List, Optional, Union
|
|
2
|
+
from typing import Dict, List, Optional, Tuple, Union
|
|
3
3
|
import uuid
|
|
4
4
|
import threading
|
|
5
5
|
|
|
@@ -74,14 +74,14 @@ class Expr:
|
|
|
74
74
|
return self.value
|
|
75
75
|
|
|
76
76
|
class Error:
|
|
77
|
-
def __init__(self,
|
|
78
|
-
self.
|
|
77
|
+
def __init__(self, topic: str, origin: Optional['Expr'] = None):
|
|
78
|
+
self.topic = topic
|
|
79
79
|
self.origin = origin
|
|
80
80
|
|
|
81
81
|
def __repr__(self):
|
|
82
82
|
if self.origin is None:
|
|
83
|
-
return f'(
|
|
84
|
-
return f'(
|
|
83
|
+
return f'({self.topic} err)'
|
|
84
|
+
return f'({self.origin} {self.topic} err)'
|
|
85
85
|
|
|
86
86
|
class Env:
|
|
87
87
|
def __init__(
|
|
@@ -347,8 +347,8 @@ class Node:
|
|
|
347
347
|
code.append(bytes([tok.value & 0xFF]))
|
|
348
348
|
return None
|
|
349
349
|
|
|
350
|
-
if isinstance(tok, Expr.ListExpr):
|
|
351
|
-
rv = self.high_eval(env_id, tok, meter=meter)
|
|
350
|
+
if isinstance(tok, Expr.ListExpr):
|
|
351
|
+
rv = self.high_eval(env_id, tok, meter=meter)
|
|
352
352
|
if isinstance(rv, Expr.Error):
|
|
353
353
|
return rv
|
|
354
354
|
rb = to_bytes(rv)
|
|
@@ -367,8 +367,8 @@ class Node:
|
|
|
367
367
|
if isinstance(err, Expr.Error):
|
|
368
368
|
return err
|
|
369
369
|
|
|
370
|
-
# Execute low-level code built from sk-body using the caller's meter
|
|
371
|
-
res = self.low_eval(code, meter=meter)
|
|
370
|
+
# Execute low-level code built from sk-body using the caller's meter
|
|
371
|
+
res = self.low_eval(code, meter=meter)
|
|
372
372
|
if isinstance(res, Expr.Error):
|
|
373
373
|
return res
|
|
374
374
|
return Expr.ListExpr([Expr.Byte(b) for b in res])
|
|
@@ -401,8 +401,8 @@ class Node:
|
|
|
401
401
|
return Expr.Error("arity mismatch", origin=expr)
|
|
402
402
|
|
|
403
403
|
arg_bytes: List[bytes] = []
|
|
404
|
-
for a in args_exprs:
|
|
405
|
-
v = self.high_eval(env_id, a, meter=meter)
|
|
404
|
+
for a in args_exprs:
|
|
405
|
+
v = self.high_eval(env_id, a, meter=meter)
|
|
406
406
|
if isinstance(v, Expr.Error):
|
|
407
407
|
return v
|
|
408
408
|
if not isinstance(v, Expr.Byte):
|
|
@@ -415,9 +415,78 @@ class Node:
|
|
|
415
415
|
for name_b, val_b in zip(params, arg_bytes):
|
|
416
416
|
self.env_set(child_env, name_b, Expr.Byte(val_b[0]))
|
|
417
417
|
|
|
418
|
-
# evaluate HL body, metered from the top
|
|
419
|
-
return self.high_eval(child_env, body_expr, meter=meter)
|
|
418
|
+
# evaluate HL body, metered from the top
|
|
419
|
+
return self.high_eval(child_env, body_expr, meter=meter)
|
|
420
420
|
|
|
421
421
|
# ---------- default: resolve each element and return list ----------
|
|
422
|
-
resolved: List[Expr] = [self.high_eval(env_id, e, meter=meter) for e in expr.elements]
|
|
423
|
-
return Expr.ListExpr(resolved)
|
|
422
|
+
resolved: List[Expr] = [self.high_eval(env_id, e, meter=meter) for e in expr.elements]
|
|
423
|
+
return Expr.ListExpr(resolved)
|
|
424
|
+
|
|
425
|
+
# ===============================
|
|
426
|
+
# 3. Lightweight Parser for Expr (postfix, limited forms)
|
|
427
|
+
# ===============================
|
|
428
|
+
|
|
429
|
+
class ParseError(Exception):
|
|
430
|
+
pass
|
|
431
|
+
|
|
432
|
+
def tokenize(source: str) -> List[str]:
|
|
433
|
+
"""Tokenize a minimal Lispeum subset for this module.
|
|
434
|
+
|
|
435
|
+
Supports:
|
|
436
|
+
- Integers (e.g., -1, 0, 255) → Byte
|
|
437
|
+
- Symbols (e.g., add, nand, def, fn, sk, int.sub, $0)
|
|
438
|
+
- Lists using parentheses
|
|
439
|
+
"""
|
|
440
|
+
tokens: List[str] = []
|
|
441
|
+
cur: List[str] = []
|
|
442
|
+
for ch in source:
|
|
443
|
+
if ch.isspace():
|
|
444
|
+
if cur:
|
|
445
|
+
tokens.append("".join(cur))
|
|
446
|
+
cur = []
|
|
447
|
+
continue
|
|
448
|
+
if ch in ("(", ")"):
|
|
449
|
+
if cur:
|
|
450
|
+
tokens.append("".join(cur))
|
|
451
|
+
cur = []
|
|
452
|
+
tokens.append(ch)
|
|
453
|
+
continue
|
|
454
|
+
cur.append(ch)
|
|
455
|
+
if cur:
|
|
456
|
+
tokens.append("".join(cur))
|
|
457
|
+
return tokens
|
|
458
|
+
|
|
459
|
+
def _parse_one(tokens: List[str], pos: int = 0) -> Tuple[Expr, int]:
|
|
460
|
+
if pos >= len(tokens):
|
|
461
|
+
raise ParseError("unexpected end")
|
|
462
|
+
tok = tokens[pos]
|
|
463
|
+
|
|
464
|
+
if tok == '(': # list
|
|
465
|
+
items: List[Expr] = []
|
|
466
|
+
i = pos + 1
|
|
467
|
+
while i < len(tokens):
|
|
468
|
+
if tokens[i] == ')':
|
|
469
|
+
# special-case error form at close: (origin topic err) or (topic err)
|
|
470
|
+
if len(items) >= 3 and isinstance(items[-1], Expr.Symbol) and items[-1].value == 'err' and isinstance(items[-2], Expr.Symbol):
|
|
471
|
+
return Expr.Error(items[-2].value, origin=items[-3]), i + 1
|
|
472
|
+
if len(items) == 2 and isinstance(items[-1], Expr.Symbol) and items[-1].value == 'err' and isinstance(items[-2], Expr.Symbol):
|
|
473
|
+
return Expr.Error(items[-2].value), i + 1
|
|
474
|
+
return Expr.ListExpr(items), i + 1
|
|
475
|
+
expr, i = _parse_one(tokens, i)
|
|
476
|
+
items.append(expr)
|
|
477
|
+
raise ParseError("expected ')'")
|
|
478
|
+
|
|
479
|
+
if tok == ')':
|
|
480
|
+
raise ParseError("unexpected ')'")
|
|
481
|
+
|
|
482
|
+
# try integer → Byte
|
|
483
|
+
try:
|
|
484
|
+
n = int(tok)
|
|
485
|
+
return Expr.Byte(n), pos + 1
|
|
486
|
+
except ValueError:
|
|
487
|
+
return Expr.Symbol(tok), pos + 1
|
|
488
|
+
|
|
489
|
+
def parse(tokens: List[str]) -> Tuple[Expr, List[str]]:
|
|
490
|
+
"""Parse tokens into an Expr and return (expr, remaining_tokens)."""
|
|
491
|
+
expr, next_pos = _parse_one(tokens, 0)
|
|
492
|
+
return expr, tokens[next_pos:]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: astreum
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.33
|
|
4
4
|
Summary: Python library to interact with the Astreum blockchain and its Lispeum virtual machine.
|
|
5
5
|
Author-email: "Roy R. O. Okello" <roy@stelar.xyz>
|
|
6
6
|
Project-URL: Homepage, https://github.com/astreum/lib
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
astreum/__init__.py,sha256=y2Ok3EY_FstcmlVASr80lGR_0w-dH-SXDCCQFmL6uwA,28
|
|
2
|
-
astreum/_node.py,sha256=
|
|
2
|
+
astreum/_node.py,sha256=cJSzj7N4unkOH5T_nDa7bKy_jBD-p0oJTDlAXjuFFYw,18773
|
|
3
3
|
astreum/format.py,sha256=X4tG5GGPweNCE54bHYkLFiuLTbmpy5upO_s1Cef-MGA,2711
|
|
4
4
|
astreum/node.py,sha256=SuVm1b0QWl1FpDUaLRH1fiFYnXCrPs6qYeUQlPDae8w,38358
|
|
5
5
|
astreum/crypto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -27,8 +27,8 @@ astreum/relay/setup.py,sha256=ynvGaJdlDtw_f5LLiow2Wo7IRzUjvgk8eSr1Sv4_zTg,2090
|
|
|
27
27
|
astreum/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
astreum/storage/object.py,sha256=knFlvw_tpcC4twSu1DGNpHX31wlANN8E5dgEqIfU--Q,2041
|
|
29
29
|
astreum/storage/setup.py,sha256=1-9ztEFI_BvRDvAA0lAn4mFya8iq65THTArlj--M3Hg,626
|
|
30
|
-
astreum-0.2.
|
|
31
|
-
astreum-0.2.
|
|
32
|
-
astreum-0.2.
|
|
33
|
-
astreum-0.2.
|
|
34
|
-
astreum-0.2.
|
|
30
|
+
astreum-0.2.33.dist-info/licenses/LICENSE,sha256=gYBvRDP-cPLmTyJhvZ346QkrYW_eleke4Z2Yyyu43eQ,1089
|
|
31
|
+
astreum-0.2.33.dist-info/METADATA,sha256=t-sfdHamxd73CFIfgiXrl5zph6CnZRtlwCRCqVrQGVA,6149
|
|
32
|
+
astreum-0.2.33.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
33
|
+
astreum-0.2.33.dist-info/top_level.txt,sha256=1EG1GmkOk3NPmUA98FZNdKouhRyget-KiFiMk0i2Uz0,8
|
|
34
|
+
astreum-0.2.33.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|