| summaryrefslogtreecommitdiff | 
diff options
3 files changed, 300 insertions, 2 deletions
| diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/Cast.java b/src/core/src/tonkadur/fate/v1/lang/computation/Cast.java index 8e283c9..a14bf27 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/Cast.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/Cast.java @@ -107,6 +107,8 @@ public class Cast extends Computation     {        final Type hint; +      value.expect_string(); +        if        (           (value.get_type().can_be_used_as(to)) diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/CondValue.java b/src/core/src/tonkadur/fate/v1/lang/computation/CondValue.java index 91f6b6b..cf4395d 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/CondValue.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/CondValue.java @@ -49,13 +49,43 @@ public class CondValue extends Computation     {        Type hint; -      hint = branches.get(0).get_cdr().get_type(); +      hint = null;        for (final Cons<Computation, Computation> entry: branches)        { +         if (entry.get_cdr().get_type().can_be_used_as(Type.STRING)) +         { +            expect_string = 1; + +            hint = Type.STRING; + +            break; +         } +         else if (entry.get_cdr().get_type() != Type.ANY) +         { +            expect_string = 0; + +            hint = entry.get_cdr().get_type(); + +            break; +         } +      } + +      for (final Cons<Computation, Computation> entry: branches) +      { +         entry.get_car().expect_non_string(); +           RecurrentChecks.assert_can_be_used_as(entry.get_car(), Type.BOOL); -         hint = RecurrentChecks.assert_can_be_used_as(entry.get_cdr(), hint); +         if (hint != null) +         { +            hint = RecurrentChecks.assert_can_be_used_as(entry.get_cdr(), hint); +         } +      } + +      if (hint == null) +      { +         hint = new FutureType(origin, new ArrayList<Type>());        }        return new CondValue(origin, hint, branches); @@ -63,6 +93,46 @@ public class CondValue extends Computation     /**** Accessors ************************************************************/     @Override +   public void expect_non_string () +   { +      if (get_type() instanceof FutureType) +      { +         Type hint; + +         hint = branches.get(0).get_cdr().expect_non_string(); + +         for (final Cons<Computation, Computation> entry: branches) +         { +            entry.get_cdr().expect_non_string(); + +            hint = RecurrentChecks.assert_can_be_used_as(entry.get_cdr(), hint); +         } + +         ((FutureType) get_type()).resolve_to(hint); +      } +   } + +   @Override +   public void expect_string () +   { +      if (get_type() instanceof FutureType) +      { +         Type hint; + +         hint = branches.get(0).get_cdr().expect_string(); + +         for (final Cons<Computation, Computation> entry: branches) +         { +            entry.get_cdr().expect_non_string(); + +            hint = RecurrentChecks.assert_can_be_used_as(entry.get_cdr(), hint); +         } + +         ((FutureType) get_type()).resolve_to(hint); +      } +   } + +   @Override     public void get_visited_by (final ComputationVisitor cv)     throws Throwable     { diff --git a/src/core/src/tonkadur/fate/v1/lang/type/FutureType.java b/src/core/src/tonkadur/fate/v1/lang/type/FutureType.java new file mode 100644 index 0000000..2eadd4f --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/type/FutureType.java @@ -0,0 +1,226 @@ +package tonkadur.fate.v1.lang.type; + +import java.util.ArrayList; +import java.util.Collection; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Context; +import tonkadur.parser.Location; +import tonkadur.parser.Origin; + +public class FutureType extends Type +{ +   public static final Collection<FutureType> FUTURE_TYPES; + +   static +   { +      FUTURE_TYPES = new ArrayList<FutureType>(); +   } + +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected Type resolved_type; + +   protected void assert_is_resolved () +   { +      if (resolved_type == null) +      { +         // TODO: proper error handling +         // +         System.err.println +         ( +            "[F] Future Type from " +            + get_origin().toString() +            + " used prior to resolution." +         ); + +         System.exit(-1); +      } +   } + +   public static Collection<FutureType> get_unresolved_types () +   { +      final Collection<FutureType> result; + +      result = new ArraList<FutureType>(); + +      for (final FutureType t: FUTURE_TYPES) +      { +         if (t.resolved_type == null) +         { +            result.add(t); +         } +      } + +      return result; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   public FutureType +   ( +      final Origin origin, +      final List<Type> parameters +   ) +   { +      super(origin, null, "Future Type", parameters); + +      FUTURE_TYPES.add(this); +   } + + +   /**** Accessors ************************************************************/ +   public Type get_base_type () +   { +      assert_is_resolved(); + +      return resolved_type.get_base_type(); +   } + +   public Type get_act_as_type () +   { +      assert_is_resolved(); + +      return resolved_type.get_act_as_type(); +   } + +   public boolean is_base_type () +   { +      assert_is_resolved(); + +      return resolved_type.is_base_type(); +   } + +   public Type try_merging_with (final Type t) +   { +      assert_is_resolved(); + +      return resolved_type.try_merging_with(t); +   } + +   /**** Compatibility ********************************************************/ +   public boolean can_be_used_as (final Type t) +   { +      assert_is_resolved(); + +      return resolved_type.can_be_used_as(t); +   } + +   @Override +   public DeclaredEntity generate_comparable_to (final DeclaredEntity de) +   { +      assert_is_resolved(); + +      return resolved_type.generate_comparable_to(de); +   } + + +   /**** Misc. ****************************************************************/ +   @Override +   public Type generate_alias (final Origin origin, final String name) +   { +      // FutureType won't work as a stand in for non-basic types, since +      // the casts performed on such classes won't be allowed. +      final FutureType result; + +      result = new FutureType(origin, parameters); + +      result.resolve_to(this); + +      return result; +   } + +   @Override +   public boolean is_incompatible_with_declaration (final DeclaredEntity de) +   { +      assert_is_resolved(); + +      return resolved_type.is_incompatible_with_declaration(de); +   } + +   @Override +   public String toString () +   { +      if (resolved_type == null) +      { +         return "Unresolved Future Type"; +      } +      else +      { +         return resolved_type.toString(); +      } +   } + +   @Override +   public Type generate_variant +   ( +      final Origin origin, +      final List<Type> parameters +   ) +   throws Throwable +   { +      assert_is_resolved(); + +      return resolved_type.generate_variant(parameters); +   } + +   public Type get_resolved_type () +   { +      if +      ( +         (resolved_type != null) +         && (resolved_type instanceof FutureType) +      ) +      { +         return ((FutureType) resolved_type).get_resolved_type(); +      } +      else +      { +         return resolved_type; +      } +   } + +   public void resolve_to (final Type t) +   { +      if (resolved_type == null) +      { +         resolved_type = t; +      } +   } + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   @Override +   protected boolean this_or_parent_equals (final Type t) +   { +      assert_is_resolved(); + +      return resolved_type.this_or_parent_equals(t); +   } + +   @Override +   protected List<Type> compute_full_type_chain () +   { +      final List<Type> result; +      Type t; + +      result = new ArrayList<Type>(); + +      t = this; + +      while (t != null) +      { +         result.add(t); + +         t = t.parent; +      } + +      Collections.reverse(result); + +      return result; +   } +} | 


