Divert target vars via more interp extension. Close #48
This commit is contained in:
41
examples/divert-vars/main.hank
Normal file
41
examples/divert-vars/main.hank
Normal file
@@ -0,0 +1,41 @@
|
||||
~ var target = ->knot1;
|
||||
-> start
|
||||
|
||||
== start
|
||||
|
||||
-> @target
|
||||
|
||||
= stitch1
|
||||
Text 3
|
||||
~ target = ->stitch2;
|
||||
-> start
|
||||
= stitch2
|
||||
Text 4
|
||||
~ target = ->gather1
|
||||
-> start
|
||||
- (gather1)
|
||||
Woooow!
|
||||
~target = ->finish.real_finish.real_tricky;
|
||||
->start
|
||||
|
||||
== knot1
|
||||
|
||||
Text 1
|
||||
~ target = ->knot2
|
||||
-> start
|
||||
|
||||
== knot2
|
||||
|
||||
Text 2
|
||||
~ target = ->finish;
|
||||
-> start
|
||||
|
||||
== finish
|
||||
|
||||
Seems to have worked! Time to get more complicated.
|
||||
~target = ->start.stitch1
|
||||
->start
|
||||
|
||||
= real_finish
|
||||
|
||||
- (real_tricky) That's incredible.
|
||||
7
examples/divert-vars/test1.hlog
Normal file
7
examples/divert-vars/test1.hlog
Normal file
@@ -0,0 +1,7 @@
|
||||
Text 1
|
||||
Text 2
|
||||
Seems to have worked! Time to get more complicated.
|
||||
Text 3
|
||||
Text 4
|
||||
Woooow!
|
||||
That's incredible.
|
||||
@@ -10,9 +10,14 @@ import hscript.Expr;
|
||||
|
||||
using hank.Extensions;
|
||||
import hank.StoryTree;
|
||||
import hank.Story;
|
||||
|
||||
class HankInterp extends Interp {
|
||||
var hInterface: HInterface;
|
||||
var story: Story;
|
||||
public function setStory(story: Story) {
|
||||
this.story = story;
|
||||
}
|
||||
public function new(hInterface: HInterface) {
|
||||
this.hInterface = hInterface;
|
||||
super();
|
||||
@@ -20,7 +25,7 @@ class HankInterp extends Interp {
|
||||
public override function expr(e: Expr): Dynamic {
|
||||
switch (e) {
|
||||
// pointers are actually just string keys to the Interp's variables.
|
||||
// TODO Divert target variables are just fully qualified strings that can be passed to divertTo()
|
||||
|
||||
case EUnop("&", true, e):
|
||||
switch (e) {
|
||||
case EIdent(id):
|
||||
@@ -35,6 +40,28 @@ class HankInterp extends Interp {
|
||||
default:
|
||||
throw 'Dereferencing complex expressions is not implemented';
|
||||
}
|
||||
// TODO Divert target variables are just StoryNode values
|
||||
case EUnop("->", true, e):
|
||||
trace(e);
|
||||
var targetWithDots = '';
|
||||
var trailingDot = false;
|
||||
while (true) {
|
||||
switch (e) {
|
||||
case EIdent(lastTarget):
|
||||
targetWithDots = lastTarget + '.' + targetWithDots;
|
||||
if (trailingDot) targetWithDots = targetWithDots.substr(0,targetWithDots.length-1);
|
||||
var node = story.resolveNodeInScope(targetWithDots);
|
||||
trace (node);
|
||||
return node;
|
||||
case EField(eNested, lastTarget):
|
||||
targetWithDots = lastTarget + '.' + targetWithDots;
|
||||
|
||||
trailingDot = true;
|
||||
e = eNested;
|
||||
default: throw 'Divert target variable cannot be specified in form $e';
|
||||
}
|
||||
}
|
||||
|
||||
default: return super.expr(e);
|
||||
}
|
||||
|
||||
@@ -68,11 +95,15 @@ class HInterface {
|
||||
var interp: HankInterp;
|
||||
var viewCounts: Map<StoryNode, Int>;
|
||||
|
||||
public function new(storyTree: StoryNode, viewCounts: Map<StoryNode, Int>) {
|
||||
public function setStory(story: Story) {
|
||||
interp.setStory(story);
|
||||
}
|
||||
public function new(storyTree: StoryNode, viewCounts: Map<StoryNode, Int>) {
|
||||
|
||||
this.parser = new Parser();
|
||||
parser.unops["*"] = false;
|
||||
parser.unops["&"] = false;
|
||||
parser.unops["->"] = false;
|
||||
this.interp = new HankInterp(this);
|
||||
|
||||
this.interp.variables['_isTruthy'] = isTruthy.bind(viewCounts);
|
||||
@@ -149,6 +180,10 @@ class HInterface {
|
||||
this.interp.variables[identifier] = value;
|
||||
}
|
||||
|
||||
public function getVariable(identifier: String) {
|
||||
return this.interp.variables[identifier];
|
||||
}
|
||||
|
||||
/**
|
||||
Run a pre-processed block of Haxe embedded in a Hank story.
|
||||
**/
|
||||
|
||||
@@ -87,6 +87,7 @@ class Story {
|
||||
var hInterface = new HInterface(storyTree, viewCounts);
|
||||
|
||||
var story = new Story(random, new Parser(), ast, storyTree, nodeScopes, viewCounts, hInterface);
|
||||
hInterface.setStory(story);
|
||||
hInterface.addVariable('story', story);
|
||||
|
||||
story.runRootIncludedHaxe(script);
|
||||
@@ -245,6 +246,7 @@ class Story {
|
||||
exprIndex = gatherIndex;
|
||||
}
|
||||
|
||||
@:allow(hank.HankInterp)
|
||||
private function resolveNodeInScope(label: String, ?whichScope: Array<StoryNode>): Array<StoryNode> {
|
||||
if (whichScope == null) whichScope = nodeScopes;
|
||||
|
||||
@@ -292,8 +294,9 @@ class Story {
|
||||
}
|
||||
|
||||
// trace('diverting to $target');
|
||||
|
||||
|
||||
var newScopes = resolveNodeInScope(target);
|
||||
var newScopes = if (target.startsWith("@")) hInterface.getVariable(target.substr(1)) else resolveNodeInScope(target);
|
||||
var targetIdx = newScopes[0].astIndex;
|
||||
|
||||
if (targetIdx == -1) {
|
||||
|
||||
Reference in New Issue
Block a user