summaryrefslogtreecommitdiff
path: root/threads.js
diff options
context:
space:
mode:
Diffstat (limited to 'threads.js')
-rw-r--r--threads.js64
1 files changed, 55 insertions, 9 deletions
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