package org.fusionlanguage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Locale;
class FileGenHost extends FuConsoleHost
{
private final ArrayList<String> resourceDirs = new ArrayList<String>();
private File filename;
private FileWriter currentFile;
public void addResourceDir(String path)
{
this.resourceDirs.add(path);
}
private ArrayList<Byte> readAllBytes(File path)
{
try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(path))) {
for (final ArrayList<Byte> result = new ArrayList<Byte>();;) {
int b = in.read();
if (b < 0)
return result;
result.add((byte) b);
}
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
private ArrayList<Byte> readResource(String name, FuPrefixExpr expr)
{
for (String dir : this.resourceDirs) {
File path = new File(dir, name);
if (path.isFile())
return readAllBytes(path);
}
File path = new File(name);
if (path.isFile())
return readAllBytes(path);
reportStatementError(expr, String.format("File %s not found", name));
return new ArrayList<Byte>();
}
protected @Override int getResourceLength(String name, FuPrefixExpr expr)
{
ArrayList<Byte> content = getResources().get(name);
if (content == null) {
content = readResource(name, expr);
getResources().put(name, content);
}
return content.size();
}
public @Override Appendable createFile(String directory, String filename)
{
this.filename = new File(directory, filename);
try {
this.currentFile = new FileWriter(this.filename);
}
catch (IOException e) {
throw new RuntimeException(e);
}
return this.currentFile;
}
public @Override void closeFile()
{
try {
this.currentFile.close();
}
catch (IOException e) {
throw new RuntimeException(e);
}
if (hasErrors())
filename.delete();
}
protected @Override String toDirectory(String path)
{
File file = new File(path);
return file.isDirectory() ? path : file.getParent();
}
}
public class Fut
{
private static FuProgram parseAndResolve(FuParser parser, FuSystem system, FuScope parent, ArrayList<String> files, FuSema sema, FuConsoleHost host) throws IOException
{
new FuProgram().init(parent, system, host);
for (String file : files) {
byte[] input = Files.readAllBytes(Paths.get(file));
parser.parse(file, input, input.length);
}
if (host.hasErrors())
System.exit(1);
sema.process();
if (host.hasErrors())
System.exit(1);
return host.program;
}
public static void main(String[] args)
{
Locale.setDefault(Locale.US);
final FileGenHost host = new FileGenHost();
final FuParser parser = new FuParser();
final ArrayList<String> inputFiles = new ArrayList<String>();
final ArrayList<String> referencedFiles = new ArrayList<String>();
String lang = null;
String outputFile = null;
String namespace = "";
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (!arg.startsWith("-"))
inputFiles.add(arg);
else if (arg.equals("--help")) {
FuConsoleHost.usage("java -jar fut.jar");
return;
}
else if (arg.equals("--version")) {
System.out.format("Fusion Transpiler %s (Java)\n", FuConsoleHost.VERSION);
return;
}
else if (arg.length() == 2 && i + 1 < args.length) {
switch (arg.charAt(1)) {
case 'l':
lang = args[++i];
break;
case 'o':
outputFile = args[++i];
break;
case 'n':
namespace = args[++i];
break;
case 'D':
String symbol = args[++i];
if (symbol.equals("true") || symbol.equals("false")) {
System.err.format("fut: ERROR: '%s' is reserved\n", symbol);
System.exit(1);
}
parser.addPreSymbol(symbol);
break;
case 'r':
referencedFiles.add(args[++i]);
break;
case 'I':
host.addResourceDir(args[++i]);
break;
default:
System.err.format("fut: ERROR: Unknown option: %s\n", arg);
System.exit(1);
}
}
else {
System.err.format("fut: ERROR: Unknown option: %s\n", arg);
System.exit(1);
}
}
if (outputFile == null || inputFiles.size() == 0) {
FuConsoleHost.usage("java -jar fut.jar");
System.exit(1);
}
final FuSema sema = new FuSema();
parser.setHost(host);
sema.setHost(host);
final FuSystem system = FuSystem.new_();
FuScope parent = system;
try {
if (!referencedFiles.isEmpty())
parent = parseAndResolve(parser, system, parent, referencedFiles, sema, host);
final FuProgram program = parseAndResolve(parser, system, parent, inputFiles, sema, host);
if (lang != null) {
host.emit(program, lang, namespace, outputFile);
if (host.hasErrors())
System.exit(1);
return;
}
for (int i = outputFile.length(); --i >= 0; ) {
char c = outputFile.charAt(i);
if (c == '.') {
if (i >= 2
&& (outputFile.charAt(i - 2) == '.' || outputFile.charAt(i - 2) == ',')
&& outputFile.regionMatches(true, i - 1, "d.ts", 0, 4)
&& (i + 3 == outputFile.length() || outputFile.charAt(i + 3) == ','))
continue;
String outputBase = outputFile.substring(0, i + 1);
boolean error = false;
for (String outputExt : outputFile.substring(i + 1).split(",")) {
host.emit(program, outputExt, namespace, outputBase + outputExt);
if (host.hasErrors()) {
host.setErrors(false);
error = true;
}
}
if (error)
System.exit(1);
return;
}
if (c == '/' || c == '\\' || c == ':')
break;
}
System.err.format("fut: ERROR: Don't know what language to translate to: no extension in '%s' and no '-l' option\n", outputFile);
System.exit(1);
}
catch (IOException e) {
System.err.println("fut: ERROR: " + e.getMessage());
System.exit(1);
}
}
}