Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!willett!ForthNet From: ForthNet@willett.UUCP (ForthNet articles from GEnie) Newsgroups: comp.lang.forth Subject: Forth Implementation Message-ID: <616.UUL1.3#5129@willett.UUCP> Date: 6 Mar 90 01:04:20 GMT Organization: Latest link in the ForthNet chain. (Pgh, PA) Lines: 105 Category 3, Topic 24 Message 52 Mon Mar 05, 1990 R.BERKEY [Robert] at 05:48 PST Re: ?FOR , a version of FOR that executes zero times. Frank Sergeant writes: > Rob Chapman (via Usenet) suggests that u FOR ... NEXT should > execute u times. > > Rob, thanks for your suggestion... ... > I have about decided that I agree with Rob. ... > cmFORTH has the word -ZERO that accomplishes this change to u > instead of u+1. It is used like this > : STARS ( u -) FOR -ZERO STAR THEN NEXT ; ... > Rather than use -ZERO, I think I will build it in as the default. ... > Anyone have any thoughts on why we shouldn't make this change? I like Rob Chapman's structure, also. However, I think that using the name FOR impedes readability, portability of code, and potential for standardization. I don't see any basic technical problem with FOR (the name NEXT and using I equivalent to R@ with FOR are different issues). We went through this after Forth-83--there were those who chose to code or recode DO as ?DO . As to a zero executing version of FOR , here's an implementation I've added after seeing Rob Chapman's posting. The loop code is in the target system. Here are some of the target compiler implementations. thread, BRANCH, \ target compile BRANCH thread, ?FOR, \ target compile (?FOR) thread, ?LOOP, \ the (loop) that get's compiled can vary 0 value -1LOOP \ returns the compilation token of (-1LOOP) T: ?FOR ( -- >mark ) \ T: adds the word to a compiler vocabulary ?FOR, \ compile (?FOR) BRANCH, >MARK \ (inefficient: BRANCH, should be eliminated) IP-R> SAVE> ?LOOP, \ save what ?LOOP compiles on return stack IP->R \ (should be left on parameter stack?) -1LOOP =: ?LOOP, \ set ?LOOP, ; T: ?LOOP ( >mark -- ) DUP >RESOLVE \ resolve the branch after ?FOR ?LOOP, RESTORE> ?LOOP, IP->R \ put back previous copy in ?LOOP, ; This design is so that the syntax ?LOOP can be used to terminate a variety of loops. Also, ?FOR puts branch addresses on the stack as would BEGIN so that using WHILE inside a ?FOR loop is like using it inside a BEGIN ... UNTIL loop. I'm not at all sure about this--the ANS ?DO requires two addresses. Any comments? The following code is for the target system. On the 80x8x, using the overflow flag for (LOOP) and (NEXT) is a bit faster than using the carry flag (here it's 15 bytes memory access vs. 16). This is the same basic loop body I've always implemented for (LOOP) , except that this version has no provision for LEAVE . Maybe I'll add that later for compatibility, but for now I plan on using WHILE and UNLOOP for new code. CODE (-1LOOP) ( -- ) 0 [+BP] WORD DEC OV<> IF ES: LODSB CBW AX, SI ADD NEXT JMP THEN SI INC 4 #, BP ADD NEXT JMP END-CODE ' (-1LOOP) =: -1LOOP CODE (?FOR) ( u -- ) AX POP $80 #, AH XOR SWITCH, AX PUSH AX PUSH SWITCH, NEXT JMP END-CODE ' (?FOR) =: ?FOR, I'm not using I with these loops right now, but it could be coded as follows. This coding for I makes ?FOR ... I ... the same as 0 ?DO ... I ... CODE I ( -- w ) \ get the current index of the innermost loop 2 [+BP], AX MOV 0 [+BP], AX SUB AX PUSH NEXT JMP END-CODE Robert ----- This message came from GEnie via willett through a semi-automated process. Report problems to: 'uunet!willett!dwp' or 'willett!dwp@gateway.sei.cmu.edu'