Correctly identify errors when parsing erroneous code (make sure flex goes back to INITIAL state when code contains errors that do not allow determining whether ST or IL is being parsed)
FUNCTION_BLOCK STACK_INT
VAR_INPUT PUSH, POP: BOOL R_EDGE; (* Basic stack operations *)
R1 : BOOL ; (* Over-riding reset *)
IN : INT ; (* Input to be pushed *)
N : INT ; (* Maximum depth after reset *)
END_VAR
VAR_OUTPUT EMPTY : BOOL := 1 ; (* Stack empty *)
OFLO : BOOL := 0 ; (* Stack overflow *)
OUT : INT := 0 ; (* Top of stack data *)
END_VAR
VAR STK : ARRAY[0..127] OF INT; (* Internal stack *)
NI : INT :=128 ; (* Storage for N upon reset *)
PTR : INT := -1 ; (* Stack pointer *)
END_VAR
(* Function Block body *)
LD R1 (* Dispatch on operations *)
JMPC RESET
LD POP
ANDN EMPTY (* Don't pop empty stack *)
JMPC POP_STK
LD PUSH
ANDN OFLO (* Don't push overflowed stack *)
JMPC PUSH_STK
RET (* Return if no operations active *)
RESET: LD 0 (* Stack reset operations *)
ST OFLO
LD 1
ST EMPTY
LD -1
ST PTR
CAL LIMIT(MN:=1,IN:=N,MX:=128)
ST NI
JMP ZRO_OUT
POP_STK: LD 0
ST OFLO (* Popped stack is not overflowing *)
LD PTR
SUB 1
ST PTR
LT 0 (* Empty when PTR < 0 *)
ST EMPTY
JMPC ZRO_OUT
LD STK[PTR]
JMP SET_OUT
PUSH_STK: LD 0
ST EMPTY (* Pushed stack is not empty *)
LD PTR
ADD 1
ST PTR
EQ NI (* Overflow when PTR = NI *)
ST OFLO
JMPC ZRO_OUT
LD IN
ST STK[PTR] (* Push IN onto STK *)
JMP SET_OUT
ZRO_OUT: LD 0 (* OUT=0 for EMPTY or OFLO *)
SET_OUT: ST OUT
END_FUNCTION_BLOCK