diff --git a/Source/DafnyCore/Compilers/Python/Compiler-python.cs b/Source/DafnyCore/Compilers/Python/Compiler-python.cs index 4c9718b0990..f65db3d367f 100644 --- a/Source/DafnyCore/Compilers/Python/Compiler-python.cs +++ b/Source/DafnyCore/Compilers/Python/Compiler-python.cs @@ -57,6 +57,10 @@ string FormatDefaultTypeParameterValue(TopLevelDecl tp) { protected override string True { get => "True"; } protected override string False { get => "False"; } protected override string Conj { get => "and"; } + private static readonly IEnumerable Keywords = new HashSet { "False", "None", "True", "and", "as" + , "assert", "async", "await", "break", "class", "continue", "def", "del", "enum", "elif", "else", "except" + , "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "nonlocal", "not", "or", "pass" + , "raise", "return", "try", "while", "with", "yield" }; protected override void EmitHeader(Program program, ConcreteSyntaxTree wr) { wr.WriteLine($"# Dafny program {program.Name} compiled into Python"); if (Options.IncludeRuntime) { @@ -122,53 +126,15 @@ private void EmitImports(string moduleName, ConcreteSyntaxTree wr) { protected override string GetHelperModuleName() => DafnyRuntimeModule; private static string MangleName(string name) { - switch (name) { - case "False": - case "None": - case "True": - case "and": - case "as": - case "assert": - case "async": - case "await": - case "break": - case "class": - case "continue": - case "def": - case "del": - case "enum": - case "elif": - case "else": - case "except": - case "finally": - case "for": - case "from": - case "global": - case "if": - case "import": - case "in": - case "is": - case "lambda": - case "nonlocal": - case "not": - case "or": - case "pass": - case "raise": - case "return": - case "try": - case "while": - case "with": - case "yield": - name = $"{name}_"; - break; - default: - while (name.StartsWith("_")) { - name = $"{name[1..]}_"; - } - if (name.Length > 0 && char.IsDigit(name[0])) { - name = $"d_{name}"; - } - break; + if (Keywords.Contains(name)) { + name = $"{name}_"; + } else { + while (name.StartsWith("_")) { + name = $"{name[1..]}_"; + } + if (name.Length > 0 && char.IsDigit(name[0])) { + name = $"d_{name}"; + } } return name; } @@ -262,7 +228,7 @@ protected override IClassWriter DeclareDatatype(DatatypeDecl dt, ConcreteSyntaxT return null; } - var DtT = dt.GetCompileName(Options); + var DtT = IdProtect(dt.GetCompileName(Options)); var baseClasses = dt.ParentTypeInformation.UniqueParentTraits().Any() ? $"({dt.ParentTypeInformation.UniqueParentTraits().Comma(trait => TypeName(trait, wr, dt.tok))})" diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-4830.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-4830.dfy new file mode 100644 index 00000000000..9171d3bd42b --- /dev/null +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-4830.dfy @@ -0,0 +1,3 @@ +// RUN: %testDafnyForEachCompiler "%s" + +datatype None = None diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-4830.dfy.expect b/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-4830.dfy.expect new file mode 100644 index 00000000000..e69de29bb2d diff --git a/docs/dev/news/4843.fix b/docs/dev/news/4843.fix new file mode 100644 index 00000000000..be55b74964a --- /dev/null +++ b/docs/dev/news/4843.fix @@ -0,0 +1 @@ +The Python compiler emits reserved names for datatypes