kopia lustrzana https://github.com/backface/turtlestitch
tweaked hyperization for APL-style scalars (nested single-item lists)
rodzic
ee730138ba
commit
1dade6c03f
|
@ -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>
|
||||
|
|
127
src/threads.js
127
src/threads.js
|
@ -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);
|
||||
};
|
||||
|
|
Plik diff jest za duży
Load Diff
Ładowanie…
Reference in New Issue