nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.58k stars 1.47k forks source link

in JS backend, importcpp string is used to get a function pointer by the compiler cause a syntax error with # in generated output #14535

Open mildred opened 4 years ago

mildred commented 4 years ago

I got a strange javascript error with my code: SyntaxError: private fields are not currently supported

The generated javascript function looks like:

function bind_value_12246249() {
    function HEX3Aanonymous_12246256(re_12246262) {
        function HEX3Aanonymous_12246263(e_12246265) {
          // ...
        }

      var F={procname:"bindValue.:anonymous",prev:framePtr,filename:"util.nim",line:0};
      framePtr = F;
        if (re_12246262.init) {
        F.line = 237;
        re_12246262.node.addEventListener("change", HEX3Aanonymous_12246263, false);
        }

        F.line = 239;
        (re_12246262.node).value = #.value;
      framePtr = F.prev;

    }
    // ...
}

The error is: (re_12246262.node).value = #.value; which is obviously not a valid javascript syntax (or perhaps will be with private fields, but I suppose this was not intended). The nim procedure is:

proc bindValue*[T](typ: typedesc[T]): ProcRefresh[T] =
  return proc(re: RefreshEvent[T]) =
    if re.init:
      re.node.addEventListener("change") do(e: dom.Event):
        re.set(re.node.toJs["value"].to(T))
    re.node.toJs.value = value

There is an error in the above function, on its last line (re.node.toJs.value = value), the value on the right hand side is not bound to a function argument. I believe it's not bound in the global scope too (but perhaps I'm wrong here). In any case, it should not produce erroneous javascript.

The correct writing of that line is: re.node.toJs.value = re.data.toJs

I believe the compiler should have stopped producing an error telling that value cannot be bound to anything.

The error can be reproduced with: https://github.com/mildred/nclearseam/commit/5706b88750033dd13f2f0cd1f9cb1f2e40fce009

$ nim js samples/compute/calcul_meubles
$ python -m http.server 8000
$ firefox http://localhost:8000/samples/compute/

Nim version:

Nim Compiler Version 1.2.0 [Linux: amd64]
Compiled at 2020-04-03
Copyright (c) 2006-2020 by Andreas Rumpf

active boot switches: -d:release
mildred commented 4 years ago

I was wrong with value not bound in scope, there is in scope the dom module with:

proc value*(n: Node): cstring {.importcpp: "#.value", nodecl.}
proc `value=`*(n: Node; v: cstring) {.importcpp: "#.value = #", nodecl.}

It seems the first procedure has been used but without any argument, and the # has been preserved in the javascript output.