diff src/luan/interp/LuaStateImpl.java @ 37:8a57ebfdfd78

add JavaLib git-svn-id: https://luan-java.googlecode.com/svn/trunk@38 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Thu, 20 Dec 2012 02:36:07 +0000
parents 2a35154aec14
children e3624b7cd603
line wrap: on
line diff
--- a/src/luan/interp/LuaStateImpl.java	Tue Dec 18 09:53:42 2012 +0000
+++ b/src/luan/interp/LuaStateImpl.java	Thu Dec 20 02:36:07 2012 +0000
@@ -1,21 +1,25 @@
 package luan.interp;
 
+import java.util.List;
+import java.util.ArrayList;
 import luan.Lua;
 import luan.LuaState;
 import luan.LuaTable;
 import luan.LuaFunction;
+import luan.MetatableGetter;
 import luan.LuaException;
 
 
 final class LuaStateImpl implements LuaState {
 	private final LuaTable global = new LuaTable();
+	private final List<MetatableGetter> mtGetters = new ArrayList<MetatableGetter>();
 
 	@Override public LuaTable global() {
 		return global;
 	}
 
 	@Override public String toString(Object obj) throws LuaException {
-		LuaFunction fn = Utils.getHandlerFunction("__tostring",obj);
+		LuaFunction fn = getHandlerFunction("__tostring",obj);
 		if( fn != null )
 			return Lua.checkString( Utils.first( fn.call(this,obj) ) );
 		if( obj == null )
@@ -23,6 +27,51 @@
 		return obj.toString();
 	}
 
+	@Override public 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 void addMetatableGetter(MetatableGetter mg) {
+		mtGetters.add(mg);
+	}
+
+	Object getHandler(String op,Object obj) throws LuaException {
+		LuaTable t = getMetatable(obj);
+		return t==null ? null : t.get(op);
+	}
+
+	LuaFunction getHandlerFunction(String op,Object obj) throws LuaException {
+		Object f = getHandler(op,obj);
+		if( f == null )
+			return null;
+		return Lua.checkFunction(f);
+	}
+
+	LuaFunction getBinHandler(String op,Object o1,Object o2) throws LuaException {
+		LuaFunction f1 = getHandlerFunction(op,o1);
+		if( f1 != null )
+			return f1;
+		return getHandlerFunction(op,o2);
+	}
+
+	final Object arithmetic(String op,Object o1,Object o2) throws LuaException {
+		LuaFunction fn = getBinHandler(op,o1,o2);
+		if( fn != null )
+			return Utils.first(fn.call(this,o1,o2));
+		String type = Lua.toNumber(o1)==null ? Lua.type(o1) : Lua.type(o2);
+		throw new LuaException("attempt to perform arithmetic on a "+type+" value");
+	}
+
+
 	private static class Frame {
 		final Frame previousFrame;
 		final LuaClosure closure;