summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-06 23:50:57 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-06 23:50:57 +0200
commit55dedea5a27e0eb9719c4ec913d6ced7892b6e19 (patch)
tree313061bff64f91eae52ba8463fd6dd085d039797
parent543768e5a9517b6674d8d41a8d026b5f387d76e2 (diff)
Adds variable referencing.
-rw-r--r--src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java39
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/VariableFieldReference.java123
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/VariableReference.java64
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateLexer.g44
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4115
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)+