inscript-lang 1.9.4__tar.gz → 1.9.6__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-1.9.4 → inscript_lang-1.9.6}/PKG-INFO +1 -1
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/errors.py +2 -1
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/inscript.py +19 -6
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/inscript_lang.egg-info/PKG-INFO +1 -1
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/lexer.py +7 -19
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/parser.py +7 -1
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/pyproject.toml +1 -1
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/repl.py +1 -1
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/README.md +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/analyzer.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/ast_nodes.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/compiler.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/environment.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/inscript_fmt.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/inscript_lang.egg-info/SOURCES.txt +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/inscript_lang.egg-info/dependency_links.txt +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/inscript_lang.egg-info/entry_points.txt +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/inscript_lang.egg-info/requires.txt +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/inscript_lang.egg-info/top_level.txt +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/inscript_test.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/interpreter.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/pygame_backend.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/setup.cfg +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/setup.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/stdlib.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/stdlib_extended.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/stdlib_extended_2.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/stdlib_game.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/stdlib_values.py +0 -0
- {inscript_lang-1.9.4 → inscript_lang-1.9.6}/vm.py +0 -0
|
@@ -54,8 +54,9 @@ ERROR_CODES = {
|
|
|
54
54
|
"PropertyError": "E0048",
|
|
55
55
|
"NilAccess": "E0049",
|
|
56
56
|
|
|
57
|
-
# Deprecated-keyword hard errors (v1.7.4)
|
|
57
|
+
# Deprecated-keyword hard errors (v1.7.4+)
|
|
58
58
|
"NullKeyword": "E0055",
|
|
59
|
+
"DivKeyword": "E0056",
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
DOCS_BASE = "https://docs.inscript.dev/errors"
|
|
@@ -24,7 +24,7 @@ from errors import (InScriptError, LexerError, ParseError,
|
|
|
24
24
|
SemanticError, InScriptRuntimeError,
|
|
25
25
|
MultiError, InScriptWarning)
|
|
26
26
|
|
|
27
|
-
VERSION = "1.9.
|
|
27
|
+
VERSION = "1.9.6"
|
|
28
28
|
LANG = "InScript"
|
|
29
29
|
PACKAGES_DIR = os.path.join(os.path.expanduser("~"), ".inscript", "packages")
|
|
30
30
|
REGISTRY_URL = "https://raw.githubusercontent.com/authorss81/inscript-packages/main/registry.json"
|
|
@@ -256,9 +256,9 @@ def _compat_files(path: str) -> int:
|
|
|
256
256
|
|
|
257
257
|
CHECKS = [
|
|
258
258
|
(_re.compile(r'\bnull\b'),
|
|
259
|
-
"use of 'null' — removed in
|
|
259
|
+
"use of 'null' — removed in v1.7.4, use 'nil'"),
|
|
260
260
|
(_re.compile(r'\bdiv\b'),
|
|
261
|
-
"use of 'div' operator — removed in
|
|
261
|
+
"use of 'div' operator — removed in v1.9.5 (hard error), use '//' for floor division"),
|
|
262
262
|
(_re.compile(r':\s*\[\]'),
|
|
263
263
|
"bare ':[]' type annotation — use ':array' or ':[T]' with element type"),
|
|
264
264
|
(_re.compile(r'\barray\b(?!\s*<)(?!\s*\[)'),
|
|
@@ -276,7 +276,8 @@ def _compat_files(path: str) -> int:
|
|
|
276
276
|
print(f"[InScript compat] Cannot read '{fpath}': {e}", file=sys.stderr)
|
|
277
277
|
return issues
|
|
278
278
|
for lineno, line in enumerate(src.splitlines(), 1):
|
|
279
|
-
|
|
279
|
+
stripped = line.lstrip()
|
|
280
|
+
if stripped.startswith("//") or stripped.startswith("#"):
|
|
280
281
|
continue
|
|
281
282
|
for pat, msg in CHECKS:
|
|
282
283
|
if pat.search(line):
|
|
@@ -333,9 +334,20 @@ def _migrate_files(path: str) -> int:
|
|
|
333
334
|
with open(fpath, encoding="utf-8") as f:
|
|
334
335
|
original = f.read()
|
|
335
336
|
src = original
|
|
337
|
+
# v1.9.6: // line comments → # line comments (MUST run before div→// rewrite)
|
|
338
|
+
# Rule 1: standalone comment lines — optional whitespace then //
|
|
339
|
+
src = re.sub(r'^(\s*)//', r'\1#', src, flags=re.MULTILINE)
|
|
340
|
+
# Rule 2: inline word comment — ` // word` → ` # word`
|
|
341
|
+
# Fires only when identifier/word follows, not digit (digits are floor-div)
|
|
342
|
+
src = re.sub(r'(\s)//(\s+[A-Za-z_])', r'\1#\2', src)
|
|
343
|
+
# Rule 3: warn about ambiguous ` // <digit>` patterns (may be comment or floor-div)
|
|
344
|
+
ambiguous = re.findall(r'(\s)//(\s+\d)', src)
|
|
345
|
+
if ambiguous:
|
|
346
|
+
print(f" WARNING {fpath}: {len(ambiguous)} ambiguous ' // <digit>' pattern(s) — "
|
|
347
|
+
f"check manually: floor-div or comment? Change to '#' if comment.")
|
|
336
348
|
# null → nil
|
|
337
349
|
src = re.sub(r'\bnull\b', 'nil', src)
|
|
338
|
-
# x div y → x // y (only bare `div` between expressions)
|
|
350
|
+
# x div y → x // y (only bare `div` between expressions, safe after comment rules)
|
|
339
351
|
src = re.sub(r'\bdiv\b', '//', src)
|
|
340
352
|
# bare [] type annotation → array (e.g. `: []` → `: array`)
|
|
341
353
|
src = re.sub(r':\s*\[\]', ': array', src)
|
|
@@ -786,6 +798,7 @@ ERROR_CATALOGUE = {
|
|
|
786
798
|
"E0053": ("ConstInLoop", "const declaration inside a loop"),
|
|
787
799
|
"E0054": ("NeverNotDiverging", "Function declared -> never but has a non-throwing path"),
|
|
788
800
|
"E0055": ("NullKeyword", "'null' keyword removed in v1.7.4 — use 'nil'"),
|
|
801
|
+
"E0056": ("DivKeyword", "'div' keyword removed in v1.9.5 — use '//' for integer division"),
|
|
789
802
|
}
|
|
790
803
|
|
|
791
804
|
|
|
@@ -1153,7 +1166,7 @@ LANGUAGE_SPEC = """# InScript Language Specification
|
|
|
1153
1166
|
## 1. Lexical Structure
|
|
1154
1167
|
|
|
1155
1168
|
### 1.1 Comments
|
|
1156
|
-
- Line comments: `// text`
|
|
1169
|
+
- Line comments: `# text` (v1.9.6: was `// text`)
|
|
1157
1170
|
- Block comments: `/* text */` (nestable)
|
|
1158
1171
|
- Doc comments: `/// text` (parsed by `inscript doc`)
|
|
1159
1172
|
|
|
@@ -292,26 +292,12 @@ class Lexer:
|
|
|
292
292
|
if ch in (" ", "\t", "\r", "\n"):
|
|
293
293
|
return
|
|
294
294
|
|
|
295
|
-
# // — floor-division operator
|
|
296
|
-
# v1.
|
|
297
|
-
#
|
|
298
|
-
# Floor division: `10 // 3`, `x//2`, `(a+b) // c`
|
|
299
|
-
# Rule: if the character BEFORE // was a digit, ), ], or identifier char → floor div
|
|
300
|
-
# otherwise → line comment
|
|
295
|
+
# // — floor-division operator (v1.9.6: ALWAYS floor division, no exceptions)
|
|
296
|
+
# v1.9.6: `#` is the new line-comment character.
|
|
297
|
+
# `//` with or without spaces is always integer floor division: 10 // 3 → 3
|
|
301
298
|
if ch == "/" and self.current == "/":
|
|
302
299
|
self.advance() # consume second /
|
|
303
|
-
|
|
304
|
-
# Rule: the character IMMEDIATELY before first '/' (no whitespace allowed)
|
|
305
|
-
# must be digit/identifier/closing bracket to be floor-div.
|
|
306
|
-
# Any space/tab before the // → line comment.
|
|
307
|
-
first_slash_pos = self.pos - 2
|
|
308
|
-
prev = self.source[first_slash_pos - 1] if first_slash_pos > 0 else ''
|
|
309
|
-
if prev and (prev.isdigit() or prev.isalpha() or prev in ')]}'):
|
|
310
|
-
# `10//3`, `x//2`, `(a+b)//c` — no space → floor division
|
|
311
|
-
self._emit(TT.SLASH_SLASH, "//", sl, sc)
|
|
312
|
-
else:
|
|
313
|
-
# `10 // 3` with spaces, `5 // comment`, `// standalone` → comment
|
|
314
|
-
self._skip_line_comment()
|
|
300
|
+
self._emit(TT.SLASH_SLASH, "//", sl, sc)
|
|
315
301
|
return
|
|
316
302
|
if ch == "/" and self.current == "*":
|
|
317
303
|
self._skip_block_comment(sl, sc); return
|
|
@@ -586,7 +572,9 @@ class Lexer:
|
|
|
586
572
|
if self.match("?"): emit(TT.NULLISH, "??")
|
|
587
573
|
elif self.match("."): emit(TT.QUESTION_DOT, "?.")
|
|
588
574
|
else: emit(TT.QUESTION, "?")
|
|
589
|
-
elif ch == "#":
|
|
575
|
+
elif ch == "#":
|
|
576
|
+
# v1.9.6: # is the line-comment character (was: HASH annotation token)
|
|
577
|
+
self._skip_line_comment(); return
|
|
590
578
|
elif ch == "@": emit(TT.AT, "@")
|
|
591
579
|
elif ch == "(": emit(TT.LPAREN)
|
|
592
580
|
elif ch == ")": emit(TT.RPAREN)
|
|
@@ -1610,7 +1610,13 @@ class Parser:
|
|
|
1610
1610
|
left = self.parse_unary() # BUG-09 fix: call parse_unary (was parse_power)
|
|
1611
1611
|
while self.check(TT.STAR, TT.SLASH, TT.SLASH_SLASH, TT.PERCENT) or self.check(TT.DIV):
|
|
1612
1612
|
op_tok = self.advance()
|
|
1613
|
-
|
|
1613
|
+
if op_tok.type == TT.DIV:
|
|
1614
|
+
self._error(
|
|
1615
|
+
"[E0056] 'div' was removed in v1.9.5 — use '//' for integer division. "
|
|
1616
|
+
"Run: inscript migrate <file> to auto-fix.",
|
|
1617
|
+
op_tok
|
|
1618
|
+
)
|
|
1619
|
+
op = op_tok.value
|
|
1614
1620
|
right = self.parse_unary()
|
|
1615
1621
|
left = BinaryExpr(left=left, op=op, right=right,
|
|
1616
1622
|
line=line, col=col)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "inscript-lang"
|
|
7
|
-
version = "1.9.
|
|
7
|
+
version = "1.9.6"
|
|
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 = "1.9.
|
|
43
|
+
VERSION = "1.9.6"
|
|
44
44
|
|
|
45
45
|
# ── ANSI colours ──────────────────────────────────────────────────────────────
|
|
46
46
|
def _c(code, text):
|
|
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
|
|
File without changes
|
|
File without changes
|