PetScan::extract_for: rename variable "dim" to "space"
[pet.git] / parse.c
blobb239efa20a2bb4aa9cf0d3d7dd251f3e1f0ac1bc
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 int 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_map *extract_map(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_map_read_from_str(ctx, (char *) node->data.scalar.value);
110 static struct pet_array *extract_array(isl_ctx *ctx, yaml_document_t *document,
111 yaml_node_t *node)
113 struct pet_array *array;
114 yaml_node_pair_t * pair;
116 if (node->type != YAML_MAPPING_NODE)
117 isl_die(ctx, isl_error_invalid, "expecting mapping",
118 return NULL);
120 array = isl_calloc_type(ctx, struct pet_array);
121 if (!array)
122 return NULL;
124 for (pair = node->data.mapping.pairs.start;
125 pair < node->data.mapping.pairs.top; ++pair) {
126 yaml_node_t *key, *value;
128 key = yaml_document_get_node(document, pair->key);
129 value = yaml_document_get_node(document, pair->value);
131 if (key->type != YAML_SCALAR_NODE)
132 isl_die(ctx, isl_error_invalid, "expecting scalar key",
133 return pet_array_free(array));
135 if (!strcmp((char *) key->data.scalar.value, "context"))
136 array->context = extract_set(ctx, document, value);
137 if (!strcmp((char *) key->data.scalar.value, "extent"))
138 array->extent = extract_set(ctx, document, value);
139 if (!strcmp((char *) key->data.scalar.value, "value_bounds"))
140 array->value_bounds = extract_set(ctx, document, value);
141 if (!strcmp((char *) key->data.scalar.value, "element_type"))
142 array->element_type =
143 extract_string(ctx, document, value);
144 if (!strcmp((char *) key->data.scalar.value, "element_size"))
145 array->element_size = extract_int(ctx, document, value);
146 if (!strcmp((char *) key->data.scalar.value, "live_out"))
147 array->live_out = extract_int(ctx, document, value);
148 if (!strcmp((char *) key->data.scalar.value,
149 "uniquely_defined"))
150 array->uniquely_defined =
151 extract_int(ctx, document, value);
154 return array;
157 static struct pet_scop *extract_arrays(isl_ctx *ctx, yaml_document_t *document,
158 yaml_node_t *node, struct pet_scop *scop)
160 int i;
161 yaml_node_item_t *item;
163 if (node->type != YAML_SEQUENCE_NODE)
164 isl_die(ctx, isl_error_invalid, "expecting sequence",
165 return NULL);
167 scop->n_array = node->data.sequence.items.top
168 - node->data.sequence.items.start;
169 scop->arrays = isl_calloc_array(ctx, struct pet_array *, scop->n_array);
170 if (!scop->arrays)
171 return pet_scop_free(scop);
173 for (item = node->data.sequence.items.start, i = 0;
174 item < node->data.sequence.items.top; ++item, ++i) {
175 yaml_node_t *n;
177 n = yaml_document_get_node(document, *item);
178 scop->arrays[i] = extract_array(ctx, document, n);
179 if (!scop->arrays[i])
180 return pet_scop_free(scop);
183 return scop;
186 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
187 yaml_node_t *node);
189 static struct pet_expr *extract_arguments(isl_ctx *ctx,
190 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
192 int i;
193 yaml_node_item_t *item;
195 if (node->type != YAML_SEQUENCE_NODE)
196 isl_die(ctx, isl_error_invalid, "expecting sequence",
197 return pet_expr_free(expr));
199 expr->n_arg = node->data.sequence.items.top
200 - node->data.sequence.items.start;
201 expr->args = isl_calloc_array(ctx, struct pet_expr *, expr->n_arg);
202 if (!expr->args)
203 return pet_expr_free(expr);
205 for (item = node->data.sequence.items.start, i = 0;
206 item < node->data.sequence.items.top; ++item, ++i) {
207 yaml_node_t *n;
209 n = yaml_document_get_node(document, *item);
210 expr->args[i] = extract_expr(ctx, document, n);
211 if (!expr->args[i])
212 return pet_expr_free(expr);
215 return expr;
218 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
219 yaml_node_t *node)
221 struct pet_expr *expr;
222 yaml_node_pair_t * pair;
224 if (node->type != YAML_MAPPING_NODE)
225 isl_die(ctx, isl_error_invalid, "expecting mapping",
226 return NULL);
228 expr = isl_calloc_type(ctx, struct pet_expr);
229 if (!expr)
230 return NULL;
232 for (pair = node->data.mapping.pairs.start;
233 pair < node->data.mapping.pairs.top; ++pair) {
234 yaml_node_t *key, *value;
236 key = yaml_document_get_node(document, pair->key);
237 value = yaml_document_get_node(document, pair->value);
239 if (key->type != YAML_SCALAR_NODE)
240 isl_die(ctx, isl_error_invalid, "expecting scalar key",
241 return pet_expr_free(expr));
243 if (!strcmp((char *) key->data.scalar.value, "type"))
244 expr->type = extract_type(ctx, document, value);
246 if (!strcmp((char *) key->data.scalar.value, "value"))
247 expr->d = extract_double(ctx, document, value);
249 if (!strcmp((char *) key->data.scalar.value, "relation"))
250 expr->acc.access = extract_map(ctx, document, value);
251 if (!strcmp((char *) key->data.scalar.value, "read"))
252 expr->acc.read = extract_int(ctx, document, value);
253 if (!strcmp((char *) key->data.scalar.value, "write"))
254 expr->acc.write = extract_int(ctx, document, value);
256 if (!strcmp((char *) key->data.scalar.value, "operation"))
257 expr->op = extract_op(ctx, document, value);
259 if (!strcmp((char *) key->data.scalar.value, "name"))
260 expr->name = extract_string(ctx, document, value);
262 if (!strcmp((char *) key->data.scalar.value, "arguments"))
263 expr = extract_arguments(ctx, document, value, expr);
264 if (!expr)
265 return NULL;
268 return expr;
271 static struct pet_stmt *extract_stmt_arguments(isl_ctx *ctx,
272 yaml_document_t *document, yaml_node_t *node, struct pet_stmt *stmt)
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 pet_stmt_free(stmt));
281 stmt->n_arg = node->data.sequence.items.top
282 - node->data.sequence.items.start;
283 stmt->args = isl_calloc_array(ctx, struct pet_expr *, stmt->n_arg);
284 if (!stmt->args)
285 return pet_stmt_free(stmt);
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 stmt->args[i] = extract_expr(ctx, document, n);
293 if (!stmt->args[i])
294 return pet_stmt_free(stmt);
297 return stmt;
300 static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document,
301 yaml_node_t *node)
303 struct pet_stmt *stmt;
304 yaml_node_pair_t * pair;
306 if (node->type != YAML_MAPPING_NODE)
307 isl_die(ctx, isl_error_invalid, "expecting mapping",
308 return NULL);
310 stmt = isl_calloc_type(ctx, struct pet_stmt);
311 if (!stmt)
312 return NULL;
314 for (pair = node->data.mapping.pairs.start;
315 pair < node->data.mapping.pairs.top; ++pair) {
316 yaml_node_t *key, *value;
318 key = yaml_document_get_node(document, pair->key);
319 value = yaml_document_get_node(document, pair->value);
321 if (key->type != YAML_SCALAR_NODE)
322 isl_die(ctx, isl_error_invalid, "expecting scalar key",
323 return pet_stmt_free(stmt));
325 if (!strcmp((char *) key->data.scalar.value, "line"))
326 stmt->line = extract_int(ctx, document, value);
327 if (!strcmp((char *) key->data.scalar.value, "domain"))
328 stmt->domain = extract_set(ctx, document, value);
329 if (!strcmp((char *) key->data.scalar.value, "schedule"))
330 stmt->schedule = extract_map(ctx, document, value);
331 if (!strcmp((char *) key->data.scalar.value, "body"))
332 stmt->body = extract_expr(ctx, document, value);
334 if (!strcmp((char *) key->data.scalar.value, "arguments"))
335 stmt = extract_stmt_arguments(ctx, document,
336 value, stmt);
337 if (!stmt)
338 return NULL;
341 return stmt;
344 static struct pet_scop *extract_statements(isl_ctx *ctx,
345 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
347 int i;
348 yaml_node_item_t *item;
350 if (node->type != YAML_SEQUENCE_NODE)
351 isl_die(ctx, isl_error_invalid, "expecting sequence",
352 return NULL);
354 scop->n_stmt = node->data.sequence.items.top
355 - node->data.sequence.items.start;
356 scop->stmts = isl_calloc_array(ctx, struct pet_stmt *, scop->n_stmt);
357 if (!scop->stmts)
358 return pet_scop_free(scop);
360 for (item = node->data.sequence.items.start, i = 0;
361 item < node->data.sequence.items.top; ++item, ++i) {
362 yaml_node_t *n;
364 n = yaml_document_get_node(document, *item);
365 scop->stmts[i] = extract_stmt(ctx, document, n);
366 if (!scop->stmts[i])
367 return pet_scop_free(scop);
370 return scop;
373 static struct pet_scop *extract_scop(isl_ctx *ctx, yaml_document_t *document,
374 yaml_node_t *node)
376 struct pet_scop *scop;
377 yaml_node_pair_t * pair;
379 if (!node)
380 return NULL;
382 if (node->type != YAML_MAPPING_NODE)
383 isl_die(ctx, isl_error_invalid, "expecting mapping",
384 return NULL);
386 scop = isl_calloc_type(ctx, struct pet_scop);
387 if (!scop)
388 return NULL;
390 for (pair = node->data.mapping.pairs.start;
391 pair < node->data.mapping.pairs.top; ++pair) {
392 yaml_node_t *key, *value;
394 key = yaml_document_get_node(document, pair->key);
395 value = yaml_document_get_node(document, pair->value);
397 if (key->type != YAML_SCALAR_NODE)
398 isl_die(ctx, isl_error_invalid, "expecting scalar key",
399 return pet_scop_free(scop));
400 if (!strcmp((char *) key->data.scalar.value, "context"))
401 scop->context = extract_set(ctx, document, value);
402 if (!strcmp((char *) key->data.scalar.value, "context_value"))
403 scop->context_value = extract_set(ctx, document, value);
404 if (!strcmp((char *) key->data.scalar.value, "arrays"))
405 scop = extract_arrays(ctx, document, value, scop);
406 if (!strcmp((char *) key->data.scalar.value, "statements"))
407 scop = extract_statements(ctx, document, value, scop);
408 if (!scop)
409 return NULL;
412 if (!scop->context_value) {
413 isl_space *space = isl_space_params_alloc(ctx, 0);
414 scop->context_value = isl_set_universe(space);
415 if (!scop->context_value)
416 return pet_scop_free(scop);
419 return scop;
422 /* Extract a pet_scop from the YAML description in "in".
424 struct pet_scop *pet_scop_parse(isl_ctx *ctx, FILE *in)
426 struct pet_scop *scop = NULL;
427 yaml_parser_t parser;
428 yaml_node_t *root;
429 yaml_document_t document = { 0 };
431 yaml_parser_initialize(&parser);
433 yaml_parser_set_input_file(&parser, in);
435 if (!yaml_parser_load(&parser, &document))
436 goto error;
438 root = yaml_document_get_root_node(&document);
440 scop = extract_scop(ctx, &document, root);
442 yaml_document_delete(&document);
444 yaml_parser_delete(&parser);
446 return scop;
447 error:
448 yaml_parser_delete(&parser);
449 pet_scop_free(scop);
450 return NULL;