tengwar 0.3.3__py3-none-any.whl → 0.3.4__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 CHANGED
@@ -5,7 +5,7 @@ Built from first principles for machine intelligence.
5
5
  Zero ambiguity. Maximum semantic density. Binary AST protocol.
6
6
  """
7
7
 
8
- __version__ = "0.3.3"
8
+ __version__ = "0.3.4"
9
9
  __author__ = "TENGWAR Project"
10
10
 
11
11
  from .lexer import tokenize
tengwar/interpreter.py CHANGED
@@ -75,18 +75,12 @@ class TengwarVector(TengwarValue):
75
75
 
76
76
 
77
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)}>'
78
+ """Lazy sequence — uses a generator factory for composable lazy ops."""
79
+ def __init__(self, make_gen):
80
+ self._make_gen = make_gen # callable that returns a fresh generator
81
+ def __iter__(self):
82
+ return self._make_gen()
83
+ def __repr__(self): return '<lazy-seq>'
90
84
 
91
85
 
92
86
  class TengwarClosure(TengwarValue):
@@ -543,6 +537,8 @@ class Interpreter:
543
537
  return TengwarFloat(math.sqrt(args[0].value))
544
538
 
545
539
  def _builtin_mod(self, args):
540
+ if args[1].value == 0:
541
+ raise RuntimeError_("Modulo by zero")
546
542
  return TengwarInt(args[0].value % args[1].value)
547
543
 
548
544
  def _builtin_len(self, args):
@@ -642,15 +638,30 @@ class Interpreter:
642
638
  return TengwarVector(vec.elements[start:end])
643
639
 
644
640
  def _builtin_map(self, args):
645
- fn, vec = args[0], args[1]
646
- if not isinstance(vec, TengwarVector):
647
- raise RuntimeError_("map requires a vector")
648
- return TengwarVector([self._call_function(fn, [e]) for e in vec.elements])
641
+ fn, seq = args[0], args[1]
642
+ if isinstance(seq, TengwarLazy):
643
+ interp = self
644
+ parent = seq._make_gen
645
+ def make_gen():
646
+ for val in parent():
647
+ yield interp._call_function(fn, [val])
648
+ return TengwarLazy(make_gen)
649
+ if not isinstance(seq, TengwarVector):
650
+ raise RuntimeError_("map requires a vector or lazy sequence")
651
+ return TengwarVector([self._call_function(fn, [e]) for e in seq.elements])
649
652
 
650
653
  def _builtin_filter(self, args):
651
- fn, vec = args[0], args[1]
654
+ fn, seq = args[0], args[1]
655
+ if isinstance(seq, TengwarLazy):
656
+ interp = self
657
+ parent = seq._make_gen
658
+ def make_gen():
659
+ for val in parent():
660
+ if interp._is_truthy(interp._call_function(fn, [val])):
661
+ yield val
662
+ return TengwarLazy(make_gen)
652
663
  result = []
653
- for e in vec.elements:
664
+ for e in seq.elements:
654
665
  if self._is_truthy(self._call_function(fn, [e])):
655
666
  result.append(e)
656
667
  return TengwarVector(result)
@@ -745,13 +756,22 @@ class Interpreter:
745
756
  def _builtin_head(self, args):
746
757
  vec = args[0]
747
758
  if isinstance(vec, TengwarLazy):
748
- return vec.init_val
759
+ for val in vec:
760
+ return val
761
+ raise RuntimeError_("head of empty lazy sequence")
749
762
  if not vec.elements:
750
763
  raise RuntimeError_("head of empty vector")
751
764
  return vec.elements[0]
752
765
 
753
766
  def _builtin_tail(self, args):
754
767
  vec = args[0]
768
+ if isinstance(vec, TengwarLazy):
769
+ parent = vec._make_gen
770
+ def make_gen():
771
+ gen = parent()
772
+ next(gen, None) # skip first
773
+ yield from gen
774
+ return TengwarLazy(make_gen)
755
775
  if not vec.elements:
756
776
  raise RuntimeError_("tail of empty vector")
757
777
  return TengwarVector(vec.elements[1:])
@@ -764,6 +784,11 @@ class Interpreter:
764
784
 
765
785
  def _builtin_nth(self, args):
766
786
  col, idx = args[0], args[1].value
787
+ if isinstance(col, TengwarLazy):
788
+ for i, val in enumerate(col):
789
+ if i == idx:
790
+ return val
791
+ raise RuntimeError_(f"nth: index {idx} out of range")
767
792
  if isinstance(col, TengwarTuple): return col.elements[idx]
768
793
  if isinstance(col, TengwarVector): return col.elements[idx]
769
794
  raise RuntimeError_(f"Cannot nth into {type(col).__name__}")
@@ -897,8 +922,16 @@ class Interpreter:
897
922
  def _builtin_enumerate(self, args):
898
923
  """(enumerate vec) = vector of (index, element) tuples"""
899
924
  vec = args[0]
925
+ if isinstance(vec, TengwarLazy):
926
+ parent = vec._make_gen
927
+ def make_gen():
928
+ i = 0
929
+ for val in parent():
930
+ yield TengwarTuple([TengwarInt(i), val])
931
+ i += 1
932
+ return TengwarLazy(make_gen)
900
933
  if not isinstance(vec, TengwarVector):
901
- raise RuntimeError_("enumerate requires a vector")
934
+ raise RuntimeError_("enumerate requires a vector or lazy sequence")
902
935
  return TengwarVector([
903
936
  TengwarTuple([TengwarInt(i), e])
904
937
  for i, e in enumerate(vec.elements)
@@ -915,10 +948,25 @@ class Interpreter:
915
948
  def _builtin_apply(self, args):
916
949
  fn, arg_vec = args[0], args[1]
917
950
  if isinstance(arg_vec, TengwarVector):
918
- return self._call_function(fn, arg_vec.elements)
919
- if isinstance(arg_vec, TengwarTuple):
920
- return self._call_function(fn, arg_vec.elements)
921
- return self._call_function(fn, [arg_vec])
951
+ elems = arg_vec.elements
952
+ elif isinstance(arg_vec, TengwarTuple):
953
+ elems = arg_vec.elements
954
+ else:
955
+ elems = [arg_vec]
956
+ if not elems:
957
+ raise RuntimeError_("apply: cannot apply function to empty collection")
958
+ if len(elems) == 1:
959
+ try:
960
+ return self._call_function(fn, elems)
961
+ except (TypeError, IndexError):
962
+ raise RuntimeError_("apply: function requires more arguments")
963
+ if len(elems) == 2:
964
+ return self._call_function(fn, elems)
965
+ # >2 args: reduce (Clojure-style variadic apply)
966
+ acc = self._call_function(fn, [elems[0], elems[1]])
967
+ for e in elems[2:]:
968
+ acc = self._call_function(fn, [acc, e])
969
+ return acc
922
970
 
923
971
  def _builtin_err(self, args):
924
972
  raise RuntimeError_(self._display(args[0]) if args else "error")
@@ -1014,17 +1062,39 @@ class Interpreter:
1014
1062
  def _builtin_take(self, args):
1015
1063
  n, seq = int(self._num_val(args[0])), args[1]
1016
1064
  if isinstance(seq, TengwarLazy):
1017
- return TengwarVector(seq.take(n, self._call_function))
1065
+ result = []
1066
+ for val in seq:
1067
+ result.append(val)
1068
+ if len(result) >= n:
1069
+ break
1070
+ return TengwarVector(result)
1018
1071
  return TengwarVector(seq.elements[:n])
1019
1072
 
1020
1073
  def _builtin_drop(self, args):
1021
- n, vec = int(self._num_val(args[0])), args[1]
1022
- return TengwarVector(vec.elements[n:])
1074
+ n, seq = int(self._num_val(args[0])), args[1]
1075
+ if isinstance(seq, TengwarLazy):
1076
+ parent = seq._make_gen
1077
+ count = n
1078
+ def make_gen():
1079
+ gen = parent()
1080
+ for _ in range(count):
1081
+ next(gen, None)
1082
+ yield from gen
1083
+ return TengwarLazy(make_gen)
1084
+ return TengwarVector(seq.elements[n:])
1023
1085
 
1024
1086
  def _builtin_take_while(self, args):
1025
- fn, vec = args[0], args[1]
1087
+ fn, seq = args[0], args[1]
1088
+ if isinstance(seq, TengwarLazy):
1089
+ result = []
1090
+ for val in seq:
1091
+ if self._is_truthy(self._call_function(fn, [val])):
1092
+ result.append(val)
1093
+ else:
1094
+ break
1095
+ return TengwarVector(result)
1026
1096
  result = []
1027
- for e in vec.elements:
1097
+ for e in seq.elements:
1028
1098
  if self._is_truthy(self._call_function(fn, [e])):
1029
1099
  result.append(e)
1030
1100
  else:
@@ -1032,10 +1102,21 @@ class Interpreter:
1032
1102
  return TengwarVector(result)
1033
1103
 
1034
1104
  def _builtin_drop_while(self, args):
1035
- fn, vec = args[0], args[1]
1105
+ fn, seq = args[0], args[1]
1106
+ if isinstance(seq, TengwarLazy):
1107
+ interp = self
1108
+ parent = seq._make_gen
1109
+ def make_gen():
1110
+ dropping = True
1111
+ for val in parent():
1112
+ if dropping and interp._is_truthy(interp._call_function(fn, [val])):
1113
+ continue
1114
+ dropping = False
1115
+ yield val
1116
+ return TengwarLazy(make_gen)
1036
1117
  dropping = True
1037
1118
  result = []
1038
- for e in vec.elements:
1119
+ for e in seq.elements:
1039
1120
  if dropping and self._is_truthy(self._call_function(fn, [e])):
1040
1121
  continue
1041
1122
  dropping = False
@@ -1089,10 +1170,20 @@ class Interpreter:
1089
1170
  return TengwarTuple([TengwarVector(yes), TengwarVector(no)])
1090
1171
 
1091
1172
  def _builtin_scan(self, args):
1092
- fn, init, vec = args[0], args[1], args[2]
1173
+ fn, init, seq = args[0], args[1], args[2]
1174
+ if isinstance(seq, TengwarLazy):
1175
+ interp = self
1176
+ parent = seq._make_gen
1177
+ def make_gen():
1178
+ acc = init
1179
+ yield acc
1180
+ for val in parent():
1181
+ acc = interp._call_function(fn, [acc, val])
1182
+ yield acc
1183
+ return TengwarLazy(make_gen)
1093
1184
  acc = init
1094
1185
  result = [acc]
1095
- for e in vec.elements:
1186
+ for e in seq.elements:
1096
1187
  acc = self._call_function(fn, [acc, e])
1097
1188
  result.append(acc)
1098
1189
  return TengwarVector(result)
@@ -1116,9 +1207,14 @@ class Interpreter:
1116
1207
  def _builtin_iterate(self, args):
1117
1208
  """(iterate fn init n) → eager vector, (iterate fn init) → lazy sequence"""
1118
1209
  if len(args) == 2:
1119
- # Lazy form: return a TengwarLazy that take/head can consume
1120
1210
  fn, init = args[0], args[1]
1121
- return TengwarLazy(fn, init)
1211
+ interp = self
1212
+ def make_gen():
1213
+ val = init
1214
+ while True:
1215
+ yield val
1216
+ val = interp._call_function(fn, [val])
1217
+ return TengwarLazy(make_gen)
1122
1218
  fn, init, n = args[0], args[1], int(self._num_val(args[2]))
1123
1219
  result = [init]
1124
1220
  val = init
@@ -1855,7 +1951,9 @@ class Interpreter:
1855
1951
  if op == '/':
1856
1952
  if rv == 0: raise RuntimeError_("Division by zero")
1857
1953
  return TengwarFloat(lv / rv) if use_float else TengwarInt(lv // rv)
1858
- if op == '%': return wrap(lv % rv)
1954
+ if op == '%':
1955
+ if rv == 0: raise RuntimeError_("Modulo by zero")
1956
+ return wrap(lv % rv)
1859
1957
  if op == '=': return TengwarBool(lv == rv)
1860
1958
  if op == '!=': return TengwarBool(lv != rv)
1861
1959
  if op == '<': return TengwarBool(lv < rv)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tengwar
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: The AI-Native Programming Language
5
5
  Author: TENGWAR Project
6
6
  License: MIT
@@ -1,17 +1,17 @@
1
- tengwar/__init__.py,sha256=LeSxwrvAQpT7OE3vzGjdN9MEuNOqHlK1O78S3hIxg-o,579
1
+ tengwar/__init__.py,sha256=r2Fv1Bxv43nmcSUzoe1rVFZ1c9rI8gwXht1EyIVuMLI,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=jej7k6I-WwupqlQgJSf6_ihTtawMPvR97_pDsVTd9ts,81919
6
+ tengwar/interpreter.py,sha256=t4Lun4pbUdVFwQoiU44_-1CSsjovo44u4CRX5IZRbuI,85532
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.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,,
12
+ tengwar-0.3.4.dist-info/licenses/LICENSE,sha256=qzDJpz75A1ntwYbNw63k1J-9Ov6v4z62Uj7uDcWxv1w,1072
13
+ tengwar-0.3.4.dist-info/METADATA,sha256=Nb-AVaVRycCRe-lrQw8y7X7gkfNwyMSEl06vR4CTFa8,6949
14
+ tengwar-0.3.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
15
+ tengwar-0.3.4.dist-info/entry_points.txt,sha256=W_Zolo2TLJBIDkgAkV7yWzQWKwicET_J9gs4crmrfI4,46
16
+ tengwar-0.3.4.dist-info/top_level.txt,sha256=VyO8Esj_l1yx0c52WUt_KUheaLbXOv2O2kGPZ1eG38k,8
17
+ tengwar-0.3.4.dist-info/RECORD,,