Files
mixly3-server/mixly/boards/default_src/arduino/arduino_generator.js
2026-01-24 16:16:48 +08:00

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();