Mercurial Hosting > luan
changeset 48:64ecb7a3aad7
rename Lua to Luan
git-svn-id: https://luan-java.googlecode.com/svn/trunk@49 21e917c8-12df-6dd8-5cb6-c86387c605b9
line wrap: on
line diff
--- a/src/luan/Lua.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -package luan; - - -public class Lua { - public static final String version = "Luan 0.0"; - - public static String type(Object obj) { - if( obj == null ) - return "nil"; - if( obj instanceof String ) - return "string"; - if( obj instanceof Boolean ) - return "boolean"; - if( obj instanceof Number ) - return "number"; - return "userdata"; - } - - public static boolean toBoolean(Object obj) { - return obj != null && !Boolean.FALSE.equals(obj); - } - - public static String asString(Object obj) { - if( obj instanceof String ) - return (String)obj; - if( obj instanceof Number ) - return toString((Number)obj); - return null; - } - - public static Number toNumber(Object obj) { - return toNumber(obj,null); - } - - public static Number toNumber(Object obj,Integer base) { - if( obj instanceof Number ) - return (Number)obj; - if( obj instanceof String ) { - String s = (String)obj; - try { - if( base==null ) - return Double.valueOf(s); - else - return Long.valueOf(s,base); - } catch(NumberFormatException e) {} - } - return null; - } - - public static Object first(Object[] a) { - return a.length==0 ? null : a[0]; - } - - public static String toString(Number n) { - if( n instanceof Integer ) - return n.toString(); - String s = n.toString(); - int iE = s.indexOf('E'); - String ending = null; - if( iE != -1 ) { - ending = s.substring(iE); - s = s.substring(0,iE); - } - if( s.endsWith(".0") ) - s = s.substring(0,s.length()-2); - if( ending != null ) - s += ending; - return s; - } - - public static Integer asInteger(Object obj) { - if( obj instanceof Integer ) - return (Integer)obj; - if( !(obj instanceof Number) ) - return null; - Number n = (Number)obj; - int i = n.intValue(); - return i==n.doubleValue() ? Integer.valueOf(i) : null; - } -}
--- a/src/luan/LuaElement.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -package luan; - - -public abstract class LuaElement { - - final String toString(String fnName) { - return location() + ": in " + (fnName==null ? "main chunk" : "function '"+fnName+"'"); - } - - abstract String location(); - - public static final LuaElement JAVA = new LuaElement(){ - @Override String location() { - return "Java"; - } - }; -}
--- a/src/luan/LuaException.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -package luan; - - -public class LuaException extends Exception { - private final String stackTrace; - - public LuaException(LuaState lua,LuaElement el,Object msg) { - super(message(msg),cause(msg)); - stackTrace = stackTrace(lua,el,msg); - } - - @Override public String getMessage() { - return super.getMessage() + stackTrace; - } - - private String message() { - return super.getMessage(); - } - - private static Throwable cause(Object msg) { - return msg instanceof Throwable ? (Throwable)msg : null; - } - - private static String message(Object msg) { - 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(); - } - } - - private static String stackTrace(LuaState lua,LuaElement el,Object msg) { - StringBuilder buf = new StringBuilder(); - for( int i = lua.stackTrace.size() - 1; i>=0; i-- ) { - StackTraceElement stackTraceElement = lua.stackTrace.get(i); - buf.append( "\n\t" ).append( el.toString(stackTraceElement.fnName) ); - el = stackTraceElement.call; - } - if( msg instanceof LuaException ) { - LuaException le = (LuaException)msg; - buf.append( "\ncaused by:" ).append( le.stackTrace ); - } - return buf.toString(); - } -}
--- a/src/luan/LuaFunction.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -package luan; - - -public abstract class LuaFunction { - - public abstract Object[] call(LuaState lua,Object[] args) throws LuaException; - - public static final Object[] EMPTY_RTN = new Object[0]; - - @Override public String toString() { - return "function: " + Integer.toHexString(hashCode()); - } - -}
--- a/src/luan/LuaJavaFunction.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,465 +0,0 @@ -package luan; - -import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.List; -import java.util.Map; -import java.util.Set; - - -public final class LuaJavaFunction extends LuaFunction { - private final JavaMethod method; - private final Object obj; - private final RtnConverter rtnConverter; - private final boolean takesLuaState; - private final ArgConverter[] argConverters; - private final Class<?> varArgCls; - - public LuaJavaFunction(Method method,Object obj) { - this( JavaMethod.of(method), obj ); - } - - public LuaJavaFunction(Constructor constr,Object obj) { - this( JavaMethod.of(constr), obj ); - } - - LuaJavaFunction(JavaMethod method,Object obj) { - this.method = method; - this.obj = obj; - this.rtnConverter = getRtnConverter(method); - this.takesLuaState = takesLuaState(method); - this.argConverters = getArgConverters(takesLuaState,method); - if( method.isVarArgs() ) { - Class<?>[] paramTypes = method.getParameterTypes(); - this.varArgCls = paramTypes[paramTypes.length-1].getComponentType(); - } else { - this.varArgCls = null; - } - } - - public Class<?>[] getParameterTypes() { - return method.getParameterTypes(); - } - - @Override public Object[] call(LuaState lua,Object[] args) throws LuaException { - args = fixArgs(lua,args); - Object rtn; - try { - rtn = method.invoke(obj,args); - } catch(IllegalArgumentException e) { - checkArgs(lua,args); - throw e; - } catch(IllegalAccessException e) { - throw new RuntimeException(e); - } catch(InvocationTargetException e) { - Throwable cause = e.getCause(); - if( cause instanceof Error ) - throw (Error)cause; - if( cause instanceof RuntimeException ) - throw (RuntimeException)cause; - if( cause instanceof LuaException ) - throw (LuaException)cause; - throw new RuntimeException(e); - } catch(InstantiationException e) { - throw new RuntimeException(e); - } - return rtnConverter.convert(rtn); - } - - private void checkArgs(LuaState lua,Object[] args) throws LuaException { - Class<?>[] a = getParameterTypes(); - for( int i=0; i<a.length; i++ ) { - if( !a[i].isInstance(args[i]) ) { - String got = args[i].getClass().getName(); - String expected = a[i].getName(); - if( !takesLuaState ) - i++; - throw new LuaException(lua,LuaElement.JAVA,"bad argument #"+i+" ("+expected+" expected, got "+got+")"); - } - } - } - - private Object[] fixArgs(LuaState lua,Object[] args) { - int n = argConverters.length; - Object[] rtn; - int start = 0; - if( !takesLuaState && varArgCls==null && args.length == n ) { - rtn = args; - } else { - if( takesLuaState ) - n++; - rtn = new Object[n]; - if( takesLuaState ) { - rtn[start++] = lua; - } - n = argConverters.length; - if( varArgCls != null ) { - n--; - if( args.length < argConverters.length ) { - rtn[rtn.length-1] = Array.newInstance(varArgCls,0); - } else { - int len = args.length - n; - Object varArgs = Array.newInstance(varArgCls,len); - ArgConverter ac = argConverters[n]; - for( int i=0; i<len; i++ ) { - Array.set( varArgs, i, ac.convert(args[n+i]) ); - } - rtn[rtn.length-1] = varArgs; - } - } - System.arraycopy(args,0,rtn,start,Math.min(args.length,n)); - } - for( int i=0; i<n; i++ ) { - rtn[start+i] = argConverters[i].convert(rtn[start+i]); - } - return rtn; - } - - - private interface RtnConverter { - public Object[] convert(Object obj); - } - - private static final RtnConverter RTN_EMPTY = new RtnConverter() { - public Object[] convert(Object obj) { - return EMPTY_RTN; - } - }; - - private static final RtnConverter RTN_ARRAY = new RtnConverter() { - public Object[] convert(Object obj) { - if( obj == null ) - return NULL_RTN; - return (Object[])obj; - } - }; - - private static final RtnConverter RTN_ONE = new RtnConverter() { - public Object[] convert(Object obj) { - return new Object[]{obj}; - } - }; - - private static final Object[] NULL_RTN = new Object[1]; - - private static final RtnConverter RTN_NUMBER_ARRAY = new RtnConverter() { - public Object[] convert(Object obj) { - if( obj == null ) - return NULL_RTN; - Object[] rtn = new Object[Array.getLength(obj)]; - for( int i=0; i<rtn.length; i++ ) { - rtn[i] = Array.get(obj,i); - } - return rtn; - } - }; - - private static RtnConverter getRtnConverter(JavaMethod m) { - Class<?> rtnType = m.getReturnType(); - if( rtnType == Void.TYPE ) - return RTN_EMPTY; - if( rtnType.isArray() ) { - rtnType = rtnType.getComponentType(); - if( isNumber(rtnType) ) - return RTN_NUMBER_ARRAY; - return RTN_ARRAY; - } - return RTN_ONE; - } - - private static boolean isNumber(Class<?> rtnType) { - return rtnType == Byte.TYPE - || rtnType == Short.TYPE - || rtnType == Integer.TYPE - || rtnType == Long.TYPE - || rtnType == Float.TYPE - || rtnType == Double.TYPE - ; - } - - private interface ArgConverter { - public Object convert(Object obj); - } - - private static final ArgConverter ARG_SAME = new ArgConverter() { - public Object convert(Object obj) { - return obj; - } - }; - - private static final ArgConverter ARG_DOUBLE = new ArgConverter() { - public Object convert(Object obj) { - if( obj instanceof Double ) - return obj; - if( obj instanceof Number ) { - Number n = (Number)obj; - return n.doubleValue(); - } - if( obj instanceof String ) { - String s = (String)obj; - try { - return Double.valueOf(s); - } catch(NumberFormatException e) {} - } - return obj; - } - }; - - private static final ArgConverter ARG_FLOAT = new ArgConverter() { - public Object convert(Object obj) { - if( obj instanceof Float ) - return obj; - if( obj instanceof Number ) { - Number n = (Number)obj; - float r = n.floatValue(); - if( r==n.doubleValue() ) - return r; - } - if( obj instanceof String ) { - String s = (String)obj; - try { - return Float.valueOf(s); - } catch(NumberFormatException e) {} - } - return obj; - } - }; - - private static final ArgConverter ARG_LONG = new ArgConverter() { - public Object convert(Object obj) { - if( obj instanceof Long ) - return obj; - if( obj instanceof Number ) { - Number n = (Number)obj; - long r = n.longValue(); - if( r==n.doubleValue() ) - return r; - } - else if( obj instanceof String ) { - String s = (String)obj; - try { - return Long.valueOf(s); - } catch(NumberFormatException e) {} - } - return obj; - } - }; - - private static final ArgConverter ARG_INTEGER = new ArgConverter() { - public Object convert(Object obj) { - if( obj instanceof Integer ) - return obj; - if( obj instanceof Number ) { - Number n = (Number)obj; - int r = n.intValue(); - if( r==n.doubleValue() ) - return r; - } - else if( obj instanceof String ) { - String s = (String)obj; - try { - return Integer.valueOf(s); - } catch(NumberFormatException e) {} - } - return obj; - } - }; - - private static final ArgConverter ARG_SHORT = new ArgConverter() { - public Object convert(Object obj) { - if( obj instanceof Short ) - return obj; - if( obj instanceof Number ) { - Number n = (Number)obj; - short r = n.shortValue(); - if( r==n.doubleValue() ) - return r; - } - else if( obj instanceof String ) { - String s = (String)obj; - try { - return Short.valueOf(s); - } catch(NumberFormatException e) {} - } - return obj; - } - }; - - private static final ArgConverter ARG_BYTE = new ArgConverter() { - public Object convert(Object obj) { - if( obj instanceof Byte ) - return obj; - if( obj instanceof Number ) { - Number n = (Number)obj; - byte r = n.byteValue(); - if( r==n.doubleValue() ) - return r; - } - else if( obj instanceof String ) { - String s = (String)obj; - try { - return Byte.valueOf(s); - } catch(NumberFormatException e) {} - } - return obj; - } - }; - - private static final ArgConverter ARG_TABLE = new ArgConverter() { - public Object convert(Object obj) { - if( obj instanceof List ) { - @SuppressWarnings("unchecked") - List<Object> list = (List<Object>)obj; - return new LuaTable(list); - } - if( obj instanceof Map ) { - @SuppressWarnings("unchecked") - Map<Object,Object> map = (Map<Object,Object>)obj; - return new LuaTable(map); - } - if( obj instanceof Set ) { - @SuppressWarnings("unchecked") - Set<Object> set = (Set<Object>)obj; - return new LuaTable(set); - } - return obj; - } - }; - - private static final ArgConverter ARG_MAP = new ArgConverter() { - public Object convert(Object obj) { - if( obj instanceof LuaTable ) { - LuaTable t = (LuaTable)obj; - return t.asMap(); - } - return obj; - } - }; - - private static final ArgConverter ARG_LIST = new ArgConverter() { - public Object convert(Object obj) { - if( obj instanceof LuaTable ) { - LuaTable t = (LuaTable)obj; - if( t.isList() ) - return t.asList(); - } - return obj; - } - }; - - private static final ArgConverter ARG_SET = new ArgConverter() { - public Object convert(Object obj) { - if( obj instanceof LuaTable ) { - LuaTable t = (LuaTable)obj; - if( t.isSet() ) - return t.asSet(); - } - return obj; - } - }; - - private static boolean takesLuaState(JavaMethod m) { - Class<?>[] paramTypes = m.getParameterTypes(); - return paramTypes.length > 0 && paramTypes[0].equals(LuaState.class); - } - - private static ArgConverter[] getArgConverters(boolean takesLuaState,JavaMethod m) { - final boolean isVarArgs = m.isVarArgs(); - Class<?>[] paramTypes = m.getParameterTypes(); - if( takesLuaState ) { - Class<?>[] t = new Class<?>[paramTypes.length-1]; - System.arraycopy(paramTypes,1,t,0,t.length); - paramTypes = t; - } - ArgConverter[] a = new ArgConverter[paramTypes.length]; - for( int i=0; i<a.length; i++ ) { - Class<?> paramType = paramTypes[i]; - if( isVarArgs && i == a.length-1 ) - paramType = paramType.getComponentType(); - a[i] = getArgConverter(paramType); - } - return a; - } - - private static ArgConverter getArgConverter(Class<?> cls) { - if( cls == Double.TYPE || cls.equals(Double.class) ) - return ARG_DOUBLE; - if( cls == Float.TYPE || cls.equals(Float.class) ) - return ARG_FLOAT; - if( cls == Long.TYPE || cls.equals(Long.class) ) - return ARG_LONG; - if( cls == Integer.TYPE || cls.equals(Integer.class) ) - return ARG_INTEGER; - if( cls == Short.TYPE || cls.equals(Short.class) ) - return ARG_SHORT; - if( cls == Byte.TYPE || cls.equals(Byte.class) ) - return ARG_BYTE; - if( cls.equals(LuaTable.class) ) - return ARG_TABLE; - if( cls.equals(Map.class) ) - return ARG_MAP; - if( cls.equals(List.class) ) - return ARG_LIST; - if( cls.equals(Set.class) ) - return ARG_SET; - return ARG_SAME; - } - - - - private static abstract class JavaMethod { - abstract boolean isVarArgs(); - abstract Class<?>[] getParameterTypes(); - abstract Object invoke(Object obj,Object... args) - throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException; - abstract Class<?> getReturnType(); - - static JavaMethod of(final Method m) { - return new JavaMethod() { - @Override boolean isVarArgs() { - return m.isVarArgs(); - } - @Override Class<?>[] getParameterTypes() { - return m.getParameterTypes(); - } - @Override Object invoke(Object obj,Object... args) - throws IllegalAccessException, IllegalArgumentException, InvocationTargetException - { - return m.invoke(obj,args); - } - @Override Class<?> getReturnType() { - return m.getReturnType(); - } - @Override public String toString() { - return m.toString(); - } - }; - } - - static JavaMethod of(final Constructor c) { - return new JavaMethod() { - @Override boolean isVarArgs() { - return c.isVarArgs(); - } - @Override Class<?>[] getParameterTypes() { - return c.getParameterTypes(); - } - @Override Object invoke(Object obj,Object... args) - throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException - { - return c.newInstance(args); - } - @Override Class<?> getReturnType() { - return c.getDeclaringClass(); - } - @Override public String toString() { - return c.toString(); - } - }; - } - - } - -}
--- a/src/luan/LuaSource.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -package luan; - - -public final class LuaSource { - public final String name; - public final String text; - - public LuaSource(String name,String text) { - this.name = name; - this.text = text; - } - - public static final class Element extends LuaElement { - public final LuaSource source; - public final int start; - public final int end; - - public Element(LuaSource source,int start,int end) { - if( source==null ) - throw new NullPointerException("source is null"); - this.source = source; - this.start = start; - this.end = end; - } - - public String text() { - return source.text.substring(start,end); - } - - @Override String location() { - return source.name + ':' + lineNumber(); - } - - private int lineNumber() { - int line = 0; - int i = -1; - do { - line++; - i = source.text.indexOf('\n',i+1); - } while( i != -1 && i < start ); - return line; - } - - } -}
--- a/src/luan/LuaState.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -package luan; - -import java.util.List; -import java.util.ArrayList; - - -public abstract class LuaState { - private final LuaTable global = new LuaTable(); - private final List<MetatableGetter> mtGetters = new ArrayList<MetatableGetter>(); - final List<StackTraceElement> stackTrace = new ArrayList<StackTraceElement>(); - - public final LuaTable global() { - return global; - } - - public final LuaTable getMetatable(Object obj) { - if( obj instanceof LuaTable ) { - LuaTable table = (LuaTable)obj; - return table.getMetatable(); - } - for( MetatableGetter mg : mtGetters ) { - LuaTable table = mg.getMetatable(obj); - if( table != null ) - return table; - } - return null; - } - - public final void addMetatableGetter(MetatableGetter mg) { - mtGetters.add(mg); - } - - public Object[] call(LuaFunction fn,LuaElement calledFrom,String fnName,Object... args) throws LuaException { - stackTrace.add( new StackTraceElement(calledFrom,fnName) ); - try { - return fn.call(this,args); - } finally { - stackTrace.remove(stackTrace.size()-1); - } - } - - public final String checkString(LuaElement el,Object obj) throws LuaException { - String s = Lua.asString(obj); - if( s == null ) - throw new LuaException( this, el, "attempt to use a " + Lua.type(obj) + " as a string" ); - return s; - } - - public final Number checkNumber(LuaElement el,Object obj) throws LuaException { - Number n = Lua.toNumber(obj); - if( n == null ) - throw new LuaException( this, el, "attempt to perform arithmetic on a " + Lua.type(obj) + " value" ); - return n; - } - - public final LuaFunction checkFunction(LuaElement el,Object obj) throws LuaException { - if( obj instanceof LuaFunction ) - return (LuaFunction)obj; - throw new LuaException( this, el, "attempt to call a " + Lua.type(obj) + " value" ); - } - - public final String toString(LuaElement el,Object obj) throws LuaException { - LuaFunction fn = getHandlerFunction(el,"__tostring",obj); - if( fn != null ) - return checkString( el, Lua.first( call(fn,el,"__tostring",obj) ) ); - if( obj == null ) - return "nil"; - if( obj instanceof Number ) - return Lua.toString((Number)obj); - if( obj instanceof LuaException ) { - LuaException le = (LuaException)obj; - return le.getMessage(); - } - return obj.toString(); - } - - public final LuaFunction getHandlerFunction(LuaElement el,String op,Object obj) throws LuaException { - Object f = getHandler(op,obj); - if( f == null ) - return null; - return checkFunction(el,f); - } - - public final Object getHandler(String op,Object obj) { - LuaTable t = getMetatable(obj); - 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 Number && o2 instanceof Number ) { - Number n1 = (Number)o1; - Number n2 = (Number)o2; - return n1.doubleValue() < n2.doubleValue(); - } - 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) ); - } -}
--- a/src/luan/LuaTable.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,289 +0,0 @@ -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; -import java.util.Set; -import java.util.HashSet; - - -public class LuaTable { - 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; - } - - public LuaTable(Map<Object,Object> map) { - this.map = map; - } - - public LuaTable(Set<Object> set) { - map = new HashMap<Object,Object>(); - for( Object obj : set ) { - map.put(obj,Boolean.TRUE); - } - } - - boolean isList() { - return map==null || map.isEmpty(); - } - - List<Object> asList() { - return list!=null ? list : Collections.emptyList(); - } - - Map<Object,Object> asMap() { - if( list == null || list.isEmpty() ) - return map!=null ? map : Collections.emptyMap(); - Map<Object,Object> rtn = map!=null ? new HashMap<Object,Object>(map) : new HashMap<Object,Object>(); - for( ListIterator iter = list.listIterator(); iter.hasNext(); ) { - int i = iter.nextIndex(); - rtn.put(i+1,iter.next()); - } - return rtn; - } - - boolean isSet() { - if( list != null ) { - for( Object obj : list ) { - if( obj!=null && !obj.equals(Boolean.TRUE) ) - return false; - } - } - if( map != null ) { - for( Object obj : map.values() ) { - if( !obj.equals(Boolean.TRUE) ) - return false; - } - } - return true; - } - - Set<Object> asSet() { - if( list == null || list.isEmpty() ) - return map!=null ? map.keySet() : Collections.emptySet(); - Set<Object> rtn = map!=null ? new HashSet<Object>(map.keySet()) : new HashSet<Object>(); - for( int i=1; i<=list.size(); i++ ) { - rtn.add(i); - } - return rtn; - } - - @Override public String toString() { -// return "table: " + Integer.toHexString(hashCode()); - StringBuilder sb = new StringBuilder(); - sb.append('{'); - boolean isFirst = true; - if( list != null ) { - boolean gotNull = false; - for( int i=0; i<list.size(); i++ ) { - Object obj = list.get(i); - if( obj==null ) { - gotNull = true; - } else { - if( isFirst ) { - isFirst = false; - } else { - sb.append(", "); - } - if( gotNull ) - sb.append(i+1).append('='); - sb.append(obj); - } - } - } - if( map != null ) { - for( Map.Entry<Object,Object> entry : map.entrySet() ) { - if( isFirst ) { - isFirst = false; - } else { - sb.append(", "); - } - sb.append(entry.getKey()).append('=').append(entry.getValue()); - } - } - sb.append('}'); - return sb.toString(); - } - - public Object get(Object key) { - if( list != null ) { - Integer iT = Lua.asInteger(key); - if( iT != null ) { - int i = iT - 1; - 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) { - Integer iT = Lua.asInteger(key); - if( iT != null ) { - int i = iT - 1; - if( list != null || i == 0 ) { - if( i == list().size() ) { - if( val != null ) { - list.add(val); - mapToList(); - } - 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( key instanceof Number && !(key instanceof Double) ) { - Number n = (Number)key; - key = Double.valueOf(n.doubleValue()); - } - if( val == null ) { - return map.remove(key); - } else { - return map.put(key,val); - } - } - - private void mapToList() { - if( map != null ) { - while(true) { - Object v = map.remove(Double.valueOf(list.size()+1)); - if( v == null ) - break; - list.add(v); - } - } - } - - private List<Object> list() { - if( list == null ) { - list = new ArrayList<Object>(); - mapToList(); - } - return list; - } - - public void insert(int pos,Object value) { - list().add(pos-1,value); - } - - public Object remove(int pos) { - return list().remove(pos-1); - } - - public void sort(Comparator<Object> cmp) { - Collections.sort(list(),cmp); - } - - public int length() { - return list==null ? 0 : list.size(); - } - - public Iterator<Map.Entry<Object,Object>> 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() { - Double key = Double.valueOf(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) { - return new LuaTable(new ArrayList<Object>(list().subList(from-1,to-1))); - } - - public LuaTable getMetatable() { - return metatable; - } - - 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(); - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/Luan.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,80 @@ +package luan; + + +public class Luan { + public static final String version = "Luan 0.0"; + + public static String type(Object obj) { + if( obj == null ) + return "nil"; + if( obj instanceof String ) + return "string"; + if( obj instanceof Boolean ) + return "boolean"; + if( obj instanceof Number ) + return "number"; + return "userdata"; + } + + public static boolean toBoolean(Object obj) { + return obj != null && !Boolean.FALSE.equals(obj); + } + + public static String asString(Object obj) { + if( obj instanceof String ) + return (String)obj; + if( obj instanceof Number ) + return toString((Number)obj); + return null; + } + + public static Number toNumber(Object obj) { + return toNumber(obj,null); + } + + public static Number toNumber(Object obj,Integer base) { + if( obj instanceof Number ) + return (Number)obj; + if( obj instanceof String ) { + String s = (String)obj; + try { + if( base==null ) + return Double.valueOf(s); + else + return Long.valueOf(s,base); + } catch(NumberFormatException e) {} + } + return null; + } + + public static Object first(Object[] a) { + return a.length==0 ? null : a[0]; + } + + public static String toString(Number n) { + if( n instanceof Integer ) + return n.toString(); + String s = n.toString(); + int iE = s.indexOf('E'); + String ending = null; + if( iE != -1 ) { + ending = s.substring(iE); + s = s.substring(0,iE); + } + if( s.endsWith(".0") ) + s = s.substring(0,s.length()-2); + if( ending != null ) + s += ending; + return s; + } + + public static Integer asInteger(Object obj) { + if( obj instanceof Integer ) + return (Integer)obj; + if( !(obj instanceof Number) ) + return null; + Number n = (Number)obj; + int i = n.intValue(); + return i==n.doubleValue() ? Integer.valueOf(i) : null; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/LuanElement.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,17 @@ +package luan; + + +public abstract class LuanElement { + + final String toString(String fnName) { + return location() + ": in " + (fnName==null ? "main chunk" : "function '"+fnName+"'"); + } + + abstract String location(); + + public static final LuanElement JAVA = new LuanElement(){ + @Override String location() { + return "Java"; + } + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/LuanException.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,51 @@ +package luan; + + +public class LuanException extends Exception { + private final String stackTrace; + + public LuanException(LuanState lua,LuanElement el,Object msg) { + super(message(msg),cause(msg)); + stackTrace = stackTrace(lua,el,msg); + } + + @Override public String getMessage() { + return super.getMessage() + stackTrace; + } + + private String message() { + return super.getMessage(); + } + + private static Throwable cause(Object msg) { + return msg instanceof Throwable ? (Throwable)msg : null; + } + + private static String message(Object msg) { + if( msg instanceof LuanException ) { + LuanException le = (LuanException)msg; + return le.message(); +/* + } else if( msg instanceof Throwable ) { + Throwable t = (Throwable)msg; + return t.getMessage(); +*/ + } else { + return msg.toString(); + } + } + + private static String stackTrace(LuanState lua,LuanElement el,Object msg) { + StringBuilder buf = new StringBuilder(); + for( int i = lua.stackTrace.size() - 1; i>=0; i-- ) { + StackTraceElement stackTraceElement = lua.stackTrace.get(i); + buf.append( "\n\t" ).append( el.toString(stackTraceElement.fnName) ); + el = stackTraceElement.call; + } + if( msg instanceof LuanException ) { + LuanException le = (LuanException)msg; + buf.append( "\ncaused by:" ).append( le.stackTrace ); + } + return buf.toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/LuanFunction.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,14 @@ +package luan; + + +public abstract class LuanFunction { + + public abstract Object[] call(LuanState lua,Object[] args) throws LuanException; + + public static final Object[] EMPTY_RTN = new Object[0]; + + @Override public String toString() { + return "function: " + Integer.toHexString(hashCode()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/LuanJavaFunction.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,465 @@ +package luan; + +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +public final class LuanJavaFunction extends LuanFunction { + private final JavaMethod method; + private final Object obj; + private final RtnConverter rtnConverter; + private final boolean takesLuaState; + private final ArgConverter[] argConverters; + private final Class<?> varArgCls; + + public LuanJavaFunction(Method method,Object obj) { + this( JavaMethod.of(method), obj ); + } + + public LuanJavaFunction(Constructor constr,Object obj) { + this( JavaMethod.of(constr), obj ); + } + + LuanJavaFunction(JavaMethod method,Object obj) { + this.method = method; + this.obj = obj; + this.rtnConverter = getRtnConverter(method); + this.takesLuaState = takesLuaState(method); + this.argConverters = getArgConverters(takesLuaState,method); + if( method.isVarArgs() ) { + Class<?>[] paramTypes = method.getParameterTypes(); + this.varArgCls = paramTypes[paramTypes.length-1].getComponentType(); + } else { + this.varArgCls = null; + } + } + + public Class<?>[] getParameterTypes() { + return method.getParameterTypes(); + } + + @Override public Object[] call(LuanState lua,Object[] args) throws LuanException { + args = fixArgs(lua,args); + Object rtn; + try { + rtn = method.invoke(obj,args); + } catch(IllegalArgumentException e) { + checkArgs(lua,args); + throw e; + } catch(IllegalAccessException e) { + throw new RuntimeException(e); + } catch(InvocationTargetException e) { + Throwable cause = e.getCause(); + if( cause instanceof Error ) + throw (Error)cause; + if( cause instanceof RuntimeException ) + throw (RuntimeException)cause; + if( cause instanceof LuanException ) + throw (LuanException)cause; + throw new RuntimeException(e); + } catch(InstantiationException e) { + throw new RuntimeException(e); + } + return rtnConverter.convert(rtn); + } + + private void checkArgs(LuanState lua,Object[] args) throws LuanException { + Class<?>[] a = getParameterTypes(); + for( int i=0; i<a.length; i++ ) { + if( !a[i].isInstance(args[i]) ) { + String got = args[i].getClass().getName(); + String expected = a[i].getName(); + if( !takesLuaState ) + i++; + throw new LuanException(lua,LuanElement.JAVA,"bad argument #"+i+" ("+expected+" expected, got "+got+")"); + } + } + } + + private Object[] fixArgs(LuanState lua,Object[] args) { + int n = argConverters.length; + Object[] rtn; + int start = 0; + if( !takesLuaState && varArgCls==null && args.length == n ) { + rtn = args; + } else { + if( takesLuaState ) + n++; + rtn = new Object[n]; + if( takesLuaState ) { + rtn[start++] = lua; + } + n = argConverters.length; + if( varArgCls != null ) { + n--; + if( args.length < argConverters.length ) { + rtn[rtn.length-1] = Array.newInstance(varArgCls,0); + } else { + int len = args.length - n; + Object varArgs = Array.newInstance(varArgCls,len); + ArgConverter ac = argConverters[n]; + for( int i=0; i<len; i++ ) { + Array.set( varArgs, i, ac.convert(args[n+i]) ); + } + rtn[rtn.length-1] = varArgs; + } + } + System.arraycopy(args,0,rtn,start,Math.min(args.length,n)); + } + for( int i=0; i<n; i++ ) { + rtn[start+i] = argConverters[i].convert(rtn[start+i]); + } + return rtn; + } + + + private interface RtnConverter { + public Object[] convert(Object obj); + } + + private static final RtnConverter RTN_EMPTY = new RtnConverter() { + public Object[] convert(Object obj) { + return EMPTY_RTN; + } + }; + + private static final RtnConverter RTN_ARRAY = new RtnConverter() { + public Object[] convert(Object obj) { + if( obj == null ) + return NULL_RTN; + return (Object[])obj; + } + }; + + private static final RtnConverter RTN_ONE = new RtnConverter() { + public Object[] convert(Object obj) { + return new Object[]{obj}; + } + }; + + private static final Object[] NULL_RTN = new Object[1]; + + private static final RtnConverter RTN_NUMBER_ARRAY = new RtnConverter() { + public Object[] convert(Object obj) { + if( obj == null ) + return NULL_RTN; + Object[] rtn = new Object[Array.getLength(obj)]; + for( int i=0; i<rtn.length; i++ ) { + rtn[i] = Array.get(obj,i); + } + return rtn; + } + }; + + private static RtnConverter getRtnConverter(JavaMethod m) { + Class<?> rtnType = m.getReturnType(); + if( rtnType == Void.TYPE ) + return RTN_EMPTY; + if( rtnType.isArray() ) { + rtnType = rtnType.getComponentType(); + if( isNumber(rtnType) ) + return RTN_NUMBER_ARRAY; + return RTN_ARRAY; + } + return RTN_ONE; + } + + private static boolean isNumber(Class<?> rtnType) { + return rtnType == Byte.TYPE + || rtnType == Short.TYPE + || rtnType == Integer.TYPE + || rtnType == Long.TYPE + || rtnType == Float.TYPE + || rtnType == Double.TYPE + ; + } + + private interface ArgConverter { + public Object convert(Object obj); + } + + private static final ArgConverter ARG_SAME = new ArgConverter() { + public Object convert(Object obj) { + return obj; + } + }; + + private static final ArgConverter ARG_DOUBLE = new ArgConverter() { + public Object convert(Object obj) { + if( obj instanceof Double ) + return obj; + if( obj instanceof Number ) { + Number n = (Number)obj; + return n.doubleValue(); + } + if( obj instanceof String ) { + String s = (String)obj; + try { + return Double.valueOf(s); + } catch(NumberFormatException e) {} + } + return obj; + } + }; + + private static final ArgConverter ARG_FLOAT = new ArgConverter() { + public Object convert(Object obj) { + if( obj instanceof Float ) + return obj; + if( obj instanceof Number ) { + Number n = (Number)obj; + float r = n.floatValue(); + if( r==n.doubleValue() ) + return r; + } + if( obj instanceof String ) { + String s = (String)obj; + try { + return Float.valueOf(s); + } catch(NumberFormatException e) {} + } + return obj; + } + }; + + private static final ArgConverter ARG_LONG = new ArgConverter() { + public Object convert(Object obj) { + if( obj instanceof Long ) + return obj; + if( obj instanceof Number ) { + Number n = (Number)obj; + long r = n.longValue(); + if( r==n.doubleValue() ) + return r; + } + else if( obj instanceof String ) { + String s = (String)obj; + try { + return Long.valueOf(s); + } catch(NumberFormatException e) {} + } + return obj; + } + }; + + private static final ArgConverter ARG_INTEGER = new ArgConverter() { + public Object convert(Object obj) { + if( obj instanceof Integer ) + return obj; + if( obj instanceof Number ) { + Number n = (Number)obj; + int r = n.intValue(); + if( r==n.doubleValue() ) + return r; + } + else if( obj instanceof String ) { + String s = (String)obj; + try { + return Integer.valueOf(s); + } catch(NumberFormatException e) {} + } + return obj; + } + }; + + private static final ArgConverter ARG_SHORT = new ArgConverter() { + public Object convert(Object obj) { + if( obj instanceof Short ) + return obj; + if( obj instanceof Number ) { + Number n = (Number)obj; + short r = n.shortValue(); + if( r==n.doubleValue() ) + return r; + } + else if( obj instanceof String ) { + String s = (String)obj; + try { + return Short.valueOf(s); + } catch(NumberFormatException e) {} + } + return obj; + } + }; + + private static final ArgConverter ARG_BYTE = new ArgConverter() { + public Object convert(Object obj) { + if( obj instanceof Byte ) + return obj; + if( obj instanceof Number ) { + Number n = (Number)obj; + byte r = n.byteValue(); + if( r==n.doubleValue() ) + return r; + } + else if( obj instanceof String ) { + String s = (String)obj; + try { + return Byte.valueOf(s); + } catch(NumberFormatException e) {} + } + return obj; + } + }; + + private static final ArgConverter ARG_TABLE = new ArgConverter() { + public Object convert(Object obj) { + if( obj instanceof List ) { + @SuppressWarnings("unchecked") + List<Object> list = (List<Object>)obj; + return new LuanTable(list); + } + if( obj instanceof Map ) { + @SuppressWarnings("unchecked") + Map<Object,Object> map = (Map<Object,Object>)obj; + return new LuanTable(map); + } + if( obj instanceof Set ) { + @SuppressWarnings("unchecked") + Set<Object> set = (Set<Object>)obj; + return new LuanTable(set); + } + return obj; + } + }; + + private static final ArgConverter ARG_MAP = new ArgConverter() { + public Object convert(Object obj) { + if( obj instanceof LuanTable ) { + LuanTable t = (LuanTable)obj; + return t.asMap(); + } + return obj; + } + }; + + private static final ArgConverter ARG_LIST = new ArgConverter() { + public Object convert(Object obj) { + if( obj instanceof LuanTable ) { + LuanTable t = (LuanTable)obj; + if( t.isList() ) + return t.asList(); + } + return obj; + } + }; + + private static final ArgConverter ARG_SET = new ArgConverter() { + public Object convert(Object obj) { + if( obj instanceof LuanTable ) { + LuanTable t = (LuanTable)obj; + if( t.isSet() ) + return t.asSet(); + } + return obj; + } + }; + + private static boolean takesLuaState(JavaMethod m) { + Class<?>[] paramTypes = m.getParameterTypes(); + return paramTypes.length > 0 && paramTypes[0].equals(LuanState.class); + } + + private static ArgConverter[] getArgConverters(boolean takesLuaState,JavaMethod m) { + final boolean isVarArgs = m.isVarArgs(); + Class<?>[] paramTypes = m.getParameterTypes(); + if( takesLuaState ) { + Class<?>[] t = new Class<?>[paramTypes.length-1]; + System.arraycopy(paramTypes,1,t,0,t.length); + paramTypes = t; + } + ArgConverter[] a = new ArgConverter[paramTypes.length]; + for( int i=0; i<a.length; i++ ) { + Class<?> paramType = paramTypes[i]; + if( isVarArgs && i == a.length-1 ) + paramType = paramType.getComponentType(); + a[i] = getArgConverter(paramType); + } + return a; + } + + private static ArgConverter getArgConverter(Class<?> cls) { + if( cls == Double.TYPE || cls.equals(Double.class) ) + return ARG_DOUBLE; + if( cls == Float.TYPE || cls.equals(Float.class) ) + return ARG_FLOAT; + if( cls == Long.TYPE || cls.equals(Long.class) ) + return ARG_LONG; + if( cls == Integer.TYPE || cls.equals(Integer.class) ) + return ARG_INTEGER; + if( cls == Short.TYPE || cls.equals(Short.class) ) + return ARG_SHORT; + if( cls == Byte.TYPE || cls.equals(Byte.class) ) + return ARG_BYTE; + if( cls.equals(LuanTable.class) ) + return ARG_TABLE; + if( cls.equals(Map.class) ) + return ARG_MAP; + if( cls.equals(List.class) ) + return ARG_LIST; + if( cls.equals(Set.class) ) + return ARG_SET; + return ARG_SAME; + } + + + + private static abstract class JavaMethod { + abstract boolean isVarArgs(); + abstract Class<?>[] getParameterTypes(); + abstract Object invoke(Object obj,Object... args) + throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException; + abstract Class<?> getReturnType(); + + static JavaMethod of(final Method m) { + return new JavaMethod() { + @Override boolean isVarArgs() { + return m.isVarArgs(); + } + @Override Class<?>[] getParameterTypes() { + return m.getParameterTypes(); + } + @Override Object invoke(Object obj,Object... args) + throws IllegalAccessException, IllegalArgumentException, InvocationTargetException + { + return m.invoke(obj,args); + } + @Override Class<?> getReturnType() { + return m.getReturnType(); + } + @Override public String toString() { + return m.toString(); + } + }; + } + + static JavaMethod of(final Constructor c) { + return new JavaMethod() { + @Override boolean isVarArgs() { + return c.isVarArgs(); + } + @Override Class<?>[] getParameterTypes() { + return c.getParameterTypes(); + } + @Override Object invoke(Object obj,Object... args) + throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException + { + return c.newInstance(args); + } + @Override Class<?> getReturnType() { + return c.getDeclaringClass(); + } + @Override public String toString() { + return c.toString(); + } + }; + } + + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/LuanSource.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,45 @@ +package luan; + + +public final class LuanSource { + public final String name; + public final String text; + + public LuanSource(String name,String text) { + this.name = name; + this.text = text; + } + + public static final class Element extends LuanElement { + public final LuanSource source; + public final int start; + public final int end; + + public Element(LuanSource source,int start,int end) { + if( source==null ) + throw new NullPointerException("source is null"); + this.source = source; + this.start = start; + this.end = end; + } + + public String text() { + return source.text.substring(start,end); + } + + @Override String location() { + return source.name + ':' + lineNumber(); + } + + private int lineNumber() { + int line = 0; + int i = -1; + do { + line++; + i = source.text.indexOf('\n',i+1); + } while( i != -1 && i < start ); + return line; + } + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/LuanState.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,113 @@ +package luan; + +import java.util.List; +import java.util.ArrayList; + + +public abstract class LuanState { + private final LuanTable global = new LuanTable(); + private final List<MetatableGetter> mtGetters = new ArrayList<MetatableGetter>(); + final List<StackTraceElement> stackTrace = new ArrayList<StackTraceElement>(); + + public final LuanTable global() { + return global; + } + + public final LuanTable getMetatable(Object obj) { + if( obj instanceof LuanTable ) { + LuanTable table = (LuanTable)obj; + return table.getMetatable(); + } + for( MetatableGetter mg : mtGetters ) { + LuanTable table = mg.getMetatable(obj); + if( table != null ) + return table; + } + return null; + } + + public final void addMetatableGetter(MetatableGetter mg) { + mtGetters.add(mg); + } + + public Object[] call(LuanFunction fn,LuanElement calledFrom,String fnName,Object... args) throws LuanException { + stackTrace.add( new StackTraceElement(calledFrom,fnName) ); + try { + return fn.call(this,args); + } finally { + stackTrace.remove(stackTrace.size()-1); + } + } + + public final String checkString(LuanElement el,Object obj) throws LuanException { + String s = Luan.asString(obj); + if( s == null ) + throw new LuanException( this, el, "attempt to use a " + Luan.type(obj) + " as a string" ); + return s; + } + + public final Number checkNumber(LuanElement el,Object obj) throws LuanException { + Number n = Luan.toNumber(obj); + if( n == null ) + throw new LuanException( this, el, "attempt to perform arithmetic on a " + Luan.type(obj) + " value" ); + return n; + } + + public final LuanFunction checkFunction(LuanElement el,Object obj) throws LuanException { + if( obj instanceof LuanFunction ) + return (LuanFunction)obj; + throw new LuanException( this, el, "attempt to call a " + Luan.type(obj) + " value" ); + } + + public final String toString(LuanElement el,Object obj) throws LuanException { + LuanFunction fn = getHandlerFunction(el,"__tostring",obj); + if( fn != null ) + return checkString( el, Luan.first( call(fn,el,"__tostring",obj) ) ); + if( obj == null ) + return "nil"; + if( obj instanceof Number ) + return Luan.toString((Number)obj); + if( obj instanceof LuanException ) { + LuanException le = (LuanException)obj; + return le.getMessage(); + } + return obj.toString(); + } + + public final LuanFunction getHandlerFunction(LuanElement el,String op,Object obj) throws LuanException { + Object f = getHandler(op,obj); + if( f == null ) + return null; + return checkFunction(el,f); + } + + public final Object getHandler(String op,Object obj) { + LuanTable t = getMetatable(obj); + return t==null ? null : t.get(op); + } + + + public final LuanFunction getBinHandler(LuanElement el,String op,Object o1,Object o2) throws LuanException { + LuanFunction f1 = getHandlerFunction(el,op,o1); + if( f1 != null ) + return f1; + return getHandlerFunction(el,op,o2); + } + + public final boolean isLessThan(LuanElement el,Object o1,Object o2) throws LuanException { + if( o1 instanceof Number && o2 instanceof Number ) { + Number n1 = (Number)o1; + Number n2 = (Number)o2; + return n1.doubleValue() < n2.doubleValue(); + } + if( o1 instanceof String && o2 instanceof String ) { + String s1 = (String)o1; + String s2 = (String)o2; + return s1.compareTo(s2) < 0; + } + LuanFunction fn = getBinHandler(el,"__lt",o1,o2); + if( fn != null ) + return Luan.toBoolean( Luan.first(call(fn,el,"__lt",o1,o2)) ); + throw new LuanException( this, el, "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) ); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/LuanTable.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,289 @@ +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; +import java.util.Set; +import java.util.HashSet; + + +public class LuanTable { + private Map<Object,Object> map = null; + private List<Object> list = null; + private LuanTable metatable = null; + + public LuanTable() {} + + public LuanTable(List<Object> list) { + this.list = list; + } + + public LuanTable(Map<Object,Object> map) { + this.map = map; + } + + public LuanTable(Set<Object> set) { + map = new HashMap<Object,Object>(); + for( Object obj : set ) { + map.put(obj,Boolean.TRUE); + } + } + + boolean isList() { + return map==null || map.isEmpty(); + } + + List<Object> asList() { + return list!=null ? list : Collections.emptyList(); + } + + Map<Object,Object> asMap() { + if( list == null || list.isEmpty() ) + return map!=null ? map : Collections.emptyMap(); + Map<Object,Object> rtn = map!=null ? new HashMap<Object,Object>(map) : new HashMap<Object,Object>(); + for( ListIterator iter = list.listIterator(); iter.hasNext(); ) { + int i = iter.nextIndex(); + rtn.put(i+1,iter.next()); + } + return rtn; + } + + boolean isSet() { + if( list != null ) { + for( Object obj : list ) { + if( obj!=null && !obj.equals(Boolean.TRUE) ) + return false; + } + } + if( map != null ) { + for( Object obj : map.values() ) { + if( !obj.equals(Boolean.TRUE) ) + return false; + } + } + return true; + } + + Set<Object> asSet() { + if( list == null || list.isEmpty() ) + return map!=null ? map.keySet() : Collections.emptySet(); + Set<Object> rtn = map!=null ? new HashSet<Object>(map.keySet()) : new HashSet<Object>(); + for( int i=1; i<=list.size(); i++ ) { + rtn.add(i); + } + return rtn; + } + + @Override public String toString() { +// return "table: " + Integer.toHexString(hashCode()); + StringBuilder sb = new StringBuilder(); + sb.append('{'); + boolean isFirst = true; + if( list != null ) { + boolean gotNull = false; + for( int i=0; i<list.size(); i++ ) { + Object obj = list.get(i); + if( obj==null ) { + gotNull = true; + } else { + if( isFirst ) { + isFirst = false; + } else { + sb.append(", "); + } + if( gotNull ) + sb.append(i+1).append('='); + sb.append(obj); + } + } + } + if( map != null ) { + for( Map.Entry<Object,Object> entry : map.entrySet() ) { + if( isFirst ) { + isFirst = false; + } else { + sb.append(", "); + } + sb.append(entry.getKey()).append('=').append(entry.getValue()); + } + } + sb.append('}'); + return sb.toString(); + } + + public Object get(Object key) { + if( list != null ) { + Integer iT = Luan.asInteger(key); + if( iT != null ) { + int i = iT - 1; + 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) { + Integer iT = Luan.asInteger(key); + if( iT != null ) { + int i = iT - 1; + if( list != null || i == 0 ) { + if( i == list().size() ) { + if( val != null ) { + list.add(val); + mapToList(); + } + 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( key instanceof Number && !(key instanceof Double) ) { + Number n = (Number)key; + key = Double.valueOf(n.doubleValue()); + } + if( val == null ) { + return map.remove(key); + } else { + return map.put(key,val); + } + } + + private void mapToList() { + if( map != null ) { + while(true) { + Object v = map.remove(Double.valueOf(list.size()+1)); + if( v == null ) + break; + list.add(v); + } + } + } + + private List<Object> list() { + if( list == null ) { + list = new ArrayList<Object>(); + mapToList(); + } + return list; + } + + public void insert(int pos,Object value) { + list().add(pos-1,value); + } + + public Object remove(int pos) { + return list().remove(pos-1); + } + + public void sort(Comparator<Object> cmp) { + Collections.sort(list(),cmp); + } + + public int length() { + return list==null ? 0 : list.size(); + } + + public Iterator<Map.Entry<Object,Object>> 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() { + Double key = Double.valueOf(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 LuanTable subList(int from,int to) { + return new LuanTable(new ArrayList<Object>(list().subList(from-1,to-1))); + } + + public LuanTable getMetatable() { + return metatable; + } + + public void setMetatable(LuanTable 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(); + } + } +}
--- a/src/luan/MetatableGetter.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/MetatableGetter.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,5 +1,5 @@ package luan; public interface MetatableGetter { - public LuaTable getMetatable(Object obj); + public LuanTable getMetatable(Object obj); }
--- a/src/luan/StackTraceElement.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/StackTraceElement.java Fri Dec 28 03:29:12 2012 +0000 @@ -2,10 +2,10 @@ final class StackTraceElement { - final LuaElement call; + final LuanElement call; final String fnName; - StackTraceElement(LuaElement call,String fnName) { + StackTraceElement(LuanElement call,String fnName) { this.call = call; this.fnName = fnName; }
--- a/src/luan/interp/AddExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/AddExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,21 +1,21 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class AddExpr extends BinaryOpExpr { - AddExpr(LuaSource.Element se,Expr op1,Expr op2) { + AddExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); - Number n1 = Lua.toNumber(o1); - Number n2 = Lua.toNumber(o2); + Number n1 = Luan.toNumber(o1); + Number n2 = Luan.toNumber(o2); if( n1 != null && n2 != null ) return n1.doubleValue() + n2.doubleValue(); return arithmetic(lua,"__add",o1,o2);
--- a/src/luan/interp/AndExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/AndExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,18 +1,18 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class AndExpr extends BinaryOpExpr { - AndExpr(LuaSource.Element se,Expr op1,Expr op2) { + AndExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object v1 = op1.eval(lua); - return !Lua.toBoolean(v1) ? v1 : op2.eval(lua); + return !Luan.toBoolean(v1) ? v1 : op2.eval(lua); } }
--- a/src/luan/interp/BinaryOpExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/BinaryOpExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,23 +1,23 @@ package luan.interp; -import luan.Lua; -import luan.LuaTable; -import luan.LuaFunction; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanTable; +import luan.LuanFunction; +import luan.LuanException; +import luan.LuanSource; abstract class BinaryOpExpr extends CodeImpl implements Expr { final Expr op1; final Expr op2; - BinaryOpExpr(LuaSource.Element se,Expr op1,Expr op2) { + BinaryOpExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se); this.op1 = op1; this.op2 = op2; } - Object arithmetic(LuaStateImpl lua,String op,Object o1,Object o2) throws LuaException { + Object arithmetic(LuanStateImpl lua,String op,Object o1,Object o2) throws LuanException { return lua.arithmetic(se(),"__mod",o1,o2); }
--- a/src/luan/interp/Block.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/Block.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,6 +1,6 @@ package luan.interp; -import luan.LuaException; +import luan.LuanException; final class Block implements Stmt { @@ -16,7 +16,7 @@ this.stackEnd = stackEnd; } - @Override public void eval(LuaStateImpl lua) throws LuaException { + @Override public void eval(LuanStateImpl lua) throws LuanException { try { for( Stmt stmt : stmts ) { stmt.eval(lua);
--- a/src/luan/interp/BreakStmt.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/BreakStmt.java Fri Dec 28 03:29:12 2012 +0000 @@ -3,7 +3,7 @@ final class BreakStmt implements Stmt { - @Override public void eval(LuaStateImpl lua) { + @Override public void eval(LuanStateImpl lua) { throw new BreakException(); } }
--- a/src/luan/interp/Chunk.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/Chunk.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,7 +1,7 @@ package luan.interp; -import luan.LuaException; -import luan.LuaSource; +import luan.LuanException; +import luan.LuanSource; final class Chunk extends CodeImpl implements Expr { @@ -11,7 +11,7 @@ final boolean isVarArg; final UpValue.Getter[] upValueGetters; - Chunk(LuaSource.Element se,Stmt block,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { + Chunk(LuanSource.Element se,Stmt block,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { super(se); this.block = block; this.stackSize = stackSize; @@ -35,11 +35,11 @@ } } - LuaClosure newClosure(LuaStateImpl lua) { - return new LuaClosure(this,lua); + Closure newClosure(LuanStateImpl lua) { + return new Closure(this,lua); } - @Override public Object eval(LuaStateImpl lua) { + @Override public Object eval(LuanStateImpl lua) { return newClosure(lua); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/Closure.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,66 @@ +package luan.interp; + +import luan.LuanFunction; +import luan.LuanState; +import luan.LuanElement; +import luan.LuanException; + + +final class Closure extends LuanFunction { + private final Chunk chunk; + final UpValue[] upValues; + private final static UpValue[] NO_UP_VALUES = new UpValue[0]; + + Closure(Chunk chunk,LuanStateImpl lua) { + this.chunk = chunk; + UpValue.Getter[] upValueGetters = chunk.upValueGetters; + if( upValueGetters.length==0 ) { + upValues = NO_UP_VALUES; + } else { + upValues = new UpValue[upValueGetters.length]; + for( int i=0; i<upValues.length; i++ ) { + upValues[i] = upValueGetters[i].get(lua); + } + } + } + + public Object[] call(LuanState lua,Object[] args) throws LuanException { + return call(this,(LuanStateImpl)lua,args); + } + + private static Object[] call(Closure closure,LuanStateImpl lua,Object[] args) throws LuanException { + while(true) { + Chunk chunk = closure.chunk; + Object[] varArgs = null; + if( chunk.isVarArg ) { + if( args.length > chunk.numArgs ) { + varArgs = new Object[ args.length - chunk.numArgs ]; + for( int i=0; i<varArgs.length; i++ ) { + varArgs[i] = args[chunk.numArgs+i]; + } + } else { + varArgs = LuanFunction.EMPTY_RTN; + } + } + Object[] stack = lua.newFrame(closure,chunk.stackSize,varArgs); + final int n = Math.min(args.length,chunk.numArgs); + for( int i=0; i<n; i++ ) { + stack[i] = args[i]; + } + Object[] returnValues; + Closure tailFn; + try { + chunk.block.eval(lua); + } catch(ReturnException e) { + } finally { + returnValues = lua.returnValues; + closure = lua.tailFn; + lua.popFrame(); + } + if( closure == null ) + return returnValues; + args = returnValues; + } + } + +}
--- a/src/luan/interp/Code.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/Code.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,8 +1,8 @@ package luan.interp; -import luan.LuaSource; +import luan.LuanSource; interface Code { - public LuaSource.Element se(); + public LuanSource.Element se(); }
--- a/src/luan/interp/CodeImpl.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/CodeImpl.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,16 +1,16 @@ package luan.interp; -import luan.LuaSource; +import luan.LuanSource; class CodeImpl implements Code { - final LuaSource.Element se; + final LuanSource.Element se; - CodeImpl(LuaSource.Element se) { + CodeImpl(LuanSource.Element se) { this.se = se; } - @Override public final LuaSource.Element se() { + @Override public final LuanSource.Element se() { return se; } }
--- a/src/luan/interp/ConcatExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/ConcatExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,28 +1,28 @@ package luan.interp; -import luan.Lua; -import luan.LuaFunction; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanFunction; +import luan.LuanException; +import luan.LuanSource; final class ConcatExpr extends BinaryOpExpr { - ConcatExpr(LuaSource.Element se,Expr op1,Expr op2) { + ConcatExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); - String s1 = Lua.asString(o1); - String s2 = Lua.asString(o2); + String s1 = Luan.asString(o1); + String s2 = Luan.asString(o2); if( s1 != null && s2 != null ) return s1 + s2; - LuaFunction fn = lua.getBinHandler(se,"__concat",o1,o2); + LuanFunction fn = lua.getBinHandler(se,"__concat",o1,o2); if( fn != null ) - return Lua.first(lua.call(fn,se,"__concat",o1,o2)); - String type = s1==null ? Lua.type(o1) : Lua.type(o2); - throw new LuaException( lua, se, "attempt to concatenate a " + type + " value" ); + return Luan.first(lua.call(fn,se,"__concat",o1,o2)); + String type = s1==null ? Luan.type(o1) : Luan.type(o2); + throw new LuanException( lua, se, "attempt to concatenate a " + type + " value" ); } }
--- a/src/luan/interp/ConstExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/ConstExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,6 +1,6 @@ package luan.interp; -import luan.LuaSource; +import luan.LuanSource; final class ConstExpr implements Expr { @@ -10,11 +10,11 @@ this.obj = obj; } - @Override public Object eval(LuaStateImpl lua) { + @Override public Object eval(LuanStateImpl lua) { return obj; } - @Override public final LuaSource.Element se() { + @Override public final LuanSource.Element se() { return null; } }
--- a/src/luan/interp/DivExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/DivExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,21 +1,21 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class DivExpr extends BinaryOpExpr { - DivExpr(LuaSource.Element se,Expr op1,Expr op2) { + DivExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); - Number n1 = Lua.toNumber(o1); - Number n2 = Lua.toNumber(o2); + Number n1 = Luan.toNumber(o1); + Number n2 = Luan.toNumber(o2); if( n1 != null && n2 != null ) return n1.doubleValue() / n2.doubleValue(); return arithmetic(lua,"__div",o1,o2);
--- a/src/luan/interp/EqExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/EqExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,19 +1,19 @@ package luan.interp; -import luan.Lua; -import luan.LuaFunction; -import luan.LuaTable; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanFunction; +import luan.LuanTable; +import luan.LuanException; +import luan.LuanSource; final class EqExpr extends BinaryOpExpr { - EqExpr(LuaSource.Element se,Expr op1,Expr op2) { + EqExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); if( o1 == o2 || o1 != null && o1.equals(o2) ) @@ -25,14 +25,14 @@ } if( !o1.getClass().equals(o2.getClass()) ) return false; - LuaTable mt1 = lua.getMetatable(o1); - LuaTable mt2 = lua.getMetatable(o2); + LuanTable mt1 = lua.getMetatable(o1); + LuanTable mt2 = lua.getMetatable(o2); if( mt1==null || mt2==null ) return false; Object f = mt1.get("__eq"); if( f == null || !f.equals(mt2.get("__eq")) ) return null; - LuaFunction fn = lua.checkFunction(se,f); - return Lua.toBoolean( Lua.first(lua.call(fn,se,"__eq",o1,o2)) ); + LuanFunction fn = lua.checkFunction(se,f); + return Luan.toBoolean( Luan.first(lua.call(fn,se,"__eq",o1,o2)) ); } }
--- a/src/luan/interp/ExpList.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/ExpList.java Fri Dec 28 03:29:12 2012 +0000 @@ -3,14 +3,14 @@ import java.util.List; import java.util.ArrayList; import java.util.Collections; -import luan.LuaException; -import luan.LuaSource; +import luan.LuanException; +import luan.LuanSource; final class ExpList implements Expressions { private interface Adder { - public void addTo(LuaStateImpl lua,List<Object> list) throws LuaException; + public void addTo(LuanStateImpl lua,List<Object> list) throws LuanException; public Code code(); } @@ -21,7 +21,7 @@ this.expr = expr; } - public void addTo(LuaStateImpl lua,List<Object> list) throws LuaException { + public void addTo(LuanStateImpl lua,List<Object> list) throws LuanException { list.add( expr.eval(lua) ); } @@ -38,7 +38,7 @@ this.expressions = expressions; } - public void addTo(LuaStateImpl lua,List<Object> list) throws LuaException { + public void addTo(LuanStateImpl lua,List<Object> list) throws LuanException { for( Object val : expressions.eval(lua) ) { list.add( val ); } @@ -81,11 +81,11 @@ static final Expressions emptyExpList = new Expressions() { - @Override public Object[] eval(LuaStateImpl lua) { + @Override public Object[] eval(LuanStateImpl lua) { return EMPTY; } - @Override public LuaSource.Element se() { + @Override public LuanSource.Element se() { return null; } }; @@ -97,11 +97,11 @@ this.expr = expr; } - @Override public Object[] eval(LuaStateImpl lua) throws LuaException { + @Override public Object[] eval(LuanStateImpl lua) throws LuanException { return new Object[]{expr.eval(lua)}; } - @Override public LuaSource.Element se() { + @Override public LuanSource.Element se() { return expr.se(); } } @@ -112,7 +112,7 @@ this.adders = adders; } - @Override public Object[] eval(LuaStateImpl lua) throws LuaException { + @Override public Object[] eval(LuanStateImpl lua) throws LuanException { List<Object> list = new ArrayList<Object>(); for( Adder adder : adders ) { adder.addTo(lua,list); @@ -120,7 +120,7 @@ return list.toArray(); } - @Override public LuaSource.Element se() { - return new LuaSource.Element(adders[0].code().se().source,adders[0].code().se().start,adders[adders.length-1].code().se().end); + @Override public LuanSource.Element se() { + return new LuanSource.Element(adders[0].code().se().source,adders[0].code().se().start,adders[adders.length-1].code().se().end); } }
--- a/src/luan/interp/Expr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/Expr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,8 +1,8 @@ package luan.interp; -import luan.LuaException; +import luan.LuanException; interface Expr extends Code { - public Object eval(LuaStateImpl lua) throws LuaException; + public Object eval(LuanStateImpl lua) throws LuanException; }
--- a/src/luan/interp/Expressions.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/Expressions.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,8 +1,8 @@ package luan.interp; -import luan.LuaException; +import luan.LuanException; interface Expressions extends Code { - public Object[] eval(LuaStateImpl lua) throws LuaException; + public Object[] eval(LuanStateImpl lua) throws LuanException; }
--- a/src/luan/interp/ExpressionsExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/ExpressionsExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,9 +1,9 @@ package luan.interp; import java.util.List; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class ExpressionsExpr implements Expr { @@ -13,11 +13,11 @@ this.expressions = expressions; } - @Override public Object eval(LuaStateImpl lua) throws LuaException { - return Lua.first( expressions.eval(lua) ); + @Override public Object eval(LuanStateImpl lua) throws LuanException { + return Luan.first( expressions.eval(lua) ); } - public LuaSource.Element se() { + public LuanSource.Element se() { return expressions.se(); }
--- a/src/luan/interp/ExpressionsStmt.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/ExpressionsStmt.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,6 +1,6 @@ package luan.interp; -import luan.LuaException; +import luan.LuanException; final class ExpressionsStmt implements Stmt { @@ -10,7 +10,7 @@ this.expressions = expressions; } - @Override public void eval(LuaStateImpl lua) throws LuaException { + @Override public void eval(LuanStateImpl lua) throws LuanException { expressions.eval(lua); }
--- a/src/luan/interp/FnCall.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/FnCall.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,9 +1,9 @@ package luan.interp; -import luan.Lua; -import luan.LuaFunction; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanFunction; +import luan.LuanException; +import luan.LuanSource; final class FnCall extends CodeImpl implements Expressions { @@ -11,25 +11,25 @@ final Expressions args; final String fnName; - FnCall(LuaSource.Element se,Expr fnExpr,Expressions args) { + FnCall(LuanSource.Element se,Expr fnExpr,Expressions args) { super(se); this.fnExpr = fnExpr; this.args = args; this.fnName = fnExpr.se().text(); } - @Override public Object[] eval(LuaStateImpl lua) throws LuaException { + @Override public Object[] eval(LuanStateImpl lua) throws LuanException { return call( lua, fnExpr.eval(lua) ); } - private Object[] call(LuaStateImpl lua,Object o) throws LuaException { - if( o instanceof LuaFunction ) { - LuaFunction fn = (LuaFunction)o; + private Object[] call(LuanStateImpl lua,Object o) throws LuanException { + if( o instanceof LuanFunction ) { + LuanFunction fn = (LuanFunction)o; return lua.call( fn, se, fnName, args.eval(lua) ); } Object h = lua.getHandler("__call",o); if( h != null ) return call(lua,h); - throw new LuaException( lua, se, "attempt to call a " + Lua.type(o) + " value" ); + throw new LuanException( lua, se, "attempt to call a " + Luan.type(o) + " value" ); } }
--- a/src/luan/interp/GenericForStmt.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/GenericForStmt.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,9 +1,9 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaFunction; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanFunction; +import luan.LuanSource; final class GenericForStmt extends CodeImpl implements Stmt { @@ -12,7 +12,7 @@ private final Expr iterExpr; private final Stmt block; - GenericForStmt(LuaSource.Element se,int iVars,int nVars,Expr iterExpr,Stmt block) { + GenericForStmt(LuanSource.Element se,int iVars,int nVars,Expr iterExpr,Stmt block) { super(se); this.iVars = iVars; this.nVars = nVars; @@ -20,8 +20,8 @@ this.block = block; } - @Override public void eval(LuaStateImpl lua) throws LuaException { - LuaFunction iter = lua.checkFunction( se, iterExpr.eval(lua) ); + @Override public void eval(LuanStateImpl lua) throws LuanException { + LuanFunction iter = lua.checkFunction( se, iterExpr.eval(lua) ); try { while(true) { Object[] vals = lua.call(iter,iterExpr.se(),iterExpr.se().text());
--- a/src/luan/interp/GetLocalVar.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/GetLocalVar.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,17 +1,17 @@ package luan.interp; -import luan.LuaSource; +import luan.LuanSource; final class GetLocalVar extends CodeImpl implements Expr { private final int index; - GetLocalVar(LuaSource.Element se,int index) { + GetLocalVar(LuanSource.Element se,int index) { super(se); this.index = index; } - @Override public Object eval(LuaStateImpl lua) { + @Override public Object eval(LuanStateImpl lua) { return lua.stackGet(index); } }
--- a/src/luan/interp/GetUpVar.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/GetUpVar.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,17 +1,17 @@ package luan.interp; -import luan.LuaSource; +import luan.LuanSource; final class GetUpVar extends CodeImpl implements Expr { private final int index; - GetUpVar(LuaSource.Element se,int index) { + GetUpVar(LuanSource.Element se,int index) { super(se); this.index = index; } - @Override public Object eval(LuaStateImpl lua) { + @Override public Object eval(LuanStateImpl lua) { return lua.closure().upValues[index].get(); } }
--- a/src/luan/interp/IfStmt.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/IfStmt.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,7 +1,7 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; +import luan.Luan; +import luan.LuanException; final class IfStmt implements Stmt { @@ -15,8 +15,8 @@ this.elseStmt = elseStmt; } - @Override public void eval(LuaStateImpl lua) throws LuaException { - if( Lua.toBoolean( cnd.eval(lua) ) ) { + @Override public void eval(LuanStateImpl lua) throws LuanException { + if( Luan.toBoolean( cnd.eval(lua) ) ) { thenStmt.eval(lua); } else { elseStmt.eval(lua);
--- a/src/luan/interp/IndexExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/IndexExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,26 +1,26 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaTable; -import luan.LuaFunction; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanTable; +import luan.LuanFunction; +import luan.LuanSource; final class IndexExpr extends BinaryOpExpr { - IndexExpr(LuaSource.Element se,Expr op1,Expr op2) { + IndexExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { return index(lua,op1.eval(lua),op2.eval(lua)); } - private Object index(LuaStateImpl lua,Object t,Object key) throws LuaException { + private Object index(LuanStateImpl lua,Object t,Object key) throws LuanException { Object h; - if( t instanceof LuaTable ) { - LuaTable tbl = (LuaTable)t; + if( t instanceof LuanTable ) { + LuanTable tbl = (LuanTable)t; Object value = tbl.get(key); if( value != null ) return value; @@ -30,11 +30,11 @@ } else { h = lua.getHandler("__index",t); if( h==null ) - throw new LuaException( lua, se, "attempt to index a " + Lua.type(t) + " value" ); + throw new LuanException( lua, se, "attempt to index a " + Luan.type(t) + " value" ); } - if( h instanceof LuaFunction ) { - LuaFunction fn = (LuaFunction)h; - return Lua.first(lua.call(fn,se,"__index",t,key)); + if( h instanceof LuanFunction ) { + LuanFunction fn = (LuanFunction)h; + return Luan.first(lua.call(fn,se,"__index",t,key)); } return index(lua,h,key); }
--- a/src/luan/interp/LeExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/LeExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,18 +1,18 @@ package luan.interp; -import luan.Lua; -import luan.LuaFunction; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanFunction; +import luan.LuanException; +import luan.LuanSource; final class LeExpr extends BinaryOpExpr { - LeExpr(LuaSource.Element se,Expr op1,Expr op2) { + LeExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); if( o1 instanceof Number && o2 instanceof Number ) { @@ -25,12 +25,12 @@ String s2 = (String)o2; return s1.compareTo(s2) <= 0; } - LuaFunction fn = lua.getBinHandler(se,"__le",o1,o2); + LuanFunction fn = lua.getBinHandler(se,"__le",o1,o2); if( fn != null ) - return Lua.toBoolean( Lua.first(lua.call(fn,se,"__le",o1,o2)) ); + return Luan.toBoolean( Luan.first(lua.call(fn,se,"__le",o1,o2)) ); fn = lua.getBinHandler(se,"__lt",o1,o2); if( fn != null ) - return !Lua.toBoolean( Lua.first(lua.call(fn,se,"__lt",o2,o1)) ); - throw new LuaException( lua, se, "attempt to compare " + Lua.type(o1) + " with " + Lua.type(o2) ); + return !Luan.toBoolean( Luan.first(lua.call(fn,se,"__lt",o2,o1)) ); + throw new LuanException( lua, se, "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) ); } }
--- a/src/luan/interp/LenExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/LenExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,31 +1,31 @@ package luan.interp; -import luan.Lua; -import luan.LuaTable; -import luan.LuaFunction; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanTable; +import luan.LuanFunction; +import luan.LuanException; +import luan.LuanSource; final class LenExpr extends UnaryOpExpr { - LenExpr(LuaSource.Element se,Expr op) { + LenExpr(LuanSource.Element se,Expr op) { super(se,op); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o = op.eval(lua); if( o instanceof String ) { String s = (String)o; return s.length(); } - LuaFunction fn = lua.getHandlerFunction(se,"__len",o); + LuanFunction fn = lua.getHandlerFunction(se,"__len",o); if( fn != null ) - return Lua.first(lua.call(fn,se,"__len",o)); - if( o instanceof LuaTable ) { - LuaTable t = (LuaTable)o; + return Luan.first(lua.call(fn,se,"__len",o)); + if( o instanceof LuanTable ) { + LuanTable t = (LuanTable)o; return t.length(); } - throw new LuaException( lua, se, "attempt to get length of a " + Lua.type(o) + " value" ); + throw new LuanException( lua, se, "attempt to get length of a " + Luan.type(o) + " value" ); } }
--- a/src/luan/interp/LtExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/LtExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,18 +1,18 @@ package luan.interp; -import luan.Lua; -import luan.LuaFunction; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanFunction; +import luan.LuanException; +import luan.LuanSource; final class LtExpr extends BinaryOpExpr { - LtExpr(LuaSource.Element se,Expr op1,Expr op2) { + LtExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); return lua.isLessThan(se,o1,o2);
--- a/src/luan/interp/LuaClosure.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -package luan.interp; - -import luan.LuaFunction; -import luan.LuaState; -import luan.LuaElement; -import luan.LuaException; - - -final class LuaClosure extends LuaFunction { - private final Chunk chunk; - final UpValue[] upValues; - private final static UpValue[] NO_UP_VALUES = new UpValue[0]; - - LuaClosure(Chunk chunk,LuaStateImpl lua) { - this.chunk = chunk; - UpValue.Getter[] upValueGetters = chunk.upValueGetters; - if( upValueGetters.length==0 ) { - upValues = NO_UP_VALUES; - } else { - upValues = new UpValue[upValueGetters.length]; - for( int i=0; i<upValues.length; i++ ) { - upValues[i] = upValueGetters[i].get(lua); - } - } - } - - public Object[] call(LuaState lua,Object[] args) throws LuaException { - return call(this,(LuaStateImpl)lua,args); - } - - private static Object[] call(LuaClosure closure,LuaStateImpl lua,Object[] args) throws LuaException { - while(true) { - Chunk chunk = closure.chunk; - Object[] varArgs = null; - if( chunk.isVarArg ) { - if( args.length > chunk.numArgs ) { - varArgs = new Object[ args.length - chunk.numArgs ]; - for( int i=0; i<varArgs.length; i++ ) { - varArgs[i] = args[chunk.numArgs+i]; - } - } else { - varArgs = LuaFunction.EMPTY_RTN; - } - } - Object[] stack = lua.newFrame(closure,chunk.stackSize,varArgs); - final int n = Math.min(args.length,chunk.numArgs); - for( int i=0; i<n; i++ ) { - stack[i] = args[i]; - } - Object[] returnValues; - LuaClosure tailFn; - try { - chunk.block.eval(lua); - } catch(ReturnException e) { - } finally { - returnValues = lua.returnValues; - closure = lua.tailFn; - lua.popFrame(); - } - if( closure == null ) - return returnValues; - args = returnValues; - } - } - -}
--- a/src/luan/interp/LuaCompiler.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -package luan.interp; - -import org.parboiled.Parboiled; -import org.parboiled.errors.ErrorUtils; -import org.parboiled.parserunners.ReportingParseRunner; -import org.parboiled.parserunners.TracingParseRunner; -import org.parboiled.support.ParsingResult; -import luan.LuaFunction; -import luan.LuaState; -import luan.LuaException; -import luan.LuaSource; -import luan.LuaElement; - - -public final class LuaCompiler { - private LuaCompiler() {} // never - - public static LuaFunction compile(LuaState lua,LuaSource src) throws LuaException { - LuaParser parser = Parboiled.createParser(LuaParser.class); - parser.source = src; - ParsingResult<?> result = new ReportingParseRunner(parser.Target()).run(src.text); -// ParsingResult<?> result = new TracingParseRunner(parser.Target()).run(src); - if( result.hasErrors() ) - throw new LuaException( lua, null, ErrorUtils.printParseErrors(result) ); - Object resultValue = result.resultValue; - if( resultValue instanceof Expressions ) { - final Expressions expressions = (Expressions)resultValue; - return new LuaFunction() { - public Object[] call(LuaState lua,Object[] args) throws LuaException { - return expressions.eval((LuaStateImpl)lua); - } - }; - } - Chunk chunk = (Chunk)resultValue; - return chunk.newClosure((LuaStateImpl)lua); - } - - public static LuaState newLuaState() { - return new LuaStateImpl(); - } -}
--- a/src/luan/interp/LuaParser.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1090 +0,0 @@ -package luan.interp; - -import java.util.Set; -import java.util.HashSet; -import java.util.Arrays; -import java.util.List; -import java.util.ArrayList; -import java.util.Scanner; -import org.parboiled.BaseParser; -import org.parboiled.Parboiled; -import org.parboiled.Rule; -import org.parboiled.parserunners.ReportingParseRunner; -import org.parboiled.support.ParsingResult; -import org.parboiled.support.Var; -import org.parboiled.support.StringVar; -import org.parboiled.support.StringBuilderVar; -import org.parboiled.support.ValueStack; -import org.parboiled.errors.ErrorUtils; -import luan.Lua; -import luan.LuaState; -import luan.LuaSource; - - -class LuaParser extends BaseParser<Object> { - - LuaSource source; - - LuaSource.Element se(int start) { - return new LuaSource.Element(source,start,currentIndex()); - } - - static final String _ENV = "_ENV"; - - static final class Frame { - final Frame parent; - final List<String> symbols = new ArrayList<String>(); - int stackSize = 0; - int loops = 0; - boolean isVarArg = false; - final List<String> upValueSymbols = new ArrayList<String>(); - final List<UpValue.Getter> upValueGetters = new ArrayList<UpValue.Getter>(); - - Frame() { - this.parent = null; - upValueSymbols.add(_ENV); - upValueGetters.add(UpValue.globalGetter); - } - - Frame(Frame parent) { - this.parent = parent; - } - - int stackIndex(String name) { - int i = symbols.size(); - while( --i >= 0 ) { - if( symbols.get(i).equals(name) ) - return i; - } - return -1; - } - - int upValueIndex(String name) { - int i = upValueSymbols.size(); - while( --i >= 0 ) { - if( upValueSymbols.get(i).equals(name) ) - return i; - } - if( parent==null ) - return -1; - i = parent.stackIndex(name); - if( i != -1 ) { - upValueGetters.add(new UpValue.StackGetter(i)); - } else { - i = parent.upValueIndex(name); - if( i == -1 ) - return -1; - upValueGetters.add(new UpValue.NestedGetter(i)); - } - upValueSymbols.add(name); - return upValueSymbols.size() - 1; - } - } - - static final UpValue.Getter[] NO_UP_VALUE_GETTERS = new UpValue.Getter[0]; - - int nEquals; - int parens = 0; - Frame frame = new Frame(); - - boolean nEquals(int n) { - nEquals = n; - return true; - } - - boolean incParens() { - parens++; - return true; - } - - boolean decParens() { - parens--; - return true; - } - - List<String> symbols() { - return frame.symbols; - } - - int symbolsSize() { - return frame.symbols.size(); - } - - boolean addSymbol(String name) { - frame.symbols.add(name); - if( frame.stackSize < symbolsSize() ) - frame.stackSize = symbolsSize(); - return true; - } - - boolean addSymbols(List<String> names) { - frame.symbols.addAll(names); - if( frame.stackSize < symbolsSize() ) - frame.stackSize = symbolsSize(); - return true; - } - - int stackIndex(String name) { - return frame.stackIndex(name); - } - - boolean popSymbols(int n) { - List<String> symbols = frame.symbols; - while( n-- > 0 ) { - symbols.remove(symbols.size()-1); - } - return true; - } - - int upValueIndex(String name) { - return frame.upValueIndex(name); - } - - boolean incLoops() { - frame.loops++; - return true; - } - - boolean decLoops() { - frame.loops--; - return true; - } - - Chunk newChunk(int start) { - return new Chunk( se(start), (Stmt)pop(), frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); - } - - Rule Target() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - Spaces(), - FirstOf( - Sequence( ExpList(), EOI ), - Sequence( - start.set(currentIndex()), - action( frame.isVarArg = true ), - Block(), - EOI, - push( newChunk(start.get()) ) - ) - ) - ); - } - - Rule Block() { - Var<List<Stmt>> stmts = new Var<List<Stmt>>(new ArrayList<Stmt>()); - Var<Integer> stackStart = new Var<Integer>(symbolsSize()); - return Sequence( - Optional( Stmt(stmts) ), - ZeroOrMore( - StmtSep(), - Optional( Stmt(stmts) ) - ), - push( newBlock(stmts.get(),stackStart.get()) ) - ); - } - - Stmt newBlock(List<Stmt> stmts,int stackStart) { - int stackEnd = symbolsSize(); - popSymbols( stackEnd - stackStart ); - if( stmts.isEmpty() ) - return Stmt.EMPTY; - if( stmts.size()==1 && stackStart==stackEnd ) - return stmts.get(0); - return new Block( stmts.toArray(new Stmt[0]), stackStart, stackEnd ); - } - - Rule StmtSep() { - return Sequence( - FirstOf( - ';', - Sequence( - Optional( "--", ZeroOrMore(NoneOf("\r\n")) ), - EndOfLine() - ) - ), - Spaces() - ); - } - - Rule EndOfLine() { - return FirstOf("\r\n", '\r', '\n'); - } - - Rule Stmt(Var<List<Stmt>> stmts) { - return FirstOf( - LocalStmt(stmts), - Sequence( - FirstOf( - ReturnStmt(), - FunctionStmt(), - LocalFunctionStmt(), - BreakStmt(), - GenericForStmt(), - NumericForStmt(), - TryStmt(), - DoStmt(), - WhileStmt(), - RepeatStmt(), - IfStmt(), - SetStmt(), - ExpressionsStmt() - ), - stmts.get().add( (Stmt)pop() ) - ) - ); - } - - Rule ReturnStmt() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - Keyword("return"), Expressions(), - push( new ReturnStmt( se(start.get()), (Expressions)pop() ) ) - ); - } - - Rule FunctionStmt() { - return Sequence( - Keyword("function"), FnName(), Function(), - push( new SetStmt( (Settable)pop(1), expr(pop()) ) ) - ); - } - - Rule FnName() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - push(null), // marker - Name(), - ZeroOrMore( - '.', Spaces(), - makeVarExp(start.get()), - NameExpr() - ), - makeSettableVar(start.get()) - ); - } - - Rule LocalFunctionStmt() { - return Sequence( - Keyword("local"), Keyword("function"), - Name(), - addSymbol( (String)pop() ), - Function(), - push( new SetStmt( new SetLocalVar(symbolsSize()-1), expr(pop()) ) ) - ); - } - - Rule BreakStmt() { - return Sequence( - Keyword("break"), - frame.loops > 0, - push( new BreakStmt() ) - ); - } - - Rule GenericForStmt() { - Var<Integer> start = new Var<Integer>(); - Var<Integer> stackStart = new Var<Integer>(symbolsSize()); - Var<List<String>> names = new Var<List<String>>(new ArrayList<String>()); - return Sequence( - start.set(currentIndex()), - Keyword("for"), NameList(names), Keyword("in"), Expr(), Keyword("do"), - addSymbols(names.get()), - LoopBlock(), Keyword("end"), - push( new GenericForStmt( se(start.get()), stackStart.get(), symbolsSize() - stackStart.get(), expr(pop(1)), (Stmt)pop() ) ), - popSymbols( symbolsSize() - stackStart.get() ) - ); - } - - Rule NumericForStmt() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - Keyword("for"), Name(), '=', Spaces(), Expr(), Keyword("to"), Expr(), - push( new ConstExpr(1) ), // default step - Optional( - Keyword("step"), - drop(), - Expr() - ), - addSymbol( (String)pop(3) ), // add "for" var to symbols - Keyword("do"), LoopBlock(), Keyword("end"), - push( new NumericForStmt( se(start.get()), symbolsSize()-1, expr(pop(3)), expr(pop(2)), expr(pop(1)), (Stmt)pop() ) ), - popSymbols(1) - ); - } - - Rule TryStmt() { - return Sequence( - Keyword("try"), Block(), - Keyword("catch"), Name(), addSymbol( (String)pop() ), - Keyword("do"), Block(), Keyword("end"), - push( new TryStmt( (Stmt)pop(1), symbolsSize()-1, (Stmt)pop() ) ), - popSymbols(1) - ); - } - - Rule DoStmt() { - return Sequence( - Keyword("do"), Block(), Keyword("end") - ); - } - - Rule LocalStmt(Var<List<Stmt>> stmts) { - Var<List<String>> names = new Var<List<String>>(new ArrayList<String>()); - return Sequence( - Keyword("local"), NameList(names), - Optional( - '=', Spaces(), ExpList(), - stmts.get().add( newSetLocalStmt(names.get().size()) ) - ), - addSymbols(names.get()) - ); - } - - Rule NameList(Var<List<String>> names) { - return Sequence( - Name(), - names.get().add( (String)pop() ), - ZeroOrMore( - ',', Spaces(), Name(), - names.get().add( (String)pop() ) - ) - ); - } - - SetStmt newSetLocalStmt(int nVars) { - Expressions values = (Expressions)pop(); - SetLocalVar[] vars = new SetLocalVar[nVars]; - int stackStart = symbolsSize(); - for( int i=0; i<vars.length; i++ ) { - vars[i] = new SetLocalVar(stackStart+i); - } - return new SetStmt( vars, values ); - } - - Rule WhileStmt() { - return Sequence( - Keyword("while"), Expr(), Keyword("do"), LoopBlock(), Keyword("end"), - push( new WhileStmt( expr(pop(1)), (Stmt)pop() ) ) - ); - } - - Rule RepeatStmt() { - return Sequence( - Keyword("repeat"), LoopBlock(), Keyword("until"), Expr(), - push( new RepeatStmt( (Stmt)pop(1), expr(pop()) ) ) - ); - } - - Rule LoopBlock() { - return Sequence( incLoops(), Block(), decLoops() ); - } - - Rule IfStmt() { - Var<Integer> n = new Var<Integer>(1); - return Sequence( - Keyword("if"), Expr(), Keyword("then"), Block(), - push(Stmt.EMPTY), - ZeroOrMore( - Keyword("elseif"), drop(), Expr(), Keyword("then"), Block(), - push(Stmt.EMPTY), - n.set(n.get()+1) - ), - Optional( - Keyword("else"), drop(), Block() - ), - Keyword("end"), - buildIfStmt(n.get()) - ); - } - - boolean buildIfStmt(int n) { - while( n-- > 0 ) { - Stmt elseStmt = (Stmt)pop(); - Stmt thenStmt = (Stmt)pop(); - Expr cnd = expr(pop()); - push( new IfStmt(cnd,thenStmt,elseStmt) ); - } - return true; - } - - Rule SetStmt() { - return Sequence( - VarList(), - '=', Spaces(), - ExpList(), - push( newSetStmt() ) - ); - } - - Rule ExpressionsStmt() { - return Sequence( - ExpList(), - push( new ExpressionsStmt((Expressions)pop()) ) - ); - } - - SetStmt newSetStmt() { - Expressions values = (Expressions)pop(); - @SuppressWarnings("unchecked") - List<Settable> vars = (List<Settable>)pop(); - return new SetStmt( vars.toArray(new Settable[0]), values ); - } - - Rule VarList() { - Var<List<Settable>> vars = new Var<List<Settable>>(new ArrayList<Settable>()); - return Sequence( - SettableVar(), - vars.get().add( (Settable)pop() ), - ZeroOrMore( - ',', Spaces(), SettableVar(), - vars.get().add( (Settable)pop() ) - ), - push(vars.get()) - ); - } - - Rule SettableVar() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - Var(), - makeSettableVar(start.get()) - ); - } - - boolean makeSettableVar(int start) { - Object obj2 = pop(); - if( obj2==null ) - return false; - Object obj1 = pop(); - if( obj1!=null ) { - Expr key = expr(obj2); - Expr table = expr(obj1); - return push( new SetTableEntry(se(start),table,key) ); - } - String name = (String)obj2; - int index = stackIndex(name); - if( index != -1 ) - return push( new SetLocalVar(index) ); - index = upValueIndex(name); - if( index != -1 ) - return push( new SetUpVar(index) ); - return push( new SetTableEntry( se(start), env(), new ConstExpr(name) ) ); - } - - Rule Expr() { - return FirstOf( - VarArgs(), - OrExpr() - ); - } - - Rule OrExpr() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - AndExpr(), - ZeroOrMore( "or", Spaces(), AndExpr(), push( new OrExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) - ); - } - - Rule AndExpr() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - RelExpr(), - ZeroOrMore( "and", Spaces(), RelExpr(), push( new AndExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) - ); - } - - Rule RelExpr() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - ConcatExpr(), - ZeroOrMore( - FirstOf( - Sequence( "==", Spaces(), ConcatExpr(), push( new EqExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), - Sequence( "~=", Spaces(), ConcatExpr(), push( new NotExpr(se(start.get()),new EqExpr(se(start.get()),expr(pop(1)),expr(pop()))) ) ), - Sequence( "<=", Spaces(), ConcatExpr(), push( new LeExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), - Sequence( ">=", Spaces(), ConcatExpr(), push( new LeExpr(se(start.get()),expr(pop()),expr(pop())) ) ), - Sequence( "<", Spaces(), ConcatExpr(), push( new LtExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), - Sequence( ">", Spaces(), ConcatExpr(), push( new LtExpr(se(start.get()),expr(pop()),expr(pop())) ) ) - ) - ) - ); - } - - Rule ConcatExpr() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - SumExpr(), - Optional( "..", Spaces(), ConcatExpr(), push( new ConcatExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) - ); - } - - Rule SumExpr() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - TermExpr(), - ZeroOrMore( - FirstOf( - Sequence( '+', Spaces(), TermExpr(), push( new AddExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), - Sequence( '-', TestNot('-'), Spaces(), TermExpr(), push( new SubExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) - ) - ) - ); - } - - Rule TermExpr() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - UnaryExpr(), - ZeroOrMore( - FirstOf( - Sequence( '*', Spaces(), UnaryExpr(), push( new MulExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), - Sequence( '/', Spaces(), UnaryExpr(), push( new DivExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), - Sequence( '%', Spaces(), UnaryExpr(), push( new ModExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) - ) - ) - ); - } - - Rule UnaryExpr() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - FirstOf( - Sequence( '#', Spaces(), PowExpr(), push( new LenExpr(se(start.get()),expr(pop())) ) ), - Sequence( '-', TestNot('-'), Spaces(), PowExpr(), push( new UnmExpr(se(start.get()),expr(pop())) ) ), - Sequence( "not", Spaces(), PowExpr(), push( new NotExpr(se(start.get()),expr(pop())) ) ), - PowExpr() - ) - ); - } - - Rule PowExpr() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - SingleExpr(), - Optional( '^', Spaces(), PowExpr(), push( new PowExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) - ); - } - - Rule SingleExpr() { - return FirstOf( - FunctionExpr(), - TableExpr(), - VarExp(), - LiteralExpr() - ); - } - - Rule FunctionExpr() { - return Sequence( "function", Spaces(), Function() ); - } - - Rule Function() { - Var<Integer> start = new Var<Integer>(); - Var<List<String>> names = new Var<List<String>>(new ArrayList<String>()); - return Sequence( - start.set(currentIndex()), - '(', incParens(), Spaces(), - action( frame = new Frame(frame) ), - Optional( - FirstOf( - Sequence( - NameList(names), addSymbols(names.get()), - Optional( ',', Spaces(), VarArgName() ) - ), - VarArgName() - ) - ), - ')', decParens(), Spaces(), Block(), Keyword("end"), - push( newChunk(start.get()) ), - action( frame = frame.parent ) - ); - } - - Rule VarArgName() { - return Sequence( - "...", Spaces(), - action( frame.isVarArg = true ) - ); - } - - Rule VarArgs() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - "...", Spaces(), - frame.isVarArg, - push( new VarArgs(se(start.get())) ) - ); - } - - Rule TableExpr() { - Var<Integer> start = new Var<Integer>(); - Var<List<TableExpr.Field>> fields = new Var<List<TableExpr.Field>>(new ArrayList<TableExpr.Field>()); - Var<ExpList.Builder> builder = new Var<ExpList.Builder>(new ExpList.Builder()); - return Sequence( - start.set(currentIndex()), - '{', incParens(), Spaces(), - Optional( - Field(fields,builder), - ZeroOrMore( - FieldSep(), - Field(fields,builder) - ), - Optional( FieldSep() ) - ), - '}', decParens(), - Spaces(), - push( new TableExpr( se(start.get()), fields.get().toArray(new TableExpr.Field[0]), builder.get().build() ) ) - ); - } - - Rule FieldSep() { - return Sequence( AnyOf(",;"), Spaces() ); - } - - Rule Field(Var<List<TableExpr.Field>> fields,Var<ExpList.Builder> builder) { - return FirstOf( - Sequence( - FirstOf( SubExpr(), NameExpr() ), - '=', Spaces(), Expr(), - fields.get().add( new TableExpr.Field( expr(pop(1)), expr(pop()) ) ) - ), - Sequence( - Expr(), - addToExpList(builder.get()) - ) - ); - } - - static Expr expr(Object obj) { - if( obj instanceof Expressions ) - return new ExpressionsExpr((Expressions)obj); - return (Expr)obj; - } - - Rule VarExp() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - Var(), - makeVarExp(start.get()) - ); - } - - Rule Var() { - Var<Integer> start = new Var<Integer>(); - return Sequence( - start.set(currentIndex()), - FirstOf( - Sequence( - '(', incParens(), Spaces(), Expr(), ')', decParens(), Spaces(), - push(expr(pop())), - push(null) // marker - ), - Sequence( - push(null), // marker - Name() - ) - ), - ZeroOrMore( - makeVarExp(start.get()), - FirstOf( - SubExpr(), - Sequence( '.', Spaces(), NameExpr() ), - Sequence( - Args(start), - push(null) // marker - ) - ) - ) - ); - } - - Expr env() { - int index = stackIndex(_ENV); - if( index != -1 ) - return new GetLocalVar(null,index); - index = upValueIndex(_ENV); - if( index != -1 ) - return new GetUpVar(null,index); - throw new RuntimeException("_ENV not found"); - } - - boolean makeVarExp(int start) { - Object obj2 = pop(); - if( obj2==null ) - return true; - Object obj1 = pop(); - if( obj1 != null ) - return push( new IndexExpr( se(start), expr(obj1), expr(obj2) ) ); - String name = (String)obj2; - int index = stackIndex(name); - if( index != -1 ) - return push( new GetLocalVar(se(start),index) ); - index = upValueIndex(name); - if( index != -1 ) - return push( new GetUpVar(se(start),index) ); - return push( new IndexExpr( se(start), env(), new ConstExpr(name) ) ); - } - - // function should be on top of the stack - Rule Args(Var<Integer> start) { - return Sequence( - FirstOf( - Sequence( - '(', incParens(), Spaces(), Expressions(), ')', decParens(), Spaces() - ), - Sequence( - TableExpr(), - push( new ExpList.SingleExpList(expr(pop())) ) - ), - Sequence( - StringLiteral(), Spaces(), - push( new ExpList.SingleExpList(new ConstExpr(pop())) ) - ) - ), - push( new FnCall( se(start.get()), expr(pop(1)), (Expressions)pop() ) ) - ); - } - - Rule Expressions() { - return FirstOf( - ExpList(), - push( ExpList.emptyExpList ) - ); - } - - Rule ExpList() { - Var<ExpList.Builder> builder = new Var<ExpList.Builder>(new ExpList.Builder()); - return Sequence( - Expr(), - addToExpList(builder.get()), - ZeroOrMore( - ',', Spaces(), Expr(), - addToExpList(builder.get()) - ), - push( builder.get().build() ) - ); - } - - boolean addToExpList(ExpList.Builder bld) { - Object obj = pop(); - if( obj instanceof Expressions ) { - bld.add( (Expressions)obj ); - } else { - bld.add( (Expr)obj ); - } - return true; - } - - Rule SubExpr() { - return Sequence( '[', incParens(), Spaces(), Expr(), ']', decParens(), Spaces() ); - } - - Rule NameExpr() { - return Sequence( - Name(), - push( new ConstExpr((String)pop()) ) - ); - } - - Rule Name() { - return Sequence( - Sequence( - NameFirstChar(), - ZeroOrMore( NameChar() ) - ), - !keywords.contains(match()), - push(match()), - Spaces() - ); - } - - Rule NameChar() { - return FirstOf( NameFirstChar(), Digit() ); - } - - Rule NameFirstChar() { - return FirstOf( - CharRange('a', 'z'), - CharRange('A', 'Z'), - '_' - ); - } - - Rule Keyword(String keyword) { - return Sequence( - keyword, - TestNot( NameChar() ), - Spaces() - ); - } - - static final Set<String> keywords = new HashSet<String>(Arrays.asList( - "and", - "break", - "catch", - "do", - "else", - "elseif", - "end", - "false", - "for", - "function", - "goto", - "if", - "in", - "local", - "nil", - "not", - "or", - "repeat", - "return", - "step", - "then", - "to", - "true", - "try", - "until", - "while" - )); - - Rule LiteralExpr() { - return Sequence( - Literal(), Spaces(), - push(new ConstExpr(pop())) - ); - } - - Rule Literal() { - return FirstOf( - NilLiteral(), - BooleanLiteral(), - NumberLiteral(), - StringLiteral() - ); - } - - Rule NilLiteral() { - return Sequence( "nil", push(null) ); - } - - Rule BooleanLiteral() { - return FirstOf( - Sequence( "true", push(true) ), - Sequence( "false", push(false) ) - ); - } - - Rule NumberLiteral() { - return FirstOf( - Sequence( - IgnoreCase("0x"), - HexNumber() - ), - Sequence( - DecNumber(), - push(Double.valueOf(match())) - ) - ); - } - - Rule DecNumber() { - return FirstOf( - Sequence( - Int(), - Optional( '.', Optional(Int()) ), - Exponent() - ), - Sequence( '.', Int(), Exponent() ) - ); - } - - Rule Exponent() { - return Optional( - IgnoreCase('e'), - Optional(AnyOf("+-")), - Int() - ); - } - - Rule Int() { - return OneOrMore(Digit()); - } - - Rule Digit() { - return CharRange('0', '9'); - } - - Rule HexNumber() { - return FirstOf( - Sequence( - HexInt(), - push( (double)Long.parseLong(match(),16) ), - Optional( '.', Optional(HexDec()) ), - HexExponent() - ), - Sequence( push(0.0), '.', HexDec(), HexExponent() ) - ); - } - - Rule HexDec() { - return Sequence( - HexInt(), - push( (Double)pop() + (double)Long.parseLong(match(),16) / Math.pow(16,matchLength()) ) - ); - } - - Rule HexExponent() { - return Optional( - IgnoreCase('p'), - Sequence( - Optional(AnyOf("+-")), - HexInt() - ), - push( (Double)pop() * Math.pow(2,(double)Long.parseLong(match())) ) - ); - } - - Rule HexInt() { - return OneOrMore(Digit()); - } - - - Rule HexDigit() { - return FirstOf( - Digit(), - AnyOf("abcdefABCDEF") - ); - } - - Rule StringLiteral() { - return FirstOf( - QuotedString('"'), - QuotedString('\''), - LongString() - ); - } - - Rule LongString() { - return Sequence( - '[', - ZeroOrMore('='), - nEquals(matchLength()), - '[', - ZeroOrMore( - TestNot(LongBracketsEnd()), - ANY - ), - push( match() ), - LongBracketsEnd() - ); - } - - Rule QuotedString(char quote) { - StringBuilderVar buf = new StringBuilderVar(); - return Sequence( - quote, - ZeroOrMore( - FirstOf( - Sequence( - NoneOf("\\\n"+quote), - buf.append(matchedChar()) - ), - EscSeq(buf) - ) - ), - quote, - push( buf.getString() ) - ); - } - - Rule EscSeq(StringBuilderVar buf) { - return Sequence( - '\\', - FirstOf( - Sequence( 'a', buf.append('\u0007') ), - Sequence( 'b', buf.append('\b') ), - Sequence( 'f', buf.append('\f') ), - Sequence( 'n', buf.append('\n') ), - Sequence( 'r', buf.append('\r') ), - Sequence( 't', buf.append('\t') ), - Sequence( 'v', buf.append('\u000b') ), - Sequence( '\\', buf.append('\\') ), - Sequence( '"', buf.append('"') ), - Sequence( '\'', buf.append('\'') ), - Sequence( - 'x', - Sequence( HexDigit(), HexDigit() ), - buf.append( (char)Integer.parseInt(match(),16) ) - ), - Sequence( - Sequence( - Digit(), - Optional( - Digit(), - Optional( - Digit() - ) - ) - ), - buf.append( (char)Integer.parseInt(match()) ) - ) - ) - ); - } - - Rule Spaces() { - return ZeroOrMore( - FirstOf( - AnyOf(" \t"), - Comment(), - Sequence( '\\', EndOfLine() ), - Sequence( AnyOf("\r\n"), parens > 0 ) - ) - ); - } - - Rule Comment() { - return Sequence( - "--[", - ZeroOrMore('='), - nEquals(matchLength()), - '[', - ZeroOrMore( - TestNot(LongBracketsEnd()), - ANY - ), - LongBracketsEnd() - ); - } - - Rule LongBracketsEnd() { - return Sequence( ']', ZeroOrMore('='), nEquals==matchLength(), ']' ); - } - - static boolean action(Object obj) { - return true; - } - - // for debugging - boolean print(Object o) { - System.out.println(o); - return true; - } - -}
--- a/src/luan/interp/LuaStateImpl.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -package luan.interp; - -import java.util.List; -import java.util.ArrayList; -import luan.Lua; -import luan.LuaState; -import luan.LuaTable; -import luan.LuaFunction; -import luan.MetatableGetter; -import luan.LuaException; -import luan.LuaElement; - - -final class LuaStateImpl extends LuaState { - - final Object arithmetic(LuaElement el,String op,Object o1,Object o2) throws LuaException { - LuaFunction fn = getBinHandler(el,op,o1,o2); - if( fn != null ) - return Lua.first(call(fn,el,op,o1,o2)); - String type = Lua.toNumber(o1)==null ? Lua.type(o1) : Lua.type(o2); - throw new LuaException(this,el,"attempt to perform arithmetic on a "+type+" value"); - } - - - private static class Frame { - final Frame previousFrame; - final LuaClosure closure; - final Object[] stack; - final Object[] varArgs; - UpValue[] downValues = null; - - Frame( Frame previousFrame, LuaClosure closure, int stackSize, Object[] varArgs) { - this.previousFrame = previousFrame; - this.closure = closure; - this.stack = new Object[stackSize]; - this.varArgs = varArgs; - } - - void stackClear(int start,int end) { - if( downValues != null ) { - for( int i=start; i<end; i++ ) { - UpValue downValue = downValues[i]; - if( downValue != null ) { - downValue.close(); - downValues[i] = null; - } - } - } - for( int i=start; i<end; i++ ) { - stack[i] = null; - } - } - - UpValue getUpValue(int index) { - if( downValues==null ) - downValues = new UpValue[stack.length]; - if( downValues[index] == null ) - downValues[index] = new UpValue(stack,index); - return downValues[index]; - } - } - - private Frame frame = null; - Object[] returnValues; - LuaClosure tailFn; - - // returns stack - Object[] newFrame(LuaClosure closure, int stackSize, Object[] varArgs) { - frame = new Frame(frame,closure,stackSize,varArgs); - return frame.stack; - } - - void popFrame() { - returnValues = LuaFunction.EMPTY_RTN; - tailFn = null; - frame = frame.previousFrame; - } - - Object stackGet(int index) { - return frame.stack[index]; - } - - void stackSet(int index,Object value) { - frame.stack[index] = value; - } - - void stackClear(int start,int end) { - frame.stackClear(start,end); - } - - Object[] varArgs() { - return frame.varArgs; - } - - LuaClosure closure() { - return frame.closure; - } - - UpValue getUpValue(int index) { - return frame.getUpValue(index); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/LuanCompiler.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,41 @@ +package luan.interp; + +import org.parboiled.Parboiled; +import org.parboiled.errors.ErrorUtils; +import org.parboiled.parserunners.ReportingParseRunner; +import org.parboiled.parserunners.TracingParseRunner; +import org.parboiled.support.ParsingResult; +import luan.LuanFunction; +import luan.LuanState; +import luan.LuanException; +import luan.LuanSource; +import luan.LuanElement; + + +public final class LuanCompiler { + private LuanCompiler() {} // never + + public static LuanFunction compile(LuanState lua,LuanSource src) throws LuanException { + LuanParser parser = Parboiled.createParser(LuanParser.class); + parser.source = src; + ParsingResult<?> result = new ReportingParseRunner(parser.Target()).run(src.text); +// ParsingResult<?> result = new TracingParseRunner(parser.Target()).run(src); + if( result.hasErrors() ) + throw new LuanException( lua, null, ErrorUtils.printParseErrors(result) ); + Object resultValue = result.resultValue; + if( resultValue instanceof Expressions ) { + final Expressions expressions = (Expressions)resultValue; + return new LuanFunction() { + public Object[] call(LuanState lua,Object[] args) throws LuanException { + return expressions.eval((LuanStateImpl)lua); + } + }; + } + Chunk chunk = (Chunk)resultValue; + return chunk.newClosure((LuanStateImpl)lua); + } + + public static LuanState newLuaState() { + return new LuanStateImpl(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/LuanParser.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,1090 @@ +package luan.interp; + +import java.util.Set; +import java.util.HashSet; +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; +import java.util.Scanner; +import org.parboiled.BaseParser; +import org.parboiled.Parboiled; +import org.parboiled.Rule; +import org.parboiled.parserunners.ReportingParseRunner; +import org.parboiled.support.ParsingResult; +import org.parboiled.support.Var; +import org.parboiled.support.StringVar; +import org.parboiled.support.StringBuilderVar; +import org.parboiled.support.ValueStack; +import org.parboiled.errors.ErrorUtils; +import luan.Luan; +import luan.LuanState; +import luan.LuanSource; + + +class LuanParser extends BaseParser<Object> { + + LuanSource source; + + LuanSource.Element se(int start) { + return new LuanSource.Element(source,start,currentIndex()); + } + + static final String _ENV = "_ENV"; + + static final class Frame { + final Frame parent; + final List<String> symbols = new ArrayList<String>(); + int stackSize = 0; + int loops = 0; + boolean isVarArg = false; + final List<String> upValueSymbols = new ArrayList<String>(); + final List<UpValue.Getter> upValueGetters = new ArrayList<UpValue.Getter>(); + + Frame() { + this.parent = null; + upValueSymbols.add(_ENV); + upValueGetters.add(UpValue.globalGetter); + } + + Frame(Frame parent) { + this.parent = parent; + } + + int stackIndex(String name) { + int i = symbols.size(); + while( --i >= 0 ) { + if( symbols.get(i).equals(name) ) + return i; + } + return -1; + } + + int upValueIndex(String name) { + int i = upValueSymbols.size(); + while( --i >= 0 ) { + if( upValueSymbols.get(i).equals(name) ) + return i; + } + if( parent==null ) + return -1; + i = parent.stackIndex(name); + if( i != -1 ) { + upValueGetters.add(new UpValue.StackGetter(i)); + } else { + i = parent.upValueIndex(name); + if( i == -1 ) + return -1; + upValueGetters.add(new UpValue.NestedGetter(i)); + } + upValueSymbols.add(name); + return upValueSymbols.size() - 1; + } + } + + static final UpValue.Getter[] NO_UP_VALUE_GETTERS = new UpValue.Getter[0]; + + int nEquals; + int parens = 0; + Frame frame = new Frame(); + + boolean nEquals(int n) { + nEquals = n; + return true; + } + + boolean incParens() { + parens++; + return true; + } + + boolean decParens() { + parens--; + return true; + } + + List<String> symbols() { + return frame.symbols; + } + + int symbolsSize() { + return frame.symbols.size(); + } + + boolean addSymbol(String name) { + frame.symbols.add(name); + if( frame.stackSize < symbolsSize() ) + frame.stackSize = symbolsSize(); + return true; + } + + boolean addSymbols(List<String> names) { + frame.symbols.addAll(names); + if( frame.stackSize < symbolsSize() ) + frame.stackSize = symbolsSize(); + return true; + } + + int stackIndex(String name) { + return frame.stackIndex(name); + } + + boolean popSymbols(int n) { + List<String> symbols = frame.symbols; + while( n-- > 0 ) { + symbols.remove(symbols.size()-1); + } + return true; + } + + int upValueIndex(String name) { + return frame.upValueIndex(name); + } + + boolean incLoops() { + frame.loops++; + return true; + } + + boolean decLoops() { + frame.loops--; + return true; + } + + Chunk newChunk(int start) { + return new Chunk( se(start), (Stmt)pop(), frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); + } + + Rule Target() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + Spaces(), + FirstOf( + Sequence( ExpList(), EOI ), + Sequence( + start.set(currentIndex()), + action( frame.isVarArg = true ), + Block(), + EOI, + push( newChunk(start.get()) ) + ) + ) + ); + } + + Rule Block() { + Var<List<Stmt>> stmts = new Var<List<Stmt>>(new ArrayList<Stmt>()); + Var<Integer> stackStart = new Var<Integer>(symbolsSize()); + return Sequence( + Optional( Stmt(stmts) ), + ZeroOrMore( + StmtSep(), + Optional( Stmt(stmts) ) + ), + push( newBlock(stmts.get(),stackStart.get()) ) + ); + } + + Stmt newBlock(List<Stmt> stmts,int stackStart) { + int stackEnd = symbolsSize(); + popSymbols( stackEnd - stackStart ); + if( stmts.isEmpty() ) + return Stmt.EMPTY; + if( stmts.size()==1 && stackStart==stackEnd ) + return stmts.get(0); + return new Block( stmts.toArray(new Stmt[0]), stackStart, stackEnd ); + } + + Rule StmtSep() { + return Sequence( + FirstOf( + ';', + Sequence( + Optional( "--", ZeroOrMore(NoneOf("\r\n")) ), + EndOfLine() + ) + ), + Spaces() + ); + } + + Rule EndOfLine() { + return FirstOf("\r\n", '\r', '\n'); + } + + Rule Stmt(Var<List<Stmt>> stmts) { + return FirstOf( + LocalStmt(stmts), + Sequence( + FirstOf( + ReturnStmt(), + FunctionStmt(), + LocalFunctionStmt(), + BreakStmt(), + GenericForStmt(), + NumericForStmt(), + TryStmt(), + DoStmt(), + WhileStmt(), + RepeatStmt(), + IfStmt(), + SetStmt(), + ExpressionsStmt() + ), + stmts.get().add( (Stmt)pop() ) + ) + ); + } + + Rule ReturnStmt() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + Keyword("return"), Expressions(), + push( new ReturnStmt( se(start.get()), (Expressions)pop() ) ) + ); + } + + Rule FunctionStmt() { + return Sequence( + Keyword("function"), FnName(), Function(), + push( new SetStmt( (Settable)pop(1), expr(pop()) ) ) + ); + } + + Rule FnName() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + push(null), // marker + Name(), + ZeroOrMore( + '.', Spaces(), + makeVarExp(start.get()), + NameExpr() + ), + makeSettableVar(start.get()) + ); + } + + Rule LocalFunctionStmt() { + return Sequence( + Keyword("local"), Keyword("function"), + Name(), + addSymbol( (String)pop() ), + Function(), + push( new SetStmt( new SetLocalVar(symbolsSize()-1), expr(pop()) ) ) + ); + } + + Rule BreakStmt() { + return Sequence( + Keyword("break"), + frame.loops > 0, + push( new BreakStmt() ) + ); + } + + Rule GenericForStmt() { + Var<Integer> start = new Var<Integer>(); + Var<Integer> stackStart = new Var<Integer>(symbolsSize()); + Var<List<String>> names = new Var<List<String>>(new ArrayList<String>()); + return Sequence( + start.set(currentIndex()), + Keyword("for"), NameList(names), Keyword("in"), Expr(), Keyword("do"), + addSymbols(names.get()), + LoopBlock(), Keyword("end"), + push( new GenericForStmt( se(start.get()), stackStart.get(), symbolsSize() - stackStart.get(), expr(pop(1)), (Stmt)pop() ) ), + popSymbols( symbolsSize() - stackStart.get() ) + ); + } + + Rule NumericForStmt() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + Keyword("for"), Name(), '=', Spaces(), Expr(), Keyword("to"), Expr(), + push( new ConstExpr(1) ), // default step + Optional( + Keyword("step"), + drop(), + Expr() + ), + addSymbol( (String)pop(3) ), // add "for" var to symbols + Keyword("do"), LoopBlock(), Keyword("end"), + push( new NumericForStmt( se(start.get()), symbolsSize()-1, expr(pop(3)), expr(pop(2)), expr(pop(1)), (Stmt)pop() ) ), + popSymbols(1) + ); + } + + Rule TryStmt() { + return Sequence( + Keyword("try"), Block(), + Keyword("catch"), Name(), addSymbol( (String)pop() ), + Keyword("do"), Block(), Keyword("end"), + push( new TryStmt( (Stmt)pop(1), symbolsSize()-1, (Stmt)pop() ) ), + popSymbols(1) + ); + } + + Rule DoStmt() { + return Sequence( + Keyword("do"), Block(), Keyword("end") + ); + } + + Rule LocalStmt(Var<List<Stmt>> stmts) { + Var<List<String>> names = new Var<List<String>>(new ArrayList<String>()); + return Sequence( + Keyword("local"), NameList(names), + Optional( + '=', Spaces(), ExpList(), + stmts.get().add( newSetLocalStmt(names.get().size()) ) + ), + addSymbols(names.get()) + ); + } + + Rule NameList(Var<List<String>> names) { + return Sequence( + Name(), + names.get().add( (String)pop() ), + ZeroOrMore( + ',', Spaces(), Name(), + names.get().add( (String)pop() ) + ) + ); + } + + SetStmt newSetLocalStmt(int nVars) { + Expressions values = (Expressions)pop(); + SetLocalVar[] vars = new SetLocalVar[nVars]; + int stackStart = symbolsSize(); + for( int i=0; i<vars.length; i++ ) { + vars[i] = new SetLocalVar(stackStart+i); + } + return new SetStmt( vars, values ); + } + + Rule WhileStmt() { + return Sequence( + Keyword("while"), Expr(), Keyword("do"), LoopBlock(), Keyword("end"), + push( new WhileStmt( expr(pop(1)), (Stmt)pop() ) ) + ); + } + + Rule RepeatStmt() { + return Sequence( + Keyword("repeat"), LoopBlock(), Keyword("until"), Expr(), + push( new RepeatStmt( (Stmt)pop(1), expr(pop()) ) ) + ); + } + + Rule LoopBlock() { + return Sequence( incLoops(), Block(), decLoops() ); + } + + Rule IfStmt() { + Var<Integer> n = new Var<Integer>(1); + return Sequence( + Keyword("if"), Expr(), Keyword("then"), Block(), + push(Stmt.EMPTY), + ZeroOrMore( + Keyword("elseif"), drop(), Expr(), Keyword("then"), Block(), + push(Stmt.EMPTY), + n.set(n.get()+1) + ), + Optional( + Keyword("else"), drop(), Block() + ), + Keyword("end"), + buildIfStmt(n.get()) + ); + } + + boolean buildIfStmt(int n) { + while( n-- > 0 ) { + Stmt elseStmt = (Stmt)pop(); + Stmt thenStmt = (Stmt)pop(); + Expr cnd = expr(pop()); + push( new IfStmt(cnd,thenStmt,elseStmt) ); + } + return true; + } + + Rule SetStmt() { + return Sequence( + VarList(), + '=', Spaces(), + ExpList(), + push( newSetStmt() ) + ); + } + + Rule ExpressionsStmt() { + return Sequence( + ExpList(), + push( new ExpressionsStmt((Expressions)pop()) ) + ); + } + + SetStmt newSetStmt() { + Expressions values = (Expressions)pop(); + @SuppressWarnings("unchecked") + List<Settable> vars = (List<Settable>)pop(); + return new SetStmt( vars.toArray(new Settable[0]), values ); + } + + Rule VarList() { + Var<List<Settable>> vars = new Var<List<Settable>>(new ArrayList<Settable>()); + return Sequence( + SettableVar(), + vars.get().add( (Settable)pop() ), + ZeroOrMore( + ',', Spaces(), SettableVar(), + vars.get().add( (Settable)pop() ) + ), + push(vars.get()) + ); + } + + Rule SettableVar() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + Var(), + makeSettableVar(start.get()) + ); + } + + boolean makeSettableVar(int start) { + Object obj2 = pop(); + if( obj2==null ) + return false; + Object obj1 = pop(); + if( obj1!=null ) { + Expr key = expr(obj2); + Expr table = expr(obj1); + return push( new SetTableEntry(se(start),table,key) ); + } + String name = (String)obj2; + int index = stackIndex(name); + if( index != -1 ) + return push( new SetLocalVar(index) ); + index = upValueIndex(name); + if( index != -1 ) + return push( new SetUpVar(index) ); + return push( new SetTableEntry( se(start), env(), new ConstExpr(name) ) ); + } + + Rule Expr() { + return FirstOf( + VarArgs(), + OrExpr() + ); + } + + Rule OrExpr() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + AndExpr(), + ZeroOrMore( "or", Spaces(), AndExpr(), push( new OrExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) + ); + } + + Rule AndExpr() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + RelExpr(), + ZeroOrMore( "and", Spaces(), RelExpr(), push( new AndExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) + ); + } + + Rule RelExpr() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + ConcatExpr(), + ZeroOrMore( + FirstOf( + Sequence( "==", Spaces(), ConcatExpr(), push( new EqExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), + Sequence( "~=", Spaces(), ConcatExpr(), push( new NotExpr(se(start.get()),new EqExpr(se(start.get()),expr(pop(1)),expr(pop()))) ) ), + Sequence( "<=", Spaces(), ConcatExpr(), push( new LeExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), + Sequence( ">=", Spaces(), ConcatExpr(), push( new LeExpr(se(start.get()),expr(pop()),expr(pop())) ) ), + Sequence( "<", Spaces(), ConcatExpr(), push( new LtExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), + Sequence( ">", Spaces(), ConcatExpr(), push( new LtExpr(se(start.get()),expr(pop()),expr(pop())) ) ) + ) + ) + ); + } + + Rule ConcatExpr() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + SumExpr(), + Optional( "..", Spaces(), ConcatExpr(), push( new ConcatExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) + ); + } + + Rule SumExpr() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + TermExpr(), + ZeroOrMore( + FirstOf( + Sequence( '+', Spaces(), TermExpr(), push( new AddExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), + Sequence( '-', TestNot('-'), Spaces(), TermExpr(), push( new SubExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) + ) + ) + ); + } + + Rule TermExpr() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + UnaryExpr(), + ZeroOrMore( + FirstOf( + Sequence( '*', Spaces(), UnaryExpr(), push( new MulExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), + Sequence( '/', Spaces(), UnaryExpr(), push( new DivExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ), + Sequence( '%', Spaces(), UnaryExpr(), push( new ModExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) + ) + ) + ); + } + + Rule UnaryExpr() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + FirstOf( + Sequence( '#', Spaces(), PowExpr(), push( new LenExpr(se(start.get()),expr(pop())) ) ), + Sequence( '-', TestNot('-'), Spaces(), PowExpr(), push( new UnmExpr(se(start.get()),expr(pop())) ) ), + Sequence( "not", Spaces(), PowExpr(), push( new NotExpr(se(start.get()),expr(pop())) ) ), + PowExpr() + ) + ); + } + + Rule PowExpr() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + SingleExpr(), + Optional( '^', Spaces(), PowExpr(), push( new PowExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ) + ); + } + + Rule SingleExpr() { + return FirstOf( + FunctionExpr(), + TableExpr(), + VarExp(), + LiteralExpr() + ); + } + + Rule FunctionExpr() { + return Sequence( "function", Spaces(), Function() ); + } + + Rule Function() { + Var<Integer> start = new Var<Integer>(); + Var<List<String>> names = new Var<List<String>>(new ArrayList<String>()); + return Sequence( + start.set(currentIndex()), + '(', incParens(), Spaces(), + action( frame = new Frame(frame) ), + Optional( + FirstOf( + Sequence( + NameList(names), addSymbols(names.get()), + Optional( ',', Spaces(), VarArgName() ) + ), + VarArgName() + ) + ), + ')', decParens(), Spaces(), Block(), Keyword("end"), + push( newChunk(start.get()) ), + action( frame = frame.parent ) + ); + } + + Rule VarArgName() { + return Sequence( + "...", Spaces(), + action( frame.isVarArg = true ) + ); + } + + Rule VarArgs() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + "...", Spaces(), + frame.isVarArg, + push( new VarArgs(se(start.get())) ) + ); + } + + Rule TableExpr() { + Var<Integer> start = new Var<Integer>(); + Var<List<TableExpr.Field>> fields = new Var<List<TableExpr.Field>>(new ArrayList<TableExpr.Field>()); + Var<ExpList.Builder> builder = new Var<ExpList.Builder>(new ExpList.Builder()); + return Sequence( + start.set(currentIndex()), + '{', incParens(), Spaces(), + Optional( + Field(fields,builder), + ZeroOrMore( + FieldSep(), + Field(fields,builder) + ), + Optional( FieldSep() ) + ), + '}', decParens(), + Spaces(), + push( new TableExpr( se(start.get()), fields.get().toArray(new TableExpr.Field[0]), builder.get().build() ) ) + ); + } + + Rule FieldSep() { + return Sequence( AnyOf(",;"), Spaces() ); + } + + Rule Field(Var<List<TableExpr.Field>> fields,Var<ExpList.Builder> builder) { + return FirstOf( + Sequence( + FirstOf( SubExpr(), NameExpr() ), + '=', Spaces(), Expr(), + fields.get().add( new TableExpr.Field( expr(pop(1)), expr(pop()) ) ) + ), + Sequence( + Expr(), + addToExpList(builder.get()) + ) + ); + } + + static Expr expr(Object obj) { + if( obj instanceof Expressions ) + return new ExpressionsExpr((Expressions)obj); + return (Expr)obj; + } + + Rule VarExp() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + Var(), + makeVarExp(start.get()) + ); + } + + Rule Var() { + Var<Integer> start = new Var<Integer>(); + return Sequence( + start.set(currentIndex()), + FirstOf( + Sequence( + '(', incParens(), Spaces(), Expr(), ')', decParens(), Spaces(), + push(expr(pop())), + push(null) // marker + ), + Sequence( + push(null), // marker + Name() + ) + ), + ZeroOrMore( + makeVarExp(start.get()), + FirstOf( + SubExpr(), + Sequence( '.', Spaces(), NameExpr() ), + Sequence( + Args(start), + push(null) // marker + ) + ) + ) + ); + } + + Expr env() { + int index = stackIndex(_ENV); + if( index != -1 ) + return new GetLocalVar(null,index); + index = upValueIndex(_ENV); + if( index != -1 ) + return new GetUpVar(null,index); + throw new RuntimeException("_ENV not found"); + } + + boolean makeVarExp(int start) { + Object obj2 = pop(); + if( obj2==null ) + return true; + Object obj1 = pop(); + if( obj1 != null ) + return push( new IndexExpr( se(start), expr(obj1), expr(obj2) ) ); + String name = (String)obj2; + int index = stackIndex(name); + if( index != -1 ) + return push( new GetLocalVar(se(start),index) ); + index = upValueIndex(name); + if( index != -1 ) + return push( new GetUpVar(se(start),index) ); + return push( new IndexExpr( se(start), env(), new ConstExpr(name) ) ); + } + + // function should be on top of the stack + Rule Args(Var<Integer> start) { + return Sequence( + FirstOf( + Sequence( + '(', incParens(), Spaces(), Expressions(), ')', decParens(), Spaces() + ), + Sequence( + TableExpr(), + push( new ExpList.SingleExpList(expr(pop())) ) + ), + Sequence( + StringLiteral(), Spaces(), + push( new ExpList.SingleExpList(new ConstExpr(pop())) ) + ) + ), + push( new FnCall( se(start.get()), expr(pop(1)), (Expressions)pop() ) ) + ); + } + + Rule Expressions() { + return FirstOf( + ExpList(), + push( ExpList.emptyExpList ) + ); + } + + Rule ExpList() { + Var<ExpList.Builder> builder = new Var<ExpList.Builder>(new ExpList.Builder()); + return Sequence( + Expr(), + addToExpList(builder.get()), + ZeroOrMore( + ',', Spaces(), Expr(), + addToExpList(builder.get()) + ), + push( builder.get().build() ) + ); + } + + boolean addToExpList(ExpList.Builder bld) { + Object obj = pop(); + if( obj instanceof Expressions ) { + bld.add( (Expressions)obj ); + } else { + bld.add( (Expr)obj ); + } + return true; + } + + Rule SubExpr() { + return Sequence( '[', incParens(), Spaces(), Expr(), ']', decParens(), Spaces() ); + } + + Rule NameExpr() { + return Sequence( + Name(), + push( new ConstExpr((String)pop()) ) + ); + } + + Rule Name() { + return Sequence( + Sequence( + NameFirstChar(), + ZeroOrMore( NameChar() ) + ), + !keywords.contains(match()), + push(match()), + Spaces() + ); + } + + Rule NameChar() { + return FirstOf( NameFirstChar(), Digit() ); + } + + Rule NameFirstChar() { + return FirstOf( + CharRange('a', 'z'), + CharRange('A', 'Z'), + '_' + ); + } + + Rule Keyword(String keyword) { + return Sequence( + keyword, + TestNot( NameChar() ), + Spaces() + ); + } + + static final Set<String> keywords = new HashSet<String>(Arrays.asList( + "and", + "break", + "catch", + "do", + "else", + "elseif", + "end", + "false", + "for", + "function", + "goto", + "if", + "in", + "local", + "nil", + "not", + "or", + "repeat", + "return", + "step", + "then", + "to", + "true", + "try", + "until", + "while" + )); + + Rule LiteralExpr() { + return Sequence( + Literal(), Spaces(), + push(new ConstExpr(pop())) + ); + } + + Rule Literal() { + return FirstOf( + NilLiteral(), + BooleanLiteral(), + NumberLiteral(), + StringLiteral() + ); + } + + Rule NilLiteral() { + return Sequence( "nil", push(null) ); + } + + Rule BooleanLiteral() { + return FirstOf( + Sequence( "true", push(true) ), + Sequence( "false", push(false) ) + ); + } + + Rule NumberLiteral() { + return FirstOf( + Sequence( + IgnoreCase("0x"), + HexNumber() + ), + Sequence( + DecNumber(), + push(Double.valueOf(match())) + ) + ); + } + + Rule DecNumber() { + return FirstOf( + Sequence( + Int(), + Optional( '.', Optional(Int()) ), + Exponent() + ), + Sequence( '.', Int(), Exponent() ) + ); + } + + Rule Exponent() { + return Optional( + IgnoreCase('e'), + Optional(AnyOf("+-")), + Int() + ); + } + + Rule Int() { + return OneOrMore(Digit()); + } + + Rule Digit() { + return CharRange('0', '9'); + } + + Rule HexNumber() { + return FirstOf( + Sequence( + HexInt(), + push( (double)Long.parseLong(match(),16) ), + Optional( '.', Optional(HexDec()) ), + HexExponent() + ), + Sequence( push(0.0), '.', HexDec(), HexExponent() ) + ); + } + + Rule HexDec() { + return Sequence( + HexInt(), + push( (Double)pop() + (double)Long.parseLong(match(),16) / Math.pow(16,matchLength()) ) + ); + } + + Rule HexExponent() { + return Optional( + IgnoreCase('p'), + Sequence( + Optional(AnyOf("+-")), + HexInt() + ), + push( (Double)pop() * Math.pow(2,(double)Long.parseLong(match())) ) + ); + } + + Rule HexInt() { + return OneOrMore(Digit()); + } + + + Rule HexDigit() { + return FirstOf( + Digit(), + AnyOf("abcdefABCDEF") + ); + } + + Rule StringLiteral() { + return FirstOf( + QuotedString('"'), + QuotedString('\''), + LongString() + ); + } + + Rule LongString() { + return Sequence( + '[', + ZeroOrMore('='), + nEquals(matchLength()), + '[', + ZeroOrMore( + TestNot(LongBracketsEnd()), + ANY + ), + push( match() ), + LongBracketsEnd() + ); + } + + Rule QuotedString(char quote) { + StringBuilderVar buf = new StringBuilderVar(); + return Sequence( + quote, + ZeroOrMore( + FirstOf( + Sequence( + NoneOf("\\\n"+quote), + buf.append(matchedChar()) + ), + EscSeq(buf) + ) + ), + quote, + push( buf.getString() ) + ); + } + + Rule EscSeq(StringBuilderVar buf) { + return Sequence( + '\\', + FirstOf( + Sequence( 'a', buf.append('\u0007') ), + Sequence( 'b', buf.append('\b') ), + Sequence( 'f', buf.append('\f') ), + Sequence( 'n', buf.append('\n') ), + Sequence( 'r', buf.append('\r') ), + Sequence( 't', buf.append('\t') ), + Sequence( 'v', buf.append('\u000b') ), + Sequence( '\\', buf.append('\\') ), + Sequence( '"', buf.append('"') ), + Sequence( '\'', buf.append('\'') ), + Sequence( + 'x', + Sequence( HexDigit(), HexDigit() ), + buf.append( (char)Integer.parseInt(match(),16) ) + ), + Sequence( + Sequence( + Digit(), + Optional( + Digit(), + Optional( + Digit() + ) + ) + ), + buf.append( (char)Integer.parseInt(match()) ) + ) + ) + ); + } + + Rule Spaces() { + return ZeroOrMore( + FirstOf( + AnyOf(" \t"), + Comment(), + Sequence( '\\', EndOfLine() ), + Sequence( AnyOf("\r\n"), parens > 0 ) + ) + ); + } + + Rule Comment() { + return Sequence( + "--[", + ZeroOrMore('='), + nEquals(matchLength()), + '[', + ZeroOrMore( + TestNot(LongBracketsEnd()), + ANY + ), + LongBracketsEnd() + ); + } + + Rule LongBracketsEnd() { + return Sequence( ']', ZeroOrMore('='), nEquals==matchLength(), ']' ); + } + + static boolean action(Object obj) { + return true; + } + + // for debugging + boolean print(Object o) { + System.out.println(o); + return true; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/LuanStateImpl.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,102 @@ +package luan.interp; + +import java.util.List; +import java.util.ArrayList; +import luan.Luan; +import luan.LuanState; +import luan.LuanTable; +import luan.LuanFunction; +import luan.MetatableGetter; +import luan.LuanException; +import luan.LuanElement; + + +final class LuanStateImpl extends LuanState { + + final Object arithmetic(LuanElement el,String op,Object o1,Object o2) throws LuanException { + LuanFunction fn = getBinHandler(el,op,o1,o2); + if( fn != null ) + return Luan.first(call(fn,el,op,o1,o2)); + String type = Luan.toNumber(o1)==null ? Luan.type(o1) : Luan.type(o2); + throw new LuanException(this,el,"attempt to perform arithmetic on a "+type+" value"); + } + + + private static class Frame { + final Frame previousFrame; + final Closure closure; + final Object[] stack; + final Object[] varArgs; + UpValue[] downValues = null; + + Frame( Frame previousFrame, Closure closure, int stackSize, Object[] varArgs) { + this.previousFrame = previousFrame; + this.closure = closure; + this.stack = new Object[stackSize]; + this.varArgs = varArgs; + } + + void stackClear(int start,int end) { + if( downValues != null ) { + for( int i=start; i<end; i++ ) { + UpValue downValue = downValues[i]; + if( downValue != null ) { + downValue.close(); + downValues[i] = null; + } + } + } + for( int i=start; i<end; i++ ) { + stack[i] = null; + } + } + + UpValue getUpValue(int index) { + if( downValues==null ) + downValues = new UpValue[stack.length]; + if( downValues[index] == null ) + downValues[index] = new UpValue(stack,index); + return downValues[index]; + } + } + + private Frame frame = null; + Object[] returnValues; + Closure tailFn; + + // returns stack + Object[] newFrame(Closure closure, int stackSize, Object[] varArgs) { + frame = new Frame(frame,closure,stackSize,varArgs); + return frame.stack; + } + + void popFrame() { + returnValues = LuanFunction.EMPTY_RTN; + tailFn = null; + frame = frame.previousFrame; + } + + Object stackGet(int index) { + return frame.stack[index]; + } + + void stackSet(int index,Object value) { + frame.stack[index] = value; + } + + void stackClear(int start,int end) { + frame.stackClear(start,end); + } + + Object[] varArgs() { + return frame.varArgs; + } + + Closure closure() { + return frame.closure; + } + + UpValue getUpValue(int index) { + return frame.getUpValue(index); + } +}
--- a/src/luan/interp/ModExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/ModExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,21 +1,21 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class ModExpr extends BinaryOpExpr { - ModExpr(LuaSource.Element se,Expr op1,Expr op2) { + ModExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); - Number n1 = Lua.toNumber(o1); - Number n2 = Lua.toNumber(o2); + Number n1 = Luan.toNumber(o1); + Number n2 = Luan.toNumber(o2); if( n1 != null && n2 != null ) return n1.doubleValue() % n2.doubleValue(); return arithmetic(lua,"__mod",o1,o2);
--- a/src/luan/interp/MulExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/MulExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,21 +1,21 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class MulExpr extends BinaryOpExpr { - MulExpr(LuaSource.Element se,Expr op1,Expr op2) { + MulExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); - Number n1 = Lua.toNumber(o1); - Number n2 = Lua.toNumber(o2); + Number n1 = Luan.toNumber(o1); + Number n2 = Luan.toNumber(o2); if( n1 != null && n2 != null ) return n1.doubleValue() * n2.doubleValue(); return arithmetic(lua,"__mul",o1,o2);
--- a/src/luan/interp/NotExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/NotExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,17 +1,17 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class NotExpr extends UnaryOpExpr { - NotExpr(LuaSource.Element se,Expr op) { + NotExpr(LuanSource.Element se,Expr op) { super(se,op); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { - return !Lua.toBoolean(op.eval(lua)); + @Override public Object eval(LuanStateImpl lua) throws LuanException { + return !Luan.toBoolean(op.eval(lua)); } }
--- a/src/luan/interp/NumericForStmt.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/NumericForStmt.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,8 +1,8 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class NumericForStmt extends CodeImpl implements Stmt { @@ -12,7 +12,7 @@ private final Expr stepExpr; private final Stmt block; - NumericForStmt(LuaSource.Element se,int iVar,Expr fromExpr,Expr toExpr,Expr stepExpr,Stmt block) { + NumericForStmt(LuanSource.Element se,int iVar,Expr fromExpr,Expr toExpr,Expr stepExpr,Stmt block) { super(se); this.iVar = iVar; this.fromExpr = fromExpr; @@ -21,7 +21,7 @@ this.block = block; } - @Override public void eval(LuaStateImpl lua) throws LuaException { + @Override public void eval(LuanStateImpl lua) throws LuanException { double v = lua.checkNumber( se, fromExpr.eval(lua) ).doubleValue(); double limit = lua.checkNumber( se, toExpr.eval(lua) ).doubleValue(); double step = lua.checkNumber( se, stepExpr.eval(lua) ).doubleValue();
--- a/src/luan/interp/OrExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/OrExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,18 +1,18 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class OrExpr extends BinaryOpExpr { - OrExpr(LuaSource.Element se,Expr op1,Expr op2) { + OrExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object v1 = op1.eval(lua); - return Lua.toBoolean(v1) ? v1 : op2.eval(lua); + return Luan.toBoolean(v1) ? v1 : op2.eval(lua); } }
--- a/src/luan/interp/PowExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/PowExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,21 +1,21 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class PowExpr extends BinaryOpExpr { - PowExpr(LuaSource.Element se,Expr op1,Expr op2) { + PowExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); - Number n1 = Lua.toNumber(o1); - Number n2 = Lua.toNumber(o2); + Number n1 = Luan.toNumber(o1); + Number n2 = Luan.toNumber(o2); if( n1 != null && n2 != null ) return Math.pow( n1.doubleValue(), n2.doubleValue() ); return arithmetic(lua,"__pow",o1,o2);
--- a/src/luan/interp/RepeatStmt.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/RepeatStmt.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,7 +1,7 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; +import luan.Luan; +import luan.LuanException; final class RepeatStmt implements Stmt { @@ -13,11 +13,11 @@ this.cnd = cnd; } - @Override public void eval(LuaStateImpl lua) throws LuaException { + @Override public void eval(LuanStateImpl lua) throws LuanException { try { do { doStmt.eval(lua); - } while( !Lua.toBoolean( cnd.eval(lua) ) ); + } while( !Luan.toBoolean( cnd.eval(lua) ) ); } catch(BreakException e) {} } }
--- a/src/luan/interp/ReturnStmt.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/ReturnStmt.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,9 +1,9 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaFunction; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanFunction; +import luan.LuanSource; final class ReturnStmt extends CodeImpl implements Stmt { @@ -11,7 +11,7 @@ private final Expr tailFnExpr; boolean throwReturnException = true; - ReturnStmt(LuaSource.Element se,Expressions expressions) { + ReturnStmt(LuanSource.Element se,Expressions expressions) { super(se); if( expressions instanceof FnCall ) { // tail call FnCall fnCall = (FnCall)expressions; @@ -23,12 +23,12 @@ } } - @Override public void eval(LuaStateImpl lua) throws LuaException { + @Override public void eval(LuanStateImpl lua) throws LuanException { lua.returnValues = expressions.eval(lua); if( tailFnExpr != null ) { - LuaFunction tailFn = lua.checkFunction( se, tailFnExpr.eval(lua) ); - if( tailFn instanceof LuaClosure ) { - lua.tailFn = (LuaClosure)tailFn; + LuanFunction tailFn = lua.checkFunction( se, tailFnExpr.eval(lua) ); + if( tailFn instanceof Closure ) { + lua.tailFn = (Closure)tailFn; } else { lua.returnValues = lua.call(tailFn,tailFnExpr.se(),tailFnExpr.se().text(),lua.returnValues); }
--- a/src/luan/interp/SetLocalVar.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/SetLocalVar.java Fri Dec 28 03:29:12 2012 +0000 @@ -8,7 +8,7 @@ this.index = index; } - @Override public void set(LuaStateImpl lua,Object value) { + @Override public void set(LuanStateImpl lua,Object value) { lua.stackSet( index, value ); } }
--- a/src/luan/interp/SetStmt.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/SetStmt.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,7 +1,7 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; +import luan.Luan; +import luan.LuanException; final class SetStmt implements Stmt { @@ -17,7 +17,7 @@ this.expressions = expressions; } - @Override public void eval(LuaStateImpl lua) throws LuaException { + @Override public void eval(LuanStateImpl lua) throws LuanException { final Object[] vals = expressions.eval(lua); for( int i=0; i<vars.length; i++ ) { Object val = i < vals.length ? vals[i] : null;
--- a/src/luan/interp/SetTableEntry.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/SetTableEntry.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,30 +1,30 @@ package luan.interp; -import luan.LuaException; -import luan.LuaTable; -import luan.Lua; -import luan.LuaFunction; -import luan.LuaSource; +import luan.LuanException; +import luan.LuanTable; +import luan.Luan; +import luan.LuanFunction; +import luan.LuanSource; final class SetTableEntry extends CodeImpl implements Settable { private final Expr tableExpr; private final Expr keyExpr; - SetTableEntry(LuaSource.Element se,Expr tableExpr,Expr keyExpr) { + SetTableEntry(LuanSource.Element se,Expr tableExpr,Expr keyExpr) { super(se); this.tableExpr = tableExpr; this.keyExpr = keyExpr; } - @Override public void set(LuaStateImpl lua,Object value) throws LuaException { + @Override public void set(LuanStateImpl lua,Object value) throws LuanException { newindex( lua, tableExpr.eval(lua), keyExpr.eval(lua), value ); } - private void newindex(LuaStateImpl lua,Object t,Object key,Object value) throws LuaException { + private void newindex(LuanStateImpl lua,Object t,Object key,Object value) throws LuanException { Object h; - if( t instanceof LuaTable ) { - LuaTable table = (LuaTable)t; + if( t instanceof LuanTable ) { + LuanTable table = (LuanTable)t; Object old = table.put(key,value); if( old != null ) return; @@ -35,10 +35,10 @@ } else { h = lua.getHandler("__newindex",t); if( h==null ) - throw new LuaException( lua, se, "attempt to index a " + Lua.type(t) + " value" ); + throw new LuanException( lua, se, "attempt to index a " + Luan.type(t) + " value" ); } - if( h instanceof LuaFunction ) { - LuaFunction fn = (LuaFunction)h; + if( h instanceof LuanFunction ) { + LuanFunction fn = (LuanFunction)h; lua.call(fn,se,"__newindex",t,key,value); } newindex(lua,h,key,value);
--- a/src/luan/interp/SetUpVar.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/SetUpVar.java Fri Dec 28 03:29:12 2012 +0000 @@ -8,7 +8,7 @@ this.index = index; } - @Override public void set(LuaStateImpl lua,Object value) { + @Override public void set(LuanStateImpl lua,Object value) { lua.closure().upValues[index].set(value); } }
--- a/src/luan/interp/Settable.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/Settable.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,8 +1,8 @@ package luan.interp; -import luan.LuaException; +import luan.LuanException; interface Settable { - public void set(LuaStateImpl lua,Object value) throws LuaException; + public void set(LuanStateImpl lua,Object value) throws LuanException; }
--- a/src/luan/interp/Stmt.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/Stmt.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,12 +1,12 @@ package luan.interp; -import luan.LuaException; +import luan.LuanException; interface Stmt { - public void eval(LuaStateImpl lua) throws LuaException; + public void eval(LuanStateImpl lua) throws LuanException; static final Stmt EMPTY = new Stmt() { - @Override public void eval(LuaStateImpl lua) {} + @Override public void eval(LuanStateImpl lua) {} }; }
--- a/src/luan/interp/SubExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/SubExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,21 +1,21 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanException; +import luan.LuanSource; final class SubExpr extends BinaryOpExpr { - SubExpr(LuaSource.Element se,Expr op1,Expr op2) { + SubExpr(LuanSource.Element se,Expr op1,Expr op2) { super(se,op1,op2); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o1 = op1.eval(lua); Object o2 = op2.eval(lua); - Number n1 = Lua.toNumber(o1); - Number n2 = Lua.toNumber(o2); + Number n1 = Luan.toNumber(o1); + Number n2 = Luan.toNumber(o2); if( n1 != null && n2 != null ) return n1.doubleValue() - n2.doubleValue(); return arithmetic(lua,"__sub",o1,o2);
--- a/src/luan/interp/TableExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/TableExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,8 +1,8 @@ package luan.interp; -import luan.LuaException; -import luan.LuaTable; -import luan.LuaSource; +import luan.LuanException; +import luan.LuanTable; +import luan.LuanSource; final class TableExpr extends CodeImpl implements Expr { @@ -20,14 +20,14 @@ private final Field[] fields; private final Expressions expressions; - TableExpr(LuaSource.Element se,Field[] fields,Expressions expressions) { + TableExpr(LuanSource.Element se,Field[] fields,Expressions expressions) { super(se); this.fields = fields; this.expressions = expressions; } - @Override public Object eval(LuaStateImpl lua) throws LuaException { - LuaTable table = new LuaTable(); + @Override public Object eval(LuanStateImpl lua) throws LuanException { + LuanTable table = new LuanTable(); for( Field field : fields ) { table.put( field.key.eval(lua), field.value.eval(lua) ); }
--- a/src/luan/interp/UnaryOpExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/UnaryOpExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,12 +1,12 @@ package luan.interp; -import luan.LuaSource; +import luan.LuanSource; abstract class UnaryOpExpr extends CodeImpl implements Expr { final Expr op; - UnaryOpExpr(LuaSource.Element se,Expr op) { + UnaryOpExpr(LuanSource.Element se,Expr op) { super(se); this.op = op; }
--- a/src/luan/interp/UnmExpr.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/UnmExpr.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,27 +1,27 @@ package luan.interp; -import luan.Lua; -import luan.LuaFunction; -import luan.LuaException; -import luan.LuaSource; +import luan.Luan; +import luan.LuanFunction; +import luan.LuanException; +import luan.LuanSource; // unary minus final class UnmExpr extends UnaryOpExpr { - UnmExpr(LuaSource.Element se,Expr op) { + UnmExpr(LuanSource.Element se,Expr op) { super(se,op); } - @Override public Object eval(LuaStateImpl lua) throws LuaException { + @Override public Object eval(LuanStateImpl lua) throws LuanException { Object o = op.eval(lua); - Number n = Lua.toNumber(o); + Number n = Luan.toNumber(o); if( n != null ) return -n.doubleValue(); - LuaFunction fn = lua.getHandlerFunction(se,"__unm",o); + LuanFunction fn = lua.getHandlerFunction(se,"__unm",o); if( fn != null ) { - return Lua.first(lua.call(fn,se,"__unm",o)); + return Luan.first(lua.call(fn,se,"__unm",o)); } - throw new LuaException(lua,se,"attempt to perform arithmetic on a "+Lua.type(o)+" value"); + throw new LuanException(lua,se,"attempt to perform arithmetic on a "+Luan.type(o)+" value"); } }
--- a/src/luan/interp/UpValue.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/UpValue.java Fri Dec 28 03:29:12 2012 +0000 @@ -36,7 +36,7 @@ } static interface Getter { - public UpValue get(LuaStateImpl lua); + public UpValue get(LuanStateImpl lua); } static final class StackGetter implements Getter { @@ -46,7 +46,7 @@ this.index = index; } - public UpValue get(LuaStateImpl lua) { + public UpValue get(LuanStateImpl lua) { return lua.getUpValue(index); } } @@ -58,13 +58,13 @@ this.index = index; } - public UpValue get(LuaStateImpl lua) { + public UpValue get(LuanStateImpl lua) { return lua.closure().upValues[index]; } } static final Getter globalGetter = new Getter() { - public UpValue get(LuaStateImpl lua) { + public UpValue get(LuanStateImpl lua) { return new UpValue(lua.global()); } };
--- a/src/luan/interp/VarArgs.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/VarArgs.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,15 +1,15 @@ package luan.interp; -import luan.LuaSource; +import luan.LuanSource; final class VarArgs extends CodeImpl implements Expressions { - VarArgs(LuaSource.Element se) { + VarArgs(LuanSource.Element se) { super(se); } - @Override public Object[] eval(LuaStateImpl lua) { + @Override public Object[] eval(LuanStateImpl lua) { return lua.varArgs(); } }
--- a/src/luan/interp/WhileStmt.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/interp/WhileStmt.java Fri Dec 28 03:29:12 2012 +0000 @@ -1,7 +1,7 @@ package luan.interp; -import luan.Lua; -import luan.LuaException; +import luan.Luan; +import luan.LuanException; final class WhileStmt implements Stmt { @@ -13,9 +13,9 @@ this.doStmt = doStmt; } - @Override public void eval(LuaStateImpl lua) throws LuaException { + @Override public void eval(LuanStateImpl lua) throws LuanException { try { - while( Lua.toBoolean( cnd.eval(lua) ) ) { + while( Luan.toBoolean( cnd.eval(lua) ) ) { doStmt.eval(lua); } } catch(BreakException e) {}
--- a/src/luan/lib/BasicLib.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/lib/BasicLib.java Fri Dec 28 03:29:12 2012 +0000 @@ -8,53 +8,53 @@ import java.lang.reflect.Method; import java.util.Iterator; import java.util.Map; -import luan.Lua; -import luan.LuaState; -import luan.LuaTable; -import luan.LuaFunction; -import luan.LuaJavaFunction; -import luan.LuaException; -import luan.LuaSource; -import luan.LuaElement; -import luan.interp.LuaCompiler; +import luan.Luan; +import luan.LuanState; +import luan.LuanTable; +import luan.LuanFunction; +import luan.LuanJavaFunction; +import luan.LuanException; +import luan.LuanSource; +import luan.LuanElement; +import luan.interp.LuanCompiler; public final class BasicLib { - public static void register(LuaState lua) { - LuaTable global = lua.global(); + public static void register(LuanState lua) { + LuanTable global = lua.global(); global.put( "_G", global ); - add( global, "do_file", LuaState.class, String.class ); - add( global, "error", LuaState.class, Object.class ); - add( global, "get_metatable", LuaState.class, Object.class ); - add( global, "ipairs", LuaTable.class ); - add( global, "load", LuaState.class, String.class, String.class ); - add( global, "load_file", LuaState.class, String.class ); - add( global, "pairs", LuaTable.class ); - add( global, "print", LuaState.class, new Object[0].getClass() ); + add( global, "do_file", LuanState.class, String.class ); + add( global, "error", LuanState.class, Object.class ); + add( global, "get_metatable", LuanState.class, Object.class ); + add( global, "ipairs", LuanTable.class ); + add( global, "load", LuanState.class, String.class, String.class ); + add( global, "load_file", LuanState.class, String.class ); + add( global, "pairs", LuanTable.class ); + add( global, "print", LuanState.class, new Object[0].getClass() ); add( global, "raw_equal", Object.class, Object.class ); - add( global, "raw_get", LuaTable.class, Object.class ); - add( global, "raw_len", LuaState.class, Object.class ); - add( global, "raw_set", LuaTable.class, Object.class, Object.class ); - add( global, "set_metatable", LuaTable.class, LuaTable.class ); + add( global, "raw_get", LuanTable.class, Object.class ); + add( global, "raw_len", LuanState.class, Object.class ); + add( global, "raw_set", LuanTable.class, Object.class, Object.class ); + add( global, "set_metatable", LuanTable.class, LuanTable.class ); add( global, "to_number", Object.class, Integer.class ); - add( global, "to_string", LuaState.class, Object.class ); + add( global, "to_string", LuanState.class, Object.class ); add( global, "type", Object.class ); - global.put( "_VERSION", Lua.version ); + global.put( "_VERSION", Luan.version ); - add( global, "make_standard", LuaState.class ); + add( global, "make_standard", LuanState.class ); } - private static void add(LuaTable t,String method,Class<?>... parameterTypes) { + private static void add(LuanTable t,String method,Class<?>... parameterTypes) { try { - t.put( method, new LuaJavaFunction(BasicLib.class.getMethod(method,parameterTypes),null) ); + t.put( method, new LuanJavaFunction(BasicLib.class.getMethod(method,parameterTypes),null) ); } catch(NoSuchMethodException e) { throw new RuntimeException(e); } } - public static void make_standard(LuaState lua) { - LuaTable global = lua.global(); + public static void make_standard(LuanState lua) { + LuanTable global = lua.global(); global.put( "dofile", global.get("do_file") ); global.put( "getmetatable", global.get("get_metatable") ); global.put( "loadfile", global.get("load_file") ); @@ -67,21 +67,21 @@ global.put( "tostring", global.get("to_string") ); } - public static void print(LuaState lua,Object... args) throws LuaException { + public static void print(LuanState lua,Object... args) throws LuanException { for( int i=0; i<args.length; i++ ) { if( i > 0 ) System.out.print('\t'); - System.out.print( lua.toString(LuaElement.JAVA,args[i]) ); + System.out.print( lua.toString(LuanElement.JAVA,args[i]) ); } System.out.println(); } public static String type(Object obj) { - return Lua.type(obj); + return Luan.type(obj); } - public static LuaFunction load(LuaState lua,String text,String sourceName) throws LuaException { - return LuaCompiler.compile(lua,new LuaSource(sourceName,text)); + public static LuanFunction load(LuanState lua,String text,String sourceName) throws LuanException { + return LuanCompiler.compile(lua,new LuanSource(sourceName,text)); } public static String readAll(Reader in) @@ -106,44 +106,44 @@ } - public static LuaFunction load_file(LuaState lua,String fileName) throws LuaException { + public static LuanFunction load_file(LuanState lua,String fileName) throws LuanException { try { String src = fileName==null ? readAll(new InputStreamReader(System.in)) : read(new File(fileName)); return load(lua,src,fileName); } catch(IOException e) { - throw new LuaException(lua,LuaElement.JAVA,e); + throw new LuanException(lua,LuanElement.JAVA,e); } } - public static Object[] do_file(LuaState lua,String fileName) throws LuaException { - LuaFunction fn = load_file(lua,fileName); - return lua.call(fn,LuaElement.JAVA,null); + public static Object[] do_file(LuanState lua,String fileName) throws LuanException { + LuanFunction fn = load_file(lua,fileName); + return lua.call(fn,LuanElement.JAVA,null); } - private static LuaFunction pairs(final Iterator<Map.Entry<Object,Object>> iter) { - return new LuaFunction() { - public Object[] call(LuaState lua,Object[] args) { + private static LuanFunction pairs(final Iterator<Map.Entry<Object,Object>> iter) { + return new LuanFunction() { + public Object[] call(LuanState lua,Object[] args) { if( !iter.hasNext() ) - return LuaFunction.EMPTY_RTN; + return LuanFunction.EMPTY_RTN; Map.Entry<Object,Object> entry = iter.next(); return new Object[]{entry.getKey(),entry.getValue()}; } }; } - public static LuaFunction pairs(LuaTable t) { + public static LuanFunction pairs(LuanTable t) { return pairs( t.iterator() ); } - public static LuaFunction ipairs(LuaTable t) { + public static LuanFunction ipairs(LuanTable t) { return pairs( t.listIterator() ); } - public static LuaTable get_metatable(LuaState lua,Object obj) { + public static LuanTable get_metatable(LuanState lua,Object obj) { return lua.getMetatable(obj); } - public static LuaTable set_metatable(LuaTable table,LuaTable metatable) { + public static LuanTable set_metatable(LuanTable table,LuanTable metatable) { table.setMetatable(metatable); return table; } @@ -152,37 +152,37 @@ return v1 == v2 || v1 != null && v1.equals(v2); } - public static Object raw_get(LuaTable table,Object index) { + public static Object raw_get(LuanTable table,Object index) { return table.get(index); } - public static LuaTable raw_set(LuaTable table,Object index,Object value) { + public static LuanTable raw_set(LuanTable table,Object index,Object value) { table.put(index,value); return table; } - public static int raw_len(LuaState lua,Object v) throws LuaException { + public static int raw_len(LuanState lua,Object v) throws LuanException { if( v instanceof String ) { String s = (String)v; return s.length(); } - if( v instanceof LuaTable ) { - LuaTable t = (LuaTable)v; + if( v instanceof LuanTable ) { + LuanTable t = (LuanTable)v; return t.length(); } - throw new LuaException( lua, LuaElement.JAVA, "bad argument #1 to 'raw_len' (table or string expected)" ); + throw new LuanException( lua, LuanElement.JAVA, "bad argument #1 to 'raw_len' (table or string expected)" ); } public static Number to_number(Object e,Integer base) { - return Lua.toNumber(e,base); + return Luan.toNumber(e,base); } - public static String to_string(LuaState lua,Object v) throws LuaException { - return lua.toString(LuaElement.JAVA,v); + public static String to_string(LuanState lua,Object v) throws LuanException { + return lua.toString(LuanElement.JAVA,v); } - public static void error(LuaState lua,Object msg) throws LuaException { - throw new LuaException(lua,LuaElement.JAVA,msg); + public static void error(LuanState lua,Object msg) throws LuanException { + throw new LuanException(lua,LuanElement.JAVA,msg); } }
--- a/src/luan/lib/JavaLib.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/lib/JavaLib.java Fri Dec 28 03:29:12 2012 +0000 @@ -11,53 +11,53 @@ import java.util.List; import java.util.ArrayList; import java.util.Iterator; -import luan.Lua; -import luan.LuaState; -import luan.LuaTable; +import luan.Luan; +import luan.LuanState; +import luan.LuanTable; import luan.MetatableGetter; -import luan.LuaException; -import luan.LuaFunction; -import luan.LuaJavaFunction; -import luan.LuaElement; +import luan.LuanException; +import luan.LuanFunction; +import luan.LuanJavaFunction; +import luan.LuanElement; public final class JavaLib { - public static void register(LuaState lua) { + public static void register(LuanState lua) { lua.addMetatableGetter(mg); - LuaTable module = new LuaTable(); - LuaTable global = lua.global(); + LuanTable module = new LuanTable(); + LuanTable global = lua.global(); global.put("java",module); try { - global.put( "import", new LuaJavaFunction(JavaLib.class.getMethod("importClass",LuaState.class,String.class),null) ); - module.put( "class", new LuaJavaFunction(JavaLib.class.getMethod("getClass",LuaState.class,String.class),null) ); + global.put( "import", new LuanJavaFunction(JavaLib.class.getMethod("importClass",LuanState.class,String.class),null) ); + module.put( "class", new LuanJavaFunction(JavaLib.class.getMethod("getClass",LuanState.class,String.class),null) ); } catch(NoSuchMethodException e) { throw new RuntimeException(e); } } - private static final LuaTable mt = new LuaTable(); + private static final LuanTable mt = new LuanTable(); static { - add( mt, "__index", LuaState.class, Object.class, Object.class ); + add( mt, "__index", LuanState.class, Object.class, Object.class ); } - private static void add(LuaTable t,String method,Class<?>... parameterTypes) { + private static void add(LuanTable t,String method,Class<?>... parameterTypes) { try { - t.put( method, new LuaJavaFunction(JavaLib.class.getMethod(method,parameterTypes),null) ); + t.put( method, new LuanJavaFunction(JavaLib.class.getMethod(method,parameterTypes),null) ); } catch(NoSuchMethodException e) { throw new RuntimeException(e); } } private static final MetatableGetter mg = new MetatableGetter() { - public LuaTable getMetatable(Object obj) { + public LuanTable getMetatable(Object obj) { if( obj==null ) return null; return mt; } }; - public static Object __index(LuaState lua,Object obj,Object key) throws LuaException { + public static Object __index(LuanState lua,Object obj,Object key) throws LuanException { if( obj instanceof Static ) { if( key instanceof String ) { String name = (String)key; @@ -69,11 +69,11 @@ Constructor<?>[] constructors = cls.getConstructors(); if( constructors.length > 0 ) { if( constructors.length==1 ) { - return new LuaJavaFunction(constructors[0],null); + return new LuanJavaFunction(constructors[0],null); } else { - List<LuaJavaFunction> fns = new ArrayList<LuaJavaFunction>(); + List<LuanJavaFunction> fns = new ArrayList<LuanJavaFunction>(); for( Constructor constructor : constructors ) { - fns.add(new LuaJavaFunction(constructor,null)); + fns.add(new LuanJavaFunction(constructor,null)); } return new AmbiguousJavaFunction(fns); } @@ -85,23 +85,23 @@ } } } - throw new LuaException(lua,LuaElement.JAVA,"invalid index for java class: "+key); + throw new LuanException(lua,LuanElement.JAVA,"invalid index for java class: "+key); } Class cls = obj.getClass(); if( cls.isArray() ) { if( "length".equals(key) ) { return Array.getLength(obj); } - Integer i = Lua.asInteger(key); + Integer i = Luan.asInteger(key); if( i != null ) { return Array.get(obj,i); } - throw new LuaException(lua,LuaElement.JAVA,"invalid index for java array: "+key); + throw new LuanException(lua,LuanElement.JAVA,"invalid index for java array: "+key); } if( key instanceof String ) { String name = (String)key; if( "instanceof".equals(name) ) { - return new LuaJavaFunction(instanceOf,new InstanceOf(obj)); + return new LuanJavaFunction(instanceOf,new InstanceOf(obj)); } else { List<Member> members = getMembers(cls,name); if( !members.isEmpty() ) { @@ -109,10 +109,10 @@ } } } - throw new LuaException(lua,LuaElement.JAVA,"invalid index for java object: "+key); + throw new LuanException(lua,LuanElement.JAVA,"invalid index for java object: "+key); } - private static Object member(Object obj,List<Member> members) throws LuaException { + private static Object member(Object obj,List<Member> members) throws LuanException { try { if( members.size()==1 ) { Member member = members.get(0); @@ -121,13 +121,13 @@ return field.get(obj); } else { Method method = (Method)member; - return new LuaJavaFunction(method,obj); + return new LuanJavaFunction(method,obj); } } else { - List<LuaJavaFunction> fns = new ArrayList<LuaJavaFunction>(); + List<LuanJavaFunction> fns = new ArrayList<LuanJavaFunction>(); for( Member member : members ) { Method method = (Method)member; - fns.add(new LuaJavaFunction(method,obj)); + fns.add(new LuanJavaFunction(method,obj)); } return new AmbiguousJavaFunction(fns); } @@ -182,40 +182,40 @@ } } - public static Static getClass(LuaState lua,String name) throws LuaException { + public static Static getClass(LuanState lua,String name) throws LuanException { try { return new Static( Class.forName(name) ); } catch(ClassNotFoundException e) { - throw new LuaException(lua,LuaElement.JAVA,e); + throw new LuanException(lua,LuanElement.JAVA,e); } } - public static void importClass(LuaState lua,String name) throws LuaException { + public static void importClass(LuanState lua,String name) throws LuanException { lua.global().put( name.substring(name.lastIndexOf('.')+1), getClass(lua,name) ); } - static class AmbiguousJavaFunction extends LuaFunction { - private final Map<Integer,List<LuaJavaFunction>> fnMap = new HashMap<Integer,List<LuaJavaFunction>>(); + static class AmbiguousJavaFunction extends LuanFunction { + private final Map<Integer,List<LuanJavaFunction>> fnMap = new HashMap<Integer,List<LuanJavaFunction>>(); - AmbiguousJavaFunction(List<LuaJavaFunction> fns) { - for( LuaJavaFunction fn : fns ) { + AmbiguousJavaFunction(List<LuanJavaFunction> fns) { + for( LuanJavaFunction fn : fns ) { Integer n = fn.getParameterTypes().length; - List<LuaJavaFunction> list = fnMap.get(n); + List<LuanJavaFunction> list = fnMap.get(n); if( list==null ) { - list = new ArrayList<LuaJavaFunction>(); + list = new ArrayList<LuanJavaFunction>(); fnMap.put(n,list); } list.add(fn); } } - @Override public Object[] call(LuaState lua,Object[] args) throws LuaException { - for( LuaJavaFunction fn : fnMap.get(args.length) ) { + @Override public Object[] call(LuanState lua,Object[] args) throws LuanException { + for( LuanJavaFunction fn : fnMap.get(args.length) ) { try { return fn.call(lua,args); } catch(IllegalArgumentException e) {} } - throw new LuaException(lua,LuaElement.JAVA,"no method matched args"); + throw new LuanException(lua,LuanElement.JAVA,"no method matched args"); } }
--- a/src/luan/lib/LuaRuntimeException.java Thu Dec 27 04:36:44 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -package luan.lib; - -import luan.LuaException; - - -public final class LuaRuntimeException extends RuntimeException { - public LuaRuntimeException(LuaException e) { - super(e); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/lib/LuanRuntimeException.java Fri Dec 28 03:29:12 2012 +0000 @@ -0,0 +1,10 @@ +package luan.lib; + +import luan.LuanException; + + +public final class LuanRuntimeException extends RuntimeException { + public LuanRuntimeException(LuanException e) { + super(e); + } +}
--- a/src/luan/lib/StringLib.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/lib/StringLib.java Fri Dec 28 03:29:12 2012 +0000 @@ -2,27 +2,27 @@ import java.util.regex.Pattern; import java.util.regex.Matcher; -import luan.Lua; -import luan.LuaState; -import luan.LuaTable; -import luan.LuaFunction; -import luan.LuaJavaFunction; -import luan.LuaElement; -import luan.LuaException; +import luan.Luan; +import luan.LuanState; +import luan.LuanTable; +import luan.LuanFunction; +import luan.LuanJavaFunction; +import luan.LuanElement; +import luan.LuanException; public final class StringLib { - public static void register(LuaState lua) { - LuaTable module = new LuaTable(); - LuaTable global = lua.global(); + public static void register(LuanState lua) { + LuanTable module = new LuanTable(); + LuanTable global = lua.global(); global.put("string",module); try { - module.put( "byte", new LuaJavaFunction(StringLib.class.getMethod("byte_",String.class,Integer.class,Integer.class),null) ); - module.put( "char", new LuaJavaFunction(StringLib.class.getMethod("char_",new byte[0].getClass()),null) ); + module.put( "byte", new LuanJavaFunction(StringLib.class.getMethod("byte_",String.class,Integer.class,Integer.class),null) ); + module.put( "char", new LuanJavaFunction(StringLib.class.getMethod("char_",new byte[0].getClass()),null) ); add( module, "find", String.class, String.class, Integer.class, Boolean.class ); add( module, "gmatch", String.class, String.class ); - add( module, "gsub", LuaState.class, String.class, String.class, Object.class, Integer.class ); + add( module, "gsub", LuanState.class, String.class, String.class, Object.class, Integer.class ); add( module, "len", String.class ); add( module, "lower", String.class ); add( module, "match", String.class, String.class, Integer.class ); @@ -35,8 +35,8 @@ } } - private static void add(LuaTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { - t.put( method, new LuaJavaFunction(StringLib.class.getMethod(method,parameterTypes),null) ); + private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { + t.put( method, new LuanJavaFunction(StringLib.class.getMethod(method,parameterTypes),null) ); } static int start(String s,int i) { @@ -126,12 +126,12 @@ return rtn; } - public static LuaFunction gmatch(String s,String pattern) { + public static LuanFunction gmatch(String s,String pattern) { final Matcher m = Pattern.compile(pattern).matcher(s); - return new LuaFunction() { - public Object[] call(LuaState lua,Object[] args) { + return new LuanFunction() { + public Object[] call(LuanState lua,Object[] args) { if( !m.find() ) - return LuaFunction.EMPTY_RTN; + return LuanFunction.EMPTY_RTN; final int n = m.groupCount(); if( n == 0 ) return new String[]{m.group()}; @@ -144,7 +144,7 @@ }; } - public static Object[] gsub(LuaState lua,String s,String pattern,Object repl,Integer n) throws LuaException { + public static Object[] gsub(LuanState lua,String s,String pattern,Object repl,Integer n) throws LuanException { int max = n==null ? Integer.MAX_VALUE : n; final Matcher m = Pattern.compile(pattern).matcher(s); if( repl instanceof String ) { @@ -158,17 +158,17 @@ m.appendTail(sb); return new Object[]{ sb.toString(), i }; } - if( repl instanceof LuaTable ) { - LuaTable t = (LuaTable)repl; + if( repl instanceof LuanTable ) { + LuanTable t = (LuanTable)repl; int i = 0; StringBuffer sb = new StringBuffer(); while( i<max && m.find() ) { String match = m.groupCount()==0 ? m.group() : m.group(0); Object val = t.get(match); - if( Lua.toBoolean(val) ) { - String replacement = Lua.asString(val); + if( Luan.toBoolean(val) ) { + String replacement = Luan.asString(val); if( replacement==null ) - throw new LuaException( lua, LuaElement.JAVA, "invalid replacement value (a "+Lua.type(val)+")" ); + throw new LuanException( lua, LuanElement.JAVA, "invalid replacement value (a "+Luan.type(val)+")" ); m.appendReplacement(sb,replacement); } i++; @@ -176,8 +176,8 @@ m.appendTail(sb); return new Object[]{ sb.toString(), i }; } - if( repl instanceof LuaFunction ) { - LuaFunction fn = (LuaFunction)repl; + if( repl instanceof LuanFunction ) { + LuanFunction fn = (LuanFunction)repl; int i = 0; StringBuffer sb = new StringBuffer(); while( i<max && m.find() ) { @@ -191,11 +191,11 @@ args[j] = m.group(j); } } - Object val = Lua.first( lua.call(fn,LuaElement.JAVA,"repl-arg",args) ); - if( Lua.toBoolean(val) ) { - String replacement = Lua.asString(val); + Object val = Luan.first( lua.call(fn,LuanElement.JAVA,"repl-arg",args) ); + if( Luan.toBoolean(val) ) { + String replacement = Luan.asString(val); if( replacement==null ) - throw new LuaException( lua, LuaElement.JAVA, "invalid replacement value (a "+Lua.type(val)+")" ); + throw new LuanException( lua, LuanElement.JAVA, "invalid replacement value (a "+Luan.type(val)+")" ); m.appendReplacement(sb,replacement); } i++; @@ -203,7 +203,7 @@ m.appendTail(sb); return new Object[]{ sb.toString(), i }; } - throw new LuaException( lua, LuaElement.JAVA, "bad argument #3 to 'gsub' (string/function/table expected)" ); + throw new LuanException( lua, LuanElement.JAVA, "bad argument #3 to 'gsub' (string/function/table expected)" ); } }
--- a/src/luan/lib/TableLib.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/lib/TableLib.java Fri Dec 28 03:29:12 2012 +0000 @@ -3,39 +3,39 @@ import java.util.Comparator; import java.util.ArrayList; import java.util.Arrays; -import luan.Lua; -import luan.LuaState; -import luan.LuaTable; -import luan.LuaFunction; -import luan.LuaJavaFunction; -import luan.LuaElement; -import luan.LuaException; +import luan.Luan; +import luan.LuanState; +import luan.LuanTable; +import luan.LuanFunction; +import luan.LuanJavaFunction; +import luan.LuanElement; +import luan.LuanException; public final class TableLib { - public static void register(LuaState lua) { - LuaTable module = new LuaTable(); - LuaTable global = lua.global(); + public static void register(LuanState lua) { + LuanTable module = new LuanTable(); + LuanTable 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, "concat", LuanState.class, LuanTable.class, String.class, Integer.class, Integer.class ); + add( module, "insert", LuanState.class, LuanTable.class, Integer.TYPE, Object.class ); add( module, "pack", new Object[0].getClass() ); - add( module, "remove", 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 ); + add( module, "remove", LuanState.class, LuanTable.class, Integer.TYPE ); + add( module, "sort", LuanState.class, LuanTable.class, LuanFunction.class ); + add( module, "sub_list", LuanTable.class, Integer.TYPE, Integer.TYPE ); + add( module, "unpack", LuanTable.class ); } catch(NoSuchMethodException e) { throw new RuntimeException(e); } } - private static void add(LuaTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { - t.put( method, new LuaJavaFunction(TableLib.class.getMethod(method,parameterTypes),null) ); + private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { + t.put( method, new LuanJavaFunction(TableLib.class.getMethod(method,parameterTypes),null) ); } - public static String concat(LuaState lua,LuaTable list,String sep,Integer i,Integer j) throws LuaException { + public static String concat(LuanState lua,LuanTable list,String sep,Integer i,Integer j) throws LuanException { int first = i==null ? 1 : i; int last = j==null ? list.length() : j; StringBuilder buf = new StringBuilder(); @@ -45,27 +45,27 @@ break; if( sep!=null && k > first ) buf.append(sep); - String s = Lua.asString(val); + String s = Luan.asString(val); if( s==null ) - throw new LuaException( lua, LuaElement.JAVA, "invalid value ("+Lua.type(val)+") at index "+k+" in table for 'concat'" ); + throw new LuanException( lua, LuanElement.JAVA, "invalid value ("+Luan.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 { + public static void insert(LuanState lua,LuanTable list,int pos,Object value) throws LuanException { try { list.insert(pos,value); } catch(IndexOutOfBoundsException e) { - throw new LuaException( lua, LuaElement.JAVA, e); + throw new LuanException( lua, LuanElement.JAVA, e); } } - public static Object remove(LuaState lua,LuaTable list,int pos) throws LuaException { + public static Object remove(LuanState lua,LuanTable list,int pos) throws LuanException { try { return list.remove(pos); } catch(IndexOutOfBoundsException e) { - throw new LuaException( lua, LuaElement.JAVA, e); + throw new LuanException( lua, LuanElement.JAVA, e); } } @@ -73,15 +73,15 @@ public boolean isLessThan(Object o1,Object o2); } - public static void sort(final LuaState lua,LuaTable list,final LuaFunction comp) throws LuaException { + public static void sort(final LuanState lua,LuanTable list,final LuanFunction comp) throws LuanException { 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); + return lua.isLessThan(LuanElement.JAVA,o1,o2); + } catch(LuanException e) { + throw new LuanRuntimeException(e); } } }; @@ -89,9 +89,9 @@ lt = new LessThan() { public boolean isLessThan(Object o1,Object o2) { try { - return Lua.toBoolean(Lua.first(lua.call(comp,LuaElement.JAVA,"comp-arg",o1,o2))); - } catch(LuaException e) { - throw new LuaRuntimeException(e); + return Luan.toBoolean(Luan.first(lua.call(comp,LuanElement.JAVA,"comp-arg",o1,o2))); + } catch(LuanException e) { + throw new LuanRuntimeException(e); } } }; @@ -102,20 +102,20 @@ return lt.isLessThan(o1,o2) ? -1 : lt.isLessThan(o2,o1) ? 1 : 0; } } ); - } catch(LuaRuntimeException e) { - throw (LuaException)e.getCause(); + } catch(LuanRuntimeException e) { + throw (LuanException)e.getCause(); } } - public static LuaTable pack(Object[] args) { - return new LuaTable(new ArrayList<Object>(Arrays.asList(args))); + public static LuanTable pack(Object[] args) { + return new LuanTable(new ArrayList<Object>(Arrays.asList(args))); } - public static Object[] unpack(LuaTable list) { + public static Object[] unpack(LuanTable list) { return list.listToArray(); } - public static LuaTable sub_list(LuaTable list,int from,int to) { + public static LuanTable sub_list(LuanTable list,int from,int to) { return list.subList(from,to); }
--- a/src/luan/tools/CmdLine.java Thu Dec 27 04:36:44 2012 +0000 +++ b/src/luan/tools/CmdLine.java Fri Dec 28 03:29:12 2012 +0000 @@ -6,18 +6,18 @@ import luan.lib.JavaLib; import luan.lib.StringLib; import luan.lib.TableLib; -import luan.Lua; -import luan.LuaState; -import luan.LuaFunction; -import luan.LuaTable; -import luan.LuaException; -import luan.interp.LuaCompiler; +import luan.Luan; +import luan.LuanState; +import luan.LuanFunction; +import luan.LuanTable; +import luan.LuanException; +import luan.interp.LuanCompiler; public class CmdLine { public static void main(String[] args) { - LuaState lua = LuaCompiler.newLuaState(); + LuanState lua = LuanCompiler.newLuaState(); BasicLib.register(lua); JavaLib.register(lua); StringLib.register(lua); @@ -43,16 +43,16 @@ error("'-e' needs argument"); String cmd = args[i]; try { - LuaFunction fn = BasicLib.load(lua,cmd,"(command line)"); + LuanFunction fn = BasicLib.load(lua,cmd,"(command line)"); lua.call(fn,null,null); - } catch(LuaException e) { + } catch(LuanException e) { System.err.println("command line error: "+e.getMessage()); System.exit(-1); } } else if( arg.equals("-") ) { try { BasicLib.do_file(lua,"stdin"); - } catch(LuaException e) { + } catch(LuanException e) { System.err.println(e.getMessage()); System.exit(-1); } @@ -64,20 +64,20 @@ } } if( showVersion ) - System.out.println(Lua.version); + System.out.println(Luan.version); if( i < args.length ) { String file = args[i++]; Object[] varArgs = new Object[args.length-1]; System.arraycopy(args,1,varArgs,0,varArgs.length); - LuaTable argsTable = new LuaTable(); + LuanTable argsTable = new LuanTable(); for( int j=0; j<args.length; j++ ) { argsTable.put( j, args[j] ); } lua.global().put("arg",argsTable); try { - LuaFunction fn = BasicLib.load_file(lua,file); + LuanFunction fn = BasicLib.load_file(lua,file); lua.call(fn,null,null,varArgs); - } catch(LuaException e) { + } catch(LuanException e) { // System.err.println("error: "+e.getMessage()); e.printStackTrace(); System.exit(-1); @@ -101,16 +101,16 @@ System.exit(-1); } - static void interactive(LuaState lua) { + static void interactive(LuanState lua) { while( true ) { System.out.print("> "); String input = new Scanner(System.in).nextLine(); try { - LuaFunction fn = BasicLib.load(lua,input,"stdin"); + LuanFunction fn = BasicLib.load(lua,input,"stdin"); Object[] rtn = lua.call(fn,null,null); if( rtn.length > 0 ) BasicLib.print(lua,rtn); - } catch(LuaException e) { + } catch(LuanException e) { System.out.println(e.getMessage()); } }