// Copyright (c) 2014 IBM Corporation.

package org.crsx.runtime;

import java.util.Map;

/**
 * Meta-application implementation. 
 * 
 * <p>Used by meta-compiler.
 * 
 * @author Lionel Villard
 */
public class MetaApplication extends Term
{
	// State.

	/** Meta variable name */
	final String metaVariable;

	/** Sub terms */
	public Term[] subs;

	// Constructor

	public MetaApplication(String meta)
	{
		this.metaVariable = meta;
	}

	// Overrides
	
	@Override
	public Kind kind()
	{
		return Kind.META_APPLICATION;
	}

	@Override
	public int arity()
	{
		return subs == null ? 0 : subs.length;
	}

	@Override
	public void copy(Sink sink, boolean discard)
	{
		sink.startMetaApplication(metaVariable);

		for (int i = 0; i < arity(); i++)
			subs[i].copy(sink, discard);

		sink.endMetaApplication();
		
		if (discard)
			release();
	}

	@Override
	protected void substituteTo(Sink sink, Map<Variable, Term> substitutes)
	{
		throw new UnsupportedOperationException();
	}

	@Override
	protected boolean deepEquals(Term other, Map<Variable, Variable> renamings)
	{
		if (other.kind() == Kind.META_APPLICATION)
		{
			final MetaApplication meta = (MetaApplication) other;

			if (!meta.metaVariable.equals(metaVariable))
				return false;

			if (meta.arity() != arity())
				return false;

			for (int i = arity() - 1; i >= 0; i--)
				if (!meta.subs[i].deepEquals(subs[i], renamings))
					return false;

			return true;
		}
		return false;
	}

	@Override
	protected void free()
	{
		for (int i = 0; i < arity(); i++)
			subs[i].release();
	}

	// Debugging

	@Override
	public String toString()
	{
		return metaVariable;
	}

	@Override
	public String toString4()
	{
		return metaVariable;
	}

}

@@ -446,17 +446,16 @@
 errides%0A
-%09
 %0A%09@Overr
@@ -592,24 +592,84 @@
 length;%0A%09%7D%0A%0A
+%09@Override%0A%09public Term sub(int i)%0A%09%7B%0A%09%09return subs%5Bi%5D;%0A%09%7D%0A%0A
 %09@Override%0A%09
@@ -858,18 +858,16 @@
 tion();%0A
-%09%09
 %0A%09%09if (d
@@ -1660,95 +1660,768 @@
 %7B%0A%09%09
-return metaVariable;%0A%09%7D%0A%0A%09@Override%0A%09public String toString4()%0A%09%7B%0A%09%09return metaVariable
+StringBuilder builder = new StringBuilder();%0A%0A%09%09builder.append(metaVariable);%0A%09%09final int arity = arity();%0A%09%09if (arity %3E 0)%0A%09%09%7B%0A%09%09%09builder.append(%22%5B%22);%0A%09%09%09for (int i = 0; i %3C arity; i++)%0A%09%09%09%7B%0A%09%09%09%09if (i != 0)%0A%09%09%09%09%09builder.append(%22, %22);%0A%0A%09%09%09%09Term sub = sub(i);%0A%09%09%09%09builder.append(sub.toString());%0A%09%09%09%7D%0A%09%09%09builder.append(%22%5D%22);%0A%09%09%7D%0A%09%09return builder.toString();%0A%09%7D%0A%0A%09@Override%0A%09public String toString4()%0A%09%7B%0A%09%09StringBuilder builder = new StringBuilder();%0A%0A%09%09builder.append(metaVariable);%0A%09%09final int arity = arity();%0A%09%09if (arity %3E 0)%0A%09%09%7B%0A%09%09%09builder.append(%22(%22);%0A%09%09%09for (int i = 0; i %3C arity; i++)%0A%09%09%09%7B%0A%09%09%09%09if (i != 0)%0A%09%09%09%09%09builder.append(%22, %22);%0A%0A%09%09%09%09Term sub = sub(i);%0A%09%09%09%09builder.append(sub.toString4());%0A%09%09%09%7D%0A%09%09%09builder.append(%22)%22);%0A%09%09%7D%0A%09%09return builder.toString()
 ;%0A%09%7D

Fix meta application toString4()