package jcircus.complexcomms;
import java.util.Vector;
import jcircus.complementaryenvs.ActStackVarEnv;
import jcircus.complementaryenvs.StackVarEnv;
import jcircus.newutil.ProcessUtil;
import jcircus.newutil.PrinterUtil;
import jcircus.parallelism.RenamedVarAnn;
import net.sourceforge.czt.circus.ast.Action1;
import net.sourceforge.czt.circus.ast.Action2;
import net.sourceforge.czt.circus.ast.ActionIte;
import net.sourceforge.czt.circus.ast.ActionPara;
import net.sourceforge.czt.circus.ast.AssignmentCommand;
import net.sourceforge.czt.circus.ast.BasicProcess;
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.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.SpecStmtCommand;
import net.sourceforge.czt.circus.ast.VarDeclCommand;
import net.sourceforge.czt.circus.util.Factory;
import net.sourceforge.czt.z.ast.ApplExpr;
import net.sourceforge.czt.z.ast.Expr;
import net.sourceforge.czt.z.ast.MemPred;
import net.sourceforge.czt.z.ast.NarrSect;
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.TupleExpr;
import net.sourceforge.czt.z.ast.ZExprList;
import net.sourceforge.czt.z.ast.ZNameList;
import net.sourceforge.czt.z.ast.ZParaList;
import net.sourceforge.czt.z.ast.ZSect;
import java.util.Set;
import javax.swing.JOptionPane;
/**@author: Samuel Barrocas
* Performs the renaming of the repeated variables of communication input fields
* **/
public class ComplexCommUpdater {
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;
//ParallelismPrinter.printProcessPara(processPara);
updateProcessPara (processPara, asve);
System.out.println ("Depois da atualização");
PrinterUtil.printProcessPara (processPara, spec);
}
}
}
public void updateProcessPara (ProcessPara processPara, ActStackVarEnv asve) {
CircusProcess process = processPara.getCircusProcess();
String procname = processPara.getZName().toString();
updateCircusProcess (procname, process, asve);
}
public void updateCircusProcess (String procname, CircusProcess process, ActStackVarEnv asve) {
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"))
updateCircusAction (procname, actionPara.getCircusAction(), actionPara.getName().toString(), asve, actionPara.getCircusAction());
}
}
}
else if (process instanceof ParamProcess) {
updateCircusProcess (procname, ((ParamProcess) process).getCircusBasicProcess(), asve);
}
else if (process instanceof Process1) {
updateCircusProcess (procname, ((Process1)process).getCircusProcess (), asve);
}
else if (process instanceof Process2) {
updateCircusProcess (procname, ((Process2)process).getLeftProcess (), asve);
updateCircusProcess (procname, ((Process2)process).getRightProcess (), asve);
}
else {
/*anything else?*/
}
}
private Vector <String> getCommunicationVariables (Communication comm) {
CircusFieldList cfl = comm.getCircusFieldList();
int sizecfl = cfl.size();
Vector <String> vec = new Vector <String> ();
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();
vec.addElement(varname);
}
}
return vec;
}
private void renameDotFieldVariables (Communication comm, StackVarEnv sve, String procName) {
/**
* Tenho dúvidas se esse troço vai funcionar...
* só esperando completar a implementação para checar
* */
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 DotField) {
Expr expr = ((DotField)field).getExpr();
f = new Factory ();
updateVariablesAtExpr (expr, sve, procName);
/*if (expr instanceof RefExpr) {
String varname = ((RefExpr)expr).getName().toString();
((RefExpr)expr).setName(f.createZName(varname + sve.get(varname)));
}*/
}
}
}
private void renameCommunicationVariables (Communication comm, StackVarEnv sve) {
/**
* Tenho dúvidas se esse troço vai funcionar...
* só esperando completar a implementação para checar
* */
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 (inpfield.getAnn(RenamedVarAnn.class) != null
&& isNumeral (varname.substring(varname.length() - 1))
) {
varname = varname.substring(0, varname.length() - 1);
}
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 ();
if (expr instanceof RefExpr) {
String varname = ((RefExpr)expr).getName().toString();
((RefExpr)expr).setName(f.createZName(varname + sve.get(varname)));
}
}
}
}
private void renameAssignmentCommand (AssignmentCommand ac, StackVarEnv sve) { //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];
replaceVarName (target, target + sve.get(target), rightExprs.get(i));
}
}
}
private void replaceVarName (String targetVar, String newName, Expr expr) {
Factory f = new Factory ();
if (expr instanceof RefExpr) {
String exprName = ((RefExpr)expr).getName().toString();
if (exprName.equals(targetVar)) {
((RefExpr)expr).setName(f.createZName(newName));
}
}
else if (expr instanceof ApplExpr) {
Expr left = ((ApplExpr)expr).getLeftExpr();
Expr right = ((ApplExpr)expr).getRightExpr();
replaceVarName (targetVar, newName, left);
replaceVarName (targetVar, newName, right);
}
else if (expr instanceof TupleExpr) {
ZExprList exprlist = ((TupleExpr)expr).getZExprList();
int size = exprlist.size();
for (int i = 0; i < size; i++) {
replaceVarName (targetVar, newName, exprlist.get(i));
}
}
}
private boolean isNumeral (String str) {
return str.equals("0") || str.equals("1") || str.equals("2") || str.equals("3") || str.equals("4") ||
str.equals("5") || str.equals("6") || str.equals("7") || str.equals("8") || str.equals("9");
}
public void updateVariablesAtExpr (Expr expr, StackVarEnv sve, String procName) {
if (expr instanceof RefExpr) {
String var = ((RefExpr)expr).getZName().toString();
String subvar = new String (var);
if (expr.getAnn(RenamedVarAnn.class) != null && var.length() > 1 && isNumeral (var.substring(var.length() - 1))) {
subvar = subvar.substring(0, var.length() - 1);
}
replaceVarName (var, subvar + sve.get(subvar), expr);
if (expr.getAnn(RenamedVarAnn.class) == null) {
expr.getAnns().add(new RenamedVarAnn ());
}
}
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 {
//TODO DO FOR OTHER TYPES OF EXPRESSIONS
}
}
public void updateExpr (Expr expr, StackVarEnv sve, String procName) {
if (expr instanceof RefExpr) {
String var = ((RefExpr)expr).getZName().toString();
String subvar = new String (var);
if (expr.getAnn(RenamedVarAnn.class) != null && var.length() > 1 && isNumeral (var.substring(var.length() - 1))) {
subvar = subvar.substring(0, var.length() - 1);
}
String finstr = subvar + sve.get(subvar);
replaceVarName (var, subvar + sve.get(subvar), expr);
if (expr.getAnn(RenamedVarAnn.class) == null) {
expr.getAnns().add(new RenamedVarAnn ());
}
}
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 {
//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
}
}
public void updateVariablesAtPred (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 OtherPreds)*/ {
//TODO IMPLEMENT FOR OTHER PRED TYPES
}
}
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 OtherPreds) {
//TODO IMPLEMENT FOR OTHER PRED TYPES
}*/
}
public void updateCircusAction (String procname, CircusAction action, String actionName, ActStackVarEnv asve, CircusAction motherAction) {
updateCircusAction (procname, action, actionName, asve, false, motherAction);
}
public void updateVariableNames (String procname, CircusAction action, String actionName, ActStackVarEnv asve) {
/**
* Atualiza os nomes de variáveis...
* -> Este método só não atualiza quando os nomes estiverem em um InputField
* -> Este método não altera o conteúdo de ActStackVarEnv, apenas atualiza os valores das variáveis
* */
if (action instanceof CircusCommand) {
if (action instanceof AssignmentCommand) {
renameAssignmentCommand ((AssignmentCommand)action, asve.get(actionName));
}
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();
updateVariablesAtPred (pred, asve.get(actionName), procname);
updateVariableNames (procname, ga, actionName, asve);
}
}
else if (action instanceof VarDeclCommand) { //TODO NAO TESTADO
VarDeclCommand vdc = ((VarDeclCommand)action);
updateVariableNames (procname, vdc.getCircusAction(), actionName, asve);
}
}
else if (action instanceof PrefixingAction) {
PrefixingAction prefaction = (PrefixingAction)action;
Communication comm = prefaction.getCommunication();
CircusFieldList cfl = comm.getCircusFieldList();
StackVarEnv sve = asve.get(actionName);
Vector <String> vars = getCommunicationVariables (comm);
int size = vars.size();
for (int i = 0; i < size; i++) {
Field field = cfl.get(i);
/*if (field.getAnn(RenamedVarAnn.class) == null && !choice)
sve.push(vars.elementAt(i));*/
}
renameDotFieldVariables (comm, sve, procname);
for (int i = 0; i < size; i++) {
Field field = cfl.get(i);
if (field.getAnn(RenamedVarAnn.class) == null)
field.getAnns().add(new RenamedVarAnn ());
}
//asve.update(actionName, sve);
updateVariableNames (procname, ((PrefixingAction)action).getCircusAction(), actionName, asve);
/*for (int i = 0; i < size; i++) {
Field field = cfl.get(i);
if (field.getAnn(RenamedVarAnn.class) != null) {
field.getAnns().remove(RenamedVarAnn.class);
}
}*/
}
else if (action instanceof Action2) {
CircusAction leftaction = ((Action2)action).getLeftAction();
CircusAction rightaction = ((Action2)action).getRightAction();
updateVariableNames (procname, leftaction, actionName, asve);
updateVariableNames (procname, rightaction, actionName, asve);
}
else if (action instanceof Action1 && !(action instanceof PrefixingAction)) {
updateVariableNames (procname, ((Action1)action).getCircusAction(), actionName, asve);
}
/*else if (action instanceof CallAction) {
}*/
}
public void updateCircusAction (String procname, CircusAction action, String actionName, ActStackVarEnv asve, boolean choice, CircusAction motherAction) {
/**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) {
/**Todas as subinterfaces de CircusCommand são estas abaixo*/
if (action instanceof AssignmentCommand) {
renameAssignmentCommand ((AssignmentCommand)action, asve.get(actionName));
}
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();
updatePred (pred, asve.get(actionName), procname);
updateCircusAction (procname, ga, actionName, asve, choice, motherAction);
}
}
else if (action instanceof VarDeclCommand) { //TODO NAO TESTADO
VarDeclCommand vdc = ((VarDeclCommand)action);
updateCircusAction (procname, vdc.getCircusAction(), actionName, asve, choice, motherAction);
}
else if (action instanceof SpecStmtCommand) {
/*something to do here?*/
//TODO
}
}
else if (action instanceof PrefixingAction) {
PrefixingAction prefaction = (PrefixingAction)action;
Communication comm = prefaction.getCommunication();
CircusFieldList cfl = comm.getCircusFieldList();
StackVarEnv sve = asve.get(actionName);
Vector <String> vars = getCommunicationVariables (comm);
int size = vars.size();
int counter = 0;
for (int i = 0; i < size; i++) {
Field field = cfl.get(i);
if (//field.getAnn(RenamedVarAnn.class) != null &&
field instanceof InputField
&& !choice
) {
if (vars.elementAt(counter).contains("ident")) {
System.out.print ("");
}
sve.push(vars.elementAt(counter));
counter++;
}
}
renameCommunicationVariables (comm, sve);
for (int i = 0; i < size; i++) {
Field field = cfl.get(i);
if (field.getAnn(RenamedVarAnn.class) == null
&& !choice
)
field.getAnns().add(new RenamedVarAnn ());
}
asve.update(actionName, sve);
if (procname.equals("Cassino")) {
System.out.print ("");
}
updateVariableNames (procname, motherAction, actionName, asve);
updateCircusAction (procname, ((PrefixingAction)action).getCircusAction(), actionName, asve, choice, motherAction);
counter = 0;
/*for (int i = 0; i < size; i++) {
Field field = cfl.get(i);
if (//field.getAnn(RenamedVarAnn.class) != null &&
field instanceof InputField
//&& !choice
) {
sve.pop(vars.elementAt(counter));
field.getAnns().remove(RenamedVarAnn.class);
counter++;
}
}*/
//asve.update(actionName, sve);
//updateVariableNames (procname, ((PrefixingAction)action).getCircusAction(), actionName, asve);
//updateCircusAction (procname, ((PrefixingAction)action).getCircusAction(), actionName, asve, choice);
System.out.print ("");
/**
* Temos que pensar melhor isso aqui...
* vamos ver como fica a AST quando a expressão dada por Marcel é compilada...
* **/
}
else if (action instanceof Action1) {
updateCircusAction (procname, ((Action1)action).getCircusAction(), actionName, asve, choice, motherAction);
}
else if (action instanceof Action2) {
if (action instanceof ExtChoiceAction) {
updateCircusAction (procname, ((ExtChoiceAction)action).getLeftAction(), actionName, asve, true, motherAction);
updateCircusAction (procname, ((ExtChoiceAction)action).getRightAction(), actionName, asve, true, motherAction);
}
else if (action instanceof IntChoiceAction) {
updateCircusAction (procname, ((IntChoiceAction)action).getLeftAction(), actionName, asve, true, motherAction);
updateCircusAction (procname, ((IntChoiceAction)action).getRightAction(), actionName, asve, true, motherAction);
}
else {
updateCircusAction (procname, ((Action2)action).getLeftAction(), actionName, asve, choice, motherAction);
updateCircusAction (procname, ((Action2)action).getRightAction(), actionName, asve, choice, motherAction);
}
System.out.print ("");
}
/*else if (action instanceof BasicAction) {
}*/
else {
/*anything to do?*/
}
}
}