summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjmoenig <jens@moenig.org>2013-10-09 12:37:50 +0200
committerjmoenig <jens@moenig.org>2013-10-09 12:37:50 +0200
commit24476a644e18b526f09dab730a09b88a6e501a5a (patch)
tree01a51cca09ec542c46f5ef5f4758f17ebd0da361
parenta2718204cd68a74925e1dff1892401dc9b275fff (diff)
downloadsnap-24476a644e18b526f09dab730a09b88a6e501a5a.tar.gz
snap-24476a644e18b526f09dab730a09b88a6e501a5a.zip
MAP primitive variant for linked lists
-rwxr-xr-xhistory.txt4
-rw-r--r--threads.js64
2 files changed, 59 insertions, 9 deletions
diff --git a/history.txt b/history.txt
index 9525554..4d26412 100755
--- a/history.txt
+++ b/history.txt
@@ -1946,3 +1946,7 @@ ______
* Lists: fixed type-issue for linked list indices (thanks, Nate, for reporting it!)
* Threads, Objects: experimental MAP primitive reporter in lists category, visible in dev mode
* Blocks: fixed #199 (can't delete reporter with attached comment via context menu)
+
+131009
+------
+* Theads: added a variant for linked lists to the experimental MAP primitive reporter
diff --git a/threads.js b/threads.js
index ee28e59..8b0e25b 100644
--- a/threads.js
+++ b/threads.js
@@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/
// Global stuff ////////////////////////////////////////////////////////
-modules.threads = '2013-October-08';
+modules.threads = '2013-October-09';
var ThreadManager;
var Process;
@@ -1516,15 +1516,61 @@ Process.prototype.doWaitUntil = function (goalCondition) {
};
Process.prototype.reportMap = function (reporter, list) {
- if (this.context.inputs.length - 2 === list.length()) {
- this.returnValueToParentContext(
- new List(this.context.inputs.slice(2))
- );
- return;
+ // answer a new list containing the results of the reporter applied
+ // to each value of the given list. Distinguish between linked and
+ // arrayed lists.
+ // Note: This method utilizes the current context's inputs array to
+ // manage temporary variables, whose allocation to which slot are
+ // documented in each of the variants' code (linked or arrayed) below
+
+ var next;
+ if (list.isLinked) {
+ // this.context.inputs:
+ // [0] - reporter
+ // [1] - list (original source)
+ // -----------------------------
+ // [2] - result list (target)
+ // [3] - currently last element of result list
+ // [4] - current source list (what's left to map)
+ // [5] - current value of last function call
+
+ if (this.context.inputs.length < 3) {
+ this.context.addInput(new List());
+ this.context.inputs[2].isLinked = true;
+ this.context.addInput(this.context.inputs[2]);
+ this.context.addInput(list);
+ }
+ if (this.context.inputs[4].length() === 0) {
+ this.context.inputs[3].rest = list.cons(this.context.inputs[5]);
+ this.returnValueToParentContext(this.context.inputs[2].cdr());
+ return;
+ }
+ if (this.context.inputs.length > 5) {
+ this.context.inputs[3].rest = list.cons(this.context.inputs[5]);
+ this.context.inputs[3] = this.context.inputs[3].rest;
+ this.context.inputs.splice(5);
+ }
+ next = this.context.inputs[4].at(1);
+ this.context.inputs[4] = this.context.inputs[4].cdr();
+ this.pushContext();
+ this.evaluate(reporter, new List([next]));
+ } else { // arrayed
+ // this.context.inputs:
+ // [0] - reporter
+ // [1] - list (original source)
+ // -----------------------------
+ // [2..n] - result values (target)
+
+ if (this.context.inputs.length - 2 === list.length()) {
+ this.returnValueToParentContext(
+ new List(this.context.inputs.slice(2))
+ );
+ return;
+ }
+ next = list.at(this.context.inputs.length - 1);
+ this.pushContext();
+ this.evaluate(reporter, new List([next]));
}
- var next = list.at(this.context.inputs.length - 1);
- this.pushContext();
- this.evaluate(reporter, new List([next]));
};
// Process interpolated primitives