newCTFE Status July 2017
Stefan Koch via Digitalmars-d
digitalmars-d at puremagic.com
Sun Jul 30 06:34:54 PDT 2017
On Thursday, 13 July 2017 at 12:45:19 UTC, Stefan Koch wrote:
> [ ... ]
Hey Guys!
working on the ctfe brainfuck compiler I finally figured out what
was going wrong.
consider this:
uint fn ()
{
uint[1] pointlessArray = [0];
foreach(0 .. 42)
pointlessArray[0]++;
return pointlessArray[0];
}
static assert(fn() == 42);
until a few minutes ago this would have failed and the output
would have been 0;
can you guess why ?
Well, while the ++array[0] would lower to BinAssignExp (array[0]
+= 1) which does correctly deal with references
++ is actually not lowerd but it's own special expression.
which is handled with the following code:
auto expr = genExpr(e.e1); // in x++ expr is the x
if (!canWorkWithType(expr.type) ||
!canWorkWithType(retval.type))
{
bailout("++ only i32 is supported not " ~
to!string(expr.type.type) ~ " -- " ~ e.toString);
return;
}
assert(expr.vType != BCValueType.Immediate,
"++ does not make sense as on an Immediate
Value");
Set(retval, expr); // return a copy of the old
value
// the following code adds one the the original
value
if (expr.type.type == BCTypeEnum.f23)
{
Add3(expr, expr, BCValue(Imm23f(1.0f)));
}
else if (expr.type.type == BCTypeEnum.f52)
{
Add3(expr, expr, BCValue(Imm52f(1.0)));
}
else
{
Add3(expr, expr, imm32(1));
}
of course arr[x]++ will load the value into a temporary and add
one to that temporary
never modifying the array.
Luckily I introduced a a way for rmw (read-modify-write)
operations to be done on structs on arrays a while back.
if the expr is not normal local i.e. a stack-variable it will
have heapRef which tells you to which pointer you have to write
to modify the actual value rather then just modifying the
temporary in which it was loaded.
so this was fixed by adding the following 3 lines.
if (expr.heapRef)
{
StoreToHeapRef(expr);
}
Which will work for array's slices and structs alike :)
More information about the Digitalmars-d
mailing list