CommandHelper

CommandHelper

46.5k Downloads

"Using undefined variable" in procedure default argument

LadyCailinBot opened this issue ยท 3 comments

commented

CMDHELPER-3030 - Reported by PseudoKnight

@A = 0;
proc _test(@b = @A) {

code

}

In this case you will get a:
"[ERROR][RUNTIME] Using undefined variable: @A"
on the proc line.

Either this is a bug or behavior has changed since this documentation was written:
http://wiki.sk89q.com/wiki/CommandHelper/Procedures#Default_Values

commented

Comment by LadyCailin

Nah, this has nothing to do with proc's behaviors, rather, the fact that @A is (incorrectly) not in scope per the mechanism that the undefined variable finder algorithm uses to detect that. So, I just need to add an exception for that case.

commented

Comment by PseudoKnight

Do you have an idea on how you would change this? It's happening in the optimization phase, but I'm not fully sure what this section is doing, if anything yet. Nor is it clear how one should best solve this. The test environment is of course missing the variables. I could put a flag in the environment to bypass the assignment check, but that seems non-optimal. But maybe you had an idea already?

https://github.com/EngineHub/CommandHelper/blob/master/src/main/java/com/laytonsmith/core/MethodScriptCompiler.java#L1795

commented

Comment by LadyCailin

Well, the Procedure constructor should have the current variable tree passed into it, so it can determine which variables are defined outside of the proc definition, and then add specifically those variables into the variable table inside the proc. But I don't recall offhand where the variable table is stored in that section of the code. It may not be at all, in which case, we need to figure that out beforehand. But actually, we need to write a proper scoping mechanism that takes into account the design mentioned here: http://forum.enginehub.org/threads/scope-change-impact-study.15669/ which might be a prerequisite before we can finish this task. The variable table should be created before optimize() is called anyways, because even if a variable usage/definition is optimized out, the code should still be checked for correctness. The code written that generates the variable table will only be used in optimization unfortunately, because we need different code in the interpreter to actually maintain the variable table in runtime (which will also hold values, not just meta info.) On the bright side, once that code is written, it should be relatively straightforward to start doing compile time type checks on things that define types, which currently would only be user code, but would eventually expand to built in functions.