package code.instr;

import code.lang.SystemModule;
import code.space.Computation;
import code.space.Space;
import code.stuff.Logger;
import code.stuff.Tracer;
import code.symbols.DataSymbol;
import code.symbols.Symbol;
import code.table.*;
import code.term.Term;
import code.term.TermImpl;

/**
 * Construct a term from a (root) symbol partially applied to a bunch
 * of arguments. The arguments are popped from the pre-term stack
 * (where they were pushed in reverse order). The number of arguments
 * is the second argument of the constructor.
 *
 * @author Sergio Antoy
 * @since June 17, 2003
 */

public class MakePartial implements Instruction {
    private final int root;
    private final int argsNumber;

    private static final int closureId
	= ModuleTable.getId(SystemModule.moduleName, SystemModule.closureName);

    /**
     * Constructor for the MakePartial object
     *
     * @param root       The root symbol of the partial application
     * @param modulename The module of the root symbol
     * @param argsNumber The number of arguments of the root symbol
     */
    public MakePartial(String modulename, String root, int argsNumber) {
	this.root = ModuleTable.getId(modulename, root);
	this.argsNumber = argsNumber;
    }

    public void execute(Computation computation) {
        Term[] argument = new Term[argsNumber];
        for (int i = 0; i < argsNumber; i++)
            argument[i] = (Term) Space.instance.preTerm.pop();
	Term term = new Term(root, argument);
        term = new Term(closureId, new Term[]{ term, });
        Space.instance.preTerm.push(term);

        if (Tracer.instruction) {
            Logger.logln(computation.getIdString() + ": MakePartial: " +argsNumber + " " + term);
        }
    }

    public String printAsTxtLoadable() {
        Symbol symbol = MapTable.getSymbol(root);
        return "MakePartial " + argsNumber + "  \"" + symbol.symbolName +
               "\" \"" + symbol.moduleName + "\"";
    }
}
