Mercurial Hosting > luan
changeset 1267:9fa8b8389578
add LuanTable.luan;
support metatable __gc();
add luan.sql;
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 12 Nov 2018 02:10:41 -0700 |
parents | 05934fbf635a |
children | 725e52076f03 |
files | src/luan/Luan.java src/luan/LuanException.java src/luan/LuanJavaFunction.java src/luan/LuanState.java src/luan/LuanTable.java src/luan/impl/LuanImpl.java src/luan/impl/LuanParser.java src/luan/modules/BasicLuan.java src/luan/modules/IoLuan.java src/luan/modules/JavaLuan.java src/luan/modules/PackageLuan.java src/luan/modules/StringLuan.java src/luan/modules/Table.luan src/luan/modules/TableLuan.java src/luan/modules/ThreadLuan.java src/luan/modules/http/HttpServicer.java src/luan/modules/http/LuanHandler.java src/luan/modules/lucene/LuceneIndex.java src/luan/modules/mail/SmtpCon.java src/luan/modules/parsers/Csv.java src/luan/modules/parsers/Html.java src/luan/modules/sql/Database.java src/luan/modules/sql/Sql.luan src/luan/modules/url/LuanUrl.java |
diffstat | 24 files changed, 495 insertions(+), 273 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/Luan.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/Luan.java Mon Nov 12 02:10:41 2018 -0700 @@ -1,6 +1,5 @@ package luan; -import java.lang.reflect.Array; import java.util.List; import java.util.ArrayList; import java.util.Map; @@ -202,36 +201,6 @@ return v; } */ - public static LuanTable toTable(Object obj) { - if( obj == null ) - return null; - if( obj instanceof LuanTable ) - return (LuanTable)obj; - if( obj instanceof List ) { - return new LuanTable((List)obj); - } - if( obj instanceof Map ) { - return new LuanTable((Map)obj); - } - if( obj instanceof Set ) { - return new LuanTable((Set)obj); - } - Class cls = obj.getClass(); - if( cls.isArray() ) { - if( cls.getComponentType().isPrimitive() ) { - int len = Array.getLength(obj); - List list = new ArrayList(); - for( int i=0; i<len; i++ ) { - list.add(Array.get(obj,i)); - } - return new LuanTable(list); - } else { - Object[] a = (Object[])obj; - return new LuanTable(Arrays.asList(a)); - } - } - return null; - } private Luan() {} // never }
--- a/src/luan/LuanException.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/LuanException.java Mon Nov 12 02:10:41 2018 -0700 @@ -35,11 +35,11 @@ clone.table = (LuanTable)cloner.clone(table); } - public LuanTable table() { + public LuanTable table(LuanState luan) { if( table==null ) { - table = new LuanTable(); + table = new LuanTable(luan); table.rawPut( "java", this ); - LuanTable metatable = new LuanTable(); + LuanTable metatable = new LuanTable(luan); table.setMetatable(metatable); try { table.rawPut( "get_message", new LuanJavaFunction(
--- a/src/luan/LuanJavaFunction.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/LuanJavaFunction.java Mon Nov 12 02:10:41 2018 -0700 @@ -58,7 +58,7 @@ @Override public Object call(LuanState luan,Object[] args) throws LuanException { try { args = fixArgs(luan,args); - return doCall(args); + return doCall(luan,args); } catch(IllegalArgumentException e) { checkArgs(args); throw e; @@ -67,10 +67,10 @@ public Object rawCall(LuanState luan,Object[] args) throws LuanException { args = fixArgs(luan,args); - return doCall(args); + return doCall(luan,args); } - private Object doCall(Object[] args) throws LuanException { + private Object doCall(LuanState luan,Object[] args) throws LuanException { Object rtn; try { rtn = method.invoke(obj,args); @@ -86,7 +86,7 @@ } catch(InstantiationException e) { throw new RuntimeException(e); } - return rtnConverter.convert(rtn); + return rtnConverter.convert(luan,rtn); } private static final Map primitiveMap = new HashMap(); @@ -189,30 +189,30 @@ private interface RtnConverter { - public Object convert(Object obj); + public Object convert(LuanState luan,Object obj); } private static final RtnConverter RTN_NOTHING = new RtnConverter() { - @Override public Object[] convert(Object obj) { + @Override public Object[] convert(LuanState luan,Object obj) { return NOTHING; } }; private static final RtnConverter RTN_SAME = new RtnConverter() { - @Override public Object convert(Object obj) { + @Override public Object convert(LuanState luan,Object obj) { return obj; } }; private static final RtnConverter RTN_ARRAY = new RtnConverter() { - @Override public Object convert(Object obj) { + @Override public Object convert(LuanState luan,Object obj) { if( obj == null ) return null; Object[] a = new Object[Array.getLength(obj)]; for( int i=0; i<a.length; i++ ) { a[i] = Array.get(obj,i); } - return new LuanTable(new ArrayList<Object>(Arrays.asList(a))); + return new LuanTable(luan,new ArrayList<Object>(Arrays.asList(a))); } }; @@ -339,7 +339,7 @@ private static final ArgConverter ARG_TABLE = new ArgConverter() { public Object convert(LuanState luan,Object obj) { - LuanTable tbl = Luan.toTable(obj); + LuanTable tbl = luan.toTable(obj); return tbl!=null ? tbl : obj; } @Override public String toString() { @@ -351,7 +351,7 @@ public Object convert(LuanState luan,Object obj) throws LuanException { if( obj instanceof LuanTable ) { LuanTable t = (LuanTable)obj; - return t.asMap(luan); + return t.asMap(); } return obj; } @@ -378,8 +378,8 @@ public Object convert(LuanState luan,Object obj) throws LuanException { if( obj instanceof LuanTable ) { LuanTable t = (LuanTable)obj; - if( t.isSet(luan) ) - return t.asSet(luan); + if( t.isSet() ) + return t.asSet(); } return obj; } @@ -394,8 +394,8 @@ LuanTable t = (LuanTable)obj; if( t.isList() ) return t.asList(); - if( t.isSet(luan) ) - return t.asSet(luan); + if( t.isSet() ) + return t.asSet(); } return obj; }
--- a/src/luan/LuanState.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/LuanState.java Mon Nov 12 02:10:41 2018 -0700 @@ -1,9 +1,14 @@ package luan; +import java.lang.reflect.Array; import java.io.Closeable; import java.io.IOException; import java.util.Map; import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Set; +import java.util.Arrays; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import luan.impl.LuanCompiler; @@ -64,7 +69,7 @@ public String toString(Object obj) throws LuanException { if( obj instanceof LuanTable ) { LuanTable tbl = (LuanTable)obj; - return tbl.toString(this); + return tbl.toStringLuan(); } if( obj == null ) return "nil"; @@ -78,7 +83,7 @@ public Object index(Object obj,Object key) throws LuanException { if( obj instanceof LuanTable ) { LuanTable tbl = (LuanTable)obj; - return tbl.get(this,key); + return tbl.get(key); } if( obj != null && javaOk.ok ) return JavaLuan.__index(this,obj,key); @@ -121,9 +126,41 @@ } public LuanFunction getHandlerFunction(String op,LuanTable t) throws LuanException { - Object f = t.getHandler(this,op); + Object f = t.getHandler(op); if( f == null ) return null; return Luan.checkFunction(f); } + + public LuanTable toTable(Object obj) { + if( obj == null ) + return null; + if( obj instanceof LuanTable ) + return (LuanTable)obj; + if( obj instanceof List ) { + return new LuanTable(this,(List)obj); + } + if( obj instanceof Map ) { + return new LuanTable(this,(Map)obj); + } + if( obj instanceof Set ) { + return new LuanTable(this,(Set)obj); + } + Class cls = obj.getClass(); + if( cls.isArray() ) { + if( cls.getComponentType().isPrimitive() ) { + int len = Array.getLength(obj); + List list = new ArrayList(); + for( int i=0; i<len; i++ ) { + list.add(Array.get(obj,i)); + } + return new LuanTable(this,list); + } else { + Object[] a = (Object[])obj; + return new LuanTable(this,Arrays.asList(a)); + } + } + return null; + } + }
--- a/src/luan/LuanTable.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/LuanTable.java Mon Nov 12 02:10:41 2018 -0700 @@ -14,15 +14,18 @@ public final class LuanTable implements LuanCloneable { + private LuanState luan; private Map map = null; private List list = null; private LuanTable metatable = null; public LuanJavaOk javaOk; private LuanCloner cloner; - public LuanTable() {} + public LuanTable(LuanState luan) { + this.luan = luan; + } - public LuanTable(List list) { + public LuanTable(LuanState luan,List list) { int n = list.size(); for( int i=0; i<n; i++ ) { Object val = list.get(i); @@ -31,7 +34,8 @@ } } - public LuanTable(Map map) { + public LuanTable(LuanState luan,Map map) { + this.luan = luan; for( Object stupid : map.entrySet() ) { Map.Entry entry = (Map.Entry)stupid; Object key = entry.getKey(); @@ -41,7 +45,8 @@ } } - public LuanTable(Set set) { + public LuanTable(LuanState luan,Set set) { + this.luan = luan; for( Object el : set ) { if( el != null ) rawPut(el,Boolean.TRUE); @@ -49,6 +54,7 @@ } public LuanTable(LuanTable tbl) { + this.luan = tbl.luan; if( tbl.map != null && !tbl.map.isEmpty() ) this.map = new LinkedHashMap<Object,Object>(tbl.map); if( tbl.rawLength() > 0 ) @@ -57,7 +63,7 @@ } @Override public LuanTable shallowClone() { - return new LuanTable(); + return new LuanTable(luan); } @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { @@ -85,6 +91,7 @@ } private void deepenClone(LuanTable clone,LuanCloner cloner) { + clone.luan = (LuanState)cloner.clone(luan); if( map != null ) { Map newMap = newMap(); for( Object stupid : map.entrySet() ) { @@ -118,8 +125,8 @@ return map!=null ? map : Collections.emptyMap(); } - public String toString(LuanState luan) throws LuanException { - Object h = getHandler(luan,"__to_string"); + public String toStringLuan() throws LuanException { + Object h = getHandler("__to_string"); if( h == null ) return rawToString(); LuanFunction fn = Luan.checkFunction(h); @@ -130,11 +137,11 @@ return "table: " + Integer.toHexString(hashCode()); } - public Object get(LuanState luan,Object key) throws LuanException { + public Object get(Object key) throws LuanException { Object value = rawGet(key); if( value != null ) return value; - Object h = getHandler(luan,"__index"); + Object h = getHandler("__index"); if( h==null ) return null; if( h instanceof LuanFunction ) { @@ -163,8 +170,8 @@ return map.get(key); } - public void put(LuanState luan,Object key,Object value) throws LuanException { - Object h = getHandler(luan,"__new_index"); + public void put(Object key,Object value) throws LuanException { + Object h = getHandler("__new_index"); if( h==null || rawGet(key)!=null ) { rawPut(key,value); return; @@ -176,7 +183,7 @@ } if( h instanceof LuanTable ) { LuanTable tbl = (LuanTable)h; - tbl.put(luan,key,value); + tbl.put(key,value); return; } throw new LuanException("invalid type "+Luan.type(h)+" for metamethod __new_index"); @@ -267,8 +274,8 @@ Collections.sort(list(),cmp); } - public int length(LuanState luan) throws LuanException { - Object h = getHandler(luan,"__len"); + public int length() throws LuanException { + Object h = getHandler("__len"); if( h != null ) { LuanFunction fn = Luan.checkFunction(h); return (Integer)Luan.first(fn.call(luan,new Object[]{this})); @@ -281,8 +288,8 @@ return list==null ? 0 : list.size(); } - public Iterable<Map.Entry> iterable(LuanState luan) throws LuanException { - final Iterator<Map.Entry> iter = iterator(luan); + public Iterable<Map.Entry> iterable() throws LuanException { + final Iterator<Map.Entry> iter = iterator(); return new Iterable<Map.Entry>() { public Iterator<Map.Entry> iterator() { return iter; @@ -299,10 +306,10 @@ }; } - public Iterator<Map.Entry> iterator(final LuanState luan) throws LuanException { - if( getHandler(luan,"__pairs") == null ) + public Iterator<Map.Entry> iterator() throws LuanException { + if( getHandler("__pairs") == null ) return rawIterator(); - final LuanFunction fn = pairs(luan); + final LuanFunction fn = pairs(); return new Iterator<Map.Entry>() { private Map.Entry<Object,Object> next = getNext(); @@ -336,8 +343,8 @@ }; } - public LuanFunction pairs(LuanState luan) throws LuanException { - Object h = getHandler(luan,"__pairs"); + public LuanFunction pairs() throws LuanException { + Object h = getHandler("__pairs"); if( h != null ) { if( h instanceof LuanFunction ) { LuanFunction fn = (LuanFunction)h; @@ -420,7 +427,7 @@ public LuanTable rawSubList(int from,int to) { check(); - LuanTable tbl = new LuanTable(); + LuanTable tbl = new LuanTable(luan); tbl.list = new ArrayList<Object>(list().subList(from-1,to-1)); return tbl; } @@ -435,34 +442,34 @@ this.metatable = metatable; } - public Object getHandler(LuanState luan,String op) throws LuanException { + public Object getHandler(String op) throws LuanException { check(); - return metatable==null ? null : metatable.get(luan,op); + return metatable==null ? null : metatable.get(op); } private Map<Object,Object> newMap() { return new LinkedHashMap<Object,Object>(); } - public boolean isSet(LuanState luan) throws LuanException { - for( Map.Entry<Object,Object> entry : iterable(luan) ) { + public boolean isSet() throws LuanException { + for( Map.Entry<Object,Object> entry : iterable() ) { if( !entry.getValue().equals(Boolean.TRUE) ) return false; } return true; } - public Set<Object> asSet(LuanState luan) throws LuanException { + public Set<Object> asSet() throws LuanException { Set<Object> set = new HashSet<Object>(); - for( Map.Entry<Object,Object> entry : iterable(luan) ) { + for( Map.Entry<Object,Object> entry : iterable() ) { set.add(entry.getKey()); } return set; } - public Map<Object,Object> asMap(LuanState luan) throws LuanException { + public Map<Object,Object> asMap() throws LuanException { Map<Object,Object> map = newMap(); - for( Map.Entry<Object,Object> entry : iterable(luan) ) { + for( Map.Entry<Object,Object> entry : iterable() ) { map.put(entry.getKey(),entry.getValue()); } return map; @@ -495,4 +502,14 @@ n += list.size(); return n; } + + protected void finalize() throws Throwable { + Object h = getHandler("__gc"); + if( h != null ) { + LuanFunction fn = Luan.checkFunction(h); + fn.call(luan,new Object[]{this}); + } + super.finalize(); + } + }
--- a/src/luan/impl/LuanImpl.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/impl/LuanImpl.java Mon Nov 12 02:10:41 2018 -0700 @@ -14,7 +14,7 @@ public final class LuanImpl { private LuanImpl() {} // never - public static int len(LuanState luan,Object o) throws LuanException { + public static int len(Object o) throws LuanException { if( o instanceof String ) { String s = (String)o; return s.length(); @@ -25,7 +25,7 @@ } if( o instanceof LuanTable ) { LuanTable t = (LuanTable)o; - return t.length(luan); + return t.length(); } throw new LuanException( "attempt to get length of a " + Luan.type(o) + " value" ); } @@ -159,7 +159,7 @@ public static void put(LuanState luan,Object t,Object key,Object value) throws LuanException { if( t instanceof LuanTable ) { LuanTable tbl = (LuanTable)t; - tbl.put(luan,key,value); + tbl.put(key,value); return; } if( t != null && luan.javaOk.ok ) @@ -229,8 +229,8 @@ } } - public static LuanTable table(Object[] a) { - LuanTable table = new LuanTable(); + public static LuanTable table(LuanState luan,Object[] a) { + LuanTable table = new LuanTable(luan); int i = 0; for( Object fld : a ) { if( fld instanceof TableField ) {
--- a/src/luan/impl/LuanParser.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/impl/LuanParser.java Mon Nov 12 02:10:41 2018 -0700 @@ -1011,7 +1011,7 @@ Spaces(); Expr exp = required(UnaryExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); - newExp.add( "LuanImpl.len(luan," ); + newExp.add( "LuanImpl.len(" ); newExp.addAll( exp ); newExp.add( ")" ); return parser.success(newExp); @@ -1143,7 +1143,7 @@ if( !parser.match('{') ) return parser.failure(null); Expr tblExp = new Expr(Val.SINGLE,false); - tblExp.add( "LuanImpl.table(" ); + tblExp.add( "LuanImpl.table(luan," ); Expr lastExp = tblExp; List<Expr> builder = new ArrayList<Expr>(); /*
--- a/src/luan/modules/BasicLuan.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/BasicLuan.java Mon Nov 12 02:10:41 2018 -0700 @@ -43,9 +43,9 @@ return load(src,fileName,null); } - public static LuanFunction pairs(final LuanState luan,final LuanTable t) throws LuanException { + public static LuanFunction pairs(final LuanTable t) throws LuanException { Utils.checkNotNull(t); - return t.pairs(luan); + return t.pairs(); } public static LuanFunction ipairs(final LuanTable t) throws LuanException { @@ -73,9 +73,9 @@ return obj!=null ? obj : metatable; } - public static void set_metatable(LuanState luan,LuanTable table,LuanTable metatable) throws LuanException { + public static void set_metatable(LuanTable table,LuanTable metatable) throws LuanException { Utils.checkNotNull(table); - if( table.getHandler(luan,"__metatable") != null ) + if( table.getHandler("__metatable") != null ) throw new LuanException("cannot change a protected metatable"); table.setMetatable(metatable); } @@ -110,7 +110,7 @@ public static LuanTable new_error(LuanState luan,Object msg) throws LuanException { String s = luan.toString(msg); - LuanTable tbl = new LuanException(s).table(); + LuanTable tbl = new LuanException(s).table(luan); tbl.rawPut( "message", msg ); return tbl; } @@ -166,21 +166,21 @@ public static Object try_(LuanState luan,LuanTable blocks,Object... args) throws LuanException { Utils.checkNotNull(blocks); - Object obj = blocks.get(luan,1); + Object obj = blocks.get(1); if( obj == null ) throw new LuanException("missing 'try' value"); if( !(obj instanceof LuanFunction) ) throw new LuanException("bad 'try' value (function expected, got "+Luan.type(obj)+")"); LuanFunction tryFn = (LuanFunction)obj; LuanFunction catchFn = null; - obj = blocks.get(luan,"catch"); + obj = blocks.get("catch"); if( obj != null ) { if( !(obj instanceof LuanFunction) ) throw new LuanException("bad 'catch' value (function expected, got "+Luan.type(obj)+")"); catchFn = (LuanFunction)obj; } LuanFunction finallyFn = null; - obj = blocks.get(luan,"finally"); + obj = blocks.get("finally"); if( obj != null ) { if( !(obj instanceof LuanFunction) ) throw new LuanException("bad 'finally' value (function expected, got "+Luan.type(obj)+")"); @@ -191,7 +191,7 @@ } catch(LuanException e) { if( catchFn == null ) throw e; - return catchFn.call(luan,new Object[]{e.table()}); + return catchFn.call(luan,new Object[]{e.table(luan)}); } finally { if( finallyFn != null ) finallyFn.call(luan); @@ -208,7 +208,7 @@ } return rtn; } catch(LuanException e) { - return new Object[]{false,e.table()}; + return new Object[]{false,e.table(luan)}; } }
--- a/src/luan/modules/IoLuan.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/IoLuan.java Mon Nov 12 02:10:41 2018 -0700 @@ -79,8 +79,8 @@ }; } - public static LuanTable textWriter(final PrintStream out) { - return writer(luanWriter(out)); + public static LuanTable textWriter(LuanState luan,final PrintStream out) { + return writer(luan,luanWriter(out)); } private static LuanWriter luanWriter(final Writer out) { @@ -102,12 +102,12 @@ }; } - public static LuanTable textWriter(final Writer out) { - return writer(luanWriter(out)); + public static LuanTable textWriter(LuanState luan,final Writer out) { + return writer(luan,luanWriter(out)); } - private static LuanTable writer(LuanWriter luanWriter) { - LuanTable writer = new LuanTable(); + private static LuanTable writer(LuanState luan,LuanWriter luanWriter) { + LuanTable writer = new LuanTable(luan); writer.rawPut( "java", luanWriter.out() ); try { writer.rawPut( "write", new LuanJavaFunction( @@ -123,8 +123,8 @@ } - public static LuanTable binaryWriter(final OutputStream out) { - LuanTable writer = new LuanTable(); + public static LuanTable binaryWriter(LuanState luan,final OutputStream out) { + LuanTable writer = new LuanTable(luan); writer.rawPut( "java", out ); try { writer.rawPut( "write", new LuanJavaFunction( @@ -202,40 +202,40 @@ public static abstract class LuanIn { - public abstract InputStream inputStream() throws IOException, LuanException; + public abstract InputStream inputStream(LuanState luan) throws IOException, LuanException; public abstract String to_string(); public abstract String to_uri_string(); - public Reader reader() throws IOException, LuanException { - return new InputStreamReader(inputStream()); + public Reader reader(LuanState luan) throws IOException, LuanException { + return new InputStreamReader(inputStream(luan)); } - public String read_text() throws IOException, LuanException { - Reader in = reader(); + public String read_text(LuanState luan) throws IOException, LuanException { + Reader in = reader(luan); String s = Utils.readAll(in); in.close(); return s; } - public byte[] read_binary() throws IOException, LuanException { - InputStream in = inputStream(); + public byte[] read_binary(LuanState luan) throws IOException, LuanException { + InputStream in = inputStream(luan); byte[] a = Utils.readAll(in); in.close(); return a; } - public LuanFunction read_lines() throws IOException, LuanException { - return lines(new BufferedReader(reader())); + public LuanFunction read_lines(LuanState luan) throws IOException, LuanException { + return lines(new BufferedReader(reader(luan))); } - public LuanFunction read_blocks(Integer blockSize) throws IOException, LuanException { + public LuanFunction read_blocks(LuanState luan,Integer blockSize) throws IOException, LuanException { int n = blockSize!=null ? blockSize : Utils.bufSize; - return blocks(inputStream(),n); + return blocks(inputStream(luan),n); } - public boolean exists() throws IOException, LuanException { + public boolean exists(LuanState luan) throws IOException, LuanException { try { - inputStream().close(); + inputStream(luan).close(); return true; } catch(FileNotFoundException e) { return false; @@ -244,9 +244,9 @@ } } - public long checksum() throws IOException, LuanException { + public long checksum(LuanState luan) throws IOException, LuanException { long cs = 0; - InputStream in = new BufferedInputStream(inputStream()); + InputStream in = new BufferedInputStream(inputStream(luan)); int c; while( (c=in.read()) != -1 ) { cs = 31 * cs + c; @@ -255,8 +255,8 @@ return cs; } - public LuanTable table() { - LuanTable tbl = new LuanTable(); + public LuanTable table(LuanState luan) { + LuanTable tbl = new LuanTable(luan); try { tbl.rawPut( "java", this ); tbl.rawPut( "to_string", new LuanJavaFunction( @@ -266,22 +266,22 @@ LuanIn.class.getMethod( "to_uri_string" ), this ) ); tbl.rawPut( "read_text", new LuanJavaFunction( - LuanIn.class.getMethod( "read_text" ), this + LuanIn.class.getMethod( "read_text", LuanState.class ), this ) ); tbl.rawPut( "read_binary", new LuanJavaFunction( - LuanIn.class.getMethod( "read_binary" ), this + LuanIn.class.getMethod( "read_binary", LuanState.class ), this ) ); tbl.rawPut( "read_lines", new LuanJavaFunction( - LuanIn.class.getMethod( "read_lines" ), this + LuanIn.class.getMethod( "read_lines", LuanState.class ), this ) ); tbl.rawPut( "read_blocks", new LuanJavaFunction( - LuanIn.class.getMethod( "read_blocks", Integer.class ), this + LuanIn.class.getMethod( "read_blocks", LuanState.class, Integer.class ), this ) ); tbl.rawPut( "exists", new LuanJavaFunction( - LuanIn.class.getMethod( "exists" ), this + LuanIn.class.getMethod( "exists", LuanState.class ), this ) ); tbl.rawPut( "checksum", new LuanJavaFunction( - LuanIn.class.getMethod( "checksum" ), this + LuanIn.class.getMethod( "checksum", LuanState.class ), this ) ); } catch(NoSuchMethodException e) { throw new RuntimeException(e); @@ -292,7 +292,7 @@ public static final LuanIn defaultStdin = new LuanIn() { - @Override public InputStream inputStream() { + @Override public InputStream inputStream(LuanState luan) { return System.in; } @@ -304,15 +304,15 @@ return "stdin:"; } - @Override public String read_text() throws IOException { + @Override public String read_text(LuanState luan) throws IOException { return Utils.readAll(new InputStreamReader(System.in)); } - @Override public byte[] read_binary() throws IOException { + @Override public byte[] read_binary(LuanState luan) throws IOException { return Utils.readAll(System.in); } - @Override public boolean exists() { + @Override public boolean exists(LuanState luan) { return true; } }; @@ -320,7 +320,7 @@ public static abstract class LuanIO extends LuanIn { abstract OutputStream outputStream() throws IOException; - public void write(Object obj) throws LuanException, IOException { + public void write(LuanState luan,Object obj) throws LuanException, IOException { if( obj instanceof String ) { String s = (String)obj; Writer out = new OutputStreamWriter(outputStream()); @@ -340,7 +340,7 @@ Object java = t.rawGet("java"); if( java instanceof LuanIn ) { LuanIn luanIn = (LuanIn)java; - InputStream in = luanIn.inputStream(); + InputStream in = luanIn.inputStream(luan); OutputStream out = outputStream(); Utils.copyAll(in,out); out.close(); @@ -351,12 +351,12 @@ throw new LuanException( "bad argument #1 to 'write' (string or binary or Io.uri expected)" ); } - public LuanTable text_writer() throws IOException { - return textWriter(new BufferedWriter(new OutputStreamWriter(outputStream()))); + public LuanTable text_writer(LuanState luan) throws IOException { + return textWriter(luan,new BufferedWriter(new OutputStreamWriter(outputStream()))); } - public LuanTable binary_writer() throws IOException { - return binaryWriter(new BufferedOutputStream(outputStream())); + public LuanTable binary_writer(LuanState luan) throws IOException { + return binaryWriter(luan,new BufferedOutputStream(outputStream())); } public void write_text(LuanState luan,Object... args) throws LuanException, IOException { @@ -365,17 +365,17 @@ luanWriter.close(); } - @Override public LuanTable table() { - LuanTable tbl = super.table(); + @Override public LuanTable table(LuanState luan) { + LuanTable tbl = super.table(luan); try { tbl.rawPut( "write", new LuanJavaFunction( - LuanIO.class.getMethod( "write", Object.class ), this + LuanIO.class.getMethod( "write", LuanState.class, Object.class ), this ) ); tbl.rawPut( "text_writer", new LuanJavaFunction( - LuanIO.class.getMethod( "text_writer" ), this + LuanIO.class.getMethod( "text_writer", LuanState.class ), this ) ); tbl.rawPut( "binary_writer", new LuanJavaFunction( - LuanIO.class.getMethod( "binary_writer" ), this + LuanIO.class.getMethod( "binary_writer", LuanState.class ), this ) ); tbl.rawPut( "write_text", new LuanJavaFunction( LuanIO.class.getMethod( "write_text", LuanState.class, new Object[0].getClass() ), this @@ -397,7 +397,7 @@ @Override public void write(int b) {} }; - @Override public InputStream inputStream() { + @Override public InputStream inputStream(LuanState luan) { return in; } @@ -422,7 +422,7 @@ this.s = s; } - @Override public InputStream inputStream() { + @Override public InputStream inputStream(LuanState luan) { throw new UnsupportedOperationException(); } @@ -438,19 +438,19 @@ return "string:" + s; } - @Override public Reader reader() { + @Override public Reader reader(LuanState luan) { return new StringReader(s); } - @Override public String read_text() { + @Override public String read_text(LuanState luan) { return s; } - @Override public boolean exists() { + @Override public boolean exists(LuanState luan) { return true; } - @Override public LuanTable text_writer() throws IOException { + @Override public LuanTable text_writer(LuanState luan) throws IOException { LuanWriter luanWriter = new LuanWriter() { private final Writer out = new StringWriter(); @@ -468,7 +468,7 @@ s = out.toString(); } }; - return writer(luanWriter); + return writer(luan,luanWriter); } } @@ -484,7 +484,7 @@ this.file = file; } - @Override public InputStream inputStream() throws IOException { + @Override public InputStream inputStream(LuanState luan) throws IOException { return new FileInputStream(file); } @@ -501,16 +501,16 @@ } public LuanTable child(LuanState luan,String name) throws LuanException { - return new LuanFile(luan,new File(file,name)).table(); + return new LuanFile(luan,new File(file,name)).table(luan); } public LuanTable children(LuanState luan) throws LuanException { File[] files = file.listFiles(); if( files==null ) return null; - LuanTable list = new LuanTable(); + LuanTable list = new LuanTable(luan); for( File f : files ) { - list.rawPut(list.rawLength()+1,new LuanFile(luan,f).table()); + list.rawPut(list.rawLength()+1,new LuanFile(luan,f).table(luan)); } return list; } @@ -519,10 +519,10 @@ File parent = file.getParentFile(); if( parent==null ) parent = file.getCanonicalFile().getParentFile(); - return new LuanFile(luan,parent).table(); + return new LuanFile(luan,parent).table(luan); } - @Override public boolean exists() { + @Override public boolean exists(LuanState luan) { return file.exists(); } @@ -535,12 +535,12 @@ } public LuanTable canonical(LuanState luan) throws LuanException, IOException { - return new LuanFile(luan,file.getCanonicalFile()).table(); + return new LuanFile(luan,file.getCanonicalFile()).table(luan); } public LuanTable create_temp_file(LuanState luan,String prefix,String suffix) throws LuanException, IOException { File tmp = File.createTempFile(prefix,suffix,file); - return new LuanFile(luan,tmp).table(); + return new LuanFile(luan,tmp).table(luan); } public void delete() throws LuanException { @@ -571,8 +571,8 @@ throw new LuanException("couldn't set_last_modified on "+file); } - @Override public LuanTable table() { - LuanTable tbl = super.table(); + @Override public LuanTable table(LuanState luan) { + LuanTable tbl = super.table(luan); try { tbl.rawPut( "name", new LuanJavaFunction( File.class.getMethod( "getName" ), file @@ -626,18 +626,18 @@ } } - public static LuanTable null_(String ignore) { - return nullIO.table(); + public static LuanTable null_(LuanState luan,String ignore) { + return nullIO.table(luan); } - public static LuanTable string(String s) throws LuanException { + public static LuanTable string(LuanState luan,String s) throws LuanException { Utils.checkNotNull(s); - return new LuanString(s).table(); + return new LuanString(s).table(luan); } public static LuanTable file(LuanState luan,String name) throws LuanException { File file = new File(name); - return new LuanFile(luan,file).table(); + return new LuanFile(luan,file).table(luan); } public static LuanTable classpath(LuanState luan,String name) throws LuanException { @@ -666,13 +666,13 @@ } } if( url != null ) - return new LuanUrl(luan,url,null).table(); + return new LuanUrl(url,null).table(luan); return null; } private static LuanTable url(LuanState luan,String url,LuanTable options) throws IOException, LuanException { - return new LuanUrl(luan,new URL(url),options).table(); + return new LuanUrl(new URL(url),options).table(luan); } public static LuanTable http(LuanState luan,String path,LuanTable options) throws IOException, LuanException { @@ -689,14 +689,14 @@ public static LuanTable stdin(LuanState luan) throws LuanException { LuanTable io = (LuanTable)PackageLuan.require(luan,"luan:Io.luan"); - return (LuanTable)io.get(luan,"stdin"); + return (LuanTable)io.get("stdin"); } - public static LuanTable newSchemes() { - LuanTable schemes = new LuanTable(); + public static LuanTable newSchemes(LuanState luan) { + LuanTable schemes = new LuanTable(luan); try { - schemes.rawPut( "null", new LuanJavaFunction(IoLuan.class.getMethod("null_",String.class),null) ); - add( schemes, "string", String.class ); + schemes.rawPut( "null", new LuanJavaFunction(IoLuan.class.getMethod("null_",LuanState.class,String.class),null) ); + add( schemes, "string", LuanState.class, String.class ); add( schemes, "file", LuanState.class, String.class ); add( schemes, "classpath", LuanState.class, String.class ); // add( schemes, "socket", String.class ); @@ -715,10 +715,10 @@ private static LuanTable schemes(LuanState luan) throws LuanException { LuanTable t = (LuanTable)PackageLuan.loaded(luan).rawGet("luan:Io.luan"); if( t == null ) - return newSchemes(); - t = (LuanTable)t.get(luan,"schemes"); + return newSchemes(luan); + t = (LuanTable)t.get("schemes"); if( t == null ) - return newSchemes(); + return newSchemes(luan); return t; } @@ -729,7 +729,7 @@ String scheme = name.substring(0,i); String location = name.substring(i+1); LuanTable schemes = schemes(luan); - LuanFunction opener = (LuanFunction)schemes.get(luan,scheme); + LuanFunction opener = (LuanFunction)schemes.get(scheme); if( opener == null ) throw new LuanException( "invalid scheme '"+scheme+"' in '"+name+"'" ); return (LuanTable)Luan.first(opener.call(luan,new Object[]{location,options})); @@ -802,11 +802,11 @@ final File dir; Process proc; - private BaseOs(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { + private BaseOs(String cmd,LuanTable options) throws IOException, LuanException { this.cmd = cmd; File dir = null; if( options != null ) { - Map map = options.asMap(luan); + Map map = options.asMap(); Object obj = map.remove("dir"); dir = objToFile(obj); if( dir==null ) @@ -817,7 +817,7 @@ this.dir = dir; } - @Override public InputStream inputStream() throws IOException { + @Override public InputStream inputStream(LuanState luan) throws IOException { return proc.getInputStream(); } @@ -833,7 +833,7 @@ throw new UnsupportedOperationException(); } - @Override public boolean exists() { + @Override public boolean exists(LuanState luan) { return true; } @@ -854,14 +854,14 @@ } } - @Override public String read_text() throws IOException, LuanException { - String s = super.read_text(); + @Override public String read_text(LuanState luan) throws IOException, LuanException { + String s = super.read_text(luan); wait_for(); return s; } - @Override public LuanTable table() { - LuanTable tbl = super.table(); + @Override public LuanTable table(LuanState luan) { + LuanTable tbl = super.table(luan); try { tbl.rawPut( "wait_for", new LuanJavaFunction( BaseOs.class.getMethod( "wait_for" ), this @@ -875,26 +875,26 @@ public static final class LuanOs extends BaseOs { private LuanOs(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { - super(luan,cmd,options); + super(cmd,options); check(luan,"os:"+cmd); this.proc = Runtime.getRuntime().exec(cmd,null,dir); } } public static LuanTable os(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { - return new LuanOs(luan,cmd,options).table(); + return new LuanOs(luan,cmd,options).table(luan); } public static final class LuanBash extends BaseOs { private LuanBash(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { - super(luan,cmd,options); + super(cmd,options); check(luan,"bash:"+cmd); this.proc = Runtime.getRuntime().exec(new String[]{"bash","-c",cmd},null,dir); } } public static LuanTable bash(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { - return new LuanBash(luan,cmd,options).table(); + return new LuanBash(luan,cmd,options).table(luan); } @@ -906,7 +906,7 @@ this.in = in; } - @Override public InputStream inputStream() { + @Override public InputStream inputStream(LuanState luan) { return in; } @@ -918,7 +918,7 @@ throw new UnsupportedOperationException(); } - @Override public boolean exists() { + @Override public boolean exists(LuanState luan) { return true; } }; @@ -932,8 +932,8 @@ } } - public static LuanTable my_ips() throws IOException { - LuanTable tbl = new LuanTable(); + public static LuanTable my_ips(LuanState luan) throws IOException { + LuanTable tbl = new LuanTable(luan); for( Enumeration<NetworkInterface> e1 = NetworkInterface.getNetworkInterfaces(); e1.hasMoreElements(); ) { NetworkInterface ni = e1.nextElement(); for( Enumeration<InetAddress> e2 = ni.getInetAddresses(); e2.hasMoreElements(); ) {
--- a/src/luan/modules/JavaLuan.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/JavaLuan.java Mon Nov 12 02:10:41 2018 -0700 @@ -321,7 +321,7 @@ if( args==null ) args = new Object[0]; String name = method.getName(); - Object fnObj = t.get(luan,name); + Object fnObj = t.get(name); if( fnObj == null ) throw new NullPointerException("luan_proxy couldn't find method '"+name+"'"); LuanFunction fn = Luan.checkFunction(fnObj);
--- a/src/luan/modules/PackageLuan.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/PackageLuan.java Mon Nov 12 02:10:41 2018 -0700 @@ -26,7 +26,7 @@ public static LuanTable loaded(LuanState luan) { LuanTable tbl = (LuanTable)luan.registry().get("Package.loaded"); if( tbl == null ) { - tbl = new LuanTable(); + tbl = new LuanTable(luan); luan.registry().put("Package.loaded",tbl); } return tbl; @@ -83,9 +83,9 @@ */ IoLuan.LuanIn in = (IoLuan.LuanIn)t.rawGet("java"); try { - if( !in.exists() ) + if( !in.exists(luan) ) return null; - return in.read_text(); + return in.read_text(luan); } catch(IOException e) { throw new LuanException(e); }
--- a/src/luan/modules/StringLuan.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/StringLuan.java Mon Nov 12 02:10:41 2018 -0700 @@ -167,7 +167,7 @@ StringBuffer sb = new StringBuffer(); while( i<max && m.find() ) { String match = m.groupCount()==0 ? m.group() : m.group(1); - Object val = t.get(luan,match); + Object val = t.get(match); if( val != null ) { String replacement = luan.toString(val); m.appendReplacement(sb,replacement);
--- a/src/luan/modules/Table.luan Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/Table.luan Mon Nov 12 02:10:41 2018 -0700 @@ -20,8 +20,7 @@ local error = Luan.error local type = Luan.type or error() local pairs = Luan.pairs or error() -local LuanJava = require "java:luan.Luan" -local toTable = LuanJava.toTable or error() +local toTable = TableLuan.toTable or error() function Table.java_to_table_shallow(obj) local rtn = toTable(obj)
--- a/src/luan/modules/TableLuan.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/TableLuan.java Mon Nov 12 02:10:41 2018 -0700 @@ -17,10 +17,10 @@ public static String concat(LuanState luan,LuanTable list,String sep,Integer i,Integer j) throws LuanException { int first = i==null ? 1 : i; - int last = j==null ? list.length(luan) : j; + int last = j==null ? list.length() : j; StringBuilder buf = new StringBuilder(); for( int k=first; k<=last; k++ ) { - Object val = list.get(luan,k); + Object val = list.get(k); if( val==null ) break; if( sep!=null && k > first ) @@ -84,23 +84,23 @@ } } - public static LuanTable pack(Object... args) { - LuanTable tbl = new LuanTable(Arrays.asList(args)); + public static LuanTable pack(LuanState luan,Object... args) { + LuanTable tbl = new LuanTable(luan,Arrays.asList(args)); tbl.rawPut( "n", args.length ); return tbl; } - @LuanMethod public static Object[] unpack(LuanState luan,LuanTable tbl,Integer iFrom,Integer iTo) throws LuanException { + @LuanMethod public static Object[] unpack(LuanTable tbl,Integer iFrom,Integer iTo) throws LuanException { int from = iFrom!=null ? iFrom : 1; - int to = iTo!=null ? iTo : tbl.length(luan); + int to = iTo!=null ? iTo : tbl.length(); List<Object> list = new ArrayList<Object>(); for( int i=from; i<=to; i++ ) { - list.add( tbl.get(luan,i) ); + list.add( tbl.get(i) ); } return list.toArray(); } - public static LuanTable copy(LuanTable list,Integer from,Integer to) { + public static LuanTable copy(LuanState luan,LuanTable list,Integer from,Integer to) { if( from == null ) return new LuanTable(list); if( to == null ) @@ -124,4 +124,8 @@ return tbl.rawSize(); } + public static LuanTable toTable(LuanState luan,Object obj) { + return luan.toTable(obj); + } + }
--- a/src/luan/modules/ThreadLuan.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/ThreadLuan.java Mon Nov 12 02:10:41 2018 -0700 @@ -125,17 +125,17 @@ } } - private static Object makeSafe(Object v) { + private static Object makeSafe(LuanState luan,Object v) { if( v instanceof LuanTable ) { LuanTable tbl = (LuanTable)v; if( tbl.getMetatable() != null ) return new Unsafe("table with metatable"); - LuanTable rtn = new LuanTable(); + LuanTable rtn = new LuanTable(luan); for( Map.Entry entry : tbl.rawIterable() ) { - Object key = makeSafe( entry.getKey() ); + Object key = makeSafe( luan, entry.getKey() ); if( key instanceof Unsafe ) return key; - Object value = makeSafe( entry.getValue() ); + Object value = makeSafe( luan, entry.getValue() ); if( value instanceof Unsafe ) return value; rtn.rawPut(key,value); @@ -144,7 +144,7 @@ } else if( v instanceof Object[] ) { Object[] a = (Object[])v; for( int i=0; i<a.length; i++ ) { - Object obj = makeSafe(a[i]); + Object obj = makeSafe(luan,a[i]); if( obj instanceof Unsafe ) return obj; a[i] = obj; @@ -167,19 +167,19 @@ this.fns = (LuanTable)cloner.get(fns); } - public synchronized Object call(String fnName,Object... args) throws LuanException { - Object obj = makeSafe(args); + public synchronized Object call(LuanState callerLuan,String fnName,Object... args) throws LuanException { + Object obj = makeSafe(luan,args); if( obj instanceof Unsafe ) throw new LuanException("can't pass "+((Unsafe)obj).reason+" to global_callable "+Arrays.asList(args)); args = (Object[])obj; - Object f = fns.get(luan,fnName); + Object f = fns.get(fnName); if( f == null ) throw new LuanException("function '"+fnName+"' not found in global_callable"); if( !(f instanceof LuanFunction) ) throw new LuanException("value of '"+fnName+"' not a function in global_callable"); LuanFunction fn = (LuanFunction)f; Object rtn = fn.call(luan,args); - rtn = makeSafe(rtn); + rtn = makeSafe(callerLuan,rtn); if( rtn instanceof Unsafe ) throw new LuanException("can't return "+((Unsafe)rtn).reason+" from global_callable"); return rtn;
--- a/src/luan/modules/http/HttpServicer.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/http/HttpServicer.java Mon Nov 12 02:10:41 2018 -0700 @@ -35,7 +35,7 @@ } LuanTable module = (LuanTable)PackageLuan.require(luan,"luan:http/Http.luan"); LuanFunction fn = (LuanFunction)module.rawGet("handle_error"); - return (Response)fn.call( luan, new Object[]{request,e.table()} ); + return (Response)fn.call( luan, new Object[]{request,e.table(luan)} ); } private static Response serviceLuan(LuanState luan,Request request,String modName)
--- a/src/luan/modules/http/LuanHandler.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/http/LuanHandler.java Mon Nov 12 02:10:41 2018 -0700 @@ -137,8 +137,8 @@ synchronized(luan) { PackageLuan.enableLoad(luan,"luan:Rpc.luan"); LuanTable rpc = (LuanTable)PackageLuan.require(luan,"luan:Rpc.luan"); - LuanTable fns = (LuanTable)rpc.get(luan,"functions"); - fn = (LuanFunction)fns.get(luan,fnName); + LuanTable fns = (LuanTable)rpc.get("functions"); + fn = (LuanFunction)fns.get(fnName); if( fn == null ) throw new LuanException( "function not found: " + fnName ); LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL);
--- a/src/luan/modules/lucene/LuceneIndex.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/lucene/LuceneIndex.java Mon Nov 12 02:10:41 2018 -0700 @@ -94,7 +94,7 @@ private final ThreadLocal<IndexSearcher> threadLocalSearcher = new ThreadLocal<IndexSearcher>(); private boolean isClosed = true; private final MultiFieldParser mfp; - public final LuanTable indexed_only_fields = new LuanTable(); + public final LuanTable indexed_only_fields; private final Analyzer analyzer; private final Exception created = new Exception("created"); @@ -102,7 +102,10 @@ private File fileDir; private int writeCount; - public LuceneIndex(LuanState luan,String indexDirStr,FieldParser defaultFieldParser,String[] defaultFields) throws LuanException, IOException { + public LuceneIndex(LuanState luan,String indexDirStr,FieldParser defaultFieldParser,String[] defaultFields) + throws LuanException, IOException + { + indexed_only_fields = new LuanTable(luan); // not good, not thread safe mfp = defaultFieldParser==null ? new MultiFieldParser() : new MultiFieldParser(defaultFieldParser,defaultFields); mfp.fields.put( "type", STRING_FIELD_PARSER ); mfp.fields.put( "id", NumberFieldParser.LONG ); @@ -177,18 +180,18 @@ public void save(LuanState luan,LuanTable doc) throws LuanException, IOException { Set indexedOnlySet = new HashSet(); - Object typeObj = doc.get(luan,"type"); + Object typeObj = doc.get("type"); if( typeObj==null ) throw new LuanException("missing 'type' field"); if( !(typeObj instanceof String) ) throw new LuanException("type must be string"); String type = (String)typeObj; - Object indexedOnlyObj = indexed_only_fields.get(luan,type); + Object indexedOnlyObj = indexed_only_fields.get(type); if( indexedOnlyObj != null ) { if( !(indexedOnlyObj instanceof LuanTable) ) throw new LuanException("indexed_only_fields elements must be tables"); LuanTable indexedOnly = (LuanTable)indexedOnlyObj; - for( Map.Entry<Object,Object> entry : indexedOnly.iterable(luan) ) { + for( Map.Entry<Object,Object> entry : indexedOnly.iterable() ) { Object key = entry.getKey(); if( !(key instanceof String) ) throw new LuanException("indexed_only_fields."+type+" entries must be strings"); @@ -198,11 +201,11 @@ throw new LuanException("indexed_only_fields."+type+" values must be functions"); LuanFunction fn = (LuanFunction)value; value = Luan.first(fn.call(luan,new Object[]{doc})); - doc.put(luan, name, value ); + doc.put( name, value ); indexedOnlySet.add(name); } } - Object obj = doc.get(luan,"id"); + Object obj = doc.get("id"); Long id; try { id = (Long)obj; @@ -215,10 +218,10 @@ try { if( id == null ) { id = nextId(luan); - doc.put(luan,"id",id); - writer.addDocument(toLucene(luan,doc,indexedOnlySet)); + doc.put("id",id); + writer.addDocument(toLucene(doc,indexedOnlySet)); } else { - writer.updateDocument( term("id",id), toLucene(luan,doc,indexedOnlySet) ); + writer.updateDocument( term("id",id), toLucene(doc,indexedOnlySet) ); } if(commit) writer.commit(); } finally { @@ -277,10 +280,10 @@ public synchronized long nextId(LuanState luan) throws LuanException, IOException { if( ++id > idLim ) { idLim += idBatch; - LuanTable doc = new LuanTable(); + LuanTable doc = new LuanTable(luan); doc.rawPut( "type", "next_id" ); doc.rawPut( FLD_NEXT_ID, idLim ); - writer.updateDocument(new Term("type","next_id"),toLucene(luan,doc,Collections.EMPTY_SET)); + writer.updateDocument(new Term("type","next_id"),toLucene(doc,Collections.EMPTY_SET)); wrote(); } return id; @@ -314,7 +317,7 @@ IndexCommit ic = snapshotDeletionPolicy.snapshot(); try { String dir = fileDir.toString(); - LuanTable fileNames = new LuanTable(new ArrayList(ic.getFileNames())); + LuanTable fileNames = new LuanTable(luan,new ArrayList(ic.getFileNames())); return fn.call(luan,new Object[]{dir,fileNames}); } finally { snapshotDeletionPolicy.release(ic); @@ -355,7 +358,7 @@ @Override public Object call(LuanState luan,Object[] args) throws LuanException { try { - return toTable(searcher.doc(docID)); + return toTable(luan,searcher.doc(docID)); } catch(IOException e) { throw new LuanException(e); } @@ -518,10 +521,10 @@ throw new LuanException("invalid value type "+value.getClass()+"' for '"+name+"'"); } - private Document toLucene(LuanState luan,LuanTable table,Set indexOnly) throws LuanException { + private Document toLucene(LuanTable table,Set indexOnly) throws LuanException { Set<String> indexed = mfp.fields.keySet(); Document doc = new Document(); - for( Map.Entry<Object,Object> entry : table.iterable(luan) ) { + for( Map.Entry<Object,Object> entry : table.iterable() ) { Object key = entry.getKey(); if( !(key instanceof String) ) throw new LuanException("key must be string"); @@ -553,10 +556,10 @@ throw new LuanException("invalid field type for "+ifld); } - private static LuanTable toTable(Document doc) throws LuanException { + private static LuanTable toTable(LuanState luan,Document doc) throws LuanException { if( doc==null ) return null; - LuanTable table = new LuanTable(); + LuanTable table = new LuanTable(luan); for( IndexableField ifld : doc ) { String name = ifld.name(); Object value = getValue(ifld); @@ -568,7 +571,7 @@ if( old instanceof LuanTable ) { list = (LuanTable)old; } else { - list = new LuanTable(); + list = new LuanTable(luan); list.rawPut(1,old); table.rawPut(name,list); }
--- a/src/luan/modules/mail/SmtpCon.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/mail/SmtpCon.java Mon Nov 12 02:10:41 2018 -0700 @@ -24,8 +24,8 @@ public final class SmtpCon { private final Session session; - public SmtpCon(LuanState luan,LuanTable paramsTbl) throws LuanException { - Map<Object,Object> params = new HashMap<Object,Object>(paramsTbl.asMap(luan)); + public SmtpCon(LuanTable paramsTbl) throws LuanException { + Map<Object,Object> params = new HashMap<Object,Object>(paramsTbl.asMap()); Properties props = new Properties(System.getProperties()); String host = getString(params,"host"); @@ -71,7 +71,7 @@ throw new LuanException( "unrecognized parameters: "+params ); } - private String getString(Map<Object,Object> params,String key) throws LuanException { + private static String getString(Map<Object,Object> params,String key) throws LuanException { Object val = params.remove(key); if( val!=null && !(val instanceof String) ) throw new LuanException( "parameter '"+key+"' must be a string" ); @@ -79,9 +79,9 @@ } - public void send(LuanState luan,LuanTable mailTbl) throws LuanException { + public void send(LuanTable mailTbl) throws LuanException { try { - Map<Object,Object> mailParams = new HashMap<Object,Object>(mailTbl.asMap(luan)); + Map<Object,Object> mailParams = new HashMap<Object,Object>(mailTbl.asMap()); MimeMessage msg = new MimeMessage(session); String from = getString(mailParams,"from"); @@ -113,7 +113,7 @@ bodyPart.setText((String)body); } else if( body instanceof LuanTable ) { LuanTable bodyTbl = (LuanTable)body; - Map<Object,Object> map = new HashMap<Object,Object>(bodyTbl.asMap(luan)); + Map<Object,Object> map = new HashMap<Object,Object>(bodyTbl.asMap()); MimeMultipart mp = new MimeMultipart("alternative"); String text = (String)map.remove("text"); if( text != null ) { @@ -146,7 +146,7 @@ for( Object attachment : attachmentsTbl.asList() ) { if( !(attachment instanceof LuanTable) ) throw new LuanException( "each attachment must be a table" ); - Map<Object,Object> attachmentMap = new HashMap<Object,Object>(((LuanTable)attachment).asMap(luan)); + Map<Object,Object> attachmentMap = new HashMap<Object,Object>(((LuanTable)attachment).asMap()); Object obj; obj = attachmentMap.remove("filename");
--- a/src/luan/modules/parsers/Csv.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/parsers/Csv.java Mon Nov 12 02:10:41 2018 -0700 @@ -1,5 +1,6 @@ package luan.modules.parsers; +import luan.LuanState; import luan.LuanTable; import luan.lib.parser.Parser; import luan.lib.parser.ParseException; @@ -7,8 +8,8 @@ public final class Csv { - public static LuanTable toList(String line) throws ParseException { - return new Csv(line).parse(); + public static LuanTable toList(LuanState luan,String line) throws ParseException { + return new Csv(line).parse(luan); } private final Parser parser; @@ -21,8 +22,8 @@ return new ParseException(parser,msg); } - private LuanTable parse() throws ParseException { - LuanTable list = new LuanTable(); + private LuanTable parse(LuanState luan) throws ParseException { + LuanTable list = new LuanTable(luan); while(true) { Spaces(); String field = parseField();
--- a/src/luan/modules/parsers/Html.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/parsers/Html.java Mon Nov 12 02:10:41 2018 -0700 @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Set; import java.util.HashSet; +import luan.LuanState; import luan.LuanTable; import luan.lib.parser.Parser; import luan.lib.parser.ParseException; @@ -11,14 +12,18 @@ public final class Html { - public static LuanTable toList(String text,LuanTable containerTagsTbl) throws ParseException { - return new Html(text,containerTagsTbl).parse(); + public static LuanTable toList(LuanState luan,String text,LuanTable containerTagsTbl) + throws ParseException + { + return new Html(luan,text,containerTagsTbl).parse(); } + private final LuanState luan; private final Parser parser; private final Set<String> containerTags = new HashSet<String>(); - private Html(String text,LuanTable containerTagsTbl) { + private Html(LuanState luan,String text,LuanTable containerTagsTbl) { + this.luan = luan; this.parser = new Parser(text); for( Object v : containerTagsTbl.asList() ) { containerTags.add((String)v); @@ -56,7 +61,7 @@ } if( sb.length() > 0 ) list.add(sb.toString()); - return new LuanTable(list); + return new LuanTable(luan,list); } private LuanTable parseComment() { @@ -69,7 +74,7 @@ return parser.failure(null); } String text = parser.textFrom(start); - LuanTable tbl = new LuanTable(); + LuanTable tbl = new LuanTable(luan); tbl.rawPut("type","comment"); tbl.rawPut("text",text); return parser.success(tbl); @@ -85,7 +90,7 @@ return parser.failure(null); } String text = parser.textFrom(start); - LuanTable tbl = new LuanTable(); + LuanTable tbl = new LuanTable(luan); tbl.rawPut("type","cdata"); tbl.rawPut("text",text); return parser.success(tbl); @@ -107,7 +112,7 @@ return parser.failure(null); } String text = parser.text.substring(start,end); - LuanTable tbl = new LuanTable(); + LuanTable tbl = new LuanTable(luan); tbl.rawPut("type","container"); tbl.rawPut("tag",tag); tbl.rawPut("text",text); @@ -124,7 +129,7 @@ return parser.failure(null); while( matchNameChar() ); String name = parser.textFrom(start).toLowerCase(); - LuanTable attributes = new LuanTable(); + LuanTable attributes = new LuanTable(luan); String attrName; while( (attrName = parseAttrName()) != null ) { String attrValue = parseAttrValue(); @@ -134,7 +139,7 @@ boolean isEmpty = parser.match('/'); if( !parser.match('>') ) return parser.failure(null); - LuanTable tbl = new LuanTable(); + LuanTable tbl = new LuanTable(luan); tbl.rawPut("type","tag"); tbl.rawPut("name",name); tbl.rawPut("attributes",attributes);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/modules/sql/Database.java Mon Nov 12 02:10:41 2018 -0700 @@ -0,0 +1,120 @@ +package luan.modules.sql; + +import java.io.Closeable; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; +import java.util.HashMap; +import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import luan.LuanState; +import luan.LuanTable; +import luan.LuanException; + + +public final class Database implements Closeable { + private static final Logger logger = LoggerFactory.getLogger(Database.class); + + private static Map<Map,Database> pool = new HashMap<Map,Database>(); + + public static Database get(Connection con) { + return new Database(con); + } + + public static synchronized Database get(LuanTable specTbl) + throws LuanException, ClassNotFoundException, SQLException + { + Map<Object,Object> spec = specTbl.asMap(); + Database db = pool.get(spec); + if( db==null ) { + db = new Database(spec); + pool.put(spec,db); + } + return db; + } + + public int uses = 0; + public final Connection con; + private final Map<String,PreparedStatement> pstmts = new HashMap<String,PreparedStatement>(); + + public Database(Connection con) { + this.con = con; + } + + private Database(Map<Object,Object> spec) + throws LuanException, ClassNotFoundException, SQLException + { + spec = new HashMap<Object,Object>(spec); + String cls = getString(spec,"class"); + Class.forName(cls); + String url = getString(spec,"url"); + Properties props = new Properties(); + props.putAll(spec); + this.con = DriverManager.getConnection(url,props); + } + + private static String getString(Map spec,String key) throws LuanException { + Object val = spec.remove(key); + if( val==null ) + throw new LuanException( "parameter '"+key+"' is required" ); + if( !(val instanceof String) ) + throw new LuanException( "parameter '"+key+"' must be a string" ); + return (String)val; + } + + private PreparedStatement prepareStatement(String sql,Object[] args) throws SQLException { + PreparedStatement pstmt = pstmts.get(sql); + if( pstmt==null ) { + pstmt = con.prepareStatement(sql); + pstmts.put(sql,pstmt); + } + for( int i=0; i<args.length; i++ ) { + pstmt.setObject(i+1,args[i]); + } + return pstmt; + } + + public ResultSet query(String sql,Object... args) throws SQLException { + if( args.length == 0 ) { + Statement stmt = con.createStatement(); + return stmt.executeQuery(sql); + } else { + PreparedStatement pstmt = prepareStatement(sql,args); + return pstmt.executeQuery(); + } + } + + public int update(String sql,Object... args) throws SQLException { + if( args.length == 0 ) { + Statement stmt = con.createStatement(); + int n = stmt.executeUpdate(sql); + stmt.close(); + return n; + } else { + PreparedStatement pstmt = prepareStatement(sql,args); + return pstmt.executeUpdate(); + } + } + + public void close() { + try { + con.close(); + } catch(SQLException e) { + throw new RuntimeException(e); + } + } + + protected void finalize() throws Throwable { + if( !con.isClosed() ) { + logger.error("not closed"); + close(); + } + super.finalize(); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/modules/sql/Sql.luan Mon Nov 12 02:10:41 2018 -0700 @@ -0,0 +1,67 @@ +java() +local Luan = require "luan:Luan.luan" +local error = Luan.error +local new_error = Luan.new_error or error() +local set_metatable = Luan.set_metatable or error() +local Database = require "java:luan.modules.sql.Database" +local Logging = require "luan:logging/Logging.luan" +local logger = Logging.logger "Sql" + + +local Sql = {} + +local mt = {} + +function mt.__gc(database) + if not database.is_closed then + logger.error(database.created) + database.close() + end +end + +function Sql.database(spec) + local database = {} + set_metatable(database,mt) + local java_database = Database.get(spec) + java_database.uses = java_database.uses + 1 + database.is_closed = false + database.java = java_database + database.created = new_error "not closed, created:" + database.update = java_database.update + + function database.close() + if not database.is_closed then + database.is_closed = true + java_database.uses > 0 or error "java_database.uses <= 0" + java_database.uses = java_database.uses - 1 + if java_database.uses == 0 then + java_database.close() + end + end + end + + function database.query(sql,...) + local rs = java_database.query(sql,...) + local mt = {} + function mt.__index(_,key) + local rtn = rs.getObject(key) + return not rs.wasNull() and rtn or nil + end + local result = {} + set_metatable(result,mt) + return function() + if rs.isClosed() then + return nil + end + if not rs.next() then + rs.close() + return nil + end + return result + end + end + + return database +end + +return Sql
--- a/src/luan/modules/url/LuanUrl.java Sun Sep 30 19:10:48 2018 -0600 +++ b/src/luan/modules/url/LuanUrl.java Mon Nov 12 02:10:41 2018 -0700 @@ -34,10 +34,10 @@ private MultipartClient multipart = null; private int timeout = 0; - public LuanUrl(LuanState luan,URL url,LuanTable options) throws LuanException { + public LuanUrl(URL url,LuanTable options) throws LuanException { this.url = url; if( options != null ) { - Map map = options.asMap(luan); + Map map = options.asMap(); String methodStr = getString(map,"method"); if( methodStr != null ) { methodStr = methodStr.toUpperCase(); @@ -47,7 +47,7 @@ throw new LuanException( "invalid method: "+methodStr ); } } - Map headerMap = getMap(luan,map,"headers"); + Map headerMap = getMap(map,"headers"); if( headerMap != null ) { headers = new HashMap(); for( Object hack : headerMap.entrySet() ) { @@ -66,7 +66,7 @@ } } } - Map auth = getMap(luan,map,"authorization"); + Map auth = getMap(map,"authorization"); if( auth != null ) { if( headers!=null && headers.containsKey("authorization") ) throw new LuanException( "can't define authorization with header 'authorization' defined" ); @@ -85,7 +85,7 @@ headers = new HashMap(); headers.put("authorization",val); } - Map params = getMap(luan,map,"parameters"); + Map params = getMap(map,"parameters"); String enctype = getString(map,"enctype"); if( enctype != null ) { if( !enctype.equals("multipart/form-data") ) @@ -184,12 +184,12 @@ return (LuanTable)val; } - private static Map getMap(LuanState luan,Map map,String key) throws LuanException { + private static Map getMap(Map map,String key) throws LuanException { LuanTable t = getTable(map,key); - return t==null ? null : t.asMap(luan); + return t==null ? null : t.asMap(); } - @Override public InputStream inputStream() throws IOException, LuanException { + @Override public InputStream inputStream(LuanState luan) throws IOException, LuanException { URLConnection con = url.openConnection(); if( timeout != 0 ) { con.setConnectTimeout(timeout); @@ -219,12 +219,12 @@ HttpURLConnection httpCon = (HttpURLConnection)con; if( method==Method.GET ) { - return getInputStream(httpCon); + return getInputStream(luan,httpCon); } if( method==Method.DELETE ) { httpCon.setRequestMethod("DELETE"); - return getInputStream(httpCon); + return getInputStream(luan,httpCon); } // POST @@ -244,13 +244,13 @@ } out.flush(); try { - return getInputStream(httpCon); + return getInputStream(luan,httpCon); } finally { out.close(); } } - private static InputStream getInputStream(HttpURLConnection httpCon) throws IOException, LuanException { + private static InputStream getInputStream(LuanState luan,HttpURLConnection httpCon) throws IOException, LuanException { try { return httpCon.getInputStream(); } catch(IOException e) { @@ -263,7 +263,7 @@ String msg = Utils.readAll(in); in.close(); LuanException le = new LuanException(msg,e); - LuanTable tbl = le.table(); + LuanTable tbl = le.table(luan); tbl.rawPut("response_code",responseCode); tbl.rawPut("response_message",responseMessage); throw le;