Mercurial Hosting > luan
changeset 44:57054fa43189
implement table lib
git-svn-id: https://luan-java.googlecode.com/svn/trunk@45 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Wed, 26 Dec 2012 23:53:25 +0000 |
parents | 80b67b1a653c |
children | b1b14d09fc98 |
files | src/luan/Lua.java src/luan/LuaException.java src/luan/LuaJavaFunction.java src/luan/LuaNumber.java src/luan/LuaState.java src/luan/LuaTable.java src/luan/interp/AddExpr.java src/luan/interp/DivExpr.java src/luan/interp/LenExpr.java src/luan/interp/LtExpr.java src/luan/interp/LuaParser.java src/luan/interp/LuaStateImpl.java src/luan/interp/ModExpr.java src/luan/interp/MulExpr.java src/luan/interp/NumericForStmt.java src/luan/interp/PowExpr.java src/luan/interp/SubExpr.java src/luan/interp/TableExpr.java src/luan/interp/UnmExpr.java src/luan/lib/BasicLib.java src/luan/lib/JavaLib.java src/luan/lib/LuaRuntimeException.java src/luan/lib/StringLib.java src/luan/lib/TableLib.java src/luan/tools/CmdLine.java |
diffstat | 25 files changed, 368 insertions(+), 62 deletions(-) [+] |
line wrap: on
line diff
diff -r 80b67b1a653c -r 57054fa43189 src/luan/Lua.java --- a/src/luan/Lua.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/Lua.java Wed Dec 26 23:53:25 2012 +0000 @@ -37,9 +37,9 @@ String s = (String)obj; try { if( base==null ) - return new LuaNumber( Double.parseDouble(s) ); + return LuaNumber.of( Double.parseDouble(s) ); else - return new LuaNumber( Long.parseLong(s,base) ); + return LuaNumber.of( Long.parseLong(s,base) ); } catch(NumberFormatException e) {} } return null;
diff -r 80b67b1a653c -r 57054fa43189 src/luan/LuaException.java --- a/src/luan/LuaException.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/LuaException.java Wed Dec 26 23:53:25 2012 +0000 @@ -25,9 +25,11 @@ if( msg instanceof LuaException ) { LuaException le = (LuaException)msg; return le.message(); +/* } else if( msg instanceof Throwable ) { Throwable t = (Throwable)msg; return t.getMessage(); +*/ } else { return msg.toString(); }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/LuaJavaFunction.java --- a/src/luan/LuaJavaFunction.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/LuaJavaFunction.java Wed Dec 26 23:53:25 2012 +0000 @@ -130,7 +130,7 @@ if( obj == null ) return NULL_RTN; Number n = (Number)obj; - LuaNumber ln = new LuaNumber(n.doubleValue()); + LuaNumber ln = LuaNumber.of(n); return new Object[]{ln}; } }; @@ -143,7 +143,7 @@ for( int i=0; i<rtn.length; i++ ) { Number n = (Number)Array.get(obj,i); if( n != null ) - rtn[i] = new LuaNumber(n.doubleValue()); + rtn[i] = LuaNumber.of(n.doubleValue()); } return rtn; }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/LuaNumber.java --- a/src/luan/LuaNumber.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/LuaNumber.java Wed Dec 26 23:53:25 2012 +0000 @@ -4,7 +4,7 @@ public final class LuaNumber implements Comparable<LuaNumber> { final double n; - public LuaNumber(double n) { + private LuaNumber(double n) { this.n = n; } @@ -43,4 +43,25 @@ return Double.compare(n,ln.n); } + public static LuaNumber of(double n) { + return new LuaNumber(n); + } + + private static LuaNumber[] ints = new LuaNumber[100]; + static { + for( int i=0; i<ints.length; i++ ) { + ints[i] = new LuaNumber(i); + } + } + + public static LuaNumber of(int n) { + if( 0 <= n && n < ints.length ) + return ints[n]; + return new LuaNumber(n); + } + + public static LuaNumber of(Number n) { + return n instanceof Integer ? of(n.intValue()) : of(n.doubleValue()); + } + }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/LuaState.java --- a/src/luan/LuaState.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/LuaState.java Wed Dec 26 23:53:25 2012 +0000 @@ -84,4 +84,28 @@ return t==null ? null : t.get(op); } + + public final LuaFunction getBinHandler(LuaElement el,String op,Object o1,Object o2) throws LuaException { + LuaFunction f1 = getHandlerFunction(el,op,o1); + if( f1 != null ) + return f1; + return getHandlerFunction(el,op,o2); + } + + public final boolean isLessThan(LuaElement el,Object o1,Object o2) throws LuaException { + if( o1 instanceof LuaNumber && o2 instanceof LuaNumber ) { + LuaNumber n1 = (LuaNumber)o1; + LuaNumber n2 = (LuaNumber)o2; + return n1.compareTo(n2) < 0; + } + if( o1 instanceof String && o2 instanceof String ) { + String s1 = (String)o1; + String s2 = (String)o2; + return s1.compareTo(s2) < 0; + } + LuaFunction fn = getBinHandler(el,"__lt",o1,o2); + if( fn != null ) + return Lua.toBoolean( Lua.first(call(fn,el,"__lt",o1,o2)) ); + throw new LuaException( this, el, "attempt to compare " + Lua.type(o1) + " with " + Lua.type(o2) ); + } }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/LuaTable.java --- a/src/luan/LuaTable.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/LuaTable.java Wed Dec 26 23:53:25 2012 +0000 @@ -1,23 +1,83 @@ package luan; import java.util.Iterator; +import java.util.ListIterator; import java.util.Map; import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; public class LuaTable { - private final Map<Object,Object> map = new HashMap<Object,Object>(); - private LuaTable metatable; + private Map<Object,Object> map = null; + private List<Object> list = null; + private LuaTable metatable = null; + + public LuaTable() {} + + public LuaTable(List<Object> list) { + this.list = list; + } @Override public String toString() { return "table: " + Integer.toHexString(hashCode()); } public Object get(Object key) { + if( list != null && key instanceof LuaNumber ) { + LuaNumber ln = (LuaNumber)key; + int i = (int)ln.n; + if( i == ln.n ) { + i--; + if( i>=0 && i<list.size() ) + return list.get(i); + } + } + if( map==null ) + return null; return map.get(key); } public Object put(Object key,Object val) { + if( key instanceof LuaNumber ) { + LuaNumber ln = (LuaNumber)key; + int i = (int)ln.n; + if( i == ln.n ) { + i--; + if( list == null && i == 0 ) + list = new ArrayList<Object>(); + if( list != null ) { + if( i == list.size() ) { + if( val != null ) { + list.add(val); + if( map != null ) { + while(true) { + Object v = map.remove(LuaNumber.of(list.size()+1)); + if( v == null ) + break; + list.add(v); + } + } + } + return null; + } else if( i>=0 && i<list.size() ) { + Object old = list.get(i); + list.set(i,val); + if( val == null && i == list.size()-1 ) { + while( i>=0 && list.get(i)==null ) { + list.remove(i--); + } + } + return old; + } + } + } + } + if( map==null ) { + map = new HashMap<Object,Object>(); + } if( val == null ) { return map.remove(key); } else { @@ -25,16 +85,82 @@ } } + public void insert(int pos,Object value) { + if( list == null ) + list = new ArrayList<Object>(); + list.add(pos-1,value); + } + + public Object remove(int pos) { + if( list == null ) + list = new ArrayList<Object>(); + return list.remove(pos-1); + } + + public void sort(Comparator<Object> cmp) { + if( list != null ) + Collections.sort(list,cmp); + } + public int length() { - int i = 0; - while( map.containsKey( new LuaNumber(i) ) ) { - i++; - } - return i; + return list==null ? 0 : list.size(); } public Iterator<Map.Entry<Object,Object>> iterator() { - return map.entrySet().iterator(); + if( list == null ) { + if( map == null ) + return Collections.<Map.Entry<Object,Object>>emptyList().iterator(); + return map.entrySet().iterator(); + } + if( map == null ) + return listIterator(); + return new Iterator<Map.Entry<Object,Object>>() { + Iterator<Map.Entry<Object,Object>> iter = listIterator(); + boolean isList = true; + public boolean hasNext() { + boolean b = iter.hasNext(); + if( !b && isList ) { + iter = map.entrySet().iterator(); + isList = false; + b = iter.hasNext(); + } + return b; + } + public Map.Entry<Object,Object> next() { + return iter.next(); + } + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + public Iterator<Map.Entry<Object,Object>> listIterator() { + if( list == null ) + return Collections.<Map.Entry<Object,Object>>emptyList().iterator(); + final ListIterator iter = list.listIterator(); + return new Iterator<Map.Entry<Object,Object>>() { + public boolean hasNext() { + return iter.hasNext(); + } + public Map.Entry<Object,Object> next() { + LuaNumber key = LuaNumber.of(iter.nextIndex()+1); + return new MapEntry(key,iter.next()); + } + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + public Object[] listToArray() { + return list==null ? new Object[0] : list.toArray(); + } + + public LuaTable subList(int from,int to) { + if( list == null ) + list = new ArrayList<Object>(); + return new LuaTable(new ArrayList<Object>(list.subList(from-1,to-1))); } public LuaTable getMetatable() { @@ -44,4 +170,26 @@ public void setMetatable(LuaTable metatable) { this.metatable = metatable; } + + private static final class MapEntry implements Map.Entry<Object,Object> { + private final Object key; + private final Object value; + + MapEntry(Object key,Object value) { + this.key = key; + this.value = value; + } + + @Override public Object getKey() { + return key; + } + + @Override public Object getValue() { + return value; + } + + @Override public Object setValue(Object value) { + throw new UnsupportedOperationException(); + } + } }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/AddExpr.java --- a/src/luan/interp/AddExpr.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/AddExpr.java Wed Dec 26 23:53:25 2012 +0000 @@ -18,7 +18,7 @@ LuaNumber n1 = Lua.toNumber(o1); LuaNumber n2 = Lua.toNumber(o2); if( n1 != null && n2 != null ) - return new LuaNumber( n1.value() + n2.value() ); + return LuaNumber.of( n1.value() + n2.value() ); return arithmetic(lua,"__add",o1,o2); } }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/DivExpr.java --- a/src/luan/interp/DivExpr.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/DivExpr.java Wed Dec 26 23:53:25 2012 +0000 @@ -18,7 +18,7 @@ LuaNumber n1 = Lua.toNumber(o1); LuaNumber n2 = Lua.toNumber(o2); if( n1 != null && n2 != null ) - return new LuaNumber( n1.value() / n2.value() ); + return LuaNumber.of( n1.value() / n2.value() ); return arithmetic(lua,"__div",o1,o2); } }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/LenExpr.java --- a/src/luan/interp/LenExpr.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/LenExpr.java Wed Dec 26 23:53:25 2012 +0000 @@ -18,7 +18,7 @@ Object o = op.eval(lua); if( o instanceof String ) { String s = (String)o; - return new LuaNumber( s.length() ); + return LuaNumber.of( s.length() ); } LuaFunction fn = lua.getHandlerFunction(se,"__len",o); if( fn != null )
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/LtExpr.java --- a/src/luan/interp/LtExpr.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/LtExpr.java Wed Dec 26 23:53:25 2012 +0000 @@ -16,19 +16,6 @@ @Override public Object eval(LuaStateImpl lua) throws LuaException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); - if( o1 instanceof LuaNumber && o2 instanceof LuaNumber ) { - LuaNumber n1 = (LuaNumber)o1; - LuaNumber n2 = (LuaNumber)o2; - return n1.compareTo(n2) < 0; - } - if( o1 instanceof String && o2 instanceof String ) { - String s1 = (String)o1; - String s2 = (String)o2; - return s1.compareTo(s2) < 0; - } - LuaFunction fn = lua.getBinHandler(se,"__lt",o1,o2); - if( fn != null ) - return Lua.toBoolean( Lua.first(lua.call(fn,se,"__lt",o1,o2)) ); - throw new LuaException( lua, se, "attempt to compare " + Lua.type(o1) + " with " + Lua.type(o2) ); + return lua.isLessThan(se,o1,o2); } }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/LuaParser.java --- a/src/luan/interp/LuaParser.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/LuaParser.java Wed Dec 26 23:53:25 2012 +0000 @@ -304,7 +304,7 @@ return Sequence( start.set(currentIndex()), Keyword("for"), Name(), '=', Spaces(), Expr(), Keyword("to"), Expr(), - push( new ConstExpr(new LuaNumber(1)) ), // default step + push( new ConstExpr(LuaNumber.of(1)) ), // default step Optional( Keyword("step"), drop(), @@ -894,7 +894,7 @@ Rule NumberLiteral() { return Sequence( Number(), - push(new LuaNumber((Double)pop())) + push(LuaNumber.of((Double)pop())) ); }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/LuaStateImpl.java --- a/src/luan/interp/LuaStateImpl.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/LuaStateImpl.java Wed Dec 26 23:53:25 2012 +0000 @@ -13,13 +13,6 @@ final class LuaStateImpl extends LuaState { - LuaFunction getBinHandler(LuaElement el,String op,Object o1,Object o2) throws LuaException { - LuaFunction f1 = getHandlerFunction(el,op,o1); - if( f1 != null ) - return f1; - return getHandlerFunction(el,op,o2); - } - final Object arithmetic(LuaElement el,String op,Object o1,Object o2) throws LuaException { LuaFunction fn = getBinHandler(el,op,o1,o2); if( fn != null )
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/ModExpr.java --- a/src/luan/interp/ModExpr.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/ModExpr.java Wed Dec 26 23:53:25 2012 +0000 @@ -18,7 +18,7 @@ LuaNumber n1 = Lua.toNumber(o1); LuaNumber n2 = Lua.toNumber(o2); if( n1 != null && n2 != null ) - return new LuaNumber( n1.value() % n2.value() ); + return LuaNumber.of( n1.value() % n2.value() ); return arithmetic(lua,"__mod",o1,o2); } }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/MulExpr.java --- a/src/luan/interp/MulExpr.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/MulExpr.java Wed Dec 26 23:53:25 2012 +0000 @@ -18,7 +18,7 @@ LuaNumber n1 = Lua.toNumber(o1); LuaNumber n2 = Lua.toNumber(o2); if( n1 != null && n2 != null ) - return new LuaNumber( n1.value() * n2.value() ); + return LuaNumber.of( n1.value() * n2.value() ); return arithmetic(lua,"__mul",o1,o2); } }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/NumericForStmt.java --- a/src/luan/interp/NumericForStmt.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/NumericForStmt.java Wed Dec 26 23:53:25 2012 +0000 @@ -28,7 +28,7 @@ double step = lua.checkNumber( se, stepExpr.eval(lua) ).value(); try { while( step > 0.0 && v <= limit || step < 0.0 && v >= limit ) { - lua.stackSet( iVar, new LuaNumber(v) ); + lua.stackSet( iVar, LuaNumber.of(v) ); block.eval(lua); v += step; }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/PowExpr.java --- a/src/luan/interp/PowExpr.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/PowExpr.java Wed Dec 26 23:53:25 2012 +0000 @@ -18,7 +18,7 @@ LuaNumber n1 = Lua.toNumber(o1); LuaNumber n2 = Lua.toNumber(o2); if( n1 != null && n2 != null ) - return new LuaNumber( Math.pow( n1.value(), n2.value() ) ); + return LuaNumber.of( Math.pow( n1.value(), n2.value() ) ); return arithmetic(lua,"__pow",o1,o2); } }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/SubExpr.java --- a/src/luan/interp/SubExpr.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/SubExpr.java Wed Dec 26 23:53:25 2012 +0000 @@ -18,7 +18,7 @@ LuaNumber n1 = Lua.toNumber(o1); LuaNumber n2 = Lua.toNumber(o2); if( n1 != null && n2 != null ) - return new LuaNumber( n1.value() - n2.value() ); + return LuaNumber.of( n1.value() - n2.value() ); return arithmetic(lua,"__sub",o1,o2); } }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/TableExpr.java --- a/src/luan/interp/TableExpr.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/TableExpr.java Wed Dec 26 23:53:25 2012 +0000 @@ -34,7 +34,7 @@ } Object[] a = expressions.eval(lua); for( int i=0; i<a.length; i++ ) { - table.put( new LuaNumber(i+1), a[i] ); + table.put( LuaNumber.of(i+1), a[i] ); } return table; }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/interp/UnmExpr.java --- a/src/luan/interp/UnmExpr.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/interp/UnmExpr.java Wed Dec 26 23:53:25 2012 +0000 @@ -18,7 +18,7 @@ Object o = op.eval(lua); LuaNumber n = Lua.toNumber(o); if( n != null ) - return new LuaNumber( -n.value() ); + return LuaNumber.of( -n.value() ); LuaFunction fn = lua.getHandlerFunction(se,"__unm",o); if( fn != null ) { return Lua.first(lua.call(fn,se,"__unm",o));
diff -r 80b67b1a653c -r 57054fa43189 src/luan/lib/BasicLib.java --- a/src/luan/lib/BasicLib.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/lib/BasicLib.java Wed Dec 26 23:53:25 2012 +0000 @@ -121,8 +121,7 @@ return lua.call(fn,LuaElement.JAVA,null); } - public static LuaFunction pairs(LuaTable t) { - final Iterator<Map.Entry<Object,Object>> iter = t.iterator(); + private static LuaFunction pairs(final Iterator<Map.Entry<Object,Object>> iter) { return new LuaFunction() { public Object[] call(LuaState lua,Object[] args) { if( !iter.hasNext() ) @@ -133,15 +132,12 @@ }; } - public static LuaFunction ipairs(final LuaTable t) { - return new LuaFunction() { - private double i = 0.0; - public Object[] call(LuaState lua,Object[] args) { - LuaNumber n = new LuaNumber(++i); - Object val = t.get(n); - return val==null ? LuaFunction.EMPTY_RTN : new Object[]{n,val}; - } - }; + public static LuaFunction pairs(LuaTable t) { + return pairs( t.iterator() ); + } + + public static LuaFunction ipairs(LuaTable t) { + return pairs( t.listIterator() ); } public static LuaTable get_metatable(LuaState lua,Object obj) {
diff -r 80b67b1a653c -r 57054fa43189 src/luan/lib/JavaLib.java --- a/src/luan/lib/JavaLib.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/lib/JavaLib.java Wed Dec 26 23:53:25 2012 +0000 @@ -125,7 +125,7 @@ Object value = field.get(obj); if( value instanceof Number ) { Number n = (Number)value; - value = new LuaNumber(n.doubleValue()); + value = LuaNumber.of(n); } return value; } else {
diff -r 80b67b1a653c -r 57054fa43189 src/luan/lib/LuaRuntimeException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/lib/LuaRuntimeException.java Wed Dec 26 23:53:25 2012 +0000 @@ -0,0 +1,10 @@ +package luan.lib; + +import luan.LuaException; + + +public final class LuaRuntimeException extends RuntimeException { + public LuaRuntimeException(LuaException e) { + super(e); + } +}
diff -r 80b67b1a653c -r 57054fa43189 src/luan/lib/StringLib.java --- a/src/luan/lib/StringLib.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/lib/StringLib.java Wed Dec 26 23:53:25 2012 +0000 @@ -157,7 +157,7 @@ i++; } m.appendTail(sb); - return new Object[]{ sb.toString(), new LuaNumber(i) }; + return new Object[]{ sb.toString(), LuaNumber.of(i) }; } if( repl instanceof LuaTable ) { LuaTable t = (LuaTable)repl; @@ -175,7 +175,7 @@ i++; } m.appendTail(sb); - return new Object[]{ sb.toString(), new LuaNumber(i) }; + return new Object[]{ sb.toString(), LuaNumber.of(i) }; } if( repl instanceof LuaFunction ) { LuaFunction fn = (LuaFunction)repl; @@ -202,7 +202,7 @@ i++; } m.appendTail(sb); - return new Object[]{ sb.toString(), new LuaNumber(i) }; + return new Object[]{ sb.toString(), LuaNumber.of(i) }; } throw new LuaException( lua, LuaElement.JAVA, "bad argument #3 to 'gsub' (string/function/table expected)" ); }
diff -r 80b67b1a653c -r 57054fa43189 src/luan/lib/TableLib.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/lib/TableLib.java Wed Dec 26 23:53:25 2012 +0000 @@ -0,0 +1,123 @@ +package luan.lib; + +import java.util.Comparator; +import java.util.ArrayList; +import java.util.Arrays; +import luan.Lua; +import luan.LuaState; +import luan.LuaTable; +import luan.LuaNumber; +import luan.LuaFunction; +import luan.LuaJavaFunction; +import luan.LuaElement; +import luan.LuaException; + + +public final class TableLib { + + public static void register(LuaState lua) { + LuaTable module = new LuaTable(); + LuaTable global = lua.global(); + global.put("table",module); + try { + add( module, "concat", LuaState.class, LuaTable.class, String.class, Integer.class, Integer.class ); + add( module, "insert", LuaState.class, LuaTable.class, Integer.TYPE, Object.class ); + add( module, "pack", new Object[0].getClass() ); + add( module, "remove", LuaState.class, LuaTable.class, Integer.TYPE ); + add( module, "sort", LuaState.class, LuaTable.class, LuaFunction.class ); + add( module, "sub_list", LuaTable.class, Integer.TYPE, Integer.TYPE ); + add( module, "unpack", LuaTable.class ); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + private static void add(LuaTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { + t.put( method, new LuaJavaFunction(TableLib.class.getMethod(method,parameterTypes),null) ); + } + + public static String concat(LuaState lua,LuaTable list,String sep,Integer i,Integer j) throws LuaException { + int first = i==null ? 1 : i; + int last = j==null ? list.length() : j; + StringBuilder buf = new StringBuilder(); + for( int k=first; k<=last; k++ ) { + Object val = list.get(LuaNumber.of(k)); + if( val==null ) + break; + if( sep!=null && k > first ) + buf.append(sep); + String s = Lua.asString(val); + if( s==null ) + throw new LuaException( lua, LuaElement.JAVA, "invalid value ("+Lua.type(val)+") at index "+k+" in table for 'concat'" ); + buf.append(val); + } + return buf.toString(); + } + + public static void insert(LuaState lua,LuaTable list,int pos,Object value) throws LuaException { + try { + list.insert(pos,value); + } catch(IndexOutOfBoundsException e) { + throw new LuaException( lua, LuaElement.JAVA, e); + } + } + + public static Object remove(LuaState lua,LuaTable list,int pos) throws LuaException { + try { + return list.remove(pos); + } catch(IndexOutOfBoundsException e) { + throw new LuaException( lua, LuaElement.JAVA, e); + } + } + + private static interface LessThan { + public boolean isLessThan(Object o1,Object o2); + } + + public static void sort(final LuaState lua,LuaTable list,final LuaFunction comp) throws LuaException { + final LessThan lt; + if( comp==null ) { + lt = new LessThan() { + public boolean isLessThan(Object o1,Object o2) { + try { + return lua.isLessThan(LuaElement.JAVA,o1,o2); + } catch(LuaException e) { + throw new LuaRuntimeException(e); + } + } + }; + } else { + lt = new LessThan() { + public boolean isLessThan(Object o1,Object o2) { + try { + return Lua.toBoolean(lua.call(comp,LuaElement.JAVA,"comp-arg",o1,o2)); + } catch(LuaException e) { + throw new LuaRuntimeException(e); + } + } + }; + } + try { + list.sort( new Comparator<Object>() { + public int compare(Object o1,Object o2) { + return lt.isLessThan(o1,o2) ? -1 : lt.isLessThan(o2,o1) ? 1 : 0; + } + } ); + } catch(LuaRuntimeException e) { + throw (LuaException)e.getCause(); + } + } + + public static LuaTable pack(Object[] args) { + return new LuaTable(new ArrayList<Object>(Arrays.asList(args))); + } + + public static Object[] unpack(LuaTable list) { + return list.listToArray(); + } + + public static LuaTable sub_list(LuaTable list,int from,int to) { + return list.subList(from,to); + } + +}
diff -r 80b67b1a653c -r 57054fa43189 src/luan/tools/CmdLine.java --- a/src/luan/tools/CmdLine.java Tue Dec 25 03:42:42 2012 +0000 +++ b/src/luan/tools/CmdLine.java Wed Dec 26 23:53:25 2012 +0000 @@ -5,6 +5,7 @@ import luan.lib.BasicLib; import luan.lib.JavaLib; import luan.lib.StringLib; +import luan.lib.TableLib; import luan.Lua; import luan.LuaState; import luan.LuaFunction; @@ -21,6 +22,7 @@ BasicLib.register(lua); JavaLib.register(lua); StringLib.register(lua); + TableLib.register(lua); BasicLib.make_standard(lua); boolean interactive = false; boolean showVersion = false; @@ -70,7 +72,7 @@ System.arraycopy(args,1,varArgs,0,varArgs.length); LuaTable argsTable = new LuaTable(); for( int j=0; j<args.length; j++ ) { - argsTable.put( new LuaNumber(j), args[j] ); + argsTable.put( LuaNumber.of(j), args[j] ); } lua.global().put("arg",argsTable); try {