Skip to content

Commit

Permalink
more c_type weirdness
Browse files Browse the repository at this point in the history
  • Loading branch information
slavek-kucera committed Sep 17, 2021
1 parent d36512e commit a9b8173
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum class character_expression_purpose
{
assignment,
left_side_of_comparison,
function_parameter,
};

// base class for conditional assembly expressions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void ca_function_binary_operator::resolve_expression_tree(context::SET_t_enum ki
if (expr_kind != kind)
add_diagnostic(diagnostic_op::error_CE004(expr_range));
else if ((function == ca_expr_ops::FIND || function == ca_expr_ops::INDEX)
&& !left_expr->is_character_expression(character_expression_purpose::left_side_of_comparison))
&& !left_expr->is_character_expression(character_expression_purpose::function_parameter))
add_diagnostic(diagnostic_op::error_CE004(left_expr->expr_range));
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,15 @@ void ca_function_unary_operator::resolve_expression_tree(context::SET_t_enum kin
if (expr_kind != kind)
add_diagnostic(diagnostic_op::error_CE004(expr_range));
else
expr->resolve_expression_tree(ca_common_expr_policy::get_operands_type(function, kind));
{
auto param_type = ca_common_expr_policy::get_operands_type(function, kind);
expr->resolve_expression_tree(param_type);

// TODO: additional types?
if (param_type == context::SET_t_enum::C_TYPE
&& !expr->is_character_expression(character_expression_purpose::function_parameter))
expr->add_diagnostic(diagnostic_op::error_CE017_character_expression_expected(expr->expr_range));
}
}

context::SET_t ca_function_unary_operator::operation(context::SET_t operand, const evaluation_context& eval_ctx) const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ void ca_expr_list::collect_diags() const
collect_diags_from_child(*expr);
}

bool ca_expr_list::is_character_expression(character_expression_purpose) const { return false; }
bool ca_expr_list::is_character_expression(character_expression_purpose purpose) const
{
return purpose == character_expression_purpose::assignment && expr_list.size() == 1
&& expr_list.front()->is_character_expression(purpose);
}

void ca_expr_list::apply(ca_expr_visitor& visitor) const { visitor.visit(*this); }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,27 @@ void ca_function::resolve_expression_tree(context::SET_t_enum kind)
else
{
for (auto&& expr : parameters)
{
expr->resolve_expression_tree(param_kind);

// TODO: other parameter types?
if (param_kind == context::SET_t_enum::C_TYPE)
{
if (!expr->is_character_expression(character_expression_purpose::function_parameter))
expr->add_diagnostic(
diagnostic_op::error_CE017_character_expression_expected(expr->expr_range));
}
}
}
}
}

void ca_function::collect_diags() const
{
// nothing to collect
for (auto&& expr : parameters)
collect_diags_from_child(*expr);
if (duplication_factor)
collect_diags_from_child(*duplication_factor);
}

bool ca_function::is_character_expression(character_expression_purpose purpose) const
Expand Down
2 changes: 1 addition & 1 deletion parser_library/test/expressions/ca_expr_list_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ TEST(ca_expr_list, is_character_expression)
// ('low')
ca_expr_list expr_list(std::move(list), range());

EXPECT_FALSE(expr_list.is_character_expression(character_expression_purpose::assignment));
EXPECT_TRUE(expr_list.is_character_expression(character_expression_purpose::assignment));
EXPECT_FALSE(expr_list.is_character_expression(character_expression_purpose::left_side_of_comparison));
}

Expand Down
19 changes: 19 additions & 0 deletions parser_library/test/expressions/character_expression_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ TEST(character_expresssion, single_operand_with_spaces)
&C1 SETC UPPER( 'A' )
&C2 SETC UPPER( 'A')
&C3 SETC UPPER('A' )
&C4 SETC UPPER('&C1')
&C5 SETC (UPPER '&C1')
)";
analyzer a(input);
a.analyze();
Expand All @@ -154,6 +156,23 @@ TEST(character_expresssion, single_operand_with_spaces)
SETCEQ("C1", "A");
SETCEQ("C2", "A");
SETCEQ("C3", "A");
SETCEQ("C4", "A");
SETCEQ("C5", "A");
}

TEST(character_expresssion, single_operand_fail)
{
for (std::string input : {
"&C SETC UPPER(&C)",
"&C SETC (UPPER &C)",
})
{
analyzer a(input);
a.analyze();

a.collect_diags();
EXPECT_FALSE(a.diags().empty());
}
}

TEST(character_expresssion, zero_length_substring)
Expand Down

0 comments on commit a9b8173

Please sign in to comment.