@@ -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" );
@@ -722,6 +731,16 @@ struct Expression : lexy::expression_production
722731 using operand = math_product;
723732 };
724733
734+ // x .. y
735+ struct string_concat : dsl::infix_op_left
736+ {
737+ static constexpr auto op = [] {
738+ return dsl::op<Ast::ExprBinaryArithmetic::concat>(LEXY_LIT (" .." ));
739+ }();
740+
741+ using operand = math_sum;
742+ };
743+
725744 // ~x
726745 struct bit_prefix : dsl::prefix_op
727746 {
@@ -785,7 +804,7 @@ struct Expression : lexy::expression_production
785804 dsl::op<Ast::ExprBinaryArithmetic::logic_or>(LEXY_LIT(" ||" )) /
786805 dsl::op<Ast::ExprBinaryArithmetic::logic_and>(LEXY_LIT(" &&" ));
787806
788- using operand = comparison;
807+ using operand = dsl::groups<string_concat, comparison> ;
789808 };
790809
791810 // x ? y : z
0 commit comments