isl_input.c: accept_div: accept floor/ceil of rational affine expression
authorSven Verdoolaege <skimo@kotnet.org>
Sat, 1 Jun 2013 18:09:23 +0000 (20:09 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Sun, 2 Jun 2013 18:28:00 +0000 (20:28 +0200)
We may want to print interger divisions as floor(...) instead of [...]
in the future, so we might as well start parsing such expressions.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
include/isl/stream.h
isl_input.c
isl_stream.c
isl_test.c

index 7484af1..d3f65e4 100644 (file)
@@ -35,6 +35,7 @@ enum isl_token_type { ISL_TOKEN_ERROR = -1,
                        ISL_TOKEN_CEILD, ISL_TOKEN_FLOORD, ISL_TOKEN_MOD,
                        ISL_TOKEN_STRING,
                        ISL_TOKEN_MAP, ISL_TOKEN_AFF,
+                       ISL_TOKEN_CEIL, ISL_TOKEN_FLOOR,
                        ISL_TOKEN_LAST };
 
 struct isl_token {
index ba10ce8..480d60d 100644 (file)
@@ -350,6 +350,10 @@ static int is_start_of_div(struct isl_token *tok)
                return 0;
        if (tok->type == '[')
                return 1;
+       if (tok->type == ISL_TOKEN_FLOOR)
+               return 1;
+       if (tok->type == ISL_TOKEN_CEIL)
+               return 1;
        if (tok->type == ISL_TOKEN_FLOORD)
                return 1;
        if (tok->type == ISL_TOKEN_CEILD)
@@ -357,17 +361,32 @@ static int is_start_of_div(struct isl_token *tok)
        return 0;
 }
 
+/* Read an integer division from "s" and return it as an isl_pw_aff.
+ *
+ * The integer division can be of the form
+ *
+ *     [<affine expression>]
+ *     floor(<affine expression>)
+ *     ceil(<affine expression>)
+ *     floord(<affine expression>,<denominator>)
+ *     ceild(<affine expression>,<denominator>)
+ */
 static __isl_give isl_pw_aff *accept_div(struct isl_stream *s,
        __isl_take isl_space *dim, struct vars *v)
 {
        struct isl_token *tok;
        int f = 0;
        int c = 0;
+       int extra = 0;
        isl_pw_aff *pwaff = NULL;
 
        if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOORD))
-               f = 1;
+               extra = f = 1;
        else if (isl_stream_eat_if_available(s, ISL_TOKEN_CEILD))
+               extra = c = 1;
+       else if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOOR))
+               f = 1;
+       else if (isl_stream_eat_if_available(s, ISL_TOKEN_CEIL))
                c = 1;
        if (f || c) {
                if (isl_stream_eat(s, '('))
@@ -379,7 +398,7 @@ static __isl_give isl_pw_aff *accept_div(struct isl_stream *s,
 
        pwaff = accept_affine(s, isl_space_copy(dim), v);
 
-       if (f || c) {
+       if (extra) {
                if (isl_stream_eat(s, ','))
                        goto error;
 
index c40756d..de69f45 100644 (file)
@@ -323,6 +323,10 @@ static enum isl_token_type check_keywords(struct isl_stream *s)
                return ISL_TOKEN_FLOORD;
        if (!strcasecmp(s->buffer, "mod"))
                return ISL_TOKEN_MOD;
+       if (!strcasecmp(s->buffer, "ceil"))
+               return ISL_TOKEN_CEIL;
+       if (!strcasecmp(s->buffer, "floor"))
+               return ISL_TOKEN_FLOOR;
 
        if (!s->keywords)
                return ISL_TOKEN_IDENT;
index eeb2fc3..5d3e4aa 100644 (file)
@@ -209,6 +209,10 @@ int test_parse(struct isl_ctx *ctx)
        if (test_parse_map_equal(ctx, "{ [*] }", "{ [a] }") < 0)
                return -1;
 
+       if (test_parse_map_equal(ctx, "{ [i] : 2*floor(i/2) = i }",
+                                     "{ [i] : exists a : i = 2 a }") < 0)
+               return -1;
+
        return 0;
 }