ID:2356099
 
BYOND Version:511
Operating System:Windows 10 Home
Web Browser:Chrome 65.0.3325.181
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Descriptive Problem Summary:
The compiler tends to be oddly sensitive to the indentation of closing curly braces when mixing indentation styles. While I understand that mixing indentation should generally be discouraged, this sticks out as a really odd issue.

What's even more odd is that this sensitivity seems to be related to the pre-processor and macros. Specifically: manually expanded sections (example proc1) compile just fine, but if you note down their equivalent using macros, the compiler suddenly refuses to accept it.

Code Snippet (if applicable) to Reproduce Problem:
var/list/my_list = list()

// The functional proc. This compiles just fine.
/proc/test_proc1()
for (var/a in my_list) { var/A = a;
world << A
}

#define FOR_T(o, w, ty) for (var/##o in w) { ##ty = o;
#define END_FOR_T }

// This works. For some reason.
/proc/test_proc2()
FOR_T(a, my_list, var/A)
world << A
END_FOR_T

// This breaks.
/proc/test_proc3()
FOR_T(a, my_list, var/A)
world << A
END_FOR_T // <-- this line errors out.


Expected Results:
All three examples compile just fine. Specially since the manually expanded example works fine. I do not see why or how the macros would be breaking things, outside of unintended pre-processor tomfoolery.

Actual Results:
Procs 1 and 2 compile. 3 produces an error:

error: inconsistent indentation or missing '}'
error: inconsistent indentation or extra '}'

For reference: both errors reference the line with END_FOR_T on it.

Does the problem occur:
Every time? Or how often? Every time.
In other games? N/A, compiler issue.
In other user accounts? N/A, compiler issue.
On other computers? N/A, compiler issue.

When does the problem NOT occur?

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? Tested and replicated on 511.1369, 512.1407, 512.1416.

Workarounds:
Since the original goal was to utilize macros for typeless looping, example 2 is a workaround for the issue encountered in example 3. Though it is not ideal! Closing statements for block macros should be on the same indentation level.
I believe the reason for this is that the indentation is effectively processed twice when you have the #define involved.

In the working proc you have the ReadIndent() call that also is capable of checking for the brace and "getting" it. In the #define version ReadIndent() doesn't see a brace, but it does see the lower indent level and creates a virtual one, and then the #define macro replaces the text with a brace of its own. That's why leaving END_FOR_T indented works.

In this specific case of course you don't need the END_FOR_T macro at all, so you could simply ditch it.

TBH this is not going to be an easy thing to fix and I just don't see any value in throwing time at it.