Skip to content

Commit

Permalink
Require whitespace before binary *, &, ~, closes #152
Browse files Browse the repository at this point in the history
Before this I had been trying out making `a*b` work without whitespace by making `a****b` interpret the final `*` as binary if followed by something that wouldn't make sense if it was unary, but that's a bit subtle. (And similarly for `&` and should also include `~`)

See additional discussion in #152.
  • Loading branch information
hsutter committed Dec 27, 2022
1 parent 9a319fd commit 30c79a0
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
2 changes: 1 addition & 1 deletion regression-tests/mixed-test-parens.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ constexpr int a = 1;

main: () -> int = {
v : std::vector<int> = ( 1, 2, 3 );
std::cout << (1+2)*(3+v[0]);
std::cout << (1+2) * (3+v[0]);
f<(1>2)>(3,4);
f< a+a >(5,6);
}
20 changes: 16 additions & 4 deletions source/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -1375,9 +1375,9 @@ class parser
errors.emplace_back( curr().position(), m );
}

auto error(std::string const& msg, bool = true) const -> void
auto error(std::string const& msg, bool include_curr_token = true) const -> void
{
error(msg.c_str());
error(msg.c_str(), include_curr_token);
}


Expand Down Expand Up @@ -1536,11 +1536,23 @@ class parser
curr().type() == lexeme::Dot
)
{
// * and & can't be a unary operator if followed by a (, identifier, or literal
if ((curr().type() == lexeme::Multiply || curr().type() == lexeme::Ampersand) &&
// these can't be unary operators if followed by a (, identifier, or literal
if ((curr().type() == lexeme::Multiply || curr().type() == lexeme::Ampersand || curr().type() == lexeme::Tilde) &&
peek(1) &&
(peek(1)->type() == lexeme::LeftParen || peek(1)->type() == lexeme::Identifier || is_literal(peek(1)->type())))
{
auto op = curr().to_string(true);
auto msg = "postfix unary " + op;
if (curr().type() == lexeme::Multiply ) { op += " (dereference)" ; }
else if (curr().type() == lexeme::Ampersand) { op += " (address-of)" ; }
else if (curr().type() == lexeme::Tilde ) { op += " (unary bit-complement)"; }
msg += " cannot be immediately followed by a (, identifier, or literal - add whitespace before "
+ op + " here if you meant binary " + op;
if (curr().type() == lexeme::Multiply ) { op += " (multiplication)" ; }
else if (curr().type() == lexeme::Ampersand) { op += " (bitwise and)" ; }
else if (curr().type() == lexeme::Tilde ) { op += " (binarybit-complement)"; }

error(msg, false);
break;
}

Expand Down

0 comments on commit 30c79a0

Please sign in to comment.