Line data Source code
1 : #include "../../../inc/parsingAnalysis/ast/functions/ast_funcCall.h"
2 : #include "../../../inc/parsingAnalysis/ast/functions/ast_funcDecl.h"
3 : #include "../../../inc/parsingAnalysis/ast/functions/ast_return.h"
4 : #include "../../../inc/visitors/fillSemanticInfo/fillSemanticInfo.h"
5 : #include <memory>
6 : #include <variant>
7 :
8 : namespace nicole {
9 :
10 : std::expected<std::monostate, Error>
11 0 : FillSemanticInfo::visit(const AST_FUNC_CALL *node) const noexcept {
12 0 : if (!node)
13 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_FUNC_CALL");
14 :
15 0 : if (functionTable_->getFunctions(node->id()).empty()) {
16 0 : return createError(ERROR_TYPE::FUNCTION,
17 0 : "no function with id: " + node->id() + " exists");
18 0 : }
19 :
20 0 : for (std::size_t i = 0; i < node->replaceOfGenerics().size(); ++i) {
21 0 : auto replacement = node->replaceOfGenerics()[i];
22 0 : if (!typeTable_->isPossibleType(replacement) &&
23 0 : !typeTable_->isGenericType(replacement, currentGenericList_)) {
24 0 : return createError(ERROR_TYPE::TYPE,
25 0 : replacement->toString() +
26 0 : " is not a possible type or generic");
27 0 : }
28 :
29 0 : if (auto maskedEnum = typeTable_->isCompundEnumType(replacement)) {
30 0 : replacement = *maskedEnum;
31 0 : auto setRes = node->setGenericReplacement(i, replacement);
32 0 : if (!setRes)
33 0 : return createError(setRes.error());
34 0 : }
35 :
36 0 : if (auto maskedGeneric = typeTable_->isCompundGenericType(
37 0 : replacement, currentGenericList_)) {
38 0 : replacement = *maskedGeneric;
39 0 : auto setRes = node->setGenericReplacement(i, replacement);
40 0 : if (!setRes)
41 0 : return createError(setRes.error());
42 0 : }
43 0 : }
44 :
45 0 : for (const auto &expr : node->parameters()) {
46 0 : const auto result = expr->accept(*this);
47 0 : if (!result)
48 0 : return createError(result.error());
49 0 : }
50 0 : return {};
51 0 : }
52 :
53 : std::expected<std::monostate, Error>
54 0 : FillSemanticInfo::visit(const AST_FUNC_DECL *node) const noexcept {
55 0 : if (!node)
56 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_FUNC_DECL");
57 0 : const Function newFunction{node->id(), node->generics(), node->parameters(),
58 0 : node->returnType(), node->body()};
59 :
60 0 : const auto functions = functionTable_->getFunctions(newFunction.id());
61 0 : for (const auto &func : functions) {
62 0 : if (areAmbiguousFunctions(newFunction, func)) {
63 0 : return createError(ERROR_TYPE::FUNCTION,
64 0 : "redeclaration of function: " + newFunction.id());
65 0 : }
66 0 : }
67 0 : functionTable_->insert(newFunction);
68 :
69 0 : pushScope();
70 0 : node->body()->setScope(currentScope_);
71 :
72 0 : currentGenericList_ = node->generics();
73 0 : if (hasDuplicatedGenerics(currentGenericList_)) {
74 0 : return createError(ERROR_TYPE::FUNCTION, "has duplicated generics");
75 0 : }
76 0 : node->setGenerics(currentGenericList_);
77 :
78 0 : std::vector<std::pair<std::string, std::shared_ptr<nicole::Type>>>
79 0 : newParameters;
80 0 : for (const auto ¶m : node->parameters()) {
81 0 : if (!typeTable_->isPossibleType(param.second) &&
82 0 : !typeTable_->isGenericType(param.second, currentGenericList_))
83 0 : return createError(ERROR_TYPE::TYPE,
84 0 : param.second->toString() +
85 0 : " is not a possible type or generic");
86 :
87 0 : auto newType = param.second;
88 0 : if (auto maskedEnum = typeTable_->isCompundEnumType(newType))
89 0 : newType = *maskedEnum;
90 0 : if (auto maskedGeneric =
91 0 : typeTable_->isCompundGenericType(newType, currentGenericList_))
92 0 : newType = *maskedGeneric;
93 :
94 0 : newParameters.push_back({param.first, newType});
95 0 : if (auto insertResult =
96 0 : currentScope_->insert(Variable{param.first, newType, nullptr});
97 0 : !insertResult)
98 0 : return createError(insertResult.error());
99 0 : }
100 0 : Parameters params{newParameters};
101 0 : node->setParameters(params);
102 :
103 0 : if (auto setted = functionTable_->setFuncParameters(node->id(), params);
104 0 : !setted)
105 0 : return createError(setted.error());
106 :
107 0 : if (!typeTable_->isPossibleType(node->returnType()) &&
108 0 : !typeTable_->isGenericType(node->returnType(), currentGenericList_))
109 0 : return createError(ERROR_TYPE::TYPE,
110 0 : node->returnType()->toString() +
111 0 : " is not a possible type or generic");
112 :
113 0 : auto retType = node->returnType();
114 0 : if (auto maskedEnum = typeTable_->isCompundEnumType(retType))
115 0 : retType = *maskedEnum;
116 0 : if (auto maskedGeneric =
117 0 : typeTable_->isCompundGenericType(retType, currentGenericList_))
118 0 : retType = *maskedGeneric;
119 0 : node->setReturnType(retType);
120 :
121 0 : if (auto settedReturnType =
122 0 : functionTable_->setFuncReturnType(node->id(), retType);
123 0 : !settedReturnType)
124 0 : return createError(settedReturnType.error());
125 :
126 0 : if (auto bodyResult = node->body()->accept(*this); !bodyResult)
127 0 : return createError(bodyResult.error());
128 :
129 0 : popScope();
130 0 : currentGenericList_.clear();
131 0 : return {};
132 0 : }
133 :
134 : std::expected<std::monostate, Error>
135 0 : FillSemanticInfo::visit(const AST_RETURN *node) const noexcept {
136 0 : if (!node) {
137 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_RETURN");
138 0 : }
139 0 : if (!node->expression()) {
140 0 : return {};
141 0 : }
142 0 : return node->expression()->accept(*this);
143 0 : }
144 :
145 : } // namespace nicole
|