public class Compiler {
private static final Logger log = Logger.getLogger("jagi-fs");
+ private static final Path cwd = Paths.get("").toAbsolutePath();
private final Map<Path, File> files = new HashMap<>();
private final Map<Path, ClassLoader> libs = new HashMap<>();
private final Collection<Path> searchpath = new ArrayList<>();
}
public static class Compilation implements AutoCloseable {
- public final Path dir, srcdir, outdir;
+ public final Path dir, srcdir, outdir, libdir;
private final List<Path> infiles = new ArrayList<>();
private final List<Path> classpath = new ArrayList<>();
private List<String> output = null;
+ private boolean haslib;
public Compilation() throws IOException {
dir = Files.createTempDirectory("javac");
srcdir = dir.resolve("src");
outdir = dir.resolve("out");
+ libdir = dir.resolve("lib");
Files.createDirectory(srcdir);
Files.createDirectory(outdir);
}
classpath.add(p);
}
+ public void addlib(String clnm, byte[] contents) throws IOException {
+ if(!haslib) {
+ Files.createDirectory(libdir);
+ classpath(libdir);
+ haslib = true;
+ }
+ Path p = libdir;
+ int p1 = 0;
+ while(true) {
+ int p2 = clnm.indexOf('.', p1);
+ if(p2 < 0)
+ break;
+ p = p.resolve(clnm.substring(p1, p2));
+ if(!Files.isDirectory(p))
+ Files.createDirectory(p);
+ p1 = p2 + 1;
+ }
+ p = p.resolve(clnm.substring(p1) + ".class");
+ Files.write(p, contents);
+ }
+
+ public void addlib(Map<String, byte[]> classes) throws IOException {
+ for(Map.Entry<String, byte[]> ent : classes.entrySet())
+ addlib(ent.getKey(), ent.getValue());
+ }
+
public boolean compile() throws IOException {
List<String> args = new ArrayList<>();
args.add("javac");
private static final Pattern classpat = Pattern.compile("^((public|abstract)\\s+)*(class|interface)\\s+(\\S+)");
private static final Pattern libpat = Pattern.compile("\\$use\\s*:\\s*(\\S+)");
+ private static final Pattern incpat = Pattern.compile("\\$include\\s*:\\s*(\\S+)");
public class Module {
public final Path file;
- public final ClassLoader code;
+ public final BufferedClassLoader code;
public final Collection<Path> classpath = new ArrayList<>();
+ public final Collection<Module> include = new ArrayList<>();
public Module(Path file) throws IOException {
this.file = file;
if(!c.compile())
throw(new CompilationException(file, c.output()));
ClassLoader parent = Compiler.class.getClassLoader();
- if(!classpath.isEmpty()) {
+ if(!classpath.isEmpty() || !include.isEmpty()) {
Collection<ClassLoader> libs = new ArrayList<>();
for(Path cp : classpath)
libs.add(libloader(cp));
+ for(Module mod : include)
+ libs.add(mod.code);
parent = new LibClassLoader(parent, libs);
}
code = new BufferedClassLoader(parent, c.classes());
throw(new CompilationException(file, Arrays.asList("no such library: " + m.group(1))));
classpath.add(lib);
}
+ m = incpat.matcher(ln);
+ if(m.find()) {
+ String nm = m.group(1);
+ File f= null;
+ if(f == null) {
+ Path p = file.resolveSibling(nm);
+ if(Files.isRegularFile(p))
+ f = file(p);
+ }
+ if(f == null) {
+ Path p = cwd.resolve(nm);
+ if(Files.isRegularFile(p))
+ f = file(p);
+ }
+ if(f == null)
+ throw(new CompilationException(file, Arrays.asList("no such file to include: " + nm)));
+ f.update();
+ c.addlib(f.mod().code.contents);
+ include.add(f.mod());
+ }
m = classpat.matcher(ln);
if(m.find()) {
String clnm = m.group(4);