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