279 lines
11 KiB
Racket
279 lines
11 KiB
Racket
#lang racket/base
|
|
(require "simulator-structs.rkt"
|
|
"simulator-helpers.rkt"
|
|
"../compiler/il-structs.rkt"
|
|
"../compiler/arity-structs.rkt"
|
|
racket/math
|
|
racket/list
|
|
(for-syntax racket/base))
|
|
|
|
(provide lookup-primitive set-primitive!)
|
|
|
|
(define mutated-primitives (make-hasheq))
|
|
(define (set-primitive! n p)
|
|
(hash-set! mutated-primitives n p))
|
|
|
|
|
|
(define (extract-arity proc)
|
|
(let loop ([racket-arity (procedure-arity proc)])
|
|
(cond
|
|
[(number? racket-arity)
|
|
racket-arity]
|
|
[(arity-at-least? racket-arity)
|
|
(make-ArityAtLeast (arity-at-least-value racket-arity))]
|
|
[(list? racket-arity)
|
|
(map loop racket-arity)])))
|
|
|
|
|
|
|
|
|
|
(define-syntax (make-lookup stx)
|
|
(syntax-case stx ()
|
|
[(_ #:functions (name ...)
|
|
#:constants (cname ...))
|
|
(with-syntax ([(prim-name ...) (generate-temporaries #'(name ...))]
|
|
[((name exported-name) ...)
|
|
(map (lambda (name)
|
|
(syntax-case name ()
|
|
[(real-name exported-name)
|
|
(list #'real-name #'exported-name)]
|
|
[_
|
|
(identifier? name)
|
|
(list name name)]))
|
|
(syntax->list #'(name ...)))])
|
|
(syntax/loc stx
|
|
(let ([prim-name (make-primitive-proc
|
|
(lambda (machine . args)
|
|
(apply name args))
|
|
(extract-arity name)
|
|
'exported-name)]
|
|
...)
|
|
(lambda (n)
|
|
(cond
|
|
[(hash-has-key? mutated-primitives n)
|
|
(hash-ref mutated-primitives n)]
|
|
[(eq? n 'exported-name)
|
|
prim-name]
|
|
...
|
|
[(eq? n 'cname)
|
|
cname]
|
|
...
|
|
[else
|
|
(make-undefined)]
|
|
)))))]))
|
|
|
|
(define e (exp 1))
|
|
|
|
(define my-cons (lambda (x y)
|
|
(make-MutablePair x y)))
|
|
|
|
(define my-list (lambda args
|
|
(let loop ([args args])
|
|
(cond
|
|
[(null? args)
|
|
null]
|
|
[else
|
|
(make-MutablePair (car args)
|
|
(loop (cdr args)))]))))
|
|
(define my-car (lambda (x)
|
|
(MutablePair-h x)))
|
|
|
|
(define my-cdr (lambda (x)
|
|
(MutablePair-t x)))
|
|
|
|
|
|
(define my-cadr (lambda (x)
|
|
(MutablePair-h (MutablePair-t x))))
|
|
|
|
(define my-caddr (lambda (x)
|
|
(MutablePair-h (MutablePair-t (MutablePair-t x)))))
|
|
|
|
|
|
(define my-pair? (lambda (x)
|
|
(MutablePair? x)))
|
|
|
|
(define my-box (lambda (x)
|
|
(vector x)))
|
|
|
|
(define my-unbox (lambda (x)
|
|
(vector-ref x 0)))
|
|
|
|
(define my-set-box! (lambda (x v)
|
|
(vector-set! x 0 v)
|
|
the-void-value))
|
|
|
|
(define my-vector->list (lambda (v)
|
|
(apply my-list (vector->list v))))
|
|
|
|
(define my-list->vector (lambda (l)
|
|
(apply vector
|
|
(let loop ([l l])
|
|
(cond
|
|
[(null? l)
|
|
null]
|
|
[else
|
|
(cons (MutablePair-h l)
|
|
(loop (MutablePair-t l)))])))))
|
|
|
|
|
|
(define my-set-car! (lambda (p v)
|
|
(set-MutablePair-h! p v)
|
|
the-void-value))
|
|
|
|
(define my-set-cdr! (lambda (p v)
|
|
(set-MutablePair-t! p v)
|
|
the-void-value))
|
|
|
|
(define my-void (lambda args
|
|
the-void-value))
|
|
|
|
(define my-display (lambda args
|
|
(apply display args)
|
|
the-void-value))
|
|
|
|
(define my-displayln (lambda args
|
|
(apply displayln args)
|
|
the-void-value))
|
|
|
|
(define my-newline (lambda args
|
|
(apply newline args)
|
|
the-void-value))
|
|
|
|
(define my-vector-set! (lambda args
|
|
(apply vector-set! args)
|
|
the-void-value))
|
|
|
|
|
|
|
|
(define my-member (lambda (x l)
|
|
(let loop ([l l])
|
|
(cond
|
|
[(null? l)
|
|
#f]
|
|
[(MutablePair? l)
|
|
(cond
|
|
[(equal? x (MutablePair-h l))
|
|
l]
|
|
[else
|
|
(loop (MutablePair-t l))])]
|
|
[else
|
|
(error 'member "not a list: ~s" l)]))))
|
|
|
|
(define my-reverse (lambda (l)
|
|
(let loop ([l l]
|
|
[acc null])
|
|
(cond
|
|
[(null? l)
|
|
acc]
|
|
[(MutablePair? l)
|
|
(loop (MutablePair-t l)
|
|
(make-MutablePair (MutablePair-h l) acc))]
|
|
[else
|
|
(error 'member "not a list: ~s" l)]))))
|
|
|
|
|
|
(define my-printf (lambda (fmt args)
|
|
(apply printf fmt (map (lambda (x)
|
|
(PrimitiveValue->racket x))
|
|
args))))
|
|
|
|
|
|
|
|
(define current-continuation-marks
|
|
(letrec ([f (case-lambda [(a-machine)
|
|
(f a-machine default-continuation-prompt-tag-value)]
|
|
[(a-machine tag)
|
|
(make-ContinuationMarkSet
|
|
(let loop ([frames (machine-control a-machine)])
|
|
(cond
|
|
[(empty? frames)
|
|
empty]
|
|
[else
|
|
(append (hash-map (frame-marks (first frames))
|
|
cons)
|
|
(if (eq? tag (frame-tag (first frames)))
|
|
empty
|
|
(loop (rest frames))))])))])])
|
|
(make-primitive-proc (lambda (machine . args) (apply f machine args))
|
|
'(0 1)
|
|
'current-continuation-marks)))
|
|
|
|
|
|
(define continuation-mark-set->list
|
|
;; not quite correct: ContinuationMarkSets need to preserve frame structure a bit more.
|
|
;; At the very least, we need to keep track of prompt tags somewhere.
|
|
(let ([f (lambda (a-machine mark-set key)
|
|
(let ([marks (ContinuationMarkSet-marks mark-set)])
|
|
(foldr make-MutablePair
|
|
null
|
|
(map cdr (filter (lambda (k+v)
|
|
(eq? (car k+v) key))
|
|
marks)))))])
|
|
(make-primitive-proc (lambda (machine . args) (apply f machine args))
|
|
'2 ;; fixme: should deal with prompt tags too
|
|
'current-continuation-marks)))
|
|
|
|
|
|
|
|
|
|
|
|
(define lookup-primitive (make-lookup #:functions (+ - * / = < <= > >=
|
|
sub1
|
|
not
|
|
null?
|
|
eq?
|
|
add1
|
|
sub1
|
|
zero?
|
|
abs
|
|
(my-void void)
|
|
quotient
|
|
remainder
|
|
|
|
(my-display display)
|
|
(my-displayln displayln)
|
|
(my-newline newline)
|
|
|
|
symbol->string
|
|
string-append
|
|
string-length
|
|
|
|
(my-cons cons)
|
|
(my-list list)
|
|
(my-car car)
|
|
(my-cdr cdr)
|
|
(my-cadr cadr)
|
|
(my-caddr caddr)
|
|
(my-pair? pair?)
|
|
null?
|
|
(my-set-car! set-car!)
|
|
(my-set-cdr! set-cdr!)
|
|
(my-member member)
|
|
(my-reverse reverse)
|
|
|
|
|
|
(my-box box)
|
|
(my-unbox unbox)
|
|
(my-set-box! set-box!)
|
|
|
|
vector
|
|
(my-vector-set! vector-set!)
|
|
vector-ref
|
|
(my-vector->list vector->list)
|
|
(my-list->vector list->vector)
|
|
vector-length
|
|
make-vector
|
|
|
|
|
|
equal?
|
|
symbol?
|
|
|
|
|
|
(my-printf printf)
|
|
)
|
|
#:constants (null pi e
|
|
current-continuation-marks
|
|
continuation-mark-set->list)))
|
|
|
|
|