| summaryrefslogtreecommitdiff | 
diff options
7 files changed, 394 insertions, 7 deletions
| diff --git a/data/unit-testing/count.fate b/data/unit-testing/count.fate new file mode 100644 index 0000000..99fed3d --- /dev/null +++ b/data/unit-testing/count.fate @@ -0,0 +1,78 @@ +(fate_version 1) + +(global string test_name) + +(set test_name ( COUNT )) + +(assert (= (count 10 (range 0 60 1)) 1) +   [FAILED] (var test_name) Failed to find 10 in range 0 60 1. +) + +(global (list int) li) + +(add_all! (range 0 10 1) li) +(add_all! (range 0 10 1) li) +(add_all! (range 0 10 1) li) +(add_all! (range 0 10 1) li) + +(assert (= (count 10 li) 4) +   [FAILED] (var test_name) Failed to find 10 four times in li. +) + +(global (set int) si) + +(add_all! (range 0 10 1) si) +(add_all! (range 0 10 1) si) +(add_all! (range 0 10 1) si) +(add_all! (range 0 10 1) si) + +(assert (= (count 10 si) 1) +   [FAILED] (var test_name) Failed to find 10 exactly once in si. +) + +(global (list string) ls) + +(add! test0 ls) +(add! test1 ls) +(add! test2 ls) +(add! test3 ls) + +(assert (= (count test0 ls) 1) +   [FAILED] (var test_name) Failed to find test0 exactly once in ls. +) + +(add! test0 ls) +(add! test1 ls) +(add! test2 ls) +(add! test3 ls) +(add! test0 ls) +(add! test1 ls) +(add! test2 ls) +(add! test3 ls) +(add! test0 ls) +(add! test1 ls) +(add! test2 ls) +(add! test3 ls) + +(assert (= (count test0 ls) 4) +   [FAILED] (var test_name) Failed to find test0 four times in ls. +) + +(global (list bool) lb) +(local int i) + +(for (set i 0) (=< i 10) (set i (+ i 1)) +   (add! (= (mod i 2) 0) lb) +) + +(assert (= (count (true) lb) 6) +   [FAILED] (var test_name) Failed to find six even numbers. +) + +(assert (= (count (false) lb) 5) +   [FAILED] (var test_name) Failed to find four odd numbers. +) + +[COMPLETED] (var test_name) + +(end) diff --git a/data/unit-testing/field_access.fate b/data/unit-testing/field_access.fate new file mode 100644 index 0000000..eba657a --- /dev/null +++ b/data/unit-testing/field_access.fate @@ -0,0 +1,90 @@ +(fate_version 1) + +(global string test_name) + +(set test_name ( FIELD ACCESS )) + +(declare_structure test_struct_type0 +   (int i) +   (int j) +   (int k) +   ((list int) li) +) + +(declare_structure test_struct_type1 +   (int i) +   (test_struct_type0 ts0) +   ((list test_struct_type0) lts) +) + +(declare_structure test_struct_type2 +   (int i) +   (test_struct_type0 ts0) +   (test_struct_type1 ts1) +) + +(local test_struct_type0 ts0_0) +(local test_struct_type0 ts0_1) +(local test_struct_type1 ts1_0) +(local test_struct_type1 ts1_1) +(local test_struct_type2 ts2_0) + + +(set_fields! ts0_0 +   (i 42) +   (j 69) +   (k 420) +   (li (range 0 10 1)) +) + +(set_fields! ts0_1 +   (i 42) +   (j 69) +   (k 420) +   (k 42) +   (j 69) +   (i 420) +   (li (range 11 20 1)) +) + +(set_fields! ts1_0 +   (i 1337) +   (ts0 (var ts0_0)) +   (lts (add (var ts0_1) (add (var ts0_0) (default (list test_struct_type0))))) +) + +(set_fields! ts1_1 +   (i 1337) +   (ts0 (var ts0_1)) +   (lts (add (var ts0_0) (add (var ts0_1) (default (list test_struct_type0))))) +) + +(set ts2_0 +   (set_fields (default test_struct_type2) +      (i -1337) +      (ts0 (var ts0_0)) +      (ts1 (var ts1_1)) +   ) +) + +(assert +   (= (get_field ts0_0 i) (var ts0_0.i) (get_field ts0_1 k) (var ts0_1.k) 42) +   [FAILED] (var test_name) Test 0. +   (newline) +   ts0_0.i = (var ts0_0.i) +   (newline) +   ts0_1.k = (var ts0_1.k) +) + +(assert +   (= (get_field ts0_1 i) (var ts0_1.i) (get_field ts0_0 k) (var ts0_0.k) 420) +   [FAILED] (var test_name) Test 1. +   (newline) +   ts0_0.k = (var ts0_0.k) +   (newline) +   ts0_1.i = (var ts0_1.i) +) + +[COMPLETED] (var test_name) + +(end) diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/FieldAccess.java b/src/core/src/tonkadur/fate/v1/lang/computation/FieldAccess.java new file mode 100644 index 0000000..bc0d6b5 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/FieldAccess.java @@ -0,0 +1,152 @@ +package tonkadur.fate.v1.lang.computation; + +import java.util.Collections; +import java.util.List; + +import tonkadur.parser.Origin; + +import tonkadur.error.ErrorManager; + +import tonkadur.fate.v1.error.InvalidTypeException; +import tonkadur.fate.v1.error.UnknownDictionaryFieldException; + +import tonkadur.fate.v1.lang.meta.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Reference; +import tonkadur.fate.v1.lang.meta.Computation; + +import tonkadur.fate.v1.lang.type.DictType; +import tonkadur.fate.v1.lang.type.Type; + +public class FieldAccess extends Computation +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Computation parent; +   protected final String field_name; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected FieldAccess +   ( +      final Origin origin, +      final Computation parent, +      final Type type, +      final String field_name +   ) +   { +      super(origin, type); + +      this.parent = parent; +      this.field_name = field_name; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public static FieldAccess build +   ( +      final Origin origin, +      Computation parent, +      final String field +   ) +   throws +      InvalidTypeException, +      UnknownDictionaryFieldException +   { +      Type current_type; + +      current_type = parent.get_type(); + +      while (current_type.get_act_as_type().equals(Type.REF)) +      { +         parent = AtReference.build(origin, (Reference) parent); +         current_type = parent.get_type(); +      } + +      if (!(current_type instanceof DictType)) +      { +         ErrorManager.handle +         ( +            new InvalidTypeException +            ( +               origin, +               current_type, +               Collections.singleton(Type.DICT), +               parent.toString() +            ) +         ); + +         current_type = Type.ANY; +      } +      else +      { +         current_type = ((DictType) current_type).get_field_type(origin, field); +      } + +      return new FieldAccess(origin, parent, current_type, field); +   } + +   public static FieldAccess build +   ( +      final Origin origin, +      Computation parent, +      final List<String> field_sequence +   ) +   throws +      InvalidTypeException, +      UnknownDictionaryFieldException +   { +      for (final String field: field_sequence) +      { +         parent = build(origin, parent, field); +      } + +      if (parent instanceof FieldAccess) +      { +         return (FieldAccess) parent; +      } +      else +      { +         return null; +      } +   } + +   /**** Accessors ************************************************************/ +   @Override +   public void get_visited_by (final ComputationVisitor cv) +   throws Throwable +   { +      cv.visit_field_access(this); +   } + +   public String get_field_name () +   { +      return field_name; +   } + +   public Computation get_parent () +   { +      return parent; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append("(FieldAccess ("); +      sb.append(type.get_name()); +      sb.append(") "); +      sb.append(parent.toString()); +      sb.append(" "); +      sb.append(field_name); +      sb.append(")"); + +      return sb.toString(); +   } +} 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 23fb1c8..4631a2f 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java @@ -13,6 +13,9 @@ public interface ComputationVisitor     public void visit_access_pointer (final AccessPointer n)     throws Throwable; +   public void visit_field_access (final FieldAccess n) +   throws Throwable; +     public void visit_access_as_reference (final AccessAsReference 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 077371f..c2ed078 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -59,6 +59,7 @@ FALSE_KW: L_PAREN 'false)';  IGNORE_ERROR_KW: L_PAREN 'ignore'US('error'|'warning') SEP+;  FATE_VERSION_KW: L_PAREN 'fate'US'version' SEP+;  FIELD_KW: L_PAREN 'field' SEP+; +FIELD_ACCESS_KW: L_PAREN (('get'US'field')|('field'US'access')) SEP+;  FILTER_KW: L_PAREN 'filter' SEP+;  INDEXED_FILTER_KW: L_PAREN 'indexed'US'filter' SEP+;  IMP_FILTER_KW: L_PAREN 'filter!' SEP+; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 7dd5081..88601f5 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -2501,7 +2501,7 @@ returns [RichTextNode result]:     | ENABLE_TEXT_EFFECT_KW        L_PAREN           WORD WS+ -         value_list +         value_list WS*        R_PAREN WS+        paragraph WS*        R_PAREN @@ -3446,7 +3446,7 @@ returns [Computation result]:           );     } -   | COUNT_KW value WS+ value_reference WS* R_PAREN +   | COUNT_KW value WS+ non_text_value WS* R_PAREN     {        $result =           CountOperator.build @@ -3457,7 +3457,7 @@ returns [Computation result]:                 ($COUNT_KW.getCharPositionInLine())              ),              ($value.result), -            ($value_reference.result) +            ($non_text_value.result)           );     }  ; @@ -3538,7 +3538,7 @@ returns [Computation result]     | ENABLE_TEXT_EFFECT_KW        L_PAREN           WORD WS+ -         value_list +         value_list WS*        R_PAREN WS+        paragraph WS*        R_PAREN @@ -3667,7 +3667,7 @@ returns [Computation result]           );     } -   | ACCESS_KW collection=non_text_value WS+ index=non_text_value R_PAREN +   | ACCESS_KW collection=non_text_value WS+ index=non_text_value WS* R_PAREN     {        $result =           Access.build @@ -3682,7 +3682,7 @@ returns [Computation result]           );     } -   | ACCESS_POINTER_KW value_reference WS+ non_text_value R_PAREN +   | ACCESS_POINTER_KW value_reference WS+ non_text_value WS* R_PAREN     {        $result =           AccessPointer.build @@ -3697,6 +3697,21 @@ returns [Computation result]           );     } +   | FIELD_ACCESS_KW non_text_value WS+ WORD WS* R_PAREN +   { +      $result = +         FieldAccess.build +         ( +            CONTEXT.get_origin_at +            ( +               ($FIELD_ACCESS_KW.getLine()), +               ($FIELD_ACCESS_KW.getCharPositionInLine()) +            ), +            ($non_text_value.result), +            ($WORD.text) +         ); +   } +     | FOLDL_KW           fun=non_text_value WS+           init=value WS+ 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 30fe7b8..1473c6c 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 @@ -503,6 +503,37 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     }     @Override +   public void visit_field_access +   ( +      final tonkadur.fate.v1.lang.computation.FieldAccess n +   ) +   throws Throwable +   { +      final ComputationCompiler n_cc; + +      n_cc = new ComputationCompiler(compiler); + +      n.get_parent().get_visited_by(n_cc); + +      assimilate(n_cc); + +      result_as_address = +         new RelativeAddress +         ( +            n_cc.get_address(), +            new Constant(Type.STRING, n.get_field_name()), +            TypeCompiler.compile +            ( +               compiler, +               ( +                  (tonkadur.fate.v1.lang.type.DictType) +                     n.get_parent().get_type() +               ).get_field_type(null, n.get_field_name()) +            ) +         ); +   } + +   @Override     public void visit_if_else_value     (        final tonkadur.fate.v1.lang.computation.IfElseValue n @@ -1188,8 +1219,25 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor           )        )        { +         final Iterator<Computation> operands_it; +         final Computation first_elem; + +         operands_it = operands.iterator(); + +         first_elem = operands_it.next(); +           result_as_computation = -            Operation.equals(operands.get(0), operands.get(1)); +            Operation.equals(first_elem, operands_it.next()); + +         while (operands_it.hasNext()) +         { +            result_as_computation = +               Operation.and +               ( +                  result_as_computation, +                  Operation.equals(first_elem, operands_it.next()) +               ); +         }        }        else if        ( | 


