summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2021-01-02 23:45:03 +0100
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2021-01-02 23:45:03 +0100
commit11daf8c58b8a0dd4f4c9babe2660d3779a04465a (patch)
tree21955f6c0bd2447079ecf40f181444b73bea633c /src
parente0227a5ea20aaa6eccd260de33235a307cbd85ea (diff)
Adds 'for' in 'choice' constructs.
Diffstat (limited to 'src')
-rw-r--r--src/core/src/tonkadur/fate/v1/error/UpdatingIllegalVariableFromChoiceException.java46
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4223
2 files changed, 267 insertions, 2 deletions
diff --git a/src/core/src/tonkadur/fate/v1/error/UpdatingIllegalVariableFromChoiceException.java b/src/core/src/tonkadur/fate/v1/error/UpdatingIllegalVariableFromChoiceException.java
new file mode 100644
index 0000000..7dca8f2
--- /dev/null
+++ b/src/core/src/tonkadur/fate/v1/error/UpdatingIllegalVariableFromChoiceException.java
@@ -0,0 +1,46 @@
+package tonkadur.fate.v1.error;
+
+import tonkadur.error.ErrorLevel;
+
+import tonkadur.parser.Origin;
+import tonkadur.parser.ParsingError;
+
+public class UpdatingIllegalVariableFromChoiceException extends ParsingError
+{
+ /***************************************************************************/
+ /**** MEMBERS **************************************************************/
+ /***************************************************************************/
+ protected final String var_name;
+
+ /***************************************************************************/
+ /**** PUBLIC ***************************************************************/
+ /***************************************************************************/
+ public UpdatingIllegalVariableFromChoiceException
+ (
+ final Origin origin,
+ final String var_name
+ )
+ {
+ super(ErrorLevel.ERROR, ErrorCategory.INVALID_USE, origin);
+
+ this.var_name = var_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("Updating a variable that wasn't initialized within the ");
+ sb.append("current choice construct ('");
+ sb.append(var_name);
+ sb.append("').");
+
+ return sb.toString();
+ }
+}
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
index 519a01c..fd0dd14 100644
--- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
+++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
@@ -12,8 +12,10 @@ options
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
+ import java.util.Collection;
import java.util.Map;
import java.util.HashMap;
+ import java.util.HashSet;
import tonkadur.Files;
@@ -31,6 +33,7 @@ options
import tonkadur.fate.v1.error.DuplicateLocalVariableException;
import tonkadur.fate.v1.error.IllegalReferenceNameException;
import tonkadur.fate.v1.error.InvalidTypeException;
+ import tonkadur.fate.v1.error.UpdatingIllegalVariableFromChoiceException;
import tonkadur.fate.v1.error.UnknownExtensionContentException;
import tonkadur.fate.v1.lang.*;
@@ -47,6 +50,7 @@ options
Deque<Map<String, Variable>> LOCAL_VARIABLES;
Deque<List<String>> HIERARCHICAL_VARIABLES;
int BREAKABLE_LEVELS;
+ Deque<Collection<String>> CHOICE_LIMITED_VARIABLES;
}
/******************************************************************************/
@@ -72,6 +76,7 @@ fate_file [Context context, Deque<Map<String, Variable>> local_variables, World
BREAKABLE_LEVELS = 0;
HIERARCHICAL_VARIABLES.push(new ArrayList<String>());
+ CHOICE_LIMITED_VARIABLES = new ArrayDeque<Collection<String>>();
}
:
WS* FATE_VERSION_KW WORD WS* R_PAREN WS*
@@ -2045,7 +2050,11 @@ returns [Instruction result]
);
}
- | PLAYER_CHOICE_KW player_choice_list WS* R_PAREN
+ | PLAYER_CHOICE_KW
+ {
+ CHOICE_LIMITED_VARIABLES.push(new HashSet<String>());
+ }
+ player_choice_list WS* R_PAREN
{
$result =
new PlayerChoice
@@ -2057,6 +2066,8 @@ returns [Instruction result]
),
($player_choice_list.result)
);
+
+ CHOICE_LIMITED_VARIABLES.pop();
}
| paragraph
@@ -2374,6 +2385,48 @@ returns [Instruction result]
);
}
+ | FOR_KW
+ l0=L_PAREN
+ choice_for_variable_list WS*
+ R_PAREN WS*
+ non_text_value WS*
+ l1=L_PAREN
+ choice_for_update_variable_list WS*
+ R_PAREN WS*
+ player_choice_list
+ WS* R_PAREN
+ {
+ $result =
+ For.build
+ (
+ CONTEXT.get_origin_at
+ (
+ ($FOR_KW.getLine()),
+ ($FOR_KW.getCharPositionInLine())
+ ),
+ ($non_text_value.result),
+ new InstructionList
+ (
+ CONTEXT.get_origin_at
+ (
+ ($l0.getLine()),
+ ($l0.getCharPositionInLine())
+ ),
+ ($choice_for_variable_list.result)
+ ),
+ ($player_choice_list.result),
+ new InstructionList
+ (
+ CONTEXT.get_origin_at
+ (
+ ($l1.getLine()),
+ ($l1.getCharPositionInLine())
+ ),
+ ($choice_for_update_variable_list.result)
+ )
+ );
+ }
+
| FOR_EACH_KW
non_text_value WS+ new_reference_name
{
@@ -2976,7 +3029,7 @@ returns [List<Cons<Variable, Computation>> result]
WS*
(
(
- L_PAREN WS* new_reference_name WS+
+ L_PAREN WS* new_reference_name
{
var_name = ($new_reference_name.result);
}
@@ -3038,6 +3091,172 @@ catch [final Throwable e]
}
}
+choice_for_update_variable_list
+returns [List<Instruction> result]
+@init
+{
+ Collection<String> allowed_variables;
+ String var_name;
+ Origin origin;
+
+ allowed_variables = CHOICE_LIMITED_VARIABLES.peek();
+ var_name = null;
+ origin = null;
+
+ $result = new ArrayList<Instruction>();
+}
+:
+ (
+ WS*
+ (
+ (
+ L_PAREN WS* new_reference_name
+ {
+ var_name = ($new_reference_name.result);
+ origin =
+ CONTEXT.get_origin_at
+ (
+ ($L_PAREN.getLine()),
+ ($L_PAREN.getCharPositionInLine())
+ );
+ }
+ )
+ |
+ (
+ something_else=.
+ {
+ var_name = ($something_else.text).substring(1).trim();
+ origin =
+ CONTEXT.get_origin_at
+ (
+ ($something_else.getLine()),
+ ($something_else.getCharPositionInLine())
+ );
+ }
+ )
+ )
+ WS+ value WS* R_PAREN
+ {
+ $result.add
+ (
+ SetValue.build
+ (
+ origin,
+ ($value.result),
+ VariableFromWord.generate
+ (
+ WORLD,
+ LOCAL_VARIABLES,
+ origin,
+ var_name
+ )
+ )
+ );
+
+ if (!allowed_variables.contains(var_name))
+ {
+ ErrorManager.handle
+ (
+ new UpdatingIllegalVariableFromChoiceException(origin, var_name)
+ );
+ }
+ }
+ )*
+ {
+ }
+;
+catch [final Throwable e]
+{
+ if ((e.getMessage() == null) || !e.getMessage().startsWith("Require"))
+ {
+ throw new ParseCancellationException(CONTEXT.toString() + ((e.getMessage() == null) ? "" : e.getMessage()), e);
+ }
+ else
+ {
+ throw new ParseCancellationException(e);
+ }
+}
+
+choice_for_variable_list
+returns [List<Instruction> result]
+@init
+{
+ Collection<String> allowed_variables;
+ String var_name;
+ Origin origin;
+
+ allowed_variables = CHOICE_LIMITED_VARIABLES.peek();
+ var_name = null;
+ origin = null;
+
+ $result = new ArrayList<Instruction>();
+}
+:
+ (
+ WS*
+ (
+ (
+ L_PAREN WS* new_reference_name
+ {
+ var_name = ($new_reference_name.result);
+ origin =
+ CONTEXT.get_origin_at
+ (
+ ($L_PAREN.getLine()),
+ ($L_PAREN.getCharPositionInLine())
+ );
+ }
+ )
+ |
+ (
+ something_else=.
+ {
+ var_name = ($something_else.text).substring(1).trim();
+ origin =
+ CONTEXT.get_origin_at
+ (
+ ($something_else.getLine()),
+ ($something_else.getCharPositionInLine())
+ );
+ }
+ )
+ )
+ WS+ value WS* R_PAREN
+ {
+ $result.add
+ (
+ SetValue.build
+ (
+ origin,
+ ($value.result),
+ VariableFromWord.generate
+ (
+ WORLD,
+ LOCAL_VARIABLES,
+ origin,
+ var_name
+ )
+ )
+ );
+
+ allowed_variables.add(var_name);
+ }
+ )*
+ {
+ }
+;
+catch [final Throwable e]
+{
+ if ((e.getMessage() == null) || !e.getMessage().startsWith("Require"))
+ {
+ throw new ParseCancellationException(CONTEXT.toString() + ((e.getMessage() == null) ? "" : e.getMessage()), e);
+ }
+ else
+ {
+ throw new ParseCancellationException(e);
+ }
+}
+
variable_list
returns [VariableList result]
@init