Skip to content
Snippets Groups Projects
Commit 3c62a863 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add the possibility to concatenate strings

One can write
``
string s;
s = "foo" + "bar" + 0;
``
Then `s` will contain "foobar0".

Remark that `1+"foo"` is invalid for instance. First argument of the
expression *must* be a string.
parent da5e6ba1
No related branches found
No related tags found
1 merge request!37Feature/language
......@@ -215,12 +215,73 @@ class BinaryExpressionProcessor final : public INodeProcessor
}
};
template <typename B_DataT>
class ConcatExpressionProcessor final : public INodeProcessor
{
ASTNode& m_node;
PUGS_INLINE auto
eval(const std::string& a, const ASTNodeDataVariant& b, ASTNodeDataVariant& value)
{
if constexpr (std::is_same_v<B_DataT, std::string>) {
value = a + std::get<B_DataT>(b);
} else {
value = a + std::to_string(std::get<B_DataT>(b));
}
}
public:
ConcatExpressionProcessor(ASTNode& node) : m_node{node} {}
void
execute(ExecUntilBreakOrContinue& exec_policy)
{
m_node.children[0]->execute(exec_policy);
m_node.children[1]->execute(exec_policy);
this->eval(std::get<std::string>(m_node.children[0]->m_value), m_node.children[1]->m_value, m_node.m_value);
}
};
ASTNodeBinaryOperatorExpressionBuilder::ASTNodeBinaryOperatorExpressionBuilder(ASTNode& n)
{
auto set_binary_operator_processor = [](ASTNode& n, const auto& operator_v) {
auto set_binary_operator_processor_for_data_b = [&](const auto data_a, const ASTNodeDataType& data_type_b) {
using OperatorT = std::decay_t<decltype(operator_v)>;
using DataTA = std::decay_t<decltype(data_a)>;
if constexpr (std::is_same_v<DataTA, std::string>) {
if constexpr (std::is_same_v<OperatorT, language::plus_op>) {
switch (data_type_b) {
case ASTNodeDataType::bool_t: {
n.m_node_processor = std::make_unique<ConcatExpressionProcessor<bool>>(n);
break;
}
case ASTNodeDataType::unsigned_int_t: {
n.m_node_processor = std::make_unique<ConcatExpressionProcessor<uint64_t>>(n);
break;
}
case ASTNodeDataType::int_t: {
n.m_node_processor = std::make_unique<ConcatExpressionProcessor<int64_t>>(n);
break;
}
case ASTNodeDataType::double_t: {
n.m_node_processor = std::make_unique<ConcatExpressionProcessor<double>>(n);
break;
}
case ASTNodeDataType::string_t: {
n.m_node_processor = std::make_unique<ConcatExpressionProcessor<std::string>>(n);
break;
}
default: {
throw parse_error("undefined operand type for binary operator", std::vector{n.children[1]->begin()});
}
}
} else {
throw parse_error("undefined operand type for binary operator", std::vector{n.begin()});
}
} else {
switch (data_type_b) {
case ASTNodeDataType::bool_t: {
n.m_node_processor = std::make_unique<BinaryExpressionProcessor<OperatorT, DataTA, bool>>(n);
......@@ -242,6 +303,7 @@ ASTNodeBinaryOperatorExpressionBuilder::ASTNodeBinaryOperatorExpressionBuilder(A
throw parse_error("undefined operand type for binary operator", std::vector{n.children[1]->begin()});
}
}
}
};
auto set_binary_operator_processor_for_data_a = [&](const ASTNodeDataType& data_type_a) {
......@@ -263,6 +325,10 @@ ASTNodeBinaryOperatorExpressionBuilder::ASTNodeBinaryOperatorExpressionBuilder(A
set_binary_operator_processor_for_data_b(double{}, data_type_b);
break;
}
case ASTNodeDataType::string_t: {
set_binary_operator_processor_for_data_b(std::string{}, data_type_b);
break;
}
default: {
throw parse_error("undefined operand type for binary operator", std::vector{n.children[0]->begin()});
}
......
......@@ -41,6 +41,9 @@ dataTypePromotion(const ASTNodeDataType& data_type_1, const ASTNodeDataType& dat
} else if ((std::max(data_type_1, data_type_2) <= ASTNodeDataType::double_t) and
(std::min(data_type_1, data_type_2) >= ASTNodeDataType::bool_t)) {
return std::max(data_type_1, data_type_2);
} else if ((data_type_1 == ASTNodeDataType::string_t) and (data_type_2 <= ASTNodeDataType::double_t) and
(data_type_2 >= ASTNodeDataType::bool_t)) {
return data_type_1;
} else {
return ASTNodeDataType::undefined_t;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment