view src/nabble/naml/compiler/MacroNamespace.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
line wrap: on
line source

package nabble.naml.compiler;

import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;


final class MacroNamespace implements GenericNamespace {
	private final Macro macro;
	private final List<String> names = new ArrayList<String>();

	MacroNamespace(Macro macro,StackTrace stackTrace,Map<String,List<Macro>> macros)
		throws CompileException
	{
		this.macro = macro;
		while(true) {
			names.add(macro.name);
			if( macro.extendsNs == null )
				break;
			stackTrace.push( new StackTraceElement(macro) );
			try {
				List<Macro> candidates = macros.get(macro.extendsNs);
				if( candidates==null )
					throw new CompileException(stackTrace,"'extend' namespace not found: "+macro.extendsNs);
				for( Iterator<Macro> iter = candidates.iterator(); iter.hasNext(); ) {
					Macro m = iter.next();
					if( m.type != Macro.Type.NAMESPACE )
						iter.remove();
				}
				if( candidates.size() == 0 )
					throw new CompileException(stackTrace,"'extend' namespace not found: "+macro.extendsNs);
				if( candidates.size() > 1 )
					throw new CompileException(stackTrace,"duplicate 'extend' namespaces: "+candidates);
				macro = candidates.get(0);
			} finally {
				stackTrace.pop();
			}
		}
	}

	@Override public boolean isGlobal() {
		return true;
	}

	@Override public boolean isTransparent() {
		return false;
	}

	@Override public List<String> names() {
		return names;
	}

	@Override public String getId() {
		return macro.getId();
	}

	@Override public boolean equals(Object obj) {
		if( !(obj instanceof MacroNamespace) )
			return false;
		MacroNamespace ns = (MacroNamespace)obj;
		return names.equals(ns.names);
	}

	@Override public int hashCode() {
		return names.hashCode();
	}

	@Override public String toString() {
		return names.get(0);
	}
}