Divert target vars via more interp extension. Close #48

This commit is contained in:
2019-06-04 16:35:03 -06:00
parent 0cc6be32c6
commit 075f001107
4 changed files with 89 additions and 3 deletions

View 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.

View 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.

View File

@@ -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.
**/

View File

@@ -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) {