| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-06 23:50:57 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-06 23:50:57 +0200 |
| commit | 55dedea5a27e0eb9719c4ec913d6ced7892b6e19 (patch) | |
| tree | 313061bff64f91eae52ba8463fd6dd085d039797 | |
| parent | 543768e5a9517b6674d8d41a8d026b5f387d76e2 (diff) | |
Adds variable referencing.
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)+ |


