001 package toolbus.process; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 import java.util.Stack; 006 import toolbus.AtomList; 007 import toolbus.State; 008 import toolbus.StateElement; 009 import toolbus.TBTermFactory; 010 import toolbus.environment.Environment; 011 import toolbus.exceptions.ToolBusException; 012 import toolbus.parsercup.PositionInformation; 013 import toolbus.process.debug.ExecutionResult; 014 import aterm.ATerm; 015 016 /** 017 * LeftBiasedAlternative implements the the asymmetric choice operator operator <+. It is similar 018 * to + but prefers its left argument. 019 * 020 * @author Arnold Lankamp 021 */ 022 public class LeftBiasedAlternative extends ProcessExpression implements StateElement{ 023 private final int LEFT = 0; 024 private final int RIGHT = 1; 025 026 private ProcessInstance processInstance; 027 028 private final ProcessExpression[] expr; 029 030 private final State[] state; 031 private final State mergeState; 032 033 private boolean leftLast = false; 034 035 public LeftBiasedAlternative(ProcessExpression left, ProcessExpression right, TBTermFactory tbfactory, PositionInformation posInfo){ 036 super(tbfactory, posInfo); 037 038 expr = new ProcessExpression[2]; 039 expr[LEFT] = left; 040 expr[RIGHT] = right; 041 042 state = new State[2]; 043 mergeState = new State(); 044 mergeState.addElement(this); 045 } 046 047 protected void computeFirst(){ 048 expr[LEFT].computeFirst(); 049 expr[RIGHT].computeFirst(); 050 } 051 052 protected void compile(ProcessInstance processInstance, Stack<String> calls, State follows) throws ToolBusException{ 053 this.processInstance = processInstance; 054 055 expr[LEFT].compile(processInstance, calls, follows); 056 state[LEFT] = expr[LEFT].getFirst(); 057 058 expr[RIGHT].compile(processInstance, calls, follows); 059 state[RIGHT] = expr[RIGHT].getFirst(); 060 setFollow(follows); 061 } 062 063 protected void replaceFormals(Environment env) throws ToolBusException{ 064 expr[LEFT].replaceFormals(env); 065 expr[RIGHT].replaceFormals(env); 066 } 067 068 protected ProcessExpression copy(){ 069 return new LeftBiasedAlternative(expr[LEFT].copy(), expr[RIGHT].copy(), tbfactory, getPosInfo()); 070 } 071 072 public AtomList getAtoms(){ 073 return expr[LEFT].getAtoms().union(expr[RIGHT].getAtoms()); 074 } 075 076 public State getFirst(){ 077 return mergeState; 078 } 079 080 public boolean contains(StateElement a){ 081 return state[LEFT].contains(a) || state[RIGHT].contains(a); 082 } 083 084 public ProcessInstance getProcess(){ 085 return processInstance; 086 } 087 088 public void setTest(ATerm test, Environment env) throws ToolBusException{ 089 state[LEFT].setTest(test, env); 090 state[RIGHT].setTest(test, env); 091 } 092 093 public List<ATerm> getTests(){ 094 return new ArrayList<ATerm>(0); 095 } 096 097 public boolean isEnabled(){ 098 return state[LEFT].isEnabled() || state[RIGHT].isEnabled(); 099 } 100 101 public State gotoNextStateAndActivate(){ 102 if(leftLast) return state[LEFT].gotoNextStateAndActivate(); 103 104 return state[RIGHT].gotoNextStateAndActivate(); 105 } 106 107 public State gotoNextStateAndActivate(StateElement se){ 108 if(state[LEFT].contains(se)) return state[LEFT].gotoNextStateAndActivate(se); 109 110 return state[RIGHT].gotoNextStateAndActivate(se); 111 } 112 113 public void activate(){ 114 state[LEFT].activate(); 115 state[RIGHT].activate(); 116 } 117 118 public boolean execute() throws ToolBusException{ 119 if(state[LEFT].execute()){ 120 leftLast = true; 121 return true; 122 }else if(state[RIGHT].execute()){ 123 leftLast = false; 124 return true; 125 }else return false; 126 } 127 128 public ProcessInstance[] debugExecute() throws ToolBusException{ 129 ExecutionResult er; 130 if((er = state[LEFT].debugExecute()) != null){ 131 leftLast = true; 132 return er.partners; 133 }else if((er = state[RIGHT].debugExecute()) != null){ 134 leftLast = false; 135 return er.partners; 136 } 137 138 return null; 139 } 140 141 public String toString(){ 142 return "LeftBiasedAlternative(" + state[LEFT] + "; " + state[RIGHT] + ")"; 143 } 144 }