SDF3: named children
If we add names/labels to the children of productions we can generate stratego getters and setters.
Getters and setters decouple the number of children of a constructor, such that if one adds or removes a child, or changes the order of children the whole stratego codebase does not have to be rewritten.Proposed syntax:
Role.Role = [[@type ID][@inv DotID?] [@mult Multiplicity?][@ord Ordering?][@name SpaceArrowID?]]
Would be the equivalent of:
Role.Role = [[ID][DotID?] [Multiplicity?][Ordering?][SpaceArrowID?]]
is-role = ?Role(_, _, _, _, _) role-get-type = ?Role(<id>, _, _, _, _) role-get-inv = ?Role(_, <id>, _, _, _) role-get-mult = ?Role(_, _, <id>, _, _) role-get-ord = ?Role(_, _, _, <id>, _) role-get-name = ?Role(_, _, _, _, <id>) role-set-type(s) = Role(s, id, id, id, id) role-set-inv (s) = Role(id, s, id, id, id) role-set-mult(s) = Role(id, id, s, id, id) role-set-ord (s) = Role(id, id, id, s, id) role-set-name(s) = Role(id, id, id, id, s)
When using the sort (not the constructor name) for these getters and setters this also introduces abstraction:
Attr.Attribute = <<@name ID> : <@type Type><@mult Multiplicity?>> Attr.DerivationAttribute = <<@name ID> : <@type Type><@mult Multiplicity?> = <@expr Exp>> Attr.DefaultAttribute = <<@name ID> : <@type Type><@mult Multiplicity?> = <@expr Exp> (default)>
The generated getters and setters abstract over the concrete constructors:
is-attr = ?Attribute(_, _, _) is-attr = ?DerivationAttribute(_, _, _, _) is-attr = ?DefaultAttribute(_, _, _, _) attr-get-name = ?Attribute(<id>, _, _) attr-get-name = ?DerivationAttribute(<id>, _, _, _) attr-get-name = ?DefaultAttribute(<id>, _, _, _) attr-set-mult(s) = Attribute(id, id, s) attr-set-mult(s) = DerivationAttribute(id, id, s, id) attr-set-mult(s) = DefaultAttribute(id, id, s, id)
(Note: if we add named child access to stratego SDF3 does not have to generate getters and setters. But I have no idea how hard it is to extend Stratego with:
Role : @type ID * @inv Option(DotID) * @mult Option(Multiplicity) * @ord Option(Ordering) * @name Option(SpaceArrowID) -> Role
)
Any opinions on this improvement?
Submitted by Daco Harkes on 24 October 2016 at 18:40
Issue Log
First impression: that makes for ugly (i.e. unreadable) syntax definitions.
Doing it in Stratego should not be so hard, but requires duplicating signatures which are otherwise generated.
But I see that having generated projection functions is useful. So, I would propose to add some sugar: When omitting the projector name, it is derived from the type name, so that you would be able to write this
Name = ID Attr.Attribute = <<Name> : <Type><Multiplicity?>> Attr.DerivationAttribute = <<Name> : <Type><Multiplicity?> = <Exp>> Attr.DefaultAttribute = <<Name> : <Type><Multiplicity?> = <Exp> (default)>
to get the same projections.
Relying on pattern matching would allow to get more compact strategy names:
type = ?Role(<id>, _, _, _, _) set-type(s) = Role(s, id, id, id, id)
(You could call it dynamic dispatch.)
Good suggestions!
Compact strategy names might conflict (i.e. result in obscure bugs) if you have multiple constructors with the same number of children but from different Sorts. :\
SDF3 already supports labeled children in productions. It inherited this feature from SDF2. This is valid SDF3:
Role.Role = [[type:ID][inv:DotID?] [mult:Multiplicity?][ord:Ordering?][name:SpaceArrowID?]]
The syntax highlighting uses a light grey for labels, making it less invasive. I actually think this kind of highlighting would be useful for other distractions as well.
Log in to post comments