(* Test whether the keyword XXXX may be used as an identifier for:
 * variable name/identifier
 *
 * The XXXX names in the following code are merely a placeholder.
 * They will be replaced by several identifiers before actual testing
 * of the compiler.
 *)

(* The identifiers that will replace the XXXX
 * must be placed on a line starting with #
 * All identifiers preceded by # are ignored!
 * The identifier list must be placed inside an IEC 61131-3 comment.
 *)
(*
#IL_operators ANDN CAL CALC CALCN CD CLK CU IN JMP JMPC JMPCN LD LDN ORN PT PV R R1 RET RETC RETCN S S1 ST STN XORN
#SFC_qualifiers D DS L N P #R #S SD SL
     NOTE: R and S are identical to IL operators!!
#Task_initialisers PRIORITY SINGLE INTERVAL
*)

(* NOTE: The identifier as a variable test has some special cases.
 *       Namely, when using IL operators as variable names.
 *       Even though the syntax of the IL language would not result
 *       in ambiguities in the above case, our parser does not currently
 *       allow the use of variables (with names identical to IL
 *       operators) within IL code.
 *
 *       The following test code must therefore consider two possibilities:
 *        - if the identifier under test is an IL operator
 *        - if the identifier under test is not an IL operator
 * 
 *       The test code in this file should be valid for all identifiers.
 *       Test code that is only valid for identifiers not identical to IL operators 
 *        is placed in another test file (identifier_as_variable2.test).
 *)




(* A helper FUNCTION BLOCK declaration *)
function_block foo_fb
 var_input
  a_1, b_1: real;
 end_var
 var_output
  c_1, d_1: real;
 end_var
  c_1 := 10.0 + b_1;
end_function_block


(* A helper FUNCTION declaration *)
function foo_f1 : real
 var_input
  a_1, b_1: real;
 end_var
 var_output
  c_1, d_1: real;
 end_var
  c_1 := 10.0 + b_1;
end_function

(* Another helper FUNCTION declaration *)
function foo_f2 :real 
 var_input
  a_1, b_1: foo_fb;
 end_var
 var_output
  c_1, d_1: real;
 end_var
  c_1 := 10.0;
end_function



(*********************************************************************)
(* Testing use of XXXX in several locations of variable declarations *)
(*********************************************************************)

function bar01 : real
 var_input
  XXXX, a_1, b_1: real;
 end_var
 a_1 := 1.0;
end_function

function_block bar02
 var_input
   a_1, XXXX, b_1: int;
 end_var
 a_1 := 1;
end_function_block

function_block bar03
 var_input
   a_1, b_1, XXXX: int;
 end_var
 a_1 := 1;
end_function_block


function_block bar04
 var_output
  XXXX, a_1, b_1: int;
 end_var
 a_1 := 1;
end_function_block

function_block bar05
 var_output
   a_1, XXXX, b_1: int;
 end_var
 a_1 := 1;
end_function_block

function_block bar06
 var_output
   a_1, b_1, XXXX: int;
 end_var
 a_1 := 1;
end_function_block


function_block bar07
 var_in_out
  XXXX, a_1, b_1: int;
 end_var
 a_1 := 1;
end_function_block

function_block bar08
 var_in_out
   a_1, XXXX, b_1: int;
 end_var
 a_1 := 1;
end_function_block

function_block bar09
 var_in_out
   a_1, b_1, XXXX: int;
 end_var
 a_1 := 1;
end_function_block

function_block bar10
 var_external
   XXXX: int;
   a_1 : int;
 end_var
 a_1 := 1;
end_function_block

function_block bar11
 var_external
   a_1 : int;
   XXXX : int;
 end_var
 a_1 := 1;
end_function_block

function_block bar12
 var
  XXXX, a_1, b_1: int;
 end_var
 a_1 := 1;
end_function_block

function_block bar13
 var
   a_1, XXXX, b_1: int;
 end_var
 a_1 := 1;
end_function_block

function_block bar14
 var
   a_1, b_1, XXXX: int;
 end_var
 a_1 := 1;
end_function_block



(************************************************)
(* Using XXXX as a standard variable name in ST *)
(************************************************)

function_block bar90
 var
  e_1, f_1 : real;
  XXXX : real;
  fb : foo_fb;
 end_var
  e_1 := bar01 (XXXX := 10.0);
  e_1 := bar01 (a_1 := XXXX);
  e_1 := bar01 (XXXX := XXXX);
  fb(XXXX, 20.0);
  fb (10.0, XXXX, e_1, f_1);
  fb (a_1 := XXXX, b_1:=XXXX, c_1=>XXXX, d_1=>f_1);
  fb(a_1 := 10.0, b_1:=20.0, c_1=>e_1, d_1=>XXXX);
  fb (c_1=>XXXX, a_1:=20.0, d_1=>f_1);
  XXXX := fb.c_1;
  fb.a_1 := XXXX + XXXX * 2.0 * (XXXX) / foo_f1(XXXX, 10.0, XXXX, e_1) / XXXX ** XXXX;
  IF (XXXX >= 10.0) THEN XXXX := 10.0; END_IF;
end_function_block


function_block bar90a
 var
  e_1, f_1 : int;
  XXXX : int;
 end_var
  XXXX := XXXX MOD XXXX;
  CASE (XXXX + 10) OF
    10: XXXX := 10; 
    10..20:XXXX := 20;
    ELSE XXXX := 20;
  END_CASE;
  FOR XXXX := 10 TO 20 BY 2 DO
    XXXX := XXXX + 1;
  END_FOR;
  FOR e_1 := XXXX TO 20 DO
    XXXX := XXXX + 1;
  END_FOR;
  FOR e_1 := 10 TO XXXX BY 2 DO
    XXXX := XXXX + 1;
  END_FOR;
  FOR e_1 := 10 TO XXXX DO
    XXXX := XXXX + 1;
  END_FOR;
  FOR e_1 := 10 TO 20 BY XXXX DO
    XXXX := XXXX + 1;
  END_FOR;
  WHILE (XXXX >= 10) DO 
    XXXX := 10; 
  END_WHILE;
  REPEAT XXXX := 10; UNTIL (XXXX >= 10) END_REPEAT;
end_function_block



(* Using XXXX as a function block instance/variable name in ST *)

function_block bar91
 var
  e_1, f_1 : real;
  XXXX : foo_fb;
 end_var
  XXXX(e_1, 20.0);
  XXXX (10.0, e_1, e_1, f_1);
  XXXX (a_1 := e_1, b_1:=e_1 , c_1=>e_1, d_1=>f_1);
  XXXX(a_1 := 10.0, b_1:=20.0, c_1=>e_1, d_1=>e_1);
  XXXX (c_1=>e_1, a_1:=20.0, d_1=>f_1);
  e_1 := XXXX.c_1;
  XXXX.a_1 := e_1;
  e_1 := foo_f2(XXXX, XXXX, e_1, f_1);
  e_1 := foo_f2 (XXXX, XXXX);
  e_1 := foo_f2 (c_1 => e_1, b_1 := XXXX, d_1 := 10.0, a_1 := XXXX);
  e_1 := foo_f2 (b_1 := XXXX);
end_function_block




(************************************************)
(* Using XXXX as a standard variable name in IL *)
(************************************************)

(* NOTE: Currently not supported for identifiers identical to IL operators.
 *       We therefore have two versions of this file, one with the following code
 *       commented out (used to test the identifiers that clash with IL operators)
 *       and a second with the following code included (used to test identifiers
 *       that do not clash with IL operators, such as PRIORITY, SINGLE, etc...)
 *)


(*
function_block bar93
 var
  e_1, f_1 : int;
 end_var

 (* Calling function with input parameter named XXXX **
 bar01 (
  XXXX := 10
 )
end_function_block
*)


(*
function_block bar99
(...)
end_function_block
*)






(*************************************************************************************)
(* Using XXXX as a function block instance/variable/program name in a configuration. *)
(*************************************************************************************)

(* a helper program *)
PROGRAM bar000
VAR_INPUT
  a_1, XXXX : BOOL;
END_VAR
VAR_OUTPUT
  b_1 : BOOL;
END_VAR
  a_1 := TRUE;
END_PROGRAM


 (* using in program parameter *)
CONFIGURATION config01
 TASK fast(PRIORITY := 4);
 PROGRAM foo WITH fast:
       bar000(a_1 := TRUE, XXXX := FALSE);
END_CONFIGURATION


 (* using as a program name *)
CONFIGURATION config02
 TASK fast(PRIORITY := 4);
 PROGRAM XXXX WITH fast:
       bar000(a_1 := TRUE, XXXX := FALSE);
END_CONFIGURATION


 (* using as a resource name *)
CONFIGURATION config03
 RESOURCE XXXX on processor_type_1
   TASK fast(PRIORITY := 4);
   PROGRAM foo WITH fast:
           bar000(a_1 := TRUE, XXXX := FALSE);
 END_RESOURCE
END_CONFIGURATION


 (* using as a task name *)
CONFIGURATION config11
 TASK XXXX(PRIORITY := 4);
 PROGRAM foo WITH XXXX:
       bar000(a_1 := TRUE, XXXX := FALSE);
END_CONFIGURATION


CONFIGURATION config12
 TASK XXXX(SINGLE := 3, PRIORITY := 4);
 PROGRAM P1 WITH XXXX:
       bar000(a_1 := TRUE, XXXX := FALSE);
END_CONFIGURATION


CONFIGURATION config13
 TASK XXXX(INTERVAL := T#1s, PRIORITY := 4);
 PROGRAM P1 WITH XXXX:
       bar000(a_1 := TRUE, XXXX := FALSE);
END_CONFIGURATION


CONFIGURATION config14
 TASK XXXX(SINGLE := 3, INTERVAL := T#1s, PRIORITY := 4);
 PROGRAM P1 WITH XXXX:
       bar000(a_1 := TRUE, XXXX := FALSE);
END_CONFIGURATION


 (* using as a variable name *)
CONFIGURATION config21
 VAR_GLOBAL
  XXXX : bool;
 END_VAR
 TASK fast(PRIORITY := 4);
 PROGRAM foo WITH fast:
       bar000(a_1 := XXXX, b_1 => XXXX, XXXX := XXXX);
END_CONFIGURATION












(* Checking whether the use of XXXX will confuse any other
 * normal and correct IL or ST code.
 *)
{#include "basic_code.test" }

