mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
Automatic commit Sat Jan 11 03:00:02 PST 2014
This commit is contained in:
@@ -112,6 +112,9 @@ Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
|
||||
Blockly.JavaScript.init = function() {
|
||||
// Create a dictionary of definitions to be printed before the code.
|
||||
Blockly.JavaScript.definitions_ = Object.create(null);
|
||||
// Create a dictionary mapping desired function names in definitions_
|
||||
// to actual function names (to avoid collisions with user functions).
|
||||
Blockly.JavaScript.functionNames_ = Object.create(null);
|
||||
|
||||
if (Blockly.Variables) {
|
||||
if (!Blockly.JavaScript.variableDB_) {
|
||||
|
||||
@@ -36,18 +36,13 @@ Blockly.JavaScript['colour_picker'] = function(block) {
|
||||
|
||||
Blockly.JavaScript['colour_random'] = function(block) {
|
||||
// Generate a random colour.
|
||||
if (!Blockly.JavaScript.definitions_['colour_random']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'colour_random', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.colour_random.functionName = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '() {');
|
||||
func.push(' var num = Math.floor(Math.random() * Math.pow(2, 24));');
|
||||
func.push(' return \'#\' + (\'00000\' + num.toString(16)).substr(-6);');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['colour_random'] = func.join('\n');
|
||||
}
|
||||
var code = Blockly.JavaScript.colour_random.functionName + '()';
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'colour_random',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
' var num = Math.floor(Math.random() * Math.pow(2, 24));',
|
||||
' return \'#\' + (\'00000\' + num.toString(16)).substr(-6);',
|
||||
'}']);
|
||||
var code = functionName + '()';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
@@ -59,25 +54,19 @@ Blockly.JavaScript['colour_rgb'] = function(block) {
|
||||
Blockly.JavaScript.ORDER_COMMA) || 0;
|
||||
var blue = Blockly.JavaScript.valueToCode(block, 'BLUE',
|
||||
Blockly.JavaScript.ORDER_COMMA) || 0;
|
||||
|
||||
if (!Blockly.JavaScript.definitions_['colour_rgb']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'colour_rgb', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.colour_rgb.functionName = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(r, g, b) {');
|
||||
func.push(' r = Math.max(Math.min(Number(r), 100), 0) * 2.55;');
|
||||
func.push(' g = Math.max(Math.min(Number(g), 100), 0) * 2.55;');
|
||||
func.push(' b = Math.max(Math.min(Number(b), 100), 0) * 2.55;');
|
||||
func.push(' r = (\'0\' + (Math.round(r) || 0).toString(16)).slice(-2);');
|
||||
func.push(' g = (\'0\' + (Math.round(g) || 0).toString(16)).slice(-2);');
|
||||
func.push(' b = (\'0\' + (Math.round(b) || 0).toString(16)).slice(-2);');
|
||||
func.push(' return \'#\' + r + g + b;');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['colour_rgb'] = func.join('\n');
|
||||
}
|
||||
var code = Blockly.JavaScript.colour_rgb.functionName +
|
||||
'(' + red + ', ' + green + ', ' + blue + ')';
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'colour_rgb',
|
||||
[ 'function ' + Blockly.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;',
|
||||
' b = Math.max(Math.min(Number(b), 100), 0) * 2.55;',
|
||||
' r = (\'0\' + (Math.round(r) || 0).toString(16)).slice(-2);',
|
||||
' g = (\'0\' + (Math.round(g) || 0).toString(16)).slice(-2);',
|
||||
' b = (\'0\' + (Math.round(b) || 0).toString(16)).slice(-2);',
|
||||
' return \'#\' + r + g + b;',
|
||||
'}']);
|
||||
var code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
@@ -89,31 +78,25 @@ Blockly.JavaScript['colour_blend'] = function(block) {
|
||||
Blockly.JavaScript.ORDER_COMMA) || '\'#000000\'';
|
||||
var ratio = Blockly.JavaScript.valueToCode(block, 'RATIO',
|
||||
Blockly.JavaScript.ORDER_COMMA) || 0.5;
|
||||
|
||||
if (!Blockly.JavaScript.definitions_['colour_blend']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'colour_blend', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.colour_blend.functionName = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(c1, c2, ratio) {');
|
||||
func.push(' ratio = Math.max(Math.min(Number(ratio), 1), 0);');
|
||||
func.push(' var r1 = parseInt(c1.substring(1, 3), 16);');
|
||||
func.push(' var g1 = parseInt(c1.substring(3, 5), 16);');
|
||||
func.push(' var b1 = parseInt(c1.substring(5, 7), 16);');
|
||||
func.push(' var r2 = parseInt(c2.substring(1, 3), 16);');
|
||||
func.push(' var g2 = parseInt(c2.substring(3, 5), 16);');
|
||||
func.push(' var b2 = parseInt(c2.substring(5, 7), 16);');
|
||||
func.push(' var r = Math.round(r1 * (1 - ratio) + r2 * ratio);');
|
||||
func.push(' var g = Math.round(g1 * (1 - ratio) + g2 * ratio);');
|
||||
func.push(' var b = Math.round(b1 * (1 - ratio) + b2 * ratio);');
|
||||
func.push(' r = (\'0\' + (r || 0).toString(16)).slice(-2);');
|
||||
func.push(' g = (\'0\' + (g || 0).toString(16)).slice(-2);');
|
||||
func.push(' b = (\'0\' + (b || 0).toString(16)).slice(-2);');
|
||||
func.push(' return \'#\' + r + g + b;');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['colour_blend'] = func.join('\n');
|
||||
}
|
||||
var code = Blockly.JavaScript.colour_blend.functionName +
|
||||
'(' + c1 + ', ' + c2 + ', ' + ratio + ')';
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'colour_blend',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(c1, c2, ratio) {',
|
||||
' ratio = Math.max(Math.min(Number(ratio), 1), 0);',
|
||||
' var r1 = parseInt(c1.substring(1, 3), 16);',
|
||||
' var g1 = parseInt(c1.substring(3, 5), 16);',
|
||||
' var b1 = parseInt(c1.substring(5, 7), 16);',
|
||||
' var r2 = parseInt(c2.substring(1, 3), 16);',
|
||||
' var g2 = parseInt(c2.substring(3, 5), 16);',
|
||||
' var b2 = parseInt(c2.substring(5, 7), 16);',
|
||||
' var r = Math.round(r1 * (1 - ratio) + r2 * ratio);',
|
||||
' var g = Math.round(g1 * (1 - ratio) + g2 * ratio);',
|
||||
' var b = Math.round(b1 * (1 - ratio) + b2 * ratio);',
|
||||
' r = (\'0\' + (r || 0).toString(16)).slice(-2);',
|
||||
' g = (\'0\' + (g || 0).toString(16)).slice(-2);',
|
||||
' b = (\'0\' + (b || 0).toString(16)).slice(-2);',
|
||||
' return \'#\' + r + g + b;',
|
||||
'}']);
|
||||
var code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
@@ -46,27 +46,21 @@ Blockly.JavaScript['lists_create_with'] = function(block) {
|
||||
|
||||
Blockly.JavaScript['lists_repeat'] = function(block) {
|
||||
// Create a list with one element repeated.
|
||||
if (!Blockly.JavaScript.definitions_['lists_repeat']) {
|
||||
// Function copied from Closure's goog.array.repeat.
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'lists_repeat', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.lists_repeat.repeat = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(value, n) {');
|
||||
func.push(' var array = [];');
|
||||
func.push(' for (var i = 0; i < n; i++) {');
|
||||
func.push(' array[i] = value;');
|
||||
func.push(' }');
|
||||
func.push(' return array;');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['lists_repeat'] = func.join('\n');
|
||||
}
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'lists_repeat',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(value, n) {',
|
||||
' var array = [];',
|
||||
' for (var i = 0; i < n; i++) {',
|
||||
' array[i] = value;',
|
||||
' }',
|
||||
' return array;',
|
||||
'}']);
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'ITEM',
|
||||
Blockly.JavaScript.ORDER_COMMA) || 'null';
|
||||
var argument1 = Blockly.JavaScript.valueToCode(block, 'NUM',
|
||||
Blockly.JavaScript.ORDER_COMMA) || '0';
|
||||
var code = Blockly.JavaScript.lists_repeat.repeat +
|
||||
'(' + argument0 + ', ' + argument1 + ')';
|
||||
var code = functionName + '(' + argument0 + ', ' + argument1 + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
@@ -149,20 +143,14 @@ Blockly.JavaScript['lists_getIndex'] = function(block) {
|
||||
var code = list + '.slice(-' + at + ')[0]';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'GET_REMOVE' || mode == 'REMOVE') {
|
||||
if (!Blockly.JavaScript.definitions_['lists_remove_from_end']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'lists_remove_from_end', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.lists_getIndex.lists_remove_from_end = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(list, x) {');
|
||||
func.push(' x = list.length - x;');
|
||||
func.push(' return list.splice(x, 1)[0];');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['lists_remove_from_end'] =
|
||||
func.join('\n');
|
||||
}
|
||||
code = Blockly.JavaScript.lists_getIndex.lists_remove_from_end +
|
||||
'(' + list + ', ' + at + ')';
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'lists_remove_from_end',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(list, x) {',
|
||||
' x = list.length - x;',
|
||||
' return list.splice(x, 1)[0];',
|
||||
'}']);
|
||||
code = functionName + '(' + list + ', ' + at + ')';
|
||||
if (mode == 'GET_REMOVE') {
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
@@ -170,24 +158,18 @@ Blockly.JavaScript['lists_getIndex'] = function(block) {
|
||||
}
|
||||
}
|
||||
} else if (where == 'RANDOM') {
|
||||
if (!Blockly.JavaScript.definitions_['lists_get_random_item']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'lists_get_random_item', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.lists_getIndex.random = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(list, remove) {');
|
||||
func.push(' var x = Math.floor(Math.random() * list.length);');
|
||||
func.push(' if (remove) {');
|
||||
func.push(' return list.splice(x, 1)[0];');
|
||||
func.push(' } else {');
|
||||
func.push(' return list[x];');
|
||||
func.push(' }');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['lists_get_random_item'] =
|
||||
func.join('\n');
|
||||
}
|
||||
code = Blockly.JavaScript.lists_getIndex.random +
|
||||
'(' + list + ', ' + (mode != 'GET') + ')';
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'lists_get_random_item',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(list, remove) {',
|
||||
' var x = Math.floor(Math.random() * list.length);',
|
||||
' if (remove) {',
|
||||
' return list.splice(x, 1)[0];',
|
||||
' } else {',
|
||||
' return list[x];',
|
||||
' }',
|
||||
'}']);
|
||||
code = functionName + '(' + list + ', ' + (mode != 'GET') + ')';
|
||||
if (mode == 'GET' || mode == 'GET_REMOVE') {
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
@@ -288,35 +270,29 @@ Blockly.JavaScript['lists_getSublist'] = function(block) {
|
||||
if (where1 == 'FIRST' && where2 == 'LAST') {
|
||||
var code = list + '.concat()';
|
||||
} else {
|
||||
if (!Blockly.JavaScript.definitions_['lists_get_sublist']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'lists_get_sublist', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.lists_getSublist.func = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName +
|
||||
'(list, where1, at1, where2, at2) {');
|
||||
func.push(' function getAt(where, at) {');
|
||||
func.push(' if (where == \'FROM_START\') {');
|
||||
func.push(' at--;');
|
||||
func.push(' } else if (where == \'FROM_END\') {');
|
||||
func.push(' at = list.length - at;');
|
||||
func.push(' } else if (where == \'FIRST\') {');
|
||||
func.push(' at = 0;');
|
||||
func.push(' } else if (where == \'LAST\') {');
|
||||
func.push(' at = list.length - 1;');
|
||||
func.push(' } else {');
|
||||
func.push(' throw \'Unhandled option (lists_getSublist).\';');
|
||||
func.push(' }');
|
||||
func.push(' return at;');
|
||||
func.push(' }');
|
||||
func.push(' at1 = getAt(where1, at1);');
|
||||
func.push(' at2 = getAt(where2, at2) + 1;');
|
||||
func.push(' return list.slice(at1, at2);');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['lists_get_sublist'] =
|
||||
func.join('\n');
|
||||
}
|
||||
var code = Blockly.JavaScript.lists_getSublist.func + '(' + list + ', \'' +
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'lists_get_sublist',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(list, where1, at1, where2, at2) {',
|
||||
' function getAt(where, at) {',
|
||||
' if (where == \'FROM_START\') {',
|
||||
' at--;',
|
||||
' } else if (where == \'FROM_END\') {',
|
||||
' at = list.length - at;',
|
||||
' } else if (where == \'FIRST\') {',
|
||||
' at = 0;',
|
||||
' } else if (where == \'LAST\') {',
|
||||
' at = list.length - 1;',
|
||||
' } else {',
|
||||
' throw \'Unhandled option (lists_getSublist).\';',
|
||||
' }',
|
||||
' return at;',
|
||||
' }',
|
||||
' at1 = getAt(where1, at1);',
|
||||
' at2 = getAt(where2, at2) + 1;',
|
||||
' return list.slice(at1, at2);',
|
||||
'}']);
|
||||
var code = functionName + '(' + list + ', \'' +
|
||||
where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
|
||||
}
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
|
||||
@@ -164,33 +164,28 @@ Blockly.JavaScript['math_number_property'] = function(block) {
|
||||
var code;
|
||||
if (dropdown_property == 'PRIME') {
|
||||
// Prime is a special case as it is not a one-liner test.
|
||||
if (!Blockly.JavaScript.definitions_['isPrime']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'isPrime', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.logic_prime= functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(n) {');
|
||||
func.push(' // http://en.wikipedia.org/wiki/Primality_test#Naive_methods');
|
||||
func.push(' if (n == 2 || n == 3) {');
|
||||
func.push(' return true;');
|
||||
func.push(' }');
|
||||
func.push(' // False if n is NaN, negative, is 1, or not whole.');
|
||||
func.push(' // And false if n is divisible by 2 or 3.');
|
||||
func.push(' if (isNaN(n) || n <= 1 || n % 1 != 0 || n % 2 == 0 ||' +
|
||||
' n % 3 == 0) {');
|
||||
func.push(' return false;');
|
||||
func.push(' }');
|
||||
func.push(' // Check all the numbers of form 6k +/- 1, up to sqrt(n).');
|
||||
func.push(' for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) {');
|
||||
func.push(' if (n % (x - 1) == 0 || n % (x + 1) == 0) {');
|
||||
func.push(' return false;');
|
||||
func.push(' }');
|
||||
func.push(' }');
|
||||
func.push(' return true;');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['isPrime'] = func.join('\n');
|
||||
}
|
||||
code = Blockly.JavaScript.logic_prime + '(' + number_to_check + ')';
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'math_isPrime',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(n) {',
|
||||
' // https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
|
||||
' if (n == 2 || n == 3) {',
|
||||
' return true;',
|
||||
' }',
|
||||
' // False if n is NaN, negative, is 1, or not whole.',
|
||||
' // And false if n is divisible by 2 or 3.',
|
||||
' if (isNaN(n) || n <= 1 || n % 1 != 0 || n % 2 == 0 ||' +
|
||||
' n % 3 == 0) {',
|
||||
' return false;',
|
||||
' }',
|
||||
' // Check all the numbers of form 6k +/- 1, up to sqrt(n).',
|
||||
' for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) {',
|
||||
' if (n % (x - 1) == 0 || n % (x + 1) == 0) {',
|
||||
' return false;',
|
||||
' }',
|
||||
' }',
|
||||
' return true;',
|
||||
'}']);
|
||||
code = functionName + '(' + number_to_check + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
switch (dropdown_property) {
|
||||
@@ -255,131 +250,107 @@ Blockly.JavaScript['math_on_list'] = function(block) {
|
||||
break;
|
||||
case 'AVERAGE':
|
||||
// math_median([null,null,1,3]) == 2.0.
|
||||
if (!Blockly.JavaScript.definitions_['math_mean']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'math_mean', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.math_on_list.math_mean = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(myList) {');
|
||||
func.push(' return myList.reduce(function(x, y) {return x + y;}) / ' +
|
||||
'myList.length;');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['math_mean'] = func.join('\n');
|
||||
}
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'math_mean',
|
||||
[ 'function ' + Blockly.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) || '[]';
|
||||
code = Blockly.JavaScript.math_on_list.math_mean + '(' + list + ')';
|
||||
code = functionName + '(' + list + ')';
|
||||
break;
|
||||
case 'MEDIAN':
|
||||
// math_median([null,null,1,3]) == 2.0.
|
||||
if (!Blockly.JavaScript.definitions_['math_median']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'math_median', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.math_on_list.math_median = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(myList) {');
|
||||
func.push(' var localList = myList.filter(function (x) ' +
|
||||
'{return typeof x == \'number\';});');
|
||||
func.push(' if (!localList.length) return null;');
|
||||
func.push(' localList.sort(function(a, b) {return b - a;});');
|
||||
func.push(' if (localList.length % 2 == 0) {');
|
||||
func.push(' return (localList[localList.length / 2 - 1] + ' +
|
||||
'localList[localList.length / 2]) / 2;');
|
||||
func.push(' } else {');
|
||||
func.push(' return localList[(localList.length - 1) / 2];');
|
||||
func.push(' }');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['math_median'] = func.join('\n');
|
||||
}
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'math_median',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(myList) {',
|
||||
' var localList = myList.filter(function (x) ' +
|
||||
'{return typeof x == \'number\';});',
|
||||
' if (!localList.length) return null;',
|
||||
' localList.sort(function(a, b) {return b - a;});',
|
||||
' if (localList.length % 2 == 0) {',
|
||||
' return (localList[localList.length / 2 - 1] + ' +
|
||||
'localList[localList.length / 2]) / 2;',
|
||||
' } else {',
|
||||
' return localList[(localList.length - 1) / 2];',
|
||||
' }',
|
||||
'}']);
|
||||
list = Blockly.JavaScript.valueToCode(block, 'LIST',
|
||||
Blockly.JavaScript.ORDER_NONE) || '[]';
|
||||
code = Blockly.JavaScript.math_on_list.math_median + '(' + list + ')';
|
||||
code = functionName + '(' + list + ')';
|
||||
break;
|
||||
case 'MODE':
|
||||
if (!Blockly.JavaScript.definitions_['math_modes']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'math_modes', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.math_on_list.math_modes = functionName;
|
||||
// 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].
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(values) {');
|
||||
func.push(' var modes = [];');
|
||||
func.push(' var counts = [];');
|
||||
func.push(' var maxCount = 0;');
|
||||
func.push(' for (var i = 0; i < values.length; i++) {');
|
||||
func.push(' var value = values[i];');
|
||||
func.push(' var found = false;');
|
||||
func.push(' var thisCount;');
|
||||
func.push(' for (var j = 0; j < counts.length; j++) {');
|
||||
func.push(' if (counts[j][0] === value) {');
|
||||
func.push(' thisCount = ++counts[j][1];');
|
||||
func.push(' found = true;');
|
||||
func.push(' break;');
|
||||
func.push(' }');
|
||||
func.push(' }');
|
||||
func.push(' if (!found) {');
|
||||
func.push(' counts.push([value, 1]);');
|
||||
func.push(' thisCount = 1;');
|
||||
func.push(' }');
|
||||
func.push(' maxCount = Math.max(thisCount, maxCount);');
|
||||
func.push(' }');
|
||||
func.push(' for (var j = 0; j < counts.length; j++) {');
|
||||
func.push(' if (counts[j][1] == maxCount) {');
|
||||
func.push(' modes.push(counts[j][0]);');
|
||||
func.push(' }');
|
||||
func.push(' }');
|
||||
func.push(' return modes;');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['math_modes'] = func.join('\n');
|
||||
}
|
||||
// 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].
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'math_modes',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(values) {',
|
||||
' var modes = [];',
|
||||
' var counts = [];',
|
||||
' var maxCount = 0;',
|
||||
' for (var i = 0; i < values.length; i++) {',
|
||||
' var value = values[i];',
|
||||
' var found = false;',
|
||||
' var thisCount;',
|
||||
' for (var j = 0; j < counts.length; j++) {',
|
||||
' if (counts[j][0] === value) {',
|
||||
' thisCount = ++counts[j][1];',
|
||||
' found = true;',
|
||||
' break;',
|
||||
' }',
|
||||
' }',
|
||||
' if (!found) {',
|
||||
' counts.push([value, 1]);',
|
||||
' thisCount = 1;',
|
||||
' }',
|
||||
' maxCount = Math.max(thisCount, maxCount);',
|
||||
' }',
|
||||
' for (var j = 0; j < counts.length; j++) {',
|
||||
' if (counts[j][1] == maxCount) {',
|
||||
' modes.push(counts[j][0]);',
|
||||
' }',
|
||||
' }',
|
||||
' return modes;',
|
||||
'}']);
|
||||
list = Blockly.JavaScript.valueToCode(block, 'LIST',
|
||||
Blockly.JavaScript.ORDER_NONE) || '[]';
|
||||
code = Blockly.JavaScript.math_on_list.math_modes + '(' + list + ')';
|
||||
code = functionName + '(' + list + ')';
|
||||
break;
|
||||
case 'STD_DEV':
|
||||
if (!Blockly.JavaScript.definitions_['math_standard_deviation']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'math_standard_deviation', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.math_on_list.math_standard_deviation = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(numbers) {');
|
||||
func.push(' var n = numbers.length;');
|
||||
func.push(' if (!n) return null;');
|
||||
func.push(' var mean = numbers.reduce(function(x, y) ' +
|
||||
'{return x + y;}) / n;');
|
||||
func.push(' var variance = 0;');
|
||||
func.push(' for (var j = 0; j < n; j++) {');
|
||||
func.push(' variance += Math.pow(numbers[j] - mean, 2);');
|
||||
func.push(' }');
|
||||
func.push(' variance = variance / n;');
|
||||
func.push(' return Math.sqrt(variance);');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['math_standard_deviation'] =
|
||||
func.join('\n');
|
||||
}
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'math_standard_deviation',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(numbers) {',
|
||||
' var n = numbers.length;',
|
||||
' if (!n) return null;',
|
||||
' var mean = numbers.reduce(function(x, y) {return x + y;}) / n;',
|
||||
' var variance = 0;',
|
||||
' for (var j = 0; j < n; j++) {',
|
||||
' variance += Math.pow(numbers[j] - mean, 2);',
|
||||
' }',
|
||||
' variance = variance / n;',
|
||||
' return Math.sqrt(variance);',
|
||||
'}']);
|
||||
list = Blockly.JavaScript.valueToCode(block, 'LIST',
|
||||
Blockly.JavaScript.ORDER_NONE) || '[]';
|
||||
code = Blockly.JavaScript.math_on_list.math_standard_deviation +
|
||||
'(' + list + ')';
|
||||
code = functionName + '(' + list + ')';
|
||||
break;
|
||||
case 'RANDOM':
|
||||
if (!Blockly.JavaScript.definitions_['math_random_item']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'math_random_item', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.math_on_list.math_random_item = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(list) {');
|
||||
func.push(' var x = Math.floor(Math.random() * list.length);');
|
||||
func.push(' return list[x];');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['math_random_item'] = func.join('\n');
|
||||
}
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'math_random_list',
|
||||
[ 'function ' + Blockly.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) || '[]';
|
||||
code = Blockly.JavaScript.math_on_list.math_random_item +
|
||||
'(' + list + ')';
|
||||
code = functionName + '(' + list + ')';
|
||||
break;
|
||||
default:
|
||||
throw 'Unknown operator: ' + func;
|
||||
@@ -416,24 +387,19 @@ Blockly.JavaScript['math_random_int'] = function(block) {
|
||||
Blockly.JavaScript.ORDER_COMMA) || '0';
|
||||
var argument1 = Blockly.JavaScript.valueToCode(block, 'TO',
|
||||
Blockly.JavaScript.ORDER_COMMA) || '0';
|
||||
if (!Blockly.JavaScript.definitions_['math_random_int']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'math_random_int', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.math_random_int.random_function = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(a, b) {');
|
||||
func.push(' if (a > b) {');
|
||||
func.push(' // Swap a and b to ensure a is smaller.');
|
||||
func.push(' var c = a;');
|
||||
func.push(' a = b;');
|
||||
func.push(' b = c;');
|
||||
func.push(' }');
|
||||
func.push(' return Math.floor(Math.random() * (b - a + 1) + a);');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['math_random_int'] = func.join('\n');
|
||||
}
|
||||
var code = Blockly.JavaScript.math_random_int.random_function +
|
||||
'(' + argument0 + ', ' + argument1 + ')';
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'math_random_int',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(a, b) {',
|
||||
' if (a > b) {',
|
||||
' // Swap a and b to ensure a is smaller.',
|
||||
' var c = a;',
|
||||
' a = b;',
|
||||
' b = c;',
|
||||
' }',
|
||||
' return Math.floor(Math.random() * (b - a + 1) + a);',
|
||||
'}']);
|
||||
var code = functionName + '(' + argument0 + ', ' + argument1 + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
|
||||
@@ -127,19 +127,14 @@ Blockly.JavaScript['text_charAt'] = function(block) {
|
||||
var code = text + '.slice(-' + at + ').charAt(0)';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
case 'RANDOM':
|
||||
if (!Blockly.JavaScript.definitions_['text_random_letter']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'text_random_letter', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.text_charAt.text_random_letter = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(text) {');
|
||||
func.push(' var x = Math.floor(Math.random() * text.length);');
|
||||
func.push(' return text[x];');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['text_random_letter'] = func.join('\n');
|
||||
}
|
||||
code = Blockly.JavaScript.text_charAt.text_random_letter +
|
||||
'(' + text + ')';
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'text_random_letter',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(text) {',
|
||||
' var x = Math.floor(Math.random() * text.length);',
|
||||
' return text[x];',
|
||||
'}']);
|
||||
code = functionName + '(' + text + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
throw 'Unhandled option (text_charAt).';
|
||||
@@ -158,35 +153,29 @@ Blockly.JavaScript['text_getSubstring'] = function(block) {
|
||||
if (where1 == 'FIRST' && where2 == 'LAST') {
|
||||
var code = text;
|
||||
} else {
|
||||
if (!Blockly.JavaScript.definitions_['text_get_substring']) {
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'text_get_substring', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.text_getSubstring.func = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName +
|
||||
'(text, where1, at1, where2, at2) {');
|
||||
func.push(' function getAt(where, at) {');
|
||||
func.push(' if (where == \'FROM_START\') {');
|
||||
func.push(' at--;');
|
||||
func.push(' } else if (where == \'FROM_END\') {');
|
||||
func.push(' at = text.length - at;');
|
||||
func.push(' } else if (where == \'FIRST\') {');
|
||||
func.push(' at = 0;');
|
||||
func.push(' } else if (where == \'LAST\') {');
|
||||
func.push(' at = text.length - 1;');
|
||||
func.push(' } else {');
|
||||
func.push(' throw \'Unhandled option (text_getSubstring).\';');
|
||||
func.push(' }');
|
||||
func.push(' return at;');
|
||||
func.push(' }');
|
||||
func.push(' at1 = getAt(where1, at1);');
|
||||
func.push(' at2 = getAt(where2, at2) + 1;');
|
||||
func.push(' return text.slice(at1, at2);');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['text_get_substring'] =
|
||||
func.join('\n');
|
||||
}
|
||||
var code = Blockly.JavaScript.text_getSubstring.func + '(' + text + ', \'' +
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'text_get_substring',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(text, where1, at1, where2, at2) {',
|
||||
' function getAt(where, at) {',
|
||||
' if (where == \'FROM_START\') {',
|
||||
' at--;',
|
||||
' } else if (where == \'FROM_END\') {',
|
||||
' at = text.length - at;',
|
||||
' } else if (where == \'FIRST\') {',
|
||||
' at = 0;',
|
||||
' } else if (where == \'LAST\') {',
|
||||
' at = text.length - 1;',
|
||||
' } else {',
|
||||
' throw \'Unhandled option (text_getSubstring).\';',
|
||||
' }',
|
||||
' return at;',
|
||||
' }',
|
||||
' at1 = getAt(where1, at1);',
|
||||
' at2 = getAt(where2, at2) + 1;',
|
||||
' return text.slice(at1, at2);',
|
||||
'}']);
|
||||
var code = functionName + '(' + text + ', \'' +
|
||||
where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
|
||||
}
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
@@ -207,23 +196,17 @@ Blockly.JavaScript['text_changeCase'] = function(block) {
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
|
||||
code = argument0 + operator;
|
||||
} else {
|
||||
if (!Blockly.JavaScript.definitions_['text_toTitleCase']) {
|
||||
// Title case is not a native JavaScript function. Define one.
|
||||
var functionName = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'text_toTitleCase', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.JavaScript.text_changeCase.toTitleCase = functionName;
|
||||
var func = [];
|
||||
func.push('function ' + functionName + '(str) {');
|
||||
func.push(' return str.replace(/\\S+/g,');
|
||||
func.push(' function(txt) {return txt[0].toUpperCase() + ' +
|
||||
'txt.substring(1).toLowerCase();});');
|
||||
func.push('}');
|
||||
Blockly.JavaScript.definitions_['text_toTitleCase'] = func.join('\n');
|
||||
}
|
||||
// Title case is not a native JavaScript function. Define one.
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'text_toTitleCase',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(str) {',
|
||||
' return str.replace(/\\S+/g,',
|
||||
' function(txt) {return txt[0].toUpperCase() + ' +
|
||||
'txt.substring(1).toLowerCase();});',
|
||||
'}']);
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'TEXT',
|
||||
Blockly.JavaScript.ORDER_NONE) || '\'\'';
|
||||
code = Blockly.JavaScript.text_changeCase.toTitleCase +
|
||||
'(' + argument0 + ')';
|
||||
code = functionName + '(' + argument0 + ')';
|
||||
}
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
@@ -82,16 +82,6 @@ Blockly.Python.ORDER_NONE = 99; // (...)
|
||||
*/
|
||||
Blockly.Python.INFINITE_LOOP_TRAP = null;
|
||||
|
||||
/**
|
||||
* This is used as a placeholder in functions defined using
|
||||
* Blockly.Python.provideFunction_. It must not be legal code that could
|
||||
* legitimately appear in a function definition (or comment), and it must
|
||||
* not confuse the regular expression parser.
|
||||
*/
|
||||
Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ = '{{{}}}';
|
||||
Blockly.Python.FUNCTION_NAME_PLACEHOLDER_REGEXP_ =
|
||||
new RegExp(Blockly.Python.FUNCTION_NAME_PLACEHOLDER_, 'g');
|
||||
|
||||
/**
|
||||
* Initialise the database of variable names.
|
||||
*/
|
||||
@@ -207,31 +197,3 @@ Blockly.Python.scrub_ = function(block, code) {
|
||||
var nextCode = this.blockToCode(nextBlock);
|
||||
return commentCode + code + nextCode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Define a function to be included in the generated code.
|
||||
* The first time this is called with a given desiredName, the code is
|
||||
* saved and an actual name is generated. Subsequent calls with the
|
||||
* same desiredName have no effect but have the same return value.
|
||||
*
|
||||
* It is up to the caller to make sure the same desiredName is not
|
||||
* used for different code values.
|
||||
*
|
||||
* The code gets output when Blockly.Python.finish() is called.
|
||||
*
|
||||
* @param {string} desiredName The desired name of the function (e.g., isPrime).
|
||||
* @param {code} A list of Python statements.
|
||||
* @return {string} The actual name of the new function. This may differ
|
||||
* from desiredName if the former has already been taken by the user.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Python.provideFunction_ = function(desiredName, code) {
|
||||
if (!Blockly.Python.definitions_[desiredName]) {
|
||||
var functionName = Blockly.Python.variableDB_.getDistinctName(
|
||||
desiredName, Blockly.Generator.NAME_TYPE);
|
||||
Blockly.Python.functionNames_[desiredName] = functionName;
|
||||
Blockly.Python.definitions_[desiredName] = code.join('\n').replace(
|
||||
Blockly.Python.FUNCTION_NAME_PLACEHOLDER_REGEXP_, functionName);
|
||||
}
|
||||
return Blockly.Python.functionNames_[desiredName];
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@ Blockly.Python['colour_random'] = function(block) {
|
||||
};
|
||||
|
||||
Blockly.Python['colour_rgb'] = function(block) {
|
||||
// Compose a colour from RGB components.
|
||||
// Compose a colour from RGB components expressed as percentages.
|
||||
var functionName = Blockly.Python.provideFunction_(
|
||||
'colour_rgb',
|
||||
[ 'def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b):',
|
||||
|
||||
@@ -170,9 +170,9 @@ Blockly.Python['math_number_property'] = function(block) {
|
||||
if (dropdown_property == 'PRIME') {
|
||||
Blockly.Python.definitions_['import_math'] = 'import math';
|
||||
var functionName = Blockly.Python.provideFunction_(
|
||||
'isPrime',
|
||||
'math_isPrime',
|
||||
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(n):',
|
||||
' # http://en.wikipedia.org/wiki/Primality_test#Naive_methods',
|
||||
' # https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
|
||||
' # If n is not a number but a string, try parsing it.',
|
||||
' if type(n) not in (int, float, long):',
|
||||
' try:',
|
||||
|
||||
Reference in New Issue
Block a user