From 61fa1f691e1c7ffd2222381e8b3bb6e99e457eca Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Thu, 2 Jun 2011 12:34:57 -0400 Subject: [PATCH 1/7] Notes on how we need to be able to attach external resources. --- NOTES | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/NOTES b/NOTES index 517ca3c..5a7caa6 100644 --- a/NOTES +++ b/NOTES @@ -595,4 +595,65 @@ benchmarks being able to write modules in javascript -being able to bundle external resources (like images) \ No newline at end of file +being able to bundle external resources (like images) + + +---------------------------------------------------------------------- + + +June 2, 2011 + + +We need a mechanism for attaching external resources to a program and +to be able to refer to them. External resources refer to things like: + + Images + HTML files + Sounds + +Each of these should be findable by path, and they should also be +packaged when a program is built. The user should be able to say +something like this: + + (define my-html-file (local-resource-path ...)) + +and the packager should automatically be able to statically walk +though all local-resource-path calls. + + + These files must be represented as separate files. + + +There may be additional resources that need to be included, though +they aren't directly used in the program. (Say, for example, an image +is refered to in an html resource. Maybe we should have a toplevel +element (include-resources ...) that take in a bunch of +build-resource-path. + + (include-resources (build-resource-path ...) + ...) + + + +The Whalesong make system needs to know how to deal with resources. + + +I also want to be able to refer to external web resources, and somehow +capture or cache them during building. + + + +Imaginary: I would like to be able to write something like this: + + (define my-file (remote-resource-path ...)) + +and be able to treat my-file as if it were a local resource. During +packaging, the file should be directly downloaded. + + +Other things to consider: + + We may need to consider workarounds for same-origin policy +restrictions. + + Can resources be input-port sources? From 0add763beb46040d758165add06f68e6d336ee05 Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Thu, 2 Jun 2011 14:30:42 -0400 Subject: [PATCH 2/7] the runtime includes the libraries from Moby, although they do not use them yet. --- NOTES | 12 + js-assembler/get-runtime.rkt | 46 +- js-assembler/runtime-src/helpers.js | 858 ++- js-assembler/runtime-src/link.js | 56 + js-assembler/runtime-src/primitives.js | 6855 +++++++++-------- .../runtime.js} | 21 +- js-assembler/runtime-src/types.js | 3599 ++++----- tests/browser-evaluate.rkt | 12 +- 8 files changed, 5813 insertions(+), 5646 deletions(-) create mode 100644 js-assembler/runtime-src/link.js rename js-assembler/{mini-runtime.js => runtime-src/runtime.js} (99%) diff --git a/NOTES b/NOTES index 5a7caa6..8fb78d9 100644 --- a/NOTES +++ b/NOTES @@ -657,3 +657,15 @@ Other things to consider: restrictions. Can resources be input-port sources? + + +---------------------------------------------------------------------- + +I've at least imported the libraries from Moby so that they're loaded +in the same runtime. However, there are some ugly things happening +here: for some reason, there's a circular dependency between types and +helpers. That dependency needs to be cut! I've added a workaround +for now, using the link library to delay initialization until the +modules are present, but this is an unsatisfactory solution. We +really shouldn't get into this problem in the first place... I must +do a lot of code cleanup once things stabilize... \ No newline at end of file diff --git a/js-assembler/get-runtime.rkt b/js-assembler/get-runtime.rkt index c1a0fe5..9af9c3b 100644 --- a/js-assembler/get-runtime.rkt +++ b/js-assembler/get-runtime.rkt @@ -1,6 +1,23 @@ #lang racket/base ;; Function to get the runtime library. +;; +;; The resulting Javascript will produce a file that loads: +;; +;; +;; jquery at the the toplevel +;; HashTable at the toplevel +;; jsnums at the toplevel +;; +;; followed by: +;; +;; plt.link +;; plt.helpers +;; plt.types +;; plt.primitives +;; plt.runtime + + (require racket/contract racket/runtime-path @@ -10,7 +27,27 @@ (provide/contract [get-runtime (-> string?)]) (define-runtime-path jquery.js "runtime-src/jquery-1.6.1.min.js") -(define-runtime-path runtime.js "mini-runtime.js") +(define-runtime-path hashtable.js "runtime-src/jshashtable-2.1_src.js") +(define-runtime-path jsnums.js "runtime-src/js-numbers.js") +(define-runtime-path link.js "runtime-src/link.js") +(define-runtime-path helpers.js "runtime-src/helpers.js") +(define-runtime-path types.js "runtime-src/types.js") +(define-runtime-path primitives.js "runtime-src/primitives.js") +(define-runtime-path runtime.js "runtime-src/runtime.js") + + +;; The order matters here. link needs to come near the top, because +;; the other modules below have some circular dependencies that are resolved +;; by link. +(define files (list jquery.js + hashtable.js + jsnums.js + link.js + helpers.js + types.js + primitives.js + runtime.js)) + (define (path->string p) @@ -19,11 +56,8 @@ (port->string ip)))) -(define text (string-append - (path->string jquery.js) - (path->string runtime.js))) - - +(define text (apply string-append + (map path->string files))) (define (get-runtime) diff --git a/js-assembler/runtime-src/helpers.js b/js-assembler/runtime-src/helpers.js index c793347..3415e46 100644 --- a/js-assembler/runtime-src/helpers.js +++ b/js-assembler/runtime-src/helpers.js @@ -1,441 +1,462 @@ +if (! this['plt']) { this['plt'] = {}; } + +// Helpers library: includes a bunch of helper functions that will be used +// +// +// FIXME: there's a circularity between this module and types, and that circularly +// should not be there! + ////////////////////////////////////////////////////////////// // File of helper functions for primitives and world. -var helpers = {}; -(function() { +(function(scope) { + var helpers = {}; + scope.helpers = helpers; - var format = function(formatStr, args, functionName) { - var throwFormatError = function() { - functionName = functionName || '#'; - var matches = formatStr.match(new RegExp('~[sSaA]', 'g')); - var expectedNumberOfArgs = matches == null ? 0 : matches.length; - var errorStrBuffer = [functionName + ': format string requires ' + expectedNumberOfArgs - + ' arguments, given ' + args.length + '; arguments were:', - types.toWrittenString(formatStr)]; - for (var i = 0; i < args.length; i++) { - errorStrBuffer.push( types.toWrittenString(args[i]) ); - } - raise( types.incompleteExn(types.exnFailContract, errorStrBuffer.join(' '), []) ); + // types refers to plt.types, and will be initialized later. + var types = scope['types']; + scope.link.ready('types', + function() { + types = scope['types']; + }); + + + + + + var format = function(formatStr, args, functionName) { + var throwFormatError = function() { + functionName = functionName || '#'; + var matches = formatStr.match(new RegExp('~[sSaA]', 'g')); + var expectedNumberOfArgs = matches == null ? 0 : matches.length; + var errorStrBuffer = [functionName + ': format string requires ' + expectedNumberOfArgs + + ' arguments, given ' + args.length + '; arguments were:', + types.toWrittenString(formatStr)]; + for (var i = 0; i < args.length; i++) { + errorStrBuffer.push( types.toWrittenString(args[i]) ); + } + + raise( types.incompleteExn(types.exnFailContract, errorStrBuffer.join(' '), []) ); + } + + var pattern = new RegExp("~[sSaAneE%~]", "g"); + var buffer = args.slice(0);; + function f(s) { + if (s == "~~") { + return "~"; + } else if (s == '~n' || s == '~%') { + return "\n"; + } else if (s == '~s' || s == "~S") { + if (buffer.length == 0) { + throwFormatError(); } - - var pattern = new RegExp("~[sSaAneE%~]", "g"); - var buffer = args.slice(0);; - function f(s) { - if (s == "~~") { - return "~"; - } else if (s == '~n' || s == '~%') { - return "\n"; - } else if (s == '~s' || s == "~S") { - if (buffer.length == 0) { - throwFormatError(); - } - return types.toWrittenString(buffer.shift()); - } else if (s == '~e' || s == "~E") { - // FIXME: we don't yet have support for the error-print - // handler, and currently treat ~e just like ~s. - if (buffer.length == 0) { - throwFormatError(); - } - return types.toWrittenString(buffer.shift()); - } else if (s == '~a' || s == "~A") { - if (buffer.length == 0) { - throwFormatError(); - } - return types.toDisplayedString(buffer.shift()); - } else { - throw types.internalError('format: string.replace matched invalid regexp', false); - } + return types.toWrittenString(buffer.shift()); + } else if (s == '~e' || s == "~E") { + // FIXME: we don't yet have support for the error-print + // handler, and currently treat ~e just like ~s. + if (buffer.length == 0) { + throwFormatError(); } - var result = formatStr.replace(pattern, f); - if (buffer.length > 0) { - throwFormatError(); + return types.toWrittenString(buffer.shift()); + } else if (s == '~a' || s == "~A") { + if (buffer.length == 0) { + throwFormatError(); } - return result; - }; + return types.toDisplayedString(buffer.shift()); + } else { + throw types.internalError('format: string.replace matched invalid regexp', false); + } + } + var result = formatStr.replace(pattern, f); + if (buffer.length > 0) { + throwFormatError(); + } + return result; + }; - // forEachK: CPS( array CPS(array -> void) (error -> void) -> void ) - // Iterates through an array and applies f to each element using CPS - // If an error is thrown, it catches the error and calls f_error on it - var forEachK = function(a, f, f_error, k) { - var forEachHelp = function(i) { - if( i >= a.length ) { - if (k) { - return k(); - } else { - return; - } - } - - try { - return f(a[i], function() { return forEachHelp(i+1); }); - } catch (e) { - f_error(e); - } - }; - return forEachHelp(0); - }; - - - // reportError: (or exception string) -> void - // Reports an error to the user, either at the console - // if the console exists, or as alerts otherwise. - var reportError = function(e) { - var reporter; - if (typeof(console) != 'undefined' && - typeof(console.log) != 'undefined') { - reporter = (function(x) { console.log(x); }); + // forEachK: CPS( array CPS(array -> void) (error -> void) -> void ) + // Iterates through an array and applies f to each element using CPS + // If an error is thrown, it catches the error and calls f_error on it + var forEachK = function(a, f, f_error, k) { + var forEachHelp = function(i) { + if( i >= a.length ) { + if (k) { + return k(); } else { - reporter = (function(x) { alert(x); }); + return; } - if (typeof e == 'string') { - reporter(e); - } else if ( types.isSchemeError(e) ) { - if ( types.isExn(e.val) ) { - reporter( types.exnMessage(e.val) ); - } - else { - reporter(e.val); - } - } else if ( types.isInternalError(e) ) { - reporter(e.val); - } else if (e.message) { - reporter(e.message); - } else { - reporter(e.toString()); - } -// if (plt.Kernel.lastLoc) { -// var loc = plt.Kernel.lastLoc; -// if (typeof(loc) === 'string') { -// reporter("Error was raised around " + loc); -// } else if (typeof(loc) !== 'undefined' && -// typeof(loc.line) !== 'undefined') { -// reporter("Error was raised around: " -// + plt.Kernel.locToString(loc)); -// } -// } + } + + try { + return f(a[i], function() { return forEachHelp(i+1); }); + } catch (e) { + f_error(e); + } }; + return forEachHelp(0); + }; - var raise = function(v) { - throw types.schemeError(v); - }; + // reportError: (or exception string) -> void + // Reports an error to the user, either at the console + // if the console exists, or as alerts otherwise. + var reportError = function(e) { + var reporter; + if (typeof(console) != 'undefined' && + typeof(console.log) != 'undefined') { + reporter = (function(x) { console.log(x); }); + } else { + reporter = (function(x) { alert(x); }); + } + if (typeof e == 'string') { + reporter(e); + } else if ( types.isSchemeError(e) ) { + if ( types.isExn(e.val) ) { + reporter( types.exnMessage(e.val) ); + } + else { + reporter(e.val); + } + } else if ( types.isInternalError(e) ) { + reporter(e.val); + } else if (e.message) { + reporter(e.message); + } else { + reporter(e.toString()); + } + // if (plt.Kernel.lastLoc) { + // var loc = plt.Kernel.lastLoc; + // if (typeof(loc) === 'string') { + // reporter("Error was raised around " + loc); + // } else if (typeof(loc) !== 'undefined' && + // typeof(loc.line) !== 'undefined') { + // reporter("Error was raised around: " + // + plt.Kernel.locToString(loc)); + // } + // } + }; - var procArityContains = function(n) { - return function(proc) { - var singleCase = function(aCase) { - if ( aCase instanceof types.ContinuationClosureValue ) { - return true; - } - return (aCase.numParams == n || - (aCase.isRest && aCase.numParams <= n)); - }; + var raise = function(v) { + throw types.schemeError(v); + }; - var cases = []; - if ( proc instanceof types.ContinuationClosureValue || - proc instanceof types.ClosureValue || - proc instanceof types.PrimProc ) { - return singleCase(proc); - } - else if (proc instanceof types.CasePrimitive) { - cases = proc.cases; - } - else if (proc instanceof types.CaseLambdaValue) { - cases = proc.closures; - } - for (var i = 0; i < cases.length; i++) { - if ( singleCase(cases[i]) ) - return true; - } - return false; - } - }; - - var throwCheckError = function(details, pos, args) { - var errorFormatStr; - if (args && args.length > 1) { - var errorFormatStrBuffer = ['~a: expects type <~a> as ~a arguments, given: ~s; other arguments were:']; - for (var i = 0; i < args.length; i++) { - if ( i != pos-1 ) { - errorFormatStrBuffer.push( types.toWrittenString(args[i]) ); - } - } - errorFormatStr = errorFormatStrBuffer.join(' '); - } - else { - errorFormatStr = "~a: expects argument of type <~a>, given: ~s"; - details.splice(2, 1); - } - - raise( types.incompleteExn(types.exnFailContract, - helpers.format(errorFormatStr, details), - []) ); - }; - - var check = function(x, f, functionName, typeName, position, args) { - if ( !f(x) ) { - throwCheckError([functionName, - typeName, - helpers.ordinalize(position), - x], - position, - args); - } - }; - - var isList = function(x) { - var seenPairs = makeLowLevelEqHash(); - while (true) { - if (seenPairs.containsKey(x)) { + var procArityContains = function(n) { + return function(proc) { + var singleCase = function(aCase) { + if ( aCase instanceof types.ContinuationClosureValue ) { return true; - } else if (x === types.EMPTY) { + } + return (aCase.numParams == n || + (aCase.isRest && aCase.numParams <= n)); + }; + + var cases = []; + if ( proc instanceof types.ContinuationClosureValue || + proc instanceof types.ClosureValue || + proc instanceof types.PrimProc ) { + return singleCase(proc); + } + else if (proc instanceof types.CasePrimitive) { + cases = proc.cases; + } + else if (proc instanceof types.CaseLambdaValue) { + cases = proc.closures; + } + + for (var i = 0; i < cases.length; i++) { + if ( singleCase(cases[i]) ) return true; - } else if (types.isPair(x)) { - seenPairs.put(x, true); + } + return false; + } + }; + + var throwCheckError = function(details, pos, args) { + var errorFormatStr; + if (args && args.length > 1) { + var errorFormatStrBuffer = ['~a: expects type <~a> as ~a arguments, given: ~s; other arguments were:']; + for (var i = 0; i < args.length; i++) { + if ( i != pos-1 ) { + errorFormatStrBuffer.push( types.toWrittenString(args[i]) ); + } + } + errorFormatStr = errorFormatStrBuffer.join(' '); + } + else { + errorFormatStr = "~a: expects argument of type <~a>, given: ~s"; + details.splice(2, 1); + } + + raise( types.incompleteExn(types.exnFailContract, + helpers.format(errorFormatStr, details), + []) ); + }; + + var check = function(x, f, functionName, typeName, position, args) { + if ( !f(x) ) { + throwCheckError([functionName, + typeName, + helpers.ordinalize(position), + x], + position, + args); + } + }; + + var isList = function(x) { + var seenPairs = makeLowLevelEqHash(); + while (true) { + if (seenPairs.containsKey(x)) { + return true; + } else if (x === types.EMPTY) { + return true; + } else if (types.isPair(x)) { + seenPairs.put(x, true); + x = x.rest(); + } else { + return false; + } + } + }; + + var isListOf = function(x, f) { + var seenPairs = makeLowLevelEqHash(); + while (true) { + if (seenPairs.containsKey(x)) { + return true; + } else if (x === types.EMPTY) { + return true; + } else if (types.isPair(x)) { + seenPairs.put(x, true); + if (f(x.first())) { x = x.rest(); } else { return false; } + } else { + return false; } - }; + } + }; - var isListOf = function(x, f) { - var seenPairs = makeLowLevelEqHash(); - while (true) { - if (seenPairs.containsKey(x)) { - return true; - } else if (x === types.EMPTY) { - return true; - } else if (types.isPair(x)) { - seenPairs.put(x, true); - if (f(x.first())) { - x = x.rest(); - } else { - return false; - } - } else { - return false; - } + var checkListOf = function(lst, f, functionName, typeName, position, args) { + if ( !isListOf(lst, f) ) { + helpers.throwCheckError([functionName, + 'list of ' + typeName, + helpers.ordinalize(position), + lst], + position, + args); + } + }; + + + // // remove: array any -> array + // // removes the first instance of v in a + // // or returns a copy of a if v does not exist + // var remove = function(a, v) { + // for (var i = 0; i < a.length; i++) { + // if (a[i] === v) { + // return a.slice(0, i).concat( a.slice(i+1, a.length) ); + // } + // } + // return a.slice(0); + // }; + + // map: array (any -> any) -> array + // applies f to each element of a and returns the result + // as a new array + var map = function(f, a) { + var b = new Array(a.length); + for (var i = 0; i < a.length; i++) { + b[i] = f(a[i]); + } + return b; + }; + + + var concatMap = function(f, a) { + var b = []; + for (var i = 0; i < a.length; i++) { + b = b.concat( f(a[i]) ); + } + return b; + }; + + + var schemeListToArray = function(lst) { + var result = []; + while ( !lst.isEmpty() ) { + result.push(lst.first()); + lst = lst.rest(); + } + return result; + } + + // deepListToArray: any -> any + // Converts list structure to array structure. + var deepListToArray = function(x) { + var thing = x; + if (thing === types.EMPTY) { + return []; + } else if (types.isPair(thing)) { + var result = []; + while (!thing.isEmpty()) { + result.push(deepListToArray(thing.first())); + thing = thing.rest(); } - }; - - var checkListOf = function(lst, f, functionName, typeName, position, args) { - if ( !isListOf(lst, f) ) { - helpers.throwCheckError([functionName, - 'list of ' + typeName, - helpers.ordinalize(position), - lst], - position, - args); - } - }; + return result; + } else { + return x; + } + } -// // remove: array any -> array -// // removes the first instance of v in a -// // or returns a copy of a if v does not exist -// var remove = function(a, v) { -// for (var i = 0; i < a.length; i++) { -// if (a[i] === v) { -// return a.slice(0, i).concat( a.slice(i+1, a.length) ); -// } -// } -// return a.slice(0); -// }; - - // map: array (any -> any) -> array - // applies f to each element of a and returns the result - // as a new array - var map = function(f, a) { - var b = new Array(a.length); - for (var i = 0; i < a.length; i++) { - b[i] = f(a[i]); - } - return b; - }; - - - var concatMap = function(f, a) { - var b = []; - for (var i = 0; i < a.length; i++) { - b = b.concat( f(a[i]) ); - } - return b; - }; - - - var schemeListToArray = function(lst) { - var result = []; - while ( !lst.isEmpty() ) { - result.push(lst.first()); - lst = lst.rest(); - } - return result; + var flattenSchemeListToArray = function(x) { + if ( !isList(x) ) { + return [x]; } - // deepListToArray: any -> any - // Converts list structure to array structure. - var deepListToArray = function(x) { - var thing = x; - if (thing === types.EMPTY) { - return []; - } else if (types.isPair(thing)) { - var result = []; - while (!thing.isEmpty()) { - result.push(deepListToArray(thing.first())); - thing = thing.rest(); - } - return result; - } else { - return x; - } + var ret = []; + while ( !x.isEmpty() ) { + ret = ret.concat( flattenSchemeListToArray(x.first()) ); + x = x.rest(); } + return ret; + }; - var flattenSchemeListToArray = function(x) { - if ( !isList(x) ) { - return [x]; - } - - var ret = []; - while ( !x.isEmpty() ) { - ret = ret.concat( flattenSchemeListToArray(x.first()) ); - x = x.rest(); - } - return ret; - }; - - - // assocListToHash: (listof (list X Y)) -> (hashof X Y) - var assocListToHash = function(lst) { - var result = {}; - while ( !lst.isEmpty() ) { - var key = lst.first().first(); - var val = lst.first().rest().first(); - result[key] = val; - lst = lst.rest(); - } - return result; - }; - - - var ordinalize = function(n) { - // special case for 11th: - if ( n % 100 == 11 ) { - return n + 'th'; - } - var res = n; - switch( n % 10 ) { - case 1: res += 'st'; break; - case 2: res += 'nd'; break; - case 3: res += 'rd'; break; - default: res += 'th'; break; - } - return res; + // assocListToHash: (listof (list X Y)) -> (hashof X Y) + var assocListToHash = function(lst) { + var result = {}; + while ( !lst.isEmpty() ) { + var key = lst.first().first(); + var val = lst.first().rest().first(); + result[key] = val; + lst = lst.rest(); } + return result; + }; - var wrapJsValue = function(x) { - if (x === undefined) { - return types.jsValue('undefined', x); - } - else if (x === null) { - return types.jsValue('null', x); - } - else if (typeof(x) == 'function') { - return types.jsValue('function', x); - } - else if ( x instanceof Array ) { - return types.jsValue('array', x); - } - else if ( typeof(x) == 'string' ) { - return types.jsValue("'" + x.toString() + "'", x); - } - else { - return types.jsValue(x.toString(), x); - } - }; + var ordinalize = function(n) { + // special case for 11th: + if ( n % 100 == 11 ) { + return n + 'th'; + } + var res = n; + switch( n % 10 ) { + case 1: res += 'st'; break; + case 2: res += 'nd'; break; + case 3: res += 'rd'; break; + default: res += 'th'; break; + } + return res; + } - var getKeyCodeName = function(e) { - var code = e.charCode || e.keyCode; - var keyname; - switch(code) { - case 16: keyname = "shift"; break; - case 17: keyname = "control"; break; - case 19: keyname = "pause"; break; - case 27: keyname = "escape"; break; - case 33: keyname = "prior"; break; - case 34: keyname = "next"; break; - case 35: keyname = "end"; break; - case 36: keyname = "home"; break; - case 37: keyname = "left"; break; - case 38: keyname = "up"; break; - case 39: keyname = "right"; break; - case 40: keyname = "down"; break; - case 42: keyname = "print"; break; - case 45: keyname = "insert"; break; - case 46: keyname = String.fromCharCode(127); break; - case 106: keyname = "*"; break; - case 107: keyname = "+"; break; - case 109: keyname = "-"; break; - case 110: keyname = "."; break; - case 111: keyname = "/"; break; - case 144: keyname = "numlock"; break; - case 145: keyname = "scroll"; break; - case 186: keyname = ";"; break; - case 187: keyname = "="; break; - case 188: keyname = ","; break; - case 189: keyname = "-"; break; - case 190: keyname = "."; break; - case 191: keyname = "/"; break; - case 192: keyname = "`"; break; - case 219: keyname = "["; break; - case 220: keyname = "\\"; break; - case 221: keyname = "]"; break; - case 222: keyname = "'"; break; - default: if (code >= 96 && code <= 105) { - keyname = (code - 96).toString(); - } - else if (code >= 112 && code <= 123) { - keyname = "f" + (code - 111); - } - else { - keyname = String.fromCharCode(code).toLowerCase(); - } - break; + var wrapJsValue = function(x) { + if (x === undefined) { + return types.jsValue('undefined', x); + } + else if (x === null) { + return types.jsValue('null', x); + } + else if (typeof(x) == 'function') { + return types.jsValue('function', x); + } + else if ( x instanceof Array ) { + return types.jsValue('array', x); + } + else if ( typeof(x) == 'string' ) { + return types.jsValue("'" + x.toString() + "'", x); + } + else { + return types.jsValue(x.toString(), x); + } + }; + + + var getKeyCodeName = function(e) { + var code = e.charCode || e.keyCode; + var keyname; + switch(code) { + case 16: keyname = "shift"; break; + case 17: keyname = "control"; break; + case 19: keyname = "pause"; break; + case 27: keyname = "escape"; break; + case 33: keyname = "prior"; break; + case 34: keyname = "next"; break; + case 35: keyname = "end"; break; + case 36: keyname = "home"; break; + case 37: keyname = "left"; break; + case 38: keyname = "up"; break; + case 39: keyname = "right"; break; + case 40: keyname = "down"; break; + case 42: keyname = "print"; break; + case 45: keyname = "insert"; break; + case 46: keyname = String.fromCharCode(127); break; + case 106: keyname = "*"; break; + case 107: keyname = "+"; break; + case 109: keyname = "-"; break; + case 110: keyname = "."; break; + case 111: keyname = "/"; break; + case 144: keyname = "numlock"; break; + case 145: keyname = "scroll"; break; + case 186: keyname = ";"; break; + case 187: keyname = "="; break; + case 188: keyname = ","; break; + case 189: keyname = "-"; break; + case 190: keyname = "."; break; + case 191: keyname = "/"; break; + case 192: keyname = "`"; break; + case 219: keyname = "["; break; + case 220: keyname = "\\"; break; + case 221: keyname = "]"; break; + case 222: keyname = "'"; break; + default: if (code >= 96 && code <= 105) { + keyname = (code - 96).toString(); + } + else if (code >= 112 && code <= 123) { + keyname = "f" + (code - 111); } - return keyname; - }; + else { + keyname = String.fromCharCode(code).toLowerCase(); + } + break; + } + return keyname; + }; - // maybeCallAfterAttach: dom-node -> void - // walk the tree rooted at aNode, and call afterAttach if the element has - // such a method. - var maybeCallAfterAttach = function(aNode) { - var stack = [aNode]; - while (stack.length !== 0) { - var nextNode = stack.pop(); - if (nextNode.afterAttach) { - nextNode.afterAttach(nextNode); - } - if (nextNode.hasChildNodes && nextNode.hasChildNodes()) { - var children = nextNode.childNodes; - for (var i = 0; i < children.length; i++) { - stack.push(children[i]); - } + // maybeCallAfterAttach: dom-node -> void + // walk the tree rooted at aNode, and call afterAttach if the element has + // such a method. + var maybeCallAfterAttach = function(aNode) { + var stack = [aNode]; + while (stack.length !== 0) { + var nextNode = stack.pop(); + if (nextNode.afterAttach) { + nextNode.afterAttach(nextNode); + } + if (nextNode.hasChildNodes && nextNode.hasChildNodes()) { + var children = nextNode.childNodes; + for (var i = 0; i < children.length; i++) { + stack.push(children[i]); } } - }; + } + }; @@ -543,45 +564,48 @@ var helpers = {}; - //////////////////////////////////////////////// + //////////////////////////////////////////////// - helpers.format = format; - helpers.forEachK = forEachK; - helpers.reportError = reportError; - helpers.raise = raise; + helpers.format = format; + helpers.forEachK = forEachK; + helpers.reportError = reportError; + helpers.raise = raise; - helpers.procArityContains = procArityContains; - helpers.throwCheckError = throwCheckError; - helpers.isList = isList; - helpers.isListOf = isListOf; - helpers.check = check; - helpers.checkListOf = checkListOf; - -// helpers.remove = remove; - helpers.map = map; - helpers.concatMap = concatMap; - helpers.schemeListToArray = schemeListToArray; - helpers.deepListToArray = deepListToArray; - helpers.flattenSchemeListToArray = flattenSchemeListToArray; - helpers.assocListToHash = assocListToHash; + helpers.procArityContains = procArityContains; + helpers.throwCheckError = throwCheckError; + helpers.isList = isList; + helpers.isListOf = isListOf; + helpers.check = check; + helpers.checkListOf = checkListOf; + + // helpers.remove = remove; + helpers.map = map; + helpers.concatMap = concatMap; + helpers.schemeListToArray = schemeListToArray; + helpers.deepListToArray = deepListToArray; + helpers.flattenSchemeListToArray = flattenSchemeListToArray; + helpers.assocListToHash = assocListToHash; - helpers.ordinalize = ordinalize; - helpers.wrapJsValue = wrapJsValue; + helpers.ordinalize = ordinalize; + helpers.wrapJsValue = wrapJsValue; - helpers.getKeyCodeName = getKeyCodeName; + helpers.getKeyCodeName = getKeyCodeName; - helpers.maybeCallAfterAttach = maybeCallAfterAttach; + helpers.maybeCallAfterAttach = maybeCallAfterAttach; - helpers.makeLocationDom = makeLocationDom; - helpers.isLocationDom = isLocationDom; + helpers.makeLocationDom = makeLocationDom; + helpers.isLocationDom = isLocationDom; - helpers.getEqHashCode = getEqHashCode; - helpers.makeLowLevelEqHash = makeLowLevelEqHash; + helpers.getEqHashCode = getEqHashCode; + helpers.makeLowLevelEqHash = makeLowLevelEqHash; - helpers.heir = heir; + helpers.heir = heir; -})(); + + + + scope.link.announceReady('helpers'); +})(this['plt']); ///////////////////////////////////////////////////////////////// - diff --git a/js-assembler/runtime-src/link.js b/js-assembler/runtime-src/link.js new file mode 100644 index 0000000..6156d8a --- /dev/null +++ b/js-assembler/runtime-src/link.js @@ -0,0 +1,56 @@ +// Lightweight linking of the modules. +// There are circular dependencies across the modules unfortunately, so we +// need a mechanism for letting them link to each other. +if (! this['plt']) { this['plt'] = {}; } +(function(scope) { + var link = {}; + scope['link'] = link; + + + // link.ready: (string (string -> void)) -> void + // When the name announces that it's ready, calls the function f. + link.ready = function(name, f) { + readyWaiters[name] = readyWaiters[name] || []; + readyWaiters[name].push(f); + + if (linkIsReady[name]) { + notifySingle(f, name); + } + }; + + // link.announceReady: string -> void + // Lets the world know that the name is ready. + link.announceReady = function(name) { + var i; + linkIsReady[name] = true; + notifyAll(name); + }; + + + + // notifyAll: string -> void + // Tell all listeners that the name is ready. + var notifyAll = function(name) { + var waiters = readyWaiters[name] || [], i; + for (i = 0 ; i < waiters.length; i++) { + notifySingle(waiters[i], name); + } + readyWaiters[name] = []; + }; + + + // Tell a single listener that the name is ready. + var notifySingle = function(f, name) { + setTimeout(function() { f(name); }, + 0); + }; + + + // linkIsReady: (Hashtable String Boolean) + var linkIsReady = {}; + + // readyWaiters: (Hashtable String (Arrayof (String -> Void))) + var readyWaiters = {}; + + +})(this['plt']); \ No newline at end of file diff --git a/js-assembler/runtime-src/primitives.js b/js-assembler/runtime-src/primitives.js index c416f62..19f3abf 100644 --- a/js-assembler/runtime-src/primitives.js +++ b/js-assembler/runtime-src/primitives.js @@ -1,4 +1,5 @@ -var primitive = {}; +if (! this['plt']) { this['plt'] = {}; } + /** @@ -13,164 +14,196 @@ That way, we can do a simple grep. */ - -(function() { +(function(scope) { + var primitives = {}; + scope.primitives = primitives; + var PRIMITIVES = {}; -var CALL = types.internalCall; + var types = scope.types; + var helpers = scope.helpers; -var PAUSE = types.internalPause; + var CALL, PAUSE, PrimProc, CasePrimitive, makeOptionPrimitive, procArityContains; + var assocListToHash, raise; + var isList, isListOf; + var check; + var checkListOf; + + CALL = types.internalCall; + PAUSE = types.internalPause; + PrimProc = types.PrimProc; + CasePrimitive = types.CasePrimitive; + makeOptionPrimitive = types.makeOptionPrimitive; + + procArityContains = helpers.procArityContains; + assocListToHash = helpers.assocListToHash; + raise = helpers.raise; + isList = helpers.isList; + isListOf = helpers.isListOf; + check = helpers.check; + checkListOf = helpers.checkListOf; + + scope.link.ready('types', + function() { + types = scope.types; + CALL = types.internalCall; + PAUSE = types.internalPause; + PrimProc = types.PrimProc; + CasePrimitive = types.CasePrimitive; + makeOptionPrimitive = types.makeOptionPrimitive; + }); + scope.link.ready('helpers', + function() { + helpers = scope.helpers; + procArityContains = helpers.procArityContains; + assocListToHash = helpers.assocListToHash; + raise = helpers.raise; + isList = helpers.isList; + isListOf = helpers.isListOf; + check = helpers.check; + checkListOf = helpers.checkListOf; + }); + ////////////////////////////////////////////////////////////////////// + // Helper Functions + var id = function(x) { return x; }; -var PRIMITIVES = {}; - -var PrimProc = types.PrimProc; -var CasePrimitive = types.CasePrimitive; -var makeOptionPrimitive = types.makeOptionPrimitive; - -////////////////////////////////////////////////////////////////////// - -// Helper Functions - -var id = function(x) { return x; }; - -var sub1 = function(x) { + var sub1 = function(x) { check(x, isNumber, 'sub1', 'number', 1, [x]); return jsnums.subtract(x, 1); -} + } -var add1 = function(x) { + var add1 = function(x) { check(x, isNumber, 'add1', 'number', 1, [x]); return jsnums.add(x, 1); -} + } -var callWithValues = function(f, vals) { + var callWithValues = function(f, vals) { if (vals instanceof types.ValuesWrapper) { - return CALL(f, vals.elts, id); + return CALL(f, vals.elts, id); } else { - return CALL(f, [vals], id); + return CALL(f, [vals], id); } -}; + }; -// onSingleResult: x (x -> y) -> y -// Applies f on x, but first checks that x is a single value. -// If it isn't, raises an arity error. -var onSingleResult = function(x, f) { - if (x instanceof types.ValuesWrapper) { - if (x.elts.length === 1) { - return f(x.elts[0]); - } else { - var argsStr = helpers.map(function(x) { return "~s"; }, x.elts).join(' '); - raise(types.incompleteExn( - types.exnFailContractArity, - helpers.format( - 'context expected 1 value, received ~s values: ' + argsStr, - [x.elts.length].concat(x.elts)))); - } - } else { - return f(x); - } -}; + // onSingleResult: x (x -> y) -> y + // Applies f on x, but first checks that x is a single value. + // If it isn't, raises an arity error. + var onSingleResult = function(x, f) { + if (x instanceof types.ValuesWrapper) { + if (x.elts.length === 1) { + return f(x.elts[0]); + } else { + var argsStr = helpers.map(function(x) { return "~s"; }, x.elts).join(' '); + raise(types.incompleteExn( + types.exnFailContractArity, + helpers.format( + 'context expected 1 value, received ~s values: ' + argsStr, + [x.elts.length].concat(x.elts)))); + } + } else { + return f(x); + } + }; -var procedureArity = function(proc) { + var procedureArity = function(proc) { check(proc, isFunction, 'procedure-arity', 'procedure', 1, [proc]); - + var singleCaseArity = function(aCase) { - if (aCase instanceof types.ContinuationClosureValue) { - return types.arityAtLeast(0); - } - else if (aCase.isRest) { - return types.arityAtLeast(aCase.numParams); - } - else { - return aCase.numParams; - } + if (aCase instanceof types.ContinuationClosureValue) { + return types.arityAtLeast(0); + } + else if (aCase.isRest) { + return types.arityAtLeast(aCase.numParams); + } + else { + return aCase.numParams; + } } if ( proc instanceof PrimProc || proc instanceof types.ClosureValue || proc instanceof types.ContinuationClosureValue ) { - return singleCaseArity(proc); + return singleCaseArity(proc); } else { - var cases; - if ( proc instanceof CasePrimitive ) { - cases = proc.cases; - } - else if ( proc instanceof types.CaseLambdaValue ) { - cases = proc.closures; - } - else { - throw types.internalError('procedure-arity given wrong type that passed isFunction!', false); - } + var cases; + if ( proc instanceof CasePrimitive ) { + cases = proc.cases; + } + else if ( proc instanceof types.CaseLambdaValue ) { + cases = proc.closures; + } + else { + throw types.internalError('procedure-arity given wrong type that passed isFunction!', false); + } - var ret = []; - for (var i = 0; i < cases.length; i++) { - ret.push( singleCaseArity(cases[i]) ); - } - ret = normalizeArity(ret); - return ret.length == 1 ? ret[0] : types.list(ret); + var ret = []; + for (var i = 0; i < cases.length; i++) { + ret.push( singleCaseArity(cases[i]) ); + } + ret = normalizeArity(ret); + return ret.length == 1 ? ret[0] : types.list(ret); } -}; + }; -var normalizeArity = function(arity) { + var normalizeArity = function(arity) { var newArity = arity.slice(0); var sortFunc = function(x, y) { - if ( types.isArityAtLeast(x) ) { - if ( types.isArityAtLeast(y) ) { - return types.arityAtLeastValue(x) - types.arityAtLeastValue(y); - } - else { - return types.arityAtLeastValue(x) - y - 0.5; - } + if ( types.isArityAtLeast(x) ) { + if ( types.isArityAtLeast(y) ) { + return types.arityAtLeastValue(x) - types.arityAtLeastValue(y); } else { - if ( types.isArityAtLeast(y) ) { - return x - types.arityAtLeastValue(y) + 0.5; - } - else { - return x - y; - } + return types.arityAtLeastValue(x) - y - 0.5; } + } + else { + if ( types.isArityAtLeast(y) ) { + return x - types.arityAtLeastValue(y) + 0.5; + } + else { + return x - y; + } + } }; newArity.sort(sortFunc); for (var i = 0; i < newArity.length-1; i++) { - if ( types.isArityAtLeast(newArity[i]) ) { - return newArity.slice(0, i+1); - } + if ( types.isArityAtLeast(newArity[i]) ) { + return newArity.slice(0, i+1); + } } return newArity; -}; - - -var procArityContains = helpers.procArityContains; + }; -var length = function(lst) { + + + var length = function(lst) { checkList(lst, 'length', 1, [lst]); var ret = 0; for (; !lst.isEmpty(); lst = lst.rest()) { - ret = ret+1; + ret = ret+1; } return ret; -} + } -var append = function(initArgs) { + var append = function(initArgs) { if (initArgs.length == 0) { - return types.EMPTY; + return types.EMPTY; } var args = initArgs.slice(0, initArgs.length-1); var lastArg = initArgs[initArgs.length - 1]; @@ -178,127 +211,123 @@ var append = function(initArgs) { var ret = lastArg; for (var i = args.length-1; i >= 0; i--) { - ret = args[i].append(ret); + ret = args[i].append(ret); } return ret; -} + } -var foldHelp = function(f, acc, args) { + var foldHelp = function(f, acc, args) { if ( args[0].isEmpty() ) { - return acc; + return acc; } var fArgs = []; var argsRest = []; for (var i = 0; i < args.length; i++) { - fArgs.push(args[i].first()); - argsRest.push(args[i].rest()); + fArgs.push(args[i].first()); + argsRest.push(args[i].rest()); } fArgs.push(acc); return CALL(f, fArgs, - function(result) { + function(result) { return foldHelp(f, result, argsRest); - }); -} + }); + } -var quicksort = function(functionName) { + var quicksort = function(functionName) { return function(initList, comp) { - checkList(initList, functionName, 1, arguments); - check(comp, procArityContains(2), functionName, 'procedure (arity 2)', 2, arguments); - - var quicksortHelp = function(k) { - return function(lst) { - if ( lst.isEmpty() ) { - return k(types.EMPTY); - } - - var compYes = new PrimProc('compYes', 1, false, false, - function(x) { return CALL(comp, [x, lst.first()], id); }); - var compNo = new PrimProc('compNo', 1, false, false, - function(x) { return CALL(comp, [x, lst.first()], - function(res) { return !res; }); - }); + checkList(initList, functionName, 1, arguments); + check(comp, procArityContains(2), functionName, 'procedure (arity 2)', 2, arguments); + + var quicksortHelp = function(k) { + return function(lst) { + if ( lst.isEmpty() ) { + return k(types.EMPTY); + } + + var compYes = new PrimProc('compYes', 1, false, false, + function(x) { return CALL(comp, [x, lst.first()], id); }); + var compNo = new PrimProc('compNo', 1, false, false, + function(x) { return CALL(comp, [x, lst.first()], + function(res) { return !res; }); + }); - return CALL(PRIMITIVES['filter'], - [compYes, lst.rest()], - quicksortHelp(function(sorted1) { - return CALL(PRIMITIVES['filter'], - [compNo, lst.rest()], - quicksortHelp(function(sorted2) { - return k( append([sorted1, - types.list([lst.first()]), - sorted2]) ); - })); - })); - }; - } - return quicksortHelp(id)(initList); + return CALL(PRIMITIVES['filter'], + [compYes, lst.rest()], + quicksortHelp(function(sorted1) { + return CALL(PRIMITIVES['filter'], + [compNo, lst.rest()], + quicksortHelp(function(sorted2) { + return k( append([sorted1, + types.list([lst.first()]), + sorted2]) ); + })); + })); + }; + } + return quicksortHelp(id)(initList); }; -} + } -var compare = function(args, comp) { + var compare = function(args, comp) { var curArg = args[0]; for (var i = 1; i < args.length; i++) { - if ( !comp(curArg, args[i]) ) { - return false; - } - curArg = args[i]; + if ( !comp(curArg, args[i]) ) { + return false; + } + curArg = args[i]; } return true; -} + } -// isAlphabeticString: string -> boolean -var isAlphabeticString = function(s) { + // isAlphabeticString: string -> boolean + var isAlphabeticString = function(s) { for(var i = 0; i < s.length; i++) { - if (! ((s.charAt(i) >= "a" && s.charAt(i) <= "z") || - (s.charAt(i) >= "A" && s.charAt(i) <= "Z"))) { - return false; - } + if (! ((s.charAt(i) >= "a" && s.charAt(i) <= "z") || + (s.charAt(i) >= "A" && s.charAt(i) <= "Z"))) { + return false; + } } return true; -}; + }; -var isMutableString = function(s) { - return isString(s) && typeof s != 'string'; -}; + var isMutableString = function(s) { + return isString(s) && typeof s != 'string'; + }; -var isNumericString = function(s) { + var isNumericString = function(s) { for (var i = 0; i < s.length; i++) { - if ( ! (s.charAt(i) >= '0' && s.charAt(i) <= '9') ) { - return false; - } + if ( ! (s.charAt(i) >= '0' && s.charAt(i) <= '9') ) { + return false; + } } return true; -} + } -// isWhitespaceString: string -> boolean -var isWhitespaceString = (function() { + // isWhitespaceString: string -> boolean + var isWhitespaceString = (function() { var pat = new RegExp("^\\s*$"); return function(s) { - return (s.match(pat) ? true : false); + return (s.match(pat) ? true : false); } -}()); + }()); -var isImmutable = function(x) { + var isImmutable = function(x) { return ((isString(x) || isByteString(x) || isVector(x) || isHash(x) || isBox(x)) && !x.mutable); -}; + }; -var assocListToHash = helpers.assocListToHash; - -var raise = helpers.raise; - @@ -313,230 +342,223 @@ var raise = helpers.raise; -var checkAndGetGuard = function(funName, guard, numberOfGuardArgs) { + var checkAndGetGuard = function(funName, guard, numberOfGuardArgs) { if ( !guard ) { - return false; + return false; } // Check the number of arguments on the guard if ( !procArityContains(numberOfGuardArgs)(guard) ) { - raise(types.incompleteExn( - types.exnFailContract, - helpers.format( - '~a: guard procedure does not accept ~a arguments ' - + '(one more than the number constructor arguments): ~s', - [funName, numberOfGuardArgs, guard]), - [])); + raise(types.incompleteExn( + types.exnFailContract, + helpers.format( + '~a: guard procedure does not accept ~a arguments ' + + '(one more than the number constructor arguments): ~s', + [funName, numberOfGuardArgs, guard]), + [])); } // if the guard has the right number of arguments, // then construct a javascript function to call it return function(args, name, k) { - args = args.concat([name]); - return CALL(guard, args, - function(res) { - if ( res instanceof types.ValuesWrapper ) { - return k(res.elts); - } - else { - return k([res]); - } - }); + args = args.concat([name]); + return CALL(guard, args, + function(res) { + if ( res instanceof types.ValuesWrapper ) { + return k(res.elts); + } + else { + return k([res]); + } + }); }; -}; + }; -var getMakeStructTypeReturns = function(aStructType) { + var getMakeStructTypeReturns = function(aStructType) { var name = aStructType.name; return new types.ValuesWrapper( - [aStructType, - (new types.StructConstructorProc(aStructType, - 'make-'+name, - aStructType.numberOfArgs, - false, - false, - aStructType.constructor)), - (new types.StructPredicateProc(aStructType, name+'?', 1, false, false, aStructType.predicate)), - (new types.StructAccessorProc(aStructType, - name+'-ref', - 2, - false, - false, - function(x, i) { - check(x, aStructType.predicate, name+'-ref', 'struct:'+name, 1, arguments); - check(i, isNatural, name+'-ref', 'non-negative exact integer', 2, arguments); + [aStructType, + (new types.StructConstructorProc(aStructType, + 'make-'+name, + aStructType.numberOfArgs, + false, + false, + aStructType.constructor)), + (new types.StructPredicateProc(aStructType, name+'?', 1, false, false, aStructType.predicate)), + (new types.StructAccessorProc(aStructType, + name+'-ref', + 2, + false, + false, + function(x, i) { + check(x, aStructType.predicate, name+'-ref', 'struct:'+name, 1, arguments); + check(i, isNatural, name+'-ref', 'non-negative exact integer', 2, arguments); - var numFields = aStructType.numberOfFields; - if ( jsnums.greaterThanOrEqual(i, numFields) ) { - var msg = (name+'-ref: slot index for not in ' + - '[0, ' + (numFields-1) + ']: ' + i); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - return aStructType.accessor(x, jsnums.toFixnum(i)); - })), - (new types.StructMutatorProc(aStructType, - name+'-set!', - 3, - false, - false, - function(x, i, v) { - check(x, aStructType.predicate, name+'-set!', 'struct:'+name, 1, arguments); - check(i, isNatural, name+'-set!', 'non-negative exact integer', 2, arguments); + var numFields = aStructType.numberOfFields; + if ( jsnums.greaterThanOrEqual(i, numFields) ) { + var msg = (name+'-ref: slot index for not in ' + + '[0, ' + (numFields-1) + ']: ' + i); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + return aStructType.accessor(x, jsnums.toFixnum(i)); + })), + (new types.StructMutatorProc(aStructType, + name+'-set!', + 3, + false, + false, + function(x, i, v) { + check(x, aStructType.predicate, name+'-set!', 'struct:'+name, 1, arguments); + check(i, isNatural, name+'-set!', 'non-negative exact integer', 2, arguments); - var numFields = aStructType.numberOfFields; - if ( jsnums.greaterThanOrEqual(i, numFields) ) { - var msg = (name+'-set!: slot index for not in ' + - '[0, ' + (numFields-1) + ']: ' + i); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - aStructType.mutator(x, jsnums.toFixnum(i), v) - })) ]); -}; + var numFields = aStructType.numberOfFields; + if ( jsnums.greaterThanOrEqual(i, numFields) ) { + var msg = (name+'-set!: slot index for not in ' + + '[0, ' + (numFields-1) + ']: ' + i); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + aStructType.mutator(x, jsnums.toFixnum(i), v) + })) ]); + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -var isNumber = jsnums.isSchemeNumber; -var isReal = jsnums.isReal; -var isRational = jsnums.isRational; -var isComplex = isNumber; -var isInteger = jsnums.isInteger; + var isNumber = jsnums.isSchemeNumber; + var isReal = jsnums.isReal; + var isRational = jsnums.isRational; + var isComplex = isNumber; + 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 isSymbol = types.isSymbol; -var isChar = types.isChar; -var isString = types.isString; -var isPair = types.isPair; -var isEmpty = function(x) { return x === types.EMPTY; }; -var isList = helpers.isList; -var isListOf = helpers.isListOf; + var isSymbol = types.isSymbol; + var isChar = types.isChar; + var isString = types.isString; + var isPair = types.isPair; + var isEmpty = function(x) { return x === types.EMPTY; }; + var isVector = types.isVector; + var isBox = types.isBox; + var isHash = types.isHash; + var isByteString = types.isByteString; -var isVector = types.isVector; -var isBox = types.isBox; -var isHash = types.isHash; -var isByteString = types.isByteString; - -var isByte = function(x) { + var isByte = function(x) { return (isNatural(x) && jsnums.lessThanOrEqual(x, 255)); -} + } -var isBoolean = function(x) { + var isBoolean = function(x) { return (x === true || x === false); -} + } -var isFunction = types.isFunction; + var isFunction = types.isFunction; -var isEqual = function(x, y) { + var isEqual = function(x, y) { return types.isEqual(x, y, new types.UnionFind()); -} + } -var isEq = function(x, y) { + var isEq = function(x, y) { return x === y; -} + } -var isEqv = function(x, y) { + var isEqv = function(x, y) { if (isNumber(x) && isNumber(y)) { - return jsnums.eqv(x, y); + return jsnums.eqv(x, y); } else if (isChar(x) && isChar(y)) { - return x.val === y.val; + return x.val === y.val; } return x === y; -} + } -var isAssocList = function(x) { + var isAssocList = function(x) { return isPair(x) && isPair(x.rest()) && isEmpty(x.rest().rest()); -}; + }; -var isCompoundEffect = function(x) { + var isCompoundEffect = function(x) { return ( types.isEffect(x) || isListOf(x, isCompoundEffect) ); -}; + }; -var isJsValue = types.isJsValue; + var isJsValue = types.isJsValue; -var isJsObject = function(x) { + var isJsObject = function(x) { return isJsValue(x) && typeof(x.val) == 'object'; -}; + }; -var isJsFunction = function(x) { + var isJsFunction = function(x) { return isJsValue(x) && typeof(x.val) == 'function'; -}; + }; -var arrayEach = function(arr, f) { + var arrayEach = function(arr, f) { for (var i = 0; i < arr.length; i++) { - f.call(null, arr[i], i); + f.call(null, arr[i], i); } -} + } -//var throwCheckError = helpers.throwCheckError; -var check = helpers.check; -var checkList = function(x, functionName, position, args) { + var checkList = function(x, functionName, position, args) { if ( !isList(x) ) { - helpers.throwCheckError([functionName, - 'list', - helpers.ordinalize(position), - x], - position, - args); + helpers.throwCheckError([functionName, + 'list', + helpers.ordinalize(position), + x], + position, + args); } -} + } -var checkListOf = helpers.checkListOf; - -var checkListOfLength = function(lst, n, functionName, position, args) { + var checkListOfLength = function(lst, n, functionName, position, args) { if ( !isList(lst) || (length(lst) < n) ) { - helpers.throwCheckError([functionName, - 'list with ' + n + ' or more elements', - helpers.ordinalize(position), - lst], - position, - args); + helpers.throwCheckError([functionName, + 'list with ' + n + ' or more elements', + helpers.ordinalize(position), + lst], + position, + args); } -} + } -var checkAllSameLength = function(lists, functionName, args) { + var checkAllSameLength = function(lists, functionName, args) { if (lists.length == 0) - return; + return; var len = length(lists[0]); arrayEach(lists, function(lst, i) { - if (length(lst) != len) { - var argsStr = helpers.map(function(x) { return " ~s"; }, args).join(''); - var msg = helpers.format(functionName + ': all lists must have the same size; arguments were:' + argsStr, - args); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - }); -} + if (length(lst) != len) { + var argsStr = helpers.map(function(x) { return " ~s"; }, args).join(''); + var msg = helpers.format(functionName + ': all lists must have the same size; arguments were:' + argsStr, + args); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + }); + } -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -// Special moby-specific primitives + // Special moby-specific primitives -PRIMITIVES['verify-boolean-branch-value'] = + PRIMITIVES['verify-boolean-branch-value'] = new PrimProc('verify-boolean-branch-value', 2, false, @@ -551,208 +573,208 @@ PRIMITIVES['verify-boolean-branch-value'] = return x; }) -PRIMITIVES['throw-cond-exhausted-error'] = + PRIMITIVES['throw-cond-exhausted-error'] = new PrimProc('throw-cond-exhausted-error', 1, false, false, function(aLoc) { - // FIXME: should throw structure - // make-moby-error-type:conditional-exhausted - // instead. + // FIXME: should throw structure + // make-moby-error-type:conditional-exhausted + // instead. throw types.schemeError(types.incompleteExn(types.exnFail, "cond: all question results were false", [])); }); -PRIMITIVES['print-values'] = - new PrimProc('print-values', - 0, - true, - true, - function(state, values) { - var printed = false; - for (var i = 0; i < values.length; i++) { - if (values[i] !== types.VOID) { - if (printed) { - state.getDisplayHook()("\n"); + PRIMITIVES['print-values'] = + new PrimProc('print-values', + 0, + true, + true, + function(state, values) { + var printed = false; + for (var i = 0; i < values.length; i++) { + if (values[i] !== types.VOID) { + if (printed) { + state.getDisplayHook()("\n"); + } + state.getPrintHook()(values[i]); + printed = true; } - state.getPrintHook()(values[i]); - printed = true; - } - } - if (printed) { - state.getDisplayHook()("\n"); - } - state.v = types.VOID; - }); + } + if (printed) { + state.getDisplayHook()("\n"); + } + state.v = types.VOID; + }); -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -var defaultPrint = - new PrimProc('print', - 1, - false, - true, - function(state, x) { - state.getPrintHook()(types.toWrittenString(x)); - state.v = types.VOID; - }); + var defaultPrint = + new PrimProc('print', + 1, + false, + true, + function(state, x) { + state.getPrintHook()(types.toWrittenString(x)); + state.v = types.VOID; + }); -PRIMITIVES['write'] = - new CasePrimitive('write', - [new PrimProc('write', 1, false, true, function(aState, x) { - aState.getPrintHook()(x); - aState.v = types.VOID; - }), - new PrimProc('write', 2, false, true, function(aState, x, port) { - throw types.internalError('write to a port not implemented yet.', false); - }) ]); + PRIMITIVES['write'] = + new CasePrimitive('write', + [new PrimProc('write', 1, false, true, function(aState, x) { + aState.getPrintHook()(x); + aState.v = types.VOID; + }), + new PrimProc('write', 2, false, true, function(aState, x, port) { + throw types.internalError('write to a port not implemented yet.', false); + }) ]); -PRIMITIVES['display'] = + PRIMITIVES['display'] = new CasePrimitive('display', - [new PrimProc('display', 1, false, true, function(state, x) { - state.getDisplayHook()(x); - state.v = types.VOID; - }), - new PrimProc('display', 2, false, true, function(state, x, port) { - // FIXME - throw types.internalError("display to a port not implemented yet.", false); - } )]); + [new PrimProc('display', 1, false, true, function(state, x) { + state.getDisplayHook()(x); + state.v = types.VOID; + }), + new PrimProc('display', 2, false, true, function(state, x, port) { + // FIXME + throw types.internalError("display to a port not implemented yet.", false); + } )]); -PRIMITIVES['newline'] = + PRIMITIVES['newline'] = new CasePrimitive('newline', - [new PrimProc('newline', 0, false, true, function(state) { - state.getDisplayHook()('\n'); - state.v = types.VOID; - }), - new PrimProc('newline', 1, false, false, function(port) { - // FIXME - throw types.internalError("newline to a port not implemented yet.", false); - } )]); + [new PrimProc('newline', 0, false, true, function(state) { + state.getDisplayHook()('\n'); + state.v = types.VOID; + }), + new PrimProc('newline', 1, false, false, function(port) { + // FIXME + throw types.internalError("newline to a port not implemented yet.", false); + } )]); -PRIMITIVES['current-print'] = - new PrimProc('current-print', - 0, - false, false, - function() { - return defaultPrint; - }); + PRIMITIVES['current-print'] = + new PrimProc('current-print', + 0, + false, false, + function() { + return defaultPrint; + }); -PRIMITIVES['current-continuation-marks'] = - // FIXME: should be CasePrimitive taking either 0 or 1 arguments - new PrimProc('current-continuation-marks', - 0, - false, true, - function(aState) { - aState.v = state.captureCurrentContinuationMarks(aState); - }); + PRIMITIVES['current-continuation-marks'] = + // FIXME: should be CasePrimitive taking either 0 or 1 arguments + new PrimProc('current-continuation-marks', + 0, + false, true, + function(aState) { + aState.v = state.captureCurrentContinuationMarks(aState); + }); -PRIMITIVES['continuation-mark-set?'] = + PRIMITIVES['continuation-mark-set?'] = new PrimProc('continuation-mark-set?', 1, false, false, types.isContinuationMarkSet); -PRIMITIVES['continuation-mark-set->list'] = - new PrimProc('continuation-mark-set->list', - 2, - false, - true, - function(state, markSet, keyV) { - check(markSet, - types.isContinuationMarkSet, - 'continuation-mark-set->list', - 'continuation-mark-set', - 1, - [markSet, keyV]); - state.v = types.list(markSet.ref(keyV)); - }); + PRIMITIVES['continuation-mark-set->list'] = + new PrimProc('continuation-mark-set->list', + 2, + false, + true, + function(state, markSet, keyV) { + check(markSet, + types.isContinuationMarkSet, + 'continuation-mark-set->list', + 'continuation-mark-set', + 1, + [markSet, keyV]); + state.v = types.list(markSet.ref(keyV)); + }); -PRIMITIVES['for-each'] = - new PrimProc('for-each', - 2, - true, false, - function(f, firstArg, arglists) { - var allArgs = [f, firstArg].concat(arglists); - arglists.unshift(firstArg); - check(f, isFunction, 'for-each', 'procedure', 1, allArgs); - arrayEach(arglists, function(lst, i) {checkList(lst, 'for-each', i+2, allArgs);}); - checkAllSameLength(arglists, 'for-each', allArgs); - check(f, procArityContains(arglists.length), 'for-each', 'procedure (arity ' + arglists.length + ')', 1, allArgs); + PRIMITIVES['for-each'] = + new PrimProc('for-each', + 2, + true, false, + function(f, firstArg, arglists) { + var allArgs = [f, firstArg].concat(arglists); + arglists.unshift(firstArg); + check(f, isFunction, 'for-each', 'procedure', 1, allArgs); + arrayEach(arglists, function(lst, i) {checkList(lst, 'for-each', i+2, allArgs);}); + checkAllSameLength(arglists, 'for-each', allArgs); + check(f, procArityContains(arglists.length), 'for-each', 'procedure (arity ' + arglists.length + ')', 1, allArgs); - var forEachHelp = function(args) { - if (args[0].isEmpty()) { - return types.VOID; - } + var forEachHelp = function(args) { + if (args[0].isEmpty()) { + return types.VOID; + } - var argsFirst = []; - var argsRest = []; - for (var i = 0; i < args.length; i++) { - argsFirst.push(args[i].first()); - argsRest.push(args[i].rest()); - } + var argsFirst = []; + var argsRest = []; + for (var i = 0; i < args.length; i++) { + argsFirst.push(args[i].first()); + argsRest.push(args[i].rest()); + } - return CALL(f, argsFirst, - function(result) { return forEachHelp(argsRest); }); - } + return CALL(f, argsFirst, + function(result) { return forEachHelp(argsRest); }); + } - return forEachHelp(arglists); - }); + return forEachHelp(arglists); + }); -PRIMITIVES['make-thread-cell'] = + PRIMITIVES['make-thread-cell'] = new CasePrimitive('make-thread-cell', [ - new PrimProc("make-thread-cell", - 1, false, false, - function(x) { - return new types.ThreadCell(x, false); - } - ), - new PrimProc("make-thread-cell", - 2, false, false, - function(x, y) { - return new types.ThreadCell(x, y); - } - )]); + new PrimProc("make-thread-cell", + 1, false, false, + function(x) { + return new types.ThreadCell(x, false); + } + ), + new PrimProc("make-thread-cell", + 2, false, false, + function(x, y) { + return new types.ThreadCell(x, y); + } + )]); -PRIMITIVES['make-continuation-prompt-tag'] = + PRIMITIVES['make-continuation-prompt-tag'] = new CasePrimitive('make-continuation-prompt-tag', [ - new PrimProc("make-continuation-prompt-tag", - 0, false, false, - function() { - return new types.ContinuationPromptTag(); - } - ), - new PrimProc("make-continuation-prompt-tag", - 1, false, false, - function(x) { - check(x, isSymbol, 'make-continuation-prompt-tag', - 'symbol', 1, arguments); - return new types.ContinuationPromptTag(x); - } - )]); + new PrimProc("make-continuation-prompt-tag", + 0, false, false, + function() { + return new types.ContinuationPromptTag(); + } + ), + new PrimProc("make-continuation-prompt-tag", + 1, false, false, + function(x) { + check(x, isSymbol, 'make-continuation-prompt-tag', + 'symbol', 1, arguments); + return new types.ContinuationPromptTag(x); + } + )]); -PRIMITIVES['call-with-continuation-prompt'] = + PRIMITIVES['call-with-continuation-prompt'] = new PrimProc('call-with-continuation-prompt', 1, true, true, @@ -799,7 +821,7 @@ PRIMITIVES['call-with-continuation-prompt'] = procArgs))); }); -PRIMITIVES['default-continuation-prompt-tag'] = + PRIMITIVES['default-continuation-prompt-tag'] = new PrimProc('default-continuation-prompt-tag', 0, false, false, @@ -808,7 +830,7 @@ PRIMITIVES['default-continuation-prompt-tag'] = }); -PRIMITIVES['continuation-prompt-tag?'] = + PRIMITIVES['continuation-prompt-tag?'] = new PrimProc('continuation-prompt-tag?', 1, false, false, @@ -818,9 +840,9 @@ PRIMITIVES['continuation-prompt-tag?'] = -// Implements the default handler for a continuation prompt, if one isn't provided -// by call-with-continuation-prompt. -var defaultCallWithContinuationPromptHandler = + // Implements the default handler for a continuation prompt, if one isn't provided + // by call-with-continuation-prompt. + var defaultCallWithContinuationPromptHandler = new PrimProc('default-call-with-continuation-prompt-handler', 1, false, @@ -839,7 +861,7 @@ var defaultCallWithContinuationPromptHandler = }); -PRIMITIVES['abort-current-continuation'] = + PRIMITIVES['abort-current-continuation'] = new PrimProc('abort-current-continuation', 1, true, true, @@ -858,7 +880,7 @@ PRIMITIVES['abort-current-continuation'] = -PRIMITIVES['make-struct-type'] = + PRIMITIVES['make-struct-type'] = makeOptionPrimitive( 'make-struct-type', 4, @@ -907,9 +929,9 @@ PRIMITIVES['make-struct-type'] = aState.v = getMakeStructTypeReturns(aStructType); }); - - -PRIMITIVES['make-struct-field-accessor'] = + + + PRIMITIVES['make-struct-field-accessor'] = makeOptionPrimitive( 'make-struct-field-accessor', 2, @@ -923,18 +945,18 @@ PRIMITIVES['make-struct-field-accessor'] = 'make-struct-field-accessor', 'symbol or #f', 3, userArgs); var procName = accessor.type.name + '-' - + (fieldName ? fieldName.toString() : 'field' + fieldPos.toString()); + + (fieldName ? fieldName.toString() : 'field' + fieldPos.toString()); return new types.StructAccessorProc(accessor.type, procName, 1, false, false, - function(x) { - check(x, accessor.type.predicate, procName, 'struct:'+accessor.type.name, 1); - return accessor.impl(x, fieldPos); - }); + function(x) { + check(x, accessor.type.predicate, procName, 'struct:'+accessor.type.name, 1); + return accessor.impl(x, fieldPos); + }); }); -PRIMITIVES['make-struct-field-mutator'] = + PRIMITIVES['make-struct-field-mutator'] = makeOptionPrimitive( 'make-struct-field-mutator', 2, @@ -948,45 +970,45 @@ PRIMITIVES['make-struct-field-mutator'] = 'make-struct-field-mutator', 'symbol or #f', 3, userArgs); var procName = mutator.type.name + '-' - + (fieldName ? fieldName.toString() : 'field' + fieldPos.toString()); + + (fieldName ? fieldName.toString() : 'field' + fieldPos.toString()); return new types.StructMutatorProc(mutator.type, procName, 2, false, false, - function(x, v) { - check(x, mutator.type.predicate, procName, 'struct:'+mutator.type.name, 1, arguments); - return mutator.impl(x, fieldPos, v); - }); + function(x, v) { + check(x, mutator.type.predicate, procName, 'struct:'+mutator.type.name, 1, arguments); + return mutator.impl(x, fieldPos, v); + }); }); -PRIMITIVES['struct-type?'] = + PRIMITIVES['struct-type?'] = new PrimProc('struct-type?', 1, false, false, types.isStructType); -PRIMITIVES['struct-constructor-procedure?'] = - new PrimProc('struct-constructor-procedure?', 1, false, false, - function(x) { - return x instanceof types.StructConstructorProc; }); + PRIMITIVES['struct-constructor-procedure?'] = + new PrimProc('struct-constructor-procedure?', 1, false, false, + function(x) { + return x instanceof types.StructConstructorProc; }); -PRIMITIVES['struct-predicate-procedure?'] = - new PrimProc('struct-predicate-procedure?', 1, false, false, - function(x) { - return x instanceof types.StructPredicateProc; }); + PRIMITIVES['struct-predicate-procedure?'] = + new PrimProc('struct-predicate-procedure?', 1, false, false, + function(x) { + return x instanceof types.StructPredicateProc; }); -PRIMITIVES['struct-accessor-procedure?'] = - new PrimProc('struct-accessor-procedure?', 1, false, false, - function(x) { - return x instanceof types.StructAccessorProc; }); + PRIMITIVES['struct-accessor-procedure?'] = + new PrimProc('struct-accessor-procedure?', 1, false, false, + function(x) { + return x instanceof types.StructAccessorProc; }); -PRIMITIVES['struct-mutator-procedure?'] = - new PrimProc('struct-mutator-procedure?', 1, false, false, - function(x) { - return (x instanceof types.StructMutatorProc); }); + PRIMITIVES['struct-mutator-procedure?'] = + new PrimProc('struct-mutator-procedure?', 1, false, false, + function(x) { + return (x instanceof types.StructMutatorProc); }); -PRIMITIVES['procedure-arity'] = new PrimProc('procedure-arity', 1, false, false, procedureArity); + PRIMITIVES['procedure-arity'] = new PrimProc('procedure-arity', 1, false, false, procedureArity); -PRIMITIVES['procedure-arity-includes?'] = + PRIMITIVES['procedure-arity-includes?'] = new PrimProc('procedure-arity-includes?', 2, false, @@ -998,14 +1020,14 @@ PRIMITIVES['procedure-arity-includes?'] = }); -PRIMITIVES['make-arity-at-least'] = + PRIMITIVES['make-arity-at-least'] = new PrimProc('make-arity-at-least', 1, false, false, types.arityAtLeast); -PRIMITIVES['arity-at-least?'] = + PRIMITIVES['arity-at-least?'] = new PrimProc('arity-at-least?', 1, false, false, @@ -1013,7 +1035,7 @@ PRIMITIVES['arity-at-least?'] = return types.isArityAtLeast(x); }); -PRIMITIVES['arity-at-least-value'] = + PRIMITIVES['arity-at-least-value'] = new PrimProc('arity-at-least-value', 1, false, false, @@ -1024,224 +1046,224 @@ PRIMITIVES['arity-at-least-value'] = }); -PRIMITIVES['apply'] = - new PrimProc('apply', - 2, - true, false, - function(f, firstArg, args) { - var allArgs = [f, firstArg].concat(args); - check(f, isFunction, 'apply', 'procedure', 1, allArgs); - args.unshift(firstArg); + PRIMITIVES['apply'] = + new PrimProc('apply', + 2, + true, false, + function(f, firstArg, args) { + var allArgs = [f, firstArg].concat(args); + check(f, isFunction, 'apply', 'procedure', 1, allArgs); + args.unshift(firstArg); - var lastArg = args.pop(); - checkList(lastArg, 'apply', args.length+2, allArgs); - var args = args.concat(helpers.schemeListToArray(lastArg)); + var lastArg = args.pop(); + checkList(lastArg, 'apply', args.length+2, allArgs); + var args = args.concat(helpers.schemeListToArray(lastArg)); - return CALL(f, args, id); - }); + return CALL(f, args, id); + }); -PRIMITIVES['values'] = - new PrimProc('values', - 0, - true, false, - function(args) { - if (args.length === 1) { - return args[0]; - } - return new types.ValuesWrapper(args); - }); + PRIMITIVES['values'] = + new PrimProc('values', + 0, + true, false, + function(args) { + if (args.length === 1) { + return args[0]; + } + return new types.ValuesWrapper(args); + }); -PRIMITIVES['call-with-values'] = - new PrimProc('call-with-values', - 2, - false, false, - function(g, r) { - check(g, procArityContains(0), 'call-with-values', 'procedure (arity 0)', 1, arguments); - check(r, isFunction, 'call-with-values', 'procedure', 2, arguments); + PRIMITIVES['call-with-values'] = + new PrimProc('call-with-values', + 2, + false, false, + function(g, r) { + check(g, procArityContains(0), 'call-with-values', 'procedure (arity 0)', 1, arguments); + check(r, isFunction, 'call-with-values', 'procedure', 2, arguments); - return CALL(g, [], - function(res) { - return callWithValues(r, res); - }); - }); + return CALL(g, [], + function(res) { + return callWithValues(r, res); + }); + }); -PRIMITIVES['compose'] = - new PrimProc('compose', - 0, - true, false, - function(procs) { - arrayEach(procs, function(p, i) {check(p, isFunction, 'compose', 'procedure', i+1, procs);}); + PRIMITIVES['compose'] = + new PrimProc('compose', + 0, + true, false, + function(procs) { + arrayEach(procs, function(p, i) {check(p, isFunction, 'compose', 'procedure', i+1, procs);}); - if (procs.length == 0) { - return PRIMITIVES['values']; - } - var funList = types.list(procs).reverse(); - - var composeHelp = function(x, fList) { - if ( fList.isEmpty() ) { - return x; - } + if (procs.length == 0) { + return PRIMITIVES['values']; + } + var funList = types.list(procs).reverse(); + + var composeHelp = function(x, fList) { + if ( fList.isEmpty() ) { + return x; + } - return CALL(new PrimProc('', 1, false, false, - function(args) { - return callWithValues(fList.first(), args); - }), - [x], - function(result) { - return composeHelp(result, fList.rest()); - }); - } - return new PrimProc('', 0, true, false, - function(args) { - if (args.length === 1) { - return composeHelp(args[0], funList); - } - return composeHelp(new types.ValuesWrapper(args), funList); - }); - }); + return CALL(new PrimProc('', 1, false, false, + function(args) { + return callWithValues(fList.first(), args); + }), + [x], + function(result) { + return composeHelp(result, fList.rest()); + }); + } + return new PrimProc('', 0, true, false, + function(args) { + if (args.length === 1) { + return composeHelp(args[0], funList); + } + return composeHelp(new types.ValuesWrapper(args), funList); + }); + }); -PRIMITIVES['current-inexact-milliseconds'] = - new PrimProc('current-inexact-milliseconds', - 0, - false, false, - function() { - return jsnums.makeFloat((new Date()).valueOf()); - }); + PRIMITIVES['current-inexact-milliseconds'] = + new PrimProc('current-inexact-milliseconds', + 0, + false, false, + function() { + return jsnums.makeFloat((new Date()).valueOf()); + }); -PRIMITIVES['current-seconds'] = - new PrimProc('current-seconds', - 0, - false, false, - function() { - return Math.floor( (new Date()).getTime() / 1000 ); - }); + PRIMITIVES['current-seconds'] = + new PrimProc('current-seconds', + 0, + false, false, + function() { + return Math.floor( (new Date()).getTime() / 1000 ); + }); -PRIMITIVES['current-inspector'] = - new PrimProc('current-inspector', - 0, - false, false, - function() { - return false; - }); + PRIMITIVES['current-inspector'] = + new PrimProc('current-inspector', + 0, + false, false, + function() { + return false; + }); -PRIMITIVES['not'] = - new PrimProc('not', - 1, - false, false, - function(x) { - return x === false; - }); + PRIMITIVES['not'] = + new PrimProc('not', + 1, + false, false, + function(x) { + return x === false; + }); -PRIMITIVES['void'] = - new PrimProc('void', 0, true, false, - function(args) { - return types.VOID; - }); + PRIMITIVES['void'] = + new PrimProc('void', 0, true, false, + function(args) { + return types.VOID; + }); -PRIMITIVES['random'] = + PRIMITIVES['random'] = new CasePrimitive('random', - [new PrimProc('random', 0, false, false, - function() {return types.float(Math.random());}), - new PrimProc('random', 1, false, false, - function(n) { - check(n, isNatural, 'random', 'non-negative exact integer', 1, arguments); - return Math.floor(Math.random() * jsnums.toFixnum(n)); - }) ]); + [new PrimProc('random', 0, false, false, + function() {return types.float(Math.random());}), + new PrimProc('random', 1, false, false, + function(n) { + check(n, isNatural, 'random', 'non-negative exact integer', 1, arguments); + return Math.floor(Math.random() * jsnums.toFixnum(n)); + }) ]); -PRIMITIVES['sleep'] = - new CasePrimitive('sleep', - [new PrimProc('sleep', 0, false, false, function() { return types.VOID; }), - new PrimProc('sleep', - 1, - false, false, - function(secs) { - check(secs, isNonNegativeReal, 'sleep', 'non-negative real number', 1); - - var millisecs = jsnums.toFixnum( jsnums.multiply(secs, 1000) ); - return PAUSE(function(caller, success, fail) { - setTimeout(function() { success(types.VOID); }, - millisecs); - }); - }) ]); + PRIMITIVES['sleep'] = + new CasePrimitive('sleep', + [new PrimProc('sleep', 0, false, false, function() { return types.VOID; }), + new PrimProc('sleep', + 1, + false, false, + function(secs) { + check(secs, isNonNegativeReal, 'sleep', 'non-negative real number', 1); + + var millisecs = jsnums.toFixnum( jsnums.multiply(secs, 1000) ); + return PAUSE(function(caller, success, fail) { + setTimeout(function() { success(types.VOID); }, + millisecs); + }); + }) ]); -PRIMITIVES['identity'] = new PrimProc('identity', 1, false, false, id); + PRIMITIVES['identity'] = new PrimProc('identity', 1, false, false, id); -PRIMITIVES['raise'] = + PRIMITIVES['raise'] = new PrimProc('raise', 1, false, false, raise); -PRIMITIVES['error'] = - new PrimProc('error', - 1, - true, false, - function(arg1, args) { - var allArgs = [arg1].concat(args); - check(arg1, function(x) {return isSymbol(x) || isString(x);}, - 'error', 'symbol or string', 1, allArgs); + PRIMITIVES['error'] = + new PrimProc('error', + 1, + true, false, + function(arg1, args) { + var allArgs = [arg1].concat(args); + check(arg1, function(x) {return isSymbol(x) || isString(x);}, + 'error', 'symbol or string', 1, allArgs); - if ( isSymbol(arg1) ) { - if ( args.length === 0 ) { - raise( types.incompleteExn(types.exnFail, "error: " + arg1.val, []) ); - } - var formatStr = args.shift(); - check(formatStr, isString, 'error', 'string', 2, allArgs); + if ( isSymbol(arg1) ) { + if ( args.length === 0 ) { + raise( types.incompleteExn(types.exnFail, "error: " + arg1.val, []) ); + } + var formatStr = args.shift(); + check(formatStr, isString, 'error', 'string', 2, allArgs); - args.unshift(arg1); - raise( types.incompleteExn(types.exnFail, helpers.format('~s: '+formatStr.toString(), args), []) ); - } - else { - var msgBuffer = [arg1.toString()]; - for (var i = 0; i < args.length; i++) { - msgBuffer.push( types.toWrittenString(args[i]) ); - } - raise( types.incompleteExn(types.exnFail, msgBuffer.join(''), []) ); - } - }); + args.unshift(arg1); + raise( types.incompleteExn(types.exnFail, helpers.format('~s: '+formatStr.toString(), args), []) ); + } + else { + var msgBuffer = [arg1.toString()]; + for (var i = 0; i < args.length; i++) { + msgBuffer.push( types.toWrittenString(args[i]) ); + } + raise( types.incompleteExn(types.exnFail, msgBuffer.join(''), []) ); + } + }); -PRIMITIVES['make-exn'] = new PrimProc('make-exn', 2, false, false, types.exn); + PRIMITIVES['make-exn'] = new PrimProc('make-exn', 2, false, false, types.exn); -PRIMITIVES['exn-message'] = - new PrimProc('exn-message', - 1, - false, false, - function(exn) { - check(exn, types.isExn, 'exn-message', 'exn', 1, [exn]); - return types.exnMessage(exn); - }); + PRIMITIVES['exn-message'] = + new PrimProc('exn-message', + 1, + false, false, + function(exn) { + check(exn, types.isExn, 'exn-message', 'exn', 1, [exn]); + return types.exnMessage(exn); + }); -PRIMITIVES['exn-continuation-marks'] = - new PrimProc('exn-continuation-marks', - 1, - false, false, - function(exn) { - check(exn, types.isExn, 'exn-continuation-marks', 'exn', 1, [exn]); - return types.exnContMarks(exn); - }); + PRIMITIVES['exn-continuation-marks'] = + new PrimProc('exn-continuation-marks', + 1, + false, false, + function(exn) { + check(exn, types.isExn, 'exn-continuation-marks', 'exn', 1, [exn]); + return types.exnContMarks(exn); + }); -PRIMITIVES['make-exn:fail'] = new PrimProc('make-exn:fail', 2, false, false, types.exnFail); + PRIMITIVES['make-exn:fail'] = new PrimProc('make-exn:fail', 2, false, false, types.exnFail); -PRIMITIVES['make-exn:fail:contract'] = new PrimProc('make-exn:fail:contract', 2, false, false, types.exnFailContract); + PRIMITIVES['make-exn:fail:contract'] = new PrimProc('make-exn:fail:contract', 2, false, false, types.exnFailContract); PRIMITIVES['make-exn:fail:contract:arity'] = new PrimProc('make-exn:fail:contract:arity', @@ -1260,15 +1282,15 @@ PRIMITIVES['make-exn:fail:contract'] = new PrimProc('make-exn:fail:contract', 2, -PRIMITIVES['make-exn:fail:contract:divide-by-zero'] = - new PrimProc('make-exn:fail:contract:divide-by-zero', - 2, - false, - false, - types.exnFailContractDivisionByZero); + PRIMITIVES['make-exn:fail:contract:divide-by-zero'] = + new PrimProc('make-exn:fail:contract:divide-by-zero', + 2, + false, + false, + types.exnFailContractDivisionByZero); -PRIMITIVES['exn?'] = + PRIMITIVES['exn?'] = new PrimProc('exn?', 1, false, @@ -1276,7 +1298,7 @@ PRIMITIVES['exn?'] = types.isExn); -PRIMITIVES['exn:fail?'] = + PRIMITIVES['exn:fail?'] = new PrimProc('exn:fail?', 1, false, @@ -1284,7 +1306,7 @@ PRIMITIVES['exn:fail?'] = types.isExnFail); -PRIMITIVES['exn:fail:contract?'] = + PRIMITIVES['exn:fail:contract?'] = new PrimProc('exn:fail:contract?', 1, false, @@ -1292,7 +1314,7 @@ PRIMITIVES['exn:fail:contract?'] = types.isExnFailContract); -PRIMITIVES['exn:fail:contract:arity?'] = + PRIMITIVES['exn:fail:contract:arity?'] = new PrimProc('exn:fail:contract:arity?', 1, false, @@ -1300,7 +1322,7 @@ PRIMITIVES['exn:fail:contract:arity?'] = types.isExnFailContractArity); -PRIMITIVES['exn:fail:contract:variable?'] = + PRIMITIVES['exn:fail:contract:variable?'] = new PrimProc('exn:fail:contract:variable?', 1, false, @@ -1308,7 +1330,7 @@ PRIMITIVES['exn:fail:contract:variable?'] = types.isExnFailContractVariable); -PRIMITIVES['exn:fail:contract:divide-by-zero?'] = + PRIMITIVES['exn:fail:contract:divide-by-zero?'] = new PrimProc('exn:fail:contract:divide-by-zero?', 1, false, @@ -1318,441 +1340,441 @@ PRIMITIVES['exn:fail:contract:divide-by-zero?'] = -/*********************** + /*********************** *** Math Primitives *** ***********************/ -PRIMITIVES['*'] = - new PrimProc('*', - 0, - true, false, - function(args) { - arrayEach(args, function(x, i) {check(x, isNumber, '*', 'number', i+1, args);}); + PRIMITIVES['*'] = + new PrimProc('*', + 0, + true, false, + function(args) { + arrayEach(args, function(x, i) {check(x, isNumber, '*', 'number', i+1, args);}); - var result = types.rational(1); - for(var i = 0; i < args.length; i++) { - result = jsnums.multiply(args[i], result); - } - return result; - }); + var result = types.rational(1); + for(var i = 0; i < args.length; i++) { + result = jsnums.multiply(args[i], result); + } + return result; + }); -PRIMITIVES['-'] = - new PrimProc("-", - 1, - true, false, - function(x, args) { - var allArgs = [x].concat(args); - check(x, isNumber, '-', 'number', 1, allArgs); - arrayEach(args, function(y, i) {check(y, isNumber, '-', 'number', i+2, allArgs);}); + PRIMITIVES['-'] = + new PrimProc("-", + 1, + true, false, + function(x, args) { + var allArgs = [x].concat(args); + check(x, isNumber, '-', 'number', 1, allArgs); + arrayEach(args, function(y, i) {check(y, isNumber, '-', 'number', i+2, allArgs);}); - if (args.length == 0) { - return jsnums.subtract(0, x); - } - var result = x; - for (var i = 0; i < args.length; i++) { - result = jsnums.subtract(result, args[i]); - } - return result; - }); + if (args.length == 0) { + return jsnums.subtract(0, x); + } + var result = x; + for (var i = 0; i < args.length; i++) { + result = jsnums.subtract(result, args[i]); + } + return result; + }); -PRIMITIVES['+'] = - new PrimProc("+", - 0, - true, false, - function(args) { - arrayEach(args, function(x, i) {check(x, isNumber, '+', 'number', i+1, args);}); + PRIMITIVES['+'] = + new PrimProc("+", + 0, + true, false, + function(args) { + arrayEach(args, function(x, i) {check(x, isNumber, '+', 'number', i+1, args);}); - if (args.length == 0) { - return 0; - } - var result = args[0]; - for (var i = 1; i < args.length; i++) { - result = jsnums.add(result, args[i]); - } - return result; - }); + if (args.length == 0) { + return 0; + } + var result = args[0]; + for (var i = 1; i < args.length; i++) { + result = jsnums.add(result, args[i]); + } + return result; + }); -PRIMITIVES['='] = - new PrimProc("=", - 2, - true, false, - function(x, y, args) { - args.unshift(y); - args.unshift(x); - arrayEach(args, function(z, i) {check(z, isNumber, '=', 'number', i+1, args);}); + PRIMITIVES['='] = + new PrimProc("=", + 2, + true, false, + function(x, y, args) { + args.unshift(y); + args.unshift(x); + arrayEach(args, function(z, i) {check(z, isNumber, '=', 'number', i+1, args);}); - return compare(args, jsnums.equals); - }); + return compare(args, jsnums.equals); + }); -PRIMITIVES['=~'] = - new PrimProc('=~', - 3, - false, false, - function(x, y, range) { - check(x, isReal, '=~', 'real', 1, arguments); - check(y, isReal, '=~', 'real', 2, arguments); - check(range, isNonNegativeReal, '=~', 'non-negative-real', 3, arguments); + PRIMITIVES['=~'] = + new PrimProc('=~', + 3, + false, false, + function(x, y, range) { + check(x, isReal, '=~', 'real', 1, arguments); + check(y, isReal, '=~', 'real', 2, arguments); + check(range, isNonNegativeReal, '=~', 'non-negative-real', 3, arguments); - return jsnums.lessThanOrEqual(jsnums.abs(jsnums.subtract(x, y)), range); - }); + return jsnums.lessThanOrEqual(jsnums.abs(jsnums.subtract(x, y)), range); + }); -PRIMITIVES['/'] = - new PrimProc('/', - 1, - true, false, - function(x, args) { - var allArgs = [x].concat(args); - check(x, isNumber, '/', 'number', 1, allArgs); - arrayEach(args, function(y, i) {check(y, isNumber, '/', 'number', i+2, allArgs);}); - - if (args.length == 0) { - if ( jsnums.eqv(x, 0) ) { - raise( types.incompleteExn(types.exnFailContractDivisionByZero, '/: division by zero', []) ); - } - return jsnums.divide(1, x); - } + PRIMITIVES['/'] = + new PrimProc('/', + 1, + true, false, + function(x, args) { + var allArgs = [x].concat(args); + check(x, isNumber, '/', 'number', 1, allArgs); + arrayEach(args, function(y, i) {check(y, isNumber, '/', 'number', i+2, allArgs);}); + + if (args.length == 0) { + if ( jsnums.eqv(x, 0) ) { + raise( types.incompleteExn(types.exnFailContractDivisionByZero, '/: division by zero', []) ); + } + return jsnums.divide(1, x); + } - var res = x; - for (var i = 0; i < args.length; i++) { - if ( jsnums.eqv(args[i], 0) ) { - raise( types.incompleteExn(types.exnFailContractDivisionByZero, '/: division by zero', []) ); - } - res = jsnums.divide(res, args[i]); - } - return res; - }); + var res = x; + for (var i = 0; i < args.length; i++) { + if ( jsnums.eqv(args[i], 0) ) { + raise( types.incompleteExn(types.exnFailContractDivisionByZero, '/: division by zero', []) ); + } + res = jsnums.divide(res, args[i]); + } + return res; + }); -PRIMITIVES['sub1'] = - new PrimProc("sub1", - 1, - false, false, - sub1); + PRIMITIVES['sub1'] = + new PrimProc("sub1", + 1, + false, false, + sub1); -PRIMITIVES['add1'] = - new PrimProc("add1", - 1, - false, false, - add1); + PRIMITIVES['add1'] = + new PrimProc("add1", + 1, + false, false, + add1); -PRIMITIVES['<'] = - new PrimProc('<', - 2, - true, false, - function(x, y, args) { - args.unshift(y); - args.unshift(x); - arrayEach(args, function(z, i) {check(z, isNumber, '<', 'number', i+1, args);}); + PRIMITIVES['<'] = + new PrimProc('<', + 2, + true, false, + function(x, y, args) { + args.unshift(y); + args.unshift(x); + arrayEach(args, function(z, i) {check(z, isNumber, '<', 'number', i+1, args);}); - return compare(args, jsnums.lessThan); - }); + return compare(args, jsnums.lessThan); + }); -PRIMITIVES['>'] = - new PrimProc('>', - 2, - true, false, - function(x, y, args) { - args.unshift(y); - args.unshift(x); - arrayEach(args, function(z, i) {check(z, isNumber, '>', 'number', i+1, args);}); + PRIMITIVES['>'] = + new PrimProc('>', + 2, + true, false, + function(x, y, args) { + args.unshift(y); + args.unshift(x); + arrayEach(args, function(z, i) {check(z, isNumber, '>', 'number', i+1, args);}); - return compare(args, jsnums.greaterThan); - }); + return compare(args, jsnums.greaterThan); + }); -PRIMITIVES['<='] = - new PrimProc('<=', - 2, - true, false, - function(x, y, args) { - args.unshift(y); - args.unshift(x); - arrayEach(args, function(z, i) {check(z, isNumber, '<=', 'number', i+1, args);}); + PRIMITIVES['<='] = + new PrimProc('<=', + 2, + true, false, + function(x, y, args) { + args.unshift(y); + args.unshift(x); + arrayEach(args, function(z, i) {check(z, isNumber, '<=', 'number', i+1, args);}); - return compare(args, jsnums.lessThanOrEqual); - }); + return compare(args, jsnums.lessThanOrEqual); + }); -PRIMITIVES['>='] = - new PrimProc('>=', - 2, - true, false, - function(x, y, args) { - args.unshift(y); - args.unshift(x); - arrayEach(args, function(z, i) {check(z, isNumber, '>=', 'number', i+1, args);}); + PRIMITIVES['>='] = + new PrimProc('>=', + 2, + true, false, + function(x, y, args) { + args.unshift(y); + args.unshift(x); + arrayEach(args, function(z, i) {check(z, isNumber, '>=', 'number', i+1, args);}); - return compare(args, jsnums.greaterThanOrEqual); - }); + return compare(args, jsnums.greaterThanOrEqual); + }); -PRIMITIVES['abs'] = - new PrimProc('abs', - 1, - false, false, - function(x) { - check(x, isReal, 'abs', 'real', 1); - return jsnums.abs(x); - }); + PRIMITIVES['abs'] = + new PrimProc('abs', + 1, + false, false, + function(x) { + check(x, isReal, 'abs', 'real', 1); + return jsnums.abs(x); + }); -PRIMITIVES['quotient'] = - new PrimProc('quotient', - 2, - false, false, - function(x, y) { - check(x, isInteger, 'quotient', 'integer', 1, arguments); - check(y, isInteger, 'quotient', 'integer', 2, arguments); + PRIMITIVES['quotient'] = + new PrimProc('quotient', + 2, + false, false, + function(x, y) { + check(x, isInteger, 'quotient', 'integer', 1, arguments); + check(y, isInteger, 'quotient', 'integer', 2, arguments); - return jsnums.quotient(x, y); - }); + return jsnums.quotient(x, y); + }); -PRIMITIVES['remainder'] = - new PrimProc('remainder', - 2, - false, false, - function(x, y) { - check(x, isInteger, 'remainder', 'integer', 1, arguments); - check(y, isInteger, 'remainder', 'integer', 2, arguments); + PRIMITIVES['remainder'] = + new PrimProc('remainder', + 2, + false, false, + function(x, y) { + check(x, isInteger, 'remainder', 'integer', 1, arguments); + check(y, isInteger, 'remainder', 'integer', 2, arguments); - return jsnums.remainder(x, y); - }); + return jsnums.remainder(x, y); + }); -PRIMITIVES['modulo'] = - new PrimProc('modulo', - 2, - false, false, - function(x, y) { - check(x, isInteger, 'modulo', 'integer', 1, arguments); - check(y, isInteger, 'modulo', 'integer', 2, arguments); + PRIMITIVES['modulo'] = + new PrimProc('modulo', + 2, + false, false, + function(x, y) { + check(x, isInteger, 'modulo', 'integer', 1, arguments); + check(y, isInteger, 'modulo', 'integer', 2, arguments); - return jsnums.modulo(x, y); - }); + return jsnums.modulo(x, y); + }); -PRIMITIVES['max'] = - new PrimProc('max', - 1, - true, false, - function(x, args) { - args.unshift(x); -// check(x, isReal, 'max', 'real', 1, allArgs); - arrayEach(args, function(y, i) {check(y, isReal, 'max', 'real', i+1, args);}); + PRIMITIVES['max'] = + new PrimProc('max', + 1, + true, false, + function(x, args) { + args.unshift(x); + // check(x, isReal, 'max', 'real', 1, allArgs); + arrayEach(args, function(y, i) {check(y, isReal, 'max', 'real', i+1, args);}); - var curMax = x; - for (var i = 1; i < args.length; i++) { - if ( jsnums.greaterThan(args[i], curMax) ) { - curMax = args[i]; - } - } - return curMax; - }); + var curMax = x; + for (var i = 1; i < args.length; i++) { + if ( jsnums.greaterThan(args[i], curMax) ) { + curMax = args[i]; + } + } + return curMax; + }); -PRIMITIVES['min'] = - new PrimProc('min', - 1, - true, false, - function(x, args) { - args.unshift(x); -// check(x, isReal, 'min', 'real', 1); - arrayEach(args, function(y, i) {check(y, isReal, 'min', 'real', i+1, args);}); + PRIMITIVES['min'] = + new PrimProc('min', + 1, + true, false, + function(x, args) { + args.unshift(x); + // check(x, isReal, 'min', 'real', 1); + arrayEach(args, function(y, i) {check(y, isReal, 'min', 'real', i+1, args);}); - var curMin = x; - for (var i = 1; i < args.length; i++) { - if ( jsnums.lessThan(args[i], curMin) ) { - curMin = args[i]; - } - } - return curMin; - }); + var curMin = x; + for (var i = 1; i < args.length; i++) { + if ( jsnums.lessThan(args[i], curMin) ) { + curMin = args[i]; + } + } + return curMin; + }); -PRIMITIVES['gcd'] = - new PrimProc('gcd', - 1, - true, false, - function(x, args) { - var allArgs = [x].concat(args); - check(x, isInteger, 'gcd', 'integer', 1, allArgs); - arrayEach(args, function(y, i) {check(y, isInteger, 'gcd', 'integer', i+2, allArgs);}); + PRIMITIVES['gcd'] = + new PrimProc('gcd', + 1, + true, false, + function(x, args) { + var allArgs = [x].concat(args); + check(x, isInteger, 'gcd', 'integer', 1, allArgs); + arrayEach(args, function(y, i) {check(y, isInteger, 'gcd', 'integer', i+2, allArgs);}); - return jsnums.gcd(x, args); - }); + return jsnums.gcd(x, args); + }); -PRIMITIVES['lcm'] = - new PrimProc('lcm', - 1, - true, false, - function(x, args) { - var allArgs = [x].concat(args); - check(x, isInteger, 'lcm', 'integer', 1, allArgs); - arrayEach(args, function(y, i) {check(y, isInteger, 'lcm', 'integer', i+2, allArgs);}); + PRIMITIVES['lcm'] = + new PrimProc('lcm', + 1, + true, false, + function(x, args) { + var allArgs = [x].concat(args); + check(x, isInteger, 'lcm', 'integer', 1, allArgs); + arrayEach(args, function(y, i) {check(y, isInteger, 'lcm', 'integer', i+2, allArgs);}); - return jsnums.lcm(x, args); - }); + return jsnums.lcm(x, args); + }); -PRIMITIVES['floor'] = - new PrimProc('floor', - 1, - false, false, - function(x) { - check(x, isReal, 'floor', 'real', 1); - return jsnums.floor(x); - }); - - -PRIMITIVES['ceiling'] = - new PrimProc('ceiling', - 1, - false, false, - function(x) { - check(x, isReal, 'ceiling', 'real', 1); - return jsnums.ceiling(x); - }); - - -PRIMITIVES['round'] = - new PrimProc('round', - 1, - false, false, - function(x) { - check(x, isReal, 'round', 'real', 1); - return jsnums.round(x); - }); - -PRIMITIVES['truncate'] = - new PrimProc('truncate', - 1, - false, false, - function(x) { - check(x, isReal, 'truncate', 'real', 1); - if (jsnums.lessThan(x, 0)) { - return jsnums.ceiling(x); - } else { + PRIMITIVES['floor'] = + new PrimProc('floor', + 1, + false, false, + function(x) { + check(x, isReal, 'floor', 'real', 1); return jsnums.floor(x); - } - }); + }); + + + PRIMITIVES['ceiling'] = + new PrimProc('ceiling', + 1, + false, false, + function(x) { + check(x, isReal, 'ceiling', 'real', 1); + return jsnums.ceiling(x); + }); + + + PRIMITIVES['round'] = + new PrimProc('round', + 1, + false, false, + function(x) { + check(x, isReal, 'round', 'real', 1); + return jsnums.round(x); + }); + + PRIMITIVES['truncate'] = + new PrimProc('truncate', + 1, + false, false, + function(x) { + check(x, isReal, 'truncate', 'real', 1); + if (jsnums.lessThan(x, 0)) { + return jsnums.ceiling(x); + } else { + return jsnums.floor(x); + } + }); -PRIMITIVES['numerator'] = - new PrimProc('numerator', - 1, - false, false, - function(x) { - check(x, isRational, 'numerator', 'rational number', 1); - return jsnums.numerator(x); - }); + PRIMITIVES['numerator'] = + new PrimProc('numerator', + 1, + false, false, + function(x) { + check(x, isRational, 'numerator', 'rational number', 1); + return jsnums.numerator(x); + }); -PRIMITIVES['denominator'] = - new PrimProc('denominator', - 1, - false, false, - function(x) { - check(x, isRational, 'denominator', 'rational number', 1); - return jsnums.denominator(x); - }); + PRIMITIVES['denominator'] = + new PrimProc('denominator', + 1, + false, false, + function(x) { + check(x, isRational, 'denominator', 'rational number', 1); + return jsnums.denominator(x); + }); -PRIMITIVES['expt'] = - new PrimProc("expt", - 2, - false, false, - function(x, y) { - check(x, isNumber, 'expt', 'number', 1, arguments); - check(y, isNumber, 'expt', 'number', 2, arguments); - return jsnums.expt(x, y); - }); + PRIMITIVES['expt'] = + new PrimProc("expt", + 2, + false, false, + function(x, y) { + check(x, isNumber, 'expt', 'number', 1, arguments); + check(y, isNumber, 'expt', 'number', 2, arguments); + return jsnums.expt(x, y); + }); -PRIMITIVES['exp'] = - new PrimProc('exp', - 1, - false, false, - function(x) { - check(x, isNumber, 'exp', 'number', 1); - return jsnums.exp(x); - }); + PRIMITIVES['exp'] = + new PrimProc('exp', + 1, + false, false, + function(x) { + check(x, isNumber, 'exp', 'number', 1); + return jsnums.exp(x); + }); -PRIMITIVES['log'] = - new PrimProc('log', - 1, - false, false, - function(x) { - check(x, isNumber, 'log', 'number', 1); - return jsnums.log(x); - }); + PRIMITIVES['log'] = + new PrimProc('log', + 1, + false, false, + function(x) { + check(x, isNumber, 'log', 'number', 1); + return jsnums.log(x); + }); -PRIMITIVES['sin'] = - new PrimProc('sin', - 1, - false, false, - function(x) { - check(x, isNumber, 'sin', 'number', 1); - return jsnums.sin(x); - }); + PRIMITIVES['sin'] = + new PrimProc('sin', + 1, + false, false, + function(x) { + check(x, isNumber, 'sin', 'number', 1); + return jsnums.sin(x); + }); -PRIMITIVES['cos'] = - new PrimProc('cos', - 1, - false, false, - function(x) { - check(x, isNumber, 'cos', 'number', 1); - return jsnums.cos(x); - }); + PRIMITIVES['cos'] = + new PrimProc('cos', + 1, + false, false, + function(x) { + check(x, isNumber, 'cos', 'number', 1); + return jsnums.cos(x); + }); -PRIMITIVES['tan'] = - new PrimProc('tan', - 1, - false, false, - function(x) { - check(x, isNumber, 'tan', 'number', 1); - return jsnums.tan(x); - }); + PRIMITIVES['tan'] = + new PrimProc('tan', + 1, + false, false, + function(x) { + check(x, isNumber, 'tan', 'number', 1); + return jsnums.tan(x); + }); -PRIMITIVES['asin'] = - new PrimProc('asin', - 1, - false, false, - function(x) { - check(x, isNumber, 'asin', 'number', 1); - return jsnums.asin(x); - }); + PRIMITIVES['asin'] = + new PrimProc('asin', + 1, + false, false, + function(x) { + check(x, isNumber, 'asin', 'number', 1); + return jsnums.asin(x); + }); -PRIMITIVES['acos'] = - new PrimProc('acos', - 1, - false, false, - function(x) { - check(x, isNumber, 'acos', 'number', 1); - return jsnums.acos(x); - }); + PRIMITIVES['acos'] = + new PrimProc('acos', + 1, + false, false, + function(x) { + check(x, isNumber, 'acos', 'number', 1); + return jsnums.acos(x); + }); -PRIMITIVES['atan'] = + PRIMITIVES['atan'] = new CasePrimitive('atan', [new PrimProc('atan', 1, @@ -1773,125 +1795,125 @@ PRIMITIVES['atan'] = })]); -PRIMITIVES['sinh'] = - new PrimProc('sinh', - 1, - false, false, - function(x) { - check(x, isNumber, 'sinh', 'number', 1); - return jsnums.sinh(x); - }); + PRIMITIVES['sinh'] = + new PrimProc('sinh', + 1, + false, false, + function(x) { + check(x, isNumber, 'sinh', 'number', 1); + return jsnums.sinh(x); + }); -PRIMITIVES['cosh'] = - new PrimProc('cosh', - 1, - false, false, - function(x) { - check(x, isNumber, 'cosh', 'number', 1); - return jsnums.cosh(x); - }); + PRIMITIVES['cosh'] = + new PrimProc('cosh', + 1, + false, false, + function(x) { + check(x, isNumber, 'cosh', 'number', 1); + return jsnums.cosh(x); + }); -PRIMITIVES['sqr'] = - new PrimProc('sqr', - 1, - false, false, - function(x) { - check(x, isNumber, 'sqr', 'number', 1); - return jsnums.sqr(x); - }); + PRIMITIVES['sqr'] = + new PrimProc('sqr', + 1, + false, false, + function(x) { + check(x, isNumber, 'sqr', 'number', 1); + return jsnums.sqr(x); + }); -PRIMITIVES['sqrt'] = - new PrimProc('sqrt', - 1, - false, false, - function(x) { - check(x, isNumber, 'sqrt', 'number', 1); - return jsnums.sqrt(x); - }); + PRIMITIVES['sqrt'] = + new PrimProc('sqrt', + 1, + false, false, + function(x) { + check(x, isNumber, 'sqrt', 'number', 1); + return jsnums.sqrt(x); + }); -PRIMITIVES['integer-sqrt'] = - new PrimProc('integer-sqrt', - 1, - false, false, - function(x) { - check(x, isInteger, 'integer-sqrt', 'integer', 1); - return jsnums.integerSqrt(x); - }); + PRIMITIVES['integer-sqrt'] = + new PrimProc('integer-sqrt', + 1, + false, false, + function(x) { + check(x, isInteger, 'integer-sqrt', 'integer', 1); + return jsnums.integerSqrt(x); + }); -PRIMITIVES['make-rectangular'] = - new PrimProc('make-rectangular', - 2, - false, false, - function(x, y) { - check(x, isReal, 'make-rectangular', 'real', 1, arguments); - check(y, isReal, 'make-rectangular', 'real', 2, arguments); - return types.complex(x, y); - }); + PRIMITIVES['make-rectangular'] = + new PrimProc('make-rectangular', + 2, + false, false, + function(x, y) { + check(x, isReal, 'make-rectangular', 'real', 1, arguments); + check(y, isReal, 'make-rectangular', 'real', 2, arguments); + return types.complex(x, y); + }); -PRIMITIVES['make-polar'] = - new PrimProc('make-polar', - 2, - false, false, - function(x, y) { - check(x, isReal, 'make-polar', 'real', 1, arguments); - check(x, isReal, 'make-polar', 'real', 2, arguments); - return jsnums.makeComplexPolar(x, y); - }); + PRIMITIVES['make-polar'] = + new PrimProc('make-polar', + 2, + false, false, + function(x, y) { + check(x, isReal, 'make-polar', 'real', 1, arguments); + check(x, isReal, 'make-polar', 'real', 2, arguments); + return jsnums.makeComplexPolar(x, y); + }); -PRIMITIVES['real-part'] = - new PrimProc('real-part', - 1, - false, false, - function(x) { - check(x, isNumber, 'real-part', 'number', 1); - return jsnums.realPart(x); - }); + PRIMITIVES['real-part'] = + new PrimProc('real-part', + 1, + false, false, + function(x) { + check(x, isNumber, 'real-part', 'number', 1); + return jsnums.realPart(x); + }); -PRIMITIVES['imag-part'] = - new PrimProc('imag-part', - 1, - false, false, - function(x) { - check(x, isNumber, 'imag-part', 'number', 1); - return jsnums.imaginaryPart(x); - }); + PRIMITIVES['imag-part'] = + new PrimProc('imag-part', + 1, + false, false, + function(x) { + check(x, isNumber, 'imag-part', 'number', 1); + return jsnums.imaginaryPart(x); + }); -PRIMITIVES['angle'] = - new PrimProc('angle', - 1, - false, false, - function(x) { - check(x, isNumber, 'angle', 'number', 1); - return jsnums.angle(x); - }); + PRIMITIVES['angle'] = + new PrimProc('angle', + 1, + false, false, + function(x) { + check(x, isNumber, 'angle', 'number', 1); + return jsnums.angle(x); + }); -PRIMITIVES['magnitude'] = - new PrimProc('magnitude', - 1, - false, false, - function(x) { - check(x, isNumber, 'magnitude', 'number', 1); - return jsnums.magnitude(x); - }); + PRIMITIVES['magnitude'] = + new PrimProc('magnitude', + 1, + false, false, + function(x) { + check(x, isNumber, 'magnitude', 'number', 1); + return jsnums.magnitude(x); + }); -PRIMITIVES['conjugate'] = - new PrimProc('conjugate', - 1, - false, false, - function(x) { - check(x, isNumber, 'conjugate', 'number', 1); - return jsnums.conjugate(x); - }); + PRIMITIVES['conjugate'] = + new PrimProc('conjugate', + 1, + false, false, + function(x) { + check(x, isNumber, 'conjugate', 'number', 1); + return jsnums.conjugate(x); + }); PRIMITIVES['sgn'] = @@ -1920,1369 +1942,1369 @@ PRIMITIVES['conjugate'] = }); -PRIMITIVES['inexact->exact'] = - new PrimProc('inexact->exact', - 1, - false, false, - function (x) { - check(x, isNumber, 'inexact->exact', 'number', 1); - try { - return jsnums.toExact(x); - } catch(e) { - raise( types.exnFailContract('inexact->exact: no exact representation for ' - + types.toWrittenString(x), - false) ); - } - }); + PRIMITIVES['inexact->exact'] = + new PrimProc('inexact->exact', + 1, + false, false, + function (x) { + check(x, isNumber, 'inexact->exact', 'number', 1); + try { + return jsnums.toExact(x); + } catch(e) { + raise( types.exnFailContract('inexact->exact: no exact representation for ' + + types.toWrittenString(x), + false) ); + } + }); -PRIMITIVES['exact->inexact'] = - new PrimProc('exact->inexact', - 1, - false, false, - function (x) { - check(x, isNumber, 'exact->inexact', 'number', 1); - return jsnums.toInexact(x); - }); + PRIMITIVES['exact->inexact'] = + new PrimProc('exact->inexact', + 1, + false, false, + function (x) { + check(x, isNumber, 'exact->inexact', 'number', 1); + return jsnums.toInexact(x); + }); -PRIMITIVES['number->string'] = - new PrimProc('number->string', - 1, - false, false, - function(x) { - check(x, isNumber, 'number->string', 'number', 1); - return types.string(x.toString()); - }); + PRIMITIVES['number->string'] = + new PrimProc('number->string', + 1, + false, false, + function(x) { + check(x, isNumber, 'number->string', 'number', 1); + return types.string(x.toString()); + }); -PRIMITIVES['string->number'] = - new PrimProc('string->number', - 1, - false, false, - function(str) { - check(str, isString, 'string->number', 'string', 1); - return jsnums.fromString(str.toString()); - }); + PRIMITIVES['string->number'] = + new PrimProc('string->number', + 1, + false, false, + function(str) { + check(str, isString, 'string->number', 'string', 1); + return jsnums.fromString(str.toString()); + }); -PRIMITIVES['xml->s-exp'] = - new PrimProc('xml->s-exp', - 1, - false, false, - function(str) { - check(str, isString, 'xml->s-exp', 'string', 1); - str = str.toString(); - if (str.length == 0) { - return types.string(''); - } + PRIMITIVES['xml->s-exp'] = + new PrimProc('xml->s-exp', + 1, + false, false, + function(str) { + check(str, isString, 'xml->s-exp', 'string', 1); + str = str.toString(); + if (str.length == 0) { + return types.string(''); + } - var xmlDoc; - try { - //Internet Explorer - xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); - xmlDoc.async = "false"; - xmlDoc.loadXML(s); - // FIXME: check parse errors - } - catch(e) { - var parser = new DOMParser(); - xmlDoc = parser.parseFromString(s, "text/xml"); - // FIXME: check parse errors - } + var xmlDoc; + try { + //Internet Explorer + xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); + xmlDoc.async = "false"; + xmlDoc.loadXML(s); + // FIXME: check parse errors + } + catch(e) { + var parser = new DOMParser(); + xmlDoc = parser.parseFromString(s, "text/xml"); + // FIXME: check parse errors + } - var parseAttributes = function(attrs) { - var result = types.EMPTY; - for (var i = 0; i < attrs.length; i++) { - var keyValue = types.cons(types.symbol(attrs.item(i).nodeName), - types.cons(attrs.item(i).nodeValue, - types.EMPTY)); - result = types.cons(keyValue, result); - } - return types.cons(types.symbol("@"), result).reverse(); - }; + var parseAttributes = function(attrs) { + var result = types.EMPTY; + for (var i = 0; i < attrs.length; i++) { + var keyValue = types.cons(types.symbol(attrs.item(i).nodeName), + types.cons(attrs.item(i).nodeValue, + types.EMPTY)); + result = types.cons(keyValue, result); + } + return types.cons(types.symbol("@"), result).reverse(); + }; - var parse = function(node) { - if (node.nodeType == Node.ELEMENT_NODE) { - var result = types.EMPTY; - var child = node.firstChild; - while (child != null) { - var nextResult = parse(child); - if (isString(nextResult) && - !result.isEmpty() && - isString(result.first())) { - result = types.cons(result.first() + nextResult, - result.rest()); - } else { - result = types.cons(nextResult, result); - } - child = child.nextSibling; - } - result = result.reverse(); - result = types.cons(parseAttributes(node.attributes), - result); - result = types.cons( - types.symbol(node.nodeName), - result); - return result; - } else if (node.nodeType == Node.TEXT_NODE) { - return node.textContent; - } else if (node.nodeType == Node.CDATA_SECTION_NODE) { - return node.data; - } else { - return types.EMPTY; - } - }; - var result = parse(xmlDoc.firstChild); - return result; - }); + var parse = function(node) { + if (node.nodeType == Node.ELEMENT_NODE) { + var result = types.EMPTY; + var child = node.firstChild; + while (child != null) { + var nextResult = parse(child); + if (isString(nextResult) && + !result.isEmpty() && + isString(result.first())) { + result = types.cons(result.first() + nextResult, + result.rest()); + } else { + result = types.cons(nextResult, result); + } + child = child.nextSibling; + } + result = result.reverse(); + result = types.cons(parseAttributes(node.attributes), + result); + result = types.cons( + types.symbol(node.nodeName), + result); + return result; + } else if (node.nodeType == Node.TEXT_NODE) { + return node.textContent; + } else if (node.nodeType == Node.CDATA_SECTION_NODE) { + return node.data; + } else { + return types.EMPTY; + } + }; + var result = parse(xmlDoc.firstChild); + return result; + }); -/****************** + /****************** *** Predicates *** ******************/ -PRIMITIVES['procedure?'] = new PrimProc('procedure?', 1, false, false, isFunction); + PRIMITIVES['procedure?'] = new PrimProc('procedure?', 1, false, false, isFunction); -PRIMITIVES['pair?'] = new PrimProc('pair?', 1, false, false, isPair); -PRIMITIVES['cons?'] = new PrimProc('cons?', 1, false, false, isPair); -PRIMITIVES['empty?'] = new PrimProc('empty?', 1, false, false, isEmpty); -PRIMITIVES['null?'] = new PrimProc('null?', 1, false, false, isEmpty); + PRIMITIVES['pair?'] = new PrimProc('pair?', 1, false, false, isPair); + PRIMITIVES['cons?'] = new PrimProc('cons?', 1, false, false, isPair); + PRIMITIVES['empty?'] = new PrimProc('empty?', 1, false, false, isEmpty); + PRIMITIVES['null?'] = new PrimProc('null?', 1, false, false, isEmpty); -PRIMITIVES['undefined?'] = new PrimProc('undefined?', 1, false, false, function(x) { return x === types.UNDEFINED; }); -PRIMITIVES['void?'] = new PrimProc('void?', 1, false, false, function(x) { return x === types.VOID; }); + PRIMITIVES['undefined?'] = new PrimProc('undefined?', 1, false, false, function(x) { return x === types.UNDEFINED; }); + PRIMITIVES['void?'] = new PrimProc('void?', 1, false, false, function(x) { return x === types.VOID; }); -PRIMITIVES['immutable?'] = new PrimProc('immutable?', 1, false, false, isImmutable); + PRIMITIVES['immutable?'] = new PrimProc('immutable?', 1, false, false, isImmutable); -PRIMITIVES['symbol?'] = new PrimProc('symbol?', 1, false, false, isSymbol); -PRIMITIVES['string?'] = new PrimProc('string?', 1, false, false, isString); -PRIMITIVES['char?'] = new PrimProc('char?', 1, false, false, isChar); -PRIMITIVES['boolean?'] = new PrimProc('boolean?', 1, false, false, isBoolean); -PRIMITIVES['vector?'] = new PrimProc('vector?', 1, false, false, isVector); -PRIMITIVES['struct?'] = new PrimProc('struct?', 1, false, false, types.isStruct); -PRIMITIVES['eof-object?'] = new PrimProc('eof-object?', 1, false, false, function(x) { return x === types.EOF; }); -PRIMITIVES['posn?'] = new PrimProc('posn?', 1, false, false, types.isPosn); -PRIMITIVES['bytes?'] = new PrimProc('bytes?', 1, false, false, isByteString); -PRIMITIVES['byte?'] = new PrimProc('byte?', 1, false, false, isByte); + PRIMITIVES['symbol?'] = new PrimProc('symbol?', 1, false, false, isSymbol); + PRIMITIVES['string?'] = new PrimProc('string?', 1, false, false, isString); + PRIMITIVES['char?'] = new PrimProc('char?', 1, false, false, isChar); + PRIMITIVES['boolean?'] = new PrimProc('boolean?', 1, false, false, isBoolean); + PRIMITIVES['vector?'] = new PrimProc('vector?', 1, false, false, isVector); + PRIMITIVES['struct?'] = new PrimProc('struct?', 1, false, false, types.isStruct); + PRIMITIVES['eof-object?'] = new PrimProc('eof-object?', 1, false, false, function(x) { return x === types.EOF; }); + PRIMITIVES['posn?'] = new PrimProc('posn?', 1, false, false, types.isPosn); + PRIMITIVES['bytes?'] = new PrimProc('bytes?', 1, false, false, isByteString); + PRIMITIVES['byte?'] = new PrimProc('byte?', 1, false, false, isByte); -PRIMITIVES['number?'] = new PrimProc('number?', 1, false, false, isNumber); -PRIMITIVES['complex?'] = new PrimProc('complex?', 1, false, false, isComplex); -PRIMITIVES['real?'] = new PrimProc('real?', 1, false, false, isReal); -PRIMITIVES['rational?'] = new PrimProc('rational?', 1, false, false, isRational); -PRIMITIVES['integer?'] = new PrimProc('integer?', 1, false, false, isInteger); + PRIMITIVES['number?'] = new PrimProc('number?', 1, false, false, isNumber); + PRIMITIVES['complex?'] = new PrimProc('complex?', 1, false, false, isComplex); + PRIMITIVES['real?'] = new PrimProc('real?', 1, false, false, isReal); + PRIMITIVES['rational?'] = new PrimProc('rational?', 1, false, false, isRational); + PRIMITIVES['integer?'] = new PrimProc('integer?', 1, false, false, isInteger); -PRIMITIVES['exact?'] = - new PrimProc('exact?', 1, false, false, - function(x) { - check(x, isNumber, 'exact?', 'number', 1); - return jsnums.isExact(x); - }); -PRIMITIVES['inexact?'] = - new PrimProc('inexact?', 1, false, false, - function(x) { - check(x, isNumber, 'inexact?', 'number', 1); - return jsnums.isInexact(x); - }); + PRIMITIVES['exact?'] = + new PrimProc('exact?', 1, false, false, + function(x) { + check(x, isNumber, 'exact?', 'number', 1); + return jsnums.isExact(x); + }); + PRIMITIVES['inexact?'] = + new PrimProc('inexact?', 1, false, false, + function(x) { + check(x, isNumber, 'inexact?', 'number', 1); + return jsnums.isInexact(x); + }); -PRIMITIVES['odd?'] = - new PrimProc('odd?', - 1, - false, false, - function(x) { - check(x, isInteger, 'odd?', 'integer', 1); - return jsnums.equals(jsnums.modulo(x, 2), 1); - }); -PRIMITIVES['even?'] = - new PrimProc('even?', - 1, - false, false, - function(x) { - check(x, isInteger, 'even?', 'integer', 1); - return jsnums.equals(jsnums.modulo(x, 2), 0); - }); + PRIMITIVES['odd?'] = + new PrimProc('odd?', + 1, + false, false, + function(x) { + check(x, isInteger, 'odd?', 'integer', 1); + return jsnums.equals(jsnums.modulo(x, 2), 1); + }); + PRIMITIVES['even?'] = + new PrimProc('even?', + 1, + false, false, + function(x) { + check(x, isInteger, 'even?', 'integer', 1); + return jsnums.equals(jsnums.modulo(x, 2), 0); + }); -PRIMITIVES['zero?'] = - new PrimProc("zero?", - 1, - false, false, - function(x) { - return jsnums.equals(0, x) - }); + PRIMITIVES['zero?'] = + new PrimProc("zero?", + 1, + false, false, + function(x) { + return jsnums.equals(0, x) + }); -PRIMITIVES['positive?'] = - new PrimProc('positive?', - 1, - false, false, - function(x) { - check(x, isReal, 'positive?', 'real', 1); - return jsnums.greaterThan(x, 0); - }); -PRIMITIVES['negative?'] = - new PrimProc('negative?', - 1, - false, false, - function(x) { - check(x, isReal, 'negative?', 'real', 1); - return jsnums.lessThan(x, 0); - }); + PRIMITIVES['positive?'] = + new PrimProc('positive?', + 1, + false, false, + function(x) { + check(x, isReal, 'positive?', 'real', 1); + return jsnums.greaterThan(x, 0); + }); + PRIMITIVES['negative?'] = + new PrimProc('negative?', + 1, + false, false, + function(x) { + check(x, isReal, 'negative?', 'real', 1); + return jsnums.lessThan(x, 0); + }); -PRIMITIVES['box?'] = new PrimProc('box?', 1, false, false, isBox); + PRIMITIVES['box?'] = new PrimProc('box?', 1, false, false, isBox); -PRIMITIVES['hash?'] = new PrimProc('hash?', 1, false, false, isHash); + PRIMITIVES['hash?'] = new PrimProc('hash?', 1, false, false, isHash); -PRIMITIVES['eq?'] = new PrimProc('eq?', 2, false, false, isEq); -PRIMITIVES['eqv?'] = new PrimProc('eqv?', 2, false, false, isEqv); -PRIMITIVES['equal?'] = new PrimProc('equal?', 2, false, false, isEqual); -PRIMITIVES['equal~?'] = - new PrimProc('equal~?', - 3, - false, false, - function(x, y, range) { - check(range, isNonNegativeReal, 'equal~?', 'non-negative-real', 3, arguments); + PRIMITIVES['eq?'] = new PrimProc('eq?', 2, false, false, isEq); + PRIMITIVES['eqv?'] = new PrimProc('eqv?', 2, false, false, isEqv); + PRIMITIVES['equal?'] = new PrimProc('equal?', 2, false, false, isEqual); + PRIMITIVES['equal~?'] = + new PrimProc('equal~?', + 3, + false, false, + function(x, y, range) { + check(range, isNonNegativeReal, 'equal~?', 'non-negative-real', 3, arguments); - return (isEqual(x, y) || - (isReal(x) && isReal(y) && - jsnums.lessThanOrEqual(jsnums.abs(jsnums.subtract(x, y)), range))); - }); + return (isEqual(x, y) || + (isReal(x) && isReal(y) && + jsnums.lessThanOrEqual(jsnums.abs(jsnums.subtract(x, y)), range))); + }); -PRIMITIVES['false?'] = new PrimProc('false?', 1, false, false, function(x) { return x === false; }); -PRIMITIVES['boolean=?'] = - new PrimProc('boolean=?', - 2, - false, false, - function(x, y) { - check(x, isBoolean, 'boolean=?', 'boolean', 1, arguments); - check(y, isBoolean, 'boolean=?', 'boolean', 2, arguments); - return x === y; - }); + PRIMITIVES['false?'] = new PrimProc('false?', 1, false, false, function(x) { return x === false; }); + PRIMITIVES['boolean=?'] = + new PrimProc('boolean=?', + 2, + false, false, + function(x, y) { + check(x, isBoolean, 'boolean=?', 'boolean', 1, arguments); + check(y, isBoolean, 'boolean=?', 'boolean', 2, arguments); + return x === y; + }); -PRIMITIVES['symbol=?'] = - new PrimProc('symbol=?', - 2, - false, false, - function(x, y) { - check(x, isSymbol, 'symbol=?', 'symbol', 1, arguments); - check(y, isSymbol, 'symbol=?', 'symbol', 2, arguments); - return isEqual(x, y); - }); + PRIMITIVES['symbol=?'] = + new PrimProc('symbol=?', + 2, + false, false, + function(x, y) { + check(x, isSymbol, 'symbol=?', 'symbol', 1, arguments); + check(y, isSymbol, 'symbol=?', 'symbol', 2, arguments); + return isEqual(x, y); + }); -PRIMITIVES['js-value?'] = new PrimProc('js-value?', 1, false, false, isJsValue); -PRIMITIVES['js-object?'] = new PrimProc('js-object?', 1, false, false, isJsObject); -PRIMITIVES['js-function?'] = new PrimProc('js-function?', 1, false, false, isJsFunction); + PRIMITIVES['js-value?'] = new PrimProc('js-value?', 1, false, false, isJsValue); + PRIMITIVES['js-object?'] = new PrimProc('js-object?', 1, false, false, isJsObject); + PRIMITIVES['js-function?'] = new PrimProc('js-function?', 1, false, false, isJsFunction); -/*********************** + /*********************** *** List Primitives *** ***********************/ -PRIMITIVES['cons'] = - new PrimProc('cons', - 2, - false, false, - function(f, r) { -// checkList(r, "cons", 2); - return types.cons(f, r); - }); - - -PRIMITIVES['car'] = - new PrimProc('car', - 1, - false, false, - function(lst) { - check(lst, isPair, 'car', 'pair', 1); - return lst.first(); - }); - -PRIMITIVES['cdr'] = - new PrimProc('cdr', - 1, - false, false, - function (lst) { - check(lst, isPair, 'cdr', 'pair', 1); - return lst.rest(); - }); - -PRIMITIVES['caar'] = - new PrimProc('caar', - 1, - false, false, - function(lst) { - check(lst, function(x) { return (isPair(x) && isPair(x.first())); }, - 'caar', 'caarable value', 1); - return lst.first().first(); - }); - -PRIMITIVES['cadr'] = - new PrimProc('cadr', - 1, - false, false, - function(lst) { - check(lst, function(x) { return isPair(x) && isPair(x.rest()); }, - 'cadr', 'cadrable value', 1); - return lst.rest().first(); - }); - -PRIMITIVES['cdar'] = - new PrimProc('cdar', - 1, - false, false, - function(lst) { - check(lst, function(x) { return isPair(x) && isPair(x.first()); }, - 'cdar', 'cdarable value', 1); - return lst.first().rest(); - }); - -PRIMITIVES['cddr'] = - new PrimProc('cddr', - 1, - false, false, - function(lst) { - check(lst, function(x) { return isPair(x) && isPair(x.rest()); }, - 'cddr', 'cddrable value', 1); - return lst.rest().rest(); - }); - -PRIMITIVES['caaar'] = - new PrimProc('caaar', - 1, - false, false, - function(lst) { - check(lst, function(x) { return ( isPair(x) && - isPair(x.first()) && - isPair(x.first().first()) ); }, - 'caaar', 'caaarable value', 1); - return lst.first().first().first(); - }); - -PRIMITIVES['caadr'] = - new PrimProc('caadr', - 1, - false, false, - function(lst) { - check(lst, function(x) { return ( isPair(x) && - isPair(x.rest()) && - isPair(x.rest().first()) ); }, - 'caadr', 'caadrable value', 1); - return lst.rest().first().first(); - }); - -PRIMITIVES['cadar'] = - new PrimProc('cadar', - 1, - false, false, - function(lst) { - check(lst, function(x) { return ( isPair(x) && - isPair(x.first()) && - isPair(x.first().rest()) ); }, - 'cadar', 'cadarable value', 1); - return lst.first().rest().first(); - }); - -PRIMITIVES['cdaar'] = - new PrimProc('cdaar', - 1, - false, false, - function(lst) { - check(lst, function(x) { return ( isPair(x) && - isPair(x.first()) && - isPair(x.first().first()) ); }, - 'cdaar', 'cdaarable value', 1); - return lst.first().first().rest(); - }); - -PRIMITIVES['cdadr'] = - new PrimProc('cdadr', - 1, - false, false, - function(lst) { - check(lst, function(x) { return ( isPair(x) && - isPair(x.rest()) && - isPair(x.rest().first()) ); }, - 'cdadr', 'cdadrable value', 1); - return lst.rest().first().rest(); - }); - -PRIMITIVES['cddar'] = - new PrimProc('cddar', - 1, - false, false, - function(lst) { - check(lst, function(x) { return ( isPair(x) && - isPair(x.first()) && - isPair(x.first().rest()) ); }, - 'cddar', 'cddarable value', 1); - return lst.first().rest().rest(); - }); - -PRIMITIVES['caddr'] = - new PrimProc('caddr', - 1, - false, false, - function(lst) { - check(lst, function(x) { return ( isPair(x) && - isPair(x.rest()) && - isPair(x.rest().rest()) ); }, - 'caddr', 'caddrable value', 1); - return lst.rest().rest().first(); - }); - -PRIMITIVES['cdddr'] = - new PrimProc('cdddr', - 1, - false, false, - function(lst) { - check(lst, function(x) { return ( isPair(x) && - isPair(x.rest()) && - isPair(x.rest().rest()) ); }, - 'cdddr', 'cdddrable value', 1); - return lst.rest().rest().rest(); - }); - -PRIMITIVES['cadddr'] = - new PrimProc('cadddr', - 1, - false, false, - function(lst) { - check(lst, function(x) { return ( isPair(x) && - isPair(x.rest()) && - isPair(x.rest().rest()) && - isPair(x.rest().rest().rest()) ); }, - 'cadddr', 'cadddrable value', 1); - return lst.rest().rest().rest().first(); - }); - - -PRIMITIVES['rest'] = - new PrimProc('rest', - 1, - false, false, - function(lst) { - check(lst, function(x) { return isList(x) && !isEmpty(x); }, - 'rest', 'non-empty list', 1); - return lst.rest(); - }); - -PRIMITIVES['first'] = - new PrimProc('first', - 1, - false, false, - function(lst) { - check(lst, function(x) { return isList(x) && !isEmpty(x); }, - 'first', 'non-empty list', 1); - return lst.first(); - }); - -PRIMITIVES['second'] = - new PrimProc('second', - 1, - false, false, - function(lst) { - checkListOfLength(lst, 2, 'second', 1); - return lst.rest().first(); - }); - -PRIMITIVES['third'] = - new PrimProc('third', - 1, - false, false, - function(lst) { - checkListOfLength(lst, 3, 'third', 1); - return lst.rest().rest().first(); - }); - -PRIMITIVES['fourth'] = - new PrimProc('fourth', - 1, - false, false, - function(lst) { - checkListOfLength(lst, 4, 'fourth', 1); - return lst.rest().rest().rest().first(); - }); - -PRIMITIVES['fifth'] = - new PrimProc('fifth', - 1, - false, false, - function(lst) { - checkListOfLength(lst, 5, 'fifth', 1); - return lst.rest().rest().rest().rest().first(); - }); - -PRIMITIVES['sixth'] = - new PrimProc('sixth', - 1, - false, false, - function(lst) { - checkListOfLength(lst, 6, 'sixth', 1); - return lst.rest().rest().rest().rest().rest().first(); - }); - -PRIMITIVES['seventh'] = - new PrimProc( - 'seventh', - 1, - false, false, - function(lst) { - checkListOfLength(lst, 7, 'seventh', 1); - return lst.rest().rest().rest().rest().rest().rest().first(); - }); - -PRIMITIVES['eighth'] = - new PrimProc('eighth', - 1, - false, false, - function(lst) { - checkListOfLength(lst, 8, 'eighth', 1); - return lst.rest().rest().rest().rest().rest().rest().rest().first(); - }); - - -PRIMITIVES['length'] = - new PrimProc('length', - 1, - false, false, - function(lst) { - return jsnums.makeRational(length(lst)); - }); - - -PRIMITIVES['list?'] = new PrimProc('list?', 1, false, false, isList); - - -PRIMITIVES['list'] = - new PrimProc('list', - 0, - true, false, - types.list); - - -PRIMITIVES['list*'] = - new PrimProc('list*', - 1, - true, false, - function(anItem, otherItems) { - if (otherItems.length == 0) { - return anItem; - } - var allArgs = [anItem].concat(otherItems); - - var result = allArgs[allArgs.length - 1]; - for (var i = allArgs.length - 2 ; i >= 0; i--) { - result = types.cons(allArgs[i], result); - } - return result; - -// var lastListItem = otherItems.pop(); -// checkList(lastListItem, 'list*', otherItems.length+2, allArgs); - -// otherItems.unshift(anItem); -// return append([types.list(otherItems), lastListItem]); - }); - - -PRIMITIVES['list-ref'] = - new PrimProc('list-ref', - 2, - false, false, - function(origList, num) { - check(num, isNatural, 'list-ref', 'non-negative exact integer', 2, arguments); - - var lst = origList; - var n = jsnums.toFixnum(num); - for (var i = 0; i < n; i++) { - // According to the documentation of list-ref, we don't actually - // check the whole thing as a list. We rather do it as we walk - // along the cons chain. - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('list-ref: index ' + n + - ' is too large for list (not a proper list): ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - if (lst.isEmpty()) { - var msg = ('list-ref: index ' + n + - ' is too large for list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - lst = lst.rest(); - } - - - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('list-ref: index ' + n + - ' is too large for list (not a proper list): ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - return lst.first(); - }); - -PRIMITIVES['list-tail'] = - new PrimProc('list-tail', - 2, - false, false, - function(origList, num) { - check(num, isNatural, 'list-tail', 'non-negative exact integer', 2, arguments); - - var lst = origList; - var n = jsnums.toFixnum(num); - for (var i = 0; i < n; i++) { - // According to the documentation of list-tail, we don't actually - // check the whole thing as a list. We rather do it as we walk - // along the cons chain. - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('list-tail: index ' + n + - ' is too large for list (not a proper list): ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - if (lst.isEmpty()) { - var msg = ('list-tail: index ' + n + - ' is too large for list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - lst = lst.rest(); - } - return lst; - }); - - -PRIMITIVES['append'] = - new PrimProc('append', - 0, - true, false, - append); - - -PRIMITIVES['reverse'] = - new PrimProc('reverse', - 1, - false, false, - function(lst) { - checkList(lst, 'reverse', 1); - return lst.reverse(); - }); - - -PRIMITIVES['map'] = - new PrimProc('map', - 2, - true, false, - function(f, lst, arglists) { - var allArgs = [f, lst].concat(arglists); - arglists.unshift(lst); - check(f, isFunction, 'map', 'procedure', 1, allArgs); - arrayEach(arglists, function(x, i) {checkList(x, 'map', i+2, allArgs);}); - checkAllSameLength(arglists, 'map', allArgs); - - check(f, procArityContains(arglists.length), 'map', 'procedure (arity ' + arglists.length + ')', 1, allArgs); - - var mapHelp = function(f, args, acc) { - if (args[0].isEmpty()) { - return acc.reverse(); - } - - var argsFirst = []; - var argsRest = []; - for (var i = 0; i < args.length; i++) { - argsFirst.push(args[i].first()); - argsRest.push(args[i].rest()); - } - var result = CALL(f, argsFirst, - function(result) { - return onSingleResult(result, - function(result) { - return mapHelp(f, argsRest, types.cons(result, acc)); - }); - }); - return result; - } - return mapHelp(f, arglists, types.EMPTY); - }); - - -PRIMITIVES['andmap'] = - new PrimProc('andmap', - 2, - true, false, - function(f, lst, arglists) { - var allArgs = [f, lst].concat(arglists); - arglists.unshift(lst); - check(f, isFunction, 'andmap', 'procedure', 1, allArgs); - arrayEach(arglists, function(x, i) {checkList(x, 'andmap', i+2, allArgs);}); - checkAllSameLength(arglists, 'andmap', allArgs); - check(f, procArityContains(arglists.length), 'andmap', 'procedure (arity ' + arglists.length + ')', 1, allArgs); - - var andmapHelp = function(f, args) { - if ( args[0].isEmpty() ) { - return true; - } - - var argsFirst = []; - var argsRest = []; - for (var i = 0; i < args.length; i++) { - argsFirst.push(args[i].first()); - argsRest.push(args[i].rest()); - } - - return CALL(f, argsFirst, - function(result) { - if (argsRest[0].isEmpty()) { - return result; - } - return onSingleResult(result, - function(result) { - - return result && andmapHelp(f, argsRest); - }); - }); - } - return andmapHelp(f, arglists); - }); - - -PRIMITIVES['ormap'] = - new PrimProc('ormap', - 2, - true, false, - function(f, lst, arglists) { - var allArgs = [f, lst].concat(arglists); - arglists.unshift(lst); - check(f, isFunction, 'ormap', 'procedure', 1, allArgs); - arrayEach(arglists, function(x, i) {checkList(x, 'ormap', i+2, allArgs);}); - checkAllSameLength(arglists, 'ormap', allArgs); - - check(f, procArityContains(arglists.length), 'ormap', 'procedure (arity ' + arglists.length + ')', 1, allArgs); - - var ormapHelp = function(f, args) { - if ( args[0].isEmpty() ) { - return false; - } - - var argsFirst = []; - var argsRest = []; - for (var i = 0; i < args.length; i++) { - argsFirst.push(args[i].first()); - argsRest.push(args[i].rest()); - } - - return CALL(f, argsFirst, - function(result) { - if (argsRest[0].isEmpty()) { - return result; - } - return onSingleResult( - result, - function(result) { - return result || ormapHelp(f, argsRest); - }); - }); - } - return ormapHelp(f, arglists); - }); - - -PRIMITIVES['memq'] = - new PrimProc('memq', - 2, - false, false, - function(item, origList) { - var lst = origList; - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('memq: not a proper list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - while ( !lst.isEmpty() ) { - - if ( isEq(item, lst.first()) ) { - return lst; - } - lst = lst.rest(); - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('memq: not a proper list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - } - return false; - }); - - -PRIMITIVES['memv'] = - new PrimProc('memv', - 2, - false, false, - function(item, origList) { - var lst = origList; - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('memv: not a proper list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - while ( !lst.isEmpty() ) { - if ( isEqv(item, lst.first()) ) { - return lst; - } - lst = lst.rest(); - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('memv: not a proper list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - } - return false; - }); - - -PRIMITIVES['member'] = - new PrimProc('member', - 2, - false, false, - function(item, origList) { - var lst = origList; - //checkList(lst, 'member', 2, arguments); - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('member: not a proper list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - while ( !lst.isEmpty() ) { - if ( isEqual(item, lst.first()) ) { - return lst; - } - lst = lst.rest(); - - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('member: not a proper list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - } - return false; - }); - - -PRIMITIVES['memf'] = - new PrimProc('memf', - 2, - false, false, - function(f, initList) { - check(f, isFunction, 'memf', 'procedure', 1, arguments); - checkList(initList, 'memf', 2, arguments); - - var memfHelp = function(lst) { - if ( lst.isEmpty() ) { - return false; - } - - return CALL(f, [lst.first()], - function(result) { - if (result) { - return lst; - } - return memfHelp(lst.rest()); - }); - } - return memfHelp(initList); - }); - - -PRIMITIVES['assq'] = - new PrimProc('assq', - 2, - false, false, - function(item, origList) { - var lst = origList; - // checkListOf(lst, isPair, 'assq', 'pair', 2, arguments); - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('assq: not a proper list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - while ( !lst.isEmpty() ) { - if (! isPair(lst.first())) { - var msg = ('assq: non-pair found in list: ' + - types.toWrittenString(lst.first()) +' in ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - if ( isEq(item, lst.first().first()) ) { - return lst.first(); - } - lst = lst.rest(); - - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('assq: not a proper list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - } - return false; - }); - - -PRIMITIVES['assv'] = - new PrimProc('assv', - 2, - false, false, - function(item, origList) { - //checkListOf(lst, isPair, 'assv', 'pair', 2, arguments); - var lst = origList; - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('assv: not a proper list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - while ( !lst.isEmpty() ) { - if (! isPair(lst.first())) { - var msg = ('assv: non-pair found in list: ' + - types.toWrittenString(lst.first()) +' in ' + - types.toWrittenString(origList)); + PRIMITIVES['cons'] = + new PrimProc('cons', + 2, + false, false, + function(f, r) { + // checkList(r, "cons", 2); + return types.cons(f, r); + }); + + + PRIMITIVES['car'] = + new PrimProc('car', + 1, + false, false, + function(lst) { + check(lst, isPair, 'car', 'pair', 1); + return lst.first(); + }); + + PRIMITIVES['cdr'] = + new PrimProc('cdr', + 1, + false, false, + function (lst) { + check(lst, isPair, 'cdr', 'pair', 1); + return lst.rest(); + }); + + PRIMITIVES['caar'] = + new PrimProc('caar', + 1, + false, false, + function(lst) { + check(lst, function(x) { return (isPair(x) && isPair(x.first())); }, + 'caar', 'caarable value', 1); + return lst.first().first(); + }); + + PRIMITIVES['cadr'] = + new PrimProc('cadr', + 1, + false, false, + function(lst) { + check(lst, function(x) { return isPair(x) && isPair(x.rest()); }, + 'cadr', 'cadrable value', 1); + return lst.rest().first(); + }); + + PRIMITIVES['cdar'] = + new PrimProc('cdar', + 1, + false, false, + function(lst) { + check(lst, function(x) { return isPair(x) && isPair(x.first()); }, + 'cdar', 'cdarable value', 1); + return lst.first().rest(); + }); + + PRIMITIVES['cddr'] = + new PrimProc('cddr', + 1, + false, false, + function(lst) { + check(lst, function(x) { return isPair(x) && isPair(x.rest()); }, + 'cddr', 'cddrable value', 1); + return lst.rest().rest(); + }); + + PRIMITIVES['caaar'] = + new PrimProc('caaar', + 1, + false, false, + function(lst) { + check(lst, function(x) { return ( isPair(x) && + isPair(x.first()) && + isPair(x.first().first()) ); }, + 'caaar', 'caaarable value', 1); + return lst.first().first().first(); + }); + + PRIMITIVES['caadr'] = + new PrimProc('caadr', + 1, + false, false, + function(lst) { + check(lst, function(x) { return ( isPair(x) && + isPair(x.rest()) && + isPair(x.rest().first()) ); }, + 'caadr', 'caadrable value', 1); + return lst.rest().first().first(); + }); + + PRIMITIVES['cadar'] = + new PrimProc('cadar', + 1, + false, false, + function(lst) { + check(lst, function(x) { return ( isPair(x) && + isPair(x.first()) && + isPair(x.first().rest()) ); }, + 'cadar', 'cadarable value', 1); + return lst.first().rest().first(); + }); + + PRIMITIVES['cdaar'] = + new PrimProc('cdaar', + 1, + false, false, + function(lst) { + check(lst, function(x) { return ( isPair(x) && + isPair(x.first()) && + isPair(x.first().first()) ); }, + 'cdaar', 'cdaarable value', 1); + return lst.first().first().rest(); + }); + + PRIMITIVES['cdadr'] = + new PrimProc('cdadr', + 1, + false, false, + function(lst) { + check(lst, function(x) { return ( isPair(x) && + isPair(x.rest()) && + isPair(x.rest().first()) ); }, + 'cdadr', 'cdadrable value', 1); + return lst.rest().first().rest(); + }); + + PRIMITIVES['cddar'] = + new PrimProc('cddar', + 1, + false, false, + function(lst) { + check(lst, function(x) { return ( isPair(x) && + isPair(x.first()) && + isPair(x.first().rest()) ); }, + 'cddar', 'cddarable value', 1); + return lst.first().rest().rest(); + }); + + PRIMITIVES['caddr'] = + new PrimProc('caddr', + 1, + false, false, + function(lst) { + check(lst, function(x) { return ( isPair(x) && + isPair(x.rest()) && + isPair(x.rest().rest()) ); }, + 'caddr', 'caddrable value', 1); + return lst.rest().rest().first(); + }); + + PRIMITIVES['cdddr'] = + new PrimProc('cdddr', + 1, + false, false, + function(lst) { + check(lst, function(x) { return ( isPair(x) && + isPair(x.rest()) && + isPair(x.rest().rest()) ); }, + 'cdddr', 'cdddrable value', 1); + return lst.rest().rest().rest(); + }); + + PRIMITIVES['cadddr'] = + new PrimProc('cadddr', + 1, + false, false, + function(lst) { + check(lst, function(x) { return ( isPair(x) && + isPair(x.rest()) && + isPair(x.rest().rest()) && + isPair(x.rest().rest().rest()) ); }, + 'cadddr', 'cadddrable value', 1); + return lst.rest().rest().rest().first(); + }); + + + PRIMITIVES['rest'] = + new PrimProc('rest', + 1, + false, false, + function(lst) { + check(lst, function(x) { return isList(x) && !isEmpty(x); }, + 'rest', 'non-empty list', 1); + return lst.rest(); + }); + + PRIMITIVES['first'] = + new PrimProc('first', + 1, + false, false, + function(lst) { + check(lst, function(x) { return isList(x) && !isEmpty(x); }, + 'first', 'non-empty list', 1); + return lst.first(); + }); + + PRIMITIVES['second'] = + new PrimProc('second', + 1, + false, false, + function(lst) { + checkListOfLength(lst, 2, 'second', 1); + return lst.rest().first(); + }); + + PRIMITIVES['third'] = + new PrimProc('third', + 1, + false, false, + function(lst) { + checkListOfLength(lst, 3, 'third', 1); + return lst.rest().rest().first(); + }); + + PRIMITIVES['fourth'] = + new PrimProc('fourth', + 1, + false, false, + function(lst) { + checkListOfLength(lst, 4, 'fourth', 1); + return lst.rest().rest().rest().first(); + }); + + PRIMITIVES['fifth'] = + new PrimProc('fifth', + 1, + false, false, + function(lst) { + checkListOfLength(lst, 5, 'fifth', 1); + return lst.rest().rest().rest().rest().first(); + }); + + PRIMITIVES['sixth'] = + new PrimProc('sixth', + 1, + false, false, + function(lst) { + checkListOfLength(lst, 6, 'sixth', 1); + return lst.rest().rest().rest().rest().rest().first(); + }); + + PRIMITIVES['seventh'] = + new PrimProc( + 'seventh', + 1, + false, false, + function(lst) { + checkListOfLength(lst, 7, 'seventh', 1); + return lst.rest().rest().rest().rest().rest().rest().first(); + }); + + PRIMITIVES['eighth'] = + new PrimProc('eighth', + 1, + false, false, + function(lst) { + checkListOfLength(lst, 8, 'eighth', 1); + return lst.rest().rest().rest().rest().rest().rest().rest().first(); + }); + + + PRIMITIVES['length'] = + new PrimProc('length', + 1, + false, false, + function(lst) { + return jsnums.makeRational(length(lst)); + }); + + + PRIMITIVES['list?'] = new PrimProc('list?', 1, false, false, isList); + + + PRIMITIVES['list'] = + new PrimProc('list', + 0, + true, false, + types.list); + + + PRIMITIVES['list*'] = + new PrimProc('list*', + 1, + true, false, + function(anItem, otherItems) { + if (otherItems.length == 0) { + return anItem; + } + var allArgs = [anItem].concat(otherItems); + + var result = allArgs[allArgs.length - 1]; + for (var i = allArgs.length - 2 ; i >= 0; i--) { + result = types.cons(allArgs[i], result); + } + return result; + + // var lastListItem = otherItems.pop(); + // checkList(lastListItem, 'list*', otherItems.length+2, allArgs); + + // otherItems.unshift(anItem); + // return append([types.list(otherItems), lastListItem]); + }); + + + PRIMITIVES['list-ref'] = + new PrimProc('list-ref', + 2, + false, false, + function(origList, num) { + check(num, isNatural, 'list-ref', 'non-negative exact integer', 2, arguments); + + var lst = origList; + var n = jsnums.toFixnum(num); + for (var i = 0; i < n; i++) { + // According to the documentation of list-ref, we don't actually + // check the whole thing as a list. We rather do it as we walk + // along the cons chain. + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('list-ref: index ' + n + + ' is too large for list (not a proper list): ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + if (lst.isEmpty()) { + var msg = ('list-ref: index ' + n + + ' is too large for list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + lst = lst.rest(); + } + + + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('list-ref: index ' + n + + ' is too large for list (not a proper list): ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + return lst.first(); + }); + + PRIMITIVES['list-tail'] = + new PrimProc('list-tail', + 2, + false, false, + function(origList, num) { + check(num, isNatural, 'list-tail', 'non-negative exact integer', 2, arguments); + + var lst = origList; + var n = jsnums.toFixnum(num); + for (var i = 0; i < n; i++) { + // According to the documentation of list-tail, we don't actually + // check the whole thing as a list. We rather do it as we walk + // along the cons chain. + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('list-tail: index ' + n + + ' is too large for list (not a proper list): ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + if (lst.isEmpty()) { + var msg = ('list-tail: index ' + n + + ' is too large for list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + lst = lst.rest(); + } + return lst; + }); + + + PRIMITIVES['append'] = + new PrimProc('append', + 0, + true, false, + append); + + + PRIMITIVES['reverse'] = + new PrimProc('reverse', + 1, + false, false, + function(lst) { + checkList(lst, 'reverse', 1); + return lst.reverse(); + }); + + + PRIMITIVES['map'] = + new PrimProc('map', + 2, + true, false, + function(f, lst, arglists) { + var allArgs = [f, lst].concat(arglists); + arglists.unshift(lst); + check(f, isFunction, 'map', 'procedure', 1, allArgs); + arrayEach(arglists, function(x, i) {checkList(x, 'map', i+2, allArgs);}); + checkAllSameLength(arglists, 'map', allArgs); + + check(f, procArityContains(arglists.length), 'map', 'procedure (arity ' + arglists.length + ')', 1, allArgs); + + var mapHelp = function(f, args, acc) { + if (args[0].isEmpty()) { + return acc.reverse(); + } + + var argsFirst = []; + var argsRest = []; + for (var i = 0; i < args.length; i++) { + argsFirst.push(args[i].first()); + argsRest.push(args[i].rest()); + } + var result = CALL(f, argsFirst, + function(result) { + return onSingleResult(result, + function(result) { + return mapHelp(f, argsRest, types.cons(result, acc)); + }); + }); + return result; + } + return mapHelp(f, arglists, types.EMPTY); + }); + + + PRIMITIVES['andmap'] = + new PrimProc('andmap', + 2, + true, false, + function(f, lst, arglists) { + var allArgs = [f, lst].concat(arglists); + arglists.unshift(lst); + check(f, isFunction, 'andmap', 'procedure', 1, allArgs); + arrayEach(arglists, function(x, i) {checkList(x, 'andmap', i+2, allArgs);}); + checkAllSameLength(arglists, 'andmap', allArgs); + check(f, procArityContains(arglists.length), 'andmap', 'procedure (arity ' + arglists.length + ')', 1, allArgs); + + var andmapHelp = function(f, args) { + if ( args[0].isEmpty() ) { + return true; + } + + var argsFirst = []; + var argsRest = []; + for (var i = 0; i < args.length; i++) { + argsFirst.push(args[i].first()); + argsRest.push(args[i].rest()); + } + + return CALL(f, argsFirst, + function(result) { + if (argsRest[0].isEmpty()) { + return result; + } + return onSingleResult(result, + function(result) { + + return result && andmapHelp(f, argsRest); + }); + }); + } + return andmapHelp(f, arglists); + }); + + + PRIMITIVES['ormap'] = + new PrimProc('ormap', + 2, + true, false, + function(f, lst, arglists) { + var allArgs = [f, lst].concat(arglists); + arglists.unshift(lst); + check(f, isFunction, 'ormap', 'procedure', 1, allArgs); + arrayEach(arglists, function(x, i) {checkList(x, 'ormap', i+2, allArgs);}); + checkAllSameLength(arglists, 'ormap', allArgs); + + check(f, procArityContains(arglists.length), 'ormap', 'procedure (arity ' + arglists.length + ')', 1, allArgs); + + var ormapHelp = function(f, args) { + if ( args[0].isEmpty() ) { + return false; + } + + var argsFirst = []; + var argsRest = []; + for (var i = 0; i < args.length; i++) { + argsFirst.push(args[i].first()); + argsRest.push(args[i].rest()); + } + + return CALL(f, argsFirst, + function(result) { + if (argsRest[0].isEmpty()) { + return result; + } + return onSingleResult( + result, + function(result) { + return result || ormapHelp(f, argsRest); + }); + }); + } + return ormapHelp(f, arglists); + }); + + + PRIMITIVES['memq'] = + new PrimProc('memq', + 2, + false, false, + function(item, origList) { + var lst = origList; + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('memq: not a proper list: ' + + types.toWrittenString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, - []) ); + []) ); + } + while ( !lst.isEmpty() ) { + + if ( isEq(item, lst.first()) ) { + return lst; + } + lst = lst.rest(); + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('memq: not a proper list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } } - if ( isEqv(item, lst.first().first()) ) { - return lst.first(); - } - lst = lst.rest(); + return false; + }); + + + PRIMITIVES['memv'] = + new PrimProc('memv', + 2, + false, false, + function(item, origList) { + var lst = origList; if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('assv: not a proper list: ' + + var msg = ('memv: not a proper list: ' + types.toWrittenString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } - } - return false; - }); + while ( !lst.isEmpty() ) { + if ( isEqv(item, lst.first()) ) { + return lst; + } + lst = lst.rest(); + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('memv: not a proper list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + } + return false; + }); -PRIMITIVES['assoc'] = - new PrimProc('assoc', - 2, - false, false, - function(item, origList) { - var lst = origList; - //checkListOf(lst, isPair, 'assoc', 'pair', 2, arguments); - if (! isPair(lst) && lst !== types.EMPTY) { + PRIMITIVES['member'] = + new PrimProc('member', + 2, + false, false, + function(item, origList) { + var lst = origList; + //checkList(lst, 'member', 2, arguments); + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('member: not a proper list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + while ( !lst.isEmpty() ) { + if ( isEqual(item, lst.first()) ) { + return lst; + } + lst = lst.rest(); + + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('member: not a proper list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + } + return false; + }); + + + PRIMITIVES['memf'] = + new PrimProc('memf', + 2, + false, false, + function(f, initList) { + check(f, isFunction, 'memf', 'procedure', 1, arguments); + checkList(initList, 'memf', 2, arguments); + + var memfHelp = function(lst) { + if ( lst.isEmpty() ) { + return false; + } + + return CALL(f, [lst.first()], + function(result) { + if (result) { + return lst; + } + return memfHelp(lst.rest()); + }); + } + return memfHelp(initList); + }); + + + PRIMITIVES['assq'] = + new PrimProc('assq', + 2, + false, false, + function(item, origList) { + var lst = origList; + // checkListOf(lst, isPair, 'assq', 'pair', 2, arguments); + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('assq: not a proper list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + while ( !lst.isEmpty() ) { + if (! isPair(lst.first())) { + var msg = ('assq: non-pair found in list: ' + + types.toWrittenString(lst.first()) +' in ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + if ( isEq(item, lst.first().first()) ) { + return lst.first(); + } + lst = lst.rest(); + + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('assq: not a proper list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + } + return false; + }); + + + PRIMITIVES['assv'] = + new PrimProc('assv', + 2, + false, false, + function(item, origList) { + //checkListOf(lst, isPair, 'assv', 'pair', 2, arguments); + var lst = origList; + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('assv: not a proper list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + while ( !lst.isEmpty() ) { + if (! isPair(lst.first())) { + var msg = ('assv: non-pair found in list: ' + + types.toWrittenString(lst.first()) +' in ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + if ( isEqv(item, lst.first().first()) ) { + return lst.first(); + } + lst = lst.rest(); + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('assv: not a proper list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + } + return false; + }); + + + PRIMITIVES['assoc'] = + new PrimProc('assoc', + 2, + false, false, + function(item, origList) { + var lst = origList; + //checkListOf(lst, isPair, 'assoc', 'pair', 2, arguments); + if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('assoc: not a proper list: ' + types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - while ( !lst.isEmpty() ) { - if (! isPair(lst.first())) { - var msg = ('assoc: non-pair found in list: ' + - types.toWrittenString(lst.first()) +' in ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - if ( isEqual(item, lst.first().first()) ) { - return lst.first(); - } - lst = lst.rest(); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + while ( !lst.isEmpty() ) { + if (! isPair(lst.first())) { + var msg = ('assoc: non-pair found in list: ' + + types.toWrittenString(lst.first()) +' in ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + if ( isEqual(item, lst.first().first()) ) { + return lst.first(); + } + lst = lst.rest(); - if (! isPair(lst) && lst !== types.EMPTY) { - var msg = ('assoc: not a proper list: ' + - types.toWrittenString(origList)); - raise( types.incompleteExn(types.exnFailContract, - msg, - []) ); - } - } - return false; - }); + if (! isPair(lst) && lst !== types.EMPTY) { + var msg = ('assoc: not a proper list: ' + + types.toWrittenString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + } + return false; + }); -PRIMITIVES['remove'] = - new PrimProc('remove', - 2, - false, false, - function(item, lst) { - checkList(lst, 'remove', 2, arguments); - var originalLst = lst; - var result = types.EMPTY; - while ( !lst.isEmpty() ) { - if ( isEqual(item, lst.first()) ) { - return append([result.reverse(), lst.rest()]); - } else { - result = types.cons(lst.first(), result); - lst = lst.rest(); - } - } - return originalLst; - }); + PRIMITIVES['remove'] = + new PrimProc('remove', + 2, + false, false, + function(item, lst) { + checkList(lst, 'remove', 2, arguments); + var originalLst = lst; + var result = types.EMPTY; + while ( !lst.isEmpty() ) { + if ( isEqual(item, lst.first()) ) { + return append([result.reverse(), lst.rest()]); + } else { + result = types.cons(lst.first(), result); + lst = lst.rest(); + } + } + return originalLst; + }); -PRIMITIVES['filter'] = - new PrimProc('filter', - 2, - false, false, - function(f, lst) { - check(f, procArityContains(1), 'filter', 'procedure (arity 1)', 1, arguments); - checkList(lst, 'filter', 2); + PRIMITIVES['filter'] = + new PrimProc('filter', + 2, + false, false, + function(f, lst) { + check(f, procArityContains(1), 'filter', 'procedure (arity 1)', 1, arguments); + checkList(lst, 'filter', 2); - var filterHelp = function(f, lst, acc) { - if ( lst.isEmpty() ) { - return acc.reverse(); - } + var filterHelp = function(f, lst, acc) { + if ( lst.isEmpty() ) { + return acc.reverse(); + } - return CALL(f, [lst.first()], - function(result) { - if (result) { - return filterHelp(f, lst.rest(), - types.cons(lst.first(), acc)); - } - else { - return filterHelp(f, lst.rest(), acc); - } - }); - } - return filterHelp(f, lst, types.EMPTY); - }); + return CALL(f, [lst.first()], + function(result) { + if (result) { + return filterHelp(f, lst.rest(), + types.cons(lst.first(), acc)); + } + else { + return filterHelp(f, lst.rest(), acc); + } + }); + } + return filterHelp(f, lst, types.EMPTY); + }); -PRIMITIVES['foldl'] = - new PrimProc('foldl', - 3, - true, false, - function(f, initAcc, lst, arglists) { - arglists.unshift(lst); - var allArgs = [f, initAcc].concat(arglists); - check(f, isFunction, 'foldl', 'procedure', 1, allArgs); - arrayEach(arglists, function(x, i) {checkList(x, 'foldl', i+3, allArgs);}); - checkAllSameLength(arglists, 'foldl', allArgs); - - return foldHelp(f, initAcc, arglists); - }); + PRIMITIVES['foldl'] = + new PrimProc('foldl', + 3, + true, false, + function(f, initAcc, lst, arglists) { + arglists.unshift(lst); + var allArgs = [f, initAcc].concat(arglists); + check(f, isFunction, 'foldl', 'procedure', 1, allArgs); + arrayEach(arglists, function(x, i) {checkList(x, 'foldl', i+3, allArgs);}); + checkAllSameLength(arglists, 'foldl', allArgs); + + return foldHelp(f, initAcc, arglists); + }); -PRIMITIVES['foldr'] = - new PrimProc('foldr', - 3, - true, false, - function(f, initAcc, lst, arglists) { - arglists.unshift(lst); - var allArgs = [f, initAcc].concat(arglists); - check(f, isFunction, 'foldr', 'procedure', 1, allArgs); - arrayEach(arglists, function(x, i) {checkList(x, 'foldr', i+3, allArgs);}); - checkAllSameLength(arglists, 'foldr', allArgs); + PRIMITIVES['foldr'] = + new PrimProc('foldr', + 3, + true, false, + function(f, initAcc, lst, arglists) { + arglists.unshift(lst); + var allArgs = [f, initAcc].concat(arglists); + check(f, isFunction, 'foldr', 'procedure', 1, allArgs); + arrayEach(arglists, function(x, i) {checkList(x, 'foldr', i+3, allArgs);}); + checkAllSameLength(arglists, 'foldr', allArgs); - for (var i = 0; i < arglists.length; i++) { - arglists[i] = arglists[i].reverse(); - } - - return foldHelp(f, initAcc, arglists); - }); + for (var i = 0; i < arglists.length; i++) { + arglists[i] = arglists[i].reverse(); + } + + return foldHelp(f, initAcc, arglists); + }); -PRIMITIVES['quicksort'] = new PrimProc('quicksort', 2, false, false, quicksort('quicksort')); -PRIMITIVES['sort'] = new PrimProc('sort', 2, false, false, quicksort('sort')); + PRIMITIVES['quicksort'] = new PrimProc('quicksort', 2, false, false, quicksort('quicksort')); + PRIMITIVES['sort'] = new PrimProc('sort', 2, false, false, quicksort('sort')); -PRIMITIVES['argmax'] = - new PrimProc('argmax', - 2, - false, false, - function(f, initList) { - var args = arguments - check(f, isFunction, 'argmax', 'procedure', 1, args); - check(initList, isPair, 'argmax', 'non-empty list', 2, args); + PRIMITIVES['argmax'] = + new PrimProc('argmax', + 2, + false, false, + function(f, initList) { + var args = arguments + check(f, isFunction, 'argmax', 'procedure', 1, args); + check(initList, isPair, 'argmax', 'non-empty list', 2, args); - var argmaxHelp = function(lst, curMaxVal, curMaxElt) { - if ( lst.isEmpty() ) { - return curMaxElt; - } + var argmaxHelp = function(lst, curMaxVal, curMaxElt) { + if ( lst.isEmpty() ) { + return curMaxElt; + } - return CALL(f, [lst.first()], - function(result) { - check(result, isReal, 'argmax', - 'procedure that returns real numbers', 1, args); - if (jsnums.greaterThan(result, curMaxVal)) { - return argmaxHelp(lst.rest(), result, lst.first()); - } - else { - return argmaxHelp(lst.rest(), curMaxVal, curMaxElt); - } - }); - } - return CALL(f, [initList.first()], - function(result) { - check(result, isReal, 'argmax', 'procedure that returns real numbers', 1, args); - return argmaxHelp(initList.rest(), result, initList.first()); - }); - }); + return CALL(f, [lst.first()], + function(result) { + check(result, isReal, 'argmax', + 'procedure that returns real numbers', 1, args); + if (jsnums.greaterThan(result, curMaxVal)) { + return argmaxHelp(lst.rest(), result, lst.first()); + } + else { + return argmaxHelp(lst.rest(), curMaxVal, curMaxElt); + } + }); + } + return CALL(f, [initList.first()], + function(result) { + check(result, isReal, 'argmax', 'procedure that returns real numbers', 1, args); + return argmaxHelp(initList.rest(), result, initList.first()); + }); + }); -PRIMITIVES['argmin'] = - new PrimProc('argmin', - 2, - false, false, - function(f, initList) { - var args = arguments; - check(f, isFunction, 'argmin', 'procedure', 1, args); - check(initList, isPair, 'argmin', 'non-empty list', 2, args); + PRIMITIVES['argmin'] = + new PrimProc('argmin', + 2, + false, false, + function(f, initList) { + var args = arguments; + check(f, isFunction, 'argmin', 'procedure', 1, args); + check(initList, isPair, 'argmin', 'non-empty list', 2, args); - var argminHelp = function(lst, curMaxVal, curMaxElt) { - if ( lst.isEmpty() ) { - return curMaxElt; - } + var argminHelp = function(lst, curMaxVal, curMaxElt) { + if ( lst.isEmpty() ) { + return curMaxElt; + } - return CALL(f, [lst.first()], - function(result) { - check(result, isReal, 'argmin', - 'procedure that returns real numbers', 1, args); - if (jsnums.lessThan(result, curMaxVal)) { - return argminHelp(lst.rest(), result, lst.first()); - } - else { - return argminHelp(lst.rest(), curMaxVal, curMaxElt); - } - }); - } - return CALL(f, [initList.first()], - function(result) { - check(result, isReal, 'argmin', 'procedure that returns real numbers', 1, args); - return argminHelp(initList.rest(), result, initList.first()); - }); - }); + return CALL(f, [lst.first()], + function(result) { + check(result, isReal, 'argmin', + 'procedure that returns real numbers', 1, args); + if (jsnums.lessThan(result, curMaxVal)) { + return argminHelp(lst.rest(), result, lst.first()); + } + else { + return argminHelp(lst.rest(), curMaxVal, curMaxElt); + } + }); + } + return CALL(f, [initList.first()], + function(result) { + check(result, isReal, 'argmin', 'procedure that returns real numbers', 1, args); + return argminHelp(initList.rest(), result, initList.first()); + }); + }); -PRIMITIVES['build-list'] = - new PrimProc('build-list', - 2, - false, false, - function(num, f) { - check(num, isNatural, 'build-list', 'non-negative exact integer', 1, arguments); - check(f, isFunction, 'build-list', 'procedure', 2, arguments); + PRIMITIVES['build-list'] = + new PrimProc('build-list', + 2, + false, false, + function(num, f) { + check(num, isNatural, 'build-list', 'non-negative exact integer', 1, arguments); + check(f, isFunction, 'build-list', 'procedure', 2, arguments); - var buildListHelp = function(n, acc) { - if ( jsnums.greaterThanOrEqual(n, num) ) { - return acc.reverse(); - } + var buildListHelp = function(n, acc) { + if ( jsnums.greaterThanOrEqual(n, num) ) { + return acc.reverse(); + } - return CALL(f, [n], - function (result) { - return buildListHelp(n+1, types.cons(result, acc)); - }); - } - return buildListHelp(0, types.EMPTY); - }); + return CALL(f, [n], + function (result) { + return buildListHelp(n+1, types.cons(result, acc)); + }); + } + return buildListHelp(0, types.EMPTY); + }); -/********************** + /********************** *** Box Primitives *** **********************/ -PRIMITIVES['box'] = new PrimProc('box', 1, false, false, types.box); + PRIMITIVES['box'] = new PrimProc('box', 1, false, false, types.box); -PRIMITIVES['box-immutable'] = new PrimProc('box-immutable', 1, false, false, types.boxImmutable); + PRIMITIVES['box-immutable'] = new PrimProc('box-immutable', 1, false, false, types.boxImmutable); -PRIMITIVES['unbox'] = - new PrimProc('unbox', - 1, - false, false, - function(box) { - check(box, isBox, 'unbox', 'box', 1); - return box.unbox(); - }); + PRIMITIVES['unbox'] = + new PrimProc('unbox', + 1, + false, false, + function(box) { + check(box, isBox, 'unbox', 'box', 1); + return box.unbox(); + }); -PRIMITIVES['set-box!'] = - new PrimProc('set-box!', - 2, - false, false, - function(box, newVal) { - check(box, function(x) { return isBox(x) && x.mutable; }, 'set-box!', 'mutable box', 1, arguments); - box.set(newVal); - return types.VOID; - }); + PRIMITIVES['set-box!'] = + new PrimProc('set-box!', + 2, + false, false, + function(box, newVal) { + check(box, function(x) { return isBox(x) && x.mutable; }, 'set-box!', 'mutable box', 1, arguments); + box.set(newVal); + return types.VOID; + }); -/**************************** + /**************************** *** Hashtable Primitives *** ****************************/ -PRIMITIVES['make-hash'] = + PRIMITIVES['make-hash'] = new CasePrimitive('make-hash', - [new PrimProc('make-hash', 0, false, false, function() { return types.hash(types.EMPTY); }), - new PrimProc('make-hash', - 1, - false, false, - function(lst) { - checkListOf(lst, isPair, 'make-hash', 'list of pairs', 1); - return types.hash(lst); - }) ]); + [new PrimProc('make-hash', 0, false, false, function() { return types.hash(types.EMPTY); }), + new PrimProc('make-hash', + 1, + false, false, + function(lst) { + checkListOf(lst, isPair, 'make-hash', 'list of pairs', 1); + return types.hash(lst); + }) ]); -PRIMITIVES['make-hasheq'] = + PRIMITIVES['make-hasheq'] = new CasePrimitive('make-hasheq', - [new PrimProc('make-hasheq', 0, false, false, function() { return types.hashEq(types.EMPTY); }), - new PrimProc('make-hasheq', - 1, - false, false, - function(lst) { - checkListOf(lst, isPair, 'make-hasheq', 'list of pairs', 1); - return types.hashEq(lst); - }) ]); + [new PrimProc('make-hasheq', 0, false, false, function() { return types.hashEq(types.EMPTY); }), + new PrimProc('make-hasheq', + 1, + false, false, + function(lst) { + checkListOf(lst, isPair, 'make-hasheq', 'list of pairs', 1); + return types.hashEq(lst); + }) ]); -PRIMITIVES['hash-set!'] = - new PrimProc('hash-set!', - 3, - false, false, - function(obj, key, val) { - check(obj, isHash, 'hash-set!', 'hash', 1, arguments); - obj.hash.put(key, val); - return types.VOID; - }); + PRIMITIVES['hash-set!'] = + new PrimProc('hash-set!', + 3, + false, false, + function(obj, key, val) { + check(obj, isHash, 'hash-set!', 'hash', 1, arguments); + obj.hash.put(key, val); + return types.VOID; + }); -PRIMITIVES['hash-ref'] = + PRIMITIVES['hash-ref'] = new CasePrimitive('hash-ref', - [new PrimProc('hash-ref', - 2, - false, false, - function(obj, key) { - check(obj, isHash, 'hash-ref', 'hash', 1, arguments); + [new PrimProc('hash-ref', + 2, + false, false, + function(obj, key) { + check(obj, isHash, 'hash-ref', 'hash', 1, arguments); - if ( !obj.hash.containsKey(key) ) { - var msg = 'hash-ref: no value found for key: ' + types.toWrittenString(key); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - return obj.hash.get(key); - }), - new PrimProc('hash-ref', - 3, - false, false, - function(obj, key, defaultVal) { - check(obj, isHash, 'hash-ref', 'hash', 1, arguments); + if ( !obj.hash.containsKey(key) ) { + var msg = 'hash-ref: no value found for key: ' + types.toWrittenString(key); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + return obj.hash.get(key); + }), + new PrimProc('hash-ref', + 3, + false, false, + function(obj, key, defaultVal) { + check(obj, isHash, 'hash-ref', 'hash', 1, arguments); - if (obj.hash.containsKey(key)) { - return obj.hash.get(key); - } - else { - if (isFunction(defaultVal)) { - return CALL(defaultVal, [], id); - } - return defaultVal; - } - }) ]); + if (obj.hash.containsKey(key)) { + return obj.hash.get(key); + } + else { + if (isFunction(defaultVal)) { + return CALL(defaultVal, [], id); + } + return defaultVal; + } + }) ]); -PRIMITIVES['hash-remove!'] = - new PrimProc('hash-remove', - 2, - false, false, - function(obj, key) { - check(obj, isHash, 'hash-remove!', 'hash', 1, arguments); - obj.hash.remove(key); - return types.VOID; - }); + PRIMITIVES['hash-remove!'] = + new PrimProc('hash-remove', + 2, + false, false, + function(obj, key) { + check(obj, isHash, 'hash-remove!', 'hash', 1, arguments); + obj.hash.remove(key); + return types.VOID; + }); -PRIMITIVES['hash-map'] = - new PrimProc('hash-map', - 2, - false, false, - function(ht, f) { - check(ht, isHash, 'hash-map', 'hash', 1, arguments); - check(f, isFunction, 'hash-map', 'procedure', 2, arguments); - - var keys = ht.hash.keys(); - var hashMapHelp = function(i, acc) { - if (i >= keys.length) { - return acc; - } + PRIMITIVES['hash-map'] = + new PrimProc('hash-map', + 2, + false, false, + function(ht, f) { + check(ht, isHash, 'hash-map', 'hash', 1, arguments); + check(f, isFunction, 'hash-map', 'procedure', 2, arguments); + + var keys = ht.hash.keys(); + var hashMapHelp = function(i, acc) { + if (i >= keys.length) { + return acc; + } - var val = ht.hash.get(keys[i]); - return CALL(f, [keys[i], val], - function(result) { - return hashMapHelp(i+1, types.cons(result, acc)); - }); - } - return hashMapHelp(0, types.EMPTY); - }); + var val = ht.hash.get(keys[i]); + return CALL(f, [keys[i], val], + function(result) { + return hashMapHelp(i+1, types.cons(result, acc)); + }); + } + return hashMapHelp(0, types.EMPTY); + }); -PRIMITIVES['hash-for-each'] = - new PrimProc('hash-for-each', - 2, - false, false, - function(ht, f) { - check(ht, isHash, 'hash-for-each', 'hash', 1, arguments); - check(f, isFunction, 'hash-for-each', 'procedure', 2, arguments); - - var keys = ht.hash.keys(); - var hashForEachHelp = function(i) { - if (i >= keys.length) { - return types.VOID; - } + PRIMITIVES['hash-for-each'] = + new PrimProc('hash-for-each', + 2, + false, false, + function(ht, f) { + check(ht, isHash, 'hash-for-each', 'hash', 1, arguments); + check(f, isFunction, 'hash-for-each', 'procedure', 2, arguments); + + var keys = ht.hash.keys(); + var hashForEachHelp = function(i) { + if (i >= keys.length) { + return types.VOID; + } - var val = ht.hash.get(keys[i]); - return CALL(f, [keys[i], val], - function(result) { - return hashForEachHelp(i+1); - }); - } - return hashForEachHelp(0); - }); + var val = ht.hash.get(keys[i]); + return CALL(f, [keys[i], val], + function(result) { + return hashForEachHelp(i+1); + }); + } + return hashForEachHelp(0); + }); -/************************* + /************************* *** String Primitives *** *************************/ -var makeStringImpl = function(n, c) { - check(n, isNatural, 'make-string', 'non-negative exact integer', 1, arguments); - check(c, isChar, 'make-string', 'char', 2, arguments); - var ret = []; - for (var i = 0; jsnums.lessThan(i, n); i++) { - ret.push(c.val); - } - return types.string(ret); -}; + var makeStringImpl = function(n, c) { + check(n, isNatural, 'make-string', 'non-negative exact integer', 1, arguments); + check(c, isChar, 'make-string', 'char', 2, arguments); + var ret = []; + for (var i = 0; jsnums.lessThan(i, n); i++) { + ret.push(c.val); + } + return types.string(ret); + }; -PRIMITIVES['make-string'] = + PRIMITIVES['make-string'] = new CasePrimitive( 'make-string', [new PrimProc('make-string', @@ -3295,568 +3317,568 @@ PRIMITIVES['make-string'] = function(n) { return makeStringImpl(n, types.char(String.fromCharCode(0))); })]); - - + + -PRIMITIVES['replicate'] = - new PrimProc('replicate', - 2, - false, false, - function(n, str) { - check(n, isNatural, 'replicate', 'non-negative exact integer', 1, arguments); - check(str, isString, 'replicate', 'string', 2, arguments); + PRIMITIVES['replicate'] = + new PrimProc('replicate', + 2, + false, false, + function(n, str) { + check(n, isNatural, 'replicate', 'non-negative exact integer', 1, arguments); + check(str, isString, 'replicate', 'string', 2, arguments); - var ret = ""; - var primStr = str.toString(); - for (var i = 0; jsnums.lessThan(i, n); i++) { - ret += primStr; - } - return types.string(ret); - }); + var ret = ""; + var primStr = str.toString(); + for (var i = 0; jsnums.lessThan(i, n); i++) { + ret += primStr; + } + return types.string(ret); + }); -PRIMITIVES['string'] = - new PrimProc('string', - 0, - true, false, - function(chars) { - arrayEach(chars, function(c, i) {check(c, isChar, 'string', 'char', i+1, chars);}); + PRIMITIVES['string'] = + new PrimProc('string', + 0, + true, false, + function(chars) { + arrayEach(chars, function(c, i) {check(c, isChar, 'string', 'char', i+1, chars);}); - var ret = []; - for (var i = 0; i < chars.length; i++) { - ret.push(chars[i].val); - } - return types.string(ret); - }); + var ret = []; + for (var i = 0; i < chars.length; i++) { + ret.push(chars[i].val); + } + return types.string(ret); + }); -PRIMITIVES['string-length'] = - new PrimProc('string-length', 1, false, false, - function(str) { - check(str, isString, 'string-length', 'string', 1); - return str.toString().length; - }); + PRIMITIVES['string-length'] = + new PrimProc('string-length', 1, false, false, + function(str) { + check(str, isString, 'string-length', 'string', 1); + return str.toString().length; + }); -PRIMITIVES['string-ref'] = - new PrimProc('string-ref', - 2, - false, false, - function(str, num) { - check(str, isString, 'string-ref', 'string', 1, arguments); - check(num, isNatural, 'string-ref', 'non-negative exact integer', 2, arguments); + PRIMITIVES['string-ref'] = + new PrimProc('string-ref', + 2, + false, false, + function(str, num) { + check(str, isString, 'string-ref', 'string', 1, arguments); + check(num, isNatural, 'string-ref', 'non-negative exact integer', 2, arguments); - str = str.toString(); - var n = jsnums.toFixnum(num); - if (n >= str.length) { - var msg = ('string-ref: index ' + n + ' out of range ' + - '[0, ' + (str.length-1) + '] for string: ' + - types.toWrittenString(str)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - return types.char(str.charAt(n)); - }); + str = str.toString(); + var n = jsnums.toFixnum(num); + if (n >= str.length) { + var msg = ('string-ref: index ' + n + ' out of range ' + + '[0, ' + (str.length-1) + '] for string: ' + + types.toWrittenString(str)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + return types.char(str.charAt(n)); + }); -PRIMITIVES['string=?'] = - new PrimProc('string=?', - 2, - true, false, - function(str1, str2, strs) { - strs.unshift(str2); - strs.unshift(str1); - arrayEach(strs, function(str, i) {check(str, isString, 'string=?', 'string', i+1, strs);}); - - return compare(strs, function(strA, strB) {return strA.toString() === strB.toString();}); - }); + PRIMITIVES['string=?'] = + new PrimProc('string=?', + 2, + true, false, + function(str1, str2, strs) { + strs.unshift(str2); + strs.unshift(str1); + arrayEach(strs, function(str, i) {check(str, isString, 'string=?', 'string', i+1, strs);}); + + return compare(strs, function(strA, strB) {return strA.toString() === strB.toString();}); + }); -PRIMITIVES['string-ci=?'] = - new PrimProc('string-ci=?', - 2, - true, false, - function(str1, str2, strs) { - strs.unshift(str2); - strs.unshift(str1); + PRIMITIVES['string-ci=?'] = + new PrimProc('string-ci=?', + 2, + true, false, + function(str1, str2, strs) { + strs.unshift(str2); + strs.unshift(str1); - for(var i = 0; i < strs.length; i++) { - check(strs[i], isString, 'string-ci=?', 'string', i+1, strs); - strs[i] = strs[i].toString().toLowerCase(); - } + for(var i = 0; i < strs.length; i++) { + check(strs[i], isString, 'string-ci=?', 'string', i+1, strs); + strs[i] = strs[i].toString().toLowerCase(); + } - return compare(strs, function(strA, strB) {return strA === strB;}); - }); + return compare(strs, function(strA, strB) {return strA === strB;}); + }); -PRIMITIVES['string?'] = - new PrimProc('string>?', - 2, - true, false, - function(str1, str2, strs) { - strs.unshift(str2); - strs.unshift(str1); - arrayEach(strs, function(str, i) {check(str, isString, 'string>?', 'string', i+1, strs);}); + PRIMITIVES['string>?'] = + new PrimProc('string>?', + 2, + true, false, + function(str1, str2, strs) { + strs.unshift(str2); + strs.unshift(str1); + arrayEach(strs, function(str, i) {check(str, isString, 'string>?', 'string', i+1, strs);}); - return compare(strs, function(strA, strB) {return strA.toString() > strB.toString();}); - }); + return compare(strs, function(strA, strB) {return strA.toString() > strB.toString();}); + }); -PRIMITIVES['string<=?'] = - new PrimProc('string<=?', - 2, - true, false, - function(str1, str2, strs) { - strs.unshift(str2); - strs.unshift(str1); - arrayEach(strs, function(str, i) {check(str, isString, 'string<=?', 'string', i+1, strs);}); + PRIMITIVES['string<=?'] = + new PrimProc('string<=?', + 2, + true, false, + function(str1, str2, strs) { + strs.unshift(str2); + strs.unshift(str1); + arrayEach(strs, function(str, i) {check(str, isString, 'string<=?', 'string', i+1, strs);}); - return compare(strs, function(strA, strB) {return strA.toString() <= strB.toString();}); - }); + return compare(strs, function(strA, strB) {return strA.toString() <= strB.toString();}); + }); -PRIMITIVES['string>=?'] = - new PrimProc('string>=?', - 2, - true, false, - function(str1, str2, strs) { - strs.unshift(str2); - strs.unshift(str1); - arrayEach(strs, function(str, i) {check(str, isString, 'string>=?', 'string', i+1, strs);}); + PRIMITIVES['string>=?'] = + new PrimProc('string>=?', + 2, + true, false, + function(str1, str2, strs) { + strs.unshift(str2); + strs.unshift(str1); + arrayEach(strs, function(str, i) {check(str, isString, 'string>=?', 'string', i+1, strs);}); - return compare(strs, function(strA, strB) {return strA.toString() >= strB.toString();}); - }); + return compare(strs, function(strA, strB) {return strA.toString() >= strB.toString();}); + }); -PRIMITIVES['string-ci?'] = - new PrimProc('string-ci>?', - 2, - true, false, - function(str1, str2, strs) { - strs.unshift(str2); - strs.unshift(str1); + PRIMITIVES['string-ci>?'] = + new PrimProc('string-ci>?', + 2, + true, false, + function(str1, str2, strs) { + strs.unshift(str2); + strs.unshift(str1); - for (var i = 0; i < strs.length; i++) { - check(strs[i], isString, 'string-ci>?', 'string', i+1, strs); - strs[i] = strs[i].toString().toLowerCase(); - } + for (var i = 0; i < strs.length; i++) { + check(strs[i], isString, 'string-ci>?', 'string', i+1, strs); + strs[i] = strs[i].toString().toLowerCase(); + } - return compare(strs, function(strA, strB) {return strA > strB;}); - }); + return compare(strs, function(strA, strB) {return strA > strB;}); + }); -PRIMITIVES['string-ci<=?'] = - new PrimProc('string-ci<=?', - 2, - true, false, - function(str1, str2, strs) { - strs.unshift(str2); - strs.unshift(str1); + PRIMITIVES['string-ci<=?'] = + new PrimProc('string-ci<=?', + 2, + true, false, + function(str1, str2, strs) { + strs.unshift(str2); + strs.unshift(str1); - for (var i = 0; i < strs.length; i++) { - check(strs[i], isString, 'string-ci<=?', 'string', i+1, strs); - strs[i] = strs[i].toString().toLowerCase(); - } + for (var i = 0; i < strs.length; i++) { + check(strs[i], isString, 'string-ci<=?', 'string', i+1, strs); + strs[i] = strs[i].toString().toLowerCase(); + } - return compare(strs, function(strA, strB) {return strA <= strB;}); - }); + return compare(strs, function(strA, strB) {return strA <= strB;}); + }); -PRIMITIVES['string-ci>=?'] = - new PrimProc('string-ci>=?', - 2, - true, false, - function(str1, str2, strs) { - strs.unshift(str2); - strs.unshift(str1); + PRIMITIVES['string-ci>=?'] = + new PrimProc('string-ci>=?', + 2, + true, false, + function(str1, str2, strs) { + strs.unshift(str2); + strs.unshift(str1); - for (var i = 0; i < strs.length; i++) { - check(strs[i], isString, 'string-ci>=?', 'string', i+1, strs); - strs[i] = strs[i].toString().toLowerCase(); - } + for (var i = 0; i < strs.length; i++) { + check(strs[i], isString, 'string-ci>=?', 'string', i+1, strs); + strs[i] = strs[i].toString().toLowerCase(); + } - return compare(strs, function(strA, strB) {return strA >= strB;}); - }); + return compare(strs, function(strA, strB) {return strA >= strB;}); + }); -PRIMITIVES['substring'] = + PRIMITIVES['substring'] = new CasePrimitive('substring', - [new PrimProc('substring', - 2, - false, false, - function(str, theStart) { - check(str, isString, 'substring', 'string', 1, arguments); - check(theStart, isNatural, 'substring', 'non-negative exact integer', 2, arguments); - str = str.toString(); - var start = jsnums.toFixnum(theStart); - if (start > str.length) { - var msg = ('substring: starting index ' + start + ' out of range ' + - '[0, ' + str.length + '] for string: ' + types.toWrittenString(str)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - else { - return types.string( str.substring(jsnums.toFixnum(start)) ); - } - }), - new PrimProc('substring', - 3, - false, false, - function(str, theStart, theEnd) { - check(str, isString, 'substring', 'string', 1, arguments); - check(theStart, isNatural, 'substring', 'non-negative exact integer', 2, arguments); - check(theEnd, isNatural, 'substring', 'non-negative exact integer', 3, arguments); - str = str.toString(); - var start = jsnums.toFixnum(theStart); - var end = jsnums.toFixnum(theEnd); - if (start > str.length) { - var msg = ('substring: starting index ' + start + ' out of range ' + - '[0, ' + str.length + '] for string: ' + types.toWrittenString(str)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - if (end < start || end > str.length) { - var msg = ('substring: ending index ' + end + ' out of range ' + '[' + start + - ', ' + str.length + '] for string: ' + types.toWrittenString(str)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - return types.string( str.substring(start, end) ); - }) ]); + [new PrimProc('substring', + 2, + false, false, + function(str, theStart) { + check(str, isString, 'substring', 'string', 1, arguments); + check(theStart, isNatural, 'substring', 'non-negative exact integer', 2, arguments); + str = str.toString(); + var start = jsnums.toFixnum(theStart); + if (start > str.length) { + var msg = ('substring: starting index ' + start + ' out of range ' + + '[0, ' + str.length + '] for string: ' + types.toWrittenString(str)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + else { + return types.string( str.substring(jsnums.toFixnum(start)) ); + } + }), + new PrimProc('substring', + 3, + false, false, + function(str, theStart, theEnd) { + check(str, isString, 'substring', 'string', 1, arguments); + check(theStart, isNatural, 'substring', 'non-negative exact integer', 2, arguments); + check(theEnd, isNatural, 'substring', 'non-negative exact integer', 3, arguments); + str = str.toString(); + var start = jsnums.toFixnum(theStart); + var end = jsnums.toFixnum(theEnd); + if (start > str.length) { + var msg = ('substring: starting index ' + start + ' out of range ' + + '[0, ' + str.length + '] for string: ' + types.toWrittenString(str)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + if (end < start || end > str.length) { + var msg = ('substring: ending index ' + end + ' out of range ' + '[' + start + + ', ' + str.length + '] for string: ' + types.toWrittenString(str)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + return types.string( str.substring(start, end) ); + }) ]); -PRIMITIVES['string-append'] = - new PrimProc("string-append", - 0, - true, false, - function(args) { - arrayEach(args, - function(str, i) { - check(str, isString, 'string-append', 'string', i+1, args); - }); - - for (var i = 0; i < args.length; i++) { - args[i] = args[i].toString(); - } - return types.string(args.join("")); - }); + PRIMITIVES['string-append'] = + new PrimProc("string-append", + 0, + true, false, + function(args) { + arrayEach(args, + function(str, i) { + check(str, isString, 'string-append', 'string', i+1, args); + }); + + for (var i = 0; i < args.length; i++) { + args[i] = args[i].toString(); + } + return types.string(args.join("")); + }); -PRIMITIVES['string->list'] = - new PrimProc('string->list', - 1, - false, false, - function(str) { - check(str, isString, 'string->list', 'string', 1); - str = str.toString(); - var lst = types.EMPTY; - for (var i = str.length-1; i >= 0; i--) { - lst = types.cons(types.char(str.charAt(i)), lst); - } - return lst; - }); + PRIMITIVES['string->list'] = + new PrimProc('string->list', + 1, + false, false, + function(str) { + check(str, isString, 'string->list', 'string', 1); + str = str.toString(); + var lst = types.EMPTY; + for (var i = str.length-1; i >= 0; i--) { + lst = types.cons(types.char(str.charAt(i)), lst); + } + return lst; + }); -PRIMITIVES['list->string'] = - new PrimProc('list->string', - 1, - false, false, - function(lst) { - checkListOf(lst, isChar, 'list->string', 'char', 1); + PRIMITIVES['list->string'] = + new PrimProc('list->string', + 1, + false, false, + function(lst) { + checkListOf(lst, isChar, 'list->string', 'char', 1); - var ret = []; - while( !lst.isEmpty() ) { - ret.push(lst.first().val); - lst = lst.rest(); - } - return types.string(ret); - }); + var ret = []; + while( !lst.isEmpty() ) { + ret.push(lst.first().val); + lst = lst.rest(); + } + return types.string(ret); + }); -PRIMITIVES['string-copy'] = - new PrimProc('string-copy', - 1, - false, false, - function(str) { - check(str, isString, 'string-copy', 'string', 1); - return types.string(str.toString()); - }); + PRIMITIVES['string-copy'] = + new PrimProc('string-copy', + 1, + false, false, + function(str) { + check(str, isString, 'string-copy', 'string', 1); + return types.string(str.toString()); + }); -PRIMITIVES['string->symbol'] = - new PrimProc('string->symbol', - 1, - false, false, - function(str) { - check(str, isString, 'string->symbol', 'string', 1); - return types.symbol(str.toString()); - }); + PRIMITIVES['string->symbol'] = + new PrimProc('string->symbol', + 1, + false, false, + function(str) { + check(str, isString, 'string->symbol', 'string', 1); + return types.symbol(str.toString()); + }); -PRIMITIVES['symbol->string'] = - new PrimProc('symbol->string', - 1, - false, false, - function(symb) { - check(symb, isSymbol, 'symbol->string', 'symbol', 1); - return types.string(symb.toString()); - }); + PRIMITIVES['symbol->string'] = + new PrimProc('symbol->string', + 1, + false, false, + function(symb) { + check(symb, isSymbol, 'symbol->string', 'symbol', 1); + return types.string(symb.toString()); + }); -PRIMITIVES['format'] = - new PrimProc('format', 1, true, false, - function(formatStr, args) { - check(formatStr, isString, 'format', 'string', 1, [formatStr].concat(args)); - formatStr = formatStr.toString(); - return types.string( helpers.format(formatStr, args, 'format') ); - }); + PRIMITIVES['format'] = + new PrimProc('format', 1, true, false, + function(formatStr, args) { + check(formatStr, isString, 'format', 'string', 1, [formatStr].concat(args)); + formatStr = formatStr.toString(); + return types.string( helpers.format(formatStr, args, 'format') ); + }); -PRIMITIVES['printf'] = - new PrimProc('printf', 1, true, true, - function(state, formatStr, args) { - check(formatStr, isString, 'printf', 'string', 1, [formatStr].concat(args)); - formatStr = formatStr.toString(); - var msg = helpers.format(formatStr, args, 'printf'); - state.getDisplayHook()(msg); - state.v = types.VOID; - }); + PRIMITIVES['printf'] = + new PrimProc('printf', 1, true, true, + function(state, formatStr, args) { + check(formatStr, isString, 'printf', 'string', 1, [formatStr].concat(args)); + formatStr = formatStr.toString(); + var msg = helpers.format(formatStr, args, 'printf'); + state.getDisplayHook()(msg); + state.v = types.VOID; + }); -PRIMITIVES['string->int'] = - new PrimProc('string->int', - 1, - false, false, - function(str) { - check(str, function(s) {return isString(s) && s.length == 1;}, - 'string->int', '1-letter string', 1); - str = str.toString(); - return str.charCodeAt(0); - }); + PRIMITIVES['string->int'] = + new PrimProc('string->int', + 1, + false, false, + function(str) { + check(str, function(s) {return isString(s) && s.length == 1;}, + 'string->int', '1-letter string', 1); + str = str.toString(); + return str.charCodeAt(0); + }); -PRIMITIVES['int->string'] = - new PrimProc('int->string', - 1, - false, false, - function(num) { - check(num, function(x) { - if ( !isInteger(x) ) { - return false; - } - var n = jsnums.toFixnum(x); - return ((n >= 0 && n < 55296) || - (n > 57343 && n <= 1114111)); - }, - 'int->string', - 'exact integer in [0,55295] or [57344,1114111]', - 1); + PRIMITIVES['int->string'] = + new PrimProc('int->string', + 1, + false, false, + function(num) { + check(num, function(x) { + if ( !isInteger(x) ) { + return false; + } + var n = jsnums.toFixnum(x); + return ((n >= 0 && n < 55296) || + (n > 57343 && n <= 1114111)); + }, + 'int->string', + 'exact integer in [0,55295] or [57344,1114111]', + 1); - return types.string( String.fromCharCode(jsnums.toFixnum(num)) ); - }); + return types.string( String.fromCharCode(jsnums.toFixnum(num)) ); + }); -PRIMITIVES['explode'] = - new PrimProc('explode', - 1, - false, false, - function(str) { - check(str, isString, 'explode', 'string', 1); - str = str.toString(); - var ret = types.EMPTY; - for (var i = str.length-1; i >= 0; i--) { - ret = types.cons( types.string(str.charAt(i)), ret ); - } - return ret; - }); + PRIMITIVES['explode'] = + new PrimProc('explode', + 1, + false, false, + function(str) { + check(str, isString, 'explode', 'string', 1); + str = str.toString(); + var ret = types.EMPTY; + for (var i = str.length-1; i >= 0; i--) { + ret = types.cons( types.string(str.charAt(i)), ret ); + } + return ret; + }); -PRIMITIVES['implode'] = - new PrimProc('implode', - 1, - false, false, - function(lst) { - checkListOf(lst, function(x) { return isString(x) && x.length == 1; }, - 'implode', 'list of 1-letter strings', 1); - var ret = []; - while ( !lst.isEmpty() ) { - ret.push( lst.first().toString() ); - lst = lst.rest(); - } - return types.string(ret); - }); + PRIMITIVES['implode'] = + new PrimProc('implode', + 1, + false, false, + function(lst) { + checkListOf(lst, function(x) { return isString(x) && x.length == 1; }, + 'implode', 'list of 1-letter strings', 1); + var ret = []; + while ( !lst.isEmpty() ) { + ret.push( lst.first().toString() ); + lst = lst.rest(); + } + return types.string(ret); + }); -PRIMITIVES['string-alphabetic?'] = - new PrimProc('string-alphabetic?', - 1, - false, false, - function(str) { - check(str, isString, 'string-alphabetic?', 'string', 1); - str = str.toString(); - return isAlphabeticString(str); - }); + PRIMITIVES['string-alphabetic?'] = + new PrimProc('string-alphabetic?', + 1, + false, false, + function(str) { + check(str, isString, 'string-alphabetic?', 'string', 1); + str = str.toString(); + return isAlphabeticString(str); + }); -PRIMITIVES['string-ith'] = - new PrimProc('string-ith', - 2, - false, false, - function(str, num) { - check(str, isString, 'string-ith', 'string', 1, arguments); - check(num, function(x) { return isNatural(x) && jsnums.lessThan(x, str.length); }, 'string-ith', - 'exact integer in [0, length of the given string minus 1 (' + (str.length-1) + ')]', 2, arguments); - str = str.toString(); - return types.string( str.charAt(jsnums.toFixnum(num)) ); - }); + PRIMITIVES['string-ith'] = + new PrimProc('string-ith', + 2, + false, false, + function(str, num) { + check(str, isString, 'string-ith', 'string', 1, arguments); + check(num, function(x) { return isNatural(x) && jsnums.lessThan(x, str.length); }, 'string-ith', + 'exact integer in [0, length of the given string minus 1 (' + (str.length-1) + ')]', 2, arguments); + str = str.toString(); + return types.string( str.charAt(jsnums.toFixnum(num)) ); + }); -PRIMITIVES['string-lower-case?'] = - new PrimProc('string-lower-case?', - 1, - false, false, - function(str) { - check(str, isString, 'string-lower-case?', 'string', 1); - var primStr = str.toString(); - return isAlphabeticString(str) && primStr.toLowerCase() === primStr; - }); + PRIMITIVES['string-lower-case?'] = + new PrimProc('string-lower-case?', + 1, + false, false, + function(str) { + check(str, isString, 'string-lower-case?', 'string', 1); + var primStr = str.toString(); + return isAlphabeticString(str) && primStr.toLowerCase() === primStr; + }); -PRIMITIVES['string-numeric?'] = - new PrimProc('string-numeric?', - 1, - false, false, - function(str) { - check(str, isString, 'string-numeric?', 'string', 1); - str = str.toString(); - return isNumericString(str); - }); + PRIMITIVES['string-numeric?'] = + new PrimProc('string-numeric?', + 1, + false, false, + function(str) { + check(str, isString, 'string-numeric?', 'string', 1); + str = str.toString(); + return isNumericString(str); + }); -PRIMITIVES['string-upper-case?'] = - new PrimProc('string-upper-case?', - 1, - false, false, - function(str) { - check(str, isString, 'string-upper-case?', 'string', 1); - var primStr = str.toString(); - return isAlphabeticString(str) && primStr.toUpperCase() === primStr; - }); + PRIMITIVES['string-upper-case?'] = + new PrimProc('string-upper-case?', + 1, + false, false, + function(str) { + check(str, isString, 'string-upper-case?', 'string', 1); + var primStr = str.toString(); + return isAlphabeticString(str) && primStr.toUpperCase() === primStr; + }); -PRIMITIVES['string-whitespace?'] = - new PrimProc('string-whitespace?', - 1, - false, false, - function(str) { - check(str, isString, 'string-whitespace?', 'string', 1); - str = str.toString(); - return isWhitespaceString(str); - }); + PRIMITIVES['string-whitespace?'] = + new PrimProc('string-whitespace?', + 1, + false, false, + function(str) { + check(str, isString, 'string-whitespace?', 'string', 1); + str = str.toString(); + return isWhitespaceString(str); + }); -PRIMITIVES['build-string'] = - new PrimProc('build-string', - 2, - false, false, - function(num, f) { - check(num, isNatural, 'build-string', 'non-negative exact integer', 1, arguments); - check(f, isFunction, 'build-string', 'procedure', 2, arguments); + PRIMITIVES['build-string'] = + new PrimProc('build-string', + 2, + false, false, + function(num, f) { + check(num, isNatural, 'build-string', 'non-negative exact integer', 1, arguments); + check(f, isFunction, 'build-string', 'procedure', 2, arguments); - var buildStringHelp = function(n, acc) { - if ( jsnums.greaterThanOrEqual(n, num) ) { - return types.string(acc); - } + var buildStringHelp = function(n, acc) { + if ( jsnums.greaterThanOrEqual(n, num) ) { + return types.string(acc); + } - return CALL(f, [n], - function(res) { - check(res, isChar, 'build-string', - 'procedure that returns a char', 2); - acc.push(res.val) - return buildStringHelp(n+1, acc); - }); - } - return buildStringHelp(0, []); - }); + return CALL(f, [n], + function(res) { + check(res, isChar, 'build-string', + 'procedure that returns a char', 2); + acc.push(res.val) + return buildStringHelp(n+1, acc); + }); + } + return buildStringHelp(0, []); + }); -PRIMITIVES['string->immutable-string'] = - new PrimProc('string->immutable-string', - 1, - false, false, - function(str) { - check(str, isString, 'string->immutable-string', 'string', 1); - return str.toString(); - }); + PRIMITIVES['string->immutable-string'] = + new PrimProc('string->immutable-string', + 1, + false, false, + function(str) { + check(str, isString, 'string->immutable-string', 'string', 1); + return str.toString(); + }); -PRIMITIVES['string-set!'] = - new PrimProc('string-set!', - 3, - false, false, - function(str, k, c) { - check(str, function(x) { return isMutableString(x); }, - 'string-set!', 'mutable string', 1, arguments); - check(k, isNatural, 'string-set!', 'non-negative exact integer', 2, arguments); - check(c, isChar, 'string-set!', 'char', 3, arguments); + PRIMITIVES['string-set!'] = + new PrimProc('string-set!', + 3, + false, false, + function(str, k, c) { + check(str, function(x) { return isMutableString(x); }, + 'string-set!', 'mutable string', 1, arguments); + check(k, isNatural, 'string-set!', 'non-negative exact integer', 2, arguments); + check(c, isChar, 'string-set!', 'char', 3, arguments); - if ( jsnums.greaterThanOrEqual(k, str.length) ) { - var msg = ('string-set!: index ' + k + ' out of range ' + - '[0, ' + (str.length-1) + '] for string: ' + - types.toWrittenString(str)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - str.set(jsnums.toFixnum(k), c.val); - return types.VOID; - }); + if ( jsnums.greaterThanOrEqual(k, str.length) ) { + var msg = ('string-set!: index ' + k + ' out of range ' + + '[0, ' + (str.length-1) + '] for string: ' + + types.toWrittenString(str)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + str.set(jsnums.toFixnum(k), c.val); + return types.VOID; + }); -PRIMITIVES['string-fill!'] = - new PrimProc('string-fill!', - 2, - false, false, - function(str, c) { - check(str, function(x) { return isMutableString(x); }, - 'string-fill!', 'mutable string', 1, arguments); - check(c, isChar, 'string-fill!', 'char', 2, arguments); - - for (var i = 0; i < str.length; i++) { - str.set(i, c.val); - } - return types.VOID; - }); + PRIMITIVES['string-fill!'] = + new PrimProc('string-fill!', + 2, + false, false, + function(str, c) { + check(str, function(x) { return isMutableString(x); }, + 'string-fill!', 'mutable string', 1, arguments); + check(c, isChar, 'string-fill!', 'char', 2, arguments); + + for (var i = 0; i < str.length; i++) { + str.set(i, c.val); + } + return types.VOID; + }); -////////////////////////////////////////////////////////////////////// -// Immutable cyclic data -PRIMITIVES['make-reader-graph'] = + ////////////////////////////////////////////////////////////////////// + // Immutable cyclic data + PRIMITIVES['make-reader-graph'] = new PrimProc('make-reader-graph', 1, false, false, function(x) { var result = types.readerGraph(x, types.makeLowLevelEqHash(), 0); @@ -3864,12 +3886,12 @@ PRIMITIVES['make-reader-graph'] = }); -PRIMITIVES['make-placeholder'] = + PRIMITIVES['make-placeholder'] = new PrimProc('make-placeholder', 1, false, false, function(x) { return types.placeholder(x); }); -PRIMITIVES['placeholder-set!'] = + PRIMITIVES['placeholder-set!'] = new PrimProc('placeholder-set!', 2, false, false, function(pl, x) { check(pl, types.isPlaceholder, @@ -3878,7 +3900,7 @@ PRIMITIVES['placeholder-set!'] = return types.VOID; }); -PRIMITIVES['placeholder-get'] = + PRIMITIVES['placeholder-get'] = new PrimProc('placeholder-get', 1, false, false, function(pl) { check(pl, types.isPlaceholder, @@ -3889,297 +3911,297 @@ PRIMITIVES['placeholder-get'] = -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -/****************************** + /****************************** *** Byte String Primitives *** ******************************/ -PRIMITIVES['make-bytes'] = + PRIMITIVES['make-bytes'] = new CasePrimitive('make-bytes', - [new PrimProc('make-bytes', - 1, - false, false, - function(k) { - check(k, isNatural, 'make-bytes', 'non-negative exact integer', 1); - - var ret = []; - for (var i = 0; i < jsnums.toFixnum(k); i++) { - ret.push(0); - } - return types.bytes(ret, true); - }), - new PrimProc('make-bytes', - 2, - false, false, - function(k, b) { - check(k, isNatural, 'make-bytes', 'non-negative exact integer', 1, arguments); - check(b, isByte, 'make-bytes', 'byte', 2, arguments); + [new PrimProc('make-bytes', + 1, + false, false, + function(k) { + check(k, isNatural, 'make-bytes', 'non-negative exact integer', 1); + + var ret = []; + for (var i = 0; i < jsnums.toFixnum(k); i++) { + ret.push(0); + } + return types.bytes(ret, true); + }), + new PrimProc('make-bytes', + 2, + false, false, + function(k, b) { + check(k, isNatural, 'make-bytes', 'non-negative exact integer', 1, arguments); + check(b, isByte, 'make-bytes', 'byte', 2, arguments); - var ret = []; - for (var i = 0; i < jsnums.toFixnum(k); i++) { - ret.push(b); - } - return types.bytes(ret, true); - }) ]); + var ret = []; + for (var i = 0; i < jsnums.toFixnum(k); i++) { + ret.push(b); + } + return types.bytes(ret, true); + }) ]); -PRIMITIVES['bytes'] = - new PrimProc('bytes', - 0, - true, false, - function(args) { - arrayEach(args, function(b, i) {check(b, isByte, 'bytes', 'byte', i+1, args);}); - return types.bytes(args, true); - }); + PRIMITIVES['bytes'] = + new PrimProc('bytes', + 0, + true, false, + function(args) { + arrayEach(args, function(b, i) {check(b, isByte, 'bytes', 'byte', i+1, args);}); + return types.bytes(args, true); + }); -PRIMITIVES['bytes->immutable-bytes'] = - new PrimProc('bytes->immutable-bytes', - 1, - false, false, - function(bstr) { - check(bstr, isByteString, 'bytes->immutable-bytes', 'byte string', 1); - if ( bstr.mutable ) { - return bstr.copy(false); - } - else { - return bstr; - } - }); + PRIMITIVES['bytes->immutable-bytes'] = + new PrimProc('bytes->immutable-bytes', + 1, + false, false, + function(bstr) { + check(bstr, isByteString, 'bytes->immutable-bytes', 'byte string', 1); + if ( bstr.mutable ) { + return bstr.copy(false); + } + else { + return bstr; + } + }); -PRIMITIVES['bytes-length'] = - new PrimProc('bytes-length', - 1, - false, false, - function(bstr) { - check(bstr, isByteString, 'bytes-length', 'byte string', 1); - return bstr.length(); - }); + PRIMITIVES['bytes-length'] = + new PrimProc('bytes-length', + 1, + false, false, + function(bstr) { + check(bstr, isByteString, 'bytes-length', 'byte string', 1); + return bstr.length(); + }); -PRIMITIVES['bytes-ref'] = - new PrimProc('bytes-ref', - 2, - false, false, - function(bstr, num) { - check(bstr, isByteString, 'bytes-ref', 'byte string', 1, arguments); - check(num, isNatural, 'bytes-ref', 'non-negative exact integer', 2, arguments); + PRIMITIVES['bytes-ref'] = + new PrimProc('bytes-ref', + 2, + false, false, + function(bstr, num) { + check(bstr, isByteString, 'bytes-ref', 'byte string', 1, arguments); + check(num, isNatural, 'bytes-ref', 'non-negative exact integer', 2, arguments); - var n = jsnums.toFixnum(num); - if ( n >= bstr.length() ) { - var msg = ('bytes-ref: index ' + n + ' out of range ' + - '[0, ' + (bstr.length-1) + '] for byte-string: ' + - types.toWrittenString(bstr)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - return bstr.get(n); - }); + var n = jsnums.toFixnum(num); + if ( n >= bstr.length() ) { + var msg = ('bytes-ref: index ' + n + ' out of range ' + + '[0, ' + (bstr.length-1) + '] for byte-string: ' + + types.toWrittenString(bstr)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + return bstr.get(n); + }); -PRIMITIVES['bytes-set!'] = - new PrimProc('bytes-set!', - 3, - false, false, - function(bstr, num, b) { - check(bstr, function(x) { return isByteString(x) && x.mutable; }, - 'bytes-set!', 'mutable byte string', 1, arguments); - check(num, isNatural, 'bytes-set!', 'non-negative exact integer', 2, arguments); - check(b, isByte, 'bytes-set!', 'byte', 3, arguments); + PRIMITIVES['bytes-set!'] = + new PrimProc('bytes-set!', + 3, + false, false, + function(bstr, num, b) { + check(bstr, function(x) { return isByteString(x) && x.mutable; }, + 'bytes-set!', 'mutable byte string', 1, arguments); + check(num, isNatural, 'bytes-set!', 'non-negative exact integer', 2, arguments); + check(b, isByte, 'bytes-set!', 'byte', 3, arguments); - var n = jsnums.toFixnum(num); - if ( n >= bstr.length() ) { - var msg = ('bytes-set!: index ' + n + ' out of range ' + - '[0, ' + (bstr.length-1) + '] for byte-string: ' + - types.toWrittenString(bstr)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - bstr.set(n, b); - return types.VOID; - }); + var n = jsnums.toFixnum(num); + if ( n >= bstr.length() ) { + var msg = ('bytes-set!: index ' + n + ' out of range ' + + '[0, ' + (bstr.length-1) + '] for byte-string: ' + + types.toWrittenString(bstr)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + bstr.set(n, b); + return types.VOID; + }); -PRIMITIVES['subbytes'] = + PRIMITIVES['subbytes'] = new CasePrimitive('subbytes', - [new PrimProc('subbytes', - 2, - false, false, - function(bstr, theStart) { - check(bstr, isByteString, 'subbytes', 'bytes string', 1, arguments); - check(theStart, isNatural, 'subbytes', 'non-negative exact integer', 2, arguments); - - var start = jsnums.toFixnum(theStart); - if (start > bstr.length()) { - var msg = ('subbytes: starting index ' + start + ' out of range ' + - '[0, ' + bstr.length + '] for byte-string: ' + - types.toWrittenString(bstr)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - else { - return bstr.subbytes(jsnums.toFixnum(start)); - } - }), - new PrimProc('subbytes', - 3, - false, false, - function(bstr, theStart, theEnd) { - check(bstr, isByteString, 'subbytes', 'byte string', 1, arguments); - check(theStart, isNatural, 'subbytes', 'non-negative exact integer', 2, arguments); - check(theEnd, isNatural, 'subbytes', 'non-negative exact integer', 3, arguments); + [new PrimProc('subbytes', + 2, + false, false, + function(bstr, theStart) { + check(bstr, isByteString, 'subbytes', 'bytes string', 1, arguments); + check(theStart, isNatural, 'subbytes', 'non-negative exact integer', 2, arguments); + + var start = jsnums.toFixnum(theStart); + if (start > bstr.length()) { + var msg = ('subbytes: starting index ' + start + ' out of range ' + + '[0, ' + bstr.length + '] for byte-string: ' + + types.toWrittenString(bstr)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + else { + return bstr.subbytes(jsnums.toFixnum(start)); + } + }), + new PrimProc('subbytes', + 3, + false, false, + function(bstr, theStart, theEnd) { + check(bstr, isByteString, 'subbytes', 'byte string', 1, arguments); + check(theStart, isNatural, 'subbytes', 'non-negative exact integer', 2, arguments); + check(theEnd, isNatural, 'subbytes', 'non-negative exact integer', 3, arguments); - var start = jsnums.toFixnum(theStart); - var end = jsnums.toFixnum(theEnd); - if (start > bstr.length()) { - var msg = ('subbytes: starting index ' + start + ' out of range ' + - '[0, ' + bstr.length() + '] for byte-string: ' + - types.toWrittenString(bstr)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - if (end < start || end > bstr.length()) { - var msg = ('subbytes: ending index ' + end + ' out of range ' + '[' + start + - ', ' + bstr.length() + '] for byte-string: ' + - types.toWrittenString(bstr)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - else { - return bstr.subbytes(start, end); - } - }) ]); + var start = jsnums.toFixnum(theStart); + var end = jsnums.toFixnum(theEnd); + if (start > bstr.length()) { + var msg = ('subbytes: starting index ' + start + ' out of range ' + + '[0, ' + bstr.length() + '] for byte-string: ' + + types.toWrittenString(bstr)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + if (end < start || end > bstr.length()) { + var msg = ('subbytes: ending index ' + end + ' out of range ' + '[' + start + + ', ' + bstr.length() + '] for byte-string: ' + + types.toWrittenString(bstr)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + else { + return bstr.subbytes(start, end); + } + }) ]); -PRIMITIVES['bytes-copy'] = - new PrimProc('bytes-copy', - 1, - false, false, - function(bstr) { - check(bstr, isByteString, 'bytes-copy', 'byte string', 1); - return bstr.copy(true); - }); + PRIMITIVES['bytes-copy'] = + new PrimProc('bytes-copy', + 1, + false, false, + function(bstr) { + check(bstr, isByteString, 'bytes-copy', 'byte string', 1); + return bstr.copy(true); + }); -PRIMITIVES['bytes-fill!'] = - new PrimProc('bytes-fill!', - 2, - false, false, - function(bstr, b) { - check(bstr, function(x) { return isByteString(x) && x.mutable; }, - 'bytes-fill!', 'mutable byte string', 1, arguments); - check(b, isByte, 'bytes-fill!', 'byte', 2, arguments); - - for (var i = 0; i < bstr.length(); i++) { - bstr.set(i, b); - } - return types.VOID; - }); + PRIMITIVES['bytes-fill!'] = + new PrimProc('bytes-fill!', + 2, + false, false, + function(bstr, b) { + check(bstr, function(x) { return isByteString(x) && x.mutable; }, + 'bytes-fill!', 'mutable byte string', 1, arguments); + check(b, isByte, 'bytes-fill!', 'byte', 2, arguments); + + for (var i = 0; i < bstr.length(); i++) { + bstr.set(i, b); + } + return types.VOID; + }); -PRIMITIVES['bytes-append'] = - new PrimProc('bytes-append', - 0, - true, false, - function(args) { - arrayEach(args, function(x, i) { check(x, isByteString, 'bytes-append', 'byte string', i+1, args); }); + PRIMITIVES['bytes-append'] = + new PrimProc('bytes-append', + 0, + true, false, + function(args) { + arrayEach(args, function(x, i) { check(x, isByteString, 'bytes-append', 'byte string', i+1, args); }); - var ret = []; - for (var i = 0; i < args.length; i++) { - ret = ret.concat(args[i].bytes); - } - return types.bytes(ret, true); - }); + var ret = []; + for (var i = 0; i < args.length; i++) { + ret = ret.concat(args[i].bytes); + } + return types.bytes(ret, true); + }); -PRIMITIVES['bytes->list'] = - new PrimProc('bytes->list', - 1, - false, false, - function(bstr) { - check(bstr, isByteString, 'bytes->list', 'byte string', 1); + PRIMITIVES['bytes->list'] = + new PrimProc('bytes->list', + 1, + false, false, + function(bstr) { + check(bstr, isByteString, 'bytes->list', 'byte string', 1); - var ret = types.EMPTY; - for (var i = bstr.length()-1; i >= 0; i--) { - ret = types.cons(bstr.get(i), ret); - } - return ret; - }); + var ret = types.EMPTY; + for (var i = bstr.length()-1; i >= 0; i--) { + ret = types.cons(bstr.get(i), ret); + } + return ret; + }); -PRIMITIVES['list->bytes'] = - new PrimProc('list->bytes', - 1, - false, false, - function(lst) { - checkListOf(lst, isByte, 'list->bytes', 'byte', 1); + PRIMITIVES['list->bytes'] = + new PrimProc('list->bytes', + 1, + false, false, + function(lst) { + checkListOf(lst, isByte, 'list->bytes', 'byte', 1); - var ret = []; - while ( !lst.isEmpty() ) { - ret.push(lst.first()); - lst = lst.rest(); - } - return types.bytes(ret, true); - }); + var ret = []; + while ( !lst.isEmpty() ) { + ret.push(lst.first()); + lst = lst.rest(); + } + return types.bytes(ret, true); + }); -PRIMITIVES['bytes=?'] = - new PrimProc('bytes=?', - 2, - true, false, - function(bstr1, bstr2, bstrs) { - bstrs.unshift(bstr2); - bstrs.unshift(bstr1); - arrayEach(bstrs, function(x, i) { check(x, isByteString, 'bytes=?', 'byte string', i+1, bstrs); }); + PRIMITIVES['bytes=?'] = + new PrimProc('bytes=?', + 2, + true, false, + function(bstr1, bstr2, bstrs) { + bstrs.unshift(bstr2); + bstrs.unshift(bstr1); + arrayEach(bstrs, function(x, i) { check(x, isByteString, 'bytes=?', 'byte string', i+1, bstrs); }); - return compare(bstrs, function(bstrA, bstrB) { return bstrA.toString() === bstrB.toString(); }); - }); + return compare(bstrs, function(bstrA, bstrB) { return bstrA.toString() === bstrB.toString(); }); + }); -PRIMITIVES['bytes?'] = - new PrimProc('bytes>?', - 2, - true, false, - function(bstr1, bstr2, bstrs) { - bstrs.unshift(bstr2); - bstrs.unshift(bstr1); - arrayEach(bstrs, function(x, i) { check(x, isByteString, 'bytes>?', 'byte string', i+1, bstrs); }); + PRIMITIVES['bytes>?'] = + new PrimProc('bytes>?', + 2, + true, false, + function(bstr1, bstr2, bstrs) { + bstrs.unshift(bstr2); + bstrs.unshift(bstr1); + arrayEach(bstrs, function(x, i) { check(x, isByteString, 'bytes>?', 'byte string', i+1, bstrs); }); - return compare(bstrs, function(bstrA, bstrB) { return bstrA.toString() > bstrB.toString(); }); - }); + return compare(bstrs, function(bstrA, bstrB) { return bstrA.toString() > bstrB.toString(); }); + }); -/************************* + /************************* *** Vector Primitives *** *************************/ -var makeVectorImpl = function(size, content) { - check(size, isNatural, 'make-vector', 'non-negative exact integer', 1, arguments); - var s = jsnums.toFixnum(size); - var ret = []; - for (var i = 0; i < s; i++) { - ret.push(content); - } - return types.vector(ret); -}; + var makeVectorImpl = function(size, content) { + check(size, isNatural, 'make-vector', 'non-negative exact integer', 1, arguments); + var s = jsnums.toFixnum(size); + var ret = []; + for (var i = 0; i < s; i++) { + ret.push(content); + } + return types.vector(ret); + }; -PRIMITIVES['make-vector'] = new CasePrimitive + PRIMITIVES['make-vector'] = new CasePrimitive ("make-vector", [new PrimProc('make-vector', 2, @@ -4191,381 +4213,381 @@ PRIMITIVES['make-vector'] = new CasePrimitive function(size) { return makeVectorImpl(size, jsnums.fromFixnum(0)); })]); -PRIMITIVES['vector'] = - new PrimProc('vector', - 0, - true, false, - function(args) { - return types.vector(args); - }); + PRIMITIVES['vector'] = + new PrimProc('vector', + 0, + true, false, + function(args) { + return types.vector(args); + }); -PRIMITIVES['vector-length'] = - new PrimProc('vector-length', - 1, - false, false, - function(vec) { - check(vec, isVector, 'vector-length', 'vector', 1); - return vec.length(); - }); + PRIMITIVES['vector-length'] = + new PrimProc('vector-length', + 1, + false, false, + function(vec) { + check(vec, isVector, 'vector-length', 'vector', 1); + return vec.length(); + }); -PRIMITIVES['vector-ref'] = - new PrimProc('vector-ref', - 2, - false, false, - function(vec, index) { - check(vec, isVector, 'vector-ref', 'vector', 1, arguments); - check(index, isNatural, 'vector-ref', 'non-negative exact integer', 2, arguments); + PRIMITIVES['vector-ref'] = + new PrimProc('vector-ref', + 2, + false, false, + function(vec, index) { + check(vec, isVector, 'vector-ref', 'vector', 1, arguments); + check(index, isNatural, 'vector-ref', 'non-negative exact integer', 2, arguments); - var i = jsnums.toFixnum(index); - if (i >= vec.length()) { - var msg = ('vector-ref: index ' + i + ' out of range ' + - '[0, ' + (vec.length()-1) + '] for vector: ' + - types.toWrittenString(vec)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - return vec.ref(i); - }); + var i = jsnums.toFixnum(index); + if (i >= vec.length()) { + var msg = ('vector-ref: index ' + i + ' out of range ' + + '[0, ' + (vec.length()-1) + '] for vector: ' + + types.toWrittenString(vec)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + return vec.ref(i); + }); -PRIMITIVES['vector-set!'] = - new PrimProc('vector-set!', - 3, - false, false, - function(vec, index, val) { - check(vec, isVector, 'vector-set!', 'vector', 1, arguments); - check(index, isNatural, 'vector-set!', 'non-negative exact integer', 2, arguments); + PRIMITIVES['vector-set!'] = + new PrimProc('vector-set!', + 3, + false, false, + function(vec, index, val) { + check(vec, isVector, 'vector-set!', 'vector', 1, arguments); + check(index, isNatural, 'vector-set!', 'non-negative exact integer', 2, arguments); - var i = jsnums.toFixnum(index); - if (i >= vec.length()) { - var msg = ('vector-set!: index ' + i + ' out of range ' + - '[0, ' + (vec.length()-1) + '] for vector: ' + - types.toWrittenString(vec)); - raise( types.incompleteExn(types.exnFailContract, msg, []) ); - } - vec.set(i, val); - return types.VOID; - }); + var i = jsnums.toFixnum(index); + if (i >= vec.length()) { + var msg = ('vector-set!: index ' + i + ' out of range ' + + '[0, ' + (vec.length()-1) + '] for vector: ' + + types.toWrittenString(vec)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + vec.set(i, val); + return types.VOID; + }); -PRIMITIVES['vector->list'] = - new PrimProc('vector->list', - 1, - false, false, - function(vec) { - check(vec, isVector, 'vector->list', 'vector', 1); - return vec.toList(); - }); + PRIMITIVES['vector->list'] = + new PrimProc('vector->list', + 1, + false, false, + function(vec) { + check(vec, isVector, 'vector->list', 'vector', 1); + return vec.toList(); + }); -PRIMITIVES['list->vector'] = - new PrimProc('list->vector', - 1, - false, false, - function(lst) { - checkList(lst, 'list->vector', 1); - return types.vector( helpers.schemeListToArray(lst) ); - }); + PRIMITIVES['list->vector'] = + new PrimProc('list->vector', + 1, + false, false, + function(lst) { + checkList(lst, 'list->vector', 1); + return types.vector( helpers.schemeListToArray(lst) ); + }); -PRIMITIVES['build-vector'] = - new PrimProc('build-vector', - 2, - false, false, - function(num, f) { - check(num, isNatural, 'build-vector', 'non-negative exact integer', 1, arguments); - check(f, isFunction, 'build-vector', 'procedure', 2, arguments); + PRIMITIVES['build-vector'] = + new PrimProc('build-vector', + 2, + false, false, + function(num, f) { + check(num, isNatural, 'build-vector', 'non-negative exact integer', 1, arguments); + check(f, isFunction, 'build-vector', 'procedure', 2, arguments); - var buildVectorHelp = function(n, acc) { - if ( jsnums.greaterThanOrEqual(n, num) ) { - return types.vector(acc); - } + var buildVectorHelp = function(n, acc) { + if ( jsnums.greaterThanOrEqual(n, num) ) { + return types.vector(acc); + } - return CALL(f, [n], - function (result) { - acc.push(result) - return buildVectorHelp(n+1, acc); - }); - } - return buildVectorHelp(0, []); - }); + return CALL(f, [n], + function (result) { + acc.push(result) + return buildVectorHelp(n+1, acc); + }); + } + return buildVectorHelp(0, []); + }); -/*********************** + /*********************** *** Char Primitives *** ***********************/ -PRIMITIVES['char=?'] = - new PrimProc('char=?', - 2, - true, false, - function(char1, char2, chars) { - chars.unshift(char2); - chars.unshift(char1); - arrayEach(chars, function(c, i) {check(c, isChar, 'char=?', 'char', i+1, chars);}); + PRIMITIVES['char=?'] = + new PrimProc('char=?', + 2, + true, false, + function(char1, char2, chars) { + chars.unshift(char2); + chars.unshift(char1); + arrayEach(chars, function(c, i) {check(c, isChar, 'char=?', 'char', i+1, chars);}); - return compare(chars, function(c1, c2) {return c1.val === c2.val;}); - }); + return compare(chars, function(c1, c2) {return c1.val === c2.val;}); + }); -PRIMITIVES['char?'] = - new PrimProc('char>?', - 2, - true, false, - function(char1, char2, chars) { - chars.unshift(char2); - chars.unshift(char1); - arrayEach(chars, function(c, i) {check(c, isChar, 'char>?', 'char', i+1, chars);}); + PRIMITIVES['char>?'] = + new PrimProc('char>?', + 2, + true, false, + function(char1, char2, chars) { + chars.unshift(char2); + chars.unshift(char1); + arrayEach(chars, function(c, i) {check(c, isChar, 'char>?', 'char', i+1, chars);}); - return compare(chars, function(c1, c2) {return c1.val > c2.val;}); - }); + return compare(chars, function(c1, c2) {return c1.val > c2.val;}); + }); -PRIMITIVES['char<=?'] = - new PrimProc('char<=?', - 2, - true, false, - function(char1, char2, chars) { - chars.unshift(char2); - chars.unshift(char1); - arrayEach(chars, function(c, i) {check(c, isChar, 'char<=?', 'char', i+1, chars);}); + PRIMITIVES['char<=?'] = + new PrimProc('char<=?', + 2, + true, false, + function(char1, char2, chars) { + chars.unshift(char2); + chars.unshift(char1); + arrayEach(chars, function(c, i) {check(c, isChar, 'char<=?', 'char', i+1, chars);}); - return compare(chars, function(c1, c2) {return c1.val <= c2.val;}); - }); + return compare(chars, function(c1, c2) {return c1.val <= c2.val;}); + }); -PRIMITIVES['char>=?'] = - new PrimProc('char>=?', - 2, - true, false, - function(char1, char2, chars) { - chars.unshift(char2); - chars.unshift(char1); - arrayEach(chars, function(c, i) {check(c, isChar, 'char>=?', 'char', i+1, chars);}); + PRIMITIVES['char>=?'] = + new PrimProc('char>=?', + 2, + true, false, + function(char1, char2, chars) { + chars.unshift(char2); + chars.unshift(char1); + arrayEach(chars, function(c, i) {check(c, isChar, 'char>=?', 'char', i+1, chars);}); - return compare(chars, function(c1, c2) {return c1.val >= c2.val;}); - }); + return compare(chars, function(c1, c2) {return c1.val >= c2.val;}); + }); -PRIMITIVES['char-ci=?'] = - new PrimProc('char-ci=?', - 2, - true, false, - function(char1, char2, chars) { - chars.unshift(char2); - chars.unshift(char1); - arrayEach(chars, function(c, i) {check(c, isChar, 'char-ci=?', 'char', i+1, chars);}); + PRIMITIVES['char-ci=?'] = + new PrimProc('char-ci=?', + 2, + true, false, + function(char1, char2, chars) { + chars.unshift(char2); + chars.unshift(char1); + arrayEach(chars, function(c, i) {check(c, isChar, 'char-ci=?', 'char', i+1, chars);}); - return compare(chars, - function(c1, c2) { - return c1.val.toLowerCase() === c2.val.toLowerCase(); - }); - }); + return compare(chars, + function(c1, c2) { + return c1.val.toLowerCase() === c2.val.toLowerCase(); + }); + }); -PRIMITIVES['char-ci?'] = - new PrimProc('char-ci>?', - 2, - true, false, - function(char1, char2, chars) { - chars.unshift(char2); - chars.unshift(char1); - arrayEach(chars, function(c, i) {check(c, isChar, 'char-ci>?', 'char', i+1, chars);}); + PRIMITIVES['char-ci>?'] = + new PrimProc('char-ci>?', + 2, + true, false, + function(char1, char2, chars) { + chars.unshift(char2); + chars.unshift(char1); + arrayEach(chars, function(c, i) {check(c, isChar, 'char-ci>?', 'char', i+1, chars);}); - return compare(chars, - function(c1, c2) { - return c1.val.toLowerCase() > c2.val.toLowerCase(); - }); - }); + return compare(chars, + function(c1, c2) { + return c1.val.toLowerCase() > c2.val.toLowerCase(); + }); + }); -PRIMITIVES['char-ci<=?'] = - new PrimProc('char-ci<=?', - 2, - true, false, - function(char1, char2, chars) { - chars.unshift(char2); - chars.unshift(char1); - arrayEach(chars, function(c, i) {check(c, isChar, 'char-ci<=?', 'char', i+1, chars);}); + PRIMITIVES['char-ci<=?'] = + new PrimProc('char-ci<=?', + 2, + true, false, + function(char1, char2, chars) { + chars.unshift(char2); + chars.unshift(char1); + arrayEach(chars, function(c, i) {check(c, isChar, 'char-ci<=?', 'char', i+1, chars);}); - return compare(chars, - function(c1, c2) { - return c1.val.toLowerCase() <= c2.val.toLowerCase(); - }); - }); + return compare(chars, + function(c1, c2) { + return c1.val.toLowerCase() <= c2.val.toLowerCase(); + }); + }); -PRIMITIVES['char-ci>=?'] = - new PrimProc('char-ci>=?', - 2, - true, false, - function(char1, char2, chars) { - chars.unshift(char2); - chars.unshift(char1); - arrayEach(chars, function(c, i) {check(c, isChar, 'char-ci>=?', 'char', i+1, chars);}); + PRIMITIVES['char-ci>=?'] = + new PrimProc('char-ci>=?', + 2, + true, false, + function(char1, char2, chars) { + chars.unshift(char2); + chars.unshift(char1); + arrayEach(chars, function(c, i) {check(c, isChar, 'char-ci>=?', 'char', i+1, chars);}); - return compare(chars, - function(c1, c2) { - return c1.val.toLowerCase() >= c2.val.toLowerCase(); - }); - }); + return compare(chars, + function(c1, c2) { + return c1.val.toLowerCase() >= c2.val.toLowerCase(); + }); + }); -PRIMITIVES['char-alphabetic?'] = - new PrimProc('char-alphabetic?', - 1, - false, false, - function(c) { - check(c, isChar, 'char-alphabetic?', 'char', 1); - return isAlphabeticString(c.val); - }); + PRIMITIVES['char-alphabetic?'] = + new PrimProc('char-alphabetic?', + 1, + false, false, + function(c) { + check(c, isChar, 'char-alphabetic?', 'char', 1); + return isAlphabeticString(c.val); + }); -PRIMITIVES['char-numeric?'] = - new PrimProc('char-numeric?', - 1, - false, false, - function(c) { - check(c, isChar, 'char-numeric?', 'char', 1); - return (c.val >= '0' && c.val <= '9'); - }); + PRIMITIVES['char-numeric?'] = + new PrimProc('char-numeric?', + 1, + false, false, + function(c) { + check(c, isChar, 'char-numeric?', 'char', 1); + return (c.val >= '0' && c.val <= '9'); + }); -PRIMITIVES['char-whitespace?'] = - new PrimProc('char-whitespace?', - 1, - false, false, - function(c) { - check(c, isChar, 'char-whitespace?', 'char', 1); - return isWhitespaceString(c.val); - }); + PRIMITIVES['char-whitespace?'] = + new PrimProc('char-whitespace?', + 1, + false, false, + function(c) { + check(c, isChar, 'char-whitespace?', 'char', 1); + return isWhitespaceString(c.val); + }); -PRIMITIVES['char-upper-case?'] = - new PrimProc('char-upper-case?', - 1, - false, false, - function(c) { - check(c, isChar, 'char-upper-case?', 'char', 1); - return (isAlphabeticString(c.val) && c.val.toUpperCase() === c.val); - }); + PRIMITIVES['char-upper-case?'] = + new PrimProc('char-upper-case?', + 1, + false, false, + function(c) { + check(c, isChar, 'char-upper-case?', 'char', 1); + return (isAlphabeticString(c.val) && c.val.toUpperCase() === c.val); + }); -PRIMITIVES['char-lower-case?'] = - new PrimProc('char-lower-case?', - 1, - false, false, - function(c) { - check(c, isChar, 'char-lower-case?', 'char', 1); - return (isAlphabeticString(c.val) && c.val.toLowerCase() === c.val); - }); + PRIMITIVES['char-lower-case?'] = + new PrimProc('char-lower-case?', + 1, + false, false, + function(c) { + check(c, isChar, 'char-lower-case?', 'char', 1); + return (isAlphabeticString(c.val) && c.val.toLowerCase() === c.val); + }); -PRIMITIVES['char->integer'] = - new PrimProc('char->integer', - 1, - false, false, - function(c) { - check(c, isChar, 'char->integer', 'char', 1); - return c.val.charCodeAt(0); - }); + PRIMITIVES['char->integer'] = + new PrimProc('char->integer', + 1, + false, false, + function(c) { + check(c, isChar, 'char->integer', 'char', 1); + return c.val.charCodeAt(0); + }); -PRIMITIVES['integer->char'] = - new PrimProc('integer->char', - 1, - false, false, - function(num) { - check(num, function(x) { - if ( !isNatural(x) ) { - return false; - } - var n = jsnums.toFixnum(x); - return ((n >= 0 && n < 55296) || - (n > 57343 && n <= 1114111)); - }, - 'integer->char', - 'exact integer in [0,#x10FFFF], not in [#xD800,#xDFFF]', - 1); + PRIMITIVES['integer->char'] = + new PrimProc('integer->char', + 1, + false, false, + function(num) { + check(num, function(x) { + if ( !isNatural(x) ) { + return false; + } + var n = jsnums.toFixnum(x); + return ((n >= 0 && n < 55296) || + (n > 57343 && n <= 1114111)); + }, + 'integer->char', + 'exact integer in [0,#x10FFFF], not in [#xD800,#xDFFF]', + 1); - return types.char( String.fromCharCode(jsnums.toFixnum(num)) ); - }); + return types.char( String.fromCharCode(jsnums.toFixnum(num)) ); + }); -PRIMITIVES['char-upcase'] = - new PrimProc('char-upcase', - 1, - false, false, - function(c) { - check(c, isChar, 'char-upcase', 'char', 1); - return types.char( c.val.toUpperCase() ); - }); + PRIMITIVES['char-upcase'] = + new PrimProc('char-upcase', + 1, + false, false, + function(c) { + check(c, isChar, 'char-upcase', 'char', 1); + return types.char( c.val.toUpperCase() ); + }); -PRIMITIVES['char-downcase'] = - new PrimProc('char-downcase', - 1, - false, false, - function(c) { - check(c, isChar, 'char-downcase', 'char', 1); - return types.char( c.val.toLowerCase() ); - }); + PRIMITIVES['char-downcase'] = + new PrimProc('char-downcase', + 1, + false, false, + function(c) { + check(c, isChar, 'char-downcase', 'char', 1); + return types.char( c.val.toLowerCase() ); + }); -var callCCPrim = new types.PrimProc('call/cc', - 1, - false, true, - function(aState, f) { - var continuationClosure = - state.captureContinuationClosure(aState); - aState.pushValue(continuationClosure); - aState.v = f; - aState.pushControl( - new control.CallControl(1)); - }); + var callCCPrim = new types.PrimProc('call/cc', + 1, + false, true, + function(aState, f) { + var continuationClosure = + state.captureContinuationClosure(aState); + aState.pushValue(continuationClosure); + aState.v = f; + aState.pushControl( + new control.CallControl(1)); + }); -PRIMITIVES['call/cc'] = callCCPrim; -PRIMITIVES['call-with-current-continuation'] = callCCPrim; + PRIMITIVES['call/cc'] = callCCPrim; + PRIMITIVES['call-with-current-continuation'] = callCCPrim; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// @@ -4574,19 +4596,19 @@ PRIMITIVES['call-with-current-continuation'] = callCCPrim; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -var GENSYM_COUNTER = 0; + var GENSYM_COUNTER = 0; -var gensymImpl = function(x) { - check(x, - function(x) { return isString(x) || isSymbol(x) }, - 'gensym', 'symbol or string', - 1); - return types.symbol(x.toString() + '' + (GENSYM_COUNTER++)); -}; + var gensymImpl = function(x) { + check(x, + function(x) { return isString(x) || isSymbol(x) }, + 'gensym', 'symbol or string', + 1); + return types.symbol(x.toString() + '' + (GENSYM_COUNTER++)); + }; -PRIMITIVES['gensym'] = + PRIMITIVES['gensym'] = new CasePrimitive( 'gensym', [new PrimProc('gensym', @@ -4610,69 +4632,70 @@ PRIMITIVES['gensym'] = -/*************************** + /*************************** *** Primitive Constants *** ***************************/ -PRIMITIVES['eof'] = types.EOF; -PRIMITIVES['e'] = jsnums.e; -PRIMITIVES['empty'] = types.EMPTY; -PRIMITIVES['false'] = false; -PRIMITIVES['true'] = true; -PRIMITIVES['pi'] = jsnums.pi; -PRIMITIVES['null'] = types.EMPTY; + PRIMITIVES['eof'] = types.EOF; + PRIMITIVES['e'] = jsnums.e; + PRIMITIVES['empty'] = types.EMPTY; + PRIMITIVES['false'] = false; + PRIMITIVES['true'] = true; + PRIMITIVES['pi'] = jsnums.pi; + PRIMITIVES['null'] = types.EMPTY; -////////////////////////////////////////////////////////////////////// -/** Parameters **/ -var PARAMZ = {}; + ////////////////////////////////////////////////////////////////////// + /** Parameters **/ + var PARAMZ = {}; -PARAMZ['exception-handler-key'] = types.exceptionHandlerKey; + PARAMZ['exception-handler-key'] = types.exceptionHandlerKey; -///////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////// -// getPrimitive: string (string | undefined) -> scheme-value -primitive.getPrimitive = function(name, resolvedModuleName) { - if (resolvedModuleName === undefined) { - return PRIMITIVES[name]; - } + // getPrimitive: string (string | undefined) -> scheme-value + primitives.getPrimitive = function(name, resolvedModuleName) { + if (resolvedModuleName === undefined) { + return PRIMITIVES[name]; + } - if (resolvedModuleName === types.symbol("moby/kernel")) { - return PRIMITIVES[name]; - } + if (resolvedModuleName === types.symbol("moby/kernel")) { + return PRIMITIVES[name]; + } - if (resolvedModuleName === types.symbol("moby/paramz")) { - return PARAMZ[name]; - } + if (resolvedModuleName === types.symbol("moby/paramz")) { + return PARAMZ[name]; + } - if (types.isEqual(resolvedModuleName, - types.list([types.symbol("quote"), types.symbol("#%kernel")]))) { - return PRIMITIVES[name]; - } + if (types.isEqual(resolvedModuleName, + types.list([types.symbol("quote"), types.symbol("#%kernel")]))) { + return PRIMITIVES[name]; + } - if (types.isEqual(resolvedModuleName, - types.list([types.symbol("quote"), types.symbol("#%paramz")]))) { - return PARAMZ[name]; - } + if (types.isEqual(resolvedModuleName, + types.list([types.symbol("quote"), types.symbol("#%paramz")]))) { + return PARAMZ[name]; + } - // FIXME: if we get to this point, this should be treated as an internal error... - return PRIMITIVES[name]; -}; + // FIXME: if we get to this point, this should be treated as an internal error... + return PRIMITIVES[name]; + }; -primitive.isPrimitive = function(x) { - return x instanceof PrimProc; -}; + primitives.isPrimitive = function(x) { + return x instanceof PrimProc; + }; -})(); + scope.link.announceReady('primitives'); +})(this['plt']); diff --git a/js-assembler/mini-runtime.js b/js-assembler/runtime-src/runtime.js similarity index 99% rename from js-assembler/mini-runtime.js rename to js-assembler/runtime-src/runtime.js index cdf9d6d..3986e7f 100644 --- a/js-assembler/mini-runtime.js +++ b/js-assembler/runtime-src/runtime.js @@ -1,13 +1,10 @@ - if(this['plt'] === undefined) { - this['plt'] = {}; - } - +if(this['plt'] === undefined) { this['plt'] = {}; } // All of the values here are namespaced under "plt.runtime". -(function() { - this['plt']['runtime'] = {}; - var exports = this['plt']['runtime']; +(function(scope) { + var runtime = {}; + scope['runtime'] = runtime; @@ -1343,8 +1340,8 @@ // Executes all programs that have been labeled as a main module var invokeMains = function(machine, succ, fail) { - plt.runtime.ready(function() { - machine = machine || plt.runtime.currentMachine; + runtime.ready(function() { + machine = machine || runtime.currentMachine; succ = succ || function() {}; fail = fail || function() {}; var mainModules = machine.mainModules.slice(); @@ -1368,7 +1365,7 @@ // Exports - + var exports = runtime; exports['currentMachine'] = new Machine(); exports['invokeMains'] = invokeMains; @@ -1433,4 +1430,6 @@ exports['HaltError'] = HaltError; -}).call(this); \ No newline at end of file + + scope.link.announceReady('runtime'); +})(this['plt']); \ No newline at end of file diff --git a/js-assembler/runtime-src/types.js b/js-assembler/runtime-src/types.js index 2da6eab..0299261 100644 --- a/js-assembler/runtime-src/types.js +++ b/js-assembler/runtime-src/types.js @@ -1,42 +1,57 @@ -////////////////////////////////////////////////////////////////////// -// helper functions +if (! this['plt']) { this['plt'] = {}; } -//var jsnums = require('./js-numbers'); +// FIXME: there's a circularity between this module and helpers, and that circularly +// should not be there! -var types = {}; +(function (scope) { + ////////////////////////////////////////////////////////////////////// + var types = {}; + scope['types'] = types; -(function () { - -////////////////////////////////////////////////////////////////////// + // helpers refers to plt.helpers. + var helpers = scope['helpers']; -var appendChild = function(parent, child) { - parent.appendChild(child); -}; + var getEqHashCode, makeLowLevelEqHash; + // makeLowLevelEqHash: -> hashtable + // Constructs an eq hashtable that uses Moby's getEqHashCode function. + var makeLowLevelEqHash; - -////////////////////////////////////////////////////////////////////// + scope.link.ready('helpers', function() { + helpers = scope['helpers']; + getEqHashCode = helpers.getEqHashCode; + makeLowLevelEqHash = helpers.makeLowLevelEqHash; + }); -getEqHashCode = helpers.getEqHashCode; + var appendChild = function(parent, child) { + parent.appendChild(child); + }; + + + ////////////////////////////////////////////////////////////////////// + + + + -// Union/find for circular equality testing. + // Union/find for circular equality testing. -var UnionFind = function() { + var UnionFind = function() { // this.parenMap holds the arrows from an arbitrary pointer // to its parent. this.parentMap = makeLowLevelEqHash(); -} + } -// find: ptr -> UnionFindNode -// Returns the representative for this ptr. -UnionFind.prototype.find = function(ptr) { + // find: ptr -> UnionFindNode + // Returns the representative for this ptr. + UnionFind.prototype.find = function(ptr) { var parent = (this.parentMap.containsKey(ptr) ? this.parentMap.get(ptr) : ptr); if (parent === ptr) { @@ -47,23 +62,23 @@ UnionFind.prototype.find = function(ptr) { this.parentMap.put(ptr, rep); return rep; } -}; + }; -// merge: ptr ptr -> void -// Merge the representative nodes for ptr1 and ptr2. -UnionFind.prototype.merge = function(ptr1, ptr2) { + // merge: ptr ptr -> void + // Merge the representative nodes for ptr1 and ptr2. + UnionFind.prototype.merge = function(ptr1, ptr2) { this.parentMap.put(this.find(ptr1), this.find(ptr2)); -}; + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -StructType = function(name, type, numberOfArgs, numberOfFields, firstField, - applyGuard, constructor, predicate, accessor, mutator) { + StructType = function(name, type, numberOfArgs, numberOfFields, firstField, + applyGuard, constructor, predicate, accessor, mutator) { this.name = name; this.type = type; this.numberOfArgs = numberOfArgs; @@ -75,46 +90,46 @@ StructType = function(name, type, numberOfArgs, numberOfFields, firstField, this.predicate = predicate; this.accessor = accessor; this.mutator = mutator; -}; + }; -StructType.prototype.toString = function(cache) { + StructType.prototype.toString = function(cache) { return '#'; -}; + }; -StructType.prototype.isEqual = function(other, aUnionFind) { + StructType.prototype.isEqual = function(other, aUnionFind) { return this === other; -}; + }; -var makeStructureType = function(theName, parentType, initFieldCnt, autoFieldCnt, autoV, guard) { + var makeStructureType = function(theName, parentType, initFieldCnt, autoFieldCnt, autoV, guard) { var defaultGuard = function(args, name, k) { return k(args); }; // If no parent type given, then the parent type is Struct if ( !parentType ) { - parentType = ({ type: Struct, - numberOfArgs: 0, - numberOfFields: 0, - firstField: 0, - applyGuard: defaultGuard }); + parentType = ({ type: Struct, + numberOfArgs: 0, + numberOfFields: 0, + firstField: 0, + applyGuard: defaultGuard }); } // if there's no guard, use the default one if (!guard) { - guard = defaultGuard; + guard = defaultGuard; } var numParentArgs = parentType.numberOfArgs; // Create a new struct type inheriting from the parent - var aStruct = function(name, args) { - parentType.type.call(this, name, args); - for (var i = 0; i < initFieldCnt; i++) { - this._fields.push(args[i+numParentArgs]); - } - for (var i = 0; i < autoFieldCnt; i++) { - this._fields.push(autoV); - } - }; - aStruct.prototype = helpers.heir(parentType.type.prototype); + var aStruct = function(name, args) { + parentType.type.call(this, name, args); + for (var i = 0; i < initFieldCnt; i++) { + this._fields.push(args[i+numParentArgs]); + } + for (var i = 0; i < autoFieldCnt; i++) { + this._fields.push(autoV); + } + }; + aStruct.prototype = helpers.heir(parentType.type.prototype); @@ -128,19 +143,19 @@ var makeStructureType = function(theName, parentType, initFieldCnt, autoFieldCnt 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) ); }); - }); + 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) ); }); + }); }, function() { - var args = helpers.map(function(x) { return x; }, arguments); - return newType.applyGuard(args, - Symbol.makeInstance(theName), - function(res) { return new aStruct(theName, res); }); + var args = helpers.map(function(x) { return x; }, arguments); + return newType.applyGuard(args, + Symbol.makeInstance(theName), + function(res) { return new aStruct(theName, res); }); }, function(x) { return x instanceof aStruct; @@ -148,7 +163,7 @@ var makeStructureType = function(theName, parentType, initFieldCnt, autoFieldCnt function(x, i) { return x._fields[i + this.firstField]; }, function(x, i, v) { x._fields[i + this.firstField] = v; }); return newType; -}; + }; @@ -230,227 +245,227 @@ var makeStructureType = function(theName, parentType, initFieldCnt, autoFieldCnt -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -// Regular expressions. + // Regular expressions. -var RegularExpression = function(pattern) { - this.pattern = pattern; -}; + var RegularExpression = function(pattern) { + this.pattern = pattern; + }; -var ByteRegularExpression = function(pattern) { - this.pattern = pattern; -}; + var ByteRegularExpression = function(pattern) { + this.pattern = pattern; + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -// Paths + // Paths -var Path = function(p) { - this.path = p; -}; + var Path = function(p) { + this.path = p; + }; -Path.prototype.toString = function() { - return this.path; -}; + Path.prototype.toString = function() { + return this.path; + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -// Bytes + // Bytes -var Bytes = function(bts, mutable) { - // bytes: arrayof [0-255] - this.bytes = bts; - this.mutable = (mutable === undefined) ? false : mutable; -}; + var Bytes = function(bts, mutable) { + // bytes: arrayof [0-255] + this.bytes = bts; + this.mutable = (mutable === undefined) ? false : mutable; + }; -Bytes.prototype.get = function(i) { + Bytes.prototype.get = function(i) { return this.bytes[i]; -}; + }; -Bytes.prototype.set = function(i, b) { + Bytes.prototype.set = function(i, b) { if (this.mutable) { - this.bytes[i] = b; + this.bytes[i] = b; } -}; + }; -Bytes.prototype.length = function() { + Bytes.prototype.length = function() { return this.bytes.length; -}; + }; -Bytes.prototype.copy = function(mutable) { + Bytes.prototype.copy = function(mutable) { return new Bytes(this.bytes.slice(0), mutable); -}; + }; -Bytes.prototype.subbytes = function(start, end) { + Bytes.prototype.subbytes = function(start, end) { if (end == null || end == undefined) { - end = this.bytes.length; + end = this.bytes.length; } return new Bytes( this.bytes.slice(start, end), true ); -}; + }; -Bytes.prototype.isEqual = function(other) { - if (! (other instanceof Bytes)) { - return false; - } - 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]) + Bytes.prototype.isEqual = function(other) { + if (! (other instanceof Bytes)) { return false; - } - return true; -}; + } + 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]) + return false; + } + return true; + }; -Bytes.prototype.toString = function(cache) { + Bytes.prototype.toString = function(cache) { var ret = ''; for (var i = 0; i < this.bytes.length; i++) { - ret += String.fromCharCode(this.bytes[i]); + ret += String.fromCharCode(this.bytes[i]); } return ret; -}; + }; -Bytes.prototype.toDisplayedString = Bytes.prototype.toString; + Bytes.prototype.toDisplayedString = Bytes.prototype.toString; -Bytes.prototype.toWrittenString = function() { + Bytes.prototype.toWrittenString = function() { var ret = ['#"']; for (var i = 0; i < this.bytes.length; i++) { - ret.push( escapeByte(this.bytes[i]) ); + ret.push( escapeByte(this.bytes[i]) ); } ret.push('"'); return ret.join(''); -}; + }; -var escapeByte = function(aByte) { + var escapeByte = function(aByte) { var ret = []; var returnVal; switch(aByte) { - case 7: returnVal = '\\a'; break; - case 8: returnVal = '\\b'; break; - case 9: returnVal = '\\t'; break; - case 10: returnVal = '\\n'; break; - case 11: returnVal = '\\v'; break; - case 12: returnVal = '\\f'; break; - case 13: returnVal = '\\r'; break; - case 34: returnVal = '\\"'; break; - case 92: returnVal = '\\\\'; break; - default: if (aByte >= 32 && aByte <= 126) { - returnVal = String.fromCharCode(aByte); - } - else { - ret.push( '\\' + aByte.toString(8) ); - } - break; + case 7: returnVal = '\\a'; break; + case 8: returnVal = '\\b'; break; + case 9: returnVal = '\\t'; break; + case 10: returnVal = '\\n'; break; + case 11: returnVal = '\\v'; break; + case 12: returnVal = '\\f'; break; + case 13: returnVal = '\\r'; break; + case 34: returnVal = '\\"'; break; + case 92: returnVal = '\\\\'; break; + default: if (aByte >= 32 && aByte <= 126) { + returnVal = String.fromCharCode(aByte); + } + else { + ret.push( '\\' + aByte.toString(8) ); + } + break; } return returnVal; -}; + }; -////////////////////////////////////////////////////////////////////// -// Boxes + ////////////////////////////////////////////////////////////////////// + // Boxes -var Box = function(x, mutable) { + var Box = function(x, mutable) { this.val = x; this.mutable = mutable; -}; + }; -Box.prototype.unbox = function() { - return this.val; -}; + Box.prototype.unbox = function() { + return this.val; + }; -Box.prototype.set = function(newVal) { - if (this.mutable) { + Box.prototype.set = function(newVal) { + if (this.mutable) { this.val = newVal; - } -}; + } + }; -Box.prototype.toString = function(cache) { - cache.put(this, true); - return "#&" + toWrittenString(this.val, cache); -}; + Box.prototype.toString = function(cache) { + cache.put(this, true); + return "#&" + toWrittenString(this.val, cache); + }; -Box.prototype.toWrittenString = function(cache) { - cache.put(this, true); - return "#&" + toWrittenString(this.val, cache); -}; + Box.prototype.toWrittenString = function(cache) { + cache.put(this, true); + return "#&" + toWrittenString(this.val, cache); + }; -Box.prototype.toDisplayedString = function(cache) { - cache.put(this, true); - return "#&" + toDisplayedString(this.val, cache); -}; + Box.prototype.toDisplayedString = function(cache) { + cache.put(this, true); + return "#&" + toDisplayedString(this.val, cache); + }; -Box.prototype.toDomNode = function(cache) { - cache.put(this, true); - var parent = document.createElement("span"); - parent.appendChild(document.createTextNode('#&')); - parent.appendChild(toDomNode(this.val, cache)); - return parent; -}; + Box.prototype.toDomNode = function(cache) { + cache.put(this, true); + var parent = document.createElement("span"); + parent.appendChild(document.createTextNode('#&')); + parent.appendChild(toDomNode(this.val, cache)); + return parent; + }; -Box.prototype.isEqual = function(other, aUnionFind) { - return ((other instanceof Box) && - isEqual(this.val, other.val, aUnionFind)); -}; + Box.prototype.isEqual = function(other, aUnionFind) { + return ((other instanceof Box) && + isEqual(this.val, other.val, aUnionFind)); + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -// Placeholders: same thing as boxes. Distinct type just to support make-reader-graph. + // Placeholders: same thing as boxes. Distinct type just to support make-reader-graph. -var Placeholder = function(x, mutable) { - this.val = x; -}; + var Placeholder = function(x, mutable) { + this.val = x; + }; -Placeholder.prototype.ref = function() { - return this.val; -}; + Placeholder.prototype.ref = function() { + return this.val; + }; -Placeholder.prototype.set = function(newVal) { - this.val = newVal; -}; + Placeholder.prototype.set = function(newVal) { + this.val = newVal; + }; -Placeholder.prototype.toString = function(cache) { - return "#"; -}; + Placeholder.prototype.toString = function(cache) { + return "#"; + }; -Placeholder.prototype.toWrittenString = function(cache) { - return "#"; -}; + Placeholder.prototype.toWrittenString = function(cache) { + return "#"; + }; -Placeholder.prototype.toDisplayedString = function(cache) { - return "#"; -}; + Placeholder.prototype.toDisplayedString = function(cache) { + return "#"; + }; -Placeholder.prototype.toDomNode = function(cache) { - var parent = document.createElement("span"); - parent.appendChild(document.createTextNode('#')); - return parent; -}; + Placeholder.prototype.toDomNode = function(cache) { + var parent = document.createElement("span"); + parent.appendChild(document.createTextNode('#')); + return parent; + }; -Placeholder.prototype.isEqual = function(other, aUnionFind) { - return ((other instanceof Placeholder) && - isEqual(this.val, other.val, aUnionFind)); -}; + Placeholder.prototype.isEqual = function(other, aUnionFind) { + return ((other instanceof Placeholder) && + isEqual(this.val, other.val, aUnionFind)); + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// @@ -459,591 +474,591 @@ Placeholder.prototype.isEqual = function(other, aUnionFind) { -// We are reusing the built-in Javascript boolean class here. -Logic = { - TRUE : true, - FALSE : false -}; + // We are reusing the built-in Javascript boolean class here. + Logic = { + TRUE : true, + FALSE : false + }; -var isBoolean = function(x) { + var isBoolean = function(x) { return (x === true || x === false); -} + } -// WARNING -// WARNING: we are extending the built-in Javascript boolean class here! -// WARNING -Boolean.prototype.toWrittenString = function(cache) { - if (this.valueOf()) { return "true"; } - return "false"; -}; -Boolean.prototype.toDisplayedString = Boolean.prototype.toWrittenString; + // WARNING + // WARNING: we are extending the built-in Javascript boolean class here! + // WARNING + Boolean.prototype.toWrittenString = function(cache) { + if (this.valueOf()) { return "true"; } + return "false"; + }; + Boolean.prototype.toDisplayedString = Boolean.prototype.toWrittenString; -Boolean.prototype.toString = function(cache) { return this.valueOf() ? "true" : "false"; }; + Boolean.prototype.toString = function(cache) { return this.valueOf() ? "true" : "false"; }; -Boolean.prototype.isEqual = function(other, aUnionFind){ - return this == other; -}; + Boolean.prototype.isEqual = function(other, aUnionFind){ + return this == other; + }; -// Chars -// Char: string -> Char -Char = function(val){ - this.val = val; -}; + // Chars + // Char: string -> Char + Char = function(val){ + this.val = val; + }; // The characters less than 256 must be eq?, according to the // documentation: // http://docs.racket-lang.org/reference/characters.html -var _CharCache = {}; -for (var i = 0; i < 256; i++) { - _CharCache[String.fromCharCode(i)] = new Char(String.fromCharCode(i)); -} - -// makeInstance: 1-character string -> Char -Char.makeInstance = function(val){ - if (_CharCache[val]) { - return _CharCache[val]; + var _CharCache = {}; + for (var i = 0; i < 256; i++) { + _CharCache[String.fromCharCode(i)] = new Char(String.fromCharCode(i)); } - return new Char(val); -}; + + // makeInstance: 1-character string -> Char + Char.makeInstance = function(val){ + if (_CharCache[val]) { + return _CharCache[val]; + } + return new Char(val); + }; -Char.prototype.toString = function(cache) { + Char.prototype.toString = function(cache) { var code = this.val.charCodeAt(0); var returnVal; switch (code) { - case 0: returnVal = '#\\nul'; break; - case 8: returnVal = '#\\backspace'; break; - case 9: returnVal = '#\\tab'; break; - case 10: returnVal = '#\\newline'; break; - case 11: returnVal = '#\\vtab'; break; - case 12: returnVal = '#\\page'; break; - case 13: returnVal = '#\\return'; break; - case 20: returnVal = '#\\space'; break; - case 127: returnVal = '#\\rubout'; break; - default: if (code >= 32 && code <= 126) { - returnVal = ("#\\" + this.val); - } - else { - var numStr = code.toString(16).toUpperCase(); - while (numStr.length < 4) { - numStr = '0' + numStr; - } - returnVal = ('#\\u' + numStr); - } - break; + case 0: returnVal = '#\\nul'; break; + case 8: returnVal = '#\\backspace'; break; + case 9: returnVal = '#\\tab'; break; + case 10: returnVal = '#\\newline'; break; + case 11: returnVal = '#\\vtab'; break; + case 12: returnVal = '#\\page'; break; + case 13: returnVal = '#\\return'; break; + case 20: returnVal = '#\\space'; break; + case 127: returnVal = '#\\rubout'; break; + default: if (code >= 32 && code <= 126) { + returnVal = ("#\\" + this.val); + } + else { + var numStr = code.toString(16).toUpperCase(); + while (numStr.length < 4) { + numStr = '0' + numStr; + } + returnVal = ('#\\u' + numStr); + } + break; } return returnVal; -}; + }; -Char.prototype.toWrittenString = Char.prototype.toString; + Char.prototype.toWrittenString = Char.prototype.toString; -Char.prototype.toDisplayedString = function (cache) { - return this.val; -}; + Char.prototype.toDisplayedString = function (cache) { + return this.val; + }; -Char.prototype.getValue = function() { - return this.val; -}; + Char.prototype.getValue = function() { + return this.val; + }; -Char.prototype.isEqual = function(other, aUnionFind){ - return other instanceof Char && this.val == other.val; -}; + Char.prototype.isEqual = function(other, aUnionFind){ + return other instanceof Char && this.val == other.val; + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -// Symbols + // Symbols -////////////////////////////////////////////////////////////////////// -var Symbol = function(val) { - this.val = val; -}; + ////////////////////////////////////////////////////////////////////// + var Symbol = function(val) { + this.val = val; + }; -var symbolCache = {}; + var symbolCache = {}; -// makeInstance: string -> Symbol. -Symbol.makeInstance = function(val) { - // To ensure that we can eq? symbols with equal values. - if (!(val in symbolCache)) { - symbolCache[val] = new Symbol(val); - } else { - } - return symbolCache[val]; -}; + // makeInstance: string -> Symbol. + Symbol.makeInstance = function(val) { + // To ensure that we can eq? symbols with equal values. + if (!(val in symbolCache)) { + symbolCache[val] = new Symbol(val); + } else { + } + return symbolCache[val]; + }; -Symbol.prototype.isEqual = function(other, aUnionFind) { - return other instanceof Symbol && - this.val == other.val; -}; + Symbol.prototype.isEqual = function(other, aUnionFind) { + return other instanceof Symbol && + this.val == other.val; + }; -Symbol.prototype.toString = function(cache) { - return this.val; -}; + Symbol.prototype.toString = function(cache) { + return this.val; + }; -Symbol.prototype.toWrittenString = function(cache) { - return this.val; -}; + Symbol.prototype.toWrittenString = function(cache) { + return this.val; + }; -Symbol.prototype.toDisplayedString = function(cache) { - return this.val; -}; + Symbol.prototype.toDisplayedString = function(cache) { + return this.val; + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -// Keywords + // Keywords -var Keyword = function(val) { - this.val = val; -}; + var Keyword = function(val) { + this.val = val; + }; -var keywordCache = {}; + var keywordCache = {}; -// makeInstance: string -> Keyword. -Keyword.makeInstance = function(val) { - // To ensure that we can eq? symbols with equal values. - if (!(val in keywordCache)) { - keywordCache[val] = new Keyword(val); - } else { - } - return keywordCache[val]; -}; + // makeInstance: string -> Keyword. + Keyword.makeInstance = function(val) { + // To ensure that we can eq? symbols with equal values. + if (!(val in keywordCache)) { + keywordCache[val] = new Keyword(val); + } else { + } + return keywordCache[val]; + }; -Keyword.prototype.isEqual = function(other, aUnionFind) { - return other instanceof Keyword && - this.val == other.val; -}; + Keyword.prototype.isEqual = function(other, aUnionFind) { + return other instanceof Keyword && + this.val == other.val; + }; -Keyword.prototype.toString = function(cache) { - return this.val; -}; + Keyword.prototype.toString = function(cache) { + return this.val; + }; -Keyword.prototype.toWrittenString = function(cache) { - return this.val; -}; + Keyword.prototype.toWrittenString = function(cache) { + return this.val; + }; -Keyword.prototype.toDisplayedString = function(cache) { - return this.val; -}; + Keyword.prototype.toDisplayedString = function(cache) { + return this.val; + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -Empty = function() { -}; -Empty.EMPTY = new Empty(); + Empty = function() { + }; + Empty.EMPTY = new Empty(); -Empty.prototype.isEqual = function(other, aUnionFind) { - return other instanceof Empty; -}; + Empty.prototype.isEqual = function(other, aUnionFind) { + return other instanceof Empty; + }; -Empty.prototype.reverse = function() { - return this; -}; + Empty.prototype.reverse = function() { + return this; + }; -Empty.prototype.first = function() { - helpers.raise(types.incompleteExn( - types.exnFailContract, - "first can't be applied on empty.", - [])); -}; -Empty.prototype.rest = function() { - helpers.raise(types.incompleteExn( - types.exnFailContract, - "rest can't be applied on empty.", - [])); -}; -Empty.prototype.isEmpty = function() { - return true; -}; -Empty.prototype.toWrittenString = function(cache) { return "empty"; }; -Empty.prototype.toDisplayedString = function(cache) { return "empty"; }; -Empty.prototype.toString = function(cache) { return "()"; }; + Empty.prototype.first = function() { + helpers.raise(types.incompleteExn( + types.exnFailContract, + "first can't be applied on empty.", + [])); + }; + Empty.prototype.rest = function() { + helpers.raise(types.incompleteExn( + types.exnFailContract, + "rest can't be applied on empty.", + [])); + }; + Empty.prototype.isEmpty = function() { + return true; + }; + 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){ - return b; -}; + // Empty.append: (listof X) -> (listof X) + Empty.prototype.append = function(b){ + return b; + }; -Cons = function(f, r) { - this.f = f; - this.r = r; -}; + Cons = function(f, r) { + this.f = f; + this.r = r; + }; -Cons.prototype.reverse = function() { - var lst = this; - var ret = Empty.EMPTY; - while (!lst.isEmpty()){ - ret = Cons.makeInstance(lst.first(), ret); - lst = lst.rest(); - } - return ret; -}; + Cons.prototype.reverse = function() { + var lst = this; + var ret = Empty.EMPTY; + while (!lst.isEmpty()){ + ret = Cons.makeInstance(lst.first(), ret); + lst = lst.rest(); + } + return ret; + }; -Cons.makeInstance = function(f, r) { - return new Cons(f, r); -}; + Cons.makeInstance = function(f, r) { + return new Cons(f, r); + }; -// FIXME: can we reduce the recursion on this? -Cons.prototype.isEqual = function(other, aUnionFind) { - if (! (other instanceof Cons)) { - return Logic.FALSE; - } - return (isEqual(this.first(), other.first(), aUnionFind) && - isEqual(this.rest(), other.rest(), aUnionFind)); -}; + // FIXME: can we reduce the recursion on this? + Cons.prototype.isEqual = function(other, aUnionFind) { + if (! (other instanceof Cons)) { + return Logic.FALSE; + } + return (isEqual(this.first(), other.first(), aUnionFind) && + isEqual(this.rest(), other.rest(), aUnionFind)); + }; -Cons.prototype.first = function() { - return this.f; -}; + Cons.prototype.first = function() { + return this.f; + }; -Cons.prototype.rest = function() { - return this.r; -}; + Cons.prototype.rest = function() { + return this.r; + }; -Cons.prototype.isEmpty = function() { - return false; -}; + Cons.prototype.isEmpty = function() { + return false; + }; -// Cons.append: (listof X) -> (listof X) -Cons.prototype.append = function(b){ - if (b === Empty.EMPTY) - return this; - var ret = b; - var lst = this.reverse(); - while ( !lst.isEmpty() ) { - ret = Cons.makeInstance(lst.first(), ret); - lst = lst.rest(); - } + // Cons.append: (listof X) -> (listof X) + Cons.prototype.append = function(b){ + if (b === Empty.EMPTY) + return this; + var ret = b; + var lst = this.reverse(); + while ( !lst.isEmpty() ) { + ret = Cons.makeInstance(lst.first(), ret); + lst = lst.rest(); + } - return ret; -}; + return ret; + }; -Cons.prototype.toWrittenString = function(cache) { - cache.put(this, true); - var texts = []; - var p = this; - while ( p instanceof Cons ) { - texts.push(toWrittenString(p.first(), cache)); - p = p.rest(); - if (typeof(p) === 'object' && cache.containsKey(p)) { - break; - } - } - if ( p !== Empty.EMPTY ) { - texts.push('.'); - texts.push(toWrittenString(p, cache)); - } -// while (true) { -// if ((!(p instanceof Cons)) && (!(p instanceof Empty))) { -// texts.push("."); -// texts.push(toWrittenString(p, cache)); -// break; -// } -// if (p.isEmpty()) -// break; -// texts.push(toWrittenString(p.first(), cache)); -// p = p.rest(); -// } - return "(" + texts.join(" ") + ")"; -}; + Cons.prototype.toWrittenString = function(cache) { + cache.put(this, true); + var texts = []; + var p = this; + while ( p instanceof Cons ) { + texts.push(toWrittenString(p.first(), cache)); + p = p.rest(); + if (typeof(p) === 'object' && cache.containsKey(p)) { + break; + } + } + if ( p !== Empty.EMPTY ) { + texts.push('.'); + texts.push(toWrittenString(p, cache)); + } + // while (true) { + // if ((!(p instanceof Cons)) && (!(p instanceof Empty))) { + // texts.push("."); + // texts.push(toWrittenString(p, cache)); + // break; + // } + // if (p.isEmpty()) + // break; + // texts.push(toWrittenString(p.first(), cache)); + // p = p.rest(); + // } + return "(" + texts.join(" ") + ")"; + }; -Cons.prototype.toString = Cons.prototype.toWrittenString; + Cons.prototype.toString = Cons.prototype.toWrittenString; -Cons.prototype.toDisplayedString = function(cache) { - cache.put(this, true); - var texts = []; - var p = this; - while ( p instanceof Cons ) { - texts.push(toDisplayedString(p.first(), cache)); - p = p.rest(); - if (typeof(p) === 'object' && cache.containsKey(p)) { - break; - } - } - if ( p !== Empty.EMPTY ) { - texts.push('.'); - texts.push(toDisplayedString(p, cache)); - } -// while (true) { -// if ((!(p instanceof Cons)) && (!(p instanceof Empty))) { -// texts.push("."); -// texts.push(toDisplayedString(p, cache)); -// break; -// } -// if (p.isEmpty()) -// break; -// texts.push(toDisplayedString(p.first(), cache)); -// p = p.rest(); -// } - return "(" + texts.join(" ") + ")"; -}; + Cons.prototype.toDisplayedString = function(cache) { + cache.put(this, true); + var texts = []; + var p = this; + while ( p instanceof Cons ) { + texts.push(toDisplayedString(p.first(), cache)); + p = p.rest(); + if (typeof(p) === 'object' && cache.containsKey(p)) { + break; + } + } + if ( p !== Empty.EMPTY ) { + texts.push('.'); + texts.push(toDisplayedString(p, cache)); + } + // while (true) { + // if ((!(p instanceof Cons)) && (!(p instanceof Empty))) { + // texts.push("."); + // texts.push(toDisplayedString(p, cache)); + // break; + // } + // if (p.isEmpty()) + // break; + // texts.push(toDisplayedString(p.first(), cache)); + // p = p.rest(); + // } + return "(" + texts.join(" ") + ")"; + }; -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 ) { - appendChild(node, toDomNode(p.first(), cache)); - p = p.rest(); - if ( p !== Empty.EMPTY ) { + 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 ) { + appendChild(node, toDomNode(p.first(), cache)); + p = p.rest(); + if ( p !== Empty.EMPTY ) { + appendChild(node, document.createTextNode(" ")); + } + if (typeof(p) === 'object' && cache.containsKey(p)) { + break; + } + } + if ( p !== Empty.EMPTY ) { + appendChild(node, document.createTextNode(".")); appendChild(node, document.createTextNode(" ")); - } - if (typeof(p) === 'object' && cache.containsKey(p)) { - break; - } + appendChild(node, toDomNode(p, cache)); + } + // while (true) { + // if ((!(p instanceof Cons)) && (!(p instanceof Empty))) { + // appendChild(node, document.createTextNode(" ")); + // appendChild(node, document.createTextNode(".")); + // appendChild(node, document.createTextNode(" ")); + // appendChild(node, toDomNode(p, cache)); + // break; + // } + // if (p.isEmpty()) + // break; + // appendChild(node, toDomNode(p.first(), cache)); + // p = p.rest(); + // if (! p.isEmpty()) { + // appendChild(node, document.createTextNode(" ")); + // } + // } + node.appendChild(document.createTextNode(")")); + return node; + }; + + + + ////////////////////////////////////////////////////////////////////// + + Vector = function(n, initialElements) { + this.elts = new Array(n); + if (initialElements) { + for (var i = 0; i < n; i++) { + this.elts[i] = initialElements[i]; + } + } else { + for (var i = 0; i < n; i++) { + this.elts[i] = undefined; + } + } + this.mutable = true; + }; + Vector.makeInstance = function(n, elts) { + return new Vector(n, elts); } - if ( p !== Empty.EMPTY ) { - appendChild(node, document.createTextNode(".")); - appendChild(node, document.createTextNode(" ")); - appendChild(node, toDomNode(p, cache)); - } -// while (true) { -// if ((!(p instanceof Cons)) && (!(p instanceof Empty))) { -// appendChild(node, document.createTextNode(" ")); -// appendChild(node, document.createTextNode(".")); -// appendChild(node, document.createTextNode(" ")); -// appendChild(node, toDomNode(p, cache)); -// break; -// } -// if (p.isEmpty()) -// break; -// appendChild(node, toDomNode(p.first(), cache)); -// p = p.rest(); -// if (! p.isEmpty()) { -// appendChild(node, document.createTextNode(" ")); -// } -// } - node.appendChild(document.createTextNode(")")); - return node; -}; - - - -////////////////////////////////////////////////////////////////////// - -Vector = function(n, initialElements) { - this.elts = new Array(n); - if (initialElements) { - for (var i = 0; i < n; i++) { - this.elts[i] = initialElements[i]; - } - } else { - for (var i = 0; i < n; i++) { - this.elts[i] = undefined; - } - } - this.mutable = true; -}; -Vector.makeInstance = function(n, elts) { - return new Vector(n, elts); -} Vector.prototype.length = function() { return this.elts.length; }; -Vector.prototype.ref = function(k) { - return this.elts[k]; -}; -Vector.prototype.set = function(k, v) { - this.elts[k] = v; -}; + Vector.prototype.ref = function(k) { + return this.elts[k]; + }; + Vector.prototype.set = function(k, v) { + this.elts[k] = v; + }; -Vector.prototype.isEqual = function(other, aUnionFind) { - if (other != null && other != undefined && other instanceof Vector) { - if (other.length() != this.length()) { - return false - } - for (var i = 0; i < this.length(); i++) { - if (! isEqual(this.elts[i], other.elts[i], aUnionFind)) { - return false; + Vector.prototype.isEqual = function(other, aUnionFind) { + if (other != null && other != undefined && other instanceof Vector) { + if (other.length() != this.length()) { + return false } - } - return true; - } else { - return false; - } -}; + for (var i = 0; i < this.length(); i++) { + if (! isEqual(this.elts[i], other.elts[i], aUnionFind)) { + return false; + } + } + return true; + } else { + return false; + } + }; -Vector.prototype.toList = function() { - var ret = Empty.EMPTY; - for (var i = this.length() - 1; i >= 0; i--) { - ret = Cons.makeInstance(this.elts[i], ret); - } - return ret; -}; + Vector.prototype.toList = function() { + var ret = Empty.EMPTY; + for (var i = this.length() - 1; i >= 0; i--) { + ret = Cons.makeInstance(this.elts[i], ret); + } + return ret; + }; -Vector.prototype.toWrittenString = function(cache) { - cache.put(this, true); - var texts = []; - for (var i = 0; i < this.length(); i++) { - texts.push(toWrittenString(this.ref(i), cache)); - } - return "#(" + texts.join(" ") + ")"; -}; + Vector.prototype.toWrittenString = function(cache) { + cache.put(this, true); + var texts = []; + for (var i = 0; i < this.length(); i++) { + texts.push(toWrittenString(this.ref(i), cache)); + } + return "#(" + texts.join(" ") + ")"; + }; -Vector.prototype.toDisplayedString = function(cache) { - cache.put(this, true); - var texts = []; - for (var i = 0; i < this.length(); i++) { - texts.push(toDisplayedString(this.ref(i), cache)); - } - return "#(" + texts.join(" ") + ")"; -}; + Vector.prototype.toDisplayedString = function(cache) { + cache.put(this, true); + var texts = []; + for (var i = 0; i < this.length(); i++) { + texts.push(toDisplayedString(this.ref(i), cache)); + } + return "#(" + texts.join(" ") + ")"; + }; -Vector.prototype.toDomNode = function(cache) { - cache.put(this, true); - var node = document.createElement("span"); - node.appendChild(document.createTextNode("#(")); - for (var i = 0; i < this.length(); i++) { - appendChild(node, - toDomNode(this.ref(i), cache)); - if (i !== this.length()-1) { - appendChild(node, document.createTextNode(" ")); - } - } - node.appendChild(document.createTextNode(")")); - return node; -}; + Vector.prototype.toDomNode = function(cache) { + cache.put(this, true); + var node = document.createElement("span"); + node.appendChild(document.createTextNode("#(")); + for (var i = 0; i < this.length(); i++) { + appendChild(node, + toDomNode(this.ref(i), cache)); + if (i !== this.length()-1) { + appendChild(node, document.createTextNode(" ")); + } + } + node.appendChild(document.createTextNode(")")); + return node; + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -// Now using mutable strings -var Str = function(chars) { + // Now using mutable strings + var Str = function(chars) { this.chars = chars; this.length = chars.length; this.mutable = true; -} + } -Str.makeInstance = function(chars) { + Str.makeInstance = function(chars) { return new Str(chars); -} + } -Str.fromString = function(s) { + Str.fromString = function(s) { return Str.makeInstance(s.split("")); -} + } -Str.prototype.toString = function() { + Str.prototype.toString = function() { return this.chars.join(""); -} + } -Str.prototype.toWrittenString = function(cache) { - return escapeString(this.toString()); -} + Str.prototype.toWrittenString = function(cache) { + return escapeString(this.toString()); + } -Str.prototype.toDisplayedString = Str.prototype.toString; + Str.prototype.toDisplayedString = Str.prototype.toString; -Str.prototype.copy = function() { + Str.prototype.copy = function() { return Str.makeInstance(this.chars.slice(0)); -} + } -Str.prototype.substring = function(start, end) { + Str.prototype.substring = function(start, end) { if (end == null || end == undefined) { - end = this.length; + end = this.length; } return Str.makeInstance( this.chars.slice(start, end) ); -} + } -Str.prototype.charAt = function(index) { + Str.prototype.charAt = function(index) { return this.chars[index]; -} + } -Str.prototype.charCodeAt = function(index) { + Str.prototype.charCodeAt = function(index) { return this.chars[index].charCodeAt(0); -} + } -Str.prototype.replace = function(expr, newStr) { + Str.prototype.replace = function(expr, newStr) { return Str.fromString( this.toString().replace(expr, newStr) ); -} + } -Str.prototype.isEqual = function(other, aUnionFind) { + Str.prototype.isEqual = function(other, aUnionFind) { if ( !(other instanceof Str || typeof(other) == 'string') ) { - return false; + return false; } return this.toString() === other.toString(); -} + } -Str.prototype.set = function(i, c) { + Str.prototype.set = function(i, c) { this.chars[i] = c; -} + } -Str.prototype.toUpperCase = function() { + Str.prototype.toUpperCase = function() { return Str.fromString( this.chars.join("").toUpperCase() ); -} + } -Str.prototype.toLowerCase = function() { + Str.prototype.toLowerCase = function() { return Str.fromString( this.chars.join("").toLowerCase() ); -} + } -Str.prototype.match = function(regexpr) { + Str.prototype.match = function(regexpr) { return this.toString().match(regexpr); -} + } -//var _quoteReplacingRegexp = new RegExp("[\"\\\\]", "g"); -var escapeString = function(s) { - return '"' + replaceUnprintableStringChars(s) + '"'; -// return '"' + s.replace(_quoteReplacingRegexp, -// function(match, submatch, index) { -// return "\\" + match; -// }) + '"'; -}; + //var _quoteReplacingRegexp = new RegExp("[\"\\\\]", "g"); + var escapeString = function(s) { + return '"' + replaceUnprintableStringChars(s) + '"'; + // return '"' + s.replace(_quoteReplacingRegexp, + // function(match, submatch, index) { + // return "\\" + match; + // }) + '"'; + }; -var replaceUnprintableStringChars = function(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; + 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(''); -}; + }; -/* + /* // Strings // For the moment, we just reuse Javascript strings. String = String; @@ -1073,11 +1088,7 @@ String.prototype.toDisplayedString = function(cache) { */ -////////////////////////////////////////////////////////////////////// - -// makeLowLevelEqHash: -> hashtable -// Constructs an eq hashtable that uses Moby's getEqHashCode function. -var makeLowLevelEqHash = helpers.makeLowLevelEqHash; + ////////////////////////////////////////////////////////////////////// @@ -1086,247 +1097,247 @@ var makeLowLevelEqHash = helpers.makeLowLevelEqHash; -////////////////////////////////////////////////////////////////////// -// Hashtables -var EqHashTable = function(inputHash) { - this.hash = makeLowLevelEqHash(); - this.mutable = true; + ////////////////////////////////////////////////////////////////////// + // Hashtables + var EqHashTable = function(inputHash) { + this.hash = makeLowLevelEqHash(); + this.mutable = true; -}; -EqHashTable = EqHashTable; + }; + EqHashTable = EqHashTable; -EqHashTable.prototype.toWrittenString = function(cache) { - var keys = this.hash.keys(); - var ret = []; - for (var i = 0; i < keys.length; i++) { + 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); ret.push('(' + keyStr + ' . ' + valStr + ')'); - } - return ('#hasheq(' + ret.join(' ') + ')'); -}; + } + return ('#hasheq(' + ret.join(' ') + ')'); + }; -EqHashTable.prototype.toDisplayedString = function(cache) { - var keys = this.hash.keys(); - var ret = []; - for (var i = 0; i < keys.length; i++) { + EqHashTable.prototype.toDisplayedString = function(cache) { + var keys = this.hash.keys(); + var ret = []; + for (var i = 0; i < keys.length; i++) { var keyStr = types.toDisplayedString(keys[i], cache); var valStr = types.toDisplayedString(this.hash.get(keys[i]), cache); ret.push('(' + keyStr + ' . ' + valStr + ')'); - } - return ('#hasheq(' + ret.join(' ') + ')'); -}; + } + return ('#hasheq(' + ret.join(' ') + ')'); + }; -EqHashTable.prototype.isEqual = function(other, aUnionFind) { - if ( !(other instanceof EqHashTable) ) { - return false; - } + EqHashTable.prototype.isEqual = function(other, aUnionFind) { + if ( !(other instanceof EqHashTable) ) { + return false; + } - 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]) && - isEqual(this.hash.get(keys[i]), - other.hash.get(keys[i]), - aUnionFind)) ) { - return false; - } - } - return true; -}; - - - -var EqualHashTable = function(inputHash) { - this.hash = new _Hashtable(function(x) { - return toWrittenString(x); - }, - function(x, y) { - return isEqual(x, y, new UnionFind()); - }); - this.mutable = true; -}; - -EqualHashTable = EqualHashTable; - -EqualHashTable.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); - ret.push('(' + keyStr + ' . ' + valStr + ')'); - } - return ('#hash(' + ret.join(' ') + ')'); -}; -EqualHashTable.prototype.toDisplayedString = function(cache) { - var keys = this.hash.keys(); - var ret = []; - for (var i = 0; i < keys.length; i++) { - var keyStr = types.toDisplayedString(keys[i], cache); - var valStr = types.toDisplayedString(this.hash.get(keys[i]), cache); - ret.push('(' + keyStr + ' . ' + valStr + ')'); - } - return ('#hash(' + ret.join(' ') + ')'); -}; - -EqualHashTable.prototype.isEqual = function(other, aUnionFind) { - if ( !(other instanceof EqualHashTable) ) { - return false; - } - - 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]) && - isEqual(this.hash.get(keys[i]), - other.hash.get(keys[i]), - aUnionFind))) { + if (this.hash.keys().length != other.hash.keys().length) { return false; - } - } - return true; -}; + } + + var keys = this.hash.keys(); + for (var i = 0; i < keys.length; i++){ + if ( !(other.hash.containsKey(keys[i]) && + isEqual(this.hash.get(keys[i]), + other.hash.get(keys[i]), + aUnionFind)) ) { + return false; + } + } + return true; + }; -////////////////////////////////////////////////////////////////////// -var JsValue = function(name, val) { + var EqualHashTable = function(inputHash) { + this.hash = new _Hashtable(function(x) { + return toWrittenString(x); + }, + function(x, y) { + return isEqual(x, y, new UnionFind()); + }); + this.mutable = true; + }; + + EqualHashTable = EqualHashTable; + + EqualHashTable.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); + ret.push('(' + keyStr + ' . ' + valStr + ')'); + } + return ('#hash(' + ret.join(' ') + ')'); + }; + EqualHashTable.prototype.toDisplayedString = function(cache) { + var keys = this.hash.keys(); + var ret = []; + for (var i = 0; i < keys.length; i++) { + var keyStr = types.toDisplayedString(keys[i], cache); + var valStr = types.toDisplayedString(this.hash.get(keys[i]), cache); + ret.push('(' + keyStr + ' . ' + valStr + ')'); + } + return ('#hash(' + ret.join(' ') + ')'); + }; + + EqualHashTable.prototype.isEqual = function(other, aUnionFind) { + if ( !(other instanceof EqualHashTable) ) { + return false; + } + + 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]) && + isEqual(this.hash.get(keys[i]), + other.hash.get(keys[i]), + aUnionFind))) { + return false; + } + } + return true; + }; + + + ////////////////////////////////////////////////////////////////////// + + var JsValue = function(name, val) { this.name = name; this.val = val; -}; + }; -JsValue.prototype.toString = function() { + JsValue.prototype.toString = function() { return '#'; -}; + }; -JsValue.prototype.toDomNode = function(cache) { + JsValue.prototype.toDomNode = function(cache) { return toDomNode(this.val, cache); -}; + }; -JsValue.prototype.isEqual = function(other, aUnionFind) { + JsValue.prototype.isEqual = function(other, aUnionFind) { return (this.val === other.val); -}; + }; -// unbox: jsvalue -> any -// Unwraps the value out of the JsValue box. -JsValue.prototype.unbox = function() { - return this.val; -}; + // unbox: jsvalue -> any + // Unwraps the value out of the JsValue box. + JsValue.prototype.unbox = function() { + return this.val; + }; -var WrappedSchemeValue = function(val) { + var WrappedSchemeValue = function(val) { this.val = val; -}; + }; -WrappedSchemeValue.prototype.toString = function() { return toString(this.val); }; -WrappedSchemeValue.prototype.toWrittenString = function(cache) { return toWrittenString(this.val, cache); }; -WrappedSchemeValue.prototype.toDisplayedString = function(cache) { return toDisplayedString(this.val, cache); }; + WrappedSchemeValue.prototype.toString = function() { return toString(this.val); }; + WrappedSchemeValue.prototype.toWrittenString = function(cache) { return toWrittenString(this.val, cache); }; + WrappedSchemeValue.prototype.toDisplayedString = function(cache) { return toDisplayedString(this.val, cache); }; -// unbox: jsvalue -> any -// Unwraps the value out of the WrappedSchemeValue box. -WrappedSchemeValue.prototype.unbox = function() { - return this.val; -}; + // unbox: jsvalue -> any + // Unwraps the value out of the WrappedSchemeValue box. + WrappedSchemeValue.prototype.unbox = function() { + return this.val; + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -var WorldConfig = function(startup, shutdown, startupArgs) { + var WorldConfig = function(startup, shutdown, startupArgs) { this.startup = startup; this.shutdown = shutdown; this.startupArgs = startupArgs; -}; + }; -WorldConfig.prototype.toString = function() { + WorldConfig.prototype.toString = function() { return '#'; -}; + }; -WorldConfig.prototype.isEqual = function(other, aUnionFind) { + WorldConfig.prototype.isEqual = function(other, aUnionFind) { return ( isEqual(this.startup, other.startup, aUnionFind) && isEqual(this.shutdown, other.shutdown, aUnionFind) && isEqual(this.shutdownArg, other.shutdownArg, aUnionFind) && isEqual(this.restartArg, other.restartArg, aUnionFind) ); -}; + }; -var Effect = makeStructureType('effect', false, 0, 0, false, false); -Effect.type.prototype.invokeEffect = function() { + var Effect = makeStructureType('effect', false, 0, 0, false, false); + Effect.type.prototype.invokeEffect = function() { helpers.raise(types.incompleteExn( - types.exnFail, - 'effect type created without using make-effect-type', - [])); -}; + types.exnFail, + 'effect type created without using make-effect-type', + [])); + }; -var makeEffectType = function(name, superType, initFieldCnt, impl, guard) { + var makeEffectType = function(name, superType, initFieldCnt, impl, guard) { if ( !superType ) { - superType = Effect; + superType = Effect; } var newType = makeStructureType(name, superType, initFieldCnt, 0, false, guard); var lastFieldIndex = newType.firstField + newType.numberOfFields; newType.type.prototype.invokeEffect = function(aBigBang, k) { - var schemeChangeWorld = new PrimProc('update-world', 1, false, false, - function(worldUpdater) { - helpers.check(worldUpdater, helpers.procArityContains(1), - 'update-world', 'procedure (arity 1)', 1); - - return new INTERNAL_PAUSE( - function(caller, onSuccess, onFail) { - aBigBang.changeWorld(function(w, k2) { - caller(worldUpdater, - [w], k2, - function(e) { throw e; }, - 'change-world (effect)'); - }, - function() { onSuccess(VOID_VALUE, 'restarting (change-world (effect))'); }); - }); - }); + var schemeChangeWorld = new PrimProc('update-world', 1, false, false, + function(worldUpdater) { + helpers.check(worldUpdater, helpers.procArityContains(1), + 'update-world', 'procedure (arity 1)', 1); + + return new INTERNAL_PAUSE( + function(caller, onSuccess, onFail) { + aBigBang.changeWorld(function(w, k2) { + caller(worldUpdater, + [w], k2, + function(e) { throw e; }, + 'change-world (effect)'); + }, + function() { onSuccess(VOID_VALUE, 'restarting (change-world (effect))'); }); + }); + }); - var args = this._fields.slice(0, lastFieldIndex); - args.unshift(schemeChangeWorld); - return aBigBang.caller(impl, args, k, function(e) { throw e; }, 'invoking effect ' + name); + var args = this._fields.slice(0, lastFieldIndex); + args.unshift(schemeChangeWorld); + return aBigBang.caller(impl, args, k, function(e) { throw e; }, 'invoking effect ' + name); } return newType; -}; + }; -var RenderEffect = makeStructureType('render-effect', false, 0, 0, false, false); -RenderEffect.type.prototype.callImplementation = function(caller, k) { + var RenderEffect = makeStructureType('render-effect', false, 0, 0, false, false); + RenderEffect.type.prototype.callImplementation = function(caller, k) { helpers.raise(types.incompleteExn( - types.exnFail, - 'render effect created without using make-render-effect-type', - [])); -}; + types.exnFail, + 'render effect created without using make-render-effect-type', + [])); + }; -var makeRenderEffectType = function(name, superType, initFieldCnt, impl, guard) { + var makeRenderEffectType = function(name, superType, initFieldCnt, impl, guard) { if ( !superType ) { - superType = RenderEffect; + superType = RenderEffect; } var newType = makeStructureType(name, superType, initFieldCnt, 0, false, guard); var lastFieldIndex = newType.firstField + newType.numberOfFields; newType.type.prototype.callImplementation = function(caller, k) { - var args = this._fields.slice(0, lastFieldIndex); - caller(impl, args, k); + var args = this._fields.slice(0, lastFieldIndex); + caller(impl, args, k); } return newType; -}; + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// @@ -1336,7 +1347,7 @@ var makeRenderEffectType = function(name, superType, initFieldCnt, impl, guard) -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// @@ -1344,689 +1355,689 @@ var makeRenderEffectType = function(name, superType, initFieldCnt, impl, guard) -var toWrittenString = function(x, cache) { - if (! cache) { - cache = makeLowLevelEqHash(); - } + var toWrittenString = function(x, cache) { + if (! cache) { + cache = makeLowLevelEqHash(); + } - if (typeof(x) === 'object') { + if (typeof(x) === 'object') { if (cache.containsKey(x)) { - return "..."; + return "..."; } - } + } - if (x == undefined || x == null) { - return "#"; - } - if (typeof(x) == 'string') { - return escapeString(x.toString()); - } - if (typeof(x) != 'object' && typeof(x) != 'function') { - return x.toString(); - } + if (x == undefined || x == null) { + return "#"; + } + if (typeof(x) == 'string') { + return escapeString(x.toString()); + } + if (typeof(x) != 'object' && typeof(x) != 'function') { + return x.toString(); + } - var returnVal; - if (typeof(x.toWrittenString) !== 'undefined') { - returnVal = x.toWrittenString(cache); - } else if (typeof(x.toDisplayedString) !== 'undefined') { - returnVal = x.toDisplayedString(cache); - } else { - returnVal = x.toString(); - } - cache.remove(x); - return returnVal; -}; + var returnVal; + if (typeof(x.toWrittenString) !== 'undefined') { + returnVal = x.toWrittenString(cache); + } else if (typeof(x.toDisplayedString) !== 'undefined') { + returnVal = x.toDisplayedString(cache); + } else { + returnVal = x.toString(); + } + cache.remove(x); + return returnVal; + }; -var toDisplayedString = function(x, cache) { - if (! cache) { - cache = makeLowLevelEqHash(); - } - if (typeof(x) === 'object') { + var toDisplayedString = function(x, cache) { + if (! cache) { + cache = makeLowLevelEqHash(); + } + if (typeof(x) === 'object') { if (cache.containsKey(x)) { - return "..."; + return "..."; } - } + } - if (x == undefined || x == null) { - return "#"; - } - if (typeof(x) == 'string') { - return x; - } - if (typeof(x) != 'object' && typeof(x) != 'function') { - return x.toString(); - } + if (x == undefined || x == null) { + return "#"; + } + 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 returnVal; + if (typeof(x.toDisplayedString) !== 'undefined') { + returnVal = x.toDisplayedString(cache); + } else if (typeof(x.toWrittenString) !== 'undefined') { + returnVal = x.toWrittenString(cache); + } else { + returnVal = x.toString(); + } + cache.remove(x); + return returnVal; + }; -// toDomNode: scheme-value -> dom-node -var toDomNode = function(x, cache) { - if (! cache) { - cache = makeLowLevelEqHash(); - } - if (isNumber(x)) { - return numberToDomNode(x); - } + // toDomNode: scheme-value -> dom-node + var toDomNode = function(x, cache) { + if (! cache) { + cache = makeLowLevelEqHash(); + } + if (isNumber(x)) { + return numberToDomNode(x); + } - if (typeof(x) == 'object') { + if (typeof(x) == 'object') { if (cache.containsKey(x)) { var node = document.createElement("span"); node.appendChild(document.createTextNode("...")); return node; } - } + } - if (x == undefined || x == null) { - var node = document.createElement("span"); - node.appendChild(document.createTextNode("#")); - return node; - } - if (typeof(x) == 'string') { - var wrapper = document.createElement("span"); - wrapper.style["white-space"] = "pre"; - var node = document.createTextNode(toWrittenString(x)); - wrapper.appendChild(node); - return wrapper; - } - if (typeof(x) != 'object' && typeof(x) != 'function') { - var node = document.createElement("span"); - node.appendChild(document.createTextNode(x.toString())); - return node; - } - - var returnVal; - if (x.nodeType) { - returnVal = x; - } else if (typeof(x.toDomNode) !== 'undefined') { - returnVal = x.toDomNode(cache); - } else if (typeof(x.toWrittenString) !== 'undefined') { - - var node = document.createElement("span"); - node.appendChild(document.createTextNode(x.toWrittenString(cache))); - returnVal = node; - } else if (typeof(x.toDisplayedString) !== 'undefined') { - var node = document.createElement("span"); - node.appendChild(document.createTextNode(x.toDisplayedString(cache))); - returnVal = node; - } else { - var node = document.createElement("span"); - node.appendChild(document.createTextNode(x.toString())); - returnVal = node; - } - cache.remove(x); - return returnVal; -}; - - -// numberToDomNode: jsnum -> dom -// Given a jsnum, produces a dom-node representation. -var numberToDomNode = function(n) { - var node; - if (jsnums.isExact(n)) { - if (jsnums.isInteger(n)) { - node = document.createElement("span"); - node.appendChild(document.createTextNode(n.toString())); + if (x == undefined || x == null) { + var node = document.createElement("span"); + node.appendChild(document.createTextNode("#")); return node; - } else if (jsnums.isRational(n)) { - return rationalToDomNode(n); - } else if (jsnums.isComplex(n)) { - node = document.createElement("span"); - node.appendChild(document.createTextNode(n.toString())); + } + if (typeof(x) == 'string') { + var wrapper = document.createElement("span"); + wrapper.style["white-space"] = "pre"; + var node = document.createTextNode(toWrittenString(x)); + wrapper.appendChild(node); + return wrapper; + } + if (typeof(x) != 'object' && typeof(x) != 'function') { + var node = document.createElement("span"); + node.appendChild(document.createTextNode(x.toString())); return node; - } else { - node = document.createElement("span"); - node.appendChild(document.createTextNode(n.toString())); - return node; - } - } else { - node = document.createElement("span"); - node.appendChild(document.createTextNode(n.toString())); - return node; - } -}; + } -// rationalToDomNode: rational -> dom-node -var rationalToDomNode = function(n) { - var node = document.createElement("span"); - var chunks = jsnums.toRepeatingDecimal(jsnums.numerator(n), - jsnums.denominator(n)); - node.appendChild(document.createTextNode(chunks[0] + '.')) - node.appendChild(document.createTextNode(chunks[1])); - var overlineSpan = document.createElement("span"); - overlineSpan.style.textDecoration = 'overline'; - overlineSpan.appendChild(document.createTextNode(chunks[2])); - node.appendChild(overlineSpan); - return node; -} - - - - -var isNumber = jsnums.isSchemeNumber; - -var isReal = jsnums.isReal; -var isRational = jsnums.isRational; -var isComplex = isNumber; -var isInteger = jsnums.isInteger; - -var isNatural = function(x) { - return (jsnums.isExact(x) && isInteger(x) - && jsnums.greaterThanOrEqual(x, 0)); -}; -var isNonNegativeReal = function(x) { - return isReal(x) && jsnums.greaterThanOrEqual(x, 0); -}; - - - - - - -var isString = function(s) { - return (typeof s === 'string' || s instanceof Str); -} - - -// isEqual: X Y -> boolean -// Returns true if the objects are equivalent; otherwise, returns false. -var isEqual = function(x, y, aUnionFind) { - if (x === y) { return true; } - - if (isNumber(x) && isNumber(y)) { - return jsnums.eqv(x, y); - } - - if (isString(x) && isString(y)) { - return x.toString() === y.toString(); - } - - if (x == undefined || x == null) { - return (y == undefined || y == null); - } - - if ( typeof(x) == 'object' && - typeof(y) == 'object' && - x.isEqual && - y.isEqual) { - - if (typeof (aUnionFind) === 'undefined') { - aUnionFind = new UnionFind(); - } - - if (aUnionFind.find(x) === aUnionFind.find(y)) { - return true; - } - else { - aUnionFind.merge(x, y); - return x.isEqual(y, aUnionFind); - } - } - return false; -}; - - - - - -// liftToplevelToFunctionValue: primitive-function string fixnum scheme-value -> scheme-value -// Lifts a primitive toplevel or module-bound value to a scheme value. -var liftToplevelToFunctionValue = function(primitiveF, - name, - minArity, - procedureArityDescription) { - if (! primitiveF._mobyLiftedFunction) { - var lifted = function(args) { - return primitiveF.apply(null, args.slice(0, minArity).concat([args.slice(minArity)])); - }; - lifted.isEqual = function(other, cache) { - return this === other; - } - lifted.toWrittenString = function(cache) { - return "#"; - }; - lifted.toDisplayedString = lifted.toWrittenString; - lifted.procedureArity = procedureArityDescription; - primitiveF._mobyLiftedFunction = lifted; + var returnVal; + if (x.nodeType) { + returnVal = x; + } else if (typeof(x.toDomNode) !== 'undefined') { + returnVal = x.toDomNode(cache); + } else if (typeof(x.toWrittenString) !== 'undefined') { - } - return primitiveF._mobyLiftedFunction; -}; + var node = document.createElement("span"); + node.appendChild(document.createTextNode(x.toWrittenString(cache))); + returnVal = node; + } else if (typeof(x.toDisplayedString) !== 'undefined') { + var node = document.createElement("span"); + node.appendChild(document.createTextNode(x.toDisplayedString(cache))); + returnVal = node; + } else { + var node = document.createElement("span"); + node.appendChild(document.createTextNode(x.toString())); + returnVal = node; + } + cache.remove(x); + return returnVal; + }; + + + // numberToDomNode: jsnum -> dom + // Given a jsnum, produces a dom-node representation. + var numberToDomNode = function(n) { + var node; + if (jsnums.isExact(n)) { + if (jsnums.isInteger(n)) { + node = document.createElement("span"); + node.appendChild(document.createTextNode(n.toString())); + return node; + } else if (jsnums.isRational(n)) { + return rationalToDomNode(n); + } else if (jsnums.isComplex(n)) { + node = document.createElement("span"); + node.appendChild(document.createTextNode(n.toString())); + return node; + } else { + node = document.createElement("span"); + node.appendChild(document.createTextNode(n.toString())); + return node; + } + } else { + node = document.createElement("span"); + node.appendChild(document.createTextNode(n.toString())); + return node; + } + }; + + // rationalToDomNode: rational -> dom-node + var rationalToDomNode = function(n) { + var node = document.createElement("span"); + var chunks = jsnums.toRepeatingDecimal(jsnums.numerator(n), + jsnums.denominator(n)); + node.appendChild(document.createTextNode(chunks[0] + '.')) + node.appendChild(document.createTextNode(chunks[1])); + var overlineSpan = document.createElement("span"); + overlineSpan.style.textDecoration = 'overline'; + overlineSpan.appendChild(document.createTextNode(chunks[2])); + node.appendChild(overlineSpan); + return node; + } -////////////////////////////////////////////////////////////////////// -var ThreadCell = function(v, isPreserved) { - this.v = v; - this.isPreserved = isPreserved || false; -}; + + var isNumber = jsnums.isSchemeNumber; + + var isReal = jsnums.isReal; + var isRational = jsnums.isRational; + var isComplex = isNumber; + var isInteger = jsnums.isInteger; + + var isNatural = function(x) { + return (jsnums.isExact(x) && isInteger(x) + && jsnums.greaterThanOrEqual(x, 0)); + }; + var isNonNegativeReal = function(x) { + return isReal(x) && jsnums.greaterThanOrEqual(x, 0); + }; -////////////////////////////////////////////////////////////////////// -// Wrapper around functions that return multiple values. -var ValuesWrapper = function(elts) { - this.elts = elts; -}; -ValuesWrapper.prototype.toDomNode = function(cache) { - var parent = document.createElement("span"); - parent.style["white-space"] = "pre"; - if ( this.elts.length > 0 ) { + var isString = function(s) { + return (typeof s === 'string' || s instanceof Str); + } + + + // isEqual: X Y -> boolean + // Returns true if the objects are equivalent; otherwise, returns false. + var isEqual = function(x, y, aUnionFind) { + if (x === y) { return true; } + + if (isNumber(x) && isNumber(y)) { + return jsnums.eqv(x, y); + } + + if (isString(x) && isString(y)) { + return x.toString() === y.toString(); + } + + if (x == undefined || x == null) { + return (y == undefined || y == null); + } + + if ( typeof(x) == 'object' && + typeof(y) == 'object' && + x.isEqual && + y.isEqual) { + + if (typeof (aUnionFind) === 'undefined') { + aUnionFind = new UnionFind(); + } + + if (aUnionFind.find(x) === aUnionFind.find(y)) { + return true; + } + else { + aUnionFind.merge(x, y); + return x.isEqual(y, aUnionFind); + } + } + return false; + }; + + + + + + // liftToplevelToFunctionValue: primitive-function string fixnum scheme-value -> scheme-value + // Lifts a primitive toplevel or module-bound value to a scheme value. + var liftToplevelToFunctionValue = function(primitiveF, + name, + minArity, + procedureArityDescription) { + if (! primitiveF._mobyLiftedFunction) { + var lifted = function(args) { + return primitiveF.apply(null, args.slice(0, minArity).concat([args.slice(minArity)])); + }; + lifted.isEqual = function(other, cache) { + return this === other; + } + lifted.toWrittenString = function(cache) { + return "#"; + }; + lifted.toDisplayedString = lifted.toWrittenString; + lifted.procedureArity = procedureArityDescription; + primitiveF._mobyLiftedFunction = lifted; + + } + return primitiveF._mobyLiftedFunction; + }; + + + + ////////////////////////////////////////////////////////////////////// + var ThreadCell = function(v, isPreserved) { + this.v = v; + this.isPreserved = isPreserved || false; + }; + + + + ////////////////////////////////////////////////////////////////////// + + + // Wrapper around functions that return multiple values. + var ValuesWrapper = function(elts) { + this.elts = elts; + }; + + ValuesWrapper.prototype.toDomNode = function(cache) { + var parent = document.createElement("span"); + parent.style["white-space"] = "pre"; + if ( this.elts.length > 0 ) { parent.appendChild( toDomNode(this.elts[0], cache) ); for (var i = 1; i < this.elts.length; i++) { - parent.appendChild( document.createTextNode('\n') ); - parent.appendChild( toDomNode(this.elts[i], cache) ); + parent.appendChild( document.createTextNode('\n') ); + parent.appendChild( toDomNode(this.elts[i], cache) ); } - } - return parent; -}; + } + return parent; + }; -ValuesWrapper.prototype.isEqual = function(other, aUnionFind) { - if (! other instanceof ValuesWrapper) { - return false; - } - if (this.elts.length !== other.elts.length) { - return false; - } - for (var i = 0; i < this.elts.length; i++) { - if (! isEqual(this.elts[i], other.elts[i], aUnionFind)) { + ValuesWrapper.prototype.isEqual = function(other, aUnionFind) { + if (! other instanceof ValuesWrapper) { return false; - } - } - return true; -}; + } + if (this.elts.length !== other.elts.length) { + return false; + } + for (var i = 0; i < this.elts.length; i++) { + if (! isEqual(this.elts[i], other.elts[i], aUnionFind)) { + return false; + } + } + return true; + }; -var UndefinedValue = function() { -}; -UndefinedValue.prototype.toString = function() { - return "#"; -}; -var UNDEFINED_VALUE = new UndefinedValue(); + var UndefinedValue = function() { + }; + UndefinedValue.prototype.toString = function() { + return "#"; + }; + var UNDEFINED_VALUE = new UndefinedValue(); -var VoidValue = function() {}; -VoidValue.prototype.toString = function() { + var VoidValue = function() {}; + VoidValue.prototype.toString = function() { return "#"; -}; + }; -var VOID_VALUE = new VoidValue(); + var VOID_VALUE = new VoidValue(); -var EofValue = function() {}; -EofValue.prototype.toString = function() { + var EofValue = function() {}; + EofValue.prototype.toString = function() { return "#"; -} - -var EOF_VALUE = new EofValue(); - - -var ClosureValue = function(name, numParams, paramTypes, isRest, closureVals, body) { - this.name = name; - this.numParams = numParams; - this.paramTypes = paramTypes; - this.isRest = isRest; - this.closureVals = closureVals; - this.body = body; -}; - - - - -ClosureValue.prototype.toString = function() { - if (this.name !== undefined && this.name !== Empty.EMPTY) { - return helpers.format("#", [this.name]); - } else { - return "#"; } -}; + + var EOF_VALUE = new EofValue(); -var CaseLambdaValue = function(name, closures) { - this.name = name; - this.closures = closures; -}; - -CaseLambdaValue.prototype.toString = function() { - if (this.name !== undefined && this.name !== Empty.EMPTY) { - return helpers.format("#", [this.name]); - } else { - return "#"; - } -}; - - - -var ContinuationClosureValue = function(vstack, cstack) { - this.name = types.EMPTY; - this.vstack = vstack.slice(0); - this.cstack = cstack.slice(0); -}; - -ContinuationClosureValue.prototype.toString = function() { - if (this.name !== Empty.EMPTY) { - return helpers.format("#", [this.name]); - } else { - return "#"; - } -}; - - - -////////////////////////////////////////////////////////////////////// - - - -var PrefixValue = function() { - this.slots = []; - this.definedMask = []; -}; - -PrefixValue.prototype.addSlot = function(v) { - if (v === undefined) { - this.slots.push(types.UNDEFINED); - this.definedMask.push(false); - } else { - this.slots.push(v); - if (v instanceof GlobalBucket) { - if (v.value === types.UNDEFINED) { - this.definedMask.push(false); - } else { - this.definedMask.push(true); - } - } else if (v instanceof NamedSlot) { - if (v.value === types.UNDEFINED) { - this.definedMask.push(false); - } else { - this.definedMask.push(true); - } - } else { - this.definedMask.push(true); - } - } -}; - -PrefixValue.prototype.ref = function(n) { - if (this.slots[n] instanceof GlobalBucket) { - if (this.definedMask[n]) { - return this.slots[n].value; - } else { - helpers.raise(types.incompleteExn( - types.exnFailContractVariable, - "reference to an identifier before its definition: " + this.slots[n].name, - [this.slots[n].name])); - } - } else if (this.slots[n] instanceof NamedSlot) { - if (this.definedMask[n]) { - return this.slots[n].value; - } else { - helpers.raise(types.incompleteExn( - types.exnFailContractVariable, - "reference to an identifier before its definition: " + this.slots[n].name, - [this.slots[n].name])); - } - } else { - if (this.definedMask[n]) { - return this.slots[n]; - } else { - helpers.raise(types.incompleteExn( - types.exnFailContractVariable, - "variable has not been defined", - [false])); - } - } -}; - -PrefixValue.prototype.lookup = function(name) { - for (var i = 0; i < this.slots.length; i++) { - if (this.slots[i] instanceof NamedSlot) { - if (this.slots[i].name === name) { - return this.slots[i].value; - } - } else if (this.slots[i] instanceof GlobalBucket) { - if (this.slots[i].name === name) { - return this.slots[i].value; - } - } + var ClosureValue = function(name, numParams, paramTypes, isRest, closureVals, body) { + this.name = name; + this.numParams = numParams; + this.paramTypes = paramTypes; + this.isRest = isRest; + this.closureVals = closureVals; + this.body = body; }; - return types.UNDEFINED; -}; -PrefixValue.prototype.set = function(n, v) { - if (this.slots[n] instanceof GlobalBucket) { - this.slots[n].value = v; - this.definedMask[n] = true; - } else if (this.slots[n] instanceof NamedSlot) { - this.slots[n].value = v; - this.definedMask[n] = true; - } else { - this.slots[n] = v; - this.definedMask[n] = true; + + + + ClosureValue.prototype.toString = function() { + if (this.name !== undefined && this.name !== Empty.EMPTY) { + return helpers.format("#", [this.name]); + } else { + return "#"; + } + }; + + + var CaseLambdaValue = function(name, closures) { + this.name = name; + this.closures = closures; + }; + + CaseLambdaValue.prototype.toString = function() { + if (this.name !== undefined && this.name !== Empty.EMPTY) { + return helpers.format("#", [this.name]); + } else { + return "#"; + } + }; + + + + var ContinuationClosureValue = function(vstack, cstack) { + this.name = types.EMPTY; + this.vstack = vstack.slice(0); + this.cstack = cstack.slice(0); + }; + + ContinuationClosureValue.prototype.toString = function() { + if (this.name !== Empty.EMPTY) { + return helpers.format("#", [this.name]); + } else { + return "#"; + } + }; + + + + ////////////////////////////////////////////////////////////////////// + + + + var PrefixValue = function() { + this.slots = []; + this.definedMask = []; + }; + + PrefixValue.prototype.addSlot = function(v) { + if (v === undefined) { + this.slots.push(types.UNDEFINED); + this.definedMask.push(false); + } else { + this.slots.push(v); + if (v instanceof GlobalBucket) { + if (v.value === types.UNDEFINED) { + this.definedMask.push(false); + } else { + this.definedMask.push(true); + } + } else if (v instanceof NamedSlot) { + if (v.value === types.UNDEFINED) { + this.definedMask.push(false); + } else { + this.definedMask.push(true); + } + } else { + this.definedMask.push(true); + } + } + }; + + PrefixValue.prototype.ref = function(n) { + if (this.slots[n] instanceof GlobalBucket) { + if (this.definedMask[n]) { + return this.slots[n].value; + } else { + helpers.raise(types.incompleteExn( + types.exnFailContractVariable, + "reference to an identifier before its definition: " + this.slots[n].name, + [this.slots[n].name])); + } + } else if (this.slots[n] instanceof NamedSlot) { + if (this.definedMask[n]) { + return this.slots[n].value; + } else { + helpers.raise(types.incompleteExn( + types.exnFailContractVariable, + "reference to an identifier before its definition: " + this.slots[n].name, + [this.slots[n].name])); + } + } else { + if (this.definedMask[n]) { + return this.slots[n]; + } else { + helpers.raise(types.incompleteExn( + types.exnFailContractVariable, + "variable has not been defined", + [false])); + } + } + }; + + PrefixValue.prototype.lookup = function(name) { + for (var i = 0; i < this.slots.length; i++) { + if (this.slots[i] instanceof NamedSlot) { + if (this.slots[i].name === name) { + return this.slots[i].value; + } + } else if (this.slots[i] instanceof GlobalBucket) { + if (this.slots[i].name === name) { + return this.slots[i].value; + } + } + }; + return types.UNDEFINED; + }; + + PrefixValue.prototype.set = function(n, v) { + if (this.slots[n] instanceof GlobalBucket) { + this.slots[n].value = v; + this.definedMask[n] = true; + } else if (this.slots[n] instanceof NamedSlot) { + this.slots[n].value = v; + this.definedMask[n] = true; + } else { + this.slots[n] = v; + this.definedMask[n] = true; + } + }; + + + PrefixValue.prototype.length = function() { + return this.slots.length; + }; + + + var GlobalBucket = function(name, value) { + this.name = name; + this.value = value; + }; + + var NamedSlot = function(name, value) { + this.name = name; + this.value = value; + }; + + var ModuleVariableRecord = function(resolvedModuleName, + variableName) { + this.resolvedModuleName = resolvedModuleName; + this.variableName = variableName; + }; + + + ////////////////////////////////////////////////////////////////////// + + + var Namespace = function() { + this.prefixes = []; + this.bindings = {}; + }; + + + Namespace.prototype.addPrefix = function(prefixValue) { + this.prefixes.push(prefixValue); + }; + + + Namespace.prototype.getVariableValue = function(name) { + // FIXME: fill me in. + // first, look in bindings. + // if not there, then look into each of the prefixes. + }; + + + Namespace.prototype.setVariableValue = function(name, value) { + // FIXME: fill me in. + this.bindings[name] = value; + }; + + + + + ////////////////////////////////////////////////////////////////////// + + + var VariableReference = function(prefix, pos) { + this.prefix = prefix; + this.pos = pos; + }; + + VariableReference.prototype.ref = function() { + return this.prefix.ref(this.pos); + }; + + VariableReference.prototype.set = function(v) { + this.prefix.set(this.pos, v); } -}; + ////////////////////////////////////////////////////////////////////// -PrefixValue.prototype.length = function() { - return this.slots.length; -}; + // Continuation Marks + var ContMarkRecordControl = function(dict) { + this.dict = dict || makeLowLevelEqHash(); + }; -var GlobalBucket = function(name, value) { - this.name = name; - this.value = value; -}; + ContMarkRecordControl.prototype.invoke = function(state) { + // No-op: the record will simply pop off the control stack. + }; -var NamedSlot = function(name, value) { - this.name = name; - this.value = value; -}; - -var ModuleVariableRecord = function(resolvedModuleName, - variableName) { - this.resolvedModuleName = resolvedModuleName; - this.variableName = variableName; -}; - - -////////////////////////////////////////////////////////////////////// - - -var Namespace = function() { - this.prefixes = []; - this.bindings = {}; -}; - - -Namespace.prototype.addPrefix = function(prefixValue) { - this.prefixes.push(prefixValue); -}; - - -Namespace.prototype.getVariableValue = function(name) { - // FIXME: fill me in. - // first, look in bindings. - // if not there, then look into each of the prefixes. -}; - - -Namespace.prototype.setVariableValue = function(name, value) { - // FIXME: fill me in. - this.bindings[name] = value; -}; - - - - -////////////////////////////////////////////////////////////////////// - - -var VariableReference = function(prefix, pos) { - this.prefix = prefix; - this.pos = pos; -}; - -VariableReference.prototype.ref = function() { - return this.prefix.ref(this.pos); -}; - -VariableReference.prototype.set = function(v) { - this.prefix.set(this.pos, v); -} - -////////////////////////////////////////////////////////////////////// - -// Continuation Marks - -var ContMarkRecordControl = function(dict) { - this.dict = dict || makeLowLevelEqHash(); -}; - -ContMarkRecordControl.prototype.invoke = function(state) { - // No-op: the record will simply pop off the control stack. -}; - -ContMarkRecordControl.prototype.update = function(key, val) { - var newDict = makeLowLevelEqHash(); - // FIXME: what's the javascript idiom for hash key copy? - // Maybe we should use a rbtree instead? - var oldKeys = this.dict.keys(); - for (var i = 0; i < oldKeys.length; i++) { + ContMarkRecordControl.prototype.update = function(key, val) { + var newDict = makeLowLevelEqHash(); + // FIXME: what's the javascript idiom for hash key copy? + // Maybe we should use a rbtree instead? + var oldKeys = this.dict.keys(); + for (var i = 0; i < oldKeys.length; i++) { newDict.put( oldKeys[i], this.dict.get(oldKeys[i]) ); - } - newDict.put(key, val); - return new ContMarkRecordControl(newDict); -}; - - - -var ContinuationMarkSet = function(dict) { - this.dict = dict; -} - -ContinuationMarkSet.prototype.toDomNode = function(cache) { - var dom = document.createElement("span"); - dom.appendChild(document.createTextNode('#')); - return dom; -}; - -ContinuationMarkSet.prototype.toWrittenString = function(cache) { - return '#'; -}; - -ContinuationMarkSet.prototype.toDisplayedString = function(cache) { - return '#'; -}; - -ContinuationMarkSet.prototype.ref = function(key) { - if ( this.dict.containsKey(key) ) { - return this.dict.get(key); - } - return []; -}; - - -////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////// - -var PrimProc = function(name, numParams, isRest, usesState, impl) { - this.name = name; - this.numParams = numParams; - this.isRest = isRest; - this.usesState = usesState; - this.impl = impl; -}; - -PrimProc.prototype.toString = function() { - return ("#"); -}; - -PrimProc.prototype.toWrittenString = function(cache) { - return ("#"); -}; - -PrimProc.prototype.toDisplayedString = function(cache) { - return ("#"); -}; - - -PrimProc.prototype.toDomNode = function(cache) { - var div = document.createElement("span"); - div.appendChild(document.createTextNode("#")); - return div; -}; - - -var CasePrimitive = function(name, cases) { - this.name = name; - this.cases = cases; -}; - - -CasePrimitive.prototype.toDomNode = function(cache) { - var div = document.createElement("span"); - div.appendChild(document.createTextNode("#")); - return div; -}; - -CasePrimitive.prototype.toWrittenString = function(cache) { - return ("#"); -}; - -CasePrimitive.prototype.toDisplayedString = function(cache) { - return ("#"); -}; -////////////////////////////////////////////////////////////////////// - -var makeOptionPrimitive = function(name, - numArgs, - defaultVals, - usesState, - bodyF) { - var makeNthPrimitive = function(n) { - return new PrimProc(name, - numArgs + n, - false, - usesState, - function() { - var expectedNumArgs = numArgs + n + (usesState ? 1 : 0); - assert.equal(arguments.length, - expectedNumArgs); - var args = [arguments]; - for (var i = 0; i < arguments.length; i++) { - args.push(arguments[i]); - } - var startDefaults = i - numArgs - (usesState ? 1 : 0); - return bodyF.apply( - bodyF, - args.concat(defaultVals.slice(startDefaults))); - }); + } + newDict.put(key, val); + return new ContMarkRecordControl(newDict); }; + + + + var ContinuationMarkSet = function(dict) { + this.dict = dict; + } + + ContinuationMarkSet.prototype.toDomNode = function(cache) { + var dom = document.createElement("span"); + dom.appendChild(document.createTextNode('#')); + return dom; + }; + + ContinuationMarkSet.prototype.toWrittenString = function(cache) { + return '#'; + }; + + ContinuationMarkSet.prototype.toDisplayedString = function(cache) { + return '#'; + }; + + ContinuationMarkSet.prototype.ref = function(key) { + if ( this.dict.containsKey(key) ) { + return this.dict.get(key); + } + return []; + }; + + + ////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + + var PrimProc = function(name, numParams, isRest, usesState, impl) { + this.name = name; + this.numParams = numParams; + this.isRest = isRest; + this.usesState = usesState; + this.impl = impl; + }; + + PrimProc.prototype.toString = function() { + return ("#"); + }; + + PrimProc.prototype.toWrittenString = function(cache) { + return ("#"); + }; + + PrimProc.prototype.toDisplayedString = function(cache) { + return ("#"); + }; + + + PrimProc.prototype.toDomNode = function(cache) { + var div = document.createElement("span"); + div.appendChild(document.createTextNode("#")); + return div; + }; + + + var CasePrimitive = function(name, cases) { + this.name = name; + this.cases = cases; + }; + + + CasePrimitive.prototype.toDomNode = function(cache) { + var div = document.createElement("span"); + div.appendChild(document.createTextNode("#")); + return div; + }; + + CasePrimitive.prototype.toWrittenString = function(cache) { + return ("#"); + }; + + CasePrimitive.prototype.toDisplayedString = function(cache) { + return ("#"); + }; + ////////////////////////////////////////////////////////////////////// + + var makeOptionPrimitive = function(name, + numArgs, + defaultVals, + usesState, + bodyF) { + var makeNthPrimitive = function(n) { + return new PrimProc(name, + numArgs + n, + false, + usesState, + function() { + var expectedNumArgs = numArgs + n + (usesState ? 1 : 0); + assert.equal(arguments.length, + expectedNumArgs); + var args = [arguments]; + for (var i = 0; i < arguments.length; i++) { + args.push(arguments[i]); + } + var startDefaults = i - numArgs - (usesState ? 1 : 0); + return bodyF.apply( + bodyF, + args.concat(defaultVals.slice(startDefaults))); + }); + }; - var cases = []; - for (var i = 0; i <= defaultVals.length; i++) { - cases.push(makeNthPrimitive(i)); - } - return new CasePrimitive(name, cases); -}; + var cases = []; + for (var i = 0; i <= defaultVals.length; i++) { + cases.push(makeNthPrimitive(i)); + } + return new CasePrimitive(name, cases); + }; @@ -2034,32 +2045,32 @@ var makeOptionPrimitive = function(name, -// 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 = helpers.heir(PrimProc.prototype); + // 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 = helpers.heir(PrimProc.prototype); -var StructConstructorProc = function() { - StructProc.apply(this, arguments); -}; -StructConstructorProc.prototype = helpers.heir(StructProc.prototype); + var StructConstructorProc = function() { + StructProc.apply(this, arguments); + }; + StructConstructorProc.prototype = helpers.heir(StructProc.prototype); -var StructPredicateProc = function() { - StructProc.apply(this, arguments); -}; -StructPredicateProc.prototype = helpers.heir(StructProc.prototype); + var StructPredicateProc = function() { + StructProc.apply(this, arguments); + }; + StructPredicateProc.prototype = helpers.heir(StructProc.prototype); -var StructAccessorProc = function() { - StructProc.apply(this, arguments); -}; -StructAccessorProc.prototype = helpers.heir(StructProc.prototype); + var StructAccessorProc = function() { + StructProc.apply(this, arguments); + }; + StructAccessorProc.prototype = helpers.heir(StructProc.prototype); -var StructMutatorProc = function() { - StructProc.apply(this, arguments); -}; -StructMutatorProc.prototype = helpers.heir(StructProc.prototype); + var StructMutatorProc = function() { + StructProc.apply(this, arguments); + }; + StructMutatorProc.prototype = helpers.heir(StructProc.prototype); @@ -2069,464 +2080,466 @@ StructMutatorProc.prototype = helpers.heir(StructProc.prototype); -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -// INTERNAL_CALL -// used for interaction between the Primitives and the interpreter (callPrimitiveProcedure). -// Don't confuse this with CallControl. -var INTERNAL_CALL = function(operator, operands, k) { - this.operator = operator; - this.operands = operands; - this.k = k; -}; + // INTERNAL_CALL + // used for interaction between the Primitives and the interpreter (callPrimitiveProcedure). + // Don't confuse this with CallControl. + var INTERNAL_CALL = function(operator, operands, k) { + this.operator = operator; + this.operands = operands; + this.k = k; + }; -// INTERNAL_PAUSE -// used for interaction between the Primitive functions and the -// interpreter. -// Halts the interpreter, but passing onPause the functions necessary -// to restart computation. -var INTERNAL_PAUSE = function(onPause) { - this.onPause = onPause; -}; + // INTERNAL_PAUSE + // used for interaction between the Primitive functions and the + // interpreter. + // Halts the interpreter, but passing onPause the functions necessary + // to restart computation. + var INTERNAL_PAUSE = function(onPause) { + this.onPause = onPause; + }; -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -// ContinuationPromptTag: symbol | false -> ContinuationPromptTag -var ContinuationPromptTag = function(sym) { - this.sym = sym; -}; + // ContinuationPromptTag: symbol | false -> ContinuationPromptTag + var ContinuationPromptTag = function(sym) { + this.sym = sym; + }; -var defaultContinuationPromptTag = new ContinuationPromptTag(); + var defaultContinuationPromptTag = new ContinuationPromptTag(); -var defaultContinuationPromptTagHandler = new PrimProc( - 'default-continuation-prompt-tag-handler', - 1, - false, - true, - function(aState, thunk) { - aState.pushControl( - new control.ApplicationControl( - new control.ConstantControl(thunk), - [])); - }); + var defaultContinuationPromptTagHandler = new PrimProc( + 'default-continuation-prompt-tag-handler', + 1, + false, + true, + function(aState, thunk) { + aState.pushControl( + new control.ApplicationControl( + new control.ConstantControl(thunk), + [])); + }); -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// -var makeList = function(args) { - var result = Empty.EMPTY; - for(var i = args.length-1; i >= 0; i--) { - result = Cons.makeInstance(args[i], result); - } - return result; -}; + var makeList = function(args) { + var result = Empty.EMPTY; + for(var i = args.length-1; i >= 0; i--) { + result = Cons.makeInstance(args[i], result); + } + return result; + }; -var makeVector = function(args) { - return Vector.makeInstance(args.length, args); -}; + var makeVector = function(args) { + return Vector.makeInstance(args.length, args); + }; -var makeVectorImmutable = function(args) { - var v = Vector.makeInstance(args.length, args); - v.mutable = false; - return v; -}; + var makeVectorImmutable = function(args) { + var v = Vector.makeInstance(args.length, args); + v.mutable = false; + return v; + }; -var makeString = function(s) { + var makeString = function(s) { if (s instanceof Str) { - return s; + return s; } else if (s instanceof Array) { -// for (var i = 0; i < s.length; i++) { -// if ( typeof s[i] !== 'string' || s[i].length != 1 ) { -// return undefined; -// } -// } - return Str.makeInstance(s); + // for (var i = 0; i < s.length; i++) { + // if ( typeof s[i] !== 'string' || s[i].length != 1 ) { + // return undefined; + // } + // } + return Str.makeInstance(s); } else if (typeof s === 'string') { - return Str.fromString(s); + return Str.fromString(s); } else { - throw types.internalError('makeString expects and array of 1-character strings or a string;' + - ' given ' + s.toString(), - false); + throw types.internalError('makeString expects and array of 1-character strings or a string;' + + ' given ' + s.toString(), + false); } -} + } -var makeHashEq = function(lst) { + var makeHashEq = function(lst) { var newHash = new EqHashTable(); while ( !lst.isEmpty() ) { - newHash.hash.put(lst.first().first(), lst.first().rest()); - lst = lst.rest(); + newHash.hash.put(lst.first().first(), lst.first().rest()); + lst = lst.rest(); } return newHash; -} + } -var makeHashEqual = function(lst) { + var makeHashEqual = function(lst) { var newHash = new EqualHashTable(); while ( !lst.isEmpty() ) { - newHash.hash.put(lst.first().first(), lst.first().rest()); - lst = lst.rest(); + newHash.hash.put(lst.first().first(), lst.first().rest()); + lst = lst.rest(); } return newHash; -} - - -var Color = makeStructureType('color', false, 3, 0, false, false); -var ArityAtLeast = makeStructureType('arity-at-least', false, 1, 0, false, - function(args, name, k) { - helpers.check(args[0], function(x) { return ( jsnums.isExact(x) && - jsnums.isInteger(x) && - jsnums.greaterThanOrEqual(x, 0) ); }, - name, 'exact non-negative integer', 1); - return k(args); - }); - - - - -////////////////////////////////////////////////////////////////////// - - - -var readerGraph = function(x, objectHash, n) { - if (typeof(x) === 'object' && objectHash.containsKey(x)) { - return objectHash.get(x); } - if (types.isPair(x)) { - var consPair = types.cons(x.first(), x.rest()); - objectHash.put(x, consPair); - consPair.f = readerGraph(x.first(), objectHash, n+1); - consPair.r = readerGraph(x.rest(), objectHash, n+1); - return consPair; - } - if (types.isVector(x)) { - var len = x.length(); - var aVector = types.vector(len, x.elts); - objectHash.put(x, aVector); - for (var i = 0; i < len; i++) { - aVector.elts[i] = readerGraph(aVector.elts[i], objectHash, n+1); - } - return aVector; - } - - if (types.isBox(x)) { - var aBox = types.box(x.unbox()); - objectHash.put(x, aBox); - aBox.val = readerGraph(x.unbox(), objectHash, n+1); - return aBox; - } - - if (types.isHash(x)) { - throw new Error("make-reader-graph of hash not implemented yet"); - } - - if (types.isStruct(x)) { - var aStruct = 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); - } - return aStruct; - } - - if (types.isPlaceholder(x)) { - return readerGraph(x.ref(), objectHash, n+1); - } - - return x; -}; - - - -// 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() {} - C.prototype = obj; - var c = new C(); - for (property in obj) { - if (obj.hasOwnProperty(property)) { - c[property] = obj[property]; - } - } - return c; -}; + var Color = makeStructureType('color', false, 3, 0, false, false); + var ArityAtLeast = makeStructureType('arity-at-least', false, 1, 0, false, + function(args, name, k) { + helpers.check(args[0], function(x) { return ( jsnums.isExact(x) && + jsnums.isInteger(x) && + jsnums.greaterThanOrEqual(x, 0) ); }, + name, 'exact non-negative integer', 1); + return k(args); + }); -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + + + var readerGraph = function(x, objectHash, n) { + if (typeof(x) === 'object' && objectHash.containsKey(x)) { + return objectHash.get(x); + } + + if (types.isPair(x)) { + var consPair = types.cons(x.first(), x.rest()); + objectHash.put(x, consPair); + consPair.f = readerGraph(x.first(), objectHash, n+1); + consPair.r = readerGraph(x.rest(), objectHash, n+1); + return consPair; + } + + if (types.isVector(x)) { + var len = x.length(); + var aVector = types.vector(len, x.elts); + objectHash.put(x, aVector); + for (var i = 0; i < len; i++) { + aVector.elts[i] = readerGraph(aVector.elts[i], objectHash, n+1); + } + return aVector; + } + + if (types.isBox(x)) { + var aBox = types.box(x.unbox()); + objectHash.put(x, aBox); + aBox.val = readerGraph(x.unbox(), objectHash, n+1); + return aBox; + } + + if (types.isHash(x)) { + throw new Error("make-reader-graph of hash not implemented yet"); + } + + if (types.isStruct(x)) { + var aStruct = 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); + } + return aStruct; + } + + if (types.isPlaceholder(x)) { + return readerGraph(x.ref(), objectHash, n+1); + } + + return x; + }; + + + + // 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() {} + C.prototype = obj; + var c = new C(); + for (property in obj) { + if (obj.hasOwnProperty(property)) { + c[property] = obj[property]; + } + } + return c; + }; + + + + + ////////////////////////////////////////////////////////////////////// -types.exceptionHandlerKey = new Symbol("exnh"); + types.exceptionHandlerKey = new Symbol("exnh"); -types.symbol = Symbol.makeInstance; -types.rational = jsnums.makeRational; -types.float = jsnums.makeFloat; -types.complex = jsnums.makeComplex; -types.bignum = jsnums.makeBignum; -types.list = makeList; -types.vector = makeVector; -types.vectorImmutable = makeVectorImmutable; -types.regexp = function(p) { return new RegularExpression(p) ; } -types.byteRegexp = function(p) { return new ByteRegularExpression(p) ; } -types['char'] = Char.makeInstance; -types['string'] = makeString; -types.box = function(x) { return new Box(x, true); }; -types.placeholder = function(x) { return new Placeholder(x); }; -types.boxImmutable = function(x) { return new Box(x, false); }; -types.path = function(x) { return new Path(x); }; -types.bytes = function(x, mutable) { return new Bytes(x, mutable); }; -types.bytesImmutable = function(x) { return new Bytes(x, false); }; -types.keyword = function(k) { return new Keyword(k); }; -types.pair = function(x, y) { return Cons.makeInstance(x, y); }; -types.hash = makeHashEqual; -types.hashEq = makeHashEq; -types.jsValue = function(name, val) { return new JsValue(name, val); }; -types.wrappedSchemeValue = function(val) { return new WrappedSchemeValue(val); }; + types.symbol = Symbol.makeInstance; + types.rational = jsnums.makeRational; + types.float = jsnums.makeFloat; + types.complex = jsnums.makeComplex; + types.bignum = jsnums.makeBignum; + types.list = makeList; + types.vector = makeVector; + types.vectorImmutable = makeVectorImmutable; + types.regexp = function(p) { return new RegularExpression(p) ; } + types.byteRegexp = function(p) { return new ByteRegularExpression(p) ; } + types['char'] = Char.makeInstance; + types['string'] = makeString; + types.box = function(x) { return new Box(x, true); }; + types.placeholder = function(x) { return new Placeholder(x); }; + types.boxImmutable = function(x) { return new Box(x, false); }; + types.path = function(x) { return new Path(x); }; + types.bytes = function(x, mutable) { return new Bytes(x, mutable); }; + types.bytesImmutable = function(x) { return new Bytes(x, false); }; + types.keyword = function(k) { return new Keyword(k); }; + types.pair = function(x, y) { return Cons.makeInstance(x, y); }; + types.hash = makeHashEqual; + types.hashEq = makeHashEq; + types.jsValue = function(name, val) { return new JsValue(name, val); }; + types.wrappedSchemeValue = function(val) { return new WrappedSchemeValue(val); }; -types.toWrittenString = toWrittenString; -types.toDisplayedString = toDisplayedString; -types.toDomNode = toDomNode; + types.toWrittenString = toWrittenString; + types.toDisplayedString = toDisplayedString; + types.toDomNode = toDomNode; -types.color = Color.constructor; -types.colorRed = function(x) { return Color.accessor(x, 0); }; -types.colorGreen = function(x) { return Color.accessor(x, 1); }; -types.colorBlue = function(x) { return Color.accessor(x, 2); }; + types.color = Color.constructor; + types.colorRed = function(x) { return Color.accessor(x, 0); }; + types.colorGreen = function(x) { return Color.accessor(x, 1); }; + types.colorBlue = function(x) { return Color.accessor(x, 2); }; -types.arityAtLeast = ArityAtLeast.constructor; -types.arityAtLeastValue = function(arity) { return ArityAtLeast.accessor(arity, 0); }; + types.arityAtLeast = ArityAtLeast.constructor; + types.arityAtLeastValue = function(arity) { return ArityAtLeast.accessor(arity, 0); }; -types.FALSE = Logic.FALSE; -types.TRUE = Logic.TRUE; -types.EMPTY = Empty.EMPTY; + types.FALSE = Logic.FALSE; + types.TRUE = Logic.TRUE; + types.EMPTY = Empty.EMPTY; -types.isEqual = isEqual; -types.isNumber = isNumber; + types.isEqual = isEqual; + types.isNumber = isNumber; -types.isReal = jsnums.isReal; -types.isBoolean = isBoolean; -types.isRational = jsnums.isRational; -types.isComplex = isNumber; -types.isInteger = jsnums.isInteger; -types.isNatural = isNatural; -types.isNonNegativeReal = isNonNegativeReal; + types.isReal = jsnums.isReal; + types.isBoolean = isBoolean; + types.isRational = jsnums.isRational; + types.isComplex = isNumber; + types.isInteger = jsnums.isInteger; + types.isNatural = isNatural; + types.isNonNegativeReal = isNonNegativeReal; -types.isSymbol = function(x) { return x instanceof Symbol; }; -types.isChar = function(x) { return x instanceof Char; }; -types.isString = isString; -types.isPair = function(x) { return x instanceof Cons; }; -types.isEmpty = function(x) { return x === Empty.EMPTY; }; -types.isVector = function(x) { return x instanceof Vector; }; -types.isBox = function(x) { return x instanceof Box; }; -types.isPlaceholder = function(x) { return x instanceof Placeholder; }; -types.isHash = function(x) { return (x instanceof EqHashTable || - x instanceof EqualHashTable); }; -types.isByteString = function(x) { return x instanceof Bytes; }; -types.isStruct = function(x) { return x instanceof Struct; }; -types.isArityAtLeast = ArityAtLeast.predicate; -types.isColor = Color.predicate; -types.isFunction = function(x) { + types.isSymbol = function(x) { return x instanceof Symbol; }; + types.isChar = function(x) { return x instanceof Char; }; + types.isString = isString; + types.isPair = function(x) { return x instanceof Cons; }; + types.isEmpty = function(x) { return x === Empty.EMPTY; }; + types.isVector = function(x) { return x instanceof Vector; }; + types.isBox = function(x) { return x instanceof Box; }; + types.isPlaceholder = function(x) { return x instanceof Placeholder; }; + types.isHash = function(x) { return (x instanceof EqHashTable || + x instanceof EqualHashTable); }; + types.isByteString = function(x) { return x instanceof Bytes; }; + types.isStruct = function(x) { return x instanceof Struct; }; + types.isArityAtLeast = ArityAtLeast.predicate; + types.isColor = Color.predicate; + types.isFunction = function(x) { return (x instanceof PrimProc || x instanceof CasePrimitive || x instanceof ClosureValue || x instanceof CaseLambdaValue || x instanceof ContinuationClosureValue); -}; -types.isJsValue = function(x) { return x instanceof JsValue; }; -types.isWrappedSchemeValue = function(x) { return x instanceof WrappedSchemeValue; }; + }; + types.isJsValue = function(x) { return x instanceof JsValue; }; + types.isWrappedSchemeValue = function(x) { return x instanceof WrappedSchemeValue; }; -types.UnionFind = UnionFind; -types.cons = Cons.makeInstance; + types.UnionFind = UnionFind; + types.cons = Cons.makeInstance; -types.UNDEFINED = UNDEFINED_VALUE; -types.VOID = VOID_VALUE; -types.EOF = EOF_VALUE; + types.UNDEFINED = UNDEFINED_VALUE; + types.VOID = VOID_VALUE; + types.EOF = EOF_VALUE; -types.ValuesWrapper = ValuesWrapper; -types.ClosureValue = ClosureValue; -types.ContinuationPromptTag = ContinuationPromptTag; -types.defaultContinuationPromptTag = defaultContinuationPromptTag; -types.defaultContinuationPromptTagHandler = defaultContinuationPromptTagHandler; -types.ContinuationClosureValue = ContinuationClosureValue; -types.CaseLambdaValue = CaseLambdaValue; -types.PrimProc = PrimProc; -types.CasePrimitive = CasePrimitive; -types.makeOptionPrimitive = makeOptionPrimitive; + types.ValuesWrapper = ValuesWrapper; + types.ClosureValue = ClosureValue; + types.ContinuationPromptTag = ContinuationPromptTag; + types.defaultContinuationPromptTag = defaultContinuationPromptTag; + types.defaultContinuationPromptTagHandler = defaultContinuationPromptTagHandler; + types.ContinuationClosureValue = ContinuationClosureValue; + types.CaseLambdaValue = CaseLambdaValue; + types.PrimProc = PrimProc; + types.CasePrimitive = CasePrimitive; + types.makeOptionPrimitive = makeOptionPrimitive; -types.internalCall = function(op, args, k) { return new INTERNAL_CALL(op, args, k); }; -types.isInternalCall = function(x) { return (x instanceof INTERNAL_CALL); }; -types.internalPause = function(onPause) { return new INTERNAL_PAUSE(onPause) }; -types.isInternalPause = function(x) { return (x instanceof INTERNAL_PAUSE); }; + types.internalCall = function(op, args, k) { return new INTERNAL_CALL(op, args, k); }; + types.isInternalCall = function(x) { return (x instanceof INTERNAL_CALL); }; + types.internalPause = function(onPause) { return new INTERNAL_PAUSE(onPause) }; + types.isInternalPause = function(x) { return (x instanceof INTERNAL_PAUSE); }; -types.contMarkRecordControl = function(dict) { return new ContMarkRecordControl(dict); }; -types.isContMarkRecordControl = function(x) { return x instanceof ContMarkRecordControl; }; -types.continuationMarkSet = function(dict) { return new ContinuationMarkSet(dict); }; -types.isContinuationMarkSet = function(x) { return x instanceof ContinuationMarkSet; }; -types.isContinuationPromptTag = function(x) { return x instanceof ContinuationPromptTag; }; + types.contMarkRecordControl = function(dict) { return new ContMarkRecordControl(dict); }; + types.isContMarkRecordControl = function(x) { return x instanceof ContMarkRecordControl; }; + types.continuationMarkSet = function(dict) { return new ContinuationMarkSet(dict); }; + types.isContinuationMarkSet = function(x) { return x instanceof ContinuationMarkSet; }; + types.isContinuationPromptTag = function(x) { return x instanceof ContinuationPromptTag; }; -types.PrefixValue = PrefixValue; -types.GlobalBucket = GlobalBucket; -types.NamedSlot = NamedSlot; -types.ModuleVariableRecord = ModuleVariableRecord; -types.VariableReference = VariableReference; + types.PrefixValue = PrefixValue; + types.GlobalBucket = GlobalBucket; + types.NamedSlot = NamedSlot; + types.ModuleVariableRecord = ModuleVariableRecord; + types.VariableReference = VariableReference; -types.Box = Box; -types.Placeholder = Placeholder; -types.ThreadCell = ThreadCell; + types.Box = Box; + types.Placeholder = Placeholder; + types.ThreadCell = ThreadCell; -types.makeStructureType = makeStructureType; -types.isStructType = function(x) { return x instanceof StructType; }; + types.makeStructureType = makeStructureType; + types.isStructType = function(x) { return x instanceof StructType; }; -types.StructProc = StructProc; -types.StructConstructorProc = StructConstructorProc; -types.StructPredicateProc = StructPredicateProc; -types.StructAccessorProc = StructAccessorProc; -types.StructMutatorProc = StructMutatorProc; + types.StructProc = StructProc; + types.StructConstructorProc = StructConstructorProc; + types.StructPredicateProc = StructPredicateProc; + types.StructAccessorProc = StructAccessorProc; + types.StructMutatorProc = StructMutatorProc; -types.makeLowLevelEqHash = makeLowLevelEqHash; + types.makeLowLevelEqHash = makeLowLevelEqHash; -// Error type exports -var InternalError = function(val, contMarks) { + // Error type exports + var InternalError = function(val, contMarks) { this.val = val; this.contMarks = (contMarks ? contMarks : false); -} -types.internalError = function(v, contMarks) { return new InternalError(v, contMarks); }; -types.isInternalError = function(x) { return x instanceof InternalError; }; + } + types.internalError = function(v, contMarks) { return new InternalError(v, contMarks); }; + types.isInternalError = function(x) { return x instanceof InternalError; }; -var SchemeError = function(val) { + var SchemeError = function(val) { this.val = val; -} -types.schemeError = function(v) { return new SchemeError(v); }; -types.isSchemeError = function(v) { return v instanceof SchemeError; }; + } + types.schemeError = function(v) { return new SchemeError(v); }; + types.isSchemeError = function(v) { return v instanceof SchemeError; }; -var IncompleteExn = function(constructor, msg, otherArgs) { + var IncompleteExn = function(constructor, msg, otherArgs) { this.constructor = constructor; this.msg = msg; this.otherArgs = otherArgs; -}; -types.incompleteExn = function(constructor, msg, args) { return new IncompleteExn(constructor, msg, args); }; -types.isIncompleteExn = function(x) { return x instanceof IncompleteExn; }; + }; + types.incompleteExn = function(constructor, msg, args) { return new IncompleteExn(constructor, msg, args); }; + types.isIncompleteExn = function(x) { return x instanceof IncompleteExn; }; -var Exn = makeStructureType('exn', false, 2, 0, false, - function(args, name, k) { - helpers.check(args[0], isString, name, 'string', 1); - helpers.check(args[1], types.isContinuationMarkSet, name, 'continuation mark set', 2); - return k(args); - }); -types.exn = Exn.constructor; -types.isExn = Exn.predicate; -types.exnMessage = function(exn) { return Exn.accessor(exn, 0); }; -types.exnContMarks = function(exn) { return Exn.accessor(exn, 1); }; -types.exnSetContMarks = function(exn, v) { Exn.mutator(exn, 1, v); }; + var Exn = makeStructureType('exn', false, 2, 0, false, + function(args, name, k) { + helpers.check(args[0], isString, name, 'string', 1); + helpers.check(args[1], types.isContinuationMarkSet, name, 'continuation mark set', 2); + return k(args); + }); + types.exn = Exn.constructor; + types.isExn = Exn.predicate; + types.exnMessage = function(exn) { return Exn.accessor(exn, 0); }; + types.exnContMarks = function(exn) { return Exn.accessor(exn, 1); }; + types.exnSetContMarks = function(exn, v) { Exn.mutator(exn, 1, v); }; -// (define-struct (exn:break exn) (continuation)) -var ExnBreak = makeStructureType('exn:break', Exn, 1, 0, false, - function(args, name, k) { - helpers.check(args[2], function(x) { return x instanceof ContinuationClosureValue; }, - name, 'continuation', 3); - return k(args); - }); -types.exnBreak = ExnBreak.constructor; -types.isExnBreak = ExnBreak.predicate; -types.exnBreakContinuation = function(exn) { return ExnBreak.accessor(exn, 0); }; + // (define-struct (exn:break exn) (continuation)) + var ExnBreak = makeStructureType('exn:break', Exn, 1, 0, false, + function(args, name, k) { + helpers.check(args[2], function(x) { return x instanceof ContinuationClosureValue; }, + name, 'continuation', 3); + return k(args); + }); + types.exnBreak = ExnBreak.constructor; + types.isExnBreak = ExnBreak.predicate; + types.exnBreakContinuation = function(exn) { return ExnBreak.accessor(exn, 0); }; -var ExnFail = makeStructureType('exn:fail', Exn, 0, 0, false, false); -types.exnFail = ExnFail.constructor; -types.isExnFail = ExnFail.predicate; + var ExnFail = makeStructureType('exn:fail', Exn, 0, 0, false, false); + types.exnFail = ExnFail.constructor; + types.isExnFail = ExnFail.predicate; -var ExnFailContract = makeStructureType('exn:fail:contract', ExnFail, 0, 0, false, false); -types.exnFailContract = ExnFailContract.constructor; -types.isExnFailContract = ExnFailContract.predicate; + var ExnFailContract = makeStructureType('exn:fail:contract', ExnFail, 0, 0, false, false); + types.exnFailContract = ExnFailContract.constructor; + types.isExnFailContract = ExnFailContract.predicate; -var ExnFailContractArity = makeStructureType('exn:fail:contract:arity', ExnFailContract, 0, 0, false, false); -types.exnFailContractArity = ExnFailContractArity.constructor; -types.isExnFailContractArity = ExnFailContractArity.predicate; + var ExnFailContractArity = makeStructureType('exn:fail:contract:arity', ExnFailContract, 0, 0, false, false); + types.exnFailContractArity = ExnFailContractArity.constructor; + types.isExnFailContractArity = ExnFailContractArity.predicate; -var ExnFailContractVariable = makeStructureType('exn:fail:contract:variable', ExnFailContract, 1, 0, false, false); -types.exnFailContractVariable = ExnFailContractVariable.constructor; -types.isExnFailContractVariable = ExnFailContractVariable.predicate; -types.exnFailContractVariableId = function(exn) { return ExnFailContractVariable.accessor(exn, 0); }; + var ExnFailContractVariable = makeStructureType('exn:fail:contract:variable', ExnFailContract, 1, 0, false, false); + types.exnFailContractVariable = ExnFailContractVariable.constructor; + types.isExnFailContractVariable = ExnFailContractVariable.predicate; + types.exnFailContractVariableId = function(exn) { return ExnFailContractVariable.accessor(exn, 0); }; -var ExnFailContractDivisionByZero = makeStructureType('exn:fail:contract:divide-by-zero', ExnFailContract, 0, 0, false, false); -types.exnFailContractDivisionByZero = ExnFailContractDivisionByZero.constructor; -types.isExnFailContractDivisionByZero = ExnFailContractDivisionByZero.predicate; + var ExnFailContractDivisionByZero = makeStructureType('exn:fail:contract:divide-by-zero', ExnFailContract, 0, 0, false, false); + types.exnFailContractDivisionByZero = ExnFailContractDivisionByZero.constructor; + types.isExnFailContractDivisionByZero = ExnFailContractDivisionByZero.predicate; -/////////////////////////////////////// -// World-specific exports + /////////////////////////////////////// + // World-specific exports -// big bang info to be passed into a make-world-config startup argument -var BigBangInfo = makeStructureType('bb-info', false, 2, 0, false, - function(args, name, k) { - helpers.check(args[0], helpers.procArityContains(1), name, 'procedure (arity 1)', 1); - helpers.check(args[1], types.isJsValue, name, 'js-object', 2); - return k(args); - }); -types.BigBangInfo = BigBangInfo; -types.makeBigBangInfo = BigBangInfo.constructor; -types.isBigBangInfo = BigBangInfo.predicate; -types.bbInfoChangeWorld = function(info) { return BigBangInfo.accessor(info, 0); }; -types.bbInfoToplevelNode = function(info) { return BigBangInfo.accessor(info, 1); }; + // big bang info to be passed into a make-world-config startup argument + var BigBangInfo = makeStructureType('bb-info', false, 2, 0, false, + function(args, name, k) { + helpers.check(args[0], helpers.procArityContains(1), name, 'procedure (arity 1)', 1); + helpers.check(args[1], types.isJsValue, name, 'js-object', 2); + return k(args); + }); + types.BigBangInfo = BigBangInfo; + types.makeBigBangInfo = BigBangInfo.constructor; + types.isBigBangInfo = BigBangInfo.predicate; + types.bbInfoChangeWorld = function(info) { return BigBangInfo.accessor(info, 0); }; + types.bbInfoToplevelNode = function(info) { return BigBangInfo.accessor(info, 1); }; -// World config information for user-defined configurations -types.worldConfig = function(startup, shutdown, pause, restart) { return new WorldConfig(startup, shutdown, pause, restart); }; -types.isWorldConfig = function(x) { return x instanceof WorldConfig; }; + // World config information for user-defined configurations + types.worldConfig = function(startup, shutdown, pause, restart) { return new WorldConfig(startup, shutdown, pause, restart); }; + types.isWorldConfig = function(x) { return x instanceof WorldConfig; }; -// exporting information to create effect types -types.makeEffectType = makeEffectType; -types.isEffectType = function(x) { + // exporting information to create effect types + types.makeEffectType = makeEffectType; + types.isEffectType = function(x) { return ((x instanceof StructType)&& x.type.prototype.invokeEffect) ? true : false; -}; + }; -types.isEffect = Effect.predicate; + types.isEffect = Effect.predicate; -// exporting functions to create render effect types -types.makeRenderEffectType = makeRenderEffectType; -types.isRenderEffectType = function(x) { + // exporting functions to create render effect types + types.makeRenderEffectType = makeRenderEffectType; + types.isRenderEffectType = function(x) { return (x instanceof StructType && x.type.prototype.callImplementation) ? true : false; -}; + }; -types.isRenderEffect = RenderEffect.predicate; + types.isRenderEffect = RenderEffect.predicate; -types.readerGraph = readerGraph; + types.readerGraph = readerGraph; -})(); + + scope.link.announceReady('types'); +})(this['plt']); diff --git a/tests/browser-evaluate.rkt b/tests/browser-evaluate.rkt index 185274d..398d6f3 100644 --- a/tests/browser-evaluate.rkt +++ b/tests/browser-evaluate.rkt @@ -213,9 +213,15 @@ var comet = function() { sendRequest("/eval", function(req) { // debug: - if (window.console && typeof(console.log) === 'function') { console.log(req.responseText); } - - var invoke = eval(req.responseText)(); + //if (window.console && typeof(console.log) === 'function') { + // console.log(req.responseText); + //} + try { + var invoke = eval(req.responseText)(); + } catch (e) { + if (window.console && window.console.log && e.stack) { window.console.log(e.stack); } + throw e; + } var output = []; var startTime, endTime; var params = { currentDisplayer: function(v) { From 58294db03dc5f1ff304856fdbcb184f0323b34bf Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Thu, 2 Jun 2011 16:23:17 -0400 Subject: [PATCH 3/7] integrating jsnums --- js-assembler/assemble-helpers.rkt | 14 ++- js-assembler/assemble-open-coded.rkt | 66 ++++++++++----- js-assembler/runtime-src/runtime.js | 122 ++++++++++++++------------- 3 files changed, 123 insertions(+), 79 deletions(-) diff --git a/js-assembler/assemble-helpers.rkt b/js-assembler/assemble-helpers.rkt index 513e63c..5bcf180 100644 --- a/js-assembler/assemble-helpers.rkt +++ b/js-assembler/assemble-helpers.rkt @@ -19,7 +19,8 @@ assemble-arity assemble-jump assemble-display-name - assemble-location) + assemble-location + assemble-numeric-constant) (require/typed typed/racket/base [regexp-split (Regexp String -> (Listof String))]) @@ -110,7 +111,7 @@ [(empty? val) (format "RUNTIME.NULL")] [(number? val) - (format "(~s)" val)] + (assemble-numeric-constant val)] [else (format "~s" val)]))) @@ -126,6 +127,15 @@ + +(: assemble-numeric-constant (Number -> String)) +(define (assemble-numeric-constant val) + (format "(~s)" val)) + + + + + (: assemble-lexical-reference (EnvLexicalReference -> String)) (define (assemble-lexical-reference a-lex-ref) (if (EnvLexicalReference-unbox? a-lex-ref) diff --git a/js-assembler/assemble-open-coded.rkt b/js-assembler/assemble-open-coded.rkt index 8c13742..93a204e 100644 --- a/js-assembler/assemble-open-coded.rkt +++ b/js-assembler/assemble-open-coded.rkt @@ -5,7 +5,8 @@ "../compiler/lexical-structs.rkt" "../compiler/kernel-primitives.rkt" racket/string - racket/list) + racket/list + typed/rackunit) (provide open-code-kernel-primitive-procedure) @@ -28,45 +29,48 @@ (case operator [(+) (cond [(empty? checked-operands) - "0"] + (assemble-numeric-constant 0)] [else - (string-append "(" (string-join checked-operands " + ") ")")])] + (assemble-binop-chain "jsnums.add" checked-operands)])] [(-) (cond [(empty? (rest checked-operands)) - (format "(-(~a))" (first checked-operands))] + (assemble-binop-chain "jsnums.subtract" (cons "0" checked-operands))] [else - (string-append "(" (string-join checked-operands "-") ")")])] + (assemble-binop-chain "jsnums.subtract" checked-operands)])] [(*) (cond [(empty? checked-operands) - "1"] + (assemble-numeric-constant 1)] [else - (string-append "(" (string-join checked-operands "*") ")")])] + (assemble-binop-chain "jsnums.multiply" checked-operands)])] [(/) - (string-append "(" (string-join checked-operands "/") ")")] + (assemble-binop-chain "jsnums.divide" checked-operands)] [(add1) - (format "(~a + 1)" (first checked-operands))] + (assemble-binop-chain "jsnums.add" (cons "1" checked-operands))] [(sub1) - (format "(~a - 1)" (first checked-operands))] - + (assemble-binop-chain "jsnums.subtract" (append checked-operands (list "1")))] + [(<) - (assemble-chain "<" checked-operands)] + (assemble-boolean-chain "jsnums.lessThan" checked-operands)] [(<=) - (assemble-chain "<=" checked-operands)] + (assemble-boolean-chain "jsnums.lessThanOrEqual" checked-operands)] [(=) - (assemble-chain "===" checked-operands)] + (assemble-boolean-chain "jsnums.equals" checked-operands)] [(>) - (assemble-chain ">" checked-operands)] + (assemble-boolean-chain "jsnums.greaterThan" checked-operands)] [(>=) - (assemble-chain ">=" checked-operands)] + (assemble-boolean-chain "jsnums.greaterThanOrEqual" checked-operands)] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + [(cons) (format "[~a, ~a]" (first checked-operands) (second checked-operands))] @@ -95,8 +99,32 @@ (format "(~a === ~a)" (first checked-operands) (second checked-operands))]))) -(: assemble-chain (String (Listof String) -> String)) -(define (assemble-chain rator rands) + +(: assemble-binop-chain (String (Listof String) -> String)) +(define (assemble-binop-chain rator rands) + (cond + [(empty? rands) + ""] + [(empty? (rest rands)) + (first rands)] + [else + (assemble-binop-chain + rator + (cons (string-append rator "(" (first rands) ", " (second rands) ")") + (rest (rest rands))))])) + +(check-equal? (assemble-binop-chain "jsnums.add" '("3" "4" "5")) + "jsnums.add(jsnums.add(3, 4), 5)") +(check-equal? (assemble-binop-chain "jsnums.subtract" '("0" "42")) + "jsnums.subtract(0, 42)") + + + + + + +(: assemble-boolean-chain (String (Listof String) -> String)) +(define (assemble-boolean-chain rator rands) (string-append "(" (string-join (let: loop : (Listof String) ([rands : (Listof String) rands]) (cond @@ -105,7 +133,7 @@ [(empty? (rest rands)) '()] [else - (cons (format "(~a ~a ~a)" (first rands) rator (second rands)) + (cons (format "(~a(~a,~a))" rator (first rands) (second rands)) (loop (rest rands)))])) "&&") ")")) diff --git a/js-assembler/runtime-src/runtime.js b/js-assembler/runtime-src/runtime.js index 3986e7f..c7f870e 100644 --- a/js-assembler/runtime-src/runtime.js +++ b/js-assembler/runtime-src/runtime.js @@ -23,12 +23,10 @@ if(this['plt'] === undefined) { this['plt'] = {}; } }; - var isNumber = function(x) { return typeof(x) === 'number'; }; - - var isNatural = function(x) { return typeof(x) === 'number' && - x >= 0 && - Math.floor(x) === x; }; + var isNumber = jsnums.isSchemeNumber; + var isNatural = function(x) { return (jsnums.isInteger(x) && + jsnums.greaterThanOrEqual(x, 0)); } var isPair = function(x) { return (typeof(x) == 'object' && x.length === 2 && @@ -605,9 +603,9 @@ if(this['plt'] === undefined) { this['plt'] = {}; } - Primitives['pi'] = Math.PI; + Primitives['pi'] = jsnums.pi; - Primitives['e'] = Math.E; + Primitives['e'] = jsnums.e; Primitives['='] = function(MACHINE) { var firstArg = MACHINE.env[MACHINE.env.length-1]; @@ -619,8 +617,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length - 1 - i], i, '='); - if (MACHINE.env[MACHINE.env.length - 1 - i] !== - MACHINE.env[MACHINE.env.length - 1 - i - 1]) { + if (! (jsnums.equals(MACHINE.env[MACHINE.env.length - 1 - i], + MACHINE.env[MACHINE.env.length - 1 - i - 1]))) { return false; } } @@ -641,8 +639,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length - 1 - i], i, '<'); - if (! (MACHINE.env[MACHINE.env.length - 1 - i] < - MACHINE.env[MACHINE.env.length - 1 - i - 1])) { + if (! (jsnums.lessThan(MACHINE.env[MACHINE.env.length - 1 - i], + MACHINE.env[MACHINE.env.length - 1 - i - 1]))) { return false; } } @@ -662,8 +660,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length - 1 - i], i, '>'); - if (! (MACHINE.env[MACHINE.env.length - 1 - i] > - MACHINE.env[MACHINE.env.length - 1 - i - 1])) { + if (! (jsnums.greaterThan(MACHINE.env[MACHINE.env.length - 1 - i], + MACHINE.env[MACHINE.env.length - 1 - i - 1]))) { return false; } } @@ -683,8 +681,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length - 1 - i], i, '<='); - if (! (MACHINE.env[MACHINE.env.length - 1 - i] <= - MACHINE.env[MACHINE.env.length - 1 - i - 1])) { + if (! (jsnums.lessThanOrEqual(MACHINE.env[MACHINE.env.length - 1 - i], + MACHINE.env[MACHINE.env.length - 1 - i - 1]))) { return false; } } @@ -705,8 +703,8 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length - 1 - i], i, '>='); - if (! (MACHINE.env[MACHINE.env.length - 1 - i] >= - MACHINE.env[MACHINE.env.length - 1 - i - 1])) { + if (! (jsnums.greaterThanOrEqual(MACHINE.env[MACHINE.env.length - 1 - i], + MACHINE.env[MACHINE.env.length - 1 - i - 1]))) { return false; } } @@ -726,7 +724,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length - 1 - i], i, '+'); - result += MACHINE.env[MACHINE.env.length - 1 - i]; + result = jsnums.add(result, MACHINE.env[MACHINE.env.length - 1 - i]); }; return result; }; @@ -744,7 +742,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length - 1 - i], i, '*'); - result *= MACHINE.env[MACHINE.env.length - 1 - i]; + result = jsnums.multiply(result, MACHINE.env[MACHINE.env.length - 1 - i]); } return result; }; @@ -759,7 +757,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length-1], 0, '-'); - return -(MACHINE.env[MACHINE.env.length-1]); + return jsnums.subtract(0, MACHINE.env[MACHINE.env.length-1]); } var result = MACHINE.env[MACHINE.env.length - 1]; for (var i = 1; i < MACHINE.argcount; i++) { @@ -769,7 +767,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length-1-i], i, '-'); - result -= MACHINE.env[MACHINE.env.length - 1 - i]; + result = jsnums.subtract(result, MACHINE.env[MACHINE.env.length - 1 - i]); } return result; }; @@ -791,7 +789,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length-1-i], i, '/'); - result /= MACHINE.env[MACHINE.env.length - 1 - i]; + result = jsnums.divide(result, MACHINE.env[MACHINE.env.length - 1 - i]); } return result; }; @@ -799,6 +797,47 @@ if(this['plt'] === undefined) { this['plt'] = {}; } Primitives['/'].displayName = '/'; + + Primitives['add1'] = function(MACHINE) { + testArgument(MACHINE, + 'number', + isNumber, + MACHINE.env[MACHINE.env.length - 1], + 0, + 'add1'); + var firstArg = MACHINE.env[MACHINE.env.length-1]; + return jsnums.add(firstArg, 1); + }; + Primitives['add1'].arity = 1; + Primitives['add1'].displayName = 'add1'; + + Primitives['sub1'] = function(MACHINE) { + testArgument(MACHINE, + 'number', + isNumber, + MACHINE.env[MACHINE.env.length - 1], + 0, + 'sub1'); + var firstArg = MACHINE.env[MACHINE.env.length-1]; + return jsnums.subtract(firstArg, 1); + }; + Primitives['sub1'].arity = 1; + Primitives['sub1'].displayName = 'sub1'; + + Primitives['zero?'] = function(MACHINE) { + var firstArg = MACHINE.env[MACHINE.env.length-1]; + return jsnums.equals(firstArg, 0); + }; + Primitives['zero?'].arity = 1; + Primitives['zero?'].displayName = 'zero?'; + + + + + + + + Primitives['cons'] = function(MACHINE) { var firstArg = MACHINE.env[MACHINE.env.length-1]; var secondArg = MACHINE.env[MACHINE.env.length-2]; @@ -896,39 +935,6 @@ if(this['plt'] === undefined) { this['plt'] = {}; } Primitives['null?'].arity = 1; Primitives['null?'].displayName = 'null?'; - Primitives['add1'] = function(MACHINE) { - testArgument(MACHINE, - 'number', - isNumber, - MACHINE.env[MACHINE.env.length - 1], - 0, - 'add1'); - var firstArg = MACHINE.env[MACHINE.env.length-1]; - return firstArg + 1; - }; - Primitives['add1'].arity = 1; - Primitives['add1'].displayName = 'add1'; - - Primitives['sub1'] = function(MACHINE) { - testArgument(MACHINE, - 'number', - isNumber, - MACHINE.env[MACHINE.env.length - 1], - 0, - 'sub1'); - var firstArg = MACHINE.env[MACHINE.env.length-1]; - return firstArg - 1; - }; - Primitives['sub1'].arity = 1; - Primitives['sub1'].displayName = 'sub1'; - - Primitives['zero?'] = function(MACHINE) { - var firstArg = MACHINE.env[MACHINE.env.length-1]; - return firstArg === 0; - }; - Primitives['zero?'].arity = 1; - Primitives['zero?'].displayName = 'zero?'; - Primitives['vector'] = function(MACHINE) { var i; var result = []; @@ -994,7 +1000,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } 0, 'vector-set!'); var firstArg = MACHINE.env[MACHINE.env.length-1]; - var secondArg = MACHINE.env[MACHINE.env.length-2]; + var secondArg = jsnums.toFixnum(MACHINE.env[MACHINE.env.length-2]); var thirdArg = MACHINE.env[MACHINE.env.length-3]; firstArg[secondArg] = thirdArg; return null; @@ -1010,7 +1016,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } MACHINE.env[MACHINE.env.length - 1], 0, 'vector-length'); - var firstArg = MACHINE.env[MACHINE.env.length-1]; + var firstArg = MACHINE.env[jsnums.toFixnum(MACHINE.env.length-1)]; return firstArg.length; }; Primitives['vector-length'].arity = 1; @@ -1028,7 +1034,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; } if (MACHINE.argcount == 2) { value = MACHINE.env[MACHINE.env.length - 2]; } - var length = MACHINE.env[MACHINE.env.length-1]; + var length = jsnums.toFixnum(MACHINE.env[MACHINE.env.length-1]); var arr = []; for(var i = 0; i < length; i++) { arr[i] = value; From bea918820e388c454df151efe7afdc933470a994 Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Thu, 2 Jun 2011 17:00:12 -0400 Subject: [PATCH 4/7] numeric constants are now using jsnums --- js-assembler/assemble-helpers.rkt | 86 ++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/js-assembler/assemble-helpers.rkt b/js-assembler/assemble-helpers.rkt index 5bcf180..444078a 100644 --- a/js-assembler/assemble-helpers.rkt +++ b/js-assembler/assemble-helpers.rkt @@ -126,11 +126,93 @@ +;; Slightly ridiculous definition, but I need it to get around what appear to +;; be Typed Racket bugs in its numeric tower. +(define-predicate int? Integer) + (: assemble-numeric-constant (Number -> String)) -(define (assemble-numeric-constant val) - (format "(~s)" val)) +(define (assemble-numeric-constant a-num) + + (: floating-number->js (Real -> String)) + (define (floating-number->js a-num) + (cond + [(eqv? a-num -0.0) + "jsnums.negative_zero"] + [(eqv? a-num +inf.0) + "jsnums.inf"] + [(eqv? a-num -inf.0) + "jsnums.negative_inf"] + [(eqv? a-num +nan.0) + "jsnums.nan"] + [else + (string-append "jsnums.makeFloat(" (number->string a-num) ")")])) + + ;; FIXME: fix the type signature when typed-racket isn't breaking on + ;; (define-predicate ExactRational? (U Exact-Rational)) + (: rational-number->js (Real -> String)) + (define (rational-number->js a-num) + (cond [(= (denominator a-num) 1) + (string-append (integer->js (ensure-integer (numerator a-num))))] + [else + (string-append "jsnums.makeRational(" + (integer->js (ensure-integer (numerator a-num))) + ", " + (integer->js (ensure-integer (denominator a-num))) + ")")])) + + + (: ensure-integer (Any -> Integer)) + (define (ensure-integer x) + (if (int? x) + x + (error "not an integer: ~e" x))) + + + + (: integer->js (Integer -> String)) + (define (integer->js an-int) + (cond + ;; non-overflow case + [(< (abs an-int) 9e15) + (number->string an-int)] + ;; overflow case + [else + (string-append "jsnums.makeBignum(" + (format "~s" (number->string an-int)) + ")")])) + + (cond + [(and (exact? a-num) (rational? a-num)) + (rational-number->js a-num)] + + [(real? a-num) + (floating-number->js a-num)] + + [(complex? a-num) + (string-append "jsnums.makeComplex(" + (assemble-numeric-constant (real-part a-num)) + ", " + (assemble-numeric-constant (imag-part a-num)) + ")")])) + + + + + + + + + + + + + + + + + From c3d89605ffb66b90aed321b9d10a4a5b3551b1ac Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Fri, 3 Jun 2011 11:32:06 -0400 Subject: [PATCH 5/7] moving toWrittenString, toDisplayedString, and toDomNode up to helpers --- NOTES | 13 +- js-assembler/runtime-src/helpers.js | 200 ++++++++++++++++++++++- js-assembler/runtime-src/primitives.js | 78 ++++----- js-assembler/runtime-src/types.js | 213 ++----------------------- 4 files changed, 261 insertions(+), 243 deletions(-) diff --git a/NOTES b/NOTES index 8fb78d9..95acdba 100644 --- a/NOTES +++ b/NOTES @@ -668,4 +668,15 @@ helpers. That dependency needs to be cut! I've added a workaround for now, using the link library to delay initialization until the modules are present, but this is an unsatisfactory solution. We really shouldn't get into this problem in the first place... I must -do a lot of code cleanup once things stabilize... \ No newline at end of file +do a lot of code cleanup once things stabilize... + + +---------------------------------------------------------------------- + +June 3, 2011 + +How do I test what I'm integrating? I should at least absorb the +js-vm test suite, at the very least. + +11am: I'm going to spend the next hour trying to disentangle the +circularity between helpers and types. \ No newline at end of file diff --git a/js-assembler/runtime-src/helpers.js b/js-assembler/runtime-src/helpers.js index 3415e46..130b493 100644 --- a/js-assembler/runtime-src/helpers.js +++ b/js-assembler/runtime-src/helpers.js @@ -35,9 +35,9 @@ if (! this['plt']) { this['plt'] = {}; } var expectedNumberOfArgs = matches == null ? 0 : matches.length; var errorStrBuffer = [functionName + ': format string requires ' + expectedNumberOfArgs + ' arguments, given ' + args.length + '; arguments were:', - types.toWrittenString(formatStr)]; + toWrittenString(formatStr)]; for (var i = 0; i < args.length; i++) { - errorStrBuffer.push( types.toWrittenString(args[i]) ); + errorStrBuffer.push( toWrittenString(args[i]) ); } raise( types.incompleteExn(types.exnFailContract, errorStrBuffer.join(' '), []) ); @@ -54,19 +54,19 @@ if (! this['plt']) { this['plt'] = {}; } if (buffer.length == 0) { throwFormatError(); } - return types.toWrittenString(buffer.shift()); + return toWrittenString(buffer.shift()); } else if (s == '~e' || s == "~E") { // FIXME: we don't yet have support for the error-print // handler, and currently treat ~e just like ~s. if (buffer.length == 0) { throwFormatError(); } - return types.toWrittenString(buffer.shift()); + return toWrittenString(buffer.shift()); } else if (s == '~a' || s == "~A") { if (buffer.length == 0) { throwFormatError(); } - return types.toDisplayedString(buffer.shift()); + return toDisplayedString(buffer.shift()); } else { throw types.internalError('format: string.replace matched invalid regexp', false); } @@ -184,7 +184,7 @@ if (! this['plt']) { this['plt'] = {}; } var errorFormatStrBuffer = ['~a: expects type <~a> as ~a arguments, given: ~s; other arguments were:']; for (var i = 0; i < args.length; i++) { if ( i != pos-1 ) { - errorFormatStrBuffer.push( types.toWrittenString(args[i]) ); + errorFormatStrBuffer.push(toWrittenString(args[i])); } } errorFormatStr = errorFormatStrBuffer.join(' '); @@ -564,6 +564,188 @@ if (! this['plt']) { this['plt'] = {}; } + + // toWrittenString: Any Hashtable -> String + var toWrittenString = function(x, cache) { + if (! cache) { + cache = makeLowLevelEqHash(); + } + + if (typeof(x) === 'object') { + if (cache.containsKey(x)) { + return "..."; + } + } + + if (x == undefined || x == null) { + return "#"; + } + if (typeof(x) == 'string') { + return escapeString(x.toString()); + } + if (typeof(x) != 'object' && typeof(x) != 'function') { + return x.toString(); + } + + var returnVal; + if (typeof(x.toWrittenString) !== 'undefined') { + returnVal = x.toWrittenString(cache); + } else if (typeof(x.toDisplayedString) !== 'undefined') { + returnVal = x.toDisplayedString(cache); + } else { + returnVal = x.toString(); + } + cache.remove(x); + return returnVal; + }; + + + + // toDisplayedString: Any Hashtable -> String + var toDisplayedString = function(x, cache) { + if (! cache) { + cache = makeLowLevelEqHash(); + } + if (typeof(x) === 'object') { + if (cache.containsKey(x)) { + return "..."; + } + } + + if (x == undefined || x == null) { + return "#"; + } + if (typeof(x) == 'string') { + return x; + } + if (typeof(x) != 'object' && typeof(x) != 'function') { + return x.toString(); + } + + var returnVal; + if (typeof(x.toDisplayedString) !== 'undefined') { + returnVal = x.toDisplayedString(cache); + } else if (typeof(x.toWrittenString) !== 'undefined') { + returnVal = x.toWrittenString(cache); + } else { + returnVal = x.toString(); + } + cache.remove(x); + return returnVal; + }; + + + // toDomNode: scheme-value -> dom-node + var toDomNode = function(x, cache) { + if (! cache) { + cache = makeLowLevelEqHash(); + } + + if (jsnums.isSchemeNumber(x)) { + return numberToDomNode(x); + } + + if (typeof(x) == 'object') { + if (cache.containsKey(x)) { + var node = document.createElement("span"); + node.appendChild(document.createTextNode("...")); + return node; + } + } + + if (x == undefined || x == null) { + var node = document.createElement("span"); + node.appendChild(document.createTextNode("#")); + return node; + } + + if (typeof(x) == 'string') { + var wrapper = document.createElement("span"); + wrapper.style["white-space"] = "pre"; + var node = document.createTextNode(toWrittenString(x)); + wrapper.appendChild(node); + return wrapper; + } + if (typeof(x) != 'object' && typeof(x) != 'function') { + var node = document.createElement("span"); + node.appendChild(document.createTextNode(x.toString())); + return node; + } + + var returnVal; + if (x.nodeType) { + returnVal = x; + } else if (typeof(x.toDomNode) !== 'undefined') { + returnVal = x.toDomNode(cache); + } else if (typeof(x.toWrittenString) !== 'undefined') { + + var node = document.createElement("span"); + node.appendChild(document.createTextNode(x.toWrittenString(cache))); + returnVal = node; + } else if (typeof(x.toDisplayedString) !== 'undefined') { + var node = document.createElement("span"); + node.appendChild(document.createTextNode(x.toDisplayedString(cache))); + returnVal = node; + } else { + var node = document.createElement("span"); + node.appendChild(document.createTextNode(x.toString())); + returnVal = node; + } + cache.remove(x); + return returnVal; + }; + + + + // numberToDomNode: jsnum -> dom + // Given a jsnum, produces a dom-node representation. + var numberToDomNode = function(n) { + var node; + if (jsnums.isExact(n)) { + if (jsnums.isInteger(n)) { + node = document.createElement("span"); + node.appendChild(document.createTextNode(n.toString())); + return node; + } else if (jsnums.isRational(n)) { + return rationalToDomNode(n); + } else if (jsnums.isComplex(n)) { + node = document.createElement("span"); + node.appendChild(document.createTextNode(n.toString())); + return node; + } else { + node = document.createElement("span"); + node.appendChild(document.createTextNode(n.toString())); + return node; + } + } else { + node = document.createElement("span"); + node.appendChild(document.createTextNode(n.toString())); + return node; + } + }; + + // rationalToDomNode: rational -> dom-node + var rationalToDomNode = function(n) { + var node = document.createElement("span"); + var chunks = jsnums.toRepeatingDecimal(jsnums.numerator(n), + jsnums.denominator(n)); + node.appendChild(document.createTextNode(chunks[0] + '.')) + node.appendChild(document.createTextNode(chunks[1])); + var overlineSpan = document.createElement("span"); + overlineSpan.style.textDecoration = 'overline'; + overlineSpan.appendChild(document.createTextNode(chunks[2])); + node.appendChild(overlineSpan); + return node; + } + + + + + + + + + //////////////////////////////////////////////// helpers.format = format; @@ -605,6 +787,12 @@ if (! this['plt']) { this['plt'] = {}; } + helpers.toWrittenString = toWrittenString; + helpers.toDisplayedString = toDisplayedString; + helpers.toDomNode = toDomNode; + + + scope.link.announceReady('helpers'); })(this['plt']); diff --git a/js-assembler/runtime-src/primitives.js b/js-assembler/runtime-src/primitives.js index 19f3abf..2bd09f5 100644 --- a/js-assembler/runtime-src/primitives.js +++ b/js-assembler/runtime-src/primitives.js @@ -620,7 +620,7 @@ That way, we can do a simple grep. false, true, function(state, x) { - state.getPrintHook()(types.toWrittenString(x)); + state.getPrintHook()(helpers.toDisplayedString(x)); state.v = types.VOID; }); @@ -1230,7 +1230,7 @@ That way, we can do a simple grep. else { var msgBuffer = [arg1.toString()]; for (var i = 0; i < args.length; i++) { - msgBuffer.push( types.toWrittenString(args[i]) ); + msgBuffer.push( helpers.toDisplayedString(args[i]) ); } raise( types.incompleteExn(types.exnFail, msgBuffer.join(''), []) ); } @@ -1952,7 +1952,7 @@ That way, we can do a simple grep. return jsnums.toExact(x); } catch(e) { raise( types.exnFailContract('inexact->exact: no exact representation for ' - + types.toWrittenString(x), + + helpers.toDisplayedString(x), false) ); } }); @@ -2525,7 +2525,7 @@ That way, we can do a simple grep. if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('list-ref: index ' + n + ' is too large for list (not a proper list): ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2533,7 +2533,7 @@ That way, we can do a simple grep. if (lst.isEmpty()) { var msg = ('list-ref: index ' + n + ' is too large for list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } lst = lst.rest(); @@ -2543,7 +2543,7 @@ That way, we can do a simple grep. if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('list-ref: index ' + n + ' is too large for list (not a proper list): ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2567,7 +2567,7 @@ That way, we can do a simple grep. if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('list-tail: index ' + n + ' is too large for list (not a proper list): ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2575,7 +2575,7 @@ That way, we can do a simple grep. if (lst.isEmpty()) { var msg = ('list-tail: index ' + n + ' is too large for list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } lst = lst.rest(); @@ -2727,7 +2727,7 @@ That way, we can do a simple grep. var lst = origList; if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('memq: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2740,7 +2740,7 @@ That way, we can do a simple grep. lst = lst.rest(); if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('memq: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2758,7 +2758,7 @@ That way, we can do a simple grep. var lst = origList; if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('memv: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2770,7 +2770,7 @@ That way, we can do a simple grep. lst = lst.rest(); if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('memv: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2789,7 +2789,7 @@ That way, we can do a simple grep. //checkList(lst, 'member', 2, arguments); if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('member: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2802,7 +2802,7 @@ That way, we can do a simple grep. if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('member: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2846,7 +2846,7 @@ That way, we can do a simple grep. // checkListOf(lst, isPair, 'assq', 'pair', 2, arguments); if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('assq: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2854,8 +2854,8 @@ That way, we can do a simple grep. while ( !lst.isEmpty() ) { if (! isPair(lst.first())) { var msg = ('assq: non-pair found in list: ' + - types.toWrittenString(lst.first()) +' in ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(lst.first()) +' in ' + + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2867,7 +2867,7 @@ That way, we can do a simple grep. if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('assq: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2886,7 +2886,7 @@ That way, we can do a simple grep. var lst = origList; if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('assv: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2894,8 +2894,8 @@ That way, we can do a simple grep. while ( !lst.isEmpty() ) { if (! isPair(lst.first())) { var msg = ('assv: non-pair found in list: ' + - types.toWrittenString(lst.first()) +' in ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(lst.first()) +' in ' + + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2906,7 +2906,7 @@ That way, we can do a simple grep. lst = lst.rest(); if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('assv: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2925,7 +2925,7 @@ That way, we can do a simple grep. //checkListOf(lst, isPair, 'assoc', 'pair', 2, arguments); if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('assoc: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2933,8 +2933,8 @@ That way, we can do a simple grep. while ( !lst.isEmpty() ) { if (! isPair(lst.first())) { var msg = ('assoc: non-pair found in list: ' + - types.toWrittenString(lst.first()) +' in ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(lst.first()) +' in ' + + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -2946,7 +2946,7 @@ That way, we can do a simple grep. if (! isPair(lst) && lst !== types.EMPTY) { var msg = ('assoc: not a proper list: ' + - types.toWrittenString(origList)); + helpers.toDisplayedString(origList)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); @@ -3208,7 +3208,7 @@ That way, we can do a simple grep. check(obj, isHash, 'hash-ref', 'hash', 1, arguments); if ( !obj.hash.containsKey(key) ) { - var msg = 'hash-ref: no value found for key: ' + types.toWrittenString(key); + var msg = 'hash-ref: no value found for key: ' + helpers.toDisplayedString(key); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } return obj.hash.get(key); @@ -3373,7 +3373,7 @@ That way, we can do a simple grep. if (n >= str.length) { var msg = ('string-ref: index ' + n + ' out of range ' + '[0, ' + (str.length-1) + '] for string: ' + - types.toWrittenString(str)); + helpers.toDisplayedString(str)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } return types.char(str.charAt(n)); @@ -3542,7 +3542,7 @@ That way, we can do a simple grep. var start = jsnums.toFixnum(theStart); if (start > str.length) { var msg = ('substring: starting index ' + start + ' out of range ' + - '[0, ' + str.length + '] for string: ' + types.toWrittenString(str)); + '[0, ' + str.length + '] for string: ' + helpers.toDisplayedString(str)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } else { @@ -3561,12 +3561,12 @@ That way, we can do a simple grep. var end = jsnums.toFixnum(theEnd); if (start > str.length) { var msg = ('substring: starting index ' + start + ' out of range ' + - '[0, ' + str.length + '] for string: ' + types.toWrittenString(str)); + '[0, ' + str.length + '] for string: ' + helpers.toDisplayedString(str)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } if (end < start || end > str.length) { var msg = ('substring: ending index ' + end + ' out of range ' + '[' + start + - ', ' + str.length + '] for string: ' + types.toWrittenString(str)); + ', ' + str.length + '] for string: ' + helpers.toDisplayedString(str)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } return types.string( str.substring(start, end) ); @@ -3851,7 +3851,7 @@ That way, we can do a simple grep. if ( jsnums.greaterThanOrEqual(k, str.length) ) { var msg = ('string-set!: index ' + k + ' out of range ' + '[0, ' + (str.length-1) + '] for string: ' + - types.toWrittenString(str)); + helpers.toDisplayedString(str)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } str.set(jsnums.toFixnum(k), c.val); @@ -3997,7 +3997,7 @@ That way, we can do a simple grep. if ( n >= bstr.length() ) { var msg = ('bytes-ref: index ' + n + ' out of range ' + '[0, ' + (bstr.length-1) + '] for byte-string: ' + - types.toWrittenString(bstr)); + helpers.toDisplayedString(bstr)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } return bstr.get(n); @@ -4018,7 +4018,7 @@ That way, we can do a simple grep. if ( n >= bstr.length() ) { var msg = ('bytes-set!: index ' + n + ' out of range ' + '[0, ' + (bstr.length-1) + '] for byte-string: ' + - types.toWrittenString(bstr)); + helpers.toDisplayedString(bstr)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } bstr.set(n, b); @@ -4039,7 +4039,7 @@ That way, we can do a simple grep. if (start > bstr.length()) { var msg = ('subbytes: starting index ' + start + ' out of range ' + '[0, ' + bstr.length + '] for byte-string: ' + - types.toWrittenString(bstr)); + helpers.toDisplayedString(bstr)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } else { @@ -4059,13 +4059,13 @@ That way, we can do a simple grep. if (start > bstr.length()) { var msg = ('subbytes: starting index ' + start + ' out of range ' + '[0, ' + bstr.length() + '] for byte-string: ' + - types.toWrittenString(bstr)); + helpers.toDisplayedString(bstr)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } if (end < start || end > bstr.length()) { var msg = ('subbytes: ending index ' + end + ' out of range ' + '[' + start + ', ' + bstr.length() + '] for byte-string: ' + - types.toWrittenString(bstr)); + helpers.toDisplayedString(bstr)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } else { @@ -4244,7 +4244,7 @@ That way, we can do a simple grep. if (i >= vec.length()) { var msg = ('vector-ref: index ' + i + ' out of range ' + '[0, ' + (vec.length()-1) + '] for vector: ' + - types.toWrittenString(vec)); + helpers.toDisplayedString(vec)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } return vec.ref(i); @@ -4263,7 +4263,7 @@ That way, we can do a simple grep. if (i >= vec.length()) { var msg = ('vector-set!: index ' + i + ' out of range ' + '[0, ' + (vec.length()-1) + '] for vector: ' + - types.toWrittenString(vec)); + helpers.toDisplayedString(vec)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } vec.set(i, val); diff --git a/js-assembler/runtime-src/types.js b/js-assembler/runtime-src/types.js index 0299261..1cc9b44 100644 --- a/js-assembler/runtime-src/types.js +++ b/js-assembler/runtime-src/types.js @@ -14,15 +14,23 @@ if (! this['plt']) { this['plt'] = {}; } var helpers = scope['helpers']; - var getEqHashCode, makeLowLevelEqHash; - // makeLowLevelEqHash: -> hashtable - // Constructs an eq hashtable that uses Moby's getEqHashCode function. - var makeLowLevelEqHash; + var getEqHashCode = helpers.getEqHashCode, + // makeLowLevelEqHash: -> hashtable + // Constructs an eq hashtable that uses Moby's getEqHashCode function. + + makeLowLevelEqHash = helpers.makeLowLevelEqHash; + + var toWrittenString = helpers.toWrittenString; + var toDisplayedString = helpers.toDisplayedString; + var toDomNode = helpers.toDomNode; scope.link.ready('helpers', function() { helpers = scope['helpers']; getEqHashCode = helpers.getEqHashCode; makeLowLevelEqHash = helpers.makeLowLevelEqHash; + toWrittenString = helpers.toWrittenString; + toDisplayedString = helpers.toDisplayedString; + toDomNode = helpers.toDomNode; }); @@ -761,17 +769,6 @@ if (! this['plt']) { this['plt'] = {}; } texts.push('.'); texts.push(toWrittenString(p, cache)); } - // while (true) { - // if ((!(p instanceof Cons)) && (!(p instanceof Empty))) { - // texts.push("."); - // texts.push(toWrittenString(p, cache)); - // break; - // } - // if (p.isEmpty()) - // break; - // texts.push(toWrittenString(p.first(), cache)); - // p = p.rest(); - // } return "(" + texts.join(" ") + ")"; }; @@ -1121,8 +1118,8 @@ String.prototype.toDisplayedString = function(cache) { var keys = this.hash.keys(); var ret = []; for (var i = 0; i < keys.length; i++) { - var keyStr = types.toDisplayedString(keys[i], cache); - var valStr = types.toDisplayedString(this.hash.get(keys[i]), cache); + var keyStr = toDisplayedString(keys[i], cache); + var valStr = toDisplayedString(this.hash.get(keys[i]), cache); ret.push('(' + keyStr + ' . ' + valStr + ')'); } return ('#hasheq(' + ret.join(' ') + ')'); @@ -1177,8 +1174,8 @@ String.prototype.toDisplayedString = function(cache) { var keys = this.hash.keys(); var ret = []; for (var i = 0; i < keys.length; i++) { - var keyStr = types.toDisplayedString(keys[i], cache); - var valStr = types.toDisplayedString(this.hash.get(keys[i]), cache); + var keyStr = toDisplayedString(keys[i], cache); + var valStr = toDisplayedString(this.hash.get(keys[i]), cache); ret.push('(' + keyStr + ' . ' + valStr + ')'); } return ('#hash(' + ret.join(' ') + ')'); @@ -1353,180 +1350,6 @@ String.prototype.toDisplayedString = function(cache) { - - - var toWrittenString = function(x, cache) { - if (! cache) { - cache = makeLowLevelEqHash(); - } - - if (typeof(x) === 'object') { - if (cache.containsKey(x)) { - return "..."; - } - } - - if (x == undefined || x == null) { - return "#"; - } - if (typeof(x) == 'string') { - return escapeString(x.toString()); - } - if (typeof(x) != 'object' && typeof(x) != 'function') { - return x.toString(); - } - - var returnVal; - if (typeof(x.toWrittenString) !== 'undefined') { - returnVal = x.toWrittenString(cache); - } else if (typeof(x.toDisplayedString) !== 'undefined') { - returnVal = x.toDisplayedString(cache); - } else { - returnVal = x.toString(); - } - cache.remove(x); - return returnVal; - }; - - - - var toDisplayedString = function(x, cache) { - if (! cache) { - cache = makeLowLevelEqHash(); - } - if (typeof(x) === 'object') { - if (cache.containsKey(x)) { - return "..."; - } - } - - if (x == undefined || x == null) { - return "#"; - } - if (typeof(x) == 'string') { - return x; - } - if (typeof(x) != 'object' && typeof(x) != 'function') { - return x.toString(); - } - - var returnVal; - if (typeof(x.toDisplayedString) !== 'undefined') { - returnVal = x.toDisplayedString(cache); - } else if (typeof(x.toWrittenString) !== 'undefined') { - returnVal = x.toWrittenString(cache); - } else { - returnVal = x.toString(); - } - cache.remove(x); - return returnVal; - }; - - - - // toDomNode: scheme-value -> dom-node - var toDomNode = function(x, cache) { - if (! cache) { - cache = makeLowLevelEqHash(); - } - if (isNumber(x)) { - return numberToDomNode(x); - } - - if (typeof(x) == 'object') { - if (cache.containsKey(x)) { - var node = document.createElement("span"); - node.appendChild(document.createTextNode("...")); - return node; - } - } - - if (x == undefined || x == null) { - var node = document.createElement("span"); - node.appendChild(document.createTextNode("#")); - return node; - } - if (typeof(x) == 'string') { - var wrapper = document.createElement("span"); - wrapper.style["white-space"] = "pre"; - var node = document.createTextNode(toWrittenString(x)); - wrapper.appendChild(node); - return wrapper; - } - if (typeof(x) != 'object' && typeof(x) != 'function') { - var node = document.createElement("span"); - node.appendChild(document.createTextNode(x.toString())); - return node; - } - - var returnVal; - if (x.nodeType) { - returnVal = x; - } else if (typeof(x.toDomNode) !== 'undefined') { - returnVal = x.toDomNode(cache); - } else if (typeof(x.toWrittenString) !== 'undefined') { - - var node = document.createElement("span"); - node.appendChild(document.createTextNode(x.toWrittenString(cache))); - returnVal = node; - } else if (typeof(x.toDisplayedString) !== 'undefined') { - var node = document.createElement("span"); - node.appendChild(document.createTextNode(x.toDisplayedString(cache))); - returnVal = node; - } else { - var node = document.createElement("span"); - node.appendChild(document.createTextNode(x.toString())); - returnVal = node; - } - cache.remove(x); - return returnVal; - }; - - - // numberToDomNode: jsnum -> dom - // Given a jsnum, produces a dom-node representation. - var numberToDomNode = function(n) { - var node; - if (jsnums.isExact(n)) { - if (jsnums.isInteger(n)) { - node = document.createElement("span"); - node.appendChild(document.createTextNode(n.toString())); - return node; - } else if (jsnums.isRational(n)) { - return rationalToDomNode(n); - } else if (jsnums.isComplex(n)) { - node = document.createElement("span"); - node.appendChild(document.createTextNode(n.toString())); - return node; - } else { - node = document.createElement("span"); - node.appendChild(document.createTextNode(n.toString())); - return node; - } - } else { - node = document.createElement("span"); - node.appendChild(document.createTextNode(n.toString())); - return node; - } - }; - - // rationalToDomNode: rational -> dom-node - var rationalToDomNode = function(n) { - var node = document.createElement("span"); - var chunks = jsnums.toRepeatingDecimal(jsnums.numerator(n), - jsnums.denominator(n)); - node.appendChild(document.createTextNode(chunks[0] + '.')) - node.appendChild(document.createTextNode(chunks[1])); - var overlineSpan = document.createElement("span"); - overlineSpan.style.textDecoration = 'overline'; - overlineSpan.appendChild(document.createTextNode(chunks[2])); - node.appendChild(overlineSpan); - return node; - } - - - - var isNumber = jsnums.isSchemeNumber; var isReal = jsnums.isReal; @@ -2317,10 +2140,6 @@ String.prototype.toDisplayedString = function(cache) { types.jsValue = function(name, val) { return new JsValue(name, val); }; types.wrappedSchemeValue = function(val) { return new WrappedSchemeValue(val); }; - types.toWrittenString = toWrittenString; - types.toDisplayedString = toDisplayedString; - types.toDomNode = toDomNode; - types.color = Color.constructor; types.colorRed = function(x) { return Color.accessor(x, 0); }; From 84f643cb3ddbfdd3b38fe7b13b4ceffe5b1a3f74 Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Fri, 3 Jun 2011 16:45:43 -0400 Subject: [PATCH 6/7] trying to use the closure compiler to reduce the size of the runtime --- NOTES | 6 +++++- js-assembler/get-runtime.rkt | 8 +++++--- js-assembler/runtime-src/primitives.js | 14 +++++++------- js-assembler/runtime-src/types.js | 4 ++-- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/NOTES b/NOTES index 95acdba..b78af7f 100644 --- a/NOTES +++ b/NOTES @@ -679,4 +679,8 @@ How do I test what I'm integrating? I should at least absorb the js-vm test suite, at the very least. 11am: I'm going to spend the next hour trying to disentangle the -circularity between helpers and types. \ No newline at end of file +circularity between helpers and types. + + +The parameters I'm using to control bounce are too high for Firefox, +leading it to raise the dialog about an out of control jva process. Not good. \ No newline at end of file diff --git a/js-assembler/get-runtime.rkt b/js-assembler/get-runtime.rkt index 9af9c3b..d3562a1 100644 --- a/js-assembler/get-runtime.rkt +++ b/js-assembler/get-runtime.rkt @@ -21,7 +21,8 @@ (require racket/contract racket/runtime-path - racket/port) + racket/port + (planet dyoo/closure-compile:1:1)) (provide/contract [get-runtime (-> string?)]) @@ -56,8 +57,9 @@ (port->string ip)))) -(define text (apply string-append - (map path->string files))) +(define text (closure-compile + (apply string-append + (map path->string files)))) (define (get-runtime) diff --git a/js-assembler/runtime-src/primitives.js b/js-assembler/runtime-src/primitives.js index 2bd09f5..208b799 100644 --- a/js-assembler/runtime-src/primitives.js +++ b/js-assembler/runtime-src/primitives.js @@ -1173,7 +1173,7 @@ That way, we can do a simple grep. PRIMITIVES['random'] = new CasePrimitive('random', [new PrimProc('random', 0, false, false, - function() {return types.float(Math.random());}), + function() {return types.floatpoint(Math.random());}), new PrimProc('random', 1, false, false, function(n) { check(n, isNatural, 'random', 'non-negative exact integer', 1, arguments); @@ -3315,7 +3315,7 @@ That way, we can do a simple grep. 1, false, false, function(n) { - return makeStringImpl(n, types.char(String.fromCharCode(0))); + return makeStringImpl(n, types.character(String.fromCharCode(0))); })]); @@ -3376,7 +3376,7 @@ That way, we can do a simple grep. helpers.toDisplayedString(str)); raise( types.incompleteExn(types.exnFailContract, msg, []) ); } - return types.char(str.charAt(n)); + return types.character(str.charAt(n)); }); @@ -3599,7 +3599,7 @@ That way, we can do a simple grep. str = str.toString(); var lst = types.EMPTY; for (var i = str.length-1; i >= 0; i--) { - lst = types.cons(types.char(str.charAt(i)), lst); + lst = types.cons(types.character(str.charAt(i)), lst); } return lst; }); @@ -4542,7 +4542,7 @@ That way, we can do a simple grep. 'exact integer in [0,#x10FFFF], not in [#xD800,#xDFFF]', 1); - return types.char( String.fromCharCode(jsnums.toFixnum(num)) ); + return types.character( String.fromCharCode(jsnums.toFixnum(num)) ); }); @@ -4552,7 +4552,7 @@ That way, we can do a simple grep. false, false, function(c) { check(c, isChar, 'char-upcase', 'char', 1); - return types.char( c.val.toUpperCase() ); + return types.character( c.val.toUpperCase() ); }); @@ -4562,7 +4562,7 @@ That way, we can do a simple grep. false, false, function(c) { check(c, isChar, 'char-downcase', 'char', 1); - return types.char( c.val.toLowerCase() ); + return types.character( c.val.toLowerCase() ); }); diff --git a/js-assembler/runtime-src/types.js b/js-assembler/runtime-src/types.js index 1cc9b44..ff70603 100644 --- a/js-assembler/runtime-src/types.js +++ b/js-assembler/runtime-src/types.js @@ -2117,7 +2117,7 @@ String.prototype.toDisplayedString = function(cache) { types.symbol = Symbol.makeInstance; types.rational = jsnums.makeRational; - types.float = jsnums.makeFloat; + types.floatpoint = jsnums.makeFloat; types.complex = jsnums.makeComplex; types.bignum = jsnums.makeBignum; types.list = makeList; @@ -2125,7 +2125,7 @@ String.prototype.toDisplayedString = function(cache) { types.vectorImmutable = makeVectorImmutable; types.regexp = function(p) { return new RegularExpression(p) ; } types.byteRegexp = function(p) { return new ByteRegularExpression(p) ; } - types['char'] = Char.makeInstance; + types.character = Char.makeInstance; types['string'] = makeString; types.box = function(x) { return new Box(x, true); }; types.placeholder = function(x) { return new Placeholder(x); }; From c92f018aa8a927dfb0d0ebfd2b99a0a46e098dbe Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Fri, 3 Jun 2011 17:10:24 -0400 Subject: [PATCH 7/7] compressing the output of the compiler with google-closure. Fixing the typechecks on numbers --- js-assembler/assemble-open-coded.rkt | 2 +- js-assembler/get-runtime.rkt | 9 ++++----- js-assembler/package.rkt | 27 ++++++++++++++++++--------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/js-assembler/assemble-open-coded.rkt b/js-assembler/assemble-open-coded.rkt index 93a204e..f7aeae1 100644 --- a/js-assembler/assemble-open-coded.rkt +++ b/js-assembler/assemble-open-coded.rkt @@ -151,7 +151,7 @@ (let: ([test-string : String (case domain [(number) - (format "(typeof(~a) === 'number')" + (format "(jsnums.isSchemeNumber(~a))" operand-string)] [(string) (format "(typeof(~a) === 'string')" diff --git a/js-assembler/get-runtime.rkt b/js-assembler/get-runtime.rkt index d3562a1..6bf2ab7 100644 --- a/js-assembler/get-runtime.rkt +++ b/js-assembler/get-runtime.rkt @@ -21,8 +21,8 @@ (require racket/contract racket/runtime-path - racket/port - (planet dyoo/closure-compile:1:1)) + racket/port) + (provide/contract [get-runtime (-> string?)]) @@ -57,9 +57,8 @@ (port->string ip)))) -(define text (closure-compile - (apply string-append - (map path->string files)))) +(define text (apply string-append + (map path->string files))) (define (get-runtime) diff --git a/js-assembler/package.rkt b/js-assembler/package.rkt index 5b2d1ef..98ee9b3 100644 --- a/js-assembler/package.rkt +++ b/js-assembler/package.rkt @@ -4,6 +4,7 @@ "quote-cdata.rkt" "../make.rkt" "../make-structs.rkt" + (planet dyoo/closure-compile:1:1) (prefix-in runtime: "get-runtime.rkt") (prefix-in racket: racket/base)) @@ -87,13 +88,6 @@ -;; get-runtime: -> string -(define (get-runtime) - (let ([buffer (open-output-string)]) - (write-runtime buffer) - (get-output-string buffer))) - - ;; write-runtime: output-port -> void (define (write-runtime op) (let ([packaging-configuration @@ -121,6 +115,19 @@ +(define *the-runtime* + (let ([buffer (open-output-string)]) + (write-runtime buffer) + (closure-compile + (get-output-string buffer)))) + + +;; get-runtime: -> string +(define (get-runtime) + *the-runtime*) + + + ;; *header* : string @@ -144,7 +151,8 @@ EOF (package source-code #:should-follow? (lambda (src p) #t) #:output-port buffer) - (get-output-string buffer))) + (closure-compile + (get-output-string buffer)))) @@ -152,7 +160,8 @@ EOF (define (get-standalone-code source-code) (let ([buffer (open-output-string)]) (write-standalone-code source-code buffer) - (get-output-string buffer))) + (closure-compile + (get-output-string buffer)))) ;; write-standalone-code: source output-port -> void