package scotch.runner; import static java.lang.System.err; import static java.lang.System.exit; import static java.util.Arrays.stream; import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import java.util.Optional; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import scotch.compiler.ClassLoaderResolver; import scotch.compiler.PathCompiler; import scotch.compiler.error.CompileException; import scotch.symbol.SymbolResolver; public class CompilerRunner { public static void main(String[] args) throws ParseException, IOException { Options options = createOptions(); try { run(args, options); } catch (CompileException exception) { exception.printErrors(); exit(1); } catch (IOException | RuntimeException exception) { err.println(exception.getMessage()); exit(1); } catch (ParseException exception) { showHelp(options); } } private static Options createOptions() { Options options = new Options(); options.addOption(new Option("cp", "Specifies the classpath to use during compilation") {{ setLongOpt("classpath"); setRequired(false); setArgs(1); }}); options.addOption(new Option("o", "Specifies the output path for compiled classes") {{ setLongOpt("output-path"); setRequired(false); setArgs(1); }}); options.addOption(new Option("h", "Shows this help") {{ setLongOpt("help"); setRequired(false); setArgs(0); }}); return options; } private static List<URL> getClasspath(CommandLine cli) { List<URL> classpath; if (cli.hasOption("cp") || cli.hasOption("classpath")) { classpath = stream(cli.getOptionValue("cp", cli.getOptionValue("classpath", "")).split(File.pathSeparator)) .map(path -> { try { return new File(path).getAbsoluteFile().toURI().toURL(); } catch (MalformedURLException exception) { throw new RuntimeException(exception); } }) .collect(toList()); } else { classpath = emptyList(); } return classpath; } private static void run(String[] args, Options options) throws ParseException, IOException { CommandLineParser parser = new GnuParser(); CommandLine cli = parser.parse(options, args); if (cli.hasOption("h") || cli.hasOption("help")) { showHelp(options); return; } List<URL> classpath = getClasspath(cli); File outputPath = new File(cli.getOptionValue("o", cli.getOptionValue("output-path", "build"))); List<File> inputFiles = stream(cli.getArgs()).map(File::new).collect(toList()); SymbolResolver symbolResolver = new ClassLoaderResolver( Optional.empty(), classpath.toArray(new URL[classpath.size()]), CompilerRunner.class.getClassLoader() ); new PathCompiler(symbolResolver, outputPath, inputFiles).compile(); } private static void showHelp(Options options) { new HelpFormatter().printHelp("sc [-o output path] [-cp classpath] file1 [file2 [fileN...]]", options); } }