Skip to content

Commit 2e2bece

Browse files
committed
Tweak operators
Add back unary `+` and `-` as prefix operators (with `!` these are the natural, and currently only, prefix operators) Add recognizing `*` or `&` as must-be-binary if followed by a literal (as when followed by `(` or an identifier)
1 parent 92ff88c commit 2e2bece

File tree

3 files changed

+32
-8
lines changed

3 files changed

+32
-8
lines changed

source/cppfront.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,10 +1830,14 @@ class cppfront
18301830
auto suffix = std::string{};
18311831
for (auto const& x : n.ops) {
18321832
assert(x);
1833-
assert(x->type() == lexeme::Not); // should be the only prefix operator
1834-
printer.add_pad_in_this_line(-3);
1835-
printer.print_cpp2("!(", n.position());
1836-
suffix += ")";
1833+
if (x->type() == lexeme::Not) {
1834+
printer.print_cpp2("!(", n.position());
1835+
printer.add_pad_in_this_line(-3);
1836+
suffix += ")";
1837+
}
1838+
else {
1839+
printer.print_cpp2(*x, x->position());
1840+
}
18371841
}
18381842
assert(n.expr);
18391843
emit(*n.expr);

source/lex.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ enum class lexeme : std::int8_t {
9595
Identifier
9696
};
9797

98+
auto is_literal(lexeme l) {
99+
switch (l) {
100+
break;case lexeme::FloatLiteral:
101+
case lexeme::BinaryLiteral:
102+
case lexeme::DecimalLiteral:
103+
case lexeme::HexadecimalLiteral:
104+
case lexeme::StringLiteral:
105+
case lexeme::CharacterLiteral: return true;
106+
break;default: return false;
107+
}
108+
}
109+
98110
// TODO: Remove the duplication above/below with a variadic macro,
99111
// but for now it's simpler just to write it out
100112

source/parse.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,14 @@ auto violates_lifetime_safety = false;
3737
//G
3838
auto is_prefix_operator(lexeme l) -> bool
3939
{
40-
return l == lexeme::Not;
40+
switch (l) {
41+
break;case lexeme::Not:
42+
case lexeme::Minus:
43+
case lexeme::Plus:
44+
return true;
45+
break;default:
46+
return false;
47+
}
4148
}
4249

4350

@@ -1389,9 +1396,10 @@ class parser
13891396
curr().type() == lexeme::Dot
13901397
)
13911398
{
1392-
// * & and ~ can't be a unary operator if followed by ( or identifier
1393-
if ((curr().type() == lexeme::Multiply || curr().type() == lexeme::Ampersand || curr().type() == lexeme::Tilde) &&
1394-
(peek(1)->type() == lexeme::LeftParen || peek(1)->type() == lexeme::Identifier))
1399+
// * and & can't be a unary operator if followed by a (, identifier, or literal
1400+
if ((curr().type() == lexeme::Multiply || curr().type() == lexeme::Ampersand) &&
1401+
peek(1) &&
1402+
(peek(1)->type() == lexeme::LeftParen || peek(1)->type() == lexeme::Identifier || is_literal(peek(1)->type())))
13951403
{
13961404
break;
13971405
}

0 commit comments

Comments
 (0)