News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

ISFLOAT? MACRO

Started by GoneFishing, October 18, 2015, 08:30:45 PM

Previous topic - Next topic

GoneFishing

Please help me to create  macro which performs check if its argument is a float.
My current not-working draft:
Quote
ISFLOAT? MACRO arg
         FORC c,<&arg>
             %echo c
             IFIDN c , <.>
             %echo arg is FLOAT!
             ENDIF   
         ENDM
ENDM

jj2007

You were pretty <close> ;)

include \masm32\include\masm32rt.inc
ISFLOAT? MACRO arg
         FORC c,<&arg>
             %echo c
             IFIDN <c> , <.>
             %echo arg is FLOAT!
             ENDIF   
         ENDM
ENDM

IsFloat MACRO arg
  if @InStr(1, <arg>, <.>)
EXITM <100>
  elseif @InStr(1, <arg>, <xmm>) eq 1
EXITM <112>
  elseif (opattr arg) eq 36
EXITM <101>
  elseif (opattr arg) eq 48
EXITM <111>
  elseifndef arg
EXITM <-77>
  elseif type(arg) eq DWORD
EXITM <102>
  elseif type(arg) eq QWORD
EXITM <103>
  elseif type(arg) eq REAL4
EXITM <104>
  elseif type(arg) eq REAL8
EXITM <105>
  elseif type(arg) eq REAL10
EXITM <106>
  else
.err @CatStr(<## unknown type ">, <arg>, <" in line >, %@Line, < ##>
  endif
ENDM

.code
mydw dd 123
myqw dq 123
myr4 REAL4 123.456
myr8 REAL8 123.456
myr10 REAL10 123.456
start:
  ISFLOAT? 123.456
  print str$(IsFloat(123.456)), 9, "immediate real", 13, 10
  print str$(IsFloat(123)), 9, "immediate integer", 13, 10
  print str$(IsFloat(mydw)), 9, "dword", 13, 10
  print str$(IsFloat(myqw)), 9, "qword", 13, 10
  print str$(IsFloat(myr4)), 9, "real4", 13, 10
  print str$(IsFloat(myr8)), 9, "real8", 13, 10
  print str$(IsFloat(myr10)), 9, "real10", 13, 10
  print str$(IsFloat(undefined)), 9, "undefined", 13, 10
  print str$(IsFloat(abcde)), 9, "undefined", 13, 10
  print str$(IsFloat(0abcdeh)), 9, "hex", 13, 10
  print str$(IsFloat(eax)), 9, "reg32", 13, 10
  print str$(IsFloat(xmm0)), 9, "xmm", 13, 10
  exit
end start


GoneFishing

#2
Thanks , Jochen  :t
I think your IsFloat is a whole GetType macro  :t
The solution is so simple. I'm ashamed

P.S.: Still there's a little  work for me to be done: check if arg is not  qouted string with dot(s)


mabdelouahab


DBC REAL4 0.0
DEF DWORD 0
k0 equ   type(DBC) eq DWORD
k1 equ   type(DBC) eq REAL4
k2 equ   type(DBC) eq SDWORD
% echo @CatStr(<result 1:>,%k0,<,result 2:>,%k1,<,result 3:>,%k2)

k01 equ   type(DEF) eq DWORD
k11 equ   type(DEF) eq REAL4
k21 equ   type(DEF) eq SDWORD
% echo @CatStr(<result 1:>,%k01,<,result 2:>,%k11,<,result 3:>,%k21)


Quote
result 1:0,result 2:-1,result 3:0
result 1:-1,result 2:0,result 3:0
0=FALSE and -1=TRUE

GoneFishing

Thank you,  mabdelouahab
Very non standart solution :t

GoneFishing

First working version  . Macro returns 1 if arg is FLOAT and 0 otherwise  so it can be used like this:
Quote
IF ISFLOAT?(arg)
    ; do something
ENDIF


include \masm32\include\masm32rt.inc

ISFLOAT? MACRO arg 
         IF @InStr(1, <arg>, <.>)
            quot SUBSTR <arg>,1,1
             IFIDN quot,<">   
                 %echo arg is not FLOAT!
                 EXITM <0>
             ENDIF         
            %echo arg is  FLOAT!
             EXITM <1>                   
         ENDIF
          %echo arg is not FLOAT!
         EXITM <0>
     ENDM     

.code
        start:

        ISFLOAT?(2435.56767)
        ISFLOAT?(1.5)
        ISFLOAT?(3.0)
        ISFLOAT?("dsfg.dsf")
        ISFLOAT?(7777h)
        ISFLOAT?(0)
   
      .err
end start


Thank you , Jochen and mabdelouahab for quick replies !

qWord

structure.member also float? You should at least test that the first character (or the second in case of sign +-) is a digit 0-9.
Remarks that quot is "global", which might be not intended?
MREAL macros - when you need floating point arithmetic while assembling!

GoneFishing

I thought that structure.member will be resolved to its offset , won't it?
Didn't think that quot is global
Thanks for noting these points. I'd work on it

GoneFishing

Oops, really


include \masm32\include\masm32rt.inc

ISFLOAT? MACRO arg 
         IF @InStr(1, <arg>, <.>)
            q SUBSTR <arg>,1,1
             IFIDN q,<">   
                 %echo arg is not FLOAT!
                 EXITM <0>
             ENDIF         
            %echo arg is  FLOAT!
             EXITM <1>                   
         ENDIF
          %echo arg is not FLOAT!
         EXITM <0>
     ENDM     

mys struct
    dw1   dd ?
    dw2   dd ?
    item1 db ?
    item2 db ?
mys ends   

.data

    mysinst mys<1,2,3,4>

.code
        start:

            ISFLOAT?(mysinst.dw1)
   
      .err
end start


output:
Quote
mysinst.dw1 is  FLOAT!

'quot' is replaced by 'q'

I'll think about what's better
- to add in-macro checks adviced by Qword
- or to write separate macros : ISSIGNED? and ISNUM?

qWord

Quote from: GoneFishing on October 19, 2015, 12:30:10 AM
I thought that structure.member will resolve to offset , won't it?
In an arithmetic expression yes, but that's not the case for you macro. Also, thought the case that a memory operand is used, e.g.: mem.x.
What you can do: if OPATTR does not return 0, than it can't be an FP literal (I guess that is what you want to test for). After that you could test for digits and the decimal dot.

Quote from: GoneFishing on October 19, 2015, 12:30:10 AMDidn't think that quot is global
the name quote is used as text macro while assembling- that is what I mean (so it might cause name conflicts) -> use macro-LOCAL or use an unique pre/postfix.

MREAL macros - when you need floating point arithmetic while assembling!

qWord

e.g.
ISFLOAT? MACRO arg:=<invalidToken?$?$?$>
    IF OPATTR arg
    EXITM <0>
    ENDIF
    iflt_str TEXTEQU <&arg  >
    iflt_c1 SUBSTR iflt_str,1,1
    iflt_c2 SUBSTR iflt_str,2,1
    iflt_pos1 INSTR iflt_str,<.>
    iflt_pos2 INSTR <+-0123456789>,iflt_c1
    iflt_pos3 INSTR <0123456789>,iflt_c2
   
    ;; if (sign and digit and dot) OR (digit and dot)
    IF (iflt_pos2 LE 2 AND iflt_pos3 NE 0 AND iflt_pos1 NE 0) OR (iflt_pos2 GT 2 AND iflt_pos1 NE 0)
    EXITM <-1>
    ELSE
    EXITM <0>
    ENDIF
endm
MREAL macros - when you need floating point arithmetic while assembling!

GoneFishing

Quote:=<invalidToken?$?$?$>
Never seen this expression before
Can't get your macro working here . Possibly it's
QuoteIF OPATTR arg
       EXITM <0>
    ENDIF
part affecting it. We want to catch immediate operands which are OPATTR = 24h


qWord

Quote from: GoneFishing on October 19, 2015, 01:21:28 AMWe want to catch immediate operands which are OPATTR = 24h
FP literals are not recognized by OPATTR, only integers. You must distinguish between them in some form, e.g. by having two macros or by different return values. (The above macro does only detect FP literals)

Quote from: GoneFishing on October 19, 2015, 01:21:28 AM
Quote:=<invalidToken?$?$?$>
Never seen this expression before
that is the default value for arg, just to point out that the macro should fail for blank input. Could be removed, because it seems like that OPATTR has no problem with a missing argument.
MREAL macros - when you need floating point arithmetic while assembling!

GoneFishing


include \masm32\include\masm32rt.inc


ISFLOAT?QW MACRO arg:=<invalidToken?$?$?$>
    IF OPATTR arg
    EXITM <0>
    ENDIF
    iflt_str TEXTEQU <&arg  >
    iflt_c1 SUBSTR iflt_str,1,1
    iflt_c2 SUBSTR iflt_str,2,1
    iflt_pos1 INSTR iflt_str,<.>
    iflt_pos2 INSTR <+-0123456789>,iflt_c1
    iflt_pos3 INSTR <0123456789>,iflt_c2
   
    ;; if (sign and digit and dot) OR (digit and dot)
    IF (iflt_pos2 LE 2 AND iflt_pos3 NE 0 AND iflt_pos1 NE 0) OR (iflt_pos2 GT 2 AND iflt_pos1 NE 0)
    EXITM <-1>
    ELSE
    EXITM <0>
   ENDM

ISFLOAT? MACRO arg 
         IF @InStr(1, <arg>, <.>)
            q SUBSTR <arg>,1,1
             IFIDN q,<">   
                 %echo arg is not FLOAT!
                 EXITM <0>
             ENDIF         
            %echo arg is  FLOAT!
             EXITM <1>                   
         ENDIF
          %echo arg is not FLOAT!
         EXITM <0>
     ENDM     

mys struct
    dw1   dd ?
    dw2   dd ?
    item1 db ?
    item2 db ?
mys ends   

.data

    mysinst mys<5,2,3,4>

.code
        start:

         if ISFLOAT?(mysinst.dw1)
            %echo mysinst.dw1 is mistakenly taken as a float
         endif
         if ISFLOAT?QW(-7.4)
           %echo QWORD IS MACRO WIZARD
         endif

      .err
end start

Your macro gives no output in example above . But why?

P.S.: Really, OPATTR for float is 0 . Thank you for clarification

qWord

Quote from: GoneFishing on October 19, 2015, 01:46:57 AMYour macro gives no output in example above . But why?
Thought the ECHOs were just used for debugging purpose. Just add them as you need.
MREAL macros - when you need floating point arithmetic while assembling!