Issue with JS-Interpreter and Arrays

48 views
Skip to first unread message

Mike Raptakis

unread,
Jul 4, 2023, 7:12:31 AM7/4/23
to Blockly
Hi to all,

I'm working on a project and I'm using Blockly in conjunction with JS-interpreter to provide a simple programming environment to the end user.

I noticed a strange behavior. When I have a script like the one below, instead of printing the arrays the following is printed.

Screenshot from 2023-07-04 14-08-26.png

{
    "N": {},
    "O": {},
    "h": {},
    "ja": {
        "N": {},
        "O": {},
        "h": {},
        "ja": {
            "N": {},
            "O": {},
            "h": {},
            "ja": null
        },
        "D": "Array"
    },
    "D": "Array"
}
{
    "N": {},
    "O": {},
    "h": {
        "0": 123,
        "1": "Hello"
    },
    "ja": {
        "N": {},
        "O": {},
        "h": {},
        "ja": {
            "N": {},
            "O": {},
            "h": {},
            "ja": null
        },
        "D": "Array"
    },
    "D": "Array"
}

Following is the code for the JS-interpreter API as well as the implementation of the text_print block.
const JSInterpreterAPI = (interpreter, globalObject) => {
const consoleLog = text => {
return console.log(text);
};
javascriptGenerator.addReservedWords('consoleLog');
interpreter.setProperty(
globalObject,
'consoleLog',
interpreter.createNativeFunction(consoleLog)
);
}

const code = javascriptGenerator.workspaceToCode(workspace);
const interpreter = new Interpreter( // eslint-disable-line
Babel.transform(code, { presets: ['es2015'] }).code,
JSInterpreterAPI(proxy)
);
const run = () => {
if (interpreter.run()) {
setTimeout(run, 1000);
}
};
run();

javascriptGenerator['text_print'] = function (block) {
const msg =
javascriptGenerator.valueToCode(block, 'TEXT', javascriptGenerator.ORDER_NONE) || "''";
return `consoleLog(${msg});\n`;
};

Neil Fraser

unread,
Jul 4, 2023, 9:44:22 AM7/4/23
to blo...@googlegroups.com
Whenever debugging Blockly code execution, the best thing to do is alert/console.log the output of the generator.  Just add:
  console.log(code);
That will determine if you are generating bad code (a Blockly problem), or if you are executing it incorrectly (a JS-Interpreter problem).  Splitting the problem in two is a huge help.

That said, I can see the issue.  The 'text' argument of your 'consoleLog' function isn't a string.  It's an array.  Specifically, it's a pseudo-object belonging to the JS-Interpreter.  You just need to force 'text' to be a string.  That's something that 'alert' does automatically, but 'console.log' does not.  Try this:
  const consoleLog = text => {
    console.log(String(text));
  };
Side node: I also removed the 'return' from your function since you don't really want any strange return value from 'console.log' being sent back into the interpreter (it should be 'undefined', but you never know).


--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/fb23d552-8867-4e33-8d4f-73c128dc4ac8n%40googlegroups.com.


--
Neil Fraser, Switzerland
https://neil.fraser.name

Mike Raptakis

unread,
Jul 5, 2023, 2:01:54 AM7/5/23
to Blockly
Thank you for the quick response.

The code that it is generated from Blockly is the following:

consoleLog([]);
consoleLog([123, 'Hello']);

Now, the problem occurs also for any other block that takes a lists as Value Input. So, I don't know if the problem will be solved with the suggested solution.

Christopher Allen

unread,
Jul 5, 2023, 4:54:26 AM7/5/23
to blo...@googlegroups.com
Hi Mike,

Now, the problem occurs also for any other block that takes a lists as Value Input. So, I don't know if the problem will be solved with the suggested solution.

Any block which can be implemented with pure JavaScript (i.e., where the code generated by the custom generator for that block does not call any native functions not already provided by JS Interpreter) will not require any special effort to work with arrays (or objects generally): interpreted JavaScript will deal with interpreter arrays just fine.

The place where arrays do need special handling is in developer-defined native functions, such as your consoleLog.  Here you will either need to write code in a way which is aware of how the interpreter stores object and arrays (referred to as pseudo objects and pseudo arrays in the interpreter source code), or uses pseudoToNative to convert the interpreter objects into native objects (albeit subject to some limitations).


Best wishes,

Christopher

Mike Raptakis

unread,
Jul 6, 2023, 3:30:37 AM7/6/23
to Blockly
It works! Thank you a lot for the explanation!
Reply all
Reply to author
Forward
0 new messages