Line data Source code
1 : #include "../../inc/compiler/nicole.h"
2 : #include <memory>
3 :
4 : namespace nicole {
5 :
6 : std::expected<std::monostate, Error>
7 0 : Nicole::compile(const Options &options) const noexcept {
8 0 : const nicole::TopDown topDown{sintax_};
9 :
10 0 : const std::expected<std::shared_ptr<nicole::Tree>, nicole::Error> tree{
11 0 : topDown.parse(options.entryFilePath())};
12 :
13 0 : if (!tree) {
14 0 : return createError(tree.error());
15 0 : }
16 :
17 0 : std::cout << "Finished parsing\n";
18 :
19 0 : if (options.validateTree()) {
20 0 : const nicole::ValidateTree validateTree{};
21 0 : const std::expected<bool, nicole::Error> validated{
22 0 : validateTree.validate((*tree).get())};
23 :
24 0 : if (!validated) {
25 0 : return createError(validated.error());
26 0 : }
27 0 : std::cout << "Finished validate\n";
28 0 : }
29 :
30 0 : if (options.printTree()) {
31 0 : const nicole::PrintTree printTree{};
32 0 : const std::expected<std::string, nicole::Error> toStr{
33 0 : printTree.print((*tree).get())};
34 0 : if (!toStr) {
35 0 : return createError(toStr.error());
36 0 : }
37 0 : std::cout << "|--------------------------------|\n";
38 0 : std::cout << *toStr << "\n";
39 0 : std::cout << "Finished print tree\n";
40 0 : std::cout << "|--------------------------------|\n";
41 0 : }
42 :
43 0 : std::shared_ptr<nicole::TypeTable> typeTable{
44 0 : std::make_shared<nicole::TypeTable>()};
45 0 : std::shared_ptr<nicole::FunctionTable> functionTable{
46 0 : std::make_shared<nicole::FunctionTable>()};
47 0 : const nicole::FillSemanticInfo semanticFiller{functionTable, typeTable,
48 0 : options};
49 0 : const auto isTablesFilled{semanticFiller.fill((*tree).get())};
50 0 : if (!isTablesFilled) {
51 0 : return createError(isTablesFilled.error());
52 0 : }
53 :
54 0 : std::cout << "Finished semantic analysis\n";
55 :
56 0 : if (options.printTree()) {
57 0 : const nicole::PrintTree printTree{};
58 0 : const std::expected<std::string, nicole::Error> toStr{
59 0 : printTree.print((*tree).get())};
60 0 : if (!toStr) {
61 0 : return createError(toStr.error());
62 0 : }
63 0 : std::cout << "|--------------------------------|\n";
64 0 : std::cout << *toStr << "\n";
65 0 : std::cout << "Finished print tree\n";
66 0 : std::cout << "|--------------------------------|\n";
67 0 : }
68 :
69 0 : const nicole::TypeAnalysis typeAnalysis{functionTable, typeTable};
70 0 : const auto analyzed{typeAnalysis.analyze((*tree).get())};
71 0 : if (!analyzed) {
72 0 : return createError(analyzed.error());
73 0 : }
74 :
75 0 : std::cout << "Finished type analysis\n";
76 :
77 0 : const nicole::Monomorphize monomorphizer{functionTable, typeTable};
78 0 : const auto monomorphized{monomorphizer.transform((*tree).get())};
79 0 : if (!monomorphized) {
80 0 : return createError(monomorphized.error());
81 0 : }
82 :
83 0 : std::cout << "Finished monomorphization\n";
84 :
85 0 : const auto analyzedSecondTime{typeAnalysis.analyze((*tree).get())};
86 0 : if (!analyzedSecondTime) {
87 0 : return createError(analyzedSecondTime.error());
88 0 : }
89 :
90 0 : const nicole::CodeGeneration codeGenerator{functionTable, typeTable};
91 0 : const auto generatedIR{codeGenerator.generate((*tree).get())};
92 0 : if (!generatedIR) {
93 0 : return createError(generatedIR.error());
94 0 : }
95 :
96 0 : return {};
97 0 : }
98 :
99 : } // namespace nicole
|