diff src/nabble/naml/compiler/RunStateImpl.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/RunStateImpl.java	Thu Mar 21 19:15:52 2019 -0600
@@ -0,0 +1,132 @@
+package nabble.naml.compiler;
+
+import fschmidt.util.java.ArrayStack;
+import fschmidt.util.java.Stack;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+final class RunStateImpl implements RunState {
+	private final Stack<Object> stack = new ArrayStack<Object>();
+	private final Template template;
+	private final int callDepth;
+	private final Map<String,String> args = new HashMap<String,String>();
+	private final Map<String,Object> namespaceMap = new HashMap<String,Object>();
+	private final Map<Class,List<JavaNamespace>> extensionMap;
+	private Encoder encoder;
+	private final Map<Macro,Stack<Map<String,String>>> varsMap = new HashMap<Macro,Stack<Map<String,String>>>();
+
+	RunStateImpl(Template template,int callDepth,Encoder encoder) {
+		this.template = template;
+		this.callDepth = callDepth;
+		this.encoder = encoder;
+		this.extensionMap = template.program().extensionMap();
+	}
+
+	public Template template() {
+		return template;
+	}
+
+	public Program program() {
+		return template.program();
+	}
+
+	public int callDepth() {
+		return callDepth;
+	}
+
+	public void putArg(String name,String value) {
+		args.put(name,value);
+	}
+
+	public String getArg(String name) {
+		return args.get(name);
+	}
+
+	public Object getNamespace(String key) {
+		return namespaceMap.get(key);
+	}
+
+	public String saveNamespace(Object namespace) {
+		String key = namespace.toString();
+		namespaceMap.put(key,namespace);
+		return key;
+	}
+
+	public Object getFromStack(int i) {
+		if( i < 0 )
+			i = stack.size() + i;
+		return stack.get(i);
+	}
+
+	public int push(Object scope) {
+		return push(stack,extensionMap,scope);
+	}
+
+	static int push(Stack<Object> stack,Map<Class,List<JavaNamespace>> extensionMap,Object scope) {
+		stack.push(scope);
+		int pushed = 1;
+		List<JavaNamespace> extensions = extensionMap.get(scope.getClass());
+		if( extensions == null )
+			return 1;
+		for( JavaNamespace extension : extensions ) {
+			try {
+				stack.push(extension.extensionConstructor.newInstance(scope));
+			} catch(InstantiationException e) {
+				throw new TemplateRuntimeException(e);
+			} catch(IllegalAccessException e) {
+				throw new TemplateRuntimeException(e);
+			} catch(InvocationTargetException e) {
+				throw Compiler.interpFix(e);
+			}
+		}
+		return 1 + extensions.size();
+	}
+
+	public void pop(int n) {
+		pop(stack,n);
+	}
+
+	static void pop(Stack<Object> stack,int n) {
+		for( ; n > 0; n-- ) {
+			stack.pop();
+		}
+	}
+
+	public boolean hasNamespace(String namespace) {
+		throw new RuntimeException("hasNamespace only works at compile-time");
+	}
+
+	public boolean isInCommandStack(String commandName) {
+		throw new RuntimeException("isInStack only works at compile-time");
+	}
+
+	public Encoder getEncoder() {
+		return encoder;
+	}
+
+	public void setEncoder(Encoder encoder) {
+		this.encoder = encoder;
+	}
+
+	public Map<String,String> getVars(Macro macro) {
+		return varsMap.get(macro).peek();
+	}
+
+	public void pushVars(Macro macro) {
+		Stack<Map<String,String>> vars = varsMap.get(macro);
+		if( vars == null ) {
+			vars = new ArrayStack<Map<String,String>>();
+			varsMap.put(macro,vars);
+		}
+		vars.push(new HashMap<String,String>());
+	}
+
+	public void popVars(Macro macro) {
+		varsMap.get(macro).pop();
+	}
+
+}