Author: pmichaud
Date: Sun Nov  9 18:21:29 2008
New Revision: 32475

Added:
   trunk/languages/perl6/build/gen_junction_pir.pl
Modified:
   trunk/MANIFEST
   trunk/languages/perl6/config/makefiles/root.in
   trunk/languages/perl6/perl6.pir
   trunk/languages/perl6/src/classes/Junction.pir

Log:
[rakudo]:  Refactor of Junction handling, with ideas from bacek++ (RT #60168)


Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Sun Nov  9 18:21:29 2008
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Fri Nov  7 21:44:29 2008 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Mon Nov 10 02:19:53 2008 UT
 #
 # See tools/dev/install_files.pl for documentation on the
 # format of this file.
@@ -2063,6 +2063,7 @@
 languages/perl6/README                                      [perl6]
 languages/perl6/ROADMAP                                     [perl6]
 languages/perl6/Test.pm                                     [perl6]
+languages/perl6/build/gen_junction_pir.pl                   [perl6]
 languages/perl6/build/gen_objectref_pmc.pl                  [perl6]
 languages/perl6/config/makefiles/root.in                    [perl6]
 languages/perl6/config/makefiles/utils.in                   [perl6]

Added: trunk/languages/perl6/build/gen_junction_pir.pl
==============================================================================
--- (empty file)
+++ trunk/languages/perl6/build/gen_junction_pir.pl     Sun Nov  9 18:21:29 2008
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+# Copyright (C) 2008, The Perl Foundation.
+# $Id$
+
+my @binary = qw(
+  infix:**
+  infix:* infix:/ infix:% infix:div infix:mod
+  infix:+ infix:-
+  infix:== infix:!= infix:<  infix:>  infix:<= infix:>=
+  infix:eq infix:ne infix:lt infix:gt infix:le infix:ge
+);
+
+my @unary = qw(
+  prefix:++ prefix:-- postfix:++ postfix:--
+);
+
+my $output = $ARGV[0] || '-';
+
+open my $fh, "> $output" or die "Could not write $output: $!";
+
+for (@unary) {
+    print $fh qq(
+        .namespace []
+        .sub '$_' :multi('Junction')
+            .param pmc x
+            .tailcall '!DISPATCH_JUNCTION'('$_', x)
+        .end
+    );
+}
+
+for (@binary) {
+    print $fh qq(
+        .namespace []
+        .sub '$_' :multi('Junction', _)
+            .param pmc x
+            .param pmc y
+            .tailcall '!DISPATCH_JUNCTION'('$_', x, y)
+        .end
+        
+        .sub '$_' :multi(_, 'Junction')
+            .param pmc x
+            .param pmc y
+            .tailcall '!DISPATCH_JUNCTION'('$_', x, y)
+        .end
+    );
+}
+
+close $fh;
+0;

Modified: trunk/languages/perl6/config/makefiles/root.in
==============================================================================
--- trunk/languages/perl6/config/makefiles/root.in      (original)
+++ trunk/languages/perl6/config/makefiles/root.in      Sun Nov  9 18:21:29 2008
@@ -42,6 +42,7 @@
   src/gen_grammar.pir \
   src/gen_actions.pir \
   src/gen_builtins.pir \
+  src/gen_junction.pir \
   src/parser/expression.pir \
   src/parser/quote_expression.pir \
   $(PERL6_GROUP) \
@@ -134,6 +135,9 @@
 src/gen_builtins.pir: $(BUILTINS_PIR)
        $(CAT) $(BUILTINS_PIR) >src/gen_builtins.pir
 
+src/gen_junction.pir: build/gen_junction_pir.pl
+       $(PERL) build/gen_junction_pir.pl src/gen_junction.pir
+
 $(PERL6_GROUP): $(PARROT) $(PMC_SOURCES)
        cd $(PMC_DIR) && $(BUILD_DYNPMC) generate $(PMCS)
        cd $(PMC_DIR) && $(BUILD_DYNPMC) compile $(PMCS)

Modified: trunk/languages/perl6/perl6.pir
==============================================================================
--- trunk/languages/perl6/perl6.pir     (original)
+++ trunk/languages/perl6/perl6.pir     Sun Nov  9 18:21:29 2008
@@ -227,6 +227,7 @@
 .include 'src/parser/expression.pir'
 .include 'src/parser/quote_expression.pir'
 .include 'src/gen_actions.pir'
+.include 'src/gen_junction.pir'
 
 
 =back

Modified: trunk/languages/perl6/src/classes/Junction.pir
==============================================================================
--- trunk/languages/perl6/src/classes/Junction.pir      (original)
+++ trunk/languages/perl6/src/classes/Junction.pir      Sun Nov  9 18:21:29 2008
@@ -4,1587 +4,345 @@
 
 src/classes/Junction.pir - Perl 6 Junction and related functions
 
-=head1 Methods
-
-=over 4
-
 =cut
 
-.namespace ['Junction']
-
 # Constants for types of junctions.
-.const int JUNCTION_TYPE_ALL  = 1
-.const int JUNCTION_TYPE_ANY  = 2
-.const int JUNCTION_TYPE_ONE  = 3
+.const int JUNCTION_TYPE_ANY  = 1
+.const int JUNCTION_TYPE_ONE  = 2
+.const int JUNCTION_TYPE_ALL  = 3
 .const int JUNCTION_TYPE_NONE = 4
 
+.namespace []
 .sub 'onload' :anon :load :init
     .local pmc p6meta
     p6meta = get_hll_global ['Perl6Object'], '$!P6META'
-    p6meta.'new_class'('Junction', 'parent'=>'Perl6Object', 'attr'=>'@values 
$type')
+    p6meta.'new_class'('Junction', 'parent'=>'Perl6Object', 
'attr'=>'@!eigenstates $!type')
 .end
 
+=head2 Methods
+
+=over 4
 
-=item Scalar
+=item perl()
 
-This is a value type, so just returns itself.
+Return perl representation.  (This should actually be autothreaded.)
 
 =cut
 
-.sub 'Scalar' :method
-    .return (self)
+.namespace ['Junction']
+.sub 'perl' :method
+    .local int type
+    type = self.'!type'()
+
+    .local string res
+    if type == JUNCTION_TYPE_ANY goto any
+    if type == JUNCTION_TYPE_ONE goto one
+    if type == JUNCTION_TYPE_ALL goto all
+    if type == JUNCTION_TYPE_NONE goto none
+  any:
+    res = 'any('
+    goto type_done
+  one:
+    res = 'one('
+    goto type_done
+  all:
+    res = 'all('
+    goto type_done
+  none:
+    res = 'none('
+  type_done:
+
+    .local pmc it
+    $P0 = self.'!eigenstates'()
+    it = iter $P0
+    unless it goto states_done
+    $P0 = shift it
+    $S0 = $P0.'perl'()
+    concat res, $S0
+  states_loop:
+    unless it goto states_done
+    $P0 = shift it
+    $S0 = $P0.'perl'()
+    concat res, ', '
+    concat res, $S0
+    goto states_loop
+  states_done:
+    concat res, ')'
+    .return (res)
 .end
 
 
-=item ACCEPTS
+=item true()
 
-Implements smart-match for junctions.
+Evaluate Junction as a boolean.
 
 =cut
 
-.sub 'ACCEPTS' :method
-    .param pmc topic
-    .local pmc type, values, it, cur_val
-    type = getattribute self, "$type"
-    values = getattribute self, "@values"
-    it = iter values
-    if type == JUNCTION_TYPE_ALL goto all
-    if type == JUNCTION_TYPE_ANY goto any
-    if type == JUNCTION_TYPE_ONE goto one
+.namespace ['Junction']
+.sub 'true' :method
+    .local pmc eigenstates, it
+    .local int type
+    eigenstates = self.'!eigenstates'()
+    it = iter eigenstates
+    type = self.'!type'()
     if type == JUNCTION_TYPE_NONE goto none
+    if type == JUNCTION_TYPE_ALL goto all
 
-  all:
-    unless it goto true
-    cur_val = shift it
-    $P0 = cur_val.'ACCEPTS'(topic)
-    unless $P0 goto false
-    goto all
-
-  any:
+  any_one:
     unless it goto false
-    cur_val = shift it
-    $P0 = cur_val.'ACCEPTS'(topic)
-    if $P0 goto true
-    goto any
+    $P0 = shift it
+    unless $P0 goto any_one
+    if type == JUNCTION_TYPE_ANY goto true
+    # fall through
 
   none:
     unless it goto true
-    cur_val = shift it
-    $P0 = cur_val.'ACCEPTS'(topic)
+    $P0 = shift it
     if $P0 goto false
     goto none
 
-  one:
-    $I0 = 0
-    unless it goto done_one
-    cur_val = shift it
-    $P0 = cur_val.'ACCEPTS'(topic)
-    unless $P0 goto one
-    inc $I0
-    if $I0 > 1 goto true
-    goto one
-  done_one:
-    if $I0 == 1 goto true
-    goto false
+  all:
+    unless it goto true
+    $P0 = shift it
+    if $P0 goto all
+    # fall through
 
-  true:
-    $P0 = get_hll_global [ 'Bool' ], 'True'
-    .return ($P0)
   false:
-    $P0 = get_hll_global [ 'Bool' ], 'False'
+    $P0 = get_hll_global ['Bool'], 'False'
     .return ($P0)
-.end
 
+  true:
+    $P0 = get_hll_global ['Bool'], 'True'
+    .return ($P0)
+.end
 
-=item values()
+=item ACCEPTS
 
-Get the values in the junction.
+Smart-matching for junctions, short-circuiting.
 
 =cut
 
-.sub 'values' :method
-    $P0 = getattribute self, "@values"
-    unless null $P0 goto have_values
-    .return 'list'()
-  have_values:
-    $P0 = clone $P0
-    .return($P0)
-.end
+.namespace ['Junction']
+.sub 'ACCEPTS' :method
+    .param pmc topic
+    .local pmc eigenstates, it, state
+    .local int type
+    eigenstates = self.'!eigenstates'()
+    it = iter eigenstates
+    type = self.'!type'()
+    if type == JUNCTION_TYPE_NONE goto none
+    if type == JUNCTION_TYPE_ALL goto all
 
+  any_one:
+    unless it goto false
+    state = shift it
+    $P0 = state.'ACCEPTS'(topic)
+    unless $P0 goto any_one
+    if type == JUNCTION_TYPE_ANY goto true
+    # fall through
 
-=item !values(...)
+  none:
+    unless it goto true
+    state = shift it
+    $P0 = state.'ACCEPTS'(topic)
+    if $P0 goto false
+    goto none
 
-Private method to sets the values in the junction.
+  all:
+    unless it goto true
+    state = shift it
+    $P0 = state.'ACCEPTS'(topic)
+    if $P0 goto all
 
-=cut
+  false:
+    $P0 = get_hll_global ['Bool'], 'False'
+    .return ($P0)
 
-.sub '!values' :method
-    .param pmc l
-    l = 'list'(l :flat)
-    setattribute self, "@values", l
+  true:
+    $P0 = get_hll_global ['Bool'], 'True'
+    .return ($P0)
 .end
+    
 
+=item !type()
 
-=item !type(...)
+Return the type of the Junction.
 
-Private method to set the type of the junction.
+=item !eigenstates()
+
+Return the components of the Junction.
 
 =cut
 
+.namespace ['Junction']
 .sub '!type' :method
-    .param pmc type     :optional
-    .param int got_type :opt_flag
-    unless got_type goto ret_type
-    setattribute self, "$type", type
-    .return()
-ret_type:
-    type = getattribute self, "$type"
-    .return(type)
+    $P0 = getattribute self, '$!type'
+    .return ($P0)
 .end
 
-
-=item clone
-
-Clone v-table method.
-
-=cut
-
-.sub 'clone' :method :vtable
-    .local pmc junc_class, junc
-    junc_class = class self
-    junc = new junc_class
-
-    # Copy values and set type.
-    $P0 = self.'values'()
-    $P0 = clone $P0
-    junc.'!values'($P0)
-    $P0 = self.'!type'()
-    junc.'!type'($P0)
-
-    .return(junc)
+.sub '!eigenstates' :method
+    $P0 = getattribute self, '@!eigenstates'
+    .return ($P0)
 .end
 
 
-=item perl()
+=back
 
-Returns a Perl representation of a junction.
+=head2 VTABLE functions
 
 =cut
 
-.sub 'perl' :method
-    # Emit junction type.
-    .local int type
-    .local string res
-    type = self.'!type'()
-    if type == JUNCTION_TYPE_ALL goto all
-    if type == JUNCTION_TYPE_ANY goto any
-    if type == JUNCTION_TYPE_ONE goto one
-    if type == JUNCTION_TYPE_NONE goto none
-
-  all:
-    res = 'all'
-    goto okay
-  any:
-    res = 'any'
-    goto okay
-  one:
-    res = 'one'
-    goto okay
-  none:
-    res = 'none'
-    goto okay
-  okay:
-    concat res, '('
-
-    # Now emit .perl of all the values.
-    .local pmc values, iter, value
-    .local int first
-    first = 1
-    values = self.'values'()
-    iter = new 'Iterator', values
-  iter_loop:
-    unless iter goto iter_loop_end
-    if first goto first_time
-    concat res, ", "
-  first_time:
-    first = 0
-    value = shift iter
-    $S0 = value.perl()
-    concat res, $S0
-    goto iter_loop
-  iter_loop_end:
-
-    # Done.
-    concat res, ')'
-    .return (res)
+.namespace ['Junction']
+.sub '' :method :vtable('get_bool')
+    $I0 = self.'true'()
+    .return ($I0)
 .end
 
 
 =back
 
-=head1 Functions
-
-=over 4
+=head2 Helper functions
 
 =cut
 
 .namespace []
-
-=item C<all(...)>
-
-Builds an 'all' junction from its arguments.
-
-=cut
-
-.sub 'all'
-    .param pmc args            :slurpy
-    .local pmc junc_proto, junc
-    junc_proto = get_hll_global 'Junction'
-    junc = junc_proto.'new'()
-
-    junc."!values"(args)
-    junc."!type"(JUNCTION_TYPE_ALL)
-
+.sub '!MAKE_JUNCTION'
+    .param pmc type
+    .param pmc eigenstates
+
+    .local pmc junc
+    $P0 = get_hll_global 'Junction'
+    junc = $P0.'new'()
+    setattribute junc, '$!type', type
+    setattribute junc, '@!eigenstates', eigenstates
     .return (junc)
 .end
+    
+.sub '!DISPATCH_JUNCTION'
+    .param pmc the_sub
+    .param pmc args            :slurpy
 
+    ##  lookup a sub by name if needed
+    $I0 = isa the_sub, 'Sub'
+    if $I0 goto have_sub
+    $S0 = the_sub
+    the_sub = find_name $S0
+  have_sub:
 
-=item C<infix:&(...)>
-
-Operator form for building an 'all' junction.
-
-=cut
-
-.sub 'infix:&'
-    .param pmc args            :slurpy
-    .return 'all'(args :flat)
+    ##  Look for the left-most junction.
+    .local int argc, index, index_save
+    argc = args
+    index = 0
+  left_loop:
+    unless index < argc goto left_done
+    .local pmc junc
+    junc = args[index]
+    $I0 = isa junc, 'Junction'
+    if $I0 goto left_done
+    inc index
+    goto left_loop
+  left_done:
+    ##  If it's an all/none junction, we're good
+    .local int type
+    type = junc.'!type'()
+    if type >= JUNCTION_TYPE_ALL goto have_index
+    ##  one/any junction, so look through the remaining args for all/none
+    index_save = index
+    inc index
+  all_loop:
+    unless index < argc goto all_done
+    junc = args[index]
+    $I0 = isa junc, 'Junction'
+    unless $I0 goto all_next
+    type = junc.'!type'()
+    if type >= JUNCTION_TYPE_ALL goto have_index
+  all_next:
+    inc index
+    goto all_loop
+  all_done:
+    index = index_save
+    junc = args[index]
+    type = junc.'!type'()
+  have_index:
+
+    .local pmc eigenstates, it, results
+    eigenstates = junc.'!eigenstates'()
+    it = iter eigenstates
+    results = 'list'()
+  thread_loop:
+    unless it goto thread_done
+    $P0 = shift it
+    args[index] = $P0
+    $P0 = the_sub(args :flat)
+    push results, $P0
+    goto thread_loop
+  thread_done:
+    .tailcall '!MAKE_JUNCTION'(type, results)
 .end
 
+=head2 Functions
 
-=item C<any(...)>
+=over 4
 
-Builds an 'any' junction from its arguments.
+=item any(), infix:<|>()
 
 =cut
 
+.namespace []
 .sub 'any'
     .param pmc args            :slurpy
-    .local pmc junc_proto, junc
-    junc_proto = get_hll_global 'Junction'
-    junc = junc_proto.'new'()
-
-    junc."!values"(args)
-    junc."!type"(JUNCTION_TYPE_ANY)
-
-    .return (junc)
+    args.'!flatten'()
+    .tailcall '!MAKE_JUNCTION'(JUNCTION_TYPE_ANY, args)
 .end
 
-
-=item C<infix:|(...)>
-
-Operator form for building an 'any' junction.
-
-=cut
-
 .sub 'infix:|'
     .param pmc args            :slurpy
-    .return 'any'(args :flat)
+    .tailcall '!MAKE_JUNCTION'(JUNCTION_TYPE_ANY, args)
 .end
 
-
-=item C<one(...)>
-
-Builds a 'one' junction from its arguments.
+=item one(), infix:<^>()
 
 =cut
 
+.namespace []
 .sub 'one'
     .param pmc args            :slurpy
-    .local pmc junc_proto, junc
-    junc_proto = get_hll_global 'Junction'
-    junc = junc_proto.'new'()
-
-    junc."!values"(args)
-    junc."!type"(JUNCTION_TYPE_ONE)
-
-    .return (junc)
+    args.'!flatten'()
+    .tailcall '!MAKE_JUNCTION'(JUNCTION_TYPE_ONE, args)
 .end
 
-
-=item C<infix:^(...)>
-
-Operator form for building a 'one' junction.
-
-=cut
-
 .sub 'infix:^'
     .param pmc args            :slurpy
-    .return 'one'(args :flat)
+    .tailcall '!MAKE_JUNCTION'(JUNCTION_TYPE_ONE, args)
 .end
 
 
-=item C<none(...)>
-
-Builds a 'none' junction from its arguments.
+=item all(), infix:<&>()
 
 =cut
 
-.sub 'none'
+.namespace []
+.sub 'all'
     .param pmc args            :slurpy
-    .local pmc junc_proto, junc
-    junc_proto = get_hll_global 'Junction'
-    junc = junc_proto.'new'()
-
-    junc."!values"(args)
-    junc."!type"(JUNCTION_TYPE_NONE)
-    .return (junc)
-.end
-
-
-=item C<!junction_dispatcher(...)>
-
-Takes a name or Sub PMC along with a set of arguments, and auto-threads the
-call.
-
-TODO: Collect return values.
-
-TODO: Handle the case where junctions contain other junctions.
-
-TODO: When we get the type system in place, check for Junction in signature of
-callee; in these cases, we needn't auto-thread, but instead should pass the
-junction.
-
-=cut
-
-.sub '!junction_dispatcher'
-    .param pmc the_sub
-    .param pmc args :slurpy
-
-    # Build list of lists of possible arguments.
-    .local int num_args
-    .local int i
-    .local pmc possibles
-    possibles = new 'List'
-    num_args = elements args
-    i = 0
-get_possibles_loop:
-    if i >= num_args goto get_possibles_loop_end
-    $P0 = args[i]
-    $I0 = isa $P0, 'Junction'
-    if $I0 goto is_junction
-    $P1 = new 'List'
-    push $P1, $P0
-    goto done_possible
-is_junction:
-    $P1 = $P0.values()
-done_possible:
-    possibles[i] = $P1
-    inc i
-    goto get_possibles_loop
-get_possibles_loop_end:
-
-    # Get all permutations.
-    .local pmc perms
-    perms = 'infix:X'(possibles :flat)
-    $I0 = elements perms
-
-    # If we have a sub name, we need to look it up.
-    $I0 = isa the_sub, 'Code'
-    if $I0 goto have_code
-    $S0 = the_sub
-    the_sub = find_global $S0
-have_code:
-
-    # Now call it for each permutation.
-    num_args = elements perms
-    i = 0
-call_loop:
-    if i >= num_args goto call_loop_end
-    $P0 = perms[i]
-    the_sub($P0 :flat)
-    inc i
-    goto call_loop
-call_loop_end:
-.end
-
-
-=item C<postfix:++(...)>
-
-Override postfix increment for junctions.
-
-=cut
-
-.sub 'postfix:++' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'postfix:++'
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<postfix:--(...)>
-
-Override postfix decrement for junctions.
-
-=cut
-
-.sub 'postfix:--' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'postfix:--'
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<prefix:++(...)>
-
-Override prefix increment for junctions.
-
-=cut
-
-.sub 'prefix:++' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:++'
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<prefix:--(...)>
-
-Override prefix decrement for junctions.
-
-=cut
-
-.sub 'prefix:--' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:--'
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<prefix:!(...)>
-
-Override not for junctions.
-
-=cut
-
-.sub 'prefix:!' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:!'
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<prefix:+(...)>
-
-Override numification for junctions.
-
-=cut
-
-.sub 'prefix:+' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:+'
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<prefix:-(...)>
-
-Override negation for junctions.
-
-=cut
-
-.sub 'prefix:-' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:-'
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<prefix:~(...)>
-
-Override stringification for junctions.
-
-=cut
-
-.sub 'prefix:~' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:~'
-    .return unary_junction_helper($P0, j)
+    args.'!flatten'()
+    .tailcall '!MAKE_JUNCTION'(JUNCTION_TYPE_ALL, args)
 .end
 
-
-=item C<prefix:?(...)>
-
-Override boolification for junctions.
-
-=cut
-
-.sub 'prefix:?' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:?'
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<prefix:=(...)>
-
-Override iteration for junctions.
-
-=cut
-
-.sub 'prefix:=' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:='
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<prefix:~^(...)>
-
-Override string bitwise negation for junctions.
-
-=cut
-
-.sub 'prefix:~^' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:~^'
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<prefix:+^(...)>
-
-Override numeric bitwise negation for junctions.
-
-=cut
-
-.sub 'prefix:+^' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:+^'
-    .return unary_junction_helper($P0, j)
+.sub 'infix:&'
+    .param pmc args            :slurpy
+    .tailcall '!MAKE_JUNCTION'(JUNCTION_TYPE_ALL, args)
 .end
 
 
-=item C<prefix:?^(...)>
-
-Override boolean bitwise negation for junctions.
+=item none()
 
 =cut
 
-.sub 'prefix:?^' :multi('Junction')
-    .param pmc j
-    $P0 = find_global 'prefix:?^'
-    .return unary_junction_helper($P0, j)
-.end
-
-
-=item C<infix:**(...)>
-
-Override exponentiation for junctions.
-
-=cut
-
-.sub 'infix:**' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:**'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:**' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:**'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:**' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:**'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:%(...)>
-
-Override modulo for junctions.
-
-=cut
-
-.sub 'infix:%' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:%'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:%' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:%'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:%' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:%'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:/(...)>
-
-Override division for junctions.
-
-=cut
-
-.sub 'infix:/' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:/'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:/' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:/'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:/' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:/'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:*(...)>
-
-Override multiply for junctions.
-
-=cut
-
-.sub 'infix:*' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:*'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:*' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:*'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:*' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:*'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:+&(...)>
-
-Override numeric bitwise and for junctions.
-
-=cut
-
-.sub 'infix:+&' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:+&'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:+&' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:+&'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:+&' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:+&'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:+<(...)>
-
-Override numeric left shift for junctions.
-
-=cut
-
-.sub 'infix:+<' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:+<'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:+<' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:+<'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:+<' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:+<'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:+>(...)>
-
-Override numeric right shift for junctions.
-
-=cut
-
-.sub 'infix:+>' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:+>'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:+>' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:+>'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:+>' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:+>'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:div(...)>
-
-Override div for junctions.
-
-=cut
-
-.sub 'infix:div' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:div'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:div' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:div'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:div' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:div'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:mod(...)>
-
-Override mod for junctions.
-
-=cut
-
-.sub 'infix:mod' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:mod'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:mod' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:mod'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:mod' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:mod'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:~&(...)>
-
-Override buffer bitwise and for junctions.
-
-=cut
-
-.sub 'infix:~&' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:~&'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:~&' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:~&'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:~&' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:~&'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:~<(...)>
-
-Override buffer bitwise left shift for junctions.
-
-=cut
-
-.sub 'infix:~<' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:~<'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:~<' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:~<'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:~<' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:~<'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:~>(...)>
-
-Override buffer bitwise right shift for junctions.
-
-=cut
-
-.sub 'infix:~>' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:~>'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:~>' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:~>'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:~>' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:~>'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:?&(...)>
-
-Override boolean bitwise and for junctions.
-
-=cut
-
-.sub 'infix:?&' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:?&'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:?&' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:?&'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:?&' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:?&'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:+(...)>
-
-Override addition for junctions.
-
-=cut
-
-.sub 'infix:+' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:+'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:+' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:+'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:+' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:+'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:-(...)>
-
-Override subtraction for junctions.
-
-=cut
-
-.sub 'infix:-' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:-'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:-' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:-'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:-' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:-'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:x(...)>
-
-Override repeat for junctions.
-
-=cut
-
-.sub 'infix:x' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:x'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:x' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:x'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:x' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:x'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:xx(...)>
-
-Override array repeat for junctions.
-
-=cut
-
-.sub 'infix:xx' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:xx'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:xx' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:xx'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:xx' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:xx'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:~(...)>
-
-Override concatenation for junctions.
-
-=cut
-
-.sub 'infix:~' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global 'infix:~'
-    .return infix_junction_helper($P0, j1, j2)
-.end
-
-.sub 'infix:~' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global 'infix:~'
-    .return infix_junction_helper($P0, j, x)
-.end
-
-.sub 'infix:~' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global 'infix:~'
-    .return infix_junction_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:==(...)>
-
-Override numerical equality for junctions.
-
-=cut
-
-.sub 'infix:==' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:=="
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:==' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:=="
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:==' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:=="
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:!=(...)>
-
-Override numerical inequality for junctions.
-
-=cut
-
-.sub 'infix:!=' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:!="
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:!=' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:!="
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:!=' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:!="
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:>(...)>
-
-Override numerical greater than for junctions.
-
-=cut
-
-.sub 'infix:>' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:>"
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:>' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:>"
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:>' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:>"
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:<(...)>
-
-Override numerical less than for junctions.
-
-=cut
-
-.sub 'infix:<' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:<"
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:<' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:<"
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:<' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:<"
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:>=(...)>
-
-Override numerical greater than or equal to for junctions.
-
-=cut
-
-.sub 'infix:>=' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:>="
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:>=' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:>="
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:>=' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:>="
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:<=(...)>
-
-Override numerical less than or equal to for junctions.
-
-=cut
-
-.sub 'infix:<=' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:<="
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:<=' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:<="
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:<=' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:<="
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:eq(...)>
-
-Override string equality for junctions.
-
-=cut
-
-.sub 'infix:eq' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:eq"
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:eq' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:eq"
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:eq' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:eq"
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:ne(...)>
-
-Override string inequality for junctions.
-
-=cut
-
-.sub 'infix:ne' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:ne"
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:ne' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:ne"
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:ne' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:ne"
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:lt(...)>
-
-Override string less than for junctions.
-
-=cut
-
-.sub 'infix:lt' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:lt"
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:lt' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:lt"
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:lt' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:lt"
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:gt(...)>
-
-Override string greater than for junctions.
-
-=cut
-
-.sub 'infix:gt' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:gt"
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:gt' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:gt"
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:gt' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:gt"
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:le(...)>
-
-Override string less than or equal for junctions.
-
-=cut
-
-.sub 'infix:le' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:le"
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:le' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:le"
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:le' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:le"
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-=item C<infix:ge(...)>
-
-Override string greater than or equal for junctions.
-
-=cut
-
-.sub 'infix:ge' :multi('Junction','Junction')
-    .param pmc j1
-    .param pmc j2
-    $P0 = find_global "infix:ge"
-    .return junction_comparrison_helper($P0, j1, j2, 0)
-.end
-
-.sub 'infix:ge' :multi('Junction',_)
-    .param pmc j
-    .param pmc x
-    $P0 = find_global "infix:ge"
-    .return junction_comparrison_helper($P0, j, x, 0)
-.end
-
-.sub 'infix:ge' :multi(_,'Junction')
-    .param pmc x
-    .param pmc j
-    $P0 = find_global "infix:ge"
-    .return junction_comparrison_helper($P0, j, x, 1)
-.end
-
-
-# Helper sub for applying non-comparative infixes to junctions.
-.sub infix_junction_helper :anon
-    .param pmc op_sub
-    .param pmc j
-    .param pmc x
-    .param int second_arg :optional
-
-    # Build hash of results, to ensure we are unique.
-    .local pmc ResultHash
-    ResultHash = new 'Hash'
-
-    # Get values array.
-    .local pmc values
-    values = j.'values'()
-
-    # Loop over it and call inc on each element.
-    .local int count
-    .local int i
-    .local pmc cur_elem
-    count = elements values
-    i = 0
-loop:
-    if i >= count goto loop_end
-    cur_elem = values[i]
-    if second_arg goto sa
-    $P0 = op_sub(cur_elem, x)
-    goto nsa
-sa:
-    $P0 = op_sub(x, cur_elem)
-nsa:
-    ResultHash[$P0] = 1
-    inc i
-    goto loop
-loop_end:
-
-    # Build junction of results.
-    .local pmc new_junc
-    .local pmc new_values
-    .local pmc iterator
-    .local pmc type
-
-    new_junc = new 'Junction'
-    type = j.'!type'()
-    new_junc.'!type'(type)
-
-    new_values = new 'List'
-    iterator = iter ResultHash
-nv_loop:
-    unless iterator goto nv_loop_end
-    $P0 = shift iterator
-    push new_values, $P0
-    goto nv_loop
-nv_loop_end:
-    new_junc.'!values'(new_values)
-
-    .return(new_junc)
-.end
-
-# Helper sub for junction comparrisons.
-.sub junction_comparrison_helper :anon
-    .param pmc op_func
-    .param pmc j
-    .param pmc x
-    .param int second_arg
-
-    # We need to find how many values are equal.
-    .local pmc values
-    .local int num_equal
-    .local int count
-    .local int i
-    values = j.'values'()
-    count = elements values
-    i = 0
-    num_equal = 0
-loop:
-    if i >= count goto end_loop
-    $P0 = values[i]
-    if second_arg goto sa
-    $I0 = op_func($P0, x)
-    goto not_sa
-sa:
-    $I0 = op_func(x, $P0)
-not_sa:
-    num_equal += $I0
-    inc i
-    goto loop
-end_loop:
-
-    # Now go by juction type.
-    .local int type
-    type = j.'!type'()
-    if type == JUNCTION_TYPE_ALL goto all
-    if type == JUNCTION_TYPE_ANY goto any
-    if type == JUNCTION_TYPE_ONE goto one
-    if type == JUNCTION_TYPE_NONE goto none
-
-all:
-    if num_equal == count goto ret_true
-    goto ret_false
-any:
-    if num_equal > 0 goto ret_true
-    goto ret_false
-one:
-    if num_equal == 1 goto ret_true
-    goto ret_false
-none:
-    if num_equal == 0 goto ret_true
-    goto ret_false
-
-ret_true:
-    $P0 = get_hll_global ['Bool'], 'True'
-    .return($P0)
-ret_false:
-    $P0 = get_hll_global ['Bool'], 'False'
-    .return($P0)
-.end
-
-
-# Helper sub for implementing unary operators.
-.sub unary_junction_helper :anon
-    .param pmc op_sub
-    .param pmc j
-
-    # Build hash of results, to ensure we are unique.
-    .local pmc ResultHash
-    ResultHash = new 'Hash'
-
-    # Loop over and call multiply on each value.
-    # Get values array.
-    .local pmc values
-    values = j.'values'()
-
-    # Loop over it and call inc on each element.
-    .local int count
-    .local int i
-    .local pmc cur_elem
-    count = elements values
-    i = 0
-loop:
-    if i >= count goto loop_end
-    cur_elem = values[i]
-    $P0 = op_sub(cur_elem)
-    ResultHash[$P0] = 1
-    inc i
-    goto loop
-loop_end:
-
-    # Build junction of results.
-    .local pmc new_junc
-    .local pmc new_values
-    .local pmc iterator
-    .local pmc type
-
-    new_junc = new 'Junction'
-    type = j.'!type'()
-    new_junc.'!type'(type)
-
-    new_values = new 'List'
-    iterator = iter ResultHash
-nv_loop:
-    unless iterator goto nv_loop_end
-    $P0 = shift iterator
-    push new_values, $P0
-    goto nv_loop
-nv_loop_end:
-    new_junc.'!values'(new_values)
-
-    .return(new_junc)
+.namespace []
+.sub 'none'
+    .param pmc args            :slurpy
+    args.'!flatten'()
+    .tailcall '!MAKE_JUNCTION'(JUNCTION_TYPE_NONE, args)
 .end
 
 

Reply via email to