Line data Source code
1 : #include "../../../../inc/parsingAnalysis/algorithm/topDown.h"
2 : #include <memory>
3 :
4 : namespace nicole {
5 :
6 : const std::expected<std::shared_ptr<AST>, Error>
7 0 : TopDown::parseVarDecl(const bool insideFor) const noexcept {
8 0 : const auto firsToken{tkStream_.current()};
9 0 : const Token token{*tkStream_.current()};
10 0 : std::string varName;
11 0 : std::shared_ptr<Type> varType{nullptr};
12 0 : std::shared_ptr<AST> valueExpr;
13 :
14 : // Función auxiliar para manejar la parte común de las declaraciones
15 0 : auto parseCommon = [&]() -> std::expected<void, Error> {
16 : // Verificar si el siguiente token es un identificador (nombre de la
17 : // variable)
18 0 : if (tkStream_.current()->type() != TokenType::ID) {
19 0 : return createError(ERROR_TYPE::SINTAX,
20 0 : "Expected variable name at " +
21 0 : tkStream_.current()->locInfo());
22 0 : }
23 0 : varName = tkStream_.current()->raw();
24 0 : if (auto res = tryEat(); !res) {
25 0 : return createError(res.error());
26 0 : }
27 :
28 : // Verificar si hay una especificación de tipo
29 0 : if (tkStream_.current()->type() == TokenType::DOTDOT) {
30 0 : if (auto res = tryEat(); !res) {
31 0 : return createError(res.error());
32 0 : }
33 0 : const std::expected<std::shared_ptr<Type>, Error> returnType{parseType()};
34 0 : if (!returnType) {
35 0 : return createError(returnType.error());
36 0 : }
37 0 : varType = *returnType;
38 0 : }
39 :
40 : // Verificar si hay un operador de asignación '='
41 0 : if (tkStream_.current()->type() == TokenType::ASSIGNMENT) {
42 0 : if (auto res = tryEat(); !res) {
43 0 : return createError(res.error());
44 0 : }
45 : // Parsear la expresión de valor
46 0 : auto expr = parseTernary();
47 0 : if (!expr || !*expr) {
48 0 : return createError(
49 0 : expr ? Error{ERROR_TYPE::NULL_NODE, "Expression is null"}
50 0 : : expr.error());
51 0 : }
52 0 : valueExpr = *expr;
53 0 : } else {
54 0 : return createError(ERROR_TYPE::SINTAX,
55 0 : "Expected '=' after variable declaration at " +
56 0 : tkStream_.current()->locInfo());
57 0 : }
58 :
59 : // Verificar el punto y coma al final de la declaración
60 0 : if (!insideFor) {
61 0 : if (tkStream_.current()->type() != TokenType::SEMICOLON) {
62 0 : return createError(
63 0 : ERROR_TYPE::SINTAX,
64 0 : "Expected ';' at the end of variable declaration at " +
65 0 : tkStream_.current()->locInfo());
66 0 : }
67 0 : if (auto res = tryEat(); !res) {
68 0 : return createError(res.error());
69 0 : }
70 0 : }
71 0 : return {};
72 0 : };
73 :
74 0 : switch (token.type()) {
75 0 : case TokenType::CONST: { // const variable: type = expression;
76 0 : if (auto res = tryEat(); !res) {
77 0 : return createError(res.error());
78 0 : }
79 0 : auto result = parseCommon();
80 0 : if (!result) {
81 0 : return createError(result.error());
82 0 : }
83 0 : varType = std::make_shared<ConstType>(varType);
84 0 : return Builder::createVarTypedtDecl(
85 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, varName, varType,
86 0 : valueExpr);
87 0 : }
88 0 : case TokenType::LET: { // let variable: type = expression;
89 0 : if (auto res = tryEat(); !res) {
90 0 : return createError(res.error());
91 0 : }
92 0 : auto result = parseCommon();
93 0 : if (!result) {
94 0 : return createError(result.error());
95 0 : }
96 0 : return Builder::createVarTypedtDecl(
97 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, varName, varType,
98 0 : valueExpr);
99 0 : }
100 0 : case TokenType::AUTO: { // auto variable = expression;
101 0 : if (auto res = tryEat(); !res) {
102 0 : return createError(res.error());
103 0 : }
104 0 : auto result = parseCommon();
105 0 : if (!result) {
106 0 : return createError(result.error());
107 0 : }
108 0 : if (varType) {
109 0 : return createError(ERROR_TYPE::SINTAX,
110 0 : "Auto variable should not have a type specified at " +
111 0 : tkStream_.current()->locInfo());
112 0 : }
113 0 : return Builder::createAutoDecl(
114 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, varName, valueExpr,
115 0 : false);
116 0 : }
117 0 : default: {
118 0 : return parseTernary();
119 0 : }
120 0 : }
121 0 : }
122 :
123 : const std::expected<std::shared_ptr<AST_DELETE>, Error>
124 0 : TopDown::parseDelete() const noexcept {
125 0 : const auto firsToken{tkStream_.current()};
126 0 : if (auto res = tryEat(); !res) {
127 0 : return createError(res.error());
128 0 : }
129 0 : const std::expected<std::shared_ptr<AST>, Error> value{parseOr()};
130 0 : if (!value || !*value) {
131 0 : return createError(value ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
132 0 : : value.error());
133 0 : }
134 0 : if (tkStream_.current()->type() != TokenType::SEMICOLON) {
135 0 : return createError(ERROR_TYPE::SINTAX,
136 0 : "Expected ';' at the end of delete expression at " +
137 0 : tkStream_.current()->locInfo());
138 0 : }
139 0 : return Builder::createDelete(
140 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, *value);
141 0 : }
142 :
143 : } // namespace nicole
|