Line data Source code
1 : #include "../../../../inc/parsingAnalysis/algorithm/topDown.h"
2 : #include <memory>
3 : #include <vector>
4 :
5 : namespace nicole {
6 :
7 : const std::expected<std::shared_ptr<AST_FUNC_DECL>, Error>
8 0 : TopDown::parseFuncDecl() const noexcept {
9 0 : const auto firsToken{tkStream_.current()};
10 0 : if (auto res = tryEat(); !res) {
11 0 : return createError(res.error());
12 0 : }
13 0 : if (tkStream_.current()->type() != TokenType::ID) {
14 0 : return createError(ERROR_TYPE::SINTAX,
15 0 : "missing identifier of function at " +
16 0 : tkStream_.current()->locInfo());
17 0 : }
18 0 : const Token id{*tkStream_.current()};
19 0 : if (auto res = tryEat(); !res) {
20 0 : return createError(res.error());
21 0 : }
22 0 : std::expected<std::vector<GenericParameter>, Error> generics{};
23 0 : if (tkStream_.current()->type() == TokenType::OPERATOR_SMALLER) {
24 0 : generics = parseGenerics();
25 0 : }
26 0 : if (!generics) {
27 0 : return createError(generics.error());
28 0 : }
29 0 : if (tkStream_.current()->type() != TokenType::LP) {
30 0 : return createError(ERROR_TYPE::SINTAX, "missing ( of function at " +
31 0 : tkStream_.current()->locInfo());
32 0 : }
33 0 : if (auto res = tryEat(); !res) {
34 0 : return createError(res.error());
35 0 : }
36 0 : const auto params{parseParams()};
37 0 : if (!params) {
38 0 : return createError(params.error());
39 0 : }
40 0 : if (tkStream_.current()->type() != TokenType::RP) {
41 0 : return createError(ERROR_TYPE::SINTAX, "missing ) of function at " +
42 0 : tkStream_.current()->locInfo());
43 0 : }
44 0 : if (auto res = tryEat(); !res) {
45 0 : return createError(res.error());
46 0 : }
47 0 : if (tkStream_.current()->type() != TokenType::DOTDOT) {
48 0 : return createError(ERROR_TYPE::SINTAX,
49 0 : "missing : after ) of function decl at " +
50 0 : tkStream_.current()->raw() + " at " +
51 0 : tkStream_.current()->locInfo());
52 0 : }
53 0 : if (auto res = tryEat(); !res) {
54 0 : return createError(res.error());
55 0 : }
56 0 : const std::expected<std::shared_ptr<Type>, Error> returnType{parseType()};
57 0 : if (!returnType) {
58 0 : return createError(returnType.error());
59 0 : }
60 0 : const std::expected<std::shared_ptr<AST_BODY>, Error> body{parseBody()};
61 0 : if (!body || !*body) {
62 0 : return createError(body ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
63 0 : : body.error());
64 0 : }
65 0 : return Builder::createFuncDecl(
66 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, id.raw(), *generics,
67 0 : *params, *returnType, *body);
68 0 : }
69 :
70 0 : const std::expected<Parameters, Error> TopDown::parseParams() const noexcept {
71 0 : std::vector<std::pair<std::string, std::shared_ptr<Type>>> params{};
72 0 : while (tkStream_.currentPos() < tkStream_.size() and
73 0 : tkStream_.current()->type() != TokenType::RP) {
74 0 : if (tkStream_.current()->type() != TokenType::ID) {
75 0 : return createError(ERROR_TYPE::SINTAX,
76 0 : "missing id of param of function decl at " +
77 0 : tkStream_.current()->raw() + " at " +
78 0 : tkStream_.current()->locInfo());
79 0 : }
80 0 : const Token id{*tkStream_.current()};
81 0 : if (auto res = tryEat(); !res) {
82 0 : return createError(res.error());
83 0 : }
84 0 : if (tkStream_.current()->type() != TokenType::DOTDOT) {
85 0 : return createError(ERROR_TYPE::SINTAX,
86 0 : "missing : after param of function decl at " +
87 0 : tkStream_.current()->raw() + " at " +
88 0 : tkStream_.current()->locInfo());
89 0 : }
90 0 : if (auto res = tryEat(); !res) {
91 0 : return createError(res.error());
92 0 : }
93 0 : const std::expected<std::shared_ptr<Type>, Error> returnType{parseType()};
94 0 : if (!returnType) {
95 0 : return createError(returnType.error());
96 0 : }
97 0 : params.push_back({id.raw(), *returnType});
98 0 : if (tkStream_.current()->type() == TokenType::COMMA) {
99 0 : if (auto res = tryEat(); !res) {
100 0 : return createError(res.error());
101 0 : }
102 0 : continue;
103 0 : } else if (tkStream_.current()->type() != TokenType::RP) {
104 0 : return createError(ERROR_TYPE::SINTAX,
105 0 : "missing comma or parenthesis of function decl at " +
106 0 : tkStream_.current()->locInfo());
107 0 : }
108 0 : break;
109 0 : }
110 0 : return Parameters{params};
111 0 : }
112 :
113 : const std::expected<std::shared_ptr<AST_RETURN>, Error>
114 0 : TopDown::parseReturn() const noexcept {
115 0 : const auto firsToken{tkStream_.current()};
116 0 : if (auto res = tryEat(); !res) {
117 0 : return createError(res.error());
118 0 : }
119 0 : if (tkStream_.current()->type() == TokenType::SEMICOLON) {
120 0 : return Builder::createReturn(
121 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, nullptr);
122 0 : }
123 0 : const std::expected<std::shared_ptr<AST>, Error> value{parseTernary()};
124 0 : if (!value || !*value) {
125 0 : return createError(value ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
126 0 : : value.error());
127 0 : }
128 0 : if (tkStream_.current()->type() != TokenType::SEMICOLON) {
129 0 : return createError(ERROR_TYPE::SINTAX, "missing ; of return at " +
130 0 : tkStream_.current()->locInfo());
131 0 : }
132 0 : return Builder::createReturn(
133 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, *value);
134 0 : }
135 :
136 : const std::expected<std::vector<std::shared_ptr<Type>>, Error>
137 0 : TopDown::parseReplacementOfGenerics() const noexcept {
138 0 : std::vector<std::shared_ptr<Type>> replacemments{};
139 0 : if (tkStream_.current()->type() == TokenType::OPERATOR_SMALLER) {
140 0 : auto res = tryEat(); // consume el identificador
141 0 : if (!res) {
142 0 : return createError(res.error());
143 0 : }
144 0 : auto argExpected = parseType();
145 0 : if (!argExpected) {
146 0 : return createError(argExpected.error());
147 0 : }
148 0 : replacemments.push_back(argExpected.value());
149 : // Se admiten mĂșltiples argumentos separados por ','
150 0 : while (tkStream_.current() &&
151 0 : tkStream_.current()->type() == TokenType::COMMA) {
152 0 : res = tryEat(); // consume ','
153 0 : if (!res) {
154 0 : return createError(res.error());
155 0 : }
156 0 : argExpected = parseType();
157 0 : if (!argExpected) {
158 0 : return createError(argExpected.error());
159 0 : }
160 0 : replacemments.push_back(argExpected.value());
161 0 : }
162 0 : if (!tkStream_.current() ||
163 0 : tkStream_.current()->type() != TokenType::OPERATOR_GREATER) {
164 0 : return createError(
165 0 : ERROR_TYPE::SINTAX,
166 0 : "Se esperaba '>' para cerrar los argumentos genéricos en " +
167 0 : tkStream_.lastRead()->locInfo());
168 0 : }
169 0 : res = tryEat(); // consume '>'
170 0 : if (!res) {
171 0 : return createError(res.error());
172 0 : }
173 0 : }
174 0 : return replacemments;
175 0 : }
176 :
177 : } // namespace nicole
|