From e5a95685c4e8881fa5369018244fb62ca258d6a2 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 24 Apr 2019 00:08:05 +0200 Subject: [PATCH] new "combine" primitive in list category --- HISTORY.md | 5 ++++- snap.html | 4 ++-- src/objects.js | 20 +++++++++++++++++- src/threads.js | 56 +++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 80 insertions(+), 5 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 82254785..6902f816 100755 --- a/HISTORY.md +++ b/HISTORY.md @@ -25,7 +25,7 @@ * new "get graphic effect" reporter * new "get pen attribute" reporter * new "write" command in pen category (used to be "label" in tools) - * new "map","keep" and "for each" primitives in list category + * new "map","keep", "combine" and "for each" primitives in list category * added "neg", "lg" (log2) and "2^" selectors to monadic function reporter in Operators * added "^" reporter (power of) in the Operators category * added "width" and "height" as attribute selectors of the OF primitive for the stage @@ -68,6 +68,9 @@ * German * French +### 2019-04-24 +* Threads: new "combine" primitive in list category + ### 2019-04-23 * Threads: fixed JS stack overflow issue for MAP primitive * Threads: new "map" and "for each" primitives in list category diff --git a/snap.html b/snap.html index c62e2bfa..8691e205 100755 --- a/snap.html +++ b/snap.html @@ -7,8 +7,8 @@ - - + + diff --git a/src/objects.js b/src/objects.js index d494e4c6..6786b728 100644 --- a/src/objects.js +++ b/src/objects.js @@ -84,7 +84,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize, TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph, AlignmentMorph, Process, XML_Element, VectorPaintEditorMorph*/ -modules.objects = '2019-April-23'; +modules.objects = '2019-April-24'; var SpriteMorph; var StageMorph; @@ -1270,6 +1270,16 @@ SpriteMorph.prototype.initBlocks = function () { category: 'lists', spec: 'map %repRing over %l' }, + reportKeep: { + type: 'reporter', + category: 'lists', + spec: 'keep items such that %predRing from %l' + }, + reportCombine: { + type: 'reporter', + category: 'lists', + spec: 'combine with %repRing items of %l' + }, doForEach: { type: 'command', category: 'lists', @@ -2401,6 +2411,7 @@ SpriteMorph.prototype.blockTemplates = function (category) { blocks.push('='); blocks.push(block('reportNewList')); + blocks.push('-'); blocks.push(block('reportCONS')); blocks.push(block('reportListItem')); blocks.push(block('reportCDR')); @@ -2410,6 +2421,8 @@ SpriteMorph.prototype.blockTemplates = function (category) { blocks.push('-'); blocks.push(block('doForEach')); blocks.push(block('reportMap')); + blocks.push(block('reportKeep')); + blocks.push(block('reportCombine')); blocks.push('-'); blocks.push(block('doAddToList')); blocks.push(block('doDeleteFromList')); @@ -2591,6 +2604,8 @@ SpriteMorph.prototype.freshPalette = function (category) { 'reportListContainsItem', 'doForEach', 'reportMap', + 'reportKeep', + 'reportCombine', 'doAddToList', 'doDeleteFromList', 'doInsertInList', @@ -7947,6 +7962,7 @@ StageMorph.prototype.blockTemplates = function (category) { blocks.push(block('doDeclareVariables')); blocks.push('='); blocks.push(block('reportNewList')); + blocks.push('-'); blocks.push(block('reportCONS')); blocks.push(block('reportListItem')); blocks.push(block('reportCDR')); @@ -7956,6 +7972,8 @@ StageMorph.prototype.blockTemplates = function (category) { blocks.push('-'); blocks.push(block('doForEach')); blocks.push(block('reportMap')); + blocks.push(block('reportKeep')); + blocks.push(block('reportCombine')); blocks.push('-'); blocks.push(block('doAddToList')); blocks.push(block('doDeleteFromList')); diff --git a/src/threads.js b/src/threads.js index 3e3d1346..9f7ad9bc 100644 --- a/src/threads.js +++ b/src/threads.js @@ -62,7 +62,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy, isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, Color, TableFrameMorph, ColorSlotMorph, isSnapObject, Map, newCanvas, Symbol*/ -modules.threads = '2019-April-23'; +modules.threads = '2019-April-24'; var ThreadManager; var Process; @@ -2192,6 +2192,60 @@ Process.prototype.reportKeep = function (predicate, list) { this.evaluate(predicate, new List([next])); }; +Process.prototype.reportCombine = function (reporter, list) { + // Fold - answer an aggregation of all list items from "left to right" + // Distinguish between linked and arrayed lists. + + // this.context.inputs: + // [0] - predicate + // [1] - list (original source) + // ----------------------------- + // [2] - last predicate evaluation result + + var next, current; + if (list.length() < 2) { + this.returnValueToParentContext(list.length() ? list.at(1) : 0); + return; + } + if (list.isLinked) { + if (this.context.aggregation === null) { + this.context.aggregation = { + source : list.cdr(), + target : list.at(1), + remaining : list.length() - 1 + }; + } else if (this.context.inputs.length > 2) { + this.context.aggregation.target = this.context.inputs.pop(); + this.context.aggregation.remaining -= 1; + this.context.aggregation.source = + this.context.aggregation.source.cdr(); + } + if (this.context.aggregation.remaining === 0) { + this.returnValueToParentContext(this.context.aggregation.target); + return; + } + next = this.context.aggregation.source.at(1); + } else { // arrayed + if (this.context.aggregation === null) { + this.context.aggregation = { + idx : 1, + target : list.at(1) + }; + } else if (this.context.inputs.length > 2) { + this.context.aggregation.target = this.context.inputs.pop(); + } + if (this.context.aggregation.idx === list.length()) { + this.returnValueToParentContext(this.context.aggregation.target); + return; + } + this.context.aggregation.idx += 1; + next = list.at(this.context.aggregation.idx); + } + current = this.context.aggregation.target; + this.pushContext(); + this.evaluate(reporter, new List([current, next])); +}; + Process.prototype.doForEach = function (upvar, list, script) { // perform a script for each element of a list, assigning the // current iteration's element to a variable with the name