20 static inline bool is_number(
const std::shared_ptr<ast::Expression>& node) {
21 return node->is_integer() || node->is_double() || node->is_float();
26 static double get_value(
const std::shared_ptr<ast::Expression>& node) {
27 if (node->is_integer()) {
28 return std::dynamic_pointer_cast<ast::Integer>(node)->eval();
29 }
else if (node->is_float()) {
30 return std::dynamic_pointer_cast<ast::Float>(node)->to_double();
31 }
else if (node->is_double()) {
32 return std::dynamic_pointer_cast<ast::Double>(node)->to_double();
34 throw std::runtime_error(
"Invalid type passed to is_number()");
60 throw std::logic_error(
"Invalid binary operator in constant folding");
81 if (expr->is_wrapped_expression()) {
82 auto e = std::dynamic_pointer_cast<ast::WrappedExpression>(expr);
115 bool is_parentheses =
false;
120 if (expr->is_paren_expression()) {
121 auto e = std::dynamic_pointer_cast<ast::ParenExpression>(expr);
122 expr = e->get_expression();
123 is_parentheses =
true;
127 if (!expr->is_binary_expression()) {
130 if (is_parentheses) {
136 auto binary_expr = std::dynamic_pointer_cast<ast::BinaryExpression>(expr);
137 auto lhs = binary_expr->get_lhs();
138 auto rhs = binary_expr->get_rhs();
139 auto op = binary_expr->get_op().get_value();
147 if (lhs->is_wrapped_expression()) {
148 auto e = std::dynamic_pointer_cast<ast::WrappedExpression>(lhs);
149 lhs = e->get_expression();
152 if (rhs->is_wrapped_expression()) {
153 auto e = std::dynamic_pointer_cast<ast::WrappedExpression>(rhs);
154 rhs = e->get_expression();
162 const std::string& nmodl_before =
to_nmodl(binary_expr);
168 if (lhs->is_integer() && rhs->is_integer()) {
169 node.
set_expression(std::make_shared<ast::Integer>(
static_cast<int>(value),
nullptr));
170 }
else if (lhs->is_double() || rhs->is_double()) {
177 logger->debug(
"ConstantFolderVisitor : expression {} folded to {}", nmodl_before, nmodl_after);