public CompilationUnitSyntax Parse(PackageSyntax package, SourceText sourceText) { // TODO make use of the package. We don't currently use the package, but we // are taking it as an argument becuase we should be for things like: // * Language Version // * Dependency Names // * Defined Preprocessor Symbols var builder = new ParseDiagnosticsBuilder(sourceText); var parser = sourceText.NewParser(); // Stupid ANTLR makes it difficult to do this in the constructor parser.RemoveErrorListeners(); var errorsListener = new GatherErrorsListener(builder); parser.AddErrorListener(errorsListener); parser.Interpreter.PredictionMode = PredictionMode.LlExactAmbigDetection; var tree = parser.compilationUnit(); var syntaxCheck = new SyntaxCheckVisitor(builder); tree.Accept(syntaxCheck); var diagnostics = builder.Complete(); if(diagnostics.Any()) return new CompilationUnitSyntax(sourceText, Enumerable.Empty<UsingSyntax>(), Enumerable.Empty<DeclarationSyntax>(), diagnostics); var compilationUnitBuilder = new CompilationUnitBuilder(sourceText, diagnostics); return tree.Accept(compilationUnitBuilder); }
public void Test(TestCaseConfig config, TextReader reader) { var dependencies = config.Runtime ? new[] { runtimeDependency } : Enumerable.Empty<PackageReferenceSyntax>(); var package = new PackageSyntax($"Adamant.Exploratory.Compiler.Tests.{config.TestName}", true, dependencies); var unit = compiler.Parse(package, new SourceReader(config.FileName, reader)); package = package.With(new[] { unit }); if(package.Diagnostics.Count > 0) Assert.Fail(ToString(package.Diagnostics)); var compiledPackage = compiler.Compile(package, Enumerable.Empty<Package>()); if(compiledPackage.Diagnostics.Count > 0) Assert.Fail(ToString(compiledPackage.Diagnostics)); var cppSource = compiler.EmitCpp(compiledPackage); var cppSourceName = compiledPackage.Name + ".cpp"; CreateFile(cppSourceName, cppSource); CreateFile(CppRuntime.FileName, CppRuntime.Source); var targetPath = Path.Combine(WorkPath, compiledPackage.Name + ".exe"); var result = CppCompiler.Invoke(Path.Combine(WorkPath, cppSourceName), targetPath); if(result.ExitCode != 0) { result.WriteOutputToConsole(); Assert.Fail("C++ compiler error"); } // Execute the app using(var process = new Process()) { process.StartInfo.FileName = targetPath; process.StartInfo.WorkingDirectory = Path.GetDirectoryName(WorkPath); process.StartInfo.CreateNoWindow = true; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; var outputBuffer = new StringBuilder(); var errorBuffer = new StringBuilder(); process.OutputDataReceived += (s, e) => outputBuffer.AppendLine(e.Data); process.ErrorDataReceived += (s, e) => errorBuffer.AppendLine(e.Data); process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); if(config.Result != null) Assert.AreEqual(config.Result, process.ExitCode, "Exit Code"); if(config.VerifyConsoleOutput) Assert.AreEqual(config.ExpectedConsoleOutput, outputBuffer.ToString()); } }
private static void PrintDiagnostics(PackageSyntax package) { ISourceText file = null; foreach(var diagnostic in package.Diagnostics) { if(file != diagnostic.File) { file = diagnostic.File; Console.WriteLine($"In {file.Name}"); } var level = diagnostic.Level.ToString(); var line = diagnostic.Position.Line + 1; var column = diagnostic.Position.Column + 1; Console.WriteLine($"{level} on line {line} at character {column}: "); Console.WriteLine($" {diagnostic.Message}"); } }
public void Test(TestCaseConfig config, TextReader reader) { var dependencies = config.Runtime ? new[] { runtimeDependency } : Enumerable.Empty<PackageReferenceSyntax>(); var package = new PackageSyntax($"Adamant.Exploratory.Compiler.Tests.{config.TestName}", true, dependencies); var unit = compiler.Parse(package, new SourceReader(config.FileName, reader)); package = package.With(new[] { unit }); if(package.Diagnostics.Count > 0) Assert.Fail(ToString(package.Diagnostics)); var compiledPackage = compiler.Compile(package, Enumerable.Empty<Package>()); if(compiledPackage.Diagnostics.Count > 0) Assert.Fail(ToString(compiledPackage.Diagnostics)); var interpreter = new AdamantInterpreter(compiledPackage); var entryPoint = compiledPackage.EntryPoints.Single(); var outputBuffer = new StringBuilder(); var errorBuffer = new StringBuilder(); var exitCode = interpreter.Invoke(entryPoint, new string[0], new StringWriter(outputBuffer), new StringWriter(errorBuffer)); Assert.AreEqual(config.Result, exitCode, "Exit Code"); if(config.VerifyConsoleOutput) Assert.AreEqual(config.ExpectedConsoleOutput, outputBuffer.ToString()); }
private void CompileProject(string projectDirPath, ProjectConfig projectConfig, CompiledProjects projects) { Console.WriteLine($"Compiling {projectConfig.Name} ..."); var sourceFiles = new DirectoryInfo(Path.Combine(projectDirPath, "src")).GetFiles("*.adam", SearchOption.AllDirectories); var isApp = projectConfig.Template == "app"; // TODO read trusted from config var package = new PackageSyntax(projectConfig.Name, isApp, projectConfig.Dependencies.Select(d => new PackageReferenceSyntax(d.Key, null, true))); package = package.With(sourceFiles.Select(fileInfo => compiler.Parse(package, new SourceFile(fileInfo)))); if(package.Diagnostics.Count > 0) { PrintDiagnostics(package); return; } var compiledPackage = compiler.Compile(package, projects.Select(p => p.Package)); var compiledProject = new CompiledProject(projectDirPath, compiledPackage); projects.Add(compiledProject); OnProjectCompiled(compiledProject, projects); }
public PackageSemanticsBuilder(PackageSyntax packageSyntax, IEnumerable<Package> packages) { this.packageSyntax = packageSyntax; this.packages = packages.ToList(); }
public Package Compile(PackageSyntax package, IEnumerable<Package> compiledPackages) { return new PackageSemanticsBuilder(package, compiledPackages).Build(); }