Skip to content

Commit ae78fb1

Browse files
committed
C generator: remove redundant parentheses
* pass precedence level to `emitExpr2()`, `emitBinaryOperator()`, `emitUnaryOperator()`... * only generate extra parentheses in C output when needed * rename ast_utils/c2_prec.c2 as common/c2_prec.c2 * move `Prec_table` to common/c2_prec.c2 * move `C_Prec` and `C_Prec_table` to common/c_prec.c2
1 parent d433b89 commit ae78fb1

21 files changed

+244
-200
lines changed

analyser/module_analyser_binop.c2

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
module module_analyser;
1717

1818
import ast local;
19+
import c_prec local;
1920
import c2_prec local;
2021
import conversion_checker;
2122
import ctv_analyser;
@@ -401,70 +402,6 @@ const u8[elemsof(TypeKind)][elemsof(TypeKind)] BinOpConvComparision = {
401402
// Alias + Module are zero
402403
}
403404

404-
const Prec[elemsof(BinaryOpcode)] Prec_table = {
405-
[BinaryOpcode.Multiply] = Multiplicative,
406-
[BinaryOpcode.Divide] = Multiplicative,
407-
[BinaryOpcode.Remainder] = Multiplicative,
408-
[BinaryOpcode.Add] = Additive,
409-
[BinaryOpcode.Subtract] = Additive,
410-
[BinaryOpcode.ShiftLeft] = Shift,
411-
[BinaryOpcode.ShiftRight] = Shift,
412-
[BinaryOpcode.LessThan] = Relational,
413-
[BinaryOpcode.GreaterThan] = Relational,
414-
[BinaryOpcode.LessEqual] = Relational,
415-
[BinaryOpcode.GreaterEqual] = Relational,
416-
[BinaryOpcode.Equal] = Relational,
417-
[BinaryOpcode.NotEqual] = Relational,
418-
[BinaryOpcode.And] = Bitwise,
419-
[BinaryOpcode.Xor] = Bitwise,
420-
[BinaryOpcode.Or] = Bitwise,
421-
[BinaryOpcode.LAnd] = LogicalAndOr,
422-
[BinaryOpcode.LOr] = LogicalAndOr,
423-
[BinaryOpcode.Assign] = Assignment,
424-
[BinaryOpcode.MulAssign] = Assignment,
425-
[BinaryOpcode.DivAssign] = Assignment,
426-
[BinaryOpcode.RemAssign] = Assignment,
427-
[BinaryOpcode.AddAssign] = Assignment,
428-
[BinaryOpcode.SubAssign] = Assignment,
429-
[BinaryOpcode.ShlAssign] = Assignment,
430-
[BinaryOpcode.ShrAssign] = Assignment,
431-
[BinaryOpcode.AndAssign] = Assignment,
432-
[BinaryOpcode.XorAssign] = Assignment,
433-
[BinaryOpcode.OrAssign] = Assignment,
434-
}
435-
436-
const C_Prec[elemsof(BinaryOpcode)] C_Prec_table = {
437-
[BinaryOpcode.Multiply] = Multiplicative,
438-
[BinaryOpcode.Divide] = Multiplicative,
439-
[BinaryOpcode.Remainder] = Multiplicative,
440-
[BinaryOpcode.Add] = Additive,
441-
[BinaryOpcode.Subtract] = Additive,
442-
[BinaryOpcode.ShiftLeft] = Shift,
443-
[BinaryOpcode.ShiftRight] = Shift,
444-
[BinaryOpcode.LessThan] = Relative,
445-
[BinaryOpcode.GreaterThan] = Relative,
446-
[BinaryOpcode.LessEqual] = Relative,
447-
[BinaryOpcode.GreaterEqual] = Relative,
448-
[BinaryOpcode.Equal] = Equality,
449-
[BinaryOpcode.NotEqual] = Equality,
450-
[BinaryOpcode.And] = And,
451-
[BinaryOpcode.Xor] = Xor,
452-
[BinaryOpcode.Or] = Or,
453-
[BinaryOpcode.LAnd] = LogicalAnd,
454-
[BinaryOpcode.LOr] = LogicalOr,
455-
[BinaryOpcode.Assign] = Assignment,
456-
[BinaryOpcode.MulAssign] = Assignment,
457-
[BinaryOpcode.DivAssign] = Assignment,
458-
[BinaryOpcode.RemAssign] = Assignment,
459-
[BinaryOpcode.AddAssign] = Assignment,
460-
[BinaryOpcode.SubAssign] = Assignment,
461-
[BinaryOpcode.ShlAssign] = Assignment,
462-
[BinaryOpcode.ShrAssign] = Assignment,
463-
[BinaryOpcode.AndAssign] = Assignment,
464-
[BinaryOpcode.XorAssign] = Assignment,
465-
[BinaryOpcode.OrAssign] = Assignment,
466-
}
467-
468405
fn QualType Analyser.checkBinopComparison(Analyser* ma, BinaryOperator* b, QualType lhs, QualType rhs) {
469406
QualType lcanon = lhs.getCanonicalType();
470407
QualType rcanon = rhs.getCanonicalType();

ast_utils/c2_prec.c2

Lines changed: 0 additions & 52 deletions
This file was deleted.

common/c2_prec.c2

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/* Copyright 2022-2025 Bas van den Berg
2+
* Copyright 2025 Charlie Gordon
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
module c2_prec;
18+
19+
import ast local;
20+
21+
/// PrecedenceLevels - These have been altered from C99 to C2
22+
/// In particular, addition now comes after bitwise and shifts
23+
/// Bitwise is directly after shift and equality and relational have
24+
/// the same precedence.
25+
26+
public type Prec enum u8 {
27+
Unknown, // Not binary operator.
28+
Comma, // ,
29+
Assignment, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
30+
Conditional, // ?
31+
LogicalAndOr, // &&, ||
32+
Relational, // ==, !=, >=, <=, >, <
33+
Additive, // -, +
34+
Bitwise, // ^, |, &
35+
Shift, // <<, >>
36+
Multiplicative, // *, /, %
37+
}
38+
39+
public const Prec[elemsof(BinaryOpcode)] Prec_table = {
40+
[BinaryOpcode.Multiply] = Multiplicative,
41+
[BinaryOpcode.Divide] = Multiplicative,
42+
[BinaryOpcode.Remainder] = Multiplicative,
43+
[BinaryOpcode.Add] = Additive,
44+
[BinaryOpcode.Subtract] = Additive,
45+
[BinaryOpcode.ShiftLeft] = Shift,
46+
[BinaryOpcode.ShiftRight] = Shift,
47+
[BinaryOpcode.LessThan] = Relational,
48+
[BinaryOpcode.GreaterThan] = Relational,
49+
[BinaryOpcode.LessEqual] = Relational,
50+
[BinaryOpcode.GreaterEqual] = Relational,
51+
[BinaryOpcode.Equal] = Relational,
52+
[BinaryOpcode.NotEqual] = Relational,
53+
[BinaryOpcode.And] = Bitwise,
54+
[BinaryOpcode.Xor] = Bitwise,
55+
[BinaryOpcode.Or] = Bitwise,
56+
[BinaryOpcode.LAnd] = LogicalAndOr,
57+
[BinaryOpcode.LOr] = LogicalAndOr,
58+
[BinaryOpcode.Assign] = Assignment,
59+
[BinaryOpcode.MulAssign] = Assignment,
60+
[BinaryOpcode.DivAssign] = Assignment,
61+
[BinaryOpcode.RemAssign] = Assignment,
62+
[BinaryOpcode.AddAssign] = Assignment,
63+
[BinaryOpcode.SubAssign] = Assignment,
64+
[BinaryOpcode.ShlAssign] = Assignment,
65+
[BinaryOpcode.ShrAssign] = Assignment,
66+
[BinaryOpcode.AndAssign] = Assignment,
67+
[BinaryOpcode.XorAssign] = Assignment,
68+
[BinaryOpcode.OrAssign] = Assignment,
69+
}

common/c_prec.c2

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* Copyright 2022-2025 Bas van den Berg
2+
* Copyright 2025 Charlie Gordon
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
module c_prec;
18+
19+
import ast local;
20+
21+
public type C_Prec enum u8 {
22+
Unknown, // Not binary operator.
23+
Comma, // ,
24+
Assignment, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
25+
Conditional, // ?
26+
LogicalOr, // ||
27+
LogicalAnd, // &&
28+
Or, // |
29+
Xor, // ^
30+
And, // &
31+
Equality, // !=, ==
32+
Relative, // >=, <=, >, <
33+
Shift, // <<, >>
34+
Additive, // -, +
35+
Multiplicative, // *, /, %
36+
Prefix, // unary !, +, -, ~, &, *, prefix ++, --, c-cast
37+
Postfix, // .member, ->member, [], (), postfix ++, --
38+
}
39+
40+
public const C_Prec[elemsof(BinaryOpcode)] C_Prec_table = {
41+
[BinaryOpcode.Multiply] = Multiplicative,
42+
[BinaryOpcode.Divide] = Multiplicative,
43+
[BinaryOpcode.Remainder] = Multiplicative,
44+
[BinaryOpcode.Add] = Additive,
45+
[BinaryOpcode.Subtract] = Additive,
46+
[BinaryOpcode.ShiftLeft] = Shift,
47+
[BinaryOpcode.ShiftRight] = Shift,
48+
[BinaryOpcode.LessThan] = Relative,
49+
[BinaryOpcode.GreaterThan] = Relative,
50+
[BinaryOpcode.LessEqual] = Relative,
51+
[BinaryOpcode.GreaterEqual] = Relative,
52+
[BinaryOpcode.Equal] = Equality,
53+
[BinaryOpcode.NotEqual] = Equality,
54+
[BinaryOpcode.And] = And,
55+
[BinaryOpcode.Xor] = Xor,
56+
[BinaryOpcode.Or] = Or,
57+
[BinaryOpcode.LAnd] = LogicalAnd,
58+
[BinaryOpcode.LOr] = LogicalOr,
59+
[BinaryOpcode.Assign] = Assignment,
60+
[BinaryOpcode.MulAssign] = Assignment,
61+
[BinaryOpcode.DivAssign] = Assignment,
62+
[BinaryOpcode.RemAssign] = Assignment,
63+
[BinaryOpcode.AddAssign] = Assignment,
64+
[BinaryOpcode.SubAssign] = Assignment,
65+
[BinaryOpcode.ShlAssign] = Assignment,
66+
[BinaryOpcode.ShrAssign] = Assignment,
67+
[BinaryOpcode.AndAssign] = Assignment,
68+
[BinaryOpcode.XorAssign] = Assignment,
69+
[BinaryOpcode.OrAssign] = Assignment,
70+
}

generator/c/c_generator.c2

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
module c_generator;
1717

1818
import ast local;
19+
import c_prec local;
1920
import diagnostics;
2021
import build_file;
2122
import build_target;
@@ -530,9 +531,9 @@ fn bool emitAsDefine(const VarDecl* vd) {
530531
return false;
531532
}
532533

533-
fn void Generator.emitConstExpr(Generator* gen, string_buffer.Buf* out, Expr* e) {
534+
fn void Generator.emitConstExpr(Generator* gen, string_buffer.Buf* out, Expr* e, C_Prec prec) {
534535
gen.need_const_expr++;
535-
gen.emitExpr(out, e);
536+
gen.emitExpr2(out, e, prec);
536537
gen.need_const_expr--;
537538
}
538539

@@ -565,7 +566,7 @@ fn bool Generator.emitGlobalVarDecl(Generator* gen, string_buffer.Buf* out, Decl
565566
out.add("#define ");
566567
gen.emitCName(out, d);
567568
out.space();
568-
gen.emitConstExpr(out, vd.getInit());
569+
gen.emitConstExpr(out, vd.getInit(), Postfix);
569570
out.newline();
570571
return true;
571572
}
@@ -607,7 +608,7 @@ fn bool Generator.emitGlobalVarDecl(Generator* gen, string_buffer.Buf* out, Decl
607608
out.add(" = ");
608609
Expr* ie = vd.getInit();
609610
if (ie) {
610-
gen.emitConstExpr(out, ie);
611+
gen.emitConstExpr(out, ie, Assignment);
611612
} else {
612613
// auto-initialize (only required for embedded targets)
613614
gen.emitAutoInit(out, d.getType());

generator/c/c_generator_call.c2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ fn void Generator.emitCall(Generator* gen, string_buffer.Buf* out, Expr* e) {
100100
gen.emitExpr(out, func);
101101
out.add1(')');
102102
} else {
103-
gen.emitExpr(out, func);
103+
gen.emitExpr2(out, func, Postfix);
104104
}
105105
out.lparen();
106106
}
@@ -166,7 +166,7 @@ fn void Generator.emitCall(Generator* gen, string_buffer.Buf* out, Expr* e) {
166166
args[call_index++] : func_args[func_index].getInit();
167167
if (arg.isInitList()) {
168168
Decl* d = cast<Decl*>(func_args[func_index]);
169-
gen.emitCast(out, d.getType());
169+
gen.emitCast(out, d.getType(), true);
170170
}
171171
gen.emitExpr(out, arg);
172172
}

0 commit comments

Comments
 (0)