docs: 同步日常维护指南并补齐遗漏的板卡配置

This commit is contained in:
yczpf2019
2026-01-24 16:42:42 +08:00
parent a6cdad4b21
commit f166758ec5
373 changed files with 86311 additions and 1 deletions

View File

@@ -0,0 +1,3 @@
node_modules
build
origin

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,773 @@
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Dictionary blocks for Blockly.
* @author acbart@vt.edu (Austin Cory Bart)
*/
import * as Blockly from 'blockly/core';
const DICTS_HUE = 345;
export const dicts_create_with = {
/**
* Block for creating a list with any number of elements of any type.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendDummyInput("")
.appendField(new Blockly.FieldTextInput('mydict'), 'VAR')
.appendField(new Blockly.FieldLabel(Blockly.Msg.DICTS_CREATE_WITH_INPUT_WITH), 'TIP')
this.itemCount_ = 3;
this.updateShape_();
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setMutator(new Blockly.icons.MutatorIcon(['dicts_create_with_item'], this));
this.setTooltip(Blockly.Msg.DICTS_CREATE_WITH_TOOLTIP);
},
/**
* Create XML to represent list inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('dicts_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('dicts_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ADD' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput('ADD' + i);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
}
var keyNames = [];
for (var i = 0; this.getInput('ADD' + i); i++) {
//this.getInput('VALUE' + i).removeField("KEY"+i);
keyNames.push(this.getFieldValue("KEY" + i))
this.removeInput('ADD' + i);
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.getField('TIP').setValue(Blockly.Msg.DICTS_CREATE_EMPTY_TITLE);
} else {
this.getField('TIP').setValue(Blockly.Msg.DICTS_CREATE_WITH_INPUT_WITH);
for (var i = 0; i < this.itemCount_; i++) {
this.appendValueInput('ADD' + i)
.setCheck(null)
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField(
new Blockly.FieldTextInput(
keyNames.length > i
? keyNames[i]
: (i == 0 ? '"key"' : '"key' + (i + 1) + '"')),
'KEY' + i)
.appendField(":")
}
}
}, getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
};
export const dicts_create_with_container = {
/**
* Mutator block for list container.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_TYPE_DICT);
this.appendStatementInput('STACK');
this.setTooltip(Blockly.Msg.DICTS_CREATE_WITH_CONTAINER_TOOLTIP);
this.contextMenu = false;
}
};
export const dicts_create_with_item = {
/**
* Mutator bolck for adding items.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.DICTS_CREATE_WITH_ITEM_TITLE);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.DICTS_CREATE_WITH_ITEM_TOOLTIP);
this.contextMenu = false;
}
};
export const dicts_keys = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict')
this.appendDummyInput("")
.appendField(Blockly.Msg.DICT_KEYS);
this.setTooltip(Blockly.Msg.DICTS_KEYS_TOOLTIP);
this.setOutput(true, 'List');
}
};
export const dicts_get = {
init: function () {
this.setColour(DICTS_HUE);
// this.appendDummyInput("")
// .appendField(Blockly.Msg.DICTS_GET_FROM_DICTS)
this.appendValueInput('DICT')
.setCheck('Dict')
this.appendValueInput('KEY')
.appendField(Blockly.Msg.DICTS_GET_IN)
this.appendDummyInput("")
// .appendField(new Blockly.FieldTextInput('"key"'), 'KEY')
.appendField(Blockly.Msg.DICTS_ADD_VALUE);
this.setOutput(true);
this.setTooltip(Blockly.Msg.DICTS_GET_TOOLTIP);
}
};
export const dicts_get_default = {
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict')
this.appendValueInput('KEY')
.appendField(Blockly.Msg.DICTS_GET_IN)
this.appendDummyInput("")
.appendField(Blockly.Msg.DICTS_ADD_VALUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.DICTS_DEFAULT_VALUE);
this.setOutput(true);
this.setTooltip(Blockly.Msg.DICTS_GET_DEFAULT_TOOLTIP);
}
};
export const dicts_add_or_change = {
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
this.appendValueInput('KEY')
.appendField(Blockly.Msg.DICTS_ADD)
// .appendField(new Blockly.FieldTextInput('"key"'), 'KEY')
this.appendDummyInput()
this.appendValueInput('VAR')
.appendField(Blockly.Msg.DICTS_ADD_VALUE);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.DICTS_ADD_OR_CHANGE_TOOLTIP);
}
};
export const dicts_delete = {
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
this.appendValueInput('KEY')
.appendField(Blockly.Msg.DICTS_DELETE_IN)
this.appendDummyInput("")
// .appendField(new Blockly.FieldTextInput('"key"'), 'KEY')
.appendField(Blockly.Msg.DICTS_DELETE_VALUE);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.DICTS_DELETE_TOOLTIP);
}
};
export const dicts_update = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT2')
.setCheck('Dict')
.appendField(Blockly.Msg.MAKE_DICT)
this.appendValueInput('DICT')
.setCheck('Dict')
.appendField(Blockly.Msg.DICT_UPDATE);
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_MID);
this.setTooltip(Blockly.Msg.DICTS_UPDATE_TOOLTIP);
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const dicts_clear = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict')
this.appendDummyInput("")
.appendField(Blockly.Msg.DICT_CLEAR);
this.setTooltip(Blockly.Msg.DICTS_CLEAR_TOOLTIP);
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const dicts_items = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict')
this.appendDummyInput("")
.appendField(Blockly.Msg.DICT_ITEMS);
this.setTooltip(Blockly.Msg.DICTS_ITEMS_TOOLTIP);
this.setOutput(true, 'List');
}
};
export const dicts_values = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict')
this.appendDummyInput("")
.appendField(Blockly.Msg.DICT_VALUES);
this.setTooltip(Blockly.Msg.DICTS_VALUES_TOOLTIP);
this.setOutput(true, 'List');
}
};
export const dicts_length = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict')
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_LENGTH)
this.setTooltip(Blockly.Msg.DICT_LENGTH_TOOLTIP);
this.setOutput(true, Number);
}
};
export const dicts_deldict = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict')
this.appendDummyInput("")
.appendField(Blockly.Msg.DICT_DELDICT);
this.setTooltip(Blockly.Msg.DICTS_DEL_TOOLTIP);
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const dicts_add_change_del = {
/**
* Block for getting sublist.
* @this Blockly.Block
*/
init: function () {
this['MODE'] = [
[Blockly.Msg.DICTS_ADD_OR_CHANGE, 'INSERT'],
[Blockly.Msg.MIXLY_MICROBIT_JS_DELETE_VAR, 'DELETE']
];
this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict')
this.appendDummyInput('AT2')
this.appendValueInput('KEY')
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_MICROPYTHON_SOCKET_MAKE)
// .appendField(new Blockly.FieldTextInput('"key"'), 'KEY')
.appendField(Blockly.Msg.DICTS_ADD_VALUE);
this.updateAt_(true);
this.setInputsInline(true);
this.setOutput(false);
this.setPreviousStatement(true);
this.setNextStatement(true);
var b = this;
this.setTooltip(function () {
var e = b.getFieldValue("WHERE"),
d = "";
switch (e) {
case "INSERT":
d = Blockly.Msg.DICTS_ADD_TOOLTIP;
break;
case "DELETE":
d = Blockly.Msg.DICTS_DELETE_TOOLTIP;
break;
}
//if ("FROM_START" == e || "FROM_END" == e) d += " " + Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP.replace("%1", ONE_BASED_INDEXING ? "#1": "#0");
return d
})
},
/**
* Create XML to represent whether there are 'AT' inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
var isAt = this.getInput('AT2').type == Blockly.INPUT_VALUE;
container.setAttribute('at2', isAt);
return container;
},
/**
* Parse XML to restore the 'AT' inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
var isAt = (xmlElement.getAttribute('at2') == 'true');
this.updateAt_(isAt);
},
/**
* Create or delete an input for a numeric index.
* This block has two such inputs, independant of each other.
* @param {number} n Specify first or second input (1 or 2).
* @param {boolean} isAt True if the input should exist.
* @private
* @this Blockly.Block
*/
updateAt_: function (isAt) {
// Create or delete an input for the numeric index.
// Destroy old 'AT' and 'ORDINAL' inputs.
this.removeInput('AT2');
this.removeInput('ORDINAL', true);
// Create either a value 'AT' input or a dummy input.
if (isAt) {
this.appendValueInput('AT2').setCheck(Number);
} else {
this.appendDummyInput('AT2');
}
var menu = new Blockly.FieldDropdown(this['MODE'],
function (value) {
var newAt = (value == 'INSERT');
// The 'isAt' variable is available due to this function being a
// closure.
if (newAt != isAt) {
var block = this.sourceBlock_;
block.updateAt_(newAt);
// This menu has been destroyed and replaced.
// Update the replacement.
block.setFieldValue(value, 'WHERE');
return null;
}
return undefined;
});
this.getInput('AT2')
.appendField(menu, 'WHERE');
// this.moveInputBefore('AT2','LIST');
}
};
export const dicts_pop = {
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict')
this.appendDummyInput("")
.appendField(Blockly.Msg.blockpy_DICT_POP)
this.appendValueInput('KEY')
this.appendDummyInput("")
// .appendField(new Blockly.FieldTextInput('"key"'), 'KEY')
.appendField(Blockly.Msg.DICTS_ADD_VALUE);
this.setTooltip(Blockly.Msg.DICT_POP_TOOLTIP);
this.setInputsInline(true);
this.setOutput(true);
}
};
export const dicts_setdefault = {
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict');
this.appendValueInput('KEY')
.appendField(Blockly.Msg.DICTS_SET_DEFAULT)
this.appendDummyInput("")
// .appendField(new Blockly.FieldTextInput('"key"'), 'KEY')
.appendField(Blockly.Msg.DICTS_DEFAULT_VALUE);
this.appendValueInput('VAR')
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.DICTS_SETDEFAULT_TOOLTIP);
}
};
export const dicts_create_with_noreturn = {
/**
* Block for creating a list with any number of elements of any type.
* @this Blockly.Block
*/
init: function () {
this.setColour(DICTS_HUE);
this.appendDummyInput("")
// .appendField(new Blockly.FieldTextInput('mydict'), 'VAR')
.appendField(new Blockly.FieldLabel(Blockly.Msg.MIXLY_MICROBIT_TYPE_DICT), 'TIP')
.appendField(' ')
this.itemCount_ = 3;
this.updateShape_();
this.setOutput(true, "Dict")
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setMutator(new Blockly.icons.MutatorIcon(['dicts_create_with_item'], this));
this.setTooltip(Blockly.Msg.DICTS_CREATE_WITH_TOOLTIP);
},
/**
* Create XML to represent list inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('dicts_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('dicts_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ADD' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput('ADD' + i);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
}
var keyNames = [];
for (var i = 0; this.getInput('ADD' + i); i++) {
//this.getInput('VALUE' + i).removeField("KEY"+i);
keyNames.push(this.getFieldValue("KEY" + i))
this.removeInput('ADD' + i);
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.getField('TIP').setValue(Blockly.Msg.LOGIC_NULL + Blockly.Msg.MIXLY_MICROBIT_TYPE_DICT);
} else {
this.getField('TIP').setValue(Blockly.Msg.MIXLY_MICROBIT_TYPE_DICT);
for (var i = 0; i < this.itemCount_; i++) {
this.appendValueInput('ADD' + i)
.setCheck(null)
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField(
new Blockly.FieldTextInput(
keyNames.length > i
? keyNames[i]
: (i == 0 ? '"key"' : '"key' + (i + 1) + '"')),
'KEY' + i)
.appendField(":")
}
}
}, getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
};
export const dicts_todict = {
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_TODICT);
this.setOutput(true);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_TOOLTIP_TODICT);
}
};
export const dicts_to_json = {
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict');
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_TO_JSON);
this.setTooltip(Blockly.Msg.MIXLY_TO_JSON_TOOLTIP);
this.setOutput(true);
}
};
export const json_to_dicts = {
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('VAR');
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_CONVERT_TO_JSON);
this.setTooltip(Blockly.Msg.MIXLY_CONVERT_TO_JSON_TOOLTIP);
this.setOutput(true);
}
};
export const dicts_to_to ={
init:function(){
this.setColour(DICTS_HUE);
this.appendValueInput('DICT')
.setCheck('Dict');
this.appendValueInput('VAR1')
.appendField('key1');
this.appendValueInput('VAR2')
.appendField('index');
this.appendValueInput('VAR3')
.appendField('key2');
this.appendValueInput('VAR4')
.appendField('key3');
this.setInputsInline(true)
this.setTooltip(Blockly.Msg.MIXLY_CONVERT_TO_JSON_TOOLTIP);
this.setOutput(true);
}
}
export const dicts_to_json2 = {
init: function () {
this.setColour(DICTS_HUE);
this.appendValueInput('DICT');
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_TO_JSON);
this.setTooltip(Blockly.Msg.MIXLY_TO_JSON_TOOLTIP);
this.setOutput(true);
}
};

View File

@@ -0,0 +1,177 @@
import * as Blockly from 'blockly/core';
const HTML_HUE = '#1ec1e4';
export const html_document = {
init: function () {
this.setColour(HTML_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.HTML_DOCUMENT);
this.appendStatementInput('HEAD')
.appendField(Blockly.Msg.HTML_HEAD);
this.appendStatementInput('BODY')
.appendField(Blockly.Msg.HTML_BODY);
this.setOutput(true);
}
};
export const html_title = {
init: function () {
this.setColour(HTML_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.HTML_LEVEL)
.appendField(new Blockly.FieldDropdown([["1", "1"], ["2", "2"], ["3", "3"], ["4", "4"], ["5", "5"], ["6", "6"]]), 'LEVEL');
this.appendStatementInput('DO')
.appendField('');
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const html_head_body = {
init: function () {
this.setColour(HTML_HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.HTML_HEAD, "head"],
[Blockly.Msg.HTML_BODY, "body"]
]), 'LEVEL');
this.appendStatementInput('DO')
.appendField('');
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const html_content = {
init: function () {
this.setColour(HTML_HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.HTML_P, "p"],
[Blockly.Msg.HTML_SPAN, "span"],
[Blockly.Msg.HTML_FORM, "form"],
[Blockly.Msg.HTML_TABLE, "table"],
[Blockly.Msg.HTML_LINE, "tr"],
[Blockly.Msg.HTML_CELL, "td"],
[Blockly.Msg.HTML_OL, "ol"],
[Blockly.Msg.HTML_UL, "ul"],
[Blockly.Msg.HTML_LI, "li"]
]), 'LEVEL')
// this.appendValueInput('style')
// .appendField(Blockly.Msg.MIXLY_AIP_ATTR)
// .setAlign(Blockly.inputs.Align.RIGHT);
this.appendStatementInput('DO')
.appendField('');
this.setInputsInline(false);
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const html_content_more = {
init: function () {
this.setColour(HTML_HUE);
this.appendDummyInput()
.appendField('<')
.appendField(new Blockly.FieldTextInput('tag'), "LEVEL")
.appendField('>')
this.appendValueInput('style')
.appendField(Blockly.Msg.MIXLY_AIP_ATTR)
.setAlign(Blockly.inputs.Align.RIGHT);
this.appendStatementInput('DO')
.appendField('');
this.setInputsInline(false);
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const html_style = {
init: function () {
this.setColour(HTML_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.HTML_STYLE)
this.appendStatementInput('STYLE');
this.setOutput(true);
}
};
export const html_form = {
init: function () {
this.setColour(HTML_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.HTML_FORM_CONTENT)
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.HTML_TEXT, "text"],
[Blockly.Msg.HTML_EMAIL, "email"],
[Blockly.Msg.HTML_NUMBER, "number"],
[Blockly.Msg.HTML_PASSWORD, "password"],
[Blockly.Msg.HTML_CHECKBOX, "checkbox"],
[Blockly.Msg.HTML_RADIOBUTTON, "radiobutton"],
[Blockly.Msg.HTML_BUTTON, "button"],
[Blockly.Msg.HTML_COLOUR, "colour"],
[Blockly.Msg.HTML_DATE, "date"],
[Blockly.Msg.HTML_LOCALTIME, "local time"],
[Blockly.Msg.HTML_FILE, "file"],
[Blockly.Msg.HTML_HIDDEN, "hidden"],
[Blockly.Msg.HTML_IMAGE, "image"],
[Blockly.Msg.HTML_MONTH, "month"],
[Blockly.Msg.HTML_RANGE, "range"],
[Blockly.Msg.HTML_RESET, "reset"],
[Blockly.Msg.HTML_SEARCH, "search"],
[Blockly.Msg.HTML_SUBMIT, "submit"],
[Blockly.Msg.HTML_TELEPHONENUMBER, "telephone number"],
[Blockly.Msg.HTML_TIME, "time"],
[Blockly.Msg.HTML_URL, "url"],
[Blockly.Msg.HTML_WEEK, "week"]
]), 'LEVEL')
this.appendDummyInput()
.appendField(Blockly.Msg.HTML_NAME)
.appendField(new Blockly.FieldTextInput('car'), "NAME")
this.appendDummyInput()
.appendField(Blockly.Msg.HTML_VALUE)
.appendField(new Blockly.FieldTextInput('go'), "VALUE")
this.appendValueInput('style')
.appendField(Blockly.Msg.MIXLY_AIP_ATTR)
.setAlign(Blockly.inputs.Align.RIGHT);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const html_style_content = {
init: function () {
this.setColour(HTML_HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldTextInput('property'), "KEY")
.appendField(':')
.appendField(new Blockly.FieldTextInput('value'), "VALUE")
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const html_style_color = {
init: function () {
this.setColour(HTML_HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldTextInput('property'), "KEY")
.appendField(':')
.appendField(new Blockly.FieldColour("#ff0000"), "RGB_LED_COLOR");
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const html_text = {
init: function () {
this.setColour(HTML_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.HTML_TEXT)
.appendField(new Blockly.FieldTextInput('text'), "TEXT");
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};

View File

@@ -0,0 +1,840 @@
import * as Blockly from 'blockly/core';
const LISTS_HUE = 260; //'#70b234'//260;
export const lists_get_index = {
init: function () {
this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);
this.setColour(LISTS_HUE);
this.appendValueInput("LIST")
this.appendValueInput("AT")
.setCheck(Number)
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET + " " + Blockly.Msg.LISTS_GET_INDEX_FROM_START)
this.appendDummyInput()
.appendField(Blockly.Msg.TEXT_CHARAT_TAIL);
this.setInputsInline(true);
this.setOutput(true);
this.setTooltip(Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM);
}
}
export const lists_get_sublist = {
/**
* Block for getting sublist.
* @this Blockly.Block
*/
init: function () {
this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);
this.setColour(LISTS_HUE);
this.appendValueInput('LIST')
this.appendDummyInput('')
this.appendValueInput('AT1')
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET + " " + Blockly.Msg.LISTS_GET_INDEX_FROM_START);
this.appendValueInput('AT2')
.appendField(Blockly.Msg.TEXT_CHARAT_TAIL + " " + Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START);
this.appendDummyInput()
.appendField(Blockly.Msg.TEXT_CHARAT_TAIL);
this.setInputsInline(true);
this.setOutput(true, 'List');
this.setTooltip(Blockly.Msg.PYTHON_LISTS_GET_SUBLIST_TOOLTIP);
}
}
export const lists_2d_get_data_with_col_row = {
init: function () {
this.appendValueInput("LIST")
.setCheck(null);
this.appendValueInput("row")
.setCheck(null)
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET + " " + Blockly.Msg.DATAFRAME_RAW);
this.appendValueInput("col")
.setCheck(null)
.appendField(Blockly.Msg.DATAFRAME_COLUMN);
this.setInputsInline(true);
this.setOutput(true, null);
this.setColour(LISTS_HUE);
this.setTooltip("");
this.setHelpUrl("");
}
};
export const lists_2d_get_col_row_data = {
init: function () {
this.appendValueInput("LIST")
.setCheck(null);
this.appendValueInput("row_start")
.setCheck(null)
.appendField(Blockly.Msg.MIXLY_GET + " " + Blockly.Msg.DATAFRAME_RAW + " [");
this.appendValueInput("row_end")
.setCheck(null)
.appendField(",");
this.appendValueInput("col_start")
.setCheck(null)
.appendField(") " + Blockly.Msg.DATAFRAME_COLUMN + " [");
this.appendValueInput("col_end")
.setCheck(null)
.appendField(",");
this.appendDummyInput()
.appendField(") " + Blockly.Msg.DICTS_ADD_VALUE);
this.setInputsInline(true);
this.setOutput(true, 'List');
this.setColour(LISTS_HUE);
this.setTooltip("");
this.setHelpUrl("");
}
};
export const lists_create_with = {
/**
* Block for creating a list with any number of elements of any type.
* @this Blockly.Block
*/
init: function () {
this.setColour(LISTS_HUE);
this.appendDummyInput("")
//don't need to specify the data type in Python
// .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_NUMBER, 'Array<number>'], [Blockly.Msg.LANG_MATH_STRING, 'Array<string>'], [Blockly.Msg.LANG_MATH_BOOLEAN, 'Array<boolean>']]), 'TYPE')
// .appendField(' ')
.appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
.appendField('[')
//.appendField(new Blockly.FieldTextInput('3',Blockly.FieldTextInput.math_number_validator), 'SIZE')
.appendField(']');
this.itemCount_ = 3;
this.updateShape_();
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setMutator(new Blockly.icons.MutatorIcon(['lists_create_with_item'], this));
this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_PYTHON_TOOLTIP);
},
/**
* Create XML to represent list inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('lists_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('lists_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ADD' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput('ADD' + i);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
var i = 0;
while (this.getInput('ADD' + i)) {
this.removeInput('ADD' + i);
i++;
}
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.appendDummyInput('EMPTY')
.appendField(Blockly.Msg.LISTS_CREATE_PYTHON_EMPTY_TITLE);
} else {
for (var i = 0; i < this.itemCount_; i++) {
var input = this.appendValueInput('ADD' + i);
if (i == 0) {
input.appendField(Blockly.Msg.blockpy_LISTS_CREATE_WITH_INPUT_WITH);
}
}
}
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
};
export const lists_create_with_text = {
init: function () {
this.setColour(LISTS_HUE);
this.appendDummyInput("")
//don't need to specify the data type in Python
// .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_NUMBER, 'Array<number>']]), 'TYPE')
// .appendField(' ')
// .appendField(Blockly.Msg.blockpy_MIXLY_SPLITBYDOU)
.appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
//.appendField(new Blockly.FieldTextInput('3',Blockly.FieldTextInput.math_number_validator), 'SIZE')
// .appendField(Blockly.Msg.MIXLY_MAKELISTFROM)
// .appendField(this.newQuote_(true))
.appendField(' = [')
.appendField(new Blockly.FieldTextInput('0,0,0'), 'TEXT')
.appendField(']');
// .appendField(this.newQuote_(false))
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LISTS_CREATE_WITH_TEXT2);
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
}
export const lists_create_with_container = {
/**
* Mutator block for list container.
* @this Blockly.Block
*/
init: function () {
this.setColour(LISTS_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_TYPE_LIST);
this.appendStatementInput('STACK');
this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP);
this.contextMenu = false;
}
};
export const lists_create_with_item = {
/**
* Mutator bolck for adding items.
* @this Blockly.Block
*/
init: function () {
this.setColour(LISTS_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP);
this.contextMenu = false;
}
};
export const lists_set_index = {
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput('LIST');
this.appendValueInput('AT')
.setCheck(Number)
.appendField(Blockly.Msg.MIXLY_MICROBIT_LIST_ASSIGN_AT);
this.appendValueInput('TO')
.appendField(Blockly.Msg.MIXLY_MICROBIT_JS_LIST_VALUE);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.LANG_LISTS_SET_INDEX_TOOLTIP);
}
};
export const lists_append_extend = {
init: function () {
this.setColour(LISTS_HUE);
this['TYPE'] = [
[Blockly.Msg.MIXLY_blockpy_set_add, 'append'],
[Blockly.Msg.MIXLY_MICROBIT_LIST_EXTEND, 'extend']
];
this.appendValueInput('LIST')
.setCheck('List')
this.appendValueInput('DATA')
.appendField(new Blockly.FieldDropdown(this['TYPE']), 'OP')
.appendField(Blockly.Msg.MIXLY_MICROBIT_LIST_A_ITEM)
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_MICROBIT_JS_LIST_TO_END);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'append': Blockly.Msg.MIXLY_TOOLTIP_LIST_APPEND,
'extend': Blockly.Msg.LISTS_EXTEND_TOOLTIP
};
return TOOLTIPS[mode];
});
}
};
export const lists_get_random_item = {
/**
* Block for get a random item from list.
* @this Blockly.Block
*/
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput("LIST");
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET + " " + Blockly.Msg.LISTS_GET_INDEX_RANDOM)
this.setTooltip(Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM);
this.setOutput(true);
}
};
export const lists_get_random_sublist = {
/**
* Block for get a random item from list.
* @this Blockly.Block
*/
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput("LIST");
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET + Blockly.Msg.MIXLY_MICROBIT_RANDOM)
this.appendDummyInput()
.appendField(Blockly.Msg.LANG_LISTS_GET_INDEX2 + Blockly.Msg.LISTS_GET_RANDOM_SUBLIST)
this.setTooltip(Blockly.Msg.LISTS_GET_RANDOM_SUBLIST_TOOLTIP);
this.setOutput(true, 'List');
}
};
export const lists_insert_value = {
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput('LIST');
this.appendValueInput('AT')
.setCheck(Number)
.appendField(Blockly.Msg.MIXLY_MICROBIT_JS_LIST_INSERT_AT);
this.appendValueInput('VALUE')
.appendField(Blockly.Msg.MIXLY_MICROBIT_JS_LIST_VALUE);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.LANG_LISTS_SET_INDEX_TOOLTIP);
this.setTooltip(Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT);
}
};
export const lists_reverse = {
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput('VAR')
.setCheck('List') //this.appendDummyInput("")
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_JS_LIST_REVERSE)
//.appendField(new Blockly.FieldTextInput('mylist'), 'VAR');
this.setTooltip(Blockly.Msg.LANG_LISTS_CLEAR_TOOLTIP);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const lists_clear = {
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput('VAR')
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROPYTHON_CLEAR)
//.appendField(new Blockly.FieldTextInput('mylist'), 'VAR');
this.setTooltip(Blockly.Msg.LANG_LISTS_REVERSE_TOOLTIP);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const lists_remove_at = {
init: function () {
this.setColour(LISTS_HUE);
this['TYPE'] = [
[Blockly.Msg.SERIES_INDEX, 'del'],
[Blockly.Msg.MIXLY_MICROBIT_JS_I2C_VALUE, 'remove']
];
this.appendValueInput('LIST')
.setCheck('List')
this.appendValueInput('DATA')
.appendField(Blockly.Msg.MIXLY_MIXPY_LISTS_REMOVE)
.appendField(new Blockly.FieldDropdown(this['TYPE']), 'OP')
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'del': Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_DELETE,
'remove': Blockly.Msg.MIXLY_TOOLTIP_LIST_REMOVE
};
return TOOLTIPS[mode];
});
}
};
export const lists_pop = {
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput('LIST');
this.appendValueInput('VALUE')
.appendField(Blockly.Msg.MIXLY_MICROBIT_LIST_POP);
this.appendDummyInput()
.appendField(Blockly.Msg.TEXT_CHARAT_TAIL);
this.setInputsInline(true);
this.setOutput(true);
this.setTooltip(Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM);
}
};
export const lists_find = {
init: function () {
var OPERATORS = [
[Blockly.Msg.MIXLY_LIST_INDEX, 'INDEX'],
[Blockly.Msg.MIXLY_LIST_COUNT, 'COUNT']
];
this.setColour(LISTS_HUE);
this.appendValueInput('VAR')
.setCheck('List')
this.appendValueInput('data')
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET)
.appendField(Blockly.Msg.HTML_VALUE)
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_DE)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
//.appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
this.setInputsInline(true);
this.setOutput(true, Number);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'INDEX': Blockly.Msg.MIXLY_TOOLTIP_LIST_FIND_INDEX,
'COUNT': Blockly.Msg.MIXLY_TOOLTIP_LIST_FIND_COUNT
};
return TOOLTIPS[mode];
});
}
};
export const list_trig = {
init: function () {
var OPERATORS = [
[Blockly.Msg.MIXLY_LIST_LEN, 'LEN'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_SUM, 'SUM'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_MAX, 'MAX'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_MIN, 'MIN'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE, 'AVERAGE'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN, 'MEDIAN'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_MODE, 'MODE'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV, 'STD_DEV'],
];
//this.setHelpUrl(Blockly.Msg.MATH_TRIG_HELPURL);
this.setColour(LISTS_HUE);
this.setOutput(true, Number);
this.appendValueInput('data')
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.setInputsInline(true);
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'LEN': Blockly.Msg.LISTS_LENGTH_TOOLTIP,
'SUM': Blockly.Msg.MATH_ONLIST_TOOLTIP_SUM,
'MAX': Blockly.Msg.MATH_ONLIST_TOOLTIP_MAX,
'MIN': Blockly.Msg.MATH_ONLIST_TOOLTIP_MIN,
'AVERAGE': Blockly.Msg.MATH_ONLIST_TOOLTIP_AVERAGE,
'MEDIAN': Blockly.Msg.MATH_ONLIST_TOOLTIP_MEDIAN,
'MODE': Blockly.Msg.MATH_ONLIST_TOOLTIP_MODE,
'STD_DEV': Blockly.Msg.MATH_ONLIST_TOOLTIP_STD_DEV
};
return TOOLTIPS[mode];
});
}
};
export const lists_sort = {
/**
* Block for sorting a list.
* @this Blockly.Block
*/
init: function () {
this.jsonInit({
"args0": [
{
"type": "input_value",
"name": "LIST",
"check": "List"
},
{
"type": "field_dropdown",
"name": "TYPE",
"options": [
[Blockly.Msg.LISTS_SORT_TYPE_NUMERIC, "NUMERIC"],
[Blockly.Msg.LISTS_SORT_TYPE_TEXT, "TEXT"],
[Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE, "IGNORE_CASE"]
]
},
{
"type": "field_dropdown",
"name": "DIRECTION",
"options": [
[Blockly.Msg.LISTS_SORT_ORDER_ASCENDING, "1"],
[Blockly.Msg.LISTS_SORT_ORDER_DESCENDING, "-1"]
]
},
],
"message0": Blockly.Msg.LISTS_SORT_TITLE,
"inputsInline": true,
"output": "List",
"colour": LISTS_HUE,
"tooltip": Blockly.Msg.LISTS_SORT_TOOLTIP,
"helpUrl": Blockly.Msg.LISTS_SORT_HELPURL
});
}
};
export const lists_change_to = {
init: function () {
var OPERATORS = [
[Blockly.Msg.MIXLY_MICROBIT_TYPE_TUPLE, 'tuple'],
[Blockly.Msg.blockpy_SET_CREATE_WITH_CONTAINER_TITLE_ADD, 'set'],
[Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD, 'array']
];
this.setColour(LISTS_HUE);
this.appendValueInput('VAR')
.setCheck("List")
// .appendField(Blockly.Msg.blockpy_USE_LIST);
this.appendDummyInput("")
.appendField(Blockly.Msg.A_TO_B)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'tuple': Blockly.Msg.MIXLY_TOOLTIP_CONVERT_LIST_TO_TUPLE,
'set': Blockly.Msg.MIXLY_TOOLTIP_CONVERT_LIST_TO_SET,
'array': Blockly.Msg.MIXLY_TOOLTIP_CONVERT_LIST_TO_ARRAY
};
return TOOLTIPS[mode];
});
this.setInputsInline(true);
this.setOutput(true);
}
};
export const list_many_input = {
init: function () {
this.setColour(LISTS_HUE);
this.appendDummyInput("")
.appendField('[')
.appendField(new Blockly.FieldTextInput('0,0,0'), "CONTENT")
.appendField(']');
this.setInputsInline(true);
this.setOutput(true);
}
};
export const lists_create_with_noreturn = {
/**
* Block for creating a list with any number of elements of any type.
* @this Blockly.Block
*/
init: function () {
this.setColour(LISTS_HUE);
this.itemCount_ = 3;
this.updateShape_();
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, "List")
this.setMutator(new Blockly.icons.MutatorIcon(['lists_create_with_item'], this));
this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_PYTHON_TOOLTIP);
},
/**
* Create XML to represent list inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('lists_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('lists_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ADD' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput('ADD' + i);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
var i = 0;
while (this.getInput('ADD' + i)) {
this.removeInput('ADD' + i);
i++;
}
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.appendDummyInput('EMPTY')
.appendField(Blockly.Msg.LISTS_CREATE_PYTHON_EMPTY_TITLE);
} else {
for (var i = 0; i < this.itemCount_; i++) {
var input = this.appendValueInput('ADD' + i);
if (i == 0) {
input.appendField(Blockly.Msg.blockpy_LISTS_CREATE_WITH_INPUT_WITH);
}
}
}
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
}
export const lists_change_to_general = {
init: function () {
var OPERATORS =
[
[Blockly.Msg.MIXLY_MICROBIT_TYPE_LIST, 'list'],
[Blockly.Msg.MIXLY_MICROBIT_TYPE_TUPLE, 'tuple'],
[Blockly.Msg.blockpy_SET_CREATE_WITH_CONTAINER_TITLE_ADD, 'set']
];
this.setColour(LISTS_HUE);
this.appendValueInput('VAR');
this.appendDummyInput("")
.appendField(Blockly.Msg.A_TO_B)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.setInputsInline(true);
this.setOutput(true);
}
};
export const lists_del_general = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput('TUP')
this.appendDummyInput("")
.appendField(Blockly.Msg.OBJECT_DELETE);
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const list_tolist = {
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_TOLIST);
this.setOutput(true, 'List');
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_TOOLTIP_TOLIST);
}
};
export const lists_create_with2 = lists_create_with
export const lists_create_with_text2 = lists_create_with_text
export const lists_getIndex3 = lists_get_index
export const lists_getSublist3 = lists_get_sublist
export const lists_setIndex3 = lists_set_index
export const lists_insert_value2 = lists_insert_value
export const lists_remove_at2 = lists_remove_at
export const list_tolist2 = list_tolist;
export const ENUMERATE ={
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.blockpy_USE_LIST);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_TO_INDEX_SEQUENCE);
// this.appendValueInput('VAR_N')
// .appendField(Blockly.Msg.MIXLY_INDEX+Blockly.Msg.MIXLY_STARTSWITH);
this.setInputsInline(true);
this.setOutput(true, Number);
this.setTooltip(Blockly.Msg.MIXLY_TOTO_INDEX_SEQUENC_TOOLTIP);
}
};
export const enumerate = {
init: function () {
this.setColour(LISTS_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.blockpy_USE_LIST);
this.appendValueInput('LIST');
this.appendValueInput('VALUE')
.appendField(Blockly.Msg.MIXLY_TO_INDEX_SEQUENCE)
.appendField(Blockly.Msg.MIXLY_INDEX+Blockly.Msg.MIXLY_STARTSWITH);
this.setInputsInline(true);
this.setOutput(true);
this.setTooltip(Blockly.Msg.MIXLY_TOTO_INDEX_SEQUENC_TOOLTIP);
}
};
export const content_in_lists = {
init: function () {
this.setColour(LISTS_HUE);
this.appendValueInput("CON")
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_ESP32_MIXGO_MUSIC_SHOW_IN);
this.appendValueInput("LIST")
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MID);
this.setInputsInline(true);
this.setOutput(true);
}
}

View File

@@ -0,0 +1,264 @@
import * as Blockly from 'blockly/core';
const LOGIC_HUE = 210;
export const logic_compare = {
/**
* Block for comparison operator.
* @this Blockly.Block
*/
init: function () {
var OPERATORS = Blockly.RTL ? [
['=', 'EQ'],
['\u2260', 'NEQ'],
['>', 'LT'],
['\u2265', 'LTE'],
['<', 'GT'],
['\u2264', 'GTE']
] : [
['=', 'EQ'],
['\u2260', 'NEQ'],
['<', 'LT'],
['\u2264', 'LTE'],
['>', 'GT'],
['\u2265', 'GTE']
];
//this.setHelpUrl(Blockly.Msg.LOGIC_COMPARE_HELPURL);
this.setColour(LOGIC_HUE);
this.setOutput(true, Boolean);
this.appendValueInput('A');
this.appendValueInput('B')
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.setInputsInline(true);
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function () {
var op = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'EQ': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ,
'NEQ': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ,
'LT': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT,
'LTE': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE,
'GT': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT,
'GTE': Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE
};
return TOOLTIPS[op];
});
this.prevBlocks_ = [null, null];
},
/**
* Called whenever anything on the workspace changes.
* Prevent mismatched types from being compared.
* @this Blockly.Block
*/
/*onchange: function(e) {
var blockA = this.getInputTargetBlock('A');
var blockB = this.getInputTargetBlock('B');
// Disconnect blocks that existed prior to this change if they don't match.
if (blockA && blockB &&
!blockA.outputConnection.checkType_(blockB.outputConnection)) {
// Mismatch between two inputs. Disconnect previous and bump it away.
// Ensure that any disconnections are grouped with the causing event.
Blockly.Events.setGroup(e.group);
for (var i = 0; i < this.prevBlocks_.length; i++) {
var block = this.prevBlocks_[i];
if (block === blockA || block === blockB) {
block.unplug();
block.bumpNeighbours_();
}
}
Blockly.Events.setGroup(false);
}
this.prevBlocks_[0] = blockA;
this.prevBlocks_[1] = blockB;
}*/
};
export const logic_compare_continous = {
init: function () {
var OPERATORS1 = Blockly.RTL ? [
['>', 'LT'],
['\u2265', 'LTE'],
['<', 'GT'],
['\u2264', 'GTE']
] : [
['<', 'LT'],
['\u2264', 'LTE'],
['>', 'GT'],
['\u2265', 'GTE']
];
var OPERATORS2 = Blockly.RTL ? [
['>', 'LT'],
['\u2265', 'LTE'],
['<', 'GT'],
['\u2264', 'GTE']
] : [
['<', 'LT'],
['\u2264', 'LTE'],
['>', 'GT'],
['\u2265', 'GTE']
];
//this.setHelpUrl(Blockly.Msg.LOGIC_COMPARE_HELPURL);
this.setColour(LOGIC_HUE);
this.setOutput(true, Boolean);
this.appendValueInput('A');
this.appendValueInput('B')
.appendField(new Blockly.FieldDropdown(OPERATORS1), 'OP1');
this.appendValueInput('C')
.appendField(new Blockly.FieldDropdown(OPERATORS2), 'OP2');
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_LOGIC_COMPARE_CONTINOUS_TOOLTIP);
}
};
export const logic_operation = {
/**
* Block for logical operations: 'and', 'or'.
* @this Blockly.Block
*/
init: function () {
var OPERATORS = [
[Blockly.Msg.LOGIC_OPERATION_AND, 'AND'],
[Blockly.Msg.LOGIC_OPERATION_OR, 'OR'],
[Blockly.Msg.LOGIC_OPERATION_NOR, 'NOR'],
[Blockly.Msg.LOGIC_OPERATION_XOR, 'XOR']
];
//this.setHelpUrl(Blockly.Msg.LOGIC_OPERATION_HELPURL);
this.setColour(LOGIC_HUE);
this.setOutput(true, Boolean);
this.appendValueInput('A')
.setCheck([Boolean, Number]);
this.appendValueInput('B')
.setCheck([Boolean, Number])
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.setInputsInline(true);
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function () {
var op = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'AND': Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND,
'OR': Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR,
'NOR': Blockly.Msg.LOGIC_OPERATION_TOOLTIP_NOR,
'XOR': Blockly.Msg.LOGIC_OPERATION_TOOLTIP_XOR
};
return TOOLTIPS[op];
});
}
};
export const logic_negate = {
/**
* Block for negation.
* @this Blockly.Block
*/
init: function () {
//this.setHelpUrl(Blockly.Msg.LOGIC_NEGATE_HELPURL);
this.setColour(LOGIC_HUE);
this.setOutput(true, Boolean);
this.appendValueInput('BOOL')
.setCheck([Number, Boolean])
.appendField(Blockly.Msg.LOGIC_NEGATE_TITLE);
//this.interpolateMsg(Blockly.Msg.LOGIC_NEGATE_TITLE,
// ['BOOL', Boolean, Blockly.inputs.Align.RIGHT],
// Blockly.inputs.Align.RIGHT);
this.setTooltip(Blockly.Msg.LOGIC_NEGATE_TOOLTIP);
}
};
export const logic_boolean = {
/**
* Block for boolean data type: true and false.
* @this Blockly.Block
*/
init: function () {
var BOOLEANS = [
[Blockly.Msg.LOGIC_BOOLEAN_TRUE, 'TRUE'],
[Blockly.Msg.LOGIC_BOOLEAN_FALSE, 'FALSE']
];
//this.setHelpUrl(Blockly.Msg.LOGIC_BOOLEAN_HELPURL);
this.setColour(LOGIC_HUE);
this.setOutput(true, Boolean);
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown(BOOLEANS), 'BOOL');
this.setTooltip(Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP);
}
};
export const logic_null = {
/**
* Block for null data type.
* @this Blockly.Block
*/
init: function () {
//this.setHelpUrl(Blockly.Msg.LOGIC_NULL_HELPURL);
this.setColour(LOGIC_HUE);
this.setOutput(true);
this.appendDummyInput()
.appendField(Blockly.Msg.LOGIC_NULL);
this.setTooltip(Blockly.Msg.LOGIC_NULL_TOOLTIP);
}
};
export const logic_true_or_false = {
init: function () {
this.setColour(LOGIC_HUE);
this.appendValueInput('A');
this.appendValueInput('B')
.appendField(Blockly.Msg.LOGIC_TERNARY_IF_TRUE);
this.appendValueInput('C')
.appendField(Blockly.Msg.LOGIC_TERNARY_IF_FALSE);
this.setOutput(true);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_LOGIT_TRUEORFALSE);
}
};
export const logic_is_in = {
init: function () {
var BOOLEANS = [
[Blockly.Msg.TEXT_APPEND_TO, 'in'],
[Blockly.Msg.MIXLY_PYTHON_LOGIC_IS_NOT_IN, 'not in']
];
this.setColour(LOGIC_HUE);
this.appendValueInput('A');
this.appendValueInput('B')
.setCheck([String, 'List'])
//.appendField(Blockly.Msg.TEXT_APPEND_TO)
.appendField(new Blockly.FieldDropdown(BOOLEANS), 'BOOL');
this.appendDummyInput("")
.appendField(Blockly.Msg.MICROBIT_LOGIC_IS_IN);
this.setOutput(true, Boolean);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.IN);
}
};
export const logic_is = {
init: function () {
var BOOLEANS = [
[Blockly.Msg.MIXLY_PYTHON_LOGIC_IS, 'is'],
[Blockly.Msg.MIXLY_PYTHON_LOGIC_IS_NOT, 'is not']
];
this.setColour(LOGIC_HUE);
this.appendValueInput('A');
this.appendValueInput('B')
.appendField(new Blockly.FieldDropdown(BOOLEANS), 'BOOL');
//.appendField(Blockly.Msg.MIXLY_PYTHON_LOGIC_IS);
this.setOutput(true, Boolean);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_LOGIC_IS_TOOLTIP);
}
};
export const logic_tobool = {
init: function () {
this.setColour(LOGIC_HUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_TOBOOL);
this.setOutput(true, Boolean);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_TOOLTIP_TOBOOL);
}
};

View File

@@ -0,0 +1,701 @@
import * as Blockly from 'blockly/core';
const MATH_HUE = 230; //'#e49f16';
Blockly.FieldTextInput.math_number_validator = function (text) {
//return window.isNaN(text) ? null : String(text);
// var pattern = /^-?(0X|0x|0O|0o|0B|0b)?[a-fA-F0-9]{1,}(\.[a-fA-F0-9]+)?$/;
// return pattern.test(text) ? String(text) : null;//校验,二 八 十 十六进制匹配
return String(text);//不再校验
};
Blockly.FieldTextInput.math_number_validator_include_blank = function (text) {
if (text === "") {
return "";
}
var pattern = /^-?(0X|0x|0O|0o|0B|0b)?[a-fA-F0-9]{1,}(\.[a-fA-F0-9]+)?$/;
return pattern.test(text) ? String(text) : null;//校验,二 八 十 十六进制匹配
};
export const math_number = {
/**
* Block for numeric value.
* @this Blockly.Block
*/
init: function () {
this.setColour(MATH_HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldTextInput('0',
Blockly.FieldTextInput.math_number_validator), 'NUM');
this.setOutput(true, Number);
this.setTooltip(Blockly.Msg.MATH_NUMBER_TOOLTIP);
}
};
export const math_constant = {
init: function () {
this.setColour(MATH_HUE);
var constant =
[['π', 'pi'], ['e', 'e']];
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_PYTHON_MATH_CONSTANT)
.appendField(new Blockly.FieldDropdown(constant), 'CONSTANT')
this.setOutput(true, Number);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('CONSTANT');
var TOOLTIPS = {
'pi': Blockly.Msg.MIXLY_PYTHON_MATH_CONSTANT_PI_TOOLTIP,
'e': Blockly.Msg.MIXLY_PYTHON_MATH_CONSTANT_E_TOOLTIP
};
return TOOLTIPS[mode];
});
}
};
export const math_constant_mp = {
init: function () {
this.setColour(MATH_HUE);
var constant =
[['π', 'pi'], ['e', 'e']];
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_PYTHON_MATH_CONSTANT)
.appendField(new Blockly.FieldDropdown(constant), 'CONSTANT')
this.setOutput(true, Number);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('CONSTANT');
var TOOLTIPS = {
'pi': Blockly.Msg.MIXLY_PYTHON_MATH_CONSTANT_PI_MP_TOOLTIP,
'e': Blockly.Msg.MIXLY_PYTHON_MATH_CONSTANT_E_MP_TOOLTIP
};
return TOOLTIPS[mode];
});
}
};
export const math_arithmetic = {
/**
* Block for basic arithmetic operator.
* @this Blockly.Block
*/
init: function () {
var OPERATORS = [
['+', 'ADD'],
['-', 'MINUS'],
['×', 'MULTIPLY'],
['÷', 'DIVIDE'],
['%', 'QUYU'],
['//', 'ZHENGCHU'],
['**', 'POWER']
];
//this.setHelpUrl(Blockly.Msg.MATH_ARITHMETIC_HELPURL);
this.setColour(MATH_HUE);
this.setOutput(true);
this.appendValueInput('A')
this.appendValueInput('B')
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.setInputsInline(true);
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
'QUYU': Blockly.Msg.MATH_MODULO_TOOLTIP,
'ZHENGCHU': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
};
return TOOLTIPS[mode];
});
}
};
export const math_selfcalcu = {
/**
* Block for basic arithmetic operator.
* @this Blockly.Block
*/
init: function () {
var OPERATORS = [
['+=', 'ADD'],
['-=', 'MINUS'],
['×=', 'MULTIPLY'],
['÷=', 'DIVIDE'],
['%=', 'QUYU'],
['//=', 'ZHENGCHU'],
['**=', 'POWER']
];
this.setColour(MATH_HUE);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendValueInput('A')
this.appendValueInput('B')
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.setInputsInline(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
'QUYU': Blockly.Msg.MATH_MODULO_TOOLTIP,
'ZHENGCHU': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
};
return TOOLTIPS[mode];
});
}
};
export const math_bit = {
init: function () {
var OPERATORS = [
['&', '&'],
['|', '|'],
['>>', '>>'],
['<<', '<<']
];
this.setColour(MATH_HUE);
this.setOutput(true, Number);
this.appendValueInput('A')
.setCheck(Number);
this.appendValueInput('B')
.setCheck(Number)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.setInputsInline(true);
this.setTooltip("位运算");
}
};
export const math_trig = {
/**
* Block for trigonometry operators.
* @this Blockly.Block
*/
init: function () {
var OPERATORS = [
['sin', 'SIN'],
['cos', 'COS'],
['tan', 'TAN'],
['asin', 'ASIN'],
['acos', 'ACOS'],
['atan', 'ATAN'],
['-', '-'],
['ln', 'LN'],
['log10', 'LOG10'],
['e^', 'EXP'],
['10^', 'POW10']
];
//this.setHelpUrl(Blockly.Msg.MATH_TRIG_HELPURL);
this.setColour(MATH_HUE);
this.setOutput(true, Number);
this.appendValueInput('NUM')
.setCheck(Number)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'SIN': Blockly.Msg.MATH_TRIG_TOOLTIP_SIN,
'COS': Blockly.Msg.MATH_TRIG_TOOLTIP_COS,
'TAN': Blockly.Msg.MATH_TRIG_TOOLTIP_TAN,
'ASIN': Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN,
'ACOS': Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS,
'ATAN': Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN,
'LN': Blockly.Msg.MATH_SINGLE_TOOLTIP_LN
};
return TOOLTIPS[mode];
});
}
};
export const math_dec = {
/**
* Block for trigonometry operators.
* @this Blockly.Block
*/
init: function () {
var OPERATORS = [
[Blockly.Msg.MATH_BIN, 'bin'],
[Blockly.Msg.MATH_OCT, 'oct'],
[Blockly.Msg.MATH_HEX, 'hex'],
];
//this.setHelpUrl(Blockly.Msg.MATH_TRIG_HELPURL);
this.setColour(MATH_HUE);
this.setOutput(true, String);
this.appendValueInput('NUM')
.setCheck(Number)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'bin': Blockly.Msg.MATH_DEC_TOOLTIP_BIN,
'oct': Blockly.Msg.MATH_DEC_TOOLTIP_OCT,
'hex': Blockly.Msg.MATH_DEC_TOOLTIP_HEX,
};
return TOOLTIPS[mode];
});
}
};
//取整等
export const math_to_int = {
init: function () {
var OPERATORS = [
[Blockly.Msg.LANG_MATH_TO_ROUND, 'round'],
[Blockly.Msg.LANG_MATH_TO_CEIL, 'ceil'],
[Blockly.Msg.LANG_MATH_TO_FLOOR, 'floor'],
[Blockly.Msg.MATH_ABS, 'fabs'],
// [Blockly.Msg.MATH_SQ, 'pow'],
[Blockly.Msg.MATH_SQRT, 'sqrt']
];
this.setColour(MATH_HUE);
this.appendValueInput('A')
.setCheck(Number)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.setOutput(true, Number);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'sqrt': Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT,
'fabs': Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS,
'sq': Blockly.Msg.MATH_SINGLE_TOOLTIP_SQ,
'round': Blockly.Msg.MATH_SINGLE_TOOLTIP_ROUND,
'ceil': Blockly.Msg.MATH_SINGLE_TOOLTIP_CEIL,
'floor': Blockly.Msg.MATH_SINGLE_TOOLTIP_FLOOR
};
return TOOLTIPS[mode];
});
}
};
//最大最小值
export const math_max_min = {
init: function () {
var OPERATORS = [
[Blockly.Msg.MIXLY_MAX, 'max'],
[Blockly.Msg.MIXLY_MIN, 'min'],
];
this.setColour(MATH_HUE);
this.appendValueInput('A')
.setCheck(Number)
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP')
.appendField('(');
this.appendValueInput('B')
.setCheck(Number)
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField(',');
this.appendDummyInput('')
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField(')');
this.setInputsInline(true);
this.setOutput(true, Number);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'max': Blockly.Msg.MIXLY_TOOLTIP_MATH_MAX,
'min': Blockly.Msg.MIXLY_TOOLTIP_MATH_MIN
};
return TOOLTIPS[mode];
});
}
};
export const math_number_base_conversion = {
init: function () {
var OPERATORS = [
[Blockly.Msg.MATH_TWO, 'two'],
[Blockly.Msg.MATH_EIGHT, 'eight'],
[Blockly.Msg.MATH_TEN, 'ten'],
[Blockly.Msg.MATH_SIXTEEN, 'sixteen']
];
this.setColour(MATH_HUE);
this.appendDummyInput('')
.appendField(Blockly.Msg.MATH_BA)
this.appendValueInput("NUM")
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP')
.appendField(Blockly.Msg.MATH_JinZhi)
.setCheck(Number);
this.appendDummyInput("")
.appendField(Blockly.Msg.MATH_ZHW)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP2')
.appendField(Blockly.Msg.MATH_JinZhi);
this.setFieldValue('ten', 'OP2')
// this.setPreviousStatement(true, null);
// this.setNextStatement(true, null);
this.setOutput(true)
this.setInputsInline(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'two': Blockly.Msg.MATH_Before_two,
'eight': Blockly.Msg.MATH_Before_eight,
'ten': Blockly.Msg.MATH_Before_ten,
'sixteen': Blockly.Msg.MATH_Before_sixteen,
};
var mode2 = thisBlock.getFieldValue('OP2');
var TOOLTIPS2 = {
'two': Blockly.Msg.MATH_Behind_two,
'eight': Blockly.Msg.MATH_Behind_eight,
'ten': Blockly.Msg.MATH_Behind_ten,
'sixteen': Blockly.Msg.MATH_Behind_sixteen,
};
return TOOLTIPS[mode] + TOOLTIPS2[mode2];
});
}
};
export const math_random = {
init: function () {
var INT_FLOAT = [[Blockly.Msg.LANG_MATH_INT, 'int'], [Blockly.Msg.LANG_MATH_FLOAT, 'float']];
this.setColour(MATH_HUE);
this.setOutput(true, Number);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_RANDOM)
.appendField(new Blockly.FieldDropdown(INT_FLOAT), 'TYPE');
this.appendValueInput('FROM')
.setCheck(Number)
.appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_FROM);
this.appendValueInput('TO')
.setCheck(Number)
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField(Blockly.Msg.LANG_MATH_RANDOM_INT_INPUT_TO);
this.setInputsInline(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('TYPE');
var TOOLTIPS = {
'int': Blockly.Msg.LANG_MATH_INT,
'float': Blockly.Msg.LANG_MATH_FLOAT_RANDOM
};
return Blockly.Msg.MATH_RANDOM_INT_TOOLTIP + TOOLTIPS[mode];
});
}
};
export const math_constrain = {
/**
* Block for constraining a number between two limits.
* @this Blockly.Block
*/
init: function () {
this.setColour(MATH_HUE);
this.setOutput(true, Number);
this.appendValueInput('VALUE')
.setCheck(Number)
.appendField(Blockly.Msg.LANG_MATH_CONSTRAIN_INPUT_CONSTRAIN);
this.appendValueInput('LOW')
.setCheck(Number)
.appendField(Blockly.Msg.LANG_MATH_CONSTRAIN_INPUT_LOW);
this.appendValueInput('HIGH')
.setCheck(Number)
.appendField(Blockly.Msg.LANG_MATH_CONSTRAIN_INPUT_HIGH);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MATH_CONSTRAIN_TOOLTIP);
}
};
export const math_map = {
init: function () {
this.setColour(MATH_HUE);
this.appendValueInput("NUM", Number)
.appendField(Blockly.Msg.MIXLY_MAP)
.setCheck(Number);
this.appendValueInput("fromLow", Number)
.appendField(Blockly.Msg.MIXLY_MAP_FROM)
.setCheck(Number);
this.appendValueInput("fromHigh", Number)
.appendField(",")
.setCheck(Number);
this.appendValueInput("toLow", Number)
.appendField(Blockly.Msg.MIXLY_MAP_TO)
.setCheck(Number);
this.appendValueInput("toHigh", Number)
.appendField(",")
.setCheck(Number);
this.appendDummyInput("")
.appendField("]");
this.setInputsInline(true);
this.setOutput(true);
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_MATH_MAP);
}
};
export const math_indexer_number = {
/**
* Block for numeric value.
* @this Blockly.Block
*/
init: function () {
this.setColour(MATH_HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldTextInput('0', Blockly.FieldTextInput.math_number_validator_include_blank), 'NUM');
this.setOutput(true);
this.setTooltip(Blockly.Msg.MATH_NUMBER_TOOLTIP);
}
};
export const math_random_seed = {
init: function () {
this.setColour(MATH_HUE);
this.appendValueInput('NUM')
.setCheck(Number)
.appendField(Blockly.Msg.LANG_MATH_RANDOM_SEED);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_MATH_RANDOM_SEED);
}
};
export const math_round = {
init: function () {
this.setColour(MATH_HUE);
this.setOutput(true, Number);
this.appendValueInput('VALUE')
.setCheck(Number)
this.appendValueInput('VAR')
.setCheck(Number)
.appendField(Blockly.Msg.MATH_ROUND)
.appendField(Blockly.Msg.TEXT_KEEP);
this.appendDummyInput()
.appendField(Blockly.Msg.TEXT_DECIMAL);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MATH_ROUND_NEW_TOOLTIP);
}
};
export const text_to_number = {
init: function () {
var TO_INT_FLOAT =
[[Blockly.Msg.MIXLY_TO_INT, 'int'], [Blockly.Msg.MIXLY_TO_FLOAT, 'float'], [Blockly.Msg.MIXLY_TO_BITES, 'b'], [Blockly.Msg.LANG_MATH_BYTE + Blockly.Msg.MIXLY_TO_INT, 'bti']];
this.setColour(MATH_HUE);
this.appendValueInput('VAR')
.appendField(new Blockly.FieldDropdown(TO_INT_FLOAT), 'TOWHAT');
this.setOutput(true, Number);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('TOWHAT');
var TOOLTIPS = {
'int': Blockly.Msg.MIXLY_PYTHON_TOOLTIP_TOINT,
'float': Blockly.Msg.MIXLY_PYTHON_TOOLTIP_TOFLOAT,
'b': Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOBYTE
};
return TOOLTIPS[mode];
});
}
};
export const text_to_number_skulpt = {
init: function () {
var TO_INT_FLOAT =
[[Blockly.Msg.MIXLY_TO_INT, 'int'], [Blockly.Msg.MIXLY_TO_FLOAT, 'float']];
this.setColour(MATH_HUE);
this.appendValueInput('VAR')
.appendField(new Blockly.FieldDropdown(TO_INT_FLOAT), 'TOWHAT');
this.setOutput(true, Number);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('TOWHAT');
var TOOLTIPS = {
'int': Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOINT,
'float': Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOFLOAT
};
return TOOLTIPS[mode];
});
}
};
export const base_map = math_map
export const turn_to_int = {
init: function () {
this.setColour(MATH_HUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.LANG_MATH_BYTE + Blockly.Msg.MIXLY_TO_HEX);
this.setOutput(true, Number);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_TOOLTIP_TOHEX)
}
};
export const generate_cartesian_product = {
/**
* Block for creating a list with any number of elements of any type.
* @this Blockly.Block
*/
init: function () {
this.setColour(MATH_HUE);
this.itemCount_ = 1;
this.setMutator(new Blockly.icons.MutatorIcon(['lists_create_with_item'], this));
this.appendDummyInput('DUMMY')
.appendField(Blockly.Msg.MIXLY_PRODUCT + Blockly.Msg.MIXLY_GENERATE_CARTESIAN_PRODUCT);
this.appendValueInput('REPEAT')
.appendField(Blockly.Msg.MIXLY_EVERY_PER_ELEPER_ELEMENT);
this.appendDummyInput()
.appendField(Blockly.Msg.CONTROLS_REPEAT_TITLE_TIMES);
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true);
this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_PYTHON_TOOLTIP);
this.updateShape_();
},
/**
* Create XML to represent list inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('lists_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('lists_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput(`ADD${i}`).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput(`ADD${i}`);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
let i = 0;
while (this.getInput(`ADD${i}`)) {
this.removeInput(`ADD${i}`);
i++;
}
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.appendDummyInput('EMPTY')
.appendField(Blockly.Msg.MIXLY_EMPTY_REMINDER);
} else {
for (let i = 0; i < this.itemCount_; i++) {
this.appendValueInput(`ADD${i}`);
this.moveInputBefore(`ADD${i}`, 'REPEAT');
}
}
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
}
export const math_radian_to_degree = {
init: function () {
this.setColour(MATH_HUE);
this.setOutput(true)
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_SET_RADIAN);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_TRANS_TO_ANGLE);
this.setInputsInline(true);
}
};
export const math_degree_to_radian = {
init: function () {
this.setColour(MATH_HUE);
this.setOutput(true)
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_SET_DEGREE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_TRANS_TO_RADIAN);
this.setInputsInline(true);
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,414 @@
import * as Blockly from 'blockly/core';
const SET_HUE = 100;
export const set_create_with = {
/**
* Block for creating a list with any number of elements of any type.
* @this Blockly.Block
*/
init: function () {
this.setColour(SET_HUE);
this.appendDummyInput("")
//don't need to specify the data type in Python
// .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_NUMBER, 'Array<number>'], [Blockly.Msg.LANG_MATH_STRING, 'Array<string>'], [Blockly.Msg.LANG_MATH_BOOLEAN, 'Array<boolean>']]), 'TYPE')
// .appendField(' ')
.appendField(new Blockly.FieldTextInput('s1'), 'VAR')
this.itemCount_ = 3;
this.updateShape_();
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setMutator(new Blockly.icons.MutatorIcon(['set_create_with_item'], this));
this.setTooltip(Blockly.Msg.blockpy_SET_CREATE_WITH_TOOLTIP);
},
/**
* Create XML to represent list inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('set_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('set_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ADD' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput('ADD' + i);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
var i = 0;
while (this.getInput('ADD' + i)) {
this.removeInput('ADD' + i);
i++;
}
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.appendDummyInput('EMPTY')
.appendField(Blockly.Msg.blockpy_SET_CREATE_EMPTY_TITLE);
} else {
for (var i = 0; i < this.itemCount_; i++) {
var input = this.appendValueInput('ADD' + i);
if (i == 0) {
input.appendField(Blockly.Msg.blockpy_SET_CREATE_WITH_INPUT_WITH);
}
}
}
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
};
export const set_create_with_container = {
/**
* Mutator block for list container.
* @this Blockly.Block
*/
init: function () {
this.setColour(SET_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.blockpy_SET_CREATE_WITH_CONTAINER_TITLE_ADD);
this.appendStatementInput('STACK');
this.setTooltip(Blockly.Msg.blockpy_SET_CREATE_WITH_CONTAINER_TOOLTIP);
this.contextMenu = false;
}
};
export const set_create_with_item = {
/**
* Mutator bolck for adding items.
* @this Blockly.Block
*/
init: function () {
this.setColour(SET_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.blockpy_SET_VARIABLES_NAME);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.blockpy_SET_CREATE_WITH_ITEM_TOOLTIP);
this.contextMenu = false;
}
};
export const set_length = {
init: function () {
this.setColour(SET_HUE);
this.appendValueInput('SET');
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_LENGTH);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.SET_LENGTH_TOOLTIP);
this.setOutput(true, Number);
}
};
export const set_pop = {
init: function () {
this.setColour(SET_HUE);
this.appendValueInput('SET')
.setCheck('Set')
this.appendDummyInput("")
.appendField(Blockly.Msg.blockpy_SET_GET_AND_REMOVE_LAST);
this.setTooltip(Blockly.Msg.SET_POP_TOOLTIP);
this.setInputsInline(true);
this.setOutput(true);
}
};
export const set_clear = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(SET_HUE);
this.appendValueInput('SET')
.setCheck('Set')
this.appendDummyInput("")
.appendField(Blockly.Msg.SET_CLEAR);
this.setPreviousStatement(true);
this.setNextStatement(true);
}
};
export const set_operate = {
init: function () {
this.appendValueInput('SET1')
.setCheck('Set')
var operate = [
[Blockly.Msg.blockpy_set_union, 'union'],
[Blockly.Msg.blockpy_set_intersection, 'intersection'],
[Blockly.Msg.blockpy_set_difference, 'difference']
];
this.setColour(SET_HUE);
this.appendDummyInput("")
.appendField(Blockly.Msg.blockpy_and_set)
this.appendValueInput('SET2')
.setCheck('Set')
this.appendDummyInput("")
.appendField(Blockly.Msg.blockpy_set_get_operate)
.appendField(new Blockly.FieldDropdown(operate), 'OPERATE')
this.setInputsInline(true);
this.setOutput(true, "set");
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OPERATE');
var TOOLTIPS = {
'union': Blockly.Msg.MIXLY_TOOLTIP_SET_UNION,
'intersection': Blockly.Msg.MIXLY_TOOLTIP_SET_INTERSECTION,
'difference': Blockly.Msg.MIXLY_TOOLTIP_SET_DIFFERENCE
};
return TOOLTIPS[mode];
});
}
};
export const set_operate_update = {
init: function () {
this.appendValueInput('SET1')
.setCheck('Set')
var operate_update = [
[Blockly.Msg.blockpy_set_union, 'update'],
[Blockly.Msg.blockpy_set_intersection, 'intersection_update'],
[Blockly.Msg.blockpy_set_difference, 'difference_update']
];
this.setColour(SET_HUE);
this.appendDummyInput("")
.appendField(Blockly.Msg.blockpy_and_set)
this.appendValueInput('SET2')
.setCheck('Set')
this.appendDummyInput("")
.appendField(Blockly.Msg.blockpy_set_get_operate)
.appendField(new Blockly.FieldDropdown(operate_update), 'OPERATE')
this.appendDummyInput("")
.appendField(Blockly.Msg.blockpy_set_update)
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OPERATE');
var TOOLTIPS = {
'update': Blockly.Msg.MIXLY_TOOLTIP_SET_UPDATE,
'intersection_update': Blockly.Msg.MIXLY_TOOLTIP_SET_INTERSECTION_UPDATE,
'difference_update': Blockly.Msg.MIXLY_TOOLTIP_SET_DIFFERENCE_UPDATE
};
return TOOLTIPS[mode];
});
}
};
export const set_add_discard = {
init: function () {
this.appendValueInput('SET')
.setCheck('Set')
var changenum =
[[Blockly.Msg.MIXLY_blockpy_set_add, 'add'], [Blockly.Msg.MIXLY_blockpy_set_discard, 'discard']];
this.setColour(SET_HUE);
this.appendDummyInput("")
.appendField(new Blockly.FieldDropdown(changenum), 'OPERATE')
this.appendValueInput('data')
.appendField(Blockly.Msg.blockpy_SET_VARIABLES_NAME)
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OPERATE');
var TOOLTIPS = {
'add': Blockly.Msg.SET_ADD_TOOLTIP,
'discard': Blockly.Msg.SET_DISCARD_TOOLTIP,
};
return TOOLTIPS[mode];
});
}
};
export const set_sub = {
init: function () {
this.appendValueInput('SET1')
.setCheck('Set')
var sub_super = [
[Blockly.Msg.blockpy_set_sub, 'issubset'],
[Blockly.Msg.blockpy_set_super, 'issuperset']
];
this.setColour(SET_HUE);
this.appendDummyInput("")
.appendField(Blockly.Msg.blockpy_is_set)
this.appendValueInput('SET2')
.setCheck('Set')
this.appendDummyInput("")
.appendField(Blockly.Msg.blockpy_set_of)
.appendField(new Blockly.FieldDropdown(sub_super), 'OPERATE')
this.setInputsInline(true);
this.setOutput(true, Boolean);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OPERATE');
var TOOLTIPS = {
'issubset': Blockly.Msg.MIXLY_TOOLTIP_SET_SUB,
'issuperset': Blockly.Msg.MIXLY_TOOLTIP_SET_SUPER
};
return TOOLTIPS[mode];
});
}
};
export const set_update = {
init: function () {
this.appendValueInput('SET')
.setCheck('Set')
this.setColour(SET_HUE);
this.appendValueInput('VAR')
.setCheck([String, 'List'])
.appendField(Blockly.Msg.blockpy_set_add_update);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.SET_UPDATE_TOOLTIP);
}
};
// export const set_change_to = {
// init: function() {
// var OPERATORS =
// [[Blockly.Msg.MIXLY_MICROBIT_TYPE_LIST, 'list'],
// [Blockly.Msg.MIXLY_MICROBIT_TYPE_TUPLE, 'tuple']
// ];
// this.setColour(SET_HUE);
// this.appendValueInput('VAR')
// .setCheck("Set")
// // .appendField(Blockly.Msg.blockpy_USE_LIST);
// this.appendDummyInput("")
// .appendField(Blockly.Msg.A_TO_B)
// .appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
// this.setInputsInline(true);
// this.setOutput(true);
// var thisBlock = this;
// this.setTooltip(function() {
// var mode = thisBlock.getFieldValue('OP');
// var TOOLTIPS = {
// 'list': Blockly.Msg.SET_TO_LISTS,
// 'tuple': Blockly.Msg.SET_TO_TUPLE,
// };
// return TOOLTIPS[mode];
// });
// }
// };
export const set_create_with_text_return = {
init: function () {
this.setColour(SET_HUE);
this.appendDummyInput("")
.appendField('{')
.appendField(new Blockly.FieldTextInput('0,0,0'), 'TEXT')
.appendField('}');
// .appendField(this.newQuote_(false))
this.setOutput(true);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MIXPY_TOOLTIP_SET_CREATE_WITH_TEXT);
}
}
export const set_toset = {
init: function () {
this.setColour(SET_HUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_TOSET);
this.setOutput(true);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_TOOLTIP_TOSET);
}
};

View File

@@ -0,0 +1,519 @@
import * as Blockly from 'blockly/core';
const STORAGE_HUE = 0; //'#5d69c5'//0;
export const storage_open_file_with_os = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput('fn')
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_PYTHON_STORAGE_OPEN_FILE_WITH_OS + "(For Windows)");
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setInputsInline(true);
}
}
export const storage_fileopen = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILENAME")
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_OPEN_FILE);
//.appendField(new Blockly.FieldTextInput('filename.txt'), 'FILENAME');
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MODE)
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_READ, 'r'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_WRITE, 'w'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_READ, 'rb'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_WRITE, 'wb'],
[Blockly.Msg.MIXLY_ADD, 'a'],
[Blockly.Msg.MATH_BIN + Blockly.Msg.MIXLY_ADD, 'ab'],
[Blockly.Msg.MIXLY_R_W ,'r+'],
[Blockly.Msg.MATH_BIN + Blockly.Msg.MIXLY_R_W ,'rb+'],
[Blockly.Msg.MIXLY_W_R ,'w+'],
[Blockly.Msg.MATH_BIN + Blockly.Msg.MIXLY_W_R ,'wb+'],
[Blockly.Msg.MIXLY_A_R ,'a+'],
[Blockly.Msg.MATH_BIN + Blockly.Msg.MIXLY_A_R ,'ab+']
]), 'MODE');
this.appendValueInput("FILE")
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_AS);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setInputsInline(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('MODE');
var mode0 = Blockly.Msg.MIXLY_USE;
var mode1 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MODE;
var mode2 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_OPEN_FILE;
var mode3 = Blockly.Msg.MIXLY_BELONG;
var TOOLTIPS = {
'r': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_READ,
'w': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_WRITE,
'rb': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_READ,
'wb': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_WRITE
};
return mode0 + TOOLTIPS[mode] + mode3 + mode1 + mode2;
});
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
};
export const storage_fileopen_new = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILENAME")
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_OPEN_FILE);
//.appendField(new Blockly.FieldTextInput('filename.txt'), 'FILENAME');
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MODE)
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_READ, 'r'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_WRITE, 'w'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_READ, 'rb'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_WRITE, 'wb']
]), 'MODE');
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setInputsInline(true);
this.setOutput(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('MODE');
var mode0 = Blockly.Msg.MIXLY_USE;
var mode1 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MODE;
var mode2 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_OPEN_FILE;
var mode3 = Blockly.Msg.MIXLY_BELONG;
var mode4 = Blockly.Msg.PY_STORAGE_FILE_OBJECT;
var TOOLTIPS = {
'r': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_READ,
'w': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_WRITE,
'rb': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_READ,
'wb': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_WRITE
};
return mode0 + TOOLTIPS[mode] + mode3 + mode1 + mode2 + mode4;
});
}
};
export const storage_fileopen_new_encoding = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILENAME")
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_OPEN_FILE);
//.appendField(new Blockly.FieldTextInput('filename.txt'), 'FILENAME');
var code =
[['ANSI', 'ANSI'], ['gbk', 'gbk'], ['utf-8', 'utf-8']];
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MODE)
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_READ, 'r'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_WRITE, 'w'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_READ, 'rb'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_WRITE, 'wb']
]), 'MODE');
this.appendDummyInput()
.appendField(Blockly.Msg.MIXPY_TEXT_ENCODE)
.appendField(new Blockly.FieldDropdown(code), 'CODE')
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setInputsInline(true);
this.setOutput(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('MODE');
var mode0 = Blockly.Msg.MIXLY_USE;
var mode1 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MODE;
var mode2 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_OPEN_FILE;
var mode3 = Blockly.Msg.MIXLY_BELONG;
var mode4 = Blockly.Msg.PY_STORAGE_FILE_OBJECT;
var TOOLTIPS = {
'r': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_READ,
'w': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_WRITE,
'rb': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_READ,
'wb': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_BIT_WRITE
};
return mode0 + TOOLTIPS[mode] + mode3 + mode1 + mode2 + mode4;
});
}
};
export const storage_file_write = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput('data')
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_MICROPYTHON_SOCKET_MAKE);
this.appendValueInput("FILE")
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_WRITE);
// .appendField(new Blockly.FieldTextInput('f'), 'FILE');
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MIXLY_MICROPYTHON_SOCKET_MAKE + Blockly.Msg.MIXLY_MICROBIT_TYPE_STRING + Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_WRITE);
}
}
export const storage_get_contents_without_para = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.setCheck('Variable')
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FROM_FILE);
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_ALL, 'read'], [Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_ONE_LINE, 'readline'], [Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_ALL_LINES, 'readlines']]), 'MODE');
this.setInputsInline(true);
this.setPreviousStatement(false); //in front of the block has something
this.setNextStatement(false); //beyond the ... has something
this.setOutput(true, String);
}
};
export const storage_get_contents = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.setCheck('Variable')
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FROM_FILE);
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_NO_MORE_THAN_SIZE, 'read'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_ONE_LINE_NO_MORE_THAN_SIZE, 'readline'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_ALL_LINES_NO_MORE_THAN_SIZE, 'readlines']
]), 'MODE');
this.appendValueInput("SIZE")
.setCheck(Number);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CHARACTER);
this.setInputsInline(true);
this.setPreviousStatement(false); //in front of the block has something
this.setNextStatement(false); //beyond the ... has something
this.setOutput(true, String);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('MODE');
var mode0 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FROM_FILE;
var mode2 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CHARACTER;
var TOOLTIPS = {
'read': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_NO_MORE_THAN_SIZE,
'readline': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_ONE_LINE_NO_MORE_THAN_SIZE,
'readlines': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_ALL_LINES_NO_MORE_THAN_SIZE
};
return mode0 + TOOLTIPS[mode] + 'x' + mode2;
});
}
};
export const storage_get_a_line = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FROM_FILE);
this.setNextStatement(true);
this.appendValueInput("SIZE")
.setCheck(Number)
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_ONE_LINE_NO_MORE_THAN_SIZE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CHARACTER);
this.setInputsInline(true);
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.MICROBIT_PYTHON_TYPE);
}
};
export const storage_can_write_ornot = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.appendField(Blockly.Msg.HTML_FILE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CAN_WRITE_ORNOT);
this.setInputsInline(true);
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, Boolean);
this.setTooltip(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CAN_WRITE_ORNOT1);
}
};
export const storage_get_filename = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILENAME);
this.setInputsInline(true);
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET_FILENAME);
}
};
export const storage_close_file = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CLOSE_FILE);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setOutput(false);
this.setTooltip(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CLOSE_FILE);
}
};
export const storage_list_all_files = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_LIST_ALL_FILES);
this.setInputsInline(true);
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, 'List');
this.setTooltip(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_LIST_ALL_FILES);
}
};
Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_DELETE_FILE
export const storage_delete_file = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_DELETE_FILE, 'remove'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_DELETE_DIRS, 'removedirs']
]), 'MODE');
this.appendValueInput("FILE")
.setCheck(String);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setOutput(false);
this.setTooltip(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_DELETE_FILE);
}
};
export const storage_get_file_size = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET_FILE_SIZE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_SIZE);
this.setInputsInline(true);
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, Number);
this.setTooltip(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET_FILE_SIZE + Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_SIZE);
}
};
export const storage_file_tell = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_RETURN_FILE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_PRESENT_LOCATION);
this.setInputsInline(true);
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, Number);
this.setTooltip(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_TELL);
}
};
export const storage_file_seek = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.setCheck('Variable')
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_SET_FILE_POSITION);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CURRENT_POSITION);
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_SEEK_START, 'start'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_SEEK_CURRENT, 'current'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_SEEK_END, 'end']
]), 'MODE');
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_SEEK_OFFSET);
this.appendValueInput("SIZE")
.setCheck(Number);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CHARACTER);
this.setInputsInline(true);
this.setPreviousStatement(true); //in front of the block has something
this.setNextStatement(true); //beyond the ... has something
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('MODE');
var mode0 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_SET_FILE_POSITION + Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CURRENT_POSITION;
var mode2 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CHARACTER;
var mode3 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_SEEK_OFFSET;
var TOOLTIPS = {
'start': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_SEEK_START,
'current': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_SEEK_CURRENT,
'end': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_FILE_SEEK_END
};
return mode0 + " " + TOOLTIPS[mode] + mode3 + 'x' + mode2;
});
}
};
export const storage_get_current_dir = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET_CURRENT_DIR);
this.setInputsInline(true);
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, 'List');
this.setTooltip(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET_CURRENT_DIR);
}
};
export const storage_make_dir = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("PATH")
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_PATH);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_ESP32_SET);
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MKDIR, 'mkdir'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MAKEDIRS, 'makedirs']
]), 'MODE');
this.setInputsInline(true);
this.setPreviousStatement(true); //in front of the block has something
this.setNextStatement(true); //beyond the ... has something
this.setOutput(false);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('MODE');
var mode0 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_PATH;
var mode2 = Blockly.Msg.MIXLY_ESP32_SET;
var TOOLTIPS = {
'mkdir': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MKDIR,
'makedirs': Blockly.Msg.MIXLY_MICROPYTHON_SOCKET_MAKEDIRS
};
return mode0 + 'x' + mode2 + TOOLTIPS[mode];
});
}
};
export const storage_rename = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_RENAME);
this.appendValueInput("NEWFILE")
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_AS);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setOutput(false);
this.setTooltip(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_RENAME);
}
};
export const storage_change_dir = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CHANGE_DIR);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setOutput(false);
this.setTooltip(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CHANGE_DIR);
}
};
export const storage_is_file = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput("FILE")
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_THE_PATH);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_IS_OR_NOT);
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.HTML_FILE, 'isfile'],
[Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_IS_DIR, 'isdir']
]), 'MODE');
this.setInputsInline(true);
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, Boolean);
let thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('MODE');
var mode0 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_THE_PATH;
var mode2 = Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_IS_OR_NOT;
var TOOLTIPS = {
'isfile': Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_MKDIR,
'isdir': Blockly.Msg.MIXLY_MICROPYTHON_SOCKET_MAKEDIRS
};
return mode0 + 'x' + mode2 + TOOLTIPS[mode];
});
}
};
export const sdcard_use_spi_init = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput('SPISUB')
.appendField(Blockly.Msg.CONTROLS_FOR_INPUT_WITH + "SPI")
.setCheck("var");
this.appendValueInput('PINSUB')
.appendField("CS")
this.appendValueInput('SUB')
.appendField(Blockly.Msg.MIXLY_MICROPYTHON_SOCKET_MAKE)
.setCheck("var");
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_SETUP + Blockly.Msg.LISTS_SET_INDEX_INPUT_TO)
.appendField(Blockly.Msg.MIXLY_SD_CARD);
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
}
};
export const sdcard_mount = {
init: function () {
this.setColour(STORAGE_HUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_SD_CARD);
this.appendValueInput("DIR")
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_SDCARD_MOUNT);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setInputsInline(true);
this.setTooltip();
}
}

View File

@@ -0,0 +1,999 @@
import * as Blockly from 'blockly/core';
const TEXTS_HUE = 160//'#9ec440'//160;
export const text = {
/**
* Block for text value.
* @this Blockly.Block
*/
init: function () {
//this.setHelpUrl(Blockly.Msg.TEXT_TEXT_HELPURL);
this.setColour(TEXTS_HUE);
this.appendDummyInput()
.appendField(this.newQuote_(true))
.appendField(new Blockly.FieldTextInput(''), 'TEXT')
.appendField(this.newQuote_(false));
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.TEXT_TEXT_TOOLTIP);
},
/**
* Create an image of an open or closed quote.
* @param {boolean} open True if open quote, false if closed.
* @return {!Blockly.FieldImage} The field image of the quote.
* @private
*/
newQuote_: function (open) {
if (open == this.RTL) {
var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
} else {
var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
}
return new Blockly.FieldImage(file, 12, 12, '"');
}
};
export const text_textarea = {
/**
* Block for text value.
* @this Blockly.Block
*/
init: function () {
//this.setHelpUrl(Blockly.Msg.TEXT_TEXT_HELPURL);
this.setColour(TEXTS_HUE);
this.appendDummyInput()
.appendField(this.newQuote_(true))
.appendField(new Blockly.FieldMultilineInput('Hello\nMixly'), 'VALUE')
// .appendField(new Blockly.FieldTextInput(''), 'TEXT')
.appendField(this.newQuote_(false));
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.TEXT_LINES_TOOLTIP);
},
/**
* Create an image of an open or closed quote.
* @param {boolean} open True if open quote, false if closed.
* @return {!Blockly.FieldImage} The field image of the quote.
* @private
*/
newQuote_: function (open) {
if (open == this.RTL) {
var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
} else {
var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
}
return new Blockly.FieldImage(file, 12, 12, '"');
}
};
export const text_bytes = {
/**
* Block for text value.
* @this Blockly.Block
*/
init: function () {
this.setColour(TEXTS_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_TEXT_BYTES)
.appendField(this.newQuote_(true))
.appendField(new Blockly.FieldTextInput(''), 'TEXT')
.appendField(this.newQuote_(false));
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.TEXT_TEXT_TOOLTIP);
},
/**
* Create an image of an open or closed quote.
* @param {boolean} open True if open quote, false if closed.
* @return {!Blockly.FieldImage} The field image of the quote.
* @private
*/
newQuote_: function (open) {
if (open == this.RTL) {
var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
} else {
var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
}
return new Blockly.FieldImage(file, 12, 12, '"');
}
};
Blockly.FieldTextInput.char_validator = function (text) {
if (text.length > 1) {
if (text.charAt(0) === "\\") {
var charAtOne = text.charAt(1);
if (charAtOne === "0" ||
charAtOne === "b" ||
charAtOne === "f" ||
charAtOne === "n" ||
charAtOne === "r" ||
charAtOne === "t" ||
charAtOne === "\\" ||
charAtOne === "'") {
return String(text).substring(0, 2);
} else if (charAtOne === "x" && text.charAt(2) === "0" && text.charAt(3) === "B") {
return String(text).substring(0, 4);
}
}
}
return String(text).substring(0, 1);
};
export const text_char = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendDummyInput()
.appendField(this.newQuote_(true))
.appendField(new Blockly.FieldTextInput('', Blockly.FieldTextInput.char_validator), 'TEXT')
.appendField(this.newQuote_(false));
this.setOutput(true, Number);
this.setTooltip(Blockly.Msg.TEXT_CHAR_TOOLTIP);
},
newQuote_: function (open) {
if (open == true) {
var file = '../../media/quote2.png';
} else {
var file = '../../media/quote3.png';
}
return new Blockly.FieldImage(file, 7, 12, '"');
}
};
export const text_join = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput('A')
.setCheck([String, Number]);
this.appendValueInput('B')
.setCheck([String, Number])
.appendField(Blockly.Msg.MIXLY_TEXT_JOIN);
this.setInputsInline(true);
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TEXT_JOIN);
}
};
export const ascii_to_char = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput('VAR')
.setCheck(Number)
.appendField(Blockly.Msg.MIXLY_TOCHAR);
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOCHAR);
}
};
export const char_to_ascii = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput('VAR')
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_TOASCII);
this.setOutput(true, Number);
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TEXT_TOASCII);
}
};
export const number_to_text = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_TOSTRING);
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_TOOLTIP_TOTEXT);
}
};
export const text_length = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.appendField(Blockly.Msg.MIXLY_LENGTH);
this.setOutput(true, Number);
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_TEXT_LENGTH);
}
}
export const text_char_at2 = {
init: function () {
this.WHERE_OPTIONS = [
[Blockly.Msg.LISTS_GET_INDEX_FROM_START, "FROM_START"],
[Blockly.Msg.LISTS_GET_INDEX_FROM_END, "FROM_END"],
[Blockly.Msg.TEXT_GET_INDEX_RANDOM + 1 + Blockly.Msg.TEXT_CHARAT2, "RANDOM"]
];
this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.setCheck(String)
// .appendField(Blockly.Msg.MIXLY_MICROBIT_TYPE_LIST)
this.appendValueInput("AT")
.setCheck(Number)
this.appendDummyInput()
//.appendField(Blockly.Msg.MIXLY_MID)
.appendField(Blockly.Msg.LISTS_GET_INDEX_GET, "MODE");
// .appendField("", "SPACE");
Blockly.Msg.LISTS_GET_INDEX_TAIL && this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_INDEX_TAIL);
// this.appendDummyInput().appendField(Blockly.Msg.MIXLY_DE);
this.setInputsInline(!0);
this.setOutput(!0);
this.updateAt_(!0);
var b = this;
this.setTooltip(function () {
var a = b.getFieldValue("MODE"),
e = b.getFieldValue("WHERE"),
d = "";
switch (a + " " + e) {
case "GET FROM_START":
case "GET FROM_END":
d = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM;
break;
case "GET RANDOM":
d = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM;
break;
case "GET_REMOVE FROM_START":
case "GET_REMOVE FROM_END":
d = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM;
break;
case "GET_REMOVE RANDOM":
d = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM;
break;
}
if ("FROM_START" == e || "FROM_END" == e) d += " " + Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP.replace("%1", Blockly.Msg.ONE_BASED_INDEXING ? "#1" : "#0");
return d
})
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('WHERE');
var TOOLTIPS = {
'FROM_START': Blockly.Msg.LISTS_GET_INDEX_FROM_START,
'FROM_END': Blockly.Msg.LISTS_GET_INDEX_FROM_END,
'RANDOM': Blockly.Msg.TEXT_GET_INDEX_RANDOM
};
return Blockly.Msg.PROCEDURES_DEFRETURN_RETURN + Blockly.Msg.MIXLY_MICROBIT_TYPE_STRING + TOOLTIPS[mode] + 'n' + Blockly.Msg.TEXT_CHARAT2;
});
},
mutationToDom: function () {
var a = document.createElement("mutation");
a.setAttribute("statement", !this.outputConnection);
var b = this.getInput("AT").type == Blockly.INPUT_VALUE;
a.setAttribute("at", b);
return a
},
domToMutation: function (a) {
var b = "true" == a.getAttribute("statement");
this.updateStatement_(b);
a = "false" != a.getAttribute("at");
this.updateAt_(a)
},
updateStatement_: function (a) {
a != !this.outputConnection && (this.unplug(!0, !0), a ? (this.setOutput(!1), this.setPreviousStatement(!0), this.setNextStatement(!0)) : (this.setPreviousStatement(!1), this.setNextStatement(!1), this.setOutput(!0)))
},
updateAt_: function (a) {
this.removeInput("AT");
this.removeInput("ORDINAL", !0);
a ? (this.appendValueInput("AT").setCheck(Number), Blockly.Msg.TEXT_CHARAT2 && this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.TEXT_CHARAT2)) : this.appendDummyInput("AT");
var b = new Blockly.FieldDropdown(this.WHERE_OPTIONS,
function (b) {
var e = "FROM_START" == b || "FROM_END" == b;
if (e != a) {
var d = this.sourceBlock_;
d.updateAt_(e);
d.setFieldValue(b, "WHERE");
return null
}
});
this.getInput("AT").appendField(b, "WHERE");
Blockly.Msg.LISTS_GET_INDEX_TAIL && this.moveInputBefore("TAIL", null)
}
};
export const text_char_at = {
init: function () {
this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.setCheck(String);
this.appendValueInput("AT")
.setCheck(Number)
.appendField(Blockly.Msg.LISTS_GET_INDEX_GET + " " + Blockly.Msg.LISTS_GET_INDEX_FROM_START);
this.appendDummyInput()
.appendField(Blockly.Msg.TEXT_CHARAT2);
this.setOutput(true);
this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN + Blockly.Msg.MIXLY_MICROBIT_TYPE_STRING + Blockly.Msg.LISTS_GET_INDEX_FROM_START + 'n' + Blockly.Msg.TEXT_CHARAT2);
}
}
export const text_random_char = {
init: function () {
this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.setCheck(String);
this.appendDummyInput()
.appendField(Blockly.Msg.TEXT_RANDOM_CHAR);
this.setOutput(true);
this.setTooltip(Blockly.Msg.TEXT_RANDOM_CHAR_TOOLTIP);
}
}
export const text_substring2 = {
/**
* Block for getting sublist.
* @this Blockly.Block
*/
init: function () {
this['WHERE_OPTIONS_1'] = [
[Blockly.Msg.LISTS_GET_INDEX_FROM_START, 'FROM_START'],
[Blockly.Msg.LISTS_GET_INDEX_FROM_END, 'FROM_END'],
[Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST, 'FIRST']
];
this['WHERE_OPTIONS_2'] = [
[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START, 'FROM_START'],
[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END, 'FROM_END'],
[Blockly.Msg.LISTS_GET_SUBLIST_END_LAST, 'LAST']
];
this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.setCheck(String)
//.appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL)
// if (Blockly.Msg.LISTS_GET_SUBLIST_TAIL) {
// this.appendDummyInput('TAIL')
// .appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL);
// }
this.appendDummyInput('')
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET);
this.appendDummyInput('AT1');
this.appendDummyInput('AT2');
this.setInputsInline(true);
this.setOutput(true, 'List');
this.updateAt_(1, true);
this.updateAt_(2, true);
this.setTooltip(Blockly.Msg._GET_TEXT_SUBLIST_TOOLTIP);
},
/**
* Create XML to represent whether there are 'AT' inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
var isAt1 = this.getInput('AT1').type == Blockly.INPUT_VALUE;
container.setAttribute('at1', isAt1);
var isAt2 = this.getInput('AT2').type == Blockly.INPUT_VALUE;
container.setAttribute('at2', isAt2);
return container;
},
/**
* Parse XML to restore the 'AT' inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
var isAt1 = (xmlElement.getAttribute('at1') == 'true');
var isAt2 = (xmlElement.getAttribute('at2') == 'true');
this.updateAt_(1, isAt1);
this.updateAt_(2, isAt2);
},
/**
* Create or delete an input for a numeric index.
* This block has two such inputs, independant of each other.
* @param {number} n Specify first or second input (1 or 2).
* @param {boolean} isAt True if the input should exist.
* @private
* @this Blockly.Block
*/
updateAt_: function (n, isAt) {
// Create or delete an input for the numeric index.
// Destroy old 'AT' and 'ORDINAL' inputs.
this.removeInput('AT' + n);
this.removeInput('ORDINAL' + n, true);
// Create either a value 'AT' input or a dummy input.
if (isAt) {
this.appendValueInput('AT' + n).setCheck(Number);
if (Blockly.Msg.TEXT_CHARAT2) {
this.appendDummyInput('ORDINAL' + n)
.appendField(Blockly.Msg.TEXT_CHARAT2);
}
} else {
this.appendDummyInput('AT' + n);
}
var menu = new Blockly.FieldDropdown(this['WHERE_OPTIONS_' + n],
function (value) {
var newAt = (value == 'FROM_START') || (value == 'FROM_END');
// The 'isAt' variable is available due to this function being a
// closure.
if (newAt != isAt) {
var block = this.sourceBlock_;
block.updateAt_(n, newAt);
// This menu has been destroyed and replaced.
// Update the replacement.
block.setFieldValue(value, 'WHERE' + n);
return null;
}
return undefined;
});
this.getInput('AT' + n)
.appendField(menu, 'WHERE' + n);
if (n == 1) {
this.moveInputBefore('AT1', 'AT2');
if (this.getInput('ORDINAL1')) {
this.moveInputBefore('ORDINAL1', 'AT2');
}
}
// if (Blockly.Msg.LISTS_GET_SUBLIST_TAIL) {
// this.moveInputBefore('TAIL', null);
// }
}
};
export const text_substring = {
/**
* Block for getting sublist.
* @this Blockly.Block
*/
init: function () {
this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.setCheck(String)
this.appendValueInput('AT1')
.appendField(Blockly.Msg.LISTS_GET_INDEX_GET + " " + Blockly.Msg.LISTS_GET_INDEX_FROM_START);
this.appendValueInput('AT2')
.appendField(Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START);
this.appendDummyInput()
.appendField(Blockly.Msg.TEXT_CHARAT2);
this.setInputsInline(true);
this.setOutput(true, ['List', String]);
this.setTooltip(Blockly.Msg._GET_TEXT_SUBLIST_TOOLTIP);
}
}
export const text_equals_starts_ends = {
init: function () {
var TEXT_DOWHAT = [
[Blockly.Msg.MIXLY_EQUALS, '==='],
[Blockly.Msg.MIXLY_STARTSWITH, 'startswith'],
[Blockly.Msg.MIXLY_ENDSWITH, 'endswith']
];
this.setColour(TEXTS_HUE);
this.appendValueInput("STR1")
.setCheck(String);
this.appendValueInput("STR2")
.appendField(new Blockly.FieldDropdown(TEXT_DOWHAT), 'DOWHAT')
.setCheck(String);
this.setOutput(true, [Boolean, Number]);
this.setInputsInline(true);
}
}
export const text_compare_to = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput("STR1")
.setCheck(String);
this.appendValueInput("STR2")
.appendField(Blockly.Msg.MIXLY_COMPARETO)
.setCheck(String);
this.setOutput(true, Number);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MIXLY_COMPARETO_HELP);
}
}
export const text_capital = {
init: function () {
var TEXT_CAPITAL = [
[Blockly.Msg.TEXT_UPPER, 'upper'],
[Blockly.Msg.TEXT_TITLE, 'title'],
[Blockly.Msg.TEXT_CAPITALIZE, 'capitalize'],
[Blockly.Msg.TEXT_SWAPCASE, 'swapcase'],
[Blockly.Msg.TEXT_LOWER, 'lower']
];
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET)
.appendField(new Blockly.FieldDropdown(TEXT_CAPITAL), 'CAPITAL')
.setCheck(String);
this.setOutput(true, String);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('CAPITAL');
var TOOLTIPS = {
'upper': Blockly.Msg.MIXLY_MIXPY_TEXT_UPPER_TOOLTIP,
'title': Blockly.Msg.MIXLY_MIXPY_TEXT_TITLE_TOOLTIP,
'swapcase': Blockly.Msg.MIXLY_MIXPY_TEXT_SWAPCASE_TOOLTIP,
'capitalize': Blockly.Msg.MIXLY_MIXPY_TEXT_CAPITALIZE_TOOLTIP,
'lower': Blockly.Msg.MIXLY_MIXPY_TEXT_LOWER_TOOLTIP
};
return TOOLTIPS[mode];
});
}
}
export const text_center = {
init: function () {
var TEXT_CENTER = [
[Blockly.Msg.TEXT_LJUST, 'ljust'],
[Blockly.Msg.TEXT_CENTER, 'center'],
[Blockly.Msg.TEXT_RJUST, 'rjust']
];
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.appendField(new Blockly.FieldDropdown(TEXT_CENTER), 'CENTER')
.setCheck(String);
this.appendValueInput("WID")
.appendField(Blockly.Msg.MIXLY_WIDTH)
.setCheck(Number);
this.appendValueInput("Symbol")
.appendField(Blockly.Msg.MIXLY_RECT_Fill)
.setCheck(String);
this.setInputsInline(true);
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_TEXT_CENTER_TOOLTIP);
}
}
export const text_find = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET)
.setCheck(String);
this.appendValueInput("STR")
.appendField(Blockly.Msg.MIXLY_MID + Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_CHARACTER)
.setCheck(String);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_LIST_INDEX);
this.setInputsInline(true);
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_TEXT_FIND_TOOLTIP);
}
}
export const text_join_seq = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.appendField(Blockly.Msg.MIXLY_PYTHON_TEXT_JOIN_SEQ_USE_STR)
.setCheck(String);
this.appendValueInput('LIST')
.appendField(Blockly.Msg.MIXLY_PYTHON_TEXT_JOIN_SEQ_SEQ)
.setCheck('List', 'Tuple', 'Set', 'Dict');
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_PYTHON_TEXT_JOIN_SEQ_GET_STR);
this.setInputsInline(true);
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_TEXT_JOIN_SEQ_TOOLTIP);
}
}
export const text_replace = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR")
.setCheck(String);
this.appendValueInput("STR1")
.appendField(Blockly.Msg.MIXLY_MIXPY_REPLACE)
.setCheck(String);
this.appendValueInput("STR2")
.appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_TO)
.setCheck(String);
this.setInputsInline(true);
this.setOutput(true, String);
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_TEXT_REPLACE_TOOLTIP);
}
}
export const text_split = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput("VAR");
this.appendValueInput("VAL")
.appendField(Blockly.Msg.LIST_SPLIT_AS);
this.appendDummyInput('')
.appendField(Blockly.Msg.LIST_SPLIT);
this.setOutput(true, "List");
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_TEXT_SPLIT_TOOLTIP);
this.setInputsInline(true);
}
}
export const text_strip = {
init: function () {
var STRIP =
[[Blockly.Msg.TEXT_TRIM_BOTH, 'strip'], [Blockly.Msg.TEXT_TRIM_LEFT, 'lstrip'], [Blockly.Msg.TEXT_TRIM_RIGHT, 'rstrip']];
this.setColour(TEXTS_HUE);
this.appendValueInput('VAR')
this.appendDummyInput('')
.appendField(Blockly.Msg.TEXT_STRIM);
this.appendDummyInput('')
.appendField(new Blockly.FieldDropdown(STRIP), 'TOWHAT');
this.appendDummyInput('')
.appendField(Blockly.Msg.TEXT_BLANK);
this.setOutput(true, String);
this.setInputsInline(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('TOWHAT');
var TOOLTIPS = {
'strip': Blockly.Msg.TEXT_TRIM_BOTH_TOOLTIP,
'lstrip': Blockly.Msg.TEXT_TRIM_LEFT_TOOLTIP,
'rstrip': Blockly.Msg.TEXT_TRIM_RIGHT_TOOLTIP
};
return TOOLTIPS[mode];
});
}
};
export const text_format = {
/**
* Block for creating a list with any number of elements of any type.
* @this Blockly.Block
*/
init: function () {
this.setColour(TEXTS_HUE);
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_MICROPYTHON_FORMAT)
//don't need to specify the data type in Python
// .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_NUMBER, 'Array<number>'], [Blockly.Msg.LANG_MATH_STRING, 'Array<string>'], [Blockly.Msg.LANG_MATH_BOOLEAN, 'Array<boolean>']]), 'TYPE')
// .appendField(' ')
this.appendDummyInput("")
.appendField(new Blockly.FieldTextInput('str'), 'VAR');
this.itemCount_ = 1;
this.updateShape_();
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setInputsInline(true);
this.setMutator(new Blockly.icons.MutatorIcon(['text_create_with_item'], this));
this.setOutput(true);
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_TEXT_FORMAT_TOOLTIP);
},
/**
* Create XML to represent list inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('text_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('text_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ADD' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput('ADD' + i);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
var i = 0;
while (this.getInput('ADD' + i)) {
this.removeInput('ADD' + i);
i++;
}
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.appendDummyInput('EMPTY')
.appendField();
} else {
for (var i = 0; i < this.itemCount_; i++) {
var input = this.appendValueInput('ADD' + i);
if (i == 0) {
input.appendField(Blockly.Msg.PROCEDURES_BEFORE_PARAMS);
}
}
}
},
getVars: function () {
if (this.getFieldValue('VAR') != null) {
if ((this.getFieldValue('VAR').indexOf("'") == -1) && (this.getFieldValue('VAR').indexOf('"') == -1)) {
return [this.getFieldValue('VAR')];
}
return [];
}
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
};
export const text_create_with_container = {
/**
* Mutator block for list container.
* @this Blockly.Block
*/
init: function () {
this.setColour(TEXTS_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE);
this.appendStatementInput('STACK');
this.setTooltip(Blockly.Msg.TUPLE_CREATE_WITH_CONTAINER_TOOLTIP);
this.contextMenu = false;
}
};
export const text_create_with_item = {
/**
* Mutator bolck for adding items.
* @this Blockly.Block
*/
init: function () {
this.setColour(TEXTS_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.blockpy_SET_VARIABLES_NAME);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.TUPLE_CREATE_WITH_ITEM_TOOLTIP);
this.contextMenu = false;
}
};
export const text_substring3 = text_substring
export const text_compareTo = text_compare_to
export const text_char_at3 = text_char_at
export const text_format_noreturn = {
/**
* Block for creating a list with any number of elements of any type.
* @this Blockly.Block
*/
init: function () {
this.setColour(TEXTS_HUE);
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_MICROPYTHON_FORMAT)
//don't need to specify the data type in Python
// .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_NUMBER, 'Array<number>'], [Blockly.Msg.LANG_MATH_STRING, 'Array<string>'], [Blockly.Msg.LANG_MATH_BOOLEAN, 'Array<boolean>']]), 'TYPE')
// .appendField(' ')
this.appendValueInput("VAR")
.setCheck(String);
this.itemCount_ = 1;
this.updateShape_();
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setInputsInline(true);
this.setMutator(new Blockly.icons.MutatorIcon(['text_create_with_item'], this));
this.setOutput(true);
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_TEXT_FORMAT_TOOLTIP);
},
/**
* Create XML to represent list inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('text_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('text_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ADD' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput('ADD' + i);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
var i = 0;
while (this.getInput('ADD' + i)) {
this.removeInput('ADD' + i);
i++;
}
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.appendDummyInput('EMPTY')
.appendField();
} else {
for (var i = 0; i < this.itemCount_; i++) {
var input = this.appendValueInput('ADD' + i);
if (i == 0) {
input.appendField(Blockly.Msg.PROCEDURES_BEFORE_PARAMS);
}
}
}
}
};
export const text_encode = {
init: function () {
this.setColour(TEXTS_HUE);
var encode_decode =
[[Blockly.Msg.MIXPY_TEXT_ENCODE, 'encode'], [Blockly.Msg.MIXPY_TEXT_DECODE, 'decode']];
var code =
[['ASCII', 'ASCII'], ['gb2312', 'gb2312'], ['gbk', 'gbk'], ['utf-8', 'utf-8'], ['utf-16', 'utf-16'], ['utf-32', 'utf-32']];
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown(code), 'CODE')
.appendField(' ')
this.appendValueInput("VAR")
.appendField(new Blockly.FieldDropdown(encode_decode), 'DIR')
.appendField(Blockly.Msg.LANG_MATH_STRING);
this.setOutput(true, String);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MIXPY_TEXT_ENCODE_DECODE_TOOLTIP);
}
};
export const text_eval = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput('VAR')
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_PYTHON_TEXT_EVAL);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_PYTHON_TEXT_EVAL_RESULT);
this.setInputsInline(true);
this.setOutput(true);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_TEXT_EVAL_TOOLTIP);
}
};
export const os_system = {
init: function () {
this.setColour(TEXTS_HUE);
this.appendValueInput('VAR')
.setCheck(String)
.appendField(Blockly.Msg.MIXLY_PYTHON_OS_SYSTEM);
this.setInputsInline(true);
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_OS_SYSTEM_TOOLTIP);
}
};

View File

@@ -0,0 +1,772 @@
import * as Blockly from 'blockly/core';
const TUPLE_HUE = 195; //'#5ec73d'//195;
export const tuple_create_with = {
/**
* Block for creating a list with any number of elements of any type.
* @this Blockly.Block
*/
init: function () {
this.setColour(TUPLE_HUE);
this.appendDummyInput("")
//don't need to specify the data type in Python
// .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_NUMBER, 'Array<number>'], [Blockly.Msg.LANG_MATH_STRING, 'Array<string>'], [Blockly.Msg.LANG_MATH_BOOLEAN, 'Array<boolean>']]), 'TYPE')
// .appendField(' ')
.appendField(new Blockly.FieldTextInput('mytup'), 'VAR');
this.itemCount_ = 3;
this.updateShape_();
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setMutator(new Blockly.icons.MutatorIcon(['tuple_create_with_item'], this));
this.setTooltip(Blockly.Msg.TUPLE_CREATE_WITH_TOOLTIP);
},
/**
* Create XML to represent list inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('tuple_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('tuple_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ADD' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput('ADD' + i);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
var i = 0;
while (this.getInput('ADD' + i)) {
this.removeInput('ADD' + i);
i++;
}
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.appendDummyInput('EMPTY')
.appendField(Blockly.Msg.TUPLE_CREATE_EMPTY_TITLE);
} else {
for (var i = 0; i < this.itemCount_; i++) {
var input = this.appendValueInput('ADD' + i);
if (i == 0) {
input.appendField(Blockly.Msg.TUPLE_CREATE_WITH_INPUT_WITH);
}
}
}
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
};
export const tuple_create_with_container = {
/**
* Mutator block for list container.
* @this Blockly.Block
*/
init: function () {
this.setColour(TUPLE_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.TUPLE_CREATE_WITH_CONTAINER_TITLE_ADD);
this.appendStatementInput('STACK');
this.setTooltip(Blockly.Msg.TUPLE_CREATE_WITH_CONTAINER_TOOLTIP);
this.contextMenu = false;
}
};
export const tuple_create_with_item = {
/**
* Mutator bolck for adding items.
* @this Blockly.Block
*/
init: function () {
this.setColour(TUPLE_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.blockpy_SET_VARIABLES_NAME);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.TUPLE_CREATE_WITH_ITEM_TOOLTIP);
this.contextMenu = false;
}
};
export const tuple_create_with_text2 = {
init: function () {
this.setColour(TUPLE_HUE);
this.appendDummyInput("")
//don't need to specify the data type in Python
// .appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_NUMBER, 'Array<number>']]), 'TYPE')
// .appendField(' ')
// .appendField(Blockly.Msg.blockpy_MIXLY_TUPLE_CREATE)
.appendField(new Blockly.FieldTextInput('mytup'), 'VAR')
//.appendField(new Blockly.FieldTextInput('3',Blockly.FieldTextInput.math_number_validator), 'SIZE')
// .appendField(Blockly.Msg.MIXLY_MAKELISTFROM)
// .appendField(this.newQuote_(true))
.appendField(' = (')
.appendField(new Blockly.FieldTextInput('0,0,0'), 'TEXT')
.appendField(')');
// .appendField(this.newQuote_(false))
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.MIXPY_TOOLTIP_TUPLE_CREATE_WITH_TEXT);
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
// newQuote_: function(open) {
// if (open == this.RTL) {
// var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
// } else {
// var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
// }
// return new Blockly.FieldImage(file, 12, 12, '"');
// }
}
export const tuple_create_with_text_return = {
init: function () {
this.setColour(TUPLE_HUE);
this.appendDummyInput("")
.appendField('(')
.appendField(new Blockly.FieldTextInput('0,0,0'), 'TEXT')
.appendField(')');
// .appendField(this.newQuote_(false))
this.setOutput(true);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MIXPY_TOOLTIP_TUPLE_CREATE_WITH_TEXT);
// },
// getVars: function() {
// return [this.getFieldValue('VAR')];
// },
// renameVar: function(oldName, newName) {
// if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
// this.setTitleValue(newName, 'VAR');
// }
}
// newQuote_: function(open) {
// if (open == this.RTL) {
// var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==';
// } else {
// var file = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC';
// }
// return new Blockly.FieldImage(file, 12, 12, '"');
// }
}
export const tuple_getIndex = {
init: function () {
this.setColour(TUPLE_HUE);
this.setOutput(true);
this.appendValueInput('TUP')
.setCheck('Tuple')
this.appendValueInput('AT')
.setCheck(Number)
.appendField(Blockly.Msg.LANG_LISTS_GET_INDEX1);
this.appendDummyInput("")
.appendField(Blockly.Msg.LANG_LISTS_GET_INDEX2);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.TUPLE_GET_INDEX_TOOLTIP);
}
};
export const tuple_length = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(TUPLE_HUE);
this.appendValueInput('TUP');
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_LENGTH);
this.setTooltip(Blockly.Msg.TUPLE_LENGTH_TOOLTIP);
this.setOutput(true, Number);
}
};
export const tuple_del = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(TUPLE_HUE);
this.appendValueInput('TUP')
.setCheck('Tuple')
this.appendDummyInput("")
.appendField(Blockly.Msg.TUPLE_DEL);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.TUPLE_DEL_TOOLTIP);
}
};
export const tuple_join = {
/**
* Block for list length.
* @this Blockly.Block
*/
init: function () {
this.setColour(TUPLE_HUE);
this.appendValueInput('TUP1')
.setCheck('Tuple')
this.appendDummyInput("")
.appendField(Blockly.Msg.TUPLE_JOIN)
this.appendValueInput('TUP2')
.setCheck('Tuple')
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.TUPLE_JOIN_TOOLTIP);
this.setOutput(true, "Tuple");
}
};
export const tuple_max = {
init: function () {
this.appendValueInput('TUP')
.setCheck('Tuple')
var max_min =
[[Blockly.Msg.blockpy_TUPLE_MAX, 'max'], [Blockly.Msg.blockpy_TUPLE_MIN, 'min'], [Blockly.Msg.MATH_ONLIST_OPERATOR_SUM, 'sum']];
this.setColour(TUPLE_HUE);
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_MICROBIT_JS_GET)
.appendField(new Blockly.FieldDropdown(max_min), 'DIR')
this.setInputsInline(true);
this.setOutput(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('DIR');
var TOOLTIPS = {
'max': Blockly.Msg.MIXLY_TOOLTIP_TUPLE_MAX,
'min': Blockly.Msg.MIXLY_TOOLTIP_TUPLE_MIN,
'sum': Blockly.Msg.MIXLY_TOOLTIP_TUPLE_SUM
};
return TOOLTIPS[mode];
});
}
};
export const tuple_change_to = {
init: function () {
var OPERATORS = [
[Blockly.Msg.MIXLY_MICROBIT_TYPE_LIST, 'list'],
[Blockly.Msg.blockpy_SET_CREATE_WITH_CONTAINER_TITLE_ADD, 'set']
];
this.setColour(TUPLE_HUE);
this.appendValueInput('VAR')
.setCheck("Tuple")
// .appendField(Blockly.Msg.blockpy_USE_LIST);
this.appendDummyInput("")
.appendField(Blockly.Msg.A_TO_B)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.setInputsInline(true);
this.setOutput(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'list': Blockly.Msg.TUPLE_TO_LISTS,
'set': Blockly.Msg.TUPLE_TO_SET,
};
return TOOLTIPS[mode];
});
}
};
export const tuple_find = {
init: function () {
var OPERATORS = [
[Blockly.Msg.MIXLY_LIST_INDEX, 'INDEX'],
[Blockly.Msg.MIXLY_LIST_COUNT, 'COUNT']
];
this.setColour(TUPLE_HUE);
this.appendValueInput('VAR')
.setCheck('List')
this.appendValueInput('data')
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET)
.appendField(Blockly.Msg.HTML_VALUE)
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_DE)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
//.appendField(new Blockly.FieldTextInput('mylist'), 'VAR')
this.setInputsInline(true);
this.setOutput(true, Number);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'INDEX': Blockly.Msg.MIXLY_TOOLTIP_TUPLE_FIND_INDEX,
'COUNT': Blockly.Msg.MIXLY_TOOLTIP_TUPLE_FIND_COUNT
};
return TOOLTIPS[mode];
});
}
};
export const tuple_trig = {
init: function () {
var OPERATORS = [
[Blockly.Msg.MIXLY_LIST_LEN, 'LEN'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_SUM, 'SUM'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_MAX, 'MAX'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_MIN, 'MIN'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE, 'AVERAGE'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN, 'MEDIAN'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_MODE, 'MODE'],
[Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV, 'STD_DEV'],
];
//this.setHelpUrl(Blockly.Msg.MATH_TRIG_HELPURL);
this.setColour(TUPLE_HUE);
this.setOutput(true, Number);
this.appendValueInput('data')
.setCheck('List')
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET)
.appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
this.setInputsInline(true);
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'LEN': Blockly.Msg.TUPLE_LENGTH_TOOLTIP,
'SUM': Blockly.Msg.MATH_ONLIST_TOOLTIP_TUPLE_SUM,
'MAX': Blockly.Msg.MATH_ONLIST_TOOLTIP_TUPLE_MAX,
'MIN': Blockly.Msg.MATH_ONLIST_TOOLTIP_TUPLE_MIN,
'AVERAGE': Blockly.Msg.MATH_ONLIST_TOOLTIP_TUPLE_AVERAGE,
'MEDIAN': Blockly.Msg.MATH_ONLIST_TOOLTIP_TUPLE_MEDIAN,
'MODE': Blockly.Msg.MATH_ONLIST_TOOLTIP_TUPLE_MODE,
'STD_DEV': Blockly.Msg.MATH_ONLIST_TOOLTIP_TUPLE_STD_DEV
};
return TOOLTIPS[mode];
});
}
};
export const tuple_getSublist = {
/**
* Block for getting sublist.
* @this Blockly.Block
*/
init: function () {
this['WHERE_OPTIONS_1'] = [
[Blockly.Msg.LISTS_GET_INDEX_FROM_START, 'FROM_START'],
[Blockly.Msg.LISTS_GET_INDEX_FROM_END, 'FROM_END'],
[Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST, 'FIRST']
];
this['WHERE_OPTIONS_2'] = [
[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START, 'FROM_START'],
[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END, 'FROM_END'],
[Blockly.Msg.LISTS_GET_SUBLIST_END_LAST, 'LAST']
];
this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);
this.setColour(TUPLE_HUE);
this.appendValueInput('LIST')
.setCheck('List')
//.appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL)
// if (Blockly.Msg.LISTS_GET_SUBLIST_TAIL) {
// this.appendDummyInput('TAIL')
// .appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL);
// }
this.appendDummyInput('')
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET);
this.appendDummyInput('AT1');
this.appendDummyInput('AT2');
this.setInputsInline(true);
this.setOutput(true, 'List');
this.updateAt_(1, true);
this.updateAt_(2, true);
this.setTooltip(Blockly.Msg.PYTHON_TUPLE_GET_SUBLIST_TOOLTIP);
},
/**
* Create XML to represent whether there are 'AT' inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
var isAt1 = this.getInput('AT1').type == Blockly.INPUT_VALUE;
container.setAttribute('at1', isAt1);
var isAt2 = this.getInput('AT2').type == Blockly.INPUT_VALUE;
container.setAttribute('at2', isAt2);
return container;
},
/**
* Parse XML to restore the 'AT' inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
var isAt1 = (xmlElement.getAttribute('at1') == 'true');
var isAt2 = (xmlElement.getAttribute('at2') == 'true');
this.updateAt_(1, isAt1);
this.updateAt_(2, isAt2);
},
/**
* Create or delete an input for a numeric index.
* This block has two such inputs, independant of each other.
* @param {number} n Specify first or second input (1 or 2).
* @param {boolean} isAt True if the input should exist.
* @private
* @this Blockly.Block
*/
updateAt_: function (n, isAt) {
// Create or delete an input for the numeric index.
// Destroy old 'AT' and 'ORDINAL' inputs.
this.removeInput('AT' + n);
this.removeInput('ORDINAL' + n, true);
// Create either a value 'AT' input or a dummy input.
if (isAt) {
this.appendValueInput('AT' + n).setCheck(Number);
if (Blockly.Msg.TEXT_CHARAT_TAIL) {
this.appendDummyInput('ORDINAL' + n)
.appendField(Blockly.Msg.TEXT_CHARAT_TAIL);
}
} else {
this.appendDummyInput('AT' + n);
}
var menu = new Blockly.FieldDropdown(this['WHERE_OPTIONS_' + n],
function (value) {
var newAt = (value == 'FROM_START') || (value == 'FROM_END');
// The 'isAt' variable is available due to this function being a
// closure.
if (newAt != isAt) {
var block = this.sourceBlock_;
block.updateAt_(n, newAt);
// This menu has been destroyed and replaced.
// Update the replacement.
block.setFieldValue(value, 'WHERE' + n);
return null;
}
return undefined;
});
this.getInput('AT' + n)
.appendField(menu, 'WHERE' + n);
if (n == 1) {
this.moveInputBefore('AT1', 'AT2');
if (this.getInput('ORDINAL1')) {
this.moveInputBefore('ORDINAL1', 'AT2');
}
}
// if (Blockly.Msg.LISTS_GET_SUBLIST_TAIL) {
// this.moveInputBefore('TAIL', null);
// }
}
};
export const tuple_create_with_noreturn = {
/**
* Block for creating a list with any number of elements of any type.
* @this Blockly.Block
*/
init: function () {
this.setColour(TUPLE_HUE);
this.itemCount_ = 3;
this.updateShape_();
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, "Tuple")
this.setMutator(new Blockly.icons.MutatorIcon(['tuple_create_with_item'], this));
this.setTooltip(Blockly.Msg.TUPLE_CREATE_WITH_TOOLTIP);
},
/**
* Create XML to represent list inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('tuple_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('tuple_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ADD' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput('ADD' + i);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
var i = 0;
while (this.getInput('ADD' + i)) {
this.removeInput('ADD' + i);
i++;
}
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.appendDummyInput('EMPTY')
.appendField(Blockly.Msg.TUPLE_CREATE_EMPTY_TITLE);
} else {
for (var i = 0; i < this.itemCount_; i++) {
var input = this.appendValueInput('ADD' + i);
if (i == 0) {
input.appendField(Blockly.Msg.TUPLE_CREATE_WITH_INPUT_WITH);
}
}
}
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setTitleValue(newName, 'VAR');
}
}
};
export const tuple_get_sublist = {
/**
* Block for getting sublist.
* @this Blockly.Block
*/
init: function () {
this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);
this.setColour(TUPLE_HUE);
this.appendValueInput('LIST')
this.appendDummyInput('')
this.appendValueInput('AT1')
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET + " " + Blockly.Msg.LISTS_GET_INDEX_FROM_START);
this.appendValueInput('AT2')
.appendField(Blockly.Msg.TEXT_CHARAT_TAIL + " " + Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START);
this.appendDummyInput()
.appendField(Blockly.Msg.TEXT_CHARAT_TAIL);
this.setInputsInline(true);
this.setOutput(true, 'Tuple');
this.setTooltip(Blockly.Msg.PYTHON_TUPLE_GET_SUBLIST_TOOLTIP);
}
}
export const tuple_get_random_item = {
init: function () {
this.setColour(TUPLE_HUE);
this.appendValueInput("TUP");
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_STORAGE_GET + " " + Blockly.Msg.LISTS_GET_INDEX_RANDOM)
this.setTooltip(Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM);
this.setOutput(true);
}
};
export const tuple_totuple = {
init: function () {
this.setColour(TUPLE_HUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_TOTUPLE);
this.setOutput(true);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_TOOLTIP_TOTUPLE);
}
};
function getCurrentTimeTuple() {
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth() + 1; // 月份从 0 开始,所以要加 1
var day = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
// 返回元组格式的时间字符串
return year + "," + month + "," + day + "," + hour + "," + minute + "," + second ;
}
export const tuple_input = {
init: function () {
this.setColour(TUPLE_HUE);
this.appendDummyInput("")
.appendField('(')
.appendField(new Blockly.FieldTextInput(getCurrentTimeTuple()),"CONTENT")
.appendField(')');
this.setOutput(true);
}
};
export const tuple_create_llm_params= {
init: function () {
this.setColour(TUPLE_HUE);
this.appendValueInput("params")
.appendField('(')
.appendField(Blockly.Msg.MIXLY_NAME_OF_PARAMS)
this.appendDummyInput()
.appendField(',')
.appendField(Blockly.Msg.MIXLY_TYPE)
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_TYPE_BOOLEAN,"boolean"],
[Blockly.Msg.MIXLY_TYPE_STRING,"string"],
[Blockly.Msg.MIXLY_TYPE_NUMBER,"number"],
[Blockly.Msg.MIXLY_TYPE_INTEGER,"integer"],
[Blockly.Msg.MIXLY_TYPE_NULL,"null"]
]),"type")
this.appendValueInput("des")
.appendField(',')
.appendField(Blockly.Msg.MIXLY_DESCRIPTION)
this.appendDummyInput()
.appendField(')');
this.setOutput(true);
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MIXPY_TOOLTIP_TUPLE_CREATE_WITH_TEXT);
}
};

View File

@@ -0,0 +1,445 @@
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Utility blocks for Blockly.
* @author acbart@vt.edu (Austin Cory Bart)
*/
import * as Blockly from 'blockly/core';
const UTILITY_HUE = 160;
export const raw_table = {
// Container.
init: function () {
this.setColour(UTILITY_HUE);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendDummyInput()
.appendField('Tabular Abstraction:');
this.appendDummyInput()
.appendField(new Blockly.FieldTable(''), 'TEXT');
}
};
export const raw_block = {
// Container.
init: function () {
this.setColour(UTILITY_HUE);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendDummyInput()
.appendField('Code Block:');
this.appendDummyInput()
.appendField(new Blockly.FieldMultilineInput(''), 'TEXT');
}
};
export const raw_expression = {
// Container.
init: function () {
this.setColour(UTILITY_HUE);
this.appendDummyInput()
.appendField('Code Expression:');
this.appendDummyInput()
.appendField(new Blockly.FieldMultilineInput(''), 'TEXT');
this.setOutput(true);
}
};
export const raw_empty = {
// Container.
init: function () {
this.setColour(UTILITY_HUE);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendValueInput('VALUE')
.appendField('');
this.setInputsInline(false);
}
};
export const text_comment = {
// Text value.
init: function () {
this.setColour(UTILITY_HUE);
this.appendDummyInput()
.appendTitle('Comment:')
.appendTitle(new Blockly.FieldTextInput(''), 'TEXT');
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip('This comment will be ignored by Python');
}
};
export const type_check = {
// Set element at index.
init: function () {
this.setColour(UTILITY_HUE);
this.appendValueInput('VALUE')
.appendField(Blockly.Msg.TYPE_CHECK);
this.setInputsInline(false);
this.setOutput(true, 'Type');
//this.setPreviousStatement(true);
//this.setNextStatement(true);
}
};
export const text_print_multiple = {
/**
* Block for printing multiple things (including nothing)
* @this Blockly.Block
*/
init: function () {
this.setColour(UTILITY_HUE);
this.itemCount_ = 1;
this.updateShape_();
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setMutator(new Blockly.icons.MutatorIcon(['text_print_multiple_item'], this));
this.setTooltip(Blockly.Msg.TEXT_PRINT_TOOLTIP);
},
/**
* Create XML to represent print inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock = Blockly.Block.obtain(workspace,
'text_print_multiple_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var x = 0; x < this.itemCount_; x++) {
var itemBlock = workspace.newBlock('text_print_multiple_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('PRINT' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
// Store a pointer to any connected child blocks.
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var x = 0;
while (itemBlock) {
var input = this.getInput('PRINT' + x);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
x++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
var i = 0;
while (this.getInput('PRINT' + i)) {
this.removeInput('PRINT' + i);
i++;
}
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.appendDummyInput('EMPTY')
.appendField("print");
} else {
for (var i = 0; i < this.itemCount_; i++) {
var input = this.appendValueInput('PRINT' + i);
if (i == 0) {
input.appendField("print");
}
}
}
}
};
export const text_print_multiple_container = {
// Container.
init: function () {
this.setColour(UTILITY_HUE);
this.appendDummyInput()
.appendField('print');
this.appendStatementInput('STACK');
this.setTooltip('');
this.contextMenu = false;
}
};
export const text_print_multiple_item = {
// Add items.
init: function () {
this.setColour(UTILITY_HUE);
this.appendDummyInput()
.appendField('item');
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip('');
this.contextMenu = false;
}
};
export const function_call = {
/**
* Block for printing multiple things (including nothing)
* @this Blockly.Block
*/
init: function () {
this.setColour(UTILITY_HUE);
this.itemCount_ = 1;
this.hasReturn_ = false;
this.appendDummyInput()
.appendField(new Blockly.FieldTextInput("str"), 'NAME');
this.updateShape_();
this.setMutator(new Blockly.icons.MutatorIcon(['function_call_item'], this));
this.setTooltip("Can be used to call any function");
},
/**
* Create XML to represent print inputs.
* @return {Element} XML storage element.
* @this Blockly.Block
*/
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
container.setAttribute('hasReturn', this.hasReturn_ ? "TRUE" : "FALSE");
return container;
},
/**
* Parse XML to restore the list inputs.
* @param {!Element} xmlElement XML storage element.
* @this Blockly.Block
*/
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.hasReturn_ = xmlElement.getAttribute('hasReturn') === "TRUE";
this.updateShape_();
},
/**
* Populate the mutator's dialog with this block's components.
* @param {!Blockly.Workspace} workspace Mutator's workspace.
* @return {!Blockly.Block} Root block in mutator.
* @this Blockly.Block
*/
decompose: function (workspace) {
var containerBlock = Blockly.Block.obtain(workspace,
'function_call_container');
containerBlock.initSvg();
containerBlock.setFieldValue(this.hasStatements_ ? 'TRUE' : 'FALSE',
'RETURN');
var connection = containerBlock.getInput('STACK').connection;
for (var x = 0; x < this.itemCount_; x++) {
var itemBlock = workspace.newBlock('function_call_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
/**
* Notification that the procedure's return state has changed.
* @param {boolean} returnState New return state
* @this Blockly.Block
*/
setReturn: function (returnState) {
this.unplug(true, true);
this.setOutput(returnState);
this.setPreviousStatement(!returnState);
this.setNextStatement(!returnState);
if (this.rendered) {
this.render();
}
},
/**
* Reconfigure this block based on the mutator dialog's components.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.hasReturn_ = containerBlock.getFieldValue("RETURN") === "TRUE";
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ARGUMENT' + i).connection.connect(connections[i]);
}
}
},
/**
* Store pointers to any connected child blocks.
* @param {!Blockly.Block} containerBlock Root block in mutator.
* @this Blockly.Block
*/
saveConnections: function (containerBlock) {
// Store a pointer to any connected child blocks.
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var x = 0;
while (itemBlock) {
var input = this.getInput('ARGUMENT' + x);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
x++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
/**
* Modify this block to have the correct number of inputs.
* @private
* @this Blockly.Block
*/
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
var i = 0;
while (this.getInput('ARGUMENT' + i)) {
this.removeInput('ARGUMENT' + i);
i++;
}
}
// Rebuild block.
for (var i = 0; i < this.itemCount_; i++) {
this.appendValueInput('ARGUMENT' + i);
}
// Set whether returns anything
this.setReturn(this.hasReturn_);
}
};
export const function_call_container = {
// Container.
init: function () {
this.setColour(UTILITY_HUE);
this.appendDummyInput()
.appendField('Arguments');
this.appendStatementInput('STACK');
this.appendDummyInput()
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField('has return')
.appendField(new Blockly.FieldCheckbox('TRUE'),
'RETURN');
this.setTooltip('');
this.contextMenu = false;
}
};
export const function_call_item = {
// Add items.
init: function () {
this.setColour(UTILITY_HUE);
this.appendDummyInput()
.appendField('argument');
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip('');
this.contextMenu = false;
}
};
export const attribute_access = {
init: function () {
this.appendValueInput("MODULE")
.setCheck(null);
this.appendValueInput("NAME")
.setCheck(null)
.appendField(".");
this.setInputsInline(true);
this.setOutput(true, null);
this.setColour(230);
this.setTooltip('');
this.setHelpUrl('');
}
};

View File

@@ -0,0 +1,331 @@
import * as Blockly from 'blockly/core';
import Names from '../others/names';
const VARIABLES_HUE = 330//'#af5180'//330;
// ************************************************************************
// THIS SECTION IS INSERTED INTO BLOCKLY BY BLOCKLYDUINO.
// export const variables_declare = {
// // Variable setter.
// init: function() {
// this.setColour(VARIABLES_HUE);
// this.appendValueInput('VALUE', null)
// .appendField(Blockly.Msg.MIXLY_DECLARE)
// .appendField(new Blockly.FieldTextInput(''), 'VAR')
// //.appendField(Blockly.Msg.MIXLY_AS)
// //.appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_NUMBER, 'number'], [Blockly.Msg.LANG_MATH_STRING, 'string'], [Blockly.Msg.LANG_MATH_BOOLEAN, 'boolean']]), 'TYPE')
// .appendField(Blockly.Msg.MIXLY_VALUE);
// this.setPreviousStatement(true);
// this.setNextStatement(true);
// this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_VARIABLES_DECLARE);
// },
// getVars: function() {
// return [this.getFieldValue('VAR')];
// },
// renameVar: function(oldName, newName) {
// if (Names.equals(oldName, this.getFieldValue('VAR'))) {
// this.setTitleValue(newName, 'VAR');
// }
// }
// };
// ************************************************************************
export const variables_get = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldTextInput(''), 'VAR')
this.setOutput(true);
this.setTooltip(Blockly.Msg.VARIABLES_GET_TOOLTIP);
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setFieldValue(newName, 'VAR');
}
}/*,
onchange: function() {
var varName = Blockly.Arduino.variableDB_.getName(this.getFieldValue('VAR'),Blockly.Variables.NAME_TYPE);
if(Blockly.Arduino.definitions_['var_declare'+varName]){
this.setWarningText(null);
}else{
this.setWarningText(Blockly.Msg.MIXLY_WARNING_NOT_DECLARE);
}
}*/
};
// export const variables_set = {
// init: function() {
// this.setColour(VARIABLES_HUE);
// this.appendValueInput('VALUE')
// .appendField(new Blockly.FieldTextInput(''), 'VAR')
// .appendField(Blockly.Msg.MIXLY_VALUE2);
// this.setPreviousStatement(true);
// this.setNextStatement(true);
// this.setTooltip(Blockly.Msg.VARIABLES_SET_TOOLTIP);
// },
// getVars: function() {
// return [this.getFieldValue('VAR')];
// },
// renameVar: function(oldName, newName) {
// if (Names.equals(oldName, this.getFieldValue('VAR'))) {
// this.setFieldValue(newName, 'VAR');
// }
// }/*,
// onchange: function() {
// var varName = Blockly.Arduino.variableDB_.getName(this.getFieldValue('VAR'),Blockly.Variables.NAME_TYPE);
// if(Blockly.Arduino.definitions_['var_declare'+varName]){
// this.setWarningText(null);
// }else{
// this.setWarningText(Blockly.Msg.MIXLY_WARNING_NOT_DECLARE);
// }
// }*/
// };
export const variables_set = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendValueInput('VALUE')
.appendField(new Blockly.FieldTextInput(''), 'VAR')
.appendField(Blockly.Msg.MIXLY_VALUE2);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.VARIABLES_SET_TOOLTIP);
},
getVars: function () {
var varValue = this.getFieldValue('VAR');
if (varValue == null) {
return [];
}
return varValue.split(",");
},
renameVar: function (oldName, newName) {
if (Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setFieldValue(newName, 'VAR');
}
}
};
/**
* Block for basic data type change.
* @this Blockly.Block
*/
export const variables_change = {
init: function () {
this.setColour(VARIABLES_HUE);
var DATATYPES =
[
[Blockly.Msg.LANG_MATH_INT, "int"],
[Blockly.Msg.LANG_MATH_FLOAT, "float"],
[Blockly.Msg.LANG_MATH_BOOLEAN, "bool"],
// [Blockly.Msg.MIXLY_MICROPYTHON_TYPE_COMPLEX, "complex"],
[Blockly.Msg.LANG_MATH_STRING, "str"],
[Blockly.Msg.MIXLY_MICROBIT_TYPE_LIST, "list"],
[Blockly.Msg.MIXLY_MICROBIT_TYPE_TUPLE, "tuple"],
[Blockly.Msg.MIXLY_MICROBIT_TYPE_DICT, "dict"],
[Blockly.Msg.blockpy_SET_CREATE_WITH_CONTAINER_TITLE_ADD, "set"],
[Blockly.Msg.LANG_MATH_BYTE, "bytes"]
];
this.appendValueInput('MYVALUE')
.appendField(new Blockly.FieldDropdown(DATATYPES), 'OP');
// Assign 'this' to a variable for use in the tooltip closure below.
this.setOutput(true);
// this.setInputsInline(true);
}
};
export const variables_global = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendValueInput("VAR")
.appendField(Blockly.Msg.MIXLY_PYTHON_GLOBAL)
.setCheck("var");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip(Blockly.Msg.TEXT_PRINT_TOOLTIP);
}
};
export const controls_type = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendValueInput("DATA")
.appendField(Blockly.Msg.MICROBIT_PYTHON_TYPE);
// this.setInputsInline(true);
this.setOutput(true);
this.setTooltip(Blockly.Msg.MICROBIT_PYTHON_TYPE);
}
};
export const controls_typeLists = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_MICROBIT_PY_CONTORL_GET_TYPE)
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.LANG_MATH_INT, "int"],
[Blockly.Msg.MIXLY_MICROBIT_TYPE_FLOAT, "float"],
[Blockly.Msg.MIXLY_MICROBIT_TYPE_STRING, "str"],
[Blockly.Msg.MIXLY_MICROBIT_TYPE_LIST, "list"],
[Blockly.Msg.MIXLY_MICROBIT_TYPE_TUPLE, "tuple"],
[Blockly.Msg.MIXLY_MICROBIT_TYPE_DICT, "dict"],
[Blockly.Msg.blockpy_SET_CREATE_WITH_CONTAINER_TITLE_ADD, "set"],
[Blockly.Msg.LANG_MATH_BYTE, "bytes"],
// [Blockly.Msg.MIXLY_MICROBIT_IMAGE,"image"],
[Blockly.Msg.LOGIC_NULL, "type(None)"]]), "type");
//整数、浮点数、字符串、列表、元组、字典、集合、图像不太对, unfinished
this.setInputsInline(true);
this.setOutput(true);
var thisBlock = this;
this.setTooltip(function () {
var mode = thisBlock.getFieldValue('type');
var mode0 = Blockly.Msg.MICROBIT_controls_TypeLists;
var TOOLTIPS = {
'int': Blockly.Msg.LANG_MATH_INT,
'float': Blockly.Msg.MIXLY_MICROBIT_TYPE_FLOAT,
'str': Blockly.Msg.MIXLY_MICROBIT_TYPE_STRING,
'list': Blockly.Msg.MIXLY_MICROBIT_TYPE_LIST,
'tuple': Blockly.Msg.MIXLY_MICROBIT_TYPE_TUPLE,
'dict': Blockly.Msg.MIXLY_MICROBIT_TYPE_DICT,
'set': Blockly.Msg.blockpy_SET_CREATE_WITH_CONTAINER_TITLE_ADD,
'image': Blockly.Msg.MIXLY_MICROBIT_IMAGE,
'bytes': Blockly.Msg.LANG_MATH_BYTE,
'NoneType': Blockly.Msg.LOGIC_NULL
};
return mode0 + TOOLTIPS[mode];
});
}
};
export const lists_zip = {
init: function () {
this.setColour(VARIABLES_HUE);
this.itemCount_ = 2;
this.updateShape_();
this.setInputsInline(true);
this.setPreviousStatement(false);
this.setNextStatement(false);
this.setOutput(true, "List")
this.setMutator(new Blockly.icons.MutatorIcon(['lists_zip_item'], this));
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_LISTS_ZIP_TOOLTIP);
},
mutationToDom: function () {
var container = document.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
domToMutation: function (xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
this.updateShape_();
},
decompose: function (workspace) {
var containerBlock =
workspace.newBlock('lists_zip_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('lists_zip_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
return containerBlock;
},
compose: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
var i = 0;
while (itemBlock) {
connections[i] = itemBlock.valueConnection_;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
i++;
}
this.itemCount_ = i;
this.updateShape_();
// Reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
if (connections[i]) {
this.getInput('ADD' + i).connection.connect(connections[i]);
}
}
},
saveConnections: function (containerBlock) {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
var i = 0;
while (itemBlock) {
var input = this.getInput('ADD' + i);
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
updateShape_: function () {
// Delete everything.
if (this.getInput('EMPTY')) {
this.removeInput('EMPTY');
} else {
var i = 0;
while (this.getInput('ADD' + i)) {
this.removeInput('ADD' + i);
i++;
}
}
// Rebuild block.
if (this.itemCount_ == 0) {
this.appendDummyInput('EMPTY')
.appendField(Blockly.Msg.MIXLY_PYTHON_LISTS_ZIP);
} else {
for (var i = 0; i < this.itemCount_; i++) {
var input = this.appendValueInput('ADD' + i);
if (i == 0) {
input.appendField(Blockly.Msg.MIXLY_PYTHON_LISTS_ZIP);
}
}
}
}
};
export const lists_zip_container = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_PYTHON_LISTS_ZIP);
this.appendStatementInput('STACK');
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_INOUT_PRINT_MANY_CONTAINER_TOOLTIP);
this.contextMenu = false;
}
};
export const lists_zip_item = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_PYTHON_LISTS_ZIP_ITEM);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_LISTS_ZIP_ITEM_TOOLTIP);
this.contextMenu = false;
}
};
export const unpack_iterable_object = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendValueInput('VAR')
.appendField(Blockly.Msg.MIXLY_VARIABLE_UNPACK)
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_PYTHON_LISTS_ZIP_ITEM, '*'],
[Blockly.Msg.MIXLY_MICROBIT_TYPE_DICT, '**']
]), 'TYPE');
this.setTooltip('');
this.setOutput(true);
}
};

View File

@@ -0,0 +1,98 @@
'use strict';
pbc.globalFunctionD['type'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
return block("controls_type", func.lineno, {}, {
'DATA': py2block.convert(args[0]),
}, {
"inline": "false"
});
}
function typeName() {
function converter(py2block, node, id, ctx, nodeName) {
return block("controls_typeLists", node.lineno, {'type': nodeName}, {}, {
"inline": "true"
});
}
return converter;
}
pbc.reservedNameD['int'] = typeName();
pbc.reservedNameD['float'] = typeName();
pbc.reservedNameD['str'] = typeName();
pbc.reservedNameD['list'] = typeName();
pbc.reservedNameD['tuple'] = typeName();
pbc.reservedNameD['dict'] = typeName();
pbc.reservedNameD['set'] = typeName();
pbc.reservedNameD['NoneType'] = typeName();
pbc.globalFunctionD['range'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
var args_len = args.length;
if (args_len > 3 || args_len < 1) {
throw new Error("Incorrect number of arguments");
}
var arg1block, arg2block, arg3block;
if (args_len == 1) {
arg2block = py2block.convert(args[0]);
var args0 = {
_astname: "Num",
n: {
'v': 0
}
};
arg1block = py2block.convert(args0);
var args2 = {
_astname: "Num",
n: {
'v': 1
}
};
arg3block = py2block.convert(args2);
}else if (args_len == 2) {
var args2 = {
_astname: "Num",
n: {
'v': 1
}
};
arg1block = py2block.convert(args[0]);
arg2block = py2block.convert(args[1]);
arg3block = py2block.convert(args2);
}else {
arg1block = py2block.convert(args[0]);
arg2block = py2block.convert(args[1]);
arg3block = py2block.convert(args[2]);
}
return block("controls_range", func.lineno, {
}, {
'FROM': arg1block,
'TO': arg2block,
'STEP': arg3block
}, {
"inline": "true"
});
};
pbc.moduleFunctionD.get('_thread')['start_new_thread'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
pbc.pinType = "pins_callback";
var callback = py2block.convert(args[0]);
pbc.pinType=null;
var tupblock = py2block.convert(args[1]);
return [block("controls_thread", func.lineno, {},{
"callback":callback,
"VAR":tupblock
},{
"inline": "true"
})];
};
//for i in ...在python_to_blockly.js中实现

View File

@@ -0,0 +1,153 @@
'use strict';
pbc.assignD.get('Dict')['check_assign'] = function (py2block, node, targets, value) {
if (value._astname === "Dict")
return true;
return false;
}
pbc.assignD.get('Dict')['create_block'] = function (py2block, node, targets, value) {
var keys = value.keys;
var values = value.values;
var keyList = [];
var valueList = [];
for (var i = 0; i < keys.length; i+= 1) {
var sourceCode = py2block.getSourceCode(node).split('\n')[keys[i].lineno - 1];
var s = keys[i].col_offset;
var e = sourceCode.indexOf(":", keys[i].col_offset);
keyList["KEY"+i] = sourceCode.substring(s, e).trim();
valueList["ADD"+i] = py2block.convert(values[i]);
}
keyList['VAR'] = py2block.Name_str(targets[0]);
return block("dicts_create_with", node.lineno, keyList, valueList, {
"inline": "false"
}, {
"@items": keys.length
});
}
pbc.objectFunctionD.get('keys')['Dict'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
return block("dicts_keys", func.lineno, {}, {
"DICT": objblock,
}, {
"inline": "true"
});
};
pbc.objectFunctionD.get('get')['Dict'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1 && args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
if (args.length == 2){
var args0 = py2block.convert(args[0]);
var args1 = py2block.convert(args[1]);
return block("dicts_get_default", func.lineno, {}, {
"DICT": objblock,
"KEY": args0,
"VAR": args1,
}, {
"inline": "true"
});
}
else{
var args1block = {
_astname: "Name",
id: {
'v': 'None'
}
};
var args0 = py2block.convert(args[0]);
var args1 = py2block.convert(args1block);
return block("dicts_get_default", func.lineno, {}, {
"DICT": objblock,
"KEY": args0,
"VAR": args1,
}, {
"inline": "true"
});
}
};
//d['key']在python_to_blockly.js中实现
//d['key'] = 11;在python_to_blockly.js中实现
//del d['key'];在python_to_blockly.js中实现
//d.clear()在lists.js中实现
//d.pop('key')在set.js中实现
pbc.objectFunctionD.get('setdefault')['Dict'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var args0 = py2block.convert(args[0]);
var args1 = py2block.convert(args[1]);
return [block("dicts_setdefault", func.lineno, {}, {
"DICT": objblock,
"KEY": args0,
"VAR": args1,
}, {
"inline": "true"
})];
};
pbc.objectFunctionD.get('items')['Dict'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
return block("dicts_items", func.lineno, {}, {
"DICT": objblock,
}, {
"inline": "true"
});
};
pbc.objectFunctionD.get('values')['Dict'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
return block("dicts_values", func.lineno, {}, {
"DICT": objblock,
}, {
"inline": "true"
});
};
pbc.globalFunctionD['dict'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length > 1) {
throw new Error("Incorrect number of arguments");
}
if (args.length ==0){
return block("dicts_create_with_noreturn", node.lineno, {},{}
, {
"inline": "true",
}, {
"@items": 0
});
}
if (args.length ==1){
var numblock = py2block.convert(args[0]);
return block("dicts_todict", func.lineno, {}, {
'VAR': numblock,
}, {
"inline": "false"
});
}
}

View File

@@ -0,0 +1,243 @@
'use strict';
pbc.assignD.get('List')['check_assign'] = function (py2block, node, targets, value) {
if (value._astname === "List")
return true;
return false;
}
pbc.assignD.get('List')['create_block'] = function (py2block, node, targets, value) {
return block("lists_create_with", node.lineno, {
'VAR': py2block.Name_str(targets[0])
},
py2block.convertElements("ADD", value.elts), {
"inline": elts.length < 4 ? "false" : "true",
}, {
"@items": value.elts.length
});
}
//mylist[0]在python_to_blockly.js中实现
//mylist[0:2]在python_to_blockly.js中实现
function listTrig(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
return block("list_trig", func.lineno, {
'OP':mode
}, {
"data": argblock,
}, {
"inline": "true"
});
};
return converter;
}
pbc.globalFunctionD['sum'] = listTrig('SUM');
pbc.globalFunctionD['math_mean'] = listTrig('AVERAGE');
pbc.globalFunctionD['math_median'] = listTrig('MEDIAN');
pbc.globalFunctionD['math_modes'] = listTrig('MODE');
pbc.globalFunctionD['math_standard_deviation'] = listTrig('STD_DEV');
//mylist[0] = 0在python_to_blockly.js中实现
pbc.objectFunctionD.get('insert')['List'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var atblock = py2block.convert(args[0]);
var valblock = py2block.convert(args[1]);
return [block("lists_insert_value", func.lineno, {}, {
"LIST": objblock,
"AT": atblock,
"VALUE": valblock,
}, {
"inline": "true"
})];
};
function listAppendExtend(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return [block("lists_append_extend", func.lineno, {
"OP":mode
}, {
"LIST": objblock,
"DATA": argblock
}, {
"inline": "true"
})];
};
return converter;
}
pbc.objectFunctionD.get('append')['List'] = listAppendExtend('append');
pbc.objectFunctionD.get('extend')['List'] = listAppendExtend('extend');
//del mylist[0]在python_to_blockly.js中实现
pbc.objectFunctionD.get('remove')['List'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return [block("lists_remove_at", func.lineno, {
"OP":"remove"
}, {
"LIST": objblock,
"DATA": argblock
}, {
"inline": "true"
})];
};
//mylist.pop(0)在set.js中实现
//random.choice(mylist)在text.js中实现
function listFindCount(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return block("lists_find", func.lineno, {
'OP':mode
}, {
"VAR": objblock,
"data": argblock
}, {
"inline": "true"
});
};
return converter;
}
pbc.objectFunctionD.get('index')['List'] = listFindCount('INDEX');
pbc.objectFunctionD.get('count')['List'] = listFindCount('COUNT');
pbc.globalFunctionD['lists_sort'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 3 && args[1]._astname === "Str"
&& args[2]._astname === "Name") {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
var type = py2block.Str_value(args[1]);
var reverse = py2block.Name_str(args[2]);
if(reverse == "True"){
reverse = '-1';
}else if(reverse == "False"){
reverse = '1';
}else{
throw new Error("not implement");
}
return block("lists_sort", func.lineno, {
'TYPE': type,
'DIRECTION':reverse
}, {
'LIST': argblock
}, {
"inline": "true"
});
}
pbc.objectFunctionD.get('reverse')['List'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
return [block("lists_reverse", func.lineno, {}, {
"VAR": objblock,
}, {
"inline": "true"
})];
};
pbc.objectFunctionD.get('clear')['List'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
return [block("lists_clear", func.lineno, {}, {
"VAR": objblock,
}, {
"inline": "true"
})];
};
pbc.globalFunctionD['list'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length > 1) {
throw new Error("Incorrect number of arguments");
}
if (args.length ==0){
return block("lists_create_with_noreturn", node.lineno, {},{}
, {
"inline": "true",
}, {
"@items": 0
});
}
if (args.length ==1){
var numblock = py2block.convert(args[0]);
return block("list_tolist", func.lineno, {}, {
'VAR': numblock,
}, {
"inline": "false"
})
}
}
pbc.globalFunctionD['zip'] = function(py2block, func, args, keywords, starargs, kwargs, node){
var d = py2block.convertElements("ADD", args);
return block("lists_zip", node.lineno, {
}, d, {
"inline": "true",
}, {
"@items":args.length
});
}
pbc.moduleFunctionD.get('random')['sample'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
var listname = py2block.convert(args[0]);
var varblock = py2block.convert(args[1]);
return block("lists_get_random_sublist", func.lineno, {}, {
'LIST':listname,
'VAR': varblock
}, {
"inline": "true"
});
}
pbc.objectFunctionD.get('tolist')['List'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
return block("list_tolist2", func.lineno, {}, {
"VAR": objblock
}, {
"inline": "true"
});
}

View File

@@ -0,0 +1,15 @@
'use strict';
//目前块都在python_to_blockly.js中实现
pbc.globalFunctionD['bool'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
var numblock = py2block.convert(args[0]);
return block("logic_tobool", func.lineno, {}, {
'VAR': numblock,
}, {
"inline": "false"
});
}

View File

@@ -0,0 +1,389 @@
'use strict';
//加减乘除 在python_to_blockly.js中实现
//位操作 在python_to_blockly.js中实现
function mathDecchange(mode) {
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
return block("math_dec", func.lineno, {
'OP': mode
}, {
'NUM': py2block.convert(args[0])
}, {
"inline": "true"
});
}
return converter;
}
pbc.globalFunctionD['bin'] = mathDecchange('bin');
pbc.globalFunctionD['oct'] = mathDecchange('oct');
pbc.globalFunctionD['hex'] = mathDecchange('hex');
function mathTrigonometric(mode) {
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
// if (args[0]._astname == "Call"
// && args[0].func._astname == "Attribute"
// && args[0].func.value._astname == "Name"
// && py2block.Name_str(args[0].func.value) == "math"
// && py2block.identifier(args[0].func.attr) == "radians"
// && args[0].args.length == 1) {
return block("math_trig", func.lineno, {
'OP': mode
}, {
'NUM': py2block.convert(args[0])
}, {
"inline": "true"
});
// } else {
// throw new Error("not implement math." + mode);
// }
}
return converter;
}
pbc.moduleFunctionD.get('math')['sin'] = mathTrigonometric('SIN');
pbc.moduleFunctionD.get('math')['cos'] = mathTrigonometric('COS');
pbc.moduleFunctionD.get('math')['tan'] = mathTrigonometric('TAN');
function mathAntiTrigonometric() {
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
if (args[0]._astname == "Call"
&& args[0].func._astname == "Attribute"
&& args[0].func.value._astname == "Name"
&& py2block.Name_str(args[0].func.value) == "math"
&& (py2block.identifier(args[0].func.attr) == "asin"
|| py2block.identifier(args[0].func.attr) == "acos"
|| py2block.identifier(args[0].func.attr) == "atan")
&& args[0].args.length == 1) {
return block("math_trig", func.lineno, {
'OP': py2block.identifier(args[0].func.attr).toUpperCase()
}, {
'NUM': py2block.convert(args[0].args[0])
}, {
"inline": "true"
});
} else {
throw new Error("not implement math.degrees");
}
}
return converter;
}
pbc.moduleFunctionD.get('math')['degrees'] = mathAntiTrigonometric();
function mathLogOrExp(mode) {
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (mode != "POW10") {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
return block("math_trig", func.lineno, {
'OP': mode
}, {
'NUM': py2block.convert(args[0])
}, {
"inline": "true"
});
} else {
if (args.length != 2) {
throw new Error("Incorrect number of arguments");
}
return block("math_trig", func.lineno, {
'OP': mode
}, {
'NUM': py2block.convert(args[1])
}, {
"inline": "true"
});
}
}
return converter;
}
pbc.moduleFunctionD.get('math')['log'] = mathLogOrExp('LN');
pbc.moduleFunctionD.get('math')['log10'] = mathLogOrExp('LOG10');
pbc.moduleFunctionD.get('math')['exp'] = mathLogOrExp('EXP');
pbc.moduleFunctionD.get('math')['pow'] = mathLogOrExp('POW10');
function mathIntFunc(mode) {
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
var varblock = py2block.convert(args[0]);
return block("math_to_int", func.lineno, {
'OP': mode
}, {
'A': varblock
}, {
"inline": "true"
});
}
return converter;
}
pbc.globalFunctionD['round'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1 && args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
if (args.length == 1){
var varblock = py2block.convert(args[0]);
return block("math_to_int", func.lineno, {
'OP': "round"
}, {
'A': varblock
}, {
"inline": "true"
});
}
if (args.length == 2){
var varblock = py2block.convert(args[0]);
var varblock1 = py2block.convert(args[1]);
return block("math_round", func.lineno, {}, {
'VALUE': varblock,
'VAR': varblock1
}, {
"inline": "true"
});
}
}
pbc.moduleFunctionD.get('math')['sqrt'] = mathIntFunc('sqrt');
pbc.moduleFunctionD.get('math')['ceil'] = mathIntFunc('ceil');
pbc.moduleFunctionD.get('math')['floor'] = mathIntFunc('floor');
pbc.moduleFunctionD.get('math')['fabs'] = mathIntFunc('fabs');
function mathMaxMin(mode) {
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length === 2) {
if (args[0]._astname == "Call"
&& args[0].func._astname == "Name"
&& py2block.Name_str(args[0].func) == "max"
&& py2block.Name_str(func) == "min") {
return block("math_constrain", func.lineno, {}, {
'VALUE': py2block.convert(args[0].args[0]),
'LOW': py2block.convert(args[0].args[1]),
'HIGH': py2block.convert(args[1])
}, {
"inline": "true"
});
} else {
var ablock = py2block.convert(args[0]);
var bblock = py2block.convert(args[1]);
return block("math_max_min", func.lineno, {
'OP': mode
}, {
'A': ablock,
'B': bblock
}, {
"inline": "true"
});
}
} else if (args.length === 1) {
var argblock = py2block.convert(args[0]);
return block("list_trig", func.lineno, {
'OP': mode.toUpperCase()
}, {
'data': argblock
}, {
"inline": "true"
});
} else {
throw new Error("Incorrect number of arguments");
}
}
return converter;
}
pbc.globalFunctionD['max'] = mathMaxMin('max');
pbc.globalFunctionD['min'] = mathMaxMin('min');
function mathRandom(mode) {
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 2) {
throw new Error("Incorrect number of arguments");
}
var fromblock = py2block.convert(args[0]);
var toblock = py2block.convert(args[1]);
return block("math_random", func.lineno, {
'TYPE': mode
}, {
'FROM': fromblock,
'TO': toblock
}, {
"inline": "true"
});
}
return converter;
}
pbc.moduleFunctionD.get('random')['randint'] = mathRandom('int');
pbc.moduleFunctionD.get('random')['uniform'] = mathRandom('float');
pbc.moduleFunctionD.get('random')['seed'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var varblock = py2block.convert(args[0]);
return [block("math_random_seed", func.lineno, {}, {
'NUM': varblock
}, {
"inline": "true"
})];
}
function radixToEng(num) {
if (num == 2) {
return 'two';
} else if (num == 8) {
return 'eight';
} else if (num == 10) {
return 'ten';
} else if (num == 16) {
return 'sixteen';
} else {
return "unknown";
}
}
pbc.globalFunctionD['int'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length == 1) {
var paramblock = py2block.convert(args[0]);
if (args[0]._astname == "Call" && args[0].func._astname == "Name" && py2block.Name_str(args[0].func) == "str") {
paramblock = py2block.convert(args[0].args[0]);
}else if(args[0]._astname == "Call" && args[0].func._astname == "Name" && py2block.Name_str(args[0].func) == "input"){
if(pbc.board == pbc.MIXPY) {
paramblock = py2block.convert(args[0].args[0]);
return block("inout_type_input", func.lineno, {
"DIR": "int"
}, {
'VAR': paramblock
}, {
"inline": "true"
});
}
}else if(args[0]._astname == "Call" && args[0].func._astname == "Attribute" && args[0].func.attr.v == "input"){
if(pbc.board == pbc.MIXPY) {
paramblock = py2block.convert(args[0].args[0]);
return block("inout_type_input", func.lineno, {
"DIR": "int"
}, {
'VAR': paramblock
}, {
"inline": "true"
});
}
}
return block("text_to_number", func.lineno, {
'TOWHAT': "int"
}, {
'VAR': paramblock,
}, {
"inline": "true"
});
} else if (args.length == 2) {
if (args[0]._astname == "Call" && args[0].func._astname == "Name" && py2block.Name_str(args[0].func) == "str"
&& args[1]._astname == "Num") {
var paramblock = py2block.convert(args[0].args[0]);
return block("math_number_base_conversion", func.lineno, {
'OP': radixToEng(args[1].n.v),
'OP2': 'ten'
}, {
'NUM': paramblock,
}, {
"inline": "true"
});
}
}
throw new Error("Incorrect number of arguments");
}
/*function radix(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
if (args[0]._astname == "Call"
&& args[0].func._astname == "Name" && py2block.Name_str(args[0].func) == "int"
&& args[0].args[0]._astname == "Call" && args[0].args[0].func._astname == "Name" && py2block.Name_str(args[0].args[0].func) == "str") {
var paramblock = py2block.convert(args[0].args[0].args[0]);
return block("math_number_base_conversion", func.lineno, {
'OP': radixToEng(args[0].args[1].n.v),
'OP2': mode
}, {
'NUM': paramblock,
}, {
"inline": "true"
});
}
}
return converter;
}
pbc.globalFunctionD['hex'] = radix('sixteen');
pbc.globalFunctionD['oct'] = radix('eight');
pbc.globalFunctionD['bin'] = radix('two');*/
pbc.globalFunctionD['math_map'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 5) {
throw new Error("Incorrect number of arguments");
}
return block("math_map", func.lineno, {}, {
'NUM': py2block.convert(args[0]),
'fromLow': py2block.convert(args[1]),
'fromHigh': py2block.convert(args[2]),
'toLow': py2block.convert(args[3]),
'toHigh': py2block.convert(args[4])
}, {
"inline": "true"
});
}
pbc.globalFunctionD['abs'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
return [block("math_to_int", func.lineno, {
"OP":'fabs'
}, {
'A': argblock
}, {
"inline": "true"
})];
}
function mathConstant(py2block, node, value, attr) {
return block('math_constant', node.lineno, {
'CONSTANT': value
}, {});
}
pbc.moduleAttrD.get('math')['pi'] = mathConstant;
pbc.moduleAttrD.get('math')['e'] = mathConstant;

View File

@@ -0,0 +1,180 @@
'use strict';
pbc.assignD.get('Set')['check_assign'] = function (py2block, node, targets, value) {
if (value._astname === "Set")
return true;
return false;
}
pbc.assignD.get('Set')['create_block'] = function (py2block, node, targets, value) {
return block("set_create_with", node.lineno, {
'VAR': py2block.Name_str(targets[0])
},
py2block.convertElements("ADD", value.elts), {
"inline": "false",
}, {
"@items": value.elts.length
});
}
//len在text里实现
pbc.objectFunctionD.get('pop')['Set'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length === 0) {
var popblock = py2block.convert(func.value);
return block("set_pop", func.lineno, {}, {
"SET":popblock
}, {
"inline": "true"
});
}else if(args.length === 1){
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return block("lists_pop", func.lineno, {}, {
"LIST":objblock,
"VALUE":argblock
}, {
"inline": "true"
});
}else{
throw new Error("Incorrect number of arguments");
}
}
//tuple(mytuple), set(mytup)在lists.js中实现
function setOperate(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return block("set_operate", func.lineno, {
'OPERATE': mode,
}, {
"SET1": objblock,
"SET2": argblock
}, {
"inline": "true"
});
}
return converter;
}
pbc.objectFunctionD.get('union')['Set'] = setOperate('union');
pbc.objectFunctionD.get('intersection')['Set'] = setOperate('intersection');
pbc.objectFunctionD.get('difference')['Set'] = setOperate('difference');
pbc.objectFunctionD.get('update')['Set'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return [block("set_update", func.lineno, {}, {
"SET": objblock,
"VAR": argblock
}, {
"inline": "true"
})];
};
function setOperateUpdate(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return [block("set_operate_update", func.lineno, {
'OPERATE': mode,
}, {
"SET1": objblock,
"SET2": argblock
}, {
"inline": "true"
})];
}
return converter;
}
pbc.objectFunctionD.get('difference_update')['Set'] = setOperateUpdate('difference_update');
pbc.objectFunctionD.get('intersection_update')['Set'] = setOperateUpdate('intersection_update');
function setAddDiscard(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return [block("set_add_discard", func.lineno, {
'OPERATE':mode,
}, {
"SET":objblock,
"data":argblock
}, {
"inline": "true"
})];
}
return converter;
}
pbc.objectFunctionD.get('add')['Set'] = setAddDiscard('add');
pbc.objectFunctionD.get('discard')['Set'] = setAddDiscard('discard');
function setSub(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return block("set_sub", func.lineno, {
'OPERATE':mode,
}, {
"SET1":objblock,
"SET2":argblock
}, {
"inline": "true"
});
}
return converter;
}
pbc.globalFunctionD['set'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length > 1) {
throw new Error("Incorrect number of arguments");
}
if (args.length ==0){
return block("set_create_with_noreturn", node.lineno, {},{}
, {
"inline": "true",
}, {
"@items": 0
});
}
if (args.length ==1){
var numblock = py2block.convert(args[0]);
return block("set_toset", func.lineno, {}, {
'VAR': numblock,
}, {
"inline": "false"
});
}
}
pbc.objectFunctionD.get('issubset')['Set'] = setSub('issubset');
pbc.objectFunctionD.get('issuperset')['Set'] = setSub('issuperset');

View File

@@ -0,0 +1,359 @@
'use strict';
var fileClass = 'open';
pbc.globalFunctionD['open'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
if (keywords.length == 0) {
var varblock = py2block.convert(args[0]);
var mode = py2block.Str_value(args[1]);
return block("storage_fileopen_new", node.lineno, {
"MODE":mode
}, {
"FILENAME":varblock
});
}
if (keywords.length == 1) {
var varblock = py2block.convert(args[0]);
var mode = py2block.Str_value(args[1]);
var code = py2block.Str_value(keywords[0].value);
return block("storage_fileopen_new_encoding", node.lineno, {
"MODE":mode,
"CODE":code
}, {
"FILENAME":varblock
});
}
}
pbc.objectFunctionD.get('write')[fileClass] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var fileblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return [block("storage_file_write", func.lineno, {}, {
"FILE" : fileblock,
"data" :argblock
}, {
"inline": "true"
})];
}
pbc.objectFunctionD.get('read')[fileClass] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length == 1) {
var fileblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return block("storage_get_contents", func.lineno, {
"MODE":"read"
}, {
"FILE" : fileblock,
"SIZE" : argblock
}, {
"inline": "true"
});
}
if (args.length == 0) {
var fileblock = py2block.convert(func.value);
return block("storage_get_contents_without_para", func.lineno, {
"MODE":"read"
}, {
"FILE" : fileblock
}, {
"inline": "true"
});
}
else{
throw new Error("Incorrect number of arguments");
}
}
pbc.objectFunctionD.get('readline')[fileClass] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length == 1) {
var fileblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return block("storage_get_contents", func.lineno, {
"MODE":"readline"
}, {
"FILE" : fileblock,
"SIZE" : argblock
}, {
"inline": "true"
});
}
if (args.length == 0) {
var fileblock = py2block.convert(func.value);
return block("storage_get_contents_without_para", func.lineno, {
"MODE":"readline"
}, {
"FILE" : fileblock
}, {
"inline": "true"
});
}
else{
throw new Error("Incorrect number of arguments");
}
}
pbc.objectFunctionD.get('readlines')[fileClass] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length == 1) {
var fileblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return block("storage_get_contents", func.lineno, {
"MODE":"readlines"
}, {
"FILE" : fileblock,
"SIZE" : argblock
}, {
"inline": "true"
});
}
if (args.length == 0) {
var fileblock = py2block.convert(func.value);
return block("storage_get_contents_without_para", func.lineno, {
"MODE":"readlines"
}, {
"FILE" : fileblock
}, {
"inline": "true"
});
}
else{
throw new Error("Incorrect number of arguments");
}
}
pbc.objectFunctionD.get('writable')[fileClass] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var fileblock = py2block.convert(func.value);
return block("storage_can_write_ornot", func.lineno, {}, {
"FILE" : fileblock,
}, {
"inline": "true"
});
}
pbc.objectFunctionD.get('name')[fileClass] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var fileblock = py2block.convert(func.value);
return block("storage_get_filename", func.lineno, {}, {
"FILE" : fileblock
}, {
"inline": "true"
});
}
pbc.objectFunctionD.get('close')[fileClass] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var fileblock = py2block.convert(func.value);
return [block("storage_close_file", func.lineno, {}, {
"FILE" : fileblock
}, {
"inline": "true"
})];
}
pbc.moduleFunctionD.get('os')['listdir'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
return block("storage_list_all_files", func.lineno, {}, {
}, {
"inline": "true"
});
}
pbc.moduleFunctionD.get('os')['remove'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
return [block("storage_delete_file", func.lineno, {"MODE":"remove"}, {
"FILE" : argblock
}, {
"inline": "true"
})];
}
pbc.moduleFunctionD.get('os')['removedirs'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
return [block("storage_delete_file", func.lineno, {"MODE":"removedirs"}, {
"FILE" : argblock
}, {
"inline": "true"
})];
}
pbc.moduleFunctionD.get('os')['size'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
return block("storage_get_file_size", func.lineno, {}, {
"FILE" : argblock
}, {
"inline": "true"
});
}
pbc.objectFunctionD.get('seek')[fileClass] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
var fileblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
if(args[1].n.v=="0"){
var mode = "start";
}
else if(args[1].n.v=="1"){
var mode = "current";
}
else{
var mode = "end";
}
return [block("storage_file_seek", func.lineno, {
"MODE": mode
}, {
"FILE" : fileblock,
"SIZE" : argblock
}, {
"inline": "true"
})];
}
pbc.objectFunctionD.get('tell')[fileClass] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var fileblock = py2block.convert(func.value);
return block("storage_file_tell", func.lineno, {
}, {
"FILE" : fileblock,
}, {
"inline": "true"
});
}
pbc.moduleFunctionD.get('os')['chdir'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
return [block("storage_change_dir", func.lineno, {}, {
"FILE" : argblock
}, {
"inline": "true"
})];
}
pbc.moduleFunctionD.get('os')['getcwd'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
return block("storage_get_current_dir", func.lineno, {}, {
}, {
"inline": "true"
});
}
pbc.moduleFunctionD.get('os')['mkdir'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var fun = func.attr.v;
var argblock = py2block.convert(args[0]);
return [block("storage_make_dir", func.lineno, {"MODE":fun}, {
"PATH" : argblock
}, {
"inline": "true"
})];
}
pbc.moduleFunctionD.get('os')['makedirs'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var fun = func.attr.v;
var argblock = py2block.convert(args[0]);
return [block("storage_make_dir", func.lineno, {"MODE":fun}, {
"PATH" : argblock
}, {
"inline": "true"
})];
}
pbc.moduleFunctionD.get('os')['rename'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
var arg1block = py2block.convert(args[1]);
return [block("storage_rename", func.lineno, {}, {
"FILE" : argblock,
"NEWFILE":arg1block
}, {
"inline": "true"
})];
}
pbc.moduleFunctionD.get('os')['isfile'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var fun = func.attr.v;
var argblock = py2block.convert(args[0]);
return [block("storage_is_file", func.lineno, {"MODE":fun}, {
"FILE" : argblock
}, {
"inline": "true"
})];
}
pbc.moduleFunctionD.get('os')['startfile'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var fun = func.attr.v;
var argblock = py2block.convert(args[0]);
return [block("storage_open_file_with_os", func.lineno, {"MODE":fun}, {
"fn" : argblock
}, {
"inline": "true"
})];
}
pbc.moduleFunctionD.get('os')['isdir'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var fun = func.attr.v;
var argblock = py2block.convert(args[0]);
return [block("storage_is_file", func.lineno, {"MODE":fun}, {
"FILE" : argblock
}, {
"inline": "true"
})];
}

View File

@@ -0,0 +1,377 @@
'use strict';
//01."text" 在 python_to_blockly.js实现
//02.str('Hello') + str('Mixly') 在 python_to_blockly.js实现
//03.int(str('123'))这种形式的在math.js实现
function numConvert(mode) {
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if ((mode != 'b' && args.length != 1) || (mode == 'b' && args.length != 2)) {
throw new Error("Incorrect number of arguments");
}
var paramblock = py2block.convert(args[0]);
if (args[0]._astname == "Call" && args[0].func._astname == "Name" && py2block.Name_str(args[0].func) == "str") {
paramblock = py2block.convert(args[0].args[0]);
}else if(args[0]._astname == "Call" && args[0].func._astname == "Name" && py2block.Name_str(args[0].func) == "input"){
if(pbc.board == pbc.MIXPY) {
paramblock = py2block.convert(args[0].args[0]);
return block("inout_type_input", func.lineno, {
"DIR": "float"
}, {
'VAR': paramblock
}, {
"inline": "true"
});
}
}else if(args[0]._astname == "Call" && args[0].func._astname == "Attribute" && args[0].func.attr.v == "input"){
if(pbc.board == pbc.MIXPY) {
paramblock = py2block.convert(args[0].args[0]);
return block("inout_type_input", func.lineno, {
"DIR": "float"
}, {
'VAR': paramblock
}, {
"inline": "true"
});
}
}
return block("text_to_number", func.lineno, {
'TOWHAT': mode
}, {
'VAR': paramblock,
}, {
"inline": "false"
});
}
return converter;
}
pbc.globalFunctionD['float'] = numConvert('float');
pbc.globalFunctionD['bytes'] = numConvert('b');
pbc.globalFunctionD['chr'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
var numblock = py2block.convert(args[0]);
return block("ascii_to_char", func.lineno, {}, {
'VAR': numblock,
}, {
"inline": "false"
});
}
pbc.globalFunctionD['ord'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
var numblock = py2block.convert(args[0]);
return block("char_to_ascii", func.lineno, {}, {
'VAR': numblock,
}, {
"inline": "false"
});
}
pbc.globalFunctionD['str'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
var numblock = py2block.convert(args[0]);
return block("number_to_text", func.lineno, {}, {
'VAR': numblock,
}, {
"inline": "false"
});
}
pbc.globalFunctionD['len'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
var numblock = py2block.convert(args[0]);
return block("text_length", func.lineno, {}, {
'VAR': numblock,
}, {
"inline": "false"
});
}
// 'mixly'[0]这种形式的在python_to_blockly.js中实现
pbc.moduleFunctionD.get('random')['choice'] = function (py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
var argAstname = args[0]._astname;
if(args[0]._astname == "Call" && args[0].func._astname == "Name" && py2block.Name_str(args[0].func) == "str"){
argblock = py2block.convert(args[0].args[0]);
argAstname = "Str";
}
if(argAstname == "Str"){
return block('text_random_char', func.lineno, {}, {
'VAR':argblock
}, {
"inline": "true"
});
}else{
return block('lists_get_random_item', func.lineno, {}, {
'LIST':argblock
}, {
"inline": "true"
});
}
}
//str('123') == str('234')这种形式的在python_to_blockly.js中实现
function startEndWithStr(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
if(func.value._astname == "Call" && func.value.func._astname == "Name" && py2block.Name_str(func.value.func) == "str"){
objblock = py2block.convert(func.value.args[0]);
}
var argblock = py2block.convert(args[0]);
if(args[0]._astname == "Call" && args[0].func._astname == "Name" && py2block.Name_str(args[0].func) == "str"){
argblock = py2block.convert(args[0].args[0]);
}
return block('text_equals_starts_ends', func.lineno, {
'DOWHAT':mode
}, {
'STR1':objblock,
'STR2':argblock
}, {
"inline": "true"
});
}
return converter;
}
pbc.objectFunctionD.get('startswith')['Str'] = startEndWithStr('startswith');
pbc.objectFunctionD.get('endswith')['Str'] = startEndWithStr('endswith');
// 'mixly'[0:8]这种形式的在python_to_blockly.js中实现
function strTitle(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var textblock = py2block.convert(func.value);
return block("text_capital", func.lineno, {
'CAPITAL': mode,
}, {
"VAR": textblock,
}, {
"inline": "true"
});
}
return converter;
}
pbc.objectFunctionD.get('upper')['Str'] = strTitle('upper');
pbc.objectFunctionD.get('title')['Str'] = strTitle('title');
pbc.objectFunctionD.get('lower')['Str'] = strTitle('lower');
pbc.objectFunctionD.get('swapcase')['Str'] = strTitle('swapcase');
pbc.objectFunctionD.get('capitalize')['Str'] = strTitle('capitalize');
function strencode(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var textblock = py2block.convert(func.value);
return block("text_to_number", func.lineno, {
'TOWHAT': mode,
}, {
"VAR": textblock,
}, {
"inline": "true"
});
}
return converter;
}
pbc.objectFunctionD.get('encode')['Str'] = strencode('b');
function textStrip(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 0) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
return block("text_strip", func.lineno, {
'TOWHAT': mode,
}, {
"VAR": objblock,
}, {
"inline": "true"
});
}
return converter;
}
pbc.objectFunctionD.get('strip')['Str'] = textStrip('strip');
pbc.objectFunctionD.get('lstrip')['Str'] = textStrip('lstrip');
pbc.objectFunctionD.get('rstrip')['Str'] = textStrip('rstrip');
function textAlign(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock1 = py2block.convert(args[0]);
var argblock2 = py2block.convert(args[1]);
return block("text_center", func.lineno, {
'CENTER': mode,
}, {
"VAR": objblock,
"WID": argblock1,
"Symbol": argblock2
}, {
"inline": "true"
});
}
return converter;
}
pbc.objectFunctionD.get('ljust')['Str'] = textAlign('ljust');
pbc.objectFunctionD.get('center')['Str'] = textAlign('center');
pbc.objectFunctionD.get('rjust')['Str'] = textAlign('rjust');
pbc.objectFunctionD.get('split')['Str'] = function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return block("text_split", func.lineno, {
}, {
"VAR": objblock,
"VAL": argblock
}, {
"inline": "true"
});
}
pbc.objectFunctionD.get('replace')['Str'] = function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 2) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock1 = py2block.convert(args[0]);
var argblock2 = py2block.convert(args[1]);
return block("text_replace", func.lineno, {
}, {
"VAR": objblock,
"STR1": argblock1,
"STR2": argblock2
}, {
"inline": "true"
});
}
pbc.objectFunctionD.get('find')['Str'] = function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return block("text_find", func.lineno, {
}, {
"VAR": objblock,
"STR": argblock
}, {
"inline": "true"
});
}
pbc.objectFunctionD.get('join')['Str'] = function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
var argblock = py2block.convert(args[0]);
return block("text_join_seq", func.lineno, {
}, {
"VAR": objblock,
"LIST": argblock
}, {
"inline": "true"
});
}
pbc.objectFunctionD.get('format')['Str'] = function converter(py2block, func, args, keywords, starargs, kwargs, node) {
var objblock = py2block.convert(func.value);
var d = py2block.convertElements("ADD", args);
d['VAR'] = objblock;
return block("text_format_noreturn", node.lineno, {
}, d, {
"inline": "true",
}, {
"@items":args.length
});
}
function strEncodeDecode(mode){
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var objblock = py2block.convert(func.value);
return block("text_encode", func.lineno, {
'DIR': mode,
'CODE':args[0].s.v
}, {
"VAR": objblock,
}, {
"inline": "true"
});
}
return converter;
}
pbc.objectFunctionD.get('encode')['Str'] = strEncodeDecode('encode');
pbc.objectFunctionD.get('decode')['Str'] = strEncodeDecode('decode');
pbc.globalFunctionD['eval'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length != 1) {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
return block("text_eval", func.lineno, {}, {
"VAR":argblock
}, {
"inline": "true"
});
}
pbc.moduleFunctionD.get('os')['system'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var varblock = py2block.convert(args[0]);
return [block("os_system", func.lineno, {}, {
'VAR': varblock
}, {
"inline": "true"
})];
}

View File

@@ -0,0 +1,47 @@
'use strict';
pbc.assignD.get('Tuple')['check_assign'] = function (py2block, node, targets, value) {
if (value._astname === "Tuple")
return true;
return false;
}
pbc.assignD.get('Tuple')['create_block'] = function (py2block, node, targets, value) {
return block("tuple_create_with", node.lineno, {
'VAR': py2block.Name_str(targets[0])
},
py2block.convertElements("ADD", value.elts), {
"inline": elts.length < 4 ? "false" : "true",
}, {
"@items": value.elts.length
});
}
//mytup[0]在python_to_blockly.py中实现
//len在text里实现
//max/min在math里已实现
//list(mytuple), set(mytup)在lists.js中实现
pbc.globalFunctionD['tuple'] = function(py2block, func, args, keywords, starargs, kwargs, node){
if (args.length > 1) {
throw new Error("Incorrect number of arguments");
}
if (args.length ==0){
return block("tuple_create_with_noreturn", node.lineno, {},{}
, {
"inline": "true",
}, {
"@items": 0
});
}
if (args.length ==1){
var numblock = py2block.convert(args[0]);
return block("tuple_totuple", func.lineno, {}, {
'VAR': numblock,
}, {
"inline": "false"
});
}
}

View File

@@ -0,0 +1,39 @@
'use strict';
pbc.globalFunctionD['dict'] = function converter(py2block, func, args, keywords, starargs, kwargs, node) {
var paramblock = py2block.convert(args[0]);
return block("variables_change", func.lineno, {
'OP': 'dict'
}, {
'MYVALUE': paramblock,
}, {
"inline": "false"
});
}
function TypeConvert(mode) {
function converter(py2block, func, args, keywords, starargs, kwargs, node) {
if (args.length !== 1) {
throw new Error("Incorrect number of arguments");
}
var argblock = py2block.convert(args[0]);
return block("variables_change", func.lineno, {
"OP":mode
}, {
'MYVALUE': argblock
}, {
"inline": "true"
});
}
return converter;
}
pbc.globalFunctionD['int'] = TypeConvert('int');
pbc.globalFunctionD['float'] = TypeConvert('float');
pbc.globalFunctionD['bool'] = TypeConvert('bool');
// pbc.globalFunctionD['complex'] = TypeConvert('complex');
pbc.globalFunctionD['str'] = TypeConvert('str');
pbc.globalFunctionD['list'] = TypeConvert('list');
pbc.globalFunctionD['tuple'] = TypeConvert('tuple');
pbc.globalFunctionD['set'] = TypeConvert('set');
pbc.globalFunctionD['dict'] = TypeConvert('dict');

View File

@@ -0,0 +1,65 @@
import * as PythonVariablesBlocks from './blocks/variables';
import * as PythonControlBlocks from './blocks/control';
import * as PythonMathBlocks from './blocks/math';
import * as PythonTextBlocks from './blocks/text';
import * as PythonListsBlocks from './blocks/lists';
import * as PythonDictsBlocks from './blocks/dicts';
import * as PythonLogicBlocks from './blocks/logic';
import * as PythonStorageBlocks from './blocks/storage';
import * as PythonProceduresBlocks from './blocks/procedures';
import * as PythonTupleBlocks from './blocks/tuple';
import * as PythonSetBlocks from './blocks/set';
import * as PythonHtmlBlocks from './blocks/html';
import * as PythonUtilityBlocks from './blocks/utility';
import * as PythonVariablesGenerators from './generators/variables';
import * as PythonControlGenerators from './generators/control';
import * as PythonMathGenerators from './generators/math';
import * as PythonTextGenerators from './generators/text';
import * as PythonListsGenerators from './generators/lists';
import * as PythonDictsGenerators from './generators/dicts';
import * as PythonLogicGenerators from './generators/logic';
import * as PythonStorageGenerators from './generators/storage';
import * as PythonProceduresGenerators from './generators/procedures';
import * as PythonTupleGenerators from './generators/tuple';
import * as PythonSetGenerators from './generators/set';
import * as PythonHtmlGenerators from './generators/html';
import * as PythonUtilityGenerators from './generators/utility';
import Names from './others/names';
import Procedures from './others/procedures';
import Variables from './others/variables';
import { Python } from './python_generator';
export {
PythonVariablesBlocks,
PythonControlBlocks,
PythonMathBlocks,
PythonTextBlocks,
PythonListsBlocks,
PythonDictsBlocks,
PythonLogicBlocks,
PythonStorageBlocks,
PythonProceduresBlocks,
PythonTupleBlocks,
PythonSetBlocks,
PythonHtmlBlocks,
PythonUtilityBlocks,
PythonVariablesGenerators,
PythonControlGenerators,
PythonMathGenerators,
PythonTextGenerators,
PythonListsGenerators,
PythonDictsGenerators,
PythonLogicGenerators,
PythonStorageGenerators,
PythonProceduresGenerators,
PythonTupleGenerators,
PythonSetGenerators,
PythonHtmlGenerators,
PythonUtilityGenerators,
Names,
Procedures,
Variables,
Python
};

View File

@@ -0,0 +1,89 @@
import * as Blockly from 'blockly/core';
// 物联网-wifi信息
export const blynk_server = function (_, generator) {
var wifi_ssid = generator.valueToCode(this, 'wifi_ssid', generator.ORDER_ATOMIC);
var wifi_pass = generator.valueToCode(this, 'wifi_pass', generator.ORDER_ATOMIC);
generator.definitions_.import_time = "import network,time,BlynkLib";
var code;
code = "wlan = network.WLAN(network.STA_IF)\n";
code += "wlan.active(True)\n";
code += "if not wlan.isconnected():\n";
code += " print('connecting to network...')\n";
code += " wlan.connect(" + wifi_ssid + "," + wifi_pass + ")\n";
code += " while not wlan.isconnected():\n";
code += " pass\n";
code += "print('network config:', wlan.ifconfig())\n";
code += "BLYNK_AUTH='" + "auth_key" + "'\n";
code += "blynk = BlynkLib.Blynk(BLYNK_AUTH)\n"
code += "while True:\n"
code += " blynk.run()\n"
code += " pass\n"
return code;
}
// 物联网-wifi信息
export const blynk_iot_get_data = function (_, generator) {
var Vpin = this.getFieldValue('Vpin');
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
args[x] = generator.valueToCode(this, 'ARG' + x, generator.ORDER_NONE) || 'null';
}
var code = '(a' + args.join(', ') + ');\n';
var branch = generator.statementToCode(this, 'STACK');
if (generator.INFINITE_LOOP_TRAP) {
branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + this.id + '\'') + branch;
}
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
args[x] = this.argumentstype_[x] + ' ' + generator.variableDB_.getName(this.arguments_[x], Blockly.Variables.NAME_TYPE);
}
var GetDataCode = "";
if (this.arguments_.length == 1) {
GetDataCode = generator.variableDB_.getName(this.arguments_[0], Blockly.Variables.NAME_TYPE);
if (this.argumentstype_[0] == "int")
GetDataCode += "= param.asInt();\n"
else if (this.argumentstype_[0] == "String")
GetDataCode += "= param.asStr();\n"
else if (this.argumentstype_[0] == "long")
GetDataCode += "= param.asDouble();\n"
else if (this.argumentstype_[0] == "float")
GetDataCode += "= param.asFloat();\n"
else if (this.argumentstype_[0] == "boolean")
GetDataCode += "= param.asInt();\n"
else if (this.argumentstype_[0] == "byte")
GetDataCode += "= param.asStr();\n"
else if (this.argumentstype_[0] == "char")
GetDataCode += "= param.asStr();\n"
}
else {
for (var x = 0; x < this.arguments_.length; x++) {
args[x] = this.argumentstype_[x] + ' ' + generator.variableDB_.getName(this.arguments_[x], Blockly.Variables.NAME_TYPE);
GetDataCode += generator.variableDB_.getName(this.arguments_[x], Blockly.Variables.NAME_TYPE);
if (this.argumentstype_[x] == "int")
GetDataCode += "= param[" + x + "].asInt();\n"
else if (this.argumentstype_[x] == "String")
GetDataCode += "= param[" + x + "].asStr();\n"
else if (this.argumentstype_[x] == "long")
GetDataCode += "= param[" + x + "].asDouble();\n"
else if (this.argumentstype_[x] == "float")
GetDataCode += "= param[" + x + "].asFloat();\n"
else if (this.argumentstype_[x] == "boolean")
GetDataCode += "= param[" + x + "].asInt();\n"
else if (this.argumentstype_[x] == "byte")
GetDataCode += "= param[" + x + "].asStr();\n"
else if (this.argumentstype_[x] == "char")
GetDataCode += "= param[" + x + "].asStr();\n"
}
}
if (this.arguments_.length > 0)
generator.definitions_[args] = args.join(';\n') + ";";
var code = ' BLYNK_WRITE(' + Vpin + ') {\n' + GetDataCode +
branch + '}\n';
// var code = 'BLYNK_WRITE(' + Vpin+ ') {\n'+variable+" = param.as"+datatype+"();\n"+branch+'}\n';
code = generator.scrub_(this, code);
generator.definitions_[Vpin] = code;
return null;
}

View File

@@ -0,0 +1,147 @@
import * as Blockly from 'blockly/core';
export const class_make = function (_, generator) {
var text_name = this.getFieldValue('VAR') || 'None';
var statements_data = generator.statementToCode(this, 'data');
var code = 'class ' + text_name + ':\n' + statements_data;
return code;
}
export const class_make_with_base = function (_, generator) {
var text_name = this.getFieldValue('VAR') || 'None';
var name = generator.valueToCode(this, 'NAME', generator.ORDER_ASSIGNMENT) || 'None';
var statements_data = generator.statementToCode(this, 'data');
var code = '';
if (name == 'None')
code = 'class ' + text_name + ':\n' + statements_data;
else
code = 'class ' + text_name + '(' + name + '):\n' + statements_data;
return code;
}
export const class_get = function (_, generator) {
var code = this.getFieldValue('VAR') || 'None';
return [code, generator.ORDER_ATOMIC];
}
export const property_set = function (_, generator) {
var argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || 'None';
var argument1 = generator.valueToCode(this, 'DATA', generator.ORDER_ASSIGNMENT) || 'None';
var varName = this.getFieldValue('VAR') || 'None';
return argument0 + '.' + varName + ' = ' + argument1 + '\n';
}
export const property_get = function (_, generator) {
var argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || 'None';
var code = this.getFieldValue('VAR') || 'None';
return [argument0 + '.' + code, generator.ORDER_ATOMIC];
}
export const object_set = function (_, generator) {
var text_name = this.getFieldValue('VAR10') || 'None';
var text_new_name = this.getFieldValue('VAR11') || 'None';
var code = new Array(this.itemCount_);
for (var n = 0; n < this.itemCount_; n++) {
code[n] = generator.valueToCode(this, 'ADD' + n, generator.ORDER_NONE) || 'None';
}
var code = text_new_name + ' = ' + text_name + '(' + code.join(',') + ')\n';
return code;
}
export const object_get = function (_, generator) {
var code = this.getFieldValue('VAR') || 'None';
return [code, generator.ORDER_ATOMIC];
}
export const method_procedures_defreturn = function (_, generator) {
// Define a procedure with a return value.
//var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
// Blockly.Class_Test.NAME_TYPE);
var funcName = this.getFieldValue('NAME') || 'None';
var branch = generator.statementToCode(this, 'STACK') || ' pass\n';
if (generator.INFINITE_LOOP_TRAP) {
branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
'\'' + this.id + '\'') + branch;
}
var returnValue = generator.valueToCode(this, 'RETURN',
generator.ORDER_NONE) || '';
//var type=this.getFieldValue('TYPE');
if (returnValue) {
returnValue = ' return ' + returnValue + '\n';
}
//var returnType = returnValue ? type : 'void';
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
var varName = generator.variableDB_.getName(this.arguments_[x], Blockly.Variables.NAME_TYPE);
args[x] = varName;
}
var code = '';
//if(this.arguments_.length)
code = 'def ' + funcName + '(' + args.join(', ') + '):\n' +
branch + returnValue + '\n';
//code = generator.scrub_(this, code);
//generator.setups_[funcName] = code;
return code;
}
export const method_procedures_defnoreturn = method_procedures_defreturn;
export const method_procedures_callreturn = function (_, generator) {
var argument1 = generator.valueToCode(this, 'DATA', generator.ORDER_ASSIGNMENT) || 'None';
// Call a procedure with a return value.
//var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
// Blockly.Class_Test.NAME_TYPE);
var funcName = this.getFieldValue('NAME');
var args = [];
for (var x = 0; x < this.arguments_.length - 1; x++) {
args[x] = generator.valueToCode(this, 'ARG' + (x + 1),
generator.ORDER_NONE) || 'null';
}
var code = argument1 + '.' + funcName + '(' + args.join(', ') + ')';
return [code, generator.ORDER_UNARY_POSTFIX];
}
export const method_procedures_callnoreturn = function (_, generator) {
var argument1 = generator.valueToCode(this, 'DATA', generator.ORDER_ASSIGNMENT) || 'None';
// Call a procedure with no return value.
//var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
// Blockly.Class_Test.NAME_TYPE);
var funcName = this.getFieldValue('NAME');
var args = [];
for (var x = 0; x < this.arguments_.length - 1; x++) {
args[x] = generator.valueToCode(this, 'ARG' + (x + 1),
generator.ORDER_NONE) || 'null';
}
var code = argument1 + '.' + funcName + '(' + args.join(', ') + ')\n';
return code;
}
export const method_procedures_ifreturn = function (_, generator) {
// Conditionally return value from a procedure.
var condition = generator.valueToCode(this, 'CONDITION',
generator.ORDER_NONE) || 'False';
var code = 'if (' + condition + ') :\n';
if (this.hasReturnValue_) {
var value = generator.valueToCode(this, 'VALUE',
generator.ORDER_NONE) || 'None';
code += ' return ' + value;
} else {
code += ' return None';
}
code += '\n';
return code;
}
export const method_procedures_return = function (_, generator) {
// Conditionally return value from a procedure.
var code = ""
if (this.hasReturnValue_) {
var value = generator.valueToCode(this, 'VALUE',
generator.ORDER_NONE) || 'None';
code += 'return ' + value;
} else {
code += 'return None';
}
code += '\n';
return code;
}

View File

@@ -0,0 +1,296 @@
import * as Blockly from 'blockly/core';
import { Boards } from 'mixly';
export const controls_main = function (a, generator) {
var d = generator.statementToCode(a, "DO"),
d = generator.addLoopTrap(d, a.id) || generator.PASS;
return "if __name__ == '__main__':\n" + d;
}
export const base_setup = function (_, generator) {
var branch = generator.statementToCode(this, 'DO');
branch = branch.replace(/(^\s*)|(\s*$)/g, "").replace(/\n {4}/g, '\n');//去除两端空格
if (branch.endsWith('\n')) {
generator.setups_['setup_setup'] = branch;
}
else {
generator.setups_['setup_setup'] = branch + '\n';
}
return '';
}
// ok
export const controls_if = function (a, generator) {
var b = 0,
c = "",
d,
e;
do
e = generator.valueToCode(a, "IF" + b, generator.ORDER_NONE) || "False", d = generator.statementToCode(a, "DO" + b) || generator.PASS, c += (0 == b ? "if " : "elif ") + e + ":\n" + d, ++b;
while (a.getInput("IF" + b));
a.getInput("ELSE") && (d = generator.statementToCode(a, "ELSE") || generator.PASS, c += "else:\n" + d);
return c
}
export const controls_try_finally = function (_, generator) {
var n = 1;
var argument = generator.valueToCode(this, 'IF' + n,
generator.ORDER_NONE) || 'null';
var branch = '';
var t = generator.statementToCode(this, 'try') || ' pass\n';
var code = 'try:\n' + t;
for (n = 1; n <= this.elseifCount_; n++) {
argument = generator.valueToCode(this, 'IF' + n,
generator.ORDER_NONE) || '';
if (argument !== '')
argument = ' ' + argument
branch = generator.statementToCode(this, 'DO' + n) || ' pass\n';
code += 'except' + argument + ': \n' + branch;
}
if (this.elseCount_) {
branch = generator.statementToCode(this, 'ELSE') || ' pass\n';
code += 'finally:\n' + branch;
}
// code += '}';
return code;
}
// ok
export const controls_for = function (a, generator) {
var b = generator.variableDB_.getName(a.getFieldValue("VAR"), Blockly.Variables.NAME_TYPE),
//var b = generator.valueToCode(a, "VAR", generator.ORDER_MEMBER) || "''",
c = generator.valueToCode(a, "FROM", generator.ORDER_NONE) || "0",
d = generator.valueToCode(a, "TO", generator.ORDER_NONE) || "0",
e = generator.valueToCode(a, "STEP", generator.ORDER_NONE) || "1",
f = generator.statementToCode(a, "DO"),
f = generator.addLoopTrap(f, a.id) || generator.PASS,
g = "",
h = function (_, generator) {
return generator.provideFunction_("upRange",
["def " + generator.FUNCTION_NAME_PLACEHOLDER_ + "(start, stop, step):", " while start <= stop:", " yield start", " start += abs(step)"])
},
k = function (_, generator) {
return generator.provideFunction_("downRange", ["def " + generator.FUNCTION_NAME_PLACEHOLDER_ + "(start, stop, step):", " while start >= stop:", " yield start", " start -= abs(step)"])
}
a = function (a, b, c) {
return "(" + a + " <= " + b + ") and " + h() + "(" + a + ", " + b + ", " + c + ") or " + k() + "(" + a + ", " + b + ", " + c + ")"
}
if (Blockly.isNumber(c) && Blockly.isNumber(d) &&
Blockly.isNumber(e))
c = parseFloat(c), d = parseFloat(d), e = Math.abs(parseFloat(e)), 0 === c % 1 && 0 === d % 1 && 0 === e % 1 ? (c <= d ? (d++, a = 0 == c && 1 == e ? d : c + ", " + d, 1 != e && (a += ", " + e)) : (d--, a = c + ", " + d + ", -" + e), a = "range(" + a + ")") : (a = c < d ? h() : k(), a += "(" + c + ", " + d + ", " + e + ")");
else {
var l = function (a, c) {
if (Blockly.isNumber(a))
a = parseFloat(a);
else {
var d = generator.variableDB_.getDistinctName(b + c, Blockly.Variables.NAME_TYPE);
g += d + " = " + a + "\n";
a = d
}
return a
},
c = l(c, "_start"),
d = l(d, "_end");
l(e, "_inc");
a = "number" == typeof c && "number" == typeof d ? c < d ? h(c, d, e) : k(c, d, e) : a(c, d, e)
}
return g += "for " + b + " in " + a + ":\n" + f
}
export const controls_for_range = function (block, generator) {
var iter = generator.variableDB_.getName(block.getFieldValue("VAR"), Blockly.Variables.NAME_TYPE),
from = generator.valueToCode(block, "FROM", generator.ORDER_NONE) || "0",
end = generator.valueToCode(block, "TO", generator.ORDER_NONE) || "0",
step = generator.valueToCode(block, "STEP", generator.ORDER_NONE) || "1",
dostatement = generator.statementToCode(block, "DO"),
pass = generator.addLoopTrap(dostatement, block.id) || generator.PASS;
generator.setups_["mixly_range"] = "def mixly_range(start, stop, step):\n" +
" for i in range(start, stop + 1, step):\n" +
" yield i\n\n";
return "for " + iter + " in mixly_range(" + from + ", " + end + ", " + step + "):\n" + pass;
}
export const controls_whileUntil = function (a, generator) {
var b = "UNTIL" == a.getFieldValue("MODE"),
c = generator.valueToCode(a, "BOOL", generator.ORDER_NONE) || "False",
d = generator.statementToCode(a, "DO"),
d = generator.addLoopTrap(d, a.id) || generator.PASS;
b && (c = "not " + c);
return "while " + c + ":\n" + d
}
// export const controls_flow_statements = function (_, generator) {
// // Flow statements: continue, break.
// switch (this.getFieldValue('FLOW')) {
// case 'BREAK':
// return 'break;\n';
// case 'CONTINUE':
// return 'continue;\n';
// }
// throw 'Unknown flow statement.';
// }
//ok
export const controls_flow_statements = function (a) {
switch (a.getFieldValue("FLOW")) {
case "BREAK":
return "break\n";
case "CONTINUE":
return "continue\n"
}
throw "Unknown flow statement.";
}
// ok
export const controls_delay = function (_, generator) {
var delay_time = generator.valueToCode(this, 'DELAY_TIME', generator.ORDER_ATOMIC) || '1000'
var code = 'sleep(' + delay_time + ')\n';
return code;
}
// ok
export const Panic_with_status_code = function (_, generator) {
var status_code = generator.valueToCode(this, 'STATUS_CODE', generator.ORDER_ATOMIC) || '1000'
var code = 'panic(' + status_code + ')\n';
return code;
}
// ok
export const controls_millis = function (_, generator) {
generator.definitions_.import_time = "import time";
var code = 'time.time()';
return [code, generator.ORDER_ATOMIC];
}
// ok
export const reset = function (_, generator) {
generator.definitions_['import_microbit'] = 'from microbit import *'
return 'reset()\n';
}
export const controls_interrupts = function () {
return 'interrupts();\n';
}
export const controls_nointerrupts = function () {
return 'noInterrupts();\n';
}
export const controls_forEach = function (block, generator) {
// For each loop.
var variable0 = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '\'\'';
var argument0 = generator.valueToCode(block, 'LIST',
generator.ORDER_RELATIONAL) || '[]';
var branch = generator.statementToCode(block, 'DO');
branch = generator.addLoopTrap(branch, block.id) ||
generator.PASS;
var code = 'for ' + variable0 + ' in ' + argument0 + ':\n' + branch;
return code;
}
export const controls_range = function (_, generator) {
var from = generator.valueToCode(this, "FROM", generator.ORDER_NONE) || "0";
var end = generator.valueToCode(this, "TO", generator.ORDER_NONE) || "0";
var step = generator.valueToCode(this, "STEP", generator.ORDER_NONE) || "1";
var code = "range(" + from + ", " + end + ", " + step + ")";
return [code, generator.ORDER_ATOMIC];
}
export const controls_lambda = function (a, generator) {
var c = generator.valueToCode(a, "BOOL", generator.ORDER_NONE) || "None",
d = generator.statementToCode(a, "DO") || "pass";
var code = "lambda " + c + ": " + d;
code = code.replace('\n', '').replace(' ', '')
return [code, generator.ORDER_ATOMIC];
}
export const time_sleep = function (_, generator) {
generator.definitions_['import_time'] = 'import time';
var delay_time = generator.valueToCode(this, 'DELAY_TIME', generator.ORDER_ATOMIC) || '1000'
var code = 'time.sleep(' + delay_time + ')\n';
return code;
}
export const controls_pass = function () {
return 'pass\n';
}
export const controls_thread = function (_, generator) {
generator.definitions_['import__thread'] = 'import _thread';
var v = generator.valueToCode(this, "VAR", generator.ORDER_NONE) || "None";
var callback = generator.variableDB_.getName(
generator.valueToCode(this, "callback", generator.ORDER_NONE) || "None",
Blockly.Procedures.NAME_TYPE
);
var code = "_thread.start_new_thread(" + callback + ", " + v + ")\n";
return code;
}
// do-while循环
export const do_while = function (_, generator) {
var value_select_data = generator.valueToCode(this, 'select_data', generator.ORDER_NONE) || "False";
var statements_input_data = generator.statementToCode(this, 'input_data')
var dropdown_type = this.getFieldValue('type');
if (dropdown_type == 'true') {
statements_input_data = statements_input_data + ' if (' + value_select_data + '):\n' + ' break\n';
}
else {
statements_input_data = statements_input_data + ' if not (' + value_select_data + '):\n' + ' break\n';
}
statements_input_data = generator.addLoopTrap(statements_input_data, this.id) || generator.PASS;
//var dropdown_type = this.getFieldValue('type');
var code = 'while True:\n' + statements_input_data;
return code;
}
// export const base_type = controls_type;
// export const controls_TypeLists = controls_typeLists;
export const controls_repeat_ext = function (a, generator) {
var times = generator.valueToCode(this, 'TIMES', generator.ORDER_ATOMIC);
var d = generator.statementToCode(a, "DO"),
d = generator.addLoopTrap(d, a.id) || generator.PASS;
return 'for _my_variable in range(' + times + '):\n' + d;
}
export const garbage_collection = function (_, generator) {
generator.definitions_['import_gc'] = 'import gc';
var code = 'gc.collect()\n'
return code;
}
export const get_mem_alloc = function (_, generator) {
generator.definitions_['import_gc'] = 'import gc';
var code = 'gc.mem_alloc()';
return [code, generator.ORDER_ATOMIC];
}
export const get_mem_free = function (_, generator) {
generator.definitions_['import_gc'] = 'import gc';
var code = 'gc.mem_free()';
return [code, generator.ORDER_ATOMIC]
}
export const get_unique_identifier = function (_, generator) {
generator.definitions_['import_machine'] = 'import machine';
var code = 'machine.unique_id()';
return [code, generator.ORDER_ATOMIC];
}
// ok
export const controls_repeat = controls_repeat_ext;
export const datetime_fromtimestamp = function(_,generator){
generator.definitions_['import_datetime'] = 'import datetime';
var ts = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var code = 'datetime.datetime.fromtimestamp(' + ts + ')';
return [code, generator.ORDER_ATOMIC];
}
export const gene_unique_identifier = function (_, generator) {
var version = Boards.getSelectedBoardKey().split(':')[2]
generator.definitions_['import_' + version + 'uuid'] = 'from ' + version + ' import uuid';
var code = 'uuid()';
return [code, generator.ORDER_ATOMIC]
}

View File

@@ -0,0 +1,225 @@
/**
* @license
* Visual Blocks Language
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Generating Python for dictionary blocks.
* @author acbart@vt.edu (Austin Cory Bart)
*/
import * as Blockly from 'blockly/core';
import { Boards } from 'mixly';
export const dicts_create_with = function (_, generator) {
// Create a list with any number of elements of any type.
//var dropdown_type = this.getFieldValue('TYPE');
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
Blockly.Variables.NAME_TYPE);
//var size=window.parseFloat(this.getFieldValue('SIZE'));
var code = new Array(this.itemCount_);
var default_value = '0';
for (var n = 0; n < this.itemCount_; n++) {
var keyName = this.getFieldValue('KEY' + n);
code[n] = keyName + ":" + (generator.valueToCode(this, 'ADD' + n, generator.ORDER_NONE) || default_value);
}
var code = varName + '= ' + '{' + code.join(', ') + '}\n';
//var code =''+varName+'['+size+"]"+'='+ '{' + code.join(', ') + '}\n';
//generator.setups_['setup_lists'+varName] = code;
return code;
}
export const dicts_keys = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.keys()';
return [code, generator.ORDER_ATOMIC];
}
export const dicts_get = function (_, generator) {
var version = Boards.getSelectedBoardKey().split(':')[2]
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
//var size=window.parseFloat(this.getFieldValue('SIZE'));
var text = generator.valueToCode(this, 'KEY', generator.ORDER_ASSIGNMENT);
// var text=this.getFieldValue('KEY');
if (version=='educore'){
var code = varName+'.get('+text+')';
}else{
var code = varName + "[" + text + "]";
}
return [code, generator.ORDER_ATOMIC];
}
export const dicts_get_default = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
//var size=window.parseFloat(this.getFieldValue('SIZE'));
var text = generator.valueToCode(this, 'KEY', generator.ORDER_ASSIGNMENT);
var argument = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
// var text=this.getFieldValue('KEY');
var code = varName + ".get(" + text + ',' + argument + ")";
return [code, generator.ORDER_ATOMIC];
}
export const dicts_add_or_change = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || 'mydict';
var text = generator.valueToCode(this, 'KEY', generator.ORDER_ASSIGNMENT);
// var text=this.getFieldValue('KEY');
var argument = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + "[" + text + "] = " + argument + '\n';
return code;
}
export const dicts_delete = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || 'mydict';
var text = generator.valueToCode(this, 'KEY', generator.ORDER_ASSIGNMENT);
// var text=this.getFieldValue('KEY');
var code = "del " + varName + "[" + text + "]\n";
return code;
}
export const dicts_update = function (_, generator) {
var varName2 = generator.valueToCode(this, 'DICT2', generator.ORDER_ASSIGNMENT) || '0';
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.update(' + varName2 + ')\n';
return code;
}
export const dicts_clear = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.clear()\n';
return code;
}
export const dicts_items = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.items()';
return [code, generator.ORDER_ATOMIC];
}
export const dicts_values = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.values()';
return [code, generator.ORDER_ATOMIC];
}
export const dicts_length = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var code = 'len(' + varName + ')';
return [code, generator.ORDER_ATOMIC];
}
export const dicts_deldict = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var code = 'del ' + varName + '\n';
return code;
}
export const dicts_add_change_del = function (block, generator) {
var dict = generator.valueToCode(block, 'DICT',
generator.ORDER_MEMBER) || '[]';
var mode = block.getFieldValue('WHERE');
var KEY = generator.valueToCode(this, 'KEY', generator.ORDER_ASSIGNMENT);
// var text=this.getFieldValue('KEY');
switch (mode) {
case 'INSERT':
//var at2 = block.getFieldValue('AT2');
var at2 = generator.valueToCode(this, 'AT2', generator.ORDER_ASSIGNMENT) || '0';
var code = dict + "[" + KEY + "] = " + at2 + '\n'
break;
case 'DELETE':
var code = 'del ' + dict + "[" + KEY + "]\n"
break;
default:
throw 'Unhandled option (lists_setIndex2)';
}
return code;
}
export const dicts_pop = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var text = generator.valueToCode(this, 'KEY', generator.ORDER_ASSIGNMENT);
// var text=this.getFieldValue('KEY');
var code = varName + ".pop(" + text + ")";
return [code, generator.ORDER_ATOMIC];
}
export const dicts_setdefault = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || 'mydict';
var text = generator.valueToCode(this, 'KEY', generator.ORDER_ASSIGNMENT);
// var text=this.getFieldValue('KEY');
var argument = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + ".setdefault" + "(" + text + "," + argument + ")\n";
return code;
}
export const dicts_create_with_noreturn = function (_, generator) {
// Create a list with any number of elements of any type.
// var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
// Blockly.Variables.NAME_TYPE);
//var size=window.parseFloat(this.getFieldValue('SIZE'));
var code = new Array(this.itemCount_);
var default_value = '0';
for (var n = 0; n < this.itemCount_; n++) {
var keyName = this.getFieldValue('KEY' + n);
code[n] = keyName + ": " + (generator.valueToCode(this, 'ADD' + n, generator.ORDER_NONE) || default_value);
}
// if (this.itemCount_!=1){
// generator.definitions_['var_declare'+varName] = varName+'= '+ '(' + code.join(', ') + ')\n';}
// else {
// generator.definitions_['var_declare'+varName] = varName+'= '+ '(' + code.join(', ') + ',)\n';}
var code = '{' + code.join(', ') + '}';
return [code, generator.ORDER_ATOMIC];
}
export const dicts_todict = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '0'
return ['dict(' + str + ')', generator.ORDER_ATOMIC];
}
export const dicts_to_json = function (_, generator) {
generator.definitions_['import_json'] = 'import json';
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var code = 'json.dumps(' + varName + ')';
return [code, generator.ORDER_ATOMIC];
}
export const json_to_dicts = function (_, generator) {
generator.definitions_['import_json'] = 'import json';
var varName = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || 'null';
var code = 'json.loads(' + varName + ')';
return [code, generator.ORDER_ATOMIC];
}
export const dicts_to_to = function (_, generator) {
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var R = generator.valueToCode(this, 'VAR1', generator.ORDER_ASSIGNMENT) || 'null';
var I = generator.valueToCode(this, 'VAR2', generator.ORDER_ASSIGNMENT) || 'null';
var L = generator.valueToCode(this, 'VAR3', generator.ORDER_ASSIGNMENT) || 'null';
var N = generator.valueToCode(this, 'VAR4', generator.ORDER_ASSIGNMENT) || 'null';
var code = varName + '['+R+']'+'['+I+']'+'['+L+']'+'['+N+']';
return [code, generator.ORDER_ATOMIC];
}
export const dicts_to_json2 = function (_, generator) {
generator.definitions_['import_json'] = 'import json';
generator.definitions_['import_ujson'] = 'import ujson';
var varName = generator.valueToCode(this, 'DICT', generator.ORDER_ASSIGNMENT) || '0';
var code = 'ujson.loads(' + varName + ')';
return [code, generator.ORDER_ATOMIC];
}

View File

@@ -0,0 +1,70 @@
export const html_document = function (_, generator) {
var head = generator.statementToCode(this, 'HEAD');
var body = generator.statementToCode(this, 'BODY');
var code = "'''<!DOCTYPE HTML>\n<html>\n<head>\n" + '\t<meta charset="utf-8">\n' + head + "</head>\n<body>\n" + body + "</body>\n</html>\n'''";
return [code, generator.ORDER_ATOMIC];
}
export const html_title = function (_, generator) {
var t = generator.statementToCode(this, 'DO');
var l = this.getFieldValue('LEVEL');
var code = "<h" + l + ">\n" + t + "</h" + l + ">\n";
return code;
}
export const html_head_body = function (_, generator) {
var t = generator.statementToCode(this, 'DO');
var l = this.getFieldValue('LEVEL');
if (l == 'head') {
var code = "<" + l + '>\n\t<meta charset="utf-8">\n' + t + "</" + l + ">\n";
}
else {
var code = "<" + l + ">\n" + t + "</" + l + ">\n";
}
return code;
}
export const html_content = function (_, generator) {
var t = generator.statementToCode(this, 'DO');
// var s = generator.valueToCode(this, 'style');
var l = this.getFieldValue('LEVEL');
// var code = "<" + l + " " + s + " >\n" + t + "</" + l + ">\n";
var code = "<" + l + ">\n" + t + "</" + l + ">\n";
return code;
}
export const html_content_more = function (_, generator) {
var t = generator.statementToCode(this, 'DO');
var s = generator.valueToCode(this, 'style');
var l = this.getFieldValue('LEVEL');
var code = "<" + l + " " + s + " >\n" + t + "</" + l + ">\n";
return code;
}
export const html_style = function (_, generator) {
var style = generator.statementToCode(this, 'STYLE');
var code = 'style="' + style + '"';
return [code, generator.ORDER_ATOMIC];
}
export const html_form = function (_, generator) {
var tag = this.getFieldValue('LEVEL');
var name = this.getFieldValue('NAME');
var value = this.getFieldValue('VALUE');
var s = generator.valueToCode(this, 'style') || "";
var code = '<input type="' + tag + '" name="' + name + '" value="' + value + '" ' + s + ' />';
return code;
}
export const html_style_content = function () {
var key = this.getFieldValue('KEY');
var value = this.getFieldValue('VALUE');
var code = key + ':' + value + ";";
return code;
}
export const html_text = function () {
var text = this.getFieldValue('TEXT');
var code = text + "\n";
return code;
}

View File

@@ -0,0 +1,270 @@
import * as Blockly from 'blockly/core';
export const lists_get_sublist = function (_, generator) {
// Get sublist.
var list = generator.valueToCode(this, 'LIST', generator.ORDER_ADDITIVE) || 'mylist';
var at1 = generator.valueToCode(this, 'AT1', generator.ORDER_ADDITIVE);
var at2 = generator.valueToCode(this, 'AT2', generator.ORDER_ADDITIVE);
var code = list + '[' + at1 + ' : ' + at2 + ']';
return [code, generator.ORDER_ATOMIC];
}
export const lists_2d_get_data_with_col_row = function (_, generator) {
var value_LIST = generator.valueToCode(this, 'LIST', generator.ORDER_ATOMIC) || 'mylist';
var value_row = generator.valueToCode(this, 'row', generator.ORDER_ATOMIC) || 0;
var value_col = generator.valueToCode(this, 'col', generator.ORDER_ATOMIC) || 0;
var code = value_LIST + '[' + value_row + ',' + value_col + ']';
return [code, generator.ORDER_ATOMIC];
}
export const lists_2d_get_col_row_data = function (_, generator) {
var value_LIST = generator.valueToCode(this, 'LIST', generator.ORDER_ATOMIC) || 'mylist';
var value_row_start = generator.valueToCode(this, 'row_start', generator.ORDER_ATOMIC) || 0;
var value_row_end = generator.valueToCode(this, 'row_end', generator.ORDER_ATOMIC) || 1;
var value_col_start = generator.valueToCode(this, 'col_start', generator.ORDER_ATOMIC) || 0;
var value_col_end = generator.valueToCode(this, 'col_end', generator.ORDER_ATOMIC) || 1;
var code = value_LIST + '[' + value_row_start + ' : ' + value_row_end + ',' + value_col_start + ' : ' + value_col_end + ']';
return [code, generator.ORDER_ATOMIC];
}
export const lists_create_with = function (_, generator) {
// Create a list with any number of elements of any type.
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
Blockly.Variables.NAME_TYPE);
//var size=window.parseFloat(this.getFieldValue('SIZE'));
var code = new Array(this.itemCount_);
var default_value = '0';
for (var n = 0; n < this.itemCount_; n++) {
code[n] = generator.valueToCode(this, 'ADD' + n,
generator.ORDER_NONE) || default_value;
}
//generator.setups_['var_declare'+varName] = varName+' = '+ '[' + code.join(', ') + ']\n';
var code = varName + ' = ' + '[' + code.join(', ') + ']\n';
return code;
}
export const lists_create_with_text = function (_, generator) {
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
Blockly.Variables.NAME_TYPE);
//var size=window.parseFloat(this.getFieldValue('SIZE'));
var text = this.getFieldValue('TEXT');
// generator.setups_['var_declare'+varName] = varName+' = '+ '[' + text + ']\n';
var code = varName + ' = ' + '[' + text + ']\n';
return code;
}
export const lists_get_index = function (_, generator) {
// Indexing into a list is the same as indexing into a string.
var list = generator.valueToCode(this, 'LIST', generator.ORDER_ADDITIVE) || 'mylist';
var argument0 = generator.valueToCode(this, 'AT', generator.ORDER_ADDITIVE) || 0;
var code = list + '[' + argument0 + ']';
return [code, generator.ORDER_ATOMIC];
}
export const lists_set_index = function (_, generator) {
// Set element at index.
var varName = generator.valueToCode(this, 'LIST', generator.ORDER_ADDITIVE) || 'mylist';
var argument0 = generator.valueToCode(this, 'AT',
generator.ORDER_ADDITIVE) || '0';
var argument2 = generator.valueToCode(this, 'TO',
generator.ORDER_ASSIGNMENT) || '0';
// Blockly uses one-based indicies.
return varName + '[' + argument0 + '] = ' + argument2 + '\n';
}
export const lists_append_extend = function (_, generator) {
var varName = generator.valueToCode(this, 'LIST', generator.ORDER_ASSIGNMENT) || '0';
var argument = generator.valueToCode(this, 'DATA', generator.ORDER_ASSIGNMENT) || '0';
var op = this.getFieldValue('OP');
var code = varName + '.' + op + '(' + argument + ')\n';
return code;
}
export const lists_get_random_item = function (_, generator) {
generator.definitions_['import_random'] = 'import random';
var varName = generator.valueToCode(this, 'LIST', generator.ORDER_ADDITIVE) || 'mylist';
var code = 'random.choice(' + varName + ')';
return [code, generator.ORDER_ATOMIC];
}
export const lists_get_random_sublist = function (_, generator) {
generator.definitions_['import_random'] = 'import random';
var varName = generator.valueToCode(this, 'LIST', generator.ORDER_ADDITIVE) || 'mylist';
var VALUE = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
var code = 'random.sample(' + varName + ',' + VALUE + ')';
return [code, generator.ORDER_ATOMIC];
}
export const lists_insert_value = function (_, generator) {
var varName = generator.valueToCode(this, 'LIST', generator.ORDER_ASSIGNMENT) || '0';
var at = generator.valueToCode(this, 'AT', generator.ORDER_ADDITIVE) || '0';
var VALUE = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.insert(' + at + ', ' + VALUE + ')\n';
return code;
}
export const lists_reverse = function (_, generator) {
var varName = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.reverse()\n';
return code;
}
export const lists_clear = function (_, generator) {
var varName = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.clear()\n';
return code;
}
export const lists_find = function (_, generator) {
var op = this.getFieldValue('OP');
var varName = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
var argument = generator.valueToCode(this, 'data', generator.ORDER_ASSIGNMENT) || '0';
if (op == 'INDEX')
var code = varName + '.index(' + argument + ')';
else if (op == 'COUNT')
var code = varName + '.count(' + argument + ')';
return [code, generator.ORDER_ATOMIC];
}
export const lists_remove_at = function (_, generator) {
var varName = generator.valueToCode(this, 'LIST', generator.ORDER_ASSIGNMENT) || '0';
var argument = generator.valueToCode(this, 'DATA', generator.ORDER_ASSIGNMENT) || '0';
var op = this.getFieldValue('OP');
var code = "";
if (op == "del") {
code = 'del ' + varName + '[' + argument + ']\n';
} else {
code = varName + '.remove' + '(' + argument + ')\n';
}
return code;
}
export const lists_pop = function (_, generator) {
var varName = generator.valueToCode(this, 'LIST', generator.ORDER_ADDITIVE) || 'mylist';
var argument = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.pop(' + argument + ')';
return [code, generator.ORDER_ATOMIC];
}
export const list_trig = function (a, generator) {
var b = a.getFieldValue("OP"), c;
generator.definitions_['import_math'] = "import math";
a = generator.valueToCode(a, 'data', generator.ORDER_NONE)
switch (b) {
case "LEN":
c = "len(" + a + ")";
break;
case "SUM":
c = "sum(" + a + ")";
break;
case "MIN":
c = "min(" + a + ")";
break;
case "MAX":
c = "max(" + a + ")";
break;
case 'AVERAGE':
generator.definitions_['import_mixpy_math_mean'] = "from mixpy import math_mean";
c = 'math_mean(' + a + ')';
break;
case 'MEDIAN':
generator.definitions_['import_mixpy_math_median'] = "from mixpy import math_median";
c = 'math_median(' + a + ')';
break;
case 'MODE':
generator.definitions_['import_mixpy_math_modes'] = "from mixpy import math_modes";
c = 'math_modes(' + a + ')';
break;
case 'STD_DEV':
generator.definitions_['import_mixpy_math_standard_deviation'] = "from mixpy import math_standard_deviation";
c = 'math_standard_deviation(' + a + ')';
break;
default:
throw 'Unknown operator: ' + b;
}
if (c)
return [c, generator.ORDER_ATOMIC];
}
export const lists_sort = function (block, generator) {
// Block for sorting a list.
generator.definitions_['import_mixpy_lists_sort'] = "from mixpy import lists_sort";
var list = (generator.valueToCode(block, 'LIST',
generator.ORDER_NONE) || '[]');
var type = block.getFieldValue('TYPE');
var reverse = block.getFieldValue('DIRECTION') === '1' ? 'False' : 'True';
var code = 'lists_sort(' + list + ', "' + type + '", ' + reverse + ')';
return [code, generator.ORDER_ATOMIC];
}
export const lists_change_to = function (_, generator) {
var op = this.getFieldValue('OP');
var varName = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
var code = '';
if (op == 'array') {
generator.definitions_['import_numpy'] = 'import numpy';
code = 'numpy.array(' + varName + ')';
}
else {
code = op + '(' + varName + ')';
}
return [code, generator.ORDER_ATOMIC];
}
export const list_many_input = function (_, generator) {
var text = this.getFieldValue('CONTENT');
var code = '[' + text + ']'
return [code, generator.ORDER_ATOMIC];
}
export const lists_create_with_noreturn = function (_, generator) {
// Create a list with any number of elements of any type.
var code = new Array(this.itemCount_);
var default_value = '0';
for (var n = 0; n < this.itemCount_; n++) {
code[n] = generator.valueToCode(this, 'ADD' + n,
generator.ORDER_NONE) || default_value;
}
var code = '[' + code.join(', ') + ']';
return [code, generator.ORDER_ATOMIC];
}
export const lists_change_to_general = lists_change_to;
export const lists_del_general = function (_, generator) {
var varName = generator.valueToCode(this, 'TUP', generator.ORDER_ASSIGNMENT) || '0';
var code = 'del ' + varName + '\n';
return code;
}
export const lists_create_with2 = lists_create_with
export const lists_create_with_text2 = lists_create_with_text
export const lists_getIndex3 = lists_get_index
export const lists_getSublist3 = lists_get_sublist
export const lists_setIndex3 = lists_set_index
export const lists_insert_value2 = lists_insert_value
export const lists_remove_at2 = lists_remove_at
export const list_tolist = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '0'
return ['list(' + str + ')', generator.ORDER_ATOMIC];
}
export const list_tolist2 = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '0'
return [str + '.tolist()', generator.ORDER_ATOMIC];
}
export const enumerate = function (_, generator) {
var varName = generator.valueToCode(this, 'LIST', generator.ORDER_ADDITIVE) || 'mylist';
var argument = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '0';
var code = 'enumerate(' +varName+',start='+ argument + ')';
return [code, generator.ORDER_ATOMIC];
}
export const content_in_lists = function (_, generator) {
var varName = generator.valueToCode(this, 'LIST', generator.ORDER_ADDITIVE) || 'mylist';
var con = generator.valueToCode(this, 'CON', generator.ORDER_ASSIGNMENT) || '0';
var code = con +' in '+varName;
return [code, generator.ORDER_ATOMIC];
}

View File

@@ -0,0 +1,102 @@
export const logic_compare = function (_, generator) {
// Comparison operator.
var mode = this.getFieldValue('OP');
var operator = logic_compare.OPERATORS[mode];
var order = (operator == '==' || operator == '!=') ?
generator.ORDER_EQUALITY : generator.ORDER_RELATIONAL;
var argument0 = generator.valueToCode(this, 'A', order) || '0';
var argument1 = generator.valueToCode(this, 'B', order) || '0';
var code = argument0 + ' ' + operator + ' ' + argument1;
return [code, order];
}
export const logic_compare_continous = function (_, generator) {
// Comparison operator.
var mode1 = this.getFieldValue('OP1');
var operator1 = logic_compare.OPERATORS[mode1];
var mode2 = this.getFieldValue('OP2');
var operator2 = logic_compare.OPERATORS[mode2];
var argument0 = generator.valueToCode(this, 'A', generator.ORDER_RELATIONAL) || '0';
var argument1 = generator.valueToCode(this, 'B', generator.ORDER_RELATIONAL) || '0';
var argument2 = generator.valueToCode(this, 'C', generator.ORDER_RELATIONAL) || '0';
var code = argument0 + ' ' + operator1 + ' ' + argument1 + ' ' + operator2 + ' ' + argument2;
return [code, generator.ORDER_RELATIONAL];
}
logic_compare.OPERATORS = {
EQ: '==',
NEQ: '!=',
LT: '<',
LTE: '<=',
GT: '>',
GTE: '>='
};
export const logic_operation = function (_, generator) {
// Operations 'and', 'or'.
var operator = this.getFieldValue('OP');
var order = (operator == '&&') ? generator.ORDER_LOGICAL_AND :
generator.ORDER_LOGICAL_OR;
var argument0 = generator.valueToCode(this, 'A', order) || 'False';
var argument1 = generator.valueToCode(this, 'B', order) || 'False';
if (operator == 'AND') {
var code = argument0 + ' and ' + argument1;
} else if (operator == 'OR') {
var code = argument0 + ' or ' + argument1;
} else if (operator == 'NOR') {
// var code = '('+argument0+' and '+argument1+' ) or ((not '+argument0+') and (not '+argument1+'))';
var code = 'not(' + argument0 + '^' + argument1 + ')';
} else {
// var code = '((not '+argument0+') and '+argument1+' ) or ( '+argument0+' and (not '+argument1+'))';
var code = argument0 + '^' + argument1;
}
return [code, order];
}
export const logic_negate = function (_, generator) {
// Negation.
var order = generator.ORDER_UNARY_PREFIX;
var argument0 = generator.valueToCode(this, 'BOOL', order) || 'False';
var code = 'not ' + argument0;
return [code, order];
}
export const logic_boolean = function (_, generator) {
// Boolean values true and false.
var code = (this.getFieldValue('BOOL') == 'TRUE') ? 'True' : 'False';
return [code, generator.ORDER_ATOMIC];
}
export const logic_null = function (_, generator) {
var code = 'None';
return [code, generator.ORDER_ATOMIC];
}
export const logic_true_or_false = function (_, generator) {
var a = generator.valueToCode(this, 'A', generator.ORDER_ATOMIC) || 'False';
var b = generator.valueToCode(this, 'B', generator.ORDER_ATOMIC) || 'False';
var c = generator.valueToCode(this, 'C', generator.ORDER_ATOMIC) || 'False';
var code = '(' + b + ' if ' + a + ' else ' + c + ')';
return [code, generator.ORDER_ATOMIC];
}
export const logic_is_in = function (_, generator) {
var a = generator.valueToCode(this, 'A', generator.ORDER_ATOMIC) || '\'\'';
var b = generator.valueToCode(this, 'B', generator.ORDER_ATOMIC) || '\'\'';
var bool = this.getFieldValue('BOOL');
var code = a + ' ' + bool + ' ' + b;
return [code, generator.ORDER_ATOMIC];
}
export const logic_is = function (_, generator) {
var a = generator.valueToCode(this, 'A', generator.ORDER_ATOMIC) || '\'\'';
var b = generator.valueToCode(this, 'B', generator.ORDER_ATOMIC) || '\'\'';
var bool = this.getFieldValue('BOOL');
var code = a + ' ' + bool + ' ' + b;
return [code, generator.ORDER_ATOMIC];
}
export const logic_tobool = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '0'
return ['bool(' + str + ')', generator.ORDER_ATOMIC];
}

View File

@@ -0,0 +1,338 @@
// export const math_number = function() {
// // Numeric value.
// var code = (this.getFieldValue('NUM'));
// // -4.abs() returns -4 in Dart due to strange order of operation choices.
// // -4 is actually an operator and a number. Reflect this in the order.
// var order = code < 0 ?
// generator.ORDER_UNARY_PREFIX : generator.ORDER_ATOMIC;
// return [code, order];
// }
// generator.math = {}
// generator.addReservedWords("math,random,Number");
export const math_number = function (_, generator) {
// a = parseFloat(a.getFieldValue("NUM"));
// var b;
// Infinity == a ? (a = 'float("inf")', b = generator.ORDER_FUNCTION_CALL) : -Infinity == a ? (a = '-float("inf")', b = generator.ORDER_UNARY_SIGN) : b = 0 > a ? generator.ORDER_UNARY_SIGN : generator.ORDER_ATOMIC;
// return [a, b]
var code = this.getFieldValue('NUM');
// -4.abs() returns -4 in Dart due to strange order of operation choices.
// -4 is actually an operator and a number. Reflect this in the order.
var order = code < 0 ?
generator.ORDER_UNARY_PREFIX : generator.ORDER_ATOMIC;
return [code, order];
}
export const math_constant = function (_, generator) {
generator.definitions_.import_math = "import math";
var name = this.getFieldValue('CONSTANT');
var code = 'math.' + name;
return [code, generator.ORDER_ATOMIC];
}
export const math_constant_mp = function (_, generator) {
generator.definitions_.import_math = "import math";
var name = this.getFieldValue('CONSTANT');
var code = 'math.' + name;
return [code, generator.ORDER_ATOMIC];
}
export const math_bit = function (_, generator) {
var operator = this.getFieldValue('OP');
var order = generator.ORDER_ATOMIC;
var argument0 = generator.valueToCode(this, 'A', order) || '0';
var argument1 = generator.valueToCode(this, 'B', order) || '0';
var code = '(' + argument0 + operator + argument1 + ')';
return [code, order];
}
export const math_arithmetic = function (a, generator) {
var b = {
ADD: [" + ", generator.ORDER_ADDITIVE],
MINUS: [" - ", generator.ORDER_ADDITIVE],
MULTIPLY: [" * ", generator.ORDER_MULTIPLICATIVE],
DIVIDE: [" / ", generator.ORDER_MULTIPLICATIVE],
QUYU: [' % ', generator.ORDER_MULTIPLICATIVE],//增加取余操作
ZHENGCHU: [' // ', generator.ORDER_MULTIPLICATIVE],//增加整除操作
POWER: [" ** ", generator.ORDER_EXPONENTIATION]
}[a.getFieldValue("OP")];
var c = b[0],
b = b[1],
d = generator.valueToCode(a, "A", b) || "0";
a = generator.valueToCode(a, "B", b) || "0";
return [d + c + a, b]
}
export const math_selfcalcu = function (_, generator) {
var argument0 = generator.valueToCode(this, 'A', generator.ORDER_RELATIONAL) || '0';
var argument1 = generator.valueToCode(this, 'B', generator.ORDER_RELATIONAL) || '0';
var operator = this.getFieldValue('OP');
switch (operator) {
case 'ADD': var op = '+='; break;
case 'MINUS': var op = '-='; break;
case 'MULTIPLY': var op = '*='; break;
case 'DIVIDE': var op = '/='; break;
case 'QUYU': var op = '%='; break;
case 'ZHENGCHU': var op = '//='; break;
case 'POWER': var op = '**='; break;
}
var code = argument0 + ' ' + op + ' ' + argument1 + '\n';
return code;
}
export const math_single = function (a, generator) {
var b = a.getFieldValue("OP"),
c;
if ("NEG" == b)
return c = generator.valueToCode(a, "NUM", generator.ORDER_UNARY_SIGN) || "0", ["-" + c, generator.ORDER_UNARY_SIGN];
generator.definitions_['import_math'] = "import math";
a = "SIN" == b || "COS" == b || "TAN" == b ? generator.valueToCode(a, "NUM", generator.ORDER_MULTIPLICATIVE) || "0" : generator.valueToCode(a, "NUM", generator.ORDER_NONE) || "0";
switch (b) {
case "ABS":
c = "math.fabs(" + a + ")";
break;
case "ROOT":
c = "math.sqrt(" +
a + ")";
break;
case "LN":
c = "math.log(" + a + ")";
break;
case "LOG10":
c = "math.log10(" + a + ")";
break;
case "EXP":
c = "math.exp(" + a + ")";
break;
case "POW10":
c = "math.pow(10," + a + ")";
break;
case "ROUND":
c = "round(" + a + ")";
break;
case "ROUNDUP":
c = "math.ceil(" + a + ")";
break;
case "ROUNDDOWN":
c = "math.floor(" + a + ")";
break;
case "SIN":
c = "math.sin(" + a + ")";
break;
case "COS":
c = "math.cos(" + a + ")";
break;
case "TAN":
c = "math.tan(" + a + ")";
break;
case "++":
c = "++(" + a + ")";
break;
case "--":
c = "--(" + a + ")";
break;
case "-":
c = "-(" + a + ")";
break;
default:
}
if (c)
return [c, generator.ORDER_EXPONENTIATION];
switch (b) {
case "ASIN":
c = "math.degrees(math.asin(" + a + "))";
break;
case "ACOS":
c = "math.degrees(math.acos(" + a + "))";
break;
case "ATAN":
c = "math.degrees(math.atan(" + a + "))";
break;
}
return [c, generator.ORDER_MULTIPLICATIVE]
}
export const math_trig = math_single;
export const math_dec = function (_, generator) {
var argument0 = generator.valueToCode(this, 'NUM', generator.ORDER_NONE) || '0';
var operator = this.getFieldValue('OP');
var code = operator + '(' + argument0 + ')';
return [code, generator.ORDER_ATOMIC];
}
export const math_to_int = function (_, generator) {
var argument0 = generator.valueToCode(this, 'A', generator.ORDER_NONE) || '0';
var operator = this.getFieldValue('OP');
var code = "";
if (operator === "round") {
code = operator + '(' + argument0 + ')';
} else {
code = "math." + operator + '(' + argument0 + ')';
generator.definitions_.import_math = "import math";
}
return [code, generator.ORDER_ATOMIC];
}
export const math_max_min = function (_, generator) {
var a = generator.valueToCode(this, 'A', generator.ORDER_NONE) || '0';
var b = generator.valueToCode(this, 'B', generator.ORDER_NONE) || '0';
var operator = this.getFieldValue('OP');
var code = operator + '(' + a + ', ' + b + ')';
return [code, generator.ORDER_ATOMIC];
}
export const math_random = function (_, generator) {
generator.definitions_.import_random = "import random";
// Random integer between [X] and [Y].
var type = this.getFieldValue('TYPE');
var argument0 = generator.valueToCode(this, 'FROM',
generator.ORDER_NONE) || '0';
var argument1 = generator.valueToCode(this, 'TO',
generator.ORDER_NONE) || '0';
if (type == 'int') {
var code = 'random.randint(' + argument0 + ', ' + argument1 + ')';
} else if (type == 'float') {
var code = 'random.uniform(' + argument0 + ', ' + argument1 + ')';
}
return [code, generator.ORDER_UNARY_POSTFIX];
}
export const math_map = function (_, generator) {
var value_num = generator.valueToCode(this, 'NUM', generator.ORDER_NONE);
var value_fl = generator.valueToCode(this, 'fromLow', generator.ORDER_ATOMIC);
var value_fh = generator.valueToCode(this, 'fromHigh', generator.ORDER_ATOMIC);
var value_tl = generator.valueToCode(this, 'toLow', generator.ORDER_ATOMIC);
var value_th = generator.valueToCode(this, 'toHigh', generator.ORDER_ATOMIC);
generator.definitions_['import_mixpy_math_map'] = "from mixpy import math_map";
var code = 'math_map(' + value_num + ', ' + value_fl + ', ' + value_fh + ', ' + value_tl + ', ' + value_th + ')';
return [code, generator.ORDER_NONE];
}
export const math_constrain = function (_, generator) {
// Constrain a number between two limits.
var argument0 = generator.valueToCode(this, 'VALUE',
generator.ORDER_NONE) || '0';
var argument1 = generator.valueToCode(this, 'LOW',
generator.ORDER_NONE) || '0';
var argument2 = generator.valueToCode(this, 'HIGH',
generator.ORDER_NONE) || '0';
var code = 'min(max(' + argument0 + ', ' + argument1 + '), ' + argument2 + ')';
return [code, generator.ORDER_UNARY_POSTFIX];
}
export const math_number_base_conversion = function (a, generator) {
var c1 = a.getFieldValue("OP");
var d = generator.valueToCode(this, 'NUM', generator.ORDER_NONE) || '0';
var c2 = a.getFieldValue("OP2");
generator.definitions_['import_math'] = "import math";
var param1 = "";
var param2 = "10";
if (c1 == "two") {
param2 = '2';
} else if (c1 == "eight") {
param2 = '8'
} else if (c1 == "ten") {
param2 = '10'
} else if (c1 == "sixteen") {
param2 = '16'
}
if (c2 == "two") {
param1 = 'bin';
} else if (c2 == "eight") {
param1 = 'oct'
} else if (c2 == "ten") {
param1 = ''
} else if (c2 == "sixteen") {
param1 = 'hex'
}
if (param1 == "") {
var code = "int(str(" + d + "), " + param2 + ")";
} else {
var code = param1 + "(int(str(" + d + "), " + param2 + "))";
}
return [code, generator.ORDER_ATOMIC];
}
export const math_random_seed = function (_, generator) {
// Random integer between [X] and [Y].
generator.definitions_.import_random = "import random";
var a = generator.valueToCode(this, 'NUM', generator.ORDER_NONE) || '0';
var code = 'random.seed(' + a + ');' + '\n';
return code;
}
export const math_indexer_number = function (_, generator) {
var code = this.getFieldValue('NUM');
// -4.abs() returns -4 in Dart due to strange order of operation choices.
// -4 is actually an operator and a number. Reflect this in the order.
var order = code < 0 ?
generator.ORDER_UNARY_PREFIX : generator.ORDER_ATOMIC;
return [code, order];
}
export const math_round = function (_, generator) {
var argument0 = generator.valueToCode(this, 'VALUE',
generator.ORDER_NONE) || '0';
var argument1 = generator.valueToCode(this, 'VAR',
generator.ORDER_NONE) || '0';
var code = 'round(' + argument0 + ', ' + argument1 + ')';
return [code, generator.ORDER_ATOMIC];
}
export const text_to_number = function (_, generator) {
var towhat = this.getFieldValue('TOWHAT');
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
if (towhat == 'b') return ['' + str + '.encode("utf-8")', generator.ORDER_ATOMIC];
else if (towhat == 'bti') return ['int.from_bytes(' + str + ',"big")', generator.ORDER_ATOMIC];
return [towhat + "(" + str + ')', generator.ORDER_ATOMIC];
}
export const text_to_number_skulpt = function (_, generator) {
var towhat = this.getFieldValue('TOWHAT');
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
if (towhat == 'b') return ['' + str + '.encode("utf-8")', generator.ORDER_ATOMIC];
return [towhat + "(" + str + ')', generator.ORDER_ATOMIC];
}
export const base_map = math_map;
export const turn_to_int = function (_, generator) {
generator.definitions_.import_hexlify = "from ubinascii import hexlify";
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
return ["hexlify(" + str + ').decode()', generator.ORDER_ATOMIC];
}
export const generate_cartesian_product = function (_, generator) {
generator.definitions_.import_itertools = 'import itertools';
let re = generator.valueToCode(this, 'REPEAT', generator.ORDER_ATOMIC);
let items = new Array(this.itemCount_);
for (let n = 0; n < this.itemCount_; n++) {
items[n] = generator.valueToCode(this, `ADD${n}`, generator.ORDER_NONE) || '0';
}
let code = '';
if (this.itemCount_) {
code = `itertools.product(${items.join(', ')}, repeat=${re})`;
}
return [code, generator.ORDER_ATOMIC];
}
export const math_radian_to_degree = function (_, generator) {
generator.definitions_.import_math = "import math";
var v = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var code = 'math.degrees('+ v + ')';
return [code, generator.ORDER_ATOMIC];
}
export const math_degree_to_radian = function (_, generator) {
generator.definitions_.import_math = "import math";
var v = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var code = 'math.radians('+ v + ')';
return [code, generator.ORDER_ATOMIC];
}

View File

@@ -0,0 +1,107 @@
import * as Blockly from 'blockly/core';
export const procedures_defreturn = function (_, generator) {
// Define a procedure with a return value.
var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
Blockly.Procedures.NAME_TYPE);
var branch = (this.getInput('STACK') && generator.statementToCode(this, 'STACK')) ?? ' pass\n';
if (generator.INFINITE_LOOP_TRAP) {
branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
'\'' + this.id + '\'') + branch;
}
var returnValue = generator.valueToCode(this, 'RETURN',
generator.ORDER_NONE) || '';
//var type=this.getFieldValue('TYPE');
if (returnValue) {
returnValue = ' return ' + returnValue + '\n';
}
//var returnType = returnValue ? type : 'void';
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
var varName = generator.variableDB_.getName(this.arguments_[x], Blockly.Variables.NAME_TYPE);
args[x] = varName;
}
var code = 'def ' + funcName + '(' + args.join(', ') + '):\n' +
branch + returnValue + '\n';
code = generator.scrub_(this, code);
generator.setups_[funcName] = code;
return null;
}
export const procedures_defnoreturn = function (_, generator) {
// Define a procedure with a return value.
var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
Blockly.Procedures.NAME_TYPE);
var branch = (this.getInput('STACK') && generator.statementToCode(this, 'STACK')) ?? ' pass\n';
if (generator.INFINITE_LOOP_TRAP) {
branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
'\'' + this.id + '\'') + branch;
}
//var returnType = returnValue ? type : 'void';
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
var varName = generator.variableDB_.getName(this.arguments_[x], Blockly.Variables.NAME_TYPE);
args[x] = varName;
}
var code = 'def ' + funcName + '(' + args.join(', ') + '):\n' +
branch + '\n';
code = generator.scrub_(this, code);
generator.setups_[funcName] = code;
return null;
}
export const procedures_callreturn = function (_, generator) {
// Call a procedure with a return value.
var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
Blockly.Procedures.NAME_TYPE);
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
args[x] = generator.valueToCode(this, 'ARG' + x,
generator.ORDER_NONE) || 'null';
}
var code = funcName + '(' + args.join(', ') + ')';
return [code, generator.ORDER_UNARY_POSTFIX];
}
export const procedures_callnoreturn = function (_, generator) {
// Call a procedure with no return value.
var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
Blockly.Procedures.NAME_TYPE);
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
args[x] = generator.valueToCode(this, 'ARG' + x,
generator.ORDER_NONE) || 'null';
}
var code = funcName + '(' + args.join(', ') + ')\n';
return code;
}
export const procedures_ifreturn = function (_, generator) {
// Conditionally return value from a procedure.
var condition = generator.valueToCode(this, 'CONDITION',
generator.ORDER_NONE) || 'False';
var code = 'if (' + condition + ') :\n';
if (this.hasReturnValue_) {
var value = generator.valueToCode(this, 'VALUE',
generator.ORDER_NONE) || 'None';
code += ' return ' + value;
} else {
code += ' return None';
}
code += '\n';
return code;
}
export const procedures_return = function (_, generator) {
// Conditionally return value from a procedure.
var code = ""
if (this.hasReturnValue_) {
var value = generator.valueToCode(this, 'VALUE',
generator.ORDER_NONE) || 'None';
code += 'return ' + value;
} else {
code += 'return None';
}
code += '\n';
return code;
}

View File

@@ -0,0 +1,95 @@
import * as Blockly from 'blockly/core';
export const set_create_with = function (_, generator) {
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
Blockly.Variables.NAME_TYPE);
var code = new Array(this.itemCount_);
var default_value = '0';
for (var n = 0; n < this.itemCount_; n++) {
code[n] = generator.valueToCode(this, 'ADD' + n,
generator.ORDER_NONE) || default_value;
}
//generator.definitions_['var_declare'+varName] = varName+'= '+ '{' + code.join(', ') + '}\n';
code = varName + '= ' + '{' + code.join(', ') + '}\n';
if (this.itemCount_ == 0) { code = varName + ' = ' + 'set()\n' }
return code;
}
export const set_length = function (_, generator) {
var varName = generator.valueToCode(this, 'SET', generator.ORDER_ASSIGNMENT) || '0';
var code = 'len(' + varName + ')';
return [code, generator.ORDER_ATOMIC];
}
export const set_pop = function (_, generator) {
var varName = generator.valueToCode(this, 'SET', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.pop()';
return [code, generator.ORDER_ATOMIC];
}
export const set_clear = function (_, generator) {
var varName = generator.valueToCode(this, 'SET', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + '.clear()\n';
return code;
}
export const set_operate = function (_, generator) {
var vars1 = generator.valueToCode(this, 'SET1', generator.ORDER_ASSIGNMENT) || '0';
var vars2 = generator.valueToCode(this, 'SET2', generator.ORDER_ASSIGNMENT) || '0';
var operate = this.getFieldValue('OPERATE');
//var num = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var code = vars1 + "." + operate + "(" + vars2 + ')';
return [code, generator.ORDER_ATOMIC];
}
export const set_operate_update = function (_, generator) {
var vars1 = generator.valueToCode(this, 'SET1', generator.ORDER_ASSIGNMENT) || '0';
var vars2 = generator.valueToCode(this, 'SET2', generator.ORDER_ASSIGNMENT) || '0';
var operate = this.getFieldValue('OPERATE');
//var num = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var code = vars1 + "." + operate + "(" + vars2 + ')\n';
return code;
}
export const set_add_discard = function (_, generator) {
var vars1 = generator.valueToCode(this, 'SET', generator.ORDER_ASSIGNMENT) || '0';
var operate = this.getFieldValue('OPERATE');
var argument = generator.valueToCode(this, 'data', generator.ORDER_ASSIGNMENT) || '0';
var code = vars1 + "." + operate + "(" + argument + ')\n';
return code;
}
export const set_sub = function (_, generator) {
var vars1 = generator.valueToCode(this, 'SET1', generator.ORDER_ASSIGNMENT) || '0';
var vars2 = generator.valueToCode(this, 'SET2', generator.ORDER_ASSIGNMENT) || '0';
var operate = this.getFieldValue('OPERATE');
//var num = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var code = vars1 + "." + operate + "(" + vars2 + ')';
return [code, generator.ORDER_ATOMIC];
}
export const set_update = function (_, generator) {
var varName = generator.valueToCode(this, 'SET', generator.ORDER_ASSIGNMENT) || '0';
var color = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
//var color = generator.valueToCode(this, 'data', generator.ORDER_ASSIGNMENT) || '0';
var code = varName + "." + 'update' + '(' + color + ')\n';
return code;
}
// export const set_change_to = function(){
// var op = this.getFieldValue('OP');
// var varName = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
// var code = op + '(' + varName + ')\n';
// return [code, generator.ORDER_ATOMIC];
// }
export const set_create_with_text_return = function (_, generator) {
var text = this.getFieldValue('TEXT');
var code = '{' + text + '}';
return [code, generator.ORDER_ATOMIC];
}
export const set_toset = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '0'
return ['set(' + str + ')', generator.ORDER_ATOMIC];
}

View File

@@ -0,0 +1,175 @@
export const storage_open_file_with_os = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
var fn = generator.valueToCode(this, 'fn', generator.ORDER_ATOMIC);
return "os.startfile(" + fn + ")\n";
}
export const storage_fileopen = function (_, generator) {
// For each loop.
var variable0 = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var fn = generator.valueToCode(this, 'FILENAME', generator.ORDER_ATOMIC);
var mode = this.getFieldValue('MODE');
var code = variable0 + ' = open(' + fn + ', \'' + mode + '\')\n';
return code;
}
export const storage_fileopen_new = function (_, generator) { // For each loop.
var fn = generator.valueToCode(this, 'FILENAME', generator.ORDER_ATOMIC);
var mode = this.getFieldValue('MODE');
var code = 'open(' + fn + ', \'' + mode + '\')';
return [code, generator.ORDER_ATOMIC];
}
export const storage_fileopen_new_encoding = function (_, generator) { // For each loop.
var fn = generator.valueToCode(this, 'FILENAME', generator.ORDER_ATOMIC);
var mode = this.getFieldValue('MODE');
var encode = this.getFieldValue('CODE');
var code = 'open(' + fn + ', \'' + mode + '\', encoding="' + encode + '")';
return [code, generator.ORDER_ATOMIC];
}
export const storage_file_write = function (_, generator) {
var data = generator.valueToCode(this, 'data', generator.ORDER_ATOMIC);
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
return file + ".write(" + data + ")\n";
}
export const storage_get_contents_without_para = function (_, generator) {
var mode = this.getFieldValue('MODE');
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var code = file + '.' + mode + '()';
return [code, generator.ORDER_ATOMIC];
}
export const storage_get_contents = function (_, generator) {
var mode = this.getFieldValue('MODE');
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var size = generator.valueToCode(this, 'SIZE', generator.ORDER_ATOMIC);
var code = file + '.' + mode + '(' + size + ')';
return [code, generator.ORDER_ATOMIC];
}
export const storage_get_a_line = function (_, generator) {
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var size = generator.valueToCode(this, 'SIZE', generator.ORDER_ATOMIC);
var code = file + ".readline(" + size + ')';
return [code, generator.ORDER_ATOMIC];
}
export const storage_can_write_ornot = function (_, generator) {
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var code = file + ".writable()";
return [code, generator.ORDER_ATOMIC];
}
export const storage_get_filename = function (_, generator) {
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var code = file + ".name()";
return [code, generator.ORDER_ATOMIC];
}
export const storage_close_file = function (_, generator) {
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var code = file + ".close()\n";
return code;
}
export const storage_list_all_files = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
var code = 'os.listdir()';
return [code, generator.ORDER_ATOMIC];
}
export const storage_delete_file = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
var mode = this.getFieldValue('MODE');
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var code = "os." + mode + "(" + file + ")\n";
return code;
}
export const storage_get_file_size = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var code = "os.path.getsize(" + file + ")";
return [code, generator.ORDER_ATOMIC];
}
export const storage_file_tell = function (_, generator) {
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var code = file + ".tell()";
return [code, generator.ORDER_ATOMIC];
}
export const storage_file_seek = function (_, generator) {
var mode = this.getFieldValue('MODE');
var mode_num = 0;
if (mode == 'start') {
mode_num = 0;
}
else if (mode == 'current') {
mode_num = 1;
}
else {
mode_num = 2;
}
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var size = generator.valueToCode(this, 'SIZE', generator.ORDER_ATOMIC);
var code = file + '.seek(' + size + ',' + mode_num + ')\n';
return code;
}
export const storage_change_dir = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var code = "os.chdir(" + file + ")\n";
return code;
}
export const storage_get_current_dir = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
var code = 'os.getcwd()';
return [code, generator.ORDER_ATOMIC];
}
export const storage_make_dir = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
var mode = this.getFieldValue('MODE');
var path = generator.valueToCode(this, 'PATH', generator.ORDER_ATOMIC);
var code = 'os.' + mode + '(' + path + ')\n';
return code;
}
export const storage_rename = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var file1 = generator.valueToCode(this, 'NEWFILE', generator.ORDER_ATOMIC);
var code = "os.rename(" + file + "," + file1 + ")\n";
return code;
}
export const storage_is_file = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
var file = generator.valueToCode(this, 'FILE', generator.ORDER_ATOMIC);
var mode = this.getFieldValue('MODE');
var code = "os." + mode + "(" + file + ")";
return [code, generator.ORDER_ATOMIC];
}
export const sdcard_use_spi_init = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
generator.definitions_['import_sdcard'] = 'import sdcard';
var v = generator.valueToCode(this, 'SUB', generator.ORDER_ATOMIC);
var sv = generator.valueToCode(this, 'SPISUB', generator.ORDER_ATOMIC);
var pv = generator.valueToCode(this, 'PINSUB', generator.ORDER_ATOMIC);
var code = v + ' = sdcard.SDCard(' + sv + ',' + pv + ')\n';
return code;
}
export const sdcard_mount = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
generator.definitions_['import_sdcard'] = 'import sdcard';
var sd = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var dir = generator.valueToCode(this, 'DIR', generator.ORDER_ATOMIC);
return "os.mount(" + sd + ',' + dir + ")\n";
}

View File

@@ -0,0 +1,250 @@
import * as Blockly from 'blockly/core';
export const text = function (_, generator) {
// Text value.
//var code = 'String('+generator.quote_(this.getFieldValue('TEXT'))+')';
var code = generator.quote_(this.getFieldValue('TEXT'));
return [code, generator.ORDER_ATOMIC];
}
export const text_textarea = function (_, generator) {
// Text value.
//var code = 'String('+generator.quote_(this.getFieldValue('TEXT'))+')';
var code = '"""' + (this.getFieldValue('VALUE')) + '"""';
return [code, generator.ORDER_ATOMIC];
}
export const text_bytes = function (_, generator) {
const text = this.getFieldValue('TEXT');
return [`b'${text}'`, generator.ORDER_ATOMIC];
}
export const text_char = function (_, generator) {
var code = '\'' + this.getFieldValue('TEXT') + '\'';
return [code, generator.ORDER_ATOMIC];
}
export const text_join = function (_, generator) {
// Text value.
var a = generator.valueToCode(this, 'A', generator.ORDER_ATOMIC);
var b = generator.valueToCode(this, 'B', generator.ORDER_ATOMIC);
return [a + ' + ' + b, generator.ORDER_ADDITIVE];
}
export const ascii_to_char = function (_, generator) {
var asciivalue = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '0'
return ['chr(' + asciivalue + ')', generator.ORDER_ATOMIC];
}
export const char_to_ascii = function (_, generator) {
var charvalue = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || 'a';
return ['ord(' + charvalue + ')', generator.ORDER_ATOMIC];
}
export const number_to_text = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '0';
return ['str(' + str + ')', generator.ORDER_ATOMIC];
}
export const text_length = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '""';
return ['len(' + str + ')', generator.ORDER_ATOMIC];
}
export const text_char_at2 = function (a, generator) {
var c = a.getFieldValue("WHERE") || "FROM_START",
str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '""';
switch (c) {
case "FROM_START":
a = generator.getAdjustedInt(a, "AT");
return [str + "[" + a + "]", generator.ORDER_ATOMIC];
case "FROM_END":
a = generator.getAdjustedInt(a, "AT", 1, !0);
return [str + "[" + a + "]", generator.ORDER_ATOMIC];
case "RANDOM":
generator.definitions_.import_random = "import random";
return ["random.choice(" + str + ")", generator.ORDER_FUNCTION_CALL];
}
throw "Unhandled combination (lists_getIndex).";
}
export const text_char_at = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '""';
var at = generator.valueToCode(this, 'AT', generator.ORDER_ATOMIC) || 0;
return [str + "[" + at + "]", generator.ORDER_ATOMIC];
}
export const text_random_char = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '""';
generator.definitions_.import_random = "import random";
return ["random.choice(" + str + ")", generator.ORDER_FUNCTION_CALL];
}
export const text_equals_starts_ends = function (_, generator) {
var str1 = (generator.valueToCode(this, 'STR1', generator.ORDER_ATOMIC) || '""');
var str2 = (generator.valueToCode(this, 'STR2', generator.ORDER_ATOMIC) || '""');
var dowhat = this.getFieldValue('DOWHAT');
if (dowhat === '===')
return [str1 + ' == ' + str2, generator.ORDER_ATOMIC];
return [str1 + '.' + dowhat + '(' + str2 + ')', generator.ORDER_ATOMIC];
}
export const text_compare_to = function (_, generator) {
var str1 = (generator.valueToCode(this, 'STR1', generator.ORDER_ATOMIC) || '""');
var str2 = (generator.valueToCode(this, 'STR2', generator.ORDER_ATOMIC) || '""');
return ['cmp(' + str1 + ',' + str2 + ')', generator.ORDER_ATOMIC];
}
export const text_substring2 = function (block, generator) {
// Get sublist.
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '""';
var where1 = block.getFieldValue('WHERE1');
var where2 = block.getFieldValue('WHERE2');
switch (where1) {
case 'FROM_START':
var at1 = generator.getAdjustedInt(block, 'AT1');
if (at1 == '0') {
at1 = '';
}
break;
case 'FROM_END':
var at1 = generator.getAdjustedInt(block, 'AT1', 0, true);
break;
case 'FIRST':
var at1 = '0';
break;
default:
throw 'Unhandled option (lists_getSublist)';
}
switch (where2) {
case 'FROM_START':
var at2 = generator.getAdjustedInt(block, 'AT2');
break;
case 'FROM_END':
var at2 = generator.getAdjustedInt(block, 'AT2', 0, true);
// Ensure that if the result calculated is 0 that sub-sequence will
// include all elements as expected.
if (!Blockly.isNumber(String(at2))) {
generator.definitions_['import_sys'] = 'import sys';
at2 += ' or sys.maxsize';
} else if (at2 == '0') {
at2 = '';
}
break;
case 'LAST':
var at2 = '-1';
break;
default:
throw 'Unhandled option (lists_getSublist)';
}
var code = str + '[' + at1 + ' : ' + at2 + ']';
return [code, generator.ORDER_ATOMIC];
}
export const text_substring = function (_, generator) {
// Get sublist.
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '""';
var at1 = generator.valueToCode(this, 'AT1', generator.ORDER_ATOMIC);
var at2 = generator.valueToCode(this, 'AT2', generator.ORDER_ATOMIC);
var code = str + '[' + at1 + ' : ' + at2 + ']';
return [code, generator.ORDER_ATOMIC];
}
export const text_capital = function (_, generator) {
var capital = this.getFieldValue('CAPITAL');
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
return ['' + str + '.' + capital + '()', generator.ORDER_ATOMIC];
}
export const text_center = function (_, generator) {
var center = this.getFieldValue('CENTER');
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var width = generator.valueToCode(this, 'WID', generator.ORDER_ATOMIC);
var symbol = generator.valueToCode(this, 'Symbol', generator.ORDER_ATOMIC);
return ['' + str + '.' + center + '(' + width + ',' + symbol + ')', generator.ORDER_ATOMIC];
}
export const text_find = function (_, generator) {
var sentence = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var str = generator.valueToCode(this, 'STR', generator.ORDER_ATOMIC);
return ['' + sentence + '.find(' + str + ')', generator.ORDER_ATOMIC];
}
export const text_join_seq = function (_, generator) {
var sentence = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var varName = generator.valueToCode(this, 'LIST', generator.ORDER_ASSIGNMENT) || '0';
return [sentence + '.join(' + varName + ')', generator.ORDER_ATOMIC];
}
export const text_replace = function (_, generator) {
var sentence = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var str1 = generator.valueToCode(this, 'STR1', generator.ORDER_ATOMIC);
var str2 = generator.valueToCode(this, 'STR2', generator.ORDER_ATOMIC);
return ['' + sentence + '.replace(' + str1 + ',' + str2 + ')', generator.ORDER_ATOMIC];
}
export const text_split = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '""';
var argument = generator.valueToCode(this, 'VAL', generator.ORDER_ATOMIC) || '""';
var code = str + ".split(" + argument + ")";
return [code, generator.ORDER_ATOMIC];
}
export const text_strip = function (_, generator) {
var towhat = this.getFieldValue('TOWHAT');
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var code = str + "." + towhat + "()";
return [code, generator.ORDER_ATOMIC];
}
export const text_format = function (_, generator) {
// Create a list with any number of elements of any type.
var s = this.getFieldValue('VAR');
var code = new Array(this.itemCount_);
var default_value = '0';
for (var n = 0; n < this.itemCount_; n++) {
code[n] = generator.valueToCode(this, 'ADD' + n,
generator.ORDER_NONE) || default_value;
}
var code = s + '.format(' + code.join(', ') + ')';
return [code, generator.ORDER_ATOMIC];
}
export const text_format_noreturn = function (_, generator) {
// Create a list with any number of elements of any type.
var s = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var code = new Array(this.itemCount_);
var default_value = '0';
for (var n = 0; n < this.itemCount_; n++) {
code[n] = generator.valueToCode(this, 'ADD' + n,
generator.ORDER_NONE) || default_value;
}
var code = s + '.format(' + code.join(', ') + ')';
return [code, generator.ORDER_ATOMIC];
}
export const text_substring3 = text_substring
export const text_compareTo = text_compare_to
export const text_char_at3 = text_char_at
export const text_encode = function (_, generator) {
var code = this.getFieldValue('DIR');
var varName = this.getFieldValue('CODE')
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '""';
return [str + '.' + code + '("' + varName + '")', generator.ORDER_ATOMIC];
}
export const text_eval = function (_, generator) {
var codestr = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var code = "eval" + '(' + codestr + ')';
return [code, generator.ORDER_ATOMIC];
}
export const os_system = function (_, generator) {
generator.definitions_['import_os'] = 'import os';
var codestr = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC);
var code = "os.system" + '(' + codestr + ')\n';
return code;
}

View File

@@ -0,0 +1,306 @@
import * as Blockly from 'blockly/core';
export const tuple_create_with = function (_, generator) {
// Create a list with any number of elements of any type.
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
Blockly.Variables.NAME_TYPE);
//var size=window.parseFloat(this.getFieldValue('SIZE'));
var code = new Array(this.itemCount_);
var default_value = '0';
for (var n = 0; n < this.itemCount_; n++) {
code[n] = generator.valueToCode(this, 'ADD' + n,
generator.ORDER_NONE) || default_value;
}
// if (this.itemCount_!=1){
// generator.definitions_['var_declare'+varName] = varName+'= '+ '(' + code.join(', ') + ')\n';}
// else {
// generator.definitions_['var_declare'+varName] = varName+'= '+ '(' + code.join(', ') + ',)\n';}
if (this.itemCount_ != 1) {
var code = varName + '= ' + '(' + code.join(', ') + ')\n';
}
else {
var code = varName + '= ' + '(' + code.join(', ') + ',)\n';
}
return code;
}
export const tuple_create_with_text2 = function (_, generator) {
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
Blockly.Variables.NAME_TYPE);
//var size=window.parseFloat(this.getFieldValue('SIZE'));
var text = this.getFieldValue('TEXT');
//generator.definitions_['var_declare'+varName] = varName+'= '+ '(' + text + ')\n';
var code = varName + '= ' + '(' + text + ')\n';
return code;
}
export const tuple_create_with_text_return = function (_, generator) {
var text = this.getFieldValue('TEXT');
var code = '(' + text + ')';
return [code, generator.ORDER_ATOMIC];
}
export const tuple_getIndex = function (_, generator) {
// Indexing into a list is the same as indexing into a string.
var varName = generator.valueToCode(this, 'TUP', generator.ORDER_ASSIGNMENT) || '0';
var argument0 = generator.valueToCode(this, 'AT',
generator.ORDER_ADDITIVE) || '1';
if (argument0.match(/^\d+$/)) {
// If the index is a naked number, decrement it right now.
argument0 = parseInt(argument0, 10);
}
// else {
// If the index is dynamic, decrement it in code.
// argument0;
// }
var code = varName + '[' + argument0 + ']';
return [code, generator.ORDER_ATOMIC];
}
export const tuple_length = function (_, generator) {
var varName = generator.valueToCode(this, 'TUP', generator.ORDER_ASSIGNMENT) || '0';
var code = 'len(' + varName + ')';
return [code, generator.ORDER_ATOMIC];
}
export const tuple_del = function (_, generator) {
var varName = generator.valueToCode(this, 'TUP', generator.ORDER_ASSIGNMENT) || '0';
var code = 'del ' + varName + '\n';
return code;
}
export const tuple_join = function (_, generator) {
var varName1 = generator.valueToCode(this, 'TUP1', generator.ORDER_ASSIGNMENT) || '0';
var varName2 = generator.valueToCode(this, 'TUP2', generator.ORDER_ASSIGNMENT) || '0';
var code = varName1 + " + " + varName2;
return [code, generator.ORDER_ATOMIC];
}
export const tuple_max = function (_, generator) {
var varname = generator.valueToCode(this, 'TUP', generator.ORDER_ASSIGNMENT) || '0';
var maxmin = this.getFieldValue('DIR');
var code = maxmin + "(" + varname + ')';
return [code, generator.ORDER_ATOMIC];
}
export const tuple_change_to = function (_, generator) {
var op = this.getFieldValue('OP');
var varName = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
var code = op + '(' + varName + ')\n';
return [code, generator.ORDER_ATOMIC];
}
export const tuple_find = function (_, generator) {
var op = this.getFieldValue('OP');
var varName = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '0';
var argument = generator.valueToCode(this, 'data', generator.ORDER_ASSIGNMENT) || '0';
if (op == 'INDEX')
var code = varName + '.index(' + argument + ')';
else if (op == 'COUNT')
var code = varName + '.count(' + argument + ')';
return [code, generator.ORDER_ATOMIC];
}
export const tuple_trig = function (a, generator) {
var b = a.getFieldValue("OP"), c;
generator.definitions_['import_math'] = "import math";
a = generator.valueToCode(a, 'data', generator.ORDER_NONE)
switch (b) {
case "LEN":
c = "len(" + a + ")";
break;
case "SUM":
c = "sum(" + a + ")";
break;
case "MIN":
c = "min(" + a + ")";
break;
case "MAX":
c = "max(" + a + ")";
break;
case 'AVERAGE':
// generator.definitions_['from_numbers_import_Number'] =
// 'from numbers import Number';
var functionName = generator.provideFunction_(
'math_mean',
// This operation excludes null and values that aren't int or float:',
// math_mean([null, null, "aString", 1, 9]) == 5.0.',
['def ' + generator.FUNCTION_NAME_PLACEHOLDER_ + '(myList):',
' localList = [e for e in myList if type(e) == int or type(e) == float]',
' if not localList: return',
' return float(sum(localList)) / len(localList)']);
c = functionName + '(' + a + ')';
break;
case 'MEDIAN':
// generator.definitions_['from_numbers_import_Number'] =
// 'from numbers import Numberd';
var functionName = generator.provideFunction_(
'math_median',
// This operation excludes null values:
// math_median([null, null, 1, 3]) == 2.0.
['def ' + generator.FUNCTION_NAME_PLACEHOLDER_ + '(myList):',
' localList = sorted([e for e in myList if type(e) == int or type(e) == float])',
' if not localList: return',
' if len(localList) % 2 == 0:',
' return (localList[len(localList) // 2 - 1] + ' +
'localList[len(localList) // 2]) / 2.0',
' else:',
' return localList[(len(localList) - 1) // 2]']);
c = functionName + '(' + a + ')';
break;
case 'MODE':
var functionName = generator.provideFunction_(
'math_modes',
// As a list of numbers can contain more than one mode,
// the returned result is provided as an array.
// Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1].
['def ' + generator.FUNCTION_NAME_PLACEHOLDER_ + '(some_list):',
' modes = []',
' # Using a lists of [item, count] to keep count rather than dict',
' # to avoid "unhashable" errors when the counted item is ' +
'itself a list or dict.',
' counts = []',
' maxCount = 1',
' for item in some_list:',
' found = False',
' for count in counts:',
' if count[0] == item:',
' count[1] += 1',
' maxCount = max(maxCount, count[1])',
' found = True',
' if not found:',
' counts.append([item, 1])',
' for counted_item, item_count in counts:',
' if item_count == maxCount:',
' modes.append(counted_item)',
' return modes']);
c = functionName + '(' + a + ')';
break;
case 'STD_DEV':
generator.definitions_['import_math'] = 'import math';
var functionName = generator.provideFunction_(
'math_standard_deviation',
['def ' + generator.FUNCTION_NAME_PLACEHOLDER_ + '(numbers):',
' n = len(numbers)',
' if n == 0: return',
' mean = float(sum(numbers)) / n',
' variance = sum((x - mean) ** 2 for x in numbers) / n',
' return math.sqrt(variance)']);
c = functionName + '(' + a + ')';
break;
default:
throw 'Unknown operator: ' + b;
}
if (c)
return [c, generator.ORDER_FUNCTION_CALL];
}
export const tuple_getSublist = function (block, generator) {
// Get sublist.
var list = generator.valueToCode(block, 'LIST',
generator.ORDER_MEMBER) || '[]';
var where1 = block.getFieldValue('WHERE1');
var where2 = block.getFieldValue('WHERE2');
switch (where1) {
case 'FROM_START':
var at1 = generator.getAdjustedInt(block, 'AT1');
if (at1 == '0') {
at1 = '';
}
break;
case 'FROM_END':
var at1 = generator.getAdjustedInt(block, 'AT1', 1, true);
break;
case 'FIRST':
var at1 = '0';
break;
default:
throw 'Unhandled option (lists_getSublist)';
}
switch (where2) {
case 'FROM_START':
var at2 = generator.getAdjustedInt(block, 'AT2', 1);
at2 = at2 - 1;
break;
case 'FROM_END':
var at2 = generator.getAdjustedInt(block, 'AT2', 1, true);
// Ensure that if the result calculated is 0 that sub-sequence will
// include all elements as expected.
if (!Blockly.isNumber(String(at2))) {
generator.definitions_['import_sys'] = 'import sys';
at2 += ' or sys.maxsize';
} else if (at2 == '0') {
at2 = '';
}
break;
case 'LAST':
var at2 = '-1';
break;
default:
throw 'Unhandled option (lists_getSublist)';
}
var code = list + '[' + at1 + ' : ' + at2 + ']';
return [code, generator.ORDER_MEMBER];
}
export const tuple_create_with_noreturn = function (_, generator) {
// Create a list with any number of elements of any type.
var code = new Array(this.itemCount_);
var default_value = '0';
for (var n = 0; n < this.itemCount_; n++) {
code[n] = generator.valueToCode(this, 'ADD' + n,
generator.ORDER_NONE) || default_value;
}
// if (this.itemCount_!=1){
// generator.definitions_['var_declare'+varName] = varName+'= '+ '(' + code.join(', ') + ')\n';}
// else {
// generator.definitions_['var_declare'+varName] = varName+'= '+ '(' + code.join(', ') + ',)\n';}
if (this.itemCount_ != 1) {
var code = '(' + code.join(', ') + ')';
}
else {
var code = '(' + code.join(', ') + ',)';
}
return [code, generator.ORDER_ATOMIC];
}
export const tuple_get_sublist = function (_, generator) {
// Get sublist.
var list = generator.valueToCode(this, 'LIST', generator.ORDER_ADDITIVE) || '0';
var at1 = generator.valueToCode(this, 'AT1', generator.ORDER_ADDITIVE) || '0';
var at2 = generator.valueToCode(this, 'AT2', generator.ORDER_ADDITIVE) || '0';
var code = list + '[' + at1 + ' : ' + at2 + ']';
return [code, generator.ORDER_ATOMIC];
}
export const tuple_get_random_item = function (_, generator) {
generator.definitions_['import_random'] = 'import random';
var varName = generator.valueToCode(this, 'TUP', generator.ORDER_ADDITIVE) || 'mytup';
var code = 'random.choice(' + varName + ')';
return [code, generator.ORDER_ATOMIC];
}
export const tuple_totuple = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || '0'
return ['tuple(' + str + ')', generator.ORDER_ATOMIC];
}
export const tuple_input = function (_, generator) {
var text = this.getFieldValue('CONTENT');
var code = '(' + text + ')';
return [code, generator.ORDER_ATOMIC];
}
export const tuple_create_llm_params = function (_, generator) {
var params = generator.valueToCode(this, 'params', generator.ORDER_ATOMIC) || '0'
var des = generator.valueToCode(this, 'des', generator.ORDER_ATOMIC) || '0'
var type = this.getFieldValue('type');
var code = '(' + params + ',"' + type + '",' + des +')';
return [code, generator.ORDER_ATOMIC];
}

View File

@@ -0,0 +1,78 @@
/**
* @license
* Visual Blocks Language
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Generating Python for utility blocks.
* @author acbart@vt.edu (Austin Cory Bart)
*/
export const raw_block = function (block) {
var code = block.getFieldValue('TEXT') + "\n";
return code;
}
export const raw_expression = function (block, generator) {
var code = block.getFieldValue('TEXT');
return [code, generator.ORDER_ATOMIC];
}
export const raw_empty = function (block, generator) {
var code = generator.valueToCode(block, 'VALUE',
generator.ORDER_ATOMIC) || '';
return code + "\n";
}
export const raw_table = function () {
//var code = block.getFieldValue('TEXT')+"\n";
return '';//code;
}
export const type_check = function (block, generator) {
var value = generator.valueToCode(block, 'VALUE',
generator.ORDER_MEMBER) || '___';
var code = 'type(' + value + ')';
return [code, generator.ORDER_ATOMIC];
}
export const function_call = function (block, generator) {
var name = block.getFieldValue('NAME');
var hasReturn = block.hasReturn_;
var args = new Array(block.itemCount_);
for (var n = 0; n < block.itemCount_; n++) {
args[n] = generator.valueToCode(block, 'ARGUMENT' + n,
generator.ORDER_NONE) || '___';
}
var code = name + '(' + args.join(', ') + ')';
if (hasReturn) {
return [code, generator.ORDER_ATOMIC];
}
return code + '\n';
}
export const attribute_access = function (block, generator) {
var value_module = generator.valueToCode(block, 'MODULE', generator.ORDER_ATOMIC);
var value_name = generator.valueToCode(block, 'NAME', generator.ORDER_ATOMIC);
//去除掉两端的括号,如(val()) --> val()
value_name = value_name.substring(1, value_name.length - 1);
// TODO: Assemble JavaScript into code variable.
var code = value_module + '.' + value_name;
// TODO: Change ORDER_NONE to the correct strength.
return [code, generator.ORDER_NONE];
}

View File

@@ -0,0 +1,90 @@
import * as Blockly from 'blockly/core';
export const variables_get = function (_, generator) {
// Variable getter.
var code = generator.variableDB_.getName(this.getFieldValue('VAR'),
Blockly.Variables.NAME_TYPE);
return [code, generator.ORDER_ATOMIC];
}
// export const variables_declare = function() {
// var dropdown_type = this.getFieldValue('TYPE');
// var argument0;
// //TODO: settype to variable
// argument0 = generator.valueToCode(this, 'VALUE',generator.ORDER_ASSIGNMENT) || 'None';
// var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
// Blockly.Variables.NAME_TYPE);
// if (dropdown_type === 'number')
// generator.definitions_['var_declare' + varName] = 'let ' + ' ' + varName + ' = 0;';
// else if(dropdown_type === 'string')
// generator.definitions_['var_declare' + varName] = 'let ' + ' ' + varName + ' = \'\';';
// else if(dropdown_type === 'boolean')
// generator.definitions_['var_declare' + varName] = 'let ' + ' ' + varName + ' = true;';
// else if(dropdown_type.startsWith('Array'))
// generator.definitions_['var_declare' + varName] = 'let ' + varName + ':' + dropdown_type + ' = [];';
// if(generator.setups_['var_declare' + varName] === undefined) {
// generator.setups_['var_declare' + varName] = varName + ' = ' + argument0 + '\n';
// }else {
// }
// return '';
// }
export const variables_set = function (_, generator) {
// Variable setter.
if (this.getFieldValue('VAR') == "") {
return " = None\n";
}
var argument0 = generator.valueToCode(this, 'VALUE',
generator.ORDER_ASSIGNMENT) || 'None';
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
return varName + ' = ' + argument0 + '\n';
}
export const variables_change = function (_, generator) {
// Variable setter.
var operator = this.getFieldValue('OP');
var varName = generator.valueToCode(this, 'MYVALUE', generator.ORDER_ATOMIC) || 'None';
if (operator == 'bytes') { var code = operator + '(' + varName + ',"UTF-8")'; }
else { var code = operator + '(' + varName + ')'; }
return [code, generator.ORDER_ATOMIC];
}
export const variables_global = function (_, generator) {
var str = generator.valueToCode(this, 'VAR', generator.ORDER_ATOMIC) || 'None';
var code = "global " + str + '\n';
return code;
}
// ok
export const controls_type = function (_, generator) {
var data = generator.valueToCode(this, 'DATA', generator.ORDER_ATOMIC) || 'None'
var code = 'type(' + data + ')';
return [code, generator.ORDER_ATOMIC];
}
export const controls_typeLists = function (_, generator) {
//generator.definitions_['import_microbit_*'] = 'from microbit import *';
var type = this.getFieldValue('type');
// generator.definitions_['func_type' + type] = code;
return [type, generator.ORDER_ATOMIC];
}
export const lists_zip = function (_, generator) {
var code = new Array(this.itemCount_);
var default_value = '[]';
for (var n = 0; n < this.itemCount_; n++) {
code[n] = generator.valueToCode(this, 'ADD' + n,
generator.ORDER_NONE) || default_value;
}
var code = 'zip(' + code.join(', ') + ')';
return [code, generator.ORDER_ATOMIC];
}
export const unpack_iterable_object = function (_, generator) {
const varName = generator.valueToCode(this, 'VAR', generator.ORDER_ASSIGNMENT) || '[]';
const type = this.getFieldValue('TYPE');
const code = `${type}(${varName})`;
return [code, generator.ORDER_ATOMIC];
}

View File

View File

@@ -0,0 +1,722 @@
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Utility functions for handling class_test.
* @author fraser@google.com (Neil Fraser)
*/
import * as Blockly from 'blockly/core';
//类
Blockly.Block.prototype.class_getVars = function () { for (var a = [], b = 0, c; c = this.inputList[b]; b++)for (var d = 0, e; e = c.fieldRow[d]; d++)e instanceof Blockly.FieldVariable && a.push(e.getValue()); return a }; Blockly.Block.prototype.class_renameVar = function (a, b) { for (var c = 0, d; d = this.inputList[c]; c++)for (var e = 0, f; f = d.fieldRow[e]; e++)f instanceof Blockly.FieldVariable && Blockly.Names.equals(a, f.getValue()) && f.setValue(b) };
//属性
Blockly.Block.prototype.property_getVars = function () { for (var a = [], b = 0, c; c = this.inputList[b]; b++)for (var d = 0, e; e = c.fieldRow[d]; d++)e instanceof Blockly.FieldVariable && a.push(e.getValue()); return a }; Blockly.Block.prototype.property_renameVar = function (a, b) { for (var c = 0, d; d = this.inputList[c]; c++)for (var e = 0, f; f = d.fieldRow[e]; e++)f instanceof Blockly.FieldVariable && Blockly.Names.equals(a, f.getValue()) && f.setValue(b) };
//对象
Blockly.Block.prototype.object_getVars = function () { for (var a = [], b = 0, c; c = this.inputList[b]; b++)for (var d = 0, e; e = c.fieldRow[d]; d++)e instanceof Blockly.FieldVariable && a.push(e.getValue()); return a }; Blockly.Block.prototype.object_renameVar = function (a, b) { for (var c = 0, d; d = this.inputList[c]; c++)for (var e = 0, f; f = d.fieldRow[e]; e++)f instanceof Blockly.FieldVariable && Blockly.Names.equals(a, f.getValue()) && f.setValue(b) };
//类
Blockly.Class.CLASS_NAME_TYPE = 'CLASS';
//属性
Blockly.Class.PROPERTY_NAME_TYPE = 'PROPERTY';
//方法
Blockly.Class.METHOD_NAME_TYPE = 'METHOD';
//对象
Blockly.Class.OBJECT_NAME_TYPE = 'OBJECT';
/**** 类 ****/
Blockly.Class.allClass = function (root) {
var blocks;
if (root.getDescendants) {
// Root is Block.
blocks = root.getDescendants();
} else if (root.getAllBlocks) {
// Root is Workspace.
blocks = root.getAllBlocks();
} else {
throw 'Not Block or Workspace: ' + root;
}
var variableHash = Object.create(null);
// Iterate through every block and add each variable to the hash.
for (var x = 0; x < blocks.length; x++) {
var blockClass = blocks[x].class_getVars();
for (var y = 0; y < blockClass.length; y++) {
var varName = blockClass[y];
// Variable name may be null if the block is only half-built.
if (varName) {
variableHash[varName.toLowerCase()] = varName;
}
}
}
// Flatten the hash into a list.
var variableList = [];
for (var name in variableHash) {
variableList.push(variableHash[name]);
}
return variableList;
};
Blockly.Class.renameClass = function (oldName, newName, workspace) {
Blockly.Events.setGroup(true);
var blocks = workspace.getAllBlocks();
// Iterate through every block.
for (var i = 0; i < blocks.length; i++) {
blocks[i].class_renameVar(oldName, newName);
}
Blockly.Events.setGroup(false);
};
Blockly.Class.class_generateUniqueName = function (workspace) {
var variableList = Blockly.Class.allClass(workspace);
var newName = '';
if (variableList.length) {
var nameSuffix = 1;
var letters = 'ijkmnopqrstuvwxyzabcdefgh'; // No 'l'.
var letterIndex = 0;
var potName = letters.charAt(letterIndex);
while (!newName) {
var inUse = false;
for (var i = 0; i < variableList.length; i++) {
if (variableList[i].toLowerCase() == potName) {
// This potential name is already used.
inUse = true;
break;
}
}
if (inUse) {
// Try the next potential name.
letterIndex++;
if (letterIndex == letters.length) {
// Reached the end of the character sequence so back to 'i'.
// a new suffix.
letterIndex = 0;
nameSuffix++;
}
potName = letters.charAt(letterIndex);
if (nameSuffix > 1) {
potName += nameSuffix;
}
} else {
// We can use the current potential name.
newName = potName;
}
}
} else {
newName = 'i';
}
return newName;
};
Blockly.Class.class_flyoutCategory = function (workspace) {
var variableList = Blockly.Class.allClass(workspace);
//variableList.sort(goog.string.caseInsensitiveCompare);
var xmlList = [];
//创建类
if (Blockly.Blocks['class_make']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'class_make');
if (Blockly.Blocks['class_make']) {
block.setAttribute('gap', 16);
}
xmlList.push(block);
}
if (Blockly.Blocks['class_make_with_base']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'class_make_with_base');
if (Blockly.Blocks['class_make_with_base']) {
block.setAttribute('gap', 16);
}
xmlList.push(block);
}
if (xmlList.length) {
xmlList[xmlList.length - 1].setAttribute('gap', 30);
}
for (var i = 0; i < variableList.length; i++) {
if (Blockly.Blocks['class_get']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'class_get');
if (Blockly.Blocks['class_get']) {
block.setAttribute('gap', 16);
}
var field = Blockly.utils.xml.createElement('field', null, variableList[i]);
field.setAttribute('name', 'VAR');
block.appendChild(field);
xmlList.push(block);
}
}
return xmlList;
};
/**** 属性 ****/
Blockly.Class.allProperty = function (root) {
var blocks;
if (root.getDescendants) {
// Root is Block.
blocks = root.getDescendants();
} else if (root.getAllBlocks) {
// Root is Workspace.
blocks = root.getAllBlocks();
} else {
throw 'Not Block or Workspace: ' + root;
}
var variableHash = Object.create(null);
// Iterate through every block and add each variable to the hash.
for (var x = 0; x < blocks.length; x++) {
var blockClass = blocks[x].property_getVars();
for (var y = 0; y < blockClass.length; y++) {
var varName = blockClass[y];
// Variable name may be null if the block is only half-built.
if (varName) {
variableHash[varName.toLowerCase()] = varName;
}
}
}
// Flatten the hash into a list.
var variableList = [];
for (var name in variableHash) {
variableList.push(variableHash[name]);
}
return variableList;
};
Blockly.Class.renameProperty = function (oldName, newName, workspace) {
Blockly.Events.setGroup(true);
var blocks = workspace.getAllBlocks();
// Iterate through every block.
for (var i = 0; i < blocks.length; i++) {
blocks[i].property_renameVar(oldName, newName);
}
Blockly.Events.setGroup(false);
};
Blockly.Class.property_generateUniqueName = function (workspace) {
var variableList = Blockly.Class.allProperty(workspace);
var newName = '';
if (variableList.length) {
var nameSuffix = 1;
var letters = 'ijkmnopqrstuvwxyzabcdefgh'; // No 'l'.
var letterIndex = 0;
var potName = letters.charAt(letterIndex);
while (!newName) {
var inUse = false;
for (var i = 0; i < variableList.length; i++) {
if (variableList[i].toLowerCase() == potName) {
// This potential name is already used.
inUse = true;
break;
}
}
if (inUse) {
// Try the next potential name.
letterIndex++;
if (letterIndex == letters.length) {
// Reached the end of the character sequence so back to 'i'.
// a new suffix.
letterIndex = 0;
nameSuffix++;
}
potName = letters.charAt(letterIndex);
if (nameSuffix > 1) {
potName += nameSuffix;
}
} else {
// We can use the current potential name.
newName = potName;
}
}
} else {
newName = 'i';
}
return newName;
};
Blockly.Class.property_flyoutCategory = function (workspace) {
var variableList = Blockly.Class.allProperty(workspace);
//variableList.sort(goog.string.caseInsensitiveCompare);
var xmlList = [];
//创建属性
if (Blockly.Blocks['property_set']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'property_set');
xmlList.push(block);
}
if (xmlList.length) {
xmlList[xmlList.length - 1].setAttribute('gap', 30);
}
for (var i = 0; i < variableList.length; i++) {
if (Blockly.Blocks['property_set']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'property_set');
if (Blockly.Blocks['property_set']) {
block.setAttribute('gap', 16);
}
var field = Blockly.utils.xml.createElement('field', null, variableList[i]);
field.setAttribute('name', 'VAR');
block.appendChild(field);
xmlList.push(block);
}
if (Blockly.Blocks['property_get']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'property_get');
if (Blockly.Blocks['property_get']) {
block.setAttribute('gap', 25);
}
var field = Blockly.utils.xml.createElement('field', null, variableList[i]);
field.setAttribute('name', 'VAR');
block.appendChild(field);
xmlList.push(block);
}
}
return xmlList;
};
/**** 方法 ****/
Blockly.Class.proallProcedures = function (root) {
var blocks = root.getAllBlocks();
var proceduresReturn = [];
var proceduresNoReturn = [];
var name_data = [];
var select = true;
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].method_getProcedureDef) {
var tuple = blocks[i].method_getProcedureDef();
if (tuple) {
if (tuple[4]) {
if (name_data.length == 0) {
if (tuple[4].indexOf("_") != -1) {
select = true;
name_data.push(tuple[4]);
}
else {
select = false;
}
}
else {
for (var j = 0; j < name_data.length; j++) {
if (name_data[j] == tuple[4] || tuple[4].indexOf("_") == -1) {
select = false;
break;
}
if (j == name_data.length - 1) {
select = true;
name_data.push(tuple[4]);
break;
}
}
}
}
if (select) {
if (tuple[2]) {
proceduresReturn.push(tuple);
} else {
proceduresNoReturn.push(tuple);
}
}
}
}
}
proceduresNoReturn.sort(Blockly.Class.proprocTupleComparator_);
proceduresReturn.sort(Blockly.Class.proprocTupleComparator_);
return [proceduresNoReturn, proceduresReturn];
};
/**
* Comparison function for case-insensitive sorting of the first element of
* a tuple.
* @param {!Array} ta First tuple.
* @param {!Array} tb Second tuple.
* @return {number} -1, 0, or 1 to signify greater than, equality, or less than.
* @private
*/
Blockly.Class.proprocTupleComparator_ = function (ta, tb) {
return ta[0].toLowerCase().localeCompare(tb[0].toLowerCase());
};
/**
* Ensure two identically-named procedures don't exist.
* @param {string} name Proposed procedure name.
* @param {!Blockly.Block} block Block to disambiguate.
* @return {string} Non-colliding name.
*/
Blockly.Class.profindLegalName = function (name, block) {
/*
if (block.isInFlyout) {
// Flyouts can have multiple procedures called 'do something'.
return name;
}
while (!Blockly.Class.proisLegalName(name, block.workspace, block)) {
// Collision with another procedure.
var r = name.match(/^(.*?)(\d+)$/);
if (!r) {
name += '2';
} else {
name = r[1] + (parseInt(r[2], 10) + 1);
}
name = '';
}
*/
return name;
};
/**
* Does this procedure have a legal name? Illegal names include names of
* procedures already defined.
* @param {string} name The questionable name.
* @param {!Blockly.Workspace} workspace The workspace to scan for collisions.
* @param {Blockly.Block=} opt_exclude Optional block to exclude from
* comparisons (one doesn't want to collide with oneself).
* @return {boolean} True if the name is legal.
*/
Blockly.Class.proisLegalName = function (name, workspace, opt_exclude) {
var blocks = workspace.getAllBlocks();
// Iterate through every block and check the name.
for (var i = 0; i < blocks.length; i++) {
if (blocks[i] == opt_exclude) {
continue;
}
if (blocks[i].method_getProcedureDef) {
var procName = blocks[i].method_getProcedureDef();
if (Blockly.Names.equals(procName[0], name)) {
return false;
}
}
}
return true;
};
/**
* Rename a procedure. Called by the editable field.
* @param {string} text The proposed new name.
* @return {string} The accepted name.
* @this {!Blockly.Field}
*/
Blockly.Class.prorename = function (text) {
// Strip leading and trailing whitespace. Beyond this, all names are legal.
text = text.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
// Ensure two identically-named procedures don't exist.
text = Blockly.Class.profindLegalName(text, this.sourceBlock_);
// Rename any callers.
var blocks = this.sourceBlock_.workspace.getAllBlocks();
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].method_renameProcedure) {
blocks[i].method_renameProcedure(this.text_, text);
}
}
return text;
};
/**
* Find all the callers of a named procedure.
* @param {string} name Name of procedure.
* @param {!Blockly.Workspace} workspace The workspace to find callers in.
* @return {!Array.<!Blockly.Block>} Array of caller blocks.
*/
Blockly.Class.progetCallers = function (name, workspace) {
var callers = [];
var blocks = workspace.getAllBlocks();
// Iterate through every block and check the name.
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].method_getProcedureCall) {
var procName = blocks[i].method_getProcedureCall();
// Procedure name may be null if the block is only half-built.
if (procName && Blockly.Names.equals(procName, name)) {
callers.push(blocks[i]);
}
}
}
return callers;
};
/**
* When a procedure definition is disposed of, find and dispose of all its
* callers.
* @param {string} name Name of deleted procedure definition.
* @param {!Blockly.Workspace} workspace The workspace to delete callers from.
*/
Blockly.Class.prodisposeCallers = function (name, workspace) {
var callers = Blockly.Class.progetCallers(name, workspace);
for (var i = 0; i < callers.length; i++) {
callers[i].dispose(true, false);
}
};
/**
* When a procedure definition changes its parameters, find and edit all its
* callers.
* @param {!Blockly.Block} defBlock Procedure definition block.
*/
Blockly.Class.mutateCallers = function (defBlock) {
var oldRecordUndo = Blockly.Events.recordUndo;
var name = defBlock.method_getProcedureDef()[0];
var xmlElement = defBlock.mutationToDom(true);
var callers = Blockly.Procedures.getCallers(name, defBlock.workspace);
for (var i = 0, caller; caller = callers[i]; i++) {
var oldMutationDom = caller.mutationToDom();
var oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
caller.domToMutation(xmlElement);
var newMutationDom = caller.mutationToDom();
var newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom);
if (oldMutation != newMutation) {
// Fire a mutation on every caller block. But don't record this as an
// undo action since it is deterministically tied to the procedure's
// definition mutation.
Blockly.Events.recordUndo = false;
Blockly.Events.fire(new Blockly.Events.BlockChange(
caller, 'mutation', null, oldMutation, newMutation));
Blockly.Events.recordUndo = oldRecordUndo;
}
}
};
/**
* Find the definition block for the named procedure.
* @param {string} name Name of procedure.
* @param {!Blockly.Workspace} workspace The workspace to search.
* @return {Blockly.Block} The procedure definition block, or null not found.
*/
Blockly.Class.progetDefinition = function (name, workspace) {
var blocks = workspace.getAllBlocks();
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].method_getProcedureDef) {
var tuple = blocks[i].method_getProcedureDef();
if (tuple && Blockly.Names.equals(tuple[0], name)) {
return blocks[i];
}
}
}
return null;
};
Blockly.Class.method_flyoutCategory = function (workspace) {
var xmlList = [];
//创建方法
if (Blockly.Blocks['method_procedures_defnoreturn']) {
// <block type="procedures_defnoreturn" gap="16"></block>
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'method_procedures_defnoreturn');
block.setAttribute('gap', 16);
xmlList.push(block);
}
if (Blockly.Blocks['method_procedures_defreturn']) {
// <block type="procedures_defreturn" gap="16"></block>
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'method_procedures_defreturn');
block.setAttribute('gap', 16);
xmlList.push(block);
}
/*
if (Blockly.Blocks['method_procedures_return']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'method_procedures_return');
block.setAttribute('gap', 16);
xmlList.push(block);
}
if (Blockly.Blocks['method_procedures_ifreturn']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'method_procedures_ifreturn');
block.setAttribute('gap', 16);
xmlList.push(block);
}
*/
if (Blockly.Blocks['procedures_return']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'procedures_return');
block.setAttribute('gap', 16);
xmlList.push(block);
}
if (Blockly.Blocks['procedures_ifreturn']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'procedures_ifreturn');
block.setAttribute('gap', 16);
xmlList.push(block);
}
function populateProcedures(procedureList, templateName) {
for (var i = 0; i < procedureList.length; i++) {
var name = procedureList[i][0];
var args = procedureList[i][1];
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', templateName);
block.setAttribute('gap', 16);
var mutation = Blockly.utils.xml.createElement('mutation');
mutation.setAttribute('name', name);
block.appendChild(mutation);
for (var t = 0; t < args.length; t++) {
var arg = Blockly.utils.xml.createElement('arg');
arg.setAttribute('name', args[t]);
mutation.appendChild(arg);
}
xmlList.push(block);
}
}
var tuple = Blockly.Class.proallProcedures(workspace);
populateProcedures(tuple[0], 'method_procedures_callnoreturn');
populateProcedures(tuple[1], 'method_procedures_callreturn');
return xmlList;
};
/**** 对象 ****/
Blockly.Class.allObject = function (root) {
var blocks;
if (root.getDescendants) {
// Root is Block.
blocks = root.getDescendants();
} else if (root.getAllBlocks) {
// Root is Workspace.
blocks = root.getAllBlocks();
} else {
throw 'Not Block or Workspace: ' + root;
}
var variableHash = Object.create(null);
// Iterate through every block and add each variable to the hash.
for (var x = 0; x < blocks.length; x++) {
var blockClass = blocks[x].object_getVars();
for (var y = 0; y < blockClass.length; y++) {
var varName = blockClass[y];
// Variable name may be null if the block is only half-built.
if (varName) {
variableHash[varName.toLowerCase()] = varName;
}
}
}
// Flatten the hash into a list.
var variableList = [];
for (var name in variableHash) {
variableList.push(variableHash[name]);
}
return variableList;
};
Blockly.Class.renameObject = function (oldName, newName, workspace) {
Blockly.Events.setGroup(true);
var blocks = workspace.getAllBlocks();
// Iterate through every block.
for (var i = 0; i < blocks.length; i++) {
blocks[i].object_renameVar(oldName, newName);
}
Blockly.Events.setGroup(false);
};
Blockly.Class.object_generateUniqueName = function (workspace) {
var variableList = Blockly.Class.allObject(workspace);
var newName = '';
if (variableList.length) {
var nameSuffix = 1;
var letters = 'ijkmnopqrstuvwxyzabcdefgh'; // No 'l'.
var letterIndex = 0;
var potName = letters.charAt(letterIndex);
while (!newName) {
var inUse = false;
for (var i = 0; i < variableList.length; i++) {
if (variableList[i].toLowerCase() == potName) {
// This potential name is already used.
inUse = true;
break;
}
}
if (inUse) {
// Try the next potential name.
letterIndex++;
if (letterIndex == letters.length) {
// Reached the end of the character sequence so back to 'i'.
// a new suffix.
letterIndex = 0;
nameSuffix++;
}
potName = letters.charAt(letterIndex);
if (nameSuffix > 1) {
potName += nameSuffix;
}
} else {
// We can use the current potential name.
newName = potName;
}
}
} else {
newName = 'i';
}
return newName;
};
Blockly.Class.object_flyoutCategory = function (workspace) {
var variableList = Blockly.Class.allObject(workspace);
//variableList.sort(goog.string.caseInsensitiveCompare);
var xmlList = [];
//创建对象
if (Blockly.Blocks['object_set']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'object_set');
xmlList.push(block);
}
if (xmlList.length) {
xmlList[xmlList.length - 1].setAttribute('gap', 30);
}
var variableList_class = Blockly.Class.allClass(workspace);
//variableList_class.sort(goog.string.caseInsensitiveCompare);
for (var i = 0; i < variableList_class.length; i++) {
if (Blockly.Blocks['object_set']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'object_set');
if (Blockly.Blocks['object_set']) {
block.setAttribute('gap', 16);
}
var field = Blockly.utils.xml.createElement('field', null, variableList_class[i]);
field.setAttribute('name', 'VAR10');
block.appendChild(field);
xmlList.push(block);
}
}
for (var i = 0; i < variableList.length; i++) {
if (Blockly.Blocks['object_get']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'object_get');
if (Blockly.Blocks['object_get']) {
block.setAttribute('gap', 16);
}
var field = Blockly.utils.xml.createElement('field', null, variableList[i]);
field.setAttribute('name', 'VAR');
block.appendChild(field);
xmlList.push(block);
}
}
return xmlList;
};

View File

@@ -0,0 +1,192 @@
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Utility functions for handling variables and procedure names.
* @author fraser@google.com (Neil Fraser)
*/
import Variables from './variables';
/**
* Class for a database of entity names (variables, functions, etc).
* @param {string} reservedWords A comma-separated string of words that are
* illegal for use as names in a language (e.g. 'new,if,this,...').
* @param {string=} opt_variablePrefix Some languages need a '$' or a namespace
* before all variable names.
* @constructor
*/
class Names {
constructor(reservedWords, opt_variablePrefix) {
this.variablePrefix_ = opt_variablePrefix || '';
this.reservedDict_ = Object.create(null);
if (reservedWords) {
var splitWords = reservedWords.split(',');
for (var i = 0; i < splitWords.length; i++) {
this.reservedDict_[splitWords[i]] = true;
}
}
this.reset();
}
/**
* Do the given two entity names refer to the same entity?
* Blockly names are case-insensitive.
* @param {string} name1 First name.
* @param {string} name2 Second name.
* @return {boolean} True if names are the same.
*/
static equals(name1, name2) {
return name1 == name2;
}
/**
* When JavaScript (or most other languages) is generated, variable 'foo' and
* procedure 'foo' would collide. However, Blockly has no such problems since
* variable get 'foo' and procedure call 'foo' are unambiguous.
* Therefore, Blockly keeps a separate type name to disambiguate.
* getName('foo', 'variable') -> 'foo'
* getName('foo', 'procedure') -> 'foo2'
*/
/**
* Empty the database and start from scratch. The reserved words are kept.
*/
reset() {
this.db_ = Object.create(null);
this.dbReverse_ = Object.create(null);
this.variableMap_ = null;
}
/**
* Set the variable map that maps from variable name to variable object.
* @param {!Blockly.VariableMap} map The map to track.
* @package
*/
setVariableMap(map) {
this.variableMap_ = map;
}
/**
* Get the name for a user-defined variable, based on its ID.
* This should only be used for variables of type Variables.NAME_TYPE.
* @param {string} id The ID to look up in the variable map.
* @return {?string} The name of the referenced variable, or null if there was
* no variable map or the variable was not found in the map.
* @private
*/
getNameForUserVariable_(id) {
if (!this.variableMap_) {
/*
console.log('Deprecated call to Names.prototype.getName without ' +
'defining a variable map. To fix, add the folowing code in your ' +
'generator\'s init() function:\n' +
'Blockly.YourGeneratorName.variableDB_.setVariableMap(' +
'workspace.getVariableMap());');
*/
return null;
}
var variable = this.variableMap_.getVariableById(id);
if (variable) {
return variable.name;
}
return null;
}
/**
* Convert a Blockly entity name to a legal exportable entity name.
* @param {string} name The Blockly entity name (no constraints).
* @param {string} type The type of entity in Blockly
* ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).
* @return {string} An entity name that is legal in the exported language.
*/
getName(name, type) {
if (type == Variables.NAME_TYPE) {
var varName = this.getNameForUserVariable_(name);
if (varName) {
name = varName;
}
}
var normalized = name + '_' + type;
var isVarType = type == Variables.NAME_TYPE ||
type == Names.DEVELOPER_VARIABLE_TYPE;
var prefix = isVarType ? this.variablePrefix_ : '';
if (normalized in this.db_) {
return prefix + this.db_[normalized];
}
var safeName = this.getDistinctName(name, type);
this.db_[normalized] = safeName.substr(prefix.length);
return safeName;
}
/**
* Convert a Blockly entity name to a legal exportable entity name.
* Ensure that this is a new name not overlapping any previously defined name.
* Also check against list of reserved words for the current language and
* ensure name doesn't collide.
* @param {string} name The Blockly entity name (no constraints).
* @param {string} type The type of entity in Blockly
* ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).
* @return {string} An entity name that is legal in the exported language.
*/
getDistinctName(name, type) {
var safeName = this.safeName_(name);
var i = '';
while (this.dbReverse_[safeName + i] ||
(safeName + i) in this.reservedDict_) {
// Collision with existing name. Create a unique name.
i = i ? i + 1 : 2;
}
safeName += i;
this.dbReverse_[safeName] = true;
var isVarType = type == Variables.NAME_TYPE ||
type == Names.DEVELOPER_VARIABLE_TYPE;
var prefix = isVarType ? this.variablePrefix_ : '';
return prefix + safeName;
}
/**
* Given a proposed entity name, generate a name that conforms to the
* [_A-Za-z][_A-Za-z0-9]* format that most languages consider legal for
* variables.
* @param {string} name Potentially illegal entity name.
* @return {string} Safe entity name.
* @private
*/
safeName_(name) {
if (!name) {
name = 'unnamed';
} else {
// Unfortunately names in non-latin characters will look like
// _E9_9F_B3_E4_B9_90 which is pretty meaningless.
// https://github.com/google/blockly/issues/1654
name = encodeURI(name.replace(/ /g, '_')).replace(/[^,\w]/g, '_');
// Most languages don't allow names with leading numbers.
if ('0123456789'.indexOf(name[0]) != -1) {
name = 'my_' + name;
}
}
return name;
}
}
/**
* Constant to separate developer variable names from user-defined variable
* names when running generators.
* A developer variable will be declared as a global in the generated code, but
* will never be shown to the user in the workspace or stored in the variable
* map.
*/
Names.DEVELOPER_VARIABLE_TYPE = 'DEVELOPER_VARIABLE';
export default Names;

View File

@@ -0,0 +1,327 @@
/**
* @license
* Copyright 2012 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Utility functions for handling procedures.
* @author fraser@google.com (Neil Fraser)
*/
import * as Blockly from 'blockly/core';
const Procedures = {};
/**
* Constant to separate procedure names from variables and generated functions
* when running generators.
* @deprecated Use Blockly.PROCEDURE_CATEGORY_NAME
*/
Procedures.NAME_TYPE = Blockly.PROCEDURE_CATEGORY_NAME;
/**
* Find all user-created procedure definitions in a workspace.
* @param {!Blockly.Workspace} root Root workspace.
* @return {!Array.<!Array.<!Array>>} Pair of arrays, the
* first contains procedures without return variables, the second with.
* Each procedure is defined by a three-element list of name, parameter
* list, and return value boolean.
*/
Procedures.allProcedures = function (root) {
var blocks = root.getAllBlocks(false);
var proceduresReturn = [];
var proceduresNoReturn = [];
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].getProcedureDef) {
var tuple = blocks[i].getProcedureDef();
if (tuple) {
if (tuple[2]) {
proceduresReturn.push(tuple);
} else {
proceduresNoReturn.push(tuple);
}
}
}
}
proceduresNoReturn.sort(Procedures.procTupleComparator_);
proceduresReturn.sort(Procedures.procTupleComparator_);
return [proceduresNoReturn, proceduresReturn];
};
/**
* Comparison function for case-insensitive sorting of the first element of
* a tuple.
* @param {!Array} ta First tuple.
* @param {!Array} tb Second tuple.
* @return {number} -1, 0, or 1 to signify greater than, equality, or less than.
* @private
*/
Procedures.procTupleComparator_ = function (ta, tb) {
return ta[0].toLowerCase().localeCompare(tb[0].toLowerCase());
};
/**
* Ensure two identically-named procedures don't exist.
* Take the proposed procedure name, and return a legal name i.e. one that
* is not empty and doesn't collide with other procedures.
* @param {string} name Proposed procedure name.
* @param {!Blockly.Block} block Block to disambiguate.
* @return {string} Non-colliding name.
*/
Procedures.findLegalName = function (name, block) {
if (block.isInFlyout) {
// Flyouts can have multiple procedures called 'do something'.
return name;
}
name = name || Blockly.Msg['UNNAMED_KEY'] || 'unnamed';
while (!Procedures.isLegalName_(name, block.workspace, block)) {
// Collision with another procedure.
var r = name.match(/^(.*?)(\d+)$/);
if (!r) {
name += '2';
} else {
name = r[1] + (parseInt(r[2], 10) + 1);
}
}
return name;
};
/**
* Does this procedure have a legal name? Illegal names include names of
* procedures already defined.
* @param {string} name The questionable name.
* @param {!Blockly.Workspace} workspace The workspace to scan for collisions.
* @param {Blockly.Block=} opt_exclude Optional block to exclude from
* comparisons (one doesn't want to collide with oneself).
* @return {boolean} True if the name is legal.
* @private
*/
Procedures.isLegalName_ = function (name, workspace, opt_exclude) {
return !Procedures.isNameUsed(name, workspace, opt_exclude);
};
/**
* Return if the given name is already a procedure name.
* @param {string} name The questionable name.
* @param {!Blockly.Workspace} workspace The workspace to scan for collisions.
* @param {Blockly.Block=} opt_exclude Optional block to exclude from
* comparisons (one doesn't want to collide with oneself).
* @return {boolean} True if the name is used, otherwise return false.
*/
Procedures.isNameUsed = function (name, workspace, opt_exclude) {
var blocks = workspace.getAllBlocks(false);
// Iterate through every block and check the name.
for (var i = 0; i < blocks.length; i++) {
if (blocks[i] == opt_exclude) {
continue;
}
if (blocks[i].getProcedureDef) {
var procName = blocks[i].getProcedureDef();
if (Blockly.Names.equals(procName[0], name)) {
return true;
}
}
}
return false;
};
/**
* Rename a procedure. Called by the editable field.
* @param {string} name The proposed new name.
* @return {string} The accepted name.
* @this {Blockly.Field}
*/
Procedures.rename = function (name) {
// Strip leading and trailing whitespace. Beyond this, all names are legal.
name = name.trim();
var legalName = Procedures.findLegalName(name, this.getSourceBlock());
var oldName = this.getValue();
if (oldName != name && oldName != legalName) {
// Rename any callers.
var blocks = this.getSourceBlock().workspace.getAllBlocks(false);
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].renameProcedure) {
blocks[i].renameProcedure(oldName, legalName);
}
}
}
return legalName;
};
/**
* Construct the blocks required by the flyout for the procedure category.
* @param {!Blockly.Workspace} workspace The workspace containing procedures.
* @return {!Array.<!Element>} Array of XML block elements.
*/
Procedures.flyoutCategory = function (workspace) {
var xmlList = [];
if (Blockly.Blocks['procedures_defnoreturn']) {
// <block type="procedures_defnoreturn" gap="16">
// <field name="NAME">do something</field>
// </block>
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'procedures_defnoreturn');
block.setAttribute('gap', 16);
var nameField = Blockly.utils.xml.createElement('field');
nameField.setAttribute('name', 'NAME');
nameField.appendChild(Blockly.utils.xml.createTextNode(
Blockly.Msg['PROCEDURES_DEFNORETURN_PROCEDURE']));
block.appendChild(nameField);
xmlList.push(block);
}
if (Blockly.Blocks['procedures_defreturn']) {
// <block type="procedures_defreturn" gap="16">
// <field name="NAME">do something</field>
// </block>
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'procedures_defreturn');
block.setAttribute('gap', 16);
var nameField = Blockly.utils.xml.createElement('field');
nameField.setAttribute('name', 'NAME');
nameField.appendChild(Blockly.utils.xml.createTextNode(
Blockly.Msg['PROCEDURES_DEFRETURN_PROCEDURE']));
block.appendChild(nameField);
xmlList.push(block);
}
if (Blockly.Blocks['procedures_return']) {
// <block type="procedures_return" gap="16"></block>
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'procedures_return');
block.setAttribute('gap', 16);
xmlList.push(block);
}
if (Blockly.Blocks['procedures_ifreturn']) {
// <block type="procedures_ifreturn" gap="16"></block>
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'procedures_ifreturn');
block.setAttribute('gap', 16);
xmlList.push(block);
}
if (xmlList.length) {
// Add slightly larger gap between system blocks and user calls.
xmlList[xmlList.length - 1].setAttribute('gap', 24);
}
function populateProcedures(procedureList, templateName) {
for (var i = 0; i < procedureList.length; i++) {
var name = procedureList[i][0];
var args = procedureList[i][1];
// <block type="procedures_callnoreturn" gap="16">
// <mutation name="do something">
// <arg name="x"></arg>
// </mutation>
// </block>
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', templateName);
block.setAttribute('gap', 16);
var mutation = Blockly.utils.xml.createElement('mutation');
mutation.setAttribute('name', name);
block.appendChild(mutation);
for (var j = 0; j < args.length; j++) {
var arg = Blockly.utils.xml.createElement('arg');
arg.setAttribute('name', args[j]);
mutation.appendChild(arg);
}
xmlList.push(block);
}
}
var tuple = Procedures.allProcedures(workspace);
populateProcedures(tuple[0], 'procedures_callnoreturn');
populateProcedures(tuple[1], 'procedures_callreturn');
return xmlList;
};
/**
* Find all the callers of a named procedure.
* @param {string} name Name of procedure.
* @param {!Blockly.Workspace} workspace The workspace to find callers in.
* @return {!Array.<!Blockly.Block>} Array of caller blocks.
*/
Procedures.getCallers = function (name, workspace) {
var callers = [];
var blocks = workspace.getAllBlocks(false);
// Iterate through every block and check the name.
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].getProcedureCall) {
var procName = blocks[i].getProcedureCall();
// Procedure name may be null if the block is only half-built.
if (procName && Blockly.Names.equals(procName, name)) {
callers.push(blocks[i]);
}
}
}
return callers;
};
/**
* When a procedure definition changes its parameters, find and edit all its
* callers.
* @param {!Blockly.Block} defBlock Procedure definition block.
*/
Procedures.mutateCallers = function (defBlock) {
const oldRecordUndo = Blockly.Events.getRecordUndo();
const procedureBlock = defBlock;
const name = procedureBlock.getProcedureDef()[0];
const xmlElement = defBlock.mutationToDom(true);
const callers = Blockly.Procedures.getCallers(name, defBlock.workspace);
for (let i = 0, caller; (caller = callers[i]); i++) {
const oldMutationDom = caller.mutationToDom();
const oldMutation = oldMutationDom && Blockly.utils.xml.domToText(oldMutationDom);
if (caller.domToMutation) {
caller.domToMutation(xmlElement);
}
const newMutationDom = caller.mutationToDom();
const newMutation = newMutationDom && Blockly.utils.xml.domToText(newMutationDom);
if (oldMutation !== newMutation) {
// Fire a mutation on every caller block. But don't record this as an
// undo action since it is deterministically tied to the procedure's
// definition mutation.
Blockly.Events.setRecordUndo(false);
Blockly.Events.fire(
new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
caller,
'mutation',
null,
oldMutation,
newMutation,
),
);
Blockly.Events.setRecordUndo(oldRecordUndo);
}
}
};
/**
* Find the definition block for the named procedure.
* @param {string} name Name of procedure.
* @param {!Blockly.Workspace} workspace The workspace to search.
* @return {Blockly.Block} The procedure definition block, or null not found.
*/
Procedures.getDefinition = function (name, workspace) {
// Assume that a procedure definition is a top block.
var blocks = workspace.getTopBlocks(false);
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].getProcedureDef) {
var tuple = blocks[i].getProcedureDef();
if (tuple && Blockly.Names.equals(tuple[0], name)) {
return blocks[i];
}
}
}
return null;
};
export default Procedures;

View File

@@ -0,0 +1,248 @@
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Utility functions for handling variables.
* @author fraser@google.com (Neil Fraser)
*/
import * as Blockly from 'blockly/core';
const Variables = {};
/**
* Category to separate variable names from procedures and generated functions.
*/
Variables.NAME_TYPE = 'VARIABLE';
/**
* Find all user-created variables.
* @param {!Blockly.Block|!Blockly.Workspace} root Root block or workspace.
* @return {!Array.<string>} Array of variable names.
*/
Variables.allVariables = function (root) {
var blocks;
if (root.getDescendants) {
// Root is Block.
blocks = root.getDescendants();
} else if (root.getAllBlocks) {
// Root is Workspace.
blocks = root.getAllBlocks();
} else {
throw 'Not Block or Workspace: ' + root;
}
var variableHash = Object.create(null);
// Iterate through every block and add each variable to the hash.
for (var x = 0; x < blocks.length; x++) {
var blockVariables = blocks[x].getVars();
for (var y = 0; y < blockVariables.length; y++) {
var varName = blockVariables[y];
// Variable name may be null if the block is only half-built.
if (varName) {
variableHash[varName] = varName;
}
}
}
// Flatten the hash into a list.
var variableList = [];
for (var name in variableHash) {
variableList.push(variableHash[name]);
}
return variableList;
};
/**
* Find all instances of the specified variable and rename them.
* @param {string} oldName Variable to rename.
* @param {string} newName New variable name.
* @param {!Blockly.Workspace} workspace Workspace rename variables in.
*/
Variables.renameVariable = function (oldName, newName, workspace) {
Blockly.Events.setGroup(true);
var blocks = workspace.getAllBlocks();
// Iterate through every block.
for (var i = 0; i < blocks.length; i++) {
blocks[i].renameVar(oldName, newName);
}
Blockly.Events.setGroup(false);
};
/**
* Construct the blocks required by the flyout for the variable category.
* @param {!Blockly.Workspace} workspace The workspace contianing variables.
* @return {!Array.<!Element>} Array of XML block elements.
*/
Variables.flyoutCategory = function (workspace) {
var variableList = Variables.allVariables(workspace);
//variableList.sort(goog.string.caseInsensitiveCompare);
// In addition to the user's variables, we also want to display the default
// variable name at the top. We also don't want this duplicated if the
// user has created a variable of the same name.
// alert(variableList)
// goog.array.remove(variableList, Blockly.Msg.VARIABLES_DEFAULT_NAME);
// variableList.unshift(Blockly.Msg.VARIABLES_DEFAULT_NAME);
var xmlList = [];
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_global');
xmlList.push(block);
if (Blockly.Blocks['variables_set']) {
//增加variables_declare模块
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_set');
xmlList.push(block);
}//change tyep
/*
if (Blockly.Blocks['variables_change']) {
//增加variables_declare模块
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_change');
xmlList.push(block);
}*/
if (Blockly.Blocks['variables_change']) {
//增加variables_declare模块
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_change');
xmlList.push(block);
}
if (Blockly.Blocks['controls_type']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'controls_type');
xmlList.push(block);
}
if (Blockly.Blocks['controls_typeLists']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'controls_typeLists');
xmlList.push(block);
}
if (Blockly.Blocks['lists_zip']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'lists_zip');
block.setAttribute('inline', 'false');
var mutation = Blockly.utils.xml.createElement('mutation');
mutation.setAttribute('items', 2);
block.appendChild(mutation);
for (let i = 0; i < 2; i++) {
let add = Blockly.utils.xml.createElement('value');
add.setAttribute('name', `ADD${i}`);
// let childBlock = Blockly.utils.xml.createElement('block');
// childBlock.setAttribute('type', 'list_many_input');
// let field = Blockly.utils.xml.createElement('field');
// let value = Blockly.utils.xml.createTextNode('0,1,2,3');
// field.setAttribute('name', 'CONTENT');
// field.appendChild(value);
// childBlock.appendChild(field);
// add.appendChild(childBlock);
block.appendChild(add);
}
xmlList.push(block);
}
if (Blockly.Blocks['unpack_iterable_object']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'unpack_iterable_object');
xmlList.push(block);
}
for (var i = 0; i < variableList.length; i++) {
// alert(variableList)
// if(i==0&& !(Blockly.Python.setups_['variables_set'+''])){
// continue;
// }
if (Blockly.Blocks['variables_set']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_set');
if (Blockly.Blocks['variables_get']) {
block.setAttribute('gap', 8);
}
var field = Blockly.utils.xml.createElement('field', null, variableList[i]);
field.setAttribute('name', 'VAR');
var name = Blockly.utils.xml.createTextNode(variableList[i]);
field.appendChild(name);
block.appendChild(field);
xmlList.push(block);
}
if (Blockly.Blocks['variables_get']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_get');
if (Blockly.Blocks['variables_set']) {
block.setAttribute('gap', 24);
}
var field = Blockly.utils.xml.createElement('field', null, variableList[i]);
field.setAttribute('name', 'VAR');
var name = Blockly.utils.xml.createTextNode(variableList[i]);
field.appendChild(name);
block.appendChild(field);
xmlList.push(block);
}
}
return xmlList;
};
/**
* Return a new variable name that is not yet being used. This will try to
* generate single letter variable names in the range 'i' to 'z' to start with.
* If no unique name is located it will try 'i' to 'z', 'a' to 'h',
* then 'i2' to 'z2' etc. Skip 'l'.
* @param {!Blockly.Workspace} workspace The workspace to be unique in.
* @return {string} New variable name.
*/
Variables.generateUniqueName = function (workspace) {
var variableList = Variables.allVariables(workspace);
var newName = '';
if (variableList.length) {
var nameSuffix = 1;
var letters = 'ijkmnopqrstuvwxyzabcdefgh'; // No 'l'.
var letterIndex = 0;
var potName = letters.charAt(letterIndex);
while (!newName) {
var inUse = false;
for (var i = 0; i < variableList.length; i++) {
if (variableList[i] == potName) {
// This potential name is already used.
inUse = true;
break;
}
}
if (inUse) {
// Try the next potential name.
letterIndex++;
if (letterIndex == letters.length) {
// Reached the end of the character sequence so back to 'i'.
// a new suffix.
letterIndex = 0;
nameSuffix++;
}
potName = letters.charAt(letterIndex);
if (nameSuffix > 1) {
potName += nameSuffix;
}
} else {
// We can use the current potential name.
newName = potName;
}
}
} else {
newName = 'i';
}
return newName;
};
export default Variables;

View File

@@ -0,0 +1,32 @@
{
"name": "@mixly/python",
"version": "1.4.0",
"description": "适用于mixly的python模块",
"scripts": {
"build:dev": "webpack --config=webpack.dev.js",
"build:prod": "npm run build:examples & webpack --config=webpack.prod.js",
"build:examples": "node ../../../scripts/build-examples.js -t special",
"build:examples:ob": "node ../../../scripts/build-examples.js -t special --obfuscate",
"publish:board": "npm publish --registry https://registry.npmjs.org/"
},
"main": "./export.js",
"author": "Mixly Team",
"keywords": [
"mixly",
"mixly-plugin",
"python"
],
"homepage": "https://gitee.com/bnu_mixly/mixly3/tree/master/boards/default_src/python",
"bugs": {
"url": "https://gitee.com/bnu_mixly/mixly3/issues"
},
"repository": {
"type": "git",
"url": "https://gitee.com/bnu_mixly/mixly3.git",
"directory": "default_src/python"
},
"publishConfig": {
"access": "public"
},
"license": "Apache 2.0"
}

View File

@@ -0,0 +1,329 @@
/*
Overrides for generic Python code generation.
*/
import * as Blockly from 'blockly/core';
import Names from './others/names';
/**
* Python code generator.
* @type {!Blockly.Generator}
*/
export const Python = new Blockly.Generator('Python');
Python.INDENT = " ";
/**
* List of illegal variable names.
* This is not intended to be a security feature. Blockly is 100% client-side,
* so bypassing this list is trivial. This is intended to prevent users from
* accidentally clobbering a built-in object or function.
* @private
*/
Python.addReservedWords(
// import keyword
// print(','.join(sorted(keyword.kwlist)))
// https://docs.python.org/3/reference/lexical_analysis.html#keywords
// https://docs.python.org/2/reference/lexical_analysis.html#keywords
'False,None,True,and,as,assert,break,class,continue,def,del,elif,else,' +
'except,exec,finally,for,from,global,if,import,in,is,lambda,nonlocal,not,' +
'or,pass,print,raise,return,try,while,with,yield,' +
// https://docs.python.org/3/library/constants.html
// https://docs.python.org/2/library/constants.html
'NotImplemented,Ellipsis,__debug__,quit,exit,copyright,license,credits,' +
// >>> print(','.join(sorted(dir(__builtins__))))
// https://docs.python.org/3/library/functions.html
// https://docs.python.org/2/library/functions.html
'ArithmeticError,AssertionError,AttributeError,BaseException,' +
'BlockingIOError,BrokenPipeError,BufferError,BytesWarning,' +
'ChildProcessError,ConnectionAbortedError,ConnectionError,' +
'ConnectionRefusedError,ConnectionResetError,DeprecationWarning,EOFError,' +
'Ellipsis,EnvironmentError,Exception,FileExistsError,FileNotFoundError,' +
'FloatingPointError,FutureWarning,GeneratorExit,IOError,ImportError,' +
'ImportWarning,IndentationError,IndexError,InterruptedError,' +
'IsADirectoryError,KeyError,KeyboardInterrupt,LookupError,MemoryError,' +
'ModuleNotFoundError,NameError,NotADirectoryError,NotImplemented,' +
'NotImplementedError,OSError,OverflowError,PendingDeprecationWarning,' +
'PermissionError,ProcessLookupError,RecursionError,ReferenceError,' +
'ResourceWarning,RuntimeError,RuntimeWarning,StandardError,' +
'StopAsyncIteration,StopIteration,SyntaxError,SyntaxWarning,SystemError,' +
'SystemExit,TabError,TimeoutError,TypeError,UnboundLocalError,' +
'UnicodeDecodeError,UnicodeEncodeError,UnicodeError,' +
'UnicodeTranslateError,UnicodeWarning,UserWarning,ValueError,Warning,' +
'ZeroDivisionError,_,__build_class__,__debug__,__doc__,__import__,' +
'__loader__,__name__,__package__,__spec__,abs,all,any,apply,ascii,' +
'basestring,bin,bool,buffer,bytearray,bytes,callable,chr,classmethod,cmp,' +
'coerce,compile,complex,copyright,credits,delattr,dict,dir,divmod,' +
'enumerate,eval,exec,execfile,exit,file,filter,float,format,frozenset,' +
'getattr,globals,hasattr,hash,help,hex,id,input,int,intern,isinstance,' +
'issubclass,iter,len,license,list,locals,long,map,max,memoryview,min,' +
'next,object,oct,open,ord,pow,print,property,quit,range,raw_input,reduce,' +
'reload,repr,reversed,round,set,setattr,slice,sorted,staticmethod,str,' +
'sum,super,tuple,type,unichr,unicode,vars,xrange,zip'
);
/**
* Order of operation ENUMs.
* http://docs.python.org/reference/expressions.html#summary
*/
Python.ORDER_ATOMIC = 0; // 0 "" ...
Python.ORDER_COLLECTION = 1; // tuples, lists, dictionaries
Python.ORDER_STRING_CONVERSION = 1; // `expression...`
Python.ORDER_UNARY_POSTFIX = 1; // expr++ expr-- () [] .
Python.ORDER_UNARY_PREFIX = 2; // -expr !expr ~expr ++expr --expr
Python.ORDER_MEMBER = 2.1; // . []
Python.ORDER_FUNCTION_CALL = 2.2; // ()
Python.ORDER_EXPONENTIATION = 3; // **
Python.ORDER_UNARY_SIGN = 4; // + -
Python.ORDER_BITWISE_NOT = 4; // ~
Python.ORDER_MULTIPLICATIVE = 5; // * / // %
Python.ORDER_ADDITIVE = 6; // + -
Python.ORDER_BITWISE_SHIFT = 7; // << >>
Python.ORDER_BITWISE_AND = 8; // &
Python.ORDER_BITWISE_XOR = 9; // ^
Python.ORDER_BITWISE_OR = 10; // |
Python.ORDER_RELATIONAL = 11; // in, not in, is, is not,
// <, <=, >, >=, <>, !=, ==
Python.ORDER_EQUALITY = 11; // == != === !==
Python.ORDER_LOGICAL_NOT = 12; // not
Python.ORDER_LOGICAL_AND = 13; // and
Python.ORDER_LOGICAL_OR = 14; // or
Python.ORDER_ASSIGNMENT = 14; // = *= /= ~/= %= += -= <<= >>= &= ^= |=
Python.ORDER_CONDITIONAL = 15; // if else
Python.ORDER_LAMBDA = 16; // lambda
Python.ORDER_NONE = 99; // (...)
/**
* List of outer-inner pairings that do NOT require parentheses.
* @type {!Array.<!Array.<number>>}
*/
Python.ORDER_OVERRIDES = [
// (foo()).bar -> foo().bar
// (foo())[0] -> foo()[0]
[Python.ORDER_FUNCTION_CALL, Python.ORDER_MEMBER],
// (foo())() -> foo()()
[Python.ORDER_FUNCTION_CALL, Python.ORDER_FUNCTION_CALL],
// (foo.bar).baz -> foo.bar.baz
// (foo.bar)[0] -> foo.bar[0]
// (foo[0]).bar -> foo[0].bar
// (foo[0])[1] -> foo[0][1]
[Python.ORDER_MEMBER, Python.ORDER_MEMBER],
// (foo.bar)() -> foo.bar()
// (foo[0])() -> foo[0]()
[Python.ORDER_MEMBER, Python.ORDER_FUNCTION_CALL],
// not (not foo) -> not not foo
// [Python.ORDER_LOGICAL_NOT, Python.ORDER_LOGICAL_NOT],
// a and (b and c) -> a and b and c
// [Python.ORDER_LOGICAL_AND, Python.ORDER_LOGICAL_AND],
// a or (b or c) -> a or b or c
// [Python.ORDER_LOGICAL_OR, Python.ORDER_LOGICAL_OR]
];
Python.init = function () {
/**
* Empty loops or conditionals are not allowed in Python.
*/
Python.PASS = this.INDENT + 'pass\n';
// Create a dictionary of definitions to be printed before the code.
Python.definitions_ = Object.create(null);
// Create a dictionary mapping desired function names in definitions_
// to actual function names (to avoid collisions with user functions).
Python.functionNames_ = Object.create(null);
Python.setups_ = Object.create(null);
Python.loops_ = Object.create(null);
Python.codeEnd_ = Object.create(null);
if (!Python.variableDB_) {
Python.variableDB_ = new Names(Python.RESERVED_WORDS_);
} else {
Python.variableDB_.reset();
}
}
Python.finish = function (code) {
// Convert the definitions dictionary into a list.
if (code !== "") {
code = code.replace(/\n/g, '\n');
code = code.replace(/\n\s+$/, '\n');
}
var imports = [];
var definitions_var = []; //变量定义
var definitions_fun = []; //函数定义
for (var name in this.definitions_) {
var def = this.definitions_[name];
if (name.indexOf('import') === 0) {
imports.push(def);
} else if (name.indexOf('var_declare') === 0) {
definitions_var.push(def);
} else {
definitions_fun.push(def);
}
}
if (imports.length) {
imports.push('\n\n');
}
if (definitions_var.length) {
definitions_var.push('\n\n');
}
if (definitions_fun.length) {
definitions_fun.push('\n\n');
}
var functions = [];
for (var name in Python.functions_) {
functions.push(Python.functions_[name]);
}
if (functions.length) {
functions.push('\n\n');
}
var setups = [];
for (var name in Python.setups_) {
setups.push(Python.setups_[name]);
}
if (setups.length) {
setups.push('\n\n');
}
var loops = [];
for (var name in Python.loops_) {
loops.push(Python.loops_[name]);
}
var codeEnd = [];
for (var name in Python.codeEnd_) {
codeEnd.push(Python.codeEnd_[name]);
}
if (codeEnd.length !== 0) {
codeEnd.push('\n');
}
if (loops.length > 0) {
return imports.join('\n') + definitions_var.join('\n') + definitions_fun.join('\n')
+ functions.join('\n') + setups.join('') + code + 'while True:\n' + loops.join('') + codeEnd.join('\n');
}
return imports.join('\n') + definitions_var.join('\n') + definitions_fun.join('\n')
+ functions.join('\n') + setups.join('') + code + codeEnd.join('\n');
}
/**
* Naked values are top-level blocks with outputs that aren't plugged into
* anything.
* @param {string} line Line of generated code.
* @return {string} Legal line of code.
*/
Python.scrubNakedValue = function (line) {
return line + '\n';
}
/**
* Encode a string as a properly escaped Python string, complete with quotes.
* @param {string} string Text to encode.
* @return {string} Python string.
* @private
*/
Python.quote_ = function (string) {
// Can't use goog.string.quote since % must also be escaped.
// string = string.replace(/\\/g, '\\\\')
// .replace(/\n/g, '\\\n');
// Follow the CPython behaviour of repr() for a non-byte string.
var quote = '\'';
if (string.indexOf('\'') !== -1) {
if (string.indexOf('"') === -1) {
quote = '"';
} else {
string = string.replace(/'/g, '\\\'');
}
}
return quote + string + quote;
}
/**
* Encode a string as a properly escaped multiline Python string, complete
* with quotes.
* @param {string} string Text to encode.
* @return {string} Python string.
* @private
*/
Python.multiline_quote_ = function (string) {
// Can't use goog.string.quote since % must also be escaped.
string = string.replace(/'''/g, '\\\'\\\'\\\'');
return '\'\'\'' + string + '\'\'\'';
}
/**
* Common tasks for generating Python from blocks.
* Handles comments for the specified block and any connected value blocks.
* Calls any statements following this block.
* @param {!Blockly.Block} block The current block.
* @param {string} code The Python code created for this block.
* @param {boolean=} opt_thisOnly True to generate code for only this statement.
* @return {string} Python code with comments and subsequent blocks added.
* @private
*/
Python.scrub_ = function (block, code, opt_thisOnly) {
var commentCode = '';
// Only collect comments for blocks that aren't inline.
if (!block.outputConnection || !block.outputConnection.targetConnection) {
// Collect comment for this block.
var comment = block.getCommentText();
if (comment) {
comment = Blockly.utils.string.wrap(comment,
Python.COMMENT_WRAP - 3);
commentCode += Python.prefixLines(comment + '\n', '# ');
}
// Collect comments for all value arguments.
// Don't collect comments for nested statements.
for (var i = 0; i < block.inputList.length; i++) {
if (block.inputList[i].type == Blockly.INPUT_VALUE) {
var childBlock = block.inputList[i].connection.targetBlock();
if (childBlock) {
var comment = Python.allNestedComments(childBlock);
if (comment) {
commentCode += Python.prefixLines(comment, '# ');
}
}
}
}
}
var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
var nextCode = opt_thisOnly ? '' : Python.blockToCode(nextBlock);
return commentCode + code + nextCode;
}
/**
* Gets a property and adjusts the value, taking into account indexing, and
* casts to an integer.
* @param {!Blockly.Block} block The block.
* @param {string} atId The property ID of the element to get.
* @param {number=} opt_delta Value to add.
* @param {boolean=} opt_negate Whether to negate the value.
* @return {string|number}
*/
Python.getAdjustedInt = function (block, atId, opt_delta, opt_negate) {
var delta = opt_delta || 0;
if (block.workspace.options.oneBasedIndex) {
delta--;
}
var defaultAtIndex = block.workspace.options.oneBasedIndex ? '1' : '0';
var atOrder = delta ? Python.ORDER_ADDITIVE :
Python.ORDER_NONE;
var at = Python.valueToCode(block, atId, atOrder) || defaultAtIndex;
if (Blockly.isNumber(at)) {
// If the index is a naked number, adjust it right now.
at = parseInt(at, 10) + delta;
if (opt_negate) {
at = -at;
}
} else {
// If the index is dynamic, adjust it in code.
if (delta > 0) {
at = 'int(' + at + ' + ' + delta + ')';
} else if (delta < 0) {
at = 'int(' + at + ' - ' + -delta + ')';
} else {
at = 'int(' + at + ')';
}
if (opt_negate) {
at = '-' + at;
}
}
return at;
}

View File

@@ -0,0 +1,21 @@
const path = require("path");
const common = require("../../../webpack.common");
const { merge } = require("webpack-merge");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = merge(common, {
mode: "development",
devtool: 'source-map',
plugins: [
new ESLintPlugin({
context: process.cwd(),
}),
new HtmlWebpackPlugin({
inject: false,
template: path.resolve(process.cwd(), 'template.xml'),
filename: 'index.xml',
minify: false
}),
]
});

View File

@@ -0,0 +1,27 @@
const path = require("path");
const common = require("../../../webpack.common");
const { merge } = require("webpack-merge");
const TerserPlugin = require("terser-webpack-plugin");
var HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = merge(common, {
mode: "production",
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: false,
}),
new HtmlWebpackPlugin({
inject: false,
template: path.resolve(process.cwd(), 'template.xml'),
filename: 'index.xml',
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true,
}
})
]
}
});