ccb@204: /* msousa@267: * matiec - a compiler for the programming languages defined in IEC 61131-3 ccb@204: * msousa@417: * Copyright (C) 2009-2012 Mario de Sousa (msousa@fe.up.pt) Edouard@279: * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant msousa@417: * Copyright (C) 2012 Manuele Conti (manuele.conti@sirius-es.it) msousa@417: * Copyright (C) 2012 Matteo Facchinetti (matteo.facchinetti@sirius-es.it) ccb@204: * msousa@267: * This program is free software: you can redistribute it and/or modify msousa@267: * it under the terms of the GNU General Public License as published by msousa@267: * the Free Software Foundation, either version 3 of the License, or msousa@267: * (at your option) any later version. msousa@267: * msousa@267: * This program is distributed in the hope that it will be useful, msousa@267: * but WITHOUT ANY WARRANTY; without even the implied warranty of msousa@267: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the msousa@267: * GNU General Public License for more details. msousa@267: * msousa@267: * You should have received a copy of the GNU General Public License msousa@267: * along with this program. If not, see . msousa@267: * ccb@204: * ccb@204: * This code is made available on the understanding that it will not be ccb@204: * used in safety-critical situations without a full and competent review. ccb@204: */ ccb@204: ccb@204: /* msousa@267: * An IEC 61131-3 compiler. ccb@204: * ccb@204: * Based on the msousa@267: * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) ccb@204: * ccb@204: */ ccb@204: ccb@204: #include "stage3.hh" ccb@204: msousa@443: #include "flow_control_analysis.hh" msousa@417: #include "fill_candidate_datatypes.hh" msousa@417: #include "narrow_candidate_datatypes.hh" msousa@417: #include "print_datatypes_error.hh" conti@508: #include "lvalue_check.hh" msousa@560: #include "array_range_check.hh" conti@564: #include "constant_folding.hh" msousa@530: msousa@612: msousa@530: msousa@443: static int flow_control_analysis(symbol_c *tree_root){ conti@564: flow_control_analysis_c flow_control_analysis(tree_root); conti@564: tree_root->accept(flow_control_analysis); conti@564: return 0; msousa@443: } msousa@443: msousa@530: msousa@612: /* Constant folding assumes that flow control analysis has been completed! msousa@612: * so be sure to call flow_control_analysis() before calling this function! msousa@612: */ msousa@612: static int constant_folding(symbol_c *tree_root){ msousa@612: constant_folding_c constant_folding(tree_root); msousa@612: tree_root->accept(constant_folding); msousa@612: return constant_folding.get_error_count(); msousa@612: } msousa@612: msousa@612: msousa@611: /* Type safety analysis assumes that msousa@611: * - flow control analysis msousa@611: * - constant folding (constant check) msousa@611: * has already been completed, so be sure to call those semantic checkers msousa@611: * before calling this function msousa@443: */ msousa@443: static int type_safety(symbol_c *tree_root){ msousa@417: fill_candidate_datatypes_c fill_candidate_datatypes(tree_root); msousa@417: tree_root->accept(fill_candidate_datatypes); msousa@417: narrow_candidate_datatypes_c narrow_candidate_datatypes(tree_root); msousa@417: tree_root->accept(narrow_candidate_datatypes); msousa@444: print_datatypes_error_c print_datatypes_error(tree_root); msousa@417: tree_root->accept(print_datatypes_error); msousa@510: return print_datatypes_error.get_error_count(); ccb@204: } ccb@204: msousa@443: msousa@612: /* Left value checking assumes that data type analysis has already been completed, msousa@530: * so be sure to call type_safety() before calling this function msousa@510: */ msousa@510: static int lvalue_check(symbol_c *tree_root){ msousa@510: lvalue_check_c lvalue_check(tree_root); msousa@510: tree_root->accept(lvalue_check); msousa@510: return lvalue_check.get_error_count(); msousa@510: } msousa@510: msousa@612: /* Array range check assumes that constant folding has been completed! msousa@612: * so be sure to call constant_folding() before calling this function! msousa@612: */ msousa@612: static int array_range_check(symbol_c *tree_root){ msousa@560: array_range_check_c array_range_check(tree_root); msousa@560: tree_root->accept(array_range_check); msousa@560: return array_range_check.get_error_count(); conti@559: } conti@559: msousa@443: ccb@204: int stage3(symbol_c *tree_root){ msousa@510: int error_count = 0; msousa@510: error_count += flow_control_analysis(tree_root); msousa@612: error_count += constant_folding(tree_root); msousa@510: error_count += type_safety(tree_root); msousa@510: error_count += lvalue_check(tree_root); msousa@612: error_count += array_range_check(tree_root); msousa@510: msousa@510: if (error_count > 0) { msousa@516: fprintf(stderr, "%d error(s) found. Bailing out!\n", error_count); msousa@510: return -1; msousa@510: } msousa@510: return 0; ccb@204: }