Merge remote-tracking branch 'origin/master'

This commit is contained in:
Danny Yoo 2011-06-05 16:12:39 -04:00
commit 31f96bd40a
11 changed files with 6136 additions and 5750 deletions

88
NOTES
View File

@ -596,3 +596,91 @@ benchmarks
being able to write modules in javascript
being able to bundle external resources (like images)
----------------------------------------------------------------------
June 2, 2011
We need a mechanism for attaching external resources to a program and
to be able to refer to them. External resources refer to things like:
Images
HTML files
Sounds
Each of these should be findable by path, and they should also be
packaged when a program is built. The user should be able to say
something like this:
(define my-html-file (local-resource-path ...))
and the packager should automatically be able to statically walk
though all local-resource-path calls.
These files must be represented as separate files.
There may be additional resources that need to be included, though
they aren't directly used in the program. (Say, for example, an image
is refered to in an html resource. Maybe we should have a toplevel
element (include-resources ...) that take in a bunch of
build-resource-path.
(include-resources (build-resource-path ...)
...)
The Whalesong make system needs to know how to deal with resources.
I also want to be able to refer to external web resources, and somehow
capture or cache them during building.
Imaginary: I would like to be able to write something like this:
(define my-file (remote-resource-path ...))
and be able to treat my-file as if it were a local resource. During
packaging, the file should be directly downloaded.
Other things to consider:
We may need to consider workarounds for same-origin policy
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...
----------------------------------------------------------------------
June 3, 2011
How do I test what I'm integrating? I should at least absorb the
js-vm test suite, at the very least.
11am: I'm going to spend the next hour trying to disentangle the
circularity between helpers and types.
The parameters I'm using to control bounce are too high for Firefox,
leading it to raise the dialog about an out of control jva process. Not good.

View File

@ -19,7 +19,8 @@
assemble-arity
assemble-jump
assemble-display-name
assemble-location)
assemble-location
assemble-numeric-constant)
(require/typed typed/racket/base
[regexp-split (Regexp String -> (Listof String))])
@ -110,7 +111,7 @@
[(empty? val)
(format "RUNTIME.NULL")]
[(number? val)
(format "(~s)" val)]
(assemble-numeric-constant val)]
[else
(format "~s" val)])))
@ -124,6 +125,97 @@
(format "[~a, ~a]" (first vals) (loop (rest vals)))])))
;; Slightly ridiculous definition, but I need it to get around what appear to
;; be Typed Racket bugs in its numeric tower.
(define-predicate int? Integer)
(: assemble-numeric-constant (Number -> String))
(define (assemble-numeric-constant a-num)
(: floating-number->js (Real -> String))
(define (floating-number->js a-num)
(cond
[(eqv? a-num -0.0)
"jsnums.negative_zero"]
[(eqv? a-num +inf.0)
"jsnums.inf"]
[(eqv? a-num -inf.0)
"jsnums.negative_inf"]
[(eqv? a-num +nan.0)
"jsnums.nan"]
[else
(string-append "jsnums.makeFloat(" (number->string a-num) ")")]))
;; FIXME: fix the type signature when typed-racket isn't breaking on
;; (define-predicate ExactRational? (U Exact-Rational))
(: rational-number->js (Real -> String))
(define (rational-number->js a-num)
(cond [(= (denominator a-num) 1)
(string-append (integer->js (ensure-integer (numerator a-num))))]
[else
(string-append "jsnums.makeRational("
(integer->js (ensure-integer (numerator a-num)))
", "
(integer->js (ensure-integer (denominator a-num)))
")")]))
(: ensure-integer (Any -> Integer))
(define (ensure-integer x)
(if (int? x)
x
(error "not an integer: ~e" x)))
(: integer->js (Integer -> String))
(define (integer->js an-int)
(cond
;; non-overflow case
[(< (abs an-int) 9e15)
(number->string an-int)]
;; overflow case
[else
(string-append "jsnums.makeBignum("
(format "~s" (number->string an-int))
")")]))
(cond
[(and (exact? a-num) (rational? a-num))
(rational-number->js a-num)]
[(real? a-num)
(floating-number->js a-num)]
[(complex? a-num)
(string-append "jsnums.makeComplex("
(assemble-numeric-constant (real-part a-num))
", "
(assemble-numeric-constant (imag-part a-num))
")")]))
(: assemble-lexical-reference (EnvLexicalReference -> String))

View File

@ -5,7 +5,8 @@
"../compiler/lexical-structs.rkt"
"../compiler/kernel-primitives.rkt"
racket/string
racket/list)
racket/list
typed/rackunit)
(provide open-code-kernel-primitive-procedure)
@ -28,45 +29,48 @@
(case operator
[(+)
(cond [(empty? checked-operands)
"0"]
(assemble-numeric-constant 0)]
[else
(string-append "(" (string-join checked-operands " + ") ")")])]
(assemble-binop-chain "jsnums.add" checked-operands)])]
[(-)
(cond [(empty? (rest checked-operands))
(format "(-(~a))" (first checked-operands))]
(assemble-binop-chain "jsnums.subtract" (cons "0" checked-operands))]
[else
(string-append "(" (string-join checked-operands "-") ")")])]
(assemble-binop-chain "jsnums.subtract" checked-operands)])]
[(*)
(cond [(empty? checked-operands)
"1"]
(assemble-numeric-constant 1)]
[else
(string-append "(" (string-join checked-operands "*") ")")])]
(assemble-binop-chain "jsnums.multiply" checked-operands)])]
[(/)
(string-append "(" (string-join checked-operands "/") ")")]
(assemble-binop-chain "jsnums.divide" checked-operands)]
[(add1)
(format "(~a + 1)" (first checked-operands))]
(assemble-binop-chain "jsnums.add" (cons "1" checked-operands))]
[(sub1)
(format "(~a - 1)" (first checked-operands))]
(assemble-binop-chain "jsnums.subtract" (append checked-operands (list "1")))]
[(<)
(assemble-chain "<" checked-operands)]
(assemble-boolean-chain "jsnums.lessThan" checked-operands)]
[(<=)
(assemble-chain "<=" checked-operands)]
(assemble-boolean-chain "jsnums.lessThanOrEqual" checked-operands)]
[(=)
(assemble-chain "===" checked-operands)]
(assemble-boolean-chain "jsnums.equals" checked-operands)]
[(>)
(assemble-chain ">" checked-operands)]
(assemble-boolean-chain "jsnums.greaterThan" checked-operands)]
[(>=)
(assemble-chain ">=" checked-operands)]
(assemble-boolean-chain "jsnums.greaterThanOrEqual" checked-operands)]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[(cons)
(format "[~a, ~a]" (first checked-operands) (second checked-operands))]
@ -95,8 +99,32 @@
(format "(~a === ~a)" (first checked-operands) (second checked-operands))])))
(: assemble-chain (String (Listof String) -> String))
(define (assemble-chain rator rands)
(: assemble-binop-chain (String (Listof String) -> String))
(define (assemble-binop-chain rator rands)
(cond
[(empty? rands)
""]
[(empty? (rest rands))
(first rands)]
[else
(assemble-binop-chain
rator
(cons (string-append rator "(" (first rands) ", " (second rands) ")")
(rest (rest rands))))]))
(check-equal? (assemble-binop-chain "jsnums.add" '("3" "4" "5"))
"jsnums.add(jsnums.add(3, 4), 5)")
(check-equal? (assemble-binop-chain "jsnums.subtract" '("0" "42"))
"jsnums.subtract(0, 42)")
(: assemble-boolean-chain (String (Listof String) -> String))
(define (assemble-boolean-chain rator rands)
(string-append "("
(string-join (let: loop : (Listof String) ([rands : (Listof String) rands])
(cond
@ -105,7 +133,7 @@
[(empty? (rest rands))
'()]
[else
(cons (format "(~a ~a ~a)" (first rands) rator (second rands))
(cons (format "(~a(~a,~a))" rator (first rands) (second rands))
(loop (rest rands)))]))
"&&")
")"))
@ -123,7 +151,7 @@
(let: ([test-string : String
(case domain
[(number)
(format "(typeof(~a) === 'number')"
(format "(jsnums.isSchemeNumber(~a))"
operand-string)]
[(string)
(format "(typeof(~a) === 'string')"

View File

@ -1,16 +1,54 @@
#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
racket/port)
(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 +57,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)

View File

@ -4,6 +4,7 @@
"quote-cdata.rkt"
"../make.rkt"
"../make-structs.rkt"
(planet dyoo/closure-compile:1:1)
(prefix-in runtime: "get-runtime.rkt")
(prefix-in racket: racket/base))
@ -87,13 +88,6 @@
;; get-runtime: -> string
(define (get-runtime)
(let ([buffer (open-output-string)])
(write-runtime buffer)
(get-output-string buffer)))
;; write-runtime: output-port -> void
(define (write-runtime op)
(let ([packaging-configuration
@ -121,6 +115,19 @@
(define *the-runtime*
(let ([buffer (open-output-string)])
(write-runtime buffer)
(closure-compile
(get-output-string buffer))))
;; get-runtime: -> string
(define (get-runtime)
*the-runtime*)
;; *header* : string
@ -144,7 +151,8 @@ EOF
(package source-code
#:should-follow? (lambda (src p) #t)
#:output-port buffer)
(get-output-string buffer)))
(closure-compile
(get-output-string buffer))))
@ -152,7 +160,8 @@ EOF
(define (get-standalone-code source-code)
(let ([buffer (open-output-string)])
(write-standalone-code source-code buffer)
(get-output-string buffer)))
(closure-compile
(get-output-string buffer))))
;; write-standalone-code: source output-port -> void

View File

@ -1,11 +1,32 @@
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;
// 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() {
@ -14,9 +35,9 @@ var helpers = {};
var expectedNumberOfArgs = matches == null ? 0 : matches.length;
var errorStrBuffer = [functionName + ': format string requires ' + expectedNumberOfArgs
+ ' arguments, given ' + args.length + '; arguments were:',
types.toWrittenString(formatStr)];
toWrittenString(formatStr)];
for (var i = 0; i < args.length; i++) {
errorStrBuffer.push( types.toWrittenString(args[i]) );
errorStrBuffer.push( toWrittenString(args[i]) );
}
raise( types.incompleteExn(types.exnFailContract, errorStrBuffer.join(' '), []) );
@ -33,19 +54,19 @@ var helpers = {};
if (buffer.length == 0) {
throwFormatError();
}
return types.toWrittenString(buffer.shift());
return 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());
return toWrittenString(buffer.shift());
} else if (s == '~a' || s == "~A") {
if (buffer.length == 0) {
throwFormatError();
}
return types.toDisplayedString(buffer.shift());
return toDisplayedString(buffer.shift());
} else {
throw types.internalError('format: string.replace matched invalid regexp', false);
}
@ -163,7 +184,7 @@ var helpers = {};
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]) );
errorFormatStrBuffer.push(toWrittenString(args[i]));
}
}
errorFormatStr = errorFormatStrBuffer.join(' ');
@ -543,6 +564,188 @@ var helpers = {};
// toWrittenString: Any Hashtable -> String
var toWrittenString = function(x, cache) {
if (! cache) {
cache = makeLowLevelEqHash();
}
if (typeof(x) === 'object') {
if (cache.containsKey(x)) {
return "...";
}
}
if (x == undefined || x == null) {
return "#<undefined>";
}
if (typeof(x) == 'string') {
return escapeString(x.toString());
}
if (typeof(x) != 'object' && typeof(x) != 'function') {
return x.toString();
}
var returnVal;
if (typeof(x.toWrittenString) !== 'undefined') {
returnVal = x.toWrittenString(cache);
} else if (typeof(x.toDisplayedString) !== 'undefined') {
returnVal = x.toDisplayedString(cache);
} else {
returnVal = x.toString();
}
cache.remove(x);
return returnVal;
};
// toDisplayedString: Any Hashtable -> String
var toDisplayedString = function(x, cache) {
if (! cache) {
cache = makeLowLevelEqHash();
}
if (typeof(x) === 'object') {
if (cache.containsKey(x)) {
return "...";
}
}
if (x == undefined || x == null) {
return "#<undefined>";
}
if (typeof(x) == 'string') {
return x;
}
if (typeof(x) != 'object' && typeof(x) != 'function') {
return x.toString();
}
var returnVal;
if (typeof(x.toDisplayedString) !== 'undefined') {
returnVal = x.toDisplayedString(cache);
} else if (typeof(x.toWrittenString) !== 'undefined') {
returnVal = x.toWrittenString(cache);
} else {
returnVal = x.toString();
}
cache.remove(x);
return returnVal;
};
// toDomNode: scheme-value -> dom-node
var toDomNode = function(x, cache) {
if (! cache) {
cache = makeLowLevelEqHash();
}
if (jsnums.isSchemeNumber(x)) {
return numberToDomNode(x);
}
if (typeof(x) == 'object') {
if (cache.containsKey(x)) {
var node = document.createElement("span");
node.appendChild(document.createTextNode("..."));
return node;
}
}
if (x == undefined || x == null) {
var node = document.createElement("span");
node.appendChild(document.createTextNode("#<undefined>"));
return node;
}
if (typeof(x) == 'string') {
var wrapper = document.createElement("span");
wrapper.style["white-space"] = "pre";
var node = document.createTextNode(toWrittenString(x));
wrapper.appendChild(node);
return wrapper;
}
if (typeof(x) != 'object' && typeof(x) != 'function') {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toString()));
return node;
}
var returnVal;
if (x.nodeType) {
returnVal = x;
} else if (typeof(x.toDomNode) !== 'undefined') {
returnVal = x.toDomNode(cache);
} else if (typeof(x.toWrittenString) !== 'undefined') {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toWrittenString(cache)));
returnVal = node;
} else if (typeof(x.toDisplayedString) !== 'undefined') {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toDisplayedString(cache)));
returnVal = node;
} else {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toString()));
returnVal = node;
}
cache.remove(x);
return returnVal;
};
// numberToDomNode: jsnum -> dom
// Given a jsnum, produces a dom-node representation.
var numberToDomNode = function(n) {
var node;
if (jsnums.isExact(n)) {
if (jsnums.isInteger(n)) {
node = document.createElement("span");
node.appendChild(document.createTextNode(n.toString()));
return node;
} else if (jsnums.isRational(n)) {
return rationalToDomNode(n);
} else if (jsnums.isComplex(n)) {
node = document.createElement("span");
node.appendChild(document.createTextNode(n.toString()));
return node;
} else {
node = document.createElement("span");
node.appendChild(document.createTextNode(n.toString()));
return node;
}
} else {
node = document.createElement("span");
node.appendChild(document.createTextNode(n.toString()));
return node;
}
};
// rationalToDomNode: rational -> dom-node
var rationalToDomNode = function(n) {
var node = document.createElement("span");
var chunks = jsnums.toRepeatingDecimal(jsnums.numerator(n),
jsnums.denominator(n));
node.appendChild(document.createTextNode(chunks[0] + '.'))
node.appendChild(document.createTextNode(chunks[1]));
var overlineSpan = document.createElement("span");
overlineSpan.style.textDecoration = 'overline';
overlineSpan.appendChild(document.createTextNode(chunks[2]));
node.appendChild(overlineSpan);
return node;
}
////////////////////////////////////////////////
helpers.format = format;
@ -581,7 +784,16 @@ var helpers = {};
helpers.heir = heir;
})();
helpers.toWrittenString = toWrittenString;
helpers.toDisplayedString = toDisplayedString;
helpers.toDomNode = toDomNode;
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']);

View File

@ -1,4 +1,5 @@
var primitive = {};
if (! this['plt']) { this['plt'] = {}; }
/**
@ -13,26 +14,59 @@ That way, we can do a simple grep.
*/
(function() {
var CALL = types.internalCall;
var PAUSE = types.internalPause;
(function(scope) {
var primitives = {};
scope.primitives = primitives;
var PRIMITIVES = {};
var PrimProc = types.PrimProc;
var CasePrimitive = types.CasePrimitive;
var makeOptionPrimitive = types.makeOptionPrimitive;
var types = scope.types;
var helpers = scope.helpers;
var CALL, PAUSE, PrimProc, CasePrimitive, makeOptionPrimitive, procArityContains;
var assocListToHash, raise;
var isList, isListOf;
var check;
var checkListOf;
CALL = types.internalCall;
PAUSE = types.internalPause;
PrimProc = types.PrimProc;
CasePrimitive = types.CasePrimitive;
makeOptionPrimitive = types.makeOptionPrimitive;
procArityContains = helpers.procArityContains;
assocListToHash = helpers.assocListToHash;
raise = helpers.raise;
isList = helpers.isList;
isListOf = helpers.isListOf;
check = helpers.check;
checkListOf = helpers.checkListOf;
scope.link.ready('types',
function() {
types = scope.types;
CALL = types.internalCall;
PAUSE = types.internalPause;
PrimProc = types.PrimProc;
CasePrimitive = types.CasePrimitive;
makeOptionPrimitive = types.makeOptionPrimitive;
});
scope.link.ready('helpers',
function() {
helpers = scope.helpers;
procArityContains = helpers.procArityContains;
assocListToHash = helpers.assocListToHash;
raise = helpers.raise;
isList = helpers.isList;
isListOf = helpers.isListOf;
check = helpers.check;
checkListOf = helpers.checkListOf;
});
//////////////////////////////////////////////////////////////////////
@ -153,7 +187,6 @@ var normalizeArity = function(arity) {
};
var procArityContains = helpers.procArityContains;
@ -295,10 +328,6 @@ var isImmutable = function(x) {
var assocListToHash = helpers.assocListToHash;
var raise = helpers.raise;
@ -421,9 +450,6 @@ var isChar = types.isChar;
var isString = types.isString;
var isPair = types.isPair;
var isEmpty = function(x) { return x === types.EMPTY; };
var isList = helpers.isList;
var isListOf = helpers.isListOf;
var isVector = types.isVector;
var isBox = types.isBox;
var isHash = types.isHash;
@ -487,8 +513,6 @@ var arrayEach = function(arr, f) {
}
}
//var throwCheckError = helpers.throwCheckError;
var check = helpers.check;
var checkList = function(x, functionName, position, args) {
if ( !isList(x) ) {
@ -501,8 +525,6 @@ var checkList = function(x, functionName, position, args) {
}
}
var checkListOf = helpers.checkListOf;
var checkListOfLength = function(lst, n, functionName, position, args) {
if ( !isList(lst) || (length(lst) < n) ) {
helpers.throwCheckError([functionName,
@ -598,7 +620,7 @@ var defaultPrint =
false,
true,
function(state, x) {
state.getPrintHook()(types.toWrittenString(x));
state.getPrintHook()(helpers.toDisplayedString(x));
state.v = types.VOID;
});
@ -1151,7 +1173,7 @@ PRIMITIVES['void'] =
PRIMITIVES['random'] =
new CasePrimitive('random',
[new PrimProc('random', 0, false, false,
function() {return types.float(Math.random());}),
function() {return types.floatpoint(Math.random());}),
new PrimProc('random', 1, false, false,
function(n) {
check(n, isNatural, 'random', 'non-negative exact integer', 1, arguments);
@ -1208,7 +1230,7 @@ PRIMITIVES['error'] =
else {
var msgBuffer = [arg1.toString()];
for (var i = 0; i < args.length; i++) {
msgBuffer.push( types.toWrittenString(args[i]) );
msgBuffer.push( helpers.toDisplayedString(args[i]) );
}
raise( types.incompleteExn(types.exnFail, msgBuffer.join(''), []) );
}
@ -1930,7 +1952,7 @@ PRIMITIVES['inexact->exact'] =
return jsnums.toExact(x);
} catch(e) {
raise( types.exnFailContract('inexact->exact: no exact representation for '
+ types.toWrittenString(x),
+ helpers.toDisplayedString(x),
false) );
}
});
@ -2503,7 +2525,7 @@ PRIMITIVES['list-ref'] =
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('list-ref: index ' + n +
' is too large for list (not a proper list): ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2511,7 +2533,7 @@ PRIMITIVES['list-ref'] =
if (lst.isEmpty()) {
var msg = ('list-ref: index ' + n +
' is too large for list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
lst = lst.rest();
@ -2521,7 +2543,7 @@ PRIMITIVES['list-ref'] =
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('list-ref: index ' + n +
' is too large for list (not a proper list): ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2545,7 +2567,7 @@ PRIMITIVES['list-tail'] =
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('list-tail: index ' + n +
' is too large for list (not a proper list): ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2553,7 +2575,7 @@ PRIMITIVES['list-tail'] =
if (lst.isEmpty()) {
var msg = ('list-tail: index ' + n +
' is too large for list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
lst = lst.rest();
@ -2705,7 +2727,7 @@ PRIMITIVES['memq'] =
var lst = origList;
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('memq: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2718,7 +2740,7 @@ PRIMITIVES['memq'] =
lst = lst.rest();
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('memq: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2736,7 +2758,7 @@ PRIMITIVES['memv'] =
var lst = origList;
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('memv: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2748,7 +2770,7 @@ PRIMITIVES['memv'] =
lst = lst.rest();
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('memv: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2767,7 +2789,7 @@ PRIMITIVES['member'] =
//checkList(lst, 'member', 2, arguments);
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('member: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2780,7 +2802,7 @@ PRIMITIVES['member'] =
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('member: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2824,7 +2846,7 @@ PRIMITIVES['assq'] =
// checkListOf(lst, isPair, 'assq', 'pair', 2, arguments);
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('assq: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2832,8 +2854,8 @@ PRIMITIVES['assq'] =
while ( !lst.isEmpty() ) {
if (! isPair(lst.first())) {
var msg = ('assq: non-pair found in list: ' +
types.toWrittenString(lst.first()) +' in ' +
types.toWrittenString(origList));
helpers.toDisplayedString(lst.first()) +' in ' +
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2845,7 +2867,7 @@ PRIMITIVES['assq'] =
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('assq: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2864,7 +2886,7 @@ PRIMITIVES['assv'] =
var lst = origList;
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('assv: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2872,8 +2894,8 @@ PRIMITIVES['assv'] =
while ( !lst.isEmpty() ) {
if (! isPair(lst.first())) {
var msg = ('assv: non-pair found in list: ' +
types.toWrittenString(lst.first()) +' in ' +
types.toWrittenString(origList));
helpers.toDisplayedString(lst.first()) +' in ' +
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2884,7 +2906,7 @@ PRIMITIVES['assv'] =
lst = lst.rest();
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('assv: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2903,7 +2925,7 @@ PRIMITIVES['assoc'] =
//checkListOf(lst, isPair, 'assoc', 'pair', 2, arguments);
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('assoc: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2911,8 +2933,8 @@ PRIMITIVES['assoc'] =
while ( !lst.isEmpty() ) {
if (! isPair(lst.first())) {
var msg = ('assoc: non-pair found in list: ' +
types.toWrittenString(lst.first()) +' in ' +
types.toWrittenString(origList));
helpers.toDisplayedString(lst.first()) +' in ' +
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -2924,7 +2946,7 @@ PRIMITIVES['assoc'] =
if (! isPair(lst) && lst !== types.EMPTY) {
var msg = ('assoc: not a proper list: ' +
types.toWrittenString(origList));
helpers.toDisplayedString(origList));
raise( types.incompleteExn(types.exnFailContract,
msg,
[]) );
@ -3186,7 +3208,7 @@ PRIMITIVES['hash-ref'] =
check(obj, isHash, 'hash-ref', 'hash', 1, arguments);
if ( !obj.hash.containsKey(key) ) {
var msg = 'hash-ref: no value found for key: ' + types.toWrittenString(key);
var msg = 'hash-ref: no value found for key: ' + helpers.toDisplayedString(key);
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
return obj.hash.get(key);
@ -3293,7 +3315,7 @@ PRIMITIVES['make-string'] =
1,
false, false,
function(n) {
return makeStringImpl(n, types.char(String.fromCharCode(0)));
return makeStringImpl(n, types.character(String.fromCharCode(0)));
})]);
@ -3351,10 +3373,10 @@ PRIMITIVES['string-ref'] =
if (n >= str.length) {
var msg = ('string-ref: index ' + n + ' out of range ' +
'[0, ' + (str.length-1) + '] for string: ' +
types.toWrittenString(str));
helpers.toDisplayedString(str));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
return types.char(str.charAt(n));
return types.character(str.charAt(n));
});
@ -3520,7 +3542,7 @@ PRIMITIVES['substring'] =
var start = jsnums.toFixnum(theStart);
if (start > str.length) {
var msg = ('substring: starting index ' + start + ' out of range ' +
'[0, ' + str.length + '] for string: ' + types.toWrittenString(str));
'[0, ' + str.length + '] for string: ' + helpers.toDisplayedString(str));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
else {
@ -3539,12 +3561,12 @@ PRIMITIVES['substring'] =
var end = jsnums.toFixnum(theEnd);
if (start > str.length) {
var msg = ('substring: starting index ' + start + ' out of range ' +
'[0, ' + str.length + '] for string: ' + types.toWrittenString(str));
'[0, ' + str.length + '] for string: ' + helpers.toDisplayedString(str));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
if (end < start || end > str.length) {
var msg = ('substring: ending index ' + end + ' out of range ' + '[' + start +
', ' + str.length + '] for string: ' + types.toWrittenString(str));
', ' + str.length + '] for string: ' + helpers.toDisplayedString(str));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
return types.string( str.substring(start, end) );
@ -3577,7 +3599,7 @@ PRIMITIVES['string->list'] =
str = str.toString();
var lst = types.EMPTY;
for (var i = str.length-1; i >= 0; i--) {
lst = types.cons(types.char(str.charAt(i)), lst);
lst = types.cons(types.character(str.charAt(i)), lst);
}
return lst;
});
@ -3829,7 +3851,7 @@ PRIMITIVES['string-set!'] =
if ( jsnums.greaterThanOrEqual(k, str.length) ) {
var msg = ('string-set!: index ' + k + ' out of range ' +
'[0, ' + (str.length-1) + '] for string: ' +
types.toWrittenString(str));
helpers.toDisplayedString(str));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
str.set(jsnums.toFixnum(k), c.val);
@ -3975,7 +3997,7 @@ PRIMITIVES['bytes-ref'] =
if ( n >= bstr.length() ) {
var msg = ('bytes-ref: index ' + n + ' out of range ' +
'[0, ' + (bstr.length-1) + '] for byte-string: ' +
types.toWrittenString(bstr));
helpers.toDisplayedString(bstr));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
return bstr.get(n);
@ -3996,7 +4018,7 @@ PRIMITIVES['bytes-set!'] =
if ( n >= bstr.length() ) {
var msg = ('bytes-set!: index ' + n + ' out of range ' +
'[0, ' + (bstr.length-1) + '] for byte-string: ' +
types.toWrittenString(bstr));
helpers.toDisplayedString(bstr));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
bstr.set(n, b);
@ -4017,7 +4039,7 @@ PRIMITIVES['subbytes'] =
if (start > bstr.length()) {
var msg = ('subbytes: starting index ' + start + ' out of range ' +
'[0, ' + bstr.length + '] for byte-string: ' +
types.toWrittenString(bstr));
helpers.toDisplayedString(bstr));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
else {
@ -4037,13 +4059,13 @@ PRIMITIVES['subbytes'] =
if (start > bstr.length()) {
var msg = ('subbytes: starting index ' + start + ' out of range ' +
'[0, ' + bstr.length() + '] for byte-string: ' +
types.toWrittenString(bstr));
helpers.toDisplayedString(bstr));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
if (end < start || end > bstr.length()) {
var msg = ('subbytes: ending index ' + end + ' out of range ' + '[' + start +
', ' + bstr.length() + '] for byte-string: ' +
types.toWrittenString(bstr));
helpers.toDisplayedString(bstr));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
else {
@ -4222,7 +4244,7 @@ PRIMITIVES['vector-ref'] =
if (i >= vec.length()) {
var msg = ('vector-ref: index ' + i + ' out of range ' +
'[0, ' + (vec.length()-1) + '] for vector: ' +
types.toWrittenString(vec));
helpers.toDisplayedString(vec));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
return vec.ref(i);
@ -4241,7 +4263,7 @@ PRIMITIVES['vector-set!'] =
if (i >= vec.length()) {
var msg = ('vector-set!: index ' + i + ' out of range ' +
'[0, ' + (vec.length()-1) + '] for vector: ' +
types.toWrittenString(vec));
helpers.toDisplayedString(vec));
raise( types.incompleteExn(types.exnFailContract, msg, []) );
}
vec.set(i, val);
@ -4520,7 +4542,7 @@ PRIMITIVES['integer->char'] =
'exact integer in [0,#x10FFFF], not in [#xD800,#xDFFF]',
1);
return types.char( String.fromCharCode(jsnums.toFixnum(num)) );
return types.character( String.fromCharCode(jsnums.toFixnum(num)) );
});
@ -4530,7 +4552,7 @@ PRIMITIVES['char-upcase'] =
false, false,
function(c) {
check(c, isChar, 'char-upcase', 'char', 1);
return types.char( c.val.toUpperCase() );
return types.character( c.val.toUpperCase() );
});
@ -4540,7 +4562,7 @@ PRIMITIVES['char-downcase'] =
false, false,
function(c) {
check(c, isChar, 'char-downcase', 'char', 1);
return types.char( c.val.toLowerCase() );
return types.character( c.val.toLowerCase() );
});
@ -4636,10 +4658,10 @@ PARAMZ['exception-handler-key'] = types.exceptionHandlerKey;
/////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// getPrimitive: string (string | undefined) -> scheme-value
primitive.getPrimitive = function(name, resolvedModuleName) {
primitives.getPrimitive = function(name, resolvedModuleName) {
if (resolvedModuleName === undefined) {
return PRIMITIVES[name];
}
@ -4666,7 +4688,7 @@ primitive.getPrimitive = function(name, resolvedModuleName) {
return PRIMITIVES[name];
};
primitive.isPrimitive = function(x) {
primitives.isPrimitive = function(x) {
return x instanceof PrimProc;
};
@ -4674,5 +4696,6 @@ primitive.isPrimitive = function(x) {
})();
scope.link.announceReady('primitives');
})(this['plt']);

View File

@ -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;
@ -26,12 +23,10 @@
};
var isNumber = function(x) { return typeof(x) === 'number'; };
var isNatural = function(x) { return typeof(x) === 'number' &&
x >= 0 &&
Math.floor(x) === x; };
var isNumber = jsnums.isSchemeNumber;
var isNatural = function(x) { return (jsnums.isInteger(x) &&
jsnums.greaterThanOrEqual(x, 0)); }
var isPair = function(x) { return (typeof(x) == 'object' &&
x.length === 2 &&
@ -608,9 +603,9 @@
Primitives['pi'] = Math.PI;
Primitives['pi'] = jsnums.pi;
Primitives['e'] = Math.E;
Primitives['e'] = jsnums.e;
Primitives['='] = function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1];
@ -622,8 +617,8 @@
MACHINE.env[MACHINE.env.length - 1 - i],
i,
'=');
if (MACHINE.env[MACHINE.env.length - 1 - i] !==
MACHINE.env[MACHINE.env.length - 1 - i - 1]) {
if (! (jsnums.equals(MACHINE.env[MACHINE.env.length - 1 - i],
MACHINE.env[MACHINE.env.length - 1 - i - 1]))) {
return false;
}
}
@ -644,8 +639,8 @@
MACHINE.env[MACHINE.env.length - 1 - i],
i,
'<');
if (! (MACHINE.env[MACHINE.env.length - 1 - i] <
MACHINE.env[MACHINE.env.length - 1 - i - 1])) {
if (! (jsnums.lessThan(MACHINE.env[MACHINE.env.length - 1 - i],
MACHINE.env[MACHINE.env.length - 1 - i - 1]))) {
return false;
}
}
@ -665,8 +660,8 @@
MACHINE.env[MACHINE.env.length - 1 - i],
i,
'>');
if (! (MACHINE.env[MACHINE.env.length - 1 - i] >
MACHINE.env[MACHINE.env.length - 1 - i - 1])) {
if (! (jsnums.greaterThan(MACHINE.env[MACHINE.env.length - 1 - i],
MACHINE.env[MACHINE.env.length - 1 - i - 1]))) {
return false;
}
}
@ -686,8 +681,8 @@
MACHINE.env[MACHINE.env.length - 1 - i],
i,
'<=');
if (! (MACHINE.env[MACHINE.env.length - 1 - i] <=
MACHINE.env[MACHINE.env.length - 1 - i - 1])) {
if (! (jsnums.lessThanOrEqual(MACHINE.env[MACHINE.env.length - 1 - i],
MACHINE.env[MACHINE.env.length - 1 - i - 1]))) {
return false;
}
}
@ -708,8 +703,8 @@
MACHINE.env[MACHINE.env.length - 1 - i],
i,
'>=');
if (! (MACHINE.env[MACHINE.env.length - 1 - i] >=
MACHINE.env[MACHINE.env.length - 1 - i - 1])) {
if (! (jsnums.greaterThanOrEqual(MACHINE.env[MACHINE.env.length - 1 - i],
MACHINE.env[MACHINE.env.length - 1 - i - 1]))) {
return false;
}
}
@ -729,7 +724,7 @@
MACHINE.env[MACHINE.env.length - 1 - i],
i,
'+');
result += MACHINE.env[MACHINE.env.length - 1 - i];
result = jsnums.add(result, MACHINE.env[MACHINE.env.length - 1 - i]);
};
return result;
};
@ -747,7 +742,7 @@
MACHINE.env[MACHINE.env.length - 1 - i],
i,
'*');
result *= MACHINE.env[MACHINE.env.length - 1 - i];
result = jsnums.multiply(result, MACHINE.env[MACHINE.env.length - 1 - i]);
}
return result;
};
@ -762,7 +757,7 @@
MACHINE.env[MACHINE.env.length-1],
0,
'-');
return -(MACHINE.env[MACHINE.env.length-1]);
return jsnums.subtract(0, MACHINE.env[MACHINE.env.length-1]);
}
var result = MACHINE.env[MACHINE.env.length - 1];
for (var i = 1; i < MACHINE.argcount; i++) {
@ -772,7 +767,7 @@
MACHINE.env[MACHINE.env.length-1-i],
i,
'-');
result -= MACHINE.env[MACHINE.env.length - 1 - i];
result = jsnums.subtract(result, MACHINE.env[MACHINE.env.length - 1 - i]);
}
return result;
};
@ -794,7 +789,7 @@
MACHINE.env[MACHINE.env.length-1-i],
i,
'/');
result /= MACHINE.env[MACHINE.env.length - 1 - i];
result = jsnums.divide(result, MACHINE.env[MACHINE.env.length - 1 - i]);
}
return result;
};
@ -802,6 +797,47 @@
Primitives['/'].displayName = '/';
Primitives['add1'] = function(MACHINE) {
testArgument(MACHINE,
'number',
isNumber,
MACHINE.env[MACHINE.env.length - 1],
0,
'add1');
var firstArg = MACHINE.env[MACHINE.env.length-1];
return jsnums.add(firstArg, 1);
};
Primitives['add1'].arity = 1;
Primitives['add1'].displayName = 'add1';
Primitives['sub1'] = function(MACHINE) {
testArgument(MACHINE,
'number',
isNumber,
MACHINE.env[MACHINE.env.length - 1],
0,
'sub1');
var firstArg = MACHINE.env[MACHINE.env.length-1];
return jsnums.subtract(firstArg, 1);
};
Primitives['sub1'].arity = 1;
Primitives['sub1'].displayName = 'sub1';
Primitives['zero?'] = function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1];
return jsnums.equals(firstArg, 0);
};
Primitives['zero?'].arity = 1;
Primitives['zero?'].displayName = 'zero?';
Primitives['cons'] = function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1];
var secondArg = MACHINE.env[MACHINE.env.length-2];
@ -899,39 +935,6 @@
Primitives['null?'].arity = 1;
Primitives['null?'].displayName = 'null?';
Primitives['add1'] = function(MACHINE) {
testArgument(MACHINE,
'number',
isNumber,
MACHINE.env[MACHINE.env.length - 1],
0,
'add1');
var firstArg = MACHINE.env[MACHINE.env.length-1];
return firstArg + 1;
};
Primitives['add1'].arity = 1;
Primitives['add1'].displayName = 'add1';
Primitives['sub1'] = function(MACHINE) {
testArgument(MACHINE,
'number',
isNumber,
MACHINE.env[MACHINE.env.length - 1],
0,
'sub1');
var firstArg = MACHINE.env[MACHINE.env.length-1];
return firstArg - 1;
};
Primitives['sub1'].arity = 1;
Primitives['sub1'].displayName = 'sub1';
Primitives['zero?'] = function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1];
return firstArg === 0;
};
Primitives['zero?'].arity = 1;
Primitives['zero?'].displayName = 'zero?';
Primitives['vector'] = function(MACHINE) {
var i;
var result = [];
@ -997,7 +1000,7 @@
0,
'vector-set!');
var firstArg = MACHINE.env[MACHINE.env.length-1];
var secondArg = MACHINE.env[MACHINE.env.length-2];
var secondArg = jsnums.toFixnum(MACHINE.env[MACHINE.env.length-2]);
var thirdArg = MACHINE.env[MACHINE.env.length-3];
firstArg[secondArg] = thirdArg;
return null;
@ -1013,7 +1016,7 @@
MACHINE.env[MACHINE.env.length - 1],
0,
'vector-length');
var firstArg = MACHINE.env[MACHINE.env.length-1];
var firstArg = MACHINE.env[jsnums.toFixnum(MACHINE.env.length-1)];
return firstArg.length;
};
Primitives['vector-length'].arity = 1;
@ -1031,7 +1034,7 @@
if (MACHINE.argcount == 2) {
value = MACHINE.env[MACHINE.env.length - 2];
}
var length = MACHINE.env[MACHINE.env.length-1];
var length = jsnums.toFixnum(MACHINE.env[MACHINE.env.length-1]);
var arr = [];
for(var i = 0; i < length; i++) {
arr[i] = value;
@ -1343,8 +1346,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 +1371,7 @@
// Exports
var exports = runtime;
exports['currentMachine'] = new Machine();
exports['invokeMains'] = invokeMains;
@ -1433,4 +1436,6 @@
exports['HaltError'] = HaltError;
}).call(this);
scope.link.announceReady('runtime');
})(this['plt']);

View File

@ -1,15 +1,38 @@
if (! this['plt']) { this['plt'] = {}; }
// FIXME: there's a circularity between this module and helpers, and that circularly
// should not be there!
(function (scope) {
//////////////////////////////////////////////////////////////////////
// helper functions
//var jsnums = require('./js-numbers');
var types = {};
scope['types'] = types;
(function () {
// helpers refers to plt.helpers.
var helpers = scope['helpers'];
var getEqHashCode = helpers.getEqHashCode,
// makeLowLevelEqHash: -> hashtable
// Constructs an eq hashtable that uses Moby's getEqHashCode function.
makeLowLevelEqHash = helpers.makeLowLevelEqHash;
var toWrittenString = helpers.toWrittenString;
var toDisplayedString = helpers.toDisplayedString;
var toDomNode = helpers.toDomNode;
scope.link.ready('helpers', function() {
helpers = scope['helpers'];
getEqHashCode = helpers.getEqHashCode;
makeLowLevelEqHash = helpers.makeLowLevelEqHash;
toWrittenString = helpers.toWrittenString;
toDisplayedString = helpers.toDisplayedString;
toDomNode = helpers.toDomNode;
});
//////////////////////////////////////////////////////////////////////
var appendChild = function(parent, child) {
@ -21,7 +44,7 @@ var appendChild = function(parent, child) {
getEqHashCode = helpers.getEqHashCode;
@ -746,17 +769,6 @@ Cons.prototype.toWrittenString = function(cache) {
texts.push('.');
texts.push(toWrittenString(p, cache));
}
// while (true) {
// if ((!(p instanceof Cons)) && (!(p instanceof Empty))) {
// texts.push(".");
// texts.push(toWrittenString(p, cache));
// break;
// }
// if (p.isEmpty())
// break;
// texts.push(toWrittenString(p.first(), cache));
// p = p.rest();
// }
return "(" + texts.join(" ") + ")";
};
@ -1075,10 +1087,6 @@ String.prototype.toDisplayedString = function(cache) {
//////////////////////////////////////////////////////////////////////
// makeLowLevelEqHash: -> hashtable
// Constructs an eq hashtable that uses Moby's getEqHashCode function.
var makeLowLevelEqHash = helpers.makeLowLevelEqHash;
@ -1110,8 +1118,8 @@ EqHashTable.prototype.toDisplayedString = function(cache) {
var keys = this.hash.keys();
var ret = [];
for (var i = 0; i < keys.length; i++) {
var keyStr = types.toDisplayedString(keys[i], cache);
var valStr = types.toDisplayedString(this.hash.get(keys[i]), cache);
var keyStr = toDisplayedString(keys[i], cache);
var valStr = toDisplayedString(this.hash.get(keys[i]), cache);
ret.push('(' + keyStr + ' . ' + valStr + ')');
}
return ('#hasheq(' + ret.join(' ') + ')');
@ -1166,8 +1174,8 @@ EqualHashTable.prototype.toDisplayedString = function(cache) {
var keys = this.hash.keys();
var ret = [];
for (var i = 0; i < keys.length; i++) {
var keyStr = types.toDisplayedString(keys[i], cache);
var valStr = types.toDisplayedString(this.hash.get(keys[i]), cache);
var keyStr = toDisplayedString(keys[i], cache);
var valStr = toDisplayedString(this.hash.get(keys[i]), cache);
ret.push('(' + keyStr + ' . ' + valStr + ')');
}
return ('#hash(' + ret.join(' ') + ')');
@ -1342,180 +1350,6 @@ var makeRenderEffectType = function(name, superType, initFieldCnt, impl, guard)
var toWrittenString = function(x, cache) {
if (! cache) {
cache = makeLowLevelEqHash();
}
if (typeof(x) === 'object') {
if (cache.containsKey(x)) {
return "...";
}
}
if (x == undefined || x == null) {
return "#<undefined>";
}
if (typeof(x) == 'string') {
return escapeString(x.toString());
}
if (typeof(x) != 'object' && typeof(x) != 'function') {
return x.toString();
}
var returnVal;
if (typeof(x.toWrittenString) !== 'undefined') {
returnVal = x.toWrittenString(cache);
} else if (typeof(x.toDisplayedString) !== 'undefined') {
returnVal = x.toDisplayedString(cache);
} else {
returnVal = x.toString();
}
cache.remove(x);
return returnVal;
};
var toDisplayedString = function(x, cache) {
if (! cache) {
cache = makeLowLevelEqHash();
}
if (typeof(x) === 'object') {
if (cache.containsKey(x)) {
return "...";
}
}
if (x == undefined || x == null) {
return "#<undefined>";
}
if (typeof(x) == 'string') {
return x;
}
if (typeof(x) != 'object' && typeof(x) != 'function') {
return x.toString();
}
var returnVal;
if (typeof(x.toDisplayedString) !== 'undefined') {
returnVal = x.toDisplayedString(cache);
} else if (typeof(x.toWrittenString) !== 'undefined') {
returnVal = x.toWrittenString(cache);
} else {
returnVal = x.toString();
}
cache.remove(x);
return returnVal;
};
// toDomNode: scheme-value -> dom-node
var toDomNode = function(x, cache) {
if (! cache) {
cache = makeLowLevelEqHash();
}
if (isNumber(x)) {
return numberToDomNode(x);
}
if (typeof(x) == 'object') {
if (cache.containsKey(x)) {
var node = document.createElement("span");
node.appendChild(document.createTextNode("..."));
return node;
}
}
if (x == undefined || x == null) {
var node = document.createElement("span");
node.appendChild(document.createTextNode("#<undefined>"));
return node;
}
if (typeof(x) == 'string') {
var wrapper = document.createElement("span");
wrapper.style["white-space"] = "pre";
var node = document.createTextNode(toWrittenString(x));
wrapper.appendChild(node);
return wrapper;
}
if (typeof(x) != 'object' && typeof(x) != 'function') {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toString()));
return node;
}
var returnVal;
if (x.nodeType) {
returnVal = x;
} else if (typeof(x.toDomNode) !== 'undefined') {
returnVal = x.toDomNode(cache);
} else if (typeof(x.toWrittenString) !== 'undefined') {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toWrittenString(cache)));
returnVal = node;
} else if (typeof(x.toDisplayedString) !== 'undefined') {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toDisplayedString(cache)));
returnVal = node;
} else {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toString()));
returnVal = node;
}
cache.remove(x);
return returnVal;
};
// numberToDomNode: jsnum -> dom
// Given a jsnum, produces a dom-node representation.
var numberToDomNode = function(n) {
var node;
if (jsnums.isExact(n)) {
if (jsnums.isInteger(n)) {
node = document.createElement("span");
node.appendChild(document.createTextNode(n.toString()));
return node;
} else if (jsnums.isRational(n)) {
return rationalToDomNode(n);
} else if (jsnums.isComplex(n)) {
node = document.createElement("span");
node.appendChild(document.createTextNode(n.toString()));
return node;
} else {
node = document.createElement("span");
node.appendChild(document.createTextNode(n.toString()));
return node;
}
} else {
node = document.createElement("span");
node.appendChild(document.createTextNode(n.toString()));
return node;
}
};
// rationalToDomNode: rational -> dom-node
var rationalToDomNode = function(n) {
var node = document.createElement("span");
var chunks = jsnums.toRepeatingDecimal(jsnums.numerator(n),
jsnums.denominator(n));
node.appendChild(document.createTextNode(chunks[0] + '.'))
node.appendChild(document.createTextNode(chunks[1]));
var overlineSpan = document.createElement("span");
overlineSpan.style.textDecoration = 'overline';
overlineSpan.appendChild(document.createTextNode(chunks[2]));
node.appendChild(overlineSpan);
return node;
}
var isNumber = jsnums.isSchemeNumber;
var isReal = jsnums.isReal;
@ -2283,7 +2117,7 @@ types.exceptionHandlerKey = new Symbol("exnh");
types.symbol = Symbol.makeInstance;
types.rational = jsnums.makeRational;
types.float = jsnums.makeFloat;
types.floatpoint = jsnums.makeFloat;
types.complex = jsnums.makeComplex;
types.bignum = jsnums.makeBignum;
types.list = makeList;
@ -2291,7 +2125,7 @@ types.vector = makeVector;
types.vectorImmutable = makeVectorImmutable;
types.regexp = function(p) { return new RegularExpression(p) ; }
types.byteRegexp = function(p) { return new ByteRegularExpression(p) ; }
types['char'] = Char.makeInstance;
types.character = Char.makeInstance;
types['string'] = makeString;
types.box = function(x) { return new Box(x, true); };
types.placeholder = function(x) { return new Placeholder(x); };
@ -2306,10 +2140,6 @@ types.hashEq = makeHashEq;
types.jsValue = function(name, val) { return new JsValue(name, val); };
types.wrappedSchemeValue = function(val) { return new WrappedSchemeValue(val); };
types.toWrittenString = toWrittenString;
types.toDisplayedString = toDisplayedString;
types.toDomNode = toDomNode;
types.color = Color.constructor;
types.colorRed = function(x) { return Color.accessor(x, 0); };
@ -2528,5 +2358,7 @@ types.isRenderEffect = RenderEffect.predicate;
types.readerGraph = readerGraph;
})();
scope.link.announceReady('types');
})(this['plt']);

View File

@ -213,9 +213,15 @@ var comet = function() {
sendRequest("/eval",
function(req) {
// debug:
if (window.console && typeof(console.log) === 'function') { console.log(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) {