Fixed hexpression example

This commit is contained in:
2019-03-17 19:45:42 -06:00
parent caf2f82b55
commit c57dcdc539
8 changed files with 76 additions and 22 deletions

View File

@@ -2,7 +2,8 @@
Have you tried inserting {test} in your Hank stories? Have you tried inserting {test} in your Hank stories?
~ var good = true; ~ var good = true;
Rumor has it, it can be {if (good) { Rumor has it, it can be {if (good) {
'rewarding' 'rewarding';
} else { } else {
'obnoxious' 'obnoxious';
}} to write a story with {test}. }} to write a story with {test}.
Null values will simply not appear.{if (!good) 'Invisible.'}

View File

@@ -1,2 +1,3 @@
Have you tried inserting dynamic content in your Hank stories? Have you tried inserting dynamic content in your Hank stories?
Rumor has it, it can be rewarding to write a story with dynamic content. Rumor has it, it can be rewarding to write a story with dynamic content.
Null values will simply not appear.

View File

@@ -13,38 +13,73 @@ class HInterface {
var parser: Parser = new Parser(); var parser: Parser = new Parser();
var interp: Interp = new Interp(); var interp: Interp = new Interp();
var viewCounts: ViewCounts;
public function new(?variables: Map<String, Dynamic>) { public function new(viewCounts: ViewCounts) {
if (variables != null) { this.viewCounts = viewCounts;
interp.variables = variables;
this.interp.variables['_isTruthy'] = isTruthy;
}
static function isTruthy(v: Dynamic) {
switch (Type.typeof(v)) {
case TBool:
return v;
case TInt | TFloat:
return v > 0;
default:
throw '$v cannot be coerced to a boolean';
} }
} }
public function getVariable(v: String) { public function addVariable(identifier: String, value: Dynamic) {
return interp.variables[v]; this.interp.variables[identifier] = value;
} }
/** /**
Run a pre-processed block of Haxe embedded in a Hank story. Run a pre-processed block of Haxe embedded in a Hank story.
**/ **/
public function runEmbeddedHaxe(haxe: String) { public function runEmbeddedHaxe(h: String) {
var expr = parser.parseString(haxe); trace(h);
var expr = parser.parseString(h);
expr = transmute(expr); expr = transmute(expr);
interp.execute(expr); interp.execute(expr);
} }
public function evaluateExpr(h: String): String {
var expr = parser.parseString(h);
trace(expr);
expr = transmute(expr);
var val = interp.expr(expr);
if (val == null) {
return '';
} else {
return Std.string(val);
}
}
public function resolve(identifier: String, scope: String): Dynamic {
if (interp.variables.exists(identifier)) {
return interp.variables[identifier];
} else {
return viewCounts.resolve(identifier, scope);
}
}
/** /**
Convert numerical value expressions to booleans for binary operations Convert numerical value expressions to booleans for binary operations
**/ **/
function boolify(expr: Expr): Expr { function boolify(expr: Expr): Expr {
// TODO this won't work in cases where the expression is already a bool return ECall(EIdent('_isTruthy'), [expr]);
return EBinop('>', expr, EConst(CInt(0)));
} }
/** /**
Adapt an expression for the embedded context Adapt an expression for the embedded context
**/ **/
function transmute(expr: Expr) { function transmute(expr: Expr) {
if (expr == null) {
return null;
}
return switch (expr) { return switch (expr) {
case EIdent(name): case EIdent(name):
// TODO if the name is a root-level view count, return EArray(view_counts, ...) // TODO if the name is a root-level view count, return EArray(view_counts, ...)

View File

@@ -151,6 +151,7 @@ class Output {
fullOutput += t; fullOutput += t;
case AltExpression(a): case AltExpression(a):
case HExpression(h): case HExpression(h):
fullOutput += hInterface.evaluateExpr(h);
case InlineDivert(t): case InlineDivert(t):
case ToggleOutput(o, b): case ToggleOutput(o, b):
if (b != displayToggles) { if (b != displayToggles) {

View File

@@ -30,14 +30,11 @@ class Story {
parser = new Parser(); parser = new Parser();
ast = parser.parseFile(script); ast = parser.parseFile(script);
// viewCounts = new ViewCounts(ast);
var variables = [ var viewCounts = new ViewCounts(ast);
'story' => this/*,
'viewCounts' => viewCounts hInterface = new HInterface(viewCounts);
*/ hInterface.addVariable('story', this);
];
hInterface = new HInterface(variables);
exprIndex = ast.findFile(script); exprIndex = ast.findFile(script);
} }
@@ -51,6 +48,11 @@ class Story {
case EOutput(output): case EOutput(output):
exprIndex += 1; exprIndex += 1;
return HasText(output.format(hInterface, false)); return HasText(output.format(hInterface, false));
case EHaxeLine(h):
exprIndex += 1;
hInterface.runEmbeddedHaxe(h);
return nextFrame();
default: default:
return Finished; return Finished;
} }

View File

@@ -23,7 +23,7 @@ class StoryTestCase extends utest.Test {
// Allow white-box story testing through variable checks prefixed with # // Allow white-box story testing through variable checks prefixed with #
if (StringTools.startsWith(line, "#")) { if (StringTools.startsWith(line, "#")) {
var parts = StringTools.trim(line.substr(1)).split(':'); var parts = StringTools.trim(line.substr(1)).split(':');
HankAssert.equals(StringTools.trim(parts[1]), Std.string(story.hInterface.getVariable(parts[0]))); HankAssert.equals(StringTools.trim(parts[1]), Std.string(story.hInterface.resolve(parts[0], '')));
} }
if (StringTools.startsWith(line, "*")) { if (StringTools.startsWith(line, "*")) {
// Collect the expected set of choices from the transcript. // Collect the expected set of choices from the transcript.

11
hank/ViewCounts.hx Normal file
View File

@@ -0,0 +1,11 @@
package hank;
class ViewCounts {
public function new(ast: HankAST) {
}
public function resolve(identifier: String, scope: String): Int {
return 0;
}
}

View File

@@ -4,13 +4,14 @@ import utest.Test;
import utest.Assert; import utest.Assert;
import hank.HInterface; import hank.HInterface;
import hank.ViewCounts;
class HInterfaceTest extends utest.Test { class HInterfaceTest extends utest.Test {
var hInterface: HInterface; var hInterface: HInterface;
public function setup() { public function setup() {
hInterface = new HInterface(); hInterface = new HInterface(new ViewCounts([]));
} }
function assertVar(name: String, value: Dynamic) { function assertVar(name: String, value: Dynamic) {
@@ -20,6 +21,8 @@ class HInterfaceTest extends utest.Test {
public function testVarDeclaration() { public function testVarDeclaration() {
hInterface.runEmbeddedHaxe('var test = "str"'); hInterface.runEmbeddedHaxe('var test = "str"');
assertVar('test', 'str'); assertVar('test', 'str');
hInterface.runEmbeddedHaxe('var test2 = 2');
assertVar('test2', 2);
} }
public function testBoolification() { public function testBoolification() {