moving toWrittenString, toDisplayedString, and toDomNode up to helpers

This commit is contained in:
Danny Yoo 2011-06-03 11:32:06 -04:00
parent bea918820e
commit c3d89605ff
4 changed files with 261 additions and 243 deletions

13
NOTES
View File

@ -668,4 +668,15 @@ 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...
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.

View File

@ -35,9 +35,9 @@ if (! this['plt']) { this['plt'] = {}; }
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(' '), []) );
@ -54,19 +54,19 @@ if (! this['plt']) { this['plt'] = {}; }
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);
}
@ -184,7 +184,7 @@ if (! this['plt']) { this['plt'] = {}; }
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(' ');
@ -564,6 +564,188 @@ if (! this['plt']) { this['plt'] = {}; }
// 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;
@ -605,6 +787,12 @@ if (! this['plt']) { this['plt'] = {}; }
helpers.toWrittenString = toWrittenString;
helpers.toDisplayedString = toDisplayedString;
helpers.toDomNode = toDomNode;
scope.link.announceReady('helpers');
})(this['plt']);

View File

@ -620,7 +620,7 @@ That way, we can do a simple grep.
false,
true,
function(state, x) {
state.getPrintHook()(types.toWrittenString(x));
state.getPrintHook()(helpers.toDisplayedString(x));
state.v = types.VOID;
});
@ -1230,7 +1230,7 @@ That way, we can do a simple grep.
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(''), []) );
}
@ -1952,7 +1952,7 @@ That way, we can do a simple grep.
return jsnums.toExact(x);
} catch(e) {
raise( types.exnFailContract('inexact->exact: no exact representation for '
+ types.toWrittenString(x),
+ helpers.toDisplayedString(x),
false) );
}
});
@ -2525,7 +2525,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2533,7 +2533,7 @@ That way, we can do a simple grep.
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();
@ -2543,7 +2543,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2567,7 +2567,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2575,7 +2575,7 @@ That way, we can do a simple grep.
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();
@ -2727,7 +2727,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2740,7 +2740,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2758,7 +2758,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2770,7 +2770,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2789,7 +2789,7 @@ That way, we can do a simple grep.
//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,
[]) );
@ -2802,7 +2802,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2846,7 +2846,7 @@ That way, we can do a simple grep.
// 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,
[]) );
@ -2854,8 +2854,8 @@ That way, we can do a simple grep.
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,
[]) );
@ -2867,7 +2867,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2886,7 +2886,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2894,8 +2894,8 @@ That way, we can do a simple grep.
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,
[]) );
@ -2906,7 +2906,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -2925,7 +2925,7 @@ That way, we can do a simple grep.
//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,
[]) );
@ -2933,8 +2933,8 @@ That way, we can do a simple grep.
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,
[]) );
@ -2946,7 +2946,7 @@ That way, we can do a simple grep.
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,
[]) );
@ -3208,7 +3208,7 @@ That way, we can do a simple grep.
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);
@ -3373,7 +3373,7 @@ That way, we can do a simple grep.
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));
@ -3542,7 +3542,7 @@ That way, we can do a simple grep.
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 {
@ -3561,12 +3561,12 @@ That way, we can do a simple grep.
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) );
@ -3851,7 +3851,7 @@ That way, we can do a simple grep.
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);
@ -3997,7 +3997,7 @@ That way, we can do a simple grep.
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);
@ -4018,7 +4018,7 @@ That way, we can do a simple grep.
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);
@ -4039,7 +4039,7 @@ That way, we can do a simple grep.
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 {
@ -4059,13 +4059,13 @@ That way, we can do a simple grep.
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 {
@ -4244,7 +4244,7 @@ That way, we can do a simple grep.
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);
@ -4263,7 +4263,7 @@ That way, we can do a simple grep.
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);

View File

@ -14,15 +14,23 @@ if (! this['plt']) { this['plt'] = {}; }
var helpers = scope['helpers'];
var getEqHashCode, makeLowLevelEqHash;
// makeLowLevelEqHash: -> hashtable
// Constructs an eq hashtable that uses Moby's getEqHashCode function.
var makeLowLevelEqHash;
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;
});
@ -761,17 +769,6 @@ if (! this['plt']) { this['plt'] = {}; }
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(" ") + ")";
};
@ -1121,8 +1118,8 @@ String.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(' ') + ')');
@ -1177,8 +1174,8 @@ String.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(' ') + ')');
@ -1353,180 +1350,6 @@ String.prototype.toDisplayedString = function(cache) {
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;
@ -2317,10 +2140,6 @@ String.prototype.toDisplayedString = function(cache) {
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); };