diff --git a/externs/generator-externs.js b/externs/generator-externs.js index 450735e255a..ab61a650406 100644 --- a/externs/generator-externs.js +++ b/externs/generator-externs.js @@ -15,5 +15,10 @@ goog.provide('Blockly.inputTypes'); goog.provide('Blockly.utils.global'); goog.provide('Blockly.utils.object'); goog.provide('Blockly.utils.string'); +goog.provide('Blockly.Names'); +goog.provide('Blockly.Variables'); +goog.provide('Blockly.Workspace'); +goog.provide('Blockly.Block'); +goog.provide('Blockly.Constants.Loops'); var Blockly; diff --git a/generators/dart.js b/generators/dart.js index 45df8d3543f..939ceddb9ce 100644 --- a/generators/dart.js +++ b/generators/dart.js @@ -9,18 +9,24 @@ */ 'use strict'; -goog.provide('Blockly.Dart'); +goog.module('Blockly.Dart'); +goog.module.declareLegacyNamespace(); -goog.require('Blockly.Generator'); -goog.require('Blockly.inputTypes'); -goog.require('Blockly.utils.string'); +const Blockly = goog.require('Blockly'); +const {Generator} = goog.require('Blockly.Generator'); +const {inputTypes} = goog.require('Blockly.inputTypes'); +const stringUtils = goog.require('Blockly.utils.string'); +const {Names} = goog.require('Blockly.Names'); +const Variables = goog.require('Blockly.Variables'); +const {Workspace} = goog.requireType('Blockly.Workspace'); +const {Block} = goog.requireType('Blockly.Block'); /** * Dart code generator. - * @type {!Blockly.Generator} + * @type {!Generator} */ -Blockly.Dart = new Blockly.Generator('Dart'); +const Dart = new Generator('Dart'); /** * List of illegal variable names. @@ -29,7 +35,7 @@ Blockly.Dart = new Blockly.Generator('Dart'); * accidentally clobbering a built-in object or function. * @private */ -Blockly.Dart.addReservedWords( +Dart.addReservedWords( // https://www.dartlang.org/docs/spec/latest/dart-language-specification.pdf // Section 16.1.1 'assert,break,case,catch,class,const,continue,default,do,else,enum,' + @@ -52,41 +58,41 @@ Blockly.Dart.addReservedWords( * Order of operation ENUMs. * https://dart.dev/guides/language/language-tour#operators */ -Blockly.Dart.ORDER_ATOMIC = 0; // 0 "" ... -Blockly.Dart.ORDER_UNARY_POSTFIX = 1; // expr++ expr-- () [] . ?. -Blockly.Dart.ORDER_UNARY_PREFIX = 2; // -expr !expr ~expr ++expr --expr -Blockly.Dart.ORDER_MULTIPLICATIVE = 3; // * / % ~/ -Blockly.Dart.ORDER_ADDITIVE = 4; // + - -Blockly.Dart.ORDER_SHIFT = 5; // << >> -Blockly.Dart.ORDER_BITWISE_AND = 6; // & -Blockly.Dart.ORDER_BITWISE_XOR = 7; // ^ -Blockly.Dart.ORDER_BITWISE_OR = 8; // | -Blockly.Dart.ORDER_RELATIONAL = 9; // >= > <= < as is is! -Blockly.Dart.ORDER_EQUALITY = 10; // == != -Blockly.Dart.ORDER_LOGICAL_AND = 11; // && -Blockly.Dart.ORDER_LOGICAL_OR = 12; // || -Blockly.Dart.ORDER_IF_NULL = 13; // ?? -Blockly.Dart.ORDER_CONDITIONAL = 14; // expr ? expr : expr -Blockly.Dart.ORDER_CASCADE = 15; // .. -Blockly.Dart.ORDER_ASSIGNMENT = 16; // = *= /= ~/= %= += -= <<= >>= &= ^= |= -Blockly.Dart.ORDER_NONE = 99; // (...) +Dart.ORDER_ATOMIC = 0; // 0 "" ... +Dart.ORDER_UNARY_POSTFIX = 1; // expr++ expr-- () [] . ?. +Dart.ORDER_UNARY_PREFIX = 2; // -expr !expr ~expr ++expr --expr +Dart.ORDER_MULTIPLICATIVE = 3; // * / % ~/ +Dart.ORDER_ADDITIVE = 4; // + - +Dart.ORDER_SHIFT = 5; // << >> +Dart.ORDER_BITWISE_AND = 6; // & +Dart.ORDER_BITWISE_XOR = 7; // ^ +Dart.ORDER_BITWISE_OR = 8; // | +Dart.ORDER_RELATIONAL = 9; // >= > <= < as is is! +Dart.ORDER_EQUALITY = 10; // == != +Dart.ORDER_LOGICAL_AND = 11; // && +Dart.ORDER_LOGICAL_OR = 12; // || +Dart.ORDER_IF_NULL = 13; // ?? +Dart.ORDER_CONDITIONAL = 14; // expr ? expr : expr +Dart.ORDER_CASCADE = 15; // .. +Dart.ORDER_ASSIGNMENT = 16; // = *= /= ~/= %= += -= <<= >>= &= ^= |= +Dart.ORDER_NONE = 99; // (...) /** * Whether the init method has been called. * @type {?boolean} */ -Blockly.Dart.isInitialized = false; +Dart.isInitialized = false; /** * Initialise the database of variable names. - * @param {!Blockly.Workspace} workspace Workspace to generate code from. + * @param {!Workspace} workspace Workspace to generate code from. */ -Blockly.Dart.init = function(workspace) { +Dart.init = function(workspace) { // Call Blockly.Generator's init. Object.getPrototypeOf(this).init.call(this); if (!this.nameDB_) { - this.nameDB_ = new Blockly.Names(this.RESERVED_WORDS_); + this.nameDB_ = new Names(this.RESERVED_WORDS_); } else { this.nameDB_.reset(); } @@ -97,14 +103,14 @@ Blockly.Dart.init = function(workspace) { const defvars = []; // Add developer variables (not created or named by the user). - const devVarList = Blockly.Variables.allDeveloperVariables(workspace); + const devVarList = Variables.allDeveloperVariables(workspace); for (let i = 0; i < devVarList.length; i++) { defvars.push(this.nameDB_.getName(devVarList[i], - Blockly.Names.DEVELOPER_VARIABLE_TYPE)); + Names.DEVELOPER_VARIABLE_TYPE)); } // Add user variables, but only ones that are being used. - const variables = Blockly.Variables.allUsedVarModels(workspace); + const variables = Variables.allUsedVarModels(workspace); for (let i = 0; i < variables.length; i++) { defvars.push(this.nameDB_.getName(variables[i].getId(), Blockly.VARIABLE_CATEGORY_NAME)); @@ -123,7 +129,7 @@ Blockly.Dart.init = function(workspace) { * @param {string} code Generated code. * @return {string} Completed code. */ -Blockly.Dart.finish = function(code) { +Dart.finish = function(code) { // Indent every line. if (code) { code = this.prefixLines(code, this.INDENT); @@ -156,7 +162,7 @@ Blockly.Dart.finish = function(code) { * @param {string} line Line of generated code. * @return {string} Legal line of code. */ -Blockly.Dart.scrubNakedValue = function(line) { +Dart.scrubNakedValue = function(line) { return line + ';\n'; }; @@ -166,7 +172,7 @@ Blockly.Dart.scrubNakedValue = function(line) { * @return {string} Dart string. * @protected */ -Blockly.Dart.quote_ = function(string) { +Dart.quote_ = function(string) { // Can't use goog.string.quote since $ must also be escaped. string = string.replace(/\\/g, '\\\\') .replace(/\n/g, '\\\n') @@ -182,7 +188,7 @@ Blockly.Dart.quote_ = function(string) { * @return {string} Dart string. * @protected */ -Blockly.Dart.multiline_quote_ = function (string) { +Dart.multiline_quote_ = function (string) { const lines = string.split(/\n/g).map(this.quote_); // Join with the following, plus a newline: // + '\n' + @@ -193,20 +199,20 @@ Blockly.Dart.multiline_quote_ = function (string) { * Common tasks for generating Dart 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 {!Block} block The current block. * @param {string} code The Dart code created for this block. * @param {boolean=} opt_thisOnly True to generate code for only this statement. * @return {string} Dart code with comments and subsequent blocks added. * @protected */ -Blockly.Dart.scrub_ = function(block, code, opt_thisOnly) { +Dart.scrub_ = function(block, code, opt_thisOnly) { let 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) { - comment = Blockly.utils.string.wrap(comment, this.COMMENT_WRAP - 3); + comment = stringUtils.wrap(comment, this.COMMENT_WRAP - 3); if (block.getProcedureDef) { // Use documentation comment for function comments. commentCode += this.prefixLines(comment + '\n', '/// '); @@ -217,7 +223,7 @@ Blockly.Dart.scrub_ = function(block, code, opt_thisOnly) { // Collect comments for all value arguments. // Don't collect comments for nested statements. for (let i = 0; i < block.inputList.length; i++) { - if (block.inputList[i].type === Blockly.inputTypes.VALUE) { + if (block.inputList[i].type === inputTypes.VALUE) { const childBlock = block.inputList[i].connection.targetBlock(); if (childBlock) { comment = this.allNestedComments(childBlock); @@ -235,14 +241,14 @@ Blockly.Dart.scrub_ = function(block, code, opt_thisOnly) { /** * Gets a property and adjusts the value while taking into account indexing. - * @param {!Blockly.Block} block The block. + * @param {!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. * @param {number=} opt_order The highest order acting on this value. * @return {string|number} */ -Blockly.Dart.getAdjusted = function(block, atId, opt_delta, opt_negate, +Dart.getAdjusted = function(block, atId, opt_delta, opt_negate, opt_order) { let delta = opt_delta || 0; let order = opt_order || this.ORDER_NONE; @@ -295,3 +301,5 @@ Blockly.Dart.getAdjusted = function(block, atId, opt_delta, opt_negate, } return at; }; + +exports = Dart; diff --git a/generators/dart/colour.js b/generators/dart/colour.js index e1920292884..7f6f621ac0e 100644 --- a/generators/dart/colour.js +++ b/generators/dart/colour.js @@ -9,26 +9,26 @@ */ 'use strict'; -goog.provide('Blockly.Dart.colour'); +goog.module('Blockly.Dart.colour'); -goog.require('Blockly.Dart'); +const Dart = goog.require('Blockly.Dart'); -Blockly.Dart.addReservedWords('Math'); +Dart.addReservedWords('Math'); -Blockly.Dart['colour_picker'] = function(block) { +Dart['colour_picker'] = function(block) { // Colour picker. - const code = Blockly.Dart.quote_(block.getFieldValue('COLOUR')); - return [code, Blockly.Dart.ORDER_ATOMIC]; + const code = Dart.quote_(block.getFieldValue('COLOUR')); + return [code, Dart.ORDER_ATOMIC]; }; -Blockly.Dart['colour_random'] = function(block) { +Dart['colour_random'] = function(block) { // Generate a random colour. - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'colour_random', - ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '() {', + ['String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '() {', ' String hex = \'0123456789abcdef\';', ' var rnd = new Math.Random();', ' return \'#${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}\'', @@ -36,23 +36,23 @@ Blockly.Dart['colour_random'] = function(block) { ' \'${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}\';', '}']); const code = functionName + '()'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['colour_rgb'] = function(block) { +Dart['colour_rgb'] = function(block) { // Compose a colour from RGB components expressed as percentages. - const red = Blockly.Dart.valueToCode(block, 'RED', - Blockly.Dart.ORDER_NONE) || 0; - const green = Blockly.Dart.valueToCode(block, 'GREEN', - Blockly.Dart.ORDER_NONE) || 0; - const blue = Blockly.Dart.valueToCode(block, 'BLUE', - Blockly.Dart.ORDER_NONE) || 0; + const red = Dart.valueToCode(block, 'RED', + Dart.ORDER_NONE) || 0; + const green = Dart.valueToCode(block, 'GREEN', + Dart.ORDER_NONE) || 0; + const blue = Dart.valueToCode(block, 'BLUE', + Dart.ORDER_NONE) || 0; - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'colour_rgb', - ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(num r, num g, num b) {', ' num rn = (Math.max(Math.min(r, 100), 0) * 2.55).round();', ' String rs = rn.toInt().toRadixString(16);', @@ -69,23 +69,23 @@ Blockly.Dart['colour_rgb'] = function(block) { ' return \'#$rs$gs$bs\';', '}']); const code = functionName + '(' + red + ', ' + green + ', ' + blue + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['colour_blend'] = function(block) { +Dart['colour_blend'] = function(block) { // Blend two colours together. - const c1 = Blockly.Dart.valueToCode(block, 'COLOUR1', - Blockly.Dart.ORDER_NONE) || '\'#000000\''; - const c2 = Blockly.Dart.valueToCode(block, 'COLOUR2', - Blockly.Dart.ORDER_NONE) || '\'#000000\''; - const ratio = Blockly.Dart.valueToCode(block, 'RATIO', - Blockly.Dart.ORDER_NONE) || 0.5; + const c1 = Dart.valueToCode(block, 'COLOUR1', + Dart.ORDER_NONE) || '\'#000000\''; + const c2 = Dart.valueToCode(block, 'COLOUR2', + Dart.ORDER_NONE) || '\'#000000\''; + const ratio = Dart.valueToCode(block, 'RATIO', + Dart.ORDER_NONE) || 0.5; - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'colour_blend', - ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(String c1, String c2, num ratio) {', ' ratio = Math.max(Math.min(ratio, 1), 0);', ' int r1 = int.parse(\'0x${c1.substring(1, 3)}\');', @@ -109,5 +109,5 @@ Blockly.Dart['colour_blend'] = function(block) { ' return \'#$rs$gs$bs\';', '}']); const code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; diff --git a/generators/dart/lists.js b/generators/dart/lists.js index 05419a54b1f..693f99c1a19 100644 --- a/generators/dart/lists.js +++ b/generators/dart/lists.js @@ -9,80 +9,81 @@ */ 'use strict'; -goog.provide('Blockly.Dart.lists'); +goog.module('Blockly.Dart.lists'); -goog.require('Blockly.Dart'); +const Blockly = goog.require('Blockly'); +const Dart = goog.require('Blockly.Dart'); -Blockly.Dart.addReservedWords('Math'); +Dart.addReservedWords('Math'); -Blockly.Dart['lists_create_empty'] = function(block) { +Dart['lists_create_empty'] = function(block) { // Create an empty list. - return ['[]', Blockly.Dart.ORDER_ATOMIC]; + return ['[]', Dart.ORDER_ATOMIC]; }; -Blockly.Dart['lists_create_with'] = function(block) { +Dart['lists_create_with'] = function(block) { // Create a list with any number of elements of any type. const elements = new Array(block.itemCount_); for (let i = 0; i < block.itemCount_; i++) { - elements[i] = Blockly.Dart.valueToCode(block, 'ADD' + i, - Blockly.Dart.ORDER_NONE) || 'null'; + elements[i] = Dart.valueToCode(block, 'ADD' + i, + Dart.ORDER_NONE) || 'null'; } const code = '[' + elements.join(', ') + ']'; - return [code, Blockly.Dart.ORDER_ATOMIC]; + return [code, Dart.ORDER_ATOMIC]; }; -Blockly.Dart['lists_repeat'] = function(block) { +Dart['lists_repeat'] = function(block) { // Create a list with one element repeated. - const element = Blockly.Dart.valueToCode(block, 'ITEM', - Blockly.Dart.ORDER_NONE) || 'null'; - const repeatCount = Blockly.Dart.valueToCode(block, 'NUM', - Blockly.Dart.ORDER_NONE) || '0'; + const element = Dart.valueToCode(block, 'ITEM', + Dart.ORDER_NONE) || 'null'; + const repeatCount = Dart.valueToCode(block, 'NUM', + Dart.ORDER_NONE) || '0'; const code = 'new List.filled(' + repeatCount + ', ' + element + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['lists_length'] = function(block) { +Dart['lists_length'] = function(block) { // String or array length. - const list = Blockly.Dart.valueToCode(block, 'VALUE', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]'; - return [list + '.length', Blockly.Dart.ORDER_UNARY_POSTFIX]; + const list = Dart.valueToCode(block, 'VALUE', + Dart.ORDER_UNARY_POSTFIX) || '[]'; + return [list + '.length', Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['lists_isEmpty'] = function(block) { +Dart['lists_isEmpty'] = function(block) { // Is the string null or array empty? - const list = Blockly.Dart.valueToCode(block, 'VALUE', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]'; - return [list + '.isEmpty', Blockly.Dart.ORDER_UNARY_POSTFIX]; + const list = Dart.valueToCode(block, 'VALUE', + Dart.ORDER_UNARY_POSTFIX) || '[]'; + return [list + '.isEmpty', Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['lists_indexOf'] = function(block) { +Dart['lists_indexOf'] = function(block) { // Find an item in the list. const operator = block.getFieldValue('END') === 'FIRST' ? 'indexOf' : 'lastIndexOf'; - const item = Blockly.Dart.valueToCode(block, 'FIND', - Blockly.Dart.ORDER_NONE) || '\'\''; - const list = Blockly.Dart.valueToCode(block, 'VALUE', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]'; + const item = Dart.valueToCode(block, 'FIND', + Dart.ORDER_NONE) || '\'\''; + const list = Dart.valueToCode(block, 'VALUE', + Dart.ORDER_UNARY_POSTFIX) || '[]'; const code = list + '.' + operator + '(' + item + ')'; if (block.workspace.options.oneBasedIndex) { - return [code + ' + 1', Blockly.Dart.ORDER_ADDITIVE]; + return [code + ' + 1', Dart.ORDER_ADDITIVE]; } - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['lists_getIndex'] = function(block) { +Dart['lists_getIndex'] = function(block) { // Get element at index. // Note: Until January 2013 this block did not have MODE or WHERE inputs. const mode = block.getFieldValue('MODE') || 'GET'; const where = block.getFieldValue('WHERE') || 'FROM_START'; const listOrder = (where === 'RANDOM' || where === 'FROM_END') ? - Blockly.Dart.ORDER_NONE : Blockly.Dart.ORDER_UNARY_POSTFIX; - let list = Blockly.Dart.valueToCode(block, 'VALUE', listOrder) || '[]'; + Dart.ORDER_NONE : Dart.ORDER_UNARY_POSTFIX; + let list = Dart.valueToCode(block, 'VALUE', listOrder) || '[]'; // Cache non-trivial values to variables to prevent repeated look-ups. // Closure, which accesses and modifies 'list'. function cacheList() { - const listVar = Blockly.Dart.nameDB_.getDistinctName( + const listVar = Dart.nameDB_.getDistinctName( 'tmp_list', Blockly.VARIABLE_CATEGORY_NAME); const code = 'List ' + listVar + ' = ' + list + ';\n'; list = listVar; @@ -95,11 +96,11 @@ Blockly.Dart['lists_getIndex'] = function(block) { !list.match(/^\w+$/)) { // `list` is an expression, so we may not evaluate it more than once. if (where === 'RANDOM') { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; // We can use multiple statements. let code = cacheList(); - const xVar = Blockly.Dart.nameDB_.getDistinctName( + const xVar = Dart.nameDB_.getDistinctName( 'tmp_x', Blockly.VARIABLE_CATEGORY_NAME); code += 'int ' + xVar + ' = new Math.Random().nextInt(' + list + '.length);\n'; @@ -108,36 +109,36 @@ Blockly.Dart['lists_getIndex'] = function(block) { } else { // where === 'FROM_END' if (mode === 'REMOVE') { // We can use multiple statements. - const at = Blockly.Dart.getAdjusted(block, 'AT', 1, false, - Blockly.Dart.ORDER_ADDITIVE); + const at = Dart.getAdjusted(block, 'AT', 1, false, + Dart.ORDER_ADDITIVE); let code = cacheList(); code += list + '.removeAt(' + list + '.length' + ' - ' + at + ');\n'; return code; } else if (mode === 'GET') { - const at = Blockly.Dart.getAdjusted(block, 'AT', 1); + const at = Dart.getAdjusted(block, 'AT', 1); // We need to create a procedure to avoid reevaluating values. - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'lists_get_from_end', - ['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['dynamic ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List my_list, num x) {', ' x = my_list.length - x;', ' return my_list[x];', '}']); const code = functionName + '(' + list + ', ' + at + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } else if (mode === 'GET_REMOVE') { - const at = Blockly.Dart.getAdjusted(block, 'AT', 1); + const at = Dart.getAdjusted(block, 'AT', 1); // We need to create a procedure to avoid reevaluating values. - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'lists_remove_from_end', - ['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['dynamic ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List my_list, num x) {', ' x = my_list.length - x;', ' return my_list.removeAt(x);', '}']); const code = functionName + '(' + list + ', ' + at + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } } } else { @@ -147,10 +148,10 @@ Blockly.Dart['lists_getIndex'] = function(block) { case 'FIRST': if (mode === 'GET') { const code = list + '.first'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } else if (mode === 'GET_REMOVE') { const code = list + '.removeAt(0)'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } else if (mode === 'REMOVE') { return list + '.removeAt(0);\n'; } @@ -158,37 +159,37 @@ Blockly.Dart['lists_getIndex'] = function(block) { case 'LAST': if (mode === 'GET') { const code = list + '.last'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } else if (mode === 'GET_REMOVE') { const code = list + '.removeLast()'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } else if (mode === 'REMOVE') { return list + '.removeLast();\n'; } break; case 'FROM_START': { - const at = Blockly.Dart.getAdjusted(block, 'AT'); + const at = Dart.getAdjusted(block, 'AT'); if (mode === 'GET') { const code = list + '[' + at + ']'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } else if (mode === 'GET_REMOVE') { const code = list + '.removeAt(' + at + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } else if (mode === 'REMOVE') { return list + '.removeAt(' + at + ');\n'; } break; } case 'FROM_END': { - const at = Blockly.Dart.getAdjusted(block, 'AT', 1, false, - Blockly.Dart.ORDER_ADDITIVE); + const at = Dart.getAdjusted(block, 'AT', 1, false, + Dart.ORDER_ADDITIVE); if (mode === 'GET') { const code = list + '[' + list + '.length - ' + at + ']'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } else if (mode === 'GET_REMOVE' || mode === 'REMOVE') { const code = list + '.removeAt(' + list + '.length - ' + at + ')'; if (mode === 'GET_REMOVE') { - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } else if (mode === 'REMOVE') { return code + ';\n'; } @@ -196,11 +197,11 @@ Blockly.Dart['lists_getIndex'] = function(block) { break; } case 'RANDOM': - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; if (mode === 'REMOVE') { // We can use multiple statements. - const xVar = Blockly.Dart.nameDB_.getDistinctName( + const xVar = Dart.nameDB_.getDistinctName( 'tmp_x', Blockly.VARIABLE_CATEGORY_NAME); let code = 'int ' + xVar + ' = new Math.Random().nextInt(' + list + '.length);\n'; @@ -208,24 +209,24 @@ Blockly.Dart['lists_getIndex'] = function(block) { return code; } else if (mode === 'GET') { const functionName = - Blockly.Dart.provideFunction_('lists_get_random_item', [ - 'dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + Dart.provideFunction_('lists_get_random_item', [ + 'dynamic ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List my_list) {', ' int x = new Math.Random().nextInt(my_list.length);', ' return my_list[x];', '}' ]); const code = functionName + '(' + list + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } else if (mode === 'GET_REMOVE') { const functionName = - Blockly.Dart.provideFunction_('lists_remove_random_item', [ - 'dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + Dart.provideFunction_('lists_remove_random_item', [ + 'dynamic ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List my_list) {', ' int x = new Math.Random().nextInt(my_list.length);', ' return my_list.removeAt(x);', '}' ]); const code = functionName + '(' + list + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } break; } @@ -233,22 +234,22 @@ Blockly.Dart['lists_getIndex'] = function(block) { throw Error('Unhandled combination (lists_getIndex).'); }; -Blockly.Dart['lists_setIndex'] = function(block) { +Dart['lists_setIndex'] = function(block) { // Set element at index. // Note: Until February 2013 this block did not have MODE or WHERE inputs. const mode = block.getFieldValue('MODE') || 'GET'; const where = block.getFieldValue('WHERE') || 'FROM_START'; - let list = Blockly.Dart.valueToCode(block, 'LIST', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]'; - const value = Blockly.Dart.valueToCode(block, 'TO', - Blockly.Dart.ORDER_ASSIGNMENT) || 'null'; + let list = Dart.valueToCode(block, 'LIST', + Dart.ORDER_UNARY_POSTFIX) || '[]'; + const value = Dart.valueToCode(block, 'TO', + Dart.ORDER_ASSIGNMENT) || 'null'; // Cache non-trivial values to variables to prevent repeated look-ups. // Closure, which accesses and modifies 'list'. function cacheList() { if (list.match(/^\w+$/)) { return ''; } - const listVar = Blockly.Dart.nameDB_.getDistinctName( + const listVar = Dart.nameDB_.getDistinctName( 'tmp_list', Blockly.VARIABLE_CATEGORY_NAME); const code = 'List ' + listVar + ' = ' + list + ';\n'; list = listVar; @@ -272,7 +273,7 @@ Blockly.Dart['lists_setIndex'] = function(block) { } break; case 'FROM_START': { - const at = Blockly.Dart.getAdjusted(block, 'AT'); + const at = Dart.getAdjusted(block, 'AT'); if (mode === 'SET') { return list + '[' + at + '] = ' + value + ';\n'; } else if (mode === 'INSERT') { @@ -281,8 +282,8 @@ Blockly.Dart['lists_setIndex'] = function(block) { break; } case 'FROM_END': { - const at = Blockly.Dart.getAdjusted( - block, 'AT', 1, false, Blockly.Dart.ORDER_ADDITIVE); + const at = Dart.getAdjusted( + block, 'AT', 1, false, Dart.ORDER_ADDITIVE); let code = cacheList(); if (mode === 'SET') { code += list + '[' + list + '.length - ' + at + '] = ' + value + @@ -296,10 +297,10 @@ Blockly.Dart['lists_setIndex'] = function(block) { break; } case 'RANDOM': { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; let code = cacheList(); - const xVar = Blockly.Dart.nameDB_.getDistinctName( + const xVar = Dart.nameDB_.getDistinctName( 'tmp_x', Blockly.VARIABLE_CATEGORY_NAME); code += 'int ' + xVar + ' = new Math.Random().nextInt(' + list + '.length);\n'; @@ -316,10 +317,10 @@ Blockly.Dart['lists_setIndex'] = function(block) { throw Error('Unhandled combination (lists_setIndex).'); }; -Blockly.Dart['lists_getSublist'] = function(block) { +Dart['lists_getSublist'] = function(block) { // Get sublist. - const list = Blockly.Dart.valueToCode(block, 'LIST', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]'; + const list = Dart.valueToCode(block, 'LIST', + Dart.ORDER_UNARY_POSTFIX) || '[]'; const where1 = block.getFieldValue('WHERE1'); const where2 = block.getFieldValue('WHERE2'); let code; @@ -329,11 +330,11 @@ Blockly.Dart['lists_getSublist'] = function(block) { let at1; switch (where1) { case 'FROM_START': - at1 = Blockly.Dart.getAdjusted(block, 'AT1'); + at1 = Dart.getAdjusted(block, 'AT1'); break; case 'FROM_END': - at1 = Blockly.Dart.getAdjusted(block, 'AT1', 1, false, - Blockly.Dart.ORDER_ADDITIVE); + at1 = Dart.getAdjusted(block, 'AT1', 1, false, + Dart.ORDER_ADDITIVE); at1 = list + '.length - ' + at1; break; case 'FIRST': @@ -345,11 +346,11 @@ Blockly.Dart['lists_getSublist'] = function(block) { let at2; switch (where2) { case 'FROM_START': - at2 = Blockly.Dart.getAdjusted(block, 'AT2', 1); + at2 = Dart.getAdjusted(block, 'AT2', 1); break; case 'FROM_END': - at2 = Blockly.Dart.getAdjusted(block, 'AT2', 0, false, - Blockly.Dart.ORDER_ADDITIVE); + at2 = Dart.getAdjusted(block, 'AT2', 0, false, + Dart.ORDER_ADDITIVE); at2 = list + '.length - ' + at2; break; case 'LAST': @@ -364,11 +365,11 @@ Blockly.Dart['lists_getSublist'] = function(block) { code = list + '.sublist(' + at1 + ', ' + at2 + ')'; } } else { - const at1 = Blockly.Dart.getAdjusted(block, 'AT1'); - const at2 = Blockly.Dart.getAdjusted(block, 'AT2'); - const functionName = Blockly.Dart.provideFunction_( + const at1 = Dart.getAdjusted(block, 'AT1'); + const at2 = Dart.getAdjusted(block, 'AT2'); + const functionName = Dart.provideFunction_( 'lists_get_sublist', - ['List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['List ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List list, String where1, num at1, String where2, num at2) {', ' int getAt(String where, num at) {', ' if (where == \'FROM_END\') {', @@ -389,18 +390,18 @@ Blockly.Dart['lists_getSublist'] = function(block) { code = functionName + '(' + list + ', \'' + where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')'; } - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['lists_sort'] = function(block) { +Dart['lists_sort'] = function(block) { // Block for sorting a list. - const list = Blockly.Dart.valueToCode(block, 'LIST', - Blockly.Dart.ORDER_NONE) || '[]'; + const list = Dart.valueToCode(block, 'LIST', + Dart.ORDER_NONE) || '[]'; const direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1; const type = block.getFieldValue('TYPE'); - const sortFunctionName = Blockly.Dart.provideFunction_( + const sortFunctionName = Dart.provideFunction_( 'lists_sort', - ['List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['List ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List list, String type, int direction) {', ' var compareFuncs = {', ' "NUMERIC": (a, b) => (direction * a.compareTo(b)).toInt(),', @@ -417,15 +418,15 @@ Blockly.Dart['lists_sort'] = function(block) { '}']); return [sortFunctionName + '(' + list + ', ' + '"' + type + '", ' + direction + ')', - Blockly.Dart.ORDER_UNARY_POSTFIX]; + Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['lists_split'] = function(block) { +Dart['lists_split'] = function(block) { // Block for splitting text into a list, or joining a list into text. - let input = Blockly.Dart.valueToCode(block, 'INPUT', - Blockly.Dart.ORDER_UNARY_POSTFIX); - const delimiter = Blockly.Dart.valueToCode(block, 'DELIM', - Blockly.Dart.ORDER_NONE) || '\'\''; + let input = Dart.valueToCode(block, 'INPUT', + Dart.ORDER_UNARY_POSTFIX); + const delimiter = Dart.valueToCode(block, 'DELIM', + Dart.ORDER_NONE) || '\'\''; const mode = block.getFieldValue('MODE'); let functionName; if (mode === 'SPLIT') { @@ -442,14 +443,14 @@ Blockly.Dart['lists_split'] = function(block) { throw Error('Unknown mode: ' + mode); } const code = input + '.' + functionName + '(' + delimiter + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['lists_reverse'] = function(block) { +Dart['lists_reverse'] = function(block) { // Block for reversing a list. - const list = Blockly.Dart.valueToCode(block, 'LIST', - Blockly.Dart.ORDER_NONE) || '[]'; + const list = Dart.valueToCode(block, 'LIST', + Dart.ORDER_NONE) || '[]'; // XXX What should the operator precedence be for a `new`? const code = 'new List.from(' + list + '.reversed)'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; diff --git a/generators/dart/logic.js b/generators/dart/logic.js index ac493646e4e..9690eff386b 100644 --- a/generators/dart/logic.js +++ b/generators/dart/logic.js @@ -9,48 +9,48 @@ */ 'use strict'; -goog.provide('Blockly.Dart.logic'); +goog.module('Blockly.Dart.logic'); -goog.require('Blockly.Dart'); +const Dart = goog.require('Blockly.Dart'); -Blockly.Dart['controls_if'] = function(block) { +Dart['controls_if'] = function(block) { // If/elseif/else condition. let n = 0; let code = '', branchCode, conditionCode; - if (Blockly.Dart.STATEMENT_PREFIX) { + if (Dart.STATEMENT_PREFIX) { // Automatic prefix insertion is switched off for this block. Add manually. - code += Blockly.Dart.injectId(Blockly.Dart.STATEMENT_PREFIX, block); + code += Dart.injectId(Dart.STATEMENT_PREFIX, block); } do { - conditionCode = Blockly.Dart.valueToCode(block, 'IF' + n, - Blockly.Dart.ORDER_NONE) || 'false'; - branchCode = Blockly.Dart.statementToCode(block, 'DO' + n); - if (Blockly.Dart.STATEMENT_SUFFIX) { - branchCode = Blockly.Dart.prefixLines( - Blockly.Dart.injectId(Blockly.Dart.STATEMENT_SUFFIX, block), - Blockly.Dart.INDENT) + branchCode; + conditionCode = Dart.valueToCode(block, 'IF' + n, + Dart.ORDER_NONE) || 'false'; + branchCode = Dart.statementToCode(block, 'DO' + n); + if (Dart.STATEMENT_SUFFIX) { + branchCode = Dart.prefixLines( + Dart.injectId(Dart.STATEMENT_SUFFIX, block), + Dart.INDENT) + branchCode; } code += (n > 0 ? 'else ' : '') + 'if (' + conditionCode + ') {\n' + branchCode + '}'; n++; } while (block.getInput('IF' + n)); - if (block.getInput('ELSE') || Blockly.Dart.STATEMENT_SUFFIX) { - branchCode = Blockly.Dart.statementToCode(block, 'ELSE'); - if (Blockly.Dart.STATEMENT_SUFFIX) { - branchCode = Blockly.Dart.prefixLines( - Blockly.Dart.injectId(Blockly.Dart.STATEMENT_SUFFIX, block), - Blockly.Dart.INDENT) + branchCode; + if (block.getInput('ELSE') || Dart.STATEMENT_SUFFIX) { + branchCode = Dart.statementToCode(block, 'ELSE'); + if (Dart.STATEMENT_SUFFIX) { + branchCode = Dart.prefixLines( + Dart.injectId(Dart.STATEMENT_SUFFIX, block), + Dart.INDENT) + branchCode; } code += ' else {\n' + branchCode + '}'; } return code + '\n'; }; -Blockly.Dart['controls_ifelse'] = Blockly.Dart['controls_if']; +Dart['controls_ifelse'] = Dart['controls_if']; -Blockly.Dart['logic_compare'] = function(block) { +Dart['logic_compare'] = function(block) { // Comparison operator. const OPERATORS = { 'EQ': '==', @@ -62,20 +62,20 @@ Blockly.Dart['logic_compare'] = function(block) { }; const operator = OPERATORS[block.getFieldValue('OP')]; const order = (operator === '==' || operator === '!=') ? - Blockly.Dart.ORDER_EQUALITY : Blockly.Dart.ORDER_RELATIONAL; - const argument0 = Blockly.Dart.valueToCode(block, 'A', order) || '0'; - const argument1 = Blockly.Dart.valueToCode(block, 'B', order) || '0'; + Dart.ORDER_EQUALITY : Dart.ORDER_RELATIONAL; + const argument0 = Dart.valueToCode(block, 'A', order) || '0'; + const argument1 = Dart.valueToCode(block, 'B', order) || '0'; const code = argument0 + ' ' + operator + ' ' + argument1; return [code, order]; }; -Blockly.Dart['logic_operation'] = function(block) { +Dart['logic_operation'] = function(block) { // Operations 'and', 'or'. const operator = (block.getFieldValue('OP') === 'AND') ? '&&' : '||'; - const order = (operator === '&&') ? Blockly.Dart.ORDER_LOGICAL_AND : - Blockly.Dart.ORDER_LOGICAL_OR; - let argument0 = Blockly.Dart.valueToCode(block, 'A', order); - let argument1 = Blockly.Dart.valueToCode(block, 'B', order); + const order = (operator === '&&') ? Dart.ORDER_LOGICAL_AND : + Dart.ORDER_LOGICAL_OR; + let argument0 = Dart.valueToCode(block, 'A', order); + let argument1 = Dart.valueToCode(block, 'B', order); if (!argument0 && !argument1) { // If there are no arguments, then the return value is false. argument0 = 'false'; @@ -94,33 +94,33 @@ Blockly.Dart['logic_operation'] = function(block) { return [code, order]; }; -Blockly.Dart['logic_negate'] = function(block) { +Dart['logic_negate'] = function(block) { // Negation. - const order = Blockly.Dart.ORDER_UNARY_PREFIX; - const argument0 = Blockly.Dart.valueToCode(block, 'BOOL', order) || 'true'; + const order = Dart.ORDER_UNARY_PREFIX; + const argument0 = Dart.valueToCode(block, 'BOOL', order) || 'true'; const code = '!' + argument0; return [code, order]; }; -Blockly.Dart['logic_boolean'] = function(block) { +Dart['logic_boolean'] = function(block) { // Boolean values true and false. const code = (block.getFieldValue('BOOL') === 'TRUE') ? 'true' : 'false'; - return [code, Blockly.Dart.ORDER_ATOMIC]; + return [code, Dart.ORDER_ATOMIC]; }; -Blockly.Dart['logic_null'] = function(block) { +Dart['logic_null'] = function(block) { // Null data type. - return ['null', Blockly.Dart.ORDER_ATOMIC]; + return ['null', Dart.ORDER_ATOMIC]; }; -Blockly.Dart['logic_ternary'] = function(block) { +Dart['logic_ternary'] = function(block) { // Ternary operator. - const value_if = Blockly.Dart.valueToCode(block, 'IF', - Blockly.Dart.ORDER_CONDITIONAL) || 'false'; - const value_then = Blockly.Dart.valueToCode(block, 'THEN', - Blockly.Dart.ORDER_CONDITIONAL) || 'null'; - const value_else = Blockly.Dart.valueToCode(block, 'ELSE', - Blockly.Dart.ORDER_CONDITIONAL) || 'null'; + const value_if = Dart.valueToCode(block, 'IF', + Dart.ORDER_CONDITIONAL) || 'false'; + const value_then = Dart.valueToCode(block, 'THEN', + Dart.ORDER_CONDITIONAL) || 'null'; + const value_else = Dart.valueToCode(block, 'ELSE', + Dart.ORDER_CONDITIONAL) || 'null'; const code = value_if + ' ? ' + value_then + ' : ' + value_else; - return [code, Blockly.Dart.ORDER_CONDITIONAL]; + return [code, Dart.ORDER_CONDITIONAL]; }; diff --git a/generators/dart/loops.js b/generators/dart/loops.js index 6078e3d2162..e87417bf99f 100644 --- a/generators/dart/loops.js +++ b/generators/dart/loops.js @@ -9,12 +9,14 @@ */ 'use strict'; -goog.provide('Blockly.Dart.loops'); +goog.module('Blockly.Dart.loops'); -goog.require('Blockly.Dart'); +const Blockly = goog.require('Blockly'); +const Loops = goog.require('Blockly.Constants.Loops'); +const Dart = goog.require('Blockly.Dart'); -Blockly.Dart['controls_repeat_ext'] = function(block) { +Dart['controls_repeat_ext'] = function(block) { let repeats; // Repeat n times. if (block.getField('TIMES')) { @@ -22,17 +24,17 @@ Blockly.Dart['controls_repeat_ext'] = function(block) { repeats = String(Number(block.getFieldValue('TIMES'))); } else { // External number. - repeats = Blockly.Dart.valueToCode(block, 'TIMES', - Blockly.Dart.ORDER_ASSIGNMENT) || '0'; + repeats = Dart.valueToCode(block, 'TIMES', + Dart.ORDER_ASSIGNMENT) || '0'; } - let branch = Blockly.Dart.statementToCode(block, 'DO'); - branch = Blockly.Dart.addLoopTrap(branch, block); + let branch = Dart.statementToCode(block, 'DO'); + branch = Dart.addLoopTrap(branch, block); let code = ''; - const loopVar = Blockly.Dart.nameDB_.getDistinctName( + const loopVar = Dart.nameDB_.getDistinctName( 'count', Blockly.VARIABLE_CATEGORY_NAME); let endVar = repeats; if (!repeats.match(/^\w+$/) && !Blockly.isNumber(repeats)) { - endVar = Blockly.Dart.nameDB_.getDistinctName( + endVar = Dart.nameDB_.getDistinctName( 'repeat_end', Blockly.VARIABLE_CATEGORY_NAME); code += 'var ' + endVar + ' = ' + repeats + ';\n'; } @@ -43,34 +45,34 @@ Blockly.Dart['controls_repeat_ext'] = function(block) { return code; }; -Blockly.Dart['controls_repeat'] = Blockly.Dart['controls_repeat_ext']; +Dart['controls_repeat'] = Dart['controls_repeat_ext']; -Blockly.Dart['controls_whileUntil'] = function(block) { +Dart['controls_whileUntil'] = function(block) { // Do while/until loop. const until = block.getFieldValue('MODE') === 'UNTIL'; - let argument0 = Blockly.Dart.valueToCode(block, 'BOOL', - until ? Blockly.Dart.ORDER_UNARY_PREFIX : - Blockly.Dart.ORDER_NONE) || 'false'; - let branch = Blockly.Dart.statementToCode(block, 'DO'); - branch = Blockly.Dart.addLoopTrap(branch, block); + let argument0 = Dart.valueToCode(block, 'BOOL', + until ? Dart.ORDER_UNARY_PREFIX : + Dart.ORDER_NONE) || 'false'; + let branch = Dart.statementToCode(block, 'DO'); + branch = Dart.addLoopTrap(branch, block); if (until) { argument0 = '!' + argument0; } return 'while (' + argument0 + ') {\n' + branch + '}\n'; }; -Blockly.Dart['controls_for'] = function(block) { +Dart['controls_for'] = function(block) { // For loop. - const variable0 = Blockly.Dart.nameDB_.getName( + const variable0 = Dart.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const argument0 = Blockly.Dart.valueToCode(block, 'FROM', - Blockly.Dart.ORDER_ASSIGNMENT) || '0'; - const argument1 = Blockly.Dart.valueToCode(block, 'TO', - Blockly.Dart.ORDER_ASSIGNMENT) || '0'; - const increment = Blockly.Dart.valueToCode(block, 'BY', - Blockly.Dart.ORDER_ASSIGNMENT) || '1'; - let branch = Blockly.Dart.statementToCode(block, 'DO'); - branch = Blockly.Dart.addLoopTrap(branch, block); + const argument0 = Dart.valueToCode(block, 'FROM', + Dart.ORDER_ASSIGNMENT) || '0'; + const argument1 = Dart.valueToCode(block, 'TO', + Dart.ORDER_ASSIGNMENT) || '0'; + const increment = Dart.valueToCode(block, 'BY', + Dart.ORDER_ASSIGNMENT) || '1'; + let branch = Dart.statementToCode(block, 'DO'); + branch = Dart.addLoopTrap(branch, block); let code; if (Blockly.isNumber(argument0) && Blockly.isNumber(argument1) && Blockly.isNumber(increment)) { @@ -91,19 +93,19 @@ Blockly.Dart['controls_for'] = function(block) { // Cache non-trivial values to variables to prevent repeated look-ups. let startVar = argument0; if (!argument0.match(/^\w+$/) && !Blockly.isNumber(argument0)) { - startVar = Blockly.Dart.nameDB_.getDistinctName( + startVar = Dart.nameDB_.getDistinctName( variable0 + '_start', Blockly.VARIABLE_CATEGORY_NAME); code += 'var ' + startVar + ' = ' + argument0 + ';\n'; } let endVar = argument1; if (!argument1.match(/^\w+$/) && !Blockly.isNumber(argument1)) { - endVar = Blockly.Dart.nameDB_.getDistinctName( + endVar = Dart.nameDB_.getDistinctName( variable0 + '_end', Blockly.VARIABLE_CATEGORY_NAME); code += 'var ' + endVar + ' = ' + argument1 + ';\n'; } // Determine loop direction at start, in case one of the bounds // changes during loop execution. - const incVar = Blockly.Dart.nameDB_.getDistinctName( + const incVar = Dart.nameDB_.getDistinctName( variable0 + '_inc', Blockly.VARIABLE_CATEGORY_NAME); code += 'num ' + incVar + ' = '; if (Blockly.isNumber(increment)) { @@ -112,7 +114,7 @@ Blockly.Dart['controls_for'] = function(block) { code += '(' + increment + ').abs();\n'; } code += 'if (' + startVar + ' > ' + endVar + ') {\n'; - code += Blockly.Dart.INDENT + incVar + ' = -' + incVar + ';\n'; + code += Dart.INDENT + incVar + ' = -' + incVar + ';\n'; code += '}\n'; code += 'for (' + variable0 + ' = ' + startVar + '; ' + incVar + ' >= 0 ? ' + @@ -124,39 +126,38 @@ Blockly.Dart['controls_for'] = function(block) { return code; }; -Blockly.Dart['controls_forEach'] = function(block) { +Dart['controls_forEach'] = function(block) { // For each loop. - const variable0 = Blockly.Dart.nameDB_.getName( + const variable0 = Dart.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const argument0 = Blockly.Dart.valueToCode(block, 'LIST', - Blockly.Dart.ORDER_ASSIGNMENT) || '[]'; - let branch = Blockly.Dart.statementToCode(block, 'DO'); - branch = Blockly.Dart.addLoopTrap(branch, block); + const argument0 = Dart.valueToCode(block, 'LIST', + Dart.ORDER_ASSIGNMENT) || '[]'; + let branch = Dart.statementToCode(block, 'DO'); + branch = Dart.addLoopTrap(branch, block); const code = 'for (var ' + variable0 + ' in ' + argument0 + ') {\n' + branch + '}\n'; return code; }; -Blockly.Dart['controls_flow_statements'] = function(block) { +Dart['controls_flow_statements'] = function(block) { // Flow statements: continue, break. let xfix = ''; - if (Blockly.Dart.STATEMENT_PREFIX) { + if (Dart.STATEMENT_PREFIX) { // Automatic prefix insertion is switched off for this block. Add manually. - xfix += Blockly.Dart.injectId(Blockly.Dart.STATEMENT_PREFIX, block); + xfix += Dart.injectId(Dart.STATEMENT_PREFIX, block); } - if (Blockly.Dart.STATEMENT_SUFFIX) { + if (Dart.STATEMENT_SUFFIX) { // Inject any statement suffix here since the regular one at the end // will not get executed if the break/continue is triggered. - xfix += Blockly.Dart.injectId(Blockly.Dart.STATEMENT_SUFFIX, block); + xfix += Dart.injectId(Dart.STATEMENT_SUFFIX, block); } - if (Blockly.Dart.STATEMENT_PREFIX) { - const loop = Blockly.Constants.Loops - .CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); + if (Dart.STATEMENT_PREFIX) { + const loop = Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); if (loop && !loop.suppressPrefixSuffix) { // Inject loop's statement prefix here since the regular one at the end // of the loop will not get executed if 'continue' is triggered. // In the case of 'break', a prefix is needed due to the loop's suffix. - xfix += Blockly.Dart.injectId(Blockly.Dart.STATEMENT_PREFIX, loop); + xfix += Dart.injectId(Dart.STATEMENT_PREFIX, loop); } } switch (block.getFieldValue('FLOW')) { diff --git a/generators/dart/math.js b/generators/dart/math.js index 4a70ec4372d..5375399dc00 100644 --- a/generators/dart/math.js +++ b/generators/dart/math.js @@ -9,85 +9,86 @@ */ 'use strict'; -goog.provide('Blockly.Dart.math'); +goog.module('Blockly.Dart.math'); -goog.require('Blockly.Dart'); +const Blockly = goog.require('Blockly'); +const Dart = goog.require('Blockly.Dart'); -Blockly.Dart.addReservedWords('Math'); +Dart.addReservedWords('Math'); -Blockly.Dart['math_number'] = function(block) { +Dart['math_number'] = function(block) { // Numeric value. let code = Number(block.getFieldValue('NUM')); let order; if (code === Infinity) { code = 'double.infinity'; - order = Blockly.Dart.ORDER_UNARY_POSTFIX; + order = Dart.ORDER_UNARY_POSTFIX; } else if (code === -Infinity) { code = '-double.infinity'; - order = Blockly.Dart.ORDER_UNARY_PREFIX; + order = Dart.ORDER_UNARY_PREFIX; } else { // -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. order = code < 0 ? - Blockly.Dart.ORDER_UNARY_PREFIX : Blockly.Dart.ORDER_ATOMIC; + Dart.ORDER_UNARY_PREFIX : Dart.ORDER_ATOMIC; } return [code, order]; }; -Blockly.Dart['math_arithmetic'] = function(block) { +Dart['math_arithmetic'] = function(block) { // Basic arithmetic operators, and power. const OPERATORS = { - 'ADD': [' + ', Blockly.Dart.ORDER_ADDITIVE], - 'MINUS': [' - ', Blockly.Dart.ORDER_ADDITIVE], - 'MULTIPLY': [' * ', Blockly.Dart.ORDER_MULTIPLICATIVE], - 'DIVIDE': [' / ', Blockly.Dart.ORDER_MULTIPLICATIVE], - 'POWER': [null, Blockly.Dart.ORDER_NONE] // Handle power separately. + 'ADD': [' + ', Dart.ORDER_ADDITIVE], + 'MINUS': [' - ', Dart.ORDER_ADDITIVE], + 'MULTIPLY': [' * ', Dart.ORDER_MULTIPLICATIVE], + 'DIVIDE': [' / ', Dart.ORDER_MULTIPLICATIVE], + 'POWER': [null, Dart.ORDER_NONE] // Handle power separately. }; const tuple = OPERATORS[block.getFieldValue('OP')]; const operator = tuple[0]; const order = tuple[1]; - const argument0 = Blockly.Dart.valueToCode(block, 'A', order) || '0'; - const argument1 = Blockly.Dart.valueToCode(block, 'B', order) || '0'; + const argument0 = Dart.valueToCode(block, 'A', order) || '0'; + const argument1 = Dart.valueToCode(block, 'B', order) || '0'; let code; // Power in Dart requires a special case since it has no operator. if (!operator) { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; code = 'Math.pow(' + argument0 + ', ' + argument1 + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } code = argument0 + operator + argument1; return [code, order]; }; -Blockly.Dart['math_single'] = function(block) { +Dart['math_single'] = function(block) { // Math operators with single operand. const operator = block.getFieldValue('OP'); let code; let arg; if (operator === 'NEG') { // Negation is a special case given its different operator precedence. - arg = Blockly.Dart.valueToCode(block, 'NUM', - Blockly.Dart.ORDER_UNARY_PREFIX) || '0'; + arg = Dart.valueToCode(block, 'NUM', + Dart.ORDER_UNARY_PREFIX) || '0'; if (arg[0] === '-') { // --3 is not legal in Dart. arg = ' ' + arg; } code = '-' + arg; - return [code, Blockly.Dart.ORDER_UNARY_PREFIX]; + return [code, Dart.ORDER_UNARY_PREFIX]; } - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; if (operator === 'ABS' || operator.substring(0, 5) === 'ROUND') { - arg = Blockly.Dart.valueToCode(block, 'NUM', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '0'; + arg = Dart.valueToCode(block, 'NUM', + Dart.ORDER_UNARY_POSTFIX) || '0'; } else if (operator === 'SIN' || operator === 'COS' || operator === 'TAN') { - arg = Blockly.Dart.valueToCode(block, 'NUM', - Blockly.Dart.ORDER_MULTIPLICATIVE) || '0'; + arg = Dart.valueToCode(block, 'NUM', + Dart.ORDER_MULTIPLICATIVE) || '0'; } else { - arg = Blockly.Dart.valueToCode(block, 'NUM', - Blockly.Dart.ORDER_NONE) || '0'; + arg = Dart.valueToCode(block, 'NUM', + Dart.ORDER_NONE) || '0'; } // First, handle cases which generate values that don't need parentheses // wrapping the code. @@ -127,7 +128,7 @@ Blockly.Dart['math_single'] = function(block) { break; } if (code) { - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } // Second, handle cases which generate values that may need parentheses // wrapping the code. @@ -147,45 +148,45 @@ Blockly.Dart['math_single'] = function(block) { default: throw Error('Unknown math operator: ' + operator); } - return [code, Blockly.Dart.ORDER_MULTIPLICATIVE]; + return [code, Dart.ORDER_MULTIPLICATIVE]; }; -Blockly.Dart['math_constant'] = function(block) { +Dart['math_constant'] = function(block) { // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY. const CONSTANTS = { - 'PI': ['Math.pi', Blockly.Dart.ORDER_UNARY_POSTFIX], - 'E': ['Math.e', Blockly.Dart.ORDER_UNARY_POSTFIX], + 'PI': ['Math.pi', Dart.ORDER_UNARY_POSTFIX], + 'E': ['Math.e', Dart.ORDER_UNARY_POSTFIX], 'GOLDEN_RATIO': - ['(1 + Math.sqrt(5)) / 2', Blockly.Dart.ORDER_MULTIPLICATIVE], - 'SQRT2': ['Math.sqrt2', Blockly.Dart.ORDER_UNARY_POSTFIX], - 'SQRT1_2': ['Math.sqrt1_2', Blockly.Dart.ORDER_UNARY_POSTFIX], - 'INFINITY': ['double.infinity', Blockly.Dart.ORDER_ATOMIC] + ['(1 + Math.sqrt(5)) / 2', Dart.ORDER_MULTIPLICATIVE], + 'SQRT2': ['Math.sqrt2', Dart.ORDER_UNARY_POSTFIX], + 'SQRT1_2': ['Math.sqrt1_2', Dart.ORDER_UNARY_POSTFIX], + 'INFINITY': ['double.infinity', Dart.ORDER_ATOMIC] }; const constant = block.getFieldValue('CONSTANT'); if (constant !== 'INFINITY') { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; } return CONSTANTS[constant]; }; -Blockly.Dart['math_number_property'] = function(block) { +Dart['math_number_property'] = function(block) { // Check if a number is even, odd, prime, whole, positive, or negative // or if it is divisible by certain number. Returns true or false. - const number_to_check = Blockly.Dart.valueToCode(block, 'NUMBER_TO_CHECK', - Blockly.Dart.ORDER_MULTIPLICATIVE); + const number_to_check = Dart.valueToCode(block, 'NUMBER_TO_CHECK', + Dart.ORDER_MULTIPLICATIVE); if (!number_to_check) { - return ['false', Blockly.Dart.ORDER_ATOMIC]; + return ['false', Dart.ORDER_ATOMIC]; } const dropdown_property = block.getFieldValue('PROPERTY'); let code; if (dropdown_property === 'PRIME') { // Prime is a special case as it is not a one-liner test. - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'math_isPrime', - ['bool ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '(n) {', + ['bool ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(n) {', ' // https://en.wikipedia.org/wiki/Primality_test#Naive_methods', ' if (n == 2 || n == 3) {', ' return true;', @@ -205,7 +206,7 @@ Blockly.Dart['math_number_property'] = function(block) { ' return true;', '}']); code = functionName + '(' + number_to_check + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } switch (dropdown_property) { case 'EVEN': @@ -224,43 +225,43 @@ Blockly.Dart['math_number_property'] = function(block) { code = number_to_check + ' < 0'; break; case 'DIVISIBLE_BY': - const divisor = Blockly.Dart.valueToCode(block, 'DIVISOR', - Blockly.Dart.ORDER_MULTIPLICATIVE); + const divisor = Dart.valueToCode(block, 'DIVISOR', + Dart.ORDER_MULTIPLICATIVE); if (!divisor) { - return ['false', Blockly.Dart.ORDER_ATOMIC]; + return ['false', Dart.ORDER_ATOMIC]; } code = number_to_check + ' % ' + divisor + ' == 0'; break; } - return [code, Blockly.Dart.ORDER_EQUALITY]; + return [code, Dart.ORDER_EQUALITY]; }; -Blockly.Dart['math_change'] = function(block) { +Dart['math_change'] = function(block) { // Add to a variable in place. - const argument0 = Blockly.Dart.valueToCode(block, 'DELTA', - Blockly.Dart.ORDER_ADDITIVE) || '0'; - const varName = Blockly.Dart.nameDB_.getName(block.getFieldValue('VAR'), + const argument0 = Dart.valueToCode(block, 'DELTA', + Dart.ORDER_ADDITIVE) || '0'; + const varName = Dart.nameDB_.getName(block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); return varName + ' = (' + varName + ' is num ? ' + varName + ' : 0) + ' + argument0 + ';\n'; }; // Rounding functions have a single operand. -Blockly.Dart['math_round'] = Blockly.Dart['math_single']; +Dart['math_round'] = Dart['math_single']; // Trigonometry functions have a single operand. -Blockly.Dart['math_trig'] = Blockly.Dart['math_single']; +Dart['math_trig'] = Dart['math_single']; -Blockly.Dart['math_on_list'] = function(block) { +Dart['math_on_list'] = function(block) { // Math functions for lists. const func = block.getFieldValue('OP'); - const list = Blockly.Dart.valueToCode(block, 'LIST', - Blockly.Dart.ORDER_NONE) || '[]'; + const list = Dart.valueToCode(block, 'LIST', + Dart.ORDER_NONE) || '[]'; let code; switch (func) { case 'SUM': { - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'math_sum', - ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {', ' num sumVal = 0;', ' myList.forEach((num entry) {sumVal += entry;});', @@ -270,11 +271,11 @@ Blockly.Dart['math_on_list'] = function(block) { break; } case 'MIN': { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'math_min', - ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {', ' if (myList.isEmpty) return null;', ' num minVal = myList[0];', @@ -286,11 +287,11 @@ Blockly.Dart['math_on_list'] = function(block) { break; } case 'MAX': { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'math_max', - ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {', ' if (myList.isEmpty) return null;', ' num maxVal = myList[0];', @@ -304,9 +305,9 @@ Blockly.Dart['math_on_list'] = function(block) { case 'AVERAGE': { // This operation exclude null and values that are not int or float: // math_mean([null,null,"aString",1,9]) -> 5.0 - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'math_mean', - ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {', ' // First filter list for numbers only.', ' List localList = new List.from(myList);', @@ -320,9 +321,9 @@ Blockly.Dart['math_on_list'] = function(block) { break; } case 'MEDIAN': { - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'math_median', - ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {', ' // First filter list for numbers only, then sort, ' + 'then return middle value', @@ -343,14 +344,14 @@ Blockly.Dart['math_on_list'] = function(block) { break; } case 'MODE': { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; // 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] - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'math_modes', - ['List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['List ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List values) {', ' List modes = [];', ' List counts = [];', @@ -383,11 +384,11 @@ Blockly.Dart['math_on_list'] = function(block) { break; } case 'STD_DEV': { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'math_standard_deviation', - ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {', ' // First filter list for numbers only.', ' List numbers = new List.from(myList);', @@ -406,11 +407,11 @@ Blockly.Dart['math_on_list'] = function(block) { break; } case 'RANDOM': { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'math_random_item', - ['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['dynamic ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {', ' int x = new Math.Random().nextInt(myList.length);', ' return myList[x];', @@ -421,45 +422,45 @@ Blockly.Dart['math_on_list'] = function(block) { default: throw Error('Unknown operator: ' + func); } - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['math_modulo'] = function(block) { +Dart['math_modulo'] = function(block) { // Remainder computation. - const argument0 = Blockly.Dart.valueToCode(block, 'DIVIDEND', - Blockly.Dart.ORDER_MULTIPLICATIVE) || '0'; - const argument1 = Blockly.Dart.valueToCode(block, 'DIVISOR', - Blockly.Dart.ORDER_MULTIPLICATIVE) || '0'; + const argument0 = Dart.valueToCode(block, 'DIVIDEND', + Dart.ORDER_MULTIPLICATIVE) || '0'; + const argument1 = Dart.valueToCode(block, 'DIVISOR', + Dart.ORDER_MULTIPLICATIVE) || '0'; const code = argument0 + ' % ' + argument1; - return [code, Blockly.Dart.ORDER_MULTIPLICATIVE]; + return [code, Dart.ORDER_MULTIPLICATIVE]; }; -Blockly.Dart['math_constrain'] = function(block) { +Dart['math_constrain'] = function(block) { // Constrain a number between two limits. - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const argument0 = Blockly.Dart.valueToCode(block, 'VALUE', - Blockly.Dart.ORDER_NONE) || '0'; - const argument1 = Blockly.Dart.valueToCode(block, 'LOW', - Blockly.Dart.ORDER_NONE) || '0'; - const argument2 = Blockly.Dart.valueToCode(block, 'HIGH', - Blockly.Dart.ORDER_NONE) || 'double.infinity'; + const argument0 = Dart.valueToCode(block, 'VALUE', + Dart.ORDER_NONE) || '0'; + const argument1 = Dart.valueToCode(block, 'LOW', + Dart.ORDER_NONE) || '0'; + const argument2 = Dart.valueToCode(block, 'HIGH', + Dart.ORDER_NONE) || 'double.infinity'; const code = 'Math.min(Math.max(' + argument0 + ', ' + argument1 + '), ' + argument2 + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['math_random_int'] = function(block) { +Dart['math_random_int'] = function(block) { // Random integer between [X] and [Y]. - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const argument0 = Blockly.Dart.valueToCode(block, 'FROM', - Blockly.Dart.ORDER_NONE) || '0'; - const argument1 = Blockly.Dart.valueToCode(block, 'TO', - Blockly.Dart.ORDER_NONE) || '0'; - const functionName = Blockly.Dart.provideFunction_( + const argument0 = Dart.valueToCode(block, 'FROM', + Dart.ORDER_NONE) || '0'; + const argument1 = Dart.valueToCode(block, 'TO', + Dart.ORDER_NONE) || '0'; + const functionName = Dart.provideFunction_( 'math_random_int', - ['int ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '(num a, num b) {', + ['int ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(num a, num b) {', ' if (a > b) {', ' // Swap a and b to ensure a is smaller.', ' num c = a;', @@ -469,24 +470,24 @@ Blockly.Dart['math_random_int'] = function(block) { ' return new Math.Random().nextInt(b - a + 1) + a;', '}']); const code = functionName + '(' + argument0 + ', ' + argument1 + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['math_random_float'] = function(block) { +Dart['math_random_float'] = function(block) { // Random fraction between 0 and 1. - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - return ['new Math.Random().nextDouble()', Blockly.Dart.ORDER_UNARY_POSTFIX]; + return ['new Math.Random().nextDouble()', Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['math_atan2'] = function(block) { +Dart['math_atan2'] = function(block) { // Arctangent of point (X, Y) in degrees from -180 to 180. - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const argument0 = Blockly.Dart.valueToCode(block, 'X', - Blockly.Dart.ORDER_NONE) || '0'; - const argument1 = Blockly.Dart.valueToCode(block, 'Y', - Blockly.Dart.ORDER_NONE) || '0'; + const argument0 = Dart.valueToCode(block, 'X', + Dart.ORDER_NONE) || '0'; + const argument1 = Dart.valueToCode(block, 'Y', + Dart.ORDER_NONE) || '0'; return ['Math.atan2(' + argument1 + ', ' + argument0 + ') / Math.pi * 180', - Blockly.Dart.ORDER_MULTIPLICATIVE]; + Dart.ORDER_MULTIPLICATIVE]; }; diff --git a/generators/dart/procedures.js b/generators/dart/procedures.js index bb539b8d152..5ef0661e8d2 100644 --- a/generators/dart/procedures.js +++ b/generators/dart/procedures.js @@ -9,101 +9,102 @@ */ 'use strict'; -goog.provide('Blockly.Dart.procedures'); +goog.module('Blockly.Dart.procedures'); -goog.require('Blockly.Dart'); +const Blockly = goog.require('Blockly'); +const Dart = goog.require('Blockly.Dart'); -Blockly.Dart['procedures_defreturn'] = function(block) { +Dart['procedures_defreturn'] = function(block) { // Define a procedure with a return value. - const funcName = Blockly.Dart.nameDB_.getName(block.getFieldValue('NAME'), + const funcName = Dart.nameDB_.getName(block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME); let xfix1 = ''; - if (Blockly.Dart.STATEMENT_PREFIX) { - xfix1 += Blockly.Dart.injectId(Blockly.Dart.STATEMENT_PREFIX, block); + if (Dart.STATEMENT_PREFIX) { + xfix1 += Dart.injectId(Dart.STATEMENT_PREFIX, block); } - if (Blockly.Dart.STATEMENT_SUFFIX) { - xfix1 += Blockly.Dart.injectId(Blockly.Dart.STATEMENT_SUFFIX, block); + if (Dart.STATEMENT_SUFFIX) { + xfix1 += Dart.injectId(Dart.STATEMENT_SUFFIX, block); } if (xfix1) { - xfix1 = Blockly.Dart.prefixLines(xfix1, Blockly.Dart.INDENT); + xfix1 = Dart.prefixLines(xfix1, Dart.INDENT); } let loopTrap = ''; - if (Blockly.Dart.INFINITE_LOOP_TRAP) { - loopTrap = Blockly.Dart.prefixLines( - Blockly.Dart.injectId(Blockly.Dart.INFINITE_LOOP_TRAP, block), - Blockly.Dart.INDENT); + if (Dart.INFINITE_LOOP_TRAP) { + loopTrap = Dart.prefixLines( + Dart.injectId(Dart.INFINITE_LOOP_TRAP, block), + Dart.INDENT); } - const branch = Blockly.Dart.statementToCode(block, 'STACK'); - let returnValue = Blockly.Dart.valueToCode(block, 'RETURN', - Blockly.Dart.ORDER_NONE) || ''; + const branch = Dart.statementToCode(block, 'STACK'); + let returnValue = Dart.valueToCode(block, 'RETURN', + Dart.ORDER_NONE) || ''; let xfix2 = ''; if (branch && returnValue) { // After executing the function body, revisit this block for the return. xfix2 = xfix1; } if (returnValue) { - returnValue = Blockly.Dart.INDENT + 'return ' + returnValue + ';\n'; + returnValue = Dart.INDENT + 'return ' + returnValue + ';\n'; } const returnType = returnValue ? 'dynamic' : 'void'; const args = []; const variables = block.getVars(); for (let i = 0; i < variables.length; i++) { - args[i] = Blockly.Dart.nameDB_.getName(variables[i], + args[i] = Dart.nameDB_.getName(variables[i], Blockly.VARIABLE_CATEGORY_NAME); } let code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' + xfix1 + loopTrap + branch + xfix2 + returnValue + '}'; - code = Blockly.Dart.scrub_(block, code); + code = Dart.scrub_(block, code); // Add % so as not to collide with helper functions in definitions list. - Blockly.Dart.definitions_['%' + funcName] = code; + Dart.definitions_['%' + funcName] = code; return null; }; // Defining a procedure without a return value uses the same generator as // a procedure with a return value. -Blockly.Dart['procedures_defnoreturn'] = Blockly.Dart['procedures_defreturn']; +Dart['procedures_defnoreturn'] = Dart['procedures_defreturn']; -Blockly.Dart['procedures_callreturn'] = function(block) { +Dart['procedures_callreturn'] = function(block) { // Call a procedure with a return value. - const funcName = Blockly.Dart.nameDB_.getName(block.getFieldValue('NAME'), + const funcName = Dart.nameDB_.getName(block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME); const args = []; const variables = block.getVars(); for (let i = 0; i < variables.length; i++) { - args[i] = Blockly.Dart.valueToCode(block, 'ARG' + i, - Blockly.Dart.ORDER_NONE) || 'null'; + args[i] = Dart.valueToCode(block, 'ARG' + i, + Dart.ORDER_NONE) || 'null'; } let code = funcName + '(' + args.join(', ') + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['procedures_callnoreturn'] = function(block) { +Dart['procedures_callnoreturn'] = function(block) { // Call a procedure with no return value. // Generated code is for a function call as a statement is the same as a // function call as a value, with the addition of line ending. - const tuple = Blockly.Dart['procedures_callreturn'](block); + const tuple = Dart['procedures_callreturn'](block); return tuple[0] + ';\n'; }; -Blockly.Dart['procedures_ifreturn'] = function(block) { +Dart['procedures_ifreturn'] = function(block) { // Conditionally return value from a procedure. - const condition = Blockly.Dart.valueToCode(block, 'CONDITION', - Blockly.Dart.ORDER_NONE) || 'false'; + const condition = Dart.valueToCode(block, 'CONDITION', + Dart.ORDER_NONE) || 'false'; let code = 'if (' + condition + ') {\n'; - if (Blockly.Dart.STATEMENT_SUFFIX) { + if (Dart.STATEMENT_SUFFIX) { // Inject any statement suffix here since the regular one at the end // will not get executed if the return is triggered. - code += Blockly.Dart.prefixLines( - Blockly.Dart.injectId(Blockly.Dart.STATEMENT_SUFFIX, block), - Blockly.Dart.INDENT); + code += Dart.prefixLines( + Dart.injectId(Dart.STATEMENT_SUFFIX, block), + Dart.INDENT); } if (block.hasReturnValue_) { - const value = Blockly.Dart.valueToCode(block, 'VALUE', - Blockly.Dart.ORDER_NONE) || 'null'; - code += Blockly.Dart.INDENT + 'return ' + value + ';\n'; + const value = Dart.valueToCode(block, 'VALUE', + Dart.ORDER_NONE) || 'null'; + code += Dart.INDENT + 'return ' + value + ';\n'; } else { - code += Blockly.Dart.INDENT + 'return;\n'; + code += Dart.INDENT + 'return;\n'; } code += '}\n'; return code; diff --git a/generators/dart/text.js b/generators/dart/text.js index c589571e2a0..4022b12d64e 100644 --- a/generators/dart/text.js +++ b/generators/dart/text.js @@ -9,160 +9,161 @@ */ 'use strict'; -goog.provide('Blockly.Dart.texts'); +goog.module('Blockly.Dart.texts'); -goog.require('Blockly.Dart'); +const Blockly = goog.require('Blockly') +const Dart = goog.require('Blockly.Dart'); -Blockly.Dart.addReservedWords('Html,Math'); +Dart.addReservedWords('Html,Math'); -Blockly.Dart['text'] = function(block) { +Dart['text'] = function(block) { // Text value. - const code = Blockly.Dart.quote_(block.getFieldValue('TEXT')); - return [code, Blockly.Dart.ORDER_ATOMIC]; + const code = Dart.quote_(block.getFieldValue('TEXT')); + return [code, Dart.ORDER_ATOMIC]; }; -Blockly.Dart['text_multiline'] = function(block) { +Dart['text_multiline'] = function(block) { // Text value. - const code = Blockly.Dart.multiline_quote_(block.getFieldValue('TEXT')); - const order = code.indexOf('+') !== -1 ? Blockly.Dart.ORDER_ADDITIVE : - Blockly.Dart.ORDER_ATOMIC; + const code = Dart.multiline_quote_(block.getFieldValue('TEXT')); + const order = code.indexOf('+') !== -1 ? Dart.ORDER_ADDITIVE : + Dart.ORDER_ATOMIC; return [code, order]; }; -Blockly.Dart['text_join'] = function(block) { +Dart['text_join'] = function(block) { // Create a string made up of any number of elements of any type. switch (block.itemCount_) { case 0: - return ['\'\'', Blockly.Dart.ORDER_ATOMIC]; + return ['\'\'', Dart.ORDER_ATOMIC]; case 1: { - const element = Blockly.Dart.valueToCode(block, 'ADD0', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\''; + const element = Dart.valueToCode(block, 'ADD0', + Dart.ORDER_UNARY_POSTFIX) || '\'\''; const code = element + '.toString()'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } default: { const elements = new Array(block.itemCount_); for (let i = 0; i < block.itemCount_; i++) { - elements[i] = Blockly.Dart.valueToCode(block, 'ADD' + i, - Blockly.Dart.ORDER_NONE) || '\'\''; + elements[i] = Dart.valueToCode(block, 'ADD' + i, + Dart.ORDER_NONE) || '\'\''; } const code = '[' + elements.join(',') + '].join()'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } } }; -Blockly.Dart['text_append'] = function(block) { +Dart['text_append'] = function(block) { // Append to a variable in place. - const varName = Blockly.Dart.nameDB_.getName(block.getFieldValue('VAR'), + const varName = Dart.nameDB_.getName(block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const value = Blockly.Dart.valueToCode(block, 'TEXT', - Blockly.Dart.ORDER_NONE) || '\'\''; + const value = Dart.valueToCode(block, 'TEXT', + Dart.ORDER_NONE) || '\'\''; return varName + ' = [' + varName + ', ' + value + '].join();\n'; }; -Blockly.Dart['text_length'] = function(block) { +Dart['text_length'] = function(block) { // String or array length. - const text = Blockly.Dart.valueToCode(block, 'VALUE', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\''; - return [text + '.length', Blockly.Dart.ORDER_UNARY_POSTFIX]; + const text = Dart.valueToCode(block, 'VALUE', + Dart.ORDER_UNARY_POSTFIX) || '\'\''; + return [text + '.length', Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['text_isEmpty'] = function(block) { +Dart['text_isEmpty'] = function(block) { // Is the string null or array empty? - const text = Blockly.Dart.valueToCode(block, 'VALUE', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\''; - return [text + '.isEmpty', Blockly.Dart.ORDER_UNARY_POSTFIX]; + const text = Dart.valueToCode(block, 'VALUE', + Dart.ORDER_UNARY_POSTFIX) || '\'\''; + return [text + '.isEmpty', Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['text_indexOf'] = function(block) { +Dart['text_indexOf'] = function(block) { // Search the text for a substring. const operator = block.getFieldValue('END') === 'FIRST' ? 'indexOf' : 'lastIndexOf'; - const substring = Blockly.Dart.valueToCode(block, 'FIND', - Blockly.Dart.ORDER_NONE) || '\'\''; - const text = Blockly.Dart.valueToCode(block, 'VALUE', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\''; + const substring = Dart.valueToCode(block, 'FIND', + Dart.ORDER_NONE) || '\'\''; + const text = Dart.valueToCode(block, 'VALUE', + Dart.ORDER_UNARY_POSTFIX) || '\'\''; const code = text + '.' + operator + '(' + substring + ')'; if (block.workspace.options.oneBasedIndex) { - return [code + ' + 1', Blockly.Dart.ORDER_ADDITIVE]; + return [code + ' + 1', Dart.ORDER_ADDITIVE]; } - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['text_charAt'] = function(block) { +Dart['text_charAt'] = function(block) { // Get letter at index. // Note: Until January 2013 this block did not have the WHERE input. const where = block.getFieldValue('WHERE') || 'FROM_START'; const textOrder = (where === 'FIRST' || where === 'FROM_START') ? - Blockly.Dart.ORDER_UNARY_POSTFIX : Blockly.Dart.ORDER_NONE; - const text = Blockly.Dart.valueToCode(block, 'VALUE', textOrder) || '\'\''; + Dart.ORDER_UNARY_POSTFIX : Dart.ORDER_NONE; + const text = Dart.valueToCode(block, 'VALUE', textOrder) || '\'\''; let at; switch (where) { case 'FIRST': { const code = text + '[0]'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } case 'FROM_START': { - at = Blockly.Dart.getAdjusted(block, 'AT'); + at = Dart.getAdjusted(block, 'AT'); const code = text + '[' + at + ']'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } case 'LAST': at = 1; // Fall through. case 'FROM_END': { - at = Blockly.Dart.getAdjusted(block, 'AT', 1); - const functionName = Blockly.Dart.provideFunction_( + at = Dart.getAdjusted(block, 'AT', 1); + const functionName = Dart.provideFunction_( 'text_get_from_end', - ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(String text, num x) {', ' return text[text.length - x];', '}']); const code = functionName + '(' + text + ', ' + at + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } case 'RANDOM': { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'text_random_letter', - ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(String text) {', ' int x = new Math.Random().nextInt(text.length);', ' return text[x];', '}']); const code = functionName + '(' + text + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; } } throw Error('Unhandled option (text_charAt).'); }; -Blockly.Dart['text_getSubstring'] = function(block) { +Dart['text_getSubstring'] = function(block) { // Get substring. const where1 = block.getFieldValue('WHERE1'); const where2 = block.getFieldValue('WHERE2'); const requiresLengthCall = (where1 !== 'FROM_END' && where2 === 'FROM_START'); - const textOrder = requiresLengthCall ? Blockly.Dart.ORDER_UNARY_POSTFIX : - Blockly.Dart.ORDER_NONE; - const text = Blockly.Dart.valueToCode(block, 'STRING', textOrder) || '\'\''; + const textOrder = requiresLengthCall ? Dart.ORDER_UNARY_POSTFIX : + Dart.ORDER_NONE; + const text = Dart.valueToCode(block, 'STRING', textOrder) || '\'\''; let code; if (where1 === 'FIRST' && where2 === 'LAST') { code = text; - return [code, Blockly.Dart.ORDER_NONE]; + return [code, Dart.ORDER_NONE]; } else if (text.match(/^'?\w+'?$/) || requiresLengthCall) { // If the text is a variable or literal or doesn't require a call for // length, don't generate a helper function. let at1; switch (where1) { case 'FROM_START': - at1 = Blockly.Dart.getAdjusted(block, 'AT1'); + at1 = Dart.getAdjusted(block, 'AT1'); break; case 'FROM_END': - at1 = Blockly.Dart.getAdjusted(block, 'AT1', 1, false, - Blockly.Dart.ORDER_ADDITIVE); + at1 = Dart.getAdjusted(block, 'AT1', 1, false, + Dart.ORDER_ADDITIVE); at1 = text + '.length - ' + at1; break; case 'FIRST': @@ -174,11 +175,11 @@ Blockly.Dart['text_getSubstring'] = function(block) { let at2; switch (where2) { case 'FROM_START': - at2 = Blockly.Dart.getAdjusted(block, 'AT2', 1); + at2 = Dart.getAdjusted(block, 'AT2', 1); break; case 'FROM_END': - at2 = Blockly.Dart.getAdjusted(block, 'AT2', 0, false, - Blockly.Dart.ORDER_ADDITIVE); + at2 = Dart.getAdjusted(block, 'AT2', 0, false, + Dart.ORDER_ADDITIVE); at2 = text + '.length - ' + at2; break; case 'LAST': @@ -193,11 +194,11 @@ Blockly.Dart['text_getSubstring'] = function(block) { code = text + '.substring(' + at1 + ', ' + at2 + ')'; } } else { - const at1 = Blockly.Dart.getAdjusted(block, 'AT1'); - const at2 = Blockly.Dart.getAdjusted(block, 'AT2'); - const functionName = Blockly.Dart.provideFunction_( + const at1 = Dart.getAdjusted(block, 'AT1'); + const at2 = Dart.getAdjusted(block, 'AT2'); + const functionName = Dart.provideFunction_( 'text_get_substring', - ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(String text, String where1, num at1, String where2, num at2) {', ' int getAt(String where, num at) {', ' if (where == \'FROM_END\') {', @@ -218,10 +219,10 @@ Blockly.Dart['text_getSubstring'] = function(block) { code = functionName + '(' + text + ', \'' + where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')'; } - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['text_changeCase'] = function(block) { +Dart['text_changeCase'] = function(block) { // Change capitalization. const OPERATORS = { 'UPPERCASE': '.toUpperCase()', @@ -229,18 +230,18 @@ Blockly.Dart['text_changeCase'] = function(block) { 'TITLECASE': null }; const operator = OPERATORS[block.getFieldValue('CASE')]; - const textOrder = operator ? Blockly.Dart.ORDER_UNARY_POSTFIX : - Blockly.Dart.ORDER_NONE; - const text = Blockly.Dart.valueToCode(block, 'TEXT', textOrder) || '\'\''; + const textOrder = operator ? Dart.ORDER_UNARY_POSTFIX : + Dart.ORDER_NONE; + const text = Dart.valueToCode(block, 'TEXT', textOrder) || '\'\''; let code; if (operator) { // Upper and lower case are functions built into Dart. code = text + operator; } else { // Title case is not a native Dart function. Define one. - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'text_toTitleCase', - ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['String ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(String str) {', ' RegExp exp = new RegExp(r\'\\b\');', ' List list = str.split(exp);', @@ -257,10 +258,10 @@ Blockly.Dart['text_changeCase'] = function(block) { '}']); code = functionName + '(' + text + ')'; } - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['text_trim'] = function(block) { +Dart['text_trim'] = function(block) { // Trim spaces. const OPERATORS = { 'LEFT': '.replaceFirst(new RegExp(r\'^\\s+\'), \'\')', @@ -268,52 +269,52 @@ Blockly.Dart['text_trim'] = function(block) { 'BOTH': '.trim()' }; const operator = OPERATORS[block.getFieldValue('MODE')]; - const text = Blockly.Dart.valueToCode(block, 'TEXT', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\''; - return [text + operator, Blockly.Dart.ORDER_UNARY_POSTFIX]; + const text = Dart.valueToCode(block, 'TEXT', + Dart.ORDER_UNARY_POSTFIX) || '\'\''; + return [text + operator, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['text_print'] = function(block) { +Dart['text_print'] = function(block) { // Print statement. - const msg = Blockly.Dart.valueToCode(block, 'TEXT', - Blockly.Dart.ORDER_NONE) || '\'\''; + const msg = Dart.valueToCode(block, 'TEXT', + Dart.ORDER_NONE) || '\'\''; return 'print(' + msg + ');\n'; }; -Blockly.Dart['text_prompt_ext'] = function(block) { +Dart['text_prompt_ext'] = function(block) { // Prompt function. - Blockly.Dart.definitions_['import_dart_html'] = + Dart.definitions_['import_dart_html'] = 'import \'dart:html\' as Html;'; let msg; if (block.getField('TEXT')) { // Internal message. - msg = Blockly.Dart.quote_(block.getFieldValue('TEXT')); + msg = Dart.quote_(block.getFieldValue('TEXT')); } else { // External message. - msg = Blockly.Dart.valueToCode(block, 'TEXT', - Blockly.Dart.ORDER_NONE) || '\'\''; + msg = Dart.valueToCode(block, 'TEXT', + Dart.ORDER_NONE) || '\'\''; } let code = 'Html.window.prompt(' + msg + ', \'\')'; const toNumber = block.getFieldValue('TYPE') === 'NUMBER'; if (toNumber) { - Blockly.Dart.definitions_['import_dart_math'] = + Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;'; code = 'Math.parseDouble(' + code + ')'; } - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['text_prompt'] = Blockly.Dart['text_prompt_ext']; +Dart['text_prompt'] = Dart['text_prompt_ext']; -Blockly.Dart['text_count'] = function(block) { - const text = Blockly.Dart.valueToCode(block, 'TEXT', - Blockly.Dart.ORDER_NONE) || '\'\''; - const sub = Blockly.Dart.valueToCode(block, 'SUB', - Blockly.Dart.ORDER_NONE) || '\'\''; +Dart['text_count'] = function(block) { + const text = Dart.valueToCode(block, 'TEXT', + Dart.ORDER_NONE) || '\'\''; + const sub = Dart.valueToCode(block, 'SUB', + Dart.ORDER_NONE) || '\'\''; // Substring count is not a native Dart function. Define one. - const functionName = Blockly.Dart.provideFunction_( + const functionName = Dart.provideFunction_( 'text_count', - ['int ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + + ['int ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(String haystack, String needle) {', ' if (needle.length == 0) {', ' return haystack.length + 1;', @@ -330,26 +331,26 @@ Blockly.Dart['text_count'] = function(block) { ' return count;', '}']); const code = functionName + '(' + text + ', ' + sub + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['text_replace'] = function(block) { - const text = Blockly.Dart.valueToCode(block, 'TEXT', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\''; - const from = Blockly.Dart.valueToCode(block, 'FROM', - Blockly.Dart.ORDER_NONE) || '\'\''; - const to = Blockly.Dart.valueToCode(block, 'TO', - Blockly.Dart.ORDER_NONE) || '\'\''; +Dart['text_replace'] = function(block) { + const text = Dart.valueToCode(block, 'TEXT', + Dart.ORDER_UNARY_POSTFIX) || '\'\''; + const from = Dart.valueToCode(block, 'FROM', + Dart.ORDER_NONE) || '\'\''; + const to = Dart.valueToCode(block, 'TO', + Dart.ORDER_NONE) || '\'\''; const code = text + '.replaceAll(' + from + ', ' + to + ')'; - return [code, Blockly.Dart.ORDER_UNARY_POSTFIX]; + return [code, Dart.ORDER_UNARY_POSTFIX]; }; -Blockly.Dart['text_reverse'] = function(block) { +Dart['text_reverse'] = function(block) { // There isn't a sensible way to do this in Dart. See: // http://stackoverflow.com/a/21613700/3529104 // Implementing something is possibly better than not implementing anything? - const text = Blockly.Dart.valueToCode(block, 'TEXT', - Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\''; + const text = Dart.valueToCode(block, 'TEXT', + Dart.ORDER_UNARY_POSTFIX) || '\'\''; const code = 'new String.fromCharCodes(' + text + '.runes.toList().reversed)'; - return [code, Blockly.Dart.ORDER_UNARY_PREFIX]; + return [code, Dart.ORDER_UNARY_PREFIX]; }; diff --git a/generators/dart/variables.js b/generators/dart/variables.js index 31506d3b320..5b3a42e6bc2 100644 --- a/generators/dart/variables.js +++ b/generators/dart/variables.js @@ -9,23 +9,24 @@ */ 'use strict'; -goog.provide('Blockly.Dart.variables'); +goog.module('Blockly.Dart.variables'); -goog.require('Blockly.Dart'); +const Blockly = goog.require('Blockly'); +const Dart = goog.require('Blockly.Dart'); -Blockly.Dart['variables_get'] = function(block) { +Dart['variables_get'] = function(block) { // Variable getter. - const code = Blockly.Dart.nameDB_.getName(block.getFieldValue('VAR'), + const code = Dart.nameDB_.getName(block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - return [code, Blockly.Dart.ORDER_ATOMIC]; + return [code, Dart.ORDER_ATOMIC]; }; -Blockly.Dart['variables_set'] = function(block) { +Dart['variables_set'] = function(block) { // Variable setter. - const argument0 = Blockly.Dart.valueToCode(block, 'VALUE', - Blockly.Dart.ORDER_ASSIGNMENT) || '0'; - const varName = Blockly.Dart.nameDB_.getName(block.getFieldValue('VAR'), + const argument0 = Dart.valueToCode(block, 'VALUE', + Dart.ORDER_ASSIGNMENT) || '0'; + const varName = Dart.nameDB_.getName(block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); return varName + ' = ' + argument0 + ';\n'; }; diff --git a/generators/dart/variables_dynamic.js b/generators/dart/variables_dynamic.js index c9fd9edeca5..259745331b2 100644 --- a/generators/dart/variables_dynamic.js +++ b/generators/dart/variables_dynamic.js @@ -9,12 +9,13 @@ */ 'use strict'; -goog.provide('Blockly.Dart.variablesDynamic'); +goog.module('Blockly.Dart.variablesDynamic'); -goog.require('Blockly.Dart'); -goog.require('Blockly.Dart.variables'); +const Dart = goog.require('Blockly.Dart'); +// Required for side effects. +const variables = goog.require('Blockly.Dart.variables'); // Dart is dynamically typed. -Blockly.Dart['variables_get_dynamic'] = Blockly.Dart['variables_get']; -Blockly.Dart['variables_set_dynamic'] = Blockly.Dart['variables_set']; +Dart['variables_get_dynamic'] = Dart['variables_get']; +Dart['variables_set_dynamic'] = Dart['variables_set']; diff --git a/generators/javascript.js b/generators/javascript.js index ecf0c6e2aab..fbd16f839c2 100644 --- a/generators/javascript.js +++ b/generators/javascript.js @@ -9,20 +9,26 @@ */ 'use strict'; -goog.provide('Blockly.JavaScript'); +goog.module('Blockly.JavaScript'); +goog.module.declareLegacyNamespace(); -goog.require('Blockly.Generator'); -goog.require('Blockly.inputTypes'); -goog.require('Blockly.utils.global'); -goog.require('Blockly.utils.object'); -goog.require('Blockly.utils.string'); +const Blockly = goog.require('Blockly'); +const {Generator} = goog.require('Blockly.Generator'); +const {inputTypes} = goog.require('Blockly.inputTypes'); +const {globalThis} = goog.require('Blockly.utils.global'); +const objectUtils = goog.require('Blockly.utils.object'); +const stringUtils = goog.require('Blockly.utils.string'); +const {Names} = goog.require('Blockly.Names'); +const Variables = goog.require('Blockly.Variables'); +const {Workspace} = goog.requireType('Blockly.Workspace'); +const {Block} = goog.requireType('Blockly.Block'); /** * JavaScript code generator. - * @type {!Blockly.Generator} + * @type {!Generator} */ -Blockly.JavaScript = new Blockly.Generator('JavaScript'); +const JavaScript = new Generator('JavaScript'); /** * List of illegal variable names. @@ -31,7 +37,7 @@ Blockly.JavaScript = new Blockly.Generator('JavaScript'); * accidentally clobbering a built-in object or function. * @private */ -Blockly.JavaScript.addReservedWords( +JavaScript.addReservedWords( // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords 'break,case,catch,class,const,continue,debugger,default,delete,do,else,export,extends,finally,for,function,if,import,in,instanceof,new,return,super,switch,this,throw,try,typeof,var,void,while,with,yield,' + 'enum,' + @@ -41,95 +47,95 @@ Blockly.JavaScript.addReservedWords( // Magic variable. 'arguments,' + // Everything in the current environment (835 items in Chrome, 104 in Node). - Object.getOwnPropertyNames(Blockly.utils.global.globalThis).join(',')); + Object.getOwnPropertyNames(globalThis).join(',')); /** * Order of operation ENUMs. * https://developer.mozilla.org/en/JavaScript/Reference/Operators/Operator_Precedence */ -Blockly.JavaScript.ORDER_ATOMIC = 0; // 0 "" ... -Blockly.JavaScript.ORDER_NEW = 1.1; // new -Blockly.JavaScript.ORDER_MEMBER = 1.2; // . [] -Blockly.JavaScript.ORDER_FUNCTION_CALL = 2; // () -Blockly.JavaScript.ORDER_INCREMENT = 3; // ++ -Blockly.JavaScript.ORDER_DECREMENT = 3; // -- -Blockly.JavaScript.ORDER_BITWISE_NOT = 4.1; // ~ -Blockly.JavaScript.ORDER_UNARY_PLUS = 4.2; // + -Blockly.JavaScript.ORDER_UNARY_NEGATION = 4.3; // - -Blockly.JavaScript.ORDER_LOGICAL_NOT = 4.4; // ! -Blockly.JavaScript.ORDER_TYPEOF = 4.5; // typeof -Blockly.JavaScript.ORDER_VOID = 4.6; // void -Blockly.JavaScript.ORDER_DELETE = 4.7; // delete -Blockly.JavaScript.ORDER_AWAIT = 4.8; // await -Blockly.JavaScript.ORDER_EXPONENTIATION = 5.0; // ** -Blockly.JavaScript.ORDER_MULTIPLICATION = 5.1; // * -Blockly.JavaScript.ORDER_DIVISION = 5.2; // / -Blockly.JavaScript.ORDER_MODULUS = 5.3; // % -Blockly.JavaScript.ORDER_SUBTRACTION = 6.1; // - -Blockly.JavaScript.ORDER_ADDITION = 6.2; // + -Blockly.JavaScript.ORDER_BITWISE_SHIFT = 7; // << >> >>> -Blockly.JavaScript.ORDER_RELATIONAL = 8; // < <= > >= -Blockly.JavaScript.ORDER_IN = 8; // in -Blockly.JavaScript.ORDER_INSTANCEOF = 8; // instanceof -Blockly.JavaScript.ORDER_EQUALITY = 9; // == != === !== -Blockly.JavaScript.ORDER_BITWISE_AND = 10; // & -Blockly.JavaScript.ORDER_BITWISE_XOR = 11; // ^ -Blockly.JavaScript.ORDER_BITWISE_OR = 12; // | -Blockly.JavaScript.ORDER_LOGICAL_AND = 13; // && -Blockly.JavaScript.ORDER_LOGICAL_OR = 14; // || -Blockly.JavaScript.ORDER_CONDITIONAL = 15; // ?: -Blockly.JavaScript.ORDER_ASSIGNMENT = 16; // = += -= **= *= /= %= <<= >>= ... -Blockly.JavaScript.ORDER_YIELD = 17; // yield -Blockly.JavaScript.ORDER_COMMA = 18; // , -Blockly.JavaScript.ORDER_NONE = 99; // (...) +JavaScript.ORDER_ATOMIC = 0; // 0 "" ... +JavaScript.ORDER_NEW = 1.1; // new +JavaScript.ORDER_MEMBER = 1.2; // . [] +JavaScript.ORDER_FUNCTION_CALL = 2; // () +JavaScript.ORDER_INCREMENT = 3; // ++ +JavaScript.ORDER_DECREMENT = 3; // -- +JavaScript.ORDER_BITWISE_NOT = 4.1; // ~ +JavaScript.ORDER_UNARY_PLUS = 4.2; // + +JavaScript.ORDER_UNARY_NEGATION = 4.3; // - +JavaScript.ORDER_LOGICAL_NOT = 4.4; // ! +JavaScript.ORDER_TYPEOF = 4.5; // typeof +JavaScript.ORDER_VOID = 4.6; // void +JavaScript.ORDER_DELETE = 4.7; // delete +JavaScript.ORDER_AWAIT = 4.8; // await +JavaScript.ORDER_EXPONENTIATION = 5.0; // ** +JavaScript.ORDER_MULTIPLICATION = 5.1; // * +JavaScript.ORDER_DIVISION = 5.2; // / +JavaScript.ORDER_MODULUS = 5.3; // % +JavaScript.ORDER_SUBTRACTION = 6.1; // - +JavaScript.ORDER_ADDITION = 6.2; // + +JavaScript.ORDER_BITWISE_SHIFT = 7; // << >> >>> +JavaScript.ORDER_RELATIONAL = 8; // < <= > >= +JavaScript.ORDER_IN = 8; // in +JavaScript.ORDER_INSTANCEOF = 8; // instanceof +JavaScript.ORDER_EQUALITY = 9; // == != === !== +JavaScript.ORDER_BITWISE_AND = 10; // & +JavaScript.ORDER_BITWISE_XOR = 11; // ^ +JavaScript.ORDER_BITWISE_OR = 12; // | +JavaScript.ORDER_LOGICAL_AND = 13; // && +JavaScript.ORDER_LOGICAL_OR = 14; // || +JavaScript.ORDER_CONDITIONAL = 15; // ?: +JavaScript.ORDER_ASSIGNMENT = 16; // = += -= **= *= /= %= <<= >>= ... +JavaScript.ORDER_YIELD = 17; // yield +JavaScript.ORDER_COMMA = 18; // , +JavaScript.ORDER_NONE = 99; // (...) /** * List of outer-inner pairings that do NOT require parentheses. * @type {!Array>} */ -Blockly.JavaScript.ORDER_OVERRIDES = [ +JavaScript.ORDER_OVERRIDES = [ // (foo()).bar -> foo().bar // (foo())[0] -> foo()[0] - [Blockly.JavaScript.ORDER_FUNCTION_CALL, Blockly.JavaScript.ORDER_MEMBER], + [JavaScript.ORDER_FUNCTION_CALL, JavaScript.ORDER_MEMBER], // (foo())() -> foo()() - [Blockly.JavaScript.ORDER_FUNCTION_CALL, Blockly.JavaScript.ORDER_FUNCTION_CALL], + [JavaScript.ORDER_FUNCTION_CALL, JavaScript.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] - [Blockly.JavaScript.ORDER_MEMBER, Blockly.JavaScript.ORDER_MEMBER], + [JavaScript.ORDER_MEMBER, JavaScript.ORDER_MEMBER], // (foo.bar)() -> foo.bar() // (foo[0])() -> foo[0]() - [Blockly.JavaScript.ORDER_MEMBER, Blockly.JavaScript.ORDER_FUNCTION_CALL], + [JavaScript.ORDER_MEMBER, JavaScript.ORDER_FUNCTION_CALL], // !(!foo) -> !!foo - [Blockly.JavaScript.ORDER_LOGICAL_NOT, Blockly.JavaScript.ORDER_LOGICAL_NOT], + [JavaScript.ORDER_LOGICAL_NOT, JavaScript.ORDER_LOGICAL_NOT], // a * (b * c) -> a * b * c - [Blockly.JavaScript.ORDER_MULTIPLICATION, Blockly.JavaScript.ORDER_MULTIPLICATION], + [JavaScript.ORDER_MULTIPLICATION, JavaScript.ORDER_MULTIPLICATION], // a + (b + c) -> a + b + c - [Blockly.JavaScript.ORDER_ADDITION, Blockly.JavaScript.ORDER_ADDITION], + [JavaScript.ORDER_ADDITION, JavaScript.ORDER_ADDITION], // a && (b && c) -> a && b && c - [Blockly.JavaScript.ORDER_LOGICAL_AND, Blockly.JavaScript.ORDER_LOGICAL_AND], + [JavaScript.ORDER_LOGICAL_AND, JavaScript.ORDER_LOGICAL_AND], // a || (b || c) -> a || b || c - [Blockly.JavaScript.ORDER_LOGICAL_OR, Blockly.JavaScript.ORDER_LOGICAL_OR] + [JavaScript.ORDER_LOGICAL_OR, JavaScript.ORDER_LOGICAL_OR] ]; /** * Whether the init method has been called. * @type {?boolean} */ -Blockly.JavaScript.isInitialized = false; +JavaScript.isInitialized = false; /** * Initialise the database of variable names. - * @param {!Blockly.Workspace} workspace Workspace to generate code from. + * @param {!Workspace} workspace Workspace to generate code from. */ -Blockly.JavaScript.init = function(workspace) { +JavaScript.init = function(workspace) { // Call Blockly.Generator's init. Object.getPrototypeOf(this).init.call(this); if (!this.nameDB_) { - this.nameDB_ = new Blockly.Names(this.RESERVED_WORDS_); + this.nameDB_ = new Names(this.RESERVED_WORDS_); } else { this.nameDB_.reset(); } @@ -140,14 +146,14 @@ Blockly.JavaScript.init = function(workspace) { const defvars = []; // Add developer variables (not created or named by the user). - const devVarList = Blockly.Variables.allDeveloperVariables(workspace); + const devVarList = Variables.allDeveloperVariables(workspace); for (let i = 0; i < devVarList.length; i++) { defvars.push(this.nameDB_.getName(devVarList[i], - Blockly.Names.DEVELOPER_VARIABLE_TYPE)); + Names.DEVELOPER_VARIABLE_TYPE)); } // Add user variables, but only ones that are being used. - const variables = Blockly.Variables.allUsedVarModels(workspace); + const variables = Variables.allUsedVarModels(workspace); for (let i = 0; i < variables.length; i++) { defvars.push(this.nameDB_.getName(variables[i].getId(), Blockly.VARIABLE_CATEGORY_NAME)); @@ -165,9 +171,9 @@ Blockly.JavaScript.init = function(workspace) { * @param {string} code Generated code. * @return {string} Completed code. */ -Blockly.JavaScript.finish = function(code) { +JavaScript.finish = function(code) { // Convert the definitions dictionary into a list. - const definitions = Blockly.utils.object.values(this.definitions_); + const definitions = objectUtils.values(this.definitions_); // Call Blockly.Generator's finish. code = Object.getPrototypeOf(this).finish.call(this, code); this.isInitialized = false; @@ -182,7 +188,7 @@ Blockly.JavaScript.finish = function(code) { * @param {string} line Line of generated code. * @return {string} Legal line of code. */ -Blockly.JavaScript.scrubNakedValue = function(line) { +JavaScript.scrubNakedValue = function(line) { return line + ';\n'; }; @@ -193,12 +199,12 @@ Blockly.JavaScript.scrubNakedValue = function(line) { * @return {string} JavaScript string. * @protected */ -Blockly.JavaScript.quote_ = function(string) { +JavaScript.quote_ = function(string) { // Can't use goog.string.quote since Google's style guide recommends // JS string literals use single quotes. string = string.replace(/\\/g, '\\\\') - .replace(/\n/g, '\\\n') - .replace(/'/g, '\\\''); + .replace(/\n/g, '\\\n') + .replace(/'/g, '\\\''); return '\'' + string + '\''; }; @@ -209,7 +215,7 @@ Blockly.JavaScript.quote_ = function(string) { * @return {string} JavaScript string. * @protected */ -Blockly.JavaScript.multiline_quote_ = function(string) { +JavaScript.multiline_quote_ = function(string) { // Can't use goog.string.quote since Google's style guide recommends // JS string literals use single quotes. const lines = string.split(/\n/g).map(this.quote_); @@ -220,26 +226,26 @@ Blockly.JavaScript.multiline_quote_ = function(string) { * Common tasks for generating JavaScript 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 {!Block} block The current block. * @param {string} code The JavaScript code created for this block. * @param {boolean=} opt_thisOnly True to generate code for only this statement. * @return {string} JavaScript code with comments and subsequent blocks added. * @protected */ -Blockly.JavaScript.scrub_ = function(block, code, opt_thisOnly) { +JavaScript.scrub_ = function(block, code, opt_thisOnly) { let 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) { - comment = Blockly.utils.string.wrap(comment, this.COMMENT_WRAP - 3); + comment = stringUtils.wrap(comment, this.COMMENT_WRAP - 3); commentCode += this.prefixLines(comment + '\n', '// '); } // Collect comments for all value arguments. // Don't collect comments for nested statements. for (let i = 0; i < block.inputList.length; i++) { - if (block.inputList[i].type === Blockly.inputTypes.VALUE) { + if (block.inputList[i].type === inputTypes.VALUE) { const childBlock = block.inputList[i].connection.targetBlock(); if (childBlock) { comment = this.allNestedComments(childBlock); @@ -257,14 +263,14 @@ Blockly.JavaScript.scrub_ = function(block, code, opt_thisOnly) { /** * Gets a property and adjusts the value while taking into account indexing. - * @param {!Blockly.Block} block The block. + * @param {!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. * @param {number=} opt_order The highest order acting on this value. * @return {string|number} */ -Blockly.JavaScript.getAdjusted = function(block, atId, opt_delta, opt_negate, +JavaScript.getAdjusted = function(block, atId, opt_delta, opt_negate, opt_order) { let delta = opt_delta || 0; let order = opt_order || this.ORDER_NONE; @@ -316,3 +322,5 @@ Blockly.JavaScript.getAdjusted = function(block, atId, opt_delta, opt_negate, } return at; }; + +exports = JavaScript; diff --git a/generators/javascript/colour.js b/generators/javascript/colour.js index 1d204c64319..cb0f400777f 100644 --- a/generators/javascript/colour.js +++ b/generators/javascript/colour.js @@ -9,40 +9,40 @@ */ 'use strict'; -goog.provide('Blockly.JavaScript.colour'); +goog.module('Blockly.JavaScript.colour'); -goog.require('Blockly.JavaScript'); +const JavaScript = goog.require('Blockly.JavaScript'); -Blockly.JavaScript['colour_picker'] = function(block) { +JavaScript['colour_picker'] = function(block) { // Colour picker. - const code = Blockly.JavaScript.quote_(block.getFieldValue('COLOUR')); - return [code, Blockly.JavaScript.ORDER_ATOMIC]; + const code = JavaScript.quote_(block.getFieldValue('COLOUR')); + return [code, JavaScript.ORDER_ATOMIC]; }; -Blockly.JavaScript['colour_random'] = function(block) { +JavaScript['colour_random'] = function(block) { // Generate a random colour. - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'colourRandom', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '() {', + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '() {', ' var num = Math.floor(Math.random() * Math.pow(2, 24));', ' return \'#\' + (\'00000\' + num.toString(16)).substr(-6);', '}']); const code = functionName + '()'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['colour_rgb'] = function(block) { +JavaScript['colour_rgb'] = function(block) { // Compose a colour from RGB components expressed as percentages. - const red = Blockly.JavaScript.valueToCode(block, 'RED', - Blockly.JavaScript.ORDER_NONE) || 0; - const green = Blockly.JavaScript.valueToCode(block, 'GREEN', - Blockly.JavaScript.ORDER_NONE) || 0; - const blue = Blockly.JavaScript.valueToCode(block, 'BLUE', - Blockly.JavaScript.ORDER_NONE) || 0; - const functionName = Blockly.JavaScript.provideFunction_( + const red = JavaScript.valueToCode(block, 'RED', + JavaScript.ORDER_NONE) || 0; + const green = JavaScript.valueToCode(block, 'GREEN', + JavaScript.ORDER_NONE) || 0; + const blue = JavaScript.valueToCode(block, 'BLUE', + JavaScript.ORDER_NONE) || 0; + const functionName = JavaScript.provideFunction_( 'colourRgb', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b) {', ' r = Math.max(Math.min(Number(r), 100), 0) * 2.55;', ' g = Math.max(Math.min(Number(g), 100), 0) * 2.55;', @@ -53,20 +53,20 @@ Blockly.JavaScript['colour_rgb'] = function(block) { ' return \'#\' + r + g + b;', '}']); const code = functionName + '(' + red + ', ' + green + ', ' + blue + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['colour_blend'] = function(block) { +JavaScript['colour_blend'] = function(block) { // Blend two colours together. - const c1 = Blockly.JavaScript.valueToCode(block, 'COLOUR1', - Blockly.JavaScript.ORDER_NONE) || '\'#000000\''; - const c2 = Blockly.JavaScript.valueToCode(block, 'COLOUR2', - Blockly.JavaScript.ORDER_NONE) || '\'#000000\''; - const ratio = Blockly.JavaScript.valueToCode(block, 'RATIO', - Blockly.JavaScript.ORDER_NONE) || 0.5; - const functionName = Blockly.JavaScript.provideFunction_( + const c1 = JavaScript.valueToCode(block, 'COLOUR1', + JavaScript.ORDER_NONE) || '\'#000000\''; + const c2 = JavaScript.valueToCode(block, 'COLOUR2', + JavaScript.ORDER_NONE) || '\'#000000\''; + const ratio = JavaScript.valueToCode(block, 'RATIO', + JavaScript.ORDER_NONE) || 0.5; + const functionName = JavaScript.provideFunction_( 'colourBlend', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(c1, c2, ratio) {', ' ratio = Math.max(Math.min(Number(ratio), 1), 0);', ' var r1 = parseInt(c1.substring(1, 3), 16);', @@ -84,5 +84,5 @@ Blockly.JavaScript['colour_blend'] = function(block) { ' return \'#\' + r + g + b;', '}']); const code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; diff --git a/generators/javascript/lists.js b/generators/javascript/lists.js index c85a45968f4..bbc3a8b1706 100644 --- a/generators/javascript/lists.js +++ b/generators/javascript/lists.js @@ -9,32 +9,33 @@ */ 'use strict'; -goog.provide('Blockly.JavaScript.lists'); +goog.module('Blockly.JavaScript.lists'); -goog.require('Blockly.JavaScript'); +const Blockly = goog.require('Blockly'); +const JavaScript = goog.require('Blockly.JavaScript'); -Blockly.JavaScript['lists_create_empty'] = function(block) { +JavaScript['lists_create_empty'] = function(block) { // Create an empty list. - return ['[]', Blockly.JavaScript.ORDER_ATOMIC]; + return ['[]', JavaScript.ORDER_ATOMIC]; }; -Blockly.JavaScript['lists_create_with'] = function(block) { +JavaScript['lists_create_with'] = function(block) { // Create a list with any number of elements of any type. const elements = new Array(block.itemCount_); for (let i = 0; i < block.itemCount_; i++) { - elements[i] = Blockly.JavaScript.valueToCode(block, 'ADD' + i, - Blockly.JavaScript.ORDER_NONE) || 'null'; + elements[i] = JavaScript.valueToCode(block, 'ADD' + i, + JavaScript.ORDER_NONE) || 'null'; } const code = '[' + elements.join(', ') + ']'; - return [code, Blockly.JavaScript.ORDER_ATOMIC]; + return [code, JavaScript.ORDER_ATOMIC]; }; -Blockly.JavaScript['lists_repeat'] = function(block) { +JavaScript['lists_repeat'] = function(block) { // Create a list with one element repeated. - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'listsRepeat', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(value, n) {', ' var array = [];', ' for (var i = 0; i < n; i++) {', @@ -42,60 +43,60 @@ Blockly.JavaScript['lists_repeat'] = function(block) { ' }', ' return array;', '}']); - const element = Blockly.JavaScript.valueToCode(block, 'ITEM', - Blockly.JavaScript.ORDER_NONE) || 'null'; - const repeatCount = Blockly.JavaScript.valueToCode(block, 'NUM', - Blockly.JavaScript.ORDER_NONE) || '0'; + const element = JavaScript.valueToCode(block, 'ITEM', + JavaScript.ORDER_NONE) || 'null'; + const repeatCount = JavaScript.valueToCode(block, 'NUM', + JavaScript.ORDER_NONE) || '0'; const code = functionName + '(' + element + ', ' + repeatCount + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['lists_length'] = function(block) { +JavaScript['lists_length'] = function(block) { // String or array length. - const list = Blockly.JavaScript.valueToCode(block, 'VALUE', - Blockly.JavaScript.ORDER_MEMBER) || '[]'; - return [list + '.length', Blockly.JavaScript.ORDER_MEMBER]; + const list = JavaScript.valueToCode(block, 'VALUE', + JavaScript.ORDER_MEMBER) || '[]'; + return [list + '.length', JavaScript.ORDER_MEMBER]; }; -Blockly.JavaScript['lists_isEmpty'] = function(block) { +JavaScript['lists_isEmpty'] = function(block) { // Is the string null or array empty? - const list = Blockly.JavaScript.valueToCode(block, 'VALUE', - Blockly.JavaScript.ORDER_MEMBER) || '[]'; - return ['!' + list + '.length', Blockly.JavaScript.ORDER_LOGICAL_NOT]; + const list = JavaScript.valueToCode(block, 'VALUE', + JavaScript.ORDER_MEMBER) || '[]'; + return ['!' + list + '.length', JavaScript.ORDER_LOGICAL_NOT]; }; -Blockly.JavaScript['lists_indexOf'] = function(block) { +JavaScript['lists_indexOf'] = function(block) { // Find an item in the list. const operator = block.getFieldValue('END') === 'FIRST' ? 'indexOf' : 'lastIndexOf'; - const item = Blockly.JavaScript.valueToCode(block, 'FIND', - Blockly.JavaScript.ORDER_NONE) || '\'\''; - const list = Blockly.JavaScript.valueToCode(block, 'VALUE', - Blockly.JavaScript.ORDER_MEMBER) || '[]'; + const item = JavaScript.valueToCode(block, 'FIND', + JavaScript.ORDER_NONE) || '\'\''; + const list = JavaScript.valueToCode(block, 'VALUE', + JavaScript.ORDER_MEMBER) || '[]'; const code = list + '.' + operator + '(' + item + ')'; if (block.workspace.options.oneBasedIndex) { - return [code + ' + 1', Blockly.JavaScript.ORDER_ADDITION]; + return [code + ' + 1', JavaScript.ORDER_ADDITION]; } - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['lists_getIndex'] = function(block) { +JavaScript['lists_getIndex'] = function(block) { // Get element at index. // Note: Until January 2013 this block did not have MODE or WHERE inputs. const mode = block.getFieldValue('MODE') || 'GET'; const where = block.getFieldValue('WHERE') || 'FROM_START'; - const listOrder = (where === 'RANDOM') ? Blockly.JavaScript.ORDER_NONE : - Blockly.JavaScript.ORDER_MEMBER; - const list = Blockly.JavaScript.valueToCode(block, 'VALUE', listOrder) || '[]'; + const listOrder = (where === 'RANDOM') ? JavaScript.ORDER_NONE : + JavaScript.ORDER_MEMBER; + const list = JavaScript.valueToCode(block, 'VALUE', listOrder) || '[]'; switch (where) { case ('FIRST'): if (mode === 'GET') { const code = list + '[0]'; - return [code, Blockly.JavaScript.ORDER_MEMBER]; + return [code, JavaScript.ORDER_MEMBER]; } else if (mode === 'GET_REMOVE') { const code = list + '.shift()'; - return [code, Blockly.JavaScript.ORDER_MEMBER]; + return [code, JavaScript.ORDER_MEMBER]; } else if (mode === 'REMOVE') { return list + '.shift();\n'; } @@ -103,44 +104,44 @@ Blockly.JavaScript['lists_getIndex'] = function(block) { case ('LAST'): if (mode === 'GET') { const code = list + '.slice(-1)[0]'; - return [code, Blockly.JavaScript.ORDER_MEMBER]; + return [code, JavaScript.ORDER_MEMBER]; } else if (mode === 'GET_REMOVE') { const code = list + '.pop()'; - return [code, Blockly.JavaScript.ORDER_MEMBER]; + return [code, JavaScript.ORDER_MEMBER]; } else if (mode === 'REMOVE') { return list + '.pop();\n'; } break; case ('FROM_START'): { - const at = Blockly.JavaScript.getAdjusted(block, 'AT'); + const at = JavaScript.getAdjusted(block, 'AT'); if (mode === 'GET') { const code = list + '[' + at + ']'; - return [code, Blockly.JavaScript.ORDER_MEMBER]; + return [code, JavaScript.ORDER_MEMBER]; } else if (mode === 'GET_REMOVE') { const code = list + '.splice(' + at + ', 1)[0]'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { return list + '.splice(' + at + ', 1);\n'; } break; } case ('FROM_END'): { - const at = Blockly.JavaScript.getAdjusted(block, 'AT', 1, true); + const at = JavaScript.getAdjusted(block, 'AT', 1, true); if (mode === 'GET') { const code = list + '.slice(' + at + ')[0]'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } else if (mode === 'GET_REMOVE') { const code = list + '.splice(' + at + ', 1)[0]'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { return list + '.splice(' + at + ', 1);'; } break; } case ('RANDOM'): { - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'listsGetRandomItem', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(list, remove) {', ' var x = Math.floor(Math.random() * list.length);', ' if (remove) {', @@ -151,7 +152,7 @@ Blockly.JavaScript['lists_getIndex'] = function(block) { '}']); const code = functionName + '(' + list + ', ' + (mode !== 'GET') + ')'; if (mode === 'GET' || mode === 'GET_REMOVE') { - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { return code + ';\n'; } @@ -161,22 +162,22 @@ Blockly.JavaScript['lists_getIndex'] = function(block) { throw Error('Unhandled combination (lists_getIndex).'); }; -Blockly.JavaScript['lists_setIndex'] = function(block) { +JavaScript['lists_setIndex'] = function(block) { // Set element at index. // Note: Until February 2013 this block did not have MODE or WHERE inputs. - let list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_MEMBER) || '[]'; + let list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_MEMBER) || '[]'; const mode = block.getFieldValue('MODE') || 'GET'; const where = block.getFieldValue('WHERE') || 'FROM_START'; - const value = Blockly.JavaScript.valueToCode(block, 'TO', - Blockly.JavaScript.ORDER_ASSIGNMENT) || 'null'; + const value = JavaScript.valueToCode(block, 'TO', + JavaScript.ORDER_ASSIGNMENT) || 'null'; // Cache non-trivial values to variables to prevent repeated look-ups. // Closure, which accesses and modifies 'list'. function cacheList() { if (list.match(/^\w+$/)) { return ''; } - const listVar = Blockly.JavaScript.nameDB_.getDistinctName( + const listVar = JavaScript.nameDB_.getDistinctName( 'tmpList', Blockly.VARIABLE_CATEGORY_NAME); const code = 'var ' + listVar + ' = ' + list + ';\n'; list = listVar; @@ -200,7 +201,7 @@ Blockly.JavaScript['lists_setIndex'] = function(block) { } break; case ('FROM_START'): { - const at = Blockly.JavaScript.getAdjusted(block, 'AT'); + const at = JavaScript.getAdjusted(block, 'AT'); if (mode === 'SET') { return list + '[' + at + '] = ' + value + ';\n'; } else if (mode === 'INSERT') { @@ -209,8 +210,8 @@ Blockly.JavaScript['lists_setIndex'] = function(block) { break; } case ('FROM_END'): { - const at = Blockly.JavaScript.getAdjusted(block, 'AT', 1, false, - Blockly.JavaScript.ORDER_SUBTRACTION); + const at = JavaScript.getAdjusted(block, 'AT', 1, false, + JavaScript.ORDER_SUBTRACTION); let code = cacheList(); if (mode === 'SET') { code += list + '[' + list + '.length - ' + at + '] = ' + value + ';\n'; @@ -224,7 +225,7 @@ Blockly.JavaScript['lists_setIndex'] = function(block) { } case ('RANDOM'): { let code = cacheList(); - const xVar = Blockly.JavaScript.nameDB_.getDistinctName( + const xVar = JavaScript.nameDB_.getDistinctName( 'tmpX', Blockly.VARIABLE_CATEGORY_NAME); code += 'var ' + xVar + ' = Math.floor(Math.random() * ' + list + '.length);\n'; @@ -247,9 +248,8 @@ Blockly.JavaScript['lists_setIndex'] = function(block) { * @param {string} where The method of indexing, selected by dropdown in Blockly * @param {string=} opt_at The optional offset when indexing from start/end. * @return {string|undefined} Index expression. - * @private */ -Blockly.JavaScript.lists.getIndex_ = function(listName, where, opt_at) { +const getIndex_ = function(listName, where, opt_at) { if (where === 'FIRST') { return '0'; } else if (where === 'FROM_END') { @@ -261,10 +261,10 @@ Blockly.JavaScript.lists.getIndex_ = function(listName, where, opt_at) { } }; -Blockly.JavaScript['lists_getSublist'] = function(block) { +JavaScript['lists_getSublist'] = function(block) { // Get sublist. - const list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_MEMBER) || '[]'; + const list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_MEMBER) || '[]'; const where1 = block.getFieldValue('WHERE1'); const where2 = block.getFieldValue('WHERE2'); let code; @@ -277,11 +277,11 @@ Blockly.JavaScript['lists_getSublist'] = function(block) { let at1; switch (where1) { case 'FROM_START': - at1 = Blockly.JavaScript.getAdjusted(block, 'AT1'); + at1 = JavaScript.getAdjusted(block, 'AT1'); break; case 'FROM_END': - at1 = Blockly.JavaScript.getAdjusted(block, 'AT1', 1, false, - Blockly.JavaScript.ORDER_SUBTRACTION); + at1 = JavaScript.getAdjusted(block, 'AT1', 1, false, + JavaScript.ORDER_SUBTRACTION); at1 = list + '.length - ' + at1; break; case 'FIRST': @@ -293,11 +293,11 @@ Blockly.JavaScript['lists_getSublist'] = function(block) { let at2; switch (where2) { case 'FROM_START': - at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 1); + at2 = JavaScript.getAdjusted(block, 'AT2', 1); break; case 'FROM_END': - at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 0, false, - Blockly.JavaScript.ORDER_SUBTRACTION); + at2 = JavaScript.getAdjusted(block, 'AT2', 0, false, + JavaScript.ORDER_SUBTRACTION); at2 = list + '.length - ' + at2; break; case 'LAST': @@ -308,14 +308,13 @@ Blockly.JavaScript['lists_getSublist'] = function(block) { } code = list + '.slice(' + at1 + ', ' + at2 + ')'; } else { - const at1 = Blockly.JavaScript.getAdjusted(block, 'AT1'); - const at2 = Blockly.JavaScript.getAdjusted(block, 'AT2'); - const getIndex_ = Blockly.JavaScript.lists.getIndex_; + const at1 = JavaScript.getAdjusted(block, 'AT1'); + const at2 = JavaScript.getAdjusted(block, 'AT2'); const wherePascalCase = {'FIRST': 'First', 'LAST': 'Last', 'FROM_START': 'FromStart', 'FROM_END': 'FromEnd'}; - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'subsequence' + wherePascalCase[where1] + wherePascalCase[where2], - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(sequence' + // The value for 'FROM_END' and'FROM_START' depends on `at` so // we add it as a parameter. @@ -333,18 +332,18 @@ Blockly.JavaScript['lists_getSublist'] = function(block) { ((where2 === 'FROM_END' || where2 === 'FROM_START') ? ', ' + at2 : '') + ')'; } - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['lists_sort'] = function(block) { +JavaScript['lists_sort'] = function(block) { // Block for sorting a list. - const list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_FUNCTION_CALL) || '[]'; + const list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_FUNCTION_CALL) || '[]'; const direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1; const type = block.getFieldValue('TYPE'); - const getCompareFunctionName = Blockly.JavaScript.provideFunction_( + const getCompareFunctionName = JavaScript.provideFunction_( 'listsGetSortCompare', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(type, direction) {', ' var compareFuncs = {', ' "NUMERIC": function(a, b) {', @@ -360,15 +359,15 @@ Blockly.JavaScript['lists_sort'] = function(block) { '}']); return [list + '.slice().sort(' + getCompareFunctionName + '("' + type + '", ' + direction + '))', - Blockly.JavaScript.ORDER_FUNCTION_CALL]; + JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['lists_split'] = function(block) { +JavaScript['lists_split'] = function(block) { // Block for splitting text into a list, or joining a list into text. - let input = Blockly.JavaScript.valueToCode(block, 'INPUT', - Blockly.JavaScript.ORDER_MEMBER); - const delimiter = Blockly.JavaScript.valueToCode(block, 'DELIM', - Blockly.JavaScript.ORDER_NONE) || '\'\''; + let input = JavaScript.valueToCode(block, 'INPUT', + JavaScript.ORDER_MEMBER); + const delimiter = JavaScript.valueToCode(block, 'DELIM', + JavaScript.ORDER_NONE) || '\'\''; const mode = block.getFieldValue('MODE'); let functionName; if (mode === 'SPLIT') { @@ -385,13 +384,13 @@ Blockly.JavaScript['lists_split'] = function(block) { throw Error('Unknown mode: ' + mode); } const code = input + '.' + functionName + '(' + delimiter + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['lists_reverse'] = function(block) { +JavaScript['lists_reverse'] = function(block) { // Block for reversing a list. - const list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_FUNCTION_CALL) || '[]'; + const list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_FUNCTION_CALL) || '[]'; const code = list + '.slice().reverse()'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; diff --git a/generators/javascript/logic.js b/generators/javascript/logic.js index a769a8709b4..88ff1423ed8 100644 --- a/generators/javascript/logic.js +++ b/generators/javascript/logic.js @@ -9,49 +9,49 @@ */ 'use strict'; -goog.provide('Blockly.JavaScript.logic'); +goog.module('Blockly.JavaScript.logic'); -goog.require('Blockly.JavaScript'); +const JavaScript = goog.require('Blockly.JavaScript'); -Blockly.JavaScript['controls_if'] = function(block) { +JavaScript['controls_if'] = function(block) { // If/elseif/else condition. let n = 0; let code = ''; - if (Blockly.JavaScript.STATEMENT_PREFIX) { + if (JavaScript.STATEMENT_PREFIX) { // Automatic prefix insertion is switched off for this block. Add manually. - code += Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_PREFIX, + code += JavaScript.injectId(JavaScript.STATEMENT_PREFIX, block); } do { - const conditionCode = Blockly.JavaScript.valueToCode(block, 'IF' + n, - Blockly.JavaScript.ORDER_NONE) || 'false'; - let branchCode = Blockly.JavaScript.statementToCode(block, 'DO' + n); - if (Blockly.JavaScript.STATEMENT_SUFFIX) { - branchCode = Blockly.JavaScript.prefixLines( - Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_SUFFIX, - block), Blockly.JavaScript.INDENT) + branchCode; + const conditionCode = JavaScript.valueToCode(block, 'IF' + n, + JavaScript.ORDER_NONE) || 'false'; + let branchCode = JavaScript.statementToCode(block, 'DO' + n); + if (JavaScript.STATEMENT_SUFFIX) { + branchCode = JavaScript.prefixLines( + JavaScript.injectId(JavaScript.STATEMENT_SUFFIX, + block), JavaScript.INDENT) + branchCode; } code += (n > 0 ? ' else ' : '') + 'if (' + conditionCode + ') {\n' + branchCode + '}'; n++; } while (block.getInput('IF' + n)); - if (block.getInput('ELSE') || Blockly.JavaScript.STATEMENT_SUFFIX) { - let branchCode = Blockly.JavaScript.statementToCode(block, 'ELSE'); - if (Blockly.JavaScript.STATEMENT_SUFFIX) { - branchCode = Blockly.JavaScript.prefixLines( - Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_SUFFIX, - block), Blockly.JavaScript.INDENT) + branchCode; + if (block.getInput('ELSE') || JavaScript.STATEMENT_SUFFIX) { + let branchCode = JavaScript.statementToCode(block, 'ELSE'); + if (JavaScript.STATEMENT_SUFFIX) { + branchCode = JavaScript.prefixLines( + JavaScript.injectId(JavaScript.STATEMENT_SUFFIX, + block), JavaScript.INDENT) + branchCode; } code += ' else {\n' + branchCode + '}'; } return code + '\n'; }; -Blockly.JavaScript['controls_ifelse'] = Blockly.JavaScript['controls_if']; +JavaScript['controls_ifelse'] = JavaScript['controls_if']; -Blockly.JavaScript['logic_compare'] = function(block) { +JavaScript['logic_compare'] = function(block) { // Comparison operator. const OPERATORS = { 'EQ': '==', @@ -63,20 +63,20 @@ Blockly.JavaScript['logic_compare'] = function(block) { }; const operator = OPERATORS[block.getFieldValue('OP')]; const order = (operator === '==' || operator === '!=') ? - Blockly.JavaScript.ORDER_EQUALITY : Blockly.JavaScript.ORDER_RELATIONAL; - const argument0 = Blockly.JavaScript.valueToCode(block, 'A', order) || '0'; - const argument1 = Blockly.JavaScript.valueToCode(block, 'B', order) || '0'; + JavaScript.ORDER_EQUALITY : JavaScript.ORDER_RELATIONAL; + const argument0 = JavaScript.valueToCode(block, 'A', order) || '0'; + const argument1 = JavaScript.valueToCode(block, 'B', order) || '0'; const code = argument0 + ' ' + operator + ' ' + argument1; return [code, order]; }; -Blockly.JavaScript['logic_operation'] = function(block) { +JavaScript['logic_operation'] = function(block) { // Operations 'and', 'or'. const operator = (block.getFieldValue('OP') === 'AND') ? '&&' : '||'; - const order = (operator === '&&') ? Blockly.JavaScript.ORDER_LOGICAL_AND : - Blockly.JavaScript.ORDER_LOGICAL_OR; - let argument0 = Blockly.JavaScript.valueToCode(block, 'A', order); - let argument1 = Blockly.JavaScript.valueToCode(block, 'B', order); + const order = (operator === '&&') ? JavaScript.ORDER_LOGICAL_AND : + JavaScript.ORDER_LOGICAL_OR; + let argument0 = JavaScript.valueToCode(block, 'A', order); + let argument1 = JavaScript.valueToCode(block, 'B', order); if (!argument0 && !argument1) { // If there are no arguments, then the return value is false. argument0 = 'false'; @@ -95,34 +95,34 @@ Blockly.JavaScript['logic_operation'] = function(block) { return [code, order]; }; -Blockly.JavaScript['logic_negate'] = function(block) { +JavaScript['logic_negate'] = function(block) { // Negation. - const order = Blockly.JavaScript.ORDER_LOGICAL_NOT; - const argument0 = Blockly.JavaScript.valueToCode(block, 'BOOL', order) || + const order = JavaScript.ORDER_LOGICAL_NOT; + const argument0 = JavaScript.valueToCode(block, 'BOOL', order) || 'true'; const code = '!' + argument0; return [code, order]; }; -Blockly.JavaScript['logic_boolean'] = function(block) { +JavaScript['logic_boolean'] = function(block) { // Boolean values true and false. const code = (block.getFieldValue('BOOL') === 'TRUE') ? 'true' : 'false'; - return [code, Blockly.JavaScript.ORDER_ATOMIC]; + return [code, JavaScript.ORDER_ATOMIC]; }; -Blockly.JavaScript['logic_null'] = function(block) { +JavaScript['logic_null'] = function(block) { // Null data type. - return ['null', Blockly.JavaScript.ORDER_ATOMIC]; + return ['null', JavaScript.ORDER_ATOMIC]; }; -Blockly.JavaScript['logic_ternary'] = function(block) { +JavaScript['logic_ternary'] = function(block) { // Ternary operator. - const value_if = Blockly.JavaScript.valueToCode(block, 'IF', - Blockly.JavaScript.ORDER_CONDITIONAL) || 'false'; - const value_then = Blockly.JavaScript.valueToCode(block, 'THEN', - Blockly.JavaScript.ORDER_CONDITIONAL) || 'null'; - const value_else = Blockly.JavaScript.valueToCode(block, 'ELSE', - Blockly.JavaScript.ORDER_CONDITIONAL) || 'null'; + const value_if = JavaScript.valueToCode(block, 'IF', + JavaScript.ORDER_CONDITIONAL) || 'false'; + const value_then = JavaScript.valueToCode(block, 'THEN', + JavaScript.ORDER_CONDITIONAL) || 'null'; + const value_else = JavaScript.valueToCode(block, 'ELSE', + JavaScript.ORDER_CONDITIONAL) || 'null'; const code = value_if + ' ? ' + value_then + ' : ' + value_else; - return [code, Blockly.JavaScript.ORDER_CONDITIONAL]; + return [code, JavaScript.ORDER_CONDITIONAL]; }; diff --git a/generators/javascript/loops.js b/generators/javascript/loops.js index 47975698e48..337d79f7b0b 100644 --- a/generators/javascript/loops.js +++ b/generators/javascript/loops.js @@ -9,12 +9,14 @@ */ 'use strict'; -goog.provide('Blockly.JavaScript.loops'); +goog.module('Blockly.JavaScript.loops'); -goog.require('Blockly.JavaScript'); +const Blockly = goog.require('Blockly'); +const JavaScript = goog.require('Blockly.JavaScript'); +const Loops = goog.require('Blockly.Constants.Loops'); -Blockly.JavaScript['controls_repeat_ext'] = function(block) { +JavaScript['controls_repeat_ext'] = function(block) { // Repeat n times. let repeats; if (block.getField('TIMES')) { @@ -22,17 +24,17 @@ Blockly.JavaScript['controls_repeat_ext'] = function(block) { repeats = String(Number(block.getFieldValue('TIMES'))); } else { // External number. - repeats = Blockly.JavaScript.valueToCode(block, 'TIMES', - Blockly.JavaScript.ORDER_ASSIGNMENT) || '0'; + repeats = JavaScript.valueToCode(block, 'TIMES', + JavaScript.ORDER_ASSIGNMENT) || '0'; } - let branch = Blockly.JavaScript.statementToCode(block, 'DO'); - branch = Blockly.JavaScript.addLoopTrap(branch, block); + let branch = JavaScript.statementToCode(block, 'DO'); + branch = JavaScript.addLoopTrap(branch, block); let code = ''; - const loopVar = Blockly.JavaScript.nameDB_.getDistinctName( + const loopVar = JavaScript.nameDB_.getDistinctName( 'count', Blockly.VARIABLE_CATEGORY_NAME); let endVar = repeats; if (!repeats.match(/^\w+$/) && !Blockly.isNumber(repeats)) { - endVar = Blockly.JavaScript.nameDB_.getDistinctName( + endVar = JavaScript.nameDB_.getDistinctName( 'repeat_end', Blockly.VARIABLE_CATEGORY_NAME); code += 'var ' + endVar + ' = ' + repeats + ';\n'; } @@ -43,35 +45,35 @@ Blockly.JavaScript['controls_repeat_ext'] = function(block) { return code; }; -Blockly.JavaScript['controls_repeat'] = - Blockly.JavaScript['controls_repeat_ext']; +JavaScript['controls_repeat'] = + JavaScript['controls_repeat_ext']; -Blockly.JavaScript['controls_whileUntil'] = function(block) { +JavaScript['controls_whileUntil'] = function(block) { // Do while/until loop. const until = block.getFieldValue('MODE') === 'UNTIL'; - let argument0 = Blockly.JavaScript.valueToCode(block, 'BOOL', - until ? Blockly.JavaScript.ORDER_LOGICAL_NOT : - Blockly.JavaScript.ORDER_NONE) || 'false'; - let branch = Blockly.JavaScript.statementToCode(block, 'DO'); - branch = Blockly.JavaScript.addLoopTrap(branch, block); + let argument0 = JavaScript.valueToCode(block, 'BOOL', + until ? JavaScript.ORDER_LOGICAL_NOT : + JavaScript.ORDER_NONE) || 'false'; + let branch = JavaScript.statementToCode(block, 'DO'); + branch = JavaScript.addLoopTrap(branch, block); if (until) { argument0 = '!' + argument0; } return 'while (' + argument0 + ') {\n' + branch + '}\n'; }; -Blockly.JavaScript['controls_for'] = function(block) { +JavaScript['controls_for'] = function(block) { // For loop. - const variable0 = Blockly.JavaScript.nameDB_.getName( + const variable0 = JavaScript.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const argument0 = Blockly.JavaScript.valueToCode(block, 'FROM', - Blockly.JavaScript.ORDER_ASSIGNMENT) || '0'; - const argument1 = Blockly.JavaScript.valueToCode(block, 'TO', - Blockly.JavaScript.ORDER_ASSIGNMENT) || '0'; - const increment = Blockly.JavaScript.valueToCode(block, 'BY', - Blockly.JavaScript.ORDER_ASSIGNMENT) || '1'; - let branch = Blockly.JavaScript.statementToCode(block, 'DO'); - branch = Blockly.JavaScript.addLoopTrap(branch, block); + const argument0 = JavaScript.valueToCode(block, 'FROM', + JavaScript.ORDER_ASSIGNMENT) || '0'; + const argument1 = JavaScript.valueToCode(block, 'TO', + JavaScript.ORDER_ASSIGNMENT) || '0'; + const increment = JavaScript.valueToCode(block, 'BY', + JavaScript.ORDER_ASSIGNMENT) || '1'; + let branch = JavaScript.statementToCode(block, 'DO'); + branch = JavaScript.addLoopTrap(branch, block); let code; if (Blockly.isNumber(argument0) && Blockly.isNumber(argument1) && Blockly.isNumber(increment)) { @@ -92,19 +94,19 @@ Blockly.JavaScript['controls_for'] = function(block) { // Cache non-trivial values to variables to prevent repeated look-ups. let startVar = argument0; if (!argument0.match(/^\w+$/) && !Blockly.isNumber(argument0)) { - startVar = Blockly.JavaScript.nameDB_.getDistinctName( + startVar = JavaScript.nameDB_.getDistinctName( variable0 + '_start', Blockly.VARIABLE_CATEGORY_NAME); code += 'var ' + startVar + ' = ' + argument0 + ';\n'; } let endVar = argument1; if (!argument1.match(/^\w+$/) && !Blockly.isNumber(argument1)) { - endVar = Blockly.JavaScript.nameDB_.getDistinctName( + endVar = JavaScript.nameDB_.getDistinctName( variable0 + '_end', Blockly.VARIABLE_CATEGORY_NAME); code += 'var ' + endVar + ' = ' + argument1 + ';\n'; } // Determine loop direction at start, in case one of the bounds // changes during loop execution. - const incVar = Blockly.JavaScript.nameDB_.getDistinctName( + const incVar = JavaScript.nameDB_.getDistinctName( variable0 + '_inc', Blockly.VARIABLE_CATEGORY_NAME); code += 'var ' + incVar + ' = '; if (Blockly.isNumber(increment)) { @@ -113,7 +115,7 @@ Blockly.JavaScript['controls_for'] = function(block) { code += 'Math.abs(' + increment + ');\n'; } code += 'if (' + startVar + ' > ' + endVar + ') {\n'; - code += Blockly.JavaScript.INDENT + incVar + ' = -' + incVar + ';\n'; + code += JavaScript.INDENT + incVar + ' = -' + incVar + ';\n'; code += '}\n'; code += 'for (' + variable0 + ' = ' + startVar + '; ' + incVar + ' >= 0 ? ' + @@ -125,52 +127,51 @@ Blockly.JavaScript['controls_for'] = function(block) { return code; }; -Blockly.JavaScript['controls_forEach'] = function(block) { +JavaScript['controls_forEach'] = function(block) { // For each loop. - const variable0 = Blockly.JavaScript.nameDB_.getName( + const variable0 = JavaScript.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const argument0 = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_ASSIGNMENT) || '[]'; - let branch = Blockly.JavaScript.statementToCode(block, 'DO'); - branch = Blockly.JavaScript.addLoopTrap(branch, block); + const argument0 = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_ASSIGNMENT) || '[]'; + let branch = JavaScript.statementToCode(block, 'DO'); + branch = JavaScript.addLoopTrap(branch, block); let code = ''; // Cache non-trivial values to variables to prevent repeated look-ups. let listVar = argument0; if (!argument0.match(/^\w+$/)) { - listVar = Blockly.JavaScript.nameDB_.getDistinctName( + listVar = JavaScript.nameDB_.getDistinctName( variable0 + '_list', Blockly.VARIABLE_CATEGORY_NAME); code += 'var ' + listVar + ' = ' + argument0 + ';\n'; } - const indexVar = Blockly.JavaScript.nameDB_.getDistinctName( + const indexVar = JavaScript.nameDB_.getDistinctName( variable0 + '_index', Blockly.VARIABLE_CATEGORY_NAME); - branch = Blockly.JavaScript.INDENT + variable0 + ' = ' + + branch = JavaScript.INDENT + variable0 + ' = ' + listVar + '[' + indexVar + '];\n' + branch; code += 'for (var ' + indexVar + ' in ' + listVar + ') {\n' + branch + '}\n'; return code; }; -Blockly.JavaScript['controls_flow_statements'] = function(block) { +JavaScript['controls_flow_statements'] = function(block) { // Flow statements: continue, break. let xfix = ''; - if (Blockly.JavaScript.STATEMENT_PREFIX) { + if (JavaScript.STATEMENT_PREFIX) { // Automatic prefix insertion is switched off for this block. Add manually. - xfix += Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_PREFIX, + xfix += JavaScript.injectId(JavaScript.STATEMENT_PREFIX, block); } - if (Blockly.JavaScript.STATEMENT_SUFFIX) { + if (JavaScript.STATEMENT_SUFFIX) { // Inject any statement suffix here since the regular one at the end // will not get executed if the break/continue is triggered. - xfix += Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_SUFFIX, + xfix += JavaScript.injectId(JavaScript.STATEMENT_SUFFIX, block); } - if (Blockly.JavaScript.STATEMENT_PREFIX) { - const loop = Blockly.Constants.Loops - .CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); + if (JavaScript.STATEMENT_PREFIX) { + const loop = Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); if (loop && !loop.suppressPrefixSuffix) { // Inject loop's statement prefix here since the regular one at the end // of the loop will not get executed if 'continue' is triggered. // In the case of 'break', a prefix is needed due to the loop's suffix. - xfix += Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_PREFIX, + xfix += JavaScript.injectId(JavaScript.STATEMENT_PREFIX, loop); } } diff --git a/generators/javascript/math.js b/generators/javascript/math.js index 2e3828cacd2..c1eacb2a9ca 100644 --- a/generators/javascript/math.js +++ b/generators/javascript/math.js @@ -9,65 +9,66 @@ */ 'use strict'; -goog.provide('Blockly.JavaScript.math'); +goog.module('Blockly.JavaScript.math'); -goog.require('Blockly.JavaScript'); +const Blockly = goog.require('Blockly'); +const JavaScript = goog.require('Blockly.JavaScript'); -Blockly.JavaScript['math_number'] = function(block) { +JavaScript['math_number'] = function(block) { // Numeric value. const code = Number(block.getFieldValue('NUM')); - const order = code >= 0 ? Blockly.JavaScript.ORDER_ATOMIC : - Blockly.JavaScript.ORDER_UNARY_NEGATION; + const order = code >= 0 ? JavaScript.ORDER_ATOMIC : + JavaScript.ORDER_UNARY_NEGATION; return [code, order]; }; -Blockly.JavaScript['math_arithmetic'] = function(block) { +JavaScript['math_arithmetic'] = function(block) { // Basic arithmetic operators, and power. const OPERATORS = { - 'ADD': [' + ', Blockly.JavaScript.ORDER_ADDITION], - 'MINUS': [' - ', Blockly.JavaScript.ORDER_SUBTRACTION], - 'MULTIPLY': [' * ', Blockly.JavaScript.ORDER_MULTIPLICATION], - 'DIVIDE': [' / ', Blockly.JavaScript.ORDER_DIVISION], - 'POWER': [null, Blockly.JavaScript.ORDER_NONE] // Handle power separately. + 'ADD': [' + ', JavaScript.ORDER_ADDITION], + 'MINUS': [' - ', JavaScript.ORDER_SUBTRACTION], + 'MULTIPLY': [' * ', JavaScript.ORDER_MULTIPLICATION], + 'DIVIDE': [' / ', JavaScript.ORDER_DIVISION], + 'POWER': [null, JavaScript.ORDER_NONE] // Handle power separately. }; const tuple = OPERATORS[block.getFieldValue('OP')]; const operator = tuple[0]; const order = tuple[1]; - const argument0 = Blockly.JavaScript.valueToCode(block, 'A', order) || '0'; - const argument1 = Blockly.JavaScript.valueToCode(block, 'B', order) || '0'; + const argument0 = JavaScript.valueToCode(block, 'A', order) || '0'; + const argument1 = JavaScript.valueToCode(block, 'B', order) || '0'; let code; // Power in JavaScript requires a special case since it has no operator. if (!operator) { code = 'Math.pow(' + argument0 + ', ' + argument1 + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } code = argument0 + operator + argument1; return [code, order]; }; -Blockly.JavaScript['math_single'] = function(block) { +JavaScript['math_single'] = function(block) { // Math operators with single operand. const operator = block.getFieldValue('OP'); let code; let arg; if (operator === 'NEG') { // Negation is a special case given its different operator precedence. - arg = Blockly.JavaScript.valueToCode(block, 'NUM', - Blockly.JavaScript.ORDER_UNARY_NEGATION) || '0'; + arg = JavaScript.valueToCode(block, 'NUM', + JavaScript.ORDER_UNARY_NEGATION) || '0'; if (arg[0] === '-') { // --3 is not legal in JS. arg = ' ' + arg; } code = '-' + arg; - return [code, Blockly.JavaScript.ORDER_UNARY_NEGATION]; + return [code, JavaScript.ORDER_UNARY_NEGATION]; } if (operator === 'SIN' || operator === 'COS' || operator === 'TAN') { - arg = Blockly.JavaScript.valueToCode(block, 'NUM', - Blockly.JavaScript.ORDER_DIVISION) || '0'; + arg = JavaScript.valueToCode(block, 'NUM', + JavaScript.ORDER_DIVISION) || '0'; } else { - arg = Blockly.JavaScript.valueToCode(block, 'NUM', - Blockly.JavaScript.ORDER_NONE) || '0'; + arg = JavaScript.valueToCode(block, 'NUM', + JavaScript.ORDER_NONE) || '0'; } // First, handle cases which generate values that don't need parentheses // wrapping the code. @@ -107,7 +108,7 @@ Blockly.JavaScript['math_single'] = function(block) { break; } if (code) { - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } // Second, handle cases which generate values that may need parentheses // wrapping the code. @@ -127,35 +128,35 @@ Blockly.JavaScript['math_single'] = function(block) { default: throw Error('Unknown math operator: ' + operator); } - return [code, Blockly.JavaScript.ORDER_DIVISION]; + return [code, JavaScript.ORDER_DIVISION]; }; -Blockly.JavaScript['math_constant'] = function(block) { +JavaScript['math_constant'] = function(block) { // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY. const CONSTANTS = { - 'PI': ['Math.PI', Blockly.JavaScript.ORDER_MEMBER], - 'E': ['Math.E', Blockly.JavaScript.ORDER_MEMBER], + 'PI': ['Math.PI', JavaScript.ORDER_MEMBER], + 'E': ['Math.E', JavaScript.ORDER_MEMBER], 'GOLDEN_RATIO': - ['(1 + Math.sqrt(5)) / 2', Blockly.JavaScript.ORDER_DIVISION], - 'SQRT2': ['Math.SQRT2', Blockly.JavaScript.ORDER_MEMBER], - 'SQRT1_2': ['Math.SQRT1_2', Blockly.JavaScript.ORDER_MEMBER], - 'INFINITY': ['Infinity', Blockly.JavaScript.ORDER_ATOMIC] + ['(1 + Math.sqrt(5)) / 2', JavaScript.ORDER_DIVISION], + 'SQRT2': ['Math.SQRT2', JavaScript.ORDER_MEMBER], + 'SQRT1_2': ['Math.SQRT1_2', JavaScript.ORDER_MEMBER], + 'INFINITY': ['Infinity', JavaScript.ORDER_ATOMIC] }; return CONSTANTS[block.getFieldValue('CONSTANT')]; }; -Blockly.JavaScript['math_number_property'] = function(block) { +JavaScript['math_number_property'] = function(block) { // Check if a number is even, odd, prime, whole, positive, or negative // or if it is divisible by certain number. Returns true or false. - const number_to_check = Blockly.JavaScript.valueToCode(block, 'NUMBER_TO_CHECK', - Blockly.JavaScript.ORDER_MODULUS) || '0'; + const number_to_check = JavaScript.valueToCode(block, 'NUMBER_TO_CHECK', + JavaScript.ORDER_MODULUS) || '0'; const dropdown_property = block.getFieldValue('PROPERTY'); let code; if (dropdown_property === 'PRIME') { // Prime is a special case as it is not a one-liner test. - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'mathIsPrime', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(n) {', + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(n) {', ' // https://en.wikipedia.org/wiki/Primality_test#Naive_methods', ' if (n == 2 || n == 3) {', ' return true;', @@ -175,7 +176,7 @@ Blockly.JavaScript['math_number_property'] = function(block) { ' return true;', '}']); code = functionName + '(' + number_to_check + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } switch (dropdown_property) { case 'EVEN': @@ -194,70 +195,70 @@ Blockly.JavaScript['math_number_property'] = function(block) { code = number_to_check + ' < 0'; break; case 'DIVISIBLE_BY': { - const divisor = Blockly.JavaScript.valueToCode(block, 'DIVISOR', - Blockly.JavaScript.ORDER_MODULUS) || '0'; + const divisor = JavaScript.valueToCode(block, 'DIVISOR', + JavaScript.ORDER_MODULUS) || '0'; code = number_to_check + ' % ' + divisor + ' === 0'; break; } } - return [code, Blockly.JavaScript.ORDER_EQUALITY]; + return [code, JavaScript.ORDER_EQUALITY]; }; -Blockly.JavaScript['math_change'] = function(block) { +JavaScript['math_change'] = function(block) { // Add to a variable in place. - const argument0 = Blockly.JavaScript.valueToCode(block, 'DELTA', - Blockly.JavaScript.ORDER_ADDITION) || '0'; - const varName = Blockly.JavaScript.nameDB_.getName( + const argument0 = JavaScript.valueToCode(block, 'DELTA', + JavaScript.ORDER_ADDITION) || '0'; + const varName = JavaScript.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); return varName + ' = (typeof ' + varName + ' === \'number\' ? ' + varName + ' : 0) + ' + argument0 + ';\n'; }; // Rounding functions have a single operand. -Blockly.JavaScript['math_round'] = Blockly.JavaScript['math_single']; +JavaScript['math_round'] = JavaScript['math_single']; // Trigonometry functions have a single operand. -Blockly.JavaScript['math_trig'] = Blockly.JavaScript['math_single']; +JavaScript['math_trig'] = JavaScript['math_single']; -Blockly.JavaScript['math_on_list'] = function(block) { +JavaScript['math_on_list'] = function(block) { // Math functions for lists. const func = block.getFieldValue('OP'); let list; let code; switch (func) { case 'SUM': - list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_MEMBER) || '[]'; + list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_MEMBER) || '[]'; code = list + '.reduce(function(x, y) {return x + y;})'; break; case 'MIN': - list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_NONE) || '[]'; + list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_NONE) || '[]'; code = 'Math.min.apply(null, ' + list + ')'; break; case 'MAX': - list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_NONE) || '[]'; + list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_NONE) || '[]'; code = 'Math.max.apply(null, ' + list + ')'; break; case 'AVERAGE': { // mathMean([null,null,1,3]) === 2.0. - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'mathMean', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(myList) {', ' return myList.reduce(function(x, y) {return x + y;}) / ' + 'myList.length;', '}']); - list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_NONE) || '[]'; + list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_NONE) || '[]'; code = functionName + '(' + list + ')'; break; } case 'MEDIAN': { // mathMedian([null,null,1,3]) === 2.0. - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'mathMedian', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(myList) {', ' var localList = myList.filter(function (x) ' + '{return typeof x === \'number\';});', @@ -270,8 +271,8 @@ Blockly.JavaScript['math_on_list'] = function(block) { ' return localList[(localList.length - 1) / 2];', ' }', '}']); - list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_NONE) || '[]'; + list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_NONE) || '[]'; code = functionName + '(' + list + ')'; break; } @@ -279,9 +280,9 @@ Blockly.JavaScript['math_on_list'] = function(block) { // 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]. - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'mathModes', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(values) {', ' var modes = [];', ' var counts = [];', @@ -310,15 +311,15 @@ Blockly.JavaScript['math_on_list'] = function(block) { ' }', ' return modes;', '}']); - list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_NONE) || '[]'; + list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_NONE) || '[]'; code = functionName + '(' + list + ')'; break; } case 'STD_DEV': { - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'mathStandardDeviation', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(numbers) {', ' var n = numbers.length;', ' if (!n) return null;', @@ -330,62 +331,62 @@ Blockly.JavaScript['math_on_list'] = function(block) { ' variance = variance / n;', ' return Math.sqrt(variance);', '}']); - list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_NONE) || '[]'; + list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_NONE) || '[]'; code = functionName + '(' + list + ')'; break; } case 'RANDOM': { - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'mathRandomList', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(list) {', ' var x = Math.floor(Math.random() * list.length);', ' return list[x];', '}']); - list = Blockly.JavaScript.valueToCode(block, 'LIST', - Blockly.JavaScript.ORDER_NONE) || '[]'; + list = JavaScript.valueToCode(block, 'LIST', + JavaScript.ORDER_NONE) || '[]'; code = functionName + '(' + list + ')'; break; } default: throw Error('Unknown operator: ' + func); } - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['math_modulo'] = function(block) { +JavaScript['math_modulo'] = function(block) { // Remainder computation. - const argument0 = Blockly.JavaScript.valueToCode(block, 'DIVIDEND', - Blockly.JavaScript.ORDER_MODULUS) || '0'; - const argument1 = Blockly.JavaScript.valueToCode(block, 'DIVISOR', - Blockly.JavaScript.ORDER_MODULUS) || '0'; + const argument0 = JavaScript.valueToCode(block, 'DIVIDEND', + JavaScript.ORDER_MODULUS) || '0'; + const argument1 = JavaScript.valueToCode(block, 'DIVISOR', + JavaScript.ORDER_MODULUS) || '0'; const code = argument0 + ' % ' + argument1; - return [code, Blockly.JavaScript.ORDER_MODULUS]; + return [code, JavaScript.ORDER_MODULUS]; }; -Blockly.JavaScript['math_constrain'] = function(block) { +JavaScript['math_constrain'] = function(block) { // Constrain a number between two limits. - const argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE', - Blockly.JavaScript.ORDER_NONE) || '0'; - const argument1 = Blockly.JavaScript.valueToCode(block, 'LOW', - Blockly.JavaScript.ORDER_NONE) || '0'; - const argument2 = Blockly.JavaScript.valueToCode(block, 'HIGH', - Blockly.JavaScript.ORDER_NONE) || 'Infinity'; + const argument0 = JavaScript.valueToCode(block, 'VALUE', + JavaScript.ORDER_NONE) || '0'; + const argument1 = JavaScript.valueToCode(block, 'LOW', + JavaScript.ORDER_NONE) || '0'; + const argument2 = JavaScript.valueToCode(block, 'HIGH', + JavaScript.ORDER_NONE) || 'Infinity'; const code = 'Math.min(Math.max(' + argument0 + ', ' + argument1 + '), ' + argument2 + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['math_random_int'] = function(block) { +JavaScript['math_random_int'] = function(block) { // Random integer between [X] and [Y]. - const argument0 = Blockly.JavaScript.valueToCode(block, 'FROM', - Blockly.JavaScript.ORDER_NONE) || '0'; - const argument1 = Blockly.JavaScript.valueToCode(block, 'TO', - Blockly.JavaScript.ORDER_NONE) || '0'; - const functionName = Blockly.JavaScript.provideFunction_( + const argument0 = JavaScript.valueToCode(block, 'FROM', + JavaScript.ORDER_NONE) || '0'; + const argument1 = JavaScript.valueToCode(block, 'TO', + JavaScript.ORDER_NONE) || '0'; + const functionName = JavaScript.provideFunction_( 'mathRandomInt', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(a, b) {', ' if (a > b) {', ' // Swap a and b to ensure a is smaller.', @@ -396,20 +397,20 @@ Blockly.JavaScript['math_random_int'] = function(block) { ' return Math.floor(Math.random() * (b - a + 1) + a);', '}']); const code = functionName + '(' + argument0 + ', ' + argument1 + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['math_random_float'] = function(block) { +JavaScript['math_random_float'] = function(block) { // Random fraction between 0 and 1. - return ['Math.random()', Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return ['Math.random()', JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['math_atan2'] = function(block) { +JavaScript['math_atan2'] = function(block) { // Arctangent of point (X, Y) in degrees from -180 to 180. - const argument0 = Blockly.JavaScript.valueToCode(block, 'X', - Blockly.JavaScript.ORDER_NONE) || '0'; - const argument1 = Blockly.JavaScript.valueToCode(block, 'Y', - Blockly.JavaScript.ORDER_NONE) || '0'; + const argument0 = JavaScript.valueToCode(block, 'X', + JavaScript.ORDER_NONE) || '0'; + const argument1 = JavaScript.valueToCode(block, 'Y', + JavaScript.ORDER_NONE) || '0'; return ['Math.atan2(' + argument1 + ', ' + argument0 + ') / Math.PI * 180', - Blockly.JavaScript.ORDER_DIVISION]; + JavaScript.ORDER_DIVISION]; }; diff --git a/generators/javascript/procedures.js b/generators/javascript/procedures.js index a95fe054698..ef7eb1f559d 100644 --- a/generators/javascript/procedures.js +++ b/generators/javascript/procedures.js @@ -9,103 +9,104 @@ */ 'use strict'; -goog.provide('Blockly.JavaScript.procedures'); +goog.module('Blockly.JavaScript.procedures'); -goog.require('Blockly.JavaScript'); +const Blockly = goog.require('Blockly'); +const JavaScript = goog.require('Blockly.JavaScript'); -Blockly.JavaScript['procedures_defreturn'] = function(block) { +JavaScript['procedures_defreturn'] = function(block) { // Define a procedure with a return value. - const funcName = Blockly.JavaScript.nameDB_.getName( + const funcName = JavaScript.nameDB_.getName( block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME); let xfix1 = ''; - if (Blockly.JavaScript.STATEMENT_PREFIX) { - xfix1 += Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_PREFIX, + if (JavaScript.STATEMENT_PREFIX) { + xfix1 += JavaScript.injectId(JavaScript.STATEMENT_PREFIX, block); } - if (Blockly.JavaScript.STATEMENT_SUFFIX) { - xfix1 += Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_SUFFIX, + if (JavaScript.STATEMENT_SUFFIX) { + xfix1 += JavaScript.injectId(JavaScript.STATEMENT_SUFFIX, block); } if (xfix1) { - xfix1 = Blockly.JavaScript.prefixLines(xfix1, Blockly.JavaScript.INDENT); + xfix1 = JavaScript.prefixLines(xfix1, JavaScript.INDENT); } let loopTrap = ''; - if (Blockly.JavaScript.INFINITE_LOOP_TRAP) { - loopTrap = Blockly.JavaScript.prefixLines( - Blockly.JavaScript.injectId(Blockly.JavaScript.INFINITE_LOOP_TRAP, - block), Blockly.JavaScript.INDENT); + if (JavaScript.INFINITE_LOOP_TRAP) { + loopTrap = JavaScript.prefixLines( + JavaScript.injectId(JavaScript.INFINITE_LOOP_TRAP, + block), JavaScript.INDENT); } - const branch = Blockly.JavaScript.statementToCode(block, 'STACK'); - let returnValue = Blockly.JavaScript.valueToCode(block, 'RETURN', - Blockly.JavaScript.ORDER_NONE) || ''; + const branch = JavaScript.statementToCode(block, 'STACK'); + let returnValue = JavaScript.valueToCode(block, 'RETURN', + JavaScript.ORDER_NONE) || ''; let xfix2 = ''; if (branch && returnValue) { // After executing the function body, revisit this block for the return. xfix2 = xfix1; } if (returnValue) { - returnValue = Blockly.JavaScript.INDENT + 'return ' + returnValue + ';\n'; + returnValue = JavaScript.INDENT + 'return ' + returnValue + ';\n'; } const args = []; const variables = block.getVars(); for (let i = 0; i < variables.length; i++) { - args[i] = Blockly.JavaScript.nameDB_.getName(variables[i], + args[i] = JavaScript.nameDB_.getName(variables[i], Blockly.VARIABLE_CATEGORY_NAME); } let code = 'function ' + funcName + '(' + args.join(', ') + ') {\n' + xfix1 + loopTrap + branch + xfix2 + returnValue + '}'; - code = Blockly.JavaScript.scrub_(block, code); + code = JavaScript.scrub_(block, code); // Add % so as not to collide with helper functions in definitions list. - Blockly.JavaScript.definitions_['%' + funcName] = code; + JavaScript.definitions_['%' + funcName] = code; return null; }; // Defining a procedure without a return value uses the same generator as // a procedure with a return value. -Blockly.JavaScript['procedures_defnoreturn'] = - Blockly.JavaScript['procedures_defreturn']; +JavaScript['procedures_defnoreturn'] = + JavaScript['procedures_defreturn']; -Blockly.JavaScript['procedures_callreturn'] = function(block) { +JavaScript['procedures_callreturn'] = function(block) { // Call a procedure with a return value. - const funcName = Blockly.JavaScript.nameDB_.getName( + const funcName = JavaScript.nameDB_.getName( block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME); const args = []; const variables = block.getVars(); for (let i = 0; i < variables.length; i++) { - args[i] = Blockly.JavaScript.valueToCode(block, 'ARG' + i, - Blockly.JavaScript.ORDER_NONE) || 'null'; + args[i] = JavaScript.valueToCode(block, 'ARG' + i, + JavaScript.ORDER_NONE) || 'null'; } const code = funcName + '(' + args.join(', ') + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['procedures_callnoreturn'] = function(block) { +JavaScript['procedures_callnoreturn'] = function(block) { // Call a procedure with no return value. // Generated code is for a function call as a statement is the same as a // function call as a value, with the addition of line ending. - const tuple = Blockly.JavaScript['procedures_callreturn'](block); + const tuple = JavaScript['procedures_callreturn'](block); return tuple[0] + ';\n'; }; -Blockly.JavaScript['procedures_ifreturn'] = function(block) { +JavaScript['procedures_ifreturn'] = function(block) { // Conditionally return value from a procedure. - const condition = Blockly.JavaScript.valueToCode(block, 'CONDITION', - Blockly.JavaScript.ORDER_NONE) || 'false'; + const condition = JavaScript.valueToCode(block, 'CONDITION', + JavaScript.ORDER_NONE) || 'false'; let code = 'if (' + condition + ') {\n'; - if (Blockly.JavaScript.STATEMENT_SUFFIX) { + if (JavaScript.STATEMENT_SUFFIX) { // Inject any statement suffix here since the regular one at the end // will not get executed if the return is triggered. - code += Blockly.JavaScript.prefixLines( - Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_SUFFIX, block), - Blockly.JavaScript.INDENT); + code += JavaScript.prefixLines( + JavaScript.injectId(JavaScript.STATEMENT_SUFFIX, block), + JavaScript.INDENT); } if (block.hasReturnValue_) { - const value = Blockly.JavaScript.valueToCode(block, 'VALUE', - Blockly.JavaScript.ORDER_NONE) || 'null'; - code += Blockly.JavaScript.INDENT + 'return ' + value + ';\n'; + const value = JavaScript.valueToCode(block, 'VALUE', + JavaScript.ORDER_NONE) || 'null'; + code += JavaScript.INDENT + 'return ' + value + ';\n'; } else { - code += Blockly.JavaScript.INDENT + 'return;\n'; + code += JavaScript.INDENT + 'return;\n'; } code += '}\n'; return code; diff --git a/generators/javascript/text.js b/generators/javascript/text.js index f9e203fc254..406e61eeabc 100644 --- a/generators/javascript/text.js +++ b/generators/javascript/text.js @@ -9,156 +9,155 @@ */ 'use strict'; -goog.provide('Blockly.JavaScript.texts'); +goog.module('Blockly.JavaScript.texts'); -goog.require('Blockly.JavaScript'); +const Blockly = goog.require('Blockly'); +const JavaScript = goog.require('Blockly.JavaScript'); -Blockly.JavaScript['text'] = function(block) { - // Text value. - const code = Blockly.JavaScript.quote_(block.getFieldValue('TEXT')); - return [code, Blockly.JavaScript.ORDER_ATOMIC]; -}; - -Blockly.JavaScript['text_multiline'] = function(block) { - // Text value. - const code = Blockly.JavaScript.multiline_quote_(block.getFieldValue('TEXT')); - const order = code.indexOf('+') !== -1 ? Blockly.JavaScript.ORDER_ADDITION : - Blockly.JavaScript.ORDER_ATOMIC; - return [code, order]; -}; +/** + * Regular expression to detect a single-quoted string literal. + */ +const strRegExp = /^\s*'([^']|\\')*'\s*$/; /** * Enclose the provided value in 'String(...)' function. * Leave string literals alone. * @param {string} value Code evaluating to a value. - * @return {Array} Array containing code evaluating to a string and - * the order of the returned code.[string, number] - * @private + * @return {Array} Array containing code evaluating to a string + * and the order of the returned code.[string, number] */ -Blockly.JavaScript.text.forceString_ = function(value) { - if (Blockly.JavaScript.text.forceString_.strRegExp.test(value)) { - return [value, Blockly.JavaScript.ORDER_ATOMIC]; +const forceString = function(value) { + if (strRegExp.test(value)) { + return [value, JavaScript.ORDER_ATOMIC]; } - return ['String(' + value + ')', Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return ['String(' + value + ')', JavaScript.ORDER_FUNCTION_CALL]; }; -/** - * Regular expression to detect a single-quoted string literal. - */ -Blockly.JavaScript.text.forceString_.strRegExp = /^\s*'([^']|\\')*'\s*$/; +JavaScript['text'] = function(block) { + // Text value. + const code = JavaScript.quote_(block.getFieldValue('TEXT')); + return [code, JavaScript.ORDER_ATOMIC]; +}; + +JavaScript['text_multiline'] = function(block) { + // Text value. + const code = JavaScript.multiline_quote_(block.getFieldValue('TEXT')); + const order = code.indexOf('+') !== -1 ? JavaScript.ORDER_ADDITION : + JavaScript.ORDER_ATOMIC; + return [code, order]; +}; -Blockly.JavaScript['text_join'] = function(block) { +JavaScript['text_join'] = function(block) { // Create a string made up of any number of elements of any type. switch (block.itemCount_) { case 0: - return ['\'\'', Blockly.JavaScript.ORDER_ATOMIC]; + return ['\'\'', JavaScript.ORDER_ATOMIC]; case 1: { - const element = Blockly.JavaScript.valueToCode(block, 'ADD0', - Blockly.JavaScript.ORDER_NONE) || '\'\''; - const codeAndOrder = Blockly.JavaScript.text.forceString_(element); + const element = JavaScript.valueToCode(block, 'ADD0', + JavaScript.ORDER_NONE) || '\'\''; + const codeAndOrder = forceString(element); return codeAndOrder; } case 2: { - const element0 = Blockly.JavaScript.valueToCode(block, 'ADD0', - Blockly.JavaScript.ORDER_NONE) || '\'\''; - const element1 = Blockly.JavaScript.valueToCode(block, 'ADD1', - Blockly.JavaScript.ORDER_NONE) || '\'\''; - const code = Blockly.JavaScript.text.forceString_(element0)[0] + - ' + ' + Blockly.JavaScript.text.forceString_(element1)[0]; - return [code, Blockly.JavaScript.ORDER_ADDITION]; + const element0 = JavaScript.valueToCode(block, 'ADD0', + JavaScript.ORDER_NONE) || '\'\''; + const element1 = JavaScript.valueToCode(block, 'ADD1', + JavaScript.ORDER_NONE) || '\'\''; + const code = forceString(element0)[0] + + ' + ' + forceString(element1)[0]; + return [code, JavaScript.ORDER_ADDITION]; } default: { const elements = new Array(block.itemCount_); for (let i = 0; i < block.itemCount_; i++) { - elements[i] = Blockly.JavaScript.valueToCode(block, 'ADD' + i, - Blockly.JavaScript.ORDER_NONE) || '\'\''; + elements[i] = JavaScript.valueToCode(block, 'ADD' + i, + JavaScript.ORDER_NONE) || '\'\''; } const code = '[' + elements.join(',') + '].join(\'\')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } } }; -Blockly.JavaScript['text_append'] = function(block) { +JavaScript['text_append'] = function(block) { // Append to a variable in place. - const varName = Blockly.JavaScript.nameDB_.getName( + const varName = JavaScript.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const value = Blockly.JavaScript.valueToCode(block, 'TEXT', - Blockly.JavaScript.ORDER_NONE) || '\'\''; - const code = varName + ' += ' + - Blockly.JavaScript.text.forceString_(value)[0] + ';\n'; + const value = JavaScript.valueToCode(block, 'TEXT', + JavaScript.ORDER_NONE) || '\'\''; + const code = varName + ' += ' + forceString(value)[0] + ';\n'; return code; }; -Blockly.JavaScript['text_length'] = function(block) { +JavaScript['text_length'] = function(block) { // String or array length. - const text = Blockly.JavaScript.valueToCode(block, 'VALUE', - Blockly.JavaScript.ORDER_MEMBER) || '\'\''; - return [text + '.length', Blockly.JavaScript.ORDER_MEMBER]; + const text = JavaScript.valueToCode(block, 'VALUE', + JavaScript.ORDER_MEMBER) || '\'\''; + return [text + '.length', JavaScript.ORDER_MEMBER]; }; -Blockly.JavaScript['text_isEmpty'] = function(block) { +JavaScript['text_isEmpty'] = function(block) { // Is the string null or array empty? - const text = Blockly.JavaScript.valueToCode(block, 'VALUE', - Blockly.JavaScript.ORDER_MEMBER) || '\'\''; - return ['!' + text + '.length', Blockly.JavaScript.ORDER_LOGICAL_NOT]; + const text = JavaScript.valueToCode(block, 'VALUE', + JavaScript.ORDER_MEMBER) || '\'\''; + return ['!' + text + '.length', JavaScript.ORDER_LOGICAL_NOT]; }; -Blockly.JavaScript['text_indexOf'] = function(block) { +JavaScript['text_indexOf'] = function(block) { // Search the text for a substring. const operator = block.getFieldValue('END') === 'FIRST' ? 'indexOf' : 'lastIndexOf'; - const substring = Blockly.JavaScript.valueToCode(block, 'FIND', - Blockly.JavaScript.ORDER_NONE) || '\'\''; - const text = Blockly.JavaScript.valueToCode(block, 'VALUE', - Blockly.JavaScript.ORDER_MEMBER) || '\'\''; + const substring = JavaScript.valueToCode(block, 'FIND', + JavaScript.ORDER_NONE) || '\'\''; + const text = JavaScript.valueToCode(block, 'VALUE', + JavaScript.ORDER_MEMBER) || '\'\''; const code = text + '.' + operator + '(' + substring + ')'; // Adjust index if using one-based indices. if (block.workspace.options.oneBasedIndex) { - return [code + ' + 1', Blockly.JavaScript.ORDER_ADDITION]; + return [code + ' + 1', JavaScript.ORDER_ADDITION]; } - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['text_charAt'] = function(block) { +JavaScript['text_charAt'] = function(block) { // Get letter at index. // Note: Until January 2013 this block did not have the WHERE input. const where = block.getFieldValue('WHERE') || 'FROM_START'; - const textOrder = (where === 'RANDOM') ? Blockly.JavaScript.ORDER_NONE : - Blockly.JavaScript.ORDER_MEMBER; - const text = Blockly.JavaScript.valueToCode(block, 'VALUE', + const textOrder = (where === 'RANDOM') ? JavaScript.ORDER_NONE : + JavaScript.ORDER_MEMBER; + const text = JavaScript.valueToCode(block, 'VALUE', textOrder) || '\'\''; switch (where) { case 'FIRST': { const code = text + '.charAt(0)'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } case 'LAST': { const code = text + '.slice(-1)'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } case 'FROM_START': { - const at = Blockly.JavaScript.getAdjusted(block, 'AT'); + const at = JavaScript.getAdjusted(block, 'AT'); // Adjust index if using one-based indices. const code = text + '.charAt(' + at + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } case 'FROM_END': { - const at = Blockly.JavaScript.getAdjusted(block, 'AT', 1, true); + const at = JavaScript.getAdjusted(block, 'AT', 1, true); const code = text + '.slice(' + at + ').charAt(0)'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } case 'RANDOM': { - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'textRandomLetter', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(text) {', ' var x = Math.floor(Math.random() * text.length);', ' return text[x];', '}']); const code = functionName + '(' + text + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; } } throw Error('Unhandled option (text_charAt).'); @@ -170,9 +169,8 @@ Blockly.JavaScript['text_charAt'] = function(block) { * @param {string} where The method of indexing, selected by dropdown in Blockly * @param {string=} opt_at The optional offset when indexing from start/end. * @return {string|undefined} Index expression. - * @private */ -Blockly.JavaScript.text.getIndex_ = function(stringName, where, opt_at) { +const getIndex = function(stringName, where, opt_at) { if (where === 'FIRST') { return '0'; } else if (where === 'FROM_END') { @@ -184,31 +182,31 @@ Blockly.JavaScript.text.getIndex_ = function(stringName, where, opt_at) { } }; -Blockly.JavaScript['text_getSubstring'] = function(block) { +JavaScript['text_getSubstring'] = function(block) { // Get substring. const where1 = block.getFieldValue('WHERE1'); const where2 = block.getFieldValue('WHERE2'); const requiresLengthCall = (where1 !== 'FROM_END' && where1 !== 'LAST' && where2 !== 'FROM_END' && where2 !== 'LAST'); - const textOrder = requiresLengthCall ? Blockly.JavaScript.ORDER_MEMBER : - Blockly.JavaScript.ORDER_NONE; - const text = Blockly.JavaScript.valueToCode(block, 'STRING', + const textOrder = requiresLengthCall ? JavaScript.ORDER_MEMBER : + JavaScript.ORDER_NONE; + const text = JavaScript.valueToCode(block, 'STRING', textOrder) || '\'\''; let code; if (where1 === 'FIRST' && where2 === 'LAST') { code = text; - return [code, Blockly.JavaScript.ORDER_NONE]; + return [code, JavaScript.ORDER_NONE]; } else if (text.match(/^'?\w+'?$/) || requiresLengthCall) { // If the text is a variable or literal or doesn't require a call for // length, don't generate a helper function. let at1; switch (where1) { case 'FROM_START': - at1 = Blockly.JavaScript.getAdjusted(block, 'AT1'); + at1 = JavaScript.getAdjusted(block, 'AT1'); break; case 'FROM_END': - at1 = Blockly.JavaScript.getAdjusted(block, 'AT1', 1, false, - Blockly.JavaScript.ORDER_SUBTRACTION); + at1 = JavaScript.getAdjusted(block, 'AT1', 1, false, + JavaScript.ORDER_SUBTRACTION); at1 = text + '.length - ' + at1; break; case 'FIRST': @@ -220,11 +218,11 @@ Blockly.JavaScript['text_getSubstring'] = function(block) { let at2; switch (where2) { case 'FROM_START': - at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 1); + at2 = JavaScript.getAdjusted(block, 'AT2', 1); break; case 'FROM_END': - at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 0, false, - Blockly.JavaScript.ORDER_SUBTRACTION); + at2 = JavaScript.getAdjusted(block, 'AT2', 0, false, + JavaScript.ORDER_SUBTRACTION); at2 = text + '.length - ' + at2; break; case 'LAST': @@ -235,22 +233,21 @@ Blockly.JavaScript['text_getSubstring'] = function(block) { } code = text + '.slice(' + at1 + ', ' + at2 + ')'; } else { - const at1 = Blockly.JavaScript.getAdjusted(block, 'AT1'); - const at2 = Blockly.JavaScript.getAdjusted(block, 'AT2'); - const getIndex_ = Blockly.JavaScript.text.getIndex_; + const at1 = JavaScript.getAdjusted(block, 'AT1'); + const at2 = JavaScript.getAdjusted(block, 'AT2'); const wherePascalCase = {'FIRST': 'First', 'LAST': 'Last', 'FROM_START': 'FromStart', 'FROM_END': 'FromEnd'}; - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'subsequence' + wherePascalCase[where1] + wherePascalCase[where2], - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(sequence' + // The value for 'FROM_END' and'FROM_START' depends on `at` so // we add it as a parameter. ((where1 === 'FROM_END' || where1 === 'FROM_START') ? ', at1' : '') + ((where2 === 'FROM_END' || where2 === 'FROM_START') ? ', at2' : '') + ') {', - ' var start = ' + getIndex_('sequence', where1, 'at1') + ';', - ' var end = ' + getIndex_('sequence', where2, 'at2') + ' + 1;', + ' var start = ' + getIndex('sequence', where1, 'at1') + ';', + ' var end = ' + getIndex('sequence', where2, 'at2') + ' + 1;', ' return sequence.slice(start, end);', '}']); code = functionName + '(' + text + @@ -260,10 +257,10 @@ Blockly.JavaScript['text_getSubstring'] = function(block) { ((where2 === 'FROM_END' || where2 === 'FROM_START') ? ', ' + at2 : '') + ')'; } - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['text_changeCase'] = function(block) { +JavaScript['text_changeCase'] = function(block) { // Change capitalization. const OPERATORS = { 'UPPERCASE': '.toUpperCase()', @@ -271,9 +268,9 @@ Blockly.JavaScript['text_changeCase'] = function(block) { 'TITLECASE': null }; const operator = OPERATORS[block.getFieldValue('CASE')]; - const textOrder = operator ? Blockly.JavaScript.ORDER_MEMBER : - Blockly.JavaScript.ORDER_NONE; - const text = Blockly.JavaScript.valueToCode(block, 'TEXT', + const textOrder = operator ? JavaScript.ORDER_MEMBER : + JavaScript.ORDER_NONE; + const text = JavaScript.valueToCode(block, 'TEXT', textOrder) || '\'\''; let code; if (operator) { @@ -281,9 +278,9 @@ Blockly.JavaScript['text_changeCase'] = function(block) { code = text + operator; } else { // Title case is not a native JavaScript function. Define one. - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'textToTitleCase', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(str) {', ' return str.replace(/\\S+/g,', ' function(txt) {return txt[0].toUpperCase() + ' + @@ -291,10 +288,10 @@ Blockly.JavaScript['text_changeCase'] = function(block) { '}']); code = functionName + '(' + text + ')'; } - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['text_trim'] = function(block) { +JavaScript['text_trim'] = function(block) { // Trim spaces. const OPERATORS = { 'LEFT': ".replace(/^[\\s\\xa0]+/, '')", @@ -302,47 +299,47 @@ Blockly.JavaScript['text_trim'] = function(block) { 'BOTH': '.trim()' }; const operator = OPERATORS[block.getFieldValue('MODE')]; - const text = Blockly.JavaScript.valueToCode(block, 'TEXT', - Blockly.JavaScript.ORDER_MEMBER) || '\'\''; - return [text + operator, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + const text = JavaScript.valueToCode(block, 'TEXT', + JavaScript.ORDER_MEMBER) || '\'\''; + return [text + operator, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['text_print'] = function(block) { +JavaScript['text_print'] = function(block) { // Print statement. - const msg = Blockly.JavaScript.valueToCode(block, 'TEXT', - Blockly.JavaScript.ORDER_NONE) || '\'\''; + const msg = JavaScript.valueToCode(block, 'TEXT', + JavaScript.ORDER_NONE) || '\'\''; return 'window.alert(' + msg + ');\n'; }; -Blockly.JavaScript['text_prompt_ext'] = function(block) { +JavaScript['text_prompt_ext'] = function(block) { // Prompt function. let msg; if (block.getField('TEXT')) { // Internal message. - msg = Blockly.JavaScript.quote_(block.getFieldValue('TEXT')); + msg = JavaScript.quote_(block.getFieldValue('TEXT')); } else { // External message. - msg = Blockly.JavaScript.valueToCode(block, 'TEXT', - Blockly.JavaScript.ORDER_NONE) || '\'\''; + msg = JavaScript.valueToCode(block, 'TEXT', + JavaScript.ORDER_NONE) || '\'\''; } let code = 'window.prompt(' + msg + ')'; const toNumber = block.getFieldValue('TYPE') === 'NUMBER'; if (toNumber) { code = 'Number(' + code + ')'; } - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['text_prompt'] = Blockly.JavaScript['text_prompt_ext']; +JavaScript['text_prompt'] = JavaScript['text_prompt_ext']; -Blockly.JavaScript['text_count'] = function(block) { - const text = Blockly.JavaScript.valueToCode(block, 'TEXT', - Blockly.JavaScript.ORDER_NONE) || '\'\''; - const sub = Blockly.JavaScript.valueToCode(block, 'SUB', - Blockly.JavaScript.ORDER_NONE) || '\'\''; - const functionName = Blockly.JavaScript.provideFunction_( +JavaScript['text_count'] = function(block) { + const text = JavaScript.valueToCode(block, 'TEXT', + JavaScript.ORDER_NONE) || '\'\''; + const sub = JavaScript.valueToCode(block, 'SUB', + JavaScript.ORDER_NONE) || '\'\''; + const functionName = JavaScript.provideFunction_( 'textCount', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(haystack, needle) {', ' if (needle.length === 0) {', ' return haystack.length + 1;', @@ -351,21 +348,21 @@ Blockly.JavaScript['text_count'] = function(block) { ' }', '}']); const code = functionName + '(' + text + ', ' + sub + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; + return [code, JavaScript.ORDER_FUNCTION_CALL]; }; -Blockly.JavaScript['text_replace'] = function(block) { - const text = Blockly.JavaScript.valueToCode(block, 'TEXT', - Blockly.JavaScript.ORDER_NONE) || '\'\''; - const from = Blockly.JavaScript.valueToCode(block, 'FROM', - Blockly.JavaScript.ORDER_NONE) || '\'\''; - const to = Blockly.JavaScript.valueToCode(block, 'TO', - Blockly.JavaScript.ORDER_NONE) || '\'\''; +JavaScript['text_replace'] = function(block) { + const text = JavaScript.valueToCode(block, 'TEXT', + JavaScript.ORDER_NONE) || '\'\''; + const from = JavaScript.valueToCode(block, 'FROM', + JavaScript.ORDER_NONE) || '\'\''; + const to = JavaScript.valueToCode(block, 'TO', + JavaScript.ORDER_NONE) || '\'\''; // The regex escaping code below is taken from the implementation of // goog.string.regExpEscape. - const functionName = Blockly.JavaScript.provideFunction_( + const functionName = JavaScript.provideFunction_( 'textReplace', - ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(haystack, needle, replacement) {', ' needle = ' + 'needle.replace(/([-()\\[\\]{}+?*.$\\^|,:# <= >= ~= == -Blockly.Lua.ORDER_AND = 8; // and -Blockly.Lua.ORDER_OR = 9; // or -Blockly.Lua.ORDER_NONE = 99; +Lua.ORDER_HIGH = 1; // Function calls, tables[] +Lua.ORDER_EXPONENTIATION = 2; // ^ +Lua.ORDER_UNARY = 3; // not # - ~ +Lua.ORDER_MULTIPLICATIVE = 4; // * / % +Lua.ORDER_ADDITIVE = 5; // + - +Lua.ORDER_CONCATENATION = 6; // .. +Lua.ORDER_RELATIONAL = 7; // < > <= >= ~= == +Lua.ORDER_AND = 8; // and +Lua.ORDER_OR = 9; // or +Lua.ORDER_NONE = 99; /** * Note: Lua is not supporting zero-indexing since the language itself is @@ -84,18 +89,18 @@ Blockly.Lua.ORDER_NONE = 99; * Whether the init method has been called. * @type {?boolean} */ -Blockly.Lua.isInitialized = false; +Lua.isInitialized = false; /** * Initialise the database of variable names. - * @param {!Blockly.Workspace} workspace Workspace to generate code from. + * @param {!Workspace} workspace Workspace to generate code from. */ -Blockly.Lua.init = function(workspace) { +Lua.init = function(workspace) { // Call Blockly.Generator's init. Object.getPrototypeOf(this).init.call(this); if (!this.nameDB_) { - this.nameDB_ = new Blockly.Names(this.RESERVED_WORDS_); + this.nameDB_ = new Names(this.RESERVED_WORDS_); } else { this.nameDB_.reset(); } @@ -111,9 +116,9 @@ Blockly.Lua.init = function(workspace) { * @param {string} code Generated code. * @return {string} Completed code. */ -Blockly.Lua.finish = function(code) { +Lua.finish = function(code) { // Convert the definitions dictionary into a list. - const definitions = Blockly.utils.object.values(this.definitions_); + const definitions = objectUtils.values(this.definitions_); // Call Blockly.Generator's finish. code = Object.getPrototypeOf(this).finish.call(this, code); this.isInitialized = false; @@ -130,7 +135,7 @@ Blockly.Lua.finish = function(code) { * @param {string} line Line of generated code. * @return {string} Legal line of code. */ -Blockly.Lua.scrubNakedValue = function(line) { +Lua.scrubNakedValue = function(line) { return 'local _ = ' + line + '\n'; }; @@ -141,7 +146,7 @@ Blockly.Lua.scrubNakedValue = function(line) { * @return {string} Lua string. * @protected */ -Blockly.Lua.quote_ = function(string) { +Lua.quote_ = function(string) { string = string.replace(/\\/g, '\\\\') .replace(/\n/g, '\\\n') .replace(/'/g, '\\\''); @@ -155,7 +160,7 @@ Blockly.Lua.quote_ = function(string) { * @return {string} Lua string. * @protected */ -Blockly.Lua.multiline_quote_ = function(string) { +Lua.multiline_quote_ = function(string) { const lines = string.split(/\n/g).map(this.quote_); // Join with the following, plus a newline: // .. '\n' .. @@ -166,26 +171,26 @@ Blockly.Lua.multiline_quote_ = function(string) { * Common tasks for generating Lua 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 {!Block} block The current block. * @param {string} code The Lua code created for this block. * @param {boolean=} opt_thisOnly True to generate code for only this statement. * @return {string} Lua code with comments and subsequent blocks added. * @protected */ -Blockly.Lua.scrub_ = function(block, code, opt_thisOnly) { +Lua.scrub_ = function(block, code, opt_thisOnly) { let 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) { - comment = Blockly.utils.string.wrap(comment, this.COMMENT_WRAP - 3); + comment = stringUtils.wrap(comment, this.COMMENT_WRAP - 3); commentCode += this.prefixLines(comment, '-- ') + '\n'; } // Collect comments for all value arguments. // Don't collect comments for nested statements. for (let i = 0; i < block.inputList.length; i++) { - if (block.inputList[i].type === Blockly.inputTypes.VALUE) { + if (block.inputList[i].type === inputTypes.VALUE) { const childBlock = block.inputList[i].connection.targetBlock(); if (childBlock) { comment = this.allNestedComments(childBlock); @@ -200,3 +205,5 @@ Blockly.Lua.scrub_ = function(block, code, opt_thisOnly) { const nextCode = opt_thisOnly ? '' : this.blockToCode(nextBlock); return commentCode + code + nextCode; }; + +exports = Lua; diff --git a/generators/lua/colour.js b/generators/lua/colour.js index 99649703688..1eabff3cb44 100644 --- a/generators/lua/colour.js +++ b/generators/lua/colour.js @@ -9,48 +9,48 @@ */ 'use strict'; -goog.provide('Blockly.Lua.colour'); +goog.module('Blockly.Lua.colour'); -goog.require('Blockly.Lua'); +const Lua = goog.require('Blockly.Lua'); -Blockly.Lua['colour_picker'] = function(block) { +Lua['colour_picker'] = function(block) { // Colour picker. - const code = Blockly.Lua.quote_(block.getFieldValue('COLOUR')); - return [code, Blockly.Lua.ORDER_ATOMIC]; + const code = Lua.quote_(block.getFieldValue('COLOUR')); + return [code, Lua.ORDER_ATOMIC]; }; -Blockly.Lua['colour_random'] = function(block) { +Lua['colour_random'] = function(block) { // Generate a random colour. const code = 'string.format("#%06x", math.random(0, 2^24 - 1))'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['colour_rgb'] = function(block) { +Lua['colour_rgb'] = function(block) { // Compose a colour from RGB components expressed as percentages. - const functionName = Blockly.Lua.provideFunction_( + const functionName = Lua.provideFunction_( 'colour_rgb', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b)', ' r = math.floor(math.min(100, math.max(0, r)) * 2.55 + .5)', ' g = math.floor(math.min(100, math.max(0, g)) * 2.55 + .5)', ' b = math.floor(math.min(100, math.max(0, b)) * 2.55 + .5)', ' return string.format("#%02x%02x%02x", r, g, b)', 'end']); - const r = Blockly.Lua.valueToCode(block, 'RED', - Blockly.Lua.ORDER_NONE) || 0; - const g = Blockly.Lua.valueToCode(block, 'GREEN', - Blockly.Lua.ORDER_NONE) || 0; - const b = Blockly.Lua.valueToCode(block, 'BLUE', - Blockly.Lua.ORDER_NONE) || 0; + const r = Lua.valueToCode(block, 'RED', + Lua.ORDER_NONE) || 0; + const g = Lua.valueToCode(block, 'GREEN', + Lua.ORDER_NONE) || 0; + const b = Lua.valueToCode(block, 'BLUE', + Lua.ORDER_NONE) || 0; const code = functionName + '(' + r + ', ' + g + ', ' + b + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['colour_blend'] = function(block) { +Lua['colour_blend'] = function(block) { // Blend two colours together. - const functionName = Blockly.Lua.provideFunction_( + const functionName = Lua.provideFunction_( 'colour_blend', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(colour1, colour2, ratio)', ' local r1 = tonumber(string.sub(colour1, 2, 3), 16)', ' local r2 = tonumber(string.sub(colour2, 2, 3), 16)', @@ -64,12 +64,12 @@ Blockly.Lua['colour_blend'] = function(block) { ' local b = math.floor(b1 * (1 - ratio) + b2 * ratio + .5)', ' return string.format("#%02x%02x%02x", r, g, b)', 'end']); - const colour1 = Blockly.Lua.valueToCode(block, 'COLOUR1', - Blockly.Lua.ORDER_NONE) || '\'#000000\''; - const colour2 = Blockly.Lua.valueToCode(block, 'COLOUR2', - Blockly.Lua.ORDER_NONE) || '\'#000000\''; - const ratio = Blockly.Lua.valueToCode(block, 'RATIO', - Blockly.Lua.ORDER_NONE) || 0; + const colour1 = Lua.valueToCode(block, 'COLOUR1', + Lua.ORDER_NONE) || '\'#000000\''; + const colour2 = Lua.valueToCode(block, 'COLOUR2', + Lua.ORDER_NONE) || '\'#000000\''; + const ratio = Lua.valueToCode(block, 'RATIO', + Lua.ORDER_NONE) || 0; const code = functionName + '(' + colour1 + ', ' + colour2 + ', ' + ratio + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; diff --git a/generators/lua/lists.js b/generators/lua/lists.js index 3c16c75a03c..fe66425543a 100644 --- a/generators/lua/lists.js +++ b/generators/lua/lists.js @@ -9,72 +9,73 @@ */ 'use strict'; -goog.provide('Blockly.Lua.lists'); +goog.module('Blockly.Lua.lists'); -goog.require('Blockly.Lua'); +const Blockly = goog.require('Blockly'); +const Lua = goog.require('Blockly.Lua'); -Blockly.Lua['lists_create_empty'] = function(block) { +Lua['lists_create_empty'] = function(block) { // Create an empty list. - return ['{}', Blockly.Lua.ORDER_HIGH]; + return ['{}', Lua.ORDER_HIGH]; }; -Blockly.Lua['lists_create_with'] = function(block) { +Lua['lists_create_with'] = function(block) { // Create a list with any number of elements of any type. const elements = new Array(block.itemCount_); for (let i = 0; i < block.itemCount_; i++) { - elements[i] = Blockly.Lua.valueToCode(block, 'ADD' + i, - Blockly.Lua.ORDER_NONE) || 'None'; + elements[i] = Lua.valueToCode(block, 'ADD' + i, + Lua.ORDER_NONE) || 'None'; } const code = '{' + elements.join(', ') + '}'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['lists_repeat'] = function(block) { +Lua['lists_repeat'] = function(block) { // Create a list with one element repeated. - const functionName = Blockly.Lua.provideFunction_( + const functionName = Lua.provideFunction_( 'create_list_repeated', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(item, count)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(item, count)', ' local t = {}', ' for i = 1, count do', ' table.insert(t, item)', ' end', ' return t', 'end']); - const element = Blockly.Lua.valueToCode(block, 'ITEM', - Blockly.Lua.ORDER_NONE) || 'None'; - const repeatCount = Blockly.Lua.valueToCode(block, 'NUM', - Blockly.Lua.ORDER_NONE) || '0'; + const element = Lua.valueToCode(block, 'ITEM', + Lua.ORDER_NONE) || 'None'; + const repeatCount = Lua.valueToCode(block, 'NUM', + Lua.ORDER_NONE) || '0'; const code = functionName + '(' + element + ', ' + repeatCount + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['lists_length'] = function(block) { +Lua['lists_length'] = function(block) { // String or array length. - const list = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_UNARY) || '{}'; - return ['#' + list, Blockly.Lua.ORDER_UNARY]; + const list = Lua.valueToCode(block, 'VALUE', + Lua.ORDER_UNARY) || '{}'; + return ['#' + list, Lua.ORDER_UNARY]; }; -Blockly.Lua['lists_isEmpty'] = function(block) { +Lua['lists_isEmpty'] = function(block) { // Is the string null or array empty? - const list = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_UNARY) || '{}'; + const list = Lua.valueToCode(block, 'VALUE', + Lua.ORDER_UNARY) || '{}'; const code = '#' + list + ' == 0'; - return [code, Blockly.Lua.ORDER_RELATIONAL]; + return [code, Lua.ORDER_RELATIONAL]; }; -Blockly.Lua['lists_indexOf'] = function(block) { +Lua['lists_indexOf'] = function(block) { // Find an item in the list. - const item = Blockly.Lua.valueToCode(block, 'FIND', - Blockly.Lua.ORDER_NONE) || '\'\''; - const list = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || '{}'; + const item = Lua.valueToCode(block, 'FIND', + Lua.ORDER_NONE) || '\'\''; + const list = Lua.valueToCode(block, 'VALUE', + Lua.ORDER_NONE) || '{}'; let functionName; if (block.getFieldValue('END') === 'FIRST') { - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'first_index', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, elem)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, elem)', ' for k, v in ipairs(t) do', ' if v == elem then', ' return k', @@ -83,9 +84,9 @@ Blockly.Lua['lists_indexOf'] = function(block) { ' return 0', 'end']); } else { - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'last_index', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, elem)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, elem)', ' for i = #t, 1, -1 do', ' if t[i] == elem then', ' return i', @@ -95,7 +96,7 @@ Blockly.Lua['lists_indexOf'] = function(block) { 'end']); } const code = functionName + '(' + list + ', ' + item + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; /** @@ -104,9 +105,8 @@ Blockly.Lua['lists_indexOf'] = function(block) { * @param {string} where The method of indexing, selected by dropdown in Blockly * @param {string=} opt_at The optional offset when indexing from start/end. * @return {string|undefined} Index expression. - * @private */ -Blockly.Lua.lists.getIndex_ = function(listName, where, opt_at) { +const getIndex = function(listName, where, opt_at) { if (where === 'FIRST') { return '1'; } else if (where === 'FROM_END') { @@ -120,14 +120,13 @@ Blockly.Lua.lists.getIndex_ = function(listName, where, opt_at) { } }; -Blockly.Lua['lists_getIndex'] = function(block) { +Lua['lists_getIndex'] = function(block) { // Get element at index. // Note: Until January 2013 this block did not have MODE or WHERE inputs. const mode = block.getFieldValue('MODE') || 'GET'; const where = block.getFieldValue('WHERE') || 'FROM_START'; - const list = Blockly.Lua.valueToCode(block, 'VALUE', Blockly.Lua.ORDER_HIGH) || + const list = Lua.valueToCode(block, 'VALUE', Lua.ORDER_HIGH) || '({})'; - const getIndex_ = Blockly.Lua.lists.getIndex_; // If `list` would be evaluated more than once (which is the case for LAST, // FROM_END, and RANDOM) and is non-trivial, make sure to access it only once. @@ -136,39 +135,39 @@ Blockly.Lua['lists_getIndex'] = function(block) { // `list` is an expression, so we may not evaluate it more than once. if (mode === 'REMOVE') { // We can use multiple statements. - const atOrder = (where === 'FROM_END') ? Blockly.Lua.ORDER_ADDITIVE : - Blockly.Lua.ORDER_NONE; - let at = Blockly.Lua.valueToCode(block, 'AT', atOrder) || '1'; - const listVar = Blockly.Lua.nameDB_.getDistinctName( + const atOrder = (where === 'FROM_END') ? Lua.ORDER_ADDITIVE : + Lua.ORDER_NONE; + let at = Lua.valueToCode(block, 'AT', atOrder) || '1'; + const listVar = Lua.nameDB_.getDistinctName( 'tmp_list', Blockly.VARIABLE_CATEGORY_NAME); - at = getIndex_(listVar, where, at); + at = getIndex(listVar, where, at); const code = listVar + ' = ' + list + '\n' + 'table.remove(' + listVar + ', ' + at + ')\n'; return code; } else { // We need to create a procedure to avoid reevaluating values. - const at = Blockly.Lua.valueToCode(block, 'AT', Blockly.Lua.ORDER_NONE) || + const at = Lua.valueToCode(block, 'AT', Lua.ORDER_NONE) || '1'; let functionName; if (mode === 'GET') { - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'list_get_' + where.toLowerCase(), - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t' + + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t' + // The value for 'FROM_END' and'FROM_START' depends on `at` so // we add it as a parameter. ((where === 'FROM_END' || where === 'FROM_START') ? ', at)' : ')'), - ' return t[' + getIndex_('t', where, 'at') + ']', + ' return t[' + getIndex('t', where, 'at') + ']', 'end']); } else { // `mode` === 'GET_REMOVE' - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'list_remove_' + where.toLowerCase(), - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t' + + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t' + // The value for 'FROM_END' and'FROM_START' depends on `at` so // we add it as a parameter. ((where === 'FROM_END' || where === 'FROM_START') ? ', at)' : ')'), - ' return table.remove(t, ' + getIndex_('t', where, 'at') + ')', + ' return table.remove(t, ' + getIndex('t', where, 'at') + ')', 'end']); } const code = functionName + '(' + list + @@ -176,22 +175,22 @@ Blockly.Lua['lists_getIndex'] = function(block) { // pass it. ((where === 'FROM_END' || where === 'FROM_START') ? ', ' + at : '') + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; } } else { // Either `list` is a simple variable, or we only need to refer to `list` // once. const atOrder = (mode === 'GET' && where === 'FROM_END') ? - Blockly.Lua.ORDER_ADDITIVE : Blockly.Lua.ORDER_NONE; - let at = Blockly.Lua.valueToCode(block, 'AT', atOrder) || '1'; - at = getIndex_(list, where, at); + Lua.ORDER_ADDITIVE : Lua.ORDER_NONE; + let at = Lua.valueToCode(block, 'AT', atOrder) || '1'; + at = getIndex(list, where, at); if (mode === 'GET') { const code = list + '[' + at + ']'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; } else { const code = 'table.remove(' + list + ', ' + at + ')'; if (mode === 'GET_REMOVE') { - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; } else { // `mode` === 'REMOVE' return code + '\n'; } @@ -199,18 +198,17 @@ Blockly.Lua['lists_getIndex'] = function(block) { } }; -Blockly.Lua['lists_setIndex'] = function(block) { +Lua['lists_setIndex'] = function(block) { // Set element at index. // Note: Until February 2013 this block did not have MODE or WHERE inputs. - let list = Blockly.Lua.valueToCode(block, 'LIST', - Blockly.Lua.ORDER_HIGH) || '{}'; + let list = Lua.valueToCode(block, 'LIST', + Lua.ORDER_HIGH) || '{}'; const mode = block.getFieldValue('MODE') || 'SET'; const where = block.getFieldValue('WHERE') || 'FROM_START'; - const at = Blockly.Lua.valueToCode(block, 'AT', - Blockly.Lua.ORDER_ADDITIVE) || '1'; - const value = Blockly.Lua.valueToCode(block, 'TO', - Blockly.Lua.ORDER_NONE) || 'None'; - const getIndex_ = Blockly.Lua.lists.getIndex_; + const at = Lua.valueToCode(block, 'AT', + Lua.ORDER_ADDITIVE) || '1'; + const value = Lua.valueToCode(block, 'TO', + Lua.ORDER_NONE) || 'None'; let code = ''; // If `list` would be evaluated more than once (which is the case for LAST, @@ -219,46 +217,45 @@ Blockly.Lua['lists_setIndex'] = function(block) { !list.match(/^\w+$/)) { // `list` is an expression, so we may not evaluate it more than once. // We can use multiple statements. - const listVar = Blockly.Lua.nameDB_.getDistinctName( + const listVar = Lua.nameDB_.getDistinctName( 'tmp_list', Blockly.VARIABLE_CATEGORY_NAME); code = listVar + ' = ' + list + '\n'; list = listVar; } if (mode === 'SET') { - code += list + '[' + getIndex_(list, where, at) + '] = ' + value; + code += list + '[' + getIndex(list, where, at) + '] = ' + value; } else { // `mode` === 'INSERT' // LAST is a special case, because we want to insert // *after* not *before*, the existing last element. code += 'table.insert(' + list + ', ' + - (getIndex_(list, where, at) + (where === 'LAST' ? ' + 1' : '')) + + (getIndex(list, where, at) + (where === 'LAST' ? ' + 1' : '')) + ', ' + value + ')'; } return code + '\n'; }; -Blockly.Lua['lists_getSublist'] = function(block) { +Lua['lists_getSublist'] = function(block) { // Get sublist. - const list = Blockly.Lua.valueToCode(block, 'LIST', - Blockly.Lua.ORDER_NONE) || '{}'; + const list = Lua.valueToCode(block, 'LIST', + Lua.ORDER_NONE) || '{}'; const where1 = block.getFieldValue('WHERE1'); const where2 = block.getFieldValue('WHERE2'); - const at1 = Blockly.Lua.valueToCode(block, 'AT1', - Blockly.Lua.ORDER_NONE) || '1'; - const at2 = Blockly.Lua.valueToCode(block, 'AT2', - Blockly.Lua.ORDER_NONE) || '1'; - const getIndex_ = Blockly.Lua.lists.getIndex_; + const at1 = Lua.valueToCode(block, 'AT1', + Lua.ORDER_NONE) || '1'; + const at2 = Lua.valueToCode(block, 'AT2', + Lua.ORDER_NONE) || '1'; - const functionName = Blockly.Lua.provideFunction_( + const functionName = Lua.provideFunction_( 'list_sublist_' + where1.toLowerCase() + '_' + where2.toLowerCase(), - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(source' + + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(source' + // The value for 'FROM_END' and'FROM_START' depends on `at` so // we add it as a parameter. ((where1 === 'FROM_END' || where1 === 'FROM_START') ? ', at1' : '') + ((where2 === 'FROM_END' || where2 === 'FROM_START') ? ', at2' : '') + ')', ' local t = {}', - ' local start = ' + getIndex_('source', where1, 'at1'), - ' local finish = ' + getIndex_('source', where2, 'at2'), + ' local start = ' + getIndex('source', where1, 'at1'), + ' local finish = ' + getIndex('source', where2, 'at2'), ' for i = start, finish do', ' table.insert(t, source[i])', ' end', @@ -270,19 +267,19 @@ Blockly.Lua['lists_getSublist'] = function(block) { ((where1 === 'FROM_END' || where1 === 'FROM_START') ? ', ' + at1 : '') + ((where2 === 'FROM_END' || where2 === 'FROM_START') ? ', ' + at2 : '') + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['lists_sort'] = function(block) { +Lua['lists_sort'] = function(block) { // Block for sorting a list. - const list = Blockly.Lua.valueToCode( - block, 'LIST', Blockly.Lua.ORDER_NONE) || '{}'; + const list = Lua.valueToCode( + block, 'LIST', Lua.ORDER_NONE) || '{}'; const direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1; const type = block.getFieldValue('TYPE'); - const functionName = Blockly.Lua.provideFunction_( + const functionName = Lua.provideFunction_( 'list_sort', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(list, typev, direction)', ' local t = {}', ' for n,v in pairs(list) do table.insert(t, v) end', // Shallow-copy. @@ -306,24 +303,24 @@ Blockly.Lua['lists_sort'] = function(block) { const code = functionName + '(' + list + ',"' + type + '", ' + direction + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['lists_split'] = function(block) { +Lua['lists_split'] = function(block) { // Block for splitting text into a list, or joining a list into text. - let input = Blockly.Lua.valueToCode(block, 'INPUT', - Blockly.Lua.ORDER_NONE); - const delimiter = Blockly.Lua.valueToCode(block, 'DELIM', - Blockly.Lua.ORDER_NONE) || '\'\''; + let input = Lua.valueToCode(block, 'INPUT', + Lua.ORDER_NONE); + const delimiter = Lua.valueToCode(block, 'DELIM', + Lua.ORDER_NONE) || '\'\''; const mode = block.getFieldValue('MODE'); let functionName; if (mode === 'SPLIT') { if (!input) { input = '\'\''; } - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'list_string_split', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(input, delim)', ' local t = {}', ' local pos = 1', @@ -348,16 +345,16 @@ Blockly.Lua['lists_split'] = function(block) { throw Error('Unknown mode: ' + mode); } const code = functionName + '(' + input + ', ' + delimiter + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['lists_reverse'] = function(block) { +Lua['lists_reverse'] = function(block) { // Block for reversing a list. - const list = Blockly.Lua.valueToCode(block, 'LIST', - Blockly.Lua.ORDER_NONE) || '{}'; - const functionName = Blockly.Lua.provideFunction_( + const list = Lua.valueToCode(block, 'LIST', + Lua.ORDER_NONE) || '{}'; + const functionName = Lua.provideFunction_( 'list_reverse', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(input)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(input)', ' local reversed = {}', ' for i = #input, 1, -1 do', ' table.insert(reversed, input[i])', @@ -365,5 +362,5 @@ Blockly.Lua['lists_reverse'] = function(block) { ' return reversed', 'end']); const code = functionName + '(' + list + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; diff --git a/generators/lua/logic.js b/generators/lua/logic.js index df8c460f1b3..e4245a5773a 100644 --- a/generators/lua/logic.js +++ b/generators/lua/logic.js @@ -9,48 +9,48 @@ */ 'use strict'; -goog.provide('Blockly.Lua.logic'); +goog.module('Blockly.Lua.logic'); -goog.require('Blockly.Lua'); +const Lua = goog.require('Blockly.Lua'); -Blockly.Lua['controls_if'] = function(block) { +Lua['controls_if'] = function(block) { // If/elseif/else condition. let n = 0; let code = ''; - if (Blockly.Lua.STATEMENT_PREFIX) { + if (Lua.STATEMENT_PREFIX) { // Automatic prefix insertion is switched off for this block. Add manually. - code += Blockly.Lua.injectId(Blockly.Lua.STATEMENT_PREFIX, block); + code += Lua.injectId(Lua.STATEMENT_PREFIX, block); } do { - const conditionCode = Blockly.Lua.valueToCode(block, 'IF' + n, - Blockly.Lua.ORDER_NONE) || 'false'; - let branchCode = Blockly.Lua.statementToCode(block, 'DO' + n); - if (Blockly.Lua.STATEMENT_SUFFIX) { - branchCode = Blockly.Lua.prefixLines( - Blockly.Lua.injectId(Blockly.Lua.STATEMENT_SUFFIX, block), - Blockly.Lua.INDENT) + branchCode; + const conditionCode = Lua.valueToCode(block, 'IF' + n, + Lua.ORDER_NONE) || 'false'; + let branchCode = Lua.statementToCode(block, 'DO' + n); + if (Lua.STATEMENT_SUFFIX) { + branchCode = Lua.prefixLines( + Lua.injectId(Lua.STATEMENT_SUFFIX, block), + Lua.INDENT) + branchCode; } code += (n > 0 ? 'else' : '') + 'if ' + conditionCode + ' then\n' + branchCode; n++; } while (block.getInput('IF' + n)); - if (block.getInput('ELSE') || Blockly.Lua.STATEMENT_SUFFIX) { - let branchCode = Blockly.Lua.statementToCode(block, 'ELSE'); - if (Blockly.Lua.STATEMENT_SUFFIX) { - branchCode = Blockly.Lua.prefixLines( - Blockly.Lua.injectId(Blockly.Lua.STATEMENT_SUFFIX, block), - Blockly.Lua.INDENT) + branchCode; + if (block.getInput('ELSE') || Lua.STATEMENT_SUFFIX) { + let branchCode = Lua.statementToCode(block, 'ELSE'); + if (Lua.STATEMENT_SUFFIX) { + branchCode = Lua.prefixLines( + Lua.injectId(Lua.STATEMENT_SUFFIX, block), + Lua.INDENT) + branchCode; } code += 'else\n' + branchCode; } return code + 'end\n'; }; -Blockly.Lua['controls_ifelse'] = Blockly.Lua['controls_if']; +Lua['controls_ifelse'] = Lua['controls_if']; -Blockly.Lua['logic_compare'] = function(block) { +Lua['logic_compare'] = function(block) { // Comparison operator. const OPERATORS = { 'EQ': '==', @@ -61,21 +61,21 @@ Blockly.Lua['logic_compare'] = function(block) { 'GTE': '>=' }; const operator = OPERATORS[block.getFieldValue('OP')]; - const argument0 = Blockly.Lua.valueToCode(block, 'A', - Blockly.Lua.ORDER_RELATIONAL) || '0'; - const argument1 = Blockly.Lua.valueToCode(block, 'B', - Blockly.Lua.ORDER_RELATIONAL) || '0'; + const argument0 = Lua.valueToCode(block, 'A', + Lua.ORDER_RELATIONAL) || '0'; + const argument1 = Lua.valueToCode(block, 'B', + Lua.ORDER_RELATIONAL) || '0'; const code = argument0 + ' ' + operator + ' ' + argument1; - return [code, Blockly.Lua.ORDER_RELATIONAL]; + return [code, Lua.ORDER_RELATIONAL]; }; -Blockly.Lua['logic_operation'] = function(block) { +Lua['logic_operation'] = function(block) { // Operations 'and', 'or'. const operator = (block.getFieldValue('OP') === 'AND') ? 'and' : 'or'; - const order = (operator === 'and') ? Blockly.Lua.ORDER_AND : - Blockly.Lua.ORDER_OR; - let argument0 = Blockly.Lua.valueToCode(block, 'A', order); - let argument1 = Blockly.Lua.valueToCode(block, 'B', order); + const order = (operator === 'and') ? Lua.ORDER_AND : + Lua.ORDER_OR; + let argument0 = Lua.valueToCode(block, 'A', order); + let argument1 = Lua.valueToCode(block, 'B', order); if (!argument0 && !argument1) { // If there are no arguments, then the return value is false. argument0 = 'false'; @@ -94,33 +94,33 @@ Blockly.Lua['logic_operation'] = function(block) { return [code, order]; }; -Blockly.Lua['logic_negate'] = function(block) { +Lua['logic_negate'] = function(block) { // Negation. - const argument0 = Blockly.Lua.valueToCode(block, 'BOOL', - Blockly.Lua.ORDER_UNARY) || 'true'; + const argument0 = Lua.valueToCode(block, 'BOOL', + Lua.ORDER_UNARY) || 'true'; const code = 'not ' + argument0; - return [code, Blockly.Lua.ORDER_UNARY]; + return [code, Lua.ORDER_UNARY]; }; -Blockly.Lua['logic_boolean'] = function(block) { +Lua['logic_boolean'] = function(block) { // Boolean values true and false. const code = (block.getFieldValue('BOOL') === 'TRUE') ? 'true' : 'false'; - return [code, Blockly.Lua.ORDER_ATOMIC]; + return [code, Lua.ORDER_ATOMIC]; }; -Blockly.Lua['logic_null'] = function(block) { +Lua['logic_null'] = function(block) { // Null data type. - return ['nil', Blockly.Lua.ORDER_ATOMIC]; + return ['nil', Lua.ORDER_ATOMIC]; }; -Blockly.Lua['logic_ternary'] = function(block) { +Lua['logic_ternary'] = function(block) { // Ternary operator. - const value_if = Blockly.Lua.valueToCode(block, 'IF', - Blockly.Lua.ORDER_AND) || 'false'; - const value_then = Blockly.Lua.valueToCode(block, 'THEN', - Blockly.Lua.ORDER_AND) || 'nil'; - const value_else = Blockly.Lua.valueToCode(block, 'ELSE', - Blockly.Lua.ORDER_OR) || 'nil'; + const value_if = Lua.valueToCode(block, 'IF', + Lua.ORDER_AND) || 'false'; + const value_then = Lua.valueToCode(block, 'THEN', + Lua.ORDER_AND) || 'nil'; + const value_else = Lua.valueToCode(block, 'ELSE', + Lua.ORDER_OR) || 'nil'; const code = value_if + ' and ' + value_then + ' or ' + value_else; - return [code, Blockly.Lua.ORDER_OR]; + return [code, Lua.ORDER_OR]; }; diff --git a/generators/lua/loops.js b/generators/lua/loops.js index 2cc9696c767..8ffcf043e9e 100644 --- a/generators/lua/loops.js +++ b/generators/lua/loops.js @@ -9,9 +9,11 @@ */ 'use strict'; -goog.provide('Blockly.Lua.loops'); +goog.module('Blockly.Lua.loops'); -goog.require('Blockly.Lua'); +const Blockly = goog.require('Blockly'); +const Loops = goog.require('Blockly.Constants.Loops'); +const Lua = goog.require('Blockly.Lua'); /** @@ -20,7 +22,7 @@ goog.require('Blockly.Lua'); * the appropriate label can be put at the end of the loop body. * @const {string} */ -Blockly.Lua.CONTINUE_STATEMENT = 'goto continue\n'; +Lua.CONTINUE_STATEMENT = 'goto continue\n'; /** * If the loop body contains a "goto continue" statement, add a continue label @@ -32,16 +34,16 @@ Blockly.Lua.CONTINUE_STATEMENT = 'goto continue\n'; * @return {string} Generated label or '' if unnecessary * @private */ -Blockly.Lua.addContinueLabel_ = function(branch) { - if (branch.indexOf(Blockly.Lua.CONTINUE_STATEMENT) !== -1) { +Lua.addContinueLabel_ = function(branch) { + if (branch.indexOf(Lua.CONTINUE_STATEMENT) !== -1) { // False positives are possible (e.g. a string literal), but are harmless. - return branch + Blockly.Lua.INDENT + '::continue::\n'; + return branch + Lua.INDENT + '::continue::\n'; } else { return branch; } }; -Blockly.Lua['controls_repeat_ext'] = function(block) { +Lua['controls_repeat_ext'] = function(block) { // Repeat n times. let repeats; if (block.getField('TIMES')) { @@ -49,54 +51,54 @@ Blockly.Lua['controls_repeat_ext'] = function(block) { repeats = String(Number(block.getFieldValue('TIMES'))); } else { // External number. - repeats = Blockly.Lua.valueToCode(block, 'TIMES', - Blockly.Lua.ORDER_NONE) || '0'; + repeats = Lua.valueToCode(block, 'TIMES', + Lua.ORDER_NONE) || '0'; } if (Blockly.isNumber(repeats)) { repeats = parseInt(repeats, 10); } else { repeats = 'math.floor(' + repeats + ')'; } - let branch = Blockly.Lua.statementToCode(block, 'DO'); - branch = Blockly.Lua.addLoopTrap(branch, block); - branch = Blockly.Lua.addContinueLabel_(branch); - const loopVar = Blockly.Lua.nameDB_.getDistinctName( + let branch = Lua.statementToCode(block, 'DO'); + branch = Lua.addLoopTrap(branch, block); + branch = Lua.addContinueLabel_(branch); + const loopVar = Lua.nameDB_.getDistinctName( 'count', Blockly.VARIABLE_CATEGORY_NAME); const code = 'for ' + loopVar + ' = 1, ' + repeats + ' do\n' + branch + 'end\n'; return code; }; -Blockly.Lua['controls_repeat'] = Blockly.Lua['controls_repeat_ext']; +Lua['controls_repeat'] = Lua['controls_repeat_ext']; -Blockly.Lua['controls_whileUntil'] = function(block) { +Lua['controls_whileUntil'] = function(block) { // Do while/until loop. const until = block.getFieldValue('MODE') === 'UNTIL'; - let argument0 = Blockly.Lua.valueToCode(block, 'BOOL', - until ? Blockly.Lua.ORDER_UNARY : - Blockly.Lua.ORDER_NONE) || 'false'; - let branch = Blockly.Lua.statementToCode(block, 'DO'); - branch = Blockly.Lua.addLoopTrap(branch, block); - branch = Blockly.Lua.addContinueLabel_(branch); + let argument0 = Lua.valueToCode(block, 'BOOL', + until ? Lua.ORDER_UNARY : + Lua.ORDER_NONE) || 'false'; + let branch = Lua.statementToCode(block, 'DO'); + branch = Lua.addLoopTrap(branch, block); + branch = Lua.addContinueLabel_(branch); if (until) { argument0 = 'not ' + argument0; } return 'while ' + argument0 + ' do\n' + branch + 'end\n'; }; -Blockly.Lua['controls_for'] = function(block) { +Lua['controls_for'] = function(block) { // For loop. - const variable0 = Blockly.Lua.nameDB_.getName( + const variable0 = Lua.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const startVar = Blockly.Lua.valueToCode(block, 'FROM', - Blockly.Lua.ORDER_NONE) || '0'; - const endVar = Blockly.Lua.valueToCode(block, 'TO', - Blockly.Lua.ORDER_NONE) || '0'; - const increment = Blockly.Lua.valueToCode(block, 'BY', - Blockly.Lua.ORDER_NONE) || '1'; - let branch = Blockly.Lua.statementToCode(block, 'DO'); - branch = Blockly.Lua.addLoopTrap(branch, block); - branch = Blockly.Lua.addContinueLabel_(branch); + const startVar = Lua.valueToCode(block, 'FROM', + Lua.ORDER_NONE) || '0'; + const endVar = Lua.valueToCode(block, 'TO', + Lua.ORDER_NONE) || '0'; + const increment = Lua.valueToCode(block, 'BY', + Lua.ORDER_NONE) || '1'; + let branch = Lua.statementToCode(block, 'DO'); + branch = Lua.addLoopTrap(branch, block); + branch = Lua.addContinueLabel_(branch); let code = ''; let incValue; if (Blockly.isNumber(startVar) && Blockly.isNumber(endVar) && @@ -109,7 +111,7 @@ Blockly.Lua['controls_for'] = function(block) { code = ''; // Determine loop direction at start, in case one of the bounds // changes during loop execution. - incValue = Blockly.Lua.nameDB_.getDistinctName( + incValue = Lua.nameDB_.getDistinctName( variable0 + '_inc', Blockly.VARIABLE_CATEGORY_NAME); code += incValue + ' = '; if (Blockly.isNumber(increment)) { @@ -118,7 +120,7 @@ Blockly.Lua['controls_for'] = function(block) { code += 'math.abs(' + increment + ')\n'; } code += 'if (' + startVar + ') > (' + endVar + ') then\n'; - code += Blockly.Lua.INDENT + incValue + ' = -' + incValue + '\n'; + code += Lua.INDENT + incValue + ' = -' + incValue + '\n'; code += 'end\n'; } code += 'for ' + variable0 + ' = ' + startVar + ', ' + endVar + @@ -127,47 +129,47 @@ Blockly.Lua['controls_for'] = function(block) { return code; }; -Blockly.Lua['controls_forEach'] = function(block) { +Lua['controls_forEach'] = function(block) { // For each loop. - const variable0 = Blockly.Lua.nameDB_.getName( + const variable0 = Lua.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const argument0 = Blockly.Lua.valueToCode(block, 'LIST', - Blockly.Lua.ORDER_NONE) || '{}'; - let branch = Blockly.Lua.statementToCode(block, 'DO'); - branch = Blockly.Lua.addLoopTrap(branch, block); - branch = Blockly.Lua.addContinueLabel_(branch); + const argument0 = Lua.valueToCode(block, 'LIST', + Lua.ORDER_NONE) || '{}'; + let branch = Lua.statementToCode(block, 'DO'); + branch = Lua.addLoopTrap(branch, block); + branch = Lua.addContinueLabel_(branch); const code = 'for _, ' + variable0 + ' in ipairs(' + argument0 + ') do \n' + branch + 'end\n'; return code; }; -Blockly.Lua['controls_flow_statements'] = function(block) { +Lua['controls_flow_statements'] = function(block) { // Flow statements: continue, break. let xfix = ''; - if (Blockly.Lua.STATEMENT_PREFIX) { + if (Lua.STATEMENT_PREFIX) { // Automatic prefix insertion is switched off for this block. Add manually. - xfix += Blockly.Lua.injectId(Blockly.Lua.STATEMENT_PREFIX, block); + xfix += Lua.injectId(Lua.STATEMENT_PREFIX, block); } - if (Blockly.Lua.STATEMENT_SUFFIX) { + if (Lua.STATEMENT_SUFFIX) { // Inject any statement suffix here since the regular one at the end // will not get executed if the break/continue is triggered. - xfix += Blockly.Lua.injectId(Blockly.Lua.STATEMENT_SUFFIX, block); + xfix += Lua.injectId(Lua.STATEMENT_SUFFIX, block); } - if (Blockly.Lua.STATEMENT_PREFIX) { - const loop = Blockly.Constants.Loops + if (Lua.STATEMENT_PREFIX) { + const loop = Loops .CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); if (loop && !loop.suppressPrefixSuffix) { // Inject loop's statement prefix here since the regular one at the end // of the loop will not get executed if 'continue' is triggered. // In the case of 'break', a prefix is needed due to the loop's suffix. - xfix += Blockly.Lua.injectId(Blockly.Lua.STATEMENT_PREFIX, loop); + xfix += Lua.injectId(Lua.STATEMENT_PREFIX, loop); } } switch (block.getFieldValue('FLOW')) { case 'BREAK': return xfix + 'break\n'; case 'CONTINUE': - return xfix + Blockly.Lua.CONTINUE_STATEMENT; + return xfix + Lua.CONTINUE_STATEMENT; } throw Error('Unknown flow statement.'); }; diff --git a/generators/lua/math.js b/generators/lua/math.js index aab654b86d0..05b3e0c308a 100644 --- a/generators/lua/math.js +++ b/generators/lua/math.js @@ -9,58 +9,59 @@ */ 'use strict'; -goog.provide('Blockly.Lua.math'); +goog.module('Blockly.Lua.math'); -goog.require('Blockly.Lua'); +const Blockly = goog.require('Blockly'); +const Lua = goog.require('Blockly.Lua'); -Blockly.Lua['math_number'] = function(block) { +Lua['math_number'] = function(block) { // Numeric value. const code = Number(block.getFieldValue('NUM')); - const order = code < 0 ? Blockly.Lua.ORDER_UNARY : - Blockly.Lua.ORDER_ATOMIC; + const order = code < 0 ? Lua.ORDER_UNARY : + Lua.ORDER_ATOMIC; return [code, order]; }; -Blockly.Lua['math_arithmetic'] = function(block) { +Lua['math_arithmetic'] = function(block) { // Basic arithmetic operators, and power. const OPERATORS = { - ADD: [' + ', Blockly.Lua.ORDER_ADDITIVE], - MINUS: [' - ', Blockly.Lua.ORDER_ADDITIVE], - MULTIPLY: [' * ', Blockly.Lua.ORDER_MULTIPLICATIVE], - DIVIDE: [' / ', Blockly.Lua.ORDER_MULTIPLICATIVE], - POWER: [' ^ ', Blockly.Lua.ORDER_EXPONENTIATION] + ADD: [' + ', Lua.ORDER_ADDITIVE], + MINUS: [' - ', Lua.ORDER_ADDITIVE], + MULTIPLY: [' * ', Lua.ORDER_MULTIPLICATIVE], + DIVIDE: [' / ', Lua.ORDER_MULTIPLICATIVE], + POWER: [' ^ ', Lua.ORDER_EXPONENTIATION] }; const tuple = OPERATORS[block.getFieldValue('OP')]; const operator = tuple[0]; const order = tuple[1]; - const argument0 = Blockly.Lua.valueToCode(block, 'A', order) || '0'; - const argument1 = Blockly.Lua.valueToCode(block, 'B', order) || '0'; + const argument0 = Lua.valueToCode(block, 'A', order) || '0'; + const argument1 = Lua.valueToCode(block, 'B', order) || '0'; const code = argument0 + operator + argument1; return [code, order]; }; -Blockly.Lua['math_single'] = function(block) { +Lua['math_single'] = function(block) { // Math operators with single operand. const operator = block.getFieldValue('OP'); let arg; if (operator === 'NEG') { // Negation is a special case given its different operator precedence. - arg = Blockly.Lua.valueToCode(block, 'NUM', - Blockly.Lua.ORDER_UNARY) || '0'; - return ['-' + arg, Blockly.Lua.ORDER_UNARY]; + arg = Lua.valueToCode(block, 'NUM', + Lua.ORDER_UNARY) || '0'; + return ['-' + arg, Lua.ORDER_UNARY]; } if (operator === 'POW10') { - arg = Blockly.Lua.valueToCode(block, 'NUM', - Blockly.Lua.ORDER_EXPONENTIATION) || '0'; - return ['10 ^ ' + arg, Blockly.Lua.ORDER_EXPONENTIATION]; + arg = Lua.valueToCode(block, 'NUM', + Lua.ORDER_EXPONENTIATION) || '0'; + return ['10 ^ ' + arg, Lua.ORDER_EXPONENTIATION]; } if (operator === 'ROUND') { - arg = Blockly.Lua.valueToCode(block, 'NUM', - Blockly.Lua.ORDER_ADDITIVE) || '0'; + arg = Lua.valueToCode(block, 'NUM', + Lua.ORDER_ADDITIVE) || '0'; } else { - arg = Blockly.Lua.valueToCode(block, 'NUM', - Blockly.Lua.ORDER_NONE) || '0'; + arg = Lua.valueToCode(block, 'NUM', + Lua.ORDER_NONE) || '0'; } let code; @@ -111,34 +112,34 @@ Blockly.Lua['math_single'] = function(block) { default: throw Error('Unknown math operator: ' + operator); } - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['math_constant'] = function(block) { +Lua['math_constant'] = function(block) { // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY. const CONSTANTS = { - PI: ['math.pi', Blockly.Lua.ORDER_HIGH], - E: ['math.exp(1)', Blockly.Lua.ORDER_HIGH], - GOLDEN_RATIO: ['(1 + math.sqrt(5)) / 2', Blockly.Lua.ORDER_MULTIPLICATIVE], - SQRT2: ['math.sqrt(2)', Blockly.Lua.ORDER_HIGH], - SQRT1_2: ['math.sqrt(1 / 2)', Blockly.Lua.ORDER_HIGH], - INFINITY: ['math.huge', Blockly.Lua.ORDER_HIGH] + PI: ['math.pi', Lua.ORDER_HIGH], + E: ['math.exp(1)', Lua.ORDER_HIGH], + GOLDEN_RATIO: ['(1 + math.sqrt(5)) / 2', Lua.ORDER_MULTIPLICATIVE], + SQRT2: ['math.sqrt(2)', Lua.ORDER_HIGH], + SQRT1_2: ['math.sqrt(1 / 2)', Lua.ORDER_HIGH], + INFINITY: ['math.huge', Lua.ORDER_HIGH] }; return CONSTANTS[block.getFieldValue('CONSTANT')]; }; -Blockly.Lua['math_number_property'] = function(block) { +Lua['math_number_property'] = function(block) { // Check if a number is even, odd, prime, whole, positive, or negative // or if it is divisible by certain number. Returns true or false. - const number_to_check = Blockly.Lua.valueToCode(block, 'NUMBER_TO_CHECK', - Blockly.Lua.ORDER_MULTIPLICATIVE) || '0'; + const number_to_check = Lua.valueToCode(block, 'NUMBER_TO_CHECK', + Lua.ORDER_MULTIPLICATIVE) || '0'; const dropdown_property = block.getFieldValue('PROPERTY'); let code; if (dropdown_property === 'PRIME') { // Prime is a special case as it is not a one-liner test. - const functionName = Blockly.Lua.provideFunction_( + const functionName = Lua.provideFunction_( 'math_isPrime', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(n)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(n)', ' -- https://en.wikipedia.org/wiki/Primality_test#Naive_methods', ' if n == 2 or n == 3 then', ' return true', @@ -157,7 +158,7 @@ Blockly.Lua['math_number_property'] = function(block) { ' return true', 'end']); code = functionName + '(' + number_to_check + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; } switch (dropdown_property) { case 'EVEN': @@ -176,12 +177,12 @@ Blockly.Lua['math_number_property'] = function(block) { code = number_to_check + ' < 0'; break; case 'DIVISIBLE_BY': { - const divisor = Blockly.Lua.valueToCode(block, 'DIVISOR', - Blockly.Lua.ORDER_MULTIPLICATIVE); + const divisor = Lua.valueToCode(block, 'DIVISOR', + Lua.ORDER_MULTIPLICATIVE); // If 'divisor' is some code that evals to 0, Lua will produce a nan. // Let's produce nil if we can determine this at compile-time. if (!divisor || divisor === '0') { - return ['nil', Blockly.Lua.ORDER_ATOMIC]; + return ['nil', Lua.ORDER_ATOMIC]; } // The normal trick to implement ?: with and/or doesn't work here: // divisor == 0 and nil or number_to_check % divisor == 0 @@ -190,35 +191,35 @@ Blockly.Lua['math_number_property'] = function(block) { break; } } - return [code, Blockly.Lua.ORDER_RELATIONAL]; + return [code, Lua.ORDER_RELATIONAL]; }; -Blockly.Lua['math_change'] = function(block) { +Lua['math_change'] = function(block) { // Add to a variable in place. - const argument0 = Blockly.Lua.valueToCode(block, 'DELTA', - Blockly.Lua.ORDER_ADDITIVE) || '0'; - const varName = Blockly.Lua.nameDB_.getName( + const argument0 = Lua.valueToCode(block, 'DELTA', + Lua.ORDER_ADDITIVE) || '0'; + const varName = Lua.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); return varName + ' = ' + varName + ' + ' + argument0 + '\n'; }; // Rounding functions have a single operand. -Blockly.Lua['math_round'] = Blockly.Lua['math_single']; +Lua['math_round'] = Lua['math_single']; // Trigonometry functions have a single operand. -Blockly.Lua['math_trig'] = Blockly.Lua['math_single']; +Lua['math_trig'] = Lua['math_single']; -Blockly.Lua['math_on_list'] = function(block) { +Lua['math_on_list'] = function(block) { // Math functions for lists. const func = block.getFieldValue('OP'); - const list = Blockly.Lua.valueToCode(block, 'LIST', - Blockly.Lua.ORDER_NONE) || '{}'; + const list = Lua.valueToCode(block, 'LIST', + Lua.ORDER_NONE) || '{}'; let functionName; // Functions needed in more than one case. function provideSum() { - return Blockly.Lua.provideFunction_( + return Lua.provideFunction_( 'math_sum', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', ' local result = 0', ' for _, v in ipairs(t) do', ' result = result + v', @@ -234,9 +235,9 @@ Blockly.Lua['math_on_list'] = function(block) { case 'MIN': // Returns 0 for the empty list. - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'math_min', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', ' if #t == 0 then', ' return 0', ' end', @@ -252,9 +253,9 @@ Blockly.Lua['math_on_list'] = function(block) { case 'AVERAGE': // Returns 0 for the empty list. - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'math_average', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', ' if #t == 0 then', ' return 0', ' end', @@ -264,9 +265,9 @@ Blockly.Lua['math_on_list'] = function(block) { case 'MAX': // Returns 0 for the empty list. - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'math_max', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', ' if #t == 0 then', ' return 0', ' end', @@ -281,10 +282,10 @@ Blockly.Lua['math_on_list'] = function(block) { break; case 'MEDIAN': - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'math_median', // This operation excludes non-numbers. - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', ' -- Source: http://lua-users.org/wiki/SimpleStats', ' if #t == 0 then', ' return 0', @@ -305,12 +306,12 @@ Blockly.Lua['math_on_list'] = function(block) { break; case 'MODE': - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'math_modes', // As a list of numbers can contain more than one mode, // the returned result is provided as an array. // The Lua version includes non-numbers. - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', ' -- Source: http://lua-users.org/wiki/SimpleStats', ' local counts={}', ' for _, v in ipairs(t) do', @@ -337,9 +338,9 @@ Blockly.Lua['math_on_list'] = function(block) { break; case 'STD_DEV': - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'math_standard_deviation', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', ' local m', ' local vm', ' local total = 0', @@ -359,9 +360,9 @@ Blockly.Lua['math_on_list'] = function(block) { break; case 'RANDOM': - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'math_random_list', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)', ' if #t == 0 then', ' return nil', ' end', @@ -372,53 +373,53 @@ Blockly.Lua['math_on_list'] = function(block) { default: throw Error('Unknown operator: ' + func); } - return [functionName + '(' + list + ')', Blockly.Lua.ORDER_HIGH]; + return [functionName + '(' + list + ')', Lua.ORDER_HIGH]; }; -Blockly.Lua['math_modulo'] = function(block) { +Lua['math_modulo'] = function(block) { // Remainder computation. - const argument0 = Blockly.Lua.valueToCode(block, 'DIVIDEND', - Blockly.Lua.ORDER_MULTIPLICATIVE) || '0'; - const argument1 = Blockly.Lua.valueToCode(block, 'DIVISOR', - Blockly.Lua.ORDER_MULTIPLICATIVE) || '0'; + const argument0 = Lua.valueToCode(block, 'DIVIDEND', + Lua.ORDER_MULTIPLICATIVE) || '0'; + const argument1 = Lua.valueToCode(block, 'DIVISOR', + Lua.ORDER_MULTIPLICATIVE) || '0'; const code = argument0 + ' % ' + argument1; - return [code, Blockly.Lua.ORDER_MULTIPLICATIVE]; + return [code, Lua.ORDER_MULTIPLICATIVE]; }; -Blockly.Lua['math_constrain'] = function(block) { +Lua['math_constrain'] = function(block) { // Constrain a number between two limits. - const argument0 = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || '0'; - const argument1 = Blockly.Lua.valueToCode(block, 'LOW', - Blockly.Lua.ORDER_NONE) || '-math.huge'; - const argument2 = Blockly.Lua.valueToCode(block, 'HIGH', - Blockly.Lua.ORDER_NONE) || 'math.huge'; + const argument0 = Lua.valueToCode(block, 'VALUE', + Lua.ORDER_NONE) || '0'; + const argument1 = Lua.valueToCode(block, 'LOW', + Lua.ORDER_NONE) || '-math.huge'; + const argument2 = Lua.valueToCode(block, 'HIGH', + Lua.ORDER_NONE) || 'math.huge'; const code = 'math.min(math.max(' + argument0 + ', ' + argument1 + '), ' + argument2 + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['math_random_int'] = function(block) { +Lua['math_random_int'] = function(block) { // Random integer between [X] and [Y]. - const argument0 = Blockly.Lua.valueToCode(block, 'FROM', - Blockly.Lua.ORDER_NONE) || '0'; - const argument1 = Blockly.Lua.valueToCode(block, 'TO', - Blockly.Lua.ORDER_NONE) || '0'; + const argument0 = Lua.valueToCode(block, 'FROM', + Lua.ORDER_NONE) || '0'; + const argument1 = Lua.valueToCode(block, 'TO', + Lua.ORDER_NONE) || '0'; const code = 'math.random(' + argument0 + ', ' + argument1 + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['math_random_float'] = function(block) { +Lua['math_random_float'] = function(block) { // Random fraction between 0 and 1. - return ['math.random()', Blockly.Lua.ORDER_HIGH]; + return ['math.random()', Lua.ORDER_HIGH]; }; -Blockly.Lua['math_atan2'] = function(block) { +Lua['math_atan2'] = function(block) { // Arctangent of point (X, Y) in degrees from -180 to 180. - const argument0 = Blockly.Lua.valueToCode(block, 'X', - Blockly.Lua.ORDER_NONE) || '0'; - const argument1 = Blockly.Lua.valueToCode(block, 'Y', - Blockly.Lua.ORDER_NONE) || '0'; + const argument0 = Lua.valueToCode(block, 'X', + Lua.ORDER_NONE) || '0'; + const argument1 = Lua.valueToCode(block, 'Y', + Lua.ORDER_NONE) || '0'; return ['math.deg(math.atan2(' + argument1 + ', ' + argument0 + '))', - Blockly.Lua.ORDER_HIGH]; + Lua.ORDER_HIGH]; }; diff --git a/generators/lua/procedures.js b/generators/lua/procedures.js index 70dfdd631b6..b8897f43487 100644 --- a/generators/lua/procedures.js +++ b/generators/lua/procedures.js @@ -9,103 +9,104 @@ */ 'use strict'; -goog.provide('Blockly.Lua.procedures'); +goog.module('Blockly.Lua.procedures'); -goog.require('Blockly.Lua'); +const Blockly = goog.require('Blockly'); +const Lua = goog.require('Blockly.Lua'); -Blockly.Lua['procedures_defreturn'] = function(block) { +Lua['procedures_defreturn'] = function(block) { // Define a procedure with a return value. - const funcName = Blockly.Lua.nameDB_.getName( + const funcName = Lua.nameDB_.getName( block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME); let xfix1 = ''; - if (Blockly.Lua.STATEMENT_PREFIX) { - xfix1 += Blockly.Lua.injectId(Blockly.Lua.STATEMENT_PREFIX, block); + if (Lua.STATEMENT_PREFIX) { + xfix1 += Lua.injectId(Lua.STATEMENT_PREFIX, block); } - if (Blockly.Lua.STATEMENT_SUFFIX) { - xfix1 += Blockly.Lua.injectId(Blockly.Lua.STATEMENT_SUFFIX, block); + if (Lua.STATEMENT_SUFFIX) { + xfix1 += Lua.injectId(Lua.STATEMENT_SUFFIX, block); } if (xfix1) { - xfix1 = Blockly.Lua.prefixLines(xfix1, Blockly.Lua.INDENT); + xfix1 = Lua.prefixLines(xfix1, Lua.INDENT); } let loopTrap = ''; - if (Blockly.Lua.INFINITE_LOOP_TRAP) { - loopTrap = Blockly.Lua.prefixLines( - Blockly.Lua.injectId(Blockly.Lua.INFINITE_LOOP_TRAP, block), - Blockly.Lua.INDENT); + if (Lua.INFINITE_LOOP_TRAP) { + loopTrap = Lua.prefixLines( + Lua.injectId(Lua.INFINITE_LOOP_TRAP, block), + Lua.INDENT); } - let branch = Blockly.Lua.statementToCode(block, 'STACK'); - let returnValue = Blockly.Lua.valueToCode(block, 'RETURN', - Blockly.Lua.ORDER_NONE) || ''; + let branch = Lua.statementToCode(block, 'STACK'); + let returnValue = Lua.valueToCode(block, 'RETURN', + Lua.ORDER_NONE) || ''; let xfix2 = ''; if (branch && returnValue) { // After executing the function body, revisit this block for the return. xfix2 = xfix1; } if (returnValue) { - returnValue = Blockly.Lua.INDENT + 'return ' + returnValue + '\n'; + returnValue = Lua.INDENT + 'return ' + returnValue + '\n'; } else if (!branch) { branch = ''; } const args = []; const variables = block.getVars(); for (let i = 0; i < variables.length; i++) { - args[i] = Blockly.Lua.nameDB_.getName(variables[i], + args[i] = Lua.nameDB_.getName(variables[i], Blockly.VARIABLE_CATEGORY_NAME); } let code = 'function ' + funcName + '(' + args.join(', ') + ')\n' + xfix1 + loopTrap + branch + xfix2 + returnValue + 'end\n'; - code = Blockly.Lua.scrub_(block, code); + code = Lua.scrub_(block, code); // Add % so as not to collide with helper functions in definitions list. - Blockly.Lua.definitions_['%' + funcName] = code; + Lua.definitions_['%' + funcName] = code; return null; }; // Defining a procedure without a return value uses the same generator as // a procedure with a return value. -Blockly.Lua['procedures_defnoreturn'] = - Blockly.Lua['procedures_defreturn']; +Lua['procedures_defnoreturn'] = + Lua['procedures_defreturn']; -Blockly.Lua['procedures_callreturn'] = function(block) { +Lua['procedures_callreturn'] = function(block) { // Call a procedure with a return value. - const funcName = Blockly.Lua.nameDB_.getName( + const funcName = Lua.nameDB_.getName( block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME); const args = []; const variables = block.getVars(); for (let i = 0; i < variables.length; i++) { - args[i] = Blockly.Lua.valueToCode(block, 'ARG' + i, - Blockly.Lua.ORDER_NONE) || 'nil'; + args[i] = Lua.valueToCode(block, 'ARG' + i, + Lua.ORDER_NONE) || 'nil'; } const code = funcName + '(' + args.join(', ') + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['procedures_callnoreturn'] = function(block) { +Lua['procedures_callnoreturn'] = function(block) { // Call a procedure with no return value. // Generated code is for a function call as a statement is the same as a // function call as a value, with the addition of line ending. - const tuple = Blockly.Lua['procedures_callreturn'](block); + const tuple = Lua['procedures_callreturn'](block); return tuple[0] + '\n'; }; -Blockly.Lua['procedures_ifreturn'] = function(block) { +Lua['procedures_ifreturn'] = function(block) { // Conditionally return value from a procedure. - const condition = Blockly.Lua.valueToCode(block, 'CONDITION', - Blockly.Lua.ORDER_NONE) || 'false'; + const condition = Lua.valueToCode(block, 'CONDITION', + Lua.ORDER_NONE) || 'false'; let code = 'if ' + condition + ' then\n'; - if (Blockly.Lua.STATEMENT_SUFFIX) { + if (Lua.STATEMENT_SUFFIX) { // Inject any statement suffix here since the regular one at the end // will not get executed if the return is triggered. - code += Blockly.Lua.prefixLines( - Blockly.Lua.injectId(Blockly.Lua.STATEMENT_SUFFIX, block), - Blockly.Lua.INDENT); + code += Lua.prefixLines( + Lua.injectId(Lua.STATEMENT_SUFFIX, block), + Lua.INDENT); } if (block.hasReturnValue_) { - const value = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || 'nil'; - code += Blockly.Lua.INDENT + 'return ' + value + '\n'; + const value = Lua.valueToCode(block, 'VALUE', + Lua.ORDER_NONE) || 'nil'; + code += Lua.INDENT + 'return ' + value + '\n'; } else { - code += Blockly.Lua.INDENT + 'return\n'; + code += Lua.INDENT + 'return\n'; } code += 'end\n'; return code; diff --git a/generators/lua/text.js b/generators/lua/text.js index 035df30fcd5..11274bcd54f 100644 --- a/generators/lua/text.js +++ b/generators/lua/text.js @@ -9,86 +9,87 @@ */ 'use strict'; -goog.provide('Blockly.Lua.texts'); +goog.module('Blockly.Lua.texts'); -goog.require('Blockly.Lua'); +const Blockly = goog.require('Blockly'); +const Lua = goog.require('Blockly.Lua'); -Blockly.Lua['text'] = function(block) { +Lua['text'] = function(block) { // Text value. - const code = Blockly.Lua.quote_(block.getFieldValue('TEXT')); - return [code, Blockly.Lua.ORDER_ATOMIC]; + const code = Lua.quote_(block.getFieldValue('TEXT')); + return [code, Lua.ORDER_ATOMIC]; }; -Blockly.Lua['text_multiline'] = function(block) { +Lua['text_multiline'] = function(block) { // Text value. - const code = Blockly.Lua.multiline_quote_(block.getFieldValue('TEXT')); - const order = code.indexOf('..') !== -1 ? Blockly.Lua.ORDER_CONCATENATION : - Blockly.Lua.ORDER_ATOMIC; + const code = Lua.multiline_quote_(block.getFieldValue('TEXT')); + const order = code.indexOf('..') !== -1 ? Lua.ORDER_CONCATENATION : + Lua.ORDER_ATOMIC; return [code, order]; }; -Blockly.Lua['text_join'] = function(block) { +Lua['text_join'] = function(block) { // Create a string made up of any number of elements of any type. if (block.itemCount_ === 0) { - return ['\'\'', Blockly.Lua.ORDER_ATOMIC]; + return ['\'\'', Lua.ORDER_ATOMIC]; } else if (block.itemCount_ === 1) { - const element = Blockly.Lua.valueToCode(block, 'ADD0', - Blockly.Lua.ORDER_NONE) || '\'\''; + const element = Lua.valueToCode(block, 'ADD0', + Lua.ORDER_NONE) || '\'\''; const code = 'tostring(' + element + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; } else if (block.itemCount_ === 2) { - const element0 = Blockly.Lua.valueToCode(block, 'ADD0', - Blockly.Lua.ORDER_CONCATENATION) || '\'\''; - const element1 = Blockly.Lua.valueToCode(block, 'ADD1', - Blockly.Lua.ORDER_CONCATENATION) || '\'\''; + const element0 = Lua.valueToCode(block, 'ADD0', + Lua.ORDER_CONCATENATION) || '\'\''; + const element1 = Lua.valueToCode(block, 'ADD1', + Lua.ORDER_CONCATENATION) || '\'\''; const code = element0 + ' .. ' + element1; - return [code, Blockly.Lua.ORDER_CONCATENATION]; + return [code, Lua.ORDER_CONCATENATION]; } else { const elements = []; for (let i = 0; i < block.itemCount_; i++) { - elements[i] = Blockly.Lua.valueToCode(block, 'ADD' + i, - Blockly.Lua.ORDER_NONE) || '\'\''; + elements[i] = Lua.valueToCode(block, 'ADD' + i, + Lua.ORDER_NONE) || '\'\''; } const code = 'table.concat({' + elements.join(', ') + '})'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; } }; -Blockly.Lua['text_append'] = function(block) { +Lua['text_append'] = function(block) { // Append to a variable in place. - const varName = Blockly.Lua.nameDB_.getName( + const varName = Lua.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const value = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_CONCATENATION) || '\'\''; + const value = Lua.valueToCode(block, 'TEXT', + Lua.ORDER_CONCATENATION) || '\'\''; return varName + ' = ' + varName + ' .. ' + value + '\n'; }; -Blockly.Lua['text_length'] = function(block) { +Lua['text_length'] = function(block) { // String or array length. - const text = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_UNARY) || '\'\''; - return ['#' + text, Blockly.Lua.ORDER_UNARY]; + const text = Lua.valueToCode(block, 'VALUE', + Lua.ORDER_UNARY) || '\'\''; + return ['#' + text, Lua.ORDER_UNARY]; }; -Blockly.Lua['text_isEmpty'] = function(block) { +Lua['text_isEmpty'] = function(block) { // Is the string null or array empty? - const text = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_UNARY) || '\'\''; - return ['#' + text + ' == 0', Blockly.Lua.ORDER_RELATIONAL]; + const text = Lua.valueToCode(block, 'VALUE', + Lua.ORDER_UNARY) || '\'\''; + return ['#' + text + ' == 0', Lua.ORDER_RELATIONAL]; }; -Blockly.Lua['text_indexOf'] = function(block) { +Lua['text_indexOf'] = function(block) { // Search the text for a substring. - const substring = Blockly.Lua.valueToCode(block, 'FIND', - Blockly.Lua.ORDER_NONE) || '\'\''; - const text = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || '\'\''; + const substring = Lua.valueToCode(block, 'FIND', + Lua.ORDER_NONE) || '\'\''; + const text = Lua.valueToCode(block, 'VALUE', + Lua.ORDER_NONE) || '\'\''; let functionName; if (block.getFieldValue('END') === 'FIRST') { - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'firstIndexOf', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str, substr) ', ' local i = string.find(str, substr, 1, true)', ' if i == nil then', @@ -98,9 +99,9 @@ Blockly.Lua['text_indexOf'] = function(block) { ' end', 'end']); } else { - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'lastIndexOf', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str, substr)', ' local i = string.find(string.reverse(str), ' + 'string.reverse(substr), 1, true)', @@ -111,23 +112,23 @@ Blockly.Lua['text_indexOf'] = function(block) { 'end']); } const code = functionName + '(' + text + ', ' + substring + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['text_charAt'] = function(block) { +Lua['text_charAt'] = function(block) { // Get letter at index. // Note: Until January 2013 this block did not have the WHERE input. const where = block.getFieldValue('WHERE') || 'FROM_START'; - const atOrder = (where === 'FROM_END') ? Blockly.Lua.ORDER_UNARY : - Blockly.Lua.ORDER_NONE; - const at = Blockly.Lua.valueToCode(block, 'AT', atOrder) || '1'; - const text = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || '\'\''; + const atOrder = (where === 'FROM_END') ? Lua.ORDER_UNARY : + Lua.ORDER_NONE; + const at = Lua.valueToCode(block, 'AT', atOrder) || '1'; + const text = Lua.valueToCode(block, 'VALUE', + Lua.ORDER_NONE) || '\'\''; let code; if (where === 'RANDOM') { - const functionName = Blockly.Lua.provideFunction_( + const functionName = Lua.provideFunction_( 'text_random_letter', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str)', ' local index = math.random(string.len(str))', ' return string.sub(str, index, index)', 'end']); @@ -151,28 +152,28 @@ Blockly.Lua['text_charAt'] = function(block) { code = 'string.sub(' + text + ', ' + start + ', ' + start + ')'; } else { // use function to avoid reevaluation - const functionName = Blockly.Lua.provideFunction_( + const functionName = Lua.provideFunction_( 'text_char_at', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str, index)', ' return string.sub(str, index, index)', 'end']); code = functionName + '(' + text + ', ' + start + ')'; } } - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['text_getSubstring'] = function(block) { +Lua['text_getSubstring'] = function(block) { // Get substring. - const text = Blockly.Lua.valueToCode(block, 'STRING', - Blockly.Lua.ORDER_NONE) || '\'\''; + const text = Lua.valueToCode(block, 'STRING', + Lua.ORDER_NONE) || '\'\''; // Get start index. const where1 = block.getFieldValue('WHERE1'); - const at1Order = (where1 === 'FROM_END') ? Blockly.Lua.ORDER_UNARY : - Blockly.Lua.ORDER_NONE; - const at1 = Blockly.Lua.valueToCode(block, 'AT1', at1Order) || '1'; + const at1Order = (where1 === 'FROM_END') ? Lua.ORDER_UNARY : + Lua.ORDER_NONE; + const at1 = Lua.valueToCode(block, 'AT1', at1Order) || '1'; let start; if (where1 === 'FIRST') { start = 1; @@ -186,9 +187,9 @@ Blockly.Lua['text_getSubstring'] = function(block) { // Get end index. const where2 = block.getFieldValue('WHERE2'); - const at2Order = (where2 === 'FROM_END') ? Blockly.Lua.ORDER_UNARY : - Blockly.Lua.ORDER_NONE; - const at2 = Blockly.Lua.valueToCode(block, 'AT2', at2Order) || '1'; + const at2Order = (where2 === 'FROM_END') ? Lua.ORDER_UNARY : + Lua.ORDER_NONE; + const at2 = Lua.valueToCode(block, 'AT2', at2Order) || '1'; let end; if (where2 === 'LAST') { end = -1; @@ -200,26 +201,26 @@ Blockly.Lua['text_getSubstring'] = function(block) { throw Error('Unhandled option (text_getSubstring)'); } const code = 'string.sub(' + text + ', ' + start + ', ' + end + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['text_changeCase'] = function(block) { +Lua['text_changeCase'] = function(block) { // Change capitalization. const operator = block.getFieldValue('CASE'); - const text = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; + const text = Lua.valueToCode(block, 'TEXT', + Lua.ORDER_NONE) || '\'\''; let functionName; if (operator === 'UPPERCASE') { functionName = 'string.upper'; } else if (operator === 'LOWERCASE') { functionName = 'string.lower'; } else if (operator === 'TITLECASE') { - functionName = Blockly.Lua.provideFunction_( + functionName = Lua.provideFunction_( 'text_titlecase', // There are shorter versions at // http://lua-users.org/wiki/SciteTitleCase // that do not preserve whitespace. - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str)', ' local buf = {}', ' local inWord = false', ' for i = 1, #str do', @@ -238,10 +239,10 @@ Blockly.Lua['text_changeCase'] = function(block) { 'end']); } const code = functionName + '(' + text + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['text_trim'] = function(block) { +Lua['text_trim'] = function(block) { // Trim spaces. const OPERATORS = { LEFT: '^%s*(,-)', @@ -249,34 +250,34 @@ Blockly.Lua['text_trim'] = function(block) { BOTH: '^%s*(.-)%s*$' }; const operator = OPERATORS[block.getFieldValue('MODE')]; - const text = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; + const text = Lua.valueToCode(block, 'TEXT', + Lua.ORDER_NONE) || '\'\''; const code = 'string.gsub(' + text + ', "' + operator + '", "%1")'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['text_print'] = function(block) { +Lua['text_print'] = function(block) { // Print statement. - const msg = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; + const msg = Lua.valueToCode(block, 'TEXT', + Lua.ORDER_NONE) || '\'\''; return 'print(' + msg + ')\n'; }; -Blockly.Lua['text_prompt_ext'] = function(block) { +Lua['text_prompt_ext'] = function(block) { // Prompt function. let msg; if (block.getField('TEXT')) { // Internal message. - msg = Blockly.Lua.quote_(block.getFieldValue('TEXT')); + msg = Lua.quote_(block.getFieldValue('TEXT')); } else { // External message. - msg = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; + msg = Lua.valueToCode(block, 'TEXT', + Lua.ORDER_NONE) || '\'\''; } - const functionName = Blockly.Lua.provideFunction_( + const functionName = Lua.provideFunction_( 'text_prompt', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(msg)', + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(msg)', ' io.write(msg)', ' io.flush()', ' return io.read()', @@ -287,19 +288,19 @@ Blockly.Lua['text_prompt_ext'] = function(block) { if (toNumber) { code = 'tonumber(' + code + ', 10)'; } - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['text_prompt'] = Blockly.Lua['text_prompt_ext']; +Lua['text_prompt'] = Lua['text_prompt_ext']; -Blockly.Lua['text_count'] = function(block) { - const text = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; - const sub = Blockly.Lua.valueToCode(block, 'SUB', - Blockly.Lua.ORDER_NONE) || '\'\''; - const functionName = Blockly.Lua.provideFunction_( +Lua['text_count'] = function(block) { + const text = Lua.valueToCode(block, 'TEXT', + Lua.ORDER_NONE) || '\'\''; + const sub = Lua.valueToCode(block, 'SUB', + Lua.ORDER_NONE) || '\'\''; + const functionName = Lua.provideFunction_( 'text_count', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(haystack, needle)', ' if #needle == 0 then', ' return #haystack + 1', @@ -318,19 +319,19 @@ Blockly.Lua['text_count'] = function(block) { 'end', ]); const code = functionName + '(' + text + ', ' + sub + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['text_replace'] = function(block) { - const text = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; - const from = Blockly.Lua.valueToCode(block, 'FROM', - Blockly.Lua.ORDER_NONE) || '\'\''; - const to = Blockly.Lua.valueToCode(block, 'TO', - Blockly.Lua.ORDER_NONE) || '\'\''; - const functionName = Blockly.Lua.provideFunction_( +Lua['text_replace'] = function(block) { + const text = Lua.valueToCode(block, 'TEXT', + Lua.ORDER_NONE) || '\'\''; + const from = Lua.valueToCode(block, 'FROM', + Lua.ORDER_NONE) || '\'\''; + const to = Lua.valueToCode(block, 'TO', + Lua.ORDER_NONE) || '\'\''; + const functionName = Lua.provideFunction_( 'text_replace', - ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + ['function ' + Lua.FUNCTION_NAME_PLACEHOLDER_ + '(haystack, needle, replacement)', ' local buf = {}', ' local i = 1', @@ -349,12 +350,12 @@ Blockly.Lua['text_replace'] = function(block) { 'end', ]); const code = functionName + '(' + text + ', ' + from + ', ' + to + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; -Blockly.Lua['text_reverse'] = function(block) { - const text = Blockly.Lua.valueToCode(block, 'TEXT', - Blockly.Lua.ORDER_NONE) || '\'\''; +Lua['text_reverse'] = function(block) { + const text = Lua.valueToCode(block, 'TEXT', + Lua.ORDER_NONE) || '\'\''; const code = 'string.reverse(' + text + ')'; - return [code, Blockly.Lua.ORDER_HIGH]; + return [code, Lua.ORDER_HIGH]; }; diff --git a/generators/lua/variables.js b/generators/lua/variables.js index c623984ee5b..43b725075f6 100644 --- a/generators/lua/variables.js +++ b/generators/lua/variables.js @@ -9,23 +9,24 @@ */ 'use strict'; -goog.provide('Blockly.Lua.variables'); +goog.module('Blockly.Lua.variables'); -goog.require('Blockly.Lua'); +const Blockly = goog.require('Blockly'); +const Lua = goog.require('Blockly.Lua'); -Blockly.Lua['variables_get'] = function(block) { +Lua['variables_get'] = function(block) { // Variable getter. - const code = Blockly.Lua.nameDB_.getName(block.getFieldValue('VAR'), + const code = Lua.nameDB_.getName(block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - return [code, Blockly.Lua.ORDER_ATOMIC]; + return [code, Lua.ORDER_ATOMIC]; }; -Blockly.Lua['variables_set'] = function(block) { +Lua['variables_set'] = function(block) { // Variable setter. - const argument0 = Blockly.Lua.valueToCode(block, 'VALUE', - Blockly.Lua.ORDER_NONE) || '0'; - const varName = Blockly.Lua.nameDB_.getName( + const argument0 = Lua.valueToCode(block, 'VALUE', + Lua.ORDER_NONE) || '0'; + const varName = Lua.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); return varName + ' = ' + argument0 + '\n'; }; diff --git a/generators/lua/variables_dynamic.js b/generators/lua/variables_dynamic.js index 4f729a33a46..6dd6ed66abe 100644 --- a/generators/lua/variables_dynamic.js +++ b/generators/lua/variables_dynamic.js @@ -9,12 +9,13 @@ */ 'use strict'; -goog.provide('Blockly.Lua.variablesDynamic'); +goog.module('Blockly.Lua.variablesDynamic'); -goog.require('Blockly.Lua'); -goog.require('Blockly.Lua.variables'); +const Lua = goog.require('Blockly.Lua'); +// Require for side effects. +const variables = goog.require('Blockly.Lua.variables'); // Lua is dynamically typed. -Blockly.Lua['variables_get_dynamic'] = Blockly.Lua['variables_get']; -Blockly.Lua['variables_set_dynamic'] = Blockly.Lua['variables_set']; +Lua['variables_get_dynamic'] = Lua['variables_get']; +Lua['variables_set_dynamic'] = Lua['variables_set']; diff --git a/generators/php.js b/generators/php.js index 9541657da44..836db1964e5 100644 --- a/generators/php.js +++ b/generators/php.js @@ -9,19 +9,24 @@ */ 'use strict'; -goog.provide('Blockly.PHP'); +goog.module('Blockly.PHP'); +goog.module.declareLegacyNamespace(); -goog.require('Blockly.Generator'); -goog.require('Blockly.inputTypes'); -goog.require('Blockly.utils.object'); -goog.require('Blockly.utils.string'); +const Blockly = goog.require('Blockly'); +const {Generator} = goog.require('Blockly.Generator'); +const {inputTypes} = goog.require('Blockly.inputTypes'); +const objectUtils = goog.require('Blockly.utils.object'); +const stringUtils = goog.require('Blockly.utils.string'); +const {Names} = goog.require('Blockly.Names'); +const {Workspace} = goog.requireType('Blockly.Workspace'); +const {Block} = goog.requireType('Blockly.Block'); /** * PHP code generator. - * @type {!Blockly.Generator} + * @type {!Generator} */ -Blockly.PHP = new Blockly.Generator('PHP'); +const PHP = new Generator('PHP'); /** * List of illegal variable names. @@ -30,7 +35,7 @@ Blockly.PHP = new Blockly.Generator('PHP'); * accidentally clobbering a built-in object or function. * @private */ -Blockly.PHP.addReservedWords( +PHP.addReservedWords( // http://php.net/manual/en/reserved.keywords.php '__halt_compiler,abstract,and,array,as,break,callable,case,catch,class,' + 'clone,const,continue,declare,default,die,do,echo,else,elseif,empty,' + @@ -57,83 +62,83 @@ Blockly.PHP.addReservedWords( * Order of operation ENUMs. * http://php.net/manual/en/language.operators.precedence.php */ -Blockly.PHP.ORDER_ATOMIC = 0; // 0 "" ... -Blockly.PHP.ORDER_CLONE = 1; // clone -Blockly.PHP.ORDER_NEW = 1; // new -Blockly.PHP.ORDER_MEMBER = 2.1; // [] -Blockly.PHP.ORDER_FUNCTION_CALL = 2.2; // () -Blockly.PHP.ORDER_POWER = 3; // ** -Blockly.PHP.ORDER_INCREMENT = 4; // ++ -Blockly.PHP.ORDER_DECREMENT = 4; // -- -Blockly.PHP.ORDER_BITWISE_NOT = 4; // ~ -Blockly.PHP.ORDER_CAST = 4; // (int) (float) (string) (array) ... -Blockly.PHP.ORDER_SUPPRESS_ERROR = 4; // @ -Blockly.PHP.ORDER_INSTANCEOF = 5; // instanceof -Blockly.PHP.ORDER_LOGICAL_NOT = 6; // ! -Blockly.PHP.ORDER_UNARY_PLUS = 7.1; // + -Blockly.PHP.ORDER_UNARY_NEGATION = 7.2; // - -Blockly.PHP.ORDER_MULTIPLICATION = 8.1; // * -Blockly.PHP.ORDER_DIVISION = 8.2; // / -Blockly.PHP.ORDER_MODULUS = 8.3; // % -Blockly.PHP.ORDER_ADDITION = 9.1; // + -Blockly.PHP.ORDER_SUBTRACTION = 9.2; // - -Blockly.PHP.ORDER_STRING_CONCAT = 9.3; // . -Blockly.PHP.ORDER_BITWISE_SHIFT = 10; // << >> -Blockly.PHP.ORDER_RELATIONAL = 11; // < <= > >= -Blockly.PHP.ORDER_EQUALITY = 12; // == != === !== <> <=> -Blockly.PHP.ORDER_REFERENCE = 13; // & -Blockly.PHP.ORDER_BITWISE_AND = 13; // & -Blockly.PHP.ORDER_BITWISE_XOR = 14; // ^ -Blockly.PHP.ORDER_BITWISE_OR = 15; // | -Blockly.PHP.ORDER_LOGICAL_AND = 16; // && -Blockly.PHP.ORDER_LOGICAL_OR = 17; // || -Blockly.PHP.ORDER_IF_NULL = 18; // ?? -Blockly.PHP.ORDER_CONDITIONAL = 19; // ?: -Blockly.PHP.ORDER_ASSIGNMENT = 20; // = += -= *= /= %= <<= >>= ... -Blockly.PHP.ORDER_LOGICAL_AND_WEAK = 21; // and -Blockly.PHP.ORDER_LOGICAL_XOR = 22; // xor -Blockly.PHP.ORDER_LOGICAL_OR_WEAK = 23; // or -Blockly.PHP.ORDER_NONE = 99; // (...) +PHP.ORDER_ATOMIC = 0; // 0 "" ... +PHP.ORDER_CLONE = 1; // clone +PHP.ORDER_NEW = 1; // new +PHP.ORDER_MEMBER = 2.1; // [] +PHP.ORDER_FUNCTION_CALL = 2.2; // () +PHP.ORDER_POWER = 3; // ** +PHP.ORDER_INCREMENT = 4; // ++ +PHP.ORDER_DECREMENT = 4; // -- +PHP.ORDER_BITWISE_NOT = 4; // ~ +PHP.ORDER_CAST = 4; // (int) (float) (string) (array) ... +PHP.ORDER_SUPPRESS_ERROR = 4; // @ +PHP.ORDER_INSTANCEOF = 5; // instanceof +PHP.ORDER_LOGICAL_NOT = 6; // ! +PHP.ORDER_UNARY_PLUS = 7.1; // + +PHP.ORDER_UNARY_NEGATION = 7.2; // - +PHP.ORDER_MULTIPLICATION = 8.1; // * +PHP.ORDER_DIVISION = 8.2; // / +PHP.ORDER_MODULUS = 8.3; // % +PHP.ORDER_ADDITION = 9.1; // + +PHP.ORDER_SUBTRACTION = 9.2; // - +PHP.ORDER_STRING_CONCAT = 9.3; // . +PHP.ORDER_BITWISE_SHIFT = 10; // << >> +PHP.ORDER_RELATIONAL = 11; // < <= > >= +PHP.ORDER_EQUALITY = 12; // == != === !== <> <=> +PHP.ORDER_REFERENCE = 13; // & +PHP.ORDER_BITWISE_AND = 13; // & +PHP.ORDER_BITWISE_XOR = 14; // ^ +PHP.ORDER_BITWISE_OR = 15; // | +PHP.ORDER_LOGICAL_AND = 16; // && +PHP.ORDER_LOGICAL_OR = 17; // || +PHP.ORDER_IF_NULL = 18; // ?? +PHP.ORDER_CONDITIONAL = 19; // ?: +PHP.ORDER_ASSIGNMENT = 20; // = += -= *= /= %= <<= >>= ... +PHP.ORDER_LOGICAL_AND_WEAK = 21; // and +PHP.ORDER_LOGICAL_XOR = 22; // xor +PHP.ORDER_LOGICAL_OR_WEAK = 23; // or +PHP.ORDER_NONE = 99; // (...) /** * List of outer-inner pairings that do NOT require parentheses. * @type {!Array>} */ -Blockly.PHP.ORDER_OVERRIDES = [ +PHP.ORDER_OVERRIDES = [ // (foo()).bar() -> foo().bar() // (foo())[0] -> foo()[0] - [Blockly.PHP.ORDER_MEMBER, Blockly.PHP.ORDER_FUNCTION_CALL], + [PHP.ORDER_MEMBER, PHP.ORDER_FUNCTION_CALL], // (foo[0])[1] -> foo[0][1] // (foo.bar).baz -> foo.bar.baz - [Blockly.PHP.ORDER_MEMBER, Blockly.PHP.ORDER_MEMBER], + [PHP.ORDER_MEMBER, PHP.ORDER_MEMBER], // !(!foo) -> !!foo - [Blockly.PHP.ORDER_LOGICAL_NOT, Blockly.PHP.ORDER_LOGICAL_NOT], + [PHP.ORDER_LOGICAL_NOT, PHP.ORDER_LOGICAL_NOT], // a * (b * c) -> a * b * c - [Blockly.PHP.ORDER_MULTIPLICATION, Blockly.PHP.ORDER_MULTIPLICATION], + [PHP.ORDER_MULTIPLICATION, PHP.ORDER_MULTIPLICATION], // a + (b + c) -> a + b + c - [Blockly.PHP.ORDER_ADDITION, Blockly.PHP.ORDER_ADDITION], + [PHP.ORDER_ADDITION, PHP.ORDER_ADDITION], // a && (b && c) -> a && b && c - [Blockly.PHP.ORDER_LOGICAL_AND, Blockly.PHP.ORDER_LOGICAL_AND], + [PHP.ORDER_LOGICAL_AND, PHP.ORDER_LOGICAL_AND], // a || (b || c) -> a || b || c - [Blockly.PHP.ORDER_LOGICAL_OR, Blockly.PHP.ORDER_LOGICAL_OR] + [PHP.ORDER_LOGICAL_OR, PHP.ORDER_LOGICAL_OR] ]; /** * Whether the init method has been called. * @type {?boolean} */ -Blockly.PHP.isInitialized = false; +PHP.isInitialized = false; /** * Initialise the database of variable names. - * @param {!Blockly.Workspace} workspace Workspace to generate code from. + * @param {!Workspace} workspace Workspace to generate code from. */ -Blockly.PHP.init = function(workspace) { +PHP.init = function(workspace) { // Call Blockly.Generator's init. Object.getPrototypeOf(this).init.call(this); if (!this.nameDB_) { - this.nameDB_ = new Blockly.Names(this.RESERVED_WORDS_, '$'); + this.nameDB_ = new Names(this.RESERVED_WORDS_, '$'); } else { this.nameDB_.reset(); } @@ -150,9 +155,9 @@ Blockly.PHP.init = function(workspace) { * @param {string} code Generated code. * @return {string} Completed code. */ -Blockly.PHP.finish = function(code) { +PHP.finish = function(code) { // Convert the definitions dictionary into a list. - const definitions = Blockly.utils.object.values(this.definitions_); + const definitions = objectUtils.values(this.definitions_); // Call Blockly.Generator's finish. code = Object.getPrototypeOf(this).finish.call(this, code); this.isInitialized = false; @@ -167,7 +172,7 @@ Blockly.PHP.finish = function(code) { * @param {string} line Line of generated code. * @return {string} Legal line of code. */ -Blockly.PHP.scrubNakedValue = function(line) { +PHP.scrubNakedValue = function(line) { return line + ';\n'; }; @@ -178,7 +183,7 @@ Blockly.PHP.scrubNakedValue = function(line) { * @return {string} PHP string. * @protected */ -Blockly.PHP.quote_ = function(string) { +PHP.quote_ = function(string) { string = string.replace(/\\/g, '\\\\') .replace(/\n/g, '\\\n') .replace(/'/g, '\\\''); @@ -192,7 +197,7 @@ Blockly.PHP.quote_ = function(string) { * @return {string} PHP string. * @protected */ -Blockly.PHP.multiline_quote_ = function (string) { +PHP.multiline_quote_ = function (string) { const lines = string.split(/\n/g).map(this.quote_); // Join with the following, plus a newline: // . "\n" . @@ -204,26 +209,26 @@ Blockly.PHP.multiline_quote_ = function (string) { * Common tasks for generating PHP 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 {!Block} block The current block. * @param {string} code The PHP code created for this block. * @param {boolean=} opt_thisOnly True to generate code for only this statement. * @return {string} PHP code with comments and subsequent blocks added. * @protected */ -Blockly.PHP.scrub_ = function(block, code, opt_thisOnly) { +PHP.scrub_ = function(block, code, opt_thisOnly) { let 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) { - comment = Blockly.utils.string.wrap(comment, this.COMMENT_WRAP - 3); + comment = stringUtils.wrap(comment, this.COMMENT_WRAP - 3); commentCode += this.prefixLines(comment, '// ') + '\n'; } // Collect comments for all value arguments. // Don't collect comments for nested statements. for (let i = 0; i < block.inputList.length; i++) { - if (block.inputList[i].type === Blockly.inputTypes.VALUE) { + if (block.inputList[i].type === inputTypes.VALUE) { const childBlock = block.inputList[i].connection.targetBlock(); if (childBlock) { comment = this.allNestedComments(childBlock); @@ -241,14 +246,14 @@ Blockly.PHP.scrub_ = function(block, code, opt_thisOnly) { /** * Gets a property and adjusts the value while taking into account indexing. - * @param {!Blockly.Block} block The block. + * @param {!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. * @param {number=} opt_order The highest order acting on this value. * @return {string|number} */ -Blockly.PHP.getAdjusted = function(block, atId, opt_delta, opt_negate, +PHP.getAdjusted = function(block, atId, opt_delta, opt_negate, opt_order) { let delta = opt_delta || 0; let order = opt_order || this.ORDER_NONE; @@ -298,3 +303,5 @@ Blockly.PHP.getAdjusted = function(block, atId, opt_delta, opt_negate, } return at; }; + +exports = PHP; diff --git a/generators/php/colour.js b/generators/php/colour.js index 59e55e7f1af..a5e6c6d2feb 100644 --- a/generators/php/colour.js +++ b/generators/php/colour.js @@ -9,40 +9,40 @@ */ 'use strict'; -goog.provide('Blockly.PHP.colour'); +goog.module('Blockly.PHP.colour'); -goog.require('Blockly.PHP'); +const PHP = goog.require('Blockly.PHP'); -Blockly.PHP['colour_picker'] = function(block) { +PHP['colour_picker'] = function(block) { // Colour picker. - const code = Blockly.PHP.quote_(block.getFieldValue('COLOUR')); - return [code, Blockly.PHP.ORDER_ATOMIC]; + const code = PHP.quote_(block.getFieldValue('COLOUR')); + return [code, PHP.ORDER_ATOMIC]; }; -Blockly.PHP['colour_random'] = function(block) { +PHP['colour_random'] = function(block) { // Generate a random colour. - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'colour_random', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {', + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {', ' return \'#\' . str_pad(dechex(mt_rand(0, 0xFFFFFF)), ' + '6, \'0\', STR_PAD_LEFT);', '}']); const code = functionName + '()'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['colour_rgb'] = function(block) { +PHP['colour_rgb'] = function(block) { // Compose a colour from RGB components expressed as percentages. - const red = Blockly.PHP.valueToCode(block, 'RED', - Blockly.PHP.ORDER_NONE) || 0; - const green = Blockly.PHP.valueToCode(block, 'GREEN', - Blockly.PHP.ORDER_NONE) || 0; - const blue = Blockly.PHP.valueToCode(block, 'BLUE', - Blockly.PHP.ORDER_NONE) || 0; - const functionName = Blockly.PHP.provideFunction_( + const red = PHP.valueToCode(block, 'RED', + PHP.ORDER_NONE) || 0; + const green = PHP.valueToCode(block, 'GREEN', + PHP.ORDER_NONE) || 0; + const blue = PHP.valueToCode(block, 'BLUE', + PHP.ORDER_NONE) || 0; + const functionName = PHP.provideFunction_( 'colour_rgb', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($r, $g, $b) {', ' $r = round(max(min($r, 100), 0) * 2.55);', ' $g = round(max(min($g, 100), 0) * 2.55);', @@ -54,20 +54,20 @@ Blockly.PHP['colour_rgb'] = function(block) { ' return $hex;', '}']); const code = functionName + '(' + red + ', ' + green + ', ' + blue + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['colour_blend'] = function(block) { +PHP['colour_blend'] = function(block) { // Blend two colours together. - const c1 = Blockly.PHP.valueToCode(block, 'COLOUR1', - Blockly.PHP.ORDER_NONE) || '\'#000000\''; - const c2 = Blockly.PHP.valueToCode(block, 'COLOUR2', - Blockly.PHP.ORDER_NONE) || '\'#000000\''; - const ratio = Blockly.PHP.valueToCode(block, 'RATIO', - Blockly.PHP.ORDER_NONE) || 0.5; - const functionName = Blockly.PHP.provideFunction_( + const c1 = PHP.valueToCode(block, 'COLOUR1', + PHP.ORDER_NONE) || '\'#000000\''; + const c2 = PHP.valueToCode(block, 'COLOUR2', + PHP.ORDER_NONE) || '\'#000000\''; + const ratio = PHP.valueToCode(block, 'RATIO', + PHP.ORDER_NONE) || 0.5; + const functionName = PHP.provideFunction_( 'colour_blend', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($c1, $c2, $ratio) {', ' $ratio = max(min($ratio, 1), 0);', ' $r1 = hexdec(substr($c1, 1, 2));', @@ -86,5 +86,5 @@ Blockly.PHP['colour_blend'] = function(block) { ' return $hex;', '}']); const code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; diff --git a/generators/php/lists.js b/generators/php/lists.js index bb27d6d835c..27eebd1f9b6 100644 --- a/generators/php/lists.js +++ b/generators/php/lists.js @@ -20,32 +20,33 @@ */ 'use strict'; -goog.provide('Blockly.PHP.lists'); +goog.module('Blockly.PHP.lists'); -goog.require('Blockly.PHP'); +const Blockly = goog.require('Blockly'); +const PHP = goog.require('Blockly.PHP'); -Blockly.PHP['lists_create_empty'] = function(block) { +PHP['lists_create_empty'] = function(block) { // Create an empty list. - return ['array()', Blockly.PHP.ORDER_FUNCTION_CALL]; + return ['array()', PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['lists_create_with'] = function(block) { +PHP['lists_create_with'] = function(block) { // Create a list with any number of elements of any type. let code = new Array(block.itemCount_); for (let i = 0; i < block.itemCount_; i++) { - code[i] = Blockly.PHP.valueToCode(block, 'ADD' + i, - Blockly.PHP.ORDER_NONE) || 'null'; + code[i] = PHP.valueToCode(block, 'ADD' + i, + PHP.ORDER_NONE) || 'null'; } code = 'array(' + code.join(', ') + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['lists_repeat'] = function(block) { +PHP['lists_repeat'] = function(block) { // Create a list with one element repeated. - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'lists_repeat', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value, $count) {', ' $array = array();', ' for ($index = 0; $index < $count; $index++) {', @@ -53,43 +54,43 @@ Blockly.PHP['lists_repeat'] = function(block) { ' }', ' return $array;', '}']); - const element = Blockly.PHP.valueToCode(block, 'ITEM', - Blockly.PHP.ORDER_NONE) || 'null'; - const repeatCount = Blockly.PHP.valueToCode(block, 'NUM', - Blockly.PHP.ORDER_NONE) || '0'; + const element = PHP.valueToCode(block, 'ITEM', + PHP.ORDER_NONE) || 'null'; + const repeatCount = PHP.valueToCode(block, 'NUM', + PHP.ORDER_NONE) || '0'; const code = functionName + '(' + element + ', ' + repeatCount + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['lists_length'] = function(block) { +PHP['lists_length'] = function(block) { // String or array length. - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'length', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {', + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {', ' if (is_string($value)) {', ' return strlen($value);', ' } else {', ' return count($value);', ' }', '}']); - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || '\'\''; - return [functionName + '(' + list + ')', Blockly.PHP.ORDER_FUNCTION_CALL]; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || '\'\''; + return [functionName + '(' + list + ')', PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['lists_isEmpty'] = function(block) { +PHP['lists_isEmpty'] = function(block) { // Is the string null or array empty? - const argument0 = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()'; - return ['empty(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL]; + const argument0 = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_FUNCTION_CALL) || 'array()'; + return ['empty(' + argument0 + ')', PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['lists_indexOf'] = function(block) { +PHP['lists_indexOf'] = function(block) { // Find an item in the list. - const argument0 = Blockly.PHP.valueToCode(block, 'FIND', - Blockly.PHP.ORDER_NONE) || '\'\''; - const argument1 = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_MEMBER) || '[]'; + const argument0 = PHP.valueToCode(block, 'FIND', + PHP.ORDER_NONE) || '\'\''; + const argument1 = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_MEMBER) || '[]'; let errorIndex = ' -1'; let indexAdjustment = ''; if (block.workspace.options.oneBasedIndex) { @@ -99,9 +100,9 @@ Blockly.PHP['lists_indexOf'] = function(block) { let functionName; if (block.getFieldValue('END') === 'FIRST') { // indexOf - functionName = Blockly.PHP.provideFunction_( + functionName = PHP.provideFunction_( 'indexOf', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($haystack, $needle) {', ' for ($index = 0; $index < count($haystack); $index++) {', ' if ($haystack[$index] == $needle) return $index' + @@ -111,9 +112,9 @@ Blockly.PHP['lists_indexOf'] = function(block) { '}']); } else { // lastIndexOf - functionName = Blockly.PHP.provideFunction_( + functionName = PHP.provideFunction_( 'lastIndexOf', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($haystack, $needle) {', ' $last = ' + errorIndex + ';', ' for ($index = 0; $index < count($haystack); $index++) {', @@ -125,115 +126,115 @@ Blockly.PHP['lists_indexOf'] = function(block) { } const code = functionName + '(' + argument1 + ', ' + argument0 + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['lists_getIndex'] = function(block) { +PHP['lists_getIndex'] = function(block) { // Get element at index. const mode = block.getFieldValue('MODE') || 'GET'; const where = block.getFieldValue('WHERE') || 'FROM_START'; switch (where) { case 'FIRST': if (mode === 'GET') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_MEMBER) || 'array()'; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_MEMBER) || 'array()'; const code = list + '[0]'; - return [code, Blockly.PHP.ORDER_MEMBER]; + return [code, PHP.ORDER_MEMBER]; } else if (mode === 'GET_REMOVE') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'array()'; const code = 'array_shift(' + list + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'array()'; return 'array_shift(' + list + ');\n'; } break; case 'LAST': if (mode === 'GET') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'array()'; const code = 'end(' + list + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } else if (mode === 'GET_REMOVE') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'array()'; const code = 'array_pop(' + list + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'array()'; return 'array_pop(' + list + ');\n'; } break; case 'FROM_START': { - const at = Blockly.PHP.getAdjusted(block, 'AT'); + const at = PHP.getAdjusted(block, 'AT'); if (mode === 'GET') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_MEMBER) || 'array()'; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_MEMBER) || 'array()'; const code = list + '[' + at + ']'; - return [code, Blockly.PHP.ORDER_MEMBER]; + return [code, PHP.ORDER_MEMBER]; } else if (mode === 'GET_REMOVE') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'array()'; const code = 'array_splice(' + list + ', ' + at + ', 1)[0]'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'array()'; return 'array_splice(' + list + ', ' + at + ', 1);\n'; } break; } case 'FROM_END': if (mode === 'GET') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'array()'; - const at = Blockly.PHP.getAdjusted(block, 'AT', 1, true); + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'array()'; + const at = PHP.getAdjusted(block, 'AT', 1, true); const code = 'array_slice(' + list + ', ' + at + ', 1)[0]'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } else if (mode === 'GET_REMOVE' || mode === 'REMOVE') { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'array()'; - const at = Blockly.PHP.getAdjusted(block, 'AT', 1, false, - Blockly.PHP.ORDER_SUBTRACTION); + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'array()'; + const at = PHP.getAdjusted(block, 'AT', 1, false, + PHP.ORDER_SUBTRACTION); const code = 'array_splice(' + list + ', count(' + list + ') - ' + at + ', 1)[0]'; if (mode === 'GET_REMOVE') { - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { return code + ';\n'; } } break; case 'RANDOM': { - const list = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'array()'; if (mode === 'GET') { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'lists_get_random_item', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($list) {', ' return $list[rand(0,count($list)-1)];', '}']); const code = functionName + '(' + list + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } else if (mode === 'GET_REMOVE') { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'lists_get_remove_random_item', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '(&$list) {', ' $x = rand(0,count($list)-1);', ' unset($list[$x]);', ' return array_values($list);', '}']); const code = functionName + '(' + list + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'lists_remove_random_item', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '(&$list) {', ' unset($list[rand(0,count($list)-1)]);', '}']); @@ -245,13 +246,13 @@ Blockly.PHP['lists_getIndex'] = function(block) { throw Error('Unhandled combination (lists_getIndex).'); }; -Blockly.PHP['lists_setIndex'] = function(block) { +PHP['lists_setIndex'] = function(block) { // Set element at index. // Note: Until February 2013 this block did not have MODE or WHERE inputs. const mode = block.getFieldValue('MODE') || 'GET'; const where = block.getFieldValue('WHERE') || 'FROM_START'; - const value = Blockly.PHP.valueToCode(block, 'TO', - Blockly.PHP.ORDER_ASSIGNMENT) || 'null'; + const value = PHP.valueToCode(block, 'TO', + PHP.ORDER_ASSIGNMENT) || 'null'; // Cache non-trivial values to variables to prevent repeated look-ups. // Closure, which accesses and modifies 'list'. let cachedList; @@ -259,7 +260,7 @@ Blockly.PHP['lists_setIndex'] = function(block) { if (cachedList.match(/^\$\w+$/)) { return ''; } - const listVar = Blockly.PHP.nameDB_.getDistinctName( + const listVar = PHP.nameDB_.getDistinctName( 'tmp_list', Blockly.VARIABLE_CATEGORY_NAME); const code = listVar + ' = &' + cachedList + ';\n'; cachedList = listVar; @@ -268,22 +269,22 @@ Blockly.PHP['lists_setIndex'] = function(block) { switch (where) { case 'FIRST': if (mode === 'SET') { - const list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_MEMBER) || 'array()'; + const list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_MEMBER) || 'array()'; return list + '[0] = ' + value + ';\n'; } else if (mode === 'INSERT') { - const list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || 'array()'; return 'array_unshift(' + list + ', ' + value + ');\n'; } break; case 'LAST': { - const list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || 'array()'; if (mode === 'SET') { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'lists_set_last_item', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '(&$list, $value) {', ' $list[count($list) - 1] = $value;', '}']); @@ -294,34 +295,34 @@ Blockly.PHP['lists_setIndex'] = function(block) { break; } case 'FROM_START': { - const at = Blockly.PHP.getAdjusted(block, 'AT'); + const at = PHP.getAdjusted(block, 'AT'); if (mode === 'SET') { - const list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_MEMBER) || 'array()'; + const list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_MEMBER) || 'array()'; return list + '[' + at + '] = ' + value + ';\n'; } else if (mode === 'INSERT') { - const list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || 'array()'; return 'array_splice(' + list + ', ' + at + ', 0, ' + value + ');\n'; } break; } case 'FROM_END': { - const list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || 'array()'; - const at = Blockly.PHP.getAdjusted(block, 'AT', 1); + const list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || 'array()'; + const at = PHP.getAdjusted(block, 'AT', 1); if (mode === 'SET') { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'lists_set_from_end', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '(&$list, $at, $value) {', ' $list[count($list) - $at] = $value;', '}']); return functionName + '(' + list + ', ' + at + ', ' + value + ');\n'; } else if (mode === 'INSERT') { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'lists_insert_from_end', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '(&$list, $at, $value) {', ' return array_splice($list, count($list) - $at, 0, $value);', '}']); @@ -330,11 +331,11 @@ Blockly.PHP['lists_setIndex'] = function(block) { break; } case 'RANDOM': - cachedList = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_REFERENCE) || 'array()'; + cachedList = PHP.valueToCode(block, 'LIST', + PHP.ORDER_REFERENCE) || 'array()'; let code = cacheList(); const list = cachedList; - const xVar = Blockly.PHP.nameDB_.getDistinctName( + const xVar = PHP.nameDB_.getDistinctName( 'tmp_x', Blockly.VARIABLE_CATEGORY_NAME); code += xVar + ' = rand(0, count(' + list + ')-1);\n'; if (mode === 'SET') { @@ -350,10 +351,10 @@ Blockly.PHP['lists_setIndex'] = function(block) { throw Error('Unhandled combination (lists_setIndex).'); }; -Blockly.PHP['lists_getSublist'] = function(block) { +PHP['lists_getSublist'] = function(block) { // Get sublist. - const list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || 'array()'; + const list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || 'array()'; const where1 = block.getFieldValue('WHERE1'); const where2 = block.getFieldValue('WHERE2'); let code; @@ -366,11 +367,11 @@ Blockly.PHP['lists_getSublist'] = function(block) { let at1; switch (where1) { case 'FROM_START': - at1 = Blockly.PHP.getAdjusted(block, 'AT1'); + at1 = PHP.getAdjusted(block, 'AT1'); break; case 'FROM_END': - at1 = Blockly.PHP.getAdjusted(block, 'AT1', 1, false, - Blockly.PHP.ORDER_SUBTRACTION); + at1 = PHP.getAdjusted(block, 'AT1', 1, false, + PHP.ORDER_SUBTRACTION); at1 = 'count(' + list + ') - ' + at1; break; case 'FIRST': @@ -383,8 +384,8 @@ Blockly.PHP['lists_getSublist'] = function(block) { let length; switch (where2) { case 'FROM_START': - at2 = Blockly.PHP.getAdjusted(block, 'AT2', 0, false, - Blockly.PHP.ORDER_SUBTRACTION); + at2 = PHP.getAdjusted(block, 'AT2', 0, false, + PHP.ORDER_SUBTRACTION); length = at2 + ' - '; if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) { length += at1; @@ -394,8 +395,8 @@ Blockly.PHP['lists_getSublist'] = function(block) { length += ' + 1'; break; case 'FROM_END': - at2 = Blockly.PHP.getAdjusted(block, 'AT2', 0, false, - Blockly.PHP.ORDER_SUBTRACTION); + at2 = PHP.getAdjusted(block, 'AT2', 0, false, + PHP.ORDER_SUBTRACTION); length = 'count(' + list + ') - ' + at2 + ' - '; if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) { length += at1; @@ -416,11 +417,11 @@ Blockly.PHP['lists_getSublist'] = function(block) { } code = 'array_slice(' + list + ', ' + at1 + ', ' + length + ')'; } else { - const at1 = Blockly.PHP.getAdjusted(block, 'AT1'); - const at2 = Blockly.PHP.getAdjusted(block, 'AT2'); - const functionName = Blockly.PHP.provideFunction_( + const at1 = PHP.getAdjusted(block, 'AT1'); + const at2 = PHP.getAdjusted(block, 'AT2'); + const functionName = PHP.provideFunction_( 'lists_get_sublist', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($list, $where1, $at1, $where2, $at2) {', ' if ($where1 == \'FROM_END\') {', ' $at1 = count($list) - 1 - $at1;', @@ -444,18 +445,18 @@ Blockly.PHP['lists_getSublist'] = function(block) { code = functionName + '(' + list + ', \'' + where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')'; } - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['lists_sort'] = function(block) { +PHP['lists_sort'] = function(block) { // Block for sorting a list. - const listCode = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || 'array()'; + const listCode = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || 'array()'; const direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1; const type = block.getFieldValue('TYPE'); - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'lists_sort', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($list, $type, $direction) {', ' $sortCmpFuncs = array(', ' "NUMERIC" => "strnatcasecmp",', @@ -472,15 +473,15 @@ Blockly.PHP['lists_sort'] = function(block) { '}']); const sortCode = functionName + '(' + listCode + ', "' + type + '", ' + direction + ')'; - return [sortCode, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [sortCode, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['lists_split'] = function(block) { +PHP['lists_split'] = function(block) { // Block for splitting text into a list, or joining a list into text. - let value_input = Blockly.PHP.valueToCode(block, 'INPUT', - Blockly.PHP.ORDER_NONE); - const value_delim = Blockly.PHP.valueToCode(block, 'DELIM', - Blockly.PHP.ORDER_NONE) || '\'\''; + let value_input = PHP.valueToCode(block, 'INPUT', + PHP.ORDER_NONE); + const value_delim = PHP.valueToCode(block, 'DELIM', + PHP.ORDER_NONE) || '\'\''; const mode = block.getFieldValue('MODE'); let functionName; if (mode === 'SPLIT') { @@ -497,13 +498,13 @@ Blockly.PHP['lists_split'] = function(block) { throw Error('Unknown mode: ' + mode); } const code = functionName + '(' + value_delim + ', ' + value_input + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['lists_reverse'] = function(block) { +PHP['lists_reverse'] = function(block) { // Block for reversing a list. - const list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || '[]'; + const list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || '[]'; const code = 'array_reverse(' + list + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; diff --git a/generators/php/logic.js b/generators/php/logic.js index de632f1fe59..9d352cf531b 100644 --- a/generators/php/logic.js +++ b/generators/php/logic.js @@ -9,48 +9,48 @@ */ 'use strict'; -goog.provide('Blockly.PHP.logic'); +goog.module('Blockly.PHP.logic'); -goog.require('Blockly.PHP'); +const PHP = goog.require('Blockly.PHP'); -Blockly.PHP['controls_if'] = function(block) { +PHP['controls_if'] = function(block) { // If/elseif/else condition. let n = 0; let code = '', branchCode, conditionCode; - if (Blockly.PHP.STATEMENT_PREFIX) { + if (PHP.STATEMENT_PREFIX) { // Automatic prefix insertion is switched off for this block. Add manually. - code += Blockly.PHP.injectId(Blockly.PHP.STATEMENT_PREFIX, block); + code += PHP.injectId(PHP.STATEMENT_PREFIX, block); } do { - conditionCode = Blockly.PHP.valueToCode(block, 'IF' + n, - Blockly.PHP.ORDER_NONE) || 'false'; - branchCode = Blockly.PHP.statementToCode(block, 'DO' + n); - if (Blockly.PHP.STATEMENT_SUFFIX) { - branchCode = Blockly.PHP.prefixLines( - Blockly.PHP.injectId(Blockly.PHP.STATEMENT_SUFFIX, block), - Blockly.PHP.INDENT) + branchCode; + conditionCode = PHP.valueToCode(block, 'IF' + n, + PHP.ORDER_NONE) || 'false'; + branchCode = PHP.statementToCode(block, 'DO' + n); + if (PHP.STATEMENT_SUFFIX) { + branchCode = PHP.prefixLines( + PHP.injectId(PHP.STATEMENT_SUFFIX, block), + PHP.INDENT) + branchCode; } code += (n > 0 ? ' else ' : '') + 'if (' + conditionCode + ') {\n' + branchCode + '}'; n++; } while (block.getInput('IF' + n)); - if (block.getInput('ELSE') || Blockly.PHP.STATEMENT_SUFFIX) { - branchCode = Blockly.PHP.statementToCode(block, 'ELSE'); - if (Blockly.PHP.STATEMENT_SUFFIX) { - branchCode = Blockly.PHP.prefixLines( - Blockly.PHP.injectId(Blockly.PHP.STATEMENT_SUFFIX, block), - Blockly.PHP.INDENT) + branchCode; + if (block.getInput('ELSE') || PHP.STATEMENT_SUFFIX) { + branchCode = PHP.statementToCode(block, 'ELSE'); + if (PHP.STATEMENT_SUFFIX) { + branchCode = PHP.prefixLines( + PHP.injectId(PHP.STATEMENT_SUFFIX, block), + PHP.INDENT) + branchCode; } code += ' else {\n' + branchCode + '}'; } return code + '\n'; }; -Blockly.PHP['controls_ifelse'] = Blockly.PHP['controls_if']; +PHP['controls_ifelse'] = PHP['controls_if']; -Blockly.PHP['logic_compare'] = function(block) { +PHP['logic_compare'] = function(block) { // Comparison operator. const OPERATORS = { 'EQ': '==', @@ -62,20 +62,20 @@ Blockly.PHP['logic_compare'] = function(block) { }; const operator = OPERATORS[block.getFieldValue('OP')]; const order = (operator === '==' || operator === '!=') ? - Blockly.PHP.ORDER_EQUALITY : Blockly.PHP.ORDER_RELATIONAL; - const argument0 = Blockly.PHP.valueToCode(block, 'A', order) || '0'; - const argument1 = Blockly.PHP.valueToCode(block, 'B', order) || '0'; + PHP.ORDER_EQUALITY : PHP.ORDER_RELATIONAL; + const argument0 = PHP.valueToCode(block, 'A', order) || '0'; + const argument1 = PHP.valueToCode(block, 'B', order) || '0'; const code = argument0 + ' ' + operator + ' ' + argument1; return [code, order]; }; -Blockly.PHP['logic_operation'] = function(block) { +PHP['logic_operation'] = function(block) { // Operations 'and', 'or'. const operator = (block.getFieldValue('OP') === 'AND') ? '&&' : '||'; - const order = (operator === '&&') ? Blockly.PHP.ORDER_LOGICAL_AND : - Blockly.PHP.ORDER_LOGICAL_OR; - let argument0 = Blockly.PHP.valueToCode(block, 'A', order); - let argument1 = Blockly.PHP.valueToCode(block, 'B', order); + const order = (operator === '&&') ? PHP.ORDER_LOGICAL_AND : + PHP.ORDER_LOGICAL_OR; + let argument0 = PHP.valueToCode(block, 'A', order); + let argument1 = PHP.valueToCode(block, 'B', order); if (!argument0 && !argument1) { // If there are no arguments, then the return value is false. argument0 = 'false'; @@ -94,34 +94,34 @@ Blockly.PHP['logic_operation'] = function(block) { return [code, order]; }; -Blockly.PHP['logic_negate'] = function(block) { +PHP['logic_negate'] = function(block) { // Negation. - const order = Blockly.PHP.ORDER_LOGICAL_NOT; - const argument0 = Blockly.PHP.valueToCode(block, 'BOOL', order) || + const order = PHP.ORDER_LOGICAL_NOT; + const argument0 = PHP.valueToCode(block, 'BOOL', order) || 'true'; const code = '!' + argument0; return [code, order]; }; -Blockly.PHP['logic_boolean'] = function(block) { +PHP['logic_boolean'] = function(block) { // Boolean values true and false. const code = (block.getFieldValue('BOOL') === 'TRUE') ? 'true' : 'false'; - return [code, Blockly.PHP.ORDER_ATOMIC]; + return [code, PHP.ORDER_ATOMIC]; }; -Blockly.PHP['logic_null'] = function(block) { +PHP['logic_null'] = function(block) { // Null data type. - return ['null', Blockly.PHP.ORDER_ATOMIC]; + return ['null', PHP.ORDER_ATOMIC]; }; -Blockly.PHP['logic_ternary'] = function(block) { +PHP['logic_ternary'] = function(block) { // Ternary operator. - const value_if = Blockly.PHP.valueToCode(block, 'IF', - Blockly.PHP.ORDER_CONDITIONAL) || 'false'; - const value_then = Blockly.PHP.valueToCode(block, 'THEN', - Blockly.PHP.ORDER_CONDITIONAL) || 'null'; - const value_else = Blockly.PHP.valueToCode(block, 'ELSE', - Blockly.PHP.ORDER_CONDITIONAL) || 'null'; + const value_if = PHP.valueToCode(block, 'IF', + PHP.ORDER_CONDITIONAL) || 'false'; + const value_then = PHP.valueToCode(block, 'THEN', + PHP.ORDER_CONDITIONAL) || 'null'; + const value_else = PHP.valueToCode(block, 'ELSE', + PHP.ORDER_CONDITIONAL) || 'null'; const code = value_if + ' ? ' + value_then + ' : ' + value_else; - return [code, Blockly.PHP.ORDER_CONDITIONAL]; + return [code, PHP.ORDER_CONDITIONAL]; }; diff --git a/generators/php/loops.js b/generators/php/loops.js index efc38f65408..ad17e521b29 100644 --- a/generators/php/loops.js +++ b/generators/php/loops.js @@ -9,12 +9,14 @@ */ 'use strict'; -goog.provide('Blockly.PHP.loops'); +goog.module('Blockly.PHP.loops'); -goog.require('Blockly.PHP'); +const Blockly = goog.require('Blockly'); +const Loops = goog.require('Blockly.Constants.Loops'); +const PHP = goog.require('Blockly.PHP'); -Blockly.PHP['controls_repeat_ext'] = function(block) { +PHP['controls_repeat_ext'] = function(block) { // Repeat n times. let repeats; if (block.getField('TIMES')) { @@ -22,17 +24,17 @@ Blockly.PHP['controls_repeat_ext'] = function(block) { repeats = String(Number(block.getFieldValue('TIMES'))); } else { // External number. - repeats = Blockly.PHP.valueToCode(block, 'TIMES', - Blockly.PHP.ORDER_ASSIGNMENT) || '0'; + repeats = PHP.valueToCode(block, 'TIMES', + PHP.ORDER_ASSIGNMENT) || '0'; } - let branch = Blockly.PHP.statementToCode(block, 'DO'); - branch = Blockly.PHP.addLoopTrap(branch, block); + let branch = PHP.statementToCode(block, 'DO'); + branch = PHP.addLoopTrap(branch, block); let code = ''; - const loopVar = Blockly.PHP.nameDB_.getDistinctName( + const loopVar = PHP.nameDB_.getDistinctName( 'count', Blockly.VARIABLE_CATEGORY_NAME); let endVar = repeats; if (!repeats.match(/^\w+$/) && !Blockly.isNumber(repeats)) { - endVar = Blockly.PHP.nameDB_.getDistinctName( + endVar = PHP.nameDB_.getDistinctName( 'repeat_end', Blockly.VARIABLE_CATEGORY_NAME); code += endVar + ' = ' + repeats + ';\n'; } @@ -43,34 +45,34 @@ Blockly.PHP['controls_repeat_ext'] = function(block) { return code; }; -Blockly.PHP['controls_repeat'] = Blockly.PHP['controls_repeat_ext']; +PHP['controls_repeat'] = PHP['controls_repeat_ext']; -Blockly.PHP['controls_whileUntil'] = function(block) { +PHP['controls_whileUntil'] = function(block) { // Do while/until loop. const until = block.getFieldValue('MODE') === 'UNTIL'; - let argument0 = Blockly.PHP.valueToCode(block, 'BOOL', - until ? Blockly.PHP.ORDER_LOGICAL_NOT : - Blockly.PHP.ORDER_NONE) || 'false'; - let branch = Blockly.PHP.statementToCode(block, 'DO'); - branch = Blockly.PHP.addLoopTrap(branch, block); + let argument0 = PHP.valueToCode(block, 'BOOL', + until ? PHP.ORDER_LOGICAL_NOT : + PHP.ORDER_NONE) || 'false'; + let branch = PHP.statementToCode(block, 'DO'); + branch = PHP.addLoopTrap(branch, block); if (until) { argument0 = '!' + argument0; } return 'while (' + argument0 + ') {\n' + branch + '}\n'; }; -Blockly.PHP['controls_for'] = function(block) { +PHP['controls_for'] = function(block) { // For loop. - const variable0 = Blockly.PHP.nameDB_.getName( + const variable0 = PHP.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const argument0 = Blockly.PHP.valueToCode(block, 'FROM', - Blockly.PHP.ORDER_ASSIGNMENT) || '0'; - const argument1 = Blockly.PHP.valueToCode(block, 'TO', - Blockly.PHP.ORDER_ASSIGNMENT) || '0'; - const increment = Blockly.PHP.valueToCode(block, 'BY', - Blockly.PHP.ORDER_ASSIGNMENT) || '1'; - let branch = Blockly.PHP.statementToCode(block, 'DO'); - branch = Blockly.PHP.addLoopTrap(branch, block); + const argument0 = PHP.valueToCode(block, 'FROM', + PHP.ORDER_ASSIGNMENT) || '0'; + const argument1 = PHP.valueToCode(block, 'TO', + PHP.ORDER_ASSIGNMENT) || '0'; + const increment = PHP.valueToCode(block, 'BY', + PHP.ORDER_ASSIGNMENT) || '1'; + let branch = PHP.statementToCode(block, 'DO'); + branch = PHP.addLoopTrap(branch, block); let code; if (Blockly.isNumber(argument0) && Blockly.isNumber(argument1) && Blockly.isNumber(increment)) { @@ -91,19 +93,19 @@ Blockly.PHP['controls_for'] = function(block) { // Cache non-trivial values to variables to prevent repeated look-ups. let startVar = argument0; if (!argument0.match(/^\w+$/) && !Blockly.isNumber(argument0)) { - startVar = Blockly.PHP.nameDB_.getDistinctName( + startVar = PHP.nameDB_.getDistinctName( variable0 + '_start', Blockly.VARIABLE_CATEGORY_NAME); code += startVar + ' = ' + argument0 + ';\n'; } let endVar = argument1; if (!argument1.match(/^\w+$/) && !Blockly.isNumber(argument1)) { - endVar = Blockly.PHP.nameDB_.getDistinctName( + endVar = PHP.nameDB_.getDistinctName( variable0 + '_end', Blockly.VARIABLE_CATEGORY_NAME); code += endVar + ' = ' + argument1 + ';\n'; } // Determine loop direction at start, in case one of the bounds // changes during loop execution. - const incVar = Blockly.PHP.nameDB_.getDistinctName( + const incVar = PHP.nameDB_.getDistinctName( variable0 + '_inc', Blockly.VARIABLE_CATEGORY_NAME); code += incVar + ' = '; if (Blockly.isNumber(increment)) { @@ -112,7 +114,7 @@ Blockly.PHP['controls_for'] = function(block) { code += 'abs(' + increment + ');\n'; } code += 'if (' + startVar + ' > ' + endVar + ') {\n'; - code += Blockly.PHP.INDENT + incVar + ' = -' + incVar + ';\n'; + code += PHP.INDENT + incVar + ' = -' + incVar + ';\n'; code += '}\n'; code += 'for (' + variable0 + ' = ' + startVar + '; ' + incVar + ' >= 0 ? ' + @@ -124,40 +126,39 @@ Blockly.PHP['controls_for'] = function(block) { return code; }; -Blockly.PHP['controls_forEach'] = function(block) { +PHP['controls_forEach'] = function(block) { // For each loop. - const variable0 = Blockly.PHP.nameDB_.getName( + const variable0 = PHP.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const argument0 = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_ASSIGNMENT) || '[]'; - let branch = Blockly.PHP.statementToCode(block, 'DO'); - branch = Blockly.PHP.addLoopTrap(branch, block); + const argument0 = PHP.valueToCode(block, 'LIST', + PHP.ORDER_ASSIGNMENT) || '[]'; + let branch = PHP.statementToCode(block, 'DO'); + branch = PHP.addLoopTrap(branch, block); let code = ''; code += 'foreach (' + argument0 + ' as ' + variable0 + ') {\n' + branch + '}\n'; return code; }; -Blockly.PHP['controls_flow_statements'] = function(block) { +PHP['controls_flow_statements'] = function(block) { // Flow statements: continue, break. let xfix = ''; - if (Blockly.PHP.STATEMENT_PREFIX) { + if (PHP.STATEMENT_PREFIX) { // Automatic prefix insertion is switched off for this block. Add manually. - xfix += Blockly.PHP.injectId(Blockly.PHP.STATEMENT_PREFIX, block); + xfix += PHP.injectId(PHP.STATEMENT_PREFIX, block); } - if (Blockly.PHP.STATEMENT_SUFFIX) { + if (PHP.STATEMENT_SUFFIX) { // Inject any statement suffix here since the regular one at the end // will not get executed if the break/continue is triggered. - xfix += Blockly.PHP.injectId(Blockly.PHP.STATEMENT_SUFFIX, block); + xfix += PHP.injectId(PHP.STATEMENT_SUFFIX, block); } - if (Blockly.PHP.STATEMENT_PREFIX) { - const loop = Blockly.Constants.Loops - .CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); + if (PHP.STATEMENT_PREFIX) { + const loop = Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); if (loop && !loop.suppressPrefixSuffix) { // Inject loop's statement prefix here since the regular one at the end // of the loop will not get executed if 'continue' is triggered. // In the case of 'break', a prefix is needed due to the loop's suffix. - xfix += Blockly.PHP.injectId(Blockly.PHP.STATEMENT_PREFIX, loop); + xfix += PHP.injectId(PHP.STATEMENT_PREFIX, loop); } } switch (block.getFieldValue('FLOW')) { diff --git a/generators/php/math.js b/generators/php/math.js index a442ca7ab6d..72c1e27cae3 100644 --- a/generators/php/math.js +++ b/generators/php/math.js @@ -9,16 +9,17 @@ */ 'use strict'; -goog.provide('Blockly.PHP.math'); +goog.module('Blockly.PHP.math'); -goog.require('Blockly.PHP'); +const Blockly = goog.require('Blockly'); +const PHP = goog.require('Blockly.PHP'); -Blockly.PHP['math_number'] = function(block) { +PHP['math_number'] = function(block) { // Numeric value. let code = Number(block.getFieldValue('NUM')); - const order = code >= 0 ? Blockly.PHP.ORDER_ATOMIC : - Blockly.PHP.ORDER_UNARY_NEGATION; + const order = code >= 0 ? PHP.ORDER_ATOMIC : + PHP.ORDER_UNARY_NEGATION; if (code === Infinity) { code = 'INF'; } else if (code === -Infinity) { @@ -27,46 +28,46 @@ Blockly.PHP['math_number'] = function(block) { return [code, order]; }; -Blockly.PHP['math_arithmetic'] = function(block) { +PHP['math_arithmetic'] = function(block) { // Basic arithmetic operators, and power. const OPERATORS = { - 'ADD': [' + ', Blockly.PHP.ORDER_ADDITION], - 'MINUS': [' - ', Blockly.PHP.ORDER_SUBTRACTION], - 'MULTIPLY': [' * ', Blockly.PHP.ORDER_MULTIPLICATION], - 'DIVIDE': [' / ', Blockly.PHP.ORDER_DIVISION], - 'POWER': [' ** ', Blockly.PHP.ORDER_POWER] + 'ADD': [' + ', PHP.ORDER_ADDITION], + 'MINUS': [' - ', PHP.ORDER_SUBTRACTION], + 'MULTIPLY': [' * ', PHP.ORDER_MULTIPLICATION], + 'DIVIDE': [' / ', PHP.ORDER_DIVISION], + 'POWER': [' ** ', PHP.ORDER_POWER] }; const tuple = OPERATORS[block.getFieldValue('OP')]; const operator = tuple[0]; const order = tuple[1]; - const argument0 = Blockly.PHP.valueToCode(block, 'A', order) || '0'; - const argument1 = Blockly.PHP.valueToCode(block, 'B', order) || '0'; + const argument0 = PHP.valueToCode(block, 'A', order) || '0'; + const argument1 = PHP.valueToCode(block, 'B', order) || '0'; const code = argument0 + operator + argument1; return [code, order]; }; -Blockly.PHP['math_single'] = function(block) { +PHP['math_single'] = function(block) { // Math operators with single operand. const operator = block.getFieldValue('OP'); let code; let arg; if (operator === 'NEG') { // Negation is a special case given its different operator precedence. - arg = Blockly.PHP.valueToCode(block, 'NUM', - Blockly.PHP.ORDER_UNARY_NEGATION) || '0'; + arg = PHP.valueToCode(block, 'NUM', + PHP.ORDER_UNARY_NEGATION) || '0'; if (arg[0] === '-') { // --3 is not legal in JS. arg = ' ' + arg; } code = '-' + arg; - return [code, Blockly.PHP.ORDER_UNARY_NEGATION]; + return [code, PHP.ORDER_UNARY_NEGATION]; } if (operator === 'SIN' || operator === 'COS' || operator === 'TAN') { - arg = Blockly.PHP.valueToCode(block, 'NUM', - Blockly.PHP.ORDER_DIVISION) || '0'; + arg = PHP.valueToCode(block, 'NUM', + PHP.ORDER_DIVISION) || '0'; } else { - arg = Blockly.PHP.valueToCode(block, 'NUM', - Blockly.PHP.ORDER_NONE) || '0'; + arg = PHP.valueToCode(block, 'NUM', + PHP.ORDER_NONE) || '0'; } // First, handle cases which generate values that don't need parentheses // wrapping the code. @@ -106,7 +107,7 @@ Blockly.PHP['math_single'] = function(block) { break; } if (code) { - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } // Second, handle cases which generate values that may need parentheses // wrapping the code. @@ -126,34 +127,34 @@ Blockly.PHP['math_single'] = function(block) { default: throw Error('Unknown math operator: ' + operator); } - return [code, Blockly.PHP.ORDER_DIVISION]; + return [code, PHP.ORDER_DIVISION]; }; -Blockly.PHP['math_constant'] = function(block) { +PHP['math_constant'] = function(block) { // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY. const CONSTANTS = { - 'PI': ['M_PI', Blockly.PHP.ORDER_ATOMIC], - 'E': ['M_E', Blockly.PHP.ORDER_ATOMIC], - 'GOLDEN_RATIO': ['(1 + sqrt(5)) / 2', Blockly.PHP.ORDER_DIVISION], - 'SQRT2': ['M_SQRT2', Blockly.PHP.ORDER_ATOMIC], - 'SQRT1_2': ['M_SQRT1_2', Blockly.PHP.ORDER_ATOMIC], - 'INFINITY': ['INF', Blockly.PHP.ORDER_ATOMIC] + 'PI': ['M_PI', PHP.ORDER_ATOMIC], + 'E': ['M_E', PHP.ORDER_ATOMIC], + 'GOLDEN_RATIO': ['(1 + sqrt(5)) / 2', PHP.ORDER_DIVISION], + 'SQRT2': ['M_SQRT2', PHP.ORDER_ATOMIC], + 'SQRT1_2': ['M_SQRT1_2', PHP.ORDER_ATOMIC], + 'INFINITY': ['INF', PHP.ORDER_ATOMIC] }; return CONSTANTS[block.getFieldValue('CONSTANT')]; }; -Blockly.PHP['math_number_property'] = function(block) { +PHP['math_number_property'] = function(block) { // Check if a number is even, odd, prime, whole, positive, or negative // or if it is divisible by certain number. Returns true or false. - const number_to_check = Blockly.PHP.valueToCode(block, 'NUMBER_TO_CHECK', - Blockly.PHP.ORDER_MODULUS) || '0'; + const number_to_check = PHP.valueToCode(block, 'NUMBER_TO_CHECK', + PHP.ORDER_MODULUS) || '0'; const dropdown_property = block.getFieldValue('PROPERTY'); let code; if (dropdown_property === 'PRIME') { // Prime is a special case as it is not a one-liner test. - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'math_isPrime', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($n) {', + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($n) {', ' // https://en.wikipedia.org/wiki/Primality_test#Naive_methods', ' if ($n == 2 || $n == 3) {', ' return true;', @@ -173,7 +174,7 @@ Blockly.PHP['math_number_property'] = function(block) { ' return true;', '}']); code = functionName + '(' + number_to_check + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } switch (dropdown_property) { case 'EVEN': @@ -192,74 +193,74 @@ Blockly.PHP['math_number_property'] = function(block) { code = number_to_check + ' < 0'; break; case 'DIVISIBLE_BY': { - const divisor = Blockly.PHP.valueToCode(block, 'DIVISOR', - Blockly.PHP.ORDER_MODULUS) || '0'; + const divisor = PHP.valueToCode(block, 'DIVISOR', + PHP.ORDER_MODULUS) || '0'; code = number_to_check + ' % ' + divisor + ' == 0'; break; } } - return [code, Blockly.PHP.ORDER_EQUALITY]; + return [code, PHP.ORDER_EQUALITY]; }; -Blockly.PHP['math_change'] = function(block) { +PHP['math_change'] = function(block) { // Add to a variable in place. - const argument0 = Blockly.PHP.valueToCode(block, 'DELTA', - Blockly.PHP.ORDER_ADDITION) || '0'; - const varName = Blockly.PHP.nameDB_.getName( + const argument0 = PHP.valueToCode(block, 'DELTA', + PHP.ORDER_ADDITION) || '0'; + const varName = PHP.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); return varName + ' += ' + argument0 + ';\n'; }; // Rounding functions have a single operand. -Blockly.PHP['math_round'] = Blockly.PHP['math_single']; +PHP['math_round'] = PHP['math_single']; // Trigonometry functions have a single operand. -Blockly.PHP['math_trig'] = Blockly.PHP['math_single']; +PHP['math_trig'] = PHP['math_single']; -Blockly.PHP['math_on_list'] = function(block) { +PHP['math_on_list'] = function(block) { // Math functions for lists. const func = block.getFieldValue('OP'); let list; let code; switch (func) { case 'SUM': - list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()'; + list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_FUNCTION_CALL) || 'array()'; code = 'array_sum(' + list + ')'; break; case 'MIN': - list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()'; + list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_FUNCTION_CALL) || 'array()'; code = 'min(' + list + ')'; break; case 'MAX': - list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()'; + list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_FUNCTION_CALL) || 'array()'; code = 'max(' + list + ')'; break; case 'AVERAGE': { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'math_mean', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($myList) {', ' return array_sum($myList) / count($myList);', '}']); - list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || 'array()'; + list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || 'array()'; code = functionName + '(' + list + ')'; break; } case 'MEDIAN': { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'math_median', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($arr) {', ' sort($arr,SORT_NUMERIC);', ' return (count($arr) % 2) ? $arr[floor(count($arr)/2)] : ', ' ($arr[floor(count($arr)/2)] + $arr[floor(count($arr)/2)' + ' - 1]) / 2;', '}']); - list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || '[]'; + list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || '[]'; code = functionName + '(' + list + ')'; break; } @@ -267,9 +268,9 @@ Blockly.PHP['math_on_list'] = function(block) { // 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]. - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'math_modes', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($values) {', ' if (empty($values)) return array();', ' $counts = array_count_values($values);', @@ -277,15 +278,15 @@ Blockly.PHP['math_on_list'] = function(block) { ' $modes = array_keys($counts, current($counts), true);', ' return $modes;', '}']); - list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || '[]'; + list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || '[]'; code = functionName + '(' + list + ')'; break; } case 'STD_DEV': { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'math_standard_deviation', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($numbers) {', ' $n = count($numbers);', ' if (!$n) return null;', @@ -294,62 +295,62 @@ Blockly.PHP['math_on_list'] = function(block) { 'pow($num - $mean, 2);', ' return sqrt(array_sum($devs) / (count($devs) - 1));', '}']); - list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || '[]'; + list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || '[]'; code = functionName + '(' + list + ')'; break; } case 'RANDOM': { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'math_random_list', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($list) {', ' $x = rand(0, count($list)-1);', ' return $list[$x];', '}']); - list = Blockly.PHP.valueToCode(block, 'LIST', - Blockly.PHP.ORDER_NONE) || '[]'; + list = PHP.valueToCode(block, 'LIST', + PHP.ORDER_NONE) || '[]'; code = functionName + '(' + list + ')'; break; } default: throw Error('Unknown operator: ' + func); } - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['math_modulo'] = function(block) { +PHP['math_modulo'] = function(block) { // Remainder computation. - const argument0 = Blockly.PHP.valueToCode(block, 'DIVIDEND', - Blockly.PHP.ORDER_MODULUS) || '0'; - const argument1 = Blockly.PHP.valueToCode(block, 'DIVISOR', - Blockly.PHP.ORDER_MODULUS) || '0'; + const argument0 = PHP.valueToCode(block, 'DIVIDEND', + PHP.ORDER_MODULUS) || '0'; + const argument1 = PHP.valueToCode(block, 'DIVISOR', + PHP.ORDER_MODULUS) || '0'; const code = argument0 + ' % ' + argument1; - return [code, Blockly.PHP.ORDER_MODULUS]; + return [code, PHP.ORDER_MODULUS]; }; -Blockly.PHP['math_constrain'] = function(block) { +PHP['math_constrain'] = function(block) { // Constrain a number between two limits. - const argument0 = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || '0'; - const argument1 = Blockly.PHP.valueToCode(block, 'LOW', - Blockly.PHP.ORDER_NONE) || '0'; - const argument2 = Blockly.PHP.valueToCode(block, 'HIGH', - Blockly.PHP.ORDER_NONE) || 'Infinity'; + const argument0 = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || '0'; + const argument1 = PHP.valueToCode(block, 'LOW', + PHP.ORDER_NONE) || '0'; + const argument2 = PHP.valueToCode(block, 'HIGH', + PHP.ORDER_NONE) || 'Infinity'; const code = 'min(max(' + argument0 + ', ' + argument1 + '), ' + argument2 + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['math_random_int'] = function(block) { +PHP['math_random_int'] = function(block) { // Random integer between [X] and [Y]. - const argument0 = Blockly.PHP.valueToCode(block, 'FROM', - Blockly.PHP.ORDER_NONE) || '0'; - const argument1 = Blockly.PHP.valueToCode(block, 'TO', - Blockly.PHP.ORDER_NONE) || '0'; - const functionName = Blockly.PHP.provideFunction_( + const argument0 = PHP.valueToCode(block, 'FROM', + PHP.ORDER_NONE) || '0'; + const argument1 = PHP.valueToCode(block, 'TO', + PHP.ORDER_NONE) || '0'; + const functionName = PHP.provideFunction_( 'math_random_int', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($a, $b) {', ' if ($a > $b) {', ' return rand($b, $a);', @@ -357,20 +358,20 @@ Blockly.PHP['math_random_int'] = function(block) { ' return rand($a, $b);', '}']); const code = functionName + '(' + argument0 + ', ' + argument1 + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['math_random_float'] = function(block) { +PHP['math_random_float'] = function(block) { // Random fraction between 0 and 1. - return ['(float)rand()/(float)getrandmax()', Blockly.PHP.ORDER_FUNCTION_CALL]; + return ['(float)rand()/(float)getrandmax()', PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['math_atan2'] = function(block) { +PHP['math_atan2'] = function(block) { // Arctangent of point (X, Y) in degrees from -180 to 180. - const argument0 = Blockly.PHP.valueToCode(block, 'X', - Blockly.PHP.ORDER_NONE) || '0'; - const argument1 = Blockly.PHP.valueToCode(block, 'Y', - Blockly.PHP.ORDER_NONE) || '0'; + const argument0 = PHP.valueToCode(block, 'X', + PHP.ORDER_NONE) || '0'; + const argument1 = PHP.valueToCode(block, 'Y', + PHP.ORDER_NONE) || '0'; return ['atan2(' + argument1 + ', ' + argument0 + ') / pi() * 180', - Blockly.PHP.ORDER_DIVISION]; + PHP.ORDER_DIVISION]; }; diff --git a/generators/php/procedures.js b/generators/php/procedures.js index 9b7ab47d6ee..39b0dae765c 100644 --- a/generators/php/procedures.js +++ b/generators/php/procedures.js @@ -9,122 +9,125 @@ */ 'use strict'; -goog.provide('Blockly.PHP.procedures'); +goog.module('Blockly.PHP.procedures'); -goog.require('Blockly.PHP'); +const Blockly = goog.require('Blockly'); +const {Names} = goog.require('Blockly.Names'); +const Variables = goog.require('Blockly.Variables'); +const PHP = goog.require('Blockly.PHP'); -Blockly.PHP['procedures_defreturn'] = function(block) { +PHP['procedures_defreturn'] = function(block) { // Define a procedure with a return value. // First, add a 'global' statement for every variable that is not shadowed by // a local parameter. const globals = []; const workspace = block.workspace; - const usedVariables = Blockly.Variables.allUsedVarModels(workspace) || []; + const usedVariables = Variables.allUsedVarModels(workspace) || []; for (let i = 0, variable; variable = usedVariables[i]; i++) { const varName = variable.name; if (block.getVars().indexOf(varName) === -1) { - globals.push(Blockly.PHP.nameDB_.getName(varName, + globals.push(PHP.nameDB_.getName(varName, Blockly.VARIABLE_CATEGORY_NAME)); } } // Add developer variables. - const devVarList = Blockly.Variables.allDeveloperVariables(workspace); + const devVarList = Variables.allDeveloperVariables(workspace); for (let i = 0; i < devVarList.length; i++) { - globals.push(Blockly.PHP.nameDB_.getName(devVarList[i], - Blockly.Names.DEVELOPER_VARIABLE_TYPE)); + globals.push(PHP.nameDB_.getName(devVarList[i], + Names.DEVELOPER_VARIABLE_TYPE)); } const globalStr = globals.length ? - Blockly.PHP.INDENT + 'global ' + globals.join(', ') + ';\n' : ''; + PHP.INDENT + 'global ' + globals.join(', ') + ';\n' : ''; - const funcName = Blockly.PHP.nameDB_.getName( + const funcName = PHP.nameDB_.getName( block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME); let xfix1 = ''; - if (Blockly.PHP.STATEMENT_PREFIX) { - xfix1 += Blockly.PHP.injectId(Blockly.PHP.STATEMENT_PREFIX, block); + if (PHP.STATEMENT_PREFIX) { + xfix1 += PHP.injectId(PHP.STATEMENT_PREFIX, block); } - if (Blockly.PHP.STATEMENT_SUFFIX) { - xfix1 += Blockly.PHP.injectId(Blockly.PHP.STATEMENT_SUFFIX, block); + if (PHP.STATEMENT_SUFFIX) { + xfix1 += PHP.injectId(PHP.STATEMENT_SUFFIX, block); } if (xfix1) { - xfix1 = Blockly.PHP.prefixLines(xfix1, Blockly.PHP.INDENT); + xfix1 = PHP.prefixLines(xfix1, PHP.INDENT); } let loopTrap = ''; - if (Blockly.PHP.INFINITE_LOOP_TRAP) { - loopTrap = Blockly.PHP.prefixLines( - Blockly.PHP.injectId(Blockly.PHP.INFINITE_LOOP_TRAP, block), - Blockly.PHP.INDENT); + if (PHP.INFINITE_LOOP_TRAP) { + loopTrap = PHP.prefixLines( + PHP.injectId(PHP.INFINITE_LOOP_TRAP, block), + PHP.INDENT); } - const branch = Blockly.PHP.statementToCode(block, 'STACK'); - let returnValue = Blockly.PHP.valueToCode(block, 'RETURN', - Blockly.PHP.ORDER_NONE) || ''; + const branch = PHP.statementToCode(block, 'STACK'); + let returnValue = PHP.valueToCode(block, 'RETURN', + PHP.ORDER_NONE) || ''; let xfix2 = ''; if (branch && returnValue) { // After executing the function body, revisit this block for the return. xfix2 = xfix1; } if (returnValue) { - returnValue = Blockly.PHP.INDENT + 'return ' + returnValue + ';\n'; + returnValue = PHP.INDENT + 'return ' + returnValue + ';\n'; } const args = []; const variables = block.getVars(); for (let i = 0; i < variables.length; i++) { - args[i] = Blockly.PHP.nameDB_.getName(variables[i], + args[i] = PHP.nameDB_.getName(variables[i], Blockly.VARIABLE_CATEGORY_NAME); } let code = 'function ' + funcName + '(' + args.join(', ') + ') {\n' + globalStr + xfix1 + loopTrap + branch + xfix2 + returnValue + '}'; - code = Blockly.PHP.scrub_(block, code); + code = PHP.scrub_(block, code); // Add % so as not to collide with helper functions in definitions list. - Blockly.PHP.definitions_['%' + funcName] = code; + PHP.definitions_['%' + funcName] = code; return null; }; // Defining a procedure without a return value uses the same generator as // a procedure with a return value. -Blockly.PHP['procedures_defnoreturn'] = - Blockly.PHP['procedures_defreturn']; +PHP['procedures_defnoreturn'] = + PHP['procedures_defreturn']; -Blockly.PHP['procedures_callreturn'] = function(block) { +PHP['procedures_callreturn'] = function(block) { // Call a procedure with a return value. - const funcName = Blockly.PHP.nameDB_.getName( + const funcName = PHP.nameDB_.getName( block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME); const args = []; const variables = block.getVars(); for (let i = 0; i < variables.length; i++) { - args[i] = Blockly.PHP.valueToCode(block, 'ARG' + i, - Blockly.PHP.ORDER_NONE) || 'null'; + args[i] = PHP.valueToCode(block, 'ARG' + i, + PHP.ORDER_NONE) || 'null'; } const code = funcName + '(' + args.join(', ') + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['procedures_callnoreturn'] = function(block) { +PHP['procedures_callnoreturn'] = function(block) { // Call a procedure with no return value. // Generated code is for a function call as a statement is the same as a // function call as a value, with the addition of line ending. - const tuple = Blockly.PHP['procedures_callreturn'](block); + const tuple = PHP['procedures_callreturn'](block); return tuple[0] + ';\n'; }; -Blockly.PHP['procedures_ifreturn'] = function(block) { +PHP['procedures_ifreturn'] = function(block) { // Conditionally return value from a procedure. - const condition = Blockly.PHP.valueToCode(block, 'CONDITION', - Blockly.PHP.ORDER_NONE) || 'false'; + const condition = PHP.valueToCode(block, 'CONDITION', + PHP.ORDER_NONE) || 'false'; let code = 'if (' + condition + ') {\n'; - if (Blockly.PHP.STATEMENT_SUFFIX) { + if (PHP.STATEMENT_SUFFIX) { // Inject any statement suffix here since the regular one at the end // will not get executed if the return is triggered. - code += Blockly.PHP.prefixLines( - Blockly.PHP.injectId(Blockly.PHP.STATEMENT_SUFFIX, block), - Blockly.PHP.INDENT); + code += PHP.prefixLines( + PHP.injectId(PHP.STATEMENT_SUFFIX, block), + PHP.INDENT); } if (block.hasReturnValue_) { - const value = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || 'null'; - code += Blockly.PHP.INDENT + 'return ' + value + ';\n'; + const value = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || 'null'; + code += PHP.INDENT + 'return ' + value + ';\n'; } else { - code += Blockly.PHP.INDENT + 'return;\n'; + code += PHP.INDENT + 'return;\n'; } code += '}\n'; return code; diff --git a/generators/php/text.js b/generators/php/text.js index 08fde44de8a..cc333c7a358 100644 --- a/generators/php/text.js +++ b/generators/php/text.js @@ -9,164 +9,165 @@ */ 'use strict'; -goog.provide('Blockly.PHP.texts'); +goog.module('Blockly.PHP.texts'); -goog.require('Blockly.PHP'); +const Blockly = goog.require('Blockly'); +const PHP = goog.require('Blockly.PHP'); -Blockly.PHP['text'] = function(block) { +PHP['text'] = function(block) { // Text value. - const code = Blockly.PHP.quote_(block.getFieldValue('TEXT')); - return [code, Blockly.PHP.ORDER_ATOMIC]; + const code = PHP.quote_(block.getFieldValue('TEXT')); + return [code, PHP.ORDER_ATOMIC]; }; -Blockly.PHP['text_multiline'] = function(block) { +PHP['text_multiline'] = function(block) { // Text value. - const code = Blockly.PHP.multiline_quote_(block.getFieldValue('TEXT')); - const order = code.indexOf('.') !== -1 ? Blockly.PHP.ORDER_STRING_CONCAT : - Blockly.PHP.ORDER_ATOMIC; + const code = PHP.multiline_quote_(block.getFieldValue('TEXT')); + const order = code.indexOf('.') !== -1 ? PHP.ORDER_STRING_CONCAT : + PHP.ORDER_ATOMIC; return [code, order]; }; -Blockly.PHP['text_join'] = function(block) { +PHP['text_join'] = function(block) { // Create a string made up of any number of elements of any type. if (block.itemCount_ === 0) { - return ['\'\'', Blockly.PHP.ORDER_ATOMIC]; + return ['\'\'', PHP.ORDER_ATOMIC]; } else if (block.itemCount_ === 1) { - const element = Blockly.PHP.valueToCode(block, 'ADD0', - Blockly.PHP.ORDER_NONE) || '\'\''; + const element = PHP.valueToCode(block, 'ADD0', + PHP.ORDER_NONE) || '\'\''; const code = element; - return [code, Blockly.PHP.ORDER_NONE]; + return [code, PHP.ORDER_NONE]; } else if (block.itemCount_ === 2) { - const element0 = Blockly.PHP.valueToCode(block, 'ADD0', - Blockly.PHP.ORDER_STRING_CONCAT) || '\'\''; - const element1 = Blockly.PHP.valueToCode(block, 'ADD1', - Blockly.PHP.ORDER_STRING_CONCAT) || '\'\''; + const element0 = PHP.valueToCode(block, 'ADD0', + PHP.ORDER_STRING_CONCAT) || '\'\''; + const element1 = PHP.valueToCode(block, 'ADD1', + PHP.ORDER_STRING_CONCAT) || '\'\''; const code = element0 + ' . ' + element1; - return [code, Blockly.PHP.ORDER_STRING_CONCAT]; + return [code, PHP.ORDER_STRING_CONCAT]; } else { const elements = new Array(block.itemCount_); for (let i = 0; i < block.itemCount_; i++) { - elements[i] = Blockly.PHP.valueToCode(block, 'ADD' + i, - Blockly.PHP.ORDER_NONE) || '\'\''; + elements[i] = PHP.valueToCode(block, 'ADD' + i, + PHP.ORDER_NONE) || '\'\''; } const code = 'implode(\'\', array(' + elements.join(',') + '))'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } }; -Blockly.PHP['text_append'] = function(block) { +PHP['text_append'] = function(block) { // Append to a variable in place. - const varName = Blockly.PHP.nameDB_.getName( + const varName = PHP.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const value = Blockly.PHP.valueToCode(block, 'TEXT', - Blockly.PHP.ORDER_ASSIGNMENT) || '\'\''; + const value = PHP.valueToCode(block, 'TEXT', + PHP.ORDER_ASSIGNMENT) || '\'\''; return varName + ' .= ' + value + ';\n'; }; -Blockly.PHP['text_length'] = function(block) { +PHP['text_length'] = function(block) { // String or array length. - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'length', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {', + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {', ' if (is_string($value)) {', ' return strlen($value);', ' } else {', ' return count($value);', ' }', '}']); - const text = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || '\'\''; - return [functionName + '(' + text + ')', Blockly.PHP.ORDER_FUNCTION_CALL]; + const text = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || '\'\''; + return [functionName + '(' + text + ')', PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['text_isEmpty'] = function(block) { +PHP['text_isEmpty'] = function(block) { // Is the string null or array empty? - const text = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || '\'\''; - return ['empty(' + text + ')', Blockly.PHP.ORDER_FUNCTION_CALL]; + const text = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || '\'\''; + return ['empty(' + text + ')', PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['text_indexOf'] = function(block) { +PHP['text_indexOf'] = function(block) { // Search the text for a substring. const operator = block.getFieldValue('END') === 'FIRST' ? 'strpos' : 'strrpos'; - const substring = Blockly.PHP.valueToCode(block, 'FIND', - Blockly.PHP.ORDER_NONE) || '\'\''; - const text = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_NONE) || '\'\''; + const substring = PHP.valueToCode(block, 'FIND', + PHP.ORDER_NONE) || '\'\''; + const text = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_NONE) || '\'\''; let errorIndex = ' -1'; let indexAdjustment = ''; if (block.workspace.options.oneBasedIndex) { errorIndex = ' 0'; indexAdjustment = ' + 1'; } - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( block.getFieldValue('END') === 'FIRST' ? 'text_indexOf' : 'text_lastIndexOf', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($text, $search) {', ' $pos = ' + operator + '($text, $search);', ' return $pos === false ? ' + errorIndex + ' : $pos' + indexAdjustment + ';', '}']); const code = functionName + '(' + text + ', ' + substring + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['text_charAt'] = function(block) { +PHP['text_charAt'] = function(block) { // Get letter at index. const where = block.getFieldValue('WHERE') || 'FROM_START'; - const textOrder = (where === 'RANDOM') ? Blockly.PHP.ORDER_NONE : - Blockly.PHP.ORDER_NONE; - const text = Blockly.PHP.valueToCode(block, 'VALUE', textOrder) || '\'\''; + const textOrder = (where === 'RANDOM') ? PHP.ORDER_NONE : + PHP.ORDER_NONE; + const text = PHP.valueToCode(block, 'VALUE', textOrder) || '\'\''; switch (where) { case 'FIRST': { const code = 'substr(' + text + ', 0, 1)'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } case 'LAST': { const code = 'substr(' + text + ', -1)'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } case 'FROM_START': { - const at = Blockly.PHP.getAdjusted(block, 'AT'); + const at = PHP.getAdjusted(block, 'AT'); const code = 'substr(' + text + ', ' + at + ', 1)'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } case 'FROM_END': { - const at = Blockly.PHP.getAdjusted(block, 'AT', 1, true); + const at = PHP.getAdjusted(block, 'AT', 1, true); const code = 'substr(' + text + ', ' + at + ', 1)'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } case 'RANDOM': { - const functionName = Blockly.PHP.provideFunction_( + const functionName = PHP.provideFunction_( 'text_random_letter', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($text) {', + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($text) {', ' return $text[rand(0, strlen($text) - 1)];', '}']); const code = functionName + '(' + text + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } } throw Error('Unhandled option (text_charAt).'); }; -Blockly.PHP['text_getSubstring'] = function(block) { +PHP['text_getSubstring'] = function(block) { // Get substring. const where1 = block.getFieldValue('WHERE1'); const where2 = block.getFieldValue('WHERE2'); - const text = Blockly.PHP.valueToCode(block, 'STRING', - Blockly.PHP.ORDER_NONE) || '\'\''; + const text = PHP.valueToCode(block, 'STRING', + PHP.ORDER_NONE) || '\'\''; if (where1 === 'FIRST' && where2 === 'LAST') { const code = text; - return [code, Blockly.PHP.ORDER_NONE]; + return [code, PHP.ORDER_NONE]; } else { - const at1 = Blockly.PHP.getAdjusted(block, 'AT1'); - const at2 = Blockly.PHP.getAdjusted(block, 'AT2'); - const functionName = Blockly.PHP.provideFunction_( + const at1 = PHP.getAdjusted(block, 'AT1'); + const at2 = PHP.getAdjusted(block, 'AT2'); + const functionName = PHP.provideFunction_( 'text_get_substring', - ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + ['function ' + PHP.FUNCTION_NAME_PLACEHOLDER_ + '($text, $where1, $at1, $where2, $at2) {', ' if ($where1 == \'FROM_END\') {', ' $at1 = strlen($text) - 1 - $at1;', @@ -189,14 +190,14 @@ Blockly.PHP['text_getSubstring'] = function(block) { '}']); const code = functionName + '(' + text + ', \'' + where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; } }; -Blockly.PHP['text_changeCase'] = function(block) { +PHP['text_changeCase'] = function(block) { // Change capitalization. - const text = Blockly.PHP.valueToCode(block, 'TEXT', - Blockly.PHP.ORDER_NONE) || '\'\''; + const text = PHP.valueToCode(block, 'TEXT', + PHP.ORDER_NONE) || '\'\''; let code; if (block.getFieldValue('CASE') === 'UPPERCASE') { code = 'strtoupper(' + text + ')'; @@ -205,10 +206,10 @@ Blockly.PHP['text_changeCase'] = function(block) { } else if (block.getFieldValue('CASE') === 'TITLECASE') { code = 'ucwords(strtolower(' + text + '))'; } - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['text_trim'] = function(block) { +PHP['text_trim'] = function(block) { // Trim spaces. const OPERATORS = { 'LEFT': 'ltrim', @@ -216,64 +217,64 @@ Blockly.PHP['text_trim'] = function(block) { 'BOTH': 'trim' }; const operator = OPERATORS[block.getFieldValue('MODE')]; - const text = Blockly.PHP.valueToCode(block, 'TEXT', - Blockly.PHP.ORDER_NONE) || '\'\''; - return [operator + '(' + text + ')', Blockly.PHP.ORDER_FUNCTION_CALL]; + const text = PHP.valueToCode(block, 'TEXT', + PHP.ORDER_NONE) || '\'\''; + return [operator + '(' + text + ')', PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['text_print'] = function(block) { +PHP['text_print'] = function(block) { // Print statement. - const msg = Blockly.PHP.valueToCode(block, 'TEXT', - Blockly.PHP.ORDER_NONE) || '\'\''; + const msg = PHP.valueToCode(block, 'TEXT', + PHP.ORDER_NONE) || '\'\''; return 'print(' + msg + ');\n'; }; -Blockly.PHP['text_prompt_ext'] = function(block) { +PHP['text_prompt_ext'] = function(block) { // Prompt function. let msg; if (block.getField('TEXT')) { // Internal message. - msg = Blockly.PHP.quote_(block.getFieldValue('TEXT')); + msg = PHP.quote_(block.getFieldValue('TEXT')); } else { // External message. - msg = Blockly.PHP.valueToCode(block, 'TEXT', - Blockly.PHP.ORDER_NONE) || '\'\''; + msg = PHP.valueToCode(block, 'TEXT', + PHP.ORDER_NONE) || '\'\''; } let code = 'readline(' + msg + ')'; const toNumber = block.getFieldValue('TYPE') === 'NUMBER'; if (toNumber) { code = 'floatval(' + code + ')'; } - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['text_prompt'] = Blockly.PHP['text_prompt_ext']; +PHP['text_prompt'] = PHP['text_prompt_ext']; -Blockly.PHP['text_count'] = function(block) { - const text = Blockly.PHP.valueToCode(block, 'TEXT', - Blockly.PHP.ORDER_NONE) || '\'\''; - const sub = Blockly.PHP.valueToCode(block, 'SUB', - Blockly.PHP.ORDER_NONE) || '\'\''; +PHP['text_count'] = function(block) { + const text = PHP.valueToCode(block, 'TEXT', + PHP.ORDER_NONE) || '\'\''; + const sub = PHP.valueToCode(block, 'SUB', + PHP.ORDER_NONE) || '\'\''; const code = 'strlen(' + sub + ') === 0' + ' ? strlen(' + text + ') + 1' + ' : substr_count(' + text + ', ' + sub + ')'; - return [code, Blockly.PHP.ORDER_CONDITIONAL]; + return [code, PHP.ORDER_CONDITIONAL]; }; -Blockly.PHP['text_replace'] = function(block) { - const text = Blockly.PHP.valueToCode(block, 'TEXT', - Blockly.PHP.ORDER_NONE) || '\'\''; - const from = Blockly.PHP.valueToCode(block, 'FROM', - Blockly.PHP.ORDER_NONE) || '\'\''; - const to = Blockly.PHP.valueToCode(block, 'TO', - Blockly.PHP.ORDER_NONE) || '\'\''; +PHP['text_replace'] = function(block) { + const text = PHP.valueToCode(block, 'TEXT', + PHP.ORDER_NONE) || '\'\''; + const from = PHP.valueToCode(block, 'FROM', + PHP.ORDER_NONE) || '\'\''; + const to = PHP.valueToCode(block, 'TO', + PHP.ORDER_NONE) || '\'\''; const code = 'str_replace(' + from + ', ' + to + ', ' + text + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; -Blockly.PHP['text_reverse'] = function(block) { - const text = Blockly.PHP.valueToCode(block, 'TEXT', - Blockly.PHP.ORDER_NONE) || '\'\''; +PHP['text_reverse'] = function(block) { + const text = PHP.valueToCode(block, 'TEXT', + PHP.ORDER_NONE) || '\'\''; const code = 'strrev(' + text + ')'; - return [code, Blockly.PHP.ORDER_FUNCTION_CALL]; + return [code, PHP.ORDER_FUNCTION_CALL]; }; diff --git a/generators/php/variables.js b/generators/php/variables.js index b1c19f68955..ed5d359c638 100644 --- a/generators/php/variables.js +++ b/generators/php/variables.js @@ -9,23 +9,24 @@ */ 'use strict'; -goog.provide('Blockly.PHP.variables'); +goog.module('Blockly.PHP.variables'); -goog.require('Blockly.PHP'); +const Blockly = goog.require('Blockly'); +const PHP = goog.require('Blockly.PHP'); -Blockly.PHP['variables_get'] = function(block) { +PHP['variables_get'] = function(block) { // Variable getter. - const code = Blockly.PHP.nameDB_.getName(block.getFieldValue('VAR'), + const code = PHP.nameDB_.getName(block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - return [code, Blockly.PHP.ORDER_ATOMIC]; + return [code, PHP.ORDER_ATOMIC]; }; -Blockly.PHP['variables_set'] = function(block) { +PHP['variables_set'] = function(block) { // Variable setter. - const argument0 = Blockly.PHP.valueToCode(block, 'VALUE', - Blockly.PHP.ORDER_ASSIGNMENT) || '0'; - const varName = Blockly.PHP.nameDB_.getName( + const argument0 = PHP.valueToCode(block, 'VALUE', + PHP.ORDER_ASSIGNMENT) || '0'; + const varName = PHP.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); return varName + ' = ' + argument0 + ';\n'; }; diff --git a/generators/php/variables_dynamic.js b/generators/php/variables_dynamic.js index ed15ffa7fb4..95038d6f77c 100644 --- a/generators/php/variables_dynamic.js +++ b/generators/php/variables_dynamic.js @@ -9,12 +9,13 @@ */ 'use strict'; -goog.provide('Blockly.PHP.variablesDynamic'); +goog.module('Blockly.PHP.variablesDynamic'); -goog.require('Blockly.PHP'); -goog.require('Blockly.PHP.variables'); +const PHP = goog.require('Blockly.PHP'); +// Required only for side effects. +const variables = goog.require('Blockly.PHP.variables'); // PHP is dynamically typed. -Blockly.PHP['variables_get_dynamic'] = Blockly.PHP['variables_get']; -Blockly.PHP['variables_set_dynamic'] = Blockly.PHP['variables_set']; +PHP['variables_get_dynamic'] = PHP['variables_get']; +PHP['variables_set_dynamic'] = PHP['variables_set']; diff --git a/generators/python.js b/generators/python.js index f3eaeae7ac7..f3d3f484310 100644 --- a/generators/python.js +++ b/generators/python.js @@ -9,18 +9,24 @@ */ 'use strict'; -goog.provide('Blockly.Python'); +goog.module('Blockly.Python'); +goog.module.declareLegacyNamespace(); -goog.require('Blockly.Generator'); -goog.require('Blockly.inputTypes'); -goog.require('Blockly.utils.string'); +const Blockly = goog.require('Blockly'); +const {Generator} = goog.require('Blockly.Generator'); +const {inputTypes} = goog.require('Blockly.inputTypes'); +const stringUtils = goog.require('Blockly.utils.string'); +const {Names} = goog.require('Blockly.Names'); +const Variables = goog.require('Blockly.Variables'); +const {Workspace} = goog.requireType('Blockly.Workspace'); +const {Block} = goog.requireType('Blockly.Block'); /** * Python code generator. - * @type {!Blockly.Generator} + * @type {!Generator} */ -Blockly.Python = new Blockly.Generator('Python'); +const Python = new Generator('Python'); /** * List of illegal variable names. @@ -29,7 +35,7 @@ Blockly.Python = new Blockly.Generator('Python'); * accidentally clobbering a built-in object or function. * @private */ -Blockly.Python.addReservedWords( +Python.addReservedWords( // import keyword // print(','.join(sorted(keyword.kwlist))) // https://docs.python.org/3/reference/lexical_analysis.html#keywords @@ -75,68 +81,68 @@ Blockly.Python.addReservedWords( * Order of operation ENUMs. * http://docs.python.org/reference/expressions.html#summary */ -Blockly.Python.ORDER_ATOMIC = 0; // 0 "" ... -Blockly.Python.ORDER_COLLECTION = 1; // tuples, lists, dictionaries -Blockly.Python.ORDER_STRING_CONVERSION = 1; // `expression...` -Blockly.Python.ORDER_MEMBER = 2.1; // . [] -Blockly.Python.ORDER_FUNCTION_CALL = 2.2; // () -Blockly.Python.ORDER_EXPONENTIATION = 3; // ** -Blockly.Python.ORDER_UNARY_SIGN = 4; // + - -Blockly.Python.ORDER_BITWISE_NOT = 4; // ~ -Blockly.Python.ORDER_MULTIPLICATIVE = 5; // * / // % -Blockly.Python.ORDER_ADDITIVE = 6; // + - -Blockly.Python.ORDER_BITWISE_SHIFT = 7; // << >> -Blockly.Python.ORDER_BITWISE_AND = 8; // & -Blockly.Python.ORDER_BITWISE_XOR = 9; // ^ -Blockly.Python.ORDER_BITWISE_OR = 10; // | -Blockly.Python.ORDER_RELATIONAL = 11; // in, not in, is, is not, +Python.ORDER_ATOMIC = 0; // 0 "" ... +Python.ORDER_COLLECTION = 1; // tuples, lists, dictionaries +Python.ORDER_STRING_CONVERSION = 1; // `expression...` +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, // <, <=, >, >=, <>, !=, == -Blockly.Python.ORDER_LOGICAL_NOT = 12; // not -Blockly.Python.ORDER_LOGICAL_AND = 13; // and -Blockly.Python.ORDER_LOGICAL_OR = 14; // or -Blockly.Python.ORDER_CONDITIONAL = 15; // if else -Blockly.Python.ORDER_LAMBDA = 16; // lambda -Blockly.Python.ORDER_NONE = 99; // (...) +Python.ORDER_LOGICAL_NOT = 12; // not +Python.ORDER_LOGICAL_AND = 13; // and +Python.ORDER_LOGICAL_OR = 14; // or +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>} */ -Blockly.Python.ORDER_OVERRIDES = [ +Python.ORDER_OVERRIDES = [ // (foo()).bar -> foo().bar // (foo())[0] -> foo()[0] - [Blockly.Python.ORDER_FUNCTION_CALL, Blockly.Python.ORDER_MEMBER], + [Python.ORDER_FUNCTION_CALL, Python.ORDER_MEMBER], // (foo())() -> foo()() - [Blockly.Python.ORDER_FUNCTION_CALL, Blockly.Python.ORDER_FUNCTION_CALL], + [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] - [Blockly.Python.ORDER_MEMBER, Blockly.Python.ORDER_MEMBER], + [Python.ORDER_MEMBER, Python.ORDER_MEMBER], // (foo.bar)() -> foo.bar() // (foo[0])() -> foo[0]() - [Blockly.Python.ORDER_MEMBER, Blockly.Python.ORDER_FUNCTION_CALL], + [Python.ORDER_MEMBER, Python.ORDER_FUNCTION_CALL], // not (not foo) -> not not foo - [Blockly.Python.ORDER_LOGICAL_NOT, Blockly.Python.ORDER_LOGICAL_NOT], + [Python.ORDER_LOGICAL_NOT, Python.ORDER_LOGICAL_NOT], // a and (b and c) -> a and b and c - [Blockly.Python.ORDER_LOGICAL_AND, Blockly.Python.ORDER_LOGICAL_AND], + [Python.ORDER_LOGICAL_AND, Python.ORDER_LOGICAL_AND], // a or (b or c) -> a or b or c - [Blockly.Python.ORDER_LOGICAL_OR, Blockly.Python.ORDER_LOGICAL_OR] + [Python.ORDER_LOGICAL_OR, Python.ORDER_LOGICAL_OR] ]; /** * Whether the init method has been called. * @type {?boolean} */ -Blockly.Python.isInitialized = false; +Python.isInitialized = false; /** * Initialise the database of variable names. - * @param {!Blockly.Workspace} workspace Workspace to generate code from. - * @this {Blockly.Generator} + * @param {!Workspace} workspace Workspace to generate code from. + * @this {Generator} */ -Blockly.Python.init = function(workspace) { +Python.init = function(workspace) { // Call Blockly.Generator's init. Object.getPrototypeOf(this).init.call(this); @@ -146,7 +152,7 @@ Blockly.Python.init = function(workspace) { this.PASS = this.INDENT + 'pass\n'; if (!this.nameDB_) { - this.nameDB_ = new Blockly.Names(this.RESERVED_WORDS_); + this.nameDB_ = new Names(this.RESERVED_WORDS_); } else { this.nameDB_.reset(); } @@ -157,14 +163,14 @@ Blockly.Python.init = function(workspace) { const defvars = []; // Add developer variables (not created or named by the user). - const devVarList = Blockly.Variables.allDeveloperVariables(workspace); + const devVarList = Variables.allDeveloperVariables(workspace); for (let i = 0; i < devVarList.length; i++) { defvars.push(this.nameDB_.getName(devVarList[i], - Blockly.Names.DEVELOPER_VARIABLE_TYPE) + ' = None'); + Names.DEVELOPER_VARIABLE_TYPE) + ' = None'); } // Add user variables, but only ones that are being used. - const variables = Blockly.Variables.allUsedVarModels(workspace); + const variables = Variables.allUsedVarModels(workspace); for (let i = 0; i < variables.length; i++) { defvars.push(this.nameDB_.getName(variables[i].getId(), Blockly.VARIABLE_CATEGORY_NAME) + ' = None'); @@ -179,7 +185,7 @@ Blockly.Python.init = function(workspace) { * @param {string} code Generated code. * @return {string} Completed code. */ -Blockly.Python.finish = function(code) { +Python.finish = function(code) { // Convert the definitions dictionary into a list. const imports = []; const definitions = []; @@ -206,7 +212,7 @@ Blockly.Python.finish = function(code) { * @param {string} line Line of generated code. * @return {string} Legal line of code. */ -Blockly.Python.scrubNakedValue = function(line) { +Python.scrubNakedValue = function(line) { return line + '\n'; }; @@ -216,7 +222,7 @@ Blockly.Python.scrubNakedValue = function(line) { * @return {string} Python string. * @protected */ -Blockly.Python.quote_ = function(string) { +Python.quote_ = function(string) { // Can't use goog.string.quote since % must also be escaped. string = string.replace(/\\/g, '\\\\') .replace(/\n/g, '\\\n'); @@ -240,7 +246,7 @@ Blockly.Python.quote_ = function(string) { * @return {string} Python string. * @protected */ -Blockly.Python.multiline_quote_ = function(string) { +Python.multiline_quote_ = function(string) { const lines = string.split(/\n/g).map(this.quote_); // Join with the following, plus a newline: // + '\n' + @@ -251,26 +257,26 @@ Blockly.Python.multiline_quote_ = function(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 {!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. * @protected */ -Blockly.Python.scrub_ = function(block, code, opt_thisOnly) { +Python.scrub_ = function(block, code, opt_thisOnly) { let 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) { - comment = Blockly.utils.string.wrap(comment, this.COMMENT_WRAP - 3); + comment = stringUtils.wrap(comment, this.COMMENT_WRAP - 3); commentCode += this.prefixLines(comment + '\n', '# '); } // Collect comments for all value arguments. // Don't collect comments for nested statements. for (let i = 0; i < block.inputList.length; i++) { - if (block.inputList[i].type === Blockly.inputTypes.VALUE) { + if (block.inputList[i].type === inputTypes.VALUE) { const childBlock = block.inputList[i].connection.targetBlock(); if (childBlock) { comment = this.allNestedComments(childBlock); @@ -289,13 +295,13 @@ Blockly.Python.scrub_ = function(block, code, opt_thisOnly) { /** * Gets a property and adjusts the value, taking into account indexing. * If a static int, casts to an integer, otherwise returns a code string. - * @param {!Blockly.Block} block The block. + * @param {!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} */ -Blockly.Python.getAdjustedInt = function(block, atId, opt_delta, opt_negate) { +Python.getAdjustedInt = function(block, atId, opt_delta, opt_negate) { let delta = opt_delta || 0; if (block.workspace.options.oneBasedIndex) { delta--; @@ -325,3 +331,5 @@ Blockly.Python.getAdjustedInt = function(block, atId, opt_delta, opt_negate) { } return at; }; + +exports = Python; diff --git a/generators/python/colour.js b/generators/python/colour.js index 7537b73293e..709043e7121 100644 --- a/generators/python/colour.js +++ b/generators/python/colour.js @@ -9,48 +9,48 @@ */ 'use strict'; -goog.provide('Blockly.Python.colour'); +goog.module('Blockly.Python.colour'); -goog.require('Blockly.Python'); +const Python = goog.require('Blockly.Python'); -Blockly.Python['colour_picker'] = function(block) { +Python['colour_picker'] = function(block) { // Colour picker. - const code = Blockly.Python.quote_(block.getFieldValue('COLOUR')); - return [code, Blockly.Python.ORDER_ATOMIC]; + const code = Python.quote_(block.getFieldValue('COLOUR')); + return [code, Python.ORDER_ATOMIC]; }; -Blockly.Python['colour_random'] = function(block) { +Python['colour_random'] = function(block) { // Generate a random colour. - Blockly.Python.definitions_['import_random'] = 'import random'; + Python.definitions_['import_random'] = 'import random'; const code = '\'#%06x\' % random.randint(0, 2**24 - 1)'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['colour_rgb'] = function(block) { +Python['colour_rgb'] = function(block) { // Compose a colour from RGB components expressed as percentages. - const functionName = Blockly.Python.provideFunction_( + const functionName = Python.provideFunction_( 'colour_rgb', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b):', + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b):', ' r = round(min(100, max(0, r)) * 2.55)', ' g = round(min(100, max(0, g)) * 2.55)', ' b = round(min(100, max(0, b)) * 2.55)', ' return \'#%02x%02x%02x\' % (r, g, b)']); - const r = Blockly.Python.valueToCode(block, 'RED', - Blockly.Python.ORDER_NONE) || 0; - const g = Blockly.Python.valueToCode(block, 'GREEN', - Blockly.Python.ORDER_NONE) || 0; - const b = Blockly.Python.valueToCode(block, 'BLUE', - Blockly.Python.ORDER_NONE) || 0; + const r = Python.valueToCode(block, 'RED', + Python.ORDER_NONE) || 0; + const g = Python.valueToCode(block, 'GREEN', + Python.ORDER_NONE) || 0; + const b = Python.valueToCode(block, 'BLUE', + Python.ORDER_NONE) || 0; const code = functionName + '(' + r + ', ' + g + ', ' + b + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['colour_blend'] = function(block) { +Python['colour_blend'] = function(block) { // Blend two colours together. - const functionName = Blockly.Python.provideFunction_( + const functionName = Python.provideFunction_( 'colour_blend', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(colour1, colour2, ratio):', ' r1, r2 = int(colour1[1:3], 16), int(colour2[1:3], 16)', ' g1, g2 = int(colour1[3:5], 16), int(colour2[3:5], 16)', @@ -60,12 +60,12 @@ Blockly.Python['colour_blend'] = function(block) { ' g = round(g1 * (1 - ratio) + g2 * ratio)', ' b = round(b1 * (1 - ratio) + b2 * ratio)', ' return \'#%02x%02x%02x\' % (r, g, b)']); - const colour1 = Blockly.Python.valueToCode(block, 'COLOUR1', - Blockly.Python.ORDER_NONE) || '\'#000000\''; - const colour2 = Blockly.Python.valueToCode(block, 'COLOUR2', - Blockly.Python.ORDER_NONE) || '\'#000000\''; - const ratio = Blockly.Python.valueToCode(block, 'RATIO', - Blockly.Python.ORDER_NONE) || 0; + const colour1 = Python.valueToCode(block, 'COLOUR1', + Python.ORDER_NONE) || '\'#000000\''; + const colour2 = Python.valueToCode(block, 'COLOUR2', + Python.ORDER_NONE) || '\'#000000\''; + const ratio = Python.valueToCode(block, 'RATIO', + Python.ORDER_NONE) || 0; const code = functionName + '(' + colour1 + ', ' + colour2 + ', ' + ratio + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; diff --git a/generators/python/lists.js b/generators/python/lists.js index 4e61cb6efd9..0f2d4052b78 100644 --- a/generators/python/lists.js +++ b/generators/python/lists.js @@ -9,58 +9,59 @@ */ 'use strict'; -goog.provide('Blockly.Python.lists'); +goog.module('Blockly.Python.lists'); -goog.require('Blockly.Python'); +const Blockly = goog.require('Blockly'); +const Python = goog.require('Blockly.Python'); -Blockly.Python['lists_create_empty'] = function(block) { +Python['lists_create_empty'] = function(block) { // Create an empty list. - return ['[]', Blockly.Python.ORDER_ATOMIC]; + return ['[]', Python.ORDER_ATOMIC]; }; -Blockly.Python['lists_create_with'] = function(block) { +Python['lists_create_with'] = function(block) { // Create a list with any number of elements of any type. const elements = new Array(block.itemCount_); for (let i = 0; i < block.itemCount_; i++) { - elements[i] = Blockly.Python.valueToCode(block, 'ADD' + i, - Blockly.Python.ORDER_NONE) || 'None'; + elements[i] = Python.valueToCode(block, 'ADD' + i, + Python.ORDER_NONE) || 'None'; } const code = '[' + elements.join(', ') + ']'; - return [code, Blockly.Python.ORDER_ATOMIC]; + return [code, Python.ORDER_ATOMIC]; }; -Blockly.Python['lists_repeat'] = function(block) { +Python['lists_repeat'] = function(block) { // Create a list with one element repeated. - const item = Blockly.Python.valueToCode(block, 'ITEM', - Blockly.Python.ORDER_NONE) || 'None'; - const times = Blockly.Python.valueToCode(block, 'NUM', - Blockly.Python.ORDER_MULTIPLICATIVE) || '0'; + const item = Python.valueToCode(block, 'ITEM', + Python.ORDER_NONE) || 'None'; + const times = Python.valueToCode(block, 'NUM', + Python.ORDER_MULTIPLICATIVE) || '0'; const code = '[' + item + '] * ' + times; - return [code, Blockly.Python.ORDER_MULTIPLICATIVE]; + return [code, Python.ORDER_MULTIPLICATIVE]; }; -Blockly.Python['lists_length'] = function(block) { +Python['lists_length'] = function(block) { // String or array length. - const list = Blockly.Python.valueToCode(block, 'VALUE', - Blockly.Python.ORDER_NONE) || '[]'; - return ['len(' + list + ')', Blockly.Python.ORDER_FUNCTION_CALL]; + const list = Python.valueToCode(block, 'VALUE', + Python.ORDER_NONE) || '[]'; + return ['len(' + list + ')', Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['lists_isEmpty'] = function(block) { +Python['lists_isEmpty'] = function(block) { // Is the string null or array empty? - const list = Blockly.Python.valueToCode(block, 'VALUE', - Blockly.Python.ORDER_NONE) || '[]'; + const list = Python.valueToCode(block, 'VALUE', + Python.ORDER_NONE) || '[]'; const code = 'not len(' + list + ')'; - return [code, Blockly.Python.ORDER_LOGICAL_NOT]; + return [code, Python.ORDER_LOGICAL_NOT]; }; -Blockly.Python['lists_indexOf'] = function(block) { +Python['lists_indexOf'] = function(block) { // Find an item in the list. - const item = Blockly.Python.valueToCode(block, 'FIND', - Blockly.Python.ORDER_NONE) || '[]'; - const list = Blockly.Python.valueToCode(block, 'VALUE', - Blockly.Python.ORDER_NONE) || '\'\''; + const item = Python.valueToCode(block, 'FIND', + Python.ORDER_NONE) || '[]'; + const list = Python.valueToCode(block, 'VALUE', + Python.ORDER_NONE) || '\'\''; let errorIndex = ' -1'; let firstIndexAdjustment = ''; let lastIndexAdjustment = ' - 1'; @@ -72,44 +73,44 @@ Blockly.Python['lists_indexOf'] = function(block) { } if (block.getFieldValue('END') === 'FIRST') { - const functionName = Blockly.Python.provideFunction_( + const functionName = Python.provideFunction_( 'first_index', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(my_list, elem):', ' try: index = my_list.index(elem)' + firstIndexAdjustment, ' except: index =' + errorIndex, ' return index']); const code = functionName + '(' + list + ', ' + item + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } - const functionName = Blockly.Python.provideFunction_( + const functionName = Python.provideFunction_( 'last_index', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(my_list, elem):', + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(my_list, elem):', ' try: index = len(my_list) - my_list[::-1].index(elem)' + lastIndexAdjustment, ' except: index =' + errorIndex, ' return index']); const code = functionName + '(' + list + ', ' + item + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['lists_getIndex'] = function(block) { +Python['lists_getIndex'] = function(block) { // Get element at index. // Note: Until January 2013 this block did not have MODE or WHERE inputs. const mode = block.getFieldValue('MODE') || 'GET'; const where = block.getFieldValue('WHERE') || 'FROM_START'; - const listOrder = (where === 'RANDOM') ? Blockly.Python.ORDER_NONE : - Blockly.Python.ORDER_MEMBER; - const list = Blockly.Python.valueToCode(block, 'VALUE', listOrder) || '[]'; + const listOrder = (where === 'RANDOM') ? Python.ORDER_NONE : + Python.ORDER_MEMBER; + const list = Python.valueToCode(block, 'VALUE', listOrder) || '[]'; switch (where) { case 'FIRST': if (mode === 'GET') { const code = list + '[0]'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; } else if (mode === 'GET_REMOVE') { const code = list + '.pop(0)'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { return list + '.pop(0)\n'; } @@ -117,54 +118,54 @@ Blockly.Python['lists_getIndex'] = function(block) { case 'LAST': if (mode === 'GET') { const code = list + '[-1]'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; } else if (mode === 'GET_REMOVE') { const code = list + '.pop()'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { return list + '.pop()\n'; } break; case 'FROM_START': { - const at = Blockly.Python.getAdjustedInt(block, 'AT'); + const at = Python.getAdjustedInt(block, 'AT'); if (mode === 'GET') { const code = list + '[' + at + ']'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; } else if (mode === 'GET_REMOVE') { const code = list + '.pop(' + at + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { return list + '.pop(' + at + ')\n'; } break; } case'FROM_END': { - const at = Blockly.Python.getAdjustedInt(block, 'AT', 1, true); + const at = Python.getAdjustedInt(block, 'AT', 1, true); if (mode === 'GET') { const code = list + '[' + at + ']'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; } else if (mode === 'GET_REMOVE') { const code = list + '.pop(' + at + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { return list + '.pop(' + at + ')\n'; } break; } case 'RANDOM': - Blockly.Python.definitions_['import_random'] = 'import random'; + Python.definitions_['import_random'] = 'import random'; if (mode === 'GET') { const code = 'random.choice(' + list + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } else { - const functionName = Blockly.Python.provideFunction_( + const functionName = Python.provideFunction_( 'lists_remove_random_item', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):', + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):', ' x = int(random.random() * len(myList))', ' return myList.pop(x)']); const code = functionName + '(' + list + ')'; if (mode === 'GET_REMOVE') { - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } else if (mode === 'REMOVE') { return code + '\n'; } @@ -174,22 +175,22 @@ Blockly.Python['lists_getIndex'] = function(block) { throw Error('Unhandled combination (lists_getIndex).'); }; -Blockly.Python['lists_setIndex'] = function(block) { +Python['lists_setIndex'] = function(block) { // Set element at index. // Note: Until February 2013 this block did not have MODE or WHERE inputs. - let list = Blockly.Python.valueToCode(block, 'LIST', - Blockly.Python.ORDER_MEMBER) || '[]'; + let list = Python.valueToCode(block, 'LIST', + Python.ORDER_MEMBER) || '[]'; const mode = block.getFieldValue('MODE') || 'GET'; const where = block.getFieldValue('WHERE') || 'FROM_START'; - const value = Blockly.Python.valueToCode(block, 'TO', - Blockly.Python.ORDER_NONE) || 'None'; + const value = Python.valueToCode(block, 'TO', + Python.ORDER_NONE) || 'None'; // Cache non-trivial values to variables to prevent repeated look-ups. // Closure, which accesses and modifies 'list'. function cacheList() { if (list.match(/^\w+$/)) { return ''; } - const listVar = Blockly.Python.nameDB_.getDistinctName( + const listVar = Python.nameDB_.getDistinctName( 'tmp_list', Blockly.VARIABLE_CATEGORY_NAME); const code = listVar + ' = ' + list + '\n'; list = listVar; @@ -212,7 +213,7 @@ Blockly.Python['lists_setIndex'] = function(block) { } break; case 'FROM_START': { - const at = Blockly.Python.getAdjustedInt(block, 'AT'); + const at = Python.getAdjustedInt(block, 'AT'); if (mode === 'SET') { return list + '[' + at + '] = ' + value + '\n'; } else if (mode === 'INSERT') { @@ -221,7 +222,7 @@ Blockly.Python['lists_setIndex'] = function(block) { break; } case 'FROM_END': { - const at = Blockly.Python.getAdjustedInt(block, 'AT', 1, true); + const at = Python.getAdjustedInt(block, 'AT', 1, true); if (mode === 'SET') { return list + '[' + at + '] = ' + value + '\n'; } else if (mode === 'INSERT') { @@ -230,9 +231,9 @@ Blockly.Python['lists_setIndex'] = function(block) { break; } case 'RANDOM': { - Blockly.Python.definitions_['import_random'] = 'import random'; + Python.definitions_['import_random'] = 'import random'; let code = cacheList(); - const xVar = Blockly.Python.nameDB_.getDistinctName( + const xVar = Python.nameDB_.getDistinctName( 'tmp_x', Blockly.VARIABLE_CATEGORY_NAME); code += xVar + ' = int(random.random() * len(' + list + '))\n'; if (mode === 'SET') { @@ -248,22 +249,22 @@ Blockly.Python['lists_setIndex'] = function(block) { throw Error('Unhandled combination (lists_setIndex).'); }; -Blockly.Python['lists_getSublist'] = function(block) { +Python['lists_getSublist'] = function(block) { // Get sublist. - const list = Blockly.Python.valueToCode(block, 'LIST', - Blockly.Python.ORDER_MEMBER) || '[]'; + const list = Python.valueToCode(block, 'LIST', + Python.ORDER_MEMBER) || '[]'; const where1 = block.getFieldValue('WHERE1'); const where2 = block.getFieldValue('WHERE2'); let at1; switch (where1) { case 'FROM_START': - at1 = Blockly.Python.getAdjustedInt(block, 'AT1'); + at1 = Python.getAdjustedInt(block, 'AT1'); if (at1 === 0) { at1 = ''; } break; case 'FROM_END': - at1 = Blockly.Python.getAdjustedInt(block, 'AT1', 1, true); + at1 = Python.getAdjustedInt(block, 'AT1', 1, true); break; case 'FIRST': at1 = ''; @@ -275,14 +276,14 @@ Blockly.Python['lists_getSublist'] = function(block) { let at2; switch (where2) { case 'FROM_START': - at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 1); + at2 = Python.getAdjustedInt(block, 'AT2', 1); break; case 'FROM_END': - at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 0, true); + at2 = Python.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))) { - Blockly.Python.definitions_['import_sys'] = 'import sys'; + Python.definitions_['import_sys'] = 'import sys'; at2 += ' or sys.maxsize'; } else if (at2 === 0) { at2 = ''; @@ -295,17 +296,17 @@ Blockly.Python['lists_getSublist'] = function(block) { throw Error('Unhandled option (lists_getSublist)'); } const code = list + '[' + at1 + ' : ' + at2 + ']'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; }; -Blockly.Python['lists_sort'] = function(block) { +Python['lists_sort'] = function(block) { // Block for sorting a list. - const list = (Blockly.Python.valueToCode(block, 'LIST', - Blockly.Python.ORDER_NONE) || '[]'); + const list = (Python.valueToCode(block, 'LIST', + Python.ORDER_NONE) || '[]'); const type = block.getFieldValue('TYPE'); const reverse = block.getFieldValue('DIRECTION') === '1' ? 'False' : 'True'; - const sortFunctionName = Blockly.Python.provideFunction_('lists_sort', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + + const sortFunctionName = Python.provideFunction_('lists_sort', + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(my_list, type, reverse):', ' def try_float(s):', ' try:', @@ -324,37 +325,37 @@ Blockly.Python['lists_sort'] = function(block) { const code = sortFunctionName + '(' + list + ', "' + type + '", ' + reverse + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['lists_split'] = function(block) { +Python['lists_split'] = function(block) { // Block for splitting text into a list, or joining a list into text. const mode = block.getFieldValue('MODE'); let code; if (mode === 'SPLIT') { - const value_input = Blockly.Python.valueToCode(block, 'INPUT', - Blockly.Python.ORDER_MEMBER) || '\'\''; + const value_input = Python.valueToCode(block, 'INPUT', + Python.ORDER_MEMBER) || '\'\''; const value_delim = - Blockly.Python.valueToCode(block, 'DELIM', Blockly.Python.ORDER_NONE); + Python.valueToCode(block, 'DELIM', Python.ORDER_NONE); code = value_input + '.split(' + value_delim + ')'; } else if (mode === 'JOIN') { const value_input = - Blockly.Python.valueToCode(block, 'INPUT', Blockly.Python.ORDER_NONE) || + Python.valueToCode(block, 'INPUT', Python.ORDER_NONE) || '[]'; - const value_delim = Blockly.Python.valueToCode( - block, 'DELIM', Blockly.Python.ORDER_MEMBER) || + const value_delim = Python.valueToCode( + block, 'DELIM', Python.ORDER_MEMBER) || '\'\''; code = value_delim + '.join(' + value_input + ')'; } else { throw Error('Unknown mode: ' + mode); } - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['lists_reverse'] = function(block) { +Python['lists_reverse'] = function(block) { // Block for reversing a list. - const list = Blockly.Python.valueToCode(block, 'LIST', - Blockly.Python.ORDER_NONE) || '[]'; + const list = Python.valueToCode(block, 'LIST', + Python.ORDER_NONE) || '[]'; const code = 'list(reversed(' + list + '))'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; diff --git a/generators/python/logic.js b/generators/python/logic.js index dfde8856183..a5706de1685 100644 --- a/generators/python/logic.js +++ b/generators/python/logic.js @@ -9,49 +9,49 @@ */ 'use strict'; -goog.provide('Blockly.Python.logic'); +goog.module('Blockly.Python.logic'); -goog.require('Blockly.Python'); +const Python = goog.require('Blockly.Python'); -Blockly.Python['controls_if'] = function(block) { +Python['controls_if'] = function(block) { // If/elseif/else condition. let n = 0; let code = '', branchCode, conditionCode; - if (Blockly.Python.STATEMENT_PREFIX) { + if (Python.STATEMENT_PREFIX) { // Automatic prefix insertion is switched off for this block. Add manually. - code += Blockly.Python.injectId(Blockly.Python.STATEMENT_PREFIX, block); + code += Python.injectId(Python.STATEMENT_PREFIX, block); } do { - conditionCode = Blockly.Python.valueToCode(block, 'IF' + n, - Blockly.Python.ORDER_NONE) || 'False'; - branchCode = Blockly.Python.statementToCode(block, 'DO' + n) || - Blockly.Python.PASS; - if (Blockly.Python.STATEMENT_SUFFIX) { - branchCode = Blockly.Python.prefixLines( - Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX, block), - Blockly.Python.INDENT) + branchCode; + conditionCode = Python.valueToCode(block, 'IF' + n, + Python.ORDER_NONE) || 'False'; + branchCode = Python.statementToCode(block, 'DO' + n) || + Python.PASS; + if (Python.STATEMENT_SUFFIX) { + branchCode = Python.prefixLines( + Python.injectId(Python.STATEMENT_SUFFIX, block), + Python.INDENT) + branchCode; } code += (n === 0 ? 'if ' : 'elif ') + conditionCode + ':\n' + branchCode; n++; } while (block.getInput('IF' + n)); - if (block.getInput('ELSE') || Blockly.Python.STATEMENT_SUFFIX) { - branchCode = Blockly.Python.statementToCode(block, 'ELSE') || - Blockly.Python.PASS; - if (Blockly.Python.STATEMENT_SUFFIX) { - branchCode = Blockly.Python.prefixLines( - Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX, block), - Blockly.Python.INDENT) + branchCode; + if (block.getInput('ELSE') || Python.STATEMENT_SUFFIX) { + branchCode = Python.statementToCode(block, 'ELSE') || + Python.PASS; + if (Python.STATEMENT_SUFFIX) { + branchCode = Python.prefixLines( + Python.injectId(Python.STATEMENT_SUFFIX, block), + Python.INDENT) + branchCode; } code += 'else:\n' + branchCode; } return code; }; -Blockly.Python['controls_ifelse'] = Blockly.Python['controls_if']; +Python['controls_ifelse'] = Python['controls_if']; -Blockly.Python['logic_compare'] = function(block) { +Python['logic_compare'] = function(block) { // Comparison operator. const OPERATORS = { 'EQ': '==', @@ -62,20 +62,20 @@ Blockly.Python['logic_compare'] = function(block) { 'GTE': '>=' }; const operator = OPERATORS[block.getFieldValue('OP')]; - const order = Blockly.Python.ORDER_RELATIONAL; - const argument0 = Blockly.Python.valueToCode(block, 'A', order) || '0'; - const argument1 = Blockly.Python.valueToCode(block, 'B', order) || '0'; + const order = Python.ORDER_RELATIONAL; + const argument0 = Python.valueToCode(block, 'A', order) || '0'; + const argument1 = Python.valueToCode(block, 'B', order) || '0'; const code = argument0 + ' ' + operator + ' ' + argument1; return [code, order]; }; -Blockly.Python['logic_operation'] = function(block) { +Python['logic_operation'] = function(block) { // Operations 'and', 'or'. const operator = (block.getFieldValue('OP') === 'AND') ? 'and' : 'or'; - const order = (operator === 'and') ? Blockly.Python.ORDER_LOGICAL_AND : - Blockly.Python.ORDER_LOGICAL_OR; - let argument0 = Blockly.Python.valueToCode(block, 'A', order); - let argument1 = Blockly.Python.valueToCode(block, 'B', order); + const order = (operator === 'and') ? Python.ORDER_LOGICAL_AND : + Python.ORDER_LOGICAL_OR; + let argument0 = Python.valueToCode(block, 'A', order); + let argument1 = Python.valueToCode(block, 'B', order); if (!argument0 && !argument1) { // If there are no arguments, then the return value is false. argument0 = 'False'; @@ -94,33 +94,33 @@ Blockly.Python['logic_operation'] = function(block) { return [code, order]; }; -Blockly.Python['logic_negate'] = function(block) { +Python['logic_negate'] = function(block) { // Negation. - const argument0 = Blockly.Python.valueToCode(block, 'BOOL', - Blockly.Python.ORDER_LOGICAL_NOT) || 'True'; + const argument0 = Python.valueToCode(block, 'BOOL', + Python.ORDER_LOGICAL_NOT) || 'True'; const code = 'not ' + argument0; - return [code, Blockly.Python.ORDER_LOGICAL_NOT]; + return [code, Python.ORDER_LOGICAL_NOT]; }; -Blockly.Python['logic_boolean'] = function(block) { +Python['logic_boolean'] = function(block) { // Boolean values true and false. const code = (block.getFieldValue('BOOL') === 'TRUE') ? 'True' : 'False'; - return [code, Blockly.Python.ORDER_ATOMIC]; + return [code, Python.ORDER_ATOMIC]; }; -Blockly.Python['logic_null'] = function(block) { +Python['logic_null'] = function(block) { // Null data type. - return ['None', Blockly.Python.ORDER_ATOMIC]; + return ['None', Python.ORDER_ATOMIC]; }; -Blockly.Python['logic_ternary'] = function(block) { +Python['logic_ternary'] = function(block) { // Ternary operator. - const value_if = Blockly.Python.valueToCode(block, 'IF', - Blockly.Python.ORDER_CONDITIONAL) || 'False'; - const value_then = Blockly.Python.valueToCode(block, 'THEN', - Blockly.Python.ORDER_CONDITIONAL) || 'None'; - const value_else = Blockly.Python.valueToCode(block, 'ELSE', - Blockly.Python.ORDER_CONDITIONAL) || 'None'; + const value_if = Python.valueToCode(block, 'IF', + Python.ORDER_CONDITIONAL) || 'False'; + const value_then = Python.valueToCode(block, 'THEN', + Python.ORDER_CONDITIONAL) || 'None'; + const value_else = Python.valueToCode(block, 'ELSE', + Python.ORDER_CONDITIONAL) || 'None'; const code = value_then + ' if ' + value_if + ' else ' + value_else; - return [code, Blockly.Python.ORDER_CONDITIONAL]; + return [code, Python.ORDER_CONDITIONAL]; }; diff --git a/generators/python/loops.js b/generators/python/loops.js index 6218497475a..79de2540cee 100644 --- a/generators/python/loops.js +++ b/generators/python/loops.js @@ -9,12 +9,14 @@ */ 'use strict'; -goog.provide('Blockly.Python.loops'); +goog.module('Blockly.Python.loops'); -goog.require('Blockly.Python'); +const Blockly = goog.require('Blockly'); +const Loops = goog.require('Blockly.Constants.Loops'); +const Python = goog.require('Blockly.Python'); -Blockly.Python['controls_repeat_ext'] = function(block) { +Python['controls_repeat_ext'] = function(block) { // Repeat n times. let repeats; if (block.getField('TIMES')) { @@ -22,68 +24,68 @@ Blockly.Python['controls_repeat_ext'] = function(block) { repeats = String(parseInt(block.getFieldValue('TIMES'), 10)); } else { // External number. - repeats = Blockly.Python.valueToCode(block, 'TIMES', - Blockly.Python.ORDER_NONE) || '0'; + repeats = Python.valueToCode(block, 'TIMES', + Python.ORDER_NONE) || '0'; } if (Blockly.isNumber(repeats)) { repeats = parseInt(repeats, 10); } else { repeats = 'int(' + repeats + ')'; } - let branch = Blockly.Python.statementToCode(block, 'DO'); - branch = Blockly.Python.addLoopTrap(branch, block) || Blockly.Python.PASS; - const loopVar = Blockly.Python.nameDB_.getDistinctName( + let branch = Python.statementToCode(block, 'DO'); + branch = Python.addLoopTrap(branch, block) || Python.PASS; + const loopVar = Python.nameDB_.getDistinctName( 'count', Blockly.VARIABLE_CATEGORY_NAME); const code = 'for ' + loopVar + ' in range(' + repeats + '):\n' + branch; return code; }; -Blockly.Python['controls_repeat'] = Blockly.Python['controls_repeat_ext']; +Python['controls_repeat'] = Python['controls_repeat_ext']; -Blockly.Python['controls_whileUntil'] = function(block) { +Python['controls_whileUntil'] = function(block) { // Do while/until loop. const until = block.getFieldValue('MODE') === 'UNTIL'; - let argument0 = Blockly.Python.valueToCode(block, 'BOOL', - until ? Blockly.Python.ORDER_LOGICAL_NOT : - Blockly.Python.ORDER_NONE) || 'False'; - let branch = Blockly.Python.statementToCode(block, 'DO'); - branch = Blockly.Python.addLoopTrap(branch, block) || Blockly.Python.PASS; + let argument0 = Python.valueToCode(block, 'BOOL', + until ? Python.ORDER_LOGICAL_NOT : + Python.ORDER_NONE) || 'False'; + let branch = Python.statementToCode(block, 'DO'); + branch = Python.addLoopTrap(branch, block) || Python.PASS; if (until) { argument0 = 'not ' + argument0; } return 'while ' + argument0 + ':\n' + branch; }; -Blockly.Python['controls_for'] = function(block) { +Python['controls_for'] = function(block) { // For loop. - const variable0 = Blockly.Python.nameDB_.getName( + const variable0 = Python.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - let argument0 = Blockly.Python.valueToCode(block, 'FROM', - Blockly.Python.ORDER_NONE) || '0'; - let argument1 = Blockly.Python.valueToCode(block, 'TO', - Blockly.Python.ORDER_NONE) || '0'; - let increment = Blockly.Python.valueToCode(block, 'BY', - Blockly.Python.ORDER_NONE) || '1'; - let branch = Blockly.Python.statementToCode(block, 'DO'); - branch = Blockly.Python.addLoopTrap(branch, block) || Blockly.Python.PASS; + let argument0 = Python.valueToCode(block, 'FROM', + Python.ORDER_NONE) || '0'; + let argument1 = Python.valueToCode(block, 'TO', + Python.ORDER_NONE) || '0'; + let increment = Python.valueToCode(block, 'BY', + Python.ORDER_NONE) || '1'; + let branch = Python.statementToCode(block, 'DO'); + branch = Python.addLoopTrap(branch, block) || Python.PASS; let code = ''; let range; // Helper functions. const defineUpRange = function() { - return Blockly.Python.provideFunction_( + return Python.provideFunction_( 'upRange', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(start, stop, step):', ' while start <= stop:', ' yield start', ' start += abs(step)']); }; const defineDownRange = function() { - return Blockly.Python.provideFunction_( + return Python.provideFunction_( 'downRange', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(start, stop, step):', ' while start >= stop:', ' yield start', @@ -143,7 +145,7 @@ Blockly.Python['controls_for'] = function(block) { arg = 'float(' + arg + ')'; } else { // It's complicated. - const varName = Blockly.Python.nameDB_.getDistinctName( + const varName = Python.nameDB_.getDistinctName( variable0 + suffix, Blockly.VARIABLE_CATEGORY_NAME); code += varName + ' = float(' + arg + ')\n'; arg = varName; @@ -170,38 +172,38 @@ Blockly.Python['controls_for'] = function(block) { return code; }; -Blockly.Python['controls_forEach'] = function(block) { +Python['controls_forEach'] = function(block) { // For each loop. - const variable0 = Blockly.Python.nameDB_.getName( + const variable0 = Python.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const argument0 = Blockly.Python.valueToCode(block, 'LIST', - Blockly.Python.ORDER_RELATIONAL) || '[]'; - let branch = Blockly.Python.statementToCode(block, 'DO'); - branch = Blockly.Python.addLoopTrap(branch, block) || Blockly.Python.PASS; + const argument0 = Python.valueToCode(block, 'LIST', + Python.ORDER_RELATIONAL) || '[]'; + let branch = Python.statementToCode(block, 'DO'); + branch = Python.addLoopTrap(branch, block) || Python.PASS; const code = 'for ' + variable0 + ' in ' + argument0 + ':\n' + branch; return code; }; -Blockly.Python['controls_flow_statements'] = function(block) { +Python['controls_flow_statements'] = function(block) { // Flow statements: continue, break. let xfix = ''; - if (Blockly.Python.STATEMENT_PREFIX) { + if (Python.STATEMENT_PREFIX) { // Automatic prefix insertion is switched off for this block. Add manually. - xfix += Blockly.Python.injectId(Blockly.Python.STATEMENT_PREFIX, block); + xfix += Python.injectId(Python.STATEMENT_PREFIX, block); } - if (Blockly.Python.STATEMENT_SUFFIX) { + if (Python.STATEMENT_SUFFIX) { // Inject any statement suffix here since the regular one at the end // will not get executed if the break/continue is triggered. - xfix += Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX, block); + xfix += Python.injectId(Python.STATEMENT_SUFFIX, block); } - if (Blockly.Python.STATEMENT_PREFIX) { - const loop = Blockly.Constants.Loops + if (Python.STATEMENT_PREFIX) { + const loop = Loops .CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); if (loop && !loop.suppressPrefixSuffix) { // Inject loop's statement prefix here since the regular one at the end // of the loop will not get executed if 'continue' is triggered. // In the case of 'break', a prefix is needed due to the loop's suffix. - xfix += Blockly.Python.injectId(Blockly.Python.STATEMENT_PREFIX, loop); + xfix += Python.injectId(Python.STATEMENT_PREFIX, loop); } } switch (block.getFieldValue('FLOW')) { diff --git a/generators/python/math.js b/generators/python/math.js index c605cbdf138..ee6ab9fcdb5 100644 --- a/generators/python/math.js +++ b/generators/python/math.js @@ -9,45 +9,46 @@ */ 'use strict'; -goog.provide('Blockly.Python.math'); +goog.module('Blockly.Python.math'); -goog.require('Blockly.Python'); +const Blockly = goog.require('Blockly'); +const Python = goog.require('Blockly.Python'); // If any new block imports any library, add that library name here. -Blockly.Python.addReservedWords('math,random,Number'); +Python.addReservedWords('math,random,Number'); -Blockly.Python['math_number'] = function(block) { +Python['math_number'] = function(block) { // Numeric value. let code = Number(block.getFieldValue('NUM')); let order; if (code === Infinity) { code = 'float("inf")'; - order = Blockly.Python.ORDER_FUNCTION_CALL; + order = Python.ORDER_FUNCTION_CALL; } else if (code === -Infinity) { code = '-float("inf")'; - order = Blockly.Python.ORDER_UNARY_SIGN; + order = Python.ORDER_UNARY_SIGN; } else { - order = code < 0 ? Blockly.Python.ORDER_UNARY_SIGN : - Blockly.Python.ORDER_ATOMIC; + order = code < 0 ? Python.ORDER_UNARY_SIGN : + Python.ORDER_ATOMIC; } return [code, order]; }; -Blockly.Python['math_arithmetic'] = function(block) { +Python['math_arithmetic'] = function(block) { // Basic arithmetic operators, and power. const OPERATORS = { - 'ADD': [' + ', Blockly.Python.ORDER_ADDITIVE], - 'MINUS': [' - ', Blockly.Python.ORDER_ADDITIVE], - 'MULTIPLY': [' * ', Blockly.Python.ORDER_MULTIPLICATIVE], - 'DIVIDE': [' / ', Blockly.Python.ORDER_MULTIPLICATIVE], - 'POWER': [' ** ', Blockly.Python.ORDER_EXPONENTIATION] + 'ADD': [' + ', Python.ORDER_ADDITIVE], + 'MINUS': [' - ', Python.ORDER_ADDITIVE], + 'MULTIPLY': [' * ', Python.ORDER_MULTIPLICATIVE], + 'DIVIDE': [' / ', Python.ORDER_MULTIPLICATIVE], + 'POWER': [' ** ', Python.ORDER_EXPONENTIATION] }; const tuple = OPERATORS[block.getFieldValue('OP')]; const operator = tuple[0]; const order = tuple[1]; - const argument0 = Blockly.Python.valueToCode(block, 'A', order) || '0'; - const argument1 = Blockly.Python.valueToCode(block, 'B', order) || '0'; + const argument0 = Python.valueToCode(block, 'A', order) || '0'; + const argument1 = Python.valueToCode(block, 'B', order) || '0'; const code = argument0 + operator + argument1; return [code, order]; // In case of 'DIVIDE', division between integers returns different results @@ -57,24 +58,24 @@ Blockly.Python['math_arithmetic'] = function(block) { // legibility of the generated code. }; -Blockly.Python['math_single'] = function(block) { +Python['math_single'] = function(block) { // Math operators with single operand. const operator = block.getFieldValue('OP'); let code; let arg; if (operator === 'NEG') { // Negation is a special case given its different operator precedence. - code = Blockly.Python.valueToCode(block, 'NUM', - Blockly.Python.ORDER_UNARY_SIGN) || '0'; - return ['-' + code, Blockly.Python.ORDER_UNARY_SIGN]; + code = Python.valueToCode(block, 'NUM', + Python.ORDER_UNARY_SIGN) || '0'; + return ['-' + code, Python.ORDER_UNARY_SIGN]; } - Blockly.Python.definitions_['import_math'] = 'import math'; + Python.definitions_['import_math'] = 'import math'; if (operator === 'SIN' || operator === 'COS' || operator === 'TAN') { - arg = Blockly.Python.valueToCode(block, 'NUM', - Blockly.Python.ORDER_MULTIPLICATIVE) || '0'; + arg = Python.valueToCode(block, 'NUM', + Python.ORDER_MULTIPLICATIVE) || '0'; } else { - arg = Blockly.Python.valueToCode(block, 'NUM', - Blockly.Python.ORDER_NONE) || '0'; + arg = Python.valueToCode(block, 'NUM', + Python.ORDER_NONE) || '0'; } // First, handle cases which generate values that don't need parentheses // wrapping the code. @@ -117,7 +118,7 @@ Blockly.Python['math_single'] = function(block) { break; } if (code) { - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } // Second, handle cases which generate values that may need parentheses // wrapping the code. @@ -134,41 +135,41 @@ Blockly.Python['math_single'] = function(block) { default: throw Error('Unknown math operator: ' + operator); } - return [code, Blockly.Python.ORDER_MULTIPLICATIVE]; + return [code, Python.ORDER_MULTIPLICATIVE]; }; -Blockly.Python['math_constant'] = function(block) { +Python['math_constant'] = function(block) { // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY. const CONSTANTS = { - 'PI': ['math.pi', Blockly.Python.ORDER_MEMBER], - 'E': ['math.e', Blockly.Python.ORDER_MEMBER], + 'PI': ['math.pi', Python.ORDER_MEMBER], + 'E': ['math.e', Python.ORDER_MEMBER], 'GOLDEN_RATIO': ['(1 + math.sqrt(5)) / 2', - Blockly.Python.ORDER_MULTIPLICATIVE], - 'SQRT2': ['math.sqrt(2)', Blockly.Python.ORDER_MEMBER], - 'SQRT1_2': ['math.sqrt(1.0 / 2)', Blockly.Python.ORDER_MEMBER], - 'INFINITY': ['float(\'inf\')', Blockly.Python.ORDER_ATOMIC] + Python.ORDER_MULTIPLICATIVE], + 'SQRT2': ['math.sqrt(2)', Python.ORDER_MEMBER], + 'SQRT1_2': ['math.sqrt(1.0 / 2)', Python.ORDER_MEMBER], + 'INFINITY': ['float(\'inf\')', Python.ORDER_ATOMIC] }; const constant = block.getFieldValue('CONSTANT'); if (constant !== 'INFINITY') { - Blockly.Python.definitions_['import_math'] = 'import math'; + Python.definitions_['import_math'] = 'import math'; } return CONSTANTS[constant]; }; -Blockly.Python['math_number_property'] = function(block) { +Python['math_number_property'] = function(block) { // Check if a number is even, odd, prime, whole, positive, or negative // or if it is divisible by certain number. Returns true or false. - const number_to_check = Blockly.Python.valueToCode(block, 'NUMBER_TO_CHECK', - Blockly.Python.ORDER_MULTIPLICATIVE) || '0'; + const number_to_check = Python.valueToCode(block, 'NUMBER_TO_CHECK', + Python.ORDER_MULTIPLICATIVE) || '0'; const dropdown_property = block.getFieldValue('PROPERTY'); let code; if (dropdown_property === 'PRIME') { - Blockly.Python.definitions_['import_math'] = 'import math'; - Blockly.Python.definitions_['from_numbers_import_Number'] = + Python.definitions_['import_math'] = 'import math'; + Python.definitions_['from_numbers_import_Number'] = 'from numbers import Number'; - const functionName = Blockly.Python.provideFunction_( + const functionName = Python.provideFunction_( 'math_isPrime', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(n):', + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(n):', ' # https://en.wikipedia.org/wiki/Primality_test#Naive_methods', ' # If n is not a number but a string, try parsing it.', ' if not isinstance(n, Number):', @@ -188,7 +189,7 @@ Blockly.Python['math_number_property'] = function(block) { ' return False', ' return True']); code = functionName + '(' + number_to_check + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } switch (dropdown_property) { case 'EVEN': @@ -207,41 +208,41 @@ Blockly.Python['math_number_property'] = function(block) { code = number_to_check + ' < 0'; break; case 'DIVISIBLE_BY': { - const divisor = Blockly.Python.valueToCode(block, 'DIVISOR', - Blockly.Python.ORDER_MULTIPLICATIVE); + const divisor = Python.valueToCode(block, 'DIVISOR', + Python.ORDER_MULTIPLICATIVE); // If 'divisor' is some code that evals to 0, Python will raise an error. if (!divisor || divisor === '0') { - return ['False', Blockly.Python.ORDER_ATOMIC]; + return ['False', Python.ORDER_ATOMIC]; } code = number_to_check + ' % ' + divisor + ' == 0'; break; } } - return [code, Blockly.Python.ORDER_RELATIONAL]; + return [code, Python.ORDER_RELATIONAL]; }; -Blockly.Python['math_change'] = function(block) { +Python['math_change'] = function(block) { // Add to a variable in place. - Blockly.Python.definitions_['from_numbers_import_Number'] = + Python.definitions_['from_numbers_import_Number'] = 'from numbers import Number'; - const argument0 = Blockly.Python.valueToCode(block, 'DELTA', - Blockly.Python.ORDER_ADDITIVE) || '0'; - const varName = Blockly.Python.nameDB_.getName(block.getFieldValue('VAR'), + const argument0 = Python.valueToCode(block, 'DELTA', + Python.ORDER_ADDITIVE) || '0'; + const varName = Python.nameDB_.getName(block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); return varName + ' = (' + varName + ' if isinstance(' + varName + ', Number) else 0) + ' + argument0 + '\n'; }; // Rounding functions have a single operand. -Blockly.Python['math_round'] = Blockly.Python['math_single']; +Python['math_round'] = Python['math_single']; // Trigonometry functions have a single operand. -Blockly.Python['math_trig'] = Blockly.Python['math_single']; +Python['math_trig'] = Python['math_single']; -Blockly.Python['math_on_list'] = function(block) { +Python['math_on_list'] = function(block) { // Math functions for lists. const func = block.getFieldValue('OP'); - const list = Blockly.Python.valueToCode(block, 'LIST', - Blockly.Python.ORDER_NONE) || '[]'; + const list = Python.valueToCode(block, 'LIST', + Python.ORDER_NONE) || '[]'; let code; switch (func) { case 'SUM': @@ -254,13 +255,13 @@ Blockly.Python['math_on_list'] = function(block) { code = 'max(' + list + ')'; break; case 'AVERAGE': { - Blockly.Python.definitions_['from_numbers_import_Number'] = + Python.definitions_['from_numbers_import_Number'] = 'from numbers import Number'; - const functionName = Blockly.Python.provideFunction_( + const functionName = Python.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 ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):', + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):', ' localList = [e for e in myList if isinstance(e, Number)]', ' if not localList: return', ' return float(sum(localList)) / len(localList)']); @@ -268,13 +269,13 @@ Blockly.Python['math_on_list'] = function(block) { break; } case 'MEDIAN': { - Blockly.Python.definitions_['from_numbers_import_Number'] = + Python.definitions_['from_numbers_import_Number'] = 'from numbers import Number'; - const functionName = Blockly.Python.provideFunction_( + const functionName = Python.provideFunction_( 'math_median', // This operation excludes null values: // math_median([null, null, 1, 3]) -> 2.0 - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):', + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):', ' localList = sorted([e for e in myList if isinstance(e, Number)])', ' if not localList: return', ' if len(localList) % 2 == 0:', @@ -286,12 +287,12 @@ Blockly.Python['math_on_list'] = function(block) { break; } case 'MODE': { - const functionName = Blockly.Python.provideFunction_( + const functionName = Python.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 ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(some_list):', + ['def ' + Python.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 ' + @@ -315,10 +316,10 @@ Blockly.Python['math_on_list'] = function(block) { break; } case 'STD_DEV': { - Blockly.Python.definitions_['import_math'] = 'import math'; - const functionName = Blockly.Python.provideFunction_( + Python.definitions_['import_math'] = 'import math'; + const functionName = Python.provideFunction_( 'math_standard_deviation', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(numbers):', + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(numbers):', ' n = len(numbers)', ' if n == 0: return', ' mean = float(sum(numbers)) / n', @@ -328,62 +329,62 @@ Blockly.Python['math_on_list'] = function(block) { break; } case 'RANDOM': - Blockly.Python.definitions_['import_random'] = 'import random'; + Python.definitions_['import_random'] = 'import random'; code = 'random.choice(' + list + ')'; break; default: throw Error('Unknown operator: ' + func); } - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['math_modulo'] = function(block) { +Python['math_modulo'] = function(block) { // Remainder computation. - const argument0 = Blockly.Python.valueToCode(block, 'DIVIDEND', - Blockly.Python.ORDER_MULTIPLICATIVE) || '0'; - const argument1 = Blockly.Python.valueToCode(block, 'DIVISOR', - Blockly.Python.ORDER_MULTIPLICATIVE) || '0'; + const argument0 = Python.valueToCode(block, 'DIVIDEND', + Python.ORDER_MULTIPLICATIVE) || '0'; + const argument1 = Python.valueToCode(block, 'DIVISOR', + Python.ORDER_MULTIPLICATIVE) || '0'; const code = argument0 + ' % ' + argument1; - return [code, Blockly.Python.ORDER_MULTIPLICATIVE]; + return [code, Python.ORDER_MULTIPLICATIVE]; }; -Blockly.Python['math_constrain'] = function(block) { +Python['math_constrain'] = function(block) { // Constrain a number between two limits. - const argument0 = Blockly.Python.valueToCode(block, 'VALUE', - Blockly.Python.ORDER_NONE) || '0'; - const argument1 = Blockly.Python.valueToCode(block, 'LOW', - Blockly.Python.ORDER_NONE) || '0'; - const argument2 = Blockly.Python.valueToCode(block, 'HIGH', - Blockly.Python.ORDER_NONE) || 'float(\'inf\')'; + const argument0 = Python.valueToCode(block, 'VALUE', + Python.ORDER_NONE) || '0'; + const argument1 = Python.valueToCode(block, 'LOW', + Python.ORDER_NONE) || '0'; + const argument2 = Python.valueToCode(block, 'HIGH', + Python.ORDER_NONE) || 'float(\'inf\')'; const code = 'min(max(' + argument0 + ', ' + argument1 + '), ' + argument2 + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['math_random_int'] = function(block) { +Python['math_random_int'] = function(block) { // Random integer between [X] and [Y]. - Blockly.Python.definitions_['import_random'] = 'import random'; - const argument0 = Blockly.Python.valueToCode(block, 'FROM', - Blockly.Python.ORDER_NONE) || '0'; - const argument1 = Blockly.Python.valueToCode(block, 'TO', - Blockly.Python.ORDER_NONE) || '0'; + Python.definitions_['import_random'] = 'import random'; + const argument0 = Python.valueToCode(block, 'FROM', + Python.ORDER_NONE) || '0'; + const argument1 = Python.valueToCode(block, 'TO', + Python.ORDER_NONE) || '0'; const code = 'random.randint(' + argument0 + ', ' + argument1 + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['math_random_float'] = function(block) { +Python['math_random_float'] = function(block) { // Random fraction between 0 and 1. - Blockly.Python.definitions_['import_random'] = 'import random'; - return ['random.random()', Blockly.Python.ORDER_FUNCTION_CALL]; + Python.definitions_['import_random'] = 'import random'; + return ['random.random()', Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['math_atan2'] = function(block) { +Python['math_atan2'] = function(block) { // Arctangent of point (X, Y) in degrees from -180 to 180. - Blockly.Python.definitions_['import_math'] = 'import math'; - const argument0 = Blockly.Python.valueToCode(block, 'X', - Blockly.Python.ORDER_NONE) || '0'; - const argument1 = Blockly.Python.valueToCode(block, 'Y', - Blockly.Python.ORDER_NONE) || '0'; + Python.definitions_['import_math'] = 'import math'; + const argument0 = Python.valueToCode(block, 'X', + Python.ORDER_NONE) || '0'; + const argument1 = Python.valueToCode(block, 'Y', + Python.ORDER_NONE) || '0'; return ['math.atan2(' + argument1 + ', ' + argument0 + ') / math.pi * 180', - Blockly.Python.ORDER_MULTIPLICATIVE]; + Python.ORDER_MULTIPLICATIVE]; }; diff --git a/generators/python/procedures.js b/generators/python/procedures.js index bc1b90fa257..145bda1a2c2 100644 --- a/generators/python/procedures.js +++ b/generators/python/procedures.js @@ -9,124 +9,127 @@ */ 'use strict'; -goog.provide('Blockly.Python.procedures'); +goog.module('Blockly.Python.procedures'); -goog.require('Blockly.Python'); +const Blockly = goog.require('Blockly'); +const {Names} = goog.require('Blockly.Names'); +const Variables = goog.require('Blockly.Variables'); +const Python = goog.require('Blockly.Python'); -Blockly.Python['procedures_defreturn'] = function(block) { +Python['procedures_defreturn'] = function(block) { // Define a procedure with a return value. // First, add a 'global' statement for every variable that is not shadowed by // a local parameter. const globals = []; const workspace = block.workspace; - const usedVariables = Blockly.Variables.allUsedVarModels(workspace) || []; + const usedVariables = Variables.allUsedVarModels(workspace) || []; for (let i = 0, variable; (variable = usedVariables[i]); i++) { const varName = variable.name; if (block.getVars().indexOf(varName) === -1) { - globals.push(Blockly.Python.nameDB_.getName(varName, + globals.push(Python.nameDB_.getName(varName, Blockly.VARIABLE_CATEGORY_NAME)); } } // Add developer variables. - const devVarList = Blockly.Variables.allDeveloperVariables(workspace); + const devVarList = Variables.allDeveloperVariables(workspace); for (let i = 0; i < devVarList.length; i++) { - globals.push(Blockly.Python.nameDB_.getName(devVarList[i], - Blockly.Names.DEVELOPER_VARIABLE_TYPE)); + globals.push(Python.nameDB_.getName(devVarList[i], + Names.DEVELOPER_VARIABLE_TYPE)); } const globalString = globals.length ? - Blockly.Python.INDENT + 'global ' + globals.join(', ') + '\n' : ''; - const funcName = Blockly.Python.nameDB_.getName( + Python.INDENT + 'global ' + globals.join(', ') + '\n' : ''; + const funcName = Python.nameDB_.getName( block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME); let xfix1 = ''; - if (Blockly.Python.STATEMENT_PREFIX) { - xfix1 += Blockly.Python.injectId(Blockly.Python.STATEMENT_PREFIX, block); + if (Python.STATEMENT_PREFIX) { + xfix1 += Python.injectId(Python.STATEMENT_PREFIX, block); } - if (Blockly.Python.STATEMENT_SUFFIX) { - xfix1 += Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX, block); + if (Python.STATEMENT_SUFFIX) { + xfix1 += Python.injectId(Python.STATEMENT_SUFFIX, block); } if (xfix1) { - xfix1 = Blockly.Python.prefixLines(xfix1, Blockly.Python.INDENT); + xfix1 = Python.prefixLines(xfix1, Python.INDENT); } let loopTrap = ''; - if (Blockly.Python.INFINITE_LOOP_TRAP) { - loopTrap = Blockly.Python.prefixLines( - Blockly.Python.injectId(Blockly.Python.INFINITE_LOOP_TRAP, block), - Blockly.Python.INDENT); + if (Python.INFINITE_LOOP_TRAP) { + loopTrap = Python.prefixLines( + Python.injectId(Python.INFINITE_LOOP_TRAP, block), + Python.INDENT); } - let branch = Blockly.Python.statementToCode(block, 'STACK'); - let returnValue = Blockly.Python.valueToCode(block, 'RETURN', - Blockly.Python.ORDER_NONE) || ''; + let branch = Python.statementToCode(block, 'STACK'); + let returnValue = Python.valueToCode(block, 'RETURN', + Python.ORDER_NONE) || ''; let xfix2 = ''; if (branch && returnValue) { // After executing the function body, revisit this block for the return. xfix2 = xfix1; } if (returnValue) { - returnValue = Blockly.Python.INDENT + 'return ' + returnValue + '\n'; + returnValue = Python.INDENT + 'return ' + returnValue + '\n'; } else if (!branch) { - branch = Blockly.Python.PASS; + branch = Python.PASS; } const args = []; const variables = block.getVars(); for (let i = 0; i < variables.length; i++) { - args[i] = Blockly.Python.nameDB_.getName(variables[i], + args[i] = Python.nameDB_.getName(variables[i], Blockly.VARIABLE_CATEGORY_NAME); } let code = 'def ' + funcName + '(' + args.join(', ') + '):\n' + globalString + xfix1 + loopTrap + branch + xfix2 + returnValue; - code = Blockly.Python.scrub_(block, code); + code = Python.scrub_(block, code); // Add % so as not to collide with helper functions in definitions list. - Blockly.Python.definitions_['%' + funcName] = code; + Python.definitions_['%' + funcName] = code; return null; }; // Defining a procedure without a return value uses the same generator as // a procedure with a return value. -Blockly.Python['procedures_defnoreturn'] = - Blockly.Python['procedures_defreturn']; +Python['procedures_defnoreturn'] = + Python['procedures_defreturn']; -Blockly.Python['procedures_callreturn'] = function(block) { +Python['procedures_callreturn'] = function(block) { // Call a procedure with a return value. - const funcName = Blockly.Python.nameDB_.getName(block.getFieldValue('NAME'), + const funcName = Python.nameDB_.getName(block.getFieldValue('NAME'), Blockly.PROCEDURE_CATEGORY_NAME); const args = []; const variables = block.getVars(); for (let i = 0; i < variables.length; i++) { - args[i] = Blockly.Python.valueToCode(block, 'ARG' + i, - Blockly.Python.ORDER_NONE) || 'None'; + args[i] = Python.valueToCode(block, 'ARG' + i, + Python.ORDER_NONE) || 'None'; } const code = funcName + '(' + args.join(', ') + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['procedures_callnoreturn'] = function(block) { +Python['procedures_callnoreturn'] = function(block) { // Call a procedure with no return value. // Generated code is for a function call as a statement is the same as a // function call as a value, with the addition of line ending. - const tuple = Blockly.Python['procedures_callreturn'](block); + const tuple = Python['procedures_callreturn'](block); return tuple[0] + '\n'; }; -Blockly.Python['procedures_ifreturn'] = function(block) { +Python['procedures_ifreturn'] = function(block) { // Conditionally return value from a procedure. - const condition = Blockly.Python.valueToCode(block, 'CONDITION', - Blockly.Python.ORDER_NONE) || 'False'; + const condition = Python.valueToCode(block, 'CONDITION', + Python.ORDER_NONE) || 'False'; let code = 'if ' + condition + ':\n'; - if (Blockly.Python.STATEMENT_SUFFIX) { + if (Python.STATEMENT_SUFFIX) { // Inject any statement suffix here since the regular one at the end // will not get executed if the return is triggered. - code += Blockly.Python.prefixLines( - Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX, block), - Blockly.Python.INDENT); + code += Python.prefixLines( + Python.injectId(Python.STATEMENT_SUFFIX, block), + Python.INDENT); } if (block.hasReturnValue_) { - const value = Blockly.Python.valueToCode(block, 'VALUE', - Blockly.Python.ORDER_NONE) || 'None'; - code += Blockly.Python.INDENT + 'return ' + value + '\n'; + const value = Python.valueToCode(block, 'VALUE', + Python.ORDER_NONE) || 'None'; + code += Python.INDENT + 'return ' + value + '\n'; } else { - code += Blockly.Python.INDENT + 'return\n'; + code += Python.INDENT + 'return\n'; } return code; }; diff --git a/generators/python/text.js b/generators/python/text.js index c244884f034..4693423cc1d 100644 --- a/generators/python/text.js +++ b/generators/python/text.js @@ -9,22 +9,23 @@ */ 'use strict'; -goog.provide('Blockly.Python.texts'); +goog.module('Blockly.Python.texts'); -goog.require('Blockly.Python'); +const Blockly = goog.require('Blockly'); +const Python = goog.require('Blockly.Python'); -Blockly.Python['text'] = function(block) { +Python['text'] = function(block) { // Text value. - const code = Blockly.Python.quote_(block.getFieldValue('TEXT')); - return [code, Blockly.Python.ORDER_ATOMIC]; + const code = Python.quote_(block.getFieldValue('TEXT')); + return [code, Python.ORDER_ATOMIC]; }; -Blockly.Python['text_multiline'] = function(block) { +Python['text_multiline'] = function(block) { // Text value. - const code = Blockly.Python.multiline_quote_(block.getFieldValue('TEXT')); - const order = code.indexOf('+') !== -1 ? Blockly.Python.ORDER_ADDITIVE : - Blockly.Python.ORDER_ATOMIC; + const code = Python.multiline_quote_(block.getFieldValue('TEXT')); + const order = code.indexOf('+') !== -1 ? Python.ORDER_ADDITIVE : + Python.ORDER_ATOMIC; return [code, order]; }; @@ -36,152 +37,152 @@ Blockly.Python['text_multiline'] = function(block) { * the order of the returned code.[string, number] * @private */ -Blockly.Python.text.forceString_ = function(value) { - if (Blockly.Python.text.forceString_.strRegExp.test(value)) { - return [value, Blockly.Python.ORDER_ATOMIC]; +Python.text.forceString_ = function(value) { + if (Python.text.forceString_.strRegExp.test(value)) { + return [value, Python.ORDER_ATOMIC]; } - return ['str(' + value + ')', Blockly.Python.ORDER_FUNCTION_CALL]; + return ['str(' + value + ')', Python.ORDER_FUNCTION_CALL]; }; /** * Regular expression to detect a single-quoted string literal. */ -Blockly.Python.text.forceString_.strRegExp = /^\s*'([^']|\\')*'\s*$/; +Python.text.forceString_.strRegExp = /^\s*'([^']|\\')*'\s*$/; -Blockly.Python['text_join'] = function(block) { +Python['text_join'] = function(block) { // Create a string made up of any number of elements of any type. //Should we allow joining by '-' or ',' or any other characters? switch (block.itemCount_) { case 0: - return ['\'\'', Blockly.Python.ORDER_ATOMIC]; + return ['\'\'', Python.ORDER_ATOMIC]; case 1: { - const element = Blockly.Python.valueToCode(block, 'ADD0', - Blockly.Python.ORDER_NONE) || '\'\''; - const codeAndOrder = Blockly.Python.text.forceString_(element); + const element = Python.valueToCode(block, 'ADD0', + Python.ORDER_NONE) || '\'\''; + const codeAndOrder = Python.text.forceString_(element); return codeAndOrder; } case 2: { - const element0 = Blockly.Python.valueToCode( - block, 'ADD0', Blockly.Python.ORDER_NONE) || + const element0 = Python.valueToCode( + block, 'ADD0', Python.ORDER_NONE) || '\'\''; - const element1 = Blockly.Python.valueToCode( - block, 'ADD1', Blockly.Python.ORDER_NONE) || + const element1 = Python.valueToCode( + block, 'ADD1', Python.ORDER_NONE) || '\'\''; - const code = Blockly.Python.text.forceString_(element0)[0] + ' + ' + - Blockly.Python.text.forceString_(element1)[0]; - return [code, Blockly.Python.ORDER_ADDITIVE]; + const code = Python.text.forceString_(element0)[0] + ' + ' + + Python.text.forceString_(element1)[0]; + return [code, Python.ORDER_ADDITIVE]; } default: { const elements = []; for (let i = 0; i < block.itemCount_; i++) { - elements[i] = Blockly.Python.valueToCode(block, 'ADD' + i, - Blockly.Python.ORDER_NONE) || '\'\''; + elements[i] = Python.valueToCode(block, 'ADD' + i, + Python.ORDER_NONE) || '\'\''; } - const tempVar = Blockly.Python.nameDB_.getDistinctName( + const tempVar = Python.nameDB_.getDistinctName( 'x', Blockly.VARIABLE_CATEGORY_NAME); const code = '\'\'.join([str(' + tempVar + ') for ' + tempVar + ' in [' + elements.join(', ') + ']])'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } } }; -Blockly.Python['text_append'] = function(block) { +Python['text_append'] = function(block) { // Append to a variable in place. - const varName = Blockly.Python.nameDB_.getName(block.getFieldValue('VAR'), + const varName = Python.nameDB_.getName(block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - const value = Blockly.Python.valueToCode(block, 'TEXT', - Blockly.Python.ORDER_NONE) || '\'\''; + const value = Python.valueToCode(block, 'TEXT', + Python.ORDER_NONE) || '\'\''; return varName + ' = str(' + varName + ') + ' + - Blockly.Python.text.forceString_(value)[0] + '\n'; + Python.text.forceString_(value)[0] + '\n'; }; -Blockly.Python['text_length'] = function(block) { +Python['text_length'] = function(block) { // Is the string null or array empty? - const text = Blockly.Python.valueToCode(block, 'VALUE', - Blockly.Python.ORDER_NONE) || '\'\''; - return ['len(' + text + ')', Blockly.Python.ORDER_FUNCTION_CALL]; + const text = Python.valueToCode(block, 'VALUE', + Python.ORDER_NONE) || '\'\''; + return ['len(' + text + ')', Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['text_isEmpty'] = function(block) { +Python['text_isEmpty'] = function(block) { // Is the string null or array empty? - const text = Blockly.Python.valueToCode(block, 'VALUE', - Blockly.Python.ORDER_NONE) || '\'\''; + const text = Python.valueToCode(block, 'VALUE', + Python.ORDER_NONE) || '\'\''; const code = 'not len(' + text + ')'; - return [code, Blockly.Python.ORDER_LOGICAL_NOT]; + return [code, Python.ORDER_LOGICAL_NOT]; }; -Blockly.Python['text_indexOf'] = function(block) { +Python['text_indexOf'] = function(block) { // Search the text for a substring. // Should we allow for non-case sensitive??? const operator = block.getFieldValue('END') === 'FIRST' ? 'find' : 'rfind'; - const substring = Blockly.Python.valueToCode(block, 'FIND', - Blockly.Python.ORDER_NONE) || '\'\''; - const text = Blockly.Python.valueToCode(block, 'VALUE', - Blockly.Python.ORDER_MEMBER) || '\'\''; + const substring = Python.valueToCode(block, 'FIND', + Python.ORDER_NONE) || '\'\''; + const text = Python.valueToCode(block, 'VALUE', + Python.ORDER_MEMBER) || '\'\''; const code = text + '.' + operator + '(' + substring + ')'; if (block.workspace.options.oneBasedIndex) { - return [code + ' + 1', Blockly.Python.ORDER_ADDITIVE]; + return [code + ' + 1', Python.ORDER_ADDITIVE]; } - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['text_charAt'] = function(block) { +Python['text_charAt'] = function(block) { // Get letter at index. // Note: Until January 2013 this block did not have the WHERE input. const where = block.getFieldValue('WHERE') || 'FROM_START'; - const textOrder = (where === 'RANDOM') ? Blockly.Python.ORDER_NONE : - Blockly.Python.ORDER_MEMBER; - const text = Blockly.Python.valueToCode(block, 'VALUE', textOrder) || '\'\''; + const textOrder = (where === 'RANDOM') ? Python.ORDER_NONE : + Python.ORDER_MEMBER; + const text = Python.valueToCode(block, 'VALUE', textOrder) || '\'\''; switch (where) { case 'FIRST': { const code = text + '[0]'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; } case 'LAST': { const code = text + '[-1]'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; } case 'FROM_START': { - const at = Blockly.Python.getAdjustedInt(block, 'AT'); + const at = Python.getAdjustedInt(block, 'AT'); const code = text + '[' + at + ']'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; } case 'FROM_END': { - const at = Blockly.Python.getAdjustedInt(block, 'AT', 1, true); + const at = Python.getAdjustedInt(block, 'AT', 1, true); const code = text + '[' + at + ']'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; } case 'RANDOM': { - Blockly.Python.definitions_['import_random'] = 'import random'; + Python.definitions_['import_random'] = 'import random'; const functionName = - Blockly.Python.provideFunction_('text_random_letter', [ - 'def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(text):', + Python.provideFunction_('text_random_letter', [ + 'def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(text):', ' x = int(random.random() * len(text))', ' return text[x];' ]); const code = functionName + '(' + text + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; } } throw Error('Unhandled option (text_charAt).'); }; -Blockly.Python['text_getSubstring'] = function(block) { +Python['text_getSubstring'] = function(block) { // Get substring. const where1 = block.getFieldValue('WHERE1'); const where2 = block.getFieldValue('WHERE2'); - const text = Blockly.Python.valueToCode(block, 'STRING', - Blockly.Python.ORDER_MEMBER) || '\'\''; + const text = Python.valueToCode(block, 'STRING', + Python.ORDER_MEMBER) || '\'\''; let at1; switch (where1) { case 'FROM_START': - at1 = Blockly.Python.getAdjustedInt(block, 'AT1'); + at1 = Python.getAdjustedInt(block, 'AT1'); if (at1 === 0) { at1 = ''; } break; case 'FROM_END': - at1 = Blockly.Python.getAdjustedInt(block, 'AT1', 1, true); + at1 = Python.getAdjustedInt(block, 'AT1', 1, true); break; case 'FIRST': at1 = ''; @@ -193,14 +194,14 @@ Blockly.Python['text_getSubstring'] = function(block) { let at2; switch (where2) { case 'FROM_START': - at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 1); + at2 = Python.getAdjustedInt(block, 'AT2', 1); break; case 'FROM_END': - at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 0, true); + at2 = Python.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))) { - Blockly.Python.definitions_['import_sys'] = 'import sys'; + Python.definitions_['import_sys'] = 'import sys'; at2 += ' or sys.maxsize'; } else if (at2 === 0) { at2 = ''; @@ -213,10 +214,10 @@ Blockly.Python['text_getSubstring'] = function(block) { throw Error('Unhandled option (text_getSubstring)'); } const code = text + '[' + at1 + ' : ' + at2 + ']'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; }; -Blockly.Python['text_changeCase'] = function(block) { +Python['text_changeCase'] = function(block) { // Change capitalization. const OPERATORS = { 'UPPERCASE': '.upper()', @@ -224,13 +225,13 @@ Blockly.Python['text_changeCase'] = function(block) { 'TITLECASE': '.title()' }; const operator = OPERATORS[block.getFieldValue('CASE')]; - const text = Blockly.Python.valueToCode(block, 'TEXT', - Blockly.Python.ORDER_MEMBER) || '\'\''; + const text = Python.valueToCode(block, 'TEXT', + Python.ORDER_MEMBER) || '\'\''; const code = text + operator; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['text_trim'] = function(block) { +Python['text_trim'] = function(block) { // Trim spaces. const OPERATORS = { 'LEFT': '.lstrip()', @@ -238,24 +239,24 @@ Blockly.Python['text_trim'] = function(block) { 'BOTH': '.strip()' }; const operator = OPERATORS[block.getFieldValue('MODE')]; - const text = Blockly.Python.valueToCode(block, 'TEXT', - Blockly.Python.ORDER_MEMBER) || '\'\''; + const text = Python.valueToCode(block, 'TEXT', + Python.ORDER_MEMBER) || '\'\''; const code = text + operator; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['text_print'] = function(block) { +Python['text_print'] = function(block) { // Print statement. - const msg = Blockly.Python.valueToCode(block, 'TEXT', - Blockly.Python.ORDER_NONE) || '\'\''; + const msg = Python.valueToCode(block, 'TEXT', + Python.ORDER_NONE) || '\'\''; return 'print(' + msg + ')\n'; }; -Blockly.Python['text_prompt_ext'] = function(block) { +Python['text_prompt_ext'] = function(block) { // Prompt function. - const functionName = Blockly.Python.provideFunction_( + const functionName = Python.provideFunction_( 'text_prompt', - ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(msg):', + ['def ' + Python.FUNCTION_NAME_PLACEHOLDER_ + '(msg):', ' try:', ' return raw_input(msg)', ' except NameError:', @@ -263,45 +264,45 @@ Blockly.Python['text_prompt_ext'] = function(block) { let msg; if (block.getField('TEXT')) { // Internal message. - msg = Blockly.Python.quote_(block.getFieldValue('TEXT')); + msg = Python.quote_(block.getFieldValue('TEXT')); } else { // External message. - msg = Blockly.Python.valueToCode(block, 'TEXT', - Blockly.Python.ORDER_NONE) || '\'\''; + msg = Python.valueToCode(block, 'TEXT', + Python.ORDER_NONE) || '\'\''; } let code = functionName + '(' + msg + ')'; const toNumber = block.getFieldValue('TYPE') === 'NUMBER'; if (toNumber) { code = 'float(' + code + ')'; } - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['text_prompt'] = Blockly.Python['text_prompt_ext']; +Python['text_prompt'] = Python['text_prompt_ext']; -Blockly.Python['text_count'] = function(block) { - const text = Blockly.Python.valueToCode(block, 'TEXT', - Blockly.Python.ORDER_MEMBER) || '\'\''; - const sub = Blockly.Python.valueToCode(block, 'SUB', - Blockly.Python.ORDER_NONE) || '\'\''; +Python['text_count'] = function(block) { + const text = Python.valueToCode(block, 'TEXT', + Python.ORDER_MEMBER) || '\'\''; + const sub = Python.valueToCode(block, 'SUB', + Python.ORDER_NONE) || '\'\''; const code = text + '.count(' + sub + ')'; - return [code, Blockly.Python.ORDER_FUNCTION_CALL]; + return [code, Python.ORDER_FUNCTION_CALL]; }; -Blockly.Python['text_replace'] = function(block) { - const text = Blockly.Python.valueToCode(block, 'TEXT', - Blockly.Python.ORDER_MEMBER) || '\'\''; - const from = Blockly.Python.valueToCode(block, 'FROM', - Blockly.Python.ORDER_NONE) || '\'\''; - const to = Blockly.Python.valueToCode(block, 'TO', - Blockly.Python.ORDER_NONE) || '\'\''; +Python['text_replace'] = function(block) { + const text = Python.valueToCode(block, 'TEXT', + Python.ORDER_MEMBER) || '\'\''; + const from = Python.valueToCode(block, 'FROM', + Python.ORDER_NONE) || '\'\''; + const to = Python.valueToCode(block, 'TO', + Python.ORDER_NONE) || '\'\''; const code = text + '.replace(' + from + ', ' + to + ')'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; }; -Blockly.Python['text_reverse'] = function(block) { - const text = Blockly.Python.valueToCode(block, 'TEXT', - Blockly.Python.ORDER_MEMBER) || '\'\''; +Python['text_reverse'] = function(block) { + const text = Python.valueToCode(block, 'TEXT', + Python.ORDER_MEMBER) || '\'\''; const code = text + '[::-1]'; - return [code, Blockly.Python.ORDER_MEMBER]; + return [code, Python.ORDER_MEMBER]; }; diff --git a/generators/python/variables.js b/generators/python/variables.js index 6f1c0785de2..9b5c18f222c 100644 --- a/generators/python/variables.js +++ b/generators/python/variables.js @@ -9,24 +9,25 @@ */ 'use strict'; -goog.provide('Blockly.Python.variables'); +goog.module('Blockly.Python.variables'); -goog.require('Blockly.Python'); +const Blockly = goog.require('Blockly'); +const Python = goog.require('Blockly.Python'); -Blockly.Python['variables_get'] = function(block) { +Python['variables_get'] = function(block) { // Variable getter. - const code = Blockly.Python.nameDB_.getName(block.getFieldValue('VAR'), + const code = Python.nameDB_.getName(block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); - return [code, Blockly.Python.ORDER_ATOMIC]; + return [code, Python.ORDER_ATOMIC]; }; -Blockly.Python['variables_set'] = function(block) { +Python['variables_set'] = function(block) { // Variable setter. const argument0 = - Blockly.Python.valueToCode(block, 'VALUE', Blockly.Python.ORDER_NONE) || + Python.valueToCode(block, 'VALUE', Python.ORDER_NONE) || '0'; - const varName = Blockly.Python.nameDB_.getName( + const varName = Python.nameDB_.getName( block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); return varName + ' = ' + argument0 + '\n'; }; diff --git a/generators/python/variables_dynamic.js b/generators/python/variables_dynamic.js index db5bfc9565e..96f8d10c4b0 100644 --- a/generators/python/variables_dynamic.js +++ b/generators/python/variables_dynamic.js @@ -9,12 +9,13 @@ */ 'use strict'; -goog.provide('Blockly.Python.variablesDynamic'); +goog.module('Blockly.Python.variablesDynamic'); -goog.require('Blockly.Python'); -goog.require('Blockly.Python.variables'); +const Python = goog.require('Blockly.Python'); +// Required for side effects. +const variables = goog.require('Blockly.Python.variables'); // Python is dynamically typed. -Blockly.Python['variables_get_dynamic'] = Blockly.Python['variables_get']; -Blockly.Python['variables_set_dynamic'] = Blockly.Python['variables_set']; +Python['variables_get_dynamic'] = Python['variables_get']; +Python['variables_set_dynamic'] = Python['variables_set']; diff --git a/tests/deps.js b/tests/deps.js index 00a200c2c9d..204f00bb5bb 100644 --- a/tests/deps.js +++ b/tests/deps.js @@ -264,55 +264,55 @@ goog.addDependency('../../core/workspace_dragger.js', ['Blockly.WorkspaceDragger goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ComponentManager', 'Blockly.ConnectionDB', 'Blockly.ContextMenu', 'Blockly.ContextMenuRegistry', 'Blockly.DropDownDiv', 'Blockly.Events.BlockCreate', 'Blockly.Events.ThemeChange', 'Blockly.Events.ViewportChange', 'Blockly.Events.utils', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.IASTNodeLocationSvg', 'Blockly.MarkerManager', 'Blockly.MetricsManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.Tooltip', 'Blockly.TouchGesture', 'Blockly.WidgetDiv', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.browserEvents', 'Blockly.common', 'Blockly.internalConstants', 'Blockly.registry', 'Blockly.serialization.blocks', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.array', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.svgMath', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/xml.js', ['Blockly.Xml'], ['Blockly.Events.utils', 'Blockly.inputTypes', 'Blockly.utils.Size', 'Blockly.utils.dom', 'Blockly.utils.xml'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/zoom_controls.js', ['Blockly.ZoomControls'], ['Blockly.ComponentManager', 'Blockly.Css', 'Blockly.Events.Click', 'Blockly.Events.utils', 'Blockly.IPositionable', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.internalConstants', 'Blockly.uiPosition', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es6', 'module': 'goog'}); -goog.addDependency('../../generators/dart.js', ['Blockly.Dart'], ['Blockly.Generator', 'Blockly.inputTypes', 'Blockly.utils.string'], {'lang': 'es6'}); -goog.addDependency('../../generators/dart/colour.js', ['Blockly.Dart.colour'], ['Blockly.Dart'], {'lang': 'es6'}); -goog.addDependency('../../generators/dart/lists.js', ['Blockly.Dart.lists'], ['Blockly.Dart'], {'lang': 'es6'}); -goog.addDependency('../../generators/dart/logic.js', ['Blockly.Dart.logic'], ['Blockly.Dart'], {'lang': 'es6'}); -goog.addDependency('../../generators/dart/loops.js', ['Blockly.Dart.loops'], ['Blockly.Dart'], {'lang': 'es6'}); -goog.addDependency('../../generators/dart/math.js', ['Blockly.Dart.math'], ['Blockly.Dart'], {'lang': 'es6'}); -goog.addDependency('../../generators/dart/procedures.js', ['Blockly.Dart.procedures'], ['Blockly.Dart'], {'lang': 'es6'}); -goog.addDependency('../../generators/dart/text.js', ['Blockly.Dart.texts'], ['Blockly.Dart'], {'lang': 'es6'}); -goog.addDependency('../../generators/dart/variables.js', ['Blockly.Dart.variables'], ['Blockly.Dart'], {'lang': 'es6'}); -goog.addDependency('../../generators/dart/variables_dynamic.js', ['Blockly.Dart.variablesDynamic'], ['Blockly.Dart', 'Blockly.Dart.variables']); -goog.addDependency('../../generators/javascript.js', ['Blockly.JavaScript'], ['Blockly.Generator', 'Blockly.inputTypes', 'Blockly.utils.global', 'Blockly.utils.object', 'Blockly.utils.string'], {'lang': 'es6'}); -goog.addDependency('../../generators/javascript/colour.js', ['Blockly.JavaScript.colour'], ['Blockly.JavaScript'], {'lang': 'es6'}); -goog.addDependency('../../generators/javascript/lists.js', ['Blockly.JavaScript.lists'], ['Blockly.JavaScript'], {'lang': 'es6'}); -goog.addDependency('../../generators/javascript/logic.js', ['Blockly.JavaScript.logic'], ['Blockly.JavaScript'], {'lang': 'es6'}); -goog.addDependency('../../generators/javascript/loops.js', ['Blockly.JavaScript.loops'], ['Blockly.JavaScript'], {'lang': 'es6'}); -goog.addDependency('../../generators/javascript/math.js', ['Blockly.JavaScript.math'], ['Blockly.JavaScript'], {'lang': 'es6'}); -goog.addDependency('../../generators/javascript/procedures.js', ['Blockly.JavaScript.procedures'], ['Blockly.JavaScript'], {'lang': 'es6'}); -goog.addDependency('../../generators/javascript/text.js', ['Blockly.JavaScript.texts'], ['Blockly.JavaScript'], {'lang': 'es6'}); -goog.addDependency('../../generators/javascript/variables.js', ['Blockly.JavaScript.variables'], ['Blockly.JavaScript'], {'lang': 'es6'}); -goog.addDependency('../../generators/javascript/variables_dynamic.js', ['Blockly.JavaScript.variablesDynamic'], ['Blockly.JavaScript', 'Blockly.JavaScript.variables']); -goog.addDependency('../../generators/lua.js', ['Blockly.Lua'], ['Blockly.Generator', 'Blockly.inputTypes', 'Blockly.utils.object', 'Blockly.utils.string'], {'lang': 'es6'}); -goog.addDependency('../../generators/lua/colour.js', ['Blockly.Lua.colour'], ['Blockly.Lua'], {'lang': 'es6'}); -goog.addDependency('../../generators/lua/lists.js', ['Blockly.Lua.lists'], ['Blockly.Lua'], {'lang': 'es6'}); -goog.addDependency('../../generators/lua/logic.js', ['Blockly.Lua.logic'], ['Blockly.Lua'], {'lang': 'es6'}); -goog.addDependency('../../generators/lua/loops.js', ['Blockly.Lua.loops'], ['Blockly.Lua'], {'lang': 'es6'}); -goog.addDependency('../../generators/lua/math.js', ['Blockly.Lua.math'], ['Blockly.Lua'], {'lang': 'es6'}); -goog.addDependency('../../generators/lua/procedures.js', ['Blockly.Lua.procedures'], ['Blockly.Lua'], {'lang': 'es6'}); -goog.addDependency('../../generators/lua/text.js', ['Blockly.Lua.texts'], ['Blockly.Lua'], {'lang': 'es6'}); -goog.addDependency('../../generators/lua/variables.js', ['Blockly.Lua.variables'], ['Blockly.Lua'], {'lang': 'es6'}); -goog.addDependency('../../generators/lua/variables_dynamic.js', ['Blockly.Lua.variablesDynamic'], ['Blockly.Lua', 'Blockly.Lua.variables']); -goog.addDependency('../../generators/php.js', ['Blockly.PHP'], ['Blockly.Generator', 'Blockly.inputTypes', 'Blockly.utils.object', 'Blockly.utils.string'], {'lang': 'es6'}); -goog.addDependency('../../generators/php/colour.js', ['Blockly.PHP.colour'], ['Blockly.PHP'], {'lang': 'es6'}); -goog.addDependency('../../generators/php/lists.js', ['Blockly.PHP.lists'], ['Blockly.PHP'], {'lang': 'es6'}); -goog.addDependency('../../generators/php/logic.js', ['Blockly.PHP.logic'], ['Blockly.PHP'], {'lang': 'es6'}); -goog.addDependency('../../generators/php/loops.js', ['Blockly.PHP.loops'], ['Blockly.PHP'], {'lang': 'es6'}); -goog.addDependency('../../generators/php/math.js', ['Blockly.PHP.math'], ['Blockly.PHP'], {'lang': 'es6'}); -goog.addDependency('../../generators/php/procedures.js', ['Blockly.PHP.procedures'], ['Blockly.PHP'], {'lang': 'es6'}); -goog.addDependency('../../generators/php/text.js', ['Blockly.PHP.texts'], ['Blockly.PHP'], {'lang': 'es6'}); -goog.addDependency('../../generators/php/variables.js', ['Blockly.PHP.variables'], ['Blockly.PHP'], {'lang': 'es6'}); -goog.addDependency('../../generators/php/variables_dynamic.js', ['Blockly.PHP.variablesDynamic'], ['Blockly.PHP', 'Blockly.PHP.variables']); -goog.addDependency('../../generators/python.js', ['Blockly.Python'], ['Blockly.Generator', 'Blockly.inputTypes', 'Blockly.utils.string'], {'lang': 'es6'}); -goog.addDependency('../../generators/python/colour.js', ['Blockly.Python.colour'], ['Blockly.Python'], {'lang': 'es6'}); -goog.addDependency('../../generators/python/lists.js', ['Blockly.Python.lists'], ['Blockly.Python'], {'lang': 'es6'}); -goog.addDependency('../../generators/python/logic.js', ['Blockly.Python.logic'], ['Blockly.Python'], {'lang': 'es6'}); -goog.addDependency('../../generators/python/loops.js', ['Blockly.Python.loops'], ['Blockly.Python'], {'lang': 'es6'}); -goog.addDependency('../../generators/python/math.js', ['Blockly.Python.math'], ['Blockly.Python'], {'lang': 'es6'}); -goog.addDependency('../../generators/python/procedures.js', ['Blockly.Python.procedures'], ['Blockly.Python'], {'lang': 'es6'}); -goog.addDependency('../../generators/python/text.js', ['Blockly.Python.texts'], ['Blockly.Python'], {'lang': 'es6'}); -goog.addDependency('../../generators/python/variables.js', ['Blockly.Python.variables'], ['Blockly.Python'], {'lang': 'es6'}); -goog.addDependency('../../generators/python/variables_dynamic.js', ['Blockly.Python.variablesDynamic'], ['Blockly.Python', 'Blockly.Python.variables']); +goog.addDependency('../../generators/dart.js', ['Blockly.Dart'], ['Blockly', 'Blockly.Generator', 'Blockly.Names', 'Blockly.Variables', 'Blockly.inputTypes', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/dart/colour.js', ['Blockly.Dart.colour'], ['Blockly.Dart'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/dart/lists.js', ['Blockly.Dart.lists'], ['Blockly', 'Blockly.Dart'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/dart/logic.js', ['Blockly.Dart.logic'], ['Blockly.Dart'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/dart/loops.js', ['Blockly.Dart.loops'], ['Blockly', 'Blockly.Constants.Loops', 'Blockly.Dart'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/dart/math.js', ['Blockly.Dart.math'], ['Blockly', 'Blockly.Dart'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/dart/procedures.js', ['Blockly.Dart.procedures'], ['Blockly', 'Blockly.Dart'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/dart/text.js', ['Blockly.Dart.texts'], ['Blockly', 'Blockly.Dart'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/dart/variables.js', ['Blockly.Dart.variables'], ['Blockly', 'Blockly.Dart'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/dart/variables_dynamic.js', ['Blockly.Dart.variablesDynamic'], ['Blockly.Dart', 'Blockly.Dart.variables'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/javascript.js', ['Blockly.JavaScript'], ['Blockly', 'Blockly.Generator', 'Blockly.Names', 'Blockly.Variables', 'Blockly.inputTypes', 'Blockly.utils.global', 'Blockly.utils.object', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/javascript/colour.js', ['Blockly.JavaScript.colour'], ['Blockly.JavaScript'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/javascript/lists.js', ['Blockly.JavaScript.lists'], ['Blockly', 'Blockly.JavaScript'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/javascript/logic.js', ['Blockly.JavaScript.logic'], ['Blockly.JavaScript'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/javascript/loops.js', ['Blockly.JavaScript.loops'], ['Blockly', 'Blockly.Constants.Loops', 'Blockly.JavaScript'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/javascript/math.js', ['Blockly.JavaScript.math'], ['Blockly', 'Blockly.JavaScript'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/javascript/procedures.js', ['Blockly.JavaScript.procedures'], ['Blockly', 'Blockly.JavaScript'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/javascript/text.js', ['Blockly.JavaScript.texts'], ['Blockly', 'Blockly.JavaScript'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/javascript/variables.js', ['Blockly.JavaScript.variables'], ['Blockly', 'Blockly.JavaScript'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/javascript/variables_dynamic.js', ['Blockly.JavaScript.variablesDynamic'], ['Blockly.JavaScript', 'Blockly.JavaScript.variables'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/lua.js', ['Blockly.Lua'], ['Blockly', 'Blockly.Generator', 'Blockly.Names', 'Blockly.inputTypes', 'Blockly.utils.object', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/lua/colour.js', ['Blockly.Lua.colour'], ['Blockly.Lua'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/lua/lists.js', ['Blockly.Lua.lists'], ['Blockly', 'Blockly.Lua'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/lua/logic.js', ['Blockly.Lua.logic'], ['Blockly.Lua'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/lua/loops.js', ['Blockly.Lua.loops'], ['Blockly', 'Blockly.Constants.Loops', 'Blockly.Lua'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/lua/math.js', ['Blockly.Lua.math'], ['Blockly', 'Blockly.Lua'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/lua/procedures.js', ['Blockly.Lua.procedures'], ['Blockly', 'Blockly.Lua'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/lua/text.js', ['Blockly.Lua.texts'], ['Blockly', 'Blockly.Lua'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/lua/variables.js', ['Blockly.Lua.variables'], ['Blockly', 'Blockly.Lua'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/lua/variables_dynamic.js', ['Blockly.Lua.variablesDynamic'], ['Blockly.Lua', 'Blockly.Lua.variables'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/php.js', ['Blockly.PHP'], ['Blockly', 'Blockly.Generator', 'Blockly.Names', 'Blockly.inputTypes', 'Blockly.utils.object', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/php/colour.js', ['Blockly.PHP.colour'], ['Blockly.PHP'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/php/lists.js', ['Blockly.PHP.lists'], ['Blockly', 'Blockly.PHP'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/php/logic.js', ['Blockly.PHP.logic'], ['Blockly.PHP'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/php/loops.js', ['Blockly.PHP.loops'], ['Blockly', 'Blockly.Constants.Loops', 'Blockly.PHP'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/php/math.js', ['Blockly.PHP.math'], ['Blockly', 'Blockly.PHP'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/php/procedures.js', ['Blockly.PHP.procedures'], ['Blockly', 'Blockly.Names', 'Blockly.PHP', 'Blockly.Variables'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/php/text.js', ['Blockly.PHP.texts'], ['Blockly', 'Blockly.PHP'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/php/variables.js', ['Blockly.PHP.variables'], ['Blockly', 'Blockly.PHP'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/php/variables_dynamic.js', ['Blockly.PHP.variablesDynamic'], ['Blockly.PHP', 'Blockly.PHP.variables'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/python.js', ['Blockly.Python'], ['Blockly', 'Blockly.Generator', 'Blockly.Names', 'Blockly.Variables', 'Blockly.inputTypes', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/python/colour.js', ['Blockly.Python.colour'], ['Blockly.Python'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/python/lists.js', ['Blockly.Python.lists'], ['Blockly', 'Blockly.Python'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/python/logic.js', ['Blockly.Python.logic'], ['Blockly.Python'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/python/loops.js', ['Blockly.Python.loops'], ['Blockly', 'Blockly.Constants.Loops', 'Blockly.Python'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/python/math.js', ['Blockly.Python.math'], ['Blockly', 'Blockly.Python'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/python/procedures.js', ['Blockly.Python.procedures'], ['Blockly', 'Blockly.Names', 'Blockly.Python', 'Blockly.Variables'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/python/text.js', ['Blockly.Python.texts'], ['Blockly', 'Blockly.Python'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/python/variables.js', ['Blockly.Python.variables'], ['Blockly', 'Blockly.Python'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../generators/python/variables_dynamic.js', ['Blockly.Python.variablesDynamic'], ['Blockly.Python', 'Blockly.Python.variables'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('base.js', [], []);