extended implicit parameters handling for experimental JS-Compiler

upd4.2
Jens Mönig 2018-03-22 14:55:28 +01:00
rodzic 1a0c9fe6b8
commit c313ce139f
2 zmienionych plików z 38 dodań i 8 usunięć

Wyświetl plik

@ -4056,3 +4056,7 @@ in development:
------ ------
* Threads: refactored experimental JS-compiler * Threads: refactored experimental JS-compiler
* Threads: enabled variables access for experimental JS-compiler * Threads: enabled variables access for experimental JS-compiler
180322
------
* Threads: extended implicit parameters handling for experimental JS-Compiler

Wyświetl plik

@ -62,7 +62,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy,
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph,
TableFrameMorph, ColorSlotMorph, isSnapObject*/ TableFrameMorph, ColorSlotMorph, isSnapObject*/
modules.threads = '2018-March-20'; modules.threads = '2018-March-22';
var ThreadManager; var ThreadManager;
var Process; var Process;
@ -3758,9 +3758,13 @@ Process.prototype.unflash = function () {
*** highly experimental and heavily under construction *** *** highly experimental and heavily under construction ***
*/ */
Process.prototype.reportCompiled = function (context) { Process.prototype.reportCompiled = function (context, implicitParamCount) {
// implicitParamCount is optional and indicates the number of
// expected parameters, if any. This is only used to handle
// implicit (empty slot) parameters and can otherwise be
// ignored
this.assertType(context, ['reporter', 'predicate']); this.assertType(context, ['reporter', 'predicate']);
return new JSCompiler(this).compileFunction(context); return new JSCompiler(this).compileFunction(context, implicitParamCount);
}; };
Process.prototype.getVarNamed = function (name) { Process.prototype.getVarNamed = function (name) {
@ -4223,20 +4227,24 @@ function JSCompiler(aProcess) {
this.process = aProcess; this.process = aProcess;
this.source = null; // a context this.source = null; // a context
this.gensyms = null; // temp dictionary for parameter substitutions this.gensyms = null; // temp dictionary for parameter substitutions
this.implicitParams = null;
this.paramCount = null;
} }
JSCompiler.prototype.toString = function () { JSCompiler.prototype.toString = function () {
return 'a JSCompiler'; return 'a JSCompiler';
}; };
JSCompiler.prototype.compileFunction = function (aContext) { JSCompiler.prototype.compileFunction = function (aContext, implicitParamCount) {
var block = aContext.expression, var block = aContext.expression,
parameters = aContext.inputs, parameters = aContext.inputs,
parms = [], parms = [],
hasEmptySlots = false, hasEmptySlots = false,
myself = this; myself = this,
i;
this.source = aContext; this.source = aContext;
this.implicitParams = implicitParamCount || 1;
// scan for empty input slots // scan for empty input slots
hasEmptySlots = !isNil(detect( hasEmptySlots = !isNil(detect(
@ -4246,6 +4254,7 @@ JSCompiler.prototype.compileFunction = function (aContext) {
// translate formal parameters into gensyms // translate formal parameters into gensyms
this.gensyms = {}; this.gensyms = {};
this.paramCount = 0;
if (parameters.length) { if (parameters.length) {
// test for conflicts // test for conflicts
if (hasEmptySlots) { if (hasEmptySlots) {
@ -4262,9 +4271,15 @@ JSCompiler.prototype.compileFunction = function (aContext) {
myself.gensyms[pName] = pn; myself.gensyms[pName] = pn;
}); });
} else if (hasEmptySlots) { } else if (hasEmptySlots) {
if (this.implicitParams > 1) {
for (i = 0; i < this.implicitParams; i += 1) {
parms.push('p' + i);
}
} else {
// allow for a single implicit formal parameter // allow for a single implicit formal parameter
parms = ['p0']; parms = ['p0'];
} }
}
// compile using gensyms // compile using gensyms
return Function.apply( return Function.apply(
@ -4323,6 +4338,17 @@ JSCompiler.prototype.compileInput = function (inp) {
if (inp.isEmptySlot && inp.isEmptySlot()) { if (inp.isEmptySlot && inp.isEmptySlot()) {
// implicit formal parameter // implicit formal parameter
if (this.implicitParams > 1) {
if (this.paramCount < this.implicitParams) {
this.paramCount += 1;
return 'p' + (this.paramCount - 1);
}
throw new Error(
localize('expecting') + ' ' + this.implicitParams + ' '
+ localize('input(s), but getting') + ' '
+ this.paramCount
);
}
return 'p0'; return 'p0';
} else if (inp instanceof MultiArgMorph) { } else if (inp instanceof MultiArgMorph) {
if (inp.isStatic) { if (inp.isStatic) {