From 5d3e5b3d5c69f60c503eee6221e5b1135e728809 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Thu, 19 Sep 2019 14:49:28 +0200 Subject: [PATCH] Prepare complex type handling Grammar allows constructions such as `` let f : R*R -> R*R, x -> x; `` This expression does not actually compiles since expression types are not correctly defined, thus semantic analysis fails --- src/language/ASTBuilder.cpp | 117 ++++++++++++------------ src/language/ASTNodeDataTypeBuilder.cpp | 2 +- src/language/PEGGrammar.hpp | 6 +- 3 files changed, 64 insertions(+), 61 deletions(-) diff --git a/src/language/ASTBuilder.cpp b/src/language/ASTBuilder.cpp index 984ed5cba..239da703c 100644 --- a/src/language/ASTBuilder.cpp +++ b/src/language/ASTBuilder.cpp @@ -62,7 +62,7 @@ struct ASTBuilder::simplify_unary : parse_tree::apply<ASTBuilder::simplify_unary transform(std::unique_ptr<ASTNode>& n, States&&... st) { if (n->children.size() == 1) { - if (n->is<unary_expression>()) { + if (n->is<unary_expression>() or n->is<type_expression>()) { n->remove_content(); n = std::move(n->children.back()); transform(n, st...); @@ -201,63 +201,64 @@ struct ASTBuilder::simplify_stream_statement : parse_tree::apply<ASTBuilder::sim }; template <typename Rule> -using selector = parse_tree::selector< - Rule, - parse_tree::store_content::on<true_kw, - false_kw, - integer, - real, - literal, - name, - B_set, - N_set, - Z_set, - R_set, - string_type, - cout_kw, - cerr_kw, - clog_kw, - declaration, - let_declaration, - function_domain_mapping, - function_definition, - if_statement, - do_while_statement, - while_statement, - for_statement, - break_kw, - continue_kw>, - ASTBuilder::rearrange::on<product, affectation, expression>, - ASTBuilder::simplify_unary::on<unary_minus, unary_plus, unary_not, function_evaluation, unary_expression>, - parse_tree::remove_content::on<plus_op, - minus_op, - multiply_op, - divide_op, - lesser_op, - lesser_or_eq_op, - greater_op, - greater_or_eq_op, - eqeq_op, - not_eq_op, - and_op, - or_op, - xor_op, - eq_op, - multiplyeq_op, - divideeq_op, - pluseq_op, - minuseq_op, - unary_plusplus, - unary_minusminus, - post_minusminus, - post_plusplus>, - ASTBuilder::simplify_for_statement_block::on<for_statement_block>, - parse_tree::discard_empty::on<ignored, semicol, block>, - ASTBuilder::simplify_statement_block::on<statement_block>, - ASTBuilder::simplify_for_init::on<for_init>, - ASTBuilder::simplify_for_test::on<for_test>, - ASTBuilder::simplify_for_post::on<for_post>, - ASTBuilder::simplify_stream_statement::on<ostream_statement>>; +using selector = + parse_tree::selector<Rule, + parse_tree::store_content::on<true_kw, + false_kw, + integer, + real, + literal, + name, + B_set, + N_set, + Z_set, + R_set, + string_type, + cout_kw, + cerr_kw, + clog_kw, + declaration, + let_declaration, + type_mapping, + function_definition, + if_statement, + do_while_statement, + while_statement, + for_statement, + break_kw, + continue_kw>, + ASTBuilder::rearrange::on<product, affectation, expression>, + ASTBuilder::simplify_unary:: + on<unary_minus, unary_plus, unary_not, function_evaluation, type_expression, unary_expression>, + parse_tree::remove_content::on<plus_op, + minus_op, + multiply_op, + divide_op, + lesser_op, + lesser_or_eq_op, + greater_op, + greater_or_eq_op, + eqeq_op, + not_eq_op, + and_op, + or_op, + xor_op, + eq_op, + multiplyeq_op, + divideeq_op, + pluseq_op, + minuseq_op, + unary_plusplus, + unary_minusminus, + post_minusminus, + post_plusplus>, + ASTBuilder::simplify_for_statement_block::on<for_statement_block>, + parse_tree::discard_empty::on<ignored, semicol, block>, + ASTBuilder::simplify_statement_block::on<statement_block>, + ASTBuilder::simplify_for_init::on<for_init>, + ASTBuilder::simplify_for_test::on<for_test>, + ASTBuilder::simplify_for_post::on<for_post>, + ASTBuilder::simplify_stream_statement::on<ostream_statement>>; template <typename InputT> std::unique_ptr<ASTNode> diff --git a/src/language/ASTNodeDataTypeBuilder.cpp b/src/language/ASTNodeDataTypeBuilder.cpp index b30adf664..11a812465 100644 --- a/src/language/ASTNodeDataTypeBuilder.cpp +++ b/src/language/ASTNodeDataTypeBuilder.cpp @@ -108,7 +108,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) } else if (n.is<language::eq_op>() or n.is<language::multiplyeq_op>() or n.is<language::divideeq_op>() or n.is<language::pluseq_op>() or n.is<language::minuseq_op>()) { n.m_data_type = n.children[0]->m_data_type; - } else if (n.is<language::function_domain_mapping>() or n.is<language::function_definition>()) { + } else if (n.is<language::type_mapping>() or n.is<language::function_definition>()) { n.m_data_type = ASTNodeDataType::void_t; } else if (n.is<language::for_post>() or n.is<language::for_init>() or n.is<language::for_statement_block>()) { n.m_data_type = ASTNodeDataType::void_t; diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp index 3a8eda150..646842bf3 100644 --- a/src/language/PEGGrammar.hpp +++ b/src/language/PEGGrammar.hpp @@ -203,10 +203,12 @@ struct affectation : seq< NAME , if_must< affect_op, expression > >{}; struct declaration : if_must< TYPESPECIFIER, NAME, opt< if_must< seq< one< '=' >, ignored >, expression > > >{}; -struct function_domain_mapping : seq< TYPESPECIFIER, RIGHT_ARROW, TYPESPECIFIER >{}; +struct type_expression : list_must< TYPESPECIFIER, one< '*' > >{}; + +struct type_mapping : seq< type_expression, RIGHT_ARROW, type_expression >{}; struct function_definition : seq< NAME, RIGHT_ARROW, expression >{}; -struct let_declaration : if_must< LET, NAME, COLUMN, function_domain_mapping, COMMA, function_definition >{}; +struct let_declaration : if_must< LET, NAME, COLUMN, type_mapping, COMMA, function_definition >{}; struct open_brace : seq< one< '{' >, ignored >{}; struct close_brace : seq< one< '}' >, ignored >{}; -- GitLab