Merge branch 'master' into inlining

Conflicts:

	compiler/compiler.rkt
	js-assembler/assemble.rkt
	tests/test-parse-bytecode.rkt
This commit is contained in:
Danny Yoo 2011-08-08 11:00:01 -04:00
commit 0d92fe0961
41 changed files with 4120 additions and 4076 deletions

File diff suppressed because it is too large Load Diff

View File

@ -391,7 +391,7 @@ var VideoImage = function(src, rawVideo) {
VideoImage.prototype = heir(BaseImage.prototype); VideoImage.prototype = heir(BaseImage.prototype);
videos = {}; var videos = {};
VideoImage.makeInstance = function(path, rawVideo) { VideoImage.makeInstance = function(path, rawVideo) {
if (! (path in VideoImage)) { if (! (path in VideoImage)) {
videos[path] = new VideoImage(path, rawVideo); videos[path] = new VideoImage(path, rawVideo);

View File

@ -44,7 +44,7 @@
(CaptureEnvironment-skip op))] (CaptureEnvironment-skip op))]
[(CaptureControl? op) [(CaptureControl? op)
(format "RUNTIME.captureControl(MACHINE, ~a, ~a)" (format "MACHINE.captureControl(~a, ~a)"
(CaptureControl-skip op) (CaptureControl-skip op)
(let: ([tag : (U DefaultContinuationPromptTag OpArg) (let: ([tag : (U DefaultContinuationPromptTag OpArg)
(CaptureControl-tag op)]) (CaptureControl-tag op)])

View File

@ -105,7 +105,7 @@ EOF
"MACHINE.env = MACHINE.env[MACHINE.env.length - 2].slice(0);"] "MACHINE.env = MACHINE.env[MACHINE.env.length - 2].slice(0);"]
[(RestoreControl!? op) [(RestoreControl!? op)
(format "RUNTIME.restoreControl(MACHINE, ~a);" (format "MACHINE.restoreControl(~a);"
(let: ([tag : (U DefaultContinuationPromptTag OpArg) (let: ([tag : (U DefaultContinuationPromptTag OpArg)
(RestoreControl!-tag op)]) (RestoreControl!-tag op)])
(cond (cond
@ -131,11 +131,11 @@ EOF
(assemble-oparg (SetFrameCallee!-proc op)))] (assemble-oparg (SetFrameCallee!-proc op)))]
[(SpliceListIntoStack!? op) [(SpliceListIntoStack!? op)
(format "RUNTIME.spliceListIntoStack(MACHINE, ~a);" (format "MACHINE.spliceListIntoStack(~a);"
(assemble-oparg (SpliceListIntoStack!-depth op)))] (assemble-oparg (SpliceListIntoStack!-depth op)))]
[(UnspliceRestFromStack!? op) [(UnspliceRestFromStack!? op)
(format "RUNTIME.unspliceRestFromStack(MACHINE, ~a, ~a);" (format "MACHINE.unspliceRestFromStack(~a, ~a);"
(assemble-oparg (UnspliceRestFromStack!-depth op)) (assemble-oparg (UnspliceRestFromStack!-depth op))
(assemble-oparg (UnspliceRestFromStack!-length op)))] (assemble-oparg (UnspliceRestFromStack!-length op)))]

View File

@ -117,8 +117,6 @@ EOF
(: write-linked-label-attributes ((Listof Statement) Output-Port -> 'ok)) (: write-linked-label-attributes ((Listof Statement) Output-Port -> 'ok))
(define (write-linked-label-attributes stmts op) (define (write-linked-label-attributes stmts op)
(cond (cond

View File

@ -8,7 +8,7 @@
(define-runtime-path js-vm-primitives.js "runtime-src/js-vm-primitives.js") (define-runtime-path js-vm-primitives.js "runtime-src/js-vm-primitives.js")
(define-runtime-path whalesong-primitives.js "runtime-src/runtime.js") (define-runtime-path whalesong-primitives.js "runtime-src/baselib-primitives.js")
;; sort&unique: (listof string) -> (listof string) ;; sort&unique: (listof string) -> (listof string)
(define (sort&unique names) (define (sort&unique names)

View File

@ -30,6 +30,8 @@
;; the other modules below have some circular dependencies that are resolved ;; the other modules below have some circular dependencies that are resolved
;; by link. ;; by link.
(define files '( (define files '(
top.js
;; jquery is special: we need to make sure it's resilient against ;; jquery is special: we need to make sure it's resilient against
;; multiple invokation and inclusion. ;; multiple invokation and inclusion.
jquery-protect-header.js jquery-protect-header.js
@ -65,6 +67,7 @@
baselib-ports.js baselib-ports.js
baselib-functions.js baselib-functions.js
baselib-modules.js baselib-modules.js
baselib-contmarks.js
baselib-arity.js baselib-arity.js
baselib-inspectors.js baselib-inspectors.js
@ -74,7 +77,8 @@
;; baselib-check has to come after the definitions of types, ;; baselib-check has to come after the definitions of types,
;; since it uses the type predicates immediately on init time. ;; since it uses the type predicates immediately on init time.
baselib-check.js baselib-check.js
baselib-primitives.js
runtime.js)) runtime.js))

View File

@ -333,7 +333,7 @@ MACHINE.modules[~s] =
<title>Example</title> <title>Example</title>
</head> </head>
<script> <script>
"use strict";
EOF EOF
) )
@ -375,10 +375,15 @@ var invokeMainModule = function() {
var MACHINE = plt.runtime.currentMachine; var MACHINE = plt.runtime.currentMachine;
invoke(MACHINE, invoke(MACHINE,
function() { function() {
var startTime = new Date().valueOf();
plt.runtime.invokeMains( plt.runtime.invokeMains(
MACHINE, MACHINE,
function() { function() {
// On main module invokation success // On main module invokation success:
var stopTime = new Date().valueOf();
if (console && console.log) {
console.log('evaluation took ' + (stopTime - startTime) + ' milliseconds');
}
}, },
function(MACHINE, e) { function(MACHINE, e) {
// On main module invokation failure // On main module invokation failure

View File

@ -1,11 +1,14 @@
/*jslint browser: false, unparam: true, vars: true, white: true, plusplus: true, maxerr: 50, indent: 4 */
// Arity structure // Arity structure
(function(baselib) { (function(baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.arity = exports; baselib.arity = exports;
var ArityAtLeast = plt.baselib.structs.makeStructureType( var ArityAtLeast = baselib.structs.makeStructureType(
'arity-at-least', false, 1, 0, false, false); 'arity-at-least', false, 1, 0, false, false);
@ -18,7 +21,7 @@
var arityAtLeastValue = function(x) { var arityAtLeastValue = function(x) {
var val = ArityAtLeast.accessor(x, 0); var val = ArityAtLeast.accessor(x, 0);
return val; return val;
} };
ArityAtLeast.type.prototype.toString = function() { ArityAtLeast.type.prototype.toString = function() {
@ -35,7 +38,7 @@
} else if (isArityAtLeast(arity)) { } else if (isArityAtLeast(arity)) {
return n >= arityAtLeastValue(arity); return n >= arityAtLeastValue(arity);
} else { } else {
while (arity !== plt.baselib.lists.EMPTY) { while (arity !== baselib.lists.EMPTY) {
if (typeof(arity.first) === 'number') { if (typeof(arity.first) === 'number') {
if (arity.first === n) { return true; } if (arity.first === n) { return true; }
} else if (isArityAtLeast(arity)) { } else if (isArityAtLeast(arity)) {
@ -45,7 +48,7 @@
} }
return false; return false;
} }
} };
@ -59,4 +62,4 @@
exports.isArityMatching = isArityMatching; exports.isArityMatching = isArityMatching;
exports.arityAtLeastValue = arityAtLeastValue; exports.arityAtLeastValue = arityAtLeastValue;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,6 +1,10 @@
/*jslint browser: true, unparam: true, vars: true, white: true, plusplus: true, maxerr: 50, indent: 4 */
// Exceptions // Exceptions
(function(baselib) { (function(baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.boxes = exports; baselib.boxes = exports;
@ -25,30 +29,30 @@
Box.prototype.toString = function(cache) { Box.prototype.toString = function(cache) {
cache.put(this, true); cache.put(this, true);
return "#&" + plt.baselib.format.toWrittenString(this.val, cache); return "#&" + baselib.format.toWrittenString(this.val, cache);
}; };
Box.prototype.toWrittenString = function(cache) { Box.prototype.toWrittenString = function(cache) {
cache.put(this, true); cache.put(this, true);
return "#&" + plt.baselib.format.toWrittenString(this.val, cache); return "#&" + baselib.format.toWrittenString(this.val, cache);
}; };
Box.prototype.toDisplayedString = function(cache) { Box.prototype.toDisplayedString = function(cache) {
cache.put(this, true); cache.put(this, true);
return "#&" + plt.baselib.format.toDisplayedString(this.val, cache); return "#&" + baselib.format.toDisplayedString(this.val, cache);
}; };
Box.prototype.toDomNode = function(cache) { Box.prototype.toDomNode = function(cache) {
cache.put(this, true); cache.put(this, true);
var parent = document.createElement("span"); var parent = document.createElement("span");
parent.appendChild(document.createTextNode('#&')); parent.appendChild(document.createTextNode('#&'));
parent.appendChild(plt.baselib.format.toDomNode(this.val, cache)); parent.appendChild(baselib.format.toDomNode(this.val, cache));
return parent; return parent;
}; };
Box.prototype.equals = function(other, aUnionFind) { Box.prototype.equals = function(other, aUnionFind) {
return ((other instanceof Box) && return ((other instanceof Box) &&
plt.baselib.equality.equals(this.val, other.val, aUnionFind)); baselib.equality.equals(this.val, other.val, aUnionFind));
}; };
var makeBox = function(x) { var makeBox = function(x) {
@ -83,4 +87,4 @@
exports.makeImmutableBox = makeImmutableBox; exports.makeImmutableBox = makeImmutableBox;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,5 +1,9 @@
// Arity structure /*jslint unparam: true, vars: true, white: true, plusplus: true, maxerr: 50, indent: 4 */
(function(baselib) { (function(baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.bytes = exports; baselib.bytes = exports;
@ -30,7 +34,7 @@
}; };
Bytes.prototype.subbytes = function(start, end) { Bytes.prototype.subbytes = function(start, end) {
if (end == null || end == undefined) { if (end === null || end === undefined) {
end = this.bytes.length; end = this.bytes.length;
} }
@ -42,23 +46,25 @@
if (! (other instanceof Bytes)) { if (! (other instanceof Bytes)) {
return false; return false;
} }
if (this.bytes.length != other.bytes.length) { if (this.bytes.length !== other.bytes.length) {
return false; return false;
} }
var A = this.bytes; var A = this.bytes;
var B = other.bytes; var B = other.bytes;
var n = this.bytes.length; var n = this.bytes.length;
for (var i = 0; i < n; i++) { var i;
if (A[i] !== B[i]) for (i = 0; i < n; i++) {
if (A[i] !== B[i]) {
return false; return false;
}
} }
return true; return true;
}; };
Bytes.prototype.toString = function(cache) { Bytes.prototype.toString = function(cache) {
var ret = ''; var ret = '', i;
for (var i = 0; i < this.bytes.length; i++) { for (i = 0; i < this.bytes.length; i++) {
ret += String.fromCharCode(this.bytes[i]); ret += String.fromCharCode(this.bytes[i]);
} }
@ -67,15 +73,6 @@
Bytes.prototype.toDisplayedString = Bytes.prototype.toString; Bytes.prototype.toDisplayedString = Bytes.prototype.toString;
Bytes.prototype.toWrittenString = function() {
var ret = ['#"'];
for (var i = 0; i < this.bytes.length; i++) {
ret.push( escapeByte(this.bytes[i]) );
}
ret.push('"');
return ret.join('');
};
var escapeByte = function(aByte) { var escapeByte = function(aByte) {
var ret = []; var ret = [];
var returnVal; var returnVal;
@ -100,8 +97,18 @@
return returnVal; return returnVal;
}; };
Bytes.prototype.toWrittenString = function() {
var ret = ['#"'], i;
for (i = 0; i < this.bytes.length; i++) {
ret.push(escapeByte(this.bytes[i]));
}
ret.push('"');
return ret.join('');
};
exports.Bytes = Bytes; exports.Bytes = Bytes;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -6,7 +6,7 @@
// Chars // Chars
// Char: string -> Char // Char: string -> Char
Char = function(val){ var Char = function(val){
this.val = val; this.val = val;
}; };
// The characters less than 256 must be eq?, according to the // The characters less than 256 must be eq?, according to the

View File

@ -1,55 +1,82 @@
/*jslint vars: true, white: true, plusplus: true, maxerr: 50, indent: 4 */
// Helper functions for argument checking. // Helper functions for argument checking.
(function(baselib) { (function (baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.check = exports; baselib.check = exports;
var EMPTY = plt.baselib.lists.EMPTY; var EMPTY = baselib.lists.EMPTY;
var isPair = plt.baselib.lists.isPair; var isPair = baselib.lists.isPair;
var makeLowLevelEqHash = plt.baselib.hashes.makeLowLevelEqHash; var makeLowLevelEqHash = baselib.hashes.makeLowLevelEqHash;
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
var makeCheckArgumentType = function(predicate, predicateName) { // testArgument: (X -> boolean) X number string string -> boolean
return function(MACHINE, callerName, position) { // Produces true if val is true, and otherwise raises an error.
testArgument( var testArgument = function (MACHINE,
MACHINE, expectedTypeName,
predicateName, predicate,
predicate, val,
MACHINE.env[MACHINE.env.length - 1 - position], index,
position, callerName) {
callerName); if (predicate(val)) {
return MACHINE.env[MACHINE.env.length - 1 - position]; return true;
} } else {
if (typeof(expectedTypeName) === 'function') {
expectedTypeName = expectedTypeName();
}
baselib.exceptions.raiseArgumentTypeError(MACHINE,
callerName,
expectedTypeName,
index,
val);
}
}; };
var makeCheckParameterizedArgumentType = function(parameterizedPredicate,
parameterizedPredicateName) { var makeCheckArgumentType = function (predicate, predicateName) {
return function(MACHINE, callerName, position) { return function (MACHINE, callerName, position) {
var args = []; testArgument(
for (var i = 3; i < arguments.length; i++) { MACHINE,
predicateName,
predicate,
MACHINE.env[MACHINE.env.length - 1 - position],
position,
callerName);
return MACHINE.env[MACHINE.env.length - 1 - position];
};
};
var makeCheckParameterizedArgumentType = function (parameterizedPredicate,
parameterizedPredicateName) {
return function (MACHINE, callerName, position) {
var args = [], i;
for (i = 3; i < arguments.length; i++) {
args.push(arguments[i]); args.push(arguments[i]);
} }
testArgument( testArgument(
MACHINE, MACHINE,
parameterizedPredicateName.apply(null, args), function () { parameterizedPredicateName.apply(null, args); },
function(x) { function (x) {
return parameterizedPredicate.apply(null, [x].concat(args)); return parameterizedPredicate.apply(null, [x].concat(args));
}, },
MACHINE.env[MACHINE.env.length - 1 - position], MACHINE.env[MACHINE.env.length - 1 - position],
position, position,
callerName); callerName);
return MACHINE.env[MACHINE.env.length - 1 - position]; return MACHINE.env[MACHINE.env.length - 1 - position];
} };
}; };
var makeCheckListofArgumentType = function(predicate, predicateName) { var makeCheckListofArgumentType = function (predicate, predicateName) {
var listPredicate = function(x) { var listPredicate = function (x) {
var seen = makeLowLevelEqHash(); var seen = makeLowLevelEqHash();
while (true) { while (true) {
if (x === EMPTY){ if (x === EMPTY){
@ -62,7 +89,7 @@
if(seen.containsKey(x)) { if(seen.containsKey(x)) {
// raise an error? we've got a cycle! // raise an error? we've got a cycle!
return false return false;
} }
if (! predicate(x.first)) { if (! predicate(x.first)) {
@ -73,16 +100,16 @@
x = x.rest; x = x.rest;
} }
}; };
return function(MACHINE, callerName, position) { return function (MACHINE, callerName, position) {
testArgument( testArgument(
MACHINE, MACHINE,
'list of ' + predicateName, 'list of ' + predicateName,
listPredicate, listPredicate,
MACHINE.env[MACHINE.env.length - 1 - position], MACHINE.env[MACHINE.env.length - 1 - position],
position, position,
callerName); callerName);
return MACHINE.env[MACHINE.env.length - 1 - position]; return MACHINE.env[MACHINE.env.length - 1 - position];
} };
}; };
@ -90,132 +117,111 @@
// testArgument: (X -> boolean) X number string string -> boolean
// Produces true if val is true, and otherwise raises an error.
var testArgument = function(MACHINE,
expectedTypeName,
predicate,
val,
index,
callerName) {
if (predicate(val)) {
return true;
} else {
plt.baselib.exceptions.raiseArgumentTypeError(MACHINE,
callerName,
expectedTypeName,
index,
val);
}
};
var testArity = function(callerName, observed, minimum, maximum) { var testArity = function (MACHINE, callerName, observed, minimum, maximum) {
if (observed < minimum || observed > maximum) { if (observed < minimum || observed > maximum) {
plt.baselib.exceptions.raise( baselib.exceptions.raise(
MACHINE, new Error(callerName + ": expected at least " + minimum MACHINE, new Error(callerName + ": expected at least " + minimum
+ " arguments " + " arguments "
+ " but received " + observed)); + " but received " + observed));
} }
}; };
var checkOutputPort = makeCheckArgumentType( var checkOutputPort = makeCheckArgumentType(
plt.baselib.ports.isOutputPort, baselib.ports.isOutputPort,
'output port'); 'output port');
var checkSymbol = makeCheckArgumentType( var checkSymbol = makeCheckArgumentType(
plt.baselib.symbols.isSymbol, baselib.symbols.isSymbol,
'symbol'); 'symbol');
var checkString = makeCheckArgumentType( var checkString = makeCheckArgumentType(
plt.baselib.strings.isString, baselib.strings.isString,
'string'); 'string');
var checkMutableString = makeCheckArgumentType( var checkMutableString = makeCheckArgumentType(
plt.baselib.strings.isMutableString, baselib.strings.isMutableString,
'mutable string'); 'mutable string');
var checkChar = makeCheckArgumentType( var checkChar = makeCheckArgumentType(
plt.baselib.chars.isChar, baselib.chars.isChar,
'character'); 'character');
var checkProcedure = makeCheckArgumentType( var checkProcedure = makeCheckArgumentType(
plt.baselib.functions.isProcedure, baselib.functions.isProcedure,
'procedure'); 'procedure');
var checkNumber = makeCheckArgumentType( var checkNumber = makeCheckArgumentType(
plt.baselib.numbers.isNumber, baselib.numbers.isNumber,
'number'); 'number');
var checkReal = makeCheckArgumentType( var checkReal = makeCheckArgumentType(
plt.baselib.numbers.isReal, baselib.numbers.isReal,
'real'); 'real');
var checkNatural = makeCheckArgumentType( var checkNatural = makeCheckArgumentType(
plt.baselib.numbers.isNatural, baselib.numbers.isNatural,
'natural'); 'natural');
var checkByte = makeCheckArgumentType( var checkByte = makeCheckArgumentType(
function(x) { return (typeof(x) === 'number' && 0 <= x && x < 256) }, baselib.numbers.isByte,
'byte'); 'byte');
var checkNaturalInRange = makeCheckParameterizedArgumentType( var checkNaturalInRange = makeCheckParameterizedArgumentType(
function(x, a, b) { function (x, a, b) {
if (! plt.baselib.numbers.isNatural(x)) { return false; } if (! baselib.numbers.isNatural(x)) { return false; }
return (plt.baselib.numbers.lessThanOrEqual(a, x) && return (baselib.numbers.lessThanOrEqual(a, x) &&
plt.baselib.numbers.lessThan(x, b)); baselib.numbers.lessThan(x, b));
}, },
function(a, b) { function (a, b) {
return plt.baselib.format.format('natural between ~a and ~a', [a, b]); return baselib.format.format('natural between ~a and ~a', [a, b]);
}); });
var checkInteger = makeCheckArgumentType( var checkInteger = makeCheckArgumentType(
plt.baselib.numbers.isInteger, baselib.numbers.isInteger,
'integer'); 'integer');
var checkRational = makeCheckArgumentType( var checkRational = makeCheckArgumentType(
plt.baselib.numbers.isRational, baselib.numbers.isRational,
'rational'); 'rational');
var checkNonNegativeReal = makeCheckArgumentType( var checkNonNegativeReal = makeCheckArgumentType(
plt.baselib.numbers.isNonNegativeReal, baselib.numbers.isNonNegativeReal,
'non-negative real'); 'non-negative real');
var checkPair = makeCheckArgumentType( var checkPair = makeCheckArgumentType(
plt.baselib.lists.isPair, baselib.lists.isPair,
'pair'); 'pair');
var checkList = makeCheckArgumentType( var checkList = makeCheckArgumentType(
plt.baselib.lists.isList, baselib.lists.isList,
'list'); 'list');
var checkVector = makeCheckArgumentType( var checkVector = makeCheckArgumentType(
plt.baselib.vectors.isVector, baselib.vectors.isVector,
'vector'); 'vector');
var checkBoolean = makeCheckArgumentType( var checkBoolean = makeCheckArgumentType(
function(x) { return x === true || x === false; }, function (x) { return x === true || x === false; },
'boolean'); 'boolean');
var checkBox = makeCheckArgumentType( var checkBox = makeCheckArgumentType(
plt.baselib.boxes.isBox, baselib.boxes.isBox,
'box'); 'box');
var checkMutableBox = makeCheckArgumentType( var checkMutableBox = makeCheckArgumentType(
plt.baselib.boxes.isMutableBox, baselib.boxes.isMutableBox,
'mutable box'); 'mutable box');
var checkInspector = makeCheckArgumentType( var checkInspector = makeCheckArgumentType(
plt.baselib.inspectors.isInspector, baselib.inspectors.isInspector,
'inspector'); 'inspector');
var checkByte = makeCheckArgumentType(
plt.baselib.numbers.isByte,
'byte');
@ -255,4 +261,4 @@
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,25 +1,29 @@
/*jslint vars: true, maxerr: 50, indent: 4 */
// Other miscellaneous constants // Other miscellaneous constants
(function(baselib) { (function (baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.constants = exports; baselib.constants = exports;
var VoidValue = function() {}; var VoidValue = function () {};
VoidValue.prototype.toString = function() { VoidValue.prototype.toString = function () {
return "#<void>"; return "#<void>";
}; };
var VOID_VALUE = new VoidValue(); var VOID_VALUE = new VoidValue();
var EofValue = function() {}; var EofValue = function () {};
EofValue.prototype.toString = function() { EofValue.prototype.toString = function () {
return "#<eof>"; return "#<eof>";
} };
var EOF_VALUE = new EofValue(); var EOF_VALUE = new EofValue();
exports.VOID_VALUE = VOID_VALUE; exports.VOID_VALUE = VOID_VALUE;
exports.EOF_VALUE = EOF_VALUE; exports.EOF_VALUE = EOF_VALUE;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,12 +1,15 @@
/*jslint browser: true, unparam: true, vars: true, white: true, maxerr: 50, indent: 4 */
// Continuation marks // Continuation marks
(function(baselib) { (function(baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.contmarks = exports; baselib.contmarks = exports;
var ContinuationMarkSet = function(dict) { var ContinuationMarkSet = function(dict) {
this.dict = dict; this.dict = dict;
} };
ContinuationMarkSet.prototype.toDomNode = function(cache) { ContinuationMarkSet.prototype.toDomNode = function(cache) {
var dom = document.createElement("span"); var dom = document.createElement("span");
@ -29,7 +32,20 @@
return []; return [];
}; };
// A continuation prompt tag labels a prompt frame.
var ContinuationPromptTag = function(name) {
this.name = name;
};
exports.ContinuationMarkSet = ContinuationMarkSet; exports.ContinuationMarkSet = ContinuationMarkSet;
exports.ContinuationPromptTag = ContinuationPromptTag;
}(this.plt.baselib));
})(this['plt'].baselib);

View File

@ -1,19 +1,24 @@
/*jslint vars: true, white: true, maxerr: 50, indent: 4 */
// Equality function // Equality function
(function(baselib) { /*global jsnums*/
(function (baselib, jsnums) {
'use strict';
var exports = {}; var exports = {};
baselib.equality = exports; baselib.equality = exports;
var eqv = function(x, y) { var eqv = function (x, y) {
if (x === y) { return true; } if (x === y) { return true; }
if (plt.baselib.numbers.isNumber(x) && plt.baselib.numbers.isNumber(y)) { if (baselib.numbers.isNumber(x) && baselib.numbers.isNumber(y)) {
return jsnums.eqv(x, y); return jsnums.eqv(x, y);
} else if (plt.baselib.chars.isChar(x) && plt.baselib.chars.isChar(y)) { } else if (baselib.chars.isChar(x) && baselib.chars.isChar(y)) {
return x.val === y.val; return x.val === y.val;
} else { } else {
return false; return false;
} }
}; };
@ -22,42 +27,39 @@
// equals: X Y -> boolean // equals: X Y -> boolean
// Returns true if the objects are equivalent; otherwise, returns false. // Returns true if the objects are equivalent; otherwise, returns false.
var equals = function(x, y, aUnionFind) { var equals = function (x, y, aUnionFind) {
if (x === y) { return true; } if (x === y) { return true; }
if (plt.baselib.numbers.isNumber(x) && plt.baselib.numbers.isNumber(y)) { if (baselib.numbers.isNumber(x) && baselib.numbers.isNumber(y)) {
return plt.baselib.numbers.eqv(x, y); return baselib.numbers.eqv(x, y);
} }
if (baselib.strings.isString(x) && baselib.strings.isString(y)) { if (baselib.strings.isString(x) && baselib.strings.isString(y)) {
return x.toString() === y.toString(); return x.toString() === y.toString();
} }
if (x == undefined || x == null) { if (x === undefined || x === null) {
return (y == undefined || y == null); return (y === undefined || y === null);
} }
if ( typeof(x) == 'object' && if (typeof (x) === 'object' && typeof (y) === 'object' &&
typeof(y) == 'object' && x.equals && y.equals) {
x.equals && if (typeof (aUnionFind) === 'undefined') {
y.equals) { aUnionFind = new baselib.UnionFind();
}
if (typeof (aUnionFind) === 'undefined') { if (aUnionFind.find(x) === aUnionFind.find(y)) {
aUnionFind = new plt.baselib.UnionFind(); return true;
} }
else {
if (aUnionFind.find(x) === aUnionFind.find(y)) { aUnionFind.merge(x, y);
return true; return x.equals(y, aUnionFind);
} }
else {
aUnionFind.merge(x, y);
return x.equals(y, aUnionFind);
}
} }
return false; return false;
}; };
exports.eqv = eqv;
exports.equals = equals; exports.equals = equals;
})(this['plt'].baselib); }(this.plt.baselib, jsnums));

View File

@ -1,6 +1,9 @@
/*jslint browser: true, undef: false, unparam: true, sub: true, vars: true, white: true, plusplus: true, maxerr: 50, indent: 4 */
// Exceptions // Exceptions
(function(baselib) { (function(baselib) {
'use strict';
var exceptions = {}; var exceptions = {};
baselib.exceptions = exceptions; baselib.exceptions = exceptions;
@ -8,53 +11,53 @@
// Error type exports // Error type exports
var InternalError = function(val, contMarks) { var InternalError = function(val, contMarks) {
this.val = val; this.val = val;
this.contMarks = (contMarks ? contMarks : false); this.contMarks = contMarks || false;
} };
var SchemeError = function(val) { var SchemeError = function(val) {
this.val = val; this.val = val;
} };
var IncompleteExn = function(constructor, msg, otherArgs) { var IncompleteExn = function(constructor, msg, otherArgs) {
this.constructor = constructor; this.constructor = constructor;
this.msg = msg; this.msg = msg;
this.otherArgs = otherArgs; this.otherArgs = otherArgs;
}; };
// (define-struct exn (message continuation-mark-set)) // (define-struct exn (message continuation-mark-set))
var Exn = plt.baselib.structs.makeStructureType( var Exn = baselib.structs.makeStructureType(
'exn', false, 2, 0, false, false); 'exn', false, 2, 0, false, false);
// (define-struct (exn:break exn) (continuation)) // (define-struct (exn:break exn) (continuation))
var ExnBreak = plt.baselib.structs.makeStructureType( var ExnBreak = baselib.structs.makeStructureType(
'exn:break', Exn, 1, 0, false, false); 'exn:break', Exn, 1, 0, false, false);
var ExnFail = plt.baselib.structs.makeStructureType( var ExnFail = baselib.structs.makeStructureType(
'exn:fail', Exn, 0, 0, false, false); 'exn:fail', Exn, 0, 0, false, false);
var ExnFailContract = plt.baselib.structs.makeStructureType( var ExnFailContract = baselib.structs.makeStructureType(
'exn:fail:contract', ExnFail, 0, 0, false, false); 'exn:fail:contract', ExnFail, 0, 0, false, false);
var ExnFailContractArity = plt.baselib.structs.makeStructureType( var ExnFailContractArity = baselib.structs.makeStructureType(
'exn:fail:contract:arity', ExnFailContract, 0, 0, false, false); 'exn:fail:contract:arity', ExnFailContract, 0, 0, false, false);
var ExnFailContractVariable = plt.baselib.structs.makeStructureType( var ExnFailContractVariable = baselib.structs.makeStructureType(
'exn:fail:contract:variable', ExnFailContract, 1, 0, false, false); 'exn:fail:contract:variable', ExnFailContract, 1, 0, false, false);
var ExnFailContractDivisionByZero = plt.baselib.structs.makeStructureType( var ExnFailContractDivisionByZero = baselib.structs.makeStructureType(
'exn:fail:contract:divide-by-zero', ExnFailContract, 0, 0, false, false); 'exn:fail:contract:divide-by-zero', ExnFailContract, 0, 0, false, false);
var exceptionHandlerKey = new plt.baselib.symbols.Symbol("exnh"); var exceptionHandlerKey = new baselib.symbols.Symbol("exnh");
@ -72,13 +75,13 @@
e.message = Exn.accessor(e, 0); e.message = Exn.accessor(e, 0);
} }
if (typeof(window['console']) !== 'undefined' && if (typeof(window.console) !== 'undefined' &&
typeof(console['log']) === 'function') { typeof(window.console['log']) === 'function') {
console.log(MACHINE); window.console.log(MACHINE);
if (e['stack']) { console.log(e['stack']); } if (e['stack']) { window.console.log(e['stack']); }
else { console.log(e); } else { window.console.log(e); }
} }
throw e; throw e;
}; };
@ -86,10 +89,10 @@
var raiseUnboundToplevelError = function(MACHINE, name) { var raiseUnboundToplevelError = function(MACHINE, name) {
raise(MACHINE, raise(MACHINE,
new Error( new Error(
plt.baselib.format.format( baselib.format.format(
"Not bound: ~a", "Not bound: ~a",
[name]))); [name])));
}; };
@ -99,70 +102,69 @@
argumentOffset, argumentOffset,
actualValue) { actualValue) {
if (argumentOffset !== undefined) { if (argumentOffset !== undefined) {
raise(MACHINE, raise(MACHINE,
new Error( new Error(
plt.baselib.format.format( baselib.format.format(
"~a: expected ~a as argument ~e but received ~e", "~a: expected ~a as argument ~e but received ~e",
[callerName, [callerName,
expectedTypeName, expectedTypeName,
(argumentOffset + 1), (argumentOffset + 1),
actualValue]))); actualValue])));
} else { } else {
raise(MACHINE, raise(MACHINE,
new Error( new Error(
plt.baselib.format.format( baselib.format.format(
"~a: expected ~a but received ~e", "~a: expected ~a but received ~e",
[callerName, [callerName,
expectedTypeName, expectedTypeName,
actualValue]))); actualValue])));
} }
}; };
var raiseContextExpectedValuesError = function(MACHINE, expected) { var raiseContextExpectedValuesError = function(MACHINE, expected) {
raise(MACHINE, raise(MACHINE,
new Error(plt.baselib.format.format( new Error(baselib.format.format(
"expected ~e values, received ~e values" "expected ~e values, received ~e values",
[expected, [expected, MACHINE.argcount])));
MACHINE.argcount])));
}; };
var raiseArityMismatchError = function(MACHINE, proc, expected, received) { var raiseArityMismatchError = function(MACHINE, proc, expected, received) {
raise(MACHINE, raise(MACHINE,
new Error(plt.baselib.format.format( new Error(baselib.format.format(
"~a: expected ~e value(s), received ~e value(s)", "~a: expected ~e value(s), received ~e value(s)",
[proc.displayName, [proc.displayName,
expected , expected,
received]))) received])));
}; };
var raiseOperatorApplicationError = function(MACHINE, operator) { var raiseOperatorApplicationError = function(MACHINE, operator) {
raise(MACHINE, raise(MACHINE,
new Error( new Error(
plt.baselib.format.format( baselib.format.format(
"not a procedure: ~e", "not a procedure: ~e",
[operator]))); [operator])));
}; };
var raiseOperatorIsNotClosure = function(MACHINE, operator) { var raiseOperatorIsNotClosure = function(MACHINE, operator) {
raise(MACHINE, raise(MACHINE,
new Error( new Error(
plt.baselib.format.format( baselib.format.format(
"not a closure: ~e", "not a closure: ~e",
[operator]))); [operator])));
}; };
var raiseOperatorIsNotPrimitiveProcedure = function(MACHINE, operator) { var raiseOperatorIsNotPrimitiveProcedure = function(MACHINE, operator) {
raise(MACHINE, raise(MACHINE,
new Error( new Error(
plt.baselib.format.format( baselib.format.format(
"not a primitive procedure: ~e", "not a primitive procedure: ~e",
[operator]))); [operator])));
}; };
var raiseUnimplementedPrimitiveError = function(MACHINE, name) { var raiseUnimplementedPrimitiveError = function(MACHINE, name) {
raise(MACHINE, raise(MACHINE,
new Error("unimplemented kernel procedure: " + name)) new Error("unimplemented kernel procedure: " + name));
}; };
@ -245,4 +247,4 @@
exceptions.raiseUnimplementedPrimitiveError = raiseUnimplementedPrimitiveError; exceptions.raiseUnimplementedPrimitiveError = raiseUnimplementedPrimitiveError;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,79 +1,54 @@
/*jslint browser: true, undef: false, unparam: true, sub: true, vars: true, white: true, plusplus: true, maxerr: 50, indent: 4 */
// Formatting library. // Formatting library.
// Produces string and DOM representations of values. // Produces string and DOM representations of values.
// //
(function(baselib) { /*global $*/
(function(baselib, $) {
'use strict';
var exports = {}; var exports = {};
baselib.format = exports; baselib.format = exports;
var replaceUnprintableStringChars = function(s) {
// format: string [X ...] string -> string var ret = [], i;
// String formatting. If an exception occurs, throws for (i = 0; i < s.length; i++) {
// a plain Error whose message describes the formatting error. var val = s.charCodeAt(i);
var format = function(formatStr, args, functionName) { switch(val) {
var throwFormatError = function() { case 7: ret.push('\\a'); break;
functionName = functionName || 'format'; case 8: ret.push('\\b'); break;
var matches = formatStr.match(new RegExp('~[sSaA]', 'g')); case 9: ret.push('\\t'); break;
var expectedNumberOfArgs = (matches === null ? 0 : matches.length); case 10: ret.push('\\n'); break;
var errorStrBuffer = [functionName + ': format string requires ' + expectedNumberOfArgs case 11: ret.push('\\v'); break;
+ ' arguments, given ' + args.length + '; arguments were:', case 12: ret.push('\\f'); break;
toWrittenString(formatStr)]; case 13: ret.push('\\r'); break;
for (var i = 0; i < args.length; i++) { case 34: ret.push('\\"'); break;
errorStrBuffer.push( toWrittenString(args[i]) ); case 92: ret.push('\\\\'); break;
} default: if (val >= 32 && val <= 126) {
ret.push( s.charAt(i) );
throw new Error(errorStrBuffer.join(' '));
}
var pattern = new RegExp("~[sSaAnevE%~]", "g");
var buffer = args.slice(0);
var onTemplate = function(s) {
if (s === "~~") {
return "~";
} else if (s === '~n' || s === '~%') {
return "\n";
} else if (s === '~s' || s === "~S") {
if (buffer.length === 0) {
throwFormatError();
}
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 toWrittenString(buffer.shift());
} }
else if (s === '~v') { else {
if (buffer.length === 0) { var numStr = val.toString(16).toUpperCase();
throwFormatError(); while (numStr.length < 4) {
} numStr = '0' + numStr;
// fprintf must do something more interesting here by }
// printing the dom representation directly... ret.push('\\u' + numStr);
return toWrittenString(buffer.shift()); }
} else if (s === '~a' || s === "~A") { break;
if (buffer.length === 0) { }
throwFormatError(); }
} return ret.join('');
return toDisplayedString(buffer.shift()); };
} else {
throw new Error(functionName + var escapeString = function(s) {
': string.replace matched invalid regexp'); return '"' + replaceUnprintableStringChars(s) + '"';
}
}
var result = formatStr.replace(pattern, onTemplate);
if (buffer.length > 0) {
throwFormatError();
}
return result;
}; };
// toWrittenString: Any Hashtable -> String // toWrittenString: Any Hashtable -> String
var toWrittenString = function(x, cache) { var toWrittenString = function(x, cache) {
if (! cache) { if (! cache) {
cache = plt.baselib.hashes.makeLowLevelEqHash(); cache = baselib.hashes.makeLowLevelEqHash();
} }
if (x === null) { if (x === null) {
return "null"; return "null";
@ -81,27 +56,27 @@
if (x === true) { return "true"; } if (x === true) { return "true"; }
if (x === false) { return "false"; } if (x === false) { return "false"; }
if (typeof(x) === 'object') { if (typeof(x) === 'object') {
if (cache.containsKey(x)) { if (cache.containsKey(x)) {
return "..."; return "...";
} }
} }
if (x == undefined) { if (x === undefined) {
return "#<undefined>"; return "#<undefined>";
} }
if (typeof(x) == 'string') { if (typeof(x) === 'string') {
return escapeString(x.toString()); return escapeString(x.toString());
} }
if (typeof(x) != 'object' && typeof(x) != 'function') { if (typeof(x) !== 'object' && typeof(x) !== 'function') {
return x.toString(); return x.toString();
} }
var returnVal; var returnVal;
if (typeof(x.toWrittenString) !== 'undefined') { if (typeof(x.toWrittenString) !== 'undefined') {
returnVal = x.toWrittenString(cache); returnVal = x.toWrittenString(cache);
} else if (typeof(x.toDisplayedString) !== 'undefined') { } else if (typeof(x.toDisplayedString) !== 'undefined') {
returnVal = x.toDisplayedString(cache); returnVal = x.toDisplayedString(cache);
} else { } else {
returnVal = x.toString(); returnVal = x.toString();
} }
cache.remove(x); cache.remove(x);
return returnVal; return returnVal;
@ -112,7 +87,7 @@
// toDisplayedString: Any Hashtable -> String // toDisplayedString: Any Hashtable -> String
var toDisplayedString = function(x, cache) { var toDisplayedString = function(x, cache) {
if (! cache) { if (! cache) {
cache = plt.baselib.hashes.makeLowLevelEqHash(); cache = baselib.hashes.makeLowLevelEqHash();
} }
if (x === null) { if (x === null) {
return "null"; return "null";
@ -120,41 +95,108 @@
if (x === true) { return "true"; } if (x === true) { return "true"; }
if (x === false) { return "false"; } if (x === false) { return "false"; }
if (typeof(x) === 'object') { if (typeof(x) === 'object') {
if (cache.containsKey(x)) { if (cache.containsKey(x)) {
return "..."; return "...";
} }
} }
if (x == undefined || x == null) { if (x === undefined || x === null) {
return "#<undefined>"; return "#<undefined>";
} }
if (typeof(x) == 'string') { if (typeof(x) === 'string') {
return x; return x;
} }
if (typeof(x) != 'object' && typeof(x) != 'function') { if (typeof(x) !== 'object' && typeof(x) !== 'function') {
return x.toString(); return x.toString();
} }
var returnVal; var returnVal;
if (typeof(x.toDisplayedString) !== 'undefined') { if (typeof(x.toDisplayedString) !== 'undefined') {
returnVal = x.toDisplayedString(cache); returnVal = x.toDisplayedString(cache);
} else if (typeof(x.toWrittenString) !== 'undefined') { } else if (typeof(x.toWrittenString) !== 'undefined') {
returnVal = x.toWrittenString(cache); returnVal = x.toWrittenString(cache);
} else { } else {
returnVal = x.toString(); returnVal = x.toString();
} }
cache.remove(x); cache.remove(x);
return returnVal; return returnVal;
}; };
var formatRegexp1 = new RegExp('~[sSaA]', 'g');
var formatRegexp2 = new RegExp("~[sSaAnevE%~]", "g");
// format: string [X ...] string -> string
// String formatting. If an exception occurs, throws
// a plain Error whose message describes the formatting error.
var format = function(formatStr, args, functionName) {
var throwFormatError = function() {
functionName = functionName || 'format';
var matches = formatStr.match(formatRegexp1);
var expectedNumberOfArgs = (matches === null ? 0 : matches.length);
var errorStrBuffer = [functionName + ': format string requires ' + expectedNumberOfArgs
+ ' arguments, given ' + args.length + '; arguments were:',
toWrittenString(formatStr)];
var i;
for (i = 0; i < args.length; i++) {
errorStrBuffer.push( toWrittenString(args[i]) );
}
throw new Error(errorStrBuffer.join(' '));
};
var buffer = args.slice(0);
var onTemplate = function(s) {
if (s === "~~") {
return "~";
} else if (s === '~n' || s === '~%') {
return "\n";
} else if (s === '~s' || s === "~S") {
if (buffer.length === 0) {
throwFormatError();
}
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 toWrittenString(buffer.shift());
}
else if (s === '~v') {
if (buffer.length === 0) {
throwFormatError();
}
// fprintf must do something more interesting here by
// printing the dom representation directly...
return toWrittenString(buffer.shift());
} else if (s === '~a' || s === "~A") {
if (buffer.length === 0) {
throwFormatError();
}
return toDisplayedString(buffer.shift());
} else {
throw new Error(functionName +
': string.replace matched invalid regexp');
}
};
var result = formatStr.replace(formatRegexp2, onTemplate);
if (buffer.length > 0) {
throwFormatError();
}
return result;
};
var ToDomNodeParameters = function(params) { var ToDomNodeParameters = function(params) {
if (! params) { params = {}; } if (! params) { params = {}; }
this.cache = plt.baselib.hashes.makeLowLevelEqHash(); this.cache = baselib.hashes.makeLowLevelEqHash();
for (var k in params) { var k;
for (k in params) {
if (params.hasOwnProperty(k)) { if (params.hasOwnProperty(k)) {
this[k] = params[k]; this[k] = params[k];
} }
@ -188,139 +230,14 @@
}; };
// toDomNode: scheme-value -> dom-node
var toDomNode = function(x, params) {
if (params === 'write') {
params = new ToDomNodeParameters({'mode' : 'write'});
} else if (params === 'print') {
params = new ToDomNodeParameters({'mode' : 'print'});
} else if (params === 'display') {
params = new ToDomNodeParameters({'mode' : 'display'});
} else {
params = params || new ToDomNodeParameters({'mode' : 'display'});
}
if (plt.baselib.numbers.isSchemeNumber(x)) {
var node = numberToDomNode(x, params);
$(node).addClass("number");
return node;
}
if (x === null) {
var node = document.createElement("span");
node.appendChild(document.createTextNode("null"));
$(node).addClass("null");
return node;
}
if (x === true) {
var node = document.createElement("span");
node.appendChild(document.createTextNode("true"));
$(node).addClass("boolean");
return node;
}
if (x === false) {
var node = document.createElement("span");
node.appendChild(document.createTextNode("false"));
$(node).addClass("boolean");
return node;
}
if (typeof(x) == 'object') {
if (params.containsKey(x)) {
var node = document.createElement("span");
node.appendChild(document.createTextNode("#" + params.get(x)));
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;
if (params.getMode() === 'write' || params.getMode() === 'print') {
node = document.createTextNode(toWrittenString(x));
} else {
node = document.createTextNode(toDisplayedString(x));
}
wrapper.appendChild(node);
$(wrapper).addClass("string");
return wrapper;
}
if (typeof(x) != 'object' && typeof(x) != 'function') {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toString()));
$(node).addClass("procedure");
return node;
}
var returnVal;
if (x.nodeType) {
returnVal = x;
} else if (typeof(x.toDomNode) !== 'undefined') {
returnVal = x.toDomNode(params);
} else if (params.getMode() === 'write' &&
typeof(x.toWrittenString) !== 'undefined') {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toWrittenString(params)));
returnVal = node;
} else if (params.getMode() === 'display' &&
typeof(x.toDisplayedString) !== 'undefined') {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toDisplayedString(params)));
returnVal = node;
} else {
var node = document.createElement("span");
node.appendChild(document.createTextNode(x.toString()));
returnVal = node;
}
params.remove(x);
return returnVal;
};
// numberToDomNode: jsnum -> dom
// Given a jsnum, produces a dom-node representation.
var numberToDomNode = function(n, params) {
var node;
if (plt.baselib.numbers.isExact(n)) {
if (plt.baselib.numbers.isInteger(n)) {
node = document.createElement("span");
node.appendChild(document.createTextNode(n.toString()));
return node;
} else if (plt.baselib.numbers.isRational(n)) {
return rationalToDomNode(n);
} else if (plt.baselib.numbers.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 // rationalToDomNode: rational -> dom-node
var rationalToDomNode = function(n) { var rationalToDomNode = function(n) {
var repeatingDecimalNode = document.createElement("span"); var repeatingDecimalNode = document.createElement("span");
var chunks = plt.baselib.numbers.toRepeatingDecimal(plt.baselib.numbers.numerator(n), var chunks = baselib.numbers.toRepeatingDecimal(baselib.numbers.numerator(n),
plt.baselib.numbers.denominator(n), baselib.numbers.denominator(n),
{limit: 25}); {limit: 25});
repeatingDecimalNode.appendChild(document.createTextNode(chunks[0] + '.')) repeatingDecimalNode.appendChild(document.createTextNode(chunks[0] + '.'));
repeatingDecimalNode.appendChild(document.createTextNode(chunks[1])); repeatingDecimalNode.appendChild(document.createTextNode(chunks[1]));
if (chunks[2] === '...') { if (chunks[2] === '...') {
repeatingDecimalNode.appendChild( repeatingDecimalNode.appendChild(
@ -335,9 +252,9 @@
var fractionalNode = document.createElement("span"); var fractionalNode = document.createElement("span");
var numeratorNode = document.createElement("sup"); var numeratorNode = document.createElement("sup");
numeratorNode.appendChild(document.createTextNode(String(plt.baselib.numbers.numerator(n)))); numeratorNode.appendChild(document.createTextNode(String(baselib.numbers.numerator(n))));
var denominatorNode = document.createElement("sub"); var denominatorNode = document.createElement("sub");
denominatorNode.appendChild(document.createTextNode(String(plt.baselib.numbers.denominator(n)))); denominatorNode.appendChild(document.createTextNode(String(baselib.numbers.denominator(n))));
fractionalNode.appendChild(numeratorNode); fractionalNode.appendChild(numeratorNode);
fractionalNode.appendChild(document.createTextNode("/")); fractionalNode.appendChild(document.createTextNode("/"));
fractionalNode.appendChild(denominatorNode); fractionalNode.appendChild(denominatorNode);
@ -353,59 +270,139 @@
numberNode.onclick = function(e) { numberNode.onclick = function(e) {
showingRepeating = !showingRepeating; showingRepeating = !showingRepeating;
repeatingDecimalNode.style['display'] = repeatingDecimalNode.style['display'] =
(showingRepeating ? 'inline' : 'none') (showingRepeating ? 'inline' : 'none');
fractionalNode.style['display'] = fractionalNode.style['display'] =
(!showingRepeating ? 'inline' : 'none') (!showingRepeating ? 'inline' : 'none');
}; };
numberNode.style['cursor'] = 'pointer'; numberNode.style['cursor'] = 'pointer';
return numberNode; return numberNode;
}
var escapeString = function(s) {
return '"' + replaceUnprintableStringChars(s) + '"';
};
var replaceUnprintableStringChars = function(s) {
var ret = [];
for (var i = 0; i < s.length; i++) {
var val = s.charCodeAt(i);
switch(val) {
case 7: ret.push('\\a'); break;
case 8: ret.push('\\b'); break;
case 9: ret.push('\\t'); break;
case 10: ret.push('\\n'); break;
case 11: ret.push('\\v'); break;
case 12: ret.push('\\f'); break;
case 13: ret.push('\\r'); break;
case 34: ret.push('\\"'); break;
case 92: ret.push('\\\\'); break;
default: if (val >= 32 && val <= 126) {
ret.push( s.charAt(i) );
}
else {
var numStr = val.toString(16).toUpperCase();
while (numStr.length < 4) {
numStr = '0' + numStr;
}
ret.push('\\u' + numStr);
}
break;
}
}
return ret.join('');
}; };
// numberToDomNode: jsnum -> dom
// Given a jsnum, produces a dom-node representation.
var numberToDomNode = function(n, params) {
var node;
if (baselib.numbers.isExact(n)) {
if (baselib.numbers.isInteger(n)) {
node = document.createElement("span");
node.appendChild(document.createTextNode(n.toString()));
return node;
} else if (baselib.numbers.isRational(n)) {
return rationalToDomNode(n);
} else if (baselib.numbers.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;
}
};
// toDomNode: scheme-value -> dom-node
var toDomNode = function(x, params) {
var node;
if (params === 'write') {
params = new ToDomNodeParameters({'mode' : 'write'});
} else if (params === 'print') {
params = new ToDomNodeParameters({'mode' : 'print'});
} else if (params === 'display') {
params = new ToDomNodeParameters({'mode' : 'display'});
} else {
params = params || new ToDomNodeParameters({'mode' : 'display'});
}
if (baselib.numbers.isSchemeNumber(x)) {
node = numberToDomNode(x, params);
$(node).addClass("number");
return node;
}
if (x === null) {
node = document.createElement("span");
node.appendChild(document.createTextNode("null"));
$(node).addClass("null");
return node;
}
if (x === true) {
node = document.createElement("span");
node.appendChild(document.createTextNode("true"));
$(node).addClass("boolean");
return node;
}
if (x === false) {
node = document.createElement("span");
node.appendChild(document.createTextNode("false"));
$(node).addClass("boolean");
return node;
}
if (typeof(x) === 'object') {
if (params.containsKey(x)) {
node = document.createElement("span");
node.appendChild(document.createTextNode("#" + params.get(x)));
return node;
}
}
if (x === undefined || x === null) {
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";
if (params.getMode() === 'write' || params.getMode() === 'print') {
node = document.createTextNode(toWrittenString(x));
} else {
node = document.createTextNode(toDisplayedString(x));
}
wrapper.appendChild(node);
$(wrapper).addClass("string");
return wrapper;
}
if (typeof(x) !== 'object' && typeof(x) !== 'function') {
node = document.createElement("span");
node.appendChild(document.createTextNode(x.toString()));
$(node).addClass("procedure");
return node;
}
var returnVal;
if (x.nodeType) {
returnVal = x;
} else if (typeof(x.toDomNode) !== 'undefined') {
returnVal = x.toDomNode(params);
} else if (params.getMode() === 'write' &&
typeof(x.toWrittenString) !== 'undefined') {
node = document.createElement("span");
node.appendChild(document.createTextNode(x.toWrittenString(params)));
returnVal = node;
} else if (params.getMode() === 'display' &&
typeof(x.toDisplayedString) !== 'undefined') {
node = document.createElement("span");
node.appendChild(document.createTextNode(x.toDisplayedString(params)));
returnVal = node;
} else {
node = document.createElement("span");
node.appendChild(document.createTextNode(x.toString()));
returnVal = node;
}
params.remove(x);
return returnVal;
};
@ -420,4 +417,4 @@
exports.toDomNode = toDomNode; exports.toDomNode = toDomNode;
exports.escapeString = escapeString; exports.escapeString = escapeString;
})(this['plt'].baselib); }(this.plt.baselib, $));

View File

@ -1,5 +1,8 @@
/*jslint unparam: true, sub: true, vars: true, white: true, plusplus: true, maxerr: 50, indent: 4 */
// Frame structures. // Frame structures.
(function(baselib) { (function(baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.frames = exports; baselib.frames = exports;
@ -66,4 +69,4 @@
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,9 +1,14 @@
/*jslint unparam: true, sub: true, vars: true, white: true, plusplus: true, maxerr: 50, indent: 4 */
// Procedures // Procedures
// For historical reasons, this module is called 'functions' instead of 'procedures'. // For historical reasons, this module is called 'functions' instead of 'procedures'.
// This may change soon. // This may change soon.
(function(baselib) { /*global plt*/
(function (baselib, plt) {
'use strict';
var exports = {}; var exports = {};
baselib.functions = exports; baselib.functions = exports;
@ -16,195 +21,8 @@
var isPrimitiveProcedure = function (x) {
return typeof (x) === 'function';
// coerseToJavaScript: racket function -> JavaScript function
// Given a closure or primitive, produces an
// asynchronous JavaScript function.
// The function will run on the provided MACHINE.
//
// It assumes that it must begin its own trampoline.
var asJavaScriptFunction = function(v, MACHINE) {
MACHINE = MACHINE || plt.runtime.currentMachine;
if (isPrimitiveProcedure(v)) {
return coersePrimitiveToJavaScript(v, MACHINE);
} else if (isClosure(v)) {
return coerseClosureToJavaScript(v, MACHINE);
} else {
plt.baselib.exceptions.raise(MACHINE,
plt.baselib.exceptions.makeExnFail(
plt.baselib.format.format(
"Not a procedure: ~e",
v)));
}
};
var coersePrimitiveToJavaScript = function(v, MACHINE) {
return function(succ, fail) {
try {
succ = succ || function(){};
fail = fail || function(){};
var oldArgcount = MACHINE.argcount;
MACHINE.argcount = arguments.length - 2;
for (var i = 0; i < arguments.length - 2; i++) {
MACHINE.env.push(arguments[arguments.length - 1 - i]);
}
if (! plt.baselib.arity.isArityMatching(v.racketArity, MACHINE.argcount)) {
fail(new Error(plt.baselib.format.format(
"arity mismatch: expected ~s arguments, but received ~s",
[v.racketArity, MACHINE.argcount])));
return;
}
var result = v(MACHINE);
MACHINE.argcount = oldArgcount;
for (var i = 0; i < arguments.length - 2; i++) {
MACHINE.env.pop();
}
succ(result);
} catch (e) {
fail(e);
}
}
};
var coerseClosureToJavaScript = function(v, MACHINE) {
var f = function(succ, fail) {
succ = succ || function(){};
fail = fail || function(){};
if (! plt.baselib.arity.isArityMatching(v.racketArity, arguments.length - 2)) {
fail(new Error(
plt.baselib.format.format(
"arity mismatch: expected ~s argument(s) but received ~s",
[v.racketArity, arguments.length - 2])));
return;
}
var oldVal = MACHINE.val;
var oldArgcount = MACHINE.argcount;
var oldProc = MACHINE.proc;
var oldErrorHandler = MACHINE.params['currentErrorHandler'];
var afterGoodInvoke = function(MACHINE) {
plt.runtime.PAUSE(
function(restart) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
var returnValue = MACHINE.val;
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
succ(returnValue);
});
};
afterGoodInvoke.multipleValueReturn = function(MACHINE) {
plt.runtime.PAUSE(
function(restart) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
var returnValues = [MACHINE.val];
for (var i = 0; i < MACHINE.argcount - 1; i++) {
returnValues.push(MACHINE.env.pop());
}
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
succ.apply(null, returnValues);
});
};
MACHINE.control.push(
new plt.baselib.frames.CallFrame(afterGoodInvoke, null));
MACHINE.argcount = arguments.length - 2;
for (var i = 0; i < arguments.length - 2; i++) {
MACHINE.env.push(arguments[arguments.length - 1 - i]);
}
MACHINE.proc = v;
MACHINE.params['currentErrorHandler'] = function(MACHINE, e) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
fail(e);
};
plt.runtime.trampoline(MACHINE, v.label);
};
return f;
};
// internallCallDuringPause: call a Racket procedure and get its results.
// The use assumes the machine is in a running-but-paused state.
var internalCallDuringPause = function(MACHINE, proc, success, fail) {
if (! plt.baselib.arity.isArityMatching(proc.racketArity, arguments.length - 4)) {
return fail(plt.baselib.exceptions.makeExnFailContractArity("arity mismatch"));
}
if (isPrimitiveProcedure(proc)) {
var oldArgcount = MACHINE.argcount;
MACHINE.argcount = arguments.length - 4;
for (var i = 0; i < arguments.length - 4; i++) {
MACHINE.env.push(arguments[arguments.length - 1 - i]);
}
var result = proc(MACHINE);
for (var i = 0; i < arguments.length - 4; i++) {
MACHINE.env.pop();
}
success(result);
} else if (isClosure(proc)) {
var oldVal = MACHINE.val;
var oldArgcount = MACHINE.argcount;
var oldProc = MACHINE.proc;
var oldErrorHandler = MACHINE.params['currentErrorHandler'];
var afterGoodInvoke = function(MACHINE) {
plt.runtime.PAUSE(function(restart) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
var returnValue = MACHINE.val;
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
success(returnValue);
});
};
afterGoodInvoke.multipleValueReturn = function(MACHINE) {
plt.runtime.PAUSE(function(restart) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
var returnValues = [MACHINE.val];
for (var i = 0; i < MACHINE.argcount - 1; i++) {
returnValues.push(MACHINE.env.pop());
}
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
success.apply(null, returnValues);
});
};
MACHINE.control.push(
new plt.baselib.frames.CallFrame(afterGoodInvoke, null));
MACHINE.argcount = arguments.length - 4;
for (var i = 0; i < arguments.length - 4; i++) {
MACHINE.env.push(arguments[arguments.length - 1 - i]);
}
MACHINE.proc = proc;
MACHINE.params['currentErrorHandler'] = function(MACHINE, e) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
fail(e);
};
plt.runtime.trampoline(MACHINE, proc.label);
} else {
fail(plt.baselib.exceptions.makeExnFail(
plt.baselib.format.format(
"Not a procedure: ~e",
proc)));
}
}; };
@ -221,15 +39,14 @@
// A closure consists of its free variables as well as a label // A closure consists of its free variables as well as a label
// into its text segment. // into its text segment.
var Closure = function(label, arity, closedVals, displayName) { var Closure = function (label, arity, closedVals, displayName) {
this.label = label; // (MACHINE -> void) this.label = label; // (MACHINE -> void)
this.racketArity = arity; // number this.racketArity = arity; // number
this.closedVals = closedVals; // arrayof number this.closedVals = closedVals; // arrayof number
this.displayName = displayName; // string this.displayName = displayName; // string
}; };
// Finalize the return from a closure. This is a helper function // Finalize the return from a closure. This is a helper function
// for those who implement Closures by hand. // for those who implement Closures by hand.
// //
@ -243,33 +60,237 @@
// //
// I'd personally love for this to be a macro and avoid the // I'd personally love for this to be a macro and avoid the
// extra function call here. // extra function call here.
var finalizeClosureCall = function(MACHINE) { var finalizeClosureCall = function (MACHINE) {
MACHINE.callsBeforeTrampoline--; MACHINE.callsBeforeTrampoline--;
var frame, i, returnArgs = [].slice.call(arguments, 1); var i, returnArgs = [].slice.call(arguments, 1);
// clear out stack space // clear out stack space
// TODO: replace with a splice. // TODO: replace with a splice.
for(i = 0; i < MACHINE.argcount; i++) { MACHINE.env.length = MACHINE.env.length - MACHINE.argcount;
MACHINE.env.pop();
}
if (returnArgs.length === 1) { if (returnArgs.length === 1) {
MACHINE.val = returnArgs[0]; MACHINE.val = returnArgs[0];
frame = MACHINE.control.pop(); return MACHINE.control.pop().label(MACHINE);
return frame.label(MACHINE);
} else if (returnArgs.length === 0) { } else if (returnArgs.length === 0) {
MACHINE.argcount = 0; MACHINE.argcount = 0;
frame = MACHINE.control.pop(); return MACHINE.control.pop().label.multipleValueReturn(MACHINE);
return frame.label.multipleValueReturn(MACHINE);
} else { } else {
MACHINE.argcount = returnArgs.length; MACHINE.argcount = returnArgs.length;
MACHINE.val = returnArgs.shift(); MACHINE.val = returnArgs.shift();
// TODO: replace with a splice. // TODO: replace with a splice.
for(i = 0; i < MACHINE.argcount - 1; i++) { for (i = 0; i < MACHINE.argcount - 1; i++) {
MACHINE.env.push(returnArgs.pop()); MACHINE.env.push(returnArgs.pop());
} }
frame = MACHINE.control.pop(); return MACHINE.control.pop().label.multipleValueReturn(MACHINE);
return frame.label.multipleValueReturn(MACHINE); }
};
var isClosure = function (x) {
return x instanceof Closure;
};
var isProcedure = function (x) {
return (typeof (x) === 'function' ||
x instanceof Closure);
};
var coersePrimitiveToJavaScript = function (v, MACHINE) {
return function (succ, fail) {
try {
succ = succ || function () {};
fail = fail || function () {};
var oldArgcount = MACHINE.argcount, i;
MACHINE.argcount = arguments.length - 2;
for (i = 0; i < arguments.length - 2; i++) {
MACHINE.env.push(arguments[arguments.length - 1 - i]);
}
if (!(baselib.arity.isArityMatching(v.racketArity, MACHINE.argcount))) {
fail(new Error(baselib.format.format("arity mismatch: expected ~s arguments, but received ~s",
[v.racketArity, MACHINE.argcount])));
return;
}
var result = v(MACHINE);
MACHINE.argcount = oldArgcount;
for (i = 0; i < arguments.length - 2; i++) {
MACHINE.env.pop();
}
succ(result);
} catch (e) {
fail(e);
}
};
};
var coerseClosureToJavaScript = function (v, MACHINE) {
var f = function (succ, fail) {
succ = succ || function () {};
fail = fail || function () {};
if (!(baselib.arity.isArityMatching(v.racketArity, arguments.length - 2))) {
fail(new Error(
baselib.format.format(
"arity mismatch: expected ~s argument(s) but received ~s",
[v.racketArity, arguments.length - 2])));
return;
}
var oldVal = MACHINE.val;
var oldArgcount = MACHINE.argcount;
var oldProc = MACHINE.proc;
var oldErrorHandler = MACHINE.params['currentErrorHandler'];
var afterGoodInvoke = function (MACHINE) {
plt.runtime.PAUSE(
function (restart) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
var returnValue = MACHINE.val;
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
succ(returnValue);
});
};
afterGoodInvoke.multipleValueReturn = function (MACHINE) {
plt.runtime.PAUSE(
function (restart) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
var returnValues = [MACHINE.val], i;
for (i = 0; i < MACHINE.argcount - 1; i++) {
returnValues.push(MACHINE.env.pop());
}
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
succ.apply(null, returnValues);
});
};
MACHINE.control.push(
new baselib.frames.CallFrame(afterGoodInvoke, null));
MACHINE.argcount = arguments.length - 2;
var i;
for (i = 0; i < arguments.length - 2; i++) {
MACHINE.env.push(arguments[arguments.length - 1 - i]);
}
MACHINE.proc = v;
MACHINE.params['currentErrorHandler'] = function (MACHINE, e) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
fail(e);
};
MACHINE.trampoline(v.label);
};
return f;
};
// coerseToJavaScript: racket function -> JavaScript function
// Given a closure or primitive, produces an
// asynchronous JavaScript function.
// The function will run on the provided MACHINE.
//
// It assumes that it must begin its own trampoline.
var asJavaScriptFunction = function (v, MACHINE) {
MACHINE = MACHINE || plt.runtime.currentMachine;
if (isPrimitiveProcedure(v)) {
return coersePrimitiveToJavaScript(v, MACHINE);
} else if (isClosure(v)) {
return coerseClosureToJavaScript(v, MACHINE);
} else {
baselib.exceptions.raise(MACHINE,
baselib.exceptions.makeExnFail(
baselib.format.format(
"Not a procedure: ~e",
v)));
}
};
// internallCallDuringPause: call a Racket procedure and get its results.
// The use assumes the machine is in a running-but-paused state.
var internalCallDuringPause = function (MACHINE, proc, success, fail) {
var i;
var oldArgcount, oldVal, oldProc, oldErrorHandler;
if (! baselib.arity.isArityMatching(proc.racketArity, arguments.length - 4)) {
return fail(baselib.exceptions.makeExnFailContractArity("arity mismatch"));
}
if (isPrimitiveProcedure(proc)) {
oldArgcount = MACHINE.argcount;
MACHINE.argcount = arguments.length - 4;
for (i = 0; i < arguments.length - 4; i++) {
MACHINE.env.push(arguments[arguments.length - 1 - i]);
}
var result = proc(MACHINE);
for (i = 0; i < arguments.length - 4; i++) {
MACHINE.env.pop();
}
success(result);
} else if (isClosure(proc)) {
oldVal = MACHINE.val;
oldArgcount = MACHINE.argcount;
oldProc = MACHINE.proc;
oldErrorHandler = MACHINE.params['currentErrorHandler'];
var afterGoodInvoke = function (MACHINE) {
plt.runtime.PAUSE(function (restart) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
var returnValue = MACHINE.val;
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
success(returnValue);
});
};
afterGoodInvoke.multipleValueReturn = function (MACHINE) {
plt.runtime.PAUSE(function (restart) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
var returnValues = [MACHINE.val];
var i;
for (i = 0; i < MACHINE.argcount - 1; i++) {
returnValues.push(MACHINE.env.pop());
}
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
success.apply(null, returnValues);
});
};
MACHINE.control.push(
new baselib.frames.CallFrame(afterGoodInvoke, null));
MACHINE.argcount = arguments.length - 4;
for (i = 0; i < arguments.length - 4; i++) {
MACHINE.env.push(arguments[arguments.length - 1 - i]);
}
MACHINE.proc = proc;
MACHINE.params['currentErrorHandler'] = function (MACHINE, e) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
MACHINE.val = oldVal;
MACHINE.argcount = oldArgcount;
MACHINE.proc = oldProc;
fail(e);
};
MACHINE.trampoline(proc.label);
} else {
fail(baselib.exceptions.makeExnFail(
baselib.format.format(
"Not a procedure: ~e",
proc)));
} }
}; };
@ -278,13 +299,18 @@
var makePrimitiveProcedure = function(name, arity, f) {
var makePrimitiveProcedure = function (name, arity, f) {
f.racketArity = arity; f.racketArity = arity;
f.displayName = name; f.displayName = name;
return f; return f;
}; };
var makeClosure = function(name, arity, f, closureArgs) { var makeClosure = function (name, arity, f, closureArgs) {
if (! closureArgs) { closureArgs = []; } if (! closureArgs) { closureArgs = []; }
return new Closure(f, return new Closure(f,
arity, arity,
@ -295,28 +321,15 @@
var isPrimitiveProcedure = function(x) {
return typeof(x) === 'function';
};
var isClosure = function(x) {
return x instanceof Closure;
};
var isProcedure = function(x) {
return (typeof(x) === 'function' ||
x instanceof Closure);
};
var renameProcedure = function(f, name) { var renameProcedure = function (f, name) {
if (isPrimitiveProcedure(f)) { if (isPrimitiveProcedure(f)) {
return makePrimitiveProcedure( return makePrimitiveProcedure(
name, name,
f.racketArity, f.racketArity,
function() { function () {
return f.apply(null, arguments); return f.apply(null, arguments);
}); });
} else { } else {
@ -351,4 +364,4 @@
exports.asJavaScriptFunction = asJavaScriptFunction; exports.asJavaScriptFunction = asJavaScriptFunction;
})(this['plt'].baselib); }(this.plt.baselib, this.plt));

View File

@ -1,5 +1,10 @@
/*jslint unparam: true, vars: true, white: true, newcap: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
(function(baselib) { /*global Hashtable*/
(function (baselib, Hashtable) {
'use strict';
var exports = {}; var exports = {};
baselib.hashes = exports; baselib.hashes = exports;
@ -7,28 +12,28 @@
var _eqHashCodeCounter = 0; var _eqHashCodeCounter = 0;
var makeEqHashCode = function() { var makeEqHashCode = function () {
_eqHashCodeCounter++; _eqHashCodeCounter++;
return _eqHashCodeCounter; return _eqHashCodeCounter;
}; };
// getHashCode: any -> (or fixnum string) // getHashCode: any -> (or fixnum string)
// Given a value, produces a hashcode appropriate for eq. // Given a value, produces a hashcode appropriate for eq.
var getEqHashCode = function(x) { var getEqHashCode = function (x) {
if (typeof(x) === 'string') { if (typeof (x) === 'string') {
return x; return x;
} }
if (typeof(x) === 'number') { if (typeof (x) === 'number') {
return String(x); return String(x);
} }
if (x && !x._eqHashCode) { if (x && !x._eqHashCode) {
x._eqHashCode = makeEqHashCode(); x._eqHashCode = makeEqHashCode();
} }
if (x && x._eqHashCode) { if (x && x._eqHashCode) {
return x._eqHashCode; return x._eqHashCode;
} }
return 0; return 0;
}; };
@ -36,9 +41,9 @@
// http://www.timdown.co.uk/jshashtable/ // http://www.timdown.co.uk/jshashtable/
// //
// Defined to use the getEqHashCode defined in baselib_hash.js. // Defined to use the getEqHashCode defined in baselib_hash.js.
var makeLowLevelEqHash = function() { var makeLowLevelEqHash = function () {
return new Hashtable(function(x) { return getEqHashCode(x); }, return new Hashtable(function (x) { return getEqHashCode(x); },
function(x, y) { return x === y; }); function (x, y) { return x === y; });
}; };
@ -52,51 +57,51 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Eq Hashtables // Eq Hashtables
var EqHashTable = function(inputHash) { var EqHashTable = function (inputHash) {
this.hash = makeLowLevelEqHash(); this.hash = makeLowLevelEqHash();
this.mutable = true; this.mutable = true;
}; };
EqHashTable.prototype.toWrittenString = function(cache) { EqHashTable.prototype.toWrittenString = function (cache) {
var keys = this.hash.keys(); var keys = this.hash.keys();
var ret = []; var ret = [], i;
for (var i = 0; i < keys.length; i++) { for (i = 0; i < keys.length; i++) {
var keyStr = toWrittenString(keys[i], cache); var keyStr = baselib.format.toWrittenString(keys[i], cache);
var valStr = toWrittenString(this.hash.get(keys[i]), cache); var valStr = baselib.format.toWrittenString(this.hash.get(keys[i]), cache);
ret.push('(' + keyStr + ' . ' + valStr + ')'); ret.push('(' + keyStr + ' . ' + valStr + ')');
} }
return ('#hasheq(' + ret.join(' ') + ')'); return ('#hasheq(' + ret.join(' ') + ')');
}; };
EqHashTable.prototype.toDisplayedString = function(cache) { EqHashTable.prototype.toDisplayedString = function (cache) {
var keys = this.hash.keys(); var keys = this.hash.keys();
var ret = []; var ret = [], i;
for (var i = 0; i < keys.length; i++) { for (i = 0; i < keys.length; i++) {
var keyStr = toDisplayedString(keys[i], cache); var keyStr = baselib.format.toDisplayedString(keys[i], cache);
var valStr = toDisplayedString(this.hash.get(keys[i]), cache); var valStr = baselib.format.toDisplayedString(this.hash.get(keys[i]), cache);
ret.push('(' + keyStr + ' . ' + valStr + ')'); ret.push('(' + keyStr + ' . ' + valStr + ')');
} }
return ('#hasheq(' + ret.join(' ') + ')'); return ('#hasheq(' + ret.join(' ') + ')');
}; };
EqHashTable.prototype.equals = function(other, aUnionFind) { EqHashTable.prototype.equals = function (other, aUnionFind) {
if ( !(other instanceof EqHashTable) ) { if (!(other instanceof EqHashTable)) {
return false; return false;
} }
if (this.hash.keys().length != other.hash.keys().length) { if (this.hash.keys().length !== other.hash.keys().length) {
return false; return false;
} }
var keys = this.hash.keys(); var keys = this.hash.keys(), i;
for (var i = 0; i < keys.length; i++){ for (i = 0; i < keys.length; i++) {
if ( !(other.hash.containsKey(keys[i]) && if (!(other.hash.containsKey(keys[i]) &&
plt.baselib.equality.equals(this.hash.get(keys[i]), baselib.equality.equals(this.hash.get(keys[i]),
other.hash.get(keys[i]), other.hash.get(keys[i]),
aUnionFind)) ) { aUnionFind))) {
return false; return false;
} }
} }
return true; return true;
}; };
@ -105,55 +110,55 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Equal hash tables // Equal hash tables
var EqualHashTable = function(inputHash) { var EqualHashTable = function (inputHash) {
this.hash = new _Hashtable( this.hash = new Hashtable(
function(x) { function (x) {
return plt.baselib.format.toWrittenString(x); return baselib.format.toWrittenString(x);
}, },
function(x, y) { function (x, y) {
return plt.baselib.equality.equals(x, y, new plt.baselib.UnionFind()); return baselib.equality.equals(x, y, new baselib.UnionFind());
}); });
this.mutable = true; this.mutable = true;
}; };
EqualHashTable.prototype.toWrittenString = function(cache) { EqualHashTable.prototype.toWrittenString = function (cache) {
var keys = this.hash.keys(); var keys = this.hash.keys();
var ret = []; var ret = [], i;
for (var i = 0; i < keys.length; i++) { for (i = 0; i < keys.length; i++) {
var keyStr = plt.baselib.format.toWrittenString(keys[i], cache); var keyStr = baselib.format.toWrittenString(keys[i], cache);
var valStr = plt.baselib.format.toWrittenString(this.hash.get(keys[i]), cache); var valStr = baselib.format.toWrittenString(this.hash.get(keys[i]), cache);
ret.push('(' + keyStr + ' . ' + valStr + ')'); ret.push('(' + keyStr + ' . ' + valStr + ')');
} }
return ('#hash(' + ret.join(' ') + ')'); return ('#hash(' + ret.join(' ') + ')');
}; };
EqualHashTable.prototype.toDisplayedString = function(cache) { EqualHashTable.prototype.toDisplayedString = function (cache) {
var keys = this.hash.keys(); var keys = this.hash.keys();
var ret = []; var ret = [], i;
for (var i = 0; i < keys.length; i++) { for (i = 0; i < keys.length; i++) {
var keyStr = plt.baselib.format.toDisplayedString(keys[i], cache); var keyStr = baselib.format.toDisplayedString(keys[i], cache);
var valStr = plt.baselib.format.toDisplayedString(this.hash.get(keys[i]), cache); var valStr = baselib.format.toDisplayedString(this.hash.get(keys[i]), cache);
ret.push('(' + keyStr + ' . ' + valStr + ')'); ret.push('(' + keyStr + ' . ' + valStr + ')');
} }
return ('#hash(' + ret.join(' ') + ')'); return ('#hash(' + ret.join(' ') + ')');
}; };
EqualHashTable.prototype.equals = function(other, aUnionFind) { EqualHashTable.prototype.equals = function (other, aUnionFind) {
if ( !(other instanceof EqualHashTable) ) { if ( !(other instanceof EqualHashTable) ) {
return false; return false;
} }
if (this.hash.keys().length != other.hash.keys().length) { if (this.hash.keys().length !== other.hash.keys().length) {
return false; return false;
} }
var keys = this.hash.keys(); var keys = this.hash.keys(), i;
for (var i = 0; i < keys.length; i++){ for (i = 0; i < keys.length; i++){
if (! (other.hash.containsKey(keys[i]) && if (! (other.hash.containsKey(keys[i]) &&
plt.baselib.equality.equals(this.hash.get(keys[i]), baselib.equality.equals(this.hash.get(keys[i]),
other.hash.get(keys[i]), other.hash.get(keys[i]),
aUnionFind))) { aUnionFind))) {
return false; return false;
} }
} }
return true; return true;
}; };
@ -161,27 +166,12 @@
var isHash = function(x) { var isHash = function (x) {
return (x instanceof EqHashTable || return (x instanceof EqHashTable ||
x instanceof EqualHashTable); x instanceof EqualHashTable);
}; };
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
exports.getEqHashCode = getEqHashCode; exports.getEqHashCode = getEqHashCode;
@ -194,4 +184,4 @@
exports.isHash = isHash; exports.isHash = isHash;
})(this['plt'].baselib); }(this.plt.baselib, Hashtable));

View File

@ -1,15 +1,18 @@
/*jslint vars: true, maxerr: 50, indent: 4 */
// Structure types // Structure types
(function(baselib) { (function (baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.inspectors = exports; baselib.inspectors = exports;
var Inspector = function() { var Inspector = function () {
}; };
var DEFAULT_INSPECTOR = new Inspector(); var DEFAULT_INSPECTOR = new Inspector();
Inspector.prototype.toString = function() { Inspector.prototype.toString = function () {
return "#<inspector>"; return "#<inspector>";
}; };
@ -23,4 +26,4 @@
exports.isInspector = isInspector; exports.isInspector = isInspector;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,44 +1,47 @@
/*jslint unparam: true, vars: true, maxerr: 50, indent: 4 */
// Keywords // Keywords
(function(baselib) {
(function (baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.keywords = exports; baselib.keywords = exports;
var Keyword = function(val) { var Keyword = function (val) {
this.val = val; this.val = val;
}; };
var keywordCache = {}; var keywordCache = {};
// makeInstance: string -> Keyword. // makeInstance: string -> Keyword.
Keyword.makeInstance = function(val) { Keyword.makeInstance = function (val) {
// To ensure that we can eq? symbols with equal values. // To ensure that we can eq? symbols with equal values.
if (!(val in keywordCache)) { if (!(keywordCache.hasOwnProperty(val))) {
keywordCache[val] = new Keyword(val); keywordCache[val] = new Keyword(val);
} else {
} }
return keywordCache[val]; return keywordCache[val];
}; };
Keyword.prototype.equals = function(other, aUnionFind) { Keyword.prototype.equals = function (other, aUnionFind) {
return other instanceof Keyword && return other instanceof Keyword &&
this.val == other.val; this.val === other.val;
}; };
Keyword.prototype.toString = function(cache) { Keyword.prototype.toString = function (cache) {
return this.val; return this.val;
}; };
Keyword.prototype.toWrittenString = function(cache) { Keyword.prototype.toWrittenString = function (cache) {
return this.val; return this.val;
}; };
Keyword.prototype.toDisplayedString = function(cache) { Keyword.prototype.toDisplayedString = function (cache) {
return this.val; return this.val;
}; };
exports.Keyword = Keyword; exports.Keyword = Keyword;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,5 +1,9 @@
/*jslint browser: true, unparam: true, vars: true, plusplus: true, maxerr: 50, indent: 4 */
// list structures (pairs, empty) // list structures (pairs, empty)
(function(baselib) { (function (baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.lists = exports; baselib.lists = exports;
@ -7,28 +11,28 @@
Empty = function() { var Empty = function () {
}; };
Empty.EMPTY = new Empty(); Empty.EMPTY = new Empty();
var EMPTY = Empty.EMPTY; var EMPTY = Empty.EMPTY;
Empty.prototype.equals = function(other, aUnionFind) { Empty.prototype.equals = function (other, aUnionFind) {
return other instanceof Empty; return other instanceof Empty;
}; };
Empty.prototype.reverse = function() { Empty.prototype.reverse = function () {
return this; return this;
}; };
Empty.prototype.toWrittenString = function(cache) { return "empty"; }; Empty.prototype.toWrittenString = function (cache) { return "empty"; };
Empty.prototype.toDisplayedString = function(cache) { return "empty"; }; Empty.prototype.toDisplayedString = function (cache) { return "empty"; };
Empty.prototype.toString = function(cache) { return "()"; }; Empty.prototype.toString = function (cache) { return "()"; };
// Empty.append: (listof X) -> (listof X) // Empty.append: (listof X) -> (listof X)
Empty.prototype.append = function(b){ Empty.prototype.append = function (b) {
return b; return b;
}; };
@ -39,111 +43,112 @@
// Cons Pairs // Cons Pairs
var Cons = function(first, rest) { var Cons = function (first, rest) {
this.first = first; this.first = first;
this.rest = rest; this.rest = rest;
}; };
Cons.prototype.reverse = function() { Cons.prototype.reverse = function () {
var lst = this; var lst = this;
var ret = EMPTY; var ret = EMPTY;
while (lst !== EMPTY) { while (lst !== EMPTY) {
ret = Cons.makeInstance(lst.first, ret); ret = Cons.makeInstance(lst.first, ret);
lst = lst.rest; lst = lst.rest;
} }
return ret; return ret;
}; };
Cons.makeInstance = function(first, rest) { Cons.makeInstance = function (first, rest) {
return new Cons(first, rest); return new Cons(first, rest);
}; };
// FIXME: can we reduce the recursion on this? // FIXME: can we reduce the recursion on this?
Cons.prototype.equals = function(other, aUnionFind) { Cons.prototype.equals = function (other, aUnionFind) {
if (! (other instanceof Cons)) { if (!(other instanceof Cons)) {
return false; return false;
} }
return (plt.baselib.equality.equals(this.first, other.first, aUnionFind) && return (baselib.equality.equals(this.first, other.first, aUnionFind) &&
plt.baselib.equality.equals(this.rest, other.rest, aUnionFind)); baselib.equality.equals(this.rest, other.rest, aUnionFind));
}; };
// Cons.append: (listof X) -> (listof X) // Cons.append: (listof X) -> (listof X)
Cons.prototype.append = function(b){ Cons.prototype.append = function (b) {
if (b === EMPTY) if (b === EMPTY) {
return this; return this;
}
var ret = b; var ret = b;
var lst = this.reverse(); var lst = this.reverse();
while (lst !== EMPTY) { while (lst !== EMPTY) {
ret = Cons.makeInstance(lst.first, ret); ret = Cons.makeInstance(lst.first, ret);
lst = lst.rest; lst = lst.rest;
} }
return ret; return ret;
}; };
Cons.prototype.toWrittenString = function(cache) { Cons.prototype.toWrittenString = function (cache) {
cache.put(this, true); cache.put(this, true);
var texts = []; var texts = [];
var p = this; var p = this;
while ( p instanceof Cons ) { while (p instanceof Cons) {
texts.push(plt.baselib.format.toWrittenString(p.first, cache)); texts.push(baselib.format.toWrittenString(p.first, cache));
p = p.rest; p = p.rest;
if (typeof(p) === 'object' && cache.containsKey(p)) { if (typeof (p) === 'object' && cache.containsKey(p)) {
break; break;
} }
} }
if ( p !== EMPTY ) { if (p !== EMPTY) {
texts.push('.'); texts.push('.');
texts.push(plt.baselib.format.toWrittenString(p, cache)); texts.push(baselib.format.toWrittenString(p, cache));
} }
return "(" + texts.join(" ") + ")"; return "(" + texts.join(" ") + ")";
}; };
Cons.prototype.toString = Cons.prototype.toWrittenString; Cons.prototype.toString = Cons.prototype.toWrittenString;
Cons.prototype.toDisplayedString = function(cache) { Cons.prototype.toDisplayedString = function (cache) {
cache.put(this, true); cache.put(this, true);
var texts = []; var texts = [];
var p = this; var p = this;
while ( p instanceof Cons ) { while (p instanceof Cons) {
texts.push(plt.baselib.format.toDisplayedString(p.first, cache)); texts.push(baselib.format.toDisplayedString(p.first, cache));
p = p.rest; p = p.rest;
if (typeof(p) === 'object' && cache.containsKey(p)) { if (typeof (p) === 'object' && cache.containsKey(p)) {
break; break;
} }
} }
if ( p !== Empty.EMPTY ) { if (p !== Empty.EMPTY) {
texts.push('.'); texts.push('.');
texts.push(plt.baselib.format.toDisplayedString(p, cache)); texts.push(baselib.format.toDisplayedString(p, cache));
} }
return "(" + texts.join(" ") + ")"; return "(" + texts.join(" ") + ")";
}; };
Cons.prototype.toDomNode = function(cache) { Cons.prototype.toDomNode = function (cache) {
cache.put(this, true); cache.put(this, true);
var node = document.createElement("span"); var node = document.createElement("span");
node.appendChild(document.createTextNode("(")); node.appendChild(document.createTextNode("("));
var p = this; var p = this;
while ( p instanceof Cons ) { while (p instanceof Cons) {
node.appendChild(plt.baselib.format.toDomNode(p.first, cache)); node.appendChild(baselib.format.toDomNode(p.first, cache));
p = p.rest; p = p.rest;
if ( p !== Empty.EMPTY ) { if (p !== Empty.EMPTY) {
node.appendChild(document.createTextNode(" ")); node.appendChild(document.createTextNode(" "));
} }
if (typeof(p) === 'object' && cache.containsKey(p)) { if (typeof (p) === 'object' && cache.containsKey(p)) {
break; break;
} }
} }
if ( p !== Empty.EMPTY ) { if (p !== Empty.EMPTY) {
node.appendChild(document.createTextNode(".")); node.appendChild(document.createTextNode("."));
node.appendChild(document.createTextNode(" ")); node.appendChild(document.createTextNode(" "));
node.appendChild(plt.baselib.format.toDomNode(p, cache)); node.appendChild(baselib.format.toDomNode(p, cache));
} }
node.appendChild(document.createTextNode(")")); node.appendChild(document.createTextNode(")"));
@ -151,16 +156,16 @@
}; };
var isPair = function(x) { return x instanceof Cons; }; var isPair = function (x) { return x instanceof Cons; };
var isEmpty = function(x) { return x === Empty.EMPTY; }; var isEmpty = function (x) { return x === Empty.EMPTY; };
var makePair = Cons.makeInstance; var makePair = Cons.makeInstance;
var makeList = function() { var makeList = function () {
var result = Empty.EMPTY; var result = Empty.EMPTY, i;
for(var i = arguments.length-1; i >= 0; i--) { for (i = arguments.length - 1; i >= 0; i--) {
result = Cons.makeInstance(arguments[i], result); result = Cons.makeInstance(arguments[i], result);
} }
return result; return result;
}; };
@ -168,30 +173,30 @@
// isList: Any -> Boolean // isList: Any -> Boolean
// Returns true if x is a list (a chain of pairs terminated by EMPTY). // Returns true if x is a list (a chain of pairs terminated by EMPTY).
var isList = function(x) { var isList = function (x) {
while (x !== Empty.EMPTY) { while (x !== Empty.EMPTY) {
if (x instanceof Cons) { if (x instanceof Cons) {
x = x.rest; x = x.rest;
} else { } else {
return false; return false;
} }
} }
return true; return true;
}; };
var reverse = function(lst) { var reverse = function (lst) {
var rev = EMPTY; var rev = EMPTY;
while(lst !== EMPTY) { while (lst !== EMPTY) {
rev = makePair(lst.first, rev); rev = makePair(lst.first, rev);
lst = lst.rest; lst = lst.rest;
} }
return rev; return rev;
}; };
var length = function(lst) { var length = function (lst) {
var len = 0; var len = 0;
while (lst !== EMPTY) { while (lst !== EMPTY) {
len++; len++;
@ -201,12 +206,13 @@
}; };
var listRef = function(lst, n) { var listRef = function (lst, n) {
for (var i = 0; i < n; i++) { var i;
for (i = 0; i < n; i++) {
lst = lst.rest; lst = lst.rest;
} }
return lst.first; return lst.first;
} };
@ -225,4 +231,4 @@
exports.listRef = listRef; exports.listRef = listRef;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,14 +1,19 @@
(function(baselib) { /*jslint sub: true, vars: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
/*global plt*/
// Modules
(function (baselib, plt) {
'use strict';
var exports = {}; var exports = {};
baselib.modules = exports; baselib.modules = exports;
var ModuleRecord = function(name, label) { var ModuleRecord = function (name, label) {
this.name = name; this.name = name;
this.label = label; this.label = label;
this.isInvoked = false; this.isInvoked = false;
this.prefix = false; this.prefix = false;
this.namespace = {}; this.namespace = {};
// JavaScript-implemented code will assign privateExports // JavaScript-implemented code will assign privateExports
// with all of the exported identifiers. // with all of the exported identifiers.
@ -16,37 +21,37 @@
}; };
// Returns access to the names defined in the module. // Returns access to the names defined in the module.
ModuleRecord.prototype.getNamespace = function() { ModuleRecord.prototype.getNamespace = function () {
return this.namespace; return this.namespace;
}; };
ModuleRecord.prototype.finalizeModuleInvokation = function() { ModuleRecord.prototype.finalizeModuleInvokation = function () {
var i, len = this.prefix.names.length; var i, len = this.prefix.names.length;
for (i=0; i < len; i++) { for (i = 0; i < len; i++) {
this.namespace[this.prefix.names[i]] = this.prefix[i]; this.namespace[this.prefix.names[i]] = this.prefix[i];
} }
}; };
// External invokation of a module. // External invokation of a module.
ModuleRecord.prototype.invoke = function(MACHINE, succ, fail) { ModuleRecord.prototype.invoke = function (MACHINE, succ, fail) {
this._invoke(false, MACHINE, succ, fail); this._invoke(false, MACHINE, succ, fail);
}; };
// Internal invokation of a module. // Internal invokation of a module.
ModuleRecord.prototype.internalInvoke = function(MACHINE, succ, fail) { ModuleRecord.prototype.internalInvoke = function (MACHINE, succ, fail) {
this._invoke(true, MACHINE, succ, fail); this._invoke(true, MACHINE, succ, fail);
}; };
// Private: general invokation of a module // Private: general invokation of a module
ModuleRecord.prototype._invoke = function(isInternal, MACHINE, succ, fail) { ModuleRecord.prototype._invoke = function (isInternal, MACHINE, succ, fail) {
var that = this; var that = this;
MACHINE = MACHINE || plt.runtime.currentMachine; MACHINE = MACHINE || plt.runtime.currentMachine;
succ = succ || function(){}; succ = succ || function () {};
fail = fail || function(){}; fail = fail || function () {};
var oldErrorHandler = MACHINE.params['currentErrorHandler']; var oldErrorHandler = MACHINE.params['currentErrorHandler'];
var afterGoodInvoke = function(MACHINE) { var afterGoodInvoke = function (MACHINE) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler; MACHINE.params['currentErrorHandler'] = oldErrorHandler;
succ(); succ();
}; };
@ -54,27 +59,22 @@
if (this.isInvoked) { if (this.isInvoked) {
succ(); succ();
} else { } else {
MACHINE.params['currentErrorHandler'] = function(MACHINE, anError) { MACHINE.params['currentErrorHandler'] = function (MACHINE, anError) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler; MACHINE.params['currentErrorHandler'] = oldErrorHandler;
fail(MACHINE, anError) fail(MACHINE, anError);
}; };
MACHINE.control.push(new plt.baselib.frames.CallFrame(afterGoodInvoke, null)); MACHINE.control.push(new plt.baselib.frames.CallFrame(afterGoodInvoke, null));
if (isInternal) { if (isInternal) {
throw that.label; throw that.label;
} else { } else {
plt.runtime.trampoline(MACHINE, that.label); MACHINE.trampoline(that.label);
} }
} }
}; };
exports.ModuleRecord = ModuleRecord; exports.ModuleRecord = ModuleRecord;
})(this['plt'].baselib); }(this.plt.baselib, this.plt));

View File

@ -1,5 +1,9 @@
/*jslint vars: true, maxerr: 50, indent: 4 */
// Numbers. // Numbers.
(function(baselib) { /*global jsnums*/
(function (baselib, jsnums) {
'use strict';
var exports = {}; var exports = {};
baselib.numbers = exports; baselib.numbers = exports;
@ -12,40 +16,40 @@
var isInteger = jsnums.isInteger; var isInteger = jsnums.isInteger;
var isNatural = function(x) { var isNatural = function (x) {
return (jsnums.isExact(x) && isInteger(x) return (jsnums.isExact(x) && isInteger(x)
&& jsnums.greaterThanOrEqual(x, 0)); && jsnums.greaterThanOrEqual(x, 0));
}; };
var isNonNegativeReal = function(x) { var isNonNegativeReal = function (x) {
return isReal(x) && jsnums.greaterThanOrEqual(x, 0); return isReal(x) && jsnums.greaterThanOrEqual(x, 0);
}; };
var isByte = function(x) { var isByte = function (x) {
return (isNatural(x) && return (isNatural(x) &&
jsnums.lessThan(x, 256)); jsnums.lessThan(x, 256));
}; };
// sign: number -> number // sign: number -> number
var sign = function(x) { var sign = function (x) {
if (jsnums.isInexact(x)) { if (jsnums.isInexact(x)) {
if (jsnums.greaterThan(x, 0) ) { if (jsnums.greaterThan(x, 0)) {
return jsnums.makeFloat(1); return jsnums.makeFloat(1);
} else if (jsnums.lessThan(x, 0) ) { } else if (jsnums.lessThan(x, 0)) {
return jsnums.makeFloat(-1); return jsnums.makeFloat(-1);
} else { } else {
return jsnums.makeFloat(0); return jsnums.makeFloat(0);
} }
} else { } else {
if (jsnums.greaterThan(x, 0)) { if (jsnums.greaterThan(x, 0)) {
return 1; return 1;
} else if (jsnums.lessThan(x, 0)) { } else if (jsnums.lessThan(x, 0)) {
return -1; return -1;
} else { } else {
return 0; return 0;
} }
} }
}; };
@ -56,7 +60,8 @@
// We first re-export everything in jsnums. // We first re-export everything in jsnums.
for (var prop in jsnums) { var prop;
for (prop in jsnums) {
if (jsnums.hasOwnProperty(prop)) { if (jsnums.hasOwnProperty(prop)) {
exports[prop] = jsnums[prop]; exports[prop] = jsnums[prop];
} }
@ -74,4 +79,4 @@
exports.sign = sign; exports.sign = sign;
})(this['plt'].baselib); }(this.plt.baselib, jsnums));

View File

@ -1,14 +1,18 @@
(function(baselib) { /*jslint vars: true, maxerr: 50, indent: 4 */
(function (baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.paths = exports; baselib.paths = exports;
// Paths // Paths
var Path = function(p) { var Path = function (p) {
this.path = p; this.path = p;
}; };
Path.prototype.toString = function() { Path.prototype.toString = function () {
return String(this.path); return String(this.path);
}; };
@ -16,4 +20,4 @@
exports.Path = Path; exports.Path = Path;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,49 +1,50 @@
// Placeholders // Placeholders
/*jslint browser: true, unparam: true, vars: true, maxerr: 50, indent: 4 */
(function(baselib) { (function (baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.placeholders = exports; baselib.placeholders = exports;
// Placeholders: same thing as boxes. Distinct type just to support make-reader-graph. // Placeholders: same thing as boxes. Distinct type just to support make-reader-graph.
var Placeholder = function(x, mutable) { var Placeholder = function (x, mutable) {
this.val = x; this.val = x;
}; };
Placeholder.prototype.ref = function() { Placeholder.prototype.ref = function () {
return this.val; return this.val;
}; };
Placeholder.prototype.set = function(newVal) { Placeholder.prototype.set = function (newVal) {
this.val = newVal; this.val = newVal;
}; };
Placeholder.prototype.toString = function(cache) { Placeholder.prototype.toString = function (cache) {
return "#<placeholder>"; return "#<placeholder>";
}; };
Placeholder.prototype.toWrittenString = function(cache) { Placeholder.prototype.toWrittenString = function (cache) {
return "#<placeholder>"; return "#<placeholder>";
}; };
Placeholder.prototype.toDisplayedString = function(cache) { Placeholder.prototype.toDisplayedString = function (cache) {
return "#<placeholder>"; return "#<placeholder>";
}; };
Placeholder.prototype.toDomNode = function(cache) { Placeholder.prototype.toDomNode = function (cache) {
var parent = document.createElement("span"); var parent = document.createElement("span");
parent.appendChild(document.createTextNode('#<placeholder>')); parent.appendChild(document.createTextNode('#<placeholder>'));
return parent; return parent;
}; };
Placeholder.prototype.equals = function(other, aUnionFind) { Placeholder.prototype.equals = function (other, aUnionFind) {
return ((other instanceof Placeholder) && return ((other instanceof Placeholder) &&
plt.baselib.equality.equals(this.val, other.val, aUnionFind)); baselib.equality.equals(this.val, other.val, aUnionFind));
}; };
var isPlaceholder = function(x) { var isPlaceholder = function (x) {
return x instanceof Placeholder; return x instanceof Placeholder;
}; };
@ -55,4 +56,4 @@
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,31 +1,34 @@
// Arity structure // Arity structure
(function(baselib) { /*jslint unparam: true, sub: true, vars: true, maxerr: 50, indent: 4 */
/*globals $*/
(function (baselib, $) {
'use strict';
var exports = {}; var exports = {};
baselib.ports = exports; baselib.ports = exports;
// Output Ports // Output Ports
var OutputPort = function() {}; var OutputPort = function () {};
var isOutputPort = baselib.makeClassPredicate(OutputPort); var isOutputPort = baselib.makeClassPredicate(OutputPort);
var StandardOutputPort = function() { var StandardOutputPort = function () {
OutputPort.call(this); OutputPort.call(this);
}; };
StandardOutputPort.prototype = baselib.heir(OutputPort.prototype); StandardOutputPort.prototype = baselib.heir(OutputPort.prototype);
StandardOutputPort.prototype.writeDomNode = function(MACHINE, domNode) { StandardOutputPort.prototype.writeDomNode = function (MACHINE, domNode) {
MACHINE.params['currentDisplayer'](MACHINE, domNode); MACHINE.params['currentDisplayer'](MACHINE, domNode);
jQuery('*', domNode).trigger({type : 'afterAttach'}); $('*', domNode).trigger({type : 'afterAttach'});
}; };
var StandardErrorPort = function() { var StandardErrorPort = function () {
OutputPort.call(this); OutputPort.call(this);
}; };
StandardErrorPort.prototype = baselib.heir(OutputPort.prototype); StandardErrorPort.prototype = baselib.heir(OutputPort.prototype);
StandardErrorPort.prototype.writeDomNode = function(MACHINE, domNode) { StandardErrorPort.prototype.writeDomNode = function (MACHINE, domNode) {
MACHINE.params['currentErrorDisplayer'](MACHINE, domNode); MACHINE.params['currentErrorDisplayer'](MACHINE, domNode);
jQuery('*', domNode).trigger({type : 'afterAttach'}); $('*', domNode).trigger({type : 'afterAttach'});
}; };
@ -33,15 +36,15 @@
var OutputStringPort = function() { var OutputStringPort = function () {
this.buf = []; this.buf = [];
}; };
OutputStringPort.prototype = baselib.heir(OutputPort.prototype); OutputStringPort.prototype = baselib.heir(OutputPort.prototype);
OutputStringPort.prototype.writeDomNode = function(MACHINE, v) { OutputStringPort.prototype.writeDomNode = function (MACHINE, v) {
this.buf.push($(v).text()); this.buf.push($(v).text());
}; };
OutputStringPort.prototype.getOutputString = function() { OutputStringPort.prototype.getOutputString = function () {
return this.buf.join(''); return this.buf.join('');
}; };
var isOutputStringPort = baselib.makeClassPredicate(OutputStringPort); var isOutputStringPort = baselib.makeClassPredicate(OutputStringPort);
@ -56,4 +59,4 @@
exports.isOutputStringPort = isOutputStringPort; exports.isOutputStringPort = isOutputStringPort;
})(this['plt'].baselib); }(this.plt.baselib, $));

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +1,57 @@
/*jslint vars: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
// Arity structure // Arity structure
(function(baselib) { (function (baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.readergraph = exports; baselib.readergraph = exports;
var readerGraph = function(x, objectHash, n) { var readerGraph = function (x, objectHash, n) {
if (typeof(x) === 'object' && objectHash.containsKey(x)) { var i;
return objectHash.get(x); if (typeof (x) === 'object' && objectHash.containsKey(x)) {
return objectHash.get(x);
} }
if (plt.baselib.lists.isPair(x)) { if (baselib.lists.isPair(x)) {
var consPair = plt.baselib.lists.makePair(x.first, x.rest); var consPair = baselib.lists.makePair(x.first, x.rest);
objectHash.put(x, consPair); objectHash.put(x, consPair);
consPair.first = readerGraph(x.first, objectHash, n+1); consPair.first = readerGraph(x.first, objectHash, n + 1);
consPair.rest = readerGraph(x.rest, objectHash, n+1); consPair.rest = readerGraph(x.rest, objectHash, n + 1);
return consPair; return consPair;
} }
if (plt.baselib.vectors.isVector(x)) { if (baselib.vectors.isVector(x)) {
var len = x.length(); var len = x.length();
var aVector = plt.baselib.vectors.makeVector(len, x.elts); var aVector = baselib.vectors.makeVector(len, x.elts);
objectHash.put(x, aVector); objectHash.put(x, aVector);
for (var i = 0; i < len; i++) { for (i = 0; i < len; i++) {
aVector.elts[i] = readerGraph(aVector.elts[i], objectHash, n+1); aVector.elts[i] = readerGraph(aVector.elts[i], objectHash, n + 1);
} }
return aVector; return aVector;
} }
if (plt.baselib.boxes.isBox(x)) { if (baselib.boxes.isBox(x)) {
var aBox = plt.baselib.boxes.makeBox(x.ref()); var aBox = baselib.boxes.makeBox(x.ref());
objectHash.put(x, aBox); objectHash.put(x, aBox);
aBox.val = readerGraph(x.ref(), objectHash, n+1); aBox.val = readerGraph(x.ref(), objectHash, n + 1);
return aBox; return aBox;
} }
if (plt.baselib.hashes.isHash(x)) { if (baselib.hashes.isHash(x)) {
throw new Error("make-reader-graph of hash not implemented yet"); throw new Error("make-reader-graph of hash not implemented yet");
} }
if (plt.baselib.structs.isStruct(x)) { if (baselib.structs.isStruct(x)) {
var aStruct = baselib.clone(x); var aStruct = baselib.clone(x);
objectHash.put(x, aStruct); objectHash.put(x, aStruct);
for(var i = 0 ;i < x._fields.length; i++) { for (i = 0; i < x._fields.length; i++) {
x._fields[i] = readerGraph(x._fields[i], objectHash, n+1); x._fields[i] = readerGraph(x._fields[i], objectHash, n + 1);
} }
return aStruct; return aStruct;
} }
if (plt.baselib.placeholders.isPlaceholder(x)) { if (baselib.placeholders.isPlaceholder(x)) {
return readerGraph(x.ref(), objectHash, n+1); return readerGraph(x.ref(), objectHash, n + 1);
} }
return x; return x;
@ -56,4 +59,4 @@
exports.readerGraph = readerGraph; exports.readerGraph = readerGraph;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,16 +1,19 @@
(function(baselib) { /*jslint vars: true, maxerr: 50, indent: 4 */
(function (baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.regexps = exports; baselib.regexps = exports;
// Regular expressions. // Regular expressions.
var RegularExpression = function(pattern) { var RegularExpression = function (pattern) {
this.pattern = pattern; this.pattern = pattern;
}; };
var ByteRegularExpression = function(pattern) { var ByteRegularExpression = function (pattern) {
this.pattern = pattern; this.pattern = pattern;
}; };
@ -19,4 +22,4 @@
exports.RegularExpression = RegularExpression; exports.RegularExpression = RegularExpression;
exports.ByteRegularExpression = ByteRegularExpression; exports.ByteRegularExpression = ByteRegularExpression;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,106 +1,43 @@
/*jslint browser: false, unparam: true, vars: true, white: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
// Strings // Strings
// Strings are either mutable or immutable. immutable strings are represented // Strings are either mutable or immutable. immutable strings are represented
// as regular JavaScript strings. Mutable ones are represented as instances // as regular JavaScript strings. Mutable ones are represented as instances
// of the Str class. // of the Str class.
(function(baselib) { (function (baselib) {
'use strict';
var exports = {}; var exports = {};
baselib.strings = exports; baselib.strings = exports;
var isString = function(s) {
return (typeof s === 'string' ||
s instanceof Str);
};
// chars: arrayof string // chars: arrayof string
// Precondition: each string must only be 1 character long or bad things // Precondition: each string must only be 1 character long or bad things
// happen. // happen.
var Str = function(chars) { var Str = function (chars) {
this.chars = chars; this.chars = chars;
this.length = chars.length; this.length = chars.length;
this.mutable = true; this.mutable = true;
}
Str.makeInstance = function(chars) {
return new Str(chars);
}
Str.fromString = function(s) {
return Str.makeInstance(s.split(""));
}
Str.prototype.toString = function() {
return this.chars.join("");
}
Str.prototype.toWrittenString = function(cache) {
return escapeString(this.toString());
}
Str.prototype.toDisplayedString = Str.prototype.toString;
Str.prototype.copy = function() {
return Str.makeInstance(this.chars.slice(0));
}
Str.prototype.substring = function(start, end) {
if (end == null || end == undefined) {
end = this.length;
}
return Str.makeInstance( this.chars.slice(start, end) );
}
Str.prototype.charAt = function(index) {
return this.chars[index];
}
Str.prototype.charCodeAt = function(index) {
return this.chars[index].charCodeAt(0);
}
Str.prototype.replace = function(expr, newStr) {
return Str.fromString( this.toString().replace(expr, newStr) );
}
Str.prototype.equals = function(other, aUnionFind) {
if ( !(other instanceof Str || typeof(other) == 'string') ) {
return false;
}
return this.toString() === other.toString();
}
Str.prototype.set = function(i, c) {
this.chars[i] = c;
}
Str.prototype.toUpperCase = function() {
return Str.fromString( this.chars.join("").toUpperCase() );
}
Str.prototype.toLowerCase = function() {
return Str.fromString( this.chars.join("").toLowerCase() );
}
Str.prototype.match = function(regexpr) {
return this.toString().match(regexpr);
}
var escapeString = function(s) {
return '"' + replaceUnprintableStringChars(s) + '"';
}; };
var replaceUnprintableStringChars = function(s) { Str.makeInstance = function (chars) {
var ret = []; return new Str(chars);
for (var i = 0; i < s.length; i++) { };
Str.fromString = function (s) {
return Str.makeInstance(s.split(""));
};
Str.prototype.toString = function () {
return this.chars.join("");
};
var replaceUnprintableStringChars = function (s) {
var ret = [], i;
for (i = 0; i < s.length; i++) {
var val = s.charCodeAt(i); var val = s.charCodeAt(i);
switch(val) { switch(val) {
case 7: ret.push('\\a'); break; case 7: ret.push('\\a'); break;
@ -128,7 +65,70 @@
return ret.join(''); return ret.join('');
}; };
var escapeString = function (s) {
return '"' + replaceUnprintableStringChars(s) + '"';
};
Str.prototype.toWrittenString = function (cache) {
return escapeString(this.toString());
};
Str.prototype.toDisplayedString = Str.prototype.toString;
Str.prototype.copy = function () {
return Str.makeInstance(this.chars.slice(0));
};
Str.prototype.substring = function (start, end) {
if (end === null || end === undefined) {
end = this.length;
}
return Str.makeInstance( this.chars.slice(start, end) );
};
Str.prototype.charAt = function (index) {
return this.chars[index];
};
Str.prototype.charCodeAt = function (index) {
return this.chars[index].charCodeAt(0);
};
Str.prototype.replace = function (expr, newStr) {
return Str.fromString( this.toString().replace(expr, newStr) );
};
Str.prototype.equals = function (other, aUnionFind) {
if ( !(other instanceof Str || typeof(other) === 'string') ) {
return false;
}
return this.toString() === other.toString();
};
Str.prototype.set = function (i, c) {
this.chars[i] = c;
};
Str.prototype.toUpperCase = function () {
return Str.fromString( this.chars.join("").toUpperCase() );
};
Str.prototype.toLowerCase = function () {
return Str.fromString( this.chars.join("").toLowerCase() );
};
Str.prototype.match = function (regexpr) {
return this.toString().match(regexpr);
};
var isString = function (s) {
return (typeof s === 'string' ||
s instanceof Str);
};
var isMutableString = baselib.makeClassPredicate(Str); var isMutableString = baselib.makeClassPredicate(Str);
@ -140,4 +140,4 @@
exports.isMutableString = isMutableString; exports.isMutableString = isMutableString;
exports.makeMutableString = Str.makeInstance; exports.makeMutableString = Str.makeInstance;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,45 +1,102 @@
// Structure types /*jslint browser: true, unparam: true, vars: true, white: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
/*globals $*/
(function(baselib) { (function (baselib, $) {
"use strict";
var exports = {}; var exports = {};
baselib.structs = exports; baselib.structs = exports;
//////////////////////////////////////////////////////////////////////
var Struct = function (constructorName, fields) {
this._constructorName = constructorName;
this._fields = [];
};
Struct.prototype.toWrittenString = function (cache) {
var buffer = [], i;
cache.put(this, true);
buffer.push("(");
buffer.push(this._constructorName);
for(i = 0; i < this._fields.length; i++) {
buffer.push(" ");
buffer.push(baselib.format.toWrittenString(this._fields[i], cache));
}
buffer.push(")");
return buffer.join("");
};
var StructType = function(name, // string Struct.prototype.toDisplayedString = function (cache) {
type, // StructType return baselib.format.toWrittenString(this, cache);
numberOfArgs, // number };
numberOfFields, // number
firstField,
applyGuard,
constructor,
predicate,
accessor,
mutator) {
this.name = name;
this.type = type;
this.numberOfArgs = numberOfArgs;
this.numberOfFields = numberOfFields;
this.firstField = firstField;
this.applyGuard = applyGuard; Struct.prototype.toDomNode = function (params) {
this.constructor = constructor; var node = document.createElement("span"), i;
this.predicate = predicate; params.put(this, true);
this.accessor = accessor; $(node).append(document.createTextNode("("));
this.mutator = mutator; $(node).append(document.createTextNode(this._constructorName));
for(i = 0; i < this._fields.length; i++) {
$(node).append(document.createTextNode(" "));
$(node).append(baselib.format.toDomNode(this._fields[i], params));
}
$(node).append(document.createTextNode(")"));
return node;
}; };
StructType.prototype.toString = function(cache) { Struct.prototype.equals = function (other, aUnionFind) {
return '#<struct-type:' + this.name + '>'; var i;
if (!(other instanceof this.type)) {
return false;
}
for (i = 0; i < this._fields.length; i++) {
if (! baselib.equality.equals(this._fields[i],
other._fields[i],
aUnionFind)) {
return false;
}
}
return true;
};
Struct.prototype.type = Struct;
//////////////////////////////////////////////////////////////////////
var StructType = function (name, // string
type, // StructType
numberOfArgs, // number
numberOfFields, // number
firstField,
applyGuard,
constructor,
predicate,
accessor,
mutator) {
this.name = name;
this.type = type;
this.numberOfArgs = numberOfArgs;
this.numberOfFields = numberOfFields;
this.firstField = firstField;
this.applyGuard = applyGuard;
this.constructor = constructor;
this.predicate = predicate;
this.accessor = accessor;
this.mutator = mutator;
}; };
StructType.prototype.equals = function(other, aUnionFind) { StructType.prototype.toString = function (cache) {
return this === other; return '#<struct-type:' + this.name + '>';
};
StructType.prototype.equals = function (other, aUnionFind) {
return this === other;
}; };
@ -52,17 +109,34 @@
// Default structure guard just calls the continuation argument.
var DEFAULT_GUARD = function (args, name, k) {
return k(args);
};
// The default parent type refers to the toplevel Struct.
var DEFAULT_PARENT_TYPE = { type: Struct,
numberOfArgs: 0,
numberOfFields: 0,
firstField: 0,
applyGuard: DEFAULT_GUARD };
// makeStructureType: string StructType number number boolean // makeStructureType: string StructType number number boolean
// guard-function -> StructType // guard-function -> StructType
// //
// Creates a new structure type. // Creates a new structure type.
var makeStructureType = function(theName, var makeStructureType = function (theName,
parentType, parentType,
initFieldCnt, initFieldCnt,
autoFieldCnt, autoFieldCnt,
autoV, autoV,
guard) { guard) {
// Defaults // Defaults
autoFieldCnt = autoFieldCnt || 0; autoFieldCnt = autoFieldCnt || 0;
parentType = parentType || DEFAULT_PARENT_TYPE; parentType = parentType || DEFAULT_PARENT_TYPE;
@ -70,66 +144,67 @@
// rawConstructor creates a new struct type inheriting from // RawConstructor creates a new struct type inheriting from
// the parent, with no guard checks. // the parent, with no guard checks.
var rawConstructor = function(name, args) { var RawConstructor = function (name, args) {
parentType.type.call(this, name, args); var i;
for (var i = 0; i < initFieldCnt; i++) { parentType.type.call(this, name, args);
this._fields.push(args[i+parentType.numberOfArgs]); for (i = 0; i < initFieldCnt; i++) {
} this._fields.push(args[i+parentType.numberOfArgs]);
for (var i = 0; i < autoFieldCnt; i++) { }
this._fields.push(autoV); for (i = 0; i < autoFieldCnt; i++) {
} this._fields.push(autoV);
}
}; };
rawConstructor.prototype = baselib.heir(parentType.type.prototype); RawConstructor.prototype = baselib.heir(parentType.type.prototype);
// Set type, necessary for equality checking // Set type, necessary for equality checking
rawConstructor.prototype.type = rawConstructor; RawConstructor.prototype.type = RawConstructor;
// The structure type consists of the name, its constructor, a // The structure type consists of the name, its constructor, a
// record of how many argument it and its parent type contains, // record of how many argument it and its parent type contains,
// the list of autofields, the guard, and functions corresponding // the list of autofields, the guard, and functions corresponding
// to the constructor, the predicate, the accessor, and mutators. // to the constructor, the predicate, the accessor, and mutators.
var newType = new StructType( var newType = new StructType(
theName, theName,
rawConstructor, RawConstructor,
initFieldCnt + parentType.numberOfArgs, initFieldCnt + parentType.numberOfArgs,
initFieldCnt + autoFieldCnt, initFieldCnt + autoFieldCnt,
parentType.firstField + parentType.numberOfFields, parentType.firstField + parentType.numberOfFields,
function(args, name, k) { function (args, name, k) {
return guard(args, name, return guard(args, name,
function(result) { function (result) {
var parentArgs = result.slice(0, parentType.numberOfArgs); var parentArgs = result.slice(0, parentType.numberOfArgs);
var restArgs = result.slice(parentType.numberOfArgs); var restArgs = result.slice(parentType.numberOfArgs);
return parentType.applyGuard( return parentType.applyGuard(
parentArgs, name, parentArgs, name,
function(parentRes) { function (parentRes) {
return k( parentRes.concat(restArgs) ); }); return k( parentRes.concat(restArgs) ); });
}); });
}, },
// constructor // constructor
function() { function () {
var args = [].slice.call(arguments); var args = [].slice.call(arguments);
return newType.applyGuard( return newType.applyGuard(
args, args,
baselib.symbols.Symbol.makeInstance(theName), baselib.symbols.Symbol.makeInstance(theName),
function(res) { function (res) {
return new rawConstructor(theName, res); }); return new RawConstructor(theName, res); });
}, },
// predicate // predicate
function(x) { function (x) {
return x instanceof rawConstructor; return x instanceof RawConstructor;
}, },
// accessor // accessor
function(x, i) { return x._fields[i + this.firstField]; }, function (x, i) { return x._fields[i + this.firstField]; },
// mutator // mutator
function(x, i, v) { x._fields[i + this.firstField] = v; }); function (x, i, v) { x._fields[i + this.firstField] = v; });
return newType; return newType;
}; };
@ -137,129 +212,10 @@
//////////////////////////////////////////////////////////////////////
var isStruct = function (x) { return x instanceof Struct; };
var Struct = function(constructorName, fields) { var isStructType = function (x) { return x instanceof StructType; };
this._constructorName = constructorName;
this._fields = [];
};
Struct.prototype.toWrittenString = function(cache) {
cache.put(this, true);
var buffer = [];
buffer.push("(");
buffer.push(this._constructorName);
for(var i = 0; i < this._fields.length; i++) {
buffer.push(" ");
buffer.push(plt.baselib.format.toWrittenString(this._fields[i], cache));
}
buffer.push(")");
return buffer.join("");
};
Struct.prototype.toDisplayedString = function(cache) {
return plt.baselib.format.toWrittenString(this, cache);
};
Struct.prototype.toDomNode = function(params) {
params.put(this, true);
var node = document.createElement("span");
$(node).append(document.createTextNode("("));
$(node).append(document.createTextNode(this._constructorName));
for(var i = 0; i < this._fields.length; i++) {
$(node).append(document.createTextNode(" "));
$(node).append(plt.baselib.format.toDomNode(this._fields[i], params));
}
$(node).append(document.createTextNode(")"));
return node;
};
Struct.prototype.equals = function(other, aUnionFind) {
if ( other.type == undefined ||
this.type !== other.type ||
!(other instanceof this.type) ) {
return false;
}
for (var i = 0; i < this._fields.length; i++) {
if (! equals(this._fields[i],
other._fields[i],
aUnionFind)) {
return false;
}
}
return true;
}
Struct.prototype.type = Struct;
// // Struct Procedure types
// var StructProc = function(type, name, numParams, isRest, usesState, impl) {
// PrimProc.call(this, name, numParams, isRest, usesState, impl);
// this.type = type;
// };
// StructProc.prototype = baselib.heir(PrimProc.prototype);
// var StructConstructorProc = function() {
// StructProc.apply(this, arguments);
// };
// StructConstructorProc.prototype = baselib.heir(StructProc.prototype);
// var StructPredicateProc = function() {
// StructProc.apply(this, arguments);
// };
// StructPredicateProc.prototype = baselib.heir(StructProc.prototype);
// var StructAccessorProc = function() {
// StructProc.apply(this, arguments);
// };
// StructAccessorProc.prototype = baselib.heir(StructProc.prototype);
// var StructMutatorProc = function() {
// StructProc.apply(this, arguments);
// };
// StructMutatorProc.prototype = baselib.heir(StructProc.prototype);
// Default structure guard just calls the continuation argument.
var DEFAULT_GUARD = function(args, name, k) {
return k(args);
};
// The default parent type refers to the toplevel Struct.
var DEFAULT_PARENT_TYPE = { type: Struct,
numberOfArgs: 0,
numberOfFields: 0,
firstField: 0,
applyGuard: DEFAULT_GUARD };
var isStruct = function(x) { return x instanceof Struct; };
var isStructType = function(x) { return x instanceof StructType; };
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@ -271,16 +227,4 @@
exports.isStruct = isStruct; exports.isStruct = isStruct;
exports.isStructType = isStructType; exports.isStructType = isStructType;
// exports.StructProc = StructProc; }(this.plt.baselib, $));
// exports.StructConstructorProc = StructConstructorProc;
// exports.StructPredicateProc = StructPredicateProc;
// exports.StructAccessorProc = StructAccessorProc;
// exports.StructMutatorProc = StructMutatorProc;
})(this['plt'].baselib);

View File

@ -1,7 +1,7 @@
/*jslint devel: false, browser: true, unparam: true, vars: true, plusplus: true, maxerr: 500, indent: 4 */
// Structure types // Structure types
(function (baselib) {
(function(baselib) { "use strict";
var exports = {}; var exports = {};
baselib.symbols = exports; baselib.symbols = exports;
@ -11,44 +11,43 @@
// Symbols // Symbols
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
var Symbol = function(val) { var Symbol = function (val) {
this.val = val; this.val = val;
}; };
var symbolCache = {}; var symbolCache = {};
// makeInstance: string -> Symbol. // makeInstance: string -> Symbol.
Symbol.makeInstance = function(val) { Symbol.makeInstance = function (val) {
// To ensure that we can eq? symbols with equal values. // To ensure that we can eq? symbols with equal values.
if (!(val in symbolCache)) { if (!(symbolCache.hasOwnProperty(val))) {
symbolCache[val] = new Symbol(val); symbolCache[val] = new Symbol(val);
} else {
} }
return symbolCache[val]; return symbolCache[val];
}; };
Symbol.prototype.equals = function(other, aUnionFind) { Symbol.prototype.equals = function (other, aUnionFind) {
return other instanceof Symbol && return other instanceof Symbol &&
this.val === other.val; this.val === other.val;
}; };
Symbol.prototype.toString = function(cache) { Symbol.prototype.toString = function (cache) {
return this.val; return this.val;
}; };
Symbol.prototype.toWrittenString = function(cache) { Symbol.prototype.toWrittenString = function (cache) {
return this.val; return this.val;
}; };
Symbol.prototype.toDisplayedString = function(cache) { Symbol.prototype.toDisplayedString = function (cache) {
return this.val; return this.val;
}; };
var isSymbol = function(x) { return x instanceof Symbol; }; var isSymbol = function (x) { return x instanceof Symbol; };
var makeSymbol = function(s) { return Symbol.makeInstance(s); }; var makeSymbol = function (s) { return Symbol.makeInstance(s); };
@ -58,4 +57,4 @@
exports.makeSymbol = makeSymbol; exports.makeSymbol = makeSymbol;
exports.isSymbol = isSymbol; exports.isSymbol = isSymbol;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,41 +1,38 @@
(function(baselib) { /*jslint devel: false, browser: true, vars: true, plusplus: true, maxerr: 500, indent: 4 */
(function (baselib) {
"use strict";
// Union/find for circular equality testing. // Union/find for circular equality testing.
var UnionFind = function() { var UnionFind = function () {
// this.parenMap holds the arrows from an arbitrary pointer // this.parenMap holds the arrows from an arbitrary pointer
// to its parent. // to its parent.
this.parentMap = baselib.hashes.makeLowLevelEqHash(); this.parentMap = baselib.hashes.makeLowLevelEqHash();
} };
// find: ptr -> UnionFindNode // find: ptr -> UnionFindNode
// Returns the representative for this ptr. // Returns the representative for this ptr.
UnionFind.prototype.find = function(ptr) { UnionFind.prototype.find = function (ptr) {
var parent = (this.parentMap.containsKey(ptr) ? var parent = (this.parentMap.containsKey(ptr) ?
this.parentMap.get(ptr) : ptr); this.parentMap.get(ptr) : ptr);
if (parent === ptr) { if (parent === ptr) {
return parent; return parent;
} else { } else {
var rep = this.find(parent); var rep = this.find(parent);
// Path compression: // Path compression:
this.parentMap.put(ptr, rep); this.parentMap.put(ptr, rep);
return rep; return rep;
} }
}; };
// merge: ptr ptr -> void // merge: ptr ptr -> void
// Merge the representative nodes for ptr1 and ptr2. // Merge the representative nodes for ptr1 and ptr2.
UnionFind.prototype.merge = function(ptr1, ptr2) { UnionFind.prototype.merge = function (ptr1, ptr2) {
this.parentMap.put(this.find(ptr1), this.find(ptr2)); this.parentMap.put(this.find(ptr1), this.find(ptr2));
}; };
baselib.UnionFind = UnionFind; baselib.UnionFind = UnionFind;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,104 +1,109 @@
// vectors // vectors
(function(baselib) { /*jslint devel: false, browser: true, vars: true, plusplus: true, maxerr: 500, indent: 4 */
(function (baselib) {
"use strict";
var exports = {}; var exports = {};
baselib.vectors = exports; baselib.vectors = exports;
Vector = function(n, initialElements) { var Vector = function (n, initialElements) {
this.elts = new Array(n); var i;
this.elts = [];
this.elts.length = n;
if (initialElements) { if (initialElements) {
for (var i = 0; i < n; i++) { for (i = 0; i < n; i++) {
this.elts[i] = initialElements[i]; this.elts[i] = initialElements[i];
} }
} else { } else {
for (var i = 0; i < n; i++) { for (i = 0; i < n; i++) {
this.elts[i] = undefined; this.elts[i] = undefined;
} }
} }
this.mutable = true; this.mutable = true;
}; };
Vector.makeInstance = function(n, elts) { Vector.makeInstance = function (n, elts) {
return new Vector(n, elts); return new Vector(n, elts);
}
Vector.prototype.length = function() {
return this.elts.length;
}; };
Vector.prototype.ref = function(k) { Vector.prototype.length = function () {
return this.elts.length;
};
Vector.prototype.ref = function (k) {
return this.elts[k]; return this.elts[k];
}; };
Vector.prototype.set = function(k, v) { Vector.prototype.set = function (k, v) {
this.elts[k] = v; this.elts[k] = v;
}; };
Vector.prototype.equals = function(other, aUnionFind) { Vector.prototype.equals = function (other, aUnionFind) {
if (other != null && other != undefined && other instanceof Vector) { var i;
if (other.length() != this.length()) { if (other instanceof Vector) {
return false if (other.length() !== this.length()) {
} return false;
for (var i = 0; i < this.length(); i++) { }
if (! plt.baselib.equality.equals(this.elts[i], other.elts[i], aUnionFind)) { for (i = 0; i < this.length(); i++) {
return false; if (!(baselib.equality.equals(this.elts[i], other.elts[i], aUnionFind))) {
} return false;
} }
return true; }
return true;
} else { } else {
return false; return false;
} }
}; };
Vector.prototype.toList = function() { Vector.prototype.toList = function () {
var ret = plt.baselib.lists.EMPTY; var ret = baselib.lists.EMPTY, i;
for (var i = this.length() - 1; i >= 0; i--) { for (i = this.length() - 1; i >= 0; i--) {
ret = plt.baselib.lists.Cons.makeInstance(this.elts[i], ret); ret = baselib.lists.Cons.makeInstance(this.elts[i], ret);
} }
return ret; return ret;
}; };
Vector.prototype.toWrittenString = function(cache) { Vector.prototype.toWrittenString = function (cache) {
var texts = [], i;
cache.put(this, true); cache.put(this, true);
var texts = []; for (i = 0; i < this.length(); i++) {
for (var i = 0; i < this.length(); i++) { texts.push(baselib.format.toWrittenString(this.ref(i), cache));
texts.push(plt.baselib.format.toWrittenString(this.ref(i), cache));
} }
return "#(" + texts.join(" ") + ")"; return "#(" + texts.join(" ") + ")";
}; };
Vector.prototype.toDisplayedString = function(cache) { Vector.prototype.toDisplayedString = function (cache) {
var texts = [], i;
cache.put(this, true); cache.put(this, true);
var texts = []; for (i = 0; i < this.length(); i++) {
for (var i = 0; i < this.length(); i++) { texts.push(baselib.format.toDisplayedString(this.ref(i), cache));
texts.push(plt.baselib.format.toDisplayedString(this.ref(i), cache));
} }
return "#(" + texts.join(" ") + ")"; return "#(" + texts.join(" ") + ")";
}; };
Vector.prototype.toDomNode = function(cache) { Vector.prototype.toDomNode = function (cache) {
var node = document.createElement("span"), i;
cache.put(this, true); cache.put(this, true);
var node = document.createElement("span");
node.appendChild(document.createTextNode("#(")); node.appendChild(document.createTextNode("#("));
for (var i = 0; i < this.length(); i++) { for (i = 0; i < this.length(); i++) {
node.appendChild(plt.baselib.format.toDomNode(this.ref(i), cache)); node.appendChild(baselib.format.toDomNode(this.ref(i), cache));
if (i !== this.length()-1) { if (i !== this.length() - 1) {
node.appendChild(document.createTextNode(" ")); node.appendChild(document.createTextNode(" "));
} }
} }
node.appendChild(document.createTextNode(")")); node.appendChild(document.createTextNode(")"));
return node; return node;
}; };
var isVector = function(x) { return x instanceof Vector; }; var isVector = function (x) { return x instanceof Vector; };
var makeVector = function() { var makeVector = function () {
return Vector.makeInstance(arguments.length, arguments); return Vector.makeInstance(arguments.length, arguments);
}; };
var makeVectorImmutable = function() { var makeVectorImmutable = function () {
var v = Vector.makeInstance(arguments.length, arguments); var v = Vector.makeInstance(arguments.length, arguments);
v.mutable = false; v.mutable = false;
return v; return v;
@ -114,4 +119,4 @@
exports.makeVectorImmutable = makeVectorImmutable; exports.makeVectorImmutable = makeVectorImmutable;
})(this['plt'].baselib); }(this.plt.baselib));

View File

@ -1,18 +1,21 @@
/*jslint vars: true, plusplus: true, maxerr: 50, indent: 4 */
// Basic library functions. This will include a few simple functions, // Basic library functions. This will include a few simple functions,
// but be augmented with several namespaces for the other libraries in // but be augmented with several namespaces for the other libraries in
// the base library. // the base library.
if (! this['plt']) { this['plt'] = {}; } if (!(this.plt)) { this.plt = {}; }
(function (plt) { (function (plt) {
'use strict';
var baselib = {}; var baselib = {};
plt['baselib'] = baselib; plt.baselib = baselib;
// Simple object inheritance. // Simple object inheritance.
var heir = function(parentPrototype) { var heir = function (parentPrototype) {
var f = function() {} var F = function () {};
f.prototype = parentPrototype; F.prototype = parentPrototype;
return new f(); return new F();
}; };
@ -20,22 +23,23 @@ if (! this['plt']) { this['plt'] = {}; }
// clone: object -> object // clone: object -> object
// Copies an object. The new object should respond like the old // Copies an object. The new object should respond like the old
// object, including to things like instanceof. // object, including to things like instanceof.
var clone = function(obj) { var clone = function (obj) {
var C = function() {} var property;
var C = function () {};
C.prototype = obj; C.prototype = obj;
var c = new C(); var c = new C();
for (property in obj) { for (property in obj) {
if (obj.hasOwnProperty(property)) { if (obj.hasOwnProperty(property)) {
c[property] = obj[property]; c[property] = obj[property];
} }
} }
return c; return c;
}; };
// Consumes a class and creates a predicate that recognizes subclasses. // Consumes a class and creates a predicate that recognizes subclasses.
var makeClassPredicate = function(aClass) { var makeClassPredicate = function (aClass) {
return function(x) { return x instanceof aClass; }; return function (x) { return x instanceof aClass; };
}; };
@ -45,12 +49,9 @@ if (! this['plt']) { this['plt'] = {}; }
// MACHINE.argcount has been initialized with the number of // MACHINE.argcount has been initialized with the number of
// arguments on the stack. vs provides optional values for the // arguments on the stack. vs provides optional values for the
// arguments that go beyond those of the mandatoryArgCount. // arguments that go beyond those of the mandatoryArgCount.
var withArguments = function(MACHINE, var withArguments = function (MACHINE, mandatoryArgCount, vs, f) {
mandatoryArgCount, var args = [], i;
vs, for (i = 0; i < MACHINE.argcount; i++) {
f) {
var args = [];
for (var i = 0; i < MACHINE.argcount; i++) {
if (i < mandatoryArgCount) { if (i < mandatoryArgCount) {
args.push(MACHINE.env[MACHINE.env.length - 1 - i]); args.push(MACHINE.env[MACHINE.env.length - 1 - i]);
} else { } else {
@ -72,4 +73,4 @@ if (! this['plt']) { this['plt'] = {}; }
baselib.withArguments = withArguments; baselib.withArguments = withArguments;
})(this['plt']); }(this.plt));

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
"use strict";

View File

@ -69,13 +69,16 @@
(check-equal? (run-my-parse #'(begin (define x 3) (check-true (match (run-my-parse #'(begin (define x 3)
x)) x))
(make-Top (make-Prefix (list (make-GlobalBucket 'x))) [(struct Top ((struct Prefix (_))
(make-Splice (list (make-DefValues (list (make-ToplevelRef 0 0 #f #t)) (struct Splice ((list (struct DefValues ((list (struct ToplevelRef ('0 '0 '#f '#t)))
(make-Constant 3)) (struct Constant ('3))))
(make-ToplevelRef 0 0 #f #t))))) (struct ToplevelRef ('0 '0 '#f '#t)))))))
#t]
[else
#f]))
;; Lambdas ;; Lambdas
(let ([parsed (run-my-parse #'(lambda (x) x))]) (let ([parsed (run-my-parse #'(lambda (x) x))])
@ -368,9 +371,17 @@
;; Variable reference ;; Variable reference
(check-equal? (run-my-parse #'(#%variable-reference x)) (check-true (match (run-my-parse #'(#%variable-reference x))
(make-Top (make-Prefix (list #f (make-GlobalBucket 'x))) [(struct Top ((struct Prefix
(make-VariableReference (make-ToplevelRef 0 0 #f #t)))) ((list #f (struct GlobalBucket ('x)))))
(struct VariableReference ((struct ToplevelRef ('0 '1 '#f '#t))))))
#t]
[else
#f]))
;(make-Top (make-Prefix (list (make-GlobalBucket 'x)))
; (make-VariableReference (make-ToplevelRef 0 0 #f #t))))
;; todo: see what it would take to run a typed/racket/base language. ;; todo: see what it would take to run a typed/racket/base language.
(void (void