From b694b8eb01fce552e075fee43b1282fa63032c9e Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 6 Sep 2010 17:50:57 +0200 Subject: [PATCH] iscc: add support for strings --- Makefile.am | 2 ++ doc/isl.tex | 9 +++++ iscc.c | 81 ++++++++++++++++++++++++++++++++++++------ isl_obj_str.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isl_obj_str.h | 17 +++++++++ 5 files changed, 209 insertions(+), 11 deletions(-) create mode 100644 isl_obj_str.c create mode 100644 isl_obj_str.h diff --git a/Makefile.am b/Makefile.am index 83cafd4..f769f21 100644 --- a/Makefile.am +++ b/Makefile.am @@ -366,6 +366,8 @@ evalue_convert_SOURCES = \ iscc_SOURCES = \ isl_obj_list.h \ isl_obj_list.c \ + isl_obj_str.h \ + isl_obj_str.c \ iscc.c iscc_CPPFLAGS = @CLOOG_CFLAGS@ $(AM_CPPFLAGS) iscc_LDADD = \ diff --git a/doc/isl.tex b/doc/isl.tex index 087c4e4..5c94aac 100644 --- a/doc/isl.tex +++ b/doc/isl.tex @@ -103,6 +103,7 @@ $f$: piecewise quasipolynomial fold, $l$: list, $i$: integer, $b$: boolean, +$S$: string, $o$: object of any type } \label{t:iscc} @@ -236,6 +237,14 @@ $f_2$ := $f_1$ \ai{$+$} $q$ & sum \\ $f_2$ := $q$ \ai{$+$} $f_1$ & sum \\ +$S_3$ := $S_1$ \ai{$+$} $S_2$ & concatenation +\\ +$S_2$ := $o$ \ai{$+$} $S_1$ & +concatenation of stringification of $o$ and $S_1$ +\\ +$S_2$ := $S_1$ \ai{$+$} $o$ & +concatenation of $S_1$ and stringification of $o$ +\\ $s_3$ := $s_1$ \ai{$-$} $s_2$ & set difference \\ $m_3$ := $m_1$ \ai{$-$} $m_2$ & set difference diff --git a/iscc.c b/iscc.c index 68b6a3a..c4e57cc 100644 --- a/iscc.c +++ b/iscc.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "config.h" @@ -378,6 +379,8 @@ struct isc_bin_op bin_ops[] = { { '%', isl_obj_union_pw_qpolynomial_fold, isl_obj_union_set, isl_obj_union_pw_qpolynomial_fold, (isc_bin_op_fn) &isl_union_pw_qpolynomial_fold_gist }, + { '+', isl_obj_str, isl_obj_str, isl_obj_str, + (isc_bin_op_fn) &isl_str_concat }, 0 }; struct isc_named_bin_op named_bin_ops[] = { @@ -663,6 +666,8 @@ static int is_subtype(struct isl_obj obj, isl_obj_type super) if (list->n == 2 && list->obj[1].type == isl_obj_bool) return is_subtype(list->obj[0], super); } + if (super == isl_obj_str) + return 1; return 0; } @@ -678,7 +683,8 @@ static struct isl_obj obj_at(struct isl_obj obj, int i) return obj; } -static struct isl_obj convert(struct isl_obj obj, isl_obj_type type) +static struct isl_obj convert(isl_ctx *ctx, struct isl_obj obj, + isl_obj_type type) { if (obj.type == type) return obj; @@ -728,8 +734,33 @@ static struct isl_obj convert(struct isl_obj obj, isl_obj_type type) if (obj.type == isl_obj_list) { struct isl_list *list = obj.v; if (list->n == 2 && list->obj[1].type == isl_obj_bool) - return convert(obj_at(obj, 0), type); + return convert(ctx, obj_at(obj, 0), type); } + if (type == isl_obj_str) { + isl_str *str; + isl_printer *p; + char *s; + + p = isl_printer_to_str(ctx); + if (!p) + goto error; + p = obj.type->print(p, obj.v); + s = isl_printer_get_str(p); + isl_printer_free(p); + + str = isl_str_alloc(ctx); + if (!str) { + free(s); + goto error; + } + str->s = s; + free_obj(obj); + obj.v = str; + obj.type = isl_obj_str; + return obj; + + } +error: free_obj(obj); obj.type = isl_obj_none; obj.v = NULL; @@ -861,7 +892,7 @@ static struct isl_obj read_un_op_expr(struct isl_stream *s, op = find_matching_un_op(op, obj); isl_assert(s->ctx, op, goto error); - obj = convert(obj, op->arg); + obj = convert(s->ctx, obj, op->arg); obj.v = op->fn(obj.v); obj.type = op->res; @@ -879,7 +910,7 @@ static struct isl_obj transitive_closure(struct isl_ctx *ctx, struct isl_obj obj int exact; if (obj.type != isl_obj_union_map) - obj = convert(obj, isl_obj_union_map); + obj = convert(ctx, obj, isl_obj_union_map); isl_assert(ctx, obj.type == isl_obj_union_map, goto error); list = isl_list_alloc(ctx, 2); if (!list) @@ -944,9 +975,9 @@ static struct isl_obj apply(struct isl_stream *s, __isl_take isl_union_map *umap obj = obj_at(obj, 0); } if (obj.type == isl_obj_set) - obj = convert(obj, isl_obj_union_set); + obj = convert(s->ctx, obj, isl_obj_union_set); else if (obj.type == isl_obj_map) - obj = convert(obj, isl_obj_union_map); + obj = convert(s->ctx, obj, isl_obj_union_map); if (obj.type == isl_obj_union_set) { obj.v = isl_union_set_apply(obj.v, umap); } else @@ -1033,7 +1064,7 @@ static struct isl_obj vertices(struct isl_stream *s, struct add_vertex_data data = { NULL }; obj = read_expr(s, table); - obj = convert(obj, isl_obj_union_set); + obj = convert(s->ctx, obj, isl_obj_union_set); isl_assert(s->ctx, obj.type == isl_obj_union_set, goto error); uset = obj.v; obj.v = NULL; @@ -1080,7 +1111,7 @@ static struct isl_obj power(struct isl_stream *s, struct isl_obj obj) isl_token_free(tok); isl_assert(s->ctx, is_subtype(obj, isl_obj_union_map), goto error); if (obj.type != isl_obj_union_map) - obj = convert(obj, isl_obj_union_map); + obj = convert(s->ctx, obj, isl_obj_union_map); obj.v = isl_union_map_reverse(obj.v); if (!obj.v) @@ -1130,6 +1161,31 @@ error: return obj; } +static struct isl_obj read_string_if_available(struct isl_stream *s) +{ + struct isl_token *tok; + struct isl_obj obj = { isl_obj_none, NULL }; + + tok = isl_stream_next_token(s); + if (!tok) + return obj; + if (tok->type == ISL_TOKEN_STRING) { + isl_str *str; + str = isl_str_alloc(s->ctx); + if (!str) + goto error; + str->s = strdup(tok->u.s); + isl_token_free(tok); + obj.v = str; + obj.type = isl_obj_str; + } else + isl_stream_push_token(s, tok); + return obj; +error: + isl_token_free(tok); + return obj; +} + static struct isl_obj read_obj(struct isl_stream *s, struct isl_hash_table *table) { @@ -1137,6 +1193,9 @@ static struct isl_obj read_obj(struct isl_stream *s, char *name = NULL; struct isc_un_op *op = NULL; + obj = read_string_if_available(s); + if (obj.v) + return obj; if (isl_stream_eat_if_available(s, '(')) { obj = read_expr(s, table); if (!obj.v || isl_stream_eat(s, ')')) @@ -1166,7 +1225,7 @@ static struct isl_obj read_obj(struct isl_stream *s, obj = obj_at_index(s, obj); else if (is_subtype(obj, isl_obj_union_map) && isl_stream_eat_if_available(s, '(')) { - obj = convert(obj, isl_obj_union_map); + obj = convert(s->ctx, obj, isl_obj_union_map); obj = apply(s, obj.v, table); } @@ -1231,8 +1290,8 @@ static struct isl_obj read_expr(struct isl_stream *s, op = find_matching_bin_op(op, obj, right_obj); isl_assert(s->ctx, op, goto error); - obj = convert(obj, op->lhs); - right_obj = convert(right_obj, op->rhs); + obj = convert(s->ctx, obj, op->lhs); + right_obj = convert(s->ctx, right_obj, op->rhs); obj.v = op->fn(obj.v, right_obj.v); obj.type = op->res; } diff --git a/isl_obj_str.c b/isl_obj_str.c new file mode 100644 index 0000000..f633bbd --- /dev/null +++ b/isl_obj_str.c @@ -0,0 +1,111 @@ +#include +#include + +__isl_give isl_str *isl_str_alloc(struct isl_ctx *ctx) +{ + isl_str *str; + + str = isl_alloc_type(ctx, struct isl_str); + if (!str) + return NULL; + + str->ctx = ctx; + isl_ctx_ref(str->ctx); + str->ref = 1; + + str->s = NULL; + + return str; +} + +__isl_give isl_str *isl_str_copy(__isl_keep isl_str *str) +{ + if (!str) + return NULL; + + str->ref++; + return str; +} + +void isl_str_free(__isl_take isl_str *str) +{ + int i; + + if (!str) + return; + + if (--str->ref > 0) + return; + + free(str->s); + isl_ctx_deref(str->ctx); + free(str); +} + +static void *isl_obj_str_copy(void *v) +{ + return isl_str_copy((isl_str *)v); +} + +static void isl_obj_str_free(void *v) +{ + isl_str_free((isl_str *)v); +} + +static __isl_give isl_printer *isl_obj_str_print(__isl_take isl_printer *p, + void *v) +{ + isl_str *str = (isl_str *)v; + + isl_printer_print_str(p, str->s); +} + +__isl_give isl_str *isl_str_concat(__isl_take isl_str *str1, + __isl_take isl_str *str2) +{ + int i; + isl_str *str = NULL; + size_t len1, len2; + + if (!str1 || !str2) + goto error; + + str = isl_str_alloc(str1->ctx); + if (!str) + goto error; + + len1 = strlen(str1->s); + len2 = strlen(str2->s); + str->s = isl_alloc_array(str1->ctx, char, len1 + len2 + 1); + if (!str->s) + goto error; + + memcpy(str->s, str1->s, len1); + memcpy(str->s + len1, str2->s, len2); + str->s[len1 + len2] = '\0'; + + isl_str_free(str1); + isl_str_free(str2); + + return str; +error: + isl_str_free(str1); + isl_str_free(str2); + isl_str_free(str); + return NULL; +} + +static void *isl_obj_str_add(void *v1, void *v2) +{ + isl_str *str1 = (isl_str *)v1; + isl_str *str2 = (isl_str *)v2; + + return isl_str_concat(str1, str2); +} + +struct isl_obj_vtable isl_obj_str_vtable = { + isl_obj_str_copy, + isl_obj_str_add, + isl_obj_str_print, + isl_obj_str_free +}; diff --git a/isl_obj_str.h b/isl_obj_str.h new file mode 100644 index 0000000..34d5a21 --- /dev/null +++ b/isl_obj_str.h @@ -0,0 +1,17 @@ +#include + +struct isl_str { + int ref; + + struct isl_ctx *ctx; + + char *s; +}; +typedef struct isl_str isl_str; + +__isl_give isl_str *isl_str_alloc(struct isl_ctx *ctx); +__isl_give isl_str *isl_str_concat(__isl_take isl_str *str1, + __isl_take isl_str *str2); + +extern struct isl_obj_vtable isl_obj_str_vtable; +#define isl_obj_str (&isl_obj_str_vtable) -- 2.11.4.GIT