changeset 576:4723d22062ce

remove LuanBit
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 13 Jul 2015 20:38:26 -0600
parents 7c3ad6db8ac3
children d7a85fbe15f1
files core/src/luan/LuanBit.java core/src/luan/LuanException.java core/src/luan/LuanState.java core/src/luan/impl/BinaryOpExpr.java core/src/luan/impl/ConcatExpr.java core/src/luan/impl/EqExpr.java core/src/luan/impl/FnCall.java core/src/luan/impl/ForStmt.java core/src/luan/impl/IfStmt.java core/src/luan/impl/IndexExpr.java core/src/luan/impl/LeExpr.java core/src/luan/impl/LenExpr.java core/src/luan/impl/LtExpr.java core/src/luan/impl/NotExpr.java core/src/luan/impl/RepeatStmt.java core/src/luan/impl/ReturnStmt.java core/src/luan/impl/SetTableEntry.java core/src/luan/impl/UnmExpr.java core/src/luan/impl/WhileStmt.java core/src/luan/modules/BinaryLuan.java core/src/luan/modules/JavaLuan.java core/src/luan/modules/StringLuan.java
diffstat 22 files changed, 203 insertions(+), 266 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/LuanBit.java	Mon Jul 13 18:34:31 2015 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-package luan;
-
-import java.util.List;
-
-
-public final class LuanBit {
-	public final LuanState luan;
-	public final LuanElement el;
-
-	LuanBit(LuanState luan,LuanElement el) {
-		this.luan = luan;
-		this.el = el;
-	}
-
-	public LuanException exception(Object msg) throws LuanException {
-		return new LuanException(this,msg);
-	}
-
-	public StackTraceElement[] stackTrace() {
-		List<StackTraceElement> stackTrace = luan.stackTrace;
-		if( el != null )
-			stackTrace.add(new StackTraceElement(el,null));
-		StackTraceElement[] rtn = stackTrace.toArray(new StackTraceElement[0]);
-		if( el != null )
-			stackTrace.remove(stackTrace.size()-1);
-		return rtn;
-	}
-
-	public void dumpStack() {
-		System.err.println( stackTrace() );
-	}
-
-	public Object call(LuanFunction fn,String fnName,Object[] args) throws LuanException {
-		push(fnName);
-		try {
-			return fn.call(luan,args);
-		} catch(StackOverflowError e) {
-			throw exception("stack overflow");
-		} finally {
-			pop();
-		}
-	}
-
-	private void push(String fnName) {
-		if( el == null )  throw new RuntimeException();
-		List<StackTraceElement> stackTrace = luan.stackTrace;
-		stackTrace.add( new StackTraceElement(el,fnName) );
-	}
-
-	private void pop() {
-		List<StackTraceElement> stackTrace = luan.stackTrace;
-		stackTrace.remove(stackTrace.size()-1);
-	}
-
-	public String toString(Object obj) throws LuanException {
-		push(null);
-		try {
-			return luan.toString(obj);
-		} finally {
-			pop();
-		}
-	}
-
-	public Object index(Object obj,Object key) throws LuanException {
-		push(null);
-		try {
-			return luan.index(obj,key);
-		} finally {
-			pop();
-		}
-	}
-
-	public int length(LuanTable t) throws LuanException {
-		push(null);
-		try {
-			return t.length(luan);
-		} finally {
-			pop();
-		}
-	}
-
-	public void put(LuanTable t,Object key,Object value) throws LuanException {
-		push(null);
-		try {
-			t.put(luan,key,value);
-		} finally {
-			pop();
-		}
-	}
-
-	public String checkString(Object obj) throws LuanException {
-		if( obj instanceof String )
-			return (String)obj;
-		if( el != null ) {
-			throw exception( "attempt to use '"+el.text()+"' (a " + Luan.type(obj) + " value) as a string" );
-		} else {
-			throw exception( "attempt to use a " + Luan.type(obj) + " as a string" );
-		}
-	}
-
-	public Number checkNumber(Object obj) throws LuanException {
-		if( obj instanceof Number )
-			return (Number)obj;
-		if( el != null ) {
-			throw exception( "attempt to perform arithmetic on '"+el.text()+"' (a " + Luan.type(obj) + " value)" );
-		} else {
-			throw exception( "attempt to perform arithmetic on a " + Luan.type(obj) + " value" );
-		}
-	}
-
-	public LuanFunction checkFunction(Object obj) throws LuanException {
-		if( obj instanceof LuanFunction )
-			return (LuanFunction)obj;
-		if( el != null ) {
-			throw exception( "attempt to call '"+el.text()+"' (a " + Luan.type(obj) + " value)" );
-		} else {
-			throw exception( "attempt to call a " + Luan.type(obj) + " value" );
-		}
-	}
-
-	public Boolean checkBoolean(Object obj) throws LuanException {
-		if( obj instanceof Boolean )
-			return (Boolean)obj;
-		if( el != null ) {
-			throw exception( "attempt to use '"+el.text()+"' (a " + Luan.type(obj) + " value) as a boolean" );
-		} else {
-			throw exception( "attempt to use a " + Luan.type(obj) + " as a boolean" );
-		}
-	}
-
-	public LuanFunction getHandlerFunction(String op,LuanTable t) throws LuanException {
-		Object f = t.getHandler(op);
-		if( f == null )
-			return null;
-		return checkFunction(f);
-	}
-
-	public LuanFunction getBinHandler(String op,Object o1,Object o2) throws LuanException {
-		if( o1 instanceof LuanTable ) {
-			LuanFunction f1 = getHandlerFunction(op,(LuanTable)o1);
-			if( f1 != null )
-				return f1;
-		}
-		return o2 instanceof LuanTable ? getHandlerFunction(op,(LuanTable)o2) : null;
-	}
-
-	public boolean isLessThan(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("__lt",o1,o2);
-		if( fn != null )
-			return checkBoolean( Luan.first(call(fn,"__lt",new Object[]{o1,o2})) );
-		throw exception( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
-	}
-
-	public Object arithmetic(String op,Object o1,Object o2) throws LuanException {
-		LuanFunction fn = getBinHandler(op,o1,o2);
-		if( fn != null )
-			return Luan.first(call(fn,op,new Object[]{o1,o2}));
-		String type = !(o1 instanceof Number) ? Luan.type(o1) : Luan.type(o2);
-		throw exception("attempt to perform arithmetic on a "+type+" value");
-	}
-
-}
--- a/core/src/luan/LuanException.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/LuanException.java	Mon Jul 13 20:38:26 2015 -0600
@@ -11,12 +11,12 @@
 		super(msg,cause);
 	}
 
-	LuanException(LuanBit bit,Object msg) throws LuanException {
-		this( bit.luan.toString(msg), msg instanceof Throwable ? (Throwable)msg : null );
+	LuanException(LuanState luan,Object msg) throws LuanException {
+		this( luan.toString(msg), msg instanceof Throwable ? (Throwable)msg : null );
 		table.rawPut( "java", this );
 		table.rawPut( "message", msg );
-		table.rawPut( "message_string", bit.luan.toString(msg) );
-		for( StackTraceElement ste : bit.stackTrace() ) {
+		table.rawPut( "message_string", luan.toString(msg) );
+		for( StackTraceElement ste : luan.stackTrace ) {
 			LuanTable tbl = new LuanTable();
 			tbl.rawPut( "source", ste.call.source.name );
 			tbl.rawPut( "line", ste.call.lineNumber() );
--- a/core/src/luan/LuanState.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/LuanState.java	Mon Jul 13 20:38:26 2015 -0600
@@ -64,32 +64,54 @@
 		return fn.call(this);
 	}
 
-	public final LuanBit bit(LuanElement el) {
-		return new LuanBit(this,el);
-	}
 
-	// convenience methods
-
-	private final LuanBit JAVA = bit(null);
 
 	public LuanException exception(Object msg) throws LuanException {
-		return JAVA.exception(msg);
+		return new LuanException(this,msg);
 	}
 
 	public Boolean checkBoolean(Object obj) throws LuanException {
-		return JAVA.checkBoolean(obj);
+		if( obj instanceof Boolean )
+			return (Boolean)obj;
+		throw exception( "attempt to use '"+context()+"' (a " + Luan.type(obj) + " value) as a boolean" );
+	}
+
+	public Boolean checkBoolean(Object obj,LuanElement el) throws LuanException {
+		push(el,null);
+		try {
+			return checkBoolean(obj);
+		} finally {
+			pop();
+		}
 	}
 
 	public String checkString(Object obj) throws LuanException {
-		return JAVA.checkString(obj);
+		if( obj instanceof String )
+			return (String)obj;
+		throw exception( "attempt to use '"+context()+"' (a " + Luan.type(obj) + " value) as a string" );
 	}
 
 	public LuanFunction checkFunction(Object obj) throws LuanException {
-		return JAVA.checkFunction(obj);
+		if( obj instanceof LuanFunction )
+			return (LuanFunction)obj;
+		throw exception( "attempt to call '"+context()+"' (a " + Luan.type(obj) + " value)" );
 	}
 
 	public boolean isLessThan(Object o1,Object o2) throws LuanException {
-		return JAVA.isLessThan(o1,o2);
+		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("__lt",o1,o2);
+		if( fn != null )
+			return checkBoolean( Luan.first(fn.call(this,new Object[]{o1,o2})) );
+		throw exception( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
 	}
 
 	public String toString(Object obj) throws LuanException {
@@ -106,6 +128,15 @@
 		return obj.toString();
 	}
 
+	public String toString(Object obj,LuanElement el) throws LuanException {
+		push(el,null);
+		try {
+			return toString(obj);
+		} finally {
+			pop();
+		}
+	}
+
 	public Object index(Object obj,Object key) throws LuanException {
 		if( obj instanceof LuanTable ) {
 			LuanTable tbl = (LuanTable)obj;
@@ -119,4 +150,40 @@
 	public String context() {
 		return stackTrace.get(stackTrace.size()-1).call.text();
 	}
+
+	public void push(LuanElement el,String fnName) {
+		if( el == null )  throw new RuntimeException();
+		stackTrace.add( new StackTraceElement(el,fnName) );
+	}
+
+	public void pop() {
+		stackTrace.remove(stackTrace.size()-1);
+	}
+
+	public LuanFunction getBinHandler(String op,Object o1,Object o2) throws LuanException {
+		if( o1 instanceof LuanTable ) {
+			LuanFunction f1 = getHandlerFunction(op,(LuanTable)o1);
+			if( f1 != null )
+				return f1;
+		}
+		return o2 instanceof LuanTable ? getHandlerFunction(op,(LuanTable)o2) : null;
+	}
+
+	public LuanFunction getHandlerFunction(String op,LuanTable t) throws LuanException {
+		Object f = t.getHandler(op);
+		if( f == null )
+			return null;
+		return checkFunction(f);
+	}
+
+	public void dumpStack() {
+		System.err.println( stackTrace );
+	}
+/*
+	public Number checkNumber(Object obj) throws LuanException {
+		if( obj instanceof Number )
+			return (Number)obj;
+		throw exception( "attempt to perform arithmetic on '"+context()+"' (a " + Luan.type(obj) + " value)" );
+	}
+*/
 }
--- a/core/src/luan/impl/BinaryOpExpr.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/BinaryOpExpr.java	Mon Jul 13 20:38:26 2015 -0600
@@ -18,7 +18,16 @@
 	}
 
 	Object arithmetic(LuanStateImpl luan,String op,Object o1,Object o2) throws LuanException {
-		return luan.bit(el()).arithmetic(op,o1,o2);
+		luan.push(el,null);
+		try {
+			LuanFunction fn = luan.getBinHandler(op,o1,o2);
+			if( fn != null )
+				return Luan.first(fn.call(luan,new Object[]{o1,o2}));
+			String type = !(o1 instanceof Number) ? Luan.type(o1) : Luan.type(o2);
+			throw luan.exception("attempt to perform arithmetic on a "+type+" value");
+		} finally {
+			luan.pop();
+		}
 	}
 
 }
--- a/core/src/luan/impl/ConcatExpr.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/ConcatExpr.java	Mon Jul 13 20:38:26 2015 -0600
@@ -4,7 +4,6 @@
 import luan.LuanFunction;
 import luan.LuanException;
 import luan.LuanElement;
-import luan.LuanBit;
 
 
 final class ConcatExpr extends BinaryOpExpr {
@@ -16,12 +15,16 @@
 	@Override public Object eval(LuanStateImpl luan) throws LuanException {
 		Object o1 = op1.eval(luan);
 		Object o2 = op2.eval(luan);
-		LuanBit bit = luan.bit(el);
-		LuanFunction fn = bit.getBinHandler("__concat",o1,o2);
-		if( fn != null )
-			return Luan.first(bit.call(fn,"__concat",new Object[]{o1,o2}));
-		String s1 = luan.bit(op1.el()).toString(o1);
-		String s2 = luan.bit(op2.el()).toString(o2);
+		luan.push(el,null);
+		try {
+			LuanFunction fn = luan.getBinHandler("__concat",o1,o2);
+			if( fn != null )
+				return Luan.first(fn.call(luan,new Object[]{o1,o2}));
+		} finally {
+			luan.pop();
+		}
+		String s1 = luan.toString(o1,op1.el());
+		String s2 = luan.toString(o2,op2.el());
 		return s1 + s2;
 	}
 }
--- a/core/src/luan/impl/EqExpr.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/EqExpr.java	Mon Jul 13 20:38:26 2015 -0600
@@ -6,7 +6,6 @@
 import luan.LuanTable;
 import luan.LuanException;
 import luan.LuanElement;
-import luan.LuanBit;
 
 
 final class EqExpr extends BinaryOpExpr {
@@ -45,9 +44,13 @@
 		Object f = mt1.rawGet("__eq");
 		if( f == null || !f.equals(mt2.rawGet("__eq")) )
 			return false;
-		LuanBit bit = luan.bit(el);
-		LuanFunction fn = bit.checkFunction(f);
-		return bit.checkBoolean( Luan.first(bit.call(fn,"__eq",new Object[]{o1,o2})) );
+		luan.push(el,"__eq");
+		try {
+			LuanFunction fn = luan.checkFunction(f);
+			return luan.checkBoolean( Luan.first(fn.call(luan,new Object[]{o1,o2})) );
+		} finally {
+			luan.pop();
+		}
 	}
 
 	@Override public String toString() {
--- a/core/src/luan/impl/FnCall.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/FnCall.java	Mon Jul 13 20:38:26 2015 -0600
@@ -24,17 +24,22 @@
 	}
 
 	private Object call(LuanStateImpl luan,Object o) throws LuanException {
-		if( o instanceof LuanFunction ) {
-			LuanFunction fn = (LuanFunction)o;
-			return luan.bit(el).call( fn, fnName, Luan.array(args.eval(luan)) );
+		luan.push(el,fnName);
+		try {
+			if( o instanceof LuanFunction ) {
+				LuanFunction fn = (LuanFunction)o;
+				return fn.call( luan, Luan.array(args.eval(luan)) );
+			}
+			if( o instanceof LuanTable ) {
+				LuanTable t = (LuanTable)o;
+				Object h = t.getHandler("__call");
+				if( h != null )
+					return call(luan,h);
+			}
+			throw luan.exception( "attempt to call '"+fnName+"' (a " + Luan.type(o) + " value)" );
+		} finally {
+			luan.pop();
 		}
-		if( o instanceof LuanTable ) {
-			LuanTable t = (LuanTable)o;
-			Object h = t.getHandler("__call");
-			if( h != null )
-				return call(luan,h);
-		}
-		throw luan.bit(fnExpr.el()).exception( "attempt to call '"+fnExpr.el().text()+"' (a " + Luan.type(o) + " value)" );
 	}
 
 	@Override public String toString() {
--- a/core/src/luan/impl/ForStmt.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/ForStmt.java	Mon Jul 13 20:38:26 2015 -0600
@@ -4,7 +4,6 @@
 import luan.LuanException;
 import luan.LuanFunction;
 import luan.LuanElement;
-import luan.LuanBit;
 
 
 final class ForStmt extends CodeImpl implements Stmt {
@@ -22,12 +21,12 @@
 	}
 
 	@Override public void eval(LuanStateImpl luan) throws LuanException {
-		LuanBit bit = luan.bit(iterExpr.el());
-		LuanFunction iter = bit.checkFunction( iterExpr.eval(luan) );
-		String name = iterExpr.el().text();
+		luan.push( iterExpr.el(), iterExpr.el().text() );
 		try {
+			LuanFunction iter = luan.checkFunction( iterExpr.eval(luan) );
+			String name = iterExpr.el().text();
 			while(true) {
-				Object vals = bit.call(iter,name,LuanFunction.NOTHING);
+				Object vals = iter.call(luan);
 				if( vals==null )
 					break;
 				if( vals instanceof Object[] ) {
@@ -48,6 +47,7 @@
 		} catch(BreakException e) {
 		} finally {
 			luan.stackClear(iVars,iVars+nVars);
+			luan.pop();
 		}
 	}
 
--- a/core/src/luan/impl/IfStmt.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/IfStmt.java	Mon Jul 13 20:38:26 2015 -0600
@@ -18,7 +18,7 @@
 	}
 
 	@Override public void eval(LuanStateImpl luan) throws LuanException {
-		if( luan.bit(cnd.el()).checkBoolean( cnd.eval(luan) ) ) {
+		if( luan.checkBoolean( cnd.eval(luan), cnd.el() ) ) {
 			thenStmt.eval(luan);
 		} else {
 			elseStmt.eval(luan);
--- a/core/src/luan/impl/IndexExpr.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/IndexExpr.java	Mon Jul 13 20:38:26 2015 -0600
@@ -11,7 +11,14 @@
 	}
 
 	@Override public Object eval(LuanStateImpl luan) throws LuanException {
-		return luan.bit(el()).index( op1.eval(luan), op2.eval(luan) );
+		Object o1 = op1.eval(luan);
+		Object o2 = op2.eval(luan);
+		luan.push(el,null);
+		try {
+			return luan.index(o1,o2);
+		} finally {
+			luan.pop();
+		}
 	}
 
 }
--- a/core/src/luan/impl/LeExpr.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/LeExpr.java	Mon Jul 13 20:38:26 2015 -0600
@@ -4,7 +4,6 @@
 import luan.LuanFunction;
 import luan.LuanException;
 import luan.LuanElement;
-import luan.LuanBit;
 
 
 final class LeExpr extends BinaryOpExpr {
@@ -30,13 +29,17 @@
 			String s2 = (String)o2;
 			return s1.compareTo(s2) <= 0;
 		}
-		LuanBit bit = luan.bit(el);
-		LuanFunction fn = bit.getBinHandler("__le",o1,o2);
-		if( fn != null )
-			return bit.checkBoolean( Luan.first(bit.call(fn,"__le",new Object[]{o1,o2})) );
-		fn = bit.getBinHandler("__lt",o1,o2);
-		if( fn != null )
-			return !bit.checkBoolean( Luan.first(bit.call(fn,"__lt",new Object[]{o2,o1})) );
-		throw bit.exception( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
+		luan.push(el,null);
+		try {
+			LuanFunction fn = luan.getBinHandler("__le",o1,o2);
+			if( fn != null )
+				return luan.checkBoolean( Luan.first(fn.call(luan,new Object[]{o1,o2})) );
+			fn = luan.getBinHandler("__lt",o1,o2);
+			if( fn != null )
+				return !luan.checkBoolean( Luan.first(fn.call(luan,new Object[]{o2,o1})) );
+			throw luan.exception( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
+		} finally {
+			luan.pop();
+		}
 	}
 }
--- a/core/src/luan/impl/LenExpr.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/LenExpr.java	Mon Jul 13 20:38:26 2015 -0600
@@ -5,7 +5,6 @@
 import luan.LuanFunction;
 import luan.LuanException;
 import luan.LuanElement;
-import luan.LuanBit;
 
 
 final class LenExpr extends UnaryOpExpr {
@@ -24,10 +23,14 @@
 			byte[] a = (byte[])o;
 			return a.length;
 		}
-		LuanBit bit = luan.bit(el);
-		if( !(o instanceof LuanTable) )
-			throw bit.exception( "attempt to get length of a " + Luan.type(o) + " value" );
-		LuanTable t = (LuanTable)o;
-		return bit.length(t);
+		luan.push(el,null);
+		try {
+			if( !(o instanceof LuanTable) )
+				throw luan.exception( "attempt to get length of a " + Luan.type(o) + " value" );
+			LuanTable t = (LuanTable)o;
+			return t.length(luan);
+		} finally {
+			luan.pop();
+		}
 	}
 }
--- a/core/src/luan/impl/LtExpr.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/LtExpr.java	Mon Jul 13 20:38:26 2015 -0600
@@ -15,6 +15,11 @@
 	@Override public Object eval(LuanStateImpl luan) throws LuanException {
 		Object o1 = op1.eval(luan);
 		Object o2 = op2.eval(luan);
-		return luan.bit(el).isLessThan(o1,o2);
+		luan.push(el,null);
+		try {
+			return luan.isLessThan(o1,o2);
+		} finally {
+			luan.pop();
+		}
 	}
 }
--- a/core/src/luan/impl/NotExpr.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/NotExpr.java	Mon Jul 13 20:38:26 2015 -0600
@@ -12,7 +12,7 @@
 	}
 
 	@Override public Object eval(LuanStateImpl luan) throws LuanException {
-		return !luan.bit(op.el()).checkBoolean( op.eval(luan) );
+		return !luan.checkBoolean( op.eval(luan), op.el() );
 	}
 
 	@Override public String toString() {
--- a/core/src/luan/impl/RepeatStmt.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/RepeatStmt.java	Mon Jul 13 20:38:26 2015 -0600
@@ -19,7 +19,7 @@
 		try {
 			do {
 				doStmt.eval(luan);
-			} while( !luan.bit(el).checkBoolean( cnd.eval(luan) ) );
+			} while( !luan.checkBoolean( cnd.eval(luan), el ) );
 		} catch(BreakException e) {}
 	}
 }
--- a/core/src/luan/impl/ReturnStmt.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/ReturnStmt.java	Mon Jul 13 20:38:26 2015 -0600
@@ -27,11 +27,16 @@
 		luan.returnValues = expressions.eval(luan);
 		if( tailFnExpr != null ) {
 			LuanElement elTail = tailFnExpr.el();
-			LuanFunction tailFn = luan.bit(elTail).checkFunction( tailFnExpr.eval(luan) );
-			if( tailFn instanceof Closure ) {
-				luan.tailFn = (Closure)tailFn;
-			} else {
-				luan.returnValues =  luan.bit(elTail).call(tailFn,elTail.text(),Luan.array(luan.returnValues));
+			luan.push(elTail,elTail.text());
+			try {
+				LuanFunction tailFn = luan.checkFunction( tailFnExpr.eval(luan) );
+				if( tailFn instanceof Closure ) {
+					luan.tailFn = (Closure)tailFn;
+				} else {
+					luan.returnValues =  tailFn.call(luan,Luan.array(luan.returnValues));
+				}
+			} finally {
+				luan.pop();
 			}
 		}
 		if( throwReturnException )
--- a/core/src/luan/impl/SetTableEntry.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/SetTableEntry.java	Mon Jul 13 20:38:26 2015 -0600
@@ -6,7 +6,6 @@
 import luan.LuanFunction;
 import luan.LuanElement;
 import luan.LuanMeta;
-import luan.LuanBit;
 import luan.modules.JavaLuan;
 
 
@@ -25,16 +24,20 @@
 	}
 
 	private void newIndex(LuanStateImpl luan,Object t,Object key,Object value) throws LuanException {
-		LuanBit bit = luan.bit(el());
-		if( t instanceof LuanTable ) {
-			LuanTable tbl = (LuanTable)t;
-			bit.put(tbl,key,value);
-			return;
+		luan.push(el,null);
+		try {
+			if( t instanceof LuanTable ) {
+				LuanTable tbl = (LuanTable)t;
+				tbl.put(luan,key,value);
+				return;
+			}
+			if( t != null && luan.hasJava() )
+				JavaLuan.__new_index(luan,t,key,value);
+			else
+				throw luan.exception( "attempt to index a " + Luan.type(t) + " value in '"+el.text()+"'" );
+		} finally {
+			luan.pop();
 		}
-		if( t != null && luan.hasJava() )
-			JavaLuan.__new_index(bit,t,key,value);
-		else
-			throw bit.exception( "attempt to index a " + Luan.type(t) + " value in '"+bit.el.text()+"'" );
 	}
 
 }
--- a/core/src/luan/impl/UnmExpr.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/UnmExpr.java	Mon Jul 13 20:38:26 2015 -0600
@@ -4,7 +4,6 @@
 import luan.LuanFunction;
 import luan.LuanException;
 import luan.LuanElement;
-import luan.LuanBit;
 import luan.LuanTable;
 
 
@@ -19,13 +18,17 @@
 		Object o = op.eval(luan);
 		if( o instanceof Number )
 			return -((Number)o).doubleValue();
-		LuanBit bit = luan.bit(el);
-		if( o instanceof LuanTable ) {
-			LuanFunction fn = bit.getHandlerFunction("__unm",(LuanTable)o);
-			if( fn != null ) {
-				return Luan.first(bit.call(fn,"__unm",new Object[]{o}));
+		luan.push(el,null);
+		try {
+			if( o instanceof LuanTable ) {
+				LuanFunction fn = luan.getHandlerFunction("__unm",(LuanTable)o);
+				if( fn != null ) {
+					return Luan.first(fn.call(luan,new Object[]{o}));
+				}
 			}
+			throw luan.exception("attempt to perform arithmetic on a "+Luan.type(o)+" value");
+		} finally {
+			luan.pop();
 		}
-		throw bit.exception("attempt to perform arithmetic on a "+Luan.type(o)+" value");
 	}
 }
--- a/core/src/luan/impl/WhileStmt.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/impl/WhileStmt.java	Mon Jul 13 20:38:26 2015 -0600
@@ -17,7 +17,7 @@
 
 	@Override public void eval(LuanStateImpl luan) throws LuanException {
 		try {
-			while( luan.bit(el).checkBoolean( cnd.eval(luan) ) ) {
+			while( luan.checkBoolean( cnd.eval(luan), el ) ) {
 				doStmt.eval(luan);
 			}
 		} catch(BreakException e) {}
--- a/core/src/luan/modules/BinaryLuan.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/modules/BinaryLuan.java	Mon Jul 13 20:38:26 2015 -0600
@@ -6,7 +6,6 @@
 import luan.LuanFunction;
 import luan.LuanException;
 import luan.LuanMethod;
-import luan.LuanBit;
 
 
 public final class BinaryLuan {
--- a/core/src/luan/modules/JavaLuan.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/modules/JavaLuan.java	Mon Jul 13 20:38:26 2015 -0600
@@ -23,7 +23,6 @@
 import luan.LuanFunction;
 import luan.LuanJavaFunction;
 import luan.LuanElement;
-import luan.LuanBit;
 
 
 public final class JavaLuan {
@@ -141,8 +140,7 @@
 		}
 	}
 
-	public static void __new_index(LuanBit bit,Object obj,Object key,Object value) throws LuanException {
-		LuanState luan = bit.luan;
+	public static void __new_index(LuanState luan,Object obj,Object key,Object value) throws LuanException {
 		checkJava(luan);
 		Class cls;
 		if( obj instanceof Static ) {
@@ -179,10 +177,7 @@
 				}
 			}
 		}
-		if( bit.el != null )
-			throw bit.exception( "invalid index for java "+cls+" in '"+bit.el.text()+"'" );
-		else
-			throw bit.exception( "invalid index for java "+cls );
+		throw luan.exception( "invalid index for java "+cls+" in '"+luan.context()+"'" );
 	}
 
 	private static void setMember(Object obj,List<Member> members,Object value) {
--- a/core/src/luan/modules/StringLuan.java	Mon Jul 13 18:34:31 2015 -0600
+++ b/core/src/luan/modules/StringLuan.java	Mon Jul 13 20:38:26 2015 -0600
@@ -10,7 +10,6 @@
 import luan.LuanElement;
 import luan.LuanException;
 import luan.LuanMethod;
-import luan.LuanBit;
 
 
 public final class StringLuan {