From 9cfc1c78e8b4d3f7d8a694cd5c6ea1746e8744ad Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 21 Sep 2011 14:23:46 +0200 Subject: [PATCH] add isl_pw_aff_read_from_str Signed-off-by: Sven Verdoolaege --- doc/user.pod | 2 + include/isl/aff.h | 1 + isl_input.c | 148 +++++++++++++++++++++++++++++++++++++++++++++--------- isl_test.c | 10 ++++ 4 files changed, 137 insertions(+), 24 deletions(-) diff --git a/doc/user.pod b/doc/user.pod index 27722f60..5b800fd2 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -2926,6 +2926,8 @@ An expression can be read from input using #include __isl_give isl_aff *isl_aff_read_from_str( isl_ctx *ctx, const char *str); + __isl_give isl_pw_aff *isl_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); An expression can be printed using diff --git a/include/isl/aff.h b/include/isl/aff.h index 9c5742ec..a4edf1cb 100644 --- a/include/isl/aff.h +++ b/include/isl/aff.h @@ -201,6 +201,7 @@ __isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1, __isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2); +__isl_give isl_pw_aff *isl_pw_aff_read_from_str(isl_ctx *ctx, const char *str); __isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p, __isl_keep isl_pw_aff *pwaff); void isl_pw_aff_dump(__isl_keep isl_pw_aff *pwaff); diff --git a/isl_input.c b/isl_input.c index 0a4565ae..f8df8350 100644 --- a/isl_input.c +++ b/isl_input.c @@ -2405,9 +2405,8 @@ static int next_is_fresh_ident(struct isl_stream *s, struct vars *v) 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. +/* First read the domain of the affine expression, which may be + * a parameter space or a set. * 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) @@ -2416,10 +2415,42 @@ static int next_is_fresh_ident(struct isl_stream *s, struct vars *v) * or a new identifier, we again assume it's the domain. * Otherwise, we assume we are reading an affine expression. */ +static __isl_give isl_set *read_aff_domain(struct isl_stream *s, + __isl_take isl_set *dom, struct vars *v) +{ + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (tok && (tok->type == ISL_TOKEN_IDENT || tok->is_keyword)) { + isl_stream_push_token(s, tok); + return read_tuple(s, dom, isl_dim_set, 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 dom; +error: + if (tok) + isl_stream_push_token(s, tok); + vars_free(v); + isl_set_free(dom); + return NULL; +} + +/* 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. + */ __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); @@ -2432,34 +2463,92 @@ __isl_give isl_aff *isl_stream_read_aff(struct isl_stream *s) 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 '{'"); + if (isl_stream_eat(s, '{')) goto error; + + dom = read_aff_domain(s, dom, v); + return read_aff_with_dom(s, dom, v); +error: + vars_free(v); + isl_set_free(dom); + return NULL; +} + +/* Read a piecewise affine expression from "s" with domain (space) "dom". + */ +static __isl_give isl_pw_aff *read_pw_aff_with_dom(struct isl_stream *s, + __isl_take isl_set *dom, struct vars *v) +{ + isl_pw_aff *pwaff = NULL; + + 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; + + dom = read_optional_disjuncts(s, dom, v); + pwaff = isl_pw_aff_intersect_domain(pwaff, dom); + + return pwaff; +error: + isl_set_free(dom); + isl_pw_aff_free(pwaff); + return NULL; +} + +__isl_give isl_pw_aff *isl_stream_read_pw_aff(struct isl_stream *s) +{ + struct vars *v; + isl_set *dom = NULL; + isl_set *aff_dom; + isl_pw_aff *pa = NULL; + int n; + + 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; } - 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 '['"); + if (isl_stream_eat(s, '{')) goto error; + + n = v->n; + aff_dom = read_aff_domain(s, isl_set_copy(dom), v); + pa = read_pw_aff_with_dom(s, aff_dom, v); + vars_drop(v, v->n - n); + + while (isl_stream_eat_if_available(s, ';')) { + isl_pw_aff *pa_i; + + n = v->n; + aff_dom = read_aff_domain(s, isl_set_copy(dom), v); + pa_i = read_pw_aff_with_dom(s, aff_dom, v); + vars_drop(v, v->n - n); + + pa = isl_pw_aff_add(pa, pa_i); } - 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); + if (isl_stream_eat(s, '}')) + goto error; + + vars_free(v); + isl_set_free(dom); + return pa; error: - if (tok) - isl_stream_push_token(s, tok); vars_free(v); isl_set_free(dom); + isl_pw_aff_free(pa); return NULL; } @@ -2474,6 +2563,17 @@ __isl_give isl_aff *isl_aff_read_from_str(isl_ctx *ctx, const char *str) return aff; } +__isl_give isl_pw_aff *isl_pw_aff_read_from_str(isl_ctx *ctx, const char *str) +{ + isl_pw_aff *pa; + struct isl_stream *s = isl_stream_new_str(ctx, str); + if (!s) + return NULL; + pa = isl_stream_read_pw_aff(s); + isl_stream_free(s); + return pa; +} + /* 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. diff --git a/isl_test.c b/isl_test.c index a0173b35..fdea5eee 100644 --- a/isl_test.c +++ b/isl_test.c @@ -69,6 +69,15 @@ void test_parse_pwqp(isl_ctx *ctx, const char *str) isl_pw_qpolynomial_free(pwqp); } +static void test_parse_pwaff(isl_ctx *ctx, const char *str) +{ + isl_pw_aff *pwaff; + + pwaff = isl_pw_aff_read_from_str(ctx, str); + assert(pwaff); + isl_pw_aff_free(pwaff); +} + void test_parse(struct isl_ctx *ctx) { isl_map *map, *map2; @@ -146,6 +155,7 @@ void test_parse(struct isl_ctx *ctx) test_parse_pwqp(ctx, "{ [i] -> i + [ (i + [i/3])/2 ] }"); test_parse_map(ctx, "{ S1[i] -> [([i/10]),i%10] : 0 <= i <= 45 }"); + test_parse_pwaff(ctx, "{ [i] -> [i + 1] : i > 0; [a] -> [a] : a < 0 }"); } void test_read(struct isl_ctx *ctx) -- 2.11.4.GIT