From 48ab6d06ec29e5c930aaec5ad0e32f03b3f60db8 Mon Sep 17 00:00:00 2001 From: Ajay Brahmakshatriya Date: Sun, 2 Nov 2025 18:40:06 -0500 Subject: [PATCH] Fixed C Code Generator to use actual operator precedence to decide where brackets are required --- include/blocks/c_code_generator.h | 2 +- include/builder/dyn_var.h | 14 ++- samples/outputs.var_names/sample1 | 2 +- samples/outputs.var_names/sample3 | 2 +- samples/outputs.var_names/sample31 | 2 +- samples/outputs.var_names/sample33 | 4 +- samples/outputs.var_names/sample37 | 8 +- samples/outputs.var_names/sample38 | 2 +- samples/outputs.var_names/sample43 | 2 +- samples/outputs.var_names/sample44 | 2 +- samples/outputs.var_names/sample46 | 2 +- samples/outputs.var_names/sample53 | 20 ++-- samples/outputs.var_names/sample56 | 4 +- samples/outputs.var_names/sample57 | 2 +- samples/outputs.var_names/sample59 | 2 +- samples/outputs.var_names/sample60 | 2 +- samples/outputs.var_names/sample63 | 2 +- samples/outputs.var_names/sample64 | 2 +- samples/outputs/sample1 | 2 +- samples/outputs/sample3 | 2 +- samples/outputs/sample31 | 2 +- samples/outputs/sample33 | 4 +- samples/outputs/sample37 | 8 +- samples/outputs/sample38 | 2 +- samples/outputs/sample43 | 2 +- samples/outputs/sample44 | 2 +- samples/outputs/sample46 | 2 +- samples/outputs/sample53 | 20 ++-- samples/outputs/sample56 | 4 +- samples/outputs/sample57 | 2 +- samples/outputs/sample59 | 2 +- samples/outputs/sample60 | 2 +- samples/outputs/sample63 | 2 +- samples/outputs/sample64 | 2 +- src/blocks/c_code_generator.cpp | 158 ++++++++++++++--------------- 35 files changed, 149 insertions(+), 145 deletions(-) diff --git a/include/blocks/c_code_generator.h b/include/blocks/c_code_generator.h index 7e7cc7e..45711b5 100644 --- a/include/blocks/c_code_generator.h +++ b/include/blocks/c_code_generator.h @@ -79,7 +79,6 @@ class c_code_generator : public block_visitor { virtual void visit(builder_var_type::Ptr); virtual void visit(named_type::Ptr); - void handle_func_arg(var::Ptr a); virtual void visit(func_decl::Ptr); virtual void visit(struct_decl::Ptr); virtual void visit(return_stmt::Ptr); @@ -90,6 +89,7 @@ class c_code_generator : public block_visitor { virtual void visit(label_stmt::Ptr); void print_pragma(stmt::Ptr); + void handle_child(expr::Ptr parent, expr::Ptr child, bool is_left); static void generate_code(block::Ptr ast, std::ostream &oss, int indent = 0, bool decl_only = false) { c_code_generator generator(oss); diff --git a/include/builder/dyn_var.h b/include/builder/dyn_var.h index 219c2ae..7b6560d 100644 --- a/include/builder/dyn_var.h +++ b/include/builder/dyn_var.h @@ -91,21 +91,21 @@ class dyn_var_impl : public var { template - builder operator()(const types &...args) { + builder operator()(const types &...args) const { return ((builder) * this)(args...); } // These three need to be defined inside the class, cannot be defined globally - builder operator[](const builder &a) { + builder operator[](const builder &a) const { return ((builder) * this)[a]; } - builder operator*(void) { + builder operator*(void) const { return *((builder) * this); } - builder operator!() { + builder operator!() const { return !(builder) * this; } - operator bool() { + operator bool() const { return (bool)(builder) * this; } @@ -333,6 +333,10 @@ class dyn_var_impl : public var { // TODO: Consider using dynamic_cast here return (dyn_var *)this; } + const dyn_var *addr(void) const { + // TODO: Consider using dynamic_cast here + return (const dyn_var *)this; + } }; template diff --git a/samples/outputs.var_names/sample1 b/samples/outputs.var_names/sample1 index 09314f0..b813f34 100644 --- a/samples/outputs.var_names/sample1 +++ b/samples/outputs.var_names/sample1 @@ -122,5 +122,5 @@ STMT_BLOCK a_0 = a_0 & b_1; a_0 = a_0 | b_1; a_0 = a_0 ^ b_1; - ~(b_1); + ~b_1; } diff --git a/samples/outputs.var_names/sample3 b/samples/outputs.var_names/sample3 index c54d3f3..b0fb49d 100644 --- a/samples/outputs.var_names/sample3 +++ b/samples/outputs.var_names/sample3 @@ -79,7 +79,7 @@ STMT_BLOCK int a_0; int b_1; int c_2; - if (!(c_2)) { + if (!c_2) { a_0 && b_1; if (a_0 && b_1) { c_2 && b_1; diff --git a/samples/outputs.var_names/sample31 b/samples/outputs.var_names/sample31 index b5cd74c..1d6d6aa 100644 --- a/samples/outputs.var_names/sample31 +++ b/samples/outputs.var_names/sample31 @@ -28,7 +28,7 @@ FUNC_DECL (func1) VAR_EXPR VAR (var1) int func1 (foo arg0) { - foo z_0 = (3 + arg0.var1) + (5 * arg0.var1); + foo z_0 = 3 + arg0.var1 + 5 * arg0.var1; int var1 = z_0.neighbor + 2; return var1; } diff --git a/samples/outputs.var_names/sample33 b/samples/outputs.var_names/sample33 index 9bd7044..1570ed9 100644 --- a/samples/outputs.var_names/sample33 +++ b/samples/outputs.var_names/sample33 @@ -49,6 +49,6 @@ STMT_BLOCK int x_1 = g_0.member; FooT h_2 = g_0; h_2 = g_0; - FooT* ptr_3 = (&(g_0)); - (ptr_3[0]).member = 0; + FooT* ptr_3 = &g_0; + ptr_3[0].member = 0; } diff --git a/samples/outputs.var_names/sample37 b/samples/outputs.var_names/sample37 index a0b8471..afcf303 100644 --- a/samples/outputs.var_names/sample37 +++ b/samples/outputs.var_names/sample37 @@ -1,16 +1,16 @@ void __global__ cuda_kernel_0 (int* arg0) { - int thread_id_2 = (blockIdx.x * 512) + threadIdx.x; + int thread_id_2 = blockIdx.x * 512 + threadIdx.x; arg0[thread_id_2] = 0; } void __global__ cuda_kernel_1 (int* arg0) { - int thread_id_5 = (blockIdx.x * 512) + threadIdx.x; + int thread_id_5 = blockIdx.x * 512 + threadIdx.x; arg0[thread_id_5] = 0; } char ret_2_0[sizeof(int*)] __device__; void __global__ cuda_kernel_2 (int* arg0) { - int thread_id_8 = (blockIdx.x * 512) + threadIdx.x; + int thread_id_8 = blockIdx.x * 512 + threadIdx.x; arg0[thread_id_8] = 0; if (!(blockIdx.x * blockDim.x + threadIdx.x)) { runtime::cudaMemcpyToSymbolMagic(ret_2_0, arg0); @@ -24,6 +24,6 @@ void bar (int* arg0) { cudaDeviceSynchronize(); runtime::LaunchCooperativeKernel((void*)cuda_kernel_2, 128, 512, arg0); cudaDeviceSynchronize(); - runtime::cudaMemcpyFromSymbolMagic((&(arg0)), ret_2_0); + runtime::cudaMemcpyFromSymbolMagic(&arg0, ret_2_0); } diff --git a/samples/outputs.var_names/sample38 b/samples/outputs.var_names/sample38 index 03e8fce..993dfc5 100644 --- a/samples/outputs.var_names/sample38 +++ b/samples/outputs.var_names/sample38 @@ -70,7 +70,7 @@ STMT_BLOCK int x_1 = g_0.member; FooT h_2 = g_0; h_2 = g_0; - FooT* ptr_3 = (&(g_0)); + FooT* ptr_3 = &g_0; ptr_3->member = 0; ptr_3->member = 1; FooT i_4 = ptr_3[0]; diff --git a/samples/outputs.var_names/sample43 b/samples/outputs.var_names/sample43 index 5fc6d6d..91de929 100644 --- a/samples/outputs.var_names/sample43 +++ b/samples/outputs.var_names/sample43 @@ -37,7 +37,7 @@ void foo (void) { int var28; int* var29; var28 = 0; - var21 = (&(var22)); + var21 = &var22; int var30 = var20; int* var31 = var21; int var32 = var22; diff --git a/samples/outputs.var_names/sample44 b/samples/outputs.var_names/sample44 index 8f00ea7..4ee9458 100644 --- a/samples/outputs.var_names/sample44 +++ b/samples/outputs.var_names/sample44 @@ -8,7 +8,7 @@ void staged (void) { if (var2) { } int var3 = 0; - (var1 != 1) && (var3 != 1); + var1 != 1 && var3 != 1; } void staged2 (void) { diff --git a/samples/outputs.var_names/sample46 b/samples/outputs.var_names/sample46 index 17f21f5..9f64e87 100644 --- a/samples/outputs.var_names/sample46 +++ b/samples/outputs.var_names/sample46 @@ -108,6 +108,6 @@ void my_bar (void) { FooT* i_5; i_5->member = l_4.my_member; i_5->member = 0; - (i_5[3]).member = 0; + i_5[3].member = 0; } diff --git a/samples/outputs.var_names/sample53 b/samples/outputs.var_names/sample53 index fc7ad35..17addcd 100644 --- a/samples/outputs.var_names/sample53 +++ b/samples/outputs.var_names/sample53 @@ -6,34 +6,34 @@ void foo (void) { } else { member_var = 2; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 0; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 1; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 2; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 3; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 4; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 5; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 6; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 7; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 8; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 9; } } diff --git a/samples/outputs.var_names/sample56 b/samples/outputs.var_names/sample56 index f3c916b..80566d6 100644 --- a/samples/outputs.var_names/sample56 +++ b/samples/outputs.var_names/sample56 @@ -57,8 +57,8 @@ void bar (void) { my_type a_0; custom_struct0 b_1; a_0.nested = b_1; - (a_0.nested).mem0 = a_0.mem0; - ((a_0.nested).mem1 = (a_0.nested).mem1 + 1) - 1; + a_0.nested.mem0 = a_0.mem0; + (a_0.nested.mem1 = a_0.nested.mem1 + 1) - 1; p.mem0 = 0; } diff --git a/samples/outputs.var_names/sample57 b/samples/outputs.var_names/sample57 index cd9bcd2..2d06169 100644 --- a/samples/outputs.var_names/sample57 +++ b/samples/outputs.var_names/sample57 @@ -1,6 +1,6 @@ void bar (void) { int x_0 = 0; - int* y_1 = (&(x_0)); + int* y_1 = &x_0; (y_1[0] = y_1[0] + 1) - 1; int z_2 = 0; (z_2 = z_2 + 1) - 1; diff --git a/samples/outputs.var_names/sample59 b/samples/outputs.var_names/sample59 index 21dfa51..824b379 100644 --- a/samples/outputs.var_names/sample59 +++ b/samples/outputs.var_names/sample59 @@ -24,6 +24,6 @@ FUNC_DECL (bar) void bar (void) { std::vector> x_0; x_0.resize(2); - (x_0[0]).resize(1); + x_0[0].resize(1); } diff --git a/samples/outputs.var_names/sample60 b/samples/outputs.var_names/sample60 index 3281a0d..1b0cd13 100644 --- a/samples/outputs.var_names/sample60 +++ b/samples/outputs.var_names/sample60 @@ -16,7 +16,7 @@ void bar (void) { } else { res_12 = m_4; } - int* var14 = (&(x_0)); + int* var14 = &x_0; var14[0] = 0; } diff --git a/samples/outputs.var_names/sample63 b/samples/outputs.var_names/sample63 index 90d53bd..1642289 100644 --- a/samples/outputs.var_names/sample63 +++ b/samples/outputs.var_names/sample63 @@ -4,7 +4,7 @@ struct linked_list { }; void bar (void) { linked_list* x_0; - ((x_0->next)->next)->next = 0; + x_0->next->next->next = 0; x_0->other = 0; } diff --git a/samples/outputs.var_names/sample64 b/samples/outputs.var_names/sample64 index a07c994..c979100 100644 --- a/samples/outputs.var_names/sample64 +++ b/samples/outputs.var_names/sample64 @@ -3,7 +3,7 @@ int power (int arg0, int arg1) { int res_1 = 1; int x_2 = arg0; while (exponent_0 > 1) { - if ((exponent_0 % 2) == 1) { + if (exponent_0 % 2 == 1) { res_1 = res_1 * x_2; } x_2 = x_2 * x_2; diff --git a/samples/outputs/sample1 b/samples/outputs/sample1 index 3792c17..b83aaab 100644 --- a/samples/outputs/sample1 +++ b/samples/outputs/sample1 @@ -122,5 +122,5 @@ STMT_BLOCK var0 = var0 & var1; var0 = var0 | var1; var0 = var0 ^ var1; - ~(var1); + ~var1; } diff --git a/samples/outputs/sample3 b/samples/outputs/sample3 index 8a60082..e1de9ab 100644 --- a/samples/outputs/sample3 +++ b/samples/outputs/sample3 @@ -79,7 +79,7 @@ STMT_BLOCK int var0; int var1; int var2; - if (!(var2)) { + if (!var2) { var0 && var1; if (var0 && var1) { var2 && var1; diff --git a/samples/outputs/sample31 b/samples/outputs/sample31 index 34e5e51..c24b6ae 100644 --- a/samples/outputs/sample31 +++ b/samples/outputs/sample31 @@ -28,7 +28,7 @@ FUNC_DECL (func1) VAR_EXPR VAR (var1) int func1 (foo arg0) { - foo var0 = (3 + arg0.var1) + (5 * arg0.var1); + foo var0 = 3 + arg0.var1 + 5 * arg0.var1; int var1 = var0.neighbor + 2; return var1; } diff --git a/samples/outputs/sample33 b/samples/outputs/sample33 index dfe2565..76b70f0 100644 --- a/samples/outputs/sample33 +++ b/samples/outputs/sample33 @@ -49,6 +49,6 @@ STMT_BLOCK int var1 = var0.member; FooT var2 = var0; var2 = var0; - FooT* var3 = (&(var0)); - (var3[0]).member = 0; + FooT* var3 = &var0; + var3[0].member = 0; } diff --git a/samples/outputs/sample37 b/samples/outputs/sample37 index 91667e3..333bc74 100644 --- a/samples/outputs/sample37 +++ b/samples/outputs/sample37 @@ -1,16 +1,16 @@ void __global__ cuda_kernel_0 (int* arg0) { - int var2 = (blockIdx.x * 512) + threadIdx.x; + int var2 = blockIdx.x * 512 + threadIdx.x; arg0[var2] = 0; } void __global__ cuda_kernel_1 (int* arg0) { - int var5 = (blockIdx.x * 512) + threadIdx.x; + int var5 = blockIdx.x * 512 + threadIdx.x; arg0[var5] = 0; } char ret_2_0[sizeof(int*)] __device__; void __global__ cuda_kernel_2 (int* arg0) { - int var8 = (blockIdx.x * 512) + threadIdx.x; + int var8 = blockIdx.x * 512 + threadIdx.x; arg0[var8] = 0; if (!(blockIdx.x * blockDim.x + threadIdx.x)) { runtime::cudaMemcpyToSymbolMagic(ret_2_0, arg0); @@ -24,6 +24,6 @@ void bar (int* arg0) { cudaDeviceSynchronize(); runtime::LaunchCooperativeKernel((void*)cuda_kernel_2, 128, 512, arg0); cudaDeviceSynchronize(); - runtime::cudaMemcpyFromSymbolMagic((&(arg0)), ret_2_0); + runtime::cudaMemcpyFromSymbolMagic(&arg0, ret_2_0); } diff --git a/samples/outputs/sample38 b/samples/outputs/sample38 index 7fda647..fd586bd 100644 --- a/samples/outputs/sample38 +++ b/samples/outputs/sample38 @@ -70,7 +70,7 @@ STMT_BLOCK int var1 = var0.member; FooT var2 = var0; var2 = var0; - FooT* var3 = (&(var0)); + FooT* var3 = &var0; var3->member = 0; var3->member = 1; FooT var4 = var3[0]; diff --git a/samples/outputs/sample43 b/samples/outputs/sample43 index 5fc6d6d..91de929 100644 --- a/samples/outputs/sample43 +++ b/samples/outputs/sample43 @@ -37,7 +37,7 @@ void foo (void) { int var28; int* var29; var28 = 0; - var21 = (&(var22)); + var21 = &var22; int var30 = var20; int* var31 = var21; int var32 = var22; diff --git a/samples/outputs/sample44 b/samples/outputs/sample44 index f29fee2..5899e67 100644 --- a/samples/outputs/sample44 +++ b/samples/outputs/sample44 @@ -8,7 +8,7 @@ void staged (void) { if (var2) { } int var3 = 0; - (var1 != 1) && (var3 != 1); + var1 != 1 && var3 != 1; } void staged2 (void) { diff --git a/samples/outputs/sample46 b/samples/outputs/sample46 index edff4af..66a738b 100644 --- a/samples/outputs/sample46 +++ b/samples/outputs/sample46 @@ -108,6 +108,6 @@ void my_bar (void) { FooT* var5; var5->member = var4.my_member; var5->member = 0; - (var5[3]).member = 0; + var5[3].member = 0; } diff --git a/samples/outputs/sample53 b/samples/outputs/sample53 index 2ad533b..1cda47f 100644 --- a/samples/outputs/sample53 +++ b/samples/outputs/sample53 @@ -6,34 +6,34 @@ void foo (void) { } else { member_var = 2; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 0; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 1; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 2; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 3; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 4; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 5; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 6; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 7; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 8; } - if ((member_var % 2) == 0) { + if (member_var % 2 == 0) { member_var = member_var + 9; } } diff --git a/samples/outputs/sample56 b/samples/outputs/sample56 index 89aa061..443e6d8 100644 --- a/samples/outputs/sample56 +++ b/samples/outputs/sample56 @@ -57,8 +57,8 @@ void bar (void) { my_type var0; custom_struct0 var1; var0.nested = var1; - (var0.nested).mem0 = var0.mem0; - ((var0.nested).mem1 = (var0.nested).mem1 + 1) - 1; + var0.nested.mem0 = var0.mem0; + (var0.nested.mem1 = var0.nested.mem1 + 1) - 1; p.mem0 = 0; } diff --git a/samples/outputs/sample57 b/samples/outputs/sample57 index 78d541b..2905aba 100644 --- a/samples/outputs/sample57 +++ b/samples/outputs/sample57 @@ -1,6 +1,6 @@ void bar (void) { int var0 = 0; - int* var1 = (&(var0)); + int* var1 = &var0; (var1[0] = var1[0] + 1) - 1; int var2 = 0; (var2 = var2 + 1) - 1; diff --git a/samples/outputs/sample59 b/samples/outputs/sample59 index 1ae8706..64b6497 100644 --- a/samples/outputs/sample59 +++ b/samples/outputs/sample59 @@ -24,6 +24,6 @@ FUNC_DECL (bar) void bar (void) { std::vector> var0; var0.resize(2); - (var0[0]).resize(1); + var0[0].resize(1); } diff --git a/samples/outputs/sample60 b/samples/outputs/sample60 index 4820151..d0c196d 100644 --- a/samples/outputs/sample60 +++ b/samples/outputs/sample60 @@ -16,7 +16,7 @@ void bar (void) { } else { var12 = var4; } - int* var14 = (&(var0)); + int* var14 = &var0; var14[0] = 0; } diff --git a/samples/outputs/sample63 b/samples/outputs/sample63 index 593ee4c..dada18e 100644 --- a/samples/outputs/sample63 +++ b/samples/outputs/sample63 @@ -4,7 +4,7 @@ struct linked_list { }; void bar (void) { linked_list* var0; - ((var0->next)->next)->next = 0; + var0->next->next->next = 0; var0->other = 0; } diff --git a/samples/outputs/sample64 b/samples/outputs/sample64 index 3d0d861..a278b1e 100644 --- a/samples/outputs/sample64 +++ b/samples/outputs/sample64 @@ -3,7 +3,7 @@ int power (int arg0, int arg1) { int var1 = 1; int var2 = arg0; while (var0 > 1) { - if ((var0 % 2) == 1) { + if (var0 % 2 == 1) { var1 = var1 * var2; } var2 = var2 * var2; diff --git a/src/blocks/c_code_generator.cpp b/src/blocks/c_code_generator.cpp index c531a75..7a51e67 100644 --- a/src/blocks/c_code_generator.cpp +++ b/src/blocks/c_code_generator.cpp @@ -42,45 +42,85 @@ void c_code_generator::nextl(void) { #endif + +struct precedence_t { + int pred; + bool is_left_assoc; +}; + +static precedence_t get_operator_precedence(expr::Ptr a) { + // expressions that have no precedence + if (isa(a) || isa(a)) + return {0, true}; + + if (isa(a) || isa(a) || isa(a)) { + return {2, true}; + } else if (isa(a) || isa(a) || isa(a) || isa(a)) { + return {3, false}; + } else if (isa(a) || isa(a) || isa(a)) { + return {5, true}; + } else if (isa(a) || isa(a)) { + return {6, true}; + } else if (isa(a) || isa(a)) { + return {7, true}; + } else if (isa(a) || isa(a) || isa(a) || isa(a)) { + return {9, true}; + } else if (isa(a) || isa(a)) { + return {10, true}; + } else if (isa(a)) { + return {11, true}; + } else if (isa(a)) { + return {12, true}; + } else if (isa(a)) { + return {13, true}; + } else if (isa(a)) { + return {14, true}; + } else if (isa(a)) { + return {15, true}; + } else if (isa(a)) { + return {16, false}; + } + assert(false && "Invalid operator for precedence"); +} + +// Determine if bracket should be added around the child +static bool expr_needs_bracket(expr::Ptr parent, expr::Ptr child, bool is_left) { + precedence_t pp = get_operator_precedence(parent); + precedence_t pc = get_operator_precedence(child); + if (pc.pred > pp.pred) return true; + if (pc.pred < pp.pred) return false; + // equal case + if (pc.is_left_assoc == is_left) return false; + return true; +} + +void c_code_generator::handle_child(expr::Ptr parent, expr::Ptr child, bool is_left) { + bool bracket = expr_needs_bracket(parent, child, is_left); + if (bracket) oss << "("; + child->accept(this); + if (bracket) oss << ")"; +} + + void c_code_generator::visit(not_expr::Ptr a) { - oss << "!("; - a->expr1->accept(this); - oss << ")"; + oss << "!"; + handle_child(a, a->expr1, false); } void c_code_generator::visit(unary_minus_expr::Ptr a) { - oss << "-("; - a->expr1->accept(this); - oss << ")"; + oss << "-"; + handle_child(a, a->expr1, false); } void c_code_generator::visit(bitwise_not_expr::Ptr a) { - oss << "~("; - a->expr1->accept(this); - oss << ")"; + oss << "~"; + handle_child(a, a->expr1, false); } -static bool expr_needs_bracket(expr::Ptr a) { - if (isa(a)) - return true; - else if (isa(a)) - return true; - return false; -} void c_code_generator::emit_binary_expr(binary_expr::Ptr a, std::string character) { - if (expr_needs_bracket(a->expr1)) { - oss << "("; - a->expr1->accept(this); - oss << ")"; - } else - a->expr1->accept(this); + handle_child(a, a->expr1, true); oss << " " << character << " "; - if (expr_needs_bracket(a->expr2)) { - oss << "("; - a->expr2->accept(this); - oss << ")"; - } else - a->expr2->accept(this); + handle_child(a, a->expr2, false); } void c_code_generator::visit(and_expr::Ptr a) { emit_binary_expr(a, "&&"); @@ -161,15 +201,9 @@ void c_code_generator::visit(string_const::Ptr a) { oss << "\"" << a->value << "\""; } void c_code_generator::visit(assign_expr::Ptr a) { - if (expr_needs_bracket(a->var1)) { - oss << "("; - a->var1->accept(this); - oss << ")"; - } else - a->var1->accept(this); - + handle_child(a, a->var1, true); oss << " = "; - a->expr1->accept(this); + handle_child(a, a->expr1, false); } void c_code_generator::visit(expr_stmt::Ptr a) { @@ -452,27 +486,17 @@ void c_code_generator::visit(continue_stmt::Ptr a) { oss << "continue;"; } void c_code_generator::visit(sq_bkt_expr::Ptr a) { - if (expr_needs_bracket(a->var_expr)) { - oss << "("; - } - a->var_expr->accept(this); - if (expr_needs_bracket(a->var_expr)) { - oss << ")"; - } + handle_child(a, a->var_expr, true); oss << "["; + // index never needs to be bracketed no matter what a->index->accept(this); oss << "]"; } void c_code_generator::visit(function_call_expr::Ptr a) { - if (expr_needs_bracket(a->expr1)) { - oss << "("; - } - a->expr1->accept(this); - if (expr_needs_bracket(a->expr1)) { - oss << ")"; - } + handle_child(a, a->expr1, true); oss << "("; for (unsigned int i = 0; i < a->args.size(); i++) { + // We don't have a comma operator, so we dont need brackets a->args[i]->accept(this); if (i != a->args.size() - 1) oss << ", "; @@ -482,26 +506,13 @@ void c_code_generator::visit(function_call_expr::Ptr a) { void c_code_generator::visit(initializer_list_expr::Ptr a) { oss << "{"; for (unsigned int i = 0; i < a->elems.size(); i++) { + // We don't have a comma operator, so we dont need brackets a->elems[i]->accept(this); if (i != a->elems.size() - 1) oss << ", "; } oss << "}"; } -void c_code_generator::handle_func_arg(var::Ptr a) { - function_type::Ptr type = to(a->var_type); - type->return_type->accept(this); - oss << " (*"; - oss << a->var_name; - oss << ")("; - for (unsigned int i = 0; i < type->arg_types.size(); i++) { - type->arg_types[i]->accept(this); - if (i != type->arg_types.size() - 1) - oss << ", "; - } - oss << ")"; - return; -} void c_code_generator::visit(func_decl::Ptr a) { #ifdef ENABLE_D2X @@ -590,13 +601,7 @@ void c_code_generator::visit(member_access_expr::Ptr a) { if (isa(parent->index)) { auto index = to(parent->index); if (index->value == 0) { - if (!isa(parent->var_expr)) { - oss << "("; - } - parent->var_expr->accept(this); - if (!isa(parent->var_expr)) { - oss << ")"; - } + handle_child(a, parent->var_expr, true); oss << "->" << a->member_name; return; } @@ -604,17 +609,12 @@ void c_code_generator::visit(member_access_expr::Ptr a) { } } - if (!isa(a->parent_expr)) - oss << "("; - a->parent_expr->accept(this); - if (!isa(a->parent_expr)) - oss << ")"; + handle_child(a, a->parent_expr, true); oss << "." << a->member_name; } void c_code_generator::visit(addr_of_expr::Ptr a) { - oss << "(&("; - a->expr1->accept(this); - oss << "))"; + oss << "&"; + handle_child(a, a->expr1, false); } } // namespace block