Author Topic: #IF  (Read 1952 times)

Biterider

  • Member
  • **
  • Posts: 241
  • ObjAsm32 - ObjAsm64
    • 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: 1178
    • uasm
Re: #IF
« Reply #31 on: June 19, 2018, 04:47:18 PM »
 :t
Cod-Father

johnsa

  • Member
  • ****
  • Posts: 710
    • Uasm
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: 241
  • ObjAsm32 - ObjAsm64
    • ObjAsm64
Re: #IF
« Reply #33 on: September 29, 2018, 05:51:59 PM »
Hello johnsa
Good to hear from you!  8)
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: 710
    • Uasm
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: 8832
  • Assembler is fun ;-)
    • MasmBasic
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.inc

ifndef @Defined
  @Defined MACRO arg
ifdef arg
EXITM <1>
else
EXITM <0>
endif
  ENDM
endif

.data
MyArray dd 25, 18, 23, 17, 9, 2, 6

.code
start:
  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"
  exit

end start

Biterider

  • Member
  • **
  • Posts: 241
  • ObjAsm32 - ObjAsm64
    • 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: 8832
  • Assembler is fun ;-)
    • MasmBasic
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.inc

ifndef @Defined
  @Defined MACRO arg
ifdef arg
DefResult equ <arg>
EXITM <arg>
else
DefResult equ <0>
EXITM <0>
endif
  ENDM
endif


.code
start:
  _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 " "
  exit

end start

Output (identical for UAsm and ML 6.15):
Code: [Select]
1020     = _MSC_VER, defined as equal or above 1020

1000     = _MSC_VER (UNDEFINED or less than 1020)

0        = _MSC_NOSUCHVER (UNDEFINED or less than 1020)

Biterider

  • Member
  • **
  • Posts: 241
  • ObjAsm32 - ObjAsm64
    • 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  :t , 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.  :idea:

Biterider

johnsa

  • Member
  • ****
  • Posts: 710
    • Uasm
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: 241
  • ObjAsm32 - ObjAsm64
    • 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
  endm
endif

;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
    ret
end start

Biterider

johnsa

  • Member
  • ****
  • Posts: 710
    • Uasm
Re: #IF
« Reply #41 on: November 09, 2018, 09:12:03 PM »
Just an update on this issue for 2.47..

The issue becomes more complex and the reason the 2nd example doesn't work is the expansion of the macro in a conditional assembly expression.
The only real solution to this problem would be to create a new operator (like le, gt etc) to use in expressions which tests for the defined state of a symbol as opposed to the macro approach.

Alternatively, and I've not tried this.. what is the outcome of using OPATTR against the symbol if defined / undefined, that may already work and be usable in an expression ?