初始化提交
This commit is contained in:
3
boards/default_src/python/.npmignore
Normal file
3
boards/default_src/python/.npmignore
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
build
|
||||
origin
|
||||
1163
boards/default_src/python/blocks/class.js
Normal file
1163
boards/default_src/python/blocks/class.js
Normal file
File diff suppressed because it is too large
Load Diff
993
boards/default_src/python/blocks/control.js
Normal file
993
boards/default_src/python/blocks/control.js
Normal file
@@ -0,0 +1,993 @@
|
||||
import * as Blockly from 'blockly/core';
|
||||
|
||||
const LOOPS_HUE = 120;
|
||||
|
||||
export const controls_main = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_NAME_MAIN);
|
||||
this.appendStatementInput('DO')
|
||||
.appendField('');
|
||||
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_SETUP);
|
||||
}
|
||||
};
|
||||
|
||||
export const base_setup = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.MIXLY_SETUP);
|
||||
this.appendStatementInput('DO')
|
||||
.appendField('');
|
||||
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_SETUP);
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_delay = {
|
||||
init: function () {
|
||||
var UNIT = [
|
||||
[Blockly.Msg.MIXLY_mSecond, 'delay'],
|
||||
[Blockly.Msg.MIXLY_uSecond, 'delayMicroseconds']
|
||||
];
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendValueInput("DELAY_TIME", Number)
|
||||
.appendField(Blockly.Msg.MIXLY_DELAY)
|
||||
.appendField(new Blockly.FieldDropdown(UNIT), 'UNIT')
|
||||
.setCheck(Number);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setInputsInline(true);
|
||||
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_CONTROL_DELAY);
|
||||
this.setHelpUrl("https://mixly.readthedocs.io/zh_CN/latest/arduino/03.Control.html#id9");
|
||||
this.wiki = {
|
||||
'zh-hans': {
|
||||
page: ['Arduino AVR', '控制', '延时']
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_end_program = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.MIXLY_CONTROL_END_PROGRAM);
|
||||
this.setPreviousStatement(true);
|
||||
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_CONTROL_END_TOOLTIP);
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_if = {
|
||||
/**
|
||||
* Block for if/elseif/else condition.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
//this.setHelpUrl(Blockly.Msg.CONTROLS_IF_HELPURL);
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendValueInput('IF0')
|
||||
.setCheck([Boolean, Number])
|
||||
.appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);
|
||||
this.appendStatementInput('DO0')
|
||||
.appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.setHelpUrl("https://mixly.readthedocs.io/zh_CN/latest/arduino/03.Control.html#if");
|
||||
this.setMutator(new Blockly.icons.MutatorIcon(['controls_if_elseif',
|
||||
'controls_if_else'], this));
|
||||
// Assign 'this' to a variable for use in the tooltip closure below.
|
||||
var thisBlock = this;
|
||||
this.setTooltip(function () {
|
||||
if (!thisBlock.elseifCount_ && !thisBlock.elseCount_) {
|
||||
return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;
|
||||
} else if (!thisBlock.elseifCount_ && thisBlock.elseCount_) {
|
||||
return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;
|
||||
} else if (thisBlock.elseifCount_ && !thisBlock.elseCount_) {
|
||||
return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;
|
||||
} else if (thisBlock.elseifCount_ && thisBlock.elseCount_) {
|
||||
return Blockly.Msg.CONTROLS_IF_TOOLTIP_4;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
this.elseifCount_ = 0;
|
||||
this.elseCount_ = 0;
|
||||
},
|
||||
/**
|
||||
* Create XML to represent the number of else-if and else inputs.
|
||||
* @return {Element} XML storage element.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function () {
|
||||
if (!this.elseifCount_ && !this.elseCount_) {
|
||||
return null;
|
||||
}
|
||||
var container = document.createElement('mutation');
|
||||
if (this.elseifCount_) {
|
||||
container.setAttribute('elseif', this.elseifCount_);
|
||||
}
|
||||
if (this.elseCount_) {
|
||||
container.setAttribute('else', 1);
|
||||
}
|
||||
return container;
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the else-if and else inputs.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
domToMutation: function (xmlElement) {
|
||||
var containerBlock = this;
|
||||
var valueConnections = [];
|
||||
var statementConnections = [];
|
||||
// var elseStatementConnection = null;
|
||||
if (this.elseCount_) {
|
||||
// if (containerBlock.getInputTargetBlock('ELSE') && containerBlock.getInputTargetBlock('ELSE').previousConnection)
|
||||
// elseStatementConnection = containerBlock.getInputTargetBlock('ELSE').previousConnection;
|
||||
this.removeInput('ELSE');
|
||||
}
|
||||
for (var i = this.elseifCount_; i > 0; i--) {
|
||||
if (containerBlock.getInputTargetBlock('IF' + i) && containerBlock.getInputTargetBlock('IF' + i).previousConnection)
|
||||
valueConnections[i] = (containerBlock.getInputTargetBlock('IF' + i).previousConnection);
|
||||
else
|
||||
valueConnections[i] = null;
|
||||
this.removeInput('IF' + i);
|
||||
if (containerBlock.getInputTargetBlock('DO' + i) && containerBlock.getInputTargetBlock('DO' + i).previousConnection)
|
||||
statementConnections[i] = (containerBlock.getInputTargetBlock('DO' + i).previousConnection);
|
||||
else
|
||||
statementConnections[i] = null;
|
||||
this.removeInput('DO' + i);
|
||||
}
|
||||
this.elseifCount_ = parseInt(xmlElement.getAttribute('elseif'), 10);
|
||||
this.elseCount_ = parseInt(xmlElement.getAttribute('else'), 10);
|
||||
//this.compose(containerBlock);
|
||||
for (var i = 1; i <= this.elseifCount_; i++) {
|
||||
this.appendValueInput('IF' + i)
|
||||
.setCheck([Boolean, Number])
|
||||
.appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF);
|
||||
this.appendStatementInput('DO' + i)
|
||||
.appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
|
||||
}
|
||||
if (this.elseCount_) {
|
||||
this.appendStatementInput('ELSE')
|
||||
.appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE);
|
||||
}
|
||||
for (var i = valueConnections.length - 2; i > 0; i--) {
|
||||
if (valueConnections[i])
|
||||
valueConnections[i].reconnect(this, 'IF' + i);
|
||||
}
|
||||
for (var i = statementConnections.length - 2; i > 0; i--) {
|
||||
if (statementConnections[i])
|
||||
statementConnections[i].reconnect(this, 'DO' + i);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 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('controls_if_if');
|
||||
containerBlock.initSvg();
|
||||
var connection = containerBlock.getInput('STACK').connection;
|
||||
for (var i = 1; i <= this.elseifCount_; i++) {
|
||||
var elseifBlock = workspace.newBlock('controls_if_elseif');
|
||||
elseifBlock.initSvg();
|
||||
connection.connect(elseifBlock.previousConnection);
|
||||
connection = elseifBlock.nextConnection;
|
||||
}
|
||||
if (this.elseCount_) {
|
||||
var elseBlock = workspace.newBlock('controls_if_else');
|
||||
elseBlock.initSvg();
|
||||
connection.connect(elseBlock.previousConnection);
|
||||
}
|
||||
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) {
|
||||
// Disconnect the else input blocks and remove the inputs.
|
||||
if (this.elseCount_) {
|
||||
this.removeInput('ELSE');
|
||||
}
|
||||
this.elseCount_ = 0;
|
||||
// Disconnect all the elseif input blocks and remove the inputs.
|
||||
for (var i = this.elseifCount_; i > 0; i--) {
|
||||
this.removeInput('IF' + i);
|
||||
this.removeInput('DO' + i);
|
||||
}
|
||||
this.elseifCount_ = 0;
|
||||
// Rebuild the block's optional inputs.
|
||||
var clauseBlock = containerBlock.getInputTargetBlock('STACK');
|
||||
var valueConnections = [null];
|
||||
var statementConnections = [null];
|
||||
var elseStatementConnection = null;
|
||||
while (clauseBlock) {
|
||||
switch (clauseBlock.type) {
|
||||
case 'controls_if_elseif':
|
||||
this.elseifCount_++;
|
||||
valueConnections.push(clauseBlock.valueConnection_);
|
||||
statementConnections.push(clauseBlock.statementConnection_);
|
||||
break;
|
||||
case 'controls_if_else':
|
||||
this.elseCount_++;
|
||||
elseStatementConnection = clauseBlock.statementConnection_;
|
||||
break;
|
||||
default:
|
||||
throw Error('Unknown block type: ' + clauseBlock.type);
|
||||
}
|
||||
clauseBlock = clauseBlock.nextConnection &&
|
||||
clauseBlock.nextConnection.targetBlock();
|
||||
}
|
||||
|
||||
this.updateShape_();
|
||||
// Reconnect any child blocks.
|
||||
this.reconnectChildBlocks_(valueConnections, statementConnections, elseStatementConnection);
|
||||
|
||||
},
|
||||
/**
|
||||
* Store pointers to any connected child blocks.
|
||||
* @param {!Blockly.Block} containerBlock Root block in mutator.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
saveConnections: function (containerBlock) {
|
||||
var clauseBlock = containerBlock.getInputTargetBlock('STACK');
|
||||
var i = 1;
|
||||
while (clauseBlock) {
|
||||
switch (clauseBlock.type) {
|
||||
case 'controls_if_elseif':
|
||||
var inputIf = this.getInput('IF' + i);
|
||||
var inputDo = this.getInput('DO' + i);
|
||||
clauseBlock.valueConnection_ =
|
||||
inputIf && inputIf.connection.targetConnection;
|
||||
clauseBlock.statementConnection_ =
|
||||
inputDo && inputDo.connection.targetConnection;
|
||||
i++;
|
||||
break;
|
||||
case 'controls_if_else':
|
||||
var inputDo = this.getInput('ELSE');
|
||||
clauseBlock.statementConnection_ =
|
||||
inputDo && inputDo.connection.targetConnection;
|
||||
break;
|
||||
default:
|
||||
throw 'Unknown block type.';
|
||||
}
|
||||
clauseBlock = clauseBlock.nextConnection &&
|
||||
clauseBlock.nextConnection.targetBlock();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Reconstructs the block with all child blocks attached.
|
||||
*/
|
||||
rebuildShape_: function () {
|
||||
var valueConnections = [null];
|
||||
var statementConnections = [null];
|
||||
var elseStatementConnection = null;
|
||||
|
||||
if (this.getInput('ELSE')) {
|
||||
elseStatementConnection = this.getInput('ELSE').connection.targetConnection;
|
||||
}
|
||||
var i = 1;
|
||||
while (this.getInput('IF' + i)) {
|
||||
var inputIf = this.getInput('IF' + i);
|
||||
var inputDo = this.getInput('DO' + i);
|
||||
console.log(inputIf.connection.targetConnection);
|
||||
valueConnections.push(inputIf.connection.targetConnection);
|
||||
statementConnections.push(inputDo.connection.targetConnection);
|
||||
i++;
|
||||
}
|
||||
this.updateShape_();
|
||||
this.reconnectChildBlocks_(valueConnections, statementConnections, elseStatementConnection);
|
||||
},
|
||||
/**
|
||||
* Modify this block to have the correct number of inputs.
|
||||
* @this Blockly.Block
|
||||
* @private
|
||||
*/
|
||||
updateShape_: function () {
|
||||
// Delete everything.
|
||||
if (this.getInput('ELSE')) {
|
||||
this.removeInput('ELSE');
|
||||
}
|
||||
var i = 1;
|
||||
while (this.getInput('IF' + i)) {
|
||||
this.removeInput('IF' + i);
|
||||
this.removeInput('DO' + i);
|
||||
i++;
|
||||
}
|
||||
// Rebuild block.
|
||||
for (var i = 1; i <= this.elseifCount_; i++) {
|
||||
this.appendValueInput('IF' + i)
|
||||
.setCheck([Number, Boolean])
|
||||
.appendField(Blockly.Msg['CONTROLS_IF_MSG_ELSEIF']);
|
||||
this.appendStatementInput('DO' + i)
|
||||
.appendField(Blockly.Msg['CONTROLS_IF_MSG_THEN']);
|
||||
}
|
||||
if (this.elseCount_) {
|
||||
this.appendStatementInput('ELSE')
|
||||
.appendField(Blockly.Msg['CONTROLS_IF_MSG_ELSE']);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Reconnects child blocks.
|
||||
* @param {!Array<?Blockly.RenderedConnection>} valueConnections List of value
|
||||
* connectsions for if input.
|
||||
* @param {!Array<?Blockly.RenderedConnection>} statementConnections List of
|
||||
* statement connections for do input.
|
||||
* @param {?Blockly.RenderedConnection} elseStatementConnection Statement
|
||||
* connection for else input.
|
||||
*/
|
||||
reconnectChildBlocks_: function (valueConnections, statementConnections,
|
||||
elseStatementConnection) {
|
||||
for (var i = 1; i <= this.elseifCount_; i++) {
|
||||
valueConnections[i] && valueConnections[i].reconnect(this, 'IF' + i);
|
||||
statementConnections[i] && statementConnections[i].reconnect(this, 'DO' + i);
|
||||
}
|
||||
elseStatementConnection && elseStatementConnection.reconnect(this, 'ELSE');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const controls_range = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendValueInput('FROM')
|
||||
.setCheck(Number)
|
||||
.setAlign(Blockly.inputs.Align.RIGHT)
|
||||
.appendField(Blockly.Msg.PYTHON_RANGE)
|
||||
.appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_FROM);
|
||||
this.appendValueInput('TO')
|
||||
.setCheck(Number)
|
||||
.setAlign(Blockly.inputs.Align.RIGHT)
|
||||
.appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_TO);
|
||||
this.appendValueInput('STEP')
|
||||
.setCheck(Number)
|
||||
.setAlign(Blockly.inputs.Align.RIGHT)
|
||||
.appendField(Blockly.Msg.PYTHON_RANGE_STEP);
|
||||
this.setInputsInline(true);
|
||||
this.setOutput(true);
|
||||
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_CONTROLS_RANGE_TOOLTIP);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const controls_forEach = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendValueInput('LIST')
|
||||
.setAlign(Blockly.inputs.Align.RIGHT)
|
||||
.appendField(Blockly.Msg.CONTROLS_FOREACH_INPUT);
|
||||
this.appendValueInput('VAR')
|
||||
.appendField(Blockly.Msg.CONTROLS_FOREACH_INPUT_ITEM)
|
||||
// .appendField(new Blockly.FieldTextInput('i'), 'VAR');
|
||||
this.appendStatementInput('DO')
|
||||
.appendField(Blockly.Msg.MIXLY_DO);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.setInputsInline(true);
|
||||
this.setTooltip(function () {
|
||||
return Blockly.Msg.CONTROLS_FOR_TOOLTIP.replace('“%1”', '');
|
||||
});
|
||||
},
|
||||
getVars: function () {
|
||||
return [this.getFieldValue('VAR')];
|
||||
},
|
||||
renameVar: function (oldName, newName) {
|
||||
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
|
||||
this.setTitleValue(newName, 'VAR');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_whileUntil = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendValueInput('BOOL')
|
||||
.setCheck([Boolean, Number])
|
||||
.appendField(Blockly.Msg.MIXLY_MICROBIT_JS_CURRENT)
|
||||
.appendField(new Blockly.FieldDropdown(this.OPERATORS), 'MODE')
|
||||
// this.appendDummyInput()
|
||||
// .appendField(Blockly.Msg.CONTROLS_WHILE_SHI);
|
||||
this.appendStatementInput('DO')
|
||||
.appendField(Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_TITLE_REPEAT + Blockly.Msg.MIXLY_DO);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
var thisBlock = this;
|
||||
this.setTooltip(function () {
|
||||
var op = thisBlock.getFieldValue('MODE');
|
||||
var TOOLTIPS = {
|
||||
'WHILE': Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE,
|
||||
'UNTIL': Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL
|
||||
};
|
||||
return TOOLTIPS[op];
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_try_finally = {
|
||||
/**
|
||||
* Block for if/elseif/else condition.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_TRY);
|
||||
this.appendStatementInput('try');
|
||||
this.appendValueInput('IF1')
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_EXCEPT);
|
||||
this.appendStatementInput('DO1')
|
||||
.appendField('');
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.setMutator(new Blockly.icons.MutatorIcon(['controls_except', 'controls_finally'], this));
|
||||
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_CONTROL_TRY_TOOLTIP);
|
||||
this.elseifCount_ = 1;
|
||||
this.elseCount_ = 0;
|
||||
},
|
||||
/**
|
||||
* Create XML to represent the number of else-if and else inputs.
|
||||
* @return {Element} XML storage element.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function () {
|
||||
if (!this.elseifCount_ && !this.elseCount_) {
|
||||
return null;
|
||||
}
|
||||
var container = document.createElement('mutation');
|
||||
if (this.elseifCount_) {
|
||||
container.setAttribute('elseif', this.elseifCount_);
|
||||
}
|
||||
if (this.elseCount_) {
|
||||
container.setAttribute('else', 1);
|
||||
}
|
||||
return container;
|
||||
},
|
||||
/**
|
||||
* Parse XML to restore the else-if and else inputs.
|
||||
* @param {!Element} xmlElement XML storage element.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
domToMutation: function (xmlElement) {
|
||||
var containerBlock = this;
|
||||
var valueConnections = [];
|
||||
var statementConnections = [];
|
||||
// var elseStatementConnection = null;
|
||||
if (this.elseCount_) {
|
||||
// if (containerBlock.getInputTargetBlock('ELSE') && containerBlock.getInputTargetBlock('ELSE').previousConnection)
|
||||
// elseStatementConnection = containerBlock.getInputTargetBlock('ELSE').previousConnection;
|
||||
this.removeInput('ELSE');
|
||||
}
|
||||
for (var i = this.elseifCount_; i > 0; i--) {
|
||||
if (containerBlock.getInputTargetBlock('IF' + i) && containerBlock.getInputTargetBlock('IF' + i).previousConnection)
|
||||
valueConnections[i] = (containerBlock.getInputTargetBlock('IF' + i).previousConnection);
|
||||
else
|
||||
valueConnections[i] = null;
|
||||
this.removeInput('IF' + i);
|
||||
if (containerBlock.getInputTargetBlock('DO' + i) && containerBlock.getInputTargetBlock('DO' + i).previousConnection)
|
||||
statementConnections[i] = (containerBlock.getInputTargetBlock('DO' + i).previousConnection);
|
||||
else
|
||||
statementConnections[i] = null;
|
||||
this.removeInput('DO' + i);
|
||||
}
|
||||
this.elseifCount_ = parseInt(xmlElement.getAttribute('elseif'), 10);
|
||||
this.elseCount_ = parseInt(xmlElement.getAttribute('else'), 10);
|
||||
//this.compose(containerBlock);
|
||||
for (var i = 1; i <= this.elseifCount_; i++) {
|
||||
this.appendValueInput('IF' + i)
|
||||
.setCheck([Boolean, Number])
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_EXCEPT);
|
||||
this.appendStatementInput('DO' + i)
|
||||
.appendField("");
|
||||
}
|
||||
if (this.elseCount_) {
|
||||
this.appendStatementInput('ELSE')
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_FINALLY);
|
||||
}
|
||||
for (var i = valueConnections.length - 2; i > 0; i--) {
|
||||
if (valueConnections[i])
|
||||
valueConnections[i].reconnect(this, 'IF' + i);
|
||||
}
|
||||
for (var i = statementConnections.length - 2; i > 0; i--) {
|
||||
if (statementConnections[i])
|
||||
statementConnections[i].reconnect(this, 'DO' + i);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 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('controls_try');
|
||||
containerBlock.initSvg();
|
||||
var connection = containerBlock.getInput('STACK').connection;
|
||||
for (var i = 1; i <= this.elseifCount_; i++) {
|
||||
var elseifBlock = workspace.newBlock('controls_except');
|
||||
elseifBlock.initSvg();
|
||||
connection.connect(elseifBlock.previousConnection);
|
||||
connection = elseifBlock.nextConnection;
|
||||
}
|
||||
if (this.elseCount_) {
|
||||
var elseBlock = workspace.newBlock('controls_finally');
|
||||
elseBlock.initSvg();
|
||||
connection.connect(elseBlock.previousConnection);
|
||||
}
|
||||
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) {
|
||||
// Disconnect the else input blocks and remove the inputs.
|
||||
if (this.elseCount_) {
|
||||
this.removeInput('ELSE');
|
||||
}
|
||||
this.elseCount_ = 0;
|
||||
// Disconnect all the elseif input blocks and remove the inputs.
|
||||
for (var i = this.elseifCount_; i > 0; i--) {
|
||||
this.removeInput('IF' + i);
|
||||
this.removeInput('DO' + i);
|
||||
}
|
||||
this.elseifCount_ = 0;
|
||||
// Rebuild the block's optional inputs.
|
||||
var clauseBlock = containerBlock.getInputTargetBlock('STACK');
|
||||
var valueConnections = [null];
|
||||
var statementConnections = [null];
|
||||
var elseStatementConnection = null;
|
||||
while (clauseBlock) {
|
||||
switch (clauseBlock.type) {
|
||||
case 'controls_except':
|
||||
this.elseifCount_++;
|
||||
valueConnections.push(clauseBlock.valueConnection_);
|
||||
statementConnections.push(clauseBlock.statementConnection_);
|
||||
break;
|
||||
case 'controls_finally':
|
||||
this.elseCount_++;
|
||||
elseStatementConnection = clauseBlock.statementConnection_;
|
||||
break;
|
||||
default:
|
||||
throw Error('Unknown block type: ' + clauseBlock.type);
|
||||
}
|
||||
clauseBlock = clauseBlock.nextConnection &&
|
||||
clauseBlock.nextConnection.targetBlock();
|
||||
}
|
||||
|
||||
this.updateShape_();
|
||||
// Reconnect any child blocks.
|
||||
this.reconnectChildBlocks_(valueConnections, statementConnections, elseStatementConnection);
|
||||
|
||||
},
|
||||
/**
|
||||
* Store pointers to any connected child blocks.
|
||||
* @param {!Blockly.Block} containerBlock Root block in mutator.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
saveConnections: function (containerBlock) {
|
||||
var clauseBlock = containerBlock.getInputTargetBlock('STACK');
|
||||
var i = 1;
|
||||
while (clauseBlock) {
|
||||
switch (clauseBlock.type) {
|
||||
case 'controls_except':
|
||||
var inputIf = this.getInput('IF' + i);
|
||||
var inputDo = this.getInput('DO' + i);
|
||||
clauseBlock.valueConnection_ =
|
||||
inputIf && inputIf.connection.targetConnection;
|
||||
clauseBlock.statementConnection_ =
|
||||
inputDo && inputDo.connection.targetConnection;
|
||||
i++;
|
||||
break;
|
||||
case 'controls_finally':
|
||||
var inputDo = this.getInput('ELSE');
|
||||
clauseBlock.statementConnection_ =
|
||||
inputDo && inputDo.connection.targetConnection;
|
||||
break;
|
||||
default:
|
||||
throw 'Unknown block type.';
|
||||
}
|
||||
clauseBlock = clauseBlock.nextConnection &&
|
||||
clauseBlock.nextConnection.targetBlock();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Reconstructs the block with all child blocks attached.
|
||||
*/
|
||||
rebuildShape_: function () {
|
||||
var valueConnections = [null];
|
||||
var statementConnections = [null];
|
||||
var elseStatementConnection = null;
|
||||
|
||||
if (this.getInput('ELSE')) {
|
||||
elseStatementConnection = this.getInput('ELSE').connection.targetConnection;
|
||||
}
|
||||
var i = 1;
|
||||
while (this.getInput('IF' + i)) {
|
||||
var inputIf = this.getInput('IF' + i);
|
||||
var inputDo = this.getInput('DO' + i);
|
||||
console.log(inputIf.connection.targetConnection);
|
||||
valueConnections.push(inputIf.connection.targetConnection);
|
||||
statementConnections.push(inputDo.connection.targetConnection);
|
||||
i++;
|
||||
}
|
||||
this.updateShape_();
|
||||
this.reconnectChildBlocks_(valueConnections, statementConnections, elseStatementConnection);
|
||||
},
|
||||
/**
|
||||
* Modify this block to have the correct number of inputs.
|
||||
* @this Blockly.Block
|
||||
* @private
|
||||
*/
|
||||
updateShape_: function () {
|
||||
// Delete everything.
|
||||
if (this.getInput('ELSE')) {
|
||||
this.removeInput('ELSE');
|
||||
}
|
||||
var i = 1;
|
||||
while (this.getInput('IF' + i)) {
|
||||
this.removeInput('IF' + i);
|
||||
this.removeInput('DO' + i);
|
||||
i++;
|
||||
}
|
||||
// Rebuild block.
|
||||
for (var i = 1; i <= this.elseifCount_; i++) {
|
||||
this.appendValueInput('IF' + i)
|
||||
.setCheck([Number, Boolean])
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_EXCEPT);
|
||||
this.appendStatementInput('DO' + i)
|
||||
.appendField('');
|
||||
}
|
||||
if (this.elseCount_) {
|
||||
this.appendStatementInput('ELSE')
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_FINALLY);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Reconnects child blocks.
|
||||
* @param {!Array<?Blockly.RenderedConnection>} valueConnections List of value
|
||||
* connectsions for if input.
|
||||
* @param {!Array<?Blockly.RenderedConnection>} statementConnections List of
|
||||
* statement connections for do input.
|
||||
* @param {?Blockly.RenderedConnection} elseStatementConnection Statement
|
||||
* connection for else input.
|
||||
*/
|
||||
reconnectChildBlocks_: function (valueConnections, statementConnections,
|
||||
elseStatementConnection) {
|
||||
for (var i = 1; i <= this.elseifCount_; i++) {
|
||||
valueConnections[i] && valueConnections[i].reconnect(this, 'IF' + i);
|
||||
statementConnections[i] && statementConnections[i].reconnect(this, 'DO' + i);
|
||||
}
|
||||
elseStatementConnection && elseStatementConnection.reconnect(this, 'ELSE');
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_flow_statements = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
var dropdown = new Blockly.FieldDropdown(this.OPERATORS);
|
||||
this.appendDummyInput()
|
||||
.appendField(dropdown, 'FLOW')
|
||||
.appendField(Blockly.Msg.LANG_CONTROLS_FLOW_STATEMENTS_INPUT_OFLOOP);
|
||||
this.setPreviousStatement(true);
|
||||
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_CONTROLS_FLOW_STATEMENTS_TOOLTIP);
|
||||
var thisBlock = this;
|
||||
this.setTooltip(function () {
|
||||
var op = thisBlock.getFieldValue('FLOW');
|
||||
var TOOLTIPS = {
|
||||
'BREAK': Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK,
|
||||
'CONTINUE': Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE
|
||||
};
|
||||
return TOOLTIPS[op];
|
||||
});
|
||||
},
|
||||
onchange: function () {
|
||||
if (!this.workspace) {
|
||||
// Block has been deleted.
|
||||
return;
|
||||
}
|
||||
var legal = false;
|
||||
// Is the block nested in a control statement?
|
||||
var block = this;
|
||||
do {
|
||||
if (block.type == 'controls_repeat' ||
|
||||
block.type == 'controls_for' ||
|
||||
block.type == 'controls_forEach' ||
|
||||
block.type == 'controls_repeat_ext' ||
|
||||
block.type == 'controls_whileUntil' ||
|
||||
block.type == 'do_while') {
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
block = block.getSurroundParent();
|
||||
} while (block);
|
||||
if (legal) {
|
||||
this.setWarningText(null);
|
||||
} else {
|
||||
this.setWarningText(Blockly.Msg.LANG_CONTROLS_FLOW_STATEMENTS_WARNING);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const controls_for = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_WITH)
|
||||
.appendField(new Blockly.FieldTextInput('i'), 'VAR');
|
||||
this.appendValueInput('FROM')
|
||||
.setCheck(Number)
|
||||
.setAlign(Blockly.inputs.Align.RIGHT)
|
||||
.appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_FROM);
|
||||
this.appendValueInput('TO')
|
||||
.setCheck(Number)
|
||||
.setAlign(Blockly.inputs.Align.RIGHT)
|
||||
.appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_TO);
|
||||
this.appendValueInput('STEP')
|
||||
.setCheck(Number)
|
||||
.setAlign(Blockly.inputs.Align.RIGHT)
|
||||
.appendField(Blockly.Msg.MIXLY_STEP);
|
||||
this.appendStatementInput('DO')
|
||||
.appendField(Blockly.Msg.MIXLY_DO);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.setInputsInline(true);
|
||||
var thisBlock = this;
|
||||
this.setTooltip(function () {
|
||||
return Blockly.Msg.CONTROLS_FOR_TOOLTIP.replace('%1',
|
||||
thisBlock.getFieldValue('VAR'));
|
||||
});
|
||||
},
|
||||
getVars: function () {
|
||||
return [this.getFieldValue('VAR')];
|
||||
},
|
||||
renameVar: function (oldName, newName) {
|
||||
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
|
||||
this.setTitleValue(newName, 'VAR');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_for_range = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_WITH)
|
||||
.appendField(new Blockly.FieldTextInput('i'), 'VAR');
|
||||
this.appendValueInput('FROM')
|
||||
.setCheck(Number)
|
||||
.setAlign(Blockly.inputs.Align.RIGHT)
|
||||
.appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_FROM);
|
||||
this.appendValueInput('TO')
|
||||
.setCheck(Number)
|
||||
.setAlign(Blockly.inputs.Align.RIGHT)
|
||||
.appendField(Blockly.Msg.LANG_CONTROLS_FOR_INPUT_TO);
|
||||
this.appendValueInput('STEP')
|
||||
.setCheck(Number)
|
||||
.setAlign(Blockly.inputs.Align.RIGHT)
|
||||
.appendField(Blockly.Msg.MIXLY_STEP);
|
||||
this.appendStatementInput('DO')
|
||||
.appendField(Blockly.Msg.MIXLY_DO);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.setInputsInline(true);
|
||||
var thisBlock = this;
|
||||
this.setTooltip(function () {
|
||||
return Blockly.Msg.MIXLY_PYTHON_CONTROLS_FOR_RANGE_TOOLTIP.replace('%1',
|
||||
thisBlock.getFieldValue('VAR'));
|
||||
});
|
||||
},
|
||||
getVars: function () {
|
||||
return [this.getFieldValue('VAR')];
|
||||
},
|
||||
renameVar: function (oldName, newName) {
|
||||
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
|
||||
this.setTitleValue(newName, 'VAR');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
controls_whileUntil.OPERATORS =
|
||||
[[Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_OPERATOR_WHILE, 'WHILE'],
|
||||
[Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL, 'UNTIL']];
|
||||
|
||||
|
||||
|
||||
controls_flow_statements.OPERATORS =
|
||||
[[Blockly.Msg.LANG_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK, 'BREAK'],
|
||||
[Blockly.Msg.LANG_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE, 'CONTINUE']];
|
||||
|
||||
|
||||
|
||||
export const controls_if_if = {
|
||||
/**
|
||||
* Mutator block for if container.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.CONTROLS_IF_IF_TITLE_IF);
|
||||
this.appendStatementInput('STACK');
|
||||
this.setTooltip(Blockly.Msg.CONTROLS_IF_IF_TOOLTIP);
|
||||
this.contextMenu = false;
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_if_elseif = {
|
||||
/**
|
||||
* Mutator bolck for else-if condition.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.setTooltip(Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP);
|
||||
this.contextMenu = false;
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_if_else = {
|
||||
/**
|
||||
* Mutator block for else condition.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE);
|
||||
this.setPreviousStatement(true);
|
||||
this.setTooltip(Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP);
|
||||
this.contextMenu = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const controls_try = {
|
||||
/**
|
||||
* Mutator block for if container.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField('try');
|
||||
this.appendStatementInput('STACK');
|
||||
this.setPreviousStatement(false);
|
||||
this.setNextStatement(false);
|
||||
this.contextMenu = false;
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_except = {
|
||||
/**
|
||||
* Mutator bolck for else-if condition.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_EXCEPT);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.contextMenu = false;
|
||||
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_CONTROL_EXCEPT_TOOLTIP);
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_finally = {
|
||||
/**
|
||||
* Mutator block for else condition.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_FINALLY);
|
||||
this.setPreviousStatement(true);
|
||||
this.contextMenu = false;
|
||||
this.setTooltip(Blockly.Msg.MIXLY_MIXPY_CONTROL_FINALLY_TOOLTIP);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const controls_repeat_ext = {
|
||||
/**
|
||||
* Block for repeat n times (external number).
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.jsonInit({
|
||||
"message0": Blockly.Msg.CONTROLS_REPEAT_TITLE,
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "TIMES",
|
||||
// "check": "Number"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": LOOPS_HUE,
|
||||
"tooltip": Blockly.Msg.CONTROLS_REPEAT_TOOLTIP,
|
||||
"helpUrl": Blockly.Msg.CONTROLS_REPEAT_HELPURL
|
||||
});
|
||||
this.appendStatementInput('DO');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const controls_lambda = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendValueInput('BOOL')
|
||||
.appendField('lambda')
|
||||
//.appendField(new Blockly.FieldDropdown(this.OPERATORS), 'MODE');
|
||||
this.appendStatementInput('DO')
|
||||
.appendField(Blockly.Msg.MIXLY_STAT);
|
||||
this.setOutput(true);
|
||||
// this.setNextStatement(true);
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_pass = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_PASS);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_CONTROLS_PASS_TOOLTIP);
|
||||
}
|
||||
};
|
||||
|
||||
export const controls_thread = {
|
||||
init: function () {
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_CONTROLS_THREAD_START)
|
||||
this.appendValueInput('callback')
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_CONTROLS_THREAD_USE)
|
||||
this.appendValueInput('VAR')
|
||||
.appendField(Blockly.Msg.MIXLY_PARAMS);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.setInputsInline(true);
|
||||
this.setTooltip(Blockly.Msg.MIXLY_PYTHON_CONTROLS_THREAD_TOOLTIP);
|
||||
}
|
||||
};
|
||||
|
||||
//do-while循环
|
||||
export const do_while = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.CONTROLS_REPEAT_TITLE_REPEAT + Blockly.Msg.MIXLY_DO);
|
||||
this.appendStatementInput("input_data")
|
||||
.setCheck(null)
|
||||
this.appendValueInput("select_data")
|
||||
.setCheck(null)
|
||||
.appendField(Blockly.Msg.CONTROLS_OPERATOR_UNTIL)
|
||||
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_OPERATOR_WHILE, "true"], [Blockly.Msg.LANG_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL, "false"]]), "type");
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(LOOPS_HUE);
|
||||
this.setTooltip("do-while loop");
|
||||
this.setHelpUrl("");
|
||||
}
|
||||
};
|
||||
|
||||
// export const base_type = controls_type;
|
||||
// export const controls_TypeLists = controls_typeLists;
|
||||
743
boards/default_src/python/blocks/dicts.js
Normal file
743
boards/default_src/python/blocks/dicts.js
Normal file
@@ -0,0 +1,743 @@
|
||||
/**
|
||||
* @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, Number);
|
||||
}
|
||||
};
|
||||
|
||||
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, Number);
|
||||
}
|
||||
};
|
||||
177
boards/default_src/python/blocks/html.js
Normal file
177
boards/default_src/python/blocks/html.js
Normal 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);
|
||||
}
|
||||
};
|
||||
917
boards/default_src/python/blocks/lists.js
Normal file
917
boards/default_src/python/blocks/lists.js
Normal file
@@ -0,0 +1,917 @@
|
||||
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 lists_zip = {
|
||||
init: function () {
|
||||
this.setColour(LISTS_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(LISTS_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.MIXLY_PYTHON_LISTS_ZIP)
|
||||
.appendField('[]');
|
||||
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(LISTS_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 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;
|
||||
|
||||
264
boards/default_src/python/blocks/logic.js
Normal file
264
boards/default_src/python/blocks/logic.js
Normal 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);
|
||||
}
|
||||
};
|
||||
530
boards/default_src/python/blocks/math.js
Normal file
530
boards/default_src/python/blocks/math.js
Normal file
@@ -0,0 +1,530 @@
|
||||
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']];
|
||||
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
|
||||
1174
boards/default_src/python/blocks/procedures.js
Normal file
1174
boards/default_src/python/blocks/procedures.js
Normal file
File diff suppressed because it is too large
Load Diff
414
boards/default_src/python/blocks/set.js
Normal file
414
boards/default_src/python/blocks/set.js
Normal 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);
|
||||
}
|
||||
};
|
||||
511
boards/default_src/python/blocks/storage.js
Normal file
511
boards/default_src/python/blocks/storage.js
Normal file
@@ -0,0 +1,511 @@
|
||||
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']
|
||||
]), '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();
|
||||
}
|
||||
}
|
||||
960
boards/default_src/python/blocks/text.js
Normal file
960
boards/default_src/python/blocks/text.js
Normal file
@@ -0,0 +1,960 @@
|
||||
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, '"');
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
722
boards/default_src/python/blocks/tuple.js
Normal file
722
boards/default_src/python/blocks/tuple.js
Normal file
@@ -0,0 +1,722 @@
|
||||
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);
|
||||
}
|
||||
};
|
||||
445
boards/default_src/python/blocks/utility.js
Normal file
445
boards/default_src/python/blocks/utility.js
Normal 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('');
|
||||
}
|
||||
};
|
||||
202
boards/default_src/python/blocks/variables.js
Normal file
202
boards/default_src/python/blocks/variables.js
Normal file
@@ -0,0 +1,202 @@
|
||||
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];
|
||||
});
|
||||
}
|
||||
};
|
||||
98
boards/default_src/python/converters/control.js
Normal file
98
boards/default_src/python/converters/control.js
Normal 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中实现
|
||||
153
boards/default_src/python/converters/dicts.js
Normal file
153
boards/default_src/python/converters/dicts.js
Normal 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"
|
||||
});
|
||||
}
|
||||
}
|
||||
243
boards/default_src/python/converters/lists.js
Normal file
243
boards/default_src/python/converters/lists.js
Normal 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"
|
||||
});
|
||||
}
|
||||
15
boards/default_src/python/converters/logic.js
Normal file
15
boards/default_src/python/converters/logic.js
Normal 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"
|
||||
});
|
||||
}
|
||||
389
boards/default_src/python/converters/math.js
Normal file
389
boards/default_src/python/converters/math.js
Normal 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;
|
||||
180
boards/default_src/python/converters/set.js
Normal file
180
boards/default_src/python/converters/set.js
Normal 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');
|
||||
|
||||
359
boards/default_src/python/converters/storage.js
Normal file
359
boards/default_src/python/converters/storage.js
Normal 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"
|
||||
})];
|
||||
}
|
||||
|
||||
377
boards/default_src/python/converters/text.js
Normal file
377
boards/default_src/python/converters/text.js
Normal 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"
|
||||
})];
|
||||
}
|
||||
47
boards/default_src/python/converters/tuple.js
Normal file
47
boards/default_src/python/converters/tuple.js
Normal 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"
|
||||
});
|
||||
}
|
||||
}
|
||||
39
boards/default_src/python/converters/variables.js
Normal file
39
boards/default_src/python/converters/variables.js
Normal 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');
|
||||
65
boards/default_src/python/export.js
Normal file
65
boards/default_src/python/export.js
Normal 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
|
||||
};
|
||||
89
boards/default_src/python/generators/blynk.js
Normal file
89
boards/default_src/python/generators/blynk.js
Normal 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;
|
||||
}
|
||||
147
boards/default_src/python/generators/class.js
Normal file
147
boards/default_src/python/generators/class.js
Normal 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;
|
||||
}
|
||||
256
boards/default_src/python/generators/control.js
Normal file
256
boards/default_src/python/generators/control.js
Normal file
@@ -0,0 +1,256 @@
|
||||
import * as Blockly from 'blockly/core';
|
||||
|
||||
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 = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
// ok
|
||||
export const controls_repeat = controls_repeat_ext;
|
||||
207
boards/default_src/python/generators/dicts.js
Normal file
207
boards/default_src/python/generators/dicts.js
Normal file
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* @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';
|
||||
|
||||
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 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');
|
||||
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';}
|
||||
if (this.itemCount_ != 1) {
|
||||
var code = '{' + code.join(', ') + '}';
|
||||
}
|
||||
else {
|
||||
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];
|
||||
}
|
||||
70
boards/default_src/python/generators/html.js
Normal file
70
boards/default_src/python/generators/html.js
Normal 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;
|
||||
}
|
||||
267
boards/default_src/python/generators/lists.js
Normal file
267
boards/default_src/python/generators/lists.js
Normal file
@@ -0,0 +1,267 @@
|
||||
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 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 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];
|
||||
}
|
||||
102
boards/default_src/python/generators/logic.js
Normal file
102
boards/default_src/python/generators/logic.js
Normal 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];
|
||||
}
|
||||
303
boards/default_src/python/generators/math.js
Normal file
303
boards/default_src/python/generators/math.js
Normal file
@@ -0,0 +1,303 @@
|
||||
// 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")],
|
||||
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];
|
||||
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;
|
||||
107
boards/default_src/python/generators/procedures.js
Normal file
107
boards/default_src/python/generators/procedures.js
Normal 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 = 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 = 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;
|
||||
}
|
||||
95
boards/default_src/python/generators/set.js
Normal file
95
boards/default_src/python/generators/set.js
Normal 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];
|
||||
}
|
||||
175
boards/default_src/python/generators/storage.js
Normal file
175
boards/default_src/python/generators/storage.js
Normal 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";
|
||||
}
|
||||
245
boards/default_src/python/generators/text.js
Normal file
245
boards/default_src/python/generators/text.js
Normal file
@@ -0,0 +1,245 @@
|
||||
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_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;
|
||||
}
|
||||
292
boards/default_src/python/generators/tuple.js
Normal file
292
boards/default_src/python/generators/tuple.js
Normal file
@@ -0,0 +1,292 @@
|
||||
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];
|
||||
}
|
||||
78
boards/default_src/python/generators/utility.js
Normal file
78
boards/default_src/python/generators/utility.js
Normal 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];
|
||||
}
|
||||
72
boards/default_src/python/generators/variables.js
Normal file
72
boards/default_src/python/generators/variables.js
Normal file
@@ -0,0 +1,72 @@
|
||||
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];
|
||||
}
|
||||
0
boards/default_src/python/index.js
Normal file
0
boards/default_src/python/index.js
Normal file
722
boards/default_src/python/others/class.js
Normal file
722
boards/default_src/python/others/class.js
Normal 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;
|
||||
};
|
||||
|
||||
192
boards/default_src/python/others/names.js
Normal file
192
boards/default_src/python/others/names.js
Normal 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.toLowerCase() == name2.toLowerCase();
|
||||
}
|
||||
/**
|
||||
* 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.toLowerCase() + '_' + 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;
|
||||
327
boards/default_src/python/others/procedures.js
Normal file
327
boards/default_src/python/others/procedures.js
Normal 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;
|
||||
221
boards/default_src/python/others/variables.js
Normal file
221
boards/default_src/python/others/variables.js
Normal file
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
* @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.toLowerCase()] = 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);
|
||||
}
|
||||
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].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;
|
||||
};
|
||||
|
||||
export default Variables;
|
||||
29
boards/default_src/python/package.json
Normal file
29
boards/default_src/python/package.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "@mixly/python",
|
||||
"version": "1.0.0",
|
||||
"description": "适用于mixly的python模块",
|
||||
"scripts": {
|
||||
"build:dev": "webpack --config=webpack.dev.js",
|
||||
"build:prod": "webpack --config=webpack.prod.js"
|
||||
},
|
||||
"main": "./export.js",
|
||||
"author": "Mixly Team",
|
||||
"keywords": [
|
||||
"mixly",
|
||||
"mixly-plugin",
|
||||
"python"
|
||||
],
|
||||
"homepage": "https://gitee.com/mixly2/mixly2.0_src/tree/develop/boards/default_src/python",
|
||||
"bugs": {
|
||||
"url": "https://gitee.com/mixly2/mixly2.0_src/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitee.com/mixly2/mixly2.0_src.git",
|
||||
"directory": "default_src/python"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"license": "Apache 2.0"
|
||||
}
|
||||
308
boards/default_src/python/python_generator.js
Normal file
308
boards/default_src/python/python_generator.js
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
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 definitions = [];
|
||||
for (var name in Python.definitions_) {
|
||||
definitions.push(Python.definitions_[name]);
|
||||
}
|
||||
var functions = [];
|
||||
for (var name in Python.functions_) {
|
||||
functions.push(Python.functions_[name]);
|
||||
}
|
||||
var setups = [];
|
||||
for (var name in Python.setups_) {
|
||||
setups.push(Python.setups_[name]);
|
||||
}
|
||||
if (setups.length !== 0)
|
||||
setups.push('\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');
|
||||
// Clean up temporary data.
|
||||
//delete Python.definitions_;
|
||||
//delete Python.functionNames_;
|
||||
//Python.variableDB_.reset();
|
||||
if (loops.length > 0)
|
||||
return definitions.join('\n') + '\n' + functions.join('\n') + '\n' + setups.join('') + '\n' + code + 'while True:\n' + loops.join('') + codeEnd.join('\n');
|
||||
return definitions.join('\n') + '\n' + functions.join('\n') + '\n' + setups.join('') + '\n' + 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;
|
||||
};
|
||||
0
boards/default_src/python/template.xml
Normal file
0
boards/default_src/python/template.xml
Normal file
21
boards/default_src/python/webpack.dev.js
Normal file
21
boards/default_src/python/webpack.dev.js
Normal 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
|
||||
}),
|
||||
]
|
||||
});
|
||||
27
boards/default_src/python/webpack.prod.js
Normal file
27
boards/default_src/python/webpack.prod.js
Normal 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,
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user