summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-09-19 20:44:12 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-09-19 20:44:12 +0200
commit74b263f6b679a3b1ddda0ffb2fc6938efede0721 (patch)
treeba03bffabf2f5b5ad44a73a4809a95a8b974214b /src
parent23f55690f4e84262230fd684a509f6c8ea436ffe (diff)
...
Diffstat (limited to 'src')
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/IndexedFilterComputation.java137
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java178
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/IndexedPartitionComputation.java151
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/IndexedFilter.java131
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java156
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/IndexedPartition.java156
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java9
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java9
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateLexer.g47
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4260
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java323
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java290
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedFilterLambda.java164
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java190
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedPartitionLambda.java177
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/PopElement.java97
-rw-r--r--src/core/src/tonkadur/wyrd/v1/lang/instruction/SetValue.java6
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;
}