diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index 29bc6bf7848d80f2bb39892a4bdbc62801498916..757b9d5ac69addec6ef033fe494b268775bdff6b 100644 --- a/src/language/PugsParser.cpp +++ b/src/language/PugsParser.cpp @@ -112,8 +112,9 @@ struct CONTINUE : seq < continue_kw, ignored > {}; struct cout_kw : TAO_PEGTL_KEYWORD("cout") {}; struct cerr_kw : TAO_PEGTL_KEYWORD("cerr") {}; +struct clog_kw : TAO_PEGTL_KEYWORD("clog") {}; -struct keywork : sor < basic_type, true_kw, false_kw, do_kw, while_kw, for_kw, if_kw, else_kw, and_kw, or_kw, xor_kw, bitand_kw, bitor_kw, and_eq_kw, xor_eq_kw, or_eq_kw, break_kw, continue_kw, cout_kw, cerr_kw > {}; +struct keywork : sor < basic_type, true_kw, false_kw, do_kw, while_kw, for_kw, if_kw, else_kw, and_kw, or_kw, xor_kw, bitand_kw, bitor_kw, and_eq_kw, xor_eq_kw, or_eq_kw, break_kw, continue_kw, cout_kw, cerr_kw, clog_kw > {}; struct name : minus< identifier, keywork > {}; struct NAME : seq < name, ignored > {}; @@ -236,7 +237,7 @@ struct for_statement_bloc; struct for_statement : if_must< FOR, open_parent, for_init, SEMICOL, for_test, SEMICOL, for_post, close_parent, for_statement_bloc >{}; -struct ostream_object : seq< sor< cout_kw, cerr_kw >, ignored >{}; +struct ostream_object : seq< sor< cout_kw, cerr_kw, clog_kw >, ignored >{}; struct ostream_statement : seq< ostream_object, star< if_must< shift_left_op, expression, ignored > > >{}; struct instruction @@ -664,7 +665,9 @@ using selector = parse_tree::selector<Rule, N_set, Z_set, R_set, - ostream_object, + cout_kw, + cerr_kw, + clog_kw, declaration, if_statement, do_while_statement, @@ -1554,6 +1557,38 @@ class ContinueExpression final : public INodeProcessor } }; +class OStreamObject final : public INodeProcessor +{ + Node& m_node; + std::ostream& m_os; + + public: + OStreamObject(Node& node, std::ostream& os) : m_node{node}, m_os(os) + { + ; + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + for (size_t i = 0; i < m_node.children.size(); ++i) { + m_node.children[i]->execute(exec_policy); + std::visit( + [&](auto&& value) { + using ValueT = std::decay_t<decltype(value)>; + if constexpr (not std::is_same_v<std::monostate, ValueT>) { + if constexpr (std::is_same_v<bool, ValueT>) { + m_os << std::boolalpha << value; + } else { + m_os << value; + } + } + }, + m_node.children[i]->m_value); + } + } +}; + namespace internal { void @@ -1890,6 +1925,12 @@ build_node_type(Node& n) } else if (n.is<language::B_set>()) { } else if (n.is<language::N_set>()) { } else if (n.is<language::Z_set>()) { + } else if (n.is<language::cout_kw>()) { + n.m_node_processor = std::make_unique<OStreamObject>(n, std::cout); + } else if (n.is<language::cerr_kw>()) { + n.m_node_processor = std::make_unique<OStreamObject>(n, std::cerr); + } else if (n.is<language::clog_kw>()) { + n.m_node_processor = std::make_unique<OStreamObject>(n, std::clog); } else if (n.is<language::R_set>()) { } else if (n.is<language::if_statement>()) { n.m_node_processor = std::make_unique<IfStatement>(n); @@ -2110,6 +2151,8 @@ build_node_data_types(Node& n) n.m_data_type = DataType::double_t; } else if (n.is<language::integer>()) { n.m_data_type = DataType::int_t; + } else if (n.is<language::cout_kw>() or n.is<language::cerr_kw>() or n.is<language::clog_kw>()) { + n.m_data_type = DataType::void_t; } else if (n.is<language::declaration>()) { auto& type_node = *(n.children[0]); DataType data_type{DataType::undefined_t};