Line data Source code
1 : #include "../../../inc/visitors/validateTree/validateTree.h"
2 : #include "../../../inc/parsingAnalysis/ast/loops/ast_doWhile.h"
3 : #include "../../../inc/parsingAnalysis/ast/loops/ast_for.h"
4 : #include "../../../inc/parsingAnalysis/ast/loops/ast_pass.h"
5 : #include "../../../inc/parsingAnalysis/ast/loops/ast_stop.h"
6 : #include "../../../inc/parsingAnalysis/ast/loops/ast_while.h"
7 : #include "../../../inc/parsingAnalysis/checkPosition.h"
8 :
9 : namespace nicole {
10 :
11 : // statement / body / not null
12 : std::expected<bool, Error>
13 0 : ValidateTree::visit(const AST_WHILE *node) const noexcept {
14 0 : if (!node) {
15 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_WHILE");
16 0 : }
17 0 : if (!CheckPosition::itsBodyAncestorHasParent(node)) {
18 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
19 0 : "a while loop must appear in a scope");
20 0 : }
21 0 : const auto condition{node->condition()->accept(*this)};
22 0 : if (!condition) {
23 0 : return createError(condition.error());
24 0 : }
25 0 : const auto result{node->body()->accept(*this)};
26 0 : if (!result) {
27 0 : return createError(result.error());
28 0 : }
29 0 : return true;
30 0 : }
31 :
32 : // statement / body / not null
33 : std::expected<bool, Error>
34 0 : ValidateTree::visit(const AST_FOR *node) const noexcept {
35 0 : if (!node) {
36 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_FOR");
37 0 : }
38 0 : if (!CheckPosition::itsBodyAncestorHasParent(node)) {
39 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
40 0 : "a for loop must appear in a scope");
41 0 : }
42 0 : for (const auto &expr : node->init()) {
43 0 : const auto result{expr->accept(*this)};
44 0 : if (!result) {
45 0 : return createError(result.error());
46 0 : }
47 0 : }
48 0 : const auto condition{node->condition()->accept(*this)};
49 0 : if (!condition) {
50 0 : return createError(condition.error());
51 0 : }
52 0 : for (const auto &expr : node->update()) {
53 0 : const auto result{expr->accept(*this)};
54 0 : if (!result) {
55 0 : return createError(result.error());
56 0 : }
57 0 : }
58 0 : const auto result{node->body()->accept(*this)};
59 0 : if (!result) {
60 0 : return createError(result.error());
61 0 : }
62 0 : return true;
63 0 : }
64 :
65 : // statement / body / not null
66 : std::expected<bool, Error>
67 0 : ValidateTree::visit(const AST_DO_WHILE *node) const noexcept {
68 0 : if (!node) {
69 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_DO_WHILE");
70 0 : }
71 0 : if (!CheckPosition::itsBodyAncestorHasParent(node)) {
72 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
73 0 : "a do while loop must appear in a scope");
74 0 : }
75 0 : const auto result{node->body()->accept(*this)};
76 0 : if (!result) {
77 0 : return createError(result.error());
78 0 : }
79 0 : const auto condition{node->condition()->accept(*this)};
80 0 : if (!condition) {
81 0 : return createError(condition.error());
82 0 : }
83 0 : return true;
84 0 : }
85 :
86 : // do while / while / for
87 : std::expected<bool, Error>
88 0 : ValidateTree::visit(const AST_PASS *node) const noexcept {
89 0 : if (!node) {
90 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_PASS");
91 0 : }
92 0 : if (!CheckPosition::hasAnyAncestorOf(
93 0 : node, {AST_TYPE::DO_WHILE, AST_TYPE::FOR, AST_TYPE::WHILE})) {
94 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
95 0 : "a pass statement must appear inside a loop");
96 0 : }
97 0 : return true;
98 0 : }
99 :
100 : // do while / while / for
101 : std::expected<bool, Error>
102 0 : ValidateTree::visit(const AST_STOP *node) const noexcept {
103 0 : if (!node) {
104 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_STOP");
105 0 : }
106 0 : if (!CheckPosition::hasAnyAncestorOf(node,
107 0 : {AST_TYPE::DO_WHILE, AST_TYPE::FOR,
108 0 : AST_TYPE::WHILE, AST_TYPE::SWITCH})) {
109 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
110 0 : "a stop statement must appear inside a loop");
111 0 : }
112 0 : return true;
113 0 : }
114 :
115 : }
|