changeset 405:3e68917a0dc6

add LuanMeta
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 29 Apr 2015 11:10:11 -0600
parents d55e873e1f0d
children 9321a33b9b1c
files core/src/luan/AbstractLuanTable.java core/src/luan/LuanMeta.java core/src/luan/impl/IndexExpr.java core/src/luan/impl/SetTableEntry.java lucene/src/luan/modules/lucene/FieldTable.java web/src/luan/modules/web/HttpServicer.java
diffstat 6 files changed, 113 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/AbstractLuanTable.java	Wed Apr 29 07:04:40 2015 -0600
+++ b/core/src/luan/AbstractLuanTable.java	Wed Apr 29 11:10:11 2015 -0600
@@ -14,7 +14,7 @@
 import java.util.regex.Pattern;
 
 
-public abstract class AbstractLuanTable implements LuanTable, LuanRepr {
+abstract class AbstractLuanTable implements LuanTable, LuanRepr {
 
 	protected final Map<Object,Object> newMap() {
 		return new LinkedHashMap<Object,Object>();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/src/luan/LuanMeta.java	Wed Apr 29 11:10:11 2015 -0600
@@ -0,0 +1,48 @@
+package luan;
+
+import java.util.Map;
+
+
+public abstract class LuanMeta /*implements Iterable<Map.Entry<Object,Object>>*/ {
+
+	public abstract Object __index(LuanState luan,LuanTable tbl,Object key) throws LuanException;
+
+//	public abstract LuanFunction __pairs(LuanState luan,LuanTable tbl) throws LuanException;
+
+	public boolean canNewindex() {
+		return false;
+	}
+
+	public void __newindex(LuanState luan,LuanTable tbl,Object key,Object value) throws LuanException {
+		throw new UnsupportedOperationException();
+	}
+
+	public LuanTable newMetatable() {
+		LuanTable mt = new LuanTableImpl();
+/*
+		try {
+			mt.put( "__index", new LuanJavaFunction(
+				LuanMeta.class.getMethod( "__index", LuanState.class, LuanTable.class, Object.class ), this
+			) );
+			if( canNewindex() ) {
+				mt.put( "__newindex", new LuanJavaFunction(
+					LuanMeta.class.getMethod( "__newindex", LuanState.class, LuanTable.class, Object.class, Object.class ), mt
+				) );
+			}
+		} catch(NoSuchMethodException e) {
+			throw new RuntimeException(e);
+		}
+*/
+		mt.put( "__index", this );
+//		mt.put( "__pairs", this );
+		if( canNewindex() )
+			mt.put( "__newindex", this );
+		return mt;
+	}
+
+	public LuanTable newTable() {
+		LuanTable tbl = new LuanTableImpl();
+		tbl.setMetatable( newMetatable() );
+		return tbl;
+	}
+}
--- a/core/src/luan/impl/IndexExpr.java	Wed Apr 29 07:04:40 2015 -0600
+++ b/core/src/luan/impl/IndexExpr.java	Wed Apr 29 11:10:11 2015 -0600
@@ -5,6 +5,7 @@
 import luan.LuanTable;
 import luan.LuanFunction;
 import luan.LuanSource;
+import luan.LuanMeta;
 import luan.modules.StringLuan;
 import luan.modules.BinaryLuan;
 import luan.modules.JavaLuan;
@@ -33,6 +34,10 @@
 				LuanFunction fn = (LuanFunction)h;
 				return Luan.first(luan.bit(se).call(fn,"__index",new Object[]{tbl,key}));
 			}
+			if( h instanceof LuanMeta ) {
+				LuanMeta meta = (LuanMeta)h;
+				return meta.__index(luan,tbl,key);
+			}
 			return index(luan,h,key);
 		}
 		if( obj instanceof String )
--- a/core/src/luan/impl/SetTableEntry.java	Wed Apr 29 07:04:40 2015 -0600
+++ b/core/src/luan/impl/SetTableEntry.java	Wed Apr 29 11:10:11 2015 -0600
@@ -5,6 +5,7 @@
 import luan.Luan;
 import luan.LuanFunction;
 import luan.LuanSource;
+import luan.LuanMeta;
 import luan.modules.JavaLuan;
 
 
@@ -41,6 +42,11 @@
 				luan.bit(se).call(fn,"__newindex",new Object[]{t,key,value});
 				return;
 			}
+			if( h instanceof LuanMeta ) {
+				LuanMeta meta = (LuanMeta)h;
+				meta.__newindex(luan,table,key,value);
+				return;
+			}
 			newindex(luan,h,key,value);
 		}
 		if( !JavaLuan.__newindex(luan,t,key,value) )
--- a/lucene/src/luan/modules/lucene/FieldTable.java	Wed Apr 29 07:04:40 2015 -0600
+++ b/lucene/src/luan/modules/lucene/FieldTable.java	Wed Apr 29 11:10:11 2015 -0600
@@ -4,10 +4,12 @@
 import java.util.HashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.Iterator;
-import luan.AbstractLuanTable;
+import luan.LuanState;
+import luan.LuanTable;
+import luan.LuanMeta;
 
 
-class FieldTable extends AbstractLuanTable {
+class FieldTable extends LuanMeta {
 	final Map<String,String> map = new ConcurrentHashMap<String,String>();
 	final Map<String,String> reverseMap = new ConcurrentHashMap<String,String>();
 
@@ -16,7 +18,15 @@
 		put("id","id index");
 	}
 
-	@Override public void put(Object key,Object value) {
+	@Override public boolean canNewindex() {
+		return true;
+	}
+
+	@Override public void __newindex(LuanState luan,LuanTable tbl,Object key,Object value) {
+		put(key,value);
+	}
+
+	private void put(Object key,Object value) {
 		if( !(key instanceof String) )
 			throw new UnsupportedOperationException("key must be string");
 		String name = (String)key;
@@ -38,10 +48,11 @@
 		}
 	}
 
-	@Override public final Object get(Object key) {
+	@Override public Object __index(LuanState luan,LuanTable tbl,Object key) {
+//	@Override public final Object get(Object key) {
 		return map.get(key);
 	}
-
+/*
 	@Override public final Iterator<Map.Entry<Object,Object>> iterator() {
 		return new HashMap<Object,Object>(map).entrySet().iterator();
 	}
@@ -49,4 +60,5 @@
 	@Override protected String type() {
 		return "lucene-field-table";
 	}
+*/
 }
--- a/web/src/luan/modules/web/HttpServicer.java	Wed Apr 29 07:04:40 2015 -0600
+++ b/web/src/luan/modules/web/HttpServicer.java	Wed Apr 29 11:10:11 2015 -0600
@@ -26,7 +26,7 @@
 import luan.LuanElement;
 import luan.LuanException;
 import luan.LuanTable;
-import luan.AbstractLuanTable;
+import luan.LuanMeta;
 import luan.LuanJavaFunction;
 import luan.LuanExitException;
 import luan.LuanProperty;
@@ -120,7 +120,7 @@
 	private LuanTable requestTable() throws NoSuchMethodException {
 		LuanTable tbl = Luan.newPropertyTable();
 		tbl.put("java",request);
-		LuanTable parameters = new NameTable() {
+		LuanTable parameters = new NameMeta() {
 
 			@Override Object get(String name) {
 				String[] a = request.getParameterValues(name);
@@ -130,13 +130,14 @@
 			@Override Iterator<String> names() {
 				return new EnumerationIterator<String>(request.getParameterNames());
 			}
-
+/*
 			@Override protected String type() {
 				return "request.parameters-table";
 			}
-		};
+*/
+		}.newTable();
 		tbl.put( "parameters", parameters );
-		LuanTable headers = new NameTable() {
+		LuanTable headers = new NameMeta() {
 
 			@Override Object get(String name) {
 				return request.getHeader(name);
@@ -145,11 +146,12 @@
 			@Override Iterator<String> names() {
 				return new EnumerationIterator<String>(request.getHeaderNames());
 			}
-
+/*
 			@Override protected String type() {
 				return "request.headers-table";
 			}
-		};
+*/
+		}.newTable();
 		tbl.put( "headers", headers );
 		tbl.put( "method", new LuanProperty() { public Object get() {
 			return request.getMethod();
@@ -174,15 +176,15 @@
 		tbl.put( "remote_address", new LuanProperty() { public Object get() {
 			return request.getRemoteAddr();
 		} } );
-		LuanTable cookies = new AbstractLuanTable() {
+		LuanTable cookies = new LuanMeta() {
 
-			@Override public final Object get(Object key) {
+			@Override public Object __index(LuanState luan,LuanTable tbl,Object key) {
 				if( !(key instanceof String) )
 					return null;
 				String name = (String)key;
 				return getCookieValue(request,name);
 			}
-
+/*
 			@Override public final Iterator<Map.Entry<Object,Object>> iterator() {
 				return new Iterator<Map.Entry<Object,Object>>() {
 					final Cookie[] cookies = request.getCookies();
@@ -206,7 +208,8 @@
 			@Override protected String type() {
 				return "request.cookies-table";
 			}
-		};
+*/
+		}.newTable();
 		tbl.put( "cookies", cookies );
 
 		String contentType = request.getContentType();
@@ -268,7 +271,7 @@
 		tbl.put("java",response);
 		add( tbl, "send_redirect", String.class );
 		add( tbl, "send_error", Integer.TYPE, String.class );
-		LuanTable headers = new NameTable() {
+		LuanTable headers = new NameMeta() {
 
 			@Override Object get(String name) {
 				return response.getHeader(name);
@@ -278,7 +281,11 @@
 				return response.getHeaderNames().iterator();
 			}
 
-			@Override public void put(Object key,Object val) {
+			@Override public boolean canNewindex() {
+				return true;
+			}
+
+			@Override public void __newindex(LuanState luan,LuanTable tbl,Object key,Object val) {
 				if( !(key instanceof String) )
 					throw new IllegalArgumentException("key must be string for headers table");
 				String name = (String)key;
@@ -293,11 +300,12 @@
 				}
 				throw new IllegalArgumentException("value must be string or integer for headers table");
 			}
-
+/*
 			@Override protected String type() {
 				return "response.headers-table";
 			}
-		};
+*/
+		}.newTable();
 		tbl.put( "headers", headers );
 		tbl.put( "content_type", new LuanProperty() {
 			@Override public Object get() {
@@ -335,7 +343,7 @@
 
 	private LuanTable sessionTable() throws NoSuchMethodException {
 		LuanTable tbl = Luan.newTable();
-		LuanTable attributes = new NameTable() {
+		LuanTable attributes = new NameMeta() {
 
 			@Override Object get(String name) {
 				return request.getSession().getAttribute(name);
@@ -345,17 +353,22 @@
 				return new EnumerationIterator<String>(request.getSession().getAttributeNames());
 			}
 
-			@Override public void put(Object key,Object val) {
+			@Override public boolean canNewindex() {
+				return true;
+			}
+
+			@Override public void __newindex(LuanState luan,LuanTable tbl,Object key,Object val) {
 				if( !(key instanceof String) )
 					throw new IllegalArgumentException("key must be string for session attributes table");
 				String name = (String)key;
 				request.getSession().setAttribute(name,val);
 			}
-
+/*
 			@Override protected String type() {
 				return "session.attributes-table";
 			}
-		};
+*/
+		}.newTable();
 		tbl.put( "attributes", attributes );
 		return tbl;
 	}
@@ -524,17 +537,17 @@
 		}
 	}
 
-	private static abstract class NameTable extends AbstractLuanTable {
+	private static abstract class NameMeta extends LuanMeta {
 		abstract Object get(String name);
 		abstract Iterator<String> names();
 
-		@Override public final Object get(Object key) {
+		@Override public Object __index(LuanState luan,LuanTable tbl,Object key) {
 			if( !(key instanceof String) )
 				return null;
 			String name = (String)key;
 			return get(name);
 		}
-
+/*
 		@Override public final Iterator<Map.Entry<Object,Object>> iterator() {
 			return new Iterator<Map.Entry<Object,Object>>() {
 				Iterator<String> names = names();
@@ -552,6 +565,7 @@
 				}
 			};
 		}
+*/
 	};
 
 	private static String string(Object value) {