ID:2061007
 
Resolved
#define macros that used strings with embedded expressions were parsed incorrectly when the substitution was made.
BYOND Version:510.1331
Operating System:Windows 10 Home 64-bit
Web Browser:Firefox 45.0
Applies to:Dream Maker
Status: Resolved (513.1539)

This issue has been resolved.
Descriptive Problem Summary:
Commas within strings passed to macros are interpreted by the compiler as multiple arguments

Numbered Steps to Reproduce Problem:
1. Try to compile code snippet

Code Snippet (if applicable) to Reproduce Problem:
#define MY_MACRO(X) throw EXCEPTION("X = [X]")

/proc/go()
MY_MACRO("a,b,c,d")


Expected Results:
Exception with text X = a,b,c,d

Actual Results:
Compile error (incorrect number of macro arguments)

Does the problem occur:
Every time? Or how often? Every time
In other games? Yes
In other user accounts? Not tested
On other computers? Not tested

When does the problem NOT occur?
When there are no commas present in the passed string

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit http://www.byond.com/download/build to download old versions for testing.)
Not tested

Workarounds:
Use html escaped commas
Are you sure the problem isn't that you have a blank [] in the exception? The correct code for your expected results would be:

#define MY_MACRO(X) throw EXCEPTION("X = [X]")


[edit]
I stand corrected. The correct code is what produces the error. The empty [] will not.

I ran a few quick tests, and it appears the problem is that one macro is calling another. If you replace EXECPTION(...) with new/exception(...,__FILE__,__LINE__) the error disappears. So it's the nested macro that's the issue.
oh of course, EXCEPTION is a macro, silly of me.
Thankyou
Of course it's still a bug, since EXCEPTION is not acting correctly in this case.
Interesting;
#define MACRO_A(x) throw EXCEPTION(x) // works fine with 'MACRO_A("1,2,3")'
#define MACRO_B(x) throw EXCEPTION("[x]") // does *not* work fine with 'MACRO_B("1,2,3")'
#define MACRO_C(x) throw EXCEPTION(text("[]", x)) // also fine


edit: EXCEPTION is not at fault;
#define I(x) x
#define A(x) I("A([x])")

/world/New()
world.log << A("foo,bar") // error: incorrect number of macro arguments
del(src)


double edit:
#define I(x) x
#define A(x) I("A([x])")

/world/New()
world.log << A("(") // three errors:
// error: missing ) in macro call
// error: ): expected }
// error: location of top-most unmatched {
del(src)

#define I(x) x
#define A(x) I("A([x])")

/world/New()
world.log << A("\"") // two errors:
// error: unterminated text (expecting ")
// error: bad embedded expression ["\"""]]
del(src)
Nadrew changed status to 'Verified'
Oh god what.
#define I(x) x
#define A(x) I("A([x])" // note no closing bracket here

/world/New()
world.log << A(")")
del(src)

This compiles. Output is "A( [two spaces] )".

#define I(x) x
#define A(x) I("A([x])"

/world/New()
world.log << A("foo) + \"bar\"")
del(src)

A(foo [2 spaces] + "bar")
WHAT.
Two macros aren't even necessary. The problem seems to be that the preprocessor doesn't actually recognize embedded text expressions at all, and just happens to coincidentally pass them through, unless there's a comma or closing parenthesis that it treats as a meaningful character.

#define testmacro(X) world.log << X

world/New()
testmacro("This string, with a comma, is fine")
testmacro("["This embedded string is fine"]")
// ^ The preprocessor sees this as two separate strings with non-string words in between.
testmacro("["This embedded string, with commas, is seen as separate arguments"]")
// error: incorrect number of macro arguments
testmacro("["This embedded string with a ) ends the macro early"]")
// error: error: ): expected }


I tried to replace a text-handling proc with a macro. With this bug, it did not end well.
That actually makes a lot of sense as to the behaviour of the bug.
Descriptive Problem Summary:
Preprocessor incorrectly parses comas in strings in proc calls interpolated in strings as delimiters for itself, when they are not delimeters for anything.

Numbered Steps to Reproduce Problem:
Compile code below. It won't.

Code Snippet (if applicable) to Reproduce Problem:
#define chatmessage(target,message) target << message

/world/New()
chatmessage(world, "<span class='message'>[pick("Option One","Option,Two","Option Three")]</span>")

#undef chatmessage


Expected Results:
Compiling to work.

Actual Results:
error: incorrect number of macro arguments


Does the problem occur:
Every time? Or how often? Yes
In other games? Yes
In other user accounts? Yes
On other computers? Yes

When does the problem NOT occur?
If you use HTML-encoded comas which is a silly workaround.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? Also occurs in 513 but it won't let me post in that category.

Workarounds:
If you use HTML-encoded comas which is a silly workaround.
In response to Arokha
Also can I mention I am having a hell of a time posting anything? I get:

Error: you are not authorized to post a comment here: Identity confirmation failed.

or a message about being unable to save a post. Even on this comment.
In response to Arokha
In response to Arokha
Arokha, I suspect there's something odd going on with the forums and your browser. I'd like to explore this more with you at some point if you message me.
Lummox JR resolved issue with message:
#define macros that used strings with embedded expressions were parsed incorrectly when the substitution was made.