| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 | 235 | ||||
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/parser/FateParser.g4 | 273 | ||||
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/parser/Parser.java | 84 | 
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; +      } +   }  } | 


