| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src')
8 files changed, 436 insertions, 3 deletions
| diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/Default.java b/src/core/src/tonkadur/fate/v1/lang/computation/Default.java new file mode 100644 index 0000000..5315b25 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/Default.java @@ -0,0 +1,49 @@ +package tonkadur.fate.v1.lang.computation; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.type.PointerType; +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Computation; + +public class Default extends Computation +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public Default (final Origin origin, final Type t) +   { +      super(origin, t); +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Accessors ************************************************************/ +   @Override +   public void get_visited_by (final ComputationVisitor cv) +   throws Throwable +   { +      cv.visit_default(this); +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append("(Default "); +      sb.append(type.get_name()); +      sb.append(") "); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/New.java b/src/core/src/tonkadur/fate/v1/lang/computation/New.java index 4f036af..000d74a 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/New.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/New.java @@ -47,7 +47,6 @@ public class New extends Computation     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.toString());        sb.append("(New ");        sb.append(target_type.get_name());        sb.append(") "); diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java index 1042abc..fd1ed34 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java @@ -22,6 +22,9 @@ public interface ComputationVisitor     public void visit_fold (final Fold n)     throws Throwable; +   public void visit_default (final Default n) +   throws Throwable; +     public void visit_cond_value (final CondValue n)     throws Throwable; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index 91ce261..b8d0bc7 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -41,6 +41,7 @@ DECLARE_EVENT_TYPE_KW: L_PAREN ('declare'|'define'|'def')US'event'(US'type')? SE  DECLARE_TEXT_EFFECT_KW: L_PAREN ('declare'|'define'|'def')US'text'US'effect' SEP+;  DECLARE_VARIABLE_KW: L_PAREN 'global' SEP+;  LOCAL_KW: L_PAREN 'local' SEP+; +DEFAULT_KW: L_PAREN 'default' SEP+;  DEFINE_SEQUENCE_KW: L_PAREN ('declare'|'define'|'def')US(('seq'('uence')?)|('proc'('edure'?))) SEP+;  DIVIDE_KW: L_PAREN ('divide'|'/'|'div') SEP+;  DO_WHILE_KW: L_PAREN ('do'US'while') SEP+; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index ab623a8..108813e 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -3103,6 +3103,20 @@ returns [Computation result]           );     } +   | DEFAULT_KW type WS* R_PAREN +   { +      $result = +         new Default +         ( +            CONTEXT.get_origin_at +            ( +               ($DEFAULT_KW.getLine()), +               ($DEFAULT_KW.getCharPositionInLine()) +            ), +            ($type.result) +         ); +   } +     | COND_KW value_cond_list WS* R_PAREN     {        $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 d3347c8..3d48b52 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 @@ -23,10 +23,12 @@ import tonkadur.wyrd.v1.lang.instruction.Initialize;  import tonkadur.wyrd.v1.lang.instruction.SetPC;  import tonkadur.wyrd.v1.compiler.util.AddElement; +import tonkadur.wyrd.v1.compiler.util.AddElementsOf;  import tonkadur.wyrd.v1.compiler.util.BinarySearch;  import tonkadur.wyrd.v1.compiler.util.IfElse;  import tonkadur.wyrd.v1.compiler.util.If;  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.InsertAt; @@ -1316,6 +1318,21 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     }     @Override +   public void visit_default +   ( +      final tonkadur.fate.v1.lang.computation.Default n +   ) +   throws Throwable +   { +      final Register r; + +      r = reserve(TypeCompiler.compile(compiler, n.get_type())); + +      init_instructions.add(new Initialize(r.get_address())); +   } + + +   @Override     public void visit_access     (        final tonkadur.fate.v1.lang.computation.Access n @@ -2095,7 +2112,50 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO */ +      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 +      ( +         AddElementsOf.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 @@ -2638,7 +2698,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); + +      if (in_collection_cc.has_init()) +      { +         init_instructions.add(in_collection_cc.get_init()); +      } + +      in_collection_cc.release_registers(init_instructions); + +      init_instructions.add +      ( +         FilterLambda.generate +         ( +            compiler.registers(), +            compiler.assembler(), +            lambda_cc.get_computation(), +            result_as_address +         ) +      );     }     @Override diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/AddElementsOf.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/AddElementsOf.java new file mode 100644 index 0000000..af979a8 --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/AddElementsOf.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 AddElementsOf +{ +   /* Utility Class */ +   private AddElementsOf () {} + +   /* Uses Durstenfeld's shuffling algorithm */ +   public static Instruction generate +   ( +      final RegisterManager registers, +      final InstructionManager assembler, +      final Address collection_in, +      final Address collection, +      final boolean to_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 +      ( +         AddElement.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, +            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); + +      return assembler.merge(result); +   } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/FilterLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/FilterLambda.java new file mode 100644 index 0000000..8757fe7 --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/FilterLambda.java @@ -0,0 +1,162 @@ +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 FilterLambda +{ +   /* Utility Class */ +   private FilterLambda () {} + +   /* Uses Durstenfeld's shuffling algorithm */ +   public static Instruction generate +   ( +      final RegisterManager registers, +      final InstructionManager assembler, +      final Computation lambda, +      final Address collection +   ) +   { +      final List<Computation> params; +      final List<Instruction> result, while_body, remove_instructions; +      final Register iterator, index_storage, collection_size, storage; + +      params = new ArrayList<Computation>(); +      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); + +      result.add(new SetValue(iterator.get_address(), Constant.ZERO)); +      result.add +      ( +         new SetValue(collection_size.get_address(), new Size(collection)) +      ); + +      params.add +      ( +         new ValueOf +         ( +            new RelativeAddress +            ( +               collection, +               new Cast(iterator.get_value(), Type.STRING), +               ((MapType) collection.get_target_type()).get_member_type() +            ) +         ) +      ); + +      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 +         ) +      ); + +      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(), +            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); +   } +} | 


