mirror of
https://github.com/google/blockly.git
synced 2026-01-04 23:50:12 +01:00
New initial commit with .svn directories and their contents ignored.
This commit is contained in:
200
generators/javascript/loops.js
Normal file
200
generators/javascript/loops.js
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* Visual Blocks Language
|
||||
*
|
||||
* Copyright 2012 Google Inc.
|
||||
* http://blockly.googlecode.com/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Generating JavaScript for loop blocks.
|
||||
* @author fraser@google.com (Neil Fraser)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.JavaScript.loops');
|
||||
|
||||
goog.require('Blockly.JavaScript');
|
||||
|
||||
|
||||
Blockly.JavaScript['controls_repeat'] = function(block) {
|
||||
// Repeat n times (internal number).
|
||||
var repeats = Number(block.getTitleValue('TIMES'));
|
||||
var branch = Blockly.JavaScript.statementToCode(block, 'DO');
|
||||
if (Blockly.JavaScript.INFINITE_LOOP_TRAP) {
|
||||
branch = Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g,
|
||||
'\'' + block.id + '\'') + branch;
|
||||
}
|
||||
var loopVar = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'count', Blockly.Variables.NAME_TYPE);
|
||||
var code = 'for (var ' + loopVar + ' = 0; ' +
|
||||
loopVar + ' < ' + repeats + '; ' +
|
||||
loopVar + '++) {\n' +
|
||||
branch + '}\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.JavaScript['controls_repeat_ext'] = function(block) {
|
||||
// Repeat n times (external number).
|
||||
var repeats = Blockly.JavaScript.valueToCode(block, 'TIMES',
|
||||
Blockly.JavaScript.ORDER_ASSIGNMENT) || '0';
|
||||
var branch = Blockly.JavaScript.statementToCode(block, 'DO');
|
||||
if (Blockly.JavaScript.INFINITE_LOOP_TRAP) {
|
||||
branch = Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g,
|
||||
'\'' + block.id + '\'') + branch;
|
||||
}
|
||||
var code = '';
|
||||
var loopVar = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'count', Blockly.Variables.NAME_TYPE);
|
||||
var endVar = repeats;
|
||||
if (!repeats.match(/^\w+$/) && !Blockly.isNumber(repeats)) {
|
||||
var endVar = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'repeat_end', Blockly.Variables.NAME_TYPE);
|
||||
code += 'var ' + endVar + ' = ' + repeats + ';\n';
|
||||
}
|
||||
code += 'for (var ' + loopVar + ' = 0; ' +
|
||||
loopVar + ' < ' + endVar + '; ' +
|
||||
loopVar + '++) {\n' +
|
||||
branch + '}\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.JavaScript['controls_whileUntil'] = function(block) {
|
||||
// Do while/until loop.
|
||||
var until = block.getTitleValue('MODE') == 'UNTIL';
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'BOOL',
|
||||
until ? Blockly.JavaScript.ORDER_LOGICAL_NOT :
|
||||
Blockly.JavaScript.ORDER_NONE) || 'false';
|
||||
var branch = Blockly.JavaScript.statementToCode(block, 'DO');
|
||||
if (Blockly.JavaScript.INFINITE_LOOP_TRAP) {
|
||||
branch = Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g,
|
||||
'\'' + block.id + '\'') + branch;
|
||||
}
|
||||
if (until) {
|
||||
argument0 = '!' + argument0;
|
||||
}
|
||||
return 'while (' + argument0 + ') {\n' + branch + '}\n';
|
||||
};
|
||||
|
||||
Blockly.JavaScript['controls_for'] = function(block) {
|
||||
// For loop.
|
||||
var variable0 = Blockly.JavaScript.variableDB_.getName(
|
||||
block.getTitleValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'FROM',
|
||||
Blockly.JavaScript.ORDER_ASSIGNMENT) || '0';
|
||||
var argument1 = Blockly.JavaScript.valueToCode(block, 'TO',
|
||||
Blockly.JavaScript.ORDER_ASSIGNMENT) || '0';
|
||||
var increment = Blockly.JavaScript.valueToCode(block, 'BY',
|
||||
Blockly.JavaScript.ORDER_ASSIGNMENT) || '1';
|
||||
var branch = Blockly.JavaScript.statementToCode(block, 'DO');
|
||||
if (Blockly.JavaScript.INFINITE_LOOP_TRAP) {
|
||||
branch = Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g,
|
||||
'\'' + block.id + '\'') + branch;
|
||||
}
|
||||
var code;
|
||||
if (Blockly.isNumber(argument0) && Blockly.isNumber(argument1) &&
|
||||
Blockly.isNumber(increment)) {
|
||||
// All arguments are simple numbers.
|
||||
var up = parseFloat(argument0) <= parseFloat(argument1);
|
||||
code = 'for (' + variable0 + ' = ' + argument0 + '; ' +
|
||||
variable0 + (up ? ' <= ' : ' >= ') + argument1 + '; ' +
|
||||
variable0;
|
||||
var step = Math.abs(parseFloat(increment));
|
||||
if (step == 1) {
|
||||
code += up ? '++' : '--';
|
||||
} else {
|
||||
code += (up ? ' += ' : ' -= ') + step;
|
||||
}
|
||||
code += ') {\n' + branch + '}\n';
|
||||
} else {
|
||||
code = '';
|
||||
// Cache non-trivial values to variables to prevent repeated look-ups.
|
||||
var startVar = argument0;
|
||||
if (!argument0.match(/^\w+$/) && !Blockly.isNumber(argument0)) {
|
||||
var startVar = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
variable0 + '_start', Blockly.Variables.NAME_TYPE);
|
||||
code += 'var ' + startVar + ' = ' + argument0 + ';\n';
|
||||
}
|
||||
var endVar = argument1;
|
||||
if (!argument1.match(/^\w+$/) && !Blockly.isNumber(argument1)) {
|
||||
var endVar = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
variable0 + '_end', Blockly.Variables.NAME_TYPE);
|
||||
code += 'var ' + endVar + ' = ' + argument1 + ';\n';
|
||||
}
|
||||
// Determine loop direction at start, in case one of the bounds
|
||||
// changes during loop execution.
|
||||
var incVar = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
variable0 + '_inc', Blockly.Variables.NAME_TYPE);
|
||||
code += 'var ' + incVar + ' = ';
|
||||
if (Blockly.isNumber(increment)) {
|
||||
code += Math.abs(increment) + ';\n';
|
||||
} else {
|
||||
code += 'Math.abs(' + increment + ');\n';
|
||||
}
|
||||
code += 'if (' + startVar + ' > ' + endVar + ') {\n';
|
||||
code += ' ' + incVar + ' = -' + incVar +';\n';
|
||||
code += '}\n';
|
||||
code += 'for (' + variable0 + ' = ' + startVar + ';\n' +
|
||||
' ' + incVar + ' >= 0 ? ' +
|
||||
variable0 + ' <= ' + endVar + ' : ' +
|
||||
variable0 + ' >= ' + endVar + ';\n' +
|
||||
' ' + variable0 + ' += ' + incVar + ') {\n' +
|
||||
branch + '}\n';
|
||||
}
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.JavaScript['controls_forEach'] = function(block) {
|
||||
// For each loop.
|
||||
var variable0 = Blockly.JavaScript.variableDB_.getName(
|
||||
block.getTitleValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'LIST',
|
||||
Blockly.JavaScript.ORDER_ASSIGNMENT) || '[]';
|
||||
var branch = Blockly.JavaScript.statementToCode(block, 'DO');
|
||||
if (Blockly.JavaScript.INFINITE_LOOP_TRAP) {
|
||||
branch = Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g,
|
||||
'\'' + block.id + '\'') + branch;
|
||||
}
|
||||
var code;
|
||||
var indexVar = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
variable0 + '_index', Blockly.Variables.NAME_TYPE);
|
||||
if (argument0.match(/^\w+$/)) {
|
||||
branch = ' ' + variable0 + ' = ' + argument0 + '[' + indexVar + '];\n' +
|
||||
branch;
|
||||
code = 'for (var ' + indexVar + ' in ' + argument0 + ') {\n' +
|
||||
branch + '}\n';
|
||||
} else {
|
||||
// The list appears to be more complicated than a simple variable.
|
||||
// Cache it to a variable to prevent repeated look-ups.
|
||||
var listVar = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
variable0 + '_list', Blockly.Variables.NAME_TYPE);
|
||||
branch = ' ' + variable0 + ' = ' + listVar + '[' + indexVar + '];\n' +
|
||||
branch;
|
||||
code = 'var ' + listVar + ' = ' + argument0 + ';\n' +
|
||||
'for (var ' + indexVar + ' in ' + listVar + ') {\n' +
|
||||
branch + '}\n';
|
||||
}
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.JavaScript['controls_flow_statements'] = function(block) {
|
||||
// Flow statements: continue, break.
|
||||
switch (block.getTitleValue('FLOW')) {
|
||||
case 'BREAK':
|
||||
return 'break;\n';
|
||||
case 'CONTINUE':
|
||||
return 'continue;\n';
|
||||
}
|
||||
throw 'Unknown flow statement.';
|
||||
};
|
||||
Reference in New Issue
Block a user