| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-05 23:50:10 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-05 23:50:10 +0200 |
| commit | 6cb1bae5db929432a76c884408af4b8d28184699 (patch) | |
| tree | ae1dd9bcc1a4bf8285c8c07fccf5e5539740a454 | |
| parent | 0a239d89edc33e16ff0c11721d40a406c29f75b6 (diff) | |
Adds Dictionary Types.
5 files changed, 320 insertions, 20 deletions
diff --git a/src/core/src/tonkadur/fate/v1/error/DuplicateFieldException.java b/src/core/src/tonkadur/fate/v1/error/DuplicateFieldException.java new file mode 100644 index 0000000..1b84840 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/DuplicateFieldException.java @@ -0,0 +1,55 @@ +package tonkadur.fate.v1.error; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +public class DuplicateFieldException extends ParsingError +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Origin previous_definition; + protected final String name; + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + public DuplicateFieldException + ( + final Origin new_origin, + final Origin previous_definition, + final String name + ) + { + super + ( + ErrorLevel.ERROR, + ErrorCategory.INVALID_USE, + new_origin + ); + + this.previous_definition = previous_definition; + this.name = 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("Duplicate field '"); + sb.append(name); + sb.append("'. It was previously defined at "); + sb.append(previous_definition.get_location().toString()); + sb.append("."); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/error/IllegalReferenceNameException.java b/src/core/src/tonkadur/fate/v1/error/IllegalReferenceNameException.java new file mode 100644 index 0000000..8cff054 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/IllegalReferenceNameException.java @@ -0,0 +1,46 @@ +package tonkadur.fate.v1.error; + +import java.util.Map; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +public class IllegalReferenceNameException extends ParsingError +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final String name; + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + public IllegalReferenceNameException + ( + final Origin origin, + final String name + ) + { + super(ErrorLevel.ERROR, ErrorCategory.INVALID_USE, origin); + this.name = 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("Illegal use of '.' ('"); + sb.append(name); + sb.append("')."); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/World.java b/src/core/src/tonkadur/fate/v1/lang/World.java index edfb6fa..d323457 100644 --- a/src/core/src/tonkadur/fate/v1/lang/World.java +++ b/src/core/src/tonkadur/fate/v1/lang/World.java @@ -151,7 +151,7 @@ public class World sb.append(System.lineSeparator()); sb.append(System.lineSeparator()); - sb.append("Variable: "); + sb.append("Variables: "); sb.append(System.lineSeparator()); sb.append(variable_collection.toString()); sb.append(System.lineSeparator()); diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java b/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java new file mode 100644 index 0000000..b8ad468 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java @@ -0,0 +1,89 @@ +package tonkadur.fate.v1.lang.meta; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import tonkadur.parser.Origin; + +import tonkadur.error.ErrorManager; + +import tonkadur.fate.v1.error.DuplicateFieldException; + +import tonkadur.fate.v1.lang.Type; + +public class TypedEntryList +{ + protected final Map<String, Origin> entry_origins; + protected final List<TypedEntry> entries; + + public TypedEntryList () + { + entry_origins = new HashMap<String, Origin>(); + entries = new ArrayList<TypedEntry>(); + } + + public void add + ( + final Origin origin, + final Type type, + final String name + ) + throws DuplicateFieldException + { + final Origin previous_origin; + + previous_origin = entry_origins.get(name); + + if (previous_origin != null) + { + ErrorManager.handle + ( + new DuplicateFieldException(origin, previous_origin, name) + ); + } + + entry_origins.put(name, origin); + entries.add(new TypedEntry(origin, type, name)); + } + + public List<TypedEntry> get_entries () + { + return entries; + } + + public static class TypedEntry + { + protected final Origin origin; + protected final Type type; + protected final String name; + + protected TypedEntry + ( + final Origin origin, + final Type type, + final String name + ) + { + this.origin = origin; + this.type = type; + this.name = name; + } + + public String get_name () + { + return name; + } + + public Type get_type () + { + return type; + } + + public Origin get_origin () + { + return origin; + } + } +} diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 2b581e7..aa20ad6 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -9,11 +9,15 @@ options { package tonkadur.fate.v1.parser; + import java.util.Map; + import java.util.HashMap; + import tonkadur.error.ErrorManager; import tonkadur.parser.Context; import tonkadur.parser.Origin; + import tonkadur.fate.v1.error.IllegalReferenceNameException; import tonkadur.fate.v1.error.UnknownVariableScopeException; import tonkadur.fate.v1.lang.*; @@ -55,7 +59,11 @@ general_fate_sequence: ; first_level_fate_instr: - DEFINE_SEQUENCE_KW WORD WS+ first_node=general_fate_sequence R_PAREN + DEFINE_SEQUENCE_KW + new_reference_name + WS+ + first_node=general_fate_sequence + R_PAREN { /* world.sequences().add @@ -65,13 +73,13 @@ first_level_fate_instr: ($DEFINE_SEQUENCE_KW.getLine()), ($DEFINE_SEQUENCE_KW.getCharPositionInLine()) ), - ($WORD.text), + ($new_reference_name.result), //(first_node.result) ); */ } - | DECLARE_VARIABLE_KW scope=WORD WS+ type WS+ name=WORD R_PAREN + | DECLARE_VARIABLE_KW scope=WORD WS+ type WS+ name=new_reference_name R_PAREN { final Origin start_origin, scope_origin, type_origin; final Variable new_variable; @@ -109,13 +117,13 @@ first_level_fate_instr: start_origin, variable_scope, ($type.result), - ($name.text) + ($name.result) ); WORLD.variables().add(new_variable); } - | DECLARE_TEXT_EFFECT_KW params=type_list name=WORD R_PAREN + | DECLARE_TEXT_EFFECT_KW params=type_list new_reference_name R_PAREN { final Origin start_origin; final TextEffect new_text_effect; @@ -128,17 +136,22 @@ first_level_fate_instr: ); new_text_effect = - new TextEffect(start_origin, ($type_list.result), ($name.text)); + new TextEffect + ( + start_origin, + ($type_list.result), + ($new_reference_name.result) + ); WORLD.text_effects().add(new_text_effect); } - | REQUIRE_EXTENSION_KW name=WORD R_PAREN + | REQUIRE_EXTENSION_KW WORD R_PAREN { - WORLD.add_required_extension(($name.text)); + WORLD.add_required_extension(($WORD.text)); } - | DECLARE_ALIAS_TYPE_KW parent=type WS+ name=WORD R_PAREN + | DECLARE_ALIAS_TYPE_KW parent=type WS+ new_reference_name R_PAREN { final Origin start_origin; final Type new_type; @@ -150,13 +163,50 @@ first_level_fate_instr: ($DECLARE_ALIAS_TYPE_KW.getCharPositionInLine()) ); - new_type = new Type(start_origin, ($parent.result), ($name.text)); + new_type = + new Type + ( + start_origin, + ($parent.result), + ($new_reference_name.result) + ); WORLD.types().add(new_type); } - | DECLARE_DICT_TYPE_KW name=WORD typed_param_list R_PAREN + | DECLARE_DICT_TYPE_KW new_reference_name WS* typed_entry_list R_PAREN { + final Origin start_origin; + final Type new_type; + final Map<String, Type> field_types; + + field_types = new HashMap<String, Type>(); + + for + ( + final TypedEntryList.TypedEntry te: + ($typed_entry_list.result).get_entries() + ) + { + field_types.put(te.get_name(), te.get_type()); + } + + start_origin = + CONTEXT.get_origin_at + ( + ($DECLARE_DICT_TYPE_KW.getLine()), + ($DECLARE_DICT_TYPE_KW.getCharPositionInLine()) + ); + + new_type = + new DictType + ( + start_origin, + field_types, + ($new_reference_name.result) + ); + + WORLD.types().add(new_type); } | ADD_KW value WS+ value_reference R_PAREN @@ -171,7 +221,7 @@ first_level_fate_instr: { } - | DECLARE_EVENT_TYPE_KW name=WORD WS+ type_list R_PAREN + | DECLARE_EVENT_TYPE_KW new_reference_name WS+ type_list R_PAREN { final Origin start_origin; final Event new_event; @@ -183,7 +233,13 @@ first_level_fate_instr: ($DECLARE_EVENT_TYPE_KW.getCharPositionInLine()) ); - new_event = new Event(start_origin, ($type_list.result), ($name.text)); + new_event = + new Event + ( + start_origin, + ($type_list.result), + ($new_reference_name.result) + ); WORLD.events().add(new_event); } @@ -193,7 +249,8 @@ first_level_fate_instr: } | DEFINE_MACRO_KW - L_PAREN WS+ typed_param_list R_PAREN + new_reference_name WS* + L_PAREN WS+ typed_entry_list R_PAREN general_fate_sequence R_PAREN { @@ -357,30 +414,83 @@ type_list returns [List<Type> result] @init { - final List<Type> result = new ArrayList<Type>(); + $result = new ArrayList<Type>(); } : ( type { - result.add(($type.result)); + $result.add(($type.result)); } )? (WS+ type { - result.add(($type.result)); + $result.add(($type.result)); } )* { } ; -typed_param_list: - (L_PAREN WORD WS+ type R_PAREN)* +typed_entry_list +returns [TypedEntryList result] +@init +{ + $result = new TypedEntryList(); +} +: + ( + L_PAREN type WS+ new_reference_name R_PAREN + { + $result.add + ( + CONTEXT.get_origin_at + ( + ($L_PAREN.getLine()), + ($L_PAREN.getCharPositionInLine()) + ), + ($type.result), + ($new_reference_name.result) + ); + } + )* { } ; +catch [final Throwable e] +{ + throw new ParseCancellationException(e); +} + +new_reference_name +returns [String result] +: + WORD + { + if (($WORD.text).indexOf('.') != -1) + { + ErrorManager.handle + ( + new IllegalReferenceNameException + ( + CONTEXT.get_origin_at + ( + ($WORD.getLine()), + ($WORD.getCharPositionInLine()) + ), + ($WORD.text) + ) + ); + } + + $result = ($WORD.text); + } +; +catch [final Throwable e] +{ + throw new ParseCancellationException(e); +} /******************************************************************************/ /**** VALUES ******************************************************************/ |


