cbc/net/loveruby/cflat/parser/LibraryLoader.java

72 lines
2.3 KiB
Java

package net.loveruby.cflat.parser;
import net.loveruby.cflat.ast.Declarations;
import net.loveruby.cflat.utils.ErrorHandler;
import net.loveruby.cflat.exception.*;
import java.util.*;
import java.io.*;
public class LibraryLoader {
protected List<String> loadPath;
protected LinkedList<String> loadingLibraries;
protected Map<String, Declarations> loadedLibraries;
static public List<String> defaultLoadPath() {
List<String> pathes = new ArrayList<String>();
pathes.add(".");
return pathes;
}
public LibraryLoader() {
this(defaultLoadPath());
}
public LibraryLoader(List<String> loadPath) {
this.loadPath = loadPath;
this.loadingLibraries = new LinkedList<String>();
this.loadedLibraries = new HashMap<String, Declarations>();
}
public void addLoadPath(String path) {
loadPath.add(path);
}
public Declarations loadLibrary(String libid, ErrorHandler handler)
throws CompileException {
if (loadingLibraries.contains(libid)) {
throw new SemanticException("recursive import from "
+ loadingLibraries.getLast()
+ ": " + libid);
}
loadingLibraries.addLast(libid); // stop recursive import
Declarations decls = loadedLibraries.get(libid);
if (decls != null) {
// Already loaded import file. Returns cached declarations.
return decls;
}
decls = Parser.parseDeclFile(searchLibrary(libid), this, handler);
loadedLibraries.put(libid, decls);
loadingLibraries.removeLast();
return decls;
}
public File searchLibrary(String libid) throws FileException {
try {
for (String path : loadPath) {
File file = new File(path + "/" + libPath(libid) + ".hb");
if (file.exists()) {
return file;
}
}
throw new FileException(
"no such library header file: " + libid);
}
catch (SecurityException ex) {
throw new FileException(ex.getMessage());
}
}
protected String libPath(String id) {
return id.replace('.', '/');
}
}