isl_pw_qpolynomial_upper_bound: set up variable vector after lifting
[barvinok.git] / iscc.c
blob426cab3b3186a158c308dceb779040bfa291449f
1 #include <assert.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <isl_obj.h>
5 #include <isl_stream.h>
6 #include <isl_obj_list.h>
7 #include <barvinok/barvinok.h>
9 #include "config.h"
10 #ifdef HAVE_GINAC
11 #include <barvinok/bernstein.h>
12 #endif
14 static int isl_bool_false = 0;
15 static int isl_bool_true = 1;
16 static int isl_bool_error = -1;
18 static void *isl_obj_bool_copy(void *v)
20 return v;
23 static void isl_obj_bool_free(void *v)
27 static void isl_obj_bool_print(void *v, FILE *out)
29 if (v == &isl_bool_true)
30 fprintf(out, "True");
31 else if (v == &isl_bool_false)
32 fprintf(out, "False");
33 else
34 fprintf(out, "Error");
37 static void *isl_obj_bool_add(void *v1, void *v2)
39 return v1;
42 struct isl_obj_vtable isl_obj_bool_vtable = {
43 isl_obj_bool_copy,
44 isl_obj_bool_add,
45 isl_obj_bool_print,
46 isl_obj_bool_free
48 #define isl_obj_bool (&isl_obj_bool_vtable)
50 int *isl_bool_from_int(int res)
52 return res < 0 ? &isl_bool_error : res ? &isl_bool_true : &isl_bool_false;
55 int *map_is_equal(__isl_take isl_map *map1, __isl_take isl_map *map2)
57 int res = isl_map_is_equal(map1, map2);
58 isl_map_free(map1);
59 isl_map_free(map2);
60 return isl_bool_from_int(res);
62 int *set_is_equal(__isl_take isl_set *set1, __isl_take isl_set *set2)
64 return map_is_equal((isl_map *)set1, (isl_map *)set2);
67 int *map_is_subset(__isl_take isl_map *map1, __isl_take isl_map *map2)
69 int res = isl_map_is_subset(map1, map2);
70 isl_map_free(map1);
71 isl_map_free(map2);
72 return isl_bool_from_int(res);
74 int *set_is_subset(__isl_take isl_set *set1, __isl_take isl_set *set2)
76 return map_is_subset((isl_map *)set1, (isl_map *)set2);
79 int *map_is_strict_subset(__isl_take isl_map *map1, __isl_take isl_map *map2)
81 int res = isl_map_is_strict_subset(map1, map2);
82 isl_map_free(map1);
83 isl_map_free(map2);
84 return isl_bool_from_int(res);
86 int *set_is_strict_subset(__isl_take isl_set *set1, __isl_take isl_set *set2)
88 return map_is_strict_subset((isl_map *)set1, (isl_map *)set2);
91 int *map_is_superset(__isl_take isl_map *map1, __isl_take isl_map *map2)
93 return map_is_subset(map2, map1);
95 int *set_is_superset(__isl_take isl_set *set1, __isl_take isl_set *set2)
97 return set_is_subset(set2, set1);
100 int *map_is_strict_superset(__isl_take isl_map *map1, __isl_take isl_map *map2)
102 return map_is_strict_subset(map2, map1);
104 int *set_is_strict_superset(__isl_take isl_set *set1, __isl_take isl_set *set2)
106 return set_is_strict_subset(set2, set1);
109 extern struct isl_obj_vtable isl_obj_list_vtable;
110 #define isl_obj_list (&isl_obj_list_vtable)
112 typedef void *(*isc_bin_op_fn)(void *lhs, void *rhs);
113 struct isc_bin_op {
114 enum isl_token_type op;
115 isl_obj_type lhs;
116 isl_obj_type rhs;
117 isl_obj_type res;
118 isc_bin_op_fn fn;
121 struct iscc_at {
122 isl_pw_qpolynomial *pwqp;
123 isl_pw_qpolynomial *res;
126 static int eval_at(__isl_take isl_point *pnt, void *user)
128 struct iscc_at *at = (struct iscc_at *) user;
129 isl_qpolynomial *qp;
130 isl_set *set;
132 set = isl_set_from_point(isl_point_copy(pnt));
133 qp = isl_pw_qpolynomial_eval(isl_pw_qpolynomial_copy(at->pwqp), pnt);
135 at->res = isl_pw_qpolynomial_add_disjoint(at->res,
136 isl_pw_qpolynomial_alloc(set, qp));
138 return 0;
141 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_at(
142 __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_set *set)
144 struct iscc_at at;
146 at.pwqp = pwqp;
147 at.res = isl_pw_qpolynomial_zero(isl_set_get_dim(set));
149 isl_set_foreach_point(set, eval_at, &at);
151 isl_pw_qpolynomial_free(pwqp);
152 isl_set_free(set);
154 return at.res;
157 struct iscc_fold_at {
158 isl_pw_qpolynomial_fold *pwf;
159 isl_pw_qpolynomial *res;
162 static int eval_fold_at(__isl_take isl_point *pnt, void *user)
164 struct iscc_fold_at *at = (struct iscc_fold_at *) user;
165 isl_qpolynomial *qp;
166 isl_set *set;
168 set = isl_set_from_point(isl_point_copy(pnt));
169 qp = isl_pw_qpolynomial_fold_eval(isl_pw_qpolynomial_fold_copy(at->pwf),
170 pnt);
172 at->res = isl_pw_qpolynomial_add_disjoint(at->res,
173 isl_pw_qpolynomial_alloc(set, qp));
175 return 0;
178 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_fold_at(
179 __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set)
181 struct iscc_fold_at at;
183 at.pwf = pwf;
184 at.res = isl_pw_qpolynomial_zero(isl_set_get_dim(set));
186 isl_set_foreach_point(set, eval_fold_at, &at);
188 isl_pw_qpolynomial_fold_free(pwf);
189 isl_set_free(set);
191 return at.res;
194 struct isc_bin_op bin_ops[] = {
195 { '+', isl_obj_set, isl_obj_set,
196 isl_obj_set,
197 (isc_bin_op_fn) &isl_set_union },
198 { '+', isl_obj_map, isl_obj_map,
199 isl_obj_map,
200 (isc_bin_op_fn) &isl_map_union },
201 { '-', isl_obj_set, isl_obj_set,
202 isl_obj_set,
203 (isc_bin_op_fn) &isl_set_subtract },
204 { '-', isl_obj_map, isl_obj_map,
205 isl_obj_map,
206 (isc_bin_op_fn) &isl_map_subtract },
207 { '*', isl_obj_set, isl_obj_set,
208 isl_obj_set,
209 (isc_bin_op_fn) &isl_set_intersect },
210 { '*', isl_obj_map, isl_obj_map,
211 isl_obj_map,
212 (isc_bin_op_fn) &isl_map_intersect },
213 { '*', isl_obj_map, isl_obj_set,
214 isl_obj_map,
215 (isc_bin_op_fn) &isl_map_intersect_domain },
216 { '.', isl_obj_map, isl_obj_map,
217 isl_obj_map,
218 (isc_bin_op_fn) &isl_map_apply_range },
219 { ISL_TOKEN_TO, isl_obj_set, isl_obj_set, isl_obj_map,
220 (isc_bin_op_fn) &isl_map_from_domain_and_range },
221 { '=', isl_obj_set, isl_obj_set, isl_obj_bool,
222 (isc_bin_op_fn) &set_is_equal },
223 { '=', isl_obj_map, isl_obj_map, isl_obj_bool,
224 (isc_bin_op_fn) &map_is_equal },
225 { ISL_TOKEN_LE, isl_obj_set, isl_obj_set, isl_obj_bool,
226 (isc_bin_op_fn) &set_is_subset },
227 { ISL_TOKEN_LE, isl_obj_map, isl_obj_map, isl_obj_bool,
228 (isc_bin_op_fn) &map_is_subset },
229 { ISL_TOKEN_LT, isl_obj_set, isl_obj_set, isl_obj_bool,
230 (isc_bin_op_fn) &set_is_strict_subset },
231 { ISL_TOKEN_LT, isl_obj_map, isl_obj_map, isl_obj_bool,
232 (isc_bin_op_fn) &map_is_strict_subset },
233 { ISL_TOKEN_GE, isl_obj_set, isl_obj_set, isl_obj_bool,
234 (isc_bin_op_fn) &set_is_superset },
235 { ISL_TOKEN_GE, isl_obj_map, isl_obj_map, isl_obj_bool,
236 (isc_bin_op_fn) &map_is_superset },
237 { ISL_TOKEN_GT, isl_obj_set, isl_obj_set, isl_obj_bool,
238 (isc_bin_op_fn) &set_is_strict_superset },
239 { ISL_TOKEN_GT, isl_obj_map, isl_obj_map, isl_obj_bool,
240 (isc_bin_op_fn) &map_is_strict_superset },
241 { '+', isl_obj_pw_qpolynomial, isl_obj_pw_qpolynomial,
242 isl_obj_pw_qpolynomial,
243 (isc_bin_op_fn) &isl_pw_qpolynomial_add },
244 { '-', isl_obj_pw_qpolynomial, isl_obj_pw_qpolynomial,
245 isl_obj_pw_qpolynomial,
246 (isc_bin_op_fn) &isl_pw_qpolynomial_sub },
247 { '*', isl_obj_pw_qpolynomial, isl_obj_pw_qpolynomial,
248 isl_obj_pw_qpolynomial,
249 (isc_bin_op_fn) &isl_pw_qpolynomial_mul },
250 { '*', isl_obj_pw_qpolynomial, isl_obj_set,
251 isl_obj_pw_qpolynomial,
252 (isc_bin_op_fn) &isl_pw_qpolynomial_intersect_domain },
253 { '*', isl_obj_pw_qpolynomial_fold, isl_obj_set,
254 isl_obj_pw_qpolynomial_fold,
255 (isc_bin_op_fn) &isl_pw_qpolynomial_fold_intersect_domain },
256 { '@', isl_obj_pw_qpolynomial, isl_obj_set,
257 isl_obj_pw_qpolynomial,
258 (isc_bin_op_fn) &isl_pw_qpolynomial_at },
259 { '@', isl_obj_pw_qpolynomial_fold, isl_obj_set,
260 isl_obj_pw_qpolynomial,
261 (isc_bin_op_fn) &isl_pw_qpolynomial_fold_at },
265 __isl_give isl_set *set_sample(__isl_take isl_set *set)
267 return isl_set_from_basic_set(isl_set_sample(set));
270 __isl_give isl_map *map_sample(__isl_take isl_map *map)
272 return isl_map_from_basic_map(isl_map_sample(map));
275 static __isl_give isl_set *set_affine_hull(__isl_take isl_set *set)
277 return isl_set_from_basic_set(isl_set_affine_hull(set));
280 static __isl_give isl_map *map_affine_hull(__isl_take isl_map *map)
282 return isl_map_from_basic_map(isl_map_affine_hull(map));
285 typedef void *(*isc_un_op_fn)(void *arg);
286 struct isc_un_op {
287 enum isl_token_type op;
288 isl_obj_type arg;
289 isl_obj_type res;
290 isc_un_op_fn fn;
292 struct isc_named_un_op {
293 char *name;
294 struct isc_un_op op;
296 struct isc_named_un_op named_un_ops[] = {
297 {"aff", { -1, isl_obj_map, isl_obj_map,
298 (isc_un_op_fn) &map_affine_hull } },
299 {"aff", { -1, isl_obj_set, isl_obj_set,
300 (isc_un_op_fn) &set_affine_hull } },
301 {"card", { -1, isl_obj_set, isl_obj_pw_qpolynomial,
302 (isc_un_op_fn) &isl_set_card } },
303 {"card", { -1, isl_obj_map, isl_obj_pw_qpolynomial,
304 (isc_un_op_fn) &isl_map_card } },
305 {"dom", { -1, isl_obj_map, isl_obj_set,
306 (isc_un_op_fn) &isl_map_domain } },
307 {"dom", { -1, isl_obj_pw_qpolynomial, isl_obj_set,
308 (isc_un_op_fn) &isl_pw_qpolynomial_domain } },
309 {"dom", { -1, isl_obj_pw_qpolynomial_fold, isl_obj_set,
310 (isc_un_op_fn) &isl_pw_qpolynomial_fold_domain } },
311 {"ran", { -1, isl_obj_map, isl_obj_set,
312 (isc_un_op_fn) &isl_map_range } },
313 {"lexmin", { -1, isl_obj_map, isl_obj_map,
314 (isc_un_op_fn) &isl_map_lexmin } },
315 {"lexmax", { -1, isl_obj_map, isl_obj_map,
316 (isc_un_op_fn) &isl_map_lexmax } },
317 {"lexmin", { -1, isl_obj_set, isl_obj_set,
318 (isc_un_op_fn) &isl_set_lexmin } },
319 {"lexmax", { -1, isl_obj_set, isl_obj_set,
320 (isc_un_op_fn) &isl_set_lexmax } },
321 {"sample", { -1, isl_obj_set, isl_obj_set,
322 (isc_un_op_fn) &set_sample } },
323 {"sample", { -1, isl_obj_map, isl_obj_map,
324 (isc_un_op_fn) &map_sample } },
325 {"sum", { -1, isl_obj_pw_qpolynomial, isl_obj_pw_qpolynomial,
326 (isc_un_op_fn) &isl_pw_qpolynomial_sum } },
327 #ifdef HAVE_GINAC
328 {"ub", { -1, isl_obj_pw_qpolynomial, isl_obj_pw_qpolynomial_fold,
329 (isc_un_op_fn) &isl_pw_qpolynomial_upper_bound } },
330 #endif
331 NULL
334 struct isl_named_obj {
335 char *name;
336 struct isl_obj obj;
339 static void free_obj(struct isl_obj obj)
341 obj.type->free(obj.v);
344 static int same_name(const void *entry, const void *val)
346 const struct isl_named_obj *named = (const struct isl_named_obj *)entry;
348 return !strcmp(named->name, val);
351 static int do_assign(struct isl_ctx *ctx, struct isl_hash_table *table,
352 char *name, struct isl_obj obj)
354 struct isl_hash_table_entry *entry;
355 uint32_t name_hash;
356 struct isl_named_obj *named;
358 name_hash = isl_hash_string(isl_hash_init(), name);
359 entry = isl_hash_table_find(ctx, table, name_hash, same_name, name, 1);
360 if (!entry)
361 goto error;
362 if (entry->data) {
363 named = entry->data;
364 free_obj(named->obj);
365 free(name);
366 } else {
367 named = isl_alloc_type(ctx, struct isl_named_obj);
368 if (!named)
369 goto error;
370 named->name = name;
371 entry->data = named;
373 named->obj = obj;
375 return 0;
376 error:
377 free_obj(obj);
378 free(name);
379 return -1;
382 static struct isl_obj stored_obj(struct isl_ctx *ctx,
383 struct isl_hash_table *table, char *name)
385 struct isl_obj obj = { isl_obj_none, NULL };
386 struct isl_hash_table_entry *entry;
387 uint32_t name_hash;
389 name_hash = isl_hash_string(isl_hash_init(), name);
390 entry = isl_hash_table_find(ctx, table, name_hash, same_name, name, 0);
391 if (entry) {
392 struct isl_named_obj *named;
393 named = entry->data;
394 obj = named->obj;
397 free(name);
398 obj.v = obj.type->copy(obj.v);
399 return obj;
402 static struct isc_bin_op *read_bin_op_if_available(struct isl_stream *s,
403 isl_obj_type lhs)
405 int i;
406 struct isl_token *tok;
408 tok = isl_stream_next_token(s);
409 if (!tok)
410 return NULL;
412 for (i = 0; ; ++i) {
413 if (!bin_ops[i].op)
414 break;
415 if (bin_ops[i].op != tok->type)
416 continue;
417 if (bin_ops[i].lhs != lhs)
418 continue;
420 isl_token_free(tok);
421 return &bin_ops[i];
424 isl_stream_push_token(s, tok);
426 return NULL;
429 static struct isc_un_op *read_prefix_un_op_if_available(struct isl_stream *s)
431 int i;
432 struct isl_token *tok;
434 tok = isl_stream_next_token(s);
435 if (!tok)
436 return NULL;
438 for (i = 0; ; ++i) {
439 if (!named_un_ops[i].op.op)
440 break;
441 if (named_un_ops[i].op.op != tok->type)
442 continue;
444 isl_token_free(tok);
445 return &named_un_ops[i].op;
448 isl_stream_push_token(s, tok);
450 return NULL;
453 static struct isc_un_op *find_matching_un_op(struct isc_un_op *like,
454 isl_obj_type arg)
456 int i;
458 for (i = 0; ; ++i) {
459 if (!named_un_ops[i].op.op)
460 break;
461 if (named_un_ops[i].op.op != like->op)
462 continue;
463 if (named_un_ops[i].op.arg != arg)
464 continue;
466 return &named_un_ops[i].op;
469 return NULL;
472 static int is_assign(struct isl_stream *s)
474 struct isl_token *tok;
475 struct isl_token *tok2;
476 int assign;
478 tok = isl_stream_next_token(s);
479 if (!tok)
480 return 0;
481 if (tok->type != ISL_TOKEN_IDENT) {
482 isl_stream_push_token(s, tok);
483 return 0;
486 tok2 = isl_stream_next_token(s);
487 if (!tok2) {
488 isl_stream_push_token(s, tok);
489 return 0;
491 assign = tok2->type == ISL_TOKEN_DEF;
492 isl_stream_push_token(s, tok2);
493 isl_stream_push_token(s, tok);
495 return assign;
498 static struct isl_obj read_obj(struct isl_stream *s,
499 struct isl_hash_table *table);
500 static struct isl_obj read_expr(struct isl_stream *s,
501 struct isl_hash_table *table);
503 static struct isl_obj read_un_op_expr(struct isl_stream *s,
504 struct isl_hash_table *table, struct isc_un_op *op)
506 struct isl_obj obj = { isl_obj_none, NULL };
508 obj = read_obj(s, table);
510 op = find_matching_un_op(op, obj.type);
512 isl_assert(s->ctx, op, goto error);
513 obj.v = op->fn(obj.v);
514 obj.type = op->res;
516 return obj;
517 error:
518 free_obj(obj);
519 obj.type = isl_obj_none;
520 obj.v = NULL;
521 return obj;
524 static struct isl_obj transitive_closure(struct isl_ctx *ctx, struct isl_obj obj)
526 struct isl_list *list;
527 int exact;
529 isl_assert(ctx, obj.type == isl_obj_map, goto error);
530 list = isl_list_alloc(ctx, 2);
531 if (!list)
532 goto error;
534 list->obj[0].type = isl_obj_map;
535 list->obj[0].v = isl_map_transitive_closure(obj.v, &exact);
536 list->obj[1].type = isl_obj_bool;
537 list->obj[1].v = exact ? &isl_bool_true : &isl_bool_false;
538 obj.v = list;
539 obj.type = isl_obj_list;
540 if (exact < 0 || !list->obj[0].v)
541 goto error;
543 return obj;
544 error:
545 free_obj(obj);
546 obj.type = isl_obj_none;
547 obj.v = NULL;
548 return obj;
551 static struct isl_obj obj_at_index(struct isl_stream *s, struct isl_obj obj)
553 struct isl_list *list = obj.v;
554 struct isl_token *tok;
555 int i;
557 tok = isl_stream_next_token(s);
558 if (!tok || tok->type != ISL_TOKEN_VALUE) {
559 isl_stream_error(s, tok, "expecting index");
560 if (tok)
561 isl_stream_push_token(s, tok);
562 goto error;
564 i = isl_int_get_si(tok->u.v);
565 isl_token_free(tok);
566 isl_assert(s, i < list->n, goto error);
567 if (isl_stream_eat(s, ']'))
568 goto error;
570 obj = list->obj[i];
571 obj.v = obj.type->copy(obj.v);
573 isl_list_free(list);
575 return obj;
576 error:
577 free_obj(obj);
578 obj.type = isl_obj_none;
579 obj.v = NULL;
580 return obj;
583 static struct isl_obj power(struct isl_stream *s, struct isl_obj obj)
585 struct isl_token *tok;
587 if (isl_stream_eat_if_available(s, '+'))
588 return transitive_closure(s->ctx, obj);
590 tok = isl_stream_next_token(s);
591 if (!tok || tok->type != ISL_TOKEN_VALUE || isl_int_cmp_si(tok->u.v, -1)) {
592 isl_stream_error(s, tok, "expecting -1");
593 if (tok)
594 isl_stream_push_token(s, tok);
595 goto error;
597 isl_token_free(tok);
598 isl_assert(s->ctx, obj.type == isl_obj_map, goto error);
600 obj.v = isl_map_reverse(obj.v);
601 if (!obj.v)
602 goto error;
604 return obj;
605 error:
606 free_obj(obj);
607 obj.type = isl_obj_none;
608 obj.v = NULL;
609 return obj;
612 static struct isl_obj read_obj(struct isl_stream *s,
613 struct isl_hash_table *table)
615 struct isl_obj obj = { isl_obj_none, NULL };
616 char *name = NULL;
617 struct isc_un_op *op = NULL;
619 if (isl_stream_eat_if_available(s, '(')) {
620 obj = read_expr(s, table);
621 if (isl_stream_eat(s, ')'))
622 goto error;
623 } else {
624 op = read_prefix_un_op_if_available(s);
625 if (op)
626 return read_un_op_expr(s, table, op);
628 name = isl_stream_read_ident_if_available(s);
629 if (name) {
630 obj = stored_obj(s->ctx, table, name);
631 } else {
632 obj = isl_stream_read_obj(s);
633 assert(obj.v);
637 if (isl_stream_eat_if_available(s, '^'))
638 obj = power(s, obj);
639 else if (obj.type == isl_obj_list && isl_stream_eat_if_available(s, '['))
640 obj = obj_at_index(s, obj);
642 return obj;
643 error:
644 free_obj(obj);
645 obj.type = isl_obj_none;
646 obj.v = NULL;
647 return obj;
650 static struct isc_bin_op *find_matching_bin_op(struct isc_bin_op *like,
651 isl_obj_type lhs, isl_obj_type rhs)
653 int i;
655 for (i = 0; ; ++i) {
656 if (!bin_ops[i].op)
657 break;
658 if (bin_ops[i].op != like->op)
659 continue;
660 if (bin_ops[i].lhs != lhs)
661 continue;
662 if (bin_ops[i].rhs != rhs)
663 continue;
665 return &bin_ops[i];
668 return NULL;
671 static struct isl_obj read_expr(struct isl_stream *s,
672 struct isl_hash_table *table)
674 struct isl_obj obj = { isl_obj_none, NULL };
675 struct isl_obj right_obj = { isl_obj_none, NULL };
677 obj = read_obj(s, table);
678 for (;;) {
679 struct isc_bin_op *op = NULL;
681 op = read_bin_op_if_available(s, obj.type);
682 if (!op)
683 break;
685 right_obj = read_obj(s, table);
687 op = find_matching_bin_op(op, obj.type, right_obj.type);
689 isl_assert(s->ctx, op, goto error);
690 obj.v = op->fn(obj.v, right_obj.v);
691 obj.type = op->res;
694 return obj;
695 error:
696 free_obj(right_obj);
697 free_obj(obj);
698 obj.type = isl_obj_none;
699 obj.v = NULL;
700 return obj;
703 static void read_line(struct isl_stream *s, struct isl_hash_table *table)
705 struct isl_obj obj = { isl_obj_none, NULL };
706 char *lhs = NULL;
707 int assign = 0;
708 struct isc_bin_op *op = NULL;
710 if (isl_stream_is_empty(s))
711 return;
713 assign = is_assign(s);
714 if (assign) {
715 lhs = isl_stream_read_ident_if_available(s);
716 if (isl_stream_eat(s, ISL_TOKEN_DEF))
717 goto error;
720 obj = read_expr(s, table);
721 if (obj.type == isl_obj_none || obj.v == NULL)
722 goto error;
723 if (isl_stream_eat(s, ';'))
724 goto error;
726 if (assign) {
727 if (do_assign(s->ctx, table, lhs, obj))
728 return;
729 } else {
730 obj.type->print(obj.v, stdout);
731 printf("\n");
732 free_obj(obj);
735 return;
736 error:
737 free(lhs);
738 free_obj(obj);
741 int free_cb(void *entry)
743 struct isl_named_obj *named = entry;
745 free_obj(named->obj);
746 free(named->name);
747 free(named);
749 return 0;
752 static void register_named_ops(struct isl_stream *s)
754 int i;
756 for (i = 0; ; ++i) {
757 if (!named_un_ops[i].name)
758 break;
759 named_un_ops[i].op.op = isl_stream_register_keyword(s,
760 named_un_ops[i].name);
761 assert(named_un_ops[i].op.op != ISL_TOKEN_ERROR);
765 int main(int argc, char **argv)
767 struct isl_ctx *ctx;
768 struct isl_stream *s;
769 struct isl_hash_table *table;
771 ctx = isl_ctx_alloc();
772 s = isl_stream_new_file(ctx, stdin);
773 assert(s);
774 table = isl_hash_table_alloc(ctx, 10);
775 assert(table);
777 register_named_ops(s);
779 while (!feof(stdin)) {
780 read_line(s, table);
783 isl_hash_table_foreach(ctx, table, free_cb);
784 isl_hash_table_free(ctx, table);
785 isl_stream_free(s);
786 isl_ctx_free(ctx);
788 return 0;