/// <summary> /// Generate a C# program from the Dafny program and, if "invokeCompiler" is "true", invoke /// the C# compiler to compile it. /// </summary> public static bool CompileDafnyProgram(Microsoft.Armada.Program dafnyProgram, string dafnyProgramName, ReadOnlyCollection <string> otherFileNames, bool invokeCompiler, TextWriter outputWriter = null) { Contract.Requires(dafnyProgram != null); Contract.Assert(dafnyProgramName != null); Console.WriteLine("Running CompileDafnyProgram : {0}", dafnyProgramName); Console.WriteLine("Number of modules = {0}", dafnyProgram.CompileModules.Count); if (outputWriter == null) { outputWriter = Console.Out; } // Compile the Dafny program into a string that contains the target program var oldErrorCount = dafnyProgram.reporter.Count(ErrorLevel.Error); Microsoft.Armada.Compiler compiler; switch (ArmadaOptions.O.CompileTarget) { case ArmadaOptions.CompilationTarget.Clight: default: compiler = new Microsoft.Armada.ClightTsoCompiler(dafnyProgram.reporter, otherFileNames); break; } Method mainMethod; var hasMain = compiler.HasMain(dafnyProgram, out mainMethod); string targetProgramText; var otherFiles = new Dictionary <string, string>(); { var fileQueue = new Queue <FileTargetWriter>(); using (var wr = new TargetWriter(0)) { compiler.Compile(dafnyProgram, wr); var sw = new StringWriter(); wr.Collect(sw, fileQueue); targetProgramText = sw.ToString(); } while (fileQueue.Count > 0) { var wr = fileQueue.Dequeue(); var sw = new StringWriter(); wr.Collect(sw, fileQueue); otherFiles.Add(wr.Filename, sw.ToString()); } } string baseName = Path.GetFileNameWithoutExtension(dafnyProgramName); string callToMain = null; if (hasMain) { using (var wr = new TargetWriter(0)) { compiler.EmitCallToMain(mainMethod, wr); callToMain = wr.ToString(); // assume there aren't multiple files just to call main } } bool completeProgram = dafnyProgram.reporter.Count(ErrorLevel.Error) == oldErrorCount; // blurt out the code to a file, if requested, or if other files were specified for the C# command line. string targetFilename = null; if (ArmadaOptions.O.SpillTargetCode > 0 || otherFileNames.Count > 0 || (invokeCompiler && !compiler.SupportsInMemoryCompilation)) { var p = callToMain == null ? targetProgramText : targetProgramText + callToMain; targetFilename = WriteDafnyProgramToFiles(dafnyProgramName, p, completeProgram, otherFiles, outputWriter); } // compile the program into an assembly if (!completeProgram || !invokeCompiler) { // don't compile // Caller interprets this as success/fail and returns an error if false, // but we didn't actually hit an error, we just didn't invoke the compiler return(true); } // compile the program into an assembly object compilationResult; var compiledCorrectly = compiler.CompileTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, hasMain, hasMain && ArmadaOptions.O.RunAfterCompile, outputWriter, out compilationResult); if (compiledCorrectly && ArmadaOptions.O.RunAfterCompile) { if (hasMain) { if (ArmadaOptions.O.CompileVerbose) { outputWriter.WriteLine("Running..."); outputWriter.WriteLine(); } compiledCorrectly = compiler.RunTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, compilationResult, outputWriter); } else { // make sure to give some feedback to the user if (ArmadaOptions.O.CompileVerbose) { outputWriter.WriteLine("Program compiled successfully"); } } } return(compiledCorrectly); }
/// <summary> /// Generate a C# program from the Dafny program and, if "invokeCompiler" is "true", invoke /// the C# compiler to compile it. /// </summary> public static bool CompileDafnyProgram(Dafny.Program dafnyProgram, string dafnyProgramName, ReadOnlyCollection <string> otherFileNames, bool invokeCompiler, TextWriter outputWriter = null) { Contract.Requires(dafnyProgram != null); Contract.Assert(dafnyProgramName != null); if (outputWriter == null) { outputWriter = Console.Out; } // Compile the Dafny program into a string that contains the target program var oldErrorCount = dafnyProgram.reporter.Count(ErrorLevel.Error); Dafny.Compiler compiler; switch (DafnyOptions.O.CompileTarget) { case DafnyOptions.CompilationTarget.Csharp: default: compiler = new Dafny.CsharpCompiler(dafnyProgram.reporter); break; case DafnyOptions.CompilationTarget.JavaScript: compiler = new Dafny.JavaScriptCompiler(dafnyProgram.reporter); break; case DafnyOptions.CompilationTarget.Go: compiler = new Dafny.GoCompiler(dafnyProgram.reporter); break; case DafnyOptions.CompilationTarget.Java: compiler = new Dafny.JavaCompiler(dafnyProgram.reporter); break; case DafnyOptions.CompilationTarget.Cpp: compiler = new Dafny.CppCompiler(dafnyProgram.reporter, otherFileNames); break; } var hasMain = compiler.HasMain(dafnyProgram, out var mainMethod); if (hasMain) { mainMethod.IsEntryPoint = true; dafnyProgram.MainMethod = mainMethod; } string targetProgramText; var otherFiles = new Dictionary <string, string>(); { var fileQueue = new Queue <FileTargetWriter>(); using (var wr = new TargetWriter(0)) { compiler.Compile(dafnyProgram, wr); var sw = new StringWriter(); wr.Collect(sw, fileQueue); targetProgramText = sw.ToString(); } while (fileQueue.Count > 0) { var wr = fileQueue.Dequeue(); var sw = new StringWriter(); wr.Collect(sw, fileQueue); otherFiles.Add(wr.Filename, sw.ToString()); } } string callToMain = null; if (hasMain) { using (var wr = new TargetWriter(0)) { string baseName = Path.GetFileNameWithoutExtension(dafnyProgramName); compiler.EmitCallToMain(mainMethod, baseName, wr); callToMain = wr.ToString(); // assume there aren't multiple files just to call main } } Contract.Assert(hasMain == (callToMain != null)); bool targetProgramHasErrors = dafnyProgram.reporter.Count(ErrorLevel.Error) != oldErrorCount; compiler.Coverage.WriteLegendFile(); // blurt out the code to a file, if requested, or if other target-language files were specified on the command line. string targetFilename = null; if (DafnyOptions.O.SpillTargetCode > 0 || otherFileNames.Count > 0 || (invokeCompiler && !compiler.SupportsInMemoryCompilation) || (invokeCompiler && compiler.TextualTargetIsExecutable && !DafnyOptions.O.RunAfterCompile)) { targetFilename = WriteDafnyProgramToFiles(compiler, dafnyProgramName, targetProgramHasErrors, targetProgramText, callToMain, otherFiles, outputWriter); } if (targetProgramHasErrors) { return(false); } // If we got here, compilation succeeded if (!invokeCompiler) { return(true); // If we're not asked to invoke the target compiler, we can report success } // compile the program into an assembly object compilationResult; var compiledCorrectly = compiler.CompileTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, hasMain && DafnyOptions.O.RunAfterCompile, outputWriter, out compilationResult); if (compiledCorrectly && DafnyOptions.O.RunAfterCompile) { if (hasMain) { if (DafnyOptions.O.CompileVerbose) { outputWriter.WriteLine("Running..."); outputWriter.WriteLine(); } compiledCorrectly = compiler.RunTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, compilationResult, outputWriter); } else { // make sure to give some feedback to the user if (DafnyOptions.O.CompileVerbose) { outputWriter.WriteLine("Program compiled successfully"); } } } return(compiledCorrectly); }
/// <summary> /// Generate a C# program from the Dafny program and, if "invokeCompiler" is "true", invoke /// the C# compiler to compile it. /// </summary> public static bool CompileDafnyProgram(Dafny.Program dafnyProgram, string dafnyProgramName, ReadOnlyCollection <string> otherFileNames, bool invokeCompiler, TextWriter outputWriter = null) { Contract.Requires(dafnyProgram != null); Contract.Assert(dafnyProgramName != null); if (outputWriter == null) { outputWriter = Console.Out; } // Compile the Dafny program into a string that contains the target program var oldErrorCount = dafnyProgram.reporter.Count(ErrorLevel.Error); Dafny.Compiler compiler; switch (DafnyOptions.O.CompileTarget) { case DafnyOptions.CompilationTarget.Csharp: default: compiler = new Dafny.CsharpCompiler(dafnyProgram.reporter); break; case DafnyOptions.CompilationTarget.JavaScript: compiler = new Dafny.JavaScriptCompiler(dafnyProgram.reporter); break; case DafnyOptions.CompilationTarget.Go: compiler = new Dafny.GoCompiler(dafnyProgram.reporter); break; case DafnyOptions.CompilationTarget.Java: compiler = new Dafny.JavaCompiler(dafnyProgram.reporter); break; } Method mainMethod; var hasMain = compiler.HasMain(dafnyProgram, out mainMethod); string targetProgramText; var otherFiles = new Dictionary <string, string>(); { var fileQueue = new Queue <FileTargetWriter>(); using (var wr = new TargetWriter(0)) { compiler.Compile(dafnyProgram, wr); var sw = new StringWriter(); wr.Collect(sw, fileQueue); targetProgramText = sw.ToString(); } while (fileQueue.Count > 0) { var wr = fileQueue.Dequeue(); var sw = new StringWriter(); wr.Collect(sw, fileQueue); otherFiles.Add(wr.Filename, sw.ToString()); } } string baseName = Path.GetFileNameWithoutExtension(dafnyProgramName); string callToMain = null; if (hasMain) { using (var wr = new TargetWriter(0)) { if (DafnyOptions.O.CompileTarget is DafnyOptions.CompilationTarget.Java) { dafnyProgramName = dafnyProgramName.Replace('-', '_'); wr.WriteLine($"public class {baseName.Replace('-', '_')} {{"); } compiler.EmitCallToMain(mainMethod, wr); if (DafnyOptions.O.CompileTarget is DafnyOptions.CompilationTarget.Java) { wr.WriteLine("}"); } callToMain = wr.ToString(); // assume there aren't multiple files just to call main } } bool completeProgram = dafnyProgram.reporter.Count(ErrorLevel.Error) == oldErrorCount; // blurt out the code to a file, if requested, or if other files were specified for the C# command line. string targetFilename = null; if (DafnyOptions.O.SpillTargetCode > 0 || otherFileNames.Count > 0 || (invokeCompiler && !compiler.SupportsInMemoryCompilation)) { var p = callToMain == null ? targetProgramText : targetProgramText + callToMain; if (DafnyOptions.O.CompileTarget is DafnyOptions.CompilationTarget.Java && callToMain == null) { p = null; } targetFilename = WriteDafnyProgramToFiles(dafnyProgramName, p, completeProgram, otherFiles, outputWriter); } if (DafnyOptions.O.CompileTarget is DafnyOptions.CompilationTarget.Java) { string targetBaseDir = baseName; string targetDir = Path.Combine(Path.GetDirectoryName(dafnyProgramName), targetBaseDir); var assemblyLocation = System.Reflection.Assembly.GetExecutingAssembly().Location; Contract.Assert(assemblyLocation != null); var codebase = System.IO.Path.GetDirectoryName(assemblyLocation); Contract.Assert(codebase != null); string dest = targetDir + "/dafny"; Directory.CreateDirectory(dest); var jcompiler = (JavaCompiler)compiler; jcompiler.CompileTuples(dest); jcompiler.CreateFunctionInterface(dest); jcompiler.CompileDafnyArrays(dest); jcompiler.CompileArrayInits(dest); } if (!completeProgram) { return(false); } // If we got until here, compilation to C# succeeded if (!invokeCompiler) { return(true); // If we're not asked to invoke the C# to assembly compiler, we can report success } // compile the program into an assembly object compilationResult; var compiledCorrectly = compiler.CompileTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, hasMain, hasMain && DafnyOptions.O.RunAfterCompile, outputWriter, out compilationResult); if (compiledCorrectly && DafnyOptions.O.RunAfterCompile) { if (hasMain) { if (DafnyOptions.O.CompileVerbose) { outputWriter.WriteLine("Running..."); outputWriter.WriteLine(); } compiledCorrectly = compiler.RunTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, compilationResult, outputWriter); } else { // make sure to give some feedback to the user if (DafnyOptions.O.CompileVerbose) { outputWriter.WriteLine("Program compiled successfully"); } } } return(compiledCorrectly); }
/// <summary> /// Generate a C# program from the Dafny program and, if "invokeCompiler" is "true", invoke /// the C# compiler to compile it. /// </summary> public static bool CompileDafnyProgram(Dafny.Program dafnyProgram, string dafnyProgramName, ReadOnlyCollection <string> otherFileNames, bool invokeCompiler, TextWriter outputWriter = null) { Contract.Requires(dafnyProgram != null); Contract.Assert(dafnyProgramName != null); if (outputWriter == null) { outputWriter = Console.Out; } bool runRequiresSpill = false; // Compile the Dafny program into a string that contains the target program var oldErrorCount = dafnyProgram.reporter.Count(ErrorLevel.Error); Dafny.Compiler compiler; switch (DafnyOptions.O.CompileTarget) { case DafnyOptions.CompilationTarget.Csharp: default: compiler = new Dafny.CsharpCompiler(dafnyProgram.reporter); break; case DafnyOptions.CompilationTarget.JavaScript: compiler = new Dafny.JavaScriptCompiler(dafnyProgram.reporter); break; case DafnyOptions.CompilationTarget.Go: compiler = new Dafny.GoCompiler(dafnyProgram.reporter); runRequiresSpill = true; break; } Method mainMethod; var hasMain = compiler.HasMain(dafnyProgram, out mainMethod); string targetProgramText; var otherFiles = new Dictionary <string, string>(); { var fileQueue = new Queue <FileTargetWriter>(); using (var wr = new TargetWriter(0)) { compiler.Compile(dafnyProgram, wr); var sw = new StringWriter(); wr.Collect(sw, fileQueue); targetProgramText = sw.ToString(); } while (fileQueue.Count > 0) { var wr = fileQueue.Dequeue(); var sw = new StringWriter(); wr.Collect(sw, fileQueue); otherFiles.Add(wr.Filename, sw.ToString()); } } string callToMain = null; if (hasMain) { using (var wr = new TargetWriter(0)) { compiler.EmitCallToMain(mainMethod, wr); callToMain = wr.ToString(); // assume there aren't multiple files just to call main } } bool completeProgram = dafnyProgram.reporter.Count(ErrorLevel.Error) == oldErrorCount; // blurt out the code to a file, if requested, or if other files were specified for the C# command line. string targetFilename = null; if (DafnyOptions.O.SpillTargetCode > 0 || otherFileNames.Count > 0 || (runRequiresSpill && DafnyOptions.O.RunAfterCompile)) { var p = callToMain == null ? targetProgramText : targetProgramText + callToMain; targetFilename = WriteDafnyProgramToFiles(dafnyProgramName, p, completeProgram, otherFiles, outputWriter); } // compile the program into an assembly if (!completeProgram || !invokeCompiler) { // don't compile return(false); } object compilationResult; var compiledCorrectly = compiler.CompileTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, hasMain, hasMain && DafnyOptions.O.RunAfterCompile, outputWriter, out compilationResult); if (compiledCorrectly && DafnyOptions.O.RunAfterCompile) { if (hasMain) { if (DafnyOptions.O.CompileVerbose) { outputWriter.WriteLine("Running..."); outputWriter.WriteLine(); } compiledCorrectly = compiler.RunTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, compilationResult, outputWriter); } else { // make sure to give some feedback to the user if (DafnyOptions.O.CompileVerbose) { outputWriter.WriteLine("Program compiled successfully"); } } } return(compiledCorrectly); }