--- a/absyntax/absyntax.def Tue Aug 14 19:40:01 2012 +0200
+++ b/absyntax/absyntax.def Wed Aug 22 16:46:17 2012 +0200
@@ -97,6 +97,12 @@
SYM_REF0(eno_param_c)
*/
+/* A class used to identify an entry (literal, variable, etc...) in the abstract syntax tree with an invalid data type */
+/* This is only used from stage3 onwards. Stages 1 and 2 will never create any instances of invalid_type_name_c */
+SYM_REF0(invalid_type_name_c)
+
+
+
/********************/
/* 2.1.6 - Pragmas */
/********************/
@@ -158,34 +164,15 @@
* OR
* neg_literal_c -> real_literal_c
*
- * In the semantic verification and code generation stages of the compiler,
- * the integer_c is treated as a basic (undefined) data type, since an integer
- * constant may be used as a BYTE, BOOLEAN, REAL, etc..., depending on the
- * context in which it is used.
- * However, an integer_c that is preceded by a '-' may not be used
- * as an ANY_BIT data type (BYTE, BOOLEAN, WORD, ...).
- * We must therefore be able to determine, holding a simple pointer
- * to an integer_c, if that integer_c value is preceded by a '-'.
- * However, since the neg_literal_c points to the integer_c, and not
- * vice-versa, we can't determine that.
- * There are 3 simple ways of working around this:
- * - change the order of the pointers:
- * have the integer_c and real_c point to the neg_literal_c
- * - maintain the order of the pointers, and
- * add redundant info to the integer_c and real_c
+ * However, this has since been changed to...
* - replace the neg_literal_c with two distinc classes
* (neg_integer_c and neg_real_c), one for each
- * lietral type. This means that we can now treat
- * each of these classes as an unknown data type
- * just as we do with the integer_c and real_c.
- *
- * The second option is simply ugly.
- * and the first has a serious drawback: when generating code it is
- * easier to encapsulate the real or integer values inside prefix
- * and postfix symbols (e.g. NEG(<value>) - with postfix ')' )
- * if we keep the pointer order as is.
- *
- * For the above reasoning, we use the third option.
+ * lietral type.
+ *
+ * This change was done in order to ease the writing of semantic verification (stage3) code.
+ * However, that version of the code has since been replaced by a newer and better algoritm.
+ * This means the above change can now be undone, but there is really no need to undo it,
+ * so we leave it as it is.
*/
SYM_REF1(neg_real_c, exp)
SYM_REF1(neg_integer_c, exp)
@@ -223,13 +210,15 @@
/************************/
SYM_REF0(neg_time_c)
SYM_REF3(duration_c, type_name, neg, interval)
+SYM_REF5(interval_c, days, hours, minutes, seconds, milliseconds)
SYM_TOKEN(fixed_point_c)
+/*
SYM_REF2(days_c, days, hours)
SYM_REF2(hours_c, hours, minutes)
SYM_REF2(minutes_c, minutes, seconds)
SYM_REF2(seconds_c, seconds, milliseconds)
SYM_REF1(milliseconds_c, milliseconds)
-
+*/
/************************************/
/* B 1.2.3.2 - Time of day and Date */
@@ -326,7 +315,8 @@
SYM_REF2(subrange_specification_c, integer_type_name, subrange)
/* signed_integer DOTDOT signed_integer */
-SYM_REF2(subrange_c, lower_limit, upper_limit)
+/* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */
+SYM_REF2(subrange_c, lower_limit, upper_limit, unsigned long long int dimension;)
/* enumerated_type_name ':' enumerated_spec_init */
SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init)
@@ -476,8 +466,13 @@
/* record_variable '.' field_selector */
/* WARNING: input and/or output variables of function blocks
* may be accessed as fields of a structured variable!
- * Code handling a structured_variable_c must take
- * this into account!
+ * Code handling a structured_variable_c must take this into account!
+ * (i.e. that a FB instance may be accessed as a structured variable)!
+ *
+ * WARNING: Status bit (.X) and activation time (.T) of STEPS in SFC diagrams
+ * may be accessed as fields of a structured variable!
+ * Code handling a structured_variable_c must take this into account
+ * (i.e. that an SFC STEP may be accessed as a structured variable)!
*/
SYM_REF2(structured_variable_c, record_variable, field_selector)
@@ -913,18 +908,22 @@
SYM_LIST(instruction_list_c)
/* | label ':' [il_incomplete_instruction] eol_list */
-SYM_REF2(il_instruction_c, label, il_instruction)
+/* NOTE: The parameter 'prev_il_instruction' is used to point to all previous il instructions that may be executed imedaitely before this instruction.
+ * In case of an il instruction preceded by a label, this will include all IL instructions that jump to this label!
+ * It is filled in by the flow_control_analysis_c during stage 3.
+ */
+SYM_REF2(il_instruction_c, label, il_instruction, std::vector <symbol_c *> prev_il_instruction;)
/* | il_simple_operator [il_operand] */
SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand)
/* | function_name [il_operand_list] */
-/* NOTE: The parameters 'called_function_declaration' is used to pass
+/* NOTE: The parameter 'called_function_declaration', 'extensible_param_count' and 'candidate_functions' are used to pass data between the stage 3 and stage 4.
* data between the stage 3 and stage 4.
* See the comment above function_invocation_c for more details
*/
-SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
+SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count; std::vector <symbol_c *> candidate_functions;)
/* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
@@ -939,15 +938,15 @@
* | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
* | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
*/
-SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list)
+/* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
+SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration;)
/* | function_name '(' eol_list [il_param_list] ')' */
-/* NOTE: The parameters 'called_function_declaration' is used to pass
- * data between the stage 3 and stage 4.
- * See the comment above function_invocation_c for more details
- */
-SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;)
+/* NOTE: The parameter 'called_function_declaration', 'extensible_param_count' and 'candidate_functions' are used to pass data between the stage 3 and stage 4.
+ * See the comment above function_invocation_c for more details.
+ */
+SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count; std::vector <symbol_c *> candidate_functions;)
/* | il_operand_list ',' il_operand */
SYM_LIST(il_operand_list_c)
@@ -955,6 +954,15 @@
/* | simple_instr_list il_simple_instruction */
SYM_LIST(simple_instr_list_c)
+
+/* il_simple_instruction:
+ * il_simple_operation eol_list
+ * | il_expression eol_list
+ * | il_formal_funct_call eol_list
+ */
+/* NOTE: The parameter 'prev_il_instruction' is used to point to all previous il instructions that may be executed imedaitely before this instruction. */
+SYM_REF1(il_simple_instruction_c, il_simple_instruction, std::vector <symbol_c *> prev_il_instruction;)
+
/* | il_initial_param_list il_param_instruction */
SYM_LIST(il_param_list_c)
@@ -971,31 +979,36 @@
/*******************/
/* B 2.2 Operators */
/*******************/
+/* NOTE: The parameter 'called_fb_declaration' is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
+/* NOTE: The parameter 'deprecated_operation' indicates that the operation, with the specific data types being used, is currently defined
+ * in the standard as being deprecated. This variable is filled in with the correct value in stage 3 (narrow_candidate_datatypes_c)
+ * and currently only used in stage 3 (print_datatypes_error_c).
+ */
SYM_REF0(LD_operator_c)
SYM_REF0(LDN_operator_c)
SYM_REF0(ST_operator_c)
SYM_REF0(STN_operator_c)
SYM_REF0(NOT_operator_c)
-SYM_REF0(S_operator_c)
-SYM_REF0(R_operator_c)
-SYM_REF0(S1_operator_c)
-SYM_REF0(R1_operator_c)
-SYM_REF0(CLK_operator_c)
-SYM_REF0(CU_operator_c)
-SYM_REF0(CD_operator_c)
-SYM_REF0(PV_operator_c)
-SYM_REF0(IN_operator_c)
-SYM_REF0(PT_operator_c)
+SYM_REF0(S_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(R_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(S1_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(R1_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(CLK_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(CU_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(CD_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(PV_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(IN_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(PT_operator_c, symbol_c *called_fb_declaration;)
SYM_REF0(AND_operator_c)
SYM_REF0(OR_operator_c)
SYM_REF0(XOR_operator_c)
SYM_REF0(ANDN_operator_c)
SYM_REF0(ORN_operator_c)
SYM_REF0(XORN_operator_c)
-SYM_REF0(ADD_operator_c)
-SYM_REF0(SUB_operator_c)
-SYM_REF0(MUL_operator_c)
-SYM_REF0(DIV_operator_c)
+SYM_REF0(ADD_operator_c, bool deprecated_operation;)
+SYM_REF0(SUB_operator_c, bool deprecated_operation;)
+SYM_REF0(MUL_operator_c, bool deprecated_operation;)
+SYM_REF0(DIV_operator_c, bool deprecated_operation;)
SYM_REF0(MOD_operator_c)
SYM_REF0(GT_operator_c)
SYM_REF0(GE_operator_c)
@@ -1036,10 +1049,10 @@
SYM_REF2(gt_expression_c, l_exp, r_exp)
SYM_REF2(le_expression_c, l_exp, r_exp)
SYM_REF2(ge_expression_c, l_exp, r_exp)
-SYM_REF2(add_expression_c, l_exp, r_exp)
-SYM_REF2(sub_expression_c, l_exp, r_exp)
-SYM_REF2(mul_expression_c, l_exp, r_exp)
-SYM_REF2(div_expression_c, l_exp, r_exp)
+SYM_REF2(add_expression_c, l_exp, r_exp, bool deprecated_operation;)
+SYM_REF2(sub_expression_c, l_exp, r_exp, bool deprecated_operation;)
+SYM_REF2(mul_expression_c, l_exp, r_exp, bool deprecated_operation;)
+SYM_REF2(div_expression_c, l_exp, r_exp, bool deprecated_operation;)
SYM_REF2(mod_expression_c, l_exp, r_exp)
SYM_REF2(power_expression_c, l_exp, r_exp)
SYM_REF1(neg_expression_c, exp)
@@ -1047,18 +1060,36 @@
/* formal_param_list -> may be NULL ! */
/* nonformal_param_list -> may be NULL ! */
-/* NOTE: The parameters 'called_function_declaration' is used to pass
- * data between the stage 3 and stage 4.
+/* NOTES:
+ * The parameter 'called_function_declaration'...
+ * ...is used to pass data between the stage 3 and stage 4.
* The IEC 61131-3 standard allows for overloaded standard functions. This means that some
- * function calls are not compeletely defined by the name of the function being called,
+ * function calls are not completely defined by the name of the function being called,
* and need to be disambiguated with using the data types of the parameters being passed.
- * Stage 3 does this to verify semantic correctnes.
+ * Stage 3 does this to verify semantic correctness.
* Stage 4 also needs to do this in order to determine which function to call.
* It does not make sense to determine the exact function being called twice (once in stage 3,
- * and again in stage 4), so stage 3 will store this infor in the parameter called_function_declaration
+ * and again in stage 4), so stage 3 will store this info in the parameter called_function_declaration
* for stage 4 to use it later on.
- */
-SYM_REF3(function_invocation_c, function_name, formal_param_list, nonformal_param_list, symbol_c *called_function_declaration; int extensible_param_count;)
+ * The parameter 'candidate_functions'...
+ * ...is used to pass data between two passes within stage 3
+ * (actually between fill_candidate_datatypes_c and narrow_candidate_datatypes_c).
+ * It is used to store all the functions that may be legally called with the current parameters
+ * being used in this function invocation. Note that the standard includes some standard functions
+ * that have the exact same input parameter types, but return different data types.
+ * In order to determine which of these functions should be called, we first create a list
+ * of all possible functions, and then narrow down the list (hopefully down to 1 function)
+ * once we know the data type that the function invocation must return (this will take into
+ * account the expression in which the function invocation is inserted/occurs).
+ * The 'called_function_declaration' will eventually be set (in stage 3) to one of
+ * the functions in the 'candidate_functions' list!
+ * The parameter 'extensible_param_count'...
+ * ...is used to pass data between the stage 3 and stage 4.
+ * The IEC 61131-3 standard allows for extensible standard functions. This means that some
+ * standard functions may be called with a variable number of paramters. Stage 3 will store
+ * in extensible_param_count the number of parameters being passed to the extensible parameter.
+ */
+SYM_REF3(function_invocation_c, function_name, formal_param_list, nonformal_param_list, symbol_c *called_function_declaration; int extensible_param_count; std::vector <symbol_c *> candidate_functions;)
/********************/
@@ -1083,7 +1114,8 @@
/* fb_name '(' [param_assignment_list] ')' */
/* formal_param_list -> may be NULL ! */
/* nonformal_param_list -> may be NULL ! */
-SYM_REF3(fb_invocation_c, fb_name, formal_param_list, nonformal_param_list)
+/* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
+SYM_REF3(fb_invocation_c, fb_name, formal_param_list, nonformal_param_list, symbol_c *called_fb_declaration;)
/* helper symbol for fb_invocation */
/* param_assignment_list ',' param_assignment */