view core/src/luan/LuanMeta.java @ 428:df95199ca4c0

rename __newindex to __new_index
author Franklin Schmidt <fschmidt@gmail.com>
date Sat, 02 May 2015 20:10:31 -0600
parents dae264ad6a7b
children e3a6d9dbd694
line wrap: on
line source

package luan;

import java.util.Map;
import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;


public abstract class LuanMeta {

	public abstract Object __index(LuanState luan,LuanTable tbl,Object key) throws LuanException;

	protected abstract Iterator keys(LuanTable tbl);

	public LuanFunction __pairs(final LuanState luan,final LuanTable tbl) {
		return new LuanFunction() {
			final Iterator<Map.Entry<Object,Object>> iter1 = tbl.iterator();
			final Iterator<Object> iter2 = keys(tbl);
			final Set<Object> set = new HashSet<Object>();

			@Override public Object[] call(LuanState luan,Object[] args) throws LuanException {
				if( iter1.hasNext() ) {
					Map.Entry<Object,Object> entry = iter1.next();
					Object key = entry.getKey();
					set.add(key);
					return new Object[]{key,entry.getValue()};
				}
				while( iter2.hasNext() ) {
					Object key = iter2.next();
					if( set.add(key) ) {
						Object value = __index(luan,tbl,key);
						return new Object[]{key,value};
					}
				}
				return LuanFunction.NOTHING;
			}
		};
	}

	public boolean canNewindex() {
		return false;
	}

	public void __new_index(LuanState luan,LuanTable tbl,Object key,Object value) throws LuanException {
		throw new UnsupportedOperationException();
	}

	protected abstract String type(LuanTable tbl);

	public String __tostring(LuanState luan,LuanTable tbl) throws LuanException {
		return type(tbl) + "-" + tbl;
	}

	public LuanTable newMetatable() {
		LuanTable mt = new LuanTable();
		mt.rawPut( "__index", this );
		mt.rawPut( "__pairs", this );
		mt.rawPut( "__tostring", this );
		if( canNewindex() )
			mt.rawPut( "__new_index", this );
		return mt;
	}

	public LuanTable newTable() {
		LuanTable tbl = new LuanTable();
		tbl.setMetatable( newMetatable() );
		return tbl;
	}
}