4 * Date: Tue Jan 12 17:29:03 2010
6 * GNU recutils - SEX Abstract Syntax Trees
10 /* Copyright (C) 2010-2019 Jose E. Marchesi */
12 /* This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 #include <rec-sex-ast.h>
38 #define REC_SEX_AST_MAX_CHILDREN 3
40 struct rec_sex_ast_node_s
42 enum rec_sex_ast_node_type_e type
;
53 rec_sex_ast_node_t children
[REC_SEX_AST_MAX_CHILDREN
];
59 rec_sex_ast_node_t top
;
71 new = malloc (sizeof (struct rec_sex_ast_s
));
81 rec_sex_ast_destroy (rec_sex_ast_t ast
)
85 rec_sex_ast_node_destroy (ast
->top
);
92 rec_sex_ast_node_new (void)
94 rec_sex_ast_node_t
new;
96 new = malloc (sizeof(struct rec_sex_ast_node_s
));
99 new->type
= REC_SEX_NOVAL
;
100 new->num_children
= 0;
103 new->fixed_val
= NULL
;
110 rec_sex_ast_node_destroy (rec_sex_ast_node_t node
)
114 /* Destroy children. */
115 for (i
= 0; i
< node
->num_children
; i
++)
117 rec_sex_ast_node_destroy (node
->children
[i
]);
120 /* Destroy values. */
121 if (node
->type
== REC_SEX_STR
)
123 free (node
->val
.string
);
125 else if (node
->type
== REC_SEX_NAME
)
127 free (node
->val
.name
[0]);
128 free (node
->val
.name
[1]);
131 free (node
->fixed_val
);
135 enum rec_sex_ast_node_type_e
136 rec_sex_ast_node_type (rec_sex_ast_node_t node
)
142 rec_sex_ast_node_set_type (rec_sex_ast_node_t node
,
143 enum rec_sex_ast_node_type_e type
)
149 rec_sex_ast_node_int (rec_sex_ast_node_t node
)
151 return node
->val
.integer
;
155 rec_sex_ast_node_set_int (rec_sex_ast_node_t node
,
158 node
->type
= REC_SEX_INT
;
159 node
->val
.integer
= num
;
163 rec_sex_ast_node_real (rec_sex_ast_node_t node
)
165 return node
->val
.real
;
169 rec_sex_ast_node_set_real (rec_sex_ast_node_t node
,
172 node
->type
= REC_SEX_REAL
;
173 node
->val
.real
= num
;
177 rec_sex_ast_node_str (rec_sex_ast_node_t node
)
179 return node
->val
.string
;
183 rec_sex_ast_node_set_str (rec_sex_ast_node_t node
,
186 if (node
->type
== REC_SEX_STR
)
188 free (node
->val
.string
);
191 node
->type
= REC_SEX_STR
;
192 node
->val
.string
= strdup (str
);
196 rec_sex_ast_node_name (rec_sex_ast_node_t node
)
198 return node
->val
.name
[0];
202 rec_sex_ast_node_subname (rec_sex_ast_node_t node
)
204 return node
->val
.name
[1];
208 rec_sex_ast_node_set_name (rec_sex_ast_node_t node
,
212 if (node
->type
== REC_SEX_NAME
)
214 free (node
->val
.name
[0]);
215 free (node
->val
.name
[1]);
218 node
->type
= REC_SEX_NAME
;
219 node
->val
.name
[0] = strdup (name
);
220 node
->val
.name
[1] = NULL
;
223 node
->val
.name
[1] = strdup (subname
);
228 rec_sex_ast_node_link (rec_sex_ast_node_t parent
,
229 rec_sex_ast_node_t child
)
231 if (parent
->num_children
< REC_SEX_AST_MAX_CHILDREN
)
233 parent
->children
[parent
->num_children
++] = child
;
238 rec_sex_ast_top (rec_sex_ast_t ast
)
244 rec_sex_ast_set_top (rec_sex_ast_t ast
,
245 rec_sex_ast_node_t node
)
251 rec_sex_ast_print_node (rec_sex_ast_node_t node
)
255 for (i
= 0; i
< node
->num_children
; i
++)
257 rec_sex_ast_print_node (node
->children
[i
]);
260 printf ("------- node\n");
261 printf ("type: %d\n", node
->type
);
262 if (node
->type
== REC_SEX_INT
)
264 printf("value: %d\n", node
->val
.integer
);
266 if (node
->type
== REC_SEX_NAME
)
268 printf("value: %s\n", node
->val
.name
[0]);
270 if (node
->type
== REC_SEX_STR
)
272 printf("value: %s\n", node
->val
.string
);
279 rec_sex_ast_node_num_children (rec_sex_ast_node_t node
)
281 return node
->num_children
;
285 rec_sex_ast_node_child (rec_sex_ast_node_t node
,
288 rec_sex_ast_node_t res
;
291 if (n
< node
->num_children
)
293 res
= node
->children
[n
];
300 rec_sex_ast_node_reset (rec_sex_ast_node_t node
)
304 for (i
= 0; i
< node
->num_children
; i
++)
306 rec_sex_ast_node_reset (node
->children
[i
]);
313 rec_sex_ast_node_fix (rec_sex_ast_node_t node
,
316 free (node
->fixed_val
);
318 node
->fixed_val
= strdup (val
);
322 rec_sex_ast_node_unfix (rec_sex_ast_node_t node
)
326 for (i
= 0; i
< node
->num_children
; i
++)
328 rec_sex_ast_node_unfix (node
->children
[i
]);
335 rec_sex_ast_node_fixed (rec_sex_ast_node_t node
)
341 rec_sex_ast_node_fixed_val (rec_sex_ast_node_t node
)
343 return node
->fixed_val
;
347 rec_sex_ast_node_index (rec_sex_ast_node_t node
)
353 rec_sex_ast_node_set_index (rec_sex_ast_node_t node
,
360 rec_sex_ast_print (rec_sex_ast_t ast
)
362 rec_sex_ast_print_node (ast
->top
);
366 rec_sex_ast_name_p_1 (rec_sex_ast_node_t node
,
374 if ((node
->type
== REC_SEX_NAME
)
375 && ((node
->index
== -1) || (node
->index
< idx
))
376 && (strcmp (name
, node
->val
.name
[0]) == 0))
381 for (i
= 0; i
< node
->num_children
; i
++)
383 if (rec_sex_ast_name_p_1 (node
->children
[i
], name
, idx
))
394 rec_sex_ast_name_p (rec_sex_ast_t ast
,
398 /* Traverse the AST looking for any name node NAME[I] where I <
401 return rec_sex_ast_name_p_1 (ast
->top
,
407 rec_sex_ast_hash_name_p_1 (rec_sex_ast_node_t node
,
414 if ((node
->type
== REC_SEX_OP_SHA
)
415 && (node
->num_children
== 1)
416 && (node
->children
[0]->type
== REC_SEX_NAME
)
417 && (strcmp (name
, node
->children
[0]->val
.name
[0]) == 0))
420 for (i
= 0; i
< node
->num_children
; i
++)
421 if (rec_sex_ast_hash_name_p_1 (node
->children
[i
], name
))
429 rec_sex_ast_hash_name_p (rec_sex_ast_t ast
,
432 /* Traverse the AST looking for any name node NAME whose father is a
434 return rec_sex_ast_hash_name_p_1 (ast
->top
, name
);
437 /* End of rec-sex-ast.c */