Not-too-hackish pointers. Close #51.

This commit is contained in:
2019-06-04 15:40:02 -06:00
parent 3da00b36bd
commit 0cc6be32c6
5 changed files with 80 additions and 4 deletions

View File

@@ -0,0 +1,14 @@
```
var v1 = 'Variable 1';
var v2 = 'Variable 2';
var v3 = 'Variable 3';
```
{v1}
{&v1}
{v2}
~ v2 = &v1;
{v2}
{*v2}
~ *v2 = 'Value changed.';
{v1}

View File

@@ -0,0 +1,6 @@
Variable 1
v1
Variable 2
v1
Variable 1
Value changed.

View File

@@ -11,6 +11,52 @@ import hscript.Expr;
using hank.Extensions;
import hank.StoryTree;
class HankInterp extends Interp {
var hInterface: HInterface;
public function new(hInterface: HInterface) {
this.hInterface = hInterface;
super();
}
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):
return id;
default:
throw 'Addressing complex expressions is not implemented';
}
case EUnop("*", true, e):
switch (e) {
case EIdent(id):
return variables[variables[id]];
default:
throw 'Dereferencing complex expressions is not implemented';
}
default: return super.expr(e);
}
}
override function assign(e1: Expr, e2: Expr): Dynamic {
var v = expr(e2);
switch (e1) {
case EUnop("*", true, e):
switch (e) {
case EIdent(id):
variables[variables[id]] = v;
default:
throw 'Dereferenced assignment of complex expressions is not implemented.';
}
return v;
default:
return super.assign(e1, e2);
}
}
}
/**
Interface between a Hank story, and its embedded hscript interpreter
**/
@@ -18,16 +64,23 @@ import hank.StoryTree;
class HInterface {
var BOOLEAN_OPS = ['&&', '||', '!'];
var parser: Parser = new Parser();
var interp: Interp = new Interp();
var parser: Parser;
var interp: HankInterp;
var viewCounts: Map<StoryNode, Int>;
public function new(storyTree: StoryNode, viewCounts: Map<StoryNode, Int>) {
this.parser = new Parser();
parser.unops["*"] = false;
parser.unops["&"] = false;
this.interp = new HankInterp(this);
this.interp.variables['_isTruthy'] = isTruthy.bind(viewCounts);
this.interp.variables['_valueOf'] = valueOf.bind(viewCounts);
this.interp.variables['_resolve'] = resolveInScope.bind(this.interp.variables);
this.interp.variables['_resolveField'] = resolveField.bind(this.interp.variables);
this.viewCounts = viewCounts;
}
static function resolveInScope(variables: Map<String, Dynamic>, name: String): Dynamic {

View File

@@ -426,7 +426,7 @@ class Story {
null;
}
trace(typeName);
//trace(typeName);
if (typeName != null && insertionHooks.exists(typeName)) {
return insertionHooks[typeName](value);
}

View File

@@ -140,7 +140,7 @@ class StoryTestCase extends utest.Test {
var firstColonIdx = line.indexOf(':');
var index = Std.parseInt(line.substr(0, firstColonIdx))-1;
var expectedOutput = line.substr(firstColonIdx+1).trim();
// trace('expecting: ${expectedOutput}');
// trace('expecting: ${expectedOutput}');
var output = story.choose(index);
// trace('got: ${output}');
HankAssert.equals(expectedOutput, output);
@@ -148,6 +148,9 @@ class StoryTestCase extends utest.Test {
else if (line.length > 0) {
// Assert that the story's next frame is HasText(line)
// trace('${line} from ${frame}');
//trace('expecting: ${HasText(line)}');
//trace('got: $frame');
//trace('');
HankAssert.equals(HasText(line), frame);
}