From: Sven Verdoolaege Date: Sun, 28 Aug 2011 15:08:00 +0000 (+0200) Subject: add isl_aff_read_from_str X-Git-Tag: isl-0.08~34 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=07e7e318c2a3e140dc9ec7c6e192069e4a9aead9;p=platform%2Fupstream%2Fisl.git add isl_aff_read_from_str Signed-off-by: Sven Verdoolaege --- diff --git a/doc/user.pod b/doc/user.pod index 11cf6a2..27722f6 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -2921,6 +2921,12 @@ the maximum of those of C and C. If only one of C or C is defined on a given cell, then the associated expression is the defined one. +An expression can be read from input using + + #include + __isl_give isl_aff *isl_aff_read_from_str( + isl_ctx *ctx, const char *str); + An expression can be printed using #include diff --git a/include/isl/aff.h b/include/isl/aff.h index 107e57a..9c5742e 100644 --- a/include/isl/aff.h +++ b/include/isl/aff.h @@ -92,6 +92,7 @@ __isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1, __isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2); +__isl_give isl_aff *isl_aff_read_from_str(isl_ctx *ctx, const char *str); __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p, __isl_keep isl_aff *aff); void isl_aff_dump(__isl_keep isl_aff *aff); diff --git a/isl_input.c b/isl_input.c index acc3662..0a4565a 100644 --- a/isl_input.c +++ b/isl_input.c @@ -2335,6 +2335,145 @@ __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_read_from_file(isl_ctx *ctx, return pwqp; } +/* Read an affine expression from "s" with domain (space) "dom". + * We call accept_affine to parse a possibly piecewise affine expression + * and then check that the result is a single affine expression on + * a universe domain. + */ +static __isl_give isl_aff *read_aff_with_dom(struct isl_stream *s, + __isl_take isl_set *dom, struct vars *v) +{ + isl_aff *aff = NULL; + isl_pw_aff *pwaff = NULL; + + if (!isl_set_plain_is_universe(dom)) + isl_die(s->ctx, isl_error_invalid, + "expecting universe domain", goto error); + + if (!isl_set_is_params(dom) && isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + + if (isl_stream_eat(s, '[')) + goto error; + + pwaff = accept_affine(s, isl_set_get_space(dom), v); + + if (isl_stream_eat(s, ']')) + goto error; + if (isl_stream_eat(s, '}')) + goto error; + + if (!pwaff) + goto error; + + if (pwaff->n != 1) + isl_die(s->ctx, isl_error_invalid, + "expecting single affine expression", goto error); + if (!isl_set_plain_is_universe(pwaff->p[0].set)) + isl_die(s->ctx, isl_error_invalid, + "expecting universe domain", goto error); + + aff = isl_aff_copy(pwaff->p[0].aff); + + vars_free(v); + isl_pw_aff_free(pwaff); + isl_set_free(dom); + return aff; +error: + vars_free(v); + isl_pw_aff_free(pwaff); + isl_set_free(dom); + return NULL; +} + +/* Is the next token an identifer not in "v"? + */ +static int next_is_fresh_ident(struct isl_stream *s, struct vars *v) +{ + int n = v->n; + int fresh; + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + fresh = tok->type == ISL_TOKEN_IDENT && vars_pos(v, tok->u.s, -1) >= n; + isl_stream_push_token(s, tok); + + vars_drop(v, v->n - n); + + return fresh; +} + +/* Read an affine expression from "s". + * We first read the domain of the affine expression, which may be + * a parameter space or a set, and then call read_aff_with_dom. + * The tricky part is that we don't know if the domain is a set or not, + * so when we are trying to read the domain, we may actually be reading + * the affine expression itself (defined on a parameter domains) + * If the tuple we are reading is named, we assume it's the domain. + * Also, if inside the tuple, the first thing we find is a nested tuple + * or a new identifier, we again assume it's the domain. + * Otherwise, we assume we are reading an affine expression. + */ +__isl_give isl_aff *isl_stream_read_aff(struct isl_stream *s) +{ + struct vars *v; + struct isl_token *tok; + isl_set *dom = NULL; + + v = vars_new(s->ctx); + if (!v) + return NULL; + + dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0)); + if (next_is_tuple(s)) { + dom = read_tuple(s, dom, isl_dim_param, v); + if (isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + } + tok = isl_stream_next_token(s); + if (!tok || tok->type != '{') { + isl_stream_error(s, tok, "expecting '{'"); + goto error; + } + isl_token_free(tok); + tok = isl_stream_next_token(s); + if (tok && (tok->type == ISL_TOKEN_IDENT || tok->is_keyword)) { + isl_stream_push_token(s, tok); + dom = read_tuple(s, dom, isl_dim_set, v); + return read_aff_with_dom(s, dom, v); + } + if (!tok || tok->type != '[') { + isl_stream_error(s, tok, "expecting '['"); + goto error; + } + if (next_is_tuple(s) || next_is_fresh_ident(s, v)) { + isl_stream_push_token(s, tok); + dom = read_tuple(s, dom, isl_dim_set, v); + } else + isl_stream_push_token(s, tok); + + return read_aff_with_dom(s, dom, v); +error: + if (tok) + isl_stream_push_token(s, tok); + vars_free(v); + isl_set_free(dom); + return NULL; +} + +__isl_give isl_aff *isl_aff_read_from_str(isl_ctx *ctx, const char *str) +{ + isl_aff *aff; + struct isl_stream *s = isl_stream_new_str(ctx, str); + if (!s) + return NULL; + aff = isl_stream_read_aff(s); + isl_stream_free(s); + return aff; +} + /* Read an isl_pw_multi_aff from "s". * We currently read a generic object and if it turns out to be a set or * a map, we convert that to an isl_pw_multi_aff.