| 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 /src/core | |
| parent | 0a239d89edc33e16ff0c11721d40a406c29f75b6 (diff) | |
Adds Dictionary Types.
Diffstat (limited to 'src/core')
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 ******************************************************************/ | 


