June 27, 2010 [dmd-internals] Requesting some DMD hacking advice for property lowering. | ||||
---|---|---|---|---|
| ||||
Alright it's been a number of months since I've dabbled in D, but my spare time is slowly increasing... for now. Fingers crossed. So I'm going to attack this property lowering thing again. Here is a reminder of what I'm talking about: http://prowiki.org/wiki4d/wiki.cgi?DocComments/Property When I did this first I got 95% of the way there and hit a corner-case in DMD's code. This chicken-and-egg problem is what happened: (1) e->semantic(sc) is called. (e is an Expression) - This will call e's children's semantic. (2) resolveProperties must come after e->semantic(sc). - It needs e->semantic to get the type info and - to know if e contains properties (recursively). (3) If e has side effects and the mutated value(s) contain properties, then resolveProperties turns the mutated value(s) into multiple expressions within a comma expression such that no properties are in a side-effectful expression. (4) The resulting CommaExp's (and other generated Exps) must have semantic(sc) run on them to create type information. - This will call e's children's semantic(sc), again. (5) semantic(sc) must not be run on an Expression more than once. - This is why my 95%-of-the-way-there code would work perfectly most of the time and then fail in very rare instances. 4 and 5 contradict each other. I'm wondering if there is some canonically accepted way of dealing with this kind of stuff in DMD. I'd hate to write this and have it go to waste because I missed an idiom or coding convention. I've considered these possibilities: - I could guard the execution of semantic to make sure it is never done more than once: Expression *FooExp::semantic( Scope *sc ) { if ( semanticAlreadyCalledOnThis ) return this; ... etc } - I could do the above, but place that in a non-virtual semantic so that the code isn't duplicated everywhere. I would have to make all calls to semantic point to the non-virtual version. For sake of description, I'll call the non-virtual one "semantic" and the current virtual one "onSemantic". Expression *FooExp::semantic( Scope *sc ) { if ( semanticAlreadyCalledOnThis ) return this; return onSemantic(sc) } Expression *FooExp::onSemantic( Scope *sc ) { ... (previous semantic code for FooExp) ... } - I write a "shallowSemantic" method for the CommaExp, VarDeclaration, DeclarationExp, AssignExp, and anything else generated by the property rewrite. This would have to be called manually as its generated. This may not touch as many things as the above possibilities, but I suspect it will be much uglier. Please advise. - Chad -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.puremagic.com/pipermail/dmd-internals/attachments/20100627/91147b82/attachment.html> |
July 15, 2010 [dmd-internals] Requesting some DMD hacking advice for property lowering. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chad Joan | Hi Chad, I've only just found this email. Some comments below.
On 28 June 2010 01:56, Chad Joan <chadjoan at gmail.com> wrote:
> Alright it's been a number of months since I've dabbled in D, but my spare time is slowly increasing... for now.? Fingers crossed.
>
> So I'm going to attack this property lowering thing again.
>
> Here is a reminder of what I'm talking about: http://prowiki.org/wiki4d/wiki.cgi?DocComments/Property
>
> When I did this first I got 95% of the way there and hit a corner-case in DMD's code.? This chicken-and-egg problem is what happened:
>
> (1) e->semantic(sc) is called.? (e is an Expression)
> -?? This will call e's children's semantic.
>
> (2) resolveProperties must come after e->semantic(sc).
> -?? It needs e->semantic to get the type info and
> -?? to know if e contains properties (recursively).
>
> (3) If e has side effects and the mutated value(s) contain properties,
> then resolveProperties turns the mutated value(s) into multiple
> expressions within a comma expression such that no properties are in a
> side-effectful expression.
>
> (4) The resulting CommaExp's (and other generated Exps) must have
> semantic(sc) run on them to create type information.
> -?? This will call e's children's semantic(sc), again.
>
> (5) semantic(sc) must not be run on an Expression more than once.
> -?? This is why my 95%-of-the-way-there code would work perfectly most
> of the time and then fail in very rare instances.
>
> 4 and 5 contradict each other.
>
> I'm wondering if there is some canonically accepted way of dealing with this kind of stuff in DMD.? I'd hate to write this and have it go to waste because I missed an idiom or coding convention.
>
> I've considered these possibilities:
>
> - I could guard the execution of semantic to make sure it is never done more than once:
>
> Expression *FooExp::semantic( Scope *sc )
> {
> ??? if ( semanticAlreadyCalledOnThis )
> ??? ??? return this;
>
> ??? ... etc
> }
FuncDeclaration has semanticRun which basically does that.
BTW, I have found that CommaExp often needs a special case. Maybe it
just needs a non-recursive semantic().
Personally I have almost never made intrusive patches. (My opDollar
patch is the only one I can think of, and it still isn't included in
the compiler ). If you can't do it without an intrusive change, it
might be better to just get it to 95% complete, with a clear
explanation of what else needs to be done.
- Don.
|
Copyright © 1999-2021 by the D Language Foundation