| 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; |


