In reply to Peter Lancashire.

Interesting question. One way to clear the queue is to execute a PAUSE, which runs the queued commands and the RESUME statement. Assuming that no error flags are set, this effectively clears the queue. You can then PUSH new code, if desired. I haven't used this trick in production code, but here's an example where I set up error handling code then "change my mind" and replace it with other code.

start InvEx(A);
errFlag = 1; /* set flag. Assume we will get an error :-) */
on_error = "if errFlag then do; AInv = .; resume; end;";
call push(on_error); /* PUSH code that will be executed if an error occurs */

/* Changed mind! Remove existing code and PUSH new code the returns .S for singular */
pause; /* executes existing code queue; RESUME clears queue */
on_error = "if errFlag then do; AInv = .S; resume; end;";
call push(on_error); /* PUSH code that will be executed if an error occurs */

AInv = inv(A); /* if error, AInv set to missing and function resumes */
errFlag = 0; /* remove flag for normal exit from module */
return ( AInv );
finish;

But I don't think you can easily 'pop' individual items in the queue. I think the queue is a monolithic unit.