166 lines
6.4 KiB
JavaScript
166 lines
6.4 KiB
JavaScript
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();
|