summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4136
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java26
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterContext.java29
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java10
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;