[Runtime] Added Min() and Max() overloads

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING System.Runtime.CompilerServices
/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/between/*" />
/// <seealso cref='O:XSharp.Core.Functions.Between'>Between</seealso>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Between(uValue AS USUAL, uMin AS USUAL, uMax AS USUAL) AS LOGIC
	RETURN uValue >=uMin .AND.  uValue<=uMax

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/betweentyped/*" />
/// <seealso cref='O:XSharp.Core.Functions.Between'>Between</seealso>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Between(dValue AS DATE, dMin AS DATE, dMax AS DATE) AS LOGIC
    RETURN ( dValue >= dMin .AND. dValue <= dMax )

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/betweentyped/*" />
/// <seealso cref='O:XSharp.Core.Functions.Between'>Between</seealso>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Between(nValue AS CURRENCY, nMin AS CURRENCY, nMax AS CURRENCY) AS LOGIC
    RETURN ( nValue >= nMin .AND. nValue <= nMax )

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/betweentyped/*" />
/// <seealso cref='O:XSharp.Core.Functions.Between'>Between</seealso>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Between(nValue AS FLOAT, nMin AS FLOAT, nMax AS FLOAT) AS LOGIC
    RETURN ( nValue >= nMin .AND. nValue <= nMax )

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/inlist/*" />
FUNCTION InList(u AS USUAL, uValueList PARAMS USUAL[]) AS LOGIC
	RETURN _InListWorker(u, uValueList, {x,y => x = y})

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/inlistexact/*" />
FUNCTION InListExact(u AS USUAL, uValueList PARAMS USUAL[]) AS LOGIC
	RETURN _InListWorker(u, uValueList, {x,y => x == y})

INTERNAL FUNCTION _InListWorker( u AS USUAL, args AS CONST USUAL[], compare as Func<USUAL, USUAL, LOGIC>) AS LOGIC
	LOCAL i, nLen AS INT
	nLen := args:Length
	FOR i := 1 TO nLen
		IF compare(args[i], u)
			RETURN TRUE
		ENDIF
	NEXT
	RETURN FALSE

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Max(uValue1 AS REAL8, uValue2 AS REAL8) AS REAL8
    RETURN IIF (uValue1 > uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Max(uValue1 AS LONG, uValue2 AS LONG) AS LONG
    RETURN IIF (uValue1 > uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Max(uValue1 AS INT64, uValue2 AS INT64) AS INT64
    RETURN IIF (uValue1 > uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Max(uValue1 AS DECIMAL, uValue2 AS DECIMAL) AS DECIMAL
    RETURN IIF (uValue1 > uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Max(uValue1 AS DWORD, uValue2 AS DWORD) AS DWORD
    RETURN IIF (uValue1 > uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Max(uValue1 AS FLOAT, uValue2 AS FLOAT) AS FLOAT
    RETURN IIF (uValue1 > uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Max(uValue1 AS CURRENCY, uValue2 AS CURRENCY) AS CURRENCY
    RETURN IIF (uValue1 > uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Max(uValue1 AS SYMBOL, uValue2 AS SYMBOL) AS SYMBOL
    RETURN IIF (uValue1 > uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Max(uValue1 AS STRING, uValue2 AS STRING) AS STRING
    RETURN IIF(XSharp.RuntimeState.StringCompare(uValue1, uValue2) >= 0, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
FUNCTION Max(uValue1 AS USUAL, uValue2 AS USUAL) AS USUAL

	IF uValue1:IsNumeric .AND. uValue2:IsNumeric

		IF uValue1:IsFloat .OR. uValue2:IsFloat
			RETURN Max( (REAL8) uValue1, (REAL8) uValue2)

		ELSEIF uValue1:IsDecimal .OR. uValue2:IsDecimal
			RETURN Max( (Decimal) uValue1, (Decimal) uValue2)
        ELSEIF uValue1:IsCurrency  .OR. uValue2:IsCurrency
            RETURN Max( (Currency) uValue1, (Currency) uValue2)
		ELSEIF uValue1:IsInt64 .OR. uValue2:IsInt64
			RETURN Max( (INT64) uValue1, (INT64) uValue2)
		ENDIF
		RETURN Max( (LONG) uValue1, (LONG) uValue2)

	ELSEIF uValue1:IsDate .AND. uValue2:IsDate
		RETURN Max(uValue1:_dateValue, uValue2:_dateValue)

	ELSEIF uValue1:IsDateTime .AND. uValue2:IsDateTime
		RETURN Max(uValue1:_dateTimeValue, uValue2:_dateTimeValue)

	ELSEIF (uValue1:IsDateTime .OR. uValue1:IsDate) .AND. (uValue2:IsDateTime .OR. uValue2:IsDate)
		RETURN Max((Date) uValue1 ,(Date) uValue2)

	ELSEIF uValue1:IsString .AND. uValue2:IsString
		RETURN Max (uValue1:_stringValue , uValue2:_stringValue)

	ELSEIF uValue1:IsSymbol .AND. uValue2:IsSymbol
		RETURN Max(uValue1:_symValue, uValue2:_symValue)

	ELSEIF uValue1:IsBinary .AND. uValue2:IsBinary
		RETURN iif( (BINARY) uValue1 > (BINARY) uValue2, uValue1, uValue2)

	ELSE
        THROW Error.ArgumentError( __FUNCTION__, NAMEOF(uValue2) , "Incompatible types")
	ENDIF

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Min(uValue1 AS REAL8, uValue2 AS REAL8) AS REAL8
    RETURN IIF (uValue1 < uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Min(uValue1 AS LONG, uValue2 AS LONG) AS LONG
    RETURN IIF (uValue1 < uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Min(uValue1 AS INT64, uValue2 AS INT64) AS INT64
    RETURN IIF (uValue1 < uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Min(uValue1 AS DECIMAL, uValue2 AS DECIMAL) AS DECIMAL
    RETURN IIF (uValue1 < uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Min(uValue1 AS DWORD, uValue2 AS DWORD) AS DWORD
    RETURN IIF (uValue1 < uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Min(uValue1 AS FLOAT, uValue2 AS FLOAT) AS FLOAT
    RETURN IIF (uValue1 < uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Min(uValue1 AS CURRENCY, uValue2 AS CURRENCY) AS CURRENCY
    RETURN IIF (uValue1 < uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Min(uValue1 AS SYMBOL, uValue2 AS SYMBOL) AS SYMBOL
    RETURN IIF (uValue1 < uValue2, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Min(uValue1 AS STRING, uValue2 AS STRING) AS STRING
    RETURN IIF(XSharp.RuntimeState.StringCompare(uValue1, uValue2) <= 0, uValue1, uValue2)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/min/*" />
FUNCTION Min(uValue1 AS USUAL, uValue2 AS USUAL) AS USUAL
	IF uValue1:IsNumeric .AND. uValue2:IsNumeric

		IF uValue1:IsFloat .OR. uValue2:IsFloat

			RETURN Min((REAL8) uValue1, (REAL8) uValue2)

		ELSEIF uValue1:IsDecimal .OR. uValue2:IsDecimal
			RETURN Min( (Decimal) uValue1, (Decimal) uValue2)

        ELSEIF uValue1:IsCurrency  .OR. uValue2:IsCurrency
            RETURN Min( (Currency) uValue1, (Currency) uValue2)

		ELSEIF uValue1:IsInt64 .OR. uValue2:IsInt64
			RETURN Min( (INT64) uValue1, (INT64) uValue2)
		ENDIF
		RETURN Min( (LONG) uValue1, (LONG) uValue2)

	ELSEIF uValue1:IsDate .AND. uValue2:IsDate
		RETURN Min(uValue1:_dateValue, uValue2:_dateValue)

	ELSEIF uValue1:IsDateTime .AND. uValue2:IsDateTime
		RETURN Min(uValue1:_dateTimeValue, uValue2:_dateTimeValue)

	ELSEIF (uValue1:IsDateTime .OR. uValue1:IsDate) .AND. (uValue2:IsDateTime .OR. uValue2:IsDate)
		RETURN Min((Date) uValue1 ,(Date) uValue2)

	ELSEIF uValue1:IsString .AND. uValue2:IsString
		RETURN Min (uValue1:_stringValue , uValue2:_stringValue)

	ELSEIF uValue1:IsSymbol .AND. uValue2:IsSymbol
		RETURN Min(uValue1:_symValue, uValue2:_symValue)

	ELSEIF uValue1:IsBinary .AND. uValue2:IsBinary
		RETURN iif( (BINARY) uValue1 < (BINARY) uValue2, uValue1, uValue2)

	ELSE
        THROW Error.ArgumentError( __FUNCTION__, NAMEOF(uValue2) , "Incompatible types")
	ENDIF

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/palettergb/*" />
FUNCTION PaletteRGB(bR AS USUAL,bG AS USUAL,bB AS BYTE) AS INT
	RETURN (INT) RGB(bR, bG, bB)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/tone/*" />
FUNCTION Tone(wFrequency AS DWORD,wDuration AS DWORD) AS USUAL
	Console.Beep( (INT)wFrequency, (INT)wDuration * 1000 / 18 )
RETURN	 NIL

// moved from wingdi in win32apilibrary

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetRValue(rgb AS DWORD) AS BYTE
	RETURN BYTE(_CAST,rgb)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetGValue(rgb AS DWORD) AS BYTE
	LOCAL val AS WORD
	val := WORD(_CAST,rgb)>>8
	RETURN BYTE(_CAST,val)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetBValue(rgb AS DWORD) AS BYTE
	LOCAL val AS DWORD
	val := rgb>>16
	RETURN BYTE(_CAST,val)

// Macros from wingdi.h
#define _CMYK(c,m,y,k)       ((DWORD)((((BYTE)(k)|((WORD)((BYTE)(y))<<8))|(((DWORD)(BYTE)(m))<<16))|(((DWORD)(BYTE)(c))<<24)))
#define _MAKEROP4(fore,back) (DWORD)((((back) << 8) & 0xFF000000) | (fore))
#define _GetKValue(cmyk)      ((BYTE)(cmyk))
#define _GetYValue(cmyk)      ((BYTE)((cmyk)>> 8))
#define _GetMValue(cmyk)      ((BYTE)((cmyk)>>16))
#define _GetCValue(cmyk)      ((BYTE)((cmyk)>>24))

///  <exclude/>
FUNCTION CMYK(c AS DWORD, m AS DWORD, y AS DWORD, k AS DWORD)  AS DWORD
	RETURN _CMYK(c,m,y,k)

///  <exclude/>
FUNCTION MAKEROP4(fore AS WORD, back AS WORD) AS DWORD
	return _MAKEROP4(fore,back)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetKValue(cmyk AS DWORD) AS BYTE
	RETURN _GetKValue(cmyk)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetCValue(cmyk AS DWORD) AS BYTE STRICT
	RETURN _GetCValue(cmyk)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetMValue(cmyk AS DWORD) AS BYTE
	RETURN _GetMValue(cmyk)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetYValue(cmyk AS DWORD) AS BYTE
	RETURN _GetYValue(cmyk)

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING System.Runtime.CompilerServices
/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/between/*" />
/// <seealso cref='O:XSharp.Core.Functions.Between'>Between</seealso>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Between(uValue AS USUAL,uMin AS USUAL,uMax AS USUAL) AS LOGIC
	RETURN uValue >=uMin .AND.  uValue<=uMax

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/betweentyped/*" />
/// <seealso cref='O:XSharp.Core.Functions.Between'>Between</seealso>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Between(dValue AS DATE, dMin AS DATE, dMax AS DATE) AS LOGIC
    RETURN ( dValue >= dMin .AND. dValue <= dMax )

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/betweentyped/*" />
/// <seealso cref='O:XSharp.Core.Functions.Between'>Between</seealso>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Between(nValue AS CURRENCY, nMin AS CURRENCY, nMax AS CURRENCY) AS LOGIC
    RETURN ( nValue >= nMin .AND. nValue <= nMax )

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/betweentyped/*" />
/// <seealso cref='O:XSharp.Core.Functions.Between'>Between</seealso>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION Between(nValue AS FLOAT, nMin AS FLOAT, nMax AS FLOAT) AS LOGIC
    RETURN ( nValue >= nMin .AND. nValue <= nMax )

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/inlist/*" />
FUNCTION InList(u AS USUAL, uValueList PARAMS USUAL[]) AS LOGIC
	RETURN _InListWorker(u, uValueList, FALSE)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/inlistexact/*" />
FUNCTION InListExact(u AS USUAL, uValueList PARAMS USUAL[]) AS LOGIC
	RETURN _InListWorker(u, uValueList, TRUE)

INTERNAL FUNCTION _InListWorker( u AS USUAL, args AS CONST USUAL[], lExact AS LOGIC) AS LOGIC
	LOCAL i, nLen AS INT
	nLen := args:Length
	IF lExact
		FOR i := 1 TO nLen
			IF args[i] == u
				RETURN TRUE
			ENDIF
		NEXT
	ELSE
		FOR i := 1 TO nLen
			IF u = args[i]
				RETURN TRUE
			ENDIF
		NEXT
	ENDIF
	RETURN FALSE

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/max/*" />
FUNCTION Max(uValue1 AS USUAL,uValue2 AS USUAL) AS USUAL

	IF uValue1:IsNumeric .AND. uValue2:IsNumeric

		IF uValue1:IsFloat .OR. uValue2:IsFloat
			RETURN (USUAL) Math.Max( (REAL8) uValue1, (REAL8) uValue2)

		ELSEIF uValue1:IsDecimal .OR. uValue2:IsDecimal .OR. uValue1:IsCurrency  .OR. uValue2:IsCurrency
			RETURN (USUAL) Math.Max( (Decimal) uValue1, (Decimal) uValue2)

		ELSEIF uValue1:IsInt64 .OR. uValue2:IsInt64
			RETURN (USUAL) Math.Max( (INT64) uValue1, (INT64) uValue2)
		ENDIF
		RETURN (USUAL) Math.Max( (LONG) uValue1, (LONG) uValue2)

	ELSEIF uValue1:IsDate .AND. uValue2:IsDate
		RETURN IIF ((DATE) uValue1 > (DATE) uValue2, uValue1, uValue2)

	ELSEIF uValue1:IsDateTime .AND. uValue2:IsDateTime
		RETURN IIF ((DateTime) uValue1 > (DateTime) uValue2, uValue1, uValue2)

	ELSEIF (uValue1:IsDateTime .OR. uValue1:IsDate) .AND. (uValue2:IsDateTime .OR. uValue2:IsDate)
		RETURN IIF ((Date) uValue1 > (Date) uValue2, uValue1, uValue2)

	ELSEIF uValue1:IsString .AND. uValue2:IsString
		RETURN IIF ((STRING) uValue1 > (STRING) uValue2, uValue1, uValue2)

	ELSEIF uValue1:IsSymbol .AND. uValue2:IsSymbol
		RETURN IIF ((SYMBOL) uValue1 > (SYMBOL) uValue2, uValue1, uValue2)

	ELSE
        THROW Error.ArgumentError( __FUNCTION__, NAMEOF(uValue2) , "Incompatible types")
	ENDIF

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/min/*" />
FUNCTION Min(uValue1 AS USUAL,uValue2 AS USUAL) AS USUAL
	IF uValue1:IsNumeric .AND. uValue2:IsNumeric

		IF uValue1:IsFloat .OR. uValue2:IsFloat

			RETURN (USUAL) Math.Min((REAL8) uValue1, (REAL8) uValue2)

		ELSEIF uValue1:IsDecimal .OR. uValue2:IsDecimal .OR. uValue1:IsCurrency .OR. uValue2:IsCurrency
			RETURN (USUAL) Math.Min( (Decimal) uValue1, (Decimal) uValue2)

		ELSEIF uValue1:IsInt64 .OR. uValue2:IsInt64
			RETURN (USUAL) Math.Min( (INT64) uValue1, (INT64) uValue2)
		ENDIF
		RETURN (USUAL) Math.Min( (LONG) uValue1, (LONG) uValue2)

	ELSEIF uValue1:IsDate .AND. uValue2:IsDate
		RETURN IIF ((DATE) uValue1 <(DATE) uValue2, uValue1, uValue2)

    ELSEIF uValue1:IsDateTime .AND. uValue2:IsDateTime
		RETURN IIF ((DateTime) uValue1 <(DateTime) uValue2, uValue1, uValue2)

    ELSEIF (uValue1:IsDateTime .OR. uValue1:IsDate) .AND. (uValue2:IsDateTime .OR. uValue2:IsDate)

		RETURN IIF ((Date) uValue1 <(Date) uValue2, uValue1, uValue2)

	ELSEIF uValue1:IsString .AND. uValue2:IsString
		RETURN IIF ((STRING) uValue1 < (STRING) uValue2, uValue1, uValue2)

	ELSEIF uValue1:IsSymbol .AND. uValue2:IsSymbol
		RETURN IIF ((SYMBOL) uValue1 < (SYMBOL) uValue2, uValue1, uValue2)
	ELSE
        THROW Error.ArgumentError( __FUNCTION__, NAMEOF(uValue2) , "Incompatible types")
	ENDIF

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/palettergb/*" />
FUNCTION PaletteRGB(bR AS USUAL,bG AS USUAL,bB AS BYTE) AS INT
	RETURN (INT) RGB(bR, bG, bB)

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/tone/*" />
FUNCTION Tone(wFrequency AS DWORD,wDuration AS DWORD) AS USUAL
	Console.Beep( (INT)wFrequency, (INT)wDuration * 1000 / 18 )
RETURN	 NIL

// moved from wingdi in win32apilibrary

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetRValue(rgb AS DWORD) AS BYTE
	RETURN BYTE(_CAST,rgb)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetGValue(rgb AS DWORD) AS BYTE
	LOCAL val AS WORD
	val := WORD(_CAST,rgb)>>8
	RETURN BYTE(_CAST,val)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetBValue(rgb AS DWORD) AS BYTE
	LOCAL val AS DWORD
	val := rgb>>16
	RETURN BYTE(_CAST,val)

// Macros from wingdi.h
#define _CMYK(c,m,y,k)       ((DWORD)((((BYTE)(k)|((WORD)((BYTE)(y))<<8))|(((DWORD)(BYTE)(m))<<16))|(((DWORD)(BYTE)(c))<<24)))
#define _MAKEROP4(fore,back) (DWORD)((((back) << 8) & 0xFF000000) | (fore))
#define _GetKValue(cmyk)      ((BYTE)(cmyk))
#define _GetYValue(cmyk)      ((BYTE)((cmyk)>> 8))
#define _GetMValue(cmyk)      ((BYTE)((cmyk)>>16))
#define _GetCValue(cmyk)      ((BYTE)((cmyk)>>24))

///  <exclude/>
FUNCTION CMYK(c AS DWORD, m AS DWORD, y AS DWORD, k AS DWORD)  AS DWORD
	RETURN _CMYK(c,m,y,k)

///  <exclude/>
FUNCTION MAKEROP4(fore AS WORD, back AS WORD) AS DWORD
	return _MAKEROP4(fore,back)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetKValue(cmyk AS DWORD) AS BYTE
	RETURN _GetKValue(cmyk)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetCValue(cmyk AS DWORD) AS BYTE STRICT
	RETURN _GetCValue(cmyk)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetMValue(cmyk AS DWORD) AS BYTE
	RETURN _GetMValue(cmyk)

///  <exclude/>
[MethodImpl(MethodImplOptions.AggressiveInlining)];
FUNCTION GetYValue(cmyk AS DWORD) AS BYTE
	RETURN _GetYValue(cmyk)


Added Cargo slot for Error class

Added Cargo slot for Error class

USING System
USING System.Collections.Generic
USING System.Text
USING System.Reflection
BEGIN NAMESPACE XSharp
  /// XSharp Runtime base Error class
  CLASS Error INHERIT Exception
    /// A string representing the name of the subsystem generating the error.
    PROPERTY SubSystem AS STRING AUTO
    /// An integer numeric value representing a Visual Objects generic error code.
    /// <Seealso cref="T:XSharp.Gencode"/>
    PROPERTY Gencode AS DWORD AUTO
    /// An integer numeric value representing a subsystem-specific error code.
    PROPERTY SubCode AS DWORD AUTO
    /// A string representing the name of the function or method in which the error occurred.
    PROPERTY FuncSym AS STRING AUTO
    /// A string representing the name used to open the file associated with the error condition.
    PROPERTY FileName AS STRING AUTO
    /// A constant indicating the severity of the error condition.
    /// <Seealso cref="T:XSharp.Severity"/>
    PROPERTY Severity AS DWORD AUTO
    /// A string that describes the error condition.
    PROPERTY Description		AS STRING  AUTO
    /// A string representing the argument supplied to an operator or function when an argument error occurs.
    PROPERTY Arg				AS STRING AUTO
    PRIVATE  _ArgType			AS DWORD
    /// A numeric value representing the data type of the argument that raised the error.
    PROPERTY ArgType			AS DWORD
      GET
        RETURN _ArgType
      END GET
      SET
        _ArgType := VALUE
        _ArgTypeType := UsualTypeToType(VALUE)
      END SET
    END PROPERTY
    PRIVATE  _ArgTypeType 		:= NULL AS System.Type
    /// The system type representing the data type of the argument that raised the error.
    PROPERTY ArgTypeType		AS System.Type
      GET
        RETURN _ArgTypeType
      END GET
      SET
        _ArgTypeType := VALUE
        _ArgType 	 := TypeToUsualType(VALUE)
      END SET
    END PROPERTY

    PRIVATE _ArgTypeReq		AS DWORD
    /// A numeric value representing the expected type of the argument that raised the error.
    PROPERTY ArgTypeReq			AS DWORD
      GET
        RETURN _ArgTypeReq
      END GET
      SET
        _ArgTypeReq := VALUE
        _ArgTypeReqType := UsualTypeToType(VALUE)
      END SET
    END PROPERTY
    PRIVATE  _ArgTypeReqType := NULL	AS System.Type
    /// The system type representing the expected type of the argument that raised the error.
    PROPERTY ArgTypeReqType		AS System.Type
      GET
        RETURN _ArgTypeReqType
      END GET
      SET
        _ArgTypeReqType := VALUE
        _ArgTypeReq 	 := TypeToUsualType(VALUE)
      END SET
    END PROPERTY
    /// A numeric value representing the type of the new result that the error handler substitutes for the operation that produced the error condition.
    PROPERTY SubstituteType     AS DWORD AUTO
    /// A numeric value representing the number of the argument supplied to an operator or function when an argument error occurs.
    PROPERTY ArgNum				AS DWORD AUTO
    /// An object representing the SELF of the method in which the error occurred.
    PROPERTY MethodSelf			AS OBJECT AUTO
    /// A symbol representing the calling function of the function in which the error occurred.
    PROPERTY CallFuncSym		AS STRING AUTO
    /// An array of the arguments supplied to an operator or function when an argument error occurs.
    PROPERTY Args				AS OBJECT[] AUTO
    /// An integer numeric value representing the number of times the failed operation has been attempted.
    PROPERTY Tries				AS INT AUTO
    /// A logical value indicating whether the subsystem can perform default error recovery for the error condition.
    PROPERTY CanDefault         AS LOGIC AUTO
    /// A logical value indicating whether the subsystem can retry the operation that caused the error condition.
    PROPERTY CanRetry           AS LOGIC AUTO
    /// A logical value indicating whether a new result can be substituted for the operation that produced the error condition.
    PROPERTY CanSubstitute      AS LOGIC AUTO
    /// A string that describes the operation being attempted when the error occurred.
    PROPERTY Operation          AS STRING AUTO
    /// A string representing a subsystem-specific error.  A NULL_STRING value indicates that the subsystem does not assign any particular string to the error condition.
    PROPERTY SubCodeText        AS STRING AUTO
    /// A value of 0 indicates that the error condition was not caused by an error from the operating system.  When Error:OsCode is set to a value other
    PROPERTY OSCode				AS DWORD AUTO
    /// A numeric value representing the file handle supplied to a function when an file error occurs.
    PROPERTY FileHandle         AS DWORD AUTO
    /// A numeric value representing a boundary condition for an operation (such as string overflow or array bound error).
    PROPERTY MaxSize			AS DWORD AUTO
    /// A value of any data type unused by the Error system.  It is provided as a user-definable slot, allowing arbitrary information to be attached to an Error object and retrieved later
    PROPERTY Cargo              AS OBJECT AUTO

    PRIVATE METHOD setDefaultValues() AS VOID
        SELF:Arg 			:= ""
        SELF:CallFuncSym 	:= ""
        SELF:Description    := ""
        SELF:FileName 		:= ""
        SELF:FuncSym 		:= ""
        SELF:Operation 		:= ""
        SELF:SubCodeText 	:= ""
        SELF:SubSystem 		:= ""
        SELF:Gencode		:= EG_UNKNOWN
        SELF:Subcode		:= 0
        SELF:Subsystem		:= "BASE"
        SELF:Severity		:= ES_ERROR
        SELF:CanDefault		:= FALSE
        SELF:CanRetry		:= FALSE
        SELF:CanSubstitute	:= FALSE
        SELF:Tries			:= 0
        SELF:FuncSym		:= ProcName(2)
        SELF:OSCode			:= 0

    /// Create an Error Object
    CONSTRUCTOR()
    SELF:setDefaultValues()
    RETURN

    /// Create an Error Object with the specified Description
    CONSTRUCTOR (msg AS STRING)
    SUPER(msg)
    SELF:setDefaultValues()
    SELF:Description := msg
    SELF:GenCode     := EG_EXCEPTION
    RETURN

    /// Create an Error Object with the Innner Exception
    CONSTRUCTOR (ex AS Exception)
    SUPER(ex.Message,ex)
    SELF:setDefaultValues()
    IF ex IS Error
        // Clone Error properties from Inner Exception
        LOCAL e := (Error) ex AS Error
        VAR props := typeof(error):GetProperties()
        FOREACH oProp AS PropertyInfo IN props
            IF oProp:CanWrite
                oProp:SetValue(SELF, oProp:GetValue(e))
            ENDIF
        NEXT
    ELSE
        SELF:Description := ex:Message
        SELF:GenCode     := EG_EXCEPTION
    ENDIF

    /// Create an Error Object with the Innner Exception and other parameters
    CONSTRUCTOR (ex AS Exception, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[])
    SUPER(ex.Message,ex)
    SELF:setDefaultValues()
    SELF:GenCode     := EG_EXCEPTION
    SELF:FuncSym     := cFuncName
    SELF:Arg         := cArgName
    SELF:ArgNum      := iArgNum
    SELF:Args		 := aArgs

    /// Create an Error Object for a Gencode and Argument Name.
    CONSTRUCTOR (dwgencode AS DWORD, cArg AS STRING)
    SUPER(ErrString( dwGenCode ))
    SELF:setDefaultValues()
    SELF:Gencode := dwGenCode
    SELF:Arg	 := cArg

    /// Create an Error Object for a Gencode, Argument Name and Description.
    CONSTRUCTOR (dwgencode AS DWORD, cArg AS STRING, cDescription AS STRING)
    SUPER(cDescription)
    SELF:setDefaultValues()
    SELF:Gencode		:= dwGenCode
    SELF:Arg			:= cArg
    SELF:Description	:= cDescription

    /// Create an Error Object.
    CONSTRUCTOR (dwgencode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD)
    SUPER(ErrString( dwGenCode ))
    SELF:setDefaultValues()
    SELF:Gencode := dwgencode
    SELF:SubCode := dwSubcode
    SELF:FuncSym     := cFuncName
    SELF:Arg         := cArgName
    SELF:ArgNum      := iArgNum

    /// Create an Error Object.
    CONSTRUCTOR (dwgencode AS DWORD, dwSubCode := 0 AS DWORD)
    SELF:setDefaultValues()
    SELF:Gencode := dwgencode
    SELF:SubCode := dwSubcode

    /// <inheritdoc />
    OVERRIDE METHOD ToString() AS STRING
      LOCAL sb AS StringBuilder
      sb := StringBuilder{}
      sb:AppendLine("Description     :" + SELF:Description)
      sb:AppendLine("SubSystem       :" + SELF:SubSystem )
      sb:AppendLine("SubCode         :" + SELF:SubCode   )
      sb:AppendLine("GenCode         :" + ErrString(SELF:GenCode)  )
      sb:AppendLine("OsCode          :" + SELF:OsCode:ToString() )
      sb:AppendLine("ArgType         :" + TypeString(SELF:ArgType    ) )
      sb:AppendLine("ArgNum          :" + SELF:ArgNum:ToString()    )
      sb:AppendLine("FuncSym         :" + SELF:FuncSym   )
      sb:AppendLine("Severity        :" + SELF:Severity )
      sb:AppendLine("CanDefault      :" + SELF:CanDefault)
      sb:AppendLine("CanRetry        :" + SELF:CanRetry )
      sb:AppendLine("CanSubstitute   :" + SELF:CanSubstitute)
      sb:AppendLine("Operation       :" + SELF:Operation)
      sb:AppendLine("FileName        :" + SELF:FileName )
      sb:AppendLine("Tries           :" + SELF:Tries    )
      sb:AppendLine("SubCodeText     :" + SELF:SubCodeText)
      sb:AppendLine("Arg             :" + SELF:Arg)
      IF SELF:ArgTypeReqType == NULL
        sb:AppendLine("ArgTypeReq      :")
      ELSE
        sb:AppendLine("ArgTypeReq      :" + SELF:ArgTypeReqType:FullName)
      END IF
      sb:AppendLine("CallFuncSym     :" + SELF:CallFuncSym  )
      RETURN sb:ToString()

    /// Throw the error.
    VIRTUAL METHOD @@Throw AS VOID STRICT
        THROW SELF

    #region STATIC methods TO construct an error
    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, description AS STRING) AS Error
    RETURN ArgumentError(cFuncName, name, description, 0)

    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, iArgnum  AS DWORD, aArgs PARAMS OBJECT[]) AS Error
    VAR err			:= Error{Gencode.EG_ARG, name, ErrString( EG_ARG )}
    err:FuncSym     := cFuncName
    err:Description := err:Message
    err:Argnum		:= iArgNum
    err:args			:= aArgs
    RETURN err

    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, description AS STRING, iArgnum AS DWORD) AS Error
    VAR err			:= Error{Gencode.EG_ARG, name, description}
    err:FuncSym     := cFuncName
    err:Description := err:Message
    err:Argnum		:= iArgNum
    RETURN err

    /// <exclude/>
    STATIC METHOD WrapRawException( ex AS Exception ) AS Error
    LOCAL e AS Error
    e			  := Error{ ex }
    e:Description := ErrString( EG_EXCEPTION ) + ":" + ex:Message
    RETURN e

    /// <exclude/>
    STATIC METHOD VOError( dwGenCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs AS OBJECT[] ) AS Error
        LOCAL e AS Error
        e:= Error{dwGencode,cArgName}
        e:FuncSym := cFuncName
        e:ArgNum := iArgNum
        e:Args := aArgs
        RETURN e

    /// <exclude/>
    STATIC METHOD VOError( ex AS Exception, dwGenCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs AS OBJECT[]  ) AS Error
    LOCAL e AS Error
    e			  := Error{ ex, cFuncName, cArgName, iArgNum, aArgs }
    e:GenCode     := dwGenCode
    e:Description := ErrString( dwGenCode )
    RETURN e

    /// <exclude/>
    STATIC METHOD VODBError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:FuncSym     := cFuncName
    e:Description := ErrString( dwGenCode )
    RETURN e

    /// <exclude/>
    STATIC METHOD VODBError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:FuncSym     := cFuncName
    e:Description := ErrString( dwGenCode )
    e:Args        := aArgs
    RETURN e

    /// <exclude/>
    STATIC METHOD VODBError( dwGenCode AS DWORD, dwSubCode AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e			  := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:Description := ErrString( dwGenCode )
    e:Args        := aArgs
    RETURN e

    /// <exclude/>
    STATIC METHOD VODBError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode, cFuncName, cArgName, iArgNum}
    e:SubSystem   := "DBCMD"
    e:Description := ErrString( dwGenCode )
    e:Args        := aArgs
    RETURN e

    /// <exclude/>
    STATIC METHOD DataTypeError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e				:= Error{ ArgumentException{} , cFuncName, cArgName, iArgNum, aArgs}
    e:GenCode     := EG_DATATYPE
    e:Description := __CavoStr( VOErrors.DATATYPEERROR )
    RETURN e

    /// <exclude/>
    STATIC METHOD ArgumentError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, cDescription AS STRING, aArgs PARAMS OBJECT[]) AS Error
    LOCAL e AS Error
    e				:= Error{ ArgumentException{} , cFuncName, cArgName, iArgNum, aArgs}
    e:GenCode     := EG_ARG
    e:Description := cDescription
    RETURN e

    /// <exclude/>
    STATIC METHOD NullArgumentError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD ) AS Error
    LOCAL e AS Error
    e := Error{ ArgumentNullException{} ,cFuncName, cArgName, iArgNum}
    e:GenCode     := EG_ARG
    e:Description := __CavoStr( VOErrors.ARGISNULL )
    RETURN e

    /// <exclude/>
    STATIC METHOD BoundError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{ ArgumentException{ErrString( EG_BOUND) } }
    e:Severity    := ES_ERROR
    e:GenCode     := EG_BOUND
    e:SubSystem   := "BASE"
    e:FuncSym     := cFuncName
    e:Arg         := cArgName
    e:ArgNum      := iArgNum
    e:Args        := aArgs
    RETURN e

    #endregion
    /// <exclude />
    STATIC METHOD TypeToUsualType(oType AS System.Type) AS DWORD
    SWITCH Type.GetTypeCode(oType)
    CASE TypeCode.Boolean
      RETURN __UsualType.logic
    CASE TypeCode.Byte
      RETURN __UsualType.byte
    CASE TypeCode.Char
      RETURN __UsualType.Char
    CASE TypeCode.DateTime
      RETURN __UsualType.DATETIME
    CASE TypeCode.DBNull
      RETURN __UsualType.object
    CASE TypeCode.Decimal
      RETURN __UsualType.DECIMAL
    CASE TypeCode.Double
      RETURN __UsualType.real8
    CASE TypeCode.Empty
      RETURN __UsualType.void
    CASE TypeCode.Int16
      RETURN __UsualType.shortint
    CASE TypeCode.Int32
      RETURN __UsualType.long
    CASE TypeCode.Int64
      RETURN __UsualType.int64
    CASE TypeCode.SByte
      RETURN __UsualType.byte
    CASE TypeCode.Single
      RETURN __UsualType.real4
    CASE TypeCode.UInt16
      RETURN __UsualType.word
    CASE TypeCode.UInt32
      RETURN __UsualType.dword
    CASE TypeCode.UInt64
      RETURN __UsualType.uint64
    OTHERWISE
        SWITCH oType:FullName:ToLower()
        CASE "xsharp.__array"
          RETURN __UsualType.array
        CASE "xsharp.__codeblock"
          RETURN __UsualType.codeblock
        CASE "xsharp.__date"
          RETURN __UsualType.date
        CASE "xsharp.__float"
          RETURN __UsualType.float
        CASE "xsharp.__psz"
          RETURN __UsualType.psz
        CASE "xsharp.__symbol"
          RETURN __UsualType.symbol
        CASE "xsharp.__usual"
          RETURN __UsualType.usual
        CASE "system.intptr"
          RETURN __UsualType.ptr

      END SWITCH
    END SWITCH
    RETURN __UsualType.void

    /// <exclude />
    STATIC METHOD UsualTypeTotype(dwType AS DWORD) AS System.Type
    LOCAL typename := NULL AS STRING
    SWITCH dwType
    CASE __UsualType.array
      typeName := "XSharp.__Array"
    CASE __UsualType.byte
      RETURN typeof(System.Byte)
    CASE __UsualType.char
      RETURN typeof(System.Char)
    CASE __UsualType.codeblock
      typeName := "XSharp.__CodeBlock"
    CASE __UsualType.date
      typeName := "XSharp.__Date"
    CASE __UsualType.dword
      RETURN typeof(System.UInt32)
    CASE __UsualType.int64
      RETURN typeof(System.Int64)
    CASE __UsualType.float
      typeName := "XSharp.__Float"
    CASE __UsualType.logic
      RETURN typeof(System.Boolean)
    CASE __UsualType.long
      RETURN typeof(System.Int32)
    CASE __UsualType.object
      RETURN typeof(System.Object)
    CASE __UsualType.psz
      typeName := "XSharp.__Psz"
    CASE __UsualType.ptr
      RETURN typeof(System.IntPtr)
    CASE __UsualType.real4
      RETURN typeof(System.Single)
    CASE __UsualType.real8
      RETURN typeof(System.Double)
    CASE __UsualType.shortint
      RETURN typeof(System.Int16)
    CASE __UsualType.string
      RETURN typeof(System.String)
    CASE __UsualType.symbol
      typeName := "XSharp.__Symbol"
    CASE __UsualType.uint64
      RETURN typeof(System.Int64)
    CASE __UsualType.usual
      typeName := "XSharp.__Usual"
    CASE __UsualType.void
      RETURN typeof(System.Void)
    CASE __UsualType.word
      RETURN typeof(System.Uint16)
    END SWITCH
    // lookup types in XSharp.VO
    IF typename != NULL
        FOREACH asm AS Assembly IN AppDomain.CurrentDomain:GetAssemblies()
          IF asm:Getname():Name:ToLower() == "xsharp.vo"
            VAR type := asm:GetType(typeName, FALSE, TRUE)
            IF type != NULL
              RETURN type
            ENDIF
          ENDIF
        NEXT
    ENDIF
    RETURN NULL
  END CLASS
  /// <exclude />
  ENUM __UsualType AS BYTE
        // These numbers must match with the types defined in the compiler
        // They also match with the USUAL types in VO (BaseType.h)
        /// <exclude/>
        MEMBER @@Void		:=0
        /// <exclude/>
        MEMBER @@Long		:=1
        /// <exclude/>
        MEMBER @@Date		:=2
        /// <exclude/>
        MEMBER @@Float		:=3
        /// <exclude/>
        MEMBER @@Fixed      := 4 // Note # 4 (FIXED) was defined but never used in VO
        /// <exclude/>
        MEMBER @@Array		:=5
        /// <exclude/>
        MEMBER @@Object		:=6
        /// <exclude/>
        MEMBER @@String		:=7
        /// <exclude/>
        MEMBER @@Logic		:=8
        /// <exclude/>
        MEMBER @@Codeblock	:=9
        /// <exclude/>
        MEMBER @@Symbol		:=10
        // see below for missing values
        // The follow numbers are defined but never stored inside a USUAL in VO and Vulcan
        /// <exclude/>
        MEMBER @@Byte		:=11
        /// <exclude/>
        MEMBER @@ShortInt	:=12
        /// <exclude/>
        MEMBER @@Word		:=13
        /// <exclude/>
        MEMBER @@DWord		:=14
        /// <exclude/>
        MEMBER @@Real4		:=15
        /// <exclude/>
        MEMBER @@Real8		:=16
        /// <exclude/>
        MEMBER @@Psz		:=17
        /// <exclude/>
        MEMBER @@Ptr		:=18
        /// <exclude/>
        MEMBER @@Usual		:=19	// USUAL by Ref, not implemented in Vulcan
        // 20 and 21 not used
        /// <exclude/>
        MEMBER @@Int64		:=22
        /// <exclude/>
        MEMBER @@Uint64     :=23
        /// <exclude/>
        MEMBER @@Char		:=24    // not stored in a usual
        /// <exclude/>
        MEMBER @@Dynamic    :=25
        /// <exclude/>
        MEMBER @@DateTime	:=26
        /// <exclude/>
        MEMBER @@Decimal	:=27
        /// <exclude/>
        MEMBER @@Memo		:=32	// Used in RDD system in VO
        /// <exclude/>
        MEMBER @@Invalid    :=99
    END ENUM

END NAMESPACE

/// <exclude/>
FUNCTION ErrorBuild(pErrInfo AS exception) AS XSharp.ERROR
	RETURN  XSharp.Error{pErrInfo}

USING System
USING System.Collections.Generic
USING System.Text
USING System.Reflection
BEGIN NAMESPACE XSharp
  /// XSharp Runtime base Error class
  CLASS Error INHERIT Exception
    /// A string representing the name of the subsystem generating the error.
    PROPERTY SubSystem AS STRING AUTO
    /// An integer numeric value representing a Visual Objects generic error code.
    /// <Seealso cref="T:XSharp.Gencode"/>
    PROPERTY Gencode AS DWORD AUTO
    /// An integer numeric value representing a subsystem-specific error code.
    PROPERTY SubCode AS DWORD AUTO
    /// A string representing the name of the function or method in which the error occurred.
    PROPERTY FuncSym AS STRING AUTO
    /// A string representing the name used to open the file associated with the error condition.
    PROPERTY FileName AS STRING AUTO
    /// A constant indicating the severity of the error condition.
    /// <Seealso cref="T:XSharp.Severity"/>
    PROPERTY Severity AS DWORD AUTO
    /// A string that describes the error condition.
    PROPERTY Description		AS STRING  AUTO
    /// A string representing the argument supplied to an operator or function when an argument error occurs.
    PROPERTY Arg				AS STRING AUTO
    PRIVATE  _ArgType			AS DWORD
    /// A numeric value representing the data type of the argument that raised the error.
    PROPERTY ArgType			AS DWORD
      GET
        RETURN _ArgType
      END GET
      SET
        _ArgType := VALUE
        _ArgTypeType := UsualTypeToType(VALUE)
      END SET
    END PROPERTY
    PRIVATE  _ArgTypeType 		:= NULL AS System.Type
    /// The system type representing the data type of the argument that raised the error.
    PROPERTY ArgTypeType		AS System.Type
      GET
        RETURN _ArgTypeType
      END GET
      SET
        _ArgTypeType := VALUE
        _ArgType 	 := TypeToUsualType(VALUE)
      END SET
    END PROPERTY

    PRIVATE _ArgTypeReq		AS DWORD
    /// A numeric value representing the expected type of the argument that raised the error.
    PROPERTY ArgTypeReq			AS DWORD
      GET
        RETURN _ArgTypeReq
      END GET
      SET
        _ArgTypeReq := VALUE
        _ArgTypeReqType := UsualTypeToType(VALUE)
      END SET
    END PROPERTY
    PRIVATE  _ArgTypeReqType := NULL	AS System.Type
    /// The system type representing the expected type of the argument that raised the error.
    PROPERTY ArgTypeReqType		AS System.Type
      GET
        RETURN _ArgTypeReqType
      END GET
      SET
        _ArgTypeReqType := VALUE
        _ArgTypeReq 	 := TypeToUsualType(VALUE)
      END SET
    END PROPERTY
    ///
    PROPERTY SubstituteType     AS DWORD AUTO
    ///
    PROPERTY ArgNum				AS DWORD AUTO
    ///
    PROPERTY MethodSelf			AS OBJECT AUTO
    ///
    PROPERTY CallFuncSym		AS STRING AUTO
    ///
    PROPERTY Args				AS OBJECT[] AUTO
    ///
    PROPERTY Tries				AS INT AUTO
    ///
    PROPERTY CanDefault         AS LOGIC AUTO
    ///
    PROPERTY CanRetry           AS LOGIC AUTO
    ///
    PROPERTY CanSubstitute      AS LOGIC AUTO
    ///
    PROPERTY Operation          AS STRING AUTO
    ///
    PROPERTY SubCodeText        AS STRING AUTO
    ///
    PROPERTY OSCode				AS DWORD AUTO
    ///
    PROPERTY FileHandle         AS DWORD AUTO
    ///
    PROPERTY MaxSize			AS DWORD AUTO

    PRIVATE METHOD setDefaultValues() AS VOID
    SELF:Arg 			:= ""
    SELF:CallFuncSym 	:= ""
    SELF:Description    := ""
    SELF:FileName 		:= ""
    SELF:FuncSym 		:= ""
    SELF:Operation 		:= ""
    SELF:SubCodeText 	:= ""
    SELF:SubSystem 		:= ""
    SELF:Gencode		:= EG_UNKNOWN
    SELF:Subcode		:= 0
    SELF:Subsystem		:= "BASE"
    SELF:Severity		:= ES_ERROR
    SELF:CanDefault		:= FALSE
    SELF:CanRetry		:= FALSE
    SELF:CanSubstitute	:= FALSE
    SELF:Tries			:= 0
    SELF:FuncSym		:= ProcName(2)
    SELF:OSCode			:= 0

    ///
    CONSTRUCTOR()
    SELF:setDefaultValues()
    RETURN

    CONSTRUCTOR (msg AS STRING)
    SUPER(msg)
    SELF:setDefaultValues()
    SELF:Description := msg
    SELF:GenCode     := EG_EXCEPTION
    RETURN

    ///
    CONSTRUCTOR (ex AS Exception)
    SUPER(ex.Message,ex)
    SELF:setDefaultValues()
    IF ex IS Error
        LOCAL e := (Error) ex AS Error
        VAR props := typeof(error):GetProperties()
        FOREACH oProp AS PropertyInfo IN props
            IF oProp:CanWrite
                oProp:SetValue(SELF, oProp:GetValue(e))
            ENDIF
        NEXT
    ELSE
        SELF:Description := ex:Message
        SELF:GenCode     := EG_EXCEPTION
    ENDIF

    ///
    CONSTRUCTOR (ex AS Exception, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[])
    SUPER(ex.Message,ex)
    SELF:setDefaultValues()
    SELF:GenCode     := EG_EXCEPTION
    SELF:FuncSym     := cFuncName
    SELF:Arg         := cArgName
    SELF:ArgNum      := iArgNum
    SELF:Args		 := aArgs

    ///
    CONSTRUCTOR (dwgencode AS DWORD, cArg AS STRING)
    SUPER(ErrString( dwGenCode ))
    SELF:setDefaultValues()
    SELF:Gencode := dwGenCode
    SELF:Arg	 := cArg

    ///
    CONSTRUCTOR (dwgencode AS DWORD, cArg AS STRING, cDescription AS STRING)
    SUPER(cDescription)
    SELF:setDefaultValues()
    SELF:Gencode		:= dwGenCode
    SELF:Arg			:= cArg
    SELF:Description	:= cDescription

    ///
    CONSTRUCTOR (dwgencode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD)
    SUPER(ErrString( dwGenCode ))
    SELF:setDefaultValues()
    SELF:Gencode := dwgencode
    SELF:SubCode := dwSubcode
    SELF:FuncSym     := cFuncName
    SELF:Arg         := cArgName
    SELF:ArgNum      := iArgNum

    ///
    CONSTRUCTOR (dwgencode AS DWORD, dwSubCode := 0 AS DWORD)
    SELF:setDefaultValues()
    SELF:Gencode := dwgencode
    SELF:SubCode := dwSubcode

    /// <inheritdoc />
    OVERRIDE METHOD ToString() AS STRING
      LOCAL sb AS StringBuilder
      sb := StringBuilder{}
      sb:AppendLine("Description     :" + SELF:Description)
      sb:AppendLine("SubSystem       :" + SELF:SubSystem )
      sb:AppendLine("SubCode         :" + SELF:SubCode   )
      sb:AppendLine("GenCode         :" + ErrString(SELF:GenCode)  )
      sb:AppendLine("OsCode          :" + SELF:OsCode:ToString() )
      sb:AppendLine("ArgType         :" + TypeString(SELF:ArgType    ) )
      sb:AppendLine("ArgNum          :" + SELF:ArgNum:ToString()    )
      sb:AppendLine("FuncSym         :" + SELF:FuncSym   )
      sb:AppendLine("Severity        :" + SELF:Severity )
      sb:AppendLine("CanDefault      :" + SELF:CanDefault)
      sb:AppendLine("CanRetry        :" + SELF:CanRetry )
      sb:AppendLine("CanSubstitute   :" + SELF:CanSubstitute)
      sb:AppendLine("Operation       :" + SELF:Operation)
      sb:AppendLine("FileName        :" + SELF:FileName )
      sb:AppendLine("Tries           :" + SELF:Tries    )
      sb:AppendLine("SubCodeText     :" + SELF:SubCodeText)
      sb:AppendLine("Arg             :" + SELF:Arg)
      IF SELF:ArgTypeReqType == NULL
        sb:AppendLine("ArgTypeReq      :")
      ELSE
        sb:AppendLine("ArgTypeReq      :" + SELF:ArgTypeReqType:FullName)
      END IF
      sb:AppendLine("CallFuncSym     :" + SELF:CallFuncSym  )
      RETURN sb:ToString()

    ///
    VIRTUAL METHOD @@Throw AS VOID STRICT
        THROW SELF

    #region STATIC methods TO construct an error
    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, description AS STRING) AS Error
    RETURN ArgumentError(cFuncName, name, description, 0)

    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, iArgnum  AS DWORD, aArgs PARAMS OBJECT[]) AS Error
    VAR err			:= Error{Gencode.EG_ARG, name, ErrString( EG_ARG )}
    err:FuncSym     := cFuncName
    err:Description := err:Message
    err:Argnum		:= iArgNum
    err:args			:= aArgs
    RETURN err

    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, description AS STRING, iArgnum AS DWORD) AS Error
    VAR err			:= Error{Gencode.EG_ARG, name, description}
    err:FuncSym     := cFuncName
    err:Description := err:Message
    err:Argnum		:= iArgNum
    RETURN err

    /// <exclude/>
    STATIC METHOD WrapRawException( ex AS Exception ) AS Error
    LOCAL e AS Error
    e			  := Error{ ex }
    e:Description := ErrString( EG_EXCEPTION ) + ":" + ex:Message
    RETURN e

    /// <exclude/>
    STATIC METHOD VOError( dwGenCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs AS OBJECT[] ) AS Error
        local e as Error
        e:= Error{dwGencode,cArgName}
        e:FuncSym := cFuncName
        e:ArgNum := iArgNum
        e:Args := aArgs
        return e

    /// <exclude/>
    STATIC METHOD VOError( ex AS Exception, dwGenCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs AS OBJECT[]  ) AS Error
    LOCAL e AS Error
    e			  := Error{ ex, cFuncName, cArgName, iArgNum, aArgs }
    e:GenCode     := dwGenCode
    e:Description := ErrString( dwGenCode )
    RETURN e

    /// <exclude/>
    STATIC METHOD VODBError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:FuncSym     := cFuncName
    e:Description := ErrString( dwGenCode )
    RETURN e

    /// <exclude/>
    STATIC METHOD VODBError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:FuncSym     := cFuncName
    e:Description := ErrString( dwGenCode )
    e:Args        := aArgs
    RETURN e

    /// <exclude/>
    STATIC METHOD VODBError( dwGenCode AS DWORD, dwSubCode AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e			  := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:Description := ErrString( dwGenCode )
    e:Args        := aArgs
    RETURN e

    /// <exclude/>
    STATIC METHOD VODBError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode, cFuncName, cArgName, iArgNum}
    e:SubSystem   := "DBCMD"
    e:Description := ErrString( dwGenCode )
    e:Args        := aArgs
    RETURN e

    /// <exclude/>
    STATIC METHOD DataTypeError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e				:= Error{ ArgumentException{} , cFuncName, cArgName, iArgNum, aArgs}
    e:GenCode     := EG_DATATYPE
    e:Description := __CavoStr( VOErrors.DATATYPEERROR )
    RETURN e

    /// <exclude/>
    STATIC METHOD ArgumentError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, cDescription AS STRING, aArgs PARAMS OBJECT[]) AS Error
    LOCAL e AS Error
    e				:= Error{ ArgumentException{} , cFuncName, cArgName, iArgNum, aArgs}
    e:GenCode     := EG_ARG
    e:Description := cDescription
    RETURN e

    /// <exclude/>
    STATIC METHOD NullArgumentError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD ) AS Error
    LOCAL e AS Error
    e := Error{ ArgumentNullException{} ,cFuncName, cArgName, iArgNum}
    e:GenCode     := EG_ARG
    e:Description := __CavoStr( VOErrors.ARGISNULL )
    RETURN e

    /// <exclude/>
    STATIC METHOD BoundError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{ ArgumentException{ErrString( EG_BOUND) } }
    e:Severity    := ES_ERROR
    e:GenCode     := EG_BOUND
    e:SubSystem   := "BASE"
    e:FuncSym     := cFuncName
    e:Arg         := cArgName
    e:ArgNum      := iArgNum
    e:Args        := aArgs
    RETURN e

    #endregion
    /// <exclude />
    STATIC METHOD TypeToUsualType(oType AS System.Type) AS DWORD
    SWITCH Type.GetTypeCode(oType)
    CASE TypeCode.Boolean
      RETURN __UsualType.logic
    CASE TypeCode.Byte
      RETURN __UsualType.byte
    CASE TypeCode.Char
      RETURN __UsualType.Char
    CASE TypeCode.DateTime
      RETURN __UsualType.DATETIME
    CASE TypeCode.DBNull
      RETURN __UsualType.object
    CASE TypeCode.Decimal
      RETURN __UsualType.DECIMAL
    CASE TypeCode.Double
      RETURN __UsualType.real8
    CASE TypeCode.Empty
      RETURN __UsualType.void
    CASE TypeCode.Int16
      RETURN __UsualType.shortint
    CASE TypeCode.Int32
      RETURN __UsualType.long
    CASE TypeCode.Int64
      RETURN __UsualType.int64
    CASE TypeCode.SByte
      RETURN __UsualType.byte
    CASE TypeCode.Single
      RETURN __UsualType.real4
    CASE TypeCode.UInt16
      RETURN __UsualType.word
    CASE TypeCode.UInt32
      RETURN __UsualType.dword
    CASE TypeCode.UInt64
      RETURN __UsualType.uint64
    OTHERWISE
        SWITCH oType:FullName:ToLower()
        CASE "xsharp.__array"
          RETURN __UsualType.array
        CASE "xsharp.__codeblock"
          RETURN __UsualType.codeblock
        CASE "xsharp.__date"
          RETURN __UsualType.date
        CASE "xsharp.__float"
          RETURN __UsualType.float
        CASE "xsharp.__psz"
          RETURN __UsualType.psz
        CASE "xsharp.__symbol"
          RETURN __UsualType.symbol
        CASE "xsharp.__usual"
          RETURN __UsualType.usual
        CASE "system.intptr"
          RETURN __UsualType.ptr

      END SWITCH
    END SWITCH
    RETURN __UsualType.void

    /// <exclude />
    STATIC METHOD UsualTypeTotype(dwType AS DWORD) AS System.Type
    LOCAL typename := NULL AS STRING
    SWITCH dwType
    CASE __UsualType.array
      typeName := "XSharp.__Array"
    CASE __UsualType.byte
      RETURN typeof(System.Byte)
    CASE __UsualType.char
      RETURN typeof(System.Char)
    CASE __UsualType.codeblock
      typeName := "XSharp.__CodeBlock"
    CASE __UsualType.date
      typeName := "XSharp.__Date"
    CASE __UsualType.dword
      RETURN typeof(System.UInt32)
    CASE __UsualType.int64
      RETURN typeof(System.Int64)
    CASE __UsualType.float
      typeName := "XSharp.__Float"
    CASE __UsualType.logic
      RETURN typeof(System.Boolean)
    CASE __UsualType.long
      RETURN typeof(System.Int32)
    CASE __UsualType.object
      RETURN typeof(System.Object)
    CASE __UsualType.psz
      typeName := "XSharp.__Psz"
    CASE __UsualType.ptr
      RETURN typeof(System.IntPtr)
    CASE __UsualType.real4
      RETURN typeof(System.Single)
    CASE __UsualType.real8
      RETURN typeof(System.Double)
    CASE __UsualType.shortint
      RETURN typeof(System.Int16)
    CASE __UsualType.string
      RETURN typeof(System.String)
    CASE __UsualType.symbol
      typeName := "XSharp.__Symbol"
    CASE __UsualType.uint64
      RETURN typeof(System.Int64)
    CASE __UsualType.usual
      typeName := "XSharp.__Usual"
    CASE __UsualType.void
      RETURN typeof(System.Void)
    CASE __UsualType.word
      RETURN typeof(System.Uint16)
    END SWITCH
    // lookup types in XSharp.VO
    IF typename != NULL
        FOREACH asm AS Assembly IN AppDomain.CurrentDomain:GetAssemblies()
          IF asm:Getname():Name:ToLower() == "xsharp.vo"
            VAR type := asm:GetType(typeName, FALSE, TRUE)
            IF type != NULL
              RETURN type
            ENDIF
          ENDIF
        NEXT
    ENDIF
    RETURN NULL
  END CLASS
  /// <exclude />
  ENUM __UsualType AS BYTE
        // These numbers must match with the types defined in the compiler
        // They also match with the USUAL types in VO (BaseType.h)
        /// <exclude/>
        MEMBER @@Void		:=0
        /// <exclude/>
        MEMBER @@Long		:=1
        /// <exclude/>
        MEMBER @@Date		:=2
        /// <exclude/>
        MEMBER @@Float		:=3
        /// <exclude/>
        MEMBER @@Fixed      := 4 // Note # 4 (FIXED) was defined but never used in VO
        /// <exclude/>
        MEMBER @@Array		:=5
        /// <exclude/>
        MEMBER @@Object		:=6
        /// <exclude/>
        MEMBER @@String		:=7
        /// <exclude/>
        MEMBER @@Logic		:=8
        /// <exclude/>
        MEMBER @@Codeblock	:=9
        /// <exclude/>
        MEMBER @@Symbol		:=10
        // see below for missing values
        // The follow numbers are defined but never stored inside a USUAL in VO and Vulcan
        /// <exclude/>
        MEMBER @@Byte		:=11
        /// <exclude/>
        MEMBER @@ShortInt	:=12
        /// <exclude/>
        MEMBER @@Word		:=13
        /// <exclude/>
        MEMBER @@DWord		:=14
        /// <exclude/>
        MEMBER @@Real4		:=15
        /// <exclude/>
        MEMBER @@Real8		:=16
        /// <exclude/>
        MEMBER @@Psz		:=17
        /// <exclude/>
        MEMBER @@Ptr		:=18
        /// <exclude/>
        MEMBER @@Usual		:=19	// USUAL by Ref, not implemented in Vulcan
        // 20 and 21 not used
        /// <exclude/>
        MEMBER @@Int64		:=22
        /// <exclude/>
        MEMBER @@Uint64     :=23
        /// <exclude/>
        MEMBER @@Char		:=24    // not stored in a usual
        /// <exclude/>
        MEMBER @@Dynamic    :=25
        /// <exclude/>
        MEMBER @@DateTime	:=26
        /// <exclude/>
        MEMBER @@Decimal	:=27
        /// <exclude/>
        MEMBER @@Memo		:=32	// Used in RDD system in VO
        /// <exclude/>
        MEMBER @@Invalid    :=99
    END ENUM

END NAMESPACE

/// <exclude/>
FUNCTION ErrorBuild(pErrInfo AS exception) AS XSharp.ERROR
	RETURN  XSharp.Error{pErrInfo}