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.
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/PKG-INFO +1 -1
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/analyzer.py +6 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/ast_nodes.py +6 -4
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript.py +1 -1
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/PKG-INFO +1 -1
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/interpreter.py +7 -1
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/parser.py +8 -2
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/pyproject.toml +1 -1
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/repl.py +1 -1
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/stdlib_values.py +13 -4
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/README.md +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/compiler.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/environment.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/errors.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_fmt.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/SOURCES.txt +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/dependency_links.txt +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/entry_points.txt +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/requires.txt +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_lang.egg-info/top_level.txt +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/inscript_test.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/lexer.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/pygame_backend.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/setup.cfg +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/setup.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/stdlib.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/stdlib_extended.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/stdlib_extended_2.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/stdlib_game.py +0 -0
- {inscript_lang-2.0.0 → inscript_lang-2.0.1}/vm.py +0 -0
|
@@ -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
|
|
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
|
|
567
|
+
inclusive: bool = False
|
|
568
|
+
step: object = None # None = auto (1 ascending, -1 descending)
|
|
567
569
|
|
|
568
570
|
@dataclass
|
|
569
571
|
class LambdaExpr(Node):
|
|
@@ -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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
289
|
-
|
|
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
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|