| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src')
22 files changed, 935 insertions, 48 deletions
| diff --git a/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java index d0837a7..34e1a98 100644 --- a/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java @@ -27,7 +27,7 @@ public class ConflictingDeclarationException extends ParsingError        super        (           ErrorLevel.ERROR, -         ErrorCategory.CONFLICTING_DECLARATION, +         ErrorCategory.CONFLICTING,           new_declaration.get_origin()        ); @@ -41,7 +41,8 @@ public class ConflictingDeclarationException extends ParsingError        final StringBuilder sb = new StringBuilder();        sb.append(origin.get_context().toString()); -      sb.append("Declaration for "); +      sb.append(error_category.toString()); +      sb.append(" Declaration for ");        sb.append(original_declaration.get_type_name());        sb.append(" '");        sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java b/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java new file mode 100644 index 0000000..3cf287e --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java @@ -0,0 +1,55 @@ +package tonkadur.fate.v1.error; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.Type; + +public class ConflictingTypeException extends ParsingError +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Type given_type; +   protected final Type expected_type; + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   public ConflictingTypeException +   ( +      final Origin call_origin, +      final Type given_type, +      final Type expected_type +   ) +   { +      super +      ( +         ErrorLevel.ERROR, +         ErrorCategory.CONFLICTING, +         call_origin +      ); + +      this.given_type = given_type; +      this.expected_type = expected_type; +   } + +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.get_context().toString()); +      sb.append(error_category.toString()); +      sb.append(" Resulting type '"); +      sb.append(given_type.get_name()); +      sb.append("' "); +      sb.append(" conflicts with the expected one ('"); +      sb.append(expected_type.get_name()); +      sb.append("')."); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java index 066bbe6..eb42aba 100644 --- a/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java @@ -33,7 +33,8 @@ public class DuplicateDeclarationException extends ParsingError        final StringBuilder sb = new StringBuilder();        sb.append(origin.get_context().toString()); -      sb.append("Declaration for "); +      sb.append(error_category.toString()); +      sb.append(" Declaration for ");        sb.append(original_declaration.get_type_name());        sb.append(" '");        sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/ErrorCategory.java b/src/core/src/tonkadur/fate/v1/error/ErrorCategory.java index ef1396e..35f4b94 100644 --- a/src/core/src/tonkadur/fate/v1/error/ErrorCategory.java +++ b/src/core/src/tonkadur/fate/v1/error/ErrorCategory.java @@ -2,21 +2,23 @@ package tonkadur.fate.v1.error;  class ErrorCategory extends tonkadur.error.ErrorCategory  { +   public static final ErrorCategory CONFLICTING;     public static final ErrorCategory DUPLICATE_DECLARATION; -   public static final ErrorCategory CONFLICTING_DECLARATION; +   public static final ErrorCategory INCOMPARABLE; +   public static final ErrorCategory INCOMPATIBLE; +   public static final ErrorCategory INVALID_USE;     public static final ErrorCategory MISSING_DECLARATION; -   public static final ErrorCategory UNKNOWN_SEQUENCE; -   public static final ErrorCategory INCORRECT_TYPE; -   public static final ErrorCategory INCOMPATIBLE_TYPE; +   public static final ErrorCategory UNKNOWN;     static     { +      CONFLICTING = new ErrorCategory("conflicting");        DUPLICATE_DECLARATION = new ErrorCategory("duplicate_declaration"); -      CONFLICTING_DECLARATION = new ErrorCategory("conflicting_declaration"); +      INCOMPARABLE = new ErrorCategory("incomparable"); +      INCOMPATIBLE = new ErrorCategory("incompatible"); +      INVALID_USE = new ErrorCategory("invalid_use");        MISSING_DECLARATION = new ErrorCategory("missing_declaration"); -      UNKNOWN_SEQUENCE = new ErrorCategory("unknown_sequence"); -      INCORRECT_TYPE = new ErrorCategory("incorrect_type"); -      INCOMPATIBLE_TYPE = new ErrorCategory("incompatible_type"); +      UNKNOWN = new ErrorCategory("unknown");     }     private ErrorCategory (final String name) diff --git a/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java new file mode 100644 index 0000000..c5dfc94 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java @@ -0,0 +1,65 @@ +package tonkadur.fate.v1.error; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.meta.DeclaredEntity; + +public class IncomparableDeclarationException extends ParsingError +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final DeclaredEntity new_declaration; +   protected final DeclaredEntity original_declaration; + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   public IncomparableDeclarationException +   ( +      final DeclaredEntity new_declaration, +      final DeclaredEntity original_declaration +   ) +   { +      super +      ( +         ErrorLevel.ERROR, +         ErrorCategory.INCOMPARABLE, +         new_declaration.get_origin() +      ); + +      this.new_declaration = new_declaration; +      this.original_declaration = original_declaration; +   } + +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.get_context().toString()); +      sb.append(error_category.toString()); +      sb.append(" Declaration for "); +      sb.append(original_declaration.get_type_name()); +      sb.append(" '"); +      sb.append(original_declaration.get_name()); +      sb.append("' at "); +      sb.append(origin.get_location().toString()); +      sb.append(" is incomparable with its declaration at "); +      sb.append(original_declaration.get_origin().get_location().toString()); +      sb.append("."); +      sb.append(System.lineSeparator()); +      sb.append("Previous declaration was "); +      sb.append(original_declaration.toString()); +      sb.append("."); +      sb.append(System.lineSeparator()); +      sb.append("New declaration is "); +      sb.append(new_declaration.toString()); +      sb.append("."); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java b/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java new file mode 100644 index 0000000..19ae9d6 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java @@ -0,0 +1,55 @@ +package tonkadur.fate.v1.error; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.Type; + +public class IncomparableTypeException extends ParsingError +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Type given_type; +   protected final Type expected_type; + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   public IncomparableTypeException +   ( +      final Origin call_origin, +      final Type given_type, +      final Type expected_type +   ) +   { +      super +      ( +         ErrorLevel.ERROR, +         ErrorCategory.INCOMPARABLE, +         call_origin +      ); + +      this.given_type = given_type; +      this.expected_type = expected_type; +   } + +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.get_context().toString()); +      sb.append(error_category.toString()); +      sb.append(" Resulting type '"); +      sb.append(given_type.toString()); +      sb.append("' "); +      sb.append(" is incomparable with the expected one ('"); +      sb.append(expected_type.toString()); +      sb.append("')."); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java index 582f593..f1f1be6 100644 --- a/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java @@ -27,7 +27,7 @@ public class IncompatibleDeclarationException extends ParsingError        super        (           ErrorLevel.ERROR, -         ErrorCategory.CONFLICTING_DECLARATION, +         ErrorCategory.INCOMPATIBLE,           new_declaration.get_origin()        ); @@ -41,7 +41,8 @@ public class IncompatibleDeclarationException extends ParsingError        final StringBuilder sb = new StringBuilder();        sb.append(origin.get_context().toString()); -      sb.append("Declaration for "); +      sb.append(error_category.toString()); +      sb.append(" Declaration for ");        sb.append(original_declaration.get_type_name());        sb.append(" '");        sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java b/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java new file mode 100644 index 0000000..da05cb9 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java @@ -0,0 +1,55 @@ +package tonkadur.fate.v1.error; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.Type; + +public class IncompatibleTypeException extends ParsingError +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Type given_type; +   protected final Type expected_type; + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   public IncompatibleTypeException +   ( +      final Origin call_origin, +      final Type given_type, +      final Type expected_type +   ) +   { +      super +      ( +         ErrorLevel.ERROR, +         ErrorCategory.INCOMPATIBLE, +         call_origin +      ); + +      this.given_type = given_type; +      this.expected_type = expected_type; +   } + +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.get_context().toString()); +      sb.append(error_category.toString()); +      sb.append(" Resulting type '"); +      sb.append(given_type.toString()); +      sb.append("' "); +      sb.append(" is incompatible with the expected one ('"); +      sb.append(expected_type.toString()); +      sb.append("')."); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java b/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java new file mode 100644 index 0000000..578ce60 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java @@ -0,0 +1,52 @@ +package tonkadur.fate.v1.error; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +public class InvalidArityException extends ParsingError +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final int arity; +   protected final int arguments_count; + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   public InvalidArityException +   ( +      final Origin call_origin, +      final int arguments_count, +      final int arity +   ) +   { +      super +      ( +         ErrorLevel.FATAL, +         ErrorCategory.INVALID_USE, +         call_origin +      ); + +      this.arguments_count = arguments_count; +      this.arity = arity; +   } + +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.get_context().toString()); +      sb.append(error_category.toString()); +      sb.append(" This supports a maximum or a minimum of "); +      sb.append(arity); +      sb.append(" parameter(s), but was given "); +      sb.append(arguments_count); +      sb.append(" of them."); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java b/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java new file mode 100644 index 0000000..6a62edd --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java @@ -0,0 +1,62 @@ +package tonkadur.fate.v1.error; + +import java.util.Collection; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.Type; + +public class InvalidTypeException extends ParsingError +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Type given_type; +   protected final Collection<Type> allowed_types; + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   public InvalidTypeException +   ( +      final Origin call_origin, +      final Type given_type, +      final Collection<Type> allowed_types +   ) +   { +      super +      ( +         ErrorLevel.FATAL, +         ErrorCategory.INVALID_USE, +         call_origin +      ); + +      this.given_type = given_type; +      this.allowed_types = allowed_types; +   } + +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.get_context().toString()); +      sb.append(error_category.toString()); +      sb.append(" Type '"); +      sb.append(given_type.toString()); +      sb.append("' "); +      sb.append(" is not useable here. The following base types are allowed:"); + +      for (final Type allowed_type: allowed_types) +      { +         sb.append(System.lineSeparator()); +         sb.append("- "); +         sb.append(allowed_types.toString()); +      } + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java index f564fbe..c4cb08f 100644 --- a/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java @@ -34,7 +34,8 @@ public class MissingDeclarationException extends ParsingError        final StringBuilder sb = new StringBuilder();        sb.append(origin.get_context().toString()); -      sb.append("Unknown "); +      sb.append(error_category.toString()); +      sb.append(" Unknown ");        sb.append(type_name);        sb.append(" '");        sb.append(name); diff --git a/src/core/src/tonkadur/fate/v1/lang/Event.java b/src/core/src/tonkadur/fate/v1/lang/Event.java index 38b3210..b917ebf 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Event.java +++ b/src/core/src/tonkadur/fate/v1/lang/Event.java @@ -70,6 +70,37 @@ public class Event extends DeclaredEntity        return signature;     } +   @Override +   public DeclaredEntity generate_comparable_to (final DeclaredEntity de) +   { +      final List<Type> new_signature; +      final Event e; + +      if (!(de instanceof Event)) +      { +         return ANY; +      } + +      e = (Event) de; + +      if (signature.size() != e.signature.size()) +      { +         return ANY; +      } + +      new_signature = +         new Merge<Type, Type, Type>() +         { +            @Override +            protected Type lambda (final Type a, final Type b) +            { +               return (Type) a.generate_comparable_to(b); +            } +         }.merge(signature, e.signature); + +      return new Event(origin, new_signature, name); +   } +     /**** Misc. ****************************************************************/     @Override     public boolean is_incompatible_with_declaration (final DeclaredEntity de) @@ -90,10 +121,10 @@ public class Event extends DeclaredEntity               */              compatibility_result =                 ( -                  new Merge<Type,Type,Boolean>() +                  new Merge<Type, Type, Boolean>()                    {                       @Override -                     protected Boolean merge_fun (final Type a, final Type b) +                     protected Boolean lambda (final Type a, final Type b)                       {                          return                             new Boolean(a.is_incompatible_with_declaration(b)); diff --git a/src/core/src/tonkadur/fate/v1/lang/Operation.java b/src/core/src/tonkadur/fate/v1/lang/Operation.java new file mode 100644 index 0000000..b193f5b --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/Operation.java @@ -0,0 +1,142 @@ +package tonkadur.fate.v1.lang; + +import java.util.Collection; +import java.util.List; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.ConflictingTypeException; +import tonkadur.fate.v1.error.IncomparableTypeException; +import tonkadur.fate.v1.error.IncompatibleTypeException; +import tonkadur.fate.v1.error.InvalidArityException; +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.meta.ValueNode; + +public class Operation extends ValueNode +{ +   protected final Operator operator; +   protected final List<ValueNode> operands; + +   protected Operation +   ( +      final Origin origin, +      final Type result_type, +      final Operator operator, +      final List<ValueNode> operands +   ) +   { +      super(origin, result_type); + +      this.operator = operator; +      this.operands = operands; +   } + +   public Operation build +   ( +      final Origin origin, +      final Operator operator, +      final List<ValueNode> operands +   ) +   throws +      ConflictingTypeException, +      IncomparableTypeException, +      IncompatibleTypeException, +      InvalidArityException, +      InvalidTypeException +   { +      final Collection<Type> allowed_base_types; +      final int operator_arity; +      Type computed_type, previous_computed_type; + +      allowed_base_types = operator.get_allowed_base_types(); +      operator_arity = operator.get_arity(); + +      if +      ( +         (operator_arity != 0) +         && (operator_arity < operands.size()) +      ) +      { +         ErrorManager.handle +         ( +            new InvalidArityException(origin, operands.size(), operator_arity) +         ); +      } + +      computed_type = operands.get(0).get_type(); + +      for (final ValueNode operand: operands) +      { +         final Type operand_type; + +         operand_type = operand.get_type(); + +         if (!allowed_base_types.contains(operand_type.get_true_type())) +         { +            ErrorManager.handle +            ( +               new InvalidTypeException +               ( +                  operand.get_origin(), +                  operand_type, +                  allowed_base_types +               ) +            ); +         } + +         if (computed_type.equals(operand_type)) +         { +            continue; +         } + +         ErrorManager.handle +         ( +            new ConflictingTypeException +            ( +               operand.get_origin(), +               operand_type, +               computed_type +            ) +         ); + +         if (operand_type.can_be_used_as(computed_type)) +         { +            continue; +         } + +         ErrorManager.handle +         ( +            new IncompatibleTypeException +            ( +               operand.get_origin(), +               operand_type, +               computed_type +            ) +         ); + +         previous_computed_type = computed_type; +         computed_type = +            (Type) computed_type.generate_comparable_to(operand_type); + +         if (computed_type.equals(Type.ANY)) +         { +            ErrorManager.handle +            ( +               new IncomparableTypeException +               ( +                  operand.get_origin(), +                  operand_type, +                  previous_computed_type +               ) +            ); +         } +      } + +      computed_type = operator.transform_type(computed_type); + +      return new Operation(origin, computed_type, operator, operands); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/Operator.java b/src/core/src/tonkadur/fate/v1/lang/Operator.java new file mode 100644 index 0000000..f8fb8ff --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/Operator.java @@ -0,0 +1,72 @@ +package tonkadur.fate.v1.lang; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; + +public enum Operator +{ +   PLUS("+", 0, Type.NUMBER_TYPES, null), +   MINUS("-", 0, Type.NUMBER_TYPES, null), +   TIMES("*", 0, Type.NUMBER_TYPES, null), +   DIVIDED("/", 0, Type.NUMBER_TYPES, null), +   POWER("^", 2, Type.NUMBER_TYPES, null), +   RANDOM("rand", 2, (new Type[]{Type.INT}), null), + +   AND("and", 0, (new Type[]{Type.BOOLEAN}), null), +   OR("or", 0, (new Type[]{Type.BOOLEAN}), null), +   NOT("not", 1, (new Type[]{Type.BOOLEAN}), null), +   IMPLIES("implies", 1, (new Type[]{Type.BOOLEAN}), null), + +   LOWER_THAN("<", 2, Type.NUMBER_TYPES, Type.BOOLEAN), +   LOWER_EQUAL_THAN("=<", 2, Type.NUMBER_TYPES, Type.BOOLEAN), +   GREATER_EQUAL_THAN(">=", 2, Type.NUMBER_TYPES, Type.BOOLEAN), +   GREATER_THAN(">", 2, Type.NUMBER_TYPES, Type.BOOLEAN); + +   final private String name; +   final private int arity; +   final private Collection<Type> valid_input_types; +   final private Type output_type_transform; + +   private Operator +   ( +      final String name, +      final int arity, +      final Type[] valid_input_types, +      final Type output_type_transform +   ) +   { +      this.name = name; +      this.arity = arity; +      this.valid_input_types = +         new HashSet<Type>(Arrays.asList(valid_input_types)); + +      this.output_type_transform = output_type_transform; +   } + +   public Collection<Type> get_allowed_base_types () +   { +      return valid_input_types; +   } + +   public int get_arity () +   { +      return arity; +   } + +   public Type transform_type (final Type in) +   { +      if (output_type_transform == null) +      { +         return in; +      } + +      return output_type_transform; +   } + +   @Override +   public String toString () +   { +      return name; +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/Type.java b/src/core/src/tonkadur/fate/v1/lang/Type.java index 269e011..ad49268 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Type.java +++ b/src/core/src/tonkadur/fate/v1/lang/Type.java @@ -1,5 +1,11 @@  package tonkadur.fate.v1.lang; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +  import tonkadur.parser.Context;  import tonkadur.parser.Location;  import tonkadur.parser.Origin; @@ -8,21 +14,37 @@ import tonkadur.fate.v1.lang.meta.DeclaredEntity;  public class Type extends DeclaredEntity  { -   protected static final Type ANY; +   public static final Type ANY; +   public static final Type BOOLEAN; +   public static final Type DICT; +   public static final Type FLOAT; +   public static final Type INT; +   public static final Type LIST; +   public static final Type SET; +   public static final Type STRING; + +   public static final Type[] NUMBER_TYPES;     static     { -      ANY = -         new Type -         ( -            new Origin(new Context(""), Location.BASE_LANGUAGE), -            null, -            /* -             * Use of a space necessary to avoid conflicting with a user created -             * type. -             */ -            "undetermined type" -         ); +      final Origin base; + +      base = new Origin(new Context(""), Location.BASE_LANGUAGE); + +      /* +       * Use of a space necessary to avoid conflicting with a user created type. +       */ +      ANY = new Type(base, null, "undetermined type"); + +      BOOLEAN = new Type(base, null, "boolean"); +      DICT = new Type(base, null, "dict"); +      FLOAT = new Type(base, null, "float"); +      INT = new Type(base, null, "int"); +      LIST = new Type(base, null, "list"); +      SET = new Type(base, null, "set"); +      STRING = new Type(base, null, "string"); + +      NUMBER_TYPES = new Type[]{FLOAT, INT};     }     public static Type value_on_missing () @@ -36,6 +58,7 @@ public class Type extends DeclaredEntity        return "Type";     } +     /***************************************************************************/     /**** MEMBERS **************************************************************/     /***************************************************************************/ @@ -69,7 +92,6 @@ public class Type extends DeclaredEntity     }     /**** Accessors ************************************************************/ -     public Type get_true_type ()     {        return true_type; @@ -91,6 +113,44 @@ public class Type extends DeclaredEntity        return this_or_parent_equals(t);     } +   /* +    * This is for the very special case where a type is used despite not being +    * even a sub-type of the expected one. Using this rather expensive function, +    * the most restrictive shared type will be returned. If no such type exists, +    * the ANY time is returned. +    */ +   @Override +   public DeclaredEntity generate_comparable_to (final DeclaredEntity de) +   { +      final Iterator<Type> it0, it1; +      Type result, candidate; + +      if (!(de instanceof Type)) +      { +         return ANY; +      } + +      it0 = ((Type) de).compute_full_type_chain().iterator(); +      it1 = compute_full_type_chain().iterator(); + +      result = Type.ANY; + +      while (it0.hasNext() && it1.hasNext()) +      { +         candidate = it0.next(); + +         if (!candidate.name.equals(it1.next().name)) +         { +            break; +         } + +         result = candidate; +      } + +      return result; +   } + +     /**** Misc. ****************************************************************/     @Override     public boolean is_incompatible_with_declaration (final DeclaredEntity de) @@ -144,4 +204,25 @@ public class Type extends DeclaredEntity        return parent.this_or_parent_equals(t);     } + +   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; +   }  } diff --git a/src/core/src/tonkadur/fate/v1/lang/World.java b/src/core/src/tonkadur/fate/v1/lang/World.java index e6bf2d6..5db6d16 100644 --- a/src/core/src/tonkadur/fate/v1/lang/World.java +++ b/src/core/src/tonkadur/fate/v1/lang/World.java @@ -78,18 +78,16 @@ public class World     /***************************************************************************/     protected void add_base_types ()     { -      final Origin base; - -      base = new Origin(new Context(""), Location.BASE_LANGUAGE);        try        { -         type_collection.add(new Type(base, null, "dict")); -         type_collection.add(new Type(base, null, "float")); -         type_collection.add(new Type(base, null, "int")); -         type_collection.add(new Type(base, null, "list")); -         type_collection.add(new Type(base, null, "set")); -         type_collection.add(new Type(base, null, "string")); +         type_collection.add(Type.BOOLEAN); +         type_collection.add(Type.DICT); +         type_collection.add(Type.FLOAT); +         type_collection.add(Type.INT); +         type_collection.add(Type.LIST); +         type_collection.add(Type.SET); +         type_collection.add(Type.STRING);        }        catch (final Throwable t)        { diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java b/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java index 838d109..7bcaaa1 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java @@ -12,18 +12,28 @@ import tonkadur.fate.v1.error.MissingDeclarationException;  import tonkadur.fate.v1.error.DuplicateDeclarationException;  import tonkadur.fate.v1.error.ConflictingDeclarationException;  import tonkadur.fate.v1.error.IncompatibleDeclarationException; +import tonkadur.fate.v1.error.IncomparableDeclarationException;  public class DeclarationCollection <Declared extends DeclaredEntity>  { +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/     protected final Map<String, Declared> collection;     protected final Declared value_on_missing; +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ + +   /**** Constructors *********************************************************/     public DeclarationCollection (final Declared value_on_missing)     {        collection = new HashMap<String, Declared>();        this.value_on_missing = value_on_missing;     } +   /**** Accessors ************************************************************/     public Collection<Declared> get_all ()     {        return collection.values(); @@ -34,13 +44,14 @@ public class DeclarationCollection <Declared extends DeclaredEntity>        return collection.containsKey(name);     } -   public void add (final Declared entity) +   public void add (Declared entity)     throws        DuplicateDeclarationException,        ConflictingDeclarationException, -      IncompatibleDeclarationException +      IncompatibleDeclarationException, +      IncomparableDeclarationException     { -      assert_entity_can_be_added(entity); +      entity = assert_entity_can_be_added(entity);        collection.put(entity.get_name(), entity);     } @@ -72,19 +83,21 @@ public class DeclarationCollection <Declared extends DeclaredEntity>     /***************************************************************************/     /**** PROTECTED ************************************************************/     /***************************************************************************/ -   protected void assert_entity_can_be_added (final Declared new_version) +   protected Declared assert_entity_can_be_added (Declared new_version)     throws        DuplicateDeclarationException,        ConflictingDeclarationException, -      IncompatibleDeclarationException +      IncompatibleDeclarationException, +      IncomparableDeclarationException     { +      final DeclaredEntity de;        final Declared previous_version;        previous_version = collection.get(new_version.get_name());        if (previous_version == null)        { -         return; +         return new_version;        }        ErrorManager.handle @@ -98,7 +111,7 @@ public class DeclarationCollection <Declared extends DeclaredEntity>        if (!previous_version.conflicts_with_declaration(new_version))        { -         return; +         return new_version;        }        ErrorManager.handle @@ -108,12 +121,35 @@ public class DeclarationCollection <Declared extends DeclaredEntity>        if (!previous_version.is_incompatible_with_declaration(new_version))        { -         return; +         return new_version;        }        ErrorManager.handle        (           new IncompatibleDeclarationException(new_version, previous_version)        ); + +      de = new_version.generate_comparable_to(previous_version); + +      try +      { +         new_version = (Declared) de; +      } +      catch (final ClassCastException e) +      { +         e.printStackTrace(); + +         System.exit(-1); +      } + +      if (new_version.equals(value_on_missing)) +      { +         ErrorManager.handle +         ( +            new IncomparableDeclarationException(new_version, previous_version) +         ); +      } + +      return new_version;     }  } diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/DeclaredEntity.java b/src/core/src/tonkadur/fate/v1/lang/meta/DeclaredEntity.java index 5748391..2e08cf7 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/DeclaredEntity.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/DeclaredEntity.java @@ -49,6 +49,7 @@ public abstract class DeclaredEntity        return origin;     } +   /**** Compatibility ********************************************************/     public boolean conflicts_with_declaration (final DeclaredEntity de)     {        return !equals(de); @@ -59,6 +60,13 @@ public abstract class DeclaredEntity        return !equals(de);     } +   public <ThisType extends DeclaredEntity> +   ThisType generate_comparable_to (final ThisType de) +   { +      return null; +   } + +   /**** Misc. ****************************************************************/     @Override     public boolean equals (final Object o)     { diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/InstructionNode.java b/src/core/src/tonkadur/fate/v1/lang/meta/InstructionNode.java new file mode 100644 index 0000000..3587152 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/meta/InstructionNode.java @@ -0,0 +1,60 @@ +package tonkadur.fate.v1.lang.meta; + +import java.util.Collection; +import java.util.HashSet; + +import tonkadur.parser.Origin; + +public abstract class InstructionNode extends Node +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Collection<InstructionNode> parents; +   protected InstructionNode child; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected InstructionNode (final Origin origin) +   { +      super(origin); + +      parents = new HashSet<InstructionNode>(); +      child = null; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Accessors ************************************************************/ +   public void link_parent (final InstructionNode parent) +   { +      parent.child = this; + +      parents.add(parent); +   } + +   public Collection<InstructionNode> get_parents () +   { +      return parents; +   } + +   public InstructionNode get_child () +   { +      return child; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.toString()); +      sb.append("(Instruction)"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/Node.java b/src/core/src/tonkadur/fate/v1/lang/meta/Node.java new file mode 100644 index 0000000..e5317d9 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/meta/Node.java @@ -0,0 +1,62 @@ +package tonkadur.fate.v1.lang.meta; + +import tonkadur.parser.Origin; + +public abstract class Node +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Origin origin; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected Node (final Origin origin) +   { +      this.origin = origin; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Accessors ************************************************************/ +   public Origin get_origin () +   { +      return origin; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.toString()); +      sb.append("(Node)"); + +      return sb.toString(); +   } + +   @Override +   public boolean equals (final Object o) +   { +      if (o instanceof Node) +      { +         final Node in; + +         in = (Node) o; + +         return toString().equals(in.toString()); +      } + +      return false; +   } + +   @Override +   public int hashCode () +   { +      return toString().hashCode(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/ValueNode.java b/src/core/src/tonkadur/fate/v1/lang/meta/ValueNode.java new file mode 100644 index 0000000..6670855 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/meta/ValueNode.java @@ -0,0 +1,47 @@ +package tonkadur.fate.v1.lang.meta; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.Type; + +public abstract class ValueNode extends Node +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Type type; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected ValueNode (final Origin origin, final Type type) +   { +      super(origin); + +      this.type = type; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Accessors ************************************************************/ +   public Type get_type () +   { +      return type; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.toString()); +      sb.append("("); +      sb.append(type.get_name()); +      sb.append(" Value Node)"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/functional/Merge.java b/src/core/src/tonkadur/functional/Merge.java index 68bb0e7..29d37c5 100644 --- a/src/core/src/tonkadur/functional/Merge.java +++ b/src/core/src/tonkadur/functional/Merge.java @@ -28,7 +28,7 @@ public class Merge <Input0, Input1, Output>        {           output.add           ( -            merge_fun +            lambda              (                 it0.hasNext() ? it0.next() : null,                 it1.hasNext() ? it1.next() : null @@ -39,7 +39,7 @@ public class Merge <Input0, Input1, Output>        return output;     } -   protected Output merge_fun (final Input0 i0, final Input1 i1) +   protected Output lambda (final Input0 i0, final Input1 i1)     {        return null;     } | 


