kopia lustrzana https://github.com/backface/turtlestitch
Fix reporting out of nested custom C-shaped blocks
REPORT now reports to the nearest lexical element expecting an input (which may not be the block holding the REPORT statement, this lets you REPORT out of nested FOR loops). STOP THIS BLOCK behaves as it used to. If you’ve been using REPORT instead of STOP THIS BLOCK, you should migrate.pull/3/merge
rodzic
7b96be6c40
commit
b36a358173
|
@ -2309,3 +2309,11 @@ ______
|
||||||
141008
|
141008
|
||||||
------
|
------
|
||||||
* Objects: fixed #608, #610
|
* Objects: fixed #608, #610
|
||||||
|
|
||||||
|
141106
|
||||||
|
------
|
||||||
|
* Morphic: Enable mouseMove events with right button pressed
|
||||||
|
|
||||||
|
141114
|
||||||
|
------
|
||||||
|
* Threads, Store: Fix reporting out of nested custom C-shaped blocks
|
||||||
|
|
5
store.js
5
store.js
|
@ -61,7 +61,7 @@ SyntaxElementMorph, Variable*/
|
||||||
|
|
||||||
// Global stuff ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.store = '2014-October-01';
|
modules.store = '2014-November-14';
|
||||||
|
|
||||||
|
|
||||||
// XML_Serializer ///////////////////////////////////////////////////////
|
// XML_Serializer ///////////////////////////////////////////////////////
|
||||||
|
@ -1824,9 +1824,8 @@ Context.prototype.toXML = function (serializer) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return serializer.format(
|
return serializer.format(
|
||||||
'<context% ~><inputs>%</inputs><variables>%</variables>' +
|
'<context ~><inputs>%</inputs><variables>%</variables>' +
|
||||||
'%<receiver>%</receiver>%</context>',
|
'%<receiver>%</receiver>%</context>',
|
||||||
this.isLambda ? ' lambda="lambda"' : '',
|
|
||||||
this.inputs.reduce(
|
this.inputs.reduce(
|
||||||
function (xml, input) {
|
function (xml, input) {
|
||||||
return xml + serializer.format('<input>$</input>', input);
|
return xml + serializer.format('<input>$</input>', input);
|
||||||
|
|
176
threads.js
176
threads.js
|
@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/
|
||||||
|
|
||||||
// Global stuff ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.threads = '2014-October-01';
|
modules.threads = '2014-November-15';
|
||||||
|
|
||||||
var ThreadManager;
|
var ThreadManager;
|
||||||
var Process;
|
var Process;
|
||||||
|
@ -586,7 +586,6 @@ Process.prototype.evaluateInput = function (input) {
|
||||||
) || (input instanceof CSlotMorph && !input.isStatic)) {
|
) || (input instanceof CSlotMorph && !input.isStatic)) {
|
||||||
// I know, this still needs yet to be done right....
|
// I know, this still needs yet to be done right....
|
||||||
ans = this.reify(ans, new List());
|
ans = this.reify(ans, new List());
|
||||||
ans.isImplicitLambda = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,8 +596,6 @@ Process.prototype.evaluateInput = function (input) {
|
||||||
Process.prototype.evaluateSequence = function (arr) {
|
Process.prototype.evaluateSequence = function (arr) {
|
||||||
var pc = this.context.pc,
|
var pc = this.context.pc,
|
||||||
outer = this.context.outerContext,
|
outer = this.context.outerContext,
|
||||||
isLambda = this.context.isLambda,
|
|
||||||
isImplicitLambda = this.context.isImplicitLambda,
|
|
||||||
isCustomBlock = this.context.isCustomBlock;
|
isCustomBlock = this.context.isCustomBlock;
|
||||||
if (pc === (arr.length - 1)) { // tail call elimination
|
if (pc === (arr.length - 1)) { // tail call elimination
|
||||||
this.context = new Context(
|
this.context = new Context(
|
||||||
|
@ -607,8 +604,6 @@ Process.prototype.evaluateSequence = function (arr) {
|
||||||
this.context.outerContext,
|
this.context.outerContext,
|
||||||
this.context.receiver
|
this.context.receiver
|
||||||
);
|
);
|
||||||
this.context.isLambda = isLambda;
|
|
||||||
this.context.isImplicitLambda = isImplicitLambda;
|
|
||||||
this.context.isCustomBlock = isCustomBlock;
|
this.context.isCustomBlock = isCustomBlock;
|
||||||
} else {
|
} else {
|
||||||
if (pc >= arr.length) {
|
if (pc >= arr.length) {
|
||||||
|
@ -626,8 +621,8 @@ Process.prototype.evaluateSequence = function (arr) {
|
||||||
Caution: we cannot just revert to this version of the method, because to make
|
Caution: we cannot just revert to this version of the method, because to make
|
||||||
tail call elimination work many tweaks had to be done to various primitives.
|
tail call elimination work many tweaks had to be done to various primitives.
|
||||||
For the most part these tweaks are about schlepping the outer context (for
|
For the most part these tweaks are about schlepping the outer context (for
|
||||||
the variable bindings) and the isLambda flag along, and are indicated by a
|
the variable bindings) and the isCustomBlock flag along, and are indicated
|
||||||
short comment in the code. But to really revert would take a good measure
|
by a short comment in the code. But to really revert would take a good measure
|
||||||
of trial and error as well as debugging. In the developers file archive there
|
of trial and error as well as debugging. In the developers file archive there
|
||||||
is a version of threads.js dated 120119(2) which basically resembles the
|
is a version of threads.js dated 120119(2) which basically resembles the
|
||||||
last version before introducing tail call optimization on 120123.
|
last version before introducing tail call optimization on 120123.
|
||||||
|
@ -679,6 +674,11 @@ Process.prototype.doYield = function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Process.prototype.exitReporter = function () {
|
||||||
|
// catch-tag for REPORT and STOP BLOCK primitives
|
||||||
|
this.popContext();
|
||||||
|
};
|
||||||
|
|
||||||
// Process Exception Handling
|
// Process Exception Handling
|
||||||
|
|
||||||
Process.prototype.handleError = function (error, element) {
|
Process.prototype.handleError = function (error, element) {
|
||||||
|
@ -757,9 +757,15 @@ Process.prototype.reportJSFunction = function (parmNames, body) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
Process.prototype.doRun = function (context, args, isCustomBlock) {
|
Process.prototype.doRun = function (context, args, isCustomBlock) {
|
||||||
return this.evaluate(context, args, true, isCustomBlock);
|
return this.evaluate(context, args, true, isCustomBlock);
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
Process.prototype.doRun = function (context, args) {
|
||||||
|
return this.evaluate(context, args, true);
|
||||||
|
};
|
||||||
|
|
||||||
Process.prototype.evaluate = function (
|
Process.prototype.evaluate = function (
|
||||||
context,
|
context,
|
||||||
|
@ -783,6 +789,7 @@ Process.prototype.evaluate = function (
|
||||||
var outer = new Context(null, null, context.outerContext),
|
var outer = new Context(null, null, context.outerContext),
|
||||||
runnable,
|
runnable,
|
||||||
extra,
|
extra,
|
||||||
|
exit,
|
||||||
parms = args.asArray(),
|
parms = args.asArray(),
|
||||||
i,
|
i,
|
||||||
value;
|
value;
|
||||||
|
@ -798,23 +805,17 @@ Process.prototype.evaluate = function (
|
||||||
);
|
);
|
||||||
extra = new Context(runnable, 'doYield');
|
extra = new Context(runnable, 'doYield');
|
||||||
|
|
||||||
/*
|
// Note: if the context's expression is a ReporterBlockMorph,
|
||||||
Note: if the context's expression is a ReporterBlockMorph,
|
// the extra context gets popped off immediately without taking
|
||||||
the extra context gets popped off immediately without taking
|
// effect (i.e. it doesn't yield within evaluating a stack of
|
||||||
effect (i.e. it doesn't yield within evaluating a stack of
|
// nested reporters)
|
||||||
nested reporters)
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (isCommand || (context.expression instanceof ReporterBlockMorph)) {
|
if (context.expression instanceof ReporterBlockMorph) {
|
||||||
this.context.parentContext = extra;
|
this.context.parentContext = extra;
|
||||||
} else {
|
} else {
|
||||||
this.context.parentContext = runnable;
|
this.context.parentContext = runnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
runnable.isLambda = true;
|
|
||||||
runnable.isImplicitLambda = context.isImplicitLambda;
|
|
||||||
runnable.isCustomBlock = false;
|
|
||||||
|
|
||||||
// assign parameters if any were passed
|
// assign parameters if any were passed
|
||||||
if (parms.length > 0) {
|
if (parms.length > 0) {
|
||||||
|
|
||||||
|
@ -858,6 +859,18 @@ Process.prototype.evaluate = function (
|
||||||
|
|
||||||
if (runnable.expression instanceof CommandBlockMorph) {
|
if (runnable.expression instanceof CommandBlockMorph) {
|
||||||
runnable.expression = runnable.expression.blockSequence();
|
runnable.expression = runnable.expression.blockSequence();
|
||||||
|
|
||||||
|
// insert a reporter exit tag for the
|
||||||
|
// CALL SCRIPT primitive variant
|
||||||
|
if (!isCommand) {
|
||||||
|
exit = new Context(
|
||||||
|
runnable.parentContext,
|
||||||
|
'exitReporter',
|
||||||
|
outer,
|
||||||
|
outer.receiver
|
||||||
|
);
|
||||||
|
runnable.parentContext = exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -879,8 +892,6 @@ Process.prototype.fork = function (context, args) {
|
||||||
stage = this.homeContext.receiver.parentThatIsA(StageMorph),
|
stage = this.homeContext.receiver.parentThatIsA(StageMorph),
|
||||||
proc = new Process();
|
proc = new Process();
|
||||||
|
|
||||||
runnable.isLambda = true;
|
|
||||||
|
|
||||||
// assign parameters if any were passed
|
// assign parameters if any were passed
|
||||||
if (parms.length > 0) {
|
if (parms.length > 0) {
|
||||||
|
|
||||||
|
@ -933,68 +944,39 @@ Process.prototype.fork = function (context, args) {
|
||||||
stage.threads.processes.push(proc);
|
stage.threads.processes.push(proc);
|
||||||
};
|
};
|
||||||
|
|
||||||
Process.prototype.doReport = function (value, isCSlot) {
|
Process.prototype.doReport = function (value) {
|
||||||
while (this.context && !this.context.isLambda) {
|
while (this.context && this.context.expression !== 'exitReporter') {
|
||||||
if (this.context.expression === 'doStopWarping') {
|
if (this.context.expression === 'doStopWarping') {
|
||||||
this.doStopWarping();
|
this.doStopWarping();
|
||||||
} else {
|
} else {
|
||||||
this.popContext();
|
this.popContext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.context && this.context.isImplicitLambda) {
|
|
||||||
if (this.context.expression === 'doStopWarping') {
|
|
||||||
this.doStopWarping();
|
|
||||||
} else {
|
|
||||||
this.popContext();
|
|
||||||
}
|
|
||||||
return this.doReport(value, true);
|
|
||||||
}
|
|
||||||
if (this.context && this.context.isCustomBlock) {
|
|
||||||
// now I'm back at the custom block sequence.
|
|
||||||
// advance my pc to my expression's length
|
|
||||||
this.context.pc = this.context.expression.length - 1;
|
|
||||||
}
|
|
||||||
if (isCSlot) {
|
|
||||||
if (this.context &&
|
|
||||||
this.context.parentContext &&
|
|
||||||
this.context.parentContext.expression instanceof Array) {
|
|
||||||
this.popContext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
Process.prototype.doStopBlock = function () {
|
Process.prototype.doStopBlock = function () {
|
||||||
this.doReport();
|
while (this.context && !this.context.isCustomBlock) {
|
||||||
|
if (this.context.expression === 'doStopWarping') {
|
||||||
|
this.doStopWarping();
|
||||||
|
} else {
|
||||||
|
this.popContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process evaluation variants, commented out for now (redundant)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Process.prototype.doRunWithInputList = function (context, args) {
|
|
||||||
// provide an extra selector for the palette
|
|
||||||
return this.doRun(context, args);
|
|
||||||
};
|
|
||||||
|
|
||||||
Process.prototype.evaluateWithInputList = function (context, args) {
|
|
||||||
// provide an extra selector for the palette
|
|
||||||
return this.evaluate(context, args);
|
|
||||||
};
|
|
||||||
|
|
||||||
Process.prototype.forkWithInputList = function (context, args) {
|
|
||||||
// provide an extra selector for the palette
|
|
||||||
return this.fork(context, args);
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Process continuations primitives
|
// Process continuations primitives
|
||||||
|
|
||||||
Process.prototype.doCallCC = function (aContext) {
|
Process.prototype.doCallCC = function (aContext, isReporter) {
|
||||||
this.evaluate(aContext, new List([this.context.continuation()]));
|
this.evaluate(
|
||||||
|
aContext,
|
||||||
|
new List([this.context.continuation()]),
|
||||||
|
!isReporter
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Process.prototype.reportCallCC = function (aContext) {
|
Process.prototype.reportCallCC = function (aContext) {
|
||||||
this.doCallCC(aContext);
|
this.doCallCC(aContext, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
Process.prototype.runContinuation = function (aContext, args) {
|
Process.prototype.runContinuation = function (aContext, args) {
|
||||||
|
@ -1017,6 +999,7 @@ Process.prototype.evaluateCustomBlock = function () {
|
||||||
args = new List(this.context.inputs),
|
args = new List(this.context.inputs),
|
||||||
parms = args.asArray(),
|
parms = args.asArray(),
|
||||||
runnable,
|
runnable,
|
||||||
|
exit,
|
||||||
extra,
|
extra,
|
||||||
i,
|
i,
|
||||||
value,
|
value,
|
||||||
|
@ -1024,7 +1007,7 @@ Process.prototype.evaluateCustomBlock = function () {
|
||||||
|
|
||||||
if (!context) {return null; }
|
if (!context) {return null; }
|
||||||
outer = new Context();
|
outer = new Context();
|
||||||
outer.receiver = this.context.receiver; // || this.homeContext.receiver;
|
outer.receiver = this.context.receiver;
|
||||||
outer.variables.parentFrame = outer.receiver ?
|
outer.variables.parentFrame = outer.receiver ?
|
||||||
outer.receiver.variables : null;
|
outer.receiver.variables : null;
|
||||||
|
|
||||||
|
@ -1032,15 +1015,11 @@ Process.prototype.evaluateCustomBlock = function () {
|
||||||
this.context.parentContext,
|
this.context.parentContext,
|
||||||
context.expression,
|
context.expression,
|
||||||
outer,
|
outer,
|
||||||
outer.receiver,
|
outer.receiver
|
||||||
true // is custom block
|
|
||||||
);
|
);
|
||||||
extra = new Context(runnable, 'doYield');
|
|
||||||
|
|
||||||
this.context.parentContext = extra;
|
|
||||||
|
|
||||||
runnable.isLambda = true;
|
|
||||||
runnable.isCustomBlock = true;
|
runnable.isCustomBlock = true;
|
||||||
|
extra = new Context(runnable, 'doYield');
|
||||||
|
this.context.parentContext = extra;
|
||||||
|
|
||||||
// passing parameters if any were passed
|
// passing parameters if any were passed
|
||||||
if (parms.length > 0) {
|
if (parms.length > 0) {
|
||||||
|
@ -1064,6 +1043,18 @@ Process.prototype.evaluateCustomBlock = function () {
|
||||||
|
|
||||||
if (runnable.expression instanceof CommandBlockMorph) {
|
if (runnable.expression instanceof CommandBlockMorph) {
|
||||||
runnable.expression = runnable.expression.blockSequence();
|
runnable.expression = runnable.expression.blockSequence();
|
||||||
|
|
||||||
|
// insert a reporter exit tag for the
|
||||||
|
// CALL SCRIPT primitive variant
|
||||||
|
if (this.context.expression.definition.type !== 'command') {
|
||||||
|
exit = new Context(
|
||||||
|
runnable.parentContext,
|
||||||
|
'exitReporter',
|
||||||
|
outer,
|
||||||
|
outer.receiver
|
||||||
|
);
|
||||||
|
runnable.parentContext = exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1308,16 +1299,12 @@ Process.prototype.reportListContainsItem = function (list, element) {
|
||||||
Process.prototype.doIf = function () {
|
Process.prototype.doIf = function () {
|
||||||
var args = this.context.inputs,
|
var args = this.context.inputs,
|
||||||
outer = this.context.outerContext, // for tail call elimination
|
outer = this.context.outerContext, // for tail call elimination
|
||||||
isLambda = this.context.isLambda,
|
|
||||||
isImplicitLambda = this.context.isImplicitLambda,
|
|
||||||
isCustomBlock = this.context.isCustomBlock;
|
isCustomBlock = this.context.isCustomBlock;
|
||||||
|
|
||||||
this.popContext();
|
this.popContext();
|
||||||
if (args[0]) {
|
if (args[0]) {
|
||||||
if (args[1]) {
|
if (args[1]) {
|
||||||
this.pushContext(args[1].blockSequence(), outer);
|
this.pushContext(args[1].blockSequence(), outer);
|
||||||
this.context.isLambda = isLambda;
|
|
||||||
this.context.isImplicitLambda = isImplicitLambda;
|
|
||||||
this.context.isCustomBlock = isCustomBlock;
|
this.context.isCustomBlock = isCustomBlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1327,8 +1314,6 @@ Process.prototype.doIf = function () {
|
||||||
Process.prototype.doIfElse = function () {
|
Process.prototype.doIfElse = function () {
|
||||||
var args = this.context.inputs,
|
var args = this.context.inputs,
|
||||||
outer = this.context.outerContext, // for tail call elimination
|
outer = this.context.outerContext, // for tail call elimination
|
||||||
isLambda = this.context.isLambda,
|
|
||||||
isImplicitLambda = this.context.isImplicitLambda,
|
|
||||||
isCustomBlock = this.context.isCustomBlock;
|
isCustomBlock = this.context.isCustomBlock;
|
||||||
|
|
||||||
this.popContext();
|
this.popContext();
|
||||||
|
@ -1344,8 +1329,6 @@ Process.prototype.doIfElse = function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.context) {
|
if (this.context) {
|
||||||
this.context.isLambda = isLambda;
|
|
||||||
this.context.isImplicitLambda = isImplicitLambda;
|
|
||||||
this.context.isCustomBlock = isCustomBlock;
|
this.context.isCustomBlock = isCustomBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1420,8 +1403,6 @@ Process.prototype.doStopOthers = function (choice) {
|
||||||
Process.prototype.doWarp = function (body) {
|
Process.prototype.doWarp = function (body) {
|
||||||
// execute my contents block atomically (more or less)
|
// execute my contents block atomically (more or less)
|
||||||
var outer = this.context.outerContext, // for tail call elimination
|
var outer = this.context.outerContext, // for tail call elimination
|
||||||
isLambda = this.context.isLambda,
|
|
||||||
isImplicitLambda = this.context.isImplicitLambda,
|
|
||||||
isCustomBlock = this.context.isCustomBlock,
|
isCustomBlock = this.context.isCustomBlock,
|
||||||
stage;
|
stage;
|
||||||
|
|
||||||
|
@ -1438,13 +1419,8 @@ Process.prototype.doWarp = function (body) {
|
||||||
stage.fps = 0; // variable frame rate
|
stage.fps = 0; // variable frame rate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pushContext('doYield');
|
this.pushContext('doYield');
|
||||||
|
|
||||||
this.context.isLambda = isLambda;
|
|
||||||
this.context.isImplicitLambda = isImplicitLambda;
|
|
||||||
this.context.isCustomBlock = isCustomBlock;
|
this.context.isCustomBlock = isCustomBlock;
|
||||||
|
|
||||||
if (!this.isAtomic) {
|
if (!this.isAtomic) {
|
||||||
this.pushContext('doStopWarping');
|
this.pushContext('doStopWarping');
|
||||||
}
|
}
|
||||||
|
@ -1523,28 +1499,19 @@ Process.prototype.doForever = function (body) {
|
||||||
Process.prototype.doRepeat = function (counter, body) {
|
Process.prototype.doRepeat = function (counter, body) {
|
||||||
var block = this.context.expression,
|
var block = this.context.expression,
|
||||||
outer = this.context.outerContext, // for tail call elimination
|
outer = this.context.outerContext, // for tail call elimination
|
||||||
isLambda = this.context.isLambda,
|
|
||||||
isImplicitLambda = this.context.isImplicitLambda,
|
|
||||||
isCustomBlock = this.context.isCustomBlock;
|
isCustomBlock = this.context.isCustomBlock;
|
||||||
|
|
||||||
if (counter < 1) { // was '=== 0', which caused infinite loops on non-ints
|
if (counter < 1) { // was '=== 0', which caused infinite loops on non-ints
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
this.popContext();
|
this.popContext();
|
||||||
|
|
||||||
this.pushContext(block, outer);
|
this.pushContext(block, outer);
|
||||||
|
|
||||||
this.context.isLambda = isLambda;
|
|
||||||
this.context.isImplicitLambda = isImplicitLambda;
|
|
||||||
this.context.isCustomBlock = isCustomBlock;
|
this.context.isCustomBlock = isCustomBlock;
|
||||||
|
|
||||||
this.context.addInput(counter - 1);
|
this.context.addInput(counter - 1);
|
||||||
|
|
||||||
this.pushContext('doYield');
|
this.pushContext('doYield');
|
||||||
if (body) {
|
if (body) {
|
||||||
this.pushContext(body.blockSequence());
|
this.pushContext(body.blockSequence());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pushContext();
|
this.pushContext();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2775,8 +2742,6 @@ Process.prototype.reportFrameCount = function () {
|
||||||
startValue initial value for interpolated operations
|
startValue initial value for interpolated operations
|
||||||
activeAudio audio buffer for interpolated operations, don't persist
|
activeAudio audio buffer for interpolated operations, don't persist
|
||||||
activeNote audio oscillator for interpolated ops, don't persist
|
activeNote audio oscillator for interpolated ops, don't persist
|
||||||
isLambda marker for return ops
|
|
||||||
isImplicitLambda marker for return ops
|
|
||||||
isCustomBlock marker for return ops
|
isCustomBlock marker for return ops
|
||||||
emptySlots caches the number of empty slots for reification
|
emptySlots caches the number of empty slots for reification
|
||||||
*/
|
*/
|
||||||
|
@ -2801,22 +2766,18 @@ function Context(
|
||||||
this.startTime = null;
|
this.startTime = null;
|
||||||
this.activeAudio = null;
|
this.activeAudio = null;
|
||||||
this.activeNote = null;
|
this.activeNote = null;
|
||||||
this.isLambda = false; // marks the end of a lambda
|
|
||||||
this.isImplicitLambda = false; // marks the end of a C-shaped slot
|
|
||||||
this.isCustomBlock = false; // marks the end of a custom block's stack
|
this.isCustomBlock = false; // marks the end of a custom block's stack
|
||||||
this.emptySlots = 0; // used for block reification
|
this.emptySlots = 0; // used for block reification
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.prototype.toString = function () {
|
Context.prototype.toString = function () {
|
||||||
var pref = this.isLambda ? '\u03BB-' : '',
|
var expr = this.expression;
|
||||||
expr = this.expression;
|
|
||||||
|
|
||||||
if (expr instanceof Array) {
|
if (expr instanceof Array) {
|
||||||
if (expr.length > 0) {
|
if (expr.length > 0) {
|
||||||
expr = '[' + expr[0] + ']';
|
expr = '[' + expr[0] + ']';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pref + 'Context >> ' + expr + ' ' + this.variables;
|
return 'Context >> ' + expr + ' ' + this.variables;
|
||||||
};
|
};
|
||||||
|
|
||||||
Context.prototype.image = function () {
|
Context.prototype.image = function () {
|
||||||
|
@ -2872,6 +2833,9 @@ Context.prototype.continuation = function () {
|
||||||
} else {
|
} else {
|
||||||
return new Context(null, 'doStop');
|
return new Context(null, 'doStop');
|
||||||
}
|
}
|
||||||
|
if (cont.expression === 'exitReporter') {
|
||||||
|
return cont.continuation();
|
||||||
|
}
|
||||||
cont = cont.copyForContinuation();
|
cont = cont.copyForContinuation();
|
||||||
cont.isContinuation = true;
|
cont.isContinuation = true;
|
||||||
return cont;
|
return cont;
|
||||||
|
|
Ładowanie…
Reference in New Issue