in generators/lua/lists.js [123:199]
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 list = Blockly.Lua.valueToCode(block, 'VALUE', Blockly.Lua.ORDER_HIGH) ||
'({})';
var getIndex_ = Blockly.Lua.lists.getIndex_;
// If `list` would be evaluated more than once (which is the case for LAST,
// FROM_END, and RANDOM) and is non-trivial, make sure to access it only once.
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 (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.nameDB_.getDistinctName(
'tmp_list', Blockly.VARIABLE_CATEGORY_NAME);
at = getIndex_(listVar, where, at);
var code = listVar + ' = ' + list + '\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') {
var functionName = Blockly.Lua.provideFunction_(
'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'
var functionName = Blockly.Lua.provideFunction_(
'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 +
// 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 + '[' + at + ']';
return [code, Blockly.Lua.ORDER_HIGH];
} else {
var code = 'table.remove(' + list + ', ' + at + ')';
if (mode == 'GET_REMOVE') {
return [code, Blockly.Lua.ORDER_HIGH];
} else { // `mode` == 'REMOVE'
return code + '\n';
}
}
}
};