// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) space 
// 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
{

    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);
    }

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