| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-19 17:58:58 +0200 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-19 17:58:58 +0200 | 
| commit | 99171d9707c58c4f9841a00bf6fd22c4660a81e4 (patch) | |
| tree | 99c78e3efe7f2b8535ff9d52d457af5dbb44520b /src | |
| parent | bfb30cba47d4f1a0429799bd358d371c760c4245 (diff) | |
Adds/modifies references and macros.
Diffstat (limited to 'src')
17 files changed, 1013 insertions, 128 deletions
| diff --git a/src/core/src/tonkadur/fate/v1/error/NotInAMacroException.java b/src/core/src/tonkadur/fate/v1/error/NotInAMacroException.java new file mode 100644 index 0000000..2bb1ed2 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/NotInAMacroException.java @@ -0,0 +1,41 @@ +package tonkadur.fate.v1.error; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +public class NotInAMacroException extends ParsingError +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   public NotInAMacroException (final Origin origin) +   { +      super +      ( +         ErrorLevel.ERROR, +         ErrorCategory.INVALID_USE, +         origin +      ); +   } + +   @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("This can only be done/used in a macro."); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/error/UnknownExtensionContentException.java b/src/core/src/tonkadur/fate/v1/error/UnknownExtensionContentException.java new file mode 100644 index 0000000..350b1ee --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/UnknownExtensionContentException.java @@ -0,0 +1,50 @@ +package tonkadur.fate.v1.error; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +public class UnknownExtensionContentException extends ParsingError +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final String function_name; + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   public UnknownExtensionContentException +   ( +      final Origin origin, +      final String function_name +   ) +   { +      super +      ( +         ErrorLevel.ERROR, +         ErrorCategory.UNKNOWN, +         origin +      ); + +      this.function_name = function_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("Unknown extension content '"); +      sb.append(function_name); +      sb.append("'. "); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/error/UnknownParameterException.java b/src/core/src/tonkadur/fate/v1/error/UnknownParameterException.java new file mode 100644 index 0000000..6e09bee --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/error/UnknownParameterException.java @@ -0,0 +1,68 @@ +package tonkadur.fate.v1.error; + +import tonkadur.error.ErrorLevel; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.meta.TypedEntryList; + +public class UnknownParameterException extends ParsingError +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final TypedEntryList available_parameters; +   protected final String parameter_name; + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   public UnknownParameterException +   ( +      final Origin origin, +      final String parameter_name, +      final TypedEntryList available_parameters +   ) +   { +      super +      ( +         ErrorLevel.ERROR, +         ErrorCategory.UNKNOWN, +         origin +      ); + +      this.parameter_name = parameter_name; +      this.available_parameters = available_parameters; +   } + +   @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("Unknown parameter '"); +      sb.append(parameter_name); +      sb.append("'. "); +      sb.append(System.lineSeparator()); +      sb.append("Available parameters:'"); + +      for +      ( +         final TypedEntryList.TypedEntry param: +            available_parameters.get_entries() +      ) +      { +         sb.append(System.lineSeparator()); +         sb.append("- "); +         sb.append(param.get_name()); +      } + +      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 new file mode 100644 index 0000000..7834bfc --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/Macro.java @@ -0,0 +1,90 @@ +package tonkadur.fate.v1.lang; + +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; + +public class Macro extends DeclaredEntity +{ +   @Override +   public /* static */ String get_type_name () +   { +      return "Macro"; +   } + +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final InstructionNode root; +   protected final TypedEntryList parameters; + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ + +   /**** Constructors *********************************************************/ +   public Macro +   ( +      final Origin origin, +      final InstructionNode root, +      final TypedEntryList parameters, +      final String name +   ) +   { +      super(origin, name); + +      this.root = root; +      this.parameters = parameters; +   } + +   /**** Accessors ************************************************************/ +   public TypedEntryList get_parameters () +   { +      return parameters; +   } + +   public InstructionNode get_root () +   { +      return root; +   } + +   /**** Compatibility ********************************************************/ + +   /* +    * This is for the very special case where a type is used despite not being +    * even a sub-type of the expected one. Using this rather expensive function, +    * the most restrictive shared type will be returned. If no such type exists, +    * the ANY time is returned. +    */ +   @Override +   public DeclaredEntity generate_comparable_to (final DeclaredEntity de) +   { +      return null; +   } + + +   /**** Misc. ****************************************************************/ +   @Override +   public boolean is_incompatible_with_declaration (final DeclaredEntity de) +   { +      return true; +   } + +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append("(Macro "); +      sb.append(name); +      sb.append(")"); + +      return sb.toString(); +   } + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +} diff --git a/src/core/src/tonkadur/fate/v1/lang/World.java b/src/core/src/tonkadur/fate/v1/lang/World.java index 930d84d..3afd60a 100644 --- a/src/core/src/tonkadur/fate/v1/lang/World.java +++ b/src/core/src/tonkadur/fate/v1/lang/World.java @@ -17,6 +17,8 @@ import tonkadur.parser.Origin;  import tonkadur.fate.v1.error.UnknownSequenceException;  import tonkadur.fate.v1.lang.meta.DeclarationCollection; +import tonkadur.fate.v1.lang.meta.ExtensionInstruction; +import tonkadur.fate.v1.lang.meta.ExtensionValueNode;  import tonkadur.fate.v1.lang.meta.InstructionNode;  import tonkadur.fate.v1.lang.type.Type; @@ -30,9 +32,13 @@ public class World     protected final Set<String> required_extensions;     protected final Map<String, List<Origin>> sequence_calls; +   protected final Map<String, ExtensionValueNode> extension_value_nodes; +   protected final Map<String, ExtensionInstruction> extension_instructions; +   protected final Map<String, ExtensionInstruction> +      extension_first_level_instructions;     protected final DeclarationCollection<Event> event_collection; -//   protected final DeclarationCollection<Macro> macros; +   protected final DeclarationCollection<Macro> macro_collection;     protected final DeclarationCollection<Sequence> sequence_collection;     protected final DeclarationCollection<TextEffect> text_effect_collection;     protected final DeclarationCollection<Type> type_collection; @@ -49,11 +55,16 @@ public class World     {        loaded_files = new HashSet<String>();        required_extensions = new HashSet<String>(); +        sequence_calls = new HashMap<String, List<Origin>>(); +      extension_value_nodes = new HashMap<String, ExtensionValueNode>(); +      extension_instructions = new HashMap<String, ExtensionInstruction>(); +      extension_first_level_instructions = +         new HashMap<String, ExtensionInstruction>();        event_collection =           new DeclarationCollection<Event>(Event.value_on_missing()); -      //macros = new DeclarationCollection<Macro>(); +      macro_collection = new DeclarationCollection<Macro>(null);        sequence_collection = new DeclarationCollection<Sequence>(null);        text_effect_collection = @@ -118,12 +129,37 @@ public class World        list_of_calls.add(origin);     } +   /**** Extension Stuff ****/ +   public Map<String, ExtensionInstruction> extension_instructions () +   { +      return extension_instructions; +   } + +   public Map<String, ExtensionInstruction> extension_first_level_instructions +   ( +   ) +   { +      return extension_first_level_instructions; +   } + +   public Map<String, ExtensionValueNode> extension_value_nodes +   ( +   ) +   { +      return extension_value_nodes; +   } +     /**** Collections ****/     public DeclarationCollection<Event> events ()     {        return event_collection;     } +   public DeclarationCollection<Macro> macros () +   { +      return macro_collection; +   } +     public DeclarationCollection<Sequence> sequences ()     {        return sequence_collection; diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/CondInstruction.java b/src/core/src/tonkadur/fate/v1/lang/instruction/CondInstruction.java index 71a6a69..0118ba1 100644 --- a/src/core/src/tonkadur/fate/v1/lang/instruction/CondInstruction.java +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/CondInstruction.java @@ -51,7 +51,7 @@ public class CondInstruction extends InstructionNode     {        for (final Cons<ValueNode, InstructionNode> branch: branches)        { -         if (branch.get_car().get_type().get_base_type().equals(Type.BOOLEAN)) +         if (!branch.get_car().get_type().get_base_type().equals(Type.BOOLEAN))           {              ErrorManager.handle              ( diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/SetValue.java b/src/core/src/tonkadur/fate/v1/lang/instruction/SetValue.java new file mode 100644 index 0000000..9b50b47 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/SetValue.java @@ -0,0 +1,123 @@ +package tonkadur.fate.v1.lang.instruction; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.ConflictingTypeException; +import tonkadur.fate.v1.error.IncomparableTypeException; +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.InstructionNode; +import tonkadur.fate.v1.lang.meta.ValueNode; + +public class SetValue extends InstructionNode +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final ValueNode element; +   protected final ValueNode value_reference; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected SetValue +   ( +      final Origin origin, +      final ValueNode element, +      final ValueNode value_reference +   ) +   { +      super(origin); + +      this.value_reference = value_reference; +      this.element = element; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public static SetValue build +   ( +      final Origin origin, +      final ValueNode element, +      final ValueNode value_reference +   ) +   throws +      InvalidTypeException, +      ConflictingTypeException, +      IncomparableTypeException +   { +      final Type hint; +      final Type value_reference_type; + +      value_reference_type = value_reference.get_type(); + +      if (element.get_type().can_be_used_as(value_reference_type)) +      { +         return new SetValue(origin, element, value_reference); +      } + +      ErrorManager.handle +      ( +         new ConflictingTypeException +         ( +            element.get_origin(), +            element.get_type(), +            value_reference_type +         ) +      ); + +      hint = +         (Type) element.get_type().generate_comparable_to +         ( +            value_reference_type +         ); + +      if (hint.equals(Type.ANY)) +      { +         ErrorManager.handle +         ( +            new IncomparableTypeException +            ( +               element.get_origin(), +               element.get_type(), +               value_reference_type +            ) +         ); +      } + +      return new SetValue(origin, element, value_reference); +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.toString()); +      sb.append("(SetValue"); +      sb.append(System.lineSeparator()); +      sb.append(System.lineSeparator()); + +      sb.append("element:"); +      sb.append(System.lineSeparator()); +      sb.append(element.toString()); +      sb.append(System.lineSeparator()); +      sb.append(System.lineSeparator()); + +      sb.append("value_reference:"); +      sb.append(System.lineSeparator()); +      sb.append(value_reference.toString()); + +      sb.append(")"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/ExtensionInstruction.java b/src/core/src/tonkadur/fate/v1/lang/meta/ExtensionInstruction.java new file mode 100644 index 0000000..349731f --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/meta/ExtensionInstruction.java @@ -0,0 +1,35 @@ +package tonkadur.fate.v1.lang.meta; + +import java.util.List; + +import tonkadur.parser.Context; +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.World; + +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.InstructionNode; + +public class ExtensionInstruction extends InstructionNode +{ +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public ExtensionInstruction (final Origin origin) +   { +      super(origin); +   } + +   public ExtensionInstruction build +   ( +      final World world, +      final Context context, +      final Origin origin, +      final List<InstructionNode> parameters +   ) +   { +      return new ExtensionInstruction(Origin.BASE_LANGUAGE); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/ExtensionValueNode.java b/src/core/src/tonkadur/fate/v1/lang/meta/ExtensionValueNode.java new file mode 100644 index 0000000..57addaf --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/meta/ExtensionValueNode.java @@ -0,0 +1,39 @@ +package tonkadur.fate.v1.lang.meta; + +import java.util.List; + +import tonkadur.parser.Context; +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.World; + +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.ValueNode; + +public class ExtensionValueNode extends ValueNode +{ +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected ExtensionValueNode +   ( +      final Origin origin, +      final Type result_type +   ) +   { +      super(origin, result_type); +   } + +   public ExtensionValueNode build +   ( +      final World world, +      final Context context, +      final Origin origin, +      final List<ValueNode> parameters +   ) +   { +      return new ExtensionValueNode(Origin.BASE_LANGUAGE, Type.ANY); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/Reference.java b/src/core/src/tonkadur/fate/v1/lang/meta/Reference.java new file mode 100644 index 0000000..285dac7 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/meta/Reference.java @@ -0,0 +1,48 @@ +package tonkadur.fate.v1.lang.meta; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.type.Type; + +public abstract class Reference extends ValueNode +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final String name; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected Reference (final Origin origin, final Type type, final String name) +   { +      super(origin, type); + +      this.name = name; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Accessors ************************************************************/ +   public String get_name () +   { +      return name; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append("("); +      sb.append(type.get_name()); +      sb.append(" Reference "); +      sb.append(name); +      sb.append(")"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java b/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java index 7692e38..0002449 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java @@ -15,13 +15,13 @@ import tonkadur.fate.v1.lang.type.Type;  public class TypedEntryList  { -   protected final Map<String, Origin> entry_origins; -   protected final List<TypedEntry> entries; +   protected final Map<String, TypedEntry> as_map; +   protected final List<TypedEntry> as_list;     public TypedEntryList ()     { -      entry_origins = new HashMap<String, Origin>(); -      entries = new ArrayList<TypedEntry>(); +      as_map = new HashMap<String, TypedEntry>(); +      as_list = new ArrayList<TypedEntry>();     }     public void add @@ -32,25 +32,37 @@ public class TypedEntryList     )     throws DuplicateFieldException     { -      final Origin previous_origin; +      TypedEntry previous_entry; -      previous_origin = entry_origins.get(name); +      previous_entry = as_map.get(name); -      if (previous_origin != null) +      if (previous_entry != null)        {           ErrorManager.handle           ( -            new DuplicateFieldException(origin, previous_origin, name) +            new DuplicateFieldException +            ( +               origin, +               previous_entry.get_origin(), +               name +            )           );        } -      entry_origins.put(name, origin); -      entries.add(new TypedEntry(origin, type, name)); +      previous_entry = new TypedEntry(origin, type, name); + +      as_map.put(name, previous_entry); +      as_list.add(previous_entry);     }     public List<TypedEntry> get_entries ()     { -      return entries; +      return as_list; +   } + +   public Map<String, TypedEntry> as_map () +   { +      return as_map;     }     public static class TypedEntry diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/AtReference.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/AtReference.java new file mode 100644 index 0000000..e483100 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/AtReference.java @@ -0,0 +1,101 @@ +package tonkadur.fate.v1.lang.valued_node; + +import java.util.Collections; + +import tonkadur.parser.Origin; + +import tonkadur.error.ErrorManager; + +import tonkadur.fate.v1.error.InvalidTypeException; +import tonkadur.fate.v1.error.UnknownDictionaryFieldException; + +import tonkadur.fate.v1.lang.Variable; + +import tonkadur.fate.v1.lang.meta.Reference; + +import tonkadur.fate.v1.lang.type.RefType; +import tonkadur.fate.v1.lang.type.Type; + +public class AtReference extends Reference +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Reference parent; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   protected AtReference +   ( +      final Origin origin, +      final Type reported_type, +      final Reference parent +   ) +   { +      super(origin, reported_type, ("(At " + parent.get_name() + ")")); + +      this.parent = parent; +   } +   /**** Constructors *********************************************************/ + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public static AtReference build +   ( +      final Origin origin, +      final Reference parent +   ) +   throws +      InvalidTypeException +   { +      Type current_type; + +      current_type = parent.get_type(); + +      if (!(current_type instanceof RefType)) +      { +         ErrorManager.handle +         ( +            new InvalidTypeException +            ( +               origin, +               current_type, +               Collections.singleton(Type.REF), +               parent.get_name() +            ) +         ); + +         current_type = Type.ANY; +      } +      else +      { +         current_type = ((RefType) current_type).get_referenced_type(); +      } + +      return new AtReference(origin, current_type, parent); +   } + +   /**** Accessors ************************************************************/ +   public Reference get_parent () +   { +      return parent; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append("(AtReference ("); +      sb.append(type.get_name()); +      sb.append(") "); +      sb.append(parent.get_name()); +      sb.append(")"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/VariableFieldReference.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/FieldReference.java index 17a99fa..70813d3 100644 --- a/src/core/src/tonkadur/fate/v1/lang/valued_node/VariableFieldReference.java +++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/FieldReference.java @@ -1,6 +1,6 @@  package tonkadur.fate.v1.lang.valued_node; -import java.util.Arrays; +import java.util.Collections;  import java.util.List;  import tonkadur.parser.Origin; @@ -10,97 +10,118 @@ import tonkadur.error.ErrorManager;  import tonkadur.fate.v1.error.InvalidTypeException;  import tonkadur.fate.v1.error.UnknownDictionaryFieldException; -import tonkadur.fate.v1.lang.Variable; - -import tonkadur.fate.v1.lang.meta.ValueNode; +import tonkadur.fate.v1.lang.meta.Reference;  import tonkadur.fate.v1.lang.type.DictType;  import tonkadur.fate.v1.lang.type.Type; -public class VariableFieldReference extends VariableReference +public class FieldReference extends Reference  {     /***************************************************************************/     /**** MEMBERS **************************************************************/     /***************************************************************************/ -   final List<String> field_accesses; +   protected final Reference parent; +   protected final String field_name;     /***************************************************************************/     /**** PROTECTED ************************************************************/     /***************************************************************************/     /**** Constructors *********************************************************/ -   protected VariableFieldReference +   protected FieldReference     (        final Origin origin, -      final Variable variable, +      final Reference parent,        final Type type, -      final List<String> field_accesses +      final String field_name     )     { -      super(origin, type, variable); +      super(origin, type, (parent.get_name() + "." + field_name)); -      this.field_accesses = field_accesses; +      this.parent = parent; +      this.field_name = field_name;     }     /***************************************************************************/     /**** PUBLIC ***************************************************************/     /***************************************************************************/     /**** Constructors *********************************************************/ -   public static VariableFieldReference build +   public static FieldReference build     (        final Origin origin, -      final Variable variable, -      final List<String> field_accesses +      Reference parent, +      final String field     )     throws        InvalidTypeException,        UnknownDictionaryFieldException     { -      final StringBuilder sb;        Type current_type; -      sb = new StringBuilder(); - -      current_type = variable.get_type(); +      current_type = parent.get_type(); -      for (final String field_access: field_accesses) +      if (current_type.get_base_type().equals(Type.REF))        { -         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); +         parent = AtReference.build(origin, parent); +         current_type = parent.get_type();        } -      return -         new VariableFieldReference +      if (!(current_type instanceof DictType)) +      { +         ErrorManager.handle           ( -            origin, -            variable, -            current_type, -            field_accesses +            new InvalidTypeException +            ( +               origin, +               current_type, +               Collections.singleton(Type.DICT), +               parent.get_name() +            )           ); + +         current_type = Type.ANY; +      } +      else +      { +         current_type = ((DictType) current_type).get_field_type(origin, field); +      } + +      return new FieldReference(origin, parent, current_type, field); +   } + +   public static FieldReference build +   ( +      final Origin origin, +      Reference parent, +      final List<String> field_sequence +   ) +   throws +      InvalidTypeException, +      UnknownDictionaryFieldException +   { +      for (final String field: field_sequence) +      { +         parent = build(origin, parent, field); +      } + +      if (parent instanceof FieldReference) +      { +         return (FieldReference) parent; +      } +      else +      { +         return null; +      }     }     /**** Accessors ************************************************************/ -   public List<String> get_field_accesses () +   public String get_field_name () +   { +      return field_name; +   } + +   public Reference get_parent ()     { -      return field_accesses; +      return parent;     }     /**** Misc. ****************************************************************/ @@ -109,18 +130,10 @@ public class VariableFieldReference extends VariableReference     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.toString()); -      sb.append("(VariableFieldReference ("); +      sb.append("(FieldReference (");        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(name);        sb.append(")");        return sb.toString(); diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/ParameterReference.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/ParameterReference.java new file mode 100644 index 0000000..38e59ee --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/ParameterReference.java @@ -0,0 +1,44 @@ +package tonkadur.fate.v1.lang.valued_node; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.meta.Reference; + +import tonkadur.fate.v1.lang.type.Type; + +public class ParameterReference extends Reference +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public ParameterReference +   ( +      final Origin origin, +      final Type reported_type, +      final String parameter_name +   ) +   { +      super(origin, reported_type, parameter_name); +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(origin.toString()); +      sb.append("(ParameterReference ("); +      sb.append(type.get_name()); +      sb.append(") "); +      sb.append(name); +      sb.append(")"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/valued_node/VariableReference.java b/src/core/src/tonkadur/fate/v1/lang/valued_node/VariableReference.java index 1423b31..18c2549 100644 --- a/src/core/src/tonkadur/fate/v1/lang/valued_node/VariableReference.java +++ b/src/core/src/tonkadur/fate/v1/lang/valued_node/VariableReference.java @@ -4,11 +4,11 @@ import tonkadur.parser.Origin;  import tonkadur.fate.v1.lang.Variable; -import tonkadur.fate.v1.lang.meta.ValueNode; +import tonkadur.fate.v1.lang.meta.Reference;  import tonkadur.fate.v1.lang.type.Type; -public class VariableReference extends ValueNode +public class VariableReference extends Reference  {     /***************************************************************************/     /**** MEMBERS **************************************************************/ @@ -25,7 +25,7 @@ public class VariableReference extends ValueNode        final Variable variable     )     { -      super(origin, reported_type); +      super(origin, reported_type, variable.get_name());        this.variable = variable;     }     /**** Constructors *********************************************************/ @@ -40,7 +40,7 @@ public class VariableReference extends ValueNode        final Variable variable     )     { -      super(origin, variable.get_type()); +      super(origin, variable.get_type(), variable.get_name());        this.variable = variable;     } diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index 26350ec..8d6dd29 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -16,6 +16,7 @@ ADD_KW: L_PAREN 'add';  ADD_VARIABLE_ATTRIBUTE_KW: L_PAREN 'add_variable_attribute';  AND_KW: L_PAREN ('and'|'/\\');  ASSERT_KW: L_PAREN 'assert'; +AT_KW: L_PAREN 'at';  CAST_KW: L_PAREN 'cast';  CLEAR_KW: L_PAREN 'clear';  COND_KW: L_PAREN 'cond'; @@ -39,6 +40,7 @@ EXTENSION_INSTRUCTION_KW: L_PAREN '#';  EXTENSION_VALUE_KW: L_PAREN '$';  FALSE_KW: L_PAREN 'false)';  FATE_VERSION_KW: L_PAREN 'fate_version'; +FIELD_KW: L_PAREN 'field';  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 4778cc3..1efccd1 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -26,6 +26,9 @@ options     import tonkadur.fate.v1.Utils;     import tonkadur.fate.v1.error.IllegalReferenceNameException; +   import tonkadur.fate.v1.error.NotInAMacroException; +   import tonkadur.fate.v1.error.UnknownExtensionContentException; +   import tonkadur.fate.v1.error.UnknownParameterException;     import tonkadur.fate.v1.error.UnknownVariableScopeException;     import tonkadur.fate.v1.lang.*; @@ -39,6 +42,7 @@ options  {     Context CONTEXT;     World WORLD; +   TypedEntryList PARAMETERS;  }  /******************************************************************************/ @@ -49,6 +53,7 @@ fate_file [Context context, World world]     {        CONTEXT = context;        WORLD = world; +      PARAMETERS = null;     }     :     WS* FATE_VERSION_KW WS+ WORD WS* R_PAREN WS* @@ -424,29 +429,70 @@ first_level_fate_instr:           WS+           new_reference_name           WS* -         L_PAREN WS+ typed_entry_list WS* R_PAREN +         ( +            L_PAREN WS+ typed_entry_list WS* R_PAREN +            { +               PARAMETERS=($typed_entry_list.result); +            } +         )           WS*           general_fate_sequence           WS*        R_PAREN     { -      /* TODO */ +      final Origin origin; +      final Macro new_macro; + +      PARAMETERS = null; + +      origin = +         CONTEXT.get_origin_at +         ( +            ($DEFINE_MACRO_KW.getLine()), +            ($DEFINE_MACRO_KW.getCharPositionInLine()) +         ); + +      new_macro = +         new Macro +         ( +            origin, +            new InstructionList +            ( +               origin, +               ($general_fate_sequence.result) +            ), +            ($typed_entry_list.result), +            ($new_reference_name.result) +         ); + +      WORLD.macros().add(new_macro);     }     | EXTENSION_FIRST_LEVEL_KW WORD WS+ general_fate_sequence WS* R_PAREN     { -      /* TODO */ +      final Origin origin; +      final ExtensionInstruction instr; -      /* Extension stuff */ -      System.out.println("Using extension FLI " + ($WORD.text)); -   } +      origin = +         CONTEXT.get_origin_at +         ( +            ($WORD.getLine()), +            ($WORD.getCharPositionInLine()) +         ); -   | EXTENSION_FIRST_LEVEL_KW WORD WS* R_PAREN -   { -      /* TODO */ +      instr = WORLD.extension_first_level_instructions().get(($WORD.text)); -      /* Extension stuff */ -      System.out.println("Using extension FLI " + ($WORD.text)); +      if (instr == null) +      { +         ErrorManager.handle +         ( +            new UnknownExtensionContentException(origin, ($WORD.text)) +         ); +      } +      else +      { +         instr.build(WORLD, CONTEXT, origin, ($general_fate_sequence.result)); +      }     }  ;  catch [final Throwable e] @@ -532,12 +578,20 @@ returns [InstructionNode result]     | SET_KW WS+ value WS+ value_reference WS* R_PAREN     { -      /* TODO */ - -      $result = null; +      $result = +         SetValue.build +         ( +            CONTEXT.get_origin_at +            ( +               ($SET_KW.getLine()), +               ($SET_KW.getCharPositionInLine()) +            ), +            ($value.result), +            ($value_reference.result) +         );     } -   | SET_FIELDS_KW WS+ field_value_list WS* value_reference WS* R_PAREN +   | SET_FIELDS_KW WS+ value_reference WS * field_value_list WS* R_PAREN     {        /* TODO */ @@ -656,11 +710,36 @@ returns [InstructionNode result]     | EXTENSION_INSTRUCTION_KW WORD WS+ general_fate_sequence WS* R_PAREN     { -      /* TODO */ +      final Origin origin; +      final ExtensionInstruction instr; -      /* Extension stuff */ -      System.out.println("Using extension instruction " + ($WORD.text)); -      $result = null; +      origin = +         CONTEXT.get_origin_at +         ( +            ($WORD.getLine()), +            ($WORD.getCharPositionInLine()) +         ); + +      instr = WORLD.extension_instructions().get(($WORD.text)); + +      if (instr == null) +      { +         ErrorManager.handle +         ( +            new UnknownExtensionContentException(origin, ($WORD.text)) +         ); +      } +      else +      { +         $result = +            instr.build +            ( +               WORLD, +               CONTEXT, +               origin, +               ($general_fate_sequence.result) +            ); +      }     }     | paragraph @@ -1611,18 +1690,38 @@ returns [ValueNode result]           );     } -   | EXTENSION_VALUE_KW WORD WS+ general_fate_sequence WS* R_PAREN +   | EXTENSION_VALUE_KW WORD WS+ value_list WS* R_PAREN     { -      /* TODO */ -      /* Extension stuff */ -      System.out.println("Using extension value " + ($WORD.text)); -   } +      final Origin origin; +      final ExtensionValueNode value; -   | EXTENSION_VALUE_KW WORD WS* R_PAREN -   { -      /* TODO */ -      /* Extension stuff */ -      System.out.println("Using extension value " + ($WORD.text)); +      origin = +         CONTEXT.get_origin_at +         ( +            ($WORD.getLine()), +            ($WORD.getCharPositionInLine()) +         ); + +      value = WORLD.extension_value_nodes().get(($WORD.text)); + +      if (value == null) +      { +         ErrorManager.handle +         ( +            new UnknownExtensionContentException(origin, ($WORD.text)) +         ); +      } +      else +      { +         $result = +            value.build +            ( +               WORLD, +               CONTEXT, +               origin, +               ($value_list.result) +            ); +      }     }     | value_reference @@ -1636,9 +1735,38 @@ catch [final Throwable e]  }  value_reference -returns [VariableReference result] +returns [Reference result]  : -   VARIABLE_KW WS+ WORD WS* R_PAREN +   AT_KW WS+ value_reference WS* R_PAREN +   { +      $result = +         AtReference.build +         ( +            CONTEXT.get_origin_at +            ( +               ($AT_KW.getLine()), +               ($AT_KW.getCharPositionInLine()) +            ), +            ($value_reference.result) +         ); +   } + +   | FIELD_KW WS+ value_reference WORD R_PAREN +   { +      $result = +         FieldReference.build +         ( +            CONTEXT.get_origin_at +            ( +               ($FIELD_KW.getLine()), +               ($FIELD_KW.getCharPositionInLine()) +            ), +            ($value_reference.result), +            ($WORD.text) +         ); +   } + +   | VARIABLE_KW WS+ WORD WS* R_PAREN     {        final Origin target_var_origin;        final Variable target_var; @@ -1655,20 +1783,18 @@ returns [VariableReference result]        target_var = WORLD.variables().get(target_var_origin, subrefs[0]); -      if (subrefs.length == 1) -      { -         $result = -            new VariableReference +      $result = +         new VariableReference +         ( +            CONTEXT.get_origin_at              ( -               CONTEXT.get_origin_at -               ( -                  ($VARIABLE_KW.getLine()), -                  ($VARIABLE_KW.getCharPositionInLine()) -               ), -               target_var -            ); -      } -      else +               ($VARIABLE_KW.getLine()), +               ($VARIABLE_KW.getCharPositionInLine()) +            ), +            target_var +         ); + +      if (subrefs.length > 1)        {           final List<String> subrefs_list; @@ -1677,14 +1803,10 @@ returns [VariableReference result]           subrefs_list.remove(0);           $result = -            VariableFieldReference.build +            FieldReference.build              ( -               CONTEXT.get_origin_at -               ( -                  ($VARIABLE_KW.getLine()), -                  ($VARIABLE_KW.getCharPositionInLine()) -               ), -               target_var, +               target_var_origin, +               ($result),                 subrefs_list              );        } @@ -1692,7 +1814,68 @@ returns [VariableReference result]     | PARAMETER_KW WS+ WORD WS* R_PAREN     { -      $result = null; +      final Origin origin; + +      origin = +         CONTEXT.get_origin_at +         ( +            ($PARAMETER_KW.getLine()), +            ($PARAMETER_KW.getCharPositionInLine()) +         ); + +      if (PARAMETERS == null) +      { +         ErrorManager.handle +         ( +            new NotInAMacroException(origin) +         ); +      } +      else +      { +         final TypedEntryList.TypedEntry param; +         final String[] subrefs; + +         subrefs = ($WORD.text).split("\\."); + +         param = PARAMETERS.as_map().get(subrefs[0]); + +         if (param == null) +         { +            ErrorManager.handle +            ( +               new UnknownParameterException(origin, subrefs[0], PARAMETERS) +            ); + +            $result = new ParameterReference(origin, Type.ANY, ($WORD.text)); +         } +         else +         { +            $result = +               new ParameterReference +               ( +                  origin, +                  param.get_type(), +                  ($WORD.text) +               ); + +            if (subrefs.length > 1) +            { +               final List<String> subrefs_list; + +               subrefs_list = new ArrayList(Arrays.asList(subrefs)); + +               subrefs_list.remove(0); + +               $result = +                  FieldReference.build +                  ( +                     origin, +                     ($result), +                     subrefs_list +                  ); +            } +         } +      }     }  ;  catch [final Throwable e] | 


