feat: sync arduino source board configurations
This commit is contained in:
165
mixly/boards/default_src/arduino/arduino_generator.js
Normal file
165
mixly/boards/default_src/arduino/arduino_generator.js
Normal file
@@ -0,0 +1,165 @@
|
||||
import * as Blockly from 'blockly/core';
|
||||
import Names from './others/names';
|
||||
|
||||
export class ArduinoGenerator extends Blockly.Generator {
|
||||
constructor(name) {
|
||||
super(name ?? 'Arduino')
|
||||
this.ORDER_ATOMIC = 0 // 0 "" ...
|
||||
this.ORDER_UNARY_POSTFIX = 1 // expr++ expr-- () [] .
|
||||
this.ORDER_UNARY_PREFIX = 2 // -expr !expr ~expr ++expr --expr
|
||||
this.ORDER_MULTIPLICATIVE = 3 // * / % ~/
|
||||
this.ORDER_ADDITIVE = 4 // + -
|
||||
this.ORDER_SHIFT = 5 // << >>
|
||||
this.ORDER_RELATIONAL = 6 // is is! >= > <= <
|
||||
this.ORDER_EQUALITY = 7 // == != === !==
|
||||
this.ORDER_BITWISE_AND = 8 // &
|
||||
this.ORDER_BITWISE_XOR = 9 // ^
|
||||
this.ORDER_BITWISE_OR = 10 // |
|
||||
this.ORDER_LOGICAL_AND = 11 // &&
|
||||
this.ORDER_LOGICAL_OR = 12 // ||
|
||||
this.ORDER_CONDITIONAL = 13 // expr ? expr : expr
|
||||
this.ORDER_ASSIGNMENT = 14 // = *= /= ~/= %= += -= <<= >>= &= ^= |=
|
||||
this.ORDER_NONE = 99 // (...)
|
||||
this.INDENT = ' '
|
||||
this.isInitialized = false
|
||||
this.PASS = ''
|
||||
|
||||
this.addReservedWords(
|
||||
'setup,loop,if,else,for,switch,case,while,do,break,continue,return,goto,define,include,HIGH,LOW,INPUT,OUTPUT,INPUT_PULLUP,true,false,interger,constants,floating,point,void,bookean,char,unsigned,byte,int,short,word,long,float,double,string,String,array,static,volatile,const,sizeof'
|
||||
)
|
||||
}
|
||||
|
||||
init() {
|
||||
super.init();
|
||||
// Create a dictionary of definitions to be printed before setups.
|
||||
this.definitions_ = Object.create(null)
|
||||
// Create a dictionary of setups to be printed before the code.
|
||||
this.setups_ = Object.create(null)
|
||||
this.setups_begin_ = Object.create(null)
|
||||
this.setups_end_ = Object.create(null)
|
||||
this.libs_ = Object.create(null)
|
||||
this.loops_begin_ = Object.create(null)
|
||||
this.loops_end_ = Object.create(null)
|
||||
//this.variableTypes_ = Object.create(null);//处理变量类型
|
||||
|
||||
if (!this.variableDB_) {
|
||||
this.variableDB_ = new Names(
|
||||
this.RESERVED_WORDS_
|
||||
)
|
||||
} else {
|
||||
this.variableDB_.reset()
|
||||
}
|
||||
this.isInitialized = true;
|
||||
}
|
||||
|
||||
finish(code) {
|
||||
// Indent every line.
|
||||
code = ' ' + code.replace(/\n/g, '\n ');
|
||||
code = code.replace(/\n\s+$/, '\n');
|
||||
// Convert the definitions dictionary into a list.
|
||||
var imports = [];
|
||||
var define = [];
|
||||
var definitions_var = []; //变量定义
|
||||
var definitions_fun = []; //函数定义
|
||||
//var sorted_keys=Object.keys(this.definitions_).sort();
|
||||
var sorted_keys = Object.keys(this.definitions_);
|
||||
if (sorted_keys.length) {
|
||||
for (var idx in sorted_keys) {
|
||||
var name = sorted_keys[idx];
|
||||
var def = this.definitions_[name];
|
||||
if (name.match(/^define/)) {
|
||||
define.push(def);
|
||||
} else if (name.match(/^include/)) {
|
||||
imports.push(def);
|
||||
} else if (def.match(/^WiFiClient/)) {
|
||||
imports.push(def);
|
||||
} else if (name.match(/^var_declare/)) {
|
||||
definitions_var.push(def);
|
||||
} else {
|
||||
definitions_fun.push(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Convert the setups dictionary into a list.
|
||||
var setups = [];
|
||||
for (let name in this.setups_) {
|
||||
setups.push(this.setups_[name]);
|
||||
}
|
||||
var setupsBegin = [], setupsEnd = [];
|
||||
for (let name in this.setups_begin_) {
|
||||
setupsBegin.push(this.setups_begin_[name]);
|
||||
}
|
||||
for (let name in this.setups_end_) {
|
||||
setupsEnd.push(this.setups_end_[name]);
|
||||
}
|
||||
|
||||
for (let name in this.libs_) {
|
||||
imports.push(`#include "${name}.h"`);
|
||||
}
|
||||
|
||||
var loopsBegin = [], loopsEnd = [];
|
||||
for (let name in this.loops_begin_) {
|
||||
loopsBegin.push(this.loops_begin_[name]);
|
||||
}
|
||||
for (let name in this.loops_end_) {
|
||||
loopsEnd.push(this.loops_end_[name]);
|
||||
}
|
||||
code = 'void loop() {\n'
|
||||
+ (loopsBegin.length ? (' ' + loopsBegin.join('\n ')) : '')
|
||||
+ code
|
||||
+ (loopsEnd.length ? (' ' + loopsEnd.join('\n ')) : '')
|
||||
+ '\n}';
|
||||
var allDefs = define.join('\n') + '\n' + imports.join('\n') + '\n\n'
|
||||
+ definitions_var.join('\n')
|
||||
+ '\n\n' + definitions_fun.join('\n')
|
||||
+ '\n\nvoid setup() {\n '
|
||||
+ setupsBegin.join('\n ') + ((setupsBegin.length && (setupsEnd.length || setups.length)) ? '\n ' : '')
|
||||
+ setups.join('\n ') + ((setupsEnd.length && setups.length) ? '\n ' : '')
|
||||
+ setupsEnd.join('\n ') + '\n}' + '\n\n';
|
||||
return allDefs.replace(/\n\n+/g, '\n\n').replace(/\n*$/, '\n\n') + code;
|
||||
}
|
||||
|
||||
scrubNakedValue(line) {
|
||||
return line + ';\n'
|
||||
}
|
||||
|
||||
quote_(string) {
|
||||
// TODO: This is a quick hack. Replace with goog.string.quote
|
||||
//return goog.string.quote(string);
|
||||
return "\"" + string + "\"";
|
||||
}
|
||||
|
||||
scrub_(block, code) {
|
||||
if (code === null) {
|
||||
// Block has handled code generation itself.
|
||||
return '';
|
||||
}
|
||||
var commentCode = '';
|
||||
// Only collect comments for blocks that aren't inline.
|
||||
if (!block.outputConnection || !block.outputConnection.targetConnection) {
|
||||
// Collect comment for this block.
|
||||
let comment = block.getCommentText();
|
||||
if (comment) {
|
||||
commentCode += this.prefixLines(comment, '// ') + '\n';
|
||||
}
|
||||
// Collect comments for all value arguments.
|
||||
// Don't collect comments for nested statements.
|
||||
for (var x = 0; x < block.inputList.length; x++) {
|
||||
if (block.inputList[x].type == Blockly.INPUT_VALUE) {
|
||||
var childBlock = block.inputList[x].connection.targetBlock();
|
||||
if (childBlock) {
|
||||
let comment = this.allNestedComments(childBlock);
|
||||
if (comment) {
|
||||
commentCode += this.prefixLines(comment, '// ');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
|
||||
var nextCode = this.blockToCode(nextBlock);
|
||||
return commentCode + code + nextCode;
|
||||
}
|
||||
}
|
||||
|
||||
export const Arduino = new ArduinoGenerator();
|
||||
223
mixly/boards/default_src/arduino/blocks/ethernet.js
Normal file
223
mixly/boards/default_src/arduino/blocks/ethernet.js
Normal file
@@ -0,0 +1,223 @@
|
||||
import * as Blockly from 'blockly/core';
|
||||
import CITYS_DATA from '../templates/json/cities.json';
|
||||
|
||||
const ETHERNET_HUE = 0;
|
||||
const WEATHER_HUE = '#27b6ac';
|
||||
|
||||
|
||||
/**
|
||||
* @name 模块名 Http GET请求
|
||||
* @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
|
||||
*/
|
||||
export const http_get = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_GET_REQUEST);
|
||||
this.appendValueInput("api")
|
||||
.setCheck(null)
|
||||
.appendField(Blockly.Msg.blynk_SERVER_ADD);
|
||||
this.appendStatementInput("success")
|
||||
.setCheck(null)
|
||||
.appendField(Blockly.Msg.MIXLY_SUCCESS);
|
||||
this.appendStatementInput("failure")
|
||||
.setCheck(null)
|
||||
.appendField(Blockly.Msg.MIXLY_FAILED);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(ETHERNET_HUE);
|
||||
this.setTooltip("");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @name 模块名 Http PATCH|POST|PUT请求
|
||||
* @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
|
||||
*/
|
||||
export const http_post = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField(new Blockly.FieldDropdown([
|
||||
["POST", "POST"],
|
||||
["PATCH", "PATCH"],
|
||||
["PUT", "PUT"]
|
||||
]), "TYPE")
|
||||
.appendField(Blockly.Msg.blockpy_REQUESTS);
|
||||
this.appendValueInput("api")
|
||||
.setCheck(null)
|
||||
.appendField(Blockly.Msg.blynk_SERVER_ADD);
|
||||
this.appendValueInput("data")
|
||||
.setCheck(null)
|
||||
.appendField(Blockly.Msg.MIXLY_SD_DATA);
|
||||
this.appendStatementInput("success")
|
||||
.setCheck(null)
|
||||
.appendField(Blockly.Msg.MIXLY_SUCCESS);
|
||||
this.appendStatementInput("failure")
|
||||
.setCheck(null)
|
||||
.appendField(Blockly.Msg.MIXLY_FAILED);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(ETHERNET_HUE);
|
||||
this.setTooltip("");
|
||||
}
|
||||
};
|
||||
|
||||
var PROVINCES = [], key;
|
||||
for (key in CITYS_DATA)
|
||||
PROVINCES.push([key, key]);
|
||||
|
||||
|
||||
function getCitysByProvince(a) {
|
||||
var b = [], c;
|
||||
for (c in CITYS_DATA[a])
|
||||
b.push([c, c]);
|
||||
return b;
|
||||
}
|
||||
|
||||
var citysByProvince = {};
|
||||
for (key of PROVINCES) {
|
||||
citysByProvince[key[0]] = getCitysByProvince(key[0]);
|
||||
}
|
||||
|
||||
export const china_city = {
|
||||
init: function () {
|
||||
const defaultOptions = [["-", "-"]];
|
||||
this.appendDummyInput()
|
||||
.appendField(new Blockly.FieldDropdown(PROVINCES), "province")
|
||||
.appendField(new Blockly.FieldDependentDropdown("province", citysByProvince, defaultOptions), "city");
|
||||
this.setInputsInline(true);
|
||||
this.setOutput(true, null);
|
||||
this.setColour(WEATHER_HUE);
|
||||
this.setHelpUrl("");
|
||||
this.preProvince = null;
|
||||
}
|
||||
};
|
||||
|
||||
export const weather_private_key = {
|
||||
init: function () {
|
||||
this.setColour(WEATHER_HUE);
|
||||
this.appendDummyInput("")
|
||||
.appendField(new Blockly.FieldDropdown([['S9l2sb_ZK-UsWaynG', 'S9l2sb_ZK-UsWaynG'], ['SpRpSYb7QOMT0M8Tz', 'SpRpSYb7QOMT0M8Tz'], ['SboqGMxP4tYNXUN8f', 'SboqGMxP4tYNXUN8f'], ['SJiRrYGYFkGnfi081', 'SJiRrYGYFkGnfi081'], ['SMhSshUxuTL0GLVLS', 'SMhSshUxuTL0GLVLS']]), 'key');
|
||||
this.setOutput(true, null);
|
||||
}
|
||||
};
|
||||
|
||||
export const weather_seniverse_city_weather = {
|
||||
init: function () {
|
||||
this.appendDummyInput("")
|
||||
.appendField(Blockly.Msg.MSG.catweather)
|
||||
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_LIVE_WEATHER, "weather/now"], [Blockly.Msg.MIXLY_3_DAY_WEATHER_FORECAST, "weather/daily"], [Blockly.Msg.MIXLY_6_LIFE_INDEXES, "life/suggestion"]]), "api")
|
||||
.appendField(Blockly.Msg.MIXLY_INFORMATION_CONFIGURATION);
|
||||
this.appendValueInput("location")
|
||||
.setCheck(null)
|
||||
.appendField(Blockly.Msg.MIXLY_GEOGRAPHIC_LOCATION);
|
||||
this.appendValueInput("private_key")
|
||||
.setCheck(null)
|
||||
.appendField(Blockly.Msg.MIXLY_API_PRIVATE_KEY);
|
||||
this.appendDummyInput("")
|
||||
.appendField(Blockly.Msg.MIXLY_LANGUAGE)
|
||||
.appendField(new Blockly.FieldDropdown([
|
||||
["简体中文", "zh-Hans"],
|
||||
["繁體中文", "zh-Hant"],
|
||||
["English", "en"]
|
||||
]), "language");
|
||||
this.appendDummyInput("")
|
||||
.appendField(Blockly.Msg.MIXLY_TEMPERATURE_UNIT)
|
||||
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_CELSIUS + "(℃)", "c"], [Blockly.Msg.MIXLY_FAHRENHEIT + "(℉)", "f"]]), "unit");
|
||||
this.setInputsInline(false);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(WEATHER_HUE);
|
||||
this.setTooltip("这里的API私钥免费体验有次数限制\n访问频率限制20次/分钟");
|
||||
this.setHelpUrl("");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const weather_get_seniverse_weather_info = {
|
||||
init: function () {
|
||||
this.appendDummyInput("")
|
||||
//.appendField("心知天气")
|
||||
.appendField(new Blockly.FieldDropdown([
|
||||
[Blockly.Msg.MIXLY_LIVE_WEATHER, "weather/now"],
|
||||
[Blockly.Msg.MIXLY_3_DAY_WEATHER_FORECAST, "weather/daily"],
|
||||
[Blockly.Msg.MIXLY_6_LIFE_INDEXES, "life/suggestion"]
|
||||
]), "api")
|
||||
.appendField(new Blockly.FieldDropdown([
|
||||
[Blockly.Msg.MIXLY_AVAILABLE, "update"],
|
||||
[Blockly.Msg.MIXLY_GET_DATA_UPDATE_TIME, "getLastUpdate"],
|
||||
[Blockly.Msg.MIXLY_GET_SERVER_RESPONSE_STATUS_CODE, "getServerCode"]
|
||||
]), "type");
|
||||
this.setInputsInline(true);
|
||||
this.setOutput(true, null);
|
||||
this.setColour(WEATHER_HUE);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl("");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export const weather_get_seniverse_weather_info1 = {
|
||||
init: function () {
|
||||
this.appendDummyInput("")
|
||||
//.appendField("心知天气")
|
||||
.appendField(Blockly.Msg.MIXLY_LIVE_WEATHER)
|
||||
.appendField(Blockly.Msg.MIXLY_GET)
|
||||
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_WEATHER_PHENOMENON, "getWeatherText"], [Blockly.Msg.MIXLY_WEATHER_PHENOMENON_CODE, "getWeatherCode"], [Blockly.Msg.MIXLY_TEMPERATURE, "getDegree"]]), "type");
|
||||
this.setInputsInline(true);
|
||||
this.setOutput(true, null);
|
||||
this.setColour(WEATHER_HUE);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl("");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export const weather_get_seniverse_weather_info2 = {
|
||||
init: function () {
|
||||
this.appendDummyInput("")
|
||||
//.appendField("心知天气")
|
||||
.appendField(Blockly.Msg.MIXLY_3_DAY_WEATHER_FORECAST)
|
||||
.appendField(Blockly.Msg.MIXLY_GET)
|
||||
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_TODAY, "0"], [Blockly.Msg.MIXLY_TOMORROW, "1"], [Blockly.Msg.MIXLY_DAY_AFTER_TOMORROW, "2"]]), "date")
|
||||
.appendField(new Blockly.FieldDropdown([
|
||||
[Blockly.Msg.ForecastHigh, "getHigh"],
|
||||
[Blockly.Msg.ForecastLow, "getLow"],
|
||||
[Blockly.Msg.MIXLY_DAYTIME_WEATHER_PHENOMENON, "getDayText"],
|
||||
[Blockly.Msg.MIXLY_DAYTIME_WEATHER_PHENOMENON_CODE, "getDayCode"],
|
||||
[Blockly.Msg.MIXLY_EVENING_WEATHER_PHENOMENON, "getNightText"],
|
||||
[Blockly.Msg.MIXLY_EVENING_WEATHER_PHENOMENON_CODE, "getNightCode"],
|
||||
[Blockly.Msg.MIXLY_PROBABILITY_OF_PRECIPITATION, "getRain"],
|
||||
[Blockly.Msg.ForecastFx, "getWindDirection"],
|
||||
[Blockly.Msg.MIXLY_WIND_SPEED, "getWindSpeed"],
|
||||
[Blockly.Msg.MIXLY_WIND_RATING, "getWindScale"],
|
||||
[Blockly.Msg.MIXLY_Humidity, "getHumidity"]
|
||||
]), "type");
|
||||
this.setInputsInline(true);
|
||||
this.setOutput(true, null);
|
||||
this.setColour(WEATHER_HUE);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl("");
|
||||
}
|
||||
};
|
||||
|
||||
export const weather_get_seniverse_weather_info3 = {
|
||||
init: function () {
|
||||
this.appendDummyInput("")
|
||||
//.appendField("心知天气")
|
||||
.appendField(Blockly.Msg.MIXLY_6_LIFE_INDEXES)
|
||||
.appendField(Blockly.Msg.MIXLY_GET)
|
||||
.appendField(new Blockly.FieldDropdown([
|
||||
[Blockly.Msg.MIXLY_CAR_WASH_INDEX, "getCarWash"],
|
||||
[Blockly.Msg.MIXLY_DRESSING_INDEX, "getDressing"],
|
||||
[Blockly.Msg.MIXLY_COLD_INDEX, "getFactorFlu"],
|
||||
[Blockly.Msg.MIXLY_MOVEMENT_INDEX, "getExercise"],
|
||||
[Blockly.Msg.MIXLY_TOURISM_INDEX, "getTravel"],
|
||||
[Blockly.Msg.MIXLY_UV_INDEX, "getUV"]]
|
||||
), "type");
|
||||
this.setInputsInline(true);
|
||||
this.setOutput(true, null);
|
||||
this.setColour(WEATHER_HUE);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl("");
|
||||
}
|
||||
};
|
||||
1314
mixly/boards/default_src/arduino/blocks/procedures.js
Normal file
1314
mixly/boards/default_src/arduino/blocks/procedures.js
Normal file
File diff suppressed because it is too large
Load Diff
24
mixly/boards/default_src/arduino/blocks/text.js
Normal file
24
mixly/boards/default_src/arduino/blocks/text.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import * as Blockly from 'blockly/core';
|
||||
|
||||
const TEXTS_HUE = 160;
|
||||
|
||||
|
||||
export const text_base64_url_codec = {
|
||||
init: function () {
|
||||
this.appendValueInput('VALUE')
|
||||
.setCheck(null)
|
||||
.setAlign(Blockly.inputs.Align.LEFT)
|
||||
.appendField(new Blockly.FieldDropdown([
|
||||
['Base64', 'BASE64'],
|
||||
['URL', 'URL']
|
||||
]), 'TYPE')
|
||||
.appendField(new Blockly.FieldDropdown([
|
||||
[Blockly.Msg.MIXPY_TEXT_ENCODE, 'ENCODE'],
|
||||
[Blockly.Msg.MIXPY_TEXT_DECODE, 'DECODE']
|
||||
]), 'OPTION');
|
||||
this.setOutput(true, null);
|
||||
this.setColour(TEXTS_HUE);
|
||||
this.setTooltip('');
|
||||
this.setHelpUrl('');
|
||||
}
|
||||
};
|
||||
85
mixly/boards/default_src/arduino/blocks/variables.js
Normal file
85
mixly/boards/default_src/arduino/blocks/variables.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import * as Blockly from 'blockly/core';
|
||||
import { Variables } from 'blockly/core';
|
||||
|
||||
const VARIABLES_HUE = 330;
|
||||
|
||||
|
||||
export const variables_declare = {
|
||||
init: function () {
|
||||
this.setColour(VARIABLES_HUE);
|
||||
this.appendValueInput('VALUE', null)
|
||||
.appendField(Blockly.Msg.MIXLY_DECLARE)
|
||||
.appendField(new Blockly.FieldDropdown([
|
||||
[Blockly.Msg.MIXLY_GLOBAL_VARIABLE, 'global_variate'],
|
||||
[Blockly.Msg.MIXLY_LOCAL_VARIABLE, 'local_variate']
|
||||
]), 'variables_type')
|
||||
.appendField(new Blockly.FieldTextInput('item'), 'VAR')
|
||||
.appendField(Blockly.Msg.MIXLY_AS)
|
||||
.appendField(new Blockly.FieldDropdown(Variables.DATA_TYPE), '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 (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
|
||||
this.setFieldValue(newName, 'VAR');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const variables_get = {
|
||||
init: function () {
|
||||
this.setColour(VARIABLES_HUE);
|
||||
this.appendDummyInput()
|
||||
.appendField(new Blockly.FieldTextInput('item'), 'VAR')
|
||||
this.setOutput(true);
|
||||
this.setTooltip(Blockly.Msg.VARIABLES_GET_TOOLTIP);
|
||||
},
|
||||
getVars: function () {
|
||||
return [this.getFieldValue('VAR')];
|
||||
},
|
||||
renameVar: function (oldName, newName) {
|
||||
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
|
||||
this.setFieldValue(newName, 'VAR');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const variables_set = {
|
||||
init: function () {
|
||||
this.setColour(VARIABLES_HUE);
|
||||
this.appendValueInput('VALUE')
|
||||
.appendField(new Blockly.FieldTextInput('item'), '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 (Blockly.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);
|
||||
this.appendValueInput('MYVALUE')
|
||||
.appendField(new Blockly.FieldDropdown(Variables.DATA_TYPE), 'OP');
|
||||
// Assign 'this' to a variable for use in the tooltip closure below.
|
||||
this.setOutput(true);
|
||||
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_VARIABLES_CHANGE);
|
||||
}
|
||||
};
|
||||
28
mixly/boards/default_src/arduino/export.js
Normal file
28
mixly/boards/default_src/arduino/export.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import * as ArduinoEthernetBlocks from './blocks/ethernet';
|
||||
import * as ArduinoProceduresBlocks from './blocks/procedures';
|
||||
import * as ArduinoTextBlocks from './blocks/text';
|
||||
import * as ArduinoVariablesBlocks from './blocks/variables';
|
||||
import * as ArduinoProceduresGenerators from './generators/procedures';
|
||||
import * as ArduinoEthernetGenerators from './generators/ethernet';
|
||||
import * as ArduinoTextGenerators from './generators/text';
|
||||
import * as ArduinoVariablesGenerators from './generators/variables';
|
||||
import Names from './others/names';
|
||||
import Procedures from './others/procedures';
|
||||
import Variables from './others/variables';
|
||||
import { ArduinoGenerator, Arduino } from './arduino_generator';
|
||||
|
||||
export {
|
||||
ArduinoEthernetBlocks,
|
||||
ArduinoProceduresBlocks,
|
||||
ArduinoTextBlocks,
|
||||
ArduinoVariablesBlocks,
|
||||
ArduinoEthernetGenerators,
|
||||
ArduinoProceduresGenerators,
|
||||
ArduinoTextGenerators,
|
||||
ArduinoVariablesGenerators,
|
||||
Names,
|
||||
Procedures,
|
||||
Variables,
|
||||
ArduinoGenerator,
|
||||
Arduino
|
||||
};
|
||||
196
mixly/boards/default_src/arduino/generators/ethernet.js
Normal file
196
mixly/boards/default_src/arduino/generators/ethernet.js
Normal file
@@ -0,0 +1,196 @@
|
||||
import * as Blockly from 'blockly/core';
|
||||
import * as Mixly from 'mixly';
|
||||
import CITYS_DATA from '../templates/json/cities.json';
|
||||
|
||||
|
||||
/**
|
||||
* @name 模块名 Http GET请求
|
||||
* @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
|
||||
*/
|
||||
export const http_get = function () {
|
||||
const BOARD_TYPE = Mixly.Boards.getType();
|
||||
const API = Blockly.Arduino.valueToCode(this, 'api', Blockly.Arduino.ORDER_ATOMIC);
|
||||
let branch = Blockly.Arduino.statementToCode(this, 'success') || '';
|
||||
branch = branch.replace(/(^\s*)|(\s*$)/g, "");
|
||||
let branch1 = Blockly.Arduino.statementToCode(this, 'failure') || '';
|
||||
branch1 = branch1.replace(/(^\s*)|(\s*$)/g, "");
|
||||
let code = '';
|
||||
if (BOARD_TYPE == 'arduino_esp8266') {
|
||||
Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include <ESP8266WiFi.h>';
|
||||
Blockly.Arduino.definitions_['include_ESP8266HTTPClient'] = '#include <ESP8266HTTPClient.h>';
|
||||
code
|
||||
= 'if (WiFi.status() == WL_CONNECTED) {\n'
|
||||
+ ' WiFiClient client;\n'
|
||||
+ ' HTTPClient http;\n'
|
||||
+ ' http.begin(client, ' + API + ');\n'
|
||||
+ ' int httpCode = http.GET();\n'
|
||||
+ ' if (httpCode > 0) {\n'
|
||||
+ ' String Request_result = http.getString();\n'
|
||||
+ ' ' + branch + '\n'
|
||||
+ ' } else {\n'
|
||||
+ ' ' + branch1 + '\n'
|
||||
+ ' }\n'
|
||||
+ ' http.end();\n'
|
||||
+ '}\n';
|
||||
} else {
|
||||
Blockly.Arduino.definitions_['include_WiFi'] = '#include <WiFi.h>';
|
||||
Blockly.Arduino.definitions_['include_HTTPClient'] = '#include <HTTPClient.h>';
|
||||
code
|
||||
= 'if (WiFi.status() == WL_CONNECTED) {\n'
|
||||
+ ' HTTPClient http;\n'
|
||||
+ ' http.begin(' + API + ');\n'
|
||||
+ ' int httpCode = http.GET();\n'
|
||||
+ ' if (httpCode > 0) {\n'
|
||||
+ ' String Request_result = http.getString();\n'
|
||||
+ ' ' + branch + '\n'
|
||||
+ ' }\n'
|
||||
+ ' else {\n'
|
||||
+ ' ' + branch1 + '\n'
|
||||
+ ' }\n'
|
||||
+ ' http.end();\n'
|
||||
+ '}\n';
|
||||
}
|
||||
return code;
|
||||
};
|
||||
|
||||
/**
|
||||
* @name 模块名 Http PATCH|POST|PUT请求
|
||||
* @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
|
||||
*/
|
||||
export const http_post = function () {
|
||||
const BOARD_TYPE = Mixly.Boards.getType();
|
||||
const FIELD_TYPE = this.getFieldValue("TYPE");
|
||||
const API = Blockly.Arduino.valueToCode(this, 'api', Blockly.Arduino.ORDER_ATOMIC);
|
||||
const DATA = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
|
||||
let branch = Blockly.Arduino.statementToCode(this, 'success') || '';
|
||||
branch = branch.replace(/(^\s*)|(\s*$)/g, "");
|
||||
let branch1 = Blockly.Arduino.statementToCode(this, 'failure') || '';
|
||||
branch1 = branch1.replace(/(^\s*)|(\s*$)/g, "");
|
||||
let code = '';
|
||||
if (BOARD_TYPE == 'arduino_esp8266') {
|
||||
Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include <ESP8266WiFi.h>';
|
||||
Blockly.Arduino.definitions_['include_ESP8266HTTPClient'] = '#include <ESP8266HTTPClient.h>';
|
||||
code
|
||||
= 'if (WiFi.status() == WL_CONNECTED) {\n'
|
||||
+ ' HTTPClient http;\n'
|
||||
+ ' WiFiClient client;\n'
|
||||
+ ' http.begin(client, ' + API + ');\n'
|
||||
+ ' http.addHeader("Content-Type", "application/json");\n'
|
||||
+ ' int httpCode = http.' + FIELD_TYPE + '(' + DATA + ');\n'
|
||||
+ ' if (httpCode > 0) {\n'
|
||||
+ ' String Request_result = http.getString();\n'
|
||||
+ ' ' + branch + '\n'
|
||||
+ ' } else {\n'
|
||||
+ ' ' + branch1 + '\n'
|
||||
+ ' }\n'
|
||||
+ ' http.end();\n'
|
||||
+ '}\n';
|
||||
} else {
|
||||
Blockly.Arduino.definitions_['include_WiFi'] = '#include <WiFi.h>';
|
||||
Blockly.Arduino.definitions_['include_HTTPClient'] = '#include <HTTPClient.h>';
|
||||
code
|
||||
= 'if (WiFi.status() == WL_CONNECTED) {\n'
|
||||
+ ' HTTPClient http;\n'
|
||||
+ ' http.begin(' + API + ');\n'
|
||||
+ ' http.addHeader("Content-Type", "application/json");\n'
|
||||
+ ' int httpCode = http.' + FIELD_TYPE + '(' + DATA + ');\n'
|
||||
+ ' if (httpCode > 0) {\n'
|
||||
+ ' String Request_result = http.getString();\n'
|
||||
+ ' ' + branch + '\n'
|
||||
+ ' }\n'
|
||||
+ ' else {\n'
|
||||
+ ' ' + branch1 + '\n'
|
||||
+ ' }\n'
|
||||
+ ' http.end();\n'
|
||||
+ '}\n';
|
||||
}
|
||||
return code;
|
||||
};
|
||||
|
||||
//网络天气
|
||||
export const china_city = function () {
|
||||
var a = this.getFieldValue("province");
|
||||
var b = this.getFieldValue("city");
|
||||
var code = "";
|
||||
try {
|
||||
code = '"' + CITYS_DATA[a][b].pinyin + '"';
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
export const weather_private_key = function () {
|
||||
var a = this.getFieldValue("key");
|
||||
var code = '"' + a + '"';
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
export const weather_seniverse_city_weather = function () {
|
||||
var api = this.getFieldValue("api");
|
||||
var location = Blockly.Arduino.valueToCode(this, "location", Blockly.Arduino.ORDER_ATOMIC);
|
||||
var private_key = Blockly.Arduino.valueToCode(this, "private_key", Blockly.Arduino.ORDER_ATOMIC);
|
||||
//private_key = private_key.replace(/\"/g, "")
|
||||
var language = this.getFieldValue("language");
|
||||
var unit = this.getFieldValue("unit");
|
||||
|
||||
Blockly.Arduino.definitions_['include_ESP8266_Seniverse'] = '#include <ESP8266_Seniverse.h>';
|
||||
|
||||
Blockly.Arduino.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
|
||||
|
||||
switch (api) {
|
||||
case 'weather/now':
|
||||
Blockly.Arduino.definitions_['var_declare_weatherNow'] = 'WeatherNow weatherNow;';
|
||||
Blockly.Arduino.setups_['setup_seniverse_weatherNow'] = 'weatherNow.config(' + private_key + ', ' + location + ', "' + unit + '", "' + language + '");';
|
||||
break;
|
||||
case 'weather/daily':
|
||||
Blockly.Arduino.definitions_['var_declare_forecast'] = 'Forecast forecast;';
|
||||
Blockly.Arduino.setups_['setup_seniverse_forecast'] = 'forecast.config(' + private_key + ', ' + location + ', "' + unit + '", "' + language + '");';
|
||||
break;
|
||||
case 'life/suggestion':
|
||||
default:
|
||||
Blockly.Arduino.definitions_['var_declare_lifeInfo'] = 'LifeInfo lifeInfo;';
|
||||
Blockly.Arduino.setups_['setup_seniverse_lifeInfo'] = 'lifeInfo.config(' + private_key + ', ' + location + ', "' + unit + '", "' + language + '");';
|
||||
}
|
||||
var code = '';
|
||||
|
||||
return code;
|
||||
};
|
||||
|
||||
export const weather_get_seniverse_weather_info = function () {
|
||||
var api = this.getFieldValue("api");
|
||||
var type = this.getFieldValue("type");
|
||||
var code = '';
|
||||
switch (api) {
|
||||
case 'weather/now':
|
||||
code = 'weatherNow.' + type + '()';
|
||||
break;
|
||||
case 'weather/daily':
|
||||
code = 'forecast.' + type + '()';
|
||||
break;
|
||||
case 'life/suggestion':
|
||||
default:
|
||||
code = 'lifeInfo.' + type + '()';
|
||||
}
|
||||
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
export const weather_get_seniverse_weather_info1 = function () {
|
||||
var type = this.getFieldValue("type");
|
||||
var code = 'weatherNow.' + type + '()';
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
export const weather_get_seniverse_weather_info2 = function () {
|
||||
var date = this.getFieldValue("date");
|
||||
var type = this.getFieldValue("type");
|
||||
var code = 'forecast.' + type + '(' + date + ')';
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
export const weather_get_seniverse_weather_info3 = function () {
|
||||
var type = this.getFieldValue("type");
|
||||
var code = 'lifeInfo.' + type + '()';
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
114
mixly/boards/default_src/arduino/generators/procedures.js
Normal file
114
mixly/boards/default_src/arduino/generators/procedures.js
Normal file
@@ -0,0 +1,114 @@
|
||||
import { Variables, Procedures } from 'blockly/core';
|
||||
|
||||
export const procedures_defreturn = function (_, generator) {
|
||||
// Define a procedure with a return value.
|
||||
var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
|
||||
Procedures.NAME_TYPE);
|
||||
var branch = (this.getInput('STACK') && generator.statementToCode(this, 'STACK'));
|
||||
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 (type === 'CUSTOM') {
|
||||
if (this.getField('RETRUN_TYPE')) {
|
||||
type = this.getFieldValue('RETRUN_TYPE');
|
||||
} else {
|
||||
type = 'void';
|
||||
}
|
||||
}
|
||||
if (returnValue) {
|
||||
returnValue = ' return ' + returnValue + ';\n';
|
||||
}
|
||||
var returnType = type ? type : 'void';
|
||||
var args = [];
|
||||
for (var x = 0; x < this.arguments_.length; x++) {
|
||||
args[x] = this.argumentstype_[x] + ' ' + generator.variableDB_.getName(this.arguments_[x],
|
||||
Variables.NAME_TYPE);
|
||||
}
|
||||
var code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' +
|
||||
branch + returnValue + '}\n';
|
||||
code = generator.scrub_(this, code);
|
||||
generator.definitions_[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'),
|
||||
Procedures.NAME_TYPE);
|
||||
var branch = (this.getInput('STACK') && generator.statementToCode(this, 'STACK'));
|
||||
if (generator.INFINITE_LOOP_TRAP) {
|
||||
branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
|
||||
'\'' + this.id + '\'') + branch;
|
||||
}
|
||||
var returnType = 'void';
|
||||
var args = [];
|
||||
for (var x = 0; x < this.arguments_.length; x++) {
|
||||
args[x] = this.argumentstype_[x] + ' ' + generator.variableDB_.getName(this.arguments_[x],
|
||||
Variables.NAME_TYPE);
|
||||
}
|
||||
var code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' +
|
||||
branch + '}\n';
|
||||
code = generator.scrub_(this, code);
|
||||
generator.definitions_[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'),
|
||||
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'),
|
||||
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) || '';
|
||||
code += ' return ' + value + ';\n';
|
||||
} else {
|
||||
code += ' return;\n';
|
||||
}
|
||||
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 + ';\n';
|
||||
} else {
|
||||
code += 'return;\n';
|
||||
}
|
||||
code += '\n';
|
||||
return code;
|
||||
}
|
||||
37
mixly/boards/default_src/arduino/generators/text.js
Normal file
37
mixly/boards/default_src/arduino/generators/text.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import * as Blockly from 'blockly/core';
|
||||
|
||||
export const text_base64_url_codec = function () {
|
||||
const FIELD_TYPE = this.getFieldValue("TYPE");
|
||||
const FIELD_OPTION = this.getFieldValue("OPTION");
|
||||
const VALUE_INPUT_VALUE = Blockly.Arduino.valueToCode(this, "VALUE", Blockly.Arduino.ORDER_ATOMIC);
|
||||
let code = '';
|
||||
if (FIELD_TYPE === 'BASE64') {
|
||||
Blockly.Arduino.definitions_['include_rBase64'] = '#include <rBase64.h>';
|
||||
if (FIELD_OPTION === 'ENCODE') {
|
||||
code = 'rbase64.encode(' + VALUE_INPUT_VALUE + ')';
|
||||
} else {
|
||||
code = 'rbase64.decode(' + VALUE_INPUT_VALUE + ')';
|
||||
}
|
||||
} else {
|
||||
Blockly.Arduino.definitions_['include_URLCode'] = '#include <URLCode.h>';
|
||||
Blockly.Arduino.definitions_['var_declare_urlCode'] = 'URLCode urlCode;';
|
||||
if (FIELD_OPTION === 'ENCODE') {
|
||||
Blockly.Arduino.definitions_['function_urlEncode']
|
||||
= 'String urlEncode(String urlStr) {\n'
|
||||
+ ' urlCode.strcode = urlStr;\n'
|
||||
+ ' urlCode.urlencode();\n'
|
||||
+ ' return urlCode.urlcode;\n'
|
||||
+ '}\n';
|
||||
code = 'urlEncode(' + VALUE_INPUT_VALUE + ')';
|
||||
} else {
|
||||
Blockly.Arduino.definitions_['function_urlDecode']
|
||||
= 'String urlDecode(String urlStr) {\n'
|
||||
+ ' urlCode.urlcode = urlStr;\n'
|
||||
+ ' urlCode.urldecode();\n'
|
||||
+ ' return urlCode.strcode;\n'
|
||||
+ '}\n';
|
||||
code = 'urlDecode(' + VALUE_INPUT_VALUE + ')';
|
||||
}
|
||||
}
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
61
mixly/boards/default_src/arduino/generators/variables.js
Normal file
61
mixly/boards/default_src/arduino/generators/variables.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import { Variables } from 'blockly/core';
|
||||
|
||||
export const variables_get = function (_, generator) {
|
||||
// Variable getter.
|
||||
var code = generator.variableDB_.getName(this.getFieldValue('VAR'),
|
||||
Variables.NAME_TYPE);
|
||||
return [code, generator.ORDER_ATOMIC];
|
||||
}
|
||||
|
||||
export const variables_declare = function (_, generator) {
|
||||
var dropdown_type = this.getFieldValue('TYPE');
|
||||
var dropdown_variables_type = this.getFieldValue('variables_type');
|
||||
var argument0;
|
||||
var code = '';
|
||||
//TODO: settype to variable
|
||||
if (dropdown_variables_type == 'global_variate') {
|
||||
if (dropdown_type == 'String') {
|
||||
argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '""';
|
||||
} else {
|
||||
argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '0';
|
||||
}
|
||||
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
|
||||
Variables.NAME_TYPE);
|
||||
if (dropdown_type == 'String' || dropdown_type == 'char*')
|
||||
generator.definitions_['var_declare' + varName] = dropdown_type + ' ' + varName + ';';
|
||||
else
|
||||
generator.definitions_['var_declare' + varName] = 'volatile ' + dropdown_type + ' ' + varName + ';';
|
||||
|
||||
generator.setups_['setup_var' + varName] = varName + ' = ' + argument0 + ';';
|
||||
}
|
||||
else {
|
||||
if (dropdown_type == 'String') {
|
||||
argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '""';
|
||||
} else {
|
||||
argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '0';
|
||||
}
|
||||
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
|
||||
Variables.NAME_TYPE);
|
||||
code = dropdown_type + ' ' + varName + ' = ' + argument0 + ';\n';
|
||||
}
|
||||
//generator.variableTypes_[varName] = dropdown_type;//处理变量类型
|
||||
return code;
|
||||
}
|
||||
|
||||
export const variables_set = function (_, generator) {
|
||||
// Variable setter.
|
||||
var argument0 = generator.valueToCode(this, 'VALUE',
|
||||
generator.ORDER_ASSIGNMENT) || '0';
|
||||
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
|
||||
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_ASSIGNMENT);
|
||||
//修复强制类型转换不正确的bug
|
||||
var code = '((' + operator + ')(' + varName + '))';
|
||||
return [code, generator.ORDER_ATOMIC];
|
||||
}
|
||||
0
mixly/boards/default_src/arduino/index.js
Normal file
0
mixly/boards/default_src/arduino/index.js
Normal file
199
mixly/boards/default_src/arduino/others/names.js
Normal file
199
mixly/boards/default_src/arduino/others/names.js
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* @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 'blockly/core';
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
const Names = function (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();
|
||||
};
|
||||
|
||||
/**
|
||||
* 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';
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
Names.prototype.reset = function () {
|
||||
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
|
||||
*/
|
||||
Names.prototype.setVariableMap = function (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
|
||||
*/
|
||||
Names.prototype.getNameForUserVariable_ = function (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.
|
||||
*/
|
||||
Names.prototype.getName = function (name, type) {
|
||||
if (type == Variables.NAME_TYPE) {
|
||||
var varName = this.getNameForUserVariable_(name);
|
||||
if (varName) {
|
||||
name = varName;
|
||||
}
|
||||
}
|
||||
var normalized = name + '_' + type;
|
||||
|
||||
var isVarType = type == Variables.NAME_TYPE ||
|
||||
type == Names.DEVELOPER_VARIABLE_TYPE;
|
||||
|
||||
var prefix = isVarType ? this.variablePrefix_ : '';
|
||||
if (normalized in this.db_) {
|
||||
return prefix + this.db_[normalized];
|
||||
}
|
||||
var safeName = this.getDistinctName(name, type);
|
||||
this.db_[normalized] = safeName.substr(prefix.length);
|
||||
return safeName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a Blockly entity name to a legal exportable entity name.
|
||||
* Ensure that this is a new name not overlapping any previously defined name.
|
||||
* Also check against list of reserved words for the current language and
|
||||
* ensure name doesn't collide.
|
||||
* @param {string} name The Blockly entity name (no constraints).
|
||||
* @param {string} type The type of entity in Blockly
|
||||
* ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).
|
||||
* @return {string} An entity name that is legal in the exported language.
|
||||
*/
|
||||
Names.prototype.getDistinctName = function (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
|
||||
*/
|
||||
Names.prototype.safeName_ = function (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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
Names.equals = function (name1, name2) {
|
||||
return name1 == name2;
|
||||
};
|
||||
|
||||
export default Names;
|
||||
338
mixly/boards/default_src/arduino/others/procedures.js
Normal file
338
mixly/boards/default_src/arduino/others/procedures.js
Normal file
@@ -0,0 +1,338 @@
|
||||
/**
|
||||
* @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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Blockly.Procedures
|
||||
* @namespace
|
||||
*/
|
||||
import * as Blockly from 'blockly/core';
|
||||
import Variables from './variables';
|
||||
|
||||
const Procedures = {};
|
||||
|
||||
Procedures.DATA_TYPE = [
|
||||
...Variables.DATA_TYPE,
|
||||
[Blockly.Msg.MIXLY_OTHER, 'CUSTOM']
|
||||
];
|
||||
|
||||
/**
|
||||
* 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>
|
||||
let block = Blockly.utils.xml.createElement('block');
|
||||
block.setAttribute('type', 'procedures_defreturn');
|
||||
block.setAttribute('gap', 16);
|
||||
let 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>
|
||||
let 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>
|
||||
let 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 = 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;
|
||||
255
mixly/boards/default_src/arduino/others/variables.js
Normal file
255
mixly/boards/default_src/arduino/others/variables.js
Normal file
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* @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';
|
||||
|
||||
Variables.DATA_TYPE = [
|
||||
[Blockly.Msg.LANG_MATH_INT, 'int'],
|
||||
[Blockly.Msg.LANG_MATH_UNSIGNED_INT, 'unsigned int'],
|
||||
[Blockly.Msg.LANG_MATH_WORD, 'word'],
|
||||
[Blockly.Msg.LANG_MATH_LONG, 'long'],
|
||||
[Blockly.Msg.LANG_MATH_UNSIGNED_LONG, 'unsigned long'],
|
||||
[Blockly.Msg.LANG_MATH_FLOAT, 'float'],
|
||||
[Blockly.Msg.LANG_MATH_DOUBLE, 'double'],
|
||||
[Blockly.Msg.LANG_MATH_BOOLEAN, 'bool'],
|
||||
[Blockly.Msg.LANG_MATH_BYTE, 'byte'],
|
||||
[Blockly.Msg.LANG_MATH_CHAR, 'char'],
|
||||
[Blockly.Msg.LANG_MATH_UNSIGNED_CHAR, 'unsigned char'],
|
||||
[Blockly.Msg.LANG_MATH_STRING, 'String'],
|
||||
['uint8_t', 'uint8_t'],
|
||||
['uint16_t', 'uint16_t'],
|
||||
['uint32_t', 'uint32_t'],
|
||||
['uint64_t', 'uint64_t'],
|
||||
['int*', 'int*'],
|
||||
['unsigned int*', 'unsigned int*'],
|
||||
['word*', 'word*'],
|
||||
['long*', 'long*'],
|
||||
['unsigned long*', 'unsigned long*'],
|
||||
['float*', 'float*'],
|
||||
['double*', 'double*'],
|
||||
['bool*', 'bool*'],
|
||||
['byte*', 'byte*'],
|
||||
['char*', 'char*'],
|
||||
['unsigned char*', 'unsigned char*'],
|
||||
['String*', 'String*'],
|
||||
['uint8_t*', 'uint8_t*'],
|
||||
['uint16_t*', 'uint16_t*'],
|
||||
['uint32_t*', 'uint32_t*'],
|
||||
['uint64_t*', 'uint64_t*']
|
||||
];
|
||||
|
||||
/**
|
||||
* Find all user-created variables.
|
||||
* @param {!Blockly.Block|!Blockly.Workspace} root Root block or workspace.
|
||||
* @return {!Array.<string>} Array of variable names.
|
||||
*/
|
||||
Variables.allVariables = function (root) {
|
||||
var blocks;
|
||||
if (root.getDescendants) {
|
||||
// Root is Block.
|
||||
blocks = root.getDescendants();
|
||||
} else if (root.getAllBlocks) {
|
||||
// Root is Workspace.
|
||||
blocks = root.getAllBlocks();
|
||||
} else {
|
||||
throw 'Not Block or Workspace: ' + root;
|
||||
}
|
||||
var variableHash = Object.create(null);
|
||||
// Iterate through every block and add each variable to the hash.
|
||||
for (var x = 0; x < blocks.length; x++) {
|
||||
var blockVariables = blocks[x].getVars();
|
||||
for (var y = 0; y < blockVariables.length; y++) {
|
||||
var varName = blockVariables[y];
|
||||
// Variable name may be null if the block is only half-built.
|
||||
if (varName) {
|
||||
variableHash[varName] = varName;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Flatten the hash into a list.
|
||||
var variableList = [];
|
||||
for (var name in variableHash) {
|
||||
variableList.push(variableHash[name]);
|
||||
}
|
||||
return variableList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Find all instances of the specified variable and rename them.
|
||||
* @param {string} oldName Variable to rename.
|
||||
* @param {string} newName New variable name.
|
||||
* @param {!Blockly.Workspace} workspace Workspace rename variables in.
|
||||
*/
|
||||
Variables.renameVariable = function (oldName, newName, workspace) {
|
||||
Blockly.Events.setGroup(true);
|
||||
var blocks = workspace.getAllBlocks();
|
||||
// Iterate through every block.
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
blocks[i].renameVar(oldName, newName);
|
||||
}
|
||||
Blockly.Events.setGroup(false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct the blocks required by the flyout for the variable category.
|
||||
* @param {!Blockly.Workspace} workspace The workspace contianing variables.
|
||||
* @return {!Array.<!Element>} Array of XML block elements.
|
||||
*/
|
||||
Variables.flyoutCategory = function (workspace) {
|
||||
var variableList = Variables.allVariables(workspace);
|
||||
//variableList.sort(goog.string.caseInsensitiveCompare);
|
||||
|
||||
// In addition to the user's variables, we also want to display the default
|
||||
// variable name at the top. We also don't want this duplicated if the
|
||||
// user has created a variable of the same name.
|
||||
|
||||
//在变量分类里添加默认变量取值与赋值模块时使用
|
||||
//goog.array.remove(variableList, Blockly.Msg.VARIABLES_DEFAULT_NAME);
|
||||
//variableList.unshift(Blockly.Msg.VARIABLES_DEFAULT_NAME);
|
||||
|
||||
var xmlList = [];
|
||||
|
||||
|
||||
if (Blockly.Blocks['variables_declare']) {
|
||||
//增加variables_declare模块
|
||||
let block = Blockly.utils.xml.createElement('block');
|
||||
block.setAttribute('type', 'variables_declare');
|
||||
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);
|
||||
}
|
||||
if (Blockly.Blocks['variables_get']) {
|
||||
//增加variables_declare模块
|
||||
var block = Blockly.utils.xml.createElement('block');
|
||||
block.setAttribute('type', 'variables_get');
|
||||
xmlList.push(block);
|
||||
}
|
||||
*/
|
||||
|
||||
//change tyep
|
||||
if (Blockly.Blocks['variables_change']) {
|
||||
//增加variables_declare模块
|
||||
let block = Blockly.utils.xml.createElement('block');
|
||||
block.setAttribute('type', 'variables_change');
|
||||
xmlList.push(block);
|
||||
}
|
||||
for (var i = 0; i < variableList.length; i++) {
|
||||
//if(i==0&&!(Blockly.Arduino.definitions_['var_declare'+'item'])){
|
||||
// continue;
|
||||
//}
|
||||
|
||||
if (Blockly.Blocks['variables_set']) {
|
||||
let block = Blockly.utils.xml.createElement('block');
|
||||
block.setAttribute('type', 'variables_set');
|
||||
if (Blockly.Blocks['variables_get']) {
|
||||
block.setAttribute('gap', 8);
|
||||
}
|
||||
let field = Blockly.utils.xml.createElement('field', null, variableList[i]);
|
||||
field.setAttribute('name', 'VAR');
|
||||
let 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);
|
||||
}
|
||||
let field = Blockly.utils.xml.createElement('field', null, variableList[i]);
|
||||
field.setAttribute('name', 'VAR');
|
||||
let name = Blockly.utils.xml.createTextNode(variableList[i]);
|
||||
field.appendChild(name);
|
||||
block.appendChild(field);
|
||||
xmlList.push(block);
|
||||
}
|
||||
}
|
||||
return xmlList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a new variable name that is not yet being used. This will try to
|
||||
* generate single letter variable names in the range 'i' to 'z' to start with.
|
||||
* If no unique name is located it will try 'i' to 'z', 'a' to 'h',
|
||||
* then 'i2' to 'z2' etc. Skip 'l'.
|
||||
* @param {!Blockly.Workspace} workspace The workspace to be unique in.
|
||||
* @return {string} New variable name.
|
||||
*/
|
||||
Variables.generateUniqueName = function (workspace) {
|
||||
var variableList = Variables.allVariables(workspace);
|
||||
var newName = '';
|
||||
if (variableList.length) {
|
||||
var nameSuffix = 1;
|
||||
var letters = 'ijkmnopqrstuvwxyzabcdefgh'; // No 'l'.
|
||||
var letterIndex = 0;
|
||||
var potName = letters.charAt(letterIndex);
|
||||
while (!newName) {
|
||||
var inUse = false;
|
||||
for (var i = 0; i < variableList.length; i++) {
|
||||
if (variableList[i] == potName) {
|
||||
// This potential name is already used.
|
||||
inUse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (inUse) {
|
||||
// Try the next potential name.
|
||||
letterIndex++;
|
||||
if (letterIndex == letters.length) {
|
||||
// Reached the end of the character sequence so back to 'i'.
|
||||
// a new suffix.
|
||||
letterIndex = 0;
|
||||
nameSuffix++;
|
||||
}
|
||||
potName = letters.charAt(letterIndex);
|
||||
if (nameSuffix > 1) {
|
||||
potName += nameSuffix;
|
||||
}
|
||||
} else {
|
||||
// We can use the current potential name.
|
||||
newName = potName;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newName = 'i';
|
||||
}
|
||||
return newName;
|
||||
};
|
||||
|
||||
export default Variables;
|
||||
32
mixly/boards/default_src/arduino/package.json
Normal file
32
mixly/boards/default_src/arduino/package.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "@mixly/arduino",
|
||||
"version": "1.8.0",
|
||||
"description": "适用于mixly的arduino模块",
|
||||
"scripts": {
|
||||
"build:dev": "webpack --config=webpack.dev.js",
|
||||
"build:prod": "npm run build:examples & webpack --config=webpack.prod.js",
|
||||
"build:examples": "node ../../../scripts/build-examples.js -t special",
|
||||
"build:examples:ob": "node ../../../scripts/build-examples.js -t special --obfuscate",
|
||||
"publish:board": "npm publish --registry https://registry.npmjs.org/"
|
||||
},
|
||||
"main": "./export.js",
|
||||
"author": "Mixly Team",
|
||||
"keywords": [
|
||||
"mixly",
|
||||
"mixly-plugin",
|
||||
"arduino"
|
||||
],
|
||||
"homepage": "https://gitee.com/bnu_mixly/mixly3/tree/master/boards/default_src/arduino",
|
||||
"bugs": {
|
||||
"url": "https://gitee.com/bnu_mixly/mixly3/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitee.com/bnu_mixly/mixly3.git",
|
||||
"directory": "default_src/arduino"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"license": "Apache 2.0"
|
||||
}
|
||||
0
mixly/boards/default_src/arduino/template.xml
Normal file
0
mixly/boards/default_src/arduino/template.xml
Normal file
1185
mixly/boards/default_src/arduino/templates/json/cities.json
Normal file
1185
mixly/boards/default_src/arduino/templates/json/cities.json
Normal file
File diff suppressed because it is too large
Load Diff
13
mixly/boards/default_src/arduino/webpack.common.js
Normal file
13
mixly/boards/default_src/arduino/webpack.common.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const common = require('../../../webpack.common');
|
||||
const { merge } = require('webpack-merge');
|
||||
|
||||
module.exports = merge(common, {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(txt|c|cpp|h|hpp)$/,
|
||||
type: 'asset/source'
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
21
mixly/boards/default_src/arduino/webpack.dev.js
Normal file
21
mixly/boards/default_src/arduino/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
mixly/boards/default_src/arduino/webpack.prod.js
Normal file
27
mixly/boards/default_src/arduino/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