| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-06 23:50:57 +0200 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-06 23:50:57 +0200 | 
| commit | 55dedea5a27e0eb9719c4ec913d6ced7892b6e19 (patch) | |
| tree | 313061bff64f91eae52ba8463fd6dd085d039797 /src | |
| parent | 543768e5a9517b6674d8d41a8d026b5f387d76e2 (diff) | |
Adds variable referencing.
Diffstat (limited to 'src')
5 files changed, 333 insertions, 12 deletions
| diff --git a/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java b/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java index eb9d158..fcee1ef 100644 --- a/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java +++ b/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java @@ -14,6 +14,7 @@ public class InvalidTypeException extends ParsingError     /***************************************************************************/     /**** MEMBERS **************************************************************/     /***************************************************************************/ +   protected final String name;     protected final Type given_type;     protected final Collection<Type> allowed_types; @@ -36,6 +37,27 @@ public class InvalidTypeException extends ParsingError        this.given_type = given_type;        this.allowed_types = allowed_types; +      this.name = null; +   } + +   public InvalidTypeException +   ( +      final Origin call_origin, +      final Type given_type, +      final Collection<Type> allowed_types, +      final String name +   ) +   { +      super +      ( +         ErrorLevel.FATAL, +         ErrorCategory.INVALID_USE, +         call_origin +      ); + +      this.given_type = given_type; +      this.allowed_types = allowed_types; +      this.name = name;     }     @Override @@ -48,9 +70,20 @@ public class InvalidTypeException extends ParsingError        sb.append(error_category.toString());        sb.append(System.lineSeparator()); -      sb.append("Type '"); -      sb.append(given_type.toString()); -      sb.append("' "); +      if (name != null) +      { +         sb.append(name); +         sb.append(" has type '"); +         sb.append(given_type.toString()); +         sb.append("', which"); +      } +      else +      { +         sb.append("Type '"); +         sb.append(given_type.toString()); +         sb.append("'"); +      } +        sb.append(" is not useable here. The following base types are allowed:");        for (final Type allowed_type: allowed_types) diff --git a/src/core/src/tonkadur/fate/v1/lang/VariableFieldReference.java b/src/core/src/tonkadur/fate/v1/lang/VariableFieldReference.java new file mode 100644 index 0000000..767a56b --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/VariableFieldReference.java @@ -0,0 +1,123 @@ +package tonkadur.fate.v1.lang; + +import java.util.Arrays; +import java.util.List; + +import tonkadur.parser.Origin; + +import tonkadur.error.ErrorManager; + +import tonkadur.fate.v1.lang.meta.ValueNode; + +import tonkadur.fate.v1.error.InvalidTypeException; +import tonkadur.fate.v1.error.UnknownDictionaryFieldException; + +public class VariableFieldReference extends VariableReference +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   final List<String> field_accesses; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected VariableFieldReference +   ( +      final Origin origin, +      final Variable variable, +      final Type type, +      final List<String> field_accesses +   ) +   { +      super(origin, type, variable); + +      this.field_accesses = field_accesses; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public static VariableFieldReference build +   ( +      final Origin origin, +      final Variable variable, +      final List<String> field_accesses +   ) +   throws +      InvalidTypeException, +      UnknownDictionaryFieldException +   { +      final StringBuilder sb; +      Type current_type; + +      sb = new StringBuilder(); + +      current_type = variable.get_type(); + +      for (final String field_access: field_accesses) +      { +         sb.append("."); +         sb.append(field_access); + +         if (!(current_type instanceof DictType)) +         { +            ErrorManager.handle +            ( +               new InvalidTypeException +               ( +                  origin, +                  current_type, +                  Arrays.asList(new Type[]{Type.DICT}), +                  (variable.get_name() + "." + sb.toString()) +               ) +            ); + +            break; +         } + +         current_type = +            ((DictType) current_type).get_field_type(origin, field_access); +      } + +      return +         new VariableFieldReference +         ( +            origin, +            variable, +            current_type, +            field_accesses +         ); +   } + +   /**** Accessors ************************************************************/ +   public List<String> get_field_accesses () +   { +      return field_accesses; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.toString()); +      sb.append("(VariableFieldReference ("); +      sb.append(type.get_name()); +      sb.append(") "); +      sb.append(variable.get_name()); + +      for (final String field: field_accesses) +      { +         sb.append("."); +         sb.append(field); +      } + +      sb.append(")"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/VariableReference.java b/src/core/src/tonkadur/fate/v1/lang/VariableReference.java new file mode 100644 index 0000000..5a08483 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/VariableReference.java @@ -0,0 +1,64 @@ +package tonkadur.fate.v1.lang; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.meta.ValueNode; + +public class VariableReference extends ValueNode +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Variable variable; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   protected VariableReference +   ( +      final Origin origin, +      final Type reported_type, +      final Variable variable +   ) +   { +      super(origin, reported_type); +      this.variable = variable; +   } +   /**** Constructors *********************************************************/ + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public VariableReference +   ( +      final Origin origin, +      final Variable variable +   ) +   { +      super(origin, variable.get_type()); +      this.variable = variable; +   } + +   /**** Accessors ************************************************************/ +   public Variable get_variable () +   { +      return variable; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.toString()); +      sb.append("(VariableReference ("); +      sb.append(type.get_name()); +      sb.append(") "); +      sb.append(variable.get_name()); +      sb.append(")"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index f3ec4c5..582b30b 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -23,7 +23,8 @@ COUNT_KW: L_PAREN 'count';  DECLARE_ALIAS_TYPE_KW: L_PAREN 'declare_subtype';  DECLARE_DICT_TYPE_KW: L_PAREN 'declare_dict_type';  DECLARE_EVENT_TYPE_KW: L_PAREN 'declare_event_type'; -DECLARE_TEXT_EFFECT: L_PAREN 'declare_text_effect'; +DECLARE_LIST_TYPE_KW: L_PAREN 'declare_list_type'; +DECLARE_SET_TYPE_KW: L_PAREN 'declare_set_type';  DECLARE_TEXT_EFFECT_KW: L_PAREN 'declare_text_effect';  DECLARE_VARIABLE_KW: L_PAREN 'declare_variable';  DEFINE_MACRO_KW: L_PAREN 'define_macro'; @@ -37,7 +38,6 @@ EXTENSION_INSTRUCTION_KW: L_PAREN '#';  EXTENSION_VALUE_KW: L_PAREN '$';  FALSE_KW: L_PAREN 'false)';  FATE_VERSION_KW: L_PAREN 'fate_version'; -GET_KW: L_PAREN 'get';  GREATER_EQUAL_THAN_KW: L_PAREN ('greater_equal_than'|'>=');  GREATER_THAN_KW: L_PAREN ('greater_than'|'>');  IF_ELSE_KW: L_PAREN 'if_else'; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index af50352..67a3c4f 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -9,6 +9,7 @@ options  {     package tonkadur.fate.v1.parser; +   import java.util.Arrays;     import java.util.Map;     import java.util.HashMap; @@ -190,6 +191,54 @@ first_level_fate_instr:        WORLD.types().add(new_type);     } +   | DECLARE_SET_TYPE_KW WS+ parent=type WS+ new_reference_name WS* R_PAREN +   { +      final Origin start_origin; +      final Type new_type; + +      start_origin = +         CONTEXT.get_origin_at +         ( +            ($DECLARE_SET_TYPE_KW.getLine()), +            ($DECLARE_SET_TYPE_KW.getCharPositionInLine()) +         ); + +      new_type = +         CollectionType.build +         ( +            start_origin, +            ($parent.result), +            true, +            ($new_reference_name.result) +         ); + +      WORLD.types().add(new_type); +   } + +   | DECLARE_LIST_TYPE_KW WS+ parent=type WS+ new_reference_name WS* R_PAREN +   { +      final Origin start_origin; +      final Type new_type; + +      start_origin = +         CONTEXT.get_origin_at +         ( +            ($DECLARE_LIST_TYPE_KW.getLine()), +            ($DECLARE_LIST_TYPE_KW.getCharPositionInLine()) +         ); + +      new_type = +         CollectionType.build +         ( +            start_origin, +            ($parent.result), +            false, +            ($new_reference_name.result) +         ); + +      WORLD.types().add(new_type); +   } +     | DECLARE_DICT_TYPE_KW        WS+        new_reference_name @@ -484,6 +533,7 @@ returns [TypedEntryList result]  }  :     ( +      WS*        L_PAREN WS* type WS+ new_reference_name WS* R_PAREN        {           $result.add @@ -915,8 +965,8 @@ returns [ValueNode result]           (              CONTEXT.get_origin_at              ( -               ($WORD.getLine()), -               ($WORD.getCharPositionInLine()) +               ($CAST_KW.getLine()), +               ($CAST_KW.getCharPositionInLine())              ),              target_type,              ($value.result) @@ -941,19 +991,70 @@ catch [final Throwable e]     throw new ParseCancellationException(e);  } -value_reference: +value_reference +returns [VariableReference result] +:     VARIABLE_KW WS+ WORD WS* R_PAREN     { -   } +      final Origin target_var_origin; +      final Variable target_var; +      final String[] subrefs; -   | PARAMETER_KW WS+ WORD WS* R_PAREN -   { +      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]); + +      if (subrefs.length == 1) +      { +         $result = +            new VariableReference +            ( +               CONTEXT.get_origin_at +               ( +                  ($VARIABLE_KW.getLine()), +                  ($VARIABLE_KW.getCharPositionInLine()) +               ), +               target_var +            ); +      } +      else +      { +         final List<String> subrefs_list; + +         subrefs_list = new ArrayList(Arrays.asList(subrefs)); + +         subrefs_list.remove(0); + +         $result = +            VariableFieldReference.build +            ( +               CONTEXT.get_origin_at +               ( +                  ($VARIABLE_KW.getLine()), +                  ($VARIABLE_KW.getCharPositionInLine()) +               ), +               target_var, +               subrefs_list +            ); +      }     } -   | GET_KW WS+ value_reference WS* R_PAREN +   | PARAMETER_KW WS+ WORD WS* R_PAREN     { +      $result = null;     }  ; +catch [final Throwable e] +{ +   throw new ParseCancellationException(e); +}  value_cond_list:     (L_PAREN WS* value WS+ value WS* R_PAREN)+ | 


