installing on-tick
This commit is contained in:
parent
39cec2305b
commit
03165a4191
|
@ -4,4 +4,6 @@
|
||||||
|
|
||||||
|
|
||||||
(circle 20 'solid 'blue)
|
(circle 20 'solid 'blue)
|
||||||
;(big-bang 0 (on-tick add1 1))
|
(big-bang 0 (on-tick add1 1))
|
||||||
|
|
||||||
|
"all done"
|
|
@ -85,7 +85,11 @@
|
||||||
|
|
||||||
|
|
||||||
var raiseUnboundToplevelError = function(MACHINE, name) {
|
var raiseUnboundToplevelError = function(MACHINE, name) {
|
||||||
raise(MACHINE, new Error("Not bound: " + name));
|
raise(MACHINE,
|
||||||
|
new Error(
|
||||||
|
plt.baselib.format.foramt(
|
||||||
|
"Not bound: ~a",
|
||||||
|
[name])));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,37 +99,54 @@
|
||||||
argumentOffset,
|
argumentOffset,
|
||||||
actualValue) {
|
actualValue) {
|
||||||
raise(MACHINE,
|
raise(MACHINE,
|
||||||
new Error(callerName + ": expected " + expectedTypeName
|
new Error(
|
||||||
+ " as argument " + (argumentOffset + 1)
|
plt.baselib.format.format(
|
||||||
+ " but received " + plt.baselib.format.toWrittenString(actualValue)));
|
"~a: expected ~e as argument ~e but received ~e",
|
||||||
|
[callerName,
|
||||||
|
expectedTypeName,
|
||||||
|
(argumentOffset + 1),
|
||||||
|
actualValue])));
|
||||||
};
|
};
|
||||||
|
|
||||||
var raiseContextExpectedValuesError = function(MACHINE, expected) {
|
var raiseContextExpectedValuesError = function(MACHINE, expected) {
|
||||||
raise(MACHINE,
|
raise(MACHINE,
|
||||||
new Error("expected " + expected +
|
new Error(plt.baselib.format.format(
|
||||||
" values, received " +
|
"expected ~e values, received ~e values"
|
||||||
MACHINE.argcount + " values"));
|
[expected,
|
||||||
|
MACHINE.argcount])));
|
||||||
};
|
};
|
||||||
|
|
||||||
var raiseArityMismatchError = function(MACHINE, proc, expected, received) {
|
var raiseArityMismatchError = function(MACHINE, proc, expected, received) {
|
||||||
raise(MACHINE,
|
raise(MACHINE,
|
||||||
new Error(proc.displayName + ": " + "expected " + expected
|
new Error(plt.baselib.format.format(
|
||||||
+ " value(s), received " + received + " value(s)"));
|
"~a: expected ~e value(s), received ~e value(s)",
|
||||||
|
[proc.displayName,
|
||||||
|
expected ,
|
||||||
|
received])))
|
||||||
};
|
};
|
||||||
|
|
||||||
var raiseOperatorApplicationError = function(MACHINE, operator) {
|
var raiseOperatorApplicationError = function(MACHINE, operator) {
|
||||||
raise(MACHINE,
|
raise(MACHINE,
|
||||||
new Error("not a procedure: " + plt.baselib.format.toWrittenString(operator)));
|
new Error(
|
||||||
|
plt.baselib.format.format(
|
||||||
|
"not a procedure: ~e",
|
||||||
|
[operator])));
|
||||||
};
|
};
|
||||||
|
|
||||||
var raiseOperatorIsNotClosure = function(MACHINE, operator) {
|
var raiseOperatorIsNotClosure = function(MACHINE, operator) {
|
||||||
raise(MACHINE,
|
raise(MACHINE,
|
||||||
new Error("not a closure: " + plt.baselib.format.toWrittenString(operator)));
|
new Error(
|
||||||
|
plt.baselib.format.format(
|
||||||
|
"not a closure: ~e",
|
||||||
|
[operator])));
|
||||||
};
|
};
|
||||||
|
|
||||||
var raiseOperatorIsNotPrimitiveProcedure = function(MACHINE, operator) {
|
var raiseOperatorIsNotPrimitiveProcedure = function(MACHINE, operator) {
|
||||||
raise(MACHINE,
|
raise(MACHINE,
|
||||||
new Error("not a primitive procedure: " + plt.baselib.format.toWrittenString(operator)));
|
new Error(
|
||||||
|
plt.baselib.format.format(
|
||||||
|
"not a primitive procedure: ~e",
|
||||||
|
[operator])));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
110
world/js-impl.js
110
world/js-impl.js
|
@ -0,0 +1,110 @@
|
||||||
|
var PAUSE = plt.runtime.PAUSE;
|
||||||
|
var makeClosure = plt.baselib.functions.makeClosure;
|
||||||
|
var makeRational = plt.baselib.numbers.makeRational;
|
||||||
|
var finalizeClosureCall = plt.baselib.functions.finalizeClosureCall;
|
||||||
|
var makePrimitiveProcedure = plt.baselib.functions.makePrimitiveProcedure;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var checkProcedure = plt.baselib.check.checkProcedure;
|
||||||
|
var checkNonNegativeReal = plt.baselib.check.checkNonNegativeReal;
|
||||||
|
|
||||||
|
|
||||||
|
// The default tick delay is 28 times a second.
|
||||||
|
var DEFAULT_TICK_DELAY = makeRational(1, 28);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
EXPORTS['big-bang'] =
|
||||||
|
makeClosure(
|
||||||
|
'big-bang',
|
||||||
|
plt.baselib.arity.makeArityAtLeast(1),
|
||||||
|
function(MACHINE) {
|
||||||
|
var initialWorldValue = MACHINE.env[MACHINE.env.length - 1];
|
||||||
|
var handlers = [];
|
||||||
|
for (var i = 1; i < MACHINE.argcount; i++) {
|
||||||
|
// FIXME: typecheck for configuration options
|
||||||
|
handlers.push(MACHINE.env[MACHINE.env.length - 1 - i]);
|
||||||
|
}
|
||||||
|
bigBang(initialWorldValue, handlers);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
EXPORTS['on-tick'] =
|
||||||
|
makePrimitiveProcedure(
|
||||||
|
'on-tick',
|
||||||
|
plt.baselib.lists.makeList(1, 2),
|
||||||
|
function(MACHINE) {
|
||||||
|
if (MACHINE.argcount === 1) {
|
||||||
|
var f = checkProcedure(MACHINE, "on-tick", 0);
|
||||||
|
return new OnTick(f, DEFAULT_TICK_DELAY);
|
||||||
|
} else if (MACHINE.argcount === 2) {
|
||||||
|
var f = checkProcedure(MACHINE, "on-tick", 0);
|
||||||
|
var delay = checkNonNegativeReal(MACHINE, "on-tick", 1);
|
||||||
|
return new OnTick(f, delay);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// EXPORTS['on-tick'] =
|
||||||
|
// new CasePrimitive(
|
||||||
|
// 'on-tick',
|
||||||
|
// [new PrimProc('on-tick',
|
||||||
|
// 1,
|
||||||
|
// false, false,
|
||||||
|
// function(f) {
|
||||||
|
// check(f, isFunction, "on-tick", "procedure", 1);
|
||||||
|
// return new OnTickBang(f,
|
||||||
|
// new PrimProc('', 1, false, false,
|
||||||
|
// function(w) { return types.effectDoNothing(); }),
|
||||||
|
// DEFAULT_TICK_DELAY);
|
||||||
|
// }),
|
||||||
|
// new PrimProc('on-tick',
|
||||||
|
// 2,
|
||||||
|
// false, false,
|
||||||
|
// function(f, aDelay) {
|
||||||
|
// check(f, isFunction, "on-tick", "procedure", 1, arguments);
|
||||||
|
// check(aDelay, isNumber, "on-tick", "number", 2, arguments);
|
||||||
|
// return new OnTickBang(f,
|
||||||
|
// new PrimProc('', 1, false, false,
|
||||||
|
// function(w) { return types.effectDoNothing(); }),
|
||||||
|
// aDelay);
|
||||||
|
// }) ]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// EXPORTS['on-tick!'] =
|
||||||
|
// new CasePrimitive('on-tick!',
|
||||||
|
// [new PrimProc('on-tick!',
|
||||||
|
// 2,
|
||||||
|
// false, false,
|
||||||
|
// function(handler, effectHandler) {
|
||||||
|
// check(handler, isFunction, "on-tick!", "procedure", 1, arguments);
|
||||||
|
// check(effectHandler, isFunction, "on-tick!","procedure", 2, arguments);
|
||||||
|
// return new OnTickBang(handler, effectHandler, DEFAULT_TICK_DELAY);
|
||||||
|
// }),
|
||||||
|
// new PrimProc('on-tick!',
|
||||||
|
// 3,
|
||||||
|
// false, false,
|
||||||
|
// function(handler, effectHandler, aDelay) {
|
||||||
|
// check(handler, isFunction, "on-tick!", "procedure", 1, arguments);
|
||||||
|
// check(effectHandler, isFunction, "on-tick!","procedure", 2, arguments);
|
||||||
|
// check(aDelay, isNumber, "on-tick!", "number", 3, arguments);
|
||||||
|
// return new OnTickBang(handler, effectHandler, aDelay);
|
||||||
|
// }) ]);
|
150
world/kernel.js
150
world/kernel.js
|
@ -1,26 +1,146 @@
|
||||||
|
|
||||||
|
|
||||||
var PAUSE = plt.runtime.PAUSE;
|
var PAUSE = plt.runtime.PAUSE;
|
||||||
|
var EMPTY = plt.baselib.lists.EMPTY;
|
||||||
|
var isString = plt.baselib.strings.isString;
|
||||||
|
var isBoolean = function(x) { return x === true || x === false; }
|
||||||
|
var isSymbol = plt.baselib.symbols.isSymbol;
|
||||||
|
var makePair = plt.baselib.lists.makePair;
|
||||||
|
var makeList = plt.baselib.lists.makeList;
|
||||||
|
var makeRational = plt.baselib.numbers.makeRational;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var finalizeClosureCall = plt.baselib.functions.finalizeClosureCall;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var bigBang = function(MACHINE, initW, handlers) {
|
var bigBang = function(MACHINE, initW, handlers) {
|
||||||
PAUSE(function(restart) {
|
PAUSE(function(restart) {
|
||||||
var bigBangController;
|
|
||||||
var onBreak = function() {
|
var finalWorldValue = "not done yet";
|
||||||
bigBangController.breaker();
|
// Once we finally get a value back, we can call
|
||||||
}
|
// restart at this point and finish the call to
|
||||||
state.addBreakRequestedListener(onBreak);
|
// big-bang.
|
||||||
bigBangController = rawJsworld.bigBang(
|
restart(function(MACHINE) {
|
||||||
initW,
|
finalizeClosureCall(
|
||||||
state.getToplevelNodeHook()(),
|
MACHINE,
|
||||||
unwrappedConfigs,
|
finalWorldValue);
|
||||||
caller,
|
});
|
||||||
function(v) {
|
|
||||||
state.removeBreakRequestedListener(onBreak);
|
|
||||||
restarter(v);
|
|
||||||
},
|
// var onBreak = function() {
|
||||||
onFail);
|
// bigBangController.breaker();
|
||||||
|
// }
|
||||||
|
// state.addBreakRequestedListener(onBreak);
|
||||||
|
// var bigBangController = rawJsworld.bigBang(
|
||||||
|
// initW,
|
||||||
|
// state.getToplevelNodeHook()(),
|
||||||
|
// unwrappedConfigs,
|
||||||
|
// caller,
|
||||||
|
// function(v) {
|
||||||
|
// state.removeBreakRequestedListener(onBreak);
|
||||||
|
// restarter(v);
|
||||||
|
// },
|
||||||
|
// onFail);
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Every world configuration function (on-tick, stop-when, ...)
|
||||||
|
// produces a WorldConfigOption instance.
|
||||||
|
var WorldConfigOption = function(name) {
|
||||||
|
this.name = name;
|
||||||
|
};
|
||||||
|
|
||||||
|
WorldConfigOption.prototype.configure = function(config) {
|
||||||
|
throw new Error('unimplemented WorldConfigOption');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
WorldConfigOption.prototype.toDomNode = function(cache) {
|
||||||
|
var span = document.createElement('span');
|
||||||
|
span.appendChild(document.createTextNode("(" + this.name + " ...)"));
|
||||||
|
return span;
|
||||||
|
};
|
||||||
|
|
||||||
|
WorldConfigOption.prototype.toWrittenString = function(cache) {
|
||||||
|
return "(" + this.name + " ...)";
|
||||||
|
};
|
||||||
|
|
||||||
|
WorldConfigOption.prototype.toDisplayedString = function(cache) {
|
||||||
|
return "(" + this.name + " ...)";
|
||||||
|
};
|
||||||
|
|
||||||
|
var isWorldConfigOption = function(x) { return x instanceof WorldConfigOption; };
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
var convertAttribList = function(attribList) {
|
||||||
|
var nextElt;
|
||||||
|
var key, val;
|
||||||
|
var hash = {};
|
||||||
|
while (attribList !== EMPTY) {
|
||||||
|
nextElt = attribList.first;
|
||||||
|
|
||||||
|
key = nextElt.first;
|
||||||
|
val = nextElt.rest.first;
|
||||||
|
|
||||||
|
key = String(key);
|
||||||
|
|
||||||
|
if (isString(val)) {
|
||||||
|
val = String(val);
|
||||||
|
} else if (isBoolean(val)) {
|
||||||
|
// do nothing: the representation is the same.
|
||||||
|
} else if (isSymbol(val)) {
|
||||||
|
if (String(val) === 'true') {
|
||||||
|
val = true;
|
||||||
|
} else if (String(val) === 'false') {
|
||||||
|
val = false;
|
||||||
|
} else {
|
||||||
|
val = String(val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// raise error: neither string nor boolean
|
||||||
|
throw new Error(
|
||||||
|
plt.baselib.format.format(
|
||||||
|
"attribute value ~s neither a string nor a boolean",
|
||||||
|
[val]));
|
||||||
|
}
|
||||||
|
hash[key] = val;
|
||||||
|
attribList = attribList.rest;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
var OnTick = function(handler, aDelay) {
|
||||||
|
WorldConfigOption.call(this, 'on-tick');
|
||||||
|
this.handler = handler;
|
||||||
|
this.aDelay = aDelay;
|
||||||
|
};
|
||||||
|
|
||||||
|
OnTick.prototype = plt.baselib.heir(WorldConfigOption.prototype);
|
||||||
|
|
||||||
|
OnTick.prototype.configure = function(config) {
|
||||||
|
return config.updateAll(
|
||||||
|
{ onTick: this.handler,
|
||||||
|
tickDelay: jsnums.toFixnum(jsnums.multiply(1000, this.aDelay))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
"private/raw-jsworld.js"
|
"private/raw-jsworld.js"
|
||||||
|
|
||||||
;; We add Whalesong-specific things here.
|
;; We add Whalesong-specific things here.
|
||||||
;;"kernel.js"
|
"kernel.js"
|
||||||
;;"js-impl.js"
|
"js-impl.js"
|
||||||
)
|
)
|
||||||
#:provided-values (big-bang
|
#:provided-values (big-bang
|
||||||
on-tick))
|
on-tick))
|
Loading…
Reference in New Issue
Block a user