Writing a compiler to handles, but filter seems to executed in reverse

Remi Forax forax at univ-mlv.fr
Wed Jan 3 16:13:39 UTC 2018


https://gist.github.com/forax/5d3c68733c4ff39ae20b8bdcfa3d8b0a 

The general solution for simulating a function call is to use fold and not filter (see line 87), filter only works in your case because you pass all your variables as an array. 

One interesting remark is that you can not compile the AST to a method handle in one pass, because the loop combinator ask to know all local variables upfront. 

Rémi 

> De: "Charles Oliver Nutter" <headius at headius.com>
> À: "Da Vinci Machine Project" <mlvm-dev at openjdk.java.net>
> Envoyé: Mardi 2 Janvier 2018 22:10:01
> Objet: Re: Writing a compiler to handles, but filter seems to executed in
> reverse

> Yes, I figured I would need it for that too, but this filter behavior sent me
> off on a weird tangent.
> It is gross in code to do the filters manually in forward order, but perhaps
> it's not actually a big deal? OpenJDK's impl applies each filter as its own
> layer anyway.

> - Charlie

> On Tue, Jan 2, 2018 at 3:04 PM Remi Forax < [ mailto:forax at univ-mlv.fr |
> forax at univ-mlv.fr ] > wrote:

>> You also need the loop combinator for implementing early return (the return
>> keyword),
>> I think i have an example of how to map a small language to a loop combinator
>> somewhere,
>> i will try to find that (or rewrite it) tomorrow.

>> cheers,
>> Rémi

>>> De: "Charles Oliver Nutter" < [ mailto:headius at headius.com | headius at headius.com
>>> ] >
>>> À: "Da Vinci Machine Project" < [ mailto:mlvm-dev at openjdk.java.net |
>>> mlvm-dev at openjdk.java.net ] >
>>> Envoyé: Mardi 2 Janvier 2018 21:36:33
>>> Objet: Re: Writing a compiler to handles, but filter seems to executed in
>>> reverse

>>> An alternative workaround: I do the filters myself, manually, in the order that
>>> I want them to executed. Also gross.

>>> On Tue, Jan 2, 2018 at 2:35 PM Charles Oliver Nutter < [
>>> mailto:headius at headius.com | headius at headius.com ] > wrote:

>>>> Ahh I believe I see it now.
>>>> filterArguments starts with the first filter, and wraps the incoming target
>>>> handle with each in turn. However, because it's starting at the target, you get
>>>> the filters stacked up in reverse order:

>>>> filter(target, 0, a, b, c, d)

>>>> ends up as

>>>> d_filter(c_filter(b_filter(a_filter(target))))

>>>> And so naturally when invoked, they execute in reverse order.

>>>> This seems I am surprised we have not run into this as a problem, but I believe
>>>> most of my uses of filter in JRuby have been pure functions where order was not
>>>> important (except for error conditions).

>>>> Now in looking for a fix, I've run into the nasty workaround required to get
>>>> filters to execute in the correct order: you have to reverse the filters, and
>>>> then reverse the results again. This is far from desirable, since it requires
>>>> at least one permute to put the results back in proper order.

>>>> Is there a good justification for doing it this way, rather than having
>>>> filterArguments start with the *last* filter nearest the target?

>>>> - Charlie

>>>> On Tue, Jan 2, 2018 at 2:17 PM Charles Oliver Nutter < [
>>>> mailto:headius at headius.com | headius at headius.com ] > wrote:

>>>>> Hello all, long time no write!
>>>>> I'm finally playing with writing a "compiler" for JRuby that uses only method
>>>>> handles to represent code structure. For most simple expressions, this
>>>>> obviously works well. However I'm having trouble with blocks of code that
>>>>> contain multiple expressions.

>>>>> Starting with the standard call signature through the handle tree, we have a
>>>>> basic (Object[])Object type. The Object[] contains local variable state for the
>>>>> script, and will be as wide as there are local variables. AST nodes are
>>>>> basically compiled into little functions that take in the variable state and
>>>>> produce a value. In this way, every expression in the tree can be compiled,
>>>>> including local variable sets and gets, loops, and so on.

>>>>> Now the tricky bit...

>>>>> The root node for a given script contains one or more expressions that should be
>>>>> executed in sequence, with the final result being returned. The way I'm
>>>>> handling this in method handles is as follows (invokebinder code but hopefully
>>>>> easy to read):
>>>>> MethodHandle[] handles =
>>>>> Arrays
>>>>> . stream (rootNode.children())
>>>>> .map(node -> compile(node))
>>>>> .toArray(n -> new MethodHandle[n]);
>>>>> return Binder. from (Object. class , Object[]. class )
>>>>> .permute( new int [handles. length ])
>>>>> .filter( 0 , handles)
>>>>> .drop( 0 , handles. length - 1 )
>>>>> .identity();
>>>>> In pseudo-code, this basically duplicates the Object[] as many times as there
>>>>> are lines of code to execute, and then uses filterArguments to evaluate each in
>>>>> turn. Then everything but the last result is culled and the final result is
>>>>> returned.

>>>>> Unfortunately, this doesn't work right: filterArguments appears to execute in
>>>>> reverse order. When I try to run a simple script like "a = 1; a" the "a" value
>>>>> comes back null, because it is executed first.

>>>>> Is this expected? Do filters, when executed, actually process from the last
>>>>> argument back, rather than the first argument forward?

>>>>> Note: I know this would be possible to do with guaranteed ordering using the new
>>>>> loop combinators in 9. I'm working up to that for examples for a talk.

>>>>> - Charlie

>>> _______________________________________________
>>> mlvm-dev mailing list
>>> [ mailto:mlvm-dev at openjdk.java.net | mlvm-dev at openjdk.java.net ]
>>> [ http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev |
>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev ]

>> _______________________________________________
>> mlvm-dev mailing list
>> [ mailto:mlvm-dev at openjdk.java.net | mlvm-dev at openjdk.java.net ]
>> [ http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev |
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev ]

> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20180103/fef1a9c4/attachment.html>


More information about the mlvm-dev mailing list