Fixed hexpression example
This commit is contained in:
@@ -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.'}
|
||||||
@@ -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.
|
||||||
@@ -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, ...)
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
11
hank/ViewCounts.hx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package hank;
|
||||||
|
|
||||||
|
class ViewCounts {
|
||||||
|
public function new(ast: HankAST) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resolve(identifier: String, scope: String): Int {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user