exec_program.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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. llvm::ListSeparator sep("\n\n");
  26. for (auto& declaration : ast.declarations) {
  27. set_file_ctx.update_source_loc(declaration->source_loc());
  28. if (trace_stream->is_enabled()) {
  29. *trace_stream << sep << *declaration;
  30. }
  31. }
  32. if (trace_stream->is_enabled()) {
  33. *trace_stream << "\n";
  34. }
  35. }
  36. SourceLocation source_loc("<Main()>", 0, FileKind::Main);
  37. ast.main_call = arena->New<CallExpression>(
  38. source_loc, arena->New<IdentifierExpression>(source_loc, "Main"),
  39. arena->New<TupleLiteral>(source_loc));
  40. // Although name resolution is currently done once, generic programming
  41. // (particularly templates) may require more passes.
  42. set_prog_phase.update_phase(ProgramPhase::NameResolution);
  43. if (trace_stream->is_enabled()) {
  44. trace_stream->Heading("resolving names");
  45. }
  46. CARBON_RETURN_IF_ERROR(ResolveNames(ast, trace_stream));
  47. set_prog_phase.update_phase(ProgramPhase::ControlFlowResolution);
  48. if (trace_stream->is_enabled()) {
  49. trace_stream->Heading("resolving control flow");
  50. }
  51. CARBON_RETURN_IF_ERROR(ResolveControlFlow(trace_stream, ast));
  52. set_prog_phase.update_phase(ProgramPhase::TypeChecking);
  53. if (trace_stream->is_enabled()) {
  54. trace_stream->Heading("type checking");
  55. }
  56. CARBON_RETURN_IF_ERROR(
  57. TypeChecker(arena, trace_stream, print_stream).TypeCheck(ast));
  58. set_prog_phase.update_phase(ProgramPhase::UnformedVariableResolution);
  59. if (trace_stream->is_enabled()) {
  60. trace_stream->Heading("resolving unformed variables");
  61. }
  62. CARBON_RETURN_IF_ERROR(ResolveUnformed(trace_stream, ast));
  63. set_prog_phase.update_phase(ProgramPhase::Declarations);
  64. if (trace_stream->is_enabled()) {
  65. trace_stream->Heading("printing declarations");
  66. llvm::ListSeparator sep("\n\n");
  67. for (auto& declaration : ast.declarations) {
  68. set_file_ctx.update_source_loc(declaration->source_loc());
  69. if (trace_stream->is_enabled()) {
  70. *trace_stream << sep << *declaration;
  71. }
  72. }
  73. if (trace_stream->is_enabled()) {
  74. *trace_stream << "\n";
  75. }
  76. }
  77. return ast;
  78. }
  79. auto ExecProgram(Nonnull<Arena*> arena, AST ast,
  80. Nonnull<TraceStream*> trace_stream,
  81. Nonnull<llvm::raw_ostream*> print_stream) -> ErrorOr<int> {
  82. SetProgramPhase set_program_phase(*trace_stream, ProgramPhase::Execution);
  83. if (trace_stream->is_enabled()) {
  84. trace_stream->Heading("starting execution");
  85. }
  86. CARBON_ASSIGN_OR_RETURN(
  87. auto interpreter_result,
  88. InterpProgram(ast, arena, trace_stream, print_stream));
  89. if (trace_stream->is_enabled()) {
  90. trace_stream->Result() << "interpreter result: " << interpreter_result
  91. << "\n";
  92. }
  93. return interpreter_result;
  94. }
  95. } // namespace Carbon