1) Single line macro is commonly useless without
conditional operation. I mean something like this:
%define abs(x) x>=0 ? x : -x
2) It would be very helpful if %include macro gives a
predefined parameter like this:
%define incfile "inc\foo.inc"
%include incfile
or if %define macro output reprocessed like this:
%define incfile %include "inc\foo.inc"
incfile
Logged In: NO
I agree that having support for a "x ? y : z" operator
would be nice. However, we would have to come up with
a different syntax for it, because "?" can not only be
used inside a NASM identifier, but also to start one.
As for %INCLUDE -- recent versions of NASM will expand
single-line macros inside the string argument. So do:
%DEFINE incfile inc\foo.inc
%INCLUDE "incfile"
Last but not least, NASM scans lines for preprocessor
directives before it expands single-line macros, and
before it expands multi-line macros into their lines.
So if you define a single-line macro that expands into
a preprocessor directive, then that directive is not
going to work. However, if you wrap that directive in
a multi-line macro, then it will work, because lines
expanded from a multi-line macro are processed again:
%MACRO incfile 0
%INCLUDE "inc\foo.bar"
%ENDMACRO
incfile
Logged In: YES
user_id=806493
1) Maybe use '%?' and '%:' instead '?' and ':' ?
2) I wrote such macro:
%macro INCLUDE 1.nolist
%include %1
%endmacro
But in %rep cycle only first INCLUDE works correctly, the next
ones generating errors.
Logged In: YES
user_id=806493
1) Maybe use '%?' and '%:' instead '?' and ':' ?
2) I wrote such macro:
%macro INCLUDE 1.nolist
%include %1
%endmacro
But in %rep cycle only first INCLUDE works correctly, the next
ones generating errors.
Logged In: NO
1) A leading "%" denotes preprocessor functionality. So
it wouldn't be a good pick. How about just removing
the "?" from the list of characters that can be used
to start an identifier? (Doing so would be drastic,
but supporting an "x ? y : z" operator would probably
out-weigh such a break in backwards compatibility.)
2) Can you please provide a more detailed example?
Logged In: YES
user_id=806493
1) Yes, symbol '?' is unusual symbol for identifier start (by the
way, I don't understand why '~' symbol is considered to be
identifier part).
2) Yes, of course (I just was at work and I didn't have
sources), here is part of my library:
%assign sourceCount 0
%imacro INCLUDE 1.nolist
%include %1
%endmacro
%imacro SOURCE 1.nolist
%push SOURCE
%assign %$sourceNum sourceCount
%define sourcePath_%{$sourceNum} %1
%pop
%assign sourceCount sourceCount+1
%endmacro
%imacro ProgramEnd 0.nolist
%push ProgramEnd
%assign %$sourceNum 0
%rep sourceCount
INCLUDE sourcePath_%{$sourceNum}
%assign %$sourceNum %$sourceNum+1
%endrep
%pop
%endmacro
I use this macros for post-include libraries sources by defining
path to them with SOURCE macro and finishing program with
ProgramEnd.
After first include other iterations in ProgramEnd macro returns
errors:
error: parser: instruction expected
error: symbol `INCLUDE' redefined
I tested %rep cycle with other macro instead INCLUDE, where
was directly described ways to all my source files and there
was no problem.
Logged In: YES
user_id=806493
And about %include.
Do not you think this way to pass macro parameters in string
is unusual? Maybe to change (or expand) it before it will be
described in documentation (at least, I did not find
description of such behaviour of %include)?
Do not you think that this behaviour would be more
convinient:
%DEFINE incfile "inc\foo.inc"
%INCLUDE incfile
And at last why this form of %include not allows the entire
content of macro parameter to be surrounded by quotes?
Logged In: YES
user_id=806493
I have implemented support of ternary operator to nasm.
This requires from me to change a bit grammar parse tree:
1) Any expression now passes all steps of relation parser
(rexp0, rexp1, rexp2, rexp3). To signal that it was a relation
operator in expression I introduced special flag 'is_relation'. In
each of relation parser functions sets this flag when they meet
relation instruction. If relational operators not supported in
expression there will be a warning after evaluation (it is more
useful than error 'comma or end of line expected' because
signalizes what happened and allows to compile code - relation
operators in Nasm gives scalar result).
2) There is new parser function 'texpr' replacing bexpr place in
parsing tree (bexpr no more needed on account of (1) ). It
parses ternary operation '?:'.
3) I also added support of no-evaluating expressions by adding
new flag to 'critical' parameter: NOT_EVAL = 0x0200. This is
necessary when we evaluating such expression:
%define safediv(x,y) y!=0 ? x/y : 0
Then the first branch must not evaluates when y = 0, in other
way we will have 'division by zero'. When parser function
receives 'critical' with NOT_EVAL flag set it does not try to
evaluate parsed parameters - only to pass them and return
unknown_expr().
4) At last, I implemented support of '!' operator (similar to
x==0) in expr6 (in the same branch with '~' operator).
Why need to pass all relational branches? It is done because
ternary operator may return result without relations based on
relational switch. We could not know beforehand whether we
meet '?' or not and should parse first part of expression
expecting ternary operator. Passing all relation steps may
slowdown compiler, because simple expressions will be started
with 5 unnecessary calls and so much returns. But I think it
will be units of percents and optimizations will help to speed it.
Incompatibility: I removed '?' character from isidstart() list.
Using '?' as identifier character was documented.
Disadvantages:
1) There is no such syntax support now:
a ? x ? y : z : b
This expression must look so:
a ? (x ? y : z) : b
2) Still no possibility to write recursion function, like factorial:
%define fact(x) x>0 ? x*fact(x-1) : 1
Because recursion will be avoided by expand_smacro()
function, called before expression evaluation.
My feature must be hardly tested and improved, but I think it
would be very useful.
There are two diff files in archive ternar0.zip - for 'eval.c' and
for 'nasm.h'.
Logged In: YES
user_id=806493
Sorry, I submitted reverse-compared diff files in ternar0.zip,
but it seems, it was not attached :-). The correct one is
ternar1.zip.
Logged In: NO
I have started to look at your eval.c work.
The '!' operator should really be introduced in its
own change. Also, sharing the code between the '~'
and the '!' operator does not seem to work: all the
sudden '~' seems to behave like '!'. Only when I
replicate the whole '~' code for '!', do I get the
expected results.
Will you provide a separate '!' diff, or shall I?
As for the ternary operator -- I will need more time
to look at those changes. One thing that definitely
needs to go away is that parentheses requirement for
nested ternary operators...
Logged In: YES
user_id=806493
Yes, of course, I will make new version with better nested '?:'
operators processing and without '!' as soon as possible. I
think it would be better to move our discussion to the
developers forum.
Ternary operator with enclosure
Logged In: YES
user_id=804543
I have started to review, modify, and test Nickolay's
proposed evaluator changes, needed for a conditional
ternary operator. Overall they turned out to be a very
useful starting point.
The proposed nasm.h change contains a minor bug: while
it does remove '?' from isidstart(), it fails to add
the '?' character "back in" to isidchar(), so that one
can still use it inside an identifier -- just no longer
as the first character.
Also, in light of SF request 786285, handing any flags
down with "critical" should be abandoned. So instead of
the NOT_EVAL flag I added a global boolean variable in
eval.c, which determines whether operators should be
ignored because of a ternary operator's false branch.
(I will e-mail my modified diff, since I can't seem to
attach it here.)
One item that remains to be resolved is the handling of
a particular case of an incomplete ternary expression:
one that omits the expression between '?' and ':'. When
I looked at GCC for guidance, I found that it uses the
numeric value of the ternary condition:
0 ? : 2 results in 2
1 ? : 3 results in 1
2 ? : 3 results in 2
I'm not yet sure whether NASM should match that case, or
treat it as an "expression syntax error" (just like all
the other incomplete cases).
Last but not least, I did verify the proper operation,
including nesting and precedence, with a fair number of
test cases. Let me know if you are interested in them.
(Btw Nickolay, the concerns about parentheses did not
manifest themselves. Since the ternary operator groups
from right to left, it works just fine, even for that
nested case you mentioned. :-)
Logged In: YES
user_id=804543
The observed GCC behavior is a GNU-specific C extension.
http://gcc.gnu.org/onlinedocs/gcc-3.3/gcc/Conditionals.html#
Conditionals
I have updated my code to support it.
I'll post the required changes once I've finished testing.
Logged In: YES
user_id=806493
No, I think we should not support this "feature" in NASM. I
think, it has unpredictable behaviour.
As for global variables - this is discussable, but I prefer locals.
Logged In: YES
user_id=804543
uuv wrote in SF 786285:
> But the thing disturbing me much more is docummented
> example of using '?' as first identifier sign for
> masm-emulating syntax. What do you think? To remove
> this example from documentation (less compatibility -
> someone uses this syntax, of course) or to add partial
> support to this syntax (this is bad decision, I know)
> or to add a comand line key (this is bad too)?
Well, it comes down to making NASM's ternary operator
look like that of other languages (i.e. '?' and ':')
versus breaking backwards compatibility with previous
versions of NASM (by no longer allowing '?' to begin
an identifier).
Personally I think that the former does outweigh the
latter; that opinion has already been reflected in my
local forked version.
(So I don't really care what 0.98.xx will implement.)
Logged In: YES
user_id=804543
>> The observed GCC behavior is a GNU-specific C
>> extension.
>>
>>
http://gcc.gnu.org/onlinedocs/gcc-3.3/gcc/Conditionals.html#
Conditionals
>>
>> I have updated my code to support it.
>
> No, I think we should not support this "feature" in
> NASM. I think, it has unpredictable behaviour.
The GCC behavior is not only well-documented and
predictable, but it also addresses the case where
the first operand has side effects. (Follow that
link to read it in their words.)
So far NASM does not support such operands; how-
ever, a future version might do so.
In my local forked version I decided to support
this case, because (a) it was easy to do so, (b)
it addresses the aforementioned "scenario", and
(c) it follows GCC's precedence (which happens
to be a widely used tool).
That said, I don't really care whether 0.98.xx
will implement this case, or not.
Logged In: YES
user_id=806493
> That said, I don't really care whether 0.98.xx
will implement this case, or not.
I know you are doing your own version of Nasm and I don't
demand you to care about main 0.98.xx. I just want to do the
best and ask your advise.
About GCC behaviour:
%assign x 2
%if x
%assign foo 1
%else
%assign foo 0
%endif
; result: foo=1
%assign foo x ? 1 : 0
; result: foo=0
Logged In: YES
user_id=804543
> %assign x 2
> %if x
> %assign foo 1
> %else
> %assign foo 0
> %endif
> ; result: foo=1
Yep.
> %assign foo x ? 1 : 0
> ; result: foo=0
Nope. Because x (=2) is non-zero, the condition is true
and foo should become 1. Which it does, when I feed this
example to my local forked version of NASM.
Logged In: YES
user_id=806493
Sorry, I've misunderstanded your example. But I still don't
realise what good will it do. I think it may only make debug
harder.
Logged In: YES
user_id=804543
I've got working code in my local forked version.
Both for 1) and 2).
Logged In: NO
In several topics on this forum some folks are wondering:
"Who use '?', '@', '~', '#', and '.' tokens in labels?"
-- Compilers _do_ use all these.
Unlike other asms Nasm can serve as a dumb, mute,
laborous SLAVE, ready to fulfil every whim of his compiler
MASTER.
Nasm64 seems to restrict such freedom by (possibly)
introducing:
1) '?' as ternary operation token (why not "%?" )
2) '@' as physical location (or so) counter token
3) "#" as an alternative to "%define"
4) More to come...
The only thing left then will be a Nostalgie for the Golden Age
of Freedom and Paradise Lost when reading the old Nasm
manual:
"Valid characters in labels are letters, numbers, `_', `$', `#',
`@', `~', `.', and `?'. The only characters which may be used
as the _first_ character of an identifier are letters, `.' (with
special meaning: see section 3.9), `_' and `?'."
Logged In: YES
user_id=804543
> [identifier character set for NASM64]
As of writing this, NASM64 identifiers must be composed
of letters, digits, or [_.@#$~?]. Only letters or [_.@#]
may be used as the first character though.
So it is the exact same character set as in NASM, except
that [#] replaced [?] as a valid first character.
> 1) '?' as ternary operation token (why not "%?" )
Because (a) ? is more like C, and (b) %? could be used
for future preprocessor functionality.
> 2) '@' as physical location (or so) counter token
Note that you can still use the $ prefix, e.g. $@ for @.
> 3) "#" as an alternative to "%define"
Yes, the NASM64 preprocessor does allow # instead of % as
the initial character. This allows it to process certain
types of C-like source files. And it's optonal -- that is
the user must explicitly enable it.
> 4) More to come...
Actually, right now my wishlist is pretty short.
left-to-right grouping in NASM