pet.cc: extract out PetASTConsumer::add_pragma_handlers
[pet.git] / parse.c
blobc7e1a4895896567f3aa02e25a76da983e8e19941
1 /*
2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2013-2014 Ecole Normale Superieure. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and documentation
30 * are those of the authors and should not be interpreted as
31 * representing official policies, either expressed or implied, of
32 * Leiden University.
33 */
35 #include <stdlib.h>
36 #include <yaml.h>
38 #include "expr.h"
39 #include "loc.h"
40 #include "scop.h"
41 #include "scop_yaml.h"
42 #include "tree.h"
44 static char *extract_string(isl_ctx *ctx, yaml_document_t *document,
45 yaml_node_t *node)
47 if (node->type != YAML_SCALAR_NODE)
48 isl_die(ctx, isl_error_invalid, "expecting scalar node",
49 return NULL);
51 return strdup((char *) node->data.scalar.value);
54 static int extract_int(isl_ctx *ctx, yaml_document_t *document,
55 yaml_node_t *node)
57 if (node->type != YAML_SCALAR_NODE)
58 isl_die(ctx, isl_error_invalid, "expecting scalar node",
59 return -1);
61 return atoi((char *) node->data.scalar.value);
64 static double extract_double(isl_ctx *ctx, yaml_document_t *document,
65 yaml_node_t *node)
67 if (node->type != YAML_SCALAR_NODE)
68 isl_die(ctx, isl_error_invalid, "expecting scalar node",
69 return -1);
71 return strtod((char *) node->data.scalar.value, NULL);
74 static enum pet_expr_type extract_expr_type(isl_ctx *ctx,
75 yaml_document_t *document, yaml_node_t *node)
77 if (node->type != YAML_SCALAR_NODE)
78 isl_die(ctx, isl_error_invalid, "expecting scalar node",
79 return -1);
81 return pet_str_type((char *) node->data.scalar.value);
84 static enum pet_op_type extract_op(isl_ctx *ctx, yaml_document_t *document,
85 yaml_node_t *node)
87 if (node->type != YAML_SCALAR_NODE)
88 isl_die(ctx, isl_error_invalid, "expecting scalar node",
89 return -1);
91 return pet_str_op((char *) node->data.scalar.value);
94 static __isl_give isl_set *extract_set(isl_ctx *ctx, yaml_document_t *document,
95 yaml_node_t *node)
97 if (node->type != YAML_SCALAR_NODE)
98 isl_die(ctx, isl_error_invalid, "expecting scalar node",
99 return NULL);
101 return isl_set_read_from_str(ctx, (char *) node->data.scalar.value);
104 static __isl_give isl_id *extract_id(isl_ctx *ctx, yaml_document_t *document,
105 yaml_node_t *node)
107 if (node->type != YAML_SCALAR_NODE)
108 isl_die(ctx, isl_error_invalid, "expecting scalar node",
109 return NULL);
111 return isl_id_alloc(ctx, (char *) node->data.scalar.value, NULL);
114 static __isl_give isl_map *extract_map(isl_ctx *ctx, yaml_document_t *document,
115 yaml_node_t *node)
117 if (node->type != YAML_SCALAR_NODE)
118 isl_die(ctx, isl_error_invalid, "expecting scalar node",
119 return NULL);
121 return isl_map_read_from_str(ctx, (char *) node->data.scalar.value);
124 /* Extract an isl_val from "node".
126 static __isl_give isl_val *extract_val(isl_ctx *ctx, yaml_document_t *document,
127 yaml_node_t *node)
129 if (node->type != YAML_SCALAR_NODE)
130 isl_die(ctx, isl_error_invalid, "expecting scalar node",
131 return NULL);
133 return isl_val_read_from_str(ctx, (char *) node->data.scalar.value);
136 /* Extract an isl_multi_pw_aff from "node".
138 static __isl_give isl_multi_pw_aff *extract_multi_pw_aff(isl_ctx *ctx,
139 yaml_document_t *document, yaml_node_t *node)
141 if (node->type != YAML_SCALAR_NODE)
142 isl_die(ctx, isl_error_invalid, "expecting scalar node",
143 return NULL);
145 return isl_multi_pw_aff_read_from_str(ctx,
146 (char *) node->data.scalar.value);
149 /* Extract a pet_type from "node".
151 static struct pet_type *extract_type(isl_ctx *ctx,
152 yaml_document_t *document, yaml_node_t *node)
154 struct pet_type *type;
155 yaml_node_pair_t * pair;
157 if (node->type != YAML_MAPPING_NODE)
158 isl_die(ctx, isl_error_invalid, "expecting mapping",
159 return NULL);
161 type = isl_calloc_type(ctx, struct pet_type);
162 if (!type)
163 return NULL;
165 for (pair = node->data.mapping.pairs.start;
166 pair < node->data.mapping.pairs.top; ++pair) {
167 yaml_node_t *key, *value;
169 key = yaml_document_get_node(document, pair->key);
170 value = yaml_document_get_node(document, pair->value);
172 if (key->type != YAML_SCALAR_NODE)
173 isl_die(ctx, isl_error_invalid, "expecting scalar key",
174 return pet_type_free(type));
176 if (!strcmp((char *) key->data.scalar.value, "name"))
177 type->name = extract_string(ctx, document, value);
178 if (!strcmp((char *) key->data.scalar.value, "definition"))
179 type->definition = extract_string(ctx, document, value);
182 return type;
185 /* Extract a sequence of types from "node" and store them in scop->types.
187 static struct pet_scop *extract_types(isl_ctx *ctx,
188 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
190 int i;
191 yaml_node_item_t *item;
193 if (node->type != YAML_SEQUENCE_NODE)
194 isl_die(ctx, isl_error_invalid, "expecting sequence",
195 return NULL);
197 scop->n_type = node->data.sequence.items.top
198 - node->data.sequence.items.start;
199 scop->types = isl_calloc_array(ctx, struct pet_type *, scop->n_type);
200 if (!scop->types)
201 return pet_scop_free(scop);
203 for (item = node->data.sequence.items.start, i = 0;
204 item < node->data.sequence.items.top; ++item, ++i) {
205 yaml_node_t *n;
207 n = yaml_document_get_node(document, *item);
208 scop->types[i] = extract_type(ctx, document, n);
209 if (!scop->types[i])
210 return pet_scop_free(scop);
213 return scop;
216 static struct pet_array *extract_array(isl_ctx *ctx, yaml_document_t *document,
217 yaml_node_t *node)
219 struct pet_array *array;
220 yaml_node_pair_t * pair;
222 if (node->type != YAML_MAPPING_NODE)
223 isl_die(ctx, isl_error_invalid, "expecting mapping",
224 return NULL);
226 array = isl_calloc_type(ctx, struct pet_array);
227 if (!array)
228 return NULL;
230 for (pair = node->data.mapping.pairs.start;
231 pair < node->data.mapping.pairs.top; ++pair) {
232 yaml_node_t *key, *value;
234 key = yaml_document_get_node(document, pair->key);
235 value = yaml_document_get_node(document, pair->value);
237 if (key->type != YAML_SCALAR_NODE)
238 isl_die(ctx, isl_error_invalid, "expecting scalar key",
239 return pet_array_free(array));
241 if (!strcmp((char *) key->data.scalar.value, "context"))
242 array->context = extract_set(ctx, document, value);
243 if (!strcmp((char *) key->data.scalar.value, "extent"))
244 array->extent = extract_set(ctx, document, value);
245 if (!strcmp((char *) key->data.scalar.value, "value_bounds"))
246 array->value_bounds = extract_set(ctx, document, value);
247 if (!strcmp((char *) key->data.scalar.value, "element_type"))
248 array->element_type =
249 extract_string(ctx, document, value);
250 if (!strcmp((char *) key->data.scalar.value, "element_size"))
251 array->element_size = extract_int(ctx, document, value);
252 if (!strcmp((char *) key->data.scalar.value,
253 "element_is_record"))
254 array->element_is_record =
255 extract_int(ctx, document, value);
256 if (!strcmp((char *) key->data.scalar.value, "live_out"))
257 array->live_out = extract_int(ctx, document, value);
258 if (!strcmp((char *) key->data.scalar.value,
259 "uniquely_defined"))
260 array->uniquely_defined =
261 extract_int(ctx, document, value);
262 if (!strcmp((char *) key->data.scalar.value, "declared"))
263 array->declared = extract_int(ctx, document, value);
264 if (!strcmp((char *) key->data.scalar.value, "exposed"))
265 array->exposed = extract_int(ctx, document, value);
268 return array;
271 static struct pet_scop *extract_arrays(isl_ctx *ctx, yaml_document_t *document,
272 yaml_node_t *node, struct pet_scop *scop)
274 int i;
275 yaml_node_item_t *item;
277 if (node->type != YAML_SEQUENCE_NODE)
278 isl_die(ctx, isl_error_invalid, "expecting sequence",
279 return NULL);
281 scop->n_array = node->data.sequence.items.top
282 - node->data.sequence.items.start;
283 scop->arrays = isl_calloc_array(ctx, struct pet_array *, scop->n_array);
284 if (!scop->arrays)
285 return pet_scop_free(scop);
287 for (item = node->data.sequence.items.start, i = 0;
288 item < node->data.sequence.items.top; ++item, ++i) {
289 yaml_node_t *n;
291 n = yaml_document_get_node(document, *item);
292 scop->arrays[i] = extract_array(ctx, document, n);
293 if (!scop->arrays[i])
294 return pet_scop_free(scop);
297 return scop;
300 static __isl_give pet_expr *extract_expr(isl_ctx *ctx,
301 yaml_document_t *document, yaml_node_t *node);
303 static __isl_give pet_expr *extract_arguments(isl_ctx *ctx,
304 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
306 int i, n;
307 yaml_node_item_t *item;
309 if (node->type != YAML_SEQUENCE_NODE)
310 isl_die(ctx, isl_error_invalid, "expecting sequence",
311 return pet_expr_free(expr));
313 n = node->data.sequence.items.top - node->data.sequence.items.start;
314 expr = pet_expr_set_n_arg(expr, n);
316 for (item = node->data.sequence.items.start, i = 0;
317 item < node->data.sequence.items.top; ++item, ++i) {
318 yaml_node_t *n;
319 pet_expr *arg;
321 n = yaml_document_get_node(document, *item);
322 arg = extract_expr(ctx, document, n);
323 expr = pet_expr_set_arg(expr, i, arg);
326 return expr;
329 /* Extract pet_expr_double specific fields from "node" and
330 * update "expr" accordingly.
332 static __isl_give pet_expr *extract_expr_double(isl_ctx *ctx,
333 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
335 yaml_node_pair_t *pair;
336 double d = 0;
337 char *s = NULL;
339 for (pair = node->data.mapping.pairs.start;
340 pair < node->data.mapping.pairs.top; ++pair) {
341 yaml_node_t *key, *value;
343 key = yaml_document_get_node(document, pair->key);
344 value = yaml_document_get_node(document, pair->value);
346 if (key->type != YAML_SCALAR_NODE)
347 isl_die(ctx, isl_error_invalid, "expecting scalar key",
348 return pet_expr_free(expr));
350 if (!strcmp((char *) key->data.scalar.value, "value"))
351 d = extract_double(ctx, document, value);
352 if (!strcmp((char *) key->data.scalar.value, "string"))
353 s = extract_string(ctx, document, value);
356 expr = pet_expr_double_set(expr, d, s);
357 free(s);
359 return expr;
362 /* Extract pet_expr_access specific fields from "node" and
363 * update "expr" accordingly.
365 static __isl_give pet_expr *extract_expr_access(isl_ctx *ctx,
366 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
368 yaml_node_pair_t *pair;
370 for (pair = node->data.mapping.pairs.start;
371 pair < node->data.mapping.pairs.top; ++pair) {
372 yaml_node_t *key, *value;
374 key = yaml_document_get_node(document, pair->key);
375 value = yaml_document_get_node(document, pair->value);
377 if (key->type != YAML_SCALAR_NODE)
378 isl_die(ctx, isl_error_invalid, "expecting scalar key",
379 return pet_expr_free(expr));
381 if (!strcmp((char *) key->data.scalar.value, "relation"))
382 expr = pet_expr_access_set_access(expr,
383 extract_map(ctx, document, value));
384 if (!strcmp((char *) key->data.scalar.value, "index"))
385 expr = pet_expr_access_set_index(expr,
386 extract_multi_pw_aff(ctx, document, value));
387 if (!strcmp((char *) key->data.scalar.value, "reference"))
388 expr = pet_expr_access_set_ref_id(expr,
389 extract_id(ctx, document, value));
390 if (!strcmp((char *) key->data.scalar.value, "read"))
391 expr = pet_expr_access_set_read(expr,
392 extract_int(ctx, document, value));
393 if (!strcmp((char *) key->data.scalar.value, "write"))
394 expr = pet_expr_access_set_write(expr,
395 extract_int(ctx, document, value));
398 return expr;
401 /* Extract operation expression specific fields from "node" and
402 * update "expr" accordingly.
404 static __isl_give pet_expr *extract_expr_op(isl_ctx *ctx,
405 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
407 yaml_node_pair_t *pair;
409 for (pair = node->data.mapping.pairs.start;
410 pair < node->data.mapping.pairs.top; ++pair) {
411 yaml_node_t *key, *value;
413 key = yaml_document_get_node(document, pair->key);
414 value = yaml_document_get_node(document, pair->value);
416 if (key->type != YAML_SCALAR_NODE)
417 isl_die(ctx, isl_error_invalid, "expecting scalar key",
418 return pet_expr_free(expr));
420 if (!strcmp((char *) key->data.scalar.value, "operation"))
421 expr = pet_expr_op_set_type(expr,
422 extract_op(ctx, document, value));
425 return expr;
428 /* Extract pet_expr_call specific fields from "node" and
429 * update "expr" accordingly.
431 static __isl_give pet_expr *extract_expr_call(isl_ctx *ctx,
432 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
434 yaml_node_pair_t *pair;
436 for (pair = node->data.mapping.pairs.start;
437 pair < node->data.mapping.pairs.top; ++pair) {
438 yaml_node_t *key, *value;
440 key = yaml_document_get_node(document, pair->key);
441 value = yaml_document_get_node(document, pair->value);
443 if (key->type != YAML_SCALAR_NODE)
444 isl_die(ctx, isl_error_invalid, "expecting scalar key",
445 return pet_expr_free(expr));
447 if (!strcmp((char *) key->data.scalar.value, "name"))
448 expr = pet_expr_call_set_name(expr,
449 extract_string(ctx, document, value));
452 return expr;
455 /* Extract pet_expr_cast specific fields from "node" and
456 * update "expr" accordingly.
458 static __isl_give pet_expr *extract_expr_cast(isl_ctx *ctx,
459 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
461 yaml_node_pair_t *pair;
463 for (pair = node->data.mapping.pairs.start;
464 pair < node->data.mapping.pairs.top; ++pair) {
465 yaml_node_t *key, *value;
467 key = yaml_document_get_node(document, pair->key);
468 value = yaml_document_get_node(document, pair->value);
470 if (key->type != YAML_SCALAR_NODE)
471 isl_die(ctx, isl_error_invalid, "expecting scalar key",
472 return pet_expr_free(expr));
474 if (!strcmp((char *) key->data.scalar.value, "type_name"))
475 expr = pet_expr_cast_set_type_name(expr,
476 extract_string(ctx, document, value));
479 return expr;
482 /* Extract pet_expr_int specific fields from "node" and
483 * update "expr" accordingly.
485 static __isl_give pet_expr *extract_expr_int(isl_ctx *ctx,
486 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
488 yaml_node_pair_t * pair;
490 for (pair = node->data.mapping.pairs.start;
491 pair < node->data.mapping.pairs.top; ++pair) {
492 yaml_node_t *key, *value;
494 key = yaml_document_get_node(document, pair->key);
495 value = yaml_document_get_node(document, pair->value);
497 if (key->type != YAML_SCALAR_NODE)
498 isl_die(ctx, isl_error_invalid, "expecting scalar key",
499 return pet_expr_free(expr));
501 if (!strcmp((char *) key->data.scalar.value, "value"))
502 expr = pet_expr_int_set_val(expr,
503 extract_val(ctx, document, value));
506 return expr;
509 /* Extract a pet_expr from "node".
511 * We first extract the type and arguments of the expression and
512 * then extract additional fields depending on the type.
514 static __isl_give pet_expr *extract_expr(isl_ctx *ctx,
515 yaml_document_t *document, yaml_node_t *node)
517 enum pet_expr_type type = pet_expr_error;
518 pet_expr *expr;
519 yaml_node_pair_t *pair;
521 if (node->type != YAML_MAPPING_NODE)
522 isl_die(ctx, isl_error_invalid, "expecting mapping",
523 return NULL);
525 for (pair = node->data.mapping.pairs.start;
526 pair < node->data.mapping.pairs.top; ++pair) {
527 yaml_node_t *key, *value;
529 key = yaml_document_get_node(document, pair->key);
530 value = yaml_document_get_node(document, pair->value);
532 if (key->type != YAML_SCALAR_NODE)
533 isl_die(ctx, isl_error_invalid, "expecting scalar key",
534 return pet_expr_free(expr));
536 if (!strcmp((char *) key->data.scalar.value, "type"))
537 type = extract_expr_type(ctx, document, value);
540 if (type == pet_expr_error)
541 isl_die(ctx, isl_error_invalid, "cannot determine type",
542 return NULL);
544 expr = pet_expr_alloc(ctx, type);
545 if (!expr)
546 return NULL;
548 for (pair = node->data.mapping.pairs.start;
549 pair < node->data.mapping.pairs.top; ++pair) {
550 yaml_node_t *key, *value;
552 key = yaml_document_get_node(document, pair->key);
553 value = yaml_document_get_node(document, pair->value);
555 if (!strcmp((char *) key->data.scalar.value, "arguments"))
556 expr = extract_arguments(ctx, document, value, expr);
557 if (!expr)
558 return NULL;
561 switch (type) {
562 case pet_expr_error:
563 isl_die(ctx, isl_error_internal, "unreachable code",
564 return NULL);
565 case pet_expr_access:
566 expr = extract_expr_access(ctx, document, node, expr);
567 break;
568 case pet_expr_double:
569 expr = extract_expr_double(ctx, document, node, expr);
570 break;
571 case pet_expr_call:
572 expr = extract_expr_call(ctx, document, node, expr);
573 break;
574 case pet_expr_cast:
575 expr = extract_expr_cast(ctx, document, node, expr);
576 break;
577 case pet_expr_int:
578 expr = extract_expr_int(ctx, document, node, expr);
579 break;
580 case pet_expr_op:
581 expr = extract_expr_op(ctx, document, node, expr);
582 break;
585 return expr;
588 /* Extract a pet_tree_type from "node".
590 static enum pet_tree_type extract_tree_type(isl_ctx *ctx,
591 yaml_document_t *document, yaml_node_t *node)
593 if (node->type != YAML_SCALAR_NODE)
594 isl_die(ctx, isl_error_invalid, "expecting scalar node",
595 return -1);
597 return pet_tree_str_type((char *) node->data.scalar.value);
600 static __isl_give pet_tree *extract_tree(isl_ctx *ctx,
601 yaml_document_t *document, yaml_node_t *node);
603 /* Extract a pet_tree of type pet_tree_block from "node".
605 static __isl_give pet_tree *extract_tree_block(isl_ctx *ctx,
606 yaml_document_t *document, yaml_node_t *node)
608 int block = 0;
609 int i, n;
610 yaml_node_pair_t *pair;
611 yaml_node_item_t *item;
612 yaml_node_t *children = NULL;
613 pet_tree *tree;
615 for (pair = node->data.mapping.pairs.start;
616 pair < node->data.mapping.pairs.top; ++pair) {
617 yaml_node_t *key, *value;
619 key = yaml_document_get_node(document, pair->key);
620 value = yaml_document_get_node(document, pair->value);
622 if (key->type != YAML_SCALAR_NODE)
623 isl_die(ctx, isl_error_invalid, "expecting scalar key",
624 return NULL);
626 if (!strcmp((char *) key->data.scalar.value, "block"))
627 block = extract_int(ctx, document, value);
628 if (!strcmp((char *) key->data.scalar.value, "children"))
629 children = value;
632 if (!children)
633 n = 0;
634 else
635 n = children->data.sequence.items.top -
636 children->data.sequence.items.start;
638 tree = pet_tree_new_block(ctx, block, n);
639 if (!children)
640 return tree;
642 for (item = children->data.sequence.items.start, i = 0;
643 item < children->data.sequence.items.top; ++item, ++i) {
644 yaml_node_t *n;
645 pet_tree *child;
647 n = yaml_document_get_node(document, *item);
648 child = extract_tree(ctx, document, n);
649 tree = pet_tree_block_add_child(tree, child);
652 return tree;
655 /* Extract a pet_tree of type pet_tree_decl from "node".
657 static __isl_give pet_tree *extract_tree_decl(isl_ctx *ctx,
658 yaml_document_t *document, yaml_node_t *node)
660 yaml_node_pair_t *pair;
661 pet_expr *var = NULL;
663 for (pair = node->data.mapping.pairs.start;
664 pair < node->data.mapping.pairs.top; ++pair) {
665 yaml_node_t *key, *value;
667 key = yaml_document_get_node(document, pair->key);
668 value = yaml_document_get_node(document, pair->value);
670 if (key->type != YAML_SCALAR_NODE)
671 isl_die(ctx, isl_error_invalid, "expecting scalar key",
672 return NULL);
674 if (!strcmp((char *) key->data.scalar.value, "variable")) {
675 var = extract_expr(ctx, document, value);
676 if (!var)
677 return NULL;
681 if (!var)
682 isl_die(ctx, isl_error_invalid,
683 "no variable field", return NULL);
685 return pet_tree_new_decl(var);
688 /* Extract a pet_tree of type pet_tree_decl_init from "node".
690 static __isl_give pet_tree *extract_tree_decl_init(isl_ctx *ctx,
691 yaml_document_t *document, yaml_node_t *node)
693 yaml_node_pair_t *pair;
694 pet_expr *var = NULL;
695 pet_expr *init = NULL;
697 for (pair = node->data.mapping.pairs.start;
698 pair < node->data.mapping.pairs.top; ++pair) {
699 yaml_node_t *key, *value;
701 key = yaml_document_get_node(document, pair->key);
702 value = yaml_document_get_node(document, pair->value);
704 if (key->type != YAML_SCALAR_NODE)
705 isl_die(ctx, isl_error_invalid, "expecting scalar key",
706 return NULL);
708 if (!strcmp((char *) key->data.scalar.value, "variable")) {
709 var = extract_expr(ctx, document, value);
710 if (!var)
711 goto error;
713 if (!strcmp((char *) key->data.scalar.value,
714 "initialization")) {
715 init = extract_expr(ctx, document, value);
716 if (!init)
717 goto error;
721 if (!var)
722 isl_die(ctx, isl_error_invalid,
723 "no variable field", goto error);
724 if (!init)
725 isl_die(ctx, isl_error_invalid,
726 "no initialization field", goto error);
728 return pet_tree_new_decl_init(var, init);
729 error:
730 pet_expr_free(var);
731 pet_expr_free(init);
732 return NULL;
735 /* Extract a pet_tree of type pet_tree_expr from "node".
737 static __isl_give pet_tree *extract_tree_expr(isl_ctx *ctx,
738 yaml_document_t *document, yaml_node_t *node)
740 yaml_node_pair_t *pair;
741 pet_expr *expr = NULL;
743 for (pair = node->data.mapping.pairs.start;
744 pair < node->data.mapping.pairs.top; ++pair) {
745 yaml_node_t *key, *value;
747 key = yaml_document_get_node(document, pair->key);
748 value = yaml_document_get_node(document, pair->value);
750 if (key->type != YAML_SCALAR_NODE)
751 isl_die(ctx, isl_error_invalid, "expecting scalar key",
752 return NULL);
754 if (!strcmp((char *) key->data.scalar.value, "expr")) {
755 expr = extract_expr(ctx, document, value);
756 if (!expr)
757 return NULL;
761 if (!expr)
762 isl_die(ctx, isl_error_invalid,
763 "no expr field", return NULL);
765 return pet_tree_new_expr(expr);
768 /* Extract a pet_tree of type pet_tree_while from "node".
770 static __isl_give pet_tree *extract_tree_while(isl_ctx *ctx,
771 yaml_document_t *document, yaml_node_t *node)
773 yaml_node_pair_t *pair;
774 pet_expr *cond = NULL;
775 pet_tree *body = NULL;
777 for (pair = node->data.mapping.pairs.start;
778 pair < node->data.mapping.pairs.top; ++pair) {
779 yaml_node_t *key, *value;
781 key = yaml_document_get_node(document, pair->key);
782 value = yaml_document_get_node(document, pair->value);
784 if (key->type != YAML_SCALAR_NODE)
785 isl_die(ctx, isl_error_invalid, "expecting scalar key",
786 return NULL);
788 if (!strcmp((char *) key->data.scalar.value, "condition")) {
789 cond = extract_expr(ctx, document, value);
790 if (!cond)
791 goto error;
793 if (!strcmp((char *) key->data.scalar.value, "body")) {
794 body = extract_tree(ctx, document, value);
795 if (!body)
796 goto error;
800 if (!cond)
801 isl_die(ctx, isl_error_invalid,
802 "no condition field", goto error);
803 if (!body)
804 isl_die(ctx, isl_error_invalid,
805 "no body field", goto error);
807 return pet_tree_new_while(cond, body);
808 error:
809 pet_expr_free(cond);
810 pet_tree_free(body);
811 return NULL;
814 /* Extract a pet_tree of type pet_tree_infinite_loop from "node".
816 static __isl_give pet_tree *extract_tree_infinite_loop(isl_ctx *ctx,
817 yaml_document_t *document, yaml_node_t *node)
819 yaml_node_pair_t *pair;
820 pet_tree *body;
822 for (pair = node->data.mapping.pairs.start;
823 pair < node->data.mapping.pairs.top; ++pair) {
824 yaml_node_t *key, *value;
826 key = yaml_document_get_node(document, pair->key);
827 value = yaml_document_get_node(document, pair->value);
829 if (key->type != YAML_SCALAR_NODE)
830 isl_die(ctx, isl_error_invalid, "expecting scalar key",
831 return NULL);
833 if (!strcmp((char *) key->data.scalar.value, "body")) {
834 body = extract_tree(ctx, document, value);
835 if (!body)
836 return NULL;
840 if (!body)
841 isl_die(ctx, isl_error_invalid,
842 "no body field", return NULL);
844 return pet_tree_new_infinite_loop(body);
847 /* Extract a pet_tree of type pet_tree_if from "node".
849 static __isl_give pet_tree *extract_tree_if(isl_ctx *ctx,
850 yaml_document_t *document, yaml_node_t *node)
852 yaml_node_pair_t *pair;
853 pet_expr *cond = NULL;
854 pet_tree *then_body = NULL;
856 for (pair = node->data.mapping.pairs.start;
857 pair < node->data.mapping.pairs.top; ++pair) {
858 yaml_node_t *key, *value;
860 key = yaml_document_get_node(document, pair->key);
861 value = yaml_document_get_node(document, pair->value);
863 if (key->type != YAML_SCALAR_NODE)
864 isl_die(ctx, isl_error_invalid, "expecting scalar key",
865 return NULL);
867 if (!strcmp((char *) key->data.scalar.value, "condition")) {
868 cond = extract_expr(ctx, document, value);
869 if (!cond)
870 goto error;
872 if (!strcmp((char *) key->data.scalar.value, "then")) {
873 then_body = extract_tree(ctx, document, value);
874 if (!then_body)
875 goto error;
879 if (!cond)
880 isl_die(ctx, isl_error_invalid,
881 "no condition field", goto error);
882 if (!then_body)
883 isl_die(ctx, isl_error_invalid,
884 "no then body", goto error);
886 return pet_tree_new_if(cond, then_body);
887 error:
888 pet_expr_free(cond);
889 pet_tree_free(then_body);
890 return NULL;
893 /* Extract a pet_tree of type pet_tree_if_else from "node".
895 static __isl_give pet_tree *extract_tree_if_else(isl_ctx *ctx,
896 yaml_document_t *document, yaml_node_t *node)
898 yaml_node_pair_t *pair;
899 pet_expr *cond = NULL;
900 pet_tree *then_body = NULL;
901 pet_tree *else_body = NULL;
903 for (pair = node->data.mapping.pairs.start;
904 pair < node->data.mapping.pairs.top; ++pair) {
905 yaml_node_t *key, *value;
907 key = yaml_document_get_node(document, pair->key);
908 value = yaml_document_get_node(document, pair->value);
910 if (key->type != YAML_SCALAR_NODE)
911 isl_die(ctx, isl_error_invalid, "expecting scalar key",
912 return NULL);
914 if (!strcmp((char *) key->data.scalar.value, "condition")) {
915 cond = extract_expr(ctx, document, value);
916 if (!cond)
917 goto error;
919 if (!strcmp((char *) key->data.scalar.value, "then")) {
920 then_body = extract_tree(ctx, document, value);
921 if (!then_body)
922 goto error;
924 if (!strcmp((char *) key->data.scalar.value, "else")) {
925 else_body = extract_tree(ctx, document, value);
926 if (!else_body)
927 goto error;
931 if (!cond)
932 isl_die(ctx, isl_error_invalid,
933 "no condition field", goto error);
934 if (!then_body)
935 isl_die(ctx, isl_error_invalid,
936 "no then body", goto error);
937 if (!else_body)
938 isl_die(ctx, isl_error_invalid,
939 "no else body", goto error);
941 return pet_tree_new_if_else(cond, then_body, else_body);
942 error:
943 pet_expr_free(cond);
944 pet_tree_free(then_body);
945 pet_tree_free(else_body);
946 return NULL;
949 /* Extract a pet_tree of type pet_tree_for from "node".
951 static __isl_give pet_tree *extract_tree_for(isl_ctx *ctx,
952 yaml_document_t *document, yaml_node_t *node)
954 yaml_node_pair_t *pair;
955 int declared = 0;
956 pet_expr *iv = NULL;
957 pet_expr *init = NULL;
958 pet_expr *cond = NULL;
959 pet_expr *inc = NULL;
960 pet_tree *body = NULL;
962 for (pair = node->data.mapping.pairs.start;
963 pair < node->data.mapping.pairs.top; ++pair) {
964 yaml_node_t *key, *value;
966 key = yaml_document_get_node(document, pair->key);
967 value = yaml_document_get_node(document, pair->value);
969 if (key->type != YAML_SCALAR_NODE)
970 isl_die(ctx, isl_error_invalid, "expecting scalar key",
971 return NULL);
973 if (!strcmp((char *) key->data.scalar.value, "declared"))
974 declared = extract_int(ctx, document, value);
975 if (!strcmp((char *) key->data.scalar.value, "variable")) {
976 iv = extract_expr(ctx, document, value);
977 if (!iv)
978 goto error;
980 if (!strcmp((char *) key->data.scalar.value,
981 "initialization")) {
982 init = extract_expr(ctx, document, value);
983 if (!init)
984 goto error;
986 if (!strcmp((char *) key->data.scalar.value, "condition")) {
987 cond = extract_expr(ctx, document, value);
988 if (!cond)
989 goto error;
991 if (!strcmp((char *) key->data.scalar.value, "increment")) {
992 inc = extract_expr(ctx, document, value);
993 if (!inc)
994 goto error;
996 if (!strcmp((char *) key->data.scalar.value, "body")) {
997 body = extract_tree(ctx, document, value);
998 if (!body)
999 goto error;
1003 if (!iv)
1004 isl_die(ctx, isl_error_invalid,
1005 "no variable field", goto error);
1006 if (!init)
1007 isl_die(ctx, isl_error_invalid,
1008 "no initialization field", goto error);
1009 if (!cond)
1010 isl_die(ctx, isl_error_invalid,
1011 "no condition field", goto error);
1012 if (!inc)
1013 isl_die(ctx, isl_error_invalid,
1014 "no increment field", goto error);
1015 if (!body)
1016 isl_die(ctx, isl_error_invalid,
1017 "no body field", goto error);
1019 return pet_tree_new_for(declared, iv, init, cond, inc, body);
1020 error:
1021 pet_expr_free(iv);
1022 pet_expr_free(init);
1023 pet_expr_free(cond);
1024 pet_expr_free(inc);
1025 pet_tree_free(body);
1026 return NULL;
1029 /* Extract a pet_tree from "node".
1031 * We first extract the type of the pet_tree and then call
1032 * the appropriate function to extract and construct a pet_tree
1033 * of that type.
1035 static __isl_give pet_tree *extract_tree(isl_ctx *ctx,
1036 yaml_document_t *document, yaml_node_t *node)
1038 enum pet_tree_type type = pet_tree_error;
1039 pet_tree *tree;
1040 yaml_node_pair_t *pair;
1042 if (node->type != YAML_MAPPING_NODE)
1043 isl_die(ctx, isl_error_invalid, "expecting mapping",
1044 return NULL);
1046 for (pair = node->data.mapping.pairs.start;
1047 pair < node->data.mapping.pairs.top; ++pair) {
1048 yaml_node_t *key, *value;
1050 key = yaml_document_get_node(document, pair->key);
1051 value = yaml_document_get_node(document, pair->value);
1053 if (key->type != YAML_SCALAR_NODE)
1054 isl_die(ctx, isl_error_invalid, "expecting scalar key",
1055 return pet_tree_free(tree));
1057 if (!strcmp((char *) key->data.scalar.value, "type"))
1058 type = extract_tree_type(ctx, document, value);
1061 if (type == pet_tree_error)
1062 isl_die(ctx, isl_error_invalid, "cannot determine type",
1063 return NULL);
1065 switch (type) {
1066 case pet_tree_error:
1067 return NULL;
1068 case pet_tree_block:
1069 tree = extract_tree_block(ctx, document, node);
1070 break;
1071 case pet_tree_break:
1072 tree = pet_tree_new_break(ctx);
1073 break;
1074 case pet_tree_continue:
1075 tree = pet_tree_new_continue(ctx);
1076 break;
1077 case pet_tree_decl:
1078 tree = extract_tree_decl(ctx, document, node);
1079 break;
1080 case pet_tree_decl_init:
1081 tree = extract_tree_decl_init(ctx, document, node);
1082 break;
1083 case pet_tree_expr:
1084 tree = extract_tree_expr(ctx, document, node);
1085 break;
1086 case pet_tree_for:
1087 tree = extract_tree_for(ctx, document, node);
1088 break;
1089 case pet_tree_while:
1090 tree = extract_tree_while(ctx, document, node);
1091 break;
1092 case pet_tree_infinite_loop:
1093 tree = extract_tree_infinite_loop(ctx, document, node);
1094 break;
1095 case pet_tree_if:
1096 tree = extract_tree_if(ctx, document, node);
1097 break;
1098 case pet_tree_if_else:
1099 tree = extract_tree_if_else(ctx, document, node);
1100 break;
1103 return tree;
1106 static struct pet_stmt *extract_stmt_arguments(isl_ctx *ctx,
1107 yaml_document_t *document, yaml_node_t *node, struct pet_stmt *stmt)
1109 int i;
1110 yaml_node_item_t *item;
1112 if (node->type != YAML_SEQUENCE_NODE)
1113 isl_die(ctx, isl_error_invalid, "expecting sequence",
1114 return pet_stmt_free(stmt));
1116 stmt->n_arg = node->data.sequence.items.top
1117 - node->data.sequence.items.start;
1118 stmt->args = isl_calloc_array(ctx, pet_expr *, stmt->n_arg);
1119 if (!stmt->args)
1120 return pet_stmt_free(stmt);
1122 for (item = node->data.sequence.items.start, i = 0;
1123 item < node->data.sequence.items.top; ++item, ++i) {
1124 yaml_node_t *n;
1126 n = yaml_document_get_node(document, *item);
1127 stmt->args[i] = extract_expr(ctx, document, n);
1128 if (!stmt->args[i])
1129 return pet_stmt_free(stmt);
1132 return stmt;
1135 static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document,
1136 yaml_node_t *node)
1138 struct pet_stmt *stmt;
1139 yaml_node_pair_t * pair;
1140 int line = -1;
1141 unsigned start = 0, end = 0;
1142 char *indent = NULL;
1144 if (node->type != YAML_MAPPING_NODE)
1145 isl_die(ctx, isl_error_invalid, "expecting mapping",
1146 return NULL);
1148 stmt = isl_calloc_type(ctx, struct pet_stmt);
1149 if (!stmt)
1150 return NULL;
1152 stmt->loc = &pet_loc_dummy;
1154 for (pair = node->data.mapping.pairs.start;
1155 pair < node->data.mapping.pairs.top; ++pair) {
1156 yaml_node_t *key, *value;
1158 key = yaml_document_get_node(document, pair->key);
1159 value = yaml_document_get_node(document, pair->value);
1161 if (key->type != YAML_SCALAR_NODE)
1162 isl_die(ctx, isl_error_invalid, "expecting scalar key",
1163 return pet_stmt_free(stmt));
1165 if (!strcmp((char *) key->data.scalar.value, "indent"))
1166 indent = extract_string(ctx, document, value);
1167 if (!strcmp((char *) key->data.scalar.value, "line"))
1168 line = extract_int(ctx, document, value);
1169 if (!strcmp((char *) key->data.scalar.value, "start"))
1170 start = extract_int(ctx, document, value);
1171 if (!strcmp((char *) key->data.scalar.value, "end"))
1172 end = extract_int(ctx, document, value);
1173 if (!strcmp((char *) key->data.scalar.value, "domain"))
1174 stmt->domain = extract_set(ctx, document, value);
1175 if (!strcmp((char *) key->data.scalar.value, "schedule"))
1176 stmt->schedule = extract_map(ctx, document, value);
1177 if (!strcmp((char *) key->data.scalar.value, "body"))
1178 stmt->body = extract_tree(ctx, document, value);
1180 if (!strcmp((char *) key->data.scalar.value, "arguments"))
1181 stmt = extract_stmt_arguments(ctx, document,
1182 value, stmt);
1183 if (!stmt)
1184 return NULL;
1187 if (!indent)
1188 indent = strdup("");
1189 stmt->loc = pet_loc_alloc(ctx, start, end, line, indent);
1190 if (!stmt->loc)
1191 return pet_stmt_free(stmt);
1193 return stmt;
1196 static struct pet_scop *extract_statements(isl_ctx *ctx,
1197 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
1199 int i;
1200 yaml_node_item_t *item;
1202 if (node->type != YAML_SEQUENCE_NODE)
1203 isl_die(ctx, isl_error_invalid, "expecting sequence",
1204 return NULL);
1206 scop->n_stmt = node->data.sequence.items.top
1207 - node->data.sequence.items.start;
1208 scop->stmts = isl_calloc_array(ctx, struct pet_stmt *, scop->n_stmt);
1209 if (!scop->stmts)
1210 return pet_scop_free(scop);
1212 for (item = node->data.sequence.items.start, i = 0;
1213 item < node->data.sequence.items.top; ++item, ++i) {
1214 yaml_node_t *n;
1216 n = yaml_document_get_node(document, *item);
1217 scop->stmts[i] = extract_stmt(ctx, document, n);
1218 if (!scop->stmts[i])
1219 return pet_scop_free(scop);
1222 return scop;
1225 /* Extract a pet_implication from "node".
1227 static struct pet_implication *extract_implication(isl_ctx *ctx,
1228 yaml_document_t *document, yaml_node_t *node)
1230 struct pet_implication *implication;
1231 yaml_node_pair_t * pair;
1233 if (node->type != YAML_MAPPING_NODE)
1234 isl_die(ctx, isl_error_invalid, "expecting mapping",
1235 return NULL);
1237 implication = isl_calloc_type(ctx, struct pet_implication);
1238 if (!implication)
1239 return NULL;
1241 for (pair = node->data.mapping.pairs.start;
1242 pair < node->data.mapping.pairs.top; ++pair) {
1243 yaml_node_t *key, *value;
1245 key = yaml_document_get_node(document, pair->key);
1246 value = yaml_document_get_node(document, pair->value);
1248 if (key->type != YAML_SCALAR_NODE)
1249 isl_die(ctx, isl_error_invalid, "expecting scalar key",
1250 return pet_implication_free(implication));
1252 if (!strcmp((char *) key->data.scalar.value, "satisfied"))
1253 implication->satisfied =
1254 extract_int(ctx, document, value);
1255 if (!strcmp((char *) key->data.scalar.value, "extension"))
1256 implication->extension =
1257 extract_map(ctx, document, value);
1260 return implication;
1263 /* Extract a sequence of implications from "node" and
1264 * store them in scop->implications.
1266 static struct pet_scop *extract_implications(isl_ctx *ctx,
1267 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
1269 int i;
1270 yaml_node_item_t *item;
1272 if (node->type != YAML_SEQUENCE_NODE)
1273 isl_die(ctx, isl_error_invalid, "expecting sequence",
1274 return NULL);
1276 scop->n_implication = node->data.sequence.items.top
1277 - node->data.sequence.items.start;
1278 scop->implications = isl_calloc_array(ctx, struct pet_implication *,
1279 scop->n_implication);
1280 if (!scop->implications)
1281 return pet_scop_free(scop);
1283 for (item = node->data.sequence.items.start, i = 0;
1284 item < node->data.sequence.items.top; ++item, ++i) {
1285 yaml_node_t *n;
1287 n = yaml_document_get_node(document, *item);
1288 scop->implications[i] = extract_implication(ctx, document, n);
1289 if (!scop->implications[i])
1290 return pet_scop_free(scop);
1293 return scop;
1296 static struct pet_scop *extract_scop(isl_ctx *ctx, yaml_document_t *document,
1297 yaml_node_t *node)
1299 struct pet_scop *scop;
1300 yaml_node_pair_t * pair;
1302 if (!node)
1303 return NULL;
1305 if (node->type != YAML_MAPPING_NODE)
1306 isl_die(ctx, isl_error_invalid, "expecting mapping",
1307 return NULL);
1309 scop = pet_scop_alloc(ctx);
1310 if (!scop)
1311 return NULL;
1313 for (pair = node->data.mapping.pairs.start;
1314 pair < node->data.mapping.pairs.top; ++pair) {
1315 yaml_node_t *key, *value;
1317 key = yaml_document_get_node(document, pair->key);
1318 value = yaml_document_get_node(document, pair->value);
1320 if (key->type != YAML_SCALAR_NODE)
1321 isl_die(ctx, isl_error_invalid, "expecting scalar key",
1322 return pet_scop_free(scop));
1323 if (!strcmp((char *) key->data.scalar.value, "context"))
1324 scop->context = extract_set(ctx, document, value);
1325 if (!strcmp((char *) key->data.scalar.value, "context_value"))
1326 scop->context_value = extract_set(ctx, document, value);
1327 if (!strcmp((char *) key->data.scalar.value, "types"))
1328 scop = extract_types(ctx, document, value, scop);
1329 if (!strcmp((char *) key->data.scalar.value, "arrays"))
1330 scop = extract_arrays(ctx, document, value, scop);
1331 if (!strcmp((char *) key->data.scalar.value, "statements"))
1332 scop = extract_statements(ctx, document, value, scop);
1333 if (!strcmp((char *) key->data.scalar.value, "implications"))
1334 scop = extract_implications(ctx, document, value, scop);
1335 if (!scop)
1336 return NULL;
1339 if (!scop->context_value) {
1340 isl_space *space = isl_space_params_alloc(ctx, 0);
1341 scop->context_value = isl_set_universe(space);
1342 if (!scop->context_value)
1343 return pet_scop_free(scop);
1346 return scop;
1349 /* Extract a pet_scop from the YAML description in "in".
1351 struct pet_scop *pet_scop_parse(isl_ctx *ctx, FILE *in)
1353 struct pet_scop *scop = NULL;
1354 yaml_parser_t parser;
1355 yaml_node_t *root;
1356 yaml_document_t document = { 0 };
1358 yaml_parser_initialize(&parser);
1360 yaml_parser_set_input_file(&parser, in);
1362 if (!yaml_parser_load(&parser, &document))
1363 goto error;
1365 root = yaml_document_get_root_node(&document);
1367 scop = extract_scop(ctx, &document, root);
1369 yaml_document_delete(&document);
1371 yaml_parser_delete(&parser);
1373 return scop;
1374 error:
1375 yaml_parser_delete(&parser);
1376 pet_scop_free(scop);
1377 return NULL;