Source/DafnyDriver/DafnyDriver.cs
/// <summary>
/// Generate a C# program from the Dafny program and, if "invokeCsCompiler" is "true", invoke
/// the C# compiler to compile it.
/// </summary>
Generate a C# program from the Dafny program and, if "invokeCsCompiler" is "true", invoke
the C# compiler to compile it.
Generate a C# program from the Dafny program and if " invokeCsCompiler " is " true " invoke the C# compiler to compile it .
public static bool CompileDafnyProgram(Dafny.Program dafnyProgram, string dafnyProgramName,
                                           ReadOnlyCollection<string> otherFileNames, bool invokeCsCompiler,
                                           TextWriter outputWriter = null)
    {
      Contract.Requires(dafnyProgram != null);
      if (outputWriter == null)
      {
        outputWriter = Console.Out;
      }
      StringWriter sw = new StringWriter();
      var oldErrorCount = dafnyProgram.reporter.Count(ErrorLevel.Error);
      Dafny.Compiler compiler = new Dafny.Compiler(dafnyProgram.reporter);
      var hasMain = compiler.HasMain(dafnyProgram);
      compiler.Compile(dafnyProgram, sw);
      var csharpProgram = sw.ToString();
      bool completeProgram = dafnyProgram.reporter.Count(ErrorLevel.Error) == oldErrorCount;
      string targetFilename = null;
      if (DafnyOptions.O.SpillTargetCode > 0 || otherFileNames.Count > 0)
      {
        targetFilename = WriteDafnyProgramToFile(dafnyProgramName, csharpProgram, completeProgram, outputWriter);
      }
      if (!completeProgram || !invokeCsCompiler)
      {
        return false;
      }
      else if (!CodeDomProvider.IsDefinedLanguage("CSharp"))
      {
        outputWriter.WriteLine("Error: cannot compile, because there is no provider configured for input language CSharp");
        return false;
      }
      else
      {
        var provider = CodeDomProvider.CreateProvider("CSharp", new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
        var cp = new System.CodeDom.Compiler.CompilerParameters();
        cp.GenerateExecutable = hasMain;
        if (DafnyOptions.O.RunAfterCompile) {
          cp.GenerateInMemory = true;
        } else if (hasMain) {
          cp.OutputAssembly = Path.ChangeExtension(dafnyProgramName, "exe");
          cp.GenerateInMemory = false;
        } else {
          cp.OutputAssembly = Path.ChangeExtension(dafnyProgramName, "dll");
          cp.GenerateInMemory = false;
        }
        cp.CompilerOptions = "/debug /nowarn:0164 /nowarn:0219 /nowarn:1717 /nowarn:0162";  
        cp.ReferencedAssemblies.Add("System.Numerics.dll");
        cp.ReferencedAssemblies.Add("System.Core.dll");
        cp.ReferencedAssemblies.Add("System.dll");
        var libPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar;
        if (DafnyOptions.O.UseRuntimeLib) {
          cp.ReferencedAssemblies.Add(libPath + "DafnyRuntime.dll");
        }
        var immutableDllFileName = "System.Collections.Immutable.dll";
        var immutableDllPath = libPath + immutableDllFileName;
        if (DafnyOptions.O.Optimize) {
          cp.CompilerOptions += " /optimize /define:DAFNY_USE_SYSTEM_COLLECTIONS_IMMUTABLE";
          cp.ReferencedAssemblies.Add(immutableDllPath);
          cp.ReferencedAssemblies.Add("System.Runtime.dll");
        }
        int numOtherSourceFiles = 0;
        if (otherFileNames.Count > 0) {
          foreach (var file in otherFileNames) {
            string extension = Path.GetExtension(file);
            if (extension != null) { extension = extension.ToLower(); }
            if (extension == ".cs") {
              numOtherSourceFiles++;
            }
            else if (extension == ".dll") {
              cp.ReferencedAssemblies.Add(file);
            }
          }
        }
        CompilerResults cr;
        if (numOtherSourceFiles > 0) {
          string[] sourceFiles = new string[numOtherSourceFiles + 1];
          sourceFiles[0] = targetFilename;
          int index = 1;
          foreach (var file in otherFileNames) {
            string extension = Path.GetExtension(file);
            if (extension != null) { extension = extension.ToLower(); }
            if (extension == ".cs") {
              sourceFiles[index++] = file;
            }
          }
          cr = provider.CompileAssemblyFromFile(cp, sourceFiles);
        }
        else {
          cr = provider.CompileAssemblyFromSource(cp, csharpProgram);
        }
        if (DafnyOptions.O.RunAfterCompile && !hasMain) {
          return cr.Errors.Count == 0 ? true : false;
        }
        var assemblyName = Path.GetFileName(cr.PathToAssembly);
        if (DafnyOptions.O.RunAfterCompile && cr.Errors.Count == 0) {
          outputWriter.WriteLine("Program compiled successfully");
          outputWriter.WriteLine("Running...");
          outputWriter.WriteLine();
          var entry = cr.CompiledAssembly.EntryPoint;
          try {
            object[] parameters = entry.GetParameters().Length == 0 ? new object[] { } : new object[] { new string[0] };
            entry.Invoke(null, parameters);
          } catch (System.Reflection.TargetInvocationException e) {
            outputWriter.WriteLine("Error: Execution resulted in exception: {0}", e.Message);
            outputWriter.WriteLine(e.InnerException.ToString());
          } catch (Exception e) {
            outputWriter.WriteLine("Error: Execution resulted in exception: {0}", e.Message);
            outputWriter.WriteLine(e.ToString());
          }
        } else if (cr.Errors.Count == 0) {
          outputWriter.WriteLine("Compiled assembly into {0}", assemblyName);
          if (DafnyOptions.O.Optimize) {
            var outputDir = Path.GetDirectoryName(dafnyProgramName);
            if (string.IsNullOrWhiteSpace(outputDir)) {
              outputDir = ".";
            }
            var destPath = outputDir + Path.DirectorySeparatorChar + immutableDllFileName;
            File.Copy(immutableDllPath, destPath, true);
            outputWriter.WriteLine("Copied /optimize dependency {0} to {1}", immutableDllFileName, outputDir);
          }
        } else {
          outputWriter.WriteLine("Errors compiling program into {0}", assemblyName);
          foreach (var ce in cr.Errors) {
            outputWriter.WriteLine(ce.ToString());
            outputWriter.WriteLine();
          }
          return false;
        }
        return true;
      }
    }
public static bool CompileDafnyProgram ( Dafny . Program dafnyProgram , string dafnyProgramName , ReadOnlyCollection < string > otherFileNames , bool invokeCsCompiler , TextWriter outputWriter = null ) { Contract . Requires ( dafnyProgram != null ) ; if ( outputWriter == null ) { outputWriter = Console . Out ; } StringWriter sw = new StringWriter ( ) ; var oldErrorCount = dafnyProgram . reporter . Count ( ErrorLevel . Error ) ; Dafny . Compiler compiler = new Dafny . Compiler ( dafnyProgram . reporter ) ; var hasMain = compiler . HasMain ( dafnyProgram ) ; compiler . Compile ( dafnyProgram , sw ) ; var csharpProgram = sw . ToString ( ) ; bool completeProgram = dafnyProgram . reporter . Count ( ErrorLevel . Error ) == oldErrorCount ; string targetFilename = null ; if ( DafnyOptions . O . SpillTargetCode > 0 || otherFileNames . Count > 0 ) { targetFilename = WriteDafnyProgramToFile ( dafnyProgramName , csharpProgram , completeProgram , outputWriter ) ; } if ( ! completeProgram || ! invokeCsCompiler ) { return false ; } else if ( ! CodeDomProvider . IsDefinedLanguage ( " " ) ) { outputWriter . WriteLine ( " " ) ; return false ; } else { var provider = CodeDomProvider . CreateProvider ( " " , new Dictionary < string , string > { { " " , " " } } ) ; var cp = new System . CodeDom . Compiler . CompilerParameters ( ) ; cp . GenerateExecutable = hasMain ; if ( DafnyOptions . O . RunAfterCompile ) { cp . GenerateInMemory = true ; } else if ( hasMain ) { cp . OutputAssembly = Path . ChangeExtension ( dafnyProgramName , " " ) ; cp . GenerateInMemory = false ; } else { cp . OutputAssembly = Path . ChangeExtension ( dafnyProgramName , " " ) ; cp . GenerateInMemory = false ; } cp . CompilerOptions = " " ; cp . ReferencedAssemblies . Add ( " " ) ; cp . ReferencedAssemblies . Add ( " " ) ; cp . ReferencedAssemblies . Add ( " " ) ; var libPath = Path . GetDirectoryName ( Assembly . GetExecutingAssembly ( ) . Location ) + Path . DirectorySeparatorChar ; if ( DafnyOptions . O . UseRuntimeLib ) { cp . ReferencedAssemblies . Add ( libPath + " " ) ; } var immutableDllFileName = " " ; var immutableDllPath = libPath + immutableDllFileName ; if ( DafnyOptions . O . Optimize ) { cp . CompilerOptions += " " ; cp . ReferencedAssemblies . Add ( immutableDllPath ) ; cp . ReferencedAssemblies . Add ( " " ) ; } int numOtherSourceFiles = 0 ; if ( otherFileNames . Count > 0 ) { foreach ( var file in otherFileNames ) { string extension = Path . GetExtension ( file ) ; if ( extension != null ) { extension = extension . ToLower ( ) ; } if ( extension == " " ) { numOtherSourceFiles ++ ; } else if ( extension == " " ) { cp . ReferencedAssemblies . Add ( file ) ; } } } CompilerResults cr ; if ( numOtherSourceFiles > 0 ) { string [ ] sourceFiles = new string [ numOtherSourceFiles + 1 ] ; sourceFiles [ 0 ] = targetFilename ; int index = 1 ; foreach ( var file in otherFileNames ) { string extension = Path . GetExtension ( file ) ; if ( extension != null ) { extension = extension . ToLower ( ) ; } if ( extension == " " ) { sourceFiles [ index ++ ] = file ; } } cr = provider . CompileAssemblyFromFile ( cp , sourceFiles ) ; } else { cr = provider . CompileAssemblyFromSource ( cp , csharpProgram ) ; } if ( DafnyOptions . O . RunAfterCompile && ! hasMain ) { return cr . Errors . Count == 0 ? true : false ; } var assemblyName = Path . GetFileName ( cr . PathToAssembly ) ; if ( DafnyOptions . O . RunAfterCompile && cr . Errors . Count == 0 ) { outputWriter . WriteLine ( " " ) ; outputWriter . WriteLine ( " " ) ; outputWriter . WriteLine ( ) ; var entry = cr . CompiledAssembly . EntryPoint ; try { object [ ] parameters = entry . GetParameters ( ) . Length == 0 ? new object [ ] { } : new object [ ] { new string [ 0 ] } ; entry . Invoke ( null , parameters ) ; } catch ( System . Reflection . TargetInvocationException e ) { outputWriter . WriteLine ( " " , e . Message ) ; outputWriter . WriteLine ( e . InnerException . ToString ( ) ) ; } catch ( Exception e ) { outputWriter . WriteLine ( " " , e . Message ) ; outputWriter . WriteLine ( e . ToString ( ) ) ; } } else if ( cr . Errors . Count == 0 ) { outputWriter . WriteLine ( " " , assemblyName ) ; if ( DafnyOptions . O . Optimize ) { var outputDir = Path . GetDirectoryName ( dafnyProgramName ) ; if ( string . IsNullOrWhiteSpace ( outputDir ) ) { outputDir = " " ; } var destPath = outputDir + Path . DirectorySeparatorChar + immutableDllFileName ; File . Copy ( immutableDllPath , destPath , true ) ; outputWriter . WriteLine ( " " , immutableDllFileName , outputDir ) ; } } else { outputWriter . WriteLine ( " " , assemblyName ) ; foreach ( var ce in cr . Errors ) { outputWriter . WriteLine ( ce . ToString ( ) ) ; outputWriter . WriteLine ( ) ; } return false ; } return true ; } }
Generate a C# program from the Dafny program and, if "invokeCsCompiler" is "true", invoke
the C# compiler to compile it.
Generate a C# program from the Dafny program and if " invokeCsCompiler " is " true " invoke the C# compiler to compile it .
// Compile the Dafny program into a string that contains the C# program // blurt out the code to a file, if requested, or if other files were specified for the C# command line. // compile the program into an assembly // don't compile // warning CS0164 complains about unreferenced labels, CS0219 is about unused variables, CS1717 is about assignments of a variable to itself, CS0162 is about unreachable code // do no more
dafnyProgram
Dafny.Program
dafnyProgramName
string
otherFileNames
ReadOnlyCollection<string>
invokeCsCompiler
bool
outputWriter
TextWriter