bablr-lang / agast-vm

A VM providing DOM-like guarantees about agAST trees
MIT License
1 stars 0 forks source link

Implement path ranges #3

Open conartist6 opened 4 weeks ago

conartist6 commented 4 weeks ago

Currently we use ctx.prevTerminals and ctx.nextTerminals (which should properly be termed ctx.prevTags and ctx.nextTags) to be able to construct ranges like [startTag, endTag]. Essentially each tag becomes a node in a doubly linked list. Thus a range can be as simple as an array of two tags (the head and tail pointers for traversal), yet still offer access to all the content inside it.

The idea is to swap that range implementation for a less weak one: [startPath, endPath]. Without the weak maps the paths will store path.referenceIndex and path.parentNode properties in addition to the current path.reference. This should be enough information for a path to mark a position in the tree in such a way that it is possible to look around through your siblings, e.g. with state.tagPaths.get(path.parentNode.children[path.referenceIndex + 1]) (a mouthful, so we'll want to wrap it up in a more natural API)

And one last note: we cannot safely store a node directly on a path (as path.node) because in this system because paths are completely immutable (they don't contain any state and thus don't branch). For that reason we store nodes weakly on paths (which I sometimes annotate path~.node) so that we can go back and fix up the weak link if we have to.

conartist6 commented 4 weeks ago

This was not previously possible to implement because path objects were surviving between multiple runs of the parser, but this is no longer happening.

The rationale for making the change is that it makes the system's state more self-evident, especially when using a debugger