summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-19 17:58:58 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-19 17:58:58 +0200
commit99171d9707c58c4f9841a00bf6fd22c4660a81e4 (patch)
tree99c78e3efe7f2b8535ff9d52d457af5dbb44520b
parentbfb30cba47d4f1a0429799bd358d371c760c4245 (diff)
Adds/modifies references and macros.
-rw-r--r--data/examples/the_thief/include/characters.fate15
-rw-r--r--src/core/src/tonkadur/fate/v1/error/NotInAMacroException.java41
-rw-r--r--src/core/src/tonkadur/fate/v1/error/UnknownExtensionContentException.java50
-rw-r--r--src/core/src/tonkadur/fate/v1/error/UnknownParameterException.java68
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/Macro.java90
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/World.java40
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/CondInstruction.java2
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/SetValue.java123
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/ExtensionInstruction.java35
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/ExtensionValueNode.java39
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/Reference.java48
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java34
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/AtReference.java101
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/FieldReference.java (renamed from src/core/src/tonkadur/fate/v1/lang/valued_node/VariableFieldReference.java)129
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/ParameterReference.java44
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/valued_node/VariableReference.java8
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateLexer.g42
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4287
18 files changed, 1023 insertions, 133 deletions
diff --git a/data/examples/the_thief/include/characters.fate b/data/examples/the_thief/include/characters.fate
index 386d0de..37dea7d 100644
--- a/data/examples/the_thief/include/characters.fate
+++ b/data/examples/the_thief/include/characters.fate
@@ -11,48 +11,53 @@
(require include/locations.fate)
(set_fields
+ (variable oscar)
+
(name Oscar)
(agility 50)
(perception 50)
(money 20)
(location room0)
- (variable oscar)
)
(set_fields
+ (variable carla)
+
(name Carla)
(agility 75)
(perception 35)
(money 7)
(location room1)
- (variable carla)
)
(set_fields
+ (variable simon)
+
(name Simon)
(agility 35)
(perception 75)
(money 80)
(location room1)
- (variable simon)
)
(set_fields
+ (variable julie)
+
(name Julie)
(agility 60)
(perception 60)
(money 90)
(location room2)
- (variable julie)
)
(set_fields
+ (variable statue)
+
(name ( A oddly human shaped statue, with clothes adorned ))
(agility 0)
(perception 0)
(money 30)
(location corridor)
- (variable statue)
)
;; Alright, but we clearly need to be able to point to variables using a type.
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]