Don't emit extra parentheses when outputting HLSL/GLSL (#674)
Don't emit extra parentheses when outputting HLSL/GLSL (#674)

When emitting high-level expressions we obviously need to avoid emitting expressions that mean something different than the original code. So if we had IR like:

```
%t0 = add %a %b
%t1 = mul %t0 c
```

and `t0` isn't used anywhere else in the code, we can emit HLSL like:

```hlsl
float t1 = (a + b) * c;
```

but not:

```hlsl
float t1 = a + b *c; // oops! precedence changed the meaning!
```

The existing strategy in Slang has been to be overly conservative about when it emits parentheses to guarantee precedence is respected, so you might get something like:

```hlsl
float t1 = ((a) + (b)) * (c);
```

which not only looks silly, but also leads to unhelpful diagnostics from the clang-based dxc, about all those extra parentheses being redundant.

This change follows the pattern of (and actually reuses some code from) the old AST emit logic from earlier in the compiler's life (before the IR was introduced). The basic idea is that when emitting an expression we track the precedence of the expressions to its left and right, and use those to decide if parentheses are needed, and then to compute equivalent precedences to apply for sub-expressions.

Applied correcty, this approach lets us emit minimal "unparsed" expressions. Applied incorrectly it could lead to subtle errors where the code Slang outputs doesn't faithfully represent the input. Here's hoping we get this right.
csyonghe/slang,shader-slang/slang,csyonghe/slang,shader-slang/slang,csyonghe/slang,shader-slang/slang