| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2021-09-02 00:58:02 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2021-09-02 00:58:02 +0200 |
| commit | 6d01d428f53bbe1203bc08b15bddb74554ea2d86 (patch) | |
| tree | 40c59cd523762303a58bc1acc916a54d1c541ee8 /src | |
| parent | 535eabb82e49f94f51189823f6ee78b9103ed226 (diff) | |
...
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); + } + + } +} |


