summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-20 00:51:37 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-20 00:51:37 +0200
commit39fc3eb50f3984bb128439a2cf190e51267529d9 (patch)
treeb8a36bad9b60a480c1b6fafcbd73200cd498e354
parent99171d9707c58c4f9841a00bf6fd22c4660a81e4 (diff)
Simplifies refs, adds remaining missing stuff.
-rw-r--r--data/examples/the_thief/include/characters.fate31
-rw-r--r--data/examples/the_thief/include/locations.fate39
-rw-r--r--data/examples/the_thief/include/type/character.fate4
-rw-r--r--data/examples/the_thief/include/type/location.fate14
-rw-r--r--src/core/src/tonkadur/Main.java18
-rw-r--r--src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java4
-rw-r--r--src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java2
-rw-r--r--src/core/src/tonkadur/fate/v1/error/NotAValueMacroException.java53
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/Macro.java77
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/AddElement.java7
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/EventCall.java167
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/MacroCall.java167
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/RemoveAllOfElement.java7
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/RemoveElement.java7
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/SetValue.java8
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/type/Type.java20
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/Cast.java22
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/CondValue.java11
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/CountOperator.java7
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/IfElseValue.java9
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/IsMemberOperator.java7
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/MacroValueCall.java185
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/Operation.java13
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/RefOperator.java13
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/TextWithEffect.java97
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/ValueToText.java5
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4170
-rw-r--r--src/core/src/tonkadur/functional/Merge.java39
28 files changed, 1123 insertions, 80 deletions
diff --git a/data/examples/the_thief/include/characters.fate b/data/examples/the_thief/include/characters.fate
index 37dea7d..650f253 100644
--- a/data/examples/the_thief/include/characters.fate
+++ b/data/examples/the_thief/include/characters.fate
@@ -10,57 +10,48 @@
(require include/locations.fate)
-(set_fields
- (variable oscar)
+(set_fields oscar
(name Oscar)
(agility 50)
(perception 50)
(money 20)
- (location room0)
)
+(add (ref oscar) room0.occupants)
-(set_fields
- (variable carla)
+(set_fields carla
(name Carla)
(agility 75)
(perception 35)
(money 7)
- (location room1)
)
+(add (ref carla) room1.occupants)
-(set_fields
- (variable simon)
+(set_fields simon
(name Simon)
(agility 35)
(perception 75)
(money 80)
- (location room1)
)
+(add (ref simon) room2.occupants)
-(set_fields
- (variable julie)
+(set_fields julie
(name Julie)
(agility 60)
(perception 60)
(money 90)
- (location room2)
)
+(add (ref julie) corridor.occupants)
-(set_fields
- (variable statue)
+
+(set_fields statue
(name ( A oddly human shaped statue, with clothes adorned ))
(agility 0)
(perception 0)
(money 30)
- (location corridor)
)
-
-;; Alright, but we clearly need to be able to point to variables using a type.
-;; like (pointer (variable carla)) -> pointer to variable of type character
-;; (a string, really) resolves to (variable carla), but allows characters to be
-;; put in a set, for example.
+(add (ref statue) corridor.occupants)
diff --git a/data/examples/the_thief/include/locations.fate b/data/examples/the_thief/include/locations.fate
index d7beb18..e46c504 100644
--- a/data/examples/the_thief/include/locations.fate
+++ b/data/examples/the_thief/include/locations.fate
@@ -1,2 +1,41 @@
(fate_version 1)
+(require type/location.fate)
+
+(declare_variable local location room0)
+(declare_variable local location room1)
+(declare_variable local location room2)
+(declare_variable local location corridor)
+
+(set_fields room0
+ (name ( Room 0 ))
+ (description
+ ( An luxurious bedroom, well lit. )
+ )
+ (luminosity 80)
+)
+
+(set_fields room1
+ (name ( Room 1 ))
+ (description
+ ( An overly large kitchen, unevenly lit. )
+ )
+ (luminosity 35)
+)
+
+(set_fields room2
+ (name ( Room 2 ))
+ (description
+ ( An tiny and messy study, unlit. )
+ )
+ (luminosity 0)
+)
+
+(set_fields corridor
+ (name Corridor)
+ (description
+ ( A long corridor, with many decorations, and many hiding places. )
+ )
+ (luminosity 50)
+)
+
diff --git a/data/examples/the_thief/include/type/character.fate b/data/examples/the_thief/include/type/character.fate
index 5882fd5..6278ad9 100644
--- a/data/examples/the_thief/include/type/character.fate
+++ b/data/examples/the_thief/include/type/character.fate
@@ -1,12 +1,12 @@
(fate_version 1)
(require stat.fate)
-(require location.fate)
(declare_dict_type character
(string name)
(stat agility)
(stat perception)
(int money)
- (location location)
)
+
+(declare_ref_type character character_ptr)
diff --git a/data/examples/the_thief/include/type/location.fate b/data/examples/the_thief/include/type/location.fate
index faec74a..9db494f 100644
--- a/data/examples/the_thief/include/type/location.fate
+++ b/data/examples/the_thief/include/type/location.fate
@@ -1,3 +1,15 @@
(fate_version 1)
-(declare_set_type string location)
+(require character.fate)
+
+(declare_set_type character_ptr occupants)
+(declare_subtype int luminosity)
+
+(declare_dict_type location
+ (string name)
+ (string description)
+ (luminosity luminosity)
+ (occupants occupants)
+)
+
+(declare_ref_type location location_ptr)
diff --git a/src/core/src/tonkadur/Main.java b/src/core/src/tonkadur/Main.java
index 21bc077..23666dd 100644
--- a/src/core/src/tonkadur/Main.java
+++ b/src/core/src/tonkadur/Main.java
@@ -14,7 +14,6 @@ public class Main
private Main () {};
public static void main (final String[] args)
- throws IOException
{
final World world;
final Context context;
@@ -22,9 +21,18 @@ public class Main
world = new World();
context = Context.build(args[0]);
- Utils.add_file_content(context.get_current_file(), context, world);
-
- System.out.println("Parsing completed.");
- System.out.println(world.toString());
+ try
+ {
+ Utils.add_file_content(context.get_current_file(), context, world);
+
+ System.out.println("Parsing completed.");
+ System.out.println(world.toString());
+ }
+ catch (final Exception e)
+ {
+ System.err.println("Parsing failed.");
+ System.err.println(world.toString());
+ e.printStackTrace();
+ }
}
}
diff --git a/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java b/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java
index 5a1d06e..3b49861 100644
--- a/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java
+++ b/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java
@@ -47,10 +47,10 @@ public class ConflictingTypeException extends ParsingError
sb.append(System.lineSeparator());
sb.append("Resulting type '");
- sb.append(given_type.get_name());
+ sb.append(given_type.toString());
sb.append("' ");
sb.append(" conflicts with the expected one ('");
- sb.append(expected_type.get_name());
+ sb.append(expected_type.toString());
sb.append("').");
return sb.toString();
diff --git a/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java b/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java
index 6ada2c3..20ab742 100644
--- a/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java
+++ b/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java
@@ -79,7 +79,7 @@ public class IncompatibleTypeException extends ParsingError
{
sb.append(System.lineSeparator());
sb.append("Recommended compatible type: ");
- sb.append(hint.get_name());
+ sb.append(hint.toString());
}
return sb.toString();
diff --git a/src/core/src/tonkadur/fate/v1/error/NotAValueMacroException.java b/src/core/src/tonkadur/fate/v1/error/NotAValueMacroException.java
new file mode 100644
index 0000000..b235ad9
--- /dev/null
+++ b/src/core/src/tonkadur/fate/v1/error/NotAValueMacroException.java
@@ -0,0 +1,53 @@
+package tonkadur.fate.v1.error;
+
+import tonkadur.error.ErrorLevel;
+
+import tonkadur.parser.Origin;
+import tonkadur.parser.ParsingError;
+
+public class NotAValueMacroException extends ParsingError
+{
+ /***************************************************************************/
+ /**** MEMBERS **************************************************************/
+ /***************************************************************************/
+ protected final String macro_name;
+
+ /***************************************************************************/
+ /**** PUBLIC ***************************************************************/
+ /***************************************************************************/
+ public NotAValueMacroException (final Origin origin, final String macro_name)
+ {
+ super
+ (
+ ErrorLevel.ERROR,
+ ErrorCategory.INVALID_USE,
+ origin
+ );
+
+ this.macro_name = macro_name;
+ }
+
+ @Override
+ public String toString ()
+ {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append(origin.toString());
+ sb.append(" ");
+ sb.append(error_category.toString());
+ sb.append(System.lineSeparator());
+
+ sb.append("Macro '");
+ sb.append(macro_name);
+ sb.append
+ (
+ "' is not defined as a single value and thus cannot be used as one."
+ );
+ sb.append(System.lineSeparator());
+ sb.append("Does it contain instructions?");
+ sb.append(System.lineSeparator());
+ sb.append("Is it a sequence of multiple values?");
+
+ return sb.toString();
+ }
+}
diff --git a/src/core/src/tonkadur/fate/v1/lang/Macro.java b/src/core/src/tonkadur/fate/v1/lang/Macro.java
index 7834bfc..6030663 100644
--- a/src/core/src/tonkadur/fate/v1/lang/Macro.java
+++ b/src/core/src/tonkadur/fate/v1/lang/Macro.java
@@ -1,10 +1,22 @@
package tonkadur.fate.v1.lang;
+import java.util.ArrayList;
+import java.util.List;
+
import tonkadur.parser.Origin;
import tonkadur.fate.v1.lang.meta.DeclaredEntity;
import tonkadur.fate.v1.lang.meta.InstructionNode;
import tonkadur.fate.v1.lang.meta.TypedEntryList;
+import tonkadur.fate.v1.lang.meta.ValueNode;
+
+import tonkadur.fate.v1.lang.type.Type;
+
+import tonkadur.fate.v1.lang.instruction.Display;
+import tonkadur.fate.v1.lang.instruction.InstructionList;
+
+import tonkadur.fate.v1.lang.valued_node.Cast;
+import tonkadur.fate.v1.lang.valued_node.ValueToText;
public class Macro extends DeclaredEntity
{
@@ -50,6 +62,71 @@ public class Macro extends DeclaredEntity
return root;
}
+ public List<Type> get_signature ()
+ {
+ final List<Type> result;
+
+ result = new ArrayList<Type>();
+
+ for (final TypedEntryList.TypedEntry entry: parameters.get_entries())
+ {
+ result.add(entry.get_type());
+ }
+
+ return result;
+ }
+
+ public ValueNode get_value_node_representation ()
+ {
+ final Cast result_cast;
+ InstructionList root_as_il;
+ InstructionNode instr;
+ ValueNode result;
+
+ if (!(root instanceof InstructionList))
+ {
+ return null;
+ }
+
+ root_as_il = (InstructionList) root;
+
+ if (root_as_il.get_instructions().size() != 1)
+ {
+ return null;
+ }
+
+ instr = root_as_il.get_instructions().get(0);
+
+ if (!(instr instanceof Display))
+ {
+ return null;
+ }
+
+ result = ((Display) instr).get_content();
+
+ if (!(result instanceof ValueToText))
+ {
+ return result;
+ }
+
+ result = ((ValueToText) result).get_value();
+
+ if (!(result instanceof Cast))
+ {
+ return result;
+ }
+
+ result_cast = (Cast) result;
+
+ if (result_cast.is_autogenerated())
+ {
+ return result_cast.get_parent();
+ }
+ else
+ {
+ return result;
+ }
+ }
/**** Compatibility ********************************************************/
/*
diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/AddElement.java b/src/core/src/tonkadur/fate/v1/lang/instruction/AddElement.java
index 9cc9b3b..775fa63 100644
--- a/src/core/src/tonkadur/fate/v1/lang/instruction/AddElement.java
+++ b/src/core/src/tonkadur/fate/v1/lang/instruction/AddElement.java
@@ -81,7 +81,12 @@ public class AddElement extends InstructionNode
collection_true_type = (CollectionType) collection_type;
collection_element_type = collection_true_type.get_content_type();
- if (element.get_type().can_be_used_as(collection_element_type))
+ if
+ (
+ element.get_type().can_be_used_as(collection_element_type)
+ ||
+ (element.get_type().try_merging_with(collection_element_type) != null)
+ )
{
return new AddElement(origin, element, collection);
}
diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/EventCall.java b/src/core/src/tonkadur/fate/v1/lang/instruction/EventCall.java
new file mode 100644
index 0000000..8706f9c
--- /dev/null
+++ b/src/core/src/tonkadur/fate/v1/lang/instruction/EventCall.java
@@ -0,0 +1,167 @@
+package tonkadur.fate.v1.lang.instruction;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import tonkadur.parser.Origin;
+import tonkadur.parser.ParsingError;
+
+import tonkadur.functional.Merge;
+
+import tonkadur.error.ErrorManager;
+
+import tonkadur.fate.v1.error.IncompatibleTypeException;
+import tonkadur.fate.v1.error.IncomparableTypeException;
+import tonkadur.fate.v1.error.InvalidArityException;
+
+import tonkadur.fate.v1.lang.Event;
+
+import tonkadur.fate.v1.lang.type.Type;
+
+import tonkadur.fate.v1.lang.meta.InstructionNode;
+import tonkadur.fate.v1.lang.meta.ValueNode;
+
+public class EventCall extends InstructionNode
+{
+ /***************************************************************************/
+ /**** MEMBERS **************************************************************/
+ /***************************************************************************/
+ protected final Event event;
+ protected final List<ValueNode> parameters;
+
+ /***************************************************************************/
+ /**** PROTECTED ************************************************************/
+ /***************************************************************************/
+ /**** Constructors *********************************************************/
+ protected EventCall
+ (
+ final Origin origin,
+ final Event event,
+ final List<ValueNode> parameters
+ )
+ {
+ super(origin);
+
+ this.event = event;
+ this.parameters = parameters;
+ }
+
+ /***************************************************************************/
+ /**** PUBLIC ***************************************************************/
+ /***************************************************************************/
+ /**** Constructors *********************************************************/
+ public static EventCall build
+ (
+ final Origin origin,
+ final Event event,
+ final List<ValueNode> parameters
+ )
+ throws Throwable
+ {
+ final List<Boolean> type_checks;
+ final List<Type> signature;
+
+ signature = event.get_signature();
+
+ if (parameters.size() != signature.size())
+ {
+ ErrorManager.handle
+ (
+ new InvalidArityException
+ (
+ origin,
+ parameters.size(),
+ signature.size(),
+ signature.size()
+ )
+ );
+ }
+
+ (new Merge<Type, ValueNode, Boolean>()
+ {
+ @Override
+ public Boolean risky_lambda (final Type t, final ValueNode p)
+ throws ParsingError
+ {
+ if ((t == null) || (p == null))
+ {
+ return Boolean.FALSE;
+ }
+ else
+ {
+ final Type hint;
+
+ if (p.get_type().can_be_used_as(t))
+ {
+ return Boolean.TRUE;
+ }
+
+ if (p.get_type().try_merging_with(t) != null)
+ {
+ return Boolean.TRUE;
+ }
+
+ ErrorManager.handle
+ (
+ new IncompatibleTypeException
+ (
+ p.get_origin(),
+ p.get_type(),
+ t
+ )
+ );
+
+ hint = (Type) p.get_type().generate_comparable_to(t);
+
+ if (hint.equals(Type.ANY))
+ {
+ ErrorManager.handle
+ (
+ new IncomparableTypeException
+ (
+ p.get_origin(),
+ p.get_type(),
+ t
+ )
+ );
+ }
+
+ return Boolean.FALSE;
+ }
+ }
+ }).risky_merge(signature, parameters);
+
+ return new EventCall(origin, event, parameters);
+ }
+
+ /**** Accessors ************************************************************/
+ public Event get_event ()
+ {
+ return event;
+ }
+
+ public List<ValueNode> get_parameters ()
+ {
+ return parameters;
+ }
+
+ /**** Misc. ****************************************************************/
+ @Override
+ public String toString ()
+ {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append("(EventCall (");
+ sb.append(event.get_name());
+
+ for (final ValueNode param: parameters)
+ {
+ sb.append(" ");
+ sb.append(param.toString());
+ }
+
+ sb.append("))");
+
+ return sb.toString();
+ }
+}
diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/MacroCall.java b/src/core/src/tonkadur/fate/v1/lang/instruction/MacroCall.java
new file mode 100644
index 0000000..f00c9f2
--- /dev/null
+++ b/src/core/src/tonkadur/fate/v1/lang/instruction/MacroCall.java
@@ -0,0 +1,167 @@
+package tonkadur.fate.v1.lang.instruction;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import tonkadur.parser.Origin;
+import tonkadur.parser.ParsingError;
+
+import tonkadur.functional.Merge;
+
+import tonkadur.error.ErrorManager;
+
+import tonkadur.fate.v1.error.IncompatibleTypeException;
+import tonkadur.fate.v1.error.IncomparableTypeException;
+import tonkadur.fate.v1.error.InvalidArityException;
+
+import tonkadur.fate.v1.lang.Macro;
+
+import tonkadur.fate.v1.lang.type.Type;
+
+import tonkadur.fate.v1.lang.meta.InstructionNode;
+import tonkadur.fate.v1.lang.meta.ValueNode;
+
+public class MacroCall extends InstructionNode
+{
+ /***************************************************************************/
+ /**** MEMBERS **************************************************************/
+ /***************************************************************************/
+ protected final Macro macro;
+ protected final List<ValueNode> parameters;
+
+ /***************************************************************************/
+ /**** PROTECTED ************************************************************/
+ /***************************************************************************/
+ /**** Constructors *********************************************************/
+ protected MacroCall
+ (
+ final Origin origin,
+ final Macro macro,
+ final List<ValueNode> parameters
+ )
+ {
+ super(origin);
+
+ this.macro = macro;
+ this.parameters = parameters;
+ }
+
+ /***************************************************************************/
+ /**** PUBLIC ***************************************************************/
+ /***************************************************************************/
+ /**** Constructors *********************************************************/
+ public static MacroCall build
+ (
+ final Origin origin,
+ final Macro macro,
+ final List<ValueNode> parameters
+ )
+ throws Throwable
+ {
+ final List<Boolean> type_checks;
+ final List<Type> signature;
+
+ signature = macro.get_signature();
+
+ if (parameters.size() != signature.size())
+ {
+ ErrorManager.handle
+ (
+ new InvalidArityException
+ (
+ origin,
+ parameters.size(),
+ signature.size(),
+ signature.size()
+ )
+ );
+ }
+
+ (new Merge<Type, ValueNode, Boolean>()
+ {
+ @Override
+ public Boolean risky_lambda (final Type t, final ValueNode p)
+ throws ParsingError
+ {
+ if ((t == null) || (p == null))
+ {
+ return Boolean.FALSE;
+ }
+ else
+ {
+ final Type hint;
+
+ if (p.get_type().can_be_used_as(t))
+ {
+ return Boolean.TRUE;
+ }
+
+ if (p.get_type().try_merging_with(t) != null)
+ {
+ return Boolean.TRUE;
+ }
+
+ ErrorManager.handle
+ (
+ new IncompatibleTypeException
+ (
+ p.get_origin(),
+ p.get_type(),
+ t
+ )
+ );
+
+ hint = (Type) p.get_type().generate_comparable_to(t);
+
+ if (hint.equals(Type.ANY))
+ {
+ ErrorManager.handle
+ (
+ new IncomparableTypeException
+ (
+ p.get_origin(),
+ p.get_type(),
+ t
+ )
+ );
+ }
+
+ return Boolean.FALSE;
+ }
+ }
+ }).risky_merge(signature, parameters);
+
+ return new MacroCall(origin, macro, parameters);
+ }
+
+ /**** Accessors ************************************************************/
+ public Macro get_macro ()
+ {
+ return macro;
+ }
+
+ public List<ValueNode> get_parameters ()
+ {
+ return parameters;
+ }
+
+ /**** Misc. ****************************************************************/
+ @Override
+ public String toString ()
+ {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append("(MacroCall (");
+ sb.append(macro.get_name());
+
+ for (final ValueNode param: parameters)
+ {
+ sb.append(" ");
+ sb.append(param.toString());
+ }
+
+ sb.append("))");
+
+ return sb.toString();
+ }
+}
diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveAllOfElement.java b/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveAllOfElement.java
index 937138c..0f6aba5 100644
--- a/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveAllOfElement.java
+++ b/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveAllOfElement.java
@@ -81,7 +81,12 @@ public class RemoveAllOfElement extends InstructionNode
collection_true_type = (CollectionType) collection_type;
collection_element_type = collection_true_type.get_content_type();
- if (element.get_type().can_be_used_as(collection_element_type))
+ if
+ (
+ element.get_type().can_be_used_as(collection_element_type)
+ ||
+ (element.get_type().try_merging_with(collection_element_type) != null)
+ )
{
return new RemoveAllOfElement(origin, element, collection);
}
diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveElement.java b/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveElement.java
index c05ed5e..136524b 100644
--- a/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveElement.java
+++ b/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveElement.java
@@ -81,7 +81,12 @@ public class RemoveElement extends InstructionNode
collection_true_type = (CollectionType) collection_type;
collection_element_type = collection_true_type.get_content_type();
- if (element.get_type().can_be_used_as(collection_element_type))
+ if
+ (
+ element.get_type().can_be_used_as(collection_element_type)
+ ||
+ (element.get_type().try_merging_with(collection_element_type) != null)
+ )
{
return new RemoveElement(origin, element, collection);
}
diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/SetValue.java b/src/core/src/tonkadur/fate/v1/lang/instruction/SetValue.java
index 9b50b47..efee224 100644
--- a/src/core/src/tonkadur/fate/v1/lang/instruction/SetValue.java
+++ b/src/core/src/tonkadur/fate/v1/lang/instruction/SetValue.java
@@ -58,11 +58,17 @@ public class SetValue extends InstructionNode
value_reference_type = value_reference.get_type();
- if (element.get_type().can_be_used_as(value_reference_type))
+ if
+ (
+ element.get_type().can_be_used_as(value_reference_type)
+ ||
+ (element.get_type().try_merging_with(value_reference_type) != null)
+ )
{
return new SetValue(origin, element, value_reference);
}
+
ErrorManager.handle
(
new ConflictingTypeException
diff --git a/src/core/src/tonkadur/fate/v1/lang/type/Type.java b/src/core/src/tonkadur/fate/v1/lang/type/Type.java
index 87ef5fe..ec961d8 100644
--- a/src/core/src/tonkadur/fate/v1/lang/type/Type.java
+++ b/src/core/src/tonkadur/fate/v1/lang/type/Type.java
@@ -124,6 +124,26 @@ public class Type extends DeclaredEntity
return (parent == null);
}
+ public Type try_merging_with (final Type t)
+ {
+ if (t.get_base_type() != get_base_type())
+ {
+ return null;
+ }
+
+ if (t.is_base_type())
+ {
+ return this;
+ }
+
+ if (is_base_type())
+ {
+ return t;
+ }
+
+ return null;
+ }
+
/**** Compatibility ********************************************************/
public boolean can_be_used_as (final Type t)
{
diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/Cast.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/Cast.java
index 62a258f..9a084ce 100644
--- a/src/core/src/tonkadur/fate/v1/lang/valued_node/Cast.java
+++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/Cast.java
@@ -83,6 +83,7 @@ public class Cast extends ValueNode
/**** MEMBERS **************************************************************/
/***************************************************************************/
protected final ValueNode value;
+ protected final boolean is_autogenerated;
/***************************************************************************/
/**** PROTECTED ************************************************************/
@@ -92,11 +93,13 @@ public class Cast extends ValueNode
(
final Origin origin,
final Type to,
- final ValueNode value
+ final ValueNode value,
+ final boolean is_autogenerated
)
{
super(origin, to);
this.value = value;
+ this.is_autogenerated = is_autogenerated;
}
/***************************************************************************/
@@ -107,7 +110,8 @@ public class Cast extends ValueNode
(
final Origin origin,
final Type to,
- final ValueNode value
+ final ValueNode value,
+ final boolean is_autogenerated
)
throws
IncompatibleTypeException,
@@ -131,7 +135,7 @@ public class Cast extends ValueNode
)
)
{
- return new Cast(origin, to, value);
+ return new Cast(origin, to, value, is_autogenerated);
}
hint = (Type) value.get_type().generate_comparable_to(to);
@@ -156,11 +160,21 @@ public class Cast extends ValueNode
);
}
- return new Cast(origin, hint, value);
+ return new Cast(origin, hint, value, is_autogenerated);
}
/**** Accessors ************************************************************/
+ public ValueNode get_parent ()
+ {
+ return value;
+ }
+
+ public boolean is_autogenerated ()
+ {
+ return is_autogenerated;
+ }
+
/**** Misc. ****************************************************************/
@Override
public String toString ()
diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/CondValue.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/CondValue.java
index fa8dcaf..0cdb45e 100644
--- a/src/core/src/tonkadur/fate/v1/lang/valued_node/CondValue.java
+++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/CondValue.java
@@ -55,7 +55,7 @@ public class CondValue extends ValueNode
IncomparableTypeException
{
final Type first_type;
- Type hint;
+ Type candidate_hint, hint;
first_type = branches.get(0).get_cdr().get_type();
hint = first_type;
@@ -80,6 +80,15 @@ public class CondValue extends ValueNode
continue;
}
+ candidate_hint = entry.get_cdr().get_type().try_merging_with(hint);
+
+ if (candidate_hint != null)
+ {
+ hint = candidate_hint;
+
+ continue;
+ }
+
ErrorManager.handle
(
new ConflictingTypeException
diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/CountOperator.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/CountOperator.java
index 7eacc40..3b7787c 100644
--- a/src/core/src/tonkadur/fate/v1/lang/valued_node/CountOperator.java
+++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/CountOperator.java
@@ -80,7 +80,12 @@ public class CountOperator extends ValueNode
collection_true_type = (CollectionType) collection_type;
collection_element_type = collection_true_type.get_content_type();
- if (element.get_type().can_be_used_as(collection_element_type))
+ if
+ (
+ element.get_type().can_be_used_as(collection_element_type)
+ ||
+ (element.get_type().try_merging_with(collection_element_type) != null)
+ )
{
return new CountOperator(origin, element, collection);
}
diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/IfElseValue.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/IfElseValue.java
index 1b40f73..a54c1b6 100644
--- a/src/core/src/tonkadur/fate/v1/lang/valued_node/IfElseValue.java
+++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/IfElseValue.java
@@ -59,7 +59,7 @@ public class IfElseValue extends ValueNode
ConflictingTypeException,
IncomparableTypeException
{
- final Type hint;
+ Type hint;
final Type if_true_type;
final Type if_false_type;
@@ -85,6 +85,13 @@ public class IfElseValue extends ValueNode
new IfElseValue(origin, if_true_type, condition, if_true, if_false);
}
+ hint = if_true_type.try_merging_with(if_false_type);
+
+ if (hint != null)
+ {
+ return new IfElseValue(origin, hint, condition, if_true, if_false);
+ }
+
ErrorManager.handle
(
new ConflictingTypeException
diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/IsMemberOperator.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/IsMemberOperator.java
index 7701614..b0c8fa8 100644
--- a/src/core/src/tonkadur/fate/v1/lang/valued_node/IsMemberOperator.java
+++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/IsMemberOperator.java
@@ -80,7 +80,12 @@ public class IsMemberOperator extends ValueNode
collection_true_type = (CollectionType) collection_type;
collection_element_type = collection_true_type.get_content_type();
- if (element.get_type().can_be_used_as(collection_element_type))
+ if
+ (
+ element.get_type().can_be_used_as(collection_element_type)
+ ||
+ (element.get_type().try_merging_with(collection_element_type) != null)
+ )
{
return new IsMemberOperator(origin, element, collection);
}
diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/MacroValueCall.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/MacroValueCall.java
new file mode 100644
index 0000000..1405e6f
--- /dev/null
+++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/MacroValueCall.java
@@ -0,0 +1,185 @@
+package tonkadur.fate.v1.lang.valued_node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import tonkadur.parser.Origin;
+import tonkadur.parser.ParsingError;
+
+import tonkadur.functional.Merge;
+
+import tonkadur.error.ErrorManager;
+
+import tonkadur.fate.v1.error.IncompatibleTypeException;
+import tonkadur.fate.v1.error.IncomparableTypeException;
+import tonkadur.fate.v1.error.InvalidArityException;
+import tonkadur.fate.v1.error.NotAValueMacroException;
+
+import tonkadur.fate.v1.lang.Macro;
+
+import tonkadur.fate.v1.lang.type.Type;
+
+import tonkadur.fate.v1.lang.meta.ValueNode;
+
+public class MacroValueCall extends ValueNode
+{
+ /***************************************************************************/
+ /**** MEMBERS **************************************************************/
+ /***************************************************************************/
+ protected final Macro macro;
+ protected final ValueNode act_as;
+ protected final List<ValueNode> parameters;
+
+ /***************************************************************************/
+ /**** PROTECTED ************************************************************/
+ /***************************************************************************/
+ /**** Constructors *********************************************************/
+ protected MacroValueCall
+ (
+ final Origin origin,
+ final Macro macro,
+ final List<ValueNode> parameters,
+ final ValueNode act_as
+ )
+ {
+ super(origin, act_as.get_type());
+
+ this.macro = macro;
+ this.parameters = parameters;
+ this.act_as = act_as;
+ }
+
+ /***************************************************************************/
+ /**** PUBLIC ***************************************************************/
+ /***************************************************************************/
+ /**** Constructors *********************************************************/
+ public static MacroValueCall build
+ (
+ final Origin origin,
+ final Macro macro,
+ final List<ValueNode> parameters
+ )
+ throws Throwable
+ {
+ ValueNode act_as;
+ final List<Type> signature;
+
+ act_as = macro.get_value_node_representation();
+
+ if (act_as == null)
+ {
+ ErrorManager.handle
+ (
+ new NotAValueMacroException(origin, macro.get_name())
+ );
+ }
+
+ signature = macro.get_signature();
+
+ if (parameters.size() != signature.size())
+ {
+ ErrorManager.handle
+ (
+ new InvalidArityException
+ (
+ origin,
+ parameters.size(),
+ signature.size(),
+ signature.size()
+ )
+ );
+ }
+
+ (new Merge<Type, ValueNode, Boolean>()
+ {
+ @Override
+ public Boolean risky_lambda (final Type t, final ValueNode p)
+ throws ParsingError
+ {
+ if ((t == null) || (p == null))
+ {
+ return Boolean.FALSE;
+ }
+ else
+ {
+ final Type hint;
+
+ if (p.get_type().can_be_used_as(t))
+ {
+ return Boolean.TRUE;
+ }
+
+ if (p.get_type().try_merging_with(t) != null)
+ {
+ return Boolean.TRUE;
+ }
+
+ ErrorManager.handle
+ (
+ new IncompatibleTypeException
+ (
+ p.get_origin(),
+ p.get_type(),
+ t
+ )
+ );
+
+ hint = (Type) p.get_type().generate_comparable_to(t);
+
+ if (hint.equals(Type.ANY))
+ {
+ ErrorManager.handle
+ (
+ new IncomparableTypeException
+ (
+ p.get_origin(),
+ p.get_type(),
+ t
+ )
+ );
+ }
+
+ return Boolean.FALSE;
+ }
+ }
+ }).risky_merge(signature, parameters);
+
+ return new MacroValueCall(origin, macro, parameters, act_as);
+ }
+
+ /**** Accessors ************************************************************/
+ public Macro get_macro ()
+ {
+ return macro;
+ }
+
+ public ValueNode get_actual_value_node ()
+ {
+ return act_as;
+ }
+
+ public List<ValueNode> get_parameters ()
+ {
+ return parameters;
+ }
+
+ /**** Misc. ****************************************************************/
+ @Override
+ public String toString ()
+ {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append("(MacroValueCall (");
+ sb.append(macro.get_name());
+
+ for (final ValueNode param: parameters)
+ {
+ sb.append(" ");
+ sb.append(param.toString());
+ }
+
+ sb.append("))");
+
+ return sb.toString();
+ }
+}
diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/Operation.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/Operation.java
index 87ea676..8b7e2b2 100644
--- a/src/core/src/tonkadur/fate/v1/lang/valued_node/Operation.java
+++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/Operation.java
@@ -127,19 +127,26 @@ public class Operation extends ValueNode
continue;
}
+ previous_computed_type = computed_type;
+ computed_type = computed_type.try_merging_with(operand_type);
+
+ if (computed_type != null)
+ {
+ continue;
+ }
+
ErrorManager.handle
(
new IncompatibleTypeException
(
operand.get_origin(),
operand_type,
- computed_type
+ previous_computed_type
)
);
- previous_computed_type = computed_type;
computed_type =
- (Type) computed_type.generate_comparable_to(operand_type);
+ (Type) previous_computed_type.generate_comparable_to(operand_type);
if (computed_type.equals(Type.ANY))
{
diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/RefOperator.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/RefOperator.java
index e6d03b2..d99bb76 100644
--- a/src/core/src/tonkadur/fate/v1/lang/valued_node/RefOperator.java
+++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/RefOperator.java
@@ -2,10 +2,9 @@ package tonkadur.fate.v1.lang.valued_node;
import tonkadur.parser.Origin;
-import tonkadur.fate.v1.lang.Variable;
-
import tonkadur.fate.v1.lang.type.RefType;
+import tonkadur.fate.v1.lang.meta.Reference;
import tonkadur.fate.v1.lang.meta.ValueNode;
public class RefOperator extends ValueNode
@@ -13,16 +12,16 @@ public class RefOperator extends ValueNode
/***************************************************************************/
/**** MEMBERS **************************************************************/
/***************************************************************************/
- protected final Variable variable;
+ protected final Reference referred;
/***************************************************************************/
/**** PROTECTED ************************************************************/
/***************************************************************************/
/**** Constructors *********************************************************/
- public RefOperator (final Origin origin, final Variable variable)
+ public RefOperator (final Origin origin, final Reference referred)
{
- super(origin, new RefType(origin, variable.get_type(), "auto generated"));
- this.variable = variable;
+ super(origin, new RefType(origin, referred.get_type(), "auto generated"));
+ this.referred = referred;
}
/***************************************************************************/
@@ -40,7 +39,7 @@ public class RefOperator extends ValueNode
sb.append(origin.toString());
sb.append("(Ref ");
- sb.append(variable.get_name());
+ sb.append(referred.get_name());
sb.append(") ");
return sb.toString();
diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/TextWithEffect.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/TextWithEffect.java
index 705ef64..b1fd88a 100644
--- a/src/core/src/tonkadur/fate/v1/lang/valued_node/TextWithEffect.java
+++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/TextWithEffect.java
@@ -4,6 +4,15 @@ import java.util.ArrayList;
import java.util.List;
import tonkadur.parser.Origin;
+import tonkadur.parser.ParsingError;
+
+import tonkadur.functional.Merge;
+
+import tonkadur.error.ErrorManager;
+
+import tonkadur.fate.v1.error.IncompatibleTypeException;
+import tonkadur.fate.v1.error.IncomparableTypeException;
+import tonkadur.fate.v1.error.InvalidArityException;
import tonkadur.fate.v1.lang.TextEffect;
@@ -44,20 +53,6 @@ public class TextWithEffect extends TextNode
/**** PUBLIC ***************************************************************/
/***************************************************************************/
/**** Constructors *********************************************************/
- public TextWithEffect
- (
- final Origin origin,
- final TextEffect effect,
- final TextNode text
- )
- {
- super(origin);
-
- this.effect = effect;
- this.parameters = new ArrayList<ValueNode>();
- this.text = text;
- }
-
public static TextWithEffect build
(
final Origin origin,
@@ -65,8 +60,80 @@ public class TextWithEffect extends TextNode
final List<ValueNode> parameters,
final TextNode text
)
+ throws Throwable
{
- /* TODO: Checks */
+ final List<Type> signature;
+
+ signature = effect.get_signature();
+
+ if (parameters.size() != signature.size())
+ {
+ ErrorManager.handle
+ (
+ new InvalidArityException
+ (
+ origin,
+ parameters.size(),
+ signature.size(),
+ signature.size()
+ )
+ );
+ }
+
+ (new Merge<Type,ValueNode,Boolean>()
+ {
+ @Override
+ public Boolean risky_lambda (final Type t, final ValueNode p)
+ throws ParsingError
+ {
+ if ((t == null) || (p == null))
+ {
+ return Boolean.FALSE;
+ }
+ else
+ {
+ final Type hint;
+
+ if (p.get_type().can_be_used_as(t))
+ {
+ return Boolean.TRUE;
+ }
+
+ if (p.get_type().try_merging_with(t) != null)
+ {
+ return Boolean.TRUE;
+ }
+
+ ErrorManager.handle
+ (
+ new IncompatibleTypeException
+ (
+ p.get_origin(),
+ p.get_type(),
+ t
+ )
+ );
+
+ hint = (Type) p.get_type().generate_comparable_to(t);
+
+ if (hint.equals(Type.ANY))
+ {
+ ErrorManager.handle
+ (
+ new IncomparableTypeException
+ (
+ p.get_origin(),
+ p.get_type(),
+ t
+ )
+ );
+ }
+
+ return Boolean.FALSE;
+ }
+ }
+ }).risky_merge(signature, parameters);
+
return new TextWithEffect(origin, effect, parameters, text);
}
diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/ValueToText.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/ValueToText.java
index fcfac27..ec69776 100644
--- a/src/core/src/tonkadur/fate/v1/lang/valued_node/ValueToText.java
+++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/ValueToText.java
@@ -49,11 +49,12 @@ public class ValueToText extends TextNode
return
new ValueToText
(
- new Cast
+ Cast.build
(
value.get_origin(),
Type.STRING,
- value
+ value,
+ true
)
);
}
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
index 1efccd1..3ec977a 100644
--- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
+++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
@@ -591,25 +591,89 @@ returns [InstructionNode result]
);
}
- | SET_FIELDS_KW WS+ value_reference WS * field_value_list WS* R_PAREN
+ | SET_FIELDS_KW WS+ value_reference WS* field_value_list WS* R_PAREN
{
- /* TODO */
+ final Origin origin;
+ final List<InstructionNode> operations;
+
+ origin =
+ CONTEXT.get_origin_at
+ (
+ ($SET_FIELDS_KW.getLine()),
+ ($SET_FIELDS_KW.getCharPositionInLine())
+ );
+
+ operations = new ArrayList<InstructionNode>();
+
+ for
+ (
+ final Cons<Origin, Cons<String, ValueNode>> entry:
+ ($field_value_list.result)
+ )
+ {
+ operations.add
+ (
+ SetValue.build
+ (
+ entry.get_car(),
+ entry.get_cdr().get_cdr(),
+ FieldReference.build
+ (
+ entry.get_car(),
+ ($value_reference.result),
+ entry.get_cdr().get_car()
+ )
+ )
+ );
+ }
- $result = null;
+ $result = new InstructionList(origin, operations);
}
| EVENT_KW WS+ WORD WS+ value_list WS* R_PAREN
{
- /* TODO */
+ final Origin origin;
+ final Event event;
- $result = null;
+ origin =
+ CONTEXT.get_origin_at
+ (
+ ($EVENT_KW.getLine()),
+ ($EVENT_KW.getCharPositionInLine())
+ );
+
+ event = WORLD.events().get(origin, ($WORD.text));
+
+ $result =
+ EventCall.build
+ (
+ origin,
+ event,
+ ($value_list.result)
+ );
}
| MACRO_KW WS+ WORD WS+ value_list WS* R_PAREN
{
- /* TODO */
+ final Origin origin;
+ final Macro macro;
+
+ origin =
+ CONTEXT.get_origin_at
+ (
+ ($MACRO_KW.getLine()),
+ ($MACRO_KW.getCharPositionInLine())
+ );
+
+ macro = WORLD.macros().get(origin, ($WORD.text));
- $result = null;
+ $result =
+ MacroCall.build
+ (
+ origin,
+ macro,
+ ($value_list.result)
+ );
}
| SEQUENCE_KW WS+ WORD WS* R_PAREN
@@ -956,7 +1020,7 @@ returns [TextNode result]:
);
$result =
- new TextWithEffect
+ TextWithEffect.build
(
CONTEXT.get_origin_at
(
@@ -964,6 +1028,7 @@ returns [TextNode result]:
($WORD.getCharPositionInLine())
),
effect,
+ new ArrayList<ValueNode>(),
($paragraph.result)
);
}
@@ -1550,7 +1615,7 @@ returns [ValueNode result]
);
$result =
- new TextWithEffect
+ TextWithEffect.build
(
CONTEXT.get_origin_at
(
@@ -1558,6 +1623,7 @@ returns [ValueNode result]
($WORD.getCharPositionInLine())
),
effect,
+ new ArrayList<ValueNode>(),
($paragraph.result)
);
}
@@ -1663,6 +1729,20 @@ returns [ValueNode result]
$result = ($math_expression.result);
}
+ | REF_KW WS+ value_reference WS* R_PAREN
+ {
+ $result =
+ new RefOperator
+ (
+ CONTEXT.get_origin_at
+ (
+ ($REF_KW.getLine()),
+ ($REF_KW.getCharPositionInLine())
+ ),
+ ($value_reference.result)
+ );
+ }
+
| CAST_KW WS+ WORD WS+ value WS* R_PAREN
{
final Origin target_type_origin;
@@ -1686,7 +1766,8 @@ returns [ValueNode result]
($CAST_KW.getCharPositionInLine())
),
target_type,
- ($value.result)
+ ($value.result),
+ false
);
}
@@ -1724,6 +1805,29 @@ returns [ValueNode result]
}
}
+ | MACRO_KW WS+ WORD WS+ value_list WS* R_PAREN
+ {
+ final Origin origin;
+ final Macro macro;
+
+ origin =
+ CONTEXT.get_origin_at
+ (
+ ($MACRO_KW.getLine()),
+ ($MACRO_KW.getCharPositionInLine())
+ );
+
+ macro = WORLD.macros().get(origin, ($WORD.text));
+
+ $result =
+ MacroValueCall.build
+ (
+ origin,
+ macro,
+ ($value_list.result)
+ );
+ }
+
| value_reference
{
$result = ($value_reference.result);
@@ -1877,6 +1981,52 @@ returns [Reference result]
}
}
}
+
+ | WORD
+ {
+ final Origin target_var_origin;
+ final Variable target_var;
+ final String[] subrefs;
+
+ subrefs = ($WORD.text).split("\\.");
+
+ target_var_origin =
+ CONTEXT.get_origin_at
+ (
+ ($WORD.getLine()),
+ ($WORD.getCharPositionInLine())
+ );
+
+ target_var = WORLD.variables().get(target_var_origin, subrefs[0]);
+
+ $result =
+ new VariableReference
+ (
+ CONTEXT.get_origin_at
+ (
+ ($WORD.getLine()),
+ ($WORD.getCharPositionInLine())
+ ),
+ target_var
+ );
+
+ if (subrefs.length > 1)
+ {
+ final List<String> subrefs_list;
+
+ subrefs_list = new ArrayList(Arrays.asList(subrefs));
+
+ subrefs_list.remove(0);
+
+ $result =
+ FieldReference.build
+ (
+ target_var_origin,
+ ($result),
+ subrefs_list
+ );
+ }
+ }
;
catch [final Throwable e]
{
diff --git a/src/core/src/tonkadur/functional/Merge.java b/src/core/src/tonkadur/functional/Merge.java
index 29d37c5..5d5dcb8 100644
--- a/src/core/src/tonkadur/functional/Merge.java
+++ b/src/core/src/tonkadur/functional/Merge.java
@@ -39,8 +39,47 @@ public class Merge <Input0, Input1, Output>
return output;
}
+ public List<Output> risky_merge
+ (
+ final List<Input0> i0,
+ final List<Input1> i1
+ )
+ throws Throwable
+ {
+ final int result_size;
+ final List<Output> output;
+ final Iterator<Input0> it0;
+ final Iterator<Input1> it1;
+
+ result_size = Math.max(i0.size(), i1.size());
+ output = new ArrayList<Output>(result_size);
+
+ it0 = i0.iterator();
+ it1 = i1.iterator();
+
+ for (int i = 0; i < result_size; ++i)
+ {
+ output.add
+ (
+ risky_lambda
+ (
+ it0.hasNext() ? it0.next() : null,
+ it1.hasNext() ? it1.next() : null
+ )
+ );
+ }
+
+ return output;
+ }
+
protected Output lambda (final Input0 i0, final Input1 i1)
{
return null;
}
+
+ protected Output risky_lambda (final Input0 i0, final Input1 i1)
+ throws Throwable
+ {
+ return null;
+ }
}