diff --git a/core/generator.ts b/core/generator.ts index c7c26f15f..f948924d9 100644 --- a/core/generator.ts +++ b/core/generator.ts @@ -313,6 +313,9 @@ export class CodeGenerator { throw TypeError('Expecting valid order from block: ' + block.type); } const targetBlock = block.getInputTargetBlock(name); + if (!targetBlock && !block.getInput(name)) { + throw ReferenceError(`Input "${name}" doesn't exist on "${block.type}"`); + } if (!targetBlock) { return ''; } @@ -391,6 +394,9 @@ export class CodeGenerator { */ statementToCode(block: Block, name: string): string { const targetBlock = block.getInputTargetBlock(name); + if (!targetBlock && !block.getInput(name)) { + throw ReferenceError(`Input "${name}" doesn't exist on "${block.type}"`); + } let code = this.blockToCode(targetBlock); // Value blocks must return code and order of operations info. // Statement blocks must only return code. diff --git a/generators/dart/procedures.ts b/generators/dart/procedures.ts index 5102432ad..0ecf6d210 100644 --- a/generators/dart/procedures.ts +++ b/generators/dart/procedures.ts @@ -35,8 +35,17 @@ export function procedures_defreturn(block: Block, generator: DartGenerator) { generator.INDENT, ); } - const branch = generator.statementToCode(block, 'STACK'); - let returnValue = generator.valueToCode(block, 'RETURN', Order.NONE) || ''; + let branch = ''; + if (block.getInput('STACK')) { + // The 'procedures_defreturn' block might not have a STACK input. + branch = generator.statementToCode(block, 'STACK'); + } + let returnValue = ''; + if (block.getInput('RETURN')) { + // The 'procedures_defnoreturn' block (which shares this code) + // does not have a RETURN input. + returnValue = generator.valueToCode(block, 'RETURN', Order.NONE) || ''; + } let xfix2 = ''; if (branch && returnValue) { // After executing the function body, revisit this block for the return. diff --git a/generators/dart/text.ts b/generators/dart/text.ts index 501619e03..6bb2bea82 100644 --- a/generators/dart/text.ts +++ b/generators/dart/text.ts @@ -128,10 +128,12 @@ export function text_charAt( return [code, Order.UNARY_POSTFIX]; } case 'LAST': - at = 1; - // Fall through. case 'FROM_END': { - at = generator.getAdjusted(block, 'AT', 1); + if (where === 'LAST') { + at = 1; + } else { + at = generator.getAdjusted(block, 'AT', 1); + } const functionName = generator.provideFunction_( 'text_get_from_end', ` @@ -140,7 +142,7 @@ String ${generator.FUNCTION_NAME_PLACEHOLDER_}(String text, num x) { } `, ); - const code = functionName + '(' + text + ', ' + at + ')'; + const code = `${functionName}(${text}, ${at})`; return [code, Order.UNARY_POSTFIX]; } case 'RANDOM': { diff --git a/generators/javascript/procedures.ts b/generators/javascript/procedures.ts index a835271e7..e0a055217 100644 --- a/generators/javascript/procedures.ts +++ b/generators/javascript/procedures.ts @@ -38,8 +38,17 @@ export function procedures_defreturn( generator.INDENT, ); } - const branch = generator.statementToCode(block, 'STACK'); - let returnValue = generator.valueToCode(block, 'RETURN', Order.NONE) || ''; + let branch = ''; + if (block.getInput('STACK')) { + // The 'procedures_defreturn' block might not have a STACK input. + branch = generator.statementToCode(block, 'STACK'); + } + let returnValue = ''; + if (block.getInput('RETURN')) { + // The 'procedures_defnoreturn' block (which shares this code) + // does not have a RETURN input. + returnValue = generator.valueToCode(block, 'RETURN', Order.NONE) || ''; + } let xfix2 = ''; if (branch && returnValue) { // After executing the function body, revisit this block for the return. diff --git a/generators/lua/procedures.ts b/generators/lua/procedures.ts index 07003aee9..79dc58aa2 100644 --- a/generators/lua/procedures.ts +++ b/generators/lua/procedures.ts @@ -38,8 +38,17 @@ export function procedures_defreturn( generator.INDENT, ); } - let branch = generator.statementToCode(block, 'STACK'); - let returnValue = generator.valueToCode(block, 'RETURN', Order.NONE) || ''; + let branch = ''; + if (block.getInput('STACK')) { + // The 'procedures_defreturn' block might not have a STACK input. + branch = generator.statementToCode(block, 'STACK'); + } + let returnValue = ''; + if (block.getInput('RETURN')) { + // The 'procedures_defnoreturn' block (which shares this code) + // does not have a RETURN input. + returnValue = generator.valueToCode(block, 'RETURN', Order.NONE) || ''; + } let xfix2 = ''; if (branch && returnValue) { // After executing the function body, revisit this block for the return. diff --git a/generators/lua/text.ts b/generators/lua/text.ts index defbbaf99..350b86313 100644 --- a/generators/lua/text.ts +++ b/generators/lua/text.ts @@ -132,8 +132,6 @@ export function text_charAt( // Get letter at index. // Note: Until January 2013 this block did not have the WHERE input. const where = block.getFieldValue('WHERE') || 'FROM_START'; - const atOrder = where === 'FROM_END' ? Order.UNARY : Order.NONE; - const at = generator.valueToCode(block, 'AT', atOrder) || '1'; const text = generator.valueToCode(block, 'VALUE', Order.NONE) || "''"; let code; if (where === 'RANDOM') { @@ -154,6 +152,8 @@ end } else if (where === 'LAST') { start = '-1'; } else { + const atOrder = where === 'FROM_END' ? Order.UNARY : Order.NONE; + const at = generator.valueToCode(block, 'AT', atOrder) || '1'; if (where === 'FROM_START') { start = at; } else if (where === 'FROM_END') { diff --git a/generators/php/procedures.ts b/generators/php/procedures.ts index bd114cd0d..acf84aea6 100644 --- a/generators/php/procedures.ts +++ b/generators/php/procedures.ts @@ -60,8 +60,17 @@ export function procedures_defreturn(block: Block, generator: PhpGenerator) { generator.INDENT, ); } - const branch = generator.statementToCode(block, 'STACK'); - let returnValue = generator.valueToCode(block, 'RETURN', Order.NONE) || ''; + let branch = ''; + if (block.getInput('STACK')) { + // The 'procedures_defreturn' block might not have a STACK input. + branch = generator.statementToCode(block, 'STACK'); + } + let returnValue = ''; + if (block.getInput('RETURN')) { + // The 'procedures_defnoreturn' block (which shares this code) + // does not have a RETURN input. + returnValue = generator.valueToCode(block, 'RETURN', Order.NONE) || ''; + } let xfix2 = ''; if (branch && returnValue) { // After executing the function body, revisit this block for the return. diff --git a/generators/python/procedures.ts b/generators/python/procedures.ts index 798d6d55a..51d2ee9a3 100644 --- a/generators/python/procedures.ts +++ b/generators/python/procedures.ts @@ -60,8 +60,17 @@ export function procedures_defreturn(block: Block, generator: PythonGenerator) { generator.INDENT, ); } - let branch = generator.statementToCode(block, 'STACK'); - let returnValue = generator.valueToCode(block, 'RETURN', Order.NONE) || ''; + let branch = ''; + if (block.getInput('STACK')) { + // The 'procedures_defreturn' block might not have a STACK input. + branch = generator.statementToCode(block, 'STACK'); + } + let returnValue = ''; + if (block.getInput('RETURN')) { + // The 'procedures_defnoreturn' block (which shares this code) + // does not have a RETURN input. + returnValue = generator.valueToCode(block, 'RETURN', Order.NONE) || ''; + } let xfix2 = ''; if (branch && returnValue) { // After executing the function body, revisit this block for the return.