diff --git a/src/language/ASTBuilder.cpp b/src/language/ASTBuilder.cpp index 5f8eb02e7f4de8a788e64a8c3f4aee10e40f3004..1a52ced9dd48d8781eb5c7360f1511c09bf92737 100644 --- a/src/language/ASTBuilder.cpp +++ b/src/language/ASTBuilder.cpp @@ -204,11 +204,13 @@ using selector = parse_tree::selector<Rule, false_kw, integer, real, + literal, name, B_set, N_set, Z_set, R_set, + string_type, cout_kw, cerr_kw, clog_kw, @@ -241,8 +243,6 @@ using selector = parse_tree::selector<Rule, divideeq_op, pluseq_op, minuseq_op, - // shift_left_op, - // shift_right_op, bit_andeq_op, bit_xoreq_op, bit_oreq_op, diff --git a/src/language/ASTNodeDataType.cpp b/src/language/ASTNodeDataType.cpp index 33d809c3312fdfc017ad28baacaa761fefcd1921..e5552d8db03fb52fa78a705cbcf4c6975fbe3e70 100644 --- a/src/language/ASTNodeDataType.cpp +++ b/src/language/ASTNodeDataType.cpp @@ -22,6 +22,9 @@ dataTypeName(const DataType& data_type) case DataType::double_t: name = "R"; break; + case DataType::string_t: + name = "string"; + break; case DataType::typename_t: name = "typename"; break; diff --git a/src/language/ASTNodeDataType.hpp b/src/language/ASTNodeDataType.hpp index 51a66818408371c0dbe97b496105b140896c284b..605f42524074cb9e35241c0407cc4f986dec2255 100644 --- a/src/language/ASTNodeDataType.hpp +++ b/src/language/ASTNodeDataType.hpp @@ -12,6 +12,7 @@ enum class DataType bool_t = 0, unsigned_int_t = 1, int_t = 2, + string_t = 5, double_t = 3, typename_t = 10, void_t = 9999 @@ -21,7 +22,7 @@ std::string dataTypeName(const DataType& data_type); DataType dataTypePromotion(const DataType& data_type_1, const DataType& data_type_2); -using DataVariant = std::variant<std::monostate, bool, uint64_t, int64_t, double>; +using DataVariant = std::variant<std::monostate, bool, uint64_t, int64_t, double, std::string>; } // namespace language diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp index b89fd96c3b828c9f0441e7327208f34b29910e26..e144408642c5aad880b9328ff02746425793d881 100644 --- a/src/language/ASTNodeExpressionBuilder.cpp +++ b/src/language/ASTNodeExpressionBuilder.cpp @@ -53,10 +53,10 @@ class IfStatement final : public INodeProcessor const bool is_true = static_cast<bool>(std::visit( [](const auto& value) -> bool { using T = std::decay_t<decltype(value)>; - if constexpr (std::is_same_v<T, std::monostate>) { - return false; - } else { + if constexpr (std::is_arithmetic_v<T>) { return value; + } else { + return false; } }, m_node.children[0]->m_value)); @@ -98,10 +98,10 @@ class DoWhileStatement final : public INodeProcessor continuation_test = static_cast<bool>(std::visit( [](const auto& value) -> bool { using T = std::decay_t<decltype(value)>; - if constexpr (std::is_same_v<T, std::monostate>) { - return false; - } else { + if constexpr (std::is_arithmetic_v<T>) { return value; + } else { + return false; } }, m_node.children[1]->m_value)); @@ -125,10 +125,10 @@ class WhileStatement final : public INodeProcessor return static_cast<bool>(std::visit( [](const auto& value) -> bool { using T = std::decay_t<decltype(value)>; - if constexpr (std::is_same_v<T, std::monostate>) { - return false; - } else { + if constexpr (std::is_arithmetic_v<T>) { return value; + } else { + return false; } }, m_node.children[0]->m_value)); @@ -162,10 +162,10 @@ class ForStatement final : public INodeProcessor return static_cast<bool>(std::visit( [](const auto& value) -> bool { using T = std::decay_t<decltype(value)>; - if constexpr (std::is_same_v<T, std::monostate>) { - return false; - } else { + if constexpr (std::is_arithmetic_v<T>) { return value; + } else { + return false; } }, m_node.children[1]->m_value)); @@ -280,6 +280,8 @@ build_node_type(Node& n) n.m_node_processor = std::make_unique<NoProcess>(); } else if (n.is<language::integer>()) { n.m_node_processor = std::make_unique<NoProcess>(); + } else if (n.is<language::literal>()) { + n.m_node_processor = std::make_unique<NoProcess>(); } else if (n.is<language::name>()) { n.m_node_processor = std::make_unique<NameExpression>(n); @@ -301,6 +303,7 @@ 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::string_type>()) { } 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>()) { diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp index e4c8a55afd6e337d41554fb15add2be5292dddf7..60f23afd6bb5144ae6111f024d0b52c0eee3ea74 100644 --- a/src/language/PEGGrammar.hpp +++ b/src/language/PEGGrammar.hpp @@ -48,6 +48,14 @@ struct real > >{}; + +struct escaped_c : one< '\'', '"', '?', '\\', 'a', 'b', 'f', 'n', 'r', 't', 'v' > {}; +struct character : if_must_else< one< '\\' >, escaped_c, ascii::any> {}; + +struct literal : if_must< one< '"' >, until< one< '"' >, character > > {}; + +struct LITERAL : seq< literal, ignored >{}; + struct semicol : one< ';' >{}; struct REAL : seq< real, ignored >{}; @@ -57,7 +65,9 @@ struct N_set : one< 'N' >{}; struct Z_set : one< 'Z' >{}; struct R_set : one< 'R' >{}; -struct basic_type : sor < B_set, R_set, Z_set, N_set > {}; +struct string_type : TAO_PEGTL_KEYWORD("string") {}; + +struct basic_type : sor < B_set, R_set, Z_set, N_set, string_type > {}; struct TYPESPECIFIER : seq< basic_type, ignored> {}; @@ -116,7 +126,7 @@ struct close_parent : seq< one< ')' >, ignored > {}; struct expression; struct parented_expression : if_must< open_parent, expression, close_parent > {}; -struct primary_expression : sor< BOOL, REAL, INTEGER , NAME, parented_expression > {}; +struct primary_expression : sor< BOOL, REAL, INTEGER, LITERAL, NAME, parented_expression > {}; struct unary_plusplus : TAO_PEGTL_STRING("++") {}; struct unary_minusminus : TAO_PEGTL_STRING("--") {}; diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index 092ff2bd07b21ebef17f7ba002eae259b40cbfe4..9913483227d74bc67be8fb351a28d338daebc6fd 100644 --- a/src/language/PugsParser.cpp +++ b/src/language/PugsParser.cpp @@ -192,6 +192,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::literal>()) { + n.m_data_type = DataType::string_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>()) { @@ -205,6 +207,8 @@ build_node_data_types(Node& n) data_type = DataType::unsigned_int_t; } else if (type_node.is<language::R_set>()) { data_type = DataType::double_t; + } else if (type_node.is<language::string_type>()) { + data_type = DataType::string_t; } if (data_type == DataType::undefined_t) { throw parse_error("unexpected error: invalid datatype", type_node.begin()); @@ -353,6 +357,11 @@ build_node_values(Node& n, std::shared_ptr<SymbolTable>& symbol_table) int64_t v; ss >> v; n.m_value = v; + } else if (n.is<language::literal>()) { + std::string value(&n.string()[1], n.string().size() - 2); + n.m_value = value; + std::cout << std::get<std::string>(n.m_value) << '\n'; + } else if (n.is<language::for_test>()) { // if AST contains a for_test statement, it means that no test were // given to the for-loop, so its value is always true