summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java54
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveElementsOf.java111
2 files changed, 165 insertions, 0 deletions
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 3d48b52..161acba 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
@@ -31,6 +31,7 @@ import tonkadur.wyrd.v1.compiler.util.Fold;
import tonkadur.wyrd.v1.compiler.util.FilterLambda;
import tonkadur.wyrd.v1.compiler.util.Shuffle;
import tonkadur.wyrd.v1.compiler.util.RemoveAt;
+import tonkadur.wyrd.v1.compiler.util.RemoveElementsOf;
import tonkadur.wyrd.v1.compiler.util.InsertAt;
import tonkadur.wyrd.v1.compiler.util.RemoveAllOf;
import tonkadur.wyrd.v1.compiler.util.IndexedMapLambda;
@@ -2106,6 +2107,59 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
}
@Override
+ public void visit_remove_elements_of
+ (
+ final tonkadur.fate.v1.lang.computation.RemoveElementsOfComputation n
+ )
+ throws Throwable
+ {
+ final ComputationCompiler collection_in_cc, 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();
+
+ collection_cc = new ComputationCompiler(compiler);
+
+ n.get_target_collection().get_visited_by(collection_cc);
+
+ if (collection_cc.has_init())
+ {
+ init_instructions.add(collection_cc.get_init());
+ }
+
+ init_instructions.add
+ (
+ new SetValue(result_as_address, collection_cc.get_computation())
+ );
+
+ collection_cc.release_registers(init_instructions);
+
+ collection_in_cc = new ComputationCompiler(compiler);
+
+ n.get_source_collection().get_visited_by(collection_in_cc);
+
+ assimilate(collection_in_cc);
+
+ init_instructions.add
+ (
+ RemoveElementsOf.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ collection_in_cc.get_address(),
+ result_as_address,
+ (
+ (tonkadur.fate.v1.lang.type.CollectionType)
+ n.get_target_collection().get_type()
+ ).is_set()
+ )
+ );
+ }
+
+ @Override
public void visit_add_elements_of
(
final tonkadur.fate.v1.lang.computation.AddElementsOfComputation n
diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveElementsOf.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveElementsOf.java
new file mode 100644
index 0000000..93a8829
--- /dev/null
+++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveElementsOf.java
@@ -0,0 +1,111 @@
+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.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 RemoveElementsOf
+{
+ /* Utility Class */
+ private RemoveElementsOf () {}
+
+ /* Uses Durstenfeld's shuffling algorithm */
+ public static Instruction generate
+ (
+ final RegisterManager registers,
+ final InstructionManager assembler,
+ final Address collection_in,
+ final Address collection,
+ final boolean is_set
+ )
+ {
+ final List<Instruction> result, while_body;
+ final Register iterator, collection_in_size;
+
+ result = new ArrayList<Instruction>();
+ while_body = new ArrayList<Instruction>();
+
+ iterator = registers.reserve(Type.INT, result);
+ collection_in_size = registers.reserve(Type.INT, result);
+
+ result.add(new SetValue(iterator.get_address(), Constant.ZERO));
+ result.add
+ (
+ new SetValue
+ (
+ collection_in_size.get_address(),
+ new Size(collection_in)
+ )
+ );
+
+ while_body.add
+ (
+ RemoveOneOf.generate
+ (
+ registers,
+ assembler,
+ new ValueOf
+ (
+ new RelativeAddress
+ (
+ collection_in,
+ new Cast(iterator.get_value(), Type.STRING),
+ (
+ (MapType) collection_in.get_target_type()
+ ).get_member_type()
+ )
+ ),
+ collection,
+ is_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);
+
+ return assembler.merge(result);
+ }
+}