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);
videos = {};
var videos = {};
VideoImage.makeInstance = function(path, rawVideo) {
if (! (path in VideoImage)) {
videos[path] = new VideoImage(path, rawVideo);

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@
(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)
(define (sort&unique names)

View File

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

View File

@ -333,7 +333,7 @@ MACHINE.modules[~s] =
<title>Example</title>
</head>
<script>
"use strict";
EOF
)
@ -375,10 +375,15 @@ var invokeMainModule = function() {
var MACHINE = plt.runtime.currentMachine;
invoke(MACHINE,
function() {
var startTime = new Date().valueOf();
plt.runtime.invokeMains(
MACHINE,
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) {
// 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
(function(baselib) {
'use strict';
var exports = {};
baselib.arity = exports;
var ArityAtLeast = plt.baselib.structs.makeStructureType(
var ArityAtLeast = baselib.structs.makeStructureType(
'arity-at-least', false, 1, 0, false, false);
@ -18,7 +21,7 @@
var arityAtLeastValue = function(x) {
var val = ArityAtLeast.accessor(x, 0);
return val;
}
};
ArityAtLeast.type.prototype.toString = function() {
@ -35,7 +38,7 @@
} else if (isArityAtLeast(arity)) {
return n >= arityAtLeastValue(arity);
} else {
while (arity !== plt.baselib.lists.EMPTY) {
while (arity !== baselib.lists.EMPTY) {
if (typeof(arity.first) === 'number') {
if (arity.first === n) { return true; }
} else if (isArityAtLeast(arity)) {
@ -45,7 +48,7 @@
}
return false;
}
}
};
@ -59,4 +62,4 @@
exports.isArityMatching = isArityMatching;
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
(function(baselib) {
'use strict';
var exports = {};
baselib.boxes = exports;
@ -25,30 +29,30 @@
Box.prototype.toString = function(cache) {
cache.put(this, true);
return "#&" + plt.baselib.format.toWrittenString(this.val, cache);
return "#&" + baselib.format.toWrittenString(this.val, cache);
};
Box.prototype.toWrittenString = function(cache) {
cache.put(this, true);
return "#&" + plt.baselib.format.toWrittenString(this.val, cache);
return "#&" + baselib.format.toWrittenString(this.val, cache);
};
Box.prototype.toDisplayedString = function(cache) {
cache.put(this, true);
return "#&" + plt.baselib.format.toDisplayedString(this.val, cache);
return "#&" + baselib.format.toDisplayedString(this.val, cache);
};
Box.prototype.toDomNode = function(cache) {
cache.put(this, true);
var parent = document.createElement("span");
parent.appendChild(document.createTextNode('#&'));
parent.appendChild(plt.baselib.format.toDomNode(this.val, cache));
parent.appendChild(baselib.format.toDomNode(this.val, cache));
return parent;
};
Box.prototype.equals = function(other, aUnionFind) {
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) {
@ -83,4 +87,4 @@
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) {
'use strict';
var exports = {};
baselib.bytes = exports;
@ -30,7 +34,7 @@
};
Bytes.prototype.subbytes = function(start, end) {
if (end == null || end == undefined) {
if (end === null || end === undefined) {
end = this.bytes.length;
}
@ -42,23 +46,25 @@
if (! (other instanceof Bytes)) {
return false;
}
if (this.bytes.length != other.bytes.length) {
if (this.bytes.length !== other.bytes.length) {
return false;
}
var A = this.bytes;
var B = other.bytes;
var n = this.bytes.length;
for (var i = 0; i < n; i++) {
if (A[i] !== B[i])
var i;
for (i = 0; i < n; i++) {
if (A[i] !== B[i]) {
return false;
}
}
return true;
};
Bytes.prototype.toString = function(cache) {
var ret = '';
for (var i = 0; i < this.bytes.length; i++) {
var ret = '', i;
for (i = 0; i < this.bytes.length; i++) {
ret += String.fromCharCode(this.bytes[i]);
}
@ -67,15 +73,6 @@
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 ret = [];
var returnVal;
@ -100,8 +97,18 @@
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;
})(this['plt'].baselib);
}(this.plt.baselib));

View File

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

View File

@ -1,18 +1,45 @@
/*jslint vars: true, white: true, plusplus: true, maxerr: 50, indent: 4 */
// Helper functions for argument checking.
(function(baselib) {
(function (baselib) {
'use strict';
var exports = {};
baselib.check = exports;
var EMPTY = plt.baselib.lists.EMPTY;
var isPair = plt.baselib.lists.isPair;
var makeLowLevelEqHash = plt.baselib.hashes.makeLowLevelEqHash;
var EMPTY = baselib.lists.EMPTY;
var isPair = baselib.lists.isPair;
var makeLowLevelEqHash = baselib.hashes.makeLowLevelEqHash;
//////////////////////////////////////////////////////////////////////
var makeCheckArgumentType = function(predicate, predicateName) {
return function(MACHINE, callerName, position) {
// 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 {
if (typeof(expectedTypeName) === 'function') {
expectedTypeName = expectedTypeName();
}
baselib.exceptions.raiseArgumentTypeError(MACHINE,
callerName,
expectedTypeName,
index,
val);
}
};
var makeCheckArgumentType = function (predicate, predicateName) {
return function (MACHINE, callerName, position) {
testArgument(
MACHINE,
predicateName,
@ -21,35 +48,35 @@
position,
callerName);
return MACHINE.env[MACHINE.env.length - 1 - position];
}
};
};
var makeCheckParameterizedArgumentType = function(parameterizedPredicate,
var makeCheckParameterizedArgumentType = function (parameterizedPredicate,
parameterizedPredicateName) {
return function(MACHINE, callerName, position) {
var args = [];
for (var i = 3; i < arguments.length; i++) {
return function (MACHINE, callerName, position) {
var args = [], i;
for (i = 3; i < arguments.length; i++) {
args.push(arguments[i]);
}
testArgument(
MACHINE,
parameterizedPredicateName.apply(null, args),
function(x) {
function () { parameterizedPredicateName.apply(null, args); },
function (x) {
return parameterizedPredicate.apply(null, [x].concat(args));
},
MACHINE.env[MACHINE.env.length - 1 - position],
position,
callerName);
return MACHINE.env[MACHINE.env.length - 1 - position];
}
};
};
var makeCheckListofArgumentType = function(predicate, predicateName) {
var listPredicate = function(x) {
var makeCheckListofArgumentType = function (predicate, predicateName) {
var listPredicate = function (x) {
var seen = makeLowLevelEqHash();
while (true) {
if (x === EMPTY){
@ -62,7 +89,7 @@
if(seen.containsKey(x)) {
// raise an error? we've got a cycle!
return false
return false;
}
if (! predicate(x.first)) {
@ -73,7 +100,7 @@
x = x.rest;
}
};
return function(MACHINE, callerName, position) {
return function (MACHINE, callerName, position) {
testArgument(
MACHINE,
'list of ' + predicateName,
@ -82,7 +109,7 @@
position,
callerName);
return MACHINE.env[MACHINE.env.length - 1 - position];
}
};
};
@ -90,28 +117,10 @@
// 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) {
plt.baselib.exceptions.raise(
baselib.exceptions.raise(
MACHINE, new Error(callerName + ": expected at least " + minimum
+ " arguments "
+ " but received " + observed));
@ -123,99 +132,96 @@
var checkOutputPort = makeCheckArgumentType(
plt.baselib.ports.isOutputPort,
baselib.ports.isOutputPort,
'output port');
var checkSymbol = makeCheckArgumentType(
plt.baselib.symbols.isSymbol,
baselib.symbols.isSymbol,
'symbol');
var checkString = makeCheckArgumentType(
plt.baselib.strings.isString,
baselib.strings.isString,
'string');
var checkMutableString = makeCheckArgumentType(
plt.baselib.strings.isMutableString,
baselib.strings.isMutableString,
'mutable string');
var checkChar = makeCheckArgumentType(
plt.baselib.chars.isChar,
baselib.chars.isChar,
'character');
var checkProcedure = makeCheckArgumentType(
plt.baselib.functions.isProcedure,
baselib.functions.isProcedure,
'procedure');
var checkNumber = makeCheckArgumentType(
plt.baselib.numbers.isNumber,
baselib.numbers.isNumber,
'number');
var checkReal = makeCheckArgumentType(
plt.baselib.numbers.isReal,
baselib.numbers.isReal,
'real');
var checkNatural = makeCheckArgumentType(
plt.baselib.numbers.isNatural,
baselib.numbers.isNatural,
'natural');
var checkByte = makeCheckArgumentType(
function(x) { return (typeof(x) === 'number' && 0 <= x && x < 256) },
baselib.numbers.isByte,
'byte');
var checkNaturalInRange = makeCheckParameterizedArgumentType(
function(x, a, b) {
if (! plt.baselib.numbers.isNatural(x)) { return false; }
return (plt.baselib.numbers.lessThanOrEqual(a, x) &&
plt.baselib.numbers.lessThan(x, b));
function (x, a, b) {
if (! baselib.numbers.isNatural(x)) { return false; }
return (baselib.numbers.lessThanOrEqual(a, x) &&
baselib.numbers.lessThan(x, b));
},
function(a, b) {
return plt.baselib.format.format('natural between ~a and ~a', [a, b]);
function (a, b) {
return baselib.format.format('natural between ~a and ~a', [a, b]);
});
var checkInteger = makeCheckArgumentType(
plt.baselib.numbers.isInteger,
baselib.numbers.isInteger,
'integer');
var checkRational = makeCheckArgumentType(
plt.baselib.numbers.isRational,
baselib.numbers.isRational,
'rational');
var checkNonNegativeReal = makeCheckArgumentType(
plt.baselib.numbers.isNonNegativeReal,
baselib.numbers.isNonNegativeReal,
'non-negative real');
var checkPair = makeCheckArgumentType(
plt.baselib.lists.isPair,
baselib.lists.isPair,
'pair');
var checkList = makeCheckArgumentType(
plt.baselib.lists.isList,
baselib.lists.isList,
'list');
var checkVector = makeCheckArgumentType(
plt.baselib.vectors.isVector,
baselib.vectors.isVector,
'vector');
var checkBoolean = makeCheckArgumentType(
function(x) { return x === true || x === false; },
function (x) { return x === true || x === false; },
'boolean');
var checkBox = makeCheckArgumentType(
plt.baselib.boxes.isBox,
baselib.boxes.isBox,
'box');
var checkMutableBox = makeCheckArgumentType(
plt.baselib.boxes.isMutableBox,
baselib.boxes.isMutableBox,
'mutable box');
var checkInspector = makeCheckArgumentType(
plt.baselib.inspectors.isInspector,
baselib.inspectors.isInspector,
'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
(function(baselib) {
(function (baselib) {
'use strict';
var exports = {};
baselib.constants = exports;
var VoidValue = function() {};
VoidValue.prototype.toString = function() {
var VoidValue = function () {};
VoidValue.prototype.toString = function () {
return "#<void>";
};
var VOID_VALUE = new VoidValue();
var EofValue = function() {};
EofValue.prototype.toString = function() {
var EofValue = function () {};
EofValue.prototype.toString = function () {
return "#<eof>";
}
};
var EOF_VALUE = new EofValue();
exports.VOID_VALUE = VOID_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
(function(baselib) {
'use strict';
var exports = {};
baselib.contmarks = exports;
var ContinuationMarkSet = function(dict) {
this.dict = dict;
}
};
ContinuationMarkSet.prototype.toDomNode = function(cache) {
var dom = document.createElement("span");
@ -29,7 +32,20 @@
return [];
};
// A continuation prompt tag labels a prompt frame.
var ContinuationPromptTag = function(name) {
this.name = name;
};
exports.ContinuationMarkSet = ContinuationMarkSet;
exports.ContinuationPromptTag = ContinuationPromptTag;
})(this['plt'].baselib);
}(this.plt.baselib));

View File

@ -1,16 +1,21 @@
/*jslint vars: true, white: true, maxerr: 50, indent: 4 */
// Equality function
(function(baselib) {
/*global jsnums*/
(function (baselib, jsnums) {
'use strict';
var exports = {};
baselib.equality = exports;
var eqv = function(x, y) {
var eqv = function (x, y) {
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);
} 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;
} else {
return false;
@ -22,28 +27,25 @@
// equals: X Y -> boolean
// 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 (plt.baselib.numbers.isNumber(x) && plt.baselib.numbers.isNumber(y)) {
return plt.baselib.numbers.eqv(x, y);
if (baselib.numbers.isNumber(x) && baselib.numbers.isNumber(y)) {
return baselib.numbers.eqv(x, y);
}
if (baselib.strings.isString(x) && baselib.strings.isString(y)) {
return x.toString() === y.toString();
}
if (x == undefined || x == null) {
return (y == undefined || y == null);
if (x === undefined || x === null) {
return (y === undefined || y === null);
}
if ( typeof(x) == 'object' &&
typeof(y) == 'object' &&
x.equals &&
y.equals) {
if (typeof (x) === 'object' && typeof (y) === 'object' &&
x.equals && y.equals) {
if (typeof (aUnionFind) === 'undefined') {
aUnionFind = new plt.baselib.UnionFind();
aUnionFind = new baselib.UnionFind();
}
if (aUnionFind.find(x) === aUnionFind.find(y)) {
@ -57,7 +59,7 @@
return false;
};
exports.eqv = eqv;
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
(function(baselib) {
'use strict';
var exceptions = {};
baselib.exceptions = exceptions;
@ -9,13 +12,13 @@
// Error type exports
var InternalError = function(val, contMarks) {
this.val = val;
this.contMarks = (contMarks ? contMarks : false);
}
this.contMarks = contMarks || false;
};
var SchemeError = function(val) {
this.val = val;
}
};
var IncompleteExn = function(constructor, msg, otherArgs) {
@ -26,35 +29,35 @@
// (define-struct exn (message continuation-mark-set))
var Exn = plt.baselib.structs.makeStructureType(
var Exn = baselib.structs.makeStructureType(
'exn', false, 2, 0, false, false);
// (define-struct (exn:break exn) (continuation))
var ExnBreak = plt.baselib.structs.makeStructureType(
var ExnBreak = baselib.structs.makeStructureType(
'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);
var ExnFailContract = plt.baselib.structs.makeStructureType(
var ExnFailContract = baselib.structs.makeStructureType(
'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);
var ExnFailContractVariable = plt.baselib.structs.makeStructureType(
var ExnFailContractVariable = baselib.structs.makeStructureType(
'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);
var exceptionHandlerKey = new plt.baselib.symbols.Symbol("exnh");
var exceptionHandlerKey = new baselib.symbols.Symbol("exnh");
@ -72,11 +75,11 @@
e.message = Exn.accessor(e, 0);
}
if (typeof(window['console']) !== 'undefined' &&
typeof(console['log']) === 'function') {
console.log(MACHINE);
if (e['stack']) { console.log(e['stack']); }
else { console.log(e); }
if (typeof(window.console) !== 'undefined' &&
typeof(window.console['log']) === 'function') {
window.console.log(MACHINE);
if (e['stack']) { window.console.log(e['stack']); }
else { window.console.log(e); }
}
throw e;
};
@ -87,7 +90,7 @@
var raiseUnboundToplevelError = function(MACHINE, name) {
raise(MACHINE,
new Error(
plt.baselib.format.format(
baselib.format.format(
"Not bound: ~a",
[name])));
};
@ -101,7 +104,7 @@
if (argumentOffset !== undefined) {
raise(MACHINE,
new Error(
plt.baselib.format.format(
baselib.format.format(
"~a: expected ~a as argument ~e but received ~e",
[callerName,
expectedTypeName,
@ -110,7 +113,7 @@
} else {
raise(MACHINE,
new Error(
plt.baselib.format.format(
baselib.format.format(
"~a: expected ~a but received ~e",
[callerName,
expectedTypeName,
@ -120,25 +123,24 @@
var raiseContextExpectedValuesError = function(MACHINE, expected) {
raise(MACHINE,
new Error(plt.baselib.format.format(
"expected ~e values, received ~e values"
[expected,
MACHINE.argcount])));
new Error(baselib.format.format(
"expected ~e values, received ~e values",
[expected, MACHINE.argcount])));
};
var raiseArityMismatchError = function(MACHINE, proc, expected, received) {
raise(MACHINE,
new Error(plt.baselib.format.format(
new Error(baselib.format.format(
"~a: expected ~e value(s), received ~e value(s)",
[proc.displayName,
expected ,
received])))
expected,
received])));
};
var raiseOperatorApplicationError = function(MACHINE, operator) {
raise(MACHINE,
new Error(
plt.baselib.format.format(
baselib.format.format(
"not a procedure: ~e",
[operator])));
};
@ -146,7 +148,7 @@
var raiseOperatorIsNotClosure = function(MACHINE, operator) {
raise(MACHINE,
new Error(
plt.baselib.format.format(
baselib.format.format(
"not a closure: ~e",
[operator])));
};
@ -154,7 +156,7 @@
var raiseOperatorIsNotPrimitiveProcedure = function(MACHINE, operator) {
raise(MACHINE,
new Error(
plt.baselib.format.format(
baselib.format.format(
"not a primitive procedure: ~e",
[operator])));
};
@ -162,7 +164,7 @@
var raiseUnimplementedPrimitiveError = function(MACHINE, name) {
raise(MACHINE,
new Error("unimplemented kernel procedure: " + name))
new Error("unimplemented kernel procedure: " + name));
};
@ -245,4 +247,4 @@
exceptions.raiseUnimplementedPrimitiveError = raiseUnimplementedPrimitiveError;
})(this['plt'].baselib);
}(this.plt.baselib));

View File

@ -1,11 +1,130 @@
/*jslint browser: true, undef: false, unparam: true, sub: true, vars: true, white: true, plusplus: true, maxerr: 50, indent: 4 */
// Formatting library.
// Produces string and DOM representations of values.
//
(function(baselib) {
/*global $*/
(function(baselib, $) {
'use strict';
var exports = {};
baselib.format = exports;
var replaceUnprintableStringChars = function(s) {
var ret = [], i;
for (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('');
};
var escapeString = function(s) {
return '"' + replaceUnprintableStringChars(s) + '"';
};
// toWrittenString: Any Hashtable -> String
var toWrittenString = function(x, cache) {
if (! cache) {
cache = baselib.hashes.makeLowLevelEqHash();
}
if (x === null) {
return "null";
}
if (x === true) { return "true"; }
if (x === false) { return "false"; }
if (typeof(x) === 'object') {
if (cache.containsKey(x)) {
return "...";
}
}
if (x === undefined) {
return "#<undefined>";
}
if (typeof(x) === 'string') {
return escapeString(x.toString());
}
if (typeof(x) !== 'object' && typeof(x) !== 'function') {
return x.toString();
}
var returnVal;
if (typeof(x.toWrittenString) !== 'undefined') {
returnVal = x.toWrittenString(cache);
} else if (typeof(x.toDisplayedString) !== 'undefined') {
returnVal = x.toDisplayedString(cache);
} else {
returnVal = x.toString();
}
cache.remove(x);
return returnVal;
};
// toDisplayedString: Any Hashtable -> String
var toDisplayedString = function(x, cache) {
if (! cache) {
cache = baselib.hashes.makeLowLevelEqHash();
}
if (x === null) {
return "null";
}
if (x === true) { return "true"; }
if (x === false) { return "false"; }
if (typeof(x) === 'object') {
if (cache.containsKey(x)) {
return "...";
}
}
if (x === undefined || x === null) {
return "#<undefined>";
}
if (typeof(x) === 'string') {
return x;
}
if (typeof(x) !== 'object' && typeof(x) !== 'function') {
return x.toString();
}
var returnVal;
if (typeof(x.toDisplayedString) !== 'undefined') {
returnVal = x.toDisplayedString(cache);
} else if (typeof(x.toWrittenString) !== 'undefined') {
returnVal = x.toWrittenString(cache);
} else {
returnVal = x.toString();
}
cache.remove(x);
return returnVal;
};
var formatRegexp1 = new RegExp('~[sSaA]', 'g');
var formatRegexp2 = new RegExp("~[sSaAnevE%~]", "g");
// format: string [X ...] string -> string
// String formatting. If an exception occurs, throws
@ -13,19 +132,20 @@
var format = function(formatStr, args, functionName) {
var throwFormatError = function() {
functionName = functionName || 'format';
var matches = formatStr.match(new RegExp('~[sSaA]', 'g'));
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)];
for (var i = 0; i < args.length; i++) {
var i;
for (i = 0; i < args.length; i++) {
errorStrBuffer.push( toWrittenString(args[i]) );
}
throw new Error(errorStrBuffer.join(' '));
}
};
var pattern = new RegExp("~[sSaAnevE%~]", "g");
var buffer = args.slice(0);
var onTemplate = function(s) {
if (s === "~~") {
@ -61,8 +181,8 @@
throw new Error(functionName +
': string.replace matched invalid regexp');
}
}
var result = formatStr.replace(pattern, onTemplate);
};
var result = formatStr.replace(formatRegexp2, onTemplate);
if (buffer.length > 0) {
throwFormatError();
}
@ -70,91 +190,13 @@
};
// toWrittenString: Any Hashtable -> String
var toWrittenString = function(x, cache) {
if (! cache) {
cache = plt.baselib.hashes.makeLowLevelEqHash();
}
if (x === null) {
return "null";
}
if (x === true) { return "true"; }
if (x === false) { return "false"; }
if (typeof(x) === 'object') {
if (cache.containsKey(x)) {
return "...";
}
}
if (x == undefined) {
return "#<undefined>";
}
if (typeof(x) == 'string') {
return escapeString(x.toString());
}
if (typeof(x) != 'object' && typeof(x) != 'function') {
return x.toString();
}
var returnVal;
if (typeof(x.toWrittenString) !== 'undefined') {
returnVal = x.toWrittenString(cache);
} else if (typeof(x.toDisplayedString) !== 'undefined') {
returnVal = x.toDisplayedString(cache);
} else {
returnVal = x.toString();
}
cache.remove(x);
return returnVal;
};
// toDisplayedString: Any Hashtable -> String
var toDisplayedString = function(x, cache) {
if (! cache) {
cache = plt.baselib.hashes.makeLowLevelEqHash();
}
if (x === null) {
return "null";
}
if (x === true) { return "true"; }
if (x === false) { return "false"; }
if (typeof(x) === 'object') {
if (cache.containsKey(x)) {
return "...";
}
}
if (x == undefined || x == null) {
return "#<undefined>";
}
if (typeof(x) == 'string') {
return x;
}
if (typeof(x) != 'object' && typeof(x) != 'function') {
return x.toString();
}
var returnVal;
if (typeof(x.toDisplayedString) !== 'undefined') {
returnVal = x.toDisplayedString(cache);
} else if (typeof(x.toWrittenString) !== 'undefined') {
returnVal = x.toWrittenString(cache);
} else {
returnVal = x.toString();
}
cache.remove(x);
return returnVal;
};
var ToDomNodeParameters = function(params) {
if (! params) { params = {}; }
this.cache = plt.baselib.hashes.makeLowLevelEqHash();
for (var k in params) {
this.cache = baselib.hashes.makeLowLevelEqHash();
var k;
for (k in params) {
if (params.hasOwnProperty(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
var rationalToDomNode = function(n) {
var repeatingDecimalNode = document.createElement("span");
var chunks = plt.baselib.numbers.toRepeatingDecimal(plt.baselib.numbers.numerator(n),
plt.baselib.numbers.denominator(n),
var chunks = baselib.numbers.toRepeatingDecimal(baselib.numbers.numerator(n),
baselib.numbers.denominator(n),
{limit: 25});
repeatingDecimalNode.appendChild(document.createTextNode(chunks[0] + '.'))
repeatingDecimalNode.appendChild(document.createTextNode(chunks[0] + '.'));
repeatingDecimalNode.appendChild(document.createTextNode(chunks[1]));
if (chunks[2] === '...') {
repeatingDecimalNode.appendChild(
@ -335,9 +252,9 @@
var fractionalNode = document.createElement("span");
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");
denominatorNode.appendChild(document.createTextNode(String(plt.baselib.numbers.denominator(n))));
denominatorNode.appendChild(document.createTextNode(String(baselib.numbers.denominator(n))));
fractionalNode.appendChild(numeratorNode);
fractionalNode.appendChild(document.createTextNode("/"));
fractionalNode.appendChild(denominatorNode);
@ -353,59 +270,139 @@
numberNode.onclick = function(e) {
showingRepeating = !showingRepeating;
repeatingDecimalNode.style['display'] =
(showingRepeating ? 'inline' : 'none')
(showingRepeating ? 'inline' : 'none');
fractionalNode.style['display'] =
(!showingRepeating ? 'inline' : 'none')
(!showingRepeating ? 'inline' : 'none');
};
numberNode.style['cursor'] = 'pointer';
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.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.
(function(baselib) {
'use strict';
var 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
// For historical reasons, this module is called 'functions' instead of 'procedures'.
// This may change soon.
(function(baselib) {
/*global plt*/
(function (baselib, plt) {
'use strict';
var exports = {};
baselib.functions = exports;
@ -16,195 +21,8 @@
// 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)));
}
var isPrimitiveProcedure = function (x) {
return typeof (x) === 'function';
};
@ -221,7 +39,7 @@
// A closure consists of its free variables as well as a label
// into its text segment.
var Closure = function(label, arity, closedVals, displayName) {
var Closure = function (label, arity, closedVals, displayName) {
this.label = label; // (MACHINE -> void)
this.racketArity = arity; // number
this.closedVals = closedVals; // arrayof number
@ -229,7 +47,6 @@
};
// Finalize the return from a closure. This is a helper function
// for those who implement Closures by hand.
//
@ -243,33 +60,237 @@
//
// I'd personally love for this to be a macro and avoid the
// extra function call here.
var finalizeClosureCall = function(MACHINE) {
var finalizeClosureCall = function (MACHINE) {
MACHINE.callsBeforeTrampoline--;
var frame, i, returnArgs = [].slice.call(arguments, 1);
var i, returnArgs = [].slice.call(arguments, 1);
// clear out stack space
// TODO: replace with a splice.
for(i = 0; i < MACHINE.argcount; i++) {
MACHINE.env.pop();
}
MACHINE.env.length = MACHINE.env.length - MACHINE.argcount;
if (returnArgs.length === 1) {
MACHINE.val = returnArgs[0];
frame = MACHINE.control.pop();
return frame.label(MACHINE);
return MACHINE.control.pop().label(MACHINE);
} else if (returnArgs.length === 0) {
MACHINE.argcount = 0;
frame = MACHINE.control.pop();
return frame.label.multipleValueReturn(MACHINE);
return MACHINE.control.pop().label.multipleValueReturn(MACHINE);
} else {
MACHINE.argcount = returnArgs.length;
MACHINE.val = returnArgs.shift();
// 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());
}
frame = MACHINE.control.pop();
return frame.label.multipleValueReturn(MACHINE);
return MACHINE.control.pop().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.displayName = name;
return f;
};
var makeClosure = function(name, arity, f, closureArgs) {
var makeClosure = function (name, arity, f, closureArgs) {
if (! closureArgs) { closureArgs = []; }
return new Closure(f,
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)) {
return makePrimitiveProcedure(
name,
f.racketArity,
function() {
function () {
return f.apply(null, arguments);
});
} else {
@ -351,4 +364,4 @@
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 = {};
baselib.hashes = exports;
@ -7,7 +12,7 @@
var _eqHashCodeCounter = 0;
var makeEqHashCode = function() {
var makeEqHashCode = function () {
_eqHashCodeCounter++;
return _eqHashCodeCounter;
};
@ -15,11 +20,11 @@
// getHashCode: any -> (or fixnum string)
// Given a value, produces a hashcode appropriate for eq.
var getEqHashCode = function(x) {
if (typeof(x) === 'string') {
var getEqHashCode = function (x) {
if (typeof (x) === 'string') {
return x;
}
if (typeof(x) === 'number') {
if (typeof (x) === 'number') {
return String(x);
}
if (x && !x._eqHashCode) {
@ -36,9 +41,9 @@
// http://www.timdown.co.uk/jshashtable/
//
// Defined to use the getEqHashCode defined in baselib_hash.js.
var makeLowLevelEqHash = function() {
return new Hashtable(function(x) { return getEqHashCode(x); },
function(x, y) { return x === y; });
var makeLowLevelEqHash = function () {
return new Hashtable(function (x) { return getEqHashCode(x); },
function (x, y) { return x === y; });
};
@ -52,49 +57,49 @@
//////////////////////////////////////////////////////////////////////
// Eq Hashtables
var EqHashTable = function(inputHash) {
var EqHashTable = function (inputHash) {
this.hash = makeLowLevelEqHash();
this.mutable = true;
};
EqHashTable.prototype.toWrittenString = function(cache) {
EqHashTable.prototype.toWrittenString = function (cache) {
var keys = this.hash.keys();
var ret = [];
for (var i = 0; i < keys.length; i++) {
var keyStr = toWrittenString(keys[i], cache);
var valStr = toWrittenString(this.hash.get(keys[i]), cache);
var ret = [], i;
for (i = 0; i < keys.length; i++) {
var keyStr = baselib.format.toWrittenString(keys[i], cache);
var valStr = baselib.format.toWrittenString(this.hash.get(keys[i]), cache);
ret.push('(' + keyStr + ' . ' + valStr + ')');
}
return ('#hasheq(' + ret.join(' ') + ')');
};
EqHashTable.prototype.toDisplayedString = function(cache) {
EqHashTable.prototype.toDisplayedString = function (cache) {
var keys = this.hash.keys();
var ret = [];
for (var i = 0; i < keys.length; i++) {
var keyStr = toDisplayedString(keys[i], cache);
var valStr = toDisplayedString(this.hash.get(keys[i]), cache);
var ret = [], i;
for (i = 0; i < keys.length; i++) {
var keyStr = baselib.format.toDisplayedString(keys[i], cache);
var valStr = baselib.format.toDisplayedString(this.hash.get(keys[i]), cache);
ret.push('(' + keyStr + ' . ' + valStr + ')');
}
return ('#hasheq(' + ret.join(' ') + ')');
};
EqHashTable.prototype.equals = function(other, aUnionFind) {
if ( !(other instanceof EqHashTable) ) {
EqHashTable.prototype.equals = function (other, aUnionFind) {
if (!(other instanceof EqHashTable)) {
return false;
}
if (this.hash.keys().length != other.hash.keys().length) {
if (this.hash.keys().length !== other.hash.keys().length) {
return false;
}
var keys = this.hash.keys();
for (var i = 0; i < keys.length; i++){
if ( !(other.hash.containsKey(keys[i]) &&
plt.baselib.equality.equals(this.hash.get(keys[i]),
var keys = this.hash.keys(), i;
for (i = 0; i < keys.length; i++) {
if (!(other.hash.containsKey(keys[i]) &&
baselib.equality.equals(this.hash.get(keys[i]),
other.hash.get(keys[i]),
aUnionFind)) ) {
aUnionFind))) {
return false;
}
}
@ -105,51 +110,51 @@
//////////////////////////////////////////////////////////////////////
// Equal hash tables
var EqualHashTable = function(inputHash) {
this.hash = new _Hashtable(
function(x) {
return plt.baselib.format.toWrittenString(x);
var EqualHashTable = function (inputHash) {
this.hash = new Hashtable(
function (x) {
return baselib.format.toWrittenString(x);
},
function(x, y) {
return plt.baselib.equality.equals(x, y, new plt.baselib.UnionFind());
function (x, y) {
return baselib.equality.equals(x, y, new baselib.UnionFind());
});
this.mutable = true;
};
EqualHashTable.prototype.toWrittenString = function(cache) {
EqualHashTable.prototype.toWrittenString = function (cache) {
var keys = this.hash.keys();
var ret = [];
for (var i = 0; i < keys.length; i++) {
var keyStr = plt.baselib.format.toWrittenString(keys[i], cache);
var valStr = plt.baselib.format.toWrittenString(this.hash.get(keys[i]), cache);
var ret = [], i;
for (i = 0; i < keys.length; i++) {
var keyStr = baselib.format.toWrittenString(keys[i], cache);
var valStr = baselib.format.toWrittenString(this.hash.get(keys[i]), cache);
ret.push('(' + keyStr + ' . ' + valStr + ')');
}
return ('#hash(' + ret.join(' ') + ')');
};
EqualHashTable.prototype.toDisplayedString = function(cache) {
EqualHashTable.prototype.toDisplayedString = function (cache) {
var keys = this.hash.keys();
var ret = [];
for (var i = 0; i < keys.length; i++) {
var keyStr = plt.baselib.format.toDisplayedString(keys[i], cache);
var valStr = plt.baselib.format.toDisplayedString(this.hash.get(keys[i]), cache);
var ret = [], i;
for (i = 0; i < keys.length; i++) {
var keyStr = baselib.format.toDisplayedString(keys[i], cache);
var valStr = baselib.format.toDisplayedString(this.hash.get(keys[i]), cache);
ret.push('(' + keyStr + ' . ' + valStr + ')');
}
return ('#hash(' + ret.join(' ') + ')');
};
EqualHashTable.prototype.equals = function(other, aUnionFind) {
EqualHashTable.prototype.equals = function (other, aUnionFind) {
if ( !(other instanceof EqualHashTable) ) {
return false;
}
if (this.hash.keys().length != other.hash.keys().length) {
if (this.hash.keys().length !== other.hash.keys().length) {
return false;
}
var keys = this.hash.keys();
for (var i = 0; i < keys.length; i++){
var keys = this.hash.keys(), i;
for (i = 0; i < keys.length; 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]),
aUnionFind))) {
return false;
@ -161,27 +166,12 @@
var isHash = function(x) {
var isHash = function (x) {
return (x instanceof EqHashTable ||
x instanceof EqualHashTable);
};
//////////////////////////////////////////////////////////////////////
exports.getEqHashCode = getEqHashCode;
@ -194,4 +184,4 @@
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
(function(baselib) {
(function (baselib) {
'use strict';
var exports = {};
baselib.inspectors = exports;
var Inspector = function() {
var Inspector = function () {
};
var DEFAULT_INSPECTOR = new Inspector();
Inspector.prototype.toString = function() {
Inspector.prototype.toString = function () {
return "#<inspector>";
};
@ -23,4 +26,4 @@
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
(function(baselib) {
(function (baselib) {
'use strict';
var exports = {};
baselib.keywords = exports;
var Keyword = function(val) {
var Keyword = function (val) {
this.val = val;
};
var keywordCache = {};
// makeInstance: string -> Keyword.
Keyword.makeInstance = function(val) {
Keyword.makeInstance = function (val) {
// To ensure that we can eq? symbols with equal values.
if (!(val in keywordCache)) {
if (!(keywordCache.hasOwnProperty(val))) {
keywordCache[val] = new Keyword(val);
} else {
}
return keywordCache[val];
};
Keyword.prototype.equals = function(other, aUnionFind) {
Keyword.prototype.equals = function (other, aUnionFind) {
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;
};
Keyword.prototype.toWrittenString = function(cache) {
Keyword.prototype.toWrittenString = function (cache) {
return this.val;
};
Keyword.prototype.toDisplayedString = function(cache) {
Keyword.prototype.toDisplayedString = function (cache) {
return this.val;
};
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)
(function(baselib) {
(function (baselib) {
'use strict';
var exports = {};
baselib.lists = exports;
@ -7,28 +11,28 @@
Empty = function() {
var Empty = function () {
};
Empty.EMPTY = new Empty();
var EMPTY = Empty.EMPTY;
Empty.prototype.equals = function(other, aUnionFind) {
Empty.prototype.equals = function (other, aUnionFind) {
return other instanceof Empty;
};
Empty.prototype.reverse = function() {
Empty.prototype.reverse = function () {
return this;
};
Empty.prototype.toWrittenString = function(cache) { return "empty"; };
Empty.prototype.toDisplayedString = function(cache) { return "empty"; };
Empty.prototype.toString = function(cache) { return "()"; };
Empty.prototype.toWrittenString = function (cache) { return "empty"; };
Empty.prototype.toDisplayedString = function (cache) { return "empty"; };
Empty.prototype.toString = function (cache) { return "()"; };
// Empty.append: (listof X) -> (listof X)
Empty.prototype.append = function(b){
Empty.prototype.append = function (b) {
return b;
};
@ -39,12 +43,12 @@
// Cons Pairs
var Cons = function(first, rest) {
var Cons = function (first, rest) {
this.first = first;
this.rest = rest;
};
Cons.prototype.reverse = function() {
Cons.prototype.reverse = function () {
var lst = this;
var ret = EMPTY;
while (lst !== EMPTY) {
@ -54,26 +58,27 @@
return ret;
};
Cons.makeInstance = function(first, rest) {
Cons.makeInstance = function (first, rest) {
return new Cons(first, rest);
};
// FIXME: can we reduce the recursion on this?
Cons.prototype.equals = function(other, aUnionFind) {
if (! (other instanceof Cons)) {
Cons.prototype.equals = function (other, aUnionFind) {
if (!(other instanceof Cons)) {
return false;
}
return (plt.baselib.equality.equals(this.first, other.first, aUnionFind) &&
plt.baselib.equality.equals(this.rest, other.rest, aUnionFind));
return (baselib.equality.equals(this.first, other.first, aUnionFind) &&
baselib.equality.equals(this.rest, other.rest, aUnionFind));
};
// Cons.append: (listof X) -> (listof X)
Cons.prototype.append = function(b){
if (b === EMPTY)
Cons.prototype.append = function (b) {
if (b === EMPTY) {
return this;
}
var ret = b;
var lst = this.reverse();
while (lst !== EMPTY) {
@ -85,65 +90,65 @@
};
Cons.prototype.toWrittenString = function(cache) {
Cons.prototype.toWrittenString = function (cache) {
cache.put(this, true);
var texts = [];
var p = this;
while ( p instanceof Cons ) {
texts.push(plt.baselib.format.toWrittenString(p.first, cache));
while (p instanceof Cons) {
texts.push(baselib.format.toWrittenString(p.first, cache));
p = p.rest;
if (typeof(p) === 'object' && cache.containsKey(p)) {
if (typeof (p) === 'object' && cache.containsKey(p)) {
break;
}
}
if ( p !== EMPTY ) {
if (p !== EMPTY) {
texts.push('.');
texts.push(plt.baselib.format.toWrittenString(p, cache));
texts.push(baselib.format.toWrittenString(p, cache));
}
return "(" + texts.join(" ") + ")";
};
Cons.prototype.toString = Cons.prototype.toWrittenString;
Cons.prototype.toDisplayedString = function(cache) {
Cons.prototype.toDisplayedString = function (cache) {
cache.put(this, true);
var texts = [];
var p = this;
while ( p instanceof Cons ) {
texts.push(plt.baselib.format.toDisplayedString(p.first, cache));
while (p instanceof Cons) {
texts.push(baselib.format.toDisplayedString(p.first, cache));
p = p.rest;
if (typeof(p) === 'object' && cache.containsKey(p)) {
if (typeof (p) === 'object' && cache.containsKey(p)) {
break;
}
}
if ( p !== Empty.EMPTY ) {
if (p !== Empty.EMPTY) {
texts.push('.');
texts.push(plt.baselib.format.toDisplayedString(p, cache));
texts.push(baselib.format.toDisplayedString(p, cache));
}
return "(" + texts.join(" ") + ")";
};
Cons.prototype.toDomNode = function(cache) {
Cons.prototype.toDomNode = function (cache) {
cache.put(this, true);
var node = document.createElement("span");
node.appendChild(document.createTextNode("("));
var p = this;
while ( p instanceof Cons ) {
node.appendChild(plt.baselib.format.toDomNode(p.first, cache));
while (p instanceof Cons) {
node.appendChild(baselib.format.toDomNode(p.first, cache));
p = p.rest;
if ( p !== Empty.EMPTY ) {
if (p !== Empty.EMPTY) {
node.appendChild(document.createTextNode(" "));
}
if (typeof(p) === 'object' && cache.containsKey(p)) {
if (typeof (p) === 'object' && cache.containsKey(p)) {
break;
}
}
if ( p !== Empty.EMPTY ) {
if (p !== Empty.EMPTY) {
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(")"));
@ -151,15 +156,15 @@
};
var isPair = function(x) { return x instanceof Cons; };
var isEmpty = function(x) { return x === Empty.EMPTY; };
var isPair = function (x) { return x instanceof Cons; };
var isEmpty = function (x) { return x === Empty.EMPTY; };
var makePair = Cons.makeInstance;
var makeList = function() {
var result = Empty.EMPTY;
for(var i = arguments.length-1; i >= 0; i--) {
var makeList = function () {
var result = Empty.EMPTY, i;
for (i = arguments.length - 1; i >= 0; i--) {
result = Cons.makeInstance(arguments[i], result);
}
return result;
@ -168,7 +173,7 @@
// isList: Any -> Boolean
// 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) {
if (x instanceof Cons) {
x = x.rest;
@ -181,9 +186,9 @@
var reverse = function(lst) {
var reverse = function (lst) {
var rev = EMPTY;
while(lst !== EMPTY) {
while (lst !== EMPTY) {
rev = makePair(lst.first, rev);
lst = lst.rest;
}
@ -191,7 +196,7 @@
};
var length = function(lst) {
var length = function (lst) {
var len = 0;
while (lst !== EMPTY) {
len++;
@ -201,12 +206,13 @@
};
var listRef = function(lst, n) {
for (var i = 0; i < n; i++) {
var listRef = function (lst, n) {
var i;
for (i = 0; i < n; i++) {
lst = lst.rest;
}
return lst.first;
}
};
@ -225,4 +231,4 @@
exports.listRef = listRef;
})(this['plt'].baselib);
}(this.plt.baselib));

View File

@ -1,9 +1,14 @@
(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 = {};
baselib.modules = exports;
var ModuleRecord = function(name, label) {
var ModuleRecord = function (name, label) {
this.name = name;
this.label = label;
this.isInvoked = false;
@ -16,37 +21,37 @@
};
// Returns access to the names defined in the module.
ModuleRecord.prototype.getNamespace = function() {
ModuleRecord.prototype.getNamespace = function () {
return this.namespace;
};
ModuleRecord.prototype.finalizeModuleInvokation = function() {
ModuleRecord.prototype.finalizeModuleInvokation = function () {
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];
}
};
// 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);
};
// 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);
};
// 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;
MACHINE = MACHINE || plt.runtime.currentMachine;
succ = succ || function(){};
fail = fail || function(){};
succ = succ || function () {};
fail = fail || function () {};
var oldErrorHandler = MACHINE.params['currentErrorHandler'];
var afterGoodInvoke = function(MACHINE) {
var afterGoodInvoke = function (MACHINE) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
succ();
};
@ -54,27 +59,22 @@
if (this.isInvoked) {
succ();
} else {
MACHINE.params['currentErrorHandler'] = function(MACHINE, anError) {
MACHINE.params['currentErrorHandler'] = function (MACHINE, anError) {
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
fail(MACHINE, anError)
fail(MACHINE, anError);
};
MACHINE.control.push(new plt.baselib.frames.CallFrame(afterGoodInvoke, null));
if (isInternal) {
throw that.label;
} else {
plt.runtime.trampoline(MACHINE, that.label);
MACHINE.trampoline(that.label);
}
}
};
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.
(function(baselib) {
/*global jsnums*/
(function (baselib, jsnums) {
'use strict';
var exports = {};
baselib.numbers = exports;
@ -12,27 +16,27 @@
var isInteger = jsnums.isInteger;
var isNatural = function(x) {
var isNatural = function (x) {
return (jsnums.isExact(x) && isInteger(x)
&& jsnums.greaterThanOrEqual(x, 0));
};
var isNonNegativeReal = function(x) {
var isNonNegativeReal = function (x) {
return isReal(x) && jsnums.greaterThanOrEqual(x, 0);
};
var isByte = function(x) {
var isByte = function (x) {
return (isNatural(x) &&
jsnums.lessThan(x, 256));
};
// sign: number -> number
var sign = function(x) {
var sign = function (x) {
if (jsnums.isInexact(x)) {
if (jsnums.greaterThan(x, 0) ) {
if (jsnums.greaterThan(x, 0)) {
return jsnums.makeFloat(1);
} else if (jsnums.lessThan(x, 0) ) {
} else if (jsnums.lessThan(x, 0)) {
return jsnums.makeFloat(-1);
} else {
return jsnums.makeFloat(0);
@ -56,7 +60,8 @@
// We first re-export everything in jsnums.
for (var prop in jsnums) {
var prop;
for (prop in jsnums) {
if (jsnums.hasOwnProperty(prop)) {
exports[prop] = jsnums[prop];
}
@ -74,4 +79,4 @@
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 = {};
baselib.paths = exports;
// Paths
var Path = function(p) {
var Path = function (p) {
this.path = p;
};
Path.prototype.toString = function() {
Path.prototype.toString = function () {
return String(this.path);
};
@ -16,4 +20,4 @@
exports.Path = Path;
})(this['plt'].baselib);
}(this.plt.baselib));

View File

@ -1,49 +1,50 @@
// Placeholders
(function(baselib) {
/*jslint browser: true, unparam: true, vars: true, maxerr: 50, indent: 4 */
(function (baselib) {
'use strict';
var exports = {};
baselib.placeholders = exports;
// 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;
};
Placeholder.prototype.ref = function() {
Placeholder.prototype.ref = function () {
return this.val;
};
Placeholder.prototype.set = function(newVal) {
Placeholder.prototype.set = function (newVal) {
this.val = newVal;
};
Placeholder.prototype.toString = function(cache) {
Placeholder.prototype.toString = function (cache) {
return "#<placeholder>";
};
Placeholder.prototype.toWrittenString = function(cache) {
Placeholder.prototype.toWrittenString = function (cache) {
return "#<placeholder>";
};
Placeholder.prototype.toDisplayedString = function(cache) {
Placeholder.prototype.toDisplayedString = function (cache) {
return "#<placeholder>";
};
Placeholder.prototype.toDomNode = function(cache) {
Placeholder.prototype.toDomNode = function (cache) {
var parent = document.createElement("span");
parent.appendChild(document.createTextNode('#<placeholder>'));
return parent;
};
Placeholder.prototype.equals = function(other, aUnionFind) {
Placeholder.prototype.equals = function (other, aUnionFind) {
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;
};
@ -55,4 +56,4 @@
})(this['plt'].baselib);
}(this.plt.baselib));

View File

@ -1,31 +1,34 @@
// Arity structure
(function(baselib) {
/*jslint unparam: true, sub: true, vars: true, maxerr: 50, indent: 4 */
/*globals $*/
(function (baselib, $) {
'use strict';
var exports = {};
baselib.ports = exports;
// Output Ports
var OutputPort = function() {};
var OutputPort = function () {};
var isOutputPort = baselib.makeClassPredicate(OutputPort);
var StandardOutputPort = function() {
var StandardOutputPort = function () {
OutputPort.call(this);
};
StandardOutputPort.prototype = baselib.heir(OutputPort.prototype);
StandardOutputPort.prototype.writeDomNode = function(MACHINE, domNode) {
StandardOutputPort.prototype.writeDomNode = function (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);
};
StandardErrorPort.prototype = baselib.heir(OutputPort.prototype);
StandardErrorPort.prototype.writeDomNode = function(MACHINE, domNode) {
StandardErrorPort.prototype.writeDomNode = function (MACHINE, domNode) {
MACHINE.params['currentErrorDisplayer'](MACHINE, domNode);
jQuery('*', domNode).trigger({type : 'afterAttach'});
$('*', domNode).trigger({type : 'afterAttach'});
};
@ -33,14 +36,14 @@
var OutputStringPort = function() {
var OutputStringPort = function () {
this.buf = [];
};
OutputStringPort.prototype = baselib.heir(OutputPort.prototype);
OutputStringPort.prototype.writeDomNode = function(MACHINE, v) {
OutputStringPort.prototype.writeDomNode = function (MACHINE, v) {
this.buf.push($(v).text());
};
OutputStringPort.prototype.getOutputString = function() {
OutputStringPort.prototype.getOutputString = function () {
return this.buf.join('');
};
var isOutputStringPort = baselib.makeClassPredicate(OutputStringPort);
@ -56,4 +59,4 @@
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
(function(baselib) {
(function (baselib) {
'use strict';
var exports = {};
baselib.readergraph = exports;
var readerGraph = function(x, objectHash, n) {
if (typeof(x) === 'object' && objectHash.containsKey(x)) {
var readerGraph = function (x, objectHash, n) {
var i;
if (typeof (x) === 'object' && objectHash.containsKey(x)) {
return objectHash.get(x);
}
if (plt.baselib.lists.isPair(x)) {
var consPair = plt.baselib.lists.makePair(x.first, x.rest);
if (baselib.lists.isPair(x)) {
var consPair = baselib.lists.makePair(x.first, x.rest);
objectHash.put(x, consPair);
consPair.first = readerGraph(x.first, objectHash, n+1);
consPair.rest = readerGraph(x.rest, objectHash, n+1);
consPair.first = readerGraph(x.first, objectHash, n + 1);
consPair.rest = readerGraph(x.rest, objectHash, n + 1);
return consPair;
}
if (plt.baselib.vectors.isVector(x)) {
if (baselib.vectors.isVector(x)) {
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);
for (var i = 0; i < len; i++) {
aVector.elts[i] = readerGraph(aVector.elts[i], objectHash, n+1);
for (i = 0; i < len; i++) {
aVector.elts[i] = readerGraph(aVector.elts[i], objectHash, n + 1);
}
return aVector;
}
if (plt.baselib.boxes.isBox(x)) {
var aBox = plt.baselib.boxes.makeBox(x.ref());
if (baselib.boxes.isBox(x)) {
var aBox = baselib.boxes.makeBox(x.ref());
objectHash.put(x, aBox);
aBox.val = readerGraph(x.ref(), objectHash, n+1);
aBox.val = readerGraph(x.ref(), objectHash, n + 1);
return aBox;
}
if (plt.baselib.hashes.isHash(x)) {
if (baselib.hashes.isHash(x)) {
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);
objectHash.put(x, aStruct);
for(var i = 0 ;i < x._fields.length; i++) {
x._fields[i] = readerGraph(x._fields[i], objectHash, n+1);
for (i = 0; i < x._fields.length; i++) {
x._fields[i] = readerGraph(x._fields[i], objectHash, n + 1);
}
return aStruct;
}
if (plt.baselib.placeholders.isPlaceholder(x)) {
return readerGraph(x.ref(), objectHash, n+1);
if (baselib.placeholders.isPlaceholder(x)) {
return readerGraph(x.ref(), objectHash, n + 1);
}
return x;
@ -56,4 +59,4 @@
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 = {};
baselib.regexps = exports;
// Regular expressions.
var RegularExpression = function(pattern) {
var RegularExpression = function (pattern) {
this.pattern = pattern;
};
var ByteRegularExpression = function(pattern) {
var ByteRegularExpression = function (pattern) {
this.pattern = pattern;
};
@ -19,4 +22,4 @@
exports.RegularExpression = RegularExpression;
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 are either mutable or immutable. immutable strings are represented
// as regular JavaScript strings. Mutable ones are represented as instances
// of the Str class.
(function(baselib) {
(function (baselib) {
'use strict';
var exports = {};
baselib.strings = exports;
var isString = function(s) {
return (typeof s === 'string' ||
s instanceof Str);
};
// chars: arrayof string
// Precondition: each string must only be 1 character long or bad things
// happen.
var Str = function(chars) {
var Str = function (chars) {
this.chars = chars;
this.length = chars.length;
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) {
var ret = [];
for (var i = 0; i < s.length; i++) {
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("");
};
var replaceUnprintableStringChars = function (s) {
var ret = [], i;
for (i = 0; i < s.length; i++) {
var val = s.charCodeAt(i);
switch(val) {
case 7: ret.push('\\a'); break;
@ -128,7 +65,70 @@
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);
@ -140,4 +140,4 @@
exports.isMutableString = isMutableString;
exports.makeMutableString = Str.makeInstance;
})(this['plt'].baselib);
}(this.plt.baselib));

View File

@ -1,15 +1,72 @@
// Structure types
(function(baselib) {
/*jslint browser: true, unparam: true, vars: true, white: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
/*globals $*/
(function (baselib, $) {
"use strict";
var 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("");
};
Struct.prototype.toDisplayedString = function (cache) {
return baselib.format.toWrittenString(this, cache);
};
Struct.prototype.toDomNode = function (params) {
var node = document.createElement("span"), i;
params.put(this, true);
$(node).append(document.createTextNode("("));
$(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;
};
Struct.prototype.equals = function (other, aUnionFind) {
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;
};
var StructType = function(name, // string
Struct.prototype.type = Struct;
//////////////////////////////////////////////////////////////////////
var StructType = function (name, // string
type, // StructType
numberOfArgs, // number
numberOfFields, // number
@ -33,12 +90,12 @@
};
StructType.prototype.toString = function(cache) {
StructType.prototype.toString = function (cache) {
return '#<struct-type:' + this.name + '>';
};
StructType.prototype.equals = function(other, aUnionFind) {
StructType.prototype.equals = function (other, aUnionFind) {
return this === other;
};
@ -52,199 +109,8 @@
// makeStructureType: string StructType number number boolean
// guard-function -> StructType
//
// Creates a new structure type.
var makeStructureType = function(theName,
parentType,
initFieldCnt,
autoFieldCnt,
autoV,
guard) {
// Defaults
autoFieldCnt = autoFieldCnt || 0;
parentType = parentType || DEFAULT_PARENT_TYPE;
guard = guard || DEFAULT_GUARD;
// rawConstructor creates a new struct type inheriting from
// the parent, with no guard checks.
var rawConstructor = function(name, args) {
parentType.type.call(this, name, args);
for (var i = 0; i < initFieldCnt; i++) {
this._fields.push(args[i+parentType.numberOfArgs]);
}
for (var i = 0; i < autoFieldCnt; i++) {
this._fields.push(autoV);
}
};
rawConstructor.prototype = baselib.heir(parentType.type.prototype);
// Set type, necessary for equality checking
rawConstructor.prototype.type = rawConstructor;
// The structure type consists of the name, its constructor, a
// record of how many argument it and its parent type contains,
// the list of autofields, the guard, and functions corresponding
// to the constructor, the predicate, the accessor, and mutators.
var newType = new StructType(
theName,
rawConstructor,
initFieldCnt + parentType.numberOfArgs,
initFieldCnt + autoFieldCnt,
parentType.firstField + parentType.numberOfFields,
function(args, name, k) {
return guard(args, name,
function(result) {
var parentArgs = result.slice(0, parentType.numberOfArgs);
var restArgs = result.slice(parentType.numberOfArgs);
return parentType.applyGuard(
parentArgs, name,
function(parentRes) {
return k( parentRes.concat(restArgs) ); });
});
},
// constructor
function() {
var args = [].slice.call(arguments);
return newType.applyGuard(
args,
baselib.symbols.Symbol.makeInstance(theName),
function(res) {
return new rawConstructor(theName, res); });
},
// predicate
function(x) {
return x instanceof rawConstructor;
},
// accessor
function(x, i) { return x._fields[i + this.firstField]; },
// mutator
function(x, i, v) { x._fields[i + this.firstField] = v; });
return newType;
};
//////////////////////////////////////////////////////////////////////
var Struct = function(constructorName, fields) {
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) {
var DEFAULT_GUARD = function (args, name, k) {
return k(args);
};
@ -258,8 +124,98 @@
var isStruct = function(x) { return x instanceof Struct; };
var isStructType = function(x) { return x instanceof StructType; };
// makeStructureType: string StructType number number boolean
// guard-function -> StructType
//
// Creates a new structure type.
var makeStructureType = function (theName,
parentType,
initFieldCnt,
autoFieldCnt,
autoV,
guard) {
// Defaults
autoFieldCnt = autoFieldCnt || 0;
parentType = parentType || DEFAULT_PARENT_TYPE;
guard = guard || DEFAULT_GUARD;
// RawConstructor creates a new struct type inheriting from
// the parent, with no guard checks.
var RawConstructor = function (name, args) {
var i;
parentType.type.call(this, name, args);
for (i = 0; i < initFieldCnt; i++) {
this._fields.push(args[i+parentType.numberOfArgs]);
}
for (i = 0; i < autoFieldCnt; i++) {
this._fields.push(autoV);
}
};
RawConstructor.prototype = baselib.heir(parentType.type.prototype);
// Set type, necessary for equality checking
RawConstructor.prototype.type = RawConstructor;
// The structure type consists of the name, its constructor, a
// record of how many argument it and its parent type contains,
// the list of autofields, the guard, and functions corresponding
// to the constructor, the predicate, the accessor, and mutators.
var newType = new StructType(
theName,
RawConstructor,
initFieldCnt + parentType.numberOfArgs,
initFieldCnt + autoFieldCnt,
parentType.firstField + parentType.numberOfFields,
function (args, name, k) {
return guard(args, name,
function (result) {
var parentArgs = result.slice(0, parentType.numberOfArgs);
var restArgs = result.slice(parentType.numberOfArgs);
return parentType.applyGuard(
parentArgs, name,
function (parentRes) {
return k( parentRes.concat(restArgs) ); });
});
},
// constructor
function () {
var args = [].slice.call(arguments);
return newType.applyGuard(
args,
baselib.symbols.Symbol.makeInstance(theName),
function (res) {
return new RawConstructor(theName, res); });
},
// predicate
function (x) {
return x instanceof RawConstructor;
},
// accessor
function (x, i) { return x._fields[i + this.firstField]; },
// mutator
function (x, i, v) { x._fields[i + this.firstField] = v; });
return newType;
};
var isStruct = function (x) { return x instanceof Struct; };
var isStructType = function (x) { return x instanceof StructType; };
//////////////////////////////////////////////////////////////////////
@ -271,16 +227,4 @@
exports.isStruct = isStruct;
exports.isStructType = isStructType;
// exports.StructProc = StructProc;
// exports.StructConstructorProc = StructConstructorProc;
// exports.StructPredicateProc = StructPredicateProc;
// exports.StructAccessorProc = StructAccessorProc;
// exports.StructMutatorProc = StructMutatorProc;
})(this['plt'].baselib);
}(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
(function(baselib) {
(function (baselib) {
"use strict";
var exports = {};
baselib.symbols = exports;
@ -11,44 +11,43 @@
// Symbols
//////////////////////////////////////////////////////////////////////
var Symbol = function(val) {
var Symbol = function (val) {
this.val = val;
};
var symbolCache = {};
// makeInstance: string -> Symbol.
Symbol.makeInstance = function(val) {
Symbol.makeInstance = function (val) {
// To ensure that we can eq? symbols with equal values.
if (!(val in symbolCache)) {
if (!(symbolCache.hasOwnProperty(val))) {
symbolCache[val] = new Symbol(val);
} else {
}
return symbolCache[val];
};
Symbol.prototype.equals = function(other, aUnionFind) {
Symbol.prototype.equals = function (other, aUnionFind) {
return other instanceof Symbol &&
this.val === other.val;
};
Symbol.prototype.toString = function(cache) {
Symbol.prototype.toString = function (cache) {
return this.val;
};
Symbol.prototype.toWrittenString = function(cache) {
Symbol.prototype.toWrittenString = function (cache) {
return this.val;
};
Symbol.prototype.toDisplayedString = function(cache) {
Symbol.prototype.toDisplayedString = function (cache) {
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.isSymbol = isSymbol;
})(this['plt'].baselib);
}(this.plt.baselib));

View File

@ -1,21 +1,18 @@
(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.
var UnionFind = function() {
var UnionFind = function () {
// this.parenMap holds the arrows from an arbitrary pointer
// to its parent.
this.parentMap = baselib.hashes.makeLowLevelEqHash();
}
};
// find: ptr -> UnionFindNode
// Returns the representative for this ptr.
UnionFind.prototype.find = function(ptr) {
UnionFind.prototype.find = function (ptr) {
var parent = (this.parentMap.containsKey(ptr) ?
this.parentMap.get(ptr) : ptr);
if (parent === ptr) {
@ -30,7 +27,7 @@
// merge: ptr ptr -> void
// 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));
};
@ -38,4 +35,4 @@
baselib.UnionFind = UnionFind;
})(this['plt'].baselib);
}(this.plt.baselib));

View File

@ -1,47 +1,52 @@
// vectors
(function(baselib) {
/*jslint devel: false, browser: true, vars: true, plusplus: true, maxerr: 500, indent: 4 */
(function (baselib) {
"use strict";
var exports = {};
baselib.vectors = exports;
Vector = function(n, initialElements) {
this.elts = new Array(n);
var Vector = function (n, initialElements) {
var i;
this.elts = [];
this.elts.length = n;
if (initialElements) {
for (var i = 0; i < n; i++) {
for (i = 0; i < n; i++) {
this.elts[i] = initialElements[i];
}
} else {
for (var i = 0; i < n; i++) {
for (i = 0; i < n; i++) {
this.elts[i] = undefined;
}
}
this.mutable = true;
};
Vector.makeInstance = function(n, elts) {
Vector.makeInstance = function (n, elts) {
return new Vector(n, elts);
}
};
Vector.prototype.length = function() {
Vector.prototype.length = function () {
return this.elts.length;
};
Vector.prototype.ref = function(k) {
Vector.prototype.ref = function (k) {
return this.elts[k];
};
Vector.prototype.set = function(k, v) {
Vector.prototype.set = function (k, v) {
this.elts[k] = v;
};
Vector.prototype.equals = function(other, aUnionFind) {
if (other != null && other != undefined && other instanceof Vector) {
if (other.length() != this.length()) {
return false
Vector.prototype.equals = function (other, aUnionFind) {
var i;
if (other instanceof Vector) {
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++) {
if (!(baselib.equality.equals(this.elts[i], other.elts[i], aUnionFind))) {
return false;
}
}
@ -51,39 +56,39 @@
}
};
Vector.prototype.toList = function() {
var ret = plt.baselib.lists.EMPTY;
for (var i = this.length() - 1; i >= 0; i--) {
ret = plt.baselib.lists.Cons.makeInstance(this.elts[i], ret);
Vector.prototype.toList = function () {
var ret = baselib.lists.EMPTY, i;
for (i = this.length() - 1; i >= 0; i--) {
ret = baselib.lists.Cons.makeInstance(this.elts[i], ret);
}
return ret;
};
Vector.prototype.toWrittenString = function(cache) {
Vector.prototype.toWrittenString = function (cache) {
var texts = [], i;
cache.put(this, true);
var texts = [];
for (var i = 0; i < this.length(); i++) {
texts.push(plt.baselib.format.toWrittenString(this.ref(i), cache));
for (i = 0; i < this.length(); i++) {
texts.push(baselib.format.toWrittenString(this.ref(i), cache));
}
return "#(" + texts.join(" ") + ")";
};
Vector.prototype.toDisplayedString = function(cache) {
Vector.prototype.toDisplayedString = function (cache) {
var texts = [], i;
cache.put(this, true);
var texts = [];
for (var i = 0; i < this.length(); i++) {
texts.push(plt.baselib.format.toDisplayedString(this.ref(i), cache));
for (i = 0; i < this.length(); i++) {
texts.push(baselib.format.toDisplayedString(this.ref(i), cache));
}
return "#(" + texts.join(" ") + ")";
};
Vector.prototype.toDomNode = function(cache) {
Vector.prototype.toDomNode = function (cache) {
var node = document.createElement("span"), i;
cache.put(this, true);
var node = document.createElement("span");
node.appendChild(document.createTextNode("#("));
for (var i = 0; i < this.length(); i++) {
node.appendChild(plt.baselib.format.toDomNode(this.ref(i), cache));
if (i !== this.length()-1) {
for (i = 0; i < this.length(); i++) {
node.appendChild(baselib.format.toDomNode(this.ref(i), cache));
if (i !== this.length() - 1) {
node.appendChild(document.createTextNode(" "));
}
}
@ -92,13 +97,13 @@
};
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);
};
var makeVectorImmutable = function() {
var makeVectorImmutable = function () {
var v = Vector.makeInstance(arguments.length, arguments);
v.mutable = false;
return v;
@ -114,4 +119,4 @@
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,
// but be augmented with several namespaces for the other libraries in
// the base library.
if (! this['plt']) { this['plt'] = {}; }
if (!(this.plt)) { this.plt = {}; }
(function (plt) {
'use strict';
var baselib = {};
plt['baselib'] = baselib;
plt.baselib = baselib;
// Simple object inheritance.
var heir = function(parentPrototype) {
var f = function() {}
f.prototype = parentPrototype;
return new f();
var heir = function (parentPrototype) {
var F = function () {};
F.prototype = parentPrototype;
return new F();
};
@ -20,8 +23,9 @@ if (! this['plt']) { this['plt'] = {}; }
// clone: object -> object
// Copies an object. The new object should respond like the old
// object, including to things like instanceof.
var clone = function(obj) {
var C = function() {}
var clone = function (obj) {
var property;
var C = function () {};
C.prototype = obj;
var c = new C();
for (property in obj) {
@ -34,8 +38,8 @@ if (! this['plt']) { this['plt'] = {}; }
// Consumes a class and creates a predicate that recognizes subclasses.
var makeClassPredicate = function(aClass) {
return function(x) { return x instanceof aClass; };
var makeClassPredicate = function (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
// arguments on the stack. vs provides optional values for the
// arguments that go beyond those of the mandatoryArgCount.
var withArguments = function(MACHINE,
mandatoryArgCount,
vs,
f) {
var args = [];
for (var i = 0; i < MACHINE.argcount; i++) {
var withArguments = function (MACHINE, mandatoryArgCount, vs, f) {
var args = [], i;
for (i = 0; i < MACHINE.argcount; i++) {
if (i < mandatoryArgCount) {
args.push(MACHINE.env[MACHINE.env.length - 1 - i]);
} else {
@ -72,4 +73,4 @@ if (! this['plt']) { this['plt'] = {}; }
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,12 +69,15 @@
(check-equal? (run-my-parse #'(begin (define x 3)
(check-true (match (run-my-parse #'(begin (define x 3)
x))
(make-Top (make-Prefix (list (make-GlobalBucket 'x)))
(make-Splice (list (make-DefValues (list (make-ToplevelRef 0 0 #f #t))
(make-Constant 3))
(make-ToplevelRef 0 0 #f #t)))))
[(struct Top ((struct Prefix (_))
(struct Splice ((list (struct DefValues ((list (struct ToplevelRef ('0 '0 '#f '#t)))
(struct Constant ('3))))
(struct ToplevelRef ('0 '0 '#f '#t)))))))
#t]
[else
#f]))
;; Lambdas
@ -368,9 +371,17 @@
;; Variable reference
(check-equal? (run-my-parse #'(#%variable-reference x))
(make-Top (make-Prefix (list #f (make-GlobalBucket 'x)))
(make-VariableReference (make-ToplevelRef 0 0 #f #t))))
(check-true (match (run-my-parse #'(#%variable-reference x))
[(struct Top ((struct Prefix
((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.
(void