Line data Source code
1 : #include "../../../../inc/parsingAnalysis/algorithm/topDown.h"
2 :
3 : namespace nicole {
4 :
5 : const std::expected<std::shared_ptr<AST_WHILE>, Error>
6 0 : TopDown::parseWhile() const noexcept {
7 0 : const auto firsToken{tkStream_.current()};
8 0 : if (auto res = tryEat(); !res) {
9 0 : return createError(res.error());
10 0 : }
11 0 : const std::expected<std::shared_ptr<AST_CONDITION>, Error> condition{
12 0 : parseCondition(false)};
13 0 : if (!condition || !*condition) {
14 0 : return createError(condition ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
15 0 : : condition.error());
16 0 : }
17 0 : const std::expected<std::shared_ptr<AST_BODY>, Error> body{parseBody()};
18 0 : if (!body || !*body) {
19 0 : return createError(body ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
20 0 : : body.error());
21 0 : }
22 0 : return Builder::createWhile(SourceLocation{*firsToken, *tkStream_.lastRead()},
23 0 : *condition, *body);
24 0 : }
25 :
26 : const std::expected<std::shared_ptr<AST_FOR>, Error>
27 0 : TopDown::parseFor() const noexcept {
28 0 : const auto firsToken{tkStream_.current()};
29 0 : if (auto res = tryEat(); !res) {
30 0 : return createError(res.error());
31 0 : }
32 0 : if (tkStream_.current()->type() != TokenType::LP) {
33 0 : return createError(ERROR_TYPE::SINTAX,
34 0 : "missing left parenthesis of for at " +
35 0 : tkStream_.current()->locInfo());
36 0 : }
37 0 : if (auto res = tryEat(); !res) {
38 0 : return createError(res.error());
39 0 : }
40 0 : if (tkStream_.current()->type() == TokenType::RP) {
41 0 : return createError(ERROR_TYPE::SINTAX,
42 0 : "empty for at " + tkStream_.current()->locInfo());
43 0 : }
44 0 : std::vector<std::shared_ptr<AST>> init{};
45 0 : while (tkStream_.currentPos() < tkStream_.size() and
46 0 : tkStream_.current()->type() != TokenType::SEMICOLON) {
47 0 : const std::expected<std::shared_ptr<AST>, Error> expression{
48 0 : parseVarDecl(true)};
49 0 : if (!expression || !*expression) {
50 0 : return createError(expression
51 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
52 0 : : expression.error());
53 0 : }
54 0 : init.push_back(*expression);
55 0 : if (tkStream_.current()->type() == TokenType::COMMA) {
56 0 : if (auto res = tryEat(); !res) {
57 0 : return createError(res.error());
58 0 : }
59 0 : continue;
60 0 : } else if (tkStream_.current()->type() != TokenType::SEMICOLON) {
61 0 : return createError(ERROR_TYPE::SINTAX,
62 0 : "missing comma or ; of FOR at " +
63 0 : tkStream_.current()->locInfo());
64 0 : }
65 0 : break;
66 0 : }
67 0 : if (tkStream_.current()->type() != TokenType::SEMICOLON) {
68 0 : return createError(ERROR_TYPE::SINTAX, "missing ; after init of for at " +
69 0 : tkStream_.current()->locInfo());
70 0 : }
71 0 : if (auto res = tryEat(); !res) {
72 0 : return createError(res.error());
73 0 : }
74 :
75 0 : const std::expected<std::shared_ptr<AST_CONDITION>, Error> condition{
76 0 : (tkStream_.current()->type() == TokenType::SEMICOLON)
77 0 : ? *Builder::createCondition(
78 0 : SourceLocation{*firsToken, *tkStream_.lastRead()},
79 0 : *Builder::createBool(
80 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, true))
81 0 : : parseCondition(true)};
82 0 : if (!condition || !*condition) {
83 0 : return createError(condition ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
84 0 : : condition.error());
85 0 : }
86 0 : if (tkStream_.current()->type() != TokenType::SEMICOLON) {
87 0 : return createError(ERROR_TYPE::SINTAX,
88 0 : "missing ; after condition of for at " +
89 0 : tkStream_.current()->locInfo());
90 0 : }
91 0 : if (auto res = tryEat(); !res) {
92 0 : return createError(res.error());
93 0 : }
94 0 : std::vector<std::shared_ptr<AST>> update{};
95 0 : while (tkStream_.currentPos() < tkStream_.size() and
96 0 : tkStream_.current()->type() != TokenType::RP) {
97 0 : const std::expected<std::shared_ptr<AST>, Error> expression{
98 0 : parseAssignment(true)};
99 0 : if (!expression || !*expression) {
100 0 : return createError(expression
101 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
102 0 : : expression.error());
103 0 : }
104 0 : update.push_back(*expression);
105 0 : if (tkStream_.current()->type() == TokenType::COMMA) {
106 0 : if (auto res = tryEat(); !res) {
107 0 : return createError(res.error());
108 0 : }
109 0 : continue;
110 0 : } else if (tkStream_.current()->type() != TokenType::RP) {
111 0 : return createError(ERROR_TYPE::SINTAX,
112 0 : "missing comma or ) of for at " +
113 0 : tkStream_.current()->locInfo());
114 0 : }
115 0 : break;
116 0 : }
117 0 : if (auto res = tryEat(); !res) {
118 0 : return createError(res.error());
119 0 : }
120 0 : const std::expected<std::shared_ptr<AST_BODY>, Error> body{parseBody()};
121 0 : if (!body || !*body) {
122 0 : return createError(body ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
123 0 : : body.error());
124 0 : }
125 0 : return Builder::createFor(SourceLocation{*firsToken, *tkStream_.lastRead()},
126 0 : init, *condition, update, *body);
127 0 : }
128 :
129 : const std::expected<std::shared_ptr<AST_DO_WHILE>, Error>
130 0 : TopDown::parseDoWhile() const noexcept {
131 0 : const auto firsToken{tkStream_.current()};
132 0 : if (auto res = tryEat(); !res) {
133 0 : return createError(res.error());
134 0 : }
135 0 : const std::expected<std::shared_ptr<AST_BODY>, Error> body{parseBody()};
136 0 : if (!body || !*body) {
137 0 : return createError(body ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
138 0 : : body.error());
139 0 : }
140 0 : if (tkStream_.current()->type() != TokenType::WHILE) {
141 0 : return createError(ERROR_TYPE::SINTAX,
142 0 : "missing while keyword of do while at " +
143 0 : tkStream_.current()->locInfo());
144 0 : }
145 0 : if (auto res = tryEat(); !res) {
146 0 : return createError(res.error());
147 0 : }
148 0 : const std::expected<std::shared_ptr<AST_CONDITION>, Error> condition{
149 0 : parseCondition(false)};
150 0 : if (!condition || !*condition) {
151 0 : return createError(condition ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
152 0 : : condition.error());
153 0 : }
154 0 : if (!tkStream_.current() or
155 0 : tkStream_.current()->type() != TokenType::SEMICOLON) {
156 0 : return createError(ERROR_TYPE::SINTAX,
157 0 : "missing ; of do while statement at " +
158 0 : (*tkStream_.lastRead()).locInfo());
159 0 : }
160 0 : return Builder::createDoWhile(
161 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, *body, *condition);
162 0 : }
163 :
164 : const std::expected<std::shared_ptr<AST_PASS>, Error>
165 0 : TopDown::parsePass() const noexcept {
166 0 : const auto firsToken{tkStream_.current()};
167 0 : if (auto res = tryEat(); !res) {
168 0 : return createError(res.error());
169 0 : }
170 0 : if (tkStream_.current()->type() != TokenType::SEMICOLON) {
171 0 : return createError(ERROR_TYPE::SINTAX, "missing ; of pass statement at " +
172 0 : tkStream_.current()->locInfo());
173 0 : }
174 0 : return Builder::createPass(SourceLocation{*firsToken, *tkStream_.lastRead()},
175 0 : nullptr);
176 0 : }
177 :
178 : const std::expected<std::shared_ptr<AST_STOP>, Error>
179 0 : TopDown::parseStop() const noexcept {
180 0 : const auto firsToken{tkStream_.current()};
181 0 : if (auto res = tryEat(); !res) {
182 0 : return createError(res.error());
183 0 : }
184 0 : if (tkStream_.current()->type() != TokenType::SEMICOLON) {
185 0 : return createError(ERROR_TYPE::SINTAX, "missing ; of stop statement at " +
186 0 : tkStream_.current()->locInfo());
187 0 : }
188 0 : return Builder::createStop(SourceLocation{*firsToken, *tkStream_.lastRead()},
189 0 : nullptr);
190 0 : }
191 :
192 : } // namespace nicole
|