| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src')
20 files changed, 1531 insertions, 863 deletions
| diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/FilterComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/FilterComputation.java index 9781e6f..1150b92 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/generic/FilterComputation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/FilterComputation.java @@ -44,7 +44,6 @@ public class FilterComputation extends GenericComputation        final Computation lambda_function;        final Computation collection;        final List<Computation> extra_params; -      final List<Type> signature;        if (call_parameters.size() < 2)        { @@ -56,61 +55,31 @@ public class FilterComputation extends GenericComputation        lambda_function = call_parameters.get(0);        collection = call_parameters.get(1); +      extra_params = call_parameters.subList(2, call_parameters.size()); -      if (call_parameters.size() == 2) -      { -         extra_params = new ArrayList<Computation>(); -      } -      else -      { -         extra_params = call_parameters.subList(2, call_parameters.size()); -      } - -      lambda_function.expect_non_string();        collection.expect_non_string(); -      RecurrentChecks.assert_is_a_lambda_function(lambda_function); - -      signature = ((LambdaType) lambda_function.get_type()).get_signature(); - -      if (signature.size() < 1) -      { -         // TODO: Error. -         System.err.println -         ( -            "Lambda signature too small at " -            + lambda_function.get_origin().toString() -         ); - -         return null; -      } - -      if (signature.size() > 2) -      { -         RecurrentChecks.propagate_expected_types_and_assert_computations_matches_signature -         ( -            origin, -            extra_params, -            signature.subList(1, signature.size()) -         ); -      } -        if (alias.startsWith("set:"))        { -         RecurrentChecks.assert_is_a_set_of(collection, signature.get(0)); +         RecurrentChecks.assert_is_a_set(collection);        }        else        { -         RecurrentChecks.assert_is_a_list_of(collection, signature.get(0)); +         RecurrentChecks.assert_is_a_list(collection);        } -      RecurrentChecks.assert_can_be_used_as +      RecurrentChecks.propagate_expected_types_and_assert_is_lambda        ( -         lambda_function.get_origin(), -         ((LambdaType) lambda_function.get_type()).get_return_type(), -         Type.BOOL +         lambda_function, +         Collections.singletonList +         ( +            ((CollectionType) collection.get_type()).get_content_type() +         ), +         extra_params        ); +      RecurrentChecks.assert_return_type_is(lambda_function, Type.BOOL); +        return           new FilterComputation           ( diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedFilterComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedFilterComputation.java index 8a2bf4f..e6d8469 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedFilterComputation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedFilterComputation.java @@ -46,34 +46,51 @@ public class IndexedFilterComputation extends GenericComputation     )     throws Throwable     { -      // TODO: implement -      final Computation lambda_function = null; -      final Computation collection = null; -      final List<Computation> extra_params = null; -      final List<Type> target_signature; +      final Computation lambda_function; +      final Computation collection; +      final List<Computation> extra_params; +      final List<Type> base_param_types; -      target_signature = new ArrayList<Type>(); +      base_param_types = new ArrayList<Type>(); +      base_param_types.add(Type.INT); -      RecurrentChecks.assert_is_a_collection(collection); +      if (call_parameters.size() < 2) +      { +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); -      target_signature.add(Type.INT); -      target_signature.add -      ( -         ((CollectionType) collection.get_type()).get_content_type() -      ); +         return null; +      } -      for (final Computation c: extra_params) +      lambda_function = call_parameters.get(0); +      collection = call_parameters.get(1); +      extra_params = call_parameters.subList(2, call_parameters.size()); + +      collection.expect_non_string(); + +      if (alias.startsWith("set:"))        { -         target_signature.add(c.get_type()); +         RecurrentChecks.assert_is_a_set(collection); +      } +      else +      { +         RecurrentChecks.assert_is_a_list(collection);        } -      RecurrentChecks.assert_lambda_matches_types +      base_param_types.add +      ( +         ((CollectionType) collection.get_type()).get_content_type() +      ); + +      RecurrentChecks.propagate_expected_types_and_assert_is_lambda        (           lambda_function, -         Type.BOOL, -         target_signature +         base_param_types, +         extra_params        ); +      RecurrentChecks.assert_return_type_is(lambda_function, Type.BOOL); +        return           new IndexedFilterComputation           ( diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedMapComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedMapComputation.java index a0adf57..b9057fe 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedMapComputation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedMapComputation.java @@ -46,28 +46,48 @@ public class IndexedMapComputation extends GenericComputation     )     throws Throwable     { -      // TODO: implement -      final Computation lambda_function = null; -      final Computation collection = null; -      final List<Computation> extra_params = null; -      final List<Type> in_types; +      final Computation lambda_function; +      final Computation collection; +      final List<Computation> extra_params; +      final List<Type> base_param_types; -      in_types = new ArrayList<Type>(); +      base_param_types = new ArrayList<Type>(); +      base_param_types.add(Type.INT); -      RecurrentChecks.assert_is_a_collection(collection); +      if (call_parameters.size() < 2) +      { +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); -      in_types.add(Type.INT); -      in_types.add -      ( -         ((CollectionType) collection.get_type()).get_content_type() -      ); +         return null; +      } -      for (final Computation c: extra_params) +      lambda_function = call_parameters.get(0); +      collection = call_parameters.get(1); +      extra_params = call_parameters.subList(2, call_parameters.size()); + +      collection.expect_non_string(); + +      if (alias.startsWith("set:"))        { -         in_types.add(c.get_type()); +         RecurrentChecks.assert_is_a_set(collection);        } +      else +      { +         RecurrentChecks.assert_is_a_list(collection); +      } + +      base_param_types.add +      ( +         ((CollectionType) collection.get_type()).get_content_type() +      ); -      RecurrentChecks.assert_lambda_matches_types(lambda_function, in_types); +      RecurrentChecks.propagate_expected_types_and_assert_is_lambda +      ( +         lambda_function, +         base_param_types, +         extra_params +      );        return           new IndexedMapComputation @@ -80,7 +100,7 @@ public class IndexedMapComputation extends GenericComputation              (                 origin,                 ((LambdaType) lambda_function.get_type()).get_return_type(), -               ((CollectionType) collection.get_type()).is_set(), +               false,                 "auto generated"              )           ); diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedMergeComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedMergeComputation.java index c90540d..f65e581 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedMergeComputation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedMergeComputation.java @@ -35,24 +35,6 @@ public class IndexedMergeComputation extends GenericComputation        aliases.add("set:indexedMerge");        aliases.add("set:imerge"); -      aliases.add("list:indexed_safe_merge"); -      aliases.add("list:indexedsafemerge"); -      aliases.add("list:indexedSafeMerge"); -      aliases.add("list:isafemerge"); -      aliases.add("list:safe_indexed_merge"); -      aliases.add("list:safeindexedmerge"); -      aliases.add("list:safeIndexedMerge"); -      aliases.add("list:safeimerge"); - -      aliases.add("set:indexed_safe_merge"); -      aliases.add("set:indexedsafemerge"); -      aliases.add("set:indexedSafeMerge"); -      aliases.add("set:isafemerge"); -      aliases.add("set:safe_indexed_merge"); -      aliases.add("set:safeindexedmerge"); -      aliases.add("set:safeIndexedMerge"); -      aliases.add("set:safeimerge"); -        return aliases;     } @@ -64,81 +46,68 @@ public class IndexedMergeComputation extends GenericComputation     )     throws Throwable     { -      // TODO: implement -      final Computation lambda_function = null; -      final Computation collection_in_a = null; -      final Computation default_a = null; -      final Computation collection_in_b = null; -      final Computation default_b = null; -      final boolean to_set = false; -      final List<Computation> extra_params = null; -      final List<Type> types_in; - -      types_in = new ArrayList<Type>(); - -      if (default_a == null) -      { -         RecurrentChecks.assert_is_a_collection(collection_in_a); -      } -      else -      { -         RecurrentChecks.propagate_expected_types_and_assert_is_a_collection_of -         ( -            collection_in_a, -            default_a -         ); -      } +      final Computation lambda_function; +      final Computation collection_a; +      final Computation collection_b; +      final List<Computation> extra_params; +      final List<Type> base_param_types; +      final boolean to_set; -      if (default_b == null) -      { -         RecurrentChecks.assert_is_a_collection(collection_in_b); -      } -      else +      base_param_types = new ArrayList<Type>(); + +      if (call_parameters.size() < 3)        { -         RecurrentChecks.propagate_expected_types_and_assert_is_a_collection_of -         ( -            collection_in_b, -            default_b -         ); +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); + +         return null;        } -      types_in.add(Type.INT); +      lambda_function = call_parameters.get(0); +      collection_a = call_parameters.get(1); +      collection_b = call_parameters.get(2); +      extra_params = call_parameters.subList(3, call_parameters.size()); -      types_in.add +      collection_a.expect_non_string(); +      collection_b.expect_non_string(); + +      base_param_types.add(Type.INT); + +      base_param_types.add        ( -         ((CollectionType) collection_in_a.get_type()).get_content_type() +         ((CollectionType) collection_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); -      } +      base_param_types.add +      ( +         ((CollectionType) collection_b.get_type()).get_content_type() +      ); -      types_in.add +      RecurrentChecks.propagate_expected_types_and_assert_is_lambda        ( -         ((CollectionType) collection_in_b.get_type()).get_content_type() +         lambda_function, +         base_param_types, +         extra_params        ); -      for (final Computation c: extra_params) +      to_set = alias.startsWith("set:"); + +      if (to_set)        { -         types_in.add(c.get_type()); +         RecurrentChecks.assert_can_be_used_in_set +         ( +            lambda_function.get_origin().with_hint("returned type"), +            ((LambdaType) lambda_function.get_type()).get_return_type() +         );        } -      RecurrentChecks.assert_lambda_matches_types(lambda_function, types_in); -        return           new IndexedMergeComputation           (              origin,              lambda_function, -            collection_in_a, -            default_a, -            collection_in_b, -            default_b, +            collection_a, +            collection_b,              to_set,              extra_params,              CollectionType.build @@ -157,9 +126,7 @@ public class IndexedMergeComputation extends GenericComputation     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;     /***************************************************************************/ @@ -171,9 +138,7 @@ public class IndexedMergeComputation extends GenericComputation        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 @@ -183,9 +148,7 @@ public class IndexedMergeComputation extends GenericComputation        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;     } @@ -204,21 +167,11 @@ public class IndexedMergeComputation extends GenericComputation        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; @@ -249,27 +202,7 @@ public class IndexedMergeComputation extends GenericComputation        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/computation/generic/IndexedSafeMergeComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedSafeMergeComputation.java new file mode 100644 index 0000000..dc860f6 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/IndexedSafeMergeComputation.java @@ -0,0 +1,288 @@ +package tonkadur.fate.v1.lang.computation.generic; + +import java.util.Collection; +import java.util.ArrayList; +import java.util.List; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.type.Type; +import tonkadur.fate.v1.lang.type.LambdaType; +import tonkadur.fate.v1.lang.type.CollectionType; + +import tonkadur.fate.v1.lang.meta.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.RecurrentChecks; + +import tonkadur.fate.v1.lang.computation.GenericComputation; + +public class IndexedSafeMergeComputation extends GenericComputation +{ +   public static Collection<String> get_aliases () +   { +      final Collection<String> aliases; + +      aliases = new ArrayList<String>(); + +      aliases.add("list:indexed_merge"); +      aliases.add("list:indexedmerge"); +      aliases.add("list:indexedMerge"); +      aliases.add("list:imerge"); +      aliases.add("set:indexed_merge"); +      aliases.add("set:indexedmerge"); +      aliases.add("set:indexedMerge"); +      aliases.add("set:imerge"); + +      aliases.add("list:indexed_safe_merge"); +      aliases.add("list:indexedsafemerge"); +      aliases.add("list:indexedSafeMerge"); +      aliases.add("list:isafemerge"); +      aliases.add("list:safe_indexed_merge"); +      aliases.add("list:safeindexedmerge"); +      aliases.add("list:safeIndexedSafeMerge"); +      aliases.add("list:safeimerge"); + +      aliases.add("set:indexed_safe_merge"); +      aliases.add("set:indexedsafemerge"); +      aliases.add("set:indexedSafeMerge"); +      aliases.add("set:isafemerge"); +      aliases.add("set:safe_indexed_merge"); +      aliases.add("set:safeindexedmerge"); +      aliases.add("set:safeIndexedSafeMerge"); +      aliases.add("set:safeimerge"); + +      return aliases; +   } + +   public static Computation build +   ( +      final Origin origin, +      final String alias, +      final List<Computation> call_parameters +   ) +   throws Throwable +   { +      final Computation lambda_function; +      final Computation collection_a; +      final Computation default_a; +      final Computation collection_b; +      final Computation default_b; +      final List<Computation> extra_params; +      final List<Type> base_param_types; +      final boolean to_set; + +      base_param_types = new ArrayList<Type>(); + +      if (call_parameters.size() < 5) +      { +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); + +         return null; +      } + +      lambda_function = call_parameters.get(0); +      collection_a = call_parameters.get(1); +      default_a = call_parameters.get(2); +      collection_b = call_parameters.get(3); +      default_b = call_parameters.get(4); +      extra_params = call_parameters.subList(5, call_parameters.size()); + +      RecurrentChecks.propagate_expected_types_and_assert_is_a_collection_of +      ( +         collection_a, +         default_a +      ); + +      RecurrentChecks.propagate_expected_types_and_assert_is_a_collection_of +      ( +         collection_a, +         default_b +      ); + +      base_param_types.add(Type.INT); + +      base_param_types.add +      ( +         ((CollectionType) collection_a.get_type()).get_content_type() +      ); + +      base_param_types.add(Type.INT); + +      base_param_types.add +      ( +         ((CollectionType) collection_b.get_type()).get_content_type() +      ); + +      RecurrentChecks.propagate_expected_types_and_assert_is_lambda +      ( +         lambda_function, +         base_param_types, +         extra_params +      ); + +      to_set = alias.startsWith("set:"); + +      if (to_set) +      { +         RecurrentChecks.assert_can_be_used_in_set +         ( +            lambda_function.get_origin().with_hint("returned value"), +            ((LambdaType) lambda_function.get_type()).get_return_type() +         ); +      } + +      return +         new IndexedSafeMergeComputation +         ( +            origin, +            lambda_function, +            collection_a, +            default_a, +            collection_b, +            default_b, +            to_set, +            extra_params, +            CollectionType.build +            ( +               origin, +               ((LambdaType) lambda_function.get_type()).get_return_type(), +               to_set, +               "auto generated" +            ) +         ); +   } + +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   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; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected IndexedSafeMergeComputation +   ( +      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 +   ) +   { +      super(origin, output_type); + +      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; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Accessors ************************************************************/ +   public Computation get_lambda_function () +   { +      return lambda_function; +   } + +   public Computation get_collection_in_a () +   { +      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; +   } + +   public boolean to_set () +   { +      return to_set; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      if (to_set) +      { +         sb.append("(IndexedSafeMergeToSet "); +      } +      else +      { +         sb.append("(IndexedSafeMergeToList "); +      } + +      sb.append(lambda_function.toString()); +      sb.append(" "); +      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) +      { +         sb.append(" "); +         sb.append(c.toString()); +      } + +      sb.append(")"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/MapComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/MapComputation.java index 4fcf324..a62e14c 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/generic/MapComputation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/MapComputation.java @@ -41,30 +41,41 @@ public class MapComputation extends GenericComputation     )     throws Throwable     { -      // TODO: implement -      final Computation lambda_function = null; -      final Computation collection = null; -      final List<Computation> extra_params = null; -      final List<Type> target_signature; +      final Computation lambda_function; +      final Computation collection; +      final List<Computation> extra_params; -      target_signature = new ArrayList<Type>(); +      if (call_parameters.size() < 2) +      { +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); -      RecurrentChecks.assert_is_a_collection(collection); +         return null; +      } -      target_signature.add -      ( -         ((CollectionType) collection.get_type()).get_content_type() -      ); +      lambda_function = call_parameters.get(0); +      collection = call_parameters.get(1); +      extra_params = call_parameters.subList(2, call_parameters.size()); -      for (final Computation c: extra_params) +      collection.expect_non_string(); + +      if (alias.startsWith("set:")) +      { +         RecurrentChecks.assert_is_a_set(collection); +      } +      else        { -         target_signature.add(c.get_type()); +         RecurrentChecks.assert_is_a_list(collection);        } -      RecurrentChecks.assert_lambda_matches_types +      RecurrentChecks.propagate_expected_types_and_assert_is_lambda        (           lambda_function, -         target_signature +         Collections.singletonList +         ( +            ((CollectionType) collection.get_type()).get_content_type() +         ), +         extra_params        );        return @@ -78,7 +89,7 @@ public class MapComputation extends GenericComputation              (                 origin,                 ((LambdaType) lambda_function.get_type()).get_return_type(), -               ((CollectionType) collection.get_type()).is_set(), +               false,                 "auto generated"              )           ); diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/MergeComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/MergeComputation.java index 3ebe675..287957d 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/generic/MergeComputation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/MergeComputation.java @@ -27,13 +27,7 @@ public class MergeComputation extends GenericComputation        aliases = new ArrayList<String>();        aliases.add("list:merge"); -      aliases.add("list:safe_merge"); -      aliases.add("list:safemerge"); -      aliases.add("list:safeMerge");        aliases.add("set:merge"); -      aliases.add("set:safe_merge"); -      aliases.add("set:safemerge"); -      aliases.add("set:safeMerge");        return aliases;     } @@ -46,70 +40,66 @@ public class MergeComputation extends GenericComputation     )     throws Throwable     { -      // TODO: implement -      final Computation lambda_function = null; -      final Computation collection_in_a = null; -      final Computation default_a = null; -      final Computation collection_in_b = null; -      final Computation default_b = null; -      final boolean to_set = false; -      final List<Computation> extra_params = null; -      final List<Type> types_in; - -      types_in = new ArrayList<Type>(); - -      if (default_a == null) -      { -         RecurrentChecks.assert_is_a_collection(collection_in_a); -      } -      else -      { -         RecurrentChecks.propagate_expected_types_and_assert_is_a_collection_of -         ( -            collection_in_a, -            default_a -         ); -      } +      final Computation lambda_function; +      final Computation collection_a; +      final Computation collection_b; +      final List<Computation> extra_params; +      final List<Type> base_param_types; +      final boolean to_set; -      if (default_b == null) -      { -         RecurrentChecks.assert_is_a_collection(collection_in_b); -      } -      else +      base_param_types = new ArrayList<Type>(); + +      if (call_parameters.size() < 3)        { -         RecurrentChecks.propagate_expected_types_and_assert_is_a_collection_of -         ( -            collection_in_b, -            default_b -         ); +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); + +         return null;        } -      types_in.add +      lambda_function = call_parameters.get(0); +      collection_a = call_parameters.get(1); +      collection_b = call_parameters.get(2); +      extra_params = call_parameters.subList(3, call_parameters.size()); + +      collection_a.expect_non_string(); +      collection_b.expect_non_string(); + +      base_param_types.add        ( -         ((CollectionType) collection_in_a.get_type()).get_content_type() +         ((CollectionType) collection_a.get_type()).get_content_type()        ); -      types_in.add +      base_param_types.add        ( -         ((CollectionType) collection_in_b.get_type()).get_content_type() +         ((CollectionType) collection_b.get_type()).get_content_type()        ); -      for (final Computation c: extra_params) +      RecurrentChecks.propagate_expected_types_and_assert_is_lambda +      ( +         lambda_function, +         base_param_types, +         extra_params +      ); + +      to_set = alias.startsWith("set:"); + +      if (to_set)        { -         types_in.add(c.get_type()); +         RecurrentChecks.assert_can_be_used_in_set +         ( +            lambda_function.get_origin().with_hint("returned value"), +            ((LambdaType) lambda_function.get_type()).get_return_type() +         );        } -      RecurrentChecks.assert_lambda_matches_types(lambda_function, types_in); -        return           new MergeComputation           (              origin,              lambda_function, -            collection_in_a, -            default_a, -            collection_in_b, -            default_b, +            collection_a, +            collection_b,              to_set,              extra_params,              CollectionType.build @@ -127,9 +117,7 @@ public class MergeComputation extends GenericComputation     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;     /***************************************************************************/ @@ -141,9 +129,7 @@ public class MergeComputation extends GenericComputation        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 @@ -153,9 +139,7 @@ public class MergeComputation extends GenericComputation        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;     } @@ -174,21 +158,11 @@ public class MergeComputation extends GenericComputation        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; @@ -219,27 +193,7 @@ public class MergeComputation extends GenericComputation        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/computation/generic/PartitionComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/PartitionComputation.java index 9444bc1..34c0ca3 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/generic/PartitionComputation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/PartitionComputation.java @@ -41,34 +41,46 @@ public class PartitionComputation extends GenericComputation     )     throws Throwable     { -      // TODO: implement -      final Computation lambda_function = null; -      final Computation collection = null; -      final List<Computation> extra_params = null; +      final Computation lambda_function; +      final Computation collection; +      final List<Computation> extra_params;        final Type type; -      final List<Type> target_signature; -      target_signature = new ArrayList<Type>(); +      if (call_parameters.size() < 2) +      { +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); -      RecurrentChecks.assert_is_a_collection(collection); +         return null; +      } -      target_signature.add -      ( -         ((CollectionType) collection.get_type()).get_content_type() -      ); +      lambda_function = call_parameters.get(0); +      collection = call_parameters.get(1); +      extra_params = call_parameters.subList(2, call_parameters.size()); -      for (final Computation c: extra_params) +      collection.expect_non_string(); + +      if (alias.startsWith("set:")) +      { +         RecurrentChecks.assert_is_a_set(collection); +      } +      else        { -         target_signature.add(c.get_type()); +         RecurrentChecks.assert_is_a_list(collection);        } -      RecurrentChecks.assert_lambda_matches_types +      RecurrentChecks.propagate_expected_types_and_assert_is_lambda        (           lambda_function, -         Type.BOOL, -         target_signature +         Collections.singletonList +         ( +            ((CollectionType) collection.get_type()).get_content_type() +         ), +         extra_params        ); +      RecurrentChecks.assert_return_type_is(lambda_function, Type.BOOL); +        type =           new ConsType           ( diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/SafeMergeComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/SafeMergeComputation.java new file mode 100644 index 0000000..61422ac --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/SafeMergeComputation.java @@ -0,0 +1,249 @@ +package tonkadur.fate.v1.lang.computation.generic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.type.Type; +import tonkadur.fate.v1.lang.type.LambdaType; +import tonkadur.fate.v1.lang.type.CollectionType; + +import tonkadur.fate.v1.lang.meta.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.RecurrentChecks; + +import tonkadur.fate.v1.lang.computation.GenericComputation; + +public class SafeMergeComputation extends GenericComputation +{ +   public static Collection<String> get_aliases () +   { +      final Collection<String> aliases; + +      aliases = new ArrayList<String>(); + +      aliases.add("list:safe_merge"); +      aliases.add("list:safemerge"); +      aliases.add("list:safeMerge"); +      aliases.add("set:safe_merge"); +      aliases.add("set:safemerge"); +      aliases.add("set:safeMerge"); + +      return aliases; +   } + +   public static Computation build +   ( +      final Origin origin, +      final String alias, +      final List<Computation> call_parameters +   ) +   throws Throwable +   { +      final Computation lambda_function; +      final Computation collection_a; +      final Computation default_a; +      final Computation collection_b; +      final Computation default_b; +      final List<Computation> extra_params; +      final List<Type> base_param_types; +      final boolean to_set; + +      base_param_types = new ArrayList<Type>(); + +      if (call_parameters.size() < 5) +      { +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); + +         return null; +      } + +      lambda_function = call_parameters.get(0); +      collection_a = call_parameters.get(1); +      default_a = call_parameters.get(2); +      collection_b = call_parameters.get(3); +      default_b = call_parameters.get(4); +      extra_params = call_parameters.subList(5, call_parameters.size()); + +      RecurrentChecks.propagate_expected_types_and_assert_is_a_collection_of +      ( +         collection_a, +         default_a +      ); + +      RecurrentChecks.propagate_expected_types_and_assert_is_a_collection_of +      ( +         collection_a, +         default_b +      ); + +      base_param_types.add +      ( +         ((CollectionType) collection_a.get_type()).get_content_type() +      ); + +      base_param_types.add +      ( +         ((CollectionType) collection_b.get_type()).get_content_type() +      ); + +      RecurrentChecks.propagate_expected_types_and_assert_is_lambda +      ( +         lambda_function, +         base_param_types, +         extra_params +      ); + +      to_set = alias.startsWith("set:"); + +      if (to_set) +      { +         RecurrentChecks.assert_can_be_used_in_set +         ( +            lambda_function.get_origin().with_hint("returned value"), +            ((LambdaType) lambda_function.get_type()).get_return_type() +         ); +      } + +      return +         new SafeMergeComputation +         ( +            origin, +            lambda_function, +            collection_a, +            default_a, +            collection_b, +            default_b, +            to_set, +            extra_params, +            CollectionType.build +            ( +               origin, +               ((LambdaType) lambda_function.get_type()).get_return_type(), +               to_set, +               "auto generated" +            ) +         ); +   } +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   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; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected SafeMergeComputation +   ( +      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 +   ) +   { +      super(origin, output_type); + +      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; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Accessors ************************************************************/ +   public Computation get_lambda_function () +   { +      return lambda_function; +   } + +   public Computation get_collection_in_a () +   { +      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; +   } + +   public boolean to_set () +   { +      return to_set; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      if (to_set) +      { +         sb.append("(SafeMergeToSet "); +      } +      else +      { +         sb.append("(SafeMergeToList "); +      } + +      sb.append(lambda_function.toString()); +      sb.append(" "); +      sb.append(collection_in_a.toString()); +      sb.append(" "); + +      sb.append(default_a.toString()); + +      sb.append(" "); +      sb.append(collection_in_b.toString()); +      sb.append(" "); + +      sb.append(default_b.toString()); + +      for (final Computation c: extra_params) +      { +         sb.append(" "); +         sb.append(c.toString()); +      } + +      sb.append(")"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/SortComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/SortComputation.java index 64999a7..3d14dd7 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/generic/SortComputation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/SortComputation.java @@ -38,31 +38,46 @@ public class SortComputation extends GenericComputation     )     throws Throwable     { -      // TODO: implement -      final Computation lambda_function = null; -      final Computation collection = null; -      final List<Computation> extra_params = null; -      final List<Type> types_in; +      final Computation lambda_function; +      final Computation collection; +      final List<Computation> extra_params; +      final List<Type> base_param_types; -      types_in = new ArrayList<Type>(); +      base_param_types = new ArrayList<Type>(); +      base_param_types.add(Type.INT); + +      if (call_parameters.size() < 2) +      { +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); + +         return null; +      } + +      lambda_function = call_parameters.get(0); +      collection = call_parameters.get(1); +      extra_params = call_parameters.subList(2, call_parameters.size()); + +      collection.expect_non_string();        RecurrentChecks.assert_is_a_list(collection); -      types_in.add(((CollectionType) collection.get_type()).get_content_type()); -      types_in.add(types_in.get(0)); +      base_param_types.add +      ( +         ((CollectionType) collection.get_type()).get_content_type() +      ); -      for (final Computation c: extra_params) -      { -         types_in.add(c.get_type()); -      } +      base_param_types.add(base_param_types.get(0)); -      RecurrentChecks.assert_lambda_matches_types +      RecurrentChecks.propagate_expected_types_and_assert_is_lambda        (           lambda_function, -         Type.INT, -         types_in +         base_param_types, +         extra_params        ); +      RecurrentChecks.assert_return_type_is(lambda_function, Type.INT); +        return           new SortComputation(origin, lambda_function, collection, extra_params);     } diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/RecurrentChecks.java b/src/core/src/tonkadur/fate/v1/lang/meta/RecurrentChecks.java index ae905ef..3e3c721 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/RecurrentChecks.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/RecurrentChecks.java @@ -107,6 +107,27 @@ public class RecurrentChecks        }     } +   public static void assert_can_be_used_in_set +   ( +      final Origin o, +      final Type t +   ) +   throws ParsingError +   { +      if (!Type.COMPARABLE_TYPES.contains(t.get_act_as_type())) +      { +         ErrorManager.handle +         ( +            new InvalidTypeException +            ( +               o, +               t, +               Type.COMPARABLE_TYPES +            ) +         ); +      } +   } +     public static void assert_is_a_set (final Computation a)     throws ParsingError     { @@ -355,6 +376,49 @@ public class RecurrentChecks        }     } +   public static void propagate_expected_types_and_assert_is_lambda +   ( +      final Computation lambda, +      final List<Type> filled_types, +      final List<Computation> extra_params +   ) +   throws ParsingError +   { +      final List<Type> lambda_signature; +      final int extra_params_size; + +      lambda.expect_non_string(); + +      assert_is_a_lambda_function(lambda); + +      lambda_signature = ((LambdaType) lambda.get_type()).get_signature(); + +      extra_params_size = extra_params.size(); + +      if ((filled_types.size() + extra_params_size) != lambda_signature.size()) +      { +         ErrorManager.handle +         ( +            new InvalidArityException +            ( +               lambda.get_origin(), +               (filled_types.size() + extra_params_size), +               lambda_signature.size(), +               lambda_signature.size() +            ) +         ); +      } + +      for (int i = filled_types.size(), j = 0; i < extra_params_size; ++i, ++j) +      { +         handle_expected_type_propagation +         ( +            extra_params.get(j), +            lambda_signature.get(i) +         ); +      } +   } +     public static void assert_types_matches_signature     (        final Origin o, diff --git a/src/core/src/tonkadur/parser/Origin.java b/src/core/src/tonkadur/parser/Origin.java index 99f1cb4..7adb310 100644 --- a/src/core/src/tonkadur/parser/Origin.java +++ b/src/core/src/tonkadur/parser/Origin.java @@ -6,7 +6,13 @@ public class Origin     static     { -      BASE_LANGUAGE = new Origin(Context.BASE_LANGUAGE, Location.BASE_LANGUAGE); +      BASE_LANGUAGE = +         new Origin +         ( +            Context.BASE_LANGUAGE, +            Location.BASE_LANGUAGE, +            "base language/core feature/mandatory inclusion" +         );     }     /***************************************************************************/ @@ -14,6 +20,7 @@ public class Origin     /***************************************************************************/     protected final Context context;     protected final Location location; +   protected final String hint;     /***************************************************************************/     /**** PUBLIC ***************************************************************/ @@ -26,6 +33,19 @@ public class Origin     {        this.context = context;        this.location = location; +      this.hint = ""; +   } + +   public Origin +   ( +      final Context context, +      final Location location, +      final String hint +   ) +   { +      this.context = context; +      this.location = location; +      this.hint = hint;     }     public Context get_context () @@ -38,6 +58,16 @@ public class Origin        return location;     } +   public String get_hint () +   { +      return hint; +   } + +   public Origin with_hint (final String hint) +   { +      return new Origin(context.clone(), location.clone(), hint); +   } +     @Override     public String toString()     { @@ -46,12 +76,19 @@ public class Origin        sb.append(context.toString());        sb.append(location.toString()); +      if (hint.length() > 0) +      { +         sb.append("(hint: "); +         sb.append(get_hint()); +         sb.append(")"); +      } +        return sb.toString();     }     @Override     public Origin clone ()     { -      return new Origin(context.clone(), location.clone()); +      return new Origin(context.clone(), location.clone(), hint);     }  } diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IndexedMergeComputationCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IndexedMergeComputationCompiler.java index a327d68..3106a29 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IndexedMergeComputationCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IndexedMergeComputationCompiler.java @@ -32,104 +32,28 @@ extends GenericComputationCompiler        super(compiler);     } -   protected void compile_with_defaults (final IndexedMergeComputation source) +   protected void compile_without_defaults +   ( +      final IndexedMergeComputation source +   )     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, source.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: -            source.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); - -      source.get_lambda_function().get_visited_by(lambda_cc); - -      assimilate(lambda_cc); - -      default_a_cc = new ComputationCompiler(compiler); - -      source.get_default_a().get_visited_by(default_a_cc); - -      default_a_cc.generate_address(); - -      assimilate(default_a_cc); - -      default_b_cc = new ComputationCompiler(compiler); - -      source.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); - -      source.get_collection_in_a().get_visited_by(in_collection_a_cc); - -      assimilate(in_collection_a_cc); - -      in_collection_b_cc = new ComputationCompiler(compiler); - -      source.get_collection_in_b().get_visited_by(in_collection_b_cc); - -      assimilate(in_collection_b_cc); - -      init_instructions.add -      ( -         tonkadur.wyrd.v1.compiler.util.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, -            source.to_set(), -            params -         ) -      );     } -   protected void compile_without_defaults +   public void compile     ( -      final IndexedMergeComputation source +      final tonkadur.fate.v1.lang.computation.GenericComputation computation     )     throws Throwable     { +      final IndexedMergeComputation source;        final List<Computation> params;        final ComputationCompiler lambda_cc;        final ComputationCompiler in_collection_a_cc, in_collection_b_cc;        final Register result; +      source = (IndexedMergeComputation) computation; +        result = reserve(TypeCompiler.compile(compiler, source.get_type()));        result_as_address = result.get_address(); @@ -190,24 +114,4 @@ extends GenericComputationCompiler           )        );     } - -   public void compile -   ( -      final tonkadur.fate.v1.lang.computation.GenericComputation computation -   ) -   throws Throwable -   { -      final IndexedMergeComputation source; - -      source = (IndexedMergeComputation) computation; - -      if (source.get_default_a() == null) -      { -         compile_without_defaults(source); -      } -      else -      { -         compile_with_defaults(source); -      } -   }  } diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IndexedSafeMergeComputationCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IndexedSafeMergeComputationCompiler.java new file mode 100644 index 0000000..97aabdd --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IndexedSafeMergeComputationCompiler.java @@ -0,0 +1,128 @@ +package tonkadur.wyrd.v1.compiler.fate.v1.computation.generic; + +import java.util.List; +import java.util.ArrayList; + +import tonkadur.fate.v1.lang.computation.generic.IndexedSafeMergeComputation; + +import tonkadur.wyrd.v1.lang.Register; + +import tonkadur.wyrd.v1.lang.instruction.SetValue; + +import tonkadur.wyrd.v1.lang.meta.Computation; + +import tonkadur.wyrd.v1.lang.type.Type; + +import tonkadur.wyrd.v1.compiler.fate.v1.Compiler; +import tonkadur.wyrd.v1.compiler.fate.v1.TypeCompiler; +import tonkadur.wyrd.v1.compiler.fate.v1.ComputationCompiler; + +import tonkadur.wyrd.v1.compiler.fate.v1.computation.GenericComputationCompiler; + +public class IndexedSafeMergeComputationCompiler +extends GenericComputationCompiler +{ +   public static Class get_target_class () +   { +      return IndexedSafeMergeComputation.class; +   } + +   public IndexedSafeMergeComputationCompiler (final Compiler compiler) +   { +      super(compiler); +   } + +   public void compile +   ( +      final tonkadur.fate.v1.lang.computation.GenericComputation computation +   ) +   throws Throwable +   { +      final IndexedSafeMergeComputation source; +      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; + +      source = (IndexedSafeMergeComputation) computation; + +      result = reserve(TypeCompiler.compile(compiler, source.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: +            source.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); + +      source.get_lambda_function().get_visited_by(lambda_cc); + +      assimilate(lambda_cc); + +      default_a_cc = new ComputationCompiler(compiler); + +      source.get_default_a().get_visited_by(default_a_cc); + +      default_a_cc.generate_address(); + +      assimilate(default_a_cc); + +      default_b_cc = new ComputationCompiler(compiler); + +      source.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); + +      source.get_collection_in_a().get_visited_by(in_collection_a_cc); + +      assimilate(in_collection_a_cc); + +      in_collection_b_cc = new ComputationCompiler(compiler); + +      source.get_collection_in_b().get_visited_by(in_collection_b_cc); + +      assimilate(in_collection_b_cc); + +      init_instructions.add +      ( +         tonkadur.wyrd.v1.compiler.util.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, +            source.to_set(), +            params +         ) +      ); + +   } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/MergeComputationCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/MergeComputationCompiler.java index d0cde2f..116ce1e 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/MergeComputationCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/MergeComputationCompiler.java @@ -30,101 +30,20 @@ extends GenericComputationCompiler        super(compiler);     } -   protected void compile_with_defaults (final MergeComputation source) -   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, source.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: -            source.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); - -      source.get_lambda_function().get_visited_by(lambda_cc); - -      assimilate(lambda_cc); - -      default_a_cc = new ComputationCompiler(compiler); - -      source.get_default_a().get_visited_by(default_a_cc); - -      default_a_cc.generate_address(); - -      assimilate(default_a_cc); - -      default_b_cc = new ComputationCompiler(compiler); - -      source.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); - -      source.get_collection_in_a().get_visited_by(in_collection_a_cc); - -      assimilate(in_collection_a_cc); - -      in_collection_b_cc = new ComputationCompiler(compiler); - -      source.get_collection_in_b().get_visited_by(in_collection_b_cc); - -      assimilate(in_collection_b_cc); - -      init_instructions.add -      ( -         tonkadur.wyrd.v1.compiler.util.MergeLambda.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, -            source.to_set(), -            params -         ) -      ); -   } - -   protected void compile_without_defaults (final MergeComputation source) +   public void compile +   ( +      final tonkadur.fate.v1.lang.computation.GenericComputation computation +   )     throws Throwable     { +      final MergeComputation source;        final List<Computation> params;        final ComputationCompiler lambda_cc;        final ComputationCompiler in_collection_a_cc, in_collection_b_cc;        final Register result; +      source = (MergeComputation) computation; +        result = reserve(TypeCompiler.compile(compiler, source.get_type()));        result_as_address = result.get_address(); @@ -185,24 +104,4 @@ extends GenericComputationCompiler           )        );     } - -   public void compile -   ( -      final tonkadur.fate.v1.lang.computation.GenericComputation computation -   ) -   throws Throwable -   { -      final MergeComputation source; - -      source = (MergeComputation) computation; - -      if (source.get_default_a() == null) -      { -         compile_without_defaults(source); -      } -      else -      { -         compile_with_defaults(source); -      } -   }  } diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/SafeMergeComputation.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/SafeMergeComputation.java new file mode 100644 index 0000000..17673da --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/SafeMergeComputation.java @@ -0,0 +1,126 @@ +package tonkadur.wyrd.v1.compiler.fate.v1.computation.generic; + +import java.util.List; +import java.util.ArrayList; + +import tonkadur.fate.v1.lang.computation.generic.SafeMergeComputation; + +import tonkadur.wyrd.v1.lang.Register; + +import tonkadur.wyrd.v1.lang.meta.Computation; + +import tonkadur.wyrd.v1.lang.type.Type; + +import tonkadur.wyrd.v1.compiler.fate.v1.Compiler; +import tonkadur.wyrd.v1.compiler.fate.v1.TypeCompiler; +import tonkadur.wyrd.v1.compiler.fate.v1.ComputationCompiler; + +import tonkadur.wyrd.v1.compiler.fate.v1.computation.GenericComputationCompiler; + +public class SafeMergeComputationCompiler +extends GenericComputationCompiler +{ +   public static Class get_target_class () +   { +      return SafeMergeComputation.class; +   } + +   public SafeMergeComputationCompiler (final Compiler compiler) +   { +      super(compiler); +   } + +   public void compile +   ( +      final tonkadur.fate.v1.lang.computation.GenericComputation computation +   ) +   throws Throwable +   { +      final SafeMergeComputation source; +      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; + +      source = (SafeMergeComputation) computation; + +      result = reserve(TypeCompiler.compile(compiler, source.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: +            source.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); + +      source.get_lambda_function().get_visited_by(lambda_cc); + +      assimilate(lambda_cc); + +      default_a_cc = new ComputationCompiler(compiler); + +      source.get_default_a().get_visited_by(default_a_cc); + +      default_a_cc.generate_address(); + +      assimilate(default_a_cc); + +      default_b_cc = new ComputationCompiler(compiler); + +      source.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); + +      source.get_collection_in_a().get_visited_by(in_collection_a_cc); + +      assimilate(in_collection_a_cc); + +      in_collection_b_cc = new ComputationCompiler(compiler); + +      source.get_collection_in_b().get_visited_by(in_collection_b_cc); + +      assimilate(in_collection_b_cc); + +      init_instructions.add +      ( +         tonkadur.wyrd.v1.compiler.util.MergeLambda.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, +            source.to_set(), +            params +         ) +      ); + +   } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/IndexedMergeCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/IndexedMergeCompiler.java index 0f94485..8d4d4a5 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/IndexedMergeCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/IndexedMergeCompiler.java @@ -28,161 +28,21 @@ public class IndexedMergeCompiler extends GenericInstructionCompiler        super(compiler);     } -   private void compile_indexed_merge_with_defaults (final IndexedMerge source) -   throws Throwable -   { -      final Register holder; -      final ComputationCompiler lambda_cc; -      final ComputationCompiler main_default_cc, secondary_default_cc; -      final List<Computation> params; -      final List<ComputationCompiler> param_cc_list; -      final ComputationCompiler main_collection_cc, secondary_collection_cc; - -      params = new ArrayList<Computation>(); -      param_cc_list = new ArrayList<ComputationCompiler>(); - -      lambda_cc = new ComputationCompiler(compiler); -      main_default_cc = new ComputationCompiler(compiler); -      secondary_default_cc = new ComputationCompiler(compiler); - -      source.get_lambda_function().get_visited_by(lambda_cc); - -      if (lambda_cc.has_init()) -      { -         result.add(lambda_cc.get_init()); -      } - -      main_collection_cc = new ComputationCompiler(compiler); - -      source.get_main_collection().get_visited_by(main_collection_cc); - -      if (main_collection_cc.has_init()) -      { -         result.add(main_collection_cc.get_init()); -      } - -      source.get_main_default().get_visited_by(main_default_cc); - -      main_default_cc.generate_address(); - -      if (main_default_cc.has_init()) -      { -         result.add(main_default_cc.get_init()); -      } - -      source.get_secondary_default().get_visited_by(secondary_default_cc); - -      secondary_default_cc.generate_address(); - -      if (secondary_default_cc.has_init()) -      { -         result.add(secondary_default_cc.get_init()); -      } - -      holder = -         compiler.registers().reserve -         ( -            main_collection_cc.get_computation().get_type(), -            result -         ); - -      result.add -      ( -         new SetValue -         ( -            holder.get_address(), -            main_collection_cc.get_computation() -         ) -      ); - -      result.add -      ( -         tonkadur.wyrd.v1.compiler.util.Clear.generate -         ( -            compiler.registers(), -            compiler.assembler(), -            main_collection_cc.get_address() -         ) -      ); - -      secondary_collection_cc = new ComputationCompiler(compiler); - -      source.get_secondary_collection().get_visited_by(secondary_collection_cc); - -      if (secondary_collection_cc.has_init()) -      { -         result.add(secondary_collection_cc.get_init()); -      } - -      for -      ( -         final tonkadur.fate.v1.lang.meta.Computation p: -            source.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 -      ( -         tonkadur.wyrd.v1.compiler.util.IndexedMergeLambda.generate -         ( -            compiler.registers(), -            compiler.assembler(), -            lambda_cc.get_computation(), -            secondary_default_cc.get_computation(), -            secondary_collection_cc.get_address(), -            main_default_cc.get_computation(), -            holder.get_address(), -            main_collection_cc.get_address(), -            ( -               (tonkadur.fate.v1.lang.type.CollectionType) -               source.get_main_collection().get_type() -            ).is_set(), -            params -         ) -      ); - -      main_collection_cc.release_registers(result); -      secondary_collection_cc.release_registers(result); -      main_default_cc.release_registers(result); -      secondary_default_cc.release_registers(result); -      compiler.registers().release(holder, result); - -      for (final ComputationCompiler cc: param_cc_list) -      { -         cc.release_registers(result); -      } -   } - -   private void compile_indexed_merge_without_defaults +   public void compile     ( -      final IndexedMerge source +      final tonkadur.fate.v1.lang.instruction.GenericInstruction instruction     )     throws Throwable     { +      final IndexedMerge source;        final Register holder;        final ComputationCompiler lambda_cc;        final List<Computation> params;        final List<ComputationCompiler> param_cc_list;        final ComputationCompiler main_collection_cc, secondary_collection_cc; +      source = (IndexedMerge) instruction; +        params = new ArrayList<Computation>();        param_cc_list = new ArrayList<ComputationCompiler>(); @@ -291,24 +151,4 @@ public class IndexedMergeCompiler extends GenericInstructionCompiler           cc.release_registers(result);        }     } - -   public void compile -   ( -      final tonkadur.fate.v1.lang.instruction.GenericInstruction instruction -   ) -   throws Throwable -   { -      final IndexedMerge source; - -      source = (IndexedMerge) instruction; - -      if (source.get_main_default() != null) -      { -         compile_indexed_merge_with_defaults(source); -      } -      else -      { -         compile_indexed_merge_without_defaults(source); -      } -   }  } diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/IndexedSafeMergeCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/IndexedSafeMergeCompiler.java new file mode 100644 index 0000000..726ad2e --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/IndexedSafeMergeCompiler.java @@ -0,0 +1,179 @@ +package tonkadur.wyrd.v1.compiler.fate.v1.instruction.generic; + +import java.util.List; +import java.util.ArrayList; + +import tonkadur.fate.v1.lang.instruction.generic.IndexedSafeMerge; + +import tonkadur.wyrd.v1.compiler.fate.v1.Compiler; +import tonkadur.wyrd.v1.compiler.fate.v1.ComputationCompiler; + +import tonkadur.wyrd.v1.lang.Register; + +import tonkadur.wyrd.v1.lang.meta.Computation; + +import tonkadur.wyrd.v1.lang.instruction.SetValue; + +import tonkadur.wyrd.v1.compiler.fate.v1.instruction.GenericInstructionCompiler; + +public class IndexedSafeMergeCompiler extends GenericInstructionCompiler +{ +   public static Class get_target_class () +   { +      return IndexedSafeMerge.class; +   } + +   public IndexedSafeMergeCompiler (final Compiler compiler) +   { +      super(compiler); +   } + +   public void compile +   ( +      final tonkadur.fate.v1.lang.instruction.GenericInstruction instruction +   ) +   throws Throwable +   { +      final IndexedSafeMerge source; +      final Register holder; +      final ComputationCompiler lambda_cc; +      final ComputationCompiler main_default_cc, secondary_default_cc; +      final List<Computation> params; +      final List<ComputationCompiler> param_cc_list; +      final ComputationCompiler main_collection_cc, secondary_collection_cc; + +      source = (IndexedSafeMerge) instruction; + +      params = new ArrayList<Computation>(); +      param_cc_list = new ArrayList<ComputationCompiler>(); + +      lambda_cc = new ComputationCompiler(compiler); +      main_default_cc = new ComputationCompiler(compiler); +      secondary_default_cc = new ComputationCompiler(compiler); + +      source.get_lambda_function().get_visited_by(lambda_cc); + +      if (lambda_cc.has_init()) +      { +         result.add(lambda_cc.get_init()); +      } + +      main_collection_cc = new ComputationCompiler(compiler); + +      source.get_main_collection().get_visited_by(main_collection_cc); + +      if (main_collection_cc.has_init()) +      { +         result.add(main_collection_cc.get_init()); +      } + +      source.get_main_default().get_visited_by(main_default_cc); + +      main_default_cc.generate_address(); + +      if (main_default_cc.has_init()) +      { +         result.add(main_default_cc.get_init()); +      } + +      source.get_secondary_default().get_visited_by(secondary_default_cc); + +      secondary_default_cc.generate_address(); + +      if (secondary_default_cc.has_init()) +      { +         result.add(secondary_default_cc.get_init()); +      } + +      holder = +         compiler.registers().reserve +         ( +            main_collection_cc.get_computation().get_type(), +            result +         ); + +      result.add +      ( +         new SetValue +         ( +            holder.get_address(), +            main_collection_cc.get_computation() +         ) +      ); + +      result.add +      ( +         tonkadur.wyrd.v1.compiler.util.Clear.generate +         ( +            compiler.registers(), +            compiler.assembler(), +            main_collection_cc.get_address() +         ) +      ); + +      secondary_collection_cc = new ComputationCompiler(compiler); + +      source.get_secondary_collection().get_visited_by(secondary_collection_cc); + +      if (secondary_collection_cc.has_init()) +      { +         result.add(secondary_collection_cc.get_init()); +      } + +      for +      ( +         final tonkadur.fate.v1.lang.meta.Computation p: +            source.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 +      ( +         tonkadur.wyrd.v1.compiler.util.IndexedMergeLambda.generate +         ( +            compiler.registers(), +            compiler.assembler(), +            lambda_cc.get_computation(), +            secondary_default_cc.get_computation(), +            secondary_collection_cc.get_address(), +            main_default_cc.get_computation(), +            holder.get_address(), +            main_collection_cc.get_address(), +            ( +               (tonkadur.fate.v1.lang.type.CollectionType) +               source.get_main_collection().get_type() +            ).is_set(), +            params +         ) +      ); + +      main_collection_cc.release_registers(result); +      secondary_collection_cc.release_registers(result); +      main_default_cc.release_registers(result); +      secondary_default_cc.release_registers(result); +      compiler.registers().release(holder, result); + +      for (final ComputationCompiler cc: param_cc_list) +      { +         cc.release_registers(result); +      } +   } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/MergeCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/MergeCompiler.java index 21c817e..12f77e9 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/MergeCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/MergeCompiler.java @@ -28,157 +28,20 @@ public class MergeCompiler extends GenericInstructionCompiler        super(compiler);     } -   private void compile_merge_with_defaults (final Merge source) +   public void compile +   ( +      final tonkadur.fate.v1.lang.instruction.GenericInstruction instruction +   )     throws Throwable     { +      final Merge source;        final Register holder;        final ComputationCompiler lambda_cc; -      final ComputationCompiler main_default_cc, secondary_default_cc;        final List<Computation> params;        final List<ComputationCompiler> param_cc_list;        final ComputationCompiler main_collection_cc, secondary_collection_cc; -      params = new ArrayList<Computation>(); -      param_cc_list = new ArrayList<ComputationCompiler>(); - -      lambda_cc = new ComputationCompiler(compiler); -      main_default_cc = new ComputationCompiler(compiler); -      secondary_default_cc = new ComputationCompiler(compiler); - -      source.get_lambda_function().get_visited_by(lambda_cc); - -      if (lambda_cc.has_init()) -      { -         result.add(lambda_cc.get_init()); -      } - -      main_collection_cc = new ComputationCompiler(compiler); - -      source.get_main_collection().get_visited_by(main_collection_cc); - -      if (main_collection_cc.has_init()) -      { -         result.add(main_collection_cc.get_init()); -      } - -      source.get_main_default().get_visited_by(main_default_cc); - -      main_default_cc.generate_address(); - -      if (main_default_cc.has_init()) -      { -         result.add(main_default_cc.get_init()); -      } - -      source.get_secondary_default().get_visited_by(secondary_default_cc); - -      secondary_default_cc.generate_address(); - -      if (secondary_default_cc.has_init()) -      { -         result.add(secondary_default_cc.get_init()); -      } - -      holder = -         compiler.registers().reserve -         ( -            main_collection_cc.get_computation().get_type(), -            result -         ); - -      result.add -      ( -         new SetValue -         ( -            holder.get_address(), -            main_collection_cc.get_computation() -         ) -      ); - -      result.add -      ( -         tonkadur.wyrd.v1.compiler.util.Clear.generate -         ( -            compiler.registers(), -            compiler.assembler(), -            main_collection_cc.get_address() -         ) -      ); - -      secondary_collection_cc = new ComputationCompiler(compiler); - -      source.get_secondary_collection().get_visited_by(secondary_collection_cc); - -      if (secondary_collection_cc.has_init()) -      { -         result.add(secondary_collection_cc.get_init()); -      } - -      for -      ( -         final tonkadur.fate.v1.lang.meta.Computation p: -            source.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 -      ( -         tonkadur.wyrd.v1.compiler.util.MergeLambda.generate -         ( -            compiler.registers(), -            compiler.assembler(), -            lambda_cc.get_computation(), -            secondary_default_cc.get_computation(), -            secondary_collection_cc.get_address(), -            main_default_cc.get_computation(), -            holder.get_address(), -            main_collection_cc.get_address(), -            ( -               (tonkadur.fate.v1.lang.type.CollectionType) -               source.get_main_collection().get_type() -            ).is_set(), -            params -         ) -      ); - -      main_collection_cc.release_registers(result); -      secondary_collection_cc.release_registers(result); -      main_default_cc.release_registers(result); -      secondary_default_cc.release_registers(result); -      compiler.registers().release(holder, result); - -      for (final ComputationCompiler cc: param_cc_list) -      { -         cc.release_registers(result); -      } -   } - -   private void compile_merge_without_defaults (final Merge source) -   throws Throwable -   { -      final Register holder; -      final ComputationCompiler lambda_cc; -      final List<Computation> params; -      final List<ComputationCompiler> param_cc_list; -      final ComputationCompiler main_collection_cc, secondary_collection_cc; +      source = (Merge) instruction;        params = new ArrayList<Computation>();        param_cc_list = new ArrayList<ComputationCompiler>(); @@ -288,24 +151,4 @@ public class MergeCompiler extends GenericInstructionCompiler           cc.release_registers(result);        }     } - -   public void compile -   ( -      final tonkadur.fate.v1.lang.instruction.GenericInstruction instruction -   ) -   throws Throwable -   { -      final Merge source; - -      source = (Merge) instruction; - -      if (source.get_main_default() != null) -      { -         compile_merge_with_defaults(source); -      } -      else -      { -         compile_merge_without_defaults(source); -      } -   }  } diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/SafeMergeCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/SafeMergeCompiler.java new file mode 100644 index 0000000..128569d --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/instruction/generic/SafeMergeCompiler.java @@ -0,0 +1,180 @@ +package tonkadur.wyrd.v1.compiler.fate.v1.instruction.generic; + +import java.util.List; +import java.util.ArrayList; + +import tonkadur.fate.v1.lang.instruction.generic.SafeMerge; + +import tonkadur.wyrd.v1.compiler.fate.v1.Compiler; +import tonkadur.wyrd.v1.compiler.fate.v1.ComputationCompiler; + +import tonkadur.wyrd.v1.lang.Register; + +import tonkadur.wyrd.v1.lang.meta.Computation; + +import tonkadur.wyrd.v1.lang.instruction.SetValue; + +import tonkadur.wyrd.v1.compiler.fate.v1.instruction.GenericInstructionCompiler; + +public class SafeMergeCompiler extends GenericInstructionCompiler +{ +   public static Class get_target_class () +   { +      return SafeMerge.class; +   } + +   public SafeMergeCompiler (final Compiler compiler) +   { +      super(compiler); +   } + +   public void compile +   ( +      final tonkadur.fate.v1.lang.instruction.GenericInstruction instruction +   ) +   throws Throwable +   { +      final SafeMerge source; +      final Register holder; +      final ComputationCompiler lambda_cc; +      final ComputationCompiler main_default_cc, secondary_default_cc; +      final List<Computation> params; +      final List<ComputationCompiler> param_cc_list; +      final ComputationCompiler main_collection_cc, secondary_collection_cc; + +      source = (SafeMerge) instruction; + +      params = new ArrayList<Computation>(); +      param_cc_list = new ArrayList<ComputationCompiler>(); + +      lambda_cc = new ComputationCompiler(compiler); +      main_default_cc = new ComputationCompiler(compiler); +      secondary_default_cc = new ComputationCompiler(compiler); + +      source.get_lambda_function().get_visited_by(lambda_cc); + +      if (lambda_cc.has_init()) +      { +         result.add(lambda_cc.get_init()); +      } + +      main_collection_cc = new ComputationCompiler(compiler); + +      source.get_main_collection().get_visited_by(main_collection_cc); + +      if (main_collection_cc.has_init()) +      { +         result.add(main_collection_cc.get_init()); +      } + +      source.get_main_default().get_visited_by(main_default_cc); + +      main_default_cc.generate_address(); + +      if (main_default_cc.has_init()) +      { +         result.add(main_default_cc.get_init()); +      } + +      source.get_secondary_default().get_visited_by(secondary_default_cc); + +      secondary_default_cc.generate_address(); + +      if (secondary_default_cc.has_init()) +      { +         result.add(secondary_default_cc.get_init()); +      } + +      holder = +         compiler.registers().reserve +         ( +            main_collection_cc.get_computation().get_type(), +            result +         ); + +      result.add +      ( +         new SetValue +         ( +            holder.get_address(), +            main_collection_cc.get_computation() +         ) +      ); + +      result.add +      ( +         tonkadur.wyrd.v1.compiler.util.Clear.generate +         ( +            compiler.registers(), +            compiler.assembler(), +            main_collection_cc.get_address() +         ) +      ); + +      secondary_collection_cc = new ComputationCompiler(compiler); + +      source.get_secondary_collection().get_visited_by(secondary_collection_cc); + +      if (secondary_collection_cc.has_init()) +      { +         result.add(secondary_collection_cc.get_init()); +      } + +      for +      ( +         final tonkadur.fate.v1.lang.meta.Computation p: +            source.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 +      ( +         tonkadur.wyrd.v1.compiler.util.MergeLambda.generate +         ( +            compiler.registers(), +            compiler.assembler(), +            lambda_cc.get_computation(), +            secondary_default_cc.get_computation(), +            secondary_collection_cc.get_address(), +            main_default_cc.get_computation(), +            holder.get_address(), +            main_collection_cc.get_address(), +            ( +               (tonkadur.fate.v1.lang.type.CollectionType) +               source.get_main_collection().get_type() +            ).is_set(), +            params +         ) +      ); + +      main_collection_cc.release_registers(result); +      secondary_collection_cc.release_registers(result); +      main_default_cc.release_registers(result); +      secondary_default_cc.release_registers(result); +      compiler.registers().release(holder, result); + +      for (final ComputationCompiler cc: param_cc_list) +      { +         cc.release_registers(result); +      } + +   } +} | 


