changeset 49:8ede219cd111

add WebShell git-svn-id: https://luan-java.googlecode.com/svn/trunk@50 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Fri, 28 Dec 2012 19:35:04 +0000
parents 64ecb7a3aad7
children 272b6f1d7dac
files src/luan/LuanException.java src/luan/LuanFunction.java src/luan/LuanJavaFunction.java src/luan/LuanState.java src/luan/interp/AddExpr.java src/luan/interp/AndExpr.java src/luan/interp/BinaryOpExpr.java src/luan/interp/Block.java src/luan/interp/BreakStmt.java src/luan/interp/Chunk.java src/luan/interp/Closure.java src/luan/interp/ConcatExpr.java src/luan/interp/ConstExpr.java src/luan/interp/DivExpr.java src/luan/interp/EqExpr.java src/luan/interp/ExpList.java src/luan/interp/Expr.java src/luan/interp/Expressions.java src/luan/interp/ExpressionsExpr.java src/luan/interp/ExpressionsStmt.java src/luan/interp/FnCall.java src/luan/interp/GenericForStmt.java src/luan/interp/GetLocalVar.java src/luan/interp/GetUpVar.java src/luan/interp/IfStmt.java src/luan/interp/IndexExpr.java src/luan/interp/LeExpr.java src/luan/interp/LenExpr.java src/luan/interp/LtExpr.java src/luan/interp/LuanCompiler.java src/luan/interp/LuanParser.java src/luan/interp/LuanStateImpl.java src/luan/interp/ModExpr.java src/luan/interp/MulExpr.java src/luan/interp/NotExpr.java src/luan/interp/NumericForStmt.java src/luan/interp/OrExpr.java src/luan/interp/PowExpr.java src/luan/interp/RepeatStmt.java src/luan/interp/ReturnStmt.java src/luan/interp/SetLocalVar.java src/luan/interp/SetStmt.java src/luan/interp/SetTableEntry.java src/luan/interp/SetUpVar.java src/luan/interp/Settable.java src/luan/interp/Stmt.java src/luan/interp/SubExpr.java src/luan/interp/TableExpr.java src/luan/interp/UnmExpr.java src/luan/interp/UpValue.java src/luan/interp/VarArgs.java src/luan/interp/WhileStmt.java src/luan/lib/BasicLib.java src/luan/lib/HtmlLib.java src/luan/lib/JavaLib.java src/luan/lib/StringLib.java src/luan/lib/TableLib.java src/luan/tools/CmdLine.java src/luan/tools/WebShell.java
diffstat 59 files changed, 445 insertions(+), 291 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/LuanException.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/LuanException.java	Fri Dec 28 19:35:04 2012 +0000
@@ -4,9 +4,9 @@
 public class LuanException extends Exception {
 	private final String stackTrace;
 
-	public LuanException(LuanState lua,LuanElement el,Object msg) {
+	public LuanException(LuanState luan,LuanElement el,Object msg) {
 		super(message(msg),cause(msg));
-		stackTrace = stackTrace(lua,el,msg);
+		stackTrace = stackTrace(luan,el,msg);
 	}
 
 	@Override public String getMessage() {
@@ -35,10 +35,10 @@
 		}
 	}
 
-	private static String stackTrace(LuanState lua,LuanElement el,Object msg) {
+	private static String stackTrace(LuanState luan,LuanElement el,Object msg) {
 		StringBuilder buf = new StringBuilder();
-		for( int i  = lua.stackTrace.size() - 1; i>=0; i-- ) {
-			StackTraceElement stackTraceElement = lua.stackTrace.get(i);
+		for( int i  = luan.stackTrace.size() - 1; i>=0; i-- ) {
+			StackTraceElement stackTraceElement = luan.stackTrace.get(i);
 			buf.append( "\n\t" ).append( el.toString(stackTraceElement.fnName) );
 			el = stackTraceElement.call;
 		}
--- a/src/luan/LuanFunction.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/LuanFunction.java	Fri Dec 28 19:35:04 2012 +0000
@@ -3,7 +3,7 @@
 
 public abstract class LuanFunction {
 
-	public abstract Object[] call(LuanState lua,Object[] args) throws LuanException;
+	public abstract Object[] call(LuanState luan,Object[] args) throws LuanException;
 
 	public static final Object[] EMPTY_RTN = new Object[0];
 
--- a/src/luan/LuanJavaFunction.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/LuanJavaFunction.java	Fri Dec 28 19:35:04 2012 +0000
@@ -43,13 +43,13 @@
 		return method.getParameterTypes();
 	}
 
-	@Override public Object[] call(LuanState lua,Object[] args) throws LuanException {
-		args = fixArgs(lua,args);
+	@Override public Object[] call(LuanState luan,Object[] args) throws LuanException {
+		args = fixArgs(luan,args);
 		Object rtn;
 		try {
 			rtn = method.invoke(obj,args);
 		} catch(IllegalArgumentException e) {
-			checkArgs(lua,args);
+			checkArgs(luan,args);
 			throw e;
 		} catch(IllegalAccessException e) {
 			throw new RuntimeException(e);
@@ -68,7 +68,7 @@
 		return rtnConverter.convert(rtn);
 	}
 
-	private void checkArgs(LuanState lua,Object[] args) throws LuanException {
+	private void checkArgs(LuanState luan,Object[] args) throws LuanException {
 		Class<?>[] a = getParameterTypes();
 		for( int i=0; i<a.length; i++ ) {
 			if( !a[i].isInstance(args[i]) ) {
@@ -76,12 +76,12 @@
 				String expected = a[i].getName();
 				if( !takesLuaState )
 					i++;
-				throw new LuanException(lua,LuanElement.JAVA,"bad argument #"+i+" ("+expected+" expected, got "+got+")");
+				throw new LuanException(luan,LuanElement.JAVA,"bad argument #"+i+" ("+expected+" expected, got "+got+")");
 			}
 		}
 	}
 
-	private Object[] fixArgs(LuanState lua,Object[] args) {
+	private Object[] fixArgs(LuanState luan,Object[] args) {
 		int n = argConverters.length;
 		Object[] rtn;
 		int start = 0;
@@ -92,7 +92,7 @@
 				n++;
 			rtn = new Object[n];
 			if( takesLuaState ) {
-				rtn[start++] = lua;
+				rtn[start++] = luan;
 			}
 			n = argConverters.length;
 			if( varArgCls != null ) {
--- a/src/luan/LuanState.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/LuanState.java	Fri Dec 28 19:35:04 2012 +0000
@@ -1,5 +1,7 @@
 package luan;
 
+import java.io.InputStream;
+import java.io.PrintStream;
 import java.util.List;
 import java.util.ArrayList;
 
@@ -9,6 +11,10 @@
 	private final List<MetatableGetter> mtGetters = new ArrayList<MetatableGetter>();
 	final List<StackTraceElement> stackTrace = new ArrayList<StackTraceElement>();
 
+	public InputStream in = System.in;
+	public PrintStream out = System.out;
+	public PrintStream err = System.err;
+
 	public final LuanTable global() {
 		return global;
 	}
--- a/src/luan/interp/AddExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/AddExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,13 +11,13 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o1 = op1.eval(lua);
-		Object o2 = op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
 		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);
+		return arithmetic(luan,"__add",o1,o2);
 	}
 }
--- a/src/luan/interp/AndExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/AndExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,8 +11,8 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object v1 = op1.eval(lua);
-		return !Luan.toBoolean(v1) ? v1 : op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object v1 = op1.eval(luan);
+		return !Luan.toBoolean(v1) ? v1 : op2.eval(luan);
 	}
 }
--- a/src/luan/interp/BinaryOpExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/BinaryOpExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -17,8 +17,8 @@
 		this.op2 = op2;
 	}
 
-	Object arithmetic(LuanStateImpl lua,String op,Object o1,Object o2) throws LuanException {
-		return lua.arithmetic(se(),"__mod",o1,o2);
+	Object arithmetic(LuanStateImpl luan,String op,Object o1,Object o2) throws LuanException {
+		return luan.arithmetic(se(),"__mod",o1,o2);
 	}
 
 }
--- a/src/luan/interp/Block.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/Block.java	Fri Dec 28 19:35:04 2012 +0000
@@ -16,13 +16,13 @@
 		this.stackEnd = stackEnd;
 	}
 
-	@Override public void eval(LuanStateImpl lua) throws LuanException {
+	@Override public void eval(LuanStateImpl luan) throws LuanException {
 		try {
 			for( Stmt stmt : stmts ) {
-				stmt.eval(lua);
+				stmt.eval(luan);
 			}
 		} finally {
-			lua.stackClear(stackStart,stackEnd);
+			luan.stackClear(stackStart,stackEnd);
 		}
 	}
 
--- a/src/luan/interp/BreakStmt.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/BreakStmt.java	Fri Dec 28 19:35:04 2012 +0000
@@ -3,7 +3,7 @@
 
 final class BreakStmt implements Stmt {
 
-	@Override public void eval(LuanStateImpl lua) {
+	@Override public void eval(LuanStateImpl luan) {
 		throw new BreakException();
 	}
 }
--- a/src/luan/interp/Chunk.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/Chunk.java	Fri Dec 28 19:35:04 2012 +0000
@@ -35,12 +35,8 @@
 		}
 	}
 
-	Closure newClosure(LuanStateImpl lua) {
-		return new Closure(this,lua);
-	}
-
-	@Override public Object eval(LuanStateImpl lua) {
-		return newClosure(lua);
+	@Override public Object eval(LuanStateImpl luan) {
+		return new Closure(luan,this);
 	}
 
 }
--- a/src/luan/interp/Closure.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/Closure.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,7 +11,7 @@
 	final UpValue[] upValues;
 	private final static UpValue[] NO_UP_VALUES = new UpValue[0];
 
-	Closure(Chunk chunk,LuanStateImpl lua) {
+	Closure(LuanStateImpl luan,Chunk chunk) {
 		this.chunk = chunk;
 		UpValue.Getter[] upValueGetters = chunk.upValueGetters;
 		if( upValueGetters.length==0 ) {
@@ -19,16 +19,16 @@
 		} else {
 			upValues = new UpValue[upValueGetters.length];
 			for( int i=0; i<upValues.length; i++ ) {
-				upValues[i] = upValueGetters[i].get(lua);
+				upValues[i] = upValueGetters[i].get(luan);
 			}
 		}
 	}
 
-	public Object[] call(LuanState lua,Object[] args) throws LuanException {
-		return call(this,(LuanStateImpl)lua,args);
+	public Object[] call(LuanState luan,Object[] args) throws LuanException {
+		return call(this,(LuanStateImpl)luan,args);
 	}
 
-	private static Object[] call(Closure closure,LuanStateImpl lua,Object[] args) throws LuanException {
+	private static Object[] call(Closure closure,LuanStateImpl luan,Object[] args) throws LuanException {
 		while(true) {
 			Chunk chunk = closure.chunk;
 			Object[] varArgs = null;
@@ -42,7 +42,7 @@
 					varArgs = LuanFunction.EMPTY_RTN;
 				}
 			}
-			Object[] stack = lua.newFrame(closure,chunk.stackSize,varArgs);
+			Object[] stack = luan.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];
@@ -50,12 +50,12 @@
 			Object[] returnValues;
 			Closure tailFn;
 			try {
-				chunk.block.eval(lua);
+				chunk.block.eval(luan);
 			} catch(ReturnException e) {
 			} finally {
-				returnValues = lua.returnValues;
-				closure = lua.tailFn;
-				lua.popFrame();
+				returnValues = luan.returnValues;
+				closure = luan.tailFn;
+				luan.popFrame();
 			}
 			if( closure == null )
 				return returnValues;
--- a/src/luan/interp/ConcatExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/ConcatExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -12,17 +12,17 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o1 = op1.eval(lua);
-		Object o2 = op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
 		String s1 = Luan.asString(o1);
 		String s2 = Luan.asString(o2);
 		if( s1 != null && s2 != null )
 			return s1 + s2;
-		LuanFunction fn = lua.getBinHandler(se,"__concat",o1,o2);
+		LuanFunction fn = luan.getBinHandler(se,"__concat",o1,o2);
 		if( fn != null )
-			return Luan.first(lua.call(fn,se,"__concat",o1,o2));
+			return Luan.first(luan.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" );
+		throw new LuanException( luan, se, "attempt to concatenate a " + type + " value" );
 	}
 }
--- a/src/luan/interp/ConstExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/ConstExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -10,7 +10,7 @@
 		this.obj = obj;
 	}
 
-	@Override public Object eval(LuanStateImpl lua) {
+	@Override public Object eval(LuanStateImpl luan) {
 		return obj;
 	}
 
--- a/src/luan/interp/DivExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/DivExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,13 +11,13 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o1 = op1.eval(lua);
-		Object o2 = op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
 		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);
+		return arithmetic(luan,"__div",o1,o2);
 	}
 }
--- a/src/luan/interp/EqExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/EqExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -13,9 +13,9 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o1 = op1.eval(lua);
-		Object o2 = op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
 		if( o1 == o2 || o1 != null && o1.equals(o2) )
 			return true;
 		if( o1 instanceof Number && o2 instanceof Number ) {
@@ -25,14 +25,14 @@
 		}
 		if( !o1.getClass().equals(o2.getClass()) )
 			return false;
-		LuanTable mt1 = lua.getMetatable(o1);
-		LuanTable mt2 = lua.getMetatable(o2);
+		LuanTable mt1 = luan.getMetatable(o1);
+		LuanTable mt2 = luan.getMetatable(o2);
 		if( mt1==null || mt2==null )
 			return false;
 		Object f = mt1.get("__eq");
 		if( f == null || !f.equals(mt2.get("__eq")) )
 			return null;
-		LuanFunction fn = lua.checkFunction(se,f);
-		return Luan.toBoolean( Luan.first(lua.call(fn,se,"__eq",o1,o2)) );
+		LuanFunction fn = luan.checkFunction(se,f);
+		return Luan.toBoolean( Luan.first(luan.call(fn,se,"__eq",o1,o2)) );
 	}
 }
--- a/src/luan/interp/ExpList.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/ExpList.java	Fri Dec 28 19:35:04 2012 +0000
@@ -10,7 +10,7 @@
 final class ExpList implements Expressions {
 
 	private interface Adder {
-		public void addTo(LuanStateImpl lua,List<Object> list) throws LuanException;
+		public void addTo(LuanStateImpl luan,List<Object> list) throws LuanException;
 		public Code code();
 	}
 
@@ -21,8 +21,8 @@
 			this.expr = expr;
 		}
 
-		public void addTo(LuanStateImpl lua,List<Object> list) throws LuanException {
-			list.add( expr.eval(lua) );
+		public void addTo(LuanStateImpl luan,List<Object> list) throws LuanException {
+			list.add( expr.eval(luan) );
 		}
 
 		public Code code() {
@@ -38,8 +38,8 @@
 			this.expressions = expressions;
 		}
 
-		public void addTo(LuanStateImpl lua,List<Object> list) throws LuanException {
-			for( Object val : expressions.eval(lua) ) {
+		public void addTo(LuanStateImpl luan,List<Object> list) throws LuanException {
+			for( Object val : expressions.eval(luan) ) {
 				list.add( val );
 			}
 		}
@@ -81,7 +81,7 @@
 
 	static final Expressions emptyExpList = new Expressions() {
 
-		@Override public Object[] eval(LuanStateImpl lua) {
+		@Override public Object[] eval(LuanStateImpl luan) {
 			return EMPTY;
 		}
 
@@ -97,8 +97,8 @@
 			this.expr = expr;
 		}
 
-		@Override public Object[] eval(LuanStateImpl lua) throws LuanException {
-			return new Object[]{expr.eval(lua)};
+		@Override public Object[] eval(LuanStateImpl luan) throws LuanException {
+			return new Object[]{expr.eval(luan)};
 		}
 
 		@Override public LuanSource.Element se() {
@@ -112,10 +112,10 @@
 		this.adders = adders;
 	}
 
-	@Override public Object[] eval(LuanStateImpl lua) throws LuanException {
+	@Override public Object[] eval(LuanStateImpl luan) throws LuanException {
 		List<Object> list = new ArrayList<Object>();
 		for( Adder adder : adders ) {
-			adder.addTo(lua,list);
+			adder.addTo(luan,list);
 		}
 		return list.toArray();
 	}
--- a/src/luan/interp/Expr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/Expr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -4,5 +4,5 @@
 
 
 interface Expr extends Code {
-	public Object eval(LuanStateImpl lua) throws LuanException;
+	public Object eval(LuanStateImpl luan) throws LuanException;
 }
--- a/src/luan/interp/Expressions.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/Expressions.java	Fri Dec 28 19:35:04 2012 +0000
@@ -4,5 +4,5 @@
 
 
 interface Expressions extends Code {
-	public Object[] eval(LuanStateImpl lua) throws LuanException;
+	public Object[] eval(LuanStateImpl luan) throws LuanException;
 }
--- a/src/luan/interp/ExpressionsExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/ExpressionsExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -13,8 +13,8 @@
 		this.expressions = expressions;
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		return Luan.first( expressions.eval(lua) );
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		return Luan.first( expressions.eval(luan) );
 	}
 
 	public LuanSource.Element se() {
--- a/src/luan/interp/ExpressionsStmt.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/ExpressionsStmt.java	Fri Dec 28 19:35:04 2012 +0000
@@ -10,8 +10,8 @@
 		this.expressions = expressions;
 	}
 
-	@Override public void eval(LuanStateImpl lua) throws LuanException {
-		expressions.eval(lua);
+	@Override public void eval(LuanStateImpl luan) throws LuanException {
+		expressions.eval(luan);
 	}
 
 }
--- a/src/luan/interp/FnCall.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/FnCall.java	Fri Dec 28 19:35:04 2012 +0000
@@ -18,18 +18,18 @@
 		this.fnName = fnExpr.se().text();
 	}
 
-	@Override public Object[] eval(LuanStateImpl lua) throws LuanException {
-		return call( lua, fnExpr.eval(lua) );
+	@Override public Object[] eval(LuanStateImpl luan) throws LuanException {
+		return call( luan, fnExpr.eval(luan) );
 	}
 
-	private Object[] call(LuanStateImpl lua,Object o) throws LuanException {
+	private Object[] call(LuanStateImpl luan,Object o) throws LuanException {
 		if( o instanceof LuanFunction ) {
 			LuanFunction fn = (LuanFunction)o;
-			return lua.call( fn, se, fnName, args.eval(lua) );
+			return luan.call( fn, se, fnName, args.eval(luan) );
 		}
-		Object h = lua.getHandler("__call",o);
+		Object h = luan.getHandler("__call",o);
 		if( h != null )
-			return call(lua,h);
-		throw new LuanException( lua, se, "attempt to call a " + Luan.type(o) + " value" );
+			return call(luan,h);
+		throw new LuanException( luan, se, "attempt to call a " + Luan.type(o) + " value" );
 	}
 }
--- a/src/luan/interp/GenericForStmt.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/GenericForStmt.java	Fri Dec 28 19:35:04 2012 +0000
@@ -20,21 +20,21 @@
 		this.block = block;
 	}
 
-	@Override public void eval(LuanStateImpl lua) throws LuanException {
-		LuanFunction iter = lua.checkFunction( se, iterExpr.eval(lua) );
+	@Override public void eval(LuanStateImpl luan) throws LuanException {
+		LuanFunction iter = luan.checkFunction( se, iterExpr.eval(luan) );
 		try {
 			while(true) {
-				Object[] vals = lua.call(iter,iterExpr.se(),iterExpr.se().text());
+				Object[] vals = luan.call(iter,iterExpr.se(),iterExpr.se().text());
 				if( vals.length==0 || vals[0]==null )
 					break;
 				for( int i=0; i<nVars; i++ ) {
-					lua.stackSet( iVars+i, i < vals.length ? vals[i] : null );
+					luan.stackSet( iVars+i, i < vals.length ? vals[i] : null );
 				}
-				block.eval(lua);
+				block.eval(luan);
 			}
 		} catch(BreakException e) {
 		} finally {
-			lua.stackClear(iVars,iVars+nVars);
+			luan.stackClear(iVars,iVars+nVars);
 		}
 	}
 
--- a/src/luan/interp/GetLocalVar.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/GetLocalVar.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,7 +11,7 @@
 		this.index = index;
 	}
 
-	@Override public Object eval(LuanStateImpl lua) {
-		return lua.stackGet(index);
+	@Override public Object eval(LuanStateImpl luan) {
+		return luan.stackGet(index);
 	}
 }
--- a/src/luan/interp/GetUpVar.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/GetUpVar.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,7 +11,7 @@
 		this.index = index;
 	}
 
-	@Override public Object eval(LuanStateImpl lua) {
-		return lua.closure().upValues[index].get();
+	@Override public Object eval(LuanStateImpl luan) {
+		return luan.closure().upValues[index].get();
 	}
 }
--- a/src/luan/interp/IfStmt.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/IfStmt.java	Fri Dec 28 19:35:04 2012 +0000
@@ -15,11 +15,11 @@
 		this.elseStmt = elseStmt;
 	}
 
-	@Override public void eval(LuanStateImpl lua) throws LuanException {
-		if( Luan.toBoolean( cnd.eval(lua) ) ) {
-			thenStmt.eval(lua);
+	@Override public void eval(LuanStateImpl luan) throws LuanException {
+		if( Luan.toBoolean( cnd.eval(luan) ) ) {
+			thenStmt.eval(luan);
 		} else {
-			elseStmt.eval(lua);
+			elseStmt.eval(luan);
 		}
 	}
 }
--- a/src/luan/interp/IndexExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/IndexExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -13,29 +13,29 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		return index(lua,op1.eval(lua),op2.eval(lua));
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		return index(luan,op1.eval(luan),op2.eval(luan));
 	}
 
-	private Object index(LuanStateImpl lua,Object t,Object key) throws LuanException {
+	private Object index(LuanStateImpl luan,Object t,Object key) throws LuanException {
 		Object h;
 		if( t instanceof LuanTable ) {
 			LuanTable tbl = (LuanTable)t;
 			Object value = tbl.get(key);
 			if( value != null )
 				return value;
-			h = lua.getHandler("__index",t);
+			h = luan.getHandler("__index",t);
 			if( h==null )
 				return null;
 		} else {
-			h = lua.getHandler("__index",t);
+			h = luan.getHandler("__index",t);
 			if( h==null )
-				throw new LuanException( lua, se, "attempt to index a " + Luan.type(t) + " value" );
+				throw new LuanException( luan, se, "attempt to index a " + Luan.type(t) + " value" );
 		}
 		if( h instanceof LuanFunction ) {
 			LuanFunction fn = (LuanFunction)h;
-			return Luan.first(lua.call(fn,se,"__index",t,key));
+			return Luan.first(luan.call(fn,se,"__index",t,key));
 		}
-		return index(lua,h,key);
+		return index(luan,h,key);
 	}
 }
--- a/src/luan/interp/LeExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/LeExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -12,9 +12,9 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o1 = op1.eval(lua);
-		Object o2 = op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
 		if( o1 instanceof Number && o2 instanceof Number ) {
 			Number n1 = (Number)o1;
 			Number n2 = (Number)o2;
@@ -25,12 +25,12 @@
 			String s2 = (String)o2;
 			return s1.compareTo(s2) <= 0;
 		}
-		LuanFunction fn = lua.getBinHandler(se,"__le",o1,o2);
+		LuanFunction fn = luan.getBinHandler(se,"__le",o1,o2);
 		if( fn != null )
-			return Luan.toBoolean( Luan.first(lua.call(fn,se,"__le",o1,o2)) );
-		fn = lua.getBinHandler(se,"__lt",o1,o2);
+			return Luan.toBoolean( Luan.first(luan.call(fn,se,"__le",o1,o2)) );
+		fn = luan.getBinHandler(se,"__lt",o1,o2);
 		if( fn != null )
-			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) );
+			return !Luan.toBoolean( Luan.first(luan.call(fn,se,"__lt",o2,o1)) );
+		throw new LuanException( luan, se, "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
 	}
 }
--- a/src/luan/interp/LenExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/LenExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -13,19 +13,19 @@
 		super(se,op);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o = op.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o = op.eval(luan);
 		if( o instanceof String ) {
 			String s = (String)o;
 			return s.length();
 		}
-		LuanFunction fn = lua.getHandlerFunction(se,"__len",o);
+		LuanFunction fn = luan.getHandlerFunction(se,"__len",o);
 		if( fn != null )
-			return Luan.first(lua.call(fn,se,"__len",o));
+			return Luan.first(luan.call(fn,se,"__len",o));
 		if( o instanceof LuanTable ) {
 			LuanTable t = (LuanTable)o;
 			return t.length();
 		}
-		throw new LuanException( lua, se, "attempt to get length of a " + Luan.type(o) + " value" );
+		throw new LuanException( luan, se, "attempt to get length of a " + Luan.type(o) + " value" );
 	}
 }
--- a/src/luan/interp/LtExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/LtExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -12,9 +12,9 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o1 = op1.eval(lua);
-		Object o2 = op2.eval(lua);
-		return lua.isLessThan(se,o1,o2);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
+		return luan.isLessThan(se,o1,o2);
 	}
 }
--- a/src/luan/interp/LuanCompiler.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/LuanCompiler.java	Fri Dec 28 19:35:04 2012 +0000
@@ -15,27 +15,18 @@
 public final class LuanCompiler {
 	private LuanCompiler() {}  // never
 
-	public static LuanFunction compile(LuanState lua,LuanSource src) throws LuanException {
+	public static LuanFunction compile(LuanState luan,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);
+			throw new LuanException( luan, null, ErrorUtils.printParseErrors(result) );
+		Chunk chunk = (Chunk)result.resultValue;
+		return new Closure((LuanStateImpl)luan,chunk);
 	}
 
-	public static LuanState newLuaState() {
+	public static LuanState newLuanState() {
 		return new LuanStateImpl();
 	}
 }
--- a/src/luan/interp/LuanParser.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/LuanParser.java	Fri Dec 28 19:35:04 2012 +0000
@@ -158,16 +158,20 @@
 		Var<Integer> start = new Var<Integer>();
 		return Sequence(
 			Spaces(),
+			start.set(currentIndex()),
 			FirstOf(
-				Sequence( ExpList(), EOI ),
 				Sequence(
-					start.set(currentIndex()),
+					ExpList(),
+					EOI,
+					push( new ReturnStmt( se(start.get()), (Expressions)pop() ) )
+				),
+				Sequence(
 					action( frame.isVarArg = true ),
 					Block(),
-					EOI,
-					push( newChunk(start.get()) )
+					EOI
 				)
-			)
+			),
+			push( newChunk(start.get()) )
 		);
 	}
 
--- a/src/luan/interp/LuanStateImpl.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/LuanStateImpl.java	Fri Dec 28 19:35:04 2012 +0000
@@ -61,7 +61,7 @@
 	}
 
 	private Frame frame = null;
-	Object[] returnValues;
+	Object[] returnValues = LuanFunction.EMPTY_RTN;
 	Closure tailFn;
 
 	// returns stack
--- a/src/luan/interp/ModExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/ModExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,13 +11,13 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o1 = op1.eval(lua);
-		Object o2 = op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
 		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);
+		return arithmetic(luan,"__mod",o1,o2);
 	}
 }
--- a/src/luan/interp/MulExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/MulExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,13 +11,13 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o1 = op1.eval(lua);
-		Object o2 = op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
 		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);
+		return arithmetic(luan,"__mul",o1,o2);
 	}
 }
--- a/src/luan/interp/NotExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/NotExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,7 +11,7 @@
 		super(se,op);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		return !Luan.toBoolean(op.eval(lua));
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		return !Luan.toBoolean(op.eval(luan));
 	}
 }
--- a/src/luan/interp/NumericForStmt.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/NumericForStmt.java	Fri Dec 28 19:35:04 2012 +0000
@@ -21,19 +21,19 @@
 		this.block = block;
 	}
 
-	@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();
+	@Override public void eval(LuanStateImpl luan) throws LuanException {
+		double v = luan.checkNumber( se, fromExpr.eval(luan) ).doubleValue();
+		double limit = luan.checkNumber( se, toExpr.eval(luan) ).doubleValue();
+		double step = luan.checkNumber( se, stepExpr.eval(luan) ).doubleValue();
 		try {
 			while( step > 0.0 && v <= limit || step < 0.0 && v >= limit ) {
-				lua.stackSet( iVar, v );
-				block.eval(lua);
+				luan.stackSet( iVar, v );
+				block.eval(luan);
 				v += step;
 			}
 		} catch(BreakException e) {
 		} finally {
-			lua.stackClear(iVar,iVar+1);
+			luan.stackClear(iVar,iVar+1);
 		}
 	}
 
--- a/src/luan/interp/OrExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/OrExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,8 +11,8 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object v1 = op1.eval(lua);
-		return Luan.toBoolean(v1) ? v1 : op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object v1 = op1.eval(luan);
+		return Luan.toBoolean(v1) ? v1 : op2.eval(luan);
 	}
 }
--- a/src/luan/interp/PowExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/PowExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,13 +11,13 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o1 = op1.eval(lua);
-		Object o2 = op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
 		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);
+		return arithmetic(luan,"__pow",o1,o2);
 	}
 }
--- a/src/luan/interp/RepeatStmt.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/RepeatStmt.java	Fri Dec 28 19:35:04 2012 +0000
@@ -13,11 +13,11 @@
 		this.cnd = cnd;
 	}
 
-	@Override public void eval(LuanStateImpl lua) throws LuanException {
+	@Override public void eval(LuanStateImpl luan) throws LuanException {
 		try {
 			do {
-				doStmt.eval(lua);
-			} while( !Luan.toBoolean( cnd.eval(lua) ) );
+				doStmt.eval(luan);
+			} while( !Luan.toBoolean( cnd.eval(luan) ) );
 		} catch(BreakException e) {}
 	}
 }
--- a/src/luan/interp/ReturnStmt.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/ReturnStmt.java	Fri Dec 28 19:35:04 2012 +0000
@@ -23,14 +23,14 @@
 		}
 	}
 
-	@Override public void eval(LuanStateImpl lua) throws LuanException {
-		lua.returnValues = expressions.eval(lua);
+	@Override public void eval(LuanStateImpl luan) throws LuanException {
+		luan.returnValues = expressions.eval(luan);
 		if( tailFnExpr != null ) {
-			LuanFunction tailFn = lua.checkFunction( se, tailFnExpr.eval(lua) );
+			LuanFunction tailFn = luan.checkFunction( se, tailFnExpr.eval(luan) );
 			if( tailFn instanceof Closure ) {
-				lua.tailFn = (Closure)tailFn;
+				luan.tailFn = (Closure)tailFn;
 			} else {
-				lua.returnValues =  lua.call(tailFn,tailFnExpr.se(),tailFnExpr.se().text(),lua.returnValues);
+				luan.returnValues =  luan.call(tailFn,tailFnExpr.se(),tailFnExpr.se().text(),luan.returnValues);
 			}
 		}
 		if( throwReturnException )
--- a/src/luan/interp/SetLocalVar.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/SetLocalVar.java	Fri Dec 28 19:35:04 2012 +0000
@@ -8,7 +8,7 @@
 		this.index = index;
 	}
 
-	@Override public void set(LuanStateImpl lua,Object value) {
-		lua.stackSet( index, value );
+	@Override public void set(LuanStateImpl luan,Object value) {
+		luan.stackSet( index, value );
 	}
 }
--- a/src/luan/interp/SetStmt.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/SetStmt.java	Fri Dec 28 19:35:04 2012 +0000
@@ -17,11 +17,11 @@
 		this.expressions = expressions;
 	}
 
-	@Override public void eval(LuanStateImpl lua) throws LuanException {
-		final Object[] vals = expressions.eval(lua);
+	@Override public void eval(LuanStateImpl luan) throws LuanException {
+		final Object[] vals = expressions.eval(luan);
 		for( int i=0; i<vars.length; i++ ) {
 			Object val = i < vals.length ? vals[i] : null;
-			vars[i].set(lua,val);
+			vars[i].set(luan,val);
 		}
 	}
 
--- a/src/luan/interp/SetTableEntry.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/SetTableEntry.java	Fri Dec 28 19:35:04 2012 +0000
@@ -17,31 +17,31 @@
 		this.keyExpr = keyExpr;
 	}
 
-	@Override public void set(LuanStateImpl lua,Object value) throws LuanException {
-		newindex( lua, tableExpr.eval(lua), keyExpr.eval(lua), value );
+	@Override public void set(LuanStateImpl luan,Object value) throws LuanException {
+		newindex( luan, tableExpr.eval(luan), keyExpr.eval(luan), value );
 	}
 
-	private void newindex(LuanStateImpl lua,Object t,Object key,Object value) throws LuanException {
+	private void newindex(LuanStateImpl luan,Object t,Object key,Object value) throws LuanException {
 		Object h;
 		if( t instanceof LuanTable ) {
 			LuanTable table = (LuanTable)t;
 			Object old = table.put(key,value);
 			if( old != null )
 				return;
-			h = lua.getHandler("__newindex",t);
+			h = luan.getHandler("__newindex",t);
 			if( h==null )
 				return;
 			table.put(key,old);
 		} else {
-			h = lua.getHandler("__newindex",t);
+			h = luan.getHandler("__newindex",t);
 			if( h==null )
-				throw new LuanException( lua, se, "attempt to index a " + Luan.type(t) + " value" );
+				throw new LuanException( luan, se, "attempt to index a " + Luan.type(t) + " value" );
 		}
 		if( h instanceof LuanFunction ) {
 			LuanFunction fn = (LuanFunction)h;
-			lua.call(fn,se,"__newindex",t,key,value);
+			luan.call(fn,se,"__newindex",t,key,value);
 		}
-		newindex(lua,h,key,value);
+		newindex(luan,h,key,value);
 	}
 
 }
--- a/src/luan/interp/SetUpVar.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/SetUpVar.java	Fri Dec 28 19:35:04 2012 +0000
@@ -8,7 +8,7 @@
 		this.index = index;
 	}
 
-	@Override public void set(LuanStateImpl lua,Object value) {
-		lua.closure().upValues[index].set(value);
+	@Override public void set(LuanStateImpl luan,Object value) {
+		luan.closure().upValues[index].set(value);
 	}
 }
--- a/src/luan/interp/Settable.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/Settable.java	Fri Dec 28 19:35:04 2012 +0000
@@ -4,5 +4,5 @@
 
 
 interface Settable {
-	public void set(LuanStateImpl lua,Object value) throws LuanException;
+	public void set(LuanStateImpl luan,Object value) throws LuanException;
 }
--- a/src/luan/interp/Stmt.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/Stmt.java	Fri Dec 28 19:35:04 2012 +0000
@@ -4,9 +4,9 @@
 
 
 interface Stmt {
-	public void eval(LuanStateImpl lua) throws LuanException;
+	public void eval(LuanStateImpl luan) throws LuanException;
 
 	static final Stmt EMPTY = new Stmt() {
-		@Override public void eval(LuanStateImpl lua) {}
+		@Override public void eval(LuanStateImpl luan) {}
 	};
 }
--- a/src/luan/interp/SubExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/SubExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -11,13 +11,13 @@
 		super(se,op1,op2);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o1 = op1.eval(lua);
-		Object o2 = op2.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
 		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);
+		return arithmetic(luan,"__sub",o1,o2);
 	}
 }
--- a/src/luan/interp/TableExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/TableExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -26,12 +26,12 @@
 		this.expressions = expressions;
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
 		LuanTable table = new LuanTable();
 		for( Field field : fields ) {
-			table.put( field.key.eval(lua), field.value.eval(lua) );
+			table.put( field.key.eval(luan), field.value.eval(luan) );
 		}
-		Object[] a = expressions.eval(lua);
+		Object[] a = expressions.eval(luan);
 		for( int i=0; i<a.length; i++ ) {
 			table.put( i+1, a[i] );
 		}
--- a/src/luan/interp/UnmExpr.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/UnmExpr.java	Fri Dec 28 19:35:04 2012 +0000
@@ -13,15 +13,15 @@
 		super(se,op);
 	}
 
-	@Override public Object eval(LuanStateImpl lua) throws LuanException {
-		Object o = op.eval(lua);
+	@Override public Object eval(LuanStateImpl luan) throws LuanException {
+		Object o = op.eval(luan);
 		Number n = Luan.toNumber(o);
 		if( n != null )
 			return -n.doubleValue();
-		LuanFunction fn = lua.getHandlerFunction(se,"__unm",o);
+		LuanFunction fn = luan.getHandlerFunction(se,"__unm",o);
 		if( fn != null ) {
-			return Luan.first(lua.call(fn,se,"__unm",o));
+			return Luan.first(luan.call(fn,se,"__unm",o));
 		}
-		throw new LuanException(lua,se,"attempt to perform arithmetic on a "+Luan.type(o)+" value");
+		throw new LuanException(luan,se,"attempt to perform arithmetic on a "+Luan.type(o)+" value");
 	}
 }
--- a/src/luan/interp/UpValue.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/UpValue.java	Fri Dec 28 19:35:04 2012 +0000
@@ -36,7 +36,7 @@
 	}
 
 	static interface Getter {
-		public UpValue get(LuanStateImpl lua);
+		public UpValue get(LuanStateImpl luan);
 	}
 
 	static final class StackGetter implements Getter {
@@ -46,8 +46,8 @@
 			this.index = index;
 		}
 
-		public UpValue get(LuanStateImpl lua) {
-			return lua.getUpValue(index);
+		public UpValue get(LuanStateImpl luan) {
+			return luan.getUpValue(index);
 		}
 	}
 
@@ -58,14 +58,14 @@
 			this.index = index;
 		}
 
-		public UpValue get(LuanStateImpl lua) {
-			return lua.closure().upValues[index];
+		public UpValue get(LuanStateImpl luan) {
+			return luan.closure().upValues[index];
 		}
 	}
 
 	static final Getter globalGetter = new Getter() {
-		public UpValue get(LuanStateImpl lua) {
-			return new UpValue(lua.global());
+		public UpValue get(LuanStateImpl luan) {
+			return new UpValue(luan.global());
 		}
 	};
 
--- a/src/luan/interp/VarArgs.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/VarArgs.java	Fri Dec 28 19:35:04 2012 +0000
@@ -9,7 +9,7 @@
 		super(se);
 	}
 
-	@Override public Object[] eval(LuanStateImpl lua) {
-		return lua.varArgs();
+	@Override public Object[] eval(LuanStateImpl luan) {
+		return luan.varArgs();
 	}
 }
--- a/src/luan/interp/WhileStmt.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/interp/WhileStmt.java	Fri Dec 28 19:35:04 2012 +0000
@@ -13,10 +13,10 @@
 		this.doStmt = doStmt;
 	}
 
-	@Override public void eval(LuanStateImpl lua) throws LuanException {
+	@Override public void eval(LuanStateImpl luan) throws LuanException {
 		try {
-			while( Luan.toBoolean( cnd.eval(lua) ) ) {
-				doStmt.eval(lua);
+			while( Luan.toBoolean( cnd.eval(luan) ) ) {
+				doStmt.eval(luan);
 			}
 		} catch(BreakException e) {}
 	}
--- a/src/luan/lib/BasicLib.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/lib/BasicLib.java	Fri Dec 28 19:35:04 2012 +0000
@@ -21,8 +21,8 @@
 
 public final class BasicLib {
 
-	public static void register(LuanState lua) {
-		LuanTable global = lua.global();
+	public static void register(LuanState luan) {
+		LuanTable global = luan.global();
 		global.put( "_G", global );
 		add( global, "do_file", LuanState.class, String.class );
 		add( global, "error", LuanState.class, Object.class );
@@ -53,8 +53,8 @@
 		}
 	}
 
-	public static void make_standard(LuanState lua) {
-		LuanTable global = lua.global();
+	public static void make_standard(LuanState luan) {
+		LuanTable global = luan.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(LuanState lua,Object... args) throws LuanException {
+	public static void print(LuanState luan,Object... args) throws LuanException {
 		for( int i=0; i<args.length; i++ ) {
 			if( i > 0 )
-				System.out.print('\t');
-			System.out.print( lua.toString(LuanElement.JAVA,args[i]) );
+				luan.out.print('\t');
+			luan.out.print( luan.toString(LuanElement.JAVA,args[i]) );
 		}
-		System.out.println();
+		luan.out.println();
 	}
 
 	public static String type(Object obj) {
 		return Luan.type(obj);
 	}
 
-	public static LuanFunction load(LuanState lua,String text,String sourceName) throws LuanException {
-		return LuanCompiler.compile(lua,new LuanSource(sourceName,text));
+	public static LuanFunction load(LuanState luan,String text,String sourceName) throws LuanException {
+		return LuanCompiler.compile(luan,new LuanSource(sourceName,text));
 	}
 
 	public static String readAll(Reader in)
@@ -106,23 +106,23 @@
 	}
 
 
-	public static LuanFunction load_file(LuanState lua,String fileName) throws LuanException {
+	public static LuanFunction load_file(LuanState luan,String fileName) throws LuanException {
 		try {
 			String src = fileName==null ? readAll(new InputStreamReader(System.in)) : read(new File(fileName));
-			return load(lua,src,fileName);
+			return load(luan,src,fileName);
 		} catch(IOException e) {
-			throw new LuanException(lua,LuanElement.JAVA,e);
+			throw new LuanException(luan,LuanElement.JAVA,e);
 		}
 	}
 
-	public static Object[] do_file(LuanState lua,String fileName) throws LuanException {
-		LuanFunction fn = load_file(lua,fileName);
-		return lua.call(fn,LuanElement.JAVA,null);
+	public static Object[] do_file(LuanState luan,String fileName) throws LuanException {
+		LuanFunction fn = load_file(luan,fileName);
+		return luan.call(fn,LuanElement.JAVA,null);
 	}
 
 	private static LuanFunction pairs(final Iterator<Map.Entry<Object,Object>> iter) {
 		return new LuanFunction() {
-			public Object[] call(LuanState lua,Object[] args) {
+			public Object[] call(LuanState luan,Object[] args) {
 				if( !iter.hasNext() )
 					return LuanFunction.EMPTY_RTN;
 				Map.Entry<Object,Object> entry = iter.next();
@@ -139,8 +139,8 @@
 		return pairs( t.listIterator() );
 	}
 
-	public static LuanTable get_metatable(LuanState lua,Object obj) {
-		return lua.getMetatable(obj);
+	public static LuanTable get_metatable(LuanState luan,Object obj) {
+		return luan.getMetatable(obj);
 	}
 
 	public static LuanTable set_metatable(LuanTable table,LuanTable metatable) {
@@ -161,7 +161,7 @@
 		return table;
 	}
 
-	public static int raw_len(LuanState lua,Object v) throws LuanException {
+	public static int raw_len(LuanState luan,Object v) throws LuanException {
 		if( v instanceof String ) {
 			String s = (String)v;
 			return s.length();
@@ -170,19 +170,19 @@
 			LuanTable t = (LuanTable)v;
 			return t.length();
 		}
-		throw new LuanException( lua, LuanElement.JAVA, "bad argument #1 to 'raw_len' (table or string expected)" );
+		throw new LuanException( luan, LuanElement.JAVA, "bad argument #1 to 'raw_len' (table or string expected)" );
 	}
 
 	public static Number to_number(Object e,Integer base) {
 		return Luan.toNumber(e,base);
 	}
 
-	public static String to_string(LuanState lua,Object v) throws LuanException {
-		return lua.toString(LuanElement.JAVA,v);
+	public static String to_string(LuanState luan,Object v) throws LuanException {
+		return luan.toString(LuanElement.JAVA,v);
 	}
 
-	public static void error(LuanState lua,Object msg) throws LuanException {
-		throw new LuanException(lua,LuanElement.JAVA,msg);
+	public static void error(LuanState luan,Object msg) throws LuanException {
+		throw new LuanException(luan,LuanElement.JAVA,msg);
 	}
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/lib/HtmlLib.java	Fri Dec 28 19:35:04 2012 +0000
@@ -0,0 +1,50 @@
+package luan.lib;
+
+import luan.LuanState;
+import luan.LuanTable;
+import luan.LuanJavaFunction;
+
+
+public final class HtmlLib {
+
+	public static void register(LuanState luan) {
+		LuanTable module = new LuanTable();
+		LuanTable global = luan.global();
+		global.put("html",module);
+		try {
+			add( module, "encode", String.class );
+		} catch(NoSuchMethodException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException {
+		t.put( method, new LuanJavaFunction(HtmlLib.class.getMethod(method,parameterTypes),null) );
+	}
+
+	public static String encode(String s) {
+		char[] a = s.toCharArray();
+		StringBuilder buf = new StringBuilder();
+		for( int i=0; i<a.length; i++ ) {
+			char c = a[i];
+			switch(c) {
+			case '&':
+				buf.append("&amp;");
+				break;
+			case '<':
+				buf.append("&lt;");
+				break;
+			case '>':
+				buf.append("&gt;");
+				break;
+			case '"':
+				buf.append("&quot;");
+				break;
+			default:
+				buf.append(c);
+			}
+		}
+		return buf.toString();
+	}
+
+}
--- a/src/luan/lib/JavaLib.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/lib/JavaLib.java	Fri Dec 28 19:35:04 2012 +0000
@@ -23,10 +23,10 @@
 
 public final class JavaLib {
 
-	public static void register(LuanState lua) {
-		lua.addMetatableGetter(mg);
+	public static void register(LuanState luan) {
+		luan.addMetatableGetter(mg);
 		LuanTable module = new LuanTable();
-		LuanTable global = lua.global();
+		LuanTable global = luan.global();
 		global.put("java",module);
 		try {
 			global.put( "import", new LuanJavaFunction(JavaLib.class.getMethod("importClass",LuanState.class,String.class),null) );
@@ -57,7 +57,7 @@
 		}
 	};
 
-	public static Object __index(LuanState lua,Object obj,Object key) throws LuanException {
+	public static Object __index(LuanState luan,Object obj,Object key) throws LuanException {
 		if( obj instanceof Static ) {
 			if( key instanceof String ) {
 				String name = (String)key;
@@ -85,7 +85,7 @@
 					}
 				}
 			}
-			throw new LuanException(lua,LuanElement.JAVA,"invalid index for java class: "+key);
+			throw new LuanException(luan,LuanElement.JAVA,"invalid index for java class: "+key);
 		}
 		Class cls = obj.getClass();
 		if( cls.isArray() ) {
@@ -96,7 +96,7 @@
 			if( i != null ) {
 				return Array.get(obj,i);
 			}
-			throw new LuanException(lua,LuanElement.JAVA,"invalid index for java array: "+key);
+			throw new LuanException(luan,LuanElement.JAVA,"invalid index for java array: "+key);
 		}
 		if( key instanceof String ) {
 			String name = (String)key;
@@ -109,7 +109,7 @@
 				}
 			}
 		}
-		throw new LuanException(lua,LuanElement.JAVA,"invalid index for java object: "+key);
+		throw new LuanException(luan,LuanElement.JAVA,"invalid index for java object: "+key);
 	}
 
 	private static Object member(Object obj,List<Member> members) throws LuanException {
@@ -182,16 +182,16 @@
 		}
 	}
 
-	public static Static getClass(LuanState lua,String name) throws LuanException {
+	public static Static getClass(LuanState luan,String name) throws LuanException {
 		try {
 			return new Static( Class.forName(name) );
 		} catch(ClassNotFoundException e) {
-			throw new LuanException(lua,LuanElement.JAVA,e);
+			throw new LuanException(luan,LuanElement.JAVA,e);
 		}
 	}
 
-	public static void importClass(LuanState lua,String name) throws LuanException {
-		lua.global().put( name.substring(name.lastIndexOf('.')+1), getClass(lua,name) );
+	public static void importClass(LuanState luan,String name) throws LuanException {
+		luan.global().put( name.substring(name.lastIndexOf('.')+1), getClass(luan,name) );
 	}
 
 	static class AmbiguousJavaFunction extends LuanFunction {
@@ -209,13 +209,13 @@
 			}
 		}
 
-		@Override public Object[] call(LuanState lua,Object[] args) throws LuanException {
+		@Override public Object[] call(LuanState luan,Object[] args) throws LuanException {
 			for( LuanJavaFunction fn : fnMap.get(args.length) ) {
 				try {
-					return fn.call(lua,args);
+					return fn.call(luan,args);
 				} catch(IllegalArgumentException e) {}
 			}
-			throw new LuanException(lua,LuanElement.JAVA,"no method matched args");
+			throw new LuanException(luan,LuanElement.JAVA,"no method matched args");
 		}
 	}
 
--- a/src/luan/lib/StringLib.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/lib/StringLib.java	Fri Dec 28 19:35:04 2012 +0000
@@ -13,9 +13,9 @@
 
 public final class StringLib {
 
-	public static void register(LuanState lua) {
+	public static void register(LuanState luan) {
 		LuanTable module = new LuanTable();
-		LuanTable global = lua.global();
+		LuanTable global = luan.global();
 		global.put("string",module);
 		try {
 			module.put( "byte", new LuanJavaFunction(StringLib.class.getMethod("byte_",String.class,Integer.class,Integer.class),null) );
@@ -129,7 +129,7 @@
 	public static LuanFunction gmatch(String s,String pattern) {
 		final Matcher m = Pattern.compile(pattern).matcher(s);
 		return new LuanFunction() {
-			public Object[] call(LuanState lua,Object[] args) {
+			public Object[] call(LuanState luan,Object[] args) {
 				if( !m.find() )
 					return LuanFunction.EMPTY_RTN;
 				final int n = m.groupCount();
@@ -144,7 +144,7 @@
 		};
 	}
 
-	public static Object[] gsub(LuanState lua,String s,String pattern,Object repl,Integer n) throws LuanException {
+	public static Object[] gsub(LuanState luan,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 ) {
@@ -168,7 +168,7 @@
 				if( Luan.toBoolean(val) ) {
 					String replacement = Luan.asString(val);
 					if( replacement==null )
-						throw new LuanException( lua, LuanElement.JAVA, "invalid replacement value (a "+Luan.type(val)+")" );
+						throw new LuanException( luan, LuanElement.JAVA, "invalid replacement value (a "+Luan.type(val)+")" );
 					m.appendReplacement(sb,replacement);
 				}
 				i++;
@@ -191,11 +191,11 @@
 						args[j] = m.group(j);
 					}
 				}
-				Object val = Luan.first( lua.call(fn,LuanElement.JAVA,"repl-arg",args) );
+				Object val = Luan.first( luan.call(fn,LuanElement.JAVA,"repl-arg",args) );
 				if( Luan.toBoolean(val) ) {
 					String replacement = Luan.asString(val);
 					if( replacement==null )
-						throw new LuanException( lua, LuanElement.JAVA, "invalid replacement value (a "+Luan.type(val)+")" );
+						throw new LuanException( luan, 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 LuanException( lua, LuanElement.JAVA, "bad argument #3 to 'gsub' (string/function/table expected)" );
+		throw new LuanException( luan, LuanElement.JAVA, "bad argument #3 to 'gsub' (string/function/table expected)" );
 	}
 
 }
--- a/src/luan/lib/TableLib.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/lib/TableLib.java	Fri Dec 28 19:35:04 2012 +0000
@@ -14,9 +14,9 @@
 
 public final class TableLib {
 
-	public static void register(LuanState lua) {
+	public static void register(LuanState luan) {
 		LuanTable module = new LuanTable();
-		LuanTable global = lua.global();
+		LuanTable global = luan.global();
 		global.put("table",module);
 		try {
 			add( module, "concat", LuanState.class, LuanTable.class, String.class, Integer.class, Integer.class );
@@ -35,7 +35,7 @@
 		t.put( method, new LuanJavaFunction(TableLib.class.getMethod(method,parameterTypes),null) );
 	}
 
-	public static String concat(LuanState lua,LuanTable list,String sep,Integer i,Integer j) throws LuanException {
+	public static String concat(LuanState luan,LuanTable list,String sep,Integer i,Integer j) throws LuanException {
 		int first = i==null ? 1 : i;
 		int last = j==null ? list.length() : j;
 		StringBuilder buf = new StringBuilder();
@@ -47,25 +47,25 @@
 				buf.append(sep);
 			String s = Luan.asString(val);
 			if( s==null )
-				throw new LuanException( lua, LuanElement.JAVA, "invalid value ("+Luan.type(val)+") at index "+k+" in table for 'concat'" );
+				throw new LuanException( luan, LuanElement.JAVA, "invalid value ("+Luan.type(val)+") at index "+k+" in table for 'concat'" );
 			buf.append(val);
 		}
 		return buf.toString();
 	}
 
-	public static void insert(LuanState lua,LuanTable list,int pos,Object value) throws LuanException {
+	public static void insert(LuanState luan,LuanTable list,int pos,Object value) throws LuanException {
 		try {
 			list.insert(pos,value);
 		} catch(IndexOutOfBoundsException e) {
-			throw new LuanException( lua, LuanElement.JAVA, e);
+			throw new LuanException( luan, LuanElement.JAVA, e);
 		}
 	}
 
-	public static Object remove(LuanState lua,LuanTable list,int pos) throws LuanException {
+	public static Object remove(LuanState luan,LuanTable list,int pos) throws LuanException {
 		try {
 			return list.remove(pos);
 		} catch(IndexOutOfBoundsException e) {
-			throw new LuanException( lua, LuanElement.JAVA, e);
+			throw new LuanException( luan, LuanElement.JAVA, e);
 		}
 	}
 
@@ -73,13 +73,13 @@
 		public boolean isLessThan(Object o1,Object o2);
 	}
 
-	public static void sort(final LuanState lua,LuanTable list,final LuanFunction comp) throws LuanException {
+	public static void sort(final LuanState luan,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(LuanElement.JAVA,o1,o2);
+						return luan.isLessThan(LuanElement.JAVA,o1,o2);
 					} catch(LuanException e) {
 						throw new LuanRuntimeException(e);
 					}
@@ -89,7 +89,7 @@
 			lt = new LessThan() {
 				public boolean isLessThan(Object o1,Object o2) {
 					try {
-						return Luan.toBoolean(Luan.first(lua.call(comp,LuanElement.JAVA,"comp-arg",o1,o2)));
+						return Luan.toBoolean(Luan.first(luan.call(comp,LuanElement.JAVA,"comp-arg",o1,o2)));
 					} catch(LuanException e) {
 						throw new LuanRuntimeException(e);
 					}
--- a/src/luan/tools/CmdLine.java	Fri Dec 28 03:29:12 2012 +0000
+++ b/src/luan/tools/CmdLine.java	Fri Dec 28 19:35:04 2012 +0000
@@ -17,12 +17,12 @@
 public class CmdLine {
 
 	public static void main(String[] args) {
-		LuanState lua = LuanCompiler.newLuaState();
-		BasicLib.register(lua);
-		JavaLib.register(lua);
-		StringLib.register(lua);
-		TableLib.register(lua);
-		BasicLib.make_standard(lua);
+		LuanState luan = LuanCompiler.newLuanState();
+		BasicLib.register(luan);
+		JavaLib.register(luan);
+		StringLib.register(luan);
+		TableLib.register(luan);
+		BasicLib.make_standard(luan);
 		boolean interactive = false;
 		boolean showVersion = false;
 		int i = 0;
@@ -43,15 +43,15 @@
 						error("'-e' needs argument");
 					String cmd = args[i];
 					try {
-						LuanFunction fn = BasicLib.load(lua,cmd,"(command line)");
-						lua.call(fn,null,null);
+						LuanFunction fn = BasicLib.load(luan,cmd,"(command line)");
+						luan.call(fn,null,null);
 					} catch(LuanException e) {
 						System.err.println("command line error: "+e.getMessage());
 						System.exit(-1);
 					}
 				} else if( arg.equals("-") ) {
 					try {
-						BasicLib.do_file(lua,"stdin");
+						BasicLib.do_file(luan,"stdin");
 					} catch(LuanException e) {
 						System.err.println(e.getMessage());
 						System.exit(-1);
@@ -73,10 +73,10 @@
 			for( int j=0; j<args.length; j++ ) {
 				argsTable.put( j, args[j] );
 			}
-			lua.global().put("arg",argsTable);
+			luan.global().put("arg",argsTable);
 			try {
-				LuanFunction fn = BasicLib.load_file(lua,file);
-				lua.call(fn,null,null,varArgs);
+				LuanFunction fn = BasicLib.load_file(luan,file);
+				luan.call(fn,null,null,varArgs);
 			} catch(LuanException e) {
 //				System.err.println("error: "+e.getMessage());
 				e.printStackTrace();
@@ -84,7 +84,7 @@
 			}
 		}
 		if( interactive )
-			interactive(lua);
+			interactive(luan);
 	}
 
 	private static void error(String msg) {
@@ -101,15 +101,15 @@
 		System.exit(-1);
 	}
 
-	static void interactive(LuanState lua) {
+	static void interactive(LuanState luan) {
 		while( true ) {
 			System.out.print("> ");
 			String input = new Scanner(System.in).nextLine();
 			try {
-				LuanFunction fn = BasicLib.load(lua,input,"stdin");
-				Object[] rtn = lua.call(fn,null,null);
+				LuanFunction fn = BasicLib.load(luan,input,"stdin");
+				Object[] rtn = luan.call(fn,null,null);
 				if( rtn.length > 0 )
-					BasicLib.print(lua,rtn);
+					BasicLib.print(luan,rtn);
 			} catch(LuanException e) {
 				System.out.println(e.getMessage());
 			}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/tools/WebShell.java	Fri Dec 28 19:35:04 2012 +0000
@@ -0,0 +1,107 @@
+package luan.tools;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.Writer;
+import java.io.PrintWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import luan.LuanFunction;
+import luan.LuanState;
+import luan.LuanException;
+import luan.interp.LuanCompiler;
+import luan.lib.BasicLib;
+import luan.lib.JavaLib;
+import luan.lib.StringLib;
+import luan.lib.TableLib;
+import luan.lib.HtmlLib;
+
+
+public class WebShell extends HttpServlet {
+	private static final Logger logger = LoggerFactory.getLogger(WebShell.class);
+
+	protected LuanState newLuanState() {
+		LuanState luan =  LuanCompiler.newLuanState();
+		BasicLib.register(luan);
+		JavaLib.register(luan);
+		StringLib.register(luan);
+		TableLib.register(luan);
+		HtmlLib.register(luan);
+		return luan;
+	}
+
+	protected Object[] eval(LuanState luan,String cmd) throws LuanException {
+		LuanFunction fn = BasicLib.load(luan,cmd,"WebShell");
+		return luan.call(fn,null,null);
+	}
+
+	protected void service(HttpServletRequest request,HttpServletResponse response)
+		throws ServletException, IOException
+	{
+		PrintWriter out = response.getWriter();
+		HttpSession session = request.getSession();
+
+		ByteArrayOutputStream history = (ByteArrayOutputStream)session.getValue("history");
+		if( history==null ) {
+			history = new ByteArrayOutputStream();
+			session.putValue("history",history);
+		}
+
+		if( request.getParameter("clear") != null ) {
+			history.reset();
+		} else {
+			String cmd = request.getParameter("cmd");
+			if( cmd != null ) {
+				Writer writer = new OutputStreamWriter(history);
+				writer.write( "% " + HtmlLib.encode(cmd) + "\r\n" );
+				try {
+					LuanState luan  = (LuanState)session.getValue("luan");
+					if( luan==null ) {
+						luan = newLuanState();
+						session.putValue("luan",luan);
+					}
+					luan.out = new PrintStream(history);
+					luan.global().put("request",request);
+					luan.global().put("response",response);
+					Object[] result = eval(luan,cmd);
+					if( result.length > 0 ) {
+						for( int i=0; i<result.length; i++ ) {
+							if( i > 0 )
+								writer.write("  ");
+							writer.write(HtmlLib.encode(luan.toString(null,result[i])));
+						}
+						writer.write("\r\n");
+					}
+				} catch(LuanException e) {
+					logger.info("",e);
+					writer.write( HtmlLib.encode(e.toString()) );
+				}
+				writer.flush();
+			}
+		}
+
+		out.println( "<html>" );
+		out.println( "<title>Luan Shell</title>" );
+		out.println( "<body>" );
+		out.println( "<p>This is a command shell.  Enter commands below." );
+		out.println( "<pre>" + history + "</pre>" );
+		out.println( "<form name='theForm' method='post'>" );
+		out.println( "% <input name='cmd' size=60>" );
+		out.println( "<input type=submit value=run>" );
+		out.println( "<input type=submit name=clear value=clear>" );
+		out.println( "</form>" );
+		
+		out.println( "<script>document.theForm.cmd.focus();</script>" );
+		
+		out.println( "<p>" );
+		out.println( "</body>" );
+		out.println( "</html>" );
+	}
+}