tova 0.9.6 → 0.9.7

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.
package/bin/tova.js CHANGED
@@ -4541,6 +4541,35 @@ async function startRepl() {
4541
4541
  context.__mutable.add(m[1]);
4542
4542
  }
4543
4543
 
4544
+ // Fix REPL reassignment: when compiled code declares variables that
4545
+ // already exist in context, convert to reassignment to avoid TDZ errors.
4546
+ // e.g., "a, b = b, a" compiles to "const [a, b] = [b, a];" but b/a on
4547
+ // the RHS are in TDZ because they're excluded from context destructure.
4548
+ let replCode = code;
4549
+ // Array/tuple destructuring: const [a, b] = [...] → [a, b] = [...]
4550
+ replCode = replCode.replace(/^(const|let)\s+(\[[^\]]+\])\s*=/gm, (match, kw, targets) => {
4551
+ const names = targets.slice(1, -1).split(',').map(n => n.trim()).filter(Boolean);
4552
+ if (names.length > 0 && names.every(n => n in context)) {
4553
+ for (const n of names) {
4554
+ declaredInCode.delete(n);
4555
+ if (!context.__mutable) context.__mutable = new Set();
4556
+ context.__mutable.add(n);
4557
+ }
4558
+ return `${targets} =`;
4559
+ }
4560
+ return match;
4561
+ });
4562
+ // Single variable: const x = expr → x = expr (when x exists in context)
4563
+ replCode = replCode.replace(/^(const|let)\s+([a-zA-Z_]\w*)\s*=/gm, (match, kw, name) => {
4564
+ if (name in context) {
4565
+ declaredInCode.delete(name);
4566
+ if (!context.__mutable) context.__mutable = new Set();
4567
+ context.__mutable.add(name);
4568
+ return `${name} =`;
4569
+ }
4570
+ return match;
4571
+ });
4572
+
4544
4573
  // Save declared variables back to context for persistence across inputs
4545
4574
  const saveNewDecls = declaredInCode.size > 0
4546
4575
  ? [...declaredInCode].map(n => `if(typeof ${n}!=='undefined')__ctx.${n}=${n};`).join('\n')
@@ -4561,17 +4590,17 @@ async function startRepl() {
4561
4590
  (letKeys.length > 0 ? `let {${letKeys.join(',')}} = __ctx;\n` : '');
4562
4591
 
4563
4592
  // Try wrapping last expression statement as a return for value display
4564
- const lines = code.trim().split('\n');
4593
+ const lines = replCode.trim().split('\n');
4565
4594
  const lastLine = lines[lines.length - 1].trim();
4566
- let evalCode = code;
4595
+ let evalCode = replCode;
4567
4596
  // For simple assignments (const x = expr;), echo the assigned value
4568
4597
  const constAssignMatch = lastLine.match(/^(const|let)\s+([a-zA-Z_]\w*)\s*=\s*(.+);?$/);
4569
4598
  if (constAssignMatch) {
4570
4599
  const varName = constAssignMatch[2];
4571
4600
  if (allSave) {
4572
- evalCode = `${code}\n${allSave}\nreturn ${varName};`;
4601
+ evalCode = `${replCode}\n${allSave}\nreturn ${varName};`;
4573
4602
  } else {
4574
- evalCode = `${code}\nreturn ${varName};`;
4603
+ evalCode = `${replCode}\nreturn ${varName};`;
4575
4604
  }
4576
4605
  } else if (!/^(const |let |var |function |if |for |while |class |try |switch )/.test(lastLine) && !lastLine.endsWith('{')) {
4577
4606
  // Replace the last statement with a return
@@ -4585,7 +4614,7 @@ async function startRepl() {
4585
4614
  evalCode = allButLast + (allButLast ? '\n' : '') + `return (${returnExpr});`;
4586
4615
  }
4587
4616
  } else {
4588
- evalCode = code + (allSave ? '\n' + allSave : '');
4617
+ evalCode = replCode + (allSave ? '\n' + allSave : '');
4589
4618
  }
4590
4619
  try {
4591
4620
  const fn = new Function('__ctx', `${destructure}${evalCode}`);
@@ -4597,7 +4626,7 @@ async function startRepl() {
4597
4626
  }
4598
4627
  } catch (e) {
4599
4628
  // If return-wrapping fails, fall back to plain execution
4600
- const fallbackCode = code + (allSave ? '\n' + allSave : '');
4629
+ const fallbackCode = replCode + (allSave ? '\n' + allSave : '');
4601
4630
  const fn = new Function('__ctx', `${destructure}${fallbackCode}`);
4602
4631
  fn(context);
4603
4632
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tova",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Tova — a modern programming language that transpiles to JavaScript, unifying frontend and backend",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by scripts/embed-runtime.js — do not edit
2
- export const VERSION = "0.9.6";
2
+ export const VERSION = "0.9.7";