update isl for support for member accesses in AST
[pet.git] / parse.c
blob17928db9764ba9eada07c87a84d20b58878bdbc8
1 /*
2 * Copyright 2011 Leiden University. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * The views and conclusions contained in the software and documentation
29 * are those of the authors and should not be interpreted as
30 * representing official policies, either expressed or implied, of
31 * Leiden University.
32 */
34 #include <stdlib.h>
35 #include <yaml.h>
37 #include "scop.h"
38 #include "scop_yaml.h"
40 static char *extract_string(isl_ctx *ctx, yaml_document_t *document,
41 yaml_node_t *node)
43 if (node->type != YAML_SCALAR_NODE)
44 isl_die(ctx, isl_error_invalid, "expecting scalar node",
45 return NULL);
47 return strdup((char *) node->data.scalar.value);
50 static int extract_int(isl_ctx *ctx, yaml_document_t *document,
51 yaml_node_t *node)
53 if (node->type != YAML_SCALAR_NODE)
54 isl_die(ctx, isl_error_invalid, "expecting scalar node",
55 return -1);
57 return atoi((char *) node->data.scalar.value);
60 static double extract_double(isl_ctx *ctx, yaml_document_t *document,
61 yaml_node_t *node)
63 if (node->type != YAML_SCALAR_NODE)
64 isl_die(ctx, isl_error_invalid, "expecting scalar node",
65 return -1);
67 return strtod((char *) node->data.scalar.value, NULL);
70 static enum pet_expr_type extract_type(isl_ctx *ctx, yaml_document_t *document,
71 yaml_node_t *node)
73 if (node->type != YAML_SCALAR_NODE)
74 isl_die(ctx, isl_error_invalid, "expecting scalar node",
75 return -1);
77 return pet_str_type((char *) node->data.scalar.value);
80 static enum pet_op_type extract_op(isl_ctx *ctx, yaml_document_t *document,
81 yaml_node_t *node)
83 if (node->type != YAML_SCALAR_NODE)
84 isl_die(ctx, isl_error_invalid, "expecting scalar node",
85 return -1);
87 return pet_str_op((char *) node->data.scalar.value);
90 static __isl_give isl_set *extract_set(isl_ctx *ctx, yaml_document_t *document,
91 yaml_node_t *node)
93 if (node->type != YAML_SCALAR_NODE)
94 isl_die(ctx, isl_error_invalid, "expecting scalar node",
95 return NULL);
97 return isl_set_read_from_str(ctx, (char *) node->data.scalar.value);
100 static __isl_give isl_id *extract_id(isl_ctx *ctx, yaml_document_t *document,
101 yaml_node_t *node)
103 if (node->type != YAML_SCALAR_NODE)
104 isl_die(ctx, isl_error_invalid, "expecting scalar node",
105 return NULL);
107 return isl_id_alloc(ctx, (char *) node->data.scalar.value, NULL);
110 static __isl_give isl_map *extract_map(isl_ctx *ctx, yaml_document_t *document,
111 yaml_node_t *node)
113 if (node->type != YAML_SCALAR_NODE)
114 isl_die(ctx, isl_error_invalid, "expecting scalar node",
115 return NULL);
117 return isl_map_read_from_str(ctx, (char *) node->data.scalar.value);
120 /* Extract an isl_multi_pw_aff from "node".
122 static __isl_give isl_multi_pw_aff *extract_multi_pw_aff(isl_ctx *ctx,
123 yaml_document_t *document, yaml_node_t *node)
125 if (node->type != YAML_SCALAR_NODE)
126 isl_die(ctx, isl_error_invalid, "expecting scalar node",
127 return NULL);
129 return isl_multi_pw_aff_read_from_str(ctx,
130 (char *) node->data.scalar.value);
133 static struct pet_array *extract_array(isl_ctx *ctx, yaml_document_t *document,
134 yaml_node_t *node)
136 struct pet_array *array;
137 yaml_node_pair_t * pair;
139 if (node->type != YAML_MAPPING_NODE)
140 isl_die(ctx, isl_error_invalid, "expecting mapping",
141 return NULL);
143 array = isl_calloc_type(ctx, struct pet_array);
144 if (!array)
145 return NULL;
147 for (pair = node->data.mapping.pairs.start;
148 pair < node->data.mapping.pairs.top; ++pair) {
149 yaml_node_t *key, *value;
151 key = yaml_document_get_node(document, pair->key);
152 value = yaml_document_get_node(document, pair->value);
154 if (key->type != YAML_SCALAR_NODE)
155 isl_die(ctx, isl_error_invalid, "expecting scalar key",
156 return pet_array_free(array));
158 if (!strcmp((char *) key->data.scalar.value, "context"))
159 array->context = extract_set(ctx, document, value);
160 if (!strcmp((char *) key->data.scalar.value, "extent"))
161 array->extent = extract_set(ctx, document, value);
162 if (!strcmp((char *) key->data.scalar.value, "value_bounds"))
163 array->value_bounds = extract_set(ctx, document, value);
164 if (!strcmp((char *) key->data.scalar.value, "element_type"))
165 array->element_type =
166 extract_string(ctx, document, value);
167 if (!strcmp((char *) key->data.scalar.value, "element_size"))
168 array->element_size = extract_int(ctx, document, value);
169 if (!strcmp((char *) key->data.scalar.value, "live_out"))
170 array->live_out = extract_int(ctx, document, value);
171 if (!strcmp((char *) key->data.scalar.value,
172 "uniquely_defined"))
173 array->uniquely_defined =
174 extract_int(ctx, document, value);
175 if (!strcmp((char *) key->data.scalar.value, "declared"))
176 array->declared = extract_int(ctx, document, value);
177 if (!strcmp((char *) key->data.scalar.value, "exposed"))
178 array->exposed = extract_int(ctx, document, value);
181 return array;
184 static struct pet_scop *extract_arrays(isl_ctx *ctx, yaml_document_t *document,
185 yaml_node_t *node, struct pet_scop *scop)
187 int i;
188 yaml_node_item_t *item;
190 if (node->type != YAML_SEQUENCE_NODE)
191 isl_die(ctx, isl_error_invalid, "expecting sequence",
192 return NULL);
194 scop->n_array = node->data.sequence.items.top
195 - node->data.sequence.items.start;
196 scop->arrays = isl_calloc_array(ctx, struct pet_array *, scop->n_array);
197 if (!scop->arrays)
198 return pet_scop_free(scop);
200 for (item = node->data.sequence.items.start, i = 0;
201 item < node->data.sequence.items.top; ++item, ++i) {
202 yaml_node_t *n;
204 n = yaml_document_get_node(document, *item);
205 scop->arrays[i] = extract_array(ctx, document, n);
206 if (!scop->arrays[i])
207 return pet_scop_free(scop);
210 return scop;
213 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
214 yaml_node_t *node);
216 static struct pet_expr *extract_arguments(isl_ctx *ctx,
217 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
219 int i;
220 yaml_node_item_t *item;
222 if (node->type != YAML_SEQUENCE_NODE)
223 isl_die(ctx, isl_error_invalid, "expecting sequence",
224 return pet_expr_free(expr));
226 expr->n_arg = node->data.sequence.items.top
227 - node->data.sequence.items.start;
228 expr->args = isl_calloc_array(ctx, struct pet_expr *, expr->n_arg);
229 if (!expr->args)
230 return pet_expr_free(expr);
232 for (item = node->data.sequence.items.start, i = 0;
233 item < node->data.sequence.items.top; ++item, ++i) {
234 yaml_node_t *n;
236 n = yaml_document_get_node(document, *item);
237 expr->args[i] = extract_expr(ctx, document, n);
238 if (!expr->args[i])
239 return pet_expr_free(expr);
242 return expr;
245 /* Extract pet_expr_double specific fields from "node" and
246 * update "expr" accordingly.
248 static struct pet_expr *extract_expr_double(isl_ctx *ctx,
249 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
251 yaml_node_pair_t *pair;
253 for (pair = node->data.mapping.pairs.start;
254 pair < node->data.mapping.pairs.top; ++pair) {
255 yaml_node_t *key, *value;
257 key = yaml_document_get_node(document, pair->key);
258 value = yaml_document_get_node(document, pair->value);
260 if (key->type != YAML_SCALAR_NODE)
261 isl_die(ctx, isl_error_invalid, "expecting scalar key",
262 return pet_expr_free(expr));
264 if (!strcmp((char *) key->data.scalar.value, "value"))
265 expr->d.val = extract_double(ctx, document, value);
266 if (!strcmp((char *) key->data.scalar.value, "string"))
267 expr->d.s = extract_string(ctx, document, value);
270 return expr;
273 /* Extract pet_expr_access specific fields from "node" and
274 * update "expr" accordingly.
276 static struct pet_expr *extract_expr_access(isl_ctx *ctx,
277 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
279 yaml_node_pair_t *pair;
281 for (pair = node->data.mapping.pairs.start;
282 pair < node->data.mapping.pairs.top; ++pair) {
283 yaml_node_t *key, *value;
285 key = yaml_document_get_node(document, pair->key);
286 value = yaml_document_get_node(document, pair->value);
288 if (key->type != YAML_SCALAR_NODE)
289 isl_die(ctx, isl_error_invalid, "expecting scalar key",
290 return pet_expr_free(expr));
292 if (!strcmp((char *) key->data.scalar.value, "relation"))
293 expr->acc.access = extract_map(ctx, document, value);
294 if (!strcmp((char *) key->data.scalar.value, "index"))
295 expr->acc.index = extract_multi_pw_aff(ctx, document,
296 value);
297 if (!strcmp((char *) key->data.scalar.value, "reference"))
298 expr->acc.ref_id = extract_id(ctx, document, value);
299 if (!strcmp((char *) key->data.scalar.value, "read"))
300 expr->acc.read = extract_int(ctx, document, value);
301 if (!strcmp((char *) key->data.scalar.value, "write"))
302 expr->acc.write = extract_int(ctx, document, value);
305 return expr;
308 /* Extract operation expression specific fields from "node" and
309 * update "expr" accordingly.
311 static struct pet_expr *extract_expr_op(isl_ctx *ctx,
312 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
314 yaml_node_pair_t *pair;
316 for (pair = node->data.mapping.pairs.start;
317 pair < node->data.mapping.pairs.top; ++pair) {
318 yaml_node_t *key, *value;
320 key = yaml_document_get_node(document, pair->key);
321 value = yaml_document_get_node(document, pair->value);
323 if (key->type != YAML_SCALAR_NODE)
324 isl_die(ctx, isl_error_invalid, "expecting scalar key",
325 return pet_expr_free(expr));
327 if (!strcmp((char *) key->data.scalar.value, "operation"))
328 expr->op = extract_op(ctx, document, value);
331 return expr;
334 /* Extract pet_expr_call specific fields from "node" and
335 * update "expr" accordingly.
337 static struct pet_expr *extract_expr_call(isl_ctx *ctx,
338 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
340 yaml_node_pair_t *pair;
342 for (pair = node->data.mapping.pairs.start;
343 pair < node->data.mapping.pairs.top; ++pair) {
344 yaml_node_t *key, *value;
346 key = yaml_document_get_node(document, pair->key);
347 value = yaml_document_get_node(document, pair->value);
349 if (key->type != YAML_SCALAR_NODE)
350 isl_die(ctx, isl_error_invalid, "expecting scalar key",
351 return pet_expr_free(expr));
353 if (!strcmp((char *) key->data.scalar.value, "name"))
354 expr->name = extract_string(ctx, document, value);
357 return expr;
360 /* Extract pet_expr_cast specific fields from "node" and
361 * update "expr" accordingly.
363 static struct pet_expr *extract_expr_cast(isl_ctx *ctx,
364 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
366 yaml_node_pair_t *pair;
368 for (pair = node->data.mapping.pairs.start;
369 pair < node->data.mapping.pairs.top; ++pair) {
370 yaml_node_t *key, *value;
372 key = yaml_document_get_node(document, pair->key);
373 value = yaml_document_get_node(document, pair->value);
375 if (key->type != YAML_SCALAR_NODE)
376 isl_die(ctx, isl_error_invalid, "expecting scalar key",
377 return pet_expr_free(expr));
379 if (!strcmp((char *) key->data.scalar.value, "type_name"))
380 expr->type_name = extract_string(ctx, document, value);
383 return expr;
386 /* Extract a pet_expr from "node".
388 * We first extract the type and arguments of the expression and
389 * then extract additional fields depending on the type.
391 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
392 yaml_node_t *node)
394 struct pet_expr *expr;
395 yaml_node_pair_t *pair;
397 if (node->type != YAML_MAPPING_NODE)
398 isl_die(ctx, isl_error_invalid, "expecting mapping",
399 return NULL);
401 expr = isl_calloc_type(ctx, struct pet_expr);
402 if (!expr)
403 return NULL;
405 for (pair = node->data.mapping.pairs.start;
406 pair < node->data.mapping.pairs.top; ++pair) {
407 yaml_node_t *key, *value;
409 key = yaml_document_get_node(document, pair->key);
410 value = yaml_document_get_node(document, pair->value);
412 if (key->type != YAML_SCALAR_NODE)
413 isl_die(ctx, isl_error_invalid, "expecting scalar key",
414 return pet_expr_free(expr));
416 if (!strcmp((char *) key->data.scalar.value, "type"))
417 expr->type = extract_type(ctx, document, value);
419 if (!strcmp((char *) key->data.scalar.value, "arguments"))
420 expr = extract_arguments(ctx, document, value, expr);
421 if (!expr)
422 return NULL;
425 switch (expr->type) {
426 case pet_expr_access:
427 expr = extract_expr_access(ctx, document, node, expr);
428 break;
429 case pet_expr_double:
430 expr = extract_expr_double(ctx, document, node, expr);
431 break;
432 case pet_expr_call:
433 expr = extract_expr_call(ctx, document, node, expr);
434 break;
435 case pet_expr_cast:
436 expr = extract_expr_cast(ctx, document, node, expr);
437 break;
438 case pet_expr_unary:
439 case pet_expr_binary:
440 case pet_expr_ternary:
441 expr = extract_expr_op(ctx, document, node, expr);
442 break;
445 return expr;
448 static struct pet_stmt *extract_stmt_arguments(isl_ctx *ctx,
449 yaml_document_t *document, yaml_node_t *node, struct pet_stmt *stmt)
451 int i;
452 yaml_node_item_t *item;
454 if (node->type != YAML_SEQUENCE_NODE)
455 isl_die(ctx, isl_error_invalid, "expecting sequence",
456 return pet_stmt_free(stmt));
458 stmt->n_arg = node->data.sequence.items.top
459 - node->data.sequence.items.start;
460 stmt->args = isl_calloc_array(ctx, struct pet_expr *, stmt->n_arg);
461 if (!stmt->args)
462 return pet_stmt_free(stmt);
464 for (item = node->data.sequence.items.start, i = 0;
465 item < node->data.sequence.items.top; ++item, ++i) {
466 yaml_node_t *n;
468 n = yaml_document_get_node(document, *item);
469 stmt->args[i] = extract_expr(ctx, document, n);
470 if (!stmt->args[i])
471 return pet_stmt_free(stmt);
474 return stmt;
477 static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document,
478 yaml_node_t *node)
480 struct pet_stmt *stmt;
481 yaml_node_pair_t * pair;
483 if (node->type != YAML_MAPPING_NODE)
484 isl_die(ctx, isl_error_invalid, "expecting mapping",
485 return NULL);
487 stmt = isl_calloc_type(ctx, struct pet_stmt);
488 if (!stmt)
489 return NULL;
491 for (pair = node->data.mapping.pairs.start;
492 pair < node->data.mapping.pairs.top; ++pair) {
493 yaml_node_t *key, *value;
495 key = yaml_document_get_node(document, pair->key);
496 value = yaml_document_get_node(document, pair->value);
498 if (key->type != YAML_SCALAR_NODE)
499 isl_die(ctx, isl_error_invalid, "expecting scalar key",
500 return pet_stmt_free(stmt));
502 if (!strcmp((char *) key->data.scalar.value, "line"))
503 stmt->line = extract_int(ctx, document, value);
504 if (!strcmp((char *) key->data.scalar.value, "domain"))
505 stmt->domain = extract_set(ctx, document, value);
506 if (!strcmp((char *) key->data.scalar.value, "schedule"))
507 stmt->schedule = extract_map(ctx, document, value);
508 if (!strcmp((char *) key->data.scalar.value, "body"))
509 stmt->body = extract_expr(ctx, document, value);
511 if (!strcmp((char *) key->data.scalar.value, "arguments"))
512 stmt = extract_stmt_arguments(ctx, document,
513 value, stmt);
514 if (!stmt)
515 return NULL;
518 return stmt;
521 static struct pet_scop *extract_statements(isl_ctx *ctx,
522 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
524 int i;
525 yaml_node_item_t *item;
527 if (node->type != YAML_SEQUENCE_NODE)
528 isl_die(ctx, isl_error_invalid, "expecting sequence",
529 return NULL);
531 scop->n_stmt = node->data.sequence.items.top
532 - node->data.sequence.items.start;
533 scop->stmts = isl_calloc_array(ctx, struct pet_stmt *, scop->n_stmt);
534 if (!scop->stmts)
535 return pet_scop_free(scop);
537 for (item = node->data.sequence.items.start, i = 0;
538 item < node->data.sequence.items.top; ++item, ++i) {
539 yaml_node_t *n;
541 n = yaml_document_get_node(document, *item);
542 scop->stmts[i] = extract_stmt(ctx, document, n);
543 if (!scop->stmts[i])
544 return pet_scop_free(scop);
547 return scop;
550 /* Extract a pet_implication from "node".
552 static struct pet_implication *extract_implication(isl_ctx *ctx,
553 yaml_document_t *document, yaml_node_t *node)
555 struct pet_implication *implication;
556 yaml_node_pair_t * pair;
558 if (node->type != YAML_MAPPING_NODE)
559 isl_die(ctx, isl_error_invalid, "expecting mapping",
560 return NULL);
562 implication = isl_calloc_type(ctx, struct pet_implication);
563 if (!implication)
564 return NULL;
566 for (pair = node->data.mapping.pairs.start;
567 pair < node->data.mapping.pairs.top; ++pair) {
568 yaml_node_t *key, *value;
570 key = yaml_document_get_node(document, pair->key);
571 value = yaml_document_get_node(document, pair->value);
573 if (key->type != YAML_SCALAR_NODE)
574 isl_die(ctx, isl_error_invalid, "expecting scalar key",
575 return pet_implication_free(implication));
577 if (!strcmp((char *) key->data.scalar.value, "satisfied"))
578 implication->satisfied =
579 extract_int(ctx, document, value);
580 if (!strcmp((char *) key->data.scalar.value, "extension"))
581 implication->extension =
582 extract_map(ctx, document, value);
585 return implication;
588 /* Extract a sequence of implications from "node" and
589 * store them in scop->implications.
591 static struct pet_scop *extract_implications(isl_ctx *ctx,
592 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
594 int i;
595 yaml_node_item_t *item;
597 if (node->type != YAML_SEQUENCE_NODE)
598 isl_die(ctx, isl_error_invalid, "expecting sequence",
599 return NULL);
601 scop->n_implication = node->data.sequence.items.top
602 - node->data.sequence.items.start;
603 scop->implications = isl_calloc_array(ctx, struct pet_implication *,
604 scop->n_implication);
605 if (!scop->implications)
606 return pet_scop_free(scop);
608 for (item = node->data.sequence.items.start, i = 0;
609 item < node->data.sequence.items.top; ++item, ++i) {
610 yaml_node_t *n;
612 n = yaml_document_get_node(document, *item);
613 scop->implications[i] = extract_implication(ctx, document, n);
614 if (!scop->implications[i])
615 return pet_scop_free(scop);
618 return scop;
621 static struct pet_scop *extract_scop(isl_ctx *ctx, yaml_document_t *document,
622 yaml_node_t *node)
624 struct pet_scop *scop;
625 yaml_node_pair_t * pair;
627 if (!node)
628 return NULL;
630 if (node->type != YAML_MAPPING_NODE)
631 isl_die(ctx, isl_error_invalid, "expecting mapping",
632 return NULL);
634 scop = pet_scop_alloc(ctx);
635 if (!scop)
636 return NULL;
638 for (pair = node->data.mapping.pairs.start;
639 pair < node->data.mapping.pairs.top; ++pair) {
640 yaml_node_t *key, *value;
642 key = yaml_document_get_node(document, pair->key);
643 value = yaml_document_get_node(document, pair->value);
645 if (key->type != YAML_SCALAR_NODE)
646 isl_die(ctx, isl_error_invalid, "expecting scalar key",
647 return pet_scop_free(scop));
648 if (!strcmp((char *) key->data.scalar.value, "context"))
649 scop->context = extract_set(ctx, document, value);
650 if (!strcmp((char *) key->data.scalar.value, "context_value"))
651 scop->context_value = extract_set(ctx, document, value);
652 if (!strcmp((char *) key->data.scalar.value, "arrays"))
653 scop = extract_arrays(ctx, document, value, scop);
654 if (!strcmp((char *) key->data.scalar.value, "statements"))
655 scop = extract_statements(ctx, document, value, scop);
656 if (!strcmp((char *) key->data.scalar.value, "implications"))
657 scop = extract_implications(ctx, document, value, scop);
658 if (!scop)
659 return NULL;
662 if (!scop->context_value) {
663 isl_space *space = isl_space_params_alloc(ctx, 0);
664 scop->context_value = isl_set_universe(space);
665 if (!scop->context_value)
666 return pet_scop_free(scop);
669 return scop;
672 /* Extract a pet_scop from the YAML description in "in".
674 struct pet_scop *pet_scop_parse(isl_ctx *ctx, FILE *in)
676 struct pet_scop *scop = NULL;
677 yaml_parser_t parser;
678 yaml_node_t *root;
679 yaml_document_t document = { 0 };
681 yaml_parser_initialize(&parser);
683 yaml_parser_set_input_file(&parser, in);
685 if (!yaml_parser_load(&parser, &document))
686 goto error;
688 root = yaml_document_get_root_node(&document);
690 scop = extract_scop(ctx, &document, root);
692 yaml_document_delete(&document);
694 yaml_parser_delete(&parser);
696 return scop;
697 error:
698 yaml_parser_delete(&parser);
699 pet_scop_free(scop);
700 return NULL;