exec_for proc pascal near
         local @@stkvar:for_struct
         uses ax
         
         lea ax,@@stkvar
         push ax
         call find_next         ;get corresponding NEXT location
         call get_token
         push offset token
         call find_var_index    ;get cycle variable
         mov @@stkvar.var,ax    ;store one's index
         call get_token
         cmp token,_ASSIGN      ;must be =
         je @@get_start_value
         push EQUAL_EXP
         call serror
@@get_start_value: 
         call eval_expr         ;compute initial value
         mov bx,@@stkvar.var
         mov variables[bx],ax   ;store it
         call get_token
         cmp tok,_TO            ;must be TO
         je @@get_end_value
         push TO_EXP
         call serror
@@get_end_value:         
         call eval_expr         ;compute target value
         mov @@stkvar.target,ax
         cmp ax,variables[bx]   ;store it too
         jl @@goto_next         ;if target<initial
         mov ax,_ip
         mov @@stkvar.loc,ax    ;store addres of first operator of cycle body
         lea ax,@@stkvar        ;address of local variable
         push ax
         call fpush             ;put into FOR stack
         jmp @@exit
@@goto_next:       
         mov ax,@@stkvar.next   ;skip cyle body
         mov _ip,ax
@@exit:
         ret
exec_for endp

find_next proc pascal near          
          arg @@for_stack:WORD
          local @@count:WORD
          uses ax,bp
                    
          mov @@count,00001h    ;counts FOR statements (one we already have)      
          push _ip
@@do:          
          call get_token
          cmp tok,_REM
          jne @@check_next
          call find_eol
          jmp @@do
@@check_next:          
          cmp tok,_NEXT
          jne @@check_for
          dec @@count           ;NEXT found!!!
          jnz @@do              ;if NEXT belongs to nested FOR
          mov bp,@@for_stack
          mov ax,_ip
          mov [bp].next,ax      ;store address of NEXT
          jmp @@break          
@@check_for:
          cmp tok,_FOR
          jne @@while
          inc @@count           ;nested FOR        
          jmp @@do
@@while:
          cmp tok,_FINISHED     ;scan whole program
          jne @@do
@@break:          
          pop _ip
          cmp tok,_FINISHED
          jne @@exit
          push FOR_WO_NEXT      ;corresponding NEXT not found
          call serror
@@exit:          
          ret
find_next endp

fpush proc pascal near
      arg @@i:WORD
      uses ax,cx,dx,si,di,es
      
      cmp ftos,FOR_NEST         ;is stack full ?
      jne @@enable_push
      push TOO_MNY_FOR
      call serror
@@enable_push:
      cld
      push ds
      pop es
      mov si,@@i
      mov cx,size for_struct
      mov ax,ftos
      mul cx                    ;compute item index in the FOR stack
      mov di,offset fstack
      add di,ax
      rep movsb                 
      inc ftos           
      ret
fpush endp

fpop proc pascal near
     arg @@i:WORD
     uses ax,cx,dx,si,di,es
     
     cmp ftos,0                 ;is stack empty ?
     jne @@enable_pop
     push NEXT_WO_FOR
     call serror
@@enable_pop:   
     dec ftos
     cld
     push ds
     pop es
     mov di,@@i
     mov cx,size for_struct
     mov ax,ftos
     mul cx     
     mov si,offset fstack
     add si,ax
     rep movsb
     ret
fpop endp