| summaryrefslogtreecommitdiff | 
diff options
4 files changed, 456 insertions, 5 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 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<Computation> params; +      final List<Instruction> result, while_body; +      final Register iterator, collection_in_size, storage; + +      params = new ArrayList<Computation>(); +      result = new ArrayList<Instruction>(); +      while_body = new ArrayList<Instruction>(); + +      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<Computation> params; +      final List<Instruction> result, while_body; +      final Register iterator, collection_in_size, storage; +      final Register collection_in_b_size; + +      params = new ArrayList<Computation>(); +      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() +            ) +         ) +      ); + +      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); +   } +} | 


