view src/luan/LuanClosure.java @ 1563:8fbcc4747091

remove LuanFunction.luan
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 09 Nov 2020 01:37:57 -0700
parents e1a13e707bf3
children c922446f53aa
line wrap: on
line source

package luan;

import luan.impl.Pointer;


public abstract class LuanClosure extends LuanFunction implements LuanCloneable, Cloneable {
	public Pointer[] upValues;
	public boolean javaOk;
	public final String sourceName;
	private LuanCloner cloner;
	private Luan luan;

	public LuanClosure(Pointer[] upValues,boolean javaOk,String sourceName) throws LuanException {
		this.upValues = upValues;
		this.javaOk = javaOk;
		this.sourceName = sourceName;
	}

	@Override public final LuanClosure shallowClone() {
		check();
		try {
			return (LuanClosure)clone();
		} catch(CloneNotSupportedException e) {
			throw new RuntimeException(e);
		}
	}

	private void check() {
		if( cloner != null ) {
			completeClone(this,cloner);
			cloner = null;
		}
	}

	private void checkLuan(Luan luan) {
		check();
		if( this.luan==null ) {
			this.luan = luan;
		} else if( this.luan != luan ) {
			throw new RuntimeException("wrong luan");
		}
	}

	@Override public final void deepenClone(LuanCloneable dc,LuanCloner cloner) {
		LuanClosure clone = (LuanClosure)dc;
		switch( cloner.type ) {
		case COMPLETE:
			completeClone(clone,cloner);
			return;
		case INCREMENTAL:
			clone.cloner = cloner;
			return;
		}
	}

	private void completeClone(LuanClosure dc,LuanCloner cloner) {
		LuanClosure clone = (LuanClosure)dc;
		clone.upValues = (Pointer[])cloner.clone(upValues);
		clone.luan = (Luan)cloner.clone(luan);
	}

	@Override public final void makeImmutable(LuanImmutabler immutabler) throws LuanException {
		immutabler.makeImmutable(upValues);
	}

	@Override public final Object call(Luan luan,Object... args) throws LuanException {
		check();
		luan.push(this);
		try {
			return doCall(luan,args);
		} catch(StackOverflowError e) {
			throw new LuanException( "stack overflow", e );
		} finally {
			luan.pop();
		}	
	}

	@Override public String toString() {
		return super.toString()+"="+sourceName;
	}

	public abstract Object doCall(Luan luan,Object[] args) throws LuanException;
}