package jcircus;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.swing.JOptionPane;
import jcircus.exceptions.FailParsingException;
import jcircus.exceptions.FailTranslationException;
import jcircus.exceptions.FailTypeCheckingException;
import jcircus.exceptions.JCircusException;
import jcircus.exceptions.TranslationCancelledException;
import jcircus.parallelism.ParallelismUpdater;
import jcircus.translator.Translator2Java;
import jcircus.util.Constants;
import jcircus.util.Error;
import jcircus.util.MathToolkitConstants;
import net.sourceforge.czt.base.ast.Term;
import net.sourceforge.czt.base.util.UnmarshalException;
import net.sourceforge.czt.circus.util.Factory;
import net.sourceforge.czt.parser.circus.CircusParseError;
import net.sourceforge.czt.parser.circus.ParseUtils;
import net.sourceforge.czt.parser.util.ErrorType;
import net.sourceforge.czt.parser.util.ParseException;
import net.sourceforge.czt.session.FileSource;
import net.sourceforge.czt.session.Markup;
import net.sourceforge.czt.session.SectionInfo;
import net.sourceforge.czt.session.SectionManager;
import net.sourceforge.czt.typecheck.circus.TypeChecker;
import net.sourceforge.czt.typecheck.circus.WarningManager;
import net.sourceforge.czt.typecheck.z.ErrorAnn;
import net.sourceforge.czt.z.ast.Expr;
import net.sourceforge.czt.z.ast.RefExpr;
import net.sourceforge.czt.z.ast.Spec;
//import net.sourceforge.czt.circustools.ast.*;
//import circparser.CircusParser;
/**
* JCircus.java
*
* Main class of JCircus, with access to all the modules of the tool.
*
* @author Angela Freitas
*
*/
public abstract class JCircusController {
static private final String NEWLINE = "\n";
/*Os métodos abaixo foram trazidos de JCircusControllerFrame para JCircusController
* para habilitar a possibilidade de chamar o painel de escolha de geração de
* classe Main para os processos
* */
public void cancelTranslation () throws TranslationCancelledException {
//Copiado de JCircusControllerFrame para JCircusController
throw new TranslationCancelledException();
}
public String codeForParameter(String expression, Expr typeExpr)
throws FailParsingException, FailTypeCheckingException {
String code = "";
// For the moment, typeExpr will be always a reference. This will be
// changed in the future. Probably this method will receive the actual
// Type, instead of the type expression.
assert(typeExpr instanceof RefExpr);
String typeExprSt = ((RefExpr) typeExpr).getName().toString();
if (typeExprSt.equals(MathToolkitConstants.NAT) ||
typeExprSt.equals(MathToolkitConstants.NUM) ||
typeExprSt.equals(MathToolkitConstants.ARITHMOS)) {
// Number
try {
// Simulate parsing/typeChecking here
int number = Integer.parseInt(expression);
code = "new " + Constants.CLS_CIRCNUM + "(" + number + ")";
} catch (NumberFormatException nfe) {
// Error
List<String> errors = new Factory().list("Expression is not a number.");
throw new FailParsingException(errors);
}
} else {
// Free type
if (_translator.getEnvironment().isElementFreeType(typeExprSt, expression)) {
// Simulate parsing/typeChecking here
code = "new " + typeExprSt + "(" + typeExprSt + "." + expression + ")";
} else {
// Error
List<String> errors = new Factory().list("Expression is not an element of free type.");
throw new FailParsingException(errors);
}
}
return code;
}
/*Os métodos acima foram trazidos de JCircusControllerFrame para JCircusController
* para habilitar a possibilidade de chamar o painel de escolha de geração de
* classe Main para os processos
* */
/* Translator */
protected Translator2Java _translator;
Spec spec = null;
/**
* Performs parser, type checking and translates the given input file.
*/
public void translate (String path, String projectDir, String projectName
, String compl, boolean useBarriers, boolean parallelism, boolean bench)
throws Exception {
try {
spec = parse(path);
typeCheck(spec);
translate2Java(projectDir, projectName, spec, compl, useBarriers, parallelism, bench);
reportTranslationOK(projectDir, projectName);
} catch (FailParsingException e) {
reportParsingErrors(e.getErrors());
} catch (FailTypeCheckingException e) {
reportTypeCheckingErrors(e.getErrors());
} catch (FailTranslationException e) {
reportTranslationErrors(e.getErrors());
} catch (TranslationCancelledException e) {
reportMessage("Translation cancelled by the user." + NEWLINE);
}
}
/**
* Performs parsing, and if there is no error, returns the syntax tree.
*
* If the parsing fails, throws FailParsingException.
*/
private Spec parse(String path) throws FailParsingException {
ParseException parseException = null;
Spec spec = null;
FileSource source = new FileSource (path);
try {
spec = (Spec) ParseUtils.parse(new FileSource (path), new SectionManager ("circus"));
} catch (ParseException e) {
JOptionPane.showMessageDialog (null, e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.out.println ("IOException");
e.printStackTrace();
} catch (UnmarshalException e) {
e.printStackTrace();
System.out.println ("UnmarshalException");
}//CircusParser.parse(path);
// TODO: Change this. The errors should be a simple list, as it is in the type
// checker, and not a mapping.
//System.out.println ("Passou por acu�... Depois dos catch!");
//TODO: Mudar isso aqui!!!!!!!!!!!!!!!!!!!!!!!!
/*Map<String, List<String>> errors = null;//CircusParser.getErrors();
if (errors.isEmpty()) {
System.out.println ("errors � empty!");
reportParsingOK();
} else {
// Parsing errors
System.out.println ("errors N�O � empty!");
List<String> parseErrors = null;
int i = 0;
for (List<String> list : errors.values()) {
parseErrors = list;
i++;
assert (i <= 1); // The mapping must have only one value
}
throw new FailParsingException (parseErrors);
}*/
return spec;
}
/**
* Performs type checking on a syntax tree.
*
* If the type checking fails, throwns FailTypeChecking Exception.
*/
/*Metodo abaixo implementado por Samuel, para ignorar os warnings no lançamento da exceção*/
private static boolean hasErrors (TypeChecker tcheck) {
int counterErrors = 0;
List </*net.sourceforge.czt.typecheck.circus.*/ErrorAnn> errorsOrWarnings = (List </*net.sourceforge.czt.typecheck.circus.*/ErrorAnn>) tcheck.errors();
for (int i = 0; i < errorsOrWarnings.size(); i++) {
if (errorsOrWarnings.get(i).getErrorType() == ErrorType.ERROR) {
counterErrors ++;
}
}
if (counterErrors > 0) {
return true;
}
else return false;
}
/*Método acima implementado por Samuel, para ignorar os warnings no lan�amento da exce��o*/
public static void typeCheck (Spec spec) throws FailTypeCheckingException {
@SuppressWarnings ({"unchecked", "fallthrough", "doWarn", "WarningManager"})
SectionManager manager = new SectionManager("circus");
net.sourceforge.czt.typecheck.circus.impl.Factory factory = new net.sourceforge.czt.typecheck.circus.impl.Factory();
TypeChecker typeChecker = new TypeChecker (factory, manager);
WarningManager wm = typeChecker.getWarningManager();
typeChecker.visitTerm(spec);
List<ErrorAnn> typeErrors = (List<ErrorAnn>) typeChecker.errors();
if (!hasErrors(typeChecker)) {
reportTypeCheckingOK();
} else {
throw new FailTypeCheckingException(typeErrors);
}
}
/**
*
*/
protected abstract void translate2Java (String projectDir, String projectName, Spec /*Term*/ spec, String compl, boolean useBarriers, boolean parallelism, boolean bench)
throws FailTranslationException, TranslationCancelledException, JCircusException;
/**
*
*/
protected abstract void reportMessage (String message);
/**
*
*/
private void reportParsingOK() {
String message = "No parsing errors!" + NEWLINE;
reportMessage(message);
}
/**
*
*/
private static void reportTypeCheckingOK() {
String message = "No type checking errors!" + NEWLINE;
//JOptionPane.showMessageDialog (null, "From TypeChecker: " + message);
//reportMessage(message);
}
/**
*
*/
public void reportTranslationOK(String projectDir, String projectName) {
String message = "Translation was successful! Files for project '" + projectName +
"' were created at " + getOutputDir(projectDir, projectName) + ".";
reportMessage(message);
}
/**
*
*/
protected String parsingErrorMessage(List<String> errors) {
StringBuilder message = new StringBuilder();
message.append(errors.size() + " parsing error(s)!" + NEWLINE);
for(String e : errors) {
message.append(e.toString() + NEWLINE);
}
return message.toString();
}
/**
*
*/
protected String typeCheckingErrorMessage(List<ErrorAnn> errors) {
StringBuilder message = new StringBuilder();
message.append(errors.size() + " type error(s)!" + NEWLINE);
for(ErrorAnn e : errors) {
message.append(e.toString() + NEWLINE);
}
return message.toString();
}
/**
*
*/
protected String translationErrorMessage(List<Error> errors) {
StringBuilder message = new StringBuilder();
message.append("Input file does not meet the requirements for translation." + NEWLINE);
message.append(errors.size() + " error(s)!" + NEWLINE);
for(Error e : errors) {
message.append(e.toString() + NEWLINE);
}
return message.toString();
}
/**
*
*/
protected abstract void reportParsingErrors(List<String> errors)
throws FailParsingException;
/**
*
*/
protected abstract void reportTypeCheckingErrors(List<ErrorAnn> errors)
throws FailTypeCheckingException;
/**
*
*/
protected abstract void reportTranslationErrors(List<Error> errors)
throws FailTranslationException;
/**
*
*/
public String getOutputDir(String outputPath, String projectName) {
return outputPath + "/"/*"\\"*/ + projectName + "/"/*"\\"*/ + Constants.DIR_SOURCE;
}
}