diff src/luan/LuaState.java @ 40:e3624b7cd603

implement stack trace git-svn-id: https://luan-java.googlecode.com/svn/trunk@41 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Fri, 21 Dec 2012 10:45:54 +0000
parents 8a57ebfdfd78
children 786699c78837
line wrap: on
line diff
--- a/src/luan/LuaState.java	Thu Dec 20 02:54:06 2012 +0000
+++ b/src/luan/LuaState.java	Fri Dec 21 10:45:54 2012 +0000
@@ -1,9 +1,83 @@
 package luan;
 
+import java.util.List;
+import java.util.ArrayList;
+
 
-public interface LuaState {
-	public LuaTable global();
-	public String toString(Object obj) throws LuaException;
-	public LuaTable getMetatable(Object obj);
-	public void addMetatableGetter(MetatableGetter mg);
+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 LuaNumber checkNumber(LuaElement el,Object obj) throws LuaException {
+		LuaNumber 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";
+		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);
+	}
+
 }