| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-12-22 17:05:20 +0100 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-12-22 17:05:20 +0100 | 
| commit | 81fa9a42ac0e47b4eb24cb6c0e619c21f364ea8a (patch) | |
| tree | a0866b7e97b76c7a8b691575d08fc83168270595 /src/core | |
| parent | d597bdec8c47fd388fb056f6a3238be23bd509b6 (diff) | |
Indexed Merge with defaults.
Diffstat (limited to 'src/core')
6 files changed, 728 insertions, 5 deletions
| diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java index 3a81b53..f9f8ae4 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java @@ -23,7 +23,9 @@ public class IndexedMergeComputation extends Computation     protected final List<Computation> extra_params;     protected final Computation lambda_function;     protected final Computation collection_in_a; +   protected final Computation default_a;     protected final Computation collection_in_b; +   protected final Computation default_b;     protected final boolean to_set;     /***************************************************************************/ @@ -35,7 +37,9 @@ public class IndexedMergeComputation extends Computation        final Origin origin,        final Computation lambda_function,        final Computation collection_in_a, +      final Computation default_a,        final Computation collection_in_b, +      final Computation default_b,        final boolean to_set,        final List<Computation> extra_params,        final Type output_type @@ -45,7 +49,9 @@ public class IndexedMergeComputation extends Computation        this.lambda_function = lambda_function;        this.collection_in_a = collection_in_a; +      this.default_a = default_a;        this.collection_in_b = collection_in_b; +      this.default_b = default_b;        this.to_set = to_set;        this.extra_params = extra_params;     } @@ -59,7 +65,9 @@ public class IndexedMergeComputation extends Computation        final Origin origin,        final Computation lambda_function,        final Computation collection_in_a, +      final Computation default_a,        final Computation collection_in_b, +      final Computation default_b,        final boolean to_set,        final List<Computation> extra_params     ) @@ -69,8 +77,23 @@ public class IndexedMergeComputation extends Computation        types_in = new ArrayList<Type>(); -      RecurrentChecks.assert_is_a_collection(collection_in_a); -      RecurrentChecks.assert_is_a_collection(collection_in_b); +      if (default_a == null) +      { +         RecurrentChecks.assert_is_a_collection(collection_in_a); +      } +      else +      { +         RecurrentChecks.assert_is_a_collection_of(collection_in_a, default_a); +      } + +      if (default_b == null) +      { +         RecurrentChecks.assert_is_a_collection(collection_in_b); +      } +      else +      { +         RecurrentChecks.assert_is_a_collection_of(collection_in_b, default_b); +      }        types_in.add(Type.INT); @@ -79,6 +102,15 @@ public class IndexedMergeComputation extends Computation           ((CollectionType) collection_in_a.get_type()).get_content_type()        ); +      if (default_b != null) +      { +         /* +          * Safe-Mode: two indices. +          * Unsafe-Mode: only one index, since out-of-bound means stopping. +          */ +         types_in.add(Type.INT); +      } +        types_in.add        (           ((CollectionType) collection_in_b.get_type()).get_content_type() @@ -97,7 +129,9 @@ public class IndexedMergeComputation extends Computation              origin,              lambda_function,              collection_in_a, +            default_a,              collection_in_b, +            default_b,              to_set,              extra_params,              CollectionType.build @@ -128,11 +162,21 @@ public class IndexedMergeComputation extends Computation        return collection_in_a;     } +   public Computation get_default_a () +   { +      return default_a; +   } +     public Computation get_collection_in_b ()     {        return collection_in_b;     } +   public Computation get_default_b () +   { +      return default_b; +   } +     public List<Computation> get_extra_parameters ()     {        return extra_params; @@ -163,7 +207,27 @@ public class IndexedMergeComputation extends Computation        sb.append(collection_in_a.toString());        sb.append(" "); +      if (default_a == null) +      { +         sb.append("null"); +      } +      else +      { +         sb.append(default_a.toString()); +      } + +      sb.append(" ");        sb.append(collection_in_b.toString()); +      sb.append(" "); + +      if (default_b == null) +      { +         sb.append("null"); +      } +      else +      { +         sb.append(default_b.toString()); +      }        for (final Computation c: extra_params)        { diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java b/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java index 5fd86ec..96cfefc 100644 --- a/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java @@ -23,7 +23,9 @@ public class IndexedMerge extends Instruction     protected final List<Computation> extra_params;     protected final Computation lambda_function;     protected final Reference collection; +   protected final Computation default_a;     protected final Computation collection_in_b; +   protected final Computation default_b;     /***************************************************************************/     /**** PROTECTED ************************************************************/ @@ -34,7 +36,9 @@ public class IndexedMerge extends Instruction        final Origin origin,        final Computation lambda_function,        final Reference collection, +      final Computation default_a,        final Computation collection_in_b, +      final Computation default_b,        final List<Computation> extra_params     )     { @@ -42,7 +46,9 @@ public class IndexedMerge extends Instruction        this.lambda_function = lambda_function;        this.collection = collection; +      this.default_a = default_a;        this.collection_in_b = collection_in_b; +      this.default_b = default_b;        this.extra_params = extra_params;     } @@ -55,7 +61,9 @@ public class IndexedMerge extends Instruction        final Origin origin,        final Computation lambda_function,        final Reference collection, +      final Computation default_a,        final Computation collection_in_b, +      final Computation default_b,        final List<Computation> extra_params     )     throws Throwable @@ -64,8 +72,23 @@ public class IndexedMerge extends Instruction        types_in = new ArrayList<Type>(); -      RecurrentChecks.assert_is_a_collection(collection); -      RecurrentChecks.assert_is_a_collection(collection_in_b); +      if (default_a == null) +      { +         RecurrentChecks.assert_is_a_collection(collection); +      } +      else +      { +         RecurrentChecks.assert_is_a_collection_of(collection, default_a); +      } + +      if (default_b == null) +      { +         RecurrentChecks.assert_is_a_collection(collection_in_b); +      } +      else +      { +         RecurrentChecks.assert_is_a_collection_of(collection_in_b, default_b); +      }        types_in.add(Type.INT);        types_in.add @@ -73,6 +96,11 @@ public class IndexedMerge extends Instruction           ((CollectionType) collection.get_type()).get_content_type()        ); +      if (default_b != null) +      { +         types_in.add(Type.INT); +      } +        types_in.add        (           ((CollectionType) collection_in_b.get_type()).get_content_type() @@ -96,7 +124,9 @@ public class IndexedMerge extends Instruction              origin,              lambda_function,              collection, +            default_a,              collection_in_b, +            default_b,              extra_params           );     } @@ -114,11 +144,21 @@ public class IndexedMerge extends Instruction        return lambda_function;     } +   public Computation get_default_a () +   { +      return default_a; +   } +     public Computation get_collection_in_b ()     {        return collection_in_b;     } +   public Computation get_default_b () +   { +      return default_b; +   } +     public Reference get_collection ()     {        return collection; @@ -139,9 +179,29 @@ public class IndexedMerge extends Instruction        sb.append(lambda_function.toString());        sb.append(" ");        sb.append(collection.toString()); +      sb.append(" "); + +      if (default_a == null) +      { +         sb.append("null"); +      } +      else +      { +         sb.append(default_a.toString()); +      }        sb.append(" ");        sb.append(collection_in_b.toString()); +      sb.append(" "); + +      if (default_b == null) +      { +         sb.append("null"); +      } +      else +      { +         sb.append(default_b.toString()); +      }        for (final Computation c: extra_params)        { diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 4d791e3..6f84490 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -1017,7 +1017,9 @@ returns [Instruction result]              ),              ($fun.result),              ($value_reference.result), +            null,              ($inv1.result), +            null,              new ArrayList()           );     } @@ -1039,7 +1041,9 @@ returns [Instruction result]              ),              ($fun.result),              ($value_reference.result), +            null,              ($inv1.result), +            null,              ($value_list.result)           );     } @@ -1095,6 +1099,57 @@ returns [Instruction result]           );     } +   | SAFE_IMP_INDEXED_MERGE_KW +      fun=non_text_value WS+ +      def0=value WS+ +      value_reference WS+ +      def1=value WS+ +      inv1=non_text_value WS* +      R_PAREN +   { +      $result = +         IndexedMerge.build +         ( +            CONTEXT.get_origin_at +            ( +               ($SAFE_IMP_INDEXED_MERGE_KW.getLine()), +               ($SAFE_IMP_INDEXED_MERGE_KW.getCharPositionInLine()) +            ), +            ($fun.result), +            ($value_reference.result), +            ($def0.result), +            ($inv1.result), +            ($def1.result), +            new ArrayList() +         ); +   } + +   | SAFE_IMP_INDEXED_MERGE_KW +      fun=non_text_value WS+ +      def0=value WS+ +      value_reference WS+ +      def1=value WS+ +      inv1=non_text_value WS+ +      value_list WS* +      R_PAREN +   { +      $result = +         IndexedMerge.build +         ( +            CONTEXT.get_origin_at +            ( +               ($SAFE_IMP_INDEXED_MERGE_KW.getLine()), +               ($SAFE_IMP_INDEXED_MERGE_KW.getCharPositionInLine()) +            ), +            ($fun.result), +            ($value_reference.result), +            ($def0.result), +            ($inv1.result), +            ($def1.result), +            ($value_list.result) +         ); +   } +     | IMP_SUB_LIST_KW           vstart=non_text_value WS+           vend=non_text_value WS+ @@ -4314,7 +4369,9 @@ returns [Computation result]              ),              ($fun.result),              ($inv0.result), +            null,              ($inv1.result), +            null,              false,              new ArrayList()           ); @@ -4337,7 +4394,62 @@ returns [Computation result]              ),              ($fun.result),              ($inv0.result), +            null,              ($inv1.result), +            null, +            false, +            ($value_list.result) +         ); +   } + +   | SAFE_INDEXED_MERGE_TO_LIST_KW +         fun=non_text_value WS+ +         def0=value WS+ +         inv0=non_text_value WS+ +         def1=value WS+ +         inv1=non_text_value WS* +      R_PAREN +   { +      $result = +         IndexedMergeComputation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($SAFE_INDEXED_MERGE_TO_LIST_KW.getLine()), +               ($SAFE_INDEXED_MERGE_TO_LIST_KW.getCharPositionInLine()) +            ), +            ($fun.result), +            ($inv0.result), +            ($def0.result), +            ($inv1.result), +            ($def1.result), +            false, +            new ArrayList() +         ); +   } + +   | SAFE_INDEXED_MERGE_TO_LIST_KW +         fun=non_text_value WS+ +         def0=value WS+ +         inv0=non_text_value WS+ +         def1=value WS+ +         inv1=non_text_value WS+ +         value_list WS* +      R_PAREN +   { +      $result = +         IndexedMergeComputation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($SAFE_INDEXED_MERGE_TO_LIST_KW.getLine()), +               ($SAFE_INDEXED_MERGE_TO_LIST_KW.getCharPositionInLine()) +            ), +            ($fun.result), +            ($inv0.result), +            ($def0.result), +            ($inv1.result), +            ($def1.result),              false,              ($value_list.result)           ); @@ -4461,7 +4573,9 @@ returns [Computation result]              ),              ($fun.result),              ($inv0.result), +            null,              ($inv1.result), +            null,              true,              new ArrayList()           ); @@ -4484,7 +4598,62 @@ returns [Computation result]              ),              ($fun.result),              ($inv0.result), +            null,              ($inv1.result), +            null, +            true, +            ($value_list.result) +         ); +   } + +   | SAFE_INDEXED_MERGE_TO_SET_KW +         fun=non_text_value WS+ +         def0=value WS+ +         inv0=non_text_value WS+ +         def1=value WS+ +         inv1=non_text_value WS* +      R_PAREN +   { +      $result = +         IndexedMergeComputation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($SAFE_INDEXED_MERGE_TO_SET_KW.getLine()), +               ($SAFE_INDEXED_MERGE_TO_SET_KW.getCharPositionInLine()) +            ), +            ($fun.result), +            ($inv0.result), +            ($def0.result), +            ($inv1.result), +            ($def1.result), +            true, +            new ArrayList() +         ); +   } + +   | SAFE_INDEXED_MERGE_TO_SET_KW +         fun=non_text_value WS+ +         def0=value WS+ +         inv0=non_text_value WS+ +         def1=value WS+ +         inv1=non_text_value WS+ +         value_list WS* +      R_PAREN +   { +      $result = +         IndexedMergeComputation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($SAFE_INDEXED_MERGE_TO_SET_KW.getLine()), +               ($SAFE_INDEXED_MERGE_TO_SET_KW.getCharPositionInLine()) +            ), +            ($fun.result), +            ($inv0.result), +            ($def0.result), +            ($inv1.result), +            ($def1.result),              true,              ($value_list.result)           ); diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java index 9fb288d..2df0868 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java @@ -3024,6 +3024,96 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor        );     } +   private void visit_indexed_merge_with_defaults +   ( +      final tonkadur.fate.v1.lang.computation.IndexedMergeComputation n +   ) +   throws Throwable +   { +      final List<Computation> params; +      final ComputationCompiler lambda_cc, default_a_cc, default_b_cc; +      final ComputationCompiler in_collection_a_cc, in_collection_b_cc; +      final Register result; + +      result = reserve(TypeCompiler.compile(compiler, n.get_type())); + +      result_as_address = result.get_address(); +      result_as_computation = result.get_value(); + +      params = new ArrayList<Computation>(); + +      for +      ( +         final tonkadur.fate.v1.lang.meta.Computation p: +            n.get_extra_parameters() +      ) +      { +         final ComputationCompiler param_cc; + +         param_cc = new ComputationCompiler(compiler); + +         p.get_visited_by(param_cc); + +         /* Let's not re-compute the parameters on every iteration. */ +         param_cc.generate_address(); + +         assimilate(param_cc); + +         params.add(param_cc.get_computation()); +      } + +      lambda_cc = new ComputationCompiler(compiler); + +      n.get_lambda_function().get_visited_by(lambda_cc); + +      assimilate(lambda_cc); + +      default_a_cc = new ComputationCompiler(compiler); + +      n.get_default_a().get_visited_by(default_a_cc); + +      default_a_cc.generate_address(); + +      assimilate(default_a_cc); + +      default_b_cc = new ComputationCompiler(compiler); + +      n.get_default_b().get_visited_by(default_b_cc); + +      default_b_cc.generate_address(); + +      assimilate(default_b_cc); + +      in_collection_a_cc = new ComputationCompiler(compiler); + +      n.get_collection_in_a().get_visited_by(in_collection_a_cc); + +      assimilate(in_collection_a_cc); + +      in_collection_b_cc = new ComputationCompiler(compiler); + +      n.get_collection_in_b().get_visited_by(in_collection_b_cc); + +      assimilate(in_collection_b_cc); + +      init_instructions.add +      ( +         IndexedMergeLambda.generate +         ( +            compiler.registers(), +            compiler.assembler(), +            lambda_cc.get_computation(), +            default_a_cc.get_computation(), +            in_collection_a_cc.get_address(), +            default_b_cc.get_computation(), +            in_collection_b_cc.get_address(), +            result_as_address, +            n.to_set(), +            params +         ) +      ); +   } +     @Override     public void visit_indexed_merge     ( @@ -3031,6 +3121,13 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { +      if (n.get_default_a() != null) +      { +         visit_indexed_merge_with_defaults(n); + +         return; +      } +        final List<Computation> params;        final ComputationCompiler lambda_cc;        final ComputationCompiler in_collection_a_cc, in_collection_b_cc; diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java index 2f82d3c..36e7b66 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java @@ -1010,6 +1010,147 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        }     } +   private void visit_indexed_merge_with_defaults +   ( +      final tonkadur.fate.v1.lang.instruction.IndexedMerge n +   ) +   throws Throwable +   { +      final Register holder; +      final ComputationCompiler lambda_cc, default_a_cc, default_b_cc; +      final List<Computation> params; +      final List<ComputationCompiler> param_cc_list; +      final ComputationCompiler collection_cc, in_collection_b_cc; + +      params = new ArrayList<Computation>(); +      param_cc_list = new ArrayList<ComputationCompiler>(); + +      lambda_cc = new ComputationCompiler(compiler); +      default_a_cc = new ComputationCompiler(compiler); +      default_b_cc = new ComputationCompiler(compiler); + +      n.get_lambda_function().get_visited_by(lambda_cc); + +      if (lambda_cc.has_init()) +      { +         result.add(lambda_cc.get_init()); +      } + +      collection_cc = new ComputationCompiler(compiler); + +      n.get_collection().get_visited_by(collection_cc); + +      if (collection_cc.has_init()) +      { +         result.add(collection_cc.get_init()); +      } + +      n.get_default_a().get_visited_by(default_a_cc); + +      default_a_cc.generate_address(); + +      if (default_a_cc.has_init()) +      { +         result.add(default_a_cc.get_init()); +      } + +      n.get_default_b().get_visited_by(default_b_cc); + +      default_b_cc.generate_address(); + +      if (default_b_cc.has_init()) +      { +         result.add(default_b_cc.get_init()); +      } + +      holder = +         compiler.registers().reserve +         ( +            collection_cc.get_computation().get_type(), +            result +         ); + +      result.add +      ( +         new SetValue(holder.get_address(), collection_cc.get_computation()) +      ); + +      result.add +      ( +         Clear.generate +         ( +            compiler.registers(), +            compiler.assembler(), +            collection_cc.get_address() +         ) +      ); + +      in_collection_b_cc = new ComputationCompiler(compiler); + +      n.get_collection_in_b().get_visited_by(in_collection_b_cc); + +      if (in_collection_b_cc.has_init()) +      { +         result.add(in_collection_b_cc.get_init()); +      } + +      for +      ( +         final tonkadur.fate.v1.lang.meta.Computation p: +            n.get_extra_parameters() +      ) +      { +         final ComputationCompiler param_cc; + +         param_cc = new ComputationCompiler(compiler); + +         p.get_visited_by(param_cc); + +         /* Let's not re-compute the parameters on every iteration. */ +         param_cc.generate_address(); + +         if (param_cc.has_init()) +         { +            result.add(param_cc.get_init()); +         } + +         param_cc_list.add(param_cc); + +         params.add(param_cc.get_computation()); +      } + +      result.add +      ( +         IndexedMergeLambda.generate +         ( +            compiler.registers(), +            compiler.assembler(), +            lambda_cc.get_computation(), +            default_a_cc.get_computation(), +            holder.get_address(), +            default_b_cc.get_computation(), +            in_collection_b_cc.get_address(), +            collection_cc.get_address(), +            ( +               (tonkadur.fate.v1.lang.type.CollectionType) +               n.get_collection().get_type() +            ).is_set(), +            params +         ) +      ); + +      collection_cc.release_registers(result); +      in_collection_b_cc.release_registers(result); +      default_a_cc.release_registers(result); +      default_b_cc.release_registers(result); +      compiler.registers().release(holder, result); + +      for (final ComputationCompiler cc: param_cc_list) +      { +         cc.release_registers(result); +      } +   } +     @Override     public void visit_indexed_merge     ( @@ -1017,6 +1158,12 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor     )     throws Throwable     { +      if (n.get_default_a() != null) +      { +         visit_indexed_merge_with_defaults(n); +         return; +      } +        /* This is one dangerous operation to do in-place, so we don't. */        final Register holder;        final ComputationCompiler lambda_cc; diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java index 3a501e2..e1e4e4f 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java @@ -30,7 +30,6 @@ public class IndexedMergeLambda     /* Utility Class */     private IndexedMergeLambda () {} -   /* Uses Durstenfeld's shuffling algorithm */     public static Instruction generate     (        final RegisterManager registers, @@ -187,4 +186,191 @@ public class IndexedMergeLambda        return assembler.merge(result);     } + +   public static Instruction generate +   ( +      final RegisterManager registers, +      final InstructionManager assembler, +      final Computation lambda, +      final Computation default_a, +      final Address collection_in_a, +      final Computation default_b, +      final Address collection_in_b, +      final Address collection_out, +      final boolean to_set, +      final List<Computation> extra_params +   ) +   { +      final List<Instruction> result, while_body; +      final Register iterator_a, iterator_b; +      final Register collection_a_size, collection_b_size; +      final Register storage; + +      result = new ArrayList<Instruction>(); +      while_body = new ArrayList<Instruction>(); + +      iterator_a = registers.reserve(Type.INT, result); +      iterator_b = registers.reserve(Type.INT, result); + +      collection_a_size = registers.reserve(Type.INT, result); +      collection_b_size = registers.reserve(Type.INT, result); + +      storage = +         registers.reserve +         ( +            ((MapType) collection_out.get_target_type()).get_member_type(), +            result +         ); + +      result.add(new SetValue(iterator_a.get_address(), Constant.ZERO)); +      result.add(new SetValue(iterator_b.get_address(), Constant.ZERO)); + +      result.add +      ( +         new SetValue +         ( +            collection_a_size.get_address(), +            new Size(collection_in_a) +         ) +      ); + +      result.add +      ( +         new SetValue +         ( +            collection_b_size.get_address(), +            new Size(collection_in_b) +         ) +      ); + +      extra_params.add +      ( +         0, +         new IfElseComputation +         ( +            Operation.less_than +            ( +               iterator_b.get_value(), +               collection_b_size.get_value() +            ), +            new ValueOf +            ( +               new RelativeAddress +               ( +                  collection_in_b, +                  new Cast(iterator_b.get_value(), Type.STRING), +                  ( +                     (MapType) collection_in_b.get_target_type() +                  ).get_member_type() +               ) +            ), +            default_b +         ) +      ); + +      extra_params.add(0, iterator_b.get_value()); + +      extra_params.add +      ( +         0, +         new IfElseComputation +         ( +            Operation.less_than +            ( +               iterator_a.get_value(), +               collection_a_size.get_value() +            ), +            new ValueOf +            ( +               new RelativeAddress +               ( +                  collection_in_a, +                  new Cast(iterator_a.get_value(), Type.STRING), +                  ( +                     (MapType) collection_in_a.get_target_type() +                  ).get_member_type() +               ) +            ), +            default_a +         ) +      ); + +      extra_params.add(0, iterator_a.get_value()); + +      while_body.add +      ( +         LambdaEvaluation.generate +         ( +            registers, +            assembler, +            lambda, +            /* Can't put it in the target collection directly, since that may +             * be a set. +             */ +            storage.get_address(), +            extra_params +         ) +      ); + +      while_body.add +      ( +         AddElement.generate +         ( +            registers, +            assembler, +            storage.get_value(), +            collection_out, +            to_set +         ) +      ); + +      while_body.add +      ( +         new SetValue +         ( +            iterator_a.get_address(), +            Operation.plus(iterator_a.get_value(), Constant.ONE) +         ) +      ); + +      while_body.add +      ( +         new SetValue +         ( +            iterator_b.get_address(), +            Operation.plus(iterator_b.get_value(), Constant.ONE) +         ) +      ); + +      result.add +      ( +         While.generate +         ( +            registers, +            assembler, +            Operation.or +            ( +               Operation.less_than +               ( +                  iterator_a.get_value(), +                  collection_a_size.get_value() +               ), +               Operation.less_than +               ( +                  iterator_b.get_value(), +                  collection_b_size.get_value() +               ) +            ), +            assembler.merge(while_body) +         ) +      ); + +      registers.release(iterator_a, result); +      registers.release(iterator_b, result); +      registers.release(collection_a_size, result); +      registers.release(collection_b_size, result); +      registers.release(storage, result); + +      return assembler.merge(result); +   }  } | 


