summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-05 09:33:34 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-05 09:33:34 +0200
commit9b9958e662d89d2c8c497791072edd25e09ec6de (patch)
tree45fbc158ead4f4b71e96828a61b82581d291800b
parent003323c886102a389fee7912cf8a46dc5b53012c (diff)
...
-rw-r--r--src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java5
-rw-r--r--src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java55
-rw-r--r--src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java3
-rw-r--r--src/core/src/tonkadur/fate/v1/error/ErrorCategory.java18
-rw-r--r--src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java65
-rw-r--r--src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java55
-rw-r--r--src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java5
-rw-r--r--src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java55
-rw-r--r--src/core/src/tonkadur/fate/v1/error/InvalidArityException.java52
-rw-r--r--src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java62
-rw-r--r--src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java3
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/Event.java35
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/Operation.java142
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/Operator.java72
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/Type.java107
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/World.java16
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java52
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/DeclaredEntity.java8
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/InstructionNode.java60
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/Node.java62
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/ValueNode.java47
-rw-r--r--src/core/src/tonkadur/functional/Merge.java4
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;
}