### Author Topic: #IF  (Read 1248 times)

#### Biterider

• Member
• Posts: 230
• ObjAsm32 - ObjAsm64
##### Re: #IF
« Reply #30 on: June 19, 2018, 03:51:42 PM »
Hi Habran
I can not say for sure until I have a working set of files. My best guress is that it will not be needed.
Biterider

#### habran

• Member
• Posts: 1175
##### Re: #IF
« Reply #31 on: June 19, 2018, 04:47:18 PM »

Cod-Father

#### johnsa

• Member
• Posts: 696
##### Re: #IF
« Reply #32 on: September 17, 2018, 06:43:56 PM »
Proposing the following fix:

The core of the issue is that user defined macros are not allowed to received undefined symbols as arguments.
So while IFDEF someUndefinedVar  works, passing that down via a macro will break.

Proposed fix is to allow an undefined symbol to propagate down through the user macro IFF the macro name is "defined"
We can either provide a built-in defined macro, which would be overridden by a user including an INC file such as the Windows headers that define their own defined macro.

#### Biterider

• Member
• Posts: 230
• ObjAsm32 - ObjAsm64
##### Re: #IF
« Reply #33 on: September 29, 2018, 05:51:59 PM »
Hello johnsa
Good to hear from you!
I can not say anything about the assembler internals and if your suggestion will fix the problem. BTW, ML behaves in the same way.
I only want to be sure that the problem is well understood.

In the last few weeks I implemented a super lightweight conditional evaluator using the well known "shunting-yard algorithm" in combination with a tristate truth tables (TRUE, FALSE, ERROR). In this way I was able to evaluate such cases as described above. Eventually such an approach could also solve the problem.

Just my 2 cents.

Biterider

#### johnsa

• Member
• Posts: 696
##### Re: #IF
« Reply #34 on: September 30, 2018, 03:18:46 AM »
Hi,

I agree that it is definitely expected behaviour, but we can do better.. why not have a proper "defined" macro that just works and can be combined in other expressions.. it would be backwards compatible and still allow any other approach/method to work too.. so .. we'll just do it :)

#### jj2007

• Member
• Posts: 8776
• Assembler is fun ;-)
##### Re: #IF
« Reply #35 on: September 30, 2018, 03:38:34 AM »
why not have a proper "defined" macro

I would suggest @Defined(somesymbol), for consistency with @SubStr(), @CatStr() etc. ML coders could use a workaround:
Code: [Select]
`include \masm32\include\masm32rt.incifndef @Defined  @Defined MACRO arg ifdef arg EXITM <1> else EXITM <0> endif  ENDMendif.dataMyArray dd 25, 18, 23, 17, 9, 2, 6.codestart:  if @Defined(MyArray) print "MyArray is defined", 13, 10  else print "MyArray is UNDEFINED", 13, 10  endif  if @Defined(NotMyArray) print "NotMyArray is defined", 13, 10  else print "NotMyArray is UNDEFINED", 13, 10  endif  inkey "that was easy"  exitend start`

#### Biterider

• Member
• Posts: 230
• ObjAsm32 - ObjAsm64
##### Re: #IF
« Reply #36 on: September 30, 2018, 04:26:33 AM »
Hi
Sorry, but right now I do not see the point.
A typical problematic C code line (winerror.h) looks like this

Code: [Select]
`#if defined (_MSC_VER) && (_MSC_VER> = 1020)`
The current translation would be

Code: [Select]
`if Defined(_MSC_VER) and (_MSC_VER ge 1020)`
If _MSC_VER is not defined here, only the second part of the conditional sentence is problematic because the symbol is undefined and in this case it should not be evaluated because of the use of the logical "and" operator.

I'm using a modified version of Japheth's WinInc defined macro.

Code: [Select]
`  ifndef Defined    Defined macro x      ifdef x        exitm <-1>                      ;-1 to be able to use the 'NOT' operator.      else                              ;Not(-1) = 0 (FALSE)        exitm <0>      endif    endm  endif`
Maybe you can explain with an example what you want to do.

Biterider

#### jj2007

• Member
• Posts: 8776
• Assembler is fun ;-)
##### Re: #IF
« Reply #37 on: September 30, 2018, 05:51:24 AM »
OK, here is a tailored example, with a small modification of the macro:
Code: [Select]
`include \masm32\include\masm32rt.incifndef @Defined  @Defined MACRO arg ifdef arg DefResult equ <arg> EXITM <arg> else DefResult equ <0> EXITM <0> endif  ENDMendif.codestart:  _MSC_VER equ <1020>  if @Defined(_MSC_VER) ge 1020 print str\$(DefResult), 9 print " = _MSC_VER, defined as equal or above 1020", 13, 10, 10  else print str\$(DefResult), 9 print " = _MSC_VER (UNDEFINED or less than 1020)", 13, 10, 10  endif  _MSC_VER equ <1000> if @Defined(_MSC_VER) ge 1020 print str\$(DefResult), 9 print " = _MSC_VER, defined as equal or above 1020", 13, 10, 10  else print str\$(DefResult), 9 print " = _MSC_VER (UNDEFINED or less than 1020)", 13, 10, 10  endif if @Defined(_MSC_NOSUCHVER) ge 1020 print str\$(DefResult), 9 print " = _MSC_NOSUCHVER, defined as equal or above 1020", 13, 10, 10  else print str\$(DefResult), 9 print " = _MSC_NOSUCHVER (UNDEFINED or less than 1020)", 13, 10, 10  endif  inkey " "  exitend start`
Output (identical for UAsm and ML 6.15):
Code: [Select]
`1020     = _MSC_VER, defined as equal or above 10201000     = _MSC_VER (UNDEFINED or less than 1020)0        = _MSC_NOSUCHVER (UNDEFINED or less than 1020)`

#### Biterider

• Member
• Posts: 230
• ObjAsm32 - ObjAsm64
##### Re: #IF
« Reply #38 on: October 01, 2018, 02:32:20 AM »
Hi JJ
Thanks for your proposal which works for this example case  , but we don't have to forget about all other possible logical combinations (using NOT, AND, OR, XOR) with more than only 1 argument!
The second issue is the C translation. Using this approach, the original conditional sentence has to be analysed and replaced by a modified/reorganized version. This is a very complex and error prone task.
I'm still convinced that there is only one correct way to solve the original issue adding more robustness and flexibility to the assembler as I described before.

@johnsa: can you elaborate your idea a bit more so I can understand what you have in mind. An example would be very helpful.

Biterider

#### johnsa

• Member
• Posts: 696
##### Re: #IF
« Reply #39 on: October 01, 2018, 06:28:41 PM »
Sure,

The root of the problem is that internally "IFDEF X" inherently assembles correctly whether X is defined or not, as this is it's purpose. IFDEF only supports a single argument. The problem comes in that if you attempt to create ANY sort of user-level macro like DEFINED(x) the parsing of the macro itself will fail as x is undefined, and undefined symbols are not allowed to be passed to regular macros.
So the idea was to build this macro in, and special case it to allow a direct substitution of the name (ie: x) into the macro body. That way a composite expression should evaluate as planned:

.if defined(x) AND somethingElse EQ 1
.endif

etc.. without any hacks to supports a specific combination or use of AND operator.

#### Biterider

• Member
• Posts: 230
• ObjAsm32 - ObjAsm64
##### Re: #IF
« Reply #40 on: October 01, 2018, 07:41:52 PM »
Hi johnsa
Thanks for your answer. I understand what you want to achieve. Strange for me is, that the "@Defined" macro works also with undefined symbols. The following code demonstrates the point. If you define MY_SYMBOL all is fine, but commenting it out, the second conditional sentence can not be compiled (UASM & ML).

Code: [Select]
`ifndef @Defined  @Defined macro x    ifdef x      exitm <-1>                                      ;-1 to be able to use the 'NOT' operator.    else                                              ;Not(-1) = 0 (FALSE)      exitm <0>    endif  endmendif;MY_SYMBOL equ  5.code                                          start:                                              if @Defined(MY_SYMBOL)       echo AAAA    else      echo BBBB    endif    if not @Defined(MY_SYMBOL)       echo AAAA    else      echo BBBB    endif    if @Defined(MY_SYMBOL) and MY_SYMBOL ge 10       echo CCCC    else      echo DDDD    endif    retend start`
Biterider