1 /* |
1 /* |
2 * matiec - a compiler for the programming languages defined in IEC 61131-3 |
2 * matiec - a compiler for the programming languages defined in IEC 61131-3 |
3 * |
3 * |
4 * Copyright (C) 2009-2011 Mario de Sousa (msousa@fe.up.pt) |
4 * Copyright (C) 2009-2012 Mario de Sousa (msousa@fe.up.pt) |
5 * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant |
5 * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant |
|
6 * Copyright (C) 2012 Manuele Conti (manuele.conti@sirius-es.it) |
|
7 * Copyright (C) 2012 Matteo Facchinetti (matteo.facchinetti@sirius-es.it) |
6 * |
8 * |
7 * This program is free software: you can redistribute it and/or modify |
9 * This program is free software: you can redistribute it and/or modify |
8 * it under the terms of the GNU General Public License as published by |
10 * it under the terms of the GNU General Public License as published by |
9 * the Free Software Foundation, either version 3 of the License, or |
11 * the Free Software Foundation, either version 3 of the License, or |
10 * (at your option) any later version. |
12 * (at your option) any later version. |
30 * |
32 * |
31 */ |
33 */ |
32 |
34 |
33 #include "stage3.hh" |
35 #include "stage3.hh" |
34 |
36 |
35 int type_safety(symbol_c *tree_root){ |
37 #include "flow_control_analysis.hh" |
36 visit_expression_type_c visit_expression_type(tree_root); |
38 #include "fill_candidate_datatypes.hh" |
|
39 #include "narrow_candidate_datatypes.hh" |
|
40 #include "print_datatypes_error.hh" |
|
41 #include "lvalue_check.hh" |
|
42 #include "array_range_check.hh" |
|
43 #include "constant_folding.hh" |
37 |
44 |
38 (*tree_root).accept(visit_expression_type); |
|
39 |
45 |
40 if (visit_expression_type.get_error_found()) |
46 |
41 return -1; |
47 static int flow_control_analysis(symbol_c *tree_root){ |
|
48 flow_control_analysis_c flow_control_analysis(tree_root); |
|
49 tree_root->accept(flow_control_analysis); |
|
50 return 0; |
|
51 } |
|
52 |
|
53 |
|
54 /* Constant folding assumes that flow control analysis has been completed! |
|
55 * so be sure to call flow_control_analysis() before calling this function! |
|
56 */ |
|
57 static int constant_folding(symbol_c *tree_root){ |
|
58 constant_folding_c constant_folding(tree_root); |
|
59 tree_root->accept(constant_folding); |
|
60 return constant_folding.get_error_count(); |
|
61 } |
|
62 |
|
63 |
|
64 /* Type safety analysis assumes that |
|
65 * - flow control analysis |
|
66 * - constant folding (constant check) |
|
67 * has already been completed, so be sure to call those semantic checkers |
|
68 * before calling this function |
|
69 */ |
|
70 static int type_safety(symbol_c *tree_root){ |
|
71 fill_candidate_datatypes_c fill_candidate_datatypes(tree_root); |
|
72 tree_root->accept(fill_candidate_datatypes); |
|
73 narrow_candidate_datatypes_c narrow_candidate_datatypes(tree_root); |
|
74 tree_root->accept(narrow_candidate_datatypes); |
|
75 print_datatypes_error_c print_datatypes_error(tree_root); |
|
76 tree_root->accept(print_datatypes_error); |
|
77 return print_datatypes_error.get_error_count(); |
|
78 } |
|
79 |
|
80 |
|
81 /* Left value checking assumes that data type analysis has already been completed, |
|
82 * so be sure to call type_safety() before calling this function |
|
83 */ |
|
84 static int lvalue_check(symbol_c *tree_root){ |
|
85 lvalue_check_c lvalue_check(tree_root); |
|
86 tree_root->accept(lvalue_check); |
|
87 return lvalue_check.get_error_count(); |
|
88 } |
|
89 |
|
90 /* Array range check assumes that constant folding has been completed! |
|
91 * so be sure to call constant_folding() before calling this function! |
|
92 */ |
|
93 static int array_range_check(symbol_c *tree_root){ |
|
94 array_range_check_c array_range_check(tree_root); |
|
95 tree_root->accept(array_range_check); |
|
96 return array_range_check.get_error_count(); |
|
97 } |
|
98 |
|
99 |
|
100 int stage3(symbol_c *tree_root){ |
|
101 int error_count = 0; |
|
102 error_count += flow_control_analysis(tree_root); |
|
103 error_count += constant_folding(tree_root); |
|
104 error_count += type_safety(tree_root); |
|
105 error_count += lvalue_check(tree_root); |
|
106 error_count += array_range_check(tree_root); |
42 |
107 |
|
108 if (error_count > 0) { |
|
109 fprintf(stderr, "%d error(s) found. Bailing out!\n", error_count); |
|
110 return -1; |
|
111 } |
43 return 0; |
112 return 0; |
44 } |
113 } |
45 |
|
46 int stage3(symbol_c *tree_root){ |
|
47 return type_safety(tree_root); |
|
48 } |
|