%mathpiper,def="GlobalPush;GlobalPop"

//////////////////////////////////////////////////
/// Global stack operations on variables
//////////////////////////////////////////////////


LocalSymbols(GlobalStack, x)
[
  GlobalStack := {};

	GlobalPop(x_IsAtom) <--
	[
		Check(Length(GlobalStack)>0, "Invariant", "GlobalPop: Error: empty GlobalStack");
		MacroBind(x, PopFront(GlobalStack));
		Eval(x);
	];

	HoldArgumentNumber("GlobalPop", 1, 1);

	GlobalPop() <--
	[
		Check(Length(GlobalStack)>0, "Invariant", "GlobalPop: Error: empty GlobalStack");
		PopFront(GlobalStack);
	];

	GlobalPush(_x) <--
	[
		Push(GlobalStack, x);
		x;
	];
];

%/mathpiper



%mathpiper_docs,name="GlobalPop;GlobalPush",categories="User Functions;Lists (Operations)"
*CMD GlobalPop --- restore variables using a global stack
*CMD GlobalPush --- save variables using a global stack
*STD
*CALL
	GlobalPop(var)
	GlobalPop()
	GlobalPush(expr)

*PARMS

{var} -- atom, name of variable to restore from the stack

{expr} -- expression, value to save on the stack

*DESC

These functions operate with a global stack, currently implemented as a list that is not accessible externally (it is protected 
through {LocalSymbols}).

{GlobalPush} stores a value on the stack. {GlobalPop} removes the last pushed value from the stack. If a variable name is given, the variable is assigned, otherwise the popped value is returned.

If the global stack is empty, an error message is printed.

*E.G.

In> GlobalPush(3)
Result: 3;
In> GlobalPush(Sin(x))
Result: Sin(x);
In> GlobalPop(x)
Result: Sin(x);
In> GlobalPop(x)
Result: 3;
In> x
Result: 3;

*SEE Push, PopFront
%/mathpiper_docs