summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateLexer.g4235
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4273
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/Parser.java84
3 files changed, 250 insertions, 342 deletions
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4
index 92ca943..e21134a 100644
--- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4
+++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4
@@ -7,18 +7,13 @@ lexer grammar FateLexer;
fragment SEP: [ \t\r\n]+;
fragment US: '_'?;
-
-fragment DICT_NS: 'dict:';
-fragment LIST_NS: 'list:';
-fragment SET_NS: 'set:';
-fragment STRUCT_NS: 'struct:';
-
+fragment IMP: '!';
WS: SEP;
L_PAREN: '(';
R_PAREN: ')';
-
+IMP_MARKER: IMP;
FATE_VERSION_KW: L_PAREN 'fate'US'version' SEP+;
@@ -63,201 +58,19 @@ DECLARE_LOCAL_VARIABLE_KW: L_PAREN 'local' SEP+;
-ABS_KW: L_PAREN 'abs'('olute'?) SEP+;
-CLAMP_KW: L_PAREN ('clamp') SEP+;
-DIVIDE_KW: L_PAREN (('div''ide'?)|'/') SEP+;
-MAX_KW: L_PAREN ('max'('imum'?)) SEP+;
-MINUS_KW: L_PAREN ('minus'|'-') SEP+;
-MIN_KW: L_PAREN ('min'('imum'?)) SEP+;
-MODULO_KW: L_PAREN (('mod''ulo'?)|'%') SEP+;
-PLUS_KW: L_PAREN ('plus'|'+') SEP+;
-POWER_KW: L_PAREN (('pow''er'?)|'^'|'**'|) SEP+;
-RANDOM_KW: L_PAREN (('rand''om'?)|'rnd') SEP+;
-TIMES_KW: L_PAREN ('times'|'*') SEP+;
-
-
-
DICT_KW: L_PAREN 'dict'('ionary'?) SEP+;
-DICT_FILTER_KW: L_PAREN DICT_NS 'filter' SEP+;
-DICT_FOLD_KW: L_PAREN DICT_NS 'fold' SEP+;
-DICT_FROM_LIST_KW:
- L_PAREN ((DICT_NS'from'US'list')|(LIST_NS'to'US'dict'('ionary'?))) SEP+;
-DICT_GET_KW: L_PAREN DICT_NS 'get' SEP+;
-DICT_HAS_KW: L_PAREN DICT_NS 'has' SEP+;
-DICT_KEYS_KW: L_PAREN DICT_NS ('get'US)?'keys' SEP+;
-DICT_MAP_KW: L_PAREN DICT_NS 'map' SEP+;
-DICT_MERGE_KW: L_PAREN DICT_NS 'merge' SEP+;
-DICT_REMOVE_KW: L_PAREN DICT_NS ('rm'|'remove'|'del'|'delete') SEP+;
-DICT_SET_KW: L_PAREN DICT_NS 'set' SEP+;
-DICT_SIZE_KW: L_PAREN DICT_NS 'size' SEP+;
-DICT_TO_LIST_KW:
- L_PAREN ((DICT_NS'to'US'list')|(LIST_NS'from'US'dict'('ionary'?))) SEP+;
-DICT_VALUES_KW: L_PAREN DICT_NS ('get'US)?'values' SEP+;
-IMP_DICT_FILTER_KW: L_PAREN DICT_NS 'filter''!' SEP+;
-IMP_DICT_FOLD_KW: L_PAREN DICT_NS 'fold''!' SEP+;
-IMP_DICT_FROM_LIST_KW:
- L_PAREN ((DICT_NS'from'US'list')|(LIST_NS'to'US'dict'('ionary'?)))'!' SEP+;
-IMP_DICT_GET_KW: L_PAREN DICT_NS 'get''!' SEP+;
-IMP_DICT_HAS_KW: L_PAREN DICT_NS 'has''!' SEP+;
-IMP_DICT_KEYS_KW: L_PAREN DICT_NS ('get'US)?'keys''!' SEP+;
-IMP_DICT_MAP_KW: L_PAREN DICT_NS 'map''!' SEP+;
-IMP_DICT_MERGE_KW: L_PAREN DICT_NS 'merge''!' SEP+;
-IMP_DICT_REMOVE_KW: L_PAREN DICT_NS ('rm'|'remove'|'del'|'delete')'!' SEP+;
-IMP_DICT_SET_KW: L_PAREN DICT_NS 'set''!' SEP+;
-IMP_DICT_TO_LIST_KW:
- L_PAREN ((DICT_NS'to'US'list')|(LIST_NS'from'US'dict'('ionary'?)))'!' SEP+;
-IMP_DICT_VALUES_KW: L_PAREN DICT_NS ('get'US)?'values''!' SEP+;
-
-
-
-
LIST_KW: L_PAREN 'list' SEP+;
-LIST_ADD_ALL_KW: L_PAREN LIST_NS 'add'US'all'(US'elements')? SEP+;
-LIST_ADD_ALL_KW: L_PAREN LIST_NS 'add'US'all'(US'elements')? SEP+;
-LIST_ADD_AT_KW: L_PAREN LIST_NS 'add'(US'element')?US'at' SEP+;
-LIST_ADD_KW: L_PAREN LIST_NS 'add'(US'element')? SEP+;
-LIST_COUNT_KW: L_PAREN LIST_NS 'count' SEP+;
-LIST_FILTER_KW: L_PAREN LIST_NS 'filter' SEP+;
-LIST_FOLDL_KW: L_PAREN LIST_NS 'foldl' SEP+;
-LIST_FOLDR_KW: L_PAREN LIST_NS 'foldr' SEP+;
-LIST_GET_KW: L_PAREN LIST_NS 'get' SEP+;
-LIST_INDEXED_FILTER_KW: L_PAREN LIST_NS 'indexed'US'filter' SEP+;
-LIST_INDEXED_MAP_KW: L_PAREN LIST_NS 'indexed'US'map' SEP+;
-LIST_INDEXED_MERGE_KW: L_PAREN LIST_NS 'indexed'US'merge' SEP+;
-LIST_INDEXED_PARTITION_KW: L_PAREN LIST_NS 'indexed'US'partition' SEP+;
-LIST_INDEX_OF_KW: L_PAREN LIST_NS 'index'US'of' SEP+;
-LIST_IS_EMPTY_KW: L_PAREN LIST_NS 'is'US'empty' SEP+;
-LIST_IS_MEMBER_KW: L_PAREN LIST_NS (('is'US'member')|'contains'|'has') SEP+;
-LIST_MAP_KW: L_PAREN LIST_NS 'map' SEP+;
-LIST_MERGE_KW: L_PAREN LIST_NS 'merge' SEP+;
-LIST_PARTITION_KW: L_PAREN LIST_NS 'partition' SEP+;
-LIST_POP_LEFT_KW: L_PAREN LIST_NS 'pop'US'left' SEP+;
-LIST_POP_RIGHT_KW: L_PAREN LIST_NS 'pop'US'right' SEP+;
-LIST_PUSH_LEFT_KW: L_PAREN LIST_NS 'push'US'left' SEP+;
-LIST_PUSH_RIGHT_KW: L_PAREN LIST_NS 'push'US'right' SEP+;
-LIST_RANGE_KW: L_PAREN LIST_NS 'range' SEP+;
-LIST_REMOVE_ALL_KW: L_PAREN LIST_NS 'remove'US'all' SEP+;
-LIST_REMOVE_AT_KW: L_PAREN LIST_NS 'remove'US('element'?US)?'at' SEP+;
-LIST_REMOVE_ONE_KW: L_PAREN LIST_NS 'remove'US'one' SEP+;
-LIST_REVERSE_KW: L_PAREN LIST_NS 'reverse'(US'list')? SEP+;
-LIST_SAFE_INDEXED_MERGE_KW:
- L_PAREN LIST_NS (('safe'US'indexed')|('indexed'US'safe'))US'merge' SEP+;
-LIST_SAFE_MERGE_KW: L_PAREN LIST_NS 'safe'US'merge' SEP+;
-LIST_SET_KW: L_PAREN LIST_NS 'set' SEP+;
-LIST_SHUFFLE_KW: L_PAREN LIST_NS 'shuffle' SEP+;
-LIST_SIZE_KW: L_PAREN LIST_NS 'size' SEP+;
-LIST_SORT_KW: L_PAREN LIST_NS 'sort' SEP+;
-LIST_SUB_LIST_KW: L_PAREN LIST_NS 'sub'US'list' SEP+;
-IMP_LIST_ADD_ALL_KW: L_PAREN LIST_NS 'add'US'all'(US'elements')?'!' SEP+;
-IMP_LIST_ADD_AT_KW: L_PAREN LIST_NS 'add'(US'element')?US'at!' SEP+;
-IMP_LIST_ADD_KW: L_PAREN LIST_NS 'add'(US'element')?'!' SEP+;
-IMP_LIST_CLEAR_KW: L_PAREN LIST_NS 'clear!' SEP+;
-IMP_LIST_FILTER_KW: L_PAREN LIST_NS 'filter!' SEP+;
-IMP_LIST_INDEXED_FILTER_KW: L_PAREN LIST_NS 'indexed'US'filter!' SEP+;
-IMP_LIST_INDEXED_MAP_KW: L_PAREN LIST_NS 'indexed'US'map!' SEP+;
-IMP_LIST_INDEXED_MERGE_KW: L_PAREN LIST_NS 'indexed'US'merge!' SEP+;
-IMP_LIST_INDEXED_PARTITION_KW: L_PAREN LIST_NS 'indexed'US'partition!' SEP+;
-IMP_LIST_MAP_KW: L_PAREN LIST_NS 'map!' SEP+;
-IMP_LIST_MERGE_KW: L_PAREN LIST_NS 'merge!' SEP+;
-IMP_LIST_PARTITION_KW: L_PAREN LIST_NS 'partition!' SEP+;
-IMP_LIST_POP_LEFT_KW: L_PAREN LIST_NS 'pop'US'left!' SEP+;
-IMP_LIST_POP_RIGHT_KW: L_PAREN LIST_NS 'pop'US'right!' SEP+;
-IMP_LIST_PUSH_LEFT_KW: L_PAREN LIST_NS 'push'US'left!' SEP+;
-IMP_LIST_PUSH_RIGHT_KW: L_PAREN LIST_NS 'push'US'right!' SEP+;
-IMP_LIST_REMOVE_ALL_KW: L_PAREN LIST_NS 'remove'US'all!' SEP+;
-IMP_LIST_REMOVE_AT_KW: L_PAREN LIST_NS ('remove'US('elem''ent'?US)?'at!') SEP+;
-IMP_LIST_REMOVE_ONE_KW: L_PAREN LIST_NS 'remove'US'one!' SEP+;
-IMP_LIST_REVERSE_KW: L_PAREN LIST_NS 'reverse'(US'list')?'!' SEP+;
-IMP_LIST_SAFE_INDEXED_MERGE_KW:
- L_PAREN LIST_NS (('indexed'US'safe')|('safe'US'indexed'))US'merge!' SEP+;
-IMP_LIST_SAFE_MERGE_KW: L_PAREN LIST_NS 'safe'US'merge!' SEP+;
-IMP_LIST_SET_KW: L_PAREN LIST_NS 'set!' SEP+;
-IMP_LIST_SHUFFLE_KW: L_PAREN LIST_NS 'shuffle!' SEP+;
-IMP_LIST_SORT_KW: L_PAREN LIST_NS 'sort!' SEP+;
-IMP_LIST_SUB_LIST_KW: L_PAREN LIST_NS 'sub'US'list!' SEP+;
-
-
-
-
SET_KW: L_PAREN 'set' SEP+;
-SET_ADD_ALL_KW: L_PAREN SET_NS 'add'US'all'(US'elements')? SEP+;
-SET_ADD_KW: L_PAREN SET_NS 'add'(US'element')? SEP+;
-SET_COUNT_KW: L_PAREN SET_NS 'count' SEP+;
-SET_FILTER_KW: L_PAREN SET_NS 'filter' SEP+;
-SET_FOLDL_KW: L_PAREN SET_NS foldl' SEP+;
-SET_FOLDR_KW: L_PAREN SET_NS 'foldr' SEP+;
-SET_GET_KW: L_PAREN SET_NS 'get' SEP+;
-SET_INDEXED_FILTER_KW: L_PAREN SET_NS 'indexed'US'filter' SEP+;
-SET_INDEXED_MAP_KW: L_PAREN SET_NS 'indexed'US'map' SEP+;
-SET_INDEXED_MERGE_KW: L_PAREN SET_NS 'indexed'US'merge' SEP+;
-SET_INDEXED_PARTITION_KW: L_PAREN SET_NS 'indexed'US'partition' SEP+;
-SET_INDEX_OF_KW: L_PAREN SET_NS 'index'US'of' SEP+;
-SET_IS_EMPTY_KW: L_PAREN SET_NS 'is'US'empty' SEP+;
-SET_IS_MEMBER_KW: L_PAREN SET_NS ('is'US'member'|'contains'|'has') SEP+;
-SET_MAP_KW: L_PAREN SET_NS 'map' SEP+;
-SET_MERGE_KW: L_PAREN SET_NS 'merge' SEP+;
-SET_PARTITION_KW: L_PAREN SET_NS 'partition' SEP+;
-SET_POP_LEFT_KW: L_PAREN SET_NS 'pop'US'left' SEP+;
-SET_POP_RIGHT_KW: L_PAREN SET_NS 'pop'US'right' SEP+;
-SET_RANGE_KW: L_PAREN SET_NS 'range' SEP+;
-SET_REMOVE_AT_KW: L_PAREN SET_NS ('remove'US('elem'('ent')?US)?'at') SEP+;
-SET_REMOVE_ONE_KW: L_PAREN SET_NS 'remove'US'one' SEP+;
-SET_SAFE_INDEXED_MERGE_KW:
- L_PAREN SET_NS (('safe'US'indexed')|('indexed'US'safe'))US'merge' SEP+;
-SET_SAFE_MERGE_KW: L_PAREN SET_NS 'safe'US'merge' SEP+;
-SET_SET_KW: L_PAREN SET_NS 'set' SEP+;
-SET_SIZE_KW: L_PAREN SET_NS 'size' SEP+;
-IMP_SET_ADD_ALL_KW: L_PAREN SET_NS 'add'US'all'(US'elements')?'!' SEP+;
-IMP_SET_ADD_KW: L_PAREN SET_NS 'add'(US'element')?'!' SEP+;
-IMP_SET_CLEAR_KW: L_PAREN SET_NS 'clear!' SEP+;
-IMP_SET_FILTER_KW: L_PAREN SET_NS 'filter!' SEP+;
-IMP_SET_INDEXED_FILTER_KW: L_PAREN SET_NS 'indexed'US'filter!' SEP+;
-IMP_SET_INDEXED_MAP_KW: L_PAREN SET_NS 'indexed'US'map!' SEP+;
-IMP_SET_INDEXED_MERGE_KW: L_PAREN SET_NS 'indexed'US'merge!' SEP+;
-IMP_SET_INDEXED_PARTITION_KW: L_PAREN SET_NS 'indexed'US'partition!' SEP+;
-IMP_SET_MAP_KW: L_PAREN SET_NS 'map!' SEP+;
-IMP_SET_MERGE_KW: L_PAREN SET_NS 'merge!' SEP+;
-IMP_SET_PARTITION_KW: L_PAREN SET_NS 'partition!' SEP+;
-IMP_SET_POP_LEFT_KW: L_PAREN SET_NS 'pop'US'left!' SEP+;
-IMP_SET_POP_RIGHT_KW: L_PAREN SET_NS 'pop'US'right!' SEP+;
-IMP_SET_REMOVE_AT_KW: L_PAREN SET_NS ('remove'US('elem'('ent')?US)?'at!') SEP+;
-IMP_SET_REMOVE_ONE_KW: L_PAREN SET_NS 'remove'US'one!' SEP+;
-IMP_SET_SAFE_INDEXED_MERGE_KW:
- L_PAREN SET_NS (('indexed'US'safe')|('safe'US'indexed'))US'merge!' SEP+;
-IMP_SET_SAFE_MERGE_KW: L_PAREN SET_NS 'safe'US'merge!' SEP+;
-
-
-
-
-AND_KW: L_PAREN ('and'|'/\\') SEP+;
-FALSE_KW: L_PAREN 'false' SEP* R_PAREN;
-IMPLIES_KW: L_PAREN ('implies'|'=>'|'->') SEP+;
-NOT_KW: L_PAREN ('not'|'~'|'!') SEP+;
-ONE_IN_KW: L_PAREN ('exactly'US)?'one'(US'in')? SEP+;
-OR_KW: L_PAREN ('or'|'\\/') SEP+;
-TRUE_KW: L_PAREN 'true' SEP* R_PAREN;
-
-
ENABLE_TEXT_EFFECT_KW: L_PAREN 'text'US'effect' SEP+;
+
NEWLINE_KW: L_PAREN 'newline' SEP* R_PAREN;
-TEXT_JOIN_KW: L_PAREN TEXT_NS 'join' SEP+;
TEXT_KW: L_PAREN 'text' SEP+;
-
-
-
-
-
CONS_KW: L_PAREN 'cons' SEP+;
-CAR_KW: L_PAREN 'car' SEP+;
-CDR_KW: L_PAREN 'cdr' SEP+;
-
-
-
COND_KW: L_PAREN 'cond' SEP+;
DO_WHILE_KW: L_PAREN 'do'US'while' SEP+;
@@ -269,34 +82,19 @@ IMP_BREAK_KW: L_PAREN 'break'('!'?) SEP* R_PAREN;
IMP_CONTINUE_KW: L_PAREN 'continue'('!'?) SEP* R_PAREN;
-
-
IF_ELSE_KW: L_PAREN 'if'US'else' SEP+;
IF_KW: L_PAREN 'if' SEP+;
-
STRING_KW: L_PAREN 'string' SEP+;
-
-
DEFAULT_KW: L_PAREN 'default' SEP+;
CAST_KW: L_PAREN 'cast' SEP+;
-
-EQUALS_KW: L_PAREN ('equals'|'='|'=='|'eq') SEP+;
-GREATER_EQUAL_THAN_KW: L_PAREN (('greater'US'equal'US'than')|'>='|'ge') SEP+;
-GREATER_THAN_KW: L_PAREN (('greater'US'than')|'>'|'gt') SEP+;
-LOWER_EQUAL_THAN_KW: L_PAREN (('lower'US'equal'US'than')|'=<'|'<='|'le') SEP+;
-LOWER_THAN_KW: L_PAREN (('lower'US'than')|'<'|'lt') SEP+;
-
-
-
-
IMP_ASSERT_KW: L_PAREN 'assert!' SEP+;
IGNORE_ERROR_KW: L_PAREN 'ignore'US('error'|'warning') SEP+;
@@ -309,11 +107,9 @@ EXTRA_COMPUTATION_KW: L_PAREN '$';
-
-FIELD_KW: L_PAREN STRUCT_NS ('get'US)?'field' SEP+;
-SET_FIELDS_KW: L_PAREN STRUCT_NS 'set'US'fields' SEP+;
-IMP_SET_FIELDS_KW: L_PAREN STRUCT_NS 'set'US'fields!' SEP+;
-
+FIELD_ACCESS_KW: L_PAREN 'struct:get'(US'field')? SEP+;
+SET_FIELDS_KW: L_PAREN 'struct:set'(US'fields')? SEP+;
+IMP_SET_FIELDS_KW: L_PAREN 'struct:set'((US'fields!')|'!') SEP+;
@@ -328,7 +124,6 @@ PROMPT_INTEGER_KW: L_PAREN 'prompt'US'int''eger'?'!' SEP+;
LET_KW: L_PAREN 'let' SEP+;
-AT_KW: L_PAREN 'at' SEP+;
REF_KW:
L_PAREN
(
@@ -336,27 +131,11 @@ REF_KW:
|('addr''ess'?(US'of')?)
)
SEP+;
-IMP_SET_KW: L_PAREN 'set'(US(('val''ue'?)|('var''iable'?)))?'!' SEP+;
-VARIABLE_KW: L_PAREN 'var''iable'? SEP+;
-
-
-
-
-ALLOCATE_KW: L_PAREN (('alloc''ate'?)|'malloc'|'new')'!' SEP+;
-FREE_KW: L_PAREN ('free!'|'release!'|'destroy!') SEP+;
-
+VARIABLE_KW: L_PAREN 'var''iable'? SEP+;
LAMBDA_KW: L_PAREN 'lambda' SEP+;
-EVAL_KW: L_PAREN 'eval''uate'? SEP+;
-
-
-
-
-
-
-
SEQUENCE_KW: L_PAREN 'seq''uence'? SEP+;
DONE_KW: L_PAREN 'done''!'? SEP* R_PAREN;
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
index ff7ea40..686fde2 100644
--- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
+++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
@@ -1,8 +1,8 @@
-parser grammar TinyFateParser;
+parser grammar FateParser;
options
{
- tokenVocab = TinyFateLexer;
+ tokenVocab = FateLexer;
}
@header
@@ -172,7 +172,7 @@ first_level_instruction
(
start_origin,
($identifier.result),
- ($type_list.result)
+ ($maybe_type_list.result)
);
PARSER.get_world().extra_instructions().add(extra_instruction);
@@ -200,7 +200,7 @@ first_level_instruction
start_origin,
($type.result),
($identifier.result),
- ($type_list.result)
+ ($maybe_type_list.result)
);
PARSER.get_world().extra_computations().add(extra_computation);
@@ -244,7 +244,7 @@ first_level_instruction
new Event
(
start_origin,
- ($type_list.result),
+ ($maybe_type_list.result),
($identifier.result)
);
@@ -267,7 +267,7 @@ first_level_instruction
new TextEffect
(
start_origin,
- ($type_list.result),
+ ($maybe_type_list.result),
($identifier.result)
);
@@ -283,7 +283,7 @@ first_level_instruction
PARSER.get_origin_at
(
($DECLARE_GLOBAL_VARIABLE_KW.getLine()),
- ($DECLARE_GLOBAl_VARIABLE_KW.getCharPositionInLine())
+ ($DECLARE_GLOBAL_VARIABLE_KW.getCharPositionInLine())
);
new_variable =
@@ -697,7 +697,7 @@ returns [Instruction result]
{
PARSER.increment_breakable_levels();
}
- instr_cond_list WS*
+ instruction_cond_list WS*
{
PARSER.increase_local_variables_hierarchy();
}
@@ -716,7 +716,7 @@ returns [Instruction result]
($SWITCH_KW.getCharPositionInLine())
),
($computation.result),
- ($instr_cond_list.result),
+ ($instruction_cond_list.result),
($instruction.result)
);
}
@@ -854,11 +854,8 @@ returns [Instruction result]
/******************************************************************************/
| PLAYER_CHOICE_KW
- {
- // FIXME: handle player_choice limited local variables.
- PARSER.push_choice_limited_variables_level();
- }
- player_choice_list WS*
+ player_choice_list[Parser.generate_player_choice_data()]
+ WS*
R_PAREN
{
$result =
@@ -871,8 +868,6 @@ returns [Instruction result]
),
($player_choice_list.result)
);
-
- PARSER.pop_choice_limited_variables_level();
}
| PROMPT_STRING_KW
@@ -1029,7 +1024,7 @@ returns [List<Cons<Computation, Instruction>> result]
$result.add
(
- new Cons(($value.result), ($instruction.result))
+ new Cons(($computation.result), ($instruction.result))
);
}
WS*
@@ -1038,14 +1033,15 @@ returns [List<Cons<Computation, Instruction>> result]
}
;
-player_choice_list returns [List<Instruction> result]
+player_choice_list [Parser.PlayerChoiceData pcd]
+returns [List<Instruction> result]
@init
{
$result = new ArrayList<Instruction>();
}
:
(
- WS* player_choice
+ WS* player_choice[pcd]
{
$result.add($player_choice.result);
}
@@ -1056,7 +1052,7 @@ catch [final Throwable e]
PARSER.handle_error(e);
}
-maybe_player_choice_list
+maybe_player_choice_list [Parser.PlayerChoiceData pcd]
returns [List<Instruction> result]
@init
{
@@ -1064,7 +1060,7 @@ returns [List<Instruction> result]
}
:
(WS*
- player_choice
+ player_choice[pcd]
{
$result.add(($player_choice.result));
}
@@ -1073,16 +1069,23 @@ returns [List<Instruction> result]
}
;
-player_choice
+player_choice [Parser.PlayerChoiceData pcd]
returns [Instruction result]
/*
* Do not use a separate Local Variable stack for the player choice
- * instructions.
+ * instructions but do have one for any variable defined in 'for' or 'foreach'
+ * choices.
*/
:
TEXT_OPTION_KW
- L_PAREN WS* paragraph WS* R_PAREN WS*
+ L_PAREN WS*
{
+ PARSER.enable_restricted_stack_of(pcd);
+ }
+ paragraph
+ WS* R_PAREN WS*
+ {
+ PARSER.disable_restricted_stack_of(pcd);
PARSER.increase_local_variables_hierarchy();
}
maybe_instruction_list WS*
@@ -1104,8 +1107,12 @@ returns [Instruction result]
}
| EVENT_OPTION_KW
- L_PAREN WS* WORD maybe_value_list WS* R_PAREN WS*
{
+ PARSER.enable_restricted_stack_of(pcd);
+ }
+ L_PAREN WS* WORD maybe_computation_list WS* R_PAREN WS*
+ {
+ PARSER.disable_restricted_stack_of(pcd);
PARSER.increase_local_variables_hierarchy();
}
maybe_instruction_list WS*
@@ -1130,12 +1137,12 @@ returns [Instruction result]
(
origin,
event,
- ($maybe_value_list.result),
+ ($maybe_computation_list.result),
($maybe_instruction_list.result)
);
}
- | L_PAREN maybe_player_choice_list WS* R_PAREN
+ | L_PAREN maybe_player_choice_list[pcd] WS* R_PAREN
{
$result =
new InstructionList
@@ -1149,7 +1156,16 @@ returns [Instruction result]
);
}
- | IF_KW computation WS* player_choice_list WS* R_PAREN
+ | IF_KW
+ {
+ PARSER.enable_restricted_stack_of(pcd);
+ }
+ computation WS*
+ {
+ PARSER.disable_restricted_stack_of(pcd);
+ }
+ player_choice_list[pcd] WS*
+ R_PAREN
{
$result =
IfInstruction.build
@@ -1165,9 +1181,15 @@ returns [Instruction result]
}
| IF_ELSE_KW
+ {
+ PARSER.enable_restricted_stack_of(pcd);
+ }
computation WS*
- if_true=player_choice WS*
- if_false=player_choice WS*
+ {
+ PARSER.disable_restricted_stack_of(pcd);
+ }
+ if_true=player_choice[pcd] WS*
+ if_false=player_choice[pcd] WS*
R_PAREN
{
$result =
@@ -1178,13 +1200,13 @@ returns [Instruction result]
($IF_ELSE_KW.getLine()),
($IF_ELSE_KW.getCharPositionInLine())
),
- ($non_text_value.result),
+ ($computation.result),
($if_true.result),
($if_false.result)
);
}
- | COND_KW player_choice_cond_list WS* R_PAREN
+ | COND_KW player_choice_cond_list[pcd] WS* R_PAREN
{
$result =
CondInstruction.build
@@ -1199,9 +1221,15 @@ returns [Instruction result]
}
| SWITCH_KW
+ {
+ PARSER.enable_restricted_stack_of(pcd);
+ }
computation WS*
- player_choice_switch_list WS+
- player_choice WS*
+ {
+ PARSER.disable_restricted_stack_of(pcd);
+ }
+ player_choice_switch_list[pcd] WS+
+ player_choice[pcd] WS*
R_PAREN
{
$result =
@@ -1212,7 +1240,7 @@ returns [Instruction result]
($SWITCH_KW.getLine()),
($SWITCH_KW.getCharPositionInLine())
),
- ($value.result),
+ ($computation.result),
($player_choice_switch_list.result),
($player_choice.result)
);
@@ -1220,15 +1248,28 @@ returns [Instruction result]
| FOR_KW
l0=L_PAREN
- choice_for_variable_list WS*
+ {
+ PARSER.enable_restricted_stack_of(pcd);
+ PARSER.increase_local_variables_hierarchy();
+ pcd.increase_variable_names_hierarchy();
+ }
+ choice_for_variable_list[pcd] WS*
R_PAREN WS*
computation WS*
l1=L_PAREN
- choice_for_update_variable_list WS*
+ choice_for_update_variable_list[pcd] WS*
R_PAREN WS*
- player_choice_list WS*
+ {
+ PARSER.disable_restricted_stack_of(pcd);
+ }
+ player_choice_list[pcd] WS*
R_PAREN
{
+ pcd.decrease_variable_names_hierarchy();
+ PARSER.enable_restricted_stack_of(pcd);
+ PARSER.decrease_local_variables_hierarchy();
+ PARSER.disable_restricted_stack_of(pcd);
+
$result =
For.build
(
@@ -1261,7 +1302,14 @@ returns [Instruction result]
}
| FOR_EACH_KW
- computation WS+ identifier
+ {
+ PARSER.enable_restricted_stack_of(pcd);
+ PARSER.increase_local_variables_hierarchy();
+ }
+ computation WS+
+ {
+ }
+ identifier
{
final Map<String, Variable> variable_map;
final Variable new_variable;
@@ -1270,7 +1318,7 @@ returns [Instruction result]
elem_type = Type.ANY;
- collection_type = ($non_text_value.result).get_type();
+ collection_type = ($computation.result).get_type();
if (collection_type instanceof CollectionType)
{
@@ -1308,22 +1356,16 @@ returns [Instruction result]
false
);
- PARSER.add_context_variable(new_variable);
+ PARSER.add_local_variable(new_variable);
+ PARSER.disable_restricted_stack_of(pcd);
}
WS+
- {
- PARSER.get_hierarchical_variables().push(new ArrayList());
- }
- player_choice_list
- {
- for (final String s: PARSER.get_hierarchical_variables().pop())
- {
- PARSER.get_local_variables().peekFirst().remove(s);
- }
- }
- WS*
+ player_choice_list[pcd] WS*
R_PAREN
{
+ PARSER.enable_restricted_stack_of(pcd);
+ PARSER.decrease_local_variables_hierarchy();
+ PARSER.disable_restricted_stack_of(pcd);
$result =
new ForEach
(
@@ -1332,12 +1374,10 @@ returns [Instruction result]
($FOR_EACH_KW.getLine()),
($FOR_EACH_KW.getCharPositionInLine())
),
- ($non_text_value.result),
+ ($computation.result),
($identifier.result),
($player_choice_list.result)
);
-
- variable_map.remove(($identifier.result));
}
;
catch [final Throwable e]
@@ -1345,7 +1385,7 @@ catch [final Throwable e]
PARSER.handle_error(e);
}
-player_choice_cond_list
+player_choice_cond_list [Parser.PlayerChoiceData pcd]
returns [List<Cons<Computation, Instruction>> result]
@init
{
@@ -1354,6 +1394,7 @@ returns [List<Cons<Computation, Instruction>> result]
condition = null;
$result = new ArrayList<Cons<Computation, Instruction>>();
+ // TODO: pcd enable.
}
:
(
@@ -1362,6 +1403,7 @@ returns [List<Cons<Computation, Instruction>> result]
(L_PAREN WS* computation WS+)
{
condition = ($computation.result);
+ // TODO: pcd disable.
}
)
|
@@ -1379,10 +1421,11 @@ returns [List<Cons<Computation, Instruction>> result]
),
($something_else.text).substring(1).trim()
);
+ // TODO: pcd disable.
}
)
)
- player_choice WS* R_PAREN
+ player_choice[pcd] WS* R_PAREN
{
$result.add(new Cons(condition, ($player_choice.result)));
}
@@ -1396,15 +1439,22 @@ catch [final Throwable e]
PARSER.handle_error(e);
}
-player_choice_switch_list
+player_choice_switch_list [Parser.PlayerChoiceData pcd]
returns [List<Cons<Computation, Instruction>> result]
@init
{
$result = new ArrayList<Cons<Computation, Instruction>>();
+ // todo: pcd enable
}
:
(
- L_PAREN WS* computation WS* player_choice WS* R_PAREN
+ L_PAREN
+ WS* computation
+ {
+ //todo: pcd disable
+ }
+ WS* player_choice[pcd] WS*
+ R_PAREN
{
$result.add(new Cons(($computation.result), ($player_choice.result)));
}
@@ -1499,10 +1549,10 @@ returns [Type result]
(
PARSER.get_origin_at
(
- ($WORD.getLine()),
- ($WORD.getCharPositionInLine())
+ ($L_PAREN.getLine()),
+ ($L_PAREN.getCharPositionInLine())
),
- ($WORD.text)
+ ($identifier.result)
);
$result = t.build(type_list);
@@ -1579,7 +1629,7 @@ returns [List<Cons<Variable, Computation>> result]
}
)
)
- WS+ value WS* R_PAREN
+ WS+ computation WS* R_PAREN
{
final Variable v;
@@ -1591,26 +1641,14 @@ returns [List<Cons<Variable, Computation>> result]
($L_PAREN.getLine()),
($L_PAREN.getCharPositionInLine())
),
- ($value.result).get_type(),
+ ($computation.result).get_type(),
var_name,
false
);
- if (PARSER.current_context_variable_level_has(var_name))
- {
- ErrorManager.handle
- (
- new DuplicateLocalVariableException
- (
- variables.get(var_name),
- v
- )
- );
- }
-
PARSER.add_context_variable(v);
- $result.add(new Cons(v, ($value.result)));
+ $result.add(new Cons(v, ($computation.result)));
}
)*
{
@@ -1621,15 +1659,13 @@ catch [final Throwable e]
PARSER.handle_error(e);
}
-choice_for_update_variable_list
+choice_for_update_variable_list [Parser.PlayerChoiceData pcd]
returns [List<Instruction> result]
@init
{
- Collection<String> allowed_variables;
String var_name;
Origin origin;
- allowed_variables = PARSER.get_choice_limited_variables().peek();
var_name = null;
origin = null;
@@ -1682,7 +1718,7 @@ returns [List<Instruction> result]
)
);
- if (!allowed_variables.contains(var_name))
+ if (!pcd.can_update_variable(var_name))
{
ErrorManager.handle
(
@@ -1699,15 +1735,13 @@ catch [final Throwable e]
PARSER.handle_error(e);
}
-choice_for_variable_list
+choice_for_variable_list [Parser.PlayerChoiceData pcd]
returns [List<Instruction> result]
@init
{
- Collection<String> allowed_variables;
String var_name;
Origin origin;
- allowed_variables = PARSER.get_choice_limited_variables().peek();
var_name = null;
origin = null;
@@ -1745,6 +1779,21 @@ returns [List<Instruction> result]
)
WS+ computation WS* R_PAREN
{
+ final Variable new_var;
+
+ new_var =
+ new Variable
+ (
+ origin,
+ ($computation.result).get_type(),
+ var_name,
+ false
+ );
+
+ $result.add(new LocalVariable(new_var));
+
+ PARSER.add_context_variable(v);
+
$result.add
(
SetValue.build
@@ -1755,7 +1804,7 @@ returns [List<Instruction> result]
)
);
- allowed_variables.add(var_name);
+ pcd.mark_name_as_editable(var_name);
}
)*
{
@@ -2027,7 +2076,7 @@ returns [Computation result]
}
L_PAREN WS* variable_list WS* R_PAREN
{
- PARSER.add_local_variables(($variable_lists.result).as_map());
+ PARSER.add_local_variables(($variable_list.result).as_map());
}
WS*
computation
@@ -2080,19 +2129,6 @@ returns [Computation result]
| CAST_KW type WS+ computation WS* R_PAREN
{
- final Origin target_type_origin;
- final Type target_type;
-
- target_type_origin =
- PARSER.get_origin_at
- (
- ($WORD.getLine()),
- ($WORD.getCharPositionInLine())
- );
-
- target_type =
- PARSER.get_world().types().get(target_type_origin, ($WORD.text));
-
$result =
Cast.build
(
@@ -2101,13 +2137,13 @@ returns [Computation result]
($CAST_KW.getLine()),
($CAST_KW.getCharPositionInLine())
),
- target_type,
+ $type.result,
($computation.result),
false
);
}
- | SET_FIELDS_KW computation WS* field_computation_list WS* R_PAREN
+ | SET_FIELDS_KW computation WS* field_value_list WS* R_PAREN
{
/*
* A bit of a lazy solution: build field references, then extract the data
@@ -2119,7 +2155,7 @@ returns [Computation result]
for
(
final Cons<Origin, Cons<String, Computation>> entry:
- ($field_computation_list.result)
+ ($field_value_list.result)
)
{
final FieldReference fr;
@@ -2185,7 +2221,7 @@ returns [Computation result]
| ENABLE_TEXT_EFFECT_KW
L_PAREN
WORD WS+
- value_list WS*
+ computation_list WS*
R_PAREN WS+
paragraph WS*
R_PAREN
@@ -2212,7 +2248,7 @@ returns [Computation result]
($ENABLE_TEXT_EFFECT_KW.getCharPositionInLine())
),
effect,
- ($value_list.result),
+ ($computation_list.result),
($paragraph.result)
);
}
@@ -2305,6 +2341,10 @@ returns [List<Cons<Computation, Computation>> result]
{
}
;
+catch [final Throwable e]
+{
+ PARSER.handle_error(e);
+}
maybe_computation_list
returns [List<Computation> result]
@@ -2313,12 +2353,31 @@ returns [List<Computation> result]
$result = new ArrayList<Computation>();
}
:
- (
+ (WS+
computation
{
($result).add(($computation.result));
}
)*
+ {
+ }
+;
+catch [final Throwable e]
+{
+ PARSER.handle_error(e);
+}
+
+computation_list
+returns [List<Computation> result]
+@init
+{
+ $result = new ArrayList<Computation>();
+}
+:
+ computation
+ {
+ ($result).add(($computation.result));
+ }
(WS+
computation
{
@@ -2328,3 +2387,7 @@ returns [List<Computation> result]
{
}
;
+catch [final Throwable e]
+{
+ PARSER.handle_error(e);
+}
diff --git a/src/core/src/tonkadur/fate/v1/parser/Parser.java b/src/core/src/tonkadur/fate/v1/parser/Parser.java
index d746fb5..3caa7b2 100644
--- a/src/core/src/tonkadur/fate/v1/parser/Parser.java
+++ b/src/core/src/tonkadur/fate/v1/parser/Parser.java
@@ -20,13 +20,13 @@ import tonkadur.fate.v1.lang.World;
public class Parser
{
- final World world;
- final Context context;
+ protected final World world;
+ protected final Context context;
- LocalVariables local_variables;
+ protected LocalVariables local_variables;
- int breakable_levels;
- int continue_levels;
+ protected int breakable_levels;
+ protected int continue_levels;
public Parser (final World world)
{
@@ -196,12 +196,12 @@ public class Parser
throws IOException
{
final CommonTokenStream tokens;
- final TinyFateLexer lexer;
- final TinyFateParser parser;
+ final FateLexer lexer;
+ final FateParser parser;
- lexer = new TinyFateLexer(CharStreams.fromFileName(filename));
+ lexer = new FateLexer(CharStreams.fromFileName(filename));
tokens = new CommonTokenStream(lexer);
- parser = new TinyFateParser(tokens);
+ parser = new FateParser(tokens);
if (origin != null)
{
@@ -223,7 +223,73 @@ public class Parser
}
}
+ public PlayerChoiceData generate_player_choice_data ()
+ {
+ return new Parser.PlayerChoiceData(this);
+ }
+
+ public void enable_restricted_variable_stack_of (final PlayerChoiceData pcd)
+ {
+ pcd.previous_variable_stack = get_local_variables_stack();
+
+ restore_local_variables_stack(pcd.restricted_including_variables_stack);
+ }
+
+ public void disable_restricted_stack_of (final PlayerChoiceData pcd)
+ {
+ restore_local_variables_stack(pcd.previous_variable_stack);
+ }
+
+
public static class LocalVariables extends Deque<Map<String, Variable>>
{
}
+
+ public static class PlayerChoiceData
+ {
+ protected final Parser parent;
+ protected final LocalVariables restricted_including_variables_stack;
+ protected LocalVariables previous_variable_stack;
+ protected final Deque<Set<String>> player_choice_variable_names;
+
+ protected PlayerChoiceData (final Parser parent)
+ {
+ this.parent = parent;
+
+ previous_variable_stack = parent.get_local_variables_stack();
+
+ // Note: clone makes a shallow copy.
+ restricted_including_variables_stack = previous_variable_stack.clone();
+
+ player_choice_variable_names = new ArrayDeque<Set<String>>();
+ }
+
+ public void increase_variable_names_hierarchy ()
+ {
+ player_choice_variable_names.push(new HashSet<String>());
+ }
+
+ public void decrease_variable_names_hierarchy ()
+ {
+ player_choice_variable_names.pop();
+ }
+
+ public void mark_name_as_editable (final String name)
+ {
+ player_choice_variable_names.peek().add(name);
+ }
+
+ public boolean can_update_variable (final String name)
+ {
+ for (final Set<String> variable_names: player_choice_variable_names)
+ {
+ if (variables_names.has(name))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
}