package openmods.calc; import openmods.utils.Stack; public abstract class UnaryOperator<E> extends Operator<E> { private UnaryOperator(String id) { super(id); } public abstract static class Direct<E> extends UnaryOperator<E> { public Direct(String id) { super(id); } public abstract E execute(E value); @Override public final void execute(Frame<E> frame) { final Stack<E> stack = frame.stack(); final E value = stack.pop(); final E result = execute(value); stack.push(result); } } public abstract static class Scoped<E> extends UnaryOperator<E> { public Scoped(String id) { super(id); } public abstract E execute(SymbolMap<E> symbols, E value); @Override public final void execute(Frame<E> frame) { final Stack<E> stack = frame.stack(); final E value = stack.pop(); final E result = execute(frame.symbols(), value); stack.push(result); } } public abstract static class StackBased<E> extends UnaryOperator<E> { public StackBased(String id) { super(id); } public abstract void executeOnStack(Frame<E> frame); @Override public final void execute(Frame<E> frame) { final Frame<E> executionFrame = FrameFactory.newLocalFrameWithSubstack(frame, 1); executeOnStack(executionFrame); executionFrame.stack().checkSizeIsExactly(1); } } @Override public boolean isLessThan(Operator<E> other) { return false; // every other operator has lower or equal precendence } @Override public String toString() { return "UnaryOperator [" + id + "]"; } }