#lang scheme/base
(require (planet "evector.scm" ("soegaard" "evector.plt" 1))
srfi/13/string
(except-in scheme/list empty)
scheme/match
scheme/math
"../../debug.ss"
"../syntax/regexps.ss"
"exceptions.ss"
"value.ss"
"runtime.ss")
(provide install-standard-library! install-standard-library-once! install-properties! reset-global-object! reset-primitive-constructors!)
(define (object-descriptor object)
(format "[object ~a]" (object-class object)))
(define js:print
(build-function 1
(lambda args
(let ([print1 (lambda (x)
(display (any->string x)))])
(unless (null? args)
(print1 (car args))
(for-each (lambda (arg)
(display " ")
(print1 arg))
(cdr args)))
(newline)))))
(define js:parseInt
(build-function 2
(lambda ([string (void)] [radix (void)] . _)
(let* ([s (string-trim (any->string string) char-whitespace?)]
[r (any->int32 radix)]
[sign (if (char=? (string-ref s 0) #\-)
(begin (set! s (substring s 1)) -1)
1)])
(if (or (and (not (zero? r)) (< r 2))
(> r 36))
+nan.0
(let ([r (cond
[(or (string-prefix? "0x" s) (string-prefix? "0X" s))
(set! s (substring s 2))
16]
[(string-prefix? "0" s)
(set! s (substring s 1))
8]
[(zero? r)
10]
[else r])])
(cond
[(regexp-match (build-integer-regexp r) s)
=> (lambda (match)
(let sum ([factor 1]
[total 0]
[digits (map char->digit (reverse (string->list (car match))))])
(if (null? digits)
total
(sum (* factor r)
(+ total (* (car digits) factor))
(cdr digits)))))]
[else +nan.0])))))))
(define (char->digit ch)
(cond
[(memv ch (string->list "0123456789"))
(- (char->integer ch) (char->integer #\0))]
[(memv ch (string->list "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
(- (char->integer ch) (char->integer #\A))]
[(memv ch (string->list "abcdefghijklmnopqrstuvwxyz"))
(- (char->integer ch) (char->integer #\a))]
[else
(error 'char->digit "bad digit: ~a" ch)]))
(define (build-integer-regexp base)
(regexp
(cond
[(<= base 10)
(format "^[0-~a]+" (sub1 base))]
[(= base 11)
"^[0-9Aa]+"]
[else
(let ([last-char-index (- base 11)])
(format "^[0-9A-~aa-~a]+"
(string-ref "ABCDEFGHIJKLMNOPQRSTUVWXYZ" last-char-index)
(string-ref "abcdefghijklmnopqrstuvwxyz" last-char-index)))])))
(define js:parseFloat
(build-function 1
(lambda ([arg (void)] . _)
(let ([s (string-trim (any->string arg)
char-whitespace?)])
(cond
[(regexp-match rx:float s)
=> (lambda (match)
(string->number (car match)))]
[else +nan.0])))))
(define js:isNaN
(build-function 1
(lambda ([arg (void)] . _)
(NaN? (any->number arg)))))
(define js:isFinite
(build-function 1
(lambda ([arg (void)] . _)
(let ([x (any->number arg)])
(and (not (NaN? x))
(not (infinite? x)))))))
(define js:eval
(build-function 1
(lambda args
(raise-runtime-exception here "indirect eval"))))
(define (tmp:stub arity name)
(build-function arity
(lambda args
(error name "not yet implemented"))))
(define js:decodeURI (tmp:stub 1 'decodeURI))
(define js:decodeURIComponent (tmp:stub 1 'decodeURIComponent))
(define js:encodeURI (tmp:stub 1 'encodeURI))
(define js:encodeURIComponent (tmp:stub 1 'encodeURIComponent))
(define (reset-object! object)
(set-object-properties! object (object-table))
(set-ref! eval-ref js:eval))
(define (reset-global-object! global)
(reset-object! global)
(reset-object! proto:global) (reset-object! proto:proto)
(object-put! proto:proto 'write (build-function 1
(lambda args
(write (object-descriptor (current-this)) (if (null? args) (current-output-port) (car args))))))
(object-put! proto:proto 'display (build-function 1
(lambda args
(display (object-descriptor (current-this)) (if (null? args) (current-output-port) (car args))))))
(object-put! proto:global 'toString (build-function 0
(lambda args
(object-descriptor (current-this)))))
(object-put! proto:global 'hasOwnProperty (build-function 1
(lambda args
(has-own-property? (current-this)
(any->property-name (get-arg args 0)))))))
(define (reset-primitive-constructors! global)
(for ([ctor (list Object Function Array String Boolean Number Trace Name)]
[proto (list proto:Object proto:Function proto:Array proto:String proto:Boolean proto:Number proto:Trace proto:Name)]
[name '(Object Function Array String Boolean Number Trace Name)])
(reset-object! proto)
(reset-object! ctor)
(object-put! ctor 'prototype proto (bit-field DONT-ENUM? DONT-DELETE? READ-ONLY?))
(object-put! ctor 'length 1 (bit-field DONT-ENUM? DONT-DELETE? READ-ONLY?))
(object-put! global name ctor (bit-field DONT-ENUM? DONT-DELETE?))
(object-put! proto 'constructor ctor))
(reset-object! Math)
(object-put! global 'Math Math (bit-field DONT-ENUM? DONT-DELETE?)))
(define Object-methods
`( (toString ,(build-function 0
(lambda args
(object-descriptor (current-this)))))
(toLocaleString ,(build-function 0
(lambda args
(let ([toString (object-get (current-this) 'toString (lambda ()
(raise-runtime-type-error here "function" "undefined")))])
(apply toString args)))))
(valueOf ,(build-function 0
(lambda args
(current-this))))
(hasOwnProperty ,(build-function 0
(lambda args
(has-own-property? (current-this)
(any->property-name (get-arg args 0))))))
(isPrototypeOf ,(build-function 1
(lambda args
(let ([O (current-this)]
[V (if (null? args) (void) (car args))])
(and (object? V)
(let loop ([V (object-proto V)])
(and V (or (eq? O V)
(loop (object-proto V))))))))))
(propertyIsEnumerable ,(build-function 1
(lambda args
(let ([O (current-this)]
[V (any->property-name (if (null? args) (void) (car args)))])
(and (has-own-property? O V)
(not (bit-flag-set? (object-get-attributes O V) DONT-ENUM?)))))))
))
(define Function-methods
`( (toString ,(build-function 0
(lambda args
(unless (descendant-of? (current-this) proto:Function)
(raise-runtime-type-error here "function" "object"))
"[object Function]")))
(apply ,(tmp:stub 2 "apply"))
(call ,(tmp:stub 1 "call"))
))
(define (as-if-by-new-Array)
(new-Array))
(define Array-methods
`((write ,(build-function 1
(lambda args
(let ([this (current-this)]
[out (if (null? args) (current-output-port) (car args))])
(for ([i (in-range (object-get this 'length (lambda () 0) any->uint32))])
(when (> i 0)
(display "," out))
(object-get this (any->string i) void (lambda (x) (write x out))))))))
(display ,(build-function 1
(lambda args
(let ([this (current-this)]
[out (if (null? args) (current-output-port) (car args))])
(for ([i (in-range (object-get this 'length (lambda () 0) any->uint32))])
(when (> i 0)
(display "," out))
(object-get this (any->property-name i) void (lambda (x) (display x out))))))))
(toString ,(build-function 0
(lambda args
(let ([this (current-this)])
(string-join (for/list ([i (in-range (object-get this 'length (lambda () 0) any->uint32))])
(object-get this (any->property-name i) (lambda () "") any->string))
","
'infix)))))
(toLocaleString ,(build-function 0
(lambda args
(let ([this (current-this)])
(unless (descendant-of? this proto:Array)
(raise-runtime-type-error here "array" "object"))
(string-join (for/list ([i (in-range (object-get this 'length (lambda () 0) any->uint32))])
(object-get this
(any->string i)
(lambda () "")
(lambda (v)
(invoke (any->object v)
'toLocaleString
'()
(lambda (s1 s2)
(raise-runtime-type-error here s1 s2))))))
","
'infix)))))
(concat ,(build-function 1
(lambda args
(let ([this (current-this)]
[A (as-if-by-new-Array)])
(define (copy-arrays arrays n)
(if (pair? arrays)
(let ([E (car arrays)])
(define (copy-array Result6 n k)
(if (= k Result6)
(copy-arrays (cdr arrays) n)
(let ([Result8 (any->property-name k)])
(when (has-property? E Result8)
(object-put! A (any->string n) (object-get E Result8)))
(copy-array Result6 (add1 n) (add1 k)))))
(if (array? E)
(copy-array (object-get E 'length) n 0)
(begin (object-put! A n E)
(copy-arrays (cdr arrays) (add1 n)))))
n))
(object-put! A "length" (copy-arrays (cons this args) 0))
A))))
(join ,(build-function 1
(lambda args
(let ([this (current-this)])
(string-join (for/list ([i (in-range (object-get this 'length (lambda () 0) any->uint32))])
(object-get this
(any->property-name i)
(lambda () "")
(lambda (v)
(if (or (void? v) (null? v)) "" (any->string v)))))
(or (and (pair? args) (any->string (car args)))
",")
'infix)))))
(pop ,(build-function 0
(lambda args
(let ([this (current-this)])
(let ([len (object-get this 'length (lambda () 0) any->uint32)])
(if (zero? len)
(begin (object-put! this 'length len) (void))
(let* ([key (any->property-name (sub1 len))]
[val (object-get this key void)])
(object-delete! this key)
(object-put! this "length" (sub1 len))
val)))))))
(push ,(build-function 1
(lambda args
(let ([this (current-this)])
(let* ([len (object-get this 'length (lambda () 0) any->uint32)]
[new-len (+ len (length args))])
(for ([arg args]
[n (in-range len new-len)])
(object-put! this (any->property-name n) arg))
(object-put! this 'length new-len)
new-len)))))
(reverse ,(build-function 0
(lambda args
(let ([this (current-this)])
(let* ([len (object-get this 'length (lambda () 0) any->uint32)]
[half (floor (/ len 2))])
(define (loop left)
(if (= left half)
this
(let* ([right (sub1 (- len left))]
[left-key (any->property-name left)]
[right-key (any->property-name right)])
(object-get this
left-key
(lambda ()
(object-get this
right-key
(lambda ()
(object-delete! this left-key)
(object-delete! this right-key))
(lambda (right-val)
(object-delete! this right-key)
(object-put! this left-key right-val))))
(lambda (left-val)
(object-get this
right-key
(lambda ()
(object-put! this right-key left-val)
(object-delete! this right-key))
(lambda (right-val)
(object-put! this left-key right-val)
(object-put! this right-key left-val)))))
(loop (add1 left)))))
(loop 0))))))
(shift ,(build-function 0
(lambda args
(let ([this (current-this)])
(let ([len (object-get this 'length (lambda () 0) any->uint32)])
(if (zero? len)
(begin (object-put! this 'length len) (void))
(let ([removed (object-get this "0")])
(define (loop k)
(if (= k len)
(begin (object-delete! this (any->property-name (sub1 len)))
(object-put! this 'length (sub1 len))
removed)
(let ([k-key (any->property-name k)]
[k-1-key (any->property-name (sub1 k))])
(object-get this
k-key
(lambda ()
(object-delete! this k-1-key))
(lambda (val)
(object-put! this k-1-key val)))
(loop (add1 k)))))
(loop 0))))))))
(slice ,(build-function 2
(lambda args
(let* ([this (current-this)]
[len (object-get this 'length (lambda () 0) any->uint32)]
[A (as-if-by-new-Array)])
(define (any->index x)
(let ([int (any->integer x)])
(if (negative? int)
(max (+ len int) 0)
(min int len))))
(let-values ([(start end) (match args
[(list) (values (any->index (void))
(any->index (void)))]
[(list start) (values (any->index start)
(any->index (void)))]
[(list start end _ ...) (values (any->index start)
(any->index end))])])
(define (loop k n)
(if (>= k end)
(object-put! A 'length n)
(let ([k-key (any->property-name k)])
(when (has-property? this k-key)
(object-put! A (any->property-name n) (object-get this k-key)))
(loop (add1 k) (add1 n)))))
(loop start 0)
A)))))
(sort ,(build-function 1
(lambda args
(let ([this (current-this)]
[comparefn (if (null? args) (void) (car args))])
(define (SortCompare j k)
(let ([j-key (any->property-name j)]
[k-key (any->property-name k)])
(let ([has-j? (has-property? this j-key)]
[has-k? (has-property? this k-key)])
(cond
[(and (not has-j?) (not has-k?)) 0]
[(not has-j?) 1]
[(not has-k?) -1]
[else
(let ([x (object-get this j-key)]
[y (object-get this k-key)])
(cond
[(and (void? x) (void? y)) 0]
[(void? x) 1]
[(void? y) -1]
[(void? comparefn)
(let ([x-str (any->string x)]
[y-str (any->string y)])
(cond
[(string<? x-str y-str) -1]
[(string<? x-str y-str) 1]
[else 0]))]
[else (comparefn x y)
]))]))))
(define (quicksort! p r)
(when (< p r)
(let ([q (partition! p r)])
(quicksort! p q)
(quicksort! (add1 q) r))))
(define (partition! p r)
(define (loop i j)
(let ([j (let drop-top ([j j])
(let ([cmp (any->integer (SortCompare j p))])
(if (or (zero? cmp) (negative? cmp)) j (drop-top (sub1 j)))))]
[i (let raise-bottom ([i i])
(let ([cmp (any->integer (SortCompare i p))])
(if (or (zero? cmp) (positive? cmp)) i (raise-bottom (add1 i)))))])
(if (< i j)
(begin (swap! i j)
(loop i j))
j)))
(loop (sub1 p) (add1 r)))
(define (swap! i j)
(let ([i-key (any->property-name i)]
[j-key (any->property-name j)])
(let ([has-i? (has-property? this i-key)]
[has-j? (has-property? this j-key)])
(cond
[(and (not has-i?) (not has-j?)) (void)]
[(not has-i?)
(let ([j-val (object-get this j-key)])
(object-delete! this j-key)
(object-put! this i-key j-val))]
[(not has-j?)
(let ([i-val (object-get this i-key)])
(object-delete! this i-key)
(object-put! this j-key i-val))]
[else
(let ([i-val (object-get this i-key)]
[j-val (object-get this j-key)])
(object-put! this i-key j-val)
(object-put! this j-key i-val))]))))
(let ([len (object-get this 'length (lambda () 0) any->uint32)])
(quicksort! 0 (sub1 len))
this)))))
(splice ,(build-function 2
(lambda args
(let* ([this (current-this)]
[len (object-get this 'length (lambda () 0) any->uint32)]
[A (as-if-by-new-Array)])
(let-values ([(start deleteCount items)
(match args
[(list) (values 0 0 null)]
[(list start) (values (any->integer start) 0 null)]
[(list start deleteCount items ...)
(values (any->integer start)
(any->integer deleteCount)
items)])])
(let* ([start (if (negative? start) (max (+ len start) 0)
(min start len))]
[deleteCount (min (max deleteCount 0) (- len start))]) (for ([k (in-range 0 deleteCount)])
(let ([key (any->property-name (+ start k))])
(when (has-property? this key)
(object-put! A (any->property-name k) (object-get this key)))))
(object-put! A 'length deleteCount)
(let* ([insertCount (length items)] [newLength (+ (- len deleteCount) insertCount)])
(cond
[(< insertCount deleteCount)
(for ([k (in-range start (- len deleteCount))])
(let ([from-key (any->property-name (+ k deleteCount))]
[to-key (any->property-name (+ k insertCount))])
(if (has-property? this from-key)
(object-put! this to-key (object-get this from-key))
(object-delete! this to-key))))
(for ([k (in-range len newLength)])
(object-delete! this (any->property-name (sub1 k))))]
[(> insertCount deleteCount)
(for ([k (in-range (- len deleteCount) start -1)])
(let ([from-key (any->property-name (+ k (sub1 deleteCount)))]
[to-key (any->property-name (+ k (sub1 insertCount)))])
(if (has-property? this from-key)
(object-put! this to-key (object-get this from-key))
(object-delete! this to-key))))])
(for ([item items]
[k (in-range start (+ start insertCount))])
(object-put! this (any->property-name k) item))
(object-put! this 'length newLength)
A)))))))
(unshift ,(build-function 1
(lambda args
(let* ([this (current-this)]
[len (object-get this 'length (lambda () 0) any->uint32)] [count (length args)]) (for ([k (in-range len 0 -1)])
(let ([from-key (any->property-name (sub1 k))] [to-key (any->property-name (+ count (sub1 k)))]) (if (has-property? this from-key)
(object-put! this to-key (object-get this from-key))
(object-delete! this to-key))))
(for ([item args]
[k (in-range 0 count)])
(object-put! this (any->property-name k) item))
(let ([new-len (+ len count)])
(object-put! this 'length new-len)
new-len)))))
))
(define String-statics
`( (fromCharCode ,(build-function 1
(lambda args
(list->string
(map (compose integer->char any->uint16) args)))))
))
(define (show-wrapper write?)
(build-function 1
(lambda args
(let ([this (current-this)]
[out (if (null? args) (current-output-port) (car args))]
[show (if write? write display)])
(cond
[(wrapper? this)
(show (wrapper-value this) out)]
[(object? this)
(display "[object Object]" out)]
[else
(show this out)])))))
(define write-wrapper (show-wrapper #t))
(define display-wrapper (show-wrapper #f))
(define String-methods
`((write ,write-wrapper)
(display ,display-wrapper)
(toString ,(build-function 0
(lambda args
(current-this))))
(valueOf ,(tmp:stub 0 "valueOf"))
(charAt ,(tmp:stub 1 "charAt"))
(charCodeAt ,(tmp:stub 1 "charCodeAt"))
(concat ,(tmp:stub 1 "concat"))
(indexOf ,(tmp:stub 1 "indexOf"))
(lastIndexOf ,(tmp:stub 1 "lastIndexOf"))
(localeCompare ,(tmp:stub 1 "localeCompare"))
(match ,(tmp:stub 1 "match"))
(replace ,(tmp:stub 2 "replace"))
(search ,(tmp:stub 1 "search"))
(slice ,(tmp:stub 2 "slice"))
(split ,(tmp:stub 2 "split"))
(substring ,(tmp:stub 2 "substring"))
(toLowerCase ,(tmp:stub 0 "toLowerCase"))
(toLocaleLowerCase ,(tmp:stub 0 "toLocaleLowerCase"))
(toUpperCase ,(tmp:stub 0 "toUpperCase"))
(toLocaleUpperCase ,(tmp:stub 0 "toLocaleUpperCase"))
))
(define Boolean-methods
`((write ,write-wrapper)
(display ,display-wrapper)
(toString ,(tmp:stub 0 "toString"))
(valueOf ,(tmp:stub 0 "valueOf"))
))
(define Number-statics
`( (MAX_VALUE ,(void) ,(bit-field DONT-DELETE? READ-ONLY? DONT-ENUM?))
(MIN_VALUE ,(void) ,(bit-field DONT-DELETE? READ-ONLY? DONT-ENUM?))
(NaN +nan.0 ,(bit-field DONT-DELETE? READ-ONLY? DONT-ENUM?))
(NEGATIVE_INFINITY -inf.0 ,(bit-field DONT-DELETE? READ-ONLY? DONT-ENUM?))
(POSITIVE_INFINITY +inf.0 ,(bit-field DONT-DELETE? READ-ONLY? DONT-ENUM?))
))
(define Number-methods
`((write ,write-wrapper)
(display ,display-wrapper)
(toString ,(tmp:stub 0 "toString"))
(toLocaleString ,(tmp:stub 0 "toLocaleString"))
(valueOf ,(tmp:stub 0 "valueOf"))
(toFixed ,(tmp:stub 1 "toFixed"))
(toExponential ,(tmp:stub 1 "toExponential"))
(toPrecision ,(tmp:stub 1 "toPrecision"))
))
(define Math-static-properties
`( (E ,(exp 1) ,(bit-field DONT-ENUM? DONT-DELETE? READ-ONLY?))
(LN10 ,(log 10) ,(bit-field DONT-ENUM? DONT-DELETE? READ-ONLY?))
(LN2 ,(log 2) ,(bit-field DONT-ENUM? DONT-DELETE? READ-ONLY?))
(LOG2E ,(/ 1 (log 2)) ,(bit-field DONT-ENUM? DONT-DELETE? READ-ONLY?))
(LOG10E ,(/ 1 (log 10)) ,(bit-field DONT-ENUM? DONT-DELETE? READ-ONLY?))
(PI ,pi ,(bit-field DONT-ENUM? DONT-DELETE? READ-ONLY?))
(SQRT1_2 ,(sqrt 1/2) ,(bit-field DONT-ENUM? DONT-DELETE? READ-ONLY?))
(SQRT_2 ,(sqrt 2) ,(bit-field DONT-ENUM? DONT-DELETE? READ-ONLY?))
))
(define Math-static-methods
`( (abs ,(tmp:stub 1 "abs"))
(acos ,(tmp:stub 1 "acos"))
(asin ,(tmp:stub 1 "asin"))
(atan ,(tmp:stub 1 "atan"))
(atan2 ,(tmp:stub 2 "atan2"))
(ceil ,(tmp:stub 1 "ceil"))
(cos ,(tmp:stub 1 "cos"))
(exp ,(tmp:stub 1 "exp"))
(floor ,(tmp:stub 1 "floor"))
(log ,(tmp:stub 1 "log"))
(max ,(tmp:stub 2 "max"))
(min ,(tmp:stub 2 "min"))
(pow ,(tmp:stub 2 "pow"))
(random ,(tmp:stub 0 "random"))
(round ,(tmp:stub 1 "round"))
(sin ,(tmp:stub 1 "sin"))
(sqrt ,(tmp:stub 1 "sqrt"))
(tan ,(tmp:stub 1 "tan"))
))
(define global-properties
`( (NaN +nan.0 ,(bit-field DONT-ENUM? DONT-DELETE?))
(Infinity +inf.0 ,(bit-field DONT-ENUM? DONT-DELETE?))
(undefined ,(void) ,(bit-field DONT-ENUM? DONT-DELETE?))
))
(define eval-ref
(let ([state js:eval])
(make-ref (lambda () state)
(lambda (val)
(set! state val)
(original-eval? (eq? val js:eval))
val)
(lambda () #t))))
(define global-methods
`( (eval ,eval-ref ,(bit-field DONT-DELETE?))
(parseInt ,js:parseInt)
(parseFloat ,js:parseFloat)
(isNaN ,js:isNaN)
(isFinite ,js:isFinite)
(decodeURI ,js:decodeURI)
(decodeURIComponent ,js:decodeURIComponent)
(encodeURI ,js:encodeURI)
(encodeURIComponent ,js:encodeURIComponent)
))
(define global-custom-properties
`((it ,(void) ,(bit-field DONT-ENUM? DONT-DELETE?))
))
(define global-custom-methods
`( (print ,js:print)
))
(define Trace-methods
`((toString ,(build-function 0
(lambda args
(object-descriptor (current-this)))))
(trace ,(build-function 2
(case-lambda
[() (void)]
[(x) (void)]
[(x thunk . rest)
(let ([this (current-this)])
(unless (wrapper? this)
(raise-runtime-type-error here "Trace" "object"))
(unless (procedure? thunk)
(raise-runtime-type-error here "function" "?"))
(with-continuation-mark (wrapper-value this) x
(thunk)))])))
(toArray ,(build-function 0
(lambda args
(let ([this (current-this)])
(unless (wrapper? this)
(raise-runtime-type-error here "Trace" "object"))
(list->array
(continuation-mark-set->list
(current-continuation-marks)
(wrapper-value this)))))))
))
(define Name-methods
`((toString ,(build-function 0
(lambda args
(object-descriptor (current-this)))))
))
(define (install-properties! object properties)
(for-each (lambda (property)
(match property
[(list name value)
(object-put! object name value (bit-field DONT-ENUM?))]
[(list name value attributes)
(object-put! object name value attributes)]))
properties))
(define installation-cache (make-hasheq))
(define (install-standard-library-once! global)
(hash-ref installation-cache global (lambda ()
(hash-set! installation-cache global #f)
(install-standard-library! global)
#t)))
(define (install-standard-library! global)
(reset-global-object! global)
(reset-primitive-constructors! global)
(install-properties! global global-properties)
(install-properties! global global-methods)
(install-properties! global global-custom-properties)
(install-properties! global global-custom-methods)
(install-properties! proto:Object Object-methods)
(install-properties! proto:Function Function-methods)
(install-properties! proto:Array Array-methods)
(install-properties! String String-statics)
(install-properties! proto:String String-methods)
(install-properties! proto:Boolean Boolean-methods)
(install-properties! Number Number-statics)
(install-properties! proto:Number Number-methods)
(install-properties! Math Math-static-properties)
(install-properties! Math Math-static-methods)
(install-properties! proto:Trace Trace-methods)
(install-properties! proto:Name Name-methods)
(current-this global)
(original-eval? #t)
global)