Mercurial Hosting > luan
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); + } + }