package jcircus.complexcomms;
import java.util.Set;
import java.util.Vector;
import jcircus.complementaryenvs.ActStackVarEnv;
import jcircus.complementaryenvs.StackVarEnv;
import jcircus.newutil.CommunicationUtil;
import jcircus.newutil.ExceptionUtil;
import jcircus.newutil.ExprUtil;
import jcircus.newutil.FactoryUtil;
import jcircus.newutil.PrinterUtil;
import jcircus.parallelism.CopyProcessAnn;
import jcircus.parallelism.RenamedVarAnn;
import net.sourceforge.czt.base.ast.Term;
import net.sourceforge.czt.circus.ast.Action1;
import net.sourceforge.czt.circus.ast.Action2;
import net.sourceforge.czt.circus.ast.ActionPara;
import net.sourceforge.czt.circus.ast.AssignmentCommand;
import net.sourceforge.czt.circus.ast.AssignmentPairs;
import net.sourceforge.czt.circus.ast.BasicAction;
import net.sourceforge.czt.circus.ast.BasicProcess;
import net.sourceforge.czt.circus.ast.CallAction;
import net.sourceforge.czt.circus.ast.CallProcess;
import net.sourceforge.czt.circus.ast.CircusAction;
import net.sourceforge.czt.circus.ast.CircusActionList;
import net.sourceforge.czt.circus.ast.CircusCommand;
import net.sourceforge.czt.circus.ast.CircusFieldList;
import net.sourceforge.czt.circus.ast.CircusProcess;
import net.sourceforge.czt.circus.ast.Communication;
import net.sourceforge.czt.circus.ast.DotField;
import net.sourceforge.czt.circus.ast.ExtChoiceAction;
import net.sourceforge.czt.circus.ast.Field;
import net.sourceforge.czt.circus.ast.GuardedAction;
import net.sourceforge.czt.circus.ast.IfGuardedCommand;
import net.sourceforge.czt.circus.ast.InputField;
import net.sourceforge.czt.circus.ast.IntChoiceAction;
import net.sourceforge.czt.circus.ast.ParAction;
import net.sourceforge.czt.circus.ast.ParamProcess;
import net.sourceforge.czt.circus.ast.PrefixingAction;
import net.sourceforge.czt.circus.ast.Process1;
import net.sourceforge.czt.circus.ast.Process2;
import net.sourceforge.czt.circus.ast.ProcessPara;
import net.sourceforge.czt.circus.ast.SeqAction;
import net.sourceforge.czt.circus.ast.SpecStmtCommand;
import net.sourceforge.czt.circus.ast.VarDeclCommand;
import net.sourceforge.czt.circus.util.Factory;
import net.sourceforge.czt.z.ast.AndPred;
import net.sourceforge.czt.z.ast.ApplExpr;
import net.sourceforge.czt.z.ast.ConstDecl;
import net.sourceforge.czt.z.ast.Decl;
import net.sourceforge.czt.z.ast.Expr;
import net.sourceforge.czt.z.ast.FalsePred;
import net.sourceforge.czt.z.ast.MemPred;
import net.sourceforge.czt.z.ast.NarrSect;
import net.sourceforge.czt.z.ast.NegPred;
import net.sourceforge.czt.z.ast.NumExpr;
import net.sourceforge.czt.z.ast.OrPred;
import net.sourceforge.czt.z.ast.Para;
import net.sourceforge.czt.z.ast.Pred;
import net.sourceforge.czt.z.ast.RefExpr;
import net.sourceforge.czt.z.ast.SetExpr;
import net.sourceforge.czt.z.ast.Spec;
import net.sourceforge.czt.z.ast.TruePred;
import net.sourceforge.czt.z.ast.TupleExpr;
import net.sourceforge.czt.z.ast.VarDecl;
import net.sourceforge.czt.z.ast.ZDeclList;
import net.sourceforge.czt.z.ast.ZExprList;
import net.sourceforge.czt.z.ast.ZName;
import net.sourceforge.czt.z.ast.ZNameList;
import net.sourceforge.czt.z.ast.ZParaList;
import net.sourceforge.czt.z.ast.ZSect;
public class CCUpdater {
/**@author: Samuel Barrocas
* Performs the renaming of the repeated variables of communication input fields
* **/
public void updateSpec (Spec spec) {
ZSect zSect;
ActStackVarEnv asve = new ActStackVarEnv ();
if (spec.getSect().get(0) instanceof NarrSect)
zSect = (ZSect) spec.getSect().get(1);
else
zSect = (ZSect) spec.getSect().get(0);
ZParaList paras = (ZParaList) zSect.getParaList();
int size = paras.size ();
for (int i = 0; i < size; i++) {
Para para = paras.get(i);
System.out.print("");
if (para instanceof ProcessPara) {
ProcessPara processPara = (ProcessPara) para;
updateProcessPara (processPara, asve, spec);
}
}
}
public void updateProcessPara (ProcessPara processPara, ActStackVarEnv asve, Spec spec) {
CircusProcess process = processPara.getCircusProcess();
String procname = processPara.getZName().toString();
if (processPara.getAnn(CopyProcessAnn.class) == null)
updateCircusProcess (procname, process, asve, spec);
asve = new ActStackVarEnv ();
}
public void updateCircusProcess (String procname, CircusProcess process, ActStackVarEnv asve, Spec spec) {
FactoryUtil f = new FactoryUtil ();
if (process instanceof BasicProcess) {
BasicProcess basic = (BasicProcess)process;
ZParaList paraList = basic.getZParaList();
int size = paraList.size();
for (int i = 0; i < size; i++) {
if (paraList.get(i) instanceof ActionPara) {
ActionPara actionPara = (ActionPara)paraList.get(i);
if (!actionPara.getName().toString().contains("Previous")) {
addStackVarAnns2CircusAction (procname, actionPara.getCircusAction(), actionPara.getName().toString(), new ActStackVarEnv (), true);
}
}
}
for (int i = 0; i < size; i++) {
if (paraList.get(i) instanceof ActionPara) {
ActionPara actionPara = (ActionPara)paraList.get(i);
if (!actionPara.getName().toString().contains("Previous")) {
System.out.println (PrinterUtil.specAsString (spec));
updateCircusAction (procname, actionPara.getCircusAction(), actionPara.getName().toString());
System.out.println (PrinterUtil.specAsString (spec));
System.out.print ("");
}
}
}
}
else if (process instanceof ParamProcess) {
updateCircusProcess (procname, ((ParamProcess) process).getCircusBasicProcess(), asve, spec);
}
else if (process instanceof Process1) {
updateCircusProcess (procname, ((Process1)process).getCircusProcess (), asve, spec);
}
else if (process instanceof Process2) {
updateCircusProcess (procname, ((Process2)process).getLeftProcess (), asve, spec);
updateCircusProcess (procname, ((Process2)process).getRightProcess (), asve, spec);
}
else if (process instanceof CallProcess) {
}
else {
ExceptionUtil.throwException ("CCUpdater.updateCircusProcess: Please implement an \"else if\" for " + process.getClass());
/*anything else?*/
}
}
private void removeAllSVEAnns (Term term) {
int counter = 0;
while (term.getAnn(StackVarEnvAnn.class) != null) {
StackVarEnvAnn svea = term.getAnn(StackVarEnvAnn.class);
term.getAnns().remove(svea);
counter++;
}
System.out.print ("");
}
public void addStackVarAnns2CircusAction (String procname, CircusAction action, String actionName, ActStackVarEnv asve, boolean push) {
if (action instanceof CircusCommand) {
/**Todas as subinterfaces de CircusCommand são estas abaixo*/
if (action instanceof AssignmentCommand) {
AssignmentPairs apairs = ((AssignmentCommand)action).getAssignmentPairs();
StackVarEnvAnn svea = new StackVarEnvAnn (actionName, new StackVarEnv (asve.get(actionName)));
apairs.getAnns().add(svea);
System.out.print ("");
}
else if (action instanceof IfGuardedCommand) {
CircusActionList cal = ((IfGuardedCommand) action).getGuardedActionList();
int size = cal.size();
for (int i = 0; i < size; i++) {
GuardedAction ga = (GuardedAction) cal.get(i);
//Pred pred = ga.getPred();
//StackVarEnvAnn svea = new StackVarEnvAnn (actionName, asve.get(actionName));
//pred.getAnns().add(svea);
addStackVarAnns2CircusAction (procname, ga, actionName, asve, push);
}
}
else if (action instanceof VarDeclCommand) { //TODO NAO TESTADO
VarDeclCommand vdc = ((VarDeclCommand)action);
ZDeclList decls = vdc.getZDeclList();
StackVarEnvAnn svea = new StackVarEnvAnn (actionName, new StackVarEnv (asve.get(actionName)));
vdc.getAnns().add(svea);
addStackVarAnns2CircusAction (procname, vdc.getCircusAction(), actionName, asve, push);
}
/*else if (action instanceof SpecStmtCommand) {
//TODO
}*/
else {
ExceptionUtil.throwException("CCUpdater.addStackVarAnns2CircusAction: Please implement an \"else if\" for " + action.getClass());
}
}
else if (action instanceof PrefixingAction) {
PrefixingAction prefaction = (PrefixingAction)action;
Communication comm = prefaction.getCommunication();
CircusFieldList cfl = comm.getCircusFieldList();
StackVarEnv sve = new StackVarEnv (asve.get(actionName));
ActStackVarEnv newasve = new ActStackVarEnv (asve);
int counter = 0;
Vector <String> vars = CommunicationUtil.getCommunicationVariables (comm);
int size = vars.size();
for (int i = 0; i < size; i++) {
Field field = cfl.get(i);
if (field instanceof InputField) {
if (push)
sve.push(vars.elementAt(counter));
counter++;
}
}
StackVarEnvAnn svea = new StackVarEnvAnn (actionName, sve);
removeAllSVEAnns (comm);
comm.getAnns().add(svea);
newasve.update(actionName, sve);
addStackVarAnns2CircusAction (procname, prefaction.getCircusAction(), actionName, newasve, true);
counter = 0;
System.out.print ("");
/*for (int i = 0; i < size; i++) {
Field field = cfl.get(i);
if (field instanceof InputField) {
sve.pop(vars.elementAt(counter));
counter++;
}
}
asve.update(actionName, sve);*/
/**
* Temos que pensar melhor isso aqui...
* vamos ver como fica a AST quando a expressão dada por Marcel é compilada...
* **/
}
else if (action instanceof GuardedAction) {
GuardedAction ga = (GuardedAction)action;
Pred pred = ga.getPred();
StackVarEnvAnn svea = new StackVarEnvAnn (actionName, new StackVarEnv (asve.get(actionName)));
removeAllSVEAnns (pred);
pred.getAnns().add(svea);
addStackVarAnns2CircusAction (procname, ga.getCircusAction(), actionName, asve, push);
}
else if (action instanceof Action1) {
addStackVarAnns2CircusAction (procname, ((Action1)action).getCircusAction(), actionName, asve, push);
}
else if (action instanceof Action2) {
if (action instanceof ExtChoiceAction) {
addStackVarAnns2CircusAction (procname, ((Action2)action).getLeftAction(), actionName, asve, push);
addStackVarAnns2CircusAction (procname, ((Action2)action).getRightAction(), actionName, asve, push);
}
else if (action instanceof IntChoiceAction) {
addStackVarAnns2CircusAction (procname, ((Action2)action).getLeftAction(), actionName, asve, push);
addStackVarAnns2CircusAction (procname, ((Action2)action).getRightAction(), actionName, asve, push);
}
/*if (action instanceof ExtChoiceAction || action instanceof IntChoiceAction) {
boolean pushright = false, pushleft;
CircusAction left = ((Action2)action).getLeftAction();
CircusAction right = ((Action2)action).getRightAction();
if (left instanceof PrefixingAction || left instanceof Action1 || left instanceof CircusCommand) {
pushleft = true;
}
else {
pushleft = push;
}
addStackVarAnns2CircusAction (procname, ((Action2)action).getLeftAction(), actionName, asve, true);
addStackVarAnns2CircusAction (procname, ((Action2)action).getRightAction(), actionName, asve, true);
}*/
else if (action instanceof ParAction) {
addStackVarAnns2CircusAction (procname, ((Action2)action).getLeftAction(), actionName, asve, true);
addStackVarAnns2CircusAction (procname, ((Action2)action).getRightAction(), actionName, new ActStackVarEnv () /*asve*/, true);
}
else /*if (action instanceof SeqAction)*/ {
addStackVarAnns2CircusAction (procname, ((Action2)action).getLeftAction(), actionName, asve, true);
addStackVarAnns2CircusAction (procname, ((Action2)action).getRightAction(), actionName, asve, true);
}
System.out.print ("");
}
else if (action instanceof BasicAction) {
//Nothing to do...
}
else {
/*anything to do?*/
}
}
public void updateVariablesAtExpr (Expr expr, StackVarEnv sve, String procName) {
if (expr instanceof RefExpr) {
Factory f = new Factory ();
String varname = ((RefExpr)expr).getName().toString();
((RefExpr)expr).setName(f.createZName(varname + sve.get(varname)));
//String var = ((RefExpr)expr).getZName().toString();
//String subvar = new String (var);
//ExprUtil.replaceVarName (var, subvar + sve.get(subvar), expr, procName);
}
else if (expr instanceof SetExpr) {
ZExprList list = ((SetExpr)expr).getZExprList();
for (int i = 0; i < list.size(); i++) {
updateVariablesAtExpr (list.get(i), sve, procName);
}
}
else if (expr instanceof TupleExpr) {
ZExprList list = ((TupleExpr)expr).getZExprList();
for (int i = 0; i < list.size(); i++) {
updateVariablesAtExpr (list.get(i), sve, procName);
}
}
else if (expr instanceof ApplExpr) {
updateVariablesAtExpr (((ApplExpr)expr).getRightExpr(), sve, procName);
}
else if (expr instanceof NumExpr) {
//Do nothing...
}
else {
ExceptionUtil.throwImplementationException("updateVariablesAtExpr", expr.getClass());
}
}
public void updateExpr (Expr expr, StackVarEnv sve, String procName) {
if (expr instanceof RefExpr) {
String var = ((RefExpr)expr).getZName().toString();
String subvar = new String (var);
String finstr = subvar + sve.get(subvar);
ExprUtil.replaceVarName (var, subvar + sve.get(subvar), expr, procName);
}
else if (expr instanceof SetExpr) {
ZExprList list = ((SetExpr)expr).getZExprList();
for (int i = 0; i < list.size(); i++) {
updateExpr (list.get(i), sve, procName);
}
}
else if (expr instanceof TupleExpr) {
ZExprList list = ((TupleExpr)expr).getZExprList();
for (int i = 0; i < list.size(); i++) {
updateExpr (list.get(i), sve, procName);
}
}
else if (expr instanceof ApplExpr) {
ApplExpr ae = (ApplExpr)expr;
updateExpr (ae.getRightExpr(), sve, procName);
}
else {
//TODO DO FOR OTHER TYPES OF EXPRESSIONS
}
}
private boolean containsString (String str, Expr expr) {
if (expr instanceof RefExpr) {
//return ((RefExpr)expr).toString().equals(str);
return ((RefExpr)expr).toString().contains(str);
}
else if (expr instanceof SetExpr) {
boolean aux = false;
ZExprList list = ((SetExpr)expr).getZExprList();
for (int i = 0; i < list.size(); i++) {
aux = aux || containsString (str, list.get(i));
}
return aux;
}
else if (expr instanceof TupleExpr) {
ZExprList list = ((TupleExpr)expr).getZExprList();
boolean aux = false;
for (int i = 0; i < list.size(); i++) {
aux = aux || containsString (str, list.get(i));
}
return aux;
}
else {
return false;
//TODO DO FOR OTHER TYPES OF EXPRESSIONS
}
}
private void renameAssignmentCommand (AssignmentCommand ac, StackVarEnv sve, String processname) { //TESTADO
ZNameList leftVars = (ZNameList) ac.getAssignmentPairs().getLHS();
ZExprList rightExprs = (ZExprList) ac.getAssignmentPairs().getRHS();
Set <String> keys = sve.keySet();
int nkeys = sve.keySet().size();
for (int i = 0; i < rightExprs.size(); i++) {
for (int j = 0; j < keys.size(); j++) {
String target = (String) keys.toArray() [j];
ExprUtil.replaceVarName (target, target + sve.get(target), rightExprs.get(i), processname);
}
}
}
public void updatePred (Pred pred, StackVarEnv sve, String procName) {
if (pred instanceof MemPred) {
Expr left = ((MemPred)pred).getLeftExpr();
Expr right = ((MemPred)pred).getRightExpr();
updateExpr (left, sve, procName);
updateExpr (right, sve, procName);
}
else if (pred instanceof OrPred) {
updatePred (((OrPred)pred).getLeftPred(), sve, procName);
updatePred (((OrPred)pred).getRightPred(), sve, procName);
}
else if (pred instanceof AndPred) {
updatePred (((AndPred)pred).getLeftPred(), sve, procName);
updatePred (((AndPred)pred).getRightPred(), sve, procName);
}
else if (pred instanceof TruePred) {
//nothing to do
}
else if (pred instanceof FalsePred) {
//nothing to do
}
else if (pred instanceof NegPred) {
updatePred (((NegPred)pred).getPred(), sve, procName);
}
else {//if (pred instanceof OtherPreds) {
ExceptionUtil.throwImplementationException("CCUpdater.updatePred", pred.getClass());
//TODO IMPLEMENT FOR OTHER PRED TYPES
}
}
/*private void renameDeclarations (ZDeclList decls, StackVarEnv sve) {
}*/
public void updateCircusAction (String procname, CircusAction action, String actionName) {
/**Aqui atualizaremos as variáveis dos campos de entrada das comunicações
* e dos comandos de atribuição de acordo com
* */
if (action instanceof CircusCommand) {
if (action instanceof AssignmentCommand) {
AssignmentPairs as = ((AssignmentCommand)action).getAssignmentPairs();
StackVarEnvAnn svea = as.getAnn(StackVarEnvAnn.class);
if (svea != null)
renameAssignmentCommand ((AssignmentCommand)action, svea.getStackVarEnv(), procname);
}
else if (action instanceof IfGuardedCommand) {
CircusActionList cal = ((IfGuardedCommand) action).getGuardedActionList();
int size = cal.size();
for (int i = 0; i < size; i++) {
GuardedAction ga = (GuardedAction) cal.get(i);
updateCircusAction (procname, ga, actionName);
}
}
else if (action instanceof VarDeclCommand) {
VarDeclCommand vdc = ((VarDeclCommand)action);
updateCircusAction (procname, vdc.getCircusAction(), actionName);
}
else {
ExceptionUtil.throwImplementationException("CCUpdater.updateCircusAction", action.getClass());
}
}
else if (action instanceof PrefixingAction) {
PrefixingAction prefaction = (PrefixingAction)action;
Communication comm = prefaction.getCommunication();
CircusFieldList cfl = comm.getCircusFieldList();
StackVarEnvAnn svea = comm.getAnn(StackVarEnvAnn.class);
StackVarEnv sve = new StackVarEnv ();
if (svea != null)
sve = svea.getStackVarEnv ();
renameCommunicationVariables (comm, sve, procname);
updateCircusAction (procname, ((PrefixingAction)action).getCircusAction(), actionName);
System.out.print ("");
}
else if (action instanceof GuardedAction) {
GuardedAction ga = (GuardedAction)action;
Pred pred = ga.getPred();
StackVarEnvAnn svea = pred.getAnn(StackVarEnvAnn.class);
StackVarEnv sve = new StackVarEnv ();
if (svea != null) {
sve = svea.getStackVarEnv();
}
updatePred (pred, sve, procname);
updateCircusAction (procname, ga.getCircusAction(), actionName);
}
else if (action instanceof Action1) {
updateCircusAction (procname, ((Action1)action).getCircusAction(), actionName);
}
else if (action instanceof Action2) {
if (action instanceof ExtChoiceAction) {
updateCircusAction (procname, ((ExtChoiceAction)action).getLeftAction(), actionName);
updateCircusAction (procname, ((ExtChoiceAction)action).getRightAction(), actionName);
}
else if (action instanceof IntChoiceAction) {
updateCircusAction (procname, ((IntChoiceAction)action).getLeftAction(), actionName);
updateCircusAction (procname, ((IntChoiceAction)action).getRightAction(), actionName);
}
else {
updateCircusAction (procname, ((Action2)action).getLeftAction(), actionName);
updateCircusAction (procname, ((Action2)action).getRightAction(), actionName);
}
System.out.print ("");
}
else if (action instanceof BasicAction) {
//Nothing to do...
}
else if (action instanceof CallAction) {
}
else {
ExceptionUtil.throwImplementationException("CCUpdater.updateCircusAction", action.getClass());
}
}
private void renameCommunicationVariables (Communication comm, StackVarEnv sve, String procName) {
Factory f = new Factory ();
CircusFieldList cfl = comm.getCircusFieldList();
int sizecfl = cfl.size();
for (int i = 0; i < sizecfl; i++) {
Field field = cfl.get(i);
if (field instanceof InputField) {
InputField inpfield = (InputField)field;
String varname = inpfield.getVariableName().toString();
if (sve.containsKey(varname)) {
if (!(sve.get(varname).equals(""))) {
inpfield.setVariableName(f.createZName(varname + sve.get(varname)));
}
}
}
else if (field instanceof DotField) {
Expr expr = ((DotField)field).getExpr();
f = new Factory ();
updateVariablesAtExpr (expr, sve, procName);
}
}
}
}