lists.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. /**
  2. * @license
  3. * Visual Blocks Language
  4. *
  5. * Copyright 2015 Google Inc.
  6. * https://developers.google.com/blockly/
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License");
  9. * you may not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. /**
  21. * @fileoverview Generating PHP for list blocks.
  22. * @author daarond@gmail.com (Daaron Dwyer)
  23. */
  24. /*
  25. * Lists in PHP are known to break when non-variables are passed into blocks
  26. * that require a list. PHP, unlike other languages, passes arrays as reference
  27. * value instead of value so we are unable to support it to the extent we can
  28. * for the other languages.
  29. * For example, a ternary operator with two arrays will return the array by
  30. * value and that cannot be passed into any of the built-in array functions for
  31. * PHP (because only variables can be passed by reference).
  32. * ex: end(true ? list1 : list2)
  33. */
  34. 'use strict';
  35. goog.provide('Blockly.PHP.lists');
  36. goog.require('Blockly.PHP');
  37. Blockly.PHP['lists_create_empty'] = function(block) {
  38. // Create an empty list.
  39. return ['array()', Blockly.PHP.ORDER_FUNCTION_CALL];
  40. };
  41. Blockly.PHP['lists_create_with'] = function(block) {
  42. // Create a list with any number of elements of any type.
  43. var code = new Array(block.itemCount_);
  44. for (var i = 0; i < block.itemCount_; i++) {
  45. code[i] = Blockly.PHP.valueToCode(block, 'ADD' + i,
  46. Blockly.PHP.ORDER_COMMA) || 'null';
  47. }
  48. code = 'array(' + code.join(', ') + ')';
  49. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  50. };
  51. Blockly.PHP['lists_repeat'] = function(block) {
  52. // Create a list with one element repeated.
  53. var functionName = Blockly.PHP.provideFunction_(
  54. 'lists_repeat',
  55. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  56. '($value, $count) {',
  57. ' $array = array();',
  58. ' for ($index = 0; $index < $count; $index++) {',
  59. ' $array[] = $value;',
  60. ' }',
  61. ' return $array;',
  62. '}']);
  63. var element = Blockly.PHP.valueToCode(block, 'ITEM',
  64. Blockly.PHP.ORDER_COMMA) || 'null';
  65. var repeatCount = Blockly.PHP.valueToCode(block, 'NUM',
  66. Blockly.PHP.ORDER_COMMA) || '0';
  67. var code = functionName + '(' + element + ', ' + repeatCount + ')';
  68. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  69. };
  70. Blockly.PHP['lists_length'] = function(block) {
  71. // String or array length.
  72. var functionName = Blockly.PHP.provideFunction_(
  73. 'length',
  74. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {',
  75. ' if (is_string($value)) {',
  76. ' return strlen($value);',
  77. ' } else {',
  78. ' return count($value);',
  79. ' }',
  80. '}']);
  81. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  82. Blockly.PHP.ORDER_NONE) || '\'\'';
  83. return [functionName + '(' + list + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
  84. };
  85. Blockly.PHP['lists_isEmpty'] = function(block) {
  86. // Is the string null or array empty?
  87. var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
  88. Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
  89. return ['empty(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
  90. };
  91. Blockly.PHP['lists_indexOf'] = function(block) {
  92. // Find an item in the list.
  93. var argument0 = Blockly.PHP.valueToCode(block, 'FIND',
  94. Blockly.PHP.ORDER_NONE) || '\'\'';
  95. var argument1 = Blockly.PHP.valueToCode(block, 'VALUE',
  96. Blockly.PHP.ORDER_MEMBER) || '[]';
  97. if (Blockly.PHP.ONE_BASED_INDEXING) {
  98. var errorIndex = ' 0';
  99. var indexAdjustment = ' + 1';
  100. } else {
  101. var errorIndex = ' -1';
  102. var indexAdjustment = '';
  103. }
  104. if (block.getFieldValue('END') == 'FIRST') {
  105. // indexOf
  106. var functionName = Blockly.PHP.provideFunction_(
  107. 'indexOf',
  108. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  109. '($haystack, $needle) {',
  110. ' for ($index = 0; $index < count($haystack); $index++) {',
  111. ' if ($haystack[$index] == $needle) return $index' +
  112. indexAdjustment + ';',
  113. ' }',
  114. ' return ' + errorIndex + ';',
  115. '}']);
  116. } else {
  117. // lastIndexOf
  118. var functionName = Blockly.PHP.provideFunction_(
  119. 'lastIndexOf',
  120. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  121. '($haystack, $needle) {',
  122. ' $last = ' + errorIndex + ';',
  123. ' for ($index = 0; $index < count($haystack); $index++) {',
  124. ' if ($haystack[$index] == $needle) $last = $index' +
  125. indexAdjustment + ';',
  126. ' }',
  127. ' return $last;',
  128. '}']);
  129. }
  130. var code = functionName + '(' + argument1 + ', ' + argument0 + ')';
  131. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  132. };
  133. Blockly.PHP['lists_getIndex'] = function(block) {
  134. // Get element at index.
  135. var mode = block.getFieldValue('MODE') || 'GET';
  136. var where = block.getFieldValue('WHERE') || 'FROM_START';
  137. switch (where) {
  138. case 'FIRST':
  139. if (mode == 'GET') {
  140. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  141. Blockly.PHP.ORDER_MEMBER) || 'array()';
  142. var code = list + '[0]';
  143. return [code, Blockly.PHP.ORDER_MEMBER];
  144. } else if (mode == 'GET_REMOVE') {
  145. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  146. Blockly.PHP.ORDER_NONE) || 'array()';
  147. var code = 'array_shift(' + list + ')';
  148. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  149. } else if (mode == 'REMOVE') {
  150. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  151. Blockly.PHP.ORDER_NONE) || 'array()';
  152. return 'array_shift(' + list + ');\n';
  153. }
  154. break;
  155. case 'LAST':
  156. if (mode == 'GET') {
  157. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  158. Blockly.PHP.ORDER_NONE) || 'array()';
  159. var code = 'end(' + list + ')';
  160. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  161. } else if (mode == 'GET_REMOVE') {
  162. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  163. Blockly.PHP.ORDER_NONE) || 'array()';
  164. var code = 'array_pop(' + list + ')';
  165. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  166. } else if (mode == 'REMOVE') {
  167. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  168. Blockly.PHP.ORDER_NONE) || 'array()';
  169. return 'array_pop(' + list + ');\n';
  170. }
  171. break;
  172. case 'FROM_START':
  173. var at = Blockly.PHP.getAdjusted(block, 'AT');
  174. if (mode == 'GET') {
  175. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  176. Blockly.PHP.ORDER_MEMBER) || 'array()';
  177. var code = list + '[' + at + ']';
  178. return [code, Blockly.PHP.ORDER_MEMBER];
  179. } else if (mode == 'GET_REMOVE') {
  180. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  181. Blockly.PHP.ORDER_COMMA) || 'array()';
  182. var code = 'array_splice(' + list + ', ' + at + ', 1)[0]';
  183. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  184. } else if (mode == 'REMOVE') {
  185. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  186. Blockly.PHP.ORDER_COMMA) || 'array()';
  187. return 'array_splice(' + list + ', ' + at + ', 1);\n';
  188. }
  189. break;
  190. case 'FROM_END':
  191. if (mode == 'GET') {
  192. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  193. Blockly.PHP.ORDER_COMMA) || 'array()';
  194. var at = Blockly.PHP.getAdjusted(block, 'AT', 1, true);
  195. var code = 'array_slice(' + list + ', ' + at + ', 1)[0]';
  196. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  197. } else if (mode == 'GET_REMOVE' || mode == 'REMOVE') {
  198. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  199. Blockly.PHP.ORDER_NONE) || 'array()';
  200. var at = Blockly.PHP.getAdjusted(block, 'AT', 1, false,
  201. Blockly.PHP.ORDER_SUBTRACTION);
  202. code = 'array_splice(' + list +
  203. ', count(' + list + ') - ' + at + ', 1)[0]';
  204. if (mode == 'GET_REMOVE') {
  205. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  206. } else if (mode == 'REMOVE') {
  207. return code + ';\n';
  208. }
  209. }
  210. break;
  211. case 'RANDOM':
  212. var list = Blockly.PHP.valueToCode(block, 'VALUE',
  213. Blockly.PHP.ORDER_NONE) || 'array()';
  214. if (mode == 'GET') {
  215. var functionName = Blockly.PHP.provideFunction_(
  216. 'lists_get_random_item',
  217. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  218. '($list) {',
  219. ' return $list[rand(0,count($list)-1)];',
  220. '}']);
  221. code = functionName + '(' + list + ')';
  222. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  223. } else if (mode == 'GET_REMOVE') {
  224. var functionName = Blockly.PHP.provideFunction_(
  225. 'lists_get_remove_random_item',
  226. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  227. '(&$list) {',
  228. ' $x = rand(0,count($list)-1);',
  229. ' unset($list[$x]);',
  230. ' return array_values($list);',
  231. '}']);
  232. code = functionName + '(' + list + ')';
  233. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  234. } else if (mode == 'REMOVE') {
  235. var functionName = Blockly.PHP.provideFunction_(
  236. 'lists_remove_random_item',
  237. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  238. '(&$list) {',
  239. ' unset($list[rand(0,count($list)-1)]);',
  240. '}']);
  241. return functionName + '(' + list + ');\n';
  242. }
  243. break;
  244. }
  245. throw 'Unhandled combination (lists_getIndex).';
  246. };
  247. Blockly.PHP['lists_setIndex'] = function(block) {
  248. // Set element at index.
  249. // Note: Until February 2013 this block did not have MODE or WHERE inputs.
  250. var mode = block.getFieldValue('MODE') || 'GET';
  251. var where = block.getFieldValue('WHERE') || 'FROM_START';
  252. var value = Blockly.PHP.valueToCode(block, 'TO',
  253. Blockly.PHP.ORDER_ASSIGNMENT) || 'null';
  254. // Cache non-trivial values to variables to prevent repeated look-ups.
  255. // Closure, which accesses and modifies 'list'.
  256. function cacheList() {
  257. if (list.match(/^\$\w+$/)) {
  258. return '';
  259. }
  260. var listVar = Blockly.PHP.variableDB_.getDistinctName(
  261. 'tmp_list', Blockly.Variables.NAME_TYPE);
  262. var code = listVar + ' = &' + list + ';\n';
  263. list = listVar;
  264. return code;
  265. }
  266. switch (where) {
  267. case 'FIRST':
  268. if (mode == 'SET') {
  269. var list = Blockly.PHP.valueToCode(block, 'LIST',
  270. Blockly.PHP.ORDER_MEMBER) || 'array()';
  271. return list + '[0] = ' + value + ';\n';
  272. } else if (mode == 'INSERT') {
  273. var list = Blockly.PHP.valueToCode(block, 'LIST',
  274. Blockly.PHP.ORDER_COMMA) || 'array()';
  275. return 'array_unshift(' + list + ', ' + value + ');\n';
  276. }
  277. break;
  278. case 'LAST':
  279. var list = Blockly.PHP.valueToCode(block, 'LIST',
  280. Blockly.PHP.ORDER_COMMA) || 'array()';
  281. if (mode == 'SET') {
  282. var functionName = Blockly.PHP.provideFunction_(
  283. 'lists_set_last_item',
  284. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  285. '(&$list, $value) {',
  286. ' $list[count($list) - 1] = $value;',
  287. '}']);
  288. return functionName + '(' + list + ', ' + value + ');\n';
  289. } else if (mode == 'INSERT') {
  290. return 'array_push(' + list + ', ' + value + ');\n';
  291. }
  292. break;
  293. case 'FROM_START':
  294. var at = Blockly.PHP.getAdjusted(block, 'AT');
  295. if (mode == 'SET') {
  296. var list = Blockly.PHP.valueToCode(block, 'LIST',
  297. Blockly.PHP.ORDER_MEMBER) || 'array()';
  298. return list + '[' + at + '] = ' + value + ';\n';
  299. } else if (mode == 'INSERT') {
  300. var list = Blockly.PHP.valueToCode(block, 'LIST',
  301. Blockly.PHP.ORDER_COMMA) || 'array()';
  302. return 'array_splice(' + list + ', ' + at + ', 0, ' + value + ');\n';
  303. }
  304. break;
  305. case 'FROM_END':
  306. var list = Blockly.PHP.valueToCode(block, 'LIST',
  307. Blockly.PHP.ORDER_COMMA) || 'array()';
  308. var at = Blockly.PHP.getAdjusted(block, 'AT', 1);
  309. if (mode == 'SET') {
  310. var functionName = Blockly.PHP.provideFunction_(
  311. 'lists_set_from_end',
  312. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  313. '(&$list, $at, $value) {',
  314. ' $list[count($list) - $at] = $value;',
  315. '}']);
  316. return functionName + '(' + list + ', ' + at + ', ' + value + ');\n';
  317. } else if (mode == 'INSERT') {
  318. var functionName = Blockly.PHP.provideFunction_(
  319. 'lists_insert_from_end',
  320. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  321. '(&$list, $at, $value) {',
  322. ' return array_splice($list, count($list) - $at, 0, $value);',
  323. '}']);
  324. return functionName + '(' + list + ', ' + at + ', ' + value + ');\n';
  325. }
  326. break;
  327. case 'RANDOM':
  328. var list = Blockly.PHP.valueToCode(block, 'LIST',
  329. Blockly.PHP.ORDER_REFERENCE) || 'array()';
  330. var code = cacheList();
  331. var xVar = Blockly.PHP.variableDB_.getDistinctName(
  332. 'tmp_x', Blockly.Variables.NAME_TYPE);
  333. code += xVar + ' = rand(0, count(' + list + ')-1);\n';
  334. if (mode == 'SET') {
  335. code += list + '[' + xVar + '] = ' + value + ';\n';
  336. return code;
  337. } else if (mode == 'INSERT') {
  338. code += 'array_splice(' + list + ', ' + xVar + ', 0, ' + value +
  339. ');\n';
  340. return code;
  341. }
  342. break;
  343. }
  344. throw 'Unhandled combination (lists_setIndex).';
  345. };
  346. Blockly.PHP['lists_getSublist'] = function(block) {
  347. // Get sublist.
  348. var list = Blockly.PHP.valueToCode(block, 'LIST',
  349. Blockly.PHP.ORDER_COMMA) || 'array()';
  350. var where1 = block.getFieldValue('WHERE1');
  351. var where2 = block.getFieldValue('WHERE2');
  352. if (where1 == 'FIRST' && where2 == 'LAST') {
  353. var code = list;
  354. } else if (list.match(/^\$\w+$/) ||
  355. (where1 != 'FROM_END' && where2 == 'FROM_START')) {
  356. // If the list is a simple value or doesn't require a call for length, don't
  357. // generate a helper function.
  358. switch (where1) {
  359. case 'FROM_START':
  360. var at1 = Blockly.PHP.getAdjusted(block, 'AT1');
  361. break;
  362. case 'FROM_END':
  363. var at1 = Blockly.PHP.getAdjusted(block, 'AT1', 1, false,
  364. Blockly.PHP.ORDER_SUBTRACTION);
  365. at1 = 'count(' + list + ') - ' + at1;
  366. break;
  367. case 'FIRST':
  368. var at1 = '0';
  369. break;
  370. default:
  371. throw 'Unhandled option (lists_getSublist).';
  372. }
  373. switch (where2) {
  374. case 'FROM_START':
  375. var at2 = Blockly.PHP.getAdjusted(block, 'AT2', 0, false,
  376. Blockly.PHP.ORDER_SUBTRACTION);
  377. var length = at2 + ' - ';
  378. if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) {
  379. length += at1;
  380. } else {
  381. length += '(' + at1 + ')';
  382. }
  383. length += ' + 1';
  384. break;
  385. case 'FROM_END':
  386. var at2 = Blockly.PHP.getAdjusted(block, 'AT2', 0, false,
  387. Blockly.PHP.ORDER_SUBTRACTION);
  388. var length = 'count(' + list + ') - ' + at2 + ' - ';
  389. if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) {
  390. length += at1;
  391. } else {
  392. length += '(' + at1 + ')';
  393. }
  394. break;
  395. case 'LAST':
  396. var length = 'count(' + list + ') - ';
  397. if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) {
  398. length += at1;
  399. } else {
  400. length += '(' + at1 + ')';
  401. }
  402. break;
  403. default:
  404. throw 'Unhandled option (lists_getSublist).';
  405. }
  406. code = 'array_slice(' + list + ', ' + at1 + ', ' + length + ')';
  407. } else {
  408. var at1 = Blockly.PHP.getAdjusted(block, 'AT1');
  409. var at2 = Blockly.PHP.getAdjusted(block, 'AT2');
  410. var functionName = Blockly.PHP.provideFunction_(
  411. 'lists_get_sublist',
  412. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  413. '($list, $where1, $at1, $where2, $at2) {',
  414. ' if ($where1 == \'FROM_END\') {',
  415. ' $at1 = count($list) - 1 - $at1;',
  416. ' } else if ($where1 == \'FIRST\') {',
  417. ' $at1 = 0;',
  418. ' } else if ($where1 != \'FROM_START\'){',
  419. ' throw new Exception(\'Unhandled option (lists_get_sublist).\');',
  420. ' }',
  421. ' $length = 0;',
  422. ' if ($where2 == \'FROM_START\') {',
  423. ' $length = $at2 - $at1 + 1;',
  424. ' } else if ($where2 == \'FROM_END\') {',
  425. ' $length = count($list) - $at1 - $at2;',
  426. ' } else if ($where2 == \'LAST\') {',
  427. ' $length = count($list) - $at1;',
  428. ' } else {',
  429. ' throw new Exception(\'Unhandled option (lists_get_sublist).\');',
  430. ' }',
  431. ' return array_slice($list, $at1, $length);',
  432. '}']);
  433. var code = functionName + '(' + list + ', \'' +
  434. where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
  435. }
  436. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  437. };
  438. Blockly.PHP['lists_sort'] = function(block) {
  439. // Block for sorting a list.
  440. var listCode = Blockly.PHP.valueToCode(block, 'LIST',
  441. Blockly.PHP.ORDER_COMMA) || 'array()';
  442. var direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
  443. var type = block.getFieldValue('TYPE');
  444. var functionName = Blockly.PHP.provideFunction_(
  445. 'lists_sort',
  446. ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
  447. '($list, $type, $direction) {',
  448. ' $sortCmpFuncs = array(',
  449. ' "NUMERIC" => "strnatcasecmp",',
  450. ' "TEXT" => "strcmp",',
  451. ' "IGNORE_CASE" => "strcasecmp"',
  452. ' );',
  453. ' $sortCmp = $sortCmpFuncs[$type];',
  454. ' $list2 = $list;', // Clone list.
  455. ' usort($list2, $sortCmp);',
  456. ' if ($direction == -1) {',
  457. ' $list2 = array_reverse($list2);',
  458. ' }',
  459. ' return $list2;',
  460. '}']);
  461. var sortCode = functionName +
  462. '(' + listCode + ', "' + type + '", ' + direction + ')';
  463. return [sortCode, Blockly.PHP.ORDER_FUNCTION_CALL];
  464. };
  465. Blockly.PHP['lists_split'] = function(block) {
  466. // Block for splitting text into a list, or joining a list into text.
  467. var value_input = Blockly.PHP.valueToCode(block, 'INPUT',
  468. Blockly.PHP.ORDER_COMMA);
  469. var value_delim = Blockly.PHP.valueToCode(block, 'DELIM',
  470. Blockly.PHP.ORDER_COMMA) || '\'\'';
  471. var mode = block.getFieldValue('MODE');
  472. if (mode == 'SPLIT') {
  473. if (!value_input) {
  474. value_input = '\'\'';
  475. }
  476. var functionName = 'explode';
  477. } else if (mode == 'JOIN') {
  478. if (!value_input) {
  479. value_input = 'array()';
  480. }
  481. var functionName = 'implode';
  482. } else {
  483. throw 'Unknown mode: ' + mode;
  484. }
  485. var code = functionName + '(' + value_delim + ', ' + value_input + ')';
  486. return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
  487. };