* 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
142 lines
3.8 KiB
Plaintext
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
|
|
|