Menu

#29 Ternary operator and %include parameter

open
nobody
None
1
2004-02-15
2003-06-21
No

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

Discussion

1 2 > >> (Page 1 of 2)
  • Nobody/Anonymous

    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

     
  • Nickolay Yurchenko

    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.

     
  • Nickolay Yurchenko

    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.

     
  • Nobody/Anonymous

    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?

     
  • Nickolay Yurchenko

    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.

     
  • Nickolay Yurchenko

    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?

     
  • Nickolay Yurchenko

    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'.

     
  • Nickolay Yurchenko

    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.

     
  • Nickolay Yurchenko

     
  • Nobody/Anonymous

    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...

     
  • Nickolay Yurchenko

    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.

     
  • Nickolay Yurchenko

    Ternary operator with enclosure

     
  • nasm64developer

    nasm64developer - 2003-08-10

    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. :-)

     
  • nasm64developer

    nasm64developer - 2003-08-11

    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.

     
  • Nickolay Yurchenko

    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.

     
  • nasm64developer

    nasm64developer - 2003-08-18

    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.)

     
  • nasm64developer

    nasm64developer - 2003-08-18

    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.

     
  • Nickolay Yurchenko

    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

     
  • nasm64developer

    nasm64developer - 2003-08-19

    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.

     
  • Nickolay Yurchenko

    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.

     
  • nasm64developer

    nasm64developer - 2004-02-15
    • priority: 5 --> 1
     
  • nasm64developer

    nasm64developer - 2004-02-15

    Logged In: YES
    user_id=804543

    I've got working code in my local forked version.

    Both for 1) and 2).

     
  • Nobody/Anonymous

    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 `?'."

     
  • nasm64developer

    nasm64developer - 2005-09-26

    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.

     
  • nasm64developer

    nasm64developer - 2005-12-02

    left-to-right grouping in NASM

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.