@@ -130,6 +130,7 @@ struct ExprBinaryArithmetic : ExprBase
130130 minus,
131131 times,
132132 div,
133+ concat,
133134
134135 bit_and,
135136 bit_or,
@@ -151,6 +152,8 @@ struct ExprBinaryArithmetic : ExprBase
151152 return " *" ;
152153 case div:
153154 return " /" ;
155+ case concat:
156+ return " .." ;
154157 case bit_and:
155158 return " &" ;
156159 case bit_or:
@@ -256,6 +259,12 @@ struct ExprBinaryArithmetic : ExprBase
256259 {
257260 return Any (lhs_v.cast <std::string>() + rhs_v.cast <std::string>());
258261 }
262+ else if (op == concat && ((rhs_v.isString () && lhs_v.isString ()) ||
263+ (rhs_v.isString () && lhs_v.isNumber ()) ||
264+ (rhs_v.isNumber () && lhs_v.isString ())))
265+ {
266+ return Any (lhs_v.cast <std::string>() + rhs_v.cast <std::string>());
267+ }
259268 else
260269 {
261270 throw RuntimeError (" Operation not permitted" );
@@ -694,6 +703,16 @@ struct Expression : lexy::expression_production
694703 using operand = math_product;
695704 };
696705
706+ // x .. y
707+ struct string_concat : dsl::infix_op_left
708+ {
709+ static constexpr auto op = [] {
710+ return dsl::op<Ast::ExprBinaryArithmetic::concat>(LEXY_LIT (" .." ));
711+ }();
712+
713+ using operand = math_sum;
714+ };
715+
697716 // ~x
698717 struct bit_prefix : dsl::prefix_op
699718 {
@@ -757,7 +776,7 @@ struct Expression : lexy::expression_production
757776 dsl::op<Ast::ExprBinaryArithmetic::logic_or>(LEXY_LIT(" ||" )) /
758777 dsl::op<Ast::ExprBinaryArithmetic::logic_and>(LEXY_LIT(" &&" ));
759778
760- using operand = comparison;
779+ using operand = dsl::groups<string_concat, comparison> ;
761780 };
762781
763782 // x ? y : z
0 commit comments