@@ -150,6 +150,7 @@ struct ExprBinaryArithmetic : ExprBase
150150 minus,
151151 times,
152152 div,
153+ concat,
153154
154155 bit_and,
155156 bit_or,
@@ -171,6 +172,8 @@ struct ExprBinaryArithmetic : ExprBase
171172 return " *" ;
172173 case div:
173174 return " /" ;
175+ case concat:
176+ return " .." ;
174177 case bit_and:
175178 return " &" ;
176179 case bit_or:
@@ -276,6 +279,12 @@ struct ExprBinaryArithmetic : ExprBase
276279 {
277280 return Any (lhs_v.cast <std::string>() + rhs_v.cast <std::string>());
278281 }
282+ else if (op == concat && ((rhs_v.isString () && lhs_v.isString ()) ||
283+ (rhs_v.isString () && lhs_v.isNumber ()) ||
284+ (rhs_v.isNumber () && lhs_v.isString ())))
285+ {
286+ return Any (lhs_v.cast <std::string>() + rhs_v.cast <std::string>());
287+ }
279288 else
280289 {
281290 throw RuntimeError (" Operation not permitted" );
@@ -726,6 +735,16 @@ struct Expression : lexy::expression_production
726735 using operand = math_product;
727736 };
728737
738+ // x .. y
739+ struct string_concat : dsl::infix_op_left
740+ {
741+ static constexpr auto op = [] {
742+ return dsl::op<Ast::ExprBinaryArithmetic::concat>(LEXY_LIT (" .." ));
743+ }();
744+
745+ using operand = math_sum;
746+ };
747+
729748 // ~x
730749 struct bit_prefix : dsl::prefix_op
731750 {
@@ -789,7 +808,7 @@ struct Expression : lexy::expression_production
789808 dsl::op<Ast::ExprBinaryArithmetic::logic_or>(LEXY_LIT(" ||" )) /
790809 dsl::op<Ast::ExprBinaryArithmetic::logic_and>(LEXY_LIT(" &&" ));
791810
792- using operand = comparison;
811+ using operand = dsl::groups<string_concat, comparison> ;
793812 };
794813
795814 // x ? y : z
0 commit comments