tengwar 0.3.2__py3-none-any.whl → 0.3.3__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.
- tengwar/__init__.py +1 -1
- tengwar/interpreter.py +29 -5
- {tengwar-0.3.2.dist-info → tengwar-0.3.3.dist-info}/METADATA +1 -1
- {tengwar-0.3.2.dist-info → tengwar-0.3.3.dist-info}/RECORD +8 -8
- {tengwar-0.3.2.dist-info → tengwar-0.3.3.dist-info}/WHEEL +0 -0
- {tengwar-0.3.2.dist-info → tengwar-0.3.3.dist-info}/entry_points.txt +0 -0
- {tengwar-0.3.2.dist-info → tengwar-0.3.3.dist-info}/licenses/LICENSE +0 -0
- {tengwar-0.3.2.dist-info → tengwar-0.3.3.dist-info}/top_level.txt +0 -0
tengwar/__init__.py
CHANGED
tengwar/interpreter.py
CHANGED
|
@@ -74,6 +74,21 @@ class TengwarVector(TengwarValue):
|
|
|
74
74
|
def __eq__(self, other): return isinstance(other, TengwarVector) and self.elements == other.elements
|
|
75
75
|
|
|
76
76
|
|
|
77
|
+
class TengwarLazy(TengwarValue):
|
|
78
|
+
"""Lazy sequence — generated on demand by take/head/etc."""
|
|
79
|
+
def __init__(self, gen_fn, init_val):
|
|
80
|
+
self.gen_fn = gen_fn # function: val -> next_val
|
|
81
|
+
self.init_val = init_val
|
|
82
|
+
def take(self, n, call_fn):
|
|
83
|
+
result = [self.init_val]
|
|
84
|
+
val = self.init_val
|
|
85
|
+
for _ in range(n - 1):
|
|
86
|
+
val = call_fn(self.gen_fn, [val])
|
|
87
|
+
result.append(val)
|
|
88
|
+
return result
|
|
89
|
+
def __repr__(self): return f'<lazy-seq from {repr(self.init_val)}>'
|
|
90
|
+
|
|
91
|
+
|
|
77
92
|
class TengwarClosure(TengwarValue):
|
|
78
93
|
def __init__(self, params: list, body, env: 'Environment', name: str = ""):
|
|
79
94
|
self.params = params
|
|
@@ -729,6 +744,8 @@ class Interpreter:
|
|
|
729
744
|
|
|
730
745
|
def _builtin_head(self, args):
|
|
731
746
|
vec = args[0]
|
|
747
|
+
if isinstance(vec, TengwarLazy):
|
|
748
|
+
return vec.init_val
|
|
732
749
|
if not vec.elements:
|
|
733
750
|
raise RuntimeError_("head of empty vector")
|
|
734
751
|
return vec.elements[0]
|
|
@@ -995,8 +1012,10 @@ class Interpreter:
|
|
|
995
1012
|
return TengwarInt(-1)
|
|
996
1013
|
|
|
997
1014
|
def _builtin_take(self, args):
|
|
998
|
-
n,
|
|
999
|
-
|
|
1015
|
+
n, seq = int(self._num_val(args[0])), args[1]
|
|
1016
|
+
if isinstance(seq, TengwarLazy):
|
|
1017
|
+
return TengwarVector(seq.take(n, self._call_function))
|
|
1018
|
+
return TengwarVector(seq.elements[:n])
|
|
1000
1019
|
|
|
1001
1020
|
def _builtin_drop(self, args):
|
|
1002
1021
|
n, vec = int(self._num_val(args[0])), args[1]
|
|
@@ -1095,6 +1114,11 @@ class Interpreter:
|
|
|
1095
1114
|
return TengwarVector([val] * n)
|
|
1096
1115
|
|
|
1097
1116
|
def _builtin_iterate(self, args):
|
|
1117
|
+
"""(iterate fn init n) → eager vector, (iterate fn init) → lazy sequence"""
|
|
1118
|
+
if len(args) == 2:
|
|
1119
|
+
# Lazy form: return a TengwarLazy that take/head can consume
|
|
1120
|
+
fn, init = args[0], args[1]
|
|
1121
|
+
return TengwarLazy(fn, init)
|
|
1098
1122
|
fn, init, n = args[0], args[1], int(self._num_val(args[2]))
|
|
1099
1123
|
result = [init]
|
|
1100
1124
|
val = init
|
|
@@ -1815,9 +1839,9 @@ class Interpreter:
|
|
|
1815
1839
|
raise RuntimeError_(f"Unknown node type: {type(node).__name__}")
|
|
1816
1840
|
|
|
1817
1841
|
def _eval_binop(self, op: str, left: TengwarValue, right: TengwarValue) -> TengwarValue:
|
|
1818
|
-
# String concatenation with +
|
|
1819
|
-
if op == '+' and isinstance(left, TengwarStr):
|
|
1820
|
-
return TengwarStr(left.value +
|
|
1842
|
+
# String concatenation with + (both must be strings — no implicit coercion)
|
|
1843
|
+
if op == '+' and isinstance(left, TengwarStr) and isinstance(right, TengwarStr):
|
|
1844
|
+
return TengwarStr(left.value + right.value)
|
|
1821
1845
|
|
|
1822
1846
|
# Numeric operations
|
|
1823
1847
|
if isinstance(left, (TengwarInt, TengwarFloat)) and isinstance(right, (TengwarInt, TengwarFloat)):
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
tengwar/__init__.py,sha256=
|
|
1
|
+
tengwar/__init__.py,sha256=LeSxwrvAQpT7OE3vzGjdN9MEuNOqHlK1O78S3hIxg-o,579
|
|
2
2
|
tengwar/__main__.py,sha256=dF1qCzTBDRAf47QGJ6e2kqefPZztrEaE9WuM1n1NfLI,179
|
|
3
3
|
tengwar/ast_nodes.py,sha256=ghhqQQBoqWT-oc9xdCGo2hXBLSqh1zz74hKDyIUtE_Y,7749
|
|
4
4
|
tengwar/binary_ast.py,sha256=UVDGpk_OvHxPLcaToYkAuYA_cg9QQwj6yJXZ057dW0Q,20729
|
|
5
5
|
tengwar/errors.py,sha256=tpZwlDorqUvqX-rtTjL2nhu51Kcdc2ozYBbnJBhR1Hk,773
|
|
6
|
-
tengwar/interpreter.py,sha256=
|
|
6
|
+
tengwar/interpreter.py,sha256=jej7k6I-WwupqlQgJSf6_ihTtawMPvR97_pDsVTd9ts,81919
|
|
7
7
|
tengwar/lexer.py,sha256=d8MphHWmS6aA7HhRdu-CzX1Ma_3oYZSqkhNNrqLa_Ak,17666
|
|
8
8
|
tengwar/mcp_server.py,sha256=P23h-OiedeiowHlvknKsDU1cZ1eaT2ZbXfjCMUGvHus,17921
|
|
9
9
|
tengwar/parser.py,sha256=J9Sc4x8Rs9Rmc5IkOegcfuEWOSIi54fXhjwviF0SjvY,25141
|
|
10
10
|
tengwar/repl.py,sha256=FOvKth8MLOEVExgUvdod-qJqLydbVFDEA1DRhVGjZnQ,4880
|
|
11
11
|
tengwar/vm.py,sha256=etTJTufLqn76GAnZpzG_DLQQ3rXLsyFvHPEU3aNphIY,15883
|
|
12
|
-
tengwar-0.3.
|
|
13
|
-
tengwar-0.3.
|
|
14
|
-
tengwar-0.3.
|
|
15
|
-
tengwar-0.3.
|
|
16
|
-
tengwar-0.3.
|
|
17
|
-
tengwar-0.3.
|
|
12
|
+
tengwar-0.3.3.dist-info/licenses/LICENSE,sha256=qzDJpz75A1ntwYbNw63k1J-9Ov6v4z62Uj7uDcWxv1w,1072
|
|
13
|
+
tengwar-0.3.3.dist-info/METADATA,sha256=U5NW_NAMk54OB8OxJ8O4nrxPLKsfIJpnuUAAxL9GzRc,6949
|
|
14
|
+
tengwar-0.3.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
15
|
+
tengwar-0.3.3.dist-info/entry_points.txt,sha256=W_Zolo2TLJBIDkgAkV7yWzQWKwicET_J9gs4crmrfI4,46
|
|
16
|
+
tengwar-0.3.3.dist-info/top_level.txt,sha256=VyO8Esj_l1yx0c52WUt_KUheaLbXOv2O2kGPZ1eG38k,8
|
|
17
|
+
tengwar-0.3.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|