Hi,

Here is a small patch that add the new primitive square lens with test.

The get and put directions are working. The square lens is limited to a
static string body. This has to be changed for a lens body. Also, the
typecheck is not done properly yet.

There is some cleanup to do, since there is a lot of debug output.
Valgrind reports no leaks for the test.

Since this is the first lens primitive to take a lens as an argument, I
don't know how to handle the case in lns_square. Should I add a third
argument to functions that build primitive lenses?

Francis
From 8c8d31fd51ce24fd7b8fdb8d47f08a2d0a83f701 Mon Sep 17 00:00:00 2001
From: Francis Giraldeau <[email protected]>
Date: Sat, 29 May 2010 16:00:03 -0400
Subject: [PATCH] ADD basic square lens with static string inner body

---
 src/builtin.c                 |   11 ++++
 src/get.c                     |  122 ++++++++++++++++++++++++++++++++++++++++-
 src/lens.c                    |   23 ++++++-
 src/lens.h                    |   10 ++-
 src/put.c                     |    6 ++
 tests/modules/pass_square.aug |    7 ++
 6 files changed, 170 insertions(+), 9 deletions(-)
 create mode 100644 tests/modules/pass_square.aug

diff --git a/src/builtin.c b/src/builtin.c
index ef7b7d3..2de92f8 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -85,6 +85,16 @@ static struct value *lns_counter(struct info *info, struct value *str) {
     assert(str->tag == V_STRING);
     return lns_make_prim(L_COUNTER, ref(info), NULL, ref(str->string));
 }
+/* FIXME: actual square lens takes only a static string as the inner body,
+ * should be a lens
+ */
+/* V_REGEXP -> V_STRING -> V_LENS */
+static struct value *lns_square(struct info *info, struct value *rxp, struct value *str) {
+    assert(rxp->tag == V_REGEXP);
+    assert(str->tag == V_STRING);
+    return lns_make_prim(L_SQUARE, ref(info),
+                         ref(rxp->regexp), ref(str->string));
+}
 
 static struct value *make_exn_lns_error(struct info *info,
                                         struct lns_error *err,
@@ -536,6 +546,7 @@ struct module *builtin_init(struct error *error) {
     DEFINE_NATIVE(modl, "label",   1, lns_label, T_STRING, T_LENS);
     DEFINE_NATIVE(modl, "seq",     1, lns_seq, T_STRING, T_LENS);
     DEFINE_NATIVE(modl, "counter", 1, lns_counter, T_STRING, T_LENS);
+    DEFINE_NATIVE(modl, "square",  2, lns_square, T_REGEXP, T_STRING, T_LENS);
     /* Applying lenses (mostly for tests) */
     DEFINE_NATIVE(modl, "get",     2, lens_get, T_LENS, T_STRING, T_TREE);
     DEFINE_NATIVE(modl, "put",     3, lens_put, T_LENS, T_TREE, T_STRING,
diff --git a/src/get.c b/src/get.c
index a8f05e4..f947f52 100644
--- a/src/get.c
+++ b/src/get.c
@@ -556,6 +556,18 @@ static struct skel *parse_concat(struct lens *lens, struct state *state,
     return skel;
 }
 
+void dump_regs(struct state *state);
+void dump_regs(struct state *state){
+	printf("state->nreg=%d\tstate->nregs->num_regs=%d\n", state->nreg, state->regs->num_regs);
+	for (int i=0; i<state->regs->num_regs;i++){
+		const char *start = state->text + state->regs->start[i];
+		uint size = state->regs->end[i] - state->regs->start[i];
+		char *s = strndup(start, size);
+		printf("state->nregs->start=%d\tstate->nregs->end=%d %s\n", state->regs->start[i], state->regs->end[i], s);
+		free(s);
+	}
+}
+
 static struct tree *get_quant_star(struct lens *lens, struct state *state) {
     ensure0(lens->tag == L_STAR, state->info);
     struct lens *child = lens->child;
@@ -568,6 +580,7 @@ static struct tree *get_quant_star(struct lens *lens, struct state *state) {
 
     state->regs = NULL;
     while (size > 0 && match(state, child, child->ctype, end, start) > 0) {
+    	dump_regs(state);
         struct tree *t = NULL;
 
         t = get_lens(lens->child, state);
@@ -682,6 +695,58 @@ static struct skel *parse_subtree(struct lens *lens, struct state *state,
     return make_skel(lens);
 }
 
+static struct tree *get_square(struct lens *lens, struct state *state){
+	ensure0(lens->tag == L_SQUARE, state->info);
+	dump_regs(state);
+
+	char *key1 = NULL, *inner = NULL, *key2 = NULL;
+
+	printf("nsub-total=%d %s\n", regexp_nsub(lens->ctype), lens->ctype->pattern->str);
+	printf("nsub-basic=%d %s\n", regexp_nsub(lens->regexp), lens->regexp->pattern->str);
+	// nreg for the key
+	size_t key_nreg = regexp_nsub(lens->regexp);
+	uint old_nreg = state->nreg;
+	state->nreg++;
+	// match the key
+	if (! REG_MATCHED(state))
+		no_match_error(state, lens);
+	else
+		key1 = token(state);
+
+	// match inner lens
+	state->nreg += 1 + key_nreg;
+	if (! REG_MATCHED(state))
+		no_match_error(state, lens);
+	else
+		inner = token(state);
+
+	// match again the key
+	state->nreg++;
+	if (! REG_MATCHED(state))
+		no_match_error(state, lens);
+	else
+		key2 = token(state);
+
+	state->nreg = old_nreg;
+
+	printf("key1=%s inner=%s key2=%s\n", key1, inner, key2);
+	if (strcmp(key1,key2)==0){
+		printf("key1 == key2\n");
+	} else {
+		printf("key1 != key2\n");
+	}
+
+	state->key = key1;
+	free(inner);
+	free(key2);
+	return NULL;
+}
+
+static struct skel *parse_square(struct lens *lens, struct state *state){
+	ensure0(lens->tag == L_SQUARE, state->info);
+	return make_skel(lens);
+}
+
 /*
  * Helpers for recursive lenses
  */
@@ -1060,10 +1125,59 @@ static struct skel *parse_rec(struct lens *lens, struct state *state,
     }
     return skel;
 }
+void print_lens(struct lens *lens);
+void print_lens(struct lens *lens){
+	const char *tag;
+	switch(lens->tag){
+	case L_DEL:
+		tag = "L_DEL";
+		break;
+	case L_STORE:
+		tag = "L_STORE";
+		break;
+	case L_VALUE:
+		tag = "L_VALUE";
+		break;
+	case L_KEY:
+		tag = "L_KEY";
+		break;
+	case L_LABEL:
+		tag = "L_LABEL";
+		break;
+	case L_SEQ:
+		tag = "L_SEQ";
+		break;
+	case L_COUNTER:
+		tag = "L_COUNTER";
+		break;
+	case L_CONCAT:
+		tag = "L_CONCAT";
+		break;
+	case L_UNION:
+		tag = "L_UNION";
+		break;
+	case L_SUBTREE:
+		tag = "L_SUBTREE";
+		break;
+	case L_STAR:
+		tag = "L_STAR";
+		break;
+	case L_MAYBE:
+		tag = "L_MAYBE";
+		break;
+	case L_SQUARE:
+		tag = "L_SQUARE";
+		break;
+	case L_REC:
+		tag = "L_REC";
+		break;
+	}
+	printf("%s\n", tag);
+}
 
 static struct tree *get_lens(struct lens *lens, struct state *state) {
     struct tree *tree = NULL;
-
+    print_lens(lens);
     switch(lens->tag) {
     case L_DEL:
         tree = get_del(lens, state);
@@ -1101,6 +1215,9 @@ static struct tree *get_lens(struct lens *lens, struct state *state) {
     case L_MAYBE:
         tree = get_quant_maybe(lens, state);
         break;
+    case L_SQUARE:
+    	tree = get_square(lens, state);
+    	break;
     default:
         BUG_ON(true, state->info, "illegal lens tag %d", lens->tag);
         break;
@@ -1237,6 +1354,9 @@ static struct skel *parse_lens(struct lens *lens, struct state *state,
     case L_MAYBE:
         skel = parse_quant_maybe(lens, state, dict);
         break;
+    case L_SQUARE:
+    	skel = parse_square(lens, state);
+    	break;
     default:
         BUG_ON(true, state->info, "illegal lens tag %d", lens->tag);
         break;
diff --git a/src/lens.c b/src/lens.c
index 41fcd50..3d7cae0 100644
--- a/src/lens.c
+++ b/src/lens.c
@@ -54,7 +54,7 @@ static struct value *typecheck_maybe(struct info *info, struct lens *l);
 
 /* Lens names for pretty printing */
 static const char *const tags[] = {
-    "del", "store", "value", "key", "label", "seq", "counter",
+    "del", "store", "value", "key", "label", "seq", "counter", "square",
     "concat", "union",
     "subtree", "star", "maybe", "rec"
 };
@@ -447,7 +447,7 @@ struct value *lns_make_prim(enum lens_tag tag, struct info *info,
     struct fa *fa_isect = NULL;
 
     /* Typecheck */
-    if (tag == L_KEY) {
+    if (tag == L_KEY || tag == L_SQUARE) {
         exn = str_to_fa(info, "(.|\n)*/(.|\n)*", &fa_slash, regexp->nocase);
         if (exn != NULL)
             goto error;
@@ -494,7 +494,7 @@ struct value *lns_make_prim(enum lens_tag tag, struct info *info,
     lens = make_lens(tag, info);
     lens->regexp = regexp;
     lens->string = string;
-    lens->key = (tag == L_KEY || tag == L_LABEL || tag == L_SEQ);
+    lens->key = (tag == L_KEY || tag == L_LABEL || tag == L_SEQ || tag == L_SQUARE);
     lens->value = (tag == L_STORE || tag == L_VALUE);
     lens->consumes_value = (tag == L_STORE || tag == L_VALUE);
     lens->atype = regexp_make_empty(info);
@@ -502,6 +502,17 @@ struct value *lns_make_prim(enum lens_tag tag, struct info *info,
     if (tag == L_DEL || tag == L_STORE || tag == L_KEY) {
         lens->ctype = ref(regexp);
         lens->ctype_nullable = regexp_matches_empty(lens->ctype);
+    } else if (tag == L_SQUARE) {
+    	struct regexp *rx[3];
+    	struct regexp *inner = make_regexp_literal(info, string->str);
+    	rx[0] = regexp;
+    	rx[1] = inner;
+    	rx[2] = regexp;
+    	struct regexp *r = regexp_concat_n(info, 3, rx);
+    	printf("L_SQUARE->ctype=%s\n",r->pattern->str);
+    	lens->ctype = r;
+    	lens->ctype_nullable = regexp_matches_empty(lens->ctype);
+    	unref(inner, regexp);
     } else if (tag == L_LABEL || tag == L_VALUE
                || tag == L_SEQ || tag == L_COUNTER) {
         lens->ctype = regexp_make_empty(info);
@@ -518,7 +529,7 @@ struct value *lns_make_prim(enum lens_tag tag, struct info *info,
             make_regexp_from_string(info, (struct string *) digits_pat);
         if (lens->ktype == NULL)
             goto error;
-    } else if (tag == L_KEY) {
+    } else if (tag == L_KEY || tag == L_SQUARE) {
         lens->ktype = restrict_regexp(lens->regexp);
     } else if (tag == L_LABEL) {
         lens->ktype = make_regexp_literal(info, lens->string->str);
@@ -826,6 +837,10 @@ void free_lens(struct lens *lens) {
             jmt_free(lens->jmt);
         }
         break;
+    case L_SQUARE:
+    	unref(lens->regexp, regexp);
+    	unref(lens->string, string);
+    	break;
     default:
         BUG_LENS_TAG(lens);
         break;
diff --git a/src/lens.h b/src/lens.h
index 7c2b6ce..bb848ea 100644
--- a/src/lens.h
+++ b/src/lens.h
@@ -40,7 +40,8 @@ enum lens_tag {
     L_SUBTREE,
     L_STAR,
     L_MAYBE,
-    L_REC
+    L_REC,
+    L_SQUARE
 };
 
 /* A lens. The way the type information is computed is a little
@@ -87,9 +88,10 @@ struct lens {
     unsigned int              ctype_nullable : 1;
     union {
         /* Primitive lenses */
-        struct {                   /* L_DEL uses both */
-            struct regexp *regexp; /* L_STORE, L_KEY */
-            struct string *string; /* L_VALUE, L_LABEL, L_SEQ, L_COUNTER */
+        struct {                    /* L_DEL uses both */
+            struct regexp *regexp;  /* L_STORE, L_KEY */
+            struct string *string;  /* L_VALUE, L_LABEL, L_SEQ, L_COUNTER */
+            struct lens   *content; /* L_SQUARE */
         };
         /* Combinators */
         struct lens *child;         /* L_SUBTREE, L_STAR, L_MAYBE */
diff --git a/src/put.c b/src/put.c
index 7c72dd1..263eb11 100644
--- a/src/put.c
+++ b/src/put.c
@@ -627,6 +627,9 @@ static void put_lens(struct lens *lens, struct state *state) {
     case L_REC:
         put_rec(lens, state);
         break;
+    case L_SQUARE:
+    	fprintf(state->out, "%s%s%s", state->key, lens->string->str, state->key);
+		break;
     default:
         assert(0);
         break;
@@ -749,6 +752,9 @@ static void create_lens(struct lens *lens, struct state *state) {
     case L_REC:
         create_rec(lens, state);
         break;
+    case L_SQUARE:
+		fprintf(state->out, "%s%s%s", state->key, lens->string->str, state->key);
+		break;
     default:
         assert(0);
         break;
diff --git a/tests/modules/pass_square.aug b/tests/modules/pass_square.aug
new file mode 100644
index 0000000..141b44c
--- /dev/null
+++ b/tests/modules/pass_square.aug
@@ -0,0 +1,7 @@
+module Pass_square = 
+
+let y = [ square /[a-b]*/ "zz" . del "x" "x" ] * 
+test y get "aazzaaaxbbzzbbx" = { "aa" }{ "bb" }
+
+test y get "azzax" = { "a" } 
+test y put "azzax" after clear "/b" = "azzaxbzzbx"
-- 
1.7.0.4

_______________________________________________
augeas-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/augeas-devel

Reply via email to