inscript-lang 1.9.13__tar.gz → 2.0.0__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-1.9.13 → inscript_lang-2.0.0}/PKG-INFO +1 -1
  2. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/analyzer.py +31 -0
  3. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/inscript.py +12 -10
  4. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/inscript_lang.egg-info/PKG-INFO +1 -1
  5. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/lexer.py +7 -1
  6. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/pyproject.toml +1 -1
  7. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/repl.py +1 -1
  8. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/README.md +0 -0
  9. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/ast_nodes.py +0 -0
  10. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/compiler.py +0 -0
  11. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/environment.py +0 -0
  12. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/errors.py +0 -0
  13. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/inscript_fmt.py +0 -0
  14. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/inscript_lang.egg-info/SOURCES.txt +0 -0
  15. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/inscript_lang.egg-info/dependency_links.txt +0 -0
  16. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/inscript_lang.egg-info/entry_points.txt +0 -0
  17. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/inscript_lang.egg-info/requires.txt +0 -0
  18. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/inscript_lang.egg-info/top_level.txt +0 -0
  19. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/inscript_test.py +0 -0
  20. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/interpreter.py +0 -0
  21. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/parser.py +0 -0
  22. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/pygame_backend.py +0 -0
  23. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/setup.cfg +0 -0
  24. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/setup.py +0 -0
  25. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/stdlib.py +0 -0
  26. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/stdlib_extended.py +0 -0
  27. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/stdlib_extended_2.py +0 -0
  28. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/stdlib_game.py +0 -0
  29. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/stdlib_values.py +0 -0
  30. {inscript_lang-1.9.13 → inscript_lang-2.0.0}/vm.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inscript-lang
3
- Version: 1.9.13
3
+ Version: 2.0.0
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
@@ -1160,6 +1160,37 @@ class Analyzer(Visitor):
1160
1160
  def visit_BoolLiteralExpr(self, node: BoolLiteralExpr) -> InScriptType: return T_BOOL
1161
1161
  def visit_NullLiteralExpr(self, node: NullLiteralExpr) -> InScriptType: return T_NULL
1162
1162
 
1163
+ def visit_FStringExpr(self, node) -> InScriptType:
1164
+ """v1.9.15: $"..." and f"..." interpolated strings always produce T_STRING.
1165
+ Type-check each {expr} segment by re-parsing and visiting it.
1166
+ """
1167
+ import re
1168
+ template = node.template
1169
+ for m in re.finditer(r'(?<!\x00)\{([^}\x00][^}]*)\}', template):
1170
+ inner = m.group(1).strip()
1171
+ # Strip optional format spec :spec
1172
+ depth = 0; split_at = -1; ternary_depth = 0
1173
+ for i, ch in enumerate(inner):
1174
+ if ch in '([{': depth += 1
1175
+ elif ch in ')]}': depth -= 1
1176
+ elif ch == '?' and depth == 0: ternary_depth += 1
1177
+ elif ch == ':' and depth == 0:
1178
+ if ternary_depth > 0: ternary_depth -= 1
1179
+ else: split_at = i; break
1180
+ expr_src = inner[:split_at].strip() if split_at > 0 else inner
1181
+ try:
1182
+ from parser import parse
1183
+ prog = parse(expr_src)
1184
+ # visit each stmt in a suppressed-error sub-context
1185
+ saved = self._errors; self._errors = []
1186
+ try:
1187
+ for stmt in prog.body: self.visit(stmt)
1188
+ finally:
1189
+ self._errors = saved
1190
+ except Exception:
1191
+ pass # parse errors in sub-expr are caught at runtime
1192
+ return T_STRING
1193
+
1163
1194
  def visit_IdentExpr(self, node: IdentExpr) -> InScriptType:
1164
1195
  sym = self._lookup(node.name, node.line, node.col)
1165
1196
  return sym.type_
@@ -24,7 +24,7 @@ from errors import (InScriptError, LexerError, ParseError,
24
24
  SemanticError, InScriptRuntimeError,
25
25
  MultiError, InScriptWarning)
26
26
 
27
- VERSION = "1.9.13"
27
+ VERSION = "2.0.0"
28
28
 
29
29
  MANIFEST_FILENAME = "inscript.toml"
30
30
  LOCK_FILENAME = "inscript.lock"
@@ -703,9 +703,9 @@ def _check_v2_readiness(project_dir: str = ".") -> int:
703
703
  for fpath in ins_files:
704
704
  try:
705
705
  src = open(fpath, encoding="utf-8").read()
706
- # Detect lines where // is used as a comment (standalone // line or // followed by a word)
706
+ # Only flag STANDALONE // lines inline // is always floor division in v1.9.6+
707
707
  bad = [i+1 for i, l in enumerate(src.splitlines())
708
- if _re.match(r'^\s*//', l) or _re.search(r'\s//\s+[A-Za-z_]', l)]
708
+ if _re.match(r'^\s*//', l)]
709
709
  if bad:
710
710
  comment_hits.append((fpath, bad))
711
711
  except OSError:
@@ -785,9 +785,11 @@ def _migrate_files(path: str) -> int:
785
785
  # v1.9.6: // line comments → # line comments (MUST run before div→// rewrite)
786
786
  # Rule 1: standalone comment lines — optional whitespace then //
787
787
  src = re.sub(r'^(\s*)//', r'\1#', src, flags=re.MULTILINE)
788
- # Rule 2: inline word comment — ` // word` → ` # word`
789
- # Fires only when identifier/word follows, not digit (digits are floor-div)
790
- src = re.sub(r'(\s)//(\s+[A-Za-z_])', r'\1#\2', src)
788
+ # Rule 2: inline trailing comment — `; // word` or `} // word` → `; # word`
789
+ # v1.9.15: ONLY fires after statement terminators (;, {, }),
790
+ # NOT after expression-ending chars like ), ], identifiers, digits.
791
+ # This prevents floor-division like `(a*b) // gcd(a,b)` being mangled.
792
+ src = re.sub(r'([;{}])( *)//(\s+[A-Za-z_])', r'\1\2#\3', src)
791
793
  # Rule 3: warn about ambiguous ` // <digit>` patterns (may be comment or floor-div)
792
794
  ambiguous = re.findall(r'(\s)//(\s+\d)', src)
793
795
  if ambiguous:
@@ -2335,10 +2337,6 @@ Examples:
2335
2337
  profile=profile)
2336
2338
 
2337
2339
 
2338
- if __name__ == "__main__":
2339
- sys.exit(main())
2340
-
2341
-
2342
2340
  # ─────────────────────────────────────────────────────────────────────────────
2343
2341
  # v1.9.2 — Package Manifest Foundation
2344
2342
  # ─────────────────────────────────────────────────────────────────────────────
@@ -2690,3 +2688,7 @@ def _generate_lockfile(directory: str = ".") -> int:
2690
2688
  except OSError as e:
2691
2689
  print(f"[InScript lock] Cannot write lockfile: {e}", file=sys.stderr)
2692
2690
  return 1
2691
+
2692
+
2693
+ if __name__ == "__main__":
2694
+ sys.exit(main())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inscript-lang
3
- Version: 1.9.13
3
+ Version: 2.0.0
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
@@ -365,7 +365,7 @@ class Lexer:
365
365
  self._error("Unterminated triple-quoted string", sl, sc)
366
366
 
367
367
  def _scan_fstring(self, quote: str, sl: int, sc: int):
368
- """Scan f"...{expr}..." — store the raw template as FSTRING token.
368
+ """Scan f"...{expr}..." or $"...{expr}..." — store the raw template as FSTRING token. v1.9.15: $"..." is the new preferred syntax; both prefixes share this scanner.
369
369
  {{ and }} are literal brace escapes.
370
370
  Inside {}, quote characters are allowed (e.g. d["key"])."""
371
371
  chars = []
@@ -580,6 +580,12 @@ class Lexer:
580
580
  elif ch == "#":
581
581
  # v1.9.6: # is the line-comment character (was: HASH annotation token)
582
582
  self._skip_line_comment(); return
583
+ elif ch == "$":
584
+ # v1.9.15: $"..." interpolated string (preferred over f"...")
585
+ if self.current in ('"', "'"):
586
+ self._scan_fstring(self.advance(), sl, sc)
587
+ return
588
+ # bare $ not followed by quote — skip (not used otherwise)
583
589
  elif ch == "@": emit(TT.AT, "@")
584
590
  elif ch == "(": emit(TT.LPAREN)
585
591
  elif ch == ")": emit(TT.RPAREN)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "inscript-lang"
7
- version = "1.9.13"
7
+ version = "2.0.0"
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.13"
43
+ VERSION = "2.0.0"
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