From 47145ca8f114745b2bb5de2f71771d49df4913ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20M=C3=B6nig?= Date: Sun, 1 May 2022 18:36:37 +0200 Subject: [PATCH] programmatically add inputs to a custom block --- HISTORY.md | 1 + src/byob.js | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 20866d45..bf9d876d 100755 --- a/HISTORY.md +++ b/HISTORY.md @@ -47,6 +47,7 @@ ### 2022-05-01 * byob: programmatically reduce the number of inputs in a custom block +* byob: programmatically add inputs to a custom block ### 2022-04-28 * threads, byob: programmatically re-define custom blocks, experimental, under construction diff --git a/src/byob.js b/src/byob.js index 908212a4..0eb20983 100644 --- a/src/byob.js +++ b/src/byob.js @@ -569,11 +569,13 @@ CustomBlockDefinition.prototype.setBlockDefinition = function (aContext) { declarations = this.declarations, parts = []; + // remove excess inputs or add missing ones if (oldInputs.length > newInputs.length) { this.removeInputs(oldInputs.length - newInputs.length); spec = this.abstractBlockSpec(); - } else if (oldInputs.length !== newInputs.length) { - throw new Error('expecting the number of inputs to match'); + } else if (oldInputs.length > newInputs.length) { + this.addInputs(newInputs.length - oldInputs.length); + spec = this.abstractBlockSpec(); } // change the input names in the spec to those of the given context @@ -618,7 +620,24 @@ CustomBlockDefinition.prototype.removeInputs = function (count) { }; CustomBlockDefinition.prototype.addInputs = function (count) { - // private + // private - only to be called from a Process that also does housekeeping + var inputNames = this.inputNames(), + i; + + // create gensyms + for (i = 0; i < count; i += 1) { + inputNames.push(this.gensym(inputNames)); + } + + // add gensyms to the spec + this.spec = this.parseSpec(this.spec).concat( + inputNames.slice(-count).map(str => '%' + str) + ).join(' ').trim(); + + // add slot declarations for the gensyms + inputNames.slice(-count).forEach(name => + this.declarations.set(name, ['%s']) + ); }; CustomBlockDefinition.prototype.gensym = function (existing) {