001    package toolbus.process;
002    
003    /**
004     * @author paulk
005     */
006    import java.util.Stack;
007    import toolbus.AtomList;
008    import toolbus.State;
009    import toolbus.TBTermFactory;
010    import toolbus.environment.Environment;
011    import toolbus.exceptions.ToolBusException;
012    import toolbus.parsercup.PositionInformation;
013    
014    /**
015     * Iteration implements the process expression P1 * P2. The current implementation does not handle
016     * the following case correctly: if Test1 then P1 * if Test2 then A . B . C fi else ... fi Problem:
017     * Test1 will be attached to A, but the first iteration of P1 may have modified local variables in
018     * such a way that Test1 has become false. We solve this in TscriptParser by prefixing every
019     * iteration with an extra tau so the test is always executed in an unmodified environment. So the
020     * above example becomes: if Test1 then tau. P1 * if Test2 then A . B . C fi else ... fi and Test1
021     * will be attached to tau (and is guaranteed to be still true when this branch is taken).
022     */
023    public class Iteration extends ProcessExpression{
024            private final ProcessExpression left;
025            private final ProcessExpression right;
026            
027            public Iteration(ProcessExpression left, ProcessExpression right, TBTermFactory tbfactory, PositionInformation posInfo){
028                    super(tbfactory, posInfo);
029                    this.left = left;
030                    this.right = right;
031            }
032            
033            protected ProcessExpression copy(){
034                    return new Iteration(left.copy(), right.copy(), tbfactory, getPosInfo());
035            }
036            
037            public String toString(){
038                    return "Iter(" + left.toString() + ", " + right.toString() + ")";
039            }
040            
041            protected void computeFirst(){
042                    left.computeFirst();
043                    right.computeFirst();
044                    setFirst(left.getFirst().union(right.getFirst()));
045            }
046            
047            protected void compile(ProcessInstance P, Stack<String> calls, State follow) throws ToolBusException{
048                    left.compile(P, calls, getFirst());
049                    right.compile(P, calls, follow);
050                    setFollow(follow);
051            }
052            
053            protected void replaceFormals(Environment env) throws ToolBusException{
054                    left.replaceFormals(env);
055                    right.replaceFormals(env);
056            }
057            
058            public AtomList getAtoms(){
059                    return left.getAtoms().union(right.getAtoms());
060            }
061    }