view core/src/luan/LuanState.java @ 579:f22a09e98b04

clean up LuanState
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 16 Jul 2015 15:14:31 -0600
parents 60c549d43988
children 859c0dedc8b6
line wrap: on
line source

package luan;

import java.io.Closeable;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import luan.impl.LuanCompiler;
import luan.modules.BasicLuan;
import luan.modules.JavaLuan;


public abstract class LuanState implements DeepCloneable {

	protected final List<StackTraceElement> stackTrace = new ArrayList<StackTraceElement>();

	private Map registry;
	private final List<Reference<Closeable>> onClose = new ArrayList<Reference<Closeable>>();

	protected LuanState() {
		registry = new HashMap();
	}

	protected LuanState(LuanState luan) {}

	@Override public void deepenClone(DeepCloneable clone,DeepCloner cloner) {
		((LuanState)clone).registry = cloner.deepClone(registry);
	}

	public abstract boolean hasJava();
	public abstract void setJava();
	public abstract LuanSource currentSource();

	public final Map registry() {
		return registry;
	}

	public void onClose(Closeable c) {
		onClose.add(new WeakReference<Closeable>(c));
	}

	public void close() throws IOException {
		for( Reference<Closeable> ref : onClose ) {
			Closeable c = ref.get();
			if( c != null )
				c.close();
		}
		onClose.clear();
	}

	public static LuanState newInstance() {
		return LuanCompiler.newLuanState();
	}

	public final Object eval(String cmd) throws LuanException {
		return eval(cmd,new LuanTable());
	}

	public final Object eval(String cmd,LuanTable env) throws LuanException {
		LuanFunction fn = BasicLuan.load(this,cmd,"eval",env,true);
		return fn.call(this);
	}


	public Boolean checkBoolean(Object obj) throws LuanException {
		if( obj instanceof Boolean )
			return (Boolean)obj;
		throw new LuanException(this, "attempt to use '"+context()+"' (a " + Luan.type(obj) + " value) as a boolean" );
	}

	public String checkString(Object obj) throws LuanException {
		if( obj instanceof String )
			return (String)obj;
		throw new LuanException(this, "attempt to use '"+context()+"' (a " + Luan.type(obj) + " value) as a string" );
	}

	public LuanFunction checkFunction(Object obj) throws LuanException {
		if( obj instanceof LuanFunction )
			return (LuanFunction)obj;
		throw new LuanException(this, "attempt to call '"+context()+"' (a " + Luan.type(obj) + " value)" );
	}

	abstract public boolean isLessThan(Object o1,Object o2) throws LuanException;

	public String toString(Object obj) throws LuanException {
		if( obj instanceof LuanTable ) {
			LuanTable tbl = (LuanTable)obj;
			return tbl.toString(this);
		}
		if( obj == null )
			return "nil";
		if( obj instanceof Number )
			return Luan.toString((Number)obj);
		if( obj instanceof byte[] )
			return "binary: " + Integer.toHexString(obj.hashCode());
		return obj.toString();
	}

	public Object index(Object obj,Object key) throws LuanException {
		if( obj instanceof LuanTable ) {
			LuanTable tbl = (LuanTable)obj;
			return tbl.get(this,key);
		}
		if( obj != null && hasJava() )
			return JavaLuan.__index(this,obj,key,false);
		throw new LuanException(this, "attempt to index a " + Luan.type(obj) + " value in '"+context()+"'" );
	}

	public String context() {
		return stackTrace.get(stackTrace.size()-1).call.text();
	}

	public void dumpStack() {
		System.err.println( stackTrace );
	}
/*
	public Number checkNumber(Object obj) throws LuanException {
		if( obj instanceof Number )
			return (Number)obj;
		throw new LuanException(this, "attempt to perform arithmetic on '"+context()+"' (a " + Luan.type(obj) + " value)" );
	}
*/
}