1 /* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t tw=80:
3 * Taller de Programación (75.42).
6 * Programa calculadora.
8 * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
9 * Puede copiar, modificar y distribuir este programa bajo los términos de
10 * la licencia GPL (http://www.gnu.org/).
12 * Creado: dom sep 14 13:03:49 ART 2003
17 #include "parser_variable.h"
20 #include "variable_list.h"
21 #include "parser_common.h"
22 #include "parseerror.h"
28 #include "memdebug_debugger.h"
30 #define PARSE_ERROR(str) ParseError_set_pos_message(error, str, i + 1, c)
32 bool parser_variable(const char* line, size_t len, DLList* variable_list,
34 enum {SEARCH_VAR, VAR, SEARCH_VAL, VAL, SEARCH_MIN, MIN, SEARCH_MAX, MAX}
47 for (i = 0; i < len; i++) {
50 case SEARCH_VAR: /* Busca el comienzo de una variable. */
53 /* Es una letra => es el comienzo de la variable. */
56 } else { /* es otra cosa => error */
57 PARSE_ERROR("un espacio o una letra");
61 /* Si es espacio, no hace nada, deja que siga. */
63 case VAR: /* Se fija cual es el nombre de la variable. */
64 if (!is_alpha_num(c)) {
66 /* Es un espacio, entonces hay que buscar un igual. */
68 /* Calculo la longitud de la variable. */
69 var_len = i - var_start;
70 } else { /* es otra cosa */
72 "un espacio, una letra, un número o un igual");
76 /* Si es alfanumérico, no hace nada, deja que siga. */
78 case SEARCH_VAL: /* Busca el valor. */
80 /* Pasamos a interpretar el valor. */
82 /* Pone el inicio del valor. */
84 /* Calcula la longitud como si fuera hasta el final. */
87 /* Si es espacio, no hace nada, deja que siga. */
89 case VAL: /* Se fija hasta donde va el valor actual. */
90 if (is_space(c)) { /* Si es un espacio, terminó el valor. */
91 /* Buscamos otro valor. */
93 /* Pone la longitud de este valor. */
94 val_len = i - val_start;
96 /* Si es alfanumérico, no hace nada, deja que siga. */
98 case SEARCH_MIN: /* Busca el mímino. */
100 /* Pasamos a interpretar el mínimo. */
102 /* Pone el inicio del mínimo. */
104 /* Calcula la longitud como si fuera hasta el final. */
107 /* Si es espacio, no hace nada, deja que siga. */
109 case MIN: /* Se fija hasta donde va el mínimo. */
110 if (is_space(c)) { /* Si es un espacio, terminó el mínimo. */
111 /* Buscamos el máximo. */
113 /* Pone la longitud del mínimo. */
114 min_len = i - min_start;
116 /* Si es alfanumérico, no hace nada, deja que siga. */
118 case SEARCH_MAX: /* Busca el máximo. */
120 /* Pasamos al estado de máximo encontrado. */
122 /* Pone el inicio del máximo. */
124 /* Pone la longitud del máximo hasta el final (ya no hay más
125 * valores a buscar). */
128 /* Si es espacio, no hace nada, deja que siga. */
131 /* Si status es max, no se busca mas nada, terminamo el loop for. */
136 /* Veo como terminó la interpretación. */
138 /* No se pudo interpretar una variable. */
142 /* No tiene variable. */
143 ParseError_set_message(error,
144 "No se encontró la definición de una variable");
148 /* No tiene valor de la variable. */
149 ParseError_set_message(error,
150 "No se encontró el valor de la variable");
154 /* Al menos la variable con su valor ya la tenemos. */
155 var = Variable_new(line, var_start, var_len);
157 ParseError_set_message(error, "No se pudo alocar memoria de variable");
163 if (!Variable_set_max(var, line, max_start, max_len)) {
164 /* No se pudo setear el máximo. */
165 Variable_delete(var);
166 ParseError_set_message(error,
167 "No se pudo establecer el máximo");
170 /* Continúo, tiene mínimo y valor también. */
173 /* Tiene míninimo. */
174 if (!Variable_set_min(var, line, min_start, min_len)) {
175 /* No se pudo setear el mínimo. */
176 Variable_delete(var);
177 ParseError_set_message(error,
178 "No se pudo establecer el mínimo");
181 /* Continúo, tiene valor también. */
184 /* Tiene solo valor. */
185 if (!Variable_set_value(var, line, val_start, val_len)) {
186 /* No se pudo setear el valor. */
187 Variable_delete(var);
188 ParseError_set_message(error,
189 "No se pudo establecer el valor");
193 /* Está todo ok, tengo la variable cargada, verifico max y min. */
194 if (!Variable_check_min_max(var)) {
195 Variable_delete(var);
196 ParseError_set_message(error,
197 "El mínimo es mayor que el máximo");
200 /* Ahora sí, la puedo agregar a la lista de variables. */
201 if (DLList_variable_find(variable_list, var->variable)) {
202 /* Si ya había uno, lo borro. */
203 DLList_remove_current(variable_list);
205 if (!DLList_push(variable_list, var)) {
206 ParseError_set_message(error,
207 "No se pudo agregar variable a la lista");
213 #undef PARSE_ERROR /* Sólo queremos usarlo en este fragmento */