| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src/core')
6 files changed, 871 insertions, 79 deletions
| 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 0f24995..d9162bd 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 @@ -132,13 +132,7 @@ public class InstructionCompiler extends FateVisitor         * <binary_search .anon0 collection .found .index>         * (ifelse (var .found)         *    (nop) -       *    (set .end (size collection)) -       * -       *    (while (> .index .end) -       *       (set .next (- (val .end) 1)) -       *       (set collection[.index] collection[.next]) -       *       (set .end (val .next)) -       *    ) +       *    <insert_at ...>         * )         */        final Ref element_as_ref, collection_as_ref, collection_size_as_ref; @@ -414,6 +408,11 @@ public class InstructionCompiler extends FateVisitor     public void visit_assert (final tonkadur.fate.v1.lang.instruction.Assert a)     throws Throwable     { +      /* +       * Fate: (assert Computation) +       * +       * Wyrd: (assert Computation) +       */        final ComputationCompiler cc;        cc = new_computation_compiler(); @@ -430,6 +429,12 @@ public class InstructionCompiler extends FateVisitor     public void visit_clear (final tonkadur.fate.v1.lang.instruction.Clear c)     throws Throwable     { +      /* +       * Fate: (clear collection) +       * +       * Wyrd: +       *    <clear collection> +       */        final ComputationCompiler reference_compiler;        final Ref iterator, collection_ref;        final List<Instruction> while_body; @@ -497,6 +502,26 @@ public class InstructionCompiler extends FateVisitor     )     throws Throwable     { +      /* +       * Fate: +       *    (cond +       *       (c0 i0) +       *       (... ...) +       *       (cn in) +       *    ) +       * +       * Wyrd: +       *    (ifelse c0 +       *       i0 +       *       (ifelse ... +       *          ... +       *          (ifelse cn +       *             in +       *             (nop) +       *          ) +       *       ) +       *    ) +       */        InstructionCompiler ic;        ComputationCompiler cc;        List<Instruction> previous_else_branch; @@ -546,6 +571,11 @@ public class InstructionCompiler extends FateVisitor     public void visit_display (final tonkadur.fate.v1.lang.instruction.Display n)     throws Throwable     { +      /* +       * Fate: (display Computation) +       * +       * Wyrd: (display Computation) +       */        final ComputationCompiler cc;        cc = new_computation_compiler(); @@ -565,6 +595,11 @@ public class InstructionCompiler extends FateVisitor     )     throws Throwable     { +      /* +       * Fate: (event_call <string> c0 ... cn) +       * +       * Wyrd (event_call <string> c0 ... cn) +       */        final List<ComputationCompiler> cc_list;        final List<Computation> parameters; @@ -607,6 +642,11 @@ public class InstructionCompiler extends FateVisitor     )     throws Throwable     { +      /* +       * Fate: (ifelse c0 i0 i1) +       * +       * Wyrd (ifelse c0 i0 i1) +       */        final ComputationCompiler cc;        final InstructionCompiler if_true_ic;        final InstructionCompiler if_false_ic; @@ -640,6 +680,11 @@ public class InstructionCompiler extends FateVisitor     )     throws Throwable     { +      /* +       * Fate: (ifelse c0 i0 i1) +       * +       * Wyrd (ifelse c0 i0 (nop)) +       */        final ComputationCompiler cc;        final InstructionCompiler if_true_ic; @@ -670,6 +715,11 @@ public class InstructionCompiler extends FateVisitor     )     throws Throwable     { +      /* +       * Fate: i0 ... in +       * +       * Wyrd i0 ... in +       */        for        (           final tonkadur.fate.v1.lang.meta.Instruction fate_instruction: @@ -693,6 +743,11 @@ public class InstructionCompiler extends FateVisitor     )     throws Throwable     { +      /* +       * Fate: (macro <string> c0 ... cn) +       * +       * Wyrd <content of macro with c0 ... cn> +       */        final tonkadur.fate.v1.lang.meta.Instruction fate_macro_root;        final List<ComputationCompiler> cc_list;        final List<Computation> parameters; @@ -738,6 +793,11 @@ public class InstructionCompiler extends FateVisitor     )     throws Throwable     { +      /* +       * Fate: (player_choice label i0) +       * +       * Wyrd (add_choice label i0) +       */        final ComputationCompiler cc;        final InstructionCompiler ic; @@ -769,6 +829,15 @@ public class InstructionCompiler extends FateVisitor     )     throws Throwable     { +      /* +       * Fate: (player_choice_list i0 ... in) +       * +       * Wyrd: +       *    i0 +       *    ... +       *    in +       *    (resolve_choices) +       */        for        (           final tonkadur.fate.v1.lang.meta.Instruction fate_instruction: diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/BinarySearch.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/BinarySearch.java index 8e2f926..f16537f 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/BinarySearch.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/BinarySearch.java @@ -7,6 +7,7 @@ import java.util.Collections;  import tonkadur.wyrd.v1.lang.type.Type;  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; @@ -22,64 +23,82 @@ import tonkadur.wyrd.v1.lang.instruction.While;  public class BinarySearch  { + +   /* Utility Class */ +   private BinarySearch () {} +     /* -      (set .found false) -      (declare_variable local int .top) -      (set .top (- (size collection) 1)) -      (declare_variable local int .bot) -      (set .bot 0) -      (declare_variable local int .mid) -      (declare_variable local <element.type> .midval) -      (while (and (not (var .found)) (<= (variable .bot) (variable .top))) -         (set .mid -            (+ -               (variable .bot) -               (cast float int -                  (/ -                     (cast int float (- (variable .top) (variable .bot))) -                     2.0 -                  ) -               ) -            ) -         ) -         (set .midval -            (value_of -               (relative_ref collection ( (cast int string .mid) )) -            ) -         ) -         (ifelse (< (variable .midval) (variable .anon1)) -            (set .bot (+ (var .mid) 1)) -            (ifelse (> (var .midval) (variable .anon1)) -               (set .top (- (var .mid) 1)) -               (set .found true) -            ) -         ) -      ) -   */ +    * (Computation <E> element) +    * (declare_variable global <List E> collection) +    * (Computation int collection_size) +    * (declare_variable global boolean result_found) +    * (declare_variable global index result_index) +    * +    * (declare_variable int .bot) +    * (declare_variable int .top) +    * (declare_variable <E> .midval) +    * +    * (set result_found false) +    * (set .bot 0) +    * (set .top (- collection_size 1)) +    * +    * (while (and (not (var result_found)) (<= (var .bot) (var .top))) +    *    (set result_index +    *       (+ +    *          (var .bot) +    *          (cast int +    *             (/ +    *                (cast float +    *                   (- (var .top) (var .bot)) +    *                ) +    *                2.0 +    *             ) +    *          ) +    *       ) +    *    ) +    *    (set .midval (var collection[.result_index])) +    *    (ifelse (< (var .midval) element) +    *       (set .bot (+ (var result_index) 1)) +    *       (ifelse (> (var .midval) element) +    *          (set .top (- (var result_index) 1)) +    *          (set result_found true) +    *       ) +    *    ) +    * ) +    */     public static List<Instruction> generate     (        final AnonymousVariableManager anonymous_variables, -      final Ref target, +      final Computation target,        final Ref collection, -      final Ref collection_size_or_null, -      final Ref result_was_found_holder, -      final Ref result_index_holder +      final Computation collection_size, +      final Ref result_was_found, +      final Ref result_index     )     {        final List<Instruction> result, while_body; -      final Ref top, bot, midval; +      final Ref bot, top, midval;        final Type element_type; +      final Computation value_of_result_index; +      final Computation value_of_bot, value_of_top, value_of_midval;        result = new ArrayList<Instruction>();        while_body = new ArrayList<Instruction>();        element_type = target.get_type(); -      top = anonymous_variables.reserve(Type.INT);        bot = anonymous_variables.reserve(Type.INT); +      top = anonymous_variables.reserve(Type.INT);        midval = anonymous_variables.reserve(element_type); -      result.add(new SetValue(result_was_found_holder, Constant.FALSE)); +      value_of_result_index = new ValueOf(result_index); + +      value_of_bot = new ValueOf(bot); +      value_of_top = new ValueOf(top); +      value_of_midval = new ValueOf(midval); + +      result.add(new SetValue(result_was_found, Constant.FALSE)); +      result.add(new SetValue(bot, new Constant(Type.INT, "0")));        result.add        (           new SetValue @@ -87,38 +106,42 @@ public class BinarySearch              top,              Operation.minus              ( -               ( -                  (collection_size_or_null == null) ? -                  new Size(collection) : new ValueOf(collection_size_or_null) -               ), +               collection_size,                 new Constant(Type.INT, "1")              )           )        ); -      result.add -      ( -         new SetValue(bot, new Constant(Type.INT, "0")) -      ); +      /* +       *    (set result_index +       *       (+ +       *          (var .bot) +       *          (cast int +       *             (/ +       *                (cast float +       *                   (- (var .top) (var .bot)) +       *                ) +       *                2.0 +       *             ) +       *          ) +       *       ) +       *    ) +       */        while_body.add        (           new SetValue           ( -            result_index_holder, +            result_index,              Operation.plus              ( -               new ValueOf(bot), +               value_of_bot,                 new Cast                 (                    Operation.divide                    (                       new Cast                       ( -                        Operation.minus -                        ( -                           new ValueOf(top), -                           new ValueOf(bot) -                        ), +                        Operation.minus(value_of_top, value_of_bot),                          Type.FLOAT                       ),                       new Constant(Type.FLOAT, "2.0") @@ -128,6 +151,8 @@ public class BinarySearch              )           )        ); + +      /* (set .midval (var collection[.result_index])) */        while_body.add        (           new SetValue @@ -140,18 +165,28 @@ public class BinarySearch                    collection,                    Collections.singletonList                    ( -                     new Cast(new ValueOf(result_index_holder), Type.STRING) +                     new Cast(value_of_result_index, Type.STRING)                    ),                    element_type                 )              )           )        ); + +      /* +       *    (ifelse (< (var .midval) element) +       *       (set .bot (+ (var result_index) 1)) +       *       (ifelse (> (var .midval) element) +       *          (set .top (- (var result_index) 1)) +       *          (set result_found true) +       *       ) +       *    ) +       */        while_body.add        (           new IfElseInstruction           ( -            Operation.less_than(new ValueOf(midval), new ValueOf(target)), +            Operation.less_than(value_of_midval, target),              Collections.singletonList              (                 new SetValue @@ -159,7 +194,7 @@ public class BinarySearch                    bot,                    Operation.plus                    ( -                     new ValueOf(result_index_holder), +                     value_of_result_index,                       new Constant(Type.INT, "1")                    )                 ) @@ -168,11 +203,7 @@ public class BinarySearch              (                 new IfElseInstruction                 ( -                  Operation.greater_than -                  ( -                     new ValueOf(midval), -                     new ValueOf(target) -                  ), +                  Operation.greater_than(value_of_midval, target),                    Collections.singletonList                    (                       new SetValue @@ -180,14 +211,14 @@ public class BinarySearch                          top,                          Operation.minus                          ( -                           new ValueOf(result_index_holder), +                           value_of_result_index,                             new Constant(Type.INT, "1")                          )                       )                    ),                    Collections.singletonList                    ( -                     new SetValue(result_was_found_holder, Constant.TRUE) +                     new SetValue(result_was_found, Constant.TRUE)                    )                 )              ) @@ -200,19 +231,15 @@ public class BinarySearch           (              Operation.and              ( -               Operation.not(new ValueOf(result_was_found_holder)), -               Operation.less_equal_than -               ( -                  new ValueOf(bot), -                  new ValueOf(top) -               ) +               Operation.not(new ValueOf(result_was_found)), +               Operation.less_equal_than(value_of_bot, value_of_top)              ),              while_body           )        ); -      anonymous_variables.release(top);        anonymous_variables.release(bot); +      anonymous_variables.release(top);        anonymous_variables.release(midval);        return result; diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/InsertAt.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/InsertAt.java new file mode 100644 index 0000000..46369e2 --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/InsertAt.java @@ -0,0 +1,153 @@ +package tonkadur.wyrd.v1.compiler.util; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; + +import tonkadur.wyrd.v1.lang.type.Type; + +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.Ref; +import tonkadur.wyrd.v1.lang.computation.RelativeRef; +import tonkadur.wyrd.v1.lang.computation.ValueOf; + +import tonkadur.wyrd.v1.lang.instruction.IfElseInstruction; +import tonkadur.wyrd.v1.lang.instruction.SetValue; +import tonkadur.wyrd.v1.lang.instruction.While; + +public class InsertAt +{ +   /* Utility Class */ +   private InsertAt () {} + +   /* +    * (declare_variable global int index) +    * (Computation <E> element) +    * (Computation <int> collection_size) +    * (declare_variable global <List E> collection) +    * +    * (declare_variable int .prev) +    * (declare_variable int .end) +    * +    * (set .end collection_size) +    * +    * (while (> .index .end) +    *    (set .prev (- (val .collection_size) 1)) +    *    (set collection[.end] (val collection[.prev])) +    *    (set .end (val .prev)) +    * ) +    * +    * (set collection[.index] element) +   */ +   public static List<Instruction> generate +   ( +      final AnonymousVariableManager anonymous_variables, +      final Ref index, +      final Computation element, +      final Computation collection_size, +      final Ref collection +   ) +   { +      final List<Instruction> result, while_body; +      final Type element_type; +      final Ref prev, end; +      final Computation value_of_prev, value_of_index, value_of_end; + +      result = new ArrayList<Instruction>(); +      while_body = new ArrayList<Instruction>(); + +      element_type = element.get_type(); + +      prev = anonymous_variables.reserve(Type.INT); +      end = anonymous_variables.reserve(Type.INT); + +      value_of_prev = new ValueOf(prev); +      value_of_index = new ValueOf(index); +      value_of_end = new ValueOf(end); + +      /* (set .end collection_size) */ +      result.add(new SetValue(end, collection_size)); + +      /* (set .prev (- (val .end) 1)) */ +      while_body.add +      ( +         new SetValue +         ( +            prev, +            Operation.minus(value_of_end, new Constant(Type.INT, "1")) +         ) +      ); + +      /* (set collection[.end] (val collection[.prev])) */ +      while_body.add +      ( +         new SetValue +         ( +            new RelativeRef +            ( +               collection, +               Collections.singletonList +               ( +                  new Cast(value_of_end, Type.STRING) +               ), +               element_type +            ), +            new ValueOf +            ( +               new RelativeRef +               ( +                  collection, +                  Collections.singletonList +                  ( +                     new Cast(value_of_prev, Type.STRING) +                  ), +                  element_type +               ) +            ) +         ) +      ); + +      /* (set .end (val .prev)) */ +      while_body.add(new SetValue(end, value_of_prev)); + +      /* +       * (while (> .index .end) +       *    (set .prev (- (val .collection_size) 1)) +       *    (set collection[.end] (val collection[.prev])) +       *    (set .end (val .prev)) +       * ) +       */ +      result.add +      ( +         new While(Operation.minus(value_of_index, value_of_end), while_body) +      ); + +      /* (set collection[.index] element) */ +      result.add +      ( +         new SetValue +         ( +            new RelativeRef +            ( +               collection, +               Collections.singletonList +               ( +                  new Cast(value_of_index, Type.STRING) +               ), +               element_type +            ), +            element +         ) +      ); + +      anonymous_variables.release(end); +      anonymous_variables.release(prev); + +      return result; +   } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/IterativeSearch.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/IterativeSearch.java new file mode 100644 index 0000000..aa62bbd --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/IterativeSearch.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.type.Type; + +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.Ref; +import tonkadur.wyrd.v1.lang.computation.RelativeRef; +import tonkadur.wyrd.v1.lang.computation.ValueOf; + +import tonkadur.wyrd.v1.lang.instruction.IfElseInstruction; +import tonkadur.wyrd.v1.lang.instruction.SetValue; +import tonkadur.wyrd.v1.lang.instruction.While; + +public class IterativeSearch +{ + +   /* Utility Class */ +   private IterativeSearch () {} + +   /* +    * (Computation <E> target) +    * (declare_variable global <List E> collection) +    * (Computation int collection_size) +    * (declare_variable global boolean result_found) +    * (declare_variable global index result_index) +    * +    * (set result_found false) +    * (set result_index (- collection_size 1)) +    * +    * (while +    *    (and +    *       (not (var result_found)) +    *       (>= (var result_index) 0) +    *    ) +    *    (ifelse (= (var collection[result_index]) target) +    *       (set result_found true) +    *       (set result_index (- (var result_index) 1)) +    *    ) +    * ) +    */ +   public static List<Instruction> generate +   ( +      final AnonymousVariableManager anonymous_variables, +      final Computation target, +      final Ref collection, +      final Computation collection_size, +      final Ref result_was_found, +      final Ref result_index +   ) +   { +      final List<Instruction> result; +      final Type target_type; +      final Computation value_of_result_index; + +      result = new ArrayList<Instruction>(); + +      target_type = target.get_type(); + +      value_of_result_index = new ValueOf(result_index); + +      result.add(new SetValue(result_was_found, Constant.FALSE)); +      result.add +      ( +         new SetValue +         ( +            result_index, +            Operation.minus(collection_size, new Constant(Type.INT, "0")) +         ) +      ); + +      result.add +      ( +         new While +         ( +            Operation.and +            ( +               Operation.not(new ValueOf(result_was_found)), +               Operation.greater_equal_than +               ( +                  value_of_result_index, +                  new Constant(Type.INT, "0") +               ) +            ), +            Collections.singletonList +            ( +               /* +                * (ifelse (= (var collection[result_index]) target) +                *    (set result_found true) +                *    (set result_index (- (var result_index) 1)) +                * ) +                */ +               new IfElseInstruction +               ( +                  Operation.equals +                  ( +                     new ValueOf +                     ( +                        new RelativeRef +                        ( +                           collection, +                           Collections.singletonList +                           ( +                              new Cast(value_of_result_index, Type.STRING) +                           ), +                           target_type +                        ) +                     ), +                     target +                  ), +                  Collections.singletonList +                  ( +                     new SetValue(result_was_found, Constant.TRUE) +                  ), +                  Collections.singletonList +                  ( +                     new SetValue +                     ( +                        result_index, +                        Operation.minus +                        ( +                           value_of_result_index, +                           new Constant(Type.INT, "1") +                        ) +                     ) +                  ) +               ) +            ) +         ) +      ); + +      return result; +   } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAll.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAll.java new file mode 100644 index 0000000..699f18d --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAll.java @@ -0,0 +1,250 @@ +package tonkadur.wyrd.v1.compiler.util; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; + +import tonkadur.wyrd.v1.lang.type.Type; + +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.Ref; +import tonkadur.wyrd.v1.lang.computation.RelativeRef; +import tonkadur.wyrd.v1.lang.computation.ValueOf; + +import tonkadur.wyrd.v1.lang.instruction.IfElseInstruction; +import tonkadur.wyrd.v1.lang.instruction.NOP; +import tonkadur.wyrd.v1.lang.instruction.Remove; +import tonkadur.wyrd.v1.lang.instruction.SetValue; +import tonkadur.wyrd.v1.lang.instruction.While; + +public class RemoveAll +{ +   /* Utility Class */ +   private RemoveAll () {} + +   /* +    * (Computation <E> element) +    * (Computation <int> collection_size) +    * (declare_variable global <List E> collection) +    * +    * (declare_variable int .end) +    * (declare_variable int .index) +    * (declare_variable int .found) +    * +    * (set .index 0) +    * (set .found 0) +    * (set .end (- collection_size 1)) +    * +    * (while (< (var .index) (var .end)) +    *    ;; while_body0 +    *    (ifelse (= (var .found) 0) +    *       ( +    *          (nop) +    *       ) +    *       ( +    *          (ifelse (= element (var collection[.index])) +    *             ( +    *                ;; if_false_true_body +    *                (set .found (+ (var .found) 1)) +    *                (set .end (- (var .end) 1)) +    *             ) +    *             (nop) +    *          ) +    *          (set +    *             collection[.index] +    *             (var collection[(+ (var .index) (var .found))]) +    *          ) +    *       ) +    *    ) +    *    (set index ((val .index) + 1)) +    * ) +    * +    * (while (> (var .found) 0) +    *    ;; while_body1 +    *    (remove collection[(+ (var .end) (var .found))]) +    *    (set .found (- (var .found) 1)) +    * ) +    */ +   public static List<Instruction> generate +   ( +      final AnonymousVariableManager anonymous_variables, +      final Computation element, +      final Computation collection_size, +      final Ref collection +   ) +   { +      final List<Instruction> result; +      final List<Instruction> while_body0, while_body1, if_false_body; +      final List<Instruction> if_false_true_body; +      final List<Instruction> nop_branch; +      final Type element_type; +      final Ref index, found, end; +      final Computation value_of_index, value_of_found, value_of_end; +      final Computation const_0, const_1; +      final Ref collection_at_index; + +      result = new ArrayList<Instruction>(); + +      while_body0 = new ArrayList<Instruction>(); +      while_body1 = new ArrayList<Instruction>(); +      if_false_body = new ArrayList<Instruction>(); +      if_false_true_body = new ArrayList<Instruction>(); + +      nop_branch = Collections.singletonList(new NOP()); + +      element_type = element.get_type(); + +      index = anonymous_variables.reserve(Type.INT); +      found = anonymous_variables.reserve(Type.INT); +      end = anonymous_variables.reserve(Type.INT); + +      value_of_index = new ValueOf(index); +      value_of_found = new ValueOf(found); +      value_of_end = new ValueOf(end); + +      const_0 = new Constant(Type.INT, "0"); +      const_1 = new Constant(Type.INT, "1"); + +      collection_at_index = +         new RelativeRef +         ( +            collection, +            Collections.singletonList +            ( +               new Cast(value_of_index, Type.STRING) +            ), +            element_type +         ); + +      /* (set .index 0) */ +      result.add(new SetValue(index, const_0)); +      /* (set .found 0) */ +      result.add(new SetValue(found, const_0)); + +      /* (set .end (- (collection_size) 1) */ +      result.add +      ( +         new SetValue(end, Operation.minus(collection_size, const_1)) +      ); + +      /* +       * ( +       *    (set .found (+ (var .found) 1)) +       *    (set .end (- (var .end) 1)) +       * ) +       */ +      if_false_true_body.add +      ( +         new SetValue(found, Operation.plus(value_of_found, const_1)) +      ); +      if_false_true_body.add +      ( +         new SetValue(found, Operation.minus(value_of_found, const_1)) +      ); + +      if_false_body.add +      ( +         new IfElseInstruction +         ( +            Operation.equals(element, new ValueOf(collection_at_index)), +            if_false_true_body, +            nop_branch +         ) +      ); + +      /* +       * (set +       *    collection[.index] +       *    (var collection[(+ (var .index) (var .found))]) +       * ) +       */ +      if_false_body.add +      ( +         new SetValue +         ( +            collection_at_index, +            new RelativeRef +            ( +               collection, +               Collections.singletonList +               ( +                  new Cast +                  ( +                     Operation.plus(value_of_index, value_of_found), +                     Type.STRING +                  ) +               ), +               element_type +            ) +         ) +      ); + +      while_body0.add +      ( +         new IfElseInstruction +         ( +            Operation.equals(value_of_found, const_0), +            nop_branch, +            if_false_body +         ) +      ); + +      while_body0.add +      ( +         new SetValue(index, Operation.plus(value_of_index, const_1)) +      ); + +      result.add +      ( +         new While +         ( +            Operation.less_than(value_of_index, value_of_end), +            while_body0 +         ) +      ); + +      while_body1.add +      ( +         new Remove +         ( +            new RelativeRef +            ( +               collection, +               Collections.singletonList +               ( +                  new Cast +                  ( +                     Operation.plus(value_of_end, value_of_found), +                     Type.STRING +                  ) +               ), +               element_type +            ) +         ) +      ); +      while_body1.add +      ( +         new SetValue(found, Operation.minus(value_of_found, const_1)) +      ); + +      result.add +      ( +         new While +         ( +            Operation.less_than(value_of_found, const_0), +            while_body1 +         ) +      ); + +      anonymous_variables.release(index); +      anonymous_variables.release(found); +      anonymous_variables.release(end); + +      return result; +   } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAt.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAt.java new file mode 100644 index 0000000..2ec46cd --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAt.java @@ -0,0 +1,151 @@ +package tonkadur.wyrd.v1.compiler.util; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; + +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.Ref; +import tonkadur.wyrd.v1.lang.computation.RelativeRef; +import tonkadur.wyrd.v1.lang.computation.ValueOf; + +import tonkadur.wyrd.v1.lang.instruction.IfElseInstruction; +import tonkadur.wyrd.v1.lang.instruction.SetValue; +import tonkadur.wyrd.v1.lang.instruction.While; +import tonkadur.wyrd.v1.lang.instruction.Remove; + +public class RemoveAt +{ +   /* Utility Class */ +   private RemoveAt () {} + +   /* +    * (declare_variable global int index) +    * (Computation int collection_size) +    * (declare_variable global <List E> collection) +    * +    * (declare_variable int .next) +    * (declare_variable int .end) +    * +    * (set .end (- (collection_size) 1)) +    * +    * (while (< (var index) (var .end)) +    *    (set .next (+ (val index) 1)) +    *    (set collection[index] (val collection[.next])) +    *    (set index (val .next)) +    * ) +    * +    * (remove collection[index]) +    */ +   public static List<Instruction> generate +   ( +      final AnonymousVariableManager anonymous_variables, +      final Ref index, +      final Computation collection_size, +      final Ref collection +   ) +   { +      final List<Instruction> result, while_body; +      final Type element_type; +      final Ref next, end; +      final Computation value_of_index; +      final Computation value_of_next, value_of_end; +      final Computation const_1; +      final Ref collection_at_index; + +      result = new ArrayList<Instruction>(); +      while_body = new ArrayList<Instruction>(); + +      element_type = +         ((MapType) collection.get_target_type()).get_member_type(); + +      next = anonymous_variables.reserve(Type.INT); +      end = anonymous_variables.reserve(Type.INT); + +      value_of_index = new ValueOf(index); + +      value_of_next = new ValueOf(next); +      value_of_end = new ValueOf(end); + +      const_1 = new Constant(Type.INT, "1"); + +      collection_at_index = +         new RelativeRef +         ( +            collection, +            Collections.singletonList +            ( +               new Cast(value_of_index, Type.STRING) +            ), +            element_type +         ); + +      /* (set .end (- (collection_size) 1) */ +      result.add +      ( +         new SetValue(end, Operation.minus(collection_size, const_1)) +      ); + +      /* (set .next (+ (val index) 1)) */ +      while_body.add +      ( +         new SetValue(next, Operation.plus(value_of_end, const_1)) +      ); + +      /* (set collection[index] (val collection[.next])) */ +      while_body.add +      ( +         new SetValue +         ( +            collection_at_index, +            new ValueOf +            ( +               new RelativeRef +               ( +                  collection, +                  Collections.singletonList +                  ( +                     new Cast(value_of_next, Type.STRING) +                  ), +                  element_type +               ) +            ) +         ) +      ); + +      /* (set .end (val .next)) */ +      while_body.add(new SetValue(index, value_of_next)); + +      /* +       * (while (< (var index) (var .end)) +       *    (set .next (+ (val index) 1)) +       *    (set collection[index] (val collection[.next])) +       *    (set index (val .next)) +       * ) +       */ +      result.add +      ( +         new While +         ( +            Operation.less_than(value_of_index, value_of_end), +            while_body +         ) +      ); + +      /* (remove collection[index]) */ +      result.add(new Remove(collection_at_index)); + +      anonymous_variables.release(end); +      anonymous_variables.release(next); + +      return result; +   } +} | 


