2016-08-11 18:47:34 -04:00
|
|
|
var Cast = require('../util/cast.js');
|
|
|
|
|
2016-06-09 14:29:07 -04:00
|
|
|
function Scratch3OperatorsBlocks(runtime) {
|
|
|
|
/**
|
|
|
|
* The runtime instantiating this block package.
|
|
|
|
* @type {Runtime}
|
|
|
|
*/
|
|
|
|
this.runtime = runtime;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve the block primitives implemented by this package.
|
|
|
|
* @return {Object.<string, Function>} Mapping of opcode to Function.
|
|
|
|
*/
|
|
|
|
Scratch3OperatorsBlocks.prototype.getPrimitives = function() {
|
|
|
|
return {
|
|
|
|
'math_number': this.number,
|
2016-07-06 14:13:03 -04:00
|
|
|
'math_positive_number': this.number,
|
|
|
|
'math_whole_number': this.number,
|
2016-08-08 16:44:48 -04:00
|
|
|
'math_angle': this.number,
|
2016-06-10 10:36:05 -04:00
|
|
|
'text': this.text,
|
2016-06-14 18:08:41 -04:00
|
|
|
'operator_add': this.add,
|
2016-06-20 14:42:06 -04:00
|
|
|
'operator_subtract': this.subtract,
|
|
|
|
'operator_multiply': this.multiply,
|
|
|
|
'operator_divide': this.divide,
|
|
|
|
'operator_lt': this.lt,
|
2016-06-17 15:10:28 -04:00
|
|
|
'operator_equals': this.equals,
|
2016-06-20 14:42:06 -04:00
|
|
|
'operator_gt': this.gt,
|
|
|
|
'operator_and': this.and,
|
|
|
|
'operator_or': this.or,
|
2016-06-20 14:42:56 -04:00
|
|
|
'operator_not': this.not,
|
2016-08-11 12:05:58 -04:00
|
|
|
'operator_random': this.random,
|
|
|
|
'operator_join': this.join,
|
|
|
|
'operator_letter_of': this.letterOf,
|
|
|
|
'operator_length': this.length,
|
|
|
|
'operator_mod': this.mod,
|
|
|
|
'operator_round': this.round,
|
|
|
|
'operator_mathop_menu': this.mathopMenu,
|
|
|
|
'operator_mathop': this.mathop
|
2016-06-09 14:29:07 -04:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2016-06-10 10:36:05 -04:00
|
|
|
Scratch3OperatorsBlocks.prototype.number = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.toNumber(args.NUM);
|
2016-06-09 14:29:07 -04:00
|
|
|
};
|
|
|
|
|
2016-06-10 10:36:05 -04:00
|
|
|
Scratch3OperatorsBlocks.prototype.text = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.toString(args.TEXT);
|
2016-06-10 10:36:05 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.add = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.toNumber(args.NUM1) + Cast.toNumber(args.NUM2);
|
2016-06-09 14:29:07 -04:00
|
|
|
};
|
|
|
|
|
2016-06-20 14:42:06 -04:00
|
|
|
Scratch3OperatorsBlocks.prototype.subtract = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.toNumber(args.NUM1) - Cast.toNumber(args.NUM2);
|
2016-06-20 14:42:06 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.multiply = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.toNumber(args.NUM1) * Cast.toNumber(args.NUM2);
|
2016-06-20 14:42:06 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.divide = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.toNumber(args.NUM1) / Cast.toNumber(args.NUM2);
|
2016-06-20 14:42:06 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.lt = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.compare(args.OPERAND1, args.OPERAND2) < 0;
|
2016-06-20 14:42:06 -04:00
|
|
|
};
|
|
|
|
|
2016-06-10 10:36:05 -04:00
|
|
|
Scratch3OperatorsBlocks.prototype.equals = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.compare(args.OPERAND1, args.OPERAND2) == 0;
|
2016-06-10 10:36:05 -04:00
|
|
|
};
|
|
|
|
|
2016-06-20 14:42:06 -04:00
|
|
|
Scratch3OperatorsBlocks.prototype.gt = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.compare(args.OPERAND1, args.OPERAND2) > 0;
|
2016-06-20 14:42:06 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.and = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.toBoolean(args.OPERAND1 && args.OPERAND2);
|
2016-06-20 14:42:06 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.or = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.toBoolean(args.OPERAND1 || args.OPERAND2);
|
2016-06-20 14:42:06 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.not = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.toBoolean(!args.OPERAND);
|
2016-06-20 14:42:06 -04:00
|
|
|
};
|
|
|
|
|
2016-06-30 16:57:12 -04:00
|
|
|
Scratch3OperatorsBlocks.prototype.random = function (args) {
|
2016-06-30 19:04:15 -04:00
|
|
|
var low = args.FROM <= args.TO ? args.FROM : args.TO;
|
|
|
|
var high = args.FROM <= args.TO ? args.TO : args.FROM;
|
|
|
|
if (low == high) return low;
|
|
|
|
// If both low and high are ints, truncate the result to an int.
|
|
|
|
var lowInt = low == parseInt(low);
|
|
|
|
var highInt = high == parseInt(high);
|
|
|
|
if (lowInt && highInt) {
|
|
|
|
return low + parseInt(Math.random() * ((high + 1) - low));
|
|
|
|
}
|
|
|
|
return (Math.random() * (high - low)) + low;
|
2016-06-17 15:10:28 -04:00
|
|
|
};
|
|
|
|
|
2016-08-11 12:05:58 -04:00
|
|
|
Scratch3OperatorsBlocks.prototype.join = function (args) {
|
2016-08-11 19:00:11 -04:00
|
|
|
return Cast.toString(args.STRING1) + Cast.toString(args.STRING2);
|
2016-08-11 12:05:58 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.letterOf = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
var index = Cast.toNumber(args.LETTER) - 1;
|
|
|
|
var str = Cast.toString(args.STRING);
|
2016-08-11 12:05:58 -04:00
|
|
|
// Out of bounds?
|
|
|
|
if (index < 0 || index >= str.length) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
return str.charAt(index);
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.length = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Cast.toString(args.STRING).length;
|
2016-08-11 12:05:58 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.mod = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
var n = Cast.toNumber(args.NUM1);
|
|
|
|
var modulus = Cast.toNumber(args.NUM2);
|
2016-08-11 12:05:58 -04:00
|
|
|
var result = n % modulus;
|
|
|
|
// Scratch mod is kept positive.
|
|
|
|
if (result / modulus < 0) result += modulus;
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.round = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
return Math.round(Cast.toNumber(args.NUM));
|
2016-08-11 12:05:58 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.mathopMenu = function (args) {
|
|
|
|
return args.OPERATOR;
|
|
|
|
};
|
|
|
|
|
|
|
|
Scratch3OperatorsBlocks.prototype.mathop = function (args) {
|
2016-08-11 18:47:34 -04:00
|
|
|
var operator = Cast.toString(args.OPERATOR).toLowerCase();
|
|
|
|
var n = Cast.toNumber(args.NUM);
|
2016-08-11 12:05:58 -04:00
|
|
|
switch (operator) {
|
|
|
|
case 'abs': return Math.abs(n);
|
|
|
|
case 'floor': return Math.floor(n);
|
|
|
|
case 'ceiling': return Math.ceil(n);
|
|
|
|
case 'sqrt': return Math.sqrt(n);
|
|
|
|
case 'sin': return Math.sin((Math.PI * n) / 180);
|
|
|
|
case 'cos': return Math.cos((Math.PI * n) / 180);
|
|
|
|
case 'tan': return Math.tan((Math.PI * n) / 180);
|
|
|
|
case 'asin': return (Math.asin(n) * 180) / Math.PI;
|
|
|
|
case 'acos': return (Math.acos(n) * 180) / Math.PI;
|
|
|
|
case 'atan': return (Math.atan(n) * 180) / Math.PI;
|
|
|
|
case 'ln': return Math.log(n);
|
|
|
|
case 'log': return Math.log(n) / Math.LN10;
|
|
|
|
case 'e ^': return Math.exp(n);
|
|
|
|
case '10 ^': return Math.pow(10, n);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
2016-06-09 14:29:07 -04:00
|
|
|
module.exports = Scratch3OperatorsBlocks;
|