What's wrong
CSharpGenerator (Coder/Languages/CSharpGenerator.cs ~line 894) writes const for every VariableDeclaration with IsConstant whose type isn't var, whatever its InitialValue is. C# only allows compile-time constants in a const local, so an expression, a parameter reference or a call produces code that doesn't compile.
Other generators get this right:
- The README describes a constant as one "with a literal InitialValue".
- Go already checks the initial value:
GoGenerator.IsCompileTimeValue (~line 1318) falls back to var with a note.
- C++, Rust, JS and C are unaffected, because their immutable bindings accept runtime values.
Repro
var f = new FunctionDeclaration("Twice") { ReturnType = "int", IsStatic = true };
f.Parameters.Add(new Parameter("n", "int"));
f.Body.Add(new VariableDeclaration("doubled", "int",
new BinaryExpression(new VariableReference("n"), BinaryOperator.Multiply, Literal.Number(2))) { IsConstant = true });
var call = new CallExpression("Math.Abs"); call.Arguments.Add(new VariableReference("doubled"));
f.Body.Add(new VariableDeclaration("size", "int", call) { IsConstant = true });
f.Body.Add(new ReturnStatement(new VariableReference("size")));
// placed inside a ClassDeclaration("Sample") and generated with CSharpGenerator
- Actual:
const int doubled = (n * 2); and const int size = Math.Abs(doubled);. dotnet build reports error CS0133: The expression being assigned to 'doubled' must be constant, and the same for size.
- Expected:
int doubled = (n * 2); and int size = Math.Abs(doubled);. C# has no readonly locals, which is also how the generator already handles an inferred (var) constant.
Suggested fix
Write const only when the initial value is a compile-time value. Moving Go's IsCompileTimeValue into LanguageGeneratorBase would let both generators share the same rule. Add a test that compiles the output with a non-literal constant.
What's wrong
CSharpGenerator(Coder/Languages/CSharpGenerator.cs~line 894) writesconstfor everyVariableDeclarationwithIsConstantwhose type isn'tvar, whatever itsInitialValueis. C# only allows compile-time constants in aconstlocal, so an expression, a parameter reference or a call produces code that doesn't compile.Other generators get this right:
GoGenerator.IsCompileTimeValue(~line 1318) falls back tovarwith a note.Repro
const int doubled = (n * 2);andconst int size = Math.Abs(doubled);.dotnet buildreportserror CS0133: The expression being assigned to 'doubled' must be constant, and the same forsize.int doubled = (n * 2);andint size = Math.Abs(doubled);. C# has no readonly locals, which is also how the generator already handles an inferred (var) constant.Suggested fix
Write
constonly when the initial value is a compile-time value. Moving Go'sIsCompileTimeValueintoLanguageGeneratorBasewould let both generators share the same rule. Add a test that compiles the output with a non-literal constant.