mirror of
https://github.com/google/blockly.git
synced 2026-01-06 00:20:37 +01:00
Adding indexing settings, tests and fixing bugs (#464)
* Add indexing setting for JavaScript Generation Adding setting to allow for switching between zero and one based indexing for Blockly Blocks such that the generated code will use this flag to determine whether one based or zero based indexing should be used. One based indexing is enabled by default. * Updating js lists to do zero and one based index Updated generated JavaScript to change depending on whether one based indexing is enabled or not. * Updating js text to do zero and one based index Change so that JavaScript generated for text blocks either assumes blocks use zero or one based index based on setting. * Start of python indexing Start of work on allowing one and zero indexing for generated python for lists. * Fixing bug and lint fixed Fixing bug caused by not setting the return of concat when concatenating lines for sublist and substring functions. Also renamed these functions to be getSubsequece. Fixed lint errors with spacing * Converting from if to switch statements Comverting if statements to switch statements when appropriate and adding spacing. * Modified sublist JavaScript generation Added case so that helper function is not generated if not necessary. Helper function is not generated if list length is not needed or if list is a simple block (such as a variable, as oppossed to a function call or list create). * Stripping unecessary ids Removing ids from xml file. * Localisation updates from https://translatewiki.net. * Fix typo in flyout.js (#403) * Fix typo in flyout.js (#402) * Localisation updates from https://translatewiki.net. * Add indexing setting for JavaScript Generation Adding setting to allow for switching between zero and one based indexing for Blockly Blocks such that the generated code will use this flag to determine whether one based or zero based indexing should be used. One based indexing is enabled by default. * Updating js lists to do zero and one based index Updated generated JavaScript to change depending on whether one based indexing is enabled or not. * Updating js text to do zero and one based index Change so that JavaScript generated for text blocks either assumes blocks use zero or one based index based on setting. * Fixing bug and lint fixed Fixing bug caused by not setting the return of concat when concatenating lines for sublist and substring functions. Also renamed these functions to be getSubsequece. Fixed lint errors with spacing * Converting from if to switch statements Comverting if statements to switch statements when appropriate and adding spacing. * Modified sublist JavaScript generation Added case so that helper function is not generated if not necessary. Helper function is not generated if list length is not needed or if list is a simple block (such as a variable, as oppossed to a function call or list create). * Stripping unecessary ids Removing ids from xml file. * Updating generator test Modifying sublist test and re-formatting spacing between blocks. * Updating js lists to do zero and one based index Updated generated JavaScript to change depending on whether one based indexing is enabled or not. * Updating js text to do zero and one based index Change so that JavaScript generated for text blocks either assumes blocks use zero or one based index based on setting. * Fixing bug and lint fixed Fixing bug caused by not setting the return of concat when concatenating lines for sublist and substring functions. Also renamed these functions to be getSubsequece. Fixed lint errors with spacing * Converting from if to switch statements Comverting if statements to switch statements when appropriate and adding spacing. * Modified sublist JavaScript generation Added case so that helper function is not generated if not necessary. Helper function is not generated if list length is not needed or if list is a simple block (such as a variable, as oppossed to a function call or list create). * Stripping unecessary ids Removing ids from xml file. * Localisation updates from https://translatewiki.net. * Localisation updates from https://translatewiki.net. * Updating js lists to do zero and one based index Updated generated JavaScript to change depending on whether one based indexing is enabled or not. * Fixing bug and lint fixed Fixing bug caused by not setting the return of concat when concatenating lines for sublist and substring functions. Also renamed these functions to be getSubsequece. Fixed lint errors with spacing * Modified sublist JavaScript generation Added case so that helper function is not generated if not necessary. Helper function is not generated if list length is not needed or if list is a simple block (such as a variable, as oppossed to a function call or list create). * Stripping unecessary ids Removing ids from xml file. * Updating generator test Modifying sublist test and re-formatting spacing between blocks. * Adding tests for indexing and extra cases Adding tests for indexing with custom block to adjust number based on what indexing is being generated. * Adding tests and renaming tests Adding tests for sublist and renaming tests. * Fixes for order for sublists Fixes so that parenthesis are generated properly for index for sublist * Cleaning up test generated code Changing order returned for unit test adjust index function to generate less unecessary parenthesis. * Adding tests for order Adding tests for order, relevant for methods that use index from start (because 1 is added) * Fixing JS order for getIndex and setIndex Changing to the correct order type when calling valueToCode in JS generation for getIndex and setIndex. * Fixed unittest adjustIndex Fixed uninttest adjustindex to also check whether the ONE_BASED_INDEXING variable has been defined to ensure proper behaviour. * Fixing lint and formatting for JS/lists Making line fixes and changing an if/elseif to case statement. * Tests added to include case for bug found Added tests with sublist combinations of different where's for the two indices after bug for this found in python. * Adding and renaming tests Adding test case for creating a sublist that encompasses the whole list but uses # and #-end instead of first last (applicable for python). Also, renaming tests. * Adding contant and fixing python lists bugs Adding contant for ONE_BASED_INDEXING and fixing bugs in python for lists. * Fixing test get random Fixing test get random to take into account indexing for return value. * Adding indexing checkbox to test page Adding checkbos on test page so that code can be generated for one and zero based indexing. Languages that are generated with zero based indexing that do not have it implemented will fail tests as expected. * Fixing unittest getremove random Fixing unittest getremove random to take into account the return value based on indexing. * Change comparison for getremove random test Fixed comparison to equal for the return value for getremove random. * Fixing bugs with lists zero-indexing Fixing getIndex and getSublist methods to pass for zero-indexed tests. * Adding test cases and formatting Adding test cases to text tests, reordering a couple list test, and formatting block spacing. * Fixing unittest expected value Fixing expected value fore unit tests for sublist. * Cleanup Removing obvious comments, formatting fixes, and naming in generated code in JS. * Helper function for Python lists Adding helper function for casting to int for indices. * Expanding helper to reduce duplicated code Expanding helper method to also get the property with the correct order and check indexing to reduce duplicated code. * Cleaning up JS indexing with helper function Adding helper function for indexing and used it in lists and text. * Moving helper function and formatting fixes Moving helper function, formatting fixes, and changing some generated code variable names. * Fixing python generation for text Fixing all failinng tests for python and using new helper method. * Lint fixes and order in indexOf Making lint fixes and correcting returned order in indexOf. * Python variable renaming Renaming a few generated variables. * Fixing comment and order Fixing comment to list Blockly.Block type and fixing order because it could be higher. * Switching back to if Switching switch back to if statements because there weren't enough cases to warrant for a switch. * Adding order and fixing lists for Dart Adding if null operator to operator precedence for Dart. Also, fixing lists implementation to pass unit tests and adding zero-indexing functionality. * Formatting and lint fixes Formatting and lint fixes * Dart text fixed Fixing Dart text generation to pass unit tests. * Changing back to variable Changing switch condition back to variable. * Fixing ORDER_OVERRIDES Inner and outer order was switched . * Adding bug with order caused by generator change Flooring order before comparision because of how the order constants were modified. * Adding list tests Adding tests for additional cases for lists/ * Adding comment for dart order Adding comment for Dart ORDER_IF_NULL operator. * Formatting fixes Formatting fixes for line indentation. * Fixing PHP order and lists generation Fixing PHP order constants and fixing lists so that they pass unit tests. * Fixing tests Removing duplicate unit test * Adding text tests Adding tests for text. * Renaming variable and removing unused variable Renaming variables from exceptionIndex to errorIndex and removing unused at variable. * Adding missing function call to test Adding missing funciton call to test that was causing tests to fail when they shouldn't. * Fixing PHP text generation Fixing PHP text code generation so it passes unit tests. * Formatting fixes Cleaning up code, renamiing a variable. * Fixing failing subsequence tests Fixing JS code that failed for sublist/substring tests. * Fixing intentation Fixing indentation. * Fixing Dart sublist/substring Fixing sublist/substring to include condiiton where FROM_START (and not throw error by mistake) when zero-indexed. * Adding order subtraction test Adding test for checking order for subtraction x- (y - z) x - (y + z). * Updating to new PHP power operator Updating from pow function to ** operator to clean up code. * Updating to new removeWhere Updating removeMatching to removeWhere because new version of Dart now use removeWhere. * Fix for lua rounding assertequals Adding check for number in equlity check for comparing number for floats. * Adding test for copy of list Adding test that checks the list is copied when a sublist is made first-last. * Formatting and order fixes Fixing formatting such as indentation and order fixes. * Adding comment for clarity Adding comment about how Lua code generation is not supporting zero indexing. * Changed variable names in code Changed variable names to follow style guide and changed for loop variable from n to i as is typical. * Reducing unecessarily generated functions and renaming variables Reducing number of generated functions using gensym_ by adding parameters to provided function. Renaming variables to make functions more readble. * Fixing sublist order and sort variable Fixing order used for valueToCode for sublist and renaming list variable in sort to match rest of code.. * Fixing order constant order Removing operator () that was incorrect and addiung ~, * Fixing order and indentation Fixing order return fro create lists blocks and fixing indentationn for string array. * Fixing order and renaming variables Fixing order to be the correct strength and renaming variables to be more readable/ * Changing assert blocks for unit tests Changing assert blocks to have a value input instead of a field so there is more flexibility in writing tests. * Cleaning up and adding missing order tests Adding tests for order for paramters for list blocks that weren't being tested to uncover bugs. Test were also cleaned up/reorganized/renamed to be more readable and shorter vertically (but lines wider horizontally). * Compile error fix and order in Dart generation. Fixing compile error in generated code and incorrect order in get sublist for Dart. * Fixing typo in getIndex and invalid parameter name Fixing type in getIndex where list code should have been appended but instead an undefined variable was added. The parameter in lists_sort was changed to my_list because list is a reserved word in python. * Fixing order, parenthesis bug, and variable declaration in Lua Fixing incorrect order in Lua. Fixing bug caused by missing parenthesis around ternary operator in code. Variable code was declared with JavaScript syntax, this was fixed to be valid in Lua. * Adding tests and formatting tests Adding missing test for order in text/lists. Changing spacing/order of tests and updating comments. * Fixing error in code Changing to correct function call in empy tests and changing test name that was duplicated to be more clear. * Renamed test helper function * Fixing order and renaming variable in JS generator Fixing order for charAt and renaming variable in code list_sort from listCode to list to be consistent with rest of code. * Fixing order for dart text Fixing roder for dart charAt * Cleaning up generated code for Dart getIndex Cleaning up generated code for Dart getIndex so that helper functions aren't generated unecessarily and adding comments. * Fixing Dart remove random error Fixing error caused by remove random implementation in Dart. index should have been x but instead was length - x. * Fixing unit test blocks Fixing Lua unit test block that should have just returned the number and removing unecessary checks in other blocks because the constant was defined. * Fixing Lua assert equals block string.format was throwing an error if one of the values happened to be a boolean. * Adding tests for create text with number Adding test for create text with numbers as parameters * Fixing lua unit test block Lua unit test block should have added 1 * Removing indexing setting for Lua tests Removing setting index setting for Lua generation because it is always one-indexed. * Fixing order and create text Fixing failing test caused by improper order and fixed create text to properly convert to string when there is one element. * Running linter on generator code Running linter on generator code and fixing spacing/indentation problems. * Editing comments and removing uneeded parenthesis Editing and adding comments and removing uneeded parenthesis around ternary operator condition. * Fixing order and changing variable names Fixing orders that were incorrect and changing variable names to be more descriptive and consistent across code. * Adding comment about list support and fixes for PHP Adding comment about how lists are not fully supported for PHP. Adding missing order to PHP and fixing order errors throughout. Fixing regex for variable matching in lists. Cleaning up variable names to be more readable and consistent with other parts of code. * Reducing complexity for getremove/remove in JS Reducing complexity in generated code for getremove/remove in JavaScript by replacing unecessary helper function. * Fixing spacing before inline comments Ensuring there are two spaces before inline comments. * Changing JS list copy for clarity Changing JavaScript list copy to use slice(0) instead of concat for clarity and to use the same pattern as the other sublist methods. * Changing generated variable name tmp_x Changing tmp_x to tmpX to follow closer to the correct style for JavaScript. * Prefixing empy lines between comment text Prior to this change, comments with an empty line between text did not have a comment prefix before it, resulting in comment blocks that seemed disjoined although they were for the same block. This change affects how the prefix line function works so that those lines will have the prefix (if applicable) while still taking into account the trailing newline character. * Changing for loops variable names Changing most for loops to use i as the variable name (or j if applicable) or changing name to be more readable. * Simplifying provided subsequence function Simplifying subsequence function to generate a simpler function depending on where combination instead of a larger complex function that works for all where combinations. * Style fixes Fixing indentation, comments, and other formatting-type changes based on pull request comments. * Fixing indentation Fixing indentation and removing an extra newline. * Fixing PHP mode implementation Fixing PHP mode implementation to properlyu return multiple modes if applicable. * Fixing line too long Wrapping lines in php/math.js with lines longer than 80 characters. * Wrapping long lines Wrapping lines that are too long. * Changing boolean casing Changing boolean casing to be lowercase.
This commit is contained in:
committed by
Neil Fraser
parent
603477d188
commit
2b191e897e
@@ -154,15 +154,15 @@ Blockly.FieldAngle.prototype.showEditor_ = function() {
|
||||
'y1': Blockly.FieldAngle.HALF,
|
||||
'class': 'blocklyAngleLine'}, svg);
|
||||
// Draw markers around the edge.
|
||||
for (var a = 0; a < 360; a += 15) {
|
||||
for (var angle = 0; angle < 360; angle += 15) {
|
||||
Blockly.createSvgElement('line', {
|
||||
'x1': Blockly.FieldAngle.HALF + Blockly.FieldAngle.RADIUS,
|
||||
'y1': Blockly.FieldAngle.HALF,
|
||||
'x2': Blockly.FieldAngle.HALF + Blockly.FieldAngle.RADIUS -
|
||||
(a % 45 == 0 ? 10 : 5),
|
||||
(angle % 45 == 0 ? 10 : 5),
|
||||
'y2': Blockly.FieldAngle.HALF,
|
||||
'class': 'blocklyAngleMarks',
|
||||
'transform': 'rotate(' + a + ',' +
|
||||
'transform': 'rotate(' + angle + ',' +
|
||||
Blockly.FieldAngle.HALF + ',' + Blockly.FieldAngle.HALF + ')'
|
||||
}, svg);
|
||||
}
|
||||
|
||||
@@ -122,9 +122,9 @@ Blockly.FieldDropdown.prototype.showEditor_ = function() {
|
||||
var menu = new goog.ui.Menu();
|
||||
menu.setRightToLeft(this.sourceBlock_.RTL);
|
||||
var options = this.getOptions_();
|
||||
for (var x = 0; x < options.length; x++) {
|
||||
var text = options[x][0]; // Human-readable text.
|
||||
var value = options[x][1]; // Language-neutral value.
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
var text = options[i][0]; // Human-readable text.
|
||||
var value = options[i][1]; // Language-neutral value.
|
||||
var menuItem = new goog.ui.MenuItem(text);
|
||||
menuItem.setRightToLeft(this.sourceBlock_.RTL);
|
||||
menuItem.setValue(value);
|
||||
@@ -223,11 +223,11 @@ Blockly.FieldDropdown.prototype.trimOptions_ = function() {
|
||||
}
|
||||
// Remove the prefix and suffix from the options.
|
||||
var newOptions = [];
|
||||
for (var x = 0; x < options.length; x++) {
|
||||
var text = options[x][0];
|
||||
var value = options[x][1];
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
var text = options[i][0];
|
||||
var value = options[i][1];
|
||||
text = text.substring(prefixLength, text.length - suffixLength);
|
||||
newOptions[x] = [text, value];
|
||||
newOptions[i] = [text, value];
|
||||
}
|
||||
this.menuGenerator_ = newOptions;
|
||||
};
|
||||
@@ -268,10 +268,10 @@ Blockly.FieldDropdown.prototype.setValue = function(newValue) {
|
||||
this.value_ = newValue;
|
||||
// Look up and display the human-readable text.
|
||||
var options = this.getOptions_();
|
||||
for (var x = 0; x < options.length; x++) {
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
// Options are tuples of human-readable text and language-neutral values.
|
||||
if (options[x][1] == newValue) {
|
||||
this.setText(options[x][0]);
|
||||
if (options[i][1] == newValue) {
|
||||
this.setText(options[i][0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,8 +113,8 @@ Blockly.FieldVariable.dropdownCreate = function() {
|
||||
// Variables are not language-specific, use the name as both the user-facing
|
||||
// text and the internal representation.
|
||||
var options = [];
|
||||
for (var x = 0; x < variableList.length; x++) {
|
||||
options[x] = [variableList[x], variableList[x]];
|
||||
for (var i = 0; i < variableList.length; i++) {
|
||||
options[i] = [variableList[i], variableList[i]];
|
||||
}
|
||||
return options;
|
||||
};
|
||||
|
||||
@@ -132,7 +132,7 @@ Blockly.Generator.prototype.workspaceToCode = function(workspace) {
|
||||
* @return {string} The prefixed lines of code.
|
||||
*/
|
||||
Blockly.Generator.prototype.prefixLines = function(text, prefix) {
|
||||
return prefix + text.replace(/\n(.)/g, '\n' + prefix + '$1');
|
||||
return prefix + text.replace(/(?!\n$)\n/g, '\n' + prefix);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -143,8 +143,8 @@ Blockly.Generator.prototype.prefixLines = function(text, prefix) {
|
||||
Blockly.Generator.prototype.allNestedComments = function(block) {
|
||||
var comments = [];
|
||||
var blocks = block.getDescendants();
|
||||
for (var x = 0; x < blocks.length; x++) {
|
||||
var comment = blocks[x].getCommentText();
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
var comment = blocks[i].getCommentText();
|
||||
if (comment) {
|
||||
comments.push(comment);
|
||||
}
|
||||
|
||||
@@ -222,8 +222,8 @@ Blockly.Input.prototype.init = function() {
|
||||
if (!this.sourceBlock_.workspace.rendered) {
|
||||
return; // Headless blocks don't need fields initialized.
|
||||
}
|
||||
for (var x = 0; x < this.fieldRow.length; x++) {
|
||||
this.fieldRow[x].init();
|
||||
for (var i = 0; i < this.fieldRow.length; i++) {
|
||||
this.fieldRow[i].init();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -197,9 +197,9 @@ Blockly.Procedures.flyoutCategory = function(workspace) {
|
||||
var mutation = goog.dom.createDom('mutation');
|
||||
mutation.setAttribute('name', name);
|
||||
block.appendChild(mutation);
|
||||
for (var t = 0; t < args.length; t++) {
|
||||
for (var j = 0; j < args.length; j++) {
|
||||
var arg = goog.dom.createDom('arg');
|
||||
arg.setAttribute('name', args[t]);
|
||||
arg.setAttribute('name', args[j]);
|
||||
mutation.appendChild(arg);
|
||||
}
|
||||
xmlList.push(block);
|
||||
|
||||
@@ -234,8 +234,8 @@ Blockly.RenderedConnection.prototype.unhideAll = function() {
|
||||
// Show all connections of this block.
|
||||
connections = block.getConnections_(true);
|
||||
}
|
||||
for (var c = 0; c < connections.length; c++) {
|
||||
renderList.push.apply(renderList, connections[c].unhideAll());
|
||||
for (var i = 0; i < connections.length; i++) {
|
||||
renderList.push.apply(renderList, connections[i].unhideAll());
|
||||
}
|
||||
if (!renderList.length) {
|
||||
// Leaf block.
|
||||
@@ -275,17 +275,17 @@ Blockly.RenderedConnection.prototype.hideAll = function() {
|
||||
this.setHidden(true);
|
||||
if (this.targetConnection) {
|
||||
var blocks = this.targetBlock().getDescendants();
|
||||
for (var b = 0; b < blocks.length; b++) {
|
||||
var block = blocks[b];
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
var block = blocks[i];
|
||||
// Hide all connections of all children.
|
||||
var connections = block.getConnections_(true);
|
||||
for (var c = 0; c < connections.length; c++) {
|
||||
connections[c].setHidden(true);
|
||||
for (var j = 0; j < connections.length; j++) {
|
||||
connections[j].setHidden(true);
|
||||
}
|
||||
// Close all bubbles of all children.
|
||||
var icons = block.getIcons();
|
||||
for (var i = 0; i < icons.length; i++) {
|
||||
icons[i].setVisible(false);
|
||||
for (var j = 0; j < icons.length; j++) {
|
||||
icons[j].setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,10 +54,10 @@ Blockly.Variables.allVariables = function(root) {
|
||||
}
|
||||
var variableHash = Object.create(null);
|
||||
// Iterate through every block and add each variable to the hash.
|
||||
for (var x = 0; x < blocks.length; x++) {
|
||||
var blockVariables = blocks[x].getVars();
|
||||
for (var y = 0; y < blockVariables.length; y++) {
|
||||
var varName = blockVariables[y];
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
var blockVariables = blocks[i].getVars();
|
||||
for (var j = 0; j < blockVariables.length; j++) {
|
||||
var varName = blockVariables[j];
|
||||
// Variable name may be null if the block is only half-built.
|
||||
if (varName) {
|
||||
variableHash[varName.toLowerCase()] = varName;
|
||||
|
||||
@@ -505,13 +505,13 @@ Blockly.Blocks['type_group'] = {
|
||||
// Parse XML to restore the group of types.
|
||||
this.typeCount_ = parseInt(container.getAttribute('types'), 10);
|
||||
this.updateShape_();
|
||||
for (var x = 0; x < this.typeCount_; x++) {
|
||||
this.removeInput('TYPE' + x);
|
||||
for (var i = 0; i < this.typeCount_; i++) {
|
||||
this.removeInput('TYPE' + i);
|
||||
}
|
||||
for (var x = 0; x < this.typeCount_; x++) {
|
||||
var input = this.appendValueInput('TYPE' + x)
|
||||
for (var i = 0; i < this.typeCount_; i++) {
|
||||
var input = this.appendValueInput('TYPE' + i)
|
||||
.setCheck('Type');
|
||||
if (x == 0) {
|
||||
if (i == 0) {
|
||||
input.appendField('any of');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,8 +501,8 @@ function getTypesFrom_(block, name) {
|
||||
types = [escapeString(typeBlock.getFieldValue('TYPE'))];
|
||||
} else if (typeBlock.type == 'type_group') {
|
||||
types = [];
|
||||
for (var n = 0; n < typeBlock.typeCount_; n++) {
|
||||
types = types.concat(getTypesFrom_(typeBlock, 'TYPE' + n));
|
||||
for (var i = 0; i < typeBlock.typeCount_; i++) {
|
||||
types = types.concat(getTypesFrom_(typeBlock, 'TYPE' + i));
|
||||
}
|
||||
// Remove duplicates.
|
||||
var hash = Object.create(null);
|
||||
|
||||
@@ -45,16 +45,28 @@ Blockly.Dart = new Blockly.Generator('Dart');
|
||||
Blockly.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,extends,false,final,finally,for,if,in,is,new,null,rethrow,return,super,switch,this,throw,true,try,var,void,while,with,' +
|
||||
'assert,break,case,catch,class,const,continue,default,do,else,enum,' +
|
||||
'extends,false,final,finally,for,if,in,is,new,null,rethrow,return,super,' +
|
||||
'switch,this,throw,true,try,var,void,while,with,' +
|
||||
// https://api.dartlang.org/dart_core.html
|
||||
'print,identityHashCode,identical,BidirectionalIterator,Comparable,double,Function,int,Invocation,Iterable,Iterator,List,Map,Match,num,Pattern,RegExp,Set,StackTrace,String,StringSink,Type,bool,DateTime,Deprecated,Duration,Expando,Null,Object,RuneIterator,Runes,Stopwatch,StringBuffer,Symbol,Uri,Comparator,AbstractClassInstantiationError,ArgumentError,AssertionError,CastError,ConcurrentModificationError,CyclicInitializationError,Error,Exception,FallThroughError,FormatException,IntegerDivisionByZeroException,NoSuchMethodError,NullThrownError,OutOfMemoryError,RangeError,StackOverflowError,StateError,TypeError,UnimplementedError,UnsupportedError');
|
||||
'print,identityHashCode,identical,BidirectionalIterator,Comparable,' +
|
||||
'double,Function,int,Invocation,Iterable,Iterator,List,Map,Match,num,' +
|
||||
'Pattern,RegExp,Set,StackTrace,String,StringSink,Type,bool,DateTime,' +
|
||||
'Deprecated,Duration,Expando,Null,Object,RuneIterator,Runes,Stopwatch,' +
|
||||
'StringBuffer,Symbol,Uri,Comparator,AbstractClassInstantiationError,' +
|
||||
'ArgumentError,AssertionError,CastError,ConcurrentModificationError,' +
|
||||
'CyclicInitializationError,Error,Exception,FallThroughError,' +
|
||||
'FormatException,IntegerDivisionByZeroException,NoSuchMethodError,' +
|
||||
'NullThrownError,OutOfMemoryError,RangeError,StackOverflowError,' +
|
||||
'StateError,TypeError,UnimplementedError,UnsupportedError'
|
||||
);
|
||||
|
||||
/**
|
||||
* Order of operation ENUMs.
|
||||
* https://www.dartlang.org/docs/dart-up-and-running/ch02.html#operator_table
|
||||
*/
|
||||
Blockly.Dart.ORDER_ATOMIC = 0; // 0 "" ...
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX = 1; // expr++ expr-- () [] .
|
||||
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; // + -
|
||||
@@ -66,11 +78,18 @@ 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_CONDITIONAL = 13; // expr ? expr : expr
|
||||
Blockly.Dart.ORDER_CASCADE = 14; // ..
|
||||
Blockly.Dart.ORDER_ASSIGNMENT = 15; // = *= /= ~/= %= += -= <<= >>= &= ^= |=
|
||||
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; // (...)
|
||||
|
||||
/**
|
||||
* Allow for switching between one and zero based indexing for lists and text,
|
||||
* one based by default.
|
||||
*/
|
||||
Blockly.Dart.ONE_BASED_INDEXING = true;
|
||||
|
||||
/**
|
||||
* Initialise the database of variable names.
|
||||
* @param {!Blockly.Workspace} workspace Workspace to generate code from.
|
||||
@@ -182,9 +201,9 @@ Blockly.Dart.scrub_ = function(block, code) {
|
||||
}
|
||||
// Collect comments for all value arguments.
|
||||
// Don't collect comments for nested statements.
|
||||
for (var x = 0; x < block.inputList.length; x++) {
|
||||
if (block.inputList[x].type == Blockly.INPUT_VALUE) {
|
||||
var childBlock = block.inputList[x].connection.targetBlock();
|
||||
for (var i = 0; i < block.inputList.length; i++) {
|
||||
if (block.inputList[i].type == Blockly.INPUT_VALUE) {
|
||||
var childBlock = block.inputList[i].connection.targetBlock();
|
||||
if (childBlock) {
|
||||
var comment = Blockly.Dart.allNestedComments(childBlock);
|
||||
if (comment) {
|
||||
@@ -198,3 +217,63 @@ Blockly.Dart.scrub_ = function(block, code) {
|
||||
var nextCode = Blockly.Dart.blockToCode(nextBlock);
|
||||
return commentCode + code + nextCode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a property and adjusts the value while taking into account indexing.
|
||||
* @param {!Blockly.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,
|
||||
opt_order) {
|
||||
var delta = opt_delta || 0;
|
||||
var order = opt_order || Blockly.Dart.ORDER_NONE;
|
||||
if (Blockly.Dart.ONE_BASED_INDEXING) {
|
||||
delta--;
|
||||
}
|
||||
var defaultAtIndex = Blockly.Dart.ONE_BASED_INDEXING ? '1' : '0';
|
||||
if (delta) {
|
||||
var at = Blockly.Dart.valueToCode(block, atId,
|
||||
Blockly.Dart.ORDER_ADDITIVE) || defaultAtIndex;
|
||||
} else if (opt_negate) {
|
||||
var at = Blockly.Dart.valueToCode(block, atId,
|
||||
Blockly.Dart.ORDER_UNARY_PREFIX) || defaultAtIndex;
|
||||
} else {
|
||||
var at = Blockly.Dart.valueToCode(block, atId, order) ||
|
||||
defaultAtIndex;
|
||||
}
|
||||
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, adjust it right now.
|
||||
at = parseInt(at, 10) + delta;
|
||||
if (opt_negate) {
|
||||
at = -at;
|
||||
}
|
||||
} else {
|
||||
// If the index is dynamic, adjust it in code.
|
||||
if (delta > 0) {
|
||||
at = at + ' + ' + delta;
|
||||
var innerOrder = Blockly.Dart.ORDER_ADDITIVE;
|
||||
} else if (delta < 0) {
|
||||
at = at + ' - ' + -delta;
|
||||
var innerOrder = Blockly.Dart.ORDER_ADDITIVE;
|
||||
}
|
||||
if (opt_negate) {
|
||||
if (delta) {
|
||||
at = '-(' + at + ')';
|
||||
} else {
|
||||
at = '-' + at;
|
||||
}
|
||||
var innerOrder = Blockly.Dart.ORDER_UNARY_PREFIX;
|
||||
}
|
||||
innerOrder = Math.floor(innerOrder);
|
||||
order = Math.floor(order);
|
||||
if (innerOrder && order >= innerOrder) {
|
||||
at = '(' + at + ')';
|
||||
}
|
||||
}
|
||||
return at;
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ Blockly.Dart['colour_random'] = function(block) {
|
||||
'import \'dart:math\' as Math;';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'colour_random',
|
||||
[ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
' String hex = \'0123456789abcdef\';',
|
||||
' var rnd = new Math.Random();',
|
||||
' return \'#${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}\'',
|
||||
@@ -67,7 +67,7 @@ Blockly.Dart['colour_rgb'] = function(block) {
|
||||
'import \'dart:math\' as Math;';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'colour_rgb',
|
||||
[ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(num r, num g, num b) {',
|
||||
' num rn = (Math.max(Math.min(r, 1), 0) * 255).round();',
|
||||
' String rs = rn.toInt().toRadixString(16);',
|
||||
@@ -100,7 +100,7 @@ Blockly.Dart['colour_blend'] = function(block) {
|
||||
'import \'dart:math\' as Math;';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'colour_blend',
|
||||
[ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['String ' + Blockly.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)}\');',
|
||||
|
||||
@@ -38,49 +38,52 @@ Blockly.Dart['lists_create_empty'] = function(block) {
|
||||
|
||||
Blockly.Dart['lists_create_with'] = function(block) {
|
||||
// Create a list with any number of elements of any type.
|
||||
var code = new Array(block.itemCount_);
|
||||
for (var n = 0; n < block.itemCount_; n++) {
|
||||
code[n] = Blockly.Dart.valueToCode(block, 'ADD' + n,
|
||||
var elements = new Array(block.itemCount_);
|
||||
for (var i = 0; i < block.itemCount_; i++) {
|
||||
elements[i] = Blockly.Dart.valueToCode(block, 'ADD' + i,
|
||||
Blockly.Dart.ORDER_NONE) || 'null';
|
||||
}
|
||||
code = '[' + code.join(', ') + ']';
|
||||
var code = '[' + elements.join(', ') + ']';
|
||||
return [code, Blockly.Dart.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
Blockly.Dart['lists_repeat'] = function(block) {
|
||||
// Create a list with one element repeated.
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'ITEM',
|
||||
var element = Blockly.Dart.valueToCode(block, 'ITEM',
|
||||
Blockly.Dart.ORDER_NONE) || 'null';
|
||||
var argument1 = Blockly.Dart.valueToCode(block, 'NUM',
|
||||
var repeatCount = Blockly.Dart.valueToCode(block, 'NUM',
|
||||
Blockly.Dart.ORDER_NONE) || '0';
|
||||
var code = 'new List.filled(' + argument1 + ', ' + argument0 + ')';
|
||||
var code = 'new List.filled(' + repeatCount + ', ' + element + ')';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
Blockly.Dart['lists_length'] = function(block) {
|
||||
// String or array length.
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
var list = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
|
||||
return [argument0 + '.length', Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
return [list + '.length', Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
Blockly.Dart['lists_isEmpty'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
var list = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
|
||||
return [argument0 + '.isEmpty', Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
return [list + '.isEmpty', Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
Blockly.Dart['lists_indexOf'] = function(block) {
|
||||
// Find an item in the list.
|
||||
var operator = block.getFieldValue('END') == 'FIRST' ?
|
||||
'indexOf' : 'lastIndexOf';
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'FIND',
|
||||
var item = Blockly.Dart.valueToCode(block, 'FIND',
|
||||
Blockly.Dart.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
var list = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
|
||||
var code = argument1 + '.' + operator + '(' + argument0 + ') + 1';
|
||||
return [code, Blockly.Dart.ORDER_ADDITIVE];
|
||||
var code = list + '.' + operator + '(' + item + ')';
|
||||
if (Blockly.Dart.ONE_BASED_INDEXING) {
|
||||
return [code + ' + 1', Blockly.Dart.ORDER_ADDITIVE];
|
||||
}
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
Blockly.Dart['lists_getIndex'] = function(block) {
|
||||
@@ -88,12 +91,75 @@ Blockly.Dart['lists_getIndex'] = function(block) {
|
||||
// Note: Until January 2013 this block did not have MODE or WHERE inputs.
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.Dart.valueToCode(block, 'AT',
|
||||
Blockly.Dart.ORDER_UNARY_PREFIX) || '1';
|
||||
var list = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
|
||||
var listOrder = (where == 'RANDOM' || where == 'FROM_END') ?
|
||||
Blockly.Dart.ORDER_NONE : Blockly.Dart.ORDER_UNARY_POSTFIX;
|
||||
var list = Blockly.Dart.valueToCode(block, 'VALUE', listOrder) || '[]';
|
||||
// Cache non-trivial values to variables to prevent repeated look-ups.
|
||||
// Closure, which accesses and modifies 'list'.
|
||||
function cacheList() {
|
||||
var listVar = Blockly.Dart.variableDB_.getDistinctName(
|
||||
'tmp_list', Blockly.Variables.NAME_TYPE);
|
||||
var code = 'List ' + listVar + ' = ' + list + ';\n';
|
||||
list = listVar;
|
||||
return code;
|
||||
}
|
||||
// If `list` would be evaluated more than once (which is the case for
|
||||
// RANDOM REMOVE and FROM_END) and is non-trivial, make sure to access it
|
||||
// only once.
|
||||
if (((where == 'RANDOM' && mode == 'REMOVE') || where == 'FROM_END') &&
|
||||
!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'] =
|
||||
'import \'dart:math\' as Math;';
|
||||
// We can use multiple statements.
|
||||
var code = cacheList();
|
||||
var xVar = Blockly.Dart.variableDB_.getDistinctName(
|
||||
'tmp_x', Blockly.Variables.NAME_TYPE);
|
||||
code += 'int ' + xVar + ' = new Math.Random().nextInt(' + list +
|
||||
'.length);\n';
|
||||
code += list + '.removeAt(' + xVar + ');\n';
|
||||
return code;
|
||||
} else { // where == 'FROM_END'
|
||||
if (mode == 'REMOVE') {
|
||||
// We can use multiple statements.
|
||||
var at = Blockly.Dart.getAdjusted(block, 'AT', 1, false,
|
||||
Blockly.Dart.ORDER_ADDITIVE);
|
||||
var code = cacheList();
|
||||
code += list + '.removeAt(' + list + '.length' + ' - ' + at + ');\n';
|
||||
return code;
|
||||
|
||||
if (where == 'FIRST') {
|
||||
} else if (mode == 'GET') {
|
||||
var at = Blockly.Dart.getAdjusted(block, 'AT', 1);
|
||||
// We need to create a procedure to avoid reevaluating values.
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'lists_get_from_end',
|
||||
['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List my_list, num x) {',
|
||||
' x = my_list.length - x;',
|
||||
' return my_list[x];',
|
||||
'}']);
|
||||
var code = functionName + '(' + list + ', ' + at + ')';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var at = Blockly.Dart.getAdjusted(block, 'AT', 1);
|
||||
// We need to create a procedure to avoid reevaluating values.
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'lists_remove_from_end',
|
||||
['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List my_list, num x) {',
|
||||
' x = my_list.length - x;',
|
||||
' return my_list.removeAt(x);',
|
||||
'}']);
|
||||
var code = functionName + '(' + list + ', ' + at + ')';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Either `list` is a simple variable, or we only need to refer to `list`
|
||||
// once.
|
||||
switch (where) {
|
||||
case 'FIRST':
|
||||
if (mode == 'GET') {
|
||||
var code = list + '.first';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
@@ -103,7 +169,8 @@ Blockly.Dart['lists_getIndex'] = function(block) {
|
||||
} else if (mode == 'REMOVE') {
|
||||
return list + '.removeAt(0);\n';
|
||||
}
|
||||
} else if (where == 'LAST') {
|
||||
break;
|
||||
case 'LAST':
|
||||
if (mode == 'GET') {
|
||||
var code = list + '.last';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
@@ -113,15 +180,9 @@ Blockly.Dart['lists_getIndex'] = function(block) {
|
||||
} else if (mode == 'REMOVE') {
|
||||
return list + '.removeLast();\n';
|
||||
}
|
||||
} else if (where == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseInt(at, 10) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at += ' - 1';
|
||||
}
|
||||
break;
|
||||
case 'FROM_START':
|
||||
var at = Blockly.Dart.getAdjusted(block, 'AT');
|
||||
if (mode == 'GET') {
|
||||
var code = list + '[' + at + ']';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
@@ -131,51 +192,55 @@ Blockly.Dart['lists_getIndex'] = function(block) {
|
||||
} else if (mode == 'REMOVE') {
|
||||
return list + '.removeAt(' + at + ');\n';
|
||||
}
|
||||
} else if (where == 'FROM_END') {
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at = Blockly.Dart.getAdjusted(block, 'AT', 1, false,
|
||||
Blockly.Dart.ORDER_ADDITIVE);
|
||||
if (mode == 'GET') {
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'lists_get_from_end',
|
||||
[ 'dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List myList, num x) {',
|
||||
' x = myList.length - x;',
|
||||
' return myList.removeAt(x);',
|
||||
'}']);
|
||||
code = functionName + '(' + list + ', ' + at + ')';
|
||||
var code = list + '[' + list + '.length - ' + at + ']';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
} else if (mode == 'GET_REMOVE' || mode == 'REMOVE') {
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'lists_remove_from_end',
|
||||
[ 'dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List myList, num x) {',
|
||||
' x = myList.length - x;',
|
||||
' return myList.removeAt(x);',
|
||||
'}']);
|
||||
code = functionName + '(' + list + ', ' + at + ')';
|
||||
var code = list + '.removeAt(' + list + '.length - ' + at + ')';
|
||||
if (mode == 'GET_REMOVE') {
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
} else if (mode == 'REMOVE') {
|
||||
return code + ';\n';
|
||||
}
|
||||
}
|
||||
} else if (where == 'RANDOM') {
|
||||
break;
|
||||
case 'RANDOM':
|
||||
Blockly.Dart.definitions_['import_dart_math'] =
|
||||
'import \'dart:math\' as Math;';
|
||||
if (mode == 'REMOVE') {
|
||||
// We can use multiple statements.
|
||||
var xVar = Blockly.Dart.variableDB_.getDistinctName(
|
||||
'tmp_x', Blockly.Variables.NAME_TYPE);
|
||||
var code = 'int ' + xVar + ' = new Math.Random().nextInt(' + list +
|
||||
'.length);\n';
|
||||
code += list + '.removeAt(' + xVar + ');\n';
|
||||
return code;
|
||||
} else if (mode == 'GET') {
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'lists_get_random_item',
|
||||
[ 'dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List myList, bool remove) {',
|
||||
' int x = new Math.Random().nextInt(myList.length);',
|
||||
' if (remove) {',
|
||||
' return myList.removeAt(x);',
|
||||
' } else {',
|
||||
' return myList[x];',
|
||||
' }',
|
||||
['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List my_list) {',
|
||||
' int x = new Math.Random().nextInt(my_list.length);',
|
||||
' return my_list[x];',
|
||||
'}']);
|
||||
code = functionName + '(' + list + ', ' + (mode != 'GET') + ')';
|
||||
if (mode == 'GET' || mode == 'GET_REMOVE') {
|
||||
var code = functionName + '(' + list + ')';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
} else if (mode == 'REMOVE') {
|
||||
return code + ';\n';
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'lists_remove_random_item',
|
||||
['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List my_list) {',
|
||||
' int x = new Math.Random().nextInt(my_list.length);',
|
||||
' return my_list.removeAt(x);',
|
||||
'}']);
|
||||
var code = functionName + '(' + list + ')';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
throw 'Unhandled combination (lists_getIndex).';
|
||||
@@ -184,12 +249,10 @@ Blockly.Dart['lists_getIndex'] = function(block) {
|
||||
Blockly.Dart['lists_setIndex'] = function(block) {
|
||||
// Set element at index.
|
||||
// Note: Until February 2013 this block did not have MODE or WHERE inputs.
|
||||
var list = Blockly.Dart.valueToCode(block, 'LIST',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.Dart.valueToCode(block, 'AT',
|
||||
Blockly.Dart.ORDER_ADDITIVE) || '1';
|
||||
var list = Blockly.Dart.valueToCode(block, 'LIST',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
|
||||
var value = Blockly.Dart.valueToCode(block, 'TO',
|
||||
Blockly.Dart.ORDER_ASSIGNMENT) || 'null';
|
||||
// Cache non-trivial values to variables to prevent repeated look-ups.
|
||||
@@ -204,13 +267,15 @@ Blockly.Dart['lists_setIndex'] = function(block) {
|
||||
list = listVar;
|
||||
return code;
|
||||
}
|
||||
if (where == 'FIRST') {
|
||||
switch (where) {
|
||||
case 'FIRST':
|
||||
if (mode == 'SET') {
|
||||
return list + '[0] = ' + value + ';\n';
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + '.insert(0, ' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'LAST') {
|
||||
break;
|
||||
case 'LAST':
|
||||
if (mode == 'SET') {
|
||||
var code = cacheList();
|
||||
code += list + '[' + list + '.length - 1] = ' + value + ';\n';
|
||||
@@ -218,38 +283,37 @@ Blockly.Dart['lists_setIndex'] = function(block) {
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + '.add(' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseInt(at, 10) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at += ' - 1';
|
||||
}
|
||||
break;
|
||||
case 'FROM_START':
|
||||
var at = Blockly.Dart.getAdjusted(block, 'AT');
|
||||
if (mode == 'SET') {
|
||||
return list + '[' + at + '] = ' + value + ';\n';
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + '.insert(' + at + ', ' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'FROM_END') {
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at = Blockly.Dart.getAdjusted(block, 'AT', 1, false,
|
||||
Blockly.Dart.ORDER_ADDITIVE);
|
||||
var code = cacheList();
|
||||
if (mode == 'SET') {
|
||||
code += list + '[' + list + '.length - ' + at + '] = ' + value + ';\n';
|
||||
code += list + '[' + list + '.length - ' + at + '] = ' + value +
|
||||
';\n';
|
||||
return code;
|
||||
} else if (mode == 'INSERT') {
|
||||
code += list + '.insert(' + list + '.length - ' + at + ', ' +
|
||||
value + ');\n';
|
||||
return code;
|
||||
}
|
||||
} else if (where == 'RANDOM') {
|
||||
break;
|
||||
case 'RANDOM':
|
||||
Blockly.Dart.definitions_['import_dart_math'] =
|
||||
'import \'dart:math\' as Math;';
|
||||
var code = cacheList();
|
||||
var xVar = Blockly.Dart.variableDB_.getDistinctName(
|
||||
'tmp_x', Blockly.Variables.NAME_TYPE);
|
||||
code += 'int ' + xVar +
|
||||
' = new Math.Random().nextInt(' + list + '.length);';
|
||||
' = new Math.Random().nextInt(' + list + '.length);\n';
|
||||
if (mode == 'SET') {
|
||||
code += list + '[' + xVar + '] = ' + value + ';\n';
|
||||
return code;
|
||||
@@ -257,6 +321,7 @@ Blockly.Dart['lists_setIndex'] = function(block) {
|
||||
code += list + '.insert(' + xVar + ', ' + value + ');\n';
|
||||
return code;
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw 'Unhandled combination (lists_setIndex).';
|
||||
};
|
||||
@@ -267,35 +332,59 @@ Blockly.Dart['lists_getSublist'] = function(block) {
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at1 = Blockly.Dart.valueToCode(block, 'AT1',
|
||||
Blockly.Dart.ORDER_NONE) || '1';
|
||||
var at2 = Blockly.Dart.valueToCode(block, 'AT2',
|
||||
Blockly.Dart.ORDER_NONE) || '1';
|
||||
if ((where1 == 'FIRST' || where1 == 'FROM_START' && Blockly.isNumber(at1)) &&
|
||||
(where2 == 'LAST' || where2 == 'FROM_START' && Blockly.isNumber(at2))) {
|
||||
// Simple case that can be done inline.
|
||||
at1 = where1 == 'FIRST' ? 0 : parseInt(at1, 10) - 1;
|
||||
if (list.match(/^\w+$/) || (where1 != 'FROM_END' && where2 == 'FROM_START')) {
|
||||
// If the list is a is a variable or doesn't require a call for length,
|
||||
// don't generate a helper function.
|
||||
switch (where1) {
|
||||
case 'FROM_START':
|
||||
var at1 = Blockly.Dart.getAdjusted(block, 'AT1');
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at1 = Blockly.Dart.getAdjusted(block, 'AT1', 1, false,
|
||||
Blockly.Dart.ORDER_ADDITIVE);
|
||||
at1 = list + '.length - ' + at1;
|
||||
break;
|
||||
case 'FIRST':
|
||||
var at1 = '0';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (lists_getSublist).';
|
||||
}
|
||||
switch (where2) {
|
||||
case 'FROM_START':
|
||||
var at2 = Blockly.Dart.getAdjusted(block, 'AT2', 1);
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at2 = Blockly.Dart.getAdjusted(block, 'AT2', 0, false,
|
||||
Blockly.Dart.ORDER_ADDITIVE);
|
||||
at2 = list + '.length - ' + at2;
|
||||
break;
|
||||
case 'LAST':
|
||||
// There is no second index if LAST option is chosen.
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (lists_getSublist).';
|
||||
}
|
||||
if (where2 == 'LAST') {
|
||||
code = list + '.sublist(' + at1 + ')';
|
||||
var code = list + '.sublist(' + at1 + ')';
|
||||
} else {
|
||||
at2 = parseInt(at2, 10);
|
||||
code = list + '.sublist(' + at1 + ', ' + at2 + ')';
|
||||
var code = list + '.sublist(' + at1 + ', ' + at2 + ')';
|
||||
}
|
||||
} else {
|
||||
var at1 = Blockly.Dart.getAdjusted(block, 'AT1');
|
||||
var at2 = Blockly.Dart.getAdjusted(block, 'AT2');
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'lists_get_sublist',
|
||||
[ 'List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(list, where1, at1, where2, at2) {',
|
||||
' int getAt(where, at) {',
|
||||
' if (where == \'FROM_START\') {',
|
||||
' at--;',
|
||||
' } else if (where == \'FROM_END\') {',
|
||||
' at = list.length - at;',
|
||||
' if (where == \'FROM_END\') {',
|
||||
' at = list.length - 1 - at;',
|
||||
' } else if (where == \'FIRST\') {',
|
||||
' at = 0;',
|
||||
' } else if (where == \'LAST\') {',
|
||||
' at = list.length - 1;',
|
||||
' } else {',
|
||||
' } else if (where != \'FROM_START\') {',
|
||||
' throw \'Unhandled option (lists_getSublist).\';',
|
||||
' }',
|
||||
' return at;',
|
||||
@@ -312,8 +401,8 @@ Blockly.Dart['lists_getSublist'] = function(block) {
|
||||
|
||||
Blockly.Dart['lists_sort'] = function(block) {
|
||||
// Block for sorting a list.
|
||||
var listCode = Blockly.Dart.valueToCode(block, 'LIST',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
|
||||
var list = Blockly.Dart.valueToCode(block, 'LIST',
|
||||
Blockly.Dart.ORDER_NONE) || '[]';
|
||||
var direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
|
||||
var type = block.getFieldValue('TYPE');
|
||||
var sortFunctionName = Blockly.Dart.provideFunction_(
|
||||
@@ -322,7 +411,8 @@ Blockly.Dart['lists_sort'] = function(block) {
|
||||
'(list, type, direction) {',
|
||||
' var compareFuncs = {',
|
||||
' "NUMERIC": (a, b) => direction * a.compareTo(b),',
|
||||
' "TEXT": (a, b) => direction * a.toString().compareTo(b.toString()),',
|
||||
' "TEXT": (a, b) => direction * ' +
|
||||
'a.toString().compareTo(b.toString()),',
|
||||
' "IGNORE_CASE": ',
|
||||
' (a, b) => direction * ',
|
||||
' a.toString().toLowerCase().compareTo(b.toString().toLowerCase())',
|
||||
@@ -332,31 +422,31 @@ Blockly.Dart['lists_sort'] = function(block) {
|
||||
' list.sort(compare);',
|
||||
' return list;',
|
||||
'}']);
|
||||
return [sortFunctionName + '(' + listCode + ', ' +
|
||||
return [sortFunctionName + '(' + list + ', ' +
|
||||
'"' + type + '", ' + direction + ')',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
Blockly.Dart['lists_split'] = function(block) {
|
||||
// Block for splitting text into a list, or joining a list into text.
|
||||
var value_input = Blockly.Dart.valueToCode(block, 'INPUT',
|
||||
var input = Blockly.Dart.valueToCode(block, 'INPUT',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX);
|
||||
var value_delim = Blockly.Dart.valueToCode(block, 'DELIM',
|
||||
var delimiter = Blockly.Dart.valueToCode(block, 'DELIM',
|
||||
Blockly.Dart.ORDER_NONE) || '\'\'';
|
||||
var mode = block.getFieldValue('MODE');
|
||||
if (mode == 'SPLIT') {
|
||||
if (!value_input) {
|
||||
value_input = '\'\'';
|
||||
if (!input) {
|
||||
input = '\'\'';
|
||||
}
|
||||
var functionName = 'split';
|
||||
} else if (mode == 'JOIN') {
|
||||
if (!value_input) {
|
||||
value_input = '[]';
|
||||
if (!input) {
|
||||
input = '[]';
|
||||
}
|
||||
var functionName = 'join';
|
||||
} else {
|
||||
throw 'Unknown mode: ' + mode;
|
||||
}
|
||||
var code = value_input + '.' + functionName + '(' + value_delim + ')';
|
||||
var code = input + '.' + functionName + '(' + delimiter + ')';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
@@ -200,7 +200,7 @@ Blockly.Dart['math_number_property'] = function(block) {
|
||||
'import \'dart:math\' as Math;';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'math_isPrime',
|
||||
[ 'bool ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '(n) {',
|
||||
['bool ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '(n) {',
|
||||
' // https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
|
||||
' if (n == 2 || n == 3) {',
|
||||
' return true;',
|
||||
@@ -275,7 +275,7 @@ Blockly.Dart['math_on_list'] = function(block) {
|
||||
case 'SUM':
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'math_sum',
|
||||
[ 'num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List myList) {',
|
||||
' num sumVal = 0;',
|
||||
' myList.forEach((num entry) {sumVal += entry;});',
|
||||
@@ -288,7 +288,7 @@ Blockly.Dart['math_on_list'] = function(block) {
|
||||
'import \'dart:math\' as Math;';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'math_min',
|
||||
[ 'num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List myList) {',
|
||||
' if (myList.isEmpty) return null;',
|
||||
' num minVal = myList[0];',
|
||||
@@ -303,7 +303,7 @@ Blockly.Dart['math_on_list'] = function(block) {
|
||||
'import \'dart:math\' as Math;';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'math_max',
|
||||
[ 'num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List myList) {',
|
||||
' if (myList.isEmpty) return null;',
|
||||
' num maxVal = myList[0];',
|
||||
@@ -318,11 +318,11 @@ Blockly.Dart['math_on_list'] = function(block) {
|
||||
// math_mean([null,null,"aString",1,9]) == 5.0.
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'math_mean',
|
||||
[ 'num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List myList) {',
|
||||
' // First filter list for numbers only.',
|
||||
' List localList = new List.from(myList);',
|
||||
' localList.removeMatching((a) => a is! num);',
|
||||
' localList.removeWhere((a) => a is! num);',
|
||||
' if (localList.isEmpty) return null;',
|
||||
' num sumVal = 0;',
|
||||
' localList.forEach((num entry) {sumVal += entry;});',
|
||||
@@ -333,14 +333,14 @@ Blockly.Dart['math_on_list'] = function(block) {
|
||||
case 'MEDIAN':
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'math_median',
|
||||
[ 'num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List myList) {',
|
||||
' // First filter list for numbers only, then sort, ' +
|
||||
'then return middle value',
|
||||
' // or the average of two middle values if list has an ' +
|
||||
'even number of elements.',
|
||||
' List localList = new List.from(myList);',
|
||||
' localList.removeMatching((a) => a is! num);',
|
||||
' localList.removeWhere((a) => a is! num);',
|
||||
' if (localList.isEmpty) return null;',
|
||||
' localList.sort((a, b) => (a - b));',
|
||||
' int index = localList.length ~/ 2;',
|
||||
@@ -360,7 +360,7 @@ Blockly.Dart['math_on_list'] = function(block) {
|
||||
// Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1].
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'math_modes',
|
||||
[ 'List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List values) {',
|
||||
' List modes = [];',
|
||||
' List counts = [];',
|
||||
@@ -396,11 +396,11 @@ Blockly.Dart['math_on_list'] = function(block) {
|
||||
'import \'dart:math\' as Math;';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'math_standard_deviation',
|
||||
[ 'num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List myList) {',
|
||||
' // First filter list for numbers only.',
|
||||
' List numbers = new List.from(myList);',
|
||||
' numbers.removeMatching((a) => a is! num);',
|
||||
' numbers.removeWhere((a) => a is! num);',
|
||||
' if (numbers.isEmpty) return null;',
|
||||
' num n = numbers.length;',
|
||||
' num sum = 0;',
|
||||
@@ -418,7 +418,7 @@ Blockly.Dart['math_on_list'] = function(block) {
|
||||
'import \'dart:math\' as Math;';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'math_random_item',
|
||||
[ 'dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(List myList) {',
|
||||
' int x = new Math.Random().nextInt(myList.length);',
|
||||
' return myList[x];',
|
||||
@@ -466,7 +466,7 @@ Blockly.Dart['math_random_int'] = function(block) {
|
||||
Blockly.Dart.ORDER_NONE) || '0';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'math_random_int',
|
||||
[ 'int ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '(num a, num b) {',
|
||||
['int ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '(num a, num b) {',
|
||||
' if (a > b) {',
|
||||
' // Swap a and b to ensure a is smaller.',
|
||||
' num c = a;',
|
||||
|
||||
@@ -50,8 +50,8 @@ Blockly.Dart['procedures_defreturn'] = function(block) {
|
||||
}
|
||||
var returnType = returnValue ? 'dynamic' : 'void';
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.Dart.variableDB_.getName(block.arguments_[x],
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.Dart.variableDB_.getName(block.arguments_[i],
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
}
|
||||
var code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' +
|
||||
@@ -71,8 +71,8 @@ Blockly.Dart['procedures_callreturn'] = function(block) {
|
||||
var funcName = Blockly.Dart.variableDB_.getName(block.getFieldValue('NAME'),
|
||||
Blockly.Procedures.NAME_TYPE);
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.Dart.valueToCode(block, 'ARG' + x,
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.Dart.valueToCode(block, 'ARG' + i,
|
||||
Blockly.Dart.ORDER_NONE) || 'null';
|
||||
}
|
||||
var code = funcName + '(' + args.join(', ') + ')';
|
||||
@@ -84,8 +84,8 @@ Blockly.Dart['procedures_callnoreturn'] = function(block) {
|
||||
var funcName = Blockly.Dart.variableDB_.getName(block.getFieldValue('NAME'),
|
||||
Blockly.Procedures.NAME_TYPE);
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.Dart.valueToCode(block, 'ARG' + x,
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.Dart.valueToCode(block, 'ARG' + i,
|
||||
Blockly.Dart.ORDER_NONE) || 'null';
|
||||
}
|
||||
var code = funcName + '(' + args.join(', ') + ');\n';
|
||||
|
||||
@@ -39,21 +39,21 @@ Blockly.Dart['text'] = function(block) {
|
||||
|
||||
Blockly.Dart['text_join'] = function(block) {
|
||||
// Create a string made up of any number of elements of any type.
|
||||
var code;
|
||||
if (block.itemCount_ == 0) {
|
||||
switch (block.itemCount_) {
|
||||
case 0:
|
||||
return ['\'\'', Blockly.Dart.ORDER_ATOMIC];
|
||||
} else if (block.itemCount_ == 1) {
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'ADD0',
|
||||
case 1:
|
||||
var element = Blockly.Dart.valueToCode(block, 'ADD0',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
|
||||
code = argument0 + '.toString()';
|
||||
var code = element + '.toString()';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
} else {
|
||||
code = new Array(block.itemCount_);
|
||||
for (var n = 0; n < block.itemCount_; n++) {
|
||||
code[n] = Blockly.Dart.valueToCode(block, 'ADD' + n,
|
||||
default:
|
||||
var elements = new Array(block.itemCount_);
|
||||
for (var i = 0; i < block.itemCount_; i++) {
|
||||
elements[i] = Blockly.Dart.valueToCode(block, 'ADD' + i,
|
||||
Blockly.Dart.ORDER_NONE) || '\'\'';
|
||||
}
|
||||
code = '[' + code.join(',') + '].join()';
|
||||
var code = '[' + elements.join(',') + '].join()';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
}
|
||||
};
|
||||
@@ -62,43 +62,44 @@ Blockly.Dart['text_append'] = function(block) {
|
||||
// Append to a variable in place.
|
||||
var varName = Blockly.Dart.variableDB_.getName(block.getFieldValue('VAR'),
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'TEXT',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
|
||||
return varName + ' = [' + varName + ', ' + argument0 + '].join();\n';
|
||||
var value = Blockly.Dart.valueToCode(block, 'TEXT',
|
||||
Blockly.Dart.ORDER_NONE) || '\'\'';
|
||||
return varName + ' = [' + varName + ', ' + value + '].join();\n';
|
||||
};
|
||||
|
||||
Blockly.Dart['text_length'] = function(block) {
|
||||
// String or array length.
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
var text = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
|
||||
return [argument0 + '.length', Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
return [text + '.length', Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
Blockly.Dart['text_isEmpty'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
var text = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
|
||||
return [argument0 + '.isEmpty', Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
return [text + '.isEmpty', Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
Blockly.Dart['text_indexOf'] = function(block) {
|
||||
// Search the text for a substring.
|
||||
var operator = block.getFieldValue('END') == 'FIRST' ?
|
||||
'indexOf' : 'lastIndexOf';
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'FIND',
|
||||
var substring = Blockly.Dart.valueToCode(block, 'FIND',
|
||||
Blockly.Dart.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
var text = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
|
||||
var code = argument1 + '.' + operator + '(' + argument0 + ') + 1';
|
||||
return [code, Blockly.Dart.ORDER_ADDITIVE];
|
||||
var code = text + '.' + operator + '(' + substring + ')';
|
||||
if (Blockly.Dart.ONE_BASED_INDEXING) {
|
||||
return [code + ' + 1', Blockly.Dart.ORDER_ADDITIVE];
|
||||
}
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
Blockly.Dart['text_charAt'] = function(block) {
|
||||
// Get letter at index.
|
||||
// Note: Until January 2013 this block did not have the WHERE input.
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.Dart.valueToCode(block, 'AT',
|
||||
Blockly.Dart.ORDER_NONE) || '1';
|
||||
var text = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
|
||||
switch (where) {
|
||||
@@ -106,23 +107,17 @@ Blockly.Dart['text_charAt'] = function(block) {
|
||||
var code = text + '[0]';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
case 'FROM_START':
|
||||
// Blockly uses one-based indicies.
|
||||
if (at.match(/^-?\d+$/)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseInt(at, 10) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at += ' - 1';
|
||||
}
|
||||
var at = Blockly.Dart.getAdjusted(block, 'AT');
|
||||
var code = text + '[' + at + ']';
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
case 'LAST':
|
||||
at = 1;
|
||||
// Fall through.
|
||||
case 'FROM_END':
|
||||
var at = Blockly.Dart.getAdjusted(block, 'AT', 1);
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'text_get_from_end',
|
||||
[ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(String text, num x) {',
|
||||
' return text[text.length - x];',
|
||||
'}']);
|
||||
@@ -133,7 +128,7 @@ Blockly.Dart['text_charAt'] = function(block) {
|
||||
'import \'dart:math\' as Math;';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'text_random_letter',
|
||||
[ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(String text) {',
|
||||
' int x = new Math.Random().nextInt(text.length);',
|
||||
' return text[x];',
|
||||
@@ -150,27 +145,61 @@ Blockly.Dart['text_getSubstring'] = function(block) {
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at1 = Blockly.Dart.valueToCode(block, 'AT1',
|
||||
Blockly.Dart.ORDER_NONE) || '1';
|
||||
var at2 = Blockly.Dart.valueToCode(block, 'AT2',
|
||||
Blockly.Dart.ORDER_NONE) || '1';
|
||||
if (where1 == 'FIRST' && where2 == 'LAST') {
|
||||
var code = text;
|
||||
} else if (text.match(/^'?\w+'?$/) ||
|
||||
(where1 != 'FROM_END' && where2 == 'FROM_START')) {
|
||||
// If the text is a variable or literal or doesn't require a call for
|
||||
// length, don't generate a helper function.
|
||||
switch (where1) {
|
||||
case 'FROM_START':
|
||||
var at1 = Blockly.Dart.getAdjusted(block, 'AT1');
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at1 = Blockly.Dart.getAdjusted(block, 'AT1', 1, false,
|
||||
Blockly.Dart.ORDER_ADDITIVE);
|
||||
at1 = text + '.length - ' + at1;
|
||||
break;
|
||||
case 'FIRST':
|
||||
var at1 = '0';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (text_getSubstring).';
|
||||
}
|
||||
switch (where2) {
|
||||
case 'FROM_START':
|
||||
var at2 = Blockly.Dart.getAdjusted(block, 'AT2', 1);
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at2 = Blockly.Dart.getAdjusted(block, 'AT2', 0, false,
|
||||
Blockly.Dart.ORDER_ADDITIVE);
|
||||
at2 = text + '.length - ' + at2;
|
||||
break;
|
||||
case 'LAST':
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (text_getSubstring).';
|
||||
}
|
||||
if (where2 == 'LAST') {
|
||||
var code = text + '.substring(' + at1 + ')';
|
||||
} else {
|
||||
var code = text + '.substring(' + at1 + ', ' + at2 + ')';
|
||||
}
|
||||
} else {
|
||||
var at1 = Blockly.Dart.getAdjusted(block, 'AT1');
|
||||
var at2 = Blockly.Dart.getAdjusted(block, 'AT2');
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'text_get_substring',
|
||||
[ 'function ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['List ' + Blockly.Dart.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;',
|
||||
' int getAt(where, at) {',
|
||||
' if (where == \'FROM_END\') {',
|
||||
' at = text.length - 1 - at;',
|
||||
' } else if (where == \'FIRST\') {',
|
||||
' at = 0;',
|
||||
' } else if (where == \'LAST\') {',
|
||||
' at = text.length - 1;',
|
||||
' } else {',
|
||||
' } else if (where != \'FROM_START\') {',
|
||||
' throw \'Unhandled option (text_getSubstring).\';',
|
||||
' }',
|
||||
' return at;',
|
||||
@@ -193,17 +222,17 @@ Blockly.Dart['text_changeCase'] = function(block) {
|
||||
'TITLECASE': null
|
||||
};
|
||||
var operator = OPERATORS[block.getFieldValue('CASE')];
|
||||
var code;
|
||||
var textOrder = operator ? Blockly.Dart.ORDER_UNARY_POSTFIX :
|
||||
Blockly.Dart.ORDER_NONE;
|
||||
var text = Blockly.Dart.valueToCode(block, 'TEXT', textOrder) || '\'\'';
|
||||
if (operator) {
|
||||
// Upper and lower case are functions built into Dart.
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'TEXT',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
|
||||
code = argument0 + operator;
|
||||
var code = text + operator;
|
||||
} else {
|
||||
// Title case is not a native Dart function. Define one.
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'text_toTitleCase',
|
||||
[ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(String str) {',
|
||||
' RegExp exp = new RegExp(r\'\\b\');',
|
||||
' List<String> list = str.split(exp);',
|
||||
@@ -218,9 +247,7 @@ Blockly.Dart['text_changeCase'] = function(block) {
|
||||
' }',
|
||||
' return title.toString();',
|
||||
'}']);
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'TEXT',
|
||||
Blockly.Dart.ORDER_NONE) || '\'\'';
|
||||
code = functionName + '(' + argument0 + ')';
|
||||
var code = functionName + '(' + text + ')';
|
||||
}
|
||||
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
@@ -233,16 +260,16 @@ Blockly.Dart['text_trim'] = function(block) {
|
||||
'BOTH': '.trim()'
|
||||
};
|
||||
var operator = OPERATORS[block.getFieldValue('MODE')];
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'TEXT',
|
||||
var text = Blockly.Dart.valueToCode(block, 'TEXT',
|
||||
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
|
||||
return [argument0 + operator, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
return [text + operator, Blockly.Dart.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
Blockly.Dart['text_print'] = function(block) {
|
||||
// Print statement.
|
||||
var argument0 = Blockly.Dart.valueToCode(block, 'TEXT',
|
||||
var msg = Blockly.Dart.valueToCode(block, 'TEXT',
|
||||
Blockly.Dart.ORDER_NONE) || '\'\'';
|
||||
return 'print(' + argument0 + ');\n';
|
||||
return 'print(' + msg + ');\n';
|
||||
};
|
||||
|
||||
Blockly.Dart['text_prompt_ext'] = function(block) {
|
||||
|
||||
@@ -135,8 +135,8 @@ Blockly.JavaScript.ORDER_OVERRIDES = [
|
||||
];
|
||||
|
||||
/**
|
||||
* Allow for switching between one and zero based indexing, one based by
|
||||
* default.
|
||||
* Allow for switching between one and zero based indexing for lists and text,
|
||||
* one based by default.
|
||||
*/
|
||||
Blockly.JavaScript.ONE_BASED_INDEXING = true;
|
||||
|
||||
@@ -258,3 +258,66 @@ Blockly.JavaScript.scrub_ = function(block, code) {
|
||||
var nextCode = Blockly.JavaScript.blockToCode(nextBlock);
|
||||
return commentCode + code + nextCode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a property and adjusts the value while taking into account indexing.
|
||||
* @param {!Blockly.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,
|
||||
opt_order) {
|
||||
var delta = opt_delta || 0;
|
||||
var order = opt_order || Blockly.JavaScript.ORDER_NONE;
|
||||
if (Blockly.JavaScript.ONE_BASED_INDEXING) {
|
||||
delta--;
|
||||
}
|
||||
var defaultAtIndex = Blockly.JavaScript.ONE_BASED_INDEXING ? '1' : '0';
|
||||
if (delta > 0) {
|
||||
var at = Blockly.JavaScript.valueToCode(block, atId,
|
||||
Blockly.JavaScript.ORDER_ADDITION) || defaultAtIndex;
|
||||
} else if (delta < 0) {
|
||||
var at = Blockly.JavaScript.valueToCode(block, atId,
|
||||
Blockly.JavaScript.ORDER_SUBTRACTION) || defaultAtIndex;
|
||||
} else if (opt_negate) {
|
||||
var at = Blockly.JavaScript.valueToCode(block, atId,
|
||||
Blockly.JavaScript.ORDER_UNARY_NEGATION) || defaultAtIndex;
|
||||
} else {
|
||||
var at = Blockly.JavaScript.valueToCode(block, atId, order) ||
|
||||
defaultAtIndex;
|
||||
}
|
||||
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, adjust it right now.
|
||||
at = parseFloat(at) + delta;
|
||||
if (opt_negate) {
|
||||
at = -at;
|
||||
}
|
||||
} else {
|
||||
// If the index is dynamic, adjust it in code.
|
||||
if (delta > 0) {
|
||||
at = at + ' + ' + delta;
|
||||
var innerOrder = Blockly.JavaScript.ORDER_ADDITION;
|
||||
} else if (delta < 0) {
|
||||
at = at + ' - ' + -delta;
|
||||
var innerOrder = Blockly.JavaScript.ORDER_SUBTRACTION;
|
||||
}
|
||||
if (opt_negate) {
|
||||
if (delta) {
|
||||
at = '-(' + at + ')';
|
||||
} else {
|
||||
at = '-' + at;
|
||||
}
|
||||
var innerOrder = Blockly.JavaScript.ORDER_UNARY_NEGATION;
|
||||
}
|
||||
innerOrder = Math.floor(innerOrder);
|
||||
order = Math.floor(order);
|
||||
if (innerOrder && order >= innerOrder) {
|
||||
at = '(' + at + ')';
|
||||
}
|
||||
}
|
||||
return at;
|
||||
};
|
||||
|
||||
@@ -39,7 +39,7 @@ Blockly.JavaScript['colour_random'] = function(block) {
|
||||
// Generate a random colour.
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'colourRandom',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
' var num = Math.floor(Math.random() * Math.pow(2, 24));',
|
||||
' return \'#\' + (\'00000\' + num.toString(16)).substr(-6);',
|
||||
'}']);
|
||||
@@ -57,7 +57,7 @@ Blockly.JavaScript['colour_rgb'] = function(block) {
|
||||
Blockly.JavaScript.ORDER_COMMA) || 0;
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'colourRgb',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['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;',
|
||||
@@ -81,7 +81,7 @@ Blockly.JavaScript['colour_blend'] = function(block) {
|
||||
Blockly.JavaScript.ORDER_COMMA) || 0.5;
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'colourBlend',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['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);',
|
||||
|
||||
@@ -36,12 +36,12 @@ Blockly.JavaScript['lists_create_empty'] = function(block) {
|
||||
|
||||
Blockly.JavaScript['lists_create_with'] = function(block) {
|
||||
// Create a list with any number of elements of any type.
|
||||
var code = new Array(block.itemCount_);
|
||||
for (var n = 0; n < block.itemCount_; n++) {
|
||||
code[n] = Blockly.JavaScript.valueToCode(block, 'ADD' + n,
|
||||
var elements = new Array(block.itemCount_);
|
||||
for (var i = 0; i < block.itemCount_; i++) {
|
||||
elements[i] = Blockly.JavaScript.valueToCode(block, 'ADD' + i,
|
||||
Blockly.JavaScript.ORDER_COMMA) || 'null';
|
||||
}
|
||||
code = '[' + code.join(', ') + ']';
|
||||
var code = '[' + elements.join(', ') + ']';
|
||||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ Blockly.JavaScript['lists_repeat'] = function(block) {
|
||||
// Create a list with one element repeated.
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'listsRepeat',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(value, n) {',
|
||||
' var array = [];',
|
||||
' for (var i = 0; i < n; i++) {',
|
||||
@@ -57,38 +57,41 @@ Blockly.JavaScript['lists_repeat'] = function(block) {
|
||||
' }',
|
||||
' return array;',
|
||||
'}']);
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'ITEM',
|
||||
var element = Blockly.JavaScript.valueToCode(block, 'ITEM',
|
||||
Blockly.JavaScript.ORDER_COMMA) || 'null';
|
||||
var argument1 = Blockly.JavaScript.valueToCode(block, 'NUM',
|
||||
var repeatCount = Blockly.JavaScript.valueToCode(block, 'NUM',
|
||||
Blockly.JavaScript.ORDER_COMMA) || '0';
|
||||
var code = functionName + '(' + argument0 + ', ' + argument1 + ')';
|
||||
var code = functionName + '(' + element + ', ' + repeatCount + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.JavaScript['lists_length'] = function(block) {
|
||||
// String or array length.
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
Blockly.JavaScript.ORDER_FUNCTION_CALL) || '[]';
|
||||
return [argument0 + '.length', Blockly.JavaScript.ORDER_MEMBER];
|
||||
var list = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '[]';
|
||||
return [list + '.length', Blockly.JavaScript.ORDER_MEMBER];
|
||||
};
|
||||
|
||||
Blockly.JavaScript['lists_isEmpty'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
var list = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '[]';
|
||||
return ['!' + argument0 + '.length', Blockly.JavaScript.ORDER_LOGICAL_NOT];
|
||||
return ['!' + list + '.length', Blockly.JavaScript.ORDER_LOGICAL_NOT];
|
||||
};
|
||||
|
||||
Blockly.JavaScript['lists_indexOf'] = function(block) {
|
||||
// Find an item in the list.
|
||||
var operator = block.getFieldValue('END') == 'FIRST' ?
|
||||
'indexOf' : 'lastIndexOf';
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'FIND',
|
||||
var item = Blockly.JavaScript.valueToCode(block, 'FIND',
|
||||
Blockly.JavaScript.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
var list = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '[]';
|
||||
var code = argument1 + '.' + operator + '(' + argument0 + ') + 1';
|
||||
return [code, Blockly.JavaScript.ORDER_ADDITION];
|
||||
var code = list + '.' + operator + '(' + item + ')';
|
||||
if (Blockly.JavaScript.ONE_BASED_INDEXING) {
|
||||
return [code + ' + 1', Blockly.JavaScript.ORDER_ADDITION];
|
||||
}
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.JavaScript['lists_getIndex'] = function(block) {
|
||||
@@ -96,12 +99,12 @@ Blockly.JavaScript['lists_getIndex'] = function(block) {
|
||||
// Note: Until January 2013 this block did not have MODE or WHERE inputs.
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.JavaScript.valueToCode(block, 'AT',
|
||||
Blockly.JavaScript.ORDER_UNARY_NEGATION) || '1';
|
||||
var list = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '[]';
|
||||
var listOrder = (where == 'RANDOM') ? Blockly.JavaScript.ORDER_COMMA :
|
||||
Blockly.JavaScript.ORDER_MEMBER;
|
||||
var list = Blockly.JavaScript.valueToCode(block, 'VALUE', listOrder) || '[]';
|
||||
|
||||
if (where == 'FIRST') {
|
||||
switch (where) {
|
||||
case ('FIRST'):
|
||||
if (mode == 'GET') {
|
||||
var code = list + '[0]';
|
||||
return [code, Blockly.JavaScript.ORDER_MEMBER];
|
||||
@@ -111,7 +114,8 @@ Blockly.JavaScript['lists_getIndex'] = function(block) {
|
||||
} else if (mode == 'REMOVE') {
|
||||
return list + '.shift();\n';
|
||||
}
|
||||
} else if (where == 'LAST') {
|
||||
break;
|
||||
case ('LAST'):
|
||||
if (mode == 'GET') {
|
||||
var code = list + '.slice(-1)[0]';
|
||||
return [code, Blockly.JavaScript.ORDER_MEMBER];
|
||||
@@ -121,15 +125,9 @@ Blockly.JavaScript['lists_getIndex'] = function(block) {
|
||||
} else if (mode == 'REMOVE') {
|
||||
return list + '.pop();\n';
|
||||
}
|
||||
} else if (where == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseFloat(at) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at += ' - 1';
|
||||
}
|
||||
break;
|
||||
case ('FROM_START'):
|
||||
var at = Blockly.JavaScript.getAdjusted(block, 'AT');
|
||||
if (mode == 'GET') {
|
||||
var code = list + '[' + at + ']';
|
||||
return [code, Blockly.JavaScript.ORDER_MEMBER];
|
||||
@@ -139,29 +137,23 @@ Blockly.JavaScript['lists_getIndex'] = function(block) {
|
||||
} else if (mode == 'REMOVE') {
|
||||
return list + '.splice(' + at + ', 1);\n';
|
||||
}
|
||||
} else if (where == 'FROM_END') {
|
||||
break;
|
||||
case ('FROM_END'):
|
||||
var at = Blockly.JavaScript.getAdjusted(block, 'AT', 1, true);
|
||||
if (mode == 'GET') {
|
||||
var code = list + '.slice(-' + at + ')[0]';
|
||||
var code = list + '.slice(' + at + ')[0]';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'GET_REMOVE' || mode == 'REMOVE') {
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'listsRemoveFromEnd',
|
||||
[ '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') {
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var code = list + '.splice(' + at + ', 1)[0]';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
return code + ';\n';
|
||||
return list + '.splice(' + at + ', 1);';
|
||||
}
|
||||
}
|
||||
} else if (where == 'RANDOM') {
|
||||
break;
|
||||
case ('RANDOM'):
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'listsGetRandomItem',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(list, remove) {',
|
||||
' var x = Math.floor(Math.random() * list.length);',
|
||||
' if (remove) {',
|
||||
@@ -176,6 +168,7 @@ Blockly.JavaScript['lists_getIndex'] = function(block) {
|
||||
} else if (mode == 'REMOVE') {
|
||||
return code + ';\n';
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw 'Unhandled combination (lists_getIndex).';
|
||||
};
|
||||
@@ -187,8 +180,6 @@ Blockly.JavaScript['lists_setIndex'] = function(block) {
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '[]';
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.JavaScript.valueToCode(block, 'AT',
|
||||
Blockly.JavaScript.ORDER_NONE) || '1';
|
||||
var value = Blockly.JavaScript.valueToCode(block, 'TO',
|
||||
Blockly.JavaScript.ORDER_ASSIGNMENT) || 'null';
|
||||
// Cache non-trivial values to variables to prevent repeated look-ups.
|
||||
@@ -198,18 +189,20 @@ Blockly.JavaScript['lists_setIndex'] = function(block) {
|
||||
return '';
|
||||
}
|
||||
var listVar = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'tmp_list', Blockly.Variables.NAME_TYPE);
|
||||
'tmpList', Blockly.Variables.NAME_TYPE);
|
||||
var code = 'var ' + listVar + ' = ' + list + ';\n';
|
||||
list = listVar;
|
||||
return code;
|
||||
}
|
||||
if (where == 'FIRST') {
|
||||
switch (where) {
|
||||
case ('FIRST'):
|
||||
if (mode == 'SET') {
|
||||
return list + '[0] = ' + value + ';\n';
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + '.unshift(' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'LAST') {
|
||||
break;
|
||||
case ('LAST'):
|
||||
if (mode == 'SET') {
|
||||
var code = cacheList();
|
||||
code += list + '[' + list + '.length - 1] = ' + value + ';\n';
|
||||
@@ -217,21 +210,18 @@ Blockly.JavaScript['lists_setIndex'] = function(block) {
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + '.push(' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseFloat(at) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at += ' - 1';
|
||||
}
|
||||
break;
|
||||
case ('FROM_START'):
|
||||
var at = Blockly.JavaScript.getAdjusted(block, 'AT');
|
||||
if (mode == 'SET') {
|
||||
return list + '[' + at + '] = ' + value + ';\n';
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + '.splice(' + at + ', 0, ' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'FROM_END') {
|
||||
break;
|
||||
case ('FROM_END'):
|
||||
var at = Blockly.JavaScript.getAdjusted(block, 'AT', 1, false,
|
||||
Blockly.JavaScript.ORDER_SUBTRACTION);
|
||||
var code = cacheList();
|
||||
if (mode == 'SET') {
|
||||
code += list + '[' + list + '.length - ' + at + '] = ' + value + ';\n';
|
||||
@@ -241,10 +231,11 @@ Blockly.JavaScript['lists_setIndex'] = function(block) {
|
||||
');\n';
|
||||
return code;
|
||||
}
|
||||
} else if (where == 'RANDOM') {
|
||||
break;
|
||||
case ('RANDOM'):
|
||||
var code = cacheList();
|
||||
var xVar = Blockly.JavaScript.variableDB_.getDistinctName(
|
||||
'tmp_x', Blockly.Variables.NAME_TYPE);
|
||||
'tmpX', Blockly.Variables.NAME_TYPE);
|
||||
code += 'var ' + xVar + ' = Math.floor(Math.random() * ' + list +
|
||||
'.length);\n';
|
||||
if (mode == 'SET') {
|
||||
@@ -254,55 +245,106 @@ Blockly.JavaScript['lists_setIndex'] = function(block) {
|
||||
code += list + '.splice(' + xVar + ', 0, ' + value + ');\n';
|
||||
return code;
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw 'Unhandled combination (lists_setIndex).';
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an expression calculating the index into a list.
|
||||
* @private
|
||||
* @param {string} listName Name of the list, used to calculate length.
|
||||
* @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} Index expression.
|
||||
*/
|
||||
Blockly.JavaScript.lists.getIndex_ = function(listName, where, opt_at) {
|
||||
if (where == 'FIRST') {
|
||||
return '0';
|
||||
} else if (where == 'FROM_END') {
|
||||
return listName + '.length - 1 - ' + opt_at;
|
||||
} else if (where == 'LAST') {
|
||||
return listName + '.length - 1';
|
||||
} else {
|
||||
return opt_at;
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.JavaScript['lists_getSublist'] = function(block) {
|
||||
// Get sublist.
|
||||
var list = Blockly.JavaScript.valueToCode(block, 'LIST',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '[]';
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at1 = Blockly.JavaScript.valueToCode(block, 'AT1',
|
||||
Blockly.JavaScript.ORDER_NONE) || '1';
|
||||
var at2 = Blockly.JavaScript.valueToCode(block, 'AT2',
|
||||
Blockly.JavaScript.ORDER_NONE) || '1';
|
||||
if (where1 == 'FIRST' && where2 == 'LAST') {
|
||||
var code = list + '.concat()';
|
||||
var code = list + '.slice(0)';
|
||||
} else if (list.match(/^\w+$/) ||
|
||||
(where1 != 'FROM_END' && where2 == 'FROM_START')) {
|
||||
// If the list is a variable or doesn't require a call for length, don't
|
||||
// generate a helper function.
|
||||
switch (where1) {
|
||||
case 'FROM_START':
|
||||
var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1');
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1', 1, false,
|
||||
Blockly.JavaScript.ORDER_SUBTRACTION);
|
||||
at1 = list + '.length - ' + at1;
|
||||
break;
|
||||
case 'FIRST':
|
||||
var at1 = '0';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (lists_getSublist).';
|
||||
}
|
||||
switch (where2) {
|
||||
case 'FROM_START':
|
||||
var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 1);
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 0, false,
|
||||
Blockly.JavaScript.ORDER_SUBTRACTION);
|
||||
at2 = list + '.length - ' + at2;
|
||||
break;
|
||||
case 'LAST':
|
||||
var at2 = list + '.length';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (lists_getSublist).';
|
||||
}
|
||||
code = list + '.slice(' + at1 + ', ' + at2 + ')';
|
||||
} else {
|
||||
var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1');
|
||||
var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2');
|
||||
var getIndex_ = Blockly.JavaScript.lists.getIndex_;
|
||||
var wherePascalCase = {'FIRST': 'First', 'LAST': 'Last',
|
||||
'FROM_START': 'FromStart', 'FROM_END': 'FromEnd'};
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'listsGetSublist',
|
||||
[ '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);',
|
||||
'subsequence' + wherePascalCase[where1] + wherePascalCase[where2],
|
||||
['function ' + Blockly.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;',
|
||||
' return sequence.slice(start, end);',
|
||||
'}']);
|
||||
var code = functionName + '(' + list + ', \'' +
|
||||
where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
|
||||
var code = functionName + '(' + list +
|
||||
// The value for 'FROM_END' and 'FROM_START' depends on `at` so we
|
||||
// pass it.
|
||||
((where1 == 'FROM_END' || where1 == 'FROM_START') ? ', ' + at1 : '') +
|
||||
((where2 == 'FROM_END' || where2 == 'FROM_START') ? ', ' + at2 : '') +
|
||||
')';
|
||||
}
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.JavaScript['lists_sort'] = function(block) {
|
||||
// Block for sorting a list.
|
||||
var listCode = Blockly.JavaScript.valueToCode(
|
||||
block, 'LIST',
|
||||
var list = Blockly.JavaScript.valueToCode(block, 'LIST',
|
||||
Blockly.JavaScript.ORDER_FUNCTION_CALL) || '[]';
|
||||
var direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
|
||||
var type = block.getFieldValue('TYPE');
|
||||
@@ -322,31 +364,31 @@ Blockly.JavaScript['lists_sort'] = function(block) {
|
||||
' var compare = compareFuncs[type];',
|
||||
' return function(a, b) { return compare(a, b) * direction; }',
|
||||
'}']);
|
||||
return ['(' + listCode + ').slice().sort(' +
|
||||
return [list + '.slice().sort(' +
|
||||
getCompareFunctionName + '("' + type + '", ' + direction + '))',
|
||||
Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.JavaScript['lists_split'] = function(block) {
|
||||
// Block for splitting text into a list, or joining a list into text.
|
||||
var value_input = Blockly.JavaScript.valueToCode(block, 'INPUT',
|
||||
var input = Blockly.JavaScript.valueToCode(block, 'INPUT',
|
||||
Blockly.JavaScript.ORDER_MEMBER);
|
||||
var value_delim = Blockly.JavaScript.valueToCode(block, 'DELIM',
|
||||
var delimiter = Blockly.JavaScript.valueToCode(block, 'DELIM',
|
||||
Blockly.JavaScript.ORDER_NONE) || '\'\'';
|
||||
var mode = block.getFieldValue('MODE');
|
||||
if (mode == 'SPLIT') {
|
||||
if (!value_input) {
|
||||
value_input = '\'\'';
|
||||
if (!input) {
|
||||
input = '\'\'';
|
||||
}
|
||||
var functionName = 'split';
|
||||
} else if (mode == 'JOIN') {
|
||||
if (!value_input) {
|
||||
value_input = '[]';
|
||||
if (!input) {
|
||||
input = '[]';
|
||||
}
|
||||
var functionName = 'join';
|
||||
} else {
|
||||
throw 'Unknown mode: ' + mode;
|
||||
}
|
||||
var code = value_input + '.' + functionName + '(' + value_delim + ')';
|
||||
var code = input + '.' + functionName + '(' + delimiter + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
@@ -168,7 +168,7 @@ Blockly.JavaScript['math_number_property'] = function(block) {
|
||||
// Prime is a special case as it is not a one-liner test.
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'mathIsPrime',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(n) {',
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(n) {',
|
||||
' // https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
|
||||
' if (n == 2 || n == 3) {',
|
||||
' return true;',
|
||||
@@ -254,7 +254,7 @@ Blockly.JavaScript['math_on_list'] = function(block) {
|
||||
// mathMean([null,null,1,3]) == 2.0.
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'mathMean',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(myList) {',
|
||||
' return myList.reduce(function(x, y) {return x + y;}) / ' +
|
||||
'myList.length;',
|
||||
@@ -267,7 +267,7 @@ Blockly.JavaScript['math_on_list'] = function(block) {
|
||||
// mathMedian([null,null,1,3]) == 2.0.
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'mathMedian',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(myList) {',
|
||||
' var localList = myList.filter(function (x) ' +
|
||||
'{return typeof x == \'number\';});',
|
||||
@@ -290,7 +290,7 @@ Blockly.JavaScript['math_on_list'] = function(block) {
|
||||
// Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1].
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'mathModes',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(values) {',
|
||||
' var modes = [];',
|
||||
' var counts = [];',
|
||||
@@ -326,7 +326,7 @@ Blockly.JavaScript['math_on_list'] = function(block) {
|
||||
case 'STD_DEV':
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'mathStandardDeviation',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(numbers) {',
|
||||
' var n = numbers.length;',
|
||||
' if (!n) return null;',
|
||||
@@ -345,7 +345,7 @@ Blockly.JavaScript['math_on_list'] = function(block) {
|
||||
case 'RANDOM':
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'mathRandomList',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(list) {',
|
||||
' var x = Math.floor(Math.random() * list.length);',
|
||||
' return list[x];',
|
||||
@@ -391,7 +391,7 @@ Blockly.JavaScript['math_random_int'] = function(block) {
|
||||
Blockly.JavaScript.ORDER_COMMA) || '0';
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'mathRandomInt',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(a, b) {',
|
||||
' if (a > b) {',
|
||||
' // Swap a and b to ensure a is smaller.',
|
||||
|
||||
@@ -37,28 +37,28 @@ Blockly.JavaScript['text'] = function(block) {
|
||||
|
||||
Blockly.JavaScript['text_join'] = function(block) {
|
||||
// Create a string made up of any number of elements of any type.
|
||||
var code;
|
||||
if (block.itemCount_ == 0) {
|
||||
switch (block.itemCount_) {
|
||||
case 0:
|
||||
return ['\'\'', Blockly.JavaScript.ORDER_ATOMIC];
|
||||
} else if (block.itemCount_ == 1) {
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'ADD0',
|
||||
case 1:
|
||||
var element = Blockly.JavaScript.valueToCode(block, 'ADD0',
|
||||
Blockly.JavaScript.ORDER_NONE) || '\'\'';
|
||||
code = 'String(' + argument0 + ')';
|
||||
var code = 'String(' + element + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
} else if (block.itemCount_ == 2) {
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'ADD0',
|
||||
case 2:
|
||||
var element0 = Blockly.JavaScript.valueToCode(block, 'ADD0',
|
||||
Blockly.JavaScript.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.JavaScript.valueToCode(block, 'ADD1',
|
||||
var element1 = Blockly.JavaScript.valueToCode(block, 'ADD1',
|
||||
Blockly.JavaScript.ORDER_NONE) || '\'\'';
|
||||
code = 'String(' + argument0 + ') + String(' + argument1 + ')';
|
||||
var code = 'String(' + element0 + ') + String(' + element1 + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_ADDITION];
|
||||
} else {
|
||||
code = new Array(block.itemCount_);
|
||||
for (var n = 0; n < block.itemCount_; n++) {
|
||||
code[n] = Blockly.JavaScript.valueToCode(block, 'ADD' + n,
|
||||
default:
|
||||
var elements = new Array(block.itemCount_);
|
||||
for (var i = 0; i < block.itemCount_; i++) {
|
||||
elements[i] = Blockly.JavaScript.valueToCode(block, 'ADD' + i,
|
||||
Blockly.JavaScript.ORDER_COMMA) || '\'\'';
|
||||
}
|
||||
code = '[' + code.join(',') + '].join(\'\')';
|
||||
var code = '[' + elements.join(',') + '].join(\'\')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
};
|
||||
@@ -67,45 +67,49 @@ Blockly.JavaScript['text_append'] = function(block) {
|
||||
// Append to a variable in place.
|
||||
var varName = Blockly.JavaScript.variableDB_.getName(
|
||||
block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'TEXT',
|
||||
var value = Blockly.JavaScript.valueToCode(block, 'TEXT',
|
||||
Blockly.JavaScript.ORDER_NONE) || '\'\'';
|
||||
return varName + ' = String(' + varName + ') + String(' + argument0 + ');\n';
|
||||
return varName + ' = String(' + varName + ') + String(' + value + ');\n';
|
||||
};
|
||||
|
||||
Blockly.JavaScript['text_length'] = function(block) {
|
||||
// String or array length.
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
return [argument0 + '.length', Blockly.JavaScript.ORDER_MEMBER];
|
||||
return [text + '.length', Blockly.JavaScript.ORDER_MEMBER];
|
||||
};
|
||||
|
||||
Blockly.JavaScript['text_isEmpty'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
|
||||
return ['!' + argument0 + '.length', Blockly.JavaScript.ORDER_LOGICAL_NOT];
|
||||
return ['!' + text + '.length', Blockly.JavaScript.ORDER_LOGICAL_NOT];
|
||||
};
|
||||
|
||||
Blockly.JavaScript['text_indexOf'] = function(block) {
|
||||
// Search the text for a substring.
|
||||
var operator = block.getFieldValue('END') == 'FIRST' ?
|
||||
'indexOf' : 'lastIndexOf';
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'FIND',
|
||||
var substring = Blockly.JavaScript.valueToCode(block, 'FIND',
|
||||
Blockly.JavaScript.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
|
||||
var code = argument1 + '.' + operator + '(' + argument0 + ') + 1';
|
||||
return [code, Blockly.JavaScript.ORDER_ADDITION];
|
||||
var code = text + '.' + operator + '(' + substring + ')';
|
||||
// Adjust index if using one-based indices.
|
||||
if (Blockly.JavaScript.ONE_BASED_INDEXING) {
|
||||
return [code + ' + 1', Blockly.JavaScript.ORDER_ADDITION];
|
||||
}
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.JavaScript['text_charAt'] = function(block) {
|
||||
// Get letter at index.
|
||||
// Note: Until January 2013 this block did not have the WHERE input.
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.JavaScript.valueToCode(block, 'AT',
|
||||
Blockly.JavaScript.ORDER_UNARY_NEGATION) || '1';
|
||||
var textOrder = (where == 'RANDOM') ? Blockly.JavaScript.ORDER_NONE :
|
||||
Blockly.JavaScript.ORDER_MEMBER;
|
||||
var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
|
||||
textOrder) || '\'\'';
|
||||
switch (where) {
|
||||
case 'FIRST':
|
||||
var code = text + '.charAt(0)';
|
||||
@@ -114,70 +118,117 @@ Blockly.JavaScript['text_charAt'] = function(block) {
|
||||
var code = text + '.slice(-1)';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
case 'FROM_START':
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseFloat(at) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at += ' - 1';
|
||||
}
|
||||
var at = Blockly.JavaScript.getAdjusted(block, 'AT');
|
||||
// Adjust index if using one-based indices.
|
||||
var code = text + '.charAt(' + at + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
case 'FROM_END':
|
||||
var code = text + '.slice(-' + at + ').charAt(0)';
|
||||
var at = Blockly.JavaScript.getAdjusted(block, 'AT', 1, true);
|
||||
var code = text + '.slice(' + at + ').charAt(0)';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
case 'RANDOM':
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'textRandomLetter',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(text) {',
|
||||
' var x = Math.floor(Math.random() * text.length);',
|
||||
' return text[x];',
|
||||
'}']);
|
||||
code = functionName + '(' + text + ')';
|
||||
var code = functionName + '(' + text + ')';
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
throw 'Unhandled option (text_charAt).';
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an expression calculating the index into a string.
|
||||
* @private
|
||||
* @param {string} stringName Name of the string, used to calculate length.
|
||||
* @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} Index expression.
|
||||
*/
|
||||
Blockly.JavaScript.text.getIndex_ = function(stringName, where, opt_at) {
|
||||
if (where == 'FIRST') {
|
||||
return '0';
|
||||
} else if (where == 'FROM_END') {
|
||||
return stringName + '.length - 1 - ' + opt_at;
|
||||
} else if (where == 'LAST') {
|
||||
return stringName + '.length - 1';
|
||||
} else {
|
||||
return opt_at;
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.JavaScript['text_getSubstring'] = function(block) {
|
||||
// Get substring.
|
||||
var text = Blockly.JavaScript.valueToCode(block, 'STRING',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
|
||||
Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at1 = Blockly.JavaScript.valueToCode(block, 'AT1',
|
||||
Blockly.JavaScript.ORDER_NONE) || '1';
|
||||
var at2 = Blockly.JavaScript.valueToCode(block, 'AT2',
|
||||
Blockly.JavaScript.ORDER_NONE) || '1';
|
||||
if (where1 == 'FIRST' && where2 == 'LAST') {
|
||||
var code = text;
|
||||
} else if (text.match(/^'?\w+'?$/) ||
|
||||
(where1 != 'FROM_END' && where1 != 'LAST' &&
|
||||
where2 != 'FROM_END' && where2 != 'LAST')) {
|
||||
// If the text is a variable or literal or doesn't require a call for
|
||||
// length, don't generate a helper function.
|
||||
switch (where1) {
|
||||
case 'FROM_START':
|
||||
var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1');
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1', 1, false,
|
||||
Blockly.JavaScript.ORDER_SUBTRACTION);
|
||||
at1 = text + '.length - ' + at1;
|
||||
break;
|
||||
case 'FIRST':
|
||||
var at1 = '0';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (text_getSubstring).';
|
||||
}
|
||||
switch (where2) {
|
||||
case 'FROM_START':
|
||||
var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 1);
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 0, false,
|
||||
Blockly.JavaScript.ORDER_SUBTRACTION);
|
||||
at2 = text + '.length - ' + at2;
|
||||
break;
|
||||
case 'LAST':
|
||||
var at2 = text + '.length';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (text_getSubstring).';
|
||||
}
|
||||
code = text + '.slice(' + at1 + ', ' + at2 + ')';
|
||||
} else {
|
||||
var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1');
|
||||
var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2');
|
||||
var getIndex_ = Blockly.JavaScript.text.getIndex_;
|
||||
var wherePascalCase = {'FIRST': 'First', 'LAST': 'Last',
|
||||
'FROM_START': 'FromStart', 'FROM_END': 'FromEnd'};
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'textGetSubstring',
|
||||
[ '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);',
|
||||
'subsequence' + wherePascalCase[where1] + wherePascalCase[where2],
|
||||
['function ' + Blockly.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;',
|
||||
' return sequence.slice(start, end);',
|
||||
'}']);
|
||||
var code = functionName + '(' + text + ', \'' +
|
||||
where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
|
||||
var code = functionName + '(' + text +
|
||||
// The value for 'FROM_END' and 'FROM_START' depends on `at` so we
|
||||
// pass it.
|
||||
((where1 == 'FROM_END' || where1 == 'FROM_START') ? ', ' + at1 : '') +
|
||||
((where2 == 'FROM_END' || where2 == 'FROM_START') ? ', ' + at2 : '') +
|
||||
')';
|
||||
}
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
@@ -190,25 +241,24 @@ Blockly.JavaScript['text_changeCase'] = function(block) {
|
||||
'TITLECASE': null
|
||||
};
|
||||
var operator = OPERATORS[block.getFieldValue('CASE')];
|
||||
var code;
|
||||
var textOrder = operator ? Blockly.JavaScript.ORDER_MEMBER :
|
||||
Blockly.JavaScript.ORDER_NONE;
|
||||
var text = Blockly.JavaScript.valueToCode(block, 'TEXT',
|
||||
textOrder) || '\'\'';
|
||||
if (operator) {
|
||||
// Upper and lower case are functions built into JavaScript.
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'TEXT',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
|
||||
code = argument0 + operator;
|
||||
var code = text + operator;
|
||||
} else {
|
||||
// Title case is not a native JavaScript function. Define one.
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'textToTitleCase',
|
||||
[ 'function ' +
|
||||
Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(str) {',
|
||||
['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 = functionName + '(' + argument0 + ')';
|
||||
var code = functionName + '(' + text + ')';
|
||||
}
|
||||
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
@@ -221,16 +271,16 @@ Blockly.JavaScript['text_trim'] = function(block) {
|
||||
'BOTH': '.trim()'
|
||||
};
|
||||
var operator = OPERATORS[block.getFieldValue('MODE')];
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'TEXT',
|
||||
var text = Blockly.JavaScript.valueToCode(block, 'TEXT',
|
||||
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
|
||||
return [argument0 + operator, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
return [text + operator, Blockly.JavaScript.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.JavaScript['text_print'] = function(block) {
|
||||
// Print statement.
|
||||
var argument0 = Blockly.JavaScript.valueToCode(block, 'TEXT',
|
||||
var msg = Blockly.JavaScript.valueToCode(block, 'TEXT',
|
||||
Blockly.JavaScript.ORDER_NONE) || '\'\'';
|
||||
return 'window.alert(' + argument0 + ');\n';
|
||||
return 'window.alert(' + msg + ');\n';
|
||||
};
|
||||
|
||||
Blockly.JavaScript['text_prompt_ext'] = function(block) {
|
||||
|
||||
@@ -77,7 +77,7 @@ Blockly.Lua.ORDER_ATOMIC = 0; // literals
|
||||
// The next level was not explicit in documentation and inferred by Ellen.
|
||||
Blockly.Lua.ORDER_HIGH = 1; // Function calls, tables[]
|
||||
Blockly.Lua.ORDER_EXPONENTIATION = 2; // ^
|
||||
Blockly.Lua.ORDER_UNARY = 3; // not # - ()
|
||||
Blockly.Lua.ORDER_UNARY = 3; // not # - ~
|
||||
Blockly.Lua.ORDER_MULTIPLICATIVE = 4; // * / %
|
||||
Blockly.Lua.ORDER_ADDITIVE = 5; // + -
|
||||
Blockly.Lua.ORDER_CONCATENATION = 6; // ..
|
||||
@@ -86,6 +86,12 @@ Blockly.Lua.ORDER_AND = 8; // and
|
||||
Blockly.Lua.ORDER_OR = 9; // or
|
||||
Blockly.Lua.ORDER_NONE = 99;
|
||||
|
||||
/**
|
||||
* Lua is not supporting zero-indexing since the language itself is one-indexed,
|
||||
* so there is not flag for ONE_BASED_INDEXING to indicate which indexing is
|
||||
* used for lists and text.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialise the database of variable names.
|
||||
* @param {!Blockly.Workspace} workspace Workspace to generate code from.
|
||||
@@ -170,9 +176,9 @@ Blockly.Lua.scrub_ = function(block, code) {
|
||||
}
|
||||
// Collect comments for all value arguments.
|
||||
// Don't collect comments for nested statements.
|
||||
for (var x = 0; x < block.inputList.length; x++) {
|
||||
if (block.inputList[x].type == Blockly.INPUT_VALUE) {
|
||||
var childBlock = block.inputList[x].connection.targetBlock();
|
||||
for (var i = 0; i < block.inputList.length; i++) {
|
||||
if (block.inputList[i].type == Blockly.INPUT_VALUE) {
|
||||
var childBlock = block.inputList[i].connection.targetBlock();
|
||||
if (childBlock) {
|
||||
comment = Blockly.Lua.allNestedComments(childBlock);
|
||||
if (comment) {
|
||||
|
||||
@@ -31,18 +31,17 @@ goog.require('Blockly.Lua');
|
||||
|
||||
Blockly.Lua['lists_create_empty'] = function(block) {
|
||||
// Create an empty list.
|
||||
// List literals must be parenthesized before indexing into.
|
||||
return ['({})', Blockly.Lua.ORDER_ATOMIC];
|
||||
return ['{}', Blockly.Lua.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
Blockly.Lua['lists_create_with'] = function(block) {
|
||||
// Create a list with any number of elements of any type.
|
||||
var code = new Array(block.itemCount_);
|
||||
for (var n = 0; n < block.itemCount_; n++) {
|
||||
code[n] = Blockly.Lua.valueToCode(block, 'ADD' + n,
|
||||
var elements = new Array(block.itemCount_);
|
||||
for (var i = 0; i < block.itemCount_; i++) {
|
||||
elements[i] = Blockly.Lua.valueToCode(block, 'ADD' + i,
|
||||
Blockly.Lua.ORDER_NONE) || 'None';
|
||||
}
|
||||
code = '({' + code.join(', ') + '})';
|
||||
var code = '{' + elements.join(', ') + '}';
|
||||
return [code, Blockly.Lua.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
@@ -57,38 +56,37 @@ Blockly.Lua['lists_repeat'] = function(block) {
|
||||
' end',
|
||||
' return t',
|
||||
'end']);
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'ITEM',
|
||||
var element = Blockly.Lua.valueToCode(block, 'ITEM',
|
||||
Blockly.Lua.ORDER_NONE) || 'None';
|
||||
var argument1 = Blockly.Lua.valueToCode(block, 'NUM',
|
||||
var repeatCount = Blockly.Lua.valueToCode(block, 'NUM',
|
||||
Blockly.Lua.ORDER_NONE) || '0';
|
||||
var code = functionName + '(' + argument0 + ', ' + argument1 + ')';
|
||||
var code = functionName + '(' + element + ', ' + repeatCount + ')';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
};
|
||||
|
||||
Blockly.Lua['lists_length'] = function(block) {
|
||||
// String or array length.
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_HIGH) || '({})';
|
||||
return ['#' + argument0, Blockly.Lua.ORDER_HIGH];
|
||||
var list = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_UNARY) || '{}';
|
||||
return ['#' + list, Blockly.Lua.ORDER_UNARY];
|
||||
};
|
||||
|
||||
Blockly.Lua['lists_isEmpty'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_HIGH) || '({})';
|
||||
var code = '#' + argument0 + ' == 0';
|
||||
var list = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_UNARY) || '{}';
|
||||
var code = '#' + list + ' == 0';
|
||||
return [code, Blockly.Lua.ORDER_RELATIONAL];
|
||||
};
|
||||
|
||||
Blockly.Lua['lists_indexOf'] = function(block) {
|
||||
// Find an item in the list.
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'FIND',
|
||||
var item = Blockly.Lua.valueToCode(block, 'FIND',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_NONE) || '({})';
|
||||
var functionName;
|
||||
var list = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_NONE) || '{}';
|
||||
if (block.getFieldValue('END') == 'FIRST') {
|
||||
functionName = Blockly.Lua.provideFunction_(
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'first_index',
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, elem)',
|
||||
' for k, v in ipairs(t) do',
|
||||
@@ -99,7 +97,7 @@ Blockly.Lua['lists_indexOf'] = function(block) {
|
||||
' return 0',
|
||||
'end']);
|
||||
} else {
|
||||
functionName = Blockly.Lua.provideFunction_(
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'last_index',
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, elem)',
|
||||
' for i = #t, 1, -1 do',
|
||||
@@ -110,64 +108,40 @@ Blockly.Lua['lists_indexOf'] = function(block) {
|
||||
' return 0',
|
||||
'end']);
|
||||
}
|
||||
var code = functionName + '(' + argument1 + ', ' + argument0 + ')';
|
||||
var code = functionName + '(' + list + ', ' + item + ')';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an expression calculating the index into a list.
|
||||
* @private
|
||||
* @param {string} listname Name of the list, used to calculate length.
|
||||
* @param {string} listName Name of the list, used to calculate length.
|
||||
* @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} Index expression.
|
||||
*/
|
||||
Blockly.Lua.lists.getIndex_ = function(listname, where, opt_at) {
|
||||
Blockly.Lua.lists.getIndex_ = function(listName, where, opt_at) {
|
||||
if (where == 'FIRST') {
|
||||
return '1';
|
||||
} else if (where == 'FROM_END') {
|
||||
return '#' + listname + ' + 1 - ' + opt_at;
|
||||
return '#' + listName + ' + 1 - ' + opt_at;
|
||||
} else if (where == 'LAST') {
|
||||
return '#' + listname;
|
||||
return '#' + listName;
|
||||
} else if (where == 'RANDOM') {
|
||||
return 'math.random(#' + listname + ')';
|
||||
return 'math.random(#' + listName + ')';
|
||||
} else {
|
||||
return opt_at;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Counter for generating unique symbols.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
Blockly.Lua.lists.gensym_counter_ = 0;
|
||||
|
||||
/**
|
||||
* Generate a unique symbol.
|
||||
* @private
|
||||
* @return {string} unique symbol, eg 'G123'
|
||||
*/
|
||||
Blockly.Lua.lists.gensym_ = function() {
|
||||
return 'G' + Blockly.Lua.lists.gensym_counter_++;
|
||||
};
|
||||
|
||||
Blockly.Lua['lists_getIndex'] = function(block) {
|
||||
// Get element at index.
|
||||
// Note: Until January 2013 this block did not have MODE or WHERE inputs.
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.Lua.valueToCode(block, 'AT',
|
||||
Blockly.Lua.ORDER_ADDITIVE) || '1';
|
||||
if (mode == 'GET') {
|
||||
var order = Blockly.Lua.ORDER_HIGH;
|
||||
} else {
|
||||
// List will be an argument in a function call.
|
||||
var order = Blockly.Lua.ORDER_NONE;
|
||||
}
|
||||
var list = Blockly.Lua.valueToCode(block, 'VALUE', order) || '({})';
|
||||
var list = Blockly.Lua.valueToCode(block, 'VALUE', Blockly.Lua.ORDER_HIGH) ||
|
||||
'{}';
|
||||
var getIndex_ = Blockly.Lua.lists.getIndex_;
|
||||
var gensym_ = Blockly.Lua.lists.gensym_;
|
||||
|
||||
// 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.
|
||||
@@ -176,46 +150,59 @@ 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.
|
||||
var atOrder = (where == 'FROM_END') ? Blockly.Lua.ORDER_ADDITIVE :
|
||||
Blockly.Lua.ORDER_NONE;
|
||||
var at = Blockly.Lua.valueToCode(block, 'AT', atOrder) || '1';
|
||||
var listVar = Blockly.Lua.variableDB_.getDistinctName(
|
||||
'tmp_list', Blockly.Variables.NAME_TYPE);
|
||||
at = getIndex_(listVar, where, at);
|
||||
var code = listVar + ' = ' + list + '\n' +
|
||||
'table.remove(' + listVar + ', ' + getIndex_(listVar, where, at) +
|
||||
')\n';
|
||||
'table.remove(' + listVar + ', ' + at + ')\n';
|
||||
return code;
|
||||
} else {
|
||||
// We need to create a procedure to avoid reevaluating values.
|
||||
var at = Blockly.Lua.valueToCode(block, 'AT', Blockly.Lua.ORDER_NONE) ||
|
||||
'1';
|
||||
if (mode == 'GET') {
|
||||
// Note that getIndex_() ignores `at` when `where` == 'LAST' or
|
||||
// 'RANDOM', so we only need one procedure for each of those 'where'
|
||||
// values. The value for 'FROM_END' depends on `at`, so we will
|
||||
// generate a unique procedure (name) each time.
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'list_get_' + where.toLowerCase() +
|
||||
(where == 'FROM_END' ? '_' + gensym_() : ''),
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
|
||||
' return t[' + getIndex_('t', where, at) + ']',
|
||||
'list_get_' + where.toLowerCase(),
|
||||
['function ' + Blockly.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') + ']',
|
||||
'end']);
|
||||
} else { // mode == 'GET_REMOVE'
|
||||
// We need to create a procedure.
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'list_remove_' + where.toLowerCase() +
|
||||
(where == 'FROM_END' ? '_' + gensym_() : ''),
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
|
||||
' return table.remove(t, ' + getIndex_('t', where, at) + ')',
|
||||
'list_remove_' + where.toLowerCase(),
|
||||
['function ' + Blockly.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') + ')',
|
||||
'end']);
|
||||
}
|
||||
var code = functionName + '(' + list + ')';
|
||||
var code = functionName + '(' + list +
|
||||
// The value for 'FROM_END' and 'FROM_START' depends on `at` so we
|
||||
// pass it.
|
||||
((where == 'FROM_END' || where == 'FROM_START') ? ', ' + at : '') +
|
||||
')';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
}
|
||||
} else {
|
||||
// Either `list` is a simple variable, or we only need to refer to `list`
|
||||
// once.
|
||||
var atOrder = (mode == 'GET' && where == 'FROM_END') ?
|
||||
Blockly.Lua.ORDER_ADDITIVE : Blockly.Lua.ORDER_NONE;
|
||||
var at = Blockly.Lua.valueToCode(block, 'AT', atOrder) || '1';
|
||||
at = getIndex_(list, where, at);
|
||||
if (mode == 'GET') {
|
||||
var code = list + '[' + getIndex_(list, where, at) + ']';
|
||||
var code = list + '[' + at + ']';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
} else {
|
||||
var code = 'table.remove(' + list + ', ' + getIndex_(list, where, at) +
|
||||
')';
|
||||
var code = 'table.remove(' + list + ', ' + at + ')';
|
||||
if (mode == 'GET_REMOVE') {
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
} else { // `mode` == 'REMOVE'
|
||||
@@ -229,7 +216,7 @@ Blockly.Lua['lists_setIndex'] = function(block) {
|
||||
// Set element at index.
|
||||
// Note: Until February 2013 this block did not have MODE or WHERE inputs.
|
||||
var list = Blockly.Lua.valueToCode(block, 'LIST',
|
||||
Blockly.Lua.ORDER_HIGH) || '({})';
|
||||
Blockly.Lua.ORDER_HIGH) || '{}';
|
||||
var mode = block.getFieldValue('MODE') || 'SET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.Lua.valueToCode(block, 'AT',
|
||||
@@ -238,97 +225,71 @@ Blockly.Lua['lists_setIndex'] = function(block) {
|
||||
Blockly.Lua.ORDER_NONE) || 'None';
|
||||
var getIndex_ = Blockly.Lua.lists.getIndex_;
|
||||
|
||||
var code = '';
|
||||
// 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.
|
||||
if ((where == 'LAST' || where == 'FROM_END' || where == 'RANDOM') &&
|
||||
!list.match(/^\w+$/)) {
|
||||
// `list` is an expression, so we may not evaluate it more than once.
|
||||
if (where == 'RANDOM' || where == 'LAST') {
|
||||
// In these cases, `at` is implicit. getIndex_() ignores its value.
|
||||
if (mode == 'SET') {
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'list_set_' + where.toLowerCase(),
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, val)',
|
||||
' t[' + getIndex_('t', where, at) + '] = val',
|
||||
'end']);
|
||||
} else { // `mode` == 'INSERT'
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'list_insert_' + where.toLowerCase(),
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, val)',
|
||||
' table.insert(t, ' +
|
||||
// LAST is a special case, because we want to insert
|
||||
// *after* not *before*, the existing last element.
|
||||
getIndex_('t', where, at) + (where == 'LAST' ? ' + 1' : '') +
|
||||
', val)',
|
||||
'end']);
|
||||
// We can use multiple statements.
|
||||
var listVar = Blockly.Lua.variableDB_.getDistinctName(
|
||||
'tmp_list', Blockly.Variables.NAME_TYPE);
|
||||
code = listVar + ' = ' + list + '\n';
|
||||
list = listVar;
|
||||
}
|
||||
var code = functionName + '(' + list + ', ' + value + ')\n';
|
||||
return code;
|
||||
} else { // `where` = 'FROM_END'
|
||||
if (mode == 'SET') {
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'list_set_from_end',
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(t, index, val)',
|
||||
' t[#t + 1 - index] = val',
|
||||
'end']);
|
||||
} else { // `mode` == 'INSERT'
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'list_insert_from_end',
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(t, index, val)',
|
||||
' table.insert(t, #t + 1 - index, val)',
|
||||
'end']);
|
||||
}
|
||||
var code = functionName + '(' + list + ', ' + at + ', ' + value + ')\n';
|
||||
return code;
|
||||
}
|
||||
} else {
|
||||
// It's okay to have multiple references to the list.
|
||||
if (mode == 'SET') {
|
||||
var 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.
|
||||
var code = 'table.insert(' + list + ', ' +
|
||||
code += 'table.insert(' + list + ', ' +
|
||||
(getIndex_(list, where, at) + (where == 'LAST' ? ' + 1' : '')) +
|
||||
', ' + value + ')';
|
||||
}
|
||||
return code + '\n';
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Lua['lists_getSublist'] = function(block) {
|
||||
// Get sublist.
|
||||
var list = Blockly.Lua.valueToCode(block, 'LIST',
|
||||
Blockly.Lua.ORDER_HIGH) || '({})';
|
||||
Blockly.Lua.ORDER_NONE) || '{}';
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at1 = Blockly.Lua.valueToCode(block, 'AT1',
|
||||
Blockly.Lua.ORDER_ADDITIVE) || '1';
|
||||
Blockly.Lua.ORDER_NONE) || '1';
|
||||
var at2 = Blockly.Lua.valueToCode(block, 'AT2',
|
||||
Blockly.Lua.ORDER_ADDITIVE) || '1';
|
||||
Blockly.Lua.ORDER_NONE) || '1';
|
||||
var getIndex_ = Blockly.Lua.lists.getIndex_;
|
||||
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'list_sublist_' + Blockly.Lua.lists.gensym_(),
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(source)',
|
||||
'list_sublist_' + where1.toLowerCase() + '_' + where2.toLowerCase(),
|
||||
['function ' + Blockly.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',
|
||||
' return t',
|
||||
'end']);
|
||||
var code = functionName + '(' + list + ')';
|
||||
var code = functionName + '(' + list +
|
||||
// The value for 'FROM_END' and 'FROM_START' depends on `at` so we
|
||||
// pass it.
|
||||
((where1 == 'FROM_END' || where1 == 'FROM_START') ? ', ' + at1 : '') +
|
||||
((where2 == 'FROM_END' || where2 == 'FROM_START') ? ', ' + at2 : '') +
|
||||
')';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
};
|
||||
|
||||
Blockly.Lua['lists_sort'] = function(block) {
|
||||
// Block for sorting a list.
|
||||
var listCode = Blockly.Lua.valueToCode(
|
||||
block, 'LIST', Blockly.Lua.ORDER_HIGH) || '({})';
|
||||
var list = Blockly.Lua.valueToCode(
|
||||
block, 'LIST', Blockly.Lua.ORDER_NONE) || '{}';
|
||||
var direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
|
||||
var type = block.getFieldValue('TYPE');
|
||||
|
||||
@@ -357,21 +318,21 @@ Blockly.Lua['lists_sort'] = function(block) {
|
||||
'end']);
|
||||
|
||||
var code = functionName +
|
||||
'(' + listCode + ',"' + type + '", ' + direction + ')';
|
||||
'(' + list + ',"' + type + '", ' + direction + ')';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
};
|
||||
|
||||
Blockly.Lua['lists_split'] = function(block) {
|
||||
// Block for splitting text into a list, or joining a list into text.
|
||||
var value_input = Blockly.Lua.valueToCode(block, 'INPUT',
|
||||
var input = Blockly.Lua.valueToCode(block, 'INPUT',
|
||||
Blockly.Lua.ORDER_NONE);
|
||||
var value_delim = Blockly.Lua.valueToCode(block, 'DELIM',
|
||||
var delimiter = Blockly.Lua.valueToCode(block, 'DELIM',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
var mode = block.getFieldValue('MODE');
|
||||
var functionName;
|
||||
if (mode == 'SPLIT') {
|
||||
if (!value_input) {
|
||||
value_input = '\'\'';
|
||||
if (!input) {
|
||||
input = '\'\'';
|
||||
}
|
||||
functionName = Blockly.Lua.provideFunction_(
|
||||
'list_string_split',
|
||||
@@ -392,13 +353,13 @@ Blockly.Lua['lists_split'] = function(block) {
|
||||
' return t',
|
||||
'end']);
|
||||
} else if (mode == 'JOIN') {
|
||||
if (!value_input) {
|
||||
value_input = '({})';
|
||||
if (!input) {
|
||||
input = '{}';
|
||||
}
|
||||
functionName = 'table.concat';
|
||||
} else {
|
||||
throw 'Unknown mode: ' + mode;
|
||||
}
|
||||
var code = functionName + '(' + value_input + ', ' + value_delim + ')';
|
||||
var code = functionName + '(' + input + ', ' + delimiter + ')';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
};
|
||||
|
||||
@@ -51,8 +51,8 @@ Blockly.Lua['procedures_defreturn'] = function(block) {
|
||||
branch = '';
|
||||
}
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.Lua.variableDB_.getName(block.arguments_[x],
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.Lua.variableDB_.getName(block.arguments_[i],
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
}
|
||||
var code = 'function ' + funcName + '(' + args.join(', ') + ')\n' +
|
||||
@@ -73,8 +73,8 @@ Blockly.Lua['procedures_callreturn'] = function(block) {
|
||||
var funcName = Blockly.Lua.variableDB_.getName(
|
||||
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.Lua.valueToCode(block, 'ARG' + x,
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.Lua.valueToCode(block, 'ARG' + i,
|
||||
Blockly.Lua.ORDER_NONE) || 'nil';
|
||||
}
|
||||
var code = funcName + '(' + args.join(', ') + ')';
|
||||
@@ -86,8 +86,8 @@ Blockly.Lua['procedures_callnoreturn'] = function(block) {
|
||||
var funcName = Blockly.Lua.variableDB_.getName(
|
||||
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.Lua.valueToCode(block, 'ARG' + x,
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.Lua.valueToCode(block, 'ARG' + i,
|
||||
Blockly.Lua.ORDER_NONE) || 'nil';
|
||||
}
|
||||
var code = funcName + '(' + args.join(', ') + ')\n';
|
||||
|
||||
@@ -40,24 +40,24 @@ Blockly.Lua['text_join'] = function(block) {
|
||||
if (block.itemCount_ == 0) {
|
||||
return ['\'\'', Blockly.Lua.ORDER_ATOMIC];
|
||||
} else if (block.itemCount_ == 1) {
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'ADD0',
|
||||
var element = Blockly.Lua.valueToCode(block, 'ADD0',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
var code = argument0;
|
||||
var code = 'tostring(' + element + ')';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
} else if (block.itemCount_ == 2) {
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'ADD0',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.Lua.valueToCode(block, 'ADD1',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
var code = argument0 + ' .. ' + argument1;
|
||||
return [code, Blockly.Lua.ORDER_UNARY];
|
||||
var element0 = Blockly.Lua.valueToCode(block, 'ADD0',
|
||||
Blockly.Lua.ORDER_CONCATENATION) || '\'\'';
|
||||
var element1 = Blockly.Lua.valueToCode(block, 'ADD1',
|
||||
Blockly.Lua.ORDER_CONCATENATION) || '\'\'';
|
||||
var code = element0 + ' .. ' + element1;
|
||||
return [code, Blockly.Lua.ORDER_CONCATENATION];
|
||||
} else {
|
||||
var code = [];
|
||||
for (var n = 0; n < block.itemCount_; n++) {
|
||||
code[n] = Blockly.Lua.valueToCode(block, 'ADD' + n,
|
||||
var elements = [];
|
||||
for (var i = 0; i < block.itemCount_; i++) {
|
||||
elements[i] = Blockly.Lua.valueToCode(block, 'ADD' + i,
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
}
|
||||
code = 'table.concat({' + code.join(', ') + '})';
|
||||
var code = 'table.concat({' + elements.join(', ') + '})';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
}
|
||||
};
|
||||
@@ -66,32 +66,30 @@ Blockly.Lua['text_append'] = function(block) {
|
||||
// Append to a variable in place.
|
||||
var varName = Blockly.Lua.variableDB_.getName(
|
||||
block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'TEXT',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
return varName + ' = ' + varName + ' .. ' + argument0 + '\n';
|
||||
var value = Blockly.Lua.valueToCode(block, 'TEXT',
|
||||
Blockly.Lua.ORDER_CONCATENATION) || '\'\'';
|
||||
return varName + ' = ' + varName + ' .. ' + value + '\n';
|
||||
};
|
||||
|
||||
Blockly.Lua['text_length'] = function(block) {
|
||||
// String or array length.
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_HIGH) || '\'\'';
|
||||
return ['#' + argument0, Blockly.Lua.ORDER_HIGH];
|
||||
var text = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_UNARY) || '\'\'';
|
||||
return ['#' + text, Blockly.Lua.ORDER_UNARY];
|
||||
};
|
||||
|
||||
Blockly.Lua['text_isEmpty'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_HIGH) || '\'\'';
|
||||
return ['#' + argument0 + ' == 0', Blockly.Lua.ORDER_RELATIONAL];
|
||||
var text = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_UNARY) || '\'\'';
|
||||
return ['#' + text + ' == 0', Blockly.Lua.ORDER_RELATIONAL];
|
||||
};
|
||||
|
||||
Blockly.Lua['text_indexOf'] = function(block) {
|
||||
// Search the text for a substring.
|
||||
var operator = block.getFieldValue('END') == 'FIRST' ?
|
||||
'indexOf' : 'lastIndexOf';
|
||||
var substr = Blockly.Lua.valueToCode(block, 'FIND',
|
||||
var substring = Blockly.Lua.valueToCode(block, 'FIND',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
var str = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
var text = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
if (block.getFieldValue('END') == 'FIRST') {
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
@@ -118,7 +116,7 @@ Blockly.Lua['text_indexOf'] = function(block) {
|
||||
' return 0',
|
||||
'end']);
|
||||
}
|
||||
var code = functionName + '(' + str + ', ' + substr + ')';
|
||||
var code = functionName + '(' + text + ', ' + substring + ')';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
};
|
||||
|
||||
@@ -126,8 +124,9 @@ Blockly.Lua['text_charAt'] = function(block) {
|
||||
// Get letter at index.
|
||||
// Note: Until January 2013 this block did not have the WHERE input.
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.Lua.valueToCode(block, 'AT',
|
||||
Blockly.Lua.ORDER_UNARY) || '1';
|
||||
var atOrder = (where == 'FROM_END') ? Blockly.Lua.ORDER_UNARY :
|
||||
Blockly.Lua.ORDER_NONE;
|
||||
var at = Blockly.Lua.valueToCode(block, 'AT', atOrder) || '1';
|
||||
var text = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
var code;
|
||||
@@ -176,8 +175,9 @@ Blockly.Lua['text_getSubstring'] = function(block) {
|
||||
|
||||
// Get start index.
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var at1 = Blockly.Lua.valueToCode(block, 'AT1',
|
||||
Blockly.Lua.ORDER_UNARY) || '1';
|
||||
var at1Order = (where1 == 'FROM_END') ? Blockly.Lua.ORDER_UNARY :
|
||||
Blockly.Lua.ORDER_NONE;
|
||||
var at1 = Blockly.Lua.valueToCode(block, 'AT1', at1Order) || '1';
|
||||
if (where1 == 'FIRST') {
|
||||
var start = 1;
|
||||
} else if (where1 == 'FROM_START') {
|
||||
@@ -190,8 +190,9 @@ Blockly.Lua['text_getSubstring'] = function(block) {
|
||||
|
||||
// Get end index.
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at2 = Blockly.Lua.valueToCode(block, 'AT2',
|
||||
Blockly.Lua.ORDER_UNARY) || '1';
|
||||
var at2Order = (where2 == 'FROM_END') ? Blockly.Lua.ORDER_UNARY :
|
||||
Blockly.Lua.ORDER_NONE;
|
||||
var at2 = Blockly.Lua.valueToCode(block, 'AT2', at2Order) || '1';
|
||||
if (where2 == 'LAST') {
|
||||
var end = -1;
|
||||
} else if (where2 == 'FROM_START') {
|
||||
@@ -208,7 +209,7 @@ Blockly.Lua['text_getSubstring'] = function(block) {
|
||||
Blockly.Lua['text_changeCase'] = function(block) {
|
||||
// Change capitalization.
|
||||
var operator = block.getFieldValue('CASE');
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'TEXT',
|
||||
var text = Blockly.Lua.valueToCode(block, 'TEXT',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
if (operator == 'UPPERCASE') {
|
||||
var functionName = 'string.upper';
|
||||
@@ -238,7 +239,7 @@ Blockly.Lua['text_changeCase'] = function(block) {
|
||||
' return table.concat(buf)',
|
||||
'end']);
|
||||
}
|
||||
var code = functionName + '(' + argument0 + ')';
|
||||
var code = functionName + '(' + text + ')';
|
||||
return [code, Blockly.Lua.ORDER_HIGH];
|
||||
};
|
||||
|
||||
@@ -258,9 +259,9 @@ Blockly.Lua['text_trim'] = function(block) {
|
||||
|
||||
Blockly.Lua['text_print'] = function(block) {
|
||||
// Print statement.
|
||||
var argument0 = Blockly.Lua.valueToCode(block, 'TEXT',
|
||||
var msg = Blockly.Lua.valueToCode(block, 'TEXT',
|
||||
Blockly.Lua.ORDER_NONE) || '\'\'';
|
||||
return 'print(' + argument0 + ')\n';
|
||||
return 'print(' + msg + ')\n';
|
||||
};
|
||||
|
||||
Blockly.Lua['text_prompt_ext'] = function(block) {
|
||||
|
||||
@@ -44,9 +44,26 @@ Blockly.PHP = new Blockly.Generator('PHP');
|
||||
*/
|
||||
Blockly.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,enddeclare,endfor,endforeach,endif,endswitch,endwhile,eval,exit,extends,final,for,foreach,function,global,goto,if,implements,include,include_once,instanceof,insteadof,interface,isset,list,namespace,new,or,print,private,protected,public,require,require_once,return,static,switch,throw,trait,try,unset,use,var,while,xor,' +
|
||||
'__halt_compiler,abstract,and,array,as,break,callable,case,catch,class,' +
|
||||
'clone,const,continue,declare,default,die,do,echo,else,elseif,empty,' +
|
||||
'enddeclare,endfor,endforeach,endif,endswitch,endwhile,eval,exit,extends,' +
|
||||
'final,for,foreach,function,global,goto,if,implements,include,' +
|
||||
'include_once,instanceof,insteadof,interface,isset,list,namespace,new,or,' +
|
||||
'print,private,protected,public,require,require_once,return,static,' +
|
||||
'switch,throw,trait,try,unset,use,var,while,xor,' +
|
||||
// http://php.net/manual/en/reserved.constants.php
|
||||
'PHP_VERSION,PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,PHP_VERSION_ID,PHP_EXTRA_VERSION,PHP_ZTS,PHP_DEBUG,PHP_MAXPATHLEN,PHP_OS,PHP_SAPI,PHP_EOL,PHP_INT_MAX,PHP_INT_SIZE,DEFAULT_INCLUDE_PATH,PEAR_INSTALL_DIR,PEAR_EXTENSION_DIR,PHP_EXTENSION_DIR,PHP_PREFIX,PHP_BINDIR,PHP_BINARY,PHP_MANDIR,PHP_LIBDIR,PHP_DATADIR,PHP_SYSCONFDIR,PHP_LOCALSTATEDIR,PHP_CONFIG_FILE_PATH,PHP_CONFIG_FILE_SCAN_DIR,PHP_SHLIB_SUFFIX,E_ERROR,E_WARNING,E_PARSE,E_NOTICE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING,E_USER_ERROR,E_USER_WARNING,E_USER_NOTICE,E_DEPRECATED,E_USER_DEPRECATED,E_ALL,E_STRICT,__COMPILER_HALT_OFFSET__,TRUE,FALSE,NULL,__CLASS__,__DIR__,__FILE__,__FUNCTION__,__LINE__,__METHOD__,__NAMESPACE__,__TRAIT__');
|
||||
'PHP_VERSION,PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,' +
|
||||
'PHP_VERSION_ID,PHP_EXTRA_VERSION,PHP_ZTS,PHP_DEBUG,PHP_MAXPATHLEN,' +
|
||||
'PHP_OS,PHP_SAPI,PHP_EOL,PHP_INT_MAX,PHP_INT_SIZE,DEFAULT_INCLUDE_PATH,' +
|
||||
'PEAR_INSTALL_DIR,PEAR_EXTENSION_DIR,PHP_EXTENSION_DIR,PHP_PREFIX,' +
|
||||
'PHP_BINDIR,PHP_BINARY,PHP_MANDIR,PHP_LIBDIR,PHP_DATADIR,PHP_SYSCONFDIR,' +
|
||||
'PHP_LOCALSTATEDIR,PHP_CONFIG_FILE_PATH,PHP_CONFIG_FILE_SCAN_DIR,' +
|
||||
'PHP_SHLIB_SUFFIX,E_ERROR,E_WARNING,E_PARSE,E_NOTICE,E_CORE_ERROR,' +
|
||||
'E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING,E_USER_ERROR,' +
|
||||
'E_USER_WARNING,E_USER_NOTICE,E_DEPRECATED,E_USER_DEPRECATED,E_ALL,' +
|
||||
'E_STRICT,__COMPILER_HALT_OFFSET__,TRUE,FALSE,NULL,__CLASS__,__DIR__,' +
|
||||
'__FILE__,__FUNCTION__,__LINE__,__METHOD__,__NAMESPACE__,__TRAIT__'
|
||||
);
|
||||
|
||||
/**
|
||||
* Order of operation ENUMs.
|
||||
@@ -55,34 +72,71 @@ Blockly.PHP.addReservedWords(
|
||||
Blockly.PHP.ORDER_ATOMIC = 0; // 0 "" ...
|
||||
Blockly.PHP.ORDER_CLONE = 1; // clone
|
||||
Blockly.PHP.ORDER_NEW = 1; // new
|
||||
Blockly.PHP.ORDER_MEMBER = 2; // ()
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL = 2; // ()
|
||||
Blockly.PHP.ORDER_INCREMENT = 3; // ++
|
||||
Blockly.PHP.ORDER_DECREMENT = 3; // --
|
||||
Blockly.PHP.ORDER_LOGICAL_NOT = 4; // !
|
||||
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_UNARY_PLUS = 4; // +
|
||||
Blockly.PHP.ORDER_UNARY_NEGATION = 4; // -
|
||||
Blockly.PHP.ORDER_MULTIPLICATION = 5; // *
|
||||
Blockly.PHP.ORDER_DIVISION = 5; // /
|
||||
Blockly.PHP.ORDER_MODULUS = 5; // %
|
||||
Blockly.PHP.ORDER_ADDITION = 6; // +
|
||||
Blockly.PHP.ORDER_SUBTRACTION = 6; // -
|
||||
Blockly.PHP.ORDER_BITWISE_SHIFT = 7; // << >> >>>
|
||||
Blockly.PHP.ORDER_RELATIONAL = 8; // < <= > >=
|
||||
Blockly.PHP.ORDER_IN = 8; // in
|
||||
Blockly.PHP.ORDER_INSTANCEOF = 8; // instanceof
|
||||
Blockly.PHP.ORDER_EQUALITY = 9; // == != === !==
|
||||
Blockly.PHP.ORDER_BITWISE_AND = 10; // &
|
||||
Blockly.PHP.ORDER_BITWISE_XOR = 11; // ^
|
||||
Blockly.PHP.ORDER_BITWISE_OR = 12; // |
|
||||
Blockly.PHP.ORDER_CONDITIONAL = 13; // ?:
|
||||
Blockly.PHP.ORDER_ASSIGNMENT = 14; // = += -= *= /= %= <<= >>= ...
|
||||
Blockly.PHP.ORDER_LOGICAL_AND = 15; // &&
|
||||
Blockly.PHP.ORDER_LOGICAL_OR = 16; // ||
|
||||
Blockly.PHP.ORDER_COMMA = 17; // ,
|
||||
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_COMMA = 24; // ,
|
||||
Blockly.PHP.ORDER_NONE = 99; // (...)
|
||||
|
||||
/**
|
||||
* List of outer-inner pairings that do NOT require parentheses.
|
||||
* @type {!Array.<!Array.<number>>}
|
||||
*/
|
||||
Blockly.PHP.ORDER_OVERRIDES = [
|
||||
// (foo()).bar() -> foo().bar()
|
||||
// (foo())[0] -> foo()[0]
|
||||
[Blockly.PHP.ORDER_MEMBER, Blockly.PHP.ORDER_FUNCTION_CALL],
|
||||
// (foo[0])[1] -> foo[0][1]
|
||||
// (foo.bar).baz -> foo.bar.baz
|
||||
[Blockly.PHP.ORDER_MEMBER, Blockly.PHP.ORDER_MEMBER],
|
||||
// !(!foo) -> !!foo
|
||||
[Blockly.PHP.ORDER_LOGICAL_NOT, Blockly.PHP.ORDER_LOGICAL_NOT],
|
||||
// a * (b * c) -> a * b * c
|
||||
[Blockly.PHP.ORDER_MULTIPLICATION, Blockly.PHP.ORDER_MULTIPLICATION],
|
||||
// a + (b + c) -> a + b + c
|
||||
[Blockly.PHP.ORDER_ADDITION, Blockly.PHP.ORDER_ADDITION],
|
||||
// a && (b && c) -> a && b && c
|
||||
[Blockly.PHP.ORDER_LOGICAL_AND, Blockly.PHP.ORDER_LOGICAL_AND],
|
||||
// a || (b || c) -> a || b || c
|
||||
[Blockly.PHP.ORDER_LOGICAL_OR, Blockly.PHP.ORDER_LOGICAL_OR]
|
||||
];
|
||||
|
||||
/**
|
||||
* Allow for switching between one and zero based indexing for lists and text,
|
||||
* one based by default.
|
||||
*/
|
||||
Blockly.PHP.ONE_BASED_INDEXING = true;
|
||||
|
||||
/**
|
||||
* Initialise the database of variable names.
|
||||
* @param {!Blockly.Workspace} workspace Workspace to generate code from.
|
||||
@@ -173,9 +227,9 @@ Blockly.PHP.scrub_ = function(block, code) {
|
||||
}
|
||||
// Collect comments for all value arguments.
|
||||
// Don't collect comments for nested statements.
|
||||
for (var x = 0; x < block.inputList.length; x++) {
|
||||
if (block.inputList[x].type == Blockly.INPUT_VALUE) {
|
||||
var childBlock = block.inputList[x].connection.targetBlock();
|
||||
for (var i = 0; i < block.inputList.length; i++) {
|
||||
if (block.inputList[i].type == Blockly.INPUT_VALUE) {
|
||||
var childBlock = block.inputList[i].connection.targetBlock();
|
||||
if (childBlock) {
|
||||
var comment = Blockly.PHP.allNestedComments(childBlock);
|
||||
if (comment) {
|
||||
@@ -189,3 +243,66 @@ Blockly.PHP.scrub_ = function(block, code) {
|
||||
var nextCode = Blockly.PHP.blockToCode(nextBlock);
|
||||
return commentCode + code + nextCode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a property and adjusts the value while taking into account indexing.
|
||||
* @param {!Blockly.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,
|
||||
opt_order) {
|
||||
var delta = opt_delta || 0;
|
||||
var order = opt_order || Blockly.PHP.ORDER_NONE;
|
||||
if (Blockly.PHP.ONE_BASED_INDEXING) {
|
||||
delta--;
|
||||
}
|
||||
var defaultAtIndex = Blockly.PHP.ONE_BASED_INDEXING ? '1' : '0';
|
||||
if (delta > 0) {
|
||||
var at = Blockly.PHP.valueToCode(block, atId,
|
||||
Blockly.PHP.ORDER_ADDITION) || defaultAtIndex;
|
||||
} else if (delta < 0) {
|
||||
var at = Blockly.PHP.valueToCode(block, atId,
|
||||
Blockly.PHP.ORDER_SUBTRACTION) || defaultAtIndex;
|
||||
} else if (opt_negate) {
|
||||
var at = Blockly.PHP.valueToCode(block, atId,
|
||||
Blockly.PHP.ORDER_UNARY_NEGATION) || defaultAtIndex;
|
||||
} else {
|
||||
var at = Blockly.PHP.valueToCode(block, atId, order) ||
|
||||
defaultAtIndex;
|
||||
}
|
||||
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, adjust it right now.
|
||||
at = parseFloat(at) + delta;
|
||||
if (opt_negate) {
|
||||
at = -at;
|
||||
}
|
||||
} else {
|
||||
// If the index is dynamic, adjust it in code.
|
||||
if (delta > 0) {
|
||||
at = at + ' + ' + delta;
|
||||
var innerOrder = Blockly.PHP.ORDER_ADDITION;
|
||||
} else if (delta < 0) {
|
||||
at = at + ' - ' + -delta;
|
||||
var innerOrder = Blockly.PHP.ORDER_SUBTRACTION;
|
||||
}
|
||||
if (opt_negate) {
|
||||
if (delta) {
|
||||
at = '-(' + at + ')';
|
||||
} else {
|
||||
at = '-' + at;
|
||||
}
|
||||
var innerOrder = Blockly.PHP.ORDER_UNARY_NEGATION;
|
||||
}
|
||||
innerOrder = Math.floor(innerOrder);
|
||||
order = Math.floor(order);
|
||||
if (innerOrder && order >= innerOrder) {
|
||||
at = '(' + at + ')';
|
||||
}
|
||||
}
|
||||
return at;
|
||||
};
|
||||
|
||||
@@ -39,7 +39,7 @@ Blockly.PHP['colour_random'] = function(block) {
|
||||
// Generate a random colour.
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'colour_random',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {',
|
||||
' return \'#\' . str_pad(dechex(mt_rand(0, 0xFFFFFF)), ' +
|
||||
'6, \'0\', STR_PAD_LEFT);',
|
||||
'}']);
|
||||
@@ -57,15 +57,15 @@ Blockly.PHP['colour_rgb'] = function(block) {
|
||||
Blockly.PHP.ORDER_COMMA) || 0;
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'colour_rgb',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.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);',
|
||||
' $b = round(max(min($b, 100), 0) * 2.55);',
|
||||
' $hex = "#";',
|
||||
' $hex .= str_pad(dechex($r), 2, "0", STR_PAD_LEFT);',
|
||||
' $hex .= str_pad(dechex($g), 2, "0", STR_PAD_LEFT);',
|
||||
' $hex .= str_pad(dechex($b), 2, "0", STR_PAD_LEFT);',
|
||||
' $hex = \'#\';',
|
||||
' $hex .= str_pad(dechex($r), 2, \'0\', STR_PAD_LEFT);',
|
||||
' $hex .= str_pad(dechex($g), 2, \'0\', STR_PAD_LEFT);',
|
||||
' $hex .= str_pad(dechex($b), 2, \'0\', STR_PAD_LEFT);',
|
||||
' return $hex;',
|
||||
'}']);
|
||||
var code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
|
||||
@@ -82,7 +82,7 @@ Blockly.PHP['colour_blend'] = function(block) {
|
||||
Blockly.PHP.ORDER_COMMA) || 0.5;
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'colour_blend',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($c1, $c2, $ratio) {',
|
||||
' $ratio = max(min($ratio, 1), 0);',
|
||||
' $r1 = hexdec(substr($c1, 1, 2));',
|
||||
@@ -94,10 +94,10 @@ Blockly.PHP['colour_blend'] = function(block) {
|
||||
' $r = round($r1 * (1 - $ratio) + $r2 * $ratio);',
|
||||
' $g = round($g1 * (1 - $ratio) + $g2 * $ratio);',
|
||||
' $b = round($b1 * (1 - $ratio) + $b2 * $ratio);',
|
||||
' $hex = "#";',
|
||||
' $hex .= str_pad(dechex($r), 2, "0", STR_PAD_LEFT);',
|
||||
' $hex .= str_pad(dechex($g), 2, "0", STR_PAD_LEFT);',
|
||||
' $hex .= str_pad(dechex($b), 2, "0", STR_PAD_LEFT);',
|
||||
' $hex = \'#\';',
|
||||
' $hex .= str_pad(dechex($r), 2, \'0\', STR_PAD_LEFT);',
|
||||
' $hex .= str_pad(dechex($g), 2, \'0\', STR_PAD_LEFT);',
|
||||
' $hex .= str_pad(dechex($b), 2, \'0\', STR_PAD_LEFT);',
|
||||
' return $hex;',
|
||||
'}']);
|
||||
var code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
|
||||
|
||||
@@ -22,6 +22,17 @@
|
||||
* @fileoverview Generating PHP for list blocks.
|
||||
* @author daarond@gmail.com (Daaron Dwyer)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Lists in PHP are known to break when non-variables are passed into blocks
|
||||
* that require a list. PHP, unlike other languages, passes arrays as reference
|
||||
* value instead of value so we are unable to support it to the extent we can
|
||||
* for the other languages.
|
||||
* For example, a ternary operator with two arrays will return the array by
|
||||
* value and that cannot be passed into any of the built-in array functions for
|
||||
* PHP (because only variables can be passed by reference).
|
||||
* ex: end(true ? list1 : list2)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.PHP.lists');
|
||||
@@ -31,25 +42,25 @@ goog.require('Blockly.PHP');
|
||||
|
||||
Blockly.PHP['lists_create_empty'] = function(block) {
|
||||
// Create an empty list.
|
||||
return ['array()', Blockly.PHP.ORDER_ATOMIC];
|
||||
return ['array()', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.PHP['lists_create_with'] = function(block) {
|
||||
// Create a list with any number of elements of any type.
|
||||
var code = new Array(block.itemCount_);
|
||||
for (var n = 0; n < block.itemCount_; n++) {
|
||||
code[n] = Blockly.PHP.valueToCode(block, 'ADD' + n,
|
||||
for (var i = 0; i < block.itemCount_; i++) {
|
||||
code[i] = Blockly.PHP.valueToCode(block, 'ADD' + i,
|
||||
Blockly.PHP.ORDER_COMMA) || 'null';
|
||||
}
|
||||
code = 'array(' + code.join(', ') + ')';
|
||||
return [code, Blockly.PHP.ORDER_ATOMIC];
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.PHP['lists_repeat'] = function(block) {
|
||||
// Create a list with one element repeated.
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lists_repeat',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($value, $count) {',
|
||||
' $array = array();',
|
||||
' for ($index = 0; $index < $count; $index++) {',
|
||||
@@ -57,11 +68,11 @@ Blockly.PHP['lists_repeat'] = function(block) {
|
||||
' }',
|
||||
' return $array;',
|
||||
'}']);
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'ITEM',
|
||||
var element = Blockly.PHP.valueToCode(block, 'ITEM',
|
||||
Blockly.PHP.ORDER_COMMA) || 'null';
|
||||
var argument1 = Blockly.PHP.valueToCode(block, 'NUM',
|
||||
var repeatCount = Blockly.PHP.valueToCode(block, 'NUM',
|
||||
Blockly.PHP.ORDER_COMMA) || '0';
|
||||
var code = functionName + '(' + argument0 + ', ' + argument1 + ')';
|
||||
var code = functionName + '(' + element + ', ' + repeatCount + ')';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
@@ -69,16 +80,16 @@ Blockly.PHP['lists_length'] = function(block) {
|
||||
// String or array length.
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'length',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {',
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {',
|
||||
' if (is_string($value)) {',
|
||||
' return strlen($value);',
|
||||
' } else {',
|
||||
' return count($value);',
|
||||
' }',
|
||||
'}']);
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
return [functionName + '(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
return [functionName + '(' + list + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.PHP['lists_isEmpty'] = function(block) {
|
||||
@@ -90,33 +101,39 @@ Blockly.PHP['lists_isEmpty'] = function(block) {
|
||||
|
||||
Blockly.PHP['lists_indexOf'] = function(block) {
|
||||
// Find an item in the list.
|
||||
var operator = block.getFieldValue('END') == 'FIRST' ?
|
||||
'indexOf' : 'lastIndexOf';
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'FIND',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_MEMBER) || '[]';
|
||||
var functionName;
|
||||
if (block.getFieldValue('END') == 'FIRST'){
|
||||
if (Blockly.PHP.ONE_BASED_INDEXING) {
|
||||
var errorIndex = ' 0';
|
||||
var indexAdjustment = ' + 1';
|
||||
} else {
|
||||
var errorIndex = ' -1';
|
||||
var indexAdjustment = '';
|
||||
}
|
||||
if (block.getFieldValue('END') == 'FIRST') {
|
||||
// indexOf
|
||||
functionName = Blockly.PHP.provideFunction_(
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'indexOf',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($haystack, $needle) {',
|
||||
' for ($index = 0; $index < count($haystack); $index++) {',
|
||||
' if ($haystack[$index] == $needle) return $index + 1;',
|
||||
' if ($haystack[$index] == $needle) return $index' +
|
||||
indexAdjustment + ';',
|
||||
' }',
|
||||
' return 0;',
|
||||
' return ' + errorIndex + ';',
|
||||
'}']);
|
||||
} else {
|
||||
// lastIndexOf
|
||||
functionName = Blockly.PHP.provideFunction_(
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lastIndexOf',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($haystack, $needle) {',
|
||||
' $last = 0;',
|
||||
' $last = ' + errorIndex + ';',
|
||||
' for ($index = 0; $index < count($haystack); $index++) {',
|
||||
' if ($haystack[$index] == $needle) $last = $index + 1;',
|
||||
' if ($haystack[$index] == $needle) $last = $index' +
|
||||
indexAdjustment + ';',
|
||||
' }',
|
||||
' return $last;',
|
||||
'}']);
|
||||
@@ -130,59 +147,71 @@ Blockly.PHP['lists_getIndex'] = function(block) {
|
||||
// Get element at index.
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.PHP.valueToCode(block, 'AT',
|
||||
Blockly.PHP.ORDER_UNARY_NEGATION) || '1';
|
||||
if (mode == 'GET') {
|
||||
var order = Blockly.PHP.ORDER_FUNCTION_CALL;
|
||||
} else {
|
||||
// List will be an argument in a function call.
|
||||
var order = Blockly.PHP.ORDER_COMMA;
|
||||
}
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE', order) || 'array()';
|
||||
|
||||
if (where == 'FIRST') {
|
||||
switch (where) {
|
||||
case 'FIRST':
|
||||
if (mode == 'GET') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_MEMBER) || 'array()';
|
||||
var code = list + '[0]';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
return [code, Blockly.PHP.ORDER_MEMBER];
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || 'array()';
|
||||
var code = 'array_shift(' + list + ')';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || 'array()';
|
||||
return 'array_shift(' + list + ');\n';
|
||||
}
|
||||
} else if (where == 'LAST') {
|
||||
break;
|
||||
case 'LAST':
|
||||
if (mode == 'GET') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || 'array()';
|
||||
var code = 'end(' + list + ')';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || 'array()';
|
||||
var code = 'array_pop(' + list + ')';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || 'array()';
|
||||
return 'array_pop(' + list + ');\n';
|
||||
}
|
||||
} else if (where == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseFloat(at) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at += ' - 1';
|
||||
}
|
||||
break;
|
||||
case 'FROM_START':
|
||||
var at = Blockly.PHP.getAdjusted(block, 'AT');
|
||||
if (mode == 'GET') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_MEMBER) || 'array()';
|
||||
var code = list + '[' + at + ']';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
return [code, Blockly.PHP.ORDER_MEMBER];
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_COMMA) || 'array()';
|
||||
var code = 'array_splice(' + list + ', ' + at + ', 1)[0]';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_COMMA) || 'array()';
|
||||
return 'array_splice(' + list + ', ' + at + ', 1);\n';
|
||||
}
|
||||
} else if (where == 'FROM_END') {
|
||||
break;
|
||||
case 'FROM_END':
|
||||
if (mode == 'GET') {
|
||||
var code = 'array_slice(' + list + ', -' + at + ', 1)[0]';
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_COMMA) || 'array()';
|
||||
var at = Blockly.PHP.getAdjusted(block, 'AT', 1, true);
|
||||
var code = 'array_slice(' + list + ', ' + at + ', 1)[0]';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'GET_REMOVE' || mode == 'REMOVE') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || 'array()';
|
||||
var at = Blockly.PHP.getAdjusted(block, 'AT', 1, false,
|
||||
Blockly.PHP.ORDER_SUBTRACTION);
|
||||
code = 'array_splice(' + list +
|
||||
', count(' + list + ') - ' + at + ', 1)[0]';
|
||||
if (mode == 'GET_REMOVE') {
|
||||
@@ -191,20 +220,23 @@ Blockly.PHP['lists_getIndex'] = function(block) {
|
||||
return code + ';\n';
|
||||
}
|
||||
}
|
||||
} else if (where == 'RANDOM') {
|
||||
if (mode == 'GET'){
|
||||
break;
|
||||
case 'RANDOM':
|
||||
var list = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || 'array()';
|
||||
if (mode == 'GET') {
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lists_get_random_item',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($list) {',
|
||||
' return $list[rand(0,count($list)-1)];',
|
||||
'}']);
|
||||
code = functionName + '(' + list + ')';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'GET_REMOVE'){
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lists_get_remove_random_item',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(&$list) {',
|
||||
' $x = rand(0,count($list)-1);',
|
||||
' unset($list[$x]);',
|
||||
@@ -215,12 +247,13 @@ Blockly.PHP['lists_getIndex'] = function(block) {
|
||||
} else if (mode == 'REMOVE') {
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lists_remove_random_item',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(&$list) {',
|
||||
' unset($list[rand(0,count($list)-1)]);',
|
||||
'}']);
|
||||
return functionName + '(' + list + ');\n';
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw 'Unhandled combination (lists_getIndex).';
|
||||
};
|
||||
@@ -228,18 +261,14 @@ Blockly.PHP['lists_getIndex'] = function(block) {
|
||||
Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
// Set element at index.
|
||||
// Note: Until February 2013 this block did not have MODE or WHERE inputs.
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_MEMBER) || 'array()';
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.PHP.valueToCode(block, 'AT',
|
||||
Blockly.PHP.ORDER_NONE) || '1';
|
||||
var value = Blockly.PHP.valueToCode(block, 'TO',
|
||||
Blockly.PHP.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+$/)) {
|
||||
if (list.match(/^\$\w+$/)) {
|
||||
return '';
|
||||
}
|
||||
var listVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
@@ -248,17 +277,25 @@ Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
list = listVar;
|
||||
return code;
|
||||
}
|
||||
if (where == 'FIRST') {
|
||||
switch (where) {
|
||||
case 'FIRST':
|
||||
if (mode == 'SET') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_MEMBER) || 'array()';
|
||||
return list + '[0] = ' + value + ';\n';
|
||||
} else if (mode == 'INSERT') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_COMMA) || 'array()';
|
||||
return 'array_unshift(' + list + ', ' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'LAST') {
|
||||
break;
|
||||
case 'LAST':
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_COMMA) || 'array()';
|
||||
if (mode == 'SET') {
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lists_set_last_item',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(&$list, $value) {',
|
||||
' $list[count($list) - 1] = $value;',
|
||||
'}']);
|
||||
@@ -266,25 +303,27 @@ Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
} else if (mode == 'INSERT') {
|
||||
return 'array_push(' + list + ', ' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseFloat(at) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at += ' - 1';
|
||||
}
|
||||
break;
|
||||
case 'FROM_START':
|
||||
var at = Blockly.PHP.getAdjusted(block, 'AT');
|
||||
if (mode == 'SET') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_MEMBER) || 'array()';
|
||||
return list + '[' + at + '] = ' + value + ';\n';
|
||||
} else if (mode == 'INSERT') {
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_COMMA) || 'array()';
|
||||
return 'array_splice(' + list + ', ' + at + ', 0, ' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'FROM_END') {
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_COMMA) || 'array()';
|
||||
var at = Blockly.PHP.getAdjusted(block, 'AT', 1);
|
||||
if (mode == 'SET') {
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lists_set_from_end',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(&$list, $at, $value) {',
|
||||
' $list[count($list) - $at] = $value;',
|
||||
'}']);
|
||||
@@ -292,13 +331,16 @@ Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
} else if (mode == 'INSERT') {
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lists_insert_from_end',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(&$list, $at, $value) {',
|
||||
' return array_splice($list, count($list) - $at, 0, $value);',
|
||||
'}']);
|
||||
return functionName + '(' + list + ', ' + at + ', ' + value + ');\n';
|
||||
}
|
||||
} else if (where == 'RANDOM') {
|
||||
break;
|
||||
case 'RANDOM':
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_REFERENCE) || 'array()';
|
||||
var code = cacheList();
|
||||
var xVar = Blockly.PHP.variableDB_.getDistinctName(
|
||||
'tmp_x', Blockly.Variables.NAME_TYPE);
|
||||
@@ -307,9 +349,11 @@ Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
code += list + '[' + xVar + '] = ' + value + ';\n';
|
||||
return code;
|
||||
} else if (mode == 'INSERT') {
|
||||
code += 'array_splice(' + list + ', ' + xVar + ', 0, ' + value + ');\n';
|
||||
code += 'array_splice(' + list + ', ' + xVar + ', 0, ' + value +
|
||||
');\n';
|
||||
return code;
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw 'Unhandled combination (lists_setIndex).';
|
||||
};
|
||||
@@ -317,43 +361,89 @@ Blockly.PHP['lists_setIndex'] = function(block) {
|
||||
Blockly.PHP['lists_getSublist'] = function(block) {
|
||||
// Get sublist.
|
||||
var list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_MEMBER) || 'array()';
|
||||
Blockly.PHP.ORDER_COMMA) || 'array()';
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at1 = Blockly.PHP.valueToCode(block, 'AT1',
|
||||
Blockly.PHP.ORDER_NONE) || '1';
|
||||
var at2 = Blockly.PHP.valueToCode(block, 'AT2',
|
||||
Blockly.PHP.ORDER_NONE) || '1';
|
||||
if (where1 == 'FIRST' && where2 == 'LAST') {
|
||||
var code = list;
|
||||
} else if (list.match(/^\$\w+$/) ||
|
||||
(where1 != 'FROM_END' && where2 == 'FROM_START')) {
|
||||
// If the list is a simple value or doesn't require a call for length, don't
|
||||
// generate a helper function.
|
||||
switch (where1) {
|
||||
case 'FROM_START':
|
||||
var at1 = Blockly.PHP.getAdjusted(block, 'AT1');
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at1 = Blockly.PHP.getAdjusted(block, 'AT1', 1, false,
|
||||
Blockly.PHP.ORDER_SUBTRACTION);
|
||||
at1 = 'count(' + list + ') - ' + at1;
|
||||
break;
|
||||
case 'FIRST':
|
||||
var at1 = '0';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (lists_getSublist).';
|
||||
}
|
||||
switch (where2) {
|
||||
case 'FROM_START':
|
||||
var at2 = Blockly.PHP.getAdjusted(block, 'AT2', 0, false,
|
||||
Blockly.PHP.ORDER_SUBTRACTION);
|
||||
var length = at2 + ' - ';
|
||||
if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) {
|
||||
length += at1;
|
||||
} else {
|
||||
length += '(' + at1 + ')';
|
||||
}
|
||||
length += ' + 1';
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at2 = Blockly.PHP.getAdjusted(block, 'AT2', 0, false,
|
||||
Blockly.PHP.ORDER_SUBTRACTION);
|
||||
var length = 'count(' + list + ') - ' + at2 + ' - ';
|
||||
if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) {
|
||||
length += at1;
|
||||
} else {
|
||||
length += '(' + at1 + ')';
|
||||
}
|
||||
break;
|
||||
case 'LAST':
|
||||
var length = 'count(' + list + ') - ';
|
||||
if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) {
|
||||
length += at1;
|
||||
} else {
|
||||
length += '(' + at1 + ')';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (lists_getSublist).';
|
||||
}
|
||||
code = 'array_slice(' + list + ', ' + at1 + ', ' + length + ')';
|
||||
} else {
|
||||
var at1 = Blockly.PHP.getAdjusted(block, 'AT1');
|
||||
var at2 = Blockly.PHP.getAdjusted(block, 'AT2');
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lists_get_sublist',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($list, $where1, $at1, $where2, $at2) {',
|
||||
' if ($where2 == \'FROM_START\') {',
|
||||
' $at2--;',
|
||||
' } else if ($where2 == \'FROM_END\') {',
|
||||
' $at2 = $at2 - $at1;',
|
||||
' } else if ($where2 == \'FIRST\') {',
|
||||
' $at2 = 0;',
|
||||
' } else if ($where2 == \'LAST\') {',
|
||||
' $at2 = count($list);',
|
||||
' } else {',
|
||||
' throw \'Unhandled option (lists_getSublist).\';',
|
||||
' }',
|
||||
' if ($where1 == \'FROM_START\') {',
|
||||
' $at1--;',
|
||||
' } else if ($where1 == \'FROM_END\') {',
|
||||
' $at1 = count($list) - $at1;',
|
||||
' if ($where1 == \'FROM_END\') {',
|
||||
' $at1 = count($list) - 1 - $at1;',
|
||||
' } else if ($where1 == \'FIRST\') {',
|
||||
' $at1 = 0;',
|
||||
' } else if ($where1 == \'LAST\') {',
|
||||
' $at1 = count($list) - 1;',
|
||||
' } else {',
|
||||
' throw \'Unhandled option (lists_getSublist).\';',
|
||||
' } else if ($where1 != \'FROM_START\'){',
|
||||
' throw new Exception(\'Unhandled option (lists_get_sublist).\');',
|
||||
' }',
|
||||
' return array_slice($list, $at1, $at2);',
|
||||
' $length = 0;',
|
||||
' if ($where2 == \'FROM_START\') {',
|
||||
' $length = $at2 - $at1 + 1;',
|
||||
' } else if ($where2 == \'FROM_END\') {',
|
||||
' $length = count($list) - $at1 - $at2;',
|
||||
' } else if ($where2 == \'LAST\') {',
|
||||
' $length = count($list) - $at1;',
|
||||
' } else {',
|
||||
' throw new Exception(\'Unhandled option (lists_get_sublist).\');',
|
||||
' }',
|
||||
' return array_slice($list, $at1, $length);',
|
||||
'}']);
|
||||
var code = functionName + '(' + list + ', \'' +
|
||||
where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
|
||||
@@ -364,12 +454,12 @@ Blockly.PHP['lists_getSublist'] = function(block) {
|
||||
Blockly.PHP['lists_sort'] = function(block) {
|
||||
// Block for sorting a list.
|
||||
var listCode = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
|
||||
Blockly.PHP.ORDER_COMMA) || 'array()';
|
||||
var direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
|
||||
var type = block.getFieldValue('TYPE');
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'lists_sort', [
|
||||
'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'lists_sort',
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($list, $type, $direction) {',
|
||||
' $sortCmpFuncs = array(',
|
||||
' "NUMERIC" => "strnatcasecmp",',
|
||||
@@ -392,9 +482,9 @@ Blockly.PHP['lists_sort'] = function(block) {
|
||||
Blockly.PHP['lists_split'] = function(block) {
|
||||
// Block for splitting text into a list, or joining a list into text.
|
||||
var value_input = Blockly.PHP.valueToCode(block, 'INPUT',
|
||||
Blockly.PHP.ORDER_MEMBER);
|
||||
Blockly.PHP.ORDER_COMMA);
|
||||
var value_delim = Blockly.PHP.valueToCode(block, 'DELIM',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
Blockly.PHP.ORDER_COMMA) || '\'\'';
|
||||
var mode = block.getFieldValue('MODE');
|
||||
if (mode == 'SPLIT') {
|
||||
if (!value_input) {
|
||||
|
||||
@@ -47,20 +47,14 @@ Blockly.PHP['math_arithmetic'] = function(block) {
|
||||
'MINUS': [' - ', Blockly.PHP.ORDER_SUBTRACTION],
|
||||
'MULTIPLY': [' * ', Blockly.PHP.ORDER_MULTIPLICATION],
|
||||
'DIVIDE': [' / ', Blockly.PHP.ORDER_DIVISION],
|
||||
'POWER': [null, Blockly.PHP.ORDER_COMMA] // Handle power separately.
|
||||
'POWER': [' ** ', Blockly.PHP.ORDER_POWER]
|
||||
};
|
||||
var tuple = OPERATORS[block.getFieldValue('OP')];
|
||||
var operator = tuple[0];
|
||||
var order = tuple[1];
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'A', order) || '0';
|
||||
var argument1 = Blockly.PHP.valueToCode(block, 'B', order) || '0';
|
||||
var code;
|
||||
// Power in PHP requires a special case since it has no operator.
|
||||
if (!operator) {
|
||||
code = 'pow(' + argument0 + ', ' + argument1 + ')';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
code = argument0 + operator + argument1;
|
||||
var code = argument0 + operator + argument1;
|
||||
return [code, order];
|
||||
};
|
||||
|
||||
@@ -172,7 +166,7 @@ Blockly.PHP['math_number_property'] = function(block) {
|
||||
// Prime is a special case as it is not a one-liner test.
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_isPrime',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($n) {',
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($n) {',
|
||||
' // https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
|
||||
' if ($n == 2 || $n == 3) {',
|
||||
' return true;',
|
||||
@@ -256,7 +250,7 @@ Blockly.PHP['math_on_list'] = function(block) {
|
||||
case 'AVERAGE':
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_mean',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($myList) {',
|
||||
' return array_sum($myList) / count($myList);',
|
||||
'}']);
|
||||
@@ -267,11 +261,12 @@ Blockly.PHP['math_on_list'] = function(block) {
|
||||
case 'MEDIAN':
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_median',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.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;',
|
||||
' ($arr[floor(count($arr)/2)] + $arr[floor(count($arr)/2)' +
|
||||
' - 1]) / 2;',
|
||||
'}']);
|
||||
list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_NONE) || '[]';
|
||||
@@ -283,12 +278,13 @@ Blockly.PHP['math_on_list'] = function(block) {
|
||||
// Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1].
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_modes',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($values) {',
|
||||
' $v = array_count_values($values);',
|
||||
' arsort($v);',
|
||||
' foreach($v as $k => $v){$total = $k; break;}',
|
||||
' return array($total);',
|
||||
' if (empty($values)) return array();',
|
||||
' $counts = array_count_values($values);',
|
||||
' arsort($counts); // Sort counts in descending order',
|
||||
' $modes = array_keys($counts, current($counts), true);',
|
||||
' return $modes;',
|
||||
'}']);
|
||||
list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
Blockly.PHP.ORDER_NONE) || '[]';
|
||||
@@ -297,12 +293,13 @@ Blockly.PHP['math_on_list'] = function(block) {
|
||||
case 'STD_DEV':
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_standard_deviation',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($numbers) {',
|
||||
' $n = count($numbers);',
|
||||
' if (!$n) return null;',
|
||||
' $mean = array_sum($numbers) / count($numbers);',
|
||||
' foreach($numbers as $key => $num) $devs[$key] = pow($num - $mean, 2);',
|
||||
' foreach($numbers as $key => $num) $devs[$key] = ' +
|
||||
'pow($num - $mean, 2);',
|
||||
' return sqrt(array_sum($devs) / (count($devs) - 1));',
|
||||
'}']);
|
||||
list = Blockly.PHP.valueToCode(block, 'LIST',
|
||||
@@ -312,7 +309,7 @@ Blockly.PHP['math_on_list'] = function(block) {
|
||||
case 'RANDOM':
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_random_list',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($list) {',
|
||||
' $x = rand(0, count($list)-1);',
|
||||
' return $list[$x];',
|
||||
@@ -358,7 +355,7 @@ Blockly.PHP['math_random_int'] = function(block) {
|
||||
Blockly.PHP.ORDER_COMMA) || '0';
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'math_random_int',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($a, $b) {',
|
||||
' if ($a > $b) {',
|
||||
' return rand($b, $a);',
|
||||
|
||||
@@ -63,8 +63,8 @@ Blockly.PHP['procedures_defreturn'] = function(block) {
|
||||
returnValue = ' return ' + returnValue + ';\n';
|
||||
}
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.PHP.variableDB_.getName(block.arguments_[x],
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.PHP.variableDB_.getName(block.arguments_[i],
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
}
|
||||
var code = 'function ' + funcName + '(' + args.join(', ') + ') {\n' +
|
||||
@@ -85,8 +85,8 @@ Blockly.PHP['procedures_callreturn'] = function(block) {
|
||||
var funcName = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.PHP.valueToCode(block, 'ARG' + x,
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.PHP.valueToCode(block, 'ARG' + i,
|
||||
Blockly.PHP.ORDER_COMMA) || 'null';
|
||||
}
|
||||
var code = funcName + '(' + args.join(', ') + ')';
|
||||
@@ -98,8 +98,8 @@ Blockly.PHP['procedures_callnoreturn'] = function(block) {
|
||||
var funcName = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.PHP.valueToCode(block, 'ARG' + x,
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.PHP.valueToCode(block, 'ARG' + i,
|
||||
Blockly.PHP.ORDER_COMMA) || 'null';
|
||||
}
|
||||
var code = funcName + '(' + args.join(', ') + ');\n';
|
||||
|
||||
@@ -37,28 +37,27 @@ Blockly.PHP['text'] = function(block) {
|
||||
|
||||
Blockly.PHP['text_join'] = function(block) {
|
||||
// Create a string made up of any number of elements of any type.
|
||||
var code;
|
||||
if (block.itemCount_ == 0) {
|
||||
return ['\'\'', Blockly.PHP.ORDER_ATOMIC];
|
||||
} else if (block.itemCount_ == 1) {
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'ADD0',
|
||||
var element = Blockly.PHP.valueToCode(block, 'ADD0',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
code = argument0;
|
||||
var code = element;
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
} else if (block.itemCount_ == 2) {
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'ADD0',
|
||||
var element0 = Blockly.PHP.valueToCode(block, 'ADD0',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.PHP.valueToCode(block, 'ADD1',
|
||||
var element1 = Blockly.PHP.valueToCode(block, 'ADD1',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
code = argument0 + ' . ' + argument1;
|
||||
var code = element0 + ' . ' + element1;
|
||||
return [code, Blockly.PHP.ORDER_ADDITION];
|
||||
} else {
|
||||
code = new Array(block.itemCount_);
|
||||
for (var n = 0; n < block.itemCount_; n++) {
|
||||
code[n] = Blockly.PHP.valueToCode(block, 'ADD' + n,
|
||||
var elements = new Array(block.itemCount_);
|
||||
for (var i = 0; i < block.itemCount_; i++) {
|
||||
elements[i] = Blockly.PHP.valueToCode(block, 'ADD' + i,
|
||||
Blockly.PHP.ORDER_COMMA) || '\'\'';
|
||||
}
|
||||
code = 'implode(\'\', array(' + code.join(',') + '))';
|
||||
var code = 'implode(\'\', array(' + elements.join(',') + '))';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
};
|
||||
@@ -67,87 +66,87 @@ Blockly.PHP['text_append'] = function(block) {
|
||||
// Append to a variable in place.
|
||||
var varName = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
return varName + ' .= ' + argument0 + ';\n';
|
||||
var value = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
Blockly.PHP.ORDER_ASSIGNMENT) || '\'\'';
|
||||
return varName + ' .= ' + value + ';\n';
|
||||
};
|
||||
|
||||
Blockly.PHP['text_length'] = function(block) {
|
||||
// String or array length.
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'length',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {',
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {',
|
||||
' if (is_string($value)) {',
|
||||
' return strlen($value);',
|
||||
' } else {',
|
||||
' return count($value);',
|
||||
' }',
|
||||
'}']);
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
return [functionName + '(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
var text = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
return [functionName + '(' + text + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.PHP['text_isEmpty'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
return ['empty(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
var text = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
return ['empty(' + text + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.PHP['text_indexOf'] = function(block) {
|
||||
// Search the text for a substring.
|
||||
var operator = block.getFieldValue('END') == 'FIRST' ?
|
||||
'strpos' : 'strrpos';
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'FIND',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
var argument1 = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
|
||||
var substring = Blockly.PHP.valueToCode(block, 'FIND',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
var text = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
if (Blockly.PHP.ONE_BASED_INDEXING) {
|
||||
var errorIndex = ' 0';
|
||||
var indexAdjustment = ' + 1';
|
||||
} else {
|
||||
var errorIndex = ' -1';
|
||||
var indexAdjustment = '';
|
||||
}
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
block.getFieldValue('END') == 'FIRST' ?
|
||||
'text_indexOf' : 'text_lastIndexOf',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($text, $search) {',
|
||||
' $pos = ' + operator + '($text, $search);',
|
||||
' return $pos === false ? 0 : $pos + 1;',
|
||||
' return $pos === false ? ' + errorIndex + ' : $pos' +
|
||||
indexAdjustment + ';',
|
||||
'}']);
|
||||
var code = functionName + '(' + argument1 + ', ' + argument0 + ')';
|
||||
var code = functionName + '(' + text + ', ' + substring + ')';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.PHP['text_charAt'] = function(block) {
|
||||
// Get letter at index.
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.PHP.valueToCode(block, 'AT',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '0';
|
||||
var text = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
var textOrder = (where == 'RANDOM') ? Blockly.PHP.ORDER_NONE :
|
||||
Blockly.PHP.ORDER_COMMA;
|
||||
var text = Blockly.PHP.valueToCode(block, 'VALUE', textOrder) || '\'\'';
|
||||
switch (where) {
|
||||
case 'FIRST':
|
||||
var code = text + '[0]';
|
||||
var code = 'substr(' + text + ', 0, 1)';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
case 'LAST':
|
||||
var code = 'substr(' + text + ', -1, 1)';
|
||||
var code = 'substr(' + text + ', -1)';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
case 'FROM_START':
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseFloat(at) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at += ' - 1';
|
||||
}
|
||||
var at = Blockly.PHP.getAdjusted(block, 'AT');
|
||||
var code = 'substr(' + text + ', ' + at + ', 1)';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
case 'FROM_END':
|
||||
var code = 'substr(' + text + ', -' + at + ', 1)';
|
||||
var at = Blockly.PHP.getAdjusted(block, 'AT', 1, true);
|
||||
var code = 'substr(' + text + ', ' + at + ', 1)';
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
case 'RANDOM':
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'text_random_letter',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($text) {',
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($text) {',
|
||||
' return $text[rand(0, strlen($text) - 1)];',
|
||||
'}']);
|
||||
code = functionName + '(' + text + ')';
|
||||
@@ -162,36 +161,33 @@ Blockly.PHP['text_getSubstring'] = function(block) {
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at1 = Blockly.PHP.valueToCode(block, 'AT1',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '0';
|
||||
var at2 = Blockly.PHP.valueToCode(block, 'AT2',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '0';
|
||||
if (where1 == 'FIRST' && where2 == 'LAST') {
|
||||
var code = text;
|
||||
} else {
|
||||
var at1 = Blockly.PHP.getAdjusted(block, 'AT1');
|
||||
var at2 = Blockly.PHP.getAdjusted(block, 'AT2');
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'text_get_substring',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'($text, $where1, $at1, $where2, $at2) {',
|
||||
' if ($where2 == \'FROM_START\') {',
|
||||
' $at2--;',
|
||||
' } else if ($where2 == \'FROM_END\') {',
|
||||
' $at2 = $at2 - $at1;',
|
||||
' } else if ($where2 == \'FIRST\') {',
|
||||
' $at2 = 0;',
|
||||
' } else if ($where2 == \'LAST\') {',
|
||||
' $at2 = strlen($text);',
|
||||
' } else { $at2 = 0; }',
|
||||
' if ($where1 == \'FROM_START\') {',
|
||||
' $at1--;',
|
||||
' } else if ($where1 == \'FROM_END\') {',
|
||||
' $at1 = strlen($text) - $at1;',
|
||||
' if ($where1 == \'FROM_END\') {',
|
||||
' $at1 = strlen($text) - 1 - $at1;',
|
||||
' } else if ($where1 == \'FIRST\') {',
|
||||
' $at1 = 0;',
|
||||
' } else if ($where1 == \'LAST\') {',
|
||||
' $at1 = strlen($text) - 1;',
|
||||
' } else { $at1 = 0; }',
|
||||
' return substr($text, $at1, $at2);',
|
||||
' } else if ($where1 != \'FROM_START\'){',
|
||||
' throw new Exception(\'Unhandled option (text_get_substring).\');',
|
||||
' }',
|
||||
' $length = 0;',
|
||||
' if ($where2 == \'FROM_START\') {',
|
||||
' $length = $at2 - $at1 + 1;',
|
||||
' } else if ($where2 == \'FROM_END\') {',
|
||||
' $length = strlen($text) - $at1 - $at2;',
|
||||
' } else if ($where2 == \'LAST\') {',
|
||||
' $length = strlen($text) - $at1;',
|
||||
' } else {',
|
||||
' throw new Exception(\'Unhandled option (text_get_substring).\');',
|
||||
' }',
|
||||
' return substr($text, $at1, $length);',
|
||||
'}']);
|
||||
var code = functionName + '(' + text + ', \'' +
|
||||
where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
|
||||
@@ -201,19 +197,14 @@ Blockly.PHP['text_getSubstring'] = function(block) {
|
||||
|
||||
Blockly.PHP['text_changeCase'] = function(block) {
|
||||
// Change capitalization.
|
||||
var code;
|
||||
var text = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
if (block.getFieldValue('CASE') == 'UPPERCASE') {
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
code = 'strtoupper(' + argument0 + ')';
|
||||
var code = 'strtoupper(' + text + ')';
|
||||
} else if (block.getFieldValue('CASE') == 'LOWERCASE') {
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
code = 'strtolower(' + argument0 + ')';
|
||||
var code = 'strtolower(' + text + ')';
|
||||
} else if (block.getFieldValue('CASE') == 'TITLECASE') {
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
|
||||
code = 'ucwords(strtolower(' + argument0 + '))';
|
||||
var code = 'ucwords(strtolower(' + text + '))';
|
||||
}
|
||||
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
@@ -226,16 +217,16 @@ Blockly.PHP['text_trim'] = function(block) {
|
||||
'BOTH': 'trim'
|
||||
};
|
||||
var operator = OPERATORS[block.getFieldValue('MODE')];
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
var text = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
return [ operator + '(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
return [operator + '(' + text + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.PHP['text_print'] = function(block) {
|
||||
// Print statement.
|
||||
var argument0 = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
var msg = Blockly.PHP.valueToCode(block, 'TEXT',
|
||||
Blockly.PHP.ORDER_NONE) || '\'\'';
|
||||
return 'print(' + argument0 + ');\n';
|
||||
return 'print(' + msg + ');\n';
|
||||
};
|
||||
|
||||
Blockly.PHP['text_prompt_ext'] = function(block) {
|
||||
|
||||
@@ -46,11 +46,22 @@ Blockly.Python.addReservedWords(
|
||||
// import keyword
|
||||
// print ','.join(keyword.kwlist)
|
||||
// http://docs.python.org/reference/lexical_analysis.html#keywords
|
||||
'and,as,assert,break,class,continue,def,del,elif,else,except,exec,finally,for,from,global,if,import,in,is,lambda,not,or,pass,print,raise,return,try,while,with,yield,' +
|
||||
'and,as,assert,break,class,continue,def,del,elif,else,except,exec,' +
|
||||
'finally,for,from,global,if,import,in,is,lambda,not,or,pass,print,raise,' +
|
||||
'return,try,while,with,yield,' +
|
||||
//http://docs.python.org/library/constants.html
|
||||
'True,False,None,NotImplemented,Ellipsis,__debug__,quit,exit,copyright,license,credits,' +
|
||||
'True,False,None,NotImplemented,Ellipsis,__debug__,quit,exit,copyright,' +
|
||||
'license,credits,' +
|
||||
// http://docs.python.org/library/functions.html
|
||||
'abs,divmod,input,open,staticmethod,all,enumerate,int,ord,str,any,eval,isinstance,pow,sum,basestring,execfile,issubclass,print,super,bin,file,iter,property,tuple,bool,filter,len,range,type,bytearray,float,list,raw_input,unichr,callable,format,locals,reduce,unicode,chr,frozenset,long,reload,vars,classmethod,getattr,map,repr,xrange,cmp,globals,max,reversed,zip,compile,hasattr,memoryview,round,__import__,complex,hash,min,set,apply,delattr,help,next,setattr,buffer,dict,hex,object,slice,coerce,dir,id,oct,sorted,intern');
|
||||
'abs,divmod,input,open,staticmethod,all,enumerate,int,ord,str,any,eval,' +
|
||||
'isinstance,pow,sum,basestring,execfile,issubclass,print,super,bin,file,' +
|
||||
'iter,property,tuple,bool,filter,len,range,type,bytearray,float,list,' +
|
||||
'raw_input,unichr,callable,format,locals,reduce,unicode,chr,frozenset,' +
|
||||
'long,reload,vars,classmethod,getattr,map,repr,xrange,cmp,globals,max,' +
|
||||
'reversed,zip,compile,hasattr,memoryview,round,__import__,complex,hash,' +
|
||||
'min,set,apply,delattr,help,next,setattr,buffer,dict,hex,object,slice,' +
|
||||
'coerce,dir,id,oct,sorted,intern'
|
||||
);
|
||||
|
||||
/**
|
||||
* Order of operation ENUMs.
|
||||
@@ -79,6 +90,12 @@ Blockly.Python.ORDER_CONDITIONAL = 15; // if else
|
||||
Blockly.Python.ORDER_LAMBDA = 16; // lambda
|
||||
Blockly.Python.ORDER_NONE = 99; // (...)
|
||||
|
||||
/**
|
||||
* Allow for switching between one and zero based indexing for lists and text,
|
||||
* one based by default.
|
||||
*/
|
||||
Blockly.Python.ONE_BASED_INDEXING = true;
|
||||
|
||||
/**
|
||||
* List of outer-inner pairings that do NOT require parentheses.
|
||||
* @type {!Array.<!Array.<number>>}
|
||||
@@ -213,9 +230,9 @@ Blockly.Python.scrub_ = function(block, code) {
|
||||
}
|
||||
// Collect comments for all value arguments.
|
||||
// Don't collect comments for nested statements.
|
||||
for (var x = 0; x < block.inputList.length; x++) {
|
||||
if (block.inputList[x].type == Blockly.INPUT_VALUE) {
|
||||
var childBlock = block.inputList[x].connection.targetBlock();
|
||||
for (var i = 0; i < block.inputList.length; i++) {
|
||||
if (block.inputList[i].type == Blockly.INPUT_VALUE) {
|
||||
var childBlock = block.inputList[i].connection.targetBlock();
|
||||
if (childBlock) {
|
||||
var comment = Blockly.Python.allNestedComments(childBlock);
|
||||
if (comment) {
|
||||
@@ -229,3 +246,45 @@ Blockly.Python.scrub_ = function(block, code) {
|
||||
var nextCode = Blockly.Python.blockToCode(nextBlock);
|
||||
return commentCode + code + nextCode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a property and adjusts the value, taking into account indexing, and
|
||||
* casts to an integer.
|
||||
* @param {!Blockly.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) {
|
||||
var delta = opt_delta || 0;
|
||||
if (Blockly.Python.ONE_BASED_INDEXING) {
|
||||
delta--;
|
||||
}
|
||||
var defaultAtIndex = Blockly.Python.ONE_BASED_INDEXING ? '1' : '0';
|
||||
var atOrder = delta ? Blockly.Python.ORDER_ADDITIVE :
|
||||
Blockly.Python.ORDER_NONE;
|
||||
var at = Blockly.Python.valueToCode(block, atId, atOrder) || defaultAtIndex;
|
||||
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, adjust it right now.
|
||||
at = parseInt(at, 10) + delta;
|
||||
if (opt_negate) {
|
||||
at = -at;
|
||||
}
|
||||
} else {
|
||||
// If the index is dynamic, adjust it in code.
|
||||
if (delta > 0) {
|
||||
at = 'int(' + at + ' + ' + delta + ')';
|
||||
} else if (delta < 0) {
|
||||
at = 'int(' + at + ' - ' + -delta + ')';
|
||||
} else {
|
||||
at = 'int(' + at + ')';
|
||||
}
|
||||
if (opt_negate) {
|
||||
at = '-' + at;
|
||||
}
|
||||
}
|
||||
return at;
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ Blockly.Python['colour_rgb'] = function(block) {
|
||||
// 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):',
|
||||
['def ' + Blockly.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)',
|
||||
|
||||
@@ -36,66 +36,75 @@ Blockly.Python['lists_create_empty'] = function(block) {
|
||||
|
||||
Blockly.Python['lists_create_with'] = function(block) {
|
||||
// Create a list with any number of elements of any type.
|
||||
var code = new Array(block.itemCount_);
|
||||
for (var n = 0; n < block.itemCount_; n++) {
|
||||
code[n] = Blockly.Python.valueToCode(block, 'ADD' + n,
|
||||
var elements = new Array(block.itemCount_);
|
||||
for (var i = 0; i < block.itemCount_; i++) {
|
||||
elements[i] = Blockly.Python.valueToCode(block, 'ADD' + i,
|
||||
Blockly.Python.ORDER_NONE) || 'None';
|
||||
}
|
||||
code = '[' + code.join(', ') + ']';
|
||||
var code = '[' + elements.join(', ') + ']';
|
||||
return [code, Blockly.Python.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
Blockly.Python['lists_repeat'] = function(block) {
|
||||
// Create a list with one element repeated.
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'ITEM',
|
||||
var item = Blockly.Python.valueToCode(block, 'ITEM',
|
||||
Blockly.Python.ORDER_NONE) || 'None';
|
||||
var argument1 = Blockly.Python.valueToCode(block, 'NUM',
|
||||
var times = Blockly.Python.valueToCode(block, 'NUM',
|
||||
Blockly.Python.ORDER_MULTIPLICATIVE) || '0';
|
||||
var code = '[' + argument0 + '] * ' + argument1;
|
||||
var code = '[' + item + '] * ' + times;
|
||||
return [code, Blockly.Python.ORDER_MULTIPLICATIVE];
|
||||
};
|
||||
|
||||
Blockly.Python['lists_length'] = function(block) {
|
||||
// String or array length.
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
var list = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
Blockly.Python.ORDER_NONE) || '[]';
|
||||
return ['len(' + argument0 + ')', Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
return ['len(' + list + ')', Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.Python['lists_isEmpty'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
var list = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
Blockly.Python.ORDER_NONE) || '[]';
|
||||
var code = 'not len(' + argument0 + ')';
|
||||
var code = 'not len(' + list + ')';
|
||||
return [code, Blockly.Python.ORDER_LOGICAL_NOT];
|
||||
};
|
||||
|
||||
Blockly.Python['lists_indexOf'] = function(block) {
|
||||
// Find an item in the list.
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'FIND',
|
||||
var item = Blockly.Python.valueToCode(block, 'FIND',
|
||||
Blockly.Python.ORDER_NONE) || '[]';
|
||||
var argument1 = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
Blockly.Python.ORDER_MEMBER) || '\'\'';
|
||||
var code;
|
||||
var list = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
Blockly.Python.ORDER_NONE) || '\'\'';
|
||||
if (Blockly.Python.ONE_BASED_INDEXING) {
|
||||
var errorIndex = ' 0';
|
||||
var firstIndexAdjustment = ' + 1';
|
||||
var lastIndexAdjustment = '';
|
||||
} else {
|
||||
var errorIndex = ' -1';
|
||||
var firstIndexAdjustment = '';
|
||||
var lastIndexAdjustment = ' - 1';
|
||||
}
|
||||
if (block.getFieldValue('END') == 'FIRST') {
|
||||
var functionName = Blockly.Python.provideFunction_(
|
||||
'first_index',
|
||||
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList, elem):',
|
||||
' try: theIndex = myList.index(elem) + 1',
|
||||
' except: theIndex = 0',
|
||||
' return theIndex']);
|
||||
code = functionName + '(' + argument1 + ', ' + argument0 + ')';
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
} else {
|
||||
var functionName = Blockly.Python.provideFunction_(
|
||||
'last_index',
|
||||
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList, elem):',
|
||||
' try: theIndex = len(myList) - myList[::-1].index(elem)',
|
||||
' except: theIndex = 0',
|
||||
' return theIndex']);
|
||||
code = functionName + '(' + argument1 + ', ' + argument0 + ')';
|
||||
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(my_list, elem):',
|
||||
' try: index = my_list.index(elem)' + firstIndexAdjustment,
|
||||
' except: index =' + errorIndex,
|
||||
' return index']);
|
||||
var code = functionName + '(' + list + ', ' + item + ')';
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
var functionName = Blockly.Python.provideFunction_(
|
||||
'last_index',
|
||||
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(my_list, elem):',
|
||||
' try: index = len(my_list) - my_list[::-1].index(elem)' +
|
||||
lastIndexAdjustment,
|
||||
' except: index =' + errorIndex,
|
||||
' return index']);
|
||||
var code = functionName + '(' + list + ', ' + item + ')';
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.Python['lists_getIndex'] = function(block) {
|
||||
@@ -103,68 +112,58 @@ Blockly.Python['lists_getIndex'] = function(block) {
|
||||
// Note: Until January 2013 this block did not have MODE or WHERE inputs.
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.Python.valueToCode(block, 'AT',
|
||||
Blockly.Python.ORDER_UNARY_SIGN) || '1';
|
||||
var list = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
Blockly.Python.ORDER_MEMBER) || '[]';
|
||||
var listOrder = (where == 'RANDOM') ? Blockly.Python.ORDER_NONE :
|
||||
Blockly.Python.ORDER_MEMBER;
|
||||
var list = Blockly.Python.valueToCode(block, 'VALUE', listOrder) || '[]';
|
||||
|
||||
if (where == 'FIRST') {
|
||||
switch (where) {
|
||||
case 'FIRST':
|
||||
if (mode == 'GET') {
|
||||
var code = list + '[0]';
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
} else {
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var code = list + '.pop(0)';
|
||||
if (mode == 'GET_REMOVE') {
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
return code + '\n';
|
||||
return list + '.pop(0)\n';
|
||||
}
|
||||
}
|
||||
} else if (where == 'LAST') {
|
||||
break;
|
||||
case 'LAST':
|
||||
if (mode == 'GET') {
|
||||
var code = list + '[-1]';
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
} else {
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var code = list + '.pop()';
|
||||
if (mode == 'GET_REMOVE') {
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
return code + '\n';
|
||||
}
|
||||
}
|
||||
} else if (where == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseInt(at, 10) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at = 'int(' + at + ' - 1)';
|
||||
return list + '.pop()\n';
|
||||
}
|
||||
break;
|
||||
case 'FROM_START':
|
||||
var at = Blockly.Python.getAdjustedInt(block, 'AT');
|
||||
if (mode == 'GET') {
|
||||
var code = list + '[' + at + ']';
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
} else {
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var code = list + '.pop(' + at + ')';
|
||||
if (mode == 'GET_REMOVE') {
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
return code + '\n';
|
||||
return list + '.pop(' + at + ')\n';
|
||||
}
|
||||
}
|
||||
} else if (where == 'FROM_END') {
|
||||
break;
|
||||
case'FROM_END':
|
||||
var at = Blockly.Python.getAdjustedInt(block, 'AT', 1, true);
|
||||
if (mode == 'GET') {
|
||||
var code = list + '[-' + at + ']';
|
||||
var code = list + '[' + at + ']';
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
} else {
|
||||
var code = list + '.pop(-' + at + ')';
|
||||
if (mode == 'GET_REMOVE') {
|
||||
} else if (mode == 'GET_REMOVE') {
|
||||
var code = list + '.pop(' + at + ')';
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
} else if (mode == 'REMOVE') {
|
||||
return code + '\n';
|
||||
return list + '.pop(' + at + ')\n';
|
||||
}
|
||||
}
|
||||
} else if (where == 'RANDOM') {
|
||||
break;
|
||||
case 'RANDOM':
|
||||
Blockly.Python.definitions_['import_random'] = 'import random';
|
||||
if (mode == 'GET') {
|
||||
code = 'random.choice(' + list + ')';
|
||||
@@ -182,6 +181,7 @@ Blockly.Python['lists_getIndex'] = function(block) {
|
||||
return code + '\n';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw 'Unhandled combination (lists_getIndex).';
|
||||
};
|
||||
@@ -193,8 +193,6 @@ Blockly.Python['lists_setIndex'] = function(block) {
|
||||
Blockly.Python.ORDER_MEMBER) || '[]';
|
||||
var mode = block.getFieldValue('MODE') || 'GET';
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.Python.valueToCode(block, 'AT',
|
||||
Blockly.Python.ORDER_NONE) || '1';
|
||||
var value = Blockly.Python.valueToCode(block, 'TO',
|
||||
Blockly.Python.ORDER_NONE) || 'None';
|
||||
// Cache non-trivial values to variables to prevent repeated look-ups.
|
||||
@@ -209,39 +207,39 @@ Blockly.Python['lists_setIndex'] = function(block) {
|
||||
list = listVar;
|
||||
return code;
|
||||
}
|
||||
if (where == 'FIRST') {
|
||||
|
||||
switch (where) {
|
||||
case 'FIRST':
|
||||
if (mode == 'SET') {
|
||||
return list + '[0] = ' + value + '\n';
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + '.insert(0, ' + value + ')\n';
|
||||
}
|
||||
} else if (where == 'LAST') {
|
||||
break;
|
||||
case 'LAST':
|
||||
if (mode == 'SET') {
|
||||
return list + '[-1] = ' + value + '\n';
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + '.append(' + value + ')\n';
|
||||
}
|
||||
} else if (where == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseInt(at, 10) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at = 'int(' + at + ' - 1)';
|
||||
}
|
||||
break;
|
||||
case 'FROM_START':
|
||||
var at = Blockly.Python.getAdjustedInt(block, 'AT');
|
||||
if (mode == 'SET') {
|
||||
return list + '[' + at + '] = ' + value + '\n';
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + '.insert(' + at + ', ' + value + ')\n';
|
||||
}
|
||||
} else if (where == 'FROM_END') {
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at = Blockly.Python.getAdjustedInt(block, 'AT', 1, true);
|
||||
if (mode == 'SET') {
|
||||
return list + '[-' + at + '] = ' + value + '\n';
|
||||
return list + '[' + at + '] = ' + value + '\n';
|
||||
} else if (mode == 'INSERT') {
|
||||
return list + '.insert(-' + at + ', ' + value + ')\n';
|
||||
return list + '.insert(' + at + ', ' + value + ')\n';
|
||||
}
|
||||
} else if (where == 'RANDOM') {
|
||||
break;
|
||||
case 'RANDOM':
|
||||
Blockly.Python.definitions_['import_random'] = 'import random';
|
||||
var code = cacheList();
|
||||
var xVar = Blockly.Python.variableDB_.getDistinctName(
|
||||
@@ -254,6 +252,7 @@ Blockly.Python['lists_setIndex'] = function(block) {
|
||||
code += list + '.insert(' + xVar + ', ' + value + ')\n';
|
||||
return code;
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw 'Unhandled combination (lists_setIndex).';
|
||||
};
|
||||
@@ -264,49 +263,42 @@ Blockly.Python['lists_getSublist'] = function(block) {
|
||||
Blockly.Python.ORDER_MEMBER) || '[]';
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at1 = Blockly.Python.valueToCode(block, 'AT1',
|
||||
Blockly.Python.ORDER_ADDITIVE) || '1';
|
||||
var at2 = Blockly.Python.valueToCode(block, 'AT2',
|
||||
Blockly.Python.ORDER_ADDITIVE) || '1';
|
||||
if (where1 == 'FIRST' || (where1 == 'FROM_START' && at1 == '1')) {
|
||||
switch (where1) {
|
||||
case 'FROM_START':
|
||||
var at1 = Blockly.Python.getAdjustedInt(block, 'AT1');
|
||||
if (at1 == '0') {
|
||||
at1 = '';
|
||||
} else if (where1 == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at1)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at1 = parseInt(at1, 10) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at1 = 'int(' + at1 + ' - 1)';
|
||||
}
|
||||
} else if (where1 == 'FROM_END') {
|
||||
if (Blockly.isNumber(at1)) {
|
||||
at1 = -parseInt(at1, 10);
|
||||
} else {
|
||||
at1 = '-int(' + at1 + ')';
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at1 = Blockly.Python.getAdjustedInt(block, 'AT1', 1, true);
|
||||
break;
|
||||
case 'FIRST':
|
||||
var at1 = '';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (lists_getSublist)';
|
||||
}
|
||||
}
|
||||
if (where2 == 'LAST' || (where2 == 'FROM_END' && at2 == '1')) {
|
||||
at2 = '';
|
||||
} else if (where1 == 'FROM_START') {
|
||||
if (Blockly.isNumber(at2)) {
|
||||
at2 = parseInt(at2, 10);
|
||||
} else {
|
||||
at2 = 'int(' + at2 + ')';
|
||||
}
|
||||
} else if (where1 == 'FROM_END') {
|
||||
if (Blockly.isNumber(at2)) {
|
||||
// If the index is a naked number, increment it right now.
|
||||
// Add special case for -0.
|
||||
at2 = 1 - parseInt(at2, 10);
|
||||
if (at2 == 0) {
|
||||
at2 = '';
|
||||
}
|
||||
} else {
|
||||
// If the index is dynamic, increment it in code.
|
||||
switch (where2) {
|
||||
case 'FROM_START':
|
||||
var at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 1);
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at2 = Blockly.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';
|
||||
at2 = 'int(1 - ' + at2 + ') or sys.maxsize';
|
||||
at2 += ' or sys.maxsize';
|
||||
} else if (at2 == '0') {
|
||||
at2 = '';
|
||||
}
|
||||
break;
|
||||
case 'LAST':
|
||||
var at2 = '';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (lists_getSublist)';
|
||||
}
|
||||
var code = list + '[' + at1 + ' : ' + at2 + ']';
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
@@ -314,30 +306,30 @@ Blockly.Python['lists_getSublist'] = function(block) {
|
||||
|
||||
Blockly.Python['lists_sort'] = function(block) {
|
||||
// Block for sorting a list.
|
||||
var listCode = (Blockly.Python.valueToCode(block, 'LIST',
|
||||
Blockly.Python.ORDER_MEMBER) || '[]');
|
||||
var list = (Blockly.Python.valueToCode(block, 'LIST',
|
||||
Blockly.Python.ORDER_NONE) || '[]');
|
||||
var type = block.getFieldValue('TYPE');
|
||||
var reverse = block.getFieldValue('DIRECTION') === '1' ? 'False' : 'True';
|
||||
var sortFunctionName = Blockly.Python.provideFunction_('lists_sort',
|
||||
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
'(listv, type, reversev):',
|
||||
' def tryfloat(s):',
|
||||
'(my_list, type, reverse):',
|
||||
' def try_float(s):',
|
||||
' try:',
|
||||
' return float(s)',
|
||||
' except:',
|
||||
' return 0',
|
||||
' keyFuncts = {',
|
||||
' "NUMERIC": tryfloat,',
|
||||
' key_funcs = {',
|
||||
' "NUMERIC": try_float,',
|
||||
' "TEXT": str,',
|
||||
' "IGNORE_CASE": lambda s: str(s).lower()',
|
||||
' }',
|
||||
' keyv = keyFuncts[type]',
|
||||
' tmp_list = list(listv)', // Clone the list.
|
||||
' return sorted(tmp_list, key=keyv, reverse=reversev)'
|
||||
' key_func = key_funcs[type]',
|
||||
' list_cpy = list(my_list)', // Clone the list.
|
||||
' return sorted(list_cpy, key=key_func, reverse=reverse)'
|
||||
]);
|
||||
|
||||
var code = sortFunctionName +
|
||||
'(' + listCode + ', "' + type + '", ' + reverse + ')';
|
||||
'(' + list + ', "' + type + '", ' + reverse + ')';
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ Blockly.Python['procedures_defreturn'] = function(block) {
|
||||
branch = Blockly.Python.PASS;
|
||||
}
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.Python.variableDB_.getName(block.arguments_[x],
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.Python.variableDB_.getName(block.arguments_[i],
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
}
|
||||
var code = 'def ' + funcName + '(' + args.join(', ') + '):\n' +
|
||||
@@ -87,8 +87,8 @@ Blockly.Python['procedures_callreturn'] = function(block) {
|
||||
var funcName = Blockly.Python.variableDB_.getName(block.getFieldValue('NAME'),
|
||||
Blockly.Procedures.NAME_TYPE);
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.Python.valueToCode(block, 'ARG' + x,
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.Python.valueToCode(block, 'ARG' + i,
|
||||
Blockly.Python.ORDER_NONE) || 'None';
|
||||
}
|
||||
var code = funcName + '(' + args.join(', ') + ')';
|
||||
@@ -100,8 +100,8 @@ Blockly.Python['procedures_callnoreturn'] = function(block) {
|
||||
var funcName = Blockly.Python.variableDB_.getName(block.getFieldValue('NAME'),
|
||||
Blockly.Procedures.NAME_TYPE);
|
||||
var args = [];
|
||||
for (var x = 0; x < block.arguments_.length; x++) {
|
||||
args[x] = Blockly.Python.valueToCode(block, 'ARG' + x,
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
args[i] = Blockly.Python.valueToCode(block, 'ARG' + i,
|
||||
Blockly.Python.ORDER_NONE) || 'None';
|
||||
}
|
||||
var code = funcName + '(' + args.join(', ') + ')\n';
|
||||
|
||||
@@ -38,31 +38,34 @@ Blockly.Python['text'] = function(block) {
|
||||
Blockly.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?
|
||||
var code;
|
||||
if (block.itemCount_ == 0) {
|
||||
switch (block.itemCount_) {
|
||||
case 0:
|
||||
return ['\'\'', Blockly.Python.ORDER_ATOMIC];
|
||||
} else if (block.itemCount_ == 1) {
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'ADD0',
|
||||
break;
|
||||
case 1:
|
||||
var element = Blockly.Python.valueToCode(block, 'ADD0',
|
||||
Blockly.Python.ORDER_NONE) || '\'\'';
|
||||
code = 'str(' + argument0 + ')';
|
||||
var code = 'str(' + element + ')';
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
} else if (block.itemCount_ == 2) {
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'ADD0',
|
||||
break;
|
||||
case 2:
|
||||
var element0 = Blockly.Python.valueToCode(block, 'ADD0',
|
||||
Blockly.Python.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.Python.valueToCode(block, 'ADD1',
|
||||
var element1 = Blockly.Python.valueToCode(block, 'ADD1',
|
||||
Blockly.Python.ORDER_NONE) || '\'\'';
|
||||
var code = 'str(' + argument0 + ') + str(' + argument1 + ')';
|
||||
return [code, Blockly.Python.ORDER_UNARY_SIGN];
|
||||
} else {
|
||||
var code = [];
|
||||
for (var n = 0; n < block.itemCount_; n++) {
|
||||
code[n] = Blockly.Python.valueToCode(block, 'ADD' + n,
|
||||
var code = 'str(' + element0 + ') + str(' + element1 + ')';
|
||||
return [code, Blockly.Python.ORDER_ADDITIVE];
|
||||
break;
|
||||
default:
|
||||
var elements = [];
|
||||
for (var i = 0; i < block.itemCount_; i++) {
|
||||
elements[i] = Blockly.Python.valueToCode(block, 'ADD' + i,
|
||||
Blockly.Python.ORDER_NONE) || '\'\'';
|
||||
}
|
||||
var tempVar = Blockly.Python.variableDB_.getDistinctName('temp_value',
|
||||
var tempVar = Blockly.Python.variableDB_.getDistinctName('x',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
code = '\'\'.join([str(' + tempVar + ') for ' + tempVar + ' in [' +
|
||||
code.join(', ') + ']])';
|
||||
var code = '\'\'.join([str(' + tempVar + ') for ' + tempVar + ' in [' +
|
||||
elements.join(', ') + ']])';
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
};
|
||||
@@ -71,23 +74,23 @@ Blockly.Python['text_append'] = function(block) {
|
||||
// Append to a variable in place.
|
||||
var varName = Blockly.Python.variableDB_.getName(block.getFieldValue('VAR'),
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'TEXT',
|
||||
var value = Blockly.Python.valueToCode(block, 'TEXT',
|
||||
Blockly.Python.ORDER_NONE) || '\'\'';
|
||||
return varName + ' = str(' + varName + ') + str(' + argument0 + ')\n';
|
||||
return varName + ' = str(' + varName + ') + str(' + value + ')\n';
|
||||
};
|
||||
|
||||
Blockly.Python['text_length'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
var text = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
Blockly.Python.ORDER_NONE) || '\'\'';
|
||||
return ['len(' + argument0 + ')', Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
return ['len(' + text + ')', Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.Python['text_isEmpty'] = function(block) {
|
||||
// Is the string null or array empty?
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
var text = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
Blockly.Python.ORDER_NONE) || '\'\'';
|
||||
var code = 'not len(' + argument0 + ')';
|
||||
var code = 'not len(' + text + ')';
|
||||
return [code, Blockly.Python.ORDER_LOGICAL_NOT];
|
||||
};
|
||||
|
||||
@@ -95,20 +98,21 @@ Blockly.Python['text_indexOf'] = function(block) {
|
||||
// Search the text for a substring.
|
||||
// Should we allow for non-case sensitive???
|
||||
var operator = block.getFieldValue('END') == 'FIRST' ? 'find' : 'rfind';
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'FIND',
|
||||
var substring = Blockly.Python.valueToCode(block, 'FIND',
|
||||
Blockly.Python.ORDER_NONE) || '\'\'';
|
||||
var argument1 = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
var text = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
Blockly.Python.ORDER_MEMBER) || '\'\'';
|
||||
var code = argument1 + '.' + operator + '(' + argument0 + ') + 1';
|
||||
return [code, Blockly.Python.ORDER_ADDITIVE];
|
||||
var code = text + '.' + operator + '(' + substring + ')';
|
||||
if (Blockly.Python.ONE_BASED_INDEXING) {
|
||||
return [code + ' + 1', Blockly.Python.ORDER_ADDITIVE];
|
||||
}
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.Python['text_charAt'] = function(block) {
|
||||
// Get letter at index.
|
||||
// Note: Until January 2013 this block did not have the WHERE input.
|
||||
var where = block.getFieldValue('WHERE') || 'FROM_START';
|
||||
var at = Blockly.Python.valueToCode(block, 'AT',
|
||||
Blockly.Python.ORDER_UNARY_SIGN) || '1';
|
||||
var text = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
Blockly.Python.ORDER_MEMBER) || '\'\'';
|
||||
switch (where) {
|
||||
@@ -119,18 +123,12 @@ Blockly.Python['text_charAt'] = function(block) {
|
||||
var code = text + '[-1]';
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
case 'FROM_START':
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at = parseInt(at, 10) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at = 'int(' + at + ' - 1)';
|
||||
}
|
||||
var at = Blockly.Python.getAdjustedInt(block, 'AT');
|
||||
var code = text + '[' + at + ']';
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
case 'FROM_END':
|
||||
var code = text + '[-' + at + ']';
|
||||
var at = Blockly.Python.getAdjustedInt(block, 'AT', 1, true);
|
||||
var code = text + '[' + at + ']';
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
case 'RANDOM':
|
||||
Blockly.Python.definitions_['import_random'] = 'import random';
|
||||
@@ -147,53 +145,46 @@ Blockly.Python['text_charAt'] = function(block) {
|
||||
|
||||
Blockly.Python['text_getSubstring'] = function(block) {
|
||||
// Get substring.
|
||||
var text = Blockly.Python.valueToCode(block, 'STRING',
|
||||
Blockly.Python.ORDER_MEMBER) || '\'\'';
|
||||
var where1 = block.getFieldValue('WHERE1');
|
||||
var where2 = block.getFieldValue('WHERE2');
|
||||
var at1 = Blockly.Python.valueToCode(block, 'AT1',
|
||||
Blockly.Python.ORDER_ADDITIVE) || '1';
|
||||
var at2 = Blockly.Python.valueToCode(block, 'AT2',
|
||||
Blockly.Python.ORDER_ADDITIVE) || '1';
|
||||
if (where1 == 'FIRST' || (where1 == 'FROM_START' && at1 == '1')) {
|
||||
var text = Blockly.Python.valueToCode(block, 'STRING',
|
||||
Blockly.Python.ORDER_MEMBER) || '\'\'';
|
||||
switch (where1) {
|
||||
case 'FROM_START':
|
||||
var at1 = Blockly.Python.getAdjustedInt(block, 'AT1');
|
||||
if (at1 == '0') {
|
||||
at1 = '';
|
||||
} else if (where1 == 'FROM_START') {
|
||||
// Blockly uses one-based indicies.
|
||||
if (Blockly.isNumber(at1)) {
|
||||
// If the index is a naked number, decrement it right now.
|
||||
at1 = parseInt(at1, 10) - 1;
|
||||
} else {
|
||||
// If the index is dynamic, decrement it in code.
|
||||
at1 = 'int(' + at1 + ' - 1)';
|
||||
}
|
||||
} else if (where1 == 'FROM_END') {
|
||||
if (Blockly.isNumber(at1)) {
|
||||
at1 = -parseInt(at1, 10);
|
||||
} else {
|
||||
at1 = '-int(' + at1 + ')';
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at1 = Blockly.Python.getAdjustedInt(block, 'AT1', 1, true);
|
||||
break;
|
||||
case 'FIRST':
|
||||
var at1 = '';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (text_getSubstring)';
|
||||
}
|
||||
}
|
||||
if (where2 == 'LAST' || (where2 == 'FROM_END' && at2 == '1')) {
|
||||
at2 = '';
|
||||
} else if (where1 == 'FROM_START') {
|
||||
if (Blockly.isNumber(at2)) {
|
||||
at2 = parseInt(at2, 10);
|
||||
} else {
|
||||
at2 = 'int(' + at2 + ')';
|
||||
}
|
||||
} else if (where1 == 'FROM_END') {
|
||||
if (Blockly.isNumber(at2)) {
|
||||
// If the index is a naked number, increment it right now.
|
||||
at2 = 1 - parseInt(at2, 10);
|
||||
if (at2 == 0) {
|
||||
at2 = '';
|
||||
}
|
||||
} else {
|
||||
// If the index is dynamic, increment it in code.
|
||||
// Add special case for -0.
|
||||
switch (where2) {
|
||||
case 'FROM_START':
|
||||
var at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 1);
|
||||
break;
|
||||
case 'FROM_END':
|
||||
var at2 = Blockly.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';
|
||||
at2 = 'int(1 - ' + at2 + ') or sys.maxsize';
|
||||
at2 += ' or sys.maxsize';
|
||||
} else if (at2 == '0') {
|
||||
at2 = '';
|
||||
}
|
||||
break;
|
||||
case 'LAST':
|
||||
var at2 = '';
|
||||
break;
|
||||
default:
|
||||
throw 'Unhandled option (text_getSubstring)';
|
||||
}
|
||||
var code = text + '[' + at1 + ' : ' + at2 + ']';
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
@@ -207,10 +198,10 @@ Blockly.Python['text_changeCase'] = function(block) {
|
||||
'TITLECASE': '.title()'
|
||||
};
|
||||
var operator = OPERATORS[block.getFieldValue('CASE')];
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'TEXT',
|
||||
var text = Blockly.Python.valueToCode(block, 'TEXT',
|
||||
Blockly.Python.ORDER_MEMBER) || '\'\'';
|
||||
var code = argument0 + operator;
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
var code = text + operator;
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.Python['text_trim'] = function(block) {
|
||||
@@ -221,17 +212,17 @@ Blockly.Python['text_trim'] = function(block) {
|
||||
'BOTH': '.strip()'
|
||||
};
|
||||
var operator = OPERATORS[block.getFieldValue('MODE')];
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'TEXT',
|
||||
var text = Blockly.Python.valueToCode(block, 'TEXT',
|
||||
Blockly.Python.ORDER_MEMBER) || '\'\'';
|
||||
var code = argument0 + operator;
|
||||
return [code, Blockly.Python.ORDER_MEMBER];
|
||||
var code = text + operator;
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
};
|
||||
|
||||
Blockly.Python['text_print'] = function(block) {
|
||||
// Print statement.
|
||||
var argument0 = Blockly.Python.valueToCode(block, 'TEXT',
|
||||
var msg = Blockly.Python.valueToCode(block, 'TEXT',
|
||||
Blockly.Python.ORDER_NONE) || '\'\'';
|
||||
return 'print(' + argument0 + ')\n';
|
||||
return 'print(' + msg + ')\n';
|
||||
};
|
||||
|
||||
Blockly.Python['text_prompt_ext'] = function(block) {
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
<field name="NAME">test colour picker</field>
|
||||
<statement name="STACK">
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">static colour</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">static colour</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="colour_picker">
|
||||
<field name="COLOUR">#ff6600</field>
|
||||
@@ -21,7 +25,11 @@
|
||||
<field name="NAME">test rgb</field>
|
||||
<statement name="STACK">
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">from rgb</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">from rgb</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="colour_rgb" inline="false">
|
||||
<value name="RED">
|
||||
@@ -88,7 +96,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">test name</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">test name</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="text_length" inline="false">
|
||||
<value name="VALUE">
|
||||
@@ -105,7 +117,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">test name</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">test name</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="text_charAt">
|
||||
<mutation at="false"></mutation>
|
||||
@@ -137,7 +153,11 @@
|
||||
</value>
|
||||
<statement name="DO">
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">test name</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">test name</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -192,7 +212,11 @@
|
||||
<field name="NAME">test blend</field>
|
||||
<statement name="STACK">
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">blend</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">blend</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="colour_blend" inline="false">
|
||||
<value name="COLOUR1">
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
<mutation name="test function"></mutation>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">test recurse</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">test recurse</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="procedures_callreturn" inline="false">
|
||||
<mutation name="recurse">
|
||||
@@ -53,7 +57,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">procedure with global</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">procedure with global</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">proc z</field>
|
||||
@@ -84,7 +92,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">procedure no return</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">procedure no return</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
@@ -111,7 +123,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">procedure return</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">procedure return</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
@@ -192,7 +208,11 @@
|
||||
<field name="NAME">test function</field>
|
||||
<statement name="STACK">
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">function with arguments</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">function with arguments</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="procedures_callreturn" inline="false">
|
||||
<mutation name="function 1">
|
||||
@@ -218,7 +238,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">function with side effect</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">function with side effect</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">func z</field>
|
||||
@@ -247,7 +271,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">function with global</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">function with global</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="procedures_callreturn" inline="false">
|
||||
<mutation name="function 2">
|
||||
@@ -267,7 +295,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">function with scope</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">function with scope</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">func a</field>
|
||||
@@ -280,7 +312,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">function return</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">function return</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="procedures_callreturn" inline="false">
|
||||
@@ -296,7 +332,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">function no return</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">function no return</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="procedures_callreturn" inline="false">
|
||||
|
||||
@@ -153,17 +153,23 @@ function toXml() {
|
||||
}
|
||||
|
||||
function toJavaScript() {
|
||||
var oneBasedIndexing = document.getElementById('indexing').checked;
|
||||
Blockly.JavaScript.ONE_BASED_INDEXING = oneBasedIndexing;
|
||||
var code = '\'use strict\';\n\n'
|
||||
code += Blockly.JavaScript.workspaceToCode(workspace);
|
||||
setOutput(code);
|
||||
}
|
||||
|
||||
function toPython() {
|
||||
var oneBasedIndexing = document.getElementById('indexing').checked;
|
||||
Blockly.Python.ONE_BASED_INDEXING = oneBasedIndexing;
|
||||
var code = Blockly.Python.workspaceToCode(workspace);
|
||||
setOutput(code);
|
||||
}
|
||||
|
||||
function toPhp() {
|
||||
var oneBasedIndexing = document.getElementById('indexing').checked;
|
||||
Blockly.PHP.ONE_BASED_INDEXING = oneBasedIndexing;
|
||||
var code = Blockly.PHP.workspaceToCode(workspace);
|
||||
setOutput(code);
|
||||
}
|
||||
@@ -174,6 +180,8 @@ function toLua() {
|
||||
}
|
||||
|
||||
function toDart() {
|
||||
var oneBasedIndexing = document.getElementById('indexing').checked;
|
||||
Blockly.Dart.ONE_BASED_INDEXING = oneBasedIndexing;
|
||||
var code = Blockly.Dart.workspaceToCode(workspace);
|
||||
setOutput(code);
|
||||
}
|
||||
@@ -212,9 +220,22 @@ h1 {
|
||||
<xml id="toolbox" style="display: none">
|
||||
<category name="Unit test" colour="65">
|
||||
<block type="unittest_main"></block>
|
||||
<block type="unittest_assertequals"></block>
|
||||
<block type="unittest_assertvalue"></block>
|
||||
<block type="unittest_assertequals">
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT"></field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
<block type="unittest_assertvalue">
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT"></field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
<block type="unittest_fail"></block>
|
||||
<block type="unittest_adjustindex"></block>
|
||||
</category>
|
||||
<category name="Logic" colour="210">
|
||||
<block type="controls_if"></block>
|
||||
@@ -305,6 +326,10 @@ h1 {
|
||||
<input type="button" value="Load" onclick="loadXml()">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<input id="indexing" type="checkbox" checked> Generate with one-based indexing
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Generate:
|
||||
<input type="button" value="XML" onclick="toXml()">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,11 @@
|
||||
<block type="unittest_main" x="-4" y="-12">
|
||||
<statement name="DO">
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">True</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">True</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_boolean">
|
||||
@@ -11,7 +15,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">False</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">False</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_boolean">
|
||||
@@ -20,7 +28,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Not true</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Not true</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_negate" inline="false">
|
||||
@@ -33,7 +45,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Not false</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Not false</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_negate" inline="false">
|
||||
@@ -119,7 +135,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">if true</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">if true</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
@@ -159,7 +179,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">if/else false</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">if/else false</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
@@ -199,7 +223,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">if/else true</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">if/else true</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
@@ -259,7 +287,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">elseif 4</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">elseif 4</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
@@ -297,7 +329,11 @@
|
||||
<field name="NAME">test equalities</field>
|
||||
<statement name="STACK">
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Equal yes</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Equal yes</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -316,7 +352,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Equal no</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Equal no</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -335,7 +375,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Not equal yes</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Not equal yes</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -354,7 +398,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Not equal no</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Not equal no</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -373,7 +421,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Smaller yes</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Smaller yes</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -392,7 +444,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Smaller no</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Smaller no</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -411,7 +467,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Greater yes</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Greater yes</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -430,7 +490,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Greater no</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Greater no</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -449,7 +513,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Smaller-equal yes</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Smaller-equal yes</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -468,7 +536,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Smaller-equal no</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Smaller-equal no</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -487,7 +559,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Greater-equal yes</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Greater-equal yes</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -506,7 +582,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Greater-equal no</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Greater-equal no</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_compare">
|
||||
@@ -552,7 +632,11 @@
|
||||
<field name="NAME">test or</field>
|
||||
<statement name="STACK">
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Or true/true</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Or true/true</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_operation">
|
||||
@@ -571,7 +655,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Or false/true</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Or false/true</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_operation">
|
||||
@@ -590,7 +678,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Or true/false</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Or true/false</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_operation">
|
||||
@@ -609,7 +701,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">Or false/false</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">Or false/false</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_operation">
|
||||
@@ -639,7 +735,11 @@
|
||||
<field name="NAME">test and</field>
|
||||
<statement name="STACK">
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">And true/true</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">And true/true</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">TRUE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_operation">
|
||||
@@ -658,7 +758,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">And false/true</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">And false/true</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_operation">
|
||||
@@ -677,7 +781,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">And true/false</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">And true/false</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_operation">
|
||||
@@ -696,7 +804,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertvalue" inline="false">
|
||||
<field name="MESSAGE">And false/false</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">And false/false</field>
|
||||
</block>
|
||||
</value>
|
||||
<field name="EXPECTED">FALSE</field>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_operation">
|
||||
@@ -726,7 +838,11 @@
|
||||
<field name="NAME">test ternary</field>
|
||||
<statement name="STACK">
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">if true</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">if true</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_ternary" inline="true">
|
||||
<value name="IF">
|
||||
@@ -753,7 +869,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">if true</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">if true</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="logic_ternary" inline="true">
|
||||
<value name="IF">
|
||||
|
||||
@@ -62,7 +62,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">for loop</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">for loop</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
@@ -147,7 +151,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">while 10</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">while 10</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">count</field>
|
||||
@@ -196,7 +204,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">until 10</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">until 10</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">count</field>
|
||||
@@ -254,7 +266,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">repeat 10</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">repeat 10</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">count</field>
|
||||
|
||||
@@ -51,7 +51,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count up ints</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count up ints</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
@@ -100,7 +104,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count down ints</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count down ints</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
@@ -154,7 +162,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count with floats</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count with floats</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">loglist</field>
|
||||
@@ -263,7 +275,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count up non-trivial ints</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count up non-trivial ints</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">loglist</field>
|
||||
@@ -377,7 +393,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count down non-trivial ints</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count down non-trivial ints</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">loglist</field>
|
||||
@@ -481,7 +501,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count with floats</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count with floats</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">loglist</field>
|
||||
@@ -589,7 +613,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count up</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count up</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
@@ -633,7 +661,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count down</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count down</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
@@ -702,7 +734,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count up non-trivial</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count up non-trivial</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">loglist</field>
|
||||
@@ -791,7 +827,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count down non-trivial</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count down non-trivial</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">loglist</field>
|
||||
|
||||
@@ -93,7 +93,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">while continue</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">while continue</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
@@ -184,7 +188,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">until continue</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">until continue</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
@@ -252,7 +260,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count continue</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count continue</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
@@ -335,7 +347,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">for continue</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">for continue</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
@@ -439,7 +455,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">while break</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">while break</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">count</field>
|
||||
@@ -512,7 +532,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">until break</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">until break</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">count</field>
|
||||
@@ -580,7 +604,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">count break</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">count break</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
@@ -663,7 +691,11 @@
|
||||
</statement>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">for break</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">for break</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">log</field>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -45,11 +45,12 @@ Blockly.Blocks['unittest_assertequals'] = {
|
||||
this.setColour(65);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.appendDummyInput()
|
||||
.appendField(new Blockly.FieldTextInput('test name'), 'MESSAGE');
|
||||
this.appendValueInput('ACTUAL', null)
|
||||
this.appendValueInput('MESSAGE')
|
||||
.appendField('name')
|
||||
.setCheck('String');
|
||||
this.appendValueInput('ACTUAL')
|
||||
.appendField('actual');
|
||||
this.appendValueInput('EXPECTED', null)
|
||||
this.appendValueInput('EXPECTED')
|
||||
.appendField('expected');
|
||||
this.setTooltip('Tests that "actual == expected".');
|
||||
},
|
||||
@@ -64,9 +65,10 @@ Blockly.Blocks['unittest_assertvalue'] = {
|
||||
this.setColour(65);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.appendDummyInput()
|
||||
.appendField(new Blockly.FieldTextInput('test name'), 'MESSAGE');
|
||||
this.appendValueInput('ACTUAL', Boolean)
|
||||
this.appendValueInput('MESSAGE', 'test name')
|
||||
.appendField('name')
|
||||
.setCheck('String');
|
||||
this.appendValueInput('ACTUAL')
|
||||
.appendField('assert')
|
||||
.appendField(new Blockly.FieldDropdown(
|
||||
[['true', 'TRUE'], ['false', 'FALSE'], ['null', 'NULL']]), 'EXPECTED');
|
||||
@@ -92,3 +94,24 @@ Blockly.Blocks['unittest_fail'] = {
|
||||
return ['unittestResults'];
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['unittest_adjustindex'] = {
|
||||
// Adjusts the indexing based on current setting.
|
||||
init: function() {
|
||||
this.jsonInit({
|
||||
"message0": "adjusted %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "INDEX",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"inputsInline": true,
|
||||
"output": "Number",
|
||||
"colour": 65,
|
||||
"tooltip": "Adjusts the value based on whether generated code is using " +
|
||||
"zero or one based indexing"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -111,7 +111,8 @@ Blockly.Dart['unittest_main'].defineAssert_ = function() {
|
||||
|
||||
Blockly.Dart['unittest_assertequals'] = function(block) {
|
||||
// Asserts that a value equals another value.
|
||||
var message = Blockly.Dart.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.Dart.valueToCode(block, 'MESSAGE',
|
||||
Blockly.Dart.ORDER_NONE) || '';
|
||||
var actual = Blockly.Dart.valueToCode(block, 'ACTUAL',
|
||||
Blockly.Dart.ORDER_NONE) || 'null';
|
||||
var expected = Blockly.Dart.valueToCode(block, 'EXPECTED',
|
||||
@@ -122,7 +123,8 @@ Blockly.Dart['unittest_assertequals'] = function(block) {
|
||||
|
||||
Blockly.Dart['unittest_assertvalue'] = function(block) {
|
||||
// Asserts that a value is true, false, or null.
|
||||
var message = Blockly.Dart.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.Dart.valueToCode(block, 'MESSAGE',
|
||||
Blockly.Dart.ORDER_NONE) || '';
|
||||
var actual = Blockly.Dart.valueToCode(block, 'ACTUAL',
|
||||
Blockly.Dart.ORDER_NONE) || 'null';
|
||||
var expected = block.getFieldValue('EXPECTED');
|
||||
@@ -141,7 +143,8 @@ Blockly.Dart['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.Dart.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var message = Blockly.Dart.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.Dart.valueToCode(block, 'MESSAGE',
|
||||
Blockly.Dart.ORDER_NONE) || '';
|
||||
var functionName = Blockly.Dart.provideFunction_(
|
||||
'unittest_fail',
|
||||
[ 'void ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
@@ -154,3 +157,21 @@ Blockly.Dart['unittest_fail'] = function(block) {
|
||||
'}']);
|
||||
return functionName + '(' + message + ');\n';
|
||||
};
|
||||
|
||||
Blockly.Dart['unittest_adjustindex'] = function(block) {
|
||||
var index = Blockly.Dart.valueToCode(block, 'INDEX',
|
||||
Blockly.Dart.ORDER_ADDITIVE) || '0';
|
||||
// Adjust index if using one-based indexing.
|
||||
if (Blockly.Dart.ONE_BASED_INDEXING) {
|
||||
if (Blockly.isNumber(index)) {
|
||||
// If the index is a naked number, adjust it right now.
|
||||
return [parseFloat(index) + 1, Blockly.Dart.ORDER_ATOMIC];
|
||||
} else {
|
||||
// If the index is dynamic, adjust it in code.
|
||||
index = index + ' + 1';
|
||||
}
|
||||
} else if (Blockly.isNumber(index)) {
|
||||
return [index, Blockly.Dart.ORDER_ATOMIC];
|
||||
}
|
||||
return [index, Blockly.Dart.ORDER_ADDITIVE];
|
||||
};
|
||||
|
||||
@@ -35,15 +35,15 @@ Blockly.JavaScript['unittest_main'] = function(block) {
|
||||
' var report = [];',
|
||||
' var summary = [];',
|
||||
' var fails = 0;',
|
||||
' for (var x = 0; x < ' + resultsVar + '.length; x++) {',
|
||||
' if (' + resultsVar + '[x][0]) {',
|
||||
' for (var i = 0; i < ' + resultsVar + '.length; i++) {',
|
||||
' if (' + resultsVar + '[i][0]) {',
|
||||
' summary.push(".");',
|
||||
' } else {',
|
||||
' summary.push("F");',
|
||||
' fails++;',
|
||||
' report.push("");',
|
||||
' report.push("FAIL: " + ' + resultsVar + '[x][2]);',
|
||||
' report.push(' + resultsVar + '[x][1]);',
|
||||
' report.push("FAIL: " + ' + resultsVar + '[i][2]);',
|
||||
' report.push(' + resultsVar + '[i][1]);',
|
||||
' }',
|
||||
' }',
|
||||
' report.unshift(summary.join(""));',
|
||||
@@ -115,7 +115,8 @@ Blockly.JavaScript['unittest_main'].defineAssert_ = function(block) {
|
||||
|
||||
Blockly.JavaScript['unittest_assertequals'] = function(block) {
|
||||
// Asserts that a value equals another value.
|
||||
var message = Blockly.JavaScript.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.JavaScript.valueToCode(block, 'MESSAGE',
|
||||
Blockly.JavaScript.ORDER_NONE) || '';
|
||||
var actual = Blockly.JavaScript.valueToCode(block, 'ACTUAL',
|
||||
Blockly.JavaScript.ORDER_COMMA) || 'null';
|
||||
var expected = Blockly.JavaScript.valueToCode(block, 'EXPECTED',
|
||||
@@ -126,7 +127,8 @@ Blockly.JavaScript['unittest_assertequals'] = function(block) {
|
||||
|
||||
Blockly.JavaScript['unittest_assertvalue'] = function(block) {
|
||||
// Asserts that a value is true, false, or null.
|
||||
var message = Blockly.JavaScript.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.JavaScript.valueToCode(block, 'MESSAGE',
|
||||
Blockly.JavaScript.ORDER_NONE) || '';
|
||||
var actual = Blockly.JavaScript.valueToCode(block, 'ACTUAL',
|
||||
Blockly.JavaScript.ORDER_COMMA) || 'null';
|
||||
var expected = block.getFieldValue('EXPECTED');
|
||||
@@ -145,7 +147,8 @@ Blockly.JavaScript['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.JavaScript.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var message = Blockly.JavaScript.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.JavaScript.valueToCode(block, 'MESSAGE',
|
||||
Blockly.JavaScript.ORDER_NONE) || '';
|
||||
var functionName = Blockly.JavaScript.provideFunction_(
|
||||
'unittest_fail',
|
||||
[ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
@@ -158,3 +161,21 @@ Blockly.JavaScript['unittest_fail'] = function(block) {
|
||||
'}']);
|
||||
return functionName + '(' + message + ');\n';
|
||||
};
|
||||
|
||||
Blockly.JavaScript['unittest_adjustindex'] = function(block) {
|
||||
var index = Blockly.JavaScript.valueToCode(block, 'INDEX',
|
||||
Blockly.JavaScript.ORDER_ADDITION) || '0';
|
||||
// Adjust index if using one-based indexing.
|
||||
if (Blockly.JavaScript.ONE_BASED_INDEXING) {
|
||||
if (Blockly.isNumber(index)) {
|
||||
// If the index is a naked number, adjust it right now.
|
||||
return [parseFloat(index) + 1, Blockly.JavaScript.ORDER_ATOMIC];
|
||||
} else {
|
||||
// If the index is dynamic, adjust it in code.
|
||||
index = index + ' + 1';
|
||||
}
|
||||
} else if (Blockly.isNumber(index)) {
|
||||
return [index, Blockly.JavaScript.ORDER_ATOMIC];
|
||||
}
|
||||
return [index, Blockly.JavaScript.ORDER_ADDITION];
|
||||
};
|
||||
|
||||
@@ -105,13 +105,15 @@ Blockly.Lua['unittest_main'].defineAssert_ = function(block) {
|
||||
' actual = "{" .. table.concat(actual, ", ") .. "}"',
|
||||
' end',
|
||||
' end',
|
||||
' if actual == expected then',
|
||||
' if actual == expected or (type(actual) == "number" and ' +
|
||||
'type(expected) == "number" and math.abs(actual - expected) < ' +
|
||||
'1e-9) then ',
|
||||
' table.insert(' + resultsVar +
|
||||
', {success=true, log="OK", title=message})',
|
||||
' else',
|
||||
' table.insert(' + resultsVar + ', {success=false, ' +
|
||||
'log=string.format("Expected: %s\\nActual: %s"' +
|
||||
', expected, actual), title=message})',
|
||||
', tostring(expected), tostring(actual)), title=message})',
|
||||
' end',
|
||||
'end']);
|
||||
return functionName;
|
||||
@@ -119,7 +121,8 @@ Blockly.Lua['unittest_main'].defineAssert_ = function(block) {
|
||||
|
||||
Blockly.Lua['unittest_assertequals'] = function(block) {
|
||||
// Asserts that a value equals another value.
|
||||
var message = Blockly.Lua.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.Lua.valueToCode(block, 'MESSAGE',
|
||||
Blockly.Lua.ORDER_NONE) || '';
|
||||
var actual = Blockly.Lua.valueToCode(block, 'ACTUAL',
|
||||
Blockly.Lua.ORDER_NONE) || 'nil';
|
||||
var expected = Blockly.Lua.valueToCode(block, 'EXPECTED',
|
||||
@@ -130,7 +133,8 @@ Blockly.Lua['unittest_assertequals'] = function(block) {
|
||||
|
||||
Blockly.Lua['unittest_assertvalue'] = function(block) {
|
||||
// Asserts that a value is true, false, or null.
|
||||
var message = Blockly.Lua.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.Lua.valueToCode(block, 'MESSAGE',
|
||||
Blockly.Lua.ORDER_NONE) || '';
|
||||
var actual = Blockly.Lua.valueToCode(block, 'ACTUAL',
|
||||
Blockly.Lua.ORDER_NONE) || 'nil';
|
||||
var expected = block.getFieldValue('EXPECTED');
|
||||
@@ -149,7 +153,8 @@ Blockly.Lua['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.Lua.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var message = Blockly.Lua.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.Lua.valueToCode(block, 'MESSAGE',
|
||||
Blockly.Lua.ORDER_NONE) || '';
|
||||
var functionName = Blockly.Lua.provideFunction_(
|
||||
'unittest_fail',
|
||||
['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(message)',
|
||||
@@ -161,3 +166,14 @@ Blockly.Lua['unittest_fail'] = function(block) {
|
||||
'end']);
|
||||
return functionName + '(' + message + ')\n';
|
||||
};
|
||||
|
||||
Blockly.Lua['unittest_adjustindex'] = function(block) {
|
||||
var index = Blockly.Lua.valueToCode(block, 'INDEX',
|
||||
Blockly.Lua.ORDER_ADDITIVE) || '0';
|
||||
if (Blockly.isNumber(index)) {
|
||||
// If the index is a naked number, adjust it right now.
|
||||
return [parseFloat(index) + 1, Blockly.Lua.ORDER_ATOMIC];
|
||||
}
|
||||
// If the index is dynamic, adjust it in code.
|
||||
return [index + ' + 1', Blockly.Lua.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
@@ -78,7 +78,7 @@ Blockly.PHP['unittest_main'].defineAssert_ = function(block) {
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'assertEquals',
|
||||
[ ' function equals($a, $b) {',
|
||||
[' function equals($a, $b) {',
|
||||
' if ($a === $b) {',
|
||||
' return true;',
|
||||
' } else if ((is_numeric($a)) && (is_numeric($b)) &&',
|
||||
@@ -107,6 +107,10 @@ Blockly.PHP['unittest_main'].defineAssert_ = function(block) {
|
||||
' if (equals($actual, $expected)) {',
|
||||
' array_push(' + resultsVar + ', [true, "OK", $message]);',
|
||||
' } else {',
|
||||
' $expected = is_array($expected) ? implode(" ", $expected) : ' +
|
||||
'$expected;',
|
||||
' $actual = is_array($actual) ? implode(" ", $actual) : ' +
|
||||
'$actual;',
|
||||
' array_push(' + resultsVar + ', [false, ' +
|
||||
'"Expected: " . $expected . "\\nActual: " . $actual, $message]);',
|
||||
' }',
|
||||
@@ -116,7 +120,8 @@ Blockly.PHP['unittest_main'].defineAssert_ = function(block) {
|
||||
|
||||
Blockly.PHP['unittest_assertequals'] = function(block) {
|
||||
// Asserts that a value equals another value.
|
||||
var message = Blockly.PHP.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.PHP.valueToCode(block, 'MESSAGE',
|
||||
Blockly.PHP.ORDER_NONE) || '';
|
||||
var actual = Blockly.PHP.valueToCode(block, 'ACTUAL',
|
||||
Blockly.PHP.ORDER_COMMA) || 'null';
|
||||
var expected = Blockly.PHP.valueToCode(block, 'EXPECTED',
|
||||
@@ -127,7 +132,8 @@ Blockly.PHP['unittest_assertequals'] = function(block) {
|
||||
|
||||
Blockly.PHP['unittest_assertvalue'] = function(block) {
|
||||
// Asserts that a value is true, false, or null.
|
||||
var message = Blockly.PHP.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.PHP.valueToCode(block, 'MESSAGE',
|
||||
Blockly.PHP.ORDER_NONE) || '';
|
||||
var actual = Blockly.PHP.valueToCode(block, 'ACTUAL',
|
||||
Blockly.PHP.ORDER_COMMA) || 'null';
|
||||
var expected = block.getFieldValue('EXPECTED');
|
||||
@@ -146,7 +152,8 @@ Blockly.PHP['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var message = Blockly.PHP.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.PHP.valueToCode(block, 'MESSAGE',
|
||||
Blockly.PHP.ORDER_NONE) || '';
|
||||
var functionName = Blockly.PHP.provideFunction_(
|
||||
'unittest_fail',
|
||||
[ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
|
||||
@@ -160,3 +167,21 @@ Blockly.PHP['unittest_fail'] = function(block) {
|
||||
'}']);
|
||||
return functionName + '(' + message + ');\n';
|
||||
};
|
||||
|
||||
Blockly.PHP['unittest_adjustindex'] = function(block) {
|
||||
var index = Blockly.PHP.valueToCode(block, 'INDEX',
|
||||
Blockly.PHP.ORDER_ADDITION) || '0';
|
||||
// Adjust index if using one-based indexing.
|
||||
if (Blockly.PHP.ONE_BASED_INDEXING) {
|
||||
if (Blockly.isNumber(index)) {
|
||||
// If the index is a naked number, adjust it right now.
|
||||
return [parseFloat(index) + 1, Blockly.PHP.ORDER_ATOMIC];
|
||||
} else {
|
||||
// If the index is dynamic, adjust it in code.
|
||||
index = index + ' + 1';
|
||||
}
|
||||
} else if (Blockly.isNumber(index)) {
|
||||
return [index, Blockly.PHP.ORDER_ATOMIC];
|
||||
}
|
||||
return [index, Blockly.PHP.ORDER_ADDITION];
|
||||
};
|
||||
|
||||
@@ -89,7 +89,8 @@ Blockly.Python['unittest_main'].defineAssert_ = function() {
|
||||
|
||||
Blockly.Python['unittest_assertequals'] = function(block) {
|
||||
// Asserts that a value equals another value.
|
||||
var message = Blockly.Python.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.Python.valueToCode(block, 'MESSAGE',
|
||||
Blockly.Python.ORDER_NONE) || '';
|
||||
var actual = Blockly.Python.valueToCode(block, 'ACTUAL',
|
||||
Blockly.Python.ORDER_NONE) || 'None';
|
||||
var expected = Blockly.Python.valueToCode(block, 'EXPECTED',
|
||||
@@ -100,7 +101,8 @@ Blockly.Python['unittest_assertequals'] = function(block) {
|
||||
|
||||
Blockly.Python['unittest_assertvalue'] = function(block) {
|
||||
// Asserts that a value is true, false, or null.
|
||||
var message = Blockly.Python.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.Python.valueToCode(block, 'MESSAGE',
|
||||
Blockly.Python.ORDER_NONE) || '';
|
||||
var actual = Blockly.Python.valueToCode(block, 'ACTUAL',
|
||||
Blockly.Python.ORDER_NONE) || 'None';
|
||||
var expected = block.getFieldValue('EXPECTED');
|
||||
@@ -119,7 +121,8 @@ Blockly.Python['unittest_fail'] = function(block) {
|
||||
// Always assert an error.
|
||||
var resultsVar = Blockly.Python.variableDB_.getName('unittestResults',
|
||||
Blockly.Variables.NAME_TYPE);
|
||||
var message = Blockly.Python.quote_(block.getFieldValue('MESSAGE'));
|
||||
var message = Blockly.Python.valueToCode(block, 'MESSAGE',
|
||||
Blockly.Python.ORDER_NONE) || '';
|
||||
var functionName = Blockly.Python.provideFunction_(
|
||||
'fail',
|
||||
['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(message):',
|
||||
@@ -129,3 +132,21 @@ Blockly.Python['unittest_fail'] = function(block) {
|
||||
' ' + resultsVar + '.append((False, "Fail.", message))']);
|
||||
return functionName + '(' + message + ')\n';
|
||||
};
|
||||
|
||||
Blockly.Python['unittest_adjustindex'] = function(block) {
|
||||
var index = Blockly.Python.valueToCode(block, 'INDEX',
|
||||
Blockly.Python.ORDER_ADDITIVE) || '0';
|
||||
// Adjust index if using one-based indexing.
|
||||
if (Blockly.Python.ONE_BASED_INDEXING) {
|
||||
if (Blockly.isNumber(index)) {
|
||||
// If the index is a naked number, adjust it right now.
|
||||
return [parseFloat(index) + 1, Blockly.Python.ORDER_ATOMIC];
|
||||
} else {
|
||||
// If the index is dynamic, adjust it in code.
|
||||
index = index + ' + 1';
|
||||
}
|
||||
} else if (Blockly.isNumber(index)) {
|
||||
return [index, Blockly.Python.ORDER_ATOMIC];
|
||||
}
|
||||
return [index, Blockly.Python.ORDER_ADDITIVE];
|
||||
};
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">variable</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">variable</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">item</field>
|
||||
@@ -31,7 +35,11 @@
|
||||
</value>
|
||||
<next>
|
||||
<block type="unittest_assertequals" inline="false">
|
||||
<field name="MESSAGE">reserved variable</field>
|
||||
<value name="MESSAGE">
|
||||
<block type="text">
|
||||
<field name="TEXT">reserved variable</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ACTUAL">
|
||||
<block type="variables_get">
|
||||
<field name="VAR">if</field>
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
function verify_DB_(msg, expected, db) {
|
||||
var equal = (expected.length == db.length);
|
||||
if (equal) {
|
||||
for (var x = 0; x < expected.length; x++) {
|
||||
if (expected[x] != db[x]) {
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
if (expected[i] != db[i]) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user