comparison src/luan/lib/PackageLib.java @ 108:3c404a296995

make Package module more standard; return _ENV by default; add "import" statement; git-svn-id: https://luan-java.googlecode.com/svn/trunk@109 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Fri, 23 May 2014 03:21:54 +0000
parents 72a4a5550ec7
children 2428ecfed375
comparison
equal deleted inserted replaced
107:dbf459397217 108:3c404a296995
7 import java.util.Collections; 7 import java.util.Collections;
8 import luan.Luan; 8 import luan.Luan;
9 import luan.LuanState; 9 import luan.LuanState;
10 import luan.LuanTable; 10 import luan.LuanTable;
11 import luan.LuanFunction; 11 import luan.LuanFunction;
12 import luan.LuanLoader;
13 import luan.LuanJavaFunction; 12 import luan.LuanJavaFunction;
14 import luan.LuanElement; 13 import luan.LuanElement;
15 import luan.LuanException; 14 import luan.LuanException;
16 15
17 16
18 public final class PackageLib { 17 public final class PackageLib {
19 18
20 public static final String NAME = "Package"; 19 public static final String NAME = "Package";
21 20
22 public static final LuanLoader LOADER = new LuanLoader() { 21 public static final LuanFunction LOADER = new LuanFunction() {
23 @Override protected void load(LuanState luan) { 22 @Override public Object[] call(LuanState luan,Object[] args) {
24 LuanTable module = new LuanTable(); 23 LuanTable module = new LuanTable();
25 LuanTable global = new LuanTable(); 24 LuanTable global = luan.global();
26 module.put( LuanState._G, global );
27 module.put("loaded",luan.loaded()); 25 module.put("loaded",luan.loaded());
28 module.put("preload",luan.preload()); 26 module.put("preload",luan.preload());
29 module.put("path","?.lua"); 27 module.put("path","?.luan");
30 try { 28 try {
31 add( global, "require", LuanState.class, String.class ); 29 global.put("require",require);
32 add( global, "module", LuanState.class, String.class, String.class );
33 add( module, "search_path", String.class, String.class ); 30 add( module, "search_path", String.class, String.class );
34 } catch(NoSuchMethodException e) { 31 } catch(NoSuchMethodException e) {
35 throw new RuntimeException(e); 32 throw new RuntimeException(e);
36 } 33 }
37 module.put("searchers",new LuanTable(Arrays.<Object>asList(preloadSearcher,fileSearcher,javaFileSearcher))); 34 LuanTable searchers = luan.searchers();
38 luan.loaded().put(NAME,module); 35 searchers.add(preloadSearcher);
36 searchers.add(fileSearcher);
37 searchers.add(javaFileSearcher);
38 module.put("searchers",searchers);
39 return new Object[]{module};
39 } 40 }
40 }; 41 };
42
43 public static final LuanFunction require;
44 static {
45 try {
46 require = new LuanJavaFunction(PackageLib.class.getMethod("require", LuanState.class, String.class),null);
47 } catch(NoSuchMethodException e) {
48 throw new RuntimeException(e);
49 }
50 }
41 51
42 private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { 52 private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException {
43 t.put( method, new LuanJavaFunction(PackageLib.class.getMethod(method,parameterTypes),null) ); 53 t.put( method, new LuanJavaFunction(PackageLib.class.getMethod(method,parameterTypes),null) );
44 } 54 }
45 55
46 public static void module(LuanState luan,String modName,String superMod) throws LuanException { 56 public static Object require(LuanState luan,String modName) throws LuanException {
47 LuanTable module; 57 LuanTable loaded = luan.loaded();
48 if( superMod==null ) { 58 Object mod = loaded.get(modName);
49 module = new LuanTable();
50 } else {
51 require(luan,superMod);
52 module = (LuanTable)luan.loaded().get(superMod);
53 }
54 luan.currentEnvironment().put(modName,module);
55 luan.loaded().put(modName,module);
56 }
57
58 public static void require(LuanState luan,String modName) throws LuanException {
59 require(luan,modName,luan.currentEnvironment());
60 }
61
62 public static void require(LuanState luan,String modName,LuanTable env) throws LuanException {
63 LuanTable mod = (LuanTable)luan.loaded().get(modName);
64 if( mod == null ) { 59 if( mod == null ) {
65 LuanTable searchers = (LuanTable)luan.get("Package.searchers"); 60 LuanTable searchers = (LuanTable)luan.get("Package.searchers");
66 if( searchers == null ) 61 if( searchers == null )
67 searchers = new LuanTable(Collections.<Object>singletonList(preloadSearcher)); 62 searchers = new LuanTable(Collections.<Object>singletonList(preloadSearcher));
68 for( Object s : searchers.asList() ) { 63 for( Object s : searchers.asList() ) {
69 LuanFunction searcher = (LuanFunction)s; 64 LuanFunction searcher = (LuanFunction)s;
70 Object[] a = luan.JAVA.call(searcher,"<searcher>",modName); 65 Object[] a = luan.JAVA.call(searcher,"<searcher>",modName);
71 if( a.length >= 1 && a[0] instanceof LuanFunction ) { 66 if( a.length >= 1 && a[0] instanceof LuanFunction ) {
72 LuanFunction loader = (LuanFunction)a[0]; 67 LuanFunction loader = (LuanFunction)a[0];
73 luan.JAVA.call(loader,"<require \""+modName+"\">"); 68 a[0] = modName;
74 mod = (LuanTable)luan.loaded().get(modName); 69 mod = Luan.first(luan.JAVA.call(loader,"<require \""+modName+"\">",a));
75 if( mod==null ) 70 if( mod != null ) {
76 throw luan.JAVA.exception( "module '"+modName+"' didn't define its module" ); 71 loaded.put(modName,mod);
72 } else {
73 mod = loaded.get(modName);
74 if( mod==null )
75 loaded.put(modName,true);
76 }
77 break; 77 break;
78 } 78 }
79 } 79 }
80 if( mod == null ) 80 if( mod == null )
81 throw luan.JAVA.exception( "module '"+modName+"' not found" ); 81 throw luan.JAVA.exception( "module '"+modName+"' not found" );
82 } 82 }
83 if( env != null ) 83 return mod;
84 env.put(modName,mod);
85 } 84 }
86 85
87 public static String search_path(String name,String path) { 86 public static String search_path(String name,String path) {
88 for( String s : path.split(";") ) { 87 for( String s : path.split(";") ) {
89 String file = s.replaceAll("\\?",name); 88 String file = s.replaceAll("\\?",name);
91 return file; 90 return file;
92 } 91 }
93 return null; 92 return null;
94 } 93 }
95 94
96 private static final class FileLoader extends LuanLoader { 95 public static final LuanFunction fileLoader = new LuanFunction() {
97 private final String fileName; 96 @Override public Object[] call(LuanState luan,Object[] args) throws LuanException {
98 97 String modName = (String)args[0];
99 FileLoader(String fileName) { 98 String fileName = (String)args[1];
100 this.fileName = fileName; 99 LuanFunction fn = BasicLib.load_file(luan,fileName);
101 } 100 return fn.call(luan,new Object[]{args[0],fileName});
102
103 @Override protected void load(LuanState luan) throws LuanException {
104 LuanFunction fn = BasicLib.load_file(luan,fileName,null);
105 fn.call(luan,EMPTY);
106 } 101 }
107 }; 102 };
108 103
109 public static final LuanFunction fileSearcher = new LuanFunction() { 104 public static final LuanFunction fileSearcher = new LuanFunction() {
110 public Object[] call(LuanState luan,Object[] args) throws LuanException { 105 @Override public Object[] call(LuanState luan,Object[] args) {
111 String modName = (String)args[0]; 106 String modName = (String)args[0];
112 String path = (String)luan.get("Package.path"); 107 String path = (String)luan.get("Package.path");
113 if( path==null ) 108 if( path==null )
114 return LuanFunction.EMPTY; 109 return LuanFunction.EMPTY;
115 String file = search_path(modName,path); 110 String file = search_path(modName,path);
116 return file==null ? LuanFunction.EMPTY : new Object[]{new FileLoader(file)}; 111 return file==null ? LuanFunction.EMPTY : new Object[]{fileLoader,file};
117 } 112 }
118 }; 113 };
119 114
120 public static final LuanFunction preloadSearcher = new LuanFunction() { 115 public static final LuanFunction preloadSearcher = new LuanFunction() {
121 public Object[] call(LuanState luan,Object[] args) throws LuanException { 116 @Override public Object[] call(LuanState luan,Object[] args) {
122 String modName = (String)args[0]; 117 String modName = (String)args[0];
123 Object mod = luan.preload().get(modName); 118 Object mod = luan.preload().get(modName);
124 return new Object[]{mod}; 119 return new Object[]{mod};
125 } 120 }
126 }; 121 };
127 122
128 123
129 124
130 125
131 private static final class JavaFileLoader extends LuanLoader { 126 public static final LuanFunction javaFileLoader = new LuanFunction() {
132 private final URL url; 127 @Override public Object[] call(LuanState luan,Object[] args) throws LuanException {
133 128 String modName = (String)args[0];
134 JavaFileLoader(URL url) { 129 URL url = (URL)args[0];
135 this.url = url;
136 }
137
138 @Override protected void load(LuanState luan) throws LuanException {
139 try { 130 try {
140 String src = Utils.read(url); 131 String src = Utils.read(url);
141 LuanFunction fn = BasicLib.load(luan,src,url.toString(),null); 132 LuanFunction fn = BasicLib.load(luan,src,url.toString(),false);
142 fn.call(luan,EMPTY); 133 return fn.call(luan,new Object[]{args[0],url.toString()});
143 } catch(IOException e) { 134 } catch(IOException e) {
144 throw luan.JAVA.exception(e); 135 throw luan.JAVA.exception(e);
145 } 136 }
146 } 137 }
147 }; 138 };
148 139
149 public static final LuanFunction javaFileSearcher = new LuanFunction() { 140 public static final LuanFunction javaFileSearcher = new LuanFunction() {
150 public Object[] call(LuanState luan,Object[] args) throws LuanException { 141 @Override public Object[] call(LuanState luan,Object[] args) {
151 String modName = (String)args[0]; 142 String modName = (String)args[0];
152 String path = (String)luan.get("Package.jpath"); 143 String path = (String)luan.get("Package.jpath");
153 if( path==null ) 144 if( path==null )
154 return LuanFunction.EMPTY; 145 return LuanFunction.EMPTY;
155 for( String s : path.split(";") ) { 146 for( String s : path.split(";") ) {
156 String file = s.replaceAll("\\?",modName); 147 String file = s.replaceAll("\\?",modName);
157 URL url = ClassLoader.getSystemResource(file); 148 URL url = ClassLoader.getSystemResource(file);
158 if( url != null ) { 149 if( url != null ) {
159 return new Object[]{new JavaFileLoader(url)}; 150 return new Object[]{javaFileLoader,url};
160 } 151 }
161 } 152 }
162 return LuanFunction.EMPTY; 153 return LuanFunction.EMPTY;
163 } 154 }
164 }; 155 };