Skip to content

Commit 8f94821

Browse files
kubeclaude
andcommitted
FE-514: Reject var declarations and standalone expressions in SymPy compiler
Only const is allowed — both let and var are now rejected. Standalone expression statements (not assigned or returned) produce a diagnostic. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 980a2ce commit 8f94821

2 files changed

Lines changed: 37 additions & 4 deletions

File tree

libs/@hashintel/petrinaut/src/simulation/simulator/compile-to-sympy.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,19 @@ describe("compileToSymPy", () => {
726726
}
727727
});
728728

729+
it("should reject var declarations", () => {
730+
const code = `export default Lambda(() => {
731+
var x = 1;
732+
return x;
733+
})`;
734+
const result = compileToSymPy(code, defaultContext);
735+
expect(result.ok).toBe(false);
736+
if (!result.ok) {
737+
expect(result.error).toContain("var");
738+
expect(result.error).toContain("use 'const'");
739+
}
740+
});
741+
729742
it("should reject string literals with position", () => {
730743
const code = `export default Lambda(() => "hello")`;
731744
const result = compileToSymPy(code, defaultContext);
@@ -748,6 +761,23 @@ describe("compileToSymPy", () => {
748761
}
749762
});
750763

764+
it("should reject standalone expression statements", () => {
765+
const code = `export default Lambda((tokensByPlace, parameters) => {
766+
const a = Boolean(1 + 2);
767+
Boolean(1 + 2);
768+
return Boolean(1 + 2);
769+
})`;
770+
const result = compileToSymPy(code, defaultContext);
771+
expect(result.ok).toBe(false);
772+
if (!result.ok) {
773+
expect(result.error).toContain("Standalone expression has no effect");
774+
// The standalone expression is the second line in the block
775+
const standalonePos = code.indexOf("\n Boolean(1 + 2);") + 11;
776+
expect(result.start).toBe(standalonePos);
777+
expect(result.length).toBe("Boolean(1 + 2);".length);
778+
}
779+
});
780+
751781
it("should reject unsupported binary operator with position", () => {
752782
const code = `export default Lambda(() => 1 << 2)`;
753783
const result = compileToSymPy(code, defaultContext);

libs/@hashintel/petrinaut/src/simulation/simulator/compile-to-sympy.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ function compileBlock(
226226
sourceFile,
227227
);
228228
}
229-
if (stmt.declarationList.flags & ts.NodeFlags.Let) {
229+
if (!(stmt.declarationList.flags & ts.NodeFlags.Const)) {
230230
return err(
231-
"'let' declarations are not supported, use 'const'",
231+
"'let' and 'var' declarations are not supported, use 'const'",
232232
stmt,
233233
sourceFile,
234234
);
@@ -259,8 +259,11 @@ function compileBlock(
259259
if (!result.ok) return result;
260260
lines.push(result.sympyCode);
261261
} else if (ts.isExpressionStatement(stmt)) {
262-
// Allow comments parsed as expression statements, skip them
263-
continue;
262+
return err(
263+
"Standalone expression has no effect — assign to a const or return it",
264+
stmt,
265+
sourceFile,
266+
);
264267
} else {
265268
return err(
266269
`Unsupported statement: ${ts.SyntaxKind[stmt.kind]}`,

0 commit comments

Comments
 (0)