Files
harbour-core/harbour/tests/foreach.prg
Ryszard Glab d947f68c8e 2005-11-07 14:35 UTC+0100 Ryszard Glab <rglab@imid.med.pl>
* include/hbapi.h
   * include/hbapiitm.h
   * include/hbcomp.h
   * include/hberrors.h
   * include/hbexpra.c
   * include/hbpcode.h
   * include/hbsetup.h
   * source/common/expropt1.c
   * source/compiler/expropta.c
   * source/compiler/genc.c
   * source/compiler/gencli.c
   * source/compiler/harbour.c
   * source/compiler/harbour.l
   * source/compiler/harbour.y
   * source/compiler/hbfix.c
   * source/compiler/hbgenerr.c
   * source/compiler/hbpcode.c
   * source/macro/macroa.c
   * source/vm/hvm.c
   * source/vm/itemapi.c
   + tests/foreach.prg
      + added support for FOR EACH loop
         FOR EACH var1 [,var255] IN expr1 [,expr255] [DESCEND]
         NEXT

         Note:
            -expr can be a string or an array
               if it is a string then assigments to the control
               variable does not change the string
            -after the loop the controlling variable(s) store the
             value which they had before entering the loop
            -the controlling variable supports the following properties
             :__enumindex - the loop counter for variable
             :__enumbase  - the value that is being traversed
             :__enumvalue - the value of variable
            -see tests/foreach.prg for examples

      + added warnings in cases of duplicated loop variables
       eg. FOR i:=1 TO 5
            FOR i:=i TO i+5

      -removed strong typing in the compiler (xHarbour too)
      (reactivate it by compiling with -DHB_COMP_STRONG_TYPES)

NOTE:
   The new pcodes were added - rebuild everything
2005-11-07 13:28:40 +00:00

142 lines
3.8 KiB
Plaintext

/*
* $Id$
*/
PROCEDURE MAIN()
LOCAL A:={ "one ", "two ", "three" }
LOCAL AA:={ "AA-one ", "AA-two ", "AA-three", "AA-four " }
LOCAL c:="abcdefghij"
LOCAL enum:="b"
LOCAL bb, cc
LOCAL i
/*
test(@a,b)
test(a,@b)
test(@a,@b)
*/
? "========================================================"
? "before loop: ENUM=",ENUM
? 'before loop: a[1]=',a[1], 'a[2]=',a[2], 'a[3]=',a[3]
FOR EACH enum IN A
? "start: ENUM=", ENUM
IF( ENUM = 'two' )
ENUM := UPPER( ENUM )
ENDIF
? "end: ENUM=", ENUM, "| index:", ENUM:__enumIndex, "| value:", ENUM:__enumValue, "| base: ", VALTYPE(ENUM:__enumBase)
NEXT
? "after loop ENUM=", ENUM
? 'after loop: a[1]=',a[1], 'a[2]=',a[2], 'a[3]=',a[3]
? "-----------------"
?
inkey(0)
? "========================================================"
? "Testing passing by reference"
? "before loop: ENUM=",ENUM
? 'after loop: a[1]=',a[1], 'a[2]=',a[2], 'a[3]=',a[3]
FOR EACH ENUM IN A
IF( UPPER(ENUM) = 'TWO' )
ENUM := UPPER( ENUM )
? "before passing by @ | ENUM=", ENUM, "| index:", ENUM:__enumIndex, "| value:", ENUM:__enumValue, "| base: ", VALTYPE(ENUM:__enumBase)
testBYREF( @ENUM )
? " after passing by @ | ENUM=", ENUM, "| index:", ENUM:__enumIndex, "| value:", ENUM:__enumValue, "| base: ", VALTYPE(ENUM:__enumBase)
ENDIF
NEXT
? "after loop ENUM=", ENUM
? 'after loop: a[1]=',a[1], 'a[2]=',a[2], 'a[3]=',a[3]
inkey(0)
? "========================================================"
? "Testing BREAK"
? "before loop: ENUM=",ENUM
? 'after loop: a[1]=',a[1], 'a[2]=',a[2], 'a[3]=',a[3]
BEGIN SEQUENCE
FOR EACH enum IN A DESCEND
? "loop: ENUM=", ENUM, "| index:", ENUM:__enumIndex, "| value:", ENUM:__enumValue, "| base: ", VALTYPE(ENUM:__enumBase)
TESTbreak( ENUM )
NEXT
RECOVER USING i
? "after loop ENUM=", ENUM
? 'after loop: a[1]=',a[1], 'a[2]=',a[2], 'a[3]=',a[3]
? "recover variable i=", i
END SEQUENCE
inkey(0)
? "========================================================"
? "before loop: ENUM=",ENUM
? 'before loop: c=',c
BEGIN SEQUENCE
FOR EACH enum IN c
? "start: ENUM=", ENUM
IF( enum = 'd' )
enum := UPPER( enum )
ENDIF
Testbreak( enum )
? "end: ENUM=", ENUM, "| index:", ENUM:__enumIndex, "| value:", ENUM:__enumValue, "| base: ", VALTYPE(ENUM:__enumBase)
NEXT
RECOVER USING i
? "after loop ENUM=", ENUM
? 'after loop: c=', c
? "recover variable i=", i
END SEQUENCE
? "========================================================"
FOR EACH enum,bb,cc IN A,AA,c
? enum, enum:__enumIndex, enum:__enumValue
? bb, bb:__enumIndex, bb:__enumValue
? cc, cc:__enumIndex, cc:__enumValue
NEXT
inkey(0)
? "========================================================"
FOR EACH enum,bb,cc IN A,AA,c DESCEND
? enum, enum:__enumIndex, enum:__enumValue
? bb, bb:__enumIndex, bb:__enumValue
? cc, cc:__enumIndex, cc:__enumValue
NEXT
FOR EACH enum IN a
BEGIN SEQUENCE
IF( enum = '2' )
BREAK
ENDIF
END SEQUENCE
NEXT
FOR EACH enum IN a
BEGIN SEQUENCE
IF( enum = '2' )
? "Breaking... enum=", enum
BREAK enum
ENDIF
RECOVER USING enum
? "after recovery: enum=", enum
END SEQUENCE
NEXT
RETURN
PROCEDURE TESTbreak( v )
IF( v = '2' .or. v = 'd' )
? "issuing break"
BREAK( v )
ENDIF
RETURN
PROCEDURE TESTBYREF( enum )
? "start of testBYREF ENUM=", ENUM
FOR EACH ENUM IN {1,2,3}
? " -testBYREF=", ENUM
NEXT
? "end of loop: ENUM=", ENUM
ENUM := "22222"
? "end of testBYREF ENUM=", ENUM
RETURN