Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changes between Version 14 and Version 15 of LanguageSpec2/Statements

Show
Ignore:
Author:
JarrettBillingsley (IP: 24.112.131.93)
Timestamp:
07/06/09 04:41:00 (15 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • LanguageSpec2/Statements

    v14 v15  
    248248}}} 
    249249 
     250although it isn't entirely identical, since a variable declared in the condition is not visible in the 'else' block, if any exists. 
     251 
    250252Both the if body and the else body introduce a scope, so the following code, while not doing much, is legal: 
    251253 
    413415All indices are implicitly declared as local, and are only visible inside the loop.  This means previously-defined variables cannot be used.  This simplifies the implementation of foreach loops. 
    414416 
    415 Foreach loops actually accept three values for the container, though commonly these are provided as return values from an "iterator bootstrap" function.  The first container value is the true iterator function; the second is the "invariant state," usually the container being iterated; and the third is the "control," usually the index.  If the first value given in the foreach container is not a function, its opApply is looked up, and if it exists, it is called, retrieving the true iterator function and states for iteration. 
    416  
    417 Iteration begins by calling the iterator function with two parameters: the invariant state and the control.  The iterator function is expected to return the new indices.  Iteration ends when the first index is null.  Otherwise, the first index is used as the control for the next iteration of the loop.  Operation of the foreach statement could be summed up as: 
    418  
    419 {{{ 
    420 #!minid 
    421 
     417Foreach loops actually accept three values for the container, though commonly these are provided as return values from an "iterator bootstrap" function, usually in the form of an `opApply` metamethod.  The first container value is the iterator function or thread; the second is the "invariant state," usually the container being iterated, which is passed as 'this' to the iterator; and the third is the "control," usually the current index.   
     418 
     419If the first value given in the foreach container is not a function or thread, its opApply is looked up, and if it exists, it is called, retrieving the true iterator and states for iteration.  If none exists, it is an error. 
     420 
     421If the iterator is a function, each iteration of the loop, the iterator function is called with the invariant state as the 'this' parameter and the control as the first parameter.  The iterator function is expected to return the new indices.  Iteration ends when the first index that is returned is null.  Otherwise, the first index is used as the control value for the next iteration of the loop.   
     422 
     423If the iterator is a thread, before iteration begins, the thread must be in the 'initial' state.  Each iteration of the loop, the thread is called with the invariant state as the 'this' parameter and the control as the first parameter.  The iterator thread is expected to yield the new indices.  Iteration ends ''when the thread enters the dead state''.  When that happens, any values that may have been returned are ''not'' used for a final iteration of the loop.   
     424 
     425Operation of the foreach statement could be summed up as: 
     426 
     427{{{ 
     428#!minid 
     429
     430        local iterator, invState, control = ..  // stuff after the semicolon 
    422431        local index1, index2 .. // names before the semicolon 
    423         local iterFunc, invState, control = ..  // stuff after the semicolon 
    424  
    425         if(!isFunction(iterFunc)) 
    426                 iterFunc, invState, control = iterFunc.opApply(invState) 
    427  
    428         index1, index2 .. = iterFunc(with invState, control) 
    429  
    430         while(index1 !is null) 
     432 
     433        if(!isFunction(iterator) && !isThread(iterator)) 
    431434        { 
     435                iterator, invState, control = iterator.opApply(invState) 
     436 
     437                if(!isFunction(iterator) && !isThread(iterator)) 
     438                        throw "Error!" 
     439        } 
     440 
     441        if(isThread(iterator) && !iterator.isInitial()) 
     442                throw "Error!" 
     443 
     444        while(true) 
     445        { 
     446                index1, index2 .. = iterator(with invState, control) 
     447 
     448                if(isFunction(iterator)) 
     449                { 
     450                        if(index1 is null) 
     451                                break 
     452 
     453                        control = index1 
     454                } 
     455                else if(iterator.isDead()) 
     456                        break 
     457 
    432458                body 
    433  
    434                 index1, index2 .. = iterFunc(with invState, control) 
    435                 control = index1 
    436459        } 
    437460} 
    706729#!minid 
    707730stuff() 
     731 
    708732{ 
    709733        local _succeeded = true 
     734 
    710735        try 
    711736                rest() 
    716741        } 
    717742        finally 
    718                 foo() 
     743        { 
     744                if(_succeeded) 
     745                        foo() 
     746        } 
    719747} 
    720748}}} 
    727755#!minid 
    728756stuff() 
    729 scope(success) foo() 
     757scope(failure) foo() 
    730758rest() 
    731759}}} 
    736764#!minid 
    737765stuff() 
     766 
    738767try 
    739768        rest()