the runtime includes the libraries from Moby, although they do not use them yet.
This commit is contained in:
parent
61fa1f691e
commit
0add763beb
12
NOTES
12
NOTES
|
@ -657,3 +657,15 @@ Other things to consider:
|
|||
restrictions.
|
||||
|
||||
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...
|
|
@ -1,6 +1,23 @@
|
|||
#lang racket/base
|
||||
|
||||
;; 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
|
||||
racket/runtime-path
|
||||
|
@ -10,7 +27,27 @@
|
|||
(provide/contract [get-runtime (-> string?)])
|
||||
|
||||
(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)
|
||||
|
@ -19,11 +56,8 @@
|
|||
(port->string ip))))
|
||||
|
||||
|
||||
(define text (string-append
|
||||
(path->string jquery.js)
|
||||
(path->string runtime.js)))
|
||||
|
||||
|
||||
(define text (apply string-append
|
||||
(map path->string files)))
|
||||
|
||||
|
||||
(define (get-runtime)
|
||||
|
|
|
@ -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.
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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());
|
||||
} 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);
|
||||
}
|
||||
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();
|
||||
}
|
||||
var result = formatStr.replace(pattern, f);
|
||||
if (buffer.length > 0) {
|
||||
throwFormatError();
|
||||
return types.toWrittenString(buffer.shift());
|
||||
} else if (s == '~a' || s == "~A") {
|
||||
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 )
|
||||
// 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
|
||||
var forEachK = function(a, f, f_error, k) {
|
||||
var forEachHelp = function(i) {
|
||||
if( i >= a.length ) {
|
||||
if (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); });
|
||||
// forEachK: CPS( array CPS(array -> void) (error -> void) -> void )
|
||||
// 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
|
||||
var forEachK = function(a, f, f_error, k) {
|
||||
var forEachHelp = function(i) {
|
||||
if( i >= a.length ) {
|
||||
if (k) {
|
||||
return k();
|
||||
} else {
|
||||
reporter = (function(x) { alert(x); });
|
||||
return;
|
||||
}
|
||||
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));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
try {
|
||||
return f(a[i], function() { return forEachHelp(i+1); });
|
||||
} catch (e) {
|
||||
f_error(e);
|
||||
}
|
||||
};
|
||||
return forEachHelp(0);
|
||||
};
|
||||
|
||||
|
||||
var raise = function(v) {
|
||||
throw types.schemeError(v);
|
||||
};
|
||||
// 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 {
|
||||
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) {
|
||||
return function(proc) {
|
||||
var singleCase = function(aCase) {
|
||||
if ( aCase instanceof types.ContinuationClosureValue ) {
|
||||
return true;
|
||||
}
|
||||
return (aCase.numParams == n ||
|
||||
(aCase.isRest && aCase.numParams <= n));
|
||||
};
|
||||
var raise = function(v) {
|
||||
throw types.schemeError(v);
|
||||
};
|
||||
|
||||
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 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)) {
|
||||
var procArityContains = function(n) {
|
||||
return function(proc) {
|
||||
var singleCase = function(aCase) {
|
||||
if ( aCase instanceof types.ContinuationClosureValue ) {
|
||||
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;
|
||||
} 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();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} 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();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
var checkListOf = function(lst, f, functionName, typeName, position, args) {
|
||||
if ( !isListOf(lst, f) ) {
|
||||
helpers.throwCheckError([functionName,
|
||||
'list of ' + typeName,
|
||||
helpers.ordinalize(position),
|
||||
lst],
|
||||
position,
|
||||
args);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// // remove: array any -> array
|
||||
// // removes the first instance of v in a
|
||||
// // or returns a copy of a if v does not exist
|
||||
// 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();
|
||||
}
|
||||
};
|
||||
|
||||
var checkListOf = function(lst, f, functionName, typeName, position, args) {
|
||||
if ( !isListOf(lst, f) ) {
|
||||
helpers.throwCheckError([functionName,
|
||||
'list of ' + typeName,
|
||||
helpers.ordinalize(position),
|
||||
lst],
|
||||
position,
|
||||
args);
|
||||
}
|
||||
};
|
||||
return result;
|
||||
} else {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// // remove: array any -> array
|
||||
// // removes the first instance of v in a
|
||||
// // or returns a copy of a if v does not exist
|
||||
// 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;
|
||||
var flattenSchemeListToArray = function(x) {
|
||||
if ( !isList(x) ) {
|
||||
return [x];
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return x;
|
||||
}
|
||||
var ret = [];
|
||||
while ( !x.isEmpty() ) {
|
||||
ret = ret.concat( flattenSchemeListToArray(x.first()) );
|
||||
x = x.rest();
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
var flattenSchemeListToArray = function(x) {
|
||||
if ( !isList(x) ) {
|
||||
return [x];
|
||||
}
|
||||
|
||||
var ret = [];
|
||||
while ( !x.isEmpty() ) {
|
||||
ret = ret.concat( flattenSchemeListToArray(x.first()) );
|
||||
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;
|
||||
// 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 wrapJsValue = function(x) {
|
||||
if (x === undefined) {
|
||||
return types.jsValue('undefined', x);
|
||||
}
|
||||
else if (x === null) {
|
||||
return types.jsValue('null', x);
|
||||
}
|
||||
else if (typeof(x) == 'function') {
|
||||
return types.jsValue('function', x);
|
||||
}
|
||||
else if ( x instanceof Array ) {
|
||||
return types.jsValue('array', x);
|
||||
}
|
||||
else if ( typeof(x) == 'string' ) {
|
||||
return types.jsValue("'" + x.toString() + "'", x);
|
||||
}
|
||||
else {
|
||||
return types.jsValue(x.toString(), x);
|
||||
}
|
||||
};
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
var getKeyCodeName = function(e) {
|
||||
var code = e.charCode || e.keyCode;
|
||||
var keyname;
|
||||
switch(code) {
|
||||
case 16: keyname = "shift"; break;
|
||||
case 17: keyname = "control"; break;
|
||||
case 19: keyname = "pause"; break;
|
||||
case 27: keyname = "escape"; break;
|
||||
case 33: keyname = "prior"; break;
|
||||
case 34: keyname = "next"; break;
|
||||
case 35: keyname = "end"; break;
|
||||
case 36: keyname = "home"; break;
|
||||
case 37: keyname = "left"; break;
|
||||
case 38: keyname = "up"; break;
|
||||
case 39: keyname = "right"; break;
|
||||
case 40: keyname = "down"; break;
|
||||
case 42: keyname = "print"; break;
|
||||
case 45: keyname = "insert"; break;
|
||||
case 46: keyname = String.fromCharCode(127); break;
|
||||
case 106: keyname = "*"; break;
|
||||
case 107: keyname = "+"; break;
|
||||
case 109: keyname = "-"; break;
|
||||
case 110: keyname = "."; break;
|
||||
case 111: keyname = "/"; 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);
|
||||
}
|
||||
else {
|
||||
keyname = String.fromCharCode(code).toLowerCase();
|
||||
}
|
||||
break;
|
||||
var wrapJsValue = function(x) {
|
||||
if (x === undefined) {
|
||||
return types.jsValue('undefined', x);
|
||||
}
|
||||
else if (x === null) {
|
||||
return types.jsValue('null', x);
|
||||
}
|
||||
else if (typeof(x) == 'function') {
|
||||
return types.jsValue('function', x);
|
||||
}
|
||||
else if ( x instanceof Array ) {
|
||||
return types.jsValue('array', x);
|
||||
}
|
||||
else if ( typeof(x) == 'string' ) {
|
||||
return types.jsValue("'" + x.toString() + "'", x);
|
||||
}
|
||||
else {
|
||||
return types.jsValue(x.toString(), x);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var getKeyCodeName = function(e) {
|
||||
var code = e.charCode || e.keyCode;
|
||||
var keyname;
|
||||
switch(code) {
|
||||
case 16: keyname = "shift"; break;
|
||||
case 17: keyname = "control"; break;
|
||||
case 19: keyname = "pause"; break;
|
||||
case 27: keyname = "escape"; break;
|
||||
case 33: keyname = "prior"; break;
|
||||
case 34: keyname = "next"; break;
|
||||
case 35: keyname = "end"; break;
|
||||
case 36: keyname = "home"; break;
|
||||
case 37: keyname = "left"; break;
|
||||
case 38: keyname = "up"; break;
|
||||
case 39: keyname = "right"; break;
|
||||
case 40: keyname = "down"; break;
|
||||
case 42: keyname = "print"; break;
|
||||
case 45: keyname = "insert"; break;
|
||||
case 46: keyname = String.fromCharCode(127); break;
|
||||
case 106: keyname = "*"; break;
|
||||
case 107: keyname = "+"; break;
|
||||
case 109: keyname = "-"; break;
|
||||
case 110: keyname = "."; break;
|
||||
case 111: keyname = "/"; 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
|
||||
// walk the tree rooted at aNode, and call afterAttach if the element has
|
||||
// such a method.
|
||||
var maybeCallAfterAttach = function(aNode) {
|
||||
var stack = [aNode];
|
||||
while (stack.length !== 0) {
|
||||
var nextNode = stack.pop();
|
||||
if (nextNode.afterAttach) {
|
||||
nextNode.afterAttach(nextNode);
|
||||
}
|
||||
if (nextNode.hasChildNodes && nextNode.hasChildNodes()) {
|
||||
var children = nextNode.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
stack.push(children[i]);
|
||||
}
|
||||
// maybeCallAfterAttach: dom-node -> void
|
||||
// walk the tree rooted at aNode, and call afterAttach if the element has
|
||||
// such a method.
|
||||
var maybeCallAfterAttach = function(aNode) {
|
||||
var stack = [aNode];
|
||||
while (stack.length !== 0) {
|
||||
var nextNode = stack.pop();
|
||||
if (nextNode.afterAttach) {
|
||||
nextNode.afterAttach(nextNode);
|
||||
}
|
||||
if (nextNode.hasChildNodes && nextNode.hasChildNodes()) {
|
||||
var children = nextNode.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
stack.push(children[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -543,45 +564,48 @@ var helpers = {};
|
|||
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////
|
||||
|
||||
helpers.format = format;
|
||||
helpers.forEachK = forEachK;
|
||||
helpers.reportError = reportError;
|
||||
helpers.raise = raise;
|
||||
helpers.format = format;
|
||||
helpers.forEachK = forEachK;
|
||||
helpers.reportError = reportError;
|
||||
helpers.raise = raise;
|
||||
|
||||
helpers.procArityContains = procArityContains;
|
||||
helpers.throwCheckError = throwCheckError;
|
||||
helpers.isList = isList;
|
||||
helpers.isListOf = isListOf;
|
||||
helpers.check = check;
|
||||
helpers.checkListOf = checkListOf;
|
||||
|
||||
// helpers.remove = remove;
|
||||
helpers.map = map;
|
||||
helpers.concatMap = concatMap;
|
||||
helpers.schemeListToArray = schemeListToArray;
|
||||
helpers.deepListToArray = deepListToArray;
|
||||
helpers.flattenSchemeListToArray = flattenSchemeListToArray;
|
||||
helpers.assocListToHash = assocListToHash;
|
||||
helpers.procArityContains = procArityContains;
|
||||
helpers.throwCheckError = throwCheckError;
|
||||
helpers.isList = isList;
|
||||
helpers.isListOf = isListOf;
|
||||
helpers.check = check;
|
||||
helpers.checkListOf = checkListOf;
|
||||
|
||||
// helpers.remove = remove;
|
||||
helpers.map = map;
|
||||
helpers.concatMap = concatMap;
|
||||
helpers.schemeListToArray = schemeListToArray;
|
||||
helpers.deepListToArray = deepListToArray;
|
||||
helpers.flattenSchemeListToArray = flattenSchemeListToArray;
|
||||
helpers.assocListToHash = assocListToHash;
|
||||
|
||||
helpers.ordinalize = ordinalize;
|
||||
helpers.wrapJsValue = wrapJsValue;
|
||||
helpers.ordinalize = ordinalize;
|
||||
helpers.wrapJsValue = wrapJsValue;
|
||||
|
||||
helpers.getKeyCodeName = getKeyCodeName;
|
||||
helpers.getKeyCodeName = getKeyCodeName;
|
||||
|
||||
helpers.maybeCallAfterAttach = maybeCallAfterAttach;
|
||||
helpers.maybeCallAfterAttach = maybeCallAfterAttach;
|
||||
|
||||
helpers.makeLocationDom = makeLocationDom;
|
||||
helpers.isLocationDom = isLocationDom;
|
||||
helpers.makeLocationDom = makeLocationDom;
|
||||
helpers.isLocationDom = isLocationDom;
|
||||
|
||||
|
||||
helpers.getEqHashCode = getEqHashCode;
|
||||
helpers.makeLowLevelEqHash = makeLowLevelEqHash;
|
||||
helpers.getEqHashCode = getEqHashCode;
|
||||
helpers.makeLowLevelEqHash = makeLowLevelEqHash;
|
||||
|
||||
helpers.heir = heir;
|
||||
helpers.heir = heir;
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
||||
scope.link.announceReady('helpers');
|
||||
})(this['plt']);
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
56
js-assembler/runtime-src/link.js
Normal file
56
js-assembler/runtime-src/link.js
Normal 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
|
@ -1,13 +1,10 @@
|
|||
if(this['plt'] === undefined) {
|
||||
this['plt'] = {};
|
||||
}
|
||||
|
||||
if(this['plt'] === undefined) { this['plt'] = {}; }
|
||||
|
||||
// All of the values here are namespaced under "plt.runtime".
|
||||
|
||||
(function() {
|
||||
this['plt']['runtime'] = {};
|
||||
var exports = this['plt']['runtime'];
|
||||
(function(scope) {
|
||||
var runtime = {};
|
||||
scope['runtime'] = runtime;
|
||||
|
||||
|
||||
|
||||
|
@ -1343,8 +1340,8 @@
|
|||
|
||||
// Executes all programs that have been labeled as a main module
|
||||
var invokeMains = function(machine, succ, fail) {
|
||||
plt.runtime.ready(function() {
|
||||
machine = machine || plt.runtime.currentMachine;
|
||||
runtime.ready(function() {
|
||||
machine = machine || runtime.currentMachine;
|
||||
succ = succ || function() {};
|
||||
fail = fail || function() {};
|
||||
var mainModules = machine.mainModules.slice();
|
||||
|
@ -1368,7 +1365,7 @@
|
|||
|
||||
|
||||
// Exports
|
||||
|
||||
var exports = runtime;
|
||||
exports['currentMachine'] = new Machine();
|
||||
exports['invokeMains'] = invokeMains;
|
||||
|
||||
|
@ -1433,4 +1430,6 @@
|
|||
|
||||
exports['HaltError'] = HaltError;
|
||||
|
||||
}).call(this);
|
||||
|
||||
scope.link.announceReady('runtime');
|
||||
})(this['plt']);
|
File diff suppressed because it is too large
Load Diff
|
@ -213,9 +213,15 @@ var comet = function() {
|
|||
sendRequest("/eval",
|
||||
function(req) {
|
||||
// debug:
|
||||
if (window.console && typeof(console.log) === 'function') { console.log(req.responseText); }
|
||||
|
||||
var invoke = eval(req.responseText)();
|
||||
//if (window.console && typeof(console.log) === 'function') {
|
||||
// console.log(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 startTime, endTime;
|
||||
var params = { currentDisplayer: function(v) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user