Description
nim js
prevents valid compile time functionality, see example below.
I'd like to be able to call code at CT with nim js
, and it should works just like it does with nim c
Example
import std/json
const jsonNode = parseJson("12") # in my application, use case is to read/process at CT a config file
# note that getEnv and readFile do work at compile time with `nim js`
Current Output
json.nim(939, 12) Error: cannot 'importc' variable at compile time; parseNativeJson
return parseNativeJson(buffer).convertObject()
Expected Output
should compile
Possible Solution
here's the relevant snippet from std/json
when not defined(js):
proc parseJson*(buffer: string): JsonNode = ...
else:
proc parseNativeJson(x: cstring): JSObject {.importc: "JSON.parse".}
proc parseJson*(buffer: string): JsonNode = return parseNativeJson(buffer).convertObject()
the tricky part is when defined(js)
doesn't care whether the procs are used at CT or RT, as the symbol table is defined once.
A workaround could be to use vm callbacks, but that's not a general solution (would require 1 callback per proc that needs to be usable at CT)
An actual solution could be a CT import:
# both RT and CT imports can coexist
{.push undef:js.}
# `when defined(js)` become false when the import is processed
import std/json as jsonCT
{.pop.}
# or: import std/json {.undef:js.} as jsonCT
import std/json # `when defined(js)` true for `nim js` when import is processed
const a = jsonCT.parseJson("12") # would use the non-js version
let a = json.parseJson("12") # would use the js version
# no magic implied, the symbol is dictated by visibility of fully qualified identifier
let a = jsonCT.parseJson("12") # CT error: jsonCT.parseJson only usable at CT
const a = json.parseJson("12") # CT error: same as in this issue report
implementation wise: checkModuleName
would assign a distinct suffix to a module imported via {.undef:js.}
(see processUndef
), to make sure it's treated as a different module (similar to how we can now import 2 modules with same name but different paths); likewise with all modules recursively imported by it.
There may be other applications of this idea, eg to test a given windows proc on posix (can be useful in some cases, but won't always work, eg when there are system dependencies involved)
aditional examples
same root cause:
DynlibFormat
at CT withnim js
returnslib$1.so
even if we're on OSXHash
uses 4 bytes instead of 8 bytes with nim js at CT, likenim js
, and unlike withnim c
these are expected with current implementation, but the point is the limitations ofnim js
platform port over to CT code, which could be avoided.
Additional Information
- Was it working in the previous Nim releases?
no
$ nim -v
latest devel 4264e9576d0f3753dcff206fcff06217f2e70833