From 137b9b51dfc77293fca2508953de05f0f7e4940f Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 29 May 2019 11:53:21 +0200 Subject: [PATCH] added JIT-compiled "blitz" version of FIND --- HISTORY.md | 3 ++- snap.html | 2 +- src/blocks.js | 13 ++++++++++--- src/objects.js | 6 ++++++ src/threads.js | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 8b88b8cb..9d30f962 100755 --- a/HISTORY.md +++ b/HISTORY.md @@ -29,7 +29,7 @@ * new "get pen attribute" reporter * new "write" command in pen category (used to be "label" in tools) * new "numbers", "is empty", "map","keep", "find", "combine" and "for each" primitives in list category - * new JIT-compiler "blitz-HOF" primitives for "map", "keep" & "combine" via "compile" + * new JIT-compiler "blitz-HOF" primitives for "map", "keep", "find" & "combine" via "compile" * new "for" loop and "if then else" reporter primitives in the Control category * added "neg", "lg" (log2) and "2^" selectors to monadic function reporter in Operators * added "^" reporter (power of) in the Operators category @@ -82,6 +82,7 @@ ### 2019-05-29 * Threads, Objects: added "Find First" primitive to lists category +* Blocks, Thread, Objects: added "blitz" version of FIND ### 2019-05-28 * Maps: added various different tile hosts diff --git a/snap.html b/snap.html index 7d2fd9f4..2080c88d 100755 --- a/snap.html +++ b/snap.html @@ -6,7 +6,7 @@ - + diff --git a/src/blocks.js b/src/blocks.js index e75473fd..fabab3ec 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -148,7 +148,7 @@ CustomCommandBlockMorph, SymbolMorph, ToggleButtonMorph, DialMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2019-May-20'; +modules.blocks = '2019-May-29'; var SyntaxElementMorph; var BlockMorph; @@ -2835,13 +2835,14 @@ BlockMorph.prototype.userMenu = function () { // JIT-compile HOFs - experimental if ( contains( - ['reportMap', 'reportKeep', 'reportCombine'], + ['reportMap', 'reportKeep', 'reportFindFirst', 'reportCombine'], this.selector ) ) { alternatives = { reportMap : 'reportAtomicMap', reportKeep : 'reportAtomicKeep', + reportFindFirst: 'reportAtomicFindFirst', reportCombine : 'reportAtomicCombine' }; menu.addItem( @@ -2855,13 +2856,19 @@ BlockMorph.prototype.userMenu = function () { ); } else if ( contains( - ['reportAtomicMap', 'reportAtomicKeep', 'reportAtomicCombine'], + [ + 'reportAtomicMap', + 'reportAtomicKeep', + 'reportAtomicFindFirst', + 'reportAtomicCombine' + ], this.selector ) ) { alternatives = { reportAtomicMap : 'reportMap', reportAtomicKeep : 'reportKeep', + reportAtomicFindFirst: 'reportFindFirst', reportAtomicCombine : 'reportCombine' }; menu.addItem( diff --git a/src/objects.js b/src/objects.js index 985b0560..024a1a33 100644 --- a/src/objects.js +++ b/src/objects.js @@ -1317,6 +1317,12 @@ SpriteMorph.prototype.initBlocks = function () { category: 'lists', spec: 'find first item such that %predRing in %l' }, + reportAtomicFindFirst: { + dev: true, // not shown in palette, only accessible via relabelling + type: 'reporter', + category: 'lists', + spec: '%blitz find first item such that %predRing in %l' + }, reportCombine: { type: 'reporter', category: 'lists', diff --git a/src/threads.js b/src/threads.js index d5d8874e..7bee88f6 100644 --- a/src/threads.js +++ b/src/threads.js @@ -5043,6 +5043,42 @@ Process.prototype.reportAtomicKeep = function (reporter, list) { return new List(result); }; +Process.prototype.reportAtomicFindFirst = function (reporter, list) { + this.assertType(list, 'list'); + var src = list.asArray(), + len = src.length, + func, + i; + + // try compiling the reporter into generic JavaScript + // fall back to the morphic reporter if unsuccessful + try { + func = this.reportCompiled(reporter, 1); // a single expected input + } catch (err) { + console.log(err.message); + func = reporter; + } + + // iterate over the data in a single frame: + // to do: Insert some kind of user escape mechanism + for (i = 0; i < len; i += 1) { + if ( + invoke( + func, + new List([src[i]]), + null, + null, + null, + null, + this.capture(reporter) // process + ) + ) { + return src[i]; + } + } + return false; +}; + Process.prototype.reportAtomicCombine = function (reporter, list) { this.assertType(list, 'list'); var result = '',