Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <gyoji-frontend.hpp> | ||
2 | #include <gyoji-misc/input-source-file.hpp> | ||
3 | #include <gyoji-analysis.hpp> | ||
4 | #include <gyoji-codegen.hpp> | ||
5 | |||
6 | using namespace Gyoji::codegen; | ||
7 | using namespace Gyoji::context; | ||
8 | using namespace Gyoji::frontend; | ||
9 | using namespace Gyoji::mir; | ||
10 | using namespace Gyoji::analysis; | ||
11 | |||
12 | 30 | int main(int argc, char **argv) | |
13 | { | ||
14 | |||
15 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
|
30 | if (argc != 3) { |
16 | ✗ | fprintf(stderr, "Invalid number of arguments %d\n", argc); | |
17 | ✗ | fprintf(stderr, "Usage: jcc source-file object-file\n"); | |
18 | ✗ | exit(1); | |
19 | } | ||
20 | |||
21 | 30 | int input = open(argv[1], O_RDONLY); | |
22 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
|
30 | if (input == -1) { |
23 | ✗ | fprintf(stderr, "Cannot open file %s\n", argv[1]); | |
24 | ✗ | exit(1); | |
25 | } | ||
26 | 60 | std::string input_filename(argv[1]); | |
27 | 30 | std::string output_filename(argv[2]); | |
28 | |||
29 | 30 | CompilerContext context(input_filename); | |
30 | 30 | Gyoji::misc::InputSourceFile input_source(input); | |
31 | |||
32 | Gyoji::owned<MIR> mir = | ||
33 | Parser::parse_to_mir( | ||
34 | context, | ||
35 | input_source | ||
36 | 30 | ); | |
37 | 30 | close(input); | |
38 | |||
39 | // Dump our MIR | ||
40 | // for debugging/review purposes | ||
41 | // before any analysis or code-generation | ||
42 | // passes. | ||
43 | { | ||
44 | 30 | std::string mir_filename = output_filename + std::string(".mir"); | |
45 | 30 | FILE *mir_output = fopen(mir_filename.c_str(), "w"); | |
46 | 30 | mir->dump(mir_output); | |
47 | 30 | fclose(mir_output); | |
48 | 30 | } | |
49 | |||
50 | // If we had errors at the MIR construction | ||
51 | // phase, it is likely we'll have an unsuitable | ||
52 | // MIR for analysis, so don't bother. | ||
53 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
|
30 | if (context.has_errors()) { |
54 | ✗ | context.get_errors().print(); | |
55 | ✗ | return -1; | |
56 | } | ||
57 | |||
58 | // Make sure that all types that are used in functions | ||
59 | // actually have 'complete' definitions. | ||
60 | 30 | std::vector<Gyoji::owned<AnalysisPass>> analysis_passes; | |
61 | |||
62 | 30 | analysis_passes.push_back(std::make_unique<AnalysisPassTypeResolution>(context)); | |
63 | 30 | analysis_passes.push_back(std::make_unique<AnalysisPassUnreachable>(context)); | |
64 | 30 | analysis_passes.push_back(std::make_unique<AnalysisPassBorrowChecker>(context)); | |
65 | |||
66 | |||
67 |
2/2✓ Branch 5 taken 90 times.
✓ Branch 6 taken 30 times.
|
120 | for (const auto & analysis_pass : analysis_passes) { |
68 | 90 | fprintf(stderr, "============================\n"); | |
69 | 90 | fprintf(stderr, "Analysis pass %s\n", analysis_pass->get_name().c_str()); | |
70 | 90 | fprintf(stderr, "============================\n"); | |
71 | 90 | analysis_pass->check(*mir); | |
72 | } | ||
73 | |||
74 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
|
30 | if (context.has_errors()) { |
75 | ✗ | context.get_errors().print(); | |
76 | ✗ | return -1; | |
77 | } | ||
78 | |||
79 | 30 | fprintf(stderr, "============================\n"); | |
80 | 30 | fprintf(stderr, "Code Generation Pass\n"); | |
81 | 30 | fprintf(stderr, "============================\n"); | |
82 | // This leaks memory. The code-generation | ||
83 | // stage is a bit problematic | ||
84 | // because we're not really cleaning up the | ||
85 | // LLVM stuff at the moment. | ||
86 | 30 | generate_code(context, *mir, output_filename); | |
87 | |||
88 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
|
30 | if (context.has_errors()) { |
89 | ✗ | context.get_errors().print(); | |
90 | ✗ | return -1; | |
91 | } | ||
92 | 30 | return 0; | |
93 | 30 | } | |
94 |