Writing a compiler to handles, but filter seems to executed in reverse
Charles Oliver Nutter
headius at headius.com
Tue Jan 2 20:36:33 UTC 2018
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 <headius at headius.com>
> 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
> 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
> 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 <headius at headius.com>
>> 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
>> 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 =
>> .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)
>> 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
>> - Charlie
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the mlvm-dev