Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inherit ktype and vtype in subtree lens #288

Closed
wants to merge 1 commit into from

Conversation

raphink
Copy link
Member

@raphink raphink commented Sep 1, 2015

Currently, subtree lenses do not have ktype and vtype set. For this reason, the following code:

module Test =
let lns = [ key "a" . store "b" ]
let _ = print_string "\nktype:\n"
let _ = print_regexp (lens_ktype lns)
let _ = print_string "\nvtype:\n"
let _ = print_regexp (lens_vtype lns)
let _ = print_string "\n"

returns:

$ augparse test.aug 

ktype:
/()/
vtype:
/()/

It would make sense (and it would be very useful) for them to inherit their sublens types, such that the above code returns:


ktype:
/a/
vtype:
/b/

I've tried two approaches so far:

Set ktype and vtype in lns_make_subtree

diff --git a/src/lens.c b/src/lens.c
index 37db306..078fdfa 100644
--- a/src/lens.c
+++ b/src/lens.c
@@ -334,6 +334,8 @@ struct value *lns_make_subtree(struct info *info, struct lens *l) {

     lens = make_lens_unop(L_SUBTREE, info, l);
     lens->ctype = ref(l->ctype);
+    lens->ktype = l->ktype;
+    lens->vtype = l->vtype;
     if (! l->recursive)
         lens->atype = subtree_atype(info, l->ktype, l->vtype);
     lens->value = lens->key = 0;
  • this is the most obvious/simple option
  • it makes my tests pass

but it makes lots of lenses fail typechecking, and I have no idea why (and digging into fa stuff gives me a headache)

Add a sub field in lenses, and use it to print ktype and vtype

diff --git a/src/builtin.c b/src/builtin.c
index e674181..8cf210c 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -527,12 +527,20 @@ static struct value *lns_atype(struct info *info, struct value *l) {

 /* V_LENS -> V_REGEXP */
 static struct value *lns_vtype(struct info *info, struct value *l) {
-    return lns_value_of_type(info, l->lens->vtype);
+    if (l->lens->tag == L_SUBTREE) {
+        return lns_value_of_type(info, l->lens->sub->vtype);
+    } else {
+        return lns_value_of_type(info, l->lens->vtype);
+    }
 }

 /* V_LENS -> V_REGEXP */
 static struct value *lns_ktype(struct info *info, struct value *l) {
-    return lns_value_of_type(info, l->lens->ktype);
+    if (l->lens->tag == L_SUBTREE) {
+        return lns_value_of_type(info, l->lens->sub->ktype);
+    } else {
+      return lns_value_of_type(info, l->lens->ktype);
+    }
 }

 /* V_LENS -> V_STRING */
diff --git a/src/lens.c b/src/lens.c
index 37db306..b0430bb 100644
--- a/src/lens.c
+++ b/src/lens.c
@@ -334,6 +334,7 @@ struct value *lns_make_subtree(struct info *info, struct lens *l) {

     lens = make_lens_unop(L_SUBTREE, info, l);
     lens->ctype = ref(l->ctype);
+    lens->sub = l;
     if (! l->recursive)
         lens->atype = subtree_atype(info, l->ktype, l->vtype);
     lens->value = lens->key = 0;
diff --git a/src/lens.h b/src/lens.h
index dfa7cbd..051988d 100644
--- a/src/lens.h
+++ b/src/lens.h
@@ -80,6 +80,7 @@ struct lens {
     struct regexp            *ktype;
     struct regexp            *vtype;
     struct jmt               *jmt;    /* When recursive == 1, might have jmt */
+    struct lens              *sub;
     unsigned int              value : 1;
     unsigned int              key : 1;
     unsigned int              recursive : 1;
  • this doesn't break the lenses typechecking as the first option
  • but it fails on recursive cases, such as [ key "a" ] | [ key "b" ], because each lens in the union has a NULL ktype and vtype.

@raphink
Copy link
Member Author

raphink commented Sep 1, 2015

@lutter is there another way I could fix this?

@lutter
Copy link
Member

lutter commented Sep 4, 2015

I think what you really want is some variation of the atype - the ktype of l gives you the regexp for the key of [ l ]; the atype has the regular expression for all the keys of a tree level, unfortunately it has a bit more than that, namely the regular expressions for both the keys and the values of that tree level.

The encoding of the atype is described in lens.h; in a nutshell, it's a regular expression where the primitives are KEY . ENC_EQ . VALUE . ENC_SLASH. What you want is the same regular expression, but only have the KEY part from above in it. The format_atype function in lens.c might be a good starting point; you want a function key_re_from_atype : lens -> regexp, which behind the scenes takes the atype apart and returns a regular expression that only matches the key parts of the atype.

@raphink
Copy link
Member Author

raphink commented Sep 4, 2015

That makes sense indeed, thank you.

@lutter
Copy link
Member

lutter commented Nov 26, 2015

Do we still need this ?

@raphink
Copy link
Member Author

raphink commented Nov 26, 2015

I guess not then. I still don't know exactly how to achieve what I wanted. I guess I'll need new builtin functions.

@raphink raphink closed this Nov 26, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants