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