package org.sugarj;
import static org.sugarj.common.ATermCommands.getApplicationSubterm;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.sugarj.common.ATermCommands;
import org.sugarj.common.Environment;
import org.sugarj.common.FileCommands;
import org.sugarj.common.StringCommands;
import org.sugarj.common.path.Path;
import org.sugarj.common.path.RelativePath;
/**
* @author Florian Lorenzen <florian.lorenzen at tu-berlin de>
*/
public class FomegaProcessor extends AbstractBaseProcessor {
private static final long serialVersionUID = 6325786656556068937L;
private String moduleHeader;
private List<String> imports = new LinkedList<String>();
private List<String> body = new LinkedList<String>();
private boolean hasExtension = false;
private Set<RelativePath> generatedModules = new HashSet<RelativePath>();
private Environment environment;
private String relNamespaceName;
private RelativePath sourceFile;
private Path outFile;
private String moduleName;
private IStrategoTerm ppTable;
@Override
public String getGeneratedSource() {
if (moduleHeader == null)
return "";
if (hasExtension && body.isEmpty())
return "";
return moduleHeader + "\n"
+ StringCommands.printListSeparated(imports, "\n") + "\n"
+ StringCommands.printListSeparated(body, "\n");
}
@Override
public Path getGeneratedSourceFile() {
return outFile;
}
@Override
public String getNamespace() {
return relNamespaceName;
}
@Override
public FomegaLanguage getLanguage() {
return FomegaLanguage.getInstance();
}
/*
* processing stuff follows here
*/
@Override
public void init(RelativePath sourceFile, Environment environment) {
this.environment = environment;
this.sourceFile = sourceFile;
outFile = environment.createOutPath(FileCommands.dropExtension(sourceFile.getRelativePath()) + ".pts-source");
}
private void processNamespaceDecl(IStrategoTerm toplevelDecl) throws IOException {
String qualifiedModuleName = prettyPrint(getApplicationSubterm(toplevelDecl, "ModuleDec", 0));
String qualifiedModulePath = qualifiedModuleName.replace('.', '/');
String declaredModuleName = FileCommands.fileName(qualifiedModulePath);
moduleName = FileCommands.dropExtension(FileCommands.fileName(sourceFile.getRelativePath()));
String declaredRelNamespaceName = FileCommands.dropFilename(qualifiedModulePath);
relNamespaceName = FileCommands.dropFilename(sourceFile.getRelativePath());
RelativePath objectFile = environment.createOutPath(getRelativeNamespaceSep() + moduleName + "." + getLanguage().getBinaryFileExtension());
generatedModules.add(objectFile);
moduleHeader = prettyPrint(toplevelDecl);
if (!declaredRelNamespaceName.equals(relNamespaceName))
throw new RuntimeException(
"The declared namespace '" + declaredRelNamespaceName + "'" +
" does not match the expected namespace '" + relNamespaceName + "'.");
if (!declaredModuleName.equals(moduleName))
throw new RuntimeException(
"The declared module name '" + declaredModuleName + "'" +
" does not match the expected module name '" + moduleName + "'.");
}
@Override
public List<String> processBaseDecl(IStrategoTerm toplevelDecl) throws IOException {
if (getLanguage().isNamespaceDec(toplevelDecl)) {
processNamespaceDecl(toplevelDecl);
return Collections.emptyList();
}
// IStrategoTerm term = getApplicationSubterm(toplevelDecl, "FomegaBody", 0);
String text = null;
try {
text = prettyPrint(toplevelDecl);
} catch (NullPointerException e) {
ATermCommands.setErrorMessage(toplevelDecl, "pretty printing Fomega failed");
}
if (text != null)
body.add(text);
return Collections.emptyList();
}
@Override
public String getModulePathOfImport(IStrategoTerm toplevelDecl) {
return prettyPrint(getApplicationSubterm(toplevelDecl, "Import", 1)).replace('.', '/');
}
@Override
public void processModuleImport(IStrategoTerm toplevelDecl) throws IOException {
imports.add(prettyPrint(toplevelDecl));
}
public String prettyPrint(IStrategoTerm term) {
if (ppTable == null)
ppTable = ATermCommands.readPrettyPrintTable(getLanguage().ensureFile("org/sugarj/languages/Fomega.pp").getAbsolutePath());
return ATermCommands.prettyPrint(ppTable, term, interp);
}
@Override
public List<Path> compile(List<Path> outFiles, Path bin, List<Path> includePaths) throws IOException {
List<Path> generatedFiles = new LinkedList<Path>();
for (Path out : outFiles) {
RelativePath relOut = (RelativePath) out;
Path compilePath = new RelativePath(bin, FileCommands.dropExtension(relOut.getRelativePath()) + ".pts");
FileCommands.copyFile(out, compilePath);
generatedFiles.add(compilePath);
}
return generatedFiles;
}
@Override
public boolean isModuleExternallyResolvable(String relModulePath) {
return false;
}
@Override
public String getExtensionName(IStrategoTerm decl) throws IOException {
hasExtension = true;
return moduleName;
}
@Override
public IStrategoTerm getExtensionBody(IStrategoTerm decl) {
return getApplicationSubterm(decl, "ExtensionBody", 0);
}
}