From 3821bf0f0c7276eb0fbe8e7cf27c41531d4dd381 Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Wed, 16 Sep 2020 12:35:30 +0200 Subject: ... --- .../v1/compiler/fate/v1/ComputationCompiler.java | 83 ++++++++- .../v1/compiler/fate/v1/InstructionCompiler.java | 50 +++++- .../wyrd/v1/compiler/util/IndexedMapLambda.java | 142 ++++++++++++++++ .../wyrd/v1/compiler/util/MergeLambda.java | 186 +++++++++++++++++++++ 4 files changed, 456 insertions(+), 5 deletions(-) create mode 100644 src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMapLambda.java create mode 100644 src/core/src/tonkadur/wyrd/v1/compiler/util/MergeLambda.java 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 2e595cd..d3347c8 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,7 +31,9 @@ import tonkadur.wyrd.v1.compiler.util.Shuffle; import tonkadur.wyrd.v1.compiler.util.RemoveAt; 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.MapLambda; +import tonkadur.wyrd.v1.compiler.util.MergeLambda; import tonkadur.wyrd.v1.compiler.util.RemoveOneOf; import tonkadur.wyrd.v1.compiler.util.ReverseList; import tonkadur.wyrd.v1.compiler.util.CreateCons; @@ -2113,7 +2115,7 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor default_cc = new ComputationCompiler(compiler); - n.get_default().get_visited_by(default_cc); + n.get_initial_value().get_visited_by(default_cc); if (default_cc.has_init()) { @@ -2125,7 +2127,7 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor new SetValue(result_as_address, default_cc.get_computation()) ); - default_cc.release_registers(init_instructions()); + default_cc.release_registers(init_instructions); lambda_cc = new ComputationCompiler(compiler); @@ -2557,7 +2559,46 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor ) throws Throwable { - /* TODO */ + 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(); + + 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 + ( + MergeLambda.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() + ) + ); } @Override @@ -2607,7 +2648,41 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor ) throws Throwable { - /* TODO */ + 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(); + + 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); + + assimilate(in_collection_cc); + + init_instructions.add + ( + IndexedMapLambda.generate + ( + compiler.registers(), + compiler.assembler(), + lambda_cc.get_computation(), + in_collection_cc.get_address(), + result_as_address, + ( + (tonkadur.fate.v1.lang.type.CollectionType) + n.get_collection().get_type() + ).is_set() + ) + ); } @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 931a8ca..b6fd8bf 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 @@ -52,6 +52,7 @@ import tonkadur.wyrd.v1.compiler.util.While; 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.IndexedMapLambda; import tonkadur.wyrd.v1.compiler.util.IterativeSearch; import tonkadur.wyrd.v1.compiler.util.RemoveAllOf; import tonkadur.wyrd.v1.compiler.util.RemoveOneOf; @@ -604,7 +605,54 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor ) throws Throwable { - /* TODO */ + final ComputationCompiler lambda_cc, in_collection_cc, out_collection_cc; + + 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()); + } + + in_collection_cc = new ComputationCompiler(compiler); + + n.get_collection_in().get_visited_by(in_collection_cc); + + if (in_collection_cc.has_init()) + { + result.add(in_collection_cc.get_init()); + } + + out_collection_cc = new ComputationCompiler(compiler); + + n.get_collection_out().get_visited_by(out_collection_cc); + + if (out_collection_cc.has_init()) + { + result.add(out_collection_cc.get_init()); + } + + result.add + ( + IndexedMapLambda.generate + ( + compiler.registers(), + compiler.assembler(), + lambda_cc.get_computation(), + in_collection_cc.get_address(), + out_collection_cc.get_address(), + ( + (tonkadur.fate.v1.lang.type.CollectionType) + n.get_collection_out().get_type() + ).is_set() + ) + ); + + lambda_cc.release_registers(result); + in_collection_cc.release_registers(result); + out_collection_cc.release_registers(result); } @Override diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMapLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMapLambda.java new file mode 100644 index 0000000..1ff80d1 --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMapLambda.java @@ -0,0 +1,142 @@ +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 IndexedMapLambda +{ + /* Utility Class */ + private IndexedMapLambda () {} + + /* 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 params; + final List result, while_body; + final Register iterator, collection_in_size, storage; + + params = new ArrayList(); + result = new ArrayList(); + while_body = new ArrayList(); + + iterator = registers.reserve(Type.INT, result); + collection_in_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) + ) + ); + + params.add(iterator.get_value()); + + params.add + ( + new ValueOf + ( + new RelativeAddress + ( + collection_in, + new Cast(iterator.get_value(), Type.STRING), + ((MapType) collection_in.get_target_type()).get_member_type() + ) + ) + ); + + 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(), + 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(storage, result); + + return assembler.merge(result); + } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/MergeLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/MergeLambda.java new file mode 100644 index 0000000..f17cf02 --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/MergeLambda.java @@ -0,0 +1,186 @@ +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 MergeLambda +{ + /* Utility Class */ + private MergeLambda () {} + + /* 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 params; + final List result, while_body; + final Register iterator, collection_in_size, storage; + final Register collection_in_b_size; + + params = new ArrayList(); + result = new ArrayList(); + while_body = new ArrayList(); + + 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() + ) + ) + ); + + params.add + ( + new ValueOf + ( + new RelativeAddress + ( + collection_in_a, + new Cast(iterator.get_value(), Type.STRING), + ((MapType) collection_in_a.get_target_type()).get_member_type() + ) + ) + ); + + params.add + ( + new ValueOf + ( + new RelativeAddress + ( + collection_in_b, + new Cast(iterator.get_value(), Type.STRING), + ((MapType) collection_in_b.get_target_type()).get_member_type() + ) + ) + ); + + 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(), + 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); + } +} -- cgit v1.2.3-70-g09d2