www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - CTFE Evaluation with JSON Objects

reply rbscott <tjonsies818 yahoo.com> writes:
Hello,

I am running into an error during compilation and I can't figure 
out a way to work around it. The use case is pretty simple, to 
pull an integer out of a JSON Object at compile time.

import std.json;

void main()
{
     // Basic, should be the same principle?
     const jsonNumber = new JSONValue(1);
     pragma(msg, jsonNumber.integer);

     // Why does this work?
     const jsonObject = parseJSON(`{ "str" : "string", "integer": 
2 }`);
     pragma(msg, jsonObject["str"].str);

     // Why does this fail?
     pragma(msg, jsonObject["integer"].integer);
}

All of the compilers seem to fail with the error, "Error: 
reinterpretation through overlapped field integer is not allowed 
in CTFE". I think this is related to working with unions at 
compile time, but a. I am not sure why it doesn't happen when 
using a new JSONValue directly, and b. how to work around this 
limitation. Looking at the JSONValue source, the store is private 
and so even using a C cast wouldn't work without modifying the 
source.

Any thoughts or ideas?

thanks!
rbscott
Jan 22
parent reply Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Wednesday, 22 January 2020 at 10:17:43 UTC, rbscott wrote:
 Hello,

 [snip]

 Any thoughts or ideas?

 thanks!
 rbscott
Hi, I hope this helps: ```D import std.json; void main() {    // 1) Use `enum` instead of `const` to    // guarantee that the value will be    // computed at compile-time.    // 2) Don't use `new` for enum values    // as we currently don't have a robust    // mechanism to materialize heap-allocated values.    enum jsonNumber = JSONValue(1); pragma(msg, jsonNumber.integer);    // Q: Why does this work?    // A: Although reinterpretation through unions    // is (mostly?) forbidden during CTFE, you can    // still read union members that have been    // written to before.    const jsonObject = parseJSON(`{ "my key" : "some value", "integer": 42 }`);    pragma(msg, jsonObject["my key"].str);    // Q: Why does this fail?    // A: Because of a slightly obscure implementation    // detail of std.json:    // https://github.com/dlang/phobos/blob/45b2b0d1ad67ee041cf67e4e10c9e225b75acb18/std/json.d#L1275-L1281    // Basically, if the value read is a non-negative    // integer, the `uinteger` union member is set,    // however if the value is <= 2^^63,    // then the `JSONType.integer` type is set,    // which prevents reading through the uinteger() JSONValue property.    // This can be worked around by directly accessing    // the `store` private field using `.tupleof[0]`:    pragma(msg, jsonObject["integer"].tupleof[0].uinteger); } ``` Cheers, Petar
Jan 22
next sibling parent rbscott <tjonsies818 yahoo.com> writes:
On Thursday, 23 January 2020 at 00:20:24 UTC, Petar Kirov 
[ZombineDev] wrote:
 Hi,

 I hope this helps:

 ```D
 import std.json;

 void main()
 {
     const jsonObject = parseJSON(`{ "my key" : "some value", 
 "integer": 42 }`);
     pragma(msg, jsonObject["my key"].str);
     pragma(msg, jsonObject["integer"].tupleof[0].uinteger);
 }
 ```

 Cheers,
 Petar
Hi Petar, This worked perfectly. I was stuck on that for a while, and now I understand what is going on. Using tupleof is a nice trick! Thanks! rbscott
Jan 23
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/22/20 7:20 PM, Petar Kirov [ZombineDev] wrote:
      // Q: Why does this fail?
      // A: Because of a slightly obscure implementation
      // detail of std.json:
      // 
 https://github.com/dlang/phobos/blob/45b2b0d1ad67ee041cf67e4e10c9e225b75acb18/st
/json.d#L1275-L1281 
 
      // Basically, if the value read is a non-negative
      // integer, the `uinteger` union member is set,
      // however if the value is <= 2^^63,
      // then the `JSONType.integer` type is set,
      // which prevents reading through the uinteger() JSONValue property.
This is a bug in std.json that can/should be fixed. https://issues.dlang.org/show_bug.cgi?id=20527 I'll whip up a PR. -Steve
Jan 23
parent reply James Blachly <james.blachly gmail.com> writes:
On 1/23/20 8:00 AM, Steven Schveighoffer wrote:
 
 This is a bug in std.json that can/should be fixed.
 
 https://issues.dlang.org/show_bug.cgi?id=20527
 
 I'll whip up a PR.
 
 -Steve
Steve, thanks for addressing. This kind of ergonomic friction (writ large) hampers adoption of the language overall IMO. You are doing great work to make D accessible. James
Jan 25
parent rbscott <tjonsies818 yahoo.com> writes:
On Saturday, 25 January 2020 at 15:53:28 UTC, James Blachly wrote:
 On 1/23/20 8:00 AM, Steven Schveighoffer wrote:
 
 This is a bug in std.json that can/should be fixed.
 
 https://issues.dlang.org/show_bug.cgi?id=20527
 
 I'll whip up a PR.
 
 -Steve
Hi Steve, Thanks for the fast bug fix! cheers, rbscott
Jan 30