diff options
| author | 2026-10-14 16:17:42 +0330 | |
|---|---|---|
| committer | 2026-10-14 16:17:42 +0330 | |
| commit | b6f4d415c5fae9bfe9243ab0044135ce65492665 (patch) | |
| tree | 2cde21aad5a1e2250784a590a40aa1ffd0f55313 /src/compiler | |
| parent | include: written inside a function body is 'include is top level only' (appen... (diff) | |
ternary: an int side and a float side convert the int on its own path only (appendix b.2.5)
Diffstat (limited to 'src/compiler')
| -rw-r--r-- | src/compiler/expr.zc | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc index ffb90a7..95ce67b 100644 --- a/src/compiler/expr.zc +++ b/src/compiler/expr.zc @@ -1727,7 +1727,7 @@ int storekeep(int t) { // restored for the second side) and then joined, so a variable can't be given // away on one side only. both sides are fresh objects, or neither is. int ternary(int c) { - int a, b, s0, sa, livea, live0 = live, n0 = nloc, ca, cb, ta, ba, bb; word temp_a, temp_b, mask_a, mask_b; + int a, b, s0, sa, livea, live0 = live, n0 = nloc, ca, cb, ta, ba, bb, conv, skip, back; word temp_a, temp_b, mask_a, mask_b; rval(); plainuse(c); ftest(); next(); @@ -1735,6 +1735,7 @@ int ternary(int c) { s0 = snap_push(); ca = expr(); rval(); ta = xty; ba = xbor; temp_a = xaf; mask_a = effect_mask(ca); if (ca != C_FRESH) plainuse(ca); + conv = -1; if (isnum(ta) && !isfl(ta) && ta != tword) { conv = hole(); op(O_JMP); back = here; setlit(conv, back); } // a jump to the next word, redirected below if the other side is a float (appendix b.2.5) livea = live; sa = snap_push(); b = hole(); op(O_JMP); expect(s_colon); @@ -1742,11 +1743,14 @@ int ternary(int c) { snap_restore(s0); live = live0; cb = expr(); rval(); bb = xbor; temp_b = xaf; mask_b = effect_mask(cb); if (cb != C_FRESH) plainuse(cb); + if (isfl(ta) && !isfl(xty)) { op(OP_I2F); xfloat = 1; xty = tfloat; } // on the second side's path only join2(sa, livea, b, live, n0, "ends the two sides of ?: in different states"); snap_pop(s0); - if (isfl(ta) && !isfl(xty)) { op(OP_I2F); xfloat = 1; xty = tfloat; } + if (conv >= 0 && isfl(xty)) { // the first side was an integer: convert it out of line + skip = hole(); op(O_JMP); setlit(conv, here); op(OP_I2F); lit(back); op(O_JMP); setlit(skip, here); + } if (!compat(ta, xty) && !compat(xty, ta)) tcerr("the two sides of ?:", ta, xty); - if (ta != tword && !isfl(ta)) xty = ta; + if (ta != tword && !isfl(ta) && !(conv >= 0 && isfl(xty))) xty = ta; else if (isfl(ta) || isfl(xty)) { xty = tfloat; xfloat = 1; } if_value = 0; effect_value = mask_a | mask_b; |
