How do I find the arity of an Expression? (dmd hacking)

Ellery Newcomer ellery-newcomer at utulsa.edu
Mon Nov 30 21:21:57 PST 2009


On 11/30/2009 07:59 PM, Chad J wrote:
>
> If you care for a bit of reading, I'll tell you my story and ping an idea.
>
> This is about the property expression rewrite of course.  I'd love to
> just use the current convention in dmd and write the rewrite as a
> non-recursive function that gets called at every point in the tree
> whenever someExpr->semantic(sc) is called.  However, there's a snag.
>

Personally, I've come to hate this pattern (just from reading DMD src). 
It seems like the antithesis of code reuse.

> When doing the property rewrite, the inner-most subexpression will need
> to generate the outermost temporaries.
>
> An example:
>
> prop1.prop2 += foo;
>
> AFAIK, the compiler sees this as ((prop1).prop2) += foo; or
> ((prop1()).prop2()) += foo; after resolveProperties is called.  So prop1
> is the innermost expression.
>
> It would be rewritten as this comma expression:
>
> (auto t1 = prop1()),
> (auto t2 = t1.prop2()),
> (t2 += foo),
> (t1.prop2(t2)),
> (prop1(t1))

This is an interesting problem. I like it. Is this rewrite condoned by 
the powers that be? It'd be fun to implement if I ever get this far in 
my semantic analyzer.

>
> So t1 is the outermost temporary, and it corresponds to prop1, the
> innermost expression.
>
> This is problematic in dmd's traditional approach, because the semantic
> pass on prop1 does not have access to it's enclosing expression (as far
> as I can tell).  If it did, I'd just go to the root of the tree, uproot
> the tree, stick it in a comma expression, and just start nesting:

I'm not convinced you need access to the enclosing expression to make 
this rewrite happen. Working it out on paper, it appears to be a matter 
of a few AST copies, keeping track of your t's, and building your comma 
tree (in two directions simultaneously) as you traverse the AST via eg 
semantic.

Here's some chicken scratch that more or less illustrates what I 
envision going on (I can't attest that DMD's ASTs look exactly like 
this, but I assume they're similar):

http://personal.utulsa.edu/~ellery-newcomer/scribble.png

How much effort it would entail is another matter though. I would assume 
you could just add a field or two to struct Expression for pushing 
information up the tree. It seems like copying functionality is already 
there. Pushing 't' information across the tree would probably propagate 
to each special case and be the most annoying part. But basically, every 
time you come across a property, you generate a new symbol and pair of 
pre/post trees. Then at the top, you make a single tree copy with the 
last symbol generated.

>
> Now for the idea.
>
> Currently I'm planning an approach that's a bit more minimalistic than
> the visitor pattern; just to solve my immediate problem.  I will define
> these methods in Expression:
>
> virtual Expression *getChild(unsigned index);
> virtual void setChild(unsigned index, Expression* val);
> virtual unsigned numChildren();
>

I can imagine this would be welcome regardless of how you set about your 
rewrite procedure. I came across a need for something like this as I was 
building my semantic analyzer a while back. Can't wait for school to get 
out so I can get back to work.

> Then I will implement them as needed in the subclasses of Expression.  I
> figure I'd have to write this logic into my function anyways, so I might
> as well make this usable to others.  I've already written a draft of the
> property rewrite that uses these, so I know they get the job done in
> principle.  I just hope this will all be OK in the patch (or even holds
> up under debugging).
>
> So yeah, if I haven't put you to sleep already, please let me know if I
> messed up somewhere.

I do have one nitpick:

auto t1 = p1();

isn't an expression, it's a declaration. That could potentially make 
things difficult for you, particularly when your property assignment is 
deep within an expression tree.

>
> - Chad



More information about the Digitalmars-d-learn mailing list