Mercurial Hosting > luan
changeset 73:f86e4f77ef32
add package module
git-svn-id: https://luan-java.googlecode.com/svn/trunk@74 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Tue, 12 Feb 2013 09:46:45 +0000 |
parents | cd9dbd7477ca |
children | f003338d503b |
files | src/luan/LuanState.java src/luan/interp/UpValue.java src/luan/lib/BasicLib.java src/luan/lib/HtmlLib.java src/luan/lib/JavaLib.java src/luan/lib/MathLib.java src/luan/lib/PackageLib.java src/luan/lib/StringLib.java src/luan/lib/TableLib.java src/luan/tools/CmdLine.java src/luan/tools/WebRun.java src/luan/tools/WebShell.java |
diffstat | 12 files changed, 266 insertions(+), 126 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/LuanState.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/LuanState.java Tue Feb 12 09:46:45 2013 +0000 @@ -6,6 +6,7 @@ import java.util.ArrayList; import luan.interp.LuanCompiler; import luan.lib.BasicLib; +import luan.lib.PackageLib; import luan.lib.JavaLib; import luan.lib.MathLib; import luan.lib.StringLib; @@ -15,15 +16,44 @@ public abstract class LuanState { + public final LuanTable global = new LuanTable(); + public final LuanTable loaded = new LuanTable(); + public final LuanTable preload = new LuanTable(); + + public InputStream in = System.in; + public PrintStream out = System.out; + public PrintStream err = System.err; + + private final List<MetatableGetter> mtGetters = new ArrayList<MetatableGetter>(); + final List<StackTraceElement> stackTrace = new ArrayList<StackTraceElement>(); + + + public Object load(LuanFunction loader,String modName) throws LuanException { + return load(loader,modName,null); + } + + public Object load(LuanFunction loader,String modName,Object extra) throws LuanException { + Object mod = Luan.first(call(loader,LuanElement.JAVA,"loader",modName,extra)); + if( mod == null ) + mod = true; + loaded.put(modName,mod); + return mod; + } + public static LuanState newStandard() { - LuanState luan = LuanCompiler.newLuanState(); - BasicLib.register(luan); - JavaLib.register(luan); - MathLib.register(luan); - StringLib.register(luan); - TableLib.register(luan); - HtmlLib.register(luan); - return luan; + try { + LuanState luan = LuanCompiler.newLuanState(); + luan.load(BasicLib.LOADER,BasicLib.NAME); + luan.load(PackageLib.LOADER,PackageLib.NAME); + luan.load(JavaLib.LOADER,JavaLib.NAME); + luan.load(MathLib.LOADER,MathLib.NAME); + luan.load(StringLib.LOADER,StringLib.NAME); + luan.load(TableLib.LOADER,TableLib.NAME); + luan.load(HtmlLib.LOADER,HtmlLib.NAME); + return luan; + } catch(LuanException e) { + throw new RuntimeException(e); + } } public Object[] eval(String cmd,String sourceName) throws LuanException { @@ -32,19 +62,6 @@ } - - private final LuanTable global = new LuanTable(); - private final List<MetatableGetter> mtGetters = new ArrayList<MetatableGetter>(); - final List<StackTraceElement> stackTrace = new ArrayList<StackTraceElement>(); - - public InputStream in = System.in; - public PrintStream out = System.out; - public PrintStream err = System.err; - - public final LuanTable global() { - return global; - } - public final LuanTable getMetatable(Object obj) { if( obj instanceof LuanTable ) { LuanTable table = (LuanTable)obj;
--- a/src/luan/interp/UpValue.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/interp/UpValue.java Tue Feb 12 09:46:45 2013 +0000 @@ -65,7 +65,7 @@ static final Getter globalGetter = new Getter() { public UpValue get(LuanStateImpl luan) { - return new UpValue(luan.global()); + return new UpValue(luan.global); } };
--- a/src/luan/lib/BasicLib.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/lib/BasicLib.java Tue Feb 12 09:46:45 2013 +0000 @@ -21,46 +21,51 @@ public final class BasicLib { - public static void register(LuanState luan) { - LuanTable global = luan.global(); - global.put( "_G", global ); - try { - global.put( "assert", new LuanJavaFunction(BasicLib.class.getMethod("assert_",LuanState.class,Object.class,String.class),null) ); - add( global, "assert_boolean", LuanState.class, Boolean.TYPE ); - add( global, "assert_nil", LuanState.class, Object.class ); - add( global, "assert_number", LuanState.class, Number.class ); - add( global, "assert_string", LuanState.class, String.class ); - add( global, "assert_table", LuanState.class, LuanTable.class ); - add( global, "do_file", LuanState.class, String.class ); - add( global, "error", LuanState.class, Object.class ); - add( global, "get_metatable", LuanState.class, Object.class ); - add( global, "ipairs", LuanTable.class ); - add( global, "load", LuanState.class, String.class, String.class ); - add( global, "load_file", LuanState.class, String.class ); - add( global, "pairs", LuanTable.class ); - add( global, "print", LuanState.class, new Object[0].getClass() ); - add( global, "raw_equal", Object.class, Object.class ); - add( global, "raw_get", LuanTable.class, Object.class ); - add( global, "raw_len", LuanState.class, Object.class ); - add( global, "raw_set", LuanTable.class, Object.class, Object.class ); - add( global, "set_metatable", LuanTable.class, LuanTable.class ); - add( global, "to_number", Object.class, Integer.class ); - add( global, "to_string", LuanState.class, Object.class ); - add( global, "type", Object.class ); - global.put( "_VERSION", Luan.version ); - - add( global, "make_standard", LuanState.class ); - } catch(NoSuchMethodException e) { - throw new RuntimeException(e); + public static final String NAME = "basic"; + + public static final LuanFunction LOADER = new LuanFunction() { + public Object[] call(LuanState luan,Object[] args) throws LuanException { + LuanTable global = luan.global; + global.put( "_G", global ); + try { + global.put( "assert", new LuanJavaFunction(BasicLib.class.getMethod("assert_",LuanState.class,Object.class,String.class),null) ); + add( global, "assert_boolean", LuanState.class, Boolean.TYPE ); + add( global, "assert_nil", LuanState.class, Object.class ); + add( global, "assert_number", LuanState.class, Number.class ); + add( global, "assert_string", LuanState.class, String.class ); + add( global, "assert_table", LuanState.class, LuanTable.class ); + add( global, "do_file", LuanState.class, String.class ); + add( global, "error", LuanState.class, Object.class ); + add( global, "get_metatable", LuanState.class, Object.class ); + add( global, "ipairs", LuanTable.class ); + add( global, "load", LuanState.class, String.class, String.class ); + add( global, "load_file", LuanState.class, String.class ); + add( global, "pairs", LuanTable.class ); + add( global, "print", LuanState.class, new Object[0].getClass() ); + add( global, "raw_equal", Object.class, Object.class ); + add( global, "raw_get", LuanTable.class, Object.class ); + add( global, "raw_len", LuanState.class, Object.class ); + add( global, "raw_set", LuanTable.class, Object.class, Object.class ); + add( global, "set_metatable", LuanTable.class, LuanTable.class ); + add( global, "to_number", Object.class, Integer.class ); + add( global, "to_string", LuanState.class, Object.class ); + add( global, "type", Object.class ); + global.put( "_VERSION", Luan.version ); + + add( global, "make_standard", LuanState.class ); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + return LuanFunction.EMPTY_RTN; } - } + }; private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { t.put( method, new LuanJavaFunction(BasicLib.class.getMethod(method,parameterTypes),null) ); } public static void make_standard(LuanState luan) { - LuanTable global = luan.global(); + LuanTable global = luan.global; global.put( "dofile", global.get("do_file") ); global.put( "getmetatable", global.get("get_metatable") ); global.put( "loadfile", global.get("load_file") );
--- a/src/luan/lib/HtmlLib.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/lib/HtmlLib.java Tue Feb 12 09:46:45 2013 +0000 @@ -2,21 +2,27 @@ import luan.LuanState; import luan.LuanTable; +import luan.LuanFunction; import luan.LuanJavaFunction; public final class HtmlLib { - public static void register(LuanState luan) { - LuanTable module = new LuanTable(); - LuanTable global = luan.global(); - global.put("html",module); - try { - add( module, "encode", String.class ); - } catch(NoSuchMethodException e) { - throw new RuntimeException(e); + public static final String NAME = "html"; + + public static final LuanFunction LOADER = new LuanFunction() { + public Object[] call(LuanState luan,Object[] args) { + LuanTable module = new LuanTable(); + LuanTable global = luan.global; + global.put(NAME,module); + try { + add( module, "encode", String.class ); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + return LuanFunction.EMPTY_RTN; } - } + }; private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { t.put( method, new LuanJavaFunction(HtmlLib.class.getMethod(method,parameterTypes),null) );
--- a/src/luan/lib/JavaLib.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/lib/JavaLib.java Tue Feb 12 09:46:45 2013 +0000 @@ -27,19 +27,24 @@ public final class JavaLib { - public static void register(LuanState luan) { - luan.addMetatableGetter(mg); - LuanTable module = new LuanTable(); - LuanTable global = luan.global(); - global.put("java",module); - try { - global.put( "import", new LuanJavaFunction(JavaLib.class.getMethod("importClass",LuanState.class,String.class),null) ); - module.put( "class", new LuanJavaFunction(JavaLib.class.getMethod("getClass",LuanState.class,String.class),null) ); - add( module, "proxy", LuanState.class, Static.class, LuanTable.class, Object.class ); - } catch(NoSuchMethodException e) { - throw new RuntimeException(e); + public static final String NAME = "java"; + + public static final LuanFunction LOADER = new LuanFunction() { + public Object[] call(LuanState luan,Object[] args) throws LuanException { + luan.addMetatableGetter(mg); + LuanTable module = new LuanTable(); + LuanTable global = luan.global; + global.put(NAME,module); + try { + global.put( "import", new LuanJavaFunction(JavaLib.class.getMethod("importClass",LuanState.class,String.class),null) ); + module.put( "class", new LuanJavaFunction(JavaLib.class.getMethod("getClass",LuanState.class,String.class),null) ); + add( module, "proxy", LuanState.class, Static.class, LuanTable.class, Object.class ); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + return LuanFunction.EMPTY_RTN; } - } + }; private static final LuanTable mt = new LuanTable(); static { @@ -294,7 +299,7 @@ } public static void importClass(LuanState luan,String name) throws LuanException { - luan.global().put( name.substring(name.lastIndexOf('.')+1), getClass(luan,name) ); + luan.global.put( name.substring(name.lastIndexOf('.')+1), getClass(luan,name) ); } static class AmbiguousJavaFunction extends LuanFunction {
--- a/src/luan/lib/MathLib.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/lib/MathLib.java Tue Feb 12 09:46:45 2013 +0000 @@ -2,21 +2,27 @@ import luan.LuanState; import luan.LuanTable; +import luan.LuanFunction; import luan.LuanJavaFunction; public final class MathLib { - public static void register(LuanState luan) { - LuanTable module = new LuanTable(); - LuanTable global = luan.global(); - global.put("math",module); - try { - add( module, "floor", Double.TYPE ); - } catch(NoSuchMethodException e) { - throw new RuntimeException(e); + public static final String NAME = "math"; + + public static final LuanFunction LOADER = new LuanFunction() { + public Object[] call(LuanState luan,Object[] args) { + LuanTable module = new LuanTable(); + LuanTable global = luan.global; + global.put(NAME,module); + try { + add( module, "floor", Double.TYPE ); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + return LuanFunction.EMPTY_RTN; } - } + }; private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { t.put( method, new LuanJavaFunction(MathLib.class.getMethod(method,parameterTypes),null) );
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/lib/PackageLib.java Tue Feb 12 09:46:45 2013 +0000 @@ -0,0 +1,91 @@ +package luan.lib; + +import java.io.File; +import java.util.List; +import java.util.ArrayList; +import luan.Luan; +import luan.LuanState; +import luan.LuanTable; +import luan.LuanFunction; +import luan.LuanJavaFunction; +import luan.LuanElement; +import luan.LuanException; + + +public final class PackageLib { + + public static final String NAME = "package"; + + public static final LuanFunction LOADER = new LuanFunction() { + public Object[] call(LuanState luan,Object[] args) throws LuanException { + LuanTable global = luan.global; + LuanTable module = new LuanTable(); + List<Object> searchers = new ArrayList<Object>(); + global.put(NAME,module); + module.put("loaded",luan.loaded); + module.put("preload",luan.preload); + module.put("path","?.lua"); + try { + add( global, "require", LuanState.class, String.class ); + add( module, "search_path", String.class, String.class ); + searchers.add( new LuanJavaFunction(PackageLib.class.getMethod("preloadSearcher",LuanState.class,String.class),null) ); + searchers.add( new LuanJavaFunction(PackageLib.class.getMethod("fileSearcher",LuanState.class,String.class),null) ); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + module.put("searchers",new LuanTable(searchers)); + return LuanFunction.EMPTY_RTN; + } + }; + + private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { + t.put( method, new LuanJavaFunction(PackageLib.class.getMethod(method,parameterTypes),null) ); + } + + public static Object require(LuanState luan,String modName) throws LuanException { + LuanTable module = (LuanTable)luan.global.get(NAME); + Object mod = luan.loaded.get(modName); + if( mod == null ) { + LuanTable searchers = (LuanTable)module.get("searchers"); + for( Object s : searchers.asList() ) { + LuanFunction searcher = (LuanFunction)s; + Object[] a = luan.call(searcher,LuanElement.JAVA,"searcher",modName); + if( a.length >= 1 && a[0] instanceof LuanFunction ) { + LuanFunction loader = (LuanFunction)a[0]; + Object extra = a.length >= 2 ? a[1] : null; + mod = luan.load(loader,modName,extra); + } + } + if( mod == null ) + throw new LuanException( luan, LuanElement.JAVA, "module '"+modName+"' not found" ); + } + return mod; + } + + public static String search_path(String NAME,String path) { + for( String s : path.split(";") ) { + String file = s.replaceAll("\\?",NAME); + if( new File(file).exists() ) + return file; + } + return null; + } + + private static final LuanFunction fileLoader = new LuanFunction() { + public Object[] call(LuanState luan,Object[] args) throws LuanException { + return BasicLib.do_file(luan,(String)args[1]); + } + }; + + public static Object[] fileSearcher(LuanState luan,String modName) { + LuanTable module = (LuanTable)luan.global.get(NAME); + String path = (String)module.get("path"); + String file = search_path(modName,path); + return file==null ? LuanFunction.EMPTY_RTN : new Object[]{fileLoader,file}; + } + + public static Object preloadSearcher(LuanState luan,String modName) { + return luan.preload.get(modName); + } + +}
--- a/src/luan/lib/StringLib.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/lib/StringLib.java Tue Feb 12 09:46:45 2013 +0000 @@ -13,27 +13,32 @@ public final class StringLib { - public static void register(LuanState luan) { - LuanTable module = new LuanTable(); - LuanTable global = luan.global(); - global.put("string",module); - try { - module.put( "byte", new LuanJavaFunction(StringLib.class.getMethod("byte_",String.class,Integer.class,Integer.class),null) ); - module.put( "char", new LuanJavaFunction(StringLib.class.getMethod("char_",new byte[0].getClass()),null) ); - add( module, "find", String.class, String.class, Integer.class, Boolean.class ); - add( module, "gmatch", String.class, String.class ); - add( module, "gsub", LuanState.class, String.class, String.class, Object.class, Integer.class ); - add( module, "len", String.class ); - add( module, "lower", String.class ); - add( module, "match", String.class, String.class, Integer.class ); - add( module, "rep", String.class, Integer.TYPE, String.class ); - add( module, "reverse", String.class ); - add( module, "sub", String.class, Integer.TYPE, Integer.class ); - add( module, "upper", String.class ); - } catch(NoSuchMethodException e) { - throw new RuntimeException(e); + public static final String NAME = "string"; + + public static final LuanFunction LOADER = new LuanFunction() { + public Object[] call(LuanState luan,Object[] args) throws LuanException { + LuanTable module = new LuanTable(); + LuanTable global = luan.global; + global.put(NAME,module); + try { + module.put( "byte", new LuanJavaFunction(StringLib.class.getMethod("byte_",String.class,Integer.class,Integer.class),null) ); + module.put( "char", new LuanJavaFunction(StringLib.class.getMethod("char_",new byte[0].getClass()),null) ); + add( module, "find", String.class, String.class, Integer.class, Boolean.class ); + add( module, "gmatch", String.class, String.class ); + add( module, "gsub", LuanState.class, String.class, String.class, Object.class, Integer.class ); + add( module, "len", String.class ); + add( module, "lower", String.class ); + add( module, "match", String.class, String.class, Integer.class ); + add( module, "rep", String.class, Integer.TYPE, String.class ); + add( module, "reverse", String.class ); + add( module, "sub", String.class, Integer.TYPE, Integer.class ); + add( module, "upper", String.class ); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + return LuanFunction.EMPTY_RTN; } - } + }; private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { t.put( method, new LuanJavaFunction(StringLib.class.getMethod(method,parameterTypes),null) );
--- a/src/luan/lib/TableLib.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/lib/TableLib.java Tue Feb 12 09:46:45 2013 +0000 @@ -14,22 +14,27 @@ public final class TableLib { - public static void register(LuanState luan) { - LuanTable module = new LuanTable(); - LuanTable global = luan.global(); - global.put("table",module); - try { - add( module, "concat", LuanState.class, LuanTable.class, String.class, Integer.class, Integer.class ); - add( module, "insert", LuanState.class, LuanTable.class, Integer.TYPE, Object.class ); - add( module, "pack", new Object[0].getClass() ); - add( module, "remove", LuanState.class, LuanTable.class, Integer.TYPE ); - add( module, "sort", LuanState.class, LuanTable.class, LuanFunction.class ); - add( module, "sub_list", LuanTable.class, Integer.TYPE, Integer.TYPE ); - add( module, "unpack", LuanTable.class ); - } catch(NoSuchMethodException e) { - throw new RuntimeException(e); + public static final String NAME = "table"; + + public static final LuanFunction LOADER = new LuanFunction() { + public Object[] call(LuanState luan,Object[] args) throws LuanException { + LuanTable module = new LuanTable(); + LuanTable global = luan.global; + global.put(NAME,module); + try { + add( module, "concat", LuanState.class, LuanTable.class, String.class, Integer.class, Integer.class ); + add( module, "insert", LuanState.class, LuanTable.class, Integer.TYPE, Object.class ); + add( module, "pack", new Object[0].getClass() ); + add( module, "remove", LuanState.class, LuanTable.class, Integer.TYPE ); + add( module, "sort", LuanState.class, LuanTable.class, LuanFunction.class ); + add( module, "sub_list", LuanTable.class, Integer.TYPE, Integer.TYPE ); + add( module, "unpack", LuanTable.class ); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + return LuanFunction.EMPTY_RTN; } - } + }; private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { t.put( method, new LuanJavaFunction(TableLib.class.getMethod(method,parameterTypes),null) );
--- a/src/luan/tools/CmdLine.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/tools/CmdLine.java Tue Feb 12 09:46:45 2013 +0000 @@ -65,7 +65,7 @@ for( int j=0; j<args.length; j++ ) { argsTable.put( j, args[j] ); } - luan.global().put("arg",argsTable); + luan.global.put("arg",argsTable); try { LuanFunction fn = BasicLib.load_file(luan,file); luan.call(fn,null,null,varArgs);
--- a/src/luan/tools/WebRun.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/tools/WebRun.java Tue Feb 12 09:46:45 2013 +0000 @@ -33,8 +33,8 @@ try { LuanState luan = newLuanState(); luan.out = out; - luan.global().put("request",request); - luan.global().put("response",response); + luan.global.put("request",request); + luan.global.put("response",response); luan.eval(code,"WebRun"); } catch(LuanException e) { logger.error(null,e);
--- a/src/luan/tools/WebShell.java Tue Feb 12 05:44:15 2013 +0000 +++ b/src/luan/tools/WebShell.java Tue Feb 12 09:46:45 2013 +0000 @@ -59,8 +59,8 @@ session.putValue("luan",luan); } luan.out = new PrintStream(history); - luan.global().put("request",request); - luan.global().put("response",response); + luan.global.put("request",request); + luan.global.put("response",response); Object[] result = eval(luan,cmd); if( result.length > 0 ) { for( int i=0; i<result.length; i++ ) {