// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) fieldsfirst 
// Source File Name:   NodeCompiler.java

package lt.monarch.function;

import lt.monarch.jasm.*;

// Referenced classes of package lt.monarch.function:
//			Node, CompiledFunctionSet, Variable

public class NodeCompiler
{

	CompiledFunctionSet cset;
	MethodBuilder method;
	ConstantPool constants;
	Variable variables[];
	int firstParameterIndex;

	public void setParameters(Variable avariable[])
	{
		setParameters((method.getFlags() & 8) != 0, method.getDescriptor(), avariable);
	}

	public void setParameters(boolean flag, String s, Variable avariable[])
	{
		variables = avariable;
		method.code.resetArguments();
		method.setName(method.getName(), s);
		if(flag)
		{
			firstParameterIndex = 0;
			method.setFlags(25);
		} else
		{
			firstParameterIndex = 1;
			method.code.reserveArguments(1);
			method.setFlags(17);
		}
		if(method.getDescriptor().charAt(1) != '[')
			method.code.reserveArguments(avariable != null ? avariable.length * 2 : 0);
		else
			method.code.reserveArguments(1);
	}

	public CompiledFunctionSet functionSet()
	{
		return cset;
	}

	public void compile(Node node)
	{
		node.compile(this);
		method.code.append(175);
	}

	public void reserveStack(int i)
	{
		method.code.reserveStack(i);
	}

	public void freeStack(int i)
	{
		method.code.freeStack(i);
	}

	protected int getVariableIndex(Variable variable)
	{
		if(variables != null)
		{
			for(int i = 0; i < variables.length; i++)
				if(variables[i] == variable)
					return i;

		}
		return -1;
	}

	public void appendConst(double d)
	{
		reserveStack(2);
		method.code.append(20);
		method.code.appendInt(constants.define(d));
	}

	public void appendConst(int i)
	{
		if(i <= 5)
			method.code.append(3 + i);
		else
		if(i < 127 && i > -128)
		{
			method.code.append(16);
			method.code.append(i);
		} else
		{
			method.code.append(18);
			method.code.append(constants.define(i));
		}
	}

	public void append(int i)
	{
		method.code.append(i);
	}

	protected void appendLocalVariable(int i)
	{
		if(method.getDescriptor().charAt(1) != '[')
			appendLocalDoubleParameter(i);
		else
			appendLocalArrayParameter(i);
	}

	protected void appendLocalArrayParameter(int i)
	{
		method.code.append(42 + firstParameterIndex);
		appendConst(i);
		method.code.append(49);
	}

	protected void appendLocalDoubleParameter(int i)
	{
		i = i * 2 + firstParameterIndex;
		if(i <= 3)
		{
			method.code.append(38 + i);
		} else
		{
			method.code.append(24);
			method.code.append(i);
		}
	}

	protected void appendGlobalVariable(int i)
	{
		reserveStack(1);
		method.code.append(178);
		method.code.appendInt(constants.defineField(null, "globals", "[Llt/monarch/function/Variable;"));
		appendConst(i);
		method.code.append(50);
		appendCall("lt.monarch.function.Variable", "getValue", "()D");
		freeStack(1);
	}

	public void appendVariable(Variable variable)
	{
		reserveStack(2);
		int i = getVariableIndex(variable);
		if(i != -1)
			appendLocalVariable(i);
		else
			appendGlobalVariable(cset.getReferencedVariableIndex(variable));
	}

	public void appendStaticCall(String s, String s1, String s2)
	{
		method.code.append(184);
		method.code.appendInt(constants.defineMethod(s, s1, s2));
	}

	public void appendCall(String s, String s1, String s2)
	{
		method.code.append(182);
		method.code.appendInt(constants.defineMethod(s, s1, s2));
	}

	public NodeCompiler(CompiledFunctionSet compiledfunctionset, String s)
	{
		cset = compiledfunctionset;
		method = new MethodBuilder(cset.classBuilder.constantPool);
		constants = method.constantPool;
		method.setName(s, "()D");
		setParameters(false, "()D", null);
	}
}
