installing on-tick

This commit is contained in:
Danny Yoo 2011-07-14 18:26:56 -04:00
parent 39cec2305b
commit 03165a4191
5 changed files with 283 additions and 30 deletions

View File

@ -4,4 +4,6 @@
(circle 20 'solid 'blue)
;(big-bang 0 (on-tick add1 1))
(big-bang 0 (on-tick add1 1))
"all done"

View File

@ -85,7 +85,11 @@
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,
actualValue) {
raise(MACHINE,
new Error(callerName + ": expected " + expectedTypeName
+ " as argument " + (argumentOffset + 1)
+ " but received " + plt.baselib.format.toWrittenString(actualValue)));
new Error(
plt.baselib.format.format(
"~a: expected ~e as argument ~e but received ~e",
[callerName,
expectedTypeName,
(argumentOffset + 1),
actualValue])));
};
var raiseContextExpectedValuesError = function(MACHINE, expected) {
raise(MACHINE,
new Error("expected " + expected +
" values, received " +
MACHINE.argcount + " values"));
new Error(plt.baselib.format.format(
"expected ~e values, received ~e values"
[expected,
MACHINE.argcount])));
};
var raiseArityMismatchError = function(MACHINE, proc, expected, received) {
raise(MACHINE,
new Error(proc.displayName + ": " + "expected " + expected
+ " value(s), received " + received + " value(s)"));
new Error(plt.baselib.format.format(
"~a: expected ~e value(s), received ~e value(s)",
[proc.displayName,
expected ,
received])))
};
var raiseOperatorApplicationError = function(MACHINE, operator) {
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) {
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) {
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])));
};

View File

@ -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);
// }) ]);

View File

@ -1,26 +1,146 @@
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) {
PAUSE(function(restart) {
var bigBangController;
var onBreak = function() {
bigBangController.breaker();
}
state.addBreakRequestedListener(onBreak);
bigBangController = rawJsworld.bigBang(
initW,
state.getToplevelNodeHook()(),
unwrappedConfigs,
caller,
function(v) {
state.removeBreakRequestedListener(onBreak);
restarter(v);
},
onFail);
var finalWorldValue = "not done yet";
// Once we finally get a value back, we can call
// restart at this point and finish the call to
// big-bang.
restart(function(MACHINE) {
finalizeClosureCall(
MACHINE,
finalWorldValue);
});
// var onBreak = function() {
// 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))
}
);
};

View File

@ -8,8 +8,8 @@
"private/raw-jsworld.js"
;; We add Whalesong-specific things here.
;;"kernel.js"
;;"js-impl.js"
"kernel.js"
"js-impl.js"
)
#:provided-values (big-bang
on-tick))