From 45facfed0df2d61a82fc205780d88d9b09b6bf5e Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sun, 3 May 2020 16:13:29 -0400 Subject: [PATCH] Improve the walk up test to prove that DustJS is doing dynamic scoping, not lexical scoping. --- js/test_cases/walk_up/README.md | 33 +++++++++++++++++++++++++++++++ js/test_cases/walk_up/input1.json | 2 +- js/test_cases/walk_up/main.dust | 1 + src/renderer/renderer.rs | 1 + 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 js/test_cases/walk_up/README.md diff --git a/js/test_cases/walk_up/README.md b/js/test_cases/walk_up/README.md new file mode 100644 index 0000000..f30e7cc --- /dev/null +++ b/js/test_cases/walk_up/README.md @@ -0,0 +1,33 @@ +Through experimentation it seems that you can walk up to access higher levels in the context. Interestingly enough, it seems that walking up to a higher context does not unwind the context stack but instead seems to add the higher level context element to the bottom. For example: + +```js +{ + "foo": { + "f1": "f", + "f2": "ff" + }, + "bar": { + "b1": "b", + "b2": "bb" + } +} +``` + +if we walk down into bar and then into foo then our variable look ups appear to follow this pattern: +``` +(attempts to read from the context in-order starting with the first line) + +Starting access context: +{"foo":{"f1":"f","f2":"ff"},"bar":{"b1":"b","b2":"bb"}} + +After walk "bar": +{"b1":"b","b2":"bb"} +{"foo":{"f1":"f","f2":"ff"},"bar":{"b1":"b","b2":"bb"}} + +After walk "foo": +{"f1":"f","f2":"ff"} +{"b1":"b","b2":"bb"} +{"foo":{"f1":"f","f2":"ff"},"bar":{"b1":"b","b2":"bb"}} +``` + +This appears to be using dynamic scoping instead of lexical scoping. For example, in lexical scoping a read of "b1" would fail after that final walk because you're inside the "foo" context which does not have any "b1" in or above it, however, since this is using dynamic scoping its using the invocations to build a scope tree rather than their original position. diff --git a/js/test_cases/walk_up/input1.json b/js/test_cases/walk_up/input1.json index 993ee52..1d96d10 100644 --- a/js/test_cases/walk_up/input1.json +++ b/js/test_cases/walk_up/input1.json @@ -6,6 +6,6 @@ "people": [ {"name": "Alice", "job": "Chief Swinger"}, {"name": "Bob", "job": "Chief Swayer"}, - {"name": "Chris", "job": "Barista", "company": "GenericCoffee"} + {"name": "Chris", "job": "Barista", "company": "GenericCoffee", "email": "thecoffeeguy@generic.coffee"} ] } diff --git a/js/test_cases/walk_up/main.dust b/js/test_cases/walk_up/main.dust index af4f875..94a2d2f 100644 --- a/js/test_cases/walk_up/main.dust +++ b/js/test_cases/walk_up/main.dust @@ -1,4 +1,5 @@ Directory for {company}:{~n} {#people} {name}: {job} at {company} (email: {globals.email}){~n} +Testing walking after entering a parent context {#globals}job: {job}, email: {email}, company: {company}{/globals}{~n} {/people} diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index d542a61..d260408 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -181,6 +181,7 @@ impl<'a> DustRenderer<'a> { fn walk_path<'a>( context: &'a dyn ContextElement, path: &Vec<&str>, + breadcrumbs: Vec<&'a dyn ContextElement>, ) -> Result<&'a dyn ContextElement, RenderError<'a>> { let mut output = context;