Operator overloading

/*
Operator overloading

 Some operators overloaded by extending their functionalities.
"$" was an operator for "checking substring existence in a string" 

 For example :

 ? "A" $ "ABC" // Result: .T.
 ? "Z" $ "ABC" // Result: .F.

 Now, this operator can be used for arrays and hashs too, not only strings.

 See examples below.

 "=>" was a preprocessor operator with meaning "translate to : ...".

Now, this operator can be used as a <key> - <value> separator in Hashs
for define and / or assign <key> - <value> to Hashs.
See examples below.

 "[ ]" was Array element indicator (Special)
 "{ }" was Literal array and code block delimiters (Special)

Now, this indicators can be used for hashs too. 
See examples below.

"+=" is self-increment operator that can be used both numeric 
and string values.

 Such as :

 cTest := "This"
 cTest += " is" 
 ? cTest // This is

 nTest := 3
 nTest += 10
 ? nTest // 13

 Now, this operator can be used for adding elements to an existing hash;
 ( but no for arrays ! ).
 Note : Extended functionalities of $ and += operators depends xHB lib.
        So need this usages to xHB lib and xHB.ch.

 See examples below.

*/
#include "xhb.ch"
PROCEDURE Main()

 CLS

 aFruits := { "apple", "appricot", "cherry", "melon", "pear", "mulberry" }

 ? "aFruits", IF( "pear" $ aFruits, '', 'not ' ) + "contain pear"
 ? "aFruits", IF( "grapes" $ aFruits, '', 'not ' ) +"contain grapes"

 aComplex := ARRAY( 10 )
AEVAL( aComplex, { | x1, i1 | aComplex[ i1 ] := i1 } )

 aComplex[ 5 ] := DATE()
 aComplex[ 7 ] := .F.

 ?
 ? "aComplex", IF( 3 $ aComplex, '', 'not ' ) + "contain 3"
 ? "aComplex", IF( 13 $ aComplex, '', 'not ' ) + "contain 13"
 ? "aComplex", IF( .T. $ aComplex, '', 'not ' ) + "contain .T."
 ? "aComplex", IF( .F. $ aComplex, '', 'not ' ) + "contain .F."
hEmpty := { => }
 ?
 ? "hEmpty is a", VALTYPE( hEmpty ), "type variable have",;
 STR( LEN( hEmpty ), 1 ), "element and it's",;
 IF( EMPTY( hEmpty ), '', 'not' ), "Empty"
hCountries := { 'Argentina' => "Buenos Aires" }
 hCountries += { 'Brasil' => "Brasilia" }
 hCountries += { 'Chile' => "Santiago" }
 hCountries += { 'Mexico' => "Mexico City" }

 ?
 ? "hCountries is a", VALTYPE( hCountries ), "type variable have",;
 STR( LEN( hCountries ), 1 ), "elements and and it's",;
 IF( EMPTY( hCountries ), '', 'not' ), "Empty"
cCountry := NIL
 FOR EACH cCountry IN hCountries
 ? cCountry:__ENUMKEY(), "=>", cCountry:__ENUMVALUE()
 NEXT 

 hDays := { 'Days' => { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" } }

 ?
 ? "hDays", IF( 'Days' $ hDays, '', 'not ' ) + "contain Days" 
 ? "hDays", IF( "Mon" $ hDays, '', 'not ' ) + "contain Mon" 
 ? "hDays['Days']", IF( "Fri" $ hDays["Days"], '', 'not ' ) + "contain Fri"
hLanguages := { "EN" => "English" } +; 
 { "DE" => "Deutsche" } +; 
 { "ES" => "Español" } +; 
 { "FR" => "Français" } +; 
 { "IT" => "Italiano" } +; 
 { "PL" => "Polkski" } +; 
 { "PT" => "Português" } +; 
 { "RU" => "Russkî" } +; 
 { "TR" => "Türkçe" }

 ?
 ? "hLanguages is a", VALTYPE( hLanguages ), "type variable have",;
 STR( LEN( hLanguages ), 1 ), "elements and and it's",;
 IF( EMPTY( hLanguages ), '', 'not' ), "Empty"
cLanguage := NIL 
 FOR EACH cLanguage IN hLanguages
 ? cLanguage:__ENUMKEY(), "=>", cLanguage:__ENUMVALUE()
 NEXT 

 @ MAXROW(), 0 
 WAIT "EOF OprOLoad.prg"
RETURN // OprOLoad.Prg.Main()
OprOLoad