exec_program.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "explorer/interpreter/exec_program.h"
  5. #include <variant>
  6. #include "common/check.h"
  7. #include "common/error.h"
  8. #include "common/ostream.h"
  9. #include "explorer/base/arena.h"
  10. #include "explorer/base/trace_stream.h"
  11. #include "explorer/interpreter/interpreter.h"
  12. #include "explorer/interpreter/resolve_control_flow.h"
  13. #include "explorer/interpreter/resolve_names.h"
  14. #include "explorer/interpreter/resolve_unformed.h"
  15. #include "explorer/interpreter/type_checker.h"
  16. #include "llvm/Support/Error.h"
  17. namespace Carbon {
  18. auto AnalyzeProgram(Nonnull<Arena*> arena, AST ast,
  19. Nonnull<TraceStream*> trace_stream,
  20. Nonnull<llvm::raw_ostream*> print_stream) -> ErrorOr<AST> {
  21. SetProgramPhase set_prog_phase(*trace_stream, ProgramPhase::SourceProgram);
  22. SetFileContext set_file_ctx(*trace_stream, std::nullopt);
  23. if (trace_stream->is_enabled()) {
  24. trace_stream->Heading("source program");
  25. for (auto& declaration : ast.declarations) {
  26. set_file_ctx.update_source_loc(declaration->source_loc());
  27. if (trace_stream->is_enabled()) {
  28. *trace_stream << *declaration;
  29. }
  30. }
  31. }
  32. SourceLocation source_loc("<Main()>", 0, FileKind::Main);
  33. ast.main_call = arena->New<CallExpression>(
  34. source_loc, arena->New<IdentifierExpression>(source_loc, "Main"),
  35. arena->New<TupleLiteral>(source_loc));
  36. // Although name resolution is currently done once, generic programming
  37. // (particularly templates) may require more passes.
  38. set_prog_phase.update_phase(ProgramPhase::NameResolution);
  39. if (trace_stream->is_enabled()) {
  40. trace_stream->Heading("resolving names");
  41. }
  42. CARBON_RETURN_IF_ERROR(ResolveNames(ast, trace_stream));
  43. set_prog_phase.update_phase(ProgramPhase::ControlFlowResolution);
  44. if (trace_stream->is_enabled()) {
  45. trace_stream->Heading("resolving control flow");
  46. }
  47. CARBON_RETURN_IF_ERROR(ResolveControlFlow(trace_stream, ast));
  48. set_prog_phase.update_phase(ProgramPhase::TypeChecking);
  49. if (trace_stream->is_enabled()) {
  50. trace_stream->Heading("type checking");
  51. }
  52. CARBON_RETURN_IF_ERROR(
  53. TypeChecker(arena, trace_stream, print_stream).TypeCheck(ast));
  54. set_prog_phase.update_phase(ProgramPhase::UnformedVariableResolution);
  55. if (trace_stream->is_enabled()) {
  56. trace_stream->Heading("resolving unformed variables");
  57. }
  58. CARBON_RETURN_IF_ERROR(ResolveUnformed(trace_stream, ast));
  59. set_prog_phase.update_phase(ProgramPhase::Declarations);
  60. if (trace_stream->is_enabled()) {
  61. trace_stream->Heading("printing declarations");
  62. for (auto& declaration : ast.declarations) {
  63. set_file_ctx.update_source_loc(declaration->source_loc());
  64. if (trace_stream->is_enabled()) {
  65. *trace_stream << *declaration;
  66. }
  67. }
  68. }
  69. return ast;
  70. }
  71. auto ExecProgram(Nonnull<Arena*> arena, AST ast,
  72. Nonnull<TraceStream*> trace_stream,
  73. Nonnull<llvm::raw_ostream*> print_stream) -> ErrorOr<int> {
  74. SetProgramPhase set_program_phase(*trace_stream, ProgramPhase::Execution);
  75. if (trace_stream->is_enabled()) {
  76. trace_stream->Heading("starting execution");
  77. }
  78. CARBON_ASSIGN_OR_RETURN(
  79. auto interpreter_result,
  80. InterpProgram(ast, arena, trace_stream, print_stream));
  81. if (trace_stream->is_enabled()) {
  82. trace_stream->Result() << "interpreter result: " << interpreter_result
  83. << "\n";
  84. }
  85. return interpreter_result;
  86. }
  87. } // namespace Carbon