public CompileResult CompileProject(SourceProject project) { // Set active project this.m_currentProject = project; // Meta data generation this.m_thisLog = new(); this.m_externalBindables = new(); this.m_timer = Stopwatch.StartNew(); // Parse all files AST[] asts = new AST[this.m_currentProject.Sources.Length]; for (int i = 0; i < this.m_currentProject.Sources.Length; i++) { var parseResult = ParseFile(this.m_currentProject.Sources[i], out AST ast); if (!parseResult) { Log.WriteLine($"Failed to parse {this.m_currentProject.Sources[i].Name} :\n\t{"Some currently un-generated error!"}"); Log.WriteLine(); return(parseResult); } asts[i] = ast; } // Create the global domain and import external references Domain globalDomain = Domain.GetGlobalDomain(); var result = ImportReferences(globalDomain, this.m_currentProject); if (!result) { return(this.FatalError(result)); } // Detect types result = StaticTypeDetector.Detect(asts, globalDomain); if (!result) { return(this.FatalError(result)); } // Define types result = StaticTypeDefiner.DefineAllTypes(asts, globalDomain); if (!result) { return(this.FatalError(result)); } // Solve potential inheritance problems etc. result = InheritanceSolver.Solve(asts, globalDomain); if (!result) { return(this.FatalError(result)); } // TODO: Run static checks // Verify variables VarsVerifier vVerifier = new VarsVerifier(); for (int i = 0; i < asts.Length; i++) { result = vVerifier.Vars(asts[i]); if (!result) { return(this.FatalError(result)); } } // Verify control paths ControlpathVerifier pathVerifier = new ControlpathVerifier(); for (int i = 0; i < asts.Length; i++) { result = pathVerifier.Verify(asts[i]); if (!result) { return(this.FatalError(result)); } } // Run static typecheck Typechecker typechecker = new Typechecker(); for (int i = 0; i < asts.Length; i++) { result = typechecker.Typecheck(asts[i], globalDomain); if (!result) { return(this.FatalError(result)); } } // Compile Application ASTCompiler astCompiler = new ASTCompiler(asts); result = astCompiler.Compile(); if (!result) { return(this.FatalError(result)); } // Apply linking Linker linker = new Linker(astCompiler, globalDomain, this.m_externalBindables); result = linker.Link(); if (!result) { return(this.FatalError(result)); } // Stop timer this.m_timer.Stop(); // Get compile output ProgramOutput compilerOutput = this.GetCompileOutput(astCompiler, linker, globalDomain); // If successful compile, save, otherwise log error if (compilerOutput is not null) { compilerOutput.Save(project.Output); compilerOutput.SaveAsText(project.Output.Replace(".bin", ".txt").Replace(".hlib", ".txt")); Log.WriteLine($"Compiled \"{project.Name}\" successfully in {this.m_timer.ElapsedMilliseconds / 1000.0}s."); Log.WriteLine(); this.m_thisLog.SaveAndClose(project.Output.Replace(".bin", ".log").Replace(".hlib", ".log")); return(new CompileResult(true)); } else { Log.WriteLine($"Compile Error \"{project.Name}\" : {result}"); Log.WriteLine(); this.m_thisLog.SaveAndClose(project.Output.Replace(".bin", ".log").Replace(".hlib", ".log")); return(new CompileResult(false)); } }