Revert "WIP nightmare working on #69"

This reverts commit 47031d0077.
This commit is contained in:
2019-06-15 16:59:02 -06:00
parent 47031d0077
commit e01b20b1c1
2 changed files with 18 additions and 69 deletions

View File

@@ -2,8 +2,6 @@ package hank;
using Reflect;
using Type;
using Lambda;
using StringTools;
import haxe.ds.Option;
import hscript.Parser;
@@ -46,7 +44,7 @@ class HankInterp extends Interp {
default:
throw 'Dereferencing complex expressions is not implemented';
}
// Divert target variables are just StoryNode values
// TODO Divert target variables are just StoryNode values
case EUnop("->", true, e):
// trace(e);
var targetWithDots = '';
@@ -74,7 +72,6 @@ class HankInterp extends Interp {
}
}
// TODO need to allow local variables
override function assign(e1:Expr, e2:Expr):Dynamic {
var v = expr(e2);
switch (e1) {
@@ -90,35 +87,6 @@ class HankInterp extends Interp {
return super.assign(e1, e2);
}
}
override function forLoop(n,it,e) {
var old = declared.length;
declared.push({ n : n, old : variables.get(n) });
var it = makeIterator(expr(it));
while( it.hasNext() ) {
locals.set(n,{ r : it.next() });
try {
expr(e);
} catch( err : Stop ) {
switch( err ) {
case SContinue:
case SBreak: break;
case SReturn: throw err;
}
}
}
restore(old);
}
override function restore( old : Int ) {
while( declared.length > old ) {
var d = declared.pop();
variables.set(d.n,d.old);
}
}
}
}
/**
@@ -136,7 +104,7 @@ class HInterface {
interp.setStory(story);
}
public function new(viewCounts:Map<StoryNode, Int>) {
public function new(storyTree:StoryNode, viewCounts:Map<StoryNode, Int>) {
this.parser = new Parser();
parser.unops["*"] = false;
parser.unops["&"] = false;
@@ -145,30 +113,15 @@ class HInterface {
this.interp.variables['_isTruthy'] = isTruthy.bind(viewCounts);
this.interp.variables['_valueOf'] = valueOf.bind(viewCounts);
this.interp.variables['_resolve'] = resolveInScope.bind(interp.variables);
this.interp.variables['_resolveField'] = resolveField.bind(interp.locals, interp.variables);
this.interp.variables['_resolve'] = resolveInScope.bind(this.interp.variables);
this.interp.variables['_resolveField'] = resolveField.bind(this.interp.variables);
this.viewCounts = viewCounts;
}
public function clone(): HInterface {
var c = new HInterface(viewCounts);
for (name in interp.variables.keys.toIterable().filter(function(name) { return !name.startsWith("_"); })) {
c.interp.variables[name] = interp.variables[name];
}
// Local variables of embedded Haxe become globals of that embedded Hank
var locals = interp.locals;
trace(locals);
for (name in locals.keys()) {
trace('$name: ${locals[name]}');
c.addVariable(name, locals[name]);
}
return c;
}
static function resolveInScope(locals: Map<String, Dynamic>, variables:Map<String, Dynamic>, name:String):Dynamic {
var scope:Array<Dynamic> = cast(variables['_scope'], Array<Dynamic>);
static function resolveInScope(variables:Map<String, Dynamic>, name:String):Dynamic {
var scope:Array<Dynamic> = cast(variables['scope'], Array<Dynamic>);
for (container in scope) {
switch (resolve(locals, variables, container, name)) {
switch (resolve(variables, container, name)) {
case Some(v):
return v;
case None:
@@ -178,15 +131,12 @@ class HInterface {
throw 'Could not resolve $name in scope $scope.';
}
static function resolveField(locals:Map<String, Dynamic>, variables:Map<String, Dynamic>, container:Dynamic, name:String):Dynamic {
return resolve(locals, variables, container, name).unwrap();
static function resolveField(variables:Map<String, Dynamic>, container:Dynamic, name:String):Dynamic {
return resolve(variables, container, name).unwrap();
}
static function resolve(locals:Map<String, Dynamic>, variables:Map<String, Dynamic>, container:Dynamic, name:String):Option<Dynamic> {
if (locals.exists(name) && locals[name] != null) {
return Some(locals[name]);
}
else if (variables.exists(name)) {
static function resolve(variables:Map<String, Dynamic>, container:Dynamic, name:String):Option<Dynamic> {
if (variables.exists(name)) {
return Some(variables[name]);
} else if (Std.is(container, StoryNode)) {
var node:StoryNode = cast(container, StoryNode);
@@ -240,16 +190,16 @@ class HInterface {
Run a pre-processed block of Haxe embedded in a Hank story.
**/
public function runEmbeddedHaxe(h:String, scope:Array<Dynamic>) {
interp.variables['_scope'] = scope;
interp.variables['scope'] = scope;
// trace(h); // TODO toggle in verbose mode
// trace(h);
var expr = parser.parseString(h);
expr = transmute(expr);
interp.execute(expr);
}
public function expr(h:String, scope:Array<Dynamic>):Dynamic {
interp.variables['_scope'] = scope;
interp.variables['scope'] = scope;
var expr = parser.parseString(h);
expr = transmute(expr);

View File

@@ -91,14 +91,13 @@ class Story {
function embeddedStory(h:String):Story {
var ast = parser.parseString(h);
var embeddedHInterface = hInterface.clone();
var story = new Story(random, // embedded stories must continue giving deterministic random numbers without resetting -- to avoid exploitable behavior
parser, ast, // embedded stories have their OWN AST of Hank statements
// but they keep the parent's view count tree and current scope
storyTree,
nodeScopes, viewCounts, embeddedHInterface);
nodeScopes, viewCounts, hInterface);
story.exprIndex = 0;
story.parent = Some(this);
return story;
@@ -121,7 +120,7 @@ class Story {
var nodeScopes = [storyTree];
var viewCounts = storyTree.createViewCounts();
var hInterface = new HInterface(viewCounts);
var hInterface = new HInterface(storyTree, viewCounts);
var story = new Story(random, new Parser(), ast, storyTree, nodeScopes, viewCounts, hInterface);
hInterface.setStory(story);
@@ -449,7 +448,7 @@ class Story {
var newScopes = if (target.startsWith("@")) {
var parts = target.split('.');
var root:Array<StoryNode> = cast hInterface.getVariable(parts[0].substr(1));
var root:Array<StoryNode> = hInterface.getVariable(parts[0].substr(1));
if (parts.length > 1) {
var subTarget = parts.slice(1).join('.');
// trace(subTarget);
@@ -571,7 +570,7 @@ class Story {
}
/** Parse and run embedded Hank script on the fly. **/
public function runEmbeddedHank(h:String, locals) {
public function runEmbeddedHank(h:String) {
embedMode = Tunnel;
embeddedBlocks.push(embeddedStory(h));
}