Mercurial Hosting > luan
changeset 327:0be73ac9103d
handle circular package loading
git-svn-id: https://luan-java.googlecode.com/svn/trunk@328 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Thu, 19 Mar 2015 05:36:05 +0000 |
parents | db37d6aee4db |
children | 71e4f4ce74a3 |
files | core/src/luan/impl/LuanCompiler.java core/src/luan/modules/PackageLuan.java |
diffstat | 2 files changed, 39 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/core/src/luan/impl/LuanCompiler.java Thu Mar 19 00:01:57 2015 +0000 +++ b/core/src/luan/impl/LuanCompiler.java Thu Mar 19 05:36:05 2015 +0000 @@ -16,8 +16,7 @@ private LuanCompiler() {} // never public static LuanFunction compile(LuanState luan,LuanSource src,LuanTable env,boolean allowExpr) throws LuanException { - boolean passedEnv = env != null; - if( !passedEnv ) + if( env==null ) env = Luan.newTable(); UpValue.Getter envGetter = new UpValue.ValueGetter(env); LuanParser parser = new LuanParser(src,envGetter); @@ -25,17 +24,7 @@ parser.addVar( "require", PackageLuan.requireFn ); FnDef fnDef = parse(luan,parser,allowExpr); final LuanStateImpl luanImpl = (LuanStateImpl)luan; - final Closure c = new Closure(luanImpl,fnDef); - if( passedEnv ) - return c; - return new LuanFunction() { - @Override public Object call(LuanState luan,Object[] args) throws LuanException { - Object rtn = c.call(luan,args); - if( rtn instanceof Object[] && ((Object[])rtn).length==0 ) - rtn = c.upValues()[0].get(); - return rtn; - } - }; + return new Closure(luanImpl,fnDef); } private static FnDef parse(LuanState luan,LuanParser parser,boolean allowExpr) throws LuanException {
--- a/core/src/luan/modules/PackageLuan.java Thu Mar 19 00:01:57 2015 +0000 +++ b/core/src/luan/modules/PackageLuan.java Thu Mar 19 05:36:05 2015 +0000 @@ -3,7 +3,8 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collections; -import java.util.List; +import java.util.Set; +import java.util.HashSet; import luan.Luan; import luan.LuanState; import luan.LuanTable; @@ -46,25 +47,46 @@ if( mod == null ) { if( modName.startsWith("java:") ) { mod = JavaLuan.load(luan,modName.substring(5)); - if( mod == null ) - return null; + if( mod != null ) + loaded.put(modName,mod); } else { String src = read(luan,modName+".luan"); if( src == null ) return null; - LuanFunction loader = BasicLuan.load(luan,src,modName,null,false); - mod = Luan.first( - luan.call(loader,"<require \""+modName+"\">",new Object[]{modName}) - ); - } - if( mod != null ) { - loaded.put(modName,mod); - } else { - mod = loaded.get(modName); - if( mod==null ) { - mod = true; + LuanTable env = Luan.newTable(); + LuanFunction loader = BasicLuan.load(luan,src,modName,env,false); + loaded.put(modName,env); + @SuppressWarnings("unchecked") + Set<String> loading = (Set<String>)luan.registry().get("Package.loading"); + boolean top = loading==null; + if(top) { + loading = new HashSet<String>(); + luan.registry().put("Package.loading",loading); + } + loading.add(modName); + boolean ok = false; + try { + mod = Luan.first( + luan.call(loader,"<require \""+modName+"\">",new Object[]{modName}) + ); + ok = true; + } finally { + if( !ok ) { + if(top) { + for( String mn : loading ) { + loaded.put(mn,null); + } + } else { + loaded.put(modName,null); + } + } + if(top) + luan.registry().put("Package.loading",null); + } + if( mod != null ) loaded.put(modName,mod); - } + else + mod = env; } } return mod;