Multiline macro expander doesn't handle square brackets
enclosure:
%define foo1(x) x
%macro foo2 1-*
%error %1
%endm
%error foo1( {1, {2}, 3} ) ; result: 1, {2}, 3
foo2 {1, {2}, 3} ; result: 1, {2
This is bug, I suppose, and I'll fix it.
Current behaviour doesn't allow some interesting syntax,
like hierachical structure initialization:
;foo structure definition:
;foo.a, foo.b, foo.bar.a, foo.bar.b, foo.c
initstruc foo, {v1, v2, {v3, v4}, v5}
Logged In: YES
user_id=804543
Yeah, preproc.c's count_mmac_params() and expand_mmacro()
functions don't count opening/closing curly braces, like
the expand_smacro() function does. Which is why -- as of
writing this -- one can't pass "{.+}" as an argument to
a multi-line macro, i.e. a closing curly brace.
Logged In: YES
user_id=804543
As noted by Nickolay, a comma between the arguments of
a single-line macro invocation didn't act like a "}",
and thus lead to incorrect argument treatment. The fix
is to set brackets to 0 just after the 2nd of the three
occurences of "white = 0;" in preproc.c.
With that bug out of the way, I'll look at multi-line
macro arguments and curly braces next.
Logged In: YES
user_id=806493
I've redesigned a bit multiline macro expansion - now only
count_mmac_params() counts and demarcates parameters.
And does it correctly. I've also renamed is_mmacro() to
get_mmacro(), which returns full-formed multiline macro
reference with filled parameters array (this is not in CVS yey,
of course - it's for Nasm 0.99).
Logged In: YES
user_id=804543
Since Nickolay's re-write of preproc.c isn't likely
to be accepted until it has been (a) spec'd/approved
and (b) thoroughly verified by a substantial number
of users and developers, I have started to work on a
fix for the existing preproc.c, that can be used in
the meantime.
I think that I've got it, but I want to do some more
testing first.
So stay tuned...
Logged In: YES
user_id=804543
I've got everything to work, except for one case.
How does one pass the opening curly brace '{' as
an argument to a single-line macro?
In case of a multi-line macro it can be done, as
long as it is the last argument.
However, in case of a single-line macro there has
to be a closing parenthesis. Which, if preceded by
an opening curly brace, just becomes part of that
last (literal) argument and thus causes an error
due to a missing closing parenthesis.
All those curly braces made my head hurt... 8-)
Let me know if you're interested in my testcases.
Logged In: YES
user_id=804543
I have found the answer to my question.
Since single-line macro arguments are counted before
they are expanded, the opening curly brace '{' can be
passed as a single-line macro argument by "wrapping"
it in another single-line macro, like so:
%define oc {
%define smac(x) x
%error [smac(oc)] ; filename.asm:3: warning: [{]
Btw, the same trick won't work for multi-line macro
arguments, because single-line macros are expanded
before multi-line macros are. That is, a multi-line
macro would see '{' instead of 'oc'.
However, with my upcoming fixes one can pass '{{'
as the last argument of a multi-line macro -- this
will result in '{'.
That said, I'm in the process of wrapping up those
fixes; I'll post them shortly. As well as all the
testcases I've come up with.
Logged In: YES
user_id=804543
I've posted my changes and testcases to the nasm-devel
list, since I can't seem to attach them here.
Logged In: YES
user_id=806493
I don't think we should use such hacks for '{' itself. This is a
control token anyway. And it should have a pair - otherwise
error must be given. If we want to use it as usual token we
should add escape syntax (like \{ ). But I think if someone
wants to pass safely complex token list into a multiline macro
he can use following syntax:
%define oc {
%define smac(x) x
foo %detok(smac(x)) ; foo "{"
where foo is:
%macro foo 1
%xdefine param1 %strtok(%1)
...
%endm
We'll get the expected result.
And one even may pass something monsterous in this way:
foo "{(,{)[]"
Logged In: YES
user_id=804543
Yes, normally curly braces should be used in pairs and
the outer-most pair should enclose an entire parameter.
However, there are occasions when I need to pass single
opening or closing curly braces to a single- or multi-
line macro. For example, during my debug output macros.
I did consider adding support for a more generic escape
mechanism a la backslash (and in fact had to do so for
the primitive assembler directives, to be able to use a
closing square bracket in an argument), but shied away
from attempting such an intrusive overall change, which
would have rammifications in many places through NASM.
So, instead I ended up relying on existing NASM behavior
as mentioned in my previous update to this bug report.
On a side note...
For now I've got to live with the existing preprocessor,
not one that may one day supersede it... or not. To me a
step by step improvement is way more valuable, than one
big fat re-write, which I can't verify in any reasonable
amount of time. Read: %DETOK, %STRTOK, or function-like
syntax are -- as of writing this -- not an option to me.
It's kinda like when someone suggests "use YASM". ;-)
Logged In: YES
user_id=806493
I just ask you not to introduce any doubtful behaviour as
usual for Nasm. This syntax is unsafe. How will you pass '}' to
the macro?
> For now I've got to live with the existing preprocessor,
> not one that may one day supersede it... or not.
No, not supersede - extend the right word. And fix a lot of
bugs. I've sent a lot of comments with it in my last 'preproc.c'
message (but I cannot see attaches in the mail list).
Step-by-step improvement is slow. After a lot of patches
preprocessor had to be refactored.
Logged In: YES
user_id=804543
> I just ask you not to introduce any doubtful
> behaviour as usual for Nasm.
I didn't introduce any new behavior.
I just tried to fix the existing one that was broken.
> This syntax is unsafe.
Perhaps.
I never claimed that the curly brace solution is ideal.
> How will you pass '}' to the macro?
Check out the testcases I posted earlier.
In particular, read the comments they contain.
As for the pros and cons of your massive preprocessor
work -- that's a separate debate, which doesn't really
belong into this particular bug report. I should not
have brought it up here -- my apologies for doing so.
Logged In: YES
user_id=806493
During single line macro function call '{' and '}' enclosure
would be counted only if '{' is in the start of parameter:
foo({a}) ; a
foo(\{a}) ; \{a}
So, escape syntax already exists. I think, the same must be
done with multiline macro.