diff --git a/NOTES b/NOTES index 517ca3c..b78af7f 100644 --- a/NOTES +++ b/NOTES @@ -595,4 +595,92 @@ 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? + + +---------------------------------------------------------------------- + +I've at least imported the libraries from Moby so that they're loaded +in the same runtime. However, there are some ugly things happening +here: for some reason, there's a circular dependency between types and +helpers. That dependency needs to be cut! I've added a workaround +for now, using the link library to delay initialization until the +modules are present, but this is an unsatisfactory solution. We +really shouldn't get into this problem in the first place... I must +do a lot of code cleanup once things stabilize... + + +---------------------------------------------------------------------- + +June 3, 2011 + +How do I test what I'm integrating? I should at least absorb the +js-vm test suite, at the very least. + +11am: I'm going to spend the next hour trying to disentangle the +circularity between helpers and types. + + +The parameters I'm using to control bounce are too high for Firefox, +leading it to raise the dialog about an out of control jva process. Not good. \ No newline at end of file diff --git a/js-assembler/assemble-helpers.rkt b/js-assembler/assemble-helpers.rkt index 513e63c..444078a 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)]))) @@ -124,6 +125,97 @@ (format "[~a, ~a]" (first vals) (loop (rest vals)))]))) + +;; Slightly ridiculous definition, but I need it to get around what appear to +;; be Typed Racket bugs in its numeric tower. +(define-predicate int? Integer) + + + +(: assemble-numeric-constant (Number -> String)) +(define (assemble-numeric-constant a-num) + + (: floating-number->js (Real -> String)) + (define (floating-number->js a-num) + (cond + [(eqv? a-num -0.0) + "jsnums.negative_zero"] + [(eqv? a-num +inf.0) + "jsnums.inf"] + [(eqv? a-num -inf.0) + "jsnums.negative_inf"] + [(eqv? a-num +nan.0) + "jsnums.nan"] + [else + (string-append "jsnums.makeFloat(" (number->string a-num) ")")])) + + ;; FIXME: fix the type signature when typed-racket isn't breaking on + ;; (define-predicate ExactRational? (U Exact-Rational)) + (: rational-number->js (Real -> String)) + (define (rational-number->js a-num) + (cond [(= (denominator a-num) 1) + (string-append (integer->js (ensure-integer (numerator a-num))))] + [else + (string-append "jsnums.makeRational(" + (integer->js (ensure-integer (numerator a-num))) + ", " + (integer->js (ensure-integer (denominator a-num))) + ")")])) + + + (: ensure-integer (Any -> Integer)) + (define (ensure-integer x) + (if (int? x) + x + (error "not an integer: ~e" x))) + + + + (: integer->js (Integer -> String)) + (define (integer->js an-int) + (cond + ;; non-overflow case + [(< (abs an-int) 9e15) + (number->string an-int)] + ;; overflow case + [else + (string-append "jsnums.makeBignum(" + (format "~s" (number->string an-int)) + ")")])) + + (cond + [(and (exact? a-num) (rational? a-num)) + (rational-number->js a-num)] + + [(real? a-num) + (floating-number->js a-num)] + + [(complex? a-num) + (string-append "jsnums.makeComplex(" + (assemble-numeric-constant (real-part a-num)) + ", " + (assemble-numeric-constant (imag-part a-num)) + ")")])) + + + + + + + + + + + + + + + + + + + + (: assemble-lexical-reference (EnvLexicalReference -> String)) diff --git a/js-assembler/assemble-open-coded.rkt b/js-assembler/assemble-open-coded.rkt index 8c13742..f7aeae1 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)))])) "&&") ")")) @@ -123,7 +151,7 @@ (let: ([test-string : String (case domain [(number) - (format "(typeof(~a) === 'number')" + (format "(jsnums.isSchemeNumber(~a))" operand-string)] [(string) (format "(typeof(~a) === 'string')" diff --git a/js-assembler/get-runtime.rkt b/js-assembler/get-runtime.rkt index c1a0fe5..6bf2ab7 100644 --- a/js-assembler/get-runtime.rkt +++ b/js-assembler/get-runtime.rkt @@ -1,16 +1,54 @@ #lang racket/base ;; Function to get the runtime library. +;; +;; The resulting Javascript will produce a file that loads: +;; +;; +;; jquery at the the toplevel +;; HashTable at the toplevel +;; jsnums at the toplevel +;; +;; followed by: +;; +;; plt.link +;; plt.helpers +;; plt.types +;; plt.primitives +;; plt.runtime + + (require racket/contract racket/runtime-path racket/port) + (provide/contract [get-runtime (-> string?)]) (define-runtime-path jquery.js "runtime-src/jquery-1.6.1.min.js") -(define-runtime-path runtime.js "mini-runtime.js") +(define-runtime-path hashtable.js "runtime-src/jshashtable-2.1_src.js") +(define-runtime-path jsnums.js "runtime-src/js-numbers.js") +(define-runtime-path link.js "runtime-src/link.js") +(define-runtime-path helpers.js "runtime-src/helpers.js") +(define-runtime-path types.js "runtime-src/types.js") +(define-runtime-path primitives.js "runtime-src/primitives.js") +(define-runtime-path runtime.js "runtime-src/runtime.js") + + +;; The order matters here. link needs to come near the top, because +;; the other modules below have some circular dependencies that are resolved +;; by link. +(define files (list jquery.js + hashtable.js + jsnums.js + link.js + helpers.js + types.js + primitives.js + runtime.js)) + (define (path->string p) @@ -19,11 +57,8 @@ (port->string ip)))) -(define text (string-append - (path->string jquery.js) - (path->string runtime.js))) - - +(define text (apply string-append + (map path->string files))) (define (get-runtime) 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 diff --git a/js-assembler/runtime-src/helpers.js b/js-assembler/runtime-src/helpers.js index c793347..130b493 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:', + toWrittenString(formatStr)]; + for (var i = 0; i < args.length; i++) { + errorStrBuffer.push( 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 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 toWrittenString(buffer.shift()); + } else if (s == '~a' || s == "~A") { + if (buffer.length == 0) { + throwFormatError(); } - return result; - }; + return 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(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,236 @@ var helpers = {}; - //////////////////////////////////////////////// + + // toWrittenString: Any Hashtable -> String + var toWrittenString = function(x, cache) { + if (! cache) { + cache = makeLowLevelEqHash(); + } - helpers.format = format; - helpers.forEachK = forEachK; - helpers.reportError = reportError; - helpers.raise = raise; + if (typeof(x) === 'object') { + if (cache.containsKey(x)) { + return "..."; + } + } - 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; + if (x == undefined || x == null) { + return "#"; + } + if (typeof(x) == 'string') { + return escapeString(x.toString()); + } + if (typeof(x) != 'object' && typeof(x) != 'function') { + return x.toString(); + } - helpers.ordinalize = ordinalize; - helpers.wrapJsValue = wrapJsValue; - - helpers.getKeyCodeName = getKeyCodeName; - - helpers.maybeCallAfterAttach = maybeCallAfterAttach; - - helpers.makeLocationDom = makeLocationDom; - helpers.isLocationDom = isLocationDom; + 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; + }; - helpers.getEqHashCode = getEqHashCode; - helpers.makeLowLevelEqHash = makeLowLevelEqHash; - helpers.heir = heir; + // 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; + 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.ordinalize = ordinalize; + helpers.wrapJsValue = wrapJsValue; + + helpers.getKeyCodeName = getKeyCodeName; + + helpers.maybeCallAfterAttach = maybeCallAfterAttach; + + helpers.makeLocationDom = makeLocationDom; + helpers.isLocationDom = isLocationDom; + + + helpers.getEqHashCode = getEqHashCode; + helpers.makeLowLevelEqHash = makeLowLevelEqHash; + + helpers.heir = heir; + + + + + helpers.toWrittenString = toWrittenString; + helpers.toDisplayedString = toDisplayedString; + helpers.toDomNode = toDomNode; + + + + 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..208b799 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()(helpers.toDisplayedString(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.floatpoint(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( helpers.toDisplayedString(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 ' + + helpers.toDisplayedString(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): ' + + helpers.toDisplayedString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + if (lst.isEmpty()) { + var msg = ('list-ref: index ' + n + + ' is too large for list: ' + + helpers.toDisplayedString(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): ' + + helpers.toDisplayedString(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): ' + + helpers.toDisplayedString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + if (lst.isEmpty()) { + var msg = ('list-tail: index ' + n + + ' is too large for list: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + - types.toWrittenString(origList)); + var msg = ('memv: not a proper list: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + while ( !lst.isEmpty() ) { + if (! isPair(lst.first())) { + var msg = ('assq: non-pair found in list: ' + + helpers.toDisplayedString(lst.first()) +' in ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + while ( !lst.isEmpty() ) { + if (! isPair(lst.first())) { + var msg = ('assv: non-pair found in list: ' + + helpers.toDisplayedString(lst.first()) +' in ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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(); + helpers.toDisplayedString(origList)); + raise( types.incompleteExn(types.exnFailContract, + msg, + []) ); + } + while ( !lst.isEmpty() ) { + if (! isPair(lst.first())) { + var msg = ('assoc: non-pair found in list: ' + + helpers.toDisplayedString(lst.first()) +' in ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + helpers.toDisplayedString(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', @@ -3293,570 +3315,570 @@ PRIMITIVES['make-string'] = 1, false, false, function(n) { - return makeStringImpl(n, types.char(String.fromCharCode(0))); + return makeStringImpl(n, types.character(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: ' + + helpers.toDisplayedString(str)); + raise( types.incompleteExn(types.exnFailContract, msg, []) ); + } + return types.character(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: ' + helpers.toDisplayedString(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: ' + 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: ' + helpers.toDisplayedString(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.character(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: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + + 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: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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: ' + + helpers.toDisplayedString(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.character( 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.character( 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.character( 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 95% rename from js-assembler/mini-runtime.js rename to js-assembler/runtime-src/runtime.js index cdf9d6d..c7f870e 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; @@ -26,12 +23,10 @@ }; - var isNumber = function(x) { return typeof(x) === 'number'; }; - - var isNatural = function(x) { return typeof(x) === 'number' && - x >= 0 && - Math.floor(x) === x; }; + var isNumber = jsnums.isSchemeNumber; + var isNatural = function(x) { return (jsnums.isInteger(x) && + jsnums.greaterThanOrEqual(x, 0)); } var isPair = function(x) { return (typeof(x) == 'object' && x.length === 2 && @@ -608,9 +603,9 @@ - Primitives['pi'] = Math.PI; + Primitives['pi'] = jsnums.pi; - Primitives['e'] = Math.E; + Primitives['e'] = jsnums.e; Primitives['='] = function(MACHINE) { var firstArg = MACHINE.env[MACHINE.env.length-1]; @@ -622,8 +617,8 @@ MACHINE.env[MACHINE.env.length - 1 - i], i, '='); - if (MACHINE.env[MACHINE.env.length - 1 - i] !== - MACHINE.env[MACHINE.env.length - 1 - i - 1]) { + if (! (jsnums.equals(MACHINE.env[MACHINE.env.length - 1 - i], + MACHINE.env[MACHINE.env.length - 1 - i - 1]))) { return false; } } @@ -644,8 +639,8 @@ MACHINE.env[MACHINE.env.length - 1 - i], i, '<'); - if (! (MACHINE.env[MACHINE.env.length - 1 - i] < - MACHINE.env[MACHINE.env.length - 1 - i - 1])) { + if (! (jsnums.lessThan(MACHINE.env[MACHINE.env.length - 1 - i], + MACHINE.env[MACHINE.env.length - 1 - i - 1]))) { return false; } } @@ -665,8 +660,8 @@ MACHINE.env[MACHINE.env.length - 1 - i], i, '>'); - if (! (MACHINE.env[MACHINE.env.length - 1 - i] > - MACHINE.env[MACHINE.env.length - 1 - i - 1])) { + if (! (jsnums.greaterThan(MACHINE.env[MACHINE.env.length - 1 - i], + MACHINE.env[MACHINE.env.length - 1 - i - 1]))) { return false; } } @@ -686,8 +681,8 @@ MACHINE.env[MACHINE.env.length - 1 - i], i, '<='); - if (! (MACHINE.env[MACHINE.env.length - 1 - i] <= - MACHINE.env[MACHINE.env.length - 1 - i - 1])) { + if (! (jsnums.lessThanOrEqual(MACHINE.env[MACHINE.env.length - 1 - i], + MACHINE.env[MACHINE.env.length - 1 - i - 1]))) { return false; } } @@ -708,8 +703,8 @@ MACHINE.env[MACHINE.env.length - 1 - i], i, '>='); - if (! (MACHINE.env[MACHINE.env.length - 1 - i] >= - MACHINE.env[MACHINE.env.length - 1 - i - 1])) { + if (! (jsnums.greaterThanOrEqual(MACHINE.env[MACHINE.env.length - 1 - i], + MACHINE.env[MACHINE.env.length - 1 - i - 1]))) { return false; } } @@ -729,7 +724,7 @@ MACHINE.env[MACHINE.env.length - 1 - i], i, '+'); - result += MACHINE.env[MACHINE.env.length - 1 - i]; + result = jsnums.add(result, MACHINE.env[MACHINE.env.length - 1 - i]); }; return result; }; @@ -747,7 +742,7 @@ MACHINE.env[MACHINE.env.length - 1 - i], i, '*'); - result *= MACHINE.env[MACHINE.env.length - 1 - i]; + result = jsnums.multiply(result, MACHINE.env[MACHINE.env.length - 1 - i]); } return result; }; @@ -762,7 +757,7 @@ MACHINE.env[MACHINE.env.length-1], 0, '-'); - return -(MACHINE.env[MACHINE.env.length-1]); + return jsnums.subtract(0, MACHINE.env[MACHINE.env.length-1]); } var result = MACHINE.env[MACHINE.env.length - 1]; for (var i = 1; i < MACHINE.argcount; i++) { @@ -772,7 +767,7 @@ MACHINE.env[MACHINE.env.length-1-i], i, '-'); - result -= MACHINE.env[MACHINE.env.length - 1 - i]; + result = jsnums.subtract(result, MACHINE.env[MACHINE.env.length - 1 - i]); } return result; }; @@ -794,7 +789,7 @@ MACHINE.env[MACHINE.env.length-1-i], i, '/'); - result /= MACHINE.env[MACHINE.env.length - 1 - i]; + result = jsnums.divide(result, MACHINE.env[MACHINE.env.length - 1 - i]); } return result; }; @@ -802,6 +797,47 @@ Primitives['/'].displayName = '/'; + + Primitives['add1'] = function(MACHINE) { + testArgument(MACHINE, + 'number', + isNumber, + MACHINE.env[MACHINE.env.length - 1], + 0, + 'add1'); + var firstArg = MACHINE.env[MACHINE.env.length-1]; + return jsnums.add(firstArg, 1); + }; + Primitives['add1'].arity = 1; + Primitives['add1'].displayName = 'add1'; + + Primitives['sub1'] = function(MACHINE) { + testArgument(MACHINE, + 'number', + isNumber, + MACHINE.env[MACHINE.env.length - 1], + 0, + 'sub1'); + var firstArg = MACHINE.env[MACHINE.env.length-1]; + return jsnums.subtract(firstArg, 1); + }; + Primitives['sub1'].arity = 1; + Primitives['sub1'].displayName = 'sub1'; + + Primitives['zero?'] = function(MACHINE) { + var firstArg = MACHINE.env[MACHINE.env.length-1]; + return jsnums.equals(firstArg, 0); + }; + Primitives['zero?'].arity = 1; + Primitives['zero?'].displayName = 'zero?'; + + + + + + + + Primitives['cons'] = function(MACHINE) { var firstArg = MACHINE.env[MACHINE.env.length-1]; var secondArg = MACHINE.env[MACHINE.env.length-2]; @@ -899,39 +935,6 @@ Primitives['null?'].arity = 1; Primitives['null?'].displayName = 'null?'; - Primitives['add1'] = function(MACHINE) { - testArgument(MACHINE, - 'number', - isNumber, - MACHINE.env[MACHINE.env.length - 1], - 0, - 'add1'); - var firstArg = MACHINE.env[MACHINE.env.length-1]; - return firstArg + 1; - }; - Primitives['add1'].arity = 1; - Primitives['add1'].displayName = 'add1'; - - Primitives['sub1'] = function(MACHINE) { - testArgument(MACHINE, - 'number', - isNumber, - MACHINE.env[MACHINE.env.length - 1], - 0, - 'sub1'); - var firstArg = MACHINE.env[MACHINE.env.length-1]; - return firstArg - 1; - }; - Primitives['sub1'].arity = 1; - Primitives['sub1'].displayName = 'sub1'; - - Primitives['zero?'] = function(MACHINE) { - var firstArg = MACHINE.env[MACHINE.env.length-1]; - return firstArg === 0; - }; - Primitives['zero?'].arity = 1; - Primitives['zero?'].displayName = 'zero?'; - Primitives['vector'] = function(MACHINE) { var i; var result = []; @@ -997,7 +1000,7 @@ 0, 'vector-set!'); var firstArg = MACHINE.env[MACHINE.env.length-1]; - var secondArg = MACHINE.env[MACHINE.env.length-2]; + var secondArg = jsnums.toFixnum(MACHINE.env[MACHINE.env.length-2]); var thirdArg = MACHINE.env[MACHINE.env.length-3]; firstArg[secondArg] = thirdArg; return null; @@ -1013,7 +1016,7 @@ MACHINE.env[MACHINE.env.length - 1], 0, 'vector-length'); - var firstArg = MACHINE.env[MACHINE.env.length-1]; + var firstArg = MACHINE.env[jsnums.toFixnum(MACHINE.env.length-1)]; return firstArg.length; }; Primitives['vector-length'].arity = 1; @@ -1031,7 +1034,7 @@ if (MACHINE.argcount == 2) { value = MACHINE.env[MACHINE.env.length - 2]; } - var length = MACHINE.env[MACHINE.env.length-1]; + var length = jsnums.toFixnum(MACHINE.env[MACHINE.env.length-1]); var arr = []; for(var i = 0; i < length; i++) { arr[i] = value; @@ -1343,8 +1346,8 @@ // Executes all programs that have been labeled as a main module var invokeMains = function(machine, succ, fail) { - plt.runtime.ready(function() { - machine = machine || plt.runtime.currentMachine; + runtime.ready(function() { + machine = machine || runtime.currentMachine; succ = succ || function() {}; fail = fail || function() {}; var mainModules = machine.mainModules.slice(); @@ -1368,7 +1371,7 @@ // Exports - + var exports = runtime; exports['currentMachine'] = new Machine(); exports['invokeMains'] = invokeMains; @@ -1433,4 +1436,6 @@ exports['HaltError'] = HaltError; -}).call(this); \ 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..ff70603 100644 --- a/js-assembler/runtime-src/types.js +++ b/js-assembler/runtime-src/types.js @@ -1,42 +1,65 @@ -////////////////////////////////////////////////////////////////////// -// 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 = 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; + }); -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 +70,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 +98,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 +151,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 +171,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 +253,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 +482,580 @@ 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)); + } + 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 +1085,7 @@ String.prototype.toDisplayedString = function(cache) { */ -////////////////////////////////////////////////////////////////////// - -// makeLowLevelEqHash: -> hashtable -// Constructs an eq hashtable that uses Moby's getEqHashCode function. -var makeLowLevelEqHash = helpers.makeLowLevelEqHash; + ////////////////////////////////////////////////////////////////////// @@ -1086,247 +1094,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++) { - var keyStr = types.toDisplayedString(keys[i], cache); - var valStr = types.toDisplayedString(this.hash.get(keys[i]), cache); + EqHashTable.prototype.toDisplayedString = function(cache) { + var keys = this.hash.keys(); + var ret = []; + for (var i = 0; i < keys.length; i++) { + var keyStr = toDisplayedString(keys[i], cache); + var valStr = toDisplayedString(this.hash.get(keys[i]), cache); 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 = toDisplayedString(keys[i], cache); + var valStr = 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,697 +1344,523 @@ var makeRenderEffectType = function(name, superType, initFieldCnt, impl, guard) -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + var isNumber = jsnums.isSchemeNumber; + var isReal = jsnums.isReal; + var isRational = jsnums.isRational; + var isComplex = isNumber; + var isInteger = jsnums.isInteger; -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; -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) { + 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) { + 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); - } + // 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 ( typeof(x) == 'object' && - typeof(y) == 'object' && - x.isEqual && - y.isEqual) { + if (isNumber(x) && isNumber(y)) { + return jsnums.eqv(x, y); + } - if (typeof (aUnionFind) === 'undefined') { - aUnionFind = new UnionFind(); - } + if (isString(x) && isString(y)) { + return x.toString() === y.toString(); + } - if (aUnionFind.find(x) === aUnionFind.find(y)) { - return true; - } - else { - aUnionFind.merge(x, y); - return x.isEqual(y, aUnionFind); - } - } - return false; -}; + 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; + // 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; -}; + } + return primitiveF._mobyLiftedFunction; + }; -////////////////////////////////////////////////////////////////////// -var ThreadCell = function(v, isPreserved) { - this.v = v; - this.isPreserved = isPreserved || false; -}; + ////////////////////////////////////////////////////////////////////// + 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; -}; + // 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 ) { + 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 +1868,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 +1903,462 @@ 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.toWrittenString = toWrittenString; -types.toDisplayedString = toDisplayedString; -types.toDomNode = toDomNode; + types.symbol = Symbol.makeInstance; + types.rational = jsnums.makeRational; + types.floatpoint = 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.character = 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.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) {