Mercurial Hosting > nabble
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(); + } + +}