| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-05 09:33:34 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-05 09:33:34 +0200 |
| commit | 9b9958e662d89d2c8c497791072edd25e09ec6de (patch) | |
| tree | 45fbc158ead4f4b71e96828a61b82581d291800b | |
| parent | 003323c886102a389fee7912cf8a46dc5b53012c (diff) | |
...
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; } |


