0

I want to preface this by saying I'm new to JavaScript, blockly and most certainly the use of Neil Fraser JS-interpreter.

I've made some custom blocks that simply create JavaScript that when eval() put an object of its block type and user inputs into an array.

The function they use to do this is called pushInstruction(blockName, inputs); where inputs is an array of the blocks user inputs, and blockName is the name of the block.

Now I am trying to use the JS-interpreter, but the problem is with how I go about using these blocks with it.

I'm desperate for help, and for the life of me can't find any resources to help me. It may be something silly.

Custom block code

Blockly.Blocks['select_hand_position'] = {
  init: function() {
    this.appendDummyInput()
        .appendField("Move");
    this.appendDummyInput()
        .appendField(new Blockly.FieldDropdown([["left hand","Left hand"], ["right hand","Right hand"]]), "handSelect")
        .appendField("to index")
        .appendField(new Blockly.FieldNumber(0), "indexSelect");
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(290);
 this.setTooltip("");
 this.setHelpUrl("");
  }
};
Blockly.JavaScript['select_hand_position'] = function(block) {
  var dropdown_handselect = block.getFieldValue('handSelect');
  var number_indexselect = block.getFieldValue('indexSelect'); 
  var input = '["'+dropdown_handselect+'",'+number_indexselect+']';
  var code = 'pushInstruction("select_hand_position",'+input+');'               
  return code;
};

I have a global array to hold the objects

instructionStructure = new Array();

which is then used in this function, of which is the one that the blocks generate code to use.

function pushInstruction(blockName,inputs) {  
  var instruction = null;
  switch(blockName) {
    case "place_book":
    case "grab_book":
    case "select_hand_position":
      instruction = {
        blockName: blockName,
        hand: inputs[0],
        index: inputs[1].toString()
      };
      instructionStructure.push(instruction);
      break;

    default:
      throw 'attempted to push unknown instruction block';
  }       
} 

Step Code

here is the code that is run upon button press of the step button

function stepCode() {
  Blockly.JavaScript.STATEMENT_PREFIX = 'highlightBlock(%1);\n';
  Blockly.JavaScript.addReservedWords('highlightBlock');
  var code = Blockly.JavaScript.workspaceToCode(workspace);
  var myInterpreter = new Interpreter(code, initApi);
  function nextStep() {
    if (myInterpreter.step()) {
      window.setTimeout(nextStep, 1000);
    }
  }
  nextStep();
  alert(instructionStructure);
}

initAPI function

this is where i keep getting a

Uncaught TypeError: Interpreter.setProperty is not a function

on the line

Interpreter.setProperty(scope, 'pushInstruction', interpreter.createNativeFunction(wrapper));

function initApi(interpreter, scope) {

  var wrapper = function(id) {
    id = id ? id.toString() : '';
    return interpreter.createPrimitive(highlightBlock(id));
  };
  interpreter.setProperty(scope, 'highlightBlock',
      interpreter.createNativeFunction(wrapper));


  wrapper = function(blockName, inputs) {
    return pushInstruction(blockName,inputs);
  };
  Interpreter.setProperty(scope, 'pushInstruction',
      interpreter.createNativeFunction(wrapper));  
}

Thank you for spending the time to read over this, I greatly appreciate it!

extempl
  • 2,987
  • 1
  • 26
  • 38

1 Answers1

0

You have a typo here:

Interpreter.setProperty(scope, 'pushInstruction',
  interpreter.createNativeFunction(wrapper));  

=>

interpreter.setProperty(scope, 'pushInstruction',
  interpreter.createNativeFunction(wrapper));  

That's for the Uncaught TypeError. Is it the only problem here? Because I don't really got the

but the problem is with how I go about using these blocks with it.

extempl
  • 2,987
  • 1
  • 26
  • 38
  • Thankyou! that was it. Sorry again for it being so simple.However now I am getting another TypeError in the pushInstruction() function. Here is the error - "Uncaught TypeError: Cannot read property 'toString' of undefined" for the line 'index: inputs[1].toString()' – Iamprettybadatthis Feb 28 '19 at 22:56
  • @Iamprettybadatthis that's because `inputs` here is not an array, but an `Interpreter.Object`. You should use `inputs.properties[1].toString()` instead. Same for `inputs.properties[0].toString()` – extempl Mar 01 '19 at 09:28
  • thanks ever so much! would there be a way of changing `inputs` so it is seen as an array and not an `Interpreter.Object`. As I've tried with the properties but gives the type error `Cannot read property '0' of undefined` – Iamprettybadatthis Mar 01 '19 at 17:36
  • @Iamprettybadatthis Uhm, I tried it with latest versions of blockly-demo and it worked well with `properties`. Try this one: https://jsfiddle.net/extempl/ym0hbtdj/ – extempl Mar 01 '19 at 17:54
  • thanks for the help, with a lot of fiddling i managed to get it to work. but i had to use `inputs.a[0].toString()` not properties. any ideas why? I also get this if i console log `inputs`: `qb {O: {…}, R: {…}, a: {…}, na: qb, K: "Array"} K: "Array" O: {} R: {} a: {0: "Left hand", 1: 0, length: 2} na: qb {O: {…}, R: {…}, a: {…}, na: qb} __proto__: Object` do you know the reason its in this format and not the format specified in the generator functions like a simple array `{"name",[-inputs-]}`? thanks for your time! – Iamprettybadatthis Mar 03 '19 at 19:12
  • @Iamprettybadatthis that looks like minified and compressed code, have you tried my version? I am not sure how to use simple array here, I'll check that later – extempl Mar 04 '19 at 04:59
  • yeah i tried using your code but it would return a type error saying `Uncaught TypeError: Cannot read property '0' of undefined`. I wasn't 100% sure of how to structure the code though file wise as I'm not very knowledgeable, so it could have been that – Iamprettybadatthis Mar 05 '19 at 09:22