Line data Source code
1 : #include "../../../inc/visitors/fillSemanticInfo/fillSemanticInfo.h"
2 : #include "../../../inc/parsingAnalysis/ast/tree.h"
3 : #include <cstddef>
4 : #include <memory>
5 : #include <variant>
6 :
7 : /**
8 :
9 : FillSemanticInfo ---> insertar delcaraciones en las tablas / insertar tipos /
10 : comprobar que las variables pertenecen al scope (llamadas a variables) /
11 : comrpobar llamadas a enum
12 :
13 : TypeAnalysis ---> comprobar en una llamada a funcion que esta existe debido a
14 : sobrecarga de funciones requiere que se trate en el typeAnalysis / igual con
15 : metodos / llamadas a atributos / variables auto
16 :
17 : */
18 :
19 : namespace nicole {
20 :
21 0 : void FillSemanticInfo::pushScope() const noexcept {
22 0 : auto newScope = std::make_shared<Scope>(currentScope_);
23 0 : currentScope_ = newScope;
24 0 : if (!firstScope_) {
25 0 : firstScope_ = currentScope_;
26 0 : }
27 0 : }
28 :
29 0 : void FillSemanticInfo::popScope() const noexcept {
30 0 : if (currentScope_) {
31 0 : currentScope_ = currentScope_->father();
32 0 : }
33 0 : }
34 :
35 : std::expected<std::vector<GenericParameter>, Error>
36 : FillSemanticInfo::mergeGenericLists(
37 : const std::vector<GenericParameter> &list,
38 0 : const std::vector<GenericParameter> &list1) const noexcept {
39 0 : if (hasDuplicatedGenerics(list)) {
40 0 : return createError(ERROR_TYPE::TYPE, "has duplicated generics");
41 0 : }
42 0 : if (hasDuplicatedGenerics(list1)) {
43 0 : return createError(ERROR_TYPE::TYPE, "has duplicated generics");
44 0 : }
45 0 : std::vector<GenericParameter> result{};
46 0 : result.insert(result.end(), list.begin(), list.end());
47 0 : result.insert(result.end(), list1.begin(), list1.end());
48 0 : if (hasDuplicatedGenerics(result)) {
49 0 : return createError(ERROR_TYPE::TYPE, "has duplicated generics");
50 0 : }
51 0 : return result;
52 0 : }
53 :
54 : bool FillSemanticInfo::hasDuplicatedGenerics(
55 0 : const std::vector<GenericParameter> &list) const noexcept {
56 0 : std::unordered_set<GenericParameter> set(list.begin(), list.end());
57 0 : return set.size() != list.size();
58 0 : }
59 :
60 : bool FillSemanticInfo::areAmbiguousFunctions(
61 0 : const Function &first, const Function &second) const noexcept {
62 0 : if (first.id() != second.id()) {
63 0 : return false;
64 0 : }
65 0 : if (first.generics().size() != second.generics().size()) {
66 0 : return false;
67 0 : }
68 0 : if (first.params().size() != second.params().size()) {
69 0 : return false;
70 0 : }
71 0 : const auto parameters = first.params().params();
72 0 : const auto parametersOther = second.params().params();
73 0 : for (size_t i = 0; i < parameters.size(); ++i) {
74 0 : if (!typeTable_->areSameType(parameters[i].second,
75 0 : parametersOther[i].second)) {
76 0 : if (!(typeTable_->isGenericType(parameters[i].second, first.generics()) &&
77 0 : typeTable_->isGenericType(parametersOther[i].second,
78 0 : second.generics()))) {
79 0 : return false;
80 0 : }
81 0 : }
82 0 : }
83 0 : return true;
84 0 : }
85 :
86 : bool FillSemanticInfo::areAmbiguousMethods(
87 0 : const Method &first, const Method &second) const noexcept {
88 0 : if (first.id() != second.id()) {
89 0 : return false;
90 0 : }
91 0 : if (first.generics().size() != second.generics().size()) {
92 0 : return false;
93 0 : }
94 0 : if (first.params().size() != second.params().size()) {
95 0 : return false;
96 0 : }
97 0 : const auto parameters = first.params().params();
98 0 : const auto parametersOther = second.params().params();
99 0 : for (size_t i = 0; i < parameters.size(); ++i) {
100 0 : if (!typeTable_->areSameType(parameters[i].second,
101 0 : parametersOther[i].second)) {
102 0 : if (!(typeTable_->isGenericType(parameters[i].second, first.generics()) &&
103 0 : typeTable_->isGenericType(parametersOther[i].second,
104 0 : second.generics()))) {
105 0 : return false;
106 0 : }
107 0 : }
108 0 : }
109 0 : return true;
110 0 : }
111 :
112 : std::expected<std::monostate, Error>
113 0 : FillSemanticInfo::visit(const AST_STATEMENT *node) const noexcept {
114 0 : if (!node) {
115 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_STATEMENT");
116 0 : }
117 0 : return node->expression()->accept(*this);
118 0 : }
119 :
120 : std::expected<std::monostate, Error>
121 0 : FillSemanticInfo::visit(const AST_BODY *node) const noexcept {
122 0 : if (!node) {
123 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_BODY");
124 0 : }
125 0 : for (const auto &expr : node->body()) {
126 0 : const auto result{expr->accept(*this)};
127 0 : if (!result) {
128 0 : return createError(result.error());
129 0 : }
130 0 : }
131 0 : return {};
132 0 : }
133 :
134 : std::expected<std::monostate, Error>
135 0 : FillSemanticInfo::visit(const Tree *tree) const noexcept {
136 0 : if (!tree) {
137 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid Tree");
138 0 : }
139 0 : pushScope();
140 0 : tree->root()->setScope(currentScope_);
141 0 : const auto result{tree->root()->accept(*this)};
142 0 : if (!result) {
143 0 : return createError(result.error());
144 0 : }
145 0 : popScope();
146 0 : if (options_.validateTree()) {
147 0 : const auto mainFunction{functionTable_->getFunctions("main")};
148 0 : if (mainFunction.empty() or mainFunction.size() > 1) {
149 0 : return createError(ERROR_TYPE::FUNCTION,
150 0 : "if the validation is activated the user must "
151 0 : "specifiy a main function and only one instance");
152 0 : }
153 0 : if (mainFunction[0].returnType()->toString() !=
154 0 : BasicType{BasicKind::Int}.toString()) {
155 0 : return createError(ERROR_TYPE::FUNCTION,
156 0 : "if the validation is activated the user must "
157 0 : "specifiy a main function and only one instance of it "
158 0 : "that returns type int");
159 0 : }
160 0 : }
161 0 : return {};
162 0 : }
163 :
164 : } // namespace nicole
|