//NOTEST
//
// $Id: keywords.prg 9200 2008-08-20 11:04:28Z vszakats $
//

//DO NOT RUN THIS PROGRAM - ITS PURPOSE IS THE SYNTAX CHECK ONLY!

/* NOTE: 
 * Harbour compiled with the Flex version of lexical scanner is 
 * designed to stay Clipper compatible in keywords usage.
 * Simplex version is extending their usage in some places.
 * Use HB_CLIPPER_COMPATIBLE to check compilation in full compatibility mode
 */
//#define HB_CLIPPER_COMPATIBLE

#include "keywords.ch"  //INCLUDE test

EXTERNAL __case, __begin
STATIC nExt, bEgin, bReak, cAse, do, wHile, wIth, eXit, eXternal, fIeld
STATIC for, in, include, init, loop, local, using, static, return, recover

Function Main()

//just to prevent any disaster if someone will want to run it
  IF .T.
    RETURN nil
  ENDIF

//
//DANGER!!
//One line comments that ends with '**/' doesn't work!!!
//
//

//   NEXT(nExt) //in Clipper: NEXT does not match FOR
//   BEGIN( bEgin +';' + ;;   //////Clipper doesn't like more then one ';'
//          ";" ; /* ;;;;;Clipper doesn't like this comment after ';' ;;;;;;; */
//        )
   BREAK_(bReak)
//   CASE(case) //it is not possible to call case() in this context
   case :=CASE( CASE ) //this is valid

   //DO is reserved function name in Clipper!
   DO( nExt+bEgin/bReak-do*wHile%cAse $ wIth )

   WHILE( while ) //it is not possible to call while() in this context
   END

   ELSE_()      //ELSE is reserved word for *real*
   ELSEIF_()    //ELSEIF is reserved word for *real*
   ENDIF_()     //see above
   ENDCASE_()   //see above
   ENDDO_()     //see above

   END_()    //END? surprise :) it works in some cases!

   EXIT( eXit )

   EXTERNAL( eXternal )

   _FIELD( fIeld )

   for :=FOR( for )

   in( in )

   include( include )

   Init( init )

   LOCAL( local )

   LOOP( loop )

   USING( using )

   STATIC( STATIC )

   return :=return( return )

   RECOVER( recover )

RETURN( return )

/*================================================================
* * * * * ** Checking for NEXT
*/
FUNCTION NeXT( next_next/*next next*/ )

Local nExt, nExt7, nExtNEXT

    For NExt := 1 To 10

       OutStd( nExT )

   Next /*next*/ nExt     //next

   FOR nExt := 1 TO nExt
     QOut( nExt )
   NEXT

   FOR nExt :=1 TO 10
     QOut( nExt )
   NEXT ; ////////// ;
   NEXT

   nExt := 10 //next

   //nExt++  // TODO: PP steals the ++ in Clipper: NEXT does not match FOR
   nExt :=nExt++
   --nExt     /*next*/
   nExt7 :=7
   nExtNEXT := nExt   //next

   //nExt[ 1 ] :=nExt   // TODO: PP steals the [... in Clipper: NEXT does not match FOR
   //nExt[ nExt ] := next[ next ]
   nExt :=next[ next ]

#ifndef HB_CLIPPER_COMPATIBLE
   next->next :=next->next + next->next //NEXT does not match FOR in Clipper and Harbour(Flex)
#endif   
   next :=next->next
   ( next )->( next() )

  IF( nExt > nExt+4 )
    nExt := nExt +nExt * 5
  ELSEIF( nExt > 0 )
    nExt := nExt * 6 + nExt
  ELSE
    nExt +=5
  ENDIF

RETURN( nExt * /*next*/ nExt )

/*===================================================================
* Checking for BEGIN
**/
FUNCTION BEGIN( BEGIN_BEGIN )
LOCAL bEgin
LOCAL bEgin0, /* BEGIN OF BEGIN */ ;    /* in Clipper: Incomplete statement */
bEgin1

BEGIN SEQUENCE
    bEgin :=0
    FOR bEgin:=1 TO 10
      QOUT( bEgin )
      bEgin :=bEgin[ 1 ]
      bEgin[ 1 ] :=bEgin
      bEgin :=bEgin * 10
      bEgin++
      --bEgin
      ( begin )->( begin () )
    NEXT bEgin

    bEgin :=begin->begin

   begin->begin :=begin->begin +; /************************/
begin->begin
    bEgin :=BEGIN( begin +bEgin ) +;
            bEgin[ bEgin ]

END SEQUENCE

BEGIN /* BEGIN */ SEQU

    BEGIN_BEGIN :=bEgin//begin

END /* BEGIN */ SEQUENC

RETURN bEgin ^ 2

/*====================================================================
* Test for BREAK and BEGIN/RECOVER sequence
**/
FUNCTION BREAK_( break_break )
LOCAL bReak:=0

  ++bReak
  IF bReak == 0
    Break /*break*/ ( nil )
    BREAK   /* break to beggining */
    Break(0)   //in Clipper: syntax error: ')'
  ENDIF

  Break /*** break ***/ ;
; //////////////////////////////////////////////////
; //What
; //the
; //comment
; //like
; //it
; //is
; //doing
; //in
; //place
; //like
; //this?
; //Do
; //you
; //use
; //it
; //often?
;///////////////////////////////////////////////////
  (0)  //in Clipper: incomplete statement or unbalanced delimiters

begin sequence
  FOR bReak:=1 To 10
    QOut( bReak * bReak )
    break->break :=1
    ( break )->( break(0) )
  NEXT bReak
  break->break :=break->break +break->break
  BREAK
  break :=break[ 2 ] //not allowed in Clipper
  bReak :=IIF( bReak==1, BREAK(0), BREAK(bReak) )
recover USING bReak
  BREAK( Break( break(0) ) )
end

BREAK
RETURN bReak( bReak )

/*====================================================================
* Test for CASE/DO CASE
*/
FUNCTION CASE( case_ )
LOCAL case

  FOR case:=1 TO 15
    QUOT( case )
    QOUT( case * ; ////
case )
  NEXT case

 do case
  case[ case ] == "case"
  case[ 2 ] == "2"
 endcase

  case :=case[ 2 ]
  case =case + case - case
  case :={|case| case( case )}
  case :={|| case }
  case :={|case| case[ 4 ]}

  DO /* case */ CASE
  CASE 1
    case =case ** case
  CASE 2+case
    case =case +1
  CASE case++
#ifndef HB_CLIPPER_COMPATIBLE  
    case--   //sorry -Clipper & Harbour(flex) doesn't compile this line - but SimpLex does
    case++   //sorry -Clipper & harbour(flex) doesn't compile this line - but SimpLex does
#endif    
    ( case++ )
    ( case-- )
  CASE ++case
    ++case
  CASE ;
    case( case )
  CASE CASE
  CASE !CASE
  CASE -CASE
  CASE +CASE
/*
*
*
*/
  CASE( CASE )
    case =case != case
  CASE( CASE ) //new CASE or function call? :) - CASE supercedes case as identifier when syntax is valid.
  CASE case->case
    case->case :=case->case +1
    ( case )->( case() )
  OTHERWISE
    case *=case
  ENDCASE

RETURN case

/*====================================================================
* Test for DO CASE / DO WHILE / DO / WITH
*/
FUNCTION DO_( do )
LOCAL case
LOCAL while
LOCAL with

  do case
    case do
    case case
  endcase

  do/***do***/case/**/
    case do
  endcase

  DO CASE
  ENDCASE

  while .t.
  enddo

  do ;
  while do
    do :=1
  enddo

  do/***do***/while do/***do do do, da da da***/
    do :=do
  enddo

  do :={|do| do}

  do while do
    do()
    do->do :=do()
    do++
    do--
  enddo

  do while while
    ++do
  enddo

  do++
  do +=do
  do->do :=do->do +1
  ( do )->( do() )
  do[ 1 ] :=do
  do[ do ] :=do[ do ][ do ]

  DO do WITH do
  DO do WITH do()
  DO do

  DO while;
  while
    while :=while()
  ENDDO

  while while
#ifndef HB_CLIPPER_COMPATIBLE  
    while++   //Clipper & harbour(flex) incomplete statement or unbalanced delimiter
    while--   //Clipper & harbour(flex) incomplete statement or unbalanced delimiter
#endif    
    ( while++ )
    ( while-- )
    --while
    while +=while
    while->while :=while() +while->while
  enddo

  do->do :=while->while

  while[ 1 ] ==while
     while[ 2 ] $ "2"
       while( while )
         while( while[1] )
           while[ while ] == while[ 1 ]

             while :={|while| while}

           enddo
         enddo
       enddo

       while while++ < 10
          ( while )->( while() )
       enddo

     enddo
  enddo


  while while[1]   //in Clipper: syntax error ' 1 '
  enddo

  DO /* ****  */;
;
;
  while


  DO while WITH
    do :=with + while
  ENDDO

  do WITH;
;
;

  with()

  DO while WITH while
  DO while WITH while()
  DO while WITH with
  DO do WITH with
  DO do WITH with()

  with++
  ++with
  with +=with
  with->with :=with() +with->with +1
  ( with )->( with() )
  with :={|with| with}
  with :=with[ 1 ] //Syntax error ' 1 '
  with[ with ] :=1 //Syntax error ' WITH '
  with[ with ][ with ] =with[ with ][ with ]

  DO with WITH with
  DO with WITH with()
  DO with WITH do
  DO with WITH while
  DO with WITH do()
  DO with WITH while()

RETURN DO

FUNCTION WHILE( while )
RETURN while

FUNCTION With( with )
RETURN with

/*====================================================================
* Test for END
*/
FUNCTION END_(  )
LOCAL end, while

  //end()   TODO: PP steals the () //in Clipper: ENDIF does not match IF
  end :=end()

  ++end
  //end++  TODO: PP steals the ++    //in Clipper ENDIF does not match IF
  ( end++ )
  ( end-- )
  end :=end++

#ifndef HB_CLIPPER_COMPATIBLE  
  end->end +=1     //in Clipper & Harbour(flex): ENDIF does not match IF
#endif
  end :=end->end

  DO end WITH end
  DO end WITH end++

#ifndef HB_CLIPPER_COMPATIBLE  
  end->( end() )   //in Clipper & harbour(flex): ENDIF does not match IF
#endif
  ( end )->( end() )

  DO WHILE !end
    --while
  END

  DO WHILE end
    ++while
  END

  IF end
  END

  DO CASE
  CASE end
  END

  //end[ 1 ] :=1     //TODO: PP steals the [...  in Clipper: ENDIF does not match IF
  //end[ end ] :=2
  end :=end[ end ]
  end =end[ end ]
  end +=end
  end ^=end
  end %=end

BEGIN SEQU
  end :={| end | end }
END

RETURN end

FUNCTION end( end )
RETURN end * end

/*====================================================================
* Test for EXIT
*/
EXIT FUNCTION EXIT( exit )

  exit++
  ++exit

  exit[ 1 ] :=1
  exit :=exit[ 1 ]
  exit->exit :=exit->exit +1
  ( exit )->exit :=exit
  DO exit WITH exit

  exit()
  exit( exit )

//  EXIT    //EXIT statement with no loop in sight

  FOR exit:=1 TO 10
    exit++
    DO exit
    EXIT
  NEXT

  WHILE !exit
    exit +=1
    EXIT
  ENDDO

  DO CASE
  CASE exit
//    EXIT     //EXIT statement with no loop in sight
  CASE !exit
    exit()
  ENDCASE

RETURN exit


/*====================================================================
* Test for EXTERNAL
*/
FUNCTION EXTERN( extern )
LOCAL external
LOCAL exte
EXTE exte
EXTER exter
EXTERN extern
EXTERNA externa
EXTERNAL external

  extern++
  ++extern
  extern[ 1 ] :=1
  extern[ 1 ] :=extern
  external[ external ][ external ] :=external
  extern()
  externa()
  external()
  external->external :=external->external +1
  ( external )->external :=(external)->( external( external[ external ] ) )

  DO external
  DO external WITH external
  DO exte WITH exte
  DO WHILE external
    external :=!external
  ENDDO

RETURN extern

/*====================================================================
* Test for FIELD
*/
FUNCTION _FIELD( _field )  //FIELD is reserved function name (FIELDNAME)
FIELD field
FIEL fiel

  field++
  ++field

  field[ 1 ] :=field
  field[ field ] :=field[ field ]

  field->field :=field
  field->field :=field->field

  FIELD( FIEL(0) )

#ifndef HB_CLIPPER_COMPATIBLE
  DO field  //Incorrect number of arguments
  DO field WITH field     //field cannot be passed by a reference
#endif
  WHILE field
    fiel :=field +1
  ENDDO

RETURN field


/*====================================================================
* Test for FOR
*/
FUNCTION FOR( for )

  for++
  --for

  FOR for:=1 TO for+10
    for +=1
  NEXT for

  for :=for[ for ]
  for[ 1 ] :=1
  for[ for ] :=for
  for[ for ][ for ] :=for [ for ]

#ifndef HB_CLIPPER_COMPATIBLE  
  for( for( for ) )   //in Clipper: incomplete statement or unbalanced delimiters
  for( 0 )      //in Clipper: incomplete statement or unbalanced delimiters
  for()      //syntax error ')'
#endif
  for :=for()
  for :=for( for( for ) )

  for :={|for| for}
  EVAL( {|for| for}, for )

  for->for :=for
  for :=for->for
  for->for :=for->for
  ( for )->for :=( for )->for

  DO for
  DO for WITH for
  DO WHILE for
    for ^=2
  ENDDO

RETURN for

/*====================================================================
* Test for IN
*/
FUNCTION IN( _in )
FIELD begin IN begin
FIELD break IN break
FIELD case IN case
FIELD do IN do
FIELD for IN for
FIELD in IN in
FIELD next IN next
FIELD while IN while
FIELD end IN end
FIELD with IN with
FIELD exit IN exit
FIELD external IN external
FIELD field IN field

  IN( in )
  in++
  --in
  in->in :=in
  in[ 1 ] :=1
  in[ in ] :=in[ in ]
  ( in )->in :=in

  in :={|in| in}
  EVAL( {|in| in}, in )

  DO in
#ifndef HB_CLIPPER_COMPATIBLE
  DO in WITH in       //IN cannot be passed by a reference
#endif

RETURN in

/*====================================================================
* Test for INCLUDE
*/
FUNCTION include( include )

  FOR include:=1 TO 10
    include++
    --include
  NEXT include

  WHILE include
  ENDDO

  include[ 1 ] :=1
  include := include[ include ]

  include :={|include| include}
  EVAL( {|include| include}, include )

  DO include
  DO include WITH include

  include->include :=1
  include->include :=include->include +1
  ( include )->include :=INCLUDE( include->include )

RETURN include

/*====================================================================
* Test for INIT
*/
INIT fUNCTION Init( init )

  FOR init:=1 TO 10
    init++
    --init
  NEXT init

  WHILE init
    init :=!init
  END

  init[ 1 ] :=1
  init :=init[ init ]

  init->init :=init->init +1
  ( init )->init :=INIT( init[ init->init ] )

  init :={|init| init}
  EVAL( {|init| init}, init )

  DO INIT WITH init
  DO INIT

RETURN init


/*====================================================================
* Test for LOCAL
*/
FUNCTION local( _local )
LOCAL local

  FOR local:=1 TO 10
    local++
    --local
  NEXT local

  local :={|local| local}
  EVAL( {|local| local}, local )

  WHILE local
  ENDDO

  local[ 1 ] :=1
  local :=local[ local ]

  local->local :=local->local
  ( local )->local :=LOCAL( local[ local->local ] )

  DO local
  DO local WITH local

RETURN local

/*====================================================================
* Test for LOOP
*/
FUNCTION loop( loop )

  FOR loop:=1 TO 10
    loop++
    --loop
    QOut( loop )
    IF( loop == 5 )
      Qout( "LOOP to begginig" )
      loop
    ENDIF
    IF( loop == 9 )
      Qout( "EXIT from FOR statement" )
      EXIT
    ENDIF
  NEXT loop
  Qout( "After ", loop, "loops" )


//  LOOP

  loop :={|loop| loop}
  EVAL( {|loop| loop}, loop )

  loop =1
  WHILE loop <= 10
    Qout( loop )
    IF( loop == 5 )
        Qout( "LOOP to 7" )
        loop :=7
        LOOP
    ENDIF
    IF( loop == 9 )
      Qout( "EXIT form while" )
      EXIT
    ENDIF
    ++loop
  ENDDO
  Qout( "After ", loop, " loops" )

  loop[ 1 ] :=1
  loop :=loop[ loop ]

  loop->loop :=loop->loop
  ( loop )->loop :=loop( loop[ loop->loop ] )

  DO loop
  DO loop WITH loop

RETURN loop


/*====================================================================
* Test for USING
*/
FUNCTION using
LOCAL using
PRIVATE &using

  EVAL( using )

  FOR using:=1 TO 10
    ? using
    BREAK using
  NEXT

  DO WHILE using > 0
    ++using
    using--
  ENDDO

  BEGIN SEQUENCE
    ? USING
  RECOVER USIN using
    ? using
  END

RETURN using


/*====================================================================
* Test for STATIC
*/
FUNCTION STATIC
STAT stat
STATI stati
STATIC static
PRIVATE &STATIC

  EVAL( STATIC )

  FOR static:=1 TO 10
    ? static
    static( static )
    BREAK static
  NEXT

  IF static
     BREAK stat
  ENDIF

  DO WHILE static
    ++static
    static -=2
    break stat
  ENDDO

  static++
  static--
  ( static++ )
  ( static-- )
  BEGIN SEQUENCE
    ? static
  RECOVER USIN static
    ? static
  END

RETURN static


/*====================================================================
* Test for RETURN
*/
FUNCTION RETURN
STAT return
LOCAL Self
PRIVATE &return

  EVAL( return )

  FOR return:=1 TO 10
    ? return
    return ( return )
    BREAK return
  NEXT

  IF return
     RETU return
  ENDIF

  return := return( return )
  return += return
  return-=return
  return->return ^= 3
  return:return()

  return::return
  return ::return
  return-1
  return -1
  return+2
  return +2
#ifndef HB_CLIPPER_COMPATIBLE  
  return++    //Clipper fails on this
  return--    //Clipper fails on this
#endif
  ( return++ )
  ( return-- )
  ++return
  --return
  return!return
  return &return

  DO WHILE return
    ++return
    return -=2
    break return
  ENDDO

  BEGIN SEQUENCE
    ? return
  RECOVER USIN return
    ? return
  END

RETURN( return ) + 2


/*====================================================================
* Test for RECOVER
*/
FUNCTION RECOVER
STAT RECOVER
PRIVATE &RECOVER

  EVAL( RECOVER )

  FOR RECOVER:=1 TO 10
    ? RECOVER
    RECOVER ( RECOVER )
    BREAK RECOVER
  NEXT

  IF RECOVER
     RETU RECOVER
  ENDIF

  RECOVER := RECOVER( RECOVER )

  DO WHILE RECOVER
    ++RECOVER
    RECOVER -=2
    break RECOVER
  ENDDO

  RECOVER++
  RECOVER--
  ( RECOVER++ )
  ( RECOVER-- )

  BEGIN SEQUENCE
    ? RECOVER
  RECOVER
    ? RECOVER
  END

  BEGIN SEQUENCE
    ? RECOVER
  RECOVER USIN RECOVER
    ? RECOVER
  END

RETURN( RECOVER ) +2


/*====================================================================
* Test for OTHERWISE
*/
FUNCTION OTHERWISE
STAT OTHERWISE
PRIVATE &OTHERWISE

  EVAL( OTHERWISE )

  FOR OTHERWISE:=1 TO 10
    ? OTHERWISE
    OTHERWISE ( OTHERWISE )
    BREAK OTHERWISE
  NEXT

  IF OTHERWISE
     RETU OTHERWISE
  ENDIF

  OTHERWISE := OTHERWISE( OTHERWISE )

  OTHERWISE++

  DO WHILE OTHERWISE
    ++OTHERWISE
    OTHERWISE -=2
    break OTHERWISE
  ENDDO

  DO CASE
  CASE OTHERWISE
    ? OTHERWISE
  CASE !OTHERWISE
    ? OTHERWISE
  OTHE
    ? OTHERWISE +1
//  OTHER           //Mayhem in CASE
    ? OTHERWISE +2
  END


RETURN( OTHERWISE ) +2

/* Testing macro compilation */
PROCEDURE MACRO()
MEMVAR s
PRIVATE s

 s := &s
 s := &s.
 s := &s.1
 s := &s.123
 s := &s._
 s := &s._____
 s := &s._1
 s := &s.1_bo
 s := _&s
 s := _&s.
 s := _&s.1
 s := _&s.123
 s := _&s._
 s := _&s._____
 s := _&s._1
 s := _&s.1_bo
 s := x_&s
 s := x_&s_1
 s := x_&s._1
 s := x_&s._123
 s := x_&s.123
 s := x_&s.2_
 s := x_&s.2_x

RETURN
