目录

      在开始之前,先回顾下之前写的文章《》,在文章里大概地写了生成代码的几个步骤,读者看了可能还不太理解,这是根据我的开发经验写出来的。现在具体写写实现的方法。

      一、引入一个生成代码的文件

      比如要生成arduino代码,就要引入生成arduino代码的文件,要生成python代码,就要引入python文件。

      这个生成代码的文件是从blockly引入进来的,scratch-blocks是在blockly的基础上开发出来的。现在的scratch-blocks是没有generators目录的,这个也可以从blockly那里copy过来。
      具体分析blockly的python.js代码:

      blockly.python = new blockly.generator('python');

      python是blockl.generator的一个实例,会调用generator里的方法;

      blockly.python.addreservedwords(...);

      这方法的作用是给python添加关键字,blockly的python文件已经设置了许多python的关键字在里面了。

      blockly.python.order_atomic = 0;            // 0 "" ...
      blockly.python.order_collection = 1;        // tuples, lists, dictionaries
      blockly.python.order_string_conversion = 1; // `expression...`
      blockly.python.order_member = 2.1;          // . []
      blockly.python.order_function_call = 2.2;   // ()
      blockly.python.order_exponentiation = 3;    // **
      blockly.python.order_unary_sign = 4;        // + -
      blockly.python.order_bitwise_not = 4;       // ~
      blockly.python.order_multiplicative = 5;    // * / // %
      blockly.python.order_additive = 6;          // + -
      blockly.python.order_bitwise_shift = 7;     // << >>
      blockly.python.order_bitwise_and = 8;       // &
      blockly.python.order_bitwise_xor = 9;       // ^
      blockly.python.order_bitwise_or = 10;       // |
      blockly.python.order_relational = 11;       // in, not in, is, is not,
                                                  //     <, <=, >, >=, <>, !=, ==
      blockly.python.order_logical_not = 12;      // not
      blockly.python.order_logical_and = 13;      // and
      blockly.python.order_logical_or = 14;       // or
      blockly.python.order_conditional = 15;      // if else
      blockly.python.order_lambda = 16;           // lambda
      blockly.python.order_none = 99;             // (...)

      以上代码设置了优先级。
      blockly.python的其他方法请参考blockly的python文件。

      二、定义生成的python代码

      需要对每个block定义生成的代码。

      1、获取block的type

      block是根据type来区分的,每个block的type是唯一的。scratch-blocks的基本blocks的定义是在scratch-blocks\blocks_vertical目录里。
      具体可以查阅之前的博客《》

      以下是一个type为“motion_movesteps”的block块的定义

      blockly.blocks['motion_movesteps'] = {
        /**
         * block to move steps.
         * @this blockly.block
         */
        init: function() {
          this.jsoninit({
            "message0": blockly.msg.motion_movesteps,
            "args0": [
              {
                "type": "input_value",
                "name": "steps"
              }
            ],
            "category": blockly.categories.motion,
            "extensions": ["colours_motion", "shape_statement"]
          });
        }
      };

      定义生成的python语句:

       blockly.python['motion_movesteps'] = function (block) {
              var steps = blockly.python.valuetocode(block, "steps", blockly.python.order_none);
              return 'move ' + steps + ' steps\n';
          };

      2、获取参数的值

      根据参数的类型,选择blockly.python.valuetocode、block.getfieldvalue还是blockly.python.statementtocode来获取值。

      type类型 方法
      input_value blockly.python.valuetocode
      input_statement blockly.python.statementtocode
      field_* block.getfieldvalue

      3、从xml来解析一个块的组成结构

      这是motion_movesteps块的xml结构,它由两个block组成,”motion_movesteps”和“math_number”,shadow也是一个block;

      <block type="motion_movesteps">
                  <value name="steps">
                      <shadow type="math_number">
                          <field name="num">10</field>
                      </shadow>
                  </value>
              </block>
      

      所以除了上面已经定义好的”motion_movesteps”生成python语句,还需要的定义math_number的生成语句

      blockly.python['math_number'] = function(block) {
        // numeric value.
        var code = parsefloat(block.getfieldvalue('num'));
        var order;
        if (code == infinity) {
          code = 'float("inf")';
          order = blockly.python.order_function_call;
        } else if (code == -infinity) {
          code = '-float("inf")';
          order = blockly.python.order_unary_sign;
        } else {
          order = code < 0 ? blockly.python.order_unary_sign :
                  blockly.python.order_atomic;
        }
        return [code, order];
      }

      4、根据块的形状来设置return的数据类型

      形状 return的类型
      字符串
      字符串
      [code, order] 数组
      [code, order] 数组

      引入模块:blockly.python.definitions_[模块名] = ”import xxxx”;
      声明函数:blockly.python.definitions_[模块名] = ”def xxx …”;

      三、生成python代码

      在scratch-gui/src/containers/block.jsx文件中,对workspace添加监听

       this.workspace.addchangelistener(this.generatpythoncode);

      四、结语

      本文主要介绍了blocks生成python代码的方法,由于篇幅有限,写的也不是很全面,不过大概地生成方法也就这些。如果在开发地过程中碰到问题,可以私信我给我留言,我尽可能地帮助大家解决问题

      到此这篇关于scratch3.0二次开发之用blocks生成python代码的文章就介绍到这了,更多相关scratch blocks生成python代码内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!