Coding 2020-04-04
I got a little bit more done on the port earlier today, but I also looked over the code, and realized that I'd already gone over all of the code that would have to be changed for a particular behavior change I wanted, and I hadn't changed it, which means it must be possible to write a failing test case for that behavior. And it is. Given the following Ink file:
* Text: {a|b}
-
The choice displays initially as "Text: a", and, after it is taken, as "Text: b". (Followed by a newline.) I spent a bit of time trying to figure out how to change this behavior, and, once again contrary to my initial expectations, it's not obvious to me right now. The problem is that, at least according to my ad-hoc prints, it's hard to get a sense of "context" within the VM's stack-based execution.
I've got an idea, which I'm just going to write up, and not attempt yet, that the following might be a workable starting point:
When the parent of the "previous path" is not an ancestor of the "current path", stop visiting containers "at the start", until the "current path" is not a descendant of the first "current path", modulo sticking a tunnel in the middle, so I guess this would have to be tracked on the stack. Or maybe following a choice needs to put some new data on the stack to determine when to start tracking data again.
I'm pretty sure that first idea would break most things catastrophically, so I'm not going to try it right now.
One thing that all this messing around has made me realize is that I've got a bunch of not-all-compatible things I want out of this port.
One is to basically audit the codebase, and submit the Python version to automatic analysis that can hopefully shed light on the C# version. This requires relative fidelity to the original codebase.
Another is to have a version of Ink that I can easily use in my Python projects. The big priority here is optimization, followed by adding features that I want.
I'm going to take a stab at explaining what happens with the Ink code I posted above, so I can get my thoughts in order:
- Ink begins expression evaluation.
- It assigns the label "0.0.$r1" to the local variable "$r"
- It begins string evaluation.
- It jumps to "0.0.s"
- "0.0.s.0" pushes text to the stack
- "0.0.s.1" contains the sequence logic. This is the part where I want to monkey with the visit count logic. Several internal diverts are hit in this.
- "0.0.s.2" diverts to the label stored in "$r"
- At this stage, the code after the label ends string evaluation, ends expression evaluation, bundles the value into a Choice, and knows to stop and not output anything else because... I'm not sure right now.
- Anyway, the test follows the generated Choice, which ultimately redirects to "0.c-0"
- This increments the visit count, which is necessary.
- Anyway, next it stores the label "0.c-0.$r2" in "$r", and redirects back to "0.0.s". This increments the visit counts, which I would like not to happen.
- "0.0.s" runs through its logic as normal, but now the final divert leads to "0.c-0.$r2".
Perhaps if following a choice made it so that:
- Detect entering the target path of the choice
- When the choice's container is diverted out of
- Suspend visit count increments until
- The container is diverted back into.
That might work. Maybe. And it still might break things. I'll have to try this out later. For now, it's late and I'm tired.
Good night.