A few days ago, I changed the Mint compiler to allow non-void code objects to be spliced in where statement form is required:
Code
Code
This essentially generates the code below, which allows the 1
to be discarded:
<| { { Object temp = 1; } } |>;
Eddy pointed out that there is still a problem: Since I do a static type check on the type argument of Code<T>
, the proper form cannot be determined if there is a wildcard Code<?>
. We can check at run-time whether a code object is in statement form or whether it is an expression whose result needs to be discarded, but we cannot simply write an if-statement, because one of the alternatives would always be syntactically incorrect:
<| { if (c.isStat) {
`c; // already in statement form
} else {
Object temp = `c; // expression, discard result
} } |>;
If c.isStat
is true, then the else-branch is syntactically incorrect; if c.isStat
is false, then there is a syntax error in the then-branch. Eddy pointed out that we can handle the Code<?>
case, though, because the two branches are in future-stage code. That is, we can turn
<| { `(c); } |>
into
if (c.isStat) {
<| { `(c); } |>
} else {
<| Object temp = `c; |>
}
Unfortunately, this gets more complicated if there is more than one Code<?>
being escaped in. We would have cases, where is the number of Code<?>
objects being stitched in:
<| { `(c); `(d); } |>
would have to be turned into
if (c.isStat && d.isStat) {
<| { `(c); `(d); } |>
} else if (c.isStat && !d.isStat) {
<| { `(c); { Object temp = `d; } } |>
} else if (!c.isStat && d.isStat) {
<| { { Object temp = `c; } `(d); } |>
} else {
<| { Object temp = `c; } { Object temp = `d; } |>
}
I think for now I will change the compiler so that escaping a Code<?>
in as a statement generates a compiler error. It seems like this is an unimportant corner case, and I don’t want to spend my time on something that is rarely beneficial. Again, this only happens for Code<?>
, and only when escaping into bracket with a code block where statement form is required by Java rules.