`GO_TO_TAG`, `GO_TO_END` and `APPLY_CREATURE_VARIATION` can break nesting

Bug Report

How to reproduce

[CREATURE:TEST]
    [COPY_TAGS_FROM:HUMAN]
    [GO_TO_TAG:TL_COLOR_MODIFIER:BROWN:1]
    [CV_REMOVE_TAG:TL_COLOR_MODIFIER:BROWN:1]
    [APPLY_CURRENT_CREATURE_VARIATION]
    [TL_COLOR_MODIFIER:ASH_GRAY:1:BLACK:1:CHARCOAL:1:GRAY:1:SLATE_GRAY:1:TAUPE_GRAY:1]

How often does this bug happen?: Always

Result

An unknown_token error occurs:

image

Expected

The code that causes this error is in fact valid; the example given essentially finds and replaces TL_COLOR_MODIFIER here in [CREATURE:HUMAN]:

image

But the problem is that that the example code (with GO_TO_TAG) is currently seen as invalid, because:

[TL_COLOR_MODIFIER:ASH_GRAY:1:BLACK:1:CHARCOAL:1:GRAY:1:SLATE_GRAY:1:TAUPE_GRAY:1]

Is not in a valid nesting position; it needs to have a SET_TL_GROUP above it, and it doesn't in this case.

But for DF it all works out because by using GO_TO_TAG:TL_COLOR_MODIFIER, I have actually ensured that ultimately, SET_TL_GROUP will be above it, but our LS isn't able to figure that out because it would have to run through the logic of COPY_TAGS_FROM and GO_TO_TAG to figure out where TL_COLOR_MODIFIER is actually being placed.

And therefore the LS marks it as "unknown token", and that's the problem basically.

Additional Information

As implied in the title, a similar problem applies for GO_TO_END due to doing essentially the same thing (jumping to a position that may have valid nesting), and it applies to APPLY_CREATURE_VARIATION, as APPLY_CREATURE_VARIATION can contain any number of tokens "inside" it which are later unpacked by DF, and so at the end of it there may be a valid "begin to nest here" point, but our LS won't see it.

We discussed this issue and potential solutions here: https://discord.com/channels/762761192510455850/763525168408166402/925043628341075988

In the longterm, what needs to be done is a "second pass" using semantic analysis where we actually do generate the object (using COPY_TAGS_FROM and all) to get the end result object, but in the meantime, we need some kind of stopgap measure that doesn't make the whole file break after this.

Version

  • DF Language Server version: 0.2.2
  • OS: Linux
Edited by Mr Crabman