| summaryrefslogtreecommitdiff |
diff options
17 files changed, 2425 insertions, 16 deletions
diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/IndexedFilterComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/IndexedFilterComputation.java new file mode 100644 index 0000000..573a78f --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/IndexedFilterComputation.java @@ -0,0 +1,137 @@ +package tonkadur.fate.v1.lang.computation; + +import java.util.Collections; +import java.util.List; +import java.util.ArrayList; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.type.Type; +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; + +public class IndexedFilterComputation extends Computation +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final List<Computation> extra_params; + protected final Computation lambda_function; + protected final Computation collection; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected IndexedFilterComputation + ( + final Origin origin, + final Computation lambda_function, + final Computation collection, + final List<Computation> extra_params + ) + { + super(origin, collection.get_type()); + + this.lambda_function = lambda_function; + this.collection = collection; + this.extra_params = extra_params; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static IndexedFilterComputation build + ( + final Origin origin, + final Computation lambda_function, + final Computation collection, + final List<Computation> extra_params + ) + throws ParsingError + { + final List<Type> target_signature; + + target_signature = new ArrayList<Type>(); + + RecurrentChecks.assert_is_a_collection(collection); + + target_signature.add(Type.INT); + target_signature.add + ( + ((CollectionType) collection.get_type()).get_content_type() + ); + + for (final Computation c: extra_params) + { + target_signature.add(c.get_type()); + } + + RecurrentChecks.assert_lambda_matches_types + ( + lambda_function, + Type.BOOL, + target_signature + ); + + return + new IndexedFilterComputation + ( + origin, + lambda_function, + collection, + extra_params + ); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final ComputationVisitor cv) + throws Throwable + { + cv.visit_indexed_filter(this); + } + + public Computation get_lambda_function () + { + return lambda_function; + } + + public Computation get_collection () + { + return collection; + } + + public List<Computation> get_extra_parameters () + { + return extra_params; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(IndexedFilter "); + sb.append(lambda_function.toString()); + sb.append(" "); + sb.append(collection.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/IndexedMergeComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java new file mode 100644 index 0000000..3a81b53 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java @@ -0,0 +1,178 @@ +package tonkadur.fate.v1.lang.computation; + +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; + +public class IndexedMergeComputation extends Computation +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final List<Computation> extra_params; + protected final Computation lambda_function; + protected final Computation collection_in_a; + protected final Computation collection_in_b; + protected final boolean to_set; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected IndexedMergeComputation + ( + final Origin origin, + final Computation lambda_function, + final Computation collection_in_a, + final Computation collection_in_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.collection_in_b = collection_in_b; + this.to_set = to_set; + this.extra_params = extra_params; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static IndexedMergeComputation build + ( + final Origin origin, + final Computation lambda_function, + final Computation collection_in_a, + final Computation collection_in_b, + final boolean to_set, + final List<Computation> extra_params + ) + throws Throwable + { + final List<Type> types_in; + + types_in = new ArrayList<Type>(); + + RecurrentChecks.assert_is_a_collection(collection_in_a); + RecurrentChecks.assert_is_a_collection(collection_in_b); + + types_in.add(Type.INT); + + types_in.add + ( + ((CollectionType) collection_in_a.get_type()).get_content_type() + ); + + types_in.add + ( + ((CollectionType) collection_in_b.get_type()).get_content_type() + ); + + for (final Computation c: extra_params) + { + types_in.add(c.get_type()); + } + + RecurrentChecks.assert_lambda_matches_types(lambda_function, types_in); + + return + new IndexedMergeComputation + ( + origin, + lambda_function, + collection_in_a, + collection_in_b, + to_set, + extra_params, + CollectionType.build + ( + origin, + ((LambdaType) lambda_function.get_type()).get_return_type(), + to_set, + "auto generated" + ) + ); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final ComputationVisitor cv) + throws Throwable + { + cv.visit_indexed_merge(this); + } + + public Computation get_lambda_function () + { + return lambda_function; + } + + public Computation get_collection_in_a () + { + return collection_in_a; + } + + public Computation get_collection_in_b () + { + return collection_in_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("(IndexedMergeToSet "); + } + else + { + sb.append("(IndexedMergeToList "); + } + + sb.append(lambda_function.toString()); + sb.append(" "); + sb.append(collection_in_a.toString()); + sb.append(" "); + + sb.append(collection_in_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/IndexedPartitionComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/IndexedPartitionComputation.java new file mode 100644 index 0000000..d192f36 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/IndexedPartitionComputation.java @@ -0,0 +1,151 @@ +package tonkadur.fate.v1.lang.computation; + +import java.util.Collections; +import java.util.List; +import java.util.ArrayList; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.type.CollectionType; +import tonkadur.fate.v1.lang.type.ConsType; +import tonkadur.fate.v1.lang.type.Type; + +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; + +public class IndexedPartitionComputation extends Computation +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final List<Computation> extra_params; + protected final Computation lambda_function; + protected final Computation collection; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected IndexedPartitionComputation + ( + final Origin origin, + final Computation lambda_function, + final Computation collection, + final List<Computation> extra_params, + final Type output_type + ) + { + super(origin, output_type); + + this.lambda_function = lambda_function; + this.collection = collection; + this.extra_params = extra_params; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static IndexedPartitionComputation build + ( + final Origin origin, + final Computation lambda_function, + final Computation collection, + final List<Computation> extra_params + ) + throws Throwable + { + final Type type; + final List<Type> target_signature; + + target_signature = new ArrayList<Type>(); + + RecurrentChecks.assert_is_a_collection(collection); + + target_signature.add(Type.INT); + + target_signature.add + ( + ((CollectionType) collection.get_type()).get_content_type() + ); + + for (final Computation c: extra_params) + { + target_signature.add(c.get_type()); + } + + RecurrentChecks.assert_lambda_matches_types + ( + lambda_function, + Type.BOOL, + target_signature + ); + + type = + new ConsType + ( + origin, + collection.get_type(), + collection.get_type(), + "auto generated" + ); + + return + new IndexedPartitionComputation + ( + origin, + lambda_function, + collection, + extra_params, + type + ); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final ComputationVisitor cv) + throws Throwable + { + cv.visit_indexed_partition(this); + } + + public Computation get_lambda_function () + { + return lambda_function; + } + + public Computation get_collection () + { + return collection; + } + + public List<Computation> get_extra_parameters () + { + return extra_params; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(IndexedPartition "); + sb.append(lambda_function.toString()); + sb.append(" "); + sb.append(collection.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/instruction/IndexedFilter.java b/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedFilter.java new file mode 100644 index 0000000..e05b162 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedFilter.java @@ -0,0 +1,131 @@ +package tonkadur.fate.v1.lang.instruction; + +import java.util.Collections; +import java.util.List; +import java.util.ArrayList; + +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.Computation; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Reference; +import tonkadur.fate.v1.lang.meta.RecurrentChecks; + +public class IndexedFilter extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final List<Computation> extra_params; + protected final Computation lambda_function; + protected final Reference collection; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected IndexedFilter + ( + final Origin origin, + final Computation lambda_function, + final Reference collection, + final List<Computation> extra_params + ) + { + super(origin); + + this.lambda_function = lambda_function; + this.collection = collection; + this.extra_params = extra_params; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static IndexedFilter build + ( + final Origin origin, + final Computation lambda_function, + final Reference collection, + final List<Computation> extra_params + ) + throws ParsingError + { + final List<Type> target_signature; + + target_signature = new ArrayList<Type>(); + + RecurrentChecks.assert_is_a_collection(collection); + + target_signature.add(Type.INT); + target_signature.add + ( + ((CollectionType) collection.get_type()).get_content_type() + ); + + for (final Computation c: extra_params) + { + target_signature.add(c.get_type()); + } + RecurrentChecks.assert_lambda_matches_types + ( + lambda_function, + Type.BOOL, + target_signature + ); + + return new IndexedFilter(origin, lambda_function, collection, extra_params); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_indexed_filter(this); + } + + public Computation get_lambda_function () + { + return lambda_function; + } + + public Reference get_collection () + { + return collection; + } + + public List<Computation> get_extra_parameters () + { + return extra_params; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(IndexedFilter "); + sb.append(lambda_function.toString()); + sb.append(" "); + sb.append(collection.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/instruction/IndexedMerge.java b/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java new file mode 100644 index 0000000..5fd86ec --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java @@ -0,0 +1,156 @@ +package tonkadur.fate.v1.lang.instruction; + +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.CollectionType; + +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Reference; +import tonkadur.fate.v1.lang.meta.RecurrentChecks; + +public class IndexedMerge extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final List<Computation> extra_params; + protected final Computation lambda_function; + protected final Reference collection; + protected final Computation collection_in_b; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected IndexedMerge + ( + final Origin origin, + final Computation lambda_function, + final Reference collection, + final Computation collection_in_b, + final List<Computation> extra_params + ) + { + super(origin); + + this.lambda_function = lambda_function; + this.collection = collection; + this.collection_in_b = collection_in_b; + this.extra_params = extra_params; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static IndexedMerge build + ( + final Origin origin, + final Computation lambda_function, + final Reference collection, + final Computation collection_in_b, + final List<Computation> extra_params + ) + throws Throwable + { + final List<Type> types_in; + + types_in = new ArrayList<Type>(); + + RecurrentChecks.assert_is_a_collection(collection); + RecurrentChecks.assert_is_a_collection(collection_in_b); + + types_in.add(Type.INT); + types_in.add + ( + ((CollectionType) collection.get_type()).get_content_type() + ); + + types_in.add + ( + ((CollectionType) collection_in_b.get_type()).get_content_type() + ); + + for (final Computation c: extra_params) + { + types_in.add(c.get_type()); + } + + RecurrentChecks.assert_lambda_matches_types + ( + lambda_function, + ((CollectionType) collection.get_type()).get_content_type(), + types_in + ); + + return + new IndexedMerge + ( + origin, + lambda_function, + collection, + collection_in_b, + extra_params + ); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_indexed_merge(this); + } + + public Computation get_lambda_function () + { + return lambda_function; + } + + public Computation get_collection_in_b () + { + return collection_in_b; + } + + public Reference get_collection () + { + return collection; + } + + public List<Computation> get_extra_parameters () + { + return extra_params; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(IndexedMerge "); + sb.append(lambda_function.toString()); + sb.append(" "); + sb.append(collection.toString()); + + sb.append(" "); + sb.append(collection_in_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/instruction/IndexedPartition.java b/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedPartition.java new file mode 100644 index 0000000..cec125a --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedPartition.java @@ -0,0 +1,156 @@ +package tonkadur.fate.v1.lang.instruction; + +import java.util.Collections; +import java.util.List; +import java.util.ArrayList; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.type.Type; +import tonkadur.fate.v1.lang.type.CollectionType; + +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Reference; +import tonkadur.fate.v1.lang.meta.RecurrentChecks; + +public class IndexedPartition extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final List<Computation> extra_params; + protected final Computation lambda_function; + protected final Reference collection_in; + protected final Reference collection_out; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected IndexedPartition + ( + final Origin origin, + final Computation lambda_function, + final Reference collection_in, + final Reference collection_out, + final List<Computation> extra_params + ) + { + super(origin); + + this.lambda_function = lambda_function; + this.collection_in = collection_in; + this.collection_out = collection_out; + this.extra_params = extra_params; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static IndexedPartition build + ( + final Origin origin, + final Computation lambda_function, + final Reference collection_in, + final Reference collection_out, + final List<Computation> extra_params + ) + throws ParsingError + { + final List<Type> target_signature; + + target_signature = new ArrayList<Type>(); + + RecurrentChecks.assert_is_a_collection(collection_in); + RecurrentChecks.assert_is_a_collection(collection_out); + RecurrentChecks.assert_can_be_used_as + ( + collection_in, + collection_out.get_type() + ); + + target_signature.add(Type.INT); + target_signature.add + ( + ((CollectionType) collection_in.get_type()).get_content_type() + ); + + for (final Computation c: extra_params) + { + target_signature.add(c.get_type()); + } + + RecurrentChecks.assert_lambda_matches_types + ( + lambda_function, + Type.BOOL, + target_signature + ); + + return + new IndexedPartition + ( + origin, + lambda_function, + collection_in, + collection_out, + extra_params + ); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_indexed_partition(this); + } + + public Computation get_lambda_function () + { + return lambda_function; + } + + public Reference get_collection_in () + { + return collection_in; + } + + public Reference get_collection_out () + { + return collection_out; + } + + public List<Computation> get_extra_parameters () + { + return extra_params; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(IndexedPartition "); + sb.append(lambda_function.toString()); + sb.append(" "); + sb.append(collection_in.toString()); + sb.append(" "); + sb.append(collection_out.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/meta/ComputationVisitor.java b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java index 4beca98..cd164c9 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java @@ -133,15 +133,24 @@ public interface ComputationVisitor public void visit_merge (final MergeComputation n) throws Throwable; + public void visit_indexed_merge (final IndexedMergeComputation n) + throws Throwable; + public void visit_filter (final FilterComputation n) throws Throwable; + public void visit_indexed_filter (final IndexedFilterComputation n) + throws Throwable; + public void visit_sublist (final SubListComputation n) throws Throwable; public void visit_partition (final PartitionComputation n) throws Throwable; + public void visit_indexed_partition (final IndexedPartitionComputation n) + throws Throwable; + public void visit_push_element (final PushElementComputation n) throws Throwable; diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java b/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java index b356f7d..a3038ac 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java @@ -56,15 +56,24 @@ public interface InstructionVisitor public void visit_merge (final Merge n) throws Throwable; + public void visit_indexed_merge (final IndexedMerge n) + throws Throwable; + public void visit_filter (final Filter n) throws Throwable; + public void visit_indexed_filter (final IndexedFilter n) + throws Throwable; + public void visit_sublist (final SubList n) throws Throwable; public void visit_partition (final Partition n) throws Throwable; + public void visit_indexed_partition (final IndexedPartition n) + throws Throwable; + public void visit_sort (final Sort n) throws Throwable; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index b8d0bc7..c5f073d 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -57,7 +57,9 @@ IGNORE_ERROR_KW: L_PAREN 'ignore'US('error'|'warning') SEP+; FATE_VERSION_KW: L_PAREN 'fate'US'version' SEP+; FIELD_KW: L_PAREN 'field' SEP+; FILTER_KW: L_PAREN 'filter' SEP+; +INDEXED_FILTER_KW: L_PAREN 'indexed'US'filter' SEP+; IMP_FILTER_KW: L_PAREN 'filter!' SEP+; +IMP_INDEXED_FILTER_KW: L_PAREN 'indexed'US'filter!' SEP+; FOR_EACH_KW: L_PAREN ('for'US'each') SEP+; FOR_KW: L_PAREN 'for' SEP+; FOLDR_KW: L_PAREN 'foldr' SEP+; @@ -88,7 +90,10 @@ CLAMP_KW: L_PAREN ('clamp') SEP+; MODULO_KW: L_PAREN ('modulo'|'%'|'mod') SEP+; MERGE_TO_LIST_KW : L_PAREN 'merge'US'to'US'list' SEP+; MERGE_TO_SET_KW : L_PAREN 'merge'US'to'US'set' SEP+; +INDEXED_MERGE_TO_LIST_KW : L_PAREN 'indexed'US'merge'US'to'US'list' SEP+; +INDEXED_MERGE_TO_SET_KW : L_PAREN 'indexed'US'merge'US'to'US'set' SEP+; IMP_MERGE_KW : L_PAREN 'merge!' SEP+; +IMP_INDEXED_MERGE_KW : L_PAREN 'indexed'US'merge!' SEP+; NEWLINE_KW: L_PAREN 'newline)'; NEW_KW: L_PAREN ('new'|'reserve'|'create') SEP+; NOT_KW: L_PAREN ('not'|'~'|'!') SEP+; @@ -97,6 +102,8 @@ OR_KW: L_PAREN ('or'|'\\/') SEP+; RICH_TEXT_KW: L_PAREN (('rich'US)?'text') SEP+; PARTITION_KW: L_PAREN 'partition' SEP+; IMP_PARTITION_KW: L_PAREN 'partition!' SEP+; +INDEXED_PARTITION_KW: L_PAREN 'indexed'US'partition' SEP+; +IMP_INDEXED_PARTITION_KW: L_PAREN 'indexed'US'partition!' SEP+; POP_LEFT_KW: L_PAREN 'pop'US'left' SEP+; IMP_POP_LEFT_KW: L_PAREN 'pop'US'left!' SEP+; POP_RIGHT_KW: L_PAREN 'pop'US'right' SEP+; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 1289a9e..d4798a0 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -924,6 +924,49 @@ returns [Instruction result] ); } + | IMP_INDEXED_MERGE_KW + fun=non_text_value WS+ + value_reference WS+ + inv1=non_text_value WS* + R_PAREN + { + $result = + IndexedMerge.build + ( + CONTEXT.get_origin_at + ( + ($IMP_INDEXED_MERGE_KW.getLine()), + ($IMP_INDEXED_MERGE_KW.getCharPositionInLine()) + ), + ($fun.result), + ($value_reference.result), + ($inv1.result), + new ArrayList() + ); + } + + | IMP_INDEXED_MERGE_KW + fun=non_text_value WS+ + value_reference WS+ + inv1=non_text_value WS+ + value_list WS* + R_PAREN + { + $result = + IndexedMerge.build + ( + CONTEXT.get_origin_at + ( + ($IMP_INDEXED_MERGE_KW.getLine()), + ($IMP_INDEXED_MERGE_KW.getCharPositionInLine()) + ), + ($fun.result), + ($value_reference.result), + ($inv1.result), + ($value_list.result) + ); + } + | IMP_MERGE_KW fun=non_text_value WS+ def0=value WS+ @@ -1027,6 +1070,42 @@ returns [Instruction result] ); } + | IMP_INDEXED_FILTER_KW non_text_value WS+ value_reference WS* R_PAREN + { + $result = + IndexedFilter.build + ( + CONTEXT.get_origin_at + ( + ($IMP_INDEXED_FILTER_KW.getLine()), + ($IMP_INDEXED_FILTER_KW.getCharPositionInLine()) + ), + ($non_text_value.result), + ($value_reference.result), + new ArrayList() + ); + } + + | IMP_INDEXED_FILTER_KW + non_text_value WS+ + value_reference WS+ + value_list WS* + R_PAREN + { + $result = + IndexedFilter.build + ( + CONTEXT.get_origin_at + ( + ($IMP_INDEXED_FILTER_KW.getLine()), + ($IMP_INDEXED_FILTER_KW.getCharPositionInLine()) + ), + ($non_text_value.result), + ($value_reference.result), + ($value_list.result) + ); + } + | IMP_PARTITION_KW non_text_value WS+ iftrue=value_reference WS+ @@ -1034,7 +1113,7 @@ returns [Instruction result] R_PAREN { $result = - Partition.build + Partition.build ( CONTEXT.get_origin_at ( @@ -1056,7 +1135,7 @@ returns [Instruction result] R_PAREN { $result = - Partition.build + Partition.build ( CONTEXT.get_origin_at ( @@ -1070,6 +1149,49 @@ returns [Instruction result] ); } + | IMP_INDEXED_PARTITION_KW + non_text_value WS+ + iftrue=value_reference WS+ + iffalse=value_reference WS* + R_PAREN + { + $result = + IndexedPartition.build + ( + CONTEXT.get_origin_at + ( + ($IMP_INDEXED_PARTITION_KW.getLine()), + ($IMP_INDEXED_PARTITION_KW.getCharPositionInLine()) + ), + ($non_text_value.result), + ($iftrue.result), + ($iffalse.result), + new ArrayList() + ); + } + + | IMP_INDEXED_PARTITION_KW + non_text_value WS+ + iftrue=value_reference WS+ + iffalse=value_reference WS+ + value_list WS* + R_PAREN + { + $result = + IndexedPartition.build + ( + CONTEXT.get_origin_at + ( + ($IMP_INDEXED_PARTITION_KW.getLine()), + ($IMP_INDEXED_PARTITION_KW.getCharPositionInLine()) + ), + ($non_text_value.result), + ($iftrue.result), + ($iffalse.result), + ($value_list.result) + ); + } + | IMP_SORT_KW non_text_value WS+ value_reference WS* R_PAREN { $result = @@ -1089,7 +1211,7 @@ returns [Instruction result] | IMP_SORT_KW non_text_value WS+ value_reference WS+ value_list WS* R_PAREN { $result = - Sort.build + Sort.build ( CONTEXT.get_origin_at ( @@ -1106,7 +1228,7 @@ returns [Instruction result] | IMP_SHUFFLE_KW value_reference WS* R_PAREN { $result = - Shuffle.build + Shuffle.build ( CONTEXT.get_origin_at ( @@ -3977,6 +4099,51 @@ returns [Computation result] ); } + | INDEXED_MERGE_TO_LIST_KW + fun=non_text_value WS+ + inv0=non_text_value WS+ + inv1=non_text_value WS* + R_PAREN + { + $result = + IndexedMergeComputation.build + ( + CONTEXT.get_origin_at + ( + ($INDEXED_MERGE_TO_LIST_KW.getLine()), + ($INDEXED_MERGE_TO_LIST_KW.getCharPositionInLine()) + ), + ($fun.result), + ($inv0.result), + ($inv1.result), + false, + new ArrayList() + ); + } + + | INDEXED_MERGE_TO_LIST_KW + fun=non_text_value WS+ + inv0=non_text_value WS+ + inv1=non_text_value WS+ + value_list WS* + R_PAREN + { + $result = + IndexedMergeComputation.build + ( + CONTEXT.get_origin_at + ( + ($INDEXED_MERGE_TO_LIST_KW.getLine()), + ($INDEXED_MERGE_TO_LIST_KW.getCharPositionInLine()) + ), + ($fun.result), + ($inv0.result), + ($inv1.result), + false, + ($value_list.result) + ); + } + | MERGE_TO_LIST_KW fun=non_text_value WS+ inv0=non_text_value WS+ @@ -4079,6 +4246,51 @@ returns [Computation result] ); } + | INDEXED_MERGE_TO_SET_KW + fun=non_text_value WS+ + inv0=non_text_value WS+ + inv1=non_text_value WS* + R_PAREN + { + $result = + IndexedMergeComputation.build + ( + CONTEXT.get_origin_at + ( + ($INDEXED_MERGE_TO_SET_KW.getLine()), + ($INDEXED_MERGE_TO_SET_KW.getCharPositionInLine()) + ), + ($fun.result), + ($inv0.result), + ($inv1.result), + true, + new ArrayList() + ); + } + + | INDEXED_MERGE_TO_SET_KW + fun=non_text_value WS+ + inv0=non_text_value WS+ + inv1=non_text_value WS+ + value_list WS* + R_PAREN + { + $result = + IndexedMergeComputation.build + ( + CONTEXT.get_origin_at + ( + ($INDEXED_MERGE_TO_SET_KW.getLine()), + ($INDEXED_MERGE_TO_SET_KW.getCharPositionInLine()) + ), + ($fun.result), + ($inv0.result), + ($inv1.result), + true, + ($value_list.result) + ); + } + | MERGE_TO_SET_KW fun=non_text_value WS+ inv0=non_text_value WS+ @@ -4273,10 +4485,46 @@ returns [Computation result] ); } + | INDEXED_PARTITION_KW fun=non_text_value WS+ coll=non_text_value WS* R_PAREN + { + $result = + IndexedPartitionComputation.build + ( + CONTEXT.get_origin_at + ( + ($INDEXED_PARTITION_KW.getLine()), + ($INDEXED_PARTITION_KW.getCharPositionInLine()) + ), + ($fun.result), + ($coll.result), + new ArrayList() + ); + } + + | INDEXED_PARTITION_KW + fun=non_text_value WS+ + coll=non_text_value WS+ + value_list WS* + R_PAREN + { + $result = + IndexedPartitionComputation.build + ( + CONTEXT.get_origin_at + ( + ($INDEXED_PARTITION_KW.getLine()), + ($INDEXED_PARTITION_KW.getCharPositionInLine()) + ), + ($fun.result), + ($coll.result), + ($value_list.result) + ); + } + | SORT_KW fun=non_text_value WS+ coll=non_text_value WS* R_PAREN { $result = - SortComputation.build + SortComputation.build ( CONTEXT.get_origin_at ( @@ -4296,7 +4544,7 @@ returns [Computation result] R_PAREN { $result = - SortComputation.build + SortComputation.build ( CONTEXT.get_origin_at ( diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java index 767724a..64f7220 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java @@ -29,6 +29,7 @@ import tonkadur.wyrd.v1.compiler.util.IfElse; import tonkadur.wyrd.v1.compiler.util.If; import tonkadur.wyrd.v1.compiler.util.Fold; import tonkadur.wyrd.v1.compiler.util.FilterLambda; +import tonkadur.wyrd.v1.compiler.util.IndexedFilterLambda; import tonkadur.wyrd.v1.compiler.util.Shuffle; import tonkadur.wyrd.v1.compiler.util.RemoveAt; import tonkadur.wyrd.v1.compiler.util.RemoveElementsOf; @@ -36,8 +37,11 @@ import tonkadur.wyrd.v1.compiler.util.InsertAt; import tonkadur.wyrd.v1.compiler.util.RemoveAllOf; import tonkadur.wyrd.v1.compiler.util.IndexedMapLambda; import tonkadur.wyrd.v1.compiler.util.PartitionLambda; +import tonkadur.wyrd.v1.compiler.util.IndexedPartitionLambda; import tonkadur.wyrd.v1.compiler.util.MapLambda; +import tonkadur.wyrd.v1.compiler.util.PopElement; import tonkadur.wyrd.v1.compiler.util.MergeLambda; +import tonkadur.wyrd.v1.compiler.util.IndexedMergeLambda; import tonkadur.wyrd.v1.compiler.util.RemoveOneOf; import tonkadur.wyrd.v1.compiler.util.ReverseList; import tonkadur.wyrd.v1.compiler.util.CreateCons; @@ -1929,7 +1933,6 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor ) throws Throwable { - final Address car_addr, cdr_addr; final ComputationCompiler car_compiler, cdr_compiler; final Register result; @@ -2722,6 +2725,7 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor ) throws Throwable { + /* TODO: handle the default values if there are any. */ final List<Computation> params; final ComputationCompiler lambda_cc; final ComputationCompiler in_collection_a_cc, in_collection_b_cc; @@ -2789,6 +2793,79 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor } @Override + public void visit_indexed_merge + ( + final tonkadur.fate.v1.lang.computation.IndexedMergeComputation n + ) + throws Throwable + { + final List<Computation> params; + final ComputationCompiler lambda_cc; + final ComputationCompiler in_collection_a_cc, in_collection_b_cc; + final Register result; + + result = reserve(TypeCompiler.compile(compiler, n.get_type())); + + result_as_address = result.get_address(); + result_as_computation = result.get_value(); + + params = new ArrayList<Computation>(); + + for + ( + final tonkadur.fate.v1.lang.meta.Computation p: + n.get_extra_parameters() + ) + { + final ComputationCompiler param_cc; + + param_cc = new ComputationCompiler(compiler); + + p.get_visited_by(param_cc); + + /* Let's not re-compute the parameters on every iteration. */ + param_cc.generate_address(); + + assimilate(param_cc); + + params.add(param_cc.get_computation()); + } + + lambda_cc = new ComputationCompiler(compiler); + + n.get_lambda_function().get_visited_by(lambda_cc); + + assimilate(lambda_cc); + + in_collection_a_cc = new ComputationCompiler(compiler); + + n.get_collection_in_a().get_visited_by(in_collection_a_cc); + + assimilate(in_collection_a_cc); + + in_collection_b_cc = new ComputationCompiler(compiler); + + n.get_collection_in_b().get_visited_by(in_collection_b_cc); + + assimilate(in_collection_b_cc); + + init_instructions.add + ( + IndexedMergeLambda.generate + ( + compiler.registers(), + compiler.assembler(), + lambda_cc.get_computation(), + in_collection_a_cc.get_address(), + in_collection_b_cc.get_address(), + result_as_address, + n.to_set(), + params + ) + ); + } + + @Override public void visit_sublist ( final tonkadur.fate.v1.lang.computation.SubListComputation n @@ -2900,6 +2977,107 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor } @Override + public void visit_indexed_partition + ( + final tonkadur.fate.v1.lang.computation.IndexedPartitionComputation n + ) + throws Throwable + { + final List<Computation> params; + final ComputationCompiler lambda_cc, in_collection_cc; + final Address car_addr, cdr_addr; + final Register result; + + result = reserve(DictType.WILD); + + result_as_address = result.get_address(); + result_as_computation = result.get_value(); + + params = new ArrayList<Computation>(); + + for + ( + final tonkadur.fate.v1.lang.meta.Computation p: + n.get_extra_parameters() + ) + { + final ComputationCompiler param_cc; + + param_cc = new ComputationCompiler(compiler); + + p.get_visited_by(param_cc); + + /* Let's not re-compute the parameters on every iteration. */ + param_cc.generate_address(); + + assimilate(param_cc); + + params.add(param_cc.get_computation()); + } + + lambda_cc = new ComputationCompiler(compiler); + + n.get_lambda_function().get_visited_by(lambda_cc); + + assimilate(lambda_cc); + + in_collection_cc = new ComputationCompiler(compiler); + + n.get_collection().get_visited_by(in_collection_cc); + + if (in_collection_cc.has_init()) + { + init_instructions.add(in_collection_cc.get_init()); + } + + car_addr = + new RelativeAddress + ( + result_as_address, + new Constant(Type.STRING, "0"), + in_collection_cc.get_computation().get_type() + ); + + init_instructions.add + ( + new SetValue + ( + car_addr, + in_collection_cc.get_computation() + ) + ); + + cdr_addr = + new RelativeAddress + ( + result_as_address, + new Constant(Type.STRING, "1"), + in_collection_cc.get_computation().get_type() + ); + + in_collection_cc.release_registers(init_instructions); + + init_instructions.add(new Initialize(cdr_addr)); + + init_instructions.add + ( + IndexedPartitionLambda.generate + ( + compiler.registers(), + compiler.assembler(), + lambda_cc.get_computation(), + car_addr, + cdr_addr, + ( + (tonkadur.fate.v1.lang.type.CollectionType) + n.get_collection().get_type() + ).is_set(), + params + ) + ); + } + + @Override public void visit_sort ( final tonkadur.fate.v1.lang.computation.SortComputation n @@ -2983,6 +3161,79 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor } @Override + public void visit_indexed_filter + ( + final tonkadur.fate.v1.lang.computation.IndexedFilterComputation n + ) + throws Throwable + { + final List<Computation> params; + final ComputationCompiler lambda_cc, in_collection_cc; + final Register result; + + result = reserve(TypeCompiler.compile(compiler, n.get_type())); + + result_as_address = result.get_address(); + result_as_computation = result.get_value(); + + params = new ArrayList<Computation>(); + + for + ( + final tonkadur.fate.v1.lang.meta.Computation p: + n.get_extra_parameters() + ) + { + final ComputationCompiler param_cc; + + param_cc = new ComputationCompiler(compiler); + + p.get_visited_by(param_cc); + + /* Let's not re-compute the parameters on every iteration. */ + param_cc.generate_address(); + + assimilate(param_cc); + + params.add(param_cc.get_computation()); + } + + lambda_cc = new ComputationCompiler(compiler); + + n.get_lambda_function().get_visited_by(lambda_cc); + + assimilate(lambda_cc); + + in_collection_cc = new ComputationCompiler(compiler); + + n.get_collection().get_visited_by(in_collection_cc); + + if (in_collection_cc.has_init()) + { + init_instructions.add(in_collection_cc.get_init()); + } + + init_instructions.add + ( + new SetValue(result_as_address, in_collection_cc.get_computation()) + ); + + in_collection_cc.release_registers(init_instructions); + + init_instructions.add + ( + IndexedFilterLambda.generate + ( + compiler.registers(), + compiler.assembler(), + lambda_cc.get_computation(), + result_as_address, + params + ) + ); + } + + @Override public void visit_indexed_map ( final tonkadur.fate.v1.lang.computation.IndexedMapComputation n @@ -3130,7 +3381,75 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor ) throws Throwable { - /* TODO */ + final ComputationCompiler address_compiler; + final Register result; + final Address car_addr, cdr_addr; + + result = reserve(DictType.WILD); + result_as_computation = result.get_value(); + result_as_address = result.get_address(); + + address_compiler = new ComputationCompiler(compiler); + + n.get_collection().get_visited_by(address_compiler); + + if (address_compiler.has_init()) + { + init_instructions.add(address_compiler.get_init()); + } + + init_instructions.add + ( + new SetValue(result_as_address, address_compiler.get_computation()) + ); + + car_addr = + new RelativeAddress + ( + result_as_address, + new Constant(Type.STRING, "0"), + address_compiler.get_computation().get_type() + ); + + init_instructions.add + ( + new SetValue + ( + car_addr, + address_compiler.get_computation() + ) + ); + + address_compiler.release_registers(init_instructions); + + cdr_addr = + new RelativeAddress + ( + result_as_address, + new Constant(Type.STRING, "1"), + TypeCompiler.compile + ( + compiler, + ( + (tonkadur.fate.v1.lang.type.CollectionType) + n.get_collection().get_type() + ).get_content_type() + ) + ); + + init_instructions.add(new Initialize(cdr_addr)); + + init_instructions.add + ( + PopElement.generate + ( + compiler.registers(), + compiler.assembler(), + car_addr, + cdr_addr, + n.is_from_left() + ) + ); } @Override diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java index 9cd5d43..0f23a34 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java @@ -50,12 +50,16 @@ import tonkadur.wyrd.v1.compiler.util.IfElse; import tonkadur.wyrd.v1.compiler.util.InstructionManager; import tonkadur.wyrd.v1.compiler.util.NOP; import tonkadur.wyrd.v1.compiler.util.While; +import tonkadur.wyrd.v1.compiler.util.IndexedFilterLambda; import tonkadur.wyrd.v1.compiler.util.FilterLambda; import tonkadur.wyrd.v1.compiler.util.Shuffle; import tonkadur.wyrd.v1.compiler.util.Clear; import tonkadur.wyrd.v1.compiler.util.MapLambda; +import tonkadur.wyrd.v1.compiler.util.PopElement; import tonkadur.wyrd.v1.compiler.util.MergeLambda; +import tonkadur.wyrd.v1.compiler.util.IndexedMergeLambda; import tonkadur.wyrd.v1.compiler.util.PartitionLambda; +import tonkadur.wyrd.v1.compiler.util.IndexedPartitionLambda; import tonkadur.wyrd.v1.compiler.util.IndexedMapLambda; import tonkadur.wyrd.v1.compiler.util.IterativeSearch; import tonkadur.wyrd.v1.compiler.util.RemoveAllOf; @@ -215,7 +219,6 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor result.add(index_compiler.get_init()); } - element_compiler = new ComputationCompiler(compiler); n.get_element().get_visited_by(element_compiler); @@ -641,6 +644,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor ) throws Throwable { + /* TODO: handle default values. */ /* This is one dangerous operation to do in-place, so we don't. */ final Register holder; final ComputationCompiler lambda_cc; @@ -744,6 +748,115 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor } @Override + public void visit_indexed_merge + ( + final tonkadur.fate.v1.lang.instruction.IndexedMerge n + ) + throws Throwable + { + /* This is one dangerous operation to do in-place, so we don't. */ + final Register holder; + final ComputationCompiler lambda_cc; + final List<Computation> params; + final List<ComputationCompiler> param_cc_list; + final ComputationCompiler collection_cc, in_collection_b_cc; + + params = new ArrayList<Computation>(); + param_cc_list = new ArrayList<ComputationCompiler>(); + + lambda_cc = new ComputationCompiler(compiler); + + n.get_lambda_function().get_visited_by(lambda_cc); + + if (lambda_cc.has_init()) + { + result.add(lambda_cc.get_init()); + } + + collection_cc = new ComputationCompiler(compiler); + + n.get_collection().get_visited_by(collection_cc); + + if (collection_cc.has_init()) + { + result.add(collection_cc.get_init()); + } + + holder = + compiler.registers().reserve + ( + collection_cc.get_computation().get_type(), + result + ); + + result.add + ( + new SetValue(holder.get_address(), collection_cc.get_computation()) + ); + + in_collection_b_cc = new ComputationCompiler(compiler); + + n.get_collection_in_b().get_visited_by(in_collection_b_cc); + + if (in_collection_b_cc.has_init()) + { + result.add(in_collection_b_cc.get_init()); + } + + for + ( + final tonkadur.fate.v1.lang.meta.Computation p: + n.get_extra_parameters() + ) + { + final ComputationCompiler param_cc; + + param_cc = new ComputationCompiler(compiler); + + p.get_visited_by(param_cc); + + /* Let's not re-compute the parameters on every iteration. */ + param_cc.generate_address(); + + if (param_cc.has_init()) + { + result.add(param_cc.get_init()); + } + + param_cc_list.add(param_cc); + + params.add(param_cc.get_computation()); + } + + result.add + ( + IndexedMergeLambda.generate + ( + compiler.registers(), + compiler.assembler(), + lambda_cc.get_computation(), + holder.get_address(), + in_collection_b_cc.get_address(), + collection_cc.get_address(), + ( + (tonkadur.fate.v1.lang.type.CollectionType) + n.get_collection().get_type() + ).is_set(), + params + ) + ); + + collection_cc.release_registers(result); + in_collection_b_cc.release_registers(result); + compiler.registers().release(holder, result); + + for (final ComputationCompiler cc: param_cc_list) + { + cc.release_registers(result); + } + } + + @Override public void visit_partition ( final tonkadur.fate.v1.lang.instruction.Partition n @@ -837,6 +950,99 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor } @Override + public void visit_indexed_partition + ( + final tonkadur.fate.v1.lang.instruction.IndexedPartition n + ) + throws Throwable + { + final List<Computation> params; + final List<ComputationCompiler> param_cc_list; + final ComputationCompiler lambda_cc, collection_in_cc, collection_out_cc; + + params = new ArrayList<Computation>(); + param_cc_list = new ArrayList<ComputationCompiler>(); + + for + ( + final tonkadur.fate.v1.lang.meta.Computation p: + n.get_extra_parameters() + ) + { + final ComputationCompiler param_cc; + + param_cc = new ComputationCompiler(compiler); + + p.get_visited_by(param_cc); + + /* Let's not re-compute the parameters on every iteration. */ + param_cc.generate_address(); + + if (param_cc.has_init()) + { + result.add(param_cc.get_init()); + } + + param_cc_list.add(param_cc); + + params.add(param_cc.get_computation()); + } + + lambda_cc = new ComputationCompiler(compiler); + + n.get_lambda_function().get_visited_by(lambda_cc); + + if (lambda_cc.has_init()) + { + result.add(lambda_cc.get_init()); + } + + collection_in_cc = new ComputationCompiler(compiler); + + n.get_collection_in().get_visited_by(collection_in_cc); + + if (collection_in_cc.has_init()) + { + result.add(collection_in_cc.get_init()); + } + + collection_out_cc = new ComputationCompiler(compiler); + + n.get_collection_out().get_visited_by(collection_out_cc); + + if (collection_out_cc.has_init()) + { + result.add(collection_out_cc.get_init()); + } + + result.add + ( + IndexedPartitionLambda.generate + ( + compiler.registers(), + compiler.assembler(), + lambda_cc.get_computation(), + collection_in_cc.get_address(), + collection_out_cc.get_address(), + ( + (tonkadur.fate.v1.lang.type.CollectionType) + n.get_collection_out().get_type() + ).is_set(), + params + ) + ); + + lambda_cc.release_registers(result); + collection_in_cc.release_registers(result); + collection_out_cc.release_registers(result); + + for (final ComputationCompiler cc: param_cc_list) + { + cc.release_registers(result); + } + } + + @Override public void visit_sublist ( final tonkadur.fate.v1.lang.instruction.SubList n @@ -866,8 +1072,6 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor result.add(address_compiler.get_init()); } - address_compiler.release_registers(result); - n.get_element().get_visited_by(element_compiler); if (element_compiler.has_init()) @@ -1005,6 +1209,84 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor } @Override + public void visit_indexed_filter + ( + final tonkadur.fate.v1.lang.instruction.IndexedFilter n + ) + throws Throwable + { + final List<Computation> params; + final List<ComputationCompiler> param_cc_list; + final ComputationCompiler lambda_cc, collection_cc; + + params = new ArrayList<Computation>(); + param_cc_list = new ArrayList<ComputationCompiler>(); + + for + ( + final tonkadur.fate.v1.lang.meta.Computation p: + n.get_extra_parameters() + ) + { + final ComputationCompiler param_cc; + + param_cc = new ComputationCompiler(compiler); + + p.get_visited_by(param_cc); + + /* Let's not re-compute the parameters on every iteration. */ + param_cc.generate_address(); + + if (param_cc.has_init()) + { + result.add(param_cc.get_init()); + } + + param_cc_list.add(param_cc); + + params.add(param_cc.get_computation()); + } + + lambda_cc = new ComputationCompiler(compiler); + + n.get_lambda_function().get_visited_by(lambda_cc); + + if (lambda_cc.has_init()) + { + result.add(lambda_cc.get_init()); + } + + collection_cc = new ComputationCompiler(compiler); + + n.get_collection().get_visited_by(collection_cc); + + if (collection_cc.has_init()) + { + result.add(collection_cc.get_init()); + } + + result.add + ( + IndexedFilterLambda.generate + ( + compiler.registers(), + compiler.assembler(), + lambda_cc.get_computation(), + collection_cc.get_address(), + params + ) + ); + + lambda_cc.release_registers(result); + collection_cc.release_registers(result); + + for (final ComputationCompiler cc: param_cc_list) + { + cc.release_registers(result); + } + } + + @Override public void visit_indexed_map ( final tonkadur.fate.v1.lang.instruction.IndexedMap n @@ -1670,7 +1952,6 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor collection_cc.release_registers(result); } - @Override public void visit_cond_instruction ( @@ -1772,7 +2053,6 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor result.add(compiler.assembler().merge(previous_else_branch)); } - @Override public void visit_event_call ( diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedFilterLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedFilterLambda.java new file mode 100644 index 0000000..29f08d4 --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedFilterLambda.java @@ -0,0 +1,164 @@ +package tonkadur.wyrd.v1.compiler.util; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; + +import tonkadur.wyrd.v1.lang.Register; + +import tonkadur.wyrd.v1.lang.type.Type; +import tonkadur.wyrd.v1.lang.type.MapType; + +import tonkadur.wyrd.v1.lang.meta.Instruction; +import tonkadur.wyrd.v1.lang.meta.Computation; + +import tonkadur.wyrd.v1.lang.computation.Cast; +import tonkadur.wyrd.v1.lang.computation.Constant; +import tonkadur.wyrd.v1.lang.computation.Operation; +import tonkadur.wyrd.v1.lang.computation.Address; +import tonkadur.wyrd.v1.lang.computation.RelativeAddress; +import tonkadur.wyrd.v1.lang.computation.ValueOf; +import tonkadur.wyrd.v1.lang.computation.Size; + +import tonkadur.wyrd.v1.lang.instruction.SetValue; + +import tonkadur.wyrd.v1.compiler.util.registers.RegisterManager; + +public class IndexedFilterLambda +{ + /* Utility Class */ + private IndexedFilterLambda () {} + + /* Uses Durstenfeld's shuffling algorithm */ + public static Instruction generate + ( + final RegisterManager registers, + final InstructionManager assembler, + final Computation lambda, + final Address collection, + final List<Computation> extra_params + ) + { + final List<Instruction> result, while_body, remove_instructions; + final Register iterator, index_storage, collection_size, storage; + + result = new ArrayList<Instruction>(); + while_body = new ArrayList<Instruction>(); + remove_instructions = new ArrayList<Instruction>(); + + iterator = registers.reserve(Type.INT, result); + index_storage = registers.reserve(Type.INT, result); + collection_size = registers.reserve(Type.INT, result); + storage = registers.reserve(Type.BOOL, result); + + result.add(new SetValue(iterator.get_address(), Constant.ZERO)); + result.add + ( + new SetValue(collection_size.get_address(), new Size(collection)) + ); + + extra_params.add + ( + 0, + new ValueOf + ( + new RelativeAddress + ( + collection, + new Cast(iterator.get_value(), Type.STRING), + ((MapType) collection.get_target_type()).get_member_type() + ) + ) + ); + + extra_params.add(0, iterator.get_value()); + + remove_instructions.add + ( + new SetValue(index_storage.get_address(), iterator.get_value()) + ); + + remove_instructions.add + ( + RemoveAt.generate + ( + registers, + assembler, + index_storage.get_address(), + collection_size.get_value(), + collection + ) + ); + + remove_instructions.add + ( + new SetValue + ( + collection_size.get_address(), + Operation.minus(collection_size.get_value(), Constant.ONE) + ) + ); + + while_body.add + ( + LambdaEvaluation.generate + ( + registers, + assembler, + lambda, + /* Can't put it in the target collection directly, since that may + * be a set. + */ + storage.get_address(), + extra_params + ) + ); + + while_body.add + ( + IfElse.generate + ( + registers, + assembler, + Operation.not(storage.get_value()), + assembler.merge(remove_instructions), + new SetValue + ( + iterator.get_address(), + Operation.plus(iterator.get_value(), Constant.ONE) + ) + ) + ); + + while_body.add + ( + new SetValue + ( + iterator.get_address(), + Operation.plus(iterator.get_value(), Constant.ONE) + ) + ); + + result.add + ( + While.generate + ( + registers, + assembler, + Operation.less_than + ( + iterator.get_value(), + collection_size.get_value() + ), + assembler.merge(while_body) + ) + ); + + registers.release(iterator, result); + registers.release(index_storage, result); + registers.release(collection_size, result); + registers.release(storage, result); + + return assembler.merge(result); + } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java new file mode 100644 index 0000000..3a501e2 --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java @@ -0,0 +1,190 @@ +package tonkadur.wyrd.v1.compiler.util; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; + +import tonkadur.wyrd.v1.lang.Register; + +import tonkadur.wyrd.v1.lang.type.Type; +import tonkadur.wyrd.v1.lang.type.MapType; + +import tonkadur.wyrd.v1.lang.meta.Instruction; +import tonkadur.wyrd.v1.lang.meta.Computation; + +import tonkadur.wyrd.v1.lang.computation.Cast; +import tonkadur.wyrd.v1.lang.computation.Constant; +import tonkadur.wyrd.v1.lang.computation.Operation; +import tonkadur.wyrd.v1.lang.computation.Address; +import tonkadur.wyrd.v1.lang.computation.RelativeAddress; +import tonkadur.wyrd.v1.lang.computation.ValueOf; +import tonkadur.wyrd.v1.lang.computation.Size; +import tonkadur.wyrd.v1.lang.computation.IfElseComputation; + +import tonkadur.wyrd.v1.lang.instruction.SetValue; + +import tonkadur.wyrd.v1.compiler.util.registers.RegisterManager; + +public class IndexedMergeLambda +{ + /* Utility Class */ + private IndexedMergeLambda () {} + + /* Uses Durstenfeld's shuffling algorithm */ + public static Instruction generate + ( + final RegisterManager registers, + final InstructionManager assembler, + final Computation lambda, + final Address collection_in_a, + final Address collection_in_b, + final Address collection_out, + final boolean to_set, + final List<Computation> extra_params + ) + { + final List<Instruction> result, while_body; + final Register iterator, collection_in_size, storage; + final Register collection_in_b_size; + + result = new ArrayList<Instruction>(); + while_body = new ArrayList<Instruction>(); + + iterator = registers.reserve(Type.INT, result); + collection_in_size = registers.reserve(Type.INT, result); + collection_in_b_size = registers.reserve(Type.INT, result); + storage = + registers.reserve + ( + ((MapType) collection_out.get_target_type()).get_member_type(), + result + ); + + result.add(new SetValue(iterator.get_address(), Constant.ZERO)); + + result.add + ( + new SetValue + ( + collection_in_size.get_address(), + new Size(collection_in_a) + ) + ); + + result.add + ( + new SetValue + ( + collection_in_b_size.get_address(), + new Size(collection_in_b) + ) + ); + + result.add + ( + new SetValue + ( + collection_in_size.get_address(), + new IfElseComputation + ( + Operation.less_than + ( + collection_in_b_size.get_value(), + collection_in_size.get_value() + ), + collection_in_b_size.get_value(), + collection_in_size.get_value() + ) + ) + ); + + + extra_params.add + ( + 0, + new ValueOf + ( + new RelativeAddress + ( + collection_in_b, + new Cast(iterator.get_value(), Type.STRING), + ((MapType) collection_in_b.get_target_type()).get_member_type() + ) + ) + ); + + extra_params.add + ( + 0, + new ValueOf + ( + new RelativeAddress + ( + collection_in_a, + new Cast(iterator.get_value(), Type.STRING), + ((MapType) collection_in_a.get_target_type()).get_member_type() + ) + ) + ); + + extra_params.add(0, iterator.get_value()); + + while_body.add + ( + LambdaEvaluation.generate + ( + registers, + assembler, + lambda, + /* Can't put it in the target collection directly, since that may + * be a set. + */ + storage.get_address(), + extra_params + ) + ); + + while_body.add + ( + AddElement.generate + ( + registers, + assembler, + storage.get_value(), + collection_out, + to_set + ) + ); + + while_body.add + ( + new SetValue + ( + iterator.get_address(), + Operation.plus(iterator.get_value(), Constant.ONE) + ) + ); + + result.add + ( + While.generate + ( + registers, + assembler, + Operation.less_than + ( + iterator.get_value(), + collection_in_size.get_value() + ), + assembler.merge(while_body) + ) + ); + + registers.release(iterator, result); + registers.release(collection_in_size, result); + registers.release(collection_in_b_size, result); + registers.release(storage, result); + + return assembler.merge(result); + } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedPartitionLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedPartitionLambda.java new file mode 100644 index 0000000..8bd2c74 --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedPartitionLambda.java @@ -0,0 +1,177 @@ +package tonkadur.wyrd.v1.compiler.util; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; + +import tonkadur.wyrd.v1.lang.Register; + +import tonkadur.wyrd.v1.lang.type.Type; +import tonkadur.wyrd.v1.lang.type.MapType; + +import tonkadur.wyrd.v1.lang.meta.Instruction; +import tonkadur.wyrd.v1.lang.meta.Computation; + +import tonkadur.wyrd.v1.lang.computation.Cast; +import tonkadur.wyrd.v1.lang.computation.Constant; +import tonkadur.wyrd.v1.lang.computation.Operation; +import tonkadur.wyrd.v1.lang.computation.Address; +import tonkadur.wyrd.v1.lang.computation.RelativeAddress; +import tonkadur.wyrd.v1.lang.computation.ValueOf; +import tonkadur.wyrd.v1.lang.computation.Size; + +import tonkadur.wyrd.v1.lang.instruction.SetValue; + +import tonkadur.wyrd.v1.compiler.util.registers.RegisterManager; + +public class IndexedPartitionLambda +{ + /* Utility Class */ + private IndexedPartitionLambda () {} + + /* Uses Durstenfeld's shuffling algorithm */ + public static Instruction generate + ( + final RegisterManager registers, + final InstructionManager assembler, + final Computation lambda, + final Address collection_in, + final Address collection_out, + final boolean to_set, + final List<Computation> extra_params + ) + { + final List<Instruction> result, while_body, remove_instructions; + final Register iterator, index_storage, collection_size, storage; + final Computation iterator_target; + + result = new ArrayList<Instruction>(); + while_body = new ArrayList<Instruction>(); + remove_instructions = new ArrayList<Instruction>(); + + iterator = registers.reserve(Type.INT, result); + index_storage = registers.reserve(Type.INT, result); + collection_size = registers.reserve(Type.INT, result); + storage = registers.reserve(Type.BOOL, result); + + iterator_target = + new ValueOf + ( + new RelativeAddress + ( + collection_in, + new Cast(iterator.get_value(), Type.STRING), + ((MapType) collection_in.get_target_type()).get_member_type() + ) + ); + + result.add(new SetValue(iterator.get_address(), Constant.ZERO)); + result.add + ( + new SetValue(collection_size.get_address(), new Size(collection_in)) + ); + + extra_params.add(0, iterator_target); + extra_params.add(0, iterator.get_value()); + + remove_instructions.add + ( + AddElement.generate + ( + registers, + assembler, + iterator_target, + collection_out, + to_set + ) + ); + + remove_instructions.add + ( + new SetValue(index_storage.get_address(), iterator.get_value()) + ); + + remove_instructions.add + ( + RemoveAt.generate + ( + registers, + assembler, + index_storage.get_address(), + collection_size.get_value(), + collection_in + ) + ); + + remove_instructions.add + ( + new SetValue + ( + collection_size.get_address(), + Operation.minus(collection_size.get_value(), Constant.ONE) + ) + ); + + while_body.add + ( + LambdaEvaluation.generate + ( + registers, + assembler, + lambda, + /* Can't put it in the target collection directly, since that may + * be a set. + */ + storage.get_address(), + extra_params + ) + ); + + while_body.add + ( + IfElse.generate + ( + registers, + assembler, + Operation.not(storage.get_value()), + assembler.merge(remove_instructions), + new SetValue + ( + iterator.get_address(), + Operation.plus(iterator.get_value(), Constant.ONE) + ) + ) + ); + + while_body.add + ( + new SetValue + ( + iterator.get_address(), + Operation.plus(iterator.get_value(), Constant.ONE) + ) + ); + + result.add + ( + While.generate + ( + registers, + assembler, + Operation.less_than + ( + iterator.get_value(), + collection_size.get_value() + ), + assembler.merge(while_body) + ) + ); + + registers.release(iterator, result); + registers.release(index_storage, result); + registers.release(collection_size, result); + registers.release(storage, result); + + return assembler.merge(result); + } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/PopElement.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/PopElement.java new file mode 100644 index 0000000..9e30aee --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/PopElement.java @@ -0,0 +1,97 @@ +package tonkadur.wyrd.v1.compiler.util; + +import java.util.List; +import java.util.ArrayList; + +import tonkadur.wyrd.v1.lang.Register; + +import tonkadur.wyrd.v1.lang.type.Type; +import tonkadur.wyrd.v1.lang.type.PointerType; + +import tonkadur.wyrd.v1.lang.meta.Computation; +import tonkadur.wyrd.v1.lang.meta.Instruction; + +import tonkadur.wyrd.v1.lang.computation.Cast; +import tonkadur.wyrd.v1.lang.computation.Constant; +import tonkadur.wyrd.v1.lang.computation.Operation; +import tonkadur.wyrd.v1.lang.computation.Address; +import tonkadur.wyrd.v1.lang.computation.RelativeAddress; +import tonkadur.wyrd.v1.lang.computation.ValueOf; +import tonkadur.wyrd.v1.lang.computation.Size; + +import tonkadur.wyrd.v1.lang.instruction.SetValue; +import tonkadur.wyrd.v1.lang.instruction.Initialize; + +import tonkadur.wyrd.v1.compiler.util.registers.RegisterManager; + +public class PopElement +{ + /* Utility Class */ + private PopElement () {} + public static Instruction generate + ( + final RegisterManager registers, + final InstructionManager assembler, + final Address collection, + final Computation element_holder, + final boolean is_from_left + ) + { + final Register index, collection_size; + final List<Instruction> result; + final Computation target_index; + + result = new ArrayList<Instruction>(); + + index = registers.reserve(Type.INT, result); + collection_size = registers.reserve(Type.INT, result); + + result.add + ( + new SetValue(collection_size.get_address(), new Size(collection)) + ); + + + if (is_from_left) + { + target_index = Constant.ZERO; + } + else + { + target_index = collection_size.get_value(); + } + + result.add(new SetValue(index.get_address(), target_index)); + + result.add + ( + new SetValue + ( + element_holder, + new RelativeAddress + ( + collection, + target_index, + ((PointerType) element_holder.get_type()).get_target_type() + ) + ) + ); + + result.add + ( + RemoveAt.generate + ( + registers, + assembler, + index.get_address(), + collection_size.get_value(), + collection + ) + ); + + registers.release(collection_size, result); + registers.release(index, result); + + return assembler.merge(result); + } +} diff --git a/src/core/src/tonkadur/wyrd/v1/lang/instruction/SetValue.java b/src/core/src/tonkadur/wyrd/v1/lang/instruction/SetValue.java index 4b66fbe..ad0573a 100644 --- a/src/core/src/tonkadur/wyrd/v1/lang/instruction/SetValue.java +++ b/src/core/src/tonkadur/wyrd/v1/lang/instruction/SetValue.java @@ -11,21 +11,21 @@ public class SetValue extends Instruction /***************************************************************************/ /**** MEMBERS **************************************************************/ /***************************************************************************/ - protected final Address address; + protected final Computation address; protected final Computation value; /***************************************************************************/ /**** PUBLIC ***************************************************************/ /***************************************************************************/ /**** Constructors *********************************************************/ - public SetValue (final Address address, final Computation value) + public SetValue (final Computation address, final Computation value) { this.address = address; this.value = value; } /**** Accessors ************************************************************/ - public Address get_address () + public Computation get_address () { return address; } |


