GSOC | Extending Common Lisp support
Charles Turner
chturne@gmail.com
Wed Jun 13 14:43:00 GMT 2012
Thanks for the explanation, MAKE-PACKAGE is a little less mysterious now :-)
I've been adding several more misc functions for symbols and packages.
Still a little way to go for full ANSI conformance!
Currently implementing the EXPORT feature. I've attached some code
showing how I think it should be done. One thing I've noticed in ANSI
is the notion of correctable errors with some package conditions (such
as name conflicts, missing symbols...). I've highlighted where such
interactions will need to be performed in my code, but I'm wondering
if there is any existing framework in Kawa for this kind of stuff (Per
has normally covered all bases :-)). I imagine the whole prompting
business will require its own abstraction somehwere (condition systems
in CL?) as the notion seems quite pervaisive in CL (I'm always getting
dropped into "Blah blah blah, select from the following restarts:"
when experimenting with CL.
Thanks,
Charles.
-------------- next part --------------
(defun export (symbols &optional (package *package*))
(let ((package (find-package-or-error package)))
(invoke-static gnu.mapping.lispexpr.LispPackage 'export symbols package)))
--------------
public static void export (LList syms, LispPackage pkg)
{
Stack<Symbol> validSyms = new Stack<Symbol>();
Iterator symiter = syms.getIterator();
Symbol s;
Values v;
while (symiter.hasNext())
{
s = (Symbol) symiter.next();
v = pkg.findSymbol(s.getName());
if (v.get(1) != CommonLisp.FALSE
&& !validSyms.contains(s))
{
validSyms.push(s);
}
}
NamespaceUse usedBy = pkg.imported;
symiter = syms.getIterator();
while (symiter.hasNext())
{
s = (Symbol) symiter.next();
String sname = s.getName();
while (usedBy != null)
{
v = usedBy.imported.findSymbol(sname);
if (v.get(1) != CommonLisp.FALSE
&& v.get(0) != s
&& !usedBy.imported.shadowingSymbols.contains(v.get(0)))
{
// name conflict in usedBy.imported! Correctable, ask user
// which name to nuke.
}
usedBy = usedBy.nextImported;
}
}
// Check that all symbols are accessible. If not, ask to import them.
Stack<Symbol> missing = new Stack<Symbol>();
// syms accessible in the inheritance chain, but not in this package
Stack<Symbol> imports = new Stack<Symbol>();
symiter = syms.getIterator();
while (symiter.hasNext())
{
s = (Symbol) symiter.next();
v = pkg.findSymbol(s.getName());
if ((!(v.get(0) == CommonLisp.FALSE)) ||
(!(v.get(1) == s)))
{
missing.push(s);
}
else if (v.get(1) == KeywordNamespace.valueOf("inherited"))
{
imports.push(s);
}
}
if (!missing.isEmpty())
{
// correctable error, ask user if they want ot import these
// missing symbols into the package
}
if (!imports.isEmpty())
{
// import these symbols into the package
}
symiter = syms.getIterator();
while (symiter.hasNext())
{
s = (Symbol) symiter.next();
pkg.remove(s); // remove internal
pkg.exported.add(s); // add to external
}
}
More information about the Kawa
mailing list