You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Tom Alexander c3fe7b47af
Added a test for backtracking.
DustJS appears to not do any backtracking.
4 years ago
..
README.md Added a test for backtracking. 4 years ago
input1.json Added a test for backtracking. 4 years ago
main.dust Added a test for backtracking. 4 years ago

README.md

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:

{
  "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"}}

Scoping

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.

Itermediate scopes appear to not be added. For example:

{
  "globals": {
    "item": "pencil",
    "things": {"color": "purple"}
  },
  "people": [
    {"name": "Dave"},
    {"name": "Emily", "item": "pen"}
  ]
}

If we walk into people and then into globals.things in one step, globals will not be added to the dynamic scope:

(attempts to read from the context in-order starting with the first line)

Starting access context:
{"globals":{"item":"pencil","things":{"color":"purple"}},"people":[{"name":"Dave"},{"name":"Emily","item":"pen"}]}

After walk "people":
[{"name":"Dave"},{"name":"Emily","item":"pen"}]
{"globals":{"item":"pencil","things":{"color":"purple"}},"people":[{"name":"Dave"},{"name":"Emily","item":"pen"}]}

After walk globals.things
{"color":"purple"}
[{"name":"Dave"},{"name":"Emily","item":"pen"}]
{"globals":{"item":"pencil","things":{"color":"purple"}},"people":[{"name":"Dave"},{"name":"Emily","item":"pen"}]}

So if we were on the "Dave" iteration in people and I attempted to read "item" it would not find a value despite "item" being a key in the lexical context above globals.things.

Backtracking

Item resolution appears to be greedy. For example if we have:

{
  "clothes": {
    "shirt": "t-shirt",
    "pants": "jeans"
  },
  "alice": {
    "clothes": {
      "shirt": "tank top"
    }
  },
  "bob": {},
}

If we walked into alice and then attempted to read clothes.pants it will return nothing because alice has a clothes block but no pants element inside that. However, if we walked into bob and attempted to read clothes.pants it would return jeans because bob does not have a clothes block so it would walk up to the global clothes block.