tweaked hyperization for APL-style scalars (nested single-item lists)

pull/95/head
jmoenig 2020-06-22 09:56:49 +02:00
rodzic ee730138ba
commit 1dade6c03f
3 zmienionych plików z 6762 dodań i 50 usunięć

Wyświetl plik

@ -8,7 +8,7 @@
<script src="src/symbols.js?version=2020-06-17"></script>
<script src="src/widgets.js?version=2020-05-06"></script>
<script src="src/blocks.js?version=2020-06-20"></script>
<script src="src/threads.js?version=2020-06-21"></script>
<script src="src/threads.js?version=2020-06-22"></script>
<script src="src/objects.js?version=2020-06-20"></script>
<script src="src/gui.js?version=2020-06-08"></script>
<script src="src/paint.js?version=2020-05-17"></script>

Wyświetl plik

@ -61,7 +61,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy, Map,
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, Color,
TableFrameMorph, ColorSlotMorph, isSnapObject, newCanvas, Symbol, SVG_Costume*/
modules.threads = '2020-June-21';
modules.threads = '2020-June-22';
var ThreadManager;
var Process;
@ -1915,16 +1915,6 @@ Process.prototype.reportItems = function (indices, list) {
}
};
Process.prototype.rank = function(aList) {
var rank = 0,
cur = aList;
while (cur instanceof List) {
rank += 1;
cur = cur.at(1);
}
return rank;
};
// Process - other basic list accessors
Process.prototype.reportListLength = function (list) {
@ -3552,19 +3542,28 @@ Process.prototype.reportTypeOf = function (thing) {
Process.prototype.hyperDyadic = function (baseOp, a, b) {
// enable dyadic operations to be performed on lists and tables
var len, scalar, i, result;
var len, a_info, b_info, i, result;
if (this.enableHyperOps) {
if (this.isMatrix(a)) {
if (this.isMatrix(b)) {
a_info = this.examine(a);
b_info = this.examine(b);
if (a_info.isScalar && b_info.isScalar &&
(a_info.rank !== b_info.rank)) {
// keep the shape of the higher rank
return this.hyperZip(
baseOp,
a_info.rank > b_info.rank ? a : a_info.leaf,
b_info.rank > a_info.rank ? b : b_info.leaf
);
}
if (a_info.rank > 1) {
if (b_info.rank > 1) {
if (a.length() !== b.length()) {
// test for special cased scalars in single-item lists
scalar = this.scalar(a);
if (!(scalar instanceof Array)) {
return this.hyperDyadic(baseOp, scalar, b);
if (a_info.isScalar) {
return this.hyperDyadic(baseOp, a_info.leaf, b);
}
scalar = this.scalar(b);
if (!(scalar instanceof Array)) {
return this.hyperDyadic(baseOp, a, scalar);
if (b_info.isScalar) {
return this.hyperDyadic(baseOp, a, b_info.leaf);
}
}
// zip both arguments ignoring out-of-bounds indices
@ -3577,16 +3576,14 @@ Process.prototype.hyperDyadic = function (baseOp, a, b) {
}
return new List(result);
}
scalar = this.scalar(a);
if (!(scalar instanceof Array)) {
return this.hyperZip(baseOp, scalar, b);
if (a_info.isScalar) {
return this.hyperZip(baseOp, a_info.leaf, b);
}
return a.map(each => this.hyperDyadic(baseOp, each, b));
}
if (this.isMatrix(b)) {
scalar = this.scalar(b);
if (!(scalar instanceof Array)) {
return this.hyperZip(baseOp, a, scalar);
if (b_info.rank > 1) {
if (b_info.isScalar) {
return this.hyperZip(baseOp, a, b_info.leaf);
}
return b.map(each => this.hyperDyadic(baseOp, a, each));
}
@ -3595,24 +3592,20 @@ Process.prototype.hyperDyadic = function (baseOp, a, b) {
return baseOp(a, b);
};
Process.prototype.isMatrix = function (value) {
return value instanceof List && value.at(1) instanceof List;
};
Process.prototype.hyperZip = function (baseOp, a, b) {
// enable dyadic operations to be performed on lists and tables
var len, scalar, i, result;
var len, i, result,
a_info = this.examine(a),
b_info = this.examine(b);
if (a instanceof List) {
if (b instanceof List) {
if (a.length() !== b.length()) {
// test for special cased scalars in single-item lists
scalar = this.scalar(a);
if (!(scalar instanceof Array)) {
return this.hyperZip(baseOp, scalar, b);
if (a_info.isScalar) {
return this.hyperZip(baseOp, a_info.leaf, b);
}
scalar = this.scalar(b);
if (!(scalar instanceof Array)) {
return this.hyperZip(baseOp, a, scalar);
if (b_info.isScalar) {
return this.hyperZip(baseOp, a, b_info.leaf);
}
}
// zip both arguments ignoring out-of-bounds indices
@ -3633,20 +3626,56 @@ Process.prototype.hyperZip = function (baseOp, a, b) {
return baseOp(a, b);
};
Process.prototype.scalar = function (value) {
// private - answer the value if it is a scalor or
// the leaf scalar element of single-nested lists,
// return [false] if value neither a scalar nor
// a single arbitrarily nested list
if (value instanceof List) {
if (value.length() === 1) {
return this.scalar(value.at(1));
}
return [false];
Process.prototype.dimensions = function (data) {
var dim = [],
cur = data;
while (cur instanceof List) {
dim.push(cur.length());
cur = cur.at(1);
}
return value;
return dim;
};
Process.prototype.isMatrix = function (data) {
return this.rank(data) > 1;
};
Process.prototype.rank = function(data) {
return this.dimensions(data).length;
};
Process.prototype.isScalar = function (data) {
return this.dimensions.every(n => n === 1);
};
Process.prototype.leaf = function (data) {
var cur = data;
while (cur instanceof List) {
cur = cur.at(1);
}
return cur;
};
Process.prototype.examine = function (data) {
var cur = data,
meta = {
rank: 0,
isScalar: true,
leaf: null
};
while (cur instanceof List) {
meta.rank += 1;
if (cur.length() !== 1) {
meta.isScalar = false;
}
cur = cur.at(1);
}
meta.leaf = cur;
return meta;
};
// Process math primtives - arithmetic
Process.prototype.reportSum = function (a, b) {
return this.hyperDyadic(this.reportBasicSum, a, b);
};

6683
src/threads_stable.js 100644

Plik diff jest za duży Load Diff