Line data Source code
1 : #include "../../../inc/parsingAnalysis/ast/pointer/ast_delete.h"
2 : #include "../../../inc/parsingAnalysis/ast/pointer/ast_deref.h"
3 : #include "../../../inc/parsingAnalysis/ast/pointer/ast_new.h"
4 : #include "../../../inc/visitors/typeAnalysis/typeAnalysis.h"
5 : #include <memory>
6 :
7 : namespace nicole {
8 :
9 : /*
10 : - value debe ser un puntero y que este en la tabla de memoria dinamica
11 : - retorna NoPropagate
12 : */
13 : std::expected<std::shared_ptr<Type>, Error>
14 0 : TypeAnalysis::visit(const AST_DELETE *node) const noexcept {
15 0 : if (!node)
16 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_DELETE");
17 :
18 : // Se analiza el valor que se desea borrar.
19 0 : auto result = node->value()->accept(*this);
20 0 : if (!result)
21 0 : return createError(result.error());
22 :
23 0 : auto type = result.value();
24 :
25 0 : if (insideDeclWithGenerics &&
26 0 : typeTable_->isGenericType(type, currentGenericList_)) {
27 0 : std::shared_ptr<Type> unwrapped = type;
28 0 : if (auto constType = std::dynamic_pointer_cast<ConstType>(unwrapped))
29 0 : unwrapped = constType->baseType();
30 0 : auto pointerType = std::dynamic_pointer_cast<PointerType>(unwrapped);
31 0 : if (!pointerType)
32 0 : return createError(ERROR_TYPE::TYPE,
33 0 : "Delete on generic: type is not a pointer");
34 0 : if (!std::dynamic_pointer_cast<PlaceHolder>(pointerType->baseType()))
35 0 : return createError(
36 0 : ERROR_TYPE::TYPE,
37 0 : "Delete on generic: pointer does not wrap a PlaceHolder");
38 :
39 0 : node->setReturnedFromAnalysis(typeTable_->noPropagateType());
40 0 : return typeTable_->noPropagateType();
41 0 : }
42 :
43 0 : std::shared_ptr<PointerType> pointer =
44 0 : std::dynamic_pointer_cast<PointerType>(type);
45 0 : if (!pointer) {
46 0 : if (auto constType = std::dynamic_pointer_cast<ConstType>(type)) {
47 0 : pointer = std::dynamic_pointer_cast<PointerType>(constType->baseType());
48 0 : if (!pointer)
49 0 : return createError(ERROR_TYPE::TYPE, "can only delete pointers");
50 0 : } else {
51 0 : return createError(ERROR_TYPE::TYPE, "can only delete pointers");
52 0 : }
53 0 : }
54 :
55 0 : node->setReturnedFromAnalysis(typeTable_->noPropagateType());
56 0 : return typeTable_->noPropagateType();
57 0 : }
58 :
59 : /*
60 : - envuelve en un puntero la expression y lo retorna, debe ser constructor o
61 : primitiva
62 : */
63 : std::expected<std::shared_ptr<Type>, Error>
64 0 : TypeAnalysis::visit(const AST_NEW *node) const noexcept {
65 0 : if (!node) {
66 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_NEW");
67 0 : }
68 :
69 0 : auto result = node->value()->accept(*this);
70 0 : if (!result)
71 0 : return createError(result.error());
72 :
73 0 : auto exprType = result.value();
74 :
75 0 : if (insideDeclWithGenerics and
76 0 : typeTable_->isGenericType(exprType, currentGenericList_))
77 0 : return std::make_shared<PointerType>(exprType);
78 :
79 0 : auto basicType = std::dynamic_pointer_cast<BasicType>(exprType);
80 0 : auto userType = std::dynamic_pointer_cast<UserType>(exprType);
81 0 : if (!basicType && !userType)
82 0 : return createError(
83 0 : ERROR_TYPE::TYPE,
84 0 : "can only use new with primitives, user types or generics");
85 :
86 0 : const auto wrapperTYpe{std::make_shared<PointerType>(exprType)};
87 0 : node->setReturnedFromAnalysis(wrapperTYpe);
88 0 : return wrapperTYpe;
89 0 : }
90 :
91 : /*
92 : - la expresion debe ser un puntero y retorna el tipo al que apunta
93 : */
94 : std::expected<std::shared_ptr<Type>, Error>
95 0 : TypeAnalysis::visit(const AST_DEREF *node) const noexcept {
96 0 : if (!node) {
97 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_DEREF");
98 0 : }
99 :
100 0 : auto result = node->value()->accept(*this);
101 0 : if (!result)
102 0 : return createError(result.error());
103 :
104 0 : auto type = result.value();
105 :
106 0 : std::shared_ptr<Type> unwrappedType = type;
107 0 : if (auto constType = std::dynamic_pointer_cast<ConstType>(type))
108 0 : unwrappedType = constType->baseType();
109 :
110 0 : if (insideDeclWithGenerics &&
111 0 : typeTable_->isGenericType(unwrappedType, currentGenericList_)) {
112 :
113 0 : if (auto ptrType = std::dynamic_pointer_cast<PointerType>(unwrappedType)) {
114 0 : node->setReturnedFromAnalysis(ptrType->baseType());
115 0 : return ptrType->baseType();
116 0 : }
117 0 : return createError(ERROR_TYPE::TYPE, "can only deref a pointer");
118 0 : }
119 :
120 0 : if (auto ptrType = std::dynamic_pointer_cast<PointerType>(unwrappedType)) {
121 0 : node->setReturnedFromAnalysis(ptrType->baseType());
122 0 : return ptrType->baseType();
123 0 : }
124 0 : return createError(ERROR_TYPE::TYPE, "can only deref a pointer");
125 0 : }
126 :
127 : } // namespace nicole
|