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.
|
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...
|
|
@ -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)
|
||||||
|
|
|
@ -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']);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
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) {
|
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
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user