/*
* #%~
* The Overture Abstract Syntax Tree
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.ast.util;
import java.util.List;
import java.util.Vector;
import org.overture.ast.definitions.AEqualsDefinition;
import org.overture.ast.definitions.AExplicitFunctionDefinition;
import org.overture.ast.definitions.AExplicitOperationDefinition;
import org.overture.ast.definitions.AExternalDefinition;
import org.overture.ast.definitions.AImplicitFunctionDefinition;
import org.overture.ast.definitions.AImplicitOperationDefinition;
import org.overture.ast.definitions.AImportedDefinition;
import org.overture.ast.definitions.AInheritedDefinition;
import org.overture.ast.definitions.AMultiBindListDefinition;
import org.overture.ast.definitions.AMutexSyncDefinition;
import org.overture.ast.definitions.ANamedTraceDefinition;
import org.overture.ast.definitions.APerSyncDefinition;
import org.overture.ast.definitions.ARenamedDefinition;
import org.overture.ast.definitions.AStateDefinition;
import org.overture.ast.definitions.AThreadDefinition;
import org.overture.ast.definitions.ATypeDefinition;
import org.overture.ast.definitions.AUntypedDefinition;
import org.overture.ast.definitions.AValueDefinition;
import org.overture.ast.definitions.PDefinition;
import org.overture.ast.definitions.SClassDefinition;
import org.overture.ast.intf.lex.ILexNameToken;
import org.overture.ast.lex.LexLocation;
import org.overture.ast.lex.LexNameList;
import org.overture.ast.lex.LexNameToken;
import org.overture.ast.node.NodeList;
import org.overture.ast.patterns.APatternListTypePair;
import org.overture.ast.patterns.PPattern;
import org.overture.ast.statements.ABlockSimpleBlockStm;
import org.overture.ast.statements.ACaseAlternativeStm;
import org.overture.ast.statements.ACasesStm;
import org.overture.ast.statements.AElseIfStm;
import org.overture.ast.statements.AIfStm;
import org.overture.ast.statements.ANonDeterministicSimpleBlockStm;
import org.overture.ast.statements.PStm;
import org.overture.ast.statements.SSimpleBlockStm;
import org.overture.ast.typechecker.NameScope;
public class ToStringUtil
{
public static String getExplicitFunctionString(AExplicitFunctionDefinition d)
{
StringBuilder params = new StringBuilder();
for (List<PPattern> plist : d.getParamPatternList())
{
params.append("(" + Utils.listToString(plist) + ")");
}
String accessStr = d.getAccess().toString();
if (d.getNameScope() == NameScope.LOCAL)
{
accessStr = "";
}
return accessStr
+ d.getName().getName()
+ (d.getTypeParams().isEmpty() ? ": " : "["
+ getTypeListString(d.getTypeParams()) + "]: ")
+ d.getType()
+ "\n\t"
+ d.getName().getName()
+ params
+ " ==\n"
+ d.getBody()
+ (d.getPrecondition() == null ? "" : "\n\tpre "
+ d.getPrecondition())
+ (d.getPostcondition() == null ? "" : "\n\tpost "
+ d.getPostcondition());
}
public static String getImplicitFunctionString(AImplicitFunctionDefinition d)
{
return d.getAccess()
+ " "
+ d.getName().getName()
+ (d.getTypeParams().isEmpty() ? "" : "["
+ getTypeListString(d.getTypeParams()) + "]")
+ Utils.listToString("(", getString(d.getParamPatterns()), ", ", ")")
+ d.getResult()
+ (d.getBody() == null ? "" : " ==\n\t" + d.getBody())
+ (d.getPrecondition() == null ? "" : "\n\tpre "
+ d.getPrecondition())
+ (d.getPostcondition() == null ? "" : "\n\tpost "
+ d.getPostcondition());
}
private static List<String> getString(List<APatternListTypePair> node)
{
List<String> list = new Vector<String>();
for (APatternListTypePair pl : node)
{
list.add("(" + getStringPattern(pl.getPatterns()) + ":"
+ pl.getType() + ")");
}
return list;
}
private static String getStringPattern(List<PPattern> patterns)
{
return Utils.listToString(patterns);
}
private static String getTypeListString(List<ILexNameToken> typeParams)
{
return "(" + Utils.listToString(typeParams) + ")";
}
public static String getExplicitOperationString(
AExplicitOperationDefinition d)
{
return d.getName()
+ " "
+ d.getType()
+ "\n\t"
+ d.getName()
+ "("
+ Utils.listToString(d.getParameterPatterns())
+ ")"
+ (d.getBody() == null ? "" : " ==\n" + d.getBody())
+ (d.getPrecondition() == null ? "" : "\n\tpre "
+ d.getPrecondition())
+ (d.getPostcondition() == null ? "" : "\n\tpost "
+ d.getPostcondition());
}
public static String getImplicitOperationString(
AImplicitOperationDefinition d)
{
return d.getName()
+ Utils.listToString("(", d.getParameterPatterns(), ", ", ")")
+ (d.getResult() == null ? "" : " " + d.getResult())
+ (d.getExternals().isEmpty() ? "" : "\n\text "
+ d.getExternals())
+ (d.getPrecondition() == null ? "" : "\n\tpre "
+ d.getPrecondition())
+ (d.getPostcondition() == null ? "" : "\n\tpost "
+ d.getPostcondition())
+ (d.getErrors().isEmpty() ? "" : "\n\terrs " + d.getErrors());
}
public static String getDefinitionListString(
NodeList<? extends PDefinition> _definitions)
{
StringBuilder sb = new StringBuilder();
for (PDefinition d : _definitions)
{
if (d.getAccess() != null)
{
sb.append(d.getAccess());
sb.append(" ");
}
// sb.append(d.getClass().getName() + " " + getVariableNames(d) + ":" + d.getType());
sb.append(d.toString());
sb.append("\n");
}
return sb.toString();
}
private static LexNameList getVariableNames(List<? extends PDefinition> list)
{
LexNameList variableNames = new LexNameList();
for (PDefinition dd : list)
{
variableNames.addAll(getVariableNames(dd));
}
return variableNames;
}
private static LexNameList getVariableNames(PDefinition d)
{
if (d instanceof SClassDefinition)
{
if (d instanceof SClassDefinition)
{
return getVariableNames(((SClassDefinition) d).getDefinitions());
}
assert false : "Error in class getVariableNames";
} else if (d instanceof AEqualsDefinition)
{
if (d instanceof AEqualsDefinition)
{
return ((AEqualsDefinition) d).getDefs() == null ? new LexNameList()
: getVariableNames(((AEqualsDefinition) d).getDefs());
}
assert false : "Error in equals getVariableNames";
} else if (d instanceof AExternalDefinition)
{
// return state.getVariableNames();
// TODO
return new LexNameList(new LexNameToken("Not implemented", "Not implemented", new LexLocation()));
} else if (d instanceof AImportedDefinition)
{
if (d instanceof AImportedDefinition)
{
return getVariableNames(((AImportedDefinition) d).getDef());
}
assert false : "Error in imported getVariableNames";
} else if (d instanceof AInheritedDefinition)
{
if (d instanceof AInheritedDefinition)
{
LexNameList names = new LexNameList();
// checkSuperDefinition();//TODO
AInheritedDefinition t = (AInheritedDefinition) d;
for (ILexNameToken vn : getVariableNames(t.getSuperdef()))
{
names.add(vn.getModifiedName(t.getName().getModule()));
}
return names;
}
assert false : "Error in inherited getVariableNames";
} else if (d instanceof AMultiBindListDefinition)
{
if (d instanceof AMultiBindListDefinition)
{
return ((AMultiBindListDefinition) d).getDefs() == null ? new LexNameList()
: getVariableNames(((AMultiBindListDefinition) d).getDefs());
}
} else if (d instanceof AMutexSyncDefinition
|| d instanceof ANamedTraceDefinition
|| d instanceof APerSyncDefinition)
{
return new LexNameList();
} else if (d instanceof ARenamedDefinition)
{
if (d instanceof ARenamedDefinition)
{
LexNameList both = new LexNameList(d.getName());
both.add(((ARenamedDefinition) d).getDef().getName());
return both;
}
assert false : "Error in renamed getVariableNames";
} else if (d instanceof AStateDefinition)
{
// return statedefs.getVariableNames();
// TODO
return new LexNameList(new LexNameToken("Not implemented", "Not implemented", new LexLocation()));
} else if (d instanceof AThreadDefinition)
{
if (d instanceof AThreadDefinition)
{
if (((AThreadDefinition) d).getOperationDef() != null)// Differnt from VDMJ
{
return new LexNameList(((AThreadDefinition) d).getOperationDef().getName());
} else
{
return null;
}
}
assert false : "Error in thread getVariableNames";
} else if (d instanceof ATypeDefinition)
{
return new LexNameList(d.getName());
} else if (d instanceof AUntypedDefinition)
{
assert false : "Can't get variables of untyped definition?";
} else if (d instanceof AValueDefinition)
{
if (d instanceof AValueDefinition)
{
// return ((AValueDefinition) d).getPattern()
// TODO
return new LexNameList(new LexNameToken("Not implemented", "Not implemented", new LexLocation()));
}
} else
{
return new LexNameList(d.getName());
}
return null;
}
public static String getCasesString(ACasesStm stm)
{
StringBuilder sb = new StringBuilder();
sb.append("cases " + stm.getExp() + " :\n");
for (ACaseAlternativeStm csa : stm.getCases())
{
sb.append(" ");
sb.append(csa.toString());
}
if (stm.getOthers() != null)
{
sb.append(" others -> ");
sb.append(stm.getOthers().toString());
}
sb.append(" end");
return sb.toString();
}
public static String getIfString(AIfStm node)
{
StringBuilder sb = new StringBuilder();
sb.append("if " + node.getIfExp() + "\nthen\n" + node.getThenStm());
for (AElseIfStm s : node.getElseIf())
{
sb.append(s.toString());
}
if (node.getElseStm() != null)
{
sb.append("else\n");
sb.append(node.getElseStm().toString());
}
return sb.toString();
}
public static String getSimpleBlockString(SSimpleBlockStm node)
{
StringBuilder sb = new StringBuilder();
String sep = "";
for (PStm s : node.getStatements())
{
sb.append(sep);
sb.append(s.toString());
sep = ";\n";
}
sb.append("\n");
return sb.toString();
}
public static String getBlockSimpleBlockString(ABlockSimpleBlockStm node)
{
StringBuilder sb = new StringBuilder();
sb.append("(\n");
for (PDefinition d : node.getAssignmentDefs())
{
sb.append(d);
sb.append("\n");
}
sb.append("\n");
sb.append(getSimpleBlockString(node));
sb.append(")");
return sb.toString();
}
public static String getNonDeterministicSimpleBlockString(
ANonDeterministicSimpleBlockStm node)
{
StringBuilder sb = new StringBuilder();
sb.append("||(\n");
sb.append(getSimpleBlockString(node));
sb.append(")");
return sb.toString();
}
}