Announcement

Collapse
No announcement yet.

Macro question

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Macro question

    In the following code, im using a single line macro and a multiline macro.

    Code:
    MACRO DayHasPassed() = ISTRUE(VAL(MID$(DATE$, 7, 4) & MID$(DATE$, 1, 2) & MID$(DATE$, 4, 2)) => 20100101)
    
    MACRO DISPLAYGreeting()
    
        MSGBOX "This Shouldnt be triggered before 2010."
    
    END MACRO
    
    FUNCTION PBMAIN AS LONG
    
    ' Example 1
    IF DayHasPassed() THEN DisplayGreeting()
    
    ' Example 2
    IF DayHasPassed() THEN
        DisplayGreeting()
    END IF
        
    END FUNCTION
    If my understanding of macros is correct, both do exactly as they should,
    except that Example 1 should cause a compile time error "Expected END IF"...

    I think the syntax is acceptable for the compiler but MACROS do it harder to parse? im a little confused.

    Can someone clarify this for me please?

    Clear question is: Why is a macro accepted after a single line IF as... well a
    multi line macro.. but ignores the result of the first macro and treats the second macro as a separate thing without requiring an END IF statement?
    Last edited by Elias Montoya; 22 Feb 2009, 03:45 PM.

  • #2
    Although I'm not the best person to jump in here, I think I have the answer.

    The parser simply replaces the "variable" with the statement. Since you are not using any conditionals in either macro no exception is raised. Translating your code the way I think the compiler would do it:

    Code:
    IF ISTRUE(VAL(MID$(DATE$, 7, 4) & MID$(DATE$, 1, 2) & MID$(DATE$, 4, 2)) => 20100101)  THEN MSGBOX "This Shouldnt be triggered before 2010."
    or

    Code:
     
    IF ISTRUE(VAL(MID$(DATE$, 7, 4) & MID$(DATE$, 1, 2) & MID$(DATE$, 4, 2)) =>  20100101) THEN
         MSGBOX "This Shouldnt be triggered before 2010."
    END IF
    So neither statement will produce a compile error.
    Walt Decker

    Comment


    • #3
      Originally posted by Walt Decker View Post
      So neither statement will produce a compile error.
      If that was the case (any of the two you posted)... the MSGBOX should not
      triggered until 2010, Yet it is.

      Comment


      • #4
        Incorrect Result?

        I've simplified the code to just return false.
        You are correct the message IS displayed.
        It looks like compilation is incorrectly generated.

        I've sent the sample to support.

        Code:
        #Include "win32api.inc"
        
        Macro ReturnFalse() = %false
        
        Macro DISPLAYGreeting()
        
            MsgBox "Shouldn't be here."
        
        End Macro
        
        Function PBMain As Long
        
        ' Example 1
        
        If returnfalse() Then DisplayGreeting()
        
        End Function

        Comment


        • #5
          Brian, your code will always fire. %FALSE = 0 so IF 0 is true; however, IF ISTRUE(%FALSE) is false.

          Elias, I didn't say that the message shouldn't fire. I said that a compile error should not occur. That was you original question.

          As far as firing goes, I'd bet there is something wrong in the dayhaspassed macro, either the fields are being extracted incorrectly or the math is wrong.
          Last edited by Walt Decker; 22 Feb 2009, 09:09 PM.
          Walt Decker

          Comment


          • #6
            Weird things are happening alright! - probably because..
            A multi-line macro, while more powerful in terms of coding, may be referenced only in the "statement" position, which is the first position on a line.
            According to PB Help.
            Rgds, Dave

            Comment


            • #7
              Originally posted by Walt Decker View Post
              As far as firing goes, I'd bet there is something wrong in the dayhaspassed macro, either the fields are being extracted incorrectly or the math is wrong.
              Same code in Function form works OK.

              Im not saying there is a Bug here... i just dont understand completely the logic of Macros...

              Comment


              • #8
                %FALSE = 0 so IF 0 is true; however, IF ISTRUE(%FALSE) is false.
                Wrong. A "IF 0" or "#IF 0" statement or block should never pass, ever.
                kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                Comment


                • #9
                  Code:
                   
                  IF DayHasPassed() THEN DisplayGreeting()
                  You are referencing the multiline macro in a position which is not allowed -".. it may be referenced only in the "statement" position, which is the first position on a line."

                  So unpredictable things are happening
                  Rgds, Dave

                  Comment


                  • #10
                    Exactly correct, Dave. Multi-Line Macros must only be executed at the beginning of a line. That's because they intrinsically include CR/LF characters which cause havoc inside of a single-line IF. This kind of situation must be avoided to maintain peace and harmony.

                    Now, it may be that the PowerBASIC compiler could try to handle this situation a little more gracefully. That's something we'll look into. However, you will still need to avoid this type of coding regardless.

                    Best regards,

                    Bob Zale
                    PowerBASIC Inc.

                    Comment


                    • #11
                      Originally posted by Elias Montoya View Post
                      In the following code, im using a single line macro and a multiline macro.

                      Code:
                      MACRO DayHasPassed() = ISTRUE(VAL(MID$(DATE$, 7, 4) & MID$(DATE$, 1, 2) & MID$(DATE$, 4, 2)) => 20100101)
                      
                      MACRO DISPLAYGreeting()
                      
                          MSGBOX "This Shouldnt be triggered before 2010."
                      
                      END MACRO
                      
                      FUNCTION PBMAIN AS LONG
                      
                      ' Example 1
                      IF DayHasPassed() THEN DisplayGreeting()
                      
                      ' Example 2
                      IF DayHasPassed() THEN
                          DisplayGreeting()
                      END IF
                          
                      END FUNCTION
                      If my understanding of macros is correct, both do exactly as they should,
                      except that Example 1 should cause a compile time error "Expected END IF"...

                      I think the syntax is acceptable for the compiler but MACROS do it harder to parse? im a little confused.

                      Can someone clarify this for me please?

                      Clear question is: Why is a macro accepted after a single line IF as... well a
                      multi line macro.. but ignores the result of the first macro and treats the second macro as a separate thing without requiring an END IF statement?
                      Elias,

                      I figured it out. Convert the DisplayMessage macro to a single line

                      Code:
                      MACRO displayMessage() = msgbox "This Shouldnt be triggered before 2010."
                      Seems the compiler is doing the following


                      IF DayHasPassed() THEN DisplayGreeting()

                      is converted to

                      if DayHasPassed then [NO OP thrown in]

                      msgbox "This Shouldnt be triggered before 2010."

                      This makes sense that the msgbox would always be displayed.

                      I've figured this out by doing many different tests. I can post my analysis if someone is interested. I didn't save each example so I would have to reproduce them.

                      Comment


                      • #12
                        Statement position/function position ...
                        Code:
                        MACRO FUNCTION  
                        
                        ....
                        EXAMPLE:
                        Code:
                        ' ===[ MACRO TO COMPARE FIXED-LENGTH BUFFERS FOR EQUALITY ]===
                        ' === returns: %TRUE (strings are equal) or %FALSE (they ain't)
                        '
                        MACRO FUNCTION m_CompareFixedStringEqual (a1, A2, iLen)
                        
                          MACROTEMP iChar, iRet, p1, p2
                          DIM iChar AS LONG, iRet AS LONG, p1 AS BYTE PTR, p2 AS BYTE PTR
                        
                            p1      = VARPTR(A1)
                            p2      = VARPTR(A2)
                            iRet    =  %TRUE    ' we will set to false if / when it happens
                        
                          FOR ichar = 1& TO ilen
                            IF (@p2 XOR @p1) THEN
                         '   IF @p2 <> @p1 THEN       ' as soon as any character in 2 is not equal condition is false
                              iRet = %FALSE
                              EXIT FOR
                            ELSE
                              INCR p1
                              INCR p2
                            END IF
                          NEXT
                        END MACRO = iRet
                        
                        
                        ....
                        
                        
                        TYPE  A
                            F1   AS STRING * 12
                        END TYPE 
                        
                        TYPE B 
                            F1   AS STRING * 12 
                        END TYPE 
                        ....
                         FUNCTION FOO 
                        
                         LOCAL TA AS A, TB AS B 
                        
                         .... 
                         GET hFileA, TA 
                         GET hFileB, TB 
                         iRet =   M_compareFixedStringEqual (TA.F1, TB.F1, SIZEOF(TA.F1)) 
                          IF ISTRUE iRet THEN 
                             Message "f1 members are equal....
                        
                         ....
                        MCM
                        (I did this because comparing fixed string members of UDTs requires creation/destruction of temporary dynamic strings (or at least it did thru 7x) and I have literally tens or hundreds of thousands of these comparisons to make in a typical run of this program).
                        Last edited by Michael Mattias; 23 Feb 2009, 09:28 AM. Reason: Added example
                        Michael Mattias
                        Tal Systems Inc. (retired)
                        Racine WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment

                        Working...
                        X