the runtime includes the libraries from Moby, although they do not use them yet.

This commit is contained in:
Danny Yoo 2011-06-02 14:30:42 -04:00
parent 61fa1f691e
commit 0add763beb
8 changed files with 5813 additions and 5646 deletions

12
NOTES
View File

@ -657,3 +657,15 @@ Other things to consider:
restrictions. restrictions.
Can resources be input-port sources? Can resources be input-port sources?
----------------------------------------------------------------------
I've at least imported the libraries from Moby so that they're loaded
in the same runtime. However, there are some ugly things happening
here: for some reason, there's a circular dependency between types and
helpers. That dependency needs to be cut! I've added a workaround
for now, using the link library to delay initialization until the
modules are present, but this is an unsatisfactory solution. We
really shouldn't get into this problem in the first place... I must
do a lot of code cleanup once things stabilize...

View File

@ -1,6 +1,23 @@
#lang racket/base #lang racket/base
;; Function to get the runtime library. ;; Function to get the runtime library.
;;
;; The resulting Javascript will produce a file that loads:
;;
;;
;; jquery at the the toplevel
;; HashTable at the toplevel
;; jsnums at the toplevel
;;
;; followed by:
;;
;; plt.link
;; plt.helpers
;; plt.types
;; plt.primitives
;; plt.runtime
(require racket/contract (require racket/contract
racket/runtime-path racket/runtime-path
@ -10,7 +27,27 @@
(provide/contract [get-runtime (-> string?)]) (provide/contract [get-runtime (-> string?)])
(define-runtime-path jquery.js "runtime-src/jquery-1.6.1.min.js") (define-runtime-path jquery.js "runtime-src/jquery-1.6.1.min.js")
(define-runtime-path runtime.js "mini-runtime.js") (define-runtime-path hashtable.js "runtime-src/jshashtable-2.1_src.js")
(define-runtime-path jsnums.js "runtime-src/js-numbers.js")
(define-runtime-path link.js "runtime-src/link.js")
(define-runtime-path helpers.js "runtime-src/helpers.js")
(define-runtime-path types.js "runtime-src/types.js")
(define-runtime-path primitives.js "runtime-src/primitives.js")
(define-runtime-path runtime.js "runtime-src/runtime.js")
;; The order matters here. link needs to come near the top, because
;; the other modules below have some circular dependencies that are resolved
;; by link.
(define files (list jquery.js
hashtable.js
jsnums.js
link.js
helpers.js
types.js
primitives.js
runtime.js))
(define (path->string p) (define (path->string p)
@ -19,11 +56,8 @@
(port->string ip)))) (port->string ip))))
(define text (string-append (define text (apply string-append
(path->string jquery.js) (map path->string files)))
(path->string runtime.js)))
(define (get-runtime) (define (get-runtime)

View File

@ -1,441 +1,462 @@
if (! this['plt']) { this['plt'] = {}; }
// Helpers library: includes a bunch of helper functions that will be used
//
//
// FIXME: there's a circularity between this module and types, and that circularly
// should not be there!
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// File of helper functions for primitives and world. // File of helper functions for primitives and world.
var helpers = {};
(function() { (function(scope) {
var helpers = {};
scope.helpers = helpers;
var format = function(formatStr, args, functionName) {
var throwFormatError = function() {
functionName = functionName || '#<procedure>';
var matches = formatStr.match(new RegExp('~[sSaA]', 'g'));
var expectedNumberOfArgs = matches == null ? 0 : matches.length;
var errorStrBuffer = [functionName + ': format string requires ' + expectedNumberOfArgs
+ ' arguments, given ' + args.length + '; arguments were:',
types.toWrittenString(formatStr)];
for (var i = 0; i < args.length; i++) {
errorStrBuffer.push( types.toWrittenString(args[i]) );
}
raise( types.incompleteExn(types.exnFailContract, errorStrBuffer.join(' '), []) ); // types refers to plt.types, and will be initialized later.
var types = scope['types'];
scope.link.ready('types',
function() {
types = scope['types'];
});
var format = function(formatStr, args, functionName) {
var throwFormatError = function() {
functionName = functionName || '#<procedure>';
var matches = formatStr.match(new RegExp('~[sSaA]', 'g'));
var expectedNumberOfArgs = matches == null ? 0 : matches.length;
var errorStrBuffer = [functionName + ': format string requires ' + expectedNumberOfArgs
+ ' arguments, given ' + args.length + '; arguments were:',
types.toWrittenString(formatStr)];
for (var i = 0; i < args.length; i++) {
errorStrBuffer.push( types.toWrittenString(args[i]) );
}
raise( types.incompleteExn(types.exnFailContract, errorStrBuffer.join(' '), []) );
}
var pattern = new RegExp("~[sSaAneE%~]", "g");
var buffer = args.slice(0);;
function f(s) {
if (s == "~~") {
return "~";
} else if (s == '~n' || s == '~%') {
return "\n";
} else if (s == '~s' || s == "~S") {
if (buffer.length == 0) {
throwFormatError();
} }
return types.toWrittenString(buffer.shift());
var pattern = new RegExp("~[sSaAneE%~]", "g"); } else if (s == '~e' || s == "~E") {
var buffer = args.slice(0);; // FIXME: we don't yet have support for the error-print
function f(s) { // handler, and currently treat ~e just like ~s.
if (s == "~~") { if (buffer.length == 0) {
return "~"; throwFormatError();
} else if (s == '~n' || s == '~%') {
return "\n";
} else if (s == '~s' || s == "~S") {
if (buffer.length == 0) {
throwFormatError();
}
return types.toWrittenString(buffer.shift());
} else if (s == '~e' || s == "~E") {
// FIXME: we don't yet have support for the error-print
// handler, and currently treat ~e just like ~s.
if (buffer.length == 0) {
throwFormatError();
}
return types.toWrittenString(buffer.shift());
} else if (s == '~a' || s == "~A") {
if (buffer.length == 0) {
throwFormatError();
}
return types.toDisplayedString(buffer.shift());
} else {
throw types.internalError('format: string.replace matched invalid regexp', false);
}
} }
var result = formatStr.replace(pattern, f); return types.toWrittenString(buffer.shift());
if (buffer.length > 0) { } else if (s == '~a' || s == "~A") {
throwFormatError(); if (buffer.length == 0) {
throwFormatError();
} }
return result; return types.toDisplayedString(buffer.shift());
}; } else {
throw types.internalError('format: string.replace matched invalid regexp', false);
}
}
var result = formatStr.replace(pattern, f);
if (buffer.length > 0) {
throwFormatError();
}
return result;
};
// forEachK: CPS( array CPS(array -> void) (error -> void) -> void ) // forEachK: CPS( array CPS(array -> void) (error -> void) -> void )
// Iterates through an array and applies f to each element using CPS // Iterates through an array and applies f to each element using CPS
// If an error is thrown, it catches the error and calls f_error on it // If an error is thrown, it catches the error and calls f_error on it
var forEachK = function(a, f, f_error, k) { var forEachK = function(a, f, f_error, k) {
var forEachHelp = function(i) { var forEachHelp = function(i) {
if( i >= a.length ) { if( i >= a.length ) {
if (k) { if (k) {
return k(); return k();
} else {
return;
}
}
try {
return f(a[i], function() { return forEachHelp(i+1); });
} catch (e) {
f_error(e);
}
};
return forEachHelp(0);
};
// reportError: (or exception string) -> void
// Reports an error to the user, either at the console
// if the console exists, or as alerts otherwise.
var reportError = function(e) {
var reporter;
if (typeof(console) != 'undefined' &&
typeof(console.log) != 'undefined') {
reporter = (function(x) { console.log(x); });
} else { } else {
reporter = (function(x) { alert(x); }); return;
} }
if (typeof e == 'string') { }
reporter(e);
} else if ( types.isSchemeError(e) ) { try {
if ( types.isExn(e.val) ) { return f(a[i], function() { return forEachHelp(i+1); });
reporter( types.exnMessage(e.val) ); } catch (e) {
} f_error(e);
else { }
reporter(e.val);
}
} else if ( types.isInternalError(e) ) {
reporter(e.val);
} else if (e.message) {
reporter(e.message);
} else {
reporter(e.toString());
}
// if (plt.Kernel.lastLoc) {
// var loc = plt.Kernel.lastLoc;
// if (typeof(loc) === 'string') {
// reporter("Error was raised around " + loc);
// } else if (typeof(loc) !== 'undefined' &&
// typeof(loc.line) !== 'undefined') {
// reporter("Error was raised around: "
// + plt.Kernel.locToString(loc));
// }
// }
}; };
return forEachHelp(0);
};
var raise = function(v) { // reportError: (or exception string) -> void
throw types.schemeError(v); // Reports an error to the user, either at the console
}; // if the console exists, or as alerts otherwise.
var reportError = function(e) {
var reporter;
if (typeof(console) != 'undefined' &&
typeof(console.log) != 'undefined') {
reporter = (function(x) { console.log(x); });
} else {
reporter = (function(x) { alert(x); });
}
if (typeof e == 'string') {
reporter(e);
} else if ( types.isSchemeError(e) ) {
if ( types.isExn(e.val) ) {
reporter( types.exnMessage(e.val) );
}
else {
reporter(e.val);
}
} else if ( types.isInternalError(e) ) {
reporter(e.val);
} else if (e.message) {
reporter(e.message);
} else {
reporter(e.toString());
}
// if (plt.Kernel.lastLoc) {
// var loc = plt.Kernel.lastLoc;
// if (typeof(loc) === 'string') {
// reporter("Error was raised around " + loc);
// } else if (typeof(loc) !== 'undefined' &&
// typeof(loc.line) !== 'undefined') {
// reporter("Error was raised around: "
// + plt.Kernel.locToString(loc));
// }
// }
};
var procArityContains = function(n) { var raise = function(v) {
return function(proc) { throw types.schemeError(v);
var singleCase = function(aCase) { };
if ( aCase instanceof types.ContinuationClosureValue ) {
return true;
}
return (aCase.numParams == n ||
(aCase.isRest && aCase.numParams <= n));
};
var cases = [];
if ( proc instanceof types.ContinuationClosureValue ||
proc instanceof types.ClosureValue ||
proc instanceof types.PrimProc ) {
return singleCase(proc);
}
else if (proc instanceof types.CasePrimitive) {
cases = proc.cases;
}
else if (proc instanceof types.CaseLambdaValue) {
cases = proc.closures;
}
for (var i = 0; i < cases.length; i++) { var procArityContains = function(n) {
if ( singleCase(cases[i]) ) return function(proc) {
return true; var singleCase = function(aCase) {
} if ( aCase instanceof types.ContinuationClosureValue ) {
return false;
}
};
var throwCheckError = function(details, pos, args) {
var errorFormatStr;
if (args && args.length > 1) {
var errorFormatStrBuffer = ['~a: expects type <~a> as ~a arguments, given: ~s; other arguments were:'];
for (var i = 0; i < args.length; i++) {
if ( i != pos-1 ) {
errorFormatStrBuffer.push( types.toWrittenString(args[i]) );
}
}
errorFormatStr = errorFormatStrBuffer.join(' ');
}
else {
errorFormatStr = "~a: expects argument of type <~a>, given: ~s";
details.splice(2, 1);
}
raise( types.incompleteExn(types.exnFailContract,
helpers.format(errorFormatStr, details),
[]) );
};
var check = function(x, f, functionName, typeName, position, args) {
if ( !f(x) ) {
throwCheckError([functionName,
typeName,
helpers.ordinalize(position),
x],
position,
args);
}
};
var isList = function(x) {
var seenPairs = makeLowLevelEqHash();
while (true) {
if (seenPairs.containsKey(x)) {
return true; return true;
} else if (x === types.EMPTY) { }
return (aCase.numParams == n ||
(aCase.isRest && aCase.numParams <= n));
};
var cases = [];
if ( proc instanceof types.ContinuationClosureValue ||
proc instanceof types.ClosureValue ||
proc instanceof types.PrimProc ) {
return singleCase(proc);
}
else if (proc instanceof types.CasePrimitive) {
cases = proc.cases;
}
else if (proc instanceof types.CaseLambdaValue) {
cases = proc.closures;
}
for (var i = 0; i < cases.length; i++) {
if ( singleCase(cases[i]) )
return true; return true;
} else if (types.isPair(x)) { }
seenPairs.put(x, true); return false;
}
};
var throwCheckError = function(details, pos, args) {
var errorFormatStr;
if (args && args.length > 1) {
var errorFormatStrBuffer = ['~a: expects type <~a> as ~a arguments, given: ~s; other arguments were:'];
for (var i = 0; i < args.length; i++) {
if ( i != pos-1 ) {
errorFormatStrBuffer.push( types.toWrittenString(args[i]) );
}
}
errorFormatStr = errorFormatStrBuffer.join(' ');
}
else {
errorFormatStr = "~a: expects argument of type <~a>, given: ~s";
details.splice(2, 1);
}
raise( types.incompleteExn(types.exnFailContract,
helpers.format(errorFormatStr, details),
[]) );
};
var check = function(x, f, functionName, typeName, position, args) {
if ( !f(x) ) {
throwCheckError([functionName,
typeName,
helpers.ordinalize(position),
x],
position,
args);
}
};
var isList = function(x) {
var seenPairs = makeLowLevelEqHash();
while (true) {
if (seenPairs.containsKey(x)) {
return true;
} else if (x === types.EMPTY) {
return true;
} else if (types.isPair(x)) {
seenPairs.put(x, true);
x = x.rest();
} else {
return false;
}
}
};
var isListOf = function(x, f) {
var seenPairs = makeLowLevelEqHash();
while (true) {
if (seenPairs.containsKey(x)) {
return true;
} else if (x === types.EMPTY) {
return true;
} else if (types.isPair(x)) {
seenPairs.put(x, true);
if (f(x.first())) {
x = x.rest(); x = x.rest();
} else { } else {
return false; return false;
} }
} else {
return false;
} }
}; }
};
var isListOf = function(x, f) { var checkListOf = function(lst, f, functionName, typeName, position, args) {
var seenPairs = makeLowLevelEqHash(); if ( !isListOf(lst, f) ) {
while (true) { helpers.throwCheckError([functionName,
if (seenPairs.containsKey(x)) { 'list of ' + typeName,
return true; helpers.ordinalize(position),
} else if (x === types.EMPTY) { lst],
return true; position,
} else if (types.isPair(x)) { args);
seenPairs.put(x, true); }
if (f(x.first())) { };
x = x.rest();
} else {
return false; // // remove: array any -> array
} // // removes the first instance of v in a
} else { // // or returns a copy of a if v does not exist
return false; // var remove = function(a, v) {
} // for (var i = 0; i < a.length; i++) {
// if (a[i] === v) {
// return a.slice(0, i).concat( a.slice(i+1, a.length) );
// }
// }
// return a.slice(0);
// };
// map: array (any -> any) -> array
// applies f to each element of a and returns the result
// as a new array
var map = function(f, a) {
var b = new Array(a.length);
for (var i = 0; i < a.length; i++) {
b[i] = f(a[i]);
}
return b;
};
var concatMap = function(f, a) {
var b = [];
for (var i = 0; i < a.length; i++) {
b = b.concat( f(a[i]) );
}
return b;
};
var schemeListToArray = function(lst) {
var result = [];
while ( !lst.isEmpty() ) {
result.push(lst.first());
lst = lst.rest();
}
return result;
}
// deepListToArray: any -> any
// Converts list structure to array structure.
var deepListToArray = function(x) {
var thing = x;
if (thing === types.EMPTY) {
return [];
} else if (types.isPair(thing)) {
var result = [];
while (!thing.isEmpty()) {
result.push(deepListToArray(thing.first()));
thing = thing.rest();
} }
}; return result;
} else {
var checkListOf = function(lst, f, functionName, typeName, position, args) { return x;
if ( !isListOf(lst, f) ) { }
helpers.throwCheckError([functionName, }
'list of ' + typeName,
helpers.ordinalize(position),
lst],
position,
args);
}
};
// // remove: array any -> array var flattenSchemeListToArray = function(x) {
// // removes the first instance of v in a if ( !isList(x) ) {
// // or returns a copy of a if v does not exist return [x];
// var remove = function(a, v) {
// for (var i = 0; i < a.length; i++) {
// if (a[i] === v) {
// return a.slice(0, i).concat( a.slice(i+1, a.length) );
// }
// }
// return a.slice(0);
// };
// map: array (any -> any) -> array
// applies f to each element of a and returns the result
// as a new array
var map = function(f, a) {
var b = new Array(a.length);
for (var i = 0; i < a.length; i++) {
b[i] = f(a[i]);
}
return b;
};
var concatMap = function(f, a) {
var b = [];
for (var i = 0; i < a.length; i++) {
b = b.concat( f(a[i]) );
}
return b;
};
var schemeListToArray = function(lst) {
var result = [];
while ( !lst.isEmpty() ) {
result.push(lst.first());
lst = lst.rest();
}
return result;
} }
// deepListToArray: any -> any var ret = [];
// Converts list structure to array structure. while ( !x.isEmpty() ) {
var deepListToArray = function(x) { ret = ret.concat( flattenSchemeListToArray(x.first()) );
var thing = x; x = x.rest();
if (thing === types.EMPTY) {
return [];
} else if (types.isPair(thing)) {
var result = [];
while (!thing.isEmpty()) {
result.push(deepListToArray(thing.first()));
thing = thing.rest();
}
return result;
} else {
return x;
}
} }
return ret;
};
var flattenSchemeListToArray = function(x) { // assocListToHash: (listof (list X Y)) -> (hashof X Y)
if ( !isList(x) ) { var assocListToHash = function(lst) {
return [x]; var result = {};
} while ( !lst.isEmpty() ) {
var key = lst.first().first();
var ret = []; var val = lst.first().rest().first();
while ( !x.isEmpty() ) { result[key] = val;
ret = ret.concat( flattenSchemeListToArray(x.first()) ); lst = lst.rest();
x = x.rest();
}
return ret;
};
// assocListToHash: (listof (list X Y)) -> (hashof X Y)
var assocListToHash = function(lst) {
var result = {};
while ( !lst.isEmpty() ) {
var key = lst.first().first();
var val = lst.first().rest().first();
result[key] = val;
lst = lst.rest();
}
return result;
};
var ordinalize = function(n) {
// special case for 11th:
if ( n % 100 == 11 ) {
return n + 'th';
}
var res = n;
switch( n % 10 ) {
case 1: res += 'st'; break;
case 2: res += 'nd'; break;
case 3: res += 'rd'; break;
default: res += 'th'; break;
}
return res;
} }
return result;
};
var wrapJsValue = function(x) { var ordinalize = function(n) {
if (x === undefined) { // special case for 11th:
return types.jsValue('undefined', x); if ( n % 100 == 11 ) {
} return n + 'th';
else if (x === null) { }
return types.jsValue('null', x); var res = n;
} switch( n % 10 ) {
else if (typeof(x) == 'function') { case 1: res += 'st'; break;
return types.jsValue('function', x); case 2: res += 'nd'; break;
} case 3: res += 'rd'; break;
else if ( x instanceof Array ) { default: res += 'th'; break;
return types.jsValue('array', x); }
} return res;
else if ( typeof(x) == 'string' ) { }
return types.jsValue("'" + x.toString() + "'", x);
}
else {
return types.jsValue(x.toString(), x);
}
};
var getKeyCodeName = function(e) { var wrapJsValue = function(x) {
var code = e.charCode || e.keyCode; if (x === undefined) {
var keyname; return types.jsValue('undefined', x);
switch(code) { }
case 16: keyname = "shift"; break; else if (x === null) {
case 17: keyname = "control"; break; return types.jsValue('null', x);
case 19: keyname = "pause"; break; }
case 27: keyname = "escape"; break; else if (typeof(x) == 'function') {
case 33: keyname = "prior"; break; return types.jsValue('function', x);
case 34: keyname = "next"; break; }
case 35: keyname = "end"; break; else if ( x instanceof Array ) {
case 36: keyname = "home"; break; return types.jsValue('array', x);
case 37: keyname = "left"; break; }
case 38: keyname = "up"; break; else if ( typeof(x) == 'string' ) {
case 39: keyname = "right"; break; return types.jsValue("'" + x.toString() + "'", x);
case 40: keyname = "down"; break; }
case 42: keyname = "print"; break; else {
case 45: keyname = "insert"; break; return types.jsValue(x.toString(), x);
case 46: keyname = String.fromCharCode(127); break; }
case 106: keyname = "*"; break; };
case 107: keyname = "+"; break;
case 109: keyname = "-"; break;
case 110: keyname = "."; break; var getKeyCodeName = function(e) {
case 111: keyname = "/"; break; var code = e.charCode || e.keyCode;
case 144: keyname = "numlock"; break; var keyname;
case 145: keyname = "scroll"; break; switch(code) {
case 186: keyname = ";"; break; case 16: keyname = "shift"; break;
case 187: keyname = "="; break; case 17: keyname = "control"; break;
case 188: keyname = ","; break; case 19: keyname = "pause"; break;
case 189: keyname = "-"; break; case 27: keyname = "escape"; break;
case 190: keyname = "."; break; case 33: keyname = "prior"; break;
case 191: keyname = "/"; break; case 34: keyname = "next"; break;
case 192: keyname = "`"; break; case 35: keyname = "end"; break;
case 219: keyname = "["; break; case 36: keyname = "home"; break;
case 220: keyname = "\\"; break; case 37: keyname = "left"; break;
case 221: keyname = "]"; break; case 38: keyname = "up"; break;
case 222: keyname = "'"; break; case 39: keyname = "right"; break;
default: if (code >= 96 && code <= 105) { case 40: keyname = "down"; break;
keyname = (code - 96).toString(); case 42: keyname = "print"; break;
} case 45: keyname = "insert"; break;
else if (code >= 112 && code <= 123) { case 46: keyname = String.fromCharCode(127); break;
keyname = "f" + (code - 111); case 106: keyname = "*"; break;
} case 107: keyname = "+"; break;
else { case 109: keyname = "-"; break;
keyname = String.fromCharCode(code).toLowerCase(); case 110: keyname = "."; break;
} case 111: keyname = "/"; break;
break; case 144: keyname = "numlock"; break;
case 145: keyname = "scroll"; break;
case 186: keyname = ";"; break;
case 187: keyname = "="; break;
case 188: keyname = ","; break;
case 189: keyname = "-"; break;
case 190: keyname = "."; break;
case 191: keyname = "/"; break;
case 192: keyname = "`"; break;
case 219: keyname = "["; break;
case 220: keyname = "\\"; break;
case 221: keyname = "]"; break;
case 222: keyname = "'"; break;
default: if (code >= 96 && code <= 105) {
keyname = (code - 96).toString();
}
else if (code >= 112 && code <= 123) {
keyname = "f" + (code - 111);
} }
return keyname; else {
}; keyname = String.fromCharCode(code).toLowerCase();
}
break;
}
return keyname;
};
// maybeCallAfterAttach: dom-node -> void // maybeCallAfterAttach: dom-node -> void
// walk the tree rooted at aNode, and call afterAttach if the element has // walk the tree rooted at aNode, and call afterAttach if the element has
// such a method. // such a method.
var maybeCallAfterAttach = function(aNode) { var maybeCallAfterAttach = function(aNode) {
var stack = [aNode]; var stack = [aNode];
while (stack.length !== 0) { while (stack.length !== 0) {
var nextNode = stack.pop(); var nextNode = stack.pop();
if (nextNode.afterAttach) { if (nextNode.afterAttach) {
nextNode.afterAttach(nextNode); nextNode.afterAttach(nextNode);
} }
if (nextNode.hasChildNodes && nextNode.hasChildNodes()) { if (nextNode.hasChildNodes && nextNode.hasChildNodes()) {
var children = nextNode.childNodes; var children = nextNode.childNodes;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < children.length; i++) {
stack.push(children[i]); stack.push(children[i]);
}
} }
} }
}; }
};
@ -543,45 +564,48 @@ var helpers = {};
//////////////////////////////////////////////// ////////////////////////////////////////////////
helpers.format = format; helpers.format = format;
helpers.forEachK = forEachK; helpers.forEachK = forEachK;
helpers.reportError = reportError; helpers.reportError = reportError;
helpers.raise = raise; helpers.raise = raise;
helpers.procArityContains = procArityContains; helpers.procArityContains = procArityContains;
helpers.throwCheckError = throwCheckError; helpers.throwCheckError = throwCheckError;
helpers.isList = isList; helpers.isList = isList;
helpers.isListOf = isListOf; helpers.isListOf = isListOf;
helpers.check = check; helpers.check = check;
helpers.checkListOf = checkListOf; helpers.checkListOf = checkListOf;
// helpers.remove = remove; // helpers.remove = remove;
helpers.map = map; helpers.map = map;
helpers.concatMap = concatMap; helpers.concatMap = concatMap;
helpers.schemeListToArray = schemeListToArray; helpers.schemeListToArray = schemeListToArray;
helpers.deepListToArray = deepListToArray; helpers.deepListToArray = deepListToArray;
helpers.flattenSchemeListToArray = flattenSchemeListToArray; helpers.flattenSchemeListToArray = flattenSchemeListToArray;
helpers.assocListToHash = assocListToHash; helpers.assocListToHash = assocListToHash;
helpers.ordinalize = ordinalize; helpers.ordinalize = ordinalize;
helpers.wrapJsValue = wrapJsValue; helpers.wrapJsValue = wrapJsValue;
helpers.getKeyCodeName = getKeyCodeName; helpers.getKeyCodeName = getKeyCodeName;
helpers.maybeCallAfterAttach = maybeCallAfterAttach; helpers.maybeCallAfterAttach = maybeCallAfterAttach;
helpers.makeLocationDom = makeLocationDom; helpers.makeLocationDom = makeLocationDom;
helpers.isLocationDom = isLocationDom; helpers.isLocationDom = isLocationDom;
helpers.getEqHashCode = getEqHashCode; helpers.getEqHashCode = getEqHashCode;
helpers.makeLowLevelEqHash = makeLowLevelEqHash; helpers.makeLowLevelEqHash = makeLowLevelEqHash;
helpers.heir = heir; helpers.heir = heir;
})();
scope.link.announceReady('helpers');
})(this['plt']);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,56 @@
// Lightweight linking of the modules.
// There are circular dependencies across the modules unfortunately, so we
// need a mechanism for letting them link to each other.
if (! this['plt']) { this['plt'] = {}; }
(function(scope) {
var link = {};
scope['link'] = link;
// link.ready: (string (string -> void)) -> void
// When the name announces that it's ready, calls the function f.
link.ready = function(name, f) {
readyWaiters[name] = readyWaiters[name] || [];
readyWaiters[name].push(f);
if (linkIsReady[name]) {
notifySingle(f, name);
}
};
// link.announceReady: string -> void
// Lets the world know that the name is ready.
link.announceReady = function(name) {
var i;
linkIsReady[name] = true;
notifyAll(name);
};
// notifyAll: string -> void
// Tell all listeners that the name is ready.
var notifyAll = function(name) {
var waiters = readyWaiters[name] || [], i;
for (i = 0 ; i < waiters.length; i++) {
notifySingle(waiters[i], name);
}
readyWaiters[name] = [];
};
// Tell a single listener that the name is ready.
var notifySingle = function(f, name) {
setTimeout(function() { f(name); },
0);
};
// linkIsReady: (Hashtable String Boolean)
var linkIsReady = {};
// readyWaiters: (Hashtable String (Arrayof (String -> Void)))
var readyWaiters = {};
})(this['plt']);

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,10 @@
if(this['plt'] === undefined) { if(this['plt'] === undefined) { this['plt'] = {}; }
this['plt'] = {};
}
// All of the values here are namespaced under "plt.runtime". // All of the values here are namespaced under "plt.runtime".
(function() { (function(scope) {
this['plt']['runtime'] = {}; var runtime = {};
var exports = this['plt']['runtime']; scope['runtime'] = runtime;
@ -1343,8 +1340,8 @@
// Executes all programs that have been labeled as a main module // Executes all programs that have been labeled as a main module
var invokeMains = function(machine, succ, fail) { var invokeMains = function(machine, succ, fail) {
plt.runtime.ready(function() { runtime.ready(function() {
machine = machine || plt.runtime.currentMachine; machine = machine || runtime.currentMachine;
succ = succ || function() {}; succ = succ || function() {};
fail = fail || function() {}; fail = fail || function() {};
var mainModules = machine.mainModules.slice(); var mainModules = machine.mainModules.slice();
@ -1368,7 +1365,7 @@
// Exports // Exports
var exports = runtime;
exports['currentMachine'] = new Machine(); exports['currentMachine'] = new Machine();
exports['invokeMains'] = invokeMains; exports['invokeMains'] = invokeMains;
@ -1433,4 +1430,6 @@
exports['HaltError'] = HaltError; exports['HaltError'] = HaltError;
}).call(this);
scope.link.announceReady('runtime');
})(this['plt']);

File diff suppressed because it is too large Load Diff

View File

@ -213,9 +213,15 @@ var comet = function() {
sendRequest("/eval", sendRequest("/eval",
function(req) { function(req) {
// debug: // debug:
if (window.console && typeof(console.log) === 'function') { console.log(req.responseText); } //if (window.console && typeof(console.log) === 'function') {
// console.log(req.responseText);
var invoke = eval(req.responseText)(); //}
try {
var invoke = eval(req.responseText)();
} catch (e) {
if (window.console && window.console.log && e.stack) { window.console.log(e.stack); }
throw e;
}
var output = []; var output = [];
var startTime, endTime; var startTime, endTime;
var params = { currentDisplayer: function(v) { var params = { currentDisplayer: function(v) {