xNVSE / NVSE

New Vegas Script Extender (NVSE)
https://git.io/JfSAo
702 stars 55 forks source link

Expression Parse funcs don't work well in certain contexts #173

Open Demorome opened 11 months ago

Demorome commented 11 months ago

I made the mistake of defining GetSelfAlt with DEFINE_CMD_ALT_EXP, meaning it uses the custom NVSE Expression Parser. The function works in basic contexts like calling it to store the result in a ref variable, but if you start using it in complex expressions it breaks down.

For example, this is broken as of writing:

if eval (GetSelfAlt != player)
   ; eval returns true even though player is the calling ref, and the "!=" operator code isn't even called at all
endif

But with regular GetSelf, which uses the default parser, this works as expected:

if eval (GetSelf != player)
   ; does not reach this space of code, as expected since GetSelf is not the player in this context
endif

Indeed, when switching GetSelfAlt to the regular parser, it starts working in this context again.

My guess is that the expression parser just doesn't work well with functions that have no args whatsoever, so I'll be simply sidestepping the issue since I couldn't find an obvious fix.

EDIT: This guess is wrong, I can replicate the issue with Call:

    if eval (player.Call ReturnCallingRefUDF != player)
        print "???????"  ; reached, wtf?
    endif 
scn ReturnCallingRefUDF
begin Function { }
    SetFunctionValue (GetSelf)
end

I've further studied some other cases, here are the results:

    if (GetSelfAlt_OLD != player)
        print "????? x 4"  ; does NOT print
    endif

    if ((GetSelfAlt_OLD) != player)
        print "????? x 5"  ; does NOT print
    endif

    if eval (GetSelfAlt_OLD != player)
        print "????? x 6"  ; prints
    endif

    if eval ((GetSelfAlt_OLD) != player)
        print "????? x 7" ; does NOT print
    endif

    if eval GetSelfAlt_OLD != player
        print "????? x 8" ; prints
    endif

GetSelfAlt_OLD here being the version that uses the expression parser.