diff --git a/src/language/ast/ASTNodeDataTypeBuilder.cpp b/src/language/ast/ASTNodeDataTypeBuilder.cpp index 44e30ec2e11fba9db2701268d582089f9cb839f4..d8cf06824ea5cf070a07a84d4bf3bcc711f71a79 100644 --- a/src/language/ast/ASTNodeDataTypeBuilder.cpp +++ b/src/language/ast/ASTNodeDataTypeBuilder.cpp @@ -212,9 +212,16 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const auto simple_type_allocator = [&](const ASTNode& type_node, ASTNode& symbol_node) { Assert(symbol_node.is_type<language::name>()); - const ASTNodeDataType& data_type = type_node.m_data_type.contentType(); - symbol_node.m_data_type = type_node.m_data_type.contentType(); + const ASTNodeDataType data_type = [&] { + if (type_node.m_data_type == ASTNodeDataType::type_id_t) { + return ASTNodeDataType::build<ASTNodeDataType::type_id_t>(type_node.m_data_type.nameOfTypeId()); + } else { + return type_node.m_data_type.contentType(); + } + }(); + + symbol_node.m_data_type = data_type; const std::string& symbol = symbol_node.string(); std::shared_ptr<SymbolTable>& symbol_table = n.m_symbol_table; @@ -357,6 +364,8 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const value_type = getMatrixDataType(image_node); } else if (image_node.is_type<language::string_type>()) { value_type = ASTNodeDataType::build<ASTNodeDataType::string_t>(); + } else if (image_node.is_type<language::type_name_id>()) { + value_type = ASTNodeDataType::build<ASTNodeDataType::type_id_t>(image_node.m_data_type.nameOfTypeId()); } // LCOV_EXCL_START @@ -528,7 +537,14 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ASTNode& image_domain_node = *function_descriptor.domainMappingNode().children[1]; - n.m_data_type = image_domain_node.m_data_type.contentType(); + n.m_data_type = [&] { + if (image_domain_node.m_data_type == ASTNodeDataType::type_id_t) { + return ASTNodeDataType::build<ASTNodeDataType::type_id_t>(image_domain_node.m_data_type.nameOfTypeId()); + } else { + return image_domain_node.m_data_type.contentType(); + } + }(); + } else if (n.children[0]->m_data_type == ASTNodeDataType::builtin_function_t) { auto builtin_function_embedder = getBuiltinFunctionEmbedder(n); diff --git a/src/language/ast/ASTNodeDataTypeFlattener.cpp b/src/language/ast/ASTNodeDataTypeFlattener.cpp index a2f83e5923392163f54ccc1b8bdecd5b8ed96e86..7212d6b001a12de45e6b81e2955a80fe71cd07b4 100644 --- a/src/language/ast/ASTNodeDataTypeFlattener.cpp +++ b/src/language/ast/ASTNodeDataTypeFlattener.cpp @@ -30,8 +30,20 @@ ASTNodeDataTypeFlattener::ASTNodeDataTypeFlattener(ASTNode& node, FlattenedDataT ASTNode& function_image_domain = *function_descriptor.domainMappingNode().children[1]; for (auto& image_sub_domain : function_image_domain.children) { - Assert(image_sub_domain->m_data_type == ASTNodeDataType::typename_t); - flattened_datatype_list.push_back({image_sub_domain->m_data_type.contentType(), node}); + switch (image_sub_domain->m_data_type) { + case ASTNodeDataType::typename_t: { + flattened_datatype_list.push_back({image_sub_domain->m_data_type.contentType(), node}); + break; + } + case ASTNodeDataType::type_id_t: { + flattened_datatype_list.push_back( + {ASTNodeDataType::build<ASTNodeDataType::type_id_t>(image_sub_domain->m_data_type.nameOfTypeId()), node}); + break; + } + default: { + throw UnexpectedError("invalid data type"); + } + } } break; } diff --git a/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp index 1fb23a5de3287b8b685ce9ef2ea4789697cbe198..15720a9f645616ad08588c5d00e5185d06482276 100644 --- a/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeFunctionExpressionBuilder.cpp @@ -37,7 +37,29 @@ ASTNodeFunctionExpressionBuilder::_getArgumentConverter(SymbolType& parameter_sy } // LCOV_EXCL_START default: { - throw ParseError("unexpected error: invalid argument type 0", + throw ParseError("unexpected error: invalid argument type", + std::vector{node_sub_data_type.m_parent_node.begin()}); + } + // LCOV_EXCL_STOP + } + }; + + auto get_function_argument_converter_for_type_id = + [&](const std::string& type_id_name) -> std::unique_ptr<IFunctionArgumentConverter> { + switch (node_sub_data_type.m_data_type) { + case ASTNodeDataType::type_id_t: { + if (node_sub_data_type.m_data_type.nameOfTypeId() == type_id_name) { + return std::make_unique<FunctionArgumentConverter<EmbeddedData, EmbeddedData>>(parameter_id); + } else { + // LCOV_EXCL_START + throw ParseError("unexpected error: invalid argument type", + std::vector{node_sub_data_type.m_parent_node.begin()}); + // LCOV_EXCL_STOP + } + } + // LCOV_EXCL_START + default: { + throw ParseError("unexpected error: invalid argument type", std::vector{node_sub_data_type.m_parent_node.begin()}); } // LCOV_EXCL_STOP @@ -181,6 +203,9 @@ ASTNodeFunctionExpressionBuilder::_getArgumentConverter(SymbolType& parameter_sy // LCOV_EXCL_START throw ParseError("unexpected error: undefined parameter type", std::vector{m_node.begin()}); // LCOV_EXCL_STOP + } + case ASTNodeDataType::type_id_t: { + return get_function_argument_converter_for_type_id(parameter_symbol.attributes().dataType().nameOfTypeId()); } // LCOV_EXCL_START default: { @@ -377,6 +402,28 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType& r } }; + auto get_function_processor_for_expression_type_id = + [&](const std::string& type_id_name) -> std::unique_ptr<INodeProcessor> { + switch (function_component_expression.m_data_type) { + case ASTNodeDataType::type_id_t: { + if (function_component_expression.m_data_type.nameOfTypeId() == type_id_name) { + return std::make_unique<FunctionExpressionProcessor<EmbeddedData, EmbeddedData>>(function_component_expression); + } else { + // LCOV_EXCL_START + throw ParseError("unexpected error: undefined expression value type for function", + std::vector{node.children[1]->begin()}); + // LCOV_EXCL_STOP + } + } + // LCOV_EXCL_START + default: { + throw ParseError("unexpected error: undefined expression value type for function", + std::vector{node.children[1]->begin()}); + } + // LCOV_EXCL_STOP + } + }; + auto get_function_processor_for_value = [&]() { switch (return_value_type) { case ASTNodeDataType::bool_t: { @@ -439,6 +486,9 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType& r } case ASTNodeDataType::string_t: { return get_function_processor_for_expression_value(std::string{}); + } + case ASTNodeDataType::type_id_t: { + return get_function_processor_for_expression_type_id(return_value_type.nameOfTypeId()); } // LCOV_EXCL_START default: { @@ -464,9 +514,19 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node std::unique_ptr function_processor = this->_buildArgumentConverter(function_descriptor, node); auto add_component_expression = [&](ASTNode& expression_node, const ASTNode& image_domain_node) { - Assert(image_domain_node.m_data_type == ASTNodeDataType::typename_t); - - const ASTNodeDataType return_value_type = image_domain_node.m_data_type.contentType(); + const ASTNodeDataType return_value_type = [&] { + switch (image_domain_node.m_data_type) { + case ASTNodeDataType::typename_t: { + return image_domain_node.m_data_type.contentType(); + } + case ASTNodeDataType::type_id_t: { + return ASTNodeDataType::build<ASTNodeDataType::type_id_t>(image_domain_node.m_data_type.nameOfTypeId()); + } + default: { + throw UnexpectedError("invalid function return type"); + } + } + }(); ASTNodeNaturalConversionChecker<AllowRToR1Conversion>{expression_node, return_value_type}; @@ -477,8 +537,19 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node ASTNode& function_image_domain = *function_descriptor.domainMappingNode().children[1]; ASTNode& function_expression = *function_descriptor.definitionNode().children[1]; - Assert(function_image_domain.m_data_type == ASTNodeDataType::typename_t); - const ASTNodeDataType function_return_type = function_image_domain.m_data_type.contentType(); + const ASTNodeDataType function_return_type = [&] { + switch (function_image_domain.m_data_type) { + case ASTNodeDataType::typename_t: { + return function_image_domain.m_data_type.contentType(); + } + case ASTNodeDataType::type_id_t: { + return ASTNodeDataType::build<ASTNodeDataType::type_id_t>(function_image_domain.m_data_type.nameOfTypeId()); + } + default: { + throw UnexpectedError("invalid function return type"); + } + } + }(); if (function_image_domain.is_type<language::vector_type>()) { ASTNodeDataType vector_type = getVectorDataType(function_image_domain);