Mercurial Hosting > luan
view src/luan/modules/BasicLuan.java @ 1418:732b5de211fc
add Hosted.luan
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 18 Oct 2019 22:29:46 -0600 |
parents | eb8b35dccd99 |
children | 59fd2e8b1b9d |
line wrap: on
line source
package luan.modules; import java.io.InputStreamReader; import java.io.IOException; import java.lang.reflect.Method; import java.util.Iterator; import java.util.Map; import java.util.List; import java.util.ArrayList; import java.util.Arrays; import luan.Luan; import luan.LuanTable; import luan.LuanFunction; import luan.LuanException; import luan.LuanCloner; import luan.modules.parsers.LuanToString; public final class BasicLuan { public static String type(Object obj) { return Luan.type(obj); } public static LuanFunction load(Luan luan,String text,String sourceName,LuanTable env) throws LuanException { Utils.checkNotNull(text); Utils.checkNotNull(sourceName,1); return luan.load(text,sourceName,env); } public static LuanFunction load_file(Luan luan,String fileName) throws LuanException { if( fileName == null ) { fileName = "stdin:"; } else if( fileName.indexOf(':') == -1 ) { fileName = "file:" + fileName; } String src = PackageLuan.read(luan,fileName); if( src == null ) return null; return load(luan,src,fileName,null); } public static LuanFunction pairs(final LuanTable t) throws LuanException { Utils.checkNotNull(t); return t.pairs(); } private static class Ipairs extends LuanFunction { List<Object> list; int i = 0; final int size; Ipairs(LuanTable t) { super(true); list = t.asList(); size = list.size(); } @Override public Object[] call(Object[] args) { if( i >= size ) return LuanFunction.NOTHING; Object val = list.get(i++); return new Object[]{i,val}; } @Override protected void completeClone(LuanFunction dc,LuanCloner cloner) { Ipairs clone = (Ipairs)dc; clone.list = (List)cloner.clone(list); super.completeClone(dc,cloner); } } public static LuanFunction ipairs(LuanTable t) throws LuanException { Utils.checkNotNull(t); return new Ipairs(t); } public static Object get_metatable(LuanTable table) throws LuanException { Utils.checkNotNull(table); LuanTable metatable = table.getMetatable(); if( metatable == null ) return null; Object obj = metatable.rawGet("__metatable"); return obj!=null ? obj : metatable; } public static void set_metatable(LuanTable table,LuanTable metatable) throws LuanException { Utils.checkNotNull(table); if( table.getHandler("__metatable") != null ) throw new LuanException("cannot change a protected metatable"); table.setMetatable(metatable); } public static boolean raw_equal(Object v1,Object v2) { return v1 == v2 || v1 != null && v1.equals(v2); } public static Object raw_get(LuanTable table,Object index) { return table.rawGet(index); } public static void raw_set(LuanTable table,Object index,Object value) throws LuanException { table.rawPut(index,value); } public static int raw_len(Object v) throws LuanException { if( v instanceof String ) { String s = (String)v; return s.length(); } if( v instanceof LuanTable ) { LuanTable t = (LuanTable)v; return t.rawLength(); } throw new LuanException( "bad argument #1 to 'raw_len' (table or string expected)" ); } public static String to_string(Object v) throws LuanException { return Luan.luanToString(v); } public static LuanTable new_error(Luan luan,Object msg) throws LuanException { String s = Luan.luanToString(msg); LuanTable tbl = new LuanException(s).table(luan); tbl.rawPut( "message", msg ); return tbl; } public static int assert_integer(int v) { return v; } public static long assert_long(long v) { return v; } public static double assert_double(double v) { return v; } public static float assert_float(float v) { return v; } public static LuanFunction range(final double from,final double to,Double stepV) throws LuanException { final double step = stepV==null ? 1.0 : stepV; if( step == 0.0 ) throw new LuanException("bad argument #3 (step may not be zero)"); return new LuanFunction(false) { double v = from; @Override public Object call(Object[] args) { if( step > 0.0 && v > to || step < 0.0 && v < to ) return LuanFunction.NOTHING; double rtn = v; v += step; return rtn; } }; } private static class Values extends LuanFunction { Object[] args; int i = 0; Values(Object[] args) { super(true); this.args = args; } @Override public Object[] call(Object[] x) { if( i >= args.length ) return LuanFunction.NOTHING; Object val = args[i++]; return new Object[]{i,val}; } @Override protected void completeClone(LuanFunction dc,LuanCloner cloner) { Values clone = (Values)dc; clone.args = (Object[])cloner.clone(args); super.completeClone(dc,cloner); } } public static LuanFunction values(final Object... args) throws LuanException { return new Values(args); } private LuanFunction fn(Object obj) { return obj instanceof LuanFunction ? (LuanFunction)obj : null; } public static Object try_(LuanTable blocks,Object... args) throws LuanException { Utils.checkNotNull(blocks); 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("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("finally"); if( obj != null ) { if( !(obj instanceof LuanFunction) ) throw new LuanException("bad 'finally' value (function expected, got "+Luan.type(obj)+")"); finallyFn = (LuanFunction)obj; } try { return tryFn.call(args); } catch(LuanException e) { if( catchFn == null ) throw e; return catchFn.call(e.table(blocks.luan())); } finally { if( finallyFn != null ) finallyFn.call(); } } public static Object[] pcall(LuanFunction f,Object... args) { try { Object[] r = Luan.array(f.call(args)); Object[] rtn = new Object[r.length+1]; rtn[0] = true; for( int i=0; i<r.length; i++ ) { rtn[i+1] = r[i]; } return rtn; } catch(LuanException e) { return new Object[]{false,e.table(f.luan())}; } } public static String number_type(Number v) throws LuanException { Utils.checkNotNull(v); return v.getClass().getSimpleName().toLowerCase(); } public static int hash_code(Object obj) throws LuanException { if( obj == null ) { return 0; } else if( obj instanceof byte[] ) { return Arrays.hashCode((byte[])obj); } else { return obj.hashCode(); } } public static String stringify(Object obj,LuanTable options) throws LuanException { LuanToString lts = new LuanToString(); if( options != null ) { Map map = options.asMap(); Boolean strict = Utils.removeBoolean(map,"strict"); if( strict != null ) lts.strict = strict; Boolean numberTypes = Utils.removeBoolean(map,"number_types"); if( numberTypes != null ) lts.numberTypes = numberTypes; Utils.checkEmpty(map); } return lts.toString(obj); } private void BasicLuan() {} // never }