Macro: DEFINE

Module location: FMAC line 9312 (view source)

Define with better protections against alias datatype naming

  #IFSAME !2 FOR
    #IF (!Zs=0)     // if not enum
      #IFDEF !1     // ignore redefinition of symbols (only if not enum)
        // if def'ed it means that !1 is a constant (has already been defined). If we are trying to turn this
        // into a datatype, we know that this is wrong and we should warn the developer. So check if replacement is a variable name.
        // Note in all cases, alias types will get converted to one of these real names.
        #IFSAME !3  STRING  NUMBER  DATE  INTEGER  REAL  BIGINT  BOOLEAN  ADDRESS  TIME  DATETIME  FLOAT  CHAR  UCHAR  SHORT  USHORT  UINTEGER  UBIGINT  CURRENCY  TIMESPAN  DECIMAL  VARIANT
          #ERROR DFERR_COMP_SYMBOL_ALREADY_DEFINED "Attempt to redefine a constant as a data type"
        #ELSE
           // if not a data type, we ignore the redefinition and assume all is OK
        #ENDIF
      #ELSE
        #IFSAME !1 $0     // ignore redefinition if already defined as FALSE
        #ELSE
          #IFSAME !1 $1   // ignore redefinition if already defined as TRUE
          #ELSE
            #IFSAME !1  STRING  NUMBER  DATE  INTEGER  REAL  BIGINT  BOOLEAN  ADDRESS  TIME  DATETIME  FLOAT  CHAR  UCHAR  SHORT  USHORT  UINTEGER  UBIGINT  CURRENCY  TIMESPAN  DECIMAL  VARIANT
              // if here this must be an alias datatype that has already been defined. Either this is a duplicate
              // definition (which we ignore) or a new definition (which is an error)
              #IFSAME !1 !3 // if same ok..redefinition
                // #REM define datatype ok
              #ELSE
                #ERROR DFERR_COMP_SYMBOL_ALREADY_DEFINED "Attempt to redefine a data type"
              #ENDIF
            #ELSE
              #CHECK !4 .
              #IFSAME !1 !3 // ignore self definitions. e.g. define cat for cat
                // #REM define to .self. is dumb but ok
              #ELSE
                #REPLACE !1 !3
              #ENDIF
            #ENDIF
          #ENDIF
        #ENDIF
      #ENDIF
    #ELSE           // else enum
      // check that symbol to be replaced is not a datatype or alias datatype
      #IFSAME !1  STRING  NUMBER  DATE  INTEGER  REAL  BIGINT  BOOLEAN  ADDRESS  TIME  DATETIME  FLOAT  CHAR  UCHAR  SHORT  USHORT  UINTEGER  UBIGINT  CURRENCY  TIMESPAN  DECIMAL  VARIANT
        #ERROR DFERR_COMP_SYMBOL_ALREADY_DEFINED "Attempt to redefine a data type"
      #ELSE
        #IFTYPE !3 "I"
          #IFCLASS !3 "C"
            #CHECK !4 .
            #REPLACE !1 !3
            #SET ZT$ (!3+1)
          #ELSE
            #ERROR DFERR_COMP_CONSTANT_EXPECTED ENUMERATION VALUE MUST BE A CONSTANT
          #ENDIF
        #ELSE
          #ERROR DFERR_COMP_CONSTANT_EXPECTED ENUMERATION VALUE MUST BE A CONSTANT
        #ENDIF
      #ENDIF
    #ENDIF
  #ELSE             // not "FOR"
    // check that symbol to be replaced is not a datatype or alias datatype
    #IFSAME !1  STRING  NUMBER  DATE  INTEGER  REAL  BIGINT  BOOLEAN  ADDRESS  TIME  DATETIME  FLOAT  CHAR  UCHAR  SHORT  USHORT  UINTEGER  UBIGINT  CURRENCY  TIMESPAN  DECIMAL  VARIANT
      #ERROR DFERR_COMP_SYMBOL_ALREADY_DEFINED "Attempt to redefine a data type"
    #ELSE
      #IF (!Zs=0)     // if not enum
        #CHECK !2 .
        #IFDEF !1     // define for |CI1 if they were previously undefined
          #IFSAME !1 |CI1
          #ELSE
            #ERROR DFERR_COMP_SYMBOL_ALREADY_DEFINED "ATTEMPT TO REDEFINE SYMBOL FOR DIFFERENT VALUE"
          #ENDIF
        #ELSE
          #IFSUB '!1'
            #ERROR DFERR_COMP_SYMBOL_ALREADY_DEFINED "ATTEMPT TO REDEFINE SYMBOL FOR DIFFERENT VALUE"
          #ELSE
            #REPLACE !1 |CI1
          #ENDIF
        #ENDIF
      #ELSE
        #REPLACE !1 |CI!Zt
        #SET ZT$ !ZT
        #IF (!0>1)
          DEFINE !2 !3 !4 !5 !6 !7 !8 !9
        #ENDIF
      #ENDIF
    #ENDIF
  #ENDIF