| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-09-19 16:32:42 +0200 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-09-19 16:32:42 +0200 | 
| commit | 23f55690f4e84262230fd684a509f6c8ea436ffe (patch) | |
| tree | c478c3168aef0868fb9bd46ddaf3f390d62e33a3 /src/core | |
| parent | 63b3c43af5d402530a8c10c1f71aa0e7ca3aa06f (diff) | |
...
Diffstat (limited to 'src/core')
4 files changed, 423 insertions, 7 deletions
| diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index f4a3d12..1289a9e 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -1784,7 +1784,6 @@ returns [List<Cons<Computation, Instruction>> result]  @init  {     $result = new ArrayList<Cons<Computation, Instruction>>(); -   /* TODO: resolve grammar collisions */  }  :     ( @@ -1929,7 +1928,7 @@ returns [Instruction result]     }     | FOR_EACH_KW -      value_reference WS+ new_reference_name +      non_text_value WS+ new_reference_name        {           final Map<String, Variable> variable_map;           final Variable new_variable; @@ -1938,7 +1937,7 @@ returns [Instruction result]           elem_type = Type.ANY; -         collection_type = ($value_reference.result).get_type(); +         collection_type = ($non_text_value.result).get_type();           if (collection_type instanceof CollectionType)           { @@ -2016,7 +2015,7 @@ returns [Instruction result]                 ($FOR_EACH_KW.getLine()),                 ($FOR_EACH_KW.getCharPositionInLine())              ), -            ($value_reference.result), +            ($non_text_value.result),              ($new_reference_name.result),              ($player_choice_list.result)           ); 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 487554e..767724a 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 @@ -35,6 +35,7 @@ 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; +import tonkadur.wyrd.v1.compiler.util.PartitionLambda;  import tonkadur.wyrd.v1.compiler.util.MapLambda;  import tonkadur.wyrd.v1.compiler.util.MergeLambda;  import tonkadur.wyrd.v1.compiler.util.RemoveOneOf; @@ -2804,7 +2805,98 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO */ +      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 +      ( +         PartitionLambda.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 @@ -2870,6 +2962,11 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor           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 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 a0a5810..9cd5d43 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 @@ -55,6 +55,7 @@ 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.MergeLambda; +import tonkadur.wyrd.v1.compiler.util.PartitionLambda;  import tonkadur.wyrd.v1.compiler.util.IndexedMapLambda;  import tonkadur.wyrd.v1.compiler.util.IterativeSearch;  import tonkadur.wyrd.v1.compiler.util.RemoveAllOf; @@ -749,7 +750,90 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor     )     throws Throwable     { -      /* TODO */ +      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 +      ( +         PartitionLambda.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 @@ -769,7 +853,67 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor     )     throws Throwable     { -      /* TODO */ +      final ComputationCompiler address_compiler, element_compiler; +      final Register collection_size, index; + +      address_compiler = new ComputationCompiler(compiler); +      element_compiler = new ComputationCompiler(compiler); + +      n.get_collection().get_visited_by(address_compiler); + +      if (address_compiler.has_init()) +      { +         result.add(address_compiler.get_init()); +      } + +      address_compiler.release_registers(result); + +      n.get_element().get_visited_by(element_compiler); + +      if (element_compiler.has_init()) +      { +         result.add(element_compiler.get_init()); +      } + +      collection_size = compiler.registers().reserve(Type.INT, result); +      index = compiler.registers().reserve(Type.INT, result); + +      result.add +      ( +         new SetValue +         ( +            collection_size.get_address(), +            new Size(address_compiler.get_address()) +         ) +      ); + +      result.add +      ( +         new SetValue +         ( +            index.get_address(), +            (n.is_from_left() ? Constant.ZERO : collection_size.get_value()) +         ) +      ); + +      result.add +      ( +         InsertAt.generate +         ( +            compiler.registers(), +            compiler.assembler(), +            index.get_address(), +            element_compiler.get_computation(), +            collection_size.get_value(), +            address_compiler.get_address() +         ) +      ); + +      address_compiler.release_registers(result); +      element_compiler.release_registers(result); + +      compiler.registers().release(collection_size, result); +      compiler.registers().release(index, result);     }     @Override diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/PartitionLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/PartitionLambda.java new file mode 100644 index 0000000..706aee2 --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/PartitionLambda.java @@ -0,0 +1,176 @@ +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 PartitionLambda +{ +   /* Utility Class */ +   private PartitionLambda () {} + +   /* 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); + +      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); +   } +} | 


