From 30dcc608374485d1d25b93a700af3f8b276eafb1 Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Tue, 29 Jun 2021 13:27:57 +0200 Subject: Working on yet-to-be-determined type support. --- .../tonkadur/fate/v1/lang/computation/Cast.java | 2 + .../fate/v1/lang/computation/CondValue.java | 74 ++++++- .../src/tonkadur/fate/v1/lang/type/FutureType.java | 226 +++++++++++++++++++++ 3 files changed, 300 insertions(+), 2 deletions(-) create mode 100644 src/core/src/tonkadur/fate/v1/lang/type/FutureType.java 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,19 +49,89 @@ public class CondValue extends Computation { Type hint; - hint = branches.get(0).get_cdr().get_type(); + hint = null; for (final Cons 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 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()); } return new CondValue(origin, hint, branches); } /**** 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 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 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 FUTURE_TYPES; + + static + { + FUTURE_TYPES = new ArrayList(); + } + + /***************************************************************************/ + /**** 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 get_unresolved_types () + { + final Collection result; + + result = new ArraList(); + + for (final FutureType t: FUTURE_TYPES) + { + if (t.resolved_type == null) + { + result.add(t); + } + } + + return result; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + public FutureType + ( + final Origin origin, + final List 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 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 compute_full_type_chain () + { + final List result; + Type t; + + result = new ArrayList(); + + t = this; + + while (t != null) + { + result.add(t); + + t = t.parent; + } + + Collections.reverse(result); + + return result; + } +} -- cgit v1.2.3-70-g09d2