| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-04 18:01:58 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-04 18:01:58 +0200 |
| commit | 003323c886102a389fee7912cf8a46dc5b53012c (patch) | |
| tree | 0eac908ef7119cc27fb0fac63cf43187a0b5889b | |
| parent | 9246aeb13007bcb92544b3ef1486552dbf0803ee (diff) | |
...
14 files changed, 686 insertions, 87 deletions
diff --git a/src/core/src/tonkadur/Main.java b/src/core/src/tonkadur/Main.java index 76790e9..c8f8f1b 100644 --- a/src/core/src/tonkadur/Main.java +++ b/src/core/src/tonkadur/Main.java @@ -2,6 +2,8 @@ package tonkadur; import java.io.IOException; +import tonkadur.fate.v1.lang.World; + import tonkadur.fate.v1.Utils; public class Main @@ -12,6 +14,10 @@ public class Main public static void main (final String[] args) throws IOException { - Utils.parse_file(args[0]); + final World world; + + world = new World(); + + Utils.add_file_content(args[0], world); } } diff --git a/src/core/src/tonkadur/fate/v1/Utils.java b/src/core/src/tonkadur/fate/v1/Utils.java index 048b3f2..562adee 100644 --- a/src/core/src/tonkadur/fate/v1/Utils.java +++ b/src/core/src/tonkadur/fate/v1/Utils.java @@ -29,6 +29,7 @@ public class Utils lexer = new FateLexer(CharStreams.fromFileName(filename)); tokens = new CommonTokenStream(lexer); parser = new FateParser(tokens); + parser.fate_file(world); } } diff --git a/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java new file mode 100644 index 0000000..d0837a7 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java @@ -0,0 +1,64 @@ +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 ConflictingDeclarationException extends ParsingError +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final DeclaredEntity new_declaration; + protected final DeclaredEntity original_declaration; + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + public ConflictingDeclarationException + ( + final DeclaredEntity new_declaration, + final DeclaredEntity original_declaration + ) + { + super + ( + ErrorLevel.ERROR, + ErrorCategory.CONFLICTING_DECLARATION, + 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("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(" conflicts 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/TypeAlreadyDeclaredException.java b/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java index 4050d1e..066bbe6 100644 --- a/src/core/src/tonkadur/fate/v1/error/TypeAlreadyDeclaredException.java +++ b/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java @@ -5,26 +5,26 @@ import tonkadur.error.ErrorLevel; import tonkadur.parser.Origin; import tonkadur.parser.ParsingError; -import tonkadur.fate.v1.lang.Type; +import tonkadur.fate.v1.lang.meta.DeclaredEntity; -public class TypeAlreadyDeclaredException extends ParsingError +public class DuplicateDeclarationException extends ParsingError { /***************************************************************************/ /**** MEMBERS **************************************************************/ /***************************************************************************/ - protected final Type original_type; + protected final DeclaredEntity original_declaration; /***************************************************************************/ /**** PUBLIC ***************************************************************/ /***************************************************************************/ - public TypeAlreadyDeclaredException + public DuplicateDeclarationException ( final Origin origin, - final Type original_type + final DeclaredEntity original_declaration ) { super(ErrorLevel.WARNING, ErrorCategory.DUPLICATE_DECLARATION, origin); - this.original_type = original_type; + this.original_declaration = original_declaration; } @Override @@ -33,12 +33,14 @@ public class TypeAlreadyDeclaredException extends ParsingError final StringBuilder sb = new StringBuilder(); sb.append(origin.get_context().toString()); - sb.append("Declaration for type '"); - sb.append(original_type.get_name()); + 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(" when it was already declared at "); - sb.append(original_type.get_origin().get_location().toString()); + sb.append(original_declaration.get_origin().get_location().toString()); sb.append("."); return sb.toString(); diff --git a/src/core/src/tonkadur/fate/v1/error/ErrorCategory.java b/src/core/src/tonkadur/fate/v1/error/ErrorCategory.java index f56b6d5..ef1396e 100644 --- a/src/core/src/tonkadur/fate/v1/error/ErrorCategory.java +++ b/src/core/src/tonkadur/fate/v1/error/ErrorCategory.java @@ -4,7 +4,7 @@ class ErrorCategory extends tonkadur.error.ErrorCategory { public static final ErrorCategory DUPLICATE_DECLARATION; public static final ErrorCategory CONFLICTING_DECLARATION; - public static final ErrorCategory UNDECLARED; + public static final ErrorCategory MISSING_DECLARATION; public static final ErrorCategory UNKNOWN_SEQUENCE; public static final ErrorCategory INCORRECT_TYPE; public static final ErrorCategory INCOMPATIBLE_TYPE; @@ -13,7 +13,7 @@ class ErrorCategory extends tonkadur.error.ErrorCategory { DUPLICATE_DECLARATION = new ErrorCategory("duplicate_declaration"); CONFLICTING_DECLARATION = new ErrorCategory("conflicting_declaration"); - UNDECLARED = new ErrorCategory("undeclared"); + MISSING_DECLARATION = new ErrorCategory("missing_declaration"); UNKNOWN_SEQUENCE = new ErrorCategory("unknown_sequence"); INCORRECT_TYPE = new ErrorCategory("incorrect_type"); INCOMPATIBLE_TYPE = new ErrorCategory("incompatible_type"); diff --git a/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java new file mode 100644 index 0000000..582f593 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java @@ -0,0 +1,64 @@ +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 IncompatibleDeclarationException extends ParsingError +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final DeclaredEntity new_declaration; + protected final DeclaredEntity original_declaration; + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + public IncompatibleDeclarationException + ( + final DeclaredEntity new_declaration, + final DeclaredEntity original_declaration + ) + { + super + ( + ErrorLevel.ERROR, + ErrorCategory.CONFLICTING_DECLARATION, + 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("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 incompatible 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/MissingDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java new file mode 100644 index 0000000..f564fbe --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java @@ -0,0 +1,47 @@ +package tonkadur.fate.v1.error; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +public class MissingDeclarationException extends ParsingError +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final String type_name; + protected final String name; + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + public MissingDeclarationException + ( + final Origin origin, + final String type_name, + final String name + ) + { + super(ErrorLevel.ERROR, ErrorCategory.MISSING_DECLARATION, origin); + this.type_name = type_name; + this.name = name; + } + + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append(origin.get_context().toString()); + sb.append("Unknown "); + sb.append(type_name); + sb.append(" '"); + sb.append(name); + sb.append("' at "); + sb.append(origin.get_location().toString()); + sb.append("."); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/Event.java b/src/core/src/tonkadur/fate/v1/lang/Event.java new file mode 100644 index 0000000..38b3210 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/Event.java @@ -0,0 +1,147 @@ +package tonkadur.fate.v1.lang; + +import java.util.ArrayList; +import java.util.List; + +import tonkadur.functional.Merge; + +import tonkadur.parser.Context; +import tonkadur.parser.Location; +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.meta.DeclaredEntity; + +public class Event extends DeclaredEntity +{ + protected static final Event ANY; + + static + { + ANY = + new Event + ( + new Origin(new Context(""), Location.BASE_LANGUAGE), + new ArrayList<Type>(), + /* + * Use of a space necessary to avoid conflicting with a user created + * type. + */ + "undetermined event" + ); + } + + public static Event value_on_missing () + { + return ANY; + } + + @Override + public /* static */ String get_type_name () + { + return "Event"; + } + + + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final List<Type> signature; + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + + /**** Constructors *********************************************************/ + public Event + ( + final Origin origin, + final List<Type> signature, + final String name + ) + { + super(origin, name); + + this.signature = signature; + } + + /**** Accessors ************************************************************/ + public List<Type> get_signature () + { + return signature; + } + + /**** Misc. ****************************************************************/ + @Override + public boolean is_incompatible_with_declaration (final DeclaredEntity de) + { + if (de instanceof Event) + { + final Event e; + + e = (Event) de; + + if (signature.size() == e.signature.size()) + { + final List<Boolean> compatibility_result; + + /* + * Basically, the events are compatible if, and only if, the old + * signature is as least as restrictive as the new one. + */ + compatibility_result = + ( + new Merge<Type,Type,Boolean>() + { + @Override + protected Boolean merge_fun (final Type a, final Type b) + { + return + new Boolean(a.is_incompatible_with_declaration(b)); + } + }.merge(signature, e.signature) + ); + + return compatibility_result.contains(Boolean.TRUE); + } + } + + return true; + } + + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append(name); + + if (!signature.isEmpty()) + { + boolean first_argument; + + sb.append(": "); + + first_argument = true; + + for (final Type type: signature) + { + if (first_argument) + { + first_argument = false; + } + else + { + sb.append(" -> "); + } + + sb.append(type.get_name()); + } + } + + return sb.toString(); + } + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ +} diff --git a/src/core/src/tonkadur/fate/v1/lang/Type.java b/src/core/src/tonkadur/fate/v1/lang/Type.java index 2990dc0..269e011 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Type.java +++ b/src/core/src/tonkadur/fate/v1/lang/Type.java @@ -1,14 +1,44 @@ package tonkadur.fate.v1.lang; +import tonkadur.parser.Context; +import tonkadur.parser.Location; import tonkadur.parser.Origin; -public class Type +import tonkadur.fate.v1.lang.meta.DeclaredEntity; + +public class Type extends DeclaredEntity { + protected static final Type ANY; + + 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" + ); + } + + public static Type value_on_missing () + { + return ANY; + } + + @Override + public /* static */ String get_type_name () + { + return "Type"; + } + /***************************************************************************/ /**** MEMBERS **************************************************************/ /***************************************************************************/ - protected final Origin origin; - protected final String name; protected final Type true_type; protected final Type parent; @@ -24,6 +54,8 @@ public class Type final String name ) { + super(origin, name); + if (parent == null) { true_type = this; @@ -33,21 +65,10 @@ public class Type true_type = parent.true_type; } - this.origin = origin; this.parent = parent; - this.name = name; } /**** Accessors ************************************************************/ - public String get_name () - { - return name; - } - - public Origin get_origin () - { - return origin; - } public Type get_true_type () { @@ -72,24 +93,22 @@ public class Type /**** Misc. ****************************************************************/ @Override - public boolean equals (final Object o) + public boolean is_incompatible_with_declaration (final DeclaredEntity de) { - if (o instanceof Type) + if (de instanceof Type) { final Type t; - t = (Type) o; + t = (Type) de; - return name.equals(t.name); + /* + * If the previous type cannot be used when the new one will do, the + * new declaration cannot safely stand. + */ + return !can_be_used_as(t); } - return false; - } - - @Override - public int hashCode () - { - return name.hashCode(); + return true; } @Override diff --git a/src/core/src/tonkadur/fate/v1/lang/World.java b/src/core/src/tonkadur/fate/v1/lang/World.java index cd42f55..e6bf2d6 100644 --- a/src/core/src/tonkadur/fate/v1/lang/World.java +++ b/src/core/src/tonkadur/fate/v1/lang/World.java @@ -1,9 +1,14 @@ package tonkadur.fate.v1.lang; -import tonkadur.fate.v1.error.EventAlreadyDeclaredException; -import tonkadur.fate.v1.error.TypeAlreadyDeclaredException; -import tonkadur.fate.v1.error.TextEffectAlreadyDeclaredException; -import tonkadur.fate.v1.error.UnknownTypeException; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +import tonkadur.parser.Context; +import tonkadur.parser.Location; +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.meta.DeclarationCollection; public class World { @@ -11,12 +16,12 @@ public class World /**** MEMBERS **************************************************************/ /***************************************************************************/ protected final Collection<String> loaded_files; - protected final Map<String, Event> events; - protected final Map<String, Macro> macros; - protected final Map<String, Sequence> sequences; - protected final Map<String, TextEffect> text_effects; - protected final Map<String, Type> types; - protected final Map<String, Variable> variables; + protected final DeclarationCollection<Event> event_collection; +// protected final DeclarationCollection<Macro> macros; +// protected final DeclarationCollection<Sequence> sequences; +// protected final DeclarationCollection<TextEffect> text_effects; + protected final DeclarationCollection<Type> type_collection; +// protected final DeclarationCollection<Variable> variables; /***************************************************************************/ /**** PUBLIC ***************************************************************/ @@ -27,12 +32,14 @@ public class World { loaded_files = new HashSet<String>(); - events = new HashMap<String, Event>(); - macros = new HashMap<String, Macro>(); - sequences = new HashMap<String, Sequence>(); - text_effects = new HashMap<String, TextEffect>(); - types = new HashMap<String, Type>(); - variables = new HashMap<String, Variable>(); + event_collection = + new DeclarationCollection<Event>(Event.value_on_missing()); + //macros = new DeclarationCollection<Macro>(); + //sequences = new DeclarationCollection<Sequence>(); + //text_effects = new DeclarationCollection<TextEffect>(); + type_collection = + new DeclarationCollection<Type>(Type.value_on_missing()); + //variables = new DeclarationCollection<Variable>(); add_base_types(); } @@ -41,7 +48,7 @@ public class World /**** Loaded Files ****/ public Collection<String> get_loaded_files () { - return loaded_files.clone(); + return loaded_files; } public boolean has_loaded_file (final String name) @@ -54,36 +61,14 @@ public class World loaded_files.add(name); } - /**** Events ****/ - public Collection<Event> get_events () + public DeclarationCollection<Type> types() { - return events.values(); + return type_collection; } - public boolean has_event (final String name) + public DeclarationCollection<Event> events() { - return events.containsKey(name); - } - - public void add_event - ( - final Origin origin, - final String name, - final List<Type> parameter_types - ) - throws EventAlreadyDeclaredException, UnknownTypeException - { - if (has_event(name)) - { - - } - for (final Type t: parameter_types) - { - if (!has_type(t)) - { - throw new UnknownTypeException() - } - } + return event_collection; } /**** Misc. ****************************************************************/ @@ -97,11 +82,20 @@ public class World base = new Origin(new Context(""), Location.BASE_LANGUAGE); - add_type(base, null, "dict"); - add_type(base, null, "float"); - add_type(base, null, "int"); - add_type(base, null, "list"); - add_type(base, null, "set"); - add_type(base, null, "string"); + 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")); + } + catch (final Throwable t) + { + System.err.println("Unable to add base types:" + t.toString()); + System.exit(-1); + } + } } diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java b/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java new file mode 100644 index 0000000..838d109 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java @@ -0,0 +1,119 @@ +package tonkadur.fate.v1.lang.meta; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.MissingDeclarationException; +import tonkadur.fate.v1.error.DuplicateDeclarationException; +import tonkadur.fate.v1.error.ConflictingDeclarationException; +import tonkadur.fate.v1.error.IncompatibleDeclarationException; + +public class DeclarationCollection <Declared extends DeclaredEntity> +{ + protected final Map<String, Declared> collection; + protected final Declared value_on_missing; + + public DeclarationCollection (final Declared value_on_missing) + { + collection = new HashMap<String, Declared>(); + this.value_on_missing = value_on_missing; + } + + public Collection<Declared> get_all () + { + return collection.values(); + } + + public boolean has (final String name) + { + return collection.containsKey(name); + } + + public void add (final Declared entity) + throws + DuplicateDeclarationException, + ConflictingDeclarationException, + IncompatibleDeclarationException + { + assert_entity_can_be_added(entity); + collection.put(entity.get_name(), entity); + } + + public Declared get (final Origin call_origin, final String name) + throws MissingDeclarationException + { + final Declared result; + + result = collection.get(name); + + if (result == null) + { + ErrorManager.handle + ( + new MissingDeclarationException + ( + call_origin, + value_on_missing.get_type_name(), + name + ) + ); + + return value_on_missing; + } + + return result; + } + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + protected void assert_entity_can_be_added (final Declared new_version) + throws + DuplicateDeclarationException, + ConflictingDeclarationException, + IncompatibleDeclarationException + { + final Declared previous_version; + + previous_version = collection.get(new_version.get_name()); + + if (previous_version == null) + { + return; + } + + ErrorManager.handle + ( + new DuplicateDeclarationException + ( + new_version.get_origin(), + previous_version + ) + ); + + if (!previous_version.conflicts_with_declaration(new_version)) + { + return; + } + + ErrorManager.handle + ( + new ConflictingDeclarationException(new_version, previous_version) + ); + + if (!previous_version.is_incompatible_with_declaration(new_version)) + { + return; + } + + ErrorManager.handle + ( + new IncompatibleDeclarationException(new_version, previous_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 new file mode 100644 index 0000000..5748391 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/meta/DeclaredEntity.java @@ -0,0 +1,88 @@ +package tonkadur.fate.v1.lang.meta; + +import tonkadur.parser.Origin; + +public abstract class DeclaredEntity +{ + /***************************************************************************/ + /**** STATIC ***************************************************************/ + /***************************************************************************/ + /* I wish it could be static, but it can't, because of Java limitations. */ + public /* static */ String get_type_name () + { + return "Declared Entity"; + } + + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Origin origin; + protected final String name; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + + /**** Constructors *********************************************************/ + protected DeclaredEntity + ( + final Origin origin, + final String name + ) + { + this.origin = origin; + this.name = name; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + + /**** Accessors ************************************************************/ + public String get_name () + { + return name; + } + + public Origin get_origin () + { + return origin; + } + + public boolean conflicts_with_declaration (final DeclaredEntity de) + { + return !equals(de); + } + + public boolean is_incompatible_with_declaration (final DeclaredEntity de) + { + return !equals(de); + } + + @Override + public boolean equals (final Object o) + { + if (o instanceof DeclaredEntity) + { + final DeclaredEntity de; + + de = (DeclaredEntity) o; + + return toString().equals(de.toString()); + } + + return false; + } + + @Override + public int hashCode () + { + return toString().hashCode(); + } + + @Override + public String toString () + { + return name; + } +} diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 408d71d..273722f 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -8,6 +8,8 @@ options @header { package tonkadur.fate.v1.parser; + + import tonkadur.fate.v1.lang.World; } @members @@ -18,7 +20,7 @@ options /******************************************************************************/ /******************************************************************************/ /******************************************************************************/ -fate_file: +fate_file [World world]: WS* FATE_VERSION_KW WORD L_PAREN WS* ( (first_level_fate_instr|general_fate_instr) diff --git a/src/core/src/tonkadur/functional/Merge.java b/src/core/src/tonkadur/functional/Merge.java new file mode 100644 index 0000000..68bb0e7 --- /dev/null +++ b/src/core/src/tonkadur/functional/Merge.java @@ -0,0 +1,46 @@ +package tonkadur.functional; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * I am not a fan of how Java implemented functional programming, so here is + * some alternative. + **/ + +public class Merge <Input0, Input1, Output> +{ + public List<Output> merge (final List<Input0> i0, final List<Input1> i1) + { + 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 + ( + merge_fun + ( + it0.hasNext() ? it0.next() : null, + it1.hasNext() ? it1.next() : null + ) + ); + } + + return output; + } + + protected Output merge_fun (final Input0 i0, final Input1 i1) + { + return null; + } +} |


