| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src')
4 files changed, 191 insertions, 10 deletions
| diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 8bbd4d2..06b123c 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -44,6 +44,7 @@ options     Context CONTEXT;     World WORLD;     Deque<Map<String, Variable>> LOCAL_VARIABLES; +   Deque<List<String>> HIERARCHICAL_VARIABLES;     int BREAKABLE_LEVELS;  } @@ -56,9 +57,11 @@ fate_file [Context context, World world]        CONTEXT = context;        WORLD = world;        LOCAL_VARIABLES = new ArrayDeque<Map<String, Variable>>(); +      HIERARCHICAL_VARIABLES = new ArrayDeque<List<String>>();        BREAKABLE_LEVELS = 0;        LOCAL_VARIABLES.push(new HashMap<String, Variable>()); +      HIERARCHICAL_VARIABLES.push(new ArrayList<String>());     }     :     WS* FATE_VERSION_KW WORD WS* R_PAREN WS* @@ -476,6 +479,11 @@ returns [Instruction result]        }        $result = new LocalVariable(new_variable); + +      if (!HIERARCHICAL_VARIABLES.isEmpty()) +      { +         HIERARCHICAL_VARIABLES.peekFirst().add(new_variable.get_name()); +      }     }     | ADD_KW value WS+ value_reference WS* R_PAREN @@ -667,7 +675,19 @@ returns [Instruction result]     }     | WHILE_KW value WS* -      {BREAKABLE_LEVELS++;} general_fate_sequence {BREAKABLE_LEVELS--;} +      { +         BREAKABLE_LEVELS++; +         HIERARCHICAL_VARIABLES.push(new ArrayList()); +      } +      general_fate_sequence +      { +         BREAKABLE_LEVELS--; + +         for (final String s: HIERARCHICAL_VARIABLES.pop()) +         { +            LOCAL_VARIABLES.peekFirst().remove(s); +         } +      }        WS*        R_PAREN     { @@ -685,7 +705,19 @@ returns [Instruction result]     }     | DO_WHILE_KW value WS* -      {BREAKABLE_LEVELS++;} general_fate_sequence {BREAKABLE_LEVELS--;} +      { +         BREAKABLE_LEVELS++; +         HIERARCHICAL_VARIABLES.push(new ArrayList()); +      } +      general_fate_sequence +      { +         BREAKABLE_LEVELS--; + +         for (final String s: HIERARCHICAL_VARIABLES.pop()) +         { +            LOCAL_VARIABLES.peekFirst().remove(s); +         } +      }        WS*        R_PAREN     { @@ -716,7 +748,19 @@ returns [Instruction result]     }     | FOR_KW pre=general_fate_instr WS * value WS* post=general_fate_instr WS* -      {BREAKABLE_LEVELS++;} general_fate_sequence {BREAKABLE_LEVELS--;} +      { +         BREAKABLE_LEVELS++; +         HIERARCHICAL_VARIABLES.push(new ArrayList()); +      } +      general_fate_sequence +      { +         BREAKABLE_LEVELS--; + +         for (final String s: HIERARCHICAL_VARIABLES.pop()) +         { +            LOCAL_VARIABLES.peekFirst().remove(s); +         } +      }        WS* R_PAREN     {        $result = @@ -801,7 +845,19 @@ returns [Instruction result]           }        }        WS+ -      {BREAKABLE_LEVELS++;} general_fate_sequence {BREAKABLE_LEVELS--;} +      { +         BREAKABLE_LEVELS++; +         HIERARCHICAL_VARIABLES.push(new ArrayList()); +      } +      general_fate_sequence +      { +         BREAKABLE_LEVELS--; + +         for (final String s: HIERARCHICAL_VARIABLES.pop()) +         { +            LOCAL_VARIABLES.peekFirst().remove(s); +         } +      }        WS*     R_PAREN     { @@ -964,7 +1020,18 @@ returns [Instruction result]           );     } -   | IF_KW value WS* general_fate_instr WS* R_PAREN +   | IF_KW value WS* +      { +         HIERARCHICAL_VARIABLES.push(new ArrayList()); +      } +      general_fate_instr +      { +         for (final String s: HIERARCHICAL_VARIABLES.pop()) +         { +            LOCAL_VARIABLES.peekFirst().remove(s); +         } +      } +      WS* R_PAREN     {        $result =           IfInstruction.build @@ -981,8 +1048,26 @@ returns [Instruction result]     | IF_ELSE_KW           value +         { +            HIERARCHICAL_VARIABLES.push(new ArrayList()); +         }           WS+ if_true=general_fate_instr +         { +            for (final String s: HIERARCHICAL_VARIABLES.pop()) +            { +               LOCAL_VARIABLES.peekFirst().remove(s); +            } + +            HIERARCHICAL_VARIABLES.push(new ArrayList()); +         }           WS+ if_false=general_fate_instr +         { +            for (final String s: HIERARCHICAL_VARIABLES.pop()) +            { +               LOCAL_VARIABLES.peekFirst().remove(s); +            } + +         }        WS* R_PAREN     {        $result = @@ -1107,7 +1192,18 @@ returns [List<Cons<Computation, Instruction>> result]  }  :     ( -      L_PAREN WS* value WS+ general_fate_instr WS* R_PAREN +      L_PAREN WS* value WS+ +         { +            HIERARCHICAL_VARIABLES.push(new ArrayList()); +         } +         general_fate_instr +         { +            for (final String s: HIERARCHICAL_VARIABLES.pop()) +            { +               LOCAL_VARIABLES.peekFirst().remove(s); +            } +         } +         WS* R_PAREN        {           $result.add(new Cons(($value.result), ($general_fate_instr.result)));        } @@ -1139,7 +1235,17 @@ returns [Instruction result]  :     start_p=L_PAREN WS*        L_PAREN WS* paragraph WS* R_PAREN WS+ -      general_fate_sequence WS* +      { +         HIERARCHICAL_VARIABLES.push(new ArrayList()); +      } +      general_fate_sequence +      { +         for (final String s: HIERARCHICAL_VARIABLES.pop()) +         { +            LOCAL_VARIABLES.peekFirst().remove(s); +         } +      } +      WS*     R_PAREN     {        $result = @@ -1203,6 +1309,22 @@ returns [Instruction result]              ($player_choice_cond_list.result)           );     } + +   | SWITCH_KW value WS* player_choice_cond_list WS+ player_choice WS* R_PAREN +   { +      $result = +         SwitchInstruction.build +         ( +            CONTEXT.get_origin_at +            ( +               ($SWITCH_KW.getLine()), +               ($SWITCH_KW.getCharPositionInLine()) +            ), +            ($value.result), +            ($player_choice_cond_list.result), +            ($player_choice.result) +         ); +   }  ;  catch [final Throwable e]  { diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java index de0532f..2c163e7 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java @@ -449,7 +449,10 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        previous_else_branch = new ArrayList<Instruction>();        ic = new InstructionCompiler(compiler); + +      compiler.registers().push_hierarchical_instruction_level();        n.get_default_instruction().get_visited_by(ic); +      compiler.registers().pop_hierarchical_instruction_level();        previous_else_branch.add(ic.get_result()); @@ -485,7 +488,9 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor           cc = new ComputationCompiler(compiler);           branch.get_car().get_visited_by(cc); +         compiler.registers().push_hierarchical_instruction_level();           branch.get_cdr().get_visited_by(ic); +         compiler.registers().pop_hierarchical_instruction_level();           if (cc.has_init())           { @@ -589,6 +594,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        n.get_condition().get_visited_by(cc); +      compiler.registers().push_hierarchical_instruction_level();        for (final tonkadur.fate.v1.lang.meta.Instruction i: n.get_body())        {           ic = new InstructionCompiler(compiler); @@ -596,6 +602,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor           body.add(ic.get_result());        } +      compiler.registers().pop_hierarchical_instruction_level();        if (cc.has_init()) @@ -657,6 +664,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        cc = new ComputationCompiler(compiler);        n.get_condition().get_visited_by(cc); +      compiler.registers().push_hierarchical_instruction_level();        for (final tonkadur.fate.v1.lang.meta.Instruction i: n.get_body())        {           ic = new InstructionCompiler(compiler); @@ -664,6 +672,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor           pre_cond_instructions.add(ic.get_result());        } +      compiler.registers().pop_hierarchical_instruction_level();        if (cc.has_init())        { @@ -715,6 +724,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        result.add(ic.get_result()); +      compiler.registers().push_hierarchical_instruction_level();        for (final tonkadur.fate.v1.lang.meta.Instruction i: n.get_body())        {           ic = new InstructionCompiler(compiler); @@ -722,6 +732,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor           body.add(ic.get_result());        } +      compiler.registers().pop_hierarchical_instruction_level();        ic = new InstructionCompiler(compiler);        n.get_post().get_visited_by(ic); @@ -841,6 +852,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor           )        ); +      compiler.registers().push_hierarchical_instruction_level();        for        (           final tonkadur.fate.v1.lang.meta.Instruction fate_instr: n.get_body() @@ -854,6 +866,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor           new_body.add(ic.get_result());        } +      compiler.registers().pop_hierarchical_instruction_level();        new_body.add        ( @@ -1019,7 +1032,9 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor           cc = new ComputationCompiler(compiler);           branch.get_car().get_visited_by(cc); +         compiler.registers().push_hierarchical_instruction_level();           branch.get_cdr().get_visited_by(ic); +         compiler.registers().pop_hierarchical_instruction_level();           if (cc.has_init())           { @@ -1115,8 +1130,14 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        if_false_ic = new InstructionCompiler(compiler);        n.get_condition().get_visited_by(cc); + +      compiler.registers().push_hierarchical_instruction_level();        n.get_if_true().get_visited_by(if_true_ic); +      compiler.registers().pop_hierarchical_instruction_level(); + +      compiler.registers().push_hierarchical_instruction_level();        n.get_if_false().get_visited_by(if_false_ic); +      compiler.registers().pop_hierarchical_instruction_level();        if (cc.has_init())        { @@ -1157,7 +1178,10 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        if_true_ic = new InstructionCompiler(compiler);        n.get_condition().get_visited_by(cc); + +      compiler.registers().push_hierarchical_instruction_level();        n.get_if_true().get_visited_by(if_true_ic); +      compiler.registers().pop_hierarchical_instruction_level();        if (cc.has_init())        { @@ -1302,6 +1326,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor           )        ); +      compiler.registers().push_hierarchical_instruction_level();        for        (           final tonkadur.fate.v1.lang.meta.Instruction fate_instruction: @@ -1310,6 +1335,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        {           fate_instruction.get_visited_by(this);        } +      compiler.registers().pop_hierarchical_instruction_level();        result.add        ( diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterContext.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterContext.java index 620188b..cffe1cc 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterContext.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterContext.java @@ -1,10 +1,12 @@  package tonkadur.wyrd.v1.compiler.util.registers; -import java.util.Map; -import java.util.HashMap; +import java.util.ArrayDeque; +import java.util.ArrayList;  import java.util.Collection; +import java.util.Deque; +import java.util.HashMap;  import java.util.List; -import java.util.ArrayList; +import java.util.Map;  import tonkadur.wyrd.v1.lang.meta.Instruction; @@ -18,6 +20,7 @@ class RegisterContext     protected final String name;     protected final Map<String, Register> register_by_name;     protected final Map<String, Register> aliased_registers; +   protected final Deque<Collection<String>> hierarchical_aliases;     protected final Map<Type, List<Register>> anonymous_register_by_type;     protected final String name_prefix;     protected int generated_registers; @@ -28,6 +31,7 @@ class RegisterContext        register_by_name = new HashMap<String, Register>();        aliased_registers = new HashMap<String, Register>(); +      hierarchical_aliases = new ArrayDeque<Collection<String>>();        anonymous_register_by_type = new HashMap<Type, List<Register>>();        name_prefix = default_name_prefix; @@ -41,6 +45,7 @@ class RegisterContext        register_by_name = new HashMap<String, Register>();        aliased_registers = new HashMap<String, Register>();        anonymous_register_by_type = new HashMap<Type, List<Register>>(); +      hierarchical_aliases = new ArrayDeque<Collection<String>>();        this.name_prefix = name_prefix;        generated_registers = 0; @@ -132,6 +137,11 @@ class RegisterContext        }        aliased_registers.put(name, reg); + +      if (!hierarchical_aliases.isEmpty()) +      { +         hierarchical_aliases.peekFirst().add(name); +      }     }     public void unbind (final String name) @@ -139,6 +149,19 @@ class RegisterContext        aliased_registers.remove(name);     } +   public void push_hierarchical_instruction_level () +   { +      hierarchical_aliases.push(new ArrayList<String>()); +   } + +   public void pop_hierarchical_instruction_level () +   { +      for (final String s: hierarchical_aliases.pop()) +      { +         unbind(s); +      } +   } +     public Register get_register (final String name)     {        final Register result; diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java index 847bb73..0fa9d50 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java @@ -232,6 +232,16 @@ public class RegisterManager        return context.peekFirst().get_finalize_instructions();     } +   public void push_hierarchical_instruction_level () +   { +      context.peekFirst().push_hierarchical_instruction_level(); +   } + +   public void pop_hierarchical_instruction_level () +   { +      context.peekFirst().pop_hierarchical_instruction_level(); +   } +     public Collection<DictType> get_context_structure_types ()     {        final Collection<DictType> result; | 


