package jcircus.util;
import java.io.File;
import java.io.FileWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import javax.swing.JOptionPane;
import jcircus.complementaryenvs.CallProc2ChannelSetEnv;
import jcircus.complementaryenvs.ChanDimEnv;
import jcircus.complementaryenvs.PId2PNameEnv;
import jcircus.complementaryenvs.ProcProcessParaEnv;
import jcircus.environment.ProcChanUseEnv;
import jcircus.environment.ChanInfoEnv;
import jcircus.environment.ProcChanEnv;
import jcircus.environment.NameTypeEnv;
import jcircus.environment.TypeList;
import jcircus.exceptions.InvalidFormatCommException;
import jcircus.exceptions.runtime.InvalidSubTypeException;
import jcircus.exceptions.JCircusException;
import jcircus.exceptions.runtime.NoChannelMSEnvAnnotationException;
import jcircus.exceptions.runtime.NoCircusTypeAnnotationException;
import jcircus.exceptions.runtime.NoIdCircusProcessAnnException;
import jcircus.exceptions.runtime.NoNameTypeAnnotationException;
import jcircus.exceptions.runtime.NoProcChanEnvAnnotationException;
import jcircus.exceptions.runtime.NoSignatureAnnException;
import jcircus.exceptions.runtime.VisitorException;
import jcircus.util.annotations.HideOkAnn;
import jcircus.util.annotations.IdCircusProcessAnn;
import net.sourceforge.czt.base.ast.ListTerm;
import net.sourceforge.czt.base.ast.Term;//A; //troquei TermA por Term
import net.sourceforge.czt.base.impl.ListTermImpl;
import net.sourceforge.czt.circus.ast.Action2;
import net.sourceforge.czt.circus.ast.CircusAction;
import net.sourceforge.czt.circus.ast.CircusFieldList;
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.FieldList;
import net.sourceforge.czt.circus.ast.HideProcess;
import net.sourceforge.czt.circus.ast.InputField;
import net.sourceforge.czt.circus.ast.IntChoiceAction;
//import net.sourceforge.czt.circus.ast.OutputField;
/*O de cima substitu�do por esse: */import net.sourceforge.czt.circus.ast.OutputFieldAnn;
import net.sourceforge.czt.circus.impl.CircusFieldListImpl;
import net.sourceforge.czt.z.ast.Decl;
import net.sourceforge.czt.z.ast.Expr;
import net.sourceforge.czt.z.ast.ExprList;
import net.sourceforge.czt.z.ast.Name;
import net.sourceforge.czt.z.ast.NameList;
import net.sourceforge.czt.z.ast.ProdExpr;
import net.sourceforge.czt.z.ast.RefExpr;
import net.sourceforge.czt.z.ast.ZDeclList;
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.RefName; //POR ENQUANTO, SEM SUBSTITUTO
import net.sourceforge.czt.z.ast.Signature;
import net.sourceforge.czt.z.ast.VarDecl;
import net.sourceforge.czt.circus.util.Factory;
import net.sourceforge.czt.z.ast./*DeclName*/ZName;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
/**
* Util.java
*
* Contains utility methods.
*
* @author Angela Freitas
*
*/
public class Util {
public static Factory _factory = new Factory();
/** **************************************************************************************************************
* Communication
* ***************************************************************************************************************
*/
/*Metodo abaixo definido por Samuel para verificar se um campo � "OutputField*/
public static boolean hasOutputFieldAnn (Field field) {
if (!(field instanceof DotField)) {
return false;
}
for (int i = 0; i < field.getAnns().size(); i++) {
if (field.getAnns().get(0) instanceof OutputFieldAnn) {
return true;
}
}
return false;
}
/*Metodo acima definido por Samuel para verificar se um campo � "OutputField*/
/**
* Classifies a communication according to its use (ChanUse -
* Input, Output or Undefined).
*/
public static ChanUse getChanUseClassification(Communication communication)
throws InvalidFormatCommException {
ChanUse r = null;
/*RefName*/ZName chanName = communication./*getChanName()*/getChannelExpr().getZName();
/*ListTerm <FieldList>*/CircusFieldListImpl fields = (CircusFieldListImpl) /*(ListTerm)*/ /*Esse cast n�o tava antes*/ communication.getCircusFieldList()/*getChanFields()*/;
if (fields.size() == 0) {
// Single sync channel
r = ChanUse.Undefined;
} else {
Field field;
if (fields.size() == 1) {
field = (Field) fields.get(0);
} else {
for (int i = 0; i < fields.size() - 2; i++) {
field = (Field) fields.get(i);
if (!(field instanceof DotField))
throw new InvalidFormatCommException();
}
// Get the last parameter
field = (Field) fields.get(fields.size() - 1);
}
// Validate the value of field
assert(field instanceof InputField || /*field instanceof OutputField ||*/
field instanceof DotField): "field is " + field.getClass();
if (field instanceof InputField) {
r = ChanUse.Input;
//} else if (field instanceof OutputField) { //Angela's
} else if (field instanceof DotField &&
hasOutputFieldAnn (field)
/* communication.getCommPattern().toString().equals ("Output") //Sam's
&& communication.getCommUsage().toString().equals ("Normal")
*/
) { //Sam's
r = ChanUse.Output;
} else if (field instanceof DotField &&
!hasOutputFieldAnn (field)
/*communication.getCommPattern().toString().equals ("Output") //Sam's
&& communication.getCommUsage().toString().equals ("Generic")
*/
) {
r = ChanUse.Undefined;
}
}
return r;
}
/**
* Classifies a communication regarding synchronisation (ChanSync - S or C).
*/
public static ChanSync getChanSyncClassification(Communication communication)
throws InvalidFormatCommException {
ChanSync r = null;
/*RefName*/ZName chanName = communication./*getChanName()*/getChannelExpr().getZName();
/*ListTerm*/CircusFieldListImpl fields = /*(ListTerm)*/(CircusFieldListImpl) communication./*getChanFields()*/getFieldList();
if (fields.size() == 0) {
// Single sync channel
r = ChanSync.S;
} else {
Field field;
if (fields.size() == 1) {
field = (Field) fields.get(0);
} else {
for (int i = 0; i < fields.size() - 2; i++) {
field = (Field) fields.get(i);
if (!(field instanceof DotField))
throw new InvalidFormatCommException();
}
// Gets the last parameter
field = (Field) fields.get(fields.size() - 1);
}
// Validate the value of field
assert(field instanceof InputField || /*field instanceof OutputField ||*/
field instanceof DotField): "field is " + field.getClass();
if (field instanceof InputField) {
r = ChanSync.C;
//} else if (field instanceof OutputField) { //Angela's
} else if (field instanceof DotField
&& hasOutputFieldAnn (field)
/*&& communication.getCommPattern().toString().equals ("Output")
&& communication.getCommUsage().toString().equals ("Normal")
*/
) {
r = ChanSync.C;
} else if (field instanceof DotField
&& !hasOutputFieldAnn (field)
/* && communication.getCommPattern().toString().equals ("Output")
&& communication.getCommUsage().toString().equals ("Generic")
*/
) {
r = ChanSync.S;
}
}
return r;
}
/** **************************************************************************************************************
* RenameVars
* ***************************************************************************************************************
*/
/**
* Rename variables in Java code.
*
*
public static String renameVars(String code, String newVar, String oldVar)
throws Exception {
List<String> newVars = new ArrayList<String>();
newVars.add(newVar);
List<String> oldVars = new ArrayList<String>();
oldVars.add(oldVar);
return Util.renameVars(code, newVars, oldVars);
}*/
/**
* Rename variables in Java code.
*/
public static String renameVars(String code, List/*<String or Name>*/ newVars,
List/*<String or Name>*/ oldVars) throws InvalidSubTypeException {
String newCode = "";
StringTokenizer st = new StringTokenizer(code, "!.;,(){} \t\n\r\f", true);
String token;
while (st.hasMoreTokens()) {
token = st.nextToken();
int index = contains(oldVars, token);
if (index != -1) {
Object object = newVars.get(index);
// Validate the type of object
assert(object instanceof String || object instanceof Name):
"object is " + object.getClass();
if (object instanceof String) {
// visitIntChoiceActionIte, visitMuAction, visitParAction, visitSeqActionIte
token = (String) object;
} else if (object instanceof Name) {
// visitRenameProcess
token = ((Name) object).toString();
}
}
newCode = newCode + token;
}
return newCode + "/*Util.renameVars*/";
}
/**
* Returns the position of a string in a list. Returns -1 if it is not
* in the list.
*/
private static int contains(List/*<Name or String>*/ list, String token) {
int r = -1;
for (int i = 0; i < list.size(); i++) {
Object obj = list.get(i);
if (obj.toString().equals(token)) {
r = i;
break;
}
}
return r;
}
/** **************************************************************************************************************
* Annotation
* ***************************************************************************************************************
*/
/**
* NameType
*
* @param termA
* @param nameType
*/
public static void addNameTypeAnn(Term/*TermA*/ termA, NameType nameType) {
termA.getAnns().add(nameType);
}
/**
* NameType
*
* @param termA
* @param nameType
*/
public static NameType getAndRemoveNameTypeAnn(Term/*TermA*/ termA)
throws NoNameTypeAnnotationException {
// Get
NameType nameType = Util.getNameTypeAnn(termA);
// Remove
termA.getAnns().remove(nameType);
return nameType;
}
/**
* NameType
*
* @param termA
* @param nameType
*/
public static NameType getNameTypeAnn(Term/*TermA*/ termA)
throws NoNameTypeAnnotationException {
// Get
//NameType nameType = (NameType) termA.getAnn(NameType.class);
NameType nameType = (NameType) termA.getAnn(NameType.class);
// Checks if it is null
if (nameType == null) //Comentado por Samuel
throw new NoNameTypeAnnotationException(); //Comentado por Samuel
System.out.println ("Sem NoNameTypeAnnException");
return nameType; //Angela's, depois descomentar!!!!!!!!!
//return NameType.GlobalConstant; //Sam's
}
/**
* ChannelMSEnv
*/
public static void addChannelMSEnvAnn(Term/*TermA*/ termA, ChanInfoEnv channelMSEnv) {
termA.getAnns().add(channelMSEnv);
}
/*
* ChannelMSEnv
*/
public static ChanInfoEnv getChannelMSEnvAnn(Term/*TermA*/ termA)
throws NoChannelMSEnvAnnotationException {
// Get
ChanInfoEnv channelMSEnv = (ChanInfoEnv) termA.getAnn(ChanInfoEnv.class);
// Checks if it is null
if (channelMSEnv == null)
throw new NoChannelMSEnvAnnotationException();
return channelMSEnv;
}
/**
* CircusType
*/
public static void addCircusTypeAnn(Term/*TermA*/ termA, CircusType circusType) {
termA.getAnns().add(circusType);
}
/**
* CircusType
*/
public static CircusType getCircusTypeAnn(Term/*TermA*/ termA)
throws NoCircusTypeAnnotationException {
CircusType circusType = (CircusType) termA.getAnn(CircusType.class);
if (circusType == null)
throw new NoCircusTypeAnnotationException();
return circusType;//Angela's
}
/**
* ProcessChannelEnvironment
*/
public static void addProcChanEnvAnn(Term/*TermA*/ termA, ProcChanEnv procChanEnv) {
termA.getAnns().add(procChanEnv);
}
public static ProcChanEnv getProcChanEnvAnn(Term/*TermA*/ termA)
throws NoProcChanEnvAnnotationException {
// Get
ProcChanEnv procChanEnv = (ProcChanEnv) termA.getAnn(ProcChanEnv.class);
// Checks if it is null
if (procChanEnv == null)
throw new NoProcChanEnvAnnotationException();
return procChanEnv;
}
/**
* ProcessChannelEnvironment
*/
public static void addNameTypeEnvAnn(Term/*TermA*/ termA, NameTypeEnv nameTypeEnv) {
termA.getAnns().add(nameTypeEnv);
}
/**
* IdCircusProcess
*/
public static void addIdCircusProcessAnn(Term/*TermA*/ termA, IdCircusProcessAnn ann) {
if (ann.getId().intValue() == 1 || ann.getId().intValue() == 2) {
System.out.print ("");
}
termA.getAnns().add(ann);
System.out.print("");
}
public static IdCircusProcessAnn getIdCircusProcessAnn(Term/*TermA*/ termA)
throws NoIdCircusProcessAnnException {
// Get
IdCircusProcessAnn ann = (IdCircusProcessAnn)
termA.getAnn(IdCircusProcessAnn.class);
// Checks if it is null
if (ann == null) //comentado por Sam's
throw new NoIdCircusProcessAnnException(); //Comentado por Sam's
return ann;
}
/**
* Adds a HideOkAnn.
*/
public static void addHideOkAnn (HideProcess hideProcess) {
hideProcess.getAnns().add(new HideOkAnn());
}
/**
* Returns the HideOkAnn; null if there is none.
*/
public static HideOkAnn getHideOkAnn (HideProcess hideProcess) {
return (HideOkAnn) hideProcess.getAnn(HideOkAnn.class);
}
/*
* Leo's method.
*
publicvoid addLocAnn(TermA termA, int line, int column)
{
LocAnn locAnn = fCF.createLocAnn(fFileName, line + 1, column + 1);
LocAnn existingAnn = (LocAnn) termA.getAnn(LocAnn.class);
if (existingAnn != null) {
assert locAnn.equals(existingAnn);
return;
}
termA.getAnns().add(locAnn);
}
*/
/** **************************************************************************************************************
* External and Internal Choice
* ***************************************************************************************************************
*/
/**
* This method return all the actions that take part in an internal or
* external choice in the first level. Basically it transforms the binary
* operation into an n-ary operation.
*
*/
public static List<CircusAction> getActions(CircusAction circusAction, int op) {
// Validates the operation code
assert(op == Constants.OP_EXTCHOICE || op == Constants.OP_INTCHOICE):
"Invalid operation code: " + op;
List<CircusAction> result = new ArrayList<CircusAction>();
if ((op == Constants.OP_EXTCHOICE && circusAction instanceof ExtChoiceAction)
|| (op == Constants.OP_INTCHOICE && circusAction instanceof IntChoiceAction)) {
result.addAll(getActions(
((Action2) circusAction).getLeftAction(), op));
result.addAll(getActions(
((Action2) circusAction).getRightAction(), op));
} else if (op == Constants.OP_EXTCHOICE ||
op == Constants.OP_INTCHOICE) {
// Base case
result.add(circusAction);
}
return result;
}
/** **************************************************************************************************************
* Synchronization Channels
* ***************************************************************************************************************
*/
/**
* Returns a string of '[]', as many times as the dimension of the channel.
*/
public static String arrayDim(CircusType channelType, ChanSync sc, int gap, boolean useBarriers) {
String r = "";
int dim = Util.dim(channelType, sc, useBarriers);
return arrayDim(dim - gap);
}
/**
* Returns a string of '[]', 'dim' times.
*/
private static String arrayDim(int dim) {
String r = "";
for (int i = 0; i < dim; i++) {
r = r + "[]";
}
return r;
}
/**
* Returns the dimension of the channel. Takes into account:
* - the number of generic parameters
* - the number of Fields
* - if it is S or C
*/
private static int dim(CircusType channelType, ChanSync sc, boolean useBarriers) {
//int dim;
//List/*<Name>*/ genericParameters = channelType.getGenericParameters(); //Aqui � da �ngela
List genericParameters = channelType.getGenericParameters(); //substitu� o de cima por esse aqui
List<Expr> types;
//ExprList types;
if (channelType.isSyncType()) {
// Single synchronization
types = new ArrayList(); //substitui o de cima por esse aqui
types.add(Util.createSyncExpression()); //Original, da Angela!!!!
} else {
Expr typeExpression = channelType.getExpression();
if (typeExpression instanceof ProdExpr) {
types = (List<Expr>) ((ProdExpr) typeExpression).getExprList();
System.out.print ("");
} else {
types = new ArrayList();
types.add(typeExpression);
}
}
return dim(genericParameters, types, sc, useBarriers); //Original, da �ngela
}
/**
* Returns the dimension of the channel. Takes into account:
* - the number of generic parameters (genTypes)
* - the number of Fields (types)
* - if it is S or C (sc)
*/
//private static int dim(List/*Name*/ genTypes, List/*Expr*/ types, ChanSync sc) { //Original, da �ngela
/*private static int dim (List genTypes, List types, ChanSync sc) {
return dim (genTypes, types, sc, false);
}*/
private static int dim(List genTypes, List types, ChanSync sc, boolean useBarriers) {
int dim;
if (types.size() == 1 && types.get(0).equals(Util.createSyncExpression())) {
dim = 0;
} else if (sc.equals(ChanSync.C)) {
//if (!useBarriers)
dim = types.size() - 1;
//else dim = types.size();
} else {
dim = types.size();
}
if (genTypes != null) {
// It is a generic type
dim = dim + genTypes.size();
}
return dim;
}
/**
*
public static String instArray(CircusType circusTypeChannel,
ChanSync syncType, TypeList typeList) {
String code = "";
List<Name> genPars = new ArrayList();
List<Expr> types;
if (circusTypeChannel.isGeneric()) {
genPars = circusTypeChannel.getGenericParameters();
}
if (circusTypeChannel.isSyncType()) {
types = new ArrayList();
types.add(Util.createSyncExpression());
} else {
Expr typeExpression = circusTypeChannel.getExpression();
if (typeExpression instanceof ProdExpr) {
types = ((ProdExpr) typeExpression).getExpr();
} else {
types = new ArrayList();
types.add(typeExpression);
}
}
List<String> listOfTypes = new ArrayList<String>();
Iterator iterator = typeList.iterator();
while (iterator.hasNext()) {
CircusType circusType = (CircusType) iterator.next();
listOfTypes.add(circusType.getJavaCircusTypeName());
}
return code;
}*/
/**
* Metodo replace: simplificar, considerar lista de tipos
* podendo conter apenas free types.
*
* genTypes: List of Name
* types: List of String
* typeList: List of String
*
*/
private static String instArray(List/*<Name>*/ genTypes,
List/*<Expr>*/ types, ChanSync sc, List/*String*/ typeList, boolean useBarriers) {
String code = "";
int dim = dim(genTypes, types, sc, useBarriers);
if (genTypes.size() > 0) {
//code = "new Any2OneChannel " + arrayDim(dim) + "{ " +
//genericInst(genTypes, types, sc, typeList, typeList) + " }"; //Angela's, JCSP antigo
code = "new Any2OneChannel " + arrayDim(dim) + "{ " +
genericInst(genTypes, types, sc, typeList, typeList, useBarriers) + " }"; //TODO : REFAZER ESTE TRECHO AQUI!!! (By Sam)
} else {
code = instArraySync(types, sc, useBarriers);
}
return code;
}
/**
*
*/
private static String genericInst(List/*<Name>*/ genTypes, List/*<String>*/ types,
ChanSync sc, List/*<String>*/ typeList, List/*<String>*/ typeList2, boolean useBarriers) {
String code = "";
Name genPar = (Name) genTypes.get(0);
String type = (String) typeList2.get(0);
if (typeList2.size() == 1) {
code = instArray(genTypes.subList(1, genTypes.size()),
replace(genPar, type, types), sc, typeList, useBarriers);
} else {
code = instArray(
genTypes.subList(1, genTypes.size()), replace(genPar, type, types), sc, typeList, useBarriers)
+ ", " + genericInst(genTypes, types, sc, typeList, typeList2.subList(1, typeList2.size()), useBarriers);
}
return code;
}
/**
*
*/
private static String instArraySync(List/*<String>*/ types, ChanSync sc, boolean useBarriers) {
String code = "";
int dim = dim(new ArrayList(), types, sc, useBarriers);
String type = (String) types.get(0);
if (types.size() == 1) {
code = baseCase(type, sc);
} else {
int n = 0; //... TODO
//code = " new Any2OneChannel " + arrayDim(dim) + "{ " +
//typeInstSync(types, sc, n) + "} "; //Angela's, JCSP antigo
code = " new Any2OneChannel " + arrayDim(dim) + "{ " +
typeInstSync(types, sc, n, useBarriers) + "} "; //TODO: Refazer este aqui
}
return code;
}
/**
* Invokes the method instArray for the other types
*
*
* @param types
* @param sc
* @param n
* @return
*/
private static String typeInstSync(List/*String*/ types, ChanSync sc, int n, boolean useBarriers) {
String code = "";
if (n == 1) {
code = instArraySync(types.subList(1, types.size()), sc, useBarriers);
} else {
code = instArraySync(types.subList(1, types.size()), sc, useBarriers) + ", " +
typeInstSync(types, sc, n - 1, useBarriers);
}
return code;
}
/**
* Replace every reference to 'genPar' by 't' in 'types'.
*
* @param genPar
* @param t
* @param types
* @return
*/
private static List<String> replace(Name genPar, String t, List/*<String>*/ types) {
List<String> newList = new ArrayList<String>();
Iterator iterator = types.iterator();
while(iterator.hasNext()) {
newList.add(new String(t));
}
return newList;
}
/**
* Returns Java Code, the instantiation of a Channel.
*
* sc = C -> instantiates a single Any2OneChannel
* sc = S -> instantiates an array of channels with the number of elements
* equals to the number of possible values of the type
*
* @param type
* @param sc
* @return
*/
private static String baseCase(String type, ChanSync sc) {
String code = "";
// TODO: Initialize 'n' properly
int n = 0;
if (sc.equals(ChanSync.C)) {
//code = "new Any2OneChannel()"; //Angela's, JCSP antigo
code = "org.jcsp.lang.Channel.any2one ()"; //Sam's, JCSP novo
} else {
//code = "Any2OneChannel.create(" + n + ")"; //Angela's, JCSP antigo
code = "org.jcsp.lang.Channel.any2oneArray (" + n + ")"; //Sam's, JCSP novo
}
return code;
}
/**
* Usado em dim(), instArray(), CircusType.createSyncType()
* @return
*/
public static Expr createSyncExpression() {
Factory factory = new Factory();
//return factory.createRefExpr(factory.createRefName(CircusType.SYNC_CHANNEL)); //Original, da �ngela
return factory.createRefExpr(factory.createZName(CircusType.SYNC_CHANNEL)); //Meuzis, Sam's, modificado de cima
}
/**
* Returns an empty ListTerm.
*/
public static ListTerm createEmptyListTerm() {
return new ListTermImpl();
}
/** **************************************************************************************************************
* Circus Type
* ***************************************************************************************************************
*/
/**
*
*/
private static String printExpression (List <String> string) {
String str = "[";
if (string != null) {
for (int i = 0; i < string.size(); i++) {
String expr = string.get(i);
str = str + expr;
if (i != string.size() - 1) {
str = str + ", ";
}
}
}
return str + "]";
}
public static CircusType getLastTypeChannel(CircusType circusTypeChannel,
ZExprList genActuals) {
CircusType r;
//System.out.println ("generic parameters: " + printExpression (circusTypeChannel.getGenericParameters()));
Expr lastTypeExpr;
Expr typeExpression = circusTypeChannel.getExpression();
if (typeExpression instanceof ProdExpr) {
// Builds a Circus type with the last expr
//ListTerm expressions = ((ProdExpr) typeExpression).getExpr(); //Original, da �ngela
ZExprList expressions = (ZExprList) ((ProdExpr) typeExpression).getExprList();
lastTypeExpr = (Expr) expressions.get(expressions.size()-1);
} else {
// Returns the same type that was received as parameter
lastTypeExpr = circusTypeChannel.getExpression();
}
// Validate the type expression
assert(lastTypeExpr instanceof RefExpr): "lastTypeExpr is " +
lastTypeExpr.getClass();
if (circusTypeChannel.isGeneric()) {
// Case of a generic type
List<String> genParams = circusTypeChannel.getGenericParameters();
/*RefName*/ZName name = ((RefExpr) lastTypeExpr).getZName()/*getRefName()*/;
// Checks if the type is a generic param, that is, if it
// appears in the array of generic parameters
for (int i = 0; i < genParams.size(); i++) {
String genParam = genParams.get(i);
if (genParam.equals(name.toString())) {
// If this is the case, then gets the correspondent
// type expression in the array of actuals
lastTypeExpr = (Expr) genActuals.get(i);
// Validate the type expression
assert(lastTypeExpr instanceof RefExpr): "lastTypeExpr is " +
lastTypeExpr.getClass();
break;
}
}
}
// make a new type with the type expression of the last variable
r = new CircusType(lastTypeExpr);
return r;
}
/** **************************************************************************************************************
* Template
* ***************************************************************************************************************
*/
/**
* Returns Java code contained in a Velocity template.
*
* @param String templName Name of the template
* @param Map<String, String> map
*/
public static String getCodeFromTemplate(String templName, Map<String, String> map)
throws JCircusException {
String templCode = "";
try {
VelocityContext velocityContext;
Template template = null;
// Velocity code
velocityContext = new VelocityContext();
Velocity.init();
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
String code = map.get(key);
velocityContext.put(key, code);
}
template = Velocity.getTemplate(templName);
StringWriter stringWriter = new StringWriter();
template.merge(velocityContext, stringWriter);
stringWriter.close();
templCode = stringWriter.toString();
} catch (Throwable t) {
throw new JCircusException ("Velocity exception", t);
}
return templCode;
}
/**
* Creates a file with the code in a Velocity template.
*
* @param String fileName Name of the file
* @param String templName Name of the template
* @param Map<String, String> map
*/
public static String createFileFromTemplate(String templName,
Map<String, String> map, String fileName) throws JCircusException {
String result = "";
try {
VelocityContext velocityContext;
Template template = null;
File file = new File(fileName);
FileWriter fileWriter = new FileWriter(fileName);
// Velocity code
velocityContext = new VelocityContext();
Velocity.init();
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
String code = map.get(key);
velocityContext.put(key, code);
}
template = Velocity.getTemplate(templName);
template.merge(velocityContext, fileWriter);
fileWriter.close();
} catch (Throwable t) {
throw new JCircusException("Error while executing velocity code.", t);
}
return result;
}
/** **************************************************************************************************************
* Code
* ***************************************************************************************************************
*/
/**
* This method is called for the constructor of a class.
*/
public static String instChannelSimple(String channelName, ProcChanUseEnv chanMsEnv,
Integer procId, boolean isMain, ProcProcessParaEnv procProcessParaEnv, PId2PNameEnv id2name, CallProc2ChannelSetEnv cp2cse) {
String code = "";
//List<List <Integer>> ids = resolveUndefinedChannels(chanMsEnv, isMain, channelName, procProcessParaEnv); //By Angela Freitas
List<Integer> ids = resolveUndefinedChannels(chanMsEnv, /*new PId2PNameEnv (),*/ isMain/*, channelName, procProcessParaEnv, id2name, cp2cse*/);
// Declaration of chanInfo
code += "\n" + Constants.CLS_CHINFO + " chanInfo_" + channelName + " = new " + Constants.CLS_CHINFO + "();";
// Initialization of chanInfo
/*for (int i = 0; i < ids.size(); i++) { //By Angela Freitas
Integer subProcId = (Integer) ids.get(i);
code = code + "\nchanInfo_" + channelName +
".put(new Integer(" + subProcId + "), new Integer(" + i + "));";
}*/
for (int i = 0; i < ids.size(); i++) { //By Samuel Barrocas, 16/12/2010, 18:14hs
Integer subProcId = (Integer) ids.get(i);
code = code + "\nchanInfo_" + channelName +
".put(new Integer (" + subProcId + "), new Integer(" + i + "));";
}
// Instantiation of GeneralChannel
/*code += "\nthis." + channelName + " = new GeneralChannel(" +
"new Any2OneChannel(), chanInfo_" + channelName +
", new Integer(" + procId.intValue() + "));";*/ //Angela's, JCSP antigo
code += "\nthis." + channelName + " = new /*IV*/ GeneralChannel(" +
"org.jcsp.lang.Channel.any2one (), chanInfo_" + channelName +
", new Integer(" + procId.intValue() + "));"; //Sam's, JCSP novo
return code;
}
/**
* Returns a list containing the names of the processes, in the
* position corresponding to the multisync id.
*
* Basically, tries to find any Output channel in chanMSEnv, which
* will be given the position zero. Assigns any position to the
* other channels.
*
* Maybe it would be better that this method returned a Map instead
* of a List, because there can be many writers in the case where there is
* not a multi-synchronization... So, all these writers should have id zero.
*
*/
//p2pne.put();
public static List<Integer> resolveUndefinedChannels (ProcChanUseEnv chanMSEnv, /*PId2PNameEnv p2pne,*/
boolean isMain) {
Integer [] array;
boolean writerDefined = false;
int index = 0;
if (!chanMSEnv.isSync()) {
// There is no synchronization involving the channel
// Will take part in gui, in case isMain is true
if (!isMain) {
/**Abaixo, mudamos... Porque agora a GUI será gerada inclusive para os canais sincronizados (ou seja, canais dependentes)*/
array = new Integer[chanMSEnv.size() + 1]; //+ 1 by Samuel Barrocas, pois agora a GUI será gerada para todos os canais
array [0] = new Integer (-1);
index = 1;
/**Acima, mudamos... Porque agora a GUI será gerada inclusive para os canais sincronizados (ou seja, canais dependentes)*/
// If this is being called from a constructor of a process (that is,
// the channel is hidden, then there is no concern about the gui.
// We just add all the processes in chanMSEnv to any position
// of the array.
Iterator it = chanMSEnv.iteratorKeys();
while(it.hasNext()) {
Integer procId = (Integer) it.next();
array[index] = procId;
index++;
}
} else {
array = new Integer[chanMSEnv.size()+1]; // +1 for the gui
// Checks if the process will be input or output
ChanUse chanUseNotSync = chanMSEnv.getChanUseGuiNotSyncChannel();
if(chanUseNotSync.equals(ChanUse.Input)) {
array[0] = new Integer(-1);
index = 1;
Iterator it = chanMSEnv.iteratorKeys();
while(it.hasNext()) {
Integer procId = (Integer) it.next();
ChanUse chanUse = chanMSEnv.get(procId);
array[index] = procId;
index++;
}
System.out.print("");
} else {
// gui will be input
array[1] = new Integer(-1);
index = 2;
writerDefined = false;
Iterator it = chanMSEnv.iteratorKeys();
while(it.hasNext()) {
Integer procId = (Integer) it.next();
ChanUse chanUse = chanMSEnv.get(procId);
// The first Undefined found goes to the writer position.
// There will be a bug if there is more than one Undefined
// because then only one of them will go to the writer
// position, therefore the others will try to read the
// channel instead of write.
if (chanUse.equals(ChanUse.Undefined) && !writerDefined) {
array[0] = procId;
writerDefined = true;
} else {
if (index == chanMSEnv.size() + 1) {
// Reached the end and the writer had not been defined
array[0] = procId;
}
}
}
}
}
}
else {
//JOptionPane.showMessageDialog(null, "4");
//array = new Integer[chanMSEnv.size()]; Angela's
/**20/08/2011 -> Abaixo, mudamos... Porque agora a GUI será gerada inclusive para os canais sincronizados (ou seja, canais dependentes)*/
array = new Integer[chanMSEnv.size() + 1]; //+ 1 by Samuel Barrocas, pois agora a GUI será gerada para todos os canais
array [0] = new Integer (-1);
index = 1;
/**Acima, mudamos... Porque agora a GUI será gerada inclusive para os canais sincronizados (ou seja, canais dependentes)*/
// There is simple, or multiple synchronization involving the channel
//index = 0;
writerDefined = false;
Iterator it = chanMSEnv.iteratorKeys();
while(it.hasNext()) {
Integer procId = (Integer) it.next();
ChanUse chanUse = chanMSEnv.get(procId);
if (chanUse.equals(ChanUse.Output) && !writerDefined) {
// Output channel
writerDefined = true;
//array[0] = procId; //Angela's
array[1] = procId; //Sam's
} else {
// Input channel or Undefined channel
index++; //Comentado por Samuel Barrocas
// This is the last element and there is any writer in the array
if (index == array.length)
//index = 0; //Angela's
index = 1; //Samuel Barrocas
array[index] = procId;
}
}
}
// Transforms the array into a list
List<Integer> list = new ArrayList<Integer>();
for (int i=0; i<array.length; i++) {
list.add(array[i]);
}
return list;
}
//VERS�O ANTIGA DO M�TODO resolveUndefinedChannels
/*public static List<List <Integer>> resolveUndefinedChannels(ProcChanUseEnv chanMSEnv,
boolean isMain, String channelName, ProcProcessParaEnv procProcessParaEnv, PId2PNameEnv id2name, CallProc2ChannelSetEnv cp2ces) {
// Tratar diferentemente os casos em que ha interface grafica e os que
// nao ha interface grafica. No caso em que ha interface grafica
// (!chanMSEnv.isSync()) devera ja adicionar o id da interface grafica (-1)
// como reader ou como writer.
// para decidir como eu vou fazer aqui dar uma olhada no metodo
// getChanUseGuiNotSyncChannel de chanMsEnv.
// este metodo � chamado em processCallCode para decidir quem sera o READER
// e quem sera o WRITER (o processo ou a gui).
// Creates an array
List <Integer> [] array;
List <Integer> processesOnChannel = new ArrayList <Integer> ();// = new List <Integer> ();
//processesOnChannel.add(new Integer (0)); //De olho nesta linha, pode ser que ela gere erro, acrescentei para tirar o IndexOutOfBouds que deu em Translator2Java, linha 656
List <List <Integer>> processesNotOnChannel = new ArrayList <List <Integer>> ();
processesNotOnChannel.add(new ArrayList <Integer> ());
boolean writerDefined = false;
int index = 0;
boolean shared = false;
if (!chanMSEnv.isSync()) {
// There is no synchronization involving the channel
// Will take part in gui, in case isMain is true
if (!isMain) {
System.out.println ("SITUA��O 1");
array = new List [chanMSEnv.size()];
// If this is being called from a constructor of a process (that is,
// the channel is hidden, then there is no concern about the gui.
// We just add all the processes in chanMSEnv to any position
// of the array.
Iterator it = chanMSEnv.iteratorKeys();
while(it.hasNext()) {
Integer procId = (Integer) it.next();
//Abaixo, by Samuel Barrocas
//TODO retirar este trecho de c�digo (Abaixo..., e Acima...),
//pois neste caso n�o temos sincroniza��o.
//Como n�o temos sincroniza��o (!chanMSEnv.isSync()), n�o temos interleaving,
//e portanto n�o h� a necessidade de compartilhar front-end.
ChanInfoEnv chanInfoEnv = Util.getChannelMSEnvAnn(procProcessParaEnv.get(id2name.get(procId))); //(procId);
Iterator itChannels = chanInfoEnv.iteratorKeys();
boolean containsChannel = false;
while (itChannels.hasNext()) {
if (itChannels.toString().equals(channelName)) {
containsChannel = true;
}
}
if (containsChannel) {
processesOnChannel.add(procId);
array [0].add(procId);
}
//Acima, by Samuel Barrocas
processesNotOnChannel.add(new ArrayList <Integer> ()); //By Samuel Barrocas
processesNotOnChannel.get(index).add(procId);
array[index] = processesNotOnChannel.get(index);
index++;
}
} else {
System.out.println ("SITUA��O 2");
array = new List [chanMSEnv.size()+1]; // +1 for the gui
// Checks if the process will be input or output
ChanUse chanUseNotSync = chanMSEnv.getChanUseGuiNotSyncChannel();
if(chanUseNotSync.equals(ChanUse.Input)) { //TESTADO
System.out.println ("SITUA��O 2.1");
// gui will be output
List <Integer> l_int = new ArrayList <Integer> (); //By Samuel Barrocas
l_int.add(new Integer (-1)); //By Samuel Barrocas
array[0] = l_int; //By Samuel Barrocas
//array[0] = new Integer(-1); //By Angela Freitas
// iterates over the array, inserting the other positions
index = 1;
Iterator it = chanMSEnv.iteratorKeys();
while(it.hasNext()) {
Integer procId = (Integer) it.next();
ChanUse chanUse = chanMSEnv.get(procId);
processesNotOnChannel.add(new ArrayList <Integer> ()); //By Samuel Barrocas
processesNotOnChannel.get(index).add(procId); //By Samuel Barrocas
array[index] = processesNotOnChannel.get(index); //By Samuel Barrocas
//array[index] = procId; //By Angela Freitas
index++;
}
} else {
System.out.println ("SITUA��O 2.2"); //TESTADO
// gui will be input
List <Integer> l_int = new ArrayList <Integer> (); //By Samuel Barrocas
l_int.add(new Integer (-1)); //By Samuel Barrocas
array[1] = l_int; //By Samuel Barrocas
//array[1] = new Integer(-1); //By Angela Freitas
index = 2;
writerDefined = false;
Iterator it = chanMSEnv.iteratorKeys();
while(it.hasNext()) {
Integer procId = (Integer) it.next();
ChanUse chanUse = chanMSEnv.get(procId);
// The first Undefined found goes to the writer position.
// There will be a bug if there is more than one Undefined
// because then only one of them will go to the writer
// position, therefore the others will try to read the
// channel instead of write.
if (chanUse.equals(ChanUse.Undefined) && !writerDefined) { //TODO? //Samuel Barrocas
processesNotOnChannel.add(new ArrayList <Integer> ()); //By Samuel Barrocas
processesNotOnChannel.get(0).add(procId); //By Samuel Barrocas
array[0] = processesNotOnChannel.get(0); //By Samuel Barrocas
//array[0] = procId; //By Angela Freitas
writerDefined = true;
} else { //TODO?
if (index == chanMSEnv.size() + 1) {
// Reached the end and the writer had not been defined
processesNotOnChannel.add(new ArrayList <Integer> ()); //By Samuel Barrocas
processesNotOnChannel.get(0).add(procId); //By Samuel Barrocas
array[0] = processesNotOnChannel.get(0); //By Samuel Barrocas
//array[0] = procId; //By Angela Freitas
}
}
}
}
}
} else {
System.out.println ("SITUA��O 3");
array = new List [chanMSEnv.size()];
for (int i = 0; i < chanMSEnv.size(); i++) {
array [i] = new ArrayList <Integer> ();
}
// There is simple, or multiple synchronization involving the channel
index = 1;
writerDefined = false;
Iterator it = chanMSEnv.iteratorKeys();
while(it.hasNext()) {
Integer procId = (Integer) it.next();
ChanUse chanUse = chanMSEnv.get(procId);
if (chanUse.equals(ChanUse.Output) && !writerDefined) {
System.out.println ("SITUA��O 3.1");
// Output channel
writerDefined = true;
//Abaixo, by Samuel Barrocas
ChanInfoEnv chanInfoEnv = Util.getChannelMSEnvAnn(procProcessParaEnv.get(id2name.get(procId)));
Iterator itChannels = chanInfoEnv.iteratorKeys();
boolean containsChannel = false;
while (itChannels.hasNext()) {
if (itChannels.next().toString().equals(channelName)) {
containsChannel = true;
}
}
if (containsChannel && !cp2ces.get(procId).contains(channelName)) {
processesOnChannel.add(procId);
array [0].add(procId);
shared = true;
System.out.println ("array[0].add (" + procId + ")");
}
else {
if (index == array.length && !shared)
array [0].add(procId);
else {
array [index].add(procId);
index++;
}
System.out.println ("array [index++].add (" + procId + ")");
}
//Acima, by Samuel Barrocas
//processesNotOnChannel.add(new ArrayList <Integer> ()); //By Samuel Barrocas
//processesNotOnChannel.get(0).add(procId); //By Samuel Barrocas
//array[0] = processesNotOnChannel.get(0); //By Samuel Barrocas
//array[0] = procId; //By Angela Freitas
} else {
System.out.println ("SITUA��O 3.2"); //TESTADO
// Input channel or Undefined channel
//Abaixo, by Samuel Barrocas
ChanInfoEnv chanInfoEnv = Util.getChannelMSEnvAnn(procProcessParaEnv.get(id2name.get(procId)));
Iterator itChannels = chanInfoEnv.iteratorKeys();
boolean containsChannel = false;
while (itChannels.hasNext()) {
if (itChannels.next().toString().equals(channelName)) {
containsChannel = true;
}
}
if (containsChannel && !cp2ces.get(procId).contains(channelName)) {
processesOnChannel.add(procId);
array [0].add(procId);
shared = true;
System.out.println ("array[0].add (" + procId + ")");
}
else {
if (index == array.length && !shared)
array [0].add(procId);
else {
array [index].add(procId);
index++;
}
System.out.println ("array [index++].add (" + procId + ")");
}
//Acima, by Samuel Barrocas
//index++; //By Angela Freitas, comentado em 16/12/2010, �s 20:30hs, pouco depois de eu colar o trecho de c�digo acima, delimitado por "Acima...", e "Abaixo..."
// This is the last element and there is any writer in the array
/*if (index == array.length)
index = 0;*/
/*processesNotOnChannel.add(new ArrayList <Integer> ()); //By Samuel Barrocas
processesNotOnChannel.get(index).add(procId); //By Samuel Barrocas
array[index] = processesNotOnChannel.get(0); //By Samuel Barrocas
//array[index] = procId; //By Angela Freitas
}
}
}
// Transforms the array into a list
List<List <Integer>> list = new ArrayList<List <Integer>>();
for (int i=0; i<array.length; i++) {
list.add(array[i]);
}
return list;
}*/
/**
* Takes a list of Decl's and returns a list of VarDecl's.
*/
public static List<VarDecl> formatDecls(ZDeclList/*<Decl>*/ decls) {
List<VarDecl> r = new ArrayList<VarDecl>();
for (int i = 0; i < decls.size(); i++) {
Decl decl = (Decl) decls.get(i);
// Validate the type of decl
assert (decl instanceof VarDecl): "decl is " + decl.getClass();
//ListTerm names = ((VarDecl) decl).getDeclName(); //Esse foi made by �ngela
ZNameList names = (ZNameList) ((VarDecl) decl).getName()/*getDeclName()*/; //Esse foi made by Sam, adapted do de cima
Expr expression = ((VarDecl) decl).getExpr();
for (int j = 0; j < names.size(); j++) {
/*DeclName*/ZName declName = /*(DeclName)*/(ZName) names.get(j);
//LINHA X: VarDecl newDecl = _factory.createVarDecl(_factory.list(declName), expression); //By Angela
//Abaixo reside as modifica��es feitas por Sam, tentando corresponder ao que tem logo acima!!!!
/*Equivalente � linha X, essa e a de baixo:*/
NameList nameList = _factory.createZNameList(_factory.list(declName));
VarDecl newDecl = _factory.createVarDecl(nameList, expression);
r.add(newDecl);
}
}
return r;
}
/** **************************************************************************************************************
* Other
* ***************************************************************************************************************
*/
public static void print(String st, String cl, String method) {
boolean debug = true;
if (debug) {
System.out.println(":: " + cl + ", " + method + ": " + st);
}
}
}