diff 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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nabble/naml/compiler/MacroNamespace.java	Thu Mar 21 19:15:52 2019 -0600
@@ -0,0 +1,73 @@
+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);
+	}
+}