inscript-lang 2.0.0__tar.gz → 2.0.1__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.
Files changed (30) hide show
  1. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/PKG-INFO +1 -1
  2. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/analyzer.py +6 -0
  3. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/ast_nodes.py +6 -4
  4. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript.py +1 -1
  5. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/PKG-INFO +1 -1
  6. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/interpreter.py +7 -1
  7. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/parser.py +8 -2
  8. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/pyproject.toml +1 -1
  9. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/repl.py +1 -1
  10. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/stdlib_values.py +13 -4
  11. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/README.md +0 -0
  12. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/compiler.py +0 -0
  13. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/environment.py +0 -0
  14. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/errors.py +0 -0
  15. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_fmt.py +0 -0
  16. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/SOURCES.txt +0 -0
  17. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/dependency_links.txt +0 -0
  18. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/entry_points.txt +0 -0
  19. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/requires.txt +0 -0
  20. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/top_level.txt +0 -0
  21. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_test.py +0 -0
  22. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/lexer.py +0 -0
  23. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/pygame_backend.py +0 -0
  24. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/setup.cfg +0 -0
  25. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/setup.py +0 -0
  26. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/stdlib.py +0 -0
  27. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/stdlib_extended.py +0 -0
  28. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/stdlib_extended_2.py +0 -0
  29. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/stdlib_game.py +0 -0
  30. {inscript_lang-2.0.0 → inscript_lang-2.0.1}/vm.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inscript-lang
3
- Version: 2.0.0
3
+ Version: 2.0.1
4
4
  Summary: InScript — a game-focused scripting language with 59 game modules and a bytecode VM
5
5
  Author: Shreyasi Sarkar
6
6
  License: MIT
@@ -1772,6 +1772,12 @@ class Analyzer(Visitor):
1772
1772
  if s not in (T_INT, T_ANY) or e not in (T_INT, T_ANY):
1773
1773
  self._error(f"Range bounds must be int, got '{s}' and '{e}'",
1774
1774
  node.line, node.col)
1775
+ # v2.0.1: validate optional step expression
1776
+ if node.step is not None:
1777
+ st = self.visit(node.step)
1778
+ if st not in (T_INT, T_ANY):
1779
+ self._error(f"Range step must be int, got '{st}'",
1780
+ node.line, node.col)
1775
1781
  return InScriptType("Range", [T_INT])
1776
1782
 
1777
1783
  def visit_LambdaExpr(self, node: LambdaExpr) -> InScriptType:
@@ -195,10 +195,11 @@ class LambdaExpr(Node):
195
195
 
196
196
  @dataclass
197
197
  class RangeExpr(Node):
198
- """0..10 (exclusive) | 0..=10 (inclusive)"""
198
+ """0..10 (exclusive) | 0..=10 (inclusive) | 0..10 step 2 (v2.0.1)"""
199
199
  start: Node
200
200
  end: Node
201
- inclusive: bool = False
201
+ inclusive: bool = False
202
+ step: object = None # None = auto (1, or -1 if start > end)
202
203
 
203
204
 
204
205
  # ─────────────────────────────────────────────────────────────────────────────
@@ -560,10 +561,11 @@ class PropertyDecl(Node):
560
561
 
561
562
  @dataclass
562
563
  class RangeExpr(Node):
563
- """0..10 (exclusive) | 0..=10 (inclusive)"""
564
+ """0..10 (exclusive) | 0..=10 (inclusive) | 0..10 step 2 (v2.0.1)"""
564
565
  start: Node
565
566
  end: Node
566
- inclusive: bool = False
567
+ inclusive: bool = False
568
+ step: object = None # None = auto (1 ascending, -1 descending)
567
569
 
568
570
  @dataclass
569
571
  class LambdaExpr(Node):
@@ -24,7 +24,7 @@ from errors import (InScriptError, LexerError, ParseError,
24
24
  SemanticError, InScriptRuntimeError,
25
25
  MultiError, InScriptWarning)
26
26
 
27
- VERSION = "2.0.0"
27
+ VERSION = "2.0.1"
28
28
 
29
29
  MANIFEST_FILENAME = "inscript.toml"
30
30
  LOCK_FILENAME = "inscript.lock"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inscript-lang
3
- Version: 2.0.0
3
+ Version: 2.0.1
4
4
  Summary: InScript — a game-focused scripting language with 59 game modules and a bytecode VM
5
5
  Author: Shreyasi Sarkar
6
6
  License: MIT
@@ -2470,7 +2470,13 @@ class Interpreter(Visitor):
2470
2470
  def visit_RangeExpr(self, node: RangeExpr) -> Any:
2471
2471
  start = self.visit(node.start)
2472
2472
  end = self.visit(node.end)
2473
- return InScriptRange(start, end, inclusive=node.inclusive)
2473
+ # v2.0.1: optional `step` expression
2474
+ if node.step is not None:
2475
+ step = self.visit(node.step)
2476
+ else:
2477
+ # Auto-descend: if start > end, default step to -1
2478
+ step = -1 if int(start) > int(end) else 1
2479
+ return InScriptRange(start, end, step=step, inclusive=node.inclusive)
2474
2480
 
2475
2481
  def visit_AwaitExpr(self, node: AwaitExpr) -> Any:
2476
2482
  """
@@ -1555,13 +1555,19 @@ class Parser:
1555
1555
  line, col = self._pos()
1556
1556
  left = self.parse_shift()
1557
1557
 
1558
- # Range: start..end or start..=end
1558
+ # Range: start..end or start..=end or start..end step n (v2.0.1)
1559
1559
  if self.check(TT.DOTDOT, TT.DOTDOT_EQ):
1560
1560
  inclusive = (self.current.type == TT.DOTDOT_EQ)
1561
1561
  self.advance()
1562
1562
  right = self.parse_shift()
1563
+ # Optional `step` suffix: 0..20 step 2
1564
+ step_expr = None
1565
+ if (self.current and self.current.type == TT.IDENT
1566
+ and self.current.value == "step"):
1567
+ self.advance() # consume 'step'
1568
+ step_expr = self.parse_shift()
1563
1569
  return RangeExpr(start=left, end=right, inclusive=inclusive,
1564
- line=line, col=col)
1570
+ step=step_expr, line=line, col=col)
1565
1571
 
1566
1572
  # Membership: x in collection / x not in collection
1567
1573
  if self.check(TT.IN):
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "inscript-lang"
7
- version = "2.0.0"
7
+ version = "2.0.1"
8
8
  description = "InScript — a game-focused scripting language with 59 game modules and a bytecode VM"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -40,7 +40,7 @@ sys.path.insert(0, str(Path(__file__).parent))
40
40
 
41
41
  HISTORY_FILE = Path.home() / ".inscript" / "history"
42
42
  HISTORY_FILE.parent.mkdir(parents=True, exist_ok=True)
43
- VERSION = "2.0.0"
43
+ VERSION = "2.0.1"
44
44
 
45
45
  # ── ANSI colours ──────────────────────────────────────────────────────────────
46
46
  def _c(code, text):
@@ -281,16 +281,25 @@ class InScriptRange:
281
281
  self.inclusive = inclusive
282
282
 
283
283
  def __iter__(self):
284
- stop = self.end + 1 if self.inclusive else self.end
284
+ # v2.0.1: support negative step (descending ranges)
285
+ if self.step > 0:
286
+ stop = self.end + 1 if self.inclusive else self.end
287
+ else:
288
+ stop = self.end - 1 if self.inclusive else self.end
285
289
  return iter(range(self.start, stop, self.step))
286
290
 
287
291
  def __len__(self):
288
- stop = self.end + 1 if self.inclusive else self.end
289
- return max(0, (stop - self.start + self.step - 1) // self.step)
292
+ if self.step > 0:
293
+ stop = self.end + 1 if self.inclusive else self.end
294
+ return max(0, (stop - self.start + self.step - 1) // self.step)
295
+ else:
296
+ stop = self.end - 1 if self.inclusive else self.end
297
+ return max(0, (self.start - stop + (-self.step) - 1) // (-self.step))
290
298
 
291
299
  def __repr__(self):
292
300
  op = "..=" if self.inclusive else ".."
293
- return f"{self.start}{op}{self.end}"
301
+ s = f" step {self.step}" if self.step not in (1, -1) else ("" if self.step == 1 else " step -1")
302
+ return f"{self.start}{op}{self.end}{s}"
294
303
 
295
304
 
296
305
  class InScriptGenerator:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes