scan.cc: universally: use pet_expr_from_index
[pet.git] / parse.c
bloba68efb1d38bf2f78961bdc027b0678bef8f64533
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 static struct pet_array *extract_array(isl_ctx *ctx, yaml_document_t *document,
121 yaml_node_t *node)
123 struct pet_array *array;
124 yaml_node_pair_t * pair;
126 if (node->type != YAML_MAPPING_NODE)
127 isl_die(ctx, isl_error_invalid, "expecting mapping",
128 return NULL);
130 array = isl_calloc_type(ctx, struct pet_array);
131 if (!array)
132 return NULL;
134 for (pair = node->data.mapping.pairs.start;
135 pair < node->data.mapping.pairs.top; ++pair) {
136 yaml_node_t *key, *value;
138 key = yaml_document_get_node(document, pair->key);
139 value = yaml_document_get_node(document, pair->value);
141 if (key->type != YAML_SCALAR_NODE)
142 isl_die(ctx, isl_error_invalid, "expecting scalar key",
143 return pet_array_free(array));
145 if (!strcmp((char *) key->data.scalar.value, "context"))
146 array->context = extract_set(ctx, document, value);
147 if (!strcmp((char *) key->data.scalar.value, "extent"))
148 array->extent = extract_set(ctx, document, value);
149 if (!strcmp((char *) key->data.scalar.value, "value_bounds"))
150 array->value_bounds = extract_set(ctx, document, value);
151 if (!strcmp((char *) key->data.scalar.value, "element_type"))
152 array->element_type =
153 extract_string(ctx, document, value);
154 if (!strcmp((char *) key->data.scalar.value, "element_size"))
155 array->element_size = extract_int(ctx, document, value);
156 if (!strcmp((char *) key->data.scalar.value, "live_out"))
157 array->live_out = extract_int(ctx, document, value);
158 if (!strcmp((char *) key->data.scalar.value,
159 "uniquely_defined"))
160 array->uniquely_defined =
161 extract_int(ctx, document, value);
162 if (!strcmp((char *) key->data.scalar.value, "declared"))
163 array->declared = extract_int(ctx, document, value);
164 if (!strcmp((char *) key->data.scalar.value, "exposed"))
165 array->exposed = extract_int(ctx, document, value);
168 return array;
171 static struct pet_scop *extract_arrays(isl_ctx *ctx, yaml_document_t *document,
172 yaml_node_t *node, struct pet_scop *scop)
174 int i;
175 yaml_node_item_t *item;
177 if (node->type != YAML_SEQUENCE_NODE)
178 isl_die(ctx, isl_error_invalid, "expecting sequence",
179 return NULL);
181 scop->n_array = node->data.sequence.items.top
182 - node->data.sequence.items.start;
183 scop->arrays = isl_calloc_array(ctx, struct pet_array *, scop->n_array);
184 if (!scop->arrays)
185 return pet_scop_free(scop);
187 for (item = node->data.sequence.items.start, i = 0;
188 item < node->data.sequence.items.top; ++item, ++i) {
189 yaml_node_t *n;
191 n = yaml_document_get_node(document, *item);
192 scop->arrays[i] = extract_array(ctx, document, n);
193 if (!scop->arrays[i])
194 return pet_scop_free(scop);
197 return scop;
200 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
201 yaml_node_t *node);
203 static struct pet_expr *extract_arguments(isl_ctx *ctx,
204 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
206 int i;
207 yaml_node_item_t *item;
209 if (node->type != YAML_SEQUENCE_NODE)
210 isl_die(ctx, isl_error_invalid, "expecting sequence",
211 return pet_expr_free(expr));
213 expr->n_arg = node->data.sequence.items.top
214 - node->data.sequence.items.start;
215 expr->args = isl_calloc_array(ctx, struct pet_expr *, expr->n_arg);
216 if (!expr->args)
217 return pet_expr_free(expr);
219 for (item = node->data.sequence.items.start, i = 0;
220 item < node->data.sequence.items.top; ++item, ++i) {
221 yaml_node_t *n;
223 n = yaml_document_get_node(document, *item);
224 expr->args[i] = extract_expr(ctx, document, n);
225 if (!expr->args[i])
226 return pet_expr_free(expr);
229 return expr;
232 /* Extract pet_expr_double specific fields from "node" and
233 * update "expr" accordingly.
235 static struct pet_expr *extract_expr_double(isl_ctx *ctx,
236 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
238 yaml_node_pair_t *pair;
240 for (pair = node->data.mapping.pairs.start;
241 pair < node->data.mapping.pairs.top; ++pair) {
242 yaml_node_t *key, *value;
244 key = yaml_document_get_node(document, pair->key);
245 value = yaml_document_get_node(document, pair->value);
247 if (key->type != YAML_SCALAR_NODE)
248 isl_die(ctx, isl_error_invalid, "expecting scalar key",
249 return pet_expr_free(expr));
251 if (!strcmp((char *) key->data.scalar.value, "value"))
252 expr->d.val = extract_double(ctx, document, value);
253 if (!strcmp((char *) key->data.scalar.value, "string"))
254 expr->d.s = extract_string(ctx, document, value);
257 return expr;
260 /* Extract pet_expr_access specific fields from "node" and
261 * update "expr" accordingly.
263 static struct pet_expr *extract_expr_access(isl_ctx *ctx,
264 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
266 yaml_node_pair_t *pair;
268 for (pair = node->data.mapping.pairs.start;
269 pair < node->data.mapping.pairs.top; ++pair) {
270 yaml_node_t *key, *value;
272 key = yaml_document_get_node(document, pair->key);
273 value = yaml_document_get_node(document, pair->value);
275 if (key->type != YAML_SCALAR_NODE)
276 isl_die(ctx, isl_error_invalid, "expecting scalar key",
277 return pet_expr_free(expr));
279 if (!strcmp((char *) key->data.scalar.value, "relation"))
280 expr->acc.access = extract_map(ctx, document, value);
281 if (!strcmp((char *) key->data.scalar.value, "reference"))
282 expr->acc.ref_id = extract_id(ctx, document, value);
283 if (!strcmp((char *) key->data.scalar.value, "read"))
284 expr->acc.read = extract_int(ctx, document, value);
285 if (!strcmp((char *) key->data.scalar.value, "write"))
286 expr->acc.write = extract_int(ctx, document, value);
289 return expr;
292 /* Extract operation expression specific fields from "node" and
293 * update "expr" accordingly.
295 static struct pet_expr *extract_expr_op(isl_ctx *ctx,
296 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
298 yaml_node_pair_t *pair;
300 for (pair = node->data.mapping.pairs.start;
301 pair < node->data.mapping.pairs.top; ++pair) {
302 yaml_node_t *key, *value;
304 key = yaml_document_get_node(document, pair->key);
305 value = yaml_document_get_node(document, pair->value);
307 if (key->type != YAML_SCALAR_NODE)
308 isl_die(ctx, isl_error_invalid, "expecting scalar key",
309 return pet_expr_free(expr));
311 if (!strcmp((char *) key->data.scalar.value, "operation"))
312 expr->op = extract_op(ctx, document, value);
315 return expr;
318 /* Extract pet_expr_call specific fields from "node" and
319 * update "expr" accordingly.
321 static struct pet_expr *extract_expr_call(isl_ctx *ctx,
322 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
324 yaml_node_pair_t *pair;
326 for (pair = node->data.mapping.pairs.start;
327 pair < node->data.mapping.pairs.top; ++pair) {
328 yaml_node_t *key, *value;
330 key = yaml_document_get_node(document, pair->key);
331 value = yaml_document_get_node(document, pair->value);
333 if (key->type != YAML_SCALAR_NODE)
334 isl_die(ctx, isl_error_invalid, "expecting scalar key",
335 return pet_expr_free(expr));
337 if (!strcmp((char *) key->data.scalar.value, "name"))
338 expr->name = extract_string(ctx, document, value);
341 return expr;
344 /* Extract pet_expr_cast specific fields from "node" and
345 * update "expr" accordingly.
347 static struct pet_expr *extract_expr_cast(isl_ctx *ctx,
348 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
350 yaml_node_pair_t *pair;
352 for (pair = node->data.mapping.pairs.start;
353 pair < node->data.mapping.pairs.top; ++pair) {
354 yaml_node_t *key, *value;
356 key = yaml_document_get_node(document, pair->key);
357 value = yaml_document_get_node(document, pair->value);
359 if (key->type != YAML_SCALAR_NODE)
360 isl_die(ctx, isl_error_invalid, "expecting scalar key",
361 return pet_expr_free(expr));
363 if (!strcmp((char *) key->data.scalar.value, "type_name"))
364 expr->type_name = extract_string(ctx, document, value);
367 return expr;
370 /* Extract a pet_expr from "node".
372 * We first extract the type and arguments of the expression and
373 * then extract additional fields depending on the type.
375 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
376 yaml_node_t *node)
378 struct pet_expr *expr;
379 yaml_node_pair_t *pair;
381 if (node->type != YAML_MAPPING_NODE)
382 isl_die(ctx, isl_error_invalid, "expecting mapping",
383 return NULL);
385 expr = isl_calloc_type(ctx, struct pet_expr);
386 if (!expr)
387 return NULL;
389 for (pair = node->data.mapping.pairs.start;
390 pair < node->data.mapping.pairs.top; ++pair) {
391 yaml_node_t *key, *value;
393 key = yaml_document_get_node(document, pair->key);
394 value = yaml_document_get_node(document, pair->value);
396 if (key->type != YAML_SCALAR_NODE)
397 isl_die(ctx, isl_error_invalid, "expecting scalar key",
398 return pet_expr_free(expr));
400 if (!strcmp((char *) key->data.scalar.value, "type"))
401 expr->type = extract_type(ctx, document, value);
403 if (!strcmp((char *) key->data.scalar.value, "arguments"))
404 expr = extract_arguments(ctx, document, value, expr);
405 if (!expr)
406 return NULL;
409 switch (expr->type) {
410 case pet_expr_access:
411 expr = extract_expr_access(ctx, document, node, expr);
412 break;
413 case pet_expr_double:
414 expr = extract_expr_double(ctx, document, node, expr);
415 break;
416 case pet_expr_call:
417 expr = extract_expr_call(ctx, document, node, expr);
418 break;
419 case pet_expr_cast:
420 expr = extract_expr_cast(ctx, document, node, expr);
421 break;
422 case pet_expr_unary:
423 case pet_expr_binary:
424 case pet_expr_ternary:
425 expr = extract_expr_op(ctx, document, node, expr);
426 break;
429 return expr;
432 static struct pet_stmt *extract_stmt_arguments(isl_ctx *ctx,
433 yaml_document_t *document, yaml_node_t *node, struct pet_stmt *stmt)
435 int i;
436 yaml_node_item_t *item;
438 if (node->type != YAML_SEQUENCE_NODE)
439 isl_die(ctx, isl_error_invalid, "expecting sequence",
440 return pet_stmt_free(stmt));
442 stmt->n_arg = node->data.sequence.items.top
443 - node->data.sequence.items.start;
444 stmt->args = isl_calloc_array(ctx, struct pet_expr *, stmt->n_arg);
445 if (!stmt->args)
446 return pet_stmt_free(stmt);
448 for (item = node->data.sequence.items.start, i = 0;
449 item < node->data.sequence.items.top; ++item, ++i) {
450 yaml_node_t *n;
452 n = yaml_document_get_node(document, *item);
453 stmt->args[i] = extract_expr(ctx, document, n);
454 if (!stmt->args[i])
455 return pet_stmt_free(stmt);
458 return stmt;
461 static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document,
462 yaml_node_t *node)
464 struct pet_stmt *stmt;
465 yaml_node_pair_t * pair;
467 if (node->type != YAML_MAPPING_NODE)
468 isl_die(ctx, isl_error_invalid, "expecting mapping",
469 return NULL);
471 stmt = isl_calloc_type(ctx, struct pet_stmt);
472 if (!stmt)
473 return NULL;
475 for (pair = node->data.mapping.pairs.start;
476 pair < node->data.mapping.pairs.top; ++pair) {
477 yaml_node_t *key, *value;
479 key = yaml_document_get_node(document, pair->key);
480 value = yaml_document_get_node(document, pair->value);
482 if (key->type != YAML_SCALAR_NODE)
483 isl_die(ctx, isl_error_invalid, "expecting scalar key",
484 return pet_stmt_free(stmt));
486 if (!strcmp((char *) key->data.scalar.value, "line"))
487 stmt->line = extract_int(ctx, document, value);
488 if (!strcmp((char *) key->data.scalar.value, "domain"))
489 stmt->domain = extract_set(ctx, document, value);
490 if (!strcmp((char *) key->data.scalar.value, "schedule"))
491 stmt->schedule = extract_map(ctx, document, value);
492 if (!strcmp((char *) key->data.scalar.value, "body"))
493 stmt->body = extract_expr(ctx, document, value);
495 if (!strcmp((char *) key->data.scalar.value, "arguments"))
496 stmt = extract_stmt_arguments(ctx, document,
497 value, stmt);
498 if (!stmt)
499 return NULL;
502 return stmt;
505 static struct pet_scop *extract_statements(isl_ctx *ctx,
506 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
508 int i;
509 yaml_node_item_t *item;
511 if (node->type != YAML_SEQUENCE_NODE)
512 isl_die(ctx, isl_error_invalid, "expecting sequence",
513 return NULL);
515 scop->n_stmt = node->data.sequence.items.top
516 - node->data.sequence.items.start;
517 scop->stmts = isl_calloc_array(ctx, struct pet_stmt *, scop->n_stmt);
518 if (!scop->stmts)
519 return pet_scop_free(scop);
521 for (item = node->data.sequence.items.start, i = 0;
522 item < node->data.sequence.items.top; ++item, ++i) {
523 yaml_node_t *n;
525 n = yaml_document_get_node(document, *item);
526 scop->stmts[i] = extract_stmt(ctx, document, n);
527 if (!scop->stmts[i])
528 return pet_scop_free(scop);
531 return scop;
534 /* Extract a pet_implication from "node".
536 static struct pet_implication *extract_implication(isl_ctx *ctx,
537 yaml_document_t *document, yaml_node_t *node)
539 struct pet_implication *implication;
540 yaml_node_pair_t * pair;
542 if (node->type != YAML_MAPPING_NODE)
543 isl_die(ctx, isl_error_invalid, "expecting mapping",
544 return NULL);
546 implication = isl_calloc_type(ctx, struct pet_implication);
547 if (!implication)
548 return NULL;
550 for (pair = node->data.mapping.pairs.start;
551 pair < node->data.mapping.pairs.top; ++pair) {
552 yaml_node_t *key, *value;
554 key = yaml_document_get_node(document, pair->key);
555 value = yaml_document_get_node(document, pair->value);
557 if (key->type != YAML_SCALAR_NODE)
558 isl_die(ctx, isl_error_invalid, "expecting scalar key",
559 return pet_implication_free(implication));
561 if (!strcmp((char *) key->data.scalar.value, "satisfied"))
562 implication->satisfied =
563 extract_int(ctx, document, value);
564 if (!strcmp((char *) key->data.scalar.value, "extension"))
565 implication->extension =
566 extract_map(ctx, document, value);
569 return implication;
572 /* Extract a sequence of implications from "node" and
573 * store them in scop->implications.
575 static struct pet_scop *extract_implications(isl_ctx *ctx,
576 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
578 int i;
579 yaml_node_item_t *item;
581 if (node->type != YAML_SEQUENCE_NODE)
582 isl_die(ctx, isl_error_invalid, "expecting sequence",
583 return NULL);
585 scop->n_implication = node->data.sequence.items.top
586 - node->data.sequence.items.start;
587 scop->implications = isl_calloc_array(ctx, struct pet_implication *,
588 scop->n_implication);
589 if (!scop->implications)
590 return pet_scop_free(scop);
592 for (item = node->data.sequence.items.start, i = 0;
593 item < node->data.sequence.items.top; ++item, ++i) {
594 yaml_node_t *n;
596 n = yaml_document_get_node(document, *item);
597 scop->implications[i] = extract_implication(ctx, document, n);
598 if (!scop->implications[i])
599 return pet_scop_free(scop);
602 return scop;
605 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
606 yaml_node_t *node);
608 static struct pet_scop *extract_scop(isl_ctx *ctx, yaml_document_t *document,
609 yaml_node_t *node)
611 struct pet_scop *scop;
612 yaml_node_pair_t * pair;
614 if (!node)
615 return NULL;
617 if (node->type != YAML_MAPPING_NODE)
618 isl_die(ctx, isl_error_invalid, "expecting mapping",
619 return NULL);
621 scop = pet_scop_alloc(ctx);
622 if (!scop)
623 return NULL;
625 for (pair = node->data.mapping.pairs.start;
626 pair < node->data.mapping.pairs.top; ++pair) {
627 yaml_node_t *key, *value;
629 key = yaml_document_get_node(document, pair->key);
630 value = yaml_document_get_node(document, pair->value);
632 if (key->type != YAML_SCALAR_NODE)
633 isl_die(ctx, isl_error_invalid, "expecting scalar key",
634 return pet_scop_free(scop));
635 if (!strcmp((char *) key->data.scalar.value, "context"))
636 scop->context = extract_set(ctx, document, value);
637 if (!strcmp((char *) key->data.scalar.value, "context_value"))
638 scop->context_value = extract_set(ctx, document, value);
639 if (!strcmp((char *) key->data.scalar.value, "arrays"))
640 scop = extract_arrays(ctx, document, value, scop);
641 if (!strcmp((char *) key->data.scalar.value, "statements"))
642 scop = extract_statements(ctx, document, value, scop);
643 if (!strcmp((char *) key->data.scalar.value, "implications"))
644 scop = extract_implications(ctx, document, value, scop);
645 if (!scop)
646 return NULL;
649 if (!scop->context_value) {
650 isl_space *space = isl_space_params_alloc(ctx, 0);
651 scop->context_value = isl_set_universe(space);
652 if (!scop->context_value)
653 return pet_scop_free(scop);
656 return scop;
659 /* Extract a pet_scop from the YAML description in "in".
661 struct pet_scop *pet_scop_parse(isl_ctx *ctx, FILE *in)
663 struct pet_scop *scop = NULL;
664 yaml_parser_t parser;
665 yaml_node_t *root;
666 yaml_document_t document = { 0 };
668 yaml_parser_initialize(&parser);
670 yaml_parser_set_input_file(&parser, in);
672 if (!yaml_parser_load(&parser, &document))
673 goto error;
675 root = yaml_document_get_root_node(&document);
677 scop = extract_scop(ctx, &document, root);
679 yaml_document_delete(&document);
681 yaml_parser_delete(&parser);
683 return scop;
684 error:
685 yaml_parser_delete(&parser);
686 pet_scop_free(scop);
687 return NULL;