package openmods.calc; import openmods.utils.Stack; public class Environment<E> { public static final String VAR_ANS = "_ans"; private final Frame<E> topFrame = createTopMap(); private final E nullValue; public Environment(E nullValue) { this.nullValue = nullValue; } protected Frame<E> createTopMap() { return FrameFactory.createTopFrame(); } public E nullValue() { return nullValue; } public void setGlobalSymbol(String name, ISymbol<E> symbol) { topFrame.symbols().put(name, symbol); } public void setGlobalSymbol(String name, ICallable<E> callable) { topFrame.symbols().put(name, callable); } public void setGlobalSymbol(String name, IGettable<E> gettable) { topFrame.symbols().put(name, gettable); } public void setGlobalSymbol(String name, E value) { topFrame.symbols().put(name, value); } public Frame<E> topFrame() { return topFrame; } public Frame<E> executeIsolated(IExecutable<E> executable) { final Frame<E> freshFrame = FrameFactory.newLocalFrame(topFrame); executable.execute(freshFrame); return freshFrame; } public void execute(IExecutable<E> executable) { executable.execute(topFrame); } public E executeAndPop(IExecutable<E> executable) { executable.execute(topFrame); final Stack<E> stack = topFrame.stack(); if (stack.isEmpty()) { topFrame.symbols().put(VAR_ANS, nullValue); return null; } else { final E result = stack.pop(); topFrame.symbols().put(VAR_ANS, result); return result; } } }