1 #ifndef STAN_LANG_AST_FUN_RETURNS_TYPE_VIS_DEF_HPP
2 #define STAN_LANG_AST_FUN_RETURNS_TYPE_VIS_DEF_HPP
3 
4 #include <stan/lang/ast.hpp>
5 #include <ostream>
6 
7 namespace stan {
8   namespace lang {
9 
returns_type_vis(const bare_expr_type & return_type,std::ostream & error_msgs)10     returns_type_vis::returns_type_vis(const bare_expr_type& return_type,
11                                        std::ostream& error_msgs)
12       : return_type_(return_type), error_msgs_(error_msgs) { }
13 
operator ()(const nil & st) const14     bool returns_type_vis::operator()(const nil& st) const {
15       error_msgs_ << "Expecting return, found nil statement."
16                   << std::endl;
17       return false;
18     }
19 
operator ()(const assgn & st) const20     bool returns_type_vis::operator()(const assgn& st) const {
21       error_msgs_ << "Expecting return, found assignment statement."
22                   << std::endl;
23       return false;
24     }
25 
operator ()(const sample & st) const26     bool returns_type_vis::operator()(const sample& st) const {
27       error_msgs_ << "Expecting return, found sampling statement."
28                   << std::endl;
29       return false;
30     }
31 
operator ()(const increment_log_prob_statement & t) const32     bool returns_type_vis::operator()(const
33                                       increment_log_prob_statement& t) const {
34       error_msgs_ << "Expecting return, found increment_log_prob statement."
35                   << std::endl;
36       return false;
37     }
38 
operator ()(const expression & st) const39     bool returns_type_vis::operator()(const expression& st) const  {
40       error_msgs_ << "Expecting return, found increment_log_prob statement."
41                   << std::endl;
42       return false;
43     }
44 
operator ()(const print_statement & st) const45     bool returns_type_vis::operator()(const print_statement& st) const  {
46       error_msgs_ << "Expecting return, found print statement."
47                  << std::endl;
48       return false;
49     }
50 
operator ()(const reject_statement & st) const51     bool returns_type_vis::operator()(const reject_statement& st) const  {
52       error_msgs_ << "Expecting return, found reject statement."
53                   << std::endl;
54       return false;
55     }
56 
operator ()(const no_op_statement & st) const57     bool returns_type_vis::operator()(const no_op_statement& st) const  {
58       error_msgs_ << "Expecting return, found no_op statement."
59                   << std::endl;
60       return false;
61     }
62 
operator ()(const statements & st) const63     bool returns_type_vis::operator()(const statements& st) const  {
64       // last statement in sequence must return type
65       if (st.statements_.size() == 0) {
66         error_msgs_ << ("Expecting return, found"
67                         " statement sequence with empty body.")
68                     << std::endl;
69         return false;
70       }
71       return returns_type(return_type_, st.statements_.back(), error_msgs_);
72     }
73 
operator ()(const for_statement & st) const74     bool returns_type_vis::operator()(const for_statement& st) const  {
75       // body must end in appropriate return
76       return returns_type(return_type_, st.statement_, error_msgs_);
77     }
78 
operator ()(const for_array_statement & st) const79     bool returns_type_vis::operator()(const for_array_statement& st) const  {
80       // body must end in appropriate return
81       return returns_type(return_type_, st.statement_, error_msgs_);
82     }
83 
operator ()(const for_matrix_statement & st) const84     bool returns_type_vis::operator()(const for_matrix_statement& st) const  {
85       // body must end in appropriate return
86       return returns_type(return_type_, st.statement_, error_msgs_);
87     }
88 
operator ()(const while_statement & st) const89      bool returns_type_vis::operator()(const while_statement& st) const  {
90       // body must end in appropriate return
91       return returns_type(return_type_, st.body_, error_msgs_);
92     }
93 
operator ()(const break_continue_statement & st) const94     bool returns_type_vis::operator()(const break_continue_statement& st)
95       const  {
96       // break/continue OK only as end of nested loop in void return
97       bool pass = (return_type_.is_void_type());
98       if (!pass)
99         error_msgs_ << "statement " << st.generate_
100                     << " does not match return type";
101       return pass;
102     }
103 
operator ()(const conditional_statement & st) const104     bool returns_type_vis::operator()(const conditional_statement& st) const {
105       // all condition bodies must end in appropriate return
106       if (st.bodies_.size() != (st.conditions_.size() + 1)) {
107         error_msgs_ << ("Expecting return, found conditional"
108                         " without final else.")
109                     << std::endl;
110         return false;
111       }
112       for (size_t i = 0; i < st.bodies_.size(); ++i)
113         if (!returns_type(return_type_, st.bodies_[i], error_msgs_))
114           return false;
115       return true;
116     }
117 
operator ()(const return_statement & st) const118     bool returns_type_vis::operator()(const return_statement& st) const  {
119       // return checked for type
120       return return_type_.is_void_type()
121         || is_assignable(return_type_, st.return_value_.bare_type(),
122                          "Returned expression does not match return type",
123                          error_msgs_);
124     }
125 
126   }
127 }
128 #endif
129