diff --git a/collects/mrdemo/keymap.ss b/collects/mrdemo/keymap.ss new file mode 100644 index 0000000..496ebf2 --- /dev/null +++ b/collects/mrdemo/keymap.ss @@ -0,0 +1,16 @@ +; We'll use the same function as both a keyboard and mouse event +; handler. If it's a mouse event, we only want to insert something +; on the button-down part +(define insert-star + (lambda (edit event) + (if (or (not (is-a? event wx:mouse-event%)) + (send event button-down?)) + (send edit insert "*")) + #t)) + +(let ((kmap (send mred:console-edit get-keymap))) + (send kmap add-key-function "insert-star" insert-star) + (send kmap add-mouse-function "insert-star" insert-star) + (send kmap map-function "c:." "insert-star") + (send kmap map-function "ESC;rightbutton" "insert-star")) + diff --git a/collects/mrdemo/load.ss b/collects/mrdemo/load.ss new file mode 100644 index 0000000..2132b5d --- /dev/null +++ b/collects/mrdemo/load.ss @@ -0,0 +1,2 @@ + +(load "demo.ss") diff --git a/collects/mrdemo/mines.mre b/collects/mrdemo/mines.mre new file mode 100644 index 0000000..3609e91 Binary files /dev/null and b/collects/mrdemo/mines.mre differ diff --git a/collects/mrdemo/mines.ss b/collects/mrdemo/mines.ss new file mode 100644 index 0000000..db3d30f --- /dev/null +++ b/collects/mrdemo/mines.ss @@ -0,0 +1,379 @@ + +(require-library "macro.ss") + +(define TILE-HW 24) +(define WIDTH 16) +(define HEIGHT 16) +(define BOMB-COUNT 30) + +; Temporary +(define FRDW 12) +(define FRDH 39) +(define PANEL-HEIGHT 50) +(define TIME-WIDTH 600) +(define COUNT-WIDTH 600) + +(define DIGIT-COLOR-NAMES + ; 0th is background; 8th is foreground + (vector "LIGHT GREY" "BLUE" "GREEN" "RED" "PURPLE" "ORANGE" "YELLOW" "BROWN" "BLACK")) + +(define DIGIT-COLORS + (build-vector 9 (lambda (i) + (send wx:the-colour-database find-colour + (vector-ref DIGIT-COLOR-NAMES i))))) + +(define BG-COLOR (vector-ref DIGIT-COLORS 0)) +(define FG-COLOR (vector-ref DIGIT-COLORS 8)) +(define EXPLODE-COLOR (send wx:the-colour-database find-colour "RED")) + +(define BG-PEN (send wx:the-pen-list find-or-create-pen BG-COLOR 1 wx:const-solid)) +(define FG-PEN (send wx:the-pen-list find-or-create-pen FG-COLOR 1 wx:const-solid)) + +(define step-while + (opt-lambda (first test until step f [accum void] [init (void)]) + (let loop ([n first][a init]) + (if (test n until) + (loop (step n) (accum a (f n))) + a)))) + +(define tile:plain% + (class null () + (private + [state 'covered] + [neighbor-bomb-count 0]) + (public + [set-state + (lambda (newstate) + (set! state newstate))] + [get-state + (lambda () + state)] + [set-neighbor-bomb-count + (lambda (c) + (set! neighbor-bomb-count c))] + [get-neighbor-bomb-count + (lambda () + neighbor-bomb-count)] + [draw-text-tile + (lambda (dc x y w h hilite? border? str color) + (if border? + (send dc set-pen FG-PEN) + (send dc set-pen BG-PEN)) + (send dc draw-rectangle x y w h) + (when hilite? + (send dc draw-rectangle + (add1 x) (add1 y) + (- w 2) (- h 2))) + (when str + (if color + (send dc set-text-foreground color) + (send dc set-text-foreground FG-COLOR)) + (let ([tw (box 0)][th (box 0)]) + (send dc get-text-extent str tw th) + (send dc draw-text str + (+ x (/ (- w (unbox tw)) 2)) + (+ y (/ (- h (unbox th)) 2))))))] + [draw + (lambda (dc x y w h hilite?) + (case state + [(covered) (draw-text-tile dc x y w h hilite? #t #f #f)] + [(flagged) (draw-text-tile dc x y w h hilite? #t "X" #f)] + [(semi-flagged) (draw-text-tile dc x y w h hilite? #t "?" #f)] + [(uncovered) (draw-text-tile + dc x y w h #f #f + (if (zero? neighbor-bomb-count) + #f + (number->string neighbor-bomb-count)) + (vector-ref DIGIT-COLORS neighbor-bomb-count))]))]))) + +(define tile:bomb% + (class tile:plain% () + (inherit get-state draw-text-tile) + (rename [super-draw draw]) + (private + [explode-source? #f]) + (public + [set-explode-source + (lambda (s?) + (set! explode-source? s?))] + [draw + (lambda (dc x y w h hilite?) + (if (eq? (get-state) 'uncovered) + (draw-text-tile dc x y w h #f #f "*" + (and explode-source? EXPLODE-COLOR)) + (super-draw dc x y w h hilite?)))]) + (sequence + (super-init)))) + +(define (get-tile b x y) + (vector-ref (vector-ref b x) y)) + +(define (set-tile! b x y t) + (vector-set! (vector-ref b x) y t)) + +(define (do-surrounding b x y accum start default f) + (step-while -1 <= 1 add1 + (lambda (dx) + (step-while -1 <= 1 add1 + (lambda (dy) + (if (and (not (and (zero? dx) (zero? dy))) + (< -1 (+ x dx) WIDTH) + (< -1 (+ y dy) HEIGHT)) + (f dx dy) + default)) + accum start)) + accum start)) + +(define (is-bomb? x) + (is-a? x tile:bomb%)) + +(define (count-surrounding-bombs b x y) + (do-surrounding + b x y + 0 0 + (lambda (dx dy) + (if (is-bomb? (get-tile b (+ x dx) (+ y dy))) + 1 + 0)))) + +(define (for-each-tile b f) + (step-while 0 < WIDTH add1 + (lambda (x) + (step-while 0 < HEIGHT add1 + (lambda (y) + (f (get-tile b x y) x y)))))) + +(define (make-board) + (let ([b (build-vector WIDTH + (lambda (i) + (build-vector HEIGHT + (lambda (j) + (make-object tile:plain%)))))]) + (let loop ([n BOMB-COUNT]) + (unless (zero? n) + (let rloop () + (let* ([x (random WIDTH)] + [y (random HEIGHT)] + [t (get-tile b x y)]) + (if (is-a? t tile:bomb%) + (rloop) + (begin + (set-tile! b x y (make-object tile:bomb%)) + (loop (sub1 n)))))))) + (for-each-tile b (lambda (t x y) + (send t + set-neighbor-bomb-count + (count-surrounding-bombs b x y)))) + b)) + +(define f (make-object mred:frame% null "Minesweeper")) +(define vpanel (make-object mred:vertical-panel% f)) + +(define ms:canvas% + (class mred:canvas% args + (inherit get-dc clear + set-min-width set-min-height + stretchable-in-x stretchable-in-y) + (private + [panel (make-object mred:horizontal-panel% vpanel)]) + (sequence + (send panel stretchable-in-y #f)) + (private + [lspace (make-object mred:vertical-panel% panel)] + [time (make-object mred:message% panel "Time: 00000")] + [lmspace (make-object mred:vertical-panel% panel)] + [button (make-object mred:button% panel (lambda (b e) (reset)) "Reset")] + [rmspace (make-object mred:vertical-panel% panel)] + [count (make-object mred:message% panel "Count: 000")] + [rspace (make-object mred:vertical-panel% panel)] + + [set-time + (lambda (t) + (send time set-label (string-append "Time: " (number->string t))))] + [set-count + (lambda (c) + (send count set-label (string-append "Bombs: " (number->string c))))] + + [clicking #f] + [clicking-x 0] + [clicking-y 0] + [ready? #t] + [start-time #f] + [elapsed-time 0] + [timer #f] + [bomb-count BOMB-COUNT] + [cover-count (* HEIGHT WIDTH)] + [board null]) + (public + (stop-timer + (lambda () + (when timer + (send timer stop) + (set! timer #f)))) + (start-timer + (lambda () + (set! start-time (current-seconds)) + (set! timer + (make-object + (class-asi wx:timer% + (public + [notify + (lambda () + (let ([e (- (current-seconds) start-time)]) + (when (> e elapsed-time) + (set! elapsed-time e) + (set-time e))))])))) + (send timer start 100 #f))) + (end-of-game + (lambda (win?) + (stop-timer) + (set! ready? #f) + (set! start-time #f) + (unless win? + (show-all-bombs)) + (set-count BOMB-COUNT))) + (explode + (lambda () + (end-of-game #f))) + (win + (lambda () + (end-of-game #t))) + (reset + (lambda () + (stop-timer) + (set! ready? #t) + (set! start-time #f) + (set! elapsed-time 0) + (set! cover-count (* HEIGHT WIDTH)) + (clear) + (set-time 0) + (set! bomb-count BOMB-COUNT) + (set-count BOMB-COUNT) + (set! board (make-board)) + (on-paint))) + (show-all-bombs + (lambda () + (for-each-tile board + (lambda (t x y) + (when (is-bomb? t) + (change-state t (send t get-state) 'uncovered #f) + (paint-one t x y)))))) + (autoclick-surrounding + (lambda (x y) + (do-surrounding + board x y void (void) (void) + (lambda (dx dy) + (let* ([x2 (+ x dx)] + [y2 (+ y dy)] + [t (get-tile board x2 y2)] + [state (send t get-state)] + [nc (send t get-neighbor-bomb-count)]) + (unless (eq? state 'uncovered) + (change-state t state 'uncovered #t) + (paint-one t x2 y2) + (when (zero? nc) + (autoclick-surrounding x2 y2)))))))) + (change-state + (lambda (t old-state new-state update-count?) + (send t set-state new-state) + (when (and update-count? (not (eq? new-state old-state))) + (when (eq? new-state 'uncovered) + (set! cover-count (sub1 cover-count))) + (when (eq? old-state 'uncovered) + (set! cover-count (add1 cover-count))) + (when (eq? new-state 'flagged) + (set! bomb-count (sub1 bomb-count)) + (set-count bomb-count)) + (when (eq? old-state 'flagged) + (set! bomb-count (add1 bomb-count)) + (set-count bomb-count))))) + (do-select + (lambda (x y flag?) + (let* ([t (get-tile board x y)] + [state (send t get-state)] + [new-state + (case state + [(covered) + (if flag? 'flagged 'uncovered)] + [(flagged) + (if flag? 'semi-flagged state)] + [(semi-flagged) + (if flag? 'covered 'uncovered)] + [else state])] + [nc (send t get-neighbor-bomb-count)] + [new-uncover? (and (eq? new-state 'uncovered) + (not (eq? state 'uncovered)))] + [bomb? (is-bomb? t)]) + (change-state t state new-state #t) + (when (and new-uncover? bomb?) + (send t set-explode-source #t)) + (paint-one t x y) + (when new-uncover? + (if bomb? + (explode) + (begin + (when (zero? nc) + (autoclick-surrounding x y)))) + (when (and ready? (= cover-count BOMB-COUNT)) + (win)))))) + (on-event + (lambda (e) + (when ready? + (unless start-time + (when (send e button-down?) + (start-timer))) + (let* ([x (quotient (inexact->exact (floor (send e get-x))) TILE-HW)] + [y (quotient (inexact->exact (floor (send e get-y))) TILE-HW)] + [t (if (and (< -1 x WIDTH) + (< -1 y HEIGHT)) + (get-tile board x y) + #f)]) + (cond + [(and clicking (or (not (eq? t clicking)) + (not (or (send e button-up?) + (send e dragging?))))) + (let ([old clicking]) + (set! clicking #f) + (paint-one old clicking-x clicking-y))] + [(and t + (not (eq? (send t get-state) 'uncovered)) + (or (send e button-down?) + (and (send e dragging?) + (= x clicking-x) + (= y clicking-y)))) + (set! clicking t) + (set! clicking-x x) + (set! clicking-y y) + (paint-one t x y)] + [(send e button-down?) ; click not on a tile + (set! clicking-x -1)] + [(and clicking (send e button-up?)) + (set! clicking #f) + (do-select x y (send e button-up? 3))] + [else 'ok]))))) + (paint-one + (lambda (t x y) + (let ([xloc (* x TILE-HW)] + [yloc (* y TILE-HW)]) + (send t draw dc xloc yloc TILE-HW TILE-HW + (eq? t clicking))))) + (on-paint + (lambda () + (for-each-tile board (lambda (t x y) + (paint-one t x y)))))) + (sequence + (apply super-init args) + (set-min-width (* TILE-HW WIDTH)) + (set-min-height (* TILE-HW HEIGHT)) + (stretchable-in-x #f) + (stretchable-in-y #f)) + (private + [dc (get-dc)]) + (sequence + (reset) + (send dc set-text-background BG-COLOR) + (send dc set-brush (send wx:the-brush-list find-or-create-brush + BG-COLOR wx:const-solid))))) + +(define c (make-object ms:canvas% vpanel)) + +(send f show #t) diff --git a/collects/mrdemo/morph.mre b/collects/mrdemo/morph.mre new file mode 100644 index 0000000..6dc9fae Binary files /dev/null and b/collects/mrdemo/morph.mre differ diff --git a/collects/mrdemo/morph.ss b/collects/mrdemo/morph.ss new file mode 100644 index 0000000..6de97a5 --- /dev/null +++ b/collects/mrdemo/morph.ss @@ -0,0 +1 @@ +(load-relative (build-path "morph" "load.ss")) diff --git a/collects/mrdemo/morph/2darray.ss b/collects/mrdemo/morph/2darray.ss new file mode 100644 index 0000000..da8bc7c --- /dev/null +++ b/collects/mrdemo/morph/2darray.ss @@ -0,0 +1,57 @@ +(define 2d-vector% + (make-class () + (private + [default? #f] + [default (void)] + [vec (void)] + [found-error + (lambda (x w h) + (error '2d-vector% "~s out of bounds: ~s ~s; array size ~sx~s" + x w h width height))] + [index (lambda (w h) (+ (* h width) w))]) + (public + [height (void)] + [width (void)] + [set-default + (lambda (d) + (set! default? #t) + (set! default d))] + [no-default (lambda () (set! default? #f))] + [straighten (lambda () vec)] + [bend (lambda (list) + (when (not (list? list)) + (error '2d-vector% + "bend expected a list, found: ~s" list)) + (when (not (= (length list) (* height width))) + (error '2d-vector% + (string-append "attempted to bend a list of length ~s," + " should have length ~s") + (length list) (* height width))) + (set! vec (list->vector list)))] + [update (lambda (w h v) + (let ([w (floor w)] + [h (floor h)]) + (debug-print 2d-vector% 'width width 'height height w h + 'index (index w h)) + (if (and (<= 0 w) (< w width) (<= 0 h) (< h height)) + (vector-set! vec (index w h) v) + (found-error 'update w h))))] + [lookup (lambda (w h) + (let ([w (floor w)] + [h (floor h)]) + (debug-print 2d-vector% 'width width 'height height w h + 'index (index w h)) + (if (and (<= 0 w) (< w width) (<= 0 h) (< h height)) + (vector-ref vec (index w h)) + (if default? + default + (found-error 'lookup w h)))))]) + (lambda (w h v) + (if (and (integer? w) (integer? h)) + (begin + (set! width w) + (set! height h) + (set! vec (make-vector (* w h) v))) + (error '2d-vector% + "received w = ~s and h = ~s; both must should be integral" + w h))))) \ No newline at end of file diff --git a/collects/mrdemo/morph/coord.ss b/collects/mrdemo/morph/coord.ss new file mode 100644 index 0000000..1b33a3b --- /dev/null +++ b/collects/mrdemo/morph/coord.ss @@ -0,0 +1,96 @@ +;;; this file sets up coordinates + +;; bary represents just a three tuple of coordinates, not necessarily +;; with respect to some triangle. +(define-struct bary (a b c)) +(define show-bary + (let ([shorten (lambda (x) (/ (floor (* x 100)) 100))]) + (lambda (p) + (printf "#" + (shorten (bary-a p)) + (shorten (bary-b p)) + (shorten (bary-c p)))))) + +(define-struct posn (x y)) +(define show-posn + (let ([shorten (lambda (x) (/ (floor (* x 10)) 10))]) + (lambda (p) + (printf "#" + (shorten (posn-x p)) + (shorten (posn-y p)))))) + +(define-struct tri (a b c area)) +(define build-tri + (lambda (a b c) + (make-tri a b c (find-area a b c)))) + +(define posn-minus + (lambda (p q) + (make-posn (- (posn-x p) (posn-x q)) + (- (posn-y p) (posn-y q))))) + +(define bary-minus + (lambda (p1 p2) + (make-bary (- (bary-a p1) (bary-a p2)) + (- (bary-b p1) (bary-b p2)) + (- (bary-c p1) (bary-c p2))))) + +(define square (lambda (x) (* x x))) + +(define norm + (lambda (b) + (+ (square (bary-a b)) + (square (bary-b b)) + (square (bary-c a))))) + +(define find-area + (let ([helper + (lambda (p q) + (let ([sroot (- (* (posn-y p) (posn-x q)) + (* (posn-x p) (posn-y q)))]) + (/ (abs sroot) 2)))]) + (lambda (p1 p2 p3) + (helper (posn-minus p1 p2) (posn-minus p1 p3))))) + +(define find-barycentric + (lambda (p1 p2 p3 p) + (find-barycentric-area (build-tri p1 p2 p3) p))) + +(define find-barycentric-area + (lambda (tri p) + (let* ([p1 (tri-a tri)] + [p2 (tri-b tri)] + [p3 (tri-c tri)] + [area (tri-area tri)] + [little-area/big-area + (lambda (p q) + (let ([sroot (- (* (posn-y p) (posn-x q)) + (* (posn-x p) (posn-y q)))]) + (/ sroot area 2)))] + [p1-p (posn-minus p1 p)] + [p2-p (posn-minus p2 p)] + [p3-p (posn-minus p3 p)]) + (make-bary (little-area/big-area p2-p p3-p) + (little-area/big-area p3-p p1-p) + (little-area/big-area p1-p p2-p))))) + +(define find-euclid + (lambda (tri b) + (let ([p1 (tri-a tri)] + [p2 (tri-b tri)] + [p3 (tri-c tri)] + [a (bary-a b)] + [b (bary-b b)] + [c (bary-c b)]) + (make-posn (+ (* a (posn-x p1)) + (* b (posn-x p2)) + (* c (posn-x p3))) + (+ (* a (posn-y p1)) + (* b (posn-y p2)) + (* c (posn-y p3))))))) + +(define distance-sq + (lambda (p q) + (let ([x-delta (- (posn-x p) (posn-x q))] + [y-delta (- (posn-y p) (posn-y q))]) + (+ (* x-delta x-delta) (* y-delta y-delta))))) diff --git a/collects/mrdemo/morph/debug.ss b/collects/mrdemo/morph/debug.ss new file mode 100644 index 0000000..a092cfd --- /dev/null +++ b/collects/mrdemo/morph/debug.ss @@ -0,0 +1,57 @@ +(define debug-on? (lambda (type) #f)) + +(define debug-on? (lambda (type) #t)) + +(define debug-on? + (lambda (type) + (case type + [(2d-vector%) #f] + [(engine) #t] + [(graph) #f] + [(main) #t] + [(mesh%) #t] + [(pager%) #t] + [else #t]))) + +(defmacro debug-print (type . args) + (if (debug-on? type) + `(begin + (display (quote ,type)) + (display ": ") + (debug-print-function ,@args)) + '(void))) + +(define debug-print-function + (letrec ([debug-print-one + (lambda (x) + (cond + [(list? x) (debug-print-list x)] + [(pair? x) (display "(") + (debug-print-one (car x)) + (display " . ") + (debug-print-one (cdr x)) + (display ")")] + [(posn? x) (show-posn x)] + [(bary? x) (show-bary x)] +; [(3vector? x) (show-3vector x)] +; [(intersection? x) (show-intersection x)] + [else (display x)]))] + [debug-print-list-innards + (lambda (list) + (cond + [(null? list) (void)] + [(null? (cdr list)) (debug-print-one (car list))] + [else (debug-print-one (car list)) + (display " ") + (debug-print-list-innards (cdr list))]))] + [debug-print-list + (lambda (x) + (display "(") + (debug-print-list-innards x) + (display ")"))]) + (lambda args + (debug-print-list-innards args) + (newline) + (flush-output) + (void)))) + diff --git a/collects/mrdemo/morph/engine.ss b/collects/mrdemo/morph/engine.ss new file mode 100644 index 0000000..8cc5a7b --- /dev/null +++ b/collects/mrdemo/morph/engine.ss @@ -0,0 +1,154 @@ + +;; a mesh is a graph of the connectivities of the points. +(define-struct mesh (index children)) + +;; an image is a 2d array of color values, all of which are between +;; one and zero. + + +;; input: +;; src-verticies: the positions in the mesh where the +;; verticies are in the src image. +;; src-img: the source image +;; dest-verticies: the positions in the mesh where the +;; verticies are in the dest image. +;; src-img: the destination image +;; w: a constant between zero and one indicating how far the morph between +;; the images. +;; +;; It returns a function which computes the color value for the pixel +;; x and y, which should be a number between one and zero. + + + +(define engine-simple + (lambda (mesh src-lookup dest-lookup w) + (lambda (x y) + (let ([scale-pt (+ (* w (src-lookup x y)) + (* (- 1 w) (dest-lookup x y)))] + [x (- (/ (random 101) 400) 1/8)]) + (max 0 (min 1 (+ scale-pt x))))))) + +(define ormap-count 'uhoh) + +(define ormap-debug + (lambda (f list) + (letrec ([helper + (lambda (i l) + (cond + [(null? l) (set! ormap-count 'not-there) + #f] + [else (let ([w (f (car l))]) + (if w + (begin + (set! ormap-count (cons i w)) + w) + (helper (1+ i) (cdr l))))]))]) + (helper 1 list)))) + +(define engine + (lambda (mesh src-lookup dest-lookup w) + (let* ([tmp-triangles (build-triangles w mesh)] + [triangles (cons (car tmp-triangles) tmp-triangles)] + [1-w (- 1 w)]) + (lambda (x y) + (let* ([bc-tri (ormap (point-in-triangle? (make-posn x y)) triangles)]) + (if bc-tri + (let* ([bc (car bc-tri)] + [triangle-triple (cdr bc-tri)] + [to-p (find-euclid (triangles-to triangle-triple) bc)] + [to-x (posn-x to-p)] + [to-y (posn-y to-p)] + [from-p (find-euclid (triangles-from triangle-triple) bc)] + [from-x (posn-x from-p)] + [from-y (posn-y from-p)]) + (set-car! triangles triangle-triple) + (values (+ (* w from-x) (* 1-w to-x)) + (+ (* w from-y) (* 1-w to-y)) + (+ (* w (src-lookup from-x from-y)) + (* 1-w (dest-lookup to-x to-y))))) + (values x + y + (begin '(/ (+ (src-lookup x y) (dest-lookup x y)) 2) + 1)))))))) + +'(define engine engine-simple) + +(define get-points + (lambda (node) + (let ([value (graph:value node)]) + (values (car value) (cdr value))))) + +;; this returns either #f or a pair, the triangle and the barycentric +;; coordinates of (x,y) with respect to that triangle. +(define point-in-triangle? + (lambda (posn) + (lambda (triangle-triple) + (let* ([intermediate-triangle (triangles-intermediate triangle-triple)] + [bary (find-barycentric-area intermediate-triangle posn)]) + (if (and (<= 0 (bary-a bary)) + (<= 0 (bary-b bary)) + (<= 0 (bary-c bary))) + (cons bary triangle-triple) + #f))))) + +;; This maps over a list pairwise, e.g. +;; (for-each-pairwise (list 1 2 3) f) +;; = +;; (begin (f 1 2) (f 2 3) (f 3 1)) + +(define for-each-pairwise + (lambda (l f) + (cond + [(<= (length l) 1) (void)] + [(= 2 (length l)) (f (first l) (second l))] + [else (letrec ([first-ele (car l)] + [helper + (lambda (l) + (cond + [(null? (cdr l)) (begin '(f (first l) first-ele) + (void))] + [else (f (first l) (second l)) + (helper (cdr l))]))]) + (helper l))]))) + +(define-struct triangles (from intermediate to)) + +(define build-triangles + (lambda (w mesh) + (let* ([triangles null] + [1-w (- 1 w)] + [combine + (lambda (p q) + (make-posn (+ (* w (posn-x p)) (* 1-w (posn-x q))) + (+ (* w (posn-y p)) (* 1-w (posn-y q)))))]) + (graph:traverse + mesh + (lambda (node) + (let-values ([(left right) (get-points node)]) + (let ([children (graph:children node)]) + (when (= (length children) 3) + (let ([one (first children)] + [two (second children)] + [three (third children)]) + (let-values ([(left-one right-one) (get-points one)] + [(left-two right-two) (get-points two)] + [(left-three right-three) (get-points three)]) + (let* ([int (combine left right)] + [int-one (combine left-one right-one)] + [int-two (combine left-two right-two)] + [int-three (combine left-three right-three)] + [left-tri1 (build-tri left left-one left-two)] + [int-tri1 (build-tri int int-one int-two)] + [right-tri1 (build-tri right right-one right-two)] + [left-tri2 (build-tri left left-three left-one)] + [int-tri2 (build-tri int int-three int-one)] + [right-tri2 (build-tri right right-three right-one)]) + (set! triangles + (list* + (make-triangles left-tri1 int-tri1 right-tri1) + (make-triangles left-tri2 int-tri2 right-tri2) + triangles)))))))))) + (if (null? triangles) + (error 'build-triangles "empty mesh") + triangles)))) diff --git a/collects/mrdemo/morph/load.ss b/collects/mrdemo/morph/load.ss new file mode 100644 index 0000000..368ffe1 --- /dev/null +++ b/collects/mrdemo/morph/load.ss @@ -0,0 +1,15 @@ +(for-each (lambda (x) + (printf "loading ~s...~n" x) + (flush-output) + (load-relative x)) + '("setup.ss" + "debug.ss" + "2darray.ss" + "coord.ss" + "mesh.ss" + "utils.ss" + "ui.ss" + "pager.ss" + "engine.ss" + "main.ss")) +(printf "done loading~n") diff --git a/collects/mrdemo/morph/main.ss b/collects/mrdemo/morph/main.ss new file mode 100644 index 0000000..a6a9688 --- /dev/null +++ b/collects/mrdemo/morph/main.ss @@ -0,0 +1,76 @@ +(define main + (lambda (mesh src-mem-dc dest-mem-dc src-2dvec dest-2dvec total) + (letrec* ([width (max (ivar src-2dvec width) (ivar dest-2dvec width))] + [dummy-name-width width] + [height (max (ivar src-2dvec height) (ivar dest-2dvec height))] + + [src-lookup (ivar src-2dvec lookup)] + [dest-lookup (ivar dest-2dvec lookup)] + + [build-w + (lambda (w) + (debug-print main "building image percent" w) + (let* ([new-point (engine mesh + src-lookup + dest-lookup + w)] + [memory-dc (make-object wx:memory-dc%)] + [set-pixel (ivar memory-dc set-pixel)] + [bitmap (make-object wx:bitmap% width height)] + [scale (1- num-colors)]) + (send memory-dc select-object bitmap) + (send memory-dc begin-set-pixel) + (let loop ([x width] [y height]) + (let-values ([(draw-x draw-y color) (new-point x y)]) + (set-pixel draw-x draw-y + (vector-ref colors + (floor (* color + scale)))) + (cond + [(and (zero? y) (zero? x)) (void)] + [(zero? x) (begin (when (= 0 (modulo y 15)) + (debug-print main 'y y)) + (loop width (1- y)))] + [else (loop (1- x) y)]))) + (send memory-dc end-set-pixel) + memory-dc))] + + [memory-dcs1 + '(list->vector + (reverse + (cons dest-mem-dc + (let loop ([i 1]) + (if (= i (- total 1)) (list src-mem-dc) + (cons (build-w (/ i (1- total))) + (loop (1+ i))))))))] + + [memory-dcs2 + '(list->vector + (let loop ([i total]) + (if (zero? i) + (list (build-w (/ i (1- total)))) + (cons (build-w (/ i (1- total))) + (loop (1- i))))))] + + [sub-pager% + (make-class pager% + (public + [width dummy-name-width] + [picture-height height] + [memory-dcs + (list->vector + (reverse + (cons dest-mem-dc + (let loop ([i 1]) + (if (= i (- total 1)) (list src-mem-dc) + (cons (build-w (/ i (1- total))) + (loop (1+ i))))))))]) + (lambda () + (super-init)))]) + '(debug-print main memory-dcs) + (send src-2dvec set-default 1) + (send dest-2dvec set-default 1) + (mred:show-busy-cursor + (lambda () + (make-object sub-pager%)))))) + diff --git a/collects/mrdemo/morph/mesh.ss b/collects/mrdemo/morph/mesh.ss new file mode 100644 index 0000000..4285ef6 --- /dev/null +++ b/collects/mrdemo/morph/mesh.ss @@ -0,0 +1,138 @@ +;; graph:node takes a value to be stored on a node and creates a new node. +;; graph:edge takes two edges and joins them +;; graph:value takes a node and returns it's value + +(define-values (graph:node + graph:edge + graph:value + graph:children + graph:parents + graph:connections + graph:traverse + graph:fprintf + graph:read + graph:id + find-closest) + (local + [(define counter 0) + + (define-struct node (value children parents visited? id)) + + (define graph:id node-id) + + (define graph:node + (lambda (value) + (make-node value null null #f + (begin0 counter + (set! counter (add1 counter)))))) + ; from n1 to n2. n1 is n2's parent + (define graph:edge + (lambda (n1 n2) + (set-node-children! n1 (cons n2 (node-children n1))) + (set-node-parents! n2 (cons n1 (node-parents n2))))) + (define graph:value node-value) + (define graph:children node-children) + (define graph:parents node-parents) + (define graph:connections (lambda (x) + (append (graph:parents x) + (graph:children x)))) + (define graph:traverse + (lambda (node f) + (unless (node? node) + (error 'graph:traverse "expected a node, found ~s" node)) + (letrec ([to-reset null] + [helper + (lambda (node) + (when (not (node-visited? node)) + (f node) + (set! to-reset (cons node to-reset)) + (set-node-visited?! node #t) + (for-each helper (node-children node))))]) + (helper node) + (for-each (lambda (node) + (set-node-visited?! node #f)) + to-reset)))) + + (define graph:fprintf + (lambda (port node fprintf-node-value) + (unless (node? node) + (error 'graph:fprintf "expected a node, found ~s" node)) + (let ([min (node-id node)] [max (node-id node)]) + (graph:traverse + node (lambda (x) + (when (< max (node-id x)) + (set! max (node-id x))) + (when (< (node-id x) min) + (set! min (node-id x))))) + (fprintf port "~s ; min~n~s ; max~n; nodes~n" min max)) + (graph:traverse + node + (lambda (node) + (fprintf port "~s ~s ~s " (node-id node) + (map node-id (node-children node)) + (map node-id (node-parents node))) + (fprintf-node-value port (node-value node)) + (fprintf port "~n"))) + (fprintf port "~s~n" 'double-check) + (fprintf port "~s~n" (node-id node)))) + + (define graph:read + (opt-lambda (read-value [port (current-input-port)]) + (let* ([min (read port)] + [max (read port)] + [v (tabulate (add1 (- max min)) (lambda (x) + (graph:node x)))]) + (let loop ([i (- max min)]) + (when (<= 0 i) + (let* ([index (- (read port) min)] + [node (vector-ref v index)] + [chili (lambda (i) (vector-ref v (- i min)))] + [children (read port)] + [parents (read port)]) + (set-node-children! node (map chili children)) + (set-node-parents! node (map chili parents)) + (set-node-value! node (read-value port)) + (debug-print graph (+ index min) 'children children + 'parents parents + 'node node)) + (loop (sub1 i)))) + (when (not (eq? 'double-check (read port))) + (error 'graph:read "input corrupted")) + (let ([node-count (read port)]) + (debug-print graph 'important-node node-count + 'min min + (vector-ref v (- node-count min))) + (vector-ref v (- node-count min)))))) + + (define find-closest + (lambda (node x y node-value-get) + (let* ([mouse-posn (make-posn x y)] + [closest node] + [value (graph:value node)] + [posn (node-value-get value)] + [current-dist-sq (distance-sq mouse-posn posn)]) + (graph:traverse node + (lambda (node) + (let* ([value (graph:value node)] + [this-posn (node-value-get value)] + [this-dist-sq + (distance-sq mouse-posn this-posn)]) + (when (< this-dist-sq current-dist-sq) + (set! posn this-posn) + (set! current-dist-sq this-dist-sq) + (set! closest node))))) + closest)))] + + + + (values graph:node + graph:edge + graph:value + graph:children + graph:parents + graph:connections + graph:traverse + graph:fprintf + graph:read + graph:id + find-closest))) \ No newline at end of file diff --git a/collects/mrdemo/morph/pager.ss b/collects/mrdemo/morph/pager.ss new file mode 100644 index 0000000..3251990 --- /dev/null +++ b/collects/mrdemo/morph/pager.ss @@ -0,0 +1,120 @@ +(define pager% + (make-class () + (public + [x-pos 650] + [y-pos 60] + [width 300] + [picture-height 300] + [slider-height 50] + [button-width 30] + [slider-width (- width button-width)] + [memory-dcs (vector)] + [save-images + (lambda (fn) + (let loop ([i (1- (vector-length memory-dcs))]) + (when (<= 0 i) + (let* ([this-name (string-append + fn (number->string (1+ i)) ".pgm")] + [port (open-output-file this-name 'replace)] + [memory-dc (vector-ref memory-dcs i)] + [get-pixel (ivar memory-dc get-pixel)] + [color (make-object wx:colour% "white")] + [get-colors (ivar color get)] + [bgreen (box 0)] + [bred (box 0)] + [bblue (box 0)]) + (debug-print pager% 'writing 'image this-name) + (fprintf port + "P2~n# Robby's Morpher via MrEd~n~s ~s~n255~n" + width picture-height) + (let loop ([x 0] [y 0]) + (if (get-pixel x y color) + (get-colors bred bgreen bblue) + (set-box! bgreen 255)) + (fprintf port "~s" (unbox bgreen)) + (fprintf port (if (= x width) "~n" " ")) + (cond [(and (= x (1- width)) (= y (1- picture-height))) (void)] + [(= x (1- width)) (loop 0 (1+ y))] + [else (loop (1+ x) y)])) + (debug-print pager% 'wrote this-name) + (close-output-port port)) + (loop (1- i)))))] + [frame% + (make-class mred:menu-frame% + (rename [super-make-menu-bar make-menu-bar]) + (inherit make-menu show) + (public + [make-menu-bar + (lambda () + (let ([bar (super-make-menu-bar)] + [file-menu (make-menu)]) + (send file-menu append-item "Save" + (lambda () + (let ([fn (mred:common-put-file '() + "Please Specify a prefix for the images.")]) + (debug-print pager% 'fn fn) + (when fn + (debug-print pager% 'fn fn) + (save-images fn))))) + (send file-menu append-item "Close" (lambda () (show #f))) + (send bar append file-menu "File") + bar))]))] + [frame (make-object frame% '() "Morph")] + [panel (ivar frame panel)] + [canvas% + (make-class mred:canvas% + (inherit clear set-background) + (public + [w-brush (make-object wx:brush% "white" wx:const-solid)] + [on-paint + (lambda () + '(send dc destroy-clipping-region) + '(send dc set-clipping-region 0 0 (1+ width) (1+ picture-height)) + (set-background w-brush) + (clear) + (when slider + (send dc blit 0 0 width picture-height + (vector-ref memory-dcs (send slider get-value)) + 0 0 wx:const-copy)))]))] + [canvas (make-object canvas% panel)] + [s-panel (make-object mred:horizontal-panel% panel)] + [slider + (let ([show-arg + (lambda (s e) + (send canvas on-paint))]) + (if (> (vector-length memory-dcs) 1) + (make-object mred:slider% s-panel show-arg "" + 0 0 (sub1 (vector-length memory-dcs)) slider-width) + #f))] + [button-click + (lambda args + (mred:show-busy-cursor + (lambda () + (let ([old-slider-pos (send slider get-value)]) + (let loop ([img 0]) + (when (< img (vector-length memory-dcs)) + (send slider set-value img) + (send canvas on-paint) + (wx:flush-display) + (sleep 0.5) + (loop (1+ img)))) + '(send slider set-value old-slider-pos) + (send canvas on-paint)))))] + [button + (when (> (vector-length memory-dcs) 1) + (make-object mred:button% s-panel button-click "Play"))] + [dc (send canvas get-dc)] + [shutdown (lambda () (send frame show #f))]) + (lambda () + (send panel stretchable-in-y #f) + (let ([w (box 0)] + [h (box 0)]) + (send canvas get-client-size w h) + (let ([diff (- (send canvas get-width) (unbox w))]) + (send canvas user-min-width (+ diff width)) + (send canvas user-min-height (+ diff picture-height)))) + (send canvas stretchable-in-x #f) + (send canvas stretchable-in-y #f) + (send frame show #t) + (send canvas on-paint)))) + diff --git a/collects/mrdemo/morph/setup.ss b/collects/mrdemo/morph/setup.ss new file mode 100644 index 0000000..cf6ad68 --- /dev/null +++ b/collects/mrdemo/morph/setup.ss @@ -0,0 +1,46 @@ +(print-struct #t) +(print-graph #t) +(define last + (lambda (x) + (cond + [(null? x) (error 'last "empty list")] + [(null? (cdr x)) (car x)] + [else (last (cdr x))]))) + +(define foldl2 + (lambda (f init l) + (letrec ([helper + (lambda (l sofar) + (cond + [(null? l) sofar] + [else (helper (cdr l) (f (car l) sofar))]))]) + (helper l init)))) + +(define tabulate + (lambda (n f) + (letrec ([build (lambda (i) + (cond + [(= i n) null] + [else (cons (f i) (build (1+ i)))]))]) + (list->vector (build 0))))) + +(define vector-for-each + (lambda (f v) + (let ([size (vector-length v)]) + (let loop ([n 0]) + (when (< n size) + (f i (vector-ref v i)) + (loop)))))) + +'(define remove + (lambda (list f) + (letrec ([helper + (lambda (l) + (cond [(null? l) null] + [(f (car l)) (helper (cdr l))] + [else (cons (car l) (helper (cdr l)))]))]) + (helper list)))) + +(define-macro package + (lambda (x . args) + (car 'package))) diff --git a/collects/mrdemo/morph/ui.ss b/collects/mrdemo/morph/ui.ss new file mode 100644 index 0000000..729a5ef --- /dev/null +++ b/collects/mrdemo/morph/ui.ss @@ -0,0 +1,407 @@ +(define num-colors 200) +(define mesh-color (make-object wx:colour% 50 155 50)) +(define mesh-pen (make-object wx:pen% mesh-color 1 wx:const-solid)) + +(define black-pen (make-object wx:pen% "BLACK" 1 wx:const-solid)) + +(define colors + (tabulate num-colors + (lambda (i) + (make-object wx:colour% + (* 255 (expt (/ i (1- num-colors)) 1/2)) + (* 255 (/ i (1- num-colors))) + (* 255 (expt (/ i (1- num-colors)) 1/2)))))) + +(define mesh% + (make-class mred:menu-frame% + (rename [super-make-menu-bar make-menu-bar] +; [super-on-paint on-paint] + ) + (inherit make-menu show panel) + (public + [mesh #f] + + [filename #f] + [margin 10] + + [on-paint + (lambda () + (send left-canvas on-paint) + (send right-canvas on-paint))] + + [canvas% + (make-class mred:canvas% + (inherit set-background get-dc clear get-client-size) + (rename [super-on-event on-event]) + (private + [w-brush (make-object wx:brush% "white" wx:const-solid)]) + (public + [node-value-get (void)] + [node-value-update (void)] + [memory-dc (make-object wx:memory-dc%)] + [set-memory-dc! (lambda (mdc) (set! memory-dc mdc))] + [draw-line (void)] + [dc (void)] + [on-event + (let* ([dragging-node (void)] + [connections null] + [orig-x (void)] + [orig-y (void)] + [last-x -1] + [last-y -1] + [lines (lambda () + (for-each + (lambda (x) + (let ([p (node-value-get (graph:value x))]) + (draw-line (posn-x p) (posn-y p) + last-x last-y))) + connections))]) + (lambda (event) + (cond + [(send event dragging?) + (let ([x (send event get-x)] + [y (send event get-y)]) + (when (and (not (and (= x last-x) + (= x last-y))) + '(inside-triangles dragging-node x y)) + (lines) + (set! last-x x) + (set! last-y y) + (lines)))] + [(send event button-down?) + (let ([x (send event get-x)] + [y (send event get-y)]) + (send dc set-logical-function wx:const-xor) + (when mesh + (set! dragging-node (find-closest mesh x y node-value-get)) + (set! connections (graph:connections dragging-node))) + (set! last-x x) + (set! last-y y) + (set! orig-x x) + (set! orig-y y) + (lines))] + [(send event button-up?) + (lines) + (send dc set-logical-function wx:const-copy) + (unless (void? dragging-node) + (node-value-update (graph:value dragging-node) + (make-posn last-x last-y))) + (let* ([posns (cons (make-posn last-x last-y) + (map (lambda (x) + (node-value-get (graph:value x))) + connections))] + [box-width (box 0)] + [box-height (box 0)] + [min-x orig-x] + [min-y orig-y] + [max-x orig-x] + [max-y orig-y]) + (for-each (lambda (p) + (let ([x (posn-x p)] + [y (posn-y p)]) + (when (< max-x x) (set! max-x x)) + (when (< max-y y) (set! max-y y)) + (when (< x min-x) (set! min-x x)) + (when (< y min-y) (set! min-y y)))) + posns) + '(send dc set-clipping-region min-x min-y + (1+ (- max-x min-x)) + (1+ (- max-y min-y))) + (on-paint) + (get-client-size box-width box-height) + (send dc set-clipping-region + 0 0 (unbox box-width) (unbox box-height))) + (set! dragging-node (void)) + (set! connections (void)) + (set! orig-x (void)) + (set! orig-y (void)) + (set! last-x (void)) + (set! last-y (void))] + [else (super-on-event event)])))] + [on-paint + (lambda () + (let* ([get-points + (lambda (node) + (let* ([value (graph:value node)] + [p (node-value-get value)]) + (values (posn-x p)(posn-y p))))] + [traverse + (lambda (node) + (let-values ([(b-x b-y) (get-points node)]) + (let* ([children (graph:children node)] + [chili + (lambda (child) + (let-values ([(e-x e-y) (get-points child)]) + (draw-line b-x b-y e-x e-y)))]) + (for-each chili children))))] + [dc (get-dc)] + [by (box 0)] + [bx (box 0)]) + (get-client-size bx by) + (set-background w-brush) + (clear) + (send dc set-pen black-pen) + (send dc blit 0 0 (unbox bx) (unbox by) + memory-dc 0 0 wx:const-copy) + (when mesh + (send dc set-pen mesh-pen) + '(send dc set-logical-function wx:const-xor) + (graph:traverse mesh traverse) + '(send dc set-logical-function wx:const-copy))))]) + (lambda (get update . args) + (apply super-init args) + (set! dc (get-dc)) + (set! draw-line (ivar dc draw-line)) + (set! node-value-get get) + (set! node-value-update update)))] + + [left-filename #f] + [right-filename #f] + [left-2dvec #f] + [right-2dvec #f] + [left-canvas #f] + [right-canvas #f] + [default-size 200] + + [canvas-size-diff 0] + + [get-sizes + (lambda () + (let* ([left-width (if left-2dvec + (ivar left-2dvec width) + default-size)] + [left-height (if left-2dvec + (ivar left-2dvec height) + default-size)] + [right-width (if right-2dvec + (ivar right-2dvec width) + default-size)] + [right-height (if right-2dvec + (ivar right-2dvec height) + default-size)]) + (values left-width left-height right-width right-height)))] + [resize-panels + (lambda () + (let-values ([(left-width left-height right-width right-height) + (get-sizes)]) + (send left-canvas user-min-width (+ canvas-size-diff left-width)) + (send left-canvas user-min-height (+ canvas-size-diff left-height)) + (send right-canvas user-min-width (+ canvas-size-diff right-width)) + (send right-canvas user-min-height (+ canvas-size-diff right-height))))] + [open + (lambda (fn) + (mred:show-busy-cursor + (lambda () + (let* ([port (open-input-file fn)] + [local-mesh #f] + [read-value + (lambda (port) + (let ([left (read port)] + [right (read port)]) + (cons (apply make-posn left) + (apply make-posn right))))]) + (set! left-filename (read port)) + (set! right-filename (read port)) + (when (read port) + (set! local-mesh (graph:read read-value port))) + (close-input-port port) + (debug-print mesh% 'read 'file) + (set! left-2dvec (build-image left-filename)) + (set! right-2dvec (build-image right-filename)) + (debug-print mesh% 'built-2dvecs) + (send left-canvas set-memory-dc! (build-memory-dc left-2dvec)) + (send right-canvas set-memory-dc! (build-memory-dc right-2dvec)) + (debug-print mesh% 'updated 'canvases) + (set! mesh local-mesh) + (set! filename fn) + (resize-panels) + (on-paint)))))] + [save + (lambda () + (if filename + (begin + (let ([port (open-output-file filename 'replace)] + [print-value + (lambda (port v) + (let ([left (car v)] + [right (cdr v)]) + (fprintf port "~s ~s" + (list (posn-x left) (posn-y left)) + (list (posn-x right) (posn-y right)))))]) + (fprintf port ";;; data req'd to setup a morph~n~n") + (fprintf port "~s ; source filename~n" left-filename) + (fprintf port "~s ; destination filename~n" right-filename) + (fprintf port "~n;; mesh~n") + (if mesh + (begin + (fprintf port "#t ; mesh is setup~n") + (graph:fprintf port mesh print-value)) + (fprintf port "#f ; mesh is not setup~n")) + (close-output-port port))) + (save-as)))] + [save-as + (lambda () + (let ([fn (mred:common-put-file)]) + (when fn + (set! filename fn) + (save))))] + + [make-menu-bar + (lambda () + (let ([bar (super-make-menu-bar)] + [file-menu (make-menu)] + [picture-menu (make-menu)] + [mesh-menu (make-menu)] + [morph-menu (make-menu)]) + (send file-menu append-item "Open..." + (lambda () + (let ([fn (mred:common-get-file)]) + (when fn (open fn))))) + (send file-menu append-item "Save..." save) + (send file-menu append-item "Save As..." save-as) + (send file-menu append-separator) + (send file-menu append-item "Close" (lambda () (show #f))) + (send picture-menu append-item "Select Source Image..." + (lambda () + (let ([fn (mred:common-get-file + '() "Please choose an image.")]) + (when fn + (mred:show-busy-cursor + (lambda () + (set! left-filename fn) + (time (set! left-2dvec (build-image fn))) + (time (send left-canvas set-memory-dc! + (build-memory-dc left-2dvec))) + (set! mesh #f) + (resize-panels) + (on-paint))))))) + (send picture-menu append-item "Select Destination Image..." + (lambda () + (let ([fn (mred:common-get-file + '() "Please choose an image.")]) + (when fn + (mred:show-busy-cursor + (lambda () + (set! right-filename fn) + (set! right-2dvec (build-image fn)) + (send right-canvas set-memory-dc! + (build-memory-dc right-2dvec)) + (set! mesh #f) + (resize-panels) + (on-paint))))))) + (send picture-menu append-item "Exchange Images" + (lambda () + (let ([left-mdc (ivar left-canvas memory-dc)] + [right-mdc (ivar right-canvas memory-dc)] + [tmp left-2dvec] + [exchange + (lambda (node) + (let* ([value (graph:value node)] + [left (car value)]) + (set-car! value (cdr value)) + (set-cdr! value left)))]) + (set! left-2dvec right-2dvec) + (set! right-2dvec tmp) + (send right-canvas set-memory-dc! left-mdc) + (send left-canvas set-memory-dc! right-mdc) + (graph:traverse mesh exchange) + (resize-panels) + (on-paint)))) + (send mesh-menu append-item "Fresh Mesh..." + (lambda () + (fresh-mesh (get-number-from-user + "How large should the mesh be?" + "Mesh Size" "5")) + (on-paint))) + (send morph-menu append-item "Morph..." + (lambda () (morph (get-number-from-user + "How many steps in the morph?" + "Morph Size" "3")))) + (send bar append file-menu "File") + (send bar append picture-menu "Images") + (send bar append mesh-menu "Mesh") + (send bar append morph-menu "Morph") + bar))] + [morph + (lambda (steps) + (if (and left-2dvec right-2dvec mesh) + (main mesh (ivar left-canvas memory-dc) + (ivar right-canvas memory-dc) + left-2dvec right-2dvec steps) + (wx:message-box "Please choose images and mesh.")))] + [fresh-mesh + (lambda (n) + (let-values ([(left-width left-height right-width right-height) + (get-sizes)]) + (let* ([nodes + (let loop ([row (1- n)] [column (1- n)]) + (let ([row-percent (/ row (1- n))] + [column-percent (/ column (1- n))]) + (cons + (graph:node + (cons (make-posn (* left-width row-percent) + (* left-height column-percent)) + (make-posn (* right-width row-percent) + (* right-height column-percent)))) + (cond + [(and (= row 0) (= column 0)) null] + [(= row 0) (loop (1- n) (1- column))] + [else (loop (1- row) column)]))))] + [2dvec (make-object 2d-vector% n n 0)] + [lookup (ivar 2dvec lookup)] + [update (ivar 2dvec update)]) + (send 2dvec bend (reverse nodes)) + + (if (< 2 n) + (begin + '(graph:edge (lookup 0 (1- n)) (lookup 1 (1- n))) + (let loop ([x (- n 2)] [y (- n 2)]) + (graph:edge (lookup x y) (lookup x (1+ y))) + (graph:edge (lookup x y) (lookup (1+ x) y)) + (graph:edge (lookup x y) (lookup (1+ x) (1+ y))) + (cond [(and (= x 0) (= y 0)) (void)] + [(= x 0) (loop (- n 2) (1- y))] + [else (loop (1- x) y)])) + (let loop ([i (- n 2)]) + (when (<= 0 i) + (graph:edge (lookup (1- n) i) (lookup (1- n) (1+ i))) + (graph:edge (lookup i (1- n)) (lookup (1+ i) (1- n))) + (loop (1- i))))) + (begin + (graph:edge (lookup 0 0) (lookup 0 1)) + (graph:edge (lookup 0 0) (lookup 1 0)) + (graph:edge (lookup 0 0) (lookup 1 1)) + (graph:edge (lookup 1 0) (lookup 1 1)) + (graph:edge (lookup 0 1) (lookup 1 1)))) + + (set! mesh (lookup 0 0)))))]) + + (lambda () + (super-init '() "Mesh Construction") + (send panel stretchable-in-x #f) + (send panel stretchable-in-y #f) + (let ([p (make-object mred:horizontal-panel% panel)] + [init + (lambda (c) + (send c user-min-height default-size) + (send c user-min-width default-size) + (send c stretchable-in-x #f) + (send c stretchable-in-y #f))]) + (send p stretchable-in-x #f) + (send p stretchable-in-y #f) + (set! left-canvas (make-object canvas% car set-car! p)) + (init left-canvas) + (set! right-canvas (make-object canvas% cdr set-cdr! p)) + (init right-canvas)) + (let ([w (box 0)] + [h (box 0)]) + (send right-canvas get-client-size w h) + (set! canvas-size-diff (- (send right-canvas get-width) (unbox w)))) + (show #t)))) + +(define mesh + (begin (when (defined? 'mesh) + (send mesh show #f)) + (make-object mesh%))) +'(send mesh open "/home/robby/class/graphics/lab5/test/rd.morph") +'(send mesh morph 3) diff --git a/collects/mrdemo/morph/utils.ss b/collects/mrdemo/morph/utils.ss new file mode 100644 index 0000000..f2ce7c9 --- /dev/null +++ b/collects/mrdemo/morph/utils.ss @@ -0,0 +1,114 @@ +(define build-pgm-image + (lambda (filename) + (let* ([comment #\#] + [coords + (call-with-input-file + filename + (lambda (p) + (let ([tmp null]) + (let loop ([line (read-line p)]) + (unless (eof-object? line) + (unless (char=? comment (string-ref line 0)) + (let ([sp (open-input-string line)]) + (let loop ([object (read sp)]) + (unless (eof-object? object) + (set! tmp (cons object tmp)) + (loop (read sp)))))) + (loop (read-line p)))) + (reverse tmp))))]) + (when (< (length coords) 4) + (error 'build-image "found less than four numbers in file: ~s" + filename)) + (let* ([tag (first coords)] + [width (second coords)] + [height (third coords)] + [top-value (exact->inexact (fourth coords))] + [data (list-tail coords 4)] + [2dvec (make-object 2d-vector% width height top-value)] + [normalized-data + (map (lambda (x) (/ x top-value)) + data)]) + (when (not (= (* width height) (length data))) + (error 'build-image + "data sizes incorrect in file ~s, found ~s expected ~s" + filename (length data) (* width height))) + (send 2dvec bend normalized-data) + 2dvec)))) + +(define build-image + (lambda (filename) + (let ([error + (lambda () + (error 'build-image "The file \"~a\" could not be loaded." + filename) + #f)]) + (if (regexp-match "\\.gif" filename) + (let ([b (make-object wx:bitmap% filename wx:const-bitmap-type-gif)]) + (if (send b ok?) + (let ([m (make-object wx:memory-dc%)]) + (send m select-object b) + (if (send m ok?) + (let* ([w (send b get-width)] + [h (send b get-height)] + [2dvec (make-object 2d-vector% w h 255)] + [update (ivar 2dvec update)] + [c (make-object wx:colour%)] + [r (ivar c red)] + [g (ivar c green)] + [b (ivar c blue)]) + (let iloop ([i (sub1 w)]) + (let jloop ([j (sub1 h)]) + (send m get-pixel i j c) + (let ([r (exact->inexact (r))] + [g (exact->inexact (g))] + [b (exact->inexact (b))]) + (update i j (/ (sqrt (/ (+ (* r r) (* g g) (* b b)) 3)) 255))) + (unless (zero? j) + (jloop (sub1 j)))) + (unless (zero? i) + (iloop (sub1 i)))) + 2dvec) + (error))) + (error))) + (build-pgm-image filename))))) + +(define build-memory-dc + (lambda (2dvec) + (let* ([memory-dc (make-object wx:memory-dc%)] + [set-pixel (ivar memory-dc set-pixel)] + [lookup (ivar 2dvec lookup)] + [width (ivar 2dvec width)] + [height (ivar 2dvec height)] + [bitmap (make-object wx:bitmap% width height)] + [scale (1- num-colors)]) + (send memory-dc select-object bitmap) + (send memory-dc begin-set-pixel) + (let loop ([x (1- width)] [y (1- height)]) + (let* ([l (lookup x y)]) + (set-pixel x y (vector-ref colors (floor (* scale l))))) + (cond + [(and (zero? y) (zero? x)) (void)] + [(zero? x) (loop (1- width) (1- y))] + [else (loop (1- x) y)])) + (send memory-dc end-set-pixel) + memory-dc))) + +(define get-number-from-user + (lambda (message title default) + (let* ([input (wx:get-text-from-user message title default)] + [read-in + (read-string + input + (lambda (debug string . rest) + (wx:message-box + (string-append + string + (apply + string-append + (map expr->string rest)))) + (apply reg-error debug string rest)))]) + (if (and (number? read-in) + (positive? read-in) + (integer? read-in)) + read-in + (wx:message-box "Expected a positive integer"))))) diff --git a/collects/mrdemo/ncad.mre b/collects/mrdemo/ncad.mre new file mode 100644 index 0000000..bc95574 Binary files /dev/null and b/collects/mrdemo/ncad.mre differ diff --git a/collects/mrdemo/ncad02x.ss b/collects/mrdemo/ncad02x.ss new file mode 100644 index 0000000..823f83a --- /dev/null +++ b/collects/mrdemo/ncad02x.ss @@ -0,0 +1,1395 @@ +;; ncad02c.scm - Scheme code for NanoCAD version 0.2 +;; Copyright (C) 1996 Will Ware +;; Modified by Matthew Flatt for MrEd 43 +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License +;; as published by the Free Software Foundation; either version 2 +;; of the License, or (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, write to the Free Software +;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +;; +;; I can be reached via email at . + +;; ****************************************************************** +;; DATA STRUCTURES + +;; An atom (in the chemistry sense) is list with an integer (an index +;; into the "Periodic" table, followed by a 3-vector of position +;; information in angstroms. + +;; The force list is just a list of force vectors, one for each +;; atom. Forces are in tens of nanojoules (attojoules per +;; angstrom). When I get around to implementing a velocity list, it +;; will also just be a list of vectors, but I don't know what I'll +;; use for units. + +;; A bond is a three-integer list. The first integer is the order of the +;; bond (1, 2, or 3), and the second and third integers are indices into +;; the atom list. + +;; A "Periodic" table entry is a list with five elements: an atom for the +;; name of the element, three double-precision-reals for evdw, rvdw, and +;; atomic mass, and an integer for the Official MM2 Type (to stay +;; compliant with tables in 'Nanosystems'). + +;; An MM2 term is a list starting with an atom (LENGTH, ANGLE, TORSION, or +;; VDW) followed by some integers, which are indices into the atom list. + +;; The atom list, bond list, "periodic" table, and term list are respectively +;; lists of all these things. + +(define ncad@ + (unit/sig () + (import mred:wx^ (mred : mred^)) + + (define ncad:stand-alone #f) + (define (error-msg txt) ()) ;; redefined in GUI + (define (entering fcn) ()) + + (define atom-list ()) + (define bond-list ()) + (define term-list ()) + (define force-list ()) + + ;; ****************************************************************** + ;; Empirical coefficients + + (define periodic-table + '(("C" 0.357 1.9 19.925 1) ;; sp3 + ("C" 0.357 1.94 19.925 2) ;; sp2 alkene + ("C" 0.357 1.94 19.925 3) ;; sp2 carbonyl + ("C" 0.357 1.94 19.925 4) ;; sp acetylene + ("H" 0.382 1.5 1.674 5) ;; hydrocarbon + ("O" 0.406 1.74 26.565 6) ;; C-O-[HC] + ("O" 0.536 1.74 26.565 7) ;; O carbonyl + ("N" 0.447 1.82 23.251 8) ;; sp3 + ("F" 0.634 1.65 31.545 11) ;; flouride + ("Cl" 1.95 2.03 38.064 12) ;; chloride + ("Br" 2.599 2.18 131.038 13) ;; bromide + ("I" 3.444 2.32 210.709 14) ;; iodide + ("S" 1.641 2.11 53.087 15) ;; sulfide + ("Si" 1.137 2.25 46.454 19) ;; silane + ("LP" 0.13 1.2 0.0 20) ;; lone pair + ("H" 0.292 1.2 1.674 21) ;; alcohol + ("C" 0.357 1.9 19.925 22) ;; cyclopropane + ("P" 1.641 2.11 51.464 25))) ;; phosphide + + (define (lookup-helper compare-func result-func default-result the-list) + (cond ((null? the-list) default-result) + ((compare-func (car the-list)) (result-func (car the-list))) + (else (lookup-helper compare-func result-func default-result + (cdr the-list))))) + + ;; A length-coefficient entry is two MM2 atom types, followed by a + ;; k_s value, followed by an r0 value. + + (define length-coefficients + '((1 5 460 1.113) + (1 1 440 1.523) + (2 2 960 1.337) + (4 4 1560 1.212) + (1 6 536 1.402) + (1 8 510 1.438) + (3 7 1080 1.208) + (1 11 510 1.392) + (1 12 323 1.795) + (1 13 230 1.949) + (1 14 220 2.149) + (8 20 610 0.6) + (8 8 560 1.381) + (6 20 460 0.6) + (6 21 460 0.942) + (6 6 781 1.470) + (1 19 297 1.880) + (1 25 291 1.856) + (1 15 321.3 1.815) + (19 19 185 2.332) + (22 22 440 1.501))) + + (define (lookup-length-coeffs m n) + (lookup-helper + (lambda (x) (or (and (= m (car x)) + (= n (cadr x))) + (and (= n (car x)) + (= m (cadr x))))) + (lambda (x) (cddr x)) + '(400 1.3) + length-coefficients)) + + ;; An angle-coefficient entry is three MM2 atoms types, followed by + ;; a k_th value, followed by a th0 value. + + (define angle-coefficients + '((1 1 1 0.45 1.911) + (1 1 5 0.36 1.909) + (5 1 5 0.32 1.909) + (1 1 11 0.65 1.911) + (11 1 11 1.07 1.869) + (1 2 1 0.45 2.046) + (2 1 2 0.45 1.911) + (1 2 2 0.55 2.119) + (2 2 5 0.36 2.094) + (2 2 2 0.43 2.094) + (1 4 4 0.2 3.142) + (1 3 7 0.46 2.138) + (1 6 1 0.77 1.864) + (1 8 1 0.63 1.88) + (1 1 6 0.57 1.911) + (1 6 20 0.35 1.835) + (1 8 20 0.5 1.906) + (20 6 20 0.24 2.286) + (19 19 19 0.35 1.943) + (19 1 19 0.4 2.016) + (1 19 1 0.48 1.934) + (12 1 12 1.08 1.95) + (1 1 15 0.55 1.902) + (1 15 1 0.72 1.902) + (4 4 5 0.4 3.142) + (7 3 1 0.4 3.142) + (7 3 2 0.4 3.142) + (7 3 3 0.4 3.142) + (5 8 5 1.1 1.85))) + + (define (lookup-angle-coeffs m n p) + (lookup-helper + (lambda (x) (or (and (= m (car x)) + (= n (cadr x)) + (= p (caddr x))) + (and (= p (car x)) + (= n (cadr x)) + (= m (caddr x))))) + (lambda (x) (cdddr x)) + '(0.4 2.094) + angle-coefficients)) + + ;; An torsion-coefficient entry is four MM2 atoms types, followed by + ;; three values for v1, v2, and v3 respectively. + + (define torsion-coefficients + '((1 1 1 1 1.39 1.88 0.65) + (1 1 1 5 0.0 0.0 1.85) + (5 1 1 5 0.0 0.0 1.65) + (1 1 1 11 0.0 -0.6 6.46) + (1 2 2 1 -0.69 69.47 0.0) + (2 2 2 2 -6.46 55.58 0.0) + (5 2 2 5 0.0 104.21 0.0))) + + (define (lookup-torsion-coeffs m n p q) + (lookup-helper + (lambda (x) (or (and (= m (car x)) + (= n (cadr x)) + (= p (caddr x)) + (= q (cadddr x))) + (and (= q (car x)) + (= p (cadr x)) + (= n (caddr x)) + (= m (cadddr x))))) + (lambda (x) (cddddr x)) + '(0.0 0.0 0.0) + torsion-coefficients)) + + ;; ****************************************************************** + ;; Geometric fun with vectors + + (define (vplus v1 v2) + (vector (+ (vector-ref v1 0) (vector-ref v2 0)) + (+ (vector-ref v1 1) (vector-ref v2 1)) + (+ (vector-ref v1 2) (vector-ref v2 2)))) + + (define (vdiff v1 v2) + (vector (- (vector-ref v1 0) (vector-ref v2 0)) + (- (vector-ref v1 1) (vector-ref v2 1)) + (- (vector-ref v1 2) (vector-ref v2 2)))) + + (define (dot-product v1 v2) + (+ (* (vector-ref v1 0) (vector-ref v2 0)) + (* (vector-ref v1 1) (vector-ref v2 1)) + (* (vector-ref v1 2) (vector-ref v2 2)))) + + (define (cross-product v1 v2) + (vector (- (* (vector-ref v1 1) (vector-ref v2 2)) + (* (vector-ref v1 2) (vector-ref v2 1))) + (- (* (vector-ref v1 2) (vector-ref v2 0)) + (* (vector-ref v1 0) (vector-ref v2 2))) + (- (* (vector-ref v1 0) (vector-ref v2 1)) + (* (vector-ref v1 1) (vector-ref v2 0))))) + + (define (vlen v) + (sqrt (dot-product v v))) + + (define (vscale v x) + (vector (* (vector-ref v 0) x) + (* (vector-ref v 1) x) + (* (vector-ref v 2) x))) + + ;; find the component of v1 perpendicular to v2 + (define (perpendicular-component v1 v2) + (vdiff v1 (vscale v2 (/ (dot-product v1 v2) (dot-product v2 v2))))) + + (define (safe-acos z) + (if (> z 1.0) (set! z 1.0)) + (if (< z -1.0) (set! z -1.0)) + (acos z)) + + (define (v-angle v1 v2) + (safe-acos (/ (dot-product v1 v2) (* (vlen v1) (vlen v2))))) + + (define (i-length v1 v2) + (vlen (vdiff v1 v2))) + + (define (i-angle v1 v2 v3) + (v-angle (vdiff v1 v2) (vdiff v3 v2))) + + (define (i-torsion v1 v2 v3 v4) + (let ((p (vdiff v1 v2)) + (q (vdiff v2 v3)) + (r (vdiff v4 v3))) + (v-angle (perpendicular-component p q) + (perpendicular-component r q)))) + + ;; ****************************************************************** + ;; Forces computed by energy terms + + (define (do-to-all-atoms f) + (define (helper f n lst) + (cond ((null? lst) ()) + (else (cons (apply f (list n (car lst))) + (helper f (+ n 1) (cdr lst)))))) + (set! atom-list + (helper f 0 atom-list))) + + (define (mm2-type a) + (cadddr (cdr (list-ref periodic-table a)))) + + (define (add-comp v n x) + (vector-set! v n (+ (vector-ref v n) x))) + + (define (sub-add-to-force L n vsrc) + (cond ((null? L) ()) + ((= n 0) + (let ((v (car L))) + (cons (vector (+ (vector-ref v 0) (vector-ref vsrc 0)) + (+ (vector-ref v 1) (vector-ref vsrc 1)) + (+ (vector-ref v 2) (vector-ref vsrc 2))) + (cdr L)))) + (else (cons (car L) + (sub-add-to-force (cdr L) (- n 1) vsrc))))) + + (define (add-to-force n v) + (set! force-list + (sub-add-to-force force-list n v))) + + (define (length-force m n) + (entering "length-force") + (let* ((ma (list-ref atom-list m)) ;; members of atom-list + (na (list-ref atom-list n)) + (coeffs + (lookup-length-coeffs + (mm2-type (car ma)) + (mm2-type (car na)))) + (ks (* 0.01 (car coeffs))) + (r0 (cadr coeffs)) + (rd (vdiff (cadr ma) (cadr na))) + (r (sqrt (dot-product rd rd))) + (du-dr (* ks (- r r0))) + (mult (/ (- du-dr) r))) + (add-to-force m (vscale rd mult)) + (add-to-force n (vscale rd (- mult))))) + + ;; OK, for angles it gets a bit trickier. Let the atom positions be vectors + ;; r1, r2, r3, with r2 the vertex. Define the following: + ;; L1 = -dotproduct(r1-r2,r3-r2) * (r1-r2) + dotproduct(r1-r2,r1-r2) * (r3-r2) + ;; L3 = -dotproduct(r1-r2,r3-r2) * (r3-r2) + dotproduct(r3-r2,r3-r2) * (r1-r2) + ;; m1 = L1/|L1|, m3 = L3/|L3| + ;; Potential energy is given by U = f(theta), force on atom 1 is + ;; f1 = -m1 * dU/dm1 = (-m1/|r1-r2|) * dU/dtheta + ;; Likewise f3 = (-m3/|r3-r2|) * dU/dtheta + ;; Conservation: f2 = -f1-f3 + + (define (angle-force m n p) + (entering "angle-force") + (let* ((ma (list-ref atom-list m)) ;; members of atom-list + (na (list-ref atom-list n)) + (pa (list-ref atom-list p)) + (coeffs + (lookup-angle-coeffs + (mm2-type (car ma)) + (mm2-type (car na)) + (mm2-type (car pa)))) + (kth (car coeffs)) + (th0 (cadr coeffs)) + (th (i-angle (cadr ma) (cadr na) (cadr pa))) + (tdif (- th th0)) + (du-dth (* kth (* tdif (+ 1 (* 1.508 tdif tdif))))) + (r1r2 (vdiff (cadr ma) (cadr na))) + (r3r2 (vdiff (cadr pa) (cadr na))) + (L1 (vdiff (vscale r3r2 (dot-product r1r2 r1r2)) + (vscale r1r2 (dot-product r1r2 r3r2)))) + (f1 (vscale L1 (/ du-dth (* (vlen L1) (vlen r1r2))))) + (L3 (vdiff (vscale r1r2 (dot-product r3r2 r3r2)) + (vscale r3r2 (dot-product r1r2 r3r2)))) + (f3 (vscale L3 (/ du-dth (* (vlen L3) (vlen r3r2))))) + (f2 (vscale (vplus f1 f3) -1.0))) + (add-to-force m f1) + (add-to-force n f2) + (add-to-force p f3))) + + ;; To think about torsions, think of the projection of the whole thing into + ;; the plane perpendicular to the torqued bond. + + ;; Actually, torsions appear to contribute a negligible amount of force + ;; compared even to van der Waals, but they require this atrociously complex + ;; calculation. I'm thinking about just not bothering to compute them at all. + ;; I think the math here is correct, just woefully inefficient. + + (define use-torsion-forces #f) + + (define (torsion-force m n p q) + (entering "torsion-force") + (if use-torsion-forces + (let* ((ma (list-ref atom-list m)) + (na (list-ref atom-list n)) + (pa (list-ref atom-list p)) + (qa (list-ref atom-list q)) + (coeffs + (lookup-torsion-coeffs + (mm2-type (car ma)) + (mm2-type (car na)) + (mm2-type (car pa)) + (mm2-type (car qa)))) + (v1 (car coeffs)) + (v2 (cadr coeffs)) + (v3 (caddr coeffs)) + (pv (vdiff (cadr ma) (cadr na))) + (qv (vdiff (cadr pa) (cadr na))) + (rv (vdiff (cadr qa) (cadr pa))) + (pp (dot-product pv pv)) + (qq (dot-product qv qv)) + (rr (dot-product rv rv)) + (pq (dot-product pv qv)) + (qr (dot-product qv rv)) + (alpha (sqrt (/ (* pq pq) qq))) + (beta (sqrt (* qq qq))) + (gamma (sqrt (/ (* qr qr) qq))) + (vm1 (cross-product qv pv)) + (vq1 (cross-product rv qv)) + (vm2 (vscale vm1 (/ 1.0 (* (vlen vm1))))) + (vq2 (vscale vq1 (/ 1.0 (* (vlen vq1))))) + (w (safe-acos (dot-product vm2 vq2))) + (du-dw (* -0.0005 (+ (* v1 (sin w)) + (* -2 v2 (sin (* 2 w))) + (* 3 v3 (sin (* 3 w)))))) + (fm (vscale vm2 (/ du-dw + (sqrt (- pp (/ (* pq pq) qq)))))) + (fq (vscale vq2 (/ du-dw + (sqrt (- rr (/ (* qr qr) qq))))))) + (add-to-force m fm) + (add-to-force q fq) + (add-to-force p + (vdiff (vscale fm (/ alpha beta)) + (vscale fq (/ (+ gamma beta) beta)))) + (add-to-force n + (vdiff (vscale fq (/ gamma beta)) + (vscale fm (/ (+ alpha beta) beta))))))) + + ;; vdw is similar to length force + ;; du/dr = 6*evdw*[(r/rvdw)^-7 - (r/rvdw)^-13] + ;; Don't forget the factor of 0.001 + + (define use-vdw-forces #t) + + (define (vdw-force m n) + (entering "vdw-force") + (if use-vdw-forces + (let* ((ma (list-ref atom-list m)) ;; members of atom-list + (na (list-ref atom-list n)) + (evdw (* 0.5 (+ (cadr (list-ref periodic-table (car ma))) + (cadr (list-ref periodic-table (car na)))))) + (rvdw (+ (caddr (list-ref periodic-table (car ma))) + (caddr (list-ref periodic-table (car na))))) + (rd (vdiff (cadr ma) (cadr na))) + (r (sqrt (dot-product rd rd))) + (rsq_recip (/ (* rvdw rvdw) (dot-product rd rd))) ;; (r/rvdw)^-2 + (r_recip (sqrt rsq_recip)) + (r6 (* rsq_recip rsq_recip rsq_recip)) ;; (r/rvdw)^-6 + (du-dr (* 0.006 evdw r_recip r6 (- 1 (* 2 r6)))) + (mult (/ (- du-dr) r))) + (add-to-force m (vscale rd mult)) + (add-to-force n (vscale rd (- mult)))))) + + (define need-to-resetup-terms #t) + + (define (compute-forces) + (entering "compute-forces") + (if need-to-resetup-terms + (let () + (setup-terms) + (set! need-to-resetup-terms #f))) + ;; first set all forces to zero, one force vector for each atom + (set! force-list + (map (lambda (atm) + (vector 0.0 0.0 0.0)) + atom-list)) + ;; next figure out contributions for each energy term + (do ((L term-list (cdr L))) + ((null? L) ()) + (case (caar L) + ((length) (apply length-force (cdar L))) + ((angle) (apply angle-force (cdar L))) + ((torsion) (apply torsion-force (cdar L))) + ((vdw) (apply vdw-force (cdar L)))))) + + ;; ****************************************************************** + ;; Building up a term list from an atom list and bond list + + (define (other-end bond atm) + (cond ((= atm (cadr bond)) (caddr bond)) + ((= atm (caddr bond)) (cadr bond)) + (else #f))) + + (define whine-about-bond-count #f) + + (define (count-bonds n expected) + (do ((dbonds 0) + (tbonds 0) + (sbonds 0) + (bond ()) + (L bond-list (cdr L))) + ((null? L) (let ((nb (+ sbonds (* 2 dbonds) (* 3 tbonds)))) + (if (not (= expected nb)) + (set! whine-about-bond-count #t)) + (list sbonds dbonds tbonds))) + (set! bond (car L)) + (if (or (= n (cadr bond)) (= n (caddr bond))) + (case (car bond) + ((1) (set! sbonds (+ sbonds 1))) + ((2) (set! dbonds (+ dbonds 1))) + (else (set! tbonds (+ tbonds 1))))))) + + (define (setup-terms) + ;; for each atom, figure out what element it's supposed to be, + ;; count its bonds, verify against valence, and reassign its + ;; periodic table index according to hybridization + (do-to-all-atoms + (lambda (n atm) + (let ((b ())) + (case (car atm) + ;; carbon + ((0 1 2 3) (set! b (count-bonds n 4)) + (if (= (caddr b) 1) + (cons 3 (cdr atm)) + (if (= (cadr b) 2) + (cons 2 (cdr atm)) + (if (= (cadr b) 1) + (cons 1 (cdr atm)) + (cons 0 (cdr atm)))))) + ;; hydrogen + ((4) (set! b (count-bonds n 1)) + atm) + ;; oxygen + ((5 6) (set! b (count-bonds n 2)) + (if (= (cadr b) 1) + (cons 6 (cdr atm)) + (cons 5 (cdr atm)))) + ;; nitrogen + (else (count-bonds n 3) + atm))))) + (set! term-list ()) + ;; tally up length terms + (do ((BL bond-list (cdr BL))) + ((null? BL) ()) + (set! term-list + (cons (list 'length (cadar BL) (caddar BL)) term-list))) + ;; tally up angle terms + (do ((AL atom-list (cdr AL)) + (x 0 (+ x 1))) + ((null? AL) ()) + (do ((BL bond-list (cdr BL))) + ((null? BL) ()) + (let ((y (other-end (car BL) x))) + (if y + (do ((B2L bond-list (cdr B2L))) + ((null? B2L) ()) + (let ((z (other-end (car B2L) y))) + (if (and z (> z x)) + (set! term-list + (cons (list 'angle x y z) term-list))))))))) + ;; tally up the torsion terms + (do ((AL atom-list (cdr AL)) + (w 0 (+ w 1))) + ((null? AL) ()) + (do ((BL bond-list (cdr BL))) + ((null? BL) ()) + (let ((x (other-end (car BL) w))) + (if x + (do ((B2L bond-list (cdr B2L))) + ((null? B2L) ()) + (let ((y (other-end (car B2L) x))) + (if (and y (not (= w y))) + (do ((B3L bond-list (cdr B3L))) + ((null? B3L) ()) + (let ((z (other-end (car B3L) y))) + (if (and z (not (= z x)) (> z w)) + (set! term-list + (cons (list 'torsion w x y z) + term-list)))))))))))) + ;; tally up the van der Waals terms (unbonded atom pairs) + (do ((AL atom-list (cdr AL)) + (x 0 (+ x 1))) + ((null? AL) ()) + (do ((A2L (cdr AL) (cdr A2L)) + (y (+ x 1) (+ y 1)) + (flag #t)) + ((null? A2L) ()) + (set! flag #t) + (do ((BL bond-list (cdr BL))) + ((null? BL) ()) + (let ((p (other-end (car BL) x))) + (if (and p (= p y)) + (let () + (set! flag #f) + (set! BL '(4)))))) + (if flag + (set! term-list + (cons (list 'vdw x y) + term-list)))))) + + ;; ****************************************************************** + ;; Rotations and Centering + + (define (center-structure) + (if (> (length atom-list) 0) + (let ((cog (vector 0.0 0.0 0.0)) ;; center of gravity + (num-atoms 0)) + (do ((L atom-list (cdr L))) + ((null? L) ()) + (vector-set! cog 0 + (+ (vector-ref cog 0) + (vector-ref (cadar L) 0))) + (vector-set! cog 1 + (+ (vector-ref cog 1) + (vector-ref (cadar L) 1))) + (vector-set! cog 2 + (+ (vector-ref cog 2) + (vector-ref (cadar L) 2))) + (set! num-atoms (+ num-atoms 1))) + (vector-set! cog 0 + (/ (vector-ref cog 0) num-atoms)) + (vector-set! cog 1 + (/ (vector-ref cog 1) num-atoms)) + (vector-set! cog 2 + (/ (vector-ref cog 2) num-atoms)) + (do ((L atom-list (cdr L))) + ((null? L) ()) + (vector-set! (cadar L) 0 + (- (vector-ref (cadar L) 0) (vector-ref cog 0))) + (vector-set! (cadar L) 1 + (- (vector-ref (cadar L) 1) (vector-ref cog 1))) + (vector-set! (cadar L) 2 + (- (vector-ref (cadar L) 2) (vector-ref cog 2))))))) + + (define (rotate-all-atoms-x-axis theta) + (let ((ct (cos theta)) + (st (sin theta)) + (temp 0.0)) + (do ((L atom-list (cdr L))) + ((null? L) ()) + (set! temp (- (* ct (vector-ref (cadar L) 1)) + (* st (vector-ref (cadar L) 2)))) + (vector-set! (cadar L) 2 + (+ (* ct (vector-ref (cadar L) 2)) + (* st (vector-ref (cadar L) 1)))) + (vector-set! (cadar L) 1 temp)))) + + (define (rotate-all-atoms-y-axis theta) + (let ((ct (cos theta)) + (st (sin theta)) + (temp 0.0)) + (do ((L atom-list (cdr L))) + ((null? L) ()) + (set! temp (+ (* ct (vector-ref (cadar L) 0)) + (* st (vector-ref (cadar L) 2)))) + (vector-set! (cadar L) 2 + (- (* ct (vector-ref (cadar L) 2)) + (* st (vector-ref (cadar L) 0)))) + (vector-set! (cadar L) 0 temp)))) + + (define negligible-angle-sq 0.00001) + + (define (rotate-structure xt yt) + (if (> (* xt xt) negligible-angle-sq) + (rotate-all-atoms-y-axis xt)) + (if (> (* yt yt) negligible-angle-sq) + (rotate-all-atoms-x-axis yt))) + + (define (set-atom-position n x y z) + (do ((L atom-list (cdr L)) + (got-it #f)) + ((cond ((null? L) #t) + ((= n 0) (vector-set! (cadar L) 0 x) + (vector-set! (cadar L) 1 y) + (vector-set! (cadar L) 2 z) + ; (set! n-ok #t) + #t) + (else #f)) + got-it) + (set! n (- n 1)))) + + (define (get-atom-position n x y z) + (do ((L atom-list (cdr L)) + (return-value #f)) + ((cond ((null? L) #t) + ((= n 0) (set! return-value (cadar L)) + #t) + (else #f)) + return-value) + (set! n (- n 1)))) + + + ;; ****************************************************************** + ;; Conversion, screen coordinates <=> angstroms + + (define scale-factor 25.0) + + (define (set-scale-factor x) (set! scale-factor x)) + (define (su2a x) (/ x scale-factor)) + (define (a2su x) (* x scale-factor)) + + ;; ****************************************************************** + ;; Add/delete/select atoms and bonds + + (define (remove-from-list L n) + (cond ((null? L) ()) + ((= n 0) (cdr L)) + (else (cons (car L) + (remove-from-list (cdr L) (- n 1)))))) + + (define (remove-from-list-if-test L test) + (cond ((null? L) ()) + ((apply test (list (car L))) + (remove-from-list-if-test (cdr L) test)) + (else (cons (car L) + (remove-from-list-if-test (cdr L) test))))) + + (define (add-bond m n order) + (if (not (= m n)) + (let () + (define need-to-resetup-terms #t) + (delete-bond m n) + (set! bond-list (cons (list order m n) bond-list))))) + + (define (delete-bond m n) + (set! need-to-resetup-terms #t) + (set! bond-list + (remove-from-list-if-test + bond-list + (lambda (bond) (or (and (= m (cadr bond)) + (= n (caddr bond))) + (and (= n (cadr bond)) + (= m (caddr bond)))))))) + + (define (add-atom x y e) + (set! need-to-resetup-terms #t) + (set! atom-list + (append + atom-list + (list + (list e (vector (su2a x) (su2a y) 0.0))))) + (set! force-list + (append + force-list + (list + (vector 0.0 0.0 0.0))))) + + (define (delete-atom n) + (set! need-to-resetup-terms #t) + (set! atom-list (remove-from-list atom-list n)) + (set! force-list (remove-from-list force-list n)) + (set! bond-list (remove-from-list-if-test + bond-list + (lambda (bond) (or (= n (cadr bond)) + (= n (caddr bond)))))) + (set! bond-list + (map + (lambda (bond) + (if (> (cadr bond) n) + (set! bond (list (car bond) + (- (cadr bond) 1) + (caddr bond)))) + (if (> (caddr bond) n) + (set! bond (list (car bond) + (cadr bond) + (- (caddr bond) 1)))) + bond) + bond-list))) + + (define (select-atom x y) + (set! x (su2a x)) + (set! y (su2a y)) + (do ((n #f) + (i 0 (+ i 1)) + (p 0.0) + (sq-dist 0.0) + (min-sq-dist 0.0) + (L atom-list (cdr L))) + ((null? L) n) + (set! p (- x (vector-ref (cadar L) 0))) + (set! sq-dist (* p p)) + (set! p (- y (vector-ref (cadar L) 1))) + (set! sq-dist (+ sq-dist (* p p))) + (if (or (not n) (< sq-dist min-sq-dist)) + (let () + (set! min-sq-dist sq-dist) + (set! n i))))) + + (define (move-atom n x y) + (define (move-helper n x y lst) + (cond ((null? lst) ()) + ((= n 0) (cons + (let ((atm (car lst))) + (list (car atm) + (vector (su2a x) + (su2a y) + (vector-ref (cadr atm) 2)))) + (cdr lst))) + (else (cons (car lst) + (move-helper (- n 1) x y (cdr lst)))))) + (set! atom-list + (move-helper n x y atom-list))) + + ;; ****************************************************************** + ;; Drawing lists + + ;; For wireframe drawing lists, we want only to return an unordered list + ;; of bonds, and we can throw away information about bond order. This + ;; should be very quick, so we can draw wireframes while rotating a + ;; molecule smoothly. + + (define (wireframe-drawing-list) + (entering "wireframe-drawing-list") + (do ((L bond-list (cdr L)) + (drawing-list ()) + (m 0) + (n 0)) + ((null? L) drawing-list) + (set! m (cadar L)) + (set! n (caddar L)) + (set! drawing-list + (cons + (list (a2su (vector-ref (cadr (list-ref atom-list m)) 0)) + (a2su (vector-ref (cadr (list-ref atom-list m)) 1)) + (a2su (vector-ref (cadr (list-ref atom-list n)) 0)) + (a2su (vector-ref (cadr (list-ref atom-list n)) 1))) + drawing-list)))) + + ;; To create detailed drawing lists, we want to specify an order in which + ;; things are drawn, with the most-positive-z-value things drawn first, and + ;; the more-negative-z-value things drawn on top of them (the Painter's + ;; algorithm) for crude depth rendering. To do this we use a data structure, + ;; a list of lists, each inner list containing a boolean, an integer, and a + ;; z-value. The boolean tells whether this object is in the atom list or the + ;; bond list, the integer indexes into that list, and the z value represents + ;; either an atomic nucleus or the midpoint of a bond. + + (define (bubble-1 criterion lst) + (cond ((not (pair? lst)) lst) + ((null? (cdr lst)) lst) + (else (let ((a (car lst)) + (b (cadr lst))) + (if (apply criterion (list a b)) + (cons a (bubble-1 criterion (cdr lst))) + (cons b (bubble-1 criterion (cons a (cddr lst))))))))) + + (define (bubble-sort criterion lst) + (cond ((null? lst) ()) + (else (set! lst (reverse (bubble-1 criterion (reverse lst)))) + (cons (car lst) + (bubble-sort criterion (cdr lst)))))) + + (define (detailed-drawing-list) + (entering "detailed-drawing-list") + (let ((DL ())) + (do ((L bond-list (cdr L)) + (i 0 (+ i 1))) + ((null? L) ()) + (set! DL + (cons + (list + #f i + (* 0.5 + (+ (vector-ref (cadr (list-ref atom-list (cadar L))) 2) + (vector-ref (cadr (list-ref atom-list (caddar L))) 2)))) + DL))) + (do ((L atom-list (cdr L)) + (i 0 (+ i 1))) + ((null? L) ()) + (set! DL (cons (list #t i (vector-ref (cadar L) 2)) + DL))) + (set! DL + (bubble-sort (lambda (x y) + (> (caddr x) (caddr y))) + DL)) + (map (lambda (widget) + (if (car widget) + (let* ((atm (list-ref atom-list (cadr widget))) + (atm-pos (cadr atm)) + (atm-force (list-ref force-list (cadr widget)))) + (list #t + (a2su (vector-ref atm-pos 0)) + (a2su (vector-ref atm-pos 1)) + (car atm) + (* 0.05 (a2su (vector-ref atm-force 0))) + (* 0.05 (a2su (vector-ref atm-force 1))))) + (let* ((bnd (list-ref bond-list (cadr widget))) + (pos1 (cadr (list-ref atom-list (cadr bnd)))) + (pos2 (cadr (list-ref atom-list (caddr bnd))))) + (list #f + (a2su (vector-ref pos1 0)) + (a2su (vector-ref pos1 1)) + (a2su (vector-ref pos2 0)) + (a2su (vector-ref pos2 1)) + (car bnd))))) + DL))) + + ;; ****************************************************************** + ;; Loading and saving structures + + (define (get-structure) + (list (map (lambda (z) + (list (car z) + (vector-ref (cadr z) 0) + (vector-ref (cadr z) 1) + (vector-ref (cadr z) 2))) + atom-list) + bond-list)) + + (define (set-structure s) + (set! atom-list (map (lambda (z) + (list (car z) + (vector (cadr z) (caddr z) (cadddr z)))) + (car s))) + (set! bond-list (cadr s))) + + ;; ****************************************************************** + ;; Potential energy minimization + + ;; We compute force vectors, and then scale them until to be displacement + ;; vectors, where the largest displacement has a magnitude equal to + ;; emin-factor (which is in angstroms). + + ;; currently, these represent angstroms + (define fast-emin-factor 0.2) + (define stable-emin-factor 0.01) + + (define emin-factor stable-emin-factor) + + (define (emin-step) + (entering "emin-sub-step") + (set! whine-about-bond-count #f) + (setup-terms) + (do ((i 0 (+ i 1))) + ((= i 25) ()) + (compute-forces) + (do-to-all-atoms + (lambda (n atm) + (let ((f (list-ref force-list n))) + (list (car atm) + (vplus (cadr atm) + (vscale f (/ emin-factor (vlen f))))))))) + (update-display #t #f) + (if whine-about-bond-count + (error-msg "Mismatch between bonds and valences"))) + + + + ;; ****************************************************************** + ;; ****************************************************************** + ;; THE REST IS GUI CODE + ;; ****************************************************************** + ;; ****************************************************************** + + (define center-x #f) + (define center-y #f) + (define start-mouse ()) + (define selected-atom 0) + (define current-element 0) + (define bond-order 1) + (define atom-drawing-radius 10) + (define draw-force-vectors #f) + (define current-mouse-button #f) + + (define (select-an-atom x y) + (set! selected-atom + (select-atom (- x center-x) + (- y center-y)))) + + (define (rotate-press x y) + (center-structure) + (set! start-mouse (list x y))) + + (define (rotate-drag x y) + (rotate-structure + (* 0.01 (- x (car start-mouse))) + (* -0.01 (- y (cadr start-mouse)))) + (set! start-mouse (list x y)) + (update-display #f #t)) + + (define (rotate-release x y) + (update-display #t #t)) + + (define (move-drag x y) + (move-atom selected-atom + (- x center-x) + (- y center-y)) + (update-display #t #t)) + + (define (addatom-press x y) + (let ((x1 (- x center-x)) + (y1 (- y center-y))) + (add-atom (- x center-x) + (- y center-y) + current-element) + (update-display #t #f))) + + (define (deleteatom-press x y) + (select-an-atom x y) + (delete-atom selected-atom) + (update-display #t #f)) + + (define (deletebond-release x y) + (let ((n selected-atom)) + (select-an-atom x y) + (delete-bond n selected-atom) + (update-display #t #f))) + + (define (addbond-release x y) + (let ((n selected-atom)) + (select-an-atom x y) + (if (not (= n selected-atom)) + (add-bond n selected-atom bond-order)) + (update-display #t #f))) + + (define (do-nothing x y) ()) + + (define press-function rotate-press) + (define drag-function rotate-drag) + (define release-function rotate-release) + + ;; For now, pay attention only to the left mouse button + + (define (press-function-b x y) + (if (eq? current-mouse-button 1) + (press-function x y))) + + (define (drag-function-b x y) + (if (eq? current-mouse-button 1) + (drag-function x y))) + + (define (release-function-b x y) + (if (eq? current-mouse-button 1) + (release-function x y))) + + + (define my-frame% mred:frame%) + + (define my-canvas% + (make-class mred:canvas% + (private + (which-button 0)) + (rename [super-on-paint on-paint]) + (public + (on-paint + (lambda () + (update-display #t #f) + (super-on-paint))) + (on-event + (lambda (event) + (let ((which-button + (cond ((send event button? 1) 1) + ((send event button? 2) 2) + (else 3))) + (x (send event get-x)) + (y (send event get-y))) + (cond ((send event button-down? -1) + (set! current-mouse-button which-button) + (press-function-b x y)) + ((send event button-up? -1) + (release-function-b x y) + (set! current-mouse-button #f)) + ((and current-mouse-button + (send event dragging?)) + (drag-function-b x y)) + (else #f)))))))) + + (define this-session ()) + + (define (update-display full-blown smooth) + (update-session full-blown + smooth + (send (ivar this-session canvas) get-width) + (send (ivar this-session canvas) get-height) + (ivar this-session canvas-dc) + (ivar this-session atom-color) + (ivar this-session select-pen))) + + (define session% + (class () () + (sequence + (set! this-session this)) + (public + (FRAME-WIDTH 500) + (PANEL-HEIGHT 200) + (CANVAS-HEIGHT 300) + (a-frame + (make-object my-frame% + '() ; No parent frame + "NanoCAD v0.2" ; The frame's title + -1 -1 ; Use the default position + FRAME-WIDTH (+ PANEL-HEIGHT CANVAS-HEIGHT))) + (main-panel + (make-object mred:vertical-panel% a-frame)) + (b-panel + (make-object mred:horizontal-panel% main-panel)) + (c-panel + (make-object mred:horizontal-panel% main-panel)) + (rb-panel + (let ([p (make-object mred:horizontal-panel% main-panel)]) + (send p set-label-position wx:const-vertical) + p)) + (canvas + (make-object my-canvas% main-panel)) + (canvas-dc + (send canvas get-dc))) + + (private + (internal-update + (lambda (full-blown) + (update-session full-blown + #f + (send canvas get-width) + (send canvas get-height) + canvas-dc + atom-color + select-pen))) + (carbon-brush + (make-object wx:brush% "BLACK" wx:const-solid)) + (hydrogen-brush + (make-object wx:brush% "WHITE" wx:const-solid)) + (oxygen-brush + (make-object wx:brush% "RED" wx:const-solid)) + (nitrogen-brush + (make-object wx:brush% "BLUE" wx:const-solid)) + + (normal-pen + (make-object wx:pen% "BLACK" 1 wx:const-solid)) + (double-bond-pen + (make-object wx:pen% "BLACK" 3 wx:const-solid)) + (triple-bond-pen + (make-object wx:pen% "BLACK" 5 wx:const-solid)) + (force-vector-pen + (make-object wx:pen% "RED" 1 wx:const-solid)) + + (load-button + (make-object mred:button% + b-panel + (lambda (self event) + (let ((file-name (wx:file-selector ""))) + (if (not (null? file-name)) + (let ((inf (open-input-file file-name))) + (set-structure (read inf)) + (close-input-port inf) + (set! need-to-resetup-terms #t) + (internal-update #t))))) + "Load")) + (save-button + (make-object mred:button% + b-panel + (lambda (self event) + (let ((file-name (wx:file-selector ""))) + (if (not (null? file-name)) + (let () + (delete-file file-name) + (let ((outf (open-output-file file-name)) + (s (get-structure))) + (fprintf outf "((~%") + (map (lambda (atm) + (fprintf outf " ~s~%" atm)) + (car s)) + (fprintf outf " )~% (~%") + (map (lambda (atm) + (fprintf outf " ~s~%" atm)) + (cadr s)) + (fprintf outf "))~%") + (close-output-port outf) + (internal-update #t)))))) + "Save")) + (save-xyz-button + (make-object mred:button% + b-panel + (lambda (self event) + (let ((file-name (wx:file-selector ""))) + (if (not (null? file-name)) + (let () + (delete-file file-name) + (let ((outf (open-output-file file-name))) + (fprintf outf "~a~%Gray Goo~%" + (length atom-list)) + (do ((L atom-list (cdr L))) + ((null? L) ()) + (fprintf outf "~a ~a ~a ~a~%" + (car + (list-ref periodic-table + (caar L))) + (vector-ref (cadar L) 0) + (vector-ref (cadar L) 1) + (- (vector-ref (cadar L) 2)))) + (close-output-port outf) + (internal-update #t)))))) + "SaveXYZ")) + (clear-button + (make-object mred:button% + b-panel + (lambda (self event) + (set! atom-list ()) + (set! bond-list ()) + (set! term-list ()) + (internal-update #t)) + "Clear")) + (emin-button + (make-object mred:button% + b-panel + (lambda (self event) + (emin-step)) + "Emin")) + (quit-button + (make-object mred:button% + b-panel + (lambda (self event) + (send canvas-dc end-drawing) + (send a-frame show #f)) + "Quit"))) + (private + (show-forces-checkbox + (make-object mred:check-box% + c-panel + (lambda (self event) + (set! draw-force-vectors (send event checked?)) + (internal-update #t)) + "Show Force Vectors")) + (use-torsion-checkbox + (make-object mred:check-box% + c-panel + (lambda (self event) + (set! use-torsion-forces (send event checked?))) + "Use Torsion Forces")) + (use-vdw-checkbox + (make-object mred:check-box% + c-panel + (lambda (self event) + (set! use-vdw-forces (send event checked?))) + "Use VDW Forces"))) + (public + (select-pen + (lambda (dc n) + (case n + ((0) (send dc set-pen normal-pen)) + ((1) (send dc set-pen force-vector-pen)) + ((2) (send dc set-pen double-bond-pen)) + ((3) (send dc set-pen triple-bond-pen))))) + (atom-color + (lambda (dc element) + (case element + ((0 1 2 3) (send dc set-brush carbon-brush)) + ((4) (send dc set-brush hydrogen-brush)) + ((5 6) (send dc set-brush oxygen-brush)) + (else (send dc set-brush nitrogen-brush)))))) + (private + (rb-sub-panel% + (class mred:panel% args + (inherit set-label-position) + (sequence + (apply super-init args) + (set-label-position wx:const-vertical)))) + (set-mode + (lambda (n) + (case n + ((0) (set! press-function rotate-press) + (set! drag-function rotate-drag) + (set! release-function rotate-release)) + ((1) (set! press-function select-an-atom) + (set! drag-function move-drag) + (set! release-function do-nothing)) + ((2) (set! press-function addatom-press) + (set! drag-function do-nothing) + (set! release-function do-nothing)) + ((3) (set! press-function deleteatom-press) + (set! drag-function do-nothing) + (set! release-function do-nothing)) + ((4) (set! press-function select-an-atom) + (set! drag-function do-nothing) + (set! release-function addbond-release)) + ((5) (set! press-function select-an-atom) + (set! drag-function do-nothing) + (set! release-function deletebond-release))))) + (mode-selector + (make-object mred:radio-box% + (make-object rb-sub-panel% rb-panel) + (lambda (self event) + (let ((n (send event get-command-int))) + (set-mode n))) + "Tool" + -1 -1 -1 -1 + (list "Rotate" "MoveAtom" "AddAtom" "DeleteAtom" + "AddBond" "DeleteBond"))) + (element-selector + (make-object mred:radio-box% + (make-object rb-sub-panel% rb-panel) + (lambda (self event) + (send mode-selector set-selection 2) + (set-mode 2) + (let ((n (send event get-command-int))) + (case n + ((0) (set! current-element 0)) + ((1) (set! current-element 4)) + ((2) (set! current-element 5)) + (else (set! current-element 7))))) + "Atom" + -1 -1 -1 -1 + (list "Carbon" "Hydrogen" "Oxygen" "Nitrogen"))) + (bond-order-selector + (make-object mred:radio-box% + (make-object rb-sub-panel% rb-panel) + (lambda (self event) + (send mode-selector set-selection 4) + (set-mode 4) + (let ((n (send event get-command-int))) + (set! bond-order (+ n 1)))) + "Bond" + -1 -1 -1 -1 + (list "Single" "Double" "Triple"))) + (zoom-factor + (make-object mred:radio-box% + (make-object rb-sub-panel% rb-panel) + (lambda (self event) + (let ((n (send event get-command-int))) + (case n + ((0) (set-scale-factor 10.0)) + ((1) (set-scale-factor 25.0)) + ((2) (set-scale-factor 50.0)) + (else (set-scale-factor 100.0)))) + (set! atom-drawing-radius (* 0.6 scale-factor)) + (internal-update #t)) + "Zoom" + -1 -1 -1 -1 + (list "10" "25" "50" "100"))) + (emin-convergence + (make-object mred:radio-box% + (make-object rb-sub-panel% rb-panel) + (lambda (self event) + (let ((n (send event get-command-int))) + (case n + ((0) (set! emin-factor stable-emin-factor)) + (else (set! emin-factor fast-emin-factor))))) + "Emin" + -1 -1 -1 -1 + (list "Stable" "Fast")))) + (sequence + (send main-panel border 0) + (for-each + (lambda (panel) + (send panel stretchable-in-y #f) + (send panel border 0)) + (list b-panel c-panel rb-panel)) + (set! error-msg + (lambda (txt) + (send canvas-dc draw-text txt 10 10))) + (set-scale-factor 25.0) + (send zoom-factor set-selection 1) + (send use-vdw-checkbox set-value #t) + (send a-frame show #t)))) + + (define offscreen-dc (make-object wx:memory-dc%)) + (define offscreen-dc-width -1) + (define offscreen-dc-height -1) + + (define (update-session full-blown + smooth + canvas-width + canvas-height + canvas-dc + atom-color + select-pen) + (when (and smooth (not (and (= canvas-width offscreen-dc-width) + (= canvas-height offscreen-dc-height)))) + (let ([bm (make-object wx:bitmap% canvas-width canvas-height)]) + (send offscreen-dc select-object bm) + (set! offscreen-dc-width canvas-width) + (set! offscreen-dc-height canvas-height))) + (let ([draw-dc (if (and smooth (send offscreen-dc ok?)) offscreen-dc canvas-dc)]) + (set! center-x (* 0.5 canvas-width)) + (set! center-y (* 0.5 canvas-height)) + (send draw-dc clear) + (if (or #t full-blown) + (let ((DL ()) + (minus-half-radius (* -0.5 atom-drawing-radius))) + (if draw-force-vectors (compute-forces)) + (if (< (length force-list) (length atom-list)) + (set! force-list + (map (lambda (atm) + (vector 0.0 0.0 0.0)) + atom-list))) + (set! DL (detailed-drawing-list)) + (map (lambda (z) + (if (car z) + (let () ;; for atoms, let's do both circles and forces + (atom-color draw-dc (cadddr z)) + (send draw-dc draw-ellipse + (+ (cadr z) center-x minus-half-radius) + (+ (caddr z) center-y minus-half-radius) + atom-drawing-radius atom-drawing-radius) + (if draw-force-vectors + (let () + (select-pen draw-dc 1) + (send draw-dc draw-line + (+ (cadr z) center-x) + (+ (caddr z) center-y) + (+ (cadr z) (cadr (cdddr z)) center-x) + (+ (caddr z) (caddr (cdddr z)) center-y)) + (select-pen draw-dc 0)))) + (let () + (case (cadddr (cddr z)) + ((1) (select-pen draw-dc 0)) + ((2) (select-pen draw-dc 2)) + (else (select-pen draw-dc 3))) + (send draw-dc draw-line + (+ (cadr z) center-x) + (+ (caddr z) center-y) + (+ (cadddr z) center-x) + (+ (cadddr (cdr z)) center-y)) + (select-pen draw-dc 0)))) + DL)) + (map (lambda (z) + (send draw-dc draw-line + (+ (car z) center-x) + (+ (cadr z) center-y) + (+ (caddr z) center-x) + (+ (cadddr z) center-y))) + (wireframe-drawing-list))) + (if smooth + (send canvas-dc blit 0 0 canvas-width canvas-height offscreen-dc 0 0)))) + + (make-object session%))) + +(define (ncad:go) + (invoke-unit/sig ncad@ mred:wx^ (mred : mred^))) + + + diff --git a/collects/mrdemo/phone.mre b/collects/mrdemo/phone.mre new file mode 100644 index 0000000..45e47be Binary files /dev/null and b/collects/mrdemo/phone.mre differ diff --git a/collects/mrdemo/phone.ss b/collects/mrdemo/phone.ss new file mode 100644 index 0000000..da4fced --- /dev/null +++ b/collects/mrdemo/phone.ss @@ -0,0 +1,163 @@ + +(define lookup-number + (let ([phonebook '(("Mr. Bumpy" "555-BUMP" "555-SNOT") + ("Squishington" "555-SQSH" "555-BOWL") + ("Miss Molly" "555-MOLL" "555-COMF"))]) + (lambda (name home?) + (sleep 2) ; artificial database delay + (let loop ([pb phonebook]) + (cond + [(null? pb) #f] + [(regexp-match name (caar pb)) + ((if home? cadar caddar) pb)] + [else (loop (cdr pb))]))))) + +(define a-frame + (make-object mred:frame% + null ; No parent frame + "Phone Book")) ; The frame's title + +(define a-panel + (make-object mred:vertical-panel% + a-frame)) ; Panel is in a-frame + +(define h-panel + (make-object mred:horizontal-panel% + a-panel)) ; Panel is in a-frame + +(define name-text + (make-object mred:text% + h-panel + (lambda (self event) (refresh-number-info)) + "Name" ; label + "")) ; initial value +(define quit-button + (make-object mred:button% + h-panel + (lambda (self event) + (send a-frame show #f)) + "Quit")) ; Button label + +(define number-selector + (make-object mred:radio-box% + a-panel + (lambda (self event) (refresh-number-info)) + "" ; No label + -1 -1 -1 -1 ; Default position and size + (list "Home Number" "Office Number"))) + +(define number-text + (make-object mred:text% + a-panel + (lambda (self event) #f) ; No event-handling + "Number" + "(Unknown)")) +(send number-text set-editable #f) + +;; First revision: unthreaded + +(define refresh-number-info + (lambda () + (let* ([name (send name-text get-value)] + [home? (zero? (send number-selector get-selection))] + [number (lookup-number name home?)] + [number-string (if number + number + "(Unknown)")]) + (send number-text set-value number-string)))) + +;; Second revision: threaded + +(define refresh-number-info + (let ([adj-cancel-sema (make-semaphore 1)] + [previous-cancel (box #f)]) + (lambda () + (let ([this-cancel (box #f)]) + (semaphore-wait adj-cancel-sema) + (set-box! previous-cancel #t) + (set! previous-cancel this-cancel) + (semaphore-post adj-cancel-sema) + (thread + (lambda () + (send number-text set-value "(Searching...)") + (let* ([name (send name-text get-value)] + [home? (zero? (send number-selector get-selection))] + [number (lookup-number name home?)] ; May take a while... + [number-string (if number + number + "(Unknown)")]) + (semaphore-wait adj-cancel-sema) + (unless (unbox this-cancel) + (send number-text set-value number-string)) + (semaphore-post adj-cancel-sema)))))))) + +;; Make a class: + +(define pb-session% + (class null () + (public + [refresh-number-info + (let ([adj-cancel-sema (make-semaphore 1)] + [previous-cancel (box #f)]) + (lambda () + (let ([this-cancel (box #f)]) + (semaphore-wait adj-cancel-sema) + (set-box! previous-cancel #t) + (set! previous-cancel this-cancel) + (semaphore-post adj-cancel-sema) + (thread + (lambda () + (send number-text set-value "(Searching...)") + (let* ([name (send name-text get-value)] + [home? (zero? (send number-selector get-selection))] + [number (lookup-number name home?)] ; May take a while... + [number-string (if number + number + "(Unknown)")]) + (semaphore-wait adj-cancel-sema) + (unless (unbox this-cancel) + (send number-text set-value number-string)) + (semaphore-post adj-cancel-sema)))))))]) + (public + (a-frame (make-object mred:frame% null "Phonebook")) + (a-panel (make-object mred:vertical-panel% a-frame))) + (private + (h-panel (make-object mred:horizontal-panel% a-panel)) + (name-text (make-object mred:text% h-panel + (lambda (self event) (refresh-number-info)) + "Name" "")) + (quit-button (make-object mred:button% h-panel + (lambda (self event) (send a-frame show #f)) + "Quit")) + (number-selector (make-object mred:radio-box% a-panel + (lambda (self event) (refresh-number-info)) + "" -1 -1 -1 -1 (list "Home Number" "Office Number"))) + (number-text (make-object mred:text% a-panel + (lambda (self event) #f) + "Number" "(Unknown)"))) + (sequence + (send a-frame show #t) + (send number-text set-editable #f)))) + + + +(define pb-counted-session% + (class pb-session% () + (inherit a-frame a-panel) ; We need to access the panel object... + (rename [basic-refresh-number-info refresh-number-info]) ; and old refresh + (private [search-counter 0]) ; Counter value + (public + [refresh-number-info ; Increment the counter and call old refresh + (lambda () + (set! search-counter (add1 search-counter)) + (send counter-text set-value (number->string search-counter)) + (basic-refresh-number-info))]) + (sequence + (super-init)) ; Do base class initialization + (private + (counter-text (make-object mred:text% a-panel + (lambda (self event) #f) + "Number of Searches Started" + "0"))) + (sequence + (send counter-text set-editable #f)))) diff --git a/collects/mrdemo/sig.ss b/collects/mrdemo/sig.ss new file mode 100644 index 0000000..e248986 --- /dev/null +++ b/collects/mrdemo/sig.ss @@ -0,0 +1 @@ +(require-library "sig.ss" "system") diff --git a/collects/mrdemo/toyproof.mre b/collects/mrdemo/toyproof.mre new file mode 100644 index 0000000..2e9e9ce Binary files /dev/null and b/collects/mrdemo/toyproof.mre differ diff --git a/collects/mrdemo/toyproof.ss b/collects/mrdemo/toyproof.ss new file mode 100644 index 0000000..785a7ed --- /dev/null +++ b/collects/mrdemo/toyproof.ss @@ -0,0 +1,377 @@ +;; Toy proof checkers implemented with MrEd and units +;; Kathi Fisler +;; September 3, 1996 + +;; This code demonstrates the combined use of MrEd and units to +;; implement a collection of simple proof checkers. + +;; Proof Checker Architecture: +;; +;; A proof checker consists of two main components: a list of +;; operations supported by the checker and the interface through which +;; the user invokes the checker. Each of these components is +;; implemented as a unit in the code below. +;; +;; The "operations" unit, (signature prover-core^) provides a list +;; containing the names of the operations, a list containing the +;; operations corresponding to the names, and a default operation. +;; +;; The "interface" unit (signature interface^) is a compound unit with +;; subunits corresponding to the various pieces of the interface. +;; Subunits exist for how the user inputs data to the checker, how the +;; checker displays results to the user, how the user selects from +;; among the possible operations, how the user instructs the checker +;; to check the current data against the selected operation, and how +;; the user exits the checker. The interface unit combines these +;; subunits into a main interface and provides a function +;; (create-interface) that can be invoked to create a checker with the +;; specified interface components and the specified operations from +;; the operations unit. + +;; The Collection of Checkers +;; +;; Each of the implemented checkers contains three objects into which +;; the user can enter data and one object through which the checker +;; displays results. Two operations units are provided: +;; proof-core-calculator@ and proof-core-tester@. The former computes +;; simple arithmetic functions over the three inputs and the latter +;; tests boolean-valued relationships between the three inputs. The +;; checker displays the values returned by either type of operation. +;; +;; Two types of interfaces are possible: one in which the operations +;; are selected through radio boxes and the other in which the +;; operations are selected through menu options. +;; +;; Three checkers are defined explicitly at the end of the code: +;; make-calculator/radio, make-checker/radio, and make-checker/menu, +;; each taking the appropriate combination of the described interface +;; and operations units. + +;;;;; The Implementation ;;;;; + +(require-library "trigger.ss") + +;;;;; Signature Definitions ;;;;; + +(define-signature prover-core^ + (proof-rule-names proof-rule-checkers default-rule-checker)) + +(define-signature num-entry-interface^ + (create-num-entry-interface get-numbers)) + +(define-signature result-display-interface^ + (create-result-display-interface show-result)) + +(define-signature rule-select-interface^ + (create-rule-select-interface + current-proof-rule set-current-proof-rule)) + +(define-signature compute-interface^ + (create-compute-interface)) + +(define-signature quit-interface^ + (create-quit-interface)) + +(define-signature main-interface^ + (create-interface quit-prover)) + +(define-signature interface^ + ((open main-interface^))) + +;;;;; Compound Unit Definitions ;;;;; + +(define interface@ + (lambda (numentry resdisplay ruleselect compute quit main) + (compound-unit/sig + (import (MRED : mred^) (CORE : prover-core^)) + (link + (NUMENTRY : num-entry-interface^ (numentry MRED)) + (RESDISPLAY : result-display-interface^ (resdisplay MRED)) + (RULESELECT : rule-select-interface^ (ruleselect CORE MRED)) + (COMPUTE : compute-interface^ (compute RESDISPLAY RULESELECT + NUMENTRY MRED)) + (QUIT : quit-interface^ (quit MAIN MRED)) + (MAIN : main-interface^ (main NUMENTRY RESDISPLAY + RULESELECT COMPUTE QUIT MRED)) + ) + (export (open MAIN))))) + +(define prover@ + (lambda (core interface) + (compound-unit/sig + (import (MRED : mred^)) + (link + (CORE : prover-core^ (core)) + (INTERFACE : interface^ (interface MRED CORE))) + (export (open INTERFACE))))) + +;;;;; Primitive Unit Definitions ;;;;; + +;;;;;;;; Interface Units ;;;;;;;; + +(define main-interface-no-menus@ + (unit/sig main-interface^ + (import num-entry-interface^ result-display-interface^ + rule-select-interface^ compute-interface^ + quit-interface^ (mred : mred^)) + (define outer-frame + (make-object mred:frame% `() "Toy Prover")) + (define v-panel + (make-object mred:vertical-panel% outer-frame)) + (define upper-hpanel + (make-object mred:horizontal-panel% v-panel)) + (define lower-hpanel + (make-object mred:horizontal-panel% v-panel)) + (define create-interface + (lambda () + (create-num-entry-interface upper-hpanel) + (create-result-display-interface lower-hpanel) + (create-compute-interface upper-hpanel) + (create-quit-interface upper-hpanel outer-frame) + (create-rule-select-interface lower-hpanel) + (send outer-frame show #t))) + (define quit-prover + (lambda () + (send outer-frame show #f))) + )) + +(define main-interface-menus@ + (unit/sig main-interface^ + (import num-entry-interface^ result-display-interface^ + rule-select-interface^ compute-interface^ + quit-interface^ (mred : mred^)) + (define myframe% + (class mred:standard-menus-frame% args + (rename [super-make-menu-bar make-menu-bar]) + (public + [make-menu-bar + (lambda () + (let ([mb (super-make-menu-bar)]) + (create-rule-select-interface mb) + mb))] + [panel% mred:vertical-panel%] + ) + (sequence (apply super-init args)))) + (define outer-frame + (make-object myframe% null "Toy Prover")) + (define v-panel (ivar outer-frame panel)) + (define upper-hpanel + (make-object mred:horizontal-panel% v-panel)) + (define lower-hpanel + (make-object mred:horizontal-panel% v-panel)) + (define create-interface + (lambda () + (create-num-entry-interface upper-hpanel) + (create-result-display-interface lower-hpanel) + (create-compute-interface upper-hpanel) + (create-quit-interface upper-hpanel outer-frame) + (send outer-frame show #t))) + (define quit-prover + (lambda () + (send outer-frame show #f))) + )) + +(define num-entry-interface-3text@ + (unit/sig num-entry-interface^ + (import (mred : mred^)) + + (define num1 (void)) + (define num2 (void)) + (define num3 (void)) + + (define create-num-entry-interface + (lambda (panel) + (set! num1 + (make-object mred:text% panel (lambda (self event) #f) + "" "")) + (set! num2 + (make-object mred:text% panel (lambda (self event) #f) + "" "")) + (set! num3 + (make-object mred:text% panel (lambda (self event) #f) + "" "")))) + + (define get-numbers + (lambda () + (map string->number + (list (send num1 get-value) + (send num2 get-value) + (send num3 get-value))))) + )) + +(define result-display-interface-text@ + (unit/sig result-display-interface^ + (import (mred : mred^)) + + (define resdisplay (void)) + + (define create-result-display-interface + (lambda (panel) + (set! resdisplay + (make-object mred:text% panel (lambda (self event) #f) "Result")) + )) + + (define show-result + (lambda (res) + (send resdisplay set-value + (cond ((string? res) res) + ((number? res) (number->string res)) + ((boolean? res) (if res "True" "False")) + (error "Argument of Unknown Type"))))) + )) + +(define rule-select-interface-radio@ + (unit/sig rule-select-interface^ + (import prover-core^ (mred : mred^)) + + (define current-proof-rule default-rule-checker) + + (define set-current-proof-rule + (lambda (rule) + (set! current-proof-rule rule))) + + (define create-rule-select-interface + (lambda (panel) + (make-object mred:radio-box% + panel + (lambda (self event) + (set-current-proof-rule + (list-ref proof-rule-checkers + (send self get-selection)))) + "" -1 -1 -1 -1 + proof-rule-names))) + )) + +(define rule-select-interface-menus@ + (unit/sig rule-select-interface^ + (import prover-core^ (mred : mred^)) + (define current-proof-rule default-rule-checker) + + (define set-current-proof-rule + (lambda (rule) + (set! current-proof-rule rule))) + + (define create-rule-select-interface + (lambda (mb) + (let ([rules-menu (make-object mred:menu%)]) + (map + (lambda (name checker) + (send rules-menu append-item name + (lambda () + (set-current-proof-rule checker)))) + proof-rule-names + proof-rule-checkers) + (send mb append rules-menu "Rules")))) + )) + +(define compute-interface-button@ + (unit/sig compute-interface^ + (import result-display-interface^ rule-select-interface^ + num-entry-interface^ (mred : mred^)) + (define create-compute-interface + (lambda (panel) + (make-object mred:button% + panel + (lambda (self event) + (show-result + (apply current-proof-rule (get-numbers)))) + "Apply Rule"))))) + +(define quit-interface-button@ + (unit/sig quit-interface^ + (import main-interface^ (mred : mred^)) + (define create-quit-interface + (lambda (panel outer-frame) + (make-object mred:button% + panel + (lambda (self event) (quit-prover)) + "Quit"))))) + +;;;;;;;; Prover Core Units ;;;;;;;; + +(define proof-core-calculator@ + (unit/sig prover-core^ + (import) + (define-struct proof-rule (name checker)) + + (define proof-rules + (list + (make-proof-rule "Add" +) + (make-proof-rule "Mult" *) + (make-proof-rule "Max" max))) + + (define proof-rule-names (map proof-rule-name proof-rules)) + (define proof-rule-checkers (map proof-rule-checker proof-rules)) + (define default-rule-checker (car proof-rule-checkers)))) + +(define proof-core-tester@ + (unit/sig prover-core^ + (import) + (define-struct proof-rule (name checker)) + + (define square + (lambda (num) + (* num num))) + + (define proof-rules + (list + (make-proof-rule "Test Add" + (lambda (num-1 num-2 num-3) + (= num-3 (+ num-1 num-2)))) + (make-proof-rule "Test Mult" + (lambda (num-1 num-2 num-3) + (= num-3 (* num-1 num-2)))) + (make-proof-rule "Test Increasing" + (lambda (num-1 num-2 num-3) + (and (< num-1 num-2) + (< num-2 num-3)))) + (make-proof-rule "Test Triangle" + (lambda (num-1 num-2 num-3) + (= (square num-3) + (+ (square num-1) (square num-2))))) + )) + + (define proof-rule-names (map proof-rule-name proof-rules)) + (define proof-rule-checkers (map proof-rule-checker proof-rules)) + (define default-rule-checker (car proof-rule-checkers)))) + +;;;;; Creating Provers ;;;;; + +(define make-calculator/radio + (lambda () + (invoke-open-unit/sig + (prover@ proof-core-calculator@ + (interface@ num-entry-interface-3text@ + result-display-interface-text@ + rule-select-interface-radio@ + compute-interface-button@ + quit-interface-button@ + main-interface-no-menus@)) + #f (mred : mred^)) + (create-interface))) + +(define make-checker/radio + (lambda () + (invoke-open-unit/sig + (prover@ proof-core-tester@ + (interface@ num-entry-interface-3text@ + result-display-interface-text@ + rule-select-interface-radio@ + compute-interface-button@ + quit-interface-button@ + main-interface-no-menus@)) + #f (mred : mred^)) + (create-interface))) + +(define make-checker/menu + (lambda () + (invoke-open-unit/sig + (prover@ proof-core-tester@ + (interface@ num-entry-interface-3text@ + result-display-interface-text@ + rule-select-interface-menus@ + compute-interface-button@ + quit-interface-button@ + main-interface-menus@)) + #f (mred : mred^)) + (create-interface))) diff --git a/collects/mrdemo/turtles.mre b/collects/mrdemo/turtles.mre new file mode 100644 index 0000000..223d64d Binary files /dev/null and b/collects/mrdemo/turtles.mre differ diff --git a/collects/mrdemo/turtles.ss b/collects/mrdemo/turtles.ss new file mode 100644 index 0000000..47d8a27 --- /dev/null +++ b/collects/mrdemo/turtles.ss @@ -0,0 +1,5 @@ + +(require-library "turtle.ss" "graphics") +(require-library "turex.ss" "graphics") + +(turtles) diff --git a/collects/mrspidey/Gui/Tframe.ss b/collects/mrspidey/Gui/Tframe.ss new file mode 100644 index 0000000..fdcb46e --- /dev/null +++ b/collects/mrspidey/Gui/Tframe.ss @@ -0,0 +1,343 @@ +;; Tframe.ss - creates MrSpidey frames +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +; Global variable to record the most-recently created frame +(define tf (void)) + +(define shake-it-repetitions 25) + +(define spidey:frame% + (class + (mred:make-searchable-frame% mred:simple-menu-frame%) + (arg-main arg-filename summary-edit . init-locs) + + (inherit show get-canvas ;; get-canvas% + make-menu create-status-line set-status-text + get-position get-size set-icon panel + set-title file-menu set-title-prefix + set-size) + + ;; ---------- + + (rename + [super-on-close on-close] + [super-make-menu-bar make-menu-bar]) + + ;; ---------- + + (public + + [get-edit (lambda () program-edit)] + [auto-set-wrap #f] + [edit% flow-arrow:media-edit%] + [get-canvas% (lambda () mred:wrapping-canvas%)] + [on-close + (lambda ignored + (send main on-frame-close filename) + (send this show #f) + (remq-callback-sdl-alg-changed! flush-type-cache) + (super-on-close))] + + [set-show-mode + (lambda (which) + (pretty-debug-gui `(set-show-mode ,which)) + (unless (eq? which canvas-show-mode) + (set! canvas-show-mode which) + (send summary-canvas stretchable-in-y (eq? which 'summary)) + (send panel change-children + (lambda (ignore) + (filter + (lambda (x) x) + (list + (and (or (eq? which 'program) (eq? which 'both)) + program-canvas) + (and (or (eq? which 'summary) (eq? which 'both)) + summary-canvas)))))))] + + ;; ---------- Set up the menus + [file-menu:new #f] + [file-menu:open #f] + [file-menu:revert #f] + [file-menu:save #f] + [file-menu:save-as #f] + ;;[file-menu:print #f] + ;;[file-menu:between-print-and-close (lambda args (void))] + [file-menu:between-save-and-print (lambda args (void))] + + [edit-menu:undo #f] + [edit-menu:redo #f] + [edit-menu:cut #f] + [edit-menu:paste #f] + [edit-menu:delete #f] + ;;[edit-menu:find #f] + [edit-menu:replace #f] + [edit-menu:between-replace-and-preferences (lambda args (void))] + + [file-menu:close on-close] + [file-menu:between-open-and-save + (lambda (file-menu) + (send file-menu + append-item + "Open ..." + (lambda () (send main open-analyzed-file-choice))) + (send file-menu + append-item + "Open All" + (lambda () (wrap-busy-cursor (lambda () (send main open-all #t))))) + (send file-menu + append-item + "Load All" + (lambda () (wrap-busy-cursor (lambda () (send main open-all #f))))) + (send file-menu + append-item + "Reanalyze" + (lambda () (wrap-busy-cursor (lambda () (send main reanalyze))))) + (send file-menu append-separator))] + [file-menu:between-close-and-quit + (lambda (file-menu) + (send file-menu + append-item + "Close All" + ;;(format "Close ~a" st:name) + (lambda () + (wrap-busy-cursor + (lambda () + (send main close-all-frames))))))] + + [flush-type-cache (lambda () (void))] + + [calc-show + (lambda () + (set-show-mode 'program) + (when (and + summary-canvas + ;; Show summary only if some real content + (> (send summary-edit last-line) 3)) + ;;(printf "Summary-edit size ~s~n" (send summary-edit last-line)) + (set-show-mode 'both)))] + + [make-menu-bar + (lambda () + (let ([menu-bar (super-make-menu-bar)]) + (let ([show-menu (make-menu)]) + (send menu-bar append show-menu "Show") + (set! init-show-menu + (lambda () + (send show-menu + append-check-set + (list + (cons "Program Only" 'program) + (cons "Summary Only" 'summary) + (cons "Both" 'both)) + set-show-mode + (case canvas-show-mode + [(program) 0] + [(summary) 1] + [(both) 2] + [else 0])))) + + '(send show-menu append-separator) + '(send show-menu + append-check-set + (map (lambda (mode) (cons (mode-name mode) mode)) + modes) + set-display-mode)) + + (let ([clear-menu (make-menu)]) + (send menu-bar append clear-menu "Clear") + (send* clear-menu + (append-item + "Arrows+Types" + (lambda () + (wrap-busy-cursor + (lambda () + (send* program-edit + (delete-arrows) + (delete-types)))) + "Removes both types and arrows from the window")) + (append-item + "Arrows" + (lambda () + (wrap-busy-cursor + (lambda () + (send program-edit delete-arrows)))) + "Removes all arrows from the window") + (append-item + "Types" + (lambda () + (wrap-busy-cursor + (lambda () + (send program-edit delete-types)))) + "Removes all types from the window")) + (unless st:restricted + (send clear-menu append-item + "Shake Buffer" + (lambda () (for i 0 shake-it-repetitions (shake-it))) + "Sends random inputs to buffer") + (send clear-menu append-item + "Rewrite Buffer" + (lambda () + (wrap-busy-cursor + (lambda () + (set-display-mode display-mode)))) + "Removes all types and arrows from the window"))) + + (let ([filter-menu (make-menu)]) + (send menu-bar append filter-menu "Filter") + (send filter-menu + append-check-set + (analysis-get-filters) + analysis-set-arrow-filter!) + (analysis-set-arrow-filter! #f)) + + + + menu-bar))] + + [init-show-menu #f] + ) + + ;; ---------- + + (public + [main arg-main] ; parent containing the global state + program-canvas + program-edit + summary-canvas ; or #f if no summary + [filename arg-filename] + + [canvas-show-mode 'none] ; 'program, 'summary, or 'both + [display-mode (car modes)] ; which display mode + + [set-display-mode + (lambda (which) + (set! display-mode which) + (pretty-debug-gui `(set-display-mode ,display-mode ,filename)) + ;; Call main to create a new edit buffer, + ;; and to load and annotate file + (set! program-edit + (send main annotated-edit display-mode filename program-canvas)) + (send program-canvas set-media program-edit))] + + [focus-def + (lambda (pos) + (unless (memq display-mode '(program both)) + (set-show-mode 'both)) + (let* ( [real-pos (send program-edit real-start-position pos)] + [end (mred:scheme-forward-match + program-edit real-pos + (send program-edit last-position))]) + (thread + (lambda () + (sleep) + (send program-canvas set-focus) + (send program-edit + set-position-bias-scroll -1 real-pos end)))))] + + [shake-it + (lambda () + (send program-edit shake-it))] + + ;; ---------- + + ) + + (sequence + (pretty-debug-gui + `(Tframe ,arg-main ,arg-filename ,summary-edit ,@init-locs)) + (match init-locs + [(w h x y) + (pretty-debug-gui `(send this set-size ,(+ x 15) ,(+ y 15) ,w ,h)) + (set-size x y w h)] + [() (void)]) + (pretty-debug-gui `(Tframe super-init)) + (let ([t (format "~a: ~a" + st:name (file-name-from-path arg-filename))]) + (super-init t) + (pretty-debug-gui `(Tframe super-init done)) + (set-title-prefix t))) + + + ;; --------------------------------------------------------- + + (sequence + (set! flush-type-cache + (lambda () + (pretty-debug-gui '(Tframe flush-type-cache)) + (unless (void? program-edit) + (send program-edit flush-type-cache)))) + + (add-callback-sdl-alg-changed! flush-type-cache) + + (pretty-debug-gui + `(Tframe ,arg-main ,arg-filename ,summary-edit ,@init-locs)) + (set! tf this) + + ;; ------------------------------------------------------------ + ;; build the canvases + + (pretty-debug-gui '(setting summary-canvas)) + (set! summary-canvas + (and summary-edit + (let ([c + ;(make-object (get-canvas%) panel) + (make-object (class-asi mred:one-line-canvas% + (public + [lines 5] + [style-flags 0])) + panel) + ]) + ;;(send c set-lines 2) + (send c set-media summary-edit) + c))) + (assert (is-a? summary-canvas mred:connections-media-canvas%)) + (pretty-debug-gui '(setting program-canvas)) + (set! program-canvas (get-canvas)) + (set-display-mode (car modes)) + (pretty-debug-gui '(done setting canvases)) + + ;; ------------------------------------------------------------ + ;; install the icon + + '(let ([icon (make-object wx:icon% + (build-absolute-path + (collection-path "mrspidey") ; MATTHEW: got rid of plt-home + "icon.gif") + wx:const-bitmap-type-gif + )]) + (when (send icon ok?) (set-icon icon))) + + ;; ------------------------------------------------------------ + ;; status help line + + ;;(unless (eq? mred:platform 'macintosh) + ;; (create-status-line)) + + ;;(set-status-text + ;; "Mouse: Left-type/parents Midde-Ancestors Right-Close") + + ;; ------------------------------------------------------------ + + ;;(set-display-mode display-mode) + (calc-show) + (init-show-menu) + (show #t) + + ))) + + diff --git a/collects/mrspidey/Gui/annotat.ss b/collects/mrspidey/Gui/annotat.ss new file mode 100644 index 0000000..3aaeae1 --- /dev/null +++ b/collects/mrspidey/Gui/annotat.ss @@ -0,0 +1,1073 @@ +; annotat.ss +; Defines flow-arrow:media-edit%, type-annotation% and flow-arrow% +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +;; Constants concerning positioning +;; Global so easy to modify + +(define arrow-start-dx 2) +(define arrow-start-dy 12) +(define arrow-end-dx 2) +(define arrow-end-dy 12) +(define arrow-delta 7) + +(define jump-start-dx -15) +(define jump-start-dy 25) +(define jump-end-dx -25) +(define jump-end-dy 25) + +(define offset-menu-exp-y 20) +(define offset-menu-snip-y 25) + +(define offsets-load-menu-src-known (cons 0 18)) +(define offsets-load-menu-dest-known (cons 0 18)) +(define offsets-load-menu-src-jump (cons -25 35)) +(define offsets-load-menu-dest-jump (cons -25 35)) + +(define SELECT-SHOW-VALUE-SET 0) +(define SELECT-CLOSE-VALUE-SET 1) +(define SELECT-PARENTS 2) +(define SELECT-ANCESTORS 3) +(define SELECT-PATH-SOURCE 4) +(define SELECT-CHILDREN 5) +(define SELECT-DESCENDANTS 6) +(define SELECT-COPY-VALUE-SET 7) +(define SELECT-CLOSE-MENU 8) +(define SELECT-RECOMPUTE-VALUE-SET 11) + +(define LOAD-NONLOCAL-FILE 9) +(define ZOOM-TO-FILE 10) + +;; ------------------------------------------------------------ + +(define highlight + (lambda (edit src-pos) + ;;(pretty-debug-gui `(highlight ,src-pos)) + (let* ([src-end (send edit match-paren-forward src-pos)]) + ;;(send edit set-position src-pos src-end) + (send (send edit get-frame) show #t) + (send edit relocate-set-position src-pos) + (send edit relocate-flash-on src-pos src-end) +))) + +;; ------------------------------------------------------------ +;; The brushes, pens for drawing arrows + +(define arrow-brush.pen + (cons + (make-object wx:brush% (get-resource-maybe "arrow-color" "BLUE") + wx:const-solid) + (make-object wx:pen% (get-resource-maybe "arrow-color" "BLUE") + 1 wx:const-solid))) + +(define nosrc-arrow-brush.pen + (cons + (make-object wx:brush% (get-resource-maybe "nosource-arrow-color" "RED") + wx:const-solid) + (make-object wx:pen% (get-resource-maybe "nosource-arrow-color" "RED") + 1 wx:const-solid))) + +(define nodest-arrow-brush.pen + (cons + (make-object wx:brush% (get-resource-maybe "nodest-arrow-color" "RED") + wx:const-solid) + (make-object wx:pen% (get-resource-maybe "nodest-arrow-color" "RED") + 1 wx:const-solid))) + +;; ------------------------------------------------------------ + +(define flow-report-on #t) + +(define (generic-flow-report msg) + (when flow-report-on + (wx:message-box + msg "Error" + (bitwise-ior wx:const-ok wx:const-icon-exclamation)))) + +(define (generic-flow-report-filter msg) + (generic-flow-report + (format "~a~a!" + msg + (if (analysis-filter-on?) + (format " with values matching filter '~a'" (analysis-filter-on?)) + "")))) + +(define (report-no-parents) + (generic-flow-report-filter "No parents")) + +(define (report-no-children) + (generic-flow-report-filter "No children")) + +(define (report-no-ancestors) + (generic-flow-report-filter "No ancestors")) + +(define (report-no-descendants) + (generic-flow-report-filter "No descendants")) + +(define (report-type-does-not-contain-filter) + (generic-flow-report + (if (analysis-filter-on?) + (format "Expression has no values matching filter '~a'!" + (analysis-filter-on?)) + "Expression has no values!"))) + +(define (report-no-path-to-source) + (generic-flow-report + (if (analysis-filter-on?) + (format "No path to source for values matching filter '~a'!" + (analysis-filter-on?)) + "No path to source!"))) + +(define lookup-ftype + (lambda (ftype) + (pretty-debug-gui `(lookup-ftype ,(FlowType->pretty ftype))) + (assert (FlowType? ftype) 'lookup-ftype ftype) + (let ([r (FlowType-type-annotation ftype)]) + (pretty-debug-gui `(lookup-ftype-returning ,r)) + (assert r 'lookup-ftype 'r= r ftype) + r))) + +;; ====================================================================== +;; Edit class with flow arrows +;; sets mode to scheme mode + +(define wx:const-break-special 8) + +(define flow-arrow:media-edit% + (class arrow:media-edit% (margin arg-main arg-canvas) + (inherit + edit-sequence last-position change-style + find-wordbreak set-mode set-wordbreak-map + relocate-change-style + real-start-position + last-line position-line line-start-position frame-pos->source-pos + draw-arrows add-arrow delete-arrow + margin-length + get-keymap get-frame relocate-set-position + get-start-position get-end-position) + + (public + + main + canvas + + [list-type-annotations '()] + [list-check-annotations '()] + + ;; ---------- + ;; dynamic allocation of jump positions + + [vec-free-jump-posns '()] + [jump-posn-free? + (lambda (i) + (and + (>= i 0) + (< i (vector-length vec-free-jump-posns)) + (vector-ref vec-free-jump-posns i)))] + [alloc-jump-posn + ;; input and output in terms of relocate positions + ;; not absolute positions + (lambda (posn) + (let ([line (position-line (real-start-position posn))]) + (unless (vector? vec-free-jump-posns) + (set! vec-free-jump-posns (make-vector (last-line) #t))) + (let* ([free-line + (recur loop ([i 0]) + (cond + [(= i (vector-length vec-free-jump-posns)) + (mrspidey:error "Out of jump points")] + [(jump-posn-free? (+ line i)) (+ line i)] + [(jump-posn-free? (- line i)) (- line i)] + [else (loop (add1 i))]))] + [_ (vector-set! vec-free-jump-posns free-line #f)] + [start (line-start-position free-line)] + [src (frame-pos->source-pos (+ margin-length start))]) + (pretty-debug-gui + `(alloc-jump-posn ,posn ,line ,free-line ,start ,src)) + (values + src + (lambda () + (assert (not (vector-ref vec-free-jump-posns free-line)) + 'free-jump-posn free-line) + (vector-set! vec-free-jump-posns free-line #t))))))] + + ;; ---------- + + [add-flow-arrow-part + (lambda ( src-posn src-clickback + dest-posn dest-clickback + brush.pen ) + (pretty-debug-gui + `(add-flow-arrow-part ,src-posn ,dest-posn)) + (assert + (and + (or (number? src-posn) (eq? src-posn 'jump)) + (or (number? dest-posn) (eq? dest-posn 'jump)) + (or (number? src-posn) (number? dest-posn))) + 'add-flow-arrow-part + src-posn dest-posn) + (let*-vals + ([(src-posn free-src start-dx start-dy) + (if (number? src-posn) + (values + src-posn (lambda () (void)) + arrow-start-dx arrow-start-dy) + (let*-vals ([(p free) (alloc-jump-posn dest-posn)]) + (values + p free + jump-start-dx jump-start-dy)))] + [(dest-posn free-dest end-dx end-dy) + (if (number? dest-posn) + (values + dest-posn (lambda () (void)) + arrow-end-dx arrow-end-dy) + (let*-vals ([(p free) (alloc-jump-posn src-posn)]) + (values + p free + jump-end-dx jump-end-dy)))] + [arrow + (add-arrow + src-posn start-dx start-dy + dest-posn end-dx end-dy + arrow-delta + (car brush.pen) + (cdr brush.pen) + (dest-clickback dest-posn) + (src-clickback src-posn))]) + (lambda () (free-src) (free-dest) (delete-arrow arrow))))] + + ;; ----- shake it + [shake-it + (lambda () + (fluid-let ([flow-report-on #f]) + + (let* ([n (random (length list-type-annotations))] + [ta (nth list-type-annotations n)]) + (printf "(send ta show-type-refresh)~n") + (send ta show-type-refresh) + + (printf "(send ta copy-type-to-clipboard)~n") + (send ta copy-type-to-clipboard) + + (printf "(send ta delete-type-refresh)~n") + (send ta delete-type-refresh) + + (printf "(send ta parents-refresh)~n") + (send ta parents-refresh) + (delete-arrows) + + (printf "(send ta ancestors-refresh)~n") + (send ta ancestors-refresh) + (delete-arrows) + + (printf "(send ta shortest-path-source-refresh)~n") + (send ta shortest-path-source-refresh) + (delete-arrows) + + (printf "(send ta children-refresh)~n") + (send ta children-refresh) + (delete-arrows) + + (printf "(send ta descendants-refresh)~n") + (send ta descendants-refresh) + (delete-arrows))))] + + [send-ftype + (lambda (ftype method . args) + (pretty-debug-gui `(send-ftype ,(FlowType->pretty ftype))) + (assert (symbol? method) 'send-ftype ftype method args) + (apply (uq-ivar (lookup-ftype ftype) method) args))] + + [flush-type-cache + (lambda () + (for-each + (lambda (obj) (send obj flush-type)) + list-type-annotations))] + + [delete-types + (lambda () + (edit-sequence + (lambda () + (for-each + (lambda (obj) (send obj delete-type)) + list-type-annotations))))] + + [delete-arrows + (lambda () + (send main delete-arrows))] + + [add-type-annotation + (match-lambda + [($ type-annotation start end-first finish ftype) + '(pretty-debug-gui `(type-annotation + ,(zodiac:location-offset start) + ,(zodiac:location-offset end-first) + ,(zodiac:location-offset finish))) + (let ([obj (make-object type-annotation% + this + (zodiac:location-offset start) + (zodiac:location-offset end-first) + (add1 (zodiac:location-offset finish)) + ftype)]) + (set-FlowType-type-annotation! ftype obj) + (set! list-type-annotations (cons obj list-type-annotations)))])] + + [highlight + (lambda (start-pos name delta) + (cond + [(string=? name "(") + (let* ( [real-start (real-start-position start-pos)] + [rparen (mred:scheme-forward-match + this real-start (last-position))]) + (change-style delta real-start (add1 real-start)) + (if (number? rparen) + (change-style delta (sub1 rparen) rparen) + (printf "Can't match paren from ~s ~s~n" start-pos rparen)))] + [else + (let* ([endbox (box (real-start-position start-pos))] + [_ (find-wordbreak '() endbox wx:const-break-special)] + [startbox (box (unbox endbox))] + [_ (find-wordbreak startbox '() wx:const-break-special)]) + '(pretty-debug-gui `(highlight start-pos ,start-pos endbox ,endbox + startbox ,startbox)) + (change-style delta (unbox startbox) (unbox endbox)))]))] + + [add-check-annotation + (match-lambda + [(and annotation ($ check-annotation start name num)) + (set! list-check-annotations + (cons annotation list-check-annotations)) + (highlight (zodiac:location-offset start) name check-delta)])] + + [add-uncheck-annotation + (match-lambda + [($ uncheck-annotation start name) + (highlight (zodiac:location-offset start) name uncheck-delta)])] + + [next-check-annotation + (lambda () + (next-check-annotation-list + (get-end-position) < list-check-annotations 0))] + + [prev-check-annotation + (lambda () + (next-check-annotation-list + (get-start-position) > (reverse list-check-annotations) + (last-position)))] + + [next-check-annotation-list + (lambda (start cmp list-annotations wrap) + ;(pretty-print `(start ,start cmp ,cmp wrap ,wrap)) + (or + (ormap + (match-lambda + [($ check-annotation start-ann) + ;(pretty-print `(loop start ,start start-ann ,(zodiac:location-offset start-ann) ,(real-start-position (zodiac:location-offset start-ann)))) + (if (cmp start + (real-start-position + (zodiac:location-offset start-ann))) + ;; after current start + (begin + (relocate-set-position + (zodiac:location-offset start-ann)) + #t) + #f)]) + list-annotations) + (if wrap + (next-check-annotation-list wrap cmp list-annotations #f) + (wx:bell))))] + ) + + (sequence + (set! main arg-main) + (set! canvas arg-canvas) + (super-init margin) + (let ([wb (make-object wx:media-wordbreak-map%)]) + (for i 0 256 + (unless (or (char-whitespace? (integer->char i)) + (memv (integer->char i) '(#\( #\) #\;))) + (send wb set-map i + (+ (send wb get-map i) wx:const-break-special)))) + (set-wordbreak-map wb)) + ;;(set-mode (make-object mred:scheme-mode%)) + (let ([keymap (get-keymap)]) + (send keymap add-key-function + "next-check-annotation" + (lambda (edit event) + (send edit next-check-annotation))) + (send keymap map-function "tab" "next-check-annotation") + + (send keymap add-key-function + "prev-check-annotation" + (lambda (edit event) + (send edit prev-check-annotation))) + (send keymap map-function "s:tab" "prev-check-annotation") + (send keymap map-function "a:tab" "prev-check-annotation")) + + ))) + +;; ------------------------------------------------------------ +;; A hyperlink object + +(define cur-he #f) +(define te #f) + +(define type-annotation% + (class null (arg-edit start-arg end-first finish-arg ftype-arg) + (public + + edit ;; flow-arrow:media-edit% + start-pos + type-pos + ftype + + [type #f] + [type-snip #f] + [src->arrows '()] ;; Maps ftype of source to the arrow + [dest->arrows '()] ;; ditto + + ;; ----- communication with arrows + [add-source-arrow + (lambda (src arrow) + (set! src->arrows (cons (cons src arrow) src->arrows)))] + [add-dest-arrow + (lambda (dest arrow) + (set! dest->arrows (cons (cons dest arrow) dest->arrows)))] + + [remove-source-arrow + (lambda (arrow) + (set! src->arrows + (filter-map + (lambda (src.arrow) + (if (eq? (cdr src.arrow) arrow) #f src.arrow)) + src->arrows)))] + [remove-dest-arrow + (lambda (arrow) + (set! dest->arrows + (filter-map + (lambda (dest.arrow) + (if (eq? (cdr dest.arrow) arrow) #f dest.arrow)) + dest->arrows)))] + [remove-arrows + (for-each + (lambda (arrow) (send arrow delete)) + (append (map cdr src->arrows) (map cdr dest->arrows)))] + + [file-visable? + (lambda (filename) + (send (ivar edit main) filename->frame filename))] + + + ;; ----- Arrows + [add-flow-arrow + (lambda (src dest) + (pretty-debug-gui + `(type-annotation%:add-flow-arrow + ,(FlowType->pretty src) ,(FlowType->pretty dest))) + (send (ivar edit main) add-flow-arrow src dest))] + + ;; ------ Parents, ancestors + [shortest-path-source-refresh + (lambda () + ;; Show shortest path to a source + (let ([path (analysis-shortest-path ftype file-visable?)]) + ;; Returns list of ancestor Tvar-nums, last element is () + (cond + [(eq? path #f) + (report-type-does-not-contain-filter)] + [(null? path) + (report-no-path-to-source)] + [else + (send edit edit-sequence + (lambda () + (show-path path) + (send (ivar edit main) draw-arrows)))])))] + [show-path + (lambda (path) + (unless (null? path) + (let ([parent (car path)]) + (unless (null? parent) + (add-flow-arrow parent ftype) + (send edit send-ftype parent 'show-path (cdr path))))))] + + [calc-parents + (lambda () + (analysis-parents ftype file-visable?))] + + [add-parent-arrows + (lambda () + (for-each (lambda (p) (add-flow-arrow p ftype)) (calc-parents)))] + + [parents-refresh + (lambda () + ;; (pretty-print `(parents-refresh debugging ,debugging)) + (pretty-debug-gui `(parents-refresh ,ftype ,type-snip)) + (if (null? (calc-parents)) + (report-no-parents) + (send edit edit-sequence + (lambda () + (add-parent-arrows) + (send (ivar edit main) draw-arrows)))))] + + [ancestors-refresh + (lambda () + (let ([arrows (analysis-ancestors ftype file-visable?)]) + (if (null? arrows) + (report-no-ancestors) + (send edit edit-sequence + (lambda () + (for-each + (lambda (arrow) (apply add-flow-arrow arrow)) + arrows) + (send (ivar edit main) draw-arrows))))))] + + ;; ------ Children, descendants + + [calc-children + (lambda () (analysis-children ftype file-visable?))] + + [add-child-arrows + (lambda () + (for-each (lambda (p) (add-flow-arrow ftype p)) (calc-children)))] + + [children-refresh + (lambda () + (pretty-debug-gui `(children ,ftype ,type-snip)) + (if (null? (calc-children)) + (report-no-children) + (send edit edit-sequence + (lambda () + (add-child-arrows) + (send (ivar edit main) draw-arrows)))))] + + [descendants-refresh + (lambda () + (let ([arrows (analysis-descendants ftype file-visable?)]) + (if (null? arrows) + (report-no-descendants) + (send edit edit-sequence + (lambda () + (for-each + (lambda (arrow) (apply add-flow-arrow arrow)) + arrows) + (send (ivar edit main) draw-arrows))))))] + + ;; ------ Type stuff + + [flush-type (lambda () (set! type #f))] + [calc-type + (lambda () + (unless type + (assert (FlowType? ftype) 'type-annotation% ftype) + (set! type (analysis-callback ftype))) + type)] + + ;; ------ This snip stuff + [delete-type-refresh + (lambda () + (when type-snip + (send edit edit-sequence delete-type)))] + [delete-type + (lambda () + (when type-snip + (send edit relocate-delete-snip type-pos) + (set! type-snip #f) + + ))] + [arrow-zoom (lambda () (highlight))] + [current-focus (lambda () (highlight))] + [highlight + (lambda () + (set! te edit) + (let* ( [frame (send edit get-frame)] + [frame (send (ivar edit main) filename->frame + (send edit get-filename))]) + (assert (is-a? frame wx:frame%) 'highlight frame) + (send frame show #t) + (send edit relocate-set-position start-pos) + (send edit relocate-flash-on start-pos type-pos #f #t 50000)))] + + [get-start-pos (lambda () start-pos)] + [get-type-pos (lambda () type-pos)] + + [move-before-snip + (lambda () + (pretty-debug-gui `(move-before-snip)) + (send edit relocate-set-position start-pos) + (send edit set-caret-owner '()))] + + [show-type + (lambda () + (unless type-snip + + (let* ([type (calc-type)] + [_ (set! type-snip (make-object mred:media-snip%))] + [snip-edit (make-object mred:searching-edit%)] + [_ (send type-snip set-media snip-edit)]) + + (dynamic-wind + (lambda () + (send snip-edit begin-edit-sequence)) + (lambda () + ;; put type in the box + (send snip-edit insert type) + ;; delete newline + (send snip-edit delete) + ;; set style + (send snip-edit change-style base-delta + 0 (string-length type)) + (send snip-edit change-style type-delta 0 (string-length type)) + ;; add clickback + (send snip-edit set-clickback + 0 (string-length type) + (lambda ignore + (popup-type/arrow-menu type-pos offset-menu-snip-y)) + '() + #t)) + (lambda () + (send snip-edit end-edit-sequence) + (send snip-edit lock #t)))) + + (send edit edit-sequence + (lambda () + (send edit relocate-insert-snip type-snip type-pos) + (send edit relocate-change-style normal-delta + type-pos (add1 type-pos))))))] + + [show-type-refresh + (lambda () + (send edit edit-sequence + (lambda () + (show-type) + ;;(highlight) + )))] + + [copy-type-to-clipboard + (lambda () + (let* ([snip-edit (send type-snip get-this-media)]) + (send snip-edit copy #f 0 0 (send snip-edit last-position))))] + + ;; ---------- Making the popup menus + [popup-type/arrow-menu + (lambda (where offset-menu) + ;; where is source text position for menu + (let ([menu (make-object wx:menu% '() menu-callback)] + [xb (box 0)] + [yb (box 0)]) + (if type-snip + (send menu append + SELECT-CLOSE-VALUE-SET + "Close Value Set" + "Close this value set invariant box") + (send menu append + SELECT-SHOW-VALUE-SET "Show Value Set" + "Show the expressions value set invariant")) + (send* menu + (append-separator) + (append SELECT-PARENTS "Parents" + "Show the immediate sources of this type") + (append SELECT-ANCESTORS "Ancestors" + "Show all sources of this type") + (append SELECT-PATH-SOURCE "Path to Source" + "Show shortest path to a source constructor expression") + (append-separator) + (append SELECT-CHILDREN "Children" + "Show the immediate expressions to which this type may flow") + (append SELECT-DESCENDANTS "Descendants" + "Show all expressions to which this type may flow") + (append-separator)) + (when type-snip + (send menu append + SELECT-COPY-VALUE-SET + "Copy Value Set" + "Copy the value set invariant to the clipboard") + (send menu append + SELECT-RECOMPUTE-VALUE-SET + "Recompute Value Set" + "Recompute the expressions value set invariant")) + (send menu append SELECT-CLOSE-MENU "Close Menu") + + ;; Get global location of expr + (send edit position-location + (send edit real-start-position where) + xb yb) + (pretty-debug-gui + `(source-pos ,where + frame-pos ,(send edit real-start-position where))) + + (pretty-debug-gui `(position-location returns ,xb ,yb)) + ;; Convert to local location + (send edit local-to-global xb yb) + (pretty-debug-gui `(local-to-global returns ,xb ,yb)) + (send (ivar edit canvas) popup-menu menu + (unbox xb) (+ (unbox yb) offset-menu))))] + + [menu-callback + (lambda (menu command) + (set! cur-he this) + (move-before-snip) + (let ([arg (send command get-command-int)]) + (pretty-debug-gui `(command ,arg)) + (wrap-busy-cursor + (lambda () + (cond + [(= arg SELECT-SHOW-VALUE-SET) (show-type-refresh)] + [(= arg SELECT-CLOSE-VALUE-SET) (delete-type-refresh)] + [(= arg SELECT-RECOMPUTE-VALUE-SET) + (delete-type-refresh) + (show-type-refresh)] + [(= arg SELECT-COPY-VALUE-SET) (copy-type-to-clipboard)] + [(= arg SELECT-PARENTS) (parents-refresh)] + [(= arg SELECT-ANCESTORS) (ancestors-refresh)] + [(= arg SELECT-PATH-SOURCE) (shortest-path-source-refresh)] + [(= arg SELECT-CHILDREN) (children-refresh)] + [(= arg SELECT-DESCENDANTS) (descendants-refresh)] + [(= arg SELECT-CLOSE-MENU) (void)])))))] + ) + + (sequence + + (unless (FlowType? ftype-arg) + (pretty-debug-gui `(bad-ftype ,ftype-arg ,(FlowType? ftype-arg)))) + (assert (FlowType? ftype-arg) 'type-annotation-init1 ftype-arg) + (set! edit arg-edit) + + (set! start-pos start-arg) + (set! type-pos finish-arg) + (set! ftype ftype-arg) + (assert (FlowType? ftype) 'type-annotation-init ftype ftype-arg) + + (send edit relocate-change-style type-link-delta start-arg end-first) + (send edit relocate-set-clickback start-arg end-first + (lambda ignore + (popup-type/arrow-menu start-arg offset-menu-exp-y)) + '() + #t)))) + +;; ------------------------------------------------------------ + +(define last-arrow-popup (void)) + +(define flow-arrow% + (class null (arg-main arg-src arg-dest) + (public + + src ; points to type-annotation% object + dest + main + delete-arrow-thunks + + ;; Deletion + [delete-local + (lambda () + ;; tell endpoints we're dead + (let ( [src-ta (lookup-ftype src)] + [dest-ta (lookup-ftype dest)]) + (when (is-a? src-ta type-annotation%) + (send src-ta remove-dest-arrow this)) + (when (is-a? dest-ta type-annotation%) + (send dest-ta remove-source-arrow this))) + ;; delete + (assert (list? delete-arrow-thunks) 1 delete-arrow-thunks) + (for-each (lambda (th) (th)) delete-arrow-thunks) + )] + [delete + (lambda () + (send main delete-arrow this))] + [delete-refresh + (lambda () + (pretty-debug-gui '(delete-refresh)) + (delete) + (send main draw-arrows))] + + ;; ---------- + + [update + ;; Change if necy due to loaded file + (lambda () + (let ( [src-ta (lookup-ftype src)] + [dest-ta (lookup-ftype dest)]) + (pretty-debug-gui `(flow-arrow%:update ,src-ta ,dest-ta)) + (when (and + (string? src-ta) + (send main filename->frame src-ta)) + ;; file loaded, so delete this arrow + show parents of dest + (delete) + (send dest-ta add-parent-arrows)) + (when (and + (string? dest-ta) + (send main filename->frame dest-ta)) + ;; file loaded, so delete this arrow + show children of src + (delete) + (send src-ta add-child-arrows))))] + + ;; ---------- + + [popup-load-menu + (lambda (edit offsets where direction filename) + ;; direction is "parent" or "child" + (assert (not (send main filename->edit filename))) + (let* ( [menu-callback + (lambda (menu command) + (wrap-busy-cursor + (lambda () + (send main add-frame + (send main filename->fileinfo filename) + #t))))] + [menu (make-object wx:menu% '() menu-callback)] + [xb (box 0)] + [yb (box 0)]) + (send menu append + LOAD-NONLOCAL-FILE + (format "Load ~s containing ~a" + (file-name-from-path filename) direction)) + + ;; Get global location of expr + (send edit position-location + (send edit real-start-position where) + xb yb) + (send edit local-to-global xb yb) + (pretty-debug-gui `(local-to-global returns ,xb ,yb)) + + (send (ivar edit canvas) popup-menu menu + (+ (unbox xb) (car offsets)) + (+ (unbox yb) (cdr offsets)))))] + + [popup-zoom-menu + (lambda (edit offsets where to direction) + + ;; direction is "parent" or "child" + (let* ( [menu-callback + (lambda (menu command) + (wrap-busy-cursor + (lambda () + (send to arrow-zoom))))] + [menu (make-object wx:menu% '() menu-callback)] + [xb (box 0)] + [yb (box 0)]) + (set! last-arrow-popup + (lambda () + (send this popup-zoom-menu edit offsets where to direction))) + (send menu append + ZOOM-TO-FILE + (format "Zoom to ~a in ~s" + direction + (file-name-from-path + (send (ivar to edit) get-filename)))) + + ;; Get global location of expr + (send edit position-location + (send edit real-start-position where) + xb yb) + (send edit local-to-global xb yb) + (pretty-debug-gui `(local-to-global returns ,xb ,yb)) + + (send (ivar edit canvas) popup-menu menu + (+ (unbox xb) (car offsets)) + (+ (unbox yb) (cdr offsets)))))] + ) + + (sequence + (assert (is-a? arg-main MrSpidey%)) + (assert (FlowType? arg-src) arg-src) + (assert (FlowType? arg-dest) arg-dest) + (pretty-debug-gui + `(flow-arrow% ,arg-main + ,(FlowType->pretty arg-src) ,(FlowType->pretty arg-dest))) + (set! main arg-main) + (set! src arg-src) + (set! dest arg-dest) + + ;; 4 cases for arrow + ;; local - simple case + ;; source-half - just show arrow coming in from edge + ;; sink-half - just show arrow going to edge + ;; both-halves - show incoming and outgoing arrows in resp edits + + (let* ( [src-ta (lookup-ftype src)] + [dest-ta (lookup-ftype dest)]) + + (when (or + (and + (is-a? src-ta type-annotation%) + (assq dest-ta (ivar src-ta dest->arrows))) + (and + (is-a? dest-ta type-annotation%) + (assq src-ta (ivar dest-ta src->arrows)))) + + ;; Arrow already there + (raise (make-exn:flow-arrow-exists))) + + ;; Not already there - first tell endpoints we're here + (when (is-a? src-ta type-annotation%) + (send src-ta add-dest-arrow dest-ta this)) + (when (is-a? dest-ta type-annotation%) + (send dest-ta add-source-arrow src-ta this)) + + (pretty-debug-gui + `(src-ta ,src-ta + dest-ta ,dest-ta + srctadest->arrows + ,(and + (is-a? src-ta type-annotation%) + (map car (ivar src-ta dest->arrows))) + desttasrc->arrows + ,(and + (is-a? dest-ta type-annotation%) + (map car (ivar dest-ta src->arrows))))) + + (let* + ( + [ta->edit-or-false + (lambda (ta) + (cond + [(string? ta) + ;; If ftype is from .za file, + ;; corresponding edit should not exist yet + (assert (not (send main filename->edit ta))) + #f] + [(is-a? ta type-annotation%) + ;; Is a type-annotation + (ivar ta edit)]))] + [src-edit (ta->edit-or-false src-ta)] + [dest-edit (ta->edit-or-false dest-ta)]) + + (set! delete-arrow-thunks + (cond + [(and src-edit (not dest-edit)) + ;; sink-half arrow + (let* ( [clickback-where + (lambda (offsets) + (lambda (where) + (lambda (event) + (cond + [(send event button-down? 1) + (popup-load-menu + src-edit offsets where + "child" dest-ta)] + [(send event button-down? 3) + (delete-refresh) + #t] + [else #f]))))]) + (list + (send src-edit add-flow-arrow-part + (send src-ta get-start-pos) + (clickback-where offsets-load-menu-src-known) + 'jump + (clickback-where offsets-load-menu-dest-jump) + nodest-arrow-brush.pen)))] + + [(and dest-edit (not src-edit)) + ;; sink-half arrow + (let* ( [clickback-where + (lambda (offsets) + (lambda (where) + (lambda (event) + (cond + [(send event button-down? 1) + (popup-load-menu + dest-edit offsets where + "parent" src-ta)] + [(send event button-down? 3) + (delete-refresh) + #t] + [else #f]))))]) + (list + (send dest-edit add-flow-arrow-part + 'jump + (clickback-where offsets-load-menu-src-jump) + (send dest-ta get-start-pos) + (clickback-where offsets-load-menu-dest-known) + nosrc-arrow-brush.pen)))] + + [(and src-edit dest-edit) + ;; local or non-local arrow + (let* ( [clickback-zoom + (lambda (to) + (lambda (posn) + (lambda (event) + (cond + [(send event button-down? 1) + (send to arrow-zoom)] + [(send event button-down? 3) + (delete-refresh) + #t] + [else #f]))))]) + + (cond + [(eq? src-edit dest-edit) + ;; local arrow + (list + (send src-edit add-flow-arrow-part + (send src-ta get-start-pos) + (clickback-zoom dest-ta) + (send dest-ta get-start-pos) + (clickback-zoom src-ta) + arrow-brush.pen))] + + [else + ;; non-local arrow + (let* + ( [src-posn (send src-ta get-start-pos)] + [dest-posn (send dest-ta get-start-pos)] + [clickback-where + (lambda (edit offsets to direction) + (lambda (where) + (lambda (event) + (cond + [(send event button-down? 1) + (popup-zoom-menu + edit offsets where to direction)] + [(send event button-down? 3) + (delete-refresh) + #t] + [else #f]))))]) + (list + (send src-edit add-flow-arrow-part + src-posn + (clickback-where + src-edit + offsets-load-menu-src-known + dest-ta "child") + 'jump + (clickback-where + src-edit + offsets-load-menu-dest-jump + dest-ta "child") + arrow-brush.pen) + (send dest-edit add-flow-arrow-part + 'jump + (clickback-where + dest-edit + offsets-load-menu-src-jump + src-ta "parent") + dest-posn + (clickback-where + dest-edit + offsets-load-menu-dest-known + src-ta "parent") + arrow-brush.pen)))]))] + [else + (assert #f 'flow-arrow% src-edit dest-edit)] + )) + (assert (list? delete-arrow-thunks) 2 delete-arrow-thunks) + ))))) + +;; ====================================================================== + + diff --git a/collects/mrspidey/Gui/arrow.ss b/collects/mrspidey/Gui/arrow.ss new file mode 100644 index 0000000..41b01db --- /dev/null +++ b/collects/mrspidey/Gui/arrow.ss @@ -0,0 +1,137 @@ +; arrow.ss +; defines arrow:media-edit%, an extention of graphics:media-edit% with arrows +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define arrow:media-edit% + (let* ([pi (* 2 (asin 1))] + [arrow-head-angle (/ pi 8)] + [cos-angle (cos arrow-head-angle)] + [sin-angle (sin arrow-head-angle)] + [arrow-head-size 10] + [arrow-root-radius 3.5] + [cursor-arrow (make-object wx:cursor% wx:const-cursor-arrow)]) + + (class-asi graphics:media-edit% + (inherit delete-graphic draw-graphics add-graphic set-cursor) + (public + [delete-arrow (lambda (arrow) (delete-graphic arrow))] + [draw-arrows (lambda () (draw-graphics))] + [add-arrow + (lambda (start-pos start-dx start-dy + end-pos end-dx end-dy + delta brush pen + clickback-head clickback-root) + (pretty-debug-gui (list 'add-arrow + start-pos start-dx start-dy + end-pos end-dx end-dy + delta clickback-head clickback-root)) + (add-graphic + (list start-pos end-pos) + (match-lambda + [((start-x . start-y) (end-x . end-y)) + (pretty-debug-gui + `(locs ,start-x ,start-y ,end-x ,end-y + ,start-dx ,start-dy ,end-dx ,end-dy)) + (let* + ([start-x (+ start-x start-dx)] + [start-y (+ start-y start-dy)] + [end-x (+ end-x end-dx)] + [end-y (+ end-y end-dy)] + [ofs-x (- start-x end-x)] + [ofs-y (- start-y end-y)] + [len (sqrt (+ (* ofs-x ofs-x) (* ofs-y ofs-y)))] + [ofs-x (/ ofs-x len)] + [ofs-y (/ ofs-y len)] + [head-x (* ofs-x arrow-head-size)] + [head-y (* ofs-y arrow-head-size)] + [end-x (+ end-x (* ofs-x delta))] + [end-y (+ end-y (* ofs-y delta))] + [pt1 (make-object wx:point% end-x end-y)] + [pt2 (make-object + wx:point% + (+ end-x (* cos-angle head-x) + (* sin-angle head-y)) + (+ end-y (- (* sin-angle head-x)) + (* cos-angle head-y)))] + [pt3 (make-object + wx:point% + (+ end-x (* cos-angle head-x) + (- (* sin-angle head-y))) + (+ end-y (* sin-angle head-x) + (* cos-angle head-y)))] + [pts (list pt1 pt2 pt3)] + [draw-fn + (lambda (dc dx dy) + '(pretty-debug-gui + (list 'draw-line (+ start-x dx) (+ start-y dy) + (+ end-x dx) (+ end-y dy))) + (let ([old-brush (send dc get-brush)] + [old-pen (send dc get-pen)] + [old-logfn (send dc get-logical-function)]) + (send dc set-brush brush) + (send dc set-pen pen) + ;; (send dc set-logical-function wx:const-or) + (send dc draw-line + (+ start-x dx) (+ start-y dy) + (+ end-x dx) (+ end-y dy)) + (send dc draw-polygon pts dx dy) + (send dc draw-ellipse + (- (+ start-x dx) arrow-root-radius) + (- (+ start-y dy) arrow-root-radius) + (* 2 arrow-root-radius) + (* 2 arrow-root-radius)) + (send dc set-brush old-brush) + (send dc set-pen old-pen) + (send dc set-logical-function old-logfn)))] + [on-head? + (lambda (x y) + (let* + ([xs (map (lambda (pt) (send pt get-x)) pts)] + [ys (map (lambda (pt) (send pt get-y)) pts)] + [min-x (apply min xs)] + [min-y (apply min ys)] + [max-x (apply max xs)] + [max-y (apply max ys)]) + (and (>= x min-x) + (<= x max-x) + (>= y min-y) + (<= y max-y))))] + [on-root? + (lambda (x y) + (and (>= x (- start-x arrow-root-radius)) + (<= x (+ start-x arrow-root-radius)) + (>= y (- start-y arrow-root-radius)) + (<= y (+ start-y arrow-root-radius))))] + [event-fn + (lambda (event x y) + (cond + [(on-head? x y) + (set-cursor cursor-arrow) + (clickback-head event)] + [(on-root? x y) + (set-cursor cursor-arrow) + (clickback-root event)] + [else + ;; Back to default cursor + ;; (set-cursor '()) + #f]))]) + + ;; Return draw-thunk and event function + (cons draw-fn event-fn))])))])))) + +;; ---------------------------------------- diff --git a/collects/mrspidey/Gui/deltas.ss b/collects/mrspidey/Gui/deltas.ss new file mode 100644 index 0000000..dd4db2b --- /dev/null +++ b/collects/mrspidey/Gui/deltas.ss @@ -0,0 +1,108 @@ +; deltas.ss +; Loads configuration from .Xresources +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +;; Given a resource name, this returns a style delta corresponding to the +;; attributes of the file or the default if there are none. + +(define (get-resource-maybe s2 default) + (let ([val-box (box default)]) + (wx:get-resource + (if (wx:colour-display?) "mrspidey" "mrspidey-bw") + s2 + val-box) + (unbox val-box))) + +(define delta-eval-namespace (make-namespace)) +(parameterize ([current-namespace delta-eval-namespace]) + (invoke-open-unit/sig wx@ wx)) + +(define delta-add-string! + (lambda (delta string) + (let ([p (open-input-string string)]) + (recur loop () + (let ([e (read p)]) + (unless (eof-object? e) + (apply (uq-ivar delta (car e)) (eval `(list ,@(cdr e)) delta-eval-namespace)) + (loop))))))) + +(define set-resource-delta + (lambda (name default-string default-string-bw delta) + (delta-add-string! delta + (if (wx:colour-display?) + default-string + default-string-bw)) + (delta-add-string! delta (get-resource-maybe name "")))) + +(define make-resource-delta + (lambda (name default-string default-string-bw) + (let ([delta (make-object wx:style-delta% + wx:const-change-alignment wx:const-align-top)]) + '(set-resource-delta "base-delta" + "(set-delta wx:const-change-normal) \ + (set-delta wx:const-change-family wx:const-modern) \ + (set-alignment-on wx:const-align-top) " + "(set-delta wx:const-change-normal) \ + (set-delta wx:const-change-family wx:const-modern) \ + (set-alignment-on wx:const-align-top)" + delta) + (set-resource-delta name default-string default-string-bw delta) + delta))) + +;; ---------------------------------------------------------------------- +;; These deltas are defined when the application starts, either from defaults +;; or from resources, their names and their strings agree. + +(define base-delta + (make-resource-delta "base-delta" + "(set-delta wx:const-change-normal) \ + (set-delta wx:const-change-family wx:const-modern) \ + (set-alignment-on wx:const-align-top) " + "(set-delta wx:const-change-normal) \ + (set-delta wx:const-change-family wx:const-modern) \ + (set-alignment-on wx:const-align-top)")) + +(define normal-delta + (make-resource-delta "normal-delta" + "" "")) + +(define type-link-delta + (make-resource-delta "type-link-delta" + "(set-delta wx:const-change-bold)" + "(set-delta wx:const-change-bold)")) +(define type-delta + (make-resource-delta "type-link-delta" + "" + "")) + +(define check-delta + (make-resource-delta "check-delta" + "(set-delta-foreground \"RED\")" + "(set-delta wx:const-change-underline 1)")) +(define uncheck-delta + (make-resource-delta "uncheck-delta" + "(set-delta-foreground \"FORESTGREEN\")" + "")) + +(define check-link-delta + (make-resource-delta "check-link-delta" + "(set-delta-foreground \"BLUE\") \ + (set-delta wx:const-change-underline 1)" + "(set-delta wx:const-change-underline 1)")) + +;; ---------------------------------------------------------------------- diff --git a/collects/mrspidey/Gui/dyn-edit.ss b/collects/mrspidey/Gui/dyn-edit.ss new file mode 100644 index 0000000..a91b54d --- /dev/null +++ b/collects/mrspidey/Gui/dyn-edit.ss @@ -0,0 +1,193 @@ +; dyn-edit +; +; Defines spidey:dynamic+margin-edit%, a subclass of spidey:static-edit% +; with an insert-line method that also inserts a margin +; and it handles adding and deleting snips +; while still allowing static positions in the buffer +; +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define spidey:dynamic+margin-edit% + (class spidey:static-edit% (arg-margin . init-args) + (inherit + set-auto-set-wrap + load-file last-position position-line + lock get-style-list + begin-edit-sequence end-edit-sequence edit-sequence + + change-style + set-clickback + flash-on + set-position + scroll-to-position + get-text + insert + delete + set-tabs + ) + + (public + ;; ---------- + margin + margin-length + ;[margin " "] + ;[margin-length 2] + + ;; keeps a list of all the snips in their source-locations + [sniplist ()] + + [insert-line + (lambda (s) + (insert margin) + (insert s) + (insert (string #\newline)))] + + ;; ---------- + + [account-for-margin + (lambda (pos) + (recur loop ([try pos]) + ;;(pretty-debug-gui `(accout-for-margin ,pos ,try)) + (let ([better + (+ pos + (* margin-length (add1 (position-line (+ try 0)))))]) + (if (= better try) + try + (loop better)))))] + [real-start-position + (lambda (pos) + (account-for-margin + (let loop ([l sniplist]) + (cond + [(null? l) pos] + [(> pos (car l)) (add1 (loop (cdr l)))] + [else (loop (cdr l))]))))] + [real-end-position + (lambda (pos) + (account-for-margin + (let loop ([l sniplist]) + (cond + [(null? l) pos] + [(>= pos (car l)) (add1 (loop (cdr l)))] + [else (loop (cdr l))]))))] + [old-real-end-position + (lambda (pos) + (let ([pos pos]) + (let loop ([l sniplist][pos pos]) + (cond + [(null? l) (account-for-margin pos)] + [(>= pos (car l)) + (loop (cdr l) (add1 pos))] + [else (loop (cdr l) pos)]))))] + [frame-pos->source-pos + (lambda (pos) + (assert (number? pos) 'frame-pos->source-pos) + (let ([pos (- pos (* margin-length (add1 (position-line pos))))]) + (let loop ([l sniplist]) + (cond + [(null? l) pos] + [(> pos (car l)) + (sub1 (loop (cdr l)))] + [else (loop (cdr l))]))))] + + ;; ---------- + + [relocate-change-style + (lambda (delta src-start src-end) + (let ([s (real-start-position src-start)] + [e (real-end-position src-end)]) + (pretty-debug-gui `(change-style ,src-start ,src-end ,s ,e)) + (change-style delta s e)))] + + [relocate-set-clickback + (lambda (src-start src-end . args) + (apply set-clickback + (real-start-position src-start) + (real-end-position src-end) + args))] + [relocate-flash-on + (lambda (src-start src-end a b c) + (flash-on (real-start-position src-start) + (real-end-position src-end) a b c))] + [relocate-scroll-to-position + (lambda (pos) + (let ([real-pos (real-start-position pos)]) + '(pretty-print `(scroll-to-position ,pos ,real-pos)) + (set-position real-pos) + (scroll-to-position real-pos)))] + ;; + ;; watch this function...... + [relocate-set-position + (opt-lambda + (pos [end -1][eol #f][scroll #t]) + (let ([end (if (= end -1) -1 (real-end-position end))]) + (set-position (real-start-position pos) end + eol scroll)))] + [match-paren-forward + (lambda (source-start) + (frame-pos->source-pos (mred:scheme-forward-match + this (real-start-position source-start) + (last-position))))] + + [relocate-get-text + (opt-lambda ([start -1][end -1][flat #f]) + (get-text (real-start-position start) + (real-end-position end) flat))] + [select-snip + (lambda (pos snip) + (edit-sequence + (lambda () + (send (send snip get-this-media) own-caret #f) + (set-position + (real-end-position pos) (real-start-position pos)))))] + [relocate-insert-snip + (lambda (snip pos) + ;;(lock #f) + (when (member pos sniplist) + (error "Cannot put two snips in the same position~n")) + (let ([real-pos (real-start-position pos)]) + (set! sniplist (cons pos sniplist)) + (insert snip real-pos)) + ;;(lock #t) + )] + [relocate-delete-snip + (lambda (pos) + (unless (member pos sniplist) + (error "Cannot remove snip from ~s" pos)) + (set! sniplist (remv pos sniplist)) + (let ([pos (real-start-position pos)]) + (delete pos (add1 pos))))] + ) + + (sequence + (apply super-init init-args) + (set! margin arg-margin) + (set! margin-length (string-length margin)) + + (set-auto-set-wrap #f) + ;; set-tabs doesn't work right past list of specified tabs + ;; so specify all tabs to column 200 + (set-tabs + (recur loop ([p margin-length]) + (if (< p 200) + (cons p (loop (+ p 8))) + '())) + 8 + #f) + ))) + diff --git a/collects/mrspidey/Gui/graphics.ss b/collects/mrspidey/Gui/graphics.ss new file mode 100644 index 0000000..47c7728 --- /dev/null +++ b/collects/mrspidey/Gui/graphics.ss @@ -0,0 +1,147 @@ +; graphics.ss +; Defines graphics:media-edit%, a subclass of spidey:dynamic+margin-edit% +; with facilities for graphics on top of text +; +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define-structure (graphic pos* locs->thunks draw-fn click-fn)) + +(define graphics:media-edit% + (class spidey:dynamic+margin-edit% args + (inherit set-cursor) + (rename + [super-after-insert after-insert] + [super-after-delete after-delete] + [super-on-paint on-paint] + [super-on-event on-event] + [super-resized resized] + [super-size-cache-invalid size-cache-invalid]) + + (public + [graphics-list ()] + [pos->locs + (lambda (pos) + (let* ([xb (box 0)] + [yb (box 0)] + [real-pos (send this real-start-position pos)] ) + (send this position-location real-pos xb yb #t) + (pretty-debug-gui + `(pos->locs ,pos ,real-pos ,(unbox xb) ,(unbox yb))) + (cons (unbox xb) (unbox yb))))] + [calc-graphic-thunks! + (lambda (graphic) + (match-let* + ([locs (map pos->locs (graphic-pos* graphic))] + [locs->thunks (graphic-locs->thunks graphic)] + [(draw-fn . click-fn) (locs->thunks locs)]) + (set-graphic-draw-fn! graphic draw-fn) + (set-graphic-click-fn! graphic click-fn)))] + [recalc-graphics + (lambda () + '(pretty-debug-gui `(recalc-graphics ,@graphics-list)) + (for-each calc-graphic-thunks! graphics-list))] + [add-graphic + (lambda (pos* locs->thunks) + (pretty-debug-gui (list 'add-graphic pos* locs->thunks)) + (let ([graphic (make-graphic pos* locs->thunks 0 0)]) + (calc-graphic-thunks! graphic) + (set! graphics-list (cons graphic graphics-list)) + graphic))] + [delete-graphic + (lambda (graphic) + '(pretty-debug-gui `(delete-graphic ,graphic)) + (set! graphics-list (remv graphic graphics-list)))] + [draw-graphics + (lambda () + (let ([admin (send this get-admin)]) + (pretty-debug-gui `(draw-graphics)) + (send this invalidate-bitmap-cache) + + ;; Kludge to get redrawing right + ;;(send super before-insert 0 1) + ;;(send super after-insert 0 1) + + '(unless (null? admin) + (send admin needs-update 0 0 100000 100000)) + '(pretty-debug-gui `(draw-graphics-done))))] + + ;; overwritten methods + [resized + (lambda (snip redraw-now) + '(pretty-debug-gui `(resized ,snip ,redraw-now)) + (super-resized snip redraw-now) + (recalc-graphics) + (when redraw-now (draw-graphics)))] + + [after-delete + (lambda (start len) + '(pretty-debug-gui `(after-delete ,start ,len)) + (super-after-delete start len) + (recalc-graphics) + (draw-graphics))] + + [after-insert + (lambda (start len) + '(pretty-debug-gui `(after-insert ,start ,len)) + (super-after-insert start len) + (recalc-graphics) + (draw-graphics))] + [size-cache-invalid + (lambda () + (super-size-cache-invalid) + (recalc-graphics))] + + [on-paint + (lambda (before dc left top right bottom dx dy draw-caret) + (super-on-paint + before dc left top right bottom + dx dy draw-caret) + (unless before + '(pretty-debug-gui `(on-paint)) + (for-each + (match-lambda + [($ graphic pos* locs->thunks draw-fn click-fn) + '(pretty-debug-gui (list 'on-paint-graphic pos*)) + (draw-fn dc dx dy)]) + graphics-list)))] + + [on-event + (lambda (event) + (set-cursor '()) + (let* ([admin (send this get-admin)] + [root-x (box 0)] + [root-y (box 0)]) + (send admin get-dc root-x root-y) + (let ([actual-x (+ (send event get-x) (unbox root-x))] + [actual-y (+ (send event get-y) (unbox root-y))]) + + ;; Now try to find a clickback to handle it + (let loop ([graphics graphics-list]) + (match graphics + [() (super-on-event event)] + [(($ graphic _ _ _ click-fn) . rest-graphics) + (or (click-fn event actual-x actual-y) + ;; Otherwise try next graphic + (loop rest-graphics))])))))] + ) + (sequence + ;;(pretty-debug-gui `(init graphic:media-edit% ,@init)) + (apply super-init args) + ))) + +;; ---------------------------------------- diff --git a/collects/mrspidey/Gui/load.ss b/collects/mrspidey/Gui/load.ss new file mode 100644 index 0000000..d1f282e --- /dev/null +++ b/collects/mrspidey/Gui/load.ss @@ -0,0 +1,29 @@ +;; load.ss - loads gui files +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(load-relative "deltas.ss") +(load-relative "statedit.ss") +(load-relative "dyn-edit.ss") +(load-relative "graphics.ss") +(load-relative "arrow.ss") +(load-relative "annotat.ss") +;(load-relative "paramenu.ss") +;(load-relative "option.ss") +(load-relative "prefs.ss") +(load-relative "Tframe.ss") +(load-relative "main.ss") diff --git a/collects/mrspidey/Gui/loadu.ss b/collects/mrspidey/Gui/loadu.ss new file mode 100644 index 0000000..a805d74 --- /dev/null +++ b/collects/mrspidey/Gui/loadu.ss @@ -0,0 +1,42 @@ +;; loadu.ss - loads graphic files into a unit +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define-signature mrspidey-gui^ (spidey)) + +(define mrspidey-gui@ + (unit/sig mrspidey-gui^ + (import + [wx : wx^] + [mred : mred^] + mzlib:unprefixed-core^ + mrspidey:sba^ + mrspidey:interaction^) + + (include "deltas.ss") + (include "statedit.ss") + (include "dyn-edit.ss") + (include "graphics.ss") + (include "arrow.ss") + (include "annotat.ss") + ;(include "paramenu.ss") + ;(include "option.ss") + (include "prefs.ss") + (include "Tframe.ss") + (include "main.ss") + + )) diff --git a/collects/mrspidey/Gui/main.ss b/collects/mrspidey/Gui/main.ss new file mode 100644 index 0000000..15377cb --- /dev/null +++ b/collects/mrspidey/Gui/main.ss @@ -0,0 +1,553 @@ +; main.ss +; Defines main MrSpidey class +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define-structure (fileinfo filename frame thunk-port annotations)) +;; annotations may also be (-> zodiac:parsed) + +(define NUM-EXTRA-LINES 20) + +(define-struct exn:flow-arrow-exists ()) + +(define (wrap-busy-cursor thunk) + (dynamic-wind + (lambda () (wx:begin-busy-cursor)) + thunk + (lambda () (wx:end-busy-cursor)))) + +; ---------------------------------------------------------------------- +(define tm (void)) + +(define MrSpidey% + (class null () + + (public + + [fileinfo* '()] + [multiple-files + (lambda () + (not (= (length fileinfo*) 1)))] + ;; ------------------------------ + ;; Progress frame + + [progress-frame 'progress-frame] + [progress-canvas 'progress-canvas] + [progress-edit 'progress-edit] + + [init-progress-frame! + (lambda () + (pretty-debug-gui `(init-progress-frame)) + (let* ( [f (parameterize + ([wx:current-eventspace (wx:make-eventspace)]) + (make-object mred:frame% '() + (format "~a Progress" st:name)))] + [p (make-object mred:vertical-panel% f)] + [c (make-object mred:wrapping-canvas% p)] + [ph (make-object mred:horizontal-panel% p)] + [_ (send ph stretchable-in-y #f)] + [_ (make-object mred:horizontal-panel% ph)] + [b (make-object mred:button% ph + (lambda _ (send f show #f)) + "Hide")] + [e (make-object mred:media-edit%)]) + (set! progress-frame f) + (set! progress-canvas c) + (set! progress-edit e) + (send p add-child c) + ;;(send c set-media e) + (send progress-frame set-size -1 -1 400 200);; ht was 130 + (send progress-frame show #f)))] + + [new-progress-frame! + (lambda () + (pretty-debug-gui `(new-progress-frame)) + (set! progress-edit (make-object mred:media-edit%)) + (send progress-edit lock #t) + (send progress-canvas set-media progress-edit) + (send progress-frame show #t) + (send progress-frame iconize #f) + (pretty-debug-gui `(new-progress-frame-done)))] + + [with-progress-frame + (lambda (thunk) + (let* + ( [old-progress-handler (mrspidey:progress-handler)] + [current '()] + + [current-start-time 0] + [width 6] + [total-width 18]) + (letrec + ([insert-numbers + (lambda (n) + (send progress-edit insert + (format "~a ~ams" + (padl + (if (eq? n 'done) "" (format "~a" n)) + width) + (padl (- (current-process-milliseconds) + (current-gc-milliseconds) + current-start-time) + width)) + (send progress-edit last-position)))] + [f (match-lambda* + [((? string? name) line) + (if (equal? name current) + (let ([end (send progress-edit last-position)]) + (send progress-edit delete + (- end total-width) end) + (insert-numbers line)) + (begin + (f 'fresh-line) + (set! current name) + (set! current-start-time + (- (current-process-milliseconds) + (current-gc-milliseconds))) + (send progress-edit insert + (padr name 30)) + (insert-numbers line)))] + [((? string? str)) + (f 'fresh-line) + (send progress-edit insert str) + (f #\newline)] + [(#\newline) + (send progress-edit insert (format "~n")) + (set! current '())] + [('fresh-line) + (unless (null? current) (f #\newline))])] + [g (lambda args + (send progress-edit lock #f) + (apply f args) + (send progress-edit lock #t))]) + (parameterize + ([mrspidey:progress-handler + (lambda args + ;;(apply old-progress-handler args) + (apply g args) + (wx:flush-display))]) + (send progress-frame show #t) + (begin0 + (thunk) + (mrspidey:progress + "=Done======================================"))))))] + + ;; ------------------------------ + + [filename->fileinfo + (lambda (file) + (pretty-debug-gui `(filename->fileinfo ,file)) + (or + (ormap + (match-lambda + [(and fi ($ fileinfo filename frame)) + (and (string? file) + (string=? filename file) + fi)]) + fileinfo*) + (assert #f 'filename->fileinfo file)))] + + [filename->frame + (lambda (file) + (let ([x (filename->fileinfo file)]) + (and x (fileinfo-frame x))))] + + [filename->edit + (lambda (file) + (let ([x (filename->frame file)]) + (and x (ivar x program-edit))))] + + [for-each-frame + (lambda (f) + (for-each + (match-lambda + [($ fileinfo filename frame) + (when frame (f frame))]) + fileinfo*))] + + [focus-def + (lambda (loc) + (assert (zodiac:location? loc) 'focus-def loc) + (let* ([file (zodiac:location-file loc)] + [frame (filename->frame file)]) + (if frame + (send frame focus-def (zodiac:location-offset loc)) + (wx:message-box + (format "File ~s is not loaded" (file-name-from-path file)) + "Error" + (bitwise-ior wx:const-ok)))))] + + ;; ------------------------------ + + [open-analyzed-file-choice + (lambda () + (let ([choice + (wx:get-single-choice + "Select referenced unit file to open" + "Open Unit" + (sort stringfileinfo choice) #t))))] + + [open-fileinfo + (match-lambda* + [((and fi ($ fileinfo filename frame)) show) + (if frame + (when show + (send frame show #t) + (send frame iconize #f)) + (add-frame fi show))])] + + [open-all + (lambda (show) + (for-each + (lambda (fi) (open-fileinfo fi show)) + fileinfo*))] + + [add-frame + (match-lambda* + [( (and fi ($ fileinfo filename frame thunk-port thunk-expression)) + show + . first-frame-locs) + (pretty-debug-gui + `(add-no-show-frame ,filename ,fi ,@first-frame-locs)) + (assert (not frame)) + (let ([summary-edit (make-object mred:media-edit%)]) + (initialize-summary summary-edit) + (pretty-debug-gui `(summary-initialized)) + (parameterize + ([mrspidey:add-summary-handler (add-summary summary-edit)]) + (with-progress-frame + (lambda () + (pretty-debug-gui '(progress-frame-initialized)) + (mrspidey:progress + "===========================================") + '(mrspidey:progress + (format "Analyzing ~a" (file-name-from-path filename))) + (let* ([annotations + (calc-annotations (thunk-expression))] + [_ (set-fileinfo-annotations! fi annotations)] + [_ (pretty-debug-gui `(calling-Tframe ,filename))] + [frame (apply make-object spidey:frame% + ;; only use margin + this + filename summary-edit + first-frame-locs)]) + (pretty-debug-gui `(Have-Tframe ,filename)) + (when show (send frame show #t)) + (unless show (send frame show #t) (send frame show #f)) + (set-fileinfo-frame! fi frame) + (update-arrows) + )))))])] + + [initialize-summary + (lambda (edit) + (let* ([delta (make-object wx:style-delta% + wx:const-change-family + wx:const-decorative)] + [click-delta (make-object wx:style-delta%)]) + (send delta set-delta wx:const-change-size 10) + (send click-delta copy delta) + (send click-delta set-delta-foreground "BLUE") + (send click-delta set-delta wx:const-change-underline 1) + + (let ( [insert + (lambda (s) + (let ([before (send edit get-end-position)]) + (send edit insert s) + (let ([after (send edit get-end-position)]) + (values before after))))]) + (let*-values + ( [(s1 e1) (insert "Welcome to ")] + [(s2 e2) (insert "MrSpidey")] + [(s3 e3) (insert (format ", version ~a." (mred:version)))] + [(s4 e4) (insert (format "~n"))]) + (send edit change-style delta s1 e1) + (send edit change-style click-delta s2 e2) + (send edit change-style delta s3 e3) + (send edit set-clickback s2 e2 + (lambda args + (make-object mred:hyper-view-frame% + (string-append + "file:" + (build-path + (collection-path "mrspidey") ; MATTHEW: got rid of plt-home + "about.html")))) + click-delta)))))] + + [local-record-analyzed-file + (lambda (filename thunk-port thunk-expression) + (pretty-debug-gui + `(local-record-analyzed-file ,filename + ,thunk-port + ,thunk-expression)) + (set! fileinfo* + (append fileinfo* + (list (make-fileinfo filename #f + thunk-port + thunk-expression)))))] + + ;; ------------------------------ + + [add-summary + (lambda (summary-edit) + (lambda line + (send summary-edit lock #f) + (match line + [(str loc word-ofs) + (cond + [(zodiac:zodiac? loc) + ((add-summary summary-edit) str + (zodiac:zodiac-start loc) word-ofs)] + [(zodiac:location? loc) + (let* ( [click (lambda ignore (focus-def loc))] + [init-pos-box (box 0)] + [_ (send summary-edit get-position init-pos-box)] + [_ (send summary-edit insert str)] + [_ (send summary-edit insert + (format " in file ~s line ~s" + (file-name-from-path + (zodiac:location-file loc)) + (zodiac:location-line loc)))] + [_ (send summary-edit insert #\newline)] + ;; Find start and end of word + [end (unbox init-pos-box)] + [_ + (for i 0 (add1 word-ofs) + (set! end (mred:scheme-forward-match + summary-edit end + (send summary-edit last-position))))] + [start (mred:scheme-backward-match summary-edit end 0)]) + + '(pretty-debug-gui + `(send summary-edit change-style check-link-delta + ,(send check-link-delta get-underlined-on) + ,start ,end)) + ;; Paranoia - check have proper locations + (if (and start end) + (begin + (send summary-edit set-clickback start end click) + (send summary-edit change-style check-link-delta + start end)) + ;; Error + (pretty-print + `(Error: annotate-summary + ,str ,loc ,word-ofs ,start ,end))))] + [else + (begin + (printf + "Bad location in main:add-summary-handler ~s~n" + loc) + (mrspidey:add-summary str))])] + [(str) + (send summary-edit insert str) + (send summary-edit insert #\newline)] + [x (printf "add-summary, can't handle ~s~n" x)]) + (send summary-edit lock #t)))] + + ;; ------------------------------ + + [on-frame-close + (lambda (filename) + (void))] + + [close-all-frames + (lambda () + (send progress-frame show #f) + (close-all-frames-except-progress) + )] + + [close-all-frames-except-progress + (lambda () + (for-each-frame (lambda (frame) (send frame on-close))) + )] + + ;; ------------------------------ + + [annotated-edit + (lambda (mode filename canvas) + ;; create edit buffer, load file and add annotations + (pretty-debug-gui `(annotate-edit ,mode ,filename)) + (match (filename->fileinfo filename) + [($ fileinfo filename frame thunk-port annotations) + (let* ( [port (thunk-port)] + [edit (make-object + (mode-edit-class mode) + (if (multiple-files) " " "") + this canvas)]) + (send edit set-filename filename) + (send edit edit-sequence + (lambda () + (pretty-debug-gui "loading!") + (let ([s (format "Loading ~a: " + (file-name-from-path filename))]) + (recur loop ([n 1]) + (when (zero? (modulo n 50)) + (mrspidey:progress s n)) + (let ([r (read-line port)]) + ;;(pretty-debug-gui `(inserting ,r)) + (if (eof-object? r) + (mrspidey:progress s (sub1 n)) + (begin + (send edit insert-line r) + (loop (add1 n)))))) + (when (multiple-files) + (for i 0 NUM-EXTRA-LINES (send edit insert-line "")))) + (close-input-port port) + (pretty-debug-gui `(last-line ,(send edit last-line))) + (send edit change-style base-delta + 0 (send edit last-position)) + + (pretty-debug-gui "annotating!") + (annotate! filename edit mode annotations) + + (send edit set-position 0) + (pretty-debug-gui `(annotate-buffer done)))) + + edit)]))] + + [annotate! + (lambda (filename edit mode annotations) + (let ([s (format "Annotating ~a:" (file-name-from-path filename))]) + (mrspidey:progress s '...) + (pretty-debug-gui `(annotate! ,filename ,edit ,mode ,annotations)) + (let ([annotation-fn-list (mode-annotation-fn-list mode)]) + (for-each + (lambda (annotation-fn annotations) + (when annotation-fn + (for-each + (let ([fn (uq-ivar edit annotation-fn)]) + (match-lambda + [(and annotation ($ annotation loc)) + (when (string=? (zodiac:location-file loc) + filename) + ;; Call the method named func to annotate etc. + (fn annotation))])) + annotations))) + annotation-fn-list + (vector->list annotations))) + (mrspidey:progress s 'done)))] + + ;; ------------------------------ + + [shake-it + '(lambda () + (let* ([n (random (vector-length fileinfo*))] + [fi (vector-ref fileinfo* n)] + [frame (fileinfo-frame fi)]) + (send frame shake-it)))] + + ;; ------------------------------ + ;; Arrows + + [list-flow-arrows '()] + [add-flow-arrow + (lambda (src dest) + (assert (and (FlowType? src) (FlowType? dest))) + (pretty-debug-gui + `(main:add-flow-arrow + ,(FlowType->pretty src) ,(FlowType->pretty dest))) + (with-handlers + ([exn:flow-arrow-exists? (lambda (exn) (void))]) + (let ([flow-arrow (make-object flow-arrow% this src dest)]) + (when flow-arrow + (set! list-flow-arrows (cons flow-arrow list-flow-arrows))))))] + [draw-arrows + (lambda () + (pretty-debug-gui `(main:draw-arrows)) + (for-each-frame + (lambda (frame) + (send (ivar frame program-edit) draw-arrows))))] + [update-arrows + (lambda () + (pretty-debug-gui `(main:update-arrows)) + (for-each + (lambda (arrow) (send arrow update)) + list-flow-arrows) + (draw-arrows))] + [delete-arrow + (lambda (arrow) + (send arrow delete-local) + (set! list-flow-arrows (remv arrow list-flow-arrows)))] + [delete-arrow-refresh + (lambda (arrow) + (delete-arrow arrow) + (draw-arrows))] + [delete-arrows + (lambda () + (for-each + (lambda (arrow) (send arrow delete-local)) + list-flow-arrows) + (set! list-flow-arrows '()) + (draw-arrows))] + + ;; ------------------------------ + + [reanalyze 'reanalyze] + + [run-mrspidey + + (lambda (file . first-frame-locs) + + (pretty-debug-gui `(run-mrspidey ,file)) + (set! reanalyze + (lambda () (apply run-mrspidey file first-frame-locs))) + + (close-all-frames-except-progress) + (pretty-debug-gui `(frames-closed)) + (set! fileinfo* '()) + (new-progress-frame!) + + (let ([file (normalize-path (normalize-path file))]) + ;; Following calls record-anlyzed-file + (st:analyze-and-make-annotations file) + (apply add-frame (filename->fileinfo file) #t first-frame-locs) + + ))]) + + ;; ---------------------------------------------------------------------- + + (sequence + (set! tm this) + (record-analyzed-file-hook local-record-analyzed-file) + (init-progress-frame!)))) + +(define spidey (make-object MrSpidey%)) + +;; ---------------------------------------------------------------------- +;; mode says for each set of annotations, +;; either #f or fn to handle annotation. + +(define-const-structure (mode name edit-class annotation-fn-list)) + +(define modes + (list + (make-mode + "Types and Checks" + flow-arrow:media-edit% + (list + 'add-type-annotation + 'add-check-annotation + 'add-uncheck-annotation)) + (make-mode "Normal" + spidey:static-edit% + (list #f #f #f)))) + +;; ---------------------------------------------------------------------- + + diff --git a/collects/mrspidey/Gui/prefs.ss b/collects/mrspidey/Gui/prefs.ss new file mode 100644 index 0000000..f1b5a88 --- /dev/null +++ b/collects/mrspidey/Gui/prefs.ss @@ -0,0 +1,330 @@ +;; prefs.ss - loads preferences +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define parameter-radio-boxes + (lambda (name param sym p major-dim direction) + (mred:set-preference-default sym (param) + (lambda (x) + (with-handlers ((exn? (lambda (exn) #f))) + (param x) + #t))) + (param (mred:get-preference sym)) + (let* ([o + (make-object + mred:radio-box% p + (lambda (bx event) + ;;(printf "~s~n" (param '?)) + (match + (list-ref (param '?) + (send event get-command-int)) + [(tag . _) + (param tag) + (mred:set-preference sym tag)])) + name + -1 -1 -1 -1 + (map cadr (param '?)) + major-dim + direction)] + [pairs + (map + (match-lambda [(tag name . _) (cons name tag)]) + (param '?))] + [default-ndx + (recur loop ([n 0][pairs pairs]) + (cond + [(null? pairs) + (error 'make-parameter-menu + "Can't find para in pairs ~s" (param))] + [(equal? (param) (cdar pairs)) n] + [else (loop (add1 n) (cdr pairs))]))]) + (send o stretchable-in-x #t) + (send o set-selection default-ndx) + o + ))) + +(define parameter-check-box + (lambda (name param sym p) + (mred:set-preference-default sym (param) + (lambda (x) + (with-handlers ((exn? (lambda (exn) #f))) + (param x) + #t))) + (param (mred:get-preference sym)) + (let* ( [hp (make-object mred:horizontal-panel% p)] + [o + (make-object + mred:check-box% hp + (lambda (bx event) + ;;(printf "~s~n" (param '?)) + (match + (list-ref (param '?) + (send event get-command-int)) + [(tag . _) + (param tag) + (mred:set-preference sym tag)])) + name + -1 -1 -1 -1)] + [_ (make-object mred:horizontal-panel% hp)]) + (send o set-value (param)) + o + ))) + +;; ====================================================================== +;; MrSpidey Type Display + +(define callbacks-sdl-alg-changed '()) + +(define (add-callback-sdl-alg-changed! fn) + (set! callbacks-sdl-alg-changed (cons fn callbacks-sdl-alg-changed))) + +(define (remq-callback-sdl-alg-changed! fn) + (set! callbacks-sdl-alg-changed (remq fn callbacks-sdl-alg-changed))) + +(define (sdl-alg-changed) + (for-each + (lambda (f) (f)) + callbacks-sdl-alg-changed)) + +(define (param-ctrls-sdl-alg param) + (lambda args + (sdl-alg-changed) + (apply param args))) + +;; ====================================================================== + +(mred:set-preference-default 'st:const-merge-size (st:const-merge-size) + (lambda (x) + (with-handlers ((exn? (lambda (exn) #f))) + (st:const-merge-size x) + #t))) +(st:const-merge-size (mred:get-preference 'st:const-merge-size)) + +(define mrspidey-mk-analysis-pref-panel + (lambda (panel) + (let* + ( [p (make-object mred:vertical-panel% panel)] + + [vp (make-object mred:vertical-panel% p -1 -1 -1 -1)] + [_ (parameter-check-box + "Accurate constant types" + st:constants 'st:constants + vp)] + [g (make-object mred:slider% vp + (lambda (slider event) + (st:const-merge-size (send event get-command-int)) + (mred:set-preference 'st:const-merge-size + (send event get-command-int))) + "Constant merge size" + (st:const-merge-size) + 1 100 + 100)] + [_ (send g enable #t)] + [_ (parameter-check-box + "If splitting" + st:if-split 'st:if-split + vp)] + [_ (parameter-check-box + "Flow sensitivity" + st:flow-sensitive 'st:flow-sensitive + vp)] + [_ (parameter-check-box + "Accurate analysis of numeric operations" + st:numops 'st:numops + vp)] + [_2 (parameter-radio-boxes + "Polymorphism:" + st:polymorphism + 'st:polymorphism + p 0 wx:const-horizontal)] + + [vp (make-object mred:vertical-panel% p -1 -1 -1 -1)] + [vphp (make-object mred:horizontal-panel% vp)] + [_0 (make-object mred:message% vphp + "Polymorphism simplification algorithms:")] + [vphphp (make-object mred:horizontal-panel% vphp)] + [_1 (parameter-radio-boxes + " " + st:constraint-simplification-poly + 'st:constraint-simplification-poly + vp 0 wx:const-vertical)] + + [_ (parameter-radio-boxes + "Save .za files in:" + st:save-za-in + 'st:save-za-in + p + 0 wx:const-horizontal)] + ) + + p))) + +(mred:add-preference-panel + "MrSpidey Analysis" + mrspidey-mk-analysis-pref-panel) + +(mrspidey-mk-analysis-pref-panel + (make-object mred:horizontal-panel% + (make-object mred:frame% '() "dummy"))) + +;; ====================================================================== + +;(mred:set-preference-default 'st:sdl-size-k (st:sdl-size-k)) +;(st:sdl-size-k (mred:get-preference 'st:sdl-size-k)) + +(define (indented-vertical-radio-box p name param sym) + (let* + ( [vp (make-object mred:vertical-panel% p -1 -1 -1 -1)] + [vphp1 (make-object mred:horizontal-panel% vp)] + [_0 (make-object mred:message% vphp1 name)] + [vphp2 (make-object mred:horizontal-panel% vp)] + [spc (make-object mred:horizontal-panel% vphp2)] + [_ (send spc user-min-width 20)] + [_ (send spc stretchable-in-x #f)] + [radio-box + (parameter-radio-boxes + '() + param sym + vphp2 0 wx:const-vertical)] + [_ (send radio-box stretchable-in-x #t)] + [_ (make-object mred:horizontal-panel% vphp2)]) + (void))) + +(define mrspidey-mk-type-display-prefs-panel + (lambda (panel) + (let* + ( [p (make-object mred:vertical-panel% panel )]) + + (let* + ( + [sdl-fo-container-panel + (make-object mred:horizontal-panel% p)] + [sdl-fo-sub-panel + (make-object mred:horizontal-panel% p)] + [spc (make-object mred:horizontal-panel% sdl-fo-sub-panel)] + [_ (send spc user-min-width 20)] + [_ (send spc stretchable-in-x #f)] + [sdl-fo-sub-sub-panel + (make-object mred:vertical-panel% sdl-fo-sub-panel)] + [see-ivars-panel + (parameter-check-box + "Show instance variables" + (param-ctrls-sdl-alg st:sdl-fo-ivars) + 'st:sdl-fo-ivars + sdl-fo-sub-sub-panel)] + [see-struct-fields-panel + (parameter-check-box + "Show structure fields" + (param-ctrls-sdl-alg st:sdl-fo-struct-fields) + 'st:sdl-fo-struct-fields + sdl-fo-sub-sub-panel)] + [_ (parameter-radio-boxes + "Show types as:" + (match-lambda* + [('?) (st:sdl-fo '?)] + [() (st:sdl-fo)] + [(x) + (sdl-alg-changed) + (let ([enable-sub-controls (eq? x 'basic-types)]) + (for-each + (lambda (control) + (send control enable enable-sub-controls)) + (list + see-ivars-panel + see-struct-fields-panel))) + (st:sdl-fo x)]) + 'st:sdl-fo + sdl-fo-container-panel + 0 wx:const-horizontal)]) + (void)) + + (indented-vertical-radio-box p + "Constraint simplification algorithms:" + (param-ctrls-sdl-alg st:sdl-constraint-simplification) + 'st:sdl-constraint-simplification) + + (parameter-radio-boxes + "Type naming:" + (param-ctrls-sdl-alg st:naming-strategy) + 'st:naming-strategy + p 0 wx:const-horizontal) + (parameter-radio-boxes + "Primitive types:" + (param-ctrls-sdl-alg st:primitive-types) + 'st:primitive-types + p 0 wx:const-horizontal) + + (let* + ( + [st:expand-output-type-container-panel + (make-object mred:horizontal-panel% p)] + [st:expand-output-type-sub-panel + (make-object mred:horizontal-panel% p)] + [spc (make-object mred:horizontal-panel% + st:expand-output-type-sub-panel)] + [_ (send spc user-min-width 20)] + [_ (send spc stretchable-in-x #f)] + [sdl-tidy-object + (parameter-check-box + "Uses equivalences that make types tidy" + (param-ctrls-sdl-alg st:sdl-tidy) + 'st:sdl-tidy + st:expand-output-type-sub-panel)] + [_ (parameter-check-box + "Use equivalences to simplify types" + (match-lambda* + [('?) (st:expand-output-type '?)] + [() (st:expand-output-type)] + [(x) + (sdl-alg-changed) + (send sdl-tidy-object enable x) + (st:expand-output-type x)]) + 'st:expand-output-type + st:expand-output-type-container-panel)]) + (void)) + + p))) + +(mred:add-preference-panel + "MrSpidey Type Display" + mrspidey-mk-type-display-prefs-panel) + +(mrspidey-mk-type-display-prefs-panel + (make-object mred:horizontal-panel% + (make-object mred:frame% '() "dummy"))) + +;; ====================================================================== + +'(define (make-parameter-menu parameter) + (let* ([pairs + (map + (match-lambda [(tag name . _) (cons name tag)]) + (parameter '?))] + [default-ndx + (recur loop ([n 0][pairs pairs]) + (cond + [(null? pairs) + (error 'make-parameter-menu "Can't find para in pairs")] + [(equal? (parameter) (cdar pairs)) n] + [else (loop (add1 n) (cdr pairs))]))]) + (let ([menu (make-object mred:menu%)]) + (send menu append-check-set pairs parameter default-ndx) + ;;(parameter (cdar pairs)) + menu))) + + + diff --git a/collects/mrspidey/Gui/progress.ss b/collects/mrspidey/Gui/progress.ss new file mode 100644 index 0000000..37806d8 --- /dev/null +++ b/collects/mrspidey/Gui/progress.ss @@ -0,0 +1,168 @@ +; progress.ss - not used +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define progress-box% + (class mred:frame% (title arg-bar-names . top-left-loc) + + (inherit show set-size) + + (public + num-bars + bar-names + bar-fractions + the-canvas + [top-margin 12] + [bot-margin 24] + [right-margin 20] + [left-margin 10] + [middle-margin 20] + [bar-length 150] + [line-spacing 8] + [barname-width 58] + [barname-height 12] + [bar-margin 2] + [solid-brush (make-object wx:brush% "DARKGREEN" wx:const-solid)] + [trans-brush (make-object wx:brush% "DARKGREEN" wx:const-transparent)] + [border-pen (make-object wx:pen% "BLACK" 1 wx:const-solid)] + [in-pen (make-object wx:pen% "DARKGREEN" 1 wx:const-solid)] + + [mark-progress + (lambda (bar-num fraction) + (vector-set! bar-fractions bar-num fraction) + (send the-canvas on-paint))] + ) + + (sequence + + (super-init '() title -1 -1 200 200) + + (set! num-bars (length arg-bar-names)) + (set! bar-names (list->vector arg-bar-names)) + (set! bar-fractions (make-vector num-bars 0)) + + (set! the-canvas + (make-object + (class wx:canvas% args + (inherit get-dc) + (public + [on-paint + (lambda () + (let ([the-dc (send the-canvas get-dc)]) + ;; Draw the text + (for i 0 num-bars + '(pretty-print + `(send the-dc draw-text + ,(vector-ref bar-names i) + ,left-margin + ,(+ top-margin + (* (+ barname-height line-spacing) i)))) + (send the-dc draw-text + (vector-ref bar-names i) + left-margin + (+ top-margin + (* (+ barname-height line-spacing) i)))) + + ; Draw the bar borders + (send the-dc set-pen border-pen) + (send the-dc set-brush trans-brush) + (for i 0 num-bars + '(pretty-print `(send the-dc draw-rectangle + ,(+ left-margin barname-width middle-margin) + ,(+ top-margin + (* (+ barname-height line-spacing) i)) + ,(+ (* bar-length 1) (* 2 bar-margin)) + ,barname-height)) + (send the-dc draw-rectangle + (+ left-margin barname-width middle-margin) + (+ top-margin + (* (+ barname-height line-spacing) i)) + (+ (* bar-length 1) (* 2 bar-margin)) + barname-height)) + + ;; Draw the bars + (send the-dc set-pen in-pen) + (send the-dc set-brush solid-brush) + (for i 0 num-bars + (unless (zero? (vector-ref bar-fractions i)) + '(pretty-print `(send the-dc draw-rectangle + ,(+ left-margin barname-width middle-margin + bar-margin) + ,(+ top-margin + (* (+ barname-height line-spacing) i) + bar-margin) + ,(vector-ref bar-fractions i) + ,(* bar-length (vector-ref bar-fractions i)) + ,(- barname-height (* 2 bar-margin)))) + (send the-dc draw-rectangle + (+ left-margin barname-width middle-margin + bar-margin) + (+ top-margin + (* (+ barname-height line-spacing) i) + bar-margin) + (* bar-length (vector-ref bar-fractions i)) + (- barname-height (* 2 bar-margin))))) + ) + (wx:flush-display))]) + + (sequence + (apply super-init args) + (let ([the-dc (get-dc)]) + (send the-dc set-font + (make-object wx:font% 12 wx:const-modern + wx:const-normal wx:const-normal #f)) + ))) + + this)) + + '(let* ([sizes + (map + (lambda (name) + (let ([wb (box 0)] + [hb (box 0)]) + (printf ".") (flush-output) + (send (send the-canvas get-dc) get-text-extent name wb hb) + (printf ".") (flush-output) + (cons (unbox wb) (unbox hb)))) + arg-bar-names)]) + + (pretty-print `(sizes ,sizes)) + (set! barname-width (apply max (map car sizes))) + (set! barname-height (apply max (map cdr sizes)))) + + ;; Set the frame size + position + (let ([w (+ left-margin barname-width middle-margin + bar-length (* 2 bar-margin) right-margin)] + [h (+ top-margin + (* (+ barname-height line-spacing) num-bars) + bot-margin)]) + (match top-left-loc + [(x y) (set-size (- x w) y w h)] + [() (void)]) + (set-size w h)) + ;; We're ready + (show #t) + (wx:flush-display) + (wx:yield) + ))) + +'(begin + (define p (make-object progress-box% "title" '("bar-name-1" "bar-name-2"))) + (send p mark-progress 0 0.3) + (send p mark-progress 1 0.6) + ) + diff --git a/collects/mrspidey/Gui/statedit.ss b/collects/mrspidey/Gui/statedit.ss new file mode 100644 index 0000000..241fefb --- /dev/null +++ b/collects/mrspidey/Gui/statedit.ss @@ -0,0 +1,72 @@ +; statedit.ss +; Defines spidey:static-edit%, a subclass of mred:media-edit% +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define spidey:static-edit% + (class mred:searching-edit% init-args + (inherit + insert delete flash-on flash-off get-text + set-clickback change-style lock + set-position load-file + get-keymap scroll-to-position + last-position get-style-list + set-mode + begin-edit-sequence end-edit-sequence + ) + + (public + [begin-edit-sequence-and-unlock + (lambda () + (wx:begin-busy-cursor) + (lock #f) + (begin-edit-sequence))] + [end-edit-sequence-and-lock + (lambda () + (end-edit-sequence) + (lock #t) + (wx:end-busy-cursor))] + [edit-sequence + (lambda (thunk) + (dynamic-wind + begin-edit-sequence-and-unlock + thunk + end-edit-sequence-and-lock))] + [match-paren-forward + (lambda (source-start) + (mred:scheme-forward-match + this source-start (last-position)))] + ) + + (sequence + + (apply super-init init-args) + + (set-mode (make-object mred:scheme-mode%)) + ;; disable paste for errant right mouse clicks + (let ([ k (get-keymap)]) + (send k add-mouse-function "nothing" (lambda l (void))) + (send k map-function "middlebutton" "nothing") + (send k map-function "rightbutton" "nothing")) + + ;; make snips go down instead of up + ;; oops - can't do this :-( + '(let ([stan (send (get-style-list) find-named-style "Standard")]) + (when stan (send stan set-delta normal-delta))) + + (lock #t) + ))) diff --git a/collects/mrspidey/Gui/test-gui.ss b/collects/mrspidey/Gui/test-gui.ss new file mode 100644 index 0000000..0dc9a27 --- /dev/null +++ b/collects/mrspidey/Gui/test-gui.ss @@ -0,0 +1,23 @@ +;; test-gui.ss +;; ---------------------------------------------------------------------- + +(define test-gui-shake-reps 25) + +(define (shake-test-files) test-files) + +;; ---------------------------------------------------------------------- + +(define (test-gui-file f) + (printf "FILE: ~s~n" f) + (let* ([ftd (list f (lambda () (open-input-file f)) #t)] + [ftd* (list ftd)]) + (send spidey do-and-show-analysis ftd*) + (for i 0 test-gui-shake-reps + (printf "Iteration ~s/~s~n" i test-gui-shake-reps) + (send spidey shake-it)) + (send spidey close-all-frames))) + +(define (test-gui) + (for-each test-gui-file (shake-test-files))) + + diff --git a/collects/mrspidey/Sba/atenv.ss b/collects/mrspidey/Sba/atenv.ss new file mode 100644 index 0000000..e530826 --- /dev/null +++ b/collects/mrspidey/Sba/atenv.ss @@ -0,0 +1,307 @@ +;; atenv.ss +;; Section for handling environment +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define-const-typed-structure + atenv ( (: immut (listof (cons zodiac:binding FlowType))) + (: notcap (listof (cons zodiac:binding mutable-binding))) + (: cap (listof (cons zodiac:binding mutable-binding))) + (: flushed (listof (cons zodiac:binding mutable-binding))) + (: unflushed (listof (cons zodiac:binding mutable-binding))) + (: both (listof (cons zodiac:binding mutable-binding))))) + +(define-const-typed-structure + mutable-binding ( (: current FlowType) + (: at-transfer Tvar) + (: flushed bool))) + +;; ---------------------------------------------------------------------- + +(define atenv:empty (make-atenv '() '() '() '() '() '())) + +(define (atenv:extend-mutated env name ftype tvar) + (pretty-debug-atenv `(atenv:extend-mutated ,(atenv->pretty env))) + (assert (zodiac:binding? name) 'atenv:extend name) + (let ([ftype (link-parsed-ftype! name ftype)]) + (match env + [($ atenv i n c f u b) + (make-atenv + i + (extend-env n name + (make-mutable-binding + ftype tvar + #f)) + c f u b)]))) + +(define (atenv:extend env name ftype) + (pretty-debug-atenv `(atenv:extend ,(atenv->pretty env))) + (assert (zodiac:binding? name) 'atenv:extend name) + (let ([ftype (link-parsed-ftype! name ftype)]) + (match env + [($ atenv i n c f u b) + (if (zodiac:binding-mutated name) + (make-atenv + i + (extend-env n name + (make-mutable-binding + ftype + (mk-Tvar 'mut-var + ;;(symbol-append 'mut-var- (zodiac:binding-var name)) + ) + #f)) + c f u b) + (make-atenv + (extend-env i name ftype) + n c f u b))]))) + +(define (atenv:extend* env names ftypes) + (foldr2 (lambda (name ftype env) (atenv:extend env name ftype)) + env names ftypes)) + +(define (atenv:extend-voids env names) + (atenv:extend* env names (map (lambda (x) (mk-tvar-void)) names))) + +(define (atenv:extend-undefineds env names) + (atenv:extend* env names (map (lambda (x) (mk-tvar-undefined)) names))) + +(define (atenv:lookup env name) + (pretty-debug-atenv `(atenv:lookup ,(atenv->pretty env))) + (if (zodiac:binding-mutated name) + (match (or + (lookup-or-#f (atenv-notcap env) name) + (lookup-or-#f (atenv-cap env) name) + (lookup-or-#f (atenv-flushed env) name) + (lookup-or-#f (atenv-unflushed env) name) + (lookup-or-#f (atenv-both env) name)) + [($ mutable-binding cur) cur] + [x x]) + (lookup-or-#f (atenv-immut env) name))) + +(define (atenv:change-binding env name ftype) + (pretty-debug-atenv + `(->atenv:change-binding + ,(zodiac:binding-var name) ,(FlowType->pretty ftype) + ,(atenv->pretty env))) + (match env + [($ atenv i n c f u b) + (let/cc k + (let* + ([err + (lambda () + (pretty-debug-atenv + `(atenv:change-binding + ,(zodiac:binding-var name) + ,(map zodiac:binding-var (map car env)))) + (mrspidey:warning + (format "Unbound variable ~s" (zodiac:binding-var name)) + (zodiac:zodiac-start name) + 2) + (k env))] + [result-env + (if (zodiac:binding-mutated name) + (let ([chg-fn + (match-lambda + [($ mutable-binding cur at-transfer) + (make-mutable-binding ftype at-transfer #f)])]) + (if (lookup-or-#f n name) + (make-atenv + i + (env:change-binding n name chg-fn err) + c f u b) + ;; Must be in one of c f u b + ;; Lift out to captured + (if (lookup-or-#f c name) + (make-atenv + i n + (env:change-binding c name chg-fn err) + f u b) + (let*-vals + ([(bind f u b) + (cond + [(lookup-or-#f f name) + (let*-vals ([(bind f) (env:remove f name)]) + (values bind f u b))] + [(lookup-or-#f u name) + (let*-vals ([(bind u) (env:remove u name)]) + (values bind f u b))] + [(lookup-or-#f b name) + (let*-vals ([(bind b) (env:remove b name)]) + (values bind f u b))] + [else (err)])]) + (make-atenv + i n + (extend-env c name (chg-fn bind)) + f u b))))) + (make-atenv + (env:change-binding i name (lambda (old) ftype) err) + n c f u b))]) + (pretty-debug-atenv + `(->atenv:change-binding-returns ,(atenv->pretty result-env))) + result-env))])) + +(define (atenv:change-bindings env bindings ftypes) + (foldr2 + (lambda (binding ftype env) + (atenv:change-binding env binding ftype)) + env bindings ftypes)) + +;; ------------------------------ + +(define (atenv:capture-locs env bindings) + (pretty-debug-atenv + `(atenv:capture-locs ,(atenv->pretty env) ,(map zodiac:binding-var bindings))) + (match env + [($ atenv i n c f u b) + (recur loop ([n n][n-ok '()][c c]) + (if (null? n) + (make-atenv i n-ok c f u b) + (if (and + (memq (caar n) bindings) + ;; ### KLUDGE FOR DECENT, BUT POSSIBLY WRONG, POLYMORPHISM + (not (poly-atype? (FlowType->Atype + (mutable-binding-current (cdar n)))))) + (loop (cdr n) n-ok (cons (car n) c)) + (loop (cdr n) (cons (car n) n-ok) c))))])) + +(define (atenv:unflush env) + (pretty-debug-atenv `(atenv:unflush ,(atenv->pretty env))) + (match env + [($ atenv i n c f u b) + (let ([upd + (match-lambda + [(name . ($ mutable-binding cur trans)) + (cons name (make-mutable-binding trans trans #t))])]) + (make-atenv + i n '() '() + (append (map upd c) u) + (append (map upd f) b)))])) + +(define (atenv:flush! env) + (pretty-debug-atenv `(atenv:flush! ,(atenv->pretty env))) + (match env + [($ atenv i n c f u b) + (let ([upd + (match-lambda + [(name . (and bind ($ mutable-binding cur trans flushed))) + (unless flushed + (new-edge! (FlowType->Tvar cur) trans) + (set-mutable-binding-flushed! bind #t))])]) + (for-each upd c) + (for-each upd u) + (make-atenv i n '() (append c f) '() (append u b)))])) + +(define (atenv->pretty env) + (match env + [($ atenv i n c f u b) + (let ([p (match-lambda + [(name . ($ mutable-binding cur trans)) + (list (zodiac:binding-var name) + (list + (FlowType->pretty cur) + (FlowType->pretty trans)))])]) + + (list + (map (match-lambda + [(name . ftype) + (list + (zodiac:binding-var name) + (FlowType->pretty ftype))]) + i) + (map p n) + (map p c) + (map p f) + (map p u) + (map p b)))])) + +(define (atenv:domain env) + (match env + [($ atenv i n c f u b) + (map car (append i n c f u b))])) + +(define (atenv:ok? e) + (and + (atenv? e) + (match e + [($ atenv i n c f u b) + (and + (list? i) + (andmap + (match-lambda + [(($ zodiac:binding) . ($ FlowType)) #t] + [_ #f]) + i) + (andmap + (lambda (n) + (and + (list? n) + (andmap + (match-lambda + [(($ zodiac:binding) . ($ mutable-binding)) #t] + [_ #f]) + n))) + (list n c f u b)))]))) + +'(defmacro check-atenv-fn-ok (fn) + (let ( [old-fn (gensym)]) + `(begin + (define ,old-fn ,fn) + (define ,fn + (let ([env-ok atenv:ok?]) + (lambda (env . rest) + ;;(printf "Entering ~s~n" (quote ,fn)) + (unless (env-ok env) + (pretty-print env) + (error (quote ,fn) "Bad env on entry")) + (let ([r (apply ,old-fn env rest)]) + ;;(printf "exiting ~s~n" (quote ,fn)) + (unless (env-ok env) + (error (quote ,fn) "Bad env on exit")) + r))))))) + +;(check-atenv-fn-ok atenv:extend) +;(check-atenv-fn-ok atenv:extend*) +;(check-atenv-fn-ok atenv:extend-voids) +;(check-atenv-fn-ok atenv:change-binding) +;(check-atenv-fn-ok atenv:change-bindings) +;(check-atenv-fn-ok atenv:capture-locs) +;(check-atenv-fn-ok atenv:unflush) +;(check-atenv-fn-ok atenv:flush!) + +;; ====================================================================== + +(define (link-parsed-ftype! parsed ftype) + (assert (FlowType? ftype) 'link-parsed-ftype! ftype) + (if need-label-types + (let ([nu-ftype + (if (and need-explanation (FlowType-expr ftype)) + (copy-ftype ftype) + ftype)]) + (pretty-debug-object + `(link-parsed-ftype! + ,(zodiac:stripper parsed) + ,(zodiac:location-offset (zodiac:zodiac-start parsed)) + ,(FlowType-name ftype))) + (zodiac:set-parsed-ftype! parsed nu-ftype) + (set-FlowType-expr! nu-ftype #t) ;parsed + nu-ftype) + ftype)) + +;; ====================================================================== + + + diff --git a/collects/mrspidey/Sba/atlunit.ss b/collects/mrspidey/Sba/atlunit.ss new file mode 100644 index 0000000..7301ddd --- /dev/null +++ b/collects/mrspidey/Sba/atlunit.ss @@ -0,0 +1,765 @@ +;; atlunit.ss +;; Handles annotated lazy units - units, cmpd-units and reference-units +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; The structures ... + +(define-const-typed-structure + (atlunit-unit struct:atlunit) + ((: env (listof (cons zodiac:binding FlowType))) + (: exp zodiac:unit-form))) + +(define (create-atlunit-unit env exp) + (make-atlunit-unit #f env exp)) + +;; ----- + +(define-const-typed-structure + (atlunit-cmpd struct:atlunit) + ((: cmpd-unit zodiac:compound-unit-form) + (: times (listof num)) + (: ftype* (listof FlowType)))) + +(define (create-atlunit-cmpd cmpd-unit time* ftype*) + (make-atlunit-cmpd #f cmpd-unit time* ftype*)) + +;; ----- + +(define-const-typed-structure + (atlunit-reference struct:atlunit) + ((: exp zodiac:sexp))) + +(define (create-atlunit-reference exp) + (assert (zodiac:reference-unit-form? exp)) + (make-atlunit-reference #f exp)) + +;; ---------------------------------------------------------------------- +;; (: partial-import-list +;; (union false (listof (cons (union FlowType false) time)))) + +(define (pretty-partial-import-list pil) + (and pil + (map (match-lambda + [(ftype . itime) + (cons (and ftype (FlowType->pretty ftype)) itime)]) + pil))) + +;; ---------------------------------------------------------------------- + +(define (apply-unit unit partial-import-list) + (: unit FlowType) + ;; returns (union atunit Tvar) + (match (FlowType->Atype unit) + [(? atlunit? atlunit) (apply-atlunit atlunit partial-import-list)] + [($ atunit imports exports result expr) + (let ([imports + (cond + [(eq? partial-import-list #f) imports] + [(= (length imports) (length partial-import-list)) + (map (match-lambda* + [((sym . tvars) (ftype . _)) + (if ftype + (begin + (for-each + (lambda (tvar) + (new-edge! (FlowType->Tvar ftype) tvar)) + tvars) + (list sym)) + (cons sym tvars))]) + imports partial-import-list)] + [else + (let ([msg (format "Unit takes ~s imports, given ~s" + (length imports) (length partial-import-list))]) + (if (zodiac:parsed? expr) + (mrspidey:warning msg expr 0) + (mrspidey:warning msg))) + imports])]) + (make-atunit imports exports result expr))] + [(? Tvar? tvar-u) + (for-each-with-n + (match-lambda* + [((ftype . _) n) + (new-con! tvar-u + (create-con (get-unit-import-template n) + 0 (FlowType->Tvar ftype) #f))]) + partial-import-list) + tvar-u])) + +;; ---------------------------------------------------------------------- + +(define (atlunit->atunit atlunit) + ;; returns atunit + (apply-atlunit atlunit #f)) + +(define gatlunit (void)) + +(define (apply-atlunit atlunit partial-import-list) + (: partial-import-list (listof (cons (union FlowType false) num))) + ;; (returns atunit) + (set! gatlunit atlunit) + (match atlunit + [(and atlunit ($ atlunit ui)) + (assert (or (eq? ui #f) (atunit? ui))) + (when (and ui partial-import-list) + (pretty-debug-unit `(ui ,ui partial-import-list ,partial-import-list)) + (mrspidey:error + "Annotated lazy unit invoked more than once" + (match atlunit + [($ atlunit-unit _ _ exp) exp] + [($ atlunit-cmpd _ exp) exp] + [($ atlunit-reference _ exp) exp]))) + (or ui + (let* ( [fn + (cond + [(atlunit-unit? atlunit) apply-atlunit-unit] + [(atlunit-cmpd? atlunit) apply-atlunit-cmpd] + [(atlunit-reference? atlunit) apply-atlunit-reference] + [else (mrspidey:internal-error + 'apply-atlunit->atunit "Not a lazy unit")])] + [ui (fn atlunit partial-import-list)]) + (set-atlunit-ui! atlunit ui) + ui))])) + +;; ---------------------------------------------------------------------- + +(define (apply-atlunit-unit atlunit partial-import-list) + (match atlunit + [($ atlunit-unit _ env + (and unit-exp ($ zodiac:unit-form _ s _ _ imports exports body))) + (pretty-debug-unit + `(apply-atlunit-unit + ,(zodiac:stripper unit-exp) + ,(and partial-import-list + (map FlowType->pretty (map car partial-import-list)))) + 7) + + (let*-vals + ( [free-names (zodiac:free-vars-defs body)] + [free-names2 (setdiff2 free-names imports)] + [init-env (get-default-bindings free-names2)] + [env1 (cond + [(eq? partial-import-list #f) init-env] + [(not (= (length imports) (length partial-import-list))) + (mrspidey:error + (format + "Bad number of imports for unit, expected ~s, given ~s" + (length imports) + (length partial-import-list)))] + [else (foldr2 + (lambda (name ftype env) + (if ftype + (atenv:extend env name ftype) + env)) + init-env + imports + (map car partial-import-list))])] + [(env2 refs result) (traverse-defs body env1)] + ;;[_ (pretty-print `(env2 ,(atenv->pretty env2)))] + [env3 (atenv:unflush (atenv:flush! env2))] + ;;[_ (pretty-print `(env3 ,(atenv->pretty env2)))] + [exports + (map + (match-lambda + [(lvr . z-sym) + (let* ( [binding (zodiac:varref-binding lvr)] + [ftype (atenv:lookup env3 binding)] + [_ (assert (FlowType? ftype) 'atlunit-unit->atunit + binding)] + [ftype (link-parsed-ftype! lvr ftype)]) + (cons (zodiac:read-object z-sym) ftype))]) + exports)] + [imports + (map (lambda (name) + (cons (zodiac:binding-var name) + (filter-map + (match-lambda + [(name2 . tvar) + (and (eq? name name2) tvar)]) + refs))) + imports)]) + (make-atunit imports exports result unit-exp))])) + +;; ---------------------------------------------------------------------- + +(define (apply-atlunit-cmpd atlunit partial-import-list) + (match atlunit + [($ atlunit-cmpd _ + (and cmpd-unit + ($ zodiac:compound-unit-form _ start _ _ + import-bindings links exports)) + times ftype*) + (: import-bindings (listof zodiac:lexical-binding)) + (: links + (listof (list sym zodiac:parsed (listof (cons (union sym #f) sym))))) + (: times (listof num)) + (: ftype* (listof FlowType)) + (: exports (listof (list sym sym sym))) + + (pretty-debug-unit + `(apply-atlunit-cmpd + ,(map zodiac:binding-orig-name import-bindings) + ,(zodiac:stripper cmpd-unit) + ,(map FlowType->pretty ftype*) + ,exports + ,(and partial-import-list + (map FlowType->pretty (map car partial-import-list))))) + + (letrec* + ( [time-N (zodiac-time cmpd-unit)] + [saved-refs '()] ; forward refs and refs to some imports + [imports (map zodiac:binding-orig-name import-bindings)] + [import-env + (cond + [(eq? partial-import-list #f) '()] + [(not (= (length imports) (length partial-import-list))) + (mrspidey:warning + (format "Compound-unit requires ~s imports, given ~s" + (length imports) (length partial-import-list)) + start 0) + '()] + [else + (map + (lambda (import-binding import ftype-time) + (let* ( [ftype (car ftype-time)] + [_ (assert (FlowType? ftype) 'atlunit-3 ftype)] + [ftype (link-parsed-ftype! import-binding ftype)] + [ftype-time (cons ftype (cdr ftype-time))]) + (cons import ftype-time))) + import-bindings + imports + partial-import-list)])] + [import-refs (make-vector (length imports) '())] + [access-import + (lambda (sym) + (match (lookup-or-fail import-env sym (lambda () (cons #f 0))) + [(ftype . itime) + (values + (or ftype + (let ([tvar (mk-Tvar 'get-export)] + [n (index imports sym)]) + (if n + (vector-set! import-refs n + (cons tvar (vector-ref import-refs n))) + (mrspidey:warning + (format + "Symbol ~s not in import list of compound-unit" + sym) + (zodiac:zodiac-start cmpd-unit) 7)) + tvar)) + (max time-N itime))]))] + ;; alist of tags and function to access exports + [tag->access (list (cons #f access-import))] + [tag.sym->ftype.time + (lambda (tag sym) + (assert (or (not tag) (symbol? tag)) tag 'tag.sym->ftype.time2) + (assert (symbol? sym) sym 'tag.sym->ftype.time2) + (match (lookup-or-#f tag->access tag) + [(? procedure? access) (access sym)] + [#f (let ([tvar (mk-Tvar 'forward-get-export)]) + (set! saved-refs (cons (list tag sym tvar) saved-refs)) + (values tvar time-N))]))] + [last-invoked-unit #f] + [_ + (for-each + (lambda (link time-U ftype) + (match-let* + ( [(tag _ . i*) link] + ;; [_ (pretty-print `(i* ,i* tag ,tag link ,link))] + ;; tag is not a zodiac:parsed, so cant hang type off it + ;; [ftype (link-parsed-ftype! tag ftype)] + [tag (zodiac:read-object tag)] + ;; Figure out imports + [import-ftype.times + (map + (lambda (i) + (let*-vals + ([(tag sym) + (match i + [(tag . sym) + (values + (zodiac:read-object tag) + (zodiac:read-object sym))] + [($ zodiac:lexical-varref) + (values #f + (zodiac:binding-orig-name + (zodiac:varref-binding i)))])] + [_ (assert (or (not tag) (symbol? tag)) 1)] + [(ftype itime) (tag.sym->ftype.time tag sym)] + ;;#[ftype (link-parsed-ftype! i ftype)] + ) + (cons ftype itime))) + i*)] + [time-export (apply max time-N time-U + (map cdr import-ftype.times))] + [_ (pretty-debug-unit + `(apply-atlunit-cmpd + invoking ,tag ,ftype ,import-ftype.times))] + [invoked-unit (apply-unit ftype import-ftype.times)] + [_ (pretty-debug-unit + `(apply-atlunit-cmpd result tag ,tag ,invoked-unit))] + [_ (set! last-invoked-unit invoked-unit)] + [access-exports + (match invoked-unit + [($ atunit imports exports) + (lambda (sym) + (match (lookup-or-#f exports sym) + [#f (mrspidey:warning + (format + "Exported var ~s not in unit tagged ~s in compound-unit" + sym tag) + cmpd-unit 9) + (values (mk-tvar-void) 0)] + [ftype (values ftype time-export)]))] + [(? Tvar? tvar-u) + (lambda (sym) + (let ([tvar (mk-Tvar 'get-export)]) + (new-con! tvar-u + (create-con (get-unit-export-template sym) + 0 tvar #t)) + (values tvar time-export)))])]) + + (set! tag->access (cons (cons tag access-exports) tag->access)) + (set! saved-refs + (filter + (match-lambda + [(tag2 sym tvar) + (if (eq? tag tag2) + (let-values ([(ftype _) (access-exports sym)]) + (new-edge! (FlowType->Tvar ftype) tvar) + #f) + #t)]) + saved-refs)))) + links times ftype*)] + + [unit-imports (map cons imports (vector->list import-refs))] + [unit-exports + (map + (match-lambda + [(and export (tag id . e-id)) + (let*-vals + ([(ftype _) + (tag.sym->ftype.time + (zodiac:read-object tag) + (zodiac:read-object id))] + ;;#[ftype (link-parsed-ftype! export ftype)] + ) + (cons (zodiac:read-object e-id) ftype))]) + exports)] + [result + (match last-invoked-unit + [#f (wrap-value (mk-tvar-void))] + [($ atunit _ _ result) result] + [(? Tvar? tvar-u) + (let ([tvar (mk-Tvar 'cmpd-unit-result)]) + (new-con! tvar-u (create-con template-unit 0 tvar #t)) + tvar)])]) + + (make-atunit unit-imports + unit-exports + result + cmpd-unit))])) + +;; ---------------------------------------------------------------------- +(define regenerating-ftype (void)) + +(define (apply-atlunit-reference atlunit partial-import-list) + (match atlunit + [($ atlunit-reference _ + (and N ($ zodiac:reference-unit-form _ _ _ _ file kind))) + + (pretty-debug-unit + `(apply-atlunit-reference + ,(zodiac:location-line (zodiac:zodiac-start N)) + pil ,(pretty-partial-import-list partial-import-list))) + + (let*-vals + ( [_ (unless (zodiac:string? file) + (mrspidey:error + "reference-unit requires a string argument, given ~s" + file))] + [file (zodiac:read-object file)] + [path+file + (if (relative-path? file) + (build-path (current-directory) file) + file)] + [file-directory (path-only path+file)] + [(_ file _) (split-path path+file)] + [za (regexp-replace ".ss$" file ".za")] + [_ (when (eq? za file) + (mrspidey:error + (format "Invalid extension on ~s, requires .ss" + file)))] + [t-N (zodiac-time* N)] + [za (case (st:save-za-in) + [(source-directory) + (build-path file-directory za)] + [(tmp-directory) + (build-path + (wx:find-path 'temp-dir) + (file-name-from-path za))])] + [t-za (file-modify-seconds za)] + + ;; restrict imports to prims, closed schemas, and atstructs + [partial-import-list-restricted + (and partial-import-list + (map + (match-lambda + [(ftype . itime) + (cons + (and (fo-FlowType? ftype) + (match (fo-FlowType-def ftype) + [(or ($ schema _ _ ()) (? atprim?) (? atstruct?)) + ftype] + [_ #f])) + itime)]) + partial-import-list))] + [_ (pretty-debug-unit + `(pil-restricted + ,(pretty-partial-import-list + partial-import-list-restricted)))] + + [port-for-included-unit + (lambda () + (dynamic-let ([current-directory file-directory]) + (open-code-file file)))] + + [traverse-included-unit + ;; (zodiac:parsed -> (union atunit atlunit)) + (lambda () + (let*-vals + ([_ (mrspidey:progress + (format "Analyzing referenced unit ~a" file))] + [_ (extend-file-time-cache! path+file t-N)] + [exps (zodiac:read* (port-for-included-unit) path+file)] + [(parsed-exps free-names) + (dynamic-let + ([current-directory file-directory]) + (my-scheme-expand-program exps))] + [_ (unless (= (length parsed-exps) 1) + (mrspidey:error + (format + "reference-unit file ~s not a single exp" + path+file)))] + [parsed-exp (car parsed-exps)] + [_ (pretty-debug + `(traverse-included-unit + ,(zodiac:stripper parsed-exp)))] + [gtr global-tref-env] + [gtd global-tdef-env] + [gtb global-tbang-env] + [init-env (get-default-bindings free-names)] + [(ftype env refs) (traverse-exp parsed-exp init-env)] + [ftype (extract-1st-value ftype)] + [ftype + (case kind + [(exp) ftype] + [(imp) (create-fo-FlowType + (apply-unit ftype + partial-import-list-restricted))])] + [savable-ftype (make-savable-ftype ftype)] + [atunit (FlowType->Atype savable-ftype)] + [_ (unless (atunit? atunit) + (mrspidey:error + (format + "reference-unit file did not produce an annotated unit ~s" + atunit) + N))] + [nu-tref (get-prefix global-tref-env gtr)] + [nu-tdef (get-prefix global-tdef-env gtd)] + [nu-tbang (get-prefix global-tbang-env gtb)] + ) + (init-global-tenv! gtr gtd gtb) + (pretty-debug-unit `(nu-tbang ,nu-tbang)) + (for-each + (match-lambda + [(binding . _) + (mrspidey:warning + (format + "Unit refs imported var ~s of enclosing unit" + (zodiac:binding-orig-name binding)))]) + refs) + (values + exps parsed-exp + savable-ftype nu-tref nu-tdef nu-tbang)))] + + [l-start list-ftype] + [(ftype tref tdef tbang regenerate) + (if (and (st:unit-read-za) t-za (< t-N t-za)) + + ;; ------ + ;; Just load from the file for delta-min + (let*-vals + ( [s (format "Loading ~a" (file-name-from-path za))] + [_ (mrspidey:progress s '...)] + [(delta-min tref tdef tbang) (read-za za)] + [_ (mrspidey:progress s 'done)]) + + (values delta-min tref tdef tbang traverse-included-unit)) + + ;; ------ + ;; Regenerate + (let*-vals + ( [separate-S + (and + (st:unit-separate-S) + (not (memq (st:unit-simplify) '(none nonempty))))] + [s "Saving kernel state:"] + [kernel-state + (when separate-S + (begin + (mrspidey:progress s '...) + (begin0 + (save-kernel-state) + (init-kernel!) + (mrspidey:progress s 'done))))] + [l2 list-ftype] + [(exps parsed-exp ftype nu-tref nu-tdef nu-tbang) + ;; we don't consider indirectly included files + ;; to be included + (parameterize ([record-analyzed-file-hook + (lambda (filename . _) + (void))]) + (traverse-included-unit))] + [l1 list-ftype] + ;;[_ (close-constraints (filter Tvar? (get-prefix l1 l2)))] + [E (append + (savable-ftype-external-vars ftype) + (map cdr nu-tref) + (map cdr nu-tdef) + (map cdr nu-tbang))] + [_ (pretty-debug-unit + `(external vars + ,(map FlowType-name E) + ,(FlowType-name ftype) + ,(map FlowType-name + (savable-ftype-external-vars ftype)) + ,(map FlowType-name (map cdr nu-tref)) + ,(map FlowType-name (map cdr nu-tdef)) + ,(map FlowType-name (map cdr nu-tbang))))] + + ;;[_ (show-stat-small)] + ;; Restore state + [s "Restoring kernel state"] + [new-kernel-state + (when separate-S + (mrspidey:progress s '...) + (begin0 + (save-kernel-state) + (restore-kernel-state! kernel-state) + (mrspidey:progress s 'done)))] + + [s "Simplifying constraints"] + [_ (mrspidey:progress s '...)] + [l3 list-ftype] + [(list-tvar tvar->nu) + (minimize-constraints-&-compare + (st:unit-simplify) E E l1 l2)] + [_ (mrspidey:progress s 'done)] + + ;; debugging test + [_ '(mrspidey:progress "debugging-test" '...)] + [_ '(check-unreachable + (get-prefix l1 l2) + (get-prefix list-ftype l3))] + [_ '(really-check-kernel-ok)] + [_ '(mrspidey:progress "debugging-test" 'done)] + + + [ftype2 (update-ftype ftype tvar->nu)] + [upd-binding + (match-lambda + [(sym . tvar) (cons sym (tvar->nu tvar))])] + [upd-tref (map upd-binding nu-tref)] + [upd-tdef (map upd-binding nu-tdef)] + [upd-tbang (map upd-binding nu-tbang)]) + + (when separate-S + (when (st:zero-old-constraint-sets) + (free-kernel-state! new-kernel-state)) + (when (st:zero-old-asts) + (zodiac:zero! exps) + (zodiac:zero! parsed-exp))) + ;;(show-stat-small) + + ;; Stuff to save in list-tvar, ftype2, + ;; upd-tref, upd-tdef, upd-tbang + + (when (st:unit-write-za) + (write-za + za list-tvar ftype2 + upd-tref upd-tdef upd-tbang)) + + (values ftype2 upd-tref upd-tdef upd-tbang + (if separate-S + traverse-included-unit + (lambda () + (values + exps parsed-exp + ftype nu-tref nu-tdef nu-tbang))))))] + [_ (ok-ftype ftype)] + [l-end list-ftype] + [_ + ;; Mark new ftypes as from .za file + (for-each + (lambda (ftype) + (set-FlowType-type-annotation! ftype path+file)) + (get-prefix l-end l-start))] + [atunit (apply-unit ftype partial-import-list)]) + + (pretty-debug-unit `(tbang ,tbang)) + + (begin + (for-each (match-lambda [(s . t) (add-global-tref! s t)]) tref) + (for-each (match-lambda [(s . t) (add-global-tdef! s t)]) tdef) + (for-each (match-lambda [(s . t) (add-global-tbang! s t)]) tbang)) + + (ok-ftype ftype) + + (record-analyzed-file + path+file + (lambda () (port-for-included-unit)) + (lambda () + (set! regenerating-ftype ftype) + (ok-ftype ftype) + + (let*-vals + ( [s (format "Regenerating included unit ~a" + (file-name-from-path file))] + [_ (mrspidey:progress s)] + [(exps parsed-exp ftype2 tref2 tdef2 tbang2) + ((lambda () (regenerate)))]) + (ok-ftype ftype) + (flow-d! ftype2 ftype) + (flow-e! tdef2 tdef) + (flow-e! tbang2 tbang) + (flow-e! tref tref2) + (list parsed-exp)))) + + (unless (atunit? atunit) + (mrspidey:error + (format + "reference-unit file did not produce an annotated unit ~s" + atunit))) + + atunit)])) + +;; ---------------------------------------------------------------------- + +(define (make-savable-ftype ftype) + ;; Converts an ftype to a "savable" ftype + ;; ie a tvar, a closed schema, a primitive, an atstruct + ;; or an atunit with savable exports and result + ;; atvalues could also be made savable, if there is any need + (if (Tvar? ftype) + ftype + (match (fo-FlowType-def ftype) + [($ schema tvar tvar* '()) ftype] + [($ atunit imports exports result exp) + (create-fo-FlowType + (make-atunit imports + (map (match-lambda + [(sym . ftype) + (cons sym (make-savable-ftype ftype))]) + exports) + (make-savable-ftype result) + exp))] + [(and atlunit ($ atlunit)) + (make-savable-ftype (create-fo-FlowType (atlunit->atunit atlunit)))] + [(and pi ($ atprim name type)) ftype] + [(? atstruct?) ftype] + [_ (FlowType->Tvar ftype)]))) + +;; -------------------- + +(define (savable-ftype-external-vars ftype) + (if (Tvar? ftype) + (list ftype) + (match (fo-FlowType-def ftype) + [($ schema tvar tvar* '()) (list tvar)] + [($ atprim) '()] + [($ atunit imports exports result exp) + (apply append + (append (map cdr imports) + (map savable-ftype-external-vars (map cdr exports)) + (list (savable-ftype-external-vars result))))] + [($ atstruct) '()] + [x (mrspidey:internal-error 'savable-ftype-external-vars + "Bad Atype ~s" x)]))) + +;; -------------------- + +(define (update-ftype ftype tvar->nu) + ;; Creates a copy of ftype with new type variables + (if (Tvar? ftype) + (tvar->nu ftype) + (create-fo-FlowType + (match (fo-FlowType-def ftype) + [($ schema tvar tvar* '()) + (make-schema (tvar->nu tvar) (filter-map tvar->nu tvar*) '())] + [(? atprim? atprim) atprim] + [($ atunit imports exports result exp) + (make-atunit + (map (match-lambda + [(sym . tvar*) (cons sym (map tvar->nu tvar*))]) + imports) + (map (match-lambda + [(sym . ftype) + (cons sym (update-ftype ftype tvar->nu))]) + exports) + (update-ftype result tvar->nu) + exp)] + [(? atstruct? atstruct) atstruct])))) + +;; -------------------- + +(define (flow-d! ftype2 ftype) + (let ([E2 (savable-ftype-external-vars ftype2)] + [E (savable-ftype-external-vars ftype)]) + (pretty-debug-unit + `(E ,(map FlowType-name E) E2 ,(map FlowType-name E2))) + (unless (= (length E) (length E2)) + (mrspidey:error + (format "The .za file is incompatible, and may be of date (~s ~s)" + (length E) (length E2)))) + (for-each new-bidir-edge! E E2))) + +;; -------------------- + +(define (ok-ftype ftype) + (pretty-debug-unit `(ok-ftype ,(FlowType-name ftype))) + (let ([E (savable-ftype-external-vars ftype)]) + (pretty-debug-unit `(E ,(map FlowType-name E))) + (for-each + (lambda (tvar) + (assert (list? (FlowType-arrowto tvar)) + 'ok-ftype (FlowType-num ftype))) + E))) + +;; -------------------- + +(define (flow-e! env env2) + (assert (= (length env) (length env2)) 'flow-e! env env2) + (for-each new-bidir-edge! (map cdr env) (map cdr env2))) + +;; ---------------------------------------------------------------------- + +;(trace apply-unit) +;(trace apply-atlunit) +;(trace apply-atlunit-unit) +;(trace apply-atlunit-cmpd) +;(trace apply-atlunit-reference) +;(trace atlunit->atunit) diff --git a/collects/mrspidey/Sba/atype.ss b/collects/mrspidey/Sba/atype.ss new file mode 100644 index 0000000..ff89dc2 --- /dev/null +++ b/collects/mrspidey/Sba/atype.ss @@ -0,0 +1,343 @@ +;; atype.ss - handles annotated types +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +;; ---------------------------------------------------------------------- +;; FlowType - expr, edgeto, edgefrom, type-annotation +;; Tvar - sub-structure of FlowType, is type variable +;; fo-FlowType - FlowType with def field containing fo-Atype +;; fo-Atype - atprim etc, see below +;; Atype - Tvar or fo-Atype +;; ---------------------------------------------------------------------- + +(define-const-typed-structure (fo-FlowType struct:FlowType) + ( (: def fo-Atype) + (: tvar Tvar))) + +(define (FlowType->Atype ftype) + (cond + [(Tvar? ftype) ftype] + [(fo-FlowType? ftype) (fo-FlowType-def ftype)] + [else + (mrspidey:internal-error 'FlowType->Atype "Bad ftype ~s" ftype)])) + +(define (create-fo-FlowType fo-atype) + (assert (fo-Atype? fo-atype) 'create-fo-FlowType fo-atype) + (if (and + (not (st:use-fo-ftype)) + (or + (atconst? fo-atype) + (and (atvalues? fo-atype) + (andmap Tvar? (atvalues-values fo-atype))))) + (Atype->Tvar fo-atype) + (add-FlowType! + (make-fo-FlowType num-ftype #f '() '() #f '() #f fo-atype #f)))) + +;; ---------- + +(define-type fo-Atype + (union atconst schema atprim atthunk atstruct atvalues + atunit atlunit)) + +(define (fo-Atype? x) + (or (atconst? x) + (schema? x) + (atprim? x) + (atthunk? x) + (atstruct? x) + (atvalues? x) + (atunit? x) + (atlunit? x))) + +(define (poly-atype? x) + (or (schema? x) + (atthunk? x))) + +;; -------------------- +;; atconst + +(define-const-typed-structure + atconst ((: c (union num bool)))) + +;; -------------------- +;; schema + +(define-const-typed-structure + schema ((: tvar Tvar) + (: tvar* (listof Tvar)) + (: edges (listof (cons Tvar Tvar))))) + +;; -------------------- +;; atprim + +(define-const-typed-structure + atprim ((: sym sym) + (: type sexp) + (: domain-filters (listof filter)) + predicate-fn + attrs + orig-type + )) + +;; filter-domains is a list of filters for various args, +;; if no error raised +;; inj-predicate is a fn : list-tvar x list-tvar x tvar x bool -> Tvar +;; used for (if (pred ... x ...) ...) + +;; -------------------- +;; atthunk + +(define-const-typed-structure + atthunk ((: thunk (-> FlowType)))) + +;; -------------------- +;; atstruct + +(define-const-typed-structure + atstruct ((: struct:sym sym) + (: super-constructors (listof sym)) + parent-gen-args + parent-match-args + parent-field-types + parent-list-mutable)) + +;; ---------------------------------------------------------------------- +;; atvalues + +(define-const-typed-structure + atvalues ((: values (listof FlowType)))) + +(define (wrap-value x) + (let* ([ftype (cond + [(FlowType? x) x] + [(fo-Atype? x) (create-fo-FlowType x)] + [else (mrspidey:internal-error + 'wrap-value "Bad x ~s" x)])] + [ftype (if (or (FlowType-expr ftype) + (FlowType-values-ftype ftype)) + (copy-ftype ftype) + ftype)] + [r (create-fo-FlowType (make-atvalues (list ftype)))]) + (set-FlowType-values-ftype! ftype r) + (pretty-debug-atype + `(wrap-value ,(FlowType-name ftype) ,(FlowType-name r))) + r)) + +(define (extract-1st-value ftype) + (car (multiple-value-components ftype 1))) + +(define (multiple-value-components ftype n) + ;; returns list of n value components + (assert (integer? n) 'multiple-value-components) + (cond + [(zero? n) '()] + [(fo-FlowType? ftype) + (match (fo-FlowType-def ftype) + [($ atvalues l) + (recur loop ([n n][l l]) + (cond [(zero? n) '()] + [(null? l) (cons (mk-tvar-empty) (loop (sub1 n) '()))] + [else (let* ( [a (car l)] + [b (copy-ftype a) ]) + ;(if (FlowType-expr a) (copy-ftype a) a) + (when need-explanation (add-FlowType-arrow! ftype b)) + (cons b (loop (sub1 n) (cdr l))))]))] + [_ #f])] + [else + (let ( [tvar-mv (FlowType->Tvar ftype)] + [tvar (mk-Tvar 'get-mvalues)]) + (new-con! tvar-mv (create-con template-mvalues 0 tvar #t)) + (recur loop ([tvar tvar][n n]) + (let ([a (mk-Tvar 'car-value)]) + (new-con! tvar (make-con-car a)) + (when need-explanation (add-FlowType-arrow! tvar-mv a)) + (cons a + (if (= n 1) + '() + (let ([d (mk-Tvar 'cdr-value)]) + (new-con! tvar (make-con-cdr d)) + (loop d (sub1 n))))))))])) + +;; ---------------------------------------------------------------------- +;; Annotated (lazy) unit types + +(define-const-typed-structure + atunit + ((: imports (listof (cons sym (listof Tvar)))) + (: exports (listof (cons sym FlowType))) + (: result FlowType) + (: expr zodiac:parsed))) + +(define-const-typed-structure + atlunit ((! ui (union false atunit)))) + +;; ---------------------------------------------------------------------- + +;; (: FlowType->Tvar (FlowType -> Tvar)) + +(define (FlowType->Tvar ftype) + (let ([tvar + (cond + [(Tvar? ftype) ftype] + [(fo-FlowType? ftype) + (or (fo-FlowType-tvar ftype) + (let ([tvar (Atype->Tvar (fo-FlowType-def ftype))]) + (when need-explanation (add-FlowType-arrow! ftype tvar)) + ;(set-fo-FlowType-tvar! ftype tvar) + tvar))] + [else + (mrspidey:internal-error 'FlowType->Tvar "Bad FlowType ~s" ftype)])]) + (pretty-debug-atype + `(FlowType->Tvar ,(FlowType-name ftype) ,(Tvar-name tvar))) + tvar +)) + +(define Atype->Tvar + (lambda (atype) + (let ([tvar + (match atype + [(? Tvar? tvar) tvar] + [($ atconst c) + (let ([tvar (mk-Tvar 'atconst->tvar)]) + (new-AV! tvar (traverse-const-exact c)) + tvar)] + [($ atstruct) (mk-tvar-void)] + [($ atthunk thunk) (thunk)] + [(and pi ($ atprim name type)) + (let ([tvar (mk-Tvar name)]) + (tschema->con type tvar name pi) + tvar)] + [($ schema tvar tvar* edges) + (copy-constraint-set tvar tvar* edges)] + [($ atunit imports exports result) + (pretty-debug-atype + `(Atype->Tvar (atunit ,imports ,exports ,result))) + (let ([tvar-u (mk-Tvar 'inst-unit)]) + (for-each-with-n + (lambda (import n) + (map (lambda (tvar) + (new-AV! tvar-u + (create-AV (get-unit-import-template n) + '() (vector) (vector tvar)))) + (cdr import))) + imports) + (for-each + (match-lambda + [(sym . ftype) + (new-AV! tvar-u + (create-AV (get-unit-export-template sym) + '() (vector (FlowType->Tvar ftype)) (vector)))]) + exports) + (new-AV! tvar-u + (create-AV template-unit '() + (vector (FlowType->Tvar result)) + (vector))) + tvar-u)] + [(and atlunit ($ atlunit)) + (Atype->Tvar (atlunit->atunit atlunit))] + [($ atvalues ftype*) + (let ([tvar-list + (foldr + (lambda (ftype tvar-rest) + (let* ([tvar (mk-Tvar 'atvalues->tvar)]) + (new-AV! tvar + (make-AV-cons (FlowType->Tvar ftype) + tvar-rest)) + tvar)) + (mk-tvar-nil) + ftype*)] + [tvar (mk-Tvar 'atvalues->values)]) + (new-AV! tvar + (create-AV template-mvalues '() + (vector tvar-list) (vector))) + tvar)] + [x (mrspidey:internal-error 'Atype->Tvar "Bad Atype ~s" x)])]) + (pretty-debug-atype + `(atype->tvar ,(Atype->pretty atype) ,(Tvar-name tvar))) + tvar))) + +;; ---------------------------------------------------------------------- + +(define FlowType->pretty + (lambda (ftype) + (cond + [(Tvar? ftype) (Tvar-name ftype)] + [(fo-FlowType? ftype) + (Atype->pretty (fo-FlowType-def ftype))]))) + +(define Atype->pretty + (match-lambda + [($ atconst c) `(const ,c)] + [($ atthunk thunk) 'thunk] + [(and pi ($ atprim name _ _ _ attrs type)) `(prim ,name ,type)] + [($ schema tvar tvar* edges) + `(schema ,(Tvar-name tvar) ,(map Tvar-name tvar*))] + [($ atunit imports exports result) + `(atunit + (imports ,@(map (match-lambda + [(sym . tvar*) + (cons sym (map Tvar-name tvar*))]) + imports)) + (exports ,@(map (match-lambda + [(sym . ftype) + (list sym (FlowType->pretty ftype))]) + exports)) + (result ,(FlowType->pretty result)))] + [($ atlunit thunk) `(lazy-unit)] + [($ atstruct A B C D E F) (list 'struct: A B C D E F)] + [($ atvalues ftype*) `(values ,@(map FlowType->pretty ftype*))] + [x + (mrspidey:internal-error 'Atype->pretty "Bad fo-Atype ~s" x)])) + +(define FlowType->SDL + (lambda (ftype) + (pretty-debug-sdl2 + `(FlowType->SDL ,(FlowType-name ftype) ,(FlowType->pretty ftype))) + (cond + [(Tvar? ftype) (Tvar->SDL ftype)] + [(fo-FlowType? ftype) + (match (fo-FlowType-def ftype) + [($ atconst c) `(const ,c)] + [($ atthunk thunk) `(thunk ,(Tvar->SDL (thunk)))] + [($ atprim name _ _ _ _ type) `(prim ,type)] + [($ schema tvar tvar* edges) `(schema ,(Tvar->SDL tvar))] + [(and def ($ atunit imports exports result)) + `(unit ,(Tvar->SDL (FlowType->Tvar ftype)))] + [(and ($ atlunit thunk) lui) + `(lazy ,(FlowType->SDL (create-fo-FlowType (atlunit->atunit lui))))] + [($ atstruct) 'struct:] + [($ atvalues (ftype)) (FlowType->SDL ftype)] + [($ atvalues ftype*) `(values ,@(map FlowType->SDL ftype*))] + [x (mrspidey:internal-error 'FlowType->SDL "Bad fo-Atype ~s" x)])] + [else (mrspidey:internal-error 'FlowType->SDL "Bad ftype ~s" ftype)]))) + +(define (copy-ftype ftype) + (cond + [(Tvar? ftype) + (let ([tvar (mk-Tvar 'copy)]) + (new-edge! ftype tvar) + tvar)] + [(fo-FlowType? ftype) + (let ([nu-ftype (create-fo-FlowType (fo-FlowType-def ftype))]) + (when need-explanation (add-FlowType-arrow! ftype nu-ftype)) + nu-ftype)] + [else (mrspidey:internal-error 'link-parsed-ftype! + "Bad ftype ~s, maybe old language" ftype)])) + +;; ---------------------------------------------------------------------- + + diff --git a/collects/mrspidey/Sba/checks.ss b/collects/mrspidey/Sba/checks.ss new file mode 100644 index 0000000..c66453e --- /dev/null +++ b/collects/mrspidey/Sba/checks.ss @@ -0,0 +1,716 @@ +;; smart-checks.ss - identifies unsafe operations +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + + +;;------------------------------------------- + +(define-struct annotation (loc)) +(define-struct (check-annotation struct:annotation) (text num rest)) +(define-struct (uncheck-annotation struct:annotation) (text)) +(define-struct (type-annotation struct:annotation) (end-first finish FlowType)) + +;; ------------------------------ + +(define check-annotations '()) ; store away checks for mred +(define uncheck-annotations '()) ; store away unchecked prims + +;;------------------------------- +;; Counters + +(define prim-count (void)) +(define lam-count (void)) +(define prim-apps (void)) +(define user-apps (void)) +(define ivar-count (void)) +(define type-assert-count (void)) +(define type-assert-failed-total (void)) + +(define prim-checks-def (void)) +(define lam-checks-def (void)) +(define ap-checks-def (void)) +(define ivar-checks-def (void)) +(define type-assert-failed-def (void)) + +(define total-checks (void)) + +;; -------------------- + +(define init-counts + (lambda () + (set! prim-count (make-counter)) + (set! lam-count (make-counter)) + (set! prim-apps (make-counter)) + (set! user-apps (make-counter)) + (set! ivar-count (make-counter)) + (set! type-assert-count (make-counter)) + (set! type-assert-failed-total (make-counter)) + (set! total-checks (make-counter)) + (reset-counts))) + +;; These three count per expression +;; need to be reset with every definition traversed. + +(define reset-counts + (lambda () + (set! prim-checks-def (make-counter)) + (set! lam-checks-def (make-counter)) + (set! ap-checks-def (make-counter)) + (set! ivar-checks-def (make-counter)) + (set! type-assert-failed-def (make-counter)))) + + (define make-counter + (lambda () + (let ([num 0]) + (lambda (n) + (set! num (+ n num)) + num)))) + +;; ---------------------------------------- + +(define calc-checks + (lambda (defs) + (mrspidey:add-summary (format "CHECKS:")) + (init-counts) + (set! check-annotations '()) + (set! uncheck-annotations '()) + (for-each-with-n + (lambda (def n) + (mrspidey:zprogress "Checking" (zodiac:zodiac-start def)) + (match def + [($ zodiac:define-values-form _ open _ _ + ($ zodiac:list _ _ _ ($ zodiac:varref _ _ _ _ sym)) + _) + (reset-counts) + ((zodiac:compat check-fn) def) + ;;(make-check-summary-line sym open) + ] + [_ + (reset-counts) + ((zodiac:compat check-fn) def) + '(make-check-summary-line + (format " at line ~s" + (zodiac:location-line + (zodiac:zodiac-start def))) + (zodiac:zodiac-start def)) + ])) + defs) + (unless (null? defs) + (mrspidey:zprogress "Checking" (zodiac:zodiac-finish (rac defs)))) + (make-check-summary "") + (list check-annotations uncheck-annotations))) + +;; ---------- + +(define check-fn + (lambda (M unp) + (pretty-debug-check `(check-fn ,(zodiac:stripper M))) + (match M + ;; ivars + [($ zodiac:app _ _ _ _ + ($ zodiac:varref _ open _ _ (and ivar-sym (or '#%uq-ivar 'uq-ivar))) + (obj-exp ivar-arg)) + (=> fail) + (pretty-debug-check `(ivar ,ivar-sym)) + + ;; Check the ivar is ok + (let*-vals + ( [ftype (zodiac:parsed-ftype obj-exp)] + [ftype (and ftype (extract-1st-value ftype))] + [(tvars-ivarset-ok? set-tvar-ivarset-ok!) + (alloc-Tvar-field)]) + (letrec + ([check-ivarset-ok? + (lambda (tvar sym) + (pretty-debug-check `(check-ivarset-ok? ,(Tvar-name tvar))) + (set-tvar-ivarset-ok! tvar #t) + (andmap + (match-lambda + [($ AV _ (? (lambda (t) (eq? t template-ivarset))) + misc fields+) + (assert (list? misc) 'ivar-check) + (or + (memq sym misc) + (let ([parent (vector-ref fields+ 0)]) + (and (not (null? (get-Tvar-objs parent))) + (check-ivarset-ok? parent sym))) + (begin + (pretty-debug-check + `(ivar-failure ,sym ,misc ,(Tvar-name tvar))) + #f) + )] + [_ #t]) + (get-Tvar-objs tvar)))]) + (if + (match ivar-arg + [($ zodiac:quote-form _ _ _ _ ($ zodiac:symbol _ _ _ sym)) + (and (Tvar? ftype) (check-ivarset-ok? ftype sym))] + [_ #f]) + (begin + (ivar-count 1) + (add-uncheck! open (symbol->string ivar-sym))) + (begin + (ivar-count 1) + (ivar-checks-def 1) + (mrspidey:add-summary "ivar check" open 0) + (add-check! open (symbol->string ivar-sym)))))) + + ;; Check the primitive application - NOT! + '(match ivar-arg + [($ zodiac:quote-form _ _ _ _ ($ zodiac:symbol _ open _ sym)) + (let* ([ftype (zodiac:parsed-ftype M)]) + (when ftype + (let ([ftype (extract-1st-value ftype)]) + (when (Tvar? ftype) + (pretty-debug-check '(ivar-tvar)) + (match (get-Tvar-objs ftype) + [(($ AV _ (? (lambda (t) (eq? t template-lam))) + (and pi ($ atprim name type)))) + (pretty-debug-check '(ivar-lam-AV)) + (case (check-prim pi (zodiac:parsed-ftype M)) + [(#t) + (prim-count 1) + (add-uncheck! open (symbol->string sym))] + [(#f) + (prim-count 1) + (mrspidey:add-summary "Method check" open 0) + (prim-checks-def 1) + (add-check! open (symbol->string sym) ftype) + (pretty-debug `(CHECK-fo-prim ,(zodiac:stripper M))) + (zodiac:set-parsed-check! ivar-arg #t)] + [(not-function-type) + (pretty-debug-check '(ivar-not-fn-type))] + [(not-function-AV) (printf "ivar:not-function-AV~n")])] + [_ (void)])))))] + [_ (void)]) + (fail)] + [($ zodiac:app _ _ _ _ fn args) + (unless (atprim? (zodiac:parsed-atprim fn)) + (check-ap M)) + #f] + [($ zodiac:case-lambda-form) + (check-lambda M) + #f] + [($ zodiac:top-level-varref) + (if (zodiac:parsed-atprim M) + (check-ho-prim M) + ;; Otherwise should do bound? check, but don't + (void)) + #f] + [($ zodiac::-form) + (check-type-assertion M) + #f] + [_ #f]))) + +;;------------------------------------------- + +(define (parsed-Tvar x) + ;;(pretty-print `(parsed-Tvar ,(zodiac:stripper x))) + (if (zodiac:parsed-ftype x) + (let* ( [ftype (zodiac:parsed-ftype x)] + [tvar (FlowType->Tvar ftype)]) + (pretty-debug-check + `(parsed-Tvar ,(zodiac:stripper x) ,(FlowType-name ftype) + ,(Tvar-name tvar))) + tvar) + (mk-tvar-empty))) + +(define check-ap + (match-lambda + [(and app ($ zodiac:app _ open _ _ fun args)) + (pretty-debug-check + `(check-ap,(zodiac:stripper fun) ,(zodiac:parsed-ftype fun))) + (let ([ftype-fn (zodiac:parsed-ftype fun)]) + (match (and (FlowType? ftype-fn) (FlowType->Atype ftype-fn)) + [($ atprim) (prim-apps 1)] + [_ (user-apps 1)])) + (let ([tvar (parsed-Tvar fun)]) + (unless + (or + (st:all-checks) + (Tvar-in-type? tvar + '(mvalues (cons (lambda _ _) (nil))) + '() + (lambda (a) + (mrspidey:error 'check-ap + "Reference to unbound type var ~s" a)))) + ;; Check the application + (ap-checks-def 1) + (mrspidey:add-summary "Application check" open 0) + (add-check! open "(" tvar) + (pretty-debug `(CHECK-ap ,(zodiac:stripper app))) + (zodiac:set-parsed-check! app #t)))])) + +(define check-lambda + (match-lambda + [(and lam ($ zodiac:case-lambda-form _ open _ _ arglists bodies)) + (pretty-debug-check `(check-lam ,(zodiac:stripper lam))) + ;; put arity check on lambda + (lam-count 1) + (let* ( [tvar (parsed-Tvar lam)] + [tvar (extract-1st-value tvar)]) + (match (get-Tvar-objs tvar) + [(($ AV _ (? (lambda (t) (eq? t template-lam))) misc _ #(domain)) + . _) + ;; rest may be other AV-lam's for this case-lambda + (let* ([arglist->ilist + (match-lambda + [($ zodiac:sym-arglist) + '_] + [($ zodiac:list-arglist vars) + (map (lambda (_) '_) vars)] + [($ zodiac:ilist-arglist vars) + (recur loop ([vars vars]) + (match vars + [(x) '_] + [(a . b) `(_ . ,(loop b))]))])] + [type + (recur loop ([ilists (map arglist->ilist arglists)]) + (pretty-debug-check `(ilists ,ilists)) + (if (memq '_ ilists) + '_ + (let ( [nils + (filter null? ilists)] + [non-nils + (filter + (lambda (x) (not (null? x))) + ilists)]) + (cond + [(null? non-nils) + 'nil] + [(null? nils) + `(cons _ ,(loop (map cdr non-nils)))] + [else + `(union + nil + (cons _ ,(loop (map cdr non-nils))))]))))]) + (pretty-debug-check `(type ,type)) + + (when + (or + (st:all-checks) + (not (Tvar-in-type? + domain (expand-input-type type) '() + (lambda (a) + (mrspidey:internal-error 'check-lambda + "unbound tvar"))))) + ;; Check it + (lam-checks-def 1) + (mrspidey:add-summary "Arity check" open 0) + (add-check! open "lambda" domain) + (zodiac:set-parsed-check! lam #t)))] + [_;; never analyzed + (void)]))])) + +(define (check-ho-prim M) + ;; name : name-structure of prim + ;; open: source location for primitive + ;; returns correct primitive and either 1 or 0 + + (pretty-debug-check `(check-ho-prim ,(zodiac:stripper M))) + + (match-let* + ( [($ zodiac:varref _ open _ _ sym) M] + [(and atprim ($ atprim sym tschema _ _ _)) (zodiac:parsed-atprim M)]) + + (match (parsed-Tvar M) + [(? Tvar? tvar) + + (case (check-prim atprim tvar) + [(#t) + (prim-count 1) + (add-uncheck! open (symbol->string sym))] + [(#f) + (prim-count 1) + (mrspidey:add-summary (format "~s check" sym) open 0) + (prim-checks-def 1) + (add-check! open (symbol->string sym) tvar) + (pretty-debug `(CHECK-fo-prim ,(zodiac:stripper M))) + (zodiac:set-parsed-check! M #t)] + [(not-function-type) (void)] + [(not-function-AV) + ;(printf "check-hoo-prim: not-function-AV~n") + (void)])]))) + +;; ---------------------------------------------------------------------- + +(define (check-prim atprim tvar) + + (pretty-debug-check `(check-prim ,atprim ,(Tvar-name tvar) )) + + (match (get-Tvar-objs (extract-1st-value tvar)) + [(($ AV _ template misc _ #(domain))) + (check-prim-domain atprim domain)] + [_ 'not-function-AV])) + +(define (check-prim-domain atprim domain) + (pretty-debug-check `(check-prim-domain ,atprim ,(Tvar-name domain) )) + (match-let* + ( [($ atprim sym tschema _ _ _) atprim] + [schemas (match tschema + [('case-> . schemas) schemas] + [schema (list schema)])]) + + (ormap + (lambda (schema) + + (let-values ([(forall type) (split-schema schema)]) + (match type + [('lambda expected-domain _) + (pretty-debug-check `(check-prim domain ,(Tvar-name domain))) + (if (and + (Tvar-in-type? + domain expected-domain forall + (lambda (a) + (mrspidey:warning + (format + "Reference to unbound type var ~s in domain of ho primitive ~s" + a sym)) + (lambda (AV) #f))) + (not (st:all-checks))) + #t + (begin + (pretty-debug-check + `(check-prim-domain failed on ,sym + ,(FlowType-name domain) + ,expected-domain)) + #f))] + [_ + ;; Not a primitive function + (pretty-debug-check `(Not a prim fn ,type)) + 'not-function-type]))) + + schemas))) + +;; ---------------------------------------------------------------------- + +(define check-type-assertion + (match-lambda + [(and M ($ zodiac::-form _ open _ _ exp type)) + (pretty-debug-check `(check-type-assertion ,(zodiac:stripper M))) + (type-assert-count 1) + (let* ([tvar (extract-1st-value (parsed-Tvar exp))] + [in-type? + (lambda (type) + (Tvar-in-type? + tvar (expand-input-type type) '() + (lambda (a) + (mrspidey:warning + (format "Unbound type variable ~s" a) + open 3) + (lambda (AV) #f))))]) + (unless + (match type + [('exact type) + ;; Can't do exact yet - best is nonempty + (and (not (null? (get-Tvar-objs tvar))) (in-type? type))] + [_ (in-type? type)]) + ;; Is bad + (type-assert-failed-def 1) + (type-assert-failed-total 1) + (add-check! open "(") + (mrspidey:warning + (format "Type assertion ~s failed" + (list ': '... ;;(zodiac:stripper exp) + type)) + (zodiac:zodiac-start M) + 2)))])) + +;; ---------------------------------------------------------------------- + +'(define (Tvar-in-global-type? ftype type where) + (Tvar-in-type? + Tvar + (expand-input-type type) + (lambda (fv) + (lookup-or-fail + global-tdef-env fv + (lambda () + (mrspidey:error + (format + "Reference to unbound type var ~s in ~a ~s" + fv where type))))))) + +;; ---------------------------------------------------------------------- + +(define (add-check! open text . rest) + (set! check-annotations + (cons (make-check-annotation open text (total-checks 0) rest) + check-annotations)) + (total-checks 1)) + +(define (add-uncheck! open text) + (set! uncheck-annotations + (cons (make-uncheck-annotation open text) uncheck-annotations))) + +(define (show-checks) + (for-each + (match-lambda + [($ annotation ($ zodiac:location l c o f) text) + (printf "File: ~s offset ~s text ~s~n" + (file-name-from-path f) o text)]) + check-annotations)) + +;; ---------------------------------------------------------------------- + +(define (file-wrapper-start outport) + ;; Writes prefix to file + ;(fprintf outport ";; Generated by SBA Soft Scheme ~a~%" st:version) + (fprintf outport ";; Control string ") + (for-each (lambda (x) (fprintf outport" '~a" x)) (mrspidey:control-fn)) + (fprintf outport "~n~n")) + +(define (file-wrapper-end outport) + (newline outport) + '(for-each (lambda (s) (fprintf outport ";; ~a" s)) + (reverse summary)) + (void) + ) + +;; ---------------------------------------------------------------------- + +'(define (write-soft-file outfile) + ;; Writes soft typed file - macro expanded with checks - executable + (when (file-exists? outfile) (delete-file outfile)) + (let ([outport (open-output-file outfile)]) + + (file-wrapper-start outport) + (for-each + (lambda (def) + (pretty-print + ((zodiac:unparse-dynamic-letd + (lambda (exp cl-fn) + (if (zodiac:parsed-check exp) + (match exp + [($ zodiac:app _ open close back fun args) + `(CHECK-ap ,(cl-fn fun) ,@(map cl-fn args))] + [($ zodiac:lambda-form _ open close back + args body level) + (let* ([args (map-ilist cl-fn args)]) + `(CHECK-lambda ,args ,(cl-fn body)))] + [($ zodiac:lexical-varref + _ open close _ + ($ zodiac:bound _ _ _ _ sym) + Tvar-box) + (symbol-append 'CHECK- sym)]) + #f))) + def) + outport) + (newline outport)) + defs-bind) + (file-wrapper-end outport))) + +;; ---------------------------------------------------------------------- + +'(define (write-annotated-file outfile source-thunk) + ;; As source file, but with checks + (when (file-exists? outfile) (delete-file outfile)) + (let* ([inport (source-thunk)] + [outport (open-output-file outfile)] + [checks (map + (match-lambda + [($ annotation loc) + (cons (zodiac:location-offset loc) rest)]) + check-annotations)] + [checks (sort + (match-lambda* + [((ofs1 . _) (ofs2 . _)) (< ofs1 ofs2)]) + checks)]) + + (file-wrapper-start outport) + (recur loop ([pos 0][checks checks]) + (let ([c (read-char inport)]) + (unless (eof-object? c) + (match checks + [(( (? (lambda (p) (= p pos))) + num name . _) + . _) + (let ([to-drop + (match name + ["(" + ;; Is an application check + (assert (char=? c #\()) + (display (format "(CHECK-ap ~s " num) + outport) + ""] + ["lambda" + ;; Is a lambda check + (assert (char=? c #\()) + (display (format "(CHECK-lambda ~s " num) + outport) + "lambda"] + [prim + ;; Is a primitive check + (assert (char=? c (string-ref prim 0))) + (display (format "(CHECK-~a ~s)" name num) + outport) + (substring prim 1 (string-length prim))])]) + (recur loop2 ([pos (add1 pos)] + [s (string->list to-drop)]) + (cond + [(null? s) (loop pos (cdr checks))] + [(char=? (read-char inport) (car s)) + (loop2 (add1 pos) (cdr s))] + [else + (error 'write-annotated-file + "File not as expected")])))] + [_ + (write-char c outport) + (loop (add1 pos) checks)])))) + + (close-input-port inport) + (file-wrapper-end outport) + (close-output-port outport))) + +;; -------------------- + +(define make-check-summary-line + (lambda (name src) + (let ([total (+ (prim-checks-def 0) (lam-checks-def 0) + (ap-checks-def 0) (type-assert-failed-def 0))]) + (unless (= 0 total) + (let* ((s (format "~a~a " (padr name 19) (padl total 3))) + (s (if (< 0 (prim-checks-def 0)) + (format "~a (~a prim)" s (prim-checks-def 0)) + s)) + (s (if (< 0 (lam-checks-def 0)) + (format "~a (~a lambda)" s (lam-checks-def 0)) + s)) + (s (if (< 0 (ap-checks-def 0)) + (format "~a (~a ap)" s (ap-checks-def 0)) + s)) + (s (if (< 0 (type-assert-failed-def 0)) + (format "~a (~a type assertions)" + s (type-assert-failed-def 0)) + s))) + (mrspidey:add-summary s src 0)))))) + +;; -------------------- + +(define make-check-summary + (lambda (hdr) + (let* ([f (lambda (s) (mrspidey:add-summary s))] + [total-possible + (+ (user-apps 0) (prim-count 0) (lam-count 0) + (type-assert-count 0))] + [percentage + (if (= 0 total-possible) + 0 + (string->number + (chop-number + (exact->inexact (* (/ (total-checks 0) + total-possible) 100)) + 4)))]) + + (f (format "~a~a~a~a" + hdr + (padr "TOTAL CHECKS:" 19) + (padl (total-checks 0) 3) + (format " (of ~s possible checks is ~s%)" + total-possible percentage))) + + (unless (zero? (type-assert-failed-total 0)) + (f (format "~a~a~a~a" + hdr + (padr "FAILED ASSERTIONS:" 19) + (padl (type-assert-failed-total 0) 3) + (format " (of ~s total type assertions)" + (type-assert-count 0))))) + + ))) + +;;---------------------------------------------------------------------- + +(define (calc-type-annotations defs) + (let* ( [type-annotations '()] + [locs-done-table-size 2048] + [locs-done-mask 2047] + [loc->ndx (lambda (loc) + (bitwise-and (zodiac:location-offset loc) + locs-done-mask))] + [locs-done-table (make-vector locs-done-table-size '())] + [fn + (lambda (exp cl-fn) + (match exp + [($ zodiac:parsed origin start finish) + (let* ([ftype (zodiac:parsed-ftype exp)] + [end-first (zodiac:determine-end-first-token exp)]) + + (pretty-debug + `(ftype ,(and (FlowType? ftype) (FlowType-name ftype)) + start ,(zodiac:location-offset start))) + + (when + (and + (FlowType? ftype) + ;;(memq (zodiac:origin-who origin) '(source reader)) + ) + + ;; Don't add type-annotation if something else has this + ;; start location + (let ([ndx (loc->ndx start)]) + (when (not (find + (lambda (l) + (= (zodiac:location-offset l) + (zodiac:location-offset start))) + (vector-ref locs-done-table ndx))) + ;; Check FlowType points to exp + (assert (or (eq? (FlowType-expr ftype) exp) + (eq? (FlowType-expr ftype) #t)) + 'calc-type-annotation ftype + (FlowType-expr ftype) exp) + '(set-FlowType-expr! ftype exp) + (set! type-annotations + (cons + (make-type-annotation + start end-first finish ftype) + type-annotations)) + (vector-set! + locs-done-table ndx + (cons start (vector-ref locs-done-table ndx))))))) + #f] + [_ #f]))]) + + (map-with-n + (lambda (exp n) + (begin + (mrspidey:zprogress "Typing" (zodiac:zodiac-start exp)) + ((zodiac:compat fn) exp))) + defs) + (unless (null? defs) + (mrspidey:zprogress "Typing" (zodiac:zodiac-finish (rac defs)))) + + type-annotations)) + +;; ---------------------------------------------------------------------- + + + + + + + + + + + + + + + + + diff --git a/collects/mrspidey/Sba/config.ss b/collects/mrspidey/Sba/config.ss new file mode 100644 index 0000000..6d8237f --- /dev/null +++ b/collects/mrspidey/Sba/config.ss @@ -0,0 +1,312 @@ +;; config.ss +;; Lots of parameters for analysis +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define st:restricted + (not (string? (current-load-relative-directory)))) +(define st:name "MrSpidey") +(define st:version (lambda () "49s1")) + +;; ---------------------------------------------------------------------- +;; Front end parameters + +(define st:fake-reader (make-parameter-boolean #f)) +(define st:system-expand (make-parameter-boolean #f)) + +;; ---------------------------------------------------------------------- +;; Analysis parameters + +(define st:constants (make-parameter-boolean #f)) +(define st:const-merge-size (make-parameter-integer 7)) + +(define st:if-split (make-parameter-boolean #t)) +; If #t, then knowledgeable about if's + +(define st:flow-sensitive (make-parameter-boolean #t)) +; If #t, then in (begin (car x) (cdr x)), cdr is never checked + +(define st:fo-units (make-parameter-boolean #t)) +;; If #t, then first-order units treated specially + +(define st:lazy-fo-units (make-parameter-boolean #t)) +;; If #t, then first-order units treated specially + +(define st:cache-units (make-parameter-boolean #t)) +;; If #t, then first-order units treated specially + +(define st:whole-program (make-parameter-boolean #t)) + +(define st:special-fo-prims (make-parameter-boolean #t)) +(define st:see-void (make-parameter-boolean #t)) +(define st:cons-mutable (make-parameter-boolean #t)) +(define st:use-fo-ftype (make-parameter-boolean #t)) + +(define need-label-types #t) +(define need-explanation #t) + +(define st:zero-old-constraint-sets (make-parameter-boolean #t)) +(define st:zero-old-asts (make-parameter-boolean #t)) + +;; ---------------------------------------------------------------------- +;; Simplification parameters + +(define constraint-simplification-list + (if st:restricted + '( + (none "No simplification") + (nonempty "Remove empty constraints") + (live "Remove empty and unreachable constraints") + (live-few-e "As above, and also remove epsilon constraints") + ((live-few-e dfa-min-glb dfa-min-lub) + "Live, few epsilon, DFA min") + ) + '( + (none "No simplification") + (nonempty "Remove empty constraints") + (nonempty-copy "Copy nonempty") + (live "Remove empty and unreachable constraints") + (live-few-e-L "Live, few lower epsilon") + (live-few-e-U "Live, few upper epsilon") + (live-few-e "Live, few epsilon") + ((live-few-e dfa-min-lub) + "Live, few epsilon, DFA min LUB") + ((live-few-e dfa-min-glb) + "Live, few epsilon, DFA min GLB") + ((live-few-e dfa-min-lub dfa-min-glb) + "Live, few epsilon, DFA min") + ))) + +(define make-constraint-simplification-para + (case-lambda + [() (make-constraint-simplification-para 'live-few-e)] + [(default) + (make-parameter-list + default + constraint-simplification-list + (lambda (_) (void)) + ;; also-ok? + (lambda (x) + (and (list? x) + (andmap + (lambda (y) (member y (map car constraint-simplification-list))) + x))))])) + +(define st:minimize-respect-assignable-part-of-fields + (make-parameter-boolean #t)) + +;; ---------------------------------------------------------------------- +;; Polymorphism parameters + +(define st:constraint-simplification-poly (make-constraint-simplification-para)) + +(define st:polymorphism + (make-parameter-list 'compress + `((none "No polymorphism") + (compress "Simplify constraints") + ;;(copy-con "") + (reanalyze "Reanalyze") + ))) + +;; ---------------------------------------------------------------------- +;; Unit parameters + +(define st:unit-read-za (make-parameter-boolean #t)) +(define st:unit-write-za (make-parameter-boolean #t)) +(define st:unit-simplify + (make-constraint-simplification-para 'live-few-e)) +(define st:unit-separate-S (make-parameter-boolean #t)) +(define st:save-za-in + (make-parameter-list + 'source-directory + `( (source-directory "Source file directory" "") + (tmp-directory + ,(string-append + (if (defined? 'wx:find-path) + (wx:find-path 'temp-dir) " directory")) + "")))) + +;; ---------------------------------------------------------------------- +;; Type Viewing parameters + +;; --- copying + +(define st:sdl-fo + (make-parameter-list + 'basic-types + '( (basic-types "Basic Types" "ie (1 -> 1)") + (type-schemas "Type Schemas" "ie (X1 -> X1)")))) + +(define st:sdl-fo-ivars (make-parameter-boolean #t)) +(define st:sdl-fo-struct-fields (make-parameter-boolean #t)) +(define st:sdl-fo-depth-limit? (make-parameter-boolean #t)) +(define st:sdl-fo-depth-limit (make-parameter-integer 50)) +(define st:sdl-fo-size-limit? (make-parameter-boolean #t)) +(define st:sdl-fo-size-limit (make-parameter-integer 50)) + +;; --- simplification + +(define st:sdl-constraint-simplification + (make-constraint-simplification-para 'live-few-e)) + +(define st:show-assignable-part-of-fields + (make-parameter-boolean #f)) + +;; --- to SDL + +(define st:listify-etc (make-parameter-boolean #t)) + +(define st:sdl-constructor/selector + (make-parameter-list + 'constructor + '((constructor "Show types as constructors" "") + (selector "Show types as selectors" "")))) + +(define st:naming-strategy + (make-parameter-list + 'multiple + (if st:restricted + '((recursive "Recursive" "Name types on cycles") + (multiple "Multiple" "Name types referenced more than once") + (nontrivial "Non-Trivial" "Name non-trivial types") + (all "All" "Name all types")) + '((recursive "Recursive" "Name types on cycles") + (multiple "Multiple" "Name types referenced more than once") + (nontrivial "Non-Trivial" "Name non-trivial types") + (all "All" "Name all types"))))) + +(define st:primitive-types + (make-parameter-list + 'inferred + '((prim "(prim ...)" "ie (prim car)") + (given "Given types" "ie ((cons a b) -> a)") + (inferred "Inferred types" "ie ((cons 'a-symbol 4) -> 'a-symbol)")))) + +;; --- simplifying SDL + +(define st:expand-output-type (make-parameter-boolean #t)) +(define st:sdl-tidy (make-parameter-boolean #t)) + +;; --- + +(define st:pretty-type-width (make-parameter-integer 60)) + +;; ---------------------------------------------------------------------- + +(define st:check-kernel (make-parameter-boolean #f)) +(define st:compare-min-algs (make-parameter-boolean #f)) + +;; ---------------------------------------------------------------------- +;; Checking parameters + +(define st:all-checks (make-parameter-boolean #f)) + +;; ---------------------------------------------------------------------- +;; control - interface to all parameters + +(define mrspidey:control-fn + (let ([paras + (begin-elaboration-time + (cons 'list + (map + (lambda (x) (list 'cons (list 'quote x) x)) + '(;; --- Analysis time + st:constants + st:const-merge-size + st:fo-units + st:if-split + st:flow-sensitive + st:special-fo-prims + st:system-expand + st:see-void + st:unit-read-za + st:unit-write-za + st:save-za-in + ;; --- Polymorphism + st:polymorphism + st:constraint-simplification-poly + ;;st:library-prims + ;;st:topo-sort + ;; --- Seperate analysis + st:unit-simplify + ;; --- Type viewing + st:sdl-fo + st:sdl-fo-ivars + st:sdl-fo-struct-fields + st:sdl-fo-depth-limit? + st:sdl-fo-depth-limit + st:sdl-fo-size-limit? + st:sdl-fo-size-limit + st:sdl-constraint-simplification + st:show-assignable-part-of-fields + st:listify-etc + st:sdl-constructor/selector + st:naming-strategy + st:primitive-types + st:expand-output-type + st:sdl-tidy + st:pretty-type-width + + ;; --- checking parameters + st:all-checks + ))))]) + (match-lambda* + [() + ;; Return list of all settings + (map + (match-lambda [(sym . para) (list sym (para))]) + paras) + ] + [(para-name) + ;; Return one setting + (match (assq para-name paras) + [(_ . para) (para)] + [#f (error 'mrspidey:control "Unknown parameter ~s" para-name)])] + [(para-name nu-val) + ;; Return one setting + (match (assq para-name paras) + [(_ . para) + (if (memq nu-val (map car (para '?))) + (para nu-val) + (error 'mrspidey:control "Value ~s invalid for parameter ~s" + nu-val para-name))] + [#f + (error 'mrspidey:control "Unknown parameter ~s" para-name)])] + [_ (error 'mrspidey:control "Bad # arguments")]))) + +;====================================================================== + +(when st:restricted + ;; . special configuration, if necy + (void) + ) + + + + + + + + + + + + + + + + diff --git a/collects/mrspidey/Sba/contain.ss b/collects/mrspidey/Sba/contain.ss new file mode 100644 index 0000000..c7652a6 --- /dev/null +++ b/collects/mrspidey/Sba/contain.ss @@ -0,0 +1,155 @@ +;; contained.ss +;; +;; Check if one Tvar is contained in another +;; Doesn't work for contravariant fields +;; Not currently used +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +;; ---------------------------------------------------------------------- +;; NOTE: Tvar2 must be tidy!!! + +(define stack '()) +(define fail-stack '()) + +(define Tvar-containment? + (lambda (tvar1 tvar2) + (let*-vals + ( [calc-reached + (lambda (tvar) + (let*-vals + ([(reached? set-reached! get-reached) + (field->set alloc-Tvar-field)]) + (recur traverse ([tvar tvar]) + (unless (reached? tvar) + (set-reached! tvar) + (for-each + (match-lambda + [($ AV _ ($ template _ _ _ ref) _ fields+ field-) + (vector-for-each traverse fields+)]) + (get-Tvar-objs tvar)))) + (get-reached)))] + [list-reached-1 (calc-reached tvar1)] + [list-reached-2 (calc-reached tvar2)] + [num-reached-1 (length list-reached-1)] + [(get-num set-num!) (alloc-Tvar-field)] + [(get-reached-vec set-reached-vec!) (alloc-Tvar-field)] + ) + + (for-each-with-n (lambda (tvar n) (set-num! tvar n)) + list-reached-1) + + (for-each + (lambda (tvar) (set-reached-vec! tvar (make-vector num-reached-1 #f))) + list-reached-2) + + ;; Tidyness check + '(for-each + (lambda (tvar) + (let* ([objs (get-Tvar-objs tvar)] + [templates (map AV-template objs)] + [types (map template-type templates)] + [types2 (list->set types)]) + (unless (= (length types) (length types2)) + (mrspidey:error + (format "Upper bound of containment is not tidy, types are ~s" + types))))) + list-reached-2) + + (begin0 + (let/cc + fail + + (recur ensure-contained ([tvar1 tvar1][tvar2 tvar2]) + (fluid-let ([stack (cons (cons tvar1 tvar2) stack)]) + (let ([n (get-num tvar1)] + [reached (get-reached-vec tvar2)]) + (unless (vector-ref reached n) + ;; Need to search - record true to detect loops + (vector-set! reached n #t) + (for-each + (match-lambda + [($ AV _ (and template ($ template _ _ ref)) _ fields+) + (or + + ;; More than one matching => not tidy => say contained. + (> (count (match-lambda + [($ AV _ template2) + (eq? (template-type template) + (template-type template2))]) + (get-Tvar-objs tvar2)) + 1) + + (ormap + (match-lambda + [($ AV _ template2 _ fields2+) + (and ;(eq? template template2) + (or + (eq? + (template-type template) + (template-type template2)) + (memq + template2 + (template-super-templates template))) + (begin + (for i 0 + (min + (vector-length fields+) + (vector-length fields2+)) + (ensure-contained + (vector-ref fields+ i) + (vector-ref fields2+ i))) + #t))]) + (get-Tvar-objs tvar2)) + + ;; No match + (begin + '(printf + "~s ~s not in ~s ~s~n" + (map (lambda (AV) (template-type (AV-template AV))) + (get-Tvar-objs tvar1)) + (Tvar-name tvar1) + (map (lambda (AV) (template-type (AV-template AV))) + (get-Tvar-objs tvar2)) + (Tvar-name tvar2)) + (set! fail-stack stack) + (fail #f)))]) + (get-Tvar-objs tvar1)))))) + + ;; Did not fail => succeed + #t) + + )))) + +'(define (show-fail-stack-sdl) + (map + (match-lambda + [(a . d) + (list (Tvar->SDL a) + (Tvar->SDL d))]) + fail-stack)) + +'(define (show-fail-stack) + (for-each + (match-lambda + [(a . d) + (printf "============~n") + (show-Tvar a) + (show-Tvar d)]) + fail-stack)) + + diff --git a/collects/mrspidey/Sba/contained.ss b/collects/mrspidey/Sba/contained.ss new file mode 100644 index 0000000..594aca1 --- /dev/null +++ b/collects/mrspidey/Sba/contained.ss @@ -0,0 +1,129 @@ +;; contained.ss +;; +;; Check if one Tvar is contained in another +;; Doesn't work for contravariant fields +;; ---------------------------------------------------------------------- +;; NOTE: Tvar2 must be tidy!!! + +(define stack '()) +(define fail-stack '()) + +(define Tvar-containment? + (lambda (tvar1 tvar2) + (let*-vals + ( [calc-reached + (lambda (tvar) + (let*-vals + ([(reached? set-reached! get-reached) + (field->set alloc-Tvar-field)]) + (recur traverse ([tvar tvar]) + (unless (reached? tvar) + (set-reached! tvar) + (for-each + (match-lambda + [($ AV _ ($ template _ _ ref) _ fields) + (for i 0 (vector-length ref) + (traverse + (vector-ref fields (vector-ref ref i))))]) + (get-Tvar-objs tvar)))) + (get-reached)))] + [list-reached-1 (calc-reached tvar1)] + [list-reached-2 (calc-reached tvar2)] + [num-reached-1 (length list-reached-1)] + [(get-num set-num!) (alloc-Tvar-field)] + [(get-reached-vec set-reached-vec!) (alloc-Tvar-field)] + ) + + (for-each-with-n (lambda (tvar n) (set-num! tvar n)) + list-reached-1) + + (for-each + (lambda (tvar) (set-reached-vec! tvar (make-vector num-reached-1 #f))) + list-reached-2) + + ;; Tidyness check + '(for-each + (lambda (tvar) + (let* ([objs (get-Tvar-objs tvar)] + [templates (map AV-template objs)] + [types (map template-type templates)] + [types2 (list->set types)]) + (unless (= (length types) (length types2)) + (mrspidey:error + (format "Upper bound of containment is not tidy, types are ~s" + types))))) + list-reached-2) + + (begin0 + (let/cc + fail + + (recur ensure-contained ([tvar1 tvar1][tvar2 tvar2]) + (fluid-let ([stack (cons (cons tvar1 tvar2) stack)]) + (let ([n (get-num tvar1)] + [reached (get-reached-vec tvar2)]) + (unless (vector-ref reached n) + ;; Need to search - record true to detect loops + (vector-set! reached n #t) + (for-each + (match-lambda + [($ AV _ (and template ($ template _ _ ref)) _ fields) + (or + + ;; More than one matching => not tidy => say contained. + (> (count (match-lambda + [($ AV _ template2 _ fields2) + (eq? (template-type template) + (template-type template2))]) + (get-Tvar-objs tvar2)) + 1) + + (ormap + (match-lambda + [($ AV _ template2 _ fields2) + (and ;(eq? template template2) + (eq? (template-type template) + (template-type template2)) + (begin + (for i 0 (vector-length ref) + (let ([r (vector-ref ref i)]) + (ensure-contained + (vector-ref fields r) + (vector-ref fields2 r)))) + #t))]) + (get-Tvar-objs tvar2)) + ;; No match + (begin + (printf + "~s ~s not in ~s ~s~n" + (map (lambda (AV) (template-type (AV-template AV))) + (get-Tvar-objs tvar1)) + (Tvar-name tvar1) + (map (lambda (AV) (template-type (AV-template AV))) + (get-Tvar-objs tvar2)) + (Tvar-name tvar2)) + (set! fail-stack stack) + (fail #f)))]) + (get-Tvar-objs tvar1)))))) + + ;; Did not fail => succeed + #t) + + )))) + +'(define (show-fail-stack-sdl) + (map + (match-lambda + [(a . d) + (list (Tvar->SDL a) + (Tvar->SDL d))]) + fail-stack)) + +'(define (show-fail-stack) + (for-each + (match-lambda + [(a . d) + (printf "============~n") + (show-Tvar a) + (show-Tvar d)]) + fail-stack)) diff --git a/collects/mrspidey/Sba/debug.ss b/collects/mrspidey/Sba/debug.ss new file mode 100644 index 0000000..008b3da --- /dev/null +++ b/collects/mrspidey/Sba/debug.ss @@ -0,0 +1,37 @@ +;; debugging.ss + +(define debugging #f) +(define debugging-front #f) +(define debugging-traverse #f) +(define debugging-object #f) +(define debugging-unit #f) +(define debugging-check #f) +(define debugging-atenv #f) +(define debugging-atype #f) +(define debugging-sdl #f) +(define debugging-sdl2 #f) +(define debugging-gui #t) + +(define debugging-min #f) +(define debugging-min2 #f) +(define debugging-few #f) +(define debugging-gram #f) +(define debugging-dfa-min #f) +(define debugging-min-table #f) + +(define timing-min #f) + +(define pretty-print-debug pretty-print) + +(define (set-debug-flag which val) + (case which + [(general) (set! debugging val)] + [(min) (set! debugging-min val)] + [(front) (set! debugging-front val)] + [(traverse) (set! debugging-traverse val)])) + +;(set! debugging #t) +;(set! debugging-min #t) +;(set! debugging-gram #t) +;(set! debugging-min-table #t) +;(set! timing-min #t) diff --git a/collects/mrspidey/Sba/devel.ss b/collects/mrspidey/Sba/devel.ss new file mode 100644 index 0000000..f66431b --- /dev/null +++ b/collects/mrspidey/Sba/devel.ss @@ -0,0 +1,1081 @@ +;; devel.ss +;; Development helper file +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ---------------------------------------------------------------------- +;; Timing + +(defmacro trace-time args + (match args + [(fn) + (let* ([c (box 0)] + [f (gensym)]) + `(begin + (define ,f ,fn) + (define ,fn (lambda args + (record-time ,c + (lambda () (apply ,f args))))) + ,c))])) + +(define counter-fns + '( + st: + analyze-program + zodiac:read* + top-level-parse-defs + top-level-parse-exp + top-level-traverse-defs + open-code-file + system-expand-port + expand-zexp->port + + minimize-constraints + find-nonempty-tvars + copy-live-constraints + copy-live-constraints-noe + copy-live-constraints-few-e + minimize-constraints-dfa-min + minimize-constraints-dfa-min-inv + minimize-constraints-dfa-min-1 + minimize-constraints-dfa-min-2 + + copy-constraints-equiv! + find-nonempty-nts-rhs-nts + calc-live-tvars-nts + ;; copy-constraint-set + Hopcroft-calc-equivalences + + read-za + write-za + calc-checks + + calc-productions! + Tvar-in-type? + + resize-hash-table + save-kernel-state + restore-kernel-state! + free-kernel-state! + zodiac:zero! + + ;atenv:extend + ;atenv:lookup + ;atenv:change-binding + ;atenv:capture-locs + ;atenv:unflush + ;atenv:flush! + ;zodiac:free-vars + + ;chema->con + initialize-analysis! + get-default-bindings + )) + +(define counter-nonfns + '( ;;live-data + )) + +(define counters + (append + (map + (lambda (fn) + (let ([c (cons 0 0)] + [f (gensym)]) + (eval + `(begin + (define ,f (if (defined? ',fn) ,fn (lambda (x) x))) + (define ,fn (lambda args + (record-time ',c + (lambda () (apply ,f args))))))) + (list fn c))) + counter-fns) + (map + (lambda (name) + (let ([c (cons 0 0)]) + (eval `(define ,(symbol-append name '-counter) (quote ,c))) + (list name c))) + counter-nonfns))) + +(define (show-counters) + (printf "COUNTERS:~n") + (for-each + (match-lambda + [(f (n . t)) + (unless (zero? t) + (printf " ~a ~a ~a ms~n" (padr f 35) (padl n 5) (padl t 7)))]) + counters) + (printf " ~a ~a ~a ms~n" + (padr "ANALYSIS TIME" 35) + (padl 1 5) + (padl (apply - + (map get-counter + '( + analyze-program + zodiac:read* + top-level-parse-defs + top-level-parse-exp + open-code-file + expand-zexp->port + initialize-analysis! + get-default-bindings + ))) + 7))) + +(define (clear-counters!) + (initialize-analysis!) + (set! hash-table '()) + (set! global-defs-parsed '()) + (set! global-def-env '()) + ;;((collect-request-handler) (collect-maximum-generation)) + (for-each + (match-lambda + [(f c) (set-car! c 0) (set-cdr! c 0)]) + counters)) + +(define (get-counter c) + (ormap + (match-lambda + [(f (n . t)) + (if (eq? f c) t #f)]) + counters)) + +;(collect-notify #t) + +(define (with-counters f args) + (clear-counters!) + (apply f args) + (show-counters) + (show-stats)) + +;; ====================================================================== +;; Setup live-data-counter + +'(define base-data-live 0) + +'(define my-collect + (lambda args + (apply #%collect args) + ;;(#%collect 4) + (set-car! live-data-counter (add1 (car live-data-counter))) + (let ([live (truncate (/ (- (bytes-allocated) base-data-live) 1000))]) + (set-cdr! live-data-counter (max (cdr live-data-counter) live)) + (when (collect-notify) + (printf "GC: HWM ~sK + ~sK~n" + (truncate (/ base-data-live 1000)) + live) + (show-stat-small))))) +;;(collect-request-handler my-collect) + +;; ====================================================================== +;; Compare counters under different strategies + +(define (diff-counters th1 th2) + (th1) + ;;((collect-request-handler) (collect-maximum-generation)) + (show-stat) + (let ([t* (map cdadr counters)]) + (th2) + ;;((collect-request-handler) (collect-maximum-generation)) + (show-stat) + (printf "DIFFERENCE IN TIMES:~n") + (for-each + (match-lambda* + [((f (n . t2)) t) + (unless (and (zero? t) (zero? t2)) + (printf " ~a ~a vs ~a, extra ~a ms~n" + (padr f 35) (padl t 7) (padl t2 7) (padl (- t2 t) 7)))]) + counters t*))) + +(define (diff-times files) + (diff-counters + (lambda () + (dynamic-let ([st:analysis 'sba]) (tsal files))) + (lambda () + (dynamic-let ([st:analysis 'za-reanalyze]) (tsal files))))) + +(define (diff-times2 files) + (diff-counters + (lambda () + (dynamic-let ([st:unit-simplify 'live]) (tsal files))) + (lambda () + (dynamic-let ([st:unit-simplify 'dfa-min]) (tsal files))))) + +;; ====================================================================== +;; Check correctness of seperate analysis + +(define ord-types '()) +(define sep-types '()) + +(define (test-seperate-same files) + (dynamic-let + ([st:type-compression '(basic-types . tidy)] + [st:primitive-types 'inferred]) + (let ([def-types + (lambda () + (printf "Calculating types ...") + (begin0 + (filter + (match-lambda + [($ sym-def sym def) (symbol? sym)]) + global-out-env) + (printf " done~n")))]) + (diff-counters + (lambda () + (dynamic-let ([st:analysis 'sba]) + (tsal files) + (set! ord-types (def-types)))) + (lambda () + (dynamic-let ([st:analysis 'za-reanalyze]) + (tsal files) + (set! sep-types (def-types))))) + (printf "Comparing types ... ~n") + (unless (= (length ord-types) (length sep-types)) + (error 'test-seperate-same + "Different lengths")) + (for-each + (match-lambda* + [(($ sym-def sym1 def1) + ($ sym-def sym2 def2)) + (unless (eq? sym1 sym2) + (error 'test-seperate-same "Different symbols defined")) + (unless (and (Tvar? def1) (ftype? def2)) + (error 'test-seperate-same "Definition not Tvar")) + (unless (and (Tvar-containment? def1 def1) + (Tvar-containment? def2 def2)) + (error 'test-seperate-same "Tvar-containment? bad")) + (unless (and (Tvar-containment? def1 def2) + (Tvar-containment? def2 def1)) + (dynamic-let ([st:type-compression '(first-order . none)]) + (printf "Ordinary type~n") + (pretty-print (Tvar->SDL def1)) + (printf "Seperate type~n") + (pretty-print (Tvar->SDL def2)))dev + (error 'test-seperate-same "Definitions of ~s differ" sym1))]) + ord-types sep-types) + (printf "Types are identical~n")))) + +;; ====================================================================== +;; Results File + +(define results-file "/home/cormac/Spidey/results/results") + +(define (clear-results) + (system (format "\\rm ~s" results-file))) + +(define (write-results title size) + (let ([p (open-output-file results-file 'append)] + [o `(RESULTS + ,title + (size ,size) + (num-ftype ,num-Atype) + (num-AV ,num-AV) + (num-con ,num-con) + (num-edge ,num-edge) + (num-AV-a ,num-AV-in-Tvar) + (entries ,entries-in-table) + ,counters + ,(mrspidey:control-fn))]) + (pretty-print o p) + (close-output-port p) + o)) + +(define (analyze-and-write-results files) + (tsal files) + (write-results files (apply + (map calc-AST-size global-defs-parsed)))) + +;; ====================================================================== +;; Scaling of (st:analysis 'sba) + +(define (test-scaling-file files) + (printf "TEST-SCALING-FILE ~s~n" files) + (dynamic-let + ([st:analysis 'sba]) + (analyze-and-write-results files))) + +(define (test-scaling) + (cd "/home/cormac/Spidey") + (clear-results) + (map test-scaling-file (map list benchmark-files)) + (test-scaling-file sba-kernel-spj) + (test-scaling-file TC-spj) + (test-scaling-file t11-spj) + (test-scaling-file sba-zodiac-spj) + (test-scaling-file sba-small-spj) + ;;(test-scaling-file sba-spj) + ) + +(define (test-scaling-sba) + ;; Add on extra sba files one-by-one + (recur loop ([f '()] + [r (append + sba-small-spj + (filter + (lambda (x) (not (member x sba-small-spj))) + sba-spj))]) + (unless (null? r) + (let ([f (append f (list (car r)))]) + (test-scaling-file f) + (loop f (cdr r)))))) + +(define matlab-scaling-file "/home/cormac/Spidey/results/scaling.m") +(define get-results-file + (case-lambda + [() (get-results-file results-file)] + [(file) + (match-let* + ([l '()] + [_ (with-input-from-file file + (lambda () + (recur loop () + (let ([x (read)]) + (unless (eof-object? x) + (match x + [('quote . _) (void)] + [_ (set! l (append l (list x)))]) + (loop))))))] + ;; Group l together by filename + ;; grouped-l: (listof (listof info)) + [grouped-l (recur loop ([l l]) + (match l + [() '()] + [(('RESULTS files . _) . _) + (let-values + ([(info* rest) + (filter-map-split + (match-lambda + [(and x ('RESULTS files2 . _)) + (and (equal? files files2) x)]) + l)]) + (cons (reverse info*) (loop rest)))]))] + [name->ndx + (lambda (filename) + (recur loop ([i 0]) + (cond + [(= i (length wright-files)) + (printf "Warning: not found~n") + i] + [(string=? filename (nth wright-files i)) i] + [else (loop (add1 i))])))] + [grouped-l (sort + (match-lambda* + [((and a (('RESULTS f1 ('size s1) . _) . _)) + (('RESULTS f2 ('size s2) . _) . _)) + (< s1 s2) + (< (name->ndx f1) (name->ndx f2))]) + grouped-l)] + [_ (assert (= (length l) (apply + (map length grouped-l))))] + [_ (pretty-print + (map + (match-lambda + [(('RESULTS files ('size s1) . _) . _) + (list files s1)]) + grouped-l))] + [cnth (lambda (n) (lambda (x) (cadr (nth x n))))] + [get-counters (lambda (x) (nth x 9))] + [get-control (lambda (x) (nth x 10))] + [get-time + (lambda (f) + (lambda (x) (cdr (cadr (assq f (get-counters x))))))] + [ctrl-eq? + (lambda (para val) + (lambda (x) + (eq? (cadr (assq para (get-control x))) val)))] + [select + (lambda (pred) + (map + (lambda (group) + (match (filter pred group) + [() #f] + [(x) x] + [m (pretty-print m) + (error 'get-results-file "Multiple matches")])) + grouped-l))] + [split + (lambda (preds) + (map select preds))]) + + (list l cnth get-counters get-control get-time ctrl-eq? + select split))])) + + +(define (scaling->matlab) + (system (format "\\rm ~s" matlab-scaling-file)) + (match-let* + ([(l cnth get-counters get-control get-time l-filter-ctrl split) + (get-results-file)] + [l-p (lambda (p) (select (l-filter-ctrl 'st:analysis p)))] + [l-sba (l-p 'sba)] + [l-precompress (l-p 'precompress)] + [l-za (l-p 'za-reanalyze)] + [l-nc (l-p 'no-combine)]) + + ;;(pretty-print (map cadr l)) + (with-output-to-file matlab-scaling-file + (lambda () + (for-each + (match-lambda + [(name fn) + (printf "~s = [ " name) + (for-each (lambda (x) (printf "~s " (if x (fn x) 0))) + l-sba) + (add-zeros l-sba) + (printf "; ") + (for-each (lambda (x) (printf "~s " (fn x))) + l-precompress) + (add-zeros l-precompress) + (printf "; ") + (for-each (lambda (x) (printf "~s " (fn x))) + l-za) + (add-zeros l-za) + (printf "; ") + (for-each (lambda (x) (printf "~s " (fn x))) + l-nc) + (add-zeros l-nc) + (printf "]~n")]) + `((ast_size ,(cnth 2)) + (num_Tvar ,(cnth 3)) + (num_AV ,(cnth 4)) + (num_con ,(cnth 5)) + (num_edges ,(cnth 6)) + (num_AV_a ,(cnth 7)) + (entries ,(cnth 8)) + (ttl_time ,(get-time 'seperately-analyze-and-load-files)) + (local_time ,(get-time 'sba-analyze-file)) + (parse_time ,(get-time 'load-parse-expand)) + (traverse_time ,(get-time 'traverse-def)) + (combine_time ,(get-time 'top-level-combine)) + (live_data ,(get-time 'live-data)) + (min_time ,(get-time 'minimize-constraints-live)) + (resize_time ,(get-time 'resize-hash-table)) + )))))) + +;; ====================================================================== +;; Comparison of st:analysis 'za-reanalyze and #f + +(define (compare-analyzes-files files) + (let ([size + (dynamic-let + ([st:analysis 'sba]) + (printf "~nCOMPARE-ANALYZES 'sba ~s~n" files) + (tsal files) + (let ([size (apply + (map calc-AST-size seperate-defs))]) + (write-results files size) + size))]) + (for-each + (lambda (a) + (printf "~nCOMPARE-ANALYZES '~s ~s~n" a files) + (dynamic-let + ([st:analysis a]) + (if (memq a '(precompress za-reanalyze)) + (for-each (lambda (c) + (dynamic-let + ([st:unit-simplify c]) + (tsal files) + (write-results files size))) + '(live-few-e + dfa-min)) + (begin + (tsal files) + (write-results files size))))) + '(precompress za-reanalyze no-combine)))) + +(define (compare-analyzes) + (cd "/home/cormac/Spidey") + (clear-results) + (compare-analyzes-files tp-spj) + (compare-analyzes-files sba-kernel-spj) + (compare-analyzes-files TC-spj) + (compare-analyzes-files t11-spj) + (compare-analyzes-files sba-zodiac-spj) + (compare-analyzes-files sba-small-spj) + ;;(test-scaling-file sba-spj) + (compare-analyzes-sba) + ) + +(define (compare-analyzes-sba . rest) + ;; Add on extra sba files one-by-one + (recur loop ([f '()] + [r sba-spj] + [n (match rest + [() 0] + [(n) n])]) + (unless (null? r) + (let ([f (append f (list (car r)))]) + (when (<= n 0) + (compare-analyzes-files f)) + (loop f (cdr r) (sub1 n)))))) + + +(define matlab-seperate-file "/home/cormac/Spidey/results/seperate.m") + +;; ====================================================================== + +(define (ts file) + (seperately-analyze-file-thunk* (files->file-thunk* file) "test/out.za") + (read-constraint-set "test/out.za")) + +(define (tsal files) + (clear-counters!) + (seperately-analyze-and-load-files files) + (show-counters) + (void)) + +;; ====================================================================== +;; Some benchmarks + +(define tp-spj (list "mod/part1.ss" "mod/part2.ss")) +(define mod-spj (list "mod/mod1.ss" "mod/mod2.ss" "mod/mod3.ss")) +(define TC-spj (list "mod/TC/env.ss" + "mod/TC/parse.ss" + "mod/TC/type.ss" + "mod/TC/eval.ss" + "mod/TC/go.ss" + ;;"mod/TC/test.ss" + )) +(define t11-spj (list "mod/11/FrontEnd.ss" + "mod/11/Registers.ss" + "mod/11/Memory.ss" + "mod/11/Machine.ss" + "mod/11/go.ss" + )) + +(define (tp) (tsal tp-spj)) +(define (mod) (tsal mod-spj)) +(define (TC) (tsal TC-spj)) +(define (t11) (tsal t11-spj)) + +;; ====================================================================== +;; SBA benchmarks + +(define sba-files + (list "library" + "env" + "config" + "driver" + "sba" + + "zodiac" + "compat" + "loadexpand" + "bind" + "traverse" + "global-env" + "prototype" + + "hash" + "kernel" + + "toplevelenv" + "templates" + "languages-abstract" + + "sdl" + "results" + + "calc-checks" + "hyper" + "seperate" + + "type-con" + "contained" + "gram" + "min" + "min2" + "dfa-min" + )) + +(define sba-spj + (map (lambda (s) (string-append "/home/cormac/Spidey/mod/sba/" s ".ss")) + sba-files)) + +(define (sba-spj-until x) + (recur loop ([l sba-spj]) + (cons (car l) + (if (substring? x (car l)) + '() + (loop (cdr l)))))) + +(define sba-small-spj (sba-spj-until "kernel")) +(define sba-medium-spj (sba-spj-until "calc-checks")) + +(define sba-kernel-spj + (map (lambda (s) (string-append "/home/cormac/Spidey/mod/sba/" s ".ss")) + (list "hash" "kernel" "test-kernel"))) + +(define sba-zodiac-spj + (map (lambda (s) (string-append "/home/cormac/Spidey/mod/sba/" s ".ss")) + (list "bind" "compat" "env" "zodiac" "test-zodiac"))) + +;; ---------------------------------------------------------------------- + +(define (separate-expt) + (st:polymorphism 'compress) + (st:type-compression-poly 'live-few-e) + (st:library-prims #f) + (st:topo-sort #f) + (st:use-module #t) + + (for-each + (lambda (p) + (printf "~n========================================~n") + (printf "SIMPL STRATEGY: ~s~n" p) + (st:unit-simplify p) + (st:analysis 'za-reanalyze) + (tsal sba-kernel-spj) + (write-results sba-kernel-spj 0) + (st:analysis 'za) + (for-each + (lambda (file) + (printf "~n========================================~n") + (printf "FILES: ~s~n" file) + (system (format "touch ~a" file)) + (tsal sba-kernel-spj) + (write-results file 0)) + sba-kernel-spj)) + '(live live-few-e dfa-min-AV))) + +(define (tsba) (tsal sba-spj)) +(define (tker) (tsal sba-kernel-spj)) +(define (tzod) (tsal sba-zodiac-spj)) +(define (tker2) + (clear-counters!) + (initialize-analysis!) + (read-constraint-set-to-global-env "~/Spidey/mod/sba/hash.ss") + (read-constraint-set-to-global-env "~/Spidey/mod/sba/test-kernel.ss") + (hyper (sba-analyze-file (files->file-thunk* "~/Spidey/mod/sba/kernel.ss"))) + (report-unbound-vars) + (show-counters)) + +;; ====================================================================== + +(define (test-seperate) + (for-each + (lambda (thunk) + (for-each + (lambda (c) + (for-each + (lambda (b) + (st:unit-simplify c) + (st:add-hyper-links b) + (printf "==============================~n") + (printf "Type-compression ~s Hyper-links ~s~n" c b) + (thunk) + (show-stat)) + (list #f ))) + (list 'live 'dfa-min))) + (list ;;(lambda () (tp)) + (lambda () (TC) (system "ls -l mod/TC*.za")) + ;;(lambda () (tsba) (system "ls -l sba/*.za")) + ))) + +;; ====================================================================== + +(define (st:tybe . args) + (dynamic-let + ([st:type-compression '(higher-order . live-few-e)]) + (pretty-print (apply st:type-fn args))) + (dynamic-let + ([st:type-compression '(higher-order . dfa-min)]) + (apply st:type-fn args))) + +;; ====================================================================== + +(define (compare-poly-file file) + (printf "~n========================================~nFile: ~s~n" files) + (for-each-parameter + st:polymorphism + (lambda (p) + (printf "~n==============================~nPOLY STRATEGY: ~s~n" p) + (if (eq? p 'compress) + (for-each-parameter + st:type-compression-poly + (lambda (c) + (when (memq c '(live live-few-e)) + (compare-poly-files-one files)))) + (compare-poly-file-one file))))) + +(define (compare-poly-file-one file) + (printf "~n========================================~n") + (printf "FILE: ~s~n" file) + (printf "POLY STRATEGY: ~s ~s~n" + (st:polymorphism) (st:type-compression-poly)) + (clear-counters!) + (st:analyze files) + (show-counters) + (show-stat) + (let ([size (calc-AST-size defs-ordered)]) + (write-results files size))) + +(define (make-compare-poly-file files) + `(dynamic-let + ([st:topo-sort #t] + [st:library-prims #t]) + (begin + ,@(map + (lambda (p) + `(begin + (st:polymorphism (quote ,p)) + ,(if (eq? p 'compress) + `(begin + ,@(map + (lambda (c) + `(begin + (st:type-compression-poly (quote ,c)) + (compare-poly-file-one ,files))) + '(live live-few-e dfa-min-AV))) + `(compare-poly-file-one ,files)))) + (map car (st:polymorphism '?)))))) + +(define (all-compare-poly) (for-each compare-poly-file benchmark-files)) +(define (wright-compare-poly) (for-each compare-poly-file wright-files)) + +(define wright-ok + `(begin ,@(map make-compare-poly-file wright-files))) + +(define wright-ok + '(begin (dynamic-let ([st:topo-sort #t] + [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/boyer.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/boyer.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/boyer.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/boyer.scm")))) + (begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/boyer.scm")) + (begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/boyer.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/graphs.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/graphs.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/graphs.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/graphs.scm")))) + (begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/graphs.scm")) + (begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/graphs.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/lattice.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/lattice.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/lattice.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/lattice.scm")))) + (begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/lattice.scm")) + (begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/lattice.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/matrix.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/matrix.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/matrix.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/matrix.scm")))) + (begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/matrix.scm")) + (begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/matrix.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/maze.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/maze.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/maze.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/maze.scm")))) + (begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/maze.scm")) + (begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/maze.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/nbody.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/nbody.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/nbody.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/nbody.scm")))) + (begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/nbody.scm")) + (begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/nbody.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/splay.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/splay.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/splay.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/splay.scm")))) + (begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/splay.scm")) + (begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/splay.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/browse.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/browse.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/browse.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/browse.scm")))) + (begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/browse.scm")) + (begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/browse.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/check.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/check.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/check.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/check.scm")))) + (begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/check.scm")) + (begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/check.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/nucleic.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/nucleic.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/nucleic.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/nucleic.scm")))) + '(begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/nucleic.scm")) + '(begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/nucleic.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin '(begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/nucleic-2.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/nucleic-2.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/nucleic-2.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/nucleic-2.scm")))) + '(begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/nucleic-2.scm")) + '(begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/nucleic-2.scm")))) + (dynamic-let ([st:topo-sort #t] [st:library-prims #t]) + (begin (begin (st:polymorphism 'none) + (compare-poly-file-one "~/Spidey/wright/dynamic.scm")) + (begin (st:polymorphism 'compress) + (begin (begin (st:type-compression-poly 'live) + (compare-poly-file-one "~/Spidey/wright/dynamic.scm")) + (begin (st:type-compression-poly 'live-few-e) + (compare-poly-file-one "~/Spidey/wright/dynamic.scm")) + (begin (st:type-compression-poly 'dfa-min-AV) + (compare-poly-file-one "~/Spidey/wright/dynamic.scm")))) + '(begin (st:polymorphism 'copy-con) + (compare-poly-file-one "~/Spidey/wright/dynamic.scm")) + '(begin (st:polymorphism 'reanalyze) + (compare-poly-file-one "~/Spidey/wright/dynamic.scm")))))) + +;; ====================================================================== + +(define (poly->matlab . files) + (match-let* + ([f "/home/cormac/papers/popl95/ Spidey/results/poly.m"] + [(l cnth get-counters get-control get-time ctrl-eq? select split) + (apply get-results-file files)] + [l-p (lambda (p) (select (ctrl-eq? 'st:polymorphism p)))] + [l-none (l-p 'none)] + [l-copy (l-p 'copy-con)] + [l-reanalyze (l-p 'reanalyze)] + [l-compress-alg + (lambda (alg) + (select + (lambda (x) + (and + (eq? (cadr (assq 'st:polymorphism (get-control x))) 'compress) + (eq? (cadr (assq 'st:type-compression-poly (get-control x))) + alg)))))] + [l-compress-live (l-compress-alg 'live)] + [l-compress-live-noe (l-compress-alg 'live-few-e)] + [lists (list l-reanalyze + l-copy + l-compress-live + l-compress-live-noe + (l-compress-alg 'dfa-min-AV) + l-none)] + [show-pairs `((ast_size ,(cnth 2)) + (num_Tvar ,(cnth 3)) + (num_AV ,(cnth 4)) + (num_con ,(cnth 5)) + (num_edges ,(cnth 6)) + (num_AV_a ,(cnth 7)) + (entries ,(cnth 8)) + (ttl_time ,(get-time 'st:analyze)) + (local_time ,(get-time 'sba-analyze-file)) + (parse_time ,(get-time 'load-parse-expand)) + (traverse_time ,(get-time 'traverse-def)) + (combine_time ,(get-time 'top-level-combine)) + (live_data ,(get-time 'live-data)) + (min_time ,(get-time 'minimize-constraints)) + (resize_time ,(get-time 'resize-hash-table)) + (topo ,(get-time 'topological-sort)) + (inst ,(get-time 'instantiate-polymorphic-def)) + )]) + + (if (file-exists? f) (delete-file f)) + + ;;(pretty-print (map cadr l)) + + (for-each + + (match-lambda + [(name fn) + (printf "==============~n~s~n" name) + (for i 0 (apply max (map length lists)) + (printf "~a: " + (let* ([none (nth l-none i)] + [f (if none (cadr none) "-")]) + (if (string? f) + (padr f 30) + f))) + (for-each + (lambda (l) + (let ([x (nth l i)]) + (printf "~a " (if x (padl (fn x) 7) " -")))) + lists) + (newline))]) + show-pairs) + + (with-output-to-file f + (lambda () + (for-each + + (match-lambda + [(name fn) + (printf "~s = [ " name) + (for-each + (lambda (l) + (for-each (lambda (x) (printf "~s " (if x (fn x) 0))) l) + (if (eq? l l-none) + (printf "]~n~n") + (printf "; "))) + lists)]) + + show-pairs))))) + +(define (poly->fig . files) + (match-let* + ([f "/home/cormac/papers/popl97/analysis-times.tex"] + [(l cnth get-counters get-control get-time ctrl-eq? select split) + (apply get-results-file files)] + [l-p (lambda (p) (select (ctrl-eq? 'st:polymorphism p)))] + [l-none (l-p 'none)] + [l-copy (l-p 'copy-con)] + [l-reanalyze (l-p 'reanalyze)] + [l-compress-alg + (lambda (alg) + (select + (lambda (x) + (and + (eq? (cadr (assq 'st:polymorphism (get-control x))) 'compress) + (eq? (cadr (assq 'st:type-compression-poly (get-control x))) + alg)))))] + [l-compress-live (l-compress-alg 'live)] + [l-compress-live-noe (l-compress-alg 'live-few-e)] + [l-compress-dfa (l-compress-alg 'dfa-min-AV)] + [lists (list )] + [atime + (lambda (x) + (if x + (- ((get-time 'st:analyze) x) + ((get-time 'load-parse-expand) x)) + 0))] + [doit + (lambda () + (for-each + (lambda (name lines none copy reanalyze live live-noe dfa) + (printf " {\\tt ~a } & ~s & ~ss " + name lines + (/ (round (/ (atime none) 10.0)) 100)) + (for-each + (lambda (x) + (printf " & ~a " + (if (zero? (atime x)) + '* + (/ (round (/ (atime x) (atime none) 0.010)) + 100)))) + (list copy reanalyze live live-noe dfa)) + (printf " \\\\ ~n")) + '(lattice browse splay check graph boyer + matrix maze nbody nucleic) + '(215 233 265 281 621 624 744 857 880 3335) + l-none + l-copy + l-reanalyze + l-compress-live + l-compress-live-noe + l-compress-dfa))] + ) + (pretty-print (map length (list + l-none + l-copy + l-reanalyze + l-compress-live + l-compress-live-noe + l-compress-dfa))) + + (doit) + (if (file-exists? f) (delete-file f)) + (with-output-to-file f doit))) +;; ====================================================================== + +(define (fixup x) + (let ([y (recur loop ([x x]) + (if (null? x) + '() + (cons (caddr x) (loop (cddddr x)))))]) + (apply + y))) + + + diff --git a/collects/mrspidey/Sba/driver.ss b/collects/mrspidey/Sba/driver.ss new file mode 100644 index 0000000..b3d321d --- /dev/null +++ b/collects/mrspidey/Sba/driver.ss @@ -0,0 +1,93 @@ +;; driver.ss - driver file for text version +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +;; ---------------------------------------------------------------------- + +'(define st:defconstructor add-default-constructor!) +'(define st:defprim add-default-primitive!) +'(define st:type-alias default-constructor-alias!) +'(define (st:deftype name nutype) + (install-input-type-expander! + (lambda (type) + (if (eq? type name) nutype type)))) + +(define st:set-debug set-debug-flag) + +; ---------------------------------------------------------------------- + +(define st:analyze + (lambda (file) + (analyze-program file) + (void))) + +(define st: + (lambda (file) + (let ([defs (analyze-program file)]) + (calc-checks defs) + (void)))) + + +; ---------------------------------------------------------------------- + +(define (st:type-fn . args) + ;;(when (null? defs-bind) + ;; (error 'st:type "Checking not done yet, use st:")) + (let* ([show + (lambda (name) + (list (zodiac:binding-var name) + ': + (FlowType->SDL (atenv:lookup global-def-env name))))] + [show* + (lambda (b*) + (map show b*) + ;;(for-each (lambda (b) (pretty-print (show b))) b*) + )]) + + (if (null? args) + ;; Show all + (show* (atenv:domain global-def-env)) + ;; Show selectively + (show* + (filter + (lambda (name) (memq (zodiac:binding-var name) args)) + (atenv:domain global-def-env)))))) + +;; ---------------------------------------------------------------------- + +(define st:help + (lambda () + ;(printf "Commands for SBA Soft Scheme Version ~a~%" st:version) + (printf " (st:analyze file) analyze file~n") + (printf " (st:check file) type check file~%") +; (printf " (st:write file [output]) type check file and write it~%") + (printf " (st:type [definition ...]) show type of top level defs~n") +; (printf " (st:ltype var) show type of internal vars~n") +; (printf " (st:why N) prints cause of check N~n") + (printf " (st:control [param [value]]) show or change parameters~n") + (printf " (st:help) prints this message~%"))) + +; ---------------------------------------------------------------------- +; (st:check file (output)) type check file +; (st:bench file) execute type checked file fast +; (st:run file) execute type checked file +; ---------------------------------------------------------------------- + +(st:language 'DrScheme) +;(st:language 'MrEd) + +;(printf "DrScheme selected~n") diff --git a/collects/mrspidey/Sba/exn-hierarchy.ss b/collects/mrspidey/Sba/exn-hierarchy.ss new file mode 100644 index 0000000..6bd6691 --- /dev/null +++ b/collects/mrspidey/Sba/exn-hierarchy.ss @@ -0,0 +1,105 @@ +(define-struct exn (message debug-info)) +(define-struct (exn:user struct:exn) ()) +(define-struct (exn:syntax struct:exn) (expr)) +(define-struct (exn:variable struct:exn) (id)) +(define-struct (exn:application struct:exn) (value)) +(define-struct (exn:application:non-procedure struct:exn:application) ()) +(define-struct (exn:application:arity struct:exn:application) (expected)) +(define-struct (exn:application:type struct:exn:application) (expected)) +(define-struct (exn:application:range struct:exn:application) ()) +(define-struct (exn:application:range:bounds struct:exn:application:range) (min max)) +(define-struct (exn:application:range:bounds:vector struct:exn:application:range:bounds) ()) +(define-struct (exn:application:range:bounds:string struct:exn:application:range:bounds) ()) +(define-struct (exn:application:range:bounds:struct struct:exn:application:range:bounds) ()) +(define-struct (exn:application:range:list struct:exn:application:range) ()) +(define-struct (exn:application:list-sizes struct:exn:application) ()) +(define-struct (exn:application:map-arity struct:exn:application) (provided)) +(define-struct (exn:application:integer struct:exn:application) ()) +(define-struct (exn:application:list struct:exn:application) ()) +(define-struct (exn:application:math struct:exn:application) ()) +(define-struct (exn:application:math:zero struct:exn:application:math) ()) +(define-struct (exn:application:math:infinity struct:exn:application:math) ()) +(define-struct (exn:application:math:negative struct:exn:application:math) ()) +(define-struct (exn:application:math:radix struct:exn:application:math) ()) +(define-struct (exn:application:mode-conflict struct:exn:application) (filename)) +(define-struct (exn:application:file-position struct:exn:application) ()) +(define-struct (exn:application:fprintf struct:exn:application) ()) +(define-struct (exn:application:fprintf:extra-arguments struct:exn:application:fprintf) (extras)) +(define-struct (exn:application:fprintf:no-argument struct:exn:application:fprintf) ()) +(define-struct (exn:application:fprintf:argument-type struct:exn:application:fprintf) (expected)) +(define-struct (exn:else struct:exn) ()) +(define-struct (exn:struct struct:exn) ()) +(define-struct (exn:struct:struct-type struct:exn:struct) (value)) +(define-struct (exn:object struct:exn) ()) +(define-struct (exn:object:class-type struct:exn:object) (value)) +(define-struct (exn:object:interface-type struct:exn:object) (value)) +(define-struct (exn:object:generic struct:exn:object) (object)) +(define-struct (exn:object:inherit struct:exn:object) (ivar)) +(define-struct (exn:object:implement struct:exn:object) (ivar)) +(define-struct (exn:object:class-ivar struct:exn:object) (class ivar)) +(define-struct (exn:object:interface-ivar struct:exn:object) (interface ivar)) +(define-struct (exn:object:ivar struct:exn:object) (object ivar)) +(define-struct (exn:object:private-class struct:exn:object) (class)) +(define-struct (exn:object:init struct:exn:object) (object class)) +(define-struct (exn:object:init:multiple struct:exn:object:init) ()) +(define-struct (exn:object:init:never struct:exn:object:init) ()) +(define-struct (exn:unit struct:exn) ()) +(define-struct (exn:unit:non-unit struct:exn:unit) (value)) +(define-struct (exn:unit:arity struct:exn:unit) (unit)) +(define-struct (exn:unit:import struct:exn:unit) (in-unit out-unit in-tag out-tag name)) +(define-struct (exn:unit:export struct:exn:unit) (unit tag name)) +(define-struct (exn:unit:invoke struct:exn:unit) ()) +(define-struct (exn:unit:invoke:variable struct:exn:unit:invoke) (name)) +(define-struct (exn:unit:signature struct:exn:unit) ()) +(define-struct (exn:unit:signature:non-signed-unit struct:exn:unit:signature) (value)) +(define-struct (exn:unit:signature:arity struct:exn:unit:signature) (unit)) +(define-struct (exn:unit:signature:match struct:exn:unit:signature) (dest-context src-context variable)) +(define-struct (exn:unit:signature:match:missing struct:exn:unit:signature:match) ()) +(define-struct (exn:unit:signature:match:extra struct:exn:unit:signature:match) ()) +(define-struct (exn:unit:signature:match:kind struct:exn:unit:signature:match) ()) +(define-struct (exn:read struct:exn) (port)) +(define-struct (exn:read:paren struct:exn:read) ()) +(define-struct (exn:read:number struct:exn:read) (input)) +(define-struct (exn:read:char struct:exn:read) (input)) +(define-struct (exn:read:eof struct:exn:read) (expected)) +(define-struct (exn:read:dot struct:exn:read) ()) +(define-struct (exn:read:unsupported struct:exn:read) (input)) +(define-struct (exn:read:vector-length struct:exn:read) (input)) +(define-struct (exn:read:compiled struct:exn:read) ()) +(define-struct (exn:read:graph struct:exn:read) ()) +(define-struct (exn:i/o struct:exn) ()) +(define-struct (exn:i/o:read struct:exn:i/o) (port)) +(define-struct (exn:i/o:write struct:exn:i/o) (port)) +(define-struct (exn:i/o:filesystem struct:exn:i/o) (pathname)) +(define-struct (exn:i/o:filesystem:path struct:exn:i/o:filesystem) ()) +(define-struct (exn:i/o:filesystem:path:username struct:exn:i/o:filesystem:path) ()) +(define-struct (exn:i/o:filesystem:file struct:exn:i/o:filesystem) ()) +(define-struct (exn:i/o:filesystem:directory struct:exn:i/o:filesystem) ()) +(define-struct (exn:i/o:filesystem:collection struct:exn:i/o:filesystem) ()) +(define-struct (exn:i/o:filesystem:file-exists struct:exn:i/o:filesystem) ()) +(define-struct (exn:i/o:port-closed struct:exn:i/o) (port)) +(define-struct (exn:i/o:user-port struct:exn:i/o) (port)) +(define-struct (exn:i/o:tcp struct:exn:i/o) ()) +(define-struct (exn:i/o:tcp:connect struct:exn:i/o:tcp) (address port-id)) +(define-struct (exn:i/o:tcp:listen struct:exn:i/o:tcp) (port-id)) +(define-struct (exn:i/o:tcp:accept struct:exn:i/o:tcp) (listener)) +(define-struct (exn:i/o:tcp:listener-closed struct:exn:i/o:tcp) (listener)) +(define-struct (exn:misc struct:exn) ()) +(define-struct (exn:misc:unsupported struct:exn:misc) ()) +(define-struct (exn:misc:user-break struct:exn:misc) ()) +(define-struct (exn:misc:out-of-memory struct:exn:misc) ()) +(define-struct (exn:misc:parameterization struct:exn:misc) (value)) +(define-struct (exn:misc:defmacro struct:exn:misc) (value)) +(define-struct (exn:misc:expansion-time struct:exn:misc) ()) +(define-struct (exn:misc:constant struct:exn:misc) (id)) +(define-struct (exn:misc:continuation struct:exn:misc) ()) +(define-struct (exn:misc:thread struct:exn:misc) ()) +(define-struct (exn:misc:thread:kill struct:exn:misc:thread) ()) +(define-struct (exn:misc:semaphore struct:exn:misc) ()) +(define-struct (exn:misc:hash-table struct:exn:misc) (key)) +(define-struct (exn:misc:regexp struct:exn:misc) ()) +(define-struct (exn:misc:process struct:exn:misc) ()) +(define-struct (exn:misc:dynamic-extension struct:exn:misc) (name)) +(define-struct (exn:misc:dynamic-extension:open struct:exn:misc:dynamic-extension) ()) +(define-struct (exn:misc:dynamic-extension:version struct:exn:misc:dynamic-extension) ()) +(define-struct (exn:misc:dynamic-extension:initialize struct:exn:misc:dynamic-extension) ()) diff --git a/collects/mrspidey/Sba/expander-boot.ss b/collects/mrspidey/Sba/expander-boot.ss new file mode 100644 index 0000000..b1220e4 --- /dev/null +++ b/collects/mrspidey/Sba/expander-boot.ss @@ -0,0 +1,105 @@ +;; expander-boot.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +(printf "Loading expander-boot.ss~n") + +(define __keep-mrspidey-annotations #t) +(load "~cormac/scheme/mzschemerc.ss") +(match:set-error-control 'error) + +(defmacro assert args '(void)) +(defmacro begin-test-case args `(begin ,@args)) +;(defmacro type: args `(type:-quote (quote ,args))) +(defmacro primitive: args `(type: ,@args)) + +(defmacro include-exp (f) + (let ([p (open-input-file f)]) + (begin0 + (read p) + (close-input-port p)))) + +;; ---------- structures -------------------------------------------------- +;; field = (: sym type) | (! sym type) | sym +;; field-name = sym + +(define (struct-expander-fn struct: const?) + (#%let ([make-exn make-exn:syntax] + [debug debug-info-handler]) + (#%lambda body + (#%let* ([syntax-error + (#%lambda (s) + (#%raise + (make-exn + (#%format "define-struct: ~a" s) + ((debug)) + (#%cons 'define-struct body))))] + [field->field-name + (match-lambda + [((or ': '!) sym _) sym] + [(? symbol? sym) sym] + [x (syntax-error (format "Bad field ~s" x))])] + [field-mutable? + (match-lambda + [('! sym _) #t] + [_ (not const?)])] + [build-struct-names + (#%lambda (name fields) + (#%let ([name (#%symbol->string name)] + [+ #%string-append]) + (#%map #%string->symbol + (#%append + (#%list + (+ "struct:" name) + (+ "make-" name) + (+ name "?")) + (#%apply + #%append + (#%map + (#%lambda (field) + (let ([f + (symbol->string + (field->field-name field))]) + (cons + (+ name "-" f) + (if (field-mutable? field) + (list (+ "set-" name "-" f "!")) + '())))) + fields))))))]) + (#%or (#%pair? body) + (syntax-error "empty declaration")) + (#%or (#%= 2 (#%length body)) + (syntax-error "wrong number of parts")) + (#%or (#%symbol? (#%car body)) + (#%and (#%pair? (#%car body)) + (#%symbol? (#%caar body)) + (#%pair? (#%cdar body)) + (#%null? (#%cddar body))) + (syntax-error "first part must be an identifier or identifier-expression pair")) + (#%or (#%list? (#%cadr body)) + (syntax-error "improper field list")) + (#%let* ([name (#%if (#%symbol? (#%car body)) + (#%car body) + (#%caar body))] + [fields (#%cadr body)]) + `(#%define-values ,(build-struct-names name fields) + (,struct: ,@body))))))) + +;(#%define-macro define-const-typed-structure (struct-expander-fn '#%const-typed-structure #t)) +(#%define-macro define-const-typed-structure (struct-expander-fn '#%typed-structure #f)) +(#%define-macro define-typed-structure (struct-expander-fn '#%typed-structure #f)) + +(printf "expander-boot.ss done~n") diff --git a/collects/mrspidey/Sba/gram.ss b/collects/mrspidey/Sba/gram.ss new file mode 100644 index 0000000..e70f0ae --- /dev/null +++ b/collects/mrspidey/Sba/gram.ss @@ -0,0 +1,322 @@ +;; gram.ss + +; ====================================================================== + +(define debugging-gram #f) +(defmacro pretty-debug-gram args `(when debugging-gram (pretty-print ,@args))) + +; ====================================================================== +; VIEWING CONSTRAINTS AS GRAMMARS +; ====================================================================== +; Non-Terminals + +(define-structure (NT AVS type) + ([rhs* '()][prop #f][tag #f][sources #f][num #f][edgefrom '()])) + +(define mk-AVS-NTs! + (lambda (AVS) + (set-AVS-L! AVS (make-NT AVS 'L )) + (set-AVS-U! AVS (make-NT AVS 'U )) + (set-AVS-LI! AVS (make-NT AVS 'LI)) + (set-AVS-UI! AVS (make-NT AVS 'UI)))) + +(define same-nt-type? + (match-lambda* + [(($ NT _ t1) ($ NT _ t2)) (eq? t1 t2)])) + +(define nt-chg-AVS + (match-lambda* + [(f ($ NT x type)) (make-NT (f x) type)])) + +(define drop-I + (match-lambda + [(and nt ($ NT AVS type _)) + (case type + [(or 'L 'U) nt] + [LI (AVS-L AVS)] + [UI (AVS-U AVS)])])) + +(define invert-nt + (match-lambda + [($ NT AVS 'L) (AVS-UI AVS)] + [($ NT AVS 'LI) (AVS-U AVS)] + [($ NT AVS 'U) (AVS-LI AVS)] + [($ NT AVS 'UI) (AVS-L AVS)])) + +; ====================================================================== +; Right hand side of a production + +(define-structure (rhs* grsym misc nts)) +(define (make-rhs grsym nt) (make-rhs* grsym '() (list nt))) + +(define-structure (grsym ineq fn sign template field-no)) +;; ineq is '<= or '>= +;; fn is 'inj, 'inj-tst or 'ext +;; sign is #t (monotonic) or #f (antimonotonic) +;; field-no may be #f + +(define (make-grsym->=inj+ t f) (make-grsym '>= 'inj #t t f)) +(define (make-grsym->=inj- t f) (make-grsym '>= 'inj #f t f)) +(define (make-grsym->=inj? t f) (make-grsym '>= 'inj '? t f)) + +(define (make-grsym-<=inj-tst+ t f) (make-grsym '<= 'inj-tst #t t f)) +(define (make-grsym-<=inj-tst- t f) (make-grsym '<= 'inj-tst #f t f)) + +(define (make-grsym-<=ext+ t f) (make-grsym '<= 'ext #t t f)) +(define (make-grsym->=ext- t f) (make-grsym '>= 'ext #f t f)) + +(define (make-grsym->=ext+ t f) (make-grsym '>= 'ext #t t f)) +(define (make-grsym-<=ext- t f) (make-grsym '<= 'ext #f t f)) + +;;(define (make-grsym-filter filter) (make-grsym '<= 'filter #t filter #f)) +(define (make-grsym-filter filter) (make-grsym '>= 'filter #t filter #f)) +(define grsym-crossover '>=crossover) + +;; a grsym can also be '>=epsilon or '<=epsilon + +(define grsym-eq? + (match-lambda* + [(($ grsym i1 f1 s1 t1 n1) ($ grsym i2 f2 s2 t2 n2)) + (and (eq? i1 i2) (eq? f1 f2) (eq? t1 t2) (eqv? n1 n2))] + [(x y) (eq? x y)])) + +(define invert-grsym + (match-lambda + [($ grsym '>= 'inj sign template field-no) + (make-grsym '<= 'ext sign template field-no)] + [($ grsym '<= 'inj-tst sign template field-no) + (make-grsym '>= 'ext sign template field-no)] + [($ grsym '>= 'filter #t filter #f) + (make-grsym '<= 'unfilter #t filter #f)] + ['>=crossover '<=crossover] + [(and g ($ grsym)) + (error 'invert-grsym "Bad grsym ~s" (grsym->rep g))])) + +(define grsym-epsilon-or-filter? + (match-lambda + [(? symbol?) #t] + [($ grsym _ 'filter) #t] + [_ #f])) + +; ====================================================================== +; Parameters for creating grammar + +(define-structure + (parameters-grammar + interp-sign ; applied to sign of each field + prims ; #t => treat prims as constants + filters ; #t => filters are not epsilon edges + assignable-fields ; #t => assignable fields in grammar + structure-opaque ; #t => structures are constants + )) + +; ====================================================================== +;; Prepare for creating grammar + +(define (prep-gram!) + (for-each mk-AVS-NTs! list-AVS)) + +; ====================================================================== +;; Initializing the NT fields of an AVS + +(define (add-rhs! NT rhs) + (pretty-debug-gram + (match rhs + [($ rhs* grsym _ nts) + (assert (list? nts)) + (list `(add-rhs! ,(nt->sym NT) ,(grsym->rep grsym) + ,(map nt->sym nts)))])) + (set-NT-rhs*! NT (cons rhs (NT-rhs* NT)))) + +; ---------------------------------------------------------------------- + +(define (for-each-calc-prods-L L paras fn) + (match L + [($ NT AVS 'L) + (for-each + (match-lambda + [($ AV _ (and template ($ template _ signs _ _ _ _ structure?)) + misc fields) + (if (or (zero? (vector-length fields)) + (and structure? + (parameters-grammar-structure-opaque paras))) + (fn (make-rhs* (make-grsym '>= 'inj #t template '?) misc '())) + (for i 0 (vector-length fields) + (let ([field (vector-ref fields i)] + [interp-sign (parameters-grammar-interp-sign paras)] + [sign (interp-sign (vector-ref signs i))]) + (fn (make-rhs* + (make-grsym '>= 'inj (eq? sign '>=inj+) template i) + misc + (case sign + [>=inj+ (list (AVS-L field))] + [>=inj- + (if (or #f ;; mk-assignable-part-fields? + (eq? template template-lam)) + (map AVS-U (AVS-transitive-edgeto field)) + '())]))))))]) + (get-AVS-objs AVS))])) + +; ---------------------------------------------------------------------- + +(define (for-each-calc-prods-U U paras fn) + (match U + [($ NT AVS 'U) + (let ([interp-sign (parameters-grammar-interp-sign paras)]) + (for-each + (match-lambda + [($ con _ (and template ($ template type signs)) field-no AVS2 misc) + (case (interpret-sign (vector-ref signs field-no)) + [>=inj+ + (fn (make-rhs* + (make-grsym-<=inj-tst+ template field-no) + misc + (list (AVS-U AVS2))))] + [>=inj- + (fn (make-rhs* + (make-grsym-<=inj-tst- template field-no) + misc + (list (AVS-U AVS2))))])] + [($ con-filter _ the-filter AVS2) + (fn (make-rhs* + (make-grsym-filter the-filter) + '() + (list (AVS-U AVS2))))]) + (AVS-constraints AVS))) + (for-each + (lambda (AVS2) (fn (make-rhs* '<=epsilon '() (list (AVS-U AVS2))))) + (AVS-transitive-edgeto AVS))])) + +; ---------------------------------------------------------------------- + +(define (for-each-calc-prods nt paras fn) + (match nt + [($ NT AVS 'L) (for-each-calc-prods-L nt paras fn)] + [($ NT AVS 'U) (for-each-calc-prods-U nt paras fn)])) + +; ====================================================================== + + + + + + +(define (calc-productions! + live-nts live-nt? + mk-L? mk-U? mk-LI? mk-UI? + L->LI + mk-assignable-part-fields? + treat-all-mono) + + ;; live-AVS, crossover-AVS, live-nt and live-nt? + ;; all come from calc-live-AVS-nt + ;; mk-... : bool -- controls which NTs to produce + ;; L->LI, ... : bool -- controls L->LI production rule + + (let ([interpret-sign + (if treat-all-mono + (lambda (x) '>=inj+) + (lambda (x) x))]) + + (for-each (lambda (nt) (set-NT-rhs*! nt '())) + live-nts) + + ;; ------ Now fill NTs from AV, constraints and edges + + (for-each + (lambda (AVS) + (pretty-debug-gram `(Prods for AVS ,(name-for-AVS AVS))) + + ;; ------ Invert AV + (when (and mk-L? (live-nt? (AVS-L AVS))) + (AVs->prods AVS interpret-sign live-nt?)) + + ;; ------ Invert constraints + (when (and mk-U? (live-nt? (AVS-U AVS))) + (for-each + (match-lambda + [($ con _ (and template ($ template type signs)) field-no AVS2 misc) + (case (interpret-sign (vector-ref signs field-no)) + [>=inj+ + (add-rhs! (AVS-U AVS) + (make-rhs* + (make-grsym-<=inj-tst+ template field-no) + misc + (filter live-nt? + (map AVS-U (AVS-transitive-edgeto AVS2)))))] + [>=inj- + (add-rhs! (AVS-U AVS) + (make-rhs* + (make-grsym-<=inj-tst- template field-no) + misc + (filter live-nt? (list (AVS-L AVS2)))))])] + [($ con-filter _ the-filter AVS2) + (add-rhs! (AVS-U AVS) + (make-rhs* + (make-grsym-filter the-filter) + '() + (filter live-nt? + (map AVS-U (AVS-transitive-edgeto AVS2))))) + '(for-each + (lambda (to) + (when (live-nt? (AVS-L to)) + (add-rhs! (AVS-L to) + (make-rhs* + (make-grsym-filter the-filter) + '() + (list (AVS-L AVS)))))) + (AVS-transitive-edgeto AVS2)) + ]) + (AVS-constraints AVS))) + ) + live-AVS) + + ;; ------ Add L->LI productions + (when L->LI + (for-each + (lambda (AVS) + (for-each + (lambda (to) + (when (and (NT? (AVS-L to)) (live-nt? (AVS-L to))) + (add-rhs! (AVS-L to) + (make-rhs* grsym-crossover '() (list (AVS-LI AVS)))))) + (AVS-transitive-edgeto AVS))) + crossover-AVS)) + + ;; ------ convert L, U productions into LI, UI productions + (pretty-debug '(inverting productions)) + + (for-each + (lambda (nt) + (for-each + (match-lambda + [($ rhs* grsym misc to-nts) + (unless (eq? grsym '<=crossover) + (let* ([inv-grsym (invert-grsym grsym)] + [inv-nt (invert-nt nt)] + [inv-rhs (make-rhs* inv-grsym misc (list inv-nt))]) + (for-each (lambda (to) (add-rhs! (invert-nt to) inv-rhs)) + to-nts)))]) + (NT-rhs* nt))) + live-nts) + + (let ([live-nts + (apply append + (map + (match-lambda + [($ NT AVS 'L) (list (AVS-L AVS) (AVS-UI AVS))] + [($ NT AVS 'U) (list (AVS-U AVS) (AVS-LI AVS))]) + live-nts))]) + + ;; Now group together all productions for given NT with given grsym + (for-each + (lambda (nt) + (let ([rhs* (NT-rhs* nt)]) + (set-NT-rhs*! nt '()) + (for-each (lambda (rhs) + (assert (list? (rhs*-nts rhs))) + (add-rhs! nt rhs)) + (group-rhs* rhs*)))) + live-nts) + + (list live-nts)))) diff --git a/collects/mrspidey/Sba/hash.ss b/collects/mrspidey/Sba/hash.ss new file mode 100644 index 0000000..12c28f1 --- /dev/null +++ b/collects/mrspidey/Sba/hash.ss @@ -0,0 +1,147 @@ +;; hash.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define-struct hash-table-state + (hash-table-size entries-in-table + resize-table-size entry->hash-fn + hash-table)) + + ;;------------------------------------------------------------ + + (define prime1 83) + (define prime2 1789) + (define default-hash-table-size (* 32 1024)) + (define resize-table-fraction 0.6) + + ;;------------------------------------------------------------ + + (define hash-table-size 0) + (define entries-in-table 0) + (define resize-table-size 0) + (define entry->hash-fn (void)) + (define hash-table (void)) + + ;;------------------------------------------------------------ + + (define (init-hash-table entry->hash size) + (set! hash-table-size (if (zero? size) default-hash-table-size size)) + (set! entries-in-table 0) + (set! resize-table-size + (inexact->exact + (round (* hash-table-size resize-table-fraction)))) + (set! entry->hash-fn entry->hash) + (set! hash-table (make-vector hash-table-size '()))) + + (define (capture-hash-table-state) + (make-hash-table-state hash-table-size entries-in-table + resize-table-size entry->hash-fn + hash-table)) + +(define restore-hash-table-state! + (match-lambda + [($ hash-table-state t1 t2 t3 t4 t5) + (set! hash-table-size t1) + (set! entries-in-table t2) + (set! resize-table-size t3) + (set! entry->hash-fn t4) + (set! hash-table t5)])) + +(define free-hash-table-state! + (match-lambda + [($ hash-table-state t1 t2 t3 t4 t5) + (assert (not (eq? t5 hash-table))) + (vector-zero! t5)])) + +(define (prompt-hash-table-state) + (list (capture-hash-table-state) + (vector-length hash-table) + (recur loop ([i (sub1 (vector-length hash-table))]) + (if (< i 0) + '() + (if (null? (vector-ref hash-table i)) + (loop (sub1 i)) + (cons (cons i (vector-ref hash-table i)) (loop (sub1 i)))))))) + +(define unprompt-hash-table-state! + (match-lambda + [(state vec-size vec-entries) + (restore-hash-table-state! state) + (for i 0 (vector-length hash-table) (vector-set! hash-table i '())) + (for-each + (match-lambda + [(i . elem) (vector-set! hash-table i elem)]) + vec-entries)])) + + ;;------------------------------------------------------------ + + + ;; (define (hash-fn n1 n2) + ;; (fxlogand (+ (* n1 prime1) (* n2 prime2)) (sub1 hash-table-size))) + + (define (hash-fn n1 n2) + (modulo (+ (* n1 prime1) (* n2 prime2)) hash-table-size)) + + (define (hash-fn* n*) (foldl hash-fn 0 n*)) + + (define (add-entry h entry) + (vector-set! hash-table h (cons entry (vector-ref hash-table h))) + (set! entries-in-table (add1 entries-in-table)) + '(if (zero? (mod entries-in-table 10000)) + (printf "Entries ~s~n" entries-in-table)) + (when (>= entries-in-table resize-table-size) + (resize-hash-table))) + + (define (resize-hash-table) + (set! hash-table-size (* 2 hash-table-size)) + (let ( [old hash-table] + [s (format "Resizing hash table to ~s" hash-table-size)]) + (mrspidey:progress s '...) + (flush-output) + (set! hash-table (make-vector hash-table-size '())) + (set! resize-table-size + (inexact->exact + (round (* hash-table-size resize-table-fraction)))) + (for i 0 (vector-length old) + (map + (lambda (entry) + (let ([h (entry->hash-fn entry)]) + (vector-set! hash-table h + (cons entry (vector-ref hash-table h))))) + (vector-ref old i))) + (mrspidey:progress s 'done) + ;;(show-stat-small) + )) + + (define (hash-table-list h) (vector-ref hash-table h)) + + (define (hash-find h ok?) + (recur loop ([l (vector-ref hash-table h)]) + (cond [(null? l) #f] + [(ok? (car l)) (car l)] + [else (loop (cdr l))]))) + + (define (hash-table-info) + (list hash-table-size entries-in-table + (recur loop ([i 0][c 0]) + (if (= i hash-table-size) c + (let ([l (length (vector-ref hash-table i))]) + (loop (add1 i) + (+ c (max 0 (- l 1))))))))) + + ;;------------------------------------------------------------ + diff --git a/collects/mrspidey/Sba/hyper.ss b/collects/mrspidey/Sba/hyper.ss new file mode 100644 index 0000000..65c86fa --- /dev/null +++ b/collects/mrspidey/Sba/hyper.ss @@ -0,0 +1,601 @@ +; hyper.ss - interface to GUI +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;;---------------------------------------------------------------------- + +(define (st:analyze-and-make-annotations filename) + (analysis-set-arrow-filter! #f) + (record-analyzed-file + filename + (lambda () (open-code-file filename)) + (lambda () (analyze-program filename)))) + +(define (calc-annotations defs) + (match-let* + ([type-annotations (calc-type-annotations defs)] + [(check-annotations uncheck-annotations) (calc-checks defs)] + [all-annotations + (vector type-annotations check-annotations uncheck-annotations)]) + ;;(pretty-debug `(links ,all-annotations)) + all-annotations)) + +;;---------------------------------------------------------------------- + +(define arrow-filter #f) ; if not #f, then a list of templates +; only show pred with matching AV + +(define (analysis-set-arrow-filter! C) + (set! arrow-filter + (if C + (map lookup-template (list C)) + #f))) + +(define (analysis-filter-on?) + (and arrow-filter (symbol->string (template-type (car arrow-filter))))) + +(define (analysis-get-filters) + (cons + (cons "No filter" #f) + (map + (lambda (C) (cons (symbol->string C) C)) + (append + `( nil num sym str void undefined true false + box cons vec eof iport oport + promise unit thread hash-table regexp parameterization semaphore) + (filter + (lambda (x) x) + (hash-table-map + constructor-env + (lambda (c template) + (and + (memq template-structure (template-super-templates template)) + c)))))))) + +;; ------------------------------ + +(define (objs-contain-filter? objs) + (or + (and + (eq? arrow-filter #f) + (not (null? objs))) + (ormap + (lambda (AV) + (memq (AV-template AV) arrow-filter)) + objs))) + +(define (tvar-contain-filter-mvalues? get-Tvar-objs tvar) + (or + (objs-contain-filter? (get-Tvar-objs tvar)) + (ormap + (match-lambda + [($ AV _ (? (eqc? template-mvalues)) _ #(tvar-mvlist)) + ;;(pretty-debug `(tvar-mvlist ,(Tvar-name tvar-mvlist))) + (ormap + (match-lambda + [($ AV _ (? (eqc? template-cons)) _ #(tvar-car-mvlist _)) + (objs-contain-filter? (get-Tvar-objs tvar-car-mvlist))] + [_ #f]) + (get-Tvar-objs tvar-mvlist))] + [_ #f]) + (get-Tvar-objs tvar)))) + +(define (FlowType-contains-filter? ftype) + ;(pretty-debug `(FlowType-contains-filter? ,(FlowType-name ftype))) + (or + (not arrow-filter) + (match (FlowType->Atype ftype) + [(or (? atconst?) (? atprim?) (? Tvar?)) + (tvar-contain-filter-mvalues? Tvar-objs (FlowType->Tvar ftype))] + [($ atvalues (val1 . _)) + (FlowType-contains-filter? val1)] + ;; other atypes are atschema atthunk, atstruct, atunit, atlunit + ;; all are too expensive to convert. + [x + (pretty-debug `(FlowType-contains-filter? unhandled-atype x)) + #f]))) + +(define (FlowType-orig-objs-contains-filter? ftype) + ;;(pretty-debug `(FlowType-orig-contains-filter? ,(FlowType-name ftype))) + (match (FlowType->Atype ftype) + [(or (? Tvar?)) + (tvar-contain-filter-mvalues? Tvar-orig-objs (FlowType->Tvar ftype))] + [($ atvalues (val1 . _)) + (FlowType-orig-objs-contains-filter? val1)] + ;; other atypes are atschema atthunk, atstruct, atunit, atlunit + ;; all are too expensive to convert. + [x + (pretty-debug `(FlowType-orig-objs-contains-filter? unhandled-atype x)) + #f])) + +;;---------------------------------------------------------------------- +;; Abstracts over parents and children + +(define analysis-walk1 + (lambda (start in-get-edges file-visable?) + (assert (FlowType? start)) + (pretty-debug `(analysis-walk1 ,(FlowType-name start))) + (if (string? (FlowType-type-annotation start)) + ;; start from .za file, show no edges + '() + (letrec* + ( [traversed '()] ; list of FlowType's + [preds '()] ; visable FlowType's + [get-edges + (lambda (ftype) + (let ([r (in-get-edges ftype)]) + (pretty-debug `(get-edges ,(map FlowType-name (cons ftype r)))) + r))] + [traverse + (lambda (ftype) + (pretty-debug `(traverse ,(FlowType-name ftype))) + (when + (and + (FlowType-contains-filter? ftype) + (not (memq ftype traversed))) + (set! traversed (cons ftype traversed)) + (let* + ( [ftype-w/-ta (get-ftype-w/-ta ftype)] + [ta (and ftype-w/-ta + (FlowType-type-annotation ftype-w/-ta))]) + (pretty-debug + `(traverse-ftype-w/-ta + ,(and ftype-w/-ta (FlowType-name ftype-w/-ta)))) + + (cond + [(not ta) + ;; invisable + ;; Go back to parents + (for-each traverse (get-edges ftype))] + + [(string? ta) + (if (file-visable? ta) + + ;; ftype from .za file, source file is loaded + ;; can follow this edge unless dest is from same file + (for-each + (lambda (ftype2) + (let ([ta2 (FlowType-type-annotation ftype2)]) + (unless (and (string? ta2) (string=? ta ta2)) + (traverse ftype2)))) + (get-edges ftype)) + + ;; .za file, source file not loaded + (set! preds (cons ftype-w/-ta preds)))] + + [(and + (not (string? ta)) + (not (eq? ftype-w/-ta start))) + + ;; visable + ;; add to preds unless src and dest are single value + (set! preds (cons ftype-w/-ta preds))] + + [else + ;; Invisable + ;; Go back to parents + (for-each traverse (get-edges ftype))]))))]) + + (for-each traverse (get-edges start)) + + (pretty-debug `(traversed ,(map FlowType-name traversed))) + (pretty-debug + `(preds ,(map + (lambda (i) (and (FlowType? i) (FlowType-name i))) + preds))) + + (remq start preds))))) + +(define (get-ftype-w/-ta ftype) + (if (FlowType-type-annotation ftype) + ftype + (and (FlowType-values-ftype ftype) + (get-ftype-w/-ta (FlowType-values-ftype ftype))))) + +(define (single-value-ftype ftype) + (let ([r + (match (FlowType->Atype ftype) + [(? Tvar? tvar) + (ormap + (lambda (AV) (not (eq? (AV-template AV) template-mvalues))) + (get-Tvar-objs tvar))] + [($ atvalues) #f] + [_ #t])]) + (pretty-debug `(single-value-ftype ,(FlowType-name ftype) ,r)) + r)) + +;;---------------------------------------------------------------------- +;; Returns the preds in the Tvar graph of a given ftype +;; format is a list of Tvars of predecessors that are visable + +(define analysis-parents + (lambda (ftype file-visable?) + (pretty-debug `(analysis-parents ,(FlowType-name ftype) ,(print-struct))) + (let ([r (analysis-walk1 ftype get-arrowfrom file-visable?)]) + (pretty-debug `(analysis-parents-returns ,(map FlowType-name r))) + r))) + +(define (get-arrowfrom to) + (append + (if (Tvar? to) + (append + (get-mvalue-components to) + (Tvar-edgefrom to)) + '()) + (match (FlowType->Atype to) + [($ atvalues ftypes) + ftypes] + [_ '()]) + (FlowType-arrowfrom to))) + +(define (get-mvalue-components tvar) + '(pretty-debug `(get-mvalue-components ,(Tvar-name tvar))) + (filter-map + (lambda (AV) + (if (eq? (AV-template AV) template-mvalues) + ;; get-nth + (let ( [p (mk-Tvar 'p)] + [l (mk-Tvar 'l)]) + (new-edge! (vector-ref (AV-fields+ AV) 0) p) + (new-con! p (make-con-cdr p)) + (new-con! p (make-con-car l)) + '(pretty-debug + `(get-mvalue-components + ,(Tvar-name tvar) ,(Tvar-name p) ,(Tvar-name l))) + l) + #f)) + (get-Tvar-objs tvar))) + +;; ---------------------------------------------------------------------- + +(define analysis-children + (lambda (ftype file-visable?) + (analysis-walk1 + ftype + FlowType-alledgeto + file-visable?))) + +(define FlowType-alledgeto + (lambda (ftype) + (append + ;; Direct successors + (FlowType-arrowto ftype) + (if (FlowType-values-ftype ftype) + (list (FlowType-values-ftype ftype)) + '()) + ;; For filter successors, make sure some same values + (if (Tvar? ftype) + (append + (Tvar-edgeto ftype) + (filter-map + (match-lambda + [($ con-filter _ _ tvar) tvar] + [_ #f]) + (Tvar-constraints ftype))) + '())))) + +;;---------------------------------------------------------------------- +;; Returns all ancestor/descendant arrows of a given ftype +;; as (listof (list from to)) + +(define analysis-walkn + (lambda (ftype get-edges file-visable?) + (assert (FlowType? ftype)) + (pretty-debug `(analysis-walkn ,(FlowType-name ftype))) + ;;(error) + (let ( [done '()] ; list of FlowType's + [arrows '()]) ; visable arrows + (recur traverse ([ftype ftype]) + (unless (memq ftype done) + (set! done (cons ftype done)) + (let ([parents (analysis-walk1 ftype get-edges file-visable?)]) + (for-each + (lambda (p) + (set! arrows (cons (list p ftype) arrows)) + (traverse p)) + parents)))) + + arrows))) + +;;---------------------------------------------------------------------- +;; Returns all ancestor arrows of a given ftype +;; as (listof (list from to)) + +(define analysis-ancestors + (lambda (ftype file-visable?) + (analysis-walkn ftype get-arrowfrom file-visable?))) + +(define analysis-descendants + (lambda (ftype file-visable?) + (map reverse + (analysis-walkn ftype FlowType-alledgeto file-visable?)))) + +;;---------------------------------------------------------------------- +;; Calcs the shortest path to a source FlowType with +;; orig-objs matching filter via breadth-first search +;; Returns a list of FlowTypes +;; or nil if no path to visable source +;; or #f if ftype does not contain filter + +(define analysis-shortest-path + (lambda (ftype file-visable?) + (assert (FlowType? ftype)) + (if (FlowType-contains-filter? ftype) + (let ([visited (list ftype)]) + (letrec + ([traverse + (lambda (list-paths) + (pretty-debug + `(list-paths + ,(map (lambda (p) (map FlowType-name p)) list-paths) + ,(map FlowType-name visited))) + (match list-paths + [() + ;; No paths -> return the empty path + '()] + [((and path (ftype . rest-path)) . rest-paths) + (pretty-debug + `(path ,(map FlowType-name path) + rest-paths + ,(map (lambda (p) (map FlowType-name p)) rest-paths))) + (let* ( [parents1 (analysis-parents ftype file-visable?)] + [parents2 + (filter + (lambda (p) + (if (memq p visited) + #f + (begin + (set! visited (cons p visited)) + #t))) + parents1)]) + (set! visited (cons ftype visited)) + (if (and (null? parents2) + (or (null? parents1) + (null? rest-paths))) + ;; either this path has terminated, + ;; or went to cycle and is only one left. + ;; either way, return it + (reverse path) + (traverse + (append rest-paths + (filter-map + (lambda (parent) (cons parent path)) + parents2)))))]))]) + + (let ([path (traverse + (map list (analysis-parents ftype file-visable?)))]) + + (pretty-debug `(traverse-path ,(map FlowType-name path))) + + path))) + #f))) + +'(define analysis-shortest-path + (lambda (ftype file-visable?) + (assert (FlowType? ftype)) + (if (FlowType-contains-filter? ftype) + (let ([visited '()]) + (letrec + ([traverse + (lambda (list-paths) + (pretty-debug + `(list-paths + ,(map (lambda (p) (map FlowType-name p)) list-paths) + ,(map FlowType-name visited))) + (match list-paths + [() + ;; No paths -> return the empty path + '()] + [((and path (ftype . rest-path)) . rest-paths) + (pretty-debug + `(path ,(map FlowType-name path) + rest-paths + ,(map (lambda (p) (map FlowType-name p)) rest-paths))) + (if (memq ftype visited) + ;; going around a loop + (traverse rest-paths) + (let* ( [parents (analysis-parents ftype file-visable?)]) + (set! visited (cons ftype visited)) + (if (and (null? parents) (null? rest-paths)) + ;; this path has terminated, and is the only one left, + ;; and hence the longest, so return it + (reverse path) + (traverse + (append rest-paths + (filter-map + (lambda (parent) (cons parent path)) + parents))))))]))]) + + (let ([path (traverse + (map list (analysis-parents ftype file-visable?)))]) + + (pretty-debug `(traverse-path ,(map FlowType-name path))) + + path))) + #f))) + + + +'(define analysis-shortest-path + (lambda (ftype file-visable?) + (assert (FlowType? ftype)) + (let ([visited '()]) + (letrec + ([traverse + (lambda (list-paths) + (pretty-debug + `(list-paths + ,(map (lambda (p) (map FlowType-name p)) list-paths) + ,(map FlowType-name visited))) + (match list-paths + [() + ;; No paths -> return the empty path + '()] + [((and path (ftype . rest-path)) . rest-paths) + (if (memq ftype visited) + + ;; Visited on a shorter path + (traverse rest-paths) + + (begin + (pretty-print + `(path ,(map FlowType-name path) + rest-paths + ,(map (lambda (p) (map FlowType-name p)) rest-paths))) + (set! visited (cons ftype visited)) + (cond + [(FlowType-orig-objs-contains-filter? ftype) + ;; Has orig-objs that match the filter + ;; => return this path + (reverse path)] + [(FlowType-contains-filter? ftype) + ;; Has propogated objs that match the filter + ;; => go back to parent + (let* ([new-paths + (map + (lambda (parent) (cons parent path)) + (get-arrowfrom ftype))]) + (pretty-print + `(rest-paths ,(map (lambda (p) (map FlowType-name p)) rest-paths) + new-paths + ,(map (lambda (p) (map FlowType-name p)) new-paths))) + (traverse (append rest-paths new-paths)))] + [else + ;; This FlowType no good + (traverse rest-paths)])))]))]) + (let ([path (traverse (list (list ftype)))]) + + (pretty-print `(traverse-path ,(map FlowType-name path))) + ;; Drop first FlowType - it is us + ;; Remove invisable FlowType's + ;; NO LONGER Add '() as last tag if last FlowType invisable + (assert (or (null? path) (eq? (car path) ftype))) + (if (null? path) + '() + (recur loop ([path (cdr path)]) + (match path + [(ftype . rest) + (cond + [(FlowType-type-annotation ftype) (cons ftype (loop rest))] + [(null? rest) '()] + [else (loop rest)])] + [() + ;; No path + '()])))))))) + +;; ====================================================================== +;; Returns a string representation of the the type + +(define (FlowType->SDL-text ftype) + (let ([type-port (open-output-string)]) + (dynamic-let + ([pretty-print-columns (st:pretty-type-width)]) + (pretty-print (FlowType->SDL ftype) type-port)) + (begin0 + (get-output-string type-port) + (close-output-port type-port)))) + +(define analysis-callback + (lambda (ftype) + (assert (FlowType? ftype) 'analysis-callback ftype) + (pretty-debug `(analysis-callback ,(FlowType->pretty ftype))) + (FlowType->SDL-text ftype))) + +;;---------------------------------------------------------------------- + +'(define test-hyper + (lambda (files) + (initialize-analysis!) + (match-let* + ([(defs in out) + (sba-analyze-file (files->file-thunk* files))]) + (set! global-in-env in-env) + (set! global-out-env out-env) + (report-unbound-vars) + (hyper defs) + (printf "Testing parents~n") + (pretty-print (mapLR analysis-parents list-ftype)) + (printf "Testing analysis-shortest-path~n") + (pretty-print (mapLR analysis-shortest-path list-ftype)) + (printf "Testing children~n") + (pretty-print (mapLR analysis-children list-ftype list-ftype)) + (void)))) + +;; (trace analysis-parents analysis-shortest-path analysis-children) + +;;---------------------------------------------------------------------- +;; zodiac-based source-correlating pretty-printer + +'(define (correlate-pretty-print sexp) + (let* ([p (open-output-string)] + [_ (pretty-print sexp p)] + [s (get-output-string p)] + [_ (close-output-port p)] + [p (open-input-string p)] + [r (zodiac:read p)] + [zexp (r)]) + (values s + (recur loop ([sexp sexp][zexp zexp]) + (match (list sexp zexp) + [((? list? sl) ($ zodiac:list _ s f (? list? zl))) + (list + (zodiac:location-offset s) + (zodiac:location-offset f) + (map loop sl zl))] + [(sexp ($ zodiac:zodiac _ s f)) + (list + (zodiac:location-offset s) + (zodiac:location-offset f) + sexp)]))))) + +;; ---------------------------------------------------------------------- + +'(define analysis-get-pred-filter-list + (lambda () + (cons (cons "All sources" #f) + (reverse + (map + (match-lambda + [(con . constructor) (cons (symbol->string con) (list con))]) + (append constructor-env default-constructor-env)))))) + +(define analysis-get-param + (lambda (param) + ((eval param)))) + +(define analysis-set-param! + (lambda (param val) + ((eval param) val))) + +;; ---------------------------------------------------------------------- + +;; ---------- + +'(define (contains-some-same-vals? ftype value-from-ftypes) + ;; Returns #t if ftype contains at least some values from + ;; each of value-from-ftypes + (andmap + (lambda (value-from-ftype) + (match (list + (FlowType->Atype ftype) + (FlowType->Atype value-from-ftype)) + [((? fo-Atype? x) (? fo-Atype? y)) (eq? x y)] + [((? Tvar? x) (? Tvar? y)) + (ormap + (lambda (AV) (memq AV (get-Tvar-objs y))) + (get-Tvar-objs x))] + [_ #t])) + value-from-ftypes)) diff --git a/collects/mrspidey/Sba/kern-aux.ss b/collects/mrspidey/Sba/kern-aux.ss new file mode 100644 index 0000000..e4747f9 --- /dev/null +++ b/collects/mrspidey/Sba/kern-aux.ss @@ -0,0 +1,378 @@ +;; kernel-aux.ss +;; Helper functions for building constraints +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ---------------------------------------------------------------------- +;; +(define (make-constructed-AV-template template . args) + (match-let* ( [($ template type num+ num- ref assign) template] + [fields+ (make-vector num+)] + [fields- (make-vector num-)]) + (for-each-with-n + (lambda (arg n) + (if (vector-ref assign n) + ;; Mutable - fill next two fields + (let ([tvar (mk-Tvar 'mut-field)]) + (new-edge! arg tvar) + (vector-set! fields- (vector-ref assign n) tvar) + (when (vector-ref ref n) + (vector-set! fields+ (vector-ref ref n) tvar))) + ;; Immutable - fill one field + (when (vector-ref ref n) + (vector-set! fields+ (vector-ref ref n) arg)))) + args) + (create-AV template '() fields+ fields-))) + +(define (make-constructed-AV C . args) + (apply make-constructed-AV-template (lookup-template C) args)) + +(define (make-constructed-Tvar C . args) + (let ([tvar (mk-Tvar 'constructed-Tvar)] + [AV (apply make-constructed-AV C args)]) + (new-AV! tvar AV) + tvar)) + +;; ---------------------------------------------------------------------- + +(define (make-AV-cons a d) + (if (st:cons-mutable) + (let* ( [fields+ (make-vector 2)] + [fields- (make-vector 2)]) + (let ([tvar (mk-Tvar 'mut-field)]) + (new-edge! a tvar) + (vector-set! fields+ 0 tvar) + (vector-set! fields- 0 tvar)) + (let ([tvar (mk-Tvar 'mut-field)]) + (new-edge! d tvar) + (vector-set! fields+ 1 tvar) + (vector-set! fields- 1 tvar)) + (create-AV template-cons '() fields+ fields-)) + (create-AV template-cons '() (vector a d) (vector)))) + + +(define (make-con-car tvar) (create-con template-cons 0 tvar #t)) +(define (make-con-cdr tvar) (create-con template-cons 1 tvar #t)) +(define (make-con-dom tvar) (create-con template-lam 0 tvar #f)) +(define (make-con-rng tvar) (create-con template-lam 0 tvar #t)) + +(define (make-AV-vec a) + (cond + [(lookup-template 'vect) + => + (lambda (template-vect) + (make-constructed-AV-template template-vect a AV-numb))] + [(lookup-template 'vec) + => + (lambda (template-vec) + (make-constructed-AV-template template-vec a))])) + +(define (make-AV-lam dom rng nargs restarg) + (create-AV + template-lam + (list 'lam-info nargs restarg) + (vector rng) + (vector dom))) + +(define AV-nil (void)) +(define AV-numb (void)) +(define AV-sym (void)) +(define AV-str (void)) +(define AV-char (void)) +(define AV-true (void)) +(define AV-false (void)) +(define AV-void (void)) +(define AV-undefined (void)) +(define AV-top-s (void)) + +(define (mk-tvar-nil) (mk-Tvar-init-AV 'nil AV-nil)) +(define (mk-tvar-numb) (mk-Tvar-init-AV 'num AV-numb)) +(define (mk-tvar-sym) (mk-Tvar-init-AV 'sym AV-sym)) +(define (mk-tvar-str) (mk-Tvar-init-AV 'str AV-str)) +(define (mk-tvar-char) (mk-Tvar-init-AV 'char AV-char)) +(define (mk-tvar-true) (mk-Tvar-init-AV 'true AV-true)) +(define (mk-tvar-false) (mk-Tvar-init-AV 'false AV-false)) +(define (mk-tvar-empty) (mk-Tvar 'empty)) +(define (mk-tvar-void) + (if (st:see-void) + (mk-Tvar-init-AV 'void AV-void) + (mk-Tvar 'void))) +(define (mk-tvar-undefined) (mk-Tvar-init-AV 'undefined AV-undefined)) + +(define (init-common-AV!) + (unless (template? template-nil) + (mrspidey:internal-error + "template-nil not a template, language probably not specified")) + (set! AV-nil (make-constructed-AV-template template-nil)) + (set! AV-numb (make-constructed-AV-template template-num)) + (set! AV-sym (make-constructed-AV-template template-sym)) + (set! AV-str (make-constructed-AV-template template-str)) + (set! AV-char (make-constructed-AV-template template-char)) + (set! AV-true (make-constructed-AV-template template-true)) + (set! AV-false (make-constructed-AV-template template-false)) + (set! AV-void (make-constructed-AV-template template-void)) + (set! AV-undefined (make-constructed-AV-template template-undefined)) + (set! AV-top-s (make-constructed-AV-template template-top-s)) + ) + +;; ====================================================================== + +(define traverse-simple-const + ;; Returns an AV, or #f + (match-lambda + [(or ($ zodiac:char _ _ _ c) (? char? c)) + (if (st:constants) + (create-AV template-char c (vector) (vector)) + AV-char)] + [(or ($ zodiac:symbol _ _ _ sym) (? symbol? sym)) + (if (st:constants) + (create-AV template-sym sym (vector) (vector)) + AV-sym)] + [(or ($ zodiac:number _ _ _ num) (? number? num)) + (if (st:constants) + (create-AV template-num num (vector) (vector)) + AV-numb)] + [(or ($ zodiac:string _ _ _ str) (? string? str)) AV-str] + [(or ($ zodiac:boolean _ _ _ #t) #t) AV-true] + [(or ($ zodiac:boolean _ _ _ #f) #f) AV-false] + [(or ($ zodiac:list _ _ _ ()) ()) AV-nil] + [_ #f])) + +(define traverse-const-exact + ;; Returns an AV + (lambda (V) + (or (traverse-simple-const V) + (match V + [(or ($ zodiac:list _ _ _ l) + (? pair? l) + (? null? l)) + (recur loop ([l l]) + (match l + [(a . d) + (let ([tvar-a (mk-Tvar 'car)] + [tvar-d (mk-Tvar 'cdr)]) + (new-AV! tvar-a (traverse-const-exact a)) + (new-AV! tvar-d (loop d)) + (make-AV-cons tvar-a tvar-d))] + [() AV-nil] + [x (traverse-const-exact x)]))] + [($ zodiac:improper-list _ _ _ l) + (recur loop ([l l]) + (match l + [(x) (traverse-const-exact x)] + [(a . d) + (let ([tvar-a (mk-Tvar 'car)] + [tvar-d (mk-Tvar 'cdr)]) + (new-AV! tvar-a (traverse-const-exact a)) + (new-AV! tvar-d (loop d)) + (make-AV-cons tvar-a tvar-d))]))] + [($ zodiac:vector _ _ _ v) + (let ([tvar-e (mk-Tvar 'vec-field)]) + (for-each + (lambda (e) (new-AV! tvar-e (traverse-const-exact e))) + v) + (make-AV-vec tvar-e))] + [(? vector? v) + (let ([tvar-e (mk-Tvar 'vec-field)]) + (for-each + (lambda (e) (new-AV! tvar-e (traverse-const-exact e))) + (vector->list v)) + (make-AV-vec tvar-e))] + [($ zodiac:box _ _ _ b) + (let ([tvar-e (mk-Tvar 'box-field)]) + (new-AV! tvar-e (traverse-const-exact b)) + (make-constructed-AV 'box tvar-e))] + [(? box? b) + (let ([tvar-e (mk-Tvar 'box-field)]) + (new-AV! tvar-e (traverse-const-exact (unbox b))) + (make-constructed-AV 'box tvar-e)) ] + [(? void?) + (make-constructed-AV 'void)] + [obj (error 'traverse-const-exact "Bad const ~s" obj)])))) + +;; ====================================================================== +;; Transitive closure of edgeto +;; Could use faster algorithm here + +(define (Tvar-transitive-edgeto Tvar) + (let*-vals ( [(reached? set-reached!) (alloc-Tvar-field)] + [edgeto '()]) + (recur loop ([Tvar Tvar]) + (unless (reached? Tvar) + (set-reached! Tvar #t) + (set! edgeto (cons Tvar edgeto)) + (for-each loop (Tvar-edgeto Tvar)) + (for-each + (match-lambda + [($ con-filter _ _ to) (loop to)] + [_ (void)]) + (Tvar-constraints Tvar)))) + (pretty-debug + `(Tvar-trans-edgeto ,(Tvar-name Tvar) ,(map Tvar-name edgeto))) + edgeto)) + +(define (Tvar-transitive-edgefrom Tvar) + (let*-vals ( [(reached? set-reached!) (alloc-Tvar-field)] + [edgefrom '()]) + (recur loop ([Tvar Tvar]) + (unless (reached? Tvar) + (set-reached! Tvar #t) + (set! edgefrom (cons Tvar edgefrom)) + (for-each loop (Tvar-edgefrom Tvar)))) + (pretty-debug + `(Tvar-trans-edgefrom ,(Tvar-name Tvar) ,(map Tvar-name edgefrom))) + edgefrom)) + +;; ====================================================================== + +(define (copy-constraint-set tvar tvar* edges) + ;; copies all Tvars in list tvar* + ;; edges: (listof (cons Tvar Tvar)) + + (pretty-debug + `(copy-constraint-set ,(Tvar-name (car tvar*)) ,(Tvar-name (rac tvar*)))) + + (let*-vals + ( [(tvar-nutvar set-tvar-nutvar!) (alloc-Tvar-field)] + [(AV-nuAV set-AV-nuAV!) (alloc-AV-field)] + [Tvar->nuTvar (lambda (tvar) (or (tvar-nutvar tvar) tvar))] + [copy-AV + (lambda (AV) + (or + (AV-nuAV AV) + (match AV + [(and AV ($ AV _ template misc fields+ fields-)) + (if (or + (vector-ormap tvar-nutvar fields+) + (vector-ormap tvar-nutvar fields-)) + (let* ( [nu-AV (create-AV + template misc + (vector-map Tvar->nuTvar fields+) + (vector-map Tvar->nuTvar fields-))]) + (set-AV-nuAV! AV nu-AV) + nu-AV) + (begin + (set-AV-nuAV! AV AV) + AV))])))]) + + (for-each + (lambda (Tvar) (set-tvar-nutvar! Tvar (mk-Tvar 'copy-constraint-set))) + tvar*) + + (for-each + (lambda (source) + (let ([dest (Tvar->nuTvar source)]) + ;; --- AV + (for-each + (lambda (AV) (new-AV! dest (copy-AV AV))) + (Tvar-objs source)) + ;; --- Constraints + (for-each + (match-lambda + [($ con _ template field-no Tvar sign) + (new-con! dest + (create-con template field-no (Tvar->nuTvar Tvar) sign))] + [($ con-filter _ filter Tvar) + (new-con! dest + (create-con-filter filter (Tvar->nuTvar Tvar)))]) + (Tvar-constraints source)) + ;; --- Edges + (for-each + (lambda (Tvar2) (new-edge! dest (Tvar->nuTvar Tvar2))) + (Tvar-edgeto source)))) + tvar*) + + (for-each + (match-lambda + [(from . to) + (new-edge! (Tvar->nuTvar from) (Tvar->nuTvar to))]) + edges) + + (Tvar->nuTvar tvar))) + +; ====================================================================== +; Non-Terminals + +(define-typed-structure NT (tvar type rhs*)) + +(define mk-Tvar-NTs! + (lambda (Tvar) + (set-Tvar-L! Tvar (make-NT Tvar 'L '())) + (set-Tvar-U! Tvar (make-NT Tvar 'U '())) + )) + +(define mk-AV-NTs! + (lambda (AV) + (set-AV-U! AV (make-NT AV 'U '())) + )) + +(define (chk-Tvar-L tvar) + (or (Tvar-L tvar) + (begin + (mk-Tvar-NTs! tvar) + (Tvar-L tvar)))) + +(define (chk-Tvar-U tvar) + (or (Tvar-U tvar) + (begin + (mk-Tvar-NTs! tvar) + (Tvar-U tvar)))) + +(define (chk-AV-U AV) + (or (AV-U AV) + (begin + (mk-AV-NTs! AV) + (AV-U AV)))) + +(define (alloc-NT-field) + (let* ( [table (make-hash-table)] + [get-info + (lambda (nt) + (hash-table-get table nt (lambda () #f)))] + [set-info! + (lambda (nt v) + (hash-table-put! table nt v))]) + (values get-info set-info!))) + +(define nt->sym + (match-lambda + [($ NT x type) + (symbol-append type ': + (if (Tvar? x) (Tvar-name x) + (symbol-append 'AV ': (AV-num x))))] + [x `(BAD-NT!!!! ,x)])) + +(define (AV->rep AV) (symbol-append 'AV ': (AV-num AV))) + +; ====================================================================== + +(define select-L + (lambda (nt*) + (filter-map (match-lambda [($ NT x 'L) x][_ #f]) nt*))) + +'(define select-LI + (lambda (nt*) + (filter-map (match-lambda [($ NT x 'LI) x][_ #f]) nt*))) + +(define select-U + (lambda (nt*) + (filter-map (match-lambda [($ NT x 'U) x][_ #f]) nt*))) + +'(define select-UI + (lambda (nt*) + (filter-map (match-lambda [($ NT x 'UI) x][_ #f]) nt*))) + +;; ====================================================================== diff --git a/collects/mrspidey/Sba/kernel.ss b/collects/mrspidey/Sba/kernel.ss new file mode 100644 index 0000000..62076aa --- /dev/null +++ b/collects/mrspidey/Sba/kernel.ss @@ -0,0 +1,785 @@ +;; kernel.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ----------------------------------------------------------------------= +;; FlowType == value flow graph node + +(define-const-typed-structure + FlowType + ( (: num num) + (! expr (union zodiac:parsed string false symbol)) + (! arrowto (listof FlowType)) + (! arrowfrom (listof FlowType)) + (! type-annotation any) ;; type-annotation% or file.ss (if from .za file) + (! proplist (listof (cons sym any))) + (! values-ftype (union false FlowType)) + )) + + (define num-ftype 0) + (define list-ftype '()) + (define num-edge 0) + + (define (init-FlowType!) + (set! num-ftype 0) + (set! list-ftype '()) + (set! num-edge 0)) + + ;;------------------------------------------------------------ +;; Extension functions + +(define (add-FlowType-arrow! from to) + (set-FlowType-arrowto! from (cons to (FlowType-arrowto from))) + (set-FlowType-arrowfrom! to (cons from (FlowType-arrowfrom to)))) + +(define (add-FlowType! ftype) + (set! num-ftype (add1 num-ftype)) + (set! list-ftype (cons ftype list-ftype)) + ftype) + +;;------------------------------------------------------------ +;; Property list stuff + +(define (add-FlowType-prop! ftype prop val) + (set-FlowType-proplist! ftype + (cons (cons prop val) (FlowType-proplist ftype)))) + +(define (get-FlowType-prop ftype prop default) + (recur loop ([l (FlowType-proplist ftype)]) + (match l + [() default] + [((a . d) . rest) + (if (eq? a prop) + d + (loop rest))] + [_ default]))) + +(define (FlowType-name ftype) + (symbol-append (get-FlowType-prop ftype 'symbol 'anon) + ': + (FlowType-num ftype))) + +;; ====================================================================== +;; ====================================================================== + +(define-typed-structure (Tvar struct:FlowType) + ( (: objs (listof AV)) + (: orig-objs (listof AV)) + (: constraints (listof (union con con-filter))) + (: leq-top-s bool) + (: edgeto (listof Tvar)) + (: edgefrom (listof Tvar)) + (: L NT) + (: U NT) + (: PL NT) + (: PU NT) + )) + +(define-const-typed-structure AV + ((: num num) + (: template template) + misc + (: fields+ (vec Tvar)) + (: fields- (vec Tvar)) + (! U NT) + (! PU any) + wb +)) + +(define-const-typed-structure template + ( (: type sym) + (: num+ int) + (: num- int) + (: ref (vec num)) + (: assign (vec num)) + (! super-templates (listof template)) + (: misc-eq? (any -> any)))) + + ;; ref and assign are for constructors + ;; ref maps a constructor-field to the AV-field+ to get value from + ;; assign maps a constructor-field to the AV-field- to add value to, + ;; or #f if immutable + ;; super-templates field records that eg num is a supertype of apply+ + ;; misc-eq? is an equality function on the misc field of AVs + ;; sym-ndx maps symbols to the index for that symbol + ;; eg. map ivar names + + + ;; Each elem of AV-fields is an Tvar + +(define-const-typed-structure con + ( (: num num) + (: template template) + (: field-no num) + (: tvar Tvar) + (: sign bool) + misc)) + +(define-const-typed-structure con-filter + ((: num num) + (: filter filter) + (: tvar Tvar))) + +(define-const-typed-structure filter + ((: sign bool) + (: templates (listof template)))) + +(define (create-filter sign templates) + (assert (and (boolean? sign) + (list? templates) + (andmap template? templates)) + 'create-filter sign templates) + (make-filter sign templates)) + +;; Says whether to include or exclude certain templates + +(define-const-typed-structure con-top-s + ()) + +(define con-top-s (make-con-top-s)) + +(define mt-vector (vector)) +;---------------------------------------------------------------------- + + (define num-con 0) + (define num-AV 0) + (define num-AV-in-Tvar 0) + (define max-constraint-system-size 0) + (define (constraint-system-size) (+ num-edge num-con num-AV-in-Tvar)) + + (define (SBA-entry->hash entry) + (hash-fn (FlowType-num (car entry)) + (let ([d (cdr entry)]) + (if (Tvar? d) + (FlowType-num d) + (AV-num d))))) + + (define (init-kernel!) + (init-FlowType!) + (set! num-con 0) + (set! num-AV 0) + (set! num-AV-in-Tvar 0) + (set! max-constraint-system-size 0) + (init-hash-table SBA-entry->hash 0) + ) + + ;;------------------------------------------------------------ + ;; Creation functions + + (define (create-AV template misc fields+ fields-) + (assert (and + (template? template) + (vector? fields+) + (vector? fields-) + (vector-andmap Tvar? fields+) + (vector-andmap Tvar? fields-)) + `(create-AV ,template ,misc ,fields+ ,fields-)) + (let ([AV (make-AV num-AV template misc fields+ fields- #f #f (make-weak-box 1))]) + (set! num-AV (add1 num-AV)) + AV)) + + (define mk-Tvar-nolist + (lambda (sym) + (let ([tvar (make-Tvar + ;; FlowType fields + num-ftype #f '() '() #f `((symbol . ,sym)) #f + ;; Tvar fields + '() '() '() #f '() '() + #f #f #f #f + )]) + (set! num-ftype (add1 num-ftype)) + tvar))) + + (define mk-Tvar + (lambda (sym) + (let ([tvar (mk-Tvar-nolist sym)]) + (set! list-ftype (cons tvar list-ftype)) + tvar))) + + (define (create-con template field-no tvar sign) + (create-con-misc template field-no tvar sign '())) + + (define (create-con-misc template field-no tvar sign misc) + (make-con num-con template field-no tvar sign misc)) + + (define (create-con-filter filter tvar) + (assert (filter? filter)) + (make-con-filter num-con filter tvar)) + +;; ---------------------------------------------------------------------- +;; Functions for extending graph +;; the add-* functions extend the data structures, but don't propogate +;; the check-add-* only adds if item not in data structure, but don't propogate +;; the extend-* functions also propogate values & constraints appropriately +;; the new-* functions are normally bound to extend-*, but sometines add-* +;; ---------------------------------------------------------------------- + +(define add-edge! + (lambda (from to) + (assert (and (Tvar? from) (Tvar? to)) 'add-edge! from to) + (set-Tvar-edgeto! from (cons to (Tvar-edgeto from))) + (set-Tvar-edgefrom! to (cons from (Tvar-edgefrom to))) + (set! num-edge (add1 num-edge)) + (add-entry (hash-fn (FlowType-num from) (FlowType-num to)) + (cons from to)))) + +(define add-AV! + (lambda (tvar AV) + (set! num-AV-in-Tvar (add1 num-AV-in-Tvar)) + (set-Tvar-objs! tvar (cons AV (Tvar-objs tvar))) + (add-entry (hash-fn (FlowType-num tvar) (AV-num AV)) + (cons tvar AV)))) + +(define add-con! + (lambda (tvar con) + (set! num-con (add1 num-con)) + (set-Tvar-constraints! tvar (cons con (Tvar-constraints tvar))))) + +'(define add-nohash-con! add-con!) + +;; ---------------------------------------------------------------------- +;; the check-add-* functions check if a constraint is present, +;; and if not, add it, but do not propogate + +(define check-add-edge! + (lambda (from to) + (assert (and (Tvar? from) (Tvar? to)) 'extend-edge! from to) + (unless + (or (Tvar-edge? from to) (eq? from to)) + (add-edge! from to)))) + + (define check-add-AV! + (lambda (tvar AV) + (assert (AV? AV) `(extend-AV! ,tvar ,AV)) + (set-Tvar-orig-objs! tvar (cons AV (Tvar-orig-objs tvar))))) + + (define check-add-con! + (lambda (tvar con) + (set! num-con (add1 num-con)) + (set-Tvar-constraints! tvar (cons con (Tvar-constraints tvar))) + (match con + [($ con-filter _ _ dest) + (set-Tvar-edgefrom! dest (cons tvar (Tvar-edgefrom dest)))] + [_ (void)]))) + +;; ---------------------------------------------------------------------- +;; the extend-* functions also propogate values & constraints appropriately + +(define extend-edge! + (lambda (from to) + (assert (and (Tvar? from) (Tvar? to)) 'extend-edge! from to) + (unless + (or (Tvar-edge? from to) (eq? from to)) + (add-edge! from to) + ;; Propogate all AV's + (for-each (lambda (AV) (prop-AV! to AV)) + (Tvar-objs from))))) + +(define extend-AV! + (lambda (tvar AV) + (assert (AV? AV) `(extend-AV! ,tvar ,AV)) + (set-Tvar-orig-objs! tvar (cons AV (Tvar-orig-objs tvar))) + (prop-AV! tvar AV))) + +(define prop-AV! + (lambda (tvar AV) + (assert (and (Tvar? tvar) (AV? AV)) `(prop-AV! ,tvar ,AV)) + (unless (Tvar-AV-mem? tvar AV) + (add-AV! tvar AV) + ;; Apply all constraints + (for-each + (lambda (con) (SBA-constraint tvar con AV)) + (Tvar-constraints tvar)) + ;; Propogate + (for-each + (lambda (to) (prop-AV! to AV)) + (Tvar-edgeto tvar))))) + + (define extend-con! + (lambda (tvar con) + (set! num-con (add1 num-con)) + (set-Tvar-constraints! tvar (cons con (Tvar-constraints tvar))) + (match con + [($ con-filter _ _ dest) + (set-Tvar-edgefrom! dest (cons tvar (Tvar-edgefrom dest)))] + [_ (void)]) + ;; Apply to all AV's + (for-each (lambda (AV) (SBA-constraint tvar con AV)) + (get-Tvar-objs tvar)))) + +;; ---------------------------------------------------------------------- +;; the new-* functions are normally equiv to extend-*, +;; but can be set to add-* via a parameter + +(define new-edge! extend-edge!) +(define new-AV! extend-AV!) +(define new-con! extend-con!) + +(define (new-leq-top-s! tvar) + ;; tvar <= top-s, is constraint + (unless (Tvar-leq-top-s tvar) + (set-Tvar-leq-top-s! tvar #t) + (new-con! tvar con-top-s))) + +(define (new-geq-top-s! tvar) + ;; top-s <= tvar, is AV + (new-AV! tvar AV-top-s)) + +;; ---------------------------------------------------------------------- + +(define keep-S-closed + (let ([closed #t]) + (case-lambda + [() closed] + [(x) + (set! closed x) + (if x + (begin + (set! new-edge! extend-edge!) + (set! new-AV! extend-AV!) + (set! new-con! extend-con!)) + (begin + (set! new-edge! check-add-edge!) + (set! new-AV! check-add-AV!) + (set! new-con! check-add-con!)))]))) + +(define new-create-AV! + (lambda (tvar template misc fields) + (new-AV! tvar (create-AV template misc fields)))) + +(define new-bidir-edge! + (lambda (from to) + (new-edge! from to) + (new-edge! to from))) + +(define new-edge-para + (case-lambda + [() new-edge!] + [(x) (set! new-edge! x)])) + +(define (close-constraints tvars) + (pretty-debug `(close-constraints ,(map Tvar-name tvars))) + (for-each + (lambda (tvar) + (for-each + (lambda (AV) + (for-each + (lambda (to) (prop-AV! to AV)) + (Tvar-edgeto tvar)) + (for-each + (lambda (con) (SBA-constraint tvar con AV)) + (Tvar-constraints tvar))) + (get-Tvar-objs tvar))) + tvars)) + + ;;------------------------------------------------------------ + ;; Handling constraints + +(define gSBA-constraint (void)) + +(define SBA-constraint + (lambda (tvar con AV) + (set! gSBA-constraint (list tvar con AV)) + (match con + ;; Regular constraints + [($ con _ template field-no tvar-con sign) + (match AV + [($ AV _ template2 misc fields+ fields-) + (when (or + (eq? template template2) + (memq template (template-super-templates template2))) + ;;(pretty-print `(,con ,AV)) + (if sign + (when (< field-no (vector-length fields+)) + ;; Propogate field from AV into tvar-con + (new-edge! (vector-ref fields+ field-no) tvar-con)) + (when (< field-no (vector-length fields-)) + ;; Propogate field from tvar-con into AV + (new-edge! tvar-con (vector-ref fields- field-no))))) + (when (eq? template2 template-top-s) + (if sign + (new-geq-top-s! tvar-con) + (new-leq-top-s! tvar-con)))])] + + ;; Filter constraints + [($ con-filter _ ($ filter bool templates) tvar-con) + '(printf "template ~s templates ~s memq ~s bool ~s add ~s~n" + (template-type (AV-template AV)) + (map template-type templates) + (memq (AV-template AV) templates) + bool + (case (memq (AV-template AV) templates) + [#f (not bool)] + [else bool])) + (let* ( [AV-t (AV-template AV)] + [found (ormap + (lambda (t2) + (or + (eq? AV-t t2) + (memq t2 (template-super-templates AV-t)))) + templates)]) + '(pretty-print-debug + `(con-filter found ,found + memq ,(memq AV-t templates) + AV-t ,(template-type AV-t) + ,(map template-type templates))) + (when (or (case found + [(#f) (not bool)] + [else bool]) + (eq? AV-t template-top-s)) + ;; Add AV to tvar-con + (prop-AV! tvar-con AV)))] + [($ con-top-s) + (match AV + [($ AV _ template2 misc fields+ fields-) + (vector-for-each new-leq-top-s! fields+) + (vector-for-each new-geq-top-s! fields-)])]))) + + ;;------------------------------------------------------------ + ;; Functions/predicates for examining the graph + + (define (Tvar-AV-mem? tvar AV) + (hash-find (hash-fn (FlowType-num tvar) (AV-num AV)) + (lambda (entry) + (and (eq? (car entry) tvar) + (eq? (cdr entry) AV))))) + + (define (Tvar-edge? from to) + (hash-find (hash-fn (FlowType-num from) (FlowType-num to)) + (lambda (entry) + (and (eq? (car entry) from) + (eq? (cdr entry) to))))) + + (define get-Tvar-objs Tvar-objs) + +;; ------------------------------------------------------------ + +(define (really-check-kernel-ok) + (dynamic-let + ([st:check-kernel #t]) + (check-kernel-ok))) + +(define check-kernel-ok:tvar #f) + +(define (check-kernel-ok) + ;; Sanity check + (when (st:check-kernel) + (assert (= num-ftype (length list-ftype))) + (let ([Tvar-edge? + (lambda (a b) + (or (eq? a b) + (Tvar-edge? a b)))]) + + (printf "check-kernel-ok: Consistency tests~n") + (for-each + (lambda (tvar) + (when (Tvar? tvar) + (assert (= (length (Tvar-objs tvar)) + (length (list->set (Tvar-objs tvar))))) + (assert (= (length (Tvar-edgeto tvar)) + (length (list->set (Tvar-edgeto tvar))))) + (assert (= (length (Tvar-constraints tvar)) + (length (list->set (Tvar-constraints tvar))))) + (for-each (lambda (AV) (assert (Tvar-AV-mem? tvar AV) (Tvar-name tvar))) + (Tvar-objs tvar)) + (for-each (lambda (to) (assert (Tvar-edge? tvar to))) + (Tvar-edgeto tvar)))) + list-ftype) + + ;; Now check kernel is closed under S + (printf "check-kernel-ok: Closure tests~n") + (for-each + (lambda (tvar) + (when (Tvar? tvar) + (for-each + (lambda (AV) + ;; First check AV prop'd + (for-each + (lambda (to) + (when (Tvar? to) + (assert (Tvar-AV-mem? to AV) + (Tvar-name tvar) (Tvar-name to) + (template-type (AV-template AV))))) + (Tvar-edgeto tvar)) + ;; Check AV applied to all constraints + (for-each + (match-lambda + [($ con _ template field-no tvar-con sign) + (match AV + [($ AV _ template2 misc fields+ fields-) + (when + (or + (eq? template template2) + (memq template (template-super-templates template2))) + (if sign + (when (< field-no (vector-length fields+)) + ;; Propogate field from AV into tvar-con + (assert + (Tvar-edge? + (vector-ref fields+ field-no) tvar-con) + `(Tvar-edge? + ,(Tvar-name (vector-ref fields+ field-no)) + ,(Tvar-name tvar-con)) + (Tvar-name tvar) field-no + (template-type template))) + (when (< field-no (vector-length fields-)) + ;; Propogate field from tvar-con into AV + (assert + (Tvar-edge? + tvar-con (vector-ref fields- field-no)) + (Tvar-name tvar) + field-no + (Tvar-name tvar-con) + sign + (template-type template)))))] + + [_ + ;; Constraint does not apply to this AV + (void)])] + [($ con-filter _ ($ filter bool templates) tvar-con) + ;; ignore for now + (void)]) + (Tvar-constraints tvar))) + (get-Tvar-objs tvar)))) + (reverse list-ftype)) + + ;; Now check all reachable tvars are in list-ftype + (printf "check-kernel-ok: list-ftype tests~n") + (let*-vals + ( [(get set) (alloc-Tvar-field (lambda () #f))] + [ok-tvar? (lambda (tvar) + (unless (get tvar) + (printf + "Tvar ~s reachable from ~s but not in list-ftype ~s~n" + (FlowType-num tvar) + (FlowType-num check-kernel-ok:tvar) + (memq tvar list-ftype))))] + [ok-AV? + (match-lambda + [($ AV _ _ _ fields+ fields-) + (vector-for-each ok-tvar? fields+) + (vector-for-each ok-tvar? fields-)])]) + + (for-each + (lambda (ftype) + (when (Tvar? ftype) (set ftype #t))) + list-ftype) + + (for-each + (lambda (ftype) + (when (Tvar? ftype) + (set! check-kernel-ok:tvar ftype) + (for-each ok-tvar? (Tvar-edgeto ftype)) + (for-each ok-tvar? (Tvar-edgefrom ftype)) + (for-each ok-AV? (Tvar-objs ftype)) + (for-each ok-AV? (Tvar-orig-objs ftype)) + (for-each + (match-lambda + [($ con _ _ _ tvar) (ok-tvar? tvar)] + [($ con-filter _ _ tvar) (ok-tvar? tvar)]) + (Tvar-constraints ftype)))) + list-ftype)) + + ))) + +(define (check-unreachable ftypes unreachable) + (let* ( [check-ok + (lambda (ftype) + (when (memq ftype unreachable) + (error 'check-unreachable "Ftype ~s in old ~s" + (FlowType-name ftype) + (map FlowType-name unreachable))))]) + (for-each + (lambda (ftype) + (when (Tvar? ftype) + (for-each check-ok (Tvar-edgeto ftype)) + (for-each check-ok (Tvar-edgefrom ftype)) + (for-each + (match-lambda + [($ AV _ _ _ fields+ fields-) + (vector-for-each check-ok fields+) + (vector-for-each check-ok fields-)]) + (Tvar-objs ftype)) + (for-each + (match-lambda + [($ con _ _ _ tvar) (check-ok tvar)] + [($ con-filter _ _ tvar) (check-ok tvar)]) + (Tvar-constraints ftype)))) + ftypes))) + + ;; ------------------------------------------------------------ + +(define-structure (kernel-state + num-ftype list-ftype num-edge + num-con num-AV num-AV-in-Tvar + closed? new-edge! hash-table-state)) + +(define (save-kernel-state) + (make-kernel-state + num-ftype list-ftype num-edge + num-con num-AV num-AV-in-Tvar + (keep-S-closed) new-edge! + (capture-hash-table-state))) + +(define restore-kernel-state! + (match-lambda + [($ kernel-state + saved-num-ftype saved-list-ftype saved-num-edge + saved-num-con saved-num-AV saved-num-AV-in-Tvar + closed? saved-new-edge! + hash-table-state) + (let ([old-size (constraint-system-size)]) + (set! num-ftype saved-num-ftype) + (set! list-ftype saved-list-ftype) + (set! num-edge saved-num-edge) + (set! num-con saved-num-con) + (set! num-AV saved-num-AV) + (set! num-AV-in-Tvar saved-num-AV-in-Tvar) + (keep-S-closed closed?) + (set! new-edge! saved-new-edge!) + (restore-hash-table-state! hash-table-state) + + (set! max-constraint-system-size + (max max-constraint-system-size + (+ (constraint-system-size) old-size))) + )])) + +(define free-kernel-state! + (match-lambda + [($ kernel-state + saved-num-ftype saved-list-ftype saved-num-edge + saved-num-con saved-num-AV saved-num-AV-in-Tvar + closed? saved-new-edge! + hash-table-state) + + (free-hash-table-state! hash-table-state) + (for-each + (lambda (ftype) + (set-FlowType-expr! ftype 'zerod1!) + (set-FlowType-arrowto! ftype 'zerod2!) + (set-FlowType-arrowfrom! ftype 'zerod3!) + (set-FlowType-type-annotation! ftype 'zerod4!) + (set-FlowType-proplist! ftype 'zerod5!) + (set-FlowType-values-ftype! ftype 'zerod6!) + (when (Tvar? ftype) + (set-Tvar-objs! ftype 'zerod7!) + (set-Tvar-orig-objs! ftype 'zerod8!) + (set-Tvar-constraints! ftype 'zerod9!) + (set-Tvar-edgeto! ftype 'zeroda!) + (set-Tvar-edgefrom! ftype 'zerodb!) + (set-Tvar-L! ftype 'zerodc!) + (set-Tvar-U! ftype 'zerodd!) + (set-Tvar-PL! ftype 'zerode!) + (set-Tvar-PU! ftype 'zerodf!))) + saved-list-ftype)])) + +;; ---------------------------------------------------------------------- + +(define-structure (prompt-kernel-state saved-state prompt-hash-state ftypes)) + +(define (prompt-kernel-state) + (make-prompt-kernel-state + (save-kernel-state) + (prompt-hash-table-state) + (map + (lambda (ftype) + (list + ftype + (match ftype + [($ FlowType _ _ arrowto arrowfrom _ _ values-ftype) + (list arrowto arrowfrom values-ftype)]) + (match ftype + [($ Tvar _ _ _ _ _ _ _ + objs orig-objs con edgeto edgefrom) + (list objs orig-objs con edgeto edgefrom)] + [_ #f]))) + list-ftype))) + +(define unprompt-kernel-state! + (match-lambda + [($ prompt-kernel-state saved-state prompt-hash-state ftypes) + (restore-kernel-state! saved-state) + (unprompt-hash-table-state! prompt-hash-state) + (for-each + (match-lambda + [(ftype (arrowto arrowfrom values-ftype) tvar-info) + (set-FlowType-arrowto! ftype arrowto) + (set-FlowType-arrowfrom! ftype arrowfrom) + (set-FlowType-values-ftype! ftype values-ftype) + (match tvar-info + [#f (void)] + [(objs orig-objs con edgeto edgefrom) + (set-Tvar-objs! ftype objs) + (set-Tvar-orig-objs! ftype orig-objs) + (set-Tvar-constraints! ftype con) + (set-Tvar-edgeto! ftype edgeto) + (set-Tvar-edgefrom! ftype edgefrom)])]) + ftypes)])) + +;; ------------------------------------------------------------ +;; Auxiliary info on Tvars + +(define alloc-Tvar-field + (case-lambda + [(default-fn) + (let* ( [table (make-hash-table)] + [get-info + (lambda (tvar) + (assert (FlowType? tvar) tvar 'get-info) + (hash-table-get table tvar default-fn))] + [set-info! + (lambda (tvar v) + (assert (FlowType? tvar) tvar 'set-info!) + (hash-table-put! table tvar v))]) + (values get-info set-info!))] + [() (alloc-Tvar-field (lambda () #f))])) + +(define alloc-AV-field + (case-lambda + [(default-fn) + (let* ( [table (make-hash-table)] + [get-info + (lambda (AV) + (hash-table-get table AV default-fn))] + [set-info! + (lambda (AV v) + (hash-table-put! table AV v))]) + (values get-info set-info!))] + [() (alloc-AV-field (lambda () #f))])) + +(define (field->set alloc-field) + (let*-vals ( [(get-info set-info!) (alloc-field)] + [list-obj '()] + [in? (lambda (obj) (get-info obj))] + [add! (lambda (obj) + (unless (in? obj) + (set-info! obj #t) + (set! list-obj (cons obj list-obj))))] + [get-list (lambda () list-obj)]) + (values in? add! get-list))) + +;; ---------------------------------------------------------------------- + +(define mk-Tvar-init-AV + (lambda (sym AV) + (let ([r (mk-Tvar sym)]) + (new-AV! r AV) + r))) + +(define (Tvar-name tvar) (FlowType-name tvar)) + +;; ====================================================================== + diff --git a/collects/mrspidey/Sba/language.ss b/collects/mrspidey/Sba/language.ss new file mode 100644 index 0000000..5764e87 --- /dev/null +++ b/collects/mrspidey/Sba/language.ss @@ -0,0 +1,1482 @@ +;; languages.ss - defines analyzed language +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define-struct language-spec + (kernel constructor-env initial-env tdef-env)) +(define language-spec (void)) + +(define make-expander-namespace (void)) + +;; ====================================================================== + +(define + st:language + (make-parameter-list + 'none + '( (DrScheme "DrScheme") + (MzScheme "MzScheme") + (MrEd "MrEd") + (R4RS "R4RS") + (Chez "Chez Scheme") + (none "None")) + (lambda (scheme) + (unless (eq? scheme 'none) + (init-default-constructor-env!) + (init-input-type-expander!) + (init-output-type-expander!) + (init-kernel!) + (init-common-AV!) + (set! make-expander-namespace (lambda () (make-namespace))) + (init-expand!) + (set! initial-env (make-hash-table)) + ;; --- + (init-R4RS!) + (case scheme + [(MzScheme) + (init-MzScheme-on-R4RS!)] + [(MrEd) (init-MzScheme-on-R4RS!) + (init-mzlib!) + (init-MrEd-on-MzScheme!) + (set! make-expander-namespace (lambda () (make-namespace 'wx)))] + [(DrScheme) + (init-MzScheme-on-R4RS!) + (init-mzlib!) + (init-DrScheme-on-MzScheme!) + (set! make-expander-namespace (lambda () (make-namespace 'wx))) + ] + [(R4RS) (void)] + [(Chez) (init-Chez-on-R4RS!)] + [(none) (void)]) + (when (st:numops) (init-smart-numops!) (init-vectors-w/-length)) + + (when (file-exists? "~/.spideyrc") (language-add-boot-file "~/.spideyrc")) + (let ([systemrc (string-append "~/.spidey-" + (symbol->string scheme) + "-rc")]) + (when (file-exists? systemrc) (language-add-boot-file systemrc))) + + ;; + ;(printf "Saving language spec ... ") + (set! language-spec + (make-language-spec + (prompt-kernel-state) + constructor-env + initial-env + global-tdef-env)) + ;(printf "done~n") + )))) + +;(trace st:language) + +;; ---------------------------------------------------------------------- + +(define (initialize-language!) + (mrspidey:progress "Initializing language" '...) + (match language-spec + [($ language-spec k c i t) + (pretty-debug '(initialize-language!)) + (unprompt-kernel-state! k) + (set-constructor-env! c) + (set! initial-env i) + (init-global-tenv! '() t '()) + ]) + (mrspidey:progress "Initializing language" 'done)) + +;; ---------------------------------------------------------------------- + +(define st:numops ;; Default false + (let ([value #f]) + (match-lambda* + [() value] + [('?) `( (#f "Inaccurate" "") + (#t "Accurate" ""))] + [(nu) + (unless (boolean? nu) (error 'st:numops "Bad parameter")) + (unless (eq? value nu) + (set! value nu) + (when value (st:constants #t)) + ;; Reprocess the language + (st:language (st:language))) + value]))) + +;; ====================================================================== + +(define initial-env '()) + +(define (extend-initial-env! sym ftype) + (assert (and (symbol? sym) (FlowType? ftype)) 'extend-initial-env) + (hash-table-put! initial-env sym ftype) + (hash-table-put! initial-env (symbol-append '#% sym) ftype)) + +(define list-primitives '()) + +(define (add-default-primitive! name type . attrs) + (set! list-primitives (cons (list name type) list-primitives)) + ;; working w/ default primitive env => use default constructor env + (let* ([def (apply primitive->atprim name type attrs)] + [ftype (create-fo-FlowType def)]) + (extend-initial-env! name ftype))) + +(define (show-primitives) + (let ([l (quicksort list-primitives + (lambda (a b) + (stringstring (car a)) (symbol->string (car b)))))] + [file "~/Spidey/doc/prims.tex"]) + (when (file-exists? file) (delete-file file)) + (with-output-to-file file + (lambda () + (for-each + (match-lambda + [(name type) + (printf "\\scheme|~s| \\> ~n" name) + (printf "\\begin{schemedisplay}~n") + (parameterize ([pretty-print-columns 60]) + (pretty-print type)) + (printf "\\end{schemedisplay}~n") + (printf "\\\\~n")]) + l))))) + +(define (add-default-primitives! l) + (for-each + (match-lambda + [(name 'GLOBAL-TYPE-VARIABLE) + '(add-default-tdef! name)] + [args (apply add-default-primitive! args)]) + l)) + +(define (add-default-tdef! name) (add-global-tdef! name)) + +; (let ([Tvar (mk-Tvar (symbol-append 'default-tdef: name))]) +; (set! default-tdef-env +; (cons (cons name Tvar) default-tdef-env)))) + +;; ====================================================================== + +(define (get-default-bindings free-names) + (recur loop ([env atenv:empty][free-names free-names]) + (match free-names + [() env] + [(name . rest) + (let ([sym (zodiac:binding-var name)]) + (match (hash-table-get initial-env sym (lambda () #f)) + [#f + (mrspidey:warning (format "Free variable ~s" sym)) + (loop env rest)] + [ftype (loop (atenv:extend env name ftype) rest)]))]))) + +;; ====================================================================== + +(define (language-add-boot-file filename) + (let*-vals + ( [filename (normalize-path filename)] + [boot-defs (zodiac:read* (open-code-file filename) filename)] + [(defs free-names) (my-scheme-expand-program boot-defs)] + [env (get-default-bindings free-names)] + [(env refs result) (top-level-traverse-defs defs env)]) + (for-each + (match-lambda + [($ zodiac:define-values-form _ _ _ _ refs) + (for-each + (lambda (ref) + (let ([var (zodiac:varref-binding ref)]) + (pretty-debug `(Defining ,(zodiac:binding-var var))) + (extend-initial-env! + (zodiac:binding-var var) + (atenv:lookup env var)))) + refs)] + [_ (void)]) + defs))) + +;; ====================================================================== + +(define (init-R4RS!) + ;; Also extends it with void + + (add-constructor! 'vec #t) + (add-constructor! 'iport) + (add-constructor! 'oport) + (add-constructor! 'eof ) + (add-constructor! 'box #t) + + ;; for demos + (add-constructor! 'pair #t #t) + + (add-default-primitives! + `( + ;; for demos + (nil nil) + (pair (forall (a b) (a b -> (pair a b)))) + (left (forall (a) ((pair a _) -> a))) + (right (forall (a) ((pair _ a) -> a))) + + ;;(nil nil) + + ;; booleans + (not (_ -> bool) (predicate* (#t false) (#f false))) + + ;; equivalence predicates + (eqv? (_ _ -> bool)) + (eq? (_ _ -> bool)) + (equal? (_ _ -> bool)) + + ;; pairs and lists + (cons (forall (a b) (a b -> (cons a b)))) + (car (forall (a) ((cons a _) -> a))) + (cdr (forall (a) ((cons _ a) -> a))) + (caar (forall (a) ((cons (cons a _) _) -> a))) + (cadr (forall (a) ((cons _ (cons a _)) -> a))) + (cdar (forall (a) ((cons (cons _ a) _) -> a))) + (cddr (forall (a) ((cons _ (cons _ a)) -> a))) + (caaar (forall (a) ((cons (cons (cons a _) _) _) -> a))) + (caadr (forall (a) ((cons _ (cons (cons a _) _)) -> a))) + (cadar (forall (a) ((cons (cons _ (cons a _)) _) -> a))) + (caddr (forall (a) ((cons _ (cons _ (cons a _))) -> a))) + (cdaar (forall (a) ((cons (cons (cons _ a) _) _) -> a))) + (cdadr (forall (a) ((cons _ (cons (cons _ a) _)) -> a))) + (cddar (forall (a) ((cons (cons _ (cons _ a)) _) -> a))) + (cdddr (forall (a) ((cons _ (cons _ (cons _ a))) -> a))) + (caaaar (forall (a) ((cons (cons (cons (cons a _) _) _) _) -> a))) + (caaadr (forall (a) ((cons _ (cons (cons (cons a _) _) _)) -> a))) + (caadar (forall (a) ((cons (cons _ (cons (cons a _) _)) _) -> a))) + (caaddr (forall (a) ((cons _ (cons _ (cons (cons a _) _))) -> a))) + (cadaar (forall (a) ((cons (cons (cons _ (cons a _)) _) _) -> a))) + (cadadr (forall (a) ((cons _ (cons (cons _ (cons a _)) _)) -> a))) + (caddar (forall (a) ((cons (cons _ (cons _ (cons a _))) _) -> a))) + (cadddr (forall (a) ((cons _ (cons _ (cons _ (cons a _)))) -> a))) + (cdaaar (forall (a) ((cons (cons (cons (cons _ a) _) _) _) -> a))) + (cdaadr (forall (a) ((cons _ (cons (cons (cons _ a) _) _)) -> a))) + (cdadar (forall (a) ((cons (cons _ (cons (cons _ a) _)) _) -> a))) + (cdaddr (forall (a) ((cons _ (cons _ (cons (cons _ a) _))) -> a))) + (cddaar (forall (a) ((cons (cons (cons _ (cons _ a)) _) _) -> a))) + (cddadr (forall (a) ((cons _ (cons (cons _ (cons _ a)) _)) -> a))) + (cdddar (forall (a) ((cons (cons _ (cons _ (cons _ a))) _) -> a))) + (cddddr (forall (a) ((cons _ (cons _ (cons _ (cons _ a)))) -> a))) + + (set-car! (forall (a) ((cons (! a) _) a -> void))) + (set-cdr! (forall (b) ((cons _ (! b)) b -> void))) + (list (case-> + (forall (a b c d e) (a b c d e -> (list a b c d e))) + (forall (a b c d) (a b c d -> (list a b c d))) + (forall (a b c) (a b c -> (list a b c))) + (forall (a b) (a b -> (list a b))) + (forall (a) (a -> (list a))) + (forall (a) (a *-> a)))) + (length ((listof _) -> num)) + (append (case-> + (forall (l) (l -> l)) + (forall (a l) + ((listof a) l -> + (MU out (union (cons a out) l)))) + (forall (inlist a) + ((arglistof (union inlist (listof a))) + *-> + (MU out (union (cons a out) inlist)))))) + (reverse (forall (a) ((listof a) -> (listof a)))) + (list-tail (forall (a tail) + ((MU l (union nil (cons a (union l tail)))) + num + -> (cons a tail)))) + (list-ref (forall (a) ((listof a) num -> a))) + (memq (forall (a tail) + (a (MU l (union nil (cons a l) tail)) + -> (union false (cons a tail))))) + (memv (forall (a tail) + (a (MU l (union nil (cons a l) tail)) + -> (union false (cons a tail))))) + (member (forall (a tail) + (a (MU l (union nil (cons a l) tail)) + -> (union false (cons a tail))))) + (assq (forall (a c) + (a (listof (cons a c)) -> + (union false (cons a c))))) + (assv (forall (a c) + (a (listof (cons a c)) -> + (union false (cons a c))))) + (assoc (forall (a c) + (a (listof (cons a c)) -> + (union false (cons a c))))) + + ;; symbols + (symbol->string (sym -> str)) + (string->symbol (str -> sym)) + + ;; numbers + (complex? (_ -> bool) (predicate* (#t num) _)) + (real? (_ -> bool) (predicate* (#t num) _)) + (rational? (_ -> bool) (predicate* (#t num) _)) + (integer? (_ -> bool) (predicate* (#t num) _)) + (exact? (num -> bool)) + (inexact? (num -> bool)) + (= ((arg num (arg num (arglistof num))) *-> bool) ) + (< ((arg num (arg num (arglistof num))) *-> bool) ) + (> ((arg num (arg num (arglistof num))) *-> bool) ) + (<= ((arg num (arg num (arglistof num))) *-> bool) ) + (>= ((arg num (arg num (arglistof num))) *-> bool) ) + (zero? (num -> bool)) + (positive? (num -> bool)) + (negative? (num -> bool)) + (odd? (num -> bool)) + (even? (num -> bool)) + (max ((arg num (arglistof num)) *-> num) ) + (min ((arg num (arglistof num)) *-> num) ) + (+ ((arglistof num) *-> num) ) + (* ((arglistof num) *-> num) ) + (- ((arg num (arglistof num)) *-> num) ) + (/ ((arg num (arglistof num)) *-> num) ) + (abs (num -> num)) + (quotient (num num -> num)) + (remainder (num num -> num)) + (modulo (num num -> num)) + (gcd ((arglistof num) *-> num) ) + (lcm ((arglistof num) *-> num) ) + (numerator (num -> num) ) + (denominator (num -> num) ) + (floor (num -> num) ) + (ceiling (num -> num) ) + (truncate (num -> num) ) + (round (num -> num) ) + (rationalize (num num -> num) ) + (exp (num -> num) ) + (log (num -> num) ) + (sin (num -> num) ) + (cos (num -> num) ) + (tan (num -> num) ) + (asin (num -> num) ) + (acos (num -> num) ) + (atan (num optional num -> num) ) + (sqrt (num -> num) ) + (expt (num num -> num) ) + (make-rectangular (num num -> num) ) + (make-polar (num num -> num) ) + (real-part (num -> num) ) + (imag-part (num -> num) ) + (magnitude (num -> num) ) + (angle (num -> num) ) + (exact->inexact (num -> num) ) + (inexact->exact (num -> num) ) + (number->string (num optional num -> str) ) + (string->number (str optional num -> num) ) + + ;; characters + (char=? (char char -> bool) ) + (char bool) ) + (char>? (char char -> bool) ) + (char<=? (char char -> bool) ) + (char>=? (char char -> bool) ) + (char-ci=? (char char -> bool) ) + (char-ci bool) ) + (char-ci>? (char char -> bool) ) + (char-ci<=? (char char -> bool) ) + (char-ci>=? (char char -> bool) ) + (char-alphabetic? (char -> bool) ) + (char-numeric? (char -> bool) ) + (char-whitespace? (char -> bool) ) + (char-upper-case? (char -> bool) ) + (char-lower-case? (char -> bool) ) + (char->integer (char -> num) ) + (integer->char (num -> char) ) + (char-upcase (char -> char) ) + (char-downcase (char -> char) ) + + ;; strings + (make-string (num optional char -> str) ) + (string ((arglistof char) *-> str) ) + (string-length (str -> num) ) + (string-ref (str num -> char) ) + (string-set! (str num char -> void) ) + (string=? (str str -> bool) ) + (string bool) ) + (string>? (str str -> bool) ) + (string<=? (str str -> bool) ) + (string>=? (str str -> bool) ) + (string-ci=? (str str -> bool) ) + (string-ci bool) ) + (string-ci>? (str str -> bool) ) + (string-ci<=? (str str -> bool) ) + (string-ci>=? (str str -> bool) ) + (substring (str num num -> str) ) + (string-append ((arglistof str) *-> str) ) + (string->list (str -> (listof char)) ) + (list->string ((listof char) -> str) ) + (string-copy (str -> str) ) + (string-fill! (str char -> void) ) + + ;; vectors + ;; make-vector -- different semantics + (make-vector (case-> + (num -> (vec num)) + (forall (a) (num a -> (vec a))) + (forall (a) (num optional a -> (vec (union a num)))))) + (vector (forall (a) ((arglistof a) *-> (vec a)))) + (vector-length (forall (a) ((vec a) -> num))) + (vector-ref (forall (a) ((vec a) num -> a))) + (vector-set! (forall (a) ((vec (! a)) num a -> void))) + (vector->list (forall (a) ((vec a) -> (listof a)))) + (list->vector (forall (a) ((listof a) -> (vec a)))) + (vector-fill! (forall (a) ((vec (! a)) a -> void))) + + ;; control features + (apply (case-> + (forall (l r) ((l *->* r) l ->* r)) + (forall (a l r) ((a l *->* r) a l ->* r)) + (forall (a b l r) ((a b l *->* r) a b l ->* r)) + (forall (a b c l r) ((a b c l *->* r) a b c l ->* r)) + (forall (a b c d l r) ((a b c d l *->* r) a b c d l ->* r)) + (forall (x r) + (((MU l (union (cons x l) x)) *->* r) + x + (arglistof x) + *->* r)))) + (map (case-> + (forall (a r) + ((a -> r) (listof a) + -> (listof r))) + (forall (a b r) + ((a b -> r) (listof a) (listof b) + -> (listof r))) + (forall (a b c r) + ((a b c -> r) (listof a) (listof b) (listof c) + -> (listof r))) + (forall (x r) + (((arglistof x) *-> r) (listof x) (arglistof (listof x)) + *-> (listof r))))) + + (for-each (case-> + (forall (a) + ((a -> _) (listof a) + -> void)) + (forall (a b) + ((a b -> _) (listof a) (listof b) + -> void)) + (forall (a b c) + ((a b c -> _) (listof a) (listof b) (listof c) + -> void)) + (forall (x) + (((arglistof x) *-> _) (listof x) (arglistof (listof x)) + *-> void)))) + + (force (forall (a) ((promise a) -> a))) + (make-promise ((-> a) -> (promise a))) + (promise? (_ -> bool) (predicate promise)) + (call-with-current-continuation + (forall (a) (((a *-> empty) ->* (mvalues a)) ->* (mvalues a)))) + (eval (sexp -> sexp));; --- Not quite right!!! + + ;; input and output + (call-with-input-file (forall (a) (str (iport -> a) -> a))) + (call-with-output-file (forall (a) (str (oport -> a) -> a))) + (current-input-port (-> iport) ) + (current-output-port (-> oport) ) + (with-input-from-file (forall (a) (str (-> a) -> a))) + (with-output-to-file (forall (a) (str (-> a) -> a))) + (open-input-file (str -> iport) ) + (open-output-file (str -> oport) ) + (close-input-port (iport -> void) ) + (close-output-port (oport -> void) ) + + (read (optional iport -> (union eof sexp))) + (read-char (optional iport -> (union char eof))) + (peek-char (optional iport -> (union char eof))) + (char-ready? (optional iport -> bool)) + (write (optional oport -> void)) + (display (_ optional oport -> void)) + (newline (optional oport -> void)) + (write-char (char optional oport -> void)) + + ;; system interface + (load (str -> void) ) + (transcript-on (str -> void) ) + (transcript-off (-> void) ) + + ;; predicates + (number? (_ -> bool) (predicate num)) + (null? (_ -> bool) (predicate nil)) + (char? (_ -> bool) (predicate char)) + (symbol? (_ -> bool) (predicate sym)) + (string? (_ -> bool) (predicate str)) + (vector? (_ -> bool) (predicate vec)) + (cvector? (_ -> bool) (predicate vec)) + (pair? (_ -> bool) (predicate cons)) + (procedure? (_ -> bool) (predicate lambda)) + (eof-object? (_ -> bool) (predicate eof)) + (input-port? (_ -> bool) (predicate iport)) + (output-port? (_ -> bool) (predicate oport)) + (boolean? (_ -> bool) (predicate true false)) + (list? (_ -> bool) (predicate* (#t nil cons) (#f nil))) + + ))) + +;; ====================================================================== + +(define (language-add-boxes-etc!) + (add-default-primitives! + `( + (read (optional iport -> (union eof sexp))) + (box? (_ -> bool) (predicate box)) + (box (forall (a) (a -> (box a)))) + (unbox (forall (a) ((box a) -> a))) + (set-box! (forall (a) ((box (! a)) a -> void))) + (void (-> void)) + + (add1 (num -> num) ) + (sub1 (num -> num) ) + (ormap (case-> + (forall (a r) + ((a -> r) (listof a) -> (union false r))) + (forall (a b r) + ((a b -> r) (listof a) (listof b) + -> (union false r))) + (forall (a b c r) + ((a b c -> r) (listof a) (listof b) (listof c) + -> (union false r))) + (forall (x r) + (((arglistof x) *-> r) (arglistof (listof x)) + *-> (union false r))))) + (andmap (case-> + (forall (a r) + ((a -> r) (listof a) -> (union true r))) + (forall (a b r) + ((a b -> r) (listof a) (listof b) + -> (union true r))) + (forall (a b c r) + ((a b c -> r) (listof a) (listof b) (listof c) + -> (union true r))) + (forall (x r) + (((arglistof x) *-> r) (arglistof (listof x)) + *-> (union true r))))) + + (append! (forall (p) + ((arglistof + (MU q (union (cons _ q) (cons _ p) (cons _ (! p))))) + *-> + p))) + (exit (optional num -> empty)) + (format (str _ *-> str)) + (fprintf (oport str (arglistof _) *-> void)) + (getenv (str -> (union str false))) + (list* (forall (l a) + ((arglistof (union l (listof a))) + *-> (MU o (union l (cons a o)))))) + (printf (str _ *-> void)) + (putenv (str str -> bool)) + (random (num -> num)) + (random-seed (num -> void)) + (reverse! + (forall + (l p a) + ((arglistof (MU l (union p (cons a l) (cons _ (! p))))) *-> p))) + + (pretty-print (_ optional oport -> void) ) + (gensym (optional (union sym str) -> sym)) + (sort (forall (a) ((a a -> _) (listof a) -> (listof a)))) + + (string->uninterned-symbol (str -> sym)) + + (remove (forall (a) + (a (listof a) optional (a a -> bool) + -> (listof a)))) + (remq (forall (a) (a (listof a) -> (listof a)))) + (remv (forall (a) (a (listof a) -> (listof a)))) + + (dynamic-wind (forall (b) ((-> _) (-> b) (-> _) -> b))) + (call/cc (forall (a) (((a *-> empty) ->* (mvalues a)) ->* (mvalues a)))) + + ))) + + +(define (init-Chez-on-R4RS!) + + (language-add-boxes-etc!) + + (add-default-primitives! + `( + (void (-> void) ) + + ;; Standard Chez Scheme primitives. + (make-list (forall (a) (num a -> (listof a)))) + (error (_ str _ *-> empty)) + (expand-once (sexp -> sexp) ) + + ))) + +;; ---------------------------------------------------------------------- + +(define this-directory (current-load-relative-directory)) + +(define (init-MzScheme-on-R4RS!) + + ;; Syntactic forms unimplemented + ;; define-struct + ;; objects + ;; let/cc, let/rc + ;; eval, comple + ;; begin0 + ;; fluid-let + ;; letrec* + ;; make-global-value-list + ;; time, unless + + (language-add-boxes-etc!) + + ;; Could make weight a field of thread + (add-constructor! 'thread) + (add-constructor! 'hash-table #t #t) + (add-constructor! 'weak-box #f) + (add-constructor! 'regexp) + (add-constructor! 'arity-at-least #f) + (add-constructor! 'parameterization) + (add-constructor! 'semaphore) + (add-constructor! 'type-symbol) + (add-constructor! 'namespace) + (add-constructor! 'custodian) + (add-constructor! 'will-executor) + (add-constructor! 'tcp-listener) + + (add-default-primitives! + `( + ;; MzSchemes f*cked up void :-) + (void (_ *-> void)) + + (eof eof) + + ;; Organization follows MzScheme Reference Manual + ;; --- Programming Constructs + + ;; Void and Undefined + (void? (_ -> bool) (predicate void)) + + ;; Number extensions + (bitwise-ior (num (arglistof num) *-> num)) + (bitwise-and (num (arglistof num) *-> num)) + (bitwise-xor (num (arglistof num) *-> num)) + (bitwise-not (num (arglistof num) *-> num)) + (arithmetic-shift (num num -> num)) + + ;; --- Semaphores + + (make-semaphore (num -> semaphore)) + (semaphore? (semaphore -> bool) (predicate semaphore)) + (semaphore-post (semaphore -> void)) + (semaphore-wait (semaphore -> void)) + (semaphore-try-wait (semaphore -> bool)) + (semaphore-callback (semaphore (-> _) -> bool)) + (input-port-post-semaphore (iport semaphore -> void)) + + ;; --- Ports + ;; Current ports + (current-input-port (optional iport -> iport)) + (current-output-port (optional oport -> oport)) + (current-error-port (optional oport -> oport)) + + (thread-input-port (-> iport)) + (thread-output-port (-> oport)) + (thread-error-port (-> iport)) + + (open-input-file (str optional sym -> iport)) + (open-output-file (str optional sym optional sym -> oport)) + + (call-with-input-file + (forall (a) (str (iport -> a) optional sym -> a))) + (call-with-output-file + (forall (a) (str (oport -> a) optional sym optional sym -> a))) + (with-input-from-file + (forall (a) (str (-> a) optional sym -> a))) + (with-output-to-file + (forall (a) (str (-> a) optional sym optional sym -> a))) + + ;; String ports + (open-input-string (str -> iport)) + (open-output-string (-> oport)) + (get-output-string (oport -> str)) + + ;; File ports + (flush-output (optional oport -> void)) + (file-position ((union iport oport) optional num -> num)) + + ;; Custom ports + (make-input-port ((-> char) (-> bool) (-> void) -> iport)) + (make-output-port ((str -> void) (-> void) -> oport)) + + ;; ---- Filesystem Utilities + ;; Files + (file-exists? (str -> bool)) + (delete-file (str -> bool)) + (rename-file (str str -> bool)) + (file-modify-seconds (str -> num)) + (file-or-directory-permissions (str -> (listof sym))) + + ;; Hash Tables - fields are key and value + (make-hash-table (optional sym -> (hash-table empty empty))) + (make-hash-table-weak (optional sym -> (hash-table empty empty))) + (hash-table? (_ -> bool) (predicate hash-table)) + (hash-table-put! + (forall (k v) ((hash-table (! k) (! v)) k v -> void))) + (hash-table-get + (forall (k v r) ((hash-table k v) _ optional (-> r) -> (union v r)))) + (hash-table-remove! + (forall (k v) ((hash-table _ _) _ -> void))) + (hash-table-map + (forall (k v w) ((hash-table k v) (k v -> w) -> (listof w)))) + (hash-table-for-each + (forall (k v) ((hash-table k v) (k v -> _) -> void))) + + ;; Weak boxes + (make-weak-box (forall (v) (v -> (weak-box (union v false))))) + (weak-box? (_ -> bool) (predicate weak-box)) + (weak-box-value (forall (v) ((weak-box v) -> v))) + + ;; Regular expressions + (regexp (str -> regexp)) + (regexp? (_ -> bool) (predicate regexp)) + (regexp-match ((union str regexp) str + -> (union false (listof str)))) + (regexp-match-positions + ((union str regexp) str -> (union false (listof (cons num num))))) + (regexp-replace ((union str regexp) str str -> str)) + (regexp-replace* ((union str regexp) str str -> str)) + + ;; Global type variables don't work, so analysis of + ;; exception handling is unsound here + + ;; Exceptions +;; (global:CEH GLOBAL-TYPE-VARIABLE) +;; (global:raised-values GLOBAL-TYPE-VARIABLE); +;; +;; (raise (global:raised-values -> empty)) +;; (current-exception-handler +;; (optional (intersect global:CEH +;; (global:raised-values -> _)) +;; -> global:CEH)) + + (raise (_ -> empty)) + (current-exception-handler (optional (empty -> _) -> empty)) + + (make-exn:else (_ *-> empty)) + + ;; Flow control + (call-with-escaping-continuation + (forall (a) (((a *-> empty) ->* (mvalues a)) ->* (mvalues a)))) + + (call/ec (forall (a) (((a *-> empty) ->* (mvalues a)) ->* (mvalues a)))) + + (values (forall (a) (a *->* (mvalues a)))) + (call-with-values (forall (x r) ((list (nil *->* (mvalues x)) + (x *->* (mvalues r))) + *->* (mvalues r)))) + + ;; -------------------- + + ;; Arity + (arity ((empty *-> _) -> + (rec ([r (union num (arity-at-least num))]) + (union r (listof r))))) + (arity-at-least? (_ -> bool) (predicate arity-at-least)) + (arity-at-least-value (forall (v) ((arity-at-least v) -> v))) + + ;; Global and Constant Names + (defined? (sym -> bool)) + + ;; Evaluation Handler - no can type :- + + ;; Handlers + (current-print (optional (empty -> void) -> (_ -> void))) + (current-prompt-read + (optional (-> (union eof sexp)) -> (-> (union eof sexp)))) + (error ((union sym str) (arglistof _) *-> empty)) + + ;; ### problems with types for handlers + + (error-display-handler (optional (empty -> void) -> (_ -> void))) + (error-escape-handler (optional (-> _) -> (-> empty))) + (exit-handler (optional (num -> _) -> (num -> empty))) + + ;; User Breaks + (user-break-poll-handler (optional (-> bool) -> (-> bool))) + (break-enabled (optional _ -> bool)) + (dynamic-enable-break (forall (v) ((-> v) -> v))) + + ;; Compilation + (compile-file ((union str iport) (union str oport) _ -> void)) + + ;; Dynamic extensions + (load-extension (str -> void)) + + ;; Operating System Processes + (system (str -> bool)) + (sytem* (str (arglistof str) *-> bool)) + (process (str -> + (cons iport + (cons oport + (cons num (cons iport nil)))))) + (process* (str (arglistof str) *-> + (cons iport + (cons oport + (cons num (cons iport nil)))))) + + ;; Misc + (banner (-> str)) + (gensym (optional (union str sym) -> sym)) + (load/cd (str -> void)) + (load-with-cd (str -> void)) + (promise? (_ -> bool) (predicate promise)) + (read-eval-print-loop (-> void)) + (read-line (optional iport -> (union str eof))) + (system-type (-> sym)) + (version (-> str)) + + ;; Signature stuff + (#%unit-with-signature-unit empty) + (#%make-unit-with-signature empty) + (#%verify-linkage-signature-match empty) + + ;; -------------------------------------------------------------------- + ;; the following is structured after the MzScheme ref manual 5.9.97 + + ;; ------ basic data extensions + ;; ---- procedures + ;; -- primitives + (primitive? (_ -> bool) (predicate* (#t lambda) _)) + (primitive-name ((empty *->* _) -> sym)) + (primitive-result-arity? ((empty *->* _) -> num)) + (primitive-result-arity? ((empty *->* _) -> bool)) + + ;; ------ structures + ;; ---- structure utilities + (struct? (_ -> bool) (predicate structure:)) + (struct-length (structure: -> num)) + (struct-type? (-> bool)) + (struct-constructor-procedure? (-> bool)) + (struct-predicate-procedure? (-> bool)) + (struct-selector-procedure? (-> bool)) + (struct-setter-procedure? (-> bool)) + + ;; ------ classes and objects + ;; ---- object utilities + + (object? (_ -> bool)) + (class? (_ -> bool) (predicate internal-class)) + (is-a? (_ _ -> bool)) + (make-object + (forall (args u o f v) + ( (internal-class u o (args *->* _) (! u) (! o) o (! o) (! o) v) + args + *-> + (union o v)))) + (ivar-in-class? (_ _ -> bool)) + (uq-ivar (forall (i) ((all-ivars i) _ -> i))) + + + + + ;; ------ units + (unit/sig->unit (forall (a) (a -> a))) + (unit? (_ -> bool)) + + ;; ------ threads and namespaces + ;; ---- threads + (thread ((-> _) -> thread)) + ;; -- thread utilities + (current-thread (-> thread)) + (thread? (_ -> bool) (predicate thread)) + (sleep (num -> void)) + (thread-running? (thread -> bool)) + (thread-wait (thread -> void)) + (kill-thread (thread -> void)) + (break-thread (thread -> void)) + (thread-weight (case-> + (thread -> num) + (thread num -> void))) + ;; ---- semaphores + (make-semaphore (optional num -> semaphore)) + (semaphore? (_ -> bool) (predicate semaphore)) + (semaphore-post (semaphore -> void)) + (semaphore-wait (semaphore -> void)) + (semaphore-try-wait? (semaphore -> bool)) + (semaphore-wait/enable-break (semaphore -> void)) + (semaphore-callback (semaphore (-> _) -> void)) + (input-port-post-semaphore (iport semaphore -> void)) + + ;; ---- parameterization + ;; -- built-in parameters + ;; loading + (current-load-relative-directory (union str false)) + ;; -- exceptions + (debug-info-handler (-> (-> void))) + ;; libraries + (current-library-collections-paths + (case-> + ((listof str) -> void) + (-> (listof str)))) + (require-library-use-compiled (case-> (bool -> void) (-> bool))) + ;; parsing + (read-case-sensitive (case-> (-> bool) (bool -> void))) + (read-square-bracket-as-paren (case-> (-> bool) (bool -> void))) + (read-curly-brace-as-paren (case-> (-> bool) (bool -> void))) + (read-accept-box (case-> (-> bool) (bool -> void))) + (read-accept-type-symbol (case-> (-> bool) (bool -> void))) + (read-accept-compiled (case-> (-> bool) (bool -> void))) + (read-accept-bar-quote (case-> (-> bool) (bool -> void))) + (read-accept-graph (case-> (-> bool) (bool -> void))) + ;; printing + (print-graph (case-> (-> bool) (bool -> void))) + (print-struct (case-> (-> bool) (bool -> void))) + (print-box (case-> (-> bool) (bool -> void))) + + ;; -- parameter utilities + ;; We should arguably have a separate type for parameter procedures + (make-parameter (forall (x i) + (x optional (i -> x) + -> (optional i -> (union x void))))) + (parameter? (_ -> bool)) + (parameter-procedure=? (_ _ -> bool)) + + ;; -- parameterization utilities + (make-parameterization (parameterization -> parameterization)) + (current-parameterization + (case-> + (parameterization -> void) + (-> parameterization))) + (parameterization? (-> bool) (predicate parameterization)) + (in-parameterization (forall (param) + (parameterization + param + optional _ + -> param))) + (with-parameterization (parameterization (-> result) -> result)) + (with-new-parameterization ((-> result) -> result)) + (parameterization-branch-handler (-> parameterization)) + + ;; ---- custodians + (make-custodian (custodian -> custodian)) + (custodian-shutdown-all (custodian -> void)) + (custodian? (_ -> bool) (predicate custodian)) + (current-custodian (case-> + (-> custodian) + (custodian -> void))) + + ;; ---- namespaces + (make-namespace ((listof sym) *-> namespace)) + (namespace? (_ -> bool) (predicate namespace)) + (current-namespace (case-> + (-> namespace) + (namespace -> void))) + + ;; ------ System utilities + ;; ---- ports + ;; ---- filesystem utilities + ;; -- pathnames + (build-path (str (arglistof (union str sym)) *-> str)) + (absolute-path? (str -> bool)) + (relative-path? (str -> bool)) + (complete-path? (str -> bool)) + (path->complete-path (str -> str)) + (resolve-path (str -> str)) + (expand-path (str -> str)) + (normal-case-path (str -> str)) + + (split-path (str -> (union str sym false) + (union str sym) + bool)) + (find-executable-path (str str -> str)) + ;; -- directories + (current-directory (case-> + (str -> void) + (-> str))) + (current-drive (-> (union bool str))) + (directory-exists? (str -> bool)) + (make-directory (str -> bool)) + (delete-directory (str -> bool)) + (directory-list (optional str -> (listof str))) + (filesystem-root-list (-> (listof str))) + + ;; ---- networking + (tcp-listen (num optional num -> tcp-listener)) + (tcp-connect (str num ->* (mvalues (list iport oport)))) + (tcp-accept (tcp-listener ->* (mvalues (list iport oport)))) + (tcp-accept-ready? (tcp-listener -> bool)) + (tcp-close (tcp-listener -> void)) + (tcp-listener? (_ -> bool) (predicate tcp-listener)) + (tcp-port-send-waiting? (oport -> bool)) + + ;; ---- time + ;; -- real time + (current-seconds (-> num)) + ;(seconds->date (num -> (structure:date num num num num + ; num num num num bool))) + ;; -- machine time + (current-milliseconds(-> num)) + (current-process-milliseconds(-> num)) + (current-gc-milliseconds(-> num)) + ;; -- timing execution + (time-apply (forall (a) ((-> a) -> (list a num num)))) + + ;; ---- operating system processes + (system (str -> bool)) + (system* (str (listof str) *-> bool)) + (execute (str -> void)) + (execute* (str (listof str) *-> void)) + (process (str -> (list iport oport num iport (sym -> sym)))) + (process* (str (listof str) + *-> (list iport oport num iport (sym -> sym)))) + + + ;; ------ memory management + ;; ---- will executors + (make-will-executor (-> will-executor)) + (will-executor? (_ -> bool) (predicate will-executor)) + (register-will (forall (a) + (a (a ->* _) optional will-executor + -> void))) + (will-executor-try (will-executor -> void)) + (current-will-executor + (case-> (will-executor -> void) (-> will-executor))) + + ;; ---- garbage collection + (collect-garbage (-> void)) + (dump-memory-stats (-> void)) + + ;; ------ macros + ;; ---- expanding macros + (syntax? (_ -> bool)) + (macro? (_ -> bool)) + (id-macro? (_ -> bool)) + + ;; ------ support facilities + ;; ---- input parsing + (type-symbol? (_ -> bool) (predicate type-symbol)) + (string->type-symbol (str -> type-symbol)) + + + + + ;; -------------------------------------------------------------------- + (print (_ optional oport -> void)) + (make-pipe (->* (mvalues (list iport oport)))) + + ;; -------------------------------------------------------------------- + ;; MzScheme stand-alone definitions + (program str) + (argv (vec str)) + + )) + + + '(language-add-boot-file + (build-path + (or this-directory + (build-path + (collection-path "mrspidey") ; MATTHEW: got rid of plt-home + "Sba")) + "exn-hierarchy.ss")) + ) + + + + +;; ====================================================================== + +(define (init-MrEd-on-MzScheme!) + (language-add-boot-file "~/Spidey/wx/all.sig") + ) + +;; ====================================================================== + +(define (init-mzlib!) + + (constructor-alias! 'null 'nil) + + (add-default-primitives! + '( + (require-library (str -> void)) + (=? ((arg num (arg num (arglistof num))) *-> bool) ) + ( bool) ) + (>? ((arg num (arg num (arglistof num))) *-> bool) ) + (<=? ((arg num (arg num (arglistof num))) *-> bool) ) + (>=? ((arg num (arg num (arglistof num))) *-> bool) ) + (1+ (num -> num)) + (1- (num -> num)) + + (null nil) + (cons? (_ -> bool) (predicate cons)) + (gentemp (-> sym) ) + (bound? (sym -> bool)) + (flush-output-port (optional oport -> void)) + (real-time (-> num)) + + ;; --- file.ss + (build-absolute-path (str (arglistof (union str sym)) -> str)) + (build-relative-path (str (arglistof (union str sym)) -> str)) + (explode-path (str -> (listof str))) + (filename-extension (str -> str)) + (find-relative-path (str str -> str)) + (normalize-path (str optional str -> str)) + + ;; --- function.ss + (first (forall (a) ((cons a _) -> a))) + (second (forall (a) ((cons _ (cons a _)) -> a))) + (third (forall (a) ((cons _ (cons _ (cons a _))) -> a))) + (fourth (forall (a) ((cons _ (cons _ (cons _ (cons a _)))) -> a))) + (fifth (forall (a) ((cons _ (cons _ (cons _ (cons _ (cons a _))))) -> a))) + (sixth (forall (a) ((cons _ (cons _ (cons _ (cons _ (cons _ (cons a _)))))) -> a))) + (seventh (forall (a) ((cons _ (cons _ (cons _ (cons _ (cons _ (cons _ (cons a _))))))) -> a))) + (eighth (forall (a) ((cons _ (cons _ (cons _ (cons _ (cons _ (cons _ (cons _ (cons a _)))))))) -> a))) + + (build-list (forall (a) (num (num -> a) -> (listof a)))) + (build-string (num (num -> char) -> str)) + (build-vector (forall (a) (num (num -> a) -> (vec a)))) + (cons? (_ -> bool) (predicate cons)) + (compose (forall (x y z) ((x ->* y) (y *->* z) -> (x ->* z)))) + + (dynamic-disable-break (forall (v) ((-> v) -> v))) + (dynamic-wind/protect-break + (forall (v) ((-> _) (-> v) (-> _) -> v))) + + (foldl (case-> + (forall (a z) ((a z -> z) z (listof a) -> z)) + (forall (a b z) + ((a b z -> z) z (listof a) (listof b) -> z)) + (forall + (a b c z) + ((a b c z -> z) z (listof a) (listof b) (listof c) -> z)) + (forall + (x z) + (((arglistof x) *-> z) z (listof (arglistof x)) *-> z)))) + (foldr (case-> + (forall (a z) ((a z -> z) z (listof a) -> z)) + (forall (a b z) + ((a b z -> z) z (listof a) (listof b) -> z)) + (forall + (a b c z) + ((a b c z -> z) z (listof a) (listof b) (listof c) -> z)) + (forall + (x z) + (((arglistof x) *-> z) z (listof (arglistof x)) *-> z)))) + (ignore-errors (forall (x) ((-> x) -> (union x void)))) + (last-pair (forall (p l) + ( (MU l (union p (cons _ l))) -> p))) + (loop-until (forall (x) + (x (x -> _) (x -> x) (x -> _) -> void))) + + (identity (forall (x) (x -> x))) + (quicksort (forall (a) ((listof a) (a a -> _) -> (listof a)))) + + ;; --- pretty.ss + (pretty-print (_ optional oport + optional num + optional bool + optional bool + optional num + -> void)) + (pretty-print-columns (optional num -> (union num void))) + (pretty-print-depth (optional num -> (union num void))) + ;; NOT pretty-print-handler + + ;; --- strings.ss + ;; NOT eval-string + (expr->string (_ -> str)) + (newline-string (-> str)) + (read-string (str -> sexp)) + (read-string-all (str -> (listof sexp))) + ;;(regexp-match ((union str regexp) str -> bool)) + (string-lowercase! (str -> str)) + (string-uppercase! (str -> str)) + + (match:error (_ optional _ -> empty)) +; (match:andmap (case-> +; (forall (a r) +; ((a -> r) (listof a) -> (union true r))) +; (forall (a b r) +; ((a b -> r) (listof a) (listof b) +; -> (union true r))) +; (forall (a b c r) +; ((a b c -> r) (listof a) (listof b) (listof c) +; -> (union true r))) +; (forall (x r) +; (((arglistof x) *-> r) (arglistof (listof x)) +; *-> (union true r))))) +; + ))) + + +(define (init-zmath!) + ;; --- zmath.ss + (add-default-primitives! + `( + (conjugate (num -> num)) + (cosh (num -> num)) + (make-rectangular (num num -> num) ) + (sinh (num -> num)) + (zabs (num -> num)) + (zacos (num -> num)) + (zasin (num -> num)) + (zatan (num -> num)) + (zcos (num -> num)) + (zexp (num -> num)) + (zlog (num -> num)) + (zsin (num -> num)) + (zsqrt (num -> num)) + (ztan (num -> num)) + (pi 3.14159) + (e 2.71828) + ))) + +;; ====================================================================== + +(define (init-DrScheme-on-MzScheme!) + + (add-constructor! '2vec #t) + (add-constructor! 'viewport) + (add-constructor! 'posn #t #t) + (add-constructor! 'rgb #t #t #t) + (add-constructor! 'mouse-click) + + (add-constructor! 'module #f) + + (add-default-primitives! + `( + (match:error (_ -> empty)) + + (make-rs:module (forall (x) (x -> (module x)))) + + ;; Can't do anything smarter, even though b must be a list + ;; Need to implement * + ;(cons (forall (a b) (a (union b nil (cons _ _))-> (cons a b)))) + ;(set-cdr! (forall (b) ((cons _ (! b)) b -> void))) + (atom? (_ -> bool) + (predicate* (#f cons) (#t cons))) + (build-list (forall (a) (num (num -> a) -> (listof a)))) + (build-string (num (num -> char) -> str)) + + ;; Vectors + (build-vector (forall (a) (num (num -> a) -> (vec a)))) + (tabulate (forall (a) (num (num -> a) -> (vec a)))) + (foreach! (forall + (v a b) + ((union v (vec a) (vec (! b))) (a num -> b) -> v))) + (2vector (forall (a) ((listof (listof a)) -> (2vec a)))) + (2make-vector (num num -> (2vec void))) + (2vector-init (forall (a) (num num (num num -> a) -> (2vec a)))) + (2vector-ref (forall (a) ((2vec a) num num -> a))) + (2vector-set! (forall (a) ((2vec (! a)) num num a -> void))) + (2foreach! (forall + (v a b) + ((union v (2vec a) (2vec (! b))) (a num num -> b) -> v))) + (2vector-print (forall (a) ((2vec a) ((vec a) -> void) -> void))) + + ;; -------------------- + ;; SIXlib + (open-viewport (str num optional num optional num -> viewport)) + (open-pixmap (str num optional num optional num -> viewport)) + (close-viewport (viewport -> void)) + + (make-posn (forall (x y) + ((union num x) (union num y) -> (posn x y)))) + (posn-x (forall (x) ((posn x _) -> x))) + (posn-y (forall (y) ((posn _ y) -> y))) + (posn? ((union (posn _ _) _) -> bool) (predicate posn)) + + (get-pixel (viewport -> ((posn _ _) -> num))) + + (make-rgb (forall (r g b) + ((union num r) (union num g) (union num b) + -> (rgb r g b)))) + (rgb-red (forall (r) ((rgb r _ _) -> r))) + (rgb-green (forall (g) ((rgb _ g _) -> g))) + (rgb-blue (forall (b) ((rgb _ _ b) -> b))) + (rgb? ((union (rgb _ _ _) _) -> bool) + (predicate rgb)) + (change-color (num (rgb _ _ _) -> void)) + (default-display-is-color? (-> bool)) + + ;; --- Drawing ops + (draw-viewport (viewport -> (optional num -> void))) + (draw-pixel (viewport -> ((posn _ _) optional num -> void))) + (draw-line (viewport -> + ((posn _ _) (posn _ _) optional num -> void))) + (draw-string (viewport -> ((posn _ _) str optional num -> void))) + (draw-pixmap (viewport -> (str (posn _ _) -> void))) + + (clear-viewport (viewport -> (-> void))) + (clear-pixel (viewport -> ((posn _ _) -> void))) + (clear-line (viewport -> ((posn _ _) (posn _ _) -> void))) + (clear-string (viewport -> ((posn _ _) str -> void))) + (clear-pixmap (viewport -> (str (posn _ _) -> void))) + + (flip-viewport (viewport -> (-> void))) + (flip-pixel (viewport -> ((posn _ _) -> void))) + (flip-line (viewport -> ((posn _ _) (posn _ _) -> void))) + (flip-string (viewport -> ((posn _ _) str -> void))) + (flip-pixmap (viewport -> (str (posn _ _) -> void))) + + ;; --- Mouse ops + (get-mouse-click (viewport -> mouse-click)) + (ready-mouse-click (viewport -> (union false mouse-click))) + (ready-mouse-release (viewport -> (union false mouse-click))) + (query-mouse-posn (viewport -> (union false (posn num num)))) + (mouse-click-posn (mouse-click -> (posn num num))) + (left-mouse-click? (mouse-click -> bool)) + (middle-mouse-click? (mouse-click -> bool)) + (right-mouse-click? (mouse-click -> bool)) + (viewport-flush-input (viewport -> void)) + + ;; -------------------- + ;; Module values + + ;; Miscellaneous + (rs:major-version num) + (rs:minor-version num) + (rs:date str) + (rs:banner-lines (str -> void)) + ))) + +;; ---------------------------------------------------------------------- + +(define (init-smart-numops!) + + (st:constants #t) + + (add-constructor! 'apply+ #f) + (add-constructor! 'apply- #f) + (add-constructor! 'apply* #f) + (add-constructor! 'apply/ #f) + + ;; The following are binary ops + ;; they return the elements of the first set that satisfy the + ;; appropriate relation wrt some element of the second set + (add-constructor! '= #f #f) + (add-constructor! 'not= #f #f) + (add-constructor! '< #f #f) + (add-constructor! '<= #f #f) + (add-constructor! '> #f #f) + (add-constructor! '>= #f #f) + + (record-super-constructor! 'num 'apply+) + (record-super-constructor! 'num 'apply-) + (record-super-constructor! 'num 'apply*) + (record-super-constructor! 'num 'apply/) + + (record-super-constructor! 'num '=) + (record-super-constructor! 'num 'not=) + (record-super-constructor! 'num '<) + (record-super-constructor! 'num '<=) + (record-super-constructor! 'num '>) + (record-super-constructor! 'num '>=) + + (install-output-type-expander! + (match-lambda + [('apply+ ('list . t*)) `(+ ,@t*)] + [('apply* ('list . t*)) `(* ,@t*)] + [('apply- ('list . t*)) `(- ,@t*)] + [('apply/ ('list . t*)) `(/ ,@t*)] + [('+ t 1) `(add1 ,t)] + [('- t 1) `(sub1 ,t)] + [type type])) + + (let* ([bin-pred + (lambda (op) (lambda (x y) + '(pretty-debug + `(make-constructed-Tvar ,op + ,(Tvar-name x) + ,(Tvar-name y))) + (make-constructed-Tvar op x y)))] + [bin-pred-r + (lambda (op) (lambda (x y) ((bin-pred op) y x)))] + [comparator-helper-fn + (lambda (op reverse-op negation-op negation-reverse-op) + ;; eg < > >= <= + (lambda (before after Tvar bool) + '(printf "before ~s after ~s Tvar ~s~n" + (map Tvar-name before) + (map Tvar-name after) + (Tvar-name Tvar)) + (if bool + (foldl (bin-pred-r op) + (foldl (bin-pred-r reverse-op) Tvar before) + after) + (match (list before after) + [((arg) ()) ((bin-pred negation-reverse-op) Tvar arg)] + [(() (arg)) ((bin-pred negation-op) Tvar arg)] + [_ Tvar]))))]) + + (add-default-primitives! + `( + ;; numbers + (+ (forall (a) ((union a (arglistof num)) *-> (apply+ a)))) + (* (forall (a) ((union a (arglistof num)) *-> (apply* a)))) + (- (forall (a) ((union a (arg num (arglistof num))) + *-> (apply- a)))) + (/ (forall (a) + ((union a (arg num (arglistof num))) + *-> (apply/ a)))) + (add1 (forall (a) ((union a num) -> (apply+ (list a 1))))) + (sub1 (forall (a) ((union a num) -> (apply- (list a 1))))) + + (= ((arg num (arg num (arglistof num))) *-> bool) + (predicate-fn + ,(comparator-helper-fn '= '= 'not= 'not=))) + (< ((arg num (arg num (arglistof num))) *-> bool) + (predicate-fn + ,(comparator-helper-fn '< '> '>= '<=))) + (> ((arg num (arg num (arglistof num))) *-> bool) + (predicate-fn + ,(comparator-helper-fn '> '< '<= '>=))) + (<= ((arg num (arg num (arglistof num))) *-> bool) + (predicate-fn + ,(comparator-helper-fn '<= '>= '> '<))) + (>= ((arg num (arg num (arglistof num))) *-> bool) + (predicate-fn + ,(comparator-helper-fn '>= '<= '< '>))) + (zero? (num -> bool) + (predicate-fn + ,(lambda (before after Tvar bool) + (let ([Tvar-zero (mk-Tvar 'zero?)]) + (new-AV! Tvar-zero (traverse-const-exact 0)) + (if bool + Tvar-zero + (make-constructed-Tvar 'not= Tvar Tvar-zero)))))) + + )))) + +;; ---------------------------------------------------------------------- + +(define (init-vectors-w/-length) + + (add-constructor! 'vect #t #f) + (add-default-primitives! + `( + (make-vector (case-> + (forall (n) ((union num n) -> (vect void n))) + (forall (a n) ((union num n) a -> (vect a n))) + (forall (a n) ((union num n) optional a -> (vect (union a void) n))))) + (vector (forall (a) ((arglistof a) *-> (vect a num)))) + (vector-length (forall (a n) ((vect a n) -> n))) + (vector-ref (forall (a) ((vect a _) num -> a))) + (vector-set! (forall (a) ((vect (! a) _) num a -> void))) + (vector->list (forall (a) ((vect a _) -> (listof a)))) + (list->vector (forall (a) ((listof a) -> (vect a num)))) + (vector-fill! (forall (a) ((vect (! a) _) a -> void))) + (vector? (_ -> bool) (predicate vect)) + (build-vector (forall (a) ((union num n) (num -> a) -> (vect a n)))) + (tabulate (forall (a) ((union num n) (num -> a) -> (vect a n)))) + (foreach! (forall + (v a b) + ((union v (vect a _) (vect (! b) _)) (a num -> b) + -> v))) + (2vector-print (forall (a) ((2vec a) ((vect a _) -> void) -> void))) + + ))) diff --git a/collects/mrspidey/Sba/languages-abstract.ss b/collects/mrspidey/Sba/languages-abstract.ss new file mode 100644 index 0000000..f856a83 --- /dev/null +++ b/collects/mrspidey/Sba/languages-abstract.ss @@ -0,0 +1,15 @@ +;; ====================================================================== + +(define (init-R4RS!) + ;; Also extends it with void + + (apply add-default-constructor! (type: sym) (type: (listof bool))) + (add-default-primitive! (type: (list sym sexp)))) + +;; ====================================================================== + +(define (init-Chez-on-R4RS!) (void)) +(define (init-Rice-on-Chez!) (void)) +(define (init-MzScheme-on-R4RS!) (void)) +(define (init-DrScheme-on-MzScheme!) (void)) +(define (init-smart-numops!) (void)) diff --git a/collects/mrspidey/Sba/ldexpand.ss b/collects/mrspidey/Sba/ldexpand.ss new file mode 100644 index 0000000..c7f1b15 --- /dev/null +++ b/collects/mrspidey/Sba/ldexpand.ss @@ -0,0 +1,371 @@ +; ldexpand.ss - loads and macro expands source files +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define (open-code-file filename) + (let ([filename (normalize-path filename)] + [cd (current-directory)]) + (dynamic-let + ([current-directory (path-only filename)]) + (unless (file-exists? filename) + (mrspidey:error (format "Can't open file ~s, current directory ~s" + filename (current-directory)))) + (let* ( [p (open-input-file filename 'text)] + [p (system-expand-if-necy p)]) + p)))) + +(define (zodiac:read* port filename) + (let* ( [default-loc (zodiac:make-location 1 1 0 filename)] + + [reader (if (st:fake-reader) + (fake-zodiac-reader port default-loc) + (zodiac:read port default-loc))] + [sexps + (recur loop () + (let* ([expr (reader)]) + (if (or (zodiac:eof? expr) (eof-object? expr)) + '() + (begin + (when (zodiac:zodiac? expr) + (mrspidey:zprogress "Reading" + (zodiac:zodiac-start expr))) + (cons expr (loop))))))]) + (unless (null? sexps) + (mrspidey:zprogress "Reading" (zodiac:zodiac-finish (rac sexps)))) + (close-input-port port) + (when debugging-front + (printf "~n--Loaded file---------------------~n") + (for-each (lambda (sexp) (pretty-print (zodiac:stripper sexp))) sexps) + (printf "----------------------------------~n")) + sexps)) + +(define mrspidey:zprogress + (let ( [cur-phase '()] + [cur-line -100] + [cur-file ""]) + (lambda (phase loc) + (let ( [file (zodiac:location-file loc)] + [line (zodiac:location-line loc)]) + (unless (and + (equal? file cur-file) + (eq? phase cur-phase) + ;;(>= line cur-line) + (< line (+ cur-line 10))) + (set! cur-phase phase) + (set! cur-line line) + (set! cur-file file) + (mrspidey:progress + (format "~a ~a: " + (padr phase 10) + (file-name-from-path file)) + line)))))) + +; ---------------------------------------------------------------------- + +(define fake-zodiac-reader + (case-lambda + [(p) (fake-zodiac-reader p (zodiac:make-location 1 1 0 "filename"))] + [(p loc) + (lambda () + (let ([x (read p)]) + (recur loop ([x x]) + (match x + [(? string?) (zodiac:make-string loc loc loc x)] + [(? boolean?) (zodiac:make-boolean loc loc loc x)] + [(? number?) (zodiac:make-number loc loc loc x)] + [(? symbol?) (zodiac:make-symbol loc loc loc x x x)] + [(? char?) (zodiac:make-char loc loc loc x)] + [(? vector?) (zodiac:make-vector loc loc loc + (map loop (vector->list x)) + (vector-length x))] + [(? list?) (zodiac:make-list loc loc loc + (map loop x) + (length x) + 'marks)] + [(? pair?) (zodiac:make-improper-list + loc loc loc + (recur loop2 ([x x]) + (match x + [(a . d) (cons (loop a) (loop2 d))] + [r (list (loop r))])) + 0 + 'period 'marks)] + [_ (if (eof-object? x) + (zodiac:make-eof loc) + (mrspidey:internal-error + 'fake-zodiac-reader + "Bad object ~s" x))]))))])) + +; ---------------------------------------------------------------------- + +(define (expand-zexp->port exp) + (let* ( [exp (zodiac:stripper exp)] + [s (format "~s" exp)] + [p (open-input-string s)] + [p (system-expand-if-necy p)]) + p)) + +; ---------------------------------------------------------------------- + +(define (system-expand-if-necy p) + (if (st:system-expand) + (system-expand-port p) + p)) + +(define system-macros + '(;; --- r4rs + case cond do recur rec let* letrec let and or define + ;; --- Chez things + parameterize fluid-let case-lambda let-values #%let-values + ;; --- Rice things + match match-lambda match-lambda* match-let match-let* + ;; --- My things + define-module global assert for + ;; --- Misc + defmacro + ;; Units w/ signatures + define-signature + unit-with-signature unit/sig + compound-unit/sig compound-unit-with-signature + invoke-unit/sig invoke-unit-with-signature + unit->unit/sig + )) + + +(define (expander-eval e) + (parameterize ([current-namespace expander-namespace]) + (eval e))) +(when (st:system-expand) + (expander-eval '(load "/home/cormac/Spidey/Code/Sba/expander-boot.ss"))) +(define (my-expand e) (expander-eval `(expand-defmacro ',e))) +(define (my-expand-once e) (expander-eval `(expand-defmacro-once ',e))) + +(define unchanged-list + '( define-constructor + define-type + primitive: + type:)) + +(define system-expanded-exp (void)) + +(define (system-expand-exp exp) + (set! system-expanded-exp exp) + (match exp + [((? (lambda (x) (memq x unchanged-list))) . _) + exp] + [_ (match (my-expand exp) + [(and e ((or '#%define-expansion-time '#%define-macro) . _)) + (expander-eval e) + '(void)] + [e e])])) + +(define (remove-signature-stuff e) + (recur loop ([e e]) + (match e + [('#%make-unit-with-signature x _ _) (loop x)] + [('#%verify-signed-compound-sub-units . _) '(void)] + [('#%verify-linkage-signature-match . _) '(void)] + [('#%unit-with-signature-unit x) x] + [('#%invoke-open-unit expr name-specifier . imports) + `(#%invoke-unit ,(loop expr) ,@imports)] + [('#%invoke-open-unit expr) + `(#%invoke-unit ,(loop expr))] + [(('#%global-defined-value ('#%quote match:error)) . args) + '(error 'match "Match error")] + [(a . d) (cons (loop a) (loop d))] + [x x]))) + +(define (system-expand-port p) + (pretty-debug `(system-expand-port ,p ,(current-directory))) + (let* ([o (open-output-string)]) + (parameterize + ([pretty-print-depth #f]) + (recur loop ([p p]) + (let ([e (read p)]) + (printf ".") (flush-output) + (unless (eof-object? e) + (recur process ([e e]) + (match (system-expand-exp e) + [('#%begin . e*) + (for-each process e*)] + [e + (let* ([e (remove-signature-stuff e)]) + (match e + [((or 'load '#%load '#%load/cd 'load/cd) exp) + (let ([filename (normalize-path (expander-eval exp))]) + (unless (file-exists? filename) + (mrspidey:error (format "Can't load ~s" filename))) + (dynamic-let + ([current-directory + (if (memq (car e) '(load/cd #%load/cd)) + (path-only filename) + (current-directory))]) + (let* ([p (open-input-file filename 'text)]) + (printf "[File:~s " (file-name-from-path filename)) + (loop p) + (printf "done]") + (close-input-port p))))] + [('load-recent s) + (process `(load ,(string-append s ".ss")))] + [(or '(void) (? void?)) (void)] + [e (pretty-print (strip-hash-percent e) o)]))])) + (loop p))))) + (begin0 + (open-input-string (get-output-string o)) + (close-output-port o) + (close-input-port p)))) + +(define (strip-hash-percent expr) + (recur loop ([expr expr]) + (match expr + [('|#primitive| prim) prim] + [(a . d) (cons (loop a) (loop d))] + [(? symbol? x) + (let* ([s (symbol->string x)] + [l (string-length s)]) + (if (and (> l 2) + (string=? (substring s 0 2) "#%")) + (string->symbol (substring s 2 l)) + x))] + [x x]))) + +; ---------------------------------------------------------------------- + +(define expand-file + (case-lambda + [(infile) + (let ([infile (normalize-path infile)]) + (let ([outfile (regexp-replace ".ss$" infile ".expanded")]) + (when (eq? outfile infile) + (error 'expand-file "Bad suffix on ~s" infile)) + (expand-file infile outfile)))] + [(infile outfile) + (when (file-exists? outfile) (delete-file outfile)) + (dynamic-let ( [st:system-expand #t] + [current-directory (path-only (normalize-path infile))]) + (let* ( [p (open-input-file infile 'text)] + [p2 (system-expand-if-necy p)] + [p3 (open-output-file outfile 'text)]) + (printf "~nCopying:") + (recur loop () + (let ([e (read p2)]) + (unless (eof-object? e) + (pretty-print e p3) + (printf ".") (flush-output) + (loop)))) + (newline) + (close-input-port p2) + (close-output-port p3) + outfile))])) + +; ---------------------------------------------------------------------- + +(define file-time-cache '()) + +(define (clear-file-time-cache!) + (set! file-time-cache '())) + +(define (extend-file-time-cache! file n) + (set! file-time-cache (cons (cons file n) file-time-cache))) + +(define (file-time file) + (or (lookup-or-#f file-time-cache file) + (let* ([n (file-modify-seconds file)]) + (unless (number? n) + (error 'file-time "file-modify-seconds failed on ~a" file)) + (extend-file-time-cache! file n) + n))) + +(define (zodiac-time x) + (let* ([start (zodiac:zodiac-start x)] + [file (zodiac:location-file start)]) + (file-time file))) + +(define (zodiac-time* x) + ;; ## should be either current time, or file time of any imported file + ;; is in right directory + (let* ([t (zodiac-time x)] + [fn (lambda (exp cl-fn) + (match exp + [($ zodiac:reference-unit-form _ _ _ _ file cd) + (let*-vals + ( [_ (unless (zodiac:string? file) + (mrspidey:error + (format "reference-unit requires a string argument, given ~s" file)))] + [file (zodiac:read-object file)] + [file (if (relative-path? file) + (build-path cd file) + file)]) + (when (file-exists? file) + (pretty-debug `(zodiac:time* includes ,file)) + (set! t (max t (file-time file)))) + #f)] + [_ #f]))]) + ((zodiac:compat fn) x) + t)) + +;; ====================================================================== + +(define attributes #f) +(define expander-namespace #f) + +(define (init-expand!) + (set! attributes (zodiac:make-attributes)) + (set! expander-namespace (make-expander-namespace))) + +;; ---------------------------------------------------------------------- + +(define g:prog #f) + +(define (my-scheme-expand-program defs) + ;;(printf "my-scheme-expand-program cd=~s~n" (cd)) + (let* ( [p (make-parameterization)] + [_ (with-parameterization p + (lambda () + (current-namespace + expander-namespace + ;(make-expander-namespace) + ) + (reference-library "core.ss") + (reference-library "macro.ss") + '(reference + (begin-elaboration-time + (build-path + mred:plt-home-directory "mred" "system" "sig.ss"))) + '(eval '(unit/sig () (import mred^) 1)) + ;;(printf "np=~s~n" normalize-path) + ))] + ; [defs2 (zodiac:expand-program + ; defs attributes zodiac:mrspidey-vocabulary p)] + [defs2 (call/nal + zodiac:expand-program/nal + zodiac:expand-program + (expressions: defs) + (attributes: attributes) + (vocabulary: zodiac:mrspidey-vocabulary))] + ; (parameterization: p))] + [defs2 (zodiac:inline-begins defs2)] + [_ (zodiac:initialize-mutated defs2)] + [free (zodiac:free-vars-defs defs2)]) + (set! g:prog defs2) + ;;(pretty-print defs2) + '(when debugging + (pretty-print (map zodiac:stripper defs2))) + (values defs2 free))) + +;; ---------------------------------------------------------------------- + diff --git a/collects/mrspidey/Sba/lib/env.ss b/collects/mrspidey/Sba/lib/env.ss new file mode 100644 index 0000000..0efd242 --- /dev/null +++ b/collects/mrspidey/Sba/lib/env.ss @@ -0,0 +1,69 @@ +;; env.ss +;; ---------------------------------------------------------------------- +;; Environments + + (define empty-env '()) + + (define lookup-or-fail + (lambda (env x fail-thunk) + (match (assq x env) + [#f (fail-thunk)] + [(_ . b) b]))) + + (define lookup-or-#f + (lambda (env x) + (match (assq x env) + [#f #f] + [(_ . b) b]))) + + (define lookup + (lambda (env x) + (match (assq x env) + [#f (mrspidey:internal-error 'lookup "no binding for ~a" x)] + [(_ . b) b]))) + + (define bound-in-env? + (lambda (env x) + (match (assq x env) + [#f #f] + [_ #t]))) + + (define extend-env + (lambda (env x v) + (cons (cons x v) env))) + + (define extend-env* + (lambda (env xs vs) + (append (map cons xs vs) env))) + + (define join-env + (lambda (env newenv) + (append newenv env))) + + (define bang-env! + (lambda (env x nu-v) + (let ([binding (assq x env)]) + (if binding + (set-cdr! binding nu-v) + (mrspidey:internal-error 'lookup "no binding for ~a" x))))) + +(define (env:change-binding env x f err) + (recur loop ([env env]) + (if (null? env) + (err) + (if (eq? x (caar env)) + (cons (cons x (f (cdar env))) (cdr env)) + (cons (car env) (loop (cdr env))))))) + +(define (env:remove env x) + (let* ([bind #f] + [env + (recur loop ([env env]) + (if (null? env) + '() + (if (eq? x (caar env)) + (begin + (set! bind (cdar env)) + (cdr env)) + (cons (car env) (loop (cdr env))))))]) + (values bind env))) diff --git a/collects/mrspidey/Sba/lib/lib-list.ss b/collects/mrspidey/Sba/lib/lib-list.ss new file mode 100644 index 0000000..0288803 --- /dev/null +++ b/collects/mrspidey/Sba/lib/lib-list.ss @@ -0,0 +1,247 @@ +;; library-list.ss +;; ---------------------------------------------------------------------- + +;; map from left to right +(define mapLR + (lambda (f l) + (match l + [() '()] + [(x . y) (let ([v (f x)]) (cons v (mapLR f y)))] + [l (error 'mapLR "Bad list ~s" l)]))) + +;; map from right to left +(define mapRL + (lambda (f l) + (match l + [() '()] + [(x . y) (let ([v (mapRL f y)]) (cons (f x) v))]))) + +(define foldl-with-n + (lambda (f i l) + (recur loop ([l l][acc i][n 0]) + (match l + [() acc] + [(x . y) (loop y (f x n acc) (add1 n))])))) + +;; fold for a 2-argument function +;; right operand of f is accumulator +(define foldr2 + (lambda (f i l1 l2) + (recur loop ([l1 l1][l2 l2]) + (match (list l1 l2) + [(() ()) i] + [((x1 . y1) (x2 . y2)) (f x1 x2 (loop y1 y2))])))) + +;; filter elements out of a list by a predicate +(define filter + (lambda (p l) + (match l + [() '()] + [(x . y) (if (p x) (cons x (filter p y)) (filter p y))]))) + +;; filter and map left to right +(define filter-map + (lambda (p l) + (match l + [() '()] + [(x . y) + (match (p x) + [#f (filter-map p y)] + [x (cons x (filter-map p y))])]))) + +;; filter and map left to right, and return (filtered-list . unfiltered) + +(define filter-map-split + (lambda (p l) + (recur loop ([done-filtered '()][done-unfiltered '()][l l]) + (match l + [() (values done-filtered done-unfiltered)] + [(x . y) + (match (p x) + [#f (loop done-filtered (cons x done-unfiltered) y)] + [x (loop (cons x done-filtered) done-unfiltered y)])])))) + +;; last element of a list +(define rac + (lambda (l) + (match l + [(last) last] + [(_ . rest) (rac rest)]))) + +;; all but the last element of a list +(define rdc + (lambda (l) + (match l + [(_) '()] + [(x . rest) (cons x (rdc rest))]))) + +;; map left to right over a list, but also pass f a 0-based index +(define map-with-n + (lambda (f l) + (recur loop ([l l][n 0]) + (match l + [() '()] + [(x . y) (let ([v (f x n)]) (cons v (loop y (+ 1 n))))] + [l (error 'map-with-n "Bad list ~s" l)])))) + +;; for-each, but also pass f a 0-based index +(define for-each-with-n + (lambda (f l) + (recur loop ([l l][n 0]) + (match l + [() '()] + [(x . y) (f x n) (loop y (+ 1 n))])))) + +;; map on a (possibly improper) list +(define map-ilist + (lambda (f l) + (recur loop ([l l]) + (match l + [() '()] + [(x . y) (cons (f x) (loop y))] + [x (f x)])))) + +;; length on a (possibly improper) list +(define length-ilist + (match-lambda + [(x . y) (add1 (length-ilist y))] + [_ 0])) + +(define improper? + (match-lambda + [(x . y) (improper? y)] + [() #f] + [_ #t])) + +(define (flatten-ilist l) + (cond [(null? l) '()] + [(pair? l) (cons (car l) (flatten-ilist (cdr l)))] + [else (list l)])) + +;; map a binary function down 2 lists, left to right +(define map2 + (lambda (f a b) + (match (cons a b) + [(() . ()) + '()] + [((ax . ay) . (bx . by)) + (let ([v (f ax bx)]) (cons v (map2 f ay by)))] + [else (error 'map2 "lists differ in length")]))) + +; map over a list of lists + +(define (mapmap f ll) (map (lambda (l) (map f l)) ll)) + +;; interate a binary function down 2 lists, left to right +(define for-each2 + (lambda (f a b) + (match (cons a b) + [(() . ()) + (void)] + [((ax . ay) . (bx . by)) + (f ax bx) + (for-each2 f ay by)] + [else (error 'for-each2 "lists differ in length")]))) + +;; andmap for 2 lists +(define andmap2 + (lambda (f a b) + (match (cons a b) + [(() . ()) + #t] + [((ax) . (bx)) + (f ax bx)] + [((ax . ay) . (bx . by)) + (and (f ax bx) (andmap2 f ay by))] + [else (error 'andmap2 "lists differ in length")]))) + +;; andmap for 2 lists, fail on inequal lengths +(define andmap2len + (lambda (f a b) + (match (cons a b) + [(() . ()) + #t] + [((ax) . (bx)) + (f ax bx)] + [((ax . ay) . (bx . by)) + (and (f ax bx) (andmap2len f ay by))] + [else #f]))) +;(define andmap andmap2) + +;; ormap for 2 lists +(define ormap2 + (lambda (f a b) + (match (cons a b) + [(() . ()) + #f] + [((ax) . (bx)) + (f ax bx)] + [((ax . ay) . (bx . by)) + (or (f ax bx) (ormap2 f ay by))] + [else (error 'ormap2 "lists differ in length")]))) + +;; make a list containing n copies of e +(define list-n-copies + (lambda (n e) + (if (zero? n) + '() + (cons e (list-n-copies (sub1 n) e))))) + +(define (count p l) + (recur loop ([c 0][l l]) + (cond + [(null? l) c] + [(p (car l)) (loop (add1 c) (cdr l))] + [else (loop c (cdr l))]))) + +(define (index l x) + (recur loop ([l l][i 0]) + (cond + [(null? l) #f] + [(eq? x (car l)) i] + [else (loop (cdr l) (add1 i))]))) + +(define (get-prefix l1 l2) + (if (eq? l1 l2) + '() + (cons (car l1) (get-prefix (cdr l1) l2)))) + +(define (mklist n) + (if (zero? n) + '() + (cons n (mklist (sub1 n))))) + +(define (nth l n) + (if (zero? n) + (car l) + (nth (cdr l) (sub1 n)))) + + +; Takes an atom and a list and returns the position of the atom in the list +(define list-pos + (lambda (a l) + (recur loop ([l l][i 0]) + (cond + [(null? l) #f] + [(eqv? a (car l)) i] + [else (loop (cdr l) (add1 i))])))) + +; Takes an atom and a list and returns the position of the atom in the list +; uses equal?, returns #f if no match +(define list-pos-equal + (lambda (a l) + (recur loop ([l l][n 0]) + (cond + [(null? l) #f] + [(equal? a (car l)) n] + [else (loop (cdr l) (add1 n))])))) + +;; Returns first element in set satisfying a predicate, or #f +(define (find p l) + (recur loop ([l l]) + (cond + [(null? l) #f] + [(p (car l)) (car l)] + [else (loop (cdr l))]))) + + diff --git a/collects/mrspidey/Sba/lib/lib-misc.ss b/collects/mrspidey/Sba/lib/lib-misc.ss new file mode 100644 index 0000000..737ede6 --- /dev/null +++ b/collects/mrspidey/Sba/lib/lib-misc.ss @@ -0,0 +1,150 @@ +; library-misc.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + + (define symbol-append + (lambda l + (string->symbol + (apply string-append (map (lambda (x) (#%format "~a" x)) l))))) + + (define (get-cpu-time str thunk) + (match-let + ([(t . r) (get&return-cpu-time thunk)]) + (printf "~a ~ss~n" str (/ t 1000.0)) + r)) + + (define (get&return-cpu-time thunk) + (let* ([s1 (- (current-process-milliseconds) (current-gc-milliseconds))] + [r (thunk)] + [s2 (- (current-process-milliseconds) (current-gc-milliseconds))] + [t (- s2 s1)]) + (cons t r))) + + (define (make-timer) (cons 0 0)) + (define (clear-timer! c) (set-car! c 0) (set-cdr! c 0)) + + (define (record-time timer thunk) + (match-let + ([(t . r) (get&return-cpu-time (lambda () (call-with-values thunk list)))]) + (set-car! timer (add1 (car timer))) + (set-cdr! timer (+ t (cdr timer))) + (apply #%values r))) + + (define (strip-string s c) + ;; Strips leading chars off s, up to and including c + (recur loop ([s (string->list s)]) + (cond + [(null? s) ""] + [(char=? (car s) c) (list->string (cdr s))] + [else (loop (cdr s))]))) + + ;; pad on left + (define padl + (lambda (arg n) + (let ((s (format "~a" arg))) + (recur loop ((s s)) + (if (< (string-length s) n) + (loop (string-append " " s)) + s))))) + + ;; pad on right + (define padr + (lambda (arg n) + (let ((s (format "~a" arg))) + (recur loop ((s s)) + (if (< (string-length s) n) + (loop (string-append s " ")) + s))))) + + (define chop-number + (lambda (x n) + (substring (format "~s00000000000000000000" x) 0 (- n 1)))) + + ;; Is the first string a substring of the second string? + ;; + (define substring? + (lambda (s1 s2) + (let ([l1 (string-length s1)][l2 (string-length s2)]) + (let loop ([i 0]) + (cond + [(>= (+ i l1) l2) #f] + [(string=? (substring s2 i (+ i l1)) s1) #t] + [else (loop (add1 i))]))))) + + ; Returns the part of the string after the last slash + ; + (define get-base-name + (lambda (filename) + (let ([len (string-length filename)]) + (let loop ([i 0][fname-start 0]) + (cond + [(= i len) (substring filename fname-start len)] + [(char=? (string-ref filename i) #\/) + (loop (add1 i) (add1 i))] + [else (loop (add1 i) fname-start)]))))) + + ; removes an object fro a list destructively using eqv? + ; +(define remv! + (lambda (obj l) + (let ([head l]) + (if (eqv? obj (car l)) + (if (pair? l) + (cdr l) + '()) + (let loop ([l l]) + (cond + [(null? l) head] + [(null? (cdr l)) head] + [(eqv? obj (cadr l)) + (if (pair? (cdr l)) + (set-cdr! l (cddr l)) + (set-cdr! l '())) + head] + [ else (loop (cdr l))])))))) + + ; takes a string, a position (i) and a char and resturns a substring of the characters + ; from the position to the char + ; +(define (char-find str i char) + (apply string + (let loop ([i i]) + (if (< i (string-length str)) + (let ([c (string-ref str i)]) + (if (char=? c char) + '() + (cons c (loop (add1 i))))) + '())))) + ;; + +(define (file-newer f1 f2) + (let ([s1 (file-modify-seconds f1)] + [s2 (file-modify-seconds f2)]) + (and (number? s1) + (number? s2) + (> s1 s2)))) + + +;; curried eq? + +(define eqc? + (lambda (x) + (lambda (y) + (eq? x y)))) + +;; ---------------------------------------------------------------------- + diff --git a/collects/mrspidey/Sba/lib/lib-para.ss b/collects/mrspidey/Sba/lib/lib-para.ss new file mode 100644 index 0000000..9a180f8 --- /dev/null +++ b/collects/mrspidey/Sba/lib/lib-para.ss @@ -0,0 +1,71 @@ +;; library-paras.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ---------------------------------------------------------------------- + +(define make-parameter-list + (case-lambda + [(default list-opt) + (make-parameter-list default list-opt + (lambda (x) (void)) + (lambda (x) #f))] + [(default list-opt call) + (make-parameter-list default list-opt call + (lambda (x) #f))] + [(default list-opt call also-ok?) + (let* ([list-opt + (map + (match-lambda + [(tag (? string? name) (? string? help)) (list tag name help)] + [(tag (? string? name)) (list tag name "")] + [(or (tag) (tag "") tag) (list tag (format "~a" tag) "")]) + list-opt)] + [list-tag (map car list-opt)]) + ;(assert (memq default list-tag)) + (let ([current default]) + (call current) + (match-lambda* + [() current] + [('?) list-opt] + [(x) + (unless (or (member x list-tag) (also-ok? x)) + (error + 'parameter + "Parameter argument ~s is not one of ~s" x list-tag)) + (set! current x) + (call current)])))])) + +(define (make-parameter-boolean x) + (make-parameter-list x + (list + (list #f "Off" "") + (list #t "On" "")))) + +'(define (make-parameter-integer x) + (make-parameter x + (lambda (x) + (unless (integer? x) + (error 'parameter "Must be an integer")) + x))) + +(define (make-parameter-integer x) + (unless (integer? x) (error 'parameter "Must be an integer")) + (case-lambda + [() x] + [(y) + (unless (integer? y) (error 'parameter "Must be an integer")) + (set! x y)])) diff --git a/collects/mrspidey/Sba/lib/lib-set.ss b/collects/mrspidey/Sba/lib/lib-set.ss new file mode 100644 index 0000000..f2ba51b --- /dev/null +++ b/collects/mrspidey/Sba/lib/lib-set.ss @@ -0,0 +1,111 @@ +;; library-set.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; +;; Set operations implemented by lists. +;; Identity of elements is based on eq?. +;; These should probably be sped up some day. +;; ---------------------------------------------------------------------- + + (define empty-set '()) + + (define empty-set? null?) + + ;; construct a set + (define set + (lambda l + (list->set l))) + + ;; construct a set from a list by removing duplicates + (define list->set + (match-lambda + [() '()] + [(x . y) (if (memq x y) + (list->set y) + (cons x (list->set y)))])) + + (define list->set-equal? + (match-lambda + [() '()] + [(x . y) (if (member x y) + (list->set y) + (cons x (list->set y)))])) + + ;; test for membership + (define element-of? + (lambda (x set) + (and (memq x set) #t))) + + (define (set-add x set) + (if (memq x set) set (cons x set))) + + (define cardinality length) + + ;; does s2 contain s1? + (define set<= + (lambda (a b) + (and (andmap (lambda (x) (memq x b)) a) #t))) + + ;; are two sets equal? (mutually containing) + (define set-eq? + (lambda (a b) + (and (= (cardinality a) (cardinality b)) (set<= a b)))) + + ;; unite two sets + (define union2 + (lambda (a b) + (if (null? b) + a + (foldr (lambda (x b) + (if (memq x b) + b + (cons x b))) + b + a)))) + + ;; unite any number of sets + (define union + (lambda l + (foldr union2 '() l))) + + (define setdiff2 + (lambda (a b) + (if (or (null? a) (null? b)) + a + (if (memq (car a) b) + (setdiff2 (cdr a) b) + (cons (car a) (setdiff2 (cdr a) b)))))) + + (define setdiff + (lambda l + (if (null? l) + '() + (setdiff2 (car l) (foldr union2 '() (cdr l)))))) + + (define intersect2 + (lambda (a b) + (cond [(or (null? a) (null? b)) '()] + [(memq (car b) a) (cons (car b) (intersect2 a (cdr b)))] + [else (intersect2 a (cdr b))]))) + + (define intersect + (lambda l + (if (null? l) + '() + (foldl intersect2 (car l) l)))) + + diff --git a/collects/mrspidey/Sba/lib/lib-vec.ss b/collects/mrspidey/Sba/lib/lib-vec.ss new file mode 100644 index 0000000..4fb6232 --- /dev/null +++ b/collects/mrspidey/Sba/lib/lib-vec.ss @@ -0,0 +1,106 @@ +;; library-vec.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ---------------------------------------------------------------------- + +(define (vector-copy v) + (let* ( [l (vector-length v)] + [w (make-vector l)]) + (for i 0 l (vector-set! w i (vector-ref v i))) + w)) + +;; vector map +(define vector-map1 + (lambda (f v) + (let* ([l (vector-length v)] + [w (make-vector l)]) + (for i 0 l + (vector-set! w i (f (vector-ref v i)))) + w))) + +(define vector-map2 + (lambda (f v1 v2) + (let* ([l (vector-length v1)] + [w (make-vector l)]) + (assert (= l (vector-length v2))) + (for i 0 l + (vector-set! w i (f (vector-ref v1 i) (vector-ref v2 i)))) + w))) + +(define vector-map + (case-lambda + [(f v) (vector-map1 f v)] + [(f v1 v2) (vector-map2 f v1 v2)])) + +;; for-each over a vector, but also pass f a 0-based index +(define vector-for-each-with-n + (lambda (f v) + (for i 0 (vector-length v) + (f (vector-ref v i) i)))) + +(define vector-for-each + (case-lambda + [(f v) + (for i 0 (vector-length v) + (f (vector-ref v i)))] + [(f v1 v2) + (assert (= (vector-length v1) (vector-length v2)) 'vector-for-each) + (for i 0 (vector-length v1) + (f (vector-ref v1 i) (vector-ref v2 i)))])) + +(define (vector-andmap1 f v) + (let ([l (vector-length v)]) + (recur loop ([i 0]) + (or (= i l) + (and (f (vector-ref v i)) (loop (add1 i))))))) + +(define (vector-andmap2 f v1 v2) + (let ([l (vector-length v1)]) + (assert (= l (vector-length v2))) + (recur loop ([i 0]) + (or (= i l) + (and (f (vector-ref v1 i) (vector-ref v2 i)) + (loop (add1 i))))))) + +(define vector-andmap + (match-lambda* + [(f v) (vector-andmap1 f v)] + [(f v1 v2) (vector-andmap2 f v1 v2)])) + + +(define (vector-ormap1 f v) + (let ([l (vector-length v)]) + (recur loop ([i 0]) + (and (not (= i l)) + (or (f (vector-ref v i)) (loop (add1 i))))))) + +(define (vector-ormap2 f v1 v2) + (let ([l (vector-length v1)]) + (assert (= l (vector-length v2))) + (recur loop ([i 0]) + (and (not (= i l)) + (or (f (vector-ref v1 i) (vector-ref v2 i)) + (loop (add1 i))))))) + +(define vector-ormap + (match-lambda* + [(f v) (vector-ormap1 f v)] + [(f v1 v2) (vector-ormap2 f v1 v2)])) + + +(define (vector-zero! p) + (for i 0 (vector-length p) (vector-set! p i 'zerod!))) diff --git a/collects/mrspidey/Sba/lib/main.ss b/collects/mrspidey/Sba/lib/main.ss new file mode 100644 index 0000000..d88b96a --- /dev/null +++ b/collects/mrspidey/Sba/lib/main.ss @@ -0,0 +1,29 @@ +;; Sba/lib/main.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +;; elaboration-time context: +;; mrspidey signatures + +(unit/sig mrspidey:library^ + (import mrspidey:interaction^ mzlib:unprefixed-core^) + (include "lib-para.ss") + (include "lib-list.ss") + (include "lib-vec.ss") + (include "lib-set.ss") + (include "lib-misc.ss") + (include "env.ss")) diff --git a/collects/mrspidey/Sba/link.ss b/collects/mrspidey/Sba/link.ss new file mode 100644 index 0000000..b256129 --- /dev/null +++ b/collects/mrspidey/Sba/link.ss @@ -0,0 +1,132 @@ +;; link.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define mrspidey:sba@ + (compound-unit/sig + (import + (INTERACTION : mrspidey:interaction^) + (MZLIB : mzlib:unprefixed-core^) + (WX : wx^) + ) + (link + [CDL : + mrspidey:CDL^ + (mrspidey:CDL@ INTERACTION MZLIB WX)] + [ZODIAC : + mrspidey:zodiac^ + (mrspidey:zodiac@ CDL INTERACTION)] + [LOADEXPAND : + mrspidey:loadexpand^ + (mrspidey:loadexpand@ CDL INTERACTION LANGUAGES ZODIAC MZLIB)] + [HASH : + mrspidey:hash^ + (mrspidey:hash@ CDL INTERACTION MZLIB)] + [KERNEL : + mrspidey:kernel^ + (mrspidey:kernel@ CDL HASH KERNEL-AUX TEMPLATES)] + [MIN : + mrspidey:min^ + (mrspidey:all-min@ CDL INTERACTION KERNEL KERNEL-AUX + TEMPLATES MZLIB)] + [TEMPLATES : + mrspidey:templates^ + (mrspidey:templates@ CDL INTERACTION KERNEL)] + [KERNEL-AUX : + mrspidey:kernel-aux^ + (mrspidey:kernel-aux@ CDL INTERACTION KERNEL TEMPLATES ZODIAC)] + [ATYPE : + mrspidey:atype^ + (mrspidey:atype@ CDL INTERACTION KERNEL KERNEL-AUX + MIN TYPELANG TEMPLATES + TYPE-ENV SDL ATLUNIT MZLIB)] + [TYPELANG : + mrspidey:typelang^ + (mrspidey:typelang@ CDL INTERACTION KERNEL KERNEL-AUX + TEMPLATES TYPE-ENV ATYPE CONTAINED MZLIB ZODIAC)] + [CONTAINED : + mrspidey:contained^ + (mrspidey:contained@ CDL KERNEL SDL)] + [TYPE-ENV : + mrspidey:type-env^ + (mrspidey:type-env@ CDL INTERACTION KERNEL KERNEL-AUX + TEMPLATES MIN ATYPE ZODIAC)] + [SDL : + mrspidey:sdl^ + (mrspidey:sdl@ + CDL KERNEL MIN TYPELANG KERNEL-AUX TEMPLATES ATYPE + MZLIB)] + [LANGUAGES : + mrspidey:languages^ + (mrspidey:languages@ CDL INTERACTION KERNEL + TEMPLATES KERNEL-AUX + ATYPE TYPE-ENV TYPELANG ATENV LOADEXPAND TRAVERSE + MZLIB ZODIAC )] + [ATENV : + mrspidey:atenv^ + (mrspidey:atenv@ CDL INTERACTION KERNEL KERNEL-AUX ATYPE + ZODIAC MZLIB)] + [TRAVERSE : + mrspidey:traverse^ + (mrspidey:traverse@ CDL INTERACTION KERNEL MIN + LOADEXPAND + TEMPLATES KERNEL-AUX TYPELANG TYPE-ENV + LANGUAGES ATYPE ATLUNIT ATENV + ZODIAC MZLIB)] + [ATLUNIT : + mrspidey:atlunit^ + (mrspidey:atlunit@ CDL INTERACTION KERNEL KERNEL-AUX + MIN LOADEXPAND TYPE-ENV + TEMPLATES LANGUAGES ATYPE ATENV TRAVERSE + ZA ZODIAC MZLIB WX)] + [ZA : + mrspidey:za^ + (mrspidey:za@ CDL INTERACTION KERNEL TEMPLATES + TYPE-ENV TYPELANG ATYPE MZLIB)] + [PROGRAM : + mrspidey:program^ + (mrspidey:program@ CDL INTERACTION + KERNEL KERNEL-AUX TYPE-ENV + LOADEXPAND TRAVERSE + TEMPLATES ATENV ATYPE LANGUAGES + ZODIAC MZLIB)] + [CHECKS : + mrspidey:calc-checks^ + (mrspidey:calc-checks@ CDL INTERACTION LOADEXPAND + KERNEL KERNEL-AUX + TYPELANG TEMPLATES ATYPE SDL + ZODIAC MZLIB)] + [DRIVER : + mrspidey:driver^ + (mrspidey:driver@ CDL INTERACTION KERNEL + TEMPLATES TYPELANG TYPE-ENV ATYPE ATENV + PROGRAM CHECKS LANGUAGES ZODIAC)] + [HYPER : + mrspidey:hyper^ + (mrspidey:hyper@ CDL INTERACTION LOADEXPAND + PROGRAM CHECKS TEMPLATES KERNEL KERNEL-AUX ATYPE MZLIB)] + ) + (export + (open DRIVER) + (open CDL) + (open ATYPE) + (open HYPER) + (open KERNEL) + (open CHECKS) + (open LANGUAGES) + (unit ZODIAC zodiac)))) + diff --git a/collects/mrspidey/Sba/load.ss b/collects/mrspidey/Sba/load.ss new file mode 100644 index 0000000..97fa025 --- /dev/null +++ b/collects/mrspidey/Sba/load.ss @@ -0,0 +1,92 @@ +;; Sba/load.ss +;; Loads analysis, assumes zodiac, ../aux.ss, ../macros.ss already loaded +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(load-relative "sigs.ss") + +;; ---------------------------------------------------------------------- +;; Library stuff + +(load-relative (build-path "lib" "lib-para.ss")) +(load-relative (build-path "lib" "lib-list.ss")) +(load-relative (build-path "lib" "lib-vec.ss")) +(load-relative (build-path "lib" "lib-set.ss")) +(load-relative (build-path "lib" "lib-misc.ss")) +(load-relative (build-path "lib" "env.ss")) +(load-relative "config.ss") +(load-relative "debug.ss") + +;; ---------------------------------------------------------------------- +;; Extended Zodiac + +(load-relative "zod-extra.ss") +(invoke-open-unit/sig + mrspidey:zodiac@ + zodiac + mrspidey:CDL^ mrspidey:interaction^) + +;; --------------------------------------------------------------------- +;; Front End Stuff + +(load-relative "ldexpand.ss") + +;; ====================================================================== +;; Kernel stuff + +(load-relative "hash.ss") +(load-relative "kernel.ss") +(load-relative (build-path "min" "min.ss")) +(load-relative (build-path "min" "nonempty.ss")) +(load-relative (build-path "min" "min-live.ss")) +(load-relative (build-path "min" "livefewe.ss")) +(load-relative (build-path "min" "hopcroft.ss")) +(load-relative (build-path "min" "min-dfa.ss")) + +;; ---------------------------------------------------------------------- +;; top level stuff + +(load-relative "template.ss") +(load-relative "kern-aux.ss") +(load-relative "typelang.ss") +(load-relative "contain.ss") +(load-relative "type-env.ss") +(load-relative "sdl.ss") +(load-relative "language.ss") + +;; ---------------------------------------------------------------------- +;; Traversal + +(load-relative "atype.ss") +(load-relative "atenv.ss") +(load-relative "atlunit.ss") +(load-relative "traverse.ss") + +;; ---------------------------------------------------------------------- + +(load-relative "za.ss") +(load-relative "program.ss") +(load-relative "checks.ss") +(load-relative "driver.ss") +(load-relative "results.ss") + +;; ---------------------------------------------------------------------- + +(define (t) (st: "../test/t.ss")) +;(load "test-sba.ss") +;(load "devel.ss") +;(load "poly.ss") diff --git a/collects/mrspidey/Sba/loadu.ss b/collects/mrspidey/Sba/loadu.ss new file mode 100644 index 0000000..b049c39 --- /dev/null +++ b/collects/mrspidey/Sba/loadu.ss @@ -0,0 +1,489 @@ +;; sba-unit.ss +;; Defines all the units in SBA +;; ---------------------------------------------------------------------- +;; elaboration-time context: +;; sparams.ss Spidey/Code/macros.ss + +(load-relative "sigs.ss") + +;; ---------------------------------------------------------------------- +;; Library + +(define mrspidey:library@ + (reference (build-path "lib" "main.ss"))) + +;; ---------------------------------------------------------------------- + +(define mrspidey:config@ + (unit/sig mrspidey:config^ + (import mrspidey:library^ mzlib:unprefixed-core^ [wx : wx^]) + (include "config.ss"))) + +(define mrspidey:debugging@ + (unit/sig mrspidey:debugging^ + (import + mrspidey:library^ + mzlib:unprefixed-core^) + (include "debug.ss"))) + +(define mrspidey:CDL@ + (compound-unit/sig + (import + (I : mrspidey:interaction^) + (MZLIB : mzlib:unprefixed-core^) + (WX : wx^)) + (link + [L : + mrspidey:library^ + (mrspidey:library@ I MZLIB)] + [C : + mrspidey:config^ + (mrspidey:config@ L MZLIB WX)] + [D : + mrspidey:debugging^ + (mrspidey:debugging@ L MZLIB)]) + (export (open C) (open D) (open L)))) + +;; --------------------------------------------------------------------- +;; Front End Stuff + +(define mrspidey:loadexpand@ + (unit/sig mrspidey:loadexpand^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:languages^ + (zodiac : mrspidey:zodiac^) + mzlib:unprefixed-core^) + (include "ldexpand.ss"))) + +;; ====================================================================== +;; Kernel stuff + +(define mrspidey:hash@ + (unit/sig mrspidey:hash^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mzlib:unprefixed-core^) + (include "hash.ss"))) + +(define mrspidey:kernel@ + (unit/sig mrspidey:kernel^ + (import + mrspidey:CDL^ + mrspidey:hash^ + mrspidey:kernel-aux^ + mrspidey:templates^) + (include "kernel.ss"))) + +;; ---------------------------------------------------------------------- +;; Minimization + +(define mrspidey:min-live@ + (unit/sig + mrspidey:min-live^ + (import + mrspidey:CDL^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:min^ + mrspidey:templates^) + (include (begin-elaboration-time (build-path "min" "min-live.ss"))))) + +(define mrspidey:find-nonempty-tvars@ + (unit/sig + mrspidey:find-nonempty-tvars^ + (import + mrspidey:CDL^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:min-live^ + mrspidey:templates^) + (include (begin-elaboration-time (build-path "min" "nonempty.ss"))))) + +(define mrspidey:min-live-few-e@ + (unit/sig + mrspidey:min-live-few-e^ + (import + mrspidey:CDL^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:min^ + mrspidey:min-live^) + (include (begin-elaboration-time (build-path "min" "livefewe.ss"))))) + +(define mrspidey:hopcroft@ + (unit/sig + mrspidey:hopcroft^ + (import + mrspidey:CDL^ + mzlib:unprefixed-core^ + mrspidey:min^) + (include (begin-elaboration-time (build-path "min" "hopcroft.ss"))))) + +'(define-signature mrspidey:min-dfa^ (minimize-constraints-dfa-min)) +'(mrspidey:load-unit "min/" min-dfa-old ( mrspidey:CDL^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:min^ + mrspidey:find-nonempty-tvars^ + mrspidey:min-live^ + mrspidey:hopcroft^)) + +'(define-signature mrspidey:min-dfa-inv^ (minimize-constraints-dfa-min-inv)) +'(mrspidey:load-unit "min/" min-dfa-inv ( mrspidey:CDL^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:min^ + mrspidey:min-live^ + mrspidey:hopcroft^)) + +'(define-signature mrspidey:min-dfa-strange ( minimize-constraints-dfa-min-1 + minimize-constraints-dfa-min-2)) +'(mrspidey:load-unit "min/" min-dfa-strange ( mrspidey:CDL^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:min-live^ + mrspidey:hopcroft^)) + +(define mrspidey:min-dfa-fast@ + (unit/sig + mrspidey:min-dfa-fast^ + (import + mrspidey:CDL^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:min^ + mrspidey:min-live^ + mrspidey:min-live-few-e^ + mrspidey:hopcroft^) + (include (begin-elaboration-time (build-path "min" "min-dfa.ss"))))) + +(define mrspidey:min@ + (unit/sig + mrspidey:min^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:find-nonempty-tvars^ + mrspidey:min-live^ + mrspidey:min-live-few-e^ + ;mrspidey:min-dfa^ + ;mrspidey:min-dfa-inv^ + ;mrspidey:min-dfa-strange^ + mrspidey:min-dfa-fast^ + ) + (include (begin-elaboration-time (build-path "min" "min.ss"))) + (define minimize-constraints-dfa-min 1) + (define minimize-constraints-dfa-min-inv 1) + (define minimize-constraints-dfa-min-1 1) + (define minimize-constraints-dfa-min-2 1) + (define min-table 1) + )) + +(define mrspidey:all-min@ + (compound-unit/sig + (import + (CDL : mrspidey:CDL^) + (INTERACTION : mrspidey:interaction^) + (KERNEL : mrspidey:kernel^) + (KERNEL-AUX : mrspidey:kernel-aux^) + (TEMPLATES : mrspidey:templates^) + (MZLIB : mzlib:unprefixed-core^) + ) + (link + [MIN : mrspidey:min^ + (mrspidey:min@ CDL INTERACTION KERNEL + FIND LIVE FEW FAST)] + [FIND : mrspidey:find-nonempty-tvars^ + (mrspidey:find-nonempty-tvars@ CDL KERNEL KERNEL-AUX LIVE TEMPLATES)] + [LIVE : mrspidey:min-live^ + (mrspidey:min-live@ CDL KERNEL KERNEL-AUX MIN TEMPLATES)] + [FEW : mrspidey:min-live-few-e^ + (mrspidey:min-live-few-e@ CDL KERNEL KERNEL-AUX MIN LIVE)] + [HOPCROFT : mrspidey:hopcroft^ + (mrspidey:hopcroft@ CDL MZLIB MIN)] + ;;[DFA : mrspidey:min-dfa^ + ;; (mrspidey:min-dfa@ CDL KERNEL KERNEL-AUX LIVE HOPCROFT)] + ;;[INV : mrspidey:min-dfa-inv^ + ;; (mrspidey:min-dfa-inv@ CDL KERNEL KERNEL-AUX LIVE HOPCROFT)] + ;;[STRANGE : mrspidey:min-dfa-strange^ + ;; (mrspidey:min-dfa-strange^@ CDL KERNEL KERNEL-AUX LIVE HOPCROFT)] + [FAST : mrspidey:min-dfa-fast^ + (mrspidey:min-dfa-fast@ CDL KERNEL KERNEL-AUX MIN LIVE FEW HOPCROFT)]) + (export (open MIN)))) + +;; ---------------------------------------------------------------------- +;; top level stuff + +(define mrspidey:templates@ + (unit/sig + mrspidey:templates^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^) + (include "template.ss"))) + +(define mrspidey:kernel-aux@ + (unit/sig + mrspidey:kernel-aux^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:templates^ + (zodiac : mrspidey:zodiac^)) + (include "kern-aux.ss"))) + +(define mrspidey:typelang@ + (unit/sig + mrspidey:typelang^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:templates^ + mrspidey:type-env^ + mrspidey:atype^ + mrspidey:contained^ + mzlib:unprefixed-core^ + (zodiac : mrspidey:zodiac^)) + (include "typelang.ss"))) + +(define mrspidey:contained@ + (unit/sig + mrspidey:contained^ + (import + mrspidey:CDL^ + mrspidey:kernel^ + mrspidey:sdl^) + (include "contain.ss"))) + +(define mrspidey:type-env@ + (unit/sig + mrspidey:type-env^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:templates^ + mrspidey:min^ + mrspidey:atype^ + (zodiac : mrspidey:zodiac^)) + (include "type-env.ss"))) + +(define mrspidey:sdl@ + (unit/sig + mrspidey:sdl^ + (import + mrspidey:CDL^ + mrspidey:kernel^ + mrspidey:min^ + mrspidey:typelang^ + mrspidey:kernel-aux^ + mrspidey:templates^ + mrspidey:atype^ + mzlib:unprefixed-core^) + (include "sdl.ss"))) + +(define mrspidey:languages@ + (unit/sig + mrspidey:languages^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:templates^ + mrspidey:kernel-aux^ + mrspidey:atype^ + mrspidey:type-env^ + mrspidey:typelang^ + mrspidey:atenv^ + mrspidey:loadexpand^ + mrspidey:traverse^ + mzlib:unprefixed-core^ + (zodiac : mrspidey:zodiac^)) + (include "language.ss"))) + +(define mrspidey:za@ + (unit/sig + mrspidey:za^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:templates^ + mrspidey:type-env^ + mrspidey:typelang^ + mrspidey:atype^ + mzlib:unprefixed-core^) + (include "za.ss"))) + +;; ---------------------------------------------------------------------- +;; Traversal + +(define mrspidey:atype@ + (unit/sig + mrspidey:atype^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:min^ + mrspidey:typelang^ + mrspidey:templates^ + mrspidey:type-env^ + mrspidey:sdl^ + mrspidey:atlunit^ + mzlib:unprefixed-core^) + (include "atype.ss"))) + +(define mrspidey:atenv@ + (unit/sig + mrspidey:atenv^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:atype^ + (zodiac : mrspidey:zodiac^) + mzlib:unprefixed-core^) + (include "atenv.ss"))) + +(define mrspidey:atlunit@ + (unit/sig + mrspidey:atlunit^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:min^ + mrspidey:loadexpand^ + mrspidey:type-env^ + mrspidey:templates^ + mrspidey:languages^ + mrspidey:atype^ + mrspidey:atenv^ + mrspidey:traverse^ + mrspidey:za^ + (zodiac : mrspidey:zodiac^) + mzlib:unprefixed-core^ + [wx : wx^]) + (include "atlunit.ss"))) + +(define mrspidey:traverse@ + (unit/sig + mrspidey:traverse^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:min^ + mrspidey:loadexpand^ + mrspidey:templates^ + mrspidey:kernel-aux^ + mrspidey:typelang^ + mrspidey:type-env^ + mrspidey:languages^ + mrspidey:atype^ + mrspidey:atlunit^ + mrspidey:atenv^ + (zodiac : mrspidey:zodiac^) + mzlib:unprefixed-core^) + (include "traverse.ss"))) + +;; ---------------------------------------------------------------------- + +(define mrspidey:program@ + (unit/sig + mrspidey:program^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:type-env^ + mrspidey:loadexpand^ + mrspidey:traverse^ + mrspidey:templates^ + mrspidey:atenv^ + mrspidey:atype^ + mrspidey:languages^ + (zodiac : mrspidey:zodiac^) + mzlib:unprefixed-core^) + (include "program.ss"))) + +(define mrspidey:calc-checks@ + (unit/sig + mrspidey:calc-checks^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:loadexpand^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:typelang^ + mrspidey:templates^ + mrspidey:atype^ + mrspidey:sdl^ + (zodiac : mrspidey:zodiac^) + mzlib:unprefixed-core^) + (include "checks.ss"))) + +(define mrspidey:driver@ + (unit/sig + mrspidey:driver^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:kernel^ + mrspidey:templates^ + mrspidey:typelang^ + mrspidey:type-env^ + mrspidey:atype^ + mrspidey:atenv^ + mrspidey:program^ + mrspidey:calc-checks^ + mrspidey:languages^ + (zodiac : mrspidey:zodiac^)) + (include "driver.ss"))) + +(define mrspidey:hyper@ + (unit/sig + mrspidey:hyper^ + (import + mrspidey:CDL^ + mrspidey:interaction^ + mrspidey:loadexpand^ + mrspidey:program^ + mrspidey:calc-checks^ + mrspidey:templates^ + mrspidey:kernel^ + mrspidey:kernel-aux^ + mrspidey:atype^ + mzlib:unprefixed-core^) + (include "hyper.ss"))) + +(load-relative "zod-extra.ss") + +;; ---------------------------------------------------------------------- +;; Put it all together + +(load-relative "link.ss") + +;; ---------------------------------------------------------------------- + + + + + + + diff --git a/collects/mrspidey/Sba/make-exn-hierarchy.ss b/collects/mrspidey/Sba/make-exn-hierarchy.ss new file mode 100644 index 0000000..b4c94d6 --- /dev/null +++ b/collects/mrspidey/Sba/make-exn-hierarchy.ss @@ -0,0 +1,35 @@ + +(define src "/home/mflatt/proj/mred/mzscheme/src/exnsrc.ss") +(define dest "/home/cormac/plt/mrspidey/Sba/exn-hierarchy.ss") +(when (file-exists? dest) (delete-file dest)) + +(with-input-from-file src + (lambda () + (let ([x (read)]) + (with-output-to-file dest + (lambda () + (letrec + ([trav + (lambda (tree parent) + (match tree + [(name fields+strings . subtrees) + (let* ( [fields (filter symbol? fields+strings)] + [s (symbol->string name)] + [name (if (memq (string-ref s 0) '(#\* #\+)) + (string->symbol + (substring s 1 (string-length s))) + name)] + [name (if parent (symbol-append parent ': name) name)]) + (display + `(define-struct + ,(if parent + `(,name ,(symbol-append 'struct: parent)) + name) + ,fields)) + (newline) + (for-each + (lambda (subtree) (trav subtree name)) + subtrees))] + ['- (void)] + [(? string?) (void)]))]) + (trav x #f))))))) diff --git a/collects/mrspidey/Sba/min-test.ss b/collects/mrspidey/Sba/min-test.ss new file mode 100644 index 0000000..630f152 --- /dev/null +++ b/collects/mrspidey/Sba/min-test.ss @@ -0,0 +1,1555 @@ +;; min-test.ss + +(define debug-nfa #t) +(define pretty-debug-nfa (lambda (x) (when debug-nfa (pretty-print x)))) + +(define debug-min #f) +(define pretty-debug-min (lambda (x) (when debug-nfa (pretty-print x)))) + +; ====================================================================== +; VIEWING CONSTRAINTS AS GRAMMARS +; ====================================================================== +; Non-Terminalss + +; x is an AVS +(define-structure (L x)) +(define-structure (LI x)) +(define-structure (U x)) +(define-structure (UI x)) + +(define eq-nt? + (match-lambda* + [(($ L x1) ($ L x2)) (eq? x1 x2)] + [(($ LI x1) ($ LI x2)) (eq? x1 x2)] + [(($ U x1) ($ U x2)) (eq? x1 x2)] + [(($ UI x1) ($ UI x2)) (eq? x1 x2)] + [_ #f])) + +(define nt? + (match-lambda + [(or ($ L) ($ U) ($ LI) ($ UI)) #t] + [_ #f])) + +(define same-nt-type? + (match-lambda* + [(($ L x1) ($ L x2)) #t] + [(($ LI x1) ($ LI x2)) #t] + [(($ U x1) ($ U x2)) #t] + [(($ UI x1) ($ UI x2)) #t] + [_ #f])) + +(define nt->AVS + (match-lambda + [($ L x1) x1] + [($ LI x1) x1] + [($ U x1) x1] + [($ UI x1) x1])) + +(define nt-chg-AVS + (match-lambda* + [(f ($ L x)) (make-L (f x))] + [(f ($ LI x)) (make-LI (f x))] + [(f ($ U x)) (make-U (f x))] + [(f ($ UI x)) (make-UI (f x))])) + +(define drop-I + (match-lambda + [(and nt (or ($ L _) ($ U _))) nt] + [($ LI x) (make-L x)] + [($ UI x) (make-U x)])) + +(define mem-nt? + (lambda (nt l) + (and (not (null? l)) + (or (eq-nt? nt (car l)) + (mem-nt? nt (cdr l)))))) + +(define (set-NT-prop! NT val) + (let* ([AVS (nt->AVS NT)] + [old (get-AVS-prop AVS 'NT-prop #f)] + [old (if old old + (let ([v (vector #f #f #f #f)]) + (add-AVS-prop! AVS 'NT-prop v) + v))]) + (vector-set! + old + (match NT + [($ L x1) 0] [($ LI x1) 1] [($ U x1) 2] [($ UI x1) 3]) + val))) + +(define (get-NT-prop NT) + (let* ([AVS (nt->AVS NT)] + [old (get-AVS-prop AVS 'NT-prop #f)] + [old (if old old + (let ([v (vector #f #f #f #f)]) + (add-AVS-prop! AVS 'NT-prop v) + v))]) + (vector-ref + old + (match NT + [($ L x1) 0] [($ LI x1) 1] [($ U x1) 2] [($ UI x1) 3])))) + +; ====================================================================== +; Right hand side of a production + +(define-structure (rhs* grsym nts)) +(define (make-rhs grsym nt) (make-rhs* grsym (list nt))) + +(define-structure (grsym ineq fn sign template field-no)) +;; ineq is '<= or '>= +;; fn is 'inj, 'inj-tst or 'ext +;; sign is #t (monotonic) or #f (antimonotonic) +;; field-no may be #f + +(define (make-grsym->=inj+ t f) (make-grsym '>= 'inj #t t f)) +(define (make-grsym->=inj- t f) (make-grsym '>= 'inj #f t f)) +(define (make-grsym->=inj? t f) (make-grsym '>= 'inj '? t f)) + +(define (make-grsym-<=inj-tst+ t f) (make-grsym '<= 'inj-tst #t t f)) +(define (make-grsym-<=inj-tst- t f) (make-grsym '<= 'inj-tst #f t f)) + +(define (make-grsym-<=ext+ t f) (make-grsym '<= 'ext #t t f)) +(define (make-grsym->=ext- t f) (make-grsym '>= 'ext #f t f)) + +(define (make-grsym->=ext+ t f) (make-grsym '>= 'ext #t t f)) +(define (make-grsym-<=ext- t f) (make-grsym '<= 'ext #f t f)) + +;; a grsym can also be '>=epsilon or '<=epsilon + +(define grsym-eq? + (match-lambda* + [(($ grsym i1 f1 s1 t1 n1) ($ grsym i2 f2 s2 t2 n2)) + (and (eq? i1 i2) (eq? f1 f2) (eq? t1 t2) (eqv? n1 n2))] + [(x y) (eq? x y)])) + +; ====================================================================== +;; Initializing the L, ... fields of an AVS + +(define (add-AVS-LI! AVS x) (set-AVS-LI! AVS (cons x (AVS-LI AVS)))) +(define (add-AVS-UI! AVS x) (set-AVS-UI! AVS (cons x (AVS-UI AVS)))) +(define (add-AVS-L! AVS x) (set-AVS-L! AVS (cons x (AVS-L AVS)))) +(define (add-AVS-U! AVS x) (set-AVS-U! AVS (cons x (AVS-U AVS)))) + +(define zeroary-op-AVS (void)) + +(define (calc-productions! list-AVS use-AVS? + tree zeroary + epsilon-L epsilon-U epsilon-LI epsilon-UI + L->LI U->UI) + ;; tree : bool -- controls if produce RTG or regular grammar + ;; epsilon-...: bool -- control epsilon transitions + ;; L->LI, ... : bool -- controls L->LI production rule + + (for-each + (lambda (AVS) + (set-AVS-L! AVS '()) + (set-AVS-U! AVS '()) + (set-AVS-LI! AVS '()) + (set-AVS-UI! AVS '()) + (set-AVS-edgefrom! AVS '())) + list-AVS) + + ;; ------ Invert edges + (for-each + (lambda (AVS) + (for-each + (lambda (to) (when (use-AVS? to) (add-AVS-edgefrom! to AVS))) + (AVS-edgeto AVS))) + list-AVS) + + ;; ------ Now make L, etc, from AV, constraints and edges + (for-each + (lambda (AVS) + + ;; ------ Invert original AV + (for-each + (match-lambda + [($ AV _ (and template ($ template type signs)) misc fields) + (let ([l (vector-length fields)]) + (cond + [tree + ;; Make rhs + (add-AVS-L! AVS + (make-rhs* (make-grsym->=inj? template #f) + (map + (lambda (f sign) + (case sign + [>=inj+ (make-L f)] + [>=inj- (make-U f)])) + (vector->list fields) + (vector->list signs))))] + ;; o/w not tree + [(= l 0) + ;; Terminal + (add-AVS-L! AVS + (make-rhs* (make-grsym->=inj+ template #f) '()))] + [else + ;; Non-terminal - return all prods + (for i 0 l + (let ([f (vector-ref fields i)]) + (when (use-AVS? f) + (case (vector-ref signs i) + [>=inj+ + (add-AVS-L! AVS + (make-rhs (make-grsym->=inj+ template i) + (make-L f)))] + [>=inj- + (add-AVS-L! AVS + (make-rhs (make-grsym->=inj- template i) + (make-U f)))]))))]) + + (if (and zeroary (zero? l)) + ;; Fake a unary op + (add-AVS-UI! zeroary-op-AVS + (make-rhs (make-grsym-<=ext+ template 0) + (make-UI AVS))) + + (for i 0 l + (let ([f (vector-ref fields i)]) + (when (use-AVS? f) + (case (vector-ref signs i) + [>=inj+ + (add-AVS-UI! + f + (make-rhs (make-grsym-<=ext+ template i) + (make-UI AVS)))] + [>=inj- + (add-AVS-LI! + f + (make-rhs (make-grsym->=ext- template i) + (make-UI AVS)))]))))))]) + (AVS-orig-objs AVS)) + + ;; ------ Invert constraints + (for-each + (match-lambda + [($ con _ (and template ($ template type signs)) field-no AVS2) + (when (use-AVS? AVS2) + (case (vector-ref signs field-no) + [>=inj+ + (add-AVS-U! AVS + (make-rhs (make-grsym-<=inj-tst+ template field-no) + (make-U AVS2))) + (add-AVS-LI! AVS2 + (make-rhs (make-grsym->=ext+ template field-no) + (make-LI AVS)))] + [>=inj- + (add-AVS-U! AVS + (make-rhs (make-grsym-<=inj-tst- template field-no) + (make-L AVS2))) + (add-AVS-UI! AVS2 + (make-rhs (make-grsym-<=ext- template field-no) + (make-LI AVS)))]))] + [($ con-filter _ filter AVS2) + (printf "Warning: con-filter~n")]) + (AVS-constraints AVS)) + + (for-each + (lambda (to) + (when epsilon-L (add-AVS-L! to (make-rhs '>=epsilon (make-L AVS)))) + (case epsilon-LI + [#t (add-AVS-LI! to (make-rhs '>=epsilon (make-LI AVS)))] + ['concrete + (add-AVS-LI! to (make-rhs '>=concrete-epsilon (make-LI AVS)))]) + (when epsilon-U (add-AVS-U! AVS (make-rhs '<=epsilon (make-U to)))) + (when epsilon-UI (add-AVS-UI! AVS (make-rhs '<=epsilon (make-UI to))))) + (AVS-edgeto AVS)) + + (when L->LI (add-AVS-L! AVS (make-rhs '>=epsilon (make-LI AVS)))) + (when U->UI (add-AVS-U! AVS (make-rhs '<=epsilon (make-UI AVS)))) + ) + list-AVS)) + +;; ---------------------------------------------------------------------- +;; Restricting the grammer to certain NTs + +(define (restrict-nts! list-AVS use-nt?) + ;;(display `(restrict-nts! ,(map nt->sym list-nt))) (newline) + (let* ([filter-nt + (lambda (rhs*) + (filter-map + (match-lambda + [(and rhs ($ rhs* grsym nts)) + (if (or (null? nts) (ormap use-nt? nts)) + rhs + #f)]) + rhs*))]) + (for-each + (lambda (AVS) + (for-each + (match-lambda + [(set-AVS-NT! make-NT AVS-NT) + (set-AVS-NT! AVS (if (use-nt? (make-NT AVS)) + (filter-nt (AVS-NT AVS)) + '()))]) + (list (list set-AVS-L! make-L AVS-L) + (list set-AVS-U! make-U AVS-U) + (list set-AVS-LI! make-LI AVS-LI) + (list set-AVS-UI! make-UI AVS-UI)))) + list-AVS))) + +;; ---------------------------------------------------------------------- +;; for-each-prods +;; For this to work, must have AVS-L etc setup. + +(define (for-each-prods f nt) + (match nt + [($ L x) (for-each f (AVS-L x))] + [($ U x) (for-each f (AVS-U x))] + [($ LI x) (for-each f (AVS-LI x))] + [($ UI x) (for-each f (AVS-UI x))])) + +;; ====================================================================== + +(define (add-prod nt grsym nt*) + (assert (andmap nt? nt*)) + (let ([rhs (make-rhs* grsym nt*)]) + (match nt + [($ L x) (add-AVS-L! x rhs)] + [($ LI x) (add-AVS-LI! x rhs)] + [($ U x) (add-AVS-U! x rhs)] + [($ UI x) (add-AVS-UI! x rhs)]))) + +;; ---------------------------------------------------------------------- +;; Assumes grammar is result of N->D +;; So is a D-RTG, and only has productions on L,U +;; not on LI,UI + +(define (convert-productions-to-AV-etc! list-AVS) + ;;(pretty-print `(cvt-prods ,(map name-for-AVS list-AVS))) + (let* ([AVS-empty (mk-AVS-tmp 'empty)] + [add-AV-field! + (lambda (AVS template field-no AVS2) + (or + ;; Is the zeroary-op-AVS field + (>= field-no (vector-length (template-signs template))) + ;; Reuse old AV, if possible + (ormap + (match-lambda + [($ AV _ (? (lambda (t) (eq? t template))) _ fields) + (cond + [(eq? (vector-ref fields field-no) AVS-empty) + ;;; empty, fill it + (vector-set! fields field-no AVS2) + #t] + [(eq? (vector-ref fields field-no) AVS2) + ;; Already in there + #t] + [else;; this won't work + #f])] + [_ #f]) + (get-AVS-objs AVS)) + ;; No AV in there, create and add one + (let* ([l (vector-length (template-signs template))] + [fields (make-vector l AVS-empty)]) + (vector-set! fields field-no AVS2) + (add-nohash-orig-AV! + AVS (create-AV-nolist template '() fields)))))]) + + ;; Examine each production rule, and convert it. + (for-each + (lambda (AVS) + ;;(pretty-print `(convert-prods AVS ,(AVS-num AVS))) + ;; L-AVS + (for-each + (match-lambda + [($ rhs* (or '>=epsilon '>=concrete-epsilon) ((or ($ L x) ($ LI x)))) + (unless (eq? AVS x) (add-edge! x AVS))] + [($ rhs* ($ grsym '>= 'inj sign template field-no) ()) + (add-nohash-orig-AV! AVS (create-AV-nolist template '() (vector)))] + [($ rhs* ($ grsym '>= 'inj sign template #f) + ((or ($ L x*) ($ U x*)) ...)) + (map-with-n (lambda (x n) (add-AV-field! AVS template n x)) + x*)] + [($ rhs* ($ grsym '>= 'inj sign template field-no) + ((or ($ L x) ($ U x)))) + (add-AV-field! AVS template field-no x)] + + [($ rhs* ($ grsym '>= ext #t template field-no) + ((or ($ LI x) ($ L x)))) + (add-con! x (create-con template field-no AVS))] + [($ rhs* ($ grsym '>= ext #f template field-no) + ((or ($ UI x) ($ U x)))) + (add-AV-field! x template field-no AVS)] + + [($ rhs* grsym nts) + (error 'prod-to-AV "Bad L/LI rhs ~s ~s" + (grsym->rep grsym) (map nt->sym nts))] + [rhs (error 'prod-to-AV "Bad L/LI rhs ~s" rhs)]) + (append (AVS-L AVS) (AVS-LI AVS))) + + ;; U-AVS + (for-each + (match-lambda + [($ rhs* '<=epsilon ((or ($ U x) ($ UI x)))) + (unless (eq? AVS x) (add-edge! AVS x))] + [($ rhs* ($ grsym '<= 'inj-tst #f template field-no) (($ L x))) + (add-con! AVS (create-con template field-no x))] + [($ rhs* ($ grsym '<= 'inj-tst #t template field-no) (($ U x))) + (add-con! AVS (create-con template field-no x))] + + [($ rhs* ($ grsym '<= 'ext #f template field-no) + ((or ($ L x) ($ LI x)))) + (add-con! x (create-con template field-no AVS))] + [($ rhs* ($ grsym '<= 'ext #t template field-no) + ((or ($ U x) ($ UI x)))) + (add-AV-field! x template field-no AVS)] + + [($ rhs* grsym nts) + (error 'prod-to-AV "Bad U/UI rhs ~s ~s" + (grsym->rep grsym) (map nt->sym nts))] + [rhs (error 'prod-to-AV "Bad U/UI rhs ~s" rhs)]) + (append (AVS-U AVS) (AVS-UI AVS)))) + + list-AVS) + + ;; Now prop AVs + (for-each + (lambda (AVS) + (for-each (lambda (AV) (prop-AV! AVS AV)) + (AVS-orig-objs AVS))) + list-AVS) + + )) + +; ====================================================================== +; COMPRESSING GRAMMARS +; ====================================================================== + +(define (epsilon-close-nt nt) + (epsilon-close-nts (list nt))) + +(define (epsilon-close-nts nts) + (let ([done '()]) + (letrec ([traverse + (lambda (nt) + (unless (mem-nt? nt done) + (set! done (cons nt done)) + (for-each-prods + (match-lambda + [($ rhs* (or '>=epsilon '<=epsilon) (nt2)) + (traverse nt2)] + [_ (void)]) + nt)))]) + (for-each traverse nts) + done))) + +; -------------------- + +(define for-each-prods-joined + (lambda (fn nt*) + (let* ([rhs* '()]) + (for-each + (lambda (nt) + (for-each-prods (lambda (rhs) (set! rhs* (cons rhs rhs*))) + nt)) + nt*) + (recur loop ([rhs* rhs*]) + (match rhs* + [() (void)] + [(($ rhs* grsym _) . _) + (match-let + ([(nt** . rest) + (filter-map-split + (match-lambda + [($ rhs* grsym2 nt*) + (if (grsym-eq? grsym grsym2) nt* #f)]) + rhs*)]) + (fn grsym nt**) + (loop rest))]))))) + +; -------------------- + +(define (grammar-calc-reached roots) + (let ([reached '()] + [tag (gensym)]) + (letrec + ([traverse + (lambda (nt) + (unless (eq? (get-NT-prop nt) tag) + (set-NT-prop! nt tag) + (set! reached (cons nt reached)) + (for-each-prods + (match-lambda + [($ rhs* _ nt*) + (for-each traverse nt*)]) + nt)))]) + (for-each traverse roots) + (list reached (lambda (nt) (eq? (get-NT-prop nt) tag)))))) + +; -------------------- + +(define (grammar-calc-nonempty num-NT NT->num num->NT final) + (let* ([table (make-vector num-NT '())]) + ;; entry is #t if nonempty, + ;; or else list of NT to make nonempty if proved nonempty + (letrec ([set-nonempty! + (lambda (n) + '(pretty-print `(set-nonempty! ,(nt->sym (num->NT n)))) + (let ([l (vector-ref table n)]) + (vector-set! table n #t) + (when (list? l) + (for-each set-nonempty! l))))] + [add-depends + (lambda (i j) + '(pretty-print `(add-depends ,(nt->sym (num->NT i)) + ,(nt->sym (num->NT j)))) + (if (list? (vector-ref table j)) + (vector-set! table j (cons i (vector-ref table j))) + (set-nonempty! i)))]) + + ;; fill out table + (for i 0 num-NT + (let ([nt (num->NT i)]) + ;;(pretty-print `(i ,i nt ,(nt->sym nt) ,(mem-nt? nt final))) + (if (mem-nt? nt final) + (set-nonempty! i) + ;; Look at prods + (for-each-prods + (match-lambda + [($ rhs* grsym nt*) + ;;(pretty-print `(-> ,(grsym->rep grsym) ,(nt->sym nt))) + (if (null? nt*) + (set-nonempty! i) + (for-each (lambda (nt) (add-depends i (NT->num nt))) + nt*))]) + nt)))) + + ;; return list of nonempty nts, plus membership predicate + ;; + (list (filter-map + (lambda (x) x) + (map-with-n + (lambda (entry n) + (if (eq? entry #t) + (num->NT n) + #f)) + (vector->list table))) + ;; nonempty-nt? + (lambda (nt) (if (and (NT->num nt) + (eq? (vector-ref table (NT->num nt)) #t)) + #t #f)) + )))) + +; ====================================================================== +; COMPRESSING CONSTRAINTS +; ====================================================================== + +(define select-L + (lambda (nt*) + (filter-map (match-lambda [($ L x) x][_ #f]) nt*))) + +(define select-LI + (lambda (nt*) + (filter-map (match-lambda [($ LI x) x][_ #f]) nt*))) + +(define select-U + (lambda (nt*) + (filter-map (match-lambda [($ U x) x][_ #f]) nt*))) + +(define select-UI + (lambda (nt*) + (filter-map (match-lambda [($ UI x) x][_ #f]) nt*))) + +; -------------------- + +(define (epsilon-close-forwards AVS) + (let ([done '()]) + (recur traverse ([AVS AVS]) + (unless (memq AVS done) + (set! done (cons AVS done)) + (for-each traverse (AVS-edgeto AVS)))) + done)) + +(define (epsilon-close-backwards AVS) + (let ([done '()]) + (recur traverse ([AVS AVS]) + (unless (memq AVS done) + (set! done (cons AVS done)) + (for-each traverse (AVS-edgefrom AVS)))) + done)) + +; ====================================================================== +; Could use list-AVS to be more efficient here! + +(define calc-NT<->num + (lambda (list-nt) + (let* ([num-NT 0] + [num->NT (make-vector (* 4 (length list-nt)) #f)] + [AVS->L-NT (make-vector num-AVS #f)] + [AVS->LI-NT (make-vector num-AVS #f)] + [AVS->U-NT (make-vector num-AVS #f)] + [AVS->UI-NT (make-vector num-AVS #f)] + [add-NT! (lambda (NT) + (vector-set! num->NT num-NT NT) + (begin0 + num-NT + (set! num-NT (add1 num-NT))))]) + (for-each + (lambda (nt) + (match nt + [($ L AVS) (vector-set! AVS->L-NT (AVS-num AVS) (add-NT! nt))] + [($ LI AVS) (vector-set! AVS->LI-NT (AVS-num AVS) (add-NT! nt))] + [($ U AVS) (vector-set! AVS->U-NT (AVS-num AVS) (add-NT! nt))] + [($ UI AVS) (vector-set! AVS->UI-NT (AVS-num AVS) (add-NT! nt))])) + list-nt) + (list num-NT + (match-lambda + [($ L x) (vector-ref AVS->L-NT (AVS-num x))] + [($ LI x) (vector-ref AVS->LI-NT (AVS-num x))] + [($ U x) (vector-ref AVS->U-NT (AVS-num x))] + [($ UI x) (vector-ref AVS->UI-NT (AVS-num x))]) + (lambda (num) (vector-ref num->NT num)))))) + +; ---------------------------------------------------------------------- + +(define leq->equiv + (lambda (list-e e->num e-leq?) + ;; Takes a list of elements in list-e, + ;; with e-leq? a partial order + ;; Calculates an equivalence relation + (match-let* + ([e-eq? (lambda (i j) + (let ([r (and (e-leq? i j) (e-leq? j i))]) + '(when r (printf "~s=~s~n" (nt->sym i) (nt->sym j))) + r))] + [AVS-leq? (lambda (x y) + (and (NT-leq? (make-L x) (make-L y)) + (NT-leq? (make-LI x) (make-LI y)) + (NT-leq? (make-U y) (make-U x)) + (NT-leq? (make-UI y) (make-UI x))))] + [AVS->rep-AVS (make-vector num-AVS #f)] + [list-rep-AVS '()] + [old-AVS->AVS (lambda (old-AVS) + (let ([AVS (vector-ref AVS->rep-AVS + (AVS-num old-AVS))]) + AVS))] + [old-nt->nt (lambda (nt) (nt-chg-AVS old-AVS->AVS nt))] + [AV-leq? + (match-lambda* + [(($ AV _ template1 misc1 fields1) + ($ AV _ template2 misc2 fields2) + AVS-leq?) + (and (eq? template1 template2) + (eq? misc1 misc2) + (andmap2 AVS-leq? + (vector->list fields1) + (vector->list fields2)))])]) + + ;; Have equivalence relation in AVS-eq? + ;; want to create mapping AVS -> new AVS + (printf "Calculating AVS -> new AVS~n") + (for-each + (lambda (AVS) + (ormap + (lambda (rep) + (cond + [(eq? AVS rep) + ;; This AVS not included in any representative AVS + (let ([rep-AVS (mk-AVS-nolist 'eqvcl)]) + (vector-set! AVS->rep-AVS (AVS-num AVS) rep-AVS) + (set! list-rep-AVS (cons (cons AVS rep-AVS) list-rep-AVS)) + #t)] + [(AVS-eq? AVS rep) + ;; This NT is equivalent to rep + (let ([rep-AVS (vector-ref AVS->rep-AVS (AVS-num rep))]) + ;(assert (eq? rep )) + (vector-set! AVS->rep-AVS (AVS-num AVS) rep-AVS) + (set! list-rep-AVS (cons (cons AVS rep-AVS) list-rep-AVS))) + #t] + [else;; continue + #f])) + list-AVS)) + list-AVS) + + '(begin + (display + `(AVS->rep-AVS + ,(map (lambda (AVS) + (cons (AVS-num AVS) + (AVS-num (vector-ref AVS->rep-AVS (AVS-num AVS))))) + list-AVS))) + (newline)) + (printf "Num rep AVS=~s~n" (length list-rep-AVS)) + + ;; Now fill in the AV's and constraints in the representative AVS + ;; Maybe want to remove duplicate constraints + ;; Not removing duplicate AV's from different AVSs in same rep-AVS + + (printf "Copying grammar~n") + + (for-each + (match-lambda + [(old-AVS . rep-AVS) + (for-each + (match-lambda + [(get-nt set-nt!) + (for-each + (match-lambda + [($ rhs* grsym nt*) + (or + ;; Check if already there + (ormap (match-lambda + [($ rhs* + (? (lambda (grsym2) (grsym-eq? grsym grsym2))) + (? (lambda (nt2*) (andmap2 eq-nt? nt* nt2*)))) + #t] + [_ #f]) + (get-nt rep-AVS)) + ;; Add it + (set-nt! rep-AVS + (cons (make-rhs* + grsym + (map old-nt->nt nt*)) + (get-nt rep-AVS))))]) + (get-nt old-AVS))]) + (list (list AVS-L set-AVS-L!) + (list AVS-LI set-AVS-LI!) + (list AVS-U set-AVS-U!) + (list AVS-UI set-AVS-UI!)))]) + list-rep-AVS) + + ;; Done, return mapping + old-nt->nt))) + +; ---------------------------------------------------------------------- + +(define apply-equivalence-relation + (lambda (list-nt num-NT NT->num num->NT NT-leq?) + ;; NT-leq? is ordering on NTs + (match-let* + ([list-AVS (list->set (map nt->AVS list-nt))] + [NT-eq? (lambda (i j) + (let ([r (and (NT-leq? i j) (NT-leq? j i))]) + '(when r (printf "~s=~s~n" (nt->sym i) (nt->sym j))) + r))] + [AVS-eq? (lambda (x y) + (let ([r + (and (NT-eq? (make-L x) (make-L y)) + (NT-eq? (make-LI x) (make-LI y)) + (NT-eq? (make-U x) (make-U y)) + (NT-eq? (make-UI x) (make-UI y)))]) + '(when r (printf "~s=~s~n" + (name-for-AVS x) (name-for-AVS y))) + r))] + [AVS-leq? (lambda (x y) + (and (NT-leq? (make-L x) (make-L y)) + (NT-leq? (make-LI x) (make-LI y)) + (NT-leq? (make-U y) (make-U x)) + (NT-leq? (make-UI y) (make-UI x))))] + [AVS->rep-AVS (make-vector num-AVS #f)] + [list-rep-AVS '()] + [old-AVS->AVS (lambda (old-AVS) + (let ([AVS (vector-ref AVS->rep-AVS + (AVS-num old-AVS))]) + AVS))] + [old-nt->nt (lambda (nt) (nt-chg-AVS old-AVS->AVS nt))] + [AV-leq? + (match-lambda* + [(($ AV _ template1 misc1 fields1) + ($ AV _ template2 misc2 fields2) + AVS-leq?) + (and (eq? template1 template2) + (eq? misc1 misc2) + (andmap2 AVS-leq? + (vector->list fields1) + (vector->list fields2)))])]) + + ;; Have equivalence relation in AVS-eq? + ;; want to create mapping AVS -> new AVS + (printf "Calculating AVS -> new AVS~n") + (for-each + (lambda (AVS) + (ormap + (lambda (rep) + (cond + [(eq? AVS rep) + ;; This AVS not included in any representative AVS + (let ([rep-AVS (mk-AVS-nolist 'eqvcl)]) + (vector-set! AVS->rep-AVS (AVS-num AVS) rep-AVS) + (set! list-rep-AVS (cons (cons AVS rep-AVS) list-rep-AVS)) + #t)] + [(AVS-eq? AVS rep) + ;; This NT is equivalent to rep + (let ([rep-AVS (vector-ref AVS->rep-AVS (AVS-num rep))]) + ;(assert (eq? rep )) + (vector-set! AVS->rep-AVS (AVS-num AVS) rep-AVS) + (set! list-rep-AVS (cons (cons AVS rep-AVS) list-rep-AVS))) + #t] + [else;; continue + #f])) + list-AVS)) + list-AVS) + + '(begin + (display + `(AVS->rep-AVS + ,(map (lambda (AVS) + (cons (AVS-num AVS) + (AVS-num (vector-ref AVS->rep-AVS (AVS-num AVS))))) + list-AVS))) + (newline)) + (printf "Num rep AVS=~s~n" (length list-rep-AVS)) + + ;; Now fill in the AV's and constraints in the representative AVS + ;; Maybe want to remove duplicate constraints + ;; Not removing duplicate AV's from different AVSs in same rep-AVS + + (printf "Copying grammar~n") + + (for-each + (match-lambda + [(old-AVS . rep-AVS) + (for-each + (match-lambda + [(get-nt set-nt!) + (for-each + (match-lambda + [($ rhs* grsym nt*) + (or + ;; Check if already there + (ormap (match-lambda + [($ rhs* + (? (lambda (grsym2) (grsym-eq? grsym grsym2))) + (? (lambda (nt2*) (andmap2 eq-nt? nt* nt2*)))) + #t] + [_ #f]) + (get-nt rep-AVS)) + ;; Add it + (set-nt! rep-AVS + (cons (make-rhs* + grsym + (map old-nt->nt nt*)) + (get-nt rep-AVS))))]) + (get-nt old-AVS))]) + (list (list AVS-L set-AVS-L!) + (list AVS-LI set-AVS-LI!) + (list AVS-U set-AVS-U!) + (list AVS-UI set-AVS-UI!)))]) + list-rep-AVS) + + ;; Done, return mapping + old-nt->nt))) + +; ---------------------------------------------------------------------- + +(define (make-minimization-algorithm table-builder-helper) + (lambda (list-nt roots final) + (match-let* + ([(num-NT NT->num num->NT) (calc-NT<->num list-nt)] + [table-leq (make-vector (* num-NT num-NT) (lambda () (void)))] + ;; table-leq[x][y] = #f => not(x<=y) + ;; otherwise a thunk to perform if not(x<=y) + [NT->rep-NT (make-vector num-NT)] + [list-rep-NT '()]) + (letrec + ([lookup (lambda (x y) (vector-ref table-leq (+ (* num-NT x) y)))] + [set-table-leq! + (lambda (x y v) (vector-set! table-leq (+ (* num-NT x) y) v))] + + [record-not-leq + (lambda (x y) + '(pretty-print + `(record-not-leq ,(nt->sym (num->NT x)) + ,(nt->sym (num->NT y)))) + (when (not (= x y)) + (match (lookup x y) + [#f (void)] + [thunk + (set-table-leq! x y #f) + (thunk)])))] + + [record-not-leq-action + (lambda (d-p d-q thunk) + '(pretty-print + `(record-not-leq-action ,(nt->sym (num->NT d-p)) + ,(nt->sym (num->NT d-q)))) + (unless (eq? d-p d-q) + (match (lookup d-p d-q) + [#f (thunk)] + [entry (set-table-leq! d-p d-q + (lambda () (thunk) (entry)))])))] + + [epsilon-close (make-vector num-NT #f)] + [nt->grsym->fields (make-vector num-NT #f)]) + + (printf "Calculating epsilon-close~n") + (for i 0 num-NT + (vector-set! epsilon-close i + (epsilon-close-nt (num->NT i)))) + + (printf "Calculating (x,c) -> { z* | x ->* y, y->c(z*) }~n") + (for i 0 num-NT + (let* ([alist '()]) + (for-each-prods-joined + (lambda (grsym nt**) + '(printf "nt ~s grsym ~a nt** ~s~n" + (nt->sym (num->NT i)) + (grsym->rep grsym) + nt**) + (set! alist (cons (cons grsym nt**) alist))) + (epsilon-close-nt (num->NT i))) + (vector-set! nt->grsym->fields i alist))) + + (printf "Marking final NT's as distinct~n") + (for-each + (lambda (f) + (let ([n-f (NT->num f)]) + (when n-f + (for i 0 num-NT + (unless (= n-f i) + (record-not-leq n-f i) + (record-not-leq i n-f)))))) + final) + + (printf "Filling not-leq table, num-NT=~s~n" num-NT) + ;; Fill out table-leq + (for i 0 num-NT + ;;(printf "i ~s ~s~n" i (nt->sym (num->NT i))) + (when (zero? (modulo i 25)) (printf ".") (flush-output)) + (for-each-prods + (match-lambda + [($ rhs* (or '>=epsilon '<=epsilon) (nt)) + (for j 0 num-NT + (record-not-leq-action + (NT->num nt) j + (lambda () (record-not-leq i j))))] + [($ rhs* grsym nt*) + (for j 0 num-NT + '(printf "i ~s j ~s grsym ~s nt ~s ~s ~n" + (nt->sym (num->NT i)) + (nt->sym (num->NT j)) + grsym + (map nt->sym nt*) + (map NT->num nt*)) + (unless (= i j) + (let* ([nt** (or (ormap + (match-lambda + [(grsym2 . nt**) + (if (grsym-eq? grsym grsym2) + nt** + #f)]) + (vector-ref nt->grsym->fields j)) + '())] + [n (length nt**)]) + '(printf "i ~s grsym ~a j ~s nt** ~s~n" + (nt->sym (num->NT i)) + (grsym->rep grsym) + (nt->sym (num->NT j)) + nt**) + (cond + [(zero? n) (record-not-leq i j)] + [(null? nt*) ; is a terminal + (void)] + [else + (table-builder-helper + i j nt* nt** n NT->num + record-not-leq record-not-leq-action)]))))]) + (num->NT i))) + (newline) + + '(begin + (display (map (lambda (x) (if x #t #f)) (vector->list table-leq))) + (newline) + (for-each + (lambda (nt1) + (for-each + (lambda (nt2) + (when (and (not (eq? nt1 nt2)) + (same-nt-type? nt1 nt2) + (lookup (NT->num nt1) (NT->num nt2))) + (printf "~s <= ~s~n" (nt->sym nt1) (nt->sym nt2)))) + list-nt)) + list-nt) + (newline)) + + ;; Apply the equivalence relation + (printf "Applying the eqv rel~n") + (apply-equivalence-relation + list-nt + num-NT NT->num num->NT + (lambda (i j) + (let ([num-i (NT->num i)] + [num-j (NT->num j)]) + (cond + [(and (not num-i) (not num-j)) #t] + [(or (not num-i) (not num-j)) #f] + [else (lookup (NT->num i) (NT->num j))])))))))) + +; ---------------------------------------------------------------------- + +(define (DFA-min list-nt roots final) + (printf "Calculating min DFA~n") + ((make-minimization-algorithm + (lambda (i j nt* nt** n NT->num record-not-leq record-not-leq-action) + ;; i -> c(nt*) + ;; j -> c(nt*) forall nt* in nt** + (for-each + (lambda (nt*2) + (for-each + (lambda (nt nt2) + (record-not-leq-action (NT->num nt) (NT->num nt2) + (lambda () (record-not-leq i j)))) + nt* nt*2)) + nt**))) + list-nt roots final)) + +(define (NFA-min list-nt roots final) + (printf "Calculating min NFA~n") + ((make-minimization-algorithm + (lambda (i j nt* nt** n NT->num record-not-leq record-not-leq-action) + ;; i -> c(nt*) + ;; j -> c(nt*) forall nt* in nt** + (recur loop ([nt* nt*][nt** nt**]) + (unless (null? nt*) + (let* ([f (car nt*)] + [f* (map car nt**)] + [c n] + [fn (lambda () + (set! c (sub1 c)) + (when (zero? c) (record-not-leq i j)))]) + (for-each + (lambda (f2) + (record-not-leq-action (NT->num f) (NT->num f2) fn)) + f*) + (loop (cdr nt*) (map cdr nt**))))))) + list-nt roots final)) + +(define (RTG-min list-nt roots final) + (printf "Calculating min NFA~n") + ((make-minimization-algorithm + (lambda (i j nt* nt** n NT->num record-not-leq record-not-leq-action) + ;; i -> c(nt*) + ;; j -> c(nt*) forall nt* in nt** + (let ([c n]) + (for-each + (lambda (nt*2) + (let ([nt*2-done #f]) + (for-each + (lambda (nt nt2) + (record-not-leq-action + (NT->num nt) + (NT->num nt2) + (lambda () + (unless nt*2-done + (set! nt*2-done #t) + (set! c (sub1 c)) + (when (zero? c) (record-not-leq i j)))))) + nt* nt*2))) + nt**)))) + list-nt roots final)) + +; ======================================================================; +; N->D section +; ======================================================================; + +(define (N->D roots final tidy?) + ;; n is an old nt + ;; d is new nt + (printf "Calculating N->D~n") + (letrec + ([n*->d '()] ; Maps set of NFA nts to a DFA nt + [n*<= + (lambda (n1* n2*) + (andmap (lambda (n1) (mem-nt? n1 n2*)) n1*))] + [n*= + (lambda (n1* n2*) + (and (n*<= n1* n2*) (n*<= n2* n1*)))] + [lookup + (lambda (n*) + (recur loop ([l n*->d]) + (cond + [(null? l) #f] + [(n*= n* (caar l)) (cdar l)] + [else (loop (cdr l))])))] + [AVS->nu-AVS ; Use same d for L-AVS and U-AVS + (let ([l '()]) + (lambda (AVS) + (match (assq AVS l) + [(_ . nuAVS) nuAVS] + [#f (let ([nuAVS (mk-AVS-nolist 'dfa-nuAVS)]) + (set! l (cons (cons AVS nuAVS) l)) + nuAVS)])))] + [make-d-for-nt* + (match-lambda + [(($ L x)) (make-L (AVS->nu-AVS x))] + [(($ U x)) (make-U (AVS->nu-AVS x))] + [(($ L _) ...) (make-L (mk-AVS-nolist 'dfa-L))] + [(($ U _) ...) (make-U (mk-AVS-nolist 'dfa-U))])] + [count 0] + [traverse + (lambda (n*) + (when (zero? (modulo count 25)) (printf ".") (flush-output)) + (set! count (add1 count)) + (let* ([n* (epsilon-close-nts n*)] + [n*-noI (map drop-I n*)]) + '(pretty-print `(traverse ,(map nt->sym n*))) + (or (lookup n*-noI) + ;; Need to traverse + ;; assume n* epsilon-closed + (let* ([d (make-d-for-nt* n*-noI)]) + (set! n*->d (cons (cons n*-noI d) n*->d)) + (for-each-prods-joined + (lambda (grsym nt**) + (if (and (not tidy?) + (not (null? nt**)) + (not (null? (car nt**))) + (not (null? (cdar nt**)))) + ;; Don't want to tidy multi-arity constructor + (for-each + (lambda (nt*) + (add-prod d grsym + (map (lambda (nt) (traverse (list nt))) + nt*))) + nt**) + ;; Yeah, tidy it + (recur loop ([nt** nt**][d* '()]) + (match nt** + [(() ...) + ;; All done - add the resulting production + (add-prod d grsym (reverse d*))] + [((nt* . nt**) ...) + ;; nt* is all nts for a particular field + (loop nt** (cons (traverse nt*) d*))])))) + n*) + d))))]) + + (for-each (lambda (nt) (traverse (list nt))) + roots) + (newline) + + '(begin + (printf "Table:~n") + (pretty-print + (map (match-lambda + [(n* . d) (cons (map nt->sym n*) (nt->sym d))]) + n*->d))) + + (printf "Calculating new roots, final~n") + ;; Return new roots, and nu final + (list + ;; new roots + (map (lambda (nt) (lookup (map drop-I (epsilon-close-nt nt)))) + roots) + ;; new final + (map (lambda (nt) + (let* ([nt-noI (drop-I nt)] + [nu-nt (make-d-for-nt* (list nt-noI))]) + (for-each + (match-lambda + [(n* . d) + (when (mem-nt? nt-noI n*) + (add-prod d + (match d + [($ L) '>=epsilon] + [($ U) '<=epsilon]) + (list nu-nt)))]) + n*->d) + nu-nt)) + final)))) + +;; ====================================================================== +;; A series of composable grammar manipulation stages +;; Each takes and returns (roots final list-NT list-AVS . rest) +;; May just return (roots final) + +(define (stage-restrict-reached roots final list-NT list-AVS) + (printf "Calculating reached~n") + (match-let* + ([(reached-nt reached-nt?) (grammar-calc-reached roots)]) + (printf "Restricting NTs~n") + (restrict-nts! list-AVS reached-nt?) + ;;(display (map nt->sym reached-nt)) (newline) + ;;(st:prods) + ;;(newline) + (list roots final reached-nt list-AVS))) + +(define (stage-restrict-nonempty roots final list-NT list-AVS) + (match-let* + ([_ (printf "Calculating NT<->num~n")] + [(num-NT NT->num num->NT) (calc-NT<->num list-NT)] + [_ (printf "Calculating nonempty~n")] + [(nonempty-nt nonempty-nt?) + (grammar-calc-nonempty num-NT NT->num num->NT final)]) + (printf "Restricting NTs~n") + (restrict-nts! list-AVS nonempty-nt?) + ;;(display (map nt->sym nonempty-nt)) (newline) + ;;(st:prods) + ;;(newline) + (list roots final nonempty-nt list-AVS))) + +(define (stage-N->D roots final list-NT list-AVS) + (match-let* + ([(nuroots nufinal) (N->D roots final #t)]) + (list nuroots nufinal))) + +(define (stage-N->D-notidy roots final list-NT list-AVS) + (match-let* + ([(nuroots nufinal) (N->D roots final #f)]) + (list nuroots nufinal))) + +(define (stage-DFA-min roots final list-NT list-AVS) + (match-let* + ([old-nt->nu-nt (DFA-min list-NT roots final)]) + (list (map old-nt->nu-nt roots) + (map old-nt->nu-nt final)))) + +(define (stage-NFA-min roots final list-NT list-AVS) + (match-let* + ([old-nt->nu-nt (NFA-min list-NT roots final)]) + (list (map old-nt->nu-nt roots) + (map old-nt->nu-nt final)))) + +(define (stage-RTG-min roots final list-NT list-AVS) + (match-let* + ([old-nt->nu-nt (NFA-min list-NT roots final)]) + (list (map old-nt->nu-nt roots) + (map old-nt->nu-nt final)))) + +(define (stage-kill-live-AVS roots final list-NT list-AVS) + (for-each + (lambda (AVS) + (set-AVS-edgefrom! AVS '()) + (set-AVS-edgeto! AVS '()) + (set-AVS-objs! AVS '()) + (set-AVS-orig-objs! AVS '()) + (set-AVS-constraints! AVS '())) + list-AVS) + (list roots final)) + +(define (stage-invert-grammar roots final list-NT list-AVS) + (convert-productions-to-AV-etc! list-AVS) + (calc-productions! list-AVS + (lambda (AVS) (memq AVS list-AVS)) + #t + #t #t #t #t + #f #f) + (list (append (map make-LI list-AVS) + (map make-UI list-AVS)) + (map make-UI (select-L roots)))) + +(define (stage-nothing roots final list-NT list-AVS) + (list roots final)) + +(define (calc-roots-final-L->R B list-AVS use-AVS?) + (calc-productions! list-AVS use-AVS? + #t #f + #t #t #t #t + #t #f) + (list (map make-L B) + (append (map make-UI B)))) + +(define (calc-roots-final-LU->center B list-AVS use-AVS?) + (calc-productions! list-AVS use-AVS? + #t + #t #t #t #t + #t #f) + (match-let* + ([L-B (map make-L B)] + [(reached _) (grammar-calc-reached L-B)] + ;[_ (pretty-print `(reached ,(map nt->sym reached)))] + [reached-L (select-L reached)] + ;[_ (pretty-print `(reached-L ,(map name-for-AVS reached-L)))] + [reached-U (select-U reached)] + ;[_ (pretty-print `(reached-U ,(map name-for-AVS reached-U)))] + [cross-over (intersect reached-L reached-U)] + [final (append (map make-L cross-over) + (map make-U cross-over))]) + ;(pretty-print `(cross-over ,(map name-for-AVS cross-over))) + ;(pretty-print `(final ,(map nt->sym final))) + (list L-B final))) + +(define (calc-roots-final-center->out B list-AVS use-AVS?) + (set! zeroary-op-AVS (mk-AVS-tmp 'zeroary-op)) + (calc-productions! list-AVS use-AVS? + #t #t + #t #t #t #t + #f #f) + (match-let* + ([L-B (map make-L B)] + [(reached _) (grammar-calc-reached L-B)] + ;[_ (pretty-print `(reached ,(map nt->sym reached)))] + [reached-L (select-L reached)] + ;[_ (pretty-print `(reached-L ,(map name-for-AVS reached-L)))] + [reached-U (select-U reached)] + ;[_ (pretty-print `(reached-U ,(map name-for-AVS reached-U)))] + [cross-over (intersect reached-L reached-U)] + [roots (append (list (make-UI zeroary-op-AVS)) + (map make-LI cross-over) + (map make-UI cross-over))] + [final (map make-UI B)]) + ;(pretty-print `(cross-over ,(map name-for-AVS cross-over))) + ;(pretty-print `(roots ,(map nt->sym roots))) + ;(pretty-print `(final ,(map nt->sym final))) + (list roots final))) + +(define (calc-roots-final-center->out-concrete-epsilon B list-AVS use-AVS?) + (set! zeroary-op-AVS (mk-AVS-tmp 'zeroary-op)) + (calc-productions! list-AVS use-AVS? + #t #t + #t #t 'concrete #t + #f #f) + (match-let* + ([L-B (map make-L B)] + [(reached _) (grammar-calc-reached L-B)] + ;[_ (pretty-print `(reached ,(map nt->sym reached)))] + [reached-L (select-L reached)] + ;[_ (pretty-print `(reached-L ,(map name-for-AVS reached-L)))] + [reached-U (select-U reached)] + ;[_ (pretty-print `(reached-U ,(map name-for-AVS reached-U)))] + [cross-over (intersect reached-L reached-U)] + [roots (append (list (make-UI zeroary-op-AVS)) + (map make-LI cross-over) + (map make-UI cross-over))] + [final (map make-UI B)]) + ;(pretty-print `(cross-over ,(map name-for-AVS cross-over))) + ;(pretty-print `(roots ,(map nt->sym roots))) + ;(pretty-print `(final ,(map nt->sym final))) + (list roots final))) + + +(define (get-AVS-select-L roots final) (select-L roots)) + +(define (get-AVS-select-LIUI roots final) + (select-UI final)) + +; ---------------------------------------------------------------------- + +(define calc-size + (lambda (str roots) + (match-let* + ([(reached-nt reached-nt?) (grammar-calc-reached roots)] + [reached-AVS (list->set (map nt->AVS reached-nt))]) + (printf "==========> ~a: #nt=~s #AVS=~s~n" + str + (length reached-nt) + (length reached-AVS)) + ;;(printf "~s~n" (map name-for-AVS list-AVS)) + (list reached-nt reached-AVS)))) + +; -------- + +(define resultshow (void)) +(define resultprod (void)) + +(define (minimize-constraints list-AVS use-AVS? B strategy) + + (printf "#### STRATEGY: ~s~n" strategy) + + (match-let* + ([((calc-roots-final get-AVS) . stages) strategy] + [(roots final) ((eval calc-roots-final) B list-AVS use-AVS?)]) + + (recur loop ([roots roots] + [final final] + [rest '()] + [stages stages] + [sizes '()]) + + (match stages + [() + (match-let* + ([(list-NT list-AVS) (calc-size "At end" roots)]) + (printf "Creating AV, constraints, edges from grammar~n") + (convert-productions-to-AV-etc! list-AVS) + (set! resultshow (lambda () (for-each show-AVS list-AVS))) + (set! resultprod (lambda () (for-each prods-AVS list-AVS))) + (list ((eval get-AVS) roots final) + (reverse (cons (list (length list-NT) (length list-AVS)) + sizes))))] + + [(stage . rest-stages) + (match-let* + ([(list-NT list-AVS) + (calc-size (format "Before ~a" stage) roots)]) + (match (apply (eval stage) roots final list-NT list-AVS rest) + [(roots final . _) + (loop roots final '() rest-stages + (cons (list (length list-NT) (length list-AVS)) + sizes))]))])))) + +(define (minimize-all-constraints B stages) + (let ([n num-AVS]) + (minimize-constraints list-AVS + (lambda (AVS) (< (AVS-num AVS) n)) + B stages))) + +; ====================================================================== + +(define (st:L files) + (st:analyze files) + (calc-productions! list-AVS (lambda (AVS) #t) + #t + #t #t #t #t + #t #f)) + +(define (test-min-strategy files strategy) + (printf "TEST-MIN: ~s~n" files) + (st:flow-sensitive #f) + (st:if-split #f) + (match-let* + ([(_ in out) + (parameterize + ([mrspidey:progress-handler (mrspidey:text-progress)] + [mrspidey:error-handler mrspidey:text-error]) + (time (sba-analyze-a-file-in-out (files->file-thunk* files))))] + [io (map cdr (append in out))]) + (for-each display (reverse summary)) + (printf "Orig # AVSs: ~s~n" num-AVS) + (for-each + (match-lambda + [(sym . AVS) + (printf "Def: ~s, AVS-num=~s~n" sym (AVS-num AVS)) + (pretty-print (AVS->SDL AVS))]) + out) + (match-let + ([(nu-defs . sizes) (time (minimize-all-constraints io strategy))]) + + (printf "~n=========== Summary of final types =========~n") + (for-each (lambda (AVS) + (printf "AVS-num=~s~n" (AVS-num AVS)) + (pretty-print (AVS->SDL AVS))) + nu-defs) + sizes))) + + +(define (test-min files) (test-min-strategy files default-strategy)) + +; ====================================================================== + +(define (to) (test-min "test/one.ss")) +(define (ts) (test-min "test/sum.ss")) +(define (tt) (test-min "test/test.ss")) + +(define test-files + (map (lambda (s) (string-append "mod/" s ".ss")) + '( + "TC-env" + "TC-parse" + "TC-test" + "TC-type" + "TC-eval" + + "mod-env" + "2-1-env-list" + "2-22-p" + "2-22-tc2" + "mod-TC-typechk" + "shaft" + "physics" + "mod-gauss" + ;;"mod-TC-parse" + ;;"pcf-parse" + ))) + +; mod-interp - match +; pcf-tc.ss - syntax error +; mod-pp - match +; "elevator" - match +; mod-slatex.ss - too big +; mod-TC.ss - too big + +; ====================================================================== + +(define strategy-L->R-NFA-min + '((calc-roots-final-L->R get-AVS-select-L) + stage-restrict-reached + stage-restrict-nonempty + ;;stage-kill-live-AVS + stage-N->D-notidy + stage-NFA-min)) + +(define strategy-L->R-RTG-min + '((calc-roots-final-L->R get-AVS-select-L) + stage-restrict-reached + stage-restrict-nonempty + ;;stage-kill-live-AVS + ;;stage-N->D + stage-RTG-min)) + +(define strategy-fast + '((calc-roots-final-center->out-concrete-epsilon get-AVS-select-LIUI) + stage-restrict-reached + stage-restrict-nonempty + ;;stage-kill-live-AVS + ;stage-N->D-notidy + ;stage-RTG-min + stage-DFA-min + )) + +(define default-strategy + '((calc-roots-final-L->R get-AVS-select-L) + ;;stage-restrict-reached + ;;stage-restrict-nonempty + ;;stage-kill-live-AVS + ;;stage-N->D + ;;stage-RTG-min + )) +;(define default-strategy strategy-fast) + +(define strategy-options + '(((calc-roots-final-L->R get-AVS-select-L) + (calc-roots-final-center->out get-AVS-select-LIUI) + ) + stage-restrict-reached + stage-restrict-nonempty + (stage-N->D stage-N->D-notidy stage-nothing) + (stage-RTG-min stage-NFA-min stage-DFA-min stage-nothing) + )) + +(define strategy-options + '(((calc-roots-final-center->out-concrete-epsilon get-AVS-select-LIUI) + (calc-roots-final-L->R get-AVS-select-L) + (calc-roots-final-center->out get-AVS-select-LIUI) + ) + stage-restrict-reached + stage-restrict-nonempty + (stage-DFA-min stage-RTG-min stage-NFA-min stage-nothing) + )) + +(define test-strategies + (recur loop ([opt strategy-options]) + (match opt + [() '(())] + [((? pair? opt1) . rest) + (let ([rest (loop rest)]) + (apply append + (map (lambda (r) + (map (lambda (o) (cons o r)) opt1)) + rest)))] + [(x . rest) (map (lambda (r) (cons x r)) + (loop rest))]))) + +; ====================================================================== + +(define (test-min-files) + (mapLR + (lambda (file) + (printf "============================================================~n") + (let ([r (test-min file)]) + (pretty-print r) + r)) + test-files)) + +(define (test-min-strategies) + (map (lambda (s) + (printf "#########################################################~n") + (set! default-strategy s) + (list s (test-min-files))) + test-strategies)) + +;(trace NFA-min) +;(trace calc-LI-UI!) +;(trace make-minimization-algorithm) +;(trace minimize-constraints) +;(trace grammar-calc-nonempty) + +(define (summarize l) + (map + (match-lambda + [(desc nums) + (let ([last-pairs (map (lambda (x) (rac (car x))) nums)]) + (list desc + (apply + (map car last-pairs)) + (apply + (map cadr last-pairs))))]) + l)) diff --git a/collects/mrspidey/Sba/min/hopcroft.ss b/collects/mrspidey/Sba/min/hopcroft.ss new file mode 100644 index 0000000..8951f77 --- /dev/null +++ b/collects/mrspidey/Sba/min/hopcroft.ss @@ -0,0 +1,246 @@ +;; dfa-min.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ====================================================================== +;; CHANGES +;; 01.11.96: Commented out hack to put all partitions on worklist initially +;; ====================================================================== + +(define-typed-structure state-aux (eqvcl prev next touched)) +(define-typed-structure dfa-eqvcl (states count on-worklist touched)) + +;(define inv-delta-traversal-timer (make-timer)) +;(define Fn-a-timer (make-timer)) +;(define finish-a-timer (make-timer)) + +;; ====================================================================== + +(define (Hopcroft-calc-equivalences States seperate + inv-delta-traversal + state-aux set-state-aux! state->rep) + + ;; states must have an aux field with set-state-aux! and state-aux fns + ;; seperate is a list of list of States + ;; any partition must be included in some element of seperate + + ;; inv-delta-traversal: P(states) (Sigma P(states) -> void) -> void + ;; inv-delta-traversal(X, Fn) + ;; => Fn is called with all pairs (a,C) where C = { s | delta(s,sigma) in X} + + (pretty-debug-dfa-min + `(States ,(map state->rep States))) + (pretty-debug-dfa-min + `(seperate ,(map (lambda (c) (map state->rep c)) seperate))) + + (for-each + (lambda (s) (set-state-aux! s (make-state-aux (void) (void) (void) #f))) + States) + + (for-each + (lambda (c) + (for-each + (lambda (s) (assert (state-aux? (state-aux s)) 1 (state->rep s))) + c)) + seperate) + + (let* + ( [t (lambda (s) + (when timing-min (min-record-progress (cons 'hopcroft s))))] + [_ (t 0)] + [state-prev (lambda (s) (state-aux-prev (state-aux s)))] + [state-next (lambda (s) (state-aux-next (state-aux s)))] + [state-eqvcl (lambda (s) (state-aux-eqvcl (state-aux s)))] + [state-touched (lambda (s) (state-aux-touched (state-aux s)))] + [set-state-prev! (lambda (s p) (set-state-aux-prev! (state-aux s) p))] + [set-state-next! (lambda (s p) (set-state-aux-next! (state-aux s) p))] + [set-state-eqvcl! (lambda (s p) (set-state-aux-eqvcl! (state-aux s) p))] + [set-state-touched! + (lambda (s p) (set-state-aux-touched! (state-aux s) p))] + + [partition '()] + [mk-empty-eqvcl + (lambda () + (let ([X (make-dfa-eqvcl '() 0 #f '())]) + (set! partition (cons X partition)) + X))] + + [add-to-eqvcl! + (lambda (X s) + (let ([first (dfa-eqvcl-states X)]) + (set-state-next! s first) + (unless (null? first) (set-state-prev! first s)) + (set-dfa-eqvcl-states! X s) + (set-state-prev! s X) + (set-state-eqvcl! s X) + (set-dfa-eqvcl-count! X (add1 (dfa-eqvcl-count X)))))] + [remove-from-eqvcl! + (lambda (X s) + (assert (eq? (state-eqvcl s) X)) + (let ([prev (state-prev s)] + [next (state-next s)]) + (unless (null? next) (set-state-prev! next prev)) + (if (dfa-eqvcl? prev) + (set-dfa-eqvcl-states! prev next) + (set-state-next! prev next)) + (set-dfa-eqvcl-count! X (sub1 (dfa-eqvcl-count X)))))] + [eqvcl->list + (lambda (c) + (recur loop ([state (dfa-eqvcl-states c)]) + (if (null? state) + '() + (cons state (loop (state-next state))))))] + + [worklist '()] + [add-to-worklist! + (lambda (X) + (assert (not (dfa-eqvcl-on-worklist X))) + (set! worklist (cons X worklist)) + (set-dfa-eqvcl-on-worklist! X #t))] + + [split + (lambda (generate-split-states) + + ;; Change so each partition totally included or excluded in states + ;; See Cliff Click's thesis, page ~40. + + (pretty-debug-dfa-min `(split)) + + (let* ([touched '()]) + (begin0 + (generate-split-states + (lambda (s) + (pretty-debug-dfa-min + `(add-split ,(state->rep s) ,(state-aux s))) + (assert (state-aux? (state-aux s)) + 2 (state->rep s) (state-aux s)) + (let* ([s-eqvcl (state-eqvcl s)]) + (when (null? (dfa-eqvcl-touched s-eqvcl)) + (set! touched (cons s-eqvcl touched)) + (assert (not (state-touched s)))) + (unless (state-touched s) + ;;(assert (not (memq s (dfa-eqvcl-touched s-eqvcl)))) + (set-dfa-eqvcl-touched! + s-eqvcl + (cons s (dfa-eqvcl-touched s-eqvcl))) + (set-state-touched! s #t))))) + (for-each + (lambda (Z) + + (pretty-debug-dfa-min + `(touched + ,(map state->rep (eqvcl->list Z)) + ,(map state->rep (dfa-eqvcl-touched Z)) + ,(= (dfa-eqvcl-count Z) + (length (dfa-eqvcl-touched Z))))) + (if (= (dfa-eqvcl-count Z) + (length (dfa-eqvcl-touched Z))) + + ;; No need to change, just clear touched + (for-each (lambda (s) (set-state-touched! s #f)) + (dfa-eqvcl-touched Z)) + + ;; Need to make new eqvcl + (let ([nu (mk-empty-eqvcl)]) + ;;(printf ".") (flush-output) + (for-each + (lambda (s) + (remove-from-eqvcl! Z s) + (set-state-touched! s #f) + (add-to-eqvcl! nu s)) + (dfa-eqvcl-touched Z)) + (assert (not (null? (dfa-eqvcl-states Z)))) + (assert (not (null? (dfa-eqvcl-states nu)))) + (cond + [(dfa-eqvcl-on-worklist Z) + (add-to-worklist! nu)] + [(< (dfa-eqvcl-count nu) (dfa-eqvcl-count Z)) + (add-to-worklist! nu) + ;; Kludge cause not complete grammar + (add-to-worklist! Z) + ] + [else + (add-to-worklist! Z) + ;; Kludge cause not complete grammar + (add-to-worklist! nu) + ]))) + (set-dfa-eqvcl-touched! Z '())) + touched))))]) + + (t 1) + (let ([base-eqvcl (mk-empty-eqvcl)]) + (for-each (lambda (s) (add-to-eqvcl! base-eqvcl s)) + States)) + + (t 2) + (for-each + (lambda (nts) (split (lambda (add-split!) (for-each add-split! nts)))) + seperate) + + + (t 3) + ;; ### HACK ### + ;; Put all partitions on the worklist + '(for-each + (lambda (eqvcl) + (unless (dfa-eqvcl-on-worklist eqvcl) + (add-to-worklist! eqvcl))) + partition) + ;; ### END HACK ### + + (t 4) + (recur loop () + ;; partition a partition of States union Final + ;; All equiv states in same eqvcl + ;; If s1,s2 in eqvcl B with si->a.si', and si' in Bi + ;; then either B1=B2, or (Bi,a) in worklist for one of i=1,2 + + (unless (null? worklist) + (let* ([X (car worklist)]) + (set! worklist (cdr worklist)) + (set-dfa-eqvcl-on-worklist! X #f) + (inv-delta-traversal (eqvcl->list X) split) + (loop)))) + (t 5) + + ;; All done + ;; Return mapping from states to representative states, + ;; and a mapping from states to a list of equiv states + ;; and an equiv predicate on states + ;; and a list of representative states + + (values + (lambda (s) (dfa-eqvcl-states (state-eqvcl s))) + (lambda (s) (eqvcl->list (state-eqvcl s))) + (lambda (s1 s2) (eq? (state-eqvcl s1) (state-eqvcl s2))) + (filter-map (lambda (X) + (let ([rep (dfa-eqvcl-states X)]) + (if (null? rep) #f rep))) + partition)))) + +;; ---------------------------------------------------------------------- +;; Prototypical inputs + +'(define-type dfa-state (box void)) +'(MrSpidey-test + (calc-equivalences (type: (listof dfa-state)) + (type: (listof dfa-state)) + (type: (_ (-> (list (dfa-state -> void) (-> void))) + -> void)) + unbox + set-box!)) +;(trace calc-equivalences) + diff --git a/collects/mrspidey/Sba/min/livefewe.ss b/collects/mrspidey/Sba/min/livefewe.ss new file mode 100644 index 0000000..73160b4 --- /dev/null +++ b/collects/mrspidey/Sba/min/livefewe.ss @@ -0,0 +1,215 @@ +;; File: min-live-few-e.ss +;; Can optimize later when sure only want min-live-few-e-L +;; ====================================================================== +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; CHANGES: +;; +;; (null? (Tvar-constraints tvar)) +;; -> (andmap con-filter? (Tvar-constraints tvar)) +;; +;; rhs-nts not filter w/ live-nt? +;; +;; ====================================================================== +(define-typed-structure Tvar-class (parent L-unif U-unif children)) + +;; tvars is binary tree w/ tvar at leaves + +; ====================================================================== +; minimize-constraints-live-few-e +; +; Input: lower : list Tvar +; upper : list Tvar + +(define (copy-live-constraints-few-e L-unif U-unif) + (lambda (lower upper) + + (pretty-debug-few + `(copy-live-constraints-few-e + lower ,(map Tvar-name lower) + upper ,(map Tvar-name upper))) + + ;; Calc edgefrom + ;; Calculate live Tvar and live NT + ;; Only use Tvar-orig-objs + ;; Flag NTs with non-epsilon edges + + (let*-vals + ( [t (lambda (s) + (when timing-min + (min-record-progress (cons 'copy-live-constraints-few-e s))))] + [_ (t 0)] + + ;; --- Calc empty and live + ;; not empty == reached + [(live-nts live-nt? live-tvars live-tvar? _ _ rhs-nts) + (calc-live-tvars-nts lower upper #f)] + [_ (t 1)] + [_ (pretty-debug-few `(live-nts ,(map nt->sym live-nts)))] + [_ (pretty-debug-few `(live-tvars ,(map Tvar-name live-tvars)))] + [rhs-nts + (lambda (nt) + (filter (lambda (x) (or (eq? x #t) (live-nt? x))) (rhs-nts nt)))] + + ;; Now unify to equiv classes. + ;; Define AV `a' to be L-unifiable iff + ;; con(a) = 0 and + ;; #outedge(a)=1 and + ;; # prods for LaU = 1 + ;; But aU -> bU is not counted in rhs-nts(aU) + ;; => require rhs-nts(aU) = 0 + ;; + ;; Define AV `b' to be U-unifiable iff + ;; AV(a) = AV(b) for all predecessors a of b + ;; #inedge(b)<=1 and + ;; # prods for LbL = 1 + ;; + ;; If a <= b and either a L-unif or b U-unif, then unify + + ;; Unify to equivalence classes + [(tvar-class set-tvar-class!) (alloc-Tvar-field)] + [_ (t 3)] + [_ (for-each + (lambda (tvar) + (pretty-debug-few `(Tvar ,(Tvar-name tvar))) + (let* ([pretty-and + (lambda args + (let ([r (andmap (lambda (x) x) args)]) + (pretty-debug-few `((and ,@args) ,r)) + r))] + [L-u (pretty-and + L-unif + (andmap + (match-lambda + [($ con _ _ _ tvar) (not (live-tvar? tvar))] + [($ con-filter) #t]) + (Tvar-constraints tvar)) + (let ([out + (append + (filter-map + (match-lambda + [($ con) #f] + [($ con-filter _ _ tvar) + (and (live-tvar? tvar) tvar)]) + (Tvar-constraints tvar)) + (filter live-tvar? + (Tvar-edgeto tvar)))]) + (or (null? out) (null? (cdr out)))) + (let ([nt (Tvar-U tvar)]) + (or (not (live-nt? nt)) + (let ([s (rhs-nts nt)]) + (pretty-debug-few + `(rhs-nts + ,(map + (lambda (nt) + (or (eq? nt #t) (nt->sym nt))) + s))) + (null? s) + ;;(or (null? s) (null? (cdr s))) + ))) + ; Ignore lower, upper + ; Already counted in rhs-nts + ;(not (memq tvar lower)) + ;(not (memq tvar upper)) + )] + [U-u + (let ( [in (Tvar-edgefrom tvar)]) + (pretty-and + U-unif + (or (null? in) + (and (null? (cdr in)) + (<= (length (Tvar-objs tvar)) + (length (Tvar-objs (car in)))))) + (let ([nt (Tvar-L tvar)]) + (or (not (live-nt? nt)) + (let ([s (rhs-nts nt)]) + (pretty-debug-few + `(rhs-nts + ,(map + (lambda (nt) + (or (eq? nt #t) (nt->sym nt))) + s))) + (or (null? s) (null? (cdr s))) + ))) + ;(not (memq tvar lower)) + ;(not (memq tvar upper)) + ))]) + + (set-tvar-class! tvar (make-Tvar-class #f L-u U-u tvar)))) + live-tvars)] + [_ (t 4)] + [get-class + (lambda (tvar) + (recur loop ([c (tvar-class tvar)]) + (assert (or (Tvar-class? (Tvar-class-parent c)) + (eq? #f (Tvar-class-parent c)))) + (if (Tvar-class-parent c) + (loop (Tvar-class-parent c)) + c)))] + [_ (for-each + (lambda (b) + (for-each + (lambda (a) + (when (live-tvar? a) + (match (get-class a) + [(and cl-a + ($ Tvar-class _ L-unif-a U-unif-a kids-a)) + (assert (eq? (Tvar-class-parent cl-a) #f) + (Tvar-class-parent cl-a)) + (match (get-class b) + [(and cl-b + ($ Tvar-class _ L-unif-b U-unif-b kids-b)) + (pretty-debug-few + `(epsilon ,(Tvar-name a) + ,(Tvar-name b) + ,L-unif-a + ,L-unif-b + ,U-unif-a + ,U-unif-b)) + (when (or L-unif-a U-unif-b) + ;; Unify + (let ([nu-cl + (make-Tvar-class #f + (and L-unif-a L-unif-b) + (and U-unif-a U-unif-b) + (cons kids-a kids-b))]) + + (assert (eq? (Tvar-class-parent cl-a) #f) 2) + (assert (eq? (Tvar-class-parent cl-b) #f)) + (set-Tvar-class-parent! cl-a nu-cl) + (set-Tvar-class-parent! cl-b nu-cl) + (assert (eq? (get-class a) (get-class b))) + ))])]))) + (Tvar-edgefrom b))) + live-tvars)] + [_ (t 4.5)] + ) + ;; --- Have equiv classes, now copy + ;; --- return arguments for copy-constraints-equiv! + (values + (append lower upper live-tvars) + live-tvar? + live-nts + (lambda (tvar) + (recur loop ([k (Tvar-class-children (get-class tvar))][a '()]) + (if (Tvar? k) + (cons k a) + (loop (car k) (loop (cdr k) a))))) + (lambda (AV) (list AV)))))) + +;; ====================================================================== + diff --git a/collects/mrspidey/Sba/min/min-dfa.ss b/collects/mrspidey/Sba/min/min-dfa.ss new file mode 100644 index 0000000..07e28e3 --- /dev/null +++ b/collects/mrspidey/Sba/min/min-dfa.ss @@ -0,0 +1,490 @@ +; ====================================================================== +; minimize-constraints-dfa-min-fast +; +; Input: lower : list Tvar +; upper : list Tvar +; +; see practical.tex +; ====================================================================== +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define (minimize-constraints-dfa-min-fast + lower upper + helper-fn) + + (pretty-debug-dfa-min + `(minimize-constraints-dfa-min-fast + lower ,(map Tvar-name lower) + upper ,(map Tvar-name upper))) + + (let*-vals + ([t (lambda (s) + (when timing-min + (min-record-progress + (cons 'minimize-constraints-dfa-min-fast s))))] + [_ (t 0)] + + [(live-tvars live-tvar? live-nts tvar->equiv AV->equiv) + ((copy-live-constraints-few-e #t #t) lower upper)] + [_ (t 1)] + + ;; Figure out representative elements for Tvars, + ;; and live AV + [(tvar->rep set-tvar-rep!) (alloc-Tvar-field)] + [(is-rep? add-rep! get-list-rep) (field->set alloc-Tvar-field)] + [(live-AV? set-live-AV! get-live-AVs) (field->set alloc-AV-field)] + [_ (for-each + (lambda (tvar) + (for-each set-live-AV! (get-Tvar-objs tvar)) + (unless (tvar->rep tvar) + (add-rep! tvar) + (for-each + (lambda (eq) (set-tvar-rep! eq tvar)) + (tvar->equiv tvar)) + (assert (tvar->rep tvar)))) + live-tvars)] + [live-AVs (get-live-AVs)] + [rep-tvars (get-list-rep)] + [_ (t 2)] + + ;; states = rep-tvars + live-AVs + dummy-tvar + [dummy-tvar (mk-Tvar 'Grammar-dummy)] + [all-states (append rep-tvars (list dummy-tvar) live-AVs)] + [state->sym (lambda (state) + (cond + [(Tvar? state) (Tvar-name state)] + [(AV? state) (AV->rep state)] + [else (error 'state->sym "Bad state ~s" state)]))] + + [grsym-eq? + (lambda (g1 g2) + ;; (andmap eq? g1 g2) + (recur loop ([g1 g1][g2 g2]) + (if (null? g1) + (null? g2) + (if (null? g2) + #f + (and (eq? (car g1) (car g2)) + (loop (cdr g1) (cdr g2)))))))] + + ;; mapping from grsyms to numbers + [num-grsym 0] + [grsym-table '()] + [grsym->number + (lambda (g1) + (or + (ormap + (match-lambda + [(n . g2) (and (grsym-eq? g1 g2) n)] + [_ #f]) + grsym-table) + (begin + (set! grsym-table (cons (cons num-grsym g1) grsym-table)) + (begin0 + num-grsym + (set! num-grsym (add1 num-grsym))))))] + + [(tvar-EF-epsilon set-tvar-EF-epsilon!) + (alloc-Tvar-field (lambda () '()))] + [(tvar-EF set-tvar-EF!) + (alloc-Tvar-field (lambda () '()))] + [(AV-EF-epsilon set-AV-EF-epsilon!) + (alloc-AV-field (lambda () '()))] + [(AV-EF set-AV-EF!) + (alloc-AV-field (lambda () '()))] + + [add-tvar-EF! + (lambda (tvar g1 s1) + (let* ( [tvar (tvar->rep tvar)] + [n1 (grsym->number g1)] + [x (tvar-EF tvar)]) + (unless (ormap + (match-lambda [(n2 . s2) (and (= n1 n2) (eq? s1 s2))]) + x) + (set-tvar-EF! tvar (cons (cons n1 s1) x)))))] + [add-AV-EF! + (lambda (AV g1 s1) + (let ( [x (AV-EF AV)] + [n1 (grsym->number g1)]) + (unless (ormap + (match-lambda [(n2 . s2) (and (= n1 n1) (eq? s1 s2))]) + x) + (set-AV-EF! AV (cons (cons n1 s1) x)))))] + [add-tvar-EF-epsilon! + (lambda (tvar s1) + (let* ( [tvar (tvar->rep tvar)] + [x (tvar-EF-epsilon tvar)]) + (unless (memq s1 x) + (set-tvar-EF-epsilon! tvar (cons s1 x)))))] + [add-AV-EF-epsilon! + (lambda (AV s1) + (let ([x (AV-EF-epsilon AV)]) + (unless (memq s1 x) + (set-AV-EF-epsilon! AV (cons s1 x)))))] + [state-EF-epsilon + (lambda (state) + (if (AV? state) + (AV-EF-epsilon state) + (tvar-EF-epsilon state)))] + [state-EF + (lambda (state) + (if (AV? state) + (AV-EF state) + (tvar-EF state)))] + [_ (t 2.1)] + + ;; helper-fn sets things up for inv-delta-traversal + ;; Sets U field of each state to: + ;; (listof (cons (listof any) state)) + + [extra-seperate (helper-fn live-tvars live-tvar? tvar->rep live-AVs + add-tvar-EF! add-tvar-EF-epsilon! + add-AV-EF! add-AV-EF-epsilon!)] + [_ (t 3)] + + ;; Show productions + [_ (pretty-debug-dfa-min + `(productions + ,(map + (lambda (state) + (list (state->sym state) + (map state->sym (state-EF-epsilon state)) + (map + (match-lambda [(g . s) (cons g (state->sym s))]) + (state-EF state)))) + all-states)))] + + ;; Vector of buckets for productions + [buckets (make-vector num-grsym '())] + [_ (min-record-progress (cons 'num-buckets num-grsym))] + + ;; inv-delta-traversal: + ;; P(states) x (P(states) -> void) -> void + ;; inv-delta-traversal(X, split) + ;; => no equiv class partially in X + ;; => Call split with each "partition of equiv classes" ... + ;; For effeciency, we call split with a "generator" for the set C_a + ;; The generator is passed a function add-split!, and then + ;; calls add-split! on each state in C_a + + ;; --- Set things up for Hopcrofts Algorithm + + ;; Condition 1, thms hopcroft lub and glb + ;; Also, to make up for grammar being "incomplete", + ;; seperate states into equiv classes so states in same equiv class + ;; have productions on same grammar symbols + + [seperate-grsyms (make-vector num-grsym '())] + [seperate-epsilon '()] + [_ (for-each + (lambda (state) + (when (not (null? (state-EF-epsilon state))) + (set! seperate-epsilon (cons state seperate-epsilon))) + (for-each + (match-lambda + [(g . s) + (vector-set! seperate-grsyms g + (cons s (vector-ref seperate-grsyms g)))]) + (state-EF state))) + all-states)] + [_ (pretty-debug-dfa-min + `(seperate-epsilon ,(map state->sym seperate-epsilon)))] + [_ (pretty-debug-dfa-min + `(seperate-grsyms + ,(map + (lambda (s) (map state->sym s)) + (vector->list seperate-grsyms))))] + [seperate (append + (list rep-tvars) + (list live-AVs) + extra-seperate + ;(map list lower) + ;(map list upper) + (list seperate-epsilon) + (vector->list seperate-grsyms))] + [seperate (filter + (lambda (l) (not (null? l))) + seperate)] + [_ (pretty-debug-dfa-min + `(seperate ,(map (lambda (s) (map state->sym s)) seperate)))] + [_ (t 4)] + + [inv-delta-traversal + (lambda (states split) + (pretty-debug-dfa-min + `(inv-delta-trav + ,(map (lambda (state) + `(,(state->sym state) + (epsilon + ,(map state->sym (state-EF-epsilon state))) + ,(map + (match-lambda [(g . s) (cons g (state->sym s))]) + (state-EF state)))) + states))) + ;; Do epsilons + (split + (lambda (add-split!) + (for-each + (lambda (state) + (for-each + add-split! + (state-EF-epsilon state))) + states))) + + ;; Put rest into buckets + (let ([bucket-ndxs '()]) + (for-each + (lambda (state) + (for-each + (match-lambda + [(n . s) + (let ([old (vector-ref buckets n)]) + (vector-set! buckets n (cons s old)) + (when (null? old) + (set! bucket-ndxs (cons n bucket-ndxs))))]) + (state-EF state))) + states) + ;; Run thru buckets ... + (for-each + (lambda (i) + (let ([s* (vector-ref buckets i)]) + (split (lambda (add-split!) (for-each add-split! s*))) + (vector-set! buckets i '()))) + bucket-ndxs)))] + + [(state-aux set-state-aux!) (alloc-NT-field)] + [(state->rep state->equiv equiv-state? list-rep-states) + (Hopcroft-calc-equivalences + all-states + seperate + inv-delta-traversal + state-aux set-state-aux! state->sym)] + [_ (t 5)] + + [_ (begin + (pretty-debug-dfa-min + `(list-rep-state ,(map state->sym list-rep-states))) + (pretty-debug-dfa-min + `(state->equiv + ,(map (lambda (state) + (map state->sym (state->equiv state))) + list-rep-states))))] + + ;; ---------------------------------------- + ;; Have equivalence relation on states + ;; Combine w/ previous relation on Tvars + ;; Convert to equivalence relation on Tvars + + [tvar->equiv + (lambda (tvar) + (let ([r (apply append (map tvar->equiv (state->equiv tvar)))]) + (pretty-debug-dfa-min + `(tvar->equiv ,(state->sym tvar) = ,(map state->sym r))) + r))] + + [AV->equiv + (lambda (x) + (pretty-debug-dfa-min `(AV->equiv ,(state->sym x))) + (let ([e (state->equiv x)]) + (pretty-debug-dfa-min + `(AV->equiv ,(state->sym x) = ,(map state->sym e))) + e))] + [_ (t 6)]) + + (copy-constraints-equiv! + live-tvars + live-tvar? + live-nts + tvar->equiv + AV->equiv))) + +;; ====================================================================== + +(define (minimize-constraints-dfa-min-lub lower upper) + (minimize-constraints-dfa-min-fast lower upper + + ;; helper-fn + ;; helper-fn sets things up for inv-delta-traversal + ;; Sets U field of each state to: + ;; (listof (cons (listof any) state)) + + (lambda (live-tvars live-tvar? tvar->rep live-AVs + add-tvar-EF! add-tvar-EF-epsilon! + add-AV-EF! add-AV-EF-epsilon!) + + (for-each + (lambda (tvar) + + ;; --- Condition 2 + ;; If [a <= b] => forall a'~a exists b'~b st [a' <= b'] + (for-each + (lambda (from) + (when (live-tvar? from) + (add-tvar-EF-epsilon! tvar (tvar->rep from)))) + (Tvar-edgefrom tvar)) + (for-each + (lambda (AV) (add-tvar-EF-epsilon! tvar AV)) + (get-Tvar-objs tvar)) + + ;; --- Conditions 4 and 5 + (for-each + (match-lambda + [($ con _ template field alpha sign) + (when (live-tvar? alpha) + (if sign + ;; [rng(tvar) <= alpha] + (add-tvar-EF! alpha + (list 'R4 template field) (tvar->rep tvar)) + (when #t ;; (follow-antimono-fields template) + ;; Condition 5 + ;; At bottom we put beta (or tvar) in own equiv class + ;; [alpha <= dom(tvar)] + (add-tvar-EF! tvar + (list 'R5 template field) (tvar->rep alpha)))))] + [_ (void)]) + (Tvar-constraints tvar))) + live-tvars) + + (for-each + (match-lambda + [(and AV ($ AV _ template _ fields+ fields-)) + ;; --- Condition 3 + (for i 0 (vector-length fields+) + (let ([field (vector-ref fields+ i)]) + (when (live-tvar? field) + (add-AV-EF! AV + (list 'R3 template i) (tvar->rep field)))))]) + live-AVs) + + ;; extra partitions + (append + ;; Put each beta st [alpha <= dom(beta)] in separate equiv class + (map list + (map tvar->rep + (filter + (lambda (tvar) + (ormap + (match-lambda + [($ con _ template field alpha #f) + (live-tvar? alpha)] + [_ #f]) + (Tvar-constraints tvar))) + live-tvars))) + + ;; put AVs into equiv class according to templates + ;; h maps templates to list of AVs + (let ([h (make-hash-table)]) + (for-each + (lambda (AV) + (let ([t (AV-template AV)]) + (hash-table-put! h t + (cons AV (hash-table-get h t (lambda () ())))))) + live-AVs) + (hash-table-map h + (lambda (t AVs) AVs)))) + + ))) + +;; ====================================================================== + +(define (minimize-constraints-dfa-min-glb lower upper) + (minimize-constraints-dfa-min-fast lower upper + + ;; helper-fn + ;; helper-fn sets things up for inv-delta-traversal + ;; Sets U field of each state to: + ;; (listof (cons (listof any) state)) + + (lambda (live-tvars live-tvar? tvar->rep live-AVs + add-tvar-EF! add-tvar-EF-epsilon! + add-AV-EF! add-AV-EF-epsilon!) + + (for-each + (lambda (tvar) + + ;; --- Condition 2 + ;; If [a <= b] => forall b'~b exists a'~a st [a' <= b'] + (for-each + (lambda (from) + (when (live-tvar? from) + (add-tvar-EF-epsilon! from (tvar->rep tvar)))) + (Tvar-edgefrom tvar)) + (for-each + (lambda (AV) (add-AV-EF-epsilon! AV (tvar->rep tvar))) + (get-Tvar-objs tvar)) + + ;; --- Condition 4 + (for-each + (match-lambda + [($ con _ template field alpha #t) + (when (live-tvar? alpha) + ;; [rng(tvar) <= alpha] + (add-tvar-EF! tvar + (list 'R4 template field) (tvar->rep alpha)))] + [_ (void)]) + (Tvar-constraints tvar))) + live-tvars) + + (for-each + (match-lambda + [(and AV ($ AV _ template _ fields+ fields-)) + ;; --- Condition 3 + (for i 0 (vector-length fields+) + (let ([field (vector-ref fields+ i)]) + (when (live-tvar? field) + (add-tvar-EF! field (list 'R3 template i) AV)))) + ;; --- Condition 5 + (when (follow-antimono-fields template) + (for i 0 (vector-length fields-) + (let ([field (vector-ref fields- i)]) + (when (live-tvar? field) + ;; [dom(AV) <= field] + ;; At bottom we put AV in own equiv class + (add-AV-EF! AV + (list 'R5 template i) (tvar->rep field))))))]) + live-AVs) + + ;; Conditions 5,6, thm 1.2 + ;; extra partitioning + (append + ;; Conditions 5, thm 1.2 + (filter-map + (match-lambda + [(and AV ($ AV _ template _ _ fields-)) + (and + (follow-antimono-fields template) + (> (vector-length fields-) 0) + (list AV))]) + live-AVs) + ;; Conditions 6, thm 1.2 + (let ([h (make-hash-table)]) + (for-each + (match-lambda + [(and AV ($ AV _ template)) + (hash-table-put! h template + (cons AV + (hash-table-get h template (lambda () '()))))]) + live-AVs) + (hash-table-map h + (lambda (template AVs) AVs))))))) + +;; ====================================================================== + + + + diff --git a/collects/mrspidey/Sba/min/min-live.ss b/collects/mrspidey/Sba/min/min-live.ss new file mode 100644 index 0000000..ec62c11 --- /dev/null +++ b/collects/mrspidey/Sba/min/min-live.ss @@ -0,0 +1,580 @@ +; ====================================================================== +; copy-live-constraints +; +; Input: lower : list Tvar +; upper : list Tvar +; +; Copies live constraints +; returns list-nu Tvar->nu +; ====================================================================== +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define (copy-live-constraints lower upper) + + (pretty-debug-min + `(copy-live-constraints ,(map Tvar-name lower) ,(map Tvar-name upper))) + + (let*-vals + ( [(live-nts live-nt? live-tvars live-tvar? _ _ _) + (calc-live-tvars-nts lower upper #f)]) + + (copy-constraints-equiv! + (append lower upper live-tvars) + live-tvar? live-nts + (lambda (tvar) (list tvar)) + (lambda (AV) (list AV))))) + +; ====================================================================== + +(define (copy-live-constraints-noe lower upper) + + (pretty-debug-min + `(copy-live-constraints-noe + ,(map Tvar-name lower) ,(map Tvar-name upper))) + + (let*-vals + ( [(live-nts live-nt? live-tvars live-tvar? _ _ _) + (calc-live-tvars-nts lower upper #t)] + [(get-nu-Tvar set-nu-Tvar!) (alloc-Tvar-field)] + [list-nuTvar + (map (lambda (Tvar) + (let ([nu (mk-Tvar 'min-live)]) + (set-nu-Tvar! Tvar nu) + nu)) + live-tvars)] + [dummy-tvars + (copy-constraints-noe! live-tvar? live-nts get-nu-Tvar lower)]) + + (values + (append dummy-tvars list-nuTvar) + get-nu-Tvar))) + +;; ====================================================================== +; calc-live-tvars-nts +; +; Calculates live Tvars and NTs +; Input: lower : list Tvar +; upper : list Tvar +; +; Uses find-nonempty-nts-rhs-nts to find nonempty nts and sources +; Walk "forward" in grammar using rhs-nts from crossover and AV-w/-const +; to calculate live +; +; Returns (values live-nts live-nt? live-tvars live-tvar? +; AV-w/-const crossover rhs-nts) + +(define (calc-live-tvars-nts lower upper inline-epsilon) + + (pretty-debug-min + `(calc-live-tvars-nts ,inline-epsilon + ,(map Tvar-name lower) ,(map Tvar-name upper))) + + (let*-vals + ( [t (lambda (s) + (when timing-min + (min-record-progress (cons 'calc-live-tvars-nts s))))] + [_ (t 0)] + [(rhs-nts crossover AV-w/-const) + (find-nonempty-nts-rhs-nts lower upper inline-epsilon)] + [_ (t 1)] + [(live-nt? set-live-nt! get-live-nts) (field->set alloc-NT-field)] + [_ (t 2)] + + ;; -------------------------------------------------- + ;; Walk forward from crossover and AV-w/-const, recording nts + + [_ (letrec ([mark-live + (lambda (nt) + (unless (eq? nt #t) + ;;(pretty-print `(mark-live ,(nt->sym nt))) + (unless (live-nt? nt) + (set-live-nt! nt) + (when (rhs-nts nt) + (for-each mark-live (rhs-nts nt))))))]) + + (for-each + (lambda (Tvar) + (mark-live (Tvar-U Tvar)) + (mark-live (Tvar-L Tvar))) + crossover) + + (for-each + (lambda (AV) (mark-live (AV-U AV))) + AV-w/-const) + + (pretty-debug-min `(live-nt ,(map nt->sym (get-live-nts)))))] + [_ (t 3)] + + ;; -------------------------------------------------- + ;; Have in (get-live-nts) all nts that are reached and non-empty + ;; Calc live Tvar + + [(live-tvar? set-live-tvar! get-live-tvars) + (field->set alloc-Tvar-field)] + [_ (t 4)] + [_ (begin + (for-each + (match-lambda + [($ NT tvar) (when (Tvar? tvar) (set-live-tvar! tvar))]) + (get-live-nts)) + (for-each set-live-tvar! lower) + (for-each set-live-tvar! upper))] + [_ (t 5)] + [_ (pretty-debug-min `(live-Tvar ,(map Tvar-name (get-live-tvars))))]) + + (pretty-debug-min + `(calc-live-tvars-nts-results + ,(map (lambda (nt) + `(nt-rhs ,(nt->sym nt) + ,(map (lambda (nt) (or (eq? nt #t) (nt->sym nt))) + (rhs-nts nt)))) + (get-live-nts)))) + + (values + (get-live-nts) live-nt? + (get-live-tvars) live-tvar? + AV-w/-const + crossover + rhs-nts + ))) + +;; ====================================================================== + +(define (follow-antimono-fields template) + (or + (eq? template template-lam) + (eq? template template-unit) + (eq? template template-internal-class) + (st:minimize-respect-assignable-part-of-fields))) + +;; ====================================================================== +; find-nonempty-nts-rhs-nts +; +; Calculates non-empty Tvars, NTs. +; For each non-empty NT, finds all rhs-nts NT' such that NT -> x.NT' + +; Input: lower : (listof Tvar) +; upper : (listof Tvar) +; +; Returns (values rhs-nts crossover-tvars AV-w/-const) +; +; Walks "backwards" in grammer to find nonempty NTs +; Keeps track of rhs-nts on the way +; +; crossover is the set of Tvars tvar such that +; both L(tvar_L) and L(tvar_U) are nonempty + +;; #### Always looks at assignable fields ... + +(define (find-nonempty-nts-rhs-nts lower upper inline-epsilon) + (pretty-debug-min + `(find-nonempty-tvars-nts-rhs-nts ,inline-epsilon + ,(map Tvar-name lower) ,(map Tvar-name upper))) + + (let*-vals ( [(reached-tvar? set-reached-tvar!) (alloc-Tvar-field)] + [(reached-AV? set-reached-AV!) (alloc-AV-field)] + [(rhs-nts set-rhs-nts!) (alloc-NT-field)] + [add-rhs-nt! + (lambda (nt src) (set-rhs-nts! nt (cons src (rhs-nts nt))))] + [crossover '()] + ;; crossover is set of tvars with tvar_L and tvar_U nonempty + [AV-w/-const '()] + ) + (letrec + ( [add-crossover! + (lambda (tvar) + (set! crossover (cons tvar crossover)))] + [walk-AV + (lambda (AV src) + (pretty-debug-min `(walk-AV ,(AV-num AV) ,(nt->sym src))) + (if (reached-AV? AV) + (add-rhs-nt! (AV-U AV) src) + ;; Walk it + (begin + (set-reached-AV! AV #t) + (mk-AV-NTs! AV) + (let ([nt (AV-U AV)]) + (set-rhs-nts! nt (list src)) + (match AV + [($ AV _ (and template ($ template _ _ _ ref)) + misc fields+ fields-) + (when (or + (zero? (vector-length ref)) + ;; the following are lazy + ;; ie (box empty) = empty + ;; but (empty -> empty) != empty + (eq? template template-lam) + (eq? template template-unit) + (eq? template template-internal-class) + (eq? template template-ivarset) + ) + (set! AV-w/-const (cons AV AV-w/-const))) + (vector-for-each + (lambda (f) (walk-U f nt)) + fields+) + (when (follow-antimono-fields template) + (pretty-debug-min + `(walking-U + ,(eq? template template-lam) + ,(st:minimize-respect-assignable-part-of-fields))) + (vector-for-each + (lambda (f) (walk-L f nt)) + fields-))])))))] + [reach-tvar + (lambda (tvar) + (unless (reached-tvar? tvar) + (set-reached-tvar! tvar #t) + (mk-Tvar-NTs! tvar)))] + [walk-U + (lambda (tvar src) + (let + ([f + (lambda (tvar) + (reach-tvar tvar) + (pretty-debug-min `(walk-U ,(Tvar-name tvar) ,(nt->sym src))) + (let ([nt (Tvar-U tvar)]) + (if (rhs-nts nt) + (add-rhs-nt! nt src) + ;; Walk it + (begin + (set-rhs-nts! nt (list src)) + (when (rhs-nts (Tvar-L tvar)) (add-crossover! tvar)) + (pretty-debug-min `(walk-U ,(Tvar-name tvar))) + (for-each + (lambda (AV) (walk-AV AV nt)) + (get-Tvar-objs tvar)) + '(unless inline-epsilon + (for-each + (lambda (from) + (walk-U from nt)) + (Tvar-edgefrom tvar)))))))]) + + '(if inline-epsilon + ;; really want to walk all tvar2 st tvar2_U -> tvar_U + (for-each f (Tvar-transitive-edgefrom tvar)) + (f tvar)) + (f tvar)))] + + [walk-L + (lambda (tvar src) + (let + ([f (lambda (tvar) + (reach-tvar tvar) + (pretty-debug-min + `(walk-L ,(Tvar-name tvar) ,(nt->sym src))) + (let ([nt (Tvar-L tvar)]) + (if (rhs-nts nt) + (add-rhs-nt! nt src) + ;; Walk it + (begin + (set-rhs-nts! nt (list src)) + (when (rhs-nts (Tvar-U tvar)) (add-crossover! tvar)) + (pretty-debug-min `(walk-L ,(Tvar-name tvar))) + + (unless inline-epsilon + (for-each + (lambda (to) + ;; Have to_L -> tvar_L + (walk-L to nt)) + (Tvar-edgeto tvar))) + (for-each + (match-lambda + [($ con _ _ field-no tvar2 sign misc) + ;; Have tvar2_L -> rng(tvar_L) + ;; or tvar2_U -> dom(tvar_L) + (if sign + (walk-L tvar2 nt) + (walk-U tvar2 nt))] + [($ con-filter _ filter tvar2) + ;; Have tvar2_L -> tvar_L + (unless inline-epsilon (walk-L tvar2 nt))]) + (Tvar-constraints tvar))))))]) + '(if inline-epsilon + ;; really want to walk all tvar2 st tvar2_L -> tvar_L + (for-each f (Tvar-transitive-edgeto tvar)) + (f tvar)) + (f tvar)))]) + + (for-each (lambda (tvar) (walk-U tvar #t)) upper) + (for-each (lambda (tvar) (walk-L tvar #t)) lower) + + (min-record-progress 'find-nonempty-nts-rhs-nts-done) + (: rhs-nts (NT -> (union NT true))) + + (pretty-debug-min + `(find-nonempty-nts-rhs-nts-returns + ,(map AV-num AV-w/-const) + ,(map Tvar-name crossover))) + + (values + (lambda (nt) + (let ([r (rhs-nts nt)]) + (pretty-debug-min + `(rhs-nts ,(nt->sym nt) + ,(map (lambda (nt) (or (eq? nt #t) (nt->sym nt))) r))) + r)) + crossover + AV-w/-const)))) + +;; ====================================================================== +; copy-constraints! +; +; tvar->equiv and AV->equiv describe an equivalence relation on tvars and AVs +; +; Copies the contents of a set of Tvars +; Takes care not to duplicate AVs +; returns (values nu-tvars tvar->nu-tvar) +; live-tvars should include lower and upper, and may contain duplicates + +(define (copy-constraints-equiv! + live-tvars live-tvar? live-nts + tvar->equiv AV->equiv) + + (pretty-debug-min `(copy-constraints-equiv! ,(map nt->sym live-nts))) + (let*-vals + ( [t (lambda (s) + (when timing-min + (min-record-progress (cons 'copy-constraint-equivs! s))))] + [_ (t 0)] + + ;; --- Allocate new tvar + [(Tvar-nuTvar set-Tvar-nuTvar!) (alloc-Tvar-field)] + [list-nu-tvars '()] + [_ (for-each + (lambda (tvar) + (unless (Tvar-nuTvar tvar) + (let ([nu (mk-Tvar 'copy-constraints!)]) + (set! list-nu-tvars (cons nu list-nu-tvars)) + (for-each + (lambda (tvar2) (set-Tvar-nuTvar! tvar2 nu)) + (tvar->equiv tvar))))) + live-tvars)] + [_ (t 1)] + + [Tvar->nuTvar + (lambda (Tvar) + (if (live-tvar? Tvar) + (let ([nu (Tvar-nuTvar Tvar)]) + (assert (Tvar? nu) 'Tvar->nuTvar + nu (live-tvar? Tvar) (memq Tvar live-tvars)) + nu) + (let ([dummy (mk-Tvar 'dummy)]) + (set! list-nu-tvars (cons dummy list-nu-tvars)) + dummy)))] + + [(AV-nuAV set-AV-nuAV!) (alloc-AV-field)] + [copy-AV + (lambda (AV) + (or + (AV-nuAV AV) + (match AV + [(and AV ($ AV _ template misc fields+ fields-)) + (let* + ( [nu-fields+ (vector-map Tvar->nuTvar fields+)] + [nu-fields- (vector-map Tvar->nuTvar fields-)] + [nu-AV (create-AV template misc nu-fields+ nu-fields-)]) + (set-AV-nuAV! AV nu-AV) + (for-each + (lambda (eq-AV) + (when (and + (not (AV-nuAV eq-AV)) + (eq? (AV-template eq-AV) template) + (vector-andmap2 eq? nu-fields+ + (vector-map Tvar->nuTvar (AV-fields+ eq-AV))) + '(vector-andmap2 eq? nu-fields- + (vector-map Tvar->nuTvar (AV-fields- eq-AV)))) + (set-AV-nuAV! eq-AV nu-AV))) + (AV->equiv AV)) + nu-AV)])))] + [_ (t 1.1)]) + + (for-each + (match-lambda + [($ NT source LU) + (when (Tvar? source) + (let ([dest (Tvar->nuTvar source)]) + (case LU + [(U) + ;; --- AVs + (for-each (lambda (AV) (new-AV! dest (copy-AV AV))) + (Tvar-objs source))] + [(L) + ;; --- Constraints + (for-each + (match-lambda + [($ con _ template field-no Tvar sign) + (when (live-tvar? Tvar) + (new-con! dest + (create-con template field-no + (Tvar->nuTvar Tvar) sign)))] + [($ con-filter _ filter Tvar) + (when (live-tvar? Tvar) + ;; (new-con! dest + ;; (create-con-filter filter (Tvar->nuTvar Tvar)) + (new-edge! dest (Tvar->nuTvar Tvar)))]) + (Tvar-constraints source)) + + ;; --- Edges + (for-each + (lambda (Tvar2) + (when (live-tvar? Tvar2) + (let ([nu (Tvar->nuTvar Tvar2)]) + (unless (eq? dest nu) + (new-edge! dest nu))))) + (Tvar-edgeto source))])))]) + live-nts) + (t 2) + + (pretty-debug-min + `(copy-constraints-equiv! + old->new + ,(map + (lambda (tvar) + (list (Tvar-name tvar) (Tvar-name (Tvar-nuTvar tvar)))) + live-tvars))) + + + (values list-nu-tvars Tvar-nuTvar))) + +;; ====================================================================== +; copy-constraints-noe! +; +; Copies the contents of a set of Tvars +; Does closure under epsilon +; Takes care not to add duplicate AVs +; But may make many copies of the same AV in different Tvar + +(define (copy-constraints-noe! live-tvar? live-nts Tvar-nuTvar lower) + (pretty-debug-min + `(copy-constraints-noe! + live-nts + ,(map nt->sym live-nts) + lower + ,(map Tvar-name lower) + conversion + ,(map + (lambda (tvar) + (list (Tvar-name tvar) (Tvar-name (Tvar-nuTvar tvar)))) + (filter Tvar? (map NT-tvar live-nts))))) + '(let*-vals + ( [(AV-nuAV set-AV-nuAV!) (alloc-AV-field)] + [dummy-tvars '()] + [mk-dummy-tvar + (lambda () + (let ([dummy (mk-Tvar 'dummy)]) + (set! dummy-tvars (cons dummy dummy-tvars)) + dummy))] + [Tvar->nuTvar + (lambda (Tvar) + (if (live-tvar? Tvar) + (Tvar-nuTvar Tvar) + (mk-dummy-tvar)))] + [table '()] + [Tvar*->nuTvar + (lambda (Tvar*) + (let* ( [Tvar* (if (Tvar? Tvar*) (list Tvar*) Tvar*)] + [nu-Tvar* + (list->set + (filter-map + (lambda (Tvar) + (if (live-tvar? Tvar) (Tvar->nuTvar Tvar) #f)) + Tvar*))]) + (match nu-Tvar* + [() (mk-dummy-tvar)] + [(Tvar) Tvar] + [_ (or (ormap + (match-lambda + [(Tvar2* . nu) + (if (set-eq? Tvar2* nu-Tvar*) nu #f)]) + table) + (let ([nu (mk-Tvar 'multiple)]) + (set! table (cons (cons nu-Tvar* nu) table)) + (for-each (lambda (to) (new-edge! nu to)) nu-Tvar*) + nu))])))] + [tag-reached-AV (gensym)]) + + (for-each + (match-lambda + [($ NT source LU) + (when (Tvar? source) + (pretty-debug-min `(copying ,(Tvar-name source))) + (let ([dest (Tvar->nuTvar source)]) + (case LU + [(U) + ;; --- AVs + (for-each + (match-lambda + [(and AV + ($ AV _ + (and template ($ template _ signs)) misc fields)) + + (pretty-debug-min `(AV ,(Tvar-name dest) + ,(vector-map Tvar-name fields))) + + (new-AV! dest + (or (AV-nuAV AV) + (let* ([nu-fields + (vector-map + (lambda (sign field) + (if sign + (Tvar->nuTvar field) + (Tvar*->nuTvar + (Tvar-transitive-edgeto field)))) + signs fields)] + [nu-AV (create-AV template misc nu-fields)]) + (set-AV-nuAV! AV nu-AV) + nu-AV)))]) + (Tvar-objs source))] + + [(L) + ;; --- Constraints + (for-each + (match-lambda + [($ con _ template field-no Tvar) + (for-each + (lambda (Tvar) + (when (live-tvar? Tvar) + (new-con! dest + (create-con template field-no + (Tvar->nuTvar Tvar))))) + (if (vector-ref (template-signs template) field-no) + (Tvar-transitive-edgeto Tvar) + (list Tvar) + ;;(Tvar-transitive-edgefrom Tvar) + ))] + [($ con-filter _ filter Tvar) + ;; Was treated as edge + (void)]) + (Tvar-constraints source))])))]) + live-nts) + + (for-each + (lambda (L) + (let ([nu-L (Tvar->nuTvar L)]) + (for-each + (lambda (to) + (when (live-tvar? to) + (let ([nu-to (Tvar->nuTvar to)]) + (unless (eq? nu-L nu-to) + (new-edge! nu-L nu-to))))) + (Tvar-transitive-edgeto L)))) + lower) + + (append dummy-tvars (map cdr table)))) + +;; ====================================================================== diff --git a/collects/mrspidey/Sba/min/min.ss b/collects/mrspidey/Sba/min/min.ss new file mode 100644 index 0000000..9096ada --- /dev/null +++ b/collects/mrspidey/Sba/min/min.ss @@ -0,0 +1,236 @@ +; min.ss +; Purpose: Minimize a set of constraints. +; ====================================================================== +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +; minimize-constraints-&-compare +; minimizes a constraint system +; Input: which : 'live or 'dfa-min +; lower : list Tvar +; upper : list Tvar +; l1 ... l2 : ftypes in uncompresssed set of constraints + +; Returns (list-ftype Tvar->nuTvar) +;; ---------------------------------------- + +(define global-lower (void)) +(define global-upper (void)) +(define global-all-which (void)) + +(define (minimize-constraints-&-compare all-which lower upper l1 l2) + (set! global-lower lower) + (set! global-upper upper) + (set! global-all-which all-which) + (when (st:compare-min-algs) + ;; Compare algorithms + (let* ( [alg-width 32] + [calc-sizes + (lambda (rep) + (pretty-debug-min2 `(calc-sizes ,(map Tvar-name rep))) + (let*-vals + ( [n-f (length rep)] + [AV-added (apply append (map get-Tvar-objs rep))] + [n-AV-added (length AV-added)] + [n-AV (length (list->set AV-added))] + [n-edge (length (apply append (map Tvar-edgeto rep)))] + [n-con (length (apply append (map Tvar-constraints rep)))] + [size (+ n-edge n-con n-AV-added)]) + (list size n-f n-AV n-AV-added n-edge n-con)))] + [show-sizes + (lambda (alg orig-size t size n-f n-AV n-AV-added n-edge n-con) + (if (zero? size) + (error 'minimize-constraints-&-compare + "Algorithm ~s returns empty constraint system~n" alg) + (printf + "~a: ~a ~a ~a ~a ~a ~a ~a ~a~n" + (padr alg alg-width) + (padl + (/ (round (* (exact->inexact (/ orig-size size)) 10)) 10) + 6) + (padl size 5) + (padl n-f 5) + (padl n-AV 3) + (padl n-AV-added 5) + (padl n-edge 5) + (padl n-con 4) + (padl t 5))))] + [orig-sizes (calc-sizes (filter Tvar? (get-prefix l1 l2)))] + [orig-size (car orig-sizes)]) + '(pretty-debug `(minimize-constraints-&-compare + ,(map Tvar-name lower) ,(map Tvar-name upper))) + (printf "~n~a: factor size Tvar AV AV-a edge con time~n" + (padr "Algorithm" alg-width)) + (apply show-sizes "" orig-size 0 orig-sizes) + (for-each + (lambda (p) + (let*-vals + ( [thunk + (lambda () + (let-values + ([(rep _) + (minimize-constraints p lower upper l1 l2)]) + rep))] + [(rep t real-t) (time-apply thunk)] + [sizes (calc-sizes rep)]) + (apply show-sizes p orig-size t sizes))) + min-algs-to-compare))) + + (minimize-constraints all-which lower upper l1 l2)) + +;; ---------- + +(define min-algs-to-compare + '( ;(none) + (nonempty) + (nonempty live) + (live) + ;(live-no-epsilon) + (live-few-e) + ;(live-few-e-L) + ;(live-few-e-U) + ;(live-no-epsilon dfa-min) + ;(live-no-epsilon dfa-min-inv) + ;(live-few-e dfa-min) + ;(live-few-e dfa-min-inv) + ;(live-few-e dfa-min-inv dfa-min) + ;(live-few-e dfa-min dfa-min-inv) + + ;(live-no-epsilon dfa-min-1) + ;(live-no-epsilon dfa-min-2) + + ;(live-few-e dfa-min-1) + ;(live-few-e dfa-min-2) + ;(live-few-e dfa-min-1 live-few-e dfa-min-2) + ;(live-few-e dfa-min-2 live-few-e dfa-min-1) + + (dfa-min-lub) + (dfa-min-glb) + (dfa-min-lub dfa-min-glb) + (dfa-min-glb dfa-min-lub) + (dfa-min-lub dfa-min-glb dfa-min-lub) + (dfa-min-glb dfa-min-lub dfa-min-glb) + ;(live-few-e dfa-min-1 live-no-epsilon dfa-min-2 live-no-epsilon dfa-min-1) + ;(live-few-e dfa-min-2 live-no-epsilon dfa-min-1 live-no-epsilon dfa-min-2) + ;(live-no-epsilon min-table) + )) + +;; ---------------------------------------------------------------------- + +(define min-time-base 0) +(define min-time-record '()) +(define (min-record-progress what) + (set! min-time-record + (cons (cons what (current-process-milliseconds)) min-time-record))) +(define (show-record-progress) + (pretty-debug + (map (match-lambda + [(what . when) (list what (- when min-time-base))]) + (reverse min-time-record)))) +;; ---------- + +(define (minimize-constraints all-which lower upper l1 l2) + (pretty-debug-min2 + `(input + all-which ,all-which + lower ,(map Tvar-name lower) + upper ,(map Tvar-name upper))) + + (set! min-time-record '()) + (set! min-time-base (current-process-milliseconds)) + (recur loop ( [which all-which] + [lower lower] + [upper upper] + [Tvar->nuTvar (lambda (x) x)]) + (match which + [(which . (and rest (_ . _))) + (let*-vals + ([(rep-Tvar1 Tvar->nuTvar1) + (minimize-constraints-nocount which lower upper l1 l2)]) + (loop rest + (map Tvar->nuTvar1 lower) + (map Tvar->nuTvar1 upper) + (lambda (Tvar) (Tvar->nuTvar1 (Tvar->nuTvar Tvar)))))] + [(or (which) (? symbol? which)) + (let*-vals + ([(rep-Tvar Tvar-nuTvar1) + (minimize-constraints-nocount which lower upper l1 l2)]) + + (when timing-min (show-record-progress)) + + (pretty-debug-min2 + `(output lower ,(map Tvar-name (map Tvar-nuTvar1 lower)) + upper ,(map Tvar-name (map Tvar-nuTvar1 upper)))) + + (values + rep-Tvar + (lambda (Tvar) (Tvar-nuTvar1 (Tvar->nuTvar Tvar)))))]))) + +;; ---------------------------------------------------------------------- + +(define (minimize-constraints-nocount which lower upper l1 l2) + (pretty-debug-min + `(minimize-constraints-nocount which ,which + lower ,(map Tvar-name lower) + upper ,(map Tvar-name upper))) + (check-kernel-ok) + (pretty-debug-min `(minimize-constraints-nocount kernel-ok)) + (let*-values + ([(A B) + (case which + [(none) (values + (filter Tvar? (get-prefix l1 l2)) + (lambda (Tvar) Tvar))] + [(nonempty) (let*-vals + ([(live-tvars _ _) + (find-nonempty-tvars lower upper)]) + (values + live-tvars + (lambda (tvar) tvar)))] + [(nonempty-copy) (copy-nonempty-tvars lower upper)] + [(live) (copy-live-constraints lower upper)] + [(live-no-epsilon) (copy-live-constraints-noe lower upper)] + + [(live-few-e) + (call-with-values + (lambda () ((copy-live-constraints-few-e #t #t) lower upper)) + copy-constraints-equiv!)] + [(live-few-e-L) + (call-with-values + (lambda () ((copy-live-constraints-few-e #t #f) lower upper)) + copy-constraints-equiv!)] + [(live-few-e-U) + (call-with-values + (lambda () ((copy-live-constraints-few-e #f #t) lower upper)) + copy-constraints-equiv!)] + ;[dfa-min (minimize-constraints-dfa-min lower upper)] + ;[dfa-min-inv (minimize-constraints-dfa-min-inv lower upper)] + ;[dfa-min-1 (minimize-constraints-dfa-min-1 lower upper)] + ;[dfa-min-2 (minimize-constraints-dfa-min-2 lower upper)] + [(dfa-min-lub) (minimize-constraints-dfa-min-lub lower upper)] + [(dfa-min-glb) (minimize-constraints-dfa-min-glb lower upper)] + ;[min-table (min-table lower upper)] + [else (error 'minimize-constraints-nocount "Bad which ~s" which)])]) + (check-kernel-ok) + (pretty-debug-min `(minimize-constraints-nocount kernel-ok2)) + (min-record-progress 'minimize-constraints-nocount-returning) + (values A B))) + +;; ====================================================================== + + + + diff --git a/collects/mrspidey/Sba/min/nonempty.ss b/collects/mrspidey/Sba/min/nonempty.ss new file mode 100644 index 0000000..3603925 --- /dev/null +++ b/collects/mrspidey/Sba/min/nonempty.ss @@ -0,0 +1,105 @@ +; ====================================================================== +; find-nonempty-tvars +; +; Input: lower : (listof Tvar) with non-empty Tvar_L +; upper : (listof Tvar) with non-empty Tvar_U +; +; Finds non-empty non-terminals +; returns (listof Tvar) +; ====================================================================== +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define (find-nonempty-tvars lower upper) + (pretty-debug-min + `(find-nonempty-tvars ,(map Tvar-name lower) ,(map Tvar-name upper))) + + (let*-vals ( [(reached-U? set-reached-U!) (alloc-Tvar-field)] + [(reached-L? set-reached-L!) (alloc-Tvar-field)] + [(reached-AV set-reached-AV!) (alloc-AV-field)] + [num-AV 0] + [list-tvar '()]) + (letrec + ( [add-Tvar! + (lambda (tvar) + (set! list-tvar (cons tvar list-tvar)))] + [walk-AV + (lambda (AV) + (unless (reached-AV AV) + ;; Walk it + (set-reached-AV! AV #t) + (match AV + [($ AV _ template _ fields+ fields-) + (vector-for-each walk-U fields+) + (when (follow-antimono-fields template) + (pretty-debug-min + `(walking-U + ,(eq? template template-lam) + ,(st:minimize-respect-assignable-part-of-fields))) + (vector-for-each walk-U fields-))])))] + [walk-U + (lambda (tvar) + (unless (reached-U? tvar) + (unless (reached-L? tvar) (add-Tvar! tvar)) + (set-reached-U! tvar #t) + (pretty-debug-min `(walk-U ,(Tvar-name tvar))) + (for-each walk-AV (get-Tvar-objs tvar)) + (for-each walk-U (Tvar-edgefrom tvar))))] + [walk-L + (lambda (tvar) + (unless (reached-L? tvar) + (unless (reached-U? tvar) (add-Tvar! tvar)) + (set-reached-L! tvar #t) + (pretty-debug-min `(walk-L ,(Tvar-name tvar))) + ;; Have to_L -> tvar_L + (for-each walk-L (Tvar-edgeto tvar)) + + (for-each + (match-lambda + [($ con _ _ field-no tvar2 sign misc) + ;; Have tvar2_L -> rng(tvar_L) + ;; or tvar2_U -> dom(tvar_L) + (if sign + (walk-L tvar2) + (walk-U tvar2))] + [($ con-filter _ filter tvar2) + ;; Have tvar2_L -> tvar_L + (walk-L tvar2)]) + (Tvar-constraints tvar))))]) + (for-each walk-U upper) + (for-each walk-L lower) + '(printf "walk-reachable-constraints allocated ~s tvar, ~s AV~n" + (length list-tvar) num-AV) + + (values list-tvar reached-L? reached-U?)))) + +; ====================================================================== + +(define (copy-nonempty-tvars lower upper) + (let*-vals + ( [(live-tvars _ _) (find-nonempty-tvars lower upper)] + [(tvar-live? set-tvar-live!) (alloc-Tvar-field)]) + (for-each mk-Tvar-NTs! live-tvars) + (for-each (lambda (tvar) (set-tvar-live! tvar #t)) live-tvars) + (copy-constraints-equiv! + (append lower upper live-tvars) + tvar-live? + (append + (map Tvar-L live-tvars) + (map Tvar-U live-tvars)) + (lambda (tvar) (list tvar)) + (lambda (AV) (list AV))))) diff --git a/collects/mrspidey/Sba/mod-env3.ss b/collects/mrspidey/Sba/mod-env3.ss new file mode 100644 index 0000000..2566780 --- /dev/null +++ b/collects/mrspidey/Sba/mod-env3.ss @@ -0,0 +1,46 @@ +(let ([gen:477:join-env (void)] + [gen:473:extend-env* (void)] + [gen:476:extend-env (void)] + [gen:474:lookup (void)] + [gen:475:empty-env (void)]) + (begin (set! gen:475:empty-env '()) + (begin (set! gen:474:lookup + (lambda (gen:493:env gen:492:x) + (let ([gen:494:r (assq gen:492:x gen:493:env)]) + (if (eq? gen:494:r '#f) + (error 'lookup '"no binding for ~a" gen:492:x) + (cdr gen:494:r))))) + (begin (set! gen:476:extend-env + (lambda (gen:491:env gen:489:x gen:490:v) + (cons (cons gen:489:x gen:490:v) gen:491:env))) + (begin (set! gen:473:extend-env* + (lambda (gen:488:env gen:486:xs gen:487:vs) + (append (map2 cons gen:486:xs gen:487:vs) gen:488:env))) + (begin (set! gen:477:join-env + (lambda (gen:485:env gen:484:newenv) + (append gen:484:newenv gen:485:env))) + (make-rs:module + (lambda (gen:478:msg) + (let ([gen:479:%%tmp gen:478:msg]) + (if (memv gen:479:%%tmp '(empty-env)) + gen:475:empty-env + (let ([gen:480:%%tmp gen:478:msg]) + (if (memv gen:480:%%tmp '(lookup)) + gen:474:lookup + (let ([gen:481:%%tmp gen:478:msg]) + (if (memv gen:481:%%tmp '(extend-env)) + gen:476:extend-env + (let ([gen:482:%%tmp gen:478:msg]) + (if (memv gen:482:%%tmp '(extend-env*)) + gen:473:extend-env* + (let ([gen:483:%%tmp gen:478:msg]) + (if (memv gen:483:%%tmp '(join-env)) + gen:477:join-env + (error 'import + '"attempting to import ~s~n from module with signature ~s" + gen:478:msg + '(empty-env + lookup + extend-env + extend-env* + join-env)))))))))))))))))))) diff --git a/collects/mrspidey/Sba/nfa-dfa.ss b/collects/mrspidey/Sba/nfa-dfa.ss new file mode 100644 index 0000000..fe1543b --- /dev/null +++ b/collects/mrspidey/Sba/nfa-dfa.ss @@ -0,0 +1,59 @@ +; ====================================================================== +;; NFA->DFA +;; roots: (list nt) +;; final: (list nt) +;; returns (list (list AVS) (list AVS)) + +(define (NFA->DFA for-each-prod roots final) + ;; n is an old nt + ;; d is new nt + (letrec + ([n*->d '()] ; Maps set of NFA nts to a DFA nt + [n*<= + (lambda (n1* n2*) + (andmap (lambda (n1) (mem-nt? n1 n2*)) n1*))] + [n*= + (lambda (n1* n2*) + (and (n*<= n1* n2*) (n*<= n2* n1*)))] + [lookup + (lambda (n*) + (recur loop ([l n*->d]) + (cond + [(null? l) #f] + [(n*= n* (caar l)) (cdar l)] + [else (loop (cdr l))])))] + [traverse + (lambda (n*) + (or (lookup n*) + ;; Need to traverse + ;; think about epsilon-closure + (let* ([rhs* '()] + [_ (for-each + (lambda (n) + (for-each-prod + (lambda (rhs) (set! rhs* (cons rhs rhs*))) + n)) + n*)] + [d (mk-AVS-nolist 'dfa)]) + (set! n*->d (cons (cons n* d) n*->d)) + (recur loop ([rhs* rhs*]) + (match rhs* + [() (void)] + [(($ rhs grsym nt) . _) + ;; Merge all with same grsym + (match-let* + ([(nt* . rest) + (filter-map-split + (match-lambda + [($ rhs grsym2 nt2) + (if (grsym-eq? grsym grsym2) + nt2 + #f)]) + rhs*)]) + (add-prod! d (make-rhs grsym (traverse nt*))) + (loop rest))])) + d)))]) + (traverse (list AVS)) + (list (map (lambda (r) (lookup (list r))) roots) + (map (lambda (r) (lookup (list r))) final)))) + diff --git a/collects/mrspidey/Sba/parser.ss b/collects/mrspidey/Sba/parser.ss new file mode 100644 index 0000000..d2a0341 --- /dev/null +++ b/collects/mrspidey/Sba/parser.ss @@ -0,0 +1,489 @@ +;; parser.ss +;; +;; Takes a zodiac:sexp, and an env: sym -> zodiac:bound, +;; and produces a zodiac:ast and a list of unbound zodiac:bounds +;; Only handles R4RS primitive syntax +;; ====================================================================== + +(define keywords + '(begin cond delay if set! set!-values quote begin lambda case-lambda + poly + let-values letrec*-values + unit compound-unit invoke-unit + : type:-quote + cache-exp-quote cache-inv-quote + struct typed-structure const-typed-structure + )) + +(define define-keywords + '(define-values + define-type + define-constructor + )) + +;; ---------------------------------------------------------------------- + +(define (top-level-parse-defs defs) + (set! unbound-env '()) + (let-values ([(defs nuenv) (parse-defs defs empty-env)]) + (values defs (map cdr unbound-env)))) + +(define (top-level-parse-exp exp) + (set! unbound-env '()) + (let ([ast (parse exp empty-env)]) + (values ast (map cdr unbound-env)))) + +(define unbound-env '()) + +;; ---------------------------------------------------------------------- + +(define syntax-error + (case-lambda + [(exp) (syntax-error exp "Bad syntax")] + [(exp s) + (mrspidey:error + (format "File ~s, Line ~s: ~a ~s" + (file-name-from-path + (zodiac:location-file (zodiac:zodiac-start exp))) + (zodiac:location-line (zodiac:zodiac-start exp)) + s (zodiac:stripper exp)))])) + +(define syntax-error-no-exp + (case-lambda + [(exp) (syntax-error-no-exp exp "Bad syntax")] + [(exp s) + (mrspidey:error + (format "File ~s, Line ~s: ~as" + (file-name-from-path + (zodiac:location-file (zodiac:zodiac-start exp))) + (zodiac:location-line (zodiac:zodiac-start exp)) + s))])) + +(define assert-syn + (case-lambda + [(exp x) (assert-syn exp x "Bad syntax")] + [(exp x s) (unless x (syntax-error exp s))])) + +(define parse-body + (lambda (o s f body env) + (assert (list? body)) + (recur loop ([rest body]) + (match rest + [(exp) (parse exp env)] + [(exp . rest) + (zodiac:make-begin-form o s f (box 0) + (parse exp env) + (loop rest))])))) + +(define do-bindings + (lambda (env syms) + (assert (list? syms)) + (let* ([bindings + (map + (match-lambda + [($ zodiac:symbol o s f sym) + (let ([bound (zodiac:make-bound o s f (box 0) sym sym)]) + (cons sym bound))] + [exp (syntax-error exp "Bad binding syntax")]) + syms)] + [syms (map car bindings)] + [bounds (map cdr bindings)] + [nuenv (extend-env* env syms bounds)]) + (values bounds nuenv)))) + +(define do-bindingss + (lambda (env symss) + (recur loop ([env env][symss symss][boundss '()]) + (if (null? symss) + (values (reverse boundss) env) + (let-values + ([(bounds env) (do-bindings env (car symss))]) + (loop env (cdr symss) (cons bounds boundss))))))) + +(define parse + ;; parses an expression + (lambda (exp env) + (pretty-debug-front `(parse ,(zodiac:stripper exp))) + (letrec ([lookup-sym + (lambda (sym s f env) + (let ([bound + (or (lookup-or-#f env sym) + (lookup-or-#f unbound-env sym) + ;; Add to unbound-env + (let ([n (zodiac:my-create-bound sym s f)]) + (set! unbound-env (cons (cons sym n) unbound-env)) + n))]) + ;;(set-bound-refs! bound (add1 (bound-refs bound))) + bound))] + [parse-sym-env + (lambda (env) + (match-lambda + [($ zodiac:symbol o s f sym) + ;;(printf "ref sym ~s~n" sym) + (zodiac:make-lexical-varref o s f (box 0) + sym (lookup-sym sym s f env))] + [exp (syntax-error exp "Expected a variable:")]))] + [parse-sym (parse-sym-env env)] + [call-void + (lambda (o s f) + (zodiac:make-app + o s f (box 0) + (zodiac:make-lexical-varref o s f (box 0) + 'void (lookup-sym 'void s f '())) + '()))] + [parse-exps + (lambda (exps env) + (map (lambda (e) (parse e env)) exps))] + [handle-args + (lambda (args env) + (match args + [($ zodiac:list _ _ _ args) (do-bindings env args)] + [($ zodiac:symbol) + (let-values + ([(bounds nuenv) (do-bindings env (list args))]) + (values (car bounds) nuenv))] + [($ zodiac:improper-list _ _ _ l) + (recur loop ([args '()][l l]) + (match l + [(arg) + (let-values + ([(bounds nuenv) + (do-bindings env (cons arg args))]) + (values (append (reverse (cdr bounds)) (car bounds)) + nuenv))] + [(arg . rest) (loop (cons arg args) rest)]))]))]) + + (pretty-debug-front `(parse ,(zodiac:stripper exp))) + (match exp + ;; Identifiers + [($ zodiac:symbol o s f sym) (parse-sym exp)] + + ;; Scalars, vectors + [(or ($ zodiac:scalar o s f) ($ zodiac:vector o s f)) + (zodiac:make-quote-form o s f (box 0) exp)] + + ;; Special forms + [($ zodiac:list o s f + (and l (($ zodiac:symbol _ _ _ sym) . body))) + (=> fail) + (let ([sym (strip-hash-percent sym)]) + (cond + [(memq sym keywords) + (match (cons sym body) + [('cond) + (call-void o s f)] + [('delay exp) + (zodiac:make-delay-form o s f (box 0) (parse exp env))] + [('if test then else) + (zodiac:make-if-form o s f (box 0) + (parse test env) + (parse then env) + (parse else env))] + [('if test then) + (zodiac:make-if-form o s f (box 0) + (parse test env) + (parse then env) + (call-void o s f))] + [(or + ('set! var exp) + ('set!-values ($ zodiac:list _ _ _ (var)) exp)) + + (let ([var (parse-sym var)]) + (when (zodiac:lexical-varref? var) + (zodiac:set-bound-mutated! + (zodiac:lexical-varref-binding var) + #t)) + (zodiac:make-set!-form o s f (box 0) + var (parse exp env)))] + [('quote sexp) + (assert-syn exp (= (length body) 1)) + (zodiac:make-quote-form o s f (box 0) sexp)] + [('begin . exps) + (recur loop ([exps exps]) + (match exps + [() (call-void o s f)] + [(exp) (parse exp env)] + [(exp . exps) + (zodiac:make-begin-form o s f (box 0) + (parse exp env) + (loop exps))]))] + [('lambda args . bodies) + (let-values + ([(bounds nuenv) (handle-args args env)]) + (zodiac:make-lambda-form o s f (box 0) + bounds + (parse-body o s f bodies nuenv)))] + [('case-lambda . cases) + (zodiac:make-case-lambda-form + o s f (box 0) + (mapLR + (match-lambda + [($ zodiac:list _ _ _ (args . body)) + (let-values + ([(bounds nuenv) (handle-args args env)]) + (cons bounds (parse-body o s f body nuenv)))] + [_ (syntax-error-no-exp exp "Bad case lambda")]) + cases))] + + [('let-values + ($ zodiac:list _ _ _ + (($ zodiac:list _ _ _ + (($ zodiac:list _ _ _ varss) + exps)) + ...)) + . bodies) + (let-values + ([(boundss nuenv) (do-bindingss env varss)]) + (zodiac:make-let-values-form + o s f (box 0) + boundss + (parse-exps exps env) + (parse-body o s f bodies nuenv)))] + + [('letrec*-values + ($ zodiac:list _ _ _ + (($ zodiac:list _ _ _ + (($ zodiac:list _ _ _ varss) + exps)) + ...)) + . bodies) + (let-values + ([(boundss nuenv) (do-bindingss env varss)]) + (for-each + (lambda (name) (zodiac:set-bound-mutated! name #t)) + (apply append boundss)) + (zodiac:make-letrec-values-form + o s f (box 0) + boundss + (parse-exps exps nuenv) + (parse-body o s f bodies nuenv)))] + + ;; --------------------------------------------------------- + ;; MzScheme specific code + + ;; --- units --- + [('unit ($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ 'import) + i-ids ...)) + ($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ 'export) + (or ($ zodiac:list _ _ _ + (i-eids + ($ zodiac:symbol _ _ _ e-eids))) + (and i-eids + ($ zodiac:symbol _ _ _ e-eids))) + ...)) + . body) + (let*-vals ([(i-names env1) (do-bindings env i-ids)] + [(defs env2) (parse-defs body env1)] + [e-vars + (map (parse-sym-env env2) i-eids)] + [exports (map cons e-vars e-eids)]) + (zodiac:make-unit-form o s f (box 0) + i-names exports defs))] + + ;; --- compound-units --- + [('compound-unit + ($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ 'import) + ($ zodiac:symbol _ _ _ imports) ...)) + ($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ 'link) . links)) + ($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ 'export) . exports))) + (let*-vals + ([links + (map + (match-lambda + [($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ tag) + ($ zodiac:list _ _ _ (exp . imports)))) + (list tag + (parse exp env) + (apply append + (map + (match-lambda + [($ zodiac:symbol _ _ _ sym) + (list (cons #f sym))] + [($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ tag) + ($ zodiac:symbol _ _ _ syms) + ...)) + (map (lambda (sym) (cons tag sym)) + syms)] + [_ (syntax-error exp "Bad link imp")]) + imports)))] + [_ (syntax-error exp "Bad link")]) + links)] + [exports + (apply + append + (map + (match-lambda + [($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ tag) + (or ($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ i-eids) + ($ zodiac:symbol _ _ _ e-eids))) + (and ($ zodiac:symbol _ _ _ i-eids) + ($ zodiac:symbol _ _ _ e-eids))) ...)) + (map + (lambda (i-eid e-eid) (list tag i-eid e-eid)) + i-eids e-eids)] + [_ (syntax-error exp "Bad link export")]) + exports))]) + (zodiac:make-compound-unit-form + o s f (box 0) imports links exports))] + + ;; --- invoke-unit --- + [('invoke-unit exp . ((and vars ($ zodiac:symbol)) ...)) + (zodiac:make-invoke-unit-form + o s f (box 0) + (parse exp env) + (map (lambda (var) (parse-sym var env)) vars))] + + ;; --- structures --- + [((or 'struct 'typed-structure 'const-typed-structure) + first + ($ zodiac:list _ _ _ fields)) + (let*-vals + ([(tag parent) + (match first + [($ zodiac:symbol _ _ _ tag) (values tag #f)] + [($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ tag) parent)) + (values tag (parse parent env))])] + [fields (map zodiac:stripper fields)]) + (zodiac:make-struct-form + o s f (box 0) + tag (eq? sym 'const-typed-structure) parent fields))] + + ;; ------------------------------------------------------- + ;; MrSpidey specific code + + [('poly exp) + (zodiac:make-poly-form + o s f (box 0) (parse exp env))] + [(': exp type) + (zodiac:make-:-form o s f (box 0) + (parse exp env) + (zodiac:stripper type))] + + [('type:-quote + ($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ (or 'quote '#%quote)) + ($ zodiac:list _ _ _ (type . attrs))))) + (zodiac:make-type:-form o s f (box 0) + (zodiac:stripper type) + (map zodiac:stripper attrs))] + + [('st:control para val) + (zodiac:make-st:control-form o s f (box 0) + (zodiac:stripper para) + (zodiac:stripper val))] + + [((or 'cache-exp-quote 'cache-inv-quote) + ($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ (or 'quote '#%quote)) exp)) + ($ zodiac:string _ _ _ za)) + (when (string=? za (regexp-replace ".za$" za "")) + (syntax-error exp "Cache filename must end in .za")) + (zodiac:make-cache-form + o s f (box 0) exp + (normalize-path za) + (case sym + [cache-exp-quote 'exp] + [cache-inv-quote 'inv] + [else + (mrspidey:internal-error 'parser "Bad sym ~s" sym)]) + (current-directory))] + + ;; ------------------------------------------------------- + [else (syntax-error exp)])] + [(memq sym define-keywords) + (syntax-error-no-exp exp "Defines not allowed")] + [else (fail)]))] + + ;; Don't handle vectors or improper lists + ;; Applications + + [($ zodiac:list o s f (and l (fn . exps))) + (zodiac:make-app o s f (box 0) + (parse fn env) + (parse-exps exps env))] + [($ zodiac:list o s f ()) + (zodiac:make-quote-form o s f (box 0) '())] + [_ (syntax-error exp)])))) + + + + +(define (parse-defs defs env) + (let*-vals + ([varss (mapLR + (match-lambda + [($ zodiac:list _ _ _ + (($ zodiac:symbol _ _ _ '#%define-values) + ($ zodiac:list _ _ _ vars) + exp)) + vars] + [_ '()]) + defs)] + [(boundss nuenv) (do-bindingss env varss)] + [_ (for-each + (lambda (name) (zodiac:set-bound-mutated! name #t)) + (apply append boundss))] + [defs + (map + (lambda (def bounds) + (pretty-debug-front `(parse-def ,(zodiac:stripper def))) + (mrspidey:zprogress "Parsing" (zodiac:zodiac-start def)) + (match def + ;; Special forms + [($ zodiac:list o s f + (and l (($ zodiac:symbol _ _ _ sym) . body))) + (=> fail) + (let ([sym (strip-hash-percent sym)]) + (cond + [(not (memq sym define-keywords)) (fail)] + [else + (match (cons sym body) + + [('define-values ($ zodiac:list _ _ _ vars) exp) + (zodiac:make-define-values-form + o s f (box 0) + (map + (match-lambda + [(and bound ($ zodiac:bound o s f _ sym)) + (zodiac:make-lexical-varref o s f (box 0) + sym bound)]) + bounds) + (parse exp nuenv))] + + ;; ---------------------------------------------------- + ;; MrSpidey specific code + + [('define-type ($ zodiac:symbol _ _ _ sym) type) + (zodiac:make-define-type-form + o s f (box 0) + sym (zodiac:stripper type))] + + [('define-constructor ($ zodiac:symbol _ _ _ sym) + . modes) + (let ([modes (map zodiac:stripper modes)]) + (assert-syn def (andmap boolean? modes)) + (zodiac:make-define-constructor-form o s f (box 0) + sym modes))] + + ;; ---------------------------------------------------- + [else (fail)])]))] + + [exp (parse exp nuenv)])) + defs boundss)]) + (unless (null? defs) + (mrspidey:zprogress "Parsing" (zodiac:zodiac-finish (rac defs)))) + (values defs nuenv))) + +;; ---------------------------------------------------------------------- + + diff --git a/collects/mrspidey/Sba/poly.ss b/collects/mrspidey/Sba/poly.ss new file mode 100644 index 0000000..5aaf828 --- /dev/null +++ b/collects/mrspidey/Sba/poly.ss @@ -0,0 +1,626 @@ +;; poly.ss +;; ---------------------------------------------------------------------- +;; Preprocesses the program + + +;; ---------------------------------------------------------------------- + +(define debugging-topo #f) +(defmacro pretty-debug-topo args + `(when debugging-topo (pretty-print ,@args))) + +; ====================================================================== + +(define (st:poly file) + (st: (topo-file file))) + +; ====================================================================== + +(define-struct def-info (def out in to from color)) + +(define (topo-file file) + (let ([file (normalize-path file)]) + (let*-vals + ( [sexps (zodiac:read* (open-code-file file) file)] + [(defs free-names) + (dynamic-let ([current-directory (path-only file)]) + (top-level-parse-defs sexps))] + [prims-refd (map zodiac:bound-var free-names)] + [_ (pretty-debug-topo `(prims-refd ,prims-refd))] + [prim-sexps + (filter-map + (lambda (name) + (or + (ormap + (match-lambda + [(and d ('define (? (lambda (n) (eq? n name))) _)) + (let* ( [p (open-output-string)] + [_ (pretty-print d p)] + [_ (close-output-port p)] + [p (open-input-string (get-output-string p))] + [p (system-expand-if-necy p)] + [d (zodiac:read p + (zodiac:make-location 1 1 0 "prim-file"))]) + (d))] + [_ #f]) + r4rs-prims) + (begin + (unless (memq name real-primitives) + (printf "Warning: Bad primitive ~s~n" name)) + #f))) + prims-refd)] + [_ (pretty-debug-topo `(prim-sexps ,(map zodiac:stripper prim-sexps)))] + [all-sexps (append prim-sexps sexps)] + [(defs free-names) + (dynamic-let ([current-directory (path-only file)]) + (top-level-parse-defs all-sexps))] + [def->di + (lambda (def) + (let ([di (make-def-info def '() '() '() '() #f)]) + (match def + [($ zodiac:define-values-form _ _ _ _ lvrs exp) + (set-def-info-out! di + (map zodiac:lexical-varref-binding lvrs)) + (set-def-info-in! di (zodiac:free-refs exp))] + [exp (set-def-info-in! di (zodiac:free-refs exp))]) + di))] + [di* (mapLR def->di defs)] + [_ (for-each + (lambda (di) + (pretty-debug-topo + `(DEF ,(zodiac:stripper (def-info-def di)) + ,(map zodiac:bound-var (def-info-out di)) + ,(map zodiac:bound-var (def-info-in di))))) + di*)] + + [_ (for-each + (lambda (di1) + (for-each + (lambda (sym) + (for-each + (lambda (di2) + (when (memq sym (def-info-out di2)) + (set-def-info-to! di1 + (cons di2 (def-info-to di1))) + (set-def-info-from! di2 + (cons di1 (def-info-from di2))))) + di*)) + (def-info-in di1))) + di*)] + [_ (pretty-debug-topo "to/from fields filled")] + + [dfs (lambda (di* field-sel) + (for-each (lambda (di) (set-def-info-color! di 'white)) di*) + (let ([done '()]) + (letrec ([visit + (lambda (di) + (when (eq? (def-info-color di) 'white) + (set-def-info-color! di 'black) + (for-each visit (field-sel di)) + (set! done (cons di done))))]) + (for-each visit di*) + done)))] + + ;; do topological sort. See "Intro to Algs", p. 489 + + [di*1 (dfs di* def-info-to)] + ;; di*1 contains definitions before references + [show-di + (lambda (di) + `(DEF + ,(map zodiac:bound-var (def-info-out di)) + ,(map zodiac:bound-var (def-info-in di))))] + [show (lambda (str di*) + (pretty-debug-topo str) + (pretty-debug-topo (map show-di di*)))] + [_ (show "di*1" di*1)] + [di*2 (dfs di*1 def-info-from)] + [_ (show "di*2" di*2)] + + ;; Calculate list of strongly connected components + + [_ (for-each (lambda (di) (set-def-info-color! di 'white)) di*)] + [sccs + (mapLR + (lambda (di) + (let ([scc '()]) + (recur loop ([di di]) + (when (eq? (def-info-color di) 'white) + (set-def-info-color! di 'black) + (set! scc (cons di scc)) + (for-each loop (def-info-to di)))) + scc)) + di*2)] + [sccs (filter (lambda (x) (not (null? x))) sccs)] + + [_ (begin + (pretty-debug-topo 'SCCS) + (for-each (lambda (scc) (show "scc" scc)) sccs))] + + [my-begin + (lambda (first rest) + (make-zodiac:begin-form + first rest + (zodiac:no-location)(zodiac:no-location) (box #f)))] + + [value-def? + (match-lambda + [($ zodiac:define-values-form _ _ _ _ _ exp) + (zodiac:value? exp)] + [_ #f])] + + ;; --- Figure out which are polymorphic + ;; Go from end up to know if multiple refs for each var + ;; A ref inside a polymorphic def counts as multiple refs + + [vars-single-ref '()] + [vars-multi-ref '()] + [add-multi-ref! + (lambda (var) + (set! vars-multi-ref (set-add var vars-multi-ref)))] + [add-single-ref! + (lambda (var) + (if (element-of? var vars-single-ref) + (add-multi-ref! var) + (set! vars-single-ref (set-add var vars-single-ref))))] + + [sccs2 ;; include polymorphism flag + (mapRL + (lambda (scc) + (let* ( [values? + (andmap + (match-lambda + [($ def-info def out) (value-def? def)]) + scc)] + [mutable? + '(ormap + (match-lambda + [($ def-info def out) + (ormap (lambda (o) (memq o mutable-syms)) out)]) + scc)] + [mutable? #f] + [defs (apply append (map def-info-out scc))] + [refs (apply append (map def-info-in scc))] + [multi-refs + (match defs + [(def) (element-of? def vars-multi-ref)] + [() #f] + [defs #t])] + [poly-flag + (if (and values? (not mutable?)) + (if multi-refs 'poly 'poly1ref) + #f)]) + + (pretty-debug-topo + `( defs ,(map zodiac:bound-var defs) + refs ,(map zodiac:bound-var refs) + values? ,values? mutable? ,mutable? + multi-refs ,multi-refs poly-flag ,poly-flag)) + + (if (eq? poly-flag 'poly) + (for-each add-multi-ref! refs) + (for-each add-single-ref! refs)) + + (cons poly-flag scc))) + sccs)] + + [_ (pretty-print + `(SCCS + ,(map + (match-lambda + [(poly . di*) + (let* ( [o (apply append (map def-info-out di*))] + [ov (map zodiac:bound-var o)]) + (case poly + [poly (cons '-->POLY ov)] + [poly1ref (cons '-->POLY1REF ov)] + [#f ov]))]) + sccs2)))] + + [nu-program + ;; Return new program + (apply append + (map + (match-lambda + [('poly . + (($ def-info ($ zodiac:define-values-form _ _ _ _ + (lvrs) exps)) + ...)) + (let ([syms + (map (lambda (lvr) + (zodiac:bound-var + (zodiac:lexical-varref-binding lvr))) + lvrs)]) + (if (= (length syms) 1) + `((define ,(car syms) + (poly (letrec + ([,(car syms) ,(zodiac:stripper (car exps))]) + ,(car syms))))) + `((define-values ,syms + (poly (letrec*-values + ([,syms + (values + ,@(map zodiac:stripper exps))]) + (values ,@syms)))))))] + [(_ . di*) + (map zodiac:stripper (map def-info-def di*))]) + sccs2))] + + [outfile (regexp-replace ".ss$" file ".poly.ss")] + [_ (when (eq? outfile file) + (error 'topo-file "Bad suffix on ~s" file))] + [_ (delete-file outfile)] + [p3 (open-output-file outfile)]) + + (printf "----------PROGRAM----------~n") + (for-each + (lambda (def) + (pretty-debug-topo def) + (pretty-print def p3)) + nu-program) + + (close-output-port p3) + outfile))) + +; ====================================================================== + +(define zodiac:value? + (match-lambda + [(or + ($ zodiac:quote-form) + ($ zodiac:lambda-form) + ($ zodiac:case-lambda-form) + ($ zodiac:lexical-varref)) #t] + [($ zodiac:letrec-values-form + _ _ _ _ vars + ((? zodiac:value?) ...) + (? zodiac:value?)) #t] + [_ #f])) + +;; ---------------------------------------------------------------------- + +(define r4rs-prims + `((define caar (lambda (x) (car (car x)))) + (define cadr (lambda (x) (car (cdr x)))) + (define cdar (lambda (x) (cdr (car x)))) + (define cddr (lambda (x) (cdr (cdr x)))) + (define caaar (lambda (x) (car (car (car x))))) + (define caadr (lambda (x) (car (car (cdr x))))) + (define cadar (lambda (x) (car (cdr (car x))))) + (define caddr (lambda (x) (car (cdr (cdr x))))) + (define cdaar (lambda (x) (cdr (car (car x))))) + (define cdadr (lambda (x) (cdr (car (cdr x))))) + (define cddar (lambda (x) (cdr (cdr (car x))))) + (define cdddr (lambda (x) (cdr (cdr (cdr x))))) + (define caaaar (lambda (x) (car (car (car (car x)))))) + (define caaadr (lambda (x) (car (car (car (cdr x)))))) + (define caadar (lambda (x) (car (car (cdr (car x)))))) + (define caaddr (lambda (x) (car (car (cdr (cdr x)))))) + (define cadaar (lambda (x) (car (cdr (car (car x)))))) + (define cadadr (lambda (x) (car (cdr (car (cdr x)))))) + (define caddar (lambda (x) (car (cdr (cdr (car x)))))) + (define cadddr (lambda (x) (car (cdr (cdr (cdr x)))))) + (define cdaaar (lambda (x) (cdr (car (car (car x)))))) + (define cdaadr (lambda (x) (cdr (car (car (cdr x)))))) + (define cdadar (lambda (x) (cdr (car (cdr (car x)))))) + (define cdaddr (lambda (x) (cdr (car (cdr (cdr x)))))) + (define cddaar (lambda (x) (cdr (cdr (car (car x)))))) + (define cddadr (lambda (x) (cdr (cdr (car (cdr x)))))) + (define cdddar (lambda (x) (cdr (cdr (cdr (car x)))))) + (define cddddr (lambda (x) (cdr (cdr (cdr (cdr x)))))) + (define list (lambda a a)) + (define length + (lambda (a) + (recur loop ((a a) (len 0)) + (if (null? a) + len + (loop (cdr a) (+ 1 len)))))) + (define append + (lambda a + (letrec ((app2 (lambda (a b) + (if (null? a) + b + (cons (car a) (app2 (cdr a) b)))))) + (recur loop ((a a)) + (cond ((null? a) '()) + ((null? (cdr a)) (car a)) + (else (app2 (car a) (loop (cdr a))))))))) + (define reverse + (lambda (a) + (recur loop ((a a) (acc '())) + (if (null? a) + acc + (loop (cdr a) (cons (car a) acc)))))) + (define list-tail + (lambda (a n) + (if (zero? n) + a + (list-tail (cdr a) (- n 1))))) + (define list-ref + (lambda (a n) + (if (zero? n) + (car a) + (list-ref (cdr a) (- n 1))))) + (define memq + (lambda (x a) + (cond ((null? a) #f) + ((eq? x (car a)) a) + (else (memq x (cdr a)))))) + (define memv + (lambda (x a) + (cond ((null? a) #f) + ((eqv? x (car a)) a) + (else (memv x (cdr a)))))) + (define member + (lambda (x a) + (cond ((null? a) #f) + ((equal? x (car a)) a) + (else (member x (cdr a)))))) + (define assq + (lambda (x a) + (cond ((null? a) #f) + ((eq? x (car (car a))) (car a)) + (else (assq x (cdr a)))))) + (define assv + (lambda (x a) + (cond ((null? a) #f) + ((eqv? x (car (car a))) (car a)) + (else (assv x (cdr a)))))) + (define assoc + (lambda (x a) + (cond ((null? a) #f) + ((equal? x (car (car a))) (car a)) + (else (assoc x (cdr a)))))) + (define string->list + (lambda (s) + (recur loop ((n (- (string-length s) 1)) (acc '())) + (if (negative? n) + acc + (loop (- n 1) (cons (string-ref s n) acc)))))) +; (define list->string +; (lambda (a) +; (apply string a))) + (define list->string + (lambda (a) + (letrec ([length + (lambda (a) + (recur loop ((a a) (len 0)) + (if (null? a) + len + (loop (cdr a) (+ 1 len)))))]) + (let ((s (make-string (length a)))) + (recur loop ((i 0) (a a)) + (if (null? a) + s + (begin + (string-set! s i (car a)) + (loop (+ 1 i) (cdr a))))))))) + (define vector->list + (lambda (v) + (recur loop ((n (- (vector-length v) 1)) (acc '())) + (if (negative? n) + acc + (loop (- n 1) (cons (vector-ref v n) acc)))))) +; (define list->vector +; (lambda (a) +; (apply vector a))) + (define list->vector + (lambda (a) + (letrec ([length + (lambda (a) + (recur loop ((a a) (len 0)) + (if (null? a) + len + (loop (cdr a) (+ 1 len)))))]) + (if (null? a) + (vector) + (let ((v (make-vector (length a) (car a)))) + (recur loop ((i 1) (a (cdr a))) + (if (null? a) + v + (begin + (vector-set! v i (car a)) + (loop (+ 1 i) (cdr a)))))))))) + (define map + (lambda (f a . args) + (letrec ((map1 (lambda (f l) + (if (null? l) + '() + (cons (f (car l)) + (map1 f (cdr l)))))) + (map2 (lambda (f l1 l2) + (cond ((null? l1) + '()) + ((null? l2) + (error 'map "lists differ in length")) + (else + (cons (f (car l1) (car l2)) + (map2 f (cdr l1) (cdr l2))))))) + (map* (lambda (f l*) + (if (null? (car l*)) + '() + (cons (let ((l (map1 car l*))) + (if (null? l) + (f) + (apply f l))) + (map* f (map1 cdr l*))))))) + (cond ((null? args) + (map1 f a)) + ((null? (cdr args)) + (map2 f a (car args))) + (else + (map* f (cons a args))))))) + (define for-each + (lambda (f a . args) + (letrec ((map (lambda (f l) + (if (null? l) + '() + (cons (f (car l)) + (map f (cdr l))))))) + (letrec ((for-each1 (lambda (f l) + (if (null? l) + (void) + (begin + (f (car l)) + (for-each1 f (cdr l)))))) + (for-each2 (lambda (f l1 l2) + (cond ((null? l1) + (void)) + ((null? l2) + (error 'for-each "lists differ in length")) + (else + (f (car l1) (car l2)) + (for-each2 f (cdr l1) (cdr l2)))))) + (for-each* (lambda (f l*) + (if (null? (car l*)) + (void) + (begin + (let ((l (map car l*))) + (if (null? l) + (f) + (apply f l))) + (for-each* f (map cdr l*))))))) + (cond ((null? args) + (for-each1 f a)) + ((null? (cdr args)) + (for-each2 f a (car args))) + (else + (for-each* f (cons a args)))))))) + (define call-with-input-file + (lambda (s f) + (let* ((p (open-input-file s)) + (v (f p))) + (close-input-port p) + v))) + (define call-with-output-file + (lambda (s f) + (let* ((p (open-output-file s)) + (v (f p))) + (close-output-port p) + v))) + (define with-input-from-file + (lambda (s f) + ; no way to switch current input in R4RS Scheme + (error 'with-input-from-file "not supported") + (f))) + (define with-output-to-file + (lambda (s f) + ; no way to switch current output in R4RS Scheme + (error 'with-output-to-file "not supported") + (f))) + + (define make-promise + (lambda (thunk) + (let ([first #t] + [val #f]) + (lambda () + (cond + [(eq? first 'forcing) + (error 'force "recursive force")] + [(eq? first #t) + (set! first 'forcing) + (set! val (thunk)) + (set! first #f) + val] + [else val]))))) + (define force (lambda (promise) (promise))) + (define make-list + (lambda (n val) + (recur loop ((n n)) + (if (< n 1) + '() + (cons val (loop (- n 1))))))) + (define andmap + (lambda (f list0 . lists) + (if (null? list0) + (and) + (recur loop ((lists (cons list0 lists))) + (if (null? (cdr (car lists))) + (apply f (map car lists)) + (and (apply f (map car lists)) + (loop (map cdr lists)))))))) + (define ormap + (lambda (f list0 . lists) + (if (null? list0) + (or) + (recur loop ((lists (cons list0 lists))) + (if (null? (cdr (car lists))) + (apply f (map car lists)) + (or (apply f (map car lists)) + (loop (map cdr lists)))))))) + (define dynamic-wind + (lambda (in doit out) + (let* ([a (in)] + [b (doit)] + [c (out)]) + b))) + (define not (lambda (x) (if x #f #t))) + (define add1 (lambda (x) (+ x 1))) + (define sub1 (lambda (x) (- x 1))) + (define equal? + (lambda (x y) + (or (eqv? x y) + (and (pair? x) (pair? y) + (equal? (car x) (car y)) + (equal? (cdr x) (cdr y))) + (and (vector? x) (vector? y) + (= (vector-length x) (vector-length y)) + (recur loop ([i (vector-length x)]) + (or (zero? i) + (let ([i (- i 1)]) + (and (equal? (vector-ref x i) (vector-ref y i)) + (loop i))))))))) + (define negative? (lambda (x) (< x 0))) + (define list? (lambda (x) (or (null? x) + (and (pair? x) (list? (cdr x)))))) + (define reverse! + (lambda (x) + (recur loop ([x x][p '()]) + (let ([q (cdr x)]) + (set-cdr! x p) + (if (null? q) + x + (loop q x)))))) + (define even? (lambda (x) (or (zero? x) (odd? (sub1 x))))) + (define odd? (lambda (x) (even? (sub1 x)))) +)) + +(define real-primitives + '(car cdr zero? null? nil null + - * / apply + number? cons pair? + < > <= >= = <> + vector make-vector vector-length vector-ref vector-set! + void error display newline remainder quotient modulo abs expt min + real-part even sqrt cos integer? exact? + eq? eqv? + call-with-values + boolean? procedure? symbol? gensym + set-cdr! set-car! printf random + string-ref symbol->string number->string symbol? char=? + char? string? vector? + #%eqv #%void + string->symbol string-append stringfile-thunk* files)] + [defs1 (load-parse-expand file-thunk*)] + [_ (set! defs-expanded defs1)] + [defs2 (map bind-def defs1)] + [_ (set! defs-bind defs2)] + [def (topological-sort defs2)]) + (zodiac:expr-stripper def))) + +(define (test-topo files out) + (when (file-exists? out) (delete-file out)) + (let* ([file-thunk* (files->file-thunk* files)] + [defs1 (load-parse-expand file-thunk*)] + [_ (set! defs-expanded defs1)] + [defs2 (map bind-def defs1)] + [_ (set! defs-bind defs2)] + [def (topological-sort defs2)]) + (pretty-print (zodiac:expr-stripper def)))) + +;; ---------------------------------------------------------------------- diff --git a/collects/mrspidey/Sba/program.ss b/collects/mrspidey/Sba/program.ss new file mode 100644 index 0000000..3d57558 --- /dev/null +++ b/collects/mrspidey/Sba/program.ss @@ -0,0 +1,127 @@ +;; program.ss +;; Handles cormac's program first-order structure for units +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; Global environment stuff + +(define global-def-env '()) +(define global-result (void)) +(define global-defs-parsed (void)) + +;; ---------------------------------------------------------------------- + +(define (analyze-program file) + ;; file should be normalized + (let ([file (normalize-path file)]) + (pretty-debug `(analyze-program ,file , (path-only (normalize-path file)))) + (init-constructor-env!) + (initialize-language!) + (init-expand!) + (clear-file-time-cache!) + (let*-vals + ( [sexps (zodiac:read* (open-code-file file) file)] + [_ (when debugging-front + (printf "~n--Loaded program------------------~n") + (for-each + (lambda (sexp) (pretty-print-debug (zodiac:stripper sexp))) + sexps) + (printf "----------------------------------~n"))] + [(defs free-names) + (parameterize ([current-load-relative-directory (path-only file)]) + (my-scheme-expand-program sexps))] + [_ (set! global-defs-parsed defs)] + [_ (when debugging-front + (printf "~n--Parsed program------------------~n") + (for-each + (lambda (def) (pretty-print-debug (zodiac:stripper def))) + defs) + (printf "----------------------------------~n"))] + [init-env (get-default-bindings free-names)]) + + (pretty-debug `(init-env ,(atenv->pretty init-env))) + ;; Now do analyis + + (let-values ([(env refs result) (top-level-traverse-defs defs init-env)]) + + (pretty-debug '(fixing up envs)) + (set! global-def-env env) + (set! global-result result) + ;;(assert (null? refs) refs (map zodiac:binding-var (map car refs))) + '(for-each + (lambda (ref) + (mrspidey:warning + (format "Unbound variable ~s" (zodiac:binding-var (car ref))))) + refs) + + ;; --- Fix up type variables + ;;(set! global-def-env (append global-def-env global-tdef-env)) + (report-duplicate-defs global-tdef-env) + (report-unbound-vars + (connect-refs-defs global-tref-env global-tdef-env)) + (connect-bangs-defs global-tbang-env global-tdef-env) + + (when (not (st:whole-program)) + (put-context-top-s defs env result)) + + ;;(show-stat-small) + + defs)))) + +;; ---------------------------------------------------------------------- + +(define (put-context-top-s defs env result) + (mrspidey:progress "Partial program analysis") + ;;(show-stat-small) + (when result (new-leq-top-s! (FlowType->Tvar result))) + (when (and defs env) + (for-each + (match-lambda + [($ zodiac:define-values-form _ _ _ _ refs) + (for-each + (lambda (ref) + (new-leq-top-s! + (FlowType->Tvar + (atenv:lookup env (zodiac:varref-binding ref))))) + refs)] + [_ (void)]) + defs))) + +;; ---------------------------------------------------------------------- +;; initialize-analysis! + +(define (initialize-analysis!) + (pretty-debug '(initialize-analysis!)) + (init-constructor-env!) + (let ([old-kernel (save-kernel-state)]) + (init-kernel!) + ;; First free old stuff + (when (st:zero-old-constraint-sets) (free-kernel-state! old-kernel))) + (init-global-tenv! '() '() '()) + (init-common-AV!) + (pretty-debug '(analysis-initialized))) + +;; ====================================================================== + +(define (show-global) + (list 'DEF (atenv->pretty global-def-env) + ;;'TDEF (atenv->pretty global-tdef-env) + )) + +;; ---------------------------------------------------------------------- + + + diff --git a/collects/mrspidey/Sba/results.ss b/collects/mrspidey/Sba/results.ss new file mode 100644 index 0000000..ac620a5 --- /dev/null +++ b/collects/mrspidey/Sba/results.ss @@ -0,0 +1,289 @@ +; results.ss +; Shows results of set-based analysis +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +;-------------------------------------------------------------------- +; Configuration + +(define show-val-args #t) +(define show-elements #t) +(define show-AV #t) +(define show-edgeto #t) +(define show-constraint #t) + +;-------------------------------------------------------------------- +; Showing results + +(define st:show (lambda l (for-each show-ftype (apply select l)))) + +(define show-ftype + ; Show value of ftype + (lambda (ftype) + (let* ([num (FlowType-num ftype)] + [arrowto (FlowType-arrowto ftype)] + [arrowfrom (FlowType-arrowfrom ftype)] + [var (FlowType-name ftype)] + [done #f] + [makespaces + (lambda (s) + (if done + (printf "~a [~a]" (padr "" 20) s) + (begin + (set! done #t) + (printf + "~a [~a]" + (padr (symbol->string var) 20) + s))))]) + (when (not (null? arrowto)) + (makespaces "arrowto") + (for-each + (lambda (to) (printf "| ~a " (FlowType-name to))) + arrowto) + (newline)) + (when (not (null? arrowfrom)) + (makespaces "arrowfrom") + (for-each + (lambda (from) (printf "| ~a " (FlowType-name from))) + arrowfrom) + (newline)) + (when (FlowType-type-annotation ftype) + (makespaces "visable") + (if (string? (FlowType-type-annotation ftype)) + (display (FlowType-type-annotation ftype))) + (newline)) + (when (FlowType-values-ftype ftype) + (makespaces "values-type") + (printf "~s~n" (FlowType-name (FlowType-values-ftype ftype)))) + + (if (Tvar? ftype) + (let* ( [Tvar ftype] + [objs (Tvar-objs Tvar)] + [constraints (Tvar-constraints Tvar)] + [edgeto (Tvar-edgeto Tvar)] + [edgefrom (Tvar-edgefrom Tvar)]) + + (if (and show-AV (not (null? (get-Tvar-objs Tvar)))) + (begin + (makespaces "AV ") + (begin0 + (show-sba-objs (get-Tvar-objs Tvar)) + (newline))) + '()) + (if (and show-AV (not (null? (Tvar-orig-objs Tvar)))) + (begin + (makespaces "origAV") + (begin0 + (show-sba-objs (Tvar-orig-objs Tvar)) + (newline))) + '()) + (if #t + (begin + (makespaces "num ") + (printf "~s~n" (FlowType-num Tvar))) + '()) + (if (and show-constraint (not (null? (Tvar-constraints Tvar)))) + (begin + (makespaces "constr") + ;; Show each constraint + (map + (match-lambda + [($ con num template field-no Tvar sign) + (printf "[~s ~s ~s -> ~s] " + (if (template? template) + (template-type template) + template) + field-no sign + (Tvar-name Tvar))] + [($ con-filter num ($ filter bool templates) Tvar) + (printf "[filter ~s ~s -> ~s] " + (map template-type templates) + bool (Tvar-name Tvar))] + [($ con-top-s) + (printf "[top-s] ")]) + (Tvar-constraints Tvar)) + (newline) + '()) + '()) + + (if (and show-edgeto (not (null? edgeto))) + (begin + (makespaces "edgeto") + (map (lambda (to) + (printf "| ~a " (Tvar-name to))) + edgeto) + (newline) + edgeto) + '()) + (if (and show-edgeto (not (null? edgefrom))) + (begin + (makespaces "edgefr") + (map (lambda (from) + (printf "| ~a " (Tvar-name from))) + edgefrom) + (newline) + edgefrom) + '()) + (for-each + (lambda (name get-nt) + (if (and (get-nt Tvar) + (not (null? (get-nt Tvar))) + (not (null? (NT-rhs* (get-nt Tvar))))) + (begin + (makespaces name) + (for-each (match-lambda + [($ rhs grsym nt) + (printf "| ~a ~a " + (grsym->rep grsym) + (if (null? nt) + '() + (nt->sym nt)))]) + (NT-rhs* (get-nt Tvar))) + (newline)) + '())) + (list "L " "U " "PL " "PU " + ) + (list Tvar-L Tvar-U Tvar-PL Tvar-PU + ))) + + (begin + (makespaces "fo-Atype") + (printf "~s~n" (FlowType->pretty ftype))))))) + +(define show-sba-objs + (lambda (objs) + (recur loop2 ([objs objs][dep '()]) + (match objs + [() dep] + [(AV . rest) + (match-let + ([(print-representation . new-dep) + (print-rep-AV AV)]) + (printf "| ~s ~a " (AV-num AV) print-representation) + (loop2 rest (append new-dep dep)))])))) + +(define print-rep-AV + (match-lambda + [($ AV _ template misc fields+ fields-) + (cons + (list + (template-type template) + misc + (map Tvar-name (vector->list fields+)) + (map Tvar-name (vector->list fields-))) + '())])) + +; ---------------------------------------------------------------------- + +(define select + (lambda l + (if (null? l) + list-ftype + ;; list of names and nums + (apply append + (map + (lambda (v) + (filter-map + (lambda (Tvar) + (if (or (and (number? v) + (= (FlowType-num Tvar) v))) + Tvar + #f)) + list-ftype)) + l))))) + +; ---------------------------------------------------------------------- + +(define (prods-NT nt) + (let ([named #f]) + (for-each + (match-lambda + [($ rhs* grsym nt) + (printf "~a -> ~a ~s~n" + (padr (if named + "" + (begin + (set! named #t) + (symbol->string (nt->sym nt)))) + 20) + (padr (grsym->rep grsym) 25) + (nt->sym nt))]) + (NT-rhs* nt)))) + +(define (prods-Tvar Tvar) + ;;(printf "Tvar: ~s~n" (Tvar-name Tvar)) + (for-each + (lambda (nt) + (if (NT? nt) + (prods-NT nt) + (unless (null? nt) + (printf "Warning: Bad nt ~s~n" nt)))) + (list (Tvar-L Tvar) (Tvar-LI Tvar) (Tvar-U Tvar) (Tvar-UI AVS)))) + +(define (st:prods . l) (for-each prods-Tvar (apply select l))) + +; ---------------------------------------------------------------------- + +(define show-stat + (lambda () + (printf "STATISTICS:~n") + (let* + ( [list-ftype (filter Tvar? list-ftype)] + [numTvar (length list-ftype)] + [avg (lambda (x) (/ (truncate (* (/ x numTvar) 100)) 100.0))] + [show (lambda (name f) + (let* ([l (map f list-ftype)] + [num (apply + l)] + [avg (avg num)] + [min (apply min l)] + [max (apply max l)]) + (printf " ~a: Total ~s Avg ~s min ~s max ~s~n" + name num avg min max)))]) + (show "edgeto " (lambda (Tvar) (length (Tvar-edgeto Tvar)))) + ;;(show "edgefrom" (lambda (Tvar) (length (Tvar-edgefrom Tvar)))) + (show "con " (lambda (Tvar) (length (Tvar-constraints Tvar)))) + (show "AV " + (lambda (Tvar) + (let ([objs (Tvar-objs Tvar)]) + (if (Tvar? objs) 0 (length (Tvar-objs Tvar)))))) + (printf "num-AV : ~s~n" num-AV) + (printf "num-Tvar : ~s~n" num-ftype) + (printf "num-AV-a: ~s~n" num-AV-in-Tvar) + ;;(printf "Tvar-tmp : ~s~n" counter-Tvar-tmp) + (match (hash-table-info) + [(size entries clashes) + (printf "Hashtbl : size ~s entries ~s clashes ~s~n" + size entries clashes)]) + ))) + +(define show-stat-small + (lambda () + (printf + "STATS: Size ~s HWM ~s num-Tvar ~s num-AV ~s num-con ~s num-edge ~s num-AV-a ~s~n" + (constraint-system-size) + max-constraint-system-size + num-ftype num-AV num-con + num-edge num-AV-in-Tvar) + (constraint-system-size))) + +(define (empty-vars) + (filter + (lambda (Tvar) + (if (null? (get-Tvar-objs Tvar)) + (Tvar-name Tvar) + #f)) + list-ftype)) diff --git a/collects/mrspidey/Sba/sdl.ss b/collects/mrspidey/Sba/sdl.ss new file mode 100644 index 0000000..ec77eb1 --- /dev/null +++ b/collects/mrspidey/Sba/sdl.ss @@ -0,0 +1,804 @@ +;; sdl.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +; ====================================================================== +; Tvar->SDL compresses, calcs prods and creates sdl + +;(define Tvar 'dummy-Tvar) + +(define sdl-tvar (void)) + +(define (Tvar->SDL Tvar) + (set! sdl-tvar Tvar) + (pretty-debug-sdl2 `(Tvar->SDL ,(Tvar-name Tvar))) + (let*-vals + ( [(Tvar approximated) + (if (eq? (st:sdl-fo) 'basic-types) + (copy-constraint-fo-w/-limits Tvar) + (values Tvar #f))] + [_ (pretty-debug-sdl2 `(Tvar->SDL copied ,(Tvar-name Tvar)))] + [nuTvar + (let*-vals + ([(live-Tvar cvt) + (dynamic-let + ([st:minimize-respect-assignable-part-of-fields + (st:show-assignable-part-of-fields)]) + (pretty-debug-sdl2 + `(st:minimize-respect-assignable-part-of-fields + ,(st:minimize-respect-assignable-part-of-fields))) + (minimize-constraints + (st:sdl-constraint-simplification) + '() (list Tvar) + list-ftype '()))] + [nuTvar (cvt Tvar)]) + (pretty-debug-sdl2 `(nuTvar ,(Tvar-name nuTvar))) + nuTvar)] + [sdl (raw-Tvar->SDL nuTvar #f)]) + (if approximated + `(approx ,sdl) + sdl))) + +;; (define (Tvar->SDL tvar) (Tvar-name tvar)) + +;; ---------------------------------------------------------------------- + +(define (copy-constraint-fo-w/-limits tvar) + + (let*-vals + ( [mk-tvar-dots + (lambda () + (mk-Tvar-init-AV 'dots + (create-AV template-dots '() mt-vector mt-vector)))] + [tvar-L-dots (mk-tvar-dots)] + [tvar-U-dots (mk-tvar-dots)] + [approximated #f] + [ref-tvar-L-dots (lambda () (set! approximated #t) tvar-L-dots)] + [ref-tvar-U-dots (lambda () tvar-U-dots)] + [(tvar-reached? tvar-reached! list-tvar-reached) + (field->set alloc-Tvar-field)] + [(AV-reached? AV-reached! list-AV-reached) + (field->set alloc-AV-field)] + [(tvar-nu tvar-nu!) (alloc-Tvar-field)] + [(AV-nu AV-nu!) (alloc-AV-field)] + [stack (list tvar)] + ) + + ;; doesn't do st:sdl-fo-depth-limit or st:sdl-fo-size-limit + + (recur reach ([tvar tvar]) + (unless (tvar-reached? tvar) + (tvar-reached! tvar) + (for-each + (match-lambda + [(and AV ($ AV _ template _ fields+ fields-)) + (unless (AV-reached? AV) + (AV-reached! AV) + (unless + (or + (and + (not (st:sdl-fo-ivars)) + (memq template-all-ivars + (template-super-templates template))) + (and + (not (st:sdl-fo-struct-fields)) + (memq template-structure + (template-super-templates template)))) + (vector-for-each reach fields+) + (when (eq? template template-lam) + (vector-for-each reach fields-))))]) + (get-Tvar-objs tvar)))) + + (for-each + (lambda (tvar) (tvar-nu! tvar (mk-Tvar 'copy-constraint-fo-w/-limits))) + (list-tvar-reached)) + (for-each + (match-lambda + [(and AV ($ AV _ (? (eqc? template-lam)) misc #(rng) #(dom))) + (AV-nu! AV + (create-AV template-lam++ misc + (vector-map + (lambda (tvar) + (if (tvar-reached? tvar) (tvar-nu tvar) (ref-tvar-L-dots))) + (vector dom rng)) + (vector)))] + [(and AV ($ AV _ template misc fields+ fields-)) + (AV-nu! AV + (create-AV template misc + (vector-map + (lambda (tvar) + (if (tvar-reached? tvar) (tvar-nu tvar) (ref-tvar-L-dots))) + fields+) + (vector-map + (lambda (_) (ref-tvar-U-dots)) + fields-)))]) + (list-AV-reached)) + (for-each + (lambda (tvar) + (let ([nu (tvar-nu tvar)]) + (for-each + (lambda (AV) + (new-AV! nu (AV-nu AV))) + (get-Tvar-objs tvar)))) + (list-tvar-reached)) + (assert (tvar-reached? tvar) 'copy-sdl-size-k) + (pretty-debug-sdl2 + `(copy-constraint-fo-w/-limits + src ,(Tvar-name tvar) + result ,(Tvar-name (tvar-nu tvar)) + size ,(length (list-AV-reached)) ,(length (list-tvar-reached)))) + (values + (tvar-nu tvar) + approximated))) + +;; ---------------------------------------------------------------------- +; raw-Tvar->SDL calcs prods and creates sdl +; +; We use that Tvar-L, Tvar-U and AV-U fields for eq?-ness. +; But by Tvar-L, we really mean prefixes of Tvar-L, etc. + +(define (raw-Tvar->SDL tvar mono) + ;; All reachable tvars are shown + (pretty-debug-sdl2 `(raw-Tvar->SDL ,(Tvar-name tvar))) + ;;(find-nonempty-tvars '() (list tvar)) + (let*-vals + ( [mono-convert + (if mono + (match-lambda + [($ NT tvar 'L) (chk-Tvar-U tvar)] + [nt nt]) + (lambda (nt) nt))] + [(env-crossover env-named-lfp) + (choose-named-nts (chk-Tvar-U tvar) mono-convert)]) + (letrec + ([sdl-ref + (lambda (nt) + (let ([nt (mono-convert nt)]) + (or (ormap + (match-lambda [(z . Y) (and (eq? nt z) Y)]) + env-named-lfp) + (mk-sdl nt))))] + [mk-sdl + (lambda (nt) + (let ([sdl (NT->SDL nt sdl-ref #t)]) + (if (bound-in-env? env-crossover (NT-tvar nt)) + ((if (eq? (NT-type nt) 'U) absunion absintersect) + sdl + (lookup env-crossover (NT-tvar nt))) + sdl)))]) + (let* ([binds + (map + (match-lambda + [(y . name) (list name (mk-sdl y))]) + env-named-lfp)] + [body (sdl-ref (chk-Tvar-U tvar))] + [result (expand-output-type `(rec ,binds ,body))]) + result)))) + +;; ====================================================================== + +(define choose-named-nts + ;; Returns (values env-crossover env-named-lfp) + ;; env-crossover maps Tvar to Xn + ;; env-named-lfp maps NT to Yn + + (lambda (nt mono-convert) + (let* ( [traversed '()] + [named-lfp '()] + [stack '()]) + + (letrec + ( [traverse-convert + (lambda (nt) + (let* ( [nt (mono-convert nt)]) + (unless (memq nt named-lfp) + (let* ( [children '()] + [ref (lambda (nt) + (set! children (cons nt children)) + 'blah)]) + (NT->SDL nt ref #f) + (pretty-debug-sdl + `(traversing ,(nt->sym nt) + children ,(map nt->sym children) + traversed ,(map nt->sym traversed) + stack ,(map nt->sym stack) + )) + + (let ([trivial + (or (null? children) + (match nt + [($ NT tvar 'U) + (and (Tvar? tvar) + (match (Tvar-objs tvar) + [() #t] + [(($ AV _ _ _ fields+)) + (zero? (vector-length fields+))] + [_ #f]))] + [_ #f]))]) + (pretty-debug `(trivial ,(nt->sym nt) ,trivial)) + (when (case (st:naming-strategy) + [(recursive) (memq nt stack)] + [(multiple) (and (memq nt traversed) + (not trivial))] + [(nontrivial) (not trivial)] + [(all) #t]) + ;; Name this element + (pretty-debug-sdl + `(naming ,(nt->sym nt) + ,(if (memq nt traversed) #t #f) + children ,(map nt->sym children) + ,trivial)) + (set! named-lfp (cons nt named-lfp)))) + (unless (memq nt traversed) + (set! traversed (cons nt traversed)) + ;;(pretty-print '(traversing children)) + (let ([oldstk stack]) + (set! stack (cons nt stack)) + (for-each + traverse-convert + children) + (set! stack oldstk)))))))]) + (traverse-convert nt) + (pretty-debug-sdl '(Traversed)) + + (let* ([crossover + (intersect (select-L traversed) (select-U traversed))] + [env-crossover + (map-with-n + (lambda (y n) (cons y (symbol-append 'X (add1 n)))) + (reverse crossover))] + [env-named-lfp + (map-with-n + (lambda (y n) + (cons y (symbol-append 'Y (add1 n) ;;(nt->sym y) + ))) + named-lfp)]) + + (pretty-debug-sdl + `(choose-named-nts + select-L ,(map Tvar-name (select-L traversed)) + select-U ,(map (lambda (x) (and (Tvar? x) (Tvar-name x))) + (select-U traversed)) + crossover ,(map Tvar-name crossover) + named-lfp ,(map nt->sym named-lfp) + traversed ,(map nt->sym traversed))) + + (values env-crossover env-named-lfp)))))) + +; ====================================================================== + +(define (NT->SDL nt ref-nt show?) + (pretty-debug-sdl `(NT->SDL ,(nt->sym nt) ,show?)) + (let ([r + (match nt + [($ NT (? Tvar? tvar) 'U) + (when (st:listify-etc) + (listify-Tvar! tvar) + (boolify-Tvar! tvar) + (atomify-Tvar! tvar) + (sexpify-Tvar! tvar) + (classify-objectify-Tvar! tvar)) + (absUnion + (map + (lambda (AV) (ref-nt (chk-AV-U AV))) + (get-Tvar-objs tvar)))] + [($ NT (? Tvar? tvar) 'L) + (absintersect + (absIntersect + (recur loop ([con* (filter con? (Tvar-constraints tvar))]) + (match con* + [() '()] + [(($ con _ (and template ($ template _ _ _ ref assign)) + _ _ sign) + . _) + (let*-vals + ([ (i-s-tvar* rest) + (filter-map-split + (match-lambda + [($ con _ + (? (lambda (t) (eq? t template))) + f tvar s) + (cons (cons f s) tvar)] + [_ #f]) + con*)] + [ref-i+ + (lambda (i) + (absIntersect + (filter-map + (match-lambda + [(j-s . tvar2) + (and + (equal? (car j-s) i) + (cdr j-s) + (ref-nt (chk-Tvar-L tvar2)))]) + i-s-tvar*)))] + [ref-i- + (lambda (i) + (absUnion + (filter-map + (match-lambda + [(j-s . tvar2) + (and + (equal? (car j-s) i) + (cdr j-s) + (ref-nt (chk-Tvar-U tvar2)))]) + i-s-tvar*)))] + [this + + (cond + [(eq? template template-lam) + (list (ref-i- 0) '*->* (ref-i+ 1))] + [(eq? template template-lam++) + (list (ref-i+ 0) '*->* (ref-i+ 1))] + [(st:show-assignable-part-of-fields) + (list + (template-type template) + (map ref-i+ + (filter number? (vector->list ref))) + (map ref-i- + (filter number? (vector->list assign))))] + [(and + (eq? (vector-length ref) 1) + (not (vector-ref ref 0))) + ;; Show single antimono field + (list (template-type template) (ref-i- 0))] + [else + ;; Only show ref'able fields + (cons + (template-type template) + (map ref-i+ + (filter number? (vector->list ref))))])]) + + (cons this (loop rest)))]))) + (absIntersect + (filter-map + (match-lambda + [($ con-filter _ _ tvar2) + (ref-nt (chk-Tvar-L tvar2))] + [_ #f]) + (Tvar-constraints tvar))) + (absIntersect + (map + (lambda (tvar2) (ref-nt (chk-Tvar-L tvar2))) + (Tvar-edgeto tvar))))] + + [($ NT + (and AV ($ AV _ (and template ($ template _ _ _ ref assign)) + misc fields+ fields-)) + 'U) + (let ([ref-i+ + (lambda (i) + (ref-nt (chk-Tvar-U (vector-ref fields+ i))))] + [ref-i- + (lambda (i) + (ref-nt (chk-Tvar-L (vector-ref fields- i))))]) + + (cond + [(or + (eq? template template-lam) + (eq? template template-lam++)) + + (if (and + (atprim? misc) + (not (eq? (st:primitive-types) 'inferred))) + + ;; Is a primitive + (when show? + (case (st:primitive-types) + [(prim) `(prim ,(atprim-sym misc))] + [(given) (atprim-orig-type misc)])) + + ;; Print as lambda + (let*-vals ( [(dom rng) + (if (eq? template template-lam) + (values (ref-i- 0) (ref-i+ 0)) + (values (ref-i+ 0) (ref-i+ 1)))]) + (when show? + (match + (match misc + [('lam-info nargs restarg) + (pretty-domain-list dom nargs restarg)] + [_ (pretty-domain-list dom 0 #t)]) + [(args ()) + (append args (list '->* rng))] + [(args restarg) + (append args (list restarg '*->* rng))]))))] + + ;; Not a lambda + [(memq (template-type template) '(object class)) + (cons + (template-type template) + (map-with-n + (lambda (ivar-sym n) (list ivar-sym (ref-i+ n))) + misc))] + + [(st:show-assignable-part-of-fields) + (list + (template-type template) + (map ref-i+ (filter number? (vector->list ref))) + (map ref-i- (filter number? (vector->list assign))))] + [(and + (eq? (vector-length ref) 1) + (not (vector-ref ref 0))) + (list (template-type template) (ref-i- 0))] + [(and + (eq? (vector-length ref) 0) + (eq? (vector-length assign) 0) + (st:constants) + (or (number? misc) (symbol? misc) (char? misc))) + (if (symbol? misc) (list 'quote misc) misc)] + [else + (cons + (template-type template) + (map ref-i+ (filter number? (vector->list ref))))]))])]) + + (pretty-debug-sdl `(NT->SDL ,(nt->sym nt) = ,r)) + r)) + +;; ---------------------------------------------------------------------- + +(define (pretty-domain-list dom nargs restarg) + (recur loop ([args '()][dom dom][nargs nargs]) + (match dom + [('cons arg restarg) + (loop (cons arg args) restarg (sub1 nargs))] + [('nil) + (list (reverse args) '())] + ['_ + (cond + [(> nargs 0) + (loop (cons '_ args) '_ (sub1 nargs))] + [restarg + (list (reverse args) '_)] + [else + (list (reverse args) '())])] + [dom (list (reverse args) dom)]))) + +(define (pretty-range-list rng nrngs) + (list '() rng)) + +; ====================================================================== + +(define template-listof (constructor->template 'listof #f)) + +(define template-bool (constructor->template 'bool)) + +(define template-atom (constructor->template 'atom)) + +(define template-sexp (constructor->template 'sexp)) + +; ---------------------------------------------------------------------- + +(define (listify-Tvar! tvar) + ;; If Tvar contains (union nil (cons x tvar)) + ;; then replace by (list x) + ;;(pretty-print (get-Tvar-objs tvar)) + ;; (show-sba-Tvar tvar) + (match (get-Tvar-objs tvar) + [(or + ( ($ AV _ (? (is-template? 'nil))) + ($ AV _ (? (is-template? 'cons)) _ + #(a (? (lambda (d) (eq? d tvar)))))) + ( ($ AV _ (? (is-template? 'cons)) _ + #(a (? (lambda (d) (eq? d tvar))))) + ($ AV _ (? (is-template? 'nil))))) + (set-Tvar-objs! tvar '()) + (new-AV! tvar (create-AV template-listof '() (vector a) (vector)))] + [_ (void)])) + +(define (boolify-Tvar! tvar) + ;; If Tvar contains (union true false) + ;; then replace those by bool + (let* ([bool-things '(true false)]) + (when + (andmap + (lambda (bool-thing) + (ormap + (lambda (AV) (eq? (template-type (AV-template AV)) bool-thing)) + (get-Tvar-objs tvar))) + bool-things) + ;; Do substitution + (set-Tvar-objs! tvar + (filter + (lambda (AV) + (not (memq (template-type (AV-template AV)) bool-things))) + (get-Tvar-objs tvar))) + (new-AV! tvar (create-AV template-bool '() (vector) (vector)))))) + +(define (atomify-Tvar! tvar) + ;; If Tvar contains (union nil num sym str char bool) + ;; then replace those by atom + (let* ([atom-things '(nil num sym str char bool)]) + (when + (andmap + (lambda (atom-thing) + (ormap + (lambda (AV) (eq? (template-type (AV-template AV)) atom-thing)) + (get-Tvar-objs tvar))) + atom-things) + ;; Do substitution + (set-Tvar-objs! tvar + (filter + (lambda (AV) + (not (memq (template-type (AV-template AV)) atom-things))) + (get-Tvar-objs tvar))) + (new-AV! tvar (create-AV template-atom '() (vector) (vector)))))) + +(define (sexpify-Tvar! tvar) + ;; If Tvar l contains (union atom (box l) (vec l) (cons l l)), + ;; then replace those by sexp + (let* ([sexp-things '(atom box cons vec)]) + (when + (andmap + (lambda (sexp-thing) + (ormap + (match-lambda + [($ AV _ ($ template type _ ref) _ fields+) + (and (eq? type sexp-thing) + (or (zero? (vector-length fields+)) + (eq? (vector-ref fields+ 0) tvar)))]) + (get-Tvar-objs tvar))) + sexp-things) + ;; Do substitution + (printf "Do substitution") + (set-Tvar-objs! tvar + (filter + (lambda (AV) + (not (memq (template-type (AV-template AV)) sexp-things))) + (get-Tvar-objs tvar))) + (new-AV! tvar (create-AV template-sexp '() (vector) (vector)))))) + +(define (classify-objectify-Tvar! tvar) + ;; For each ivarset in tvar, + ;; build an object AV + + (pretty-debug-sdl `(classify-objectify-Tvar! ,(FlowType-name tvar))) + + (letrec + ([make-thingy + (lambda (tvar-get-ivars tvar-put-thingy name + ivar-syms parent-ivars) + (recur loop ([ivar-syms ivar-syms][parent-ivars parent-ivars]) + ;; to ivar parents + (for-each + (match-lambda + [($ AV _ + (? (lambda (t) (eq? t template-ivarset))) + ivar-extra-syms + #(parent-parent-ivars)) + (loop + (append ivar-syms ivar-extra-syms) + parent-parent-ivars)] + [_ (void)]) + (Tvar-objs parent-ivars)) + ;; make thingy for this + (when (or + (null? (Tvar-objs parent-ivars)) + (ormap + (lambda (AV) + (not (eq? (AV-template AV) template-ivarset))) + (Tvar-objs parent-ivars))) + (pretty-debug-sdl2 `(all-ivars ,name ,ivar-syms)) + (let* + ( [ivar-syms (list->set ivar-syms)] + [ivar-syms + (sort + (lambda (s1 s2) + (stringstring s1) + (symbol->string s2))) + ivar-syms)] + [n+ (length ivar-syms)] + [template-thingy + (make-template + name n+ 0 + (list->vector + (recur loop ([n 0]) + (if (= n n+) '() (cons n (loop (add1 n)))))) + (vector) + '() + eq?)] + [fields+ + (list->vector + (map + (lambda (ivar-sym) + (let ([tvar-field (mk-Tvar 'object-field)]) + (new-con! tvar-get-ivars + (create-con + (get-ivar-template ivar-sym) + 0 tvar-field #t)) + tvar-field)) + ivar-syms))]) + (pretty-debug-sdl2 `(ivarset ,ivar-syms)) + (new-AV! tvar-put-thingy + (create-AV template-thingy + ivar-syms fields+ (vector)))))))]) + + (for-each + (match-lambda + [($ AV _ + (? (lambda (t) (eq? t template-internal-class))) + misc + #(_ alpha_o _ _ alpha_v)) + + (make-thingy alpha_o tvar 'class '() alpha_v)] + + [($ AV _ + (? (lambda (t) (eq? t template-ivarset))) + ivar-syms + #(parent-ivars)) + + (make-thingy tvar tvar 'object ivar-syms parent-ivars)] + + [_ (void)]) + (Tvar-objs tvar)) + + ;; Now drop any ivar, ivarset and class from the tvar + (set-Tvar-objs! tvar + (filter + (lambda (AV) + (let ([t (AV-template AV)]) + (not + (or + (memq template-all-ivars (template-super-templates t)) + (eq? t template-ivarset) + (eq? t template-internal-class))))) + (Tvar-objs tvar))))) + +; ---------------------------------------------------------------------- + +'(define (copy-depth-k tvar k) + (let*-vals + ( [tvar-dots + (mk-Tvar-init-AV 'dots + (create-AV template-dots '() mt-vector mt-vector))] + [tvar-empty + (mk-Tvar 'depth-k-empty)] + [(tvar-reached? tvar-reached! list-tvar-reached) + (field->set alloc-Tvar-field)] + [(AV-reached? AV-reached! list-AV-reached) + (field->set alloc-AV-field)] + [(tvar-nu tvar-nu!) (alloc-Tvar-field)] + [(AV-nu AV-nu!) (alloc-AV-field)] + ) + + (recur loop ([tvar tvar][k k]) + (when + (and + (not (zero? k)) + (not (tvar-reached? tvar))) + (tvar-reached! tvar) + (for-each + (match-lambda + [(and AV ($ AV _ _ _ fields+)) + (AV-reached! AV) + (vector-for-each + (lambda (tvar2) (loop tvar2 (sub1 k))) + fields+)]) + (get-Tvar-objs tvar)))) + + (for-each + (lambda (tvar) (tvar-nu! tvar (mk-Tvar 'copy-depth-k))) + (list-tvar-reached)) + (for-each + (match-lambda + [(and AV ($ AV _ template misc fields+ fields-)) + (AV-nu! AV + (create-AV template misc + (vector-map + (lambda (tvar) + (if (tvar-reached? tvar) (tvar-nu tvar) tvar-dots)) + fields+) + (vector-map + (lambda (_) tvar-empty) + fields-)))]) + (list-AV-reached)) + (for-each + (lambda (tvar) + (let ([nu (tvar-nu tvar)]) + (for-each + (lambda (AV) + (new-AV! nu (AV-nu AV))) + (get-Tvar-objs tvar)))) + (list-tvar-reached)) + (pretty-debug-sdl2 + `(copy-depth-k + src ,(Tvar-name tvar) + depth ,k + result ,(Tvar-name (tvar-nu tvar)) + size ,(length (list-AV-reached)) ,(length (list-tvar-reached)))) + (tvar-nu tvar))) + +;; ---------------------------------------------------------------------- + +'(define (copy-sdl-size-k tvar k) + + (let*-vals + ( [tvar-dots + (mk-Tvar-init-AV 'dots + (create-AV template-dots '() mt-vector mt-vector))] + [tvar-empty + (mk-Tvar 'depth-k-empty)] + [(tvar-reached? tvar-reached! list-tvar-reached) + (field->set alloc-Tvar-field)] + [(AV-reached? AV-reached! list-AV-reached) + (field->set alloc-AV-field)] + [(tvar-nu tvar-nu!) (alloc-Tvar-field)] + [(AV-nu AV-nu!) (alloc-AV-field)] + [stack (list tvar)] + ) + + (recur loop () + (unless (>= 0 k) + (match stack + [(tvar . rest) + (set! stack rest) + (if (tvar-reached? tvar) + (loop) + (begin + (set! k (sub1 k)) + (tvar-reached! tvar) + (for-each + (match-lambda + [(and AV ($ AV _ _ _ fields+)) + (unless (AV-reached? AV) + (set! k (sub1 k)) + (AV-reached! AV) + (set! stack + (append stack (reverse (vector->list fields+)))))]) + (get-Tvar-objs tvar)) + (loop)))] + [() (void)]))) + + (for-each + (lambda (tvar) (tvar-nu! tvar (mk-Tvar 'copy-depth-k))) + (list-tvar-reached)) + (for-each + (match-lambda + [(and AV ($ AV _ template misc fields+ fields-)) + (AV-nu! AV + (create-AV template misc + (vector-map + (lambda (tvar) + (if (tvar-reached? tvar) (tvar-nu tvar) tvar-dots)) + fields+) + (vector-map + (lambda (_) tvar-empty) + fields-)))]) + (list-AV-reached)) + (for-each + (lambda (tvar) + (let ([nu (tvar-nu tvar)]) + (for-each + (lambda (AV) + (new-AV! nu (AV-nu AV))) + (get-Tvar-objs tvar)))) + (list-tvar-reached)) + (assert (tvar-reached? tvar) 'copy-sdl-size-k k) + (pretty-debug-sdl2 + `(copy-depth-k + src ,(Tvar-name tvar) + depth ,k + result ,(Tvar-name (tvar-nu tvar)) + size ,(length (list-AV-reached)) ,(length (list-tvar-reached)))) + (tvar-nu tvar))) + + + +;; ---------------------------------------------------------------------- + + + diff --git a/collects/mrspidey/Sba/seperate.ss b/collects/mrspidey/Sba/seperate.ss new file mode 100644 index 0000000..8955783 --- /dev/null +++ b/collects/mrspidey/Sba/seperate.ss @@ -0,0 +1,110 @@ +;; seperate.ss +;; Handles seperate compilation part +;; ---------------------------------------------------------------------- + +(define (seperately-analyze-file file-thunk* out-file) + ;; Prepare language + (when (eq? (select-language) 'none) (mrspidey:error "No language selected")) + (init-input-type-expander!) + (init-current-constructor-env!) + + (match-let* + ([defs1 (load-parse-expand file-thunk*)] + [_ (set! defs-expanded defs1)] + [_ (init-kernel!)] + [_ (init-misc-analysis)] + [((out-env* in-env*) ...) + (map-with-n + (lambda (def n) + (mrspidey:progress 'analyze (/ (add1 n) (length defs1))) + (traverse-def def)) + defs1)] + [instantiate-env* + (lambda (env*) + (apply append + (map (lambda (env) + (map + (match-lambda + [(and b (_ . (? AVS? AVS))) b] + [(sym . (? procedure? thunk)) (cons sym (thunk))]) + env)) + env*)))] + [out-env (instantiate-env* out-env*)] + [in-env (instantiate-env* in-env*)] + [extract-AVS (lambda (env) (map cdr env))] + [AVS-out (extract-AVS out-env)] + [AVS-in (extract-AVS in-env)] + [(AVS-live AVS->nu) (minimize-constraints AVS-out AVS-in)] + [convert-env + (lambda (env) + (map + (match-lambda + [(sym . AVS) (cons sym (AVS->nu AVS))]) + env))] + [out-env (convert-env out-env)] + [in-env (convert-env in-env)]) + + (write-constraint-set out-file AVS-live out-env in-env))) + +;; ---------------------------------------------------------------------- + +(define (write-constraint-set file AVS-live out-env in-env) + (let* ([p (open-output-port file)] + [disp (lambda (x) (display x p) (newline p))] + [tag (gensym)] + [rep-constraint + (match-lambda + [($ con _ ($ template type) field-no ($ AVS num)) + (list 'con type field-no num)] + [($ con-filter _ ($ filter sign (($ template types) ...)) + ($ AVS num)) + (list 'con-filter sign types num)])]) + + ;; --- write AV and AVS's + (disp num-AVS) + (disp num-AV) + ;; --- write constructor-env + (disp constructor-env) + ;; --- write AV + (for-each + (lambda (AVS) + (for-each + (match-lambda + [(and AV ($ AV num ($ template type) misc fields)) + (unless (eq? (AV-aux AV) tag) + (disp (list 'AV num type misc (map AVS-num fields))) + (set-AV-aux! AV tag))]) + (AVS-orig-objs AVS))) + list-AVS) + ;; --- write AVS + (for-each + (match-lambda + [($ AVS num orig-objs _ constraints edgeto) + (disp (list `AVS num + (map AVS-num orig-objs) + (map rep-constraint constraints) + (map AVS-num edgeto)))]) + AVS-live) + ;; --- write out-env, in-env + (disp `(out-env ,@(map AVS-nu out-env))) + (disp `(in-env ,@(map AVS-nu in-env))) + ;; --- all done + (close-output-port p))) + +;; ---------------------------------------------------------------------- + +(define (read-constraint-set file) + ;; returns AVS-live out-env in-env +1 +) + +;; ---------------------------------------------------------------------- + +(define (ts file) + (parameterize + ([mrspidey:progress-handler (mrspidey:text-progress)] + [mrspidey:error-handler mrspidey:text-error]) + (seperately-analyze-file (files->file-thunk* file) "test/out.za"))) + + + diff --git a/collects/mrspidey/Sba/sigs.ss b/collects/mrspidey/Sba/sigs.ss new file mode 100644 index 0000000..2bd482d --- /dev/null +++ b/collects/mrspidey/Sba/sigs.ss @@ -0,0 +1,685 @@ +;; sba-sigs.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ---------------------------------------------------------------------- + +(define-signature mzlib:unprefixed-core^ + ( (open mzlib:pretty-print^) + (open mzlib:file^) + (open mzlib:function^) + (open mzlib:compat^) + (open mzlib:string^))) + +(define-signature mrspidey:library-paras^ + (make-parameter-boolean + make-parameter-integer + make-parameter-list)) + +(define-signature mrspidey:library-list^ + (mapLR + mapRL + foldl-with-n + foldr2 + filter + filter-map + filter-map-split + rac + rdc + map-with-n + for-each-with-n + map-ilist + length-ilist + improper? + flatten-ilist + map2 + for-each2 + andmap2 + andmap2len + ormap2 + list-n-copies + count + get-prefix + mklist + nth + list-pos + list-pos-equal + find + index +)) + +(define-signature mrspidey:library-vec^ + ( vector-copy + vector-map1 + vector-map2 + vector-map + vector-for-each-with-n + vector-for-each + vector-andmap1 + vector-andmap2 + vector-andmap + vector-ormap1 + vector-ormap2 + vector-ormap + vector-zero!)) + +(define-signature mrspidey:library-set^ + (empty-set + empty-set? + set + list->set + list->set-equal? + element-of? + cardinality + set<= + set-eq? + union2 + union + setdiff2 + setdiff + intersect2 + intersect)) + +(define-signature mrspidey:library-misc^ + (symbol-append + get-cpu-time + get&return-cpu-time + make-timer + clear-timer! + record-time + strip-string + padl + padr + chop-number + substring? + char-find + file-newer + eqc? + )) + +(define-signature + mrspidey:env^ + ( empty-env lookup-or-fail lookup-or-#f lookup bound-in-env? + extend-env extend-env* join-env bang-env! + env:change-binding env:remove + )) + +(define-signature mrspidey:library^ + ((open mrspidey:library-paras^) + (open mrspidey:library-list^) + (open mrspidey:library-vec^) + (open mrspidey:library-set^) + (open mrspidey:library-misc^) + (open mrspidey:env^))) + +;; ---------------------------------------------------------------------- + +(define-signature mrspidey:interaction^ + (mrspidey:error + mrspidey:warning + mrspidey:internal-error + mrspidey:add-summary + mrspidey:add-summary-handler + mrspidey:progress + mrspidey:progress-handler + record-analyzed-file + record-analyzed-file-hook + +)) + +(define-signature mrspidey:config^ + ( st:restricted + st:name + st:version + + st:fake-reader + st:system-expand + + st:constants + st:const-merge-size + st:if-split + st:flow-sensitive + st:fo-units + st:lazy-fo-units + st:cache-units + st:whole-program + st:special-fo-prims + st:see-void + st:cons-mutable + st:use-fo-ftype + need-label-types + need-explanation + st:zero-old-constraint-sets + st:zero-old-asts + + st:minimize-respect-assignable-part-of-fields + + st:constraint-simplification-poly + st:polymorphism + + st:unit-read-za + st:unit-write-za + st:unit-simplify + st:unit-separate-S + st:save-za-in + + ;; --- Type Viewing Parameters + st:sdl-fo + st:sdl-fo-ivars + st:sdl-fo-struct-fields + st:sdl-fo-depth-limit? + st:sdl-fo-depth-limit + st:sdl-fo-size-limit? + st:sdl-fo-size-limit + st:sdl-constraint-simplification + st:show-assignable-part-of-fields + st:listify-etc + st:sdl-constructor/selector + st:naming-strategy + st:primitive-types + st:expand-output-type + st:sdl-tidy + st:pretty-type-width + + st:check-kernel + st:compare-min-algs + + ;; --- Checking Parameters + st:all-checks + + ;; st:show-filters + ;; st:add-hyper-links + ;; st:dont-combine-definitions + ;; st:structure-opaque + ;; st:library-prims + ;; st:topo-sort + + mrspidey:control-fn + + )) + +(define-signature mrspidey:debugging^ + (debugging + debugging-front + debugging-traverse + debugging-unit + debugging-check + debugging-atenv + debugging-atype + debugging-sdl + debugging-sdl2 + debugging-gui + + debugging-min + debugging-min2 + debugging-few + debugging-gram + debugging-dfa-min + debugging-min-table + debugging-object + + timing-min + + pretty-print-debug + set-debug-flag + )) + +(define-signature mrspidey:CDL^ + ((open mrspidey:config^) + (open mrspidey:debugging^) + (open mrspidey:library^))) + +;; ---------------------------------------------------------------------- +;; Kernel analysis stuff + +(define-signature mrspidey:hash^ + ( init-hash-table + hash-fn hash-fn* + add-entry hash-find hash-table-info + capture-hash-table-state restore-hash-table-state! + prompt-hash-table-state unprompt-hash-table-state! + free-hash-table-state! + )) + +(define-signature + mrspidey:kernel^ + (;; --- Structures + (struct FlowType + (num expr arrowto arrowfrom type-annotation proplist values-ftype)) + num-ftype list-ftype num-edge + add-FlowType-arrow! add-FlowType! + add-FlowType-prop! get-FlowType-prop FlowType-name + + (struct Tvar (objs orig-objs constraints edgeto edgefrom L U)) + + (struct AV (num template misc fields+ fields- U PU)) + (struct template + (type num+ num- ref assign super-templates misc-eq?)) + (struct con (num template field-no tvar misc sign)) + (struct con-filter (num filter tvar)) + (struct filter (sign templates)) + create-filter + mt-vector + + ;; --- Values + num-con + num-AV + num-AV-in-Tvar + + ;; --- Functions + init-kernel! + create-AV + mk-Tvar + create-con create-con-misc create-con-filter + new-edge! new-bidir-edge! new-edge-para new-AV! new-create-AV! new-con! + new-leq-top-s! new-geq-top-s! + mk-Tvar-init-AV + constraint-system-size + get-Tvar-objs + add-AV! add-con! add-edge! + Tvar-name + + save-kernel-state restore-kernel-state! + prompt-kernel-state unprompt-kernel-state! + free-kernel-state! + + alloc-Tvar-field alloc-AV-field field->set + check-kernel-ok + really-check-kernel-ok + check-unreachable + )) + +(define-signature + mrspidey:gram^ + ( ;; --- grsyms + (struct grsym (fn mono)) + (struct grsym-normal (template misc field-no)) + (struct grsym-misc ()) + grsym-eq? + + ;; --- rhs + (struct rhs (grsym nt)) + add-rhs! + + calc-productions! + )) + +;; ---------------------------------------------------------------------- +;; Front end stuff + +(define-signature mrspidey:loadexpand^ + (open-code-file + zodiac:read* + mrspidey:zprogress + strip-hash-percent + system-expand-if-necy + expand-zexp->port + + clear-file-time-cache! + extend-file-time-cache! + zodiac-time + zodiac-time* + + init-expand! + my-scheme-expand-program +)) + +;;(define-signature mrspidey:parser^ (top-level-parse-defs top-level-parse-exp)) + +;; ---------------------------------------------------------------------- + +(define-signature mrspidey:atenv^ + ( atenv:empty + atenv:extend + atenv:extend-mutated + atenv:extend* + atenv:extend-voids + atenv:extend-undefineds + atenv:lookup + atenv:change-binding + atenv:change-bindings + atenv:capture-locs + atenv:unflush + atenv:flush! + atenv->pretty + atenv:domain + atenv:ok? + link-parsed-ftype! + )) + +(define-signature mrspidey:traverse^ + ( top-level-traverse-defs + traverse-defs + ;;traverse-def + traverse-exp + )) + +(define-signature mrspidey:atype^ + ((struct fo-FlowType (def)) + FlowType->Atype + create-fo-FlowType + fo-Atype? poly-atype? + + (struct atconst (c)) + (struct schema (tvar tvar* edges)) + (struct atprim (sym type domain-filters predicate-fn attrs orig-type)) + (struct atthunk (thunk)) + (struct atstruct (struct:sym super-constructors + parent-gen-args + parent-match-args + parent-field-types + parent-list-mutable)) + (struct atvalues (values)) + wrap-value extract-1st-value multiple-value-components + + (struct atunit (imports exports result expr)) + (struct atlunit (ui)) + + FlowType->Tvar + Atype->Tvar + FlowType->pretty + FlowType->SDL + copy-ftype + )) + +(define-signature mrspidey:atlunit^ + (create-atlunit-unit + create-atlunit-cmpd + create-atlunit-reference + + apply-unit + atlunit->atunit + apply-atlunit + + )) + + +(define-signature mrspidey:type-env^ + (global-tref-env + global-tdef-env + global-tbang-env + + add-global-tref! + add-global-tdef! + add-global-tbang! + init-global-tenv! + + connect-bangs-defs + report-duplicate-defs + connect-refs-defs + report-unbound-vars + )) + +;; ---------------------------------------------------------------------- +;; ??? + +(define-signature mrspidey:templates^ + ( constructor->template + constructor-env + set-constructor-env! + extend-constructor-env! + add-constructor! + constructor-alias! + record-super-constructor! + record-super-constructor-of-template! + record-super-template! + + lam-misc-eq? + template-lam + template-lam++ + filter-not-lam + template-cons + template-nil + template-num + template-sym + template-str + template-char + template-void + template-undefined + template-true + template-false + template-promise + template-unit + template-structure + template-mvalues + template-internal-class + template-all-ivars + template-dots + ;;template-ivar-box + template-top-s + template-ivarset + + init-default-constructor-env! + + saved-constructor-env + init-constructor-env! + + get-unit-import-template + get-unit-export-template + get-ivar-template + + type-constructor? + lookup-template + lookup-template-or-error + is-template? + )) + +(define-signature mrspidey:kernel-aux^ + ( make-constructed-AV-template + make-constructed-AV + make-constructed-Tvar + + make-AV-cons + make-con-car + make-con-cdr + make-con-dom + make-con-rng + ;make-con-arg-car + ;make-con-arg-cdr + make-AV-vec + make-AV-lam + + AV-nil + AV-numb + AV-sym + AV-str + AV-char + AV-true + AV-false + AV-void + AV-undefined + AV-top-s + + mk-tvar-nil + mk-tvar-numb + mk-tvar-sym + mk-tvar-str + mk-tvar-char + mk-tvar-void + mk-tvar-undefined + mk-tvar-true + mk-tvar-false + mk-tvar-empty + + init-common-AV! + traverse-simple-const + traverse-const-exact + + Tvar-transitive-edgeto + copy-constraint-set + AV->rep + + ;; --- NTs + (struct NT (tvar type rhs*)) + mk-Tvar-NTs! mk-AV-NTs! + alloc-NT-field + nt->sym + select-L + select-U + chk-Tvar-U + chk-Tvar-L + chk-AV-U + )) + +(define-signature mrspidey:sdl^ + (Tvar->SDL)) + +(define-signature mrspidey:languages^ + ( st:language + initialize-language! + st:numops + get-default-bindings + make-expander-namespace +)) + +; ---------------------------------------------------------------------- + +(define-signature mrspidey:typelang^ + ( absUnion absunion absIntersect absintersect + init-output-type-expander! install-output-type-expander! + init-input-type-expander! + install-input-type-expander! + expand-input-type expand-input-type-err expand-output-type + typevar? + + type->templates + split-schema + schema->con + tschema->con + tschema->con-for-nargs + ;;dom+rng-for-nargs + Tvar-in-type? + primitive->atprim)) + +(define-signature mrspidey:contained^ + (Tvar-containment?)) +; ---------------------------------------------------------------------- + +(define-signature mrspidey:min^ + ( minimize-constraints-&-compare + minimize-constraints + min-record-progress)) + +(define-signature mrspidey:min-live^ + ( copy-live-constraints + copy-live-constraints-noe + calc-live-tvars-nts + copy-constraints-equiv! + follow-antimono-fields)) + +(define-signature mrspidey:find-nonempty-tvars^ + ( copy-nonempty-tvars + find-nonempty-tvars)) + +(define-signature mrspidey:min-live-few-e^ + (copy-live-constraints-few-e)) + +(define-signature mrspidey:hopcroft^ + (Hopcroft-calc-equivalences)) + +(define-signature mrspidey:min-dfa-fast^ + ( minimize-constraints-dfa-min-lub + minimize-constraints-dfa-min-glb)) + +; ---------------------------------------------------------------------- + +(define-signature mrspidey:calc-checks^ + ( calc-checks + calc-type-annotations + (struct annotation (loc)) + (struct check-annotation (text num rest)) + (struct uncheck-annotation (text)) + (struct type-annotation (end-first finish FlowType)) + )) + +(define-signature mrspidey:za^ + (read-za write-za)) + +; ---------------------------------------------------------------------- + +(define-signature mrspidey:program^ + (analyze-program global-def-env initialize-analysis!)) + +(define-signature mrspidey:driver^ + (st:analyze st: st:type-fn st:help st:set-debug)) + +;; ---------------------------------------------------------------------- + +(define-signature + mrspidey:zodiac-aux^ + ( compat compat* + ast-size const-size + unparse-dynamic-letd + stripper + + parsed-ftype set-parsed-ftype! + parsed-check set-parsed-check! + parsed-atprim set-parsed-atprim! + app-tvar-args set-app-tvar-args! + binding-refs set-binding-refs! + binding-mutated set-binding-mutated! + varref-binding + my-create-binding + + lambda-flatten-arglist + + no-location + location-inc + determine-end-first-token + + parsed-value? + free-refs + free-vars + initialize-mutated + free-vars-defs + zero! + inline-begins + )) + +(define-signature mrspidey:zodiac^ + ((open zodiac:system^) (open mrspidey:zodiac-aux^))) + +; ---------------------------------------------------------------------- + +(define-signature mrspidey:hyper^ + ( analysis-set-arrow-filter! + analysis-filter-on? + analysis-get-filters + analysis-shortest-path + analysis-parents + analysis-children + analysis-ancestors + analysis-descendants + analysis-callback + analysis-get-param + analysis-set-param! + calc-annotations + st:analyze-and-make-annotations + + )) + +(define-signature mrspidey:sba^ + ( (open mrspidey:driver^) + (open mrspidey:CDL^) + (open mrspidey:atype^) + (open mrspidey:hyper^) + (open mrspidey:kernel^) + (open mrspidey:calc-checks^) + (open mrspidey:languages^) + (unit zodiac : mrspidey:zodiac^) +)) + +; ---------------------------------------------------------------------- diff --git a/collects/mrspidey/Sba/template.ss b/collects/mrspidey/Sba/template.ss new file mode 100644 index 0000000..b0f442a --- /dev/null +++ b/collects/mrspidey/Sba/template.ss @@ -0,0 +1,303 @@ +;; templates.ss +;; Handles the constructor environment, +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; +;; ====================================================================== +;; Constructor environments: symbol -> template +;; First a helper function + +(define (constructor->template con . modes) + (let* ( [n (length modes)] + [assign (make-vector n #f)] + [ref (make-vector n #f)]) + (recur loop ([i 0][n 0][modes modes]) + (match modes + [() (make-template con n i ref assign '() eqv?)] + [(#t . rest) + (vector-set! ref n n) + (vector-set! assign n i) + (loop (add1 i) (add1 n) rest)] + [(#f . rest) + (vector-set! ref n n) + (vector-set! assign n #f) + (loop i (add1 n) rest)])))) + +;; ====================================================================== +;; The constructor environment + +(define constructor-env (void)) + +(define (set-constructor-env! c) + (set! constructor-env (make-hash-table)) + (hash-table-for-each c + (lambda (key val) + (hash-table-put! constructor-env key val)))) + +(define (extend-constructor-env! template) + (let* ( [type (template-type template)] + [old (hash-table-get constructor-env type (lambda () #f))]) + (if old + (match (list template old) + [( ($ template _ n+1 n-1 ref1 assign1 super1 _) + ($ template _ n+2 n-2 ref2 assign2 super2 _)) + (unless (and (= n+1 n+2) + (= n-1 n-2) + (equal? assign1 assign2) + (equal? ref1 ref2) + (equal? super1 super2)) + (pretty-print-debug + `( (,n+1 ,n-1 ,ref1 ,assign1 ,(map template-type super1)) + (,n+2 ,n-2 ,ref2 ,assign2 ,(map template-type super2)))) + (mrspidey:error + (format "New definition of template ~s does not match old" + type))) + old]) + (begin + (hash-table-put! constructor-env type template) + template)))) + +(define (add-constructor! con . modes) + (extend-constructor-env! (apply constructor->template con modes))) + +(define (constructor-alias! new-con old-con) + (hash-table-put! constructor-env new-con + (lookup-template-or-error old-con))) + +(define (record-super-constructor! super-C C) + (record-super-constructor-of-template! + super-C (lookup-template-or-error C))) + +(define (record-super-constructor-of-template! super-C T) + (record-super-template! (lookup-template-or-error super-C) T)) + +(define (record-super-template! super-T T) + (set-template-super-templates! + T + (cons super-T (template-super-templates T)))) + +;; ====================================================================== +;; Default templates + +;(define-typed-structure (lam-info nargs restarg)) + +(define lam-misc-eq? + (match-lambda* + [(('lam-info nargs1 restarg1) ('lam-info nargs2 restarg2)) + (and (= nargs1 nargs2) (eqv? restarg1 restarg2)) + #t] + [(x y) (eq? x y)])) + +(define template-lam + (make-template + 'lambda + 1 + 1 + (vector #f 0) + (vector 0 #f) + '() + lam-misc-eq?)) + +(define filter-not-lam + (create-filter #f (list template-lam))) + +(define template-lam++ ;; monotonic in both positions + (make-template + 'lambda + 2 + 0 + (vector 0 1) + (vector) + '() + lam-misc-eq?)) + +;; ---------------------------------------------------------------------- + +(define template-top-s (void)) +(define template-cons (void)) +(define template-nil (void)) +(define template-num (void)) +(define template-sym (void)) +(define template-str (void)) +(define template-char (void)) +(define template-void (void)) +(define template-undefined (void)) +(define template-true (void)) +(define template-false (void)) +(define template-promise (void)) +(define template-unit (void)) +(define template-structure (void)) +(define template-mvalues (void)) +(define template-internal-class (void)) +(define template-all-ivars (void)) +(define template-dots (void)) +(define template-ivarset (void)) + +(define (init-default-constructor-env!) + (pretty-debug ' (init-default-constructor-env!)) + ;; These are things needed by the analysis + (set! constructor-env (make-hash-table)) + (hash-table-put! constructor-env 'lambda template-lam) + (set! template-top-s (add-constructor! 'top-s)) + (set! template-cons + (if (st:cons-mutable) + (add-constructor! 'cons #t #t) + (add-constructor! 'cons #f #f))) + (set! template-nil (add-constructor! 'nil )) + (set! template-num (add-constructor! 'num )) + (set! template-sym (add-constructor! 'sym )) + (set! template-str (add-constructor! 'str )) + (set! template-char (add-constructor! 'char )) + (set! template-void (add-constructor! 'void )) + (set! template-undefined (add-constructor! 'undefined)) + (set! template-true (add-constructor! 'true )) + (set! template-false (add-constructor! 'false)) + (set! template-promise (add-constructor! 'promise #f)) + (set! template-unit (add-constructor! 'unit-result* #f)) + (set! template-structure (add-constructor! 'structure:)) + (set! template-mvalues (add-constructor! 'mvalues #f)) + (set! template-internal-class + (extend-constructor-env! + (make-template + 'internal-class + 4 4 + (vector 0 1 2 #f #f 3 #f #f 4) + (vector #f #f #f 0 1 #f 2 3 #f) + '() eq?))) + (set! template-all-ivars + (extend-constructor-env! + (make-template + 'all-ivars + 1 + 0 + (vector 0) + (vector #f) + '() + eq?))) + (set! template-dots (add-constructor! '...)) + (set! template-ivarset (add-constructor! 'ivarset #t)) + ) + +; ====================================================================== +; The "template-prompt" + +(define saved-constructor-env (make-hash-table)) + +(define (init-constructor-env!) + (set! constructor-env saved-constructor-env) + (set! unit-import-export-env (vector (make-hash-table) (make-hash-table))) + (set! object-ivar-template-env (make-hash-table)) + ) + +; ====================================================================== +; Unit templates + +(define unit-import-export-env (vector (make-hash-table) (make-hash-table))) + +(define (get-unit-import-export-template ndx sym thunk) + (hash-table-get + (vector-ref unit-import-export-env ndx) + sym + (lambda () + (let ([template (thunk)]) + (hash-table-put! + (vector-ref unit-import-export-env ndx) + sym template) + template)))) + +(define (get-unit-import-template sym) + (get-unit-import-export-template + 0 sym + (lambda () + (extend-constructor-env! + (make-template + (symbol-append 'unit-import- sym) + 0 + 1 + (vector #f) + (vector 0) + '() + eq?))))) + +(define (get-unit-export-template sym) + (assert (symbol? sym) 'get-unit-export-template) + (get-unit-import-export-template + 1 sym + (lambda () + (extend-constructor-env! + (make-template + (symbol-append 'unit-export- sym) + 1 + 0 + (vector 0) + (vector #f) + '() + eq?))))) + +; ====================================================================== +; Object templates + +(define object-ivar-template-env (make-hash-table)) + +(define (get-ivar-template sym) + (assert (symbol? sym) 'get-ivar-template sym) + (hash-table-get + object-ivar-template-env + sym + (lambda () + (let ([template (make-template + (symbol-append 'ivar- sym) + 1 + 0 + (vector 0) + (vector #f) + '() + eq?)]) + (hash-table-put! object-ivar-template-env sym template) + (record-super-template! template-all-ivars template) + (extend-constructor-env! template) + template)))) + +;; ====================================================================== + +(define (type-constructor? C) + (if + (hash-table-get constructor-env C (lambda () #f)) + #t #f)) + +(define (lookup-template C) + (hash-table-get constructor-env C (lambda () #f))) + +(define (lookup-template-or-error C) + (or (lookup-template C) + (mrspidey:error (format "Unknown type constructor ~s" C)))) + +(define is-template? + (lambda (name) + (lambda (t) + (eq? t (lookup-template name))))) + +;; ====================================================================== + + + + + + + + + diff --git a/collects/mrspidey/Sba/test-sba.ss b/collects/mrspidey/Sba/test-sba.ss new file mode 100644 index 0000000..0add528 --- /dev/null +++ b/collects/mrspidey/Sba/test-sba.ss @@ -0,0 +1,775 @@ +;; test-suite1.ss +;; Development helper file +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ---------------------------------------------------------------------- + +;; Testing files: + +(define (run-test-suites fn) + (letrec ([doit + (case-lambda + [(s) (doit s 0 #f)] + [(s a) (doit s a #f)] + [(s a c) + (fn (string-append "~/Spidey/test-suite/" s)) + (when a + (unless (= (type-assert-failed-total 0) a) + (error 'run-test-suites "Wrong # failed assertions!"))) + (when c + (unless (= (total-checks 0) c) + (error 'run-test-suites "Wrong # checks!")))])]) + + ;; --- Core Scheme + (doit "testall.ss" 1) + (doit "test-const.ss") + (doit "test-exprs.ss") + (doit "test-if-split.ss") + (doit "test-flow.ss") + (doit "test-box.ss") + (doit "test-user-prims.ss") + (doit "test-struct.ss") + (doit "test-mvalues.ss") + (doit "test-checks.ss" 0 6) + (doit "test-no-checks.ss" 0 0) + + ;; --- Objects + (doit "test-obj-syntax.ss") + (doit "test-obj-simple.ss") + (doit "test-obj-thread.ss") + (doit "test-obj-derive.ss") + (doit "mflatt.ss" 0 3) + (doit "../test/trivia/trivia-unit.ss" 0 1) + + ;; --- Units + (dynamic-let ([st:system-expand #t]) + (dynamic-let ([st:fo-units #t]) (doit "test-unit.ss" 0)) + (dynamic-let ([st:fo-units #f]) (doit "test-unit.ss" 0)) + ;;(doit "test-fo-units.ss" 0) + ) + (doit "../test/trivia/trivia-unit.ss" 0 1) + + "MrSpidey passes the test suite :-)" + )) + +;; ---------------------------------------------------------------------- + +(define mred-system + '( + "autoload.ss" + "autosave.ss" + "canvas.ss" + "connect.ss" + "console.ss" + "containr.ss" + "contfram.ss" + "contkids.ss" + "contpanl.ss" + "cparens.ss" + "cppmode.ss" + "edframe.ss" + "edit.ss" + "exit.ss" + "exn.ss" + "fileutil.ss" + "finder.ss" + "findstr.ss" + "frame.ss" + "group.ss" + "guiutils.ss" + "handler.ss" + "html.ss" + "hyper.ss" + "hypersig.ss" + "hyprdial.ss" + "hypredit.ss" + "hyprfram.ss" + "icon.ss" + "include.ss" + "keys.ss" + "link.ss" + "macros.ss" + "mcache.ss" + "menu.ss" + "mode.ss" + "mrsystem.ss" + "noconsle.ss" + "panel.ss" + "paren.ss" + "prefs.ss" + "project.ss" + "sig.ss" + "sparen.ss" + "ssmode.ss" + "url.ss" + "version.ss" + )) +;; ---------------------------------------------------------------------- + +(define benchmark-files + (append + (map (lambda (x) (string-append "~/Spidey/benchmarks/" x ".ss")) + '( + "one" + "const" + "sum" + "qsort" + ;; Programs from experiment + "gauss" + "du" + "hanoi" + "merge" + "np" + "tc" + + "taut" + + ;; Misc others + "sba" + "bignum" + ;;"TC" + "elev" + "dfs-bfs" + "checks" + "gauss-imp" + "gauss-fn" + "Cannibals-sba" + "mst" + ;;"gab-boyer" + ;;"nucleic" -- internal defines, etc + ;;"nucleic2" -- internal defines, etc + ;;"slatex" -- too large + )) + + (map (lambda (x) (string-append "~/Spidey/wright/" x ".scm")) + '( + "boyer" + "browse" + "check" + "nbody" + "graphs1" + "graphs2" + "lattice-cormac" + ;;"dynamic" + )))) + +(define test-files + (append + (list "~/Spidey/test/sum.ss") + (list "~/Spidey/test-suite/testall.ss") + ;; Can't use testnumeric as general test + ;; type annotations require accurate numeric constants + ;; (list "~/Spidey/test-suite/testnumeric.ss") + (map (lambda (x) (string-append "~/Spidey/test/" x ".ss")) + '( + "defstruct" + "defstruct2")) + benchmark-files)) + +'(define test-files + '("~/Spidey/test/one.ss" + "~/Spidey/test/sum.ss" + "~/Spidey/sba/testall.ss" + "~/Spidey/test/du.ss")) + + +;(define test-files '("test/one.ss" "test/test.ss" "test/readlot.ss")) + +;; ====================================================================== +;; Helper functions + +(define (exec-mzscheme exps) + (recur loop ( [s "mzscheme -x -g -a -f /home/cormac/scheme/mzschemerc.ss"] + [exps exps]) + (if (null? exps) + (begin + (printf "Command: ") (display s) (newline) + (system s)) + (loop + (string-append s (format " -e '~s'" (car exps))) + (cdr exps))))) + +(define (for-each-parameter para thunk) + (for-each + (lambda (p) (dynamic-let ([para p]) (thunk p))) + (map car (para '?)))) + +(define (for-each-parameters para-list thunk) + (if (null? para-list) + (thunk) + (for-each-parameter + (car para-list) + (lambda (x) + (for-each-parameters (cdr para-list) thunk))))) + +(define (for-each-quoted-parameters para-list thunk) + (recur loop ([l para-list][d '()]) + (match l + [() + (printf "CONFIGURATION: ~s~n" d) + (thunk)] + [(p . rest) + (for-each-parameter + (eval p) + (lambda (x) (loop (cdr l) (cons `(,p ,x) d))))]))) + +(define (smart-for-each-quoted-parameters para-list limit thunk) + (for num-chgs 0 (add1 (min limit (length para-list))) + ;; Try changing num-chgs parameters + (recur loop ([l para-list][d '()][n num-chgs]) + (match l + [() + (when (zero? n) + ;; run the test + (printf "CONFIGURATION: num-chgs=~s ~s~n" num-chgs d) + (thunk))] + [(p . rest) + (let* ([para (eval p)] + [options (map car (para '?))] + [default (car options)]) + ;; --- First don't change + (dynamic-let + ([para default]) + (loop rest (cons `(,p ,default) d) n)) + ;; Now change + (unless (zero? n) + (for-each + (lambda (v) + (dynamic-let + ([para v]) + (loop rest (cons `(,p ,v) d) (sub1 n)))) + (cdr options))))])))) + +(define (for-every-nth f l n) + (recur loop ([i (random (inexact->exact n))][l l]) + (unless (null? l) + (if (zero? i) + (begin + (f (car l)) + (loop n (cdr l))) + (loop (sub1 i) (cdr l)))))) + +; ====================================================================== +; Check minimization algorithms preserve meaning + +(define min-algs-to-check + '( none + nonempty + nonempty-copy + live + live-few-e + ;live-few-e-L + ;live-few-e-U + ;(live-few-e dfa-min) + ;(live-few-e dfa-min-inv) + ;(live-few-e dfa-min-inv dfa-min) + ;(live-few-e dfa-min dfa-min-inv) + + ;(live-few-e dfa-min-1) + ;(live-few-e dfa-min-1) + ;(live-few-e dfa-min-2) + ;(live-few-e dfa-min-2) + ;(live-few-e dfa-min-1 live dfa-min-2) + ;(live-few-e dfa-min-2 live dfa-min-1) + + (dfa-min-lub) + (dfa-min-glb) + (dfa-min-lub dfa-min-glb) + (dfa-min-glb dfa-min-lub) + + ;(live-few-e min-table) + )) + +(define (check-min-ok-file file) + (let* + ( [defs (analyze-program file)] + [type-annotations (calc-type-annotations defs)] + [tvar* (filter Tvar? (map type-annotation-FlowType type-annotations))] + ;;[_ (pretty-print `(Tvar* ,(map Tvar-name tvar*)))] + [min-algs min-algs-to-check] + [p (make-parameter-list + (car min-algs) + (map (lambda (x) (list x "")) min-algs))] + [min-con-1 + (lambda (which Tvar) + (let*-vals + ([(_ Tvar->nutvar) + (minimize-constraints which '() (list Tvar) '() '())]) + (Tvar->nutvar Tvar)))]) + + (printf "Testing ~s, ~s Tvar~n" file (length tvar*)) + ;; Compression algorithms don't preserve filters, + ;; so turn all filters into edges + (for-each + (lambda (tvar) + (when (Tvar? tvar) + (set-Tvar-constraints! + tvar + (filter + (match-lambda + [($ con) #t] + [($ con-filter _ _ to) + (new-edge! tvar to) + #f]) + (Tvar-constraints tvar))))) + list-ftype) + + (for-each-parameter + p + (lambda (v) + (printf "Minimization strategy ~s~n" v) + (for-each + (lambda (Tvar) + (printf ".") (flush-output) + (let* ( [live-copy (min-con-1 'none Tvar)] + [p-copy (min-con-1 (p) Tvar)]) + (Tvar-equiv? + (lambda () + (printf "Original is:~n") + (pretty-print (Tvar-name Tvar))) + "Live copy" live-copy + (format "~s p-copy" (p)) p-copy))) + tvar*) + (newline))))) + +(define (Tvar-equiv? fail-thunk name-A A name-B B) + (let* ( [c1 (Tvar-containment? A B)] + [c2 (Tvar-containment? B A)]) + (unless (and c1 c2) + (fail-thunk) + (printf "~a is:~n" name-A) + (pretty-print (Tvar-name A)) + (printf "~a is:~n" name-B) + (pretty-print (Tvar-name B)) + (if c1 + (printf "~s is larger!~n" name-B) + (printf "~s is smaller!~n" name-B)) + (error 'Tvar-equiv? "Failure!")))) + +(define (check-min-ok-all) + (for-each check-min-ok-file benchmark-files)) + +;; ====================================================================== + +(define (check-type-file f) + (printf "==================================================~n") + (printf "File: ~s~n" f) + (st: f) + (pretty-print (st:type))) + +; ====================================================================== + +(define (check-SDL-file f) + (printf "==================================================~n") + (printf "File: ~s~n" f) + (st: f) + (let* ([l list-ftype]) + (for-each-parameter + st:type-compression + (lambda (t) + (printf "----------------------------------------~n") + (printf "Type compression: ~s~n" t) + (for-each + (lambda (Tvar) + (when (Tvar? Tvar) + (printf "~s~n" (Tvar-name Tvar)) + (flush-output) + (let ([sdl (Tvar->SDL Tvar)]) + (void)))) + l))))) + +;; ---------------------------------------------------------------------- + +(define (check-SDL2-file f) + (printf "==================================================~n") + (printf "File: ~s~n" f) + (st: f) + (let* ([l list-ftype] + [len (length l)]) + (smart-for-each-quoted-parameters + '(st:type-compression + st:primitive-types + st:naming-strategy ) + 2 + (lambda () + (for-every-nth + (lambda (Tvar) + (when (Tvar? Tvar) + (printf "~s " (FlowType-num Tvar)) + (flush-output) + (let ([sdl (Tvar->SDL Tvar)]) + (void)))) + l + ;; do (* 3 (sqrt len)) cases + (truncate (/ len (* 3 (sqrt len))))) + (newline))))) + +;; ---------------------------------------------------------------------- + + +;; ### DOESNT WORK CAUSE LISTIFY ETC +(define (check-SDL3-file f) + (printf "==================================================~n") + (printf "File: ~s~n" f) + (st: f) + (let* ([l list-ftype] + [len (length l)]) + (dynamic-let ([st:primitive-types 'inferred]) + (smart-for-each-quoted-parameters + '(st:type-compression + st:naming-strategy ) + 1 + (lambda () + (for-every-nth + (lambda (Tvar) + (when (Tvar? Tvar) + (printf "~s " (FlowType-num Tvar)) + (flush-output) + (let*-vals + (;; minimize w/ live + [(_ Tvar->nutvar) + (minimize-constraints 'live '() (list Tvar))] + [tvar-live (Tvar->nutvar Tvar)] + [sdl (dynamic-let + ([st:listify-etc #f]) + (Tvar->SDL tvar-live))] + [tvar2 (mk-Tvar 'check-SDL3)]) + (pretty-print sdl) + (tschema->con + (expand-input-type sdl) + tvar2 'check-SDL3: '()) + (Tvar-equiv? + (lambda () + (pretty-print + `( st:type-compression ,(st:type-compression) + st:naming-strategy ,(st:naming-strategy) + sdl ,sdl))) + "Live" tvar-live + "Regenerated" tvar2)))) + l + ;; do (* 3 (sqrt len)) cases + (truncate (/ len (* 3 (sqrt len))))) + (newline)))))) + +;; ====================================================================== + +(define (acid-test-analysis sub-test) + (lambda (f) + (smart-for-each-quoted-parameters + '(st:constants + st:if-split + st:flow-sensitive + st:numops + st:special-fo-prims + ;;st:system-expand + st:see-void) + 3 + (lambda () (sub-test f))))) + +(define (acid-acid-test-analysis f) + ((acid-test-analysis acid-test-SDL) f)) + +;; ---------------------------------------------------------------------- + +(define (all-test-sba-terminates) + (for-each acid-test-SDL test-files) + (for-each acid-acid-test-analysis test-files)) + +;; ====================================================================== + +(define compare-min-file-results (void)) +(define (compare-min-file file) + (set! compare-min-file-results '()) + (for-each-parameter + st:unit-simplify + (lambda (p) + (unless (eq? p 'none) + (pretty-print `(st:unit-simplify ,p)) + (let*-vals + ( [(_ t real-t) (time-apply (lambda () (st: file)))]) + (set! compare-min-file-results + (cons (list p t) compare-min-file-results)) + (pretty-print + `(compare-min-file-results ,compare-min-file-results)))))) + compare-min-file-results) + +;; ====================================================================== +;; EXPERIMENT A +;; +;; Figure describing Behavior of Constraint Compression Algorithms + +(define compress-files + (map (lambda (x) (string-append "~/papers/compress/bench/compress/" x ".ss")) + '( + "t" + "map" + "reverse2" + "substring" + "qsortmod" + "unify" + "hopcroft" + "check-mod" + "escher" + "scanner" + ))) + +(define (fig6-file file) + (dynamic-let ( [st:compare-min-algs #t] + [st:unit-read-za #f] + [st:unit-write-za #f] + [st:use-fo-ftype #f] + [st:polymorphism 'compress] + [st:if-split #f] + [st:flow-sensitive #f] + [st:unit-separate-S #f] + ) + (st:analyze file))) + +(define (fig6) + (for-each fig6-file compress-files)) + +;; ====================================================================== +;; EXPERIMENT B +;; +;; Polymorphic analysis times + +(define wright-files + (map (lambda (x) (string-append "~/papers/compress/bench/poly/" x ".ss")) + '( + "t" + "lattice" + "browse" + "splay" + "check" + "graphs" + "boyer" + "matrix" + "maze" + "nbody" + "nucleic-3" + ;; "dynamic" + + ))) + +;(define wright-poly-files +; (map (lambda (file) (regexp-replace ".ss$" file ".poly.ss")) +; wright-files)) + +(define fig7-algs + '( (traverse none) + (none none) + (compress (dfa-min-lub)) + (compress (dfa-min-glb)) + (compress live-few-e) + (compress live) + (compress nonempty) + (compress none) + ;;(copy-con none) + (reanalyze none))) + +(define (fig7-file-alg a b file) + (dynamic-let ( [st:polymorphism (if (eq? a 'traverse) 'none a)] + [st:type-compression-poly b] + [st:use-fo-ftype #f] + [st:if-split #f] + [st:flow-sensitive #f] + [keep-S-closed (if (eq? a 'traverse) #f (keep-S-closed))]) + (printf "--------------------------------------------------------~n") + (printf "FILE: ~s ANALYSIS ~s~n" file (list a b)) + (clear-counters!) + (set! need-label-types #t) + (st: file) + (printf "FILE: ~s ANALYSIS ~s~n" file (list a b)) + (show-counters) + (show-stat-small) + (list a b (get-counter 'top-level-traverse-defs)))) + +(define (fig7-file file) + (let* ( [file (topo-file file)] + [r (map + (match-lambda [(a b) (fig7-file-alg a b file)]) + fig7-algs)]) + (pretty-print `(RESULTS-FOR ,file ,r)) + (list file r))) + +(define (fig7) + (recur loop ([files wright-files][r* '()]) + (unless (null? files) + (let* ( [r (fig7-file (car files))] + [r* (append r* (list r))]) + (pretty-print `(RESULTS-TO-DATE ,r*)) + (loop (cdr files) r*))))) + +(define (fig7s-file file) + ;; Spawns nu mzscheme each time + (let* ( [file (topo-file file)]) + (for-each + (match-lambda + [(and analyze (a b)) + (printf "--------------------------------------------------------~n") + (printf "FILE: ~s ANALYSIS ~s~n" file analyze) + (exec-mzscheme + `( (define __NO_DEBUGGING 1) + (ST) + (set! mrspidey:zprogress (lambda x 1)) + (fig7-file-alg (quote ,a) (quote ,b) ,file) + (exit)))]) + fig7-algs))) + +(define (fig7s) + (for-each fig7s-file (cdr wright-files))) + +;; ====================================================================== +;; EXPERIMENT C +;; Test how analysis scales to large programs +;; Have: +;; analyze-scanner.ss +;; analyze-zodiac.ss +;; analyze-small.ss - part of sba analysis +;; analyze-no-min.ss - sba except minimization +;; analyze.ss - all of sba +;; +;; analyze-CDL.ss - usless, units never used +;; analyze-min.ss - useless, units never used + +(define (test-scalable-alg alg file) + (printf "--------------------------------------------------------~n") + (printf "FILE: ~s SIMPLIFICATION ~s~n" file alg) + (dynamic-let ( [st:unit-simplify (if (eq? alg 'traverse) 'none alg)] + [st:use-fo-ftype #f] + [st:if-split #f] + [st:flow-sensitive #f] + [keep-S-closed (if (eq? alg 'traverse) #f (keep-S-closed))] + [st:unit-read-za #f] + [st:unit-write-za #f] + [st:unit-separate-S #t]) + (clear-counters!) + (st:analyze file) + (printf "FILE: ~s SIMPLIFICATION ~s~n" file alg) + (show-counters) + (pretty-print (st:control)) + (show-stat-small))) + +(define (bad-alg-for-file? alg file) + (cond + [(equal? file "analyze-small.ss") + ;; none ran to 404M + (memq alg '(none nonempty))] + [(equal? file "analyze-no-min.ss") + (memq alg '(none nonempty))] + [(equal? file "analyze.ss") + (memq alg '(none nonempty nonempty-copy))] + [(equal? file "~/papers/compress/bench/separate/nucleic/nucleic.ss") + (memq alg '())] + [else #f])) + +(define (test-scalable-file file) + (for-each + (lambda (t) + (unless (bad-alg-for-file? t file) + (exec-mzscheme + `( (define __NO_DEBUGGING 1) + (ST) + ;;(expander-eval (quote (defmacro cache-exp (exp za) exp))) + ;;(expander-eval (quote (defmacro cache-inv (exp za) exp))) + (set! mrspidey:zprogress (lambda x 1)) + (test-scalable-alg (quote ,t) ,file) + (exit))))) + '(traverse none nonempty live live-few-e dfa-min-lub dfa-min-glb))) + +(define (test-scalable-all) + (for-each test-scalable-file + '( "analyze-scanner.ss" + "analyze-zodiac.ss" + "analyze-small.ss" + "analyze-no-min.ss" + "analyze.ss"))) + +;; ====================================================================== +;; EXPERIMENT D +;; Test separate analysis + +(define (test-separate-analyze alg read-za file) + (printf "--------------------------------------------------------~n") + (printf "FILE: ~s SIMPLIFICATION ~s ~s~n" file alg read-za) + (let ([files '()]) + (dynamic-let + ( [st:unit-simplify (if (eq? alg 'traverse) 'none alg)] + [st:use-fo-ftype #f] + [st:if-split #f] + [st:flow-sensitive #f] + [keep-S-closed (if (eq? alg 'traverse) #f (keep-S-closed))] + [st:unit-separate-S #t] + [st:unit-read-za read-za] + [st:unit-write-za #t] + [st:unit-separate-S #t] + [record-analyzed-file-hook + (lambda (filename . _) + (printf "Record-analyzed-file ~s~n" filename) + (set! files (cons filename files)))]) + (clear-counters!) + (st:analyze file) + (printf "FILE: ~s SIMPLIFICATION ~s ~s~n" file alg read-za) + (show-counters) + (pretty-print (st:control)) + (show-stat-small) + (printf "ZA FILES:~n") + (system + (foldr + (lambda (file acc) + (string-append acc " " (regexp-replace "-source$" file ""))) + "wc " + files))))) + +(define (test-separate-alg alg file module-file) + (assert (file-exists? module-file)) + (exec-mzscheme + `( (define __NO_DEBUGGING 1) + (ST) + ;(set! mrspidey:zprogress (lambda x 1)) + (test-separate-analyze (quote ,alg) (= 0 1) ,file) + (exit))) + (system (format "touch ~a" module-file)) + (exec-mzscheme + `( (define __NO_DEBUGGING 1) + (ST) + ;(set! mrspidey:zprogress (lambda x 1)) + (test-separate-analyze (quote ,alg) (= 1 1) ,file) + (exit)))) + +(define (test-separate-file file module-file) + (for-each + (lambda (t) + (unless (bad-alg-for-file? t file) + (test-separate-alg t file module-file))) + '(none nonempty-copy live live-few-e dfa-min-lub))) + +(define (test-separate-all) + '(test-separate-file + "~/Spidey/Unit/mod/test-separate.ss" + "/home/cormac/Spidey/Unit/mod/test-separate-1.ss") + (test-separate-file "analyze-scanner.ss" "zodiac/scanner-parameters.ss") + (test-separate-file "analyze-zodiac.ss" "zodiac/corelate.ss") + (test-separate-file + "~/papers/compress/bench/separate/nucleic/nucleic.ss" + "/home/cormac/papers/compress/bench/separate/nucleic/search.ss") + (test-separate-file "analyze-small.ss" "hash.ss") + (test-separate-file "analyze-no-min.ss" "hash.ss") + (test-separate-file "analyze.ss" "hash.ss")) + +;; ====================================================================== + diff --git a/collects/mrspidey/Sba/testall.ss b/collects/mrspidey/Sba/testall.ss new file mode 100644 index 0000000..2f34555 --- /dev/null +++ b/collects/mrspidey/Sba/testall.ss @@ -0,0 +1,187 @@ +; testall.ss +; Tries to test all of Teiresias's type inference algorithm +; and uses type assertions to detect when it fails + +; ---------------------------------------------------------------------- +; Constants + +(: 1 (exact num)) +(: 'a (exact sym)) +(: #\a (exact char)) +(: #t (exact true)) +(: #f (exact false)) +(: nil (exact nil)) +(: '() (exact nil)) +(: "Cormac" (exact str)) +(: '(a b c) (exact (listof sym))) +(: '(a b 1) (exact (listof (union sym num)))) +(: #(1 2 3) (exact (vec num))) +(: #(1 2 "abc") (exact (vec (union num str)))) +;;;(: #&4 (exact (box num))) + +; ---------------------------------------------------------------------- +; misc kinds of exprs + +; top-level def +(define x 'a-symbol) +(: x (exact sym)) + + +; lexical binding -various sorts +(let ([y 4][z 'a]) + (: y (exact num)) + (: z (exact sym))) +(letrec ([y 4][z 'a]) + (: y (exact num)) + (: z (exact sym))) +(let* ([y 4][z 'a]) + (: y (exact num)) + (: z (exact sym))) + +; if - one and two armed +(: (if (read) 1 'a) (exact (union num sym))) +(: (if (read) 1) (exact (union num void))) + +; set! +(let ([z 4]) + (set! z 'a) + (: z (exact (union num sym)))) + +; begin +(: (begin 'a 1) (exact num)) + +; now various lambdas and applications +((lambda (x y) (: x (exact num)) (: y (exact sym))) + 4 'a) +((lambda x (: x (exact (cons num (cons num nil))))) 1 2) +(apply (lambda (x) (: x (exact num))) (list 1)) +(apply (lambda x (: x (exact (cons num (cons num nil))))) (cons 1 (cons 2 nil))) +(: (lambda (x) x) (_ -> _)) +(: ((lambda (x) 'a) 3) (exact sym)) + +;; Multiple calls, merged returns +(let ([I (lambda (x) (: x (exact (union num sym))))]) + (: (I 3) (exact (union num sym))) + (: (I 'a) (exact (union num sym)))) + +; ---------------------------------------------------------------------- +; if-splitting + +; (if (pred arg) ...) +(let ([x (if (read) 1 'a)]) + (: x (exact (union num sym))) + (if (number? x) + (: x (exact num)) + (: x (exact sym)))) + +; assigned arg +(let ([x (if (read) 1 'a)]) + (set! x 2) + (if (number? x) + (: x (exact (union num sym))) + (: x (exact (union num sym))))) + +; (if x ...) +(let ([x (if (read) #t #f)]) + (if x + (: x (exact true)) + (: x (exact false)))) +(let ([x (if (read) 5 #f)]) + (if x + (: x (exact num)) + (: x (exact false)))) + +; (if (not x) ...) +(let ([x (if (read) #t #f)]) + (if (not x) + (: x (exact false)) + (: x (exact true)))) +(let ([x (if (read) 5 #f)]) + (if (not x) + (: x (exact false)) + (: x (exact num)))) + +; (if (not (pred arg)) ...) +(let ([x (if (read) 1 'a)]) + (if (not (number? x)) + (: x (exact sym)) + (: x (exact num)))) + +; ---------------------------------------------------------------------- +; Flow sensitive + +(let ([x (if 1 (cons 1 2) 'a)]) + (: x (exact (union (cons num num) sym))) + (car x) + (: x (exact (cons num num))) + (cdr x)) + +; not on assigned vars +(let ([x (if (read) (cons 1 2) 'a)]) + (set! x 'b) + (: x (exact (union (cons num num) sym))) + (car x) + (: x (exact (union (cons num num) sym))) + (cdr x)) + +; ---------------------------------------------------------------------- +; Boxes + +(let ([x (: (box 1) (exact (box num)))]) + (: (unbox x) (exact num))) +(let ([x (: (box 1) (exact (box (union num sym))))]) + (set-box! x 'a) + (: (unbox x) (exact (union num sym)))) +(let ([x (if (read) (box 'a) #f)]) + (if (box? x) (: x (exact (box sym))))) + +; ---------------------------------------------------------------------- +; User primitives and types + +(define-constructor Box #t) + +(define-primitive Box? (_ -> bool) (predicate Box)) +(define-primitive Box (a -> (Box a))) +(define-primitive unBox ((Box a) -> a)) +(define-primitive set-Box! ((Box (! a)) a -> void)) + +(let ([x (: (Box 1) (exact (Box num)))]) + (: (unBox x) (exact num))) +(let ([x (: (Box 1) (exact (Box (union num sym))))]) + (set-Box! x 'a) + (: (unBox x) (exact (union num sym)))) +(let ([x (if (read) (Box 'a) #f)]) + (if (Box? x) (: x (exact (Box sym))))) + +(define-type env (listof (list sym num))) +(define-primitive mk-env (-> env)) +(: (mk-env) (exact (listof (list sym num)))) + +; ---------------------------------------------------------------------- +; define-structure + +(define-structure (Triple a b c)) + +(let ([x (: (make-Triple 1 'a #\c) (exact (structure:Triple num sym char)))]) + (: (Triple-a x) (exact num)) + (: (Triple-1 x) (exact num))) +(let ([x (: (make-Triple 1 'a #\c) (exact (structure:Triple (union num sym) sym char)))]) + (set-Triple-a! x 'a) + (: (Triple-a x) (exact (union num sym)))) +(let ([x (if (read) (make-Triple 1 'a #\c) #f)]) + (if (Triple? x) (: x (exact (structure:Triple num sym char))))) + +; ---------------------------------------------------------------------- +; loops + +(define Map + (lambda (f l) + (if (null? l) + '() + (cons (f (car l)) (Map f (cdr l)))))) + +(: (Map add1 '(1 2 3)) (exact (listof num))) + +; ---------------------------------------------------------------------- +; Could test all the primitives ... + diff --git a/collects/mrspidey/Sba/text-interaction.ss b/collects/mrspidey/Sba/text-interaction.ss new file mode 100644 index 0000000..cf2cca5 --- /dev/null +++ b/collects/mrspidey/Sba/text-interaction.ss @@ -0,0 +1,60 @@ +;; text-interaction +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ---------------------------------------------------------------------- + + (define (mrspidey:error msg . obj-list) + (error 'Mrspidey msg)) + (define mrspidey:warning + (case-lambda + [(str . _) (printf "Warning: ~a~n" str)] + ;[(str loc . _) (printf "Warning: file ~s, line ~s: ~a~n" + ; (file-name-from-path (zodiac:location-file loc)) + ; (zodiac:location-line loc) + ; str)] + )) + (define mrspidey:internal-error error) + (define (mrspidey:add-summary str . _) + (printf "~a~n" str)) + (define mrspidey:progress + (let ([current ()] + [fresh-line #t]) + (letrec + ([f (match-lambda* + [((? symbol? name) (? number? fraction)) + (unless (eq? name current) + (f 'fresh-line) + (set! current name) + (mrspidey:progress-output (format "~s: " name))) + (mrspidey:progress-output ".") + (flush-output) + (set! fresh-line #f) + (when (= fraction 1) (f #\newline))] + [((? string? str)) + (f 'fresh-line) + (mrspidey:progress-output str) + (when (char=? (string-ref str (sub1 (string-length str))) + #\newline) + (set! fresh-line #t))] + [(#\newline) + (mrspidey:progress-output (format "~n")) + (set! fresh-line #t)] + [('fresh-line) + (unless fresh-line (f #\newline))])]) + f))) + (define mrspidey:progress-output + (lambda (str) (display str) (flush-output))) diff --git a/collects/mrspidey/Sba/toplevelenv.ss b/collects/mrspidey/Sba/toplevelenv.ss new file mode 100644 index 0000000..cf08f48 --- /dev/null +++ b/collects/mrspidey/Sba/toplevelenv.ss @@ -0,0 +1,212 @@ +;; toplevelenv.ss +;; Handles the default top level environment +;; +;; ====================================================================== +;; Primitive environments: symbol -> priminfo +;; First a helper fn + +(define-structure (priminfo sym type domain-filters predicate-fn)) + +;; filter-domains is a list of filters for various args, +;; if no error raised + +;; inj-predicate is a fn : list-AVS x list-AVS x AVS x bool -> AVS +;; used for (if (pred ... x ...) ...) + +(define (primitive->priminfo name type . attrs) + (let ([type (expand-type type)]) + (make-priminfo + name + type + + ;; Calculate filter-domains + (match type + [(domain '->* _) + ;; Now walk domain and args + (recur loop ([domain domain]) + (match domain + [('cons domain domain-rest) + (cons + (let ([templates (con-exp->templates domain)]) + (if templates + (make-filter #t templates) + #f)) + (loop domain-rest))] + [_ '()]))] + [_ '()]) + + ;; Calculate predicate-fn + (foldl + (lambda (attr predicate-fn) + (let* + ([mk-predicate-fn + (lambda (filter-then filter-else) + (lambda (b a AVS sign) + (let ([filter (if sign filter-then filter-else)]) + (if filter + (let ([nu-AVS (mk-AVS-tmp 'filter)]) + (new-con! AVS + (create-con-filter filter + nu-AVS)) + nu-AVS) + AVS))))] + [get-templates + (lambda (C*) (map lookup-template C*))] + [nu-fn + (match attr + [('predicate-fn exp) exp] + [('predicate . C*) + (let ([templates (get-templates C*)]) + (mk-predicate-fn (make-filter #t templates) + (make-filter #f templates)))] + [('predicate* true-info false-info) + (apply + mk-predicate-fn + (map + (match-lambda + ['_ #f] + [(bool . C*) + (let ([templates (get-templates C*)]) + (make-filter bool templates))] + [_ (error 'predicate* "Bad syntax")]) + (list true-info false-info)))] + [_ #f])]) + (if nu-fn + ;; compose + (lambda (b a AVS sign) + (nu-fn b a + (predicate-fn b a AVS sign) + sign)) + predicate-fn))) + (lambda (b a AVS bool) AVS) + attrs)))) + +;; ---------------------------------------------------------------------- +;; Now the default environment + +(define default-primitive-env (void)) +;; type: symbol -> priminfo + +;; ====================================================================== + +(define output-type-expander (void)) +(define (init-output-type-expander!) + (set! output-type-expander (lambda (x) x))) + +(define (install-output-type-expander! expander) + (let ([old-expander output-type-expander]) + (set! output-type-expander + (lambda (type) + (old-expander (recur loop ([type type]) + (let ([t (expander type)]) + (if (eq? t type) type (loop t))))))))) + +;; ====================================================================== +;; For input-type-expander, recursion is done in expand-type + +(define default-input-type-expander (void)) +(define input-type-expander (void)) + +(define (init-input-type-expander!) + (set! input-type-expander default-input-type-expander)) + +(define (init-empty-input-type-expander!) + (set! input-type-expander (lambda (x) x))) + +(define (capture-input-type-expander!) + (set! default-input-type-expander input-type-expander)) + +(define (install-input-type-expander! expander) + (let ([old-expander input-type-expander]) + (set! input-type-expander + (lambda (type) + ;;(pretty-print `(input-type-expander ,type)) + (old-expander (expander type)))))) + +;; ====================================================================== + +(define (extend-env-w/-define-structure env tag . args) + ;; env: sym -> priminfo + (let ([add! + (lambda (name type . attrs) + (set! env + (extend-env env name + (apply primitive->priminfo name type attrs))))] + [type (symbol-append 'structure: tag)] + [gen-args (map (lambda (_) (gensym)) args)] + [gen-arg (gensym)]) + (apply add-constructor! type (map (lambda (a) #t) args)) + (add! (symbol-append 'make- tag) `(,@gen-args -> (,type ,@gen-args))) + (add! (symbol-append tag '?) `(_ -> bool) `(predicate ,type)) + (for-each-with-n + (lambda (arg n) + (let ([type-ref + `((,type ,@(map (lambda (a) + (if (eq? a arg) gen-arg '_)) + args)) + -> ,gen-arg)] + [type-bang + `((,type ,@(map (lambda (a) + (if (eq? a arg) `(! ,gen-arg) '_)) + args)) + ,gen-arg + -> void)]) + (add! (symbol-append tag '- arg) type-ref) + (add! (symbol-append tag '- (add1 n)) type-ref) + (add! (symbol-append 'set- tag '- arg '!) type-bang) + (add! (symbol-append 'set- tag '- (add1 n) '!) type-bang))) + args) + env)) + +;; ====================================================================== + +(define (add-default-primitive! name type . attrs) + ;; working w/ default primitive env => use default constructor env + (init-current-constructor-env!) + (set! default-primitive-env + (extend-env default-primitive-env + name + (apply primitive->priminfo name type attrs)))) + +(define (add-default-primitives! l) + (for-each + (lambda (args) (apply add-default-primitive! args)) + l)) + +(define + select-language + (make-parameter-list + 'none + '((DrScheme "DrScheme") + (MzScheme "MzScheme") + (R4RS "R4RS") + (Chez "Chez Scheme") + (Rice "Rice Scheme") + (none "None")) + (lambda (scheme) + (unless (eq? scheme 'none) + (init-default-constructor-env!) + (init-empty-input-type-expander!) + (init-output-type-expander!) + (set! default-primitive-env empty-env) + (init-R4RS!) + (case scheme + [MzScheme (init-MzScheme-on-R4RS!)] + [DrScheme (init-MzScheme-on-R4RS!) + (init-DrScheme-on-MzScheme!)] + [R4RS (void)] + [Chez (init-Chez-on-R4RS!)] + [Rice (init-Chez-on-R4RS!) + (init-Rice-on-Chez!)] + [none (void)]) + (when (st:numops) (init-smart-numops!)) + ;; Load .spideyrc file and .spidey-system-rc files + (when (file-exists? "~/.spideyrc") (load "~/.spideyrc")) + (let ([systemrc (string-append "~/.spidey-" + (symbol->string scheme) + "-rc")]) + (when (file-exists? systemrc) (load systemrc))) + (capture-input-type-expander!))))) + +;; ====================================================================== + diff --git a/collects/mrspidey/Sba/traverse.ss b/collects/mrspidey/Sba/traverse.ss new file mode 100644 index 0000000..3e54a76 --- /dev/null +++ b/collects/mrspidey/Sba/traverse.ss @@ -0,0 +1,1469 @@ +; ASSUME DEFINED VARIABLES NEVER ASSIGNED + +; traverse.ss +; Traverses source program and produces constraints. +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ------------------------------------------------------------ + +;; Environments are: +;; (Name -> (or FlowType mutable-binding)) + +;; ---------------------------------------------------------------------- + +(define (top-level-traverse-defs defs env) + ;;(assert (atenv:ok? env) 'top-level-traverse-defs) + (begin0 + (traverse-defs defs env) + (unless (null? defs) + (mrspidey:zprogress "Analyzing" (zodiac:zodiac-finish (rac defs)))) + )) + +(define traverse:bad-expr (void)) + +(define (traverse-defs defs env) + ;;(assert (atenv:ok? env) 'traverse-defs) + ;; returns (values env refs result) + (pretty-debug-traverse `(->traverse-defs)) + ;; First alloc void for all defines + (let* ( [lvrs (apply append + (map (match-lambda + [($ zodiac:define-values-form _ _ _ _ vars) vars] + [_ '()]) + defs))] + [names (map zodiac:varref-binding lvrs)] + [nuenv (atenv:extend-undefineds env names)] + ;; bubble define-struct stuff to top + [defs + (append + (filter + (match-lambda + [($ zodiac:define-values-form _ _ _ _ _ + ($ zodiac:struct-form)) + #t] + [_ #f]) + defs) + (filter + (match-lambda + [($ zodiac:define-values-form _ _ _ _ _ + ($ zodiac:struct-form)) + #f] + [_ #t]) + defs))]) + (recur loop ([defs defs] + [env nuenv] + [refs '()] + [result (wrap-value (mk-tvar-void))]) + (match defs + [() (atenv:flush! env) + (values env refs result)] + [(first . rest) + (let-values + ([(env nu-refs result) (traverse-def first env)]) + (loop rest env (append nu-refs refs) result))])))) + +;; ---------------------------------------------------------------------- + +(define (traverse-def def env) + ;; returns (values env refs result) + ;; (: env (listof (cons Name FlowType))) + ;; (: refs (listof (cons Name Tvar))) + ;; (: result FlowType) -- multiple value list + + (pretty-debug-traverse-small + `(->traverse-def + ,(zodiac:location-offset (zodiac:zodiac-start def)) + ,(zodiac:stripper def))) + + (mrspidey:zprogress "Analyzing" (zodiac:zodiac-start def)) + + (let* ([tvar-E (mk-Tvar 'def)]) + (link-parsed-ftype! def tvar-E) + (new-AV! tvar-E AV-void) + (match def + ;; --- define + [($ zodiac:define-values-form _ _ _ _ lvrs exp) + (let*-vals ([(ftype env refs) (traverse-exp exp env)] + [ftypes (multiple-value-components ftype (length lvrs))] + [ftypes (map link-parsed-ftype! lvrs ftypes)] + [names (map zodiac:varref-binding lvrs)] + [env (atenv:change-bindings env names ftypes)]) + (values env refs (wrap-value (mk-tvar-void))))] + ;; --- define-type + [($ zodiac:define-type-form _ s _ _ sym type) + (let ([tvar (mk-Tvar 'define-type)]) + (schema->con + (expand-input-type-err type def) + tvar 'define-type '()) + (add-global-tdef! sym tvar) + (values env '() (wrap-value (mk-tvar-void))))] + ;; --- define-constructor + [($ zodiac:define-constructor-form _ _ _ _ name modes) + (apply add-constructor! name modes) + (values env '() (wrap-value (mk-tvar-void)))] + ;; --- Exp + [exp + (let-values ([(result env refs) (traverse-exp exp env)]) + (values env refs result))]))) + +;; ---------------------------------------------------------------------- + +(define values-trap-pt (void)) + +(define (traverse-exp E env) + (: env (listof (cons Name (or mutable-binding FlowType)))) + + ;; returns (values FlowType env refs) + ;; (: refs (listof (cons Name Tvar))) + ;; FlowType is annotated type for list of results + + (letrec* + ([refs '()] + [extend-ref! + (lambda (name tvar) (set! refs (cons (cons name tvar) refs)))] + [extend-refs! + (lambda (refs) + (for-each + (match-lambda + [(name . tvar) (extend-ref! name tvar)]) + refs))] + ;; --- + [pattern-match (lambda (tvar-formal tvars-actuals) + (match tvars-actuals + [(? Tvar?) (new-edge! tvar-formal tvars-actuals)] + [(tvar1 . rest) + (let ([tvar-cdr (mk-Tvar 'arg-cdr)]) + (new-con! tvar-formal (make-con-car tvar1)) + (new-con! tvar-formal (make-con-cdr tvar-cdr)) + (pattern-match tvar-cdr rest))] + [() (void)]))] + [handle-lambda-form + (lambda (args body env1) + (: args zodiac:arglist) + + (let*-vals + ( [env2 (atenv:unflush env1)] + [tvar-arg (mk-Tvar 'args)] + [improper? + (or (zodiac:sym-arglist? args) (zodiac:ilist-arglist? args))] + ;;[_ (pretty-print `(improper ,improper? ,args))] + [args (zodiac:arglist-vars args)] + [env3 + (recur loop ([env env2][args args][tvar tvar-arg]) + (cond + [(null? args) env] + [(and improper? (null? (cdr args))) + (atenv:extend env (car args) tvar)] + [else + (let ( [tvar-car (mk-Tvar 'arg-car)] + [tvar-cdr (mk-Tvar 'arg-cdr)]) + (new-con! tvar (make-con-car tvar-car)) + (new-con! tvar (make-con-cdr tvar-cdr)) + (loop (atenv:extend env (car args) tvar-car) + (cdr args) + tvar-cdr))]))] + [(ftype-rv env4) (traverse body env3)] + [AV (make-AV-lam tvar-arg (FlowType->Tvar ftype-rv) + (if improper? (sub1 (length args)) (length args)) + improper?)] + [tvar-E (mk-Tvar 'lam)]) + (atenv:flush! env4) + (new-AV! tvar-E AV) + tvar-E))] + + [handle-application + (lambda (E env flush?) + (match E + [($ zodiac:app _ _ _ _ fn args) + (set! values-trap-pt "|") + (let*-vals + ( [(ftype-fn env1 pi) + ;; Traverse fn specially if fo prim ref + ;; don't instantiate yet, wait till have # args + (match fn + [($ zodiac:varref) + (=> fail) + (if (st:special-fo-prims) + (match (atenv:lookup env (zodiac:varref-binding fn)) + [#f + (set! values-trap-pt "A") + (fail)] + [ftype + (set! values-trap-pt "B") + (match (FlowType->Atype ftype) + [(and pi ($ atprim sym tschema)) + (set! values-trap-pt "C") + (zodiac:set-parsed-atprim! fn pi) + (let ([tvar-fn (mk-Tvar sym)]) + (tschema->con-for-nargs tschema + tvar-fn sym '() (length args)) + (link-parsed-ftype! fn (wrap-value tvar-fn)) + (set! values-trap-pt "D") + (values tvar-fn env pi))] + [_ + (set! values-trap-pt "E") + (fail)])]) + (begin (set! values-trap-pt "F") (fail)))] + [_ + (set! values-trap-pt "G") + (let-values ([(ftype env) (traverse1 fn env)]) + (set! values-trap-pt "H") + (values ftype env #f))])] + [_ (set! values-trap-pt "K")] + [(ftype-arg* env2) (traverse* args env1)] + [ftype-arg* (map extract-1st-value ftype-arg*)] + [env3 (if (and flush? (not pi)) + (atenv:unflush (atenv:flush! env2)) + env2)] + + [tvar-fn (FlowType->Tvar ftype-fn)] + [tvar-arg* (map FlowType->Tvar ftype-arg*)] + [tvar-arg + (foldr + (lambda (tvar-arg tvar-rest-args) + (let* ([tvar (mk-Tvar 'arg)]) + (new-AV! tvar + (make-AV-cons tvar-arg tvar-rest-args)) + tvar)) + (mk-tvar-nil) + tvar-arg*)] + [tvar-E (mk-Tvar 'expr)]) + ;;(link-parsed-ftype! fn (wrap-value tvar-fn)) + (pretty-debug-traverse + `(tvar-fn ,(Tvar-name tvar-fn) + tvar-arg ,(Tvar-name tvar-arg))) + (zodiac:set-app-tvar-args! E tvar-arg) + (new-con! tvar-fn (make-con-dom tvar-arg)) + (new-con! tvar-fn (make-con-rng tvar-E)) + (values tvar-E + (if (and (st:flow-sensitive) pi) + (flow-sensitive-env pi args env3) + env3)))]))] + + ;; --- + [traverse* + (lambda (E* env) + ;; Returns (values (listof FlowType) env) + (pretty-debug-traverse `(->traverse* ,(length E*))) + (match + (foldl + (match-lambda* + [(E (ftype* . env)) + (let-values ([(ftype nuenv) (traverse E env)]) + (cons (cons ftype ftype*) nuenv))]) + (cons '() env) + E*) + [(ftype* . env) + (pretty-debug-traverse + `(<-traverse* ,(map FlowType->pretty (reverse ftype*)))) + (values (reverse ftype*) env)]))] + ;; --- + [made-unit (lambda (atype) + (cond + [(not (st:fo-units)) (Atype->Tvar atype)] + [(not (st:lazy-fo-units)) (atlunit->atunit atype)] + [else atype]))] + [traverse1 (lambda (E env) + (let*-vals ([(ftype env) (traverse E env)] + [ftype (extract-1st-value ftype)]) + (values ftype env)))] + [traverse + (lambda (E env) + ;;(assert (atenv:ok? env) 'traverse) + + (pretty-debug-traverse-small + `(->traverse + ,(zodiac:location-offset (zodiac:zodiac-start E)) + ,(zodiac:stripper E) + ,(atenv->pretty env))) + (let*-vals + ([trav (lambda (E) (traverse E env))] + [(result env-result) + (match E + ;; (: result (union Tvar fo-FlowType fo-Atype)) + + [($ zodiac:varref) + (let ([name (zodiac:varref-binding E)]) + (match (atenv:lookup env name) + [#f (let ([tvar (mk-Tvar 'import-var)]) + (extend-ref! name tvar) + (values (wrap-value tvar) env))] + [ftype + ;; Instantiate schemas and atprims here + (let* ( [atype (FlowType->Atype ftype)] + [ftype + (if (or (atprim? atype) (schema? atype)) + (FlowType->Tvar ftype) + ftype)]) + (when (atprim? atype) + (zodiac:set-parsed-atprim! E atype)) + (values (wrap-value ftype) env))]))] + + [($ zodiac:quote-form _ _ _ _ + (or ($ zodiac:boolean _ _ _ c) + ($ zodiac:number _ _ _ c))) + (values (wrap-value (make-atconst c)) env)] + + [($ zodiac:quote-form _ _ _ _ c) + (values (wrap-value (traverse-const c)) env)] + + ;; --- local set! + [($ zodiac:set!-form _ _ _ _ lvr exp) + (let*-vals ([(ftype env1) (trav exp)] + [ftype (extract-1st-value ftype)] + [ftype (link-parsed-ftype! lvr ftype)] + [name (zodiac:varref-binding lvr)] + [env2 (atenv:change-binding env1 name ftype)]) + (values (wrap-value (mk-tvar-void)) env2))] + + [($ zodiac:if-form _ _ _ _ test then else) + ;; old version + '(let*-vals + ([(ftype env1) (trav test)] + [env2 (atenv:capture-locs env1 + (zodiac:free-vars E (atenv:domain env1)))] + [(env-then env-else) + (if (st:if-split) + (if-splitting-env test env2) + (values env2 env2))] + [tvar-E (mk-Tvar 'expr)] + [do-branch + (lambda (exp env) + (let-values ([(ftype env2) (traverse exp env)]) + (atenv:flush! env2) + (new-edge! (FlowType->Tvar ftype) tvar-E)))]) + (when (or (not (st:if-split)) + (match (FlowType->Atype ftype) + [($ atconst #f) #f] + [_ #t])) + (do-branch then env-then)) + (when (or (not (st:if-split)) + (match (FlowType->Atype ftype) + [($ atconst #f) #t] + [($ atconst _) #f] + [_ #t])) + (do-branch else env-else)) + + (values tvar-E (atenv:unflush env2))) + + ;; new version + (let*-vals + ( [(ftype env1) (trav test)] + [env-dom (atenv:domain env1)] + [env1 (atenv:capture-locs env1 + (zodiac:free-vars then env-dom))] + [env1 (atenv:capture-locs env1 + (zodiac:free-vars else env-dom))] + [(env-then env-else) + (if (st:if-split) + (if-splitting-env test env1) + (values env1 env1))] + [tvar-E (mk-Tvar 'expr)] + [do-branch + (lambda (exp env) + (let-values ([(ftype env2) (traverse exp env)]) + (new-edge! (FlowType->Tvar ftype) tvar-E) + env2))] + [env-then-done + (and (or (not (st:if-split)) + (match (FlowType->Atype ftype) + [($ atconst #f) #f] + [_ #t])) + (do-branch then env-then))] + [env-else-done + (and (or (not (st:if-split)) + (match (FlowType->Atype ftype) + [($ atconst #f) #t] + [($ atconst _) #f] + [_ #t])) + (do-branch else env-else))]) + + (values tvar-E + (cond + [(and + (eq? env-then env-then-done) + (eq? env-else env-else-done)) + env1] + [(not env-else-done) env-then-done] + [(not env-then-done) env-else-done] + [else + (atenv:flush! env-then-done) + (atenv:flush! env-else-done) + (atenv:unflush env1)])))] + + ;; ### SPECIAL CODE FOR STRUCT-REF + [($ zodiac:app _ _ _ _ + ($ zodiac:varref _ _ _ _ '#%struct-ref) + ( struct-exp + ($ zodiac:quote-form _ _ _ _ ($ zodiac:number _ _ _ n)))) + (assert (and (integer? n) (>= n 0))) + ;;(printf "Special struct-ref~n") + (let*-vals + ( [(ftype-struct env1) (traverse1 struct-exp env)] + [tvar-struct (FlowType->Tvar ftype-struct)] + [tvar-elem (mk-Tvar 'struct-ref)]) + (new-con! tvar-struct + (create-con template-structure n tvar-elem #t)) + (values (wrap-value tvar-elem) env1))] + + ;; ### SPECIAL CODE FOR ivar + [($ zodiac:app _ _ _ _ + (and ref ($ zodiac:varref _ _ _ _ (or '#%uq-ivar 'uq-ivar))) + ( obj-exp + (and sym-exp + ($ zodiac:quote-form _ _ _ _ ($ zodiac:symbol _ _ _ sym))))) + ;;(printf "Special uq-ivar~n") + (let*-vals + ( [(ftype-obj env1) (traverse1 obj-exp env)] + [tvar-obj (FlowType->Tvar ftype-obj)] + [tvar-ivar (mk-Tvar 'ivar-ref)]) + (new-con! tvar-obj + (create-con (get-ivar-template sym) 0 tvar-ivar #t)) + ;(trav ref) + ;(trav sym-exp) + (values (wrap-value tvar-ivar) env1))] + + ;; ### SPECIAL CODE FOR UNIT/SIG + [($ zodiac:app _ _ _ _ + (and ref ($ zodiac:varref _ _ _ _ '#%make-unit-with-signature)) + (unit-exp _ _)) + (traverse unit-exp env)] + [($ zodiac:app _ _ _ _ + (and ref + ($ zodiac:varref _ _ _ _ '#%verify-linkage-signature-match)) + args) + (values (wrap-value (mk-tvar-void)) env)] + [($ zodiac:app _ _ _ _ + (and ref + ($ zodiac:varref _ _ _ _ '#%unit-with-signature-unit)) + (unit-exp)) + (traverse unit-exp env)] + + + + [($ zodiac:app _ _ _ _ fn args) + (handle-application E env #t)] + + [($ zodiac:letrec*-values-form _ _ _ _ varss exps body) + ;; First init each new var + (recur loop + ([env (atenv:extend-undefineds env (apply append varss))] + [varss varss] + [exps exps]) + (if (null? exps) + (traverse body env) + (let*-vals + ([(ftype nuenv) (traverse (car exps) env)] + [vars (car varss)] + [ftypes (multiple-value-components ftype (length vars))] + ;; overwrite void binding + [ftypes (map link-parsed-ftype! vars ftypes)] + [nuenv2 (atenv:change-bindings nuenv vars ftypes)]) + (loop nuenv2 (cdr varss) (cdr exps)))))] + + [($ zodiac:let-values-form _ _ _ _ varss exps body) + (let*-vals + ([(ftype* nuenv) (traverse* exps env)] + [nuenv2 + (foldr2 + (lambda (vars ftype env) + (assert (list? vars) 'let-valeus-form) + (atenv:extend* + env vars + (multiple-value-components ftype (length vars)))) + nuenv varss ftype*)]) + (traverse body nuenv2))] + + [($ zodiac:case-lambda-form _ _ _ _ args bodies) + (let ( [tvar-E (mk-Tvar 'expr)] + [env1 (atenv:capture-locs env + (zodiac:free-vars E (atenv:domain env)))]) + (for-each + (lambda (args body) + (new-edge! + (FlowType->Tvar (handle-lambda-form args body env1)) + tvar-E)) + args bodies) + (values (wrap-value tvar-E) env1))] + + ;;[($ zodiac:delay-form _ _ _ _ expr) + ;; (let*-vals + ;; ([env1 (atenv:capture-locs env (zodiac:free-vars E))] + ;; [env2 (atenv:unflush env1)] + ;; [(ftype-expr env3) (traverse1 expr env2)] + ;; [AV (make-constructed-AV-template + ;; template-promise (FlowType->Tvar ftype-expr))] + ;; [tvar-E (mk-Tvar 'expr)]) + ;; (atenv:flush! env3) + ;; (new-AV! tvar-E AV) + ;; (values (wrap-value tvar-E) env1))] + + [($ zodiac:begin-form _ _ _ _ bodies) + (recur loop ([env env][bodies bodies]) + (match bodies + ;;[() (values (wrap-value (mk-tvar-void)) env)] + [(a . d) + (let*-vals ([(ftype nuenv) (traverse a env)]) + (if (null? d) + (values ftype nuenv) + (loop nuenv d)))]))] + [($ zodiac:begin0-form _ _ _ _ (start . rest)) + (let*-vals ([(ftype nuenv) (traverse start env)]) + (recur loop ([env nuenv][rest rest]) + (match rest + [() (values ftype env)] + [(a . d) + (let*-vals ([(ftype nuenv) (traverse a env)]) + (loop nuenv d))])))] + + ;; -------------------------------------------------------- + ;; MzScheme special forms + + [($ zodiac:unit-form) + (let* ([env1 (atenv:unflush env)]) + ;; Assume no refs inside unit to imports of enclosing unit + (values (wrap-value (made-unit (create-atlunit-unit env1 E))) + env))] + + [($ zodiac:compound-unit-form _ s _ _ imports links exports) + (let*-vals + ([time-E (zodiac-time E)] + [exprs (map cadr links)] + [(ftype* env) (traverse* exprs env)] + [time* (map (lambda (e) (max time-E (zodiac-time* e))) + exprs)] + ;; Assume E is closed + [ftype* (mapLR extract-1st-value ftype*)]) + (values + (wrap-value (made-unit (create-atlunit-cmpd E time* ftype*))) + env))] + + ;; ### Doesn't deal in first-order fashion + [($ zodiac:invoke-unit-form _ _ _ _ exp vars) + (let*-vals ( [(ftype env1) (traverse1 exp env)] + ;;[tvar (FlowType->Tvar ftype)] + [(ftype* env2) (traverse* vars env1)] + [ftypes.times + (map (lambda (f) (cons f (current-seconds))) + ftype*)] + [env1 (atenv:flush! env1)] + [env2 (atenv:unflush env1)] + [atype-U (apply-unit ftype ftypes.times)] + [tvar-E + (match atype-U + [($ atunit _ _ result) result] + [(? Tvar? tvar-u) + (let ([tvar (mk-Tvar 'invoke-unit-result)]) + (new-con! tvar-u + (create-con template-unit 0 tvar #t)) + tvar)])]) + (values tvar-E env2))] + + ;; -------------------------------------------------------- + ;; MzScheme special forms + + [($ zodiac:class*/names-form) + (handle-class*/names-form E env + traverse traverse* handle-application)] + + ;; -------------------- + + [($ zodiac:poly-form _ _ _ _ exp) + (unless (zodiac:parsed-value? exp) + (mrspidey:error "poly annotation on non-value" exp)) + (let*-vals + ( [name-for-edge + (match-lambda + [(f . t) (cons (Tvar-name f) (Tvar-name t))])] + [analyze + (lambda () + (let*-vals + ( [l1 list-ftype] + [base-num num-ftype] + ;; Capture edges from external mono AVSs + [edges '()] + [orig-new-edge! (new-edge-para)] + [capture-edge! + (lambda (from to) + (unless (eq? from to) + (if (< (FlowType-num from) base-num) + ;; Edge from outside constraint set + (set! edges (cons (cons from to) edges)) + (orig-new-edge! from to))))] + [(env refs tvar) + (dynamic-let + ([new-edge-para capture-edge!]) + (let*-vals + ( [(ftype env refs) (traverse-exp exp env)] + [ftype1 (extract-1st-value ftype)] + [tvar (FlowType->Tvar ftype1)]) + (values env refs tvar)))] + [l2 list-ftype]) + + (pretty-debug + `(Poly-def-result + ,(FlowType-name tvar) + num-AVS + ,(- (FlowType-num (car l2)) + (FlowType-num (car l1))) + ,(FlowType-name (car l2)) + ,(FlowType-name (car l1)) + external-edges + ,(map name-for-edge edges))) + (values env refs tvar l1 l2 edges)))] + [handle-edges! (lambda (edges) + (for-each + (match-lambda + [(from . to) (new-edge! from to)]) + edges))] + [(def env) + (case (st:polymorphism) + [(reanalyze) + (mrspidey:error "Reanalyze does not work - env problem") + (make-atthunk + (lambda () + (let*-vals + ([(env refs tvar l1 l2 edges) (analyze)]) + (for-each + (match-lambda + [(binding . _) + (mrspidey:warning "Reference to ~s inside poly form with (st:polymorphism 'reanalyze)" exp 3)]) + refs) + (handle-edges! edges) + tvar)))] + [(copy-con) + (let*-vals ([(env refs tvar l1 l2 edges) (analyze)]) + (extend-refs! refs) + (values + (make-schema tvar + (filter Tvar? (get-prefix l2 l1)) + edges) + env))] + [(compress) + (let*-vals + ( [(env refs tvar l1 l2 edges) (analyze)] + [_ (extend-refs! refs)] + ;; Tracked all incoming edges in edges + ;; These correspond to upper bindings + [U-tvar* (list tvar)] + [L-tvar* (map cdr edges)] + [old-num-ftype num-ftype] + [old-num-AV num-AV] + [old-num-edge num-edge] + [old-num-con num-con] + [(rep-tvar tvar->nu) + (minimize-constraints-&-compare + (st:constraint-simplification-poly) + L-tvar* U-tvar* + l2 l1)] + ;; Update edges to point to the compressed set + [nu-edges + (filter-map + (match-lambda + [(and edge (from . to)) + (let ([nu-to (tvar->nu to)]) + (if nu-to + (cons from (tvar->nu to)) + (begin + '(pretty-debug-traverse + `(dropping ,(name-for-edge edge))) + #f)))]) + edges)]) + + (when (> (- num-ftype old-num-ftype) 250) + (printf "Poly def AVS ~s AV ~s edge ~s con ~s~n" + (- num-ftype old-num-ftype) + (- num-AV old-num-AV) + (- num-edge old-num-edge) + (- num-con old-num-con))) + + (values + (make-schema (tvar->nu tvar) rep-tvar nu-edges) + env))] + [(none) + (let*-vals ([(env refs tvar l1 l2 edges) (analyze)]) + (extend-refs! refs) + (handle-edges! edges) + (values tvar env))])]) + (values (wrap-value def) env))] + + [($ zodiac:struct-form _ s _ _ + ($ zodiac:symbol _ _ _ tag) + parent + (($ zodiac:symbol _ _ _ fields) ...)) + (let*-vals + ([(parent-ftype env1) + (match parent + [#f (values + (create-fo-FlowType + (make-atstruct 'tag '(structure:) + '() '() '() '())) + env)] + [exp (traverse1 parent env)])]) + (match (FlowType->Atype parent-ftype) + [(and atstruct ($ atstruct)) + (values (handle-struct-form tag #f atstruct fields) + env)] + [_ + (pretty-debug-traverse `(FlowType->pretty parent-ftype)) + (mrspidey:warning + (format + "Expression does not analyze to a first-order struct") + (zodiac:zodiac-start parent) + 0) + (values (mk-Tvar 'empty) env)]))] + + ;; -------------------------------------------------------- + ;; MrSpidey special forms + + [($ zodiac::-form _ _ _ _ exp type) + (let*-vals + ([(ftype nuenv) (traverse1 exp env)]) + (pretty-debug `(:: ,ftype ,nuenv)) + (match exp + [($ zodiac:varref _ _ _ _ sym) + (let ([name (zodiac:varref-binding exp)]) + (if (and (st:flow-sensitive) (Tvar? ftype)) + (let* ( [type type] + [type (match type + [('exact type) type] + [type type])] + [etype (expand-input-type type)] + [templates (type->templates etype)] + [sym (zodiac:binding-var name)]) + (if templates + (let* ( [filter (create-filter #t templates)] + [nutvar (mk-Tvar sym)]) + (new-con! ftype (create-con-filter filter nutvar)) + (values (wrap-value nutvar) + (atenv:change-binding nuenv name nutvar))) + (values (wrap-value ftype) nuenv))) + (values (wrap-value ftype) nuenv)))] + [_ (values (wrap-value ftype) nuenv)]))] + + [($ zodiac:st:control-form _ _ _ _ para val) + (mrspidey:control-fn para val) + (values (wrap-value (mk-tvar-void)) env)] + + [($ zodiac:type:-form _ s _ _ type attrs) + (let ([type (expand-input-type-err type E)]) + (values + (wrap-value (apply primitive->atprim 'user type attrs)) + env))] + + [($ zodiac:reference-unit-form) + (values + (wrap-value (made-unit (create-atlunit-reference E))) + env)] + + [($ zodiac:invoke-open-unit-form) + (mrspidey:error + "MrSpidey does not support invoke-open-unit" E)] + + [($ zodiac:define-values-form) + (mrspidey:error + "MrSpidey does not support internal defines" E)] + + [E + (set! traverse:bad-expr E) + (mrspidey:error "Bad expr in traverse" E)])] + + ;; -------------------- + + ;; env-result may contain extra bindings, + ;; but they have no effect + + [_ (: result (union Tvar fo-FlowType fo-Atype))] + [_ (pretty-debug-traverse + `(traverse result ,(FlowType->pretty result)))] + [ftype (link-parsed-ftype! E result)]) + + (pretty-debug-traverse-small + `(<-traverse + ,(zodiac:location-offset (zodiac:zodiac-start E)) + ,(zodiac:stripper E) + ,(atenv->pretty env-result) + ,(FlowType->pretty ftype))) + + (assert (FlowType? ftype) 'end-traverse ftype) + (values ftype env-result)))]) + + (let-values ([(ftype env) (traverse E env)]) + (values ftype env refs)))) + +;; ---------------------------------------------------------------------- + +(define (handle-class*/names-form E start-env + traverse traverse* handle-application) + (let ([handle-paroptarglist + (lambda (env init-arglist tvar-arg) + (pretty-debug-object + `(handle-paroptarglist ,(atenv->pretty env) + ,init-arglist + ,(Tvar-name tvar-arg))) + ;; Bindings are already in atlist + (let* + ( [improper? + (or (zodiac:sym-paroptarglist? init-arglist) + (zodiac:ilist-paroptarglist? init-arglist))] + [args (zodiac:paroptarglist-vars init-arglist)] + [initialize-arg + (lambda (env arg tvar) + (match arg + [(and bind ($ zodiac:binding)) + (atenv:change-binding env bind tvar)] + [((and bind ($ zodiac:binding)) . exp) + (let*-vals + ( [(ftype env) (traverse exp env)] + [ftype (extract-1st-value ftype)]) + (new-edge! (FlowType->Tvar ftype) tvar) + (atenv:change-binding env bind tvar))]))]) + (recur loop ([env env][args args][tvar tvar-arg]) + (cond + [(null? args) env] + [(and improper? (null? (cdr args))) + (initialize-arg env (car args) tvar)] + [else + (let ( [tvar-car (mk-Tvar 'arg-car)] + [tvar-cdr (mk-Tvar 'arg-cdr)]) + (new-con! tvar (make-con-car tvar-car)) + (new-con! tvar (make-con-cdr tvar-cdr)) + (loop + (initialize-arg env (car args) tvar-car) + (cdr args) + tvar-cdr))]))))]) + + (match E + [($ zodiac:class*/names-form _ _ _ _ + this-name + super-init-name + super-expr + _ + (and init-arglist ($ zodiac:paroptarglist init-vars)) + clauses) + + (pretty-debug-object `(init-arglist ,init-arglist)) + + (let*-vals + ( ;; --- Work from top down according to class.dvi + ;; --- Traverse super-exprs + [(super-ftype env-after-super) (traverse super-expr start-env)] + [tvar-super (FlowType->Tvar (extract-1st-value super-ftype))] + + ;; extract portions of tvar-super + [f (lambda (sign) + (lambda (ndx) + (let ([tvar (mk-Tvar 'class-field)]) + (new-con! tvar-super + (create-con template-internal-class + ndx tvar sign)) + tvar)))] + [super-u ((f #t) 0)] + [super-o ((f #t) 1)] + [super-i ((f #t) 2)] + [super-f ((f #t) 3)] + [super-b ((f #f) 0)] + [super-a ((f #f) 1)] + [super-g ((f #f) 2)] + [super-t ((f #f) 3)] + [super-v ((f #t) 4)] + + ;; Transfers control just like lambdas, capture it here + [captured-env + (atenv:capture-locs env-after-super + (zodiac:free-vars E (atenv:domain env-after-super)))] + [env (atenv:extend captured-env super-init-name super-i)] + [env (atenv:unflush env)] + + [super-init-name? + (lambda (var) + (and (zodiac:varref? var) + (eq? (zodiac:varref-binding var) + super-init-name)))] + + ;; Fields for class + + [this-u (mk-Tvar 'this-u)] + [this-o (mk-Tvar 'this-o)] + [tvar-args (mk-Tvar 'this-tvar-args)] + [this-i (mk-Tvar-init-AV 'this-i + (make-AV-lam tvar-args (mk-tvar-void) 0 #t))] + [this-b (mk-Tvar 'this-b)] + [this-a (mk-Tvar 'this-a)] + [this-f (mk-Tvar 'this-f)] + [this-g (mk-Tvar 'this-g)] + [this-t (mk-Tvar 'this-t)] + [this-v (mk-Tvar 'this-v)] + [tvar-class + (mk-Tvar-init-AV 'class + (create-AV template-internal-class '() + (vector this-u this-o this-i this-f this-v) + (vector this-b this-a this-g this-t)))] + + ;; Anything not clause dependant + + [_ (new-edge! super-u this-u)] + [_ (new-edge! this-t super-t)] + + ;; Now to do the init args and clauses + + ;; --- Build up environment + [env (atenv:extend env this-name this-t)] + ;; args + [env (foldr + (lambda (var env) + (atenv:extend env + (if (zodiac:binding? var) + var + (car var)) + (mk-Tvar 'init-var))) + env + init-vars)] + + ;; --- helper stuff + [tvar-undef (mk-Tvar-init-AV 'delta AV-undefined)] + [ivar-put + (lambda (to sym tvar) + (new-AV! to + (create-AV + (get-ivar-template sym) + '() (vector tvar) (vector))))] + [ivar-get + (lambda (from sym tvar) + (new-con! from + (create-con + (get-ivar-template sym) + 0 tvar #t)))] + + ;; Traverse clauses, alloc a-j etc, extend env + ;; and find super-init call + + [super-init-expr #f] + [_ (pretty-debug-object `(calc clause-info))] + [clause-info + (map-clause + (lambda (public? define? override? + export internal expr import) + (let* ( [a-j (mk-Tvar 'a-j)] + [b-j (mk-Tvar 'b-j)] + [r-j (mk-Tvar 'r-j)] + [g-j (mk-Tvar 'g-j)]) + (match expr + ;; straight application + [($ zodiac:app _ _ _ _ (? super-init-name?) _) + (set! super-init-expr expr)] + ;; apply + [($ zodiac:app _ _ _ _ + (and fn ($ zodiac:varref _ _ _ _ 'apply)) + ((? super-init-name?) . _)) + (match (FlowType->Atype + (atenv:lookup env (zodiac:varref-binding fn))) + [($ atprim 'apply) + (set! super-init-expr expr)] + [_ (void)])] + [_ (void)]) + (when internal + (zodiac:set-binding-mutated! internal #t) + (set! env (atenv:extend-mutated env internal b-j g-j)) + (link-parsed-ftype! internal r-j)) + (list + public? define? override? + export internal expr import + a-j b-j r-j g-j))) + clauses)] + [_ (pretty-debug-object `(got clause-info))] + + + ;; Ok, we have the full environment + ;; Handle the argument list + + [env (handle-paroptarglist env init-arglist tvar-args)] + + ;; --- create constraints for each clause + [super-init-called #f] + [public-templates '()] + [keyw-local-templates '()] + [before-not-flow-templates '()] + [after-not-flow-templates '()] + + [extend-before-not-flow-templates! + (lambda (sym) + (set! before-not-flow-templates + (cons (get-ivar-template sym) + before-not-flow-templates)))] + [extend-after-not-flow-templates! + (lambda (sym) + (set! after-not-flow-templates + (cons (get-ivar-template sym) + after-not-flow-templates)))] + + [_ + (for-each + (match-lambda + [( public? define? override? + export internal expr import + a-j b-j r-j g-j) + (pretty-debug-object + `(clause (,public? ,define? ,override?) + ,export ,internal ,expr ,import + ,(map FlowType->pretty (list a-j b-j r-j g-j)))) + (new-edge! a-j b-j) + (when public? + (ivar-put this-u export tvar-undef) + (ivar-put this-o export r-j) + (ivar-get this-b export b-j) + (ivar-get this-a export a-j) + (ivar-get this-g export g-j) + (ivar-put this-f export g-j) + (set! public-templates + (cons (get-ivar-template export) + public-templates))) + (when (not public?) + (new-edge! tvar-undef b-j) + (new-edge! r-j a-j)) + (when (not define?) + (ivar-get super-o import r-j)) + (when override? + (extend-after-not-flow-templates! export) + (if (and super-init-expr (not super-init-called)) + (begin + ;; super-init will be called after this init + (ivar-put super-b export a-j) + (ivar-put super-a export a-j) + (extend-before-not-flow-templates! export)) + (begin + ;; super-init may be called before this init + (ivar-put super-a export b-j)))) + (when (and public? (not override?)) + (when define? + ;; Prev value hidden, but define super-b, super-a + (ivar-put super-b export tvar-undef) + (let ([t (mk-Tvar 't)]) + (ivar-get super-o export t) + (ivar-put super-a export t)) + (extend-before-not-flow-templates! export) + (extend-after-not-flow-templates! export) + (set! keyw-local-templates + (cons (get-ivar-template export) + keyw-local-templates)))) + (when define? + (if (eq? expr super-init-expr) + + (let*-vals + ([(ftype nu-env) (handle-application expr env #f)]) + (link-parsed-ftype! expr (wrap-value (mk-tvar-void))) + (pretty-debug-object '(super-init called)) + (set! super-init-called #t) + (set! env nu-env) + (new-AV! r-j AV-void) + + ;; Update env that super-init called + (for-each + (match-lambda + [( _ #f _ _ internal _ import a-j b-j r-j g-j) + (set! env + (atenv:change-binding env internal a-j))] + [_ (void)]) + clause-info)) + + (let*-vals + ( [(ftype nu-env) (traverse expr env)] + [ftype (extract-1st-value ftype)]) + (pretty-debug-atenv + `(env-before-traverse ,(atenv->pretty env))) + (set! env nu-env) + (pretty-debug-atenv + `(env-after-traverse ,(atenv->pretty env))) + (new-edge! (FlowType->Tvar ftype) r-j) + (when internal + (set! env + (atenv:change-binding env internal a-j)))))) + + (pretty-debug-atenv + `(end-clause ,(atenv->pretty env))) + ]) + + clause-info)] + + ;; record ivarset + [public-ivars + (filter-map + (match-lambda + [( public? define? override? + export internal expr import + a-j b-j r-j g-j) + (and public? export)]) + clause-info)] + [_ (new-AV! this-v + (create-AV + template-ivarset public-ivars + (vector super-v) mt-vector))] + + [_ (begin + (new-con! super-o + (create-con-filter + (create-filter #f public-templates) + this-o)) + (new-con! super-f + (create-con-filter + (create-filter #f public-templates) + this-f)) + (new-con! this-b + (create-con-filter + (create-filter #f before-not-flow-templates) + super-b)) + (new-con! this-a + (create-con-filter + (create-filter #f after-not-flow-templates) + super-a)) + (new-con! this-g + (create-con-filter + (create-filter #f keyw-local-templates) + super-g)))]) + + (pretty-debug-object `(keyw-local-templates ,keyw-local-templates)) + (pretty-debug-object `(tvar-class ,(FlowType->pretty tvar-class))) + + (atenv:flush! env) + + (values (wrap-value tvar-class) captured-env))]))) + +;; ---------------------------------------- + +(define (map-clause fn clauses) + (apply append + (map + (match-lambda + [($ zodiac:public-clause exports internals exprs) + (map + (lambda (export internal expr) + (fn #t #t #t (zodiac:read-object export) internal expr #f)) + exports internals exprs)] + [($ zodiac:private-clause internals exprs) + (map + (lambda (internal expr) + (fn #f #t #f #f internal expr #f)) + internals exprs)] + [($ zodiac:inherit-clause internals imports) + (map + (lambda (internal import) + (fn #t #f #f + (zodiac:read-object import) internal #f + (zodiac:read-object import))) + internals imports)] + [($ zodiac:rename-clause internals imports) + (map + (lambda (internal import) + (fn #f #f #f #f internal #f (zodiac:read-object import))) + internals imports)] + [($ zodiac:sequence-clause exprs) + (map + (lambda (expr) + (fn #f #t #f #f #f expr #f)) + exprs)]) + clauses))) + +;; ---------------------------------------------------------------------- + +(define (handle-struct-form tag const atstruct fields) + (match atstruct + [($ atstruct + parent-struct:sym + super-constructors + parent-gen-args + parent-match-args + parent-field-types + parent-list-mutable) + (match-let* + ([constructor (symbol-append 'structure: tag)] + [gen-args (map (lambda (_) (gensym)) fields)] + [match-args + (map (lambda (field gen-arg) + (match field + [((or '! ':) _ type) `(intersect ,gen-arg ,type)] + [_ gen-arg])) + fields gen-args)] + [field-names + (map (lambda (field) + (match field + [((or ': '!) (? symbol? name) _) name] + [(? symbol? name) name] + [_ (mrspidey:error + (format "Bad define-typed-structure field ~s" + field))])) + fields)] + [list-mutable + (map (lambda (field) + (match field + [('! (? symbol? name)) #t] + [_ (not const)])) + fields)] + [field-types + (map + (match-lambda [((or '! ':) _ type) (expand-input-type type)] + [_ 'top]) + fields)] + + [all-gen-args (append parent-gen-args gen-args)] + [all-match-args (append parent-match-args match-args)] + [all-field-types (append parent-field-types field-types)] + [all-list-mutable (append parent-list-mutable list-mutable)] + [_-parent-args (map (lambda (_) '_) parent-gen-args)] + + [gen-arg (gensym)] + [defs `()] + [add-def! + (lambda (fo-Atype) + (set! defs (cons (create-fo-FlowType fo-Atype) defs)))] + [add! + (lambda (type . attrs) + (add-def! + (apply primitive->atprim 'define-struct type attrs)))]) + + ;; (pretty-print match-args) + ;; (pretty-print gen-args) + + (add-def! (make-atstruct + (symbol-append 'struct: tag) + (cons constructor super-constructors) + all-gen-args all-match-args + all-field-types all-list-mutable)) + + (let ([template + (apply constructor->template constructor all-list-mutable)]) + (for-each + (lambda (sc) (record-super-constructor-of-template! sc template)) + super-constructors) + (extend-constructor-env! template)) + + (add! + `(forall ,all-gen-args + (,@all-match-args -> (,constructor ,@all-gen-args)))) + (add! `(_ -> bool) `(predicate ,constructor)) + (for n 0 (length fields) + (let* ([gen-arg (list-ref gen-args n)] + [field-name (list-ref field-names n)]) + (add! + `(forall (,gen-arg) + ((,constructor ,@_-parent-args + ,@(map-with-n + (lambda (field m) + (if (= n m) gen-arg '_)) + fields)) + -> ,gen-arg))) + (when (list-ref list-mutable n) + (add! `(forall (,gen-arg) + ((,constructor ,@_-parent-args + ,@(map-with-n + (lambda (field m) + (if (= n m) + `(! ,gen-arg) + '_)) + fields)) + ,(list-ref match-args n) + -> void)))))) + + (create-fo-FlowType (make-atvalues (reverse defs))))])) + +;; ====================================================================== + +(define (zodiac:parsed-1st-ftype exp) + (extract-1st-value (zodiac:parsed-ftype exp))) + +;; ---------- + +(define (if-splitting-env test env) + ;; Returns (env-true env-false) + ;; Assumes test expression already traversed + ;; Can't lookup things in env, cause not defined for imported vars + (match test + ;; arg + [($ zodiac:varref _ _ _ _ sym) + (let ([arg (zodiac:varref-binding test)]) + (match (zodiac:parsed-1st-ftype test) + [(? Tvar? tvar) + (let* ([tvar-then (mk-Tvar sym)] + [tvar-else (mk-Tvar sym)] + [templates (list (lookup-template 'false))]) + (new-con! tvar + (create-con-filter (create-filter #f templates) tvar-then)) + (new-con! tvar + (create-con-filter (create-filter #t templates) tvar-else)) + (values (atenv:change-binding env arg tvar-then) + (atenv:change-binding env arg tvar-else)))] + ;; Annotated type so don't change + [_ (values env env)]))] + + ;; (not (pred? args ...)) + [($ zodiac:app _ _ _ _ fn (pred-exp)) + (=> fail) + (match (zodiac:parsed-atprim fn) + [($ atprim 'not) + ;; Use recursive call and reverse + (let-values + ([(env-true env-false) (if-splitting-env pred-exp env)]) + (values env-false env-true))] + [_ (fail)])] + + ;; (pred? args ...) + [($ zodiac:app _ _ _ _ fn args) + (=> fail) + (match (zodiac:parsed-atprim fn) + [($ atprim _ type _ predicate-fn) + ;;(pretty-print `(if (pred ,sym ,type ,predicate-fn ...))) + (recur loop ([args-before '()] + [args args] + [env-true env] + [env-false env]) + (match args + [() (values env-true env-false)] + [((and arg ($ zodiac:varref)) . rest-args) + (=> fail) + (let ([barg (zodiac:varref-binding arg)]) + (match (zodiac:parsed-1st-ftype arg) + [(? fo-FlowType?) (fail)] + [(? Tvar? tvar) + (let* + ( [tvars-before (map zodiac:parsed-1st-ftype args-before)] + [tvars-after (map zodiac:parsed-1st-ftype rest-args)] + [tvar-true + (predicate-fn tvars-before tvars-after tvar #t)] + [tvar-false + (predicate-fn tvars-before tvars-after tvar #f)]) + ;;(pretty-print-debug (list tvar-true tvar-false)) + (loop (append args-before (list arg)) + rest-args + (if tvar-true + (atenv:change-binding env-true barg tvar-true) + env-true) + (if tvar-false + (atenv:change-binding env-false barg tvar-false) + env-false)))]))] + [(arg . rest-args) + (loop (append args-before (list arg)) + rest-args env-true env-false)]))] + [_ + ;; Not a primitive + (fail)])] + + [_ (values env env)])) + +;; ---------------------------------------------------------------------- + +(define (flow-sensitive-env pi args env) + (match pi + [($ atprim _ _ domain-filters) + ;; Walk domain-filters and args + (recur loop + ([env env] + [args args] + [domain-filters domain-filters]) + (match (list args domain-filters) + [( ((and arg ($ zodiac:varref _ _ _ _ arg-sym)) + . args-rest) + ((? filter? filter) . filters-rest)) + (=> fail) + (let ([barg (zodiac:varref-binding arg)]) + (match (FlowType->Tvar (zodiac:parsed-1st-ftype arg)) + [(? fo-FlowType?) + ;; Assigned, so don't track + (fail)] + [(? Tvar? tvar) + ;; Have arg and domain + (let ([nu-tvar (mk-Tvar arg-sym)]) + (new-con! tvar (create-con-filter filter nu-tvar)) + (loop (atenv:change-binding env barg nu-tvar) + args-rest filters-rest))]))] + + [( (_ . args-rest) (_ . filters-rest)) + (loop env args-rest filters-rest)] + + [_ env]))] + [#f env])) + +;; ====================================================================== +;; Constants -> constraints +;; All fns return Tvar + +(define (traverse-const V) + ;;(set! gV V) + ;;(pretty-print (zodiac:stripper V)) + ;; Returns nothing + (let ([s (zodiac:const-size V)]) + (if (>= s (st:const-merge-size)) + (traverse-consts-tidy (list V)) + (let ([Tvar (mk-Tvar 'traverse-const)]) + (new-AV! Tvar (traverse-const-exact V)) + Tvar)))) + +(define traverse-consts-tidy + ;; Takes a list of constants + ;; Returns a Tvar + (lambda (V*) + (match-let* + ( [Tvar (mk-Tvar 'traverse-consts-tidy)] + [vec-elems + (apply append + (map + (match-lambda + [($ zodiac:vector _ _ _ v) v] + [(? vector? v) (vector->list v)] + [_ '()]) + V*))] + [elems.cdr* + (filter-map + (match-lambda + [(or ($ zodiac:list _ _ _ l) + (? pair? l) + (? null? l)) + (recur loop ([l l][elems '()]) + (cond + [(pair? l) (loop (cdr l) (cons (car l) elems))] + [else (cons elems l)]))] + [($ zodiac:improper-list _ _ _ l) + (recur loop ([l l][elems '()]) + (cond + [(and (pair? l) (null? (cdr l))) + (cons elems (car l))] + [(pair? l) + (loop (cdr l) (cons (car l) elems))] + [else (cons elems l)]))] + [_ #f]) + V*)] + [elems (apply append (map car elems.cdr*))] + [cdrs (map cdr elems.cdr*)]) + + (unless (null? vec-elems) + (new-AV! Tvar + (make-AV-vec (traverse-consts-tidy vec-elems)))) + (unless (null? elems) + (let* ([tvar-a (traverse-consts-tidy elems)] + [tvar-d (traverse-consts-tidy cdrs)] + [AV (make-AV-cons tvar-a tvar-d)]) + (new-AV! tvar-d AV) + (new-AV! Tvar AV))) + + (for-each + (lambda (V) + (let ([x (traverse-simple-const V)]) + (when x (new-AV! Tvar x)))) + V*) + + Tvar))) + +;; ====================================================================== + diff --git a/collects/mrspidey/Sba/type-con.ss b/collects/mrspidey/Sba/type-con.ss new file mode 100644 index 0000000..0d761fe --- /dev/null +++ b/collects/mrspidey/Sba/type-con.ss @@ -0,0 +1,419 @@ +;; type-con.ss +;; +;; Parses a type to produce a set of constraints +;; Also tests an AVS for membership in a type +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ---------------------------------------------------------------------- + +(define typevar? + (lambda (v) + (and (symbol? v) + (not (type-constructor? v)) + (not (memq v '(_ union rec ->*)))))) + +(define (compat-type-once type cl-fn) + (match type + [(and c (or (? number?) (? char?) ('quote (? symbol?)))) c] + [('rec bind t2) + `(rec ,(map (match-lambda [(a t) (list a (cl-fn t))]) bind) + ,(cl-fn t2))] + [('forall vars type) + `(forall ,vars ,(cl-fn type))] + [('case-> . (and types (? list?) (_ . _))) + `(case-> ,@(map cl-fn types))] + [('union . (? list? union)) `(union ,@(map cl-fn union))] + [(? symbol? a) a] + [(arg '->* res) (list (cl-fn arg) '->* (cl-fn res))] + ;; check constructors + [((? type-constructor? C) . args) + `(,C ,@(map (match-lambda + [('! arg) (list '! (cl-fn arg))] + [arg (cl-fn arg)]) + args))] + [_ #f])) + +(define (expand-input-type type) + ;; Do rewriting transformations + ;;(pretty-print `(expand-type ,type)) + (let ([t2 (input-type-expander type)]) + (if (eq? type t2) + (or (compat-type-once type expand-input-type) + (mrspidey:error + (format "Bad input type ~s" type))) + (expand-input-type t2)))) + +(define (expand-output-type type) + ;; Do rewriting transformations + ;;(pretty-print `(expand-type ,type)) + (let* ([type (or (compat-type-once type expand-output-type) + type + (mrspidey:error (format "Bad output type ~s" type)))]) + (recur fn ([type type]) + (let ([t2 (output-type-expander type)]) + (if (eq? type t2) + type + (fn t2)))))) + +;; ---------------------------------------------------------------------- + +(define (con-exp->templates con-exp) + ;; Assumes con-exp already expanded + (match con-exp + [('union . E*) + (let ([T* (map con-exp->templates E*)]) + (and (andmap (lambda (x) x) T*) + (apply append T*)))] + [('forall _ type) (con-exp->templates type)] + [(_ '->* _) (list template-lam)] + [(or (C . _) C) + (if (type-constructor? C) + (list (lookup-template C)) + #f)])) + +;; ---------------------------------------------------------------------- + +(define (generic-type->con type prefix forall-env sign) + ;; Assumes type->con is already expanded + (letrec + ([mk-AVS-tmp (lambda () (mk-AVS (symbol-append prefix ':tc)))] + [parse-type-generic + (lambda (t env sign) + ;; sign is #t for +ive, #f for -ive + (let ([new-sign-edge! + (lambda (from to) + (if sign + (new-edge! from to) + (new-edge! to from)))] + [parse-type + (lambda (t) + (parse-type-generic t env sign))]) + (match t + + ;; Recursive definitions + [('rec bind t2) + (let* ([a* (map car bind)] + [AVS* (map + (lambda (a) + (mk-AVS (symbol-append prefix ': a))) + a*)] + [env (extend-env* env a* AVS*)]) + (for-each + (match-lambda + [(a t) + (new-sign-edge! (parse-type-generic t env sign) + (lookup env a))]) + bind) + (parse-type-generic t2 env sign))] + + ;; Unions + [('union . (? list? union)) + (let ([AVS (mk-AVS-tmp)]) + (for-each + (lambda (t) + (new-sign-edge! (parse-type-generic t env sign) + AVS)) + union) + AVS)] + + ;; case-> + [('case-> . (? list? types)) + (parse-type-generic (rac types) env sign)] + + ;; type variables + ['_ (mk-AVS-tmp)] + [(? symbol? a) + (lookup-or-fail + env a + (lambda () + (lookup-or-fail + forall-env a + (lambda () + ;; reference type named a + ;; if sign +ive, use this type + ;; if sign -ive, return dummy AVS + (let ([AVS (mk-AVS (symbol-append prefix ': a))]) + (set! global-in-type-env + (cons (list a AVS (box #f)) global-in-type-env)) + (if sign + AVS + (mk-AVS (symbol-append prefix ': a))))))))] + + [(arg '->* res) + (let ([AVS (mk-AVS-tmp)]) + (if sign + ;; make the AV + (new-AV! AVS + (make-AV-lam + (parse-type-generic arg env #f) + (parse-type-generic res env #t) + 0 #t)) + ;; extract the various components + (begin + (new-con! AVS + (create-con + template-lam 0 + (parse-type-generic arg env #t))) + (new-con! AVS + (create-con + template-lam 1 + (parse-type-generic res env #f))))) + AVS)] + + ;; constants + [(or (? number? c) (? char? c) ('quote (? symbol? c))) + (let ([AVS (mk-AVS-tmp)]) + (if sign (new-AV! AVS (traverse-const c))) + AVS)] + + ;; check constructors + [((? type-constructor? C) . args) + (match-let* + ([(and template ($ template type signs ref assign)) + (lookup-template C)] + [AVS (mk-AVS-tmp)]) + (unless (= (vector-length ref) (length args)) + (mrspidey:error + (format "Constructor ~s given ~s arg(s), expected ~s" + C (length args) (vector-length ref)))) + (if sign + ;; make the AV, unless void and (st:see-void) is false + (unless (and (eq? C 'void) (not (st:see-void))) + (new-AV! + AVS + (apply + make-constructed-AV C + (map + (lambda (a) + (parse-type-generic a env sign)) + args) + ;; DO SOMETHING FOR NULL ARGS + ))) + + ;; extract the various components + ;; need to do unification on mutable fields, + ;; unless pattern matching arg is (! a) + (for-each-with-n + (lambda (arg n) + (match arg + ['_ (void)] + [('! a) + (unless (vector-ref assign n) + (mrspidey:error + "! used on immutable field in type")) + ;; Inject only + (new-con! + AVS + (create-con template (vector-ref assign n) + (parse-type-generic a env #t)))] + [arg + ;; Extract + (new-con! + AVS + (create-con template (vector-ref ref n) + (parse-type-generic arg env #f)))])) + args)) + AVS)] + [_ + ;; Didn't match any type + (mrspidey:error (format "invalid type syntax ~s" t))])))]) + + (let ([AVS (parse-type-generic type empty-env sign)]) + AVS))) + +;; ---------------------------------------------------------------------- + +(define (type->con type AVS prefix top-misc) + ;; Assumes type is already expanded + (new-edge! (generic-type->con type prefix empty-env #t) AVS) + + ;; Put top-misc in misc field of each AV + (for-each + (lambda (AV) (set-AV-misc! AV top-misc)) + (get-AVS-objs AVS))) + +;; ---------------------------------------------------------------------- + +(define (split-schema type) + (match type + [('forall vars type) + (list + (map (lambda (v) (cons v (mk-AVS-tmp v))) vars) + type)] + [type (list '() type)])) + +(define (type-schema->con type AVS prefix top-misc) + ;; Assumes type is already expanded + (match-let ([(forall-env type) (split-schema type)]) + (new-edge! (generic-type->con type prefix forall-env #t) AVS) + + ;; Put top-misc in misc field of each AV + (for-each + (lambda (AV) (set-AV-misc! AV top-misc)) + (get-AVS-objs AVS)))) + +;; ---------------------------------------------------------------------- + +(define (type-schema->con-for-nargs type prefix n) + ;; Assumes type is already expanded + ;; Puts top-misc in misc field of top AV + ;; returns ((AVS-para ...) . AVS-result) if possible + ;; otherwise returns #f + + (match-let ([(forall-env type) (split-schema type)]) + (match (dom+rng-for-nargs type n) + [#f #f] + [(forall-env para* rng) + (recur loop ([para* para*] + [AVS-para* '()]) + (match para* + [() + (cons (reverse AVS-para*) + (generic-type->con rng prefix forall-env #t))] + [(para . rest) + (let* ([AVS-para (generic-type->con para prefix forall-env #f)]) + (loop rest (cons AVS-para AVS-para*)))]))]))) + +;; ---------------------------------------------------------------------- + +(define (dom+rng-for-nargs type nargs) + ;; extracts appropriate type from top-level case->. + ;; returns (forall-env (para ...) result) if matching case + ;; o/w returns #f + + (let* ([try1 + (lambda (type forall) + ;; See if type has the right # args + (match type + [(dom '->* rng) + (recur loop ([dom dom][para* '()][n nargs]) + (match dom + [('nil) + (if (zero? n) + (list (map (lambda (v) (cons v (mk-AVS-tmp 'dr))) + forall) + (reverse para*) + rng) + #f)] + [('cons para rest) (loop rest (cons para para*) (sub1 n))] + [_ #f]))]) + [_ #f])] + [try2 + (lambda (type forall) + (match type + [('case-> . types) + (ormap (lambda (t) (try1 t forall)) types)] + [type (try1 type forall)]))]) + (match type + [('forall vars type) (try2 type vars)] + [type (try2 type '())]))) + +;; ---------------------------------------------------------------------- + +(define AVS-in-type? + (lambda (AVS type) + ;; Checks if AVS is contained in the type + ;; Assumes type is already expanded + + (letrec + ([visit-alloc (lambda () (make-vector num-AV #f))] + [add-visit! + (lambda (v AV) + (vector-set! v (AV-num AV) #t))] + [visited? + (lambda (v AV) + (vector-ref v (AV-num AV)))] + [AVS-in-type? + (lambda (AVS type env) + ;; env maps type vars to AV-membership test function + (andmap (lambda (AV) (AV-in-type? AV type env)) + (get-AVS-objs AVS)))] + [AV-in-type? + (lambda (AV type env) + ;; env maps type vars to AV-membership test function + (match type + + ;; Recursive definitions + [('rec bind t2) + (let* + ([a* (map car bind)] + [t* (map cadr bind)] + [envbox (box #f)] + [nuenv + (extend-env* + env a* + (map (lambda (t) + (let ([v (visit-alloc)]) + (lambda (AV) + (or (visited? v AV) + (begin + (add-visit! v AV) + (AV-in-type? AV t (unbox envbox))))))) + t*))]) + (set-box! envbox nuenv) + (AV-in-type? AV t2 nuenv))] + + [('case-> . types) (AV-in-type? AV (rac types) env)] + + [('union . (? list? union)) + (ormap (lambda (type) (AV-in-type? AV type env)) + union)] + ['_ #t] + [(? symbol? a) + ((lookup-or-fail env a (lambda () (lambda (AV) #t))) + AV)] + [(arg '->* res) (eq? (AV-template AV) template-lam)] + + [(? number? n) + (and (eq? (template-type (AV-template AV)) 'num) + (= (AV-misc AV) n))] + [(? char? c) + (and (eq? (template-type (AV-template AV)) 'char) + (char=? (AV-misc AV) c))] + [('quote (? symbol? s)) + (and (eq? (template-type (AV-template AV)) 'sym) + (eq? (AV-misc AV) s))] + + [((? type-constructor? C) . args) + (match-let + ([(and template ($ template type signs ref assign)) + (lookup-template C)]) + (cond + [(eq? (AV-template AV) template) + (recur loop ([args args][n 0]) + (if (null? args) + #t + (and + (AVS-in-type? + (vector-ref (AV-fields AV) (vector-ref ref n)) + (match args + [(('! a) . _) a] + [(a . _) a]) + env) + (loop (cdr args) (add1 n)))))] + [(memq (AV-template AV) (template-sub-templates template)) + #t] + [else #f]))] + [_ + ;; Didn't match any type + (mrspidey:error (format "Invalid type syntax ~s" type))]))]) + (AVS-in-type? AVS type empty-env)))) + +;(trace AVS-in-type?) + + + diff --git a/collects/mrspidey/Sba/type-env.ss b/collects/mrspidey/Sba/type-env.ss new file mode 100644 index 0000000..afb6232 --- /dev/null +++ b/collects/mrspidey/Sba/type-env.ss @@ -0,0 +1,116 @@ +;; type-env.ss +;; Handles the type environment (env for type inference) +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; ---------------------------------------------------------------------- + +;; ====================================================================== +;; Global type env + +(define global-tref-env '()) +(define global-tdef-env '()) +(define global-tbang-env '()) + +(define (add-global-tref! sym tvar) + (set! global-tref-env (cons (cons sym tvar) global-tref-env))) +(define (add-global-tdef! sym tvar) + (set! global-tdef-env (cons (cons sym tvar) global-tdef-env))) +(define (add-global-tbang! sym tvar) + (set! global-tbang-env (cons (cons sym tvar) global-tbang-env))) +(define (init-global-tenv! r d b) + (set! global-tref-env r) + (set! global-tdef-env d) + (set! global-tbang-env b)) + +;; ---------------------------------------------------------------------- +;; find-matching-def + +(define (find-matching-def sym defs) + (ormap (match-lambda + [(sym2 . def) (and (eq? sym sym2) def)]) + defs)) + +;; ---------------------------------------------------------------------- +;; report-duplicate-defs +;; Report duplicate definitions + +(define (report-duplicate-defs env) + (pretty-debug `(report-duplicate-defs ,@(map car env))) + (recur loop ([env env][dupls '()]) + (match env + [() (void)] + [((sym1 . _) . rest) + (if (and (find-matching-def sym1 rest) + (not (memq sym1 dupls))) + (begin + (mrspidey:warning + (format "Duplicate definition of variable ~s" sym1)) + (loop rest (cons sym1 dupls))) + (loop rest dupls))]))) + +;;---------------------------------------------------------------------- +;; report-unbound-vars-env + +(define report-unbound-vars + (case-lambda + [(ref-env) (report-unbound-vars ref-env "")] + [(ref-env msg) + (for-each + (match-lambda + [(sym . _) + (mrspidey:warning (format "Unbound type variable ~s~a" sym msg))]) + ref-env)])) + +;; ---------------------------------------------------------------------- +;; connect-refs-defs +;; Connects refs to defs, returns list of unbound refs + +(define (connect-refs-defs ref-env def-env) + (pretty-debug + `(connect-refs-defs ,(map car ref-env) ,(map car def-env))) + (filter + (match-lambda + [(and r (sym . tvar)) + (match (find-matching-def sym def-env) + [#f #t] + [ftype + (new-edge! (FlowType->Tvar ftype) tvar) + #f])]) + ref-env)) + +;; ---------------------------------------------------------------------- +;; combine-def-bang +;; Connects each bang to def, and reports bangs to undefd vars + +(define (connect-bangs-defs bang-env def-env) + (pretty-debug + `(connect-bangs-defs ,(map car bang-env) ,(map car def-env))) + (for-each + (match-lambda + [(s2 . tvar2) + (match (find-matching-def s2 def-env) + [#f (mrspidey:warning + (format "Assignment to undefined variable ~s" s2))] + [tvar1 + (unless (Tvar? tvar1) + (mrspidey:error "Assignment to annotated type")) + (assert (Tvar? tvar2)) + (new-edge! tvar2 tvar1)])]) + bang-env)) + + + diff --git a/collects/mrspidey/Sba/typelang.ss b/collects/mrspidey/Sba/typelang.ss new file mode 100644 index 0000000..68837bc --- /dev/null +++ b/collects/mrspidey/Sba/typelang.ss @@ -0,0 +1,878 @@ +;; typelang.ss +;; Parses a type to produce a set of constraints +;; Also tests an Tvar for membership in a type +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +;; type ::= ... +;; schema ::= type | (forall vars type) +;; tschema ::= schema | (case-> schema ...) +;; lambda types are +;; (a b c -> d e f) +;; (a b c rest *-> d e f) +;; (a b c ->* results) +;; (a b c rest *->* results) +;; (lambda domain range) +;; ====================================================================== +; Union, Intersect etc + +(define absUnion + (lambda (exps) + (match + (apply append + (map + (match-lambda + ['empty '()] + [('union . exps) exps] + [exp (list exp)]) + ;;(list->set-equal? exps) + exps + )) + [() 'empty] + [(e) e] + [exps `(union ,@exps)]))) + +(define absunion (lambda exps (absUnion exps))) + +(define absIntersect + (lambda (exps) + (match + (apply append + (map + (match-lambda + ['_ '()] + [('intersect . exps) exps] + [exp (list exp)]) + (list->set-equal? exps))) + [() '_] + [(e) e] + [exps `(intersect ,@exps)]))) + +(define absintersect (lambda exps (absIntersect exps))) + +;; ====================================================================== + +(define (output-type-constructor? C) + (or + (memq C '(bool listof list atom sexp values)) + (type-constructor? C))) + +(define (output-type-expander type) + (all-output-type-expanders + (or + (compat-type-once type output-type-expander) + type))) + +;--- +(define output-type-expanders '()) + +(define (all-output-type-expanders type) + (foldl + (lambda (expander type) (expander type)) + type + output-type-expanders)) + +;--- + +(define (install-output-type-expander! expander) + (set! output-type-expanders (cons expander output-type-expanders))) + +(define (init-output-type-expander!) + + (install-output-type-expander! + (match-lambda + [((? output-type-constructor? C)) C] + [('cons t 'nil) `(list ,t)] + [('cons t ('list . t*)) `(list ,t ,@t*)] + [('lambda dom rng) (list dom '*->* rng)] + [('unit-result* ('values rng)) `(unit-result ,rng)] + [('union X) X] + [(? list? t) + (=> fail) + (match (reverse t) + [( ('values x) + (and arrow (or '*->* '->*)) + . domains) + (append (reverse domains) + (list (case arrow + [(*->*) '*->] + [(->*) '->]) + x))] + [_ (fail)])] + [(('list . args) '*-> . results) `(,@args -> . ,results)] + [(('list . args) '*->* . results) `(,@args ->* . ,results)] + [('union . X) + (=> fail) + (cond + [(and (memq 'true X) (memq 'false X)) + `(union bool ,@(remq 'true (remq 'false X)))] + [(and (memq 'bool X) + (or (memq 'true X) (memq 'false X))) + `(union ,@(remq 'true (remq 'false X)))] + [else (fail)])] + [(or ('union 'true 'false) ('union 'false 'true)) 'bool] + + [('mvalues ('list . x)) `(values ,@x)] + [('rec () body) body] + [(or + ('union 'nil ('cons X ('listof Y))) + ('union ('cons X ('listof Y)) 'nil)) + (=> fail) + (if (equal? X Y) `(listof ,Y) (fail))] + [('epsilon X) X] + [((and combine (or 'union 'intersect)) . parts) + (=> fail) + (if (not (st:sdl-tidy)) + (fail) + (let ([combine-fn (case combine + [(intersect) absintersect] + [(union) absunion])]) + (pretty-debug-sdl `(combine ,combine parts ,parts)) + (apply combine-fn + (recur loop ([parts parts]) + (match parts + [(a . d) + (let ([d (loop d)]) + (if (member a d) + d + (match a + [((? output-type-constructor? C) . C-args) + (let*-vals + ( [len-C-args (length C-args)] + [(args* rest) + (filter-map-split + (match-lambda + [(C2 . args) + (and + (eq? C C2) + (= len-C-args (length args)) + args)] + [_ #f]) + parts)]) + (pretty-debug-sdl `(args* ,args* rest ,rest)) + (if (null? (cdr args*)) + (cons a d) + (cons (cons C (apply map + combine-fn + args*)) + rest)))] + [_ (cons a d)])))] + [() '()])))))] + [type type])) + ) + + + +;; ====================================================================== +;; For input-type-expander, recursion is done in expand-input-type + +(define input-type-expander 'input-type-expander) + +(define (init-input-type-expander!) + (set! input-type-expander (lambda (x) x)) + (let ([loop (lambda (x) x)]) + (install-input-type-expander! + (match-lambda + ['atom (loop '(union nil num sym str char true false))] + ['sexp (let ([u (gensym)]) + (loop `(MU ,u (union atom (box ,u) (cons ,u ,u) (vec ,u)))))] + ['bool (loop '(union false true))] + [('arg a b) (loop (list 'cons a b))] + ['noarg (loop 'nil)] + ['null (loop 'nil)] + [('arglistof t) + (let ((u (gensym))) + (loop `(MU ,u (union noarg (arg ,t ,u)))))] + [('arglist) (loop 'noarg)] + [('arglist t . t*) (loop `(arg ,t (list ,@t*)))] + [('listof t) + (let ((u (gensym))) + (loop `(MU ,u (union nil (cons ,t ,u)))))] + [('list) (loop 'nil)] + [('list t . t*) (loop `(cons ,t (list ,@t*)))] + + [('MU (? typevar? a) t) + (loop `(rec ([,a ,t]) ,a))] + [(? type-constructor? C) (loop (list C))] + [(? (lambda (t) (and (list? t) (memq '-> t))) + t) + ;; Make the *-> function + (recur loop2 ([wrapper-fn (lambda (x) x)] + [t t]) + (match t + [('-> . results) + (loop `(,(wrapper-fn 'noarg) *-> ,@results))] + [('optional y . rest) + (loop2 (lambda (x) (wrapper-fn `(union noarg (arg ,y ,x)))) + rest)] + [(y . rest) + (loop2 (lambda (x) (wrapper-fn `(arg ,y ,x))) + rest)]))] + [(? (lambda (t) (and (list? t) (memq '*-> t))) + t) + ;; Make the *->* function + (recur loop2 ( [wrapper-fn (lambda (x) x)] + [t t]) + (match t + [('*-> . _) (mrspidey:error "*-> type w/o domain")] + [(rest '*-> . results) + (loop `(,(wrapper-fn rest) + *->* + (mvalues + ,(foldr (lambda (arg rest) `(cons ,arg ,rest)) + '(nil) + results))))] + [(y . rest) + (loop2 (lambda (x) (wrapper-fn `(arg ,y ,x))) + rest)]))] + [(? (lambda (t) (and (list? t) (memq '->* t))) t) + (match (reverse t) + [(result '->* . domain) + `( (list ,@(reverse domain)) *->* ,result)] + [_ (mrspidey:error "Bad type ~s" t)])] + [(dom '*->* rng) (loop `(lambda ,dom ,rng))] + [type type])))) + +(define (install-input-type-expander! expander) + (let ([old-expander input-type-expander]) + (set! input-type-expander + (lambda (type) + ;;(pretty-print-debug `(input-type-expander ,type)) + (old-expander (expander type)))))) + +;; ====================================================================== + +(define typevar? + (lambda (v) + (and (symbol? v) + (not (output-type-constructor? v)) + (not (memq v '(_ union rec -> *-> ->* *->*)))))) + +(define (compat-type-once type cl-fn) + (match type + [(and c (or (? number?) (? char?) ((or 'quote '#%quote) (? symbol?)))) c] + [('rec bind t2) + `(rec ,(map (match-lambda [(a t) (list a (cl-fn t))]) bind) + ,(cl-fn t2))] + [('forall vars type) + `(forall ,vars ,(cl-fn type))] + [('case-> . (and types (? list?) (_ . _))) + `(case-> ,@(map cl-fn types))] + [('union . (? list? union)) `(union ,@(map cl-fn union))] + [('scheme: E) type] + [('intersect . (? list? union)) `(intersect ,@(map cl-fn union))] + [(? symbol? a) a] + [((? (lambda (t) (memq t '(object class))) t) . ivar-types) + (cons t + (map + (match-lambda + [(ivar type) (list ivar (cl-fn type))]) + ivar-types))] + ;; check constructors + [((? output-type-constructor? C) . args) + `(,C ,@(map (match-lambda + [('! arg) (list '! (cl-fn arg))] + [arg (cl-fn arg)]) + args))] + [(? (lambda (t) + (and (list? t) + (or (memq '-> t) (memq '*-> t) (memq '->* t) (memq '*->* t)))) + t) + (map cl-fn t)] + [_ #f])) + +(define (expand-input-type type) + ;; Do rewriting transformations + ;; (pretty-print-debug `(expand-type ,type)) + (let ([t2 (input-type-expander type)]) + (if (eq? type t2) + (or (compat-type-once type expand-input-type) + (mrspidey:error (format "Invalid type syntax ~s" type))) + (expand-input-type t2)))) + +(define (expand-input-type-err type at) + ;; Do rewriting transformations + ;; (pretty-print-debug `(expand-type ,type)) + (let ([t2 (input-type-expander type)]) + (if (eq? type t2) + (or (compat-type-once type + (lambda (type) (expand-input-type-err type at))) + (mrspidey:error (format "Invalid type syntax ~s" type) at)) + (expand-input-type-err t2 at)))) + +(define (expand-output-type type) + ;; Do rewriting transformations + (pretty-debug `(expand-output-type ,type)) + (letrec + ([local-expand-output-type + (lambda (type) + (let* ([type (or (compat-type-once type local-expand-output-type) + type + (mrspidey:error (format "Bad output type ~s" type)))]) + (let ([t2 (output-type-expander type)]) + (if (equal? type t2) + type + (local-expand-output-type t2)))))]) + (if (st:expand-output-type) + (match (local-expand-output-type type) + [('values x) x] + [('rec bindings ('values x)) `(rec ,bindings ,x)] + [x x]) + type))) + +;; ---------------------------------------------------------------------- + +(define (type->templates con-exp) + ;; Assumes con-exp already expanded + (match con-exp + [('union . E*) + (let* ([T* (map type->templates E*)]) + (if (andmap (lambda (x) x) T*) + (apply union T*) + #f))] + [('intersect . E*) + (let* ([T* (map type->templates E*)] + [T* (filter (lambda (x) x) T*)]) + (apply intersect T*))] + [('forall _ type) (type->templates type)] + [(or (C . _) C) + (if (type-constructor? C) + (list (lookup-template C)) + #f)])) + +;; ---------------------------------------------------------------------- + +(define ( generic-type->con type prefix forall-env sign) + ;; Assumes type is already expanded + (letrec + ([mk-Tvar-tmp (lambda () (mk-Tvar (symbol-append prefix ':tc)))] + [parse-type-generic + (lambda (t env sign) + ;; sign is #t for +ive, #f for -ive + ;; (pretty-print-debug `(parse-type-generic ,t ,env ,sign)) + (let ([new-sign-edge! + (lambda (from to) + (if sign + (new-edge! from to) + (new-edge! to from)))] + [parse-type + (lambda (t) + (let ([r (parse-type-generic t env sign)]) + ;;(pretty-print-debug `(parse-type-generic ,t ,(Tvar-name r))) + r))]) + (match t + + ;; Recursive definitions + [('rec bind t2) + (let* ( [a* (map car bind)] + [env env] + [mk-tvar* + (map + (lambda (a rhs) + (letrec + ([f (lambda (sign) + (pretty-debug `(rec ,a ,sign)) + (let* + ( [sym (symbol-append prefix ': a)] + [tvar (mk-Tvar sym)] + [_ (set! f + (lambda (sign2) + (unless (eq? sign sign2) + (mrspidey:error + (format "rec-bound variable ~s referenced in covariant and contravariant positions in type ~s" a type))) + tvar))] + [tvar2 + (parse-type-generic rhs env sign)]) + (if sign + (new-edge! tvar2 tvar) + (new-edge! tvar tvar2)) + tvar))]) + (lambda (sign) (f sign)))) + a* (map cadr bind))]) + (set! env (extend-env* env a* mk-tvar*)) + (parse-type-generic t2 env sign))] + + ;; Unions + [('union . (? list? union)) + (let ([Tvar (mk-Tvar-tmp)]) + (for-each + (lambda (t) + (new-sign-edge! (parse-type-generic t env sign) Tvar)) + union) + Tvar)] + + ;; Scheme + ;[('scheme: E) + ; (assert (eq? sign #t) 'scheme:) + ; (let*-vals + ; ( [p (open-output-string)] + ; [_ '(pretty-print E p)] + ; [p (close-output-port)] + ; [s (get-output-string p)] + ; [p (open-input-string s)] + ; [E ((zodiac:read p))] + ; [defs (my-scheme-expand-program (list E))] + ; [(ftype _ _) (traverse-exp (car defs) atenv:empty)] + ; [tvar (FlowType->Tvar ftype)]) + ; tvar)] + + [('intersect . (? list? intersect)) + (when sign + (mrspidey:error "Intersection in covariant position")) + (let ([Tvar (mk-Tvar-tmp)]) + (for-each + (lambda (t) + (new-edge! Tvar (parse-type-generic t env sign))) + intersect) + Tvar)] + + ;; type variables + ['_ + (when sign + (mrspidey:error "_ type in covariant position")) + (mk-Tvar-tmp)] + + ['empty + (unless sign + (mrspidey:error + (format "empty in contravariant position in ~s" type))) + (mk-Tvar-tmp)] + + [(? symbol? a) + (cond + [(lookup-or-#f env a) + => (lambda (mk-tvar) (mk-tvar sign))] + [else + (or + (lookup-or-#f forall-env a) + (let ([Tvar (mk-Tvar a)]) + (if sign + (add-global-tref! a Tvar) + (add-global-tbang! a Tvar)) + Tvar))])] + + [('lambda arg res) + (let ([Tvar (mk-Tvar-tmp)]) + (if sign + ;; make the AV + (new-AV! Tvar + (make-AV-lam + (parse-type-generic arg env #f) + (parse-type-generic res env #t) + 0 #t)) + ;; extract the various components + (begin + (new-con! Tvar + (make-con-dom (parse-type-generic arg env #t))) + (new-con! Tvar + (make-con-rng + (parse-type-generic res env #f))))) + Tvar)] + + ;; constants + [(or (? number? c) (? char? c) + ((or 'quote '#%quote) (? symbol? c))) + (let ([Tvar (mk-Tvar-tmp)]) + (if sign (new-AV! Tvar (traverse-simple-const c))) + Tvar)] + + ;; check constructors + [((? type-constructor? C) . args) + (match-let* + ([(and template ($ template type n+ n- ref assign)) + (lookup-template C)] + [Tvar (mk-Tvar-tmp)]) + (unless (= (vector-length ref) (length args)) + (mrspidey:error + (format "Constructor ~s given ~s arg(s), expected ~s" + C (length args) (vector-length ref)))) + (if sign + ;; make the AV, unless void and (st:see-void) is false + (unless (and (eq? C 'void) (not (st:see-void))) + (let ([args + (map + (lambda (a) (parse-type-generic a env sign)) + args)]) + ;;(pretty-print-debug `(,C ,@(map Tvar-name args))) + (new-AV! + Tvar + (apply make-constructed-AV C args)))) + ;; DO SOMETHING FOR NULL ARGS + + ;; extract the various components + ;; need to do unification on mutable fields, + ;; unless pattern matching arg is (! a) + (for-each-with-n + (lambda (arg n) + (match arg + [(or '_ 'top)(void)] + [('! a) + (match (vector-ref assign n) + [#f + (mrspidey:error + "! used on immutable field in type")] + [n + ;; Inject only + (new-con! + Tvar + (create-con template n + (parse-type-generic a env #t) #f))])] + [arg + ;; Extract + (new-con! + Tvar + (create-con template (vector-ref ref n) + (parse-type-generic arg env #f) #t))])) + args)) + Tvar)] + [_ + ;; Didn't match any type + (mrspidey:error (format "invalid type syntax ~s" t))])))]) + + (let ([Tvar (parse-type-generic type empty-env sign)]) + Tvar))) + +;; ---------------------------------------------------------------------- + +(define (split-schema type) + (match type + [('forall vars type) + (values vars type)] + [type (values '() type)])) + +(define (schema->env+type type) + (let-values ([(vars type) (split-schema type)]) + (values + (map (lambda (v) (cons v (mk-Tvar v))) vars) + type))) + +(define (schema->con schema Tvar prefix top-misc) + (let-values ([(forall-env type) (schema->env+type schema)]) + + (new-edge! (generic-type->con type prefix forall-env #t) Tvar) + + ;; Put top-misc in misc field of each AV + (for-each + (lambda (AV) (set-AV-misc! AV top-misc)) + (get-Tvar-objs Tvar)))) + +;; ---------------------------------------------------------------------- + +(define (tschema->con tschema Tvar prefix top-misc) + (schema->con + (match tschema + [('case-> . schema*) (rac schema*)] + [schema schema]) + Tvar prefix top-misc)) + +;; ---------------------------------------------------------------------- + +(define (tschema->con-for-nargs tschema Tvar prefix top-misc n) + ;; Assumes type is already expanded + + (match tschema + [('case-> . schema*) + (or + (ormap + (lambda (schema) + (let-values ([(forall-env type) (schema->env+type schema)]) + (if (function-takes-nargs? type n) + (schema->con schema Tvar prefix top-misc) + #f))) + schema*) + (schema->con (rac schema*) Tvar prefix top-misc))] + [schema + (schema->con schema Tvar prefix top-misc)])) + +;; ---------------------------------------------------------------------- + +(define (function-takes-nargs? type nargs) + (match type + [('lambda dom rng) + (recur loop ([dom dom][n nargs]) + (match dom + [('nil) (zero? n)] + [('cons para rest) (loop rest (sub1 n))] + [_ #f]))] + [_ #f])) + +;; ---------------------------------------------------------------------- + +'(define (Tvar-in-type? ftype type) + (let* ([o (old-Tvar-in-type? ftype type)] + [Tvar2 (mk-Tvar 'in-type?)] + [_ (tschema->con type Tvar 'in-type? '())] + [n (Tvar-containment? ftype ftype2)]) + (unless (eq? o n) + (mrspidey:warning + (format "Tvar-in-type old ~s new ~s type ~s" o n type)) + o))) + +(define Tvar-in-type? + (lambda (Tvar type forall-vars unbound) + + ;; (pretty-print `(Tvar-in-type? ,(Tvar-name Tvar) ,type ,forall-vars)) + ;; Checks if Tvar is contained in the type + ;; Assumes type is already expanded + + (letrec + ([visit-alloc (lambda () (make-vector num-AV #f))] + [add-visit! + (lambda (v AV) + (vector-set! v (AV-num AV) #t))] + [visited? + (lambda (v AV) + (vector-ref v (AV-num AV)))] + [Tvar-in-type? + (lambda (Tvar type env) + ;; env maps type vars to AV-membership test function + (andmap (lambda (AV) (AV-in-type? AV type env)) + (get-Tvar-objs Tvar)))] + [AV-in-type? + (lambda (AV type env) + ;; env maps type vars to AV-membership test function + (match type + + ;; Recursive definitions + [('rec bind t2) + (let* + ([a* (map car bind)] + [t* (map cadr bind)] + [envbox (box #f)] + [nuenv + (extend-env* + env a* + (map (lambda (t) + (let ([v (visit-alloc)]) + (lambda (AV) + (or (visited? v AV) + (begin + (add-visit! v AV) + (AV-in-type? AV t (unbox envbox))))))) + t*))]) + (set-box! envbox nuenv) + (AV-in-type? AV t2 nuenv))] + + [('case-> . types) (AV-in-type? AV (rac types) env)] + + [('union . (? list? union)) + (ormap (lambda (type) (AV-in-type? AV type env)) + union)] + [('intersect . (? list? intersect)) + (andmap (lambda (type) (AV-in-type? AV type env)) + intersect)] + ['_ #t] + [(? symbol? a) + (let ([fn (or (lookup-or-#f env a) + (and (memq a forall-vars) (lambda (AV) #t)) + (let ([type:a a]) + (ormap + (match-lambda + [(sym . Tvar) + (if (eq? sym type:a) + (lambda (AV) + (let ([Tvar-t (mk-Tvar 'in-type?)]) + (new-AV! Tvar-t AV) + (Tvar-containment? Tvar-t Tvar))) + #f)]) + global-tdef-env)) + (unbound a))]) + (fn AV))] + [('lambda arg res) + (and (eq? (AV-template AV) template-lam) + (Tvar-in-type? + (vector-ref (AV-fields+ AV) 0) + res + env))] + [(? number? n) + (and (eq? (template-type (AV-template AV)) 'num) + (number? (AV-misc AV)) + (= (AV-misc AV) n))] + [(? char? c) + (and (eq? (template-type (AV-template AV)) 'char) + (char=? (AV-misc AV) c))] + [((or 'quote '#%quote) (? symbol? s)) + (and (eq? (template-type (AV-template AV)) 'sym) + (eq? (AV-misc AV) s))] + + [((? type-constructor? C) . args) + (match-let + ([(and template ($ template type n+ n- ref assign)) + (lookup-template C)]) + (cond + [(or (eq? (AV-template AV) template) + (memq template + (template-super-templates (AV-template AV)))) + (recur loop ([args args][n 0]) + (if (null? args) + #t + (and + (or + (not (vector-ref ref n));; Can't reference + (Tvar-in-type? + (vector-ref (AV-fields+ AV) (vector-ref ref n)) + (match args + [(('! a) . _) a] + [(a . _) a]) + env)) + (loop (cdr args) (add1 n)))))] + [else + '(pretty-print-debug + `(fail ,(AV-template AV) + ,C + ,template + ,(template-super-templates (AV-template AV)) + ,(memq template + (template-super-templates (AV-template AV))))) + #f]))] + [_ + ;; Didn't match any type + (mrspidey:error (format "Invalid type syntax ~s" type))]))]) + (Tvar-in-type? Tvar type empty-env)))) + +; ====================================================================== + +'(define (FV-tschema tschema) + ;; returns (FV-ref FV-bang) + (let ([FV-ref '()] + [FV-bang '()]) + (letrec + ([FV-type + (lambda (type env sign) + (match type + [('rec bind t2) + (let ([env (append (map car bind) env)]) + (FV-type* (map cadr bind) env sign) + (FV-type t2 env sing))] + [((or 'union 'intersect (? type-constructor?)) . (? list? args)) + (FV-type* args env sign)] + [(or '_ 'empty (? number?) (? char?) + ((or 'quote '#%quote) (? symbol?))) + (void)] + [(or (? symbol? a) ('! (? symbol? a))) + (if sign + (set! FV-ref (set-add a FV-ref)) + (set! FV-bang (set-add a FV-bang)))] + [x + ;; Didn't match any type + (mrspidey:internal-error 'FV-type + "invalid type syntax ~s" x)]))] + [FV-type* + (lambda (types env sign) + (for-each (lambda (t) (FV-type t env sign)) types))] + [FV-schema + (match-lambda + [('forall vars type) + (setdiff2 (FV-type type) vars)] + [type (FV-type type vars #t)])] + [FV-tschema + (match-lambda + [('case-> . schemas) + (apply union (map FV-schema schemas))] + [schema (FV-schema schema)])]) + (FV-tschema tschema) + (list FV-ref FV-bang)))) + +; ====================================================================== + +(define (primitive->atprim name orig-type-schema . attrs) + ;;(pretty-debug `(primitive->atprim ,name)) + (match-let* + ( [type-schema (expand-input-type orig-type-schema)] + [type (match type-schema + [('forall _ type) type] + [type type])]) + + (make-atprim + name + type-schema + + ;; Calculate filter-domains + (match type + [('lambda domain _) + ;; Now walk domain and args + (recur loop ([domain domain]) + (match domain + [('cons domain d-rest) + (cons + (let ([templates (type->templates domain)]) + (if templates + (create-filter #t templates) + #f)) + (loop d-rest))] + [_ '()]))] + [_ '()]) + + ;; Calculate predicate-fn + (foldl + (lambda (attr predicate-fn) + (let* + ([mk-predicate-fn + (lambda (filter-then filter-else) + (lambda (b a Tvar sign) + '(printf "mk-predicate-fn ~s ~s ~s ~s ~s ~s~n" + filter-then filter-else b a Tvar sign) + (let ([filter (if sign filter-then filter-else)]) + (if filter + (let ([nu-Tvar (mk-Tvar 'filter)]) + (new-con! Tvar + (create-con-filter filter + nu-Tvar)) + nu-Tvar) + Tvar))))] + [get-templates + (lambda (C*) + (map + (lambda (C) + (or (lookup-template C) + (mrspidey:error + (format "Unknown constructor ~s in primitive def" C)))) + C*))] + [nu-fn + (match attr + [('predicate-fn exp) exp] + [('predicate . C*) + (let ([templates (get-templates C*)]) + (mk-predicate-fn (create-filter #t templates) + (create-filter #f templates)))] + [('predicate* true-info false-info) + (apply + mk-predicate-fn + (map + (match-lambda + ['_ #f] + [(bool . C*) + (let ([templates (get-templates C*)]) + (create-filter bool templates))] + [_ (error 'predicate* "Bad syntax")]) + (list true-info false-info)))] + [_ #f])]) + (if nu-fn + ;; compose + (lambda (b a Tvar sign) + (nu-fn b a + (predicate-fn b a Tvar sign) + sign)) + predicate-fn))) + (lambda (b a Tvar bool) Tvar) + attrs) + + attrs + orig-type-schema))) + +; ====================================================================== + + diff --git a/collects/mrspidey/Sba/za.ss b/collects/mrspidey/Sba/za.ss new file mode 100644 index 0000000..16dc174 --- /dev/null +++ b/collects/mrspidey/Sba/za.ss @@ -0,0 +1,328 @@ +;; za.ss +;; Reads and writes .za files +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +;; ====================================================================== +;; za handling stuff +;; ====================================================================== + +;; ---------------------------------------------------------------------- +;; read-unit-za +;; Returns (values ftype tref-env tdef-env tbang-env) + +(define (read-za za) + (let*-vals + ([(Tvar envs lookup-Tvar) (read-constraint-set za)] + [cvt-env (match-lambda + [(sym num) (cons sym (lookup-Tvar num))])]) + (match envs + [('ftype sexp + 'tref-env tref-env + 'tdef-env tdef-env + 'tbang-env tbang-env) + (values + (recur sexp->ftype ([sexp sexp]) + ;;(pretty-print `(sexp->ftype ,sexp)) + (match sexp + [(? number? n) (lookup-Tvar n)] + [('schema n n*) + (create-fo-FlowType + (make-schema (lookup-Tvar n) + (map lookup-Tvar n*) + '()))] + [('atunit imports exports result) + (create-fo-FlowType + (make-atunit (map (match-lambda + [(sym . n*) + (cons sym (map lookup-Tvar n*))]) + imports) + (map (match-lambda + [(sym sexp) + (cons sym (sexp->ftype sexp))]) + exports) + (sexp->ftype result) + #f))] + [('atstruct A B C D E F) + (create-fo-FlowType (make-atstruct A B C D E F))] + [('prim sym type attrs) + (create-fo-FlowType (apply primitive->atprim sym type attrs))] + [x (mrspidey:internal-error 'read-za + "Bad ftype-sexp in za: ~s" x)])) + (map cvt-env tref-env) + (map cvt-env tdef-env) + (map cvt-env tbang-env))]))) + +;; ---------------------------------------------------------------------- +;; write-za + +(define (write-za za tvar-live ftype tref-env tdef-env tbang-env) + (write-constraint-set + za tvar-live + (lambda (Tvar->nu-num) + (let ([cvt-env + (match-lambda + [(sym . tvar) (list sym (Tvar->nu-num tvar))])]) + (list + 'ftype + (recur ftype->sexp ([ftype ftype]) + (pretty-debug-unit `(ftype->sexp ,(FlowType->pretty ftype))) + (if (Tvar? ftype) + (Tvar->nu-num ftype) + (match (fo-FlowType-def ftype) + [($ schema tvar tvar* '()) + (list 'schema + (Tvar->nu-num tvar) + (map Tvar->nu-num tvar*))] + [($ atunit imports exports result exp) + (list 'atunit + (map (match-lambda + [(sym . tvar*) + (cons sym (map Tvar->nu-num tvar*))]) + imports) + (map (match-lambda + [(sym . ftype) + (list sym (ftype->sexp ftype))]) + exports) + (ftype->sexp result))] + [($ atstruct A B C D E F) `(atstruct ,A ,B ,C ,D ,E ,F)] + [($ atprim sym type _ _ attrs orig-type-schema) + (list 'prim sym orig-type-schema attrs)] + [x (mrspidey:internal-error 'ftype->sexp "Bad Atype ~s" x)]))) + + 'tref-env (map cvt-env tref-env) + 'tdef-env (map cvt-env tdef-env) + 'tbang-env (map cvt-env tbang-env)))))) + +;; ====================================================================== + +(define (write-constraint-set file Tvar-live mk-envs) + + (with-handlers + ([void + (lambda (exn) + (when (file-exists? file) (delete-file file)) + (raise exn))]) + + (let*-vals + ( [s (format "Saving ~a" (file-name-from-path file))] + [_ (mrspidey:progress s '...)] + [_ (when (file-exists? file) (delete-file file))] + [p (open-output-file file 'text)] + [disp (lambda (x) (write x p) (newline p))] + [num-Tvar-live (length Tvar-live)] + [(get-Tvar-ndx set-Tvar-ndx!) (alloc-Tvar-field)] + [Tvar-ndx + (lambda (tvar) + (let ([ndx (get-Tvar-ndx tvar)]) + '(unless (number? ndx) + (error 'write-constraint-set::Tvar-ndx + "Tvar ~s not live ~s" + (Tvar-name tvar) (map Tvar-name Tvar-live))) + ndx))] + [(AV-ndx set-AV-ndx!) (alloc-AV-field)] + [num-nu-AV 0]) + + ;; --- assign number to each live Tvar + (for-each-with-n + (lambda (Tvar n) + (assert (eq? (Tvar-ndx Tvar) #f)) + (set-Tvar-ndx! Tvar n)) + Tvar-live) + + ;; --- write version + (disp `(st:version ,(st:version))) + + ;; --- write configuration + (pretty-print (mrspidey:control-fn) p) + + ;; --- write num Tvars + (disp `(num-Tvar ,num-Tvar-live)) + + ;; --- write constructor-env + (disp `START-constructor-env) + (hash-table-for-each + constructor-env + (lambda (sym template) + (unless + (hash-table-get saved-constructor-env sym (lambda () #f)) + (match template + [($ template type n+ n- ref assign super-templates) + (disp (list type n+ n- ref assign + (map template-type super-templates)))])))) + ;; reverse it so defns in file occur before references ??? + (disp 'END-constructor-env) + + ;; --- write AV + (disp `START-AV) + (for-each + (lambda (Tvar) + ;;(pretty-print (Tvar-name Tvar)) + (for-each + (match-lambda + [(and AV ($ AV num ($ template type) misc fields+ fields-)) + (unless (AV-ndx AV) + (set-AV-ndx! AV num-nu-AV) + (set! num-nu-AV (add1 num-nu-AV)) + (disp (list type + (if (or (number? misc) (char? misc) (symbol? misc) + (pair? misc)) + misc + '()) + (map Tvar-ndx (vector->list fields+)) + (map Tvar-ndx (vector->list fields-)))))]) + (Tvar-objs Tvar))) + Tvar-live) + (disp 'END-AV) + + ;; --- write Tvar + (disp 'START-Tvar) + (for-each + (lambda (Tvar) + (disp + (append (map AV-ndx (Tvar-objs Tvar)) + (map + (match-lambda + [($ con _ ($ template type) field-no Tvar sign) + (list type field-no (Tvar-ndx Tvar) sign)] + [($ con-filter _ ($ filter sign (($ template types) ...)) + Tvar) + (list sign types (Tvar-ndx Tvar))]) + (Tvar-constraints Tvar)) + (let ([edgeto (Tvar-edgeto Tvar)]) + (if (null? edgeto) + '() + (cons 'T (map Tvar-ndx edgeto))))))) + Tvar-live) + (disp 'END-Tvar) + + ;; --- write in-env, out-env + (let ([rep-envs (mk-envs Tvar-ndx)]) + (pretty-print `(envs ,@rep-envs) p) + ;; --- all done + (close-output-port p)) + (mrspidey:progress s 'done)))) + +;; ---------------------------------------------------------------------- + +(define (read-constraint-set file) + (match-let* + ([p (open-input-file file 'text)] + [('st:version save-st:version) (read p)] + [configuration (read p)] + [('num-Tvar save-num-Tvar) (read p)] + [vec-Tvar (make-vector save-num-Tvar #f)] + [vec-AV (void)] + [lookup-Tvar + (lambda (n) + (if (number? n) + (vector-ref vec-Tvar n) + (let ([Tvar (mk-Tvar 'load-empty)]) + Tvar)))] + [lookup-AV + (lambda (n) + (let ([AV (vector-ref vec-AV n)]) + (assert (AV? AV) 'lookup-AV) + AV))]) + + (unless (equal? save-st:version (st:version)) + (mrspidey:error ".za file from previous MrSpidey release")) + + (for i 0 save-num-Tvar (vector-set! vec-Tvar i (mk-Tvar 'load))) + + ;; --- constructors + + (match (read p) ['START-constructor-env (void)]) + (recur loop () + (match (read p) + [(type n+ n- ref assign super) + (let ([t (make-template type n+ n- ref assign '() eqv?)]) + (for-each + (lambda (s) (record-super-constructor-of-template! s t)) + (reverse super)) + (extend-constructor-env! t) + (loop))] + ['END-constructor-env (void)])) + + ;; --- AV's + + (match (read p) ['START-AV (void)]) + (set! vec-AV + (list->vector + (recur loop () + (match (read p) + [(C misc tvar-num+* tvar-num-*) + (cons + (create-AV (lookup-template C) + misc + (list->vector (map lookup-Tvar tvar-num+*)) + (list->vector (map lookup-Tvar tvar-num-*))) + (loop))] + ['END-AV '()])))) + + ;; --- Tvar's + + (match (read p) ['START-Tvar (void)]) + (let ([new-AV! add-AV!] + [new-con! add-con!] + [new-edge! add-edge!]) + (recur loop ([n 0]) + (match (read p) + ['END-Tvar (void)] + [in + (let ([Tvar (lookup-Tvar n)]) + (recur loop2 ([in in]) + (match in + [() (void)] + [((? integer? n) . rest) + (new-AV! Tvar (lookup-AV n)) + (loop2 rest)] + [(((? boolean? sign) C* tvar-num) . rest) + (new-con! + Tvar + (create-con-filter + (create-filter sign (map lookup-template C*)) + (lookup-Tvar tvar-num))) + (loop2 rest)] + [((C n tvar-num sign) . rest) + (new-con! + Tvar + (create-con + (lookup-template C) n + (lookup-Tvar tvar-num) sign)) + (loop2 rest)] + [('T . edgeto*) + (for-each + (lambda (tvar-num) + (new-edge! Tvar (lookup-Tvar tvar-num))) + edgeto*)]))) + (loop (add1 n))]))) + + ;; --- in-env and out-env + + (match-let* + ([('envs . envs) (read p)]) + + (close-input-port p) + + (values + (vector->list vec-Tvar) + envs + lookup-Tvar)))) + +;; ---------------------------------------------------------------------- + diff --git a/collects/mrspidey/Sba/zod-aux.ss b/collects/mrspidey/Sba/zod-aux.ss new file mode 100644 index 0000000..423176d --- /dev/null +++ b/collects/mrspidey/Sba/zod-aux.ss @@ -0,0 +1,622 @@ +; zodiac-aux.ss +; Helper functions for zodiac structures +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +; ---------------------------------------------------------------------- + +(define compat + (lambda (fn) + (letrec + ([cl-fn + (lambda (exp) + ;;(pretty-print-debug `(compat ,(stripper exp))) + (let ([r (fn exp cl-fn)]) + (if r + r + (match exp + [($ zodiac:if-form o s f b test then else) + (zodiac:make-if-form o s f b + (cl-fn test) (cl-fn then) (cl-fn else))] + ;;[($ zodiac:lambda-form o s f b args body) + ;; (let* ([args (map-ilist cl-fn args)]) + ;; (zodiac:make-lambda-form o s f b args (cl-fn body)))] + + [($ zodiac:case-lambda-form o s f b arglists bodies) + (zodiac:make-case-lambda-form + o s f b + (map cl-fn arglists) + (map cl-fn bodies))] + [($ zodiac:arglist vars) + (zodiac:make-arglist (map cl-fn vars))] + [($ zodiac:set!-form o s f b var val) + (zodiac:make-set!-form o s f b (cl-fn var) (cl-fn val))] + [($ zodiac:begin-form o s f b bodies) + (zodiac:make-begin-form o s f b (map cl-fn bodies))] + [($ zodiac:let-values-form o s f b varss vals body) + (let ([varss (map (lambda (vars) (map cl-fn vars)) + varss)]) + (zodiac:make-let-values-form + o s f b + varss (map cl-fn vals) (cl-fn body)))] + [($ zodiac:letrec*-values-form o s f b varss vals body) + (let ([varss (map (lambda (vars) (map cl-fn vars)) + varss)]) + (zodiac:make-letrec*-values-form + o s f b + varss (map cl-fn vals) (cl-fn body)))] + [($ zodiac:define-values-form o s f b vars value) + (zodiac:make-define-values-form o s f b + (map cl-fn vars) + (cl-fn value))] + [($ zodiac:poly-form o s f b exp) + (zodiac:make-poly-form o s f b (cl-fn exp))] + + [($ zodiac:app o s f b fun args) + (zodiac:make-app o s f b + (cl-fn fun) (map cl-fn args))] + ;;[($ zodiac:delay-form o s f b expr) + ;; (zodiac:make-delay-form o s f b (cl-fn expr))] + + [($ zodiac::-form o s f b exp type) + (zodiac:make-:-form o s f b (cl-fn exp) type)] + + [($ zodiac:type:-form o s f b type attrs) + exp] + + [($ zodiac:unit-form o s f b imports exports body) + (zodiac:make-unit-form o s f b + (map cl-fn imports) + (map + (match-lambda + [(varref . sym) + (cons (cl-fn varref) sym)]) + exports) + (map cl-fn body))] + [($ zodiac:compound-unit-form o s f b + imports links exports) + ;;(pretty-print-debug `compound-unit) + (zodiac:make-compound-unit-form + o s f b + (map cl-fn imports) + (map (match-lambda + [(tag exp . imports) + ;;(pretty-print-debug `compound-unit-link) + (list* + tag + (cl-fn exp) + (map + (lambda (import) + (if (zodiac:lexical-varref? import) + (cl-fn import) + import)) + imports))]) + links) + exports)] + [($ zodiac:reference-unit-form o s f b file kind signed?) + (zodiac:make-reference-unit-form o s f b + file kind signed?)] + + [($ zodiac:invoke-unit-form o s f b exp vars) + (zodiac:make-invoke-unit-form + o s f b + (cl-fn exp) (map cl-fn vars))] + + ;; ---------- objects! ---------- + [($ zodiac:class*/names-form o s f b + this super-init super-expr interfaces init-vars + inst-clauses) + (zodiac:make-class*/names-form o s f b + (cl-fn this) + (cl-fn super-init) + (cl-fn super-expr) + interfaces + (cl-fn init-vars) + (map cl-fn inst-clauses))] + [($ zodiac:public-clause exports internals exprs) + (zodiac:make-public-clause + exports + (map cl-fn internals) + (map cl-fn exprs))] + [($ zodiac:private-clause internals exprs) + (zodiac:make-private-clause + (map cl-fn internals) + (map cl-fn exprs))] + [($ zodiac:inherit-clause internals imports) + (zodiac:make-inherit-clause + (map cl-fn internals) imports)] + [($ zodiac:rename-clause internals inheriteds) + (zodiac:make-rename-clause + (map cl-fn internals) + (map cl-fn inheriteds))] + [($ zodiac:sequence-clause exprs) + (zodiac:make-sequence-clause (map cl-fn exprs))] + + ;; ---------- sexps ---------- + [($ zodiac:list o s f l len marks) + (zodiac:make-list o s f (map cl-fn l) len marks)] + + [_ exp]))))]) + cl-fn))) + +(define compat* + (lambda (fn) + (let ([cl-fn (compat fn)]) + (lambda (exp*) (map cl-fn exp*))))) + +; ---------------------------------------------------------------------- + +(define (ast-size defs) + (let* ([size 0] + [fn (lambda (x f) + (set! size + (+ size + (match x + [($ zodiac:quote-form 0 s f b expr) + (const-size expr)] + [_ 1]))) + #f)]) + ((compat* fn) defs) + size)) + +; ---------------------------------------------------------------------- +;; const-size +;; Gives the size of a zodiac constant + +(define const-size + (match-lambda + [(a . d) (+ 1 (const-size a) (const-size d))] + [(or ($ zodiac:list _ _ _ l) ($ zodiac:improper-list _ _ _ l)) + (const-size l)] + [(or (? vector? v) ($ zodiac:vector _ _ _ v)) + (+ 1 (apply + (map const-size v)))] + [else 1])) + +; ---------------------------------------------------------------------- + +(define unparse-dynamic-letd + (lambda (fn) + (letrec + ([cl-fn + (lambda (exp) + (let ([r (fn exp cl-fn)]) + (if r + r + (match exp + [($ zodiac:varref _ _ _ _ sym) sym] + [($ zodiac:binding _ _ _ _ sym) sym] + [($ zodiac:if-form _ _ _ _ test then else) + `(if ,(cl-fn test) ,(cl-fn then) ,(cl-fn else))] + ;;[($ zodiac:lambda-form _ _ _ _ args body) + ;; (let* ([args (map-ilist cl-fn args)]) + ;; `(lambda ,args ,(cl-fn body)))] + [($ zodiac:case-lambda-form _ _ _ _ arglists bodies) + `(case-lambda + ,@(map + (lambda (arglist body) + (list (cl-fn arglist) (cl-fn body))) + arglists bodies))] + [($ zodiac:sym-arglist (var)) (cl-fn var)] + [($ zodiac:list-arglist vars) (map cl-fn vars)] + [($ zodiac:ilist-arglist vars) + (cons (map cl-fn (rdc vars)) (cl-fn (rac vars)))] + [($ zodiac:set!-form _ _ _ _ var val) + `(set! ,(cl-fn var) ,(cl-fn val))] + [($ zodiac:begin-form _ _ _ _ bodies) + `(begin ,@(map cl-fn bodies))] + [($ zodiac:let-values-form _ _ _ _ varss vals body) + (let ([varss (map (lambda (vars) (map cl-fn vars)) + varss)]) + `(let-values ,(map list varss (map cl-fn vals)) + ,(cl-fn body)))] + [($ zodiac:letrec*-values-form _ _ _ _ varss vals body) + (let ([varss (map (lambda (vars) (map cl-fn vars)) + varss)]) + `(letrec*-values ,(map list varss (map cl-fn vals)) + ,(cl-fn body)))] + [($ zodiac:define-values-form _ _ _ _ vars value) + `(define-values ,(map cl-fn vars) ,(cl-fn value))] + [($ zodiac:poly-form _ _ _ _ exp) + `(poly ,(cl-fn exp))] + [($ zodiac:app _ _ _ _ fun args) + `(,(cl-fn fun) ,@(map cl-fn args))] + [($ zodiac:quote-form _ _ _ _ expr) + (list 'quote (cl-fn expr))] + [($ zodiac::-form _ _ _ _ exp type) + (list ': (cl-fn exp) type)] + [($ zodiac:st:control-form o s f b para val) + (list 'st:control para val)] + + ;; [($ zodiac:unchanged _ _ _ _ expr) (cl-fn expr)] + [($ zodiac:unit-form o s f b imports exports body) + `(unit (import ,@(map cl-fn imports)) + (export + ,@(map (match-lambda + [(i . e) (list (cl-fn i) (zodiac:read-object e))]) + exports)) + ,@(map cl-fn body))] + [($ zodiac:compound-unit-form _ _ _ _ + imports links exports) + `(compound-unit + (import ,@(map cl-fn imports)) + (link + ,@(map + (match-lambda + [(tag exp . imports) + (list tag + (cons + (cl-fn exp) + (map (match-lambda + [(tag . sym) (list tag sym)] + [(? zodiac:varref? lvr) + (zodiac:varref-var lvr)]) + imports)))]) + links)) + (export ,@(map + (match-lambda + [(tag i . e) (list tag (list i e))]) + exports)))] + [($ zodiac:invoke-unit-form _ _ _ _ exp) + `(invoke-unit ,(cl-fn exp))] + [($ zodiac:reference-unit-form _ _ _ _ file kind signed?) + (list + (if signed? + 'reference-unit + 'reference-unit/sig) + file)] + [($ zodiac:struct-form _ _ _ _ + ($ zodiac:symbol _ _ _ tag) + parent + (($ zodiac:symbol _ _ _ fields) ...)) + `(struct + ,(if parent (list tag (cl-fn parent)) tag) + ,fields)] + [($ zodiac:string _ _ _ text) text] + [($ zodiac:boolean _ _ _ text) text] + [($ zodiac:char _ _ _ text) text] + [($ zodiac:symbol _ _ _ text) text] + [($ zodiac:number _ _ _ text) text] + [($ zodiac:list _ _ _ contents) + (map cl-fn contents)] + [($ zodiac:improper-list _ _ _ contents) + (map-ilist cl-fn contents)] + [($ zodiac:vector _ _ _ contents) + (list->vector (map cl-fn contents))] + [($ zodiac:define-type-form _ _ _ _ sym type) + `(define-type ,sym ,type)] + [($ zodiac:define-constructor-form _ _ _ _ sym modes) + `(define-constructor ,sym ,@modes)] + [x x] + ;;[_ (error 'unparse "Bad exp ~s" exp)] + ))))]) + cl-fn))) + +'(define (stripper exp) + ((unparse-dynamic-letd (lambda (x cl-fn) #f)) + exp)) + +(define (stripper exp) + (if (zodiac:parsed? exp) + (zodiac:parsed->raw exp) + 'stripper:not-a-parsed)) + +; ====================================================================== +;; Routines to add fields to each zodiac structure +;; mutated and refs fields are only for binding structures + +(define (myzodiac:register-client name init-fn) + (let*-vals + ([(getter setter) (zodiac:register-client name init-fn)]) + (values + (lambda (parsed) (getter (zodiac:parsed-back parsed))) + (lambda (parsed val) (setter (zodiac:parsed-back parsed) val))))) + +(define-values + (parsed-ftype set-parsed-ftype!) + (myzodiac:register-client 'ftype (lambda () #f))) + +(define-values + (parsed-check set-parsed-check!) + (myzodiac:register-client 'check (lambda () #f))) + +(define-values + (parsed-atprim set-parsed-atprim!) + (myzodiac:register-client 'atprim (lambda () #f))) + +(define-values + (app-tvar-args set-app-tvar-args!) + (myzodiac:register-client 'app-args (lambda () #f))) + +(define-values + (binding-refs set-binding-refs!) + (myzodiac:register-client 'refs (lambda () 0))) + +(define-values + (binding-mutated set-binding-mutated!) + (myzodiac:register-client 'mutated (lambda () #f))) + +;;(trace binding-mutated) +;;(trace set-binding-mutated!) + +;; ---------------------------------------------------------------------- +;; Info on varrefs + +(define (get-top-level-varref-binding x) + (let* ( [b (zodiac:top-level-varref/bind-slot x)] + [u (unbox b)]) + (if (zodiac:binding? u) + u + (let ([u (my-create-binding + (zodiac:varref-var x) + (zodiac:zodiac-start x) + (zodiac:zodiac-finish x))]) + (set-box! b u) + u)))) + +(define (varref-binding varref) + (match varref + [($ zodiac:bound-varref) (zodiac:bound-varref-binding varref)] + [($ zodiac:top-level-varref/bind) (get-top-level-varref-binding varref)] + [x (error 'varref-backinfo "Bad varref ~s" x)])) + +(define my-create-binding + (case-lambda + [(name) (my-create-binding name (no-location) (no-location))] + [(name open close) + (zodiac:make-binding + (zodiac:make-origin 'non-source 'spidey) + open close (zodiac:make-empty-back-box) name name)])) + +;; ---------------------------------------------------------------------- + +(define lambda-flatten-arglist + (match-lambda + [($ zodiac:list _ _ _ l) l] + [($ zodiac:improper-list _ _ _ l x) (append l (list x))] + [(? zodiac:binding? b) (list b)] + [() '()] + [(a . b) (cons a (lambda-flatten-arglist b))])) + +; ---------------------------------------------------------------------- + +(define (no-location) (zodiac:make-location 0 0 0 "no-file")) + +(define (location-inc loc) + (zodiac:make-location + 0 0 + (add1 (zodiac:location-offset loc)) + (zodiac:location-file loc))) + +(define determine-end-first-token + (lambda (object) + (cond + [(or (zodiac:scalar? object) + (zodiac:varref? object) + (zodiac:binding? object) + (and (zodiac:quote-form? object) + (or + (zodiac:boolean? (zodiac:quote-form-expr object)) + (zodiac:char? (zodiac:quote-form-expr object)) + (zodiac:symbol? (zodiac:quote-form-expr object)) + (zodiac:number? (zodiac:quote-form-expr object))))) + (location-inc (zodiac:zodiac-finish object))] + [(or (zodiac:sequence? object) + (zodiac:parsed? object) + (zodiac:app? object)) + (location-inc (zodiac:zodiac-start object))] + [else (error 'zodiac:determine-end-first-token + "shouldn't be here ~s" object)]))) + +; ---------------------------------------------------------------------- + +(define parsed-value? + (match-lambda + [(or + ($ zodiac:quote-form) + ;;($ zodiac:lambda-form) + ($ zodiac:case-lambda-form) + ($ zodiac:lexical-varref)) #t] + [($ zodiac:letrec*-values-form + _ _ _ _ vars + ((? parsed-value?) ...) + (? parsed-value?)) #t] + [_ #t])) + +; ---------------------------------------------------------------------- + +(define free-refs + (lambda (exp bindings) + (let* ( [hash-bindings (make-hash-table)] + [_ (for-each + (lambda (bind) (hash-table-put! hash-bindings bind #t)) + bindings)] + [refs '()] + [fn + (lambda (exp cl-fn) + (match exp + [($ zodiac:varref) + (let ([bind (varref-binding exp)]) + (when + (hash-table-get hash-bindings bind (lambda () #f)) + (set! refs (cons bind refs)))) + #f] + [($ zodiac:unit-form) 'do-not-traverse] + [_ #f]))]) + ((compat fn) exp) + refs))) + +(define (free-vars exp bindings) (list->set (free-refs exp bindings))) + +;; ---------------------------------------------------------------------- + +(define (initialize-mutated defs) + (let* (;; set binding of mutated variables + [_ (for-each + (match-lambda + [($ zodiac:define-values-form _ _ _ _ varrefs expr) + (match expr + ;; kludge - don't consider define-struct variables + ;; to be mutable + [($ zodiac:struct-form) (void)] + [_ + (for-each + (lambda (varref) + (set-binding-mutated! + (get-top-level-varref-binding varref) + #t)) + varrefs)])] + [_ (void)]) + defs)] + [free '()] + [fn + (lambda (def cl-fn) + ;;(display `(initialize-mutated ,(stripper def))) (newline) + (match def + [($ zodiac:letrec*-values-form _ _ _ _ varss) + (for-each + (lambda (vars) + (for-each + (lambda (var) (set-binding-mutated! var #t)) + vars)) + varss) + #f] + [($ zodiac:set!-form _ _ _ _ var) + ;;(display `(initialize-mutated! ,(stripper var))) (newline) + (set-binding-mutated! (varref-binding var) #t) + #f] + [_ #f]))]) + ((compat* fn) defs) + free)) + +(define (free-vars-defs defs) + (let* ( ;; Put binding on slot field of variables that are defined + ;; and set to mutated + [_ (for-each + (match-lambda + [($ zodiac:define-values-form _ _ _ _ varrefs expr) + (match expr + ;; kludge - don't consider define-struct variables + ;; to be mutable + [($ zodiac:struct-form) + (for-each + (lambda (varref) + (get-top-level-varref-binding varref)) + varrefs)] + [_ + (for-each + (lambda (varref) + (set-binding-mutated! + (get-top-level-varref-binding varref) + #t)) + varrefs)])] + [_ (void)]) + defs)] + [free '()] + [fn + (lambda (def cl-fn) + ;;(pretty-debug `(get-tlvr ,(stripper def))) + (match def + [($ zodiac:top-level-varref/bind) + (when + (not + (zodiac:binding? + (unbox (zodiac:top-level-varref/bind-slot def)))) + (set! free + (cons (get-top-level-varref-binding def) free))) + #f] + [($ zodiac:unit-form) 'do-not-traverse] + [($ zodiac:letrec*-values-form _ _ _ _ varss) + (for-each + (lambda (vars) + (for-each + (lambda (var) (set-binding-mutated! var #t)) + vars)) + varss) + #f] + ;; struct-ref in function posn is not a free variable + [($ zodiac:app _ _ _ _ + ($ zodiac:top-level-varref/bind _ _ _ _ 'struct-ref) + args) + (for-each cl-fn args) + #t] + [_ #f]))]) + ((compat* fn) defs) + free)) + +;; ---------------------------------------------------------------------- + +(define (zero! p) + '(let-macro + zerostruct + (lambda (name . fields) + `(begin + ;;(display ',(symbol-append 'zodiac: name)) + (when (,(symbol-append 'zodiac: name '?) p) + ,@(map + (lambda (field) + `(begin + ;;(display ',(symbol-append 'zodiac: name '- field)) + (zero! + (begin0 + (,(symbol-append 'zodiac: name '- field) p) + (,(symbol-append 'zodiac:set- name '- field '!) p 'zro))))) + fields)))) + + (zerostruct parsed back) + (zerostruct app fun args) + (zerostruct varref var) + (zerostruct bound-varref binding) + (zerostruct binding var orig-name) + (zerostruct top-level-varref/bind slot) + (zerostruct arglist vars) + (zerostruct paroptarglist vars) + (zerostruct set!-form var val) + (zerostruct begin-form bodies) + (zerostruct begin0-form bodies) + (zerostruct define-values-form vars val) + (zerostruct let-values-form vars vals body) + (zerostruct letrec*-values-form vars vals body) + (zerostruct if-form test then else) + (zerostruct quote-form expr) + (zerostruct case-lambda-form args bodies) + (zerostruct struct-form type super fields) + (zerostruct unit-form imports exports clauses) + (zerostruct compound-unit-form imports links exports) + (zerostruct invoke-unit-form unit variables) + (zerostruct invoke-open-unit-form unit name-specifier variables) + (zerostruct class*-form this super-names super-exprs init-vars inst-clauses) + (zerostruct public-clause exports internals exprs) + (zerostruct private-clause internals exprs) + (zerostruct inherit-clause internals imports) + (zerostruct rename-clause internals imports) + (zerostruct sequence-clause exprs) + (when (pair? p) + (zero! (begin0 (car p) (set-car! p 'zro))) + (zero! (begin0 (cdr p) (set-cdr! p 'zro)))) + + )) + +;; ---------------------------------------------------------------------- + +(define (inline-begins defs) + (recur loop ([defs defs]) + (match defs + [() '()] + [(($ zodiac:begin-form _ _ _ _ bodies) . rest) + (append (loop bodies) (loop rest))] + [(def . rest) + (cons def (loop rest))]))) + diff --git a/collects/mrspidey/Sba/zod-extra.ss b/collects/mrspidey/Sba/zod-extra.ss new file mode 100644 index 0000000..abd7286 --- /dev/null +++ b/collects/mrspidey/Sba/zod-extra.ss @@ -0,0 +1,75 @@ +; zod-extra.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(define mrspidey:zodiac:parameters@ + (unit/sig plt:parameters^ + (import) + (define case-sensitive? #t) + (define unmatched-cond/case-is-error? #t) + (define allow-set!-on-undefined? #t) + (define allow-improper-lists? #t) + (define check-syntax-level 'advanced) + ;(define allow-internal-defines? #f) + )) + +(define mrspidey:zodiac:interface@ + (unit/sig zodiac:interface^ + (import mrspidey:interaction^) + (define default-error-handler + (lambda (keyword) + (lambda (where fmt-spec . args) + (apply mrspidey:internal-error + keyword fmt-spec args)))) + (define internal-error + (lambda (where fmt-spec . args) + (let ([msg + (parameterize ([print-struct #t]) + (string-append "Syntax error: " + (apply format fmt-spec args)))]) + (if #t ;(zodiac:zodiac? where) + (mrspidey:error msg where) + (mrspidey:error msg))))) + (define static-error + (lambda (where fmt-spec . args) + (let ([msg + (parameterize ([print-struct #t]) + (string-append "Syntax error: " + (apply format fmt-spec args)))]) + (if #t ;(zodiac:zodiac? where) + (mrspidey:error msg where) + (mrspidey:error msg))))) + (define dynamic-error + (default-error-handler 'zodiac-run-time)))) + +;; ---------------------------------------------------------------------- + +(define mrspidey:zodiac-aux@ + (unit/sig + mrspidey:zodiac-aux^ + (import + mrspidey:CDL^ + (zodiac : zodiac:system^)) + (include "zod-aux.ss"))) + +;; ---------------------------------------------------------------------- + +(load-relative "zod-link.ss") + + + + diff --git a/collects/mrspidey/Sba/zod-link.ss b/collects/mrspidey/Sba/zod-link.ss new file mode 100644 index 0000000..714c3ef --- /dev/null +++ b/collects/mrspidey/Sba/zod-link.ss @@ -0,0 +1,22 @@ +;; zod-link.ss + +(define mrspidey:zodiac@;; mrspidey:zodiac^ + (compound-unit/sig + (import + (CDL : mrspidey:CDL^) + (INTERACTION : mrspidey:interaction^)) + (link + [PARAMETERS : + plt:parameters^ + (mrspidey:zodiac:parameters@)] + [INTERFACE : + zodiac:interface^ + (mrspidey:zodiac:interface@ INTERACTION)] + [Z : + zodiac:system^ + (zodiac:system@ INTERFACE PARAMETERS (CORE pretty-print@) (CORE file@))] + [CORE : + mzlib:core^ + ((reference-library-unit/sig "corer.ss"))] + [AUX : mrspidey:zodiac-aux^ (mrspidey:zodiac-aux@ CDL Z)]) + (export (open Z) (open AUX)))) diff --git a/collects/mrspidey/about.html b/collects/mrspidey/about.html new file mode 100644 index 0000000..869fb09 --- /dev/null +++ b/collects/mrspidey/about.html @@ -0,0 +1,36 @@ + + +About MrSpidey + + + +

+[logo] +MrSpidey

+

+MrSpidey version 49s1, Copyright (C) 1995-97 Cormac Flanagan +

+MrSpidey is an interactive, graphical static debugger for Scheme. For more information, visit the + MrSpidey home page +

+Thanks to Matthew Flatt and Robby Findler for MrEd, and to Shriram +Krishnamurthi for his source-correlating macro-expander. Thanks also +to Stephanie Weirich for work on the first implementation of MrSpidey, +and to Matthias Felleisen and Corky Cartwright for their feedback and +help. +

+This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +version 2 as published by the Free Software Foundation. +

+This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +

+You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + + diff --git a/collects/mrspidey/drspidey.ss b/collects/mrspidey/drspidey.ss new file mode 100644 index 0000000..b587576 --- /dev/null +++ b/collects/mrspidey/drspidey.ss @@ -0,0 +1,166 @@ +;; drspidey.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +;; The code to be loaded from DrScheme + +;;(printf "loading drspidey.ss (cd ~s)~n" (current-directory)) + +(reference "pltrc-co.ss") +(reference "macros.ss") + +(begin-elaboration-time + (unless (getenv "MREDCOMPILE") + (match:set-error-control 'match))) + + +#| MATTHEW: use require-library instead +(load/use-compiled + (let ([p (build-path (current-load-relative-directory) "Zodiac" "load.ss")]) + (if (file-exists? p) + p + (build-path (current-load-relative-directory) 'up "zodiac" "load.ss")))) +|# +(require-library "load.ss" "zodiac") + +(load/use-compiled (build-path "Sba" "loadu.ss")) +(load/use-compiled (build-path "Gui" "loadu.ss")) + +(define mrspidey:interaction@ + (unit/sig mrspidey:interaction^ + (import + [mred : mred^] + [zodiac : mrspidey:zodiac^] + mzlib:unprefixed-core^) + (include "handlers.ss") + + (mrspidey:error-handler + (case-lambda + [(message object) + (unless (zodiac:zodiac? object) + (printf "Bad object in mrspidey:error-handler ~s~n" object) + ((mrspidey:error-handler) message)) + (let* ([loc (zodiac:zodiac-start object)]) + (unless (zodiac:location? loc) + (printf "Bad location in mrspidey:error-handler ~s~n" loc) + ((mrspidey:error-handler) message)) + ((mrspidey:error-handler) + (format "~a at ~s line ~s, column ~s~n" + message + (file-name-from-path (zodiac:location-file loc)) + (zodiac:location-line loc) + (zodiac:location-column loc))))] + [(message) + (mred:message-box + (format "~a~n" message) + "MrSpidey Error") + (raise 'mrspidey-raise)])) + )) + +;; ---------------------------------------------------------------------- + +(define mrspidey-tool@ + (unit/sig () + (import + [mred : mred^] + mrspidey-gui^ + mzlib:unprefixed-core^) + (mred:add-version-spec 'sd 1) + (lambda (frame) + (let* ( [edit (ivar frame definitions-edit)] + [name (send edit get-filename)]) + (if (string? name) + (when + (or (not (send edit modified?)) + (let ([action (mred:unsaved-warning name "Analyze" #t)]) + (case action + [(save) (send edit save-file)] + [(continue) #t] + [else #f]))) + (with-handlers + ([ (lambda (x) (eq? x 'mrspidey-raise)) + (lambda (x) (void))]) + (send spidey run-mrspidey (send edit get-filename)))) + (mred:message-box + "MrSpidey can only process programs that are saved to a file" + "MrSpidey Error")))))) + +;; ---------------------------------------------------------------------- + +(define tool@ + (let ( [mrspidey:sba@ mrspidey:sba@] + [mrspidey:interaction@ mrspidey:interaction@] + [mrspidey-gui@ mrspidey-gui@] + [mrspidey-tool@ mrspidey-tool@]) + (unit/sig () + (import + [WX : wx^] + [MRED : mred^] + [MZLIB : mzlib:core^] + [PCONVERT : mzlib:print-convert^] + [DRSCHEME : drscheme:export^] + [ZODiac : zodiac:system^]) + + (invoke-unit/sig + (unit->unit/sig + (unit/sig->unit + (unit/sig () + (import + mzlib:pretty-print^ + mzlib:file^ + mzlib:function^ + mzlib:compat^ + mzlib:string^) + (invoke-unit/sig + (unit->unit/sig + (unit/sig->unit + (compound-unit/sig + (import + [WX : wx^] + [MZLIB : mzlib:unprefixed-core^] + [MRED : mred^]) + (link + [INTERACTION : mrspidey:interaction^ + (mrspidey:interaction@ MRED (SBA zodiac) MZLIB)] + [SBA : mrspidey:sba^ + (mrspidey:sba@ INTERACTION MZLIB WX)] + [GUI : mrspidey-gui^ + (mrspidey-gui@ WX MRED MZLIB SBA INTERACTION)] + [TOOL : () + (mrspidey-tool@ MRED GUI MZLIB)]) + (export))) + (wx^ mzlib:unprefixed-core^ mred^) + () + ) + [WX : wx^] + mzlib:unprefixed-core^ + [MRED : mred^]))) + (((unit pretty-print@ : mzlib:pretty-print^)) + ((unit file@ : mzlib:file^)) + ((unit function@ : mzlib:function^)) + ((unit compat@ : mzlib:compat^)) + ((unit string@ : mzlib:string^))) + ()) + (MZLIB : ((unit pretty-print@ : mzlib:pretty-print^))) + (MZLIB : ((unit file@ : mzlib:file^))) + (MZLIB : ((unit function@ : mzlib:function^))) + (MZLIB : ((unit compat@ : mzlib:compat^))) + (MZLIB : ((unit string@ : mzlib:string^))))))) + +;;(printf "tool@ defined~n") + +;; ---------------------------------------------------------------------- diff --git a/collects/mrspidey/handlers.ss b/collects/mrspidey/handlers.ss new file mode 100644 index 0000000..4c38ad9 --- /dev/null +++ b/collects/mrspidey/handlers.ss @@ -0,0 +1,145 @@ +; handlers.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +;; (printf "Loading handlers.ss~n") + +(define mrspidey:error + (lambda args + (apply (mrspidey:error-handler) args))) + +(define mrspidey:error-handler + (make-parameter + (case-lambda + [(message object) + (unless (zodiac:zodiac? object) + (printf "Bad object in mrspidey:error-handler ~s~n" object) + ((mrspidey:error-handler) message)) + (let* ([loc (zodiac:zodiac-start object)]) + (unless (zodiac:location? loc) + (printf "Bad location in mrspidey:error-handler ~s~n" loc) + ((mrspidey:error-handler) message)) + (error 'MrSpidey "~a" + (format "~a at ~s line ~s, column ~s~n" + message + (file-name-from-path (zodiac:location-file loc)) + (zodiac:location-line loc) + (zodiac:location-column loc))))] + [(message) + (error 'MrSpidey "~a" (format "~a~n" message))]) + (lambda (x) x))) + +(define mrspidey:internal-error error) + +;; ---------------------------------------------------------------------- + +(define mrspidey:add-summary + (lambda line + ;; line is: + ;; str + ;; str loc word-no + (apply (mrspidey:add-summary-handler) line))) + +(define mrspidey:add-summary-handler + (make-parameter + (match-lambda* + [(str loc word-no) + (cond + [(zodiac:location? loc) + (printf "~a at line ~s, file ~s~n" + str + (zodiac:location-line loc) + (file-name-from-path (zodiac:location-file loc)))] + [(zodiac:zodiac? loc) + (mrspidey:add-summary str (zodiac:zodiac-start loc) word-no)] + [else + (printf "Bad location in mrspidey:add-summary-handler ~s~n" loc) + (mrspidey:add-summary str)])] + [(str . _) (printf "~a~n" str)]) + (lambda (x) x))) + +(define (mrspidey:warning . line) + (apply (mrspidey:warning-handler) line)) + +(define mrspidey:warning-handler + (make-parameter + (match-lambda* + [(str loc word-no) + (mrspidey:add-summary (format "Warning: ~a" str) loc (add1 word-no))] + [(str) + (mrspidey:add-summary (format "Warning: ~a" str))]) + (lambda (x) x))) + +;; ---------------------------------------------------------------------- + +(define mrspidey:progress + (lambda args + (apply (mrspidey:progress-handler) args))) + +(define default-mrspidey:progress-handler + (let ([current ()] + [fresh-line #t]) + (letrec + ([f (match-lambda* + [((? string? name) line) + (unless (equal? name current) + (f 'fresh-line) + (set! current name) + (mrspidey:progress-output name)) + (mrspidey:progress-output (format "[~s]" line)) + (flush-output) + (set! fresh-line #f)] + [((? string? str)) + (f 'fresh-line) + (mrspidey:progress-output str) + (f #\newline)] + [(#\newline) + (mrspidey:progress-output (format "~n")) + (set! fresh-line #t)] + [('fresh-line) + (unless fresh-line (f #\newline))])]) + f))) + +(define mrspidey:progress-handler + (make-parameter default-mrspidey:progress-handler (lambda (x) x))) + +;; ---------------------------------------------------------------------- +;; Don't really use the following flexibility, but might as well keep. + +(define (mrspidey:progress-output str) + ((mrspidey:progress-output-handler) str)) + +(define mrspidey:progress-output-handler + (make-parameter (lambda (str) (display str) (flush-output)) + (lambda (x) x))) + +;; ---------------------------------------------------------------------- + +(define record-analyzed-file-hook + (make-parameter + (lambda (filename . _) + (printf "Record-analyzed-file ~s~n" filename)) + (lambda (x) x))) + +(define (record-analyzed-file . args) + (apply (record-analyzed-file-hook) args)) + +;; ---------------------------------------------------------------------- + +;(trace mrspidey:warning) +;(trace mrspidey:error) +;(trace mrspidey:internal-error) diff --git a/collects/mrspidey/logo.gif b/collects/mrspidey/logo.gif new file mode 100644 index 0000000..36f82e0 Binary files /dev/null and b/collects/mrspidey/logo.gif differ diff --git a/collects/mrspidey/macros.ss b/collects/mrspidey/macros.ss new file mode 100644 index 0000000..ffb7564 --- /dev/null +++ b/collects/mrspidey/macros.ss @@ -0,0 +1,101 @@ +;; macros.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(reference-library "defstruc.ss") + +(eval-at-compile-time + (if (defined? '__NO_DEBUGGING) + (begin + (printf "Debugging off~n") + (defmacro pretty-debug args '(void)) + (defmacro pretty-debug-traverse args '(void)) + (defmacro pretty-debug-object args '(void)) + (defmacro pretty-debug-front args '(void)) + (defmacro pretty-debug-min args '(void)) + (defmacro pretty-debug-min2 args '(void)) + (defmacro pretty-debug-check args '(void)) + (defmacro pretty-debug-atenv args '(void)) + (defmacro pretty-debug-atype args '(void)) + (defmacro pretty-debug-few args '(void)) + (defmacro pretty-debug-gram args '(void)) + (defmacro pretty-debug-sdl args '(void)) + (defmacro pretty-debug-sdl2 args '(void)) + (defmacro pretty-debug-dfa-min args '(void)) + (defmacro pretty-debug-min-table args '(void)) + (defmacro pretty-debug-traverse-small args '(void)) + (defmacro pretty-debug-unit args '(void)) + (defmacro pretty-debug-gui args '(void)) + (defmacro assert args '(void)) + + ) + + (begin + (defmacro pretty-debug args + `(when debugging (pretty-print-debug ,@args))) + (defmacro pretty-debug-traverse args + `(when debugging-traverse (pretty-print-debug ,@args))) + (defmacro pretty-debug-object args + `(when debugging-object (pretty-print-debug ,@args))) + (defmacro pretty-debug-front args + `(when debugging-front (pretty-print-debug ,@args))) + (defmacro pretty-debug-min args + `(when debugging-min (pretty-print-debug ,@args))) + (defmacro pretty-debug-min2 args + `(when debugging-min2 (pretty-print-debug ,@args))) + (defmacro pretty-debug-check args + `(when debugging-check (pretty-print-debug ,@args))) + (defmacro pretty-debug-atenv args + `(when debugging-atenv (pretty-print-debug ,@args))) + (defmacro pretty-debug-atype args + `(when debugging-atype (pretty-print-debug ,@args))) + (defmacro pretty-debug-few args + `(when debugging-few (pretty-print-debug ,@args))) + (defmacro pretty-debug-gram args + `(when debugging-gram (pretty-print-debug ,@args))) + (defmacro pretty-debug-sdl args + `(when debugging-sdl (pretty-print-debug ,@args))) + (defmacro pretty-debug-sdl2 args + `(when (or debugging-sdl2 debugging-sdl) (pretty-print-debug ,@args))) + (defmacro pretty-debug-dfa-min args + `(when debugging-dfa-min (pretty-print-debug ,@args))) + (defmacro pretty-debug-min-table args + `(when debugging-min-table (pretty-print ,@args))) + (defmacro pretty-debug-gui args + `(when debugging-gui (pretty-print ,@args))) + + (defmacro pretty-debug-traverse-small args + `(when debugging-traverse + (dynamic-let ([pretty-print-depth 4]) (pretty-print-debug ,@args)))) + + (defmacro pretty-debug-unit args + (match args + [(arg) `(when debugging-unit (pretty-print-debug ,arg))] + [(arg depth) + `(when debugging-unit + (dynamic-let ([pretty-print-depth ,depth]) (pretty-print-debug ,arg)))])) + ))) + +;; ---------------------------------------------------------------------- + + +(defmacro trace-time-lambda args + (match args + [(timer args . body) + `(lambda ,args (record-time ,timer (lambda () ,@body)))])) + +;; ---------------------------------------------------------------------- diff --git a/collects/mrspidey/mred.ss b/collects/mrspidey/mred.ss new file mode 100644 index 0000000..331b195 --- /dev/null +++ b/collects/mrspidey/mred.ss @@ -0,0 +1,65 @@ +;; mred.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- +; Pulls up MrSpidey without DrScheme +; Loads all UI and analysis files into MrEd +;; ---------------------------------------------------------------------- + +(mred:add-version-spec 's 1) + +#| MATTHEW: deleted this +(define plt-home-directory + (let ([plt (getenv "PLTHOME")]) + (normalize-path + (or plt + (case (system-type) + [(unix) "/usr/local/lib/plt/"] + [(windows) "C:\\PLT"] + [else (let-values ([(base name dir?) + (split-path (current-directory))]) + (if (string? base) + base + (current-directory)))]))))) +|# +;(reference-library "sparams.ss" "backward") + +;; ------------------------------ + +(load-relative "pltrc-co.ss") + +(load-relative "text.ss") +(load-relative "Sba/hyper.ss") +(define mrspidey:load-progress + (lambda (str) + (printf "Loading ~s~n" str) + (flush-output))) +(load-relative "Gui/load.ss") +(printf "~nAll loaded~n") + +; ---------------------------------------------------------------------- + +(define T + (lambda (file) + (send spidey run-mrspidey file))) +(define (pacwar) (T "~/Spidey/Unit/Pacwar/main.ss")) +(define (mred) (T "~/Spidey/Unit/Mred/main.ss")) +(define (zodiac) (T "~/Spidey/Unit/Zodiac/invoke.ss")) + +; ---------------------------------------------------------------------- + + + diff --git a/collects/mrspidey/mrspidey.gif b/collects/mrspidey/mrspidey.gif new file mode 100644 index 0000000..108d9e3 Binary files /dev/null and b/collects/mrspidey/mrspidey.gif differ diff --git a/collects/mrspidey/pltrc-co.ss b/collects/mrspidey/pltrc-co.ss new file mode 100644 index 0000000..829defc --- /dev/null +++ b/collects/mrspidey/pltrc-co.ss @@ -0,0 +1,203 @@ +;; pltrc-co.ss +;; Stuff that released code needs +;; ---------------------------------------------------------------------- + +(define-macro defmacro + (lambda (name args . body) + `(define-macro ,name (lambda ,args ,@body)))) + +(define (struct-expander-fn def-str struct:) + (#%let ([make-exn make-exn:syntax] + [debug debug-info-handler]) + (#%lambda body + (#%let ([syntax-error + (#%lambda (s) + (#%raise + (make-exn + (#%format "~s: ~a" (cons def-str body) s) + ((debug)) + (#%cons 'define-struct body))))] + [build-struct-names + (#%lambda (name fields) + (#%let ([name (#%symbol->string name)] + [fields (#%map #%symbol->string fields)] + [+ #%string-append]) + (#%map #%string->symbol + (#%append + (#%list + (+ "struct:" name) + (+ "make-" name) + (+ name "?")) + (#%apply + #%append + (#%map + (#%lambda (f) + (#%list + (+ name "-" f) + (+ "set-" name "-" f "!"))) + fields))))))]) + (#%or (#%pair? body) + (syntax-error "empty declaration")) + (#%or (#%= 2 (#%length body)) + (syntax-error "wrong number of parts")) + (#%or (#%symbol? (#%car body)) + (#%and (#%pair? (#%car body)) + (#%symbol? (#%caar body)) + (#%pair? (#%cdar body)) + (#%null? (#%cddar body))) + (syntax-error "first part must be an identifier or identifier-expression pair")) + (#%or (#%list? (#%cadr body)) + (syntax-error "improper field list")) + (#%let* ([name (#%if (#%symbol? (#%car body)) + (#%car body) + (#%caar body))] + [fields (#%cadr body)] + [fields + (map (lambda (arg) + (match arg + [((or ': '!) field type) field] + [(? symbol? field) field] + [x (syntax-error (format "field name not a identifier at ~s" x))])) + fields)]) + `(#%define-values ,(build-struct-names name fields) + (,struct: ,(car body) ,fields))))))) + +(#%define-macro define-const-typed-structure + (struct-expander-fn ' define-const-typed-structure '#%struct)) +(#%define-macro define-typed-structure + (struct-expander-fn 'define-typed-structure '#%struct)) + +;; ---------------------------------------------------------------------- + +(#%define-macro dynamic-let + (#%let ([make-exn make-exn:syntax] + [debug debug-info-handler]) + (#%lambda (params . body) + (#%let ([fail + (#%lambda (msg) + (#%raise (make-exn msg ((debug)) + (#%list* 'dynamic-let params body))))]) + (#%if (#%null? body) (fail "dynamic-let: bad syntax (empty body)")) + (#%if (#%null? params) + `(#%begin ,@body) + (#%if (#%or (#%not (#%pair? params)) + (#%not (#%pair? (#%car params))) + (#%not (#%pair? (#%cdar params))) + (#%not (#%null? (#%cddar params)))) + (fail "dynamic-let: bad syntax") + (#%let ([param (#%caar params)] + [orig (#%gensym)] + [pz (#%gensym)]) + `(#%let* ([param ,param] + [,pz (if (parameter? param) + (#%in-parameterization + (#%current-parameterization) ,param #t) + param)] + [,orig (,pz)]) + (#%dynamic-wind + (#%lambda () (,pz ,(#%cadar params))) + (#%lambda () (dynamic-let ,(cdr params) ,@body)) + (#%lambda () (,pz ,orig))))))))))) + +;; ---------------------------------------------------------------------- + +(define cout 0) +(define wh-cout (box '())) + +(defmacro let*-vals args + (match args + [(([varss exps] ...) . body) + (set! cout (add1 cout)) + (printf "let*-vals ~s~n" cout) + (let* ([varss (map (lambda (vars) + (map + (lambda (x) (if (eq? x '_) (gensym) x)) + (if (symbol? vars) (list vars) vars))) + varss)] + [binds (map list varss exps)]) + `(begin + (set-box! (global-defined-value 'wh-cout) + (cons ,cout (unbox (global-defined-value 'wh-cout)))) + (let*-values ,binds + (begin + (set-box! (global-defined-value 'wh-cout) + (cdr (unbox (global-defined-value 'wh-cout)))) + . ,body))))])) + +(defmacro let*-vals args + (match args + [(([varss exps] ...) . body) + (let* ([varss (map (lambda (vars) + (map + (lambda (x) (if (eq? x '_) (gensym) x)) + (if (symbol? vars) (list vars) vars))) + varss)] + [binds (map list varss exps)]) + `(let*-values ,binds . ,body))])) + +(defmacro for args + (match args + [(var base limit . body) + (let ([loop (gensym)][l (gensym)]) + `(let ([,l ,limit]) + (recur ,loop ([,var ,base]) + (when (< ,var ,l) + ,@body + (,loop (add1 ,var))))))])) + +(define assert-on (make-parameter #t (lambda (x) x))) + +(defmacro assert args + (match args + [(exp . rest) + (if (assert-on) + `(unless ,exp + ,@(apply append + (map (lambda (r) `((display ,r) (newline))) rest)) + (error 'assert "Assertion failed: ~s" ',exp)) + `(void))])) + +(defmacro eval-at-compile-time args + (apply eval args)) + +;; ---------------------------------------------------------------------- + +'(unless (defined? '__keep-mrspidey-annotations) + + (defmacro begin-test-case exps '(void)) + ;;(defmacro define-type exps '(void)) + + (defmacro define-typed-structure args + (match args + [(name.parent fields) + `(define-struct + ,name.parent + ,(map (match-lambda + [((or ': '!) (? symbol? s) type) s] + [(? symbol? s) s] + [field + (error 'define-typed-structure "Bad field ~s" field)]) + fields))] + [_ (error 'define-typed-structure + "Bad syntax ~s" `(define-typed-structure ,@args))])) + + (defmacro define-const-typed-structure args + `(define-typed-structure ,@args)) + + (defmacro : args + (match args + [(exp type) exp])) + + (defmacro cache-exp args + (match args + [(exp zafile) exp])) + + (defmacro cache-inv args + (match args + [(exp zafile) exp])) + + ;; (load "~cormac/scheme/remove-mrspidey-annotations.ss")) + + ) + +;;---------------------------------------------------------------------- diff --git a/collects/mrspidey/text.ss b/collects/mrspidey/text.ss new file mode 100644 index 0000000..70e6fc8 --- /dev/null +++ b/collects/mrspidey/text.ss @@ -0,0 +1,37 @@ +;; mrspidey-mred.ss +; ---------------------------------------------------------------------- +; Copyright (C) 1995-97 Cormac Flanagan +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; version 2 as published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +; ---------------------------------------------------------------------- + +(load-relative "handlers.ss") +(load-relative "macros.ss") + +(load/use-compiled + (let ([p (build-path (current-load-relative-directory) "Zodiac" "load.ss")]) + (if (file-exists? p) + p + (build-path (current-load-relative-directory) ".." "zodiac" "load.ss")))) +(load-relative "Sba/load.ss") +(load-relative "Sba/test-sba.ss") +;;(load-relative "Sba/devel.ss") + +(printf "~nmrspidey-text loaded~n") + +;; --- Pull up a default language +(st:language 'DrScheme) + +(define (t) (st: "/home/cormac/Spidey/Test/t.ss")) + diff --git a/collects/mzscheme/dynext/compile.ss b/collects/mzscheme/dynext/compile.ss new file mode 100644 index 0000000..b8b15f2 --- /dev/null +++ b/collects/mzscheme/dynext/compile.ss @@ -0,0 +1,4 @@ + +(require-library "compiles.ss" "mzscheme" "dynext") + +(invoke-open-unit/sig (require-library "compiler.ss" "mzscheme" "dynext")) diff --git a/collects/mzscheme/dynext/compiler.ss b/collects/mzscheme/dynext/compiler.ss new file mode 100644 index 0000000..076d623 --- /dev/null +++ b/collects/mzscheme/dynext/compiler.ss @@ -0,0 +1,105 @@ + +(unit/sig dynext:compile^ (import) + + (define include-dir (collection-path "mzscheme" "include")) + + (define (get-unix-compile) + (or (find-executable-path "gcc" "gcc") + (find-executable-path "cc" "cc"))) + + (define (get-windows-compile) + (or (find-executable-path "cl.exe" "cl.exe"))) + + (define current-extension-compiler + (make-parameter + #f + (lambda (v) + (when v + (if (and (string? v) (or (relative-path? v) (absolute-path? v))) + (unless (and (file-exists? v) + (memq 'execute (file-or-directory-permissions v))) + (error 'current-extension-compiler + "compiler not found or not executable: ~s" v)) + (raise-type-error 'current-extension-compiler "pathname string or #f" v))) + v))) + + (define current-extension-compiler-flags + (make-parameter + (case (system-type) + [(unix) '("-c" "-O2")] + [(windows) '("/c" "/O2")] + [(macos) '()]) + (lambda (l) + (unless (and (list? l) (andmap string? l)) + (raise-type-error 'current-extension-compiler-flags "list of strings" l)) + l))) + + (define current-make-compile-include-strings + (make-parameter + (case (system-type) + [(unix) (lambda (s) (list (string-append "-I" s)))] + [(windows) (lambda (s) (list (string-append "/I" s)))] + [(macos) (lambda (s) (list (string-append "-I" s)))]) + (lambda (p) + (unless (procedure-arity-includes? p 1) + (raise-type-error 'current-make-compile-include-strings "procedure of arity 1" p)) + p))) + + (define current-make-compile-input-strings + (make-parameter + (lambda (s) (list s)) + (lambda (p) + (unless (procedure-arity-includes? p 1) + (raise-type-error 'current-make-compile-input-strings "procedure of arity 1" p)) + p))) + + (define current-make-compile-output-strings + (make-parameter + (case (system-type) + [(unix) (lambda (s) (list "-o" s))] + [(windows) (lambda (s) (list (string-append "/Fo" s)))] + [(macos) (lambda (s) (list "-o" s))]) + (lambda (p) + (unless (procedure-arity-includes? p 1) + (raise-type-error 'current-make-compile-output-strings "procedure of arity 1" p)) + p))) + + (define-values (my-process* stdio-compile) + (let-values ([(p* do-stdio) (require-library "stdio.ss" "mzscheme" "dynext")]) + (values + p* + (lambda (start-process quiet?) + (do-stdio start-process quiet? (lambda (s) (error 'compile-extension "~a" s))))))) + + (define unix/windows-compile + (lambda (quiet? in out includes) + (let ([c (or (current-extension-compiler) + (if (eq? (system-type) 'unix) + (get-unix-compile) + (get-windows-compile)))]) + (if c + (stdio-compile (lambda (quiet?) + (let ([command (append + (list c) + (current-extension-compiler-flags) + (apply append + (map + (lambda (s) + ((current-make-compile-include-strings) s)) + includes)) + ((current-make-compile-include-strings) include-dir) + ((current-make-compile-input-strings) in) + ((current-make-compile-output-strings) out))]) + (unless quiet? + (printf "compile-extension: ~a~n" command)) + (apply my-process* command))) + quiet?) + (error 'compile-extension "can't find compiler"))))) + + (define (macos-compile quiet? input-file output-file) + (error 'compile-extension "Not yet supported for MacOS")) + + (define compile-extension + (case (system-type) + [(unix windows) unix/windows-compile] + [(macos) macos-compile]))) diff --git a/collects/mzscheme/dynext/compiles.ss b/collects/mzscheme/dynext/compiles.ss new file mode 100644 index 0000000..4572d35 --- /dev/null +++ b/collects/mzscheme/dynext/compiles.ss @@ -0,0 +1,8 @@ + +(define-signature dynext:compile^ + (compile-extension + current-extension-compiler + current-extension-compiler-flags + current-make-compile-include-strings + current-make-compile-input-strings + current-make-compile-output-strings)) diff --git a/collects/mzscheme/dynext/doc.txt b/collects/mzscheme/dynext/doc.txt new file mode 100644 index 0000000..2a07e67 --- /dev/null +++ b/collects/mzscheme/dynext/doc.txt @@ -0,0 +1,74 @@ +compile.ss +---------- + +`compile-extension' takes + quiet? - Boolean indicating whether command should be echoed to stdout + input-file - A .c file + output-file - A .o/.obj file + includes - A list of include directories; MzScheme's include is + added automatically. + +Compilation is controlled by a number of parameters: + + current-extension-compiler - compiler executable or #f. Under + Windows, #f looks for cl.exe using the PATH env. variable. + Under Unix, #f looks for gcc and then cc. + + current-extension-compiler-flags - list of strings. Under Windows, + the default is (list "/c" "/O2"); (list "-c" "-O2") for Unix + + current-make-compile-include-strings - procedure that takes an + include dir and returns a list of strings for the command line. + Windows: "dir" -> (list "\Idir"); Unix: "dir" -> (list "-Idir") + + current-make-compile-input-strings - procedure that takes an + input file and returns a list of strings for the command line. + The default is `list'. + + current-make-compile-output-strings - procedure that takes an + output file and returns a list of strings for the command line. + Windows: "file"->(list "\Fofile"); Unix: "file"->(list "-o" "file") + +link.ss +------- + +`link-extension' takes: + quiet? - Boolean indicating whether command should be echoed to stdout + input-files - A list of .o files + output-file - A .so/.dll file + +Linking parameters: + + current-extension-linker - linker executable or #f. Under + Windows, #f looks for cl.exe using the PATH env. variable. + Under Unix except AIX, #f looks for ld. Under AIX, #f looks + for cc. + + current-extension-linker-flags - list of strings. Under Windows, + default is (list "/LD"). Unix default varies greatly per-platform. + + current-make-link-input-strings - procedure that takes an + input file and returns a list of strings for the command line. + The default is `list'. + + current-make-link-output-strings - procedure that takes an + output file and returns a list of strings for the command line. + Windows: "file"->(list "\Fefile"); Unix: "file"->(list "-o" "file") + + current-standard-link-libraries - list of file paths; For + most platforms, the default is + (list (build-path (collection-path "mzscheme" "lib") + (system-library-subpath) + "mzdyn.o")) + +file.ss +------- + + (make-directory* dir) - makes dir, creating intermediate directoies + if necessary. If there is an error, and exception is raised. + + (append-object-suffix s) - appends the platform-standard object + file suffix to s + + (append-extension-suffix s) - appends the platform-standard dynamic + extension file suffix to s diff --git a/collects/mzscheme/dynext/dolink.ss b/collects/mzscheme/dynext/dolink.ss new file mode 100644 index 0000000..f6b1bda --- /dev/null +++ b/collects/mzscheme/dynext/dolink.ss @@ -0,0 +1,35 @@ + +(require-library "link.ss" "mzscheme" "dynext") + +; Parse arguments: +(define a (vector->list argv)) + +(define quiet? #f) + +(when (and (pair? a) (string=? (car a) "-q")) + (set! quiet? #t) + (set! a (cdr a))) + +(define inputs null) +(define output #f) + +(let loop ([a a]) + (unless (null? a) + (if (string=? (car a) "-o") + (if (null? (cdr a)) + (error 'dynlink "expected a filename after -o") + (if output + (error 'dynlink "multiple output files provided") + (begin + (set! output (cadr a)) + (loop (cddr a))))) + (begin + (set! inputs (append inputs (list (car a)))) + (loop (cdr a)))))) + +(when (not output) + (error 'dynlink "no output file specified")) +(when (null? inputs) + (error 'dynlink "no input files specified")) + +(link-extension quiet? inputs output) diff --git a/collects/mzscheme/dynext/file.ss b/collects/mzscheme/dynext/file.ss new file mode 100644 index 0000000..cdd29f3 --- /dev/null +++ b/collects/mzscheme/dynext/file.ss @@ -0,0 +1,49 @@ +(define (make-directory* dir) + (let-values ([(base name dir?) (split-path dir)]) + (when (and (string? base) + (not (directory-exists? base))) + (make-directory* base)) + (unless (make-directory dir) + (error 'make-directory* "couldn't make directory: ~s" dir)))) + +(define (append-c-suffix s) + (string-append s ".c")) + +(define (append-constant-pool-suffix s) + (string-append s ".kp")) + +(define (append-object-suffix s) + (string-append + s + (case (system-type) + [(unix macos) ".o"] + [(windows) ".obj"]))) + +(define (append-extension-suffix s) + (string-append + s + (case (system-type) + [(unix macos) ".so"] + [(windows) ".dll"]))) + +(define-values (extract-base-filename/ss + extract-base-filename/c + extract-base-filename/kp + extract-base-filename/o) + (let ([mk + (lambda (pat kind) + (letrec ([extract-base-filename + (case-lambda + [(s p) + (let ([m (regexp-match (format "^(.*)\\.(~a)$" pat) s)]) + (cond + [m (cadr m)] + [p (error p "not a ~a file: ~a" kind s)] + [else #f]))] + [(s) (extract-base-filename s #f)])]) + extract-base-filename))]) + (values + (mk "ss|scm" "Scheme") + (mk "c" "C") + (mk "kp" "constant pool") + (mk "o|obj" "compiled object")))) diff --git a/collects/mzscheme/dynext/link.ss b/collects/mzscheme/dynext/link.ss new file mode 100644 index 0000000..bce1c8c --- /dev/null +++ b/collects/mzscheme/dynext/link.ss @@ -0,0 +1,4 @@ + +(require-library "links.ss" "mzscheme" "dynext") + +(invoke-open-unit/sig (require-library "linkr.ss" "mzscheme" "dynext")) diff --git a/collects/mzscheme/dynext/linkr.ss b/collects/mzscheme/dynext/linkr.ss new file mode 100644 index 0000000..b784559 --- /dev/null +++ b/collects/mzscheme/dynext/linkr.ss @@ -0,0 +1,118 @@ +(unit/sig dynext:link^ (import) + + (define include-dir (collection-path "mzscheme" "include")) + + (define current-extension-linker + (make-parameter + #f + (lambda (v) + (when v + (if (and (string? v) (or (relative-path? v) (absolute-path? v))) + (unless (and (file-exists? v) + (memq 'execute (file-or-directory-permissions v))) + (error 'current-extension-linker + "linker not found or not executable: ~s" v)) + (raise-type-error 'current-extension-linker "pathname string or #f" v))) + v))) + + (define (get-windows-linker) + (or (find-executable-path "cl.exe" "cl.exe"))) + + (define (get-unix-linker) + (let ([s (case (string->symbol (system-library-subpath)) + [(rs6k-aix) "cc"] + [else "ld"])]) + (find-executable-path s s))) + + (define (get-unix-link-flags) + (case (string->symbol (system-library-subpath)) + [(sparc-solaris) (list "-G")] + [(sparc-sunos4) (list "-Bdynamic")] + [(i386-freebsd) (list "-Bshareable")] + [(rs6k-aix) (let ([version (read (car (process* "/usr/bin/uname" "-v")))]) + (list "-bM:SRE" + (format "-bI:~a/mzscheme.exp" include-dir) + (format "-bE:~a/ext.exp" include-dir) + (if (= 3 version) + "-e _nostart" + "-bnoentry")))] + [(parisc-hpux) "-b"] + [else (list "-shared")])) + + (define current-extension-linker-flags + (make-parameter + (case (system-type) + [(unix) (get-unix-link-flags)] + [(windows) (list "/LD")] + [(macos) null]) + (lambda (l) + (unless (and (list? l) (andmap string? l)) + (raise-type-error 'current-extension-link-flags "list of strings" l)) + l))) + + (define std-library-dir (build-path (collection-path "mzscheme" "lib") (system-library-subpath))) + + (define-values (my-process* stdio-link) + (let-values ([(p* do-stdio) (require-library "stdio.ss" "mzscheme" "dynext")]) + (values + p* + (lambda (start-process quiet?) + (do-stdio start-process quiet? (lambda (s) (error 'link-extension "~a" s))))))) + + (define current-make-link-input-strings + (make-parameter + (lambda (s) (list s)) + (lambda (p) + (unless (procedure-arity-includes? p 1) + (raise-type-error 'current-make-link-input-strings "procedure of arity 1" p)) + p))) + + (define current-make-link-output-strings + (make-parameter + (case (system-type) + [(unix) (lambda (s) (list "-o" s))] + [(windows) (lambda (s) (list (string-append "/Fe" s)))] + [(macos) (lambda (s) (list "-o" s))]) + (lambda (p) + (unless (procedure-arity-includes? p 1) + (raise-type-error 'current-make-link-output-strings "procedure of arity 1" p)) + p))) + + (define current-standard-link-libraries + (make-parameter + (case (system-type) + [(unix macos) (list (build-path std-library-dir "mzdyn.o"))] + [(windows) (list (build-path std-library-dir "msvc" "mzdyn.obj") + (build-path std-library-dir "msvc" "mzdyn.exp"))]) + (lambda (l) + (unless (and (list? l) (andmap string? l)) + (raise-type-error 'current-standard-link-libraries "list of strings" l)) + l))) + + (define unix/windows-link + (lambda (quiet? in out) + (let ([c (or (current-extension-linker) + (if (eq? (system-type) 'unix) + (get-unix-linker) + (get-windows-linker)))]) + (if c + (stdio-link (lambda (quiet?) + (let ([command (append (list c) + (current-extension-linker-flags) + (apply append (map (lambda (s) ((current-make-link-input-strings) s)) in)) + (current-standard-link-libraries) + ((current-make-link-output-strings) out))]) + (unless quiet? + (printf "link-extension: ~a~n" command)) + (apply my-process* command))) + quiet?) + (error 'link-extension "can't find linker"))))) + + (define (macos-link quiet? input-files output-file) + (error 'link-extension "Not yet supported for MacOS")) + + (define link-extension + (case (system-type) + [(unix windows) unix/windows-link] + [(macos) macos-link]))) + diff --git a/collects/mzscheme/dynext/links.ss b/collects/mzscheme/dynext/links.ss new file mode 100644 index 0000000..5d9e0b8 --- /dev/null +++ b/collects/mzscheme/dynext/links.ss @@ -0,0 +1,7 @@ +(define-signature dynext:link^ + (link-extension + current-extension-linker + current-extension-linker-flags + current-make-link-input-strings + current-make-link-output-strings + current-standard-link-libraries)) diff --git a/collects/mzscheme/dynext/stdio.ss b/collects/mzscheme/dynext/stdio.ss new file mode 100644 index 0000000..cfd870d --- /dev/null +++ b/collects/mzscheme/dynext/stdio.ss @@ -0,0 +1,49 @@ + +(values + (if (string=? (system-library-subpath) "rs6k-aix") + (letrec ([pseudo-process* + (lambda (c . args) + (if (null? args) + (let ([r (process* "/usr/bin/csh" "-t")]) + (display c (cadr r)) + (newline (cadr r)) + r) + (apply pseudo-process* (string-append c " " (car args)) (cdr args))))]) + pseudo-process*) + process*) + + (lambda (start-process quiet? error) + (let* ([l (start-process quiet?)] + [in (car l)] + [out (cadr l)] + [in-error (cadddr l)] + [control (cadddr (cdr l))] + + [collect-output (box "")] + + [make-collector + (lambda (in dest box) + (thread (lambda () + (let loop () + (let ([t (read-line in)]) + (unless (eof-object? t) + (unless quiet? (fprintf (dest) "~a~n" t)) + (set-box! box (string-append (unbox box) + (string #\newline #\space) t)) + (loop)))))))] + [in-thread (make-collector in current-output-port collect-output)] + [in-error-thread (make-collector in-error current-error-port collect-output)]) + + (control 'wait) + + (thread-wait in-thread) + (thread-wait in-error-thread) + + (close-input-port in) + (close-input-port in-error) + (close-output-port out) + + (unless (eq? (control 'status) 'done-ok) + (error (if quiet? + (unbox collect-output) + "command failed")))))) diff --git a/collects/mzscheme/include/escheme.h b/collects/mzscheme/include/escheme.h new file mode 100644 index 0000000..f0c442a --- /dev/null +++ b/collects/mzscheme/include/escheme.h @@ -0,0 +1,34 @@ +/* + MzScheme + Copyright (c) 1995 Matthew Flatt + All rights reserved. + + Please see the full copyright in the documentation. + + libscheme + Copyright (c) 1994 Brent Benson + All rights reserved. +*/ + +/* This file should be included by MzScheme dynamically-loaded + extenstion files */ + +#ifndef E_SCHEME_H +#define E_SCHEME_H + +#define SCHEME_DIRECT_EMBEDDED 0 + +#include "scheme.h" + +#ifdef CODEFRAGMENT_DYNAMIC_LOAD +#pragma export on +#endif + +extern Scheme_Object *scheme_initialize(Scheme_Env *global_env); + +#ifdef CODEFRAGMENT_DYNAMIC_LOAD +#pragma export off +#endif + +#endif /* ! E_SCHEME_H */ + diff --git a/collects/mzscheme/include/ext.exp b/collects/mzscheme/include/ext.exp new file mode 100644 index 0000000..9a09e43 --- /dev/null +++ b/collects/mzscheme/include/ext.exp @@ -0,0 +1,4 @@ +#! +scheme_initialize_internal +scheme_initialize +scheme_reload diff --git a/collects/mzscheme/include/mzscheme.exp b/collects/mzscheme/include/mzscheme.exp new file mode 100644 index 0000000..f76967f --- /dev/null +++ b/collects/mzscheme/include/mzscheme.exp @@ -0,0 +1,289 @@ +#! +scheme_init_jmpup_buf +scheme_setjmpup_relative +scheme_longjmpup +scheme_setjmp +scheme_longjmp +scheme_make_config +scheme_branch_config +scheme_new_param +scheme_param_config +scheme_register_parameter +scheme_get_env +scheme_current_process +scheme_fuel_counter +scheme_current_process_ptr +scheme_fuel_counter_ptr +scheme_make_namespace +scheme_thread +scheme_break_thread +scheme_kill_thread +scheme_process_block +scheme_swap_process +scheme_block_until +scheme_in_main_thread +scheme_tls_allocate +scheme_tls_set +scheme_tls_get +scheme_add_namespace_option +scheme_make_manager +scheme_add_managed +scheme_remove_managed +scheme_close_managed +scheme_signal_error +scheme_raise_exn +scheme_warning +scheme_wrong_count +scheme_case_lambda_wrong_count +scheme_wrong_type +scheme_wrong_return_arity +scheme_unbound_global +scheme_dynamic_wind +scheme_make_type +scheme_install_type_reader +scheme_install_type_writer +scheme_eof +scheme_null +scheme_true +scheme_false +scheme_void +scheme_undefined +scheme_tail_call_waiting +scheme_multiple_values +scheme_eval +scheme_eval_multi +scheme_eval_compiled +scheme_eval_compiled_multi +_scheme_eval_compiled +_scheme_eval_compiled_multi +scheme_apply +scheme_apply_multi +scheme_apply_to_list +scheme_eval_string +scheme_eval_string_all +_scheme_apply_known_closed_prim +_scheme_apply_known_closed_prim_multi +scheme_values +scheme_check_one_value +scheme_tail_apply +scheme_tail_apply_no_copy +scheme_tail_apply_to_list +scheme_tail_eval_expr +scheme_set_tail_buffer_size +scheme_force_value +scheme_do_eval +GC_malloc +GC_malloc_atomic +GC_malloc_stubborn +GC_malloc_uncollectable +scheme_malloc_eternal +scheme_end_stubborn_change +scheme_calloc +scheme_strdup +scheme_strdup_eternal +scheme_malloc_fail_ok +scheme_weak_reference +scheme_weak_reference_indirect +scheme_add_finalizer +scheme_add_scheme_finalizer +scheme_register_finalizer +scheme_dont_gc_ptr +scheme_gc_ptr_ok +scheme_collect_garbage +scheme_hash_table +scheme_add_to_table +scheme_change_in_table +scheme_lookup_in_table +scheme_bucket_from_table +scheme_make_prim +scheme_make_noneternal_prim +scheme_make_closed_prim +scheme_make_prim_w_arity +scheme_make_folding_prim +scheme_make_noneternal_prim_w_arity +scheme_make_closed_prim_w_arity +scheme_make_folding_closed_prim +scheme_make_closure +scheme_make_pair +scheme_make_string +scheme_make_sized_string +scheme_make_string_without_copying +scheme_alloc_string +scheme_append_string +scheme_make_vector +scheme_make_integer_value +scheme_make_integer_value_from_unsigned +scheme_make_double +scheme_make_float +scheme_make_char +scheme_make_promise +scheme_make_promise_from_thunk +scheme_make_sema +scheme_post_sema +scheme_wait_sema +scheme_char_constants +scheme_get_int_val +scheme_get_unsigned_int_val +scheme_get_proc_name +scheme_make_bignum +scheme_make_bignum_from_unsigned +scheme_bignum_to_double +scheme_bignum_from_double +scheme_bignum_to_float +scheme_bignum_from_float +scheme_bignum_to_string +scheme_read_bignum +scheme_bignum_normalize +scheme_double_to_int +scheme_make_rational +scheme_rational_to_double +scheme_rational_from_double +scheme_rational_to_float +scheme_rational_from_float +scheme_rational_normalize +scheme_rational_numerator +scheme_rational_denominator +scheme_make_complex +scheme_complex_normalize +scheme_complex_real_part +scheme_complex_imaginary_part +scheme_is_exact +scheme_is_inexact +scheme_expand +scheme_compile +scheme_make_promise_value +scheme_read +scheme_write +scheme_display +scheme_write_w_max +scheme_display_w_max +scheme_write_string +scheme_write_to_string +scheme_display_to_string +scheme_write_to_string_w_max +scheme_display_to_string_w_max +scheme_debug_print +scheme_flush_output +scheme_format +scheme_printf +scheme_getc +scheme_ungetc +scheme_char_ready +scheme_need_wakeup +scheme_get_chars +scheme_tell +scheme_output_tell +scheme_tell_line +scheme_close_input_port +scheme_close_output_port +scheme_are_all_chars_ready +scheme_make_port_type +scheme_make_input_port +scheme_make_output_port +scheme_make_file_input_port +scheme_make_named_file_input_port +scheme_make_file_output_port +scheme_make_string_input_port +scheme_make_sized_string_input_port +scheme_make_string_output_port +scheme_get_string_output +scheme_get_sized_string_output +scheme_pipe +scheme_file_exists +scheme_directory_exists +scheme_expand_filename +scheme_getcwd +scheme_setcwd +scheme_getdrive +scheme_split_pathname +scheme_build_pathname +scheme_alloc_fdset_array +scheme_init_fdset_array +scheme_get_fdset +scheme_fdzero +scheme_fdset +scheme_fdclr +scheme_fdisset +scheme_add_global +scheme_add_global_constant +scheme_add_global_keyword +scheme_remove_global +scheme_remove_global_constant +scheme_add_global_symbol +scheme_remove_global_symbol +scheme_add_global_constant_symbol +scheme_constant +scheme_set_keyword +scheme_make_envunbox +scheme_lookup_global +scheme_global_bucket +scheme_set_global_bucket +scheme_intern_symbol +scheme_intern_exact_symbol +scheme_make_symbol +scheme_make_exact_symbol +scheme_symbol_name +scheme_symbol_name_and_size +scheme_intern_type_symbol +scheme_make_type_symbol +scheme_make_struct_values +scheme_make_struct_names +scheme_make_struct_type +scheme_make_struct_instance +scheme_is_struct_instance +scheme_make_class +scheme_add_method +scheme_add_method_w_arity +scheme_made_class +scheme_make_object +scheme_make_uninited_object +scheme_find_ivar +scheme_is_subclass +scheme_is_implementation +scheme_is_interface_extension +scheme_is_a +scheme_get_class_name +scheme_get_interface_name +scheme_make_class_assembly +scheme_create_class +scheme_make_interface_assembly +scheme_create_interface +scheme_apply_generic_data +scheme_get_generic_data +scheme_invoke_unit +scheme_assemble_compound_unit +scheme_make_compound_unit +scheme_get_unit_name +scheme_eq +scheme_eqv +scheme_equal +scheme_build_list +scheme_list_length +scheme_proper_list_length +scheme_alloc_list +scheme_map_1 +scheme_car +scheme_cdr +scheme_cadr +scheme_caddr +scheme_vector_to_list +scheme_list_to_vector +scheme_append +scheme_box +scheme_unbox +scheme_set_box +scheme_make_weak_box +scheme_load +scheme_load_extension +scheme_register_extension_global +scheme_get_milliseconds +scheme_get_process_milliseconds +scheme_rep +scheme_banner +scheme_version +scheme_check_proc_arity +scheme_secure_exceptions +scheme_make_provided_string +scheme_make_args_string +scheme_no_dumps +scheme_system_library_subpath diff --git a/collects/mzscheme/include/scheme.h b/collects/mzscheme/include/scheme.h new file mode 100644 index 0000000..ce41434 --- /dev/null +++ b/collects/mzscheme/include/scheme.h @@ -0,0 +1,1063 @@ +/* + MzScheme + Copyright (c) 1995 Matthew Flatt + All rights reserved. + + Please see the full copyright in the documentation. + + libscheme + Copyright (c) 1994 Brent Benson + All rights reserved. +*/ + +#ifndef SCHEME_H +#define SCHEME_H + +/* The next line is used and set during installation: */ +#define INCLUDE_WITHOUT_PATHS + +#ifdef INCLUDE_WITHOUT_PATHS +# include "sconfig.h" +#else +# include "../sconfig.h" +#endif + +#define AGRESSIVE_ZERO_FOR_GC +#define AGRESSIVE_ZERO_TB + +#if SGC_STD_DEBUGGING +# ifndef USE_SENORA_GC +# define USE_SENORA_GC +# endif +# define USE_MEMORY_TRACING +#endif + +#ifdef USE_SENORA_GC +# define MUST_REGISTER_GLOBALS +# undef UNIX_IMAGE_DUMPS +#endif + +#ifdef USE_SINGLE_FLOATS +# define MZ_USE_SINGLE_FLOATS +#endif + +#include +#include +#include +#include +#include + +#ifndef SCHEME_DIRECT_EMBEDDED +#define SCHEME_DIRECT_EMBEDDED 1 +#endif + +#ifndef MSC_IZE +# define MSC_IZE(x) x +#endif + +#ifdef SIGSET_IS_SIGNAL +# define MZ_SIGSET(s, f) signal(s, f) +#else +# define MZ_SIGSET(s, f) sigset(s, f) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef short Scheme_Type; + +typedef struct Scheme_Bucket +{ + Scheme_Type type; + void *val; + char *key; +} Scheme_Bucket; + +typedef struct Scheme_Hash_Table +{ + Scheme_Type type; + int size, count, step; + Scheme_Bucket **buckets; + char has_constants, forever, weak; + void (*make_hash_indices)(void *v, int *h1, int *h2); + int (*compare)(void *v1, void *v2); +#ifdef MZ_REAL_THREADS + void *mutex; +#endif +} Scheme_Hash_Table; + +/* Hash tablekey types, used with scheme_hash_table */ +enum { + SCHEME_hash_string, + SCHEME_hash_ptr, + SCHEME_hash_weak_ptr +}; + +typedef struct Scheme_Env +{ + Scheme_Type type; /* scheme_namespace_type */ + Scheme_Hash_Table *globals; + Scheme_Hash_Table *loaded_libraries; + struct Scheme_Object *nonempty_cond; /* hack used when !scheme_allow_cond_auto_else */ + struct Scheme_Comp_Env *init; /* initial compilation environment */ +} Scheme_Env; + +typedef struct Scheme_Object * +(Scheme_Prim)(int argc, struct Scheme_Object *argv[]); + +typedef struct Scheme_Object * +(Scheme_Closed_Prim)(void *d, int argc, struct Scheme_Object *argv[]); + +typedef struct Scheme_Object * +(Scheme_Method_Prim)(struct Scheme_Object *o, + int argc, struct Scheme_Object *argv[]); + +typedef struct Scheme_Object +{ + Scheme_Type type; /* Anything that starts with a type field + can be a Scheme_Object */ + union + { + struct { char *string_val; int tag_val; } str_val; + struct { void *ptr1, *ptr2; } two_ptr_val; + struct { int int1; int int2; } two_int_val; + struct { void *ptr; int pint; } ptr_int_val; + struct { void *ptr; long pint; } ptr_long_val; + struct { + Scheme_Closed_Prim *f; + void *d; } clsd_prim_val; + struct { struct Scheme_Object *car, *cdr; } pair_val; + struct { struct Scheme_Env *env; struct Scheme_Object *code; } closure_val; + struct { short len; short *vec; } svector_val; + struct Scheme_Debugging_Info *debug_val; + } u; +} Scheme_Object; + +typedef struct { + Scheme_Type type; + union { + char char_val; + Scheme_Object *ptr_value; + long int_val; + Scheme_Object *ptr_val; + Scheme_Prim *prim_val; + } u; +} Scheme_Small_Object; + +typedef struct { + Scheme_Type type; + double double_val; +} Scheme_Double; + +#ifdef MZ_USE_SINGLE_FLOATS +typedef struct { + Scheme_Type type; + float float_val; +} Scheme_Float; +#endif + +#define SCHEME_PRIM_IS_FOLDING 1 +#define SCHEME_PRIM_IS_PRIMITIVE 2 +#define SCHEME_PRIM_IS_STRUCT_PROC 4 +#define SCHEME_PRIM_IS_STRUCT_SETTER 8 +#define SCHEME_PRIM_IS_PARAMETER 16 +#define SCHEME_PRIM_IS_STRUCT_GETTER 32 +#define SCHEME_PRIM_IS_STRUCT_PRED 64 +#define SCHEME_PRIM_IS_STRUCT_CONSTR 128 +#define SCHEME_PRIM_IS_MULTI_RESULT 256 +#define SCHEME_PRIM_IS_GENERIC 512 +#define SCHEME_PRIM_IS_USER_PARAMETER 1024 + +typedef struct { + Scheme_Type type; + short flags; /* keep flags at same place as in closed */ + Scheme_Prim *prim_val; + const char *name; + short mina, maxa; +} Scheme_Primitive_Proc; + +typedef struct { + Scheme_Primitive_Proc p; + short minr, maxr; +} Scheme_Prim_W_Result_Arity; + +typedef struct { + Scheme_Type type; + short flags; /* keep flags at same place as in unclosed */ + Scheme_Closed_Prim *prim_val; + void *data; + const char *name; + short mina, maxa; /* mina == -2 => maxa is negated case count and + record is a Scheme_Closed_Case_Primitive_Proc */ +} Scheme_Closed_Primitive_Proc; + +typedef struct { + Scheme_Closed_Primitive_Proc p; + short minr, maxr; +} Scheme_Closed_Prim_W_Result_Arity; + +typedef struct { + Scheme_Closed_Primitive_Proc p; + short *cases; +} Scheme_Closed_Case_Primitive_Proc; + +#define _scheme_fill_prim_closure(rec, cfunc, dt, nm, amin, amax) \ + ((rec)->type = scheme_closed_prim_type, \ + (rec)->prim_val = cfunc, \ + (rec)->data = (void *)(dt), \ + (rec)->name = nm, \ + (rec)->mina = amin, \ + (rec)->maxa = amax, \ + rec) + +#define _scheme_fill_prim_case_closure(rec, cfunc, dt, nm, ccount, cses) \ + ((rec)->p.type = scheme_closed_prim_type, \ + (rec)->p.prim_val = cfunc, \ + (rec)->p.data = (void *)(dt), \ + (rec)->p.name = nm, \ + (rec)->p.mina = -2, \ + (rec)->p.maxa = -(ccount), \ + (rec)->cases = cses, \ + rec) + +typedef struct Scheme_Debugging_Info { + Scheme_Object *src; +} Scheme_Debugging_Info; + +typedef struct Scheme_Sema { + Scheme_Type type; +#ifdef MZ_REAL_THREADS + void *sema; +#else + long value; +#endif +} Scheme_Sema; + +typedef struct Scheme_Symbol { + Scheme_Type type; + short len; + char s[1]; +} Scheme_Symbol; + +typedef struct Scheme_Vector { + Scheme_Type type; + int size; + Scheme_Object *els[1]; +} Scheme_Vector; + +typedef void Scheme_Close_Manager_Client(Scheme_Object *o, void *data); +typedef struct Scheme_Manager *Scheme_Manager_Reference; + +typedef struct Scheme_Manager { + Scheme_Type type; + short count, alloc; + Scheme_Object ***boxes; + Scheme_Manager_Reference **mrefs; + Scheme_Close_Manager_Client **closers; + void **data; + + /* atomic indirections: */ + struct Scheme_Manager **parent; + struct Scheme_Manager **sibling; + struct Scheme_Manager **children; +} Scheme_Manager; + +typedef struct Scheme_Input_Port +{ + Scheme_Type type; + short closed; + Scheme_Object *sub_type; + Scheme_Manager_Reference *mref; + void *port_data; + int (*getc_fun) (struct Scheme_Input_Port *port); + int (*char_ready_fun) (struct Scheme_Input_Port *port); + void (*close_fun) (struct Scheme_Input_Port *port); + void (*need_wakeup_fun)(struct Scheme_Input_Port *, void *); + Scheme_Object *read_handler; + char *name; + char *ungotten; + int ungotten_count, ungotten_allocated; + long position, lineNumber, charsSinceNewline; + int eoffound; +#ifdef MZ_REAL_THREADS + Scheme_Object *sema; +#endif +} Scheme_Input_Port; + +typedef struct Scheme_Output_Port +{ + Scheme_Type type; + short closed; + Scheme_Object *sub_type; + Scheme_Manager_Reference *mref; + void *port_data; + void (*write_string_fun)(char *str, long len, struct Scheme_Output_Port *); + void (*close_fun) (struct Scheme_Output_Port *); + long pos; + Scheme_Object *display_handler; + Scheme_Object *write_handler; + Scheme_Object *print_handler; +#ifdef MZ_REAL_THREADS + Scheme_Object *sema; +#endif +} Scheme_Output_Port; + +typedef struct { + Scheme_Type type; + struct Scheme_Object *sclass; + /* The following fields are only here for instances of classes + created with scheme_make_class(): */ + void *primdata; + short primflag; + short inited; +} Scheme_Class_Object; + +typedef struct Scheme_Unit { + Scheme_Type type; /* scheme_unit_type */ + short num_imports; /* num expected import args */ + short num_exports; /* num exported vars */ + Scheme_Object **exports; /* names of exported */ + Scheme_Object **export_debug_names; /* internal names; NULL => no debugging */ + Scheme_Object *(*init_func)(Scheme_Object **boxes, Scheme_Object **anchors, + struct Scheme_Unit *m, + void *debug_request); + Scheme_Object *data; +} Scheme_Unit; + +typedef void Scheme_Instance_Init_Proc(Scheme_Object **init_boxes, + Scheme_Object **extract_boxes, + Scheme_Object *super_init, + int argc, + Scheme_Object **argv, + Scheme_Object *instance, + void *data); + +/* Like setjmp & longjmp, but you can jmp to a deeper stack position */ +/* Intialize a Scheme_Jumpup_Buf record before using it */ +typedef struct Scheme_Jumpup_Buf { + void *stack_from, *stack_copy; + long stack_size, stack_max_size; + struct Scheme_Jumpup_Buf *cont; + jmp_buf buf; +} Scheme_Jumpup_Buf; + +enum { + MZCONFIG_ENV, + MZCONFIG_INPUT_PORT, + MZCONFIG_OUTPUT_PORT, + MZCONFIG_ERROR_PORT, + + MZCONFIG_USER_BREAK_POLL_HANDLER, + MZCONFIG_ENABLE_BREAK, + MZCONFIG_ENABLE_EXCEPTION_BREAK, + + MZCONFIG_ERROR_DISPLAY_HANDLER, + MZCONFIG_ERROR_PRINT_VALUE_HANDLER, + + MZCONFIG_EXIT_HANDLER, + + MZCONFIG_EXN_HANDLER, + MZCONFIG_DEBUG_INFO_HANDLER, + + MZCONFIG_EVAL_HANDLER, + MZCONFIG_LOAD_HANDLER, + + MZCONFIG_PRINT_HANDLER, + MZCONFIG_PROMPT_READ_HANDLER, + + MZCONFIG_CAN_READ_GRAPH, + MZCONFIG_CAN_READ_COMPILED, + MZCONFIG_CAN_READ_BOX, + MZCONFIG_CAN_READ_TYPE_SYMBOL, + MZCONFIG_CAN_READ_PIPE_QUOTE, + + MZCONFIG_PRINT_GRAPH, + MZCONFIG_PRINT_STRUCT, + MZCONFIG_PRINT_BOX, + + MZCONFIG_CASE_SENS, + MZCONFIG_SQUARE_BRACKETS_ARE_PARENS, + MZCONFIG_CURLY_BRACES_ARE_PARENS, + + MZCONFIG_ERROR_PRINT_WIDTH, + + MZCONFIG_CONFIG_BRANCH_HANDLER, + + MZCONFIG_WILL_EXECUTOR, + + MZCONFIG_ALLOW_SET_UNDEFINED, + MZCONFIG_COND_AUTO_ELSE, + + MZCONFIG_MANAGER, + + MZCONFIG_REQ_LIB_USE_COMPILED, + + MZCONFIG_LOAD_DIRECTORY, + + MZCONFIG_COLLECTION_PATHS, + + MZCONFIG_PORT_PRINT_HANDLER, + + MZCONFIG_REQUIRE_COLLECTION, + + MZCONFIG_LOAD_EXTENSION_HANDLER, + + __MZCONFIG_BUILTIN_COUNT__ +}; + + +typedef struct Scheme_Config { + Scheme_Type type; + Scheme_Hash_Table *extensions; + + /* For sharing as-yet uncreated parameters: */ + struct Scheme_Config **parent; + struct Scheme_Config **child; + struct Scheme_Config **sibling; + + Scheme_Object **configs[1]; +} Scheme_Config; + +#define scheme_set_param(c, pos, o) (*((c)->configs[pos]) = o) +#define scheme_get_param(c, pos) (*((c)->configs[pos])) + +typedef struct Scheme_Saved_Stack { + Scheme_Object **runstack_start; + Scheme_Object **runstack; + long runstack_size; + struct Scheme_Saved_Stack *prev; +} Scheme_Saved_Stack; + +typedef struct Scheme_Process { + Scheme_Type type; + + jmp_buf error_buf; + int jumping_to_continuation; + + Scheme_Config *config; + + Scheme_Object **runstack; + Scheme_Object **runstack_start; + long runstack_size; + Scheme_Saved_Stack *runstack_saved; + Scheme_Object **runstack_tmp_keep; + + long engine_weight; + + void *stack_start, *stack_end; + Scheme_Jumpup_Buf jmpup_buf; +#if defined(USE_WIN32_THREADS) || defined(SPAWN_NEW_STACK) + void *stack_current; +#ifdef NEW_STACK_VIA_THREAD + void *threadinfo; +#endif +#endif +#ifdef USE_WIN32_THREADS + void *thread; + void *sem; +#endif +#ifdef MZ_REAL_THREADS + void *thread; +#endif + + void *cc_start; + long *cc_ok; + struct Scheme_Dynamic_Wind *dw; + + struct Scheme_Process *next; + + int running; +#ifdef ERROR_ON_OVERFLOW + int stack_overflow; +#endif + + float sleep_time; /* blocker has starting sleep time */ + int block_descriptor; + Scheme_Object *blocker; /* semaphore or port */ + int (*block_check)(Scheme_Object *blocker); + void (*block_needs_wakeup)(Scheme_Object *blocker, void *fds); + int ran_some; + +#ifndef ERROR_ON_OVERFLOW + struct Scheme_Overflow *overflow; + jmp_buf overflow_buf; +#endif + +#ifdef USE_MAC_FILE_TOOLBOX + short wd_inited; + short vrefnum; + long dirid; +#else + char *working_directory; + int wd_len; +#endif + + struct Scheme_Comp_Env *current_local_env; + + Scheme_Object *error_escape_proc; /* Per-thread paramaterization */ + + /* These are used to lock in values during `read': */ + char quick_can_read_type_symbol; + char quick_can_read_compiled; + char quick_can_read_pipe_quote; + char quick_can_read_box; + char quick_can_read_graph; + char quick_case_sens; + char quick_square_brackets_are_parens; + char quick_curly_braces_are_parens; + + /* Used during `display' and `write': */ + char *print_buffer; + long print_position; + long print_allocated; + long print_maxlen; + Scheme_Object *print_port; + jmp_buf print_escape; + + char exn_raised; + char error_invoked; + char err_val_str_invoked; + +#ifndef ERROR_ON_OVERFLOW + Scheme_Object *(*overflow_k)(void); + Scheme_Object *overflow_reply; + Scheme_Jumpup_Buf overflow_cont; +#endif + + Scheme_Object **tail_buffer; + int tail_buffer_size; + + union { + struct { + Scheme_Object *wait_expr; + } eval; + struct { + Scheme_Object *tail_rator; + Scheme_Object **tail_rands; + int tail_num_rands; + } apply; + struct { + Scheme_Object **array; + int count; + } multiple; + struct { + void *p1, *p2, *p3, *p4; + long i1, i2; + } k; + } ku; + + short checking_break; + short external_break; + +#ifdef MZ_REAL_THREADS + Scheme_Object *done_sema; + long fuel_counter; +#define scheme_fuel_counter (scheme_current_process->fuel_counter) +#define scheme_stack_boundary ((unsigned long)scheme_current_process->stack_end) +#endif + + Scheme_Object *list_stack; + int list_stack_pos; + + long block_start_sleep; + +#ifdef AGRESSIVE_ZERO_TB + int tail_buffer_set; +#endif + + void (*on_kill)(struct Scheme_Process *p); + void *kill_data; + + void **user_tls; + int user_tls_size; + + Scheme_Manager_Reference *mref; +} Scheme_Process; + +/* Type readers & writers for compiled code data */ +typedef Scheme_Object *(*Scheme_Type_Reader)(Scheme_Object *list); +typedef Scheme_Object *(*Scheme_Type_Writer)(Scheme_Object *obj); + +/* This file defines all the built-in types */ +#ifdef INCLUDE_WITHOUT_PATHS +#include "stypes.h" +#else +#include "../src/stypes.h" +#endif + +/* This file includes the MZEXN constants */ +#ifdef INCLUDE_WITHOUT_PATHS +#include "schexn.h" +#else +#include "../src/schexn.h" +#endif + +#if defined(USE_FAR_MZ_FDCALLS) || defined(DETECT_WIN32_CONSOLE_STDIN) || defined(WINDOWS_PROCESSES) +# define MZ_GET_FDSET(p, n) scheme_get_fdset(p, n) +#else +# define MZ_GET_FDSET(p, n) ((void *)(((fd_set *)p) + n)) +#endif + +#ifdef USE_FAR_MZ_FDCALLS +# define MZ_FD_ZERO(p) scheme_fdzero(p) +# define MZ_FD_SET(n, p) scheme_fdset(p, n) +# define MZ_FD_CLR(n, p) scheme_fdclr(p, n) +# define MZ_FD_ISSET(n, p) scheme_fdisset(p, n) +#else +# define MZ_FD_ZERO(p) FD_ZERO(p) +# define MZ_FD_SET(n, p) FD_SET(n, p) +# define MZ_FD_CLR(n, p) FD_CLR(n, p) +# define MZ_FD_ISSET(n, p) FD_ISSET(n, p) +#endif + +/* Exploit the fact that these should never be dereferenced: */ +#ifndef FIRST_TWO_BYTES_ARE_LEGAL_ADDRESSES +# define MZ_EVAL_WAITING_CONSTANT ((Scheme_Object *)0x2) +# define MZ_APPLY_WAITING_CONSTANT ((Scheme_Object *)0x4) +# define MZ_MULTIPLE_VALUES_CONSTANT ((Scheme_Object *)0x6) +#endif + +#ifdef MZ_EVAL_WAITING_CONSTANT +# define SCHEME_EVAL_WAITING MZ_EVAL_WAITING_CONSTANT +# define SCHEME_TAIL_CALL_WAITING MZ_APPLY_WAITING_CONSTANT +# define SCHEME_MULTIPLE_VALUES MZ_MULTIPLE_VALUES_CONSTANT +#else +# define SCHEME_TAIL_CALL_WAITING scheme_tail_call_waiting +# define SCHEME_EVAL_WAITING scheme_eval_waiting +# define SCHEME_MULTIPLE_VALUES scheme_multiple_values +#endif + +#define FAST_NUMBERS /* Force fast numbers */ + +/* Value-access macros */ +#ifdef FAST_NUMBERS +#define SCHEME_TYPE(obj) (SCHEME_INTP(obj)?(Scheme_Type)scheme_integer_type:(obj)->type) +#define _SCHEME_TYPE(obj) ((obj)->type) /* unsafe version */ +#else +#define SCHEME_TYPE(obj) ((obj)->type) +#define _SCHEME_TYPE SCHEME_TYPE +#endif + + +#define SCHEME_CHAR_VAL(obj) (((Scheme_Small_Object *)(obj))->u.char_val) +#ifdef FAST_NUMBERS +#define SCHEME_INT_VAL(obj) (((long)(obj))>>1) +#else +#define SCHEME_INT_VAL(obj) (((Scheme_Small_Object *)(obj))->u.int_val) +#endif +#define SCHEME_DBL_VAL(obj) (((Scheme_Double *)(obj))->double_val) +#ifdef MZ_USE_SINGLE_FLOATS +# define SCHEME_FLT_VAL(obj) (((Scheme_Float *)(obj))->float_val) +# define SCHEME_FLOAT_VAL(obj) (SCHEME_DBLP(obj) ? SCHEME_DBL_VAL(obj) : SCHEME_FLT_VAL(obj)) +#else +# define SCHEME_FLT_VAL SCHEME_DBL_VAL +# define SCHEME_FLOAT_VAL SCHEME_DBL_VAL +#endif +#define SCHEME_STR_VAL(obj) ((obj)->u.str_val.string_val) +#define SCHEME_STRTAG_VAL(obj) ((obj)->u.str_val.tag_val) +#define SCHEME_STRLEN_VAL(obj) ((obj)->u.str_val.tag_val) +#define SCHEME_SYM_VAL(obj) (((Scheme_Symbol *)(obj))->s) +#define SCHEME_SYM_LEN(obj) (((Scheme_Symbol *)(obj))->len) +#define SCHEME_TSYM_VAL(obj) (SCHEME_SYM_VAL(SCHEME_PTR_VAL(obj))) +#define SCHEME_BOX_VAL(obj) (((Scheme_Small_Object *)(obj))->u.ptr_val) +#define SCHEME_PTR_VAL(obj) (((Scheme_Small_Object *)(obj))->u.ptr_val) +#define SCHEME_PTR1_VAL(obj) ((obj)->u.two_ptr_val.ptr1) +#define SCHEME_PTR2_VAL(obj) ((obj)->u.two_ptr_val.ptr2) +#define SCHEME_IPTR_VAL(obj) ((obj)->u.ptr_int_val.ptr) +#define SCHEME_LPTR_VAL(obj) ((obj)->u.ptr_long_val.ptr) +#define SCHEME_INT1_VAL(obj) ((obj)->u.two_int_val.int1) +#define SCHEME_INT2_VAL(obj) ((obj)->u.two_int_val.int2) +#define SCHEME_PINT_VAL(obj) ((obj)->u.ptr_int_val.pint) +#define SCHEME_PLONG_VAL(obj) ((obj)->u.ptr_long_val.pint) +#define SCHEME_PRIM(obj) (((Scheme_Primitive_Proc *)(obj))->prim_val) +#define SCHEME_CLSD_PRIM(obj) (((Scheme_Closed_Primitive_Proc *)(obj))->prim_val) +#define SCHEME_CLSD_PRIM_DATA(obj) (((Scheme_Closed_Primitive_Proc *)(obj))->data) +#define SCHEME_CAR(obj) ((obj)->u.pair_val.car) +#define SCHEME_CDR(obj) ((obj)->u.pair_val.cdr) +#define SCHEME_VEC_SIZE(obj) (((Scheme_Vector *)(obj))->size) +#define SCHEME_VEC_ELS(obj) (((Scheme_Vector *)(obj))->els) +#define SCHEME_VEC_BASE SCHEME_VEC_ELS +#define SCHEME_CLOS_ENV(obj) ((obj)->u.closure_val.env) +#define SCHEME_CLOS_CODE(obj) ((obj)->u.closure_val.code) +#define SCHEME_DEBUG(obj) ((obj)->u.debug_val) +#define SCHEME_OBJ_CLASS(obj) ((Scheme_Object *)((Scheme_Class_Object *)(obj))->sclass) +#define SCHEME_OBJ_DATA(obj) (((Scheme_Class_Object *)(obj))->primdata) +#define SCHEME_OBJ_FLAG(obj) (((Scheme_Class_Object *)(obj))->primflag) +#define SCHEME_INPORT_VAL(obj) (((Scheme_Input_Port)(obj))->port_data) +#define SCHEME_OUTPORT_VAL(obj) (((Scheme_Output_Port)(obj))->port_data) +#define SCHEME_VAR_BUCKET(obj) ((Scheme_Bucket *)(obj)) +#define SCHEME_ENVBOX_VAL(obj) (*((Scheme_Object **)(obj))) + +#define SCHEME_ASSERT(expr,msg) ((expr) ? 1 : (scheme_signal_error(msg), 0)) + +#if !SCHEME_DIRECT_EMBEDDED +#ifdef MZ_REAL_THREADS +#define scheme_current_process (scheme_get_current_process()) +#else +#ifdef LINK_EXTENSIONS_BY_TABLE +#define scheme_current_process (*scheme_current_process_ptr) +#endif +#endif +#endif + +#define scheme_eval_wait_expr (scheme_current_process->ku.eval.wait_expr) +#define scheme_tail_rator (scheme_current_process->ku.apply.tail_rator) +#define scheme_tail_num_rands (scheme_current_process->ku.apply.tail_num_rands) +#define scheme_tail_rands (scheme_current_process->ku.apply.tail_rands) +#define scheme_overflow_k (scheme_current_process->overflow_k) +#define scheme_overflow_reply (scheme_current_process->overflow_reply) +#define scheme_overflow_cont (scheme_current_process->overflow_cont) + +#define scheme_error_buf (scheme_current_process->error_buf) +#define scheme_jumping_to_continuation (scheme_current_process->jumping_to_continuation) +#define scheme_config (scheme_current_process->config) + +#define scheme_multiple_count (scheme_current_process->ku.multiple.count) +#define scheme_multiple_array (scheme_current_process->ku.multiple.array) + +#define scheme_setjmpup(b, s) scheme_setjmpup_relative(b, s, NULL) + +#ifdef MZ_REAL_THREADS +#define scheme_do_eval(r,n,e,f) scheme_do_eval_w_process(r,n,e,f,scheme_current_process) +#else +#define scheme_do_eval_w_process(r,n,e,f,p) scheme_do_eval(r,n,e,f) +#endif +#ifdef MZ_REAL_THREADS +#define scheme_apply(r,n,a) scheme_apply_wp(r,n,a,scheme_current_process) +#define scheme_apply_multi(r,n,a) scheme_apply_multi_wp(r,n,a,scheme_current_process) +#else +#define scheme_apply_wp(r,n,a,p) scheme_apply(r,n,a) +#define scheme_apply_multi_wp(r,n,a,p) scheme_apply_multi(r,n,a) +#endif + +#define _scheme_apply(r,n,rs) scheme_do_eval(r,n,rs,1) +#define _scheme_apply_multi(r,n,rs) scheme_do_eval(r,n,rs,-1) +#define _scheme_apply_wp(r,n,rs,p) scheme_do_eval_w_process(r,n,rs,1,p) +#define _scheme_apply_multi_wp(r,n,rs,p) scheme_do_eval_w_process(r,n,rs,-1,p) +#define _scheme_tail_apply scheme_tail_apply +#define _scheme_tail_apply_wp scheme_tail_apply_wp + +#define _scheme_tail_eval scheme_tail_eval +#define _scheme_tail_eval_wp scheme_tail_eval_wp + +#define _scheme_direct_apply_primitive_multi(prim, argc, argv) \ + (((Scheme_Primitive_Proc *)prim)->prim_val(argc, argv)) +#define _scheme_direct_apply_primitive(prim, argc, argv) \ + scheme_check_one_value(_scheme_direct_apply_primitive_multi(prim, argc, argv)) +#define _scheme_direct_apply_closed_primitive_multi(prim, argc, argv) \ + (((Scheme_Closed_Primitive_Proc *)prim)->prim_val(((Scheme_Closed_Primitive_Proc *)prim)->data, argc, argv)) +#define _scheme_direct_apply_closed_primitive(prim, argc, argv) \ + scheme_check_one_value(_scheme_direct_apply_closed_primitive_multi(prim, argc, argv)) + +#define _scheme_force_value(v) ((v == SCHEME_TAIL_CALL_WAITING) ? scheme_force_value(v) : v) + +#ifdef AGRESSIVE_ZERO_TB +#define scheme_tail_apply_buffer_wp(n, p) ((p)->tail_buffer_set = n, (p)->tail_buffer) +#else +#define scheme_tail_apply_buffer_wp(n, p) ((p)->tail_buffer) +#endif +#define scheme_tail_apply_buffer(n) scheme_tail_apply_buffer_wp(n, scheme_current_process) + +#define _scheme_tail_apply_no_copy_wp_tcw(f, n, args, p, tcw) (p->ku.apply.tail_rator = f, p->ku.apply.tail_rands = args, p->ku.apply.tail_num_rands = n, tcw) +#define _scheme_tail_apply_no_copy_wp(f, n, args, p) _scheme_tail_apply_no_copy_wp_tcw(f, n, args, p, SCHEME_TAIL_CALL_WAITING) +#define _scheme_tail_apply_no_copy(f, n, args) _scheme_tail_apply_no_copy_wp(f, n, args, scheme_current_process) + +#ifndef MZ_REAL_THREADS +#define scheme_process_block_w_process(t,p) scheme_process_block(t) +#else +#define scheme_process_block(t) scheme_process_block_w_process(t,scheme_current_process) +#endif + +#if !SCHEME_DIRECT_EMBEDDED +#ifndef MZ_REAL_THREADS +#ifdef LINK_EXTENSIONS_BY_TABLE +#define scheme_fuel_counter (*scheme_fuel_counter_ptr) +#endif +#endif +#endif + +#ifdef MZ_REAL_THREADS +#define _scheme_check_for_break_wp(penalty, p) \ + { if (((p)->fuel_counter -= penalty) <= 0) scheme_process_block_w_process(0, p); } +#else +#define _scheme_check_for_break_wp(penalty, p) \ + { if ((scheme_fuel_counter -= penalty) <= 0) scheme_process_block_w_process(0, p); } +#endif +#define _scheme_check_for_break(penalty) _scheme_check_for_break_wp(penalty, scheme_current_process) + +#if SCHEME_DIRECT_EMBEDDED +extern Scheme_Object *scheme_eval_waiting; +#define scheme_tail_eval(obj) \ + (scheme_eval_wait_expr = obj, SCHEME_EVAL_WAITING) +#endif + +#define scheme_break_waiting(p) (p->external_break) + +/* Allocation */ +#define scheme_alloc_object() \ + ((Scheme_Object *) scheme_malloc_tagged(sizeof(Scheme_Object))) +#define scheme_alloc_small_object() \ + ((Scheme_Object *) scheme_malloc_tagged(sizeof(Scheme_Small_Object))) +#define scheme_alloc_stubborn_object() \ + ((Scheme_Object *) scheme_malloc_stubborn_tagged(sizeof(Scheme_Object))) +#define scheme_alloc_stubborn_small_object() \ + ((Scheme_Object *) scheme_malloc_stubborn_tagged(sizeof(Scheme_Small_Object))) +#define scheme_alloc_eternal_object() \ + ((Scheme_Object *) scheme_malloc_eternal_tagged(sizeof(Scheme_Object))) +#define scheme_alloc_eternal_small_object() \ + ((Scheme_Object *) scheme_malloc_eternal_tagged(sizeof(Scheme_Small_Object))) + +#ifdef SCHEME_NO_GC +void *scheme_malloc(size_t size); +#define scheme_malloc_atomic scheme_malloc +#define scheme_malloc_stubborn scheme_malloc +#define scheme_malloc_uncollectable scheme_malloc +#else +#define scheme_malloc GC_malloc +#define scheme_malloc_atomic GC_malloc_atomic +#define scheme_malloc_stubborn GC_malloc_stubborn +#define scheme_malloc_uncollectable GC_malloc_uncollectable +#endif + +#ifdef USE_MEMORY_TRACING +#define USE_TAGGED_ALLOCATION +#define MEMORY_COUNTING_ON +#endif + +#ifdef USE_TAGGED_ALLOCATION +extern void *scheme_malloc_tagged(size_t); +extern void *scheme_malloc_atomic_tagged(size_t); +extern void *scheme_malloc_stubborn_tagged(size_t); +extern void *scheme_malloc_eternal_tagged(size_t); +extern void *scheme_malloc_uncollectable_tagged(size_t); +extern void *scheme_malloc_envunbox(size_t); +#else +#define scheme_malloc_tagged scheme_malloc +#define scheme_malloc_atomic_tagged scheme_malloc_atomic +#define scheme_malloc_stubborn_tagged scheme_malloc_stubborn +#define scheme_malloc_eternal_tagged scheme_malloc_eternal +#define scheme_malloc_uncollectable_tagged scheme_malloc_uncollectable +#define scheme_malloc_envunbox scheme_malloc +#endif + +#ifdef FAST_NUMBERS +#define scheme_make_integer(i) ((Scheme_Object *)((((long)i) << 1) | 0x1)) +#else +#define scheme_make_integer scheme_make_integer_value +#endif +#define scheme_make_character(ch) (scheme_char_constants[(unsigned char)(ch)]) + +#define scheme_new_frame(n) scheme_new_special_frame(n, 0) +#define scheme_extend_env(f, e) (f->basic.next = e, f) +#define scheme_next_frame(e) ((e)->basic.next) +#define scheme_settable_frame(f, s) ((f)->basic.has_set_bang = (s)) +#define scheme_get_frame_settable(f) ((f)->basic.has_set_bang) +#define scheme_get_binding(f, n) ((f)->values[n]) + +#define SNF_FOR_TS 0x1 +#define SNF_PIPE_QUOTE 0x2 +#define SNF_NO_PIPE_QUOTE 0x4 + +#if SCHEME_DIRECT_EMBEDDED + +#if defined(_IBMR2) +extern long scheme_stackbottom; +#endif + +extern int scheme_defining_primitives; + +/* These flags must be set before MzScheme is started: */ +extern int scheme_case_sensitive; /* Defaults to 0 */ +extern int scheme_constant_builtins; /* Defaults to 0 */ +extern int scheme_no_keywords; /* Defaults to 0 */ +extern int scheme_allow_set_undefined; /* Defaults to 0 */ +extern int scheme_escape_continuations_only; /* Defaults to 0 */ +extern int scheme_secure_primitive_exn; /* Defaults to 0 */ +extern int scheme_allow_cond_auto_else; /* Defaults to 1 */ +extern int scheme_square_brackets_are_parens; /* Defaults to 1 */ +extern int scheme_curly_braces_are_parens; /* Defaults to 1 */ +extern int scheme_hash_percent_syntax_only; /* Defaults to 0 */ + +#ifdef MZ_REAL_THREADS +Scheme_Process *scheme_get_current_process(); +#define scheme_current_process (SCHEME_GET_CURRENT_PROCESS()) +#else +extern Scheme_Process *scheme_current_process; +#endif +extern Scheme_Process *scheme_first_process; + +/* Set these global hooks: */ +extern void (*scheme_exit)(int v); +extern void (*scheme_console_printf)(char *str, ...); +extern void (*scheme_sleep)(float seconds, void *fds); +extern void (*scheme_notify_multithread)(int on); +extern void (*scheme_wakeup_on_input)(void *fds); +extern int (*scheme_check_for_break)(void); +#ifdef USE_WIN32_THREADS +extern void (*scheme_suspend_main_thread)(void); +int scheme_set_in_main_thread(void); +void scheme_restore_nonmain_thread(void); +#endif +#ifdef MAC_FILE_SYSTEM +extern long scheme_creator_id; +#endif +extern void *(*scheme_get_sema_callback_context)(void); + +extern Scheme_Object *(*scheme_make_stdin)(void); +extern Scheme_Object *(*scheme_make_stdout)(void); +extern Scheme_Object *(*scheme_make_stderr)(void); + +/* Initialization */ +Scheme_Env *scheme_basic_env(void); + +void scheme_check_threads(void); +void *scheme_check_sema_callbacks(int (*)(void *, void*), void *, int check_only); +void scheme_remove_sema_callbacks(int (*)(void *, void*), void *); +void scheme_wake_up(void); + +/* image dump enabling startup: */ +int scheme_image_main(int argc, char **argv); +extern int (*scheme_actual_main)(int argc, char **argv); + +/* All functions & global constants prototyped here */ +#ifdef INCLUDE_WITHOUT_PATHS +#include "schemef.h" +#else +#include "../src/schemef.h" +#endif + +#else + +#ifdef LINK_EXTENSIONS_BY_TABLE +/* Constants and function prototypes as function pointers in a struct: */ +#ifdef INCLUDE_WITHOUT_PATHS +#include "schemex.h" +#else +#include "../src/schemex.h" +#endif + +extern Scheme_Extension_Table *scheme_extension_table; + +/* Macro mapping names to record access */ +#ifdef INCLUDE_WITHOUT_PATHS +#include "schemexm.h" +#else +#include "../src/schemexm.h" +#endif + +#else + +/* Not LINK_EXTENSIONS_BY_TABLE */ +#ifdef INCLUDE_WITHOUT_PATHS +#include "schemef.h" +#else +#include "../src/schemef.h" +#endif + +#endif + +#endif + +#ifndef USE_MZ_SETJMP +#ifdef WIN32_SETJMP_HACK /* See comment in setjmpup.c */ +#define scheme_longjmp(b, v) \ + { jmp_buf hack; setjmp(hack); (b)->j_excep = hack->j_excep; \ + longjmp(b, v); } +#else +#define scheme_longjmp(b, v) longjmp(b, v) +#endif +#define scheme_setjmp(b) setjmp(b) +#endif + +#define SAME_PTR(a, b) ((a) == (b)) +#define NOT_SAME_PTR(a, b) ((a) != (b)) + +#define SCHEME_STRUCT_NO_TYPE 0x01 +#define SCHEME_STRUCT_NO_CONSTR 0x02 +#define SCHEME_STRUCT_NO_PRED 0x04 +#define SCHEME_STRUCT_NO_GET 0x08 +#define SCHEME_STRUCT_NO_SET 0x10 + +#define SAME_OBJ SAME_PTR +#define NOT_SAME_OBJ NOT_SAME_PTR + +#define SAME_TYPE(a, b) ((Scheme_Type)(a) == (Scheme_Type)(b)) +#define NOT_SAME_TYPE(a, b) ((Scheme_Type)(a) != (Scheme_Type)(b)) + +/* convenience macros */ +#define SCHEME_CHARP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_char_type) +#ifdef FAST_NUMBERS +#define SCHEME_INTP(obj) (((long)obj) & 0x1) +#else +#define SCHEME_INTP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_integer_type) +#endif +#define SCHEME_DBLP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_double_type) +#ifdef MZ_USE_SINGLE_FLOATS +# define SCHEME_FLTP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_float_type) +# define SCHEME_FLOATP(obj) (SCHEME_FLTP(obj) || SCHEME_DBLP(obj)) +#else +# define SCHEME_FLTP SCHEME_DBLP +# define SCHEME_FLOATP SCHEME_DBLP +#endif +#define SCHEME_BIGNUMP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_bignum_type) +#define SCHEME_RATIONALP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_rational_type) +#define SCHEME_COMPLEXP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_complex_type) +#define SCHEME_EXACT_INTEGERP(obj) (SCHEME_INTP(obj) || (_SCHEME_TYPE(obj) == scheme_bignum_type)) +#define SCHEME_EXACT_REALP(obj) (SCHEME_INTP(obj) || (_SCHEME_TYPE(obj) == scheme_bignum_type) || (_SCHEME_TYPE(obj) == scheme_rational_type)) +#define SCHEME_REALP(obj) (SCHEME_INTP(obj) || ((_SCHEME_TYPE(obj) >= scheme_bignum_type) && (_SCHEME_TYPE(obj) <= scheme_double_type))) +#define SCHEME_NUMBERP(obj) (SCHEME_INTP(obj) || ((_SCHEME_TYPE(obj) >= scheme_bignum_type) && (_SCHEME_TYPE(obj) <= scheme_complex_type))) +#define SCHEME_STRINGP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_string_type) +#define SCHEME_SYMBOLP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_symbol_type) +#define SCHEME_TSYMBOLP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_type_symbol_type) +#define SCHEME_BOOLP(obj) (SAME_OBJ(obj, scheme_true) || SAME_OBJ(obj, scheme_false)) +#define SCHEME_FALSEP(obj) SAME_OBJ((obj), scheme_false) +#define SCHEME_TRUEP(obj) (!SCHEME_FALSEP(obj)) +#define SCHEME_SYNTAXP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_syntax_compiler_type) +#define SCHEME_PRIMP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_prim_type) +#define SCHEME_CLSD_PRIMP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_closed_prim_type) +#define SCHEME_CONTP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_cont_type) +#define SCHEME_ECONTP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_escaping_cont_type) +#define SCHEME_NULLP(obj) SAME_OBJ(obj, scheme_null) +#define SCHEME_PAIRP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_pair_type) +#define SCHEME_LISTP(obj) (SCHEME_NULLP(obj) || SCHEME_PAIRP(obj)) +#define SCHEME_BOXP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_box_type) +#define SCHEME_HASHTP(obj) SAME_TYPE(SCHEME_TYPE(obj),scheme_hash_table_type) +#define SCHEME_VECTORP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_vector_type) +#define SCHEME_STRUCT_PROCP(obj) (SCHEME_CLSD_PRIMP(obj) && (((Scheme_Closed_Primitive_Proc *)obj)->flags & SCHEME_PRIM_IS_STRUCT_PROC)) +#define SCHEME_GENERICP(obj) (SCHEME_CLSD_PRIMP(obj) && (((Scheme_Closed_Primitive_Proc *)obj)->flags & SCHEME_PRIM_IS_GENERIC)) +#define SCHEME_STRUCTP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_structure_type) +#define SCHEME_STRUCT_TYPEP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_struct_type_type) +#define SCHEME_CLOSUREP(obj) (SAME_TYPE(SCHEME_TYPE(obj), scheme_closure_type) || SAME_TYPE(SCHEME_TYPE(obj), scheme_linked_closure_type) || SAME_TYPE(SCHEME_TYPE(obj), scheme_case_closure_type)) +#define SCHEME_PROCP(obj) (SCHEME_PRIMP(obj) || SCHEME_CLSD_PRIMP(obj) || SCHEME_CLOSUREP(obj) || SCHEME_CONTP(obj) || SCHEME_ECONTP(obj)) +#define SCHEME_INPORTP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_input_port_type) +#define SCHEME_OUTPORTP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_output_port_type) +#define SCHEME_EOFP(obj) SAME_OBJ((obj), scheme_eof) +#define SCHEME_PROMP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_promise_type) +#define SCHEME_DEBUGP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_debug_handle_type) +#define SCHEME_PROCESSP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_process_type) +#define SCHEME_MANAGERP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_manager_type) +#define SCHEME_SEMAP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_sema_type) +#define SCHEME_OBJP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_object_type) +#define SCHEME_CLASSP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_class_type) +#define SCHEME_INTERFACEP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_interface_type) +#define SCHEME_VOIDP(obj) SAME_OBJ((obj), scheme_void) +#define SCHEME_DIVARP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_delayed_ivar_type) +#define SCHEME_WEAKP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_weak_box_type) +#define SCHEME_GENDATAP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_generic_data_type) +#define SCHEME_UNITP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_unit_type) +#define SCHEME_CONFIGP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_config_type) + +/* other */ +#define SCHEME_CADR(obj) (SCHEME_CAR (SCHEME_CDR (obj))) +#define SCHEME_CAAR(obj) (SCHEME_CAR (SCHEME_CAR (obj))) +#define SCHEME_CDDR(obj) (SCHEME_CDR (SCHEME_CDR (obj))) +#define SCHEME_IPORT_NAME(obj) (((Scheme_Input_Port *)obj)->name) + +#ifdef __cplusplus +}; +#endif + +#endif /* ! SCHEME_H */ + diff --git a/collects/mzscheme/include/schemef.h b/collects/mzscheme/include/schemef.h new file mode 100644 index 0000000..173f382 --- /dev/null +++ b/collects/mzscheme/include/schemef.h @@ -0,0 +1,558 @@ +/* + MzScheme + Copyright (c) 1995 Matthew Flatt + All rights reserved. + + Please see the full copyright in the documentation. + + libscheme + Copyright (c) 1994 Brent Benson + All rights reserved. +*/ + +/* MzScheme function prototypes */ +/* No macros should go in this file; it is used both to + prototype functions, and as a parsing source for + declaring scheme_extension_table */ + +/* The scheme_extension_table parser is touchy: don't leave a space + between a function name and it's opening parameter parenthesis. */ + +/* After this START tag, all comments should start & end on same line */ + +/* START */ + +/* Call/cc utilities */ +void scheme_init_jmpup_buf(Scheme_Jumpup_Buf *b); +int scheme_setjmpup_relative(Scheme_Jumpup_Buf *b, void *start, + Scheme_Jumpup_Buf *cont); +void scheme_longjmpup(Scheme_Jumpup_Buf *b); + +#ifdef USE_MZ_SETJMP +int scheme_setjmp(jmp_buf b); +void scheme_longjmp(jmp_buf b, int v); +#endif + +/* Parameters */ +Scheme_Object *scheme_make_config(Scheme_Config *base); +Scheme_Object *scheme_branch_config(void); +int scheme_new_param(void); + +Scheme_Object *scheme_param_config(char *name, long pos, + int argc, Scheme_Object **argv, + int arity, + Scheme_Prim *check, char *expected, + int isbool); +Scheme_Object *scheme_register_parameter(Scheme_Prim *function, char *name, int which); +Scheme_Env *scheme_get_env(Scheme_Config *config); + +/* Processes */ +#ifdef MZ_REAL_THREADS +Scheme_Process *scheme_get_current_process(); +#else +#ifndef LINK_EXTENSIONS_BY_TABLE +extern Scheme_Process *scheme_current_process; +extern int scheme_fuel_counter; +#else +extern Scheme_Process **scheme_current_process_ptr; +extern int *scheme_fuel_counter_ptr; +#endif +#endif + +#ifndef NO_SCHEME_THREADS +Scheme_Object *scheme_make_namespace(int argc, Scheme_Object *argv[]); +Scheme_Object *scheme_thread(Scheme_Object *thunk, Scheme_Config *config); +void scheme_break_thread(Scheme_Process *p); +void scheme_kill_thread(Scheme_Process *p); +#endif + +#ifndef MZ_REAL_THREADS +void scheme_process_block(float sleep_time); +void scheme_swap_process(Scheme_Process *process); +#else +void scheme_process_block_w_process(float sleep_time, Scheme_Process *p); +#endif + +int scheme_block_until(int (*f)(Scheme_Object *), void (*fdfd)(Scheme_Object *, void *), void *, float); + +int scheme_in_main_thread(void); + +int scheme_tls_allocate(); +void scheme_tls_set(int pos, void *v); +void *scheme_tls_get(int pos); + +void scheme_add_namespace_option(Scheme_Object *key, void (*f)(Scheme_Env *)); + +Scheme_Manager *scheme_make_manager(Scheme_Manager *); +Scheme_Manager_Reference *scheme_add_managed(Scheme_Manager *m, Scheme_Object *o, + Scheme_Close_Manager_Client *f, void *data, + int strong); +void scheme_remove_managed(Scheme_Manager_Reference *m, Scheme_Object *o); +void scheme_close_managed(Scheme_Manager *m); + +/* error handling */ +void scheme_signal_error(char *msg, ...); +void scheme_raise_exn(int exnid, ...); +void scheme_warning(char *msg, ...); + +void scheme_wrong_count(const char *name, int minc, int maxc, int argc, + Scheme_Object **argv); +void scheme_case_lambda_wrong_count(const char *name, int argc, + Scheme_Object **argv, int count, ...); +void scheme_wrong_type(const char *name, const char *expected, + int which, int argc, + Scheme_Object **argv); +void scheme_wrong_return_arity(const char *where, + int expected, int got, + Scheme_Object **argv, + const char *context_detail, ...); +void scheme_unbound_global(Scheme_Object *name); + +Scheme_Object *scheme_dynamic_wind(void (*pre)(void *), + Scheme_Object *(*act)(void *), + void (*post)(void *), + Scheme_Object *(*jmp_handler)(void *), + void *data); + +/* Types */ +Scheme_Type scheme_make_type(const char *name); + +/* Type readers & writers for compiled code data */ +void scheme_install_type_reader(Scheme_Type type, Scheme_Type_Reader f); +void scheme_install_type_writer(Scheme_Type type, Scheme_Type_Writer f); + +/* Constants */ +extern Scheme_Object *scheme_eof; +extern Scheme_Object *scheme_null; +extern Scheme_Object *scheme_true; +extern Scheme_Object *scheme_false; +extern Scheme_Object *scheme_void; +extern Scheme_Object *scheme_undefined; +extern Scheme_Object *scheme_tail_call_waiting; +extern Scheme_Object *scheme_multiple_values; + +/* Basics */ +Scheme_Object *scheme_eval(Scheme_Object *obj, Scheme_Env *env); +Scheme_Object *scheme_eval_multi(Scheme_Object *obj, Scheme_Env *env); +Scheme_Object *scheme_eval_compiled(Scheme_Object *obj); +Scheme_Object *scheme_eval_compiled_multi(Scheme_Object *obj); +Scheme_Object *_scheme_eval_compiled(Scheme_Object *obj); +Scheme_Object *_scheme_eval_compiled_multi(Scheme_Object *obj); +#ifndef MZ_REAL_THREADS +Scheme_Object *scheme_apply(Scheme_Object *rator, int num_rands, Scheme_Object **rands); +Scheme_Object *scheme_apply_multi(Scheme_Object *rator, int num_rands, Scheme_Object **rands); +#else +Scheme_Object *scheme_apply_wp(Scheme_Object *rator, int num_rands, Scheme_Object **rands, + Scheme_Process *p); +Scheme_Object *scheme_apply_multi_wp(Scheme_Object *rator, int num_rands, Scheme_Object **rands, + Scheme_Process *p); +#endif +Scheme_Object *scheme_apply_to_list(Scheme_Object *rator, Scheme_Object *argss); +Scheme_Object *scheme_eval_string(const char *str, Scheme_Env *env); +Scheme_Object *scheme_eval_string_all(const char *str, Scheme_Env *env, int all); + +Scheme_Object *_scheme_apply_known_closed_prim(Scheme_Object *rator, int argc, + Scheme_Object **argv); +Scheme_Object *_scheme_apply_known_closed_prim_multi(Scheme_Object *rator, int argc, + Scheme_Object **argv); + +Scheme_Object *scheme_values(int c, Scheme_Object **v); + +Scheme_Object *scheme_check_one_value(Scheme_Object *v); + +/* Tail calls - only use these when you're writing new functions/syntax */ +Scheme_Object *scheme_tail_apply(Scheme_Object *f, int n, Scheme_Object **arg); +Scheme_Object *scheme_tail_apply_no_copy(Scheme_Object *f, int n, Scheme_Object **arg); +Scheme_Object *scheme_tail_apply_to_list(Scheme_Object *f, Scheme_Object *l); + +Scheme_Object *scheme_tail_eval_expr(Scheme_Object *obj); + +void scheme_set_tail_buffer_size(int s); +Scheme_Object *scheme_force_value(Scheme_Object *); + +/* Internal */ +#ifndef MZ_REAL_THREADS +Scheme_Object *scheme_do_eval(Scheme_Object *obj, int _num_rands, Scheme_Object **rands, int val); +#else +Scheme_Object *scheme_do_eval_w_process(Scheme_Object *obj, int _num_rands, Scheme_Object **rands, int val, Scheme_Process *p); +#endif + +/* Allocation */ +#ifndef SCHEME_NO_GC +#ifndef SCHEME_NO_GC_PROTO +void *GC_malloc(size_t size_in_bytes); +void *GC_malloc_atomic(size_t size_in_bytes); +void *GC_malloc_stubborn(size_t size_in_bytes); +void *GC_malloc_uncollectable(size_t size_in_bytes); +#endif +#endif + +void *scheme_malloc_eternal(size_t n); +void scheme_end_stubborn_change(void *p); + +void *scheme_calloc(size_t num, size_t size); + +char *scheme_strdup(const char *str); +char *scheme_strdup_eternal(const char *str); + +void *scheme_malloc_fail_ok(void *(*f)(size_t), size_t); + +void scheme_weak_reference(void **p); +void scheme_weak_reference_indirect(void **p, void *v); +void scheme_add_finalizer(void *p, void (*f)(void *p, void *data), void *data); +void scheme_add_scheme_finalizer(void *p, void (*f)(void *p, void *data), void *data); +void scheme_register_finalizer(void *p, + void (*f)(void *p, void *data), void *data, + void (**oldf)(void *p, void *data), + void **olddata); + +void scheme_dont_gc_ptr(void *p); +void scheme_gc_ptr_ok(void *p); + +void scheme_collect_garbage(void); + +/* Hash table */ +Scheme_Hash_Table *scheme_hash_table(int size, int type, + int w_const, int forever); +void scheme_add_to_table(Scheme_Hash_Table *table, const char *key, void *val, int); +void scheme_change_in_table(Scheme_Hash_Table *table, const char *key, void *new_val); +void *scheme_lookup_in_table(Scheme_Hash_Table *table, const char *key); +Scheme_Bucket *scheme_bucket_from_table(Scheme_Hash_Table *table, const char *key); + +/* Constructors */ +Scheme_Object *scheme_make_prim(Scheme_Prim *prim); +Scheme_Object *scheme_make_noneternal_prim(Scheme_Prim *prim); +Scheme_Object *scheme_make_closed_prim(Scheme_Closed_Prim *prim, void *data); +Scheme_Object *scheme_make_prim_w_arity(Scheme_Prim *prim, const char *name, + short mina, short maxa); +Scheme_Object *scheme_make_folding_prim(Scheme_Prim *prim, + const char *name, + short mina, short maxa, + short functional); +Scheme_Object *scheme_make_noneternal_prim_w_arity(Scheme_Prim *prim, + const char *name, + short mina, short maxa); +Scheme_Object *scheme_make_closed_prim_w_arity(Scheme_Closed_Prim *prim, + void *data, const char *name, + short mina, short maxa); +Scheme_Object *scheme_make_folding_closed_prim(Scheme_Closed_Prim *prim, + void *data, const char *name, + short mina, short maxa, + short functional); + +Scheme_Object *scheme_make_closure(Scheme_Env *env, Scheme_Object *code); +Scheme_Object *scheme_make_pair(Scheme_Object *car, Scheme_Object *cdr); +Scheme_Object *scheme_make_string(const char *chars); +Scheme_Object *scheme_make_sized_string(char *chars, long len, int copy); +Scheme_Object *scheme_make_string_without_copying(char *chars); +Scheme_Object *scheme_alloc_string(int size, char fill); +Scheme_Object *scheme_append_string(Scheme_Object *, Scheme_Object *); +Scheme_Object *scheme_make_vector(int size, Scheme_Object *fill); +Scheme_Object *scheme_make_integer_value(long i); +Scheme_Object *scheme_make_integer_value_from_unsigned(unsigned long i); +Scheme_Object *scheme_make_double(double d); +#ifdef MZ_USE_SINGLE_FLOATS +Scheme_Object *scheme_make_float(float f); +#endif +Scheme_Object *scheme_make_char(char ch); +Scheme_Object *scheme_make_promise(Scheme_Object *expr, Scheme_Env *env); +Scheme_Object *scheme_make_promise_from_thunk(Scheme_Object *expr); +#ifndef NO_SCHEME_THREADS +Scheme_Object *scheme_make_sema(long v); +#endif +void scheme_post_sema(Scheme_Object *o); +int scheme_wait_sema(Scheme_Object *o, int just_try); +extern Scheme_Object **scheme_char_constants; + +int scheme_get_int_val(Scheme_Object *o, long *v); +int scheme_get_unsigned_int_val(Scheme_Object *o, unsigned long *v); + +const char *scheme_get_proc_name(Scheme_Object *p, int *len, int for_error); + +/* Bignums */ +Scheme_Object *scheme_make_bignum(long v); +Scheme_Object *scheme_make_bignum_from_unsigned(unsigned long v); +double scheme_bignum_to_double(const Scheme_Object *n); +Scheme_Object *scheme_bignum_from_double(double d); +#ifdef MZ_USE_SINGLE_FLOATS +float scheme_bignum_to_float(const Scheme_Object *n); +Scheme_Object *scheme_bignum_from_float(float d); +#else +# define scheme_bignum_to_float scheme_bignum_to_double +# define scheme_bignum_from_float scheme_bignum_from_double +#endif +char *scheme_bignum_to_string(const Scheme_Object *n, int radix); +Scheme_Object *scheme_read_bignum(const char *str, int radix); +Scheme_Object *scheme_bignum_normalize(const Scheme_Object *n); + +long scheme_double_to_int(const char *where, double d); + +/* Rationals */ +Scheme_Object *scheme_make_rational(const Scheme_Object *r, const Scheme_Object *d); +double scheme_rational_to_double(const Scheme_Object *n); +Scheme_Object *scheme_rational_from_double(double d); +#ifdef MZ_USE_SINGLE_FLOATS +float scheme_rational_to_float(const Scheme_Object *n); +Scheme_Object *scheme_rational_from_float(float d); +#else +# define scheme_rational_to_float scheme_rational_to_double +# define scheme_rational_from_float scheme_rational_from_double +#endif +Scheme_Object *scheme_rational_normalize(const Scheme_Object *n); +Scheme_Object *scheme_rational_numerator(const Scheme_Object *n); +Scheme_Object *scheme_rational_denominator(const Scheme_Object *n); + +/* Complex */ +Scheme_Object *scheme_make_complex(const Scheme_Object *r, const Scheme_Object *i); +Scheme_Object *scheme_complex_normalize(const Scheme_Object *n); +Scheme_Object *scheme_complex_real_part(const Scheme_Object *n); +Scheme_Object *scheme_complex_imaginary_part(const Scheme_Object *n); + +/* Exact/inexact: */ +int scheme_is_exact(Scheme_Object *n); +int scheme_is_inexact(Scheme_Object *n); + +/* Macro and syntax expansion */ +Scheme_Object *scheme_expand(Scheme_Object *form, Scheme_Env *env); + +/* Compilation */ +Scheme_Object *scheme_compile(Scheme_Object *form, Scheme_Env *env, int writeable); +Scheme_Object *scheme_make_promise_value(Scheme_Object *compiled_expr); + +/* Ports */ +Scheme_Object *scheme_read(Scheme_Object *port); +void scheme_write(Scheme_Object *obj, Scheme_Object *port); +void scheme_display(Scheme_Object *obj, Scheme_Object *port); +void scheme_write_w_max(Scheme_Object *obj, Scheme_Object *port, long maxl); +void scheme_display_w_max(Scheme_Object *obj, Scheme_Object *port, long maxl); +void scheme_write_string(const char *str, long len, Scheme_Object *port); +char *scheme_write_to_string(Scheme_Object *obj, long *len); +char *scheme_display_to_string(Scheme_Object *obj, long *len); +char *scheme_write_to_string_w_max(Scheme_Object *obj, long *len, long maxl); +char *scheme_display_to_string_w_max(Scheme_Object *obj, long *len, long maxl); +void scheme_debug_print(Scheme_Object *obj); +void scheme_flush_output(Scheme_Object *port); + +char *scheme_format(char *format, int flen, int argc, Scheme_Object **argv, int *rlen); +void scheme_printf(char *format, int flen, int argc, Scheme_Object **argv); + +int scheme_getc(Scheme_Object *port); +void scheme_ungetc(int ch, Scheme_Object *port); +int scheme_char_ready(Scheme_Object *port); +void scheme_need_wakeup(Scheme_Object *port, void *fds); +long scheme_get_chars(Scheme_Object *port, long size, char *buffer); +long scheme_tell(Scheme_Object *port); +long scheme_output_tell(Scheme_Object *port); +long scheme_tell_line(Scheme_Object *port); +void scheme_close_input_port(Scheme_Object *port); +void scheme_close_output_port(Scheme_Object *port); +int scheme_are_all_chars_ready(Scheme_Object *port); + +Scheme_Object *scheme_make_port_type(const char *name); +Scheme_Input_Port *scheme_make_input_port(Scheme_Object *subtype, void *data, + int (*getc_fun)(Scheme_Input_Port*), + int (*char_ready_fun) + (Scheme_Input_Port*), + void (*close_fun) + (Scheme_Input_Port*), + void (*need_wakeup_fun) + (Scheme_Input_Port*, void *), + int must_close); +Scheme_Output_Port *scheme_make_output_port(Scheme_Object *subtype, + void *data, + void (*write_string_fun) + (char*,long, Scheme_Output_Port*), + void (*close_fun) + (Scheme_Output_Port*), + int must_close); + +Scheme_Object *scheme_make_file_input_port(FILE *fp); +Scheme_Object *scheme_make_named_file_input_port(FILE *fp, const char *filename); +Scheme_Object *scheme_make_file_output_port(FILE *fp); + +Scheme_Object *scheme_make_string_input_port(const char *str); +Scheme_Object *scheme_make_sized_string_input_port(const char *str, long len); +Scheme_Object *scheme_make_string_output_port(); +char *scheme_get_string_output(Scheme_Object *); +char *scheme_get_sized_string_output(Scheme_Object *, int *len); + +void scheme_pipe(Scheme_Object **write, Scheme_Object **read); + +int scheme_file_exists(char *filename); +int scheme_directory_exists(char *dirname); +char *scheme_expand_filename(char* filename, int ilen, char *errorin, int *ex); + +char *scheme_getcwd(char *buf, int buflen, int *actlen, int noexn); +int scheme_setcwd(char *buf, int noexn); +char *scheme_getdrive(void); + +Scheme_Object *scheme_split_pathname(int argc, Scheme_Object **argv); +Scheme_Object *scheme_build_pathname(int argc, Scheme_Object **argv); + +void *scheme_alloc_fdset_array(int count, int permanent); +void *scheme_init_fdset_array(void *fdarray, int count); +void *scheme_get_fdset(void *fdarray, int pos); +void scheme_fdzero(void *fd); +void scheme_fdset(void *fd, int pos); +void scheme_fdclr(void *fd, int pos); +int scheme_fdisset(void *fd, int pos); + +/* environment */ +void scheme_add_global(const char *name, Scheme_Object *val, Scheme_Env *env); +void scheme_add_global_constant(const char *name, Scheme_Object *v, Scheme_Env *env); +void scheme_add_global_keyword(const char *name, Scheme_Object *v, Scheme_Env *env); +void scheme_remove_global(const char *name, Scheme_Env *env); +void scheme_remove_global_constant(const char *name, Scheme_Env *env); + +void scheme_add_global_symbol(Scheme_Object *name, Scheme_Object *val, + Scheme_Env *env); +void scheme_remove_global_symbol(Scheme_Object *name, Scheme_Env *env); +void scheme_add_global_constant_symbol(Scheme_Object *name, Scheme_Object *v, Scheme_Env *env); + +void scheme_constant(Scheme_Object *sym, Scheme_Env *env); +void scheme_set_keyword(Scheme_Object *name, Scheme_Env *env); + +Scheme_Object *scheme_make_envunbox(Scheme_Object *value); + +Scheme_Object *scheme_lookup_global(Scheme_Object *symbol, Scheme_Env *env); +Scheme_Bucket *scheme_global_bucket(Scheme_Object *symbol, Scheme_Env *env); + +void scheme_set_global_bucket(char *proc, Scheme_Bucket *var, Scheme_Object *val, + int set_undef); + +/* Symbols */ +Scheme_Object *scheme_intern_symbol(const char *name); +Scheme_Object *scheme_intern_exact_symbol(const char *name, int len); +Scheme_Object *scheme_make_symbol(const char *name); /* Make uninterned */ +Scheme_Object *scheme_make_exact_symbol(const char *name, int len); /* Exact case */ +const char *scheme_symbol_name(Scheme_Object *sym); +const char *scheme_symbol_name_and_size(Scheme_Object *sym, int *l, int flags); + +/* Type Symbols */ +Scheme_Object *scheme_intern_type_symbol(Scheme_Object *sym); +Scheme_Object *scheme_make_type_symbol(Scheme_Object *sym);/*Make uninterned */ + +/* Structures */ +Scheme_Object **scheme_make_struct_values(Scheme_Object *struct_type, + Scheme_Object **names, + int count, int flags); +Scheme_Object **scheme_make_struct_names(Scheme_Object *base, + Scheme_Object *field_names, + int flags, int *count_out); +Scheme_Object *scheme_make_struct_type(Scheme_Object *base, + Scheme_Object *parent, + int num_fields); +Scheme_Object *scheme_make_struct_instance(Scheme_Object *stype, + int argc, + Scheme_Object **argv); +int scheme_is_struct_instance(Scheme_Object *type, Scheme_Object *v); + +#ifndef NO_OBJECT_SYSTEM +/* Objects */ +Scheme_Object *scheme_make_class(const char *name, Scheme_Object *sup, + Scheme_Method_Prim *init, int num_methods); +void scheme_add_method(Scheme_Object *cl, const char *name, + Scheme_Method_Prim *f); +void scheme_add_method_w_arity(Scheme_Object *cl, const char *name, + Scheme_Method_Prim *f, int mina, int maxa); +void scheme_made_class(Scheme_Object *cl); + +Scheme_Object *scheme_make_object(Scheme_Object *sclass, + int argc, Scheme_Object **argv); +Scheme_Object *scheme_make_uninited_object(Scheme_Object *sclass); + +Scheme_Object *scheme_find_ivar(Scheme_Object *obj, Scheme_Object *sym, int force); + +int scheme_is_subclass(Scheme_Object *sub, Scheme_Object *parent); +int scheme_is_implementation(Scheme_Object *cl, Scheme_Object *in); +int scheme_is_interface_extension(Scheme_Object *n1, Scheme_Object *n2); +int scheme_is_a(Scheme_Object *obj, Scheme_Object *sclass); +const char *scheme_get_class_name(Scheme_Object *cl, int *len); +const char *scheme_get_interface_name(Scheme_Object *cl, int *len); + +struct Scheme_Class_Assembly *scheme_make_class_assembly(const char *name, int n_interfaces, + int n_public, Scheme_Object **names, + int n_inh, Scheme_Object **inheritd, + int n_ren, Scheme_Object **renames, + int mina, int maxa, + Scheme_Instance_Init_Proc *initproc); +Scheme_Object *scheme_create_class(struct Scheme_Class_Assembly *a, void *data, + Scheme_Object *super, Scheme_Object **interfaces); + +struct Scheme_Interface_Assembly *scheme_make_interface_assembly(const char *name, int n_supers, + int n_names, + Scheme_Object **names); +Scheme_Object *scheme_create_interface(struct Scheme_Interface_Assembly *a, + Scheme_Object **supers); + +Scheme_Object *scheme_apply_generic_data(Scheme_Object *gdata, + Scheme_Object *sobj, int force); +Scheme_Object *scheme_get_generic_data(Scheme_Object *cl, + Scheme_Object *name); +#endif + +/* Units */ +Scheme_Object *scheme_invoke_unit(Scheme_Object *functor, int num_ins, + Scheme_Object **ins, Scheme_Object **anchors, + int open, const char *name, int tail, int multi); + +Scheme_Object *scheme_assemble_compound_unit(Scheme_Object *imports, + Scheme_Object *links, + Scheme_Object *exports); +Scheme_Object *scheme_make_compound_unit(Scheme_Object *data_in, + Scheme_Object **subs_in); + +const char *scheme_get_unit_name(Scheme_Object *cl, int *len); + +/* Misc */ +int scheme_eq(Scheme_Object *obj1, Scheme_Object *obj2); +int scheme_eqv(Scheme_Object *obj1, Scheme_Object *obj2); +int scheme_equal(Scheme_Object *obj1, Scheme_Object *obj2); + +Scheme_Object *scheme_build_list(int argc, Scheme_Object **argv); + +int scheme_list_length(Scheme_Object *list); +int scheme_proper_list_length(Scheme_Object *list); + +Scheme_Object *scheme_alloc_list(int size); +Scheme_Object *scheme_map_1(Scheme_Object *(*f)(Scheme_Object*), + Scheme_Object *l); + +Scheme_Object *scheme_car(Scheme_Object *pair); +Scheme_Object *scheme_cdr(Scheme_Object *pair); +Scheme_Object *scheme_cadr(Scheme_Object *pair); +Scheme_Object *scheme_caddr(Scheme_Object *pair); + +Scheme_Object *scheme_vector_to_list(Scheme_Object *vec); +Scheme_Object *scheme_list_to_vector(Scheme_Object *list); + +Scheme_Object *scheme_append(Scheme_Object *lstx, Scheme_Object *lsty); + +Scheme_Object *scheme_box(Scheme_Object *v); +Scheme_Object *scheme_unbox(Scheme_Object *obj); +void scheme_set_box(Scheme_Object *b, Scheme_Object *v); + +Scheme_Object *scheme_make_weak_box(Scheme_Object *v); + +Scheme_Object *scheme_load(const char *file); +Scheme_Object *scheme_load_extension(const char *filename, Scheme_Env *env); +void scheme_register_extension_global(void *ptr, long size); + +long scheme_get_milliseconds(void); +long scheme_get_process_milliseconds(void); + +void scheme_rep(void); +char *scheme_banner(void); +char *scheme_version(void); + +int scheme_check_proc_arity(const char *where, int a, + int which, int argc, Scheme_Object **argv); + +void scheme_secure_exceptions(Scheme_Env *env); + +char *scheme_make_provided_string(Scheme_Object *o, int count, int *len); +char *scheme_make_args_string(char *s, int which, int argc, Scheme_Object **argv); + +void scheme_no_dumps(char *why); + +const char *scheme_system_library_subpath(); diff --git a/collects/mzscheme/include/schemex.h b/collects/mzscheme/include/schemex.h new file mode 100644 index 0000000..2ac1158 --- /dev/null +++ b/collects/mzscheme/include/schemex.h @@ -0,0 +1,468 @@ +/* + MzScheme + Copyright (c) 1995 Matthew Flatt + All rights reserved. + + Please see the full copyright in the documentation. + + libscheme + Copyright (c) 1994 Brent Benson + All rights reserved. +*/ + +/* MzScheme function prototypes */ +/* No macros should go in this file; it is used both to + prototype functions, and as a parsing source for + declaring scheme_extension_table */ + +/* The scheme_extension_table parser is touchy: don't leave a space + between a function name and it's opening parameter parenthesis. */ + +/* After this START tag, all comments should start & end on same line */ + +typedef struct { +/* Call/cc utilities */ +void (*scheme_init_jmpup_buf)(Scheme_Jumpup_Buf *b); +int (*scheme_setjmpup_relative)(Scheme_Jumpup_Buf *b, void *start, + Scheme_Jumpup_Buf *cont); +void (*scheme_longjmpup)(Scheme_Jumpup_Buf *b); +#ifdef USE_MZ_SETJMP +int (*scheme_setjmp)(jmp_buf b); +void (*scheme_longjmp)(jmp_buf b, int v); +#endif +/* Parameters */ +Scheme_Object *(*scheme_make_config)(Scheme_Config *base); +Scheme_Object *(*scheme_branch_config)(void); +int (*scheme_new_param)(void); +Scheme_Object *(*scheme_param_config)(char *name, long pos, + int argc, Scheme_Object **argv, + int arity, + Scheme_Prim *check, char *expected, + int isbool); +Scheme_Object *(*scheme_register_parameter)(Scheme_Prim *function, char *name, int which); +Scheme_Env *(*scheme_get_env)(Scheme_Config *config); +/* Processes */ +#ifdef MZ_REAL_THREADS +Scheme_Process *(*scheme_get_current_process)(); +#else +#ifndef LINK_EXTENSIONS_BY_TABLE +Scheme_Process *scheme_current_process; +int scheme_fuel_counter; +#else +Scheme_Process **scheme_current_process_ptr; +int *scheme_fuel_counter_ptr; +#endif +#endif +#ifndef NO_SCHEME_THREADS +Scheme_Object *(*scheme_make_namespace)(int argc, Scheme_Object *argv[]); +Scheme_Object *(*scheme_thread)(Scheme_Object *thunk, Scheme_Config *config); +void (*scheme_break_thread)(Scheme_Process *p); +void (*scheme_kill_thread)(Scheme_Process *p); +#endif +#ifndef MZ_REAL_THREADS +void (*scheme_process_block)(float sleep_time); +void (*scheme_swap_process)(Scheme_Process *process); +#else +void (*scheme_process_block_w_process)(float sleep_time, Scheme_Process *p); +#endif +int (*scheme_block_until)(int (*f)(Scheme_Object *), void (*fdfd)(Scheme_Object *, void *), void *, float); +int (*scheme_in_main_thread)(void); +int (*scheme_tls_allocate)(); +void (*scheme_tls_set)(int pos, void *v); +void *(*scheme_tls_get)(int pos); +void (*scheme_add_namespace_option)(Scheme_Object *key, void (*f)(Scheme_Env *)); +Scheme_Manager *(*scheme_make_manager)(Scheme_Manager *); +Scheme_Manager_Reference *(*scheme_add_managed)(Scheme_Manager *m, Scheme_Object *o, + Scheme_Close_Manager_Client *f, void *data, + int strong); +void (*scheme_remove_managed)(Scheme_Manager_Reference *m, Scheme_Object *o); +void (*scheme_close_managed)(Scheme_Manager *m); +/* error handling */ +void (*scheme_signal_error)(char *msg, ...); +void (*scheme_raise_exn)(int exnid, ...); +void (*scheme_warning)(char *msg, ...); +void (*scheme_wrong_count)(const char *name, int minc, int maxc, int argc, + Scheme_Object **argv); +void (*scheme_case_lambda_wrong_count)(const char *name, int argc, + Scheme_Object **argv, int count, ...); +void (*scheme_wrong_type)(const char *name, const char *expected, + int which, int argc, + Scheme_Object **argv); +void (*scheme_wrong_return_arity)(const char *where, + int expected, int got, + Scheme_Object **argv, + const char *context_detail, ...); +void (*scheme_unbound_global)(Scheme_Object *name); +Scheme_Object *(*scheme_dynamic_wind)(void (*pre)(void *), + Scheme_Object *(*act)(void *), + void (*post)(void *), + Scheme_Object *(*jmp_handler)(void *), + void *data); +/* Types */ +Scheme_Type (*scheme_make_type)(const char *name); +/* Type readers & writers for compiled code data */ +void (*scheme_install_type_reader)(Scheme_Type type, Scheme_Type_Reader f); +void (*scheme_install_type_writer)(Scheme_Type type, Scheme_Type_Writer f); +/* Constants */ +Scheme_Object *scheme_eof; +Scheme_Object *scheme_null; +Scheme_Object *scheme_true; +Scheme_Object *scheme_false; +Scheme_Object *scheme_void; +Scheme_Object *scheme_undefined; +Scheme_Object *scheme_tail_call_waiting; +Scheme_Object *scheme_multiple_values; +/* Basics */ +Scheme_Object *(*scheme_eval)(Scheme_Object *obj, Scheme_Env *env); +Scheme_Object *(*scheme_eval_multi)(Scheme_Object *obj, Scheme_Env *env); +Scheme_Object *(*scheme_eval_compiled)(Scheme_Object *obj); +Scheme_Object *(*scheme_eval_compiled_multi)(Scheme_Object *obj); +Scheme_Object *(*_scheme_eval_compiled)(Scheme_Object *obj); +Scheme_Object *(*_scheme_eval_compiled_multi)(Scheme_Object *obj); +#ifndef MZ_REAL_THREADS +Scheme_Object *(*scheme_apply)(Scheme_Object *rator, int num_rands, Scheme_Object **rands); +Scheme_Object *(*scheme_apply_multi)(Scheme_Object *rator, int num_rands, Scheme_Object **rands); +#else +Scheme_Object *(*scheme_apply_wp)(Scheme_Object *rator, int num_rands, Scheme_Object **rands, + Scheme_Process *p); +Scheme_Object *(*scheme_apply_multi_wp)(Scheme_Object *rator, int num_rands, Scheme_Object **rands, + Scheme_Process *p); +#endif +Scheme_Object *(*scheme_apply_to_list)(Scheme_Object *rator, Scheme_Object *argss); +Scheme_Object *(*scheme_eval_string)(const char *str, Scheme_Env *env); +Scheme_Object *(*scheme_eval_string_all)(const char *str, Scheme_Env *env, int all); +Scheme_Object *(*_scheme_apply_known_closed_prim)(Scheme_Object *rator, int argc, + Scheme_Object **argv); +Scheme_Object *(*_scheme_apply_known_closed_prim_multi)(Scheme_Object *rator, int argc, + Scheme_Object **argv); +Scheme_Object *(*scheme_values)(int c, Scheme_Object **v); +Scheme_Object *(*scheme_check_one_value)(Scheme_Object *v); +/* Tail calls - only use these when you're writing new functions/syntax */ +Scheme_Object *(*scheme_tail_apply)(Scheme_Object *f, int n, Scheme_Object **arg); +Scheme_Object *(*scheme_tail_apply_no_copy)(Scheme_Object *f, int n, Scheme_Object **arg); +Scheme_Object *(*scheme_tail_apply_to_list)(Scheme_Object *f, Scheme_Object *l); +Scheme_Object *(*scheme_tail_eval_expr)(Scheme_Object *obj); +void (*scheme_set_tail_buffer_size)(int s); +Scheme_Object *(*scheme_force_value)(Scheme_Object *); +/* Internal */ +#ifndef MZ_REAL_THREADS +Scheme_Object *(*scheme_do_eval)(Scheme_Object *obj, int _num_rands, Scheme_Object **rands, int val); +#else +Scheme_Object *(*scheme_do_eval_w_process)(Scheme_Object *obj, int _num_rands, Scheme_Object **rands, int val, Scheme_Process *p); +#endif +/* Allocation */ +#ifndef SCHEME_NO_GC +#ifndef SCHEME_NO_GC_PROTO +void *(*GC_malloc)(size_t size_in_bytes); +void *(*GC_malloc_atomic)(size_t size_in_bytes); +void *(*GC_malloc_stubborn)(size_t size_in_bytes); +void *(*GC_malloc_uncollectable)(size_t size_in_bytes); +#endif +#endif +void *(*scheme_malloc_eternal)(size_t n); +void (*scheme_end_stubborn_change)(void *p); +void *(*scheme_calloc)(size_t num, size_t size); +char *(*scheme_strdup)(const char *str); +char *(*scheme_strdup_eternal)(const char *str); +void *(*scheme_malloc_fail_ok)(void *(*f)(size_t), size_t); +void (*scheme_weak_reference)(void **p); +void (*scheme_weak_reference_indirect)(void **p, void *v); +void (*scheme_add_finalizer)(void *p, void (*f)(void *p, void *data), void *data); +void (*scheme_add_scheme_finalizer)(void *p, void (*f)(void *p, void *data), void *data); +void (*scheme_register_finalizer)(void *p, + void (*f)(void *p, void *data), void *data, + void (**oldf)(void *p, void *data), + void **olddata); +void (*scheme_dont_gc_ptr)(void *p); +void (*scheme_gc_ptr_ok)(void *p); +void (*scheme_collect_garbage)(void); +/* Hash table */ +Scheme_Hash_Table *(*scheme_hash_table)(int size, int type, + int w_const, int forever); +void (*scheme_add_to_table)(Scheme_Hash_Table *table, const char *key, void *val, int); +void (*scheme_change_in_table)(Scheme_Hash_Table *table, const char *key, void *new_val); +void *(*scheme_lookup_in_table)(Scheme_Hash_Table *table, const char *key); +Scheme_Bucket *(*scheme_bucket_from_table)(Scheme_Hash_Table *table, const char *key); +/* Constructors */ +Scheme_Object *(*scheme_make_prim)(Scheme_Prim *prim); +Scheme_Object *(*scheme_make_noneternal_prim)(Scheme_Prim *prim); +Scheme_Object *(*scheme_make_closed_prim)(Scheme_Closed_Prim *prim, void *data); +Scheme_Object *(*scheme_make_prim_w_arity)(Scheme_Prim *prim, const char *name, + short mina, short maxa); +Scheme_Object *(*scheme_make_folding_prim)(Scheme_Prim *prim, + const char *name, + short mina, short maxa, + short functional); +Scheme_Object *(*scheme_make_noneternal_prim_w_arity)(Scheme_Prim *prim, + const char *name, + short mina, short maxa); +Scheme_Object *(*scheme_make_closed_prim_w_arity)(Scheme_Closed_Prim *prim, + void *data, const char *name, + short mina, short maxa); +Scheme_Object *(*scheme_make_folding_closed_prim)(Scheme_Closed_Prim *prim, + void *data, const char *name, + short mina, short maxa, + short functional); +Scheme_Object *(*scheme_make_closure)(Scheme_Env *env, Scheme_Object *code); +Scheme_Object *(*scheme_make_pair)(Scheme_Object *car, Scheme_Object *cdr); +Scheme_Object *(*scheme_make_string)(const char *chars); +Scheme_Object *(*scheme_make_sized_string)(char *chars, long len, int copy); +Scheme_Object *(*scheme_make_string_without_copying)(char *chars); +Scheme_Object *(*scheme_alloc_string)(int size, char fill); +Scheme_Object *(*scheme_append_string)(Scheme_Object *, Scheme_Object *); +Scheme_Object *(*scheme_make_vector)(int size, Scheme_Object *fill); +Scheme_Object *(*scheme_make_integer_value)(long i); +Scheme_Object *(*scheme_make_integer_value_from_unsigned)(unsigned long i); +Scheme_Object *(*scheme_make_double)(double d); +#ifdef MZ_USE_SINGLE_FLOATS +Scheme_Object *(*scheme_make_float)(float f); +#endif +Scheme_Object *(*scheme_make_char)(char ch); +Scheme_Object *(*scheme_make_promise)(Scheme_Object *expr, Scheme_Env *env); +Scheme_Object *(*scheme_make_promise_from_thunk)(Scheme_Object *expr); +#ifndef NO_SCHEME_THREADS +Scheme_Object *(*scheme_make_sema)(long v); +#endif +void (*scheme_post_sema)(Scheme_Object *o); +int (*scheme_wait_sema)(Scheme_Object *o, int just_try); +Scheme_Object **scheme_char_constants; +int (*scheme_get_int_val)(Scheme_Object *o, long *v); +int (*scheme_get_unsigned_int_val)(Scheme_Object *o, unsigned long *v); +const char *(*scheme_get_proc_name)(Scheme_Object *p, int *len, int for_error); +/* Bignums */ +Scheme_Object *(*scheme_make_bignum)(long v); +Scheme_Object *(*scheme_make_bignum_from_unsigned)(unsigned long v); +double (*scheme_bignum_to_double)(const Scheme_Object *n); +Scheme_Object *(*scheme_bignum_from_double)(double d); +#ifdef MZ_USE_SINGLE_FLOATS +float (*scheme_bignum_to_float)(const Scheme_Object *n); +Scheme_Object *(*scheme_bignum_from_float)(float d); +#else +# define scheme_bignum_to_float scheme_bignum_to_double +# define scheme_bignum_from_float scheme_bignum_from_double +#endif +char *(*scheme_bignum_to_string)(const Scheme_Object *n, int radix); +Scheme_Object *(*scheme_read_bignum)(const char *str, int radix); +Scheme_Object *(*scheme_bignum_normalize)(const Scheme_Object *n); +long (*scheme_double_to_int)(const char *where, double d); +/* Rationals */ +Scheme_Object *(*scheme_make_rational)(const Scheme_Object *r, const Scheme_Object *d); +double (*scheme_rational_to_double)(const Scheme_Object *n); +Scheme_Object *(*scheme_rational_from_double)(double d); +#ifdef MZ_USE_SINGLE_FLOATS +float (*scheme_rational_to_float)(const Scheme_Object *n); +Scheme_Object *(*scheme_rational_from_float)(float d); +#else +# define scheme_rational_to_float scheme_rational_to_double +# define scheme_rational_from_float scheme_rational_from_double +#endif +Scheme_Object *(*scheme_rational_normalize)(const Scheme_Object *n); +Scheme_Object *(*scheme_rational_numerator)(const Scheme_Object *n); +Scheme_Object *(*scheme_rational_denominator)(const Scheme_Object *n); +/* Complex */ +Scheme_Object *(*scheme_make_complex)(const Scheme_Object *r, const Scheme_Object *i); +Scheme_Object *(*scheme_complex_normalize)(const Scheme_Object *n); +Scheme_Object *(*scheme_complex_real_part)(const Scheme_Object *n); +Scheme_Object *(*scheme_complex_imaginary_part)(const Scheme_Object *n); +/* Exact/inexact: */ +int (*scheme_is_exact)(Scheme_Object *n); +int (*scheme_is_inexact)(Scheme_Object *n); +/* Macro and syntax expansion */ +Scheme_Object *(*scheme_expand)(Scheme_Object *form, Scheme_Env *env); +/* Compilation */ +Scheme_Object *(*scheme_compile)(Scheme_Object *form, Scheme_Env *env, int writeable); +Scheme_Object *(*scheme_make_promise_value)(Scheme_Object *compiled_expr); +/* Ports */ +Scheme_Object *(*scheme_read)(Scheme_Object *port); +void (*scheme_write)(Scheme_Object *obj, Scheme_Object *port); +void (*scheme_display)(Scheme_Object *obj, Scheme_Object *port); +void (*scheme_write_w_max)(Scheme_Object *obj, Scheme_Object *port, long maxl); +void (*scheme_display_w_max)(Scheme_Object *obj, Scheme_Object *port, long maxl); +void (*scheme_write_string)(const char *str, long len, Scheme_Object *port); +char *(*scheme_write_to_string)(Scheme_Object *obj, long *len); +char *(*scheme_display_to_string)(Scheme_Object *obj, long *len); +char *(*scheme_write_to_string_w_max)(Scheme_Object *obj, long *len, long maxl); +char *(*scheme_display_to_string_w_max)(Scheme_Object *obj, long *len, long maxl); +void (*scheme_debug_print)(Scheme_Object *obj); +void (*scheme_flush_output)(Scheme_Object *port); +char *(*scheme_format)(char *format, int flen, int argc, Scheme_Object **argv, int *rlen); +void (*scheme_printf)(char *format, int flen, int argc, Scheme_Object **argv); +int (*scheme_getc)(Scheme_Object *port); +void (*scheme_ungetc)(int ch, Scheme_Object *port); +int (*scheme_char_ready)(Scheme_Object *port); +void (*scheme_need_wakeup)(Scheme_Object *port, void *fds); +long (*scheme_get_chars)(Scheme_Object *port, long size, char *buffer); +long (*scheme_tell)(Scheme_Object *port); +long (*scheme_output_tell)(Scheme_Object *port); +long (*scheme_tell_line)(Scheme_Object *port); +void (*scheme_close_input_port)(Scheme_Object *port); +void (*scheme_close_output_port)(Scheme_Object *port); +int (*scheme_are_all_chars_ready)(Scheme_Object *port); +Scheme_Object *(*scheme_make_port_type)(const char *name); +Scheme_Input_Port *(*scheme_make_input_port)(Scheme_Object *subtype, void *data, + int (*getc_fun)(Scheme_Input_Port*), + int (*char_ready_fun) + (Scheme_Input_Port*), + void (*close_fun) + (Scheme_Input_Port*), + void (*need_wakeup_fun) + (Scheme_Input_Port*, void *), + int must_close); +Scheme_Output_Port *(*scheme_make_output_port)(Scheme_Object *subtype, + void *data, + void (*write_string_fun) + (char*,long, Scheme_Output_Port*), + void (*close_fun) + (Scheme_Output_Port*), + int must_close); +Scheme_Object *(*scheme_make_file_input_port)(FILE *fp); +Scheme_Object *(*scheme_make_named_file_input_port)(FILE *fp, const char *filename); +Scheme_Object *(*scheme_make_file_output_port)(FILE *fp); +Scheme_Object *(*scheme_make_string_input_port)(const char *str); +Scheme_Object *(*scheme_make_sized_string_input_port)(const char *str, long len); +Scheme_Object *(*scheme_make_string_output_port)(); +char *(*scheme_get_string_output)(Scheme_Object *); +char *(*scheme_get_sized_string_output)(Scheme_Object *, int *len); +void (*scheme_pipe)(Scheme_Object **write, Scheme_Object **read); +int (*scheme_file_exists)(char *filename); +int (*scheme_directory_exists)(char *dirname); +char *(*scheme_expand_filename)(char* filename, int ilen, char *errorin, int *ex); +char *(*scheme_getcwd)(char *buf, int buflen, int *actlen, int noexn); +int (*scheme_setcwd)(char *buf, int noexn); +char *(*scheme_getdrive)(void); +Scheme_Object *(*scheme_split_pathname)(int argc, Scheme_Object **argv); +Scheme_Object *(*scheme_build_pathname)(int argc, Scheme_Object **argv); +void *(*scheme_alloc_fdset_array)(int count, int permanent); +void *(*scheme_init_fdset_array)(void *fdarray, int count); +void *(*scheme_get_fdset)(void *fdarray, int pos); +void (*scheme_fdzero)(void *fd); +void (*scheme_fdset)(void *fd, int pos); +void (*scheme_fdclr)(void *fd, int pos); +int (*scheme_fdisset)(void *fd, int pos); +/* environment */ +void (*scheme_add_global)(const char *name, Scheme_Object *val, Scheme_Env *env); +void (*scheme_add_global_constant)(const char *name, Scheme_Object *v, Scheme_Env *env); +void (*scheme_add_global_keyword)(const char *name, Scheme_Object *v, Scheme_Env *env); +void (*scheme_remove_global)(const char *name, Scheme_Env *env); +void (*scheme_remove_global_constant)(const char *name, Scheme_Env *env); +void (*scheme_add_global_symbol)(Scheme_Object *name, Scheme_Object *val, + Scheme_Env *env); +void (*scheme_remove_global_symbol)(Scheme_Object *name, Scheme_Env *env); +void (*scheme_add_global_constant_symbol)(Scheme_Object *name, Scheme_Object *v, Scheme_Env *env); +void (*scheme_constant)(Scheme_Object *sym, Scheme_Env *env); +void (*scheme_set_keyword)(Scheme_Object *name, Scheme_Env *env); +Scheme_Object *(*scheme_make_envunbox)(Scheme_Object *value); +Scheme_Object *(*scheme_lookup_global)(Scheme_Object *symbol, Scheme_Env *env); +Scheme_Bucket *(*scheme_global_bucket)(Scheme_Object *symbol, Scheme_Env *env); +void (*scheme_set_global_bucket)(char *proc, Scheme_Bucket *var, Scheme_Object *val, + int set_undef); +/* Symbols */ +Scheme_Object *(*scheme_intern_symbol)(const char *name); +Scheme_Object *(*scheme_intern_exact_symbol)(const char *name, int len); +Scheme_Object *(*scheme_make_symbol)(const char *name); /* Make uninterned */ +Scheme_Object *(*scheme_make_exact_symbol)(const char *name, int len); /* Exact case */ +const char *(*scheme_symbol_name)(Scheme_Object *sym); +const char *(*scheme_symbol_name_and_size)(Scheme_Object *sym, int *l, int flags); +/* Type Symbols */ +Scheme_Object *(*scheme_intern_type_symbol)(Scheme_Object *sym); +Scheme_Object *(*scheme_make_type_symbol)(Scheme_Object *sym);/*Make uninterned */ +/* Structures */ +Scheme_Object **(*scheme_make_struct_values)(Scheme_Object *struct_type, + Scheme_Object **names, + int count, int flags); +Scheme_Object **(*scheme_make_struct_names)(Scheme_Object *base, + Scheme_Object *field_names, + int flags, int *count_out); +Scheme_Object *(*scheme_make_struct_type)(Scheme_Object *base, + Scheme_Object *parent, + int num_fields); +Scheme_Object *(*scheme_make_struct_instance)(Scheme_Object *stype, + int argc, + Scheme_Object **argv); +int (*scheme_is_struct_instance)(Scheme_Object *type, Scheme_Object *v); +#ifndef NO_OBJECT_SYSTEM +/* Objects */ +Scheme_Object *(*scheme_make_class)(const char *name, Scheme_Object *sup, + Scheme_Method_Prim *init, int num_methods); +void (*scheme_add_method)(Scheme_Object *cl, const char *name, + Scheme_Method_Prim *f); +void (*scheme_add_method_w_arity)(Scheme_Object *cl, const char *name, + Scheme_Method_Prim *f, int mina, int maxa); +void (*scheme_made_class)(Scheme_Object *cl); +Scheme_Object *(*scheme_make_object)(Scheme_Object *sclass, + int argc, Scheme_Object **argv); +Scheme_Object *(*scheme_make_uninited_object)(Scheme_Object *sclass); +Scheme_Object *(*scheme_find_ivar)(Scheme_Object *obj, Scheme_Object *sym, int force); +int (*scheme_is_subclass)(Scheme_Object *sub, Scheme_Object *parent); +int (*scheme_is_implementation)(Scheme_Object *cl, Scheme_Object *in); +int (*scheme_is_interface_extension)(Scheme_Object *n1, Scheme_Object *n2); +int (*scheme_is_a)(Scheme_Object *obj, Scheme_Object *sclass); +const char *(*scheme_get_class_name)(Scheme_Object *cl, int *len); +const char *(*scheme_get_interface_name)(Scheme_Object *cl, int *len); +struct Scheme_Class_Assembly *(*scheme_make_class_assembly)(const char *name, int n_interfaces, + int n_public, Scheme_Object **names, + int n_inh, Scheme_Object **inheritd, + int n_ren, Scheme_Object **renames, + int mina, int maxa, + Scheme_Instance_Init_Proc *initproc); +Scheme_Object *(*scheme_create_class)(struct Scheme_Class_Assembly *a, void *data, + Scheme_Object *super, Scheme_Object **interfaces); +struct Scheme_Interface_Assembly *(*scheme_make_interface_assembly)(const char *name, int n_supers, + int n_names, + Scheme_Object **names); +Scheme_Object *(*scheme_create_interface)(struct Scheme_Interface_Assembly *a, + Scheme_Object **supers); +Scheme_Object *(*scheme_apply_generic_data)(Scheme_Object *gdata, + Scheme_Object *sobj, int force); +Scheme_Object *(*scheme_get_generic_data)(Scheme_Object *cl, + Scheme_Object *name); +#endif +/* Units */ +Scheme_Object *(*scheme_invoke_unit)(Scheme_Object *functor, int num_ins, + Scheme_Object **ins, Scheme_Object **anchors, + int open, const char *name, int tail, int multi); +Scheme_Object *(*scheme_assemble_compound_unit)(Scheme_Object *imports, + Scheme_Object *links, + Scheme_Object *exports); +Scheme_Object *(*scheme_make_compound_unit)(Scheme_Object *data_in, + Scheme_Object **subs_in); +const char *(*scheme_get_unit_name)(Scheme_Object *cl, int *len); +/* Misc */ +int (*scheme_eq)(Scheme_Object *obj1, Scheme_Object *obj2); +int (*scheme_eqv)(Scheme_Object *obj1, Scheme_Object *obj2); +int (*scheme_equal)(Scheme_Object *obj1, Scheme_Object *obj2); +Scheme_Object *(*scheme_build_list)(int argc, Scheme_Object **argv); +int (*scheme_list_length)(Scheme_Object *list); +int (*scheme_proper_list_length)(Scheme_Object *list); +Scheme_Object *(*scheme_alloc_list)(int size); +Scheme_Object *(*scheme_map_1)(Scheme_Object *(*f)(Scheme_Object*), + Scheme_Object *l); +Scheme_Object *(*scheme_car)(Scheme_Object *pair); +Scheme_Object *(*scheme_cdr)(Scheme_Object *pair); +Scheme_Object *(*scheme_cadr)(Scheme_Object *pair); +Scheme_Object *(*scheme_caddr)(Scheme_Object *pair); +Scheme_Object *(*scheme_vector_to_list)(Scheme_Object *vec); +Scheme_Object *(*scheme_list_to_vector)(Scheme_Object *list); +Scheme_Object *(*scheme_append)(Scheme_Object *lstx, Scheme_Object *lsty); +Scheme_Object *(*scheme_box)(Scheme_Object *v); +Scheme_Object *(*scheme_unbox)(Scheme_Object *obj); +void (*scheme_set_box)(Scheme_Object *b, Scheme_Object *v); +Scheme_Object *(*scheme_make_weak_box)(Scheme_Object *v); +Scheme_Object *(*scheme_load)(const char *file); +Scheme_Object *(*scheme_load_extension)(const char *filename, Scheme_Env *env); +void (*scheme_register_extension_global)(void *ptr, long size); +long (*scheme_get_milliseconds)(void); +long (*scheme_get_process_milliseconds)(void); +void (*scheme_rep)(void); +char *(*scheme_banner)(void); +char *(*scheme_version)(void); +int (*scheme_check_proc_arity)(const char *where, int a, + int which, int argc, Scheme_Object **argv); +void (*scheme_secure_exceptions)(Scheme_Env *env); +char *(*scheme_make_provided_string)(Scheme_Object *o, int count, int *len); +char *(*scheme_make_args_string)(char *s, int which, int argc, Scheme_Object **argv); +void (*scheme_no_dumps)(char *why); +const char *(*scheme_system_library_subpath)(); +#ifndef SCHEME_EX_INLINE +} Scheme_Extension_Table; +#endif diff --git a/collects/mzscheme/include/schemexm.h b/collects/mzscheme/include/schemexm.h new file mode 100644 index 0000000..903eb5d --- /dev/null +++ b/collects/mzscheme/include/schemexm.h @@ -0,0 +1,332 @@ +#define scheme_init_jmpup_buf (scheme_extension_table->scheme_init_jmpup_buf) +#define scheme_setjmpup_relative (scheme_extension_table->scheme_setjmpup_relative) +#define scheme_longjmpup (scheme_extension_table->scheme_longjmpup) +#ifdef USE_MZ_SETJMP +#define scheme_setjmp (scheme_extension_table->scheme_setjmp) +#define scheme_longjmp (scheme_extension_table->scheme_longjmp) +#endif +#define scheme_make_config (scheme_extension_table->scheme_make_config) +#define scheme_branch_config (scheme_extension_table->scheme_branch_config) +#define scheme_new_param (scheme_extension_table->scheme_new_param) +#define scheme_param_config (scheme_extension_table->scheme_param_config) +#define scheme_register_parameter (scheme_extension_table->scheme_register_parameter) +#define scheme_get_env (scheme_extension_table->scheme_get_env) +#ifdef MZ_REAL_THREADS +#define scheme_get_current_process (scheme_extension_table->scheme_get_current_process) +#else +#ifndef LINK_EXTENSIONS_BY_TABLE +#define scheme_current_process (scheme_extension_table->scheme_current_process) +#define scheme_fuel_counter (scheme_extension_table->scheme_fuel_counter) +#else +#define scheme_current_process_ptr (scheme_extension_table->scheme_current_process_ptr) +#define scheme_fuel_counter_ptr (scheme_extension_table->scheme_fuel_counter_ptr) +#endif +#endif +#ifndef NO_SCHEME_THREADS +#define scheme_make_namespace (scheme_extension_table->scheme_make_namespace) +#define scheme_thread (scheme_extension_table->scheme_thread) +#define scheme_break_thread (scheme_extension_table->scheme_break_thread) +#define scheme_kill_thread (scheme_extension_table->scheme_kill_thread) +#endif +#ifndef MZ_REAL_THREADS +#define scheme_process_block (scheme_extension_table->scheme_process_block) +#define scheme_swap_process (scheme_extension_table->scheme_swap_process) +#else +#define scheme_process_block_w_process (scheme_extension_table->scheme_process_block_w_process) +#endif +#define scheme_block_until (scheme_extension_table->scheme_block_until) +#define scheme_in_main_thread (scheme_extension_table->scheme_in_main_thread) +#define scheme_tls_allocate (scheme_extension_table->scheme_tls_allocate) +#define scheme_tls_set (scheme_extension_table->scheme_tls_set) +#define scheme_tls_get (scheme_extension_table->scheme_tls_get) +#define scheme_add_namespace_option (scheme_extension_table->scheme_add_namespace_option) +#define scheme_make_manager (scheme_extension_table->scheme_make_manager) +#define scheme_add_managed (scheme_extension_table->scheme_add_managed) +#define scheme_remove_managed (scheme_extension_table->scheme_remove_managed) +#define scheme_close_managed (scheme_extension_table->scheme_close_managed) +#define scheme_signal_error (scheme_extension_table->scheme_signal_error) +#define scheme_raise_exn (scheme_extension_table->scheme_raise_exn) +#define scheme_warning (scheme_extension_table->scheme_warning) +#define scheme_wrong_count (scheme_extension_table->scheme_wrong_count) +#define scheme_case_lambda_wrong_count (scheme_extension_table->scheme_case_lambda_wrong_count) +#define scheme_wrong_type (scheme_extension_table->scheme_wrong_type) +#define scheme_wrong_return_arity (scheme_extension_table->scheme_wrong_return_arity) +#define scheme_unbound_global (scheme_extension_table->scheme_unbound_global) +#define scheme_dynamic_wind (scheme_extension_table->scheme_dynamic_wind) +#define scheme_make_type (scheme_extension_table->scheme_make_type) +#define scheme_install_type_reader (scheme_extension_table->scheme_install_type_reader) +#define scheme_install_type_writer (scheme_extension_table->scheme_install_type_writer) +#define scheme_eof (scheme_extension_table->scheme_eof) +#define scheme_null (scheme_extension_table->scheme_null) +#define scheme_true (scheme_extension_table->scheme_true) +#define scheme_false (scheme_extension_table->scheme_false) +#define scheme_void (scheme_extension_table->scheme_void) +#define scheme_undefined (scheme_extension_table->scheme_undefined) +#define scheme_tail_call_waiting (scheme_extension_table->scheme_tail_call_waiting) +#define scheme_multiple_values (scheme_extension_table->scheme_multiple_values) +#define scheme_eval (scheme_extension_table->scheme_eval) +#define scheme_eval_multi (scheme_extension_table->scheme_eval_multi) +#define scheme_eval_compiled (scheme_extension_table->scheme_eval_compiled) +#define scheme_eval_compiled_multi (scheme_extension_table->scheme_eval_compiled_multi) +#define _scheme_eval_compiled (scheme_extension_table->_scheme_eval_compiled) +#define _scheme_eval_compiled_multi (scheme_extension_table->_scheme_eval_compiled_multi) +#ifndef MZ_REAL_THREADS +#define scheme_apply (scheme_extension_table->scheme_apply) +#define scheme_apply_multi (scheme_extension_table->scheme_apply_multi) +#else +#define scheme_apply_wp (scheme_extension_table->scheme_apply_wp) +#define scheme_apply_multi_wp (scheme_extension_table->scheme_apply_multi_wp) +#endif +#define scheme_apply_to_list (scheme_extension_table->scheme_apply_to_list) +#define scheme_eval_string (scheme_extension_table->scheme_eval_string) +#define scheme_eval_string_all (scheme_extension_table->scheme_eval_string_all) +#define _scheme_apply_known_closed_prim (scheme_extension_table->_scheme_apply_known_closed_prim) +#define _scheme_apply_known_closed_prim_multi (scheme_extension_table->_scheme_apply_known_closed_prim_multi) +#define scheme_values (scheme_extension_table->scheme_values) +#define scheme_check_one_value (scheme_extension_table->scheme_check_one_value) +#define scheme_tail_apply (scheme_extension_table->scheme_tail_apply) +#define scheme_tail_apply_no_copy (scheme_extension_table->scheme_tail_apply_no_copy) +#define scheme_tail_apply_to_list (scheme_extension_table->scheme_tail_apply_to_list) +#define scheme_tail_eval_expr (scheme_extension_table->scheme_tail_eval_expr) +#define scheme_set_tail_buffer_size (scheme_extension_table->scheme_set_tail_buffer_size) +#define scheme_force_value (scheme_extension_table->scheme_force_value) +#ifndef MZ_REAL_THREADS +#define scheme_do_eval (scheme_extension_table->scheme_do_eval) +#else +#define scheme_do_eval_w_process (scheme_extension_table->scheme_do_eval_w_process) +#endif +#ifndef SCHEME_NO_GC +#ifndef SCHEME_NO_GC_PROTO +#define GC_malloc (scheme_extension_table->GC_malloc) +#define GC_malloc_atomic (scheme_extension_table->GC_malloc_atomic) +#define GC_malloc_stubborn (scheme_extension_table->GC_malloc_stubborn) +#define GC_malloc_uncollectable (scheme_extension_table->GC_malloc_uncollectable) +#endif +#endif +#define scheme_malloc_eternal (scheme_extension_table->scheme_malloc_eternal) +#define scheme_end_stubborn_change (scheme_extension_table->scheme_end_stubborn_change) +#define scheme_calloc (scheme_extension_table->scheme_calloc) +#define scheme_strdup (scheme_extension_table->scheme_strdup) +#define scheme_strdup_eternal (scheme_extension_table->scheme_strdup_eternal) +#define scheme_malloc_fail_ok (scheme_extension_table->scheme_malloc_fail_ok) +#define scheme_weak_reference (scheme_extension_table->scheme_weak_reference) +#define scheme_weak_reference_indirect (scheme_extension_table->scheme_weak_reference_indirect) +#define scheme_add_finalizer (scheme_extension_table->scheme_add_finalizer) +#define scheme_add_scheme_finalizer (scheme_extension_table->scheme_add_scheme_finalizer) +#define scheme_register_finalizer (scheme_extension_table->scheme_register_finalizer) +#define scheme_dont_gc_ptr (scheme_extension_table->scheme_dont_gc_ptr) +#define scheme_gc_ptr_ok (scheme_extension_table->scheme_gc_ptr_ok) +#define scheme_collect_garbage (scheme_extension_table->scheme_collect_garbage) +#define scheme_hash_table (scheme_extension_table->scheme_hash_table) +#define scheme_add_to_table (scheme_extension_table->scheme_add_to_table) +#define scheme_change_in_table (scheme_extension_table->scheme_change_in_table) +#define scheme_lookup_in_table (scheme_extension_table->scheme_lookup_in_table) +#define scheme_bucket_from_table (scheme_extension_table->scheme_bucket_from_table) +#define scheme_make_prim (scheme_extension_table->scheme_make_prim) +#define scheme_make_noneternal_prim (scheme_extension_table->scheme_make_noneternal_prim) +#define scheme_make_closed_prim (scheme_extension_table->scheme_make_closed_prim) +#define scheme_make_prim_w_arity (scheme_extension_table->scheme_make_prim_w_arity) +#define scheme_make_folding_prim (scheme_extension_table->scheme_make_folding_prim) +#define scheme_make_noneternal_prim_w_arity (scheme_extension_table->scheme_make_noneternal_prim_w_arity) +#define scheme_make_closed_prim_w_arity (scheme_extension_table->scheme_make_closed_prim_w_arity) +#define scheme_make_folding_closed_prim (scheme_extension_table->scheme_make_folding_closed_prim) +#define scheme_make_closure (scheme_extension_table->scheme_make_closure) +#define scheme_make_pair (scheme_extension_table->scheme_make_pair) +#define scheme_make_string (scheme_extension_table->scheme_make_string) +#define scheme_make_sized_string (scheme_extension_table->scheme_make_sized_string) +#define scheme_make_string_without_copying (scheme_extension_table->scheme_make_string_without_copying) +#define scheme_alloc_string (scheme_extension_table->scheme_alloc_string) +#define scheme_append_string (scheme_extension_table->scheme_append_string) +#define scheme_make_vector (scheme_extension_table->scheme_make_vector) +#define scheme_make_integer_value (scheme_extension_table->scheme_make_integer_value) +#define scheme_make_integer_value_from_unsigned (scheme_extension_table->scheme_make_integer_value_from_unsigned) +#define scheme_make_double (scheme_extension_table->scheme_make_double) +#ifdef MZ_USE_SINGLE_FLOATS +#define scheme_make_float (scheme_extension_table->scheme_make_float) +#endif +#define scheme_make_char (scheme_extension_table->scheme_make_char) +#define scheme_make_promise (scheme_extension_table->scheme_make_promise) +#define scheme_make_promise_from_thunk (scheme_extension_table->scheme_make_promise_from_thunk) +#ifndef NO_SCHEME_THREADS +#define scheme_make_sema (scheme_extension_table->scheme_make_sema) +#endif +#define scheme_post_sema (scheme_extension_table->scheme_post_sema) +#define scheme_wait_sema (scheme_extension_table->scheme_wait_sema) +#define scheme_char_constants (scheme_extension_table->scheme_char_constants) +#define scheme_get_int_val (scheme_extension_table->scheme_get_int_val) +#define scheme_get_unsigned_int_val (scheme_extension_table->scheme_get_unsigned_int_val) +#define scheme_get_proc_name (scheme_extension_table->scheme_get_proc_name) +#define scheme_make_bignum (scheme_extension_table->scheme_make_bignum) +#define scheme_make_bignum_from_unsigned (scheme_extension_table->scheme_make_bignum_from_unsigned) +#define scheme_bignum_to_double (scheme_extension_table->scheme_bignum_to_double) +#define scheme_bignum_from_double (scheme_extension_table->scheme_bignum_from_double) +#ifdef MZ_USE_SINGLE_FLOATS +#define scheme_bignum_to_float (scheme_extension_table->scheme_bignum_to_float) +#define scheme_bignum_from_float (scheme_extension_table->scheme_bignum_from_float) +#else +# define scheme_bignum_to_float scheme_bignum_to_double +# define scheme_bignum_from_float scheme_bignum_from_double +#endif +#define scheme_bignum_to_string (scheme_extension_table->scheme_bignum_to_string) +#define scheme_read_bignum (scheme_extension_table->scheme_read_bignum) +#define scheme_bignum_normalize (scheme_extension_table->scheme_bignum_normalize) +#define scheme_double_to_int (scheme_extension_table->scheme_double_to_int) +#define scheme_make_rational (scheme_extension_table->scheme_make_rational) +#define scheme_rational_to_double (scheme_extension_table->scheme_rational_to_double) +#define scheme_rational_from_double (scheme_extension_table->scheme_rational_from_double) +#ifdef MZ_USE_SINGLE_FLOATS +#define scheme_rational_to_float (scheme_extension_table->scheme_rational_to_float) +#define scheme_rational_from_float (scheme_extension_table->scheme_rational_from_float) +#else +# define scheme_rational_to_float scheme_rational_to_double +# define scheme_rational_from_float scheme_rational_from_double +#endif +#define scheme_rational_normalize (scheme_extension_table->scheme_rational_normalize) +#define scheme_rational_numerator (scheme_extension_table->scheme_rational_numerator) +#define scheme_rational_denominator (scheme_extension_table->scheme_rational_denominator) +#define scheme_make_complex (scheme_extension_table->scheme_make_complex) +#define scheme_complex_normalize (scheme_extension_table->scheme_complex_normalize) +#define scheme_complex_real_part (scheme_extension_table->scheme_complex_real_part) +#define scheme_complex_imaginary_part (scheme_extension_table->scheme_complex_imaginary_part) +#define scheme_is_exact (scheme_extension_table->scheme_is_exact) +#define scheme_is_inexact (scheme_extension_table->scheme_is_inexact) +#define scheme_expand (scheme_extension_table->scheme_expand) +#define scheme_compile (scheme_extension_table->scheme_compile) +#define scheme_make_promise_value (scheme_extension_table->scheme_make_promise_value) +#define scheme_read (scheme_extension_table->scheme_read) +#define scheme_write (scheme_extension_table->scheme_write) +#define scheme_display (scheme_extension_table->scheme_display) +#define scheme_write_w_max (scheme_extension_table->scheme_write_w_max) +#define scheme_display_w_max (scheme_extension_table->scheme_display_w_max) +#define scheme_write_string (scheme_extension_table->scheme_write_string) +#define scheme_write_to_string (scheme_extension_table->scheme_write_to_string) +#define scheme_display_to_string (scheme_extension_table->scheme_display_to_string) +#define scheme_write_to_string_w_max (scheme_extension_table->scheme_write_to_string_w_max) +#define scheme_display_to_string_w_max (scheme_extension_table->scheme_display_to_string_w_max) +#define scheme_debug_print (scheme_extension_table->scheme_debug_print) +#define scheme_flush_output (scheme_extension_table->scheme_flush_output) +#define scheme_format (scheme_extension_table->scheme_format) +#define scheme_printf (scheme_extension_table->scheme_printf) +#define scheme_getc (scheme_extension_table->scheme_getc) +#define scheme_ungetc (scheme_extension_table->scheme_ungetc) +#define scheme_char_ready (scheme_extension_table->scheme_char_ready) +#define scheme_need_wakeup (scheme_extension_table->scheme_need_wakeup) +#define scheme_get_chars (scheme_extension_table->scheme_get_chars) +#define scheme_tell (scheme_extension_table->scheme_tell) +#define scheme_output_tell (scheme_extension_table->scheme_output_tell) +#define scheme_tell_line (scheme_extension_table->scheme_tell_line) +#define scheme_close_input_port (scheme_extension_table->scheme_close_input_port) +#define scheme_close_output_port (scheme_extension_table->scheme_close_output_port) +#define scheme_are_all_chars_ready (scheme_extension_table->scheme_are_all_chars_ready) +#define scheme_make_port_type (scheme_extension_table->scheme_make_port_type) +#define scheme_make_input_port (scheme_extension_table->scheme_make_input_port) +#define scheme_make_output_port (scheme_extension_table->scheme_make_output_port) +#define scheme_make_file_input_port (scheme_extension_table->scheme_make_file_input_port) +#define scheme_make_named_file_input_port (scheme_extension_table->scheme_make_named_file_input_port) +#define scheme_make_file_output_port (scheme_extension_table->scheme_make_file_output_port) +#define scheme_make_string_input_port (scheme_extension_table->scheme_make_string_input_port) +#define scheme_make_sized_string_input_port (scheme_extension_table->scheme_make_sized_string_input_port) +#define scheme_make_string_output_port (scheme_extension_table->scheme_make_string_output_port) +#define scheme_get_string_output (scheme_extension_table->scheme_get_string_output) +#define scheme_get_sized_string_output (scheme_extension_table->scheme_get_sized_string_output) +#define scheme_pipe (scheme_extension_table->scheme_pipe) +#define scheme_file_exists (scheme_extension_table->scheme_file_exists) +#define scheme_directory_exists (scheme_extension_table->scheme_directory_exists) +#define scheme_expand_filename (scheme_extension_table->scheme_expand_filename) +#define scheme_getcwd (scheme_extension_table->scheme_getcwd) +#define scheme_setcwd (scheme_extension_table->scheme_setcwd) +#define scheme_getdrive (scheme_extension_table->scheme_getdrive) +#define scheme_split_pathname (scheme_extension_table->scheme_split_pathname) +#define scheme_build_pathname (scheme_extension_table->scheme_build_pathname) +#define scheme_alloc_fdset_array (scheme_extension_table->scheme_alloc_fdset_array) +#define scheme_init_fdset_array (scheme_extension_table->scheme_init_fdset_array) +#define scheme_get_fdset (scheme_extension_table->scheme_get_fdset) +#define scheme_fdzero (scheme_extension_table->scheme_fdzero) +#define scheme_fdset (scheme_extension_table->scheme_fdset) +#define scheme_fdclr (scheme_extension_table->scheme_fdclr) +#define scheme_fdisset (scheme_extension_table->scheme_fdisset) +#define scheme_add_global (scheme_extension_table->scheme_add_global) +#define scheme_add_global_constant (scheme_extension_table->scheme_add_global_constant) +#define scheme_add_global_keyword (scheme_extension_table->scheme_add_global_keyword) +#define scheme_remove_global (scheme_extension_table->scheme_remove_global) +#define scheme_remove_global_constant (scheme_extension_table->scheme_remove_global_constant) +#define scheme_add_global_symbol (scheme_extension_table->scheme_add_global_symbol) +#define scheme_remove_global_symbol (scheme_extension_table->scheme_remove_global_symbol) +#define scheme_add_global_constant_symbol (scheme_extension_table->scheme_add_global_constant_symbol) +#define scheme_constant (scheme_extension_table->scheme_constant) +#define scheme_set_keyword (scheme_extension_table->scheme_set_keyword) +#define scheme_make_envunbox (scheme_extension_table->scheme_make_envunbox) +#define scheme_lookup_global (scheme_extension_table->scheme_lookup_global) +#define scheme_global_bucket (scheme_extension_table->scheme_global_bucket) +#define scheme_set_global_bucket (scheme_extension_table->scheme_set_global_bucket) +#define scheme_intern_symbol (scheme_extension_table->scheme_intern_symbol) +#define scheme_intern_exact_symbol (scheme_extension_table->scheme_intern_exact_symbol) +#define scheme_make_symbol (scheme_extension_table->scheme_make_symbol) +#define scheme_make_exact_symbol (scheme_extension_table->scheme_make_exact_symbol) +#define scheme_symbol_name (scheme_extension_table->scheme_symbol_name) +#define scheme_symbol_name_and_size (scheme_extension_table->scheme_symbol_name_and_size) +#define scheme_intern_type_symbol (scheme_extension_table->scheme_intern_type_symbol) +#define scheme_make_type_symbol (scheme_extension_table->scheme_make_type_symbol) +#define scheme_make_struct_values (scheme_extension_table->scheme_make_struct_values) +#define scheme_make_struct_names (scheme_extension_table->scheme_make_struct_names) +#define scheme_make_struct_type (scheme_extension_table->scheme_make_struct_type) +#define scheme_make_struct_instance (scheme_extension_table->scheme_make_struct_instance) +#define scheme_is_struct_instance (scheme_extension_table->scheme_is_struct_instance) +#ifndef NO_OBJECT_SYSTEM +#define scheme_make_class (scheme_extension_table->scheme_make_class) +#define scheme_add_method (scheme_extension_table->scheme_add_method) +#define scheme_add_method_w_arity (scheme_extension_table->scheme_add_method_w_arity) +#define scheme_made_class (scheme_extension_table->scheme_made_class) +#define scheme_make_object (scheme_extension_table->scheme_make_object) +#define scheme_make_uninited_object (scheme_extension_table->scheme_make_uninited_object) +#define scheme_find_ivar (scheme_extension_table->scheme_find_ivar) +#define scheme_is_subclass (scheme_extension_table->scheme_is_subclass) +#define scheme_is_implementation (scheme_extension_table->scheme_is_implementation) +#define scheme_is_interface_extension (scheme_extension_table->scheme_is_interface_extension) +#define scheme_is_a (scheme_extension_table->scheme_is_a) +#define scheme_get_class_name (scheme_extension_table->scheme_get_class_name) +#define scheme_get_interface_name (scheme_extension_table->scheme_get_interface_name) +#define scheme_make_class_assembly (scheme_extension_table->scheme_make_class_assembly) +#define scheme_create_class (scheme_extension_table->scheme_create_class) +#define scheme_make_interface_assembly (scheme_extension_table->scheme_make_interface_assembly) +#define scheme_create_interface (scheme_extension_table->scheme_create_interface) +#define scheme_apply_generic_data (scheme_extension_table->scheme_apply_generic_data) +#define scheme_get_generic_data (scheme_extension_table->scheme_get_generic_data) +#endif +#define scheme_invoke_unit (scheme_extension_table->scheme_invoke_unit) +#define scheme_assemble_compound_unit (scheme_extension_table->scheme_assemble_compound_unit) +#define scheme_make_compound_unit (scheme_extension_table->scheme_make_compound_unit) +#define scheme_get_unit_name (scheme_extension_table->scheme_get_unit_name) +#define scheme_eq (scheme_extension_table->scheme_eq) +#define scheme_eqv (scheme_extension_table->scheme_eqv) +#define scheme_equal (scheme_extension_table->scheme_equal) +#define scheme_build_list (scheme_extension_table->scheme_build_list) +#define scheme_list_length (scheme_extension_table->scheme_list_length) +#define scheme_proper_list_length (scheme_extension_table->scheme_proper_list_length) +#define scheme_alloc_list (scheme_extension_table->scheme_alloc_list) +#define scheme_map_1 (scheme_extension_table->scheme_map_1) +#define scheme_car (scheme_extension_table->scheme_car) +#define scheme_cdr (scheme_extension_table->scheme_cdr) +#define scheme_cadr (scheme_extension_table->scheme_cadr) +#define scheme_caddr (scheme_extension_table->scheme_caddr) +#define scheme_vector_to_list (scheme_extension_table->scheme_vector_to_list) +#define scheme_list_to_vector (scheme_extension_table->scheme_list_to_vector) +#define scheme_append (scheme_extension_table->scheme_append) +#define scheme_box (scheme_extension_table->scheme_box) +#define scheme_unbox (scheme_extension_table->scheme_unbox) +#define scheme_set_box (scheme_extension_table->scheme_set_box) +#define scheme_make_weak_box (scheme_extension_table->scheme_make_weak_box) +#define scheme_load (scheme_extension_table->scheme_load) +#define scheme_load_extension (scheme_extension_table->scheme_load_extension) +#define scheme_register_extension_global (scheme_extension_table->scheme_register_extension_global) +#define scheme_get_milliseconds (scheme_extension_table->scheme_get_milliseconds) +#define scheme_get_process_milliseconds (scheme_extension_table->scheme_get_process_milliseconds) +#define scheme_rep (scheme_extension_table->scheme_rep) +#define scheme_banner (scheme_extension_table->scheme_banner) +#define scheme_version (scheme_extension_table->scheme_version) +#define scheme_check_proc_arity (scheme_extension_table->scheme_check_proc_arity) +#define scheme_secure_exceptions (scheme_extension_table->scheme_secure_exceptions) +#define scheme_make_provided_string (scheme_extension_table->scheme_make_provided_string) +#define scheme_make_args_string (scheme_extension_table->scheme_make_args_string) +#define scheme_no_dumps (scheme_extension_table->scheme_no_dumps) +#define scheme_system_library_subpath (scheme_extension_table->scheme_system_library_subpath) diff --git a/collects/mzscheme/include/schexn.h b/collects/mzscheme/include/schexn.h new file mode 100644 index 0000000..3453803 --- /dev/null +++ b/collects/mzscheme/include/schexn.h @@ -0,0 +1,515 @@ +/* This file was generated by makeexn */ +#ifndef _MZEXN_DEFINES +#define _MZEXN_DEFINES + +enum { + MZEXN, + MZEXN_USER, + MZEXN_SYNTAX, + MZEXN_VARIABLE, + MZEXN_APPLICATION, + MZEXN_APPLICATION_NON_PROCEDURE, + MZEXN_APPLICATION_ARITY, + MZEXN_APPLICATION_TYPE, + MZEXN_APPLICATION_RANGE, + MZEXN_APPLICATION_RANGE_BOUNDS, + MZEXN_APPLICATION_RANGE_BOUNDS_VECTOR, + MZEXN_APPLICATION_RANGE_BOUNDS_STRING, + MZEXN_APPLICATION_RANGE_BOUNDS_STRUCT, + MZEXN_APPLICATION_RANGE_LIST, + MZEXN_APPLICATION_LIST_SIZES, + MZEXN_APPLICATION_MAP_ARITY, + MZEXN_APPLICATION_INTEGER, + MZEXN_APPLICATION_LIST, + MZEXN_APPLICATION_MATH, + MZEXN_APPLICATION_MATH_ZERO, + MZEXN_APPLICATION_MATH_INFINITY, + MZEXN_APPLICATION_MATH_NEGATIVE, + MZEXN_APPLICATION_MATH_RADIX, + MZEXN_APPLICATION_MODE_CONFLICT, + MZEXN_APPLICATION_FILE_POSITION, + MZEXN_APPLICATION_FPRINTF, + MZEXN_APPLICATION_FPRINTF_EXTRA_ARGUMENTS, + MZEXN_APPLICATION_FPRINTF_NO_ARGUMENT, + MZEXN_APPLICATION_FPRINTF_ARGUMENT_TYPE, + MZEXN_ELSE, + MZEXN_STRUCT, + MZEXN_STRUCT_STRUCT_TYPE, + MZEXN_OBJECT, + MZEXN_OBJECT_CLASS_TYPE, + MZEXN_OBJECT_INTERFACE_TYPE, + MZEXN_OBJECT_GENERIC, + MZEXN_OBJECT_INHERIT, + MZEXN_OBJECT_IMPLEMENT, + MZEXN_OBJECT_CLASS_IVAR, + MZEXN_OBJECT_INTERFACE_IVAR, + MZEXN_OBJECT_IVAR, + MZEXN_OBJECT_PRIVATE_CLASS, + MZEXN_OBJECT_INIT, + MZEXN_OBJECT_INIT_MULTIPLE, + MZEXN_OBJECT_INIT_NEVER, + MZEXN_UNIT, + MZEXN_UNIT_NON_UNIT, + MZEXN_UNIT_ARITY, + MZEXN_UNIT_IMPORT, + MZEXN_UNIT_EXPORT, + MZEXN_UNIT_INVOKE, + MZEXN_UNIT_INVOKE_VARIABLE, + MZEXN_UNIT_SIGNATURE, + MZEXN_UNIT_SIGNATURE_NON_SIGNED_UNIT, + MZEXN_UNIT_SIGNATURE_ARITY, + MZEXN_UNIT_SIGNATURE_MATCH, + MZEXN_UNIT_SIGNATURE_MATCH_MISSING, + MZEXN_UNIT_SIGNATURE_MATCH_EXTRA, + MZEXN_UNIT_SIGNATURE_MATCH_KIND, + MZEXN_READ, + MZEXN_READ_PAREN, + MZEXN_READ_NUMBER, + MZEXN_READ_CHAR, + MZEXN_READ_EOF, + MZEXN_READ_DOT, + MZEXN_READ_UNSUPPORTED, + MZEXN_READ_VECTOR_LENGTH, + MZEXN_READ_COMPILED, + MZEXN_READ_GRAPH, + MZEXN_I_O, + MZEXN_I_O_READ, + MZEXN_I_O_WRITE, + MZEXN_I_O_FILESYSTEM, + MZEXN_I_O_FILESYSTEM_PATH, + MZEXN_I_O_FILESYSTEM_PATH_USERNAME, + MZEXN_I_O_FILESYSTEM_FILE, + MZEXN_I_O_FILESYSTEM_DIRECTORY, + MZEXN_I_O_FILESYSTEM_COLLECTION, + MZEXN_I_O_FILESYSTEM_FILE_EXISTS, + MZEXN_I_O_PORT_CLOSED, + MZEXN_I_O_USER_PORT, + MZEXN_I_O_TCP, + MZEXN_I_O_TCP_CONNECT, + MZEXN_I_O_TCP_LISTEN, + MZEXN_I_O_TCP_ACCEPT, + MZEXN_I_O_TCP_LISTENER_CLOSED, + MZEXN_MISC, + MZEXN_MISC_UNSUPPORTED, + MZEXN_MISC_USER_BREAK, + MZEXN_MISC_OUT_OF_MEMORY, + MZEXN_MISC_PARAMETERIZATION, + MZEXN_MISC_DEFMACRO, + MZEXN_MISC_EXPANSION_TIME, + MZEXN_MISC_CONSTANT, + MZEXN_MISC_CONTINUATION, + MZEXN_MISC_THREAD, + MZEXN_MISC_THREAD_KILL, + MZEXN_MISC_SEMAPHORE, + MZEXN_MISC_HASH_TABLE, + MZEXN_MISC_REGEXP, + MZEXN_MISC_PROCESS, + MZEXN_MISC_DYNAMIC_EXTENSION, + MZEXN_MISC_DYNAMIC_EXTENSION_OPEN, + MZEXN_MISC_DYNAMIC_EXTENSION_VERSION, + MZEXN_MISC_DYNAMIC_EXTENSION_INITIALIZE, + MZEXN_MISC_IMAGE, + MZEXN_OTHER +}; + +#endif + +#ifdef _MZEXN_TABLE + +#define MZEXN_MAXARGS 7 + +#ifdef GLOBAL_EXN_ARRAY +static exn_rec exn_table[] = { + { 2, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 5, NULL, NULL, 0 }, + { 5, NULL, NULL, 0 }, + { 5, NULL, NULL, 0 }, + { 5, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 7, NULL, NULL, 0 }, + { 5, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 5, NULL, NULL, 0 }, + { 5, NULL, NULL, 0 }, + { 5, NULL, NULL, 0 }, + { 5, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 4, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 2, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 }, + { 3, NULL, NULL, 0 } +}; +#else +static exn_rec *exn_table; +#endif + +#endif + +#ifdef _MZEXN_PRESETUP + +#ifndef GLOBAL_EXN_ARRAY + exn_table = (exn_rec *)scheme_malloc(sizeof(exn_rec) * MZEXN_OTHER); + exn_table[MZEXN].args = 2; + exn_table[MZEXN_USER].args = 2; + exn_table[MZEXN_SYNTAX].args = 3; + exn_table[MZEXN_VARIABLE].args = 3; + exn_table[MZEXN_APPLICATION].args = 3; + exn_table[MZEXN_APPLICATION_NON_PROCEDURE].args = 3; + exn_table[MZEXN_APPLICATION_ARITY].args = 4; + exn_table[MZEXN_APPLICATION_TYPE].args = 4; + exn_table[MZEXN_APPLICATION_RANGE].args = 3; + exn_table[MZEXN_APPLICATION_RANGE_BOUNDS].args = 5; + exn_table[MZEXN_APPLICATION_RANGE_BOUNDS_VECTOR].args = 5; + exn_table[MZEXN_APPLICATION_RANGE_BOUNDS_STRING].args = 5; + exn_table[MZEXN_APPLICATION_RANGE_BOUNDS_STRUCT].args = 5; + exn_table[MZEXN_APPLICATION_RANGE_LIST].args = 3; + exn_table[MZEXN_APPLICATION_LIST_SIZES].args = 3; + exn_table[MZEXN_APPLICATION_MAP_ARITY].args = 4; + exn_table[MZEXN_APPLICATION_INTEGER].args = 3; + exn_table[MZEXN_APPLICATION_LIST].args = 3; + exn_table[MZEXN_APPLICATION_MATH].args = 3; + exn_table[MZEXN_APPLICATION_MATH_ZERO].args = 3; + exn_table[MZEXN_APPLICATION_MATH_INFINITY].args = 3; + exn_table[MZEXN_APPLICATION_MATH_NEGATIVE].args = 3; + exn_table[MZEXN_APPLICATION_MATH_RADIX].args = 3; + exn_table[MZEXN_APPLICATION_MODE_CONFLICT].args = 4; + exn_table[MZEXN_APPLICATION_FILE_POSITION].args = 3; + exn_table[MZEXN_APPLICATION_FPRINTF].args = 3; + exn_table[MZEXN_APPLICATION_FPRINTF_EXTRA_ARGUMENTS].args = 4; + exn_table[MZEXN_APPLICATION_FPRINTF_NO_ARGUMENT].args = 3; + exn_table[MZEXN_APPLICATION_FPRINTF_ARGUMENT_TYPE].args = 4; + exn_table[MZEXN_ELSE].args = 2; + exn_table[MZEXN_STRUCT].args = 2; + exn_table[MZEXN_STRUCT_STRUCT_TYPE].args = 3; + exn_table[MZEXN_OBJECT].args = 2; + exn_table[MZEXN_OBJECT_CLASS_TYPE].args = 3; + exn_table[MZEXN_OBJECT_INTERFACE_TYPE].args = 3; + exn_table[MZEXN_OBJECT_GENERIC].args = 3; + exn_table[MZEXN_OBJECT_INHERIT].args = 3; + exn_table[MZEXN_OBJECT_IMPLEMENT].args = 3; + exn_table[MZEXN_OBJECT_CLASS_IVAR].args = 4; + exn_table[MZEXN_OBJECT_INTERFACE_IVAR].args = 4; + exn_table[MZEXN_OBJECT_IVAR].args = 4; + exn_table[MZEXN_OBJECT_PRIVATE_CLASS].args = 3; + exn_table[MZEXN_OBJECT_INIT].args = 4; + exn_table[MZEXN_OBJECT_INIT_MULTIPLE].args = 4; + exn_table[MZEXN_OBJECT_INIT_NEVER].args = 4; + exn_table[MZEXN_UNIT].args = 2; + exn_table[MZEXN_UNIT_NON_UNIT].args = 3; + exn_table[MZEXN_UNIT_ARITY].args = 3; + exn_table[MZEXN_UNIT_IMPORT].args = 7; + exn_table[MZEXN_UNIT_EXPORT].args = 5; + exn_table[MZEXN_UNIT_INVOKE].args = 2; + exn_table[MZEXN_UNIT_INVOKE_VARIABLE].args = 3; + exn_table[MZEXN_UNIT_SIGNATURE].args = 2; + exn_table[MZEXN_UNIT_SIGNATURE_NON_SIGNED_UNIT].args = 3; + exn_table[MZEXN_UNIT_SIGNATURE_ARITY].args = 3; + exn_table[MZEXN_UNIT_SIGNATURE_MATCH].args = 5; + exn_table[MZEXN_UNIT_SIGNATURE_MATCH_MISSING].args = 5; + exn_table[MZEXN_UNIT_SIGNATURE_MATCH_EXTRA].args = 5; + exn_table[MZEXN_UNIT_SIGNATURE_MATCH_KIND].args = 5; + exn_table[MZEXN_READ].args = 3; + exn_table[MZEXN_READ_PAREN].args = 3; + exn_table[MZEXN_READ_NUMBER].args = 4; + exn_table[MZEXN_READ_CHAR].args = 4; + exn_table[MZEXN_READ_EOF].args = 4; + exn_table[MZEXN_READ_DOT].args = 3; + exn_table[MZEXN_READ_UNSUPPORTED].args = 4; + exn_table[MZEXN_READ_VECTOR_LENGTH].args = 4; + exn_table[MZEXN_READ_COMPILED].args = 3; + exn_table[MZEXN_READ_GRAPH].args = 3; + exn_table[MZEXN_I_O].args = 2; + exn_table[MZEXN_I_O_READ].args = 3; + exn_table[MZEXN_I_O_WRITE].args = 3; + exn_table[MZEXN_I_O_FILESYSTEM].args = 3; + exn_table[MZEXN_I_O_FILESYSTEM_PATH].args = 3; + exn_table[MZEXN_I_O_FILESYSTEM_PATH_USERNAME].args = 3; + exn_table[MZEXN_I_O_FILESYSTEM_FILE].args = 3; + exn_table[MZEXN_I_O_FILESYSTEM_DIRECTORY].args = 3; + exn_table[MZEXN_I_O_FILESYSTEM_COLLECTION].args = 3; + exn_table[MZEXN_I_O_FILESYSTEM_FILE_EXISTS].args = 3; + exn_table[MZEXN_I_O_PORT_CLOSED].args = 3; + exn_table[MZEXN_I_O_USER_PORT].args = 3; + exn_table[MZEXN_I_O_TCP].args = 2; + exn_table[MZEXN_I_O_TCP_CONNECT].args = 4; + exn_table[MZEXN_I_O_TCP_LISTEN].args = 3; + exn_table[MZEXN_I_O_TCP_ACCEPT].args = 3; + exn_table[MZEXN_I_O_TCP_LISTENER_CLOSED].args = 3; + exn_table[MZEXN_MISC].args = 2; + exn_table[MZEXN_MISC_UNSUPPORTED].args = 2; + exn_table[MZEXN_MISC_USER_BREAK].args = 2; + exn_table[MZEXN_MISC_OUT_OF_MEMORY].args = 2; + exn_table[MZEXN_MISC_PARAMETERIZATION].args = 3; + exn_table[MZEXN_MISC_DEFMACRO].args = 3; + exn_table[MZEXN_MISC_EXPANSION_TIME].args = 2; + exn_table[MZEXN_MISC_CONSTANT].args = 3; + exn_table[MZEXN_MISC_CONTINUATION].args = 2; + exn_table[MZEXN_MISC_THREAD].args = 2; + exn_table[MZEXN_MISC_THREAD_KILL].args = 2; + exn_table[MZEXN_MISC_SEMAPHORE].args = 2; + exn_table[MZEXN_MISC_HASH_TABLE].args = 3; + exn_table[MZEXN_MISC_REGEXP].args = 2; + exn_table[MZEXN_MISC_PROCESS].args = 2; + exn_table[MZEXN_MISC_DYNAMIC_EXTENSION].args = 3; + exn_table[MZEXN_MISC_DYNAMIC_EXTENSION_OPEN].args = 3; + exn_table[MZEXN_MISC_DYNAMIC_EXTENSION_VERSION].args = 3; + exn_table[MZEXN_MISC_DYNAMIC_EXTENSION_INITIALIZE].args = 3; + exn_table[MZEXN_MISC_IMAGE].args = 3; +#endif + +#endif + +#ifdef _MZEXN_DECL_FIELDS + +static const char *MZEXN_FIELDS[2] = { "message", "debug-info" }; +static const char *MZEXN_SYNTAX_FIELDS[1] = { "expr" }; +static const char *MZEXN_VARIABLE_FIELDS[1] = { "id" }; +static const char *MZEXN_APPLICATION_FIELDS[1] = { "value" }; +static const char *MZEXN_APPLICATION_ARITY_FIELDS[1] = { "expected" }; +static const char *MZEXN_APPLICATION_TYPE_FIELDS[1] = { "expected" }; +static const char *MZEXN_APPLICATION_RANGE_BOUNDS_FIELDS[2] = { "min", "max" }; +static const char *MZEXN_APPLICATION_MAP_ARITY_FIELDS[1] = { "provided" }; +static const char *MZEXN_APPLICATION_MODE_CONFLICT_FIELDS[1] = { "filename" }; +static const char *MZEXN_APPLICATION_FPRINTF_EXTRA_ARGUMENTS_FIELDS[1] = { "extras" }; +static const char *MZEXN_APPLICATION_FPRINTF_ARGUMENT_TYPE_FIELDS[1] = { "expected" }; +static const char *MZEXN_STRUCT_STRUCT_TYPE_FIELDS[1] = { "value" }; +static const char *MZEXN_OBJECT_CLASS_TYPE_FIELDS[1] = { "value" }; +static const char *MZEXN_OBJECT_INTERFACE_TYPE_FIELDS[1] = { "value" }; +static const char *MZEXN_OBJECT_GENERIC_FIELDS[1] = { "object" }; +static const char *MZEXN_OBJECT_INHERIT_FIELDS[1] = { "ivar" }; +static const char *MZEXN_OBJECT_IMPLEMENT_FIELDS[1] = { "ivar" }; +static const char *MZEXN_OBJECT_CLASS_IVAR_FIELDS[2] = { "class", "ivar" }; +static const char *MZEXN_OBJECT_INTERFACE_IVAR_FIELDS[2] = { "interface", "ivar" }; +static const char *MZEXN_OBJECT_IVAR_FIELDS[2] = { "object", "ivar" }; +static const char *MZEXN_OBJECT_PRIVATE_CLASS_FIELDS[1] = { "class" }; +static const char *MZEXN_OBJECT_INIT_FIELDS[2] = { "object", "class" }; +static const char *MZEXN_UNIT_NON_UNIT_FIELDS[1] = { "value" }; +static const char *MZEXN_UNIT_ARITY_FIELDS[1] = { "unit" }; +static const char *MZEXN_UNIT_IMPORT_FIELDS[5] = { "in-unit", "out-unit", "in-tag", "out-tag", "name" }; +static const char *MZEXN_UNIT_EXPORT_FIELDS[3] = { "unit", "tag", "name" }; +static const char *MZEXN_UNIT_INVOKE_VARIABLE_FIELDS[1] = { "name" }; +static const char *MZEXN_UNIT_SIGNATURE_NON_SIGNED_UNIT_FIELDS[1] = { "value" }; +static const char *MZEXN_UNIT_SIGNATURE_ARITY_FIELDS[1] = { "unit" }; +static const char *MZEXN_UNIT_SIGNATURE_MATCH_FIELDS[3] = { "dest-context", "src-context", "variable" }; +static const char *MZEXN_READ_FIELDS[1] = { "port" }; +static const char *MZEXN_READ_NUMBER_FIELDS[1] = { "input" }; +static const char *MZEXN_READ_CHAR_FIELDS[1] = { "input" }; +static const char *MZEXN_READ_EOF_FIELDS[1] = { "expected" }; +static const char *MZEXN_READ_UNSUPPORTED_FIELDS[1] = { "input" }; +static const char *MZEXN_READ_VECTOR_LENGTH_FIELDS[1] = { "input" }; +static const char *MZEXN_I_O_READ_FIELDS[1] = { "port" }; +static const char *MZEXN_I_O_WRITE_FIELDS[1] = { "port" }; +static const char *MZEXN_I_O_FILESYSTEM_FIELDS[1] = { "pathname" }; +static const char *MZEXN_I_O_PORT_CLOSED_FIELDS[1] = { "port" }; +static const char *MZEXN_I_O_USER_PORT_FIELDS[1] = { "port" }; +static const char *MZEXN_I_O_TCP_CONNECT_FIELDS[2] = { "address", "port-id" }; +static const char *MZEXN_I_O_TCP_LISTEN_FIELDS[1] = { "port-id" }; +static const char *MZEXN_I_O_TCP_ACCEPT_FIELDS[1] = { "listener" }; +static const char *MZEXN_I_O_TCP_LISTENER_CLOSED_FIELDS[1] = { "listener" }; +static const char *MZEXN_MISC_PARAMETERIZATION_FIELDS[1] = { "value" }; +static const char *MZEXN_MISC_DEFMACRO_FIELDS[1] = { "value" }; +static const char *MZEXN_MISC_CONSTANT_FIELDS[1] = { "id" }; +static const char *MZEXN_MISC_HASH_TABLE_FIELDS[1] = { "key" }; +static const char *MZEXN_MISC_DYNAMIC_EXTENSION_FIELDS[1] = { "name" }; +static const char *MZEXN_MISC_IMAGE_FIELDS[1] = { "name" }; + +#endif + +#ifdef _MZEXN_SETUP + + SETUP_STRUCT(MZEXN, NULL, "exn", 2, MZEXN_FIELDS) + SETUP_STRUCT(MZEXN_USER, EXN_PARENT(MZEXN), "exn:user", 0, NULL) + SETUP_STRUCT(MZEXN_SYNTAX, EXN_PARENT(MZEXN), "exn:syntax", 1, MZEXN_SYNTAX_FIELDS) + SETUP_STRUCT(MZEXN_VARIABLE, EXN_PARENT(MZEXN), "exn:variable", 1, MZEXN_VARIABLE_FIELDS) + SETUP_STRUCT(MZEXN_APPLICATION, EXN_PARENT(MZEXN), "exn:application", 1, MZEXN_APPLICATION_FIELDS) + SETUP_STRUCT(MZEXN_APPLICATION_NON_PROCEDURE, EXN_PARENT(MZEXN_APPLICATION), "exn:application:non-procedure", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_ARITY, EXN_PARENT(MZEXN_APPLICATION), "exn:application:arity", 1, MZEXN_APPLICATION_ARITY_FIELDS) + SETUP_STRUCT(MZEXN_APPLICATION_TYPE, EXN_PARENT(MZEXN_APPLICATION), "exn:application:type", 1, MZEXN_APPLICATION_TYPE_FIELDS) + SETUP_STRUCT(MZEXN_APPLICATION_RANGE, EXN_PARENT(MZEXN_APPLICATION), "exn:application:range", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_RANGE_BOUNDS, EXN_PARENT(MZEXN_APPLICATION_RANGE), "exn:application:range:bounds", 2, MZEXN_APPLICATION_RANGE_BOUNDS_FIELDS) + SETUP_STRUCT(MZEXN_APPLICATION_RANGE_BOUNDS_VECTOR, EXN_PARENT(MZEXN_APPLICATION_RANGE_BOUNDS), "exn:application:range:bounds:vector", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_RANGE_BOUNDS_STRING, EXN_PARENT(MZEXN_APPLICATION_RANGE_BOUNDS), "exn:application:range:bounds:string", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_RANGE_BOUNDS_STRUCT, EXN_PARENT(MZEXN_APPLICATION_RANGE_BOUNDS), "exn:application:range:bounds:struct", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_RANGE_LIST, EXN_PARENT(MZEXN_APPLICATION_RANGE), "exn:application:range:list", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_LIST_SIZES, EXN_PARENT(MZEXN_APPLICATION), "exn:application:list-sizes", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_MAP_ARITY, EXN_PARENT(MZEXN_APPLICATION), "exn:application:map-arity", 1, MZEXN_APPLICATION_MAP_ARITY_FIELDS) + SETUP_STRUCT(MZEXN_APPLICATION_INTEGER, EXN_PARENT(MZEXN_APPLICATION), "exn:application:integer", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_LIST, EXN_PARENT(MZEXN_APPLICATION), "exn:application:list", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_MATH, EXN_PARENT(MZEXN_APPLICATION), "exn:application:math", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_MATH_ZERO, EXN_PARENT(MZEXN_APPLICATION_MATH), "exn:application:math:zero", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_MATH_INFINITY, EXN_PARENT(MZEXN_APPLICATION_MATH), "exn:application:math:infinity", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_MATH_NEGATIVE, EXN_PARENT(MZEXN_APPLICATION_MATH), "exn:application:math:negative", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_MATH_RADIX, EXN_PARENT(MZEXN_APPLICATION_MATH), "exn:application:math:radix", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_MODE_CONFLICT, EXN_PARENT(MZEXN_APPLICATION), "exn:application:mode-conflict", 1, MZEXN_APPLICATION_MODE_CONFLICT_FIELDS) + SETUP_STRUCT(MZEXN_APPLICATION_FILE_POSITION, EXN_PARENT(MZEXN_APPLICATION), "exn:application:file-position", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_FPRINTF, EXN_PARENT(MZEXN_APPLICATION), "exn:application:fprintf", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_FPRINTF_EXTRA_ARGUMENTS, EXN_PARENT(MZEXN_APPLICATION_FPRINTF), "exn:application:fprintf:extra-arguments", 1, MZEXN_APPLICATION_FPRINTF_EXTRA_ARGUMENTS_FIELDS) + SETUP_STRUCT(MZEXN_APPLICATION_FPRINTF_NO_ARGUMENT, EXN_PARENT(MZEXN_APPLICATION_FPRINTF), "exn:application:fprintf:no-argument", 0, NULL) + SETUP_STRUCT(MZEXN_APPLICATION_FPRINTF_ARGUMENT_TYPE, EXN_PARENT(MZEXN_APPLICATION_FPRINTF), "exn:application:fprintf:argument-type", 1, MZEXN_APPLICATION_FPRINTF_ARGUMENT_TYPE_FIELDS) + SETUP_STRUCT(MZEXN_ELSE, EXN_PARENT(MZEXN), "exn:else", 0, NULL) + SETUP_STRUCT(MZEXN_STRUCT, EXN_PARENT(MZEXN), "exn:struct", 0, NULL) + SETUP_STRUCT(MZEXN_STRUCT_STRUCT_TYPE, EXN_PARENT(MZEXN_STRUCT), "exn:struct:struct-type", 1, MZEXN_STRUCT_STRUCT_TYPE_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT, EXN_PARENT(MZEXN), "exn:object", 0, NULL) + SETUP_STRUCT(MZEXN_OBJECT_CLASS_TYPE, EXN_PARENT(MZEXN_OBJECT), "exn:object:class-type", 1, MZEXN_OBJECT_CLASS_TYPE_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT_INTERFACE_TYPE, EXN_PARENT(MZEXN_OBJECT), "exn:object:interface-type", 1, MZEXN_OBJECT_INTERFACE_TYPE_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT_GENERIC, EXN_PARENT(MZEXN_OBJECT), "exn:object:generic", 1, MZEXN_OBJECT_GENERIC_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT_INHERIT, EXN_PARENT(MZEXN_OBJECT), "exn:object:inherit", 1, MZEXN_OBJECT_INHERIT_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT_IMPLEMENT, EXN_PARENT(MZEXN_OBJECT), "exn:object:implement", 1, MZEXN_OBJECT_IMPLEMENT_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT_CLASS_IVAR, EXN_PARENT(MZEXN_OBJECT), "exn:object:class-ivar", 2, MZEXN_OBJECT_CLASS_IVAR_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT_INTERFACE_IVAR, EXN_PARENT(MZEXN_OBJECT), "exn:object:interface-ivar", 2, MZEXN_OBJECT_INTERFACE_IVAR_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT_IVAR, EXN_PARENT(MZEXN_OBJECT), "exn:object:ivar", 2, MZEXN_OBJECT_IVAR_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT_PRIVATE_CLASS, EXN_PARENT(MZEXN_OBJECT), "exn:object:private-class", 1, MZEXN_OBJECT_PRIVATE_CLASS_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT_INIT, EXN_PARENT(MZEXN_OBJECT), "exn:object:init", 2, MZEXN_OBJECT_INIT_FIELDS) + SETUP_STRUCT(MZEXN_OBJECT_INIT_MULTIPLE, EXN_PARENT(MZEXN_OBJECT_INIT), "exn:object:init:multiple", 0, NULL) + SETUP_STRUCT(MZEXN_OBJECT_INIT_NEVER, EXN_PARENT(MZEXN_OBJECT_INIT), "exn:object:init:never", 0, NULL) + SETUP_STRUCT(MZEXN_UNIT, EXN_PARENT(MZEXN), "exn:unit", 0, NULL) + SETUP_STRUCT(MZEXN_UNIT_NON_UNIT, EXN_PARENT(MZEXN_UNIT), "exn:unit:non-unit", 1, MZEXN_UNIT_NON_UNIT_FIELDS) + SETUP_STRUCT(MZEXN_UNIT_ARITY, EXN_PARENT(MZEXN_UNIT), "exn:unit:arity", 1, MZEXN_UNIT_ARITY_FIELDS) + SETUP_STRUCT(MZEXN_UNIT_IMPORT, EXN_PARENT(MZEXN_UNIT), "exn:unit:import", 5, MZEXN_UNIT_IMPORT_FIELDS) + SETUP_STRUCT(MZEXN_UNIT_EXPORT, EXN_PARENT(MZEXN_UNIT), "exn:unit:export", 3, MZEXN_UNIT_EXPORT_FIELDS) + SETUP_STRUCT(MZEXN_UNIT_INVOKE, EXN_PARENT(MZEXN_UNIT), "exn:unit:invoke", 0, NULL) + SETUP_STRUCT(MZEXN_UNIT_INVOKE_VARIABLE, EXN_PARENT(MZEXN_UNIT_INVOKE), "exn:unit:invoke:variable", 1, MZEXN_UNIT_INVOKE_VARIABLE_FIELDS) + SETUP_STRUCT(MZEXN_UNIT_SIGNATURE, EXN_PARENT(MZEXN_UNIT), "exn:unit:signature", 0, NULL) + SETUP_STRUCT(MZEXN_UNIT_SIGNATURE_NON_SIGNED_UNIT, EXN_PARENT(MZEXN_UNIT_SIGNATURE), "exn:unit:signature:non-signed-unit", 1, MZEXN_UNIT_SIGNATURE_NON_SIGNED_UNIT_FIELDS) + SETUP_STRUCT(MZEXN_UNIT_SIGNATURE_ARITY, EXN_PARENT(MZEXN_UNIT_SIGNATURE), "exn:unit:signature:arity", 1, MZEXN_UNIT_SIGNATURE_ARITY_FIELDS) + SETUP_STRUCT(MZEXN_UNIT_SIGNATURE_MATCH, EXN_PARENT(MZEXN_UNIT_SIGNATURE), "exn:unit:signature:match", 3, MZEXN_UNIT_SIGNATURE_MATCH_FIELDS) + SETUP_STRUCT(MZEXN_UNIT_SIGNATURE_MATCH_MISSING, EXN_PARENT(MZEXN_UNIT_SIGNATURE_MATCH), "exn:unit:signature:match:missing", 0, NULL) + SETUP_STRUCT(MZEXN_UNIT_SIGNATURE_MATCH_EXTRA, EXN_PARENT(MZEXN_UNIT_SIGNATURE_MATCH), "exn:unit:signature:match:extra", 0, NULL) + SETUP_STRUCT(MZEXN_UNIT_SIGNATURE_MATCH_KIND, EXN_PARENT(MZEXN_UNIT_SIGNATURE_MATCH), "exn:unit:signature:match:kind", 0, NULL) + SETUP_STRUCT(MZEXN_READ, EXN_PARENT(MZEXN), "exn:read", 1, MZEXN_READ_FIELDS) + SETUP_STRUCT(MZEXN_READ_PAREN, EXN_PARENT(MZEXN_READ), "exn:read:paren", 0, NULL) + SETUP_STRUCT(MZEXN_READ_NUMBER, EXN_PARENT(MZEXN_READ), "exn:read:number", 1, MZEXN_READ_NUMBER_FIELDS) + SETUP_STRUCT(MZEXN_READ_CHAR, EXN_PARENT(MZEXN_READ), "exn:read:char", 1, MZEXN_READ_CHAR_FIELDS) + SETUP_STRUCT(MZEXN_READ_EOF, EXN_PARENT(MZEXN_READ), "exn:read:eof", 1, MZEXN_READ_EOF_FIELDS) + SETUP_STRUCT(MZEXN_READ_DOT, EXN_PARENT(MZEXN_READ), "exn:read:dot", 0, NULL) + SETUP_STRUCT(MZEXN_READ_UNSUPPORTED, EXN_PARENT(MZEXN_READ), "exn:read:unsupported", 1, MZEXN_READ_UNSUPPORTED_FIELDS) + SETUP_STRUCT(MZEXN_READ_VECTOR_LENGTH, EXN_PARENT(MZEXN_READ), "exn:read:vector-length", 1, MZEXN_READ_VECTOR_LENGTH_FIELDS) + SETUP_STRUCT(MZEXN_READ_COMPILED, EXN_PARENT(MZEXN_READ), "exn:read:compiled", 0, NULL) + SETUP_STRUCT(MZEXN_READ_GRAPH, EXN_PARENT(MZEXN_READ), "exn:read:graph", 0, NULL) + SETUP_STRUCT(MZEXN_I_O, EXN_PARENT(MZEXN), "exn:i/o", 0, NULL) + SETUP_STRUCT(MZEXN_I_O_READ, EXN_PARENT(MZEXN_I_O), "exn:i/o:read", 1, MZEXN_I_O_READ_FIELDS) + SETUP_STRUCT(MZEXN_I_O_WRITE, EXN_PARENT(MZEXN_I_O), "exn:i/o:write", 1, MZEXN_I_O_WRITE_FIELDS) + SETUP_STRUCT(MZEXN_I_O_FILESYSTEM, EXN_PARENT(MZEXN_I_O), "exn:i/o:filesystem", 1, MZEXN_I_O_FILESYSTEM_FIELDS) + SETUP_STRUCT(MZEXN_I_O_FILESYSTEM_PATH, EXN_PARENT(MZEXN_I_O_FILESYSTEM), "exn:i/o:filesystem:path", 0, NULL) + SETUP_STRUCT(MZEXN_I_O_FILESYSTEM_PATH_USERNAME, EXN_PARENT(MZEXN_I_O_FILESYSTEM_PATH), "exn:i/o:filesystem:path:username", 0, NULL) + SETUP_STRUCT(MZEXN_I_O_FILESYSTEM_FILE, EXN_PARENT(MZEXN_I_O_FILESYSTEM), "exn:i/o:filesystem:file", 0, NULL) + SETUP_STRUCT(MZEXN_I_O_FILESYSTEM_DIRECTORY, EXN_PARENT(MZEXN_I_O_FILESYSTEM), "exn:i/o:filesystem:directory", 0, NULL) + SETUP_STRUCT(MZEXN_I_O_FILESYSTEM_COLLECTION, EXN_PARENT(MZEXN_I_O_FILESYSTEM), "exn:i/o:filesystem:collection", 0, NULL) + SETUP_STRUCT(MZEXN_I_O_FILESYSTEM_FILE_EXISTS, EXN_PARENT(MZEXN_I_O_FILESYSTEM), "exn:i/o:filesystem:file-exists", 0, NULL) + SETUP_STRUCT(MZEXN_I_O_PORT_CLOSED, EXN_PARENT(MZEXN_I_O), "exn:i/o:port-closed", 1, MZEXN_I_O_PORT_CLOSED_FIELDS) + SETUP_STRUCT(MZEXN_I_O_USER_PORT, EXN_PARENT(MZEXN_I_O), "exn:i/o:user-port", 1, MZEXN_I_O_USER_PORT_FIELDS) + SETUP_STRUCT(MZEXN_I_O_TCP, EXN_PARENT(MZEXN_I_O), "exn:i/o:tcp", 0, NULL) + SETUP_STRUCT(MZEXN_I_O_TCP_CONNECT, EXN_PARENT(MZEXN_I_O_TCP), "exn:i/o:tcp:connect", 2, MZEXN_I_O_TCP_CONNECT_FIELDS) + SETUP_STRUCT(MZEXN_I_O_TCP_LISTEN, EXN_PARENT(MZEXN_I_O_TCP), "exn:i/o:tcp:listen", 1, MZEXN_I_O_TCP_LISTEN_FIELDS) + SETUP_STRUCT(MZEXN_I_O_TCP_ACCEPT, EXN_PARENT(MZEXN_I_O_TCP), "exn:i/o:tcp:accept", 1, MZEXN_I_O_TCP_ACCEPT_FIELDS) + SETUP_STRUCT(MZEXN_I_O_TCP_LISTENER_CLOSED, EXN_PARENT(MZEXN_I_O_TCP), "exn:i/o:tcp:listener-closed", 1, MZEXN_I_O_TCP_LISTENER_CLOSED_FIELDS) + SETUP_STRUCT(MZEXN_MISC, EXN_PARENT(MZEXN), "exn:misc", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_UNSUPPORTED, EXN_PARENT(MZEXN_MISC), "exn:misc:unsupported", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_USER_BREAK, EXN_PARENT(MZEXN_MISC), "exn:misc:user-break", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_OUT_OF_MEMORY, EXN_PARENT(MZEXN_MISC), "exn:misc:out-of-memory", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_PARAMETERIZATION, EXN_PARENT(MZEXN_MISC), "exn:misc:parameterization", 1, MZEXN_MISC_PARAMETERIZATION_FIELDS) + SETUP_STRUCT(MZEXN_MISC_DEFMACRO, EXN_PARENT(MZEXN_MISC), "exn:misc:defmacro", 1, MZEXN_MISC_DEFMACRO_FIELDS) + SETUP_STRUCT(MZEXN_MISC_EXPANSION_TIME, EXN_PARENT(MZEXN_MISC), "exn:misc:expansion-time", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_CONSTANT, EXN_PARENT(MZEXN_MISC), "exn:misc:constant", 1, MZEXN_MISC_CONSTANT_FIELDS) + SETUP_STRUCT(MZEXN_MISC_CONTINUATION, EXN_PARENT(MZEXN_MISC), "exn:misc:continuation", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_THREAD, EXN_PARENT(MZEXN_MISC), "exn:misc:thread", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_THREAD_KILL, EXN_PARENT(MZEXN_MISC_THREAD), "exn:misc:thread:kill", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_SEMAPHORE, EXN_PARENT(MZEXN_MISC), "exn:misc:semaphore", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_HASH_TABLE, EXN_PARENT(MZEXN_MISC), "exn:misc:hash-table", 1, MZEXN_MISC_HASH_TABLE_FIELDS) + SETUP_STRUCT(MZEXN_MISC_REGEXP, EXN_PARENT(MZEXN_MISC), "exn:misc:regexp", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_PROCESS, EXN_PARENT(MZEXN_MISC), "exn:misc:process", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_DYNAMIC_EXTENSION, EXN_PARENT(MZEXN_MISC), "exn:misc:dynamic-extension", 1, MZEXN_MISC_DYNAMIC_EXTENSION_FIELDS) + SETUP_STRUCT(MZEXN_MISC_DYNAMIC_EXTENSION_OPEN, EXN_PARENT(MZEXN_MISC_DYNAMIC_EXTENSION), "exn:misc:dynamic-extension:open", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_DYNAMIC_EXTENSION_VERSION, EXN_PARENT(MZEXN_MISC_DYNAMIC_EXTENSION), "exn:misc:dynamic-extension:version", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_DYNAMIC_EXTENSION_INITIALIZE, EXN_PARENT(MZEXN_MISC_DYNAMIC_EXTENSION), "exn:misc:dynamic-extension:initialize", 0, NULL) + SETUP_STRUCT(MZEXN_MISC_IMAGE, EXN_PARENT(MZEXN_MISC), "exn:misc:image", 1, MZEXN_MISC_IMAGE_FIELDS) + +#endif diff --git a/collects/mzscheme/include/sconfig.h b/collects/mzscheme/include/sconfig.h new file mode 100644 index 0000000..2118a74 --- /dev/null +++ b/collects/mzscheme/include/sconfig.h @@ -0,0 +1,962 @@ + +/* + Configuration for compiling MzScheme + + If you want to set all the flags externally (on the command line + with -D or some other compiler-dependent way), then define + FLAGS_ALREADY_SET, and this file will be ignored. + + One flag cannot be set in this file: INCLUDE_WITHOUT_PATHS. + Define this flag if your compiler doesn't like #include + statements with relative paths using ".." and "/". (You will + have to #define this for Macintosh CodeWarrior in the project + header.) + + The best flag settings are already provided for some auto-detected + architecture/system/compilers. Otherwise, the default settings + are generic Unix. Send other architecture/system/compiler-specific + info to "plt-bugs@cs.rice.edu". +*/ + +#ifndef FLAGS_ALREADY_SET + +/*************** (BEGIN PLATFORM-INDEPENDENT OPTIONS) *************/ + + /***********************/ + /* Language Extensions */ +/***********************/ + + /* NO_FILE_SYSTEM_UTILS removes most file system utilities. */ + + /* NO_OBJECT_SYSTEM removes MzScheme's object system. */ + + /* NO_REGEXP_UTILS removes MzScheme's regular expression utilities. */ + + /* NO_SCHEME_THREADS removes MzScheme's threads from the Scheme user. */ + + /* NO_SCHEME_EXNS removes MzScheme's exception system. */ + + /*******************************/ + /* Evaluator Tuning Parameters */ +/*******************************/ + +#define SCHEME_STACK_SIZE 5000 + + /* SCHEME_STACK_SIZE sets the limit for the internal stack + for Scheme variables. */ + +/**************** (END PLATFORM-INDEPENDENT OPTIONS) **************/ + + + +/******** (BEGIN KNOWN ARCHITECTURE/SYSTEM CONFIGURATIONS) ********/ + + /************** SunOS/Solaris with gcc ****************/ + +#if defined(sun) + +# include "uconfig.h" + +# define STACK_GROWS_DOWN + +# define USE_EXPLICT_FP_FORM_CHECK +# define POW_HANDLES_INF_CORRECTLY + +# include +# ifdef ECHRNG +/* Solaris */ +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "sparc-solaris" +# define DIRENT_NO_NAMLEN +# define RAND_NOT_RANDOM +# define NO_USLEEP +# define USE_ULIMIT +# define USE_FCNTL_O_NONBLOCK + +# ifdef SOLARIS_THREADS +# define MZ_REAL_THREADS +# define MZ_USE_SOLARIS_THREADS + +#ifdef __cplusplus +extern "C" { +#endif +void *scheme_solaris_init_threads(void); +void scheme_solaris_create_thread(void (*f)(void *), void *data, unsigned long *stackend, void **thp); +void scheme_solaris_exit_thread(); +void scheme_solaris_break_thread(void *th); +struct Scheme_Process *scheme_solaris_get_current_process(); +void scheme_solaris_set_current_process(struct Scheme_Process *); +void *scheme_solaris_make_mutex(); +void scheme_solaris_free_mutex(void *); +void scheme_solaris_lock_mutex(void *); +void scheme_solaris_unlock_mutex(void *); +void *scheme_solaris_make_semaphore(int init); +void scheme_solaris_free_semaphore(void *); +int scheme_solaris_semaphore_up(void *); +int scheme_solaris_semaphore_down_breakable(void *); +int scheme_solaris_semaphore_try_down(void *); +#ifdef __cplusplus +} +#endif + +#define SCHEME_INIT_THREADS() scheme_solaris_init_threads() +#define SCHEME_CREATE_THREAD(f, data, slimit, thp) scheme_solaris_create_thread(f, data, slimit, thp) +#define SCHEME_EXIT_THREAD() scheme_solaris_exit_thread() +#define SCHEME_BREAK_THREAD(th) scheme_solaris_break_thread(th) +#define SCHEME_GET_CURRENT_PROCESS() scheme_solaris_get_current_process() +#define SCHEME_SET_CURRENT_PROCESS(p) scheme_solaris_set_current_process(p) +#define SCHEME_MAKE_MUTEX() scheme_solaris_make_mutex() +#define SCHEME_FREE_MUTEX(m) scheme_solaris_free_mutex(m) +#define SCHEME_LOCK_MUTEX(m) scheme_solaris_make_mutex(m) +#define SCHEME_UNLOCK_MUTEX(m) scheme_solaris_make_mutex(m) +#define SCHEME_MAKE_SEMA(init) scheme_solaris_make_semaphore(init) +#define SCHEME_FREE_SEMA(s) scheme_solaris_free_semaphore(s) +#define SCHEME_SEMA_UP(s) scheme_solaris_semaphore_up(s) +#define SCHEME_SEMA_DOWN_BREAKABLE(s) scheme_solaris_semaphore_down_breakable(s) +#define SCHEME_SEMA_TRY_DOWN(s) scheme_solaris_semaphore_try_down(s) +# endif +# else +/* SunOS4 */ +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "sparc-sunos4" +# define SIGSET_IS_SIGNAL +# endif + +# define FLAGS_ALREADY_SET + +#endif + + /************** RS6000/AIX with gcc or xlc ****************/ + +# if defined(_IBMR2) + +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "rs6k-aix" + +# include "uconfig.h" +# undef UNIX_DYNAMIC_LOAD +# undef USE_FCHDIR + +# define STACK_GROWS_DOWN +# define UNIX_LIMIT_STACK 33554944 + +# define AIX_DYNAMIC_LOAD + +# define SELECT_INCLUDE + +# define POW_HANDLES_INF_CORRECTLY + +# define FLAGS_ALREADY_SET + +#endif + + /************** x86/Linux with gcc ****************/ + +#if defined(linux) + +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "i386-linux" + +# include "uconfig.h" +# undef HAS_STANDARD_IOB +#ifndef __ELF__ +# undef UNIX_DYNAMIC_LOAD +#endif + +# define DIRENT_NO_NAMLEN + +# define HAS_LINUX_IOB + +# define STACK_GROWS_DOWN + +# define USE_IEEE_FP_PREDS +# define LINUX_CONTROL_387 +# define USE_EXPLICT_FP_FORM_CHECK + +# define SIGSET_IS_SIGNAL +# define SIGSET_NEEDS_REINSTALL + +# define FLAGS_ALREADY_SET + +#endif + + /************** x86/FreeBSD with gcc ****************/ + +# if defined(__FreeBSD__) && defined(i386) + +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "i386-freebsd" + +# include "uconfig.h" +# undef HAS_STANDARD_IOB + +# define HAS_BSD_IOB + +# define STACK_GROWS_DOWN + +# define UNDERSCORE_DYNLOAD_SYMBOL_PREFIX + +# define USE_IEEE_FP_PREDS +# define FREEBSD_CONTROL_387 +# define POW_HANDLES_INF_CORRECTLY + +# define UNIX_LIMIT_FDSET_SIZE + +# define SIGSET_IS_SIGNAL + +# define FLAGS_ALREADY_SET + +#endif + + /************** SGI/IRIX with SGI cc ****************/ + +#if (defined(mips) || defined(__mips)) \ + && !(defined(ultrix) || defined(__ultrix)) + +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "mips-irix" + +# include "uconfig.h" + +# define STACK_GROWS_DOWN + +# define DIRENT_NO_NAMLEN + +# define BSTRING_INCLUDE +# define RAND_NOT_RANDOM + +# define POW_HANDLES_INF_CORRECTLY + +# define NO_USLEEP +# define USE_FCNTL_O_NONBLOCK + +# ifdef MZ_X_THREADS +# ifndef MZ_FAKE_THREADS +# define MZ_FAKE_THREADS +# endif +# endif + +# ifndef MZ_FAKE_THREADS +# ifdef IRIX_SPROCS +# define MZ_REAL_THREADS +# define MZ_USE_IRIX_SPROCS + +#ifdef __cplusplus +extern "C" { +#endif +void *scheme_sproc_init_threads(void); +void scheme_sproc_create_thread(void (*f)(void *), void *data, unsigned long *stackend, void **thp); +void scheme_sproc_exit_thread(); +void scheme_sproc_break_thread(void *); +struct Scheme_Process *scheme_sproc_get_current_process(); +void scheme_sproc_set_current_process(struct Scheme_Process *); +void *scheme_sproc_make_mutex(); +void scheme_sproc_free_mutex(void *); +void scheme_sproc_lock_mutex(void *); +void scheme_sproc_unlock_mutex(void *); +void *scheme_sproc_make_semaphore(int init); +void scheme_sproc_free_semaphore(void *); +int scheme_sproc_semaphore_up(void *); +int scheme_sproc_semaphore_down_breakable(void *); +int scheme_sproc_semaphore_try_down(void *); +#ifdef __cplusplus +} +#endif + +#define SCHEME_INIT_THREADS() scheme_sproc_init_threads() +#define SCHEME_CREATE_THREAD(f, data, slimit, thp) scheme_sproc_create_thread(f, data, slimit, thp) +#define SCHEME_EXIT_THREAD() scheme_sproc_exit_thread() +#define SCHEME_BREAK_THREAD(th) scheme_sproc_break_thread(th) +#define SCHEME_GET_CURRENT_PROCESS() scheme_sproc_get_current_process() +#define SCHEME_SET_CURRENT_PROCESS(p) scheme_sproc_set_current_process(p) +#define SCHEME_MAKE_MUTEX() scheme_sproc_make_mutex() +#define SCHEME_FREE_MUTEX(m) scheme_sproc_free_mutex(m) +#define SCHEME_LOCK_MUTEX(m) scheme_sproc_make_mutex(m) +#define SCHEME_UNLOCK_MUTEX(m) scheme_sproc_make_mutex(m) +#define SCHEME_MAKE_SEMA(init) scheme_sproc_make_semaphore(init) +#define SCHEME_FREE_SEMA(s) scheme_sproc_free_semaphore(s) +#define SCHEME_SEMA_UP(s) scheme_sproc_semaphore_up(s) +#define SCHEME_SEMA_DOWN_BREAKABLE(s) scheme_sproc_semaphore_down_breakable(s) +#define SCHEME_SEMA_TRY_DOWN(s) scheme_sproc_semaphore_try_down(s) +# endif /* IRIX_SPROCS */ +# endif /* !MZ_FAKE_THREADS */ + +# define FLAGS_ALREADY_SET + +#endif + + /************** Ultrix with gcc ****************/ + +#if defined(ultrix) || defined(__ultrix) + +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "mips-ultrix" + +# include "uconfig.h" +# undef UNIX_DYNAMIC_LOAD +# undef USE_FCHDIR + +# define DIRENT_NO_NAMLEN + +# define STACK_GROWS_DOWN + +# define RAND_NOT_RANDOM + +# define NO_USLEEP +# define USE_FCNTL_O_NONBLOCK + +# define FLAGS_ALREADY_SET + +#endif + + /************** ALPHA/OSF1 with gcc ****************/ + +# if defined(__alpha) + +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "alpha-osf1" + +# include "uconfig.h" + +# define STACK_GROWS_DOWN + +# define RAND_NOT_RANDOM + +# define SIXTY_FOUR_BIT_INTEGERS + +# define ALPHA_CONTROL_FP + +# define FLAGS_ALREADY_SET + +#endif + + /************** HP/UX with gcc ****************/ + +# if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) + +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "parisc-hpux" + +# include "uconfig.h" + +# undef UNIX_DYNAMIC_LOAD +# define SHL_DYNAMIC_LOAD + +# define STACK_GROWS_UP + +# define USE_SYSCALL_GETRUSAGE + +# define USE_DIVIDE_MAKE_INFINITY +# define USE_IEEE_FP_PREDS +# define USE_EXPLICT_FP_FORM_CHECK + +# define USE_ULIMIT + +# define FLAGS_ALREADY_SET + +#endif + + /********* with Borland C++ or MS Visual C++ ************/ + /* See the "windows" directory for more MSVC details. */ + /* MzScheme is probably no longer Borland-friendly, */ + /* since it currently relies on one MSVC-style inline */ + /* assembly file. Nevertheless, the old flags and */ + /* instructions have been preserved. */ + /* */ + /* Old Borland instructions: */ + /* To compile a standalone MzScheme, first #define */ + /* MZWINCONSOLE. */ + /* To compile for Windows95, first #define MZWIN95. */ + /* Windows95 version also works under Windows NT, but */ + /* not under Win32s. A Win32s version will also work */ + /* under Windows NT. */ + +#if (defined(__BORLANDC__) || defined(_MSC_VER)) \ + && (defined(__WIN32__) || defined(WIN32) || defined(_WIN32)) + +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "win32\\i386" + +# define SYSTEM_TYPE_NAME "windows" +# define DOS_FILE_SYSTEM +# if defined(_MSC_VER) +# define USE_GETDRIVE +# define NO_READDIR +# define USE_FINDFIRST +# else +# define USE_GETDISK +# define DIRENT_NO_NAMLEN +# endif +# define NO_READLINK +# define MKDIR_NO_MODE_FLAG + +# define TIME_SYNTAX +# define USE_FTIME +# define GETENV_FUNCTION +# define DIR_FUNCTION + +# define STACK_GROWS_DOWN + +# define DO_STACK_CHECK + +# if defined(_MSC_VER) +# define WINDOWS_FIND_STACK_BOUNDS +# else +# define USE_STACKAVAIL +# endif + +# if defined(_MSC_VER) +# define USE_MZ_SETJMP +# endif +# define STACK_SAFETY_MARGIN 20000 + +# define WINDOWS_DYNAMIC_LOAD +# define LINK_EXTENSIONS_BY_TABLE + +# define IGNORE_BY_CONTROL_387 +# if defined(_MSC_VER) +# define NAN_EQUALS_ANYTHING +# endif +# define POW_HANDLES_INF_CORRECTLY + +# define IO_INCLUDE +# define RAND_NOT_RANDOM +# define NO_SLEEP +# define DONT_IGNORE_PIPE_SIGNAL + +# define PROCESS_FUNCTION +# define WINDOWS_PROCESSES +# define DETECT_WIN32_CONSOLE_STDIN + +# define SIGSET_IS_SIGNAL +# define SIGSET_NEEDS_REINSTALL + +# define USE_WINSOCK_TCP + +# ifdef WIN32_THREADS +# define MZ_REAL_THREADS +# define MZ_USE_WIN32_THREADS +#ifdef __cplusplus +extern "C" { +#endif +void *scheme_win32_init_threads(void); +void scheme_win32_create_thread(void (*f)(void *), void *data, unsigned long *stackend, void **thp); +void scheme_win32_exit_thread(); +void scheme_win32_break_thread(void *th); +struct Scheme_Process *scheme_win32_get_current_process(); +void scheme_win32_set_current_process(struct Scheme_Process *); +void *scheme_win32_make_mutex(); +void scheme_win32_free_mutex(void *s); +void scheme_win32_lock_mutex(void *); +void scheme_win32_unlock_mutex(void *); +void *scheme_win32_make_semaphore(int init); +void scheme_win32_free_semaphore(void *s); +int scheme_win32_semaphore_up(void *); +int scheme_win32_semaphore_down_breakable(void *); +int scheme_win32_semaphore_try_down(void *); +#ifdef __cplusplus +} +#endif + +#define SCHEME_INIT_THREADS() scheme_win32_init_threads() +#define SCHEME_CREATE_THREAD(f, data, slimit, thp) scheme_win32_create_thread(f, data, slimit, thp) +#define SCHEME_BREAK_THREAD(th) scheme_win32_break_thread(th) +#define SCHEME_EXIT_THREAD() scheme_win32_exit_thread() +#define SCHEME_GET_CURRENT_PROCESS() scheme_win32_get_current_process() +#define SCHEME_SET_CURRENT_PROCESS(p) scheme_win32_set_current_process(p) +#define SCHEME_MAKE_MUTEX() scheme_win32_make_mutex() +#define SCHEME_FREE_MUTEX(m) scheme_win32_free_mutex(m) +#define SCHEME_LOCK_MUTEX(m) scheme_win32_make_mutex(m) +#define SCHEME_UNLOCK_MUTEX(m) scheme_win32_make_mutex(m) +#define SCHEME_MAKE_SEMA(init) scheme_win32_make_semaphore(init) +#define SCHEME_FREE_SEMA(s) scheme_win32_free_semaphore(s) +#define SCHEME_SEMA_UP(s) scheme_win32_semaphore_up(s) +#define SCHEME_SEMA_DOWN_BREAKABLE(s) scheme_win32_semaphore_down_breakable(s) +#define SCHEME_SEMA_TRY_DOWN(s) scheme_win32_semaphore_try_down(s) +# endif + +/* MS Visual C++ likes underscore prefixes */ +#if defined(_MSC_VER) +# define MSC_IZE(x) _ ## x +# define DIRECT_INCLUDE +#endif + +#if defined(__BORLANDC__) +# define DIR_INCLUDE +#endif + +# define FLAGS_ALREADY_SET + +#endif + + /************ Macintosh with CodeWarrior *************/ + +#if defined(__MWERKS__) + +# if defined(__powerc) +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "ppc-mac" +# else +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "68k-mac" +# endif + +# define SYSTEM_TYPE_NAME "macos" +# define MAC_FILE_SYSTEM + +#define NO_READDIR +#define NO_READLINK +#define USE_MAC_FILE_TOOLBOX + +# define MACINTOSH_EVENTS +# define MACINTOSH_GIVE_TIME +# define MACINTOSH_SIOUX + +# if !defined(__powerc) +# define MACINTOSH_SET_STACK +# else +# define CODEFRAGMENT_DYNAMIC_LOAD +# endif + +# ifndef MZSCHEME_IS_CODEFRAGMENT +# define LINK_EXTENSIONS_BY_TABLE +# endif + +# define STACK_GROWS_DOWN + +# define DO_STACK_CHECK +# define MACOS_STACK_LIMIT +# define STACK_SAFETY_MARGIN 10000 + +# define TIME_SYNTAX +# define USE_DIFFTIME +# define DIR_FUNCTION +# define TIME_TYPE_IS_UNSIGNED + +# define RAND_NOT_RANDOM +# define NO_SYS_INCLUDE_SUBDIR +# define NO_USLEEP +# define UNISTD_INCLUDE +# define DONT_IGNORE_PIPE_SIGNAL + +# define POW_HANDLES_INF_CORRECTLY + +# define USE_MAC_TCP + +# define SIGSET_IS_SIGNAL + +# define FLAGS_ALREADY_SET + +#endif + + /************** DOS with Borland C++ ****************/ + /* (Never successfully supported) */ + +#if defined(__BORLANDC__) && defined(__MSDOS__) + +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "dos\\i386" + +# define USE_SENORA_GC +# define DOS_FAR_POINTERS +# define SMALL_HASH_TABLES + +# define SYSTEM_TYPE_NAME "dos" +# define DOS_FILE_SYSTEM +# define USE_GETDISK +# define DIRENT_NO_NAMLEN +# define NO_READLINK +# define MKDIR_NO_MODE_FLAG + +# define TIME_SYNTAX +# define USE_FTIME +# define GETENV_FUNCTION +# define DIR_FUNCTION + +# define STACK_GROWS_DOWN + +# define DO_STACK_CHECK +# define USE_STACKAVAIL +# define STACK_SAFETY_MARGIN 15000 + +# define IGNORE_BY_CONTROL_387 + +# define DIR_INCLUDE +# define IO_INCLUDE +# define RAND_NOT_RANDOM +# define NO_SLEEP +# define DONT_IGNORE_PIPE_SIGNAL + +# define FLAGS_ALREADY_SET + +#endif + +/************** (END KNOWN ARCHITECTURE/SYSTEMS) ****************/ + + +/***** (BEGIN CONFIGURATION FLAG DESCRPTIONS AND DEFAULTS) ******/ + +#ifndef FLAGS_ALREADY_SET + + /*********************/ + /* Operating System */ +/*********************/ + +#define SYSTEM_TYPE_NAME "unix" + + /* SYSTEM_TYPE_NAME must be a string; this will be converted into + a symbol for the result of (system-type) */ + + /* SCHEME_PLATFORM_LIBRARY_SUBPATH must be a string; if it is + undefined, it is automatically generated into a file named + "schsys.h" into the same directory as .o files and #included + by string.c. This string is returned by (system-library-subpath) */ + + /*********************/ + /* Language Features */ +/*********************/ + +#define TIME_SYNTAX +#define PROCESS_FUNCTION +#define DIR_FUNCTION +#define GETENV_FUNCTION + + /* TIME_SYNTAX adds the (time ...) syntax; this may need to be + turned off for compilation on some systems. + CLOCKS_PER_SEC relates the values returned by clock() to + real seconds. (The difference between two clock() calls is + devided by this number.) Usually, this is defined in ; + it defaults to 1000000 */ + + /* USE_FTIME uses ftime instead of gettimeofday; only for TIME_SYNTAX */ + + /* USE_DIFFTIME uses time and difftime; only for TIME_SYNTAX */ + + /* TIME_TYPE_IS_UNSIGNED converts time_t values as unsigned. */ + + /* PROCESS_FUNCTION adds (process ...) and (system ...) functions */ + + /* DIR_FUNCTION adds (current-directory ...) function */ + + /* GETENV_FUNCTION adds (getenv ...) function */ + + /*******************/ + /* Filesystem */ +/*******************/ + +#define UNIX_FILE_SYSTEM +#define EXPAND_FILENAME_TILDE + + /* UNIX_FILE_SYSTEM indicates that filenames are as in Unix, with + forward slash separators, ".." as the parent directory, "/" + as the root directory, and case-sensitivity */ + + /* DOS_FILE_SYSTEM indicates that filenames are as in DOS, with + slash or backward slash separators, ".." as the parent directory, + "X:\", "X:/", "\", or "/" as a root directory (for some letter X), + and case insensitivity */ + + /* MAC_FILE_SYSTEM indicates that filenames are as on the Macintosh, + with colon separators, "" as the parent directory, a volume name + (followed by a colon) as a root directory, and case insensitivity. */ + + /* EXPAND_FILENAME_TILDE expands ~ in a filename with a user's home + directory. */ + + /* NO_STAT_PROC means that there is no stat() function. */ + + /* NO_MKDIR means that there is no mkdir() function. */ + + /* NO_READLINK means that there is no readlink() function. */ + + /* USE_GETDISK uses getdisk() and setdisk() to implement the + filesystem-root-list primitive under DOS. */ + + /* NO_READDIR means that there is no opendir() and readdir() for + implementing directory-list. */ + + /* DIRENT_NO_NAMLEN specifies that dirent entries do not have a + d_namlen field; this is used only when NO_READDIR is not + specified. */ + + /* MKDIR_NO_MODE_FLAG specifies that mkdir() takes only one argument, + instead of a directory name and mode flags. */ + + /***********************/ + /* Ports */ +/***********************/ + +/* These are flags about the implementation of char-ready? for FILE*s + None of these flags are required, but char-ready? may return + spurious #ts if they are set up incorrectly. */ + +#define HAS_STANDARD_IOB +#define FILES_HAVE_FDS +#define USE_UNIX_SOCKETS_TCP + + /* HAS_STANDARD_IOB, HAS_GNU_IOB, HAS_LINUX_IOB, and HAS_BSD_IOB + are mutually exclusive; they describe how to read the FILE* + structure to determine if there are available cached characters. */ + + /* FILES_HAVE_FDS means that a FILE* is always associated with a + file desciptor, which can be select-ed to see if there are + pending bytes. Don't use this unless one of the HAS__IOB + flags is used. */ + + /* USE_UNIX_SOCKETS_TCP means that the tcp- procedures can be implemented + with the standard Unix socket functions. */ + + /* USE_WINSOCK_TCP means that the tcp- procedures can be implemented + with the Winsock toolbox. */ + + /* USE_MAC_TCP means that the tcp- procedures can be implemented + with the Mac TCP toolbox. */ + + /* DETECT_WIN32_CONSOLE_STDIN notices character reads from console + stdin so that char-ready? and blocking reads can be implemented + correctly (so that Scheme thredas are not blocked when no input + is ready). */ + + /* USE_FCNTL_O_NONBLOCK uses O_NONBLOCK instead of FNDELAY for + fcntl on Unix TCP sockets. (Posix systems need this flag). */ + + /* USE_ULIMIT uses ulimit instead of getdtablesize (Unix). */ + + /* USE_DYNAMIC_FDSET_SIZE allocates fd_set records based on the + current fd limit instead of relying on the compile-time size + of fd_set. [This is not known to be actually helpful anywhere + currently, particularly not for FreeBSD.] */ + + /* UNIX_LIMIT_FDSET_SIZE insures that the fd limit at start-up is + no greater than FD_SETSIZE */ + + /***********************/ + /* Processes & Signals */ +/***********************/ + +/* These are flags about the implementation of system, process, etc. */ + +# define UNIX_PROCESSES +# define SIGSET_IS_SIGNAL +# define SIGSET_NEEDS_REINSTALL + + /* UNIX_PROCESSES implements the process functions for Unix; uses + sigset() to install the signal handler. */ + + /* WINDOWS_PROCESSES implements the process functions for Windows. */ + + /* SIGSET_IS_SIGNAL uses signal() in place of sigset() for Unix. This + flag is often paired with SIGSET_NEEDS_REINSTALL for traditional + Unix systems. */ + + /* SIGSET_NEEDS_REINSTALL reinstalls a signal handler when it + is called to handle a signal. The expected semantics of sigset() + (when this flags is not defined) is that a signal handler is NOT + reset to SIG_DFL after a handler is called to handle a signal. */ + + /* DONT_IGNORE_FPE_SIGNAL stops MzScheme from ignoring floating-point + exception signals. */ + + /* DONT_IGNORE_PIPE_SIGNAL stops MzScheme from ignoring SIGPIPE + signals. */ + + /**********************/ + /* Inexact Arithmetic */ +/**********************/ + + /* USE_SINGLE_FLOATS turns on support for single-precision + floating point numbers. Otherwise, floating point numbers + are always represented in double-precision. */ + + /* USE_SINGLE_FLOATS_AS_DEFAULT, when used with + USE_SINGLE_FLOATS, causes exact->inexact coercions to + use single-precision numbers as the result rather + than double-precision numbers. */ + + /* INEXACT_PRINT_DIGITS "" uses as the number of digits to + use for printing floating-points. Defaults to "14". */ + + /* USE_INFINITY uses infinity() to get the infinity floating-point + constant instead of using HUGE_VAL. */ + + /* USE_DIVIDE_MAKE_INFINITY creates +inf.0 by dvividing by zero instead + of using HUGE_VAL. */ + + /* USE_IEEE_FP_PREDS uses isinf() and isnan() to implement tests for + infinity. */ + + /* IGNORE_BY_CONTROL_387 turns off floating-point error for + Intel '387 with _control87. DONT_IGNORE_PIPE_SIGNAL can be on or + off. */ + + /* FREEBSD_CONTROL_387 controls the floating-point processor under i386 + FreeBSD */ + + /* LINUX_CONTROL_387 controls the floating-point processor under i386 + Linux */ + + /* APLHA_CONTROL_FP controls the floating-point processor for Alpha + OSF1 */ + + /* NAN_EQUALS_ANYTHING indicates that the compiler is broken and + equality comparisons with +nan.0 always return #t. Currently + used for MSVC++ */ + + /* USE_EXPLICT_FP_FORM_CHECK circumvents bugs in strtod() under Linux, + SunOS/Solaris, and HP/UX by explicit pre-checking the form of the + number and looking for values that are obviously +inf.0 or -inf.0 */ + + /* POW_HANDLES_INF_CORRECTLY inidicates that thw pow() library procedure + handles +/-inf.0 correctly. Otherwise, code in inserted to specifically + check for infinite arguments. */ + + /***********************/ + /* Stack Maniuplations */ +/***********************/ + +# define DO_STACK_CHECK +# define UNIX_FIND_STACK_BOUNDS +# define STACK_SAFETY_MARGIN 50000 + + /* STACK_GROWS_UP means that deeper stack values have higher + numbered addresses. + STACK_GROWS_DOWN means that deeper stack values have lower + numbered addresses. This is usually the case (Sparc and + Intel platforms, for example, use this). + Use only one or none of these. (It's faster if you know which + one applies, but it can also be figured it out dynamically.) */ + + /* DO_STACK_CHECK checks for stack overflow during execution. + Requires either UNIX_FIND_STACK_BOUNDS, USE_STACKAVAIL, + MACOS_STACK_LIMIT, or ASSUME_FIXED_STACK_SIZE. */ + + /* UNIX_FIND_STACK_BOUNDS figures out the maximum stack position + on Unix systems, using getrlimit() and the GC_find_stack_base() + defined in the conservative garbage collector. + USE_STACKAVIL uses stackavail() function for checking stack + overflow; works with Borland C++, maybe other compilers. + WINDOWS_FIND_STACK_BOUNDS figures out the maximum stack position + under Windows (uses GC_find_stack_base()) + MACOS_STACK_LIMIT figures out the stack limit on the Mac. + ASSUME_FIXED_STACK_SIZE assumes that the main stack size is + always FIXED_STACK_SIZE. + Use only one of these if DO_STACK_CHECK is used, or none otherwise. */ + + /* FIXED_STACK_SIZE sets the stack size to when the + ASSUME_FIXED_STACK_SIZE stack-checking mode is on. */ + + /* STACK_SAFETY_MARGIN sets the number of bytes that should be + available on the stack for "safety" to . Used only if + DO_STACK_CHECK is used. STACK_SAFETY_MARGIN defaults to 50000. */ + + /* ERROR_ON_OVERFLOW causes MzScheme to produce an error if the + stack is overflowed. Normally, it would copy out the current + stack and try to continue the computation. Used only if + DO_STACK_CHECK is used. */ + + /* PROCESS_STACK_SIZE sets the size of the allocated stack when + SPAWN_NEW_STACK is used. Stack-checking and copying works on these + stacks, so that arbitrary computaions can be performed with any + size stack. (Well, it can't be *too* small...) */ + + /* UNIX_LIMIT_STACK limits stack usage to bytes. This may + be necessary to avoid GC-setup traversal over too much memory + (with GC flag HEURISTIC2?). */ + + /***********************/ + /* Dynamic Loading */ +/***********************/ + +#define UNIX_DYNAMIC_LOAD + + /* UNIX_DYNAMIC_LOAD implements dynamic extensions under Unix + using dlopen(); you may have to add the -ldl flag in the LIBS + Makefile variable. The library doesn't exist under Linux without + ELF, so it won't work. If you get linker errors about dlopen(), etc., + this flag and the -ldl linker flag are the things to adjust. + SHL_DYNAMIC_LOAD implement HP/UX dynamic loading. + WINDOWS_DYNAMIC_LOAD implements dynamic extensions under Windows + (Thanks to Patrick Barta). + CODEFRAGMENT_DYNAMIC_LOAD implements dynamic extensions with + MacOS's Code Fragment Manager (thanks to William Ng). + Use only one or none of these. */ + + /* UNDERSCORE_DYNLOAD_SYMBOL_PREFIX with UNIX_DYNAMIC_LOAD menas that + an extra underscore ("_") must be placed in front of the name passed + to dlopen(). */ + + /* LINK_EXTENSIONS_BY_TABLE specifies that the MzScheme functions + used by an extension must be manually linked via a table of + function pointers. Windows dynamic linking uses this method. */ + + /* MZSCHEME_IS_CODEFRAGMENT exploits improved CFM linking when + MzScheme is itself a shared library instead of embedded in + an application */ + + /***********************/ + /* Heap Images */ +/***********************/ + + /* UNIX_IMAGE_DUMPS turns on image save and restore for Unix systems. + This will only work if the final application is statically linked. + (As an exception, the dynamic-linking library itself can be + dynamically linked. This works because loading an extension in + MzScheme automatically turns off image saving.) */ + + /*****************************/ + /* Macintosh Standalone */ +/*****************************/ + + /* MACINTOSH_EVENTS checks for a user break on the Mac. This should always + be defined for MacOS. */ + + /* MACINTOSH_GIVE_TIME lets background processes run when checking for + a user break. */ + + /* MACINTOSH_SIOUX interfaces with Metrowerks's SIOUX library */ + + /* MACINTOSH_SET_STACK sets the stack to be 1/4 of the heap. This should + be used for 68k machines, where the stack is not user-configurable. */ + + /***********************/ + /* Miscellaneous */ +/***********************/ + +#define UNISTD_INCLUDE +#define RAND_NOT_RANDOM + + /* SIXTY_FOUR_BIT_INTEGERS indicates that 'long's are 64-bits wide. */ + + /* RAND_NOT_RANDOM uses the function rand() instead of random() + for random numbers. Some systems don't have random(). */ + + /* NO_USER_BREAK_HANDLER turns off handling of INT signal in main.c */ + + /* DIR_INCLUDE if there's a file (mainly for Windows). */ + + /* DIRECT_INCLUDE if there's a file (mainly for Windows). */ + + /* IO_INCLUDE if there's a file (mainly for Windows). */ + + /* UNISTD_INCLUDE if there's a file (mainly for Unix). */ + + /* SELECT_INCLUDE if there's a file (mainly for Unix) + to be used with FILES_HAVE_FDS. */ + + /* BSTRING_INCLUDE if there's a file (mainly for Unix) + to be used with FILES_HAVE_FDS. */ + + /* NO_SYS_INCLUDE_SUBDIR if include files should all be ; no + includes of the form . Mainly used for + for MacOS. */ + + /* USE_FCHDIR uses fchdir() to improve thread context switches when + a small number of threads are active. */ + + /* USE_GETRUSAGE uses getrusage() to for timing info; otherwise clock() + is used. */ + + /* USE_SYSCALL_GETRUSAGE uses syscall() to implement getrusage() for + timing info. Used with USE_GETRUSAGE. */ + + /* NO_SLEEP means that there is no sleep() function. Used only in + standalone MzScheme. */ + + /* NO_USLEEP means that there is no usleep() function. Used only in + standalone MzScheme. Used only if NO_SLEEP is undefined. */ + + /* WIN32S_HACK uses a special hack to implement threads under Win32s + with some compilers. Obsolete. */ + +#endif /* FLAGS_ALREADY_SET */ + +/****** (END CONFIGURATION FLAG DESCRPTIONS AND DEFAULTS) *******/ + +#endif /* FLAGS_ALREADY_SET */ diff --git a/collects/mzscheme/include/stypes.h b/collects/mzscheme/include/stypes.h new file mode 100644 index 0000000..e90fc47 --- /dev/null +++ b/collects/mzscheme/include/stypes.h @@ -0,0 +1,116 @@ + +enum { + + /* compiled object types: (internal) */ + scheme_variable_type, + scheme_local_type, + scheme_local_unbox_type, + scheme_syntax_type, + scheme_application_type, + scheme_sequence_type, + scheme_branch_type, + scheme_unclosed_procedure_type, + scheme_let_value_type, + scheme_let_void_type, + scheme_letrec_type, /* 10 */ + scheme_let_one_type, + + _scheme_values_types_, /* All following types are values */ + + /* intermediate compiled: */ + scheme_compiled_unclosed_procedure_type, + scheme_compiled_let_value_type, + scheme_compiled_let_void_type, + scheme_compiled_syntax_type, + + scheme_quote_compilation_type, + + _scheme_compiled_values_types_, + + /* procedure types */ + scheme_prim_type, /* 19 */ + scheme_closed_prim_type, /* 20 */ + scheme_linked_closure_type, + scheme_case_closure_type, + scheme_cont_type, + scheme_escaping_cont_type, + + /* basic types */ + scheme_char_type, /* 25 */ + scheme_integer_type, + scheme_bignum_type, + scheme_rational_type, + scheme_float_type, + scheme_double_type, /* 30 */ + scheme_complex_type, + scheme_string_type, + scheme_symbol_type, + scheme_null_type, + scheme_pair_type, + scheme_vector_type, + scheme_closure_type, + scheme_input_port_type, + scheme_output_port_type, + scheme_eof_type, /* 40 */ + scheme_true_type, + scheme_false_type, + scheme_void_type, + scheme_syntax_compiler_type, + scheme_macro_type, + scheme_promise_type, + scheme_box_type, + scheme_process_type, + scheme_object_type, + scheme_class_type, /* 50 */ + scheme_structure_type, + scheme_generic_type, + scheme_type_symbol_type, + scheme_sema_type, + scheme_hash_table_type, + scheme_generic_data_type, + scheme_weak_box_type, + scheme_struct_type_type, + scheme_id_macro_type, + scheme_unit_type, /* 60 */ + scheme_exp_time_type, + scheme_listener_type, + scheme_namespace_type, + scheme_config_type, + scheme_defaulting_config_type, + scheme_will_executor_type, + scheme_interface_type, + scheme_manager_type, + + /* These reserved types will let us add types + without forcing recompilation of compiled MzScheme code */ + scheme_reserved_4_type, + + /* more internal types: */ + scheme_compilation_top_type, /* 70 */ + + scheme_envunbox_type, + scheme_eval_waiting_type, + scheme_tail_call_waiting_type, + scheme_class_data_type, + scheme_undefined_type, + scheme_struct_info_type, + scheme_multiple_values_type, + scheme_reserved_5_type, + scheme_placeholder_type, + scheme_case_lambda_sequence_type, /* 80 */ + scheme_begin0_sequence_type, + + scheme_compiled_unit_type, + scheme_unit_body_data_type, + scheme_unit_body_closure_data_type, + scheme_unit_compound_data_type, + scheme_invoke_unit_data_type, + + scheme_interface_data_type, + + scheme_svector_type, + + _scheme_last_type_ +}; + +extern char *scheme_get_type_name(Scheme_Type type); diff --git a/collects/mzscheme/include/uconfig.h b/collects/mzscheme/include/uconfig.h new file mode 100644 index 0000000..b7bdf41 --- /dev/null +++ b/collects/mzscheme/include/uconfig.h @@ -0,0 +1,31 @@ + +/* Standard settings for Unix platforms. */ +/* Used by sconfig.h for known architectures. */ + +#define SYSTEM_TYPE_NAME "unix" +#define UNIX_FILE_SYSTEM + +#define TIME_SYNTAX +#define PROCESS_FUNCTION +#define DIR_FUNCTION +#define GETENV_FUNCTION + +#define HAS_STANDARD_IOB +#define FILES_HAVE_FDS +#define USE_UNIX_SOCKETS_TCP + +#define UNIX_PROCESSES + +#define EXPAND_FILENAME_TILDE + +#define DO_STACK_CHECK +#define UNIX_FIND_STACK_BOUNDS +#define STACK_SAFETY_MARGIN 50000 + +#define UNIX_DYNAMIC_LOAD + +#define UNISTD_INCLUDE +#define USE_FCHDIR + +#define USE_GETRUSAGE + diff --git a/collects/readline/mzmake b/collects/readline/mzmake new file mode 100755 index 0000000..fb77492 --- /dev/null +++ b/collects/readline/mzmake @@ -0,0 +1,65 @@ +#!/bin/sh -f +string=? ; if [ "$PLTHOME" = "" ] ; then +string=? ; echo Please define PLTHOME +string=? ; exit -1 +string=? ; fi +string=? ; exec ${PLTHOME}/bin/mzscheme -qr $0 "$@" + +(require-library "make.ss" "make") +(require-library "link.ss" "mzscheme" "dynext") +(require-library "compile.ss" "mzscheme" "dynext") +(require-library "file.ss" "mzscheme" "dynext") + +(require-library "functio.ss") + +(define header (build-path (collection-path "mzscheme" "include") "scheme.h")) + +(define dir (build-path "compiled" "native" (system-library-subpath))) +(define mzrl.so (build-path dir "mzrl.so")) +(define mzrl.o (build-path dir "mzrl.o")) + +(define (add-flags fp flags) + (fp (append (fp) flags))) + +(define (files dir regexp) + (let loop ([l (directory-list dir)]) + (cond + [(null? l) null] + [(regexp-match regexp (car l)) (cons (build-path dir (car l)) + (loop (cdr l)))] + [else (cdr l)]))) + +; Compiler flags +(case (string->symbol (system-library-subpath)) + [(sparc-solaris i386-linux) + (add-flags current-extension-compiler-flags + (list "-I/home/mflatt/proj/readline-2.1"))] + [(rs6k-aix) + (add-flags current-extension-compiler-flags + (list "-DNEEDS_SELECT_H"))] + [else (void)]) + +; Linker flags +(case (string->symbol (system-library-subpath)) + [(sparc-solaris) + (add-flags current-extension-linker-flags + (list* "-ltermcap" + (files "/home/mflatt/proj/readline-2.1/solaris/" ".*\\.o")))] + [(i386-linux) + (add-flags current-extension-linker-flags + (files "/home/mflatt/proj/readline-2.1/linux/" ".*\\.o"))] + [else (add-flags current-extension-linker-flags (list "-L/usr/local/lib" "-lreadline"))]) + +(add-flags current-extension-linker-flags (list "-lcurses")) + +(make + ((mzrl.so (mzrl.o dir) + (link-extension #f (list mzrl.o) mzrl.so)) + + (mzrl.o ("mzrl.c" header dir) + (compile-extension #f "mzrl.c" mzrl.o ())) + + (dir () + (make-directory* dir))) + + argv) diff --git a/collects/readline/mzrl.c b/collects/readline/mzrl.c new file mode 100644 index 0000000..00ba79c --- /dev/null +++ b/collects/readline/mzrl.c @@ -0,0 +1,84 @@ + +#include "escheme.h" +#include +#include +#include +#ifdef NEEDS_SELECT_H +# include +#endif +#include + +extern Function *rl_event_hook; + +Scheme_Object *do_readline(int argc, Scheme_Object **argv) +{ + char *s; + Scheme_Object *o; + + if (!SCHEME_STRINGP(argv[0])) + scheme_wrong_type("readline", "string", 0, argc, argv); + + s = readline(SCHEME_STR_VAL(argv[0])); + if (!s) + return scheme_eof; + + o = scheme_make_string(s); + + free(s); + + return o; +} + +Scheme_Object *do_add_history(int argc, Scheme_Object **argv) +{ + char *s; + Scheme_Object *o; + + if (!SCHEME_STRINGP(argv[0])) + scheme_wrong_type("add-history", "string", 0, argc, argv); + + add_history(SCHEME_STR_VAL(argv[0])); + + return scheme_void; +} + +static int check(Scheme_Object *x) +{ + fd_set fd; + struct timeval time = {0, 0}; + + FD_ZERO(&fd); + FD_SET(0, &fd); + return select(1, &fd, NULL, NULL, &time); +} + +static void set_fd_wait(Scheme_Object *x, void *fd) +{ + MZ_FD_SET(0, (fd_set *)fd); +} + +static int block(void) +{ + scheme_block_until(check, set_fd_wait, scheme_void, 0.0); + return 0; +} + +Scheme_Object *scheme_reload(Scheme_Env *env) +{ + Scheme_Object *a[2]; + + a[0] = scheme_make_prim_w_arity(do_readline, "readline", 1, 1); + a[1] = scheme_make_prim_w_arity(do_add_history, "add-history", 1, 1); + + return scheme_values(2, a); +} + +Scheme_Object *scheme_initialize(Scheme_Env *env) +{ + + rl_readline_name = "mzscheme"; + + rl_event_hook = block; + + return scheme_reload(env); +} diff --git a/collects/readline/pread.ss b/collects/readline/pread.ss new file mode 100644 index 0000000..1ca6d11 --- /dev/null +++ b/collects/readline/pread.ss @@ -0,0 +1,61 @@ + +(let*-values ([(.history) "~/.mzrl.history"] + [(MAX-HISTORY) 100] + [(readline add-history) (require-library "readline.ss" "readline")] + [(leftovers) null] + [(local-history) + (with-handlers ([void (lambda (exn) null)]) + (with-input-from-file .history + (lambda () (read))))] + [(do-readline) + (lambda (p) + (let ([s (readline p)]) + (when (string? s) + (add-history s) + (if (= (length local-history) MAX-HISTORY) + (set! local-history (cdr local-history))) + (set! local-history (append local-history (list s)))) + s))] + [(save-history) + (lambda () + (with-handlers ([void void]) + (with-output-to-file .history + (lambda () (write local-history)) + 'truncate)))]) + (exit-handler (let ([old (exit-handler)]) + (lambda (v) + (save-history) + (old v)))) + (for-each add-history local-history) + (let ([prompt-read-using-readline + (lambda (get-prompt) + (if (pair? leftovers) + (begin0 + (car leftovers) + (set! leftovers (cdr leftovers))) + (let big-loop () + (let loop ([s (do-readline (get-prompt 0))][next-pos 1]) + (if (eof-object? s) + (begin + (save-history) + s) + (with-handlers ([exn:read:eof? + (lambda (exn) + (loop (string-append + s + (string #\newline) + (do-readline (get-prompt next-pos))) + (add1 next-pos)))]) + (let* ([p (open-input-string s)] + [rs (let loop () + (let ([r (read p)]) + (if (eof-object? r) + null + (cons r (loop)))))]) + (if (null? rs) + (big-loop) + (begin0 + (car rs) + (set! leftovers (cdr rs)))))))))))]) + prompt-read-using-readline)) + diff --git a/collects/readline/readline.ss b/collects/readline/readline.ss new file mode 100644 index 0000000..f0362ae --- /dev/null +++ b/collects/readline/readline.ss @@ -0,0 +1,2 @@ + +(load-relative-extension (build-path "compiled" "native" (system-library-subpath) "mzrl.so")) diff --git a/collects/readline/rep.ss b/collects/readline/rep.ss new file mode 100644 index 0000000..ec4c60f --- /dev/null +++ b/collects/readline/rep.ss @@ -0,0 +1,5 @@ + +(current-prompt-read + (let ([read (require-library "pread.ss" "readline")]) + (lambda () + (read (lambda (n) (if (zero? n) "> " " ")))))) diff --git a/collects/tests/mred/README b/collects/tests/mred/README new file mode 100644 index 0000000..97a628a --- /dev/null +++ b/collects/tests/mred/README @@ -0,0 +1,101 @@ + +The "item.ss" test (use load/cd) creates a frame to select +among several types of control-testing frames: + + * Big - Tests basic controls; try everything + + * Medium - Tests sliders & gauges; keep a new Big or + Medium frame open while getting a new Medium + frame to use the "Enable Previous Frame" test + + * Menu - contains its own test instructions + + * Button, Checkbox, etc. - Test everything, watching for + messages in the console + +For Big & Medium, verify that hide & disbale work (via the checkboxes +on the right). Hiding or disabling a panel should hde or disable all +its contained controls. Disbaling a frame (a "Previous" frame) should +also disbale all of the contained controls. When "Null label" is +used, there should *not* be extra space left where a label might have +gone. + +--------------------------------------------------------------------------- + +The "draw.ss" test (use load/cd) tests drawing commands. There +is a checkbox for testing drawing into an intermediate offscreen +bitmap as well. The drawing area should have the following +features: + + At the top, "Pen 0 x 0" in a consistent font (i.e., re-painting + should not change the font) + "Pen 1 x 1" in a possibly different font + "Pen 2 x 2" in a bold font (bold version of 1x1 font) + + the drawings under 0x0 and 1x1 should look the same: + TopLeft: h-line should be left-aligned with box below it, + but extend 1 extra pixel. v-line similarly should be + top-aligned and 1 pixel longer. The lines should not + touch the box - there should be 2 pixels of space. + Top: Lines for the rotated L's should join in a sharp corner + Second from Top: like top-left, but lines should touch the box + Four shape lines: First and second should be exactly the same + shape, with the first hollow and the second filled. + Third shape and 2x2 shapes are ill-defined. + Octagons: two hollow octagons exactly the same shape. + Line: actually two lines, but they should form a single + unbroken line + Images: MrEd logo (b & w) + BB logo (color) + Down-left arrow (b & w) + Down-left arrow - B & W, *not* red + Down-left arrow - red with white background + BB logo, possibly reddened + Down-left arrow - red with *white* background + +--------------------------------------------------------------------------- + +The "imred.ss" test is used to check for memory leaks in a loop +invoking the mred system. Call the `go' procedure with a list +of symbol flags: + 'force not included: + Use the current eventspaces; expects mred:run-exit-callbacks + to terminate everything properly + 'force included: + Use a new eventspace; don't run mred:run-exit-callbacks and + call wx:kill-eventspace instead. + 'console included: + Open a MrEd console + 'thread included: + Spawn a sleeping-and-looping thread during each invocation. + Also tests semaphore-callback (because it has to) + 'eventspace included: + Create a new sub-eventspace during each invocation with + a wx:frame% shown + +--------------------------------------------------------------------------- + +The "mem.ss" test should be loaded at startup: + mred -nu -f tests/mem.ss +It will create a lot of frames and instance of other objects, +reporting memory information along the way. At the end, +before the last memory dump, objects that are still allocated +are displayed like this: + (frame (1 . 5)) +This means that the frame allocated by thread #1 at cycle 5 +(counting down from some number) hasn't been garbage-collected. +If there's a few of these lines (less than 10), that's ok. +A large number of lines indicates a GC problem. + +--------------------------------------------------------------------------- + +The "setup.ss" test is a randomized test of the MrEd classes that tests +MrEd's stability. Load/cd setup.ss, and then run + (init) +This attempts to create instances of classes using random +intialization arguments. (init) can be run any number of times. Then +run + (call-all-random) +This calls every method of every class (skipping some "dangerous" ones +that modify the file system) with a random instance and with random +arguments. diff --git a/collects/tests/mred/draw.ss b/collects/tests/mred/draw.ss new file mode 100644 index 0000000..8be648b --- /dev/null +++ b/collects/tests/mred/draw.ss @@ -0,0 +1,346 @@ + +(define sys-path + (lambda (f) + (build-path (collection-path "icons") f))) + +(let* ([f (make-object mred:frame% () + "Graphics Test" + -1 -1 300 350)] + [vp (make-object mred:vertical-panel% f)] + [hp0 (make-object mred:horizontal-panel% vp)] + [hp (make-object mred:horizontal-panel% vp)] + [hp2 (make-object mred:horizontal-panel% vp)] + [bb (make-object wx:bitmap% (sys-path "bb.gif") + wx:const-bitmap-type-gif)] + [return (make-object wx:bitmap% (sys-path "return.xbm") + wx:const-bitmap-type-xbm)] + [tmp-mdc (make-object wx:memory-dc%)] + [use-bitmap? #f] + [depth-one? #f]) + (send hp0 stretchable-in-y #f) + (send hp stretchable-in-y #f) + (send hp2 stretchable-in-y #f) + (let ([canvas + (make-object + (make-class mred:canvas% + (inherit get-dc) + (public + [no-bitmaps? #f] + [set-bitmaps (lambda (on?) (set! no-bitmaps? (not on?)) (on-paint))] + [no-stipples? #f] + [set-stipples (lambda (on?) (set! no-stipples? (not on?)) (on-paint))] + [scale 1] + [set-scale (lambda (s) (set! scale s) (on-paint))] + [offset 0] + [set-offset (lambda (o) (set! offset o) (on-paint))] + [on-paint + (case-lambda + [() (on-paint #f)] + [(ps?) + (let* ([can-dc (get-dc)] + [pen0s (make-object wx:pen% "BLACK" 0 wx:const-solid)] + [pen1s (make-object wx:pen% "BLACK" 1 wx:const-solid)] + [pen2s (make-object wx:pen% "BLACK" 2 wx:const-solid)] + [pen0t (make-object wx:pen% "BLACK" 0 wx:const-transparent)] + [pen1t (make-object wx:pen% "BLACK" 1 wx:const-transparent)] + [pen2t (make-object wx:pen% "BLACK" 2 wx:const-transparent)] + [brushs (make-object wx:brush% "BLACK" wx:const-solid)] + [brusht (make-object wx:brush% "BLACK" wx:const-transparent)] + [penr (make-object wx:pen% "RED" 1 wx:const-solid)] + [brushb (make-object wx:brush% "BLUE" wx:const-solid)] + [mem-dc (if use-bitmap? + (make-object wx:memory-dc%) + #f)] + [bm (if use-bitmap? + (make-object wx:bitmap% (* scale 300) (* scale 300) + (if depth-one? 1 -1)) + #f)] + [draw-series + (lambda (dc pens pent size x y flevel last?) + (let* ([ofont (send dc get-font)]) + (if (positive? flevel) + (send dc set-font + (make-object wx:font% + 10 wx:const-decorative + wx:const-normal + (if (> flevel 1) + wx:const-bold + wx:const-normal) + #t))) + + (send dc set-pen pens) + (send dc set-brush brusht) + + ; Test should overlay this line: + (send dc draw-line + (+ x 3) (+ y 12) + (+ x 40) (+ y 12)) + + (send dc draw-text (string-append size " Pen") + (+ x 5) (+ y 8)) + (send dc set-font ofont) + + (send dc draw-line + (+ x 5) (+ y 27) (+ x 10) (+ 27 y)) + (send dc draw-rectangle + (+ x 5) (+ y 30) 5 5) + (send dc draw-line + (+ x 12) (+ y 30) (+ x 12) (+ y 35)) + + (send dc draw-line + (+ x 5) (+ y 40) (+ x 10) (+ 40 y)) + (send dc draw-rectangle + (+ x 5) (+ y 41) 5 5) + (send dc draw-line + (+ x 10) (+ y 41) (+ x 10) (+ 46 y)) + + (send dc draw-line + (+ x 15) (+ y 25) (+ x 20) (+ 25 y)) + (send dc draw-line + (+ x 20) (+ y 30) (+ x 20) (+ 25 y)) + + (send dc draw-line + (+ x 30) (+ y 25) (+ x 25) (+ 25 y)) + (send dc draw-line + (+ x 25) (+ y 30) (+ x 25) (+ 25 y)) + + (send dc draw-line + (+ x 35) (+ y 30) (+ x 40) (+ 30 y)) + (send dc draw-line + (+ x 40) (+ y 25) (+ x 40) (+ 30 y)) + + (send dc draw-line + (+ x 50) (+ y 30) (+ x 45) (+ 30 y)) + (send dc draw-line + (+ x 45) (+ y 25) (+ x 45) (+ 30 y)) + + ; Check line thickness with "X" + (send dc draw-line + (+ x 20) (+ y 45) (+ x 40) (+ 39 y)) + (send dc draw-line + (+ x 20) (+ y 39) (+ x 40) (+ 45 y)) + + (send dc draw-rectangle + (+ x 5) (+ y 50) 10 10) + (send dc draw-rounded-rectangle + (+ x 5) (+ y 65) 10 10 3) + (send dc draw-ellipse + (+ x 5) (+ y 80) 10 10) + + (send dc set-brush brushs) + (send dc draw-rectangle + (+ x 17) (+ y 50) 10 10) + (send dc draw-rounded-rectangle + (+ x 17) (+ y 65) 10 10 3) + (send dc draw-ellipse + (+ x 17) (+ y 80) 10 10) + + (send dc set-pen pent) + (send dc draw-rectangle + (+ x 29) (+ y 50) 10 10) + (send dc draw-rounded-rectangle + (+ x 29) (+ y 65) 10 10 3) + (send dc draw-ellipse + (+ x 29) (+ y 80) 10 10) + + + (send dc set-pen pens) + (send dc draw-rectangle + (+ x 17) (+ y 95) 10 10) + (send dc set-logical-function wx:const-clear) + (send dc draw-rectangle + (+ x 18) (+ y 96) 8 8) + (send dc set-logical-function wx:const-copy) + + (send dc draw-rectangle + (+ x 29) (+ y 95) 10 10) + (send dc set-logical-function wx:const-clear) + (send dc set-pen pent) + (send dc draw-rectangle + (+ x 30) (+ y 96) 8 8) + + (send dc set-pen pens) + (send dc draw-rectangle + (+ x 5) (+ y 95) 10 10) + (send dc set-logical-function wx:const-xor) + (send dc draw-rectangle + (+ x 5) (+ y 95) 10 10) + (send dc set-logical-function wx:const-copy) + + (send dc draw-line + (+ x 5) (+ y 110) (+ x 8) (+ y 110)) + (send dc draw-line + (+ x 8) (+ y 110) (+ x 11) (+ y 113)) + (send dc draw-line + (+ x 11) (+ y 113) (+ x 11) (+ y 116)) + (send dc draw-line + (+ x 11) (+ y 116) (+ x 8) (+ y 119)) + (send dc draw-line + (+ x 8) (+ y 119) (+ x 5) (+ y 119)) + (send dc draw-line + (+ x 5) (+ y 119) (+ x 2) (+ y 116)) + (send dc draw-line + (+ x 2) (+ y 116) (+ x 2) (+ y 113)) + (send dc draw-line + (+ x 2) (+ y 113) (+ x 5) (+ y 110)) + + (send dc draw-lines + (list + (make-object wx:point% 5 95) + (make-object wx:point% 8 95) + (make-object wx:point% 11 98) + (make-object wx:point% 11 101) + (make-object wx:point% 8 104) + (make-object wx:point% 5 104) + (make-object wx:point% 2 101) + (make-object wx:point% 2 98) + (make-object wx:point% 5 95)) + (+ x 12) (+ y 15)) + + (send dc draw-line + (+ x 5) (+ y 125) (+ x 10) (+ y 125)) + (send dc draw-line + (+ x 11) (+ y 125) (+ x 16) (+ y 125)) + + (send dc set-brush brusht) + (send dc draw-arc + (+ x 20) (+ y 135) + (+ x 5) (+ y 150) + (+ x 20) (+ y 150)) + (send dc draw-arc + (+ x 35) (+ y 150) + (+ x 20) (+ y 135) + (+ x 20) (+ y 150)) + (send dc set-brush brushs) + (send dc draw-arc + (+ x 60) (+ y 135) + (+ x 36) (+ y 150) + (+ x 60) (+ y 150)) + (send dc set-brush brusht) + + (unless (or no-bitmaps? (not last?)) + (let ([x 5] [y 165]) + (send dc draw-icon + (mred:get-icon) x y) + (set! x (+ x (send (mred:get-icon) get-width))) + (let ([do-one + (lambda (bm mode) + (if (send bm ok?) + (begin + (send tmp-mdc select-object bm) + (let ([h (send bm get-height)] + [w (send bm get-width)]) + (send dc blit x y + w h + tmp-mdc 0 0 + mode) + (set! x (+ x w 10))) + (send tmp-mdc select-object null)) + (printf "bad bitmap~n")))]) + (do-one bb wx:const-copy) + (do-one return wx:const-copy) + (send dc set-pen penr) + (do-one return wx:const-copy) + (do-one return wx:const-colour) + (do-one bb wx:const-colour) + (let ([bg (send dc get-background)]) + (send dc set-background brushs) + (do-one return wx:const-colour) + (send dc set-background bg)) + (send dc set-pen pens)))) + + (unless (or no-stipples? (not last?)) + (send dc set-brush brushb) + (send dc draw-rectangle 80 200 100 40) + (when (send return ok?) + (let ([b (make-object wx:brush% "GREEN" wx:const-stipple)]) + (send b set-stipple return) + (send dc set-brush b) + (send dc draw-rectangle 85 205 30 30) + (send dc set-brush brushs) + (send b set-style wx:const-opaque-stipple) + (send dc set-brush b) + (send dc draw-rectangle 120 205 30 30) + (send dc set-brush brushs) + (send b set-stipple bb) + (send dc set-brush b) + (send dc draw-rectangle 155 205 20 30) + (send dc set-brush brushs) + (send b set-stipple null)))) + + (if (not (or ps? (eq? dc can-dc))) + (send can-dc blit 0 0 + (* scale 300) (* scale 300) + mem-dc 0 0 wx:const-copy))) + + 'done)]) + + (send (get-dc) set-user-scale 1 1) + (send (get-dc) set-device-origin 0 0) + + (let ([dc (if ps? + (let ([dc (make-object wx:post-script-dc% null #t)]) + (and (send dc ok?) dc)) + (if (and use-bitmap? (send bm ok?)) + (begin + (send mem-dc select-object bm) + mem-dc) + (get-dc)))]) + (when dc + (when ps? + (send dc start-doc "Draw Test") + (send dc start-page)) + + (send dc set-user-scale scale scale) + (send dc set-device-origin offset offset) + + (send dc clear) + ; check default pen/brush: + (send dc draw-rectangle 0 0 5 5) + (send dc draw-line 0 0 20 6) + + (draw-series dc pen0s pen0t "0 x 0" 5 0 0 #f) + + (draw-series dc pen1s pen1t "1 x 1" 70 0 1 #f) + + (draw-series dc pen2s pen2t "2 x 2" 135 0 2 #t) + + (when ps? + (send dc end-page) + (send dc end-doc)))) + + 'done)])])) + vp 0 50 300 300)]) + (make-object mred:radio-box% hp0 + (lambda (self event) + (set! use-bitmap? (< 0 (send event get-command-int))) + (set! depth-one? (< 1 (send event get-command-int))) + (send canvas on-paint)) + null + -1 -1 -1 -1 + '("Canvas" "Pixmap" "Bitmap") + 0 wx:const-horizontal) + (make-object mred:button% hp + (lambda (self event) + (send canvas on-paint #t)) + "PostScript") + (make-object mred:check-box% hp + (lambda (self event) + (send canvas set-scale (if (send event checked?) 2 1))) + "*2") + (make-object mred:check-box% hp + (lambda (self event) + (send canvas set-offset (if (send event checked?) 10 0))) + "+10") + (send (make-object mred:check-box% hp2 + (lambda (self event) + (send canvas set-bitmaps (send event checked?))) + "Icons") + set-value #t) + (send (make-object mred:check-box% hp2 + (lambda (self event) + (send canvas set-stipples (send event checked?))) + "Stipples") + set-value #t)) + + (send f show #t)) diff --git a/collects/tests/mred/imred.ss b/collects/tests/mred/imred.ss new file mode 100644 index 0000000..3b3c283 --- /dev/null +++ b/collects/tests/mred/imred.ss @@ -0,0 +1,72 @@ + +(define make-invokable-unit + (lambda (application) + (let* ([U + (compound-unit/sig (import) + (link [core : mzlib:core^ (mzlib:core@)] + [trigger : mzlib:trigger^ (mzlib:trigger@)] + [mred : mred^ (mred@ core trigger application)] + [application : mred:application^ (application mred core)]) + (export (open mred) + (open application)))]) + (compound-unit/sig (import) + (link [mred : ((open mred^) (open mred:application^)) (U)]) + (export (unit mred)))))) + +(define (go flags) + (define die? #f) + (define my-app + (unit/sig + mred:application^ + (import mred^ mzlib:core^) + + (define app-name "Tester") + (define console (if (memq 'console flags) + (make-object console-frame%) + #f)) + (define eval-string pretty-print@:pretty-print) + (when (memq 'thread flags) + (let ([s (make-semaphore 1)] + [s2 (make-semaphore 0)] + [done (make-semaphore 0)]) + ; Use of semaphore-callback insures that thread is a child + ; of the eventspace + (semaphore-callback s + (lambda () + (semaphore-post done) + (thread (lambda () + (let loop () + (sleep 1) + (loop)))) + (when (begin0 + die? + (set! die? (not die?))) + (kill-thread (current-thread))))) ; kills handler thread + ; Add another callback that we know will not get triggered + (semaphore-callback s2 void) + (wx:yield done))) + (when (memq 'eventspace flags) + (let ([e (wx:make-eventspace)]) + (parameterize ([wx:current-eventspace e]) + (send (make-object wx:frame% null "Testing" -1 -1 100 100) + show #t)))) + (unless (memq 'force flags) + (run-exit-callbacks)))) + + (let loop () + (collect-garbage) + (collect-garbage) + (dump-memory-stats) + (let ([e (if (memq 'force flags) + (wx:make-eventspace) + (wx:current-eventspace))]) + (parameterize ([wx:current-eventspace e]) + (invoke-unit/sig + (make-invokable-unit my-app))) + (when (memq 'force flags) + (wx:kill-eventspace e))) + (loop))) + + + + \ No newline at end of file diff --git a/collects/tests/mred/item.ss b/collects/tests/mred/item.ss new file mode 100644 index 0000000..b44212d --- /dev/null +++ b/collects/tests/mred/item.ss @@ -0,0 +1,1167 @@ + +(define my-txt #f) + +(define special-font (send wx:the-font-list find-or-create-font + 20 wx:const-decorative + wx:const-bold wx:const-normal + #f)) + +(define (make-h&s cp f) + (make-object mred:button% cp + (lambda (b e) (send f show #f) (send f show #t)) + "Hide and Show")) + +(define (add-hide name w cp) + (let ([c + (make-object mred:check-box% cp + (lambda (c e) (send w show (send c get-value))) + (format "Show ~a" name))]) + (send c set-value #t))) + +(define (add-disable name w ep) + (let ([c + (make-object mred:check-box% ep + (lambda (c e) (send w enable (send c get-value))) + (format "Enable ~a" name))]) + (send c set-value #t))) + +(define (add-disable-radio name w i ep) + (let ([c + (make-object mred:check-box% ep + (lambda (c e) (send w enable i (send c get-value))) + (format "Enable ~a" name))]) + (send c set-value #t))) + +(define (add-change-label name w lp orig other) + (make-object mred:button% lp + (let ([orig-name (if orig orig (send w get-label))] + [changed? #f]) + (lambda (b e) + (if changed? + (unless (null? orig-name) + (send w set-label orig-name)) + (send w set-label other)) + (set! changed? (not changed?)))) + (format "Relabel ~a" name))) + +(define (add-focus-note frame panel) + (define m (make-object mred:message% panel "focus: ??????????????????????????????")) + (send + (make-object + (class-asi wx:timer% + (inherit start) + (public + [notify + (lambda () + (when (send frame is-shown?) + (send m set-label + (format "focus: ~s" (mred:test:get-focused-window))) + (start 1000 #t)))]))) + start 1000 #t)) + +(define OTHER-LABEL "XXXXXXXXXXXXXXXXXXXXXX") + +(define-values (icons-path local-path) + (let ([d (current-load-relative-directory)]) + (values + (lambda (n) + (build-path (collection-path "icons") n)) + (lambda (n) + (build-path d n))))) + +(define popup-test-canvas% + (class mred:canvas% (objects names . args) + (inherit popup-menu draw-text clear) + (public + [last-m null] + [last-choice #f] + [on-paint + (lambda () + (clear) + (draw-text "Left: popup hide state" 0 0) + (draw-text "Right: popup previous" 0 20) + (draw-text (format "Last pick: ~s" last-choice) 0 40))] + [on-event + (lambda (e) + (if (send e button-down?) + (let ([x (send e get-x)] + [y (send e get-y)] + [m (if (or (null? last-m) + (send e button-down? 1)) + (let ([m (make-object mred:menu% + "Title" + (lambda (m e) + (set! last-choice + (send e get-command-int)) + (on-paint)))] + [id 1]) + (for-each + (lambda (obj name) + (send m append + (begin0 id (set! id (add1 id))) + (string-append + name ": " + (if (send obj is-shown?) + "SHOWN" + "")))) + objects names) + m) + last-m)]) + (set! last-m m) + (popup-menu m x y))))]) + (sequence + (apply super-init args)))) + +(define prev-frame #f) + +(define bitmap% + (class wx:bitmap% args + (inherit ok?) + (sequence + (apply super-init args) + (unless (ok?) + (printf "bitmap failure: ~s~n" args))))) + +(define (make-ctls ip cp lp add-testers ep radio-h? label-h? null-label? stretchy?) + + (define return-bmp + (make-object bitmap% (icons-path "return.xbm") + wx:const-bitmap-type-xbm)) + (define bb-bmp + (make-object bitmap% (icons-path "bb.gif") + wx:const-bitmap-type-gif)) + (define mred-bmp + (make-object bitmap% (icons-path "mred.xbm") + wx:const-bitmap-type-xbm)) + (define nruter-bmp + (make-object bitmap% (local-path "nruter.xbm") + wx:const-bitmap-type-xbm)) + + (define :::dummy::: + (when (not label-h?) + (send ip set-label-position wx:const-vertical))) + + (define-values (l il) + (let ([p (make-object mred:horizontal-panel% ip)]) + (send p stretchable-in-x stretchy?) + (send p stretchable-in-y stretchy?) + + (begin + (define l (make-object mred:message% p "Me&ssage")) + (define il (make-object mred:message% p return-bmp)) + + (add-testers "Message" l) + (add-change-label "Message" l lp #f OTHER-LABEL) + + (add-testers "Image Message" il) + (add-change-label "Image Message" il lp return-bmp nruter-bmp) + + (values l il)))) + + (define b (make-object mred:button% ip void "He&llo")) + + (define ib (make-object mred:button% ip void bb-bmp)) + + ; (define ib2 (make-object mred:button% ip void return-bmp)) + + (define lb (make-object mred:list-box% ip void + (if null-label? null "L&ist") + 0 -1 -1 -1 -1 + '("Apple" "Banana" "Coconut & Donuts"))) + + (define cb (make-object mred:check-box% ip void "C&heck")) + + (define icb (make-object mred:check-box% ip void mred-bmp)) + + (define rb (make-object mred:radio-box% ip void + (if null-label? null "R&adio") + -1 -1 -1 -1 + '("First" "Dos" "T&rio") + 0 (if radio-h? + wx:const-horizontal + wx:const-vertical))) + + (define irb (make-object mred:radio-box% ip void + (if null-label? null "Image Ra&dio") + -1 -1 -1 -1 + (list return-bmp nruter-bmp) + 0 (if radio-h? + wx:const-horizontal + wx:const-vertical))) + + (define ch (make-object mred:choice% ip void + (if null-label? null "Ch&oice") + -1 -1 -1 -1 + '("Alpha" "Beta" "Gamma" "Delta & Rest"))) + + (define txt (make-object mred:text% ip void + (if null-label? null "T&ext") + "initial & starting" + -1 -1 -1 -1)) + + (set! my-txt txt) + + (add-testers "Button" b) + (add-change-label "Button" b lp #f OTHER-LABEL) + + (add-testers "Image Button" ib) + (add-change-label "Image Button" ib lp bb-bmp return-bmp) + + (add-testers "List" lb) + (add-change-label "List" lb lp #f OTHER-LABEL) + + (add-testers "Checkbox" cb) + (add-change-label "Checkbox" cb lp #f OTHER-LABEL) + + (add-testers "Image Checkbox" icb) + (add-change-label "Image Checkbox" icb lp mred-bmp bb-bmp) + + (add-testers "Radiobox" rb) + (add-disable-radio "Radio Item `First'" rb 0 ep) + (add-disable-radio "Radio Item `Dos'" rb 1 ep) + (add-disable-radio "Radio Item `Trio'" rb 2 ep) + (add-change-label "Radiobox" rb lp #f OTHER-LABEL) + + (add-testers "Image Radiobox" irb) + (add-disable-radio "Radio Image Item 1" irb 0 ep) + (add-disable-radio "Radio Image Item 2" irb 1 ep) + (add-change-label "Image Radiobox" irb lp #f OTHER-LABEL) + + (add-testers "Choice" ch) + (add-change-label "Choice" ch lp #f OTHER-LABEL) + + (add-testers "Text" txt) + (add-change-label "Text" txt lp #f OTHER-LABEL) + + (make-object popup-test-canvas% + (list l il + b ib + lb + cb icb + rb irb + ch + txt) + (list "label" "image label" + "button" "image button" + "list box" + "checkbox" "image checkbox" + "radio box" "image radiobox" + "choice" + "text") + cp)) + +(define (big-frame h-radio? v-label? null-label? stretchy? special-font?) + (define f (make-object mred:frame% null "Tester")) + + (define hp (make-object mred:horizontal-panel% f)) + + (define ip (make-object mred:vertical-panel% hp)) + (define cp (make-object mred:vertical-panel% hp)) + (define ep (make-object mred:vertical-panel% hp)) + (define lp (make-object mred:vertical-panel% hp)) + + (define (basic-add-testers name w) + (add-hide name w cp) + (add-disable name w ep)) + + (define add-testers + (if stretchy? + (lambda (name control) + (send control stretchable-in-x #t) + (send control stretchable-in-y #t) + (basic-add-testers name control)) + basic-add-testers)) + + (define fp (make-object mred:vertical-panel% ip)) + + (define tp (make-object mred:vertical-panel% fp)) + + (make-h&s cp f) + + (add-testers "Sub-panel" fp) + + (add-testers "Sub-sub-panel" tp) + + (when special-font? + (send tp set-label-font special-font)) + + (make-ctls tp cp lp add-testers ep h-radio? v-label? null-label? stretchy?) + + (add-focus-note f ep) + + (send f show #t) + (set! prev-frame f) + f) + +(define (med-frame radio-h? label-h? null-label? stretchy? special-font?) + (define f2 (make-object mred:frame% null "Tester2")) + + (define hp2 (make-object mred:horizontal-panel% f2)) + + (define ip2 (make-object mred:vertical-panel% hp2)) + (define cp2 (make-object mred:vertical-panel% hp2)) + (define ep2 (make-object mred:vertical-panel% hp2)) + (define lp2 (make-object mred:vertical-panel% hp2)) + + (define (basic-add-testers2 name w) + (add-hide name w cp2) + (add-disable name w ep2)) + + (define add-testers2 + (if stretchy? + (lambda (name control) + (send control stretchable-in-x #t) + (send control stretchable-in-y #t) + (basic-add-testers2 name control)) + basic-add-testers2)) + + (make-h&s cp2 f2) + + (add-disable "Previous Tester Frame" prev-frame ep2) + + (when (not label-h?) + (send ip2 set-label-position wx:const-vertical)) + + (when special-font? + (send ip2 set-label-font special-font)) + + (begin + (define sh (make-object mred:slider% ip2 + (lambda (s e) + (send gh set-value (send sh get-value))) + (if null-label? null "H S&lider") + 5 0 10 -1 -1 -1 + wx:const-horizontal)) + + (define sv (make-object mred:slider% ip2 + (lambda (s e) + (send gv set-value (send sv get-value))) + (if null-label? null "V Sl&ider") + 5 0 10 -1 -1 -1 + wx:const-vertical)) + + (define gh (make-object mred:gauge% ip2 + (if null-label? null "H G&auge") + 10 -1 -1 -1 -1 + wx:const-horizontal)) + + (define gv (make-object mred:gauge% ip2 + (if null-label? null "V Ga&uge") + 10 -1 -1 -1 -1 + wx:const-vertical)) + + (define cmt (make-object mred:canvas-message% ip2 + "Howdy")) + + (define cmi (make-object mred:canvas-message% ip2 + (make-object bitmap% (icons-path "bb.gif") + wx:const-bitmap-type-gif))) + + + (define txt (make-object mred:media-text% ip2 void + (if null-label? null "T&ext") + "initial & starting" + -1 -1 -1 -1)) + + (add-testers2 "Horiz Slider" sh) + (add-testers2 "Vert Slider" sv) + (add-testers2 "Horiz Gauge" gh) + (add-testers2 "Vert Gauge" gv) + (add-testers2 "Text Message" cmt) + (add-testers2 "Image Message" cmi) + (add-testers2 "Text" txt) + + (add-change-label "Horiz Slider" sh lp2 #f OTHER-LABEL) + (add-change-label "Vert Slider" sv lp2 #f OTHER-LABEL) + (add-change-label "Horiz Gauge" gh lp2 #f OTHER-LABEL) + (add-change-label "Vert Gauge" gv lp2 #f OTHER-LABEL) + (add-change-label "Text" txt lp2 #f OTHER-LABEL) + + (add-focus-note f2 ep2) + + (send f2 show #t) + (set! prev-frame f2) + f2)) + +; Need: check, check-test, and enable via menubar +; All operations on Submenus +(define f% + (let-enumerate + ([ADD-APPLE + ADD-BANANA + ADD-COCONUT + DELETE-APPLE + DELETE-BANANA + DELETE-COCONUT-0 + DELETE-COCONUT + DELETE-COCONUT-2 + COCONUT-ID + DELETE-ONCE + APPLE-CHECK-ID]) + (class mred:menu-frame% args + (inherit next-menu-id make-menu) + (rename + [super-make-menu-bar make-menu-bar] + [super-on-menu-command on-menu-command]) + (private + offset + menu-bar + main-menu + apple-menu + banana-menu + coconut-menu + baseball-ids + hockey-ids + enable-item) + (public + [make-menu-bar + (lambda () + (let ([mb (super-make-menu-bar)] + [menu (make-menu)]) + (set! offset (next-menu-id)) + (set! menu-bar mb) + (set! main-menu menu) + + (send menu append (+ offset ADD-APPLE) "Add Apple" "Adds the Apple menu") + (send menu append (+ offset ADD-BANANA) "Add Banana") + (send menu append (+ offset ADD-COCONUT) "Add Coconut") + (send menu append-item "Append Donut" + (lambda () (send apple-menu append-item "Donut" void))) + (send menu append-separator) + (send menu append (+ offset DELETE-COCONUT-0) + "Delete Coconut") + (send menu append-item "Delete Apple" + (lambda () + (send menu-bar delete apple-menu) + (set! apple-installed? #f))) + + (send menu append-separator) + (set! enable-item + (send menu append-item "Apple Once Disabled" + (lambda () + (send apple-menu enable DELETE-ONCE + (not (send menu checked? enable-item)))) + null #t)) + (send menu append-item "Disable Second" + (lambda () (send menu-bar enable-top 1 #f))) + (send menu append-item "Enable Second" + (lambda () (send menu-bar enable-top 1 #t))) + + (send menu append-separator) + (set! baseball-ids + (send menu append-check-set + (list "Astros" "Braves" "Cardinals") + (lambda (which) + (wx:message-box (format "~s Checked" which))))) + (send menu append-separator) + (set! hockey-ids + (send menu append-check-set + `(("Aeros" . Houston) + ("Bruins" . Boston) + ("Capitols" . Washington)) + (lambda (which) + (wx:message-box (format "~s Checked" which))))) + + (set! apple-menu (make-menu)) + (set! banana-menu (make-menu)) + (set! coconut-menu (make-menu)) + + (send apple-menu append (+ offset DELETE-ONCE) + "Delete Once") + (send apple-menu append (+ offset DELETE-APPLE) + "Delete Apple" "Deletes the Apple menu") + (send apple-menu append (+ offset APPLE-CHECK-ID) + "Checkable" null #t) + + (send banana-menu append (+ offset DELETE-BANANA) + "Delete Banana") + (send coconut-menu append (+ offset DELETE-COCONUT) + "Delete Coconut") + (send coconut-menu append (+ offset DELETE-COCONUT-2) + "Delete Coconut By Position") + + (send mb append menu "Tester") + (send mb append apple-menu "Appul") + (send mb enable-top 1 #f) + (send mb set-label-top 1 "Apple") + mb))] + [on-menu-command + (lambda (orig-op) + (let ([op (- orig-op offset)]) + (cond + [(= op ADD-APPLE) + (send menu-bar append apple-menu "Apple") + (set! apple-installed? #t)] + [(= op ADD-BANANA) + (send menu-bar append banana-menu "Banana")] + [(= op ADD-COCONUT) + (send apple-menu append (+ offset COCONUT-ID) + "Coconut" coconut-menu "Submenu")] + [(= op DELETE-ONCE) + (send apple-menu delete (+ offset DELETE-ONCE))] + [(= op DELETE-APPLE) + (send menu-bar delete apple-menu) + (set! apple-installed? #f)] + [(= op DELETE-BANANA) + (send menu-bar delete banana-menu)] + [(or (= op DELETE-COCONUT) (= op DELETE-COCONUT-0)) + (send apple-menu delete (+ offset COCONUT-ID))] + [(= op DELETE-COCONUT-2) + (send apple-menu delete-by-position 3)] + [else + (super-on-menu-command orig-op)])))]) + (sequence (apply super-init args)) + (public + [mfp (make-object mred:vertical-panel% (ivar this panel))] + [mc (make-object mred:wrapping-canvas% mfp -1 -1 200 200)] + [restp (make-object mred:vertical-panel% mfp)] + [mfbp (make-object mred:horizontal-panel% restp)] + [lblp (make-object mred:horizontal-panel% restp)] + [badp (make-object mred:horizontal-panel% restp)] + [e (make-object mred:media-edit%)]) + (sequence + (send restp stretchable-in-y #f) + (send mc set-media e) + (send e load-file (local-path "steps.txt"))) + (public + [make-test-button + (lambda (name pnl menu id) + (make-object mred:button% pnl + (lambda (b e) + (wx:message-box + (if (send (via menu) checked? id) + "yes" + "no") + "Checked?")) + (format "Test ~a" name)))] + [make-bad-test + (lambda (method) + (lambda args + (method 777 #t) + (method 777 #f) + (method -1 #t) + (method -1 #f)))] + [compare + (lambda (expect v kind) + (unless (or (and (string? expect) (string? v) + (string=? expect v)) + (eq? expect v)) + (error 'test-compare "~a mistmatch: ~s != ~s" kind expect v)))] + [label-test + (lambda (menu id expect) + (let ([v (send menu get-label id)]) + (compare expect v "label")))] + [top-label-test + (lambda (pos expect) + (let ([v (send menu-bar get-label-top pos)]) + (compare expect v "top label")))] + [help-string-test + (lambda (menu id expect) + (let ([v (send menu get-help-string id)]) + (compare expect v "help string")))] + [find-test + (lambda (menu title expect string) + (let ([v (if use-menubar? + (send menu-bar find-menu-item title string) + (send menu find-item string))]) + (compare expect v (format "label search: ~a" string))))] + [tell-ok + (lambda () + (printf "ok~n"))] + [temp-labels? #f] + [use-menubar? #f] + [apple-installed? #f] + [via (lambda (menu) (if use-menubar? menu-bar menu))] + [tmp-pick (lambda (a b) (if temp-labels? a b))] + [apple-pick (lambda (x a b) (if (and use-menubar? (not apple-installed?)) + x + (tmp-pick a b)))]) + (sequence +(make-test-button "Aeros" mfbp main-menu (list-ref hockey-ids 0)) + (make-test-button "Bruins" mfbp main-menu (list-ref hockey-ids 1)) + (make-test-button "Capitols" mfbp main-menu (list-ref hockey-ids 2)) + (make-test-button "Apple Item" mfbp apple-menu APPLE-CHECK-ID) + (make-object mred:button% mfbp + (lambda args + (send (via apple-menu) check APPLE-CHECK-ID #t)) + "Check in Apple") + + (make-object mred:button% lblp + (lambda args + (label-test (via main-menu) ADD-APPLE (tmp-pick "Apple Adder" "Add Apple")) + (help-string-test (via main-menu) ADD-APPLE (tmp-pick "ADDER" "Adds the Apple menu")) + (label-test (via main-menu) (car baseball-ids) (tmp-pick "'Stros" "Astros")) + (help-string-test (via main-menu) (car baseball-ids) (tmp-pick "Houston" null)) + (label-test (via main-menu) (cadr hockey-ids) "Bruins") + (label-test (via apple-menu) DELETE-APPLE (apple-pick null "Apple Deleter" "Delete Apple")) + (help-string-test (via apple-menu) DELETE-APPLE (apple-pick null "DELETER" + "Deletes the Apple menu")) + (label-test (via apple-menu) COCONUT-ID (apple-pick null "Coconut!" "Coconut")) + (help-string-test (via apple-menu) COCONUT-ID (apple-pick null "SUBMENU" "Submenu")) + (label-test (via apple-menu) DELETE-COCONUT (apple-pick null "Coconut Deleter" "Delete Coconut")) ; submenu test + (help-string-test (via apple-menu) DELETE-COCONUT (apple-pick null "CDELETER" null)) + (top-label-test 0 (if temp-labels? "Hi" "Tester")) + (top-label-test 1 (if apple-installed? "Apple" null)) + (tell-ok)) + "Test Labels") + (make-object mred:button% lblp + (lambda args + (find-test main-menu (tmp-pick "Hi" "Tester") + ADD-APPLE (tmp-pick "Apple Adder" "Add Apple")) + (find-test apple-menu "Apple" (apple-pick -1 DELETE-APPLE DELETE-APPLE) + (tmp-pick "Apple Deleter" "Delete Apple")) + (find-test apple-menu "Apple" (apple-pick -1 COCONUT-ID COCONUT-ID) + (tmp-pick "Coconut!" "Coconut")) + (find-test apple-menu "Apple" (apple-pick -1 DELETE-COCONUT DELETE-COCONUT) + (tmp-pick "Coconut Deleter" "Delete Coconut")) + (tell-ok)) + "Find Labels") + (make-object mred:button% lblp + (lambda args + (set! temp-labels? (not temp-labels?)) + (let ([menu (via main-menu)]) + (send menu set-label ADD-APPLE (tmp-pick "Apple Adder" "Add Apple")) + (send menu set-label (car baseball-ids) (tmp-pick "'Stros" "Astros")) + (send apple-menu set-label DELETE-APPLE (tmp-pick "Apple Deleter" "Delete Apple")) + (send apple-menu set-label COCONUT-ID (tmp-pick "Coconut!" "Coconut")) + (send apple-menu set-label DELETE-COCONUT (tmp-pick "Coconut Deleter" "Delete Coconut")) + (send menu set-help-string ADD-APPLE (tmp-pick "ADDER" "Adds the Apple menu")) + (send menu set-help-string (car baseball-ids) (tmp-pick "Houston" null)) + (send apple-menu set-help-string DELETE-APPLE (tmp-pick "DELETER" "Deletes the Apple menu")) + (send apple-menu set-help-string COCONUT-ID (tmp-pick "SUBMENU" "Submenu")) + (send apple-menu set-help-string DELETE-COCONUT (tmp-pick "CDELETER" null)) + (send menu-bar set-label-top 0 (if temp-labels? "Hi" "Tester")))) + "Toggle Labels") + (letrec ([by-bar (make-object mred:check-box% lblp + (lambda args + (set! use-menubar? (send by-bar get-value))) + "Via Menubar")]) + by-bar) + + (make-test-button "Bad Item" badp apple-menu 777) + (make-test-button "Other Bad Item" badp apple-menu -1) + (make-object mred:button% badp + (lambda args + (label-test main-menu 777 null) + (label-test main-menu -1 null) + (help-string-test main-menu 777 null) + (help-string-test main-menu -1 null) + (top-label-test -1 null) + (top-label-test 777 null) + (find-test main-menu "No way" -1 "Not in the menus") + (tell-ok)) + "Bad Item Labels") + (make-object mred:button% badp + (make-bad-test (ivar main-menu check)) + "Check Bad") + (make-object mred:button% badp + (make-bad-test (ivar main-menu enable)) + "Enable Bad") + (make-object mred:button% badp + (make-bad-test (lambda (a b) (send main-menu delete a))) + "Delete Bad") + + #f)))) + +(define (menu-frame) + (define mf (make-object f% null "Menu Test")) + (set! prev-frame mf) + (send mf show #t) + mf) + +(define (check-callback-event orig got e types silent?) + (unless (eq? orig got) + (error "object not the same")) + (unless (is-a? e wx:command-event%) + (error "bad event object")) + (unless (eq? got (send e get-event-object)) + (error "event object mismatch")) + (let ([type (send e get-event-type)]) + (unless (member type types) + (error (format "bad event type: ~a" type)))) + (unless silent? + (printf "Callback Ok~n"))) + +(define (button-frame) + (define f (make-object mred:frame% null "Button Test")) + (define p (make-object mred:vertical-panel% f)) + (define old-list null) + (define commands (list wx:const-event-type-button-command)) + (define sema (make-semaphore)) + (define b (make-object mred:button% p + (lambda (bx e) + (semaphore-post sema) + (set! old-list (cons e old-list)) + (check-callback-event b bx e commands #f)) + "Hit Me")) + (define c (make-object mred:button% p + (lambda (c e) + (for-each + (lambda (e) + (check-callback-event b b e commands #t)) + old-list) + (printf "All Ok~n")) + "Check")) + (define e (make-object mred:button% p + (lambda (c e) + (sleep 1) + (wx:yield) ; try to catch a click, but not a callback + (set! sema (make-semaphore)) + (send b enable #f) + (thread (lambda () (wx:yield sema))) + (when (semaphore-wait-multiple (list sema) 0.5) + (printf "un-oh~n")) + (send b enable #t) + (semaphore-post sema)) + "Disable Test")) + (send f show #t)) + +(define (checkbox-frame) + (define f (make-object mred:frame% null "Checkbox Test")) + (define p (make-object mred:vertical-panel% f)) + (define old-list null) + (define commands (list wx:const-event-type-checkbox-command)) + (define cb (make-object mred:check-box% p + (lambda (cx e) + (set! old-list (cons e old-list)) + (unless (eq? (send cb get-value) + (send e checked?)) + (error "event checkstate mismatch")) + (check-callback-event cb cx e commands #f)) + "On")) + (define t (make-object mred:button% p + (lambda (t e) + (let ([on? (send cb get-value)]) + (send cb set-value (not on?)))) + "Toggle")) + (define c (make-object mred:button% p + (lambda (c e) + (for-each + (lambda (e) + (check-callback-event cb cb e commands #t)) + old-list) + (printf "All Ok~n")) + "Check")) + (send f show #t)) + +(define (choice-or-list-frame list? list-style empty?) + (define f (make-object mred:frame% null "Choice Test")) + (define p (make-object mred:vertical-panel% f)) + (define-values (actual-content actual-user-data) + (if empty? + (values null null) + (values '("Alpha" "Beta" "Gamma") + (list null null null)))) + (define commands + (if list? + (list wx:const-event-type-listbox-command) + (list wx:const-event-type-choice-command))) + (define old-list null) + (define callback + (lambda (cx e) + (when (zero? (send c number)) + (error "Callback for empty choice/list")) + (set! old-list (cons (list e + (send e get-command-int) + (send e get-command-string)) + old-list)) + (unless (= (send e get-command-int) + (send c get-selection)) + (error "event selection value mismatch")) + (unless (string=? (send e get-command-string) + (send c get-string-selection) + (send c get-string (send c get-selection))) + (error "selection string mistmatch")) + (check-callback-event c cx e commands #f))) + (define c (if list? + (make-object mred:list-box% p + callback + "Tester" + list-style + -1 -1 -1 -1 + actual-content) + (make-object mred:choice% p + callback + "Tester" + -1 -1 -1 -1 + actual-content))) + (define counter 0) + (define append-with-user-data? #f) + (define ab (make-object mred:button% p + (lambda (b e) + (set! counter (add1 counter)) + (let ([naya (format "Extra ~a" counter)] + [naya-data (box 0)]) + (set! actual-content (append actual-content (list naya))) + (set! actual-user-data (append actual-user-data (list naya-data))) + (if (and list? append-with-user-data?) + (send c append naya naya-data) + (begin + (send c append naya) + (when list? + (send c set-client-data + (sub1 (send c number)) + naya-data)))) + (set! append-with-user-data? + (not append-with-user-data?)))) + "Append")) + (define cdp (make-object mred:horizontal-panel% p)) + (define rb (make-object mred:button% cdp + (lambda (b e) + (set! actual-content null) + (set! actual-user-data null) + (send c clear)) + "Clear")) + (define db (if list? + (make-object mred:button% cdp + (lambda (b e) + (let ([p (send c get-selection)]) + (when (<= 0 p (sub1 (length actual-content))) + (send c delete p) + (if (zero? p) + (begin + (set! actual-content (cdr actual-content)) + (set! actual-user-data (cdr actual-user-data))) + (begin + (set-cdr! (list-tail actual-content (sub1 p)) + (list-tail actual-content (add1 p))) + (set-cdr! (list-tail actual-user-data (sub1 p)) + (list-tail actual-user-data (add1 p)))))))) + "Delete") + null)) + (define (make-selectors method numerical?) + (define p2 (make-object mred:horizontal-panel% p)) + (when numerical? + (make-object mred:button% p2 + (lambda (b e) + (method -1)) + "Select Bad -1")) + (make-object mred:button% p2 + (lambda (b e) + (method 0)) + "Select First") + (make-object mred:button% p2 + (lambda (b e) + (method (floor (/ (send c number) 2)))) + "Select Middle") + (make-object mred:button% p2 + (lambda (b e) + (method (sub1 (send c number)))) + "Select Last") + (make-object mred:button% p2 + (lambda (b e) + (method (if numerical? + (send c number) + #f))) + "Select Bad X") + #f) + (define dummy-1 (make-selectors (ivar c set-selection) #t)) + (define dummy-2 (make-selectors (lambda (p) + (if p + (when (positive? (length actual-content)) + (send c set-string-selection + (list-ref actual-content p))) + (send c set-string-selection "nada"))) + #f)) + (define tb (make-object mred:button% p + (lambda (b e) + (let ([c (send c number)]) + (unless (= c (length actual-content)) + (error "bad number response"))) + (let loop ([n 0][l actual-content][lud actual-user-data]) + (unless (null? l) + (let ([s (car l)] + [sud (car lud)] + [sv (send c get-string n)] + [sudv (if list? + (send c get-client-data n) + #f)]) + (unless (string=? s sv) + (error "get-string mismatch")) + (unless (or (not list?) (eq? sud sudv)) + (error "get-user-data mismatch")) + (unless (= n (send c find-string s)) + (error "bad find-string result"))) + (loop (add1 n) (cdr l) (cdr lud)))) + (unless (and (null? (send c get-string -1)) + (null? (send c get-string (send c number)))) + (error "out-of-bounds did not return null")) + (unless (= -1 (send c find-string "nada")) + (error "bad find-string result for nada")) + (for-each + (lambda (eis) + (let ([e (car eis)] + [i (cadr eis)] + [s (caddr eis)]) + (unless (= (send e get-command-int) i) + (error "event selection value mismatch")) + (unless (string=? (send e get-command-string) s) + (error "selection string mistmatch")) + (check-callback-event c c e commands #t))) + old-list) + (printf "content: ~s~n" actual-content)) + "Check")) + (send f show #t)) + +(define (gauge-frame) + (define f (make-object mred:frame% null "Gauge Test")) + (define p (make-object mred:vertical-panel% f)) + (define g (make-object mred:gauge% p "Tester" 10)) + (define (move d name) + (make-object mred:button% p + (lambda (c e) + (send g set-value (+ d (send g get-value)))) + name)) + (define (size d name) + (make-object mred:button% p + (lambda (c e) + (send g set-range (+ d (send g get-range)))) + name)) + (move 1 "+") + (move -1 "-") + (size 1 "Bigger") + (size -1 "Smaller") + (send f show #t)) + +(define (text-frame mred:text% style) + (define (handler get-this) + (lambda (c e) + (unless (eq? c (get-this)) + (printf "callback: bad item: ~a~n" c)) + (unless (eq? c (send e get-event-object)) + (printf "callback: bad item in event: ~a~n" (send e get-event-object))) + (let ([t (send e get-event-type)]) + (cond + [(= t wx:const-event-type-text-command) + (printf "Changed: ~a~n" (send e get-command-string))] + [(= t wx:const-event-type-text-enter-command) + (printf "Return: ~a~n" (send e get-command-string))] + [(= t wx:const-event-type-set-focus) + (printf "Focus in~n")] + [(= t wx:const-event-type-kill-focus) + (printf "Focus out~n")])))) + + (define f (make-object mred:frame% null "Text Test")) + (define p (make-object (class-asi mred:vertical-panel% + (public + [on-default-action + (lambda (v) + (printf "Panel default action~n"))])) + f)) + (define t1 (make-object mred:text% p (handler (lambda () t1)) null "This should just fit!" + -1 -1 -1 -1 style)) + (define t2 (make-object mred:text% p (handler (lambda () t2)) "Another" "This too!" + -1 -1 -1 -1 style)) + (define junk (send p set-label-position wx:const-vertical)) + (define t3 (make-object mred:text% p (handler (lambda () t3)) "Catch Returns" "And, yes, this!" + -1 -1 -1 -1 (+ style wx:const-process-enter))) + (send t1 stretchable-in-x #f) + (send t2 stretchable-in-x #f) + (send t3 stretchable-in-x #f) + (send f show #t)) + +(define (canvas-frame flags) + (define f (make-object mred:frame% null "Canvas Test")) + (define p (make-object mred:vertical-panel% f)) + (define c% (class mred:canvas% (name p) + (inherit clear draw-text draw-line set-clipping-region + get-scroll-pos get-scroll-range get-scroll-page + get-client-size get-virtual-size) + (public + [on-paint + (lambda () + (let ([s (format "V: p: ~s r: ~s g: ~s H: ~s ~s ~s" + (get-scroll-pos wx:const-vertical) + (get-scroll-range wx:const-vertical) + (get-scroll-page wx:const-vertical) + (get-scroll-pos wx:const-horizontal) + (get-scroll-range wx:const-horizontal) + (get-scroll-page wx:const-horizontal))] + [w (box 0)][w2 (box 0)] + [h (box 0)][h2 (box 0)]) + (get-client-size w h) + (get-virtual-size w2 h2) + ; (set-clipping-region 0 0 (unbox w2) (unbox h2)) + (clear) + (draw-text name 3 3) + ; (draw-line 3 12 40 12) + (draw-text s 3 15) + (draw-text (format "client: ~s x ~s virtual: ~s x ~s" + (unbox w) (unbox h) + (unbox w2) (unbox h2)) + 3 27)))] + [on-scroll + (lambda (e) (on-paint))]) + (sequence + (super-init p -1 -1 -1 -1 flags)))) + (define c1 (make-object c% "Unmanaged scroll" p)) + (define c2 (make-object c% "Automanaged scroll" p)) + (define (reset-scrolls) + (let* ([h? (send ck-h get-value)] + [v? (send ck-v get-value)] + [small? (send ck-s get-value)] + [swap? (send ck-w get-value)]) + (send c1 set-scrollbars (if h? 1 -1) (if v? 1 -1) 10 10 3 3 0 0 swap?) + (send c2 set-scrollbars (if h? 25 -1) (if v? 10 -1) (if small? 2 20) (if small? 2 20) + 3 3 0 0 (not swap?)))) + (define p2 (make-object mred:horizontal-panel% p)) + (define jumk (send p2 stretchable-in-y #f)) + (define ck-v (make-object mred:check-box% p2 (lambda (b e) (reset-scrolls)) "Vertical Scroll")) + (define ck-h (make-object mred:check-box% p2 (lambda (b e) (reset-scrolls)) "Horizontal Scroll")) + (define ck-s (make-object mred:check-box% p2 (lambda (b e) (reset-scrolls)) "Small")) + (define ck-w (make-object mred:check-box% p2 (lambda (b e) (reset-scrolls)) "Swap")) + (send f show #t)) + +;---------------------------------------------------------------------- + +(define selector (make-object mred:frame% null "Test Selector")) +(define ap (make-object mred:vertical-panel% selector)) + +; Test timers while we're at it: +(let ([clockp (make-object mred:horizontal-panel% ap)] + [selector selector]) + (make-object mred:vertical-panel% clockp) ; filler + (let ([time (make-object mred:message% clockp "XX:XX:XX")]) + (make-object + (class wx:timer% () + (inherit start) + (public + [notify + (lambda () + (let* ([now (seconds->date (current-seconds))] + [pad (lambda (pc d) + (let ([s (number->string d)]) + (if (= 1 (string-length s)) + (string-append pc s) + s)))] + [s (format "~a:~a:~a" + (pad " " (let ([h (modulo (date-hour now) 12)]) + (if (zero? h) + 12 + h))) + (pad "0" (date-minute now)) + (pad "0" (date-second now)))]) + (send time set-label s) + (when (send selector is-shown?) + (start 1000 #t))))]) + (sequence + (super-init) + (start 1000 #t)))))) + +(define bp (make-object mred:vertical-panel% ap -1 -1 -1 -1 wx:const-border)) +(define bp1 (make-object mred:horizontal-panel% bp)) +(define bp2 (make-object mred:horizontal-panel% bp)) +(define mp (make-object mred:vertical-panel% ap -1 -1 -1 -1 wx:const-border)) +(define mp1 (make-object mred:horizontal-panel% mp)) +(define mp2 (make-object mred:horizontal-panel% mp)) + +(send bp1 set-label-position wx:const-vertical) +(send mp1 set-label-position wx:const-vertical) + +(make-object mred:button% ap (lambda (b e) (menu-frame)) "Make Menus Frame") +(make-object mred:button% ap (lambda (b e) (button-frame)) "Make Button Frame") +(make-object mred:button% ap (lambda (b e) (checkbox-frame)) "Make Checkbox Frame") +(define cp (make-object mred:horizontal-panel% ap)) +(send cp stretchable-in-x #f) +(make-object mred:button% cp (lambda (b e) (choice-or-list-frame #f 0 #f)) "Make Choice Frame") +(make-object mred:button% cp (lambda (b e) (choice-or-list-frame #f 0 #t)) "Make Empty Choice Frame") +(define lp (make-object mred:horizontal-panel% ap)) +(send lp stretchable-in-x #f) +(make-object mred:button% lp (lambda (b e) (choice-or-list-frame #t wx:const-single #f)) "Make List Frame") +(make-object mred:button% lp (lambda (b e) (choice-or-list-frame #t wx:const-single #t)) "Make Empty List Frame") +(make-object mred:button% lp (lambda (b e) (choice-or-list-frame #t wx:const-multiple #f)) "Make Multilist Frame") +(make-object mred:button% ap (lambda (b e) (gauge-frame)) "Make Gauge Frame") +(define tp (make-object mred:horizontal-panel% ap)) +(send tp stretchable-in-x #f) +(make-object mred:button% tp (lambda (b e) (text-frame mred:text% 0)) "Make Text Frame") +(make-object mred:button% tp (lambda (b e) (text-frame mred:media-text% 0)) "Make Media Text Frame") +(make-object mred:button% tp (lambda (b e) (text-frame mred:multi-text% 0)) "Make Multitext Frame") +(make-object mred:button% tp (lambda (b e) (text-frame mred:media-multi-text% 0)) "Make Media Multitext Frame") +(define tp2 (make-object mred:horizontal-panel% ap)) +(send tp2 stretchable-in-x #f) +(make-object mred:button% tp2 (lambda (b e) (text-frame mred:multi-text% wx:const-hscroll)) "Make Multitext Frame/HScroll") +(make-object mred:button% tp2 (lambda (b e) (text-frame mred:media-multi-text% wx:const-hscroll)) "Make Media Multitext Frame/HScroll") + +(define cnp (make-object mred:horizontal-panel% ap)) +(send cnp stretchable-in-x #f) +(let ([mkf (lambda (flags name) + (make-object mred:button% cnp + (lambda (b e) (canvas-frame flags)) + (format "Make ~aCanvas Frame" name)))]) + (mkf (+ wx:const-hscroll wx:const-vscroll) "HV") + (mkf wx:const-hscroll "H") + (mkf wx:const-vscroll "V") + (mkf 0 "")) + +(define (choose-next radios) + (let loop ([l radios]) + (let* ([c (car l)] + [rest (cdr l)] + [n (send c number)] + [v (send c get-selection)]) + (if (< v (sub1 n)) + (send c set-selection (add1 v)) + (if (null? rest) + (map (lambda (c) (send c set-selection 0)) radios) + (begin + (send c set-selection 0) + (loop rest))))))) + +(define make-next-button + (lambda (p l) + (make-object mred:button% p + (lambda (b e) (choose-next l)) + "Next Configuration"))) + +(define make-selector-and-runner + (lambda (p1 p2 radios? size maker) + (define radio-h-radio + (if radios? + (make-object mred:radio-box% p1 void "Radio Box Orientation" + -1 -1 -1 -1 + '("Vertical" "Horizontal")) + #f)) + (define label-h-radio + (make-object mred:radio-box% p1 void "Label Orientation" + -1 -1 -1 -1 + '("Vertical" "Horizontal"))) + (define label-null-radio + (make-object mred:radio-box% p1 void "Optional Labels" + -1 -1 -1 -1 + '("Use Label" "No Label"))) + (define stretchy-radio + (make-object mred:radio-box% p1 void "Stretchiness" + -1 -1 -1 -1 + '("Normal" "All Stretchy"))) + (define font-radio + (make-object mred:radio-box% p1 void "Font" + -1 -1 -1 -1 + '("Normal" "Big"))) + (define next-button + (let ([basic-set (list label-h-radio label-null-radio stretchy-radio font-radio)]) + (make-next-button p2 + (if radios? + (cons radio-h-radio basic-set) + basic-set)))) + (define go-button + (make-object mred:button% p2 + (lambda (b e) + (maker + (if radios? + (positive? (send radio-h-radio get-selection)) + #f) + (positive? (send label-h-radio get-selection)) + (positive? (send label-null-radio get-selection)) + (positive? (send stretchy-radio get-selection)) + (positive? (send font-radio get-selection)))) + (format "Make ~a Frame" size))) + #t)) + +(make-selector-and-runner bp1 bp2 #t "Big" big-frame) +(make-selector-and-runner mp1 mp2 #f "Medium" med-frame) + +(send selector show #t) + +; (define e (make-object wx:key-event% wx:const-event-type-char)) +; (send e set-key-code 65) +; (send e set-shift-down #t) diff --git a/collects/tests/mred/mem.ss b/collects/tests/mred/mem.ss new file mode 100644 index 0000000..7ebc1a1 --- /dev/null +++ b/collects/tests/mred/mem.ss @@ -0,0 +1,241 @@ + +(define source-dir (current-load-relative-directory)) + +(define num-times 12) +(define num-threads 1) + +(define dump-stats? #t) + +(define edit? #t) +(define insert? #t) +(define load-file? #f) ; adds a lot of messy objects + +(define menus? #t) +(define atomic? #t) +(define offscreen? #t) +(define frame? #t) + +(define subwindows? #t) + +(define allocated '()) +(define (remember tag v) + (set! allocated + (cons (cons tag (make-weak-box v)) + allocated)) + v) + +(define frame% + ; Leave this as the (obsolete) make-class form for macro testing + (make-class mred:editor-frame% + (rename [super-show show]) + (public + [prim-show (lambda (arg) (super-show arg))] + [show + (lambda (x) (void))]))) + +(when subwindows? + (define sub-collect-frame + (make-object wx:frame% null "sub-collect" -1 -1 200 200)) + (define sub-collect-panel + (make-object wx:panel% sub-collect-frame 0 0 100 100))) + +(send sub-collect-frame show #t) + +(define (maker id n) + (sleep) + (collect-garbage) + (collect-garbage) + (printf "Thread: ~s Cycle: ~s~n" id n) + (dump-object-stats) + (if (and dump-stats? (= id 1)) + (dump-memory-stats)) + (unless (zero? n) + (let ([tag (cons id n)]) + (let* ([f (if edit? (remember tag (make-object frame%)))] + [c (make-custodian)] + [es (parameterize ([current-custodian c]) + (wx:make-eventspace))]) + + (parameterize ([wx:current-eventspace es]) + (send (remember + tag + (make-object + (class-asi wx:timer% + (public + [notify void])))) + start 100)) + + (when edit? + (remember tag (send f get-edit))) + + (when (and edit? (zero? (modulo n 2))) + (send f prim-show #t) + (sleep 0.5)) + + (if frame? + (let* ([f (make-object wx:frame% '() "Tester" -1 -1 200 200)] + [p (remember tag (make-object wx:panel% f))]) + (remember tag (make-object wx:canvas% f)) + (if (zero? (modulo n 3)) + (send f show #t)) + (remember tag (make-object wx:button% p (lambda args #t) "one")) + (let ([class wx:check-box%]) + (let loop ([m 10]) + (unless (zero? m) + (remember (cons tag m) + (make-object class p (lambda args #t) "another")) + (loop (sub1 m))))) + (send p new-line) + (remember tag (make-object wx:check-box% p (lambda args #t) "check")) + (remember tag (make-object wx:choice% p (lambda args #t) "choice")) + (remember tag (make-object wx:list-box% p (lambda args #t) "list" + wx:const-single -1 -1 -1 -1 + '("apple" "banana" "coconut"))) + (remember tag (make-object wx:button% p (lambda args #t) "two")) + (send f show #f))) + + (if subwindows? + (let ([p (make-object wx:panel% sub-collect-frame 100 100 50 50)] + [cv (make-object wx:canvas% sub-collect-frame 150 150 50 50)] + [add-objects + (lambda (p tag hide?) + (let ([b (make-object wx:button% p (lambda args #t) "one" 0 0)] + [c (make-object wx:check-box% p (lambda args #t) "check" 0 0)] + [co (make-object wx:choice% p (lambda args #t) "choice" 0 0)] + [cv (make-object wx:canvas% p 0 0 50 50)] + [lb (make-object wx:list-box% p (lambda args #t) "list" + wx:const-single 0 0 -1 -1 + '("apple" "banana" "coconut"))]) + (when hide? + (send b show #f) + (send c show #f) + (send cv show #f) + (send co show #f) + (send lb show #f)) + (remember tag b) + (remember tag c) + (remember tag cv) + (remember tag co) + (remember tag lb)))]) + (add-objects sub-collect-panel (cons 'sc1 tag) #t) + (add-objects p (cons 'sc2 tag) #f) + (remember (cons 'sc0 tag) p) + (remember (cons 'sc0 tag) cv) + (send p show #f) + (send cv show #f))) + + + (if (and edit? insert?) + (let ([e (send f get-edit)]) + (when load-file? + (send e load-file (build-path source-dir "mem.ss"))) + (let loop ([i 20]) + (send e insert (number->string i)) + (unless (zero? i) + (loop (sub1 i)))) + (let ([s (make-object wx:media-snip%)]) + (send (send s get-this-media) insert "Hello!") + (send e insert s)) + (send e insert #\newline) + (send e insert "done") + (send e set-modified #f))) + + (when menus? + (remember tag (make-object wx:menu-bar%)) + (remember tag (make-object wx:menu%)) + (let ([mb (remember tag (make-object wx:menu-bar%))] + [m (remember tag (make-object wx:menu%))]) + (send m append 5 "Hi" (remember tag (make-object wx:menu%))) + (send mb append m "x")) + + (if edit? + (let ([m (remember tag (make-object mred:menu%))] + [m2 (remember tag (make-object mred:menu%))] + [mb (send f get-menu-bar)]) + (send m append 4 "ok") + (send m2 append 4 "hao") + (send m append 5 "Hi" (remember tag (make-object mred:menu%))) + (send mb append m "Extra") + (send mb append m2 "Other") + (send m delete 5) + (send mb delete m)))) + + (when atomic? + (let loop ([m 8]) + (unless (zero? m) + (remember (cons tag m) (make-object wx:point% n m)) + (remember (cons tag m) (make-object wx:int-point% n m)) + (remember (cons tag m) (make-object wx:brush%)) + (remember (cons tag m) (make-object wx:pen%)) + (loop (sub1 m))))) + + (when offscreen? + (let ([m (remember tag (make-object wx:memory-dc%))] + [b (remember (cons tag 'u) (make-object wx:bitmap% 100 100))] + [b2 (remember (cons tag 'x) (make-object wx:bitmap% 100 100))]) + (send m select-object b))) + + + (when edit? + (let ([name (wx:get-temp-file-name "hi")]) + (send (send f get-edit) save-file name) + (send f on-close) + (send f prim-show #f) + (delete-file name))) + + (custodian-shutdown-all c) + + (collect-garbage) + + (maker id (sub1 n)))))) + +(define (still) + (map (lambda (x) + (let ([v (weak-box-value (cdr x))]) + (if v + (printf "~s ~s~n" (send v get-class-name) (car x))))) + allocated) + (void)) + +(define (xthread f) + (f)) + +(define (stw t n) + (thread-weight t (floor (/ (thread-weight t) n)))) + +(define (do-test) + (let ([sema (make-semaphore)]) + (let loop ([n num-threads]) + (unless (zero? n) + (thread (lambda () + (stw (current-thread) n) + (dynamic-wind + void + (lambda () (maker n num-times)) + (lambda () (semaphore-post sema))))) + (loop (sub1 n)))) + (let loop ([n num-threads]) + (unless (zero? n) + (wx:yield sema) + (loop (sub1 n))))) + + (collect-garbage) + (collect-garbage) + (let loop ([n 100]) + (if (zero? n) 0 (sub1 (loop (sub1 n))))) + (collect-garbage) + (collect-garbage) + (still) + (when subwindows? + (set! sub-collect-frame #f) + (set! sub-collect-panel #f)) + (when dump-stats? + (dump-memory-stats) + (still))) + +(define mred:startup + (let ([old-mred:startup mred:startup]) + (lambda args + (send mred:the-frame-group set-empty-callback (lambda () #t)) + (do-test) + (apply old-mred:startup args)))) diff --git a/collects/tests/mred/nruter.xbm b/collects/tests/mred/nruter.xbm new file mode 100644 index 0000000..9e74923 --- /dev/null +++ b/collects/tests/mred/nruter.xbm @@ -0,0 +1,4 @@ +#define nruter_width 6 +#define nruter_height 9 +static char nruter_bits[] = { + 0x1e,0x1f,0x03,0x03,0x27,0x3e,0x3c,0x3c,0x3e}; diff --git a/collects/tests/mred/random.ss b/collects/tests/mred/random.ss new file mode 100644 index 0000000..080d613 --- /dev/null +++ b/collects/tests/mred/random.ss @@ -0,0 +1,604 @@ + +(define example-list% + (class '() (parents [filter (lambda (x) (not (void? x)))]) + (public + [items '()] + [num-items 0] + + [parents-count + (if parents + (map (lambda (parent) + (ivar parent count)) + parents) + '())] + [parents-choose + (if parents + (map (lambda (parent) + (ivar parent choose-example)) + parents) + '())] + [choose-parent-example + (lambda (which) + (let loop ([pos which][counts parents-count][chooses parents-choose]) + (if (null? counts) + (void) + (let ([c ((car counts))]) + (if (< pos c) + ((car chooses) pos) + (loop (- pos c) (cdr counts) (cdr chooses)))))))] + + [count + (lambda () (+ num-items (apply + (map (lambda (x) (x)) parents-count))))] + [set-filter + (lambda (f) + (set! filter f))] + [add + (lambda (x) + (when (filter x) + (set! num-items (add1 num-items)) + (set! items (cons x items))))] + [all-examples + (lambda () + (apply append items (map (lambda (p) (send p all-examples)) parents)))] + [choose-example + (opt-lambda ([which #f]) + (let ([n (if which + which + (let ([c (count)]) + (if (zero? c) + 0 + (random c))))]) + (if (< n num-items) + (list-ref items n) + (choose-parent-example (- n num-items)))))]))) + +(define boxed-example-list% + (class () (null-ok? parent) + (public + [all-examples + (lambda () + (let ([l (map box (send parent all-examples))]) + (if null-ok? + (cons '() l) + l)))] + [choose-example + (opt-lambda ([which #f]) + (if (and null-ok? (zero? (random 2))) + '() + (let ([ex (send parent choose-example)]) + (if (void? ex) + (void) + (box ex)))))]))) + +(define array-example-list% + (class () (parent) + (public + [all-examples + (lambda () + (let ([v1 (cons (send parent choose-example) '())] + [v2 (cons (send parent choose-example) '())]) + (set-cdr! v1 v1) ; cycle + (set-cdr! v2 (send parent choose-example)) ; improper + (list v1 v2 (send parent all-examples))))] + [choose-example + (opt-lambda ([which #f]) + (let ([ex (send parent choose-example)]) + (if (void? ex) + (void) + (if (zero? (random 10)) + ; occasionally pick a mean one + (let ([v (cons ex '())]) + (if (zero? (random 2)) + (set-cdr! v v) ; cycle + (set-cdr! v (send parent choose-example))) ; improper + v) + (let loop ([count (random 10)]) + (cond + [(zero? count) '()] + [(= count 1) (list ex)] + [else + (cons (send parent choose-example) (loop (sub1 count)))]))))))]))) + +(define-macro define-main + (lambda list + (let loop ([l list][rest '()]) + (if (null? l) + (cons 'begin rest) + (loop (cdr l) + (let* ([first (car l)] + [name (if (symbol? first) + first + (car first))] + [strname (symbol->string name)] + [bases (if (symbol? first) + () + (cdr first))] + [el-name (lambda (s) + (if s + (string->symbol + (string-append + (symbol->string s) + "-example-list")) + #f))]) + (cons + `(define ,(el-name name) + (make-object example-list% (list ,@(map el-name bases)) + (lambda (v) (if (null? v) + (error ,name "got null"))))) + (if (char=? #\! (string-ref strname (sub1 (string-length strname)))) + (let* ([base (substring strname 0 (sub1 (string-length strname)))] + [caret (string->symbol (string-append base "^"))] + [percent (string->symbol (string-append base "%"))]) + (list* + `(define ,(el-name caret) + (make-object example-list% (list ,(el-name name)))) + `(define ,(el-name percent) + (make-object example-list% (list ,(el-name name)))) + `(send ,(el-name caret) add '()) + rest)) + rest)))))))) + +(define-main + void + char + ubyte + int + string + bool + float + + pathname + + void* + istream% + ostream% + + wxFunction + wxKeyErrorFunction + wxKeyFunction + wxMouseFunction + wxBreakSequenceFunction + wxGrabMouseFunction + wxGrabKeyFunction + wxClickbackFunc + wxWordbreakFunc + + (wxObject! wxWindow! wxItem! wxColour! wxList!) + + wxPoint! + wxIntPoint! + + wxButton! + wxColour! + wxFont! + wxBrush! + wxPen! + + wxFontList! + wxPenList! + wxBrushList! + wxColourDatabase! + wxFontNameDirectory! + + wxColourMap! + wxCursor! + wxIcon! + wxBitmap! + + (wxEvent! wxCommandEvent! wxMouseEvent! wxKeyEvent!) + wxCommandEvent! + wxMouseEvent! + wxKeyEvent! + + (wxDC! wxCanvasDC! wxPanelDC! wxMemoryDC! wxPostScriptDC!) + wxCanvasDC! + wxPanelDC! + wxMemoryDC! + wxPostScriptDC! + + basePrinterDC! + baseMetaFileDC! + + baseMetaFile! + + (wxWindow! wxFrame! wxCanvas! wxItem!) + + wxFrame! + wxTextWindow! + (wxCanvas! wxPanel! wxMediaCanvas!) + (wxPanel! wxDialogBox!) + wxDialogBox! + wxMediaCanvas! + + (wxItem! wxButton! wxCheckBox! wxChoice! + wxListBox! wxSlider! wxsGauge! wxText! wxMultiText! + wxRadioBox! wxMessage! wxGroupBox!) + wxButton! + wxCheckBox! + wxChoice! + wxListBox! + wxSlider! + wxsGauge! + wxText! + wxMultiText! + wxMessage! + wxRadioBox! + wxGroupBox! + + wxMenu! + wxMenuBar! + + wxNode! + wxList! + + wxHashTable! + wxPathList! + wxStringList! + + wxConnection! + (wxIPCObject! wxClient! wxServer!) + wxClient! + wxServer! + + wxTimer! + wxTypeTree! + + wxToolBarTool! + wxToolBar! + + wxLayoutConstraints! + + wxAddColour! + wxMultColour! + wxStyleDelta! + wxStyle! + wxStyleList! + + (wxMediaAdmin! wxCanvasMediaAdmin! wxMediaSnipMediaAdmin!) + wxCanvasMediaAdmin! + wxMediaSnipMediaAdmin! + wxSnipAdmin! + + (wxMediaBuffer! wxMediaEdit! wxMediaPasteboard!) + wxMediaEdit! + wxMediaPasteboard! + + (wxSnip! wxTextSnip! wxImageSnip! wxMediaSnip!) + (wxTextSnip! wxTabSnip!) + wxTabSnip! + wxImageSnip! + wxMediaSnip! + + wxSnipClass! + wxSnipClassList! + + wxBufferData! + wxBufferDataClass! + wxBufferDataClassList! + + wxKeymap! + wxMediaWordbreakMap! + + (wxMediaStreamInBase! wxMediaStreamInStringBase!) + (wxMediaStreamOutBase! wxMediaStreamOutStringBase!) + + wxMediaStreamInStringBase! + wxMediaStreamOutStringBase! + + wxMediaStreamIn! + wxMediaStreamOut! + + wxClipboard! + wxClipboardClient! + + Scheme_Object*) + +(send wxBitmap!-example-list set-filter (lambda (bm) (send bm ok?))) + +(define-macro define-boxed + (lambda list + (let ([make + (lambda (s tag) + (string->symbol + (string-append + (symbol->string s) + tag + "-example-list")))]) + (let loop ([l list][rest '()]) + (if (null? l) + (cons 'begin rest) + (loop (cdr l) + (cons `(define ,(make (car l) "*") + (make-object boxed-example-list% #f ,(make (car l) ""))) + (cons `(define ,(make (car l) "?") + (make-object boxed-example-list% #t ,(make (car l) ""))) + rest)))))))) + +(define-macro define-array + (lambda list + (let ([make + (lambda (s tag) + (string->symbol + (string-append + (symbol->string s) + tag + "-example-list")))]) + (let loop ([l list][rest '()]) + (if (null? l) + (cons 'begin rest) + (loop (cdr l) + (cons `(define ,(make (car l) "ARRAY") + (make-object array-example-list% ,(make (car l) ""))) + rest))))))) + +(define nstring-example-list (make-object example-list% (list string-example-list))) +(send nstring-example-list add '()) + +(define long-example-list int-example-list) +(define Long-example-list int-example-list) +(define short-example-list int-example-list) +(define Bool-example-list int-example-list) +(define _KEY_TYPE-example-list int-example-list) +(define uchar-example-list char-example-list) +(define double-example-list float-example-list) +(define Double-example-list double-example-list) +(define cstring-example-list string-example-list) +(define ustring-example-list string-example-list) +(define custring-example-list string-example-list) +(define ncstring-example-list nstring-example-list) +(define ncustring-example-list nstring-example-list) + +(define voidARRAY-example-list (make-object example-list% null)) +(define CAPOFunc-example-list (make-object example-list% null)) + +(define false-example-list (make-object example-list% '())) +(send false-example-list add #f) + +(define-boxed + int + string + bool + ubyte + float + Double + Long + long + short + wxSnip!) + +(define Double+-example-list Double*-example-list) +(define long+-example-list long*-example-list) +(define Long+-example-list Long*-example-list) + +(define wxBitmap*-example-list wxBitmap!-example-list) +(define wxMenu*-example-list wxMenu!-example-list) + +(define-array + char + string + int + long + float + wxBitmap* + wxMenu*) + +(define int**-example-list + (make-object array-example-list% int*-example-list)) + +(send* bool-example-list + (add #t) + (add #f)) + +(send* int-example-list + (add 0) (add 0) (add 0) (add 0) + (add 0) (add 0) (add 0) (add 0) + (add 0) (add 0) (add 0) (add 0) + (add 0) (add 0) (add 0) (add 0) + (add -1) + (add -2) + (add -3) + (add -1000) + (add 1) + (add 2) + (add 3) + (add 4) + (add 5) + (add 6) + (add 7) + (add 8) + (add 9) + (add 10) + (add 16) + (add 32) + (add 64) + (add 128) + (add 256) + (add 255) + (add 1023) + (add 1000) + (add 5.0)) + +(send* ubyte-example-list + (add 0) (add 0) (add 0) + (add 0) (add 0) (add 0) + (add 0) (add 0) (add 0) + (add 0) (add 0) (add 0) + (add 0) (add 0) (add 0) + (add 1) + (add 2) + (add 3) + (add 4) + (add 5) + (add 6) + (add 7) + (add 8) + (add 9) + (add 10) + (add 16) + (add 32) + (add 64) + (add 128) + (add 255) + (add 5)) + +(send* char-example-list + (add #\nul) + (add #\a) + (add #\1) + (add #\newline) + (add #\tab) + (add #\z) + (add #\C)) + +(send* float-example-list + (add 0.) + (add 0.) + (add 0.) + (add -1.) + (add -2.) + (add -3.) + (add -1000.) + (add 1.) + (add 2.) + (add 3.) + (add 1000.) + (add 5)) + +(send* string-example-list + (add "") + (add "hello") + (add "system/mred.xbm") + (add "system/mred.bmp") + (add "mred.gif") + (add "goodbye adious see you later zai jian seeya bye-bye")) + +(send pathname-example-list add "/tmp/x") +(define npathname-example-list (make-object example-list% (list string-example-list))) +(send npathname-example-list add '()) + +(send wxFunction-example-list add void) +(send wxKeyErrorFunction-example-list add void) +(send wxKeyFunction-example-list add void) +(send wxMouseFunction-example-list add void) +(send wxClickbackFunc-example-list add void) +(send wxWordbreakFunc-example-list add void) + +(define classinfo (make-hash-table)) + +(load-relative "tests.ss") + +(define (get-args l) + (let/ec bad + (let loop ([l l]) + (if (null? l) + '() + (let* ([source (car l)] + [value (send source choose-example #f)]) + (if (void? value) + (bad #f) + (cons value (loop (cdr l))))))))) + +(define (get-all-args l) + (let loop ([l l]) + (if (null? l) + '() + (let* ([source (car l)] + [values (send source all-examples)] + [rest (loop (cdr l))]) + (if (null? (cdr l)) + (list values) + (apply append + (map (lambda (other) + (map (lambda (v) (cons v other)) values)) + rest))))))) + +(define thread-output-port + (let ([p mred:original-output-port]) + (lambda () + p))) + + +(define (apply-args v dest name k) + (if v + (begin + (fprintf (thread-output-port) "~a: ~a" name v) + (flush-output (thread-output-port)) + (with-handlers ((void (lambda (x) + (fprintf (thread-output-port) + ": error: ~a~n" + (exn-message x))))) + (send dest add (k v)) + (wx:flush-display) + (fprintf (thread-output-port) ": success~n"))) + (fprintf (thread-output-port) "~a: failure~n" name))) + +(define (try-args arg-types dest name k) + (apply-args (get-args arg-types) dest name k)) + +(define (try-all-args arg-types dest name k) + (let ([vs (get-all-args arg-types)]) + (map (lambda (v) + (apply-args v dest name k)) + vs))) + +(define (create-some cls try) + (when (class? cls) + (let* ([v (hash-table-get classinfo cls)] + [dest (car v)] + [name (cadr v)] + [creators (caddr v)]) + (let loop ([l creators]) + (unless (null? l) + (try (car l) dest name + (lambda (v) + (apply make-object cls v))) + (loop (cdr l))))))) + +(define (create-all-random) + (fprintf (thread-output-port) "creating all randomly...~n") + (hash-table-for-each classinfo (lambda (k v) + (create-some k try-args)))) +(define (create-all-exhaust) + (fprintf (thread-output-port) "creating all exhaustively...~n") + (hash-table-for-each classinfo (lambda (k v) + (create-some k try-all-args)))) + +(define (try-methods cls try) + (let* ([v (hash-table-get classinfo cls)] + [source (car v)] + [use (if source (send source choose-example) #f)] + [name (cadr v)] + [methods (cdddr v)]) + (if (void? use) + (fprintf (thread-output-port) "~s: no examples~n" name) + (let loop ([l methods]) + (unless (null? l) + (let* ([method (car l)] + [iv (car method)] + [resulttype (cadr method)] + [argtypes (cddr method)]) + (try argtypes resulttype (list name iv use) + (lambda (args) + (if use + (apply (uq-ivar use iv) args) + (apply (global-defined-value iv) args))))) + (loop (cdr l))))))) + +(define (call-random except) + (fprintf (thread-output-port) "calling all except ~a randomly...~n" except) + (hash-table-for-each classinfo (lambda (k v) + (unless (member k except) + (try-methods k try-args))))) + +(define (call-all-random) + (call-random null)) + +(define (call-all-non-media) + (call-random (list wx:media-buffer% wx:media-edit% wx:media-snip% wx:media-pasteboard% 'wxMediaGlobal))) + +(define (init) + (create-all-random) + (create-all-random) + (create-all-random) + (create-all-random)) + diff --git a/collects/tests/mred/showkey.ss b/collects/tests/mred/showkey.ss new file mode 100644 index 0000000..7e76a19 --- /dev/null +++ b/collects/tests/mred/showkey.ss @@ -0,0 +1,15 @@ +(let ([c% + (class-asi mred:canvas% + (public + [on-char + (lambda (ev) + (printf "code: ~a meta: ~a alt: ~a shift: ~a~n" + (send ev get-key-code) + (send ev get-control-down) + (send ev get-alt-down) + (send ev get-shift-down)))]))]) + (define f (make-object mred:frame% null "tests" 0 0 100 100)) + (define p (make-object mred:vertical-panel% f)) + (define c (make-object c% p)) + (send f show #t)) + diff --git a/collects/tests/mred/startup/app-A/info.ss b/collects/tests/mred/startup/app-A/info.ss new file mode 100644 index 0000000..c4cd810 --- /dev/null +++ b/collects/tests/mred/startup/app-A/info.ss @@ -0,0 +1,7 @@ +(lambda (request) + (case request + [(name) "Startup Test"] + [(app-unit-library) "tappinfo.ss"] + [(app-sig-library) "tsig.ss"] + [(splash-image-path) #f] + [else (error 'test-A "Unknown request: ~s" request)])) diff --git a/collects/tests/mred/startup/app-A/tappinfo.ss b/collects/tests/mred/startup/app-A/tappinfo.ss new file mode 100644 index 0000000..6133a7c --- /dev/null +++ b/collects/tests/mred/startup/app-A/tappinfo.ss @@ -0,0 +1,3 @@ +(unit/sig () + (import [I : mred:application-imports^]) + (printf "whee~n")) \ No newline at end of file diff --git a/collects/tests/mred/startup/app-A/tsig.ss b/collects/tests/mred/startup/app-A/tsig.ss new file mode 100644 index 0000000..e69de29 diff --git a/collects/tests/mred/startup/app-a/tapp.ss b/collects/tests/mred/startup/app-a/tapp.ss new file mode 100644 index 0000000..6133a7c --- /dev/null +++ b/collects/tests/mred/startup/app-a/tapp.ss @@ -0,0 +1,3 @@ +(unit/sig () + (import [I : mred:application-imports^]) + (printf "whee~n")) \ No newline at end of file diff --git a/collects/tests/mred/startup/app-a/tsig.ss b/collects/tests/mred/startup/app-a/tsig.ss new file mode 100644 index 0000000..e69de29 diff --git a/collects/tests/mred/startup/ee-has-mred.ss b/collects/tests/mred/startup/ee-has-mred.ss new file mode 100644 index 0000000..2cd5888 --- /dev/null +++ b/collects/tests/mred/startup/ee-has-mred.ss @@ -0,0 +1,2 @@ +(when (and (defined? 'mred:frame%) (defined? 'mred:console)) + (printf "ee~n")) diff --git a/collects/tests/mred/startup/ee.ss b/collects/tests/mred/startup/ee.ss new file mode 100644 index 0000000..476d047 --- /dev/null +++ b/collects/tests/mred/startup/ee.ss @@ -0,0 +1 @@ +(printf "ee~n") diff --git a/collects/tests/mred/startup/run.ss b/collects/tests/mred/startup/run.ss new file mode 100755 index 0000000..bc5033a --- /dev/null +++ b/collects/tests/mred/startup/run.ss @@ -0,0 +1,213 @@ +#!/bin/sh + +string=? ; exec /home/scheme/Executables/mzscheme -x -qgr $0 $@ + +(define arg (if (= 0 (vector-length argv)) + "-x" + (vector-ref argv 0))) + +(define plt-collects + (cond + [(string=? arg "-x") ":"] + [(string=? arg "-robby") "/home/robby/plt:"] + [else (error 'plt-home "don't recognize ~a~n" arg)])) + +(define (print-plt-collects) + (printf "PLTCOLLECTS is now ~s~n" (getenv "PLTCOLLECTS"))) + +;; this takes -x, -robby etc into account +(define (extend-plt-collects path) + (let ([new-collects + (if (char=? (string-ref plt-collects 0) #\:) + (string-append path ":") + (string-append path ":" plt-collects))]) + (putenv "PLTCOLLECTS" new-collects) + (print-plt-collects))) +(define (reset-plt-collects) + (putenv "PLTCOLLECTS" plt-collects) + (print-plt-collects)) + +(define MRED (list "/home/scheme/plt/bin/mred")) + +(printf "WARNING: this script will move your ~~/.mredrc to ~~/mredrc +and write into your .mredrc. It should restore things, but if tests +fail your .mredrc may by in ~~/mredrc. + +If you pass an argument, that is passed on to +/home/scheme/Executables/mred. It's used for -robby or something like that + +If you see lines prefixed by `>' they are from mred's stderr and +mean that test has failed (even tho the script does not stop or say FAIL) + +If you see the splash screen (except during the splash screen test), +the test failed. The console window popping up occasionally is okay, +tho. + +You must run this script from the directory where it is located. + +") + +(printf "mred is: ~s~n" MRED) +(reset-plt-collects) + +(when (file-exists? "~/.mredrc") + (printf "-- moving ~~/.mredrc to ~~/mredrc~n") + (system "mv -f ~/.mredrc ~/mredrc")) + +(define (set-mredrc s) + (let ([p (open-output-file "~/.mredrc" 'replace)]) + (display s p) + (close-output-port p)) + (printf "set .mredrc to:~n~a~n" s)) +(define (clear-mredrc) + (when (file-exists? "~/.mredrc") + (delete-file "~/.mredrc")) + (printf "cleared .mredrc~n")) + +(define (move-in-mredrc) + (printf "-- moving ~~/mredrc to ~~/.mredrc~n") + (if (file-exists? "~/mredrc") + (system "mv -f ~/mredrc ~/.mredrc"))) + +(current-exception-handler + (let ([old (current-exception-handler)]) + (lambda (exn) + (when (file-exists? "~/mredrc") + (move-in-mredrc)) + (old exn)))) + +(user-break-poll-handler + (let ([old (user-break-poll-handler)]) + (lambda () + (if (old) + (begin (move-in-mredrc) + (printf "caught break ~n") + #t) + #f)))) + +(define test-mred + (lambda (expected . args) + (let*-values ([(command) (append MRED args)] + [(stdout stdin pid stderr info) + (apply values + (apply process* + command))]) + (printf "running: ~s~n" command) + (thread + (lambda () + (let loop () + (let ([line (read-line stderr)]) + (unless (eof-object? line) + (display "> ") + (display line) + (newline) + (loop)))))) + (let ([received (read-line stdout)]) + (if (equal? expected received) + (printf "test passed~n") + (printf "FAILED TEST: got: ~s wanted: ~s~n" received expected)) + (printf "killing ~a~n" pid) + (system (format "kill ~a" pid)))))) + +(define (test:no-flags) + (printf "~n- testing no flags~n") + (set-mredrc "(fprintf mred:constants:original-output-port \"whee~n\")") + (test-mred "whee") + (clear-mredrc)) + +(define (test:-f) + (printf"~n- testing -f flag~n") + (test-mred "whee" "-f" "whee.ss")) + +(define (test:-e) + (printf "~n- testing -e flag~n") + (test-mred "whee" "-e" "(printf \"whee~n\")")) + +(define (test:-nu-e) + (printf "~n- testing -nu with -e flag~n") + (test-mred "whee" + "-e" + "(when (defined? 'mred:frame%) + (printf \"wh\"))" + "-nu" + "-e" + "(when (and (defined? 'mred:frame%) + (defined? 'mred:console)) + (printf \"ee~n\"))")) + +(define (test:-nu-f) + (printf "~n- testing -nu with -f flag~n") + (test-mred "whee" + "-f" + "wh-has-mred.ss" + "-nu" + "-f" + "ee-has-mred.ss")) + +(define (test:.mredrc) + (printf "~n- testing that .mredrc is loaded~n") + (set-mredrc "(fprintf mred:constants:original-output-port \"whee~n\")") + (test-mred "whee") + (clear-mredrc)) + +(define (test:.mredrc-nu-f) + (printf "~n- testing that .mredrc is run during -nu flag~n") + (set-mredrc "(fprintf mred:constants:original-output-port \"ee~n\")") + (test-mred "whee" "-f" "wh.ss" "-nu") + (clear-mredrc)) + +(define (test:mred:startup-before) + (printf "~n- testing mred:startup after -nu~n") + (set-mredrc "(printf \"ee~n\")") + (test-mred "whee" "-nu" "-e" + "(define mred:startup (lambda x (printf \"wh\")))") + (clear-mredrc)) + +(define (test:-a) + (printf "~n- testing -a flag~n") + (extend-plt-collects (current-load-relative-directory)) + (test-mred + "whee" "-a" "app-a" "tapp.ss" "tsig.ss") + (reset-plt-collects)) + +(define (test:-A) + (printf "~n- testing -A flag~n") + (extend-plt-collects (current-load-relative-directory)) + (test-mred + "whee" "-A" "app-A") + (reset-plt-collects)) + +(define (test:-p) + (printf "~n- testing -p flag~n") + (test-mred + "whee" + "-nu" + "-p" "/home/scheme/plt/collects/icons/anchor.gif" "splash screen test" "150" "4" + "-e" "(printf \"whee~n\")")) + +(define (test:no-icons) + (let ([icons-before/after (collection-path "icons")]) + (let-values ([(path _1 _2) (split-path icons-before/after)]) + (let ([icons-during (build-path path "renamed-icons")]) + (printf "~n- testing icon-less startup~n") + (printf "~n This test expects only one icons collection is available") + (printf "~n-- moving ~a to ~a ~n" icons-before/after icons-during) + (rename-file icons-before/after icons-during) + (test-mred "whee" "-e" "(printf \"whee~n\")") + (printf "~n-- moving ~a to ~a ~n" icons-during icons-before/after) + (rename-file icons-during icons-before/after))))) + +(test:no-icons) +(test:no-flags) +(test:-e) +(test:-f) +(test:-nu-e) +(test:-nu-f) +(test:.mredrc) +(test:.mredrc-nu-f) +(test:mred:startup-before) +(test:-a) +(test:-A) +(test:-p) + +(move-in-mredrc) \ No newline at end of file diff --git a/collects/tests/mred/startup/w.ss b/collects/tests/mred/startup/w.ss new file mode 100644 index 0000000..e073ee7 --- /dev/null +++ b/collects/tests/mred/startup/w.ss @@ -0,0 +1 @@ +(printf "w") diff --git a/collects/tests/mred/startup/wh-has-mred.ss b/collects/tests/mred/startup/wh-has-mred.ss new file mode 100644 index 0000000..152c6c8 --- /dev/null +++ b/collects/tests/mred/startup/wh-has-mred.ss @@ -0,0 +1,3 @@ +(when (and (defined? 'mred:frame%) + (defined? 'mred:console)) + (printf "wh")) diff --git a/collects/tests/mred/startup/wh.ss b/collects/tests/mred/startup/wh.ss new file mode 100644 index 0000000..c5f55b4 --- /dev/null +++ b/collects/tests/mred/startup/wh.ss @@ -0,0 +1 @@ +(printf "wh") diff --git a/collects/tests/mred/startup/whee.ss b/collects/tests/mred/startup/whee.ss new file mode 100644 index 0000000..407ddff --- /dev/null +++ b/collects/tests/mred/startup/whee.ss @@ -0,0 +1 @@ +(printf "whee~n") diff --git a/collects/tests/mred/steps.txt b/collects/tests/mred/steps.txt new file mode 100644 index 0000000..b33c7e5 --- /dev/null +++ b/collects/tests/mred/steps.txt @@ -0,0 +1,130 @@ +Instructions: + Initial Setup: + - Second menu is enabled "Apple" + Delete Apple + + Menu Inserting & Deleting: + Add Apple - apple menu appears + Add Banana - banana menu appears + Delete Apple (from apple menu) - apple menu goes, banana menu still there + Delete Banana - back to starting point + Add Apple + Add Banana + Delete Banana - apple still there + Delete Apple + Add Apple + Add Coconut - coconut submenu appears + Delete Coconut (from sub-menu) - coconut submenu gone + Delete Apple + Add Coconut + Add Apple - apple menu appears with coconut already + Delete Apple + Delete Coconut + Add Apple - apple menu appears without coconut + + Menu Enabling: + Disable Second - apple menu gray & unselectable + Enable Second - back to normal + Disable Second + Delete Apple (from tester menu) + Add Apple - NOT gray anymore + + Item Enabling: + Disable Apple Once Item -> once item grayed & unselectable + Un-Disable Apple Once Item -> once item normal + Disable Apple Once Item + Delete Apple + Add Apple -> once item still gray + Un-Disable Apple Once Item + Delete Apple + Disable Apple Once Item + Add Apple -> once item gray again + Un-Disable Apple Once Item + + Item Inserting & Deleting: + Append Donut - donut item added + Delete Once - once item disappears + Delete Apple + Add Apple - once item still gone + Append Donut - another donut + Delete Apple + Append Donut + Add Apple - three donuts total + + Checkable Items & Insertions: + Test Apple Item -> "no" + Apple Checkable + Test Apple Item -> "yes" + Delete Apple + Test Apple Item -> "yes" + Apple Checkable + Test Apple Item -> "no" + Delete Apple + Test Apple Item -> "no" + + More Checkable (Apple & Banana currently deleted): + Test Aeros -> "yes" + Test Bruin -> "no" + Test Capitols -> "no" + + Check Astros -> nothing + Check Braves -> "Braves checked", braves checked, astros unchecked + Check Cardianls -> "Cardinals checked", cardinals checked, braves unchecked + + Check Bruins -> "Boston checked", aeros unchecked, bruins checked + + Test Aeros -> "no" + Test Bruin -> "yes" + Test Capitols -> "no" + + Checkable via Menubar (Apple & Banana currently deleted): + Via Menubar + Test Aeros -> "no" + Test Bruin -> "yes" + Test Apple Item -> "no" + Check in Apple (Button) + Add Apple - checkable item *not* checked + Check in Apple (Button) - item checked + Test Apple Item -> "yes" + Delete Apple + Test Apple Item -> "no" + Add Apple + Apple | Checkable + Delete Apple + Via Menubar + + Labels (Apple & Banana currently deleted): + Add Coconut - (coconut item needed for the rest) + Test Labels - "ok" in console + Find Labels - "ok" in console + Toggle Labels - "Tester" -> "Hi", "Add Apple" -> "Apple Adder", "Astros" -> "'Stros" + Add Apple - check that "Delete Apple" -> "Apple Deleter" + Delete Apple + Test Labels - "ok" in console + Find Labels - "ok" in console + Toggle Labels - original labels + Add Apple - check for original labels + Toggle Labels - "Delete Apple" -> "Apple Deleter" + Toggle Labels + Delete Apple + Via Menubar + Test Labels - "ok" in console + Find Labels - "ok" in console + Toggle Labels - "Add Apple" -> "Apple Adder", "Astros" -> "'Stros" + Test Labels - "ok" in console + Find Labels - "ok" in console + Toggle Labels - original labels + Add Apple + Test Labels - "ok" in console + Find Labels - "ok" in console + Via Menubar - off + + Handling Bad Requests: + Test Bad Item -> #f + Test Other Bad Item -> #f + Bad Item Labels - "ok" in console + Via Menubar + Bad Item Labels - "ok" in console + Via Menubar + Bad Check - nothing + Bad Enable - nothing diff --git a/collects/tests/mred/tests.ss b/collects/tests/mred/tests.ss new file mode 100644 index 0000000..4adfdfb --- /dev/null +++ b/collects/tests/mred/tests.ss @@ -0,0 +1,1698 @@ +(hash-table-put! classinfo wx:bitmap% + (list wxBitmap!-example-list (quote wx:bitmap%) + (list + (list charARRAY-example-list int-example-list int-example-list int-example-list) + (list int-example-list int-example-list int-example-list) + (list pathname-example-list long-example-list)) + (list 'set-colour-map void-example-list wxColourMap^-example-list) + (list 'load-file void-example-list pathname-example-list long-example-list) + (list 'ok? bool-example-list) + (list 'get-width int-example-list) + (list 'get-height int-example-list) + (list 'get-depth int-example-list))) +(hash-table-put! classinfo wx:button% + (list wxButton!-example-list (quote wx:button%) + (list + (list wxPanel!-example-list wxFunction-example-list string-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list) + (list wxPanel!-example-list wxFunction-example-list wxBitmap!-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'set-label void-example-list string-example-list) + (list 'set-label void-example-list wxBitmap!-example-list) + (list 'set-default void-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list))) +(hash-table-put! classinfo wx:choice% + (list wxChoice!-example-list (quote wx:choice%) + (list + (list wxPanel!-example-list wxFunction-example-list nstring-example-list int-example-list int-example-list int-example-list int-example-list stringARRAY-example-list long-example-list string-example-list)) + (list 'get-columns int-example-list) + (list 'set-columns void-example-list int-example-list) + (list 'get-string string-example-list int-example-list) + (list 'set-string-selection void-example-list string-example-list) + (list 'set-selection void-example-list int-example-list) + (list 'get-string-selection string-example-list) + (list 'get-selection int-example-list) + (list 'find-string int-example-list string-example-list) + (list 'number int-example-list) + (list 'clear void-example-list) + (list 'append void-example-list string-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list))) +(hash-table-put! classinfo wx:check-box% + (list wxCheckBox!-example-list (quote wx:check-box%) + (list + (list wxPanel!-example-list wxFunction-example-list string-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list) + (list wxPanel!-example-list wxFunction-example-list wxBitmap!-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'set-label void-example-list string-example-list) + (list 'set-label void-example-list wxBitmap!-example-list) + (list 'set-value void-example-list bool-example-list) + (list 'get-value bool-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list))) +(hash-table-put! classinfo wx:canvas% + (list wxCanvas!-example-list (quote wx:canvas%) + (list + (list wxFrame!-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list) + (list wxPanel!-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'set-text-foreground void-example-list wxColour!-example-list) + (list 'set-text-background void-example-list wxColour!-example-list) + (list 'set-pen void-example-list wxPen!-example-list) + (list 'set-logical-function void-example-list int-example-list) + (list 'set-font void-example-list wxFont!-example-list) + (list 'set-brush void-example-list wxBrush!-example-list) + (list 'set-background void-example-list wxBrush!-example-list) + (list 'get-clipping-region void-example-list float*-example-list float*-example-list float*-example-list float*-example-list) + (list 'set-clipping-region void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'destroy-clipping-region void-example-list) + (list 'draw-polygon void-example-list wxPoint!-example-list float-example-list float-example-list int-example-list) + (list 'draw-lines void-example-list wxPoint!-example-list float-example-list float-example-list) + (list 'draw-ellipse void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'draw-arc void-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'draw-text void-example-list string-example-list float-example-list float-example-list bool-example-list) + (list 'draw-spline void-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'draw-rounded-rectangle void-example-list float-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'draw-rectangle void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'draw-point void-example-list float-example-list float-example-list) + (list 'draw-line void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'clear void-example-list) + (list 'end-drawing void-example-list) + (list 'begin-drawing void-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list) + (list 'scroll void-example-list int-example-list int-example-list) + (list 'warp-pointer void-example-list int-example-list int-example-list) + (list 'view-start void-example-list int*-example-list int*-example-list) + (list 'set-scrollbars void-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list bool-example-list) + (list 'is-retained? bool-example-list) + (list 'get-virtual-size void-example-list int*-example-list int*-example-list) + (list 'get-scroll-units-per-page void-example-list int*-example-list int*-example-list) + (list 'get-dc wxCanvasDC!-example-list) + (list 'popup-menu bool-example-list wxMenu!-example-list float-example-list float-example-list) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxMouseEvent%-example-list) + (list 'on-paint void-example-list) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'enable-scrolling void-example-list bool-example-list bool-example-list) + (list 'allow-double-click void-example-list bool-example-list))) +(hash-table-put! classinfo wx:dc% + (list wxDC!-example-list (quote wx:dc%) + (list) + (list 'end-page void-example-list) + (list 'end-doc void-example-list) + (list 'start-page void-example-list) + (list 'start-doc bool-example-list string-example-list) + (list 'ok? bool-example-list) + (list 'min-y float-example-list) + (list 'min-x float-example-list) + (list 'max-y float-example-list) + (list 'max-x float-example-list) + (list 'get-size void-example-list float*-example-list float*-example-list) + (list 'get-text-foreground wxColour%-example-list) + (list 'get-text-background wxColour%-example-list) + (list 'get-pen wxPen!-example-list) + (list 'get-map-mode int-example-list) + (list 'get-logical-function int-example-list) + (list 'get-font wxFont!-example-list) + (list 'get-brush wxBrush!-example-list) + (list 'get-background wxBrush!-example-list) + (list 'set-device-origin void-example-list float-example-list float-example-list) + (list 'set-user-scale void-example-list float-example-list float-example-list) + (list 'set-colour-map void-example-list wxColourMap!-example-list) + (list 'set-background-mode void-example-list int-example-list) + (list 'set-map-mode void-example-list int-example-list) + (list 'try-colour void-example-list wxColour!-example-list wxColour!-example-list) + (list 'blit bool-example-list float-example-list float-example-list float-example-list float-example-list wxCanvasDC!-example-list float-example-list float-example-list int-example-list) + (list 'draw-icon void-example-list wxIcon!-example-list float-example-list float-example-list) + (list 'set-optimization void-example-list bool-example-list) + (list 'get-char-width float-example-list) + (list 'get-char-height float-example-list) + (list 'get-text-extent void-example-list string-example-list float*-example-list float*-example-list float?-example-list float?-example-list wxFont^-example-list bool-example-list) + (list 'set-text-foreground void-example-list wxColour!-example-list) + (list 'set-text-background void-example-list wxColour!-example-list) + (list 'set-pen void-example-list wxPen!-example-list) + (list 'set-logical-function void-example-list int-example-list) + (list 'set-font void-example-list wxFont!-example-list) + (list 'set-brush void-example-list wxBrush!-example-list) + (list 'set-background void-example-list wxBrush!-example-list) + (list 'get-clipping-region void-example-list float*-example-list float*-example-list float*-example-list float*-example-list) + (list 'set-clipping-region void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'destroy-clipping-region void-example-list) + (list 'draw-polygon void-example-list wxPoint!-example-list float-example-list float-example-list int-example-list) + (list 'draw-lines void-example-list wxPoint!-example-list float-example-list float-example-list) + (list 'draw-ellipse void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'draw-arc void-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'draw-text void-example-list string-example-list float-example-list float-example-list bool-example-list) + (list 'draw-spline void-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'draw-rounded-rectangle void-example-list float-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'draw-rectangle void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'draw-point void-example-list float-example-list float-example-list) + (list 'draw-line void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'clear void-example-list) + (list 'end-drawing void-example-list) + (list 'begin-drawing void-example-list))) +(hash-table-put! classinfo wx:canvas-dc% + (list wxCanvasDC!-example-list (quote wx:canvas-dc%) + (list + (list)) + (list 'set-pixel void-example-list float-example-list float-example-list wxColour^-example-list) + (list 'end-set-pixel void-example-list) + (list 'begin-set-pixel void-example-list) + (list 'get-pixel bool-example-list float-example-list float-example-list wxColour^-example-list))) +(hash-table-put! classinfo wx:memory-dc% + (list wxMemoryDC!-example-list (quote wx:memory-dc%) + (list + (list) + (list wxCanvasDC!-example-list)) + (list 'select-object void-example-list wxBitmap^-example-list))) +(hash-table-put! classinfo wx:post-script-dc% + (list wxPostScriptDC!-example-list (quote wx:post-script-dc%) + (list + (list npathname-example-list bool-example-list wxWindow^-example-list)))) +(hash-table-put! classinfo wx:printer-dc% + (list basePrinterDC!-example-list (quote wx:printer-dc%) + (list + (list nstring-example-list nstring-example-list nstring-example-list bool-example-list)))) +(hash-table-put! classinfo wx:meta-file-dc% + (list baseMetaFileDC!-example-list (quote wx:meta-file-dc%) + (list + (list string-example-list)))) +(hash-table-put! classinfo wx:event% + (list wxEvent!-example-list (quote wx:event%) + (list) + (list 'get-event-class long-example-list) + (list 'set-event-class void-example-list long-example-list) + (list 'get-event-type long-example-list) + (list 'set-event-type void-example-list long-example-list) + (list 'get-event-object wxObject!-example-list) + (list 'set-event-object void-example-list wxObject!-example-list))) +(hash-table-put! classinfo wx:command-event% + (list wxCommandEvent!-example-list (quote wx:command-event%) + (list + (list int-example-list)) + (list 'is-selection? bool-example-list) + (list 'checked? bool-example-list) + (list 'get-string string-example-list) + (list 'get-selection int-example-list) + (list 'get-extra-long long-example-list) + (list 'set-extra-long void-example-list long-example-list) + (list 'get-command-int int-example-list) + (list 'set-command-int void-example-list int-example-list) + (list 'get-command-string string-example-list) + (list 'set-command-string void-example-list string-example-list))) +(hash-table-put! classinfo wx:key-event% + (list wxKeyEvent!-example-list (quote wx:key-event%) + (list + (list int-example-list)) + (list 'position void-example-list float*-example-list float*-example-list) + (list 'key-code long-example-list) + (list 'get-key-code long-example-list) + (list 'set-key-code void-example-list long-example-list) + (list 'get-shift-down bool-example-list) + (list 'set-shift-down void-example-list bool-example-list) + (list 'get-control-down bool-example-list) + (list 'set-control-down void-example-list bool-example-list) + (list 'get-meta-down bool-example-list) + (list 'set-meta-down void-example-list bool-example-list) + (list 'get-alt-down bool-example-list) + (list 'set-alt-down void-example-list bool-example-list) + (list 'get-time-stamp long-example-list) + (list 'set-time-stamp void-example-list long-example-list))) +(hash-table-put! classinfo wx:mouse-event% + (list wxMouseEvent!-example-list (quote wx:mouse-event%) + (list + (list int-example-list)) + (list 'moving? bool-example-list) + (list 'is-button? bool-example-list) + (list 'leaving? bool-example-list) + (list 'entering? bool-example-list) + (list 'dragging? bool-example-list) + (list 'button-up? bool-example-list int-example-list) + (list 'button-down? bool-example-list int-example-list) + (list 'button-d-click? bool-example-list int-example-list) + (list 'button? bool-example-list int-example-list) + (list 'get-left-down bool-example-list) + (list 'set-left-down void-example-list bool-example-list) + (list 'get-middle-down bool-example-list) + (list 'set-middle-down void-example-list bool-example-list) + (list 'get-right-down bool-example-list) + (list 'set-right-down void-example-list bool-example-list) + (list 'get-shift-down bool-example-list) + (list 'set-shift-down void-example-list bool-example-list) + (list 'get-control-down bool-example-list) + (list 'set-control-down void-example-list bool-example-list) + (list 'get-meta-down bool-example-list) + (list 'set-meta-down void-example-list bool-example-list) + (list 'get-alt-down bool-example-list) + (list 'set-alt-down void-example-list bool-example-list) + (list 'get-x float-example-list) + (list 'set-x void-example-list float-example-list) + (list 'get-y float-example-list) + (list 'set-y void-example-list float-example-list) + (list 'get-time-stamp long-example-list) + (list 'set-time-stamp void-example-list long-example-list))) +(hash-table-put! classinfo 'wxEventGlobal + (list #f (quote 'wxEventGlobal) + (list) + (list 'duplicate-mouse-event wxMouseEvent!-example-list wxMouseEvent!-example-list) + (list 'duplicate-key-event wxKeyEvent!-example-list wxKeyEvent!-example-list))) +(hash-table-put! classinfo wx:frame% + (list wxFrame!-example-list (quote wx:frame%) + (list + (list wxFrame^-example-list string-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list) + (list 'on-menu-select void-example-list int-example-list) + (list 'on-menu-command void-example-list int-example-list) + (list 'command void-example-list int-example-list) + (list 'on-close bool-example-list) + (list 'on-activate void-example-list bool-example-list) + (list 'create-status-line void-example-list int-example-list string-example-list) + (list 'load-accelerators void-example-list string-example-list) + (list 'maximize void-example-list bool-example-list) + (list 'status-line-exists? bool-example-list) + (list 'iconized? bool-example-list) + (list 'set-status-text void-example-list string-example-list) + (list 'get-tool-bar wxToolBar^-example-list) + (list 'set-tool-bar void-example-list wxToolBar^-example-list) + (list 'get-menu-bar wxMenuBar^-example-list) + (list 'set-menu-bar void-example-list wxMenuBar!-example-list) + (list 'set-icon void-example-list wxIcon!-example-list) + (list 'iconize void-example-list bool-example-list) + (list 'set-title void-example-list string-example-list) + (list 'get-title string-example-list) + (list 'get-menu-bar wxMenuBar^-example-list))) +(hash-table-put! classinfo wx:gauge% + (list wxsGauge!-example-list (quote wx:gauge%) + (list + (list wxPanel!-example-list nstring-example-list int-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'get-value int-example-list) + (list 'set-value void-example-list int-example-list) + (list 'get-range int-example-list) + (list 'set-range void-example-list int-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list))) +(hash-table-put! classinfo wx:font% + (list wxFont!-example-list (quote wx:font%) + (list + (list) + (list int-example-list int-example-list int-example-list int-example-list bool-example-list) + (list int-example-list cstring-example-list int-example-list int-example-list int-example-list bool-example-list)) + (list 'get-underlined bool-example-list) + (list 'get-weight int-example-list) + (list 'get-point-size int-example-list) + (list 'get-style int-example-list) + (list 'get-font-id int-example-list) + (list 'get-family int-example-list))) +(hash-table-put! classinfo wx:font-list% + (list wxFontList!-example-list (quote wx:font-list%) + (list + (list)) + (list 'find-or-create-font wxFont!-example-list int-example-list cstring-example-list int-example-list int-example-list int-example-list bool-example-list) + (list 'find-or-create-font wxFont!-example-list int-example-list int-example-list int-example-list int-example-list bool-example-list))) +(hash-table-put! classinfo wx:colour% + (list wxColour!-example-list (quote wx:colour%) + (list + (list) + (list ubyte-example-list ubyte-example-list ubyte-example-list) + (list string-example-list)) + (list 'blue ubyte-example-list) + (list 'green ubyte-example-list) + (list 'red ubyte-example-list) + (list 'set void-example-list ubyte-example-list ubyte-example-list ubyte-example-list) + (list 'ok? bool-example-list) + (list 'get void-example-list ubyte*-example-list ubyte*-example-list ubyte*-example-list) + (list '= wxColour%-example-list wxColour%-example-list))) +(hash-table-put! classinfo wx:colour-map% + (list wxColourMap!-example-list (quote wx:colour-map%) + (list))) +(hash-table-put! classinfo wx:colour-database% + (list wxColourDatabase!-example-list (quote wx:colour-database%) + (list) + (list 'append void-example-list string-example-list wxColour!-example-list) + (list 'find-name string-example-list wxColour%-example-list) + (list 'find-colour wxColour^-example-list string-example-list))) +(hash-table-put! classinfo wx:point% + (list wxPoint!-example-list (quote wx:point%) + (list + (list) + (list float-example-list float-example-list)) + (list 'get-x float-example-list) + (list 'set-x void-example-list float-example-list) + (list 'get-y float-example-list) + (list 'set-y void-example-list float-example-list))) +(hash-table-put! classinfo wx:int-point% + (list wxIntPoint!-example-list (quote wx:int-point%) + (list + (list) + (list int-example-list int-example-list)) + (list 'get-x int-example-list) + (list 'set-x void-example-list int-example-list) + (list 'get-y int-example-list) + (list 'set-y void-example-list int-example-list))) +(hash-table-put! classinfo wx:brush% + (list wxBrush!-example-list (quote wx:brush%) + (list + (list) + (list wxColour%-example-list int-example-list) + (list string-example-list int-example-list)) + (list 'set-style void-example-list int-example-list) + (list 'get-style int-example-list) + (list 'set-stipple void-example-list wxBitmap^-example-list) + (list 'get-stipple wxBitmap!-example-list) + (list 'set-colour void-example-list int-example-list int-example-list int-example-list) + (list 'set-colour void-example-list string-example-list) + (list 'set-colour void-example-list wxColour%-example-list) + (list 'get-colour wxColour%-example-list))) +(hash-table-put! classinfo wx:brush-list% + (list wxBrushList!-example-list (quote wx:brush-list%) + (list + (list)) + (list 'find-or-create-brush wxBrush!-example-list string-example-list int-example-list) + (list 'find-or-create-brush wxBrush!-example-list wxColour!-example-list int-example-list))) +(hash-table-put! classinfo wx:pen% + (list wxPen!-example-list (quote wx:pen%) + (list + (list) + (list wxColour%-example-list int-example-list int-example-list) + (list string-example-list int-example-list int-example-list)) + (list 'set-style void-example-list int-example-list) + (list 'get-style int-example-list) + (list 'set-stipple void-example-list wxBitmap^-example-list) + (list 'get-stipple wxBitmap!-example-list) + (list 'set-colour void-example-list int-example-list int-example-list int-example-list) + (list 'set-colour void-example-list string-example-list) + (list 'set-colour void-example-list wxColour%-example-list) + (list 'get-colour wxColour%-example-list) + (list 'set-join void-example-list int-example-list) + (list 'get-join int-example-list) + (list 'set-cap void-example-list int-example-list) + (list 'get-cap int-example-list) + (list 'set-width void-example-list int-example-list) + (list 'get-width int-example-list))) +(hash-table-put! classinfo wx:pen-list% + (list wxPenList!-example-list (quote wx:pen-list%) + (list + (list)) + (list 'find-or-create-pen wxPen!-example-list string-example-list int-example-list int-example-list) + (list 'find-or-create-pen wxPen!-example-list wxColour!-example-list int-example-list int-example-list))) +(hash-table-put! classinfo wx:cursor% + (list wxCursor!-example-list (quote wx:cursor%) + (list + (list string-example-list long-example-list int-example-list int-example-list) + (list int-example-list)) + (list 'ok? bool-example-list))) +(hash-table-put! classinfo wx:icon% + (list wxIcon!-example-list (quote wx:icon%) + (list + (list string-example-list int-example-list)))) +(hash-table-put! classinfo wx:font-name-directory% + (list wxFontNameDirectory!-example-list (quote wx:font-name-directory%) + (list) + (list 'find-or-create-font-id int-example-list cstring-example-list int-example-list) + (list 'get-family int-example-list int-example-list) + (list 'get-font-name nstring-example-list int-example-list) + (list 'get-font-id int-example-list string-example-list) + (list 'initialize void-example-list int-example-list int-example-list string-example-list) + (list 'get-new-font-id int-example-list) + (list 'get-afm-name nstring-example-list int-example-list int-example-list int-example-list) + (list 'get-post-script-name nstring-example-list int-example-list int-example-list int-example-list) + (list 'get-screen-name nstring-example-list int-example-list int-example-list int-example-list))) +(hash-table-put! classinfo 'wxsGlobal + (list #f (quote 'wxsGlobal) + (list) + (list 'wx:flush-display void-example-list) + (list 'wx:yield bool-example-list voidARRAY-example-list) + (list 'wx:get-resource bool-example-list string-example-list string-example-list long*-example-list nstring-example-list) + (list 'wx:get-resource bool-example-list string-example-list string-example-list string*-example-list nstring-example-list) + (list 'wx:get-free-memory long-example-list) + (list 'wx:strip-menu-codes string-example-list string-example-list) + (list 'wx:find-window-by-name wxWindow^-example-list string-example-list wxWindow^-example-list) + (list 'wx:find-window-by-label wxWindow^-example-list string-example-list wxWindow^-example-list) + (list 'wx:display-size void-example-list int*-example-list int*-example-list) + (list 'wx:bell void-example-list) + (list 'wx:end-busy-cursor void-example-list) + (list 'wx:is-busy? bool-example-list) + (list 'wx:begin-busy-cursor void-example-list wxCursor!-example-list) + (list 'wx:register-id void-example-list long-example-list) + (list 'wx:new-id long-example-list) + (list 'wx:set-post-script-level-2 void-example-list bool-example-list) + (list 'wx:set-afm-path void-example-list nstring-example-list) + (list 'wx:set-print-paper-name void-example-list nstring-example-list) + (list 'wx:set-printer-translation void-example-list float-example-list float-example-list) + (list 'wx:set-printer-scaling void-example-list float-example-list float-example-list) + (list 'wx:set-printer-options void-example-list string-example-list) + (list 'wx:set-printer-orientation void-example-list int-example-list) + (list 'wx:set-printer-mode void-example-list int-example-list) + (list 'wx:set-printer-preview-command void-example-list string-example-list) + (list 'wx:set-printer-file void-example-list pathname-example-list) + (list 'wx:set-printer-command void-example-list string-example-list) + (list 'wx:get-post-script-level-2 bool-example-list) + (list 'wx:get-afm-path nstring-example-list) + (list 'wx:get-print-paper-name nstring-example-list) + (list 'wx:get-printer-translation void-example-list float*-example-list float*-example-list) + (list 'wx:get-printer-scaling void-example-list float*-example-list float*-example-list) + (list 'wx:get-printer-options string-example-list) + (list 'wx:get-printer-orientation int-example-list) + (list 'wx:get-printer-mode int-example-list) + (list 'wx:get-printer-preview-command string-example-list) + (list 'wx:get-printer-file string-example-list) + (list 'wx:get-printer-command string-example-list) + (list 'wx:set-cursor void-example-list wxCursor!-example-list) + (list 'wx:make-meta-file-placeable bool-example-list string-example-list float-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'wx:display-depth int-example-list) + (list 'wx:colour-display? bool-example-list) + (list 'wx:get-single-choice-data string-example-list string-example-list string-example-list stringARRAY-example-list stringARRAY-example-list wxWindow^-example-list int-example-list int-example-list bool-example-list int-example-list int-example-list) + (list 'wx:get-single-choice-index int-example-list string-example-list string-example-list stringARRAY-example-list wxWindow^-example-list int-example-list int-example-list bool-example-list int-example-list int-example-list) + (list 'wx:get-single-choice string-example-list string-example-list string-example-list stringARRAY-example-list wxWindow^-example-list int-example-list int-example-list bool-example-list int-example-list int-example-list) + (list 'wx:get-multiple-choice int-example-list string-example-list string-example-list stringARRAY-example-list int-example-list intARRAY-example-list wxWindow^-example-list int-example-list int-example-list bool-example-list int-example-list int-example-list) + (list 'wx:get-text-from-user string-example-list string-example-list string-example-list string-example-list wxWindow^-example-list int-example-list int-example-list bool-example-list) + (list 'wx:message-box int-example-list string-example-list string-example-list int-example-list wxWindow^-example-list int-example-list int-example-list) + (list 'wx:file-selector string-example-list string-example-list nstring-example-list nstring-example-list nstring-example-list string-example-list int-example-list wxWindow^-example-list int-example-list int-example-list) + (list 'wx:get-display-name nstring-example-list) + (list 'wx:set-display bool-example-list nstring-example-list) + (list 'wx:string-match? bool-example-list string-example-list string-example-list bool-example-list bool-example-list) + (list 'wx:get-user-name nstring-example-list) + (list 'wx:get-user-id nstring-example-list) + (list 'wx:get-email-address nstring-example-list) + (list 'wx:get-host-name nstring-example-list) + (list 'wx:get-temp-file-name string-example-list string-example-list))) +(hash-table-put! classinfo wx:item% + (list wxItem!-example-list (quote wx:item%) + (list) + (list 'set-button-colour void-example-list wxColour!-example-list) + (list 'set-label-colour void-example-list wxColour!-example-list) + (list 'set-background-colour void-example-list wxColour!-example-list) + (list 'get-char-width float-example-list) + (list 'get-char-height float-example-list) + (list 'set-label void-example-list string-example-list) + (list 'get-label nstring-example-list) + (list 'set-background-colour void-example-list wxColour!-example-list) + (list 'get-background-colour wxColour!-example-list) + (list 'set-label-colour void-example-list wxColour!-example-list) + (list 'get-label-colour wxColour!-example-list) + (list 'set-button-colour void-example-list wxColour!-example-list) + (list 'get-button-colour wxColour!-example-list) + (list 'command void-example-list wxCommandEvent%-example-list))) +(hash-table-put! classinfo wx:message% + (list wxMessage!-example-list (quote wx:message%) + (list + (list wxPanel!-example-list string-example-list int-example-list int-example-list long-example-list string-example-list) + (list wxPanel!-example-list wxBitmap!-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'set-label void-example-list string-example-list) + (list 'set-label void-example-list wxBitmap!-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list))) +(hash-table-put! classinfo wx:list-box% + (list wxListBox!-example-list (quote wx:list-box%) + (list + (list wxPanel!-example-list wxFunction-example-list nstring-example-list Bool-example-list int-example-list int-example-list int-example-list int-example-list stringARRAY-example-list long-example-list string-example-list)) + (list 'set-string void-example-list int-example-list string-example-list) + (list 'get-string string-example-list int-example-list) + (list 'set-string-selection void-example-list string-example-list) + (list 'set-first-item void-example-list string-example-list) + (list 'set-first-item void-example-list int-example-list) + (list 'set void-example-list stringARRAY-example-list) + (list 'get-selections int-example-list int**-example-list) + (list 'number int-example-list) + (list 'get-selection int-example-list) + (list 'find-string int-example-list string-example-list) + (list 'set-client-data void-example-list int-example-list string-example-list) + (list 'get-client-data string-example-list int-example-list) + (list 'get-string-selection string-example-list) + (list 'selected? bool-example-list int-example-list) + (list 'set-selection void-example-list int-example-list bool-example-list) + (list 'deselect void-example-list int-example-list) + (list 'delete void-example-list int-example-list) + (list 'clear void-example-list) + (list 'append void-example-list string-example-list string-example-list) + (list 'append void-example-list string-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list))) +(hash-table-put! classinfo wx:media-canvas% + (list wxMediaCanvas!-example-list (quote wx:media-canvas%) + (list + (list wxFrame!-example-list int-example-list int-example-list int-example-list int-example-list string-example-list long-example-list int-example-list wxMediaBuffer^-example-list) + (list wxPanel!-example-list int-example-list int-example-list int-example-list int-example-list string-example-list long-example-list int-example-list wxMediaBuffer^-example-list)) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxMouseEvent%-example-list) + (list 'on-paint void-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list) + (list 'call-as-primary-owner voidARRAY-example-list CAPOFunc-example-list) + (list 'set-lazy-refresh void-example-list bool-example-list) + (list 'get-lazy-refresh bool-example-list) + (list 'scroll-with-bottom-base void-example-list bool-example-list) + (list 'allow-scroll-to-last void-example-list bool-example-list) + (list 'force-display-focus void-example-list bool-example-list) + (list 'is-focus-on? bool-example-list) + (list 'on-kill-focus void-example-list) + (list 'on-set-focus void-example-list) + (list 'get-media wxMediaBuffer^-example-list) + (list 'set-media void-example-list wxMediaBuffer^-example-list bool-example-list))) +(hash-table-put! classinfo wx:media-admin% + (list wxMediaAdmin!-example-list (quote wx:media-admin%) + (list + (list)) + (list 'set-cursor void-example-list wxCursor!-example-list) + (list 'needs-update void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'resized void-example-list bool-example-list) + (list 'grab-caret void-example-list int-example-list) + (list 'scroll-to bool-example-list float-example-list float-example-list float-example-list float-example-list bool-example-list int-example-list) + (list 'get-view void-example-list float?-example-list float?-example-list float?-example-list float?-example-list bool-example-list) + (list 'get-dc wxDC^-example-list float?-example-list float?-example-list))) +(hash-table-put! classinfo wx:canvas-media-admin% + (list wxCanvasMediaAdmin!-example-list (quote wx:canvas-media-admin%) + (list) + (list 'get-canvas wxMediaCanvas!-example-list))) +(hash-table-put! classinfo wx:media-snip-media-admin% + (list wxMediaSnipMediaAdmin!-example-list (quote wx:media-snip-media-admin%) + (list) + (list 'get-snip wxMediaSnip!-example-list))) +(hash-table-put! classinfo wx:snip-admin% + (list wxSnipAdmin!-example-list (quote wx:snip-admin%) + (list + (list)) + (list 'set-cursor void-example-list wxCursor!-example-list) + (list 'release-snip bool-example-list wxSnip!-example-list) + (list 'needs-update void-example-list wxSnip!-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'recounted bool-example-list wxSnip!-example-list bool-example-list) + (list 'resized void-example-list wxSnip!-example-list bool-example-list) + (list 'set-caret-owner void-example-list wxSnip!-example-list int-example-list) + (list 'scroll-to bool-example-list wxSnip!-example-list float-example-list float-example-list float-example-list float-example-list bool-example-list int-example-list) + (list 'get-view void-example-list float?-example-list float?-example-list float?-example-list float?-example-list wxSnip^-example-list) + (list 'get-view-size void-example-list float?-example-list float?-example-list) + (list 'get-dc wxDC!-example-list) + (list 'get-media wxMediaBuffer^-example-list))) +(hash-table-put! classinfo wx:snip-class% + (list wxSnipClass!-example-list (quote wx:snip-class%) + (list + (list)) + (list 'write-done void-example-list) + (list 'write-header bool-example-list wxMediaStreamOut%-example-list) + (list 'read-done void-example-list) + (list 'read-header bool-example-list wxMediaStreamIn%-example-list) + (list 'read wxSnip^-example-list wxMediaStreamIn%-example-list) + (list 'get-classname string-example-list) + (list 'set-classname void-example-list string-example-list) + (list 'get-version int-example-list) + (list 'set-version void-example-list int-example-list))) +(hash-table-put! classinfo wx:snip-class-list% + (list wxSnipClassList!-example-list (quote wx:snip-class-list%) + (list) + (list 'nth wxSnipClass^-example-list int-example-list) + (list 'number int-example-list) + (list 'add void-example-list wxSnipClass!-example-list) + (list 'find-position short-example-list wxSnipClass!-example-list) + (list 'find wxSnipClass^-example-list string-example-list))) +(hash-table-put! classinfo wx:keymap% + (list wxKeymap!-example-list (quote wx:keymap%) + (list + (list)) + (list 'remove-chained-keymap void-example-list wxKeymap!-example-list) + (list 'chain-to-keymap void-example-list wxKeymap!-example-list bool-example-list) + (list 'set-break-sequence-callback void-example-list wxBreakSequenceFunction-example-list) + (list 'set-error-callback void-example-list wxKeyErrorFunction-example-list) + (list 'call-function bool-example-list string-example-list wxObject!-example-list wxMouseEvent%-example-list bool-example-list) + (list 'call-function bool-example-list string-example-list wxObject!-example-list wxKeyEvent%-example-list bool-example-list) + (list 'remove-grab-mouse-function void-example-list) + (list 'set-grab-mouse-function void-example-list wxGrabMouseFunction-example-list) + (list 'add-mouse-function void-example-list string-example-list wxMouseFunction-example-list) + (list 'remove-grab-key-function void-example-list) + (list 'set-grab-key-function void-example-list wxGrabKeyFunction-example-list) + (list 'add-key-function void-example-list string-example-list wxKeyFunction-example-list) + (list 'implies-shift void-example-list string-example-list) + (list 'map-function void-example-list string-example-list string-example-list) + (list 'break-sequence void-example-list) + (list 'handle-mouse-event bool-example-list wxObject!-example-list wxMouseEvent%-example-list) + (list 'handle-key-event bool-example-list wxObject!-example-list wxKeyEvent%-example-list) + (list 'set-double-click-interval void-example-list long-example-list) + (list 'get-double-click-interval long-example-list))) +(hash-table-put! classinfo wx:media-wordbreak-map% + (list wxMediaWordbreakMap!-example-list (quote wx:media-wordbreak-map%) + (list + (list)) + (list 'is-used? bool-example-list) + (list 'adjust-usage void-example-list bool-example-list) + (list 'get-map int-example-list int-example-list) + (list 'set-map void-example-list int-example-list int-example-list))) +(hash-table-put! classinfo wx:media-edit% + (list wxMediaEdit!-example-list (quote wx:media-edit%) + (list + (list float-example-list floatARRAY-example-list)) + (list 'remove-clickback void-example-list long-example-list long-example-list) + (list 'set-clickback void-example-list long-example-list long-example-list wxClickbackFunc-example-list wxStyleDelta^-example-list bool-example-list) + (list 'set-wordbreak-func void-example-list wxWordbreakFunc-example-list) + (list 'set-autowrap-bitmap wxBitmap^-example-list wxBitmap^-example-list) + (list 'on-new-tab-snip wxTabSnip!-example-list) + (list 'on-new-text-snip wxTextSnip!-example-list) + (list 'caret-hidden? bool-example-list) + (list 'hide-caret void-example-list bool-example-list) + (list 'get-wordbreak-map wxMediaWordbreakMap^-example-list) + (list 'set-wordbreak-map void-example-list wxMediaWordbreakMap^-example-list) + (list 'find-wordbreak void-example-list long?-example-list long?-example-list int-example-list) + (list 'set-region-data void-example-list long-example-list long-example-list wxBufferData^-example-list) + (list 'get-region-data wxBufferData^-example-list long-example-list long-example-list) + (list 'after-set-size-constraint void-example-list) + (list 'on-set-size-constraint bool-example-list) + (list 'after-set-position void-example-list) + (list 'after-edit-sequence void-example-list) + (list 'on-edit-sequence void-example-list) + (list 'after-change-style void-example-list long-example-list long-example-list) + (list 'on-change-style bool-example-list long-example-list long-example-list) + (list 'after-delete void-example-list long-example-list long-example-list) + (list 'on-delete bool-example-list long-example-list long-example-list) + (list 'after-insert void-example-list long-example-list long-example-list) + (list 'on-insert bool-example-list long-example-list long-example-list) + (list 'add-editor-functions void-example-list wxKeymap!-example-list) + (list 'set-tabs void-example-list floatARRAY-example-list float-example-list bool-example-list) + (list 'get-tabs floatARRAY-example-list int?-example-list float?-example-list bool?-example-list) + (list 'set-overwrite-mode void-example-list bool-example-list) + (list 'get-overwrite-mode bool-example-list) + (list 'set-file-format void-example-list int-example-list) + (list 'get-file-format int-example-list) + (list 'write-to-file bool-example-list wxMediaStreamOut%-example-list long-example-list long-example-list) + (list 'read-from-file bool-example-list wxMediaStreamIn%-example-list long-example-list bool-example-list) + (list 'insert-file bool-example-list string-example-list int-example-list) + (list 'load-file bool-example-list nstring-example-list int-example-list) + (list 'get-character uchar-example-list long-example-list) + (list 'get-text string-example-list long-example-list long-example-list bool-example-list bool-example-list) + (list 'get-snip-position long-example-list wxSnip!-example-list) + (list 'get-snip-position-and-location void-example-list wxSnip!-example-list long?-example-list float?-example-list float?-example-list) + (list 'find-snip wxSnip^-example-list long-example-list int-example-list long?-example-list) + (list 'find-string-all longARRAY-example-list string-example-list int-example-list long-example-list long-example-list bool-example-list bool-example-list) + (list 'find-string long-example-list string-example-list int-example-list long-example-list long-example-list bool-example-list bool-example-list) + (list 'last-paragraph long-example-list) + (list 'pargraph-end-line long-example-list long-example-list) + (list 'paragraph-start-line long-example-list long-example-list) + (list 'line-paragraph long-example-list long-example-list) + (list 'paragraph-end-position long-example-list long-example-list bool-example-list) + (list 'paragraph-start-position long-example-list long-example-list bool-example-list) + (list 'position-paragraph long-example-list long-example-list bool-example-list) + (list 'last-line long-example-list) + (list 'last-position long-example-list) + (list 'line-length long-example-list long-example-list) + (list 'line-end-position long-example-list long-example-list bool-example-list) + (list 'line-start-position long-example-list long-example-list bool-example-list) + (list 'line-location float-example-list long-example-list bool-example-list) + (list 'position-location void-example-list long-example-list float?-example-list float?-example-list bool-example-list bool-example-list bool-example-list) + (list 'position-line long-example-list long-example-list bool-example-list) + (list 'set-cursor void-example-list wxCursor^-example-list) + (list 'set-between-threshold void-example-list float-example-list) + (list 'get-between-threshold float-example-list) + (list 'find-position-in-line long-example-list long-example-list float-example-list bool?-example-list bool?-example-list float?-example-list) + (list 'find-line long-example-list float-example-list bool?-example-list) + (list 'find-position long-example-list float-example-list float-example-list bool?-example-list bool?-example-list float?-example-list) + (list 'split-snip void-example-list long-example-list) + (list 'change-style void-example-list wxStyle^-example-list long-example-list long-example-list) + (list 'change-style void-example-list wxStyleDelta^-example-list long-example-list long-example-list) + (list 'do-paste void-example-list long-example-list long-example-list) + (list 'do-copy void-example-list long-example-list long-example-list long-example-list bool-example-list) + (list 'kill void-example-list long-example-list long-example-list long-example-list) + (list 'paste-next void-example-list) + (list 'paste void-example-list long-example-list long-example-list long-example-list) + (list 'copy void-example-list bool-example-list long-example-list long-example-list long-example-list) + (list 'cut void-example-list bool-example-list long-example-list long-example-list long-example-list) + (list 'erase void-example-list) + (list 'delete void-example-list) + (list 'delete void-example-list long-example-list long-example-list bool-example-list) + (list 'insert void-example-list uchar-example-list long-example-list long-example-list) + (list 'insert void-example-list uchar-example-list) + (list 'insert void-example-list wxSnip!-example-list long-example-list long-example-list bool-example-list) + (list 'insert void-example-list long-example-list string-example-list) + (list 'insert void-example-list long-example-list string-example-list long-example-list long-example-list bool-example-list) + (list 'insert void-example-list string-example-list) + (list 'insert void-example-list string-example-list long-example-list long-example-list bool-example-list) + (list 'flash-off void-example-list) + (list 'flash-on void-example-list long-example-list long-example-list bool-example-list bool-example-list long-example-list) + (list 'get-anchor bool-example-list) + (list 'set-anchor void-example-list bool-example-list) + (list 'get-visible-line-range void-example-list long?-example-list long?-example-list) + (list 'get-visible-position-range void-example-list long?-example-list long?-example-list) + (list 'scroll-to-position bool-example-list long-example-list bool-example-list long-example-list int-example-list) + (list 'move-position void-example-list long-example-list bool-example-list int-example-list) + (list 'set-position-bias-scroll void-example-list int-example-list long-example-list long-example-list bool-example-list bool-example-list int-example-list) + (list 'set-position void-example-list long-example-list long-example-list bool-example-list bool-example-list int-example-list) + (list 'get-end-position long-example-list) + (list 'get-start-position long-example-list) + (list 'get-position void-example-list long?-example-list long?-example-list) + (list 'get-flattened-text string-example-list) + (list 'after-load-file void-example-list bool-example-list) + (list 'on-load-file bool-example-list string-example-list int-example-list) + (list 'after-save-file void-example-list bool-example-list) + (list 'on-save-file bool-example-list string-example-list int-example-list) + (list 'on-new-box wxSnip!-example-list int-example-list) + (list 'on-new-image-snip wxImageSnip!-example-list nstring-example-list long-example-list bool-example-list bool-example-list) + (list 'invalidate-bitmap-cache void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'on-paint void-example-list bool-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list int-example-list) + (list 'write-footers-to-file bool-example-list wxMediaStreamOut%-example-list) + (list 'write-headers-to-file bool-example-list wxMediaStreamOut%-example-list) + (list 'read-footer-from-file bool-example-list wxMediaStreamIn%-example-list string-example-list) + (list 'read-header-from-file bool-example-list wxMediaStreamIn%-example-list string-example-list) + (list 'write-to-file bool-example-list wxMediaStreamOut%-example-list) + (list 'read-from-file bool-example-list wxMediaStreamIn%-example-list bool-example-list) + (list 'set-filename void-example-list string-example-list bool-example-list) + (list 'release-snip bool-example-list wxSnip!-example-list) + (list 'set-modified void-example-list bool-example-list) + (list 'set-snip-data void-example-list wxSnip!-example-list wxBufferData^-example-list) + (list 'get-snip-data wxBufferData^-example-list wxSnip!-example-list) + (list 'needs-update void-example-list wxSnip!-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'resized void-example-list wxSnip!-example-list bool-example-list) + (list 'set-caret-owner void-example-list wxSnip^-example-list int-example-list) + (list 'scroll-to bool-example-list wxSnip!-example-list float-example-list float-example-list float-example-list float-example-list bool-example-list) + (list 'on-change void-example-list) + (list 'on-focus void-example-list bool-example-list) + (list 'on-default-char void-example-list wxKeyEvent%-example-list) + (list 'on-default-event void-example-list wxMouseEvent%-example-list) + (list 'on-local-char void-example-list wxKeyEvent%-example-list) + (list 'on-local-event void-example-list wxMouseEvent%-example-list) + (list 'size-cache-invalid void-example-list) + (list 'own-caret void-example-list bool-example-list) + (list 'refresh void-example-list float-example-list float-example-list float-example-list float-example-list bool-example-list) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxMouseEvent%-example-list) + (list 'kill void-example-list long-example-list) + (list 'paste void-example-list long-example-list) + (list 'copy void-example-list bool-example-list long-example-list) + (list 'cut void-example-list bool-example-list long-example-list) + (list 'insert void-example-list wxSnip!-example-list) + (list 'change-style void-example-list wxStyleDelta^-example-list))) +(hash-table-put! classinfo wx:media-buffer% + (list wxMediaBuffer!-example-list (quote wx:media-buffer%) + (list) + (list 'dc-location-to-buffer-location void*-example-list double-example-list double-example-list) + (list 'buffer-location-to-dc-location void*-example-list double-example-list double-example-list) + (list 'set-inactive-caret-threshold void-example-list int-example-list) + (list 'get-inactive-caret-threshold int-example-list) + (list 'get-focus-snip wxSnip^-example-list) + (list 'end-write-header-footer-to-file bool-example-list wxMediaStreamOut%-example-list long-example-list) + (list 'begin-write-header-footer-to-file bool-example-list wxMediaStreamOut%-example-list string-example-list long*-example-list) + (list 'print void-example-list nstring-example-list bool-example-list bool-example-list int-example-list) + (list 'insert-image void-example-list nstring-example-list long-example-list bool-example-list bool-example-list) + (list 'insert-box void-example-list int-example-list) + (list 'get-filename nstring-example-list bool?-example-list) + (list 'modified? bool-example-list) + (list 'lock void-example-list bool-example-list) + (list 'get-load-overwrites-styles bool-example-list) + (list 'set-load-overwrites-styles void-example-list bool-example-list) + (list 'set-style-list void-example-list wxStyleList!-example-list) + (list 'get-style-list wxStyleList!-example-list) + (list 'add-buffer-functions void-example-list wxKeymap!-example-list) + (list 'get-keymap wxKeymap!-example-list) + (list 'set-keymap void-example-list wxKeymap^-example-list) + (list 'do-font void-example-list int-example-list bool-example-list) + (list 'do-edit void-example-list int-example-list bool-example-list long-example-list) + (list 'append-font-items int-example-list wxMenu!-example-list int-example-list) + (list 'append-edit-items int-example-list wxMenu!-example-list int-example-list) + (list 'get-max-undo-history int-example-list) + (list 'set-max-undo-history void-example-list int-example-list) + (list 'clear-undos void-example-list) + (list 'redo void-example-list) + (list 'undo void-example-list) + (list 'select-all void-example-list) + (list 'clear void-example-list) + (list 'get-view-size void-example-list float?-example-list float?-example-list) + (list 'get-dc wxDC!-example-list) + (list 'local-to-global void-example-list float*-example-list float*-example-list) + (list 'global-to-local void-example-list float*-example-list float*-example-list) + (list 'set-admin void-example-list wxMediaAdmin^-example-list) + (list 'get-admin wxMediaAdmin^-example-list) + (list 'print-to-dc void-example-list wxDC!-example-list) + (list 'find-scroll-line long-example-list float-example-list) + (list 'num-scroll-lines long-example-list) + (list 'scroll-line-location float-example-list long-example-list) + (list 'get-snip-location bool-example-list wxSnip!-example-list float?-example-list float?-example-list bool-example-list) + (list 'end-edit-sequence void-example-list) + (list 'begin-edit-sequence void-example-list bool-example-list) + (list 'style-has-changed void-example-list wxStyle^-example-list) + (list 'write-to-file bool-example-list wxMediaStreamOut%-example-list) + (list 'read-from-file bool-example-list wxMediaStreamIn%-example-list) + (list 'set-min-height void-example-list float-example-list) + (list 'set-max-height void-example-list float-example-list) + (list 'get-min-height float-example-list) + (list 'get-max-height float-example-list) + (list 'set-min-width void-example-list float-example-list) + (list 'set-max-width void-example-list float-example-list) + (list 'get-min-width float-example-list) + (list 'get-max-width float-example-list) + (list 'get-space float-example-list) + (list 'get-descent float-example-list) + (list 'get-extent void-example-list float?-example-list float?-example-list) + (list 'copy-self wxMediaBuffer!-example-list) + (list 'get-flattened-text string-example-list) + (list 'after-load-file void-example-list bool-example-list) + (list 'on-load-file bool-example-list string-example-list int-example-list) + (list 'after-save-file void-example-list bool-example-list) + (list 'on-save-file bool-example-list string-example-list int-example-list) + (list 'on-new-box wxSnip!-example-list int-example-list) + (list 'on-new-image-snip wxImageSnip!-example-list nstring-example-list long-example-list bool-example-list bool-example-list) + (list 'invalidate-bitmap-cache void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'on-paint void-example-list bool-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list int-example-list) + (list 'write-footers-to-file bool-example-list wxMediaStreamOut%-example-list) + (list 'write-headers-to-file bool-example-list wxMediaStreamOut%-example-list) + (list 'read-footer-from-file bool-example-list wxMediaStreamIn%-example-list string-example-list) + (list 'read-header-from-file bool-example-list wxMediaStreamIn%-example-list string-example-list) + (list 'write-to-file bool-example-list wxMediaStreamOut%-example-list) + (list 'read-from-file bool-example-list wxMediaStreamIn%-example-list bool-example-list) + (list 'set-filename void-example-list string-example-list bool-example-list) + (list 'release-snip bool-example-list wxSnip!-example-list) + (list 'set-modified void-example-list bool-example-list) + (list 'set-snip-data void-example-list wxSnip!-example-list wxBufferData^-example-list) + (list 'get-snip-data wxBufferData^-example-list wxSnip!-example-list) + (list 'needs-update void-example-list wxSnip!-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'resized void-example-list wxSnip!-example-list bool-example-list) + (list 'set-caret-owner void-example-list wxSnip^-example-list int-example-list) + (list 'scroll-to bool-example-list wxSnip!-example-list float-example-list float-example-list float-example-list float-example-list bool-example-list) + (list 'on-change void-example-list) + (list 'on-focus void-example-list bool-example-list) + (list 'on-default-char void-example-list wxKeyEvent%-example-list) + (list 'on-default-event void-example-list wxMouseEvent%-example-list) + (list 'on-local-char void-example-list wxKeyEvent%-example-list) + (list 'on-local-event void-example-list wxMouseEvent%-example-list) + (list 'size-cache-invalid void-example-list) + (list 'own-caret void-example-list bool-example-list) + (list 'refresh void-example-list float-example-list float-example-list float-example-list float-example-list bool-example-list) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxMouseEvent%-example-list) + (list 'kill void-example-list long-example-list) + (list 'paste void-example-list long-example-list) + (list 'copy void-example-list bool-example-list long-example-list) + (list 'cut void-example-list bool-example-list long-example-list) + (list 'insert void-example-list wxSnip!-example-list) + (list 'change-style void-example-list wxStyleDelta^-example-list) + (list 'get-buffer-type int-example-list) + (list 'set-buffer-type void-example-list int-example-list))) +(hash-table-put! classinfo 'wxMediaGlobal + (list #f (quote 'wxMediaGlobal) + (list) + (list 'wx:get-the-buffer-data-class-list wxBufferDataClassList!-example-list) + (list 'wx:get-the-snip-class-list wxSnipClassList!-example-list) + (list 'wx:media-set-x-selection-mode void-example-list bool-example-list) + (list 'wx:add-media-pasteboard-functions void-example-list wxKeymap!-example-list) + (list 'wx:add-media-editor-functions void-example-list wxKeymap!-example-list) + (list 'wx:add-media-buffer-functions void-example-list wxKeymap!-example-list) + (list 'wx:write-media-global-footer bool-example-list wxMediaStreamOut%-example-list) + (list 'wx:write-media-global-header bool-example-list wxMediaStreamOut%-example-list) + (list 'wx:read-media-global-footer bool-example-list wxMediaStreamIn%-example-list) + (list 'wx:read-media-global-header bool-example-list wxMediaStreamIn%-example-list) + (list 'wx:set-media-print-margin void-example-list long-example-list long-example-list) + (list 'wx:get-media-print-margin void-example-list long?-example-list long?-example-list))) +(hash-table-put! classinfo wx:menu% + (list wxMenu!-example-list (quote wx:menu%) + (list + (list nstring-example-list wxFunction-example-list)) + (list 'set-title void-example-list string-example-list) + (list 'set-label void-example-list int-example-list string-example-list) + (list 'set-help-string void-example-list int-example-list nstring-example-list) + (list 'get-title nstring-example-list) + (list 'get-label nstring-example-list int-example-list) + (list 'get-help-string nstring-example-list int-example-list) + (list 'find-item int-example-list string-example-list) + (list 'enable void-example-list int-example-list bool-example-list) + (list 'check void-example-list int-example-list bool-example-list) + (list 'checked? bool-example-list int-example-list) + (list 'append-separator void-example-list) + (list 'delete-by-position void-example-list int-example-list) + (list 'delete void-example-list int-example-list) + (list 'append void-example-list int-example-list string-example-list nstring-example-list bool-example-list) + (list 'append void-example-list int-example-list string-example-list wxMenu!-example-list nstring-example-list))) +(hash-table-put! classinfo wx:menu-bar% + (list wxMenuBar!-example-list (quote wx:menu-bar%) + (list + (list) + (list wxMenu*ARRAY-example-list stringARRAY-example-list)) + (list 'set-label-top void-example-list int-example-list string-example-list) + (list 'set-label void-example-list int-example-list string-example-list) + (list 'set-help-string void-example-list int-example-list nstring-example-list) + (list 'get-title nstring-example-list) + (list 'get-label-top nstring-example-list int-example-list) + (list 'get-label nstring-example-list int-example-list) + (list 'get-help-string nstring-example-list int-example-list) + (list 'find-menu-item int-example-list string-example-list string-example-list) + (list 'enable-top void-example-list int-example-list bool-example-list) + (list 'enable void-example-list int-example-list bool-example-list) + (list 'checked? bool-example-list int-example-list) + (list 'check void-example-list int-example-list bool-example-list) + (list 'delete void-example-list wxMenu!-example-list int-example-list) + (list 'append void-example-list wxMenu!-example-list string-example-list))) +(hash-table-put! classinfo wx:media-stream-in-base% + (list wxMediaStreamInBase!-example-list (quote wx:media-stream-in-base%) + (list + (list)) + (list 'read long-example-list charARRAY-example-list) + (list 'bad? bool-example-list) + (list 'skip void-example-list long-example-list) + (list 'seek void-example-list long-example-list) + (list 'tell long-example-list))) +(hash-table-put! classinfo wx:media-stream-out-base% + (list wxMediaStreamOutBase!-example-list (quote wx:media-stream-out-base%) + (list + (list)) + (list 'write void-example-list charARRAY-example-list) + (list 'bad? bool-example-list) + (list 'seek void-example-list long-example-list) + (list 'tell long-example-list))) +(hash-table-put! classinfo wx:media-stream-in-string-base% + (list wxMediaStreamInStringBase!-example-list (quote wx:media-stream-in-string-base%) + (list + (list string-example-list)))) +(hash-table-put! classinfo wx:media-stream-out-string-base% + (list wxMediaStreamOutStringBase!-example-list (quote wx:media-stream-out-string-base%) + (list + (list)) + (list 'get-string string-example-list))) +(hash-table-put! classinfo wx:media-stream-in% + (list wxMediaStreamIn!-example-list (quote wx:media-stream-in%) + (list + (list wxMediaStreamInBase%-example-list)) + (list 'ok? bool-example-list) + (list 'jump-to void-example-list long-example-list) + (list 'tell long-example-list) + (list 'skip void-example-list long-example-list) + (list 'remove-boundary void-example-list) + (list 'set-boundary void-example-list long-example-list) + (list '>> wxMediaStreamIn%-example-list Double+-example-list) + (list '>> wxMediaStreamIn%-example-list Long+-example-list) + (list 'get-inexact double-example-list) + (list 'get-exact long-example-list) + (list 'get-fixed wxMediaStreamIn%-example-list long+-example-list) + (list 'get-string nstring-example-list long?-example-list) + (list 'get wxMediaStreamIn%-example-list Double+-example-list) + (list 'get wxMediaStreamIn%-example-list Long+-example-list))) +(hash-table-put! classinfo wx:media-stream-out% + (list wxMediaStreamOut!-example-list (quote wx:media-stream-out%) + (list + (list wxMediaStreamOutBase%-example-list)) + (list 'ok? bool-example-list) + (list 'jump-to void-example-list long-example-list) + (list 'tell long-example-list) + (list '<< wxMediaStreamOut%-example-list Long-example-list) + (list '<< wxMediaStreamOut%-example-list Double-example-list) + (list '<< wxMediaStreamOut%-example-list string-example-list) + (list 'put-fixed wxMediaStreamOut%-example-list long-example-list) + (list 'put wxMediaStreamOut%-example-list Double-example-list) + (list 'put wxMediaStreamOut%-example-list Long-example-list) + (list 'put wxMediaStreamOut%-example-list string-example-list) + (list 'put wxMediaStreamOut%-example-list long-example-list string-example-list))) +(hash-table-put! classinfo wx:meta-file% + (list baseMetaFile!-example-list (quote wx:meta-file%) + (list) + (list 'set-clipboard bool-example-list int-example-list int-example-list) + (list 'play void-example-list wxDC!-example-list) + (list 'ok? bool-example-list))) +(hash-table-put! classinfo wx:timer% + (list wxTimer!-example-list (quote wx:timer%) + (list + (list)) + (list 'stop void-example-list) + (list 'start bool-example-list int-example-list bool-example-list) + (list 'notify void-example-list) + (list 'interval int-example-list))) +(hash-table-put! classinfo wx:clipboard% + (list wxClipboard!-example-list (quote wx:clipboard%) + (list) + (list 'get-clipboard-data nstring-example-list string-example-list long-example-list) + (list 'get-clipboard-string nstring-example-list long-example-list) + (list 'get-clipboard-client wxClipboardClient^-example-list) + (list 'set-clipboard-string void-example-list string-example-list long-example-list) + (list 'set-clipboard-client void-example-list wxClipboardClient!-example-list long-example-list))) +(hash-table-put! classinfo wx:clipboard-client% + (list wxClipboardClient!-example-list (quote wx:clipboard-client%) + (list + (list)) + (list 'get-types Scheme_Object*-example-list) + (list 'add-type void-example-list string-example-list) + (list 'get-data nstring-example-list string-example-list) + (list 'being-replaced void-example-list))) +(hash-table-put! classinfo wx:media-pasteboard% + (list wxMediaPasteboard!-example-list (quote wx:media-pasteboard%) + (list + (list)) + (list 'set-scroll-step void-example-list float-example-list) + (list 'get-scroll-step float-example-list) + (list 'set-selection-visible void-example-list bool-example-list) + (list 'get-selection-visible bool-example-list) + (list 'set-dragable void-example-list bool-example-list) + (list 'get-dragable bool-example-list) + (list 'after-interactive-resize void-example-list wxSnip!-example-list) + (list 'on-interactive-resize bool-example-list wxSnip!-example-list) + (list 'after-interactive-move void-example-list) + (list 'on-interactive-move bool-example-list) + (list 'interactive-adjust-resize void-example-list wxSnip!-example-list float*-example-list float*-example-list) + (list 'interactive-adjust-move void-example-list wxSnip!-example-list float*-example-list float*-example-list) + (list 'interactive-adjust-mouse void-example-list float*-example-list float*-example-list) + (list 'on-double-click void-example-list wxSnip!-example-list wxMouseEvent%-example-list) + (list 'after-select void-example-list wxSnip!-example-list bool-example-list) + (list 'on-select bool-example-list wxSnip!-example-list bool-example-list) + (list 'after-resize void-example-list wxSnip!-example-list float-example-list float-example-list bool-example-list) + (list 'on-resize bool-example-list wxSnip!-example-list float-example-list float-example-list) + (list 'after-move-to void-example-list wxSnip!-example-list float-example-list float-example-list bool-example-list) + (list 'on-move-to bool-example-list wxSnip!-example-list float-example-list float-example-list bool-example-list) + (list 'after-delete void-example-list wxSnip!-example-list) + (list 'on-delete bool-example-list wxSnip!-example-list) + (list 'after-insert void-example-list wxSnip!-example-list wxSnip^-example-list float-example-list float-example-list) + (list 'on-insert bool-example-list wxSnip!-example-list wxSnip^-example-list float-example-list float-example-list) + (list 'find-next-selected-snip wxSnip^-example-list wxSnip^-example-list) + (list 'is-selected? bool-example-list wxSnip^-example-list) + (list 'find-first-snip wxSnip^-example-list) + (list 'find-snip wxSnip^-example-list float-example-list float-example-list) + (list 'add-pasteboard-functions void-example-list wxKeymap!-example-list) + (list 'get-center void-example-list float*-example-list float*-example-list) + (list 'remove-selected void-example-list wxSnip!-example-list) + (list 'no-selected void-example-list) + (list 'add-selected void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'add-selected void-example-list wxSnip!-example-list) + (list 'set-selected void-example-list wxSnip!-example-list) + (list 'change-style void-example-list wxStyle^-example-list wxSnip^-example-list) + (list 'change-style void-example-list wxStyleDelta^-example-list wxSnip^-example-list) + (list 'set-after void-example-list wxSnip!-example-list wxSnip^-example-list) + (list 'set-before void-example-list wxSnip!-example-list wxSnip^-example-list) + (list 'lower void-example-list wxSnip!-example-list) + (list 'raise void-example-list wxSnip!-example-list) + (list 'load-file bool-example-list nstring-example-list) + (list 'resize bool-example-list wxSnip!-example-list float-example-list float-example-list) + (list 'move void-example-list float-example-list float-example-list) + (list 'move void-example-list wxSnip!-example-list float-example-list float-example-list) + (list 'move-to void-example-list wxSnip!-example-list float-example-list float-example-list) + (list 'remove void-example-list wxSnip!-example-list) + (list 'erase void-example-list) + (list 'do-paste void-example-list long-example-list) + (list 'do-copy void-example-list long-example-list bool-example-list) + (list 'delete void-example-list wxSnip!-example-list) + (list 'delete void-example-list) + (list 'insert void-example-list wxSnip!-example-list wxSnip^-example-list float-example-list float-example-list) + (list 'insert void-example-list wxSnip!-example-list wxSnip^-example-list) + (list 'insert void-example-list wxSnip!-example-list float-example-list float-example-list) + (list 'get-flattened-text string-example-list) + (list 'after-load-file void-example-list bool-example-list) + (list 'on-load-file bool-example-list string-example-list int-example-list) + (list 'after-save-file void-example-list bool-example-list) + (list 'on-save-file bool-example-list string-example-list int-example-list) + (list 'on-new-box wxSnip!-example-list int-example-list) + (list 'on-new-image-snip wxImageSnip!-example-list nstring-example-list long-example-list bool-example-list bool-example-list) + (list 'invalidate-bitmap-cache void-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'on-paint void-example-list bool-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list int-example-list) + (list 'write-footers-to-file bool-example-list wxMediaStreamOut%-example-list) + (list 'write-headers-to-file bool-example-list wxMediaStreamOut%-example-list) + (list 'read-footer-from-file bool-example-list wxMediaStreamIn%-example-list string-example-list) + (list 'read-header-from-file bool-example-list wxMediaStreamIn%-example-list string-example-list) + (list 'write-to-file bool-example-list wxMediaStreamOut%-example-list) + (list 'read-from-file bool-example-list wxMediaStreamIn%-example-list bool-example-list) + (list 'set-filename void-example-list string-example-list bool-example-list) + (list 'release-snip bool-example-list wxSnip!-example-list) + (list 'set-modified void-example-list bool-example-list) + (list 'set-snip-data void-example-list wxSnip!-example-list wxBufferData^-example-list) + (list 'get-snip-data wxBufferData^-example-list wxSnip!-example-list) + (list 'needs-update void-example-list wxSnip!-example-list float-example-list float-example-list float-example-list float-example-list) + (list 'resized void-example-list wxSnip!-example-list bool-example-list) + (list 'set-caret-owner void-example-list wxSnip^-example-list int-example-list) + (list 'scroll-to bool-example-list wxSnip!-example-list float-example-list float-example-list float-example-list float-example-list bool-example-list) + (list 'on-change void-example-list) + (list 'on-focus void-example-list bool-example-list) + (list 'on-default-char void-example-list wxKeyEvent%-example-list) + (list 'on-default-event void-example-list wxMouseEvent%-example-list) + (list 'on-local-char void-example-list wxKeyEvent%-example-list) + (list 'on-local-event void-example-list wxMouseEvent%-example-list) + (list 'size-cache-invalid void-example-list) + (list 'own-caret void-example-list bool-example-list) + (list 'refresh void-example-list float-example-list float-example-list float-example-list float-example-list bool-example-list) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxMouseEvent%-example-list) + (list 'kill void-example-list long-example-list) + (list 'paste void-example-list long-example-list) + (list 'copy void-example-list bool-example-list long-example-list) + (list 'cut void-example-list bool-example-list long-example-list) + (list 'insert void-example-list wxSnip!-example-list) + (list 'change-style void-example-list wxStyleDelta^-example-list))) +(hash-table-put! classinfo wx:object% + (list wxObject!-example-list (quote wx:object%) + (list + (list)))) +(hash-table-put! classinfo wx:panel% + (list wxPanel!-example-list (quote wx:panel%) + (list + (list wxFrame!-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list) + (list wxPanel!-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'get-child wxObject!-example-list int-example-list) + (list 'advance-cursor void-example-list wxWindow!-example-list) + (list 'tab void-example-list int-example-list) + (list 'tab void-example-list) + (list 'set-background-colour void-example-list wxColour!-example-list) + (list 'get-background-colour wxColour!-example-list) + (list 'set-label-colour void-example-list wxColour!-example-list) + (list 'get-label-colour wxColour!-example-list) + (list 'set-button-colour void-example-list wxColour!-example-list) + (list 'get-button-colour wxColour!-example-list) + (list 'get-label-font wxFont!-example-list) + (list 'set-label-font void-example-list wxFont!-example-list) + (list 'get-button-font wxFont!-example-list) + (list 'set-button-font void-example-list wxFont!-example-list) + (list 'get-panel-dc wxDC!-example-list) + (list 'new-line void-example-list int-example-list) + (list 'new-line void-example-list) + (list 'set-vertical-spacing void-example-list int-example-list) + (list 'set-horizontal-spacing void-example-list int-example-list) + (list 'get-vertical-spacing int-example-list) + (list 'get-horizontal-spacing int-example-list) + (list 'set-label-position void-example-list int-example-list) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxMouseEvent%-example-list) + (list 'on-paint void-example-list) + (list 'on-default-action void-example-list wxItem!-example-list) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxMouseEvent%-example-list) + (list 'on-paint void-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list) + (list 'set-item-cursor void-example-list int-example-list int-example-list) + (list 'get-item-cursor void-example-list int*-example-list int*-example-list) + (list 'get-default-item wxButton!-example-list) + (list 'fit void-example-list))) +(hash-table-put! classinfo wx:dialog-box% + (list wxDialogBox!-example-list (quote wx:dialog-box%) + (list + (list wxWindow^-example-list nstring-example-list bool-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'on-default-action void-example-list wxItem!-example-list) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxMouseEvent%-example-list) + (list 'on-paint void-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list) + (list 'on-close bool-example-list) + (list 'on-activate void-example-list bool-example-list))) +(hash-table-put! classinfo wx:radio-box% + (list wxRadioBox!-example-list (quote wx:radio-box%) + (list + (list wxPanel!-example-list wxFunction-example-list nstring-example-list int-example-list int-example-list int-example-list int-example-list stringARRAY-example-list int-example-list long-example-list string-example-list) + (list wxPanel!-example-list wxFunction-example-list nstring-example-list int-example-list int-example-list int-example-list int-example-list wxBitmap*ARRAY-example-list int-example-list long-example-list string-example-list)) + (list 'enable void-example-list bool-example-list) + (list 'enable void-example-list int-example-list bool-example-list) + (list 'get-string string-example-list int-example-list) + (list 'set-selection void-example-list int-example-list) + (list 'set-string-selection void-example-list string-example-list) + (list 'number int-example-list) + (list 'get-string-selection nstring-example-list) + (list 'get-selection int-example-list) + (list 'find-string int-example-list string-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list))) +(hash-table-put! classinfo wx:slider% + (list wxSlider!-example-list (quote wx:slider%) + (list + (list wxPanel!-example-list wxFunction-example-list nstring-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'set-value void-example-list int-example-list) + (list 'get-value int-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list))) +(hash-table-put! classinfo wx:snip% + (list wxSnip!-example-list (quote wx:snip%) + (list + (list)) + (list 'previous wxSnip^-example-list) + (list 'next wxSnip^-example-list) + (list 'set-admin void-example-list wxSnipAdmin^-example-list) + (list 'resize bool-example-list float-example-list float-example-list) + (list 'write void-example-list wxMediaStreamOut%-example-list) + (list 'match? bool-example-list wxSnip!-example-list) + (list 'do-font void-example-list int-example-list bool-example-list) + (list 'do-edit void-example-list int-example-list bool-example-list long-example-list) + (list 'own-caret void-example-list bool-example-list) + (list 'on-char void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list wxMouseEvent%-example-list) + (list 'size-cache-invalid void-example-list) + (list 'copy wxSnip!-example-list) + (list 'get-text string-example-list long-example-list long-example-list bool-example-list) + (list 'merge-with wxSnip!-example-list wxSnip!-example-list) + (list 'split void-example-list long-example-list wxSnip!*-example-list wxSnip!*-example-list) + (list 'draw void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list int-example-list) + (list 'partial-offset float-example-list wxDC!-example-list float-example-list float-example-list long-example-list) + (list 'get-extent void-example-list wxDC!-example-list float-example-list float-example-list float?-example-list float?-example-list float?-example-list float?-example-list float?-example-list float?-example-list) + (list 'release-from-owner bool-example-list) + (list 'is-owned? bool-example-list) + (list 'set-style void-example-list wxStyle!-example-list) + (list 'set-flags void-example-list long-example-list) + (list 'set-count void-example-list long-example-list) + (list 'get-admin wxSnipAdmin!-example-list) + (list 'get-count long-example-list) + (list 'get-flags long-example-list) + (list 'get-style wxStyle!-example-list) + (list 'get-snipclass wxSnipClass^-example-list) + (list 'set-snipclass void-example-list wxSnipClass^-example-list))) +(hash-table-put! classinfo wx:text-snip% + (list wxTextSnip!-example-list (quote wx:text-snip%) + (list + (list long-example-list)) + (list 'read void-example-list long-example-list wxMediaStreamIn%-example-list) + (list 'insert void-example-list string-example-list long-example-list long-example-list) + (list 'set-admin void-example-list wxSnipAdmin^-example-list) + (list 'resize bool-example-list float-example-list float-example-list) + (list 'write void-example-list wxMediaStreamOut%-example-list) + (list 'match? bool-example-list wxSnip!-example-list) + (list 'do-font void-example-list int-example-list bool-example-list) + (list 'do-edit void-example-list int-example-list bool-example-list long-example-list) + (list 'own-caret void-example-list bool-example-list) + (list 'on-char void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list wxMouseEvent%-example-list) + (list 'size-cache-invalid void-example-list) + (list 'copy wxSnip!-example-list) + (list 'get-text string-example-list long-example-list long-example-list bool-example-list) + (list 'merge-with wxSnip!-example-list wxSnip!-example-list) + (list 'split void-example-list long-example-list wxSnip!*-example-list wxSnip!*-example-list) + (list 'draw void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list int-example-list) + (list 'partial-offset float-example-list wxDC!-example-list float-example-list float-example-list long-example-list) + (list 'get-extent void-example-list wxDC!-example-list float-example-list float-example-list float?-example-list float?-example-list float?-example-list float?-example-list float?-example-list float?-example-list))) +(hash-table-put! classinfo wx:tab-snip% + (list wxTabSnip!-example-list (quote wx:tab-snip%) + (list + (list)) + (list 'set-admin void-example-list wxSnipAdmin^-example-list) + (list 'resize bool-example-list float-example-list float-example-list) + (list 'write void-example-list wxMediaStreamOut%-example-list) + (list 'match? bool-example-list wxSnip!-example-list) + (list 'do-font void-example-list int-example-list bool-example-list) + (list 'do-edit void-example-list int-example-list bool-example-list long-example-list) + (list 'own-caret void-example-list bool-example-list) + (list 'on-char void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list wxMouseEvent%-example-list) + (list 'size-cache-invalid void-example-list) + (list 'copy wxSnip!-example-list) + (list 'get-text string-example-list long-example-list long-example-list bool-example-list) + (list 'merge-with wxSnip!-example-list wxSnip!-example-list) + (list 'split void-example-list long-example-list wxSnip!*-example-list wxSnip!*-example-list) + (list 'draw void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list int-example-list) + (list 'partial-offset float-example-list wxDC!-example-list float-example-list float-example-list long-example-list) + (list 'get-extent void-example-list wxDC!-example-list float-example-list float-example-list float?-example-list float?-example-list float?-example-list float?-example-list float?-example-list float?-example-list))) +(hash-table-put! classinfo wx:image-snip% + (list wxImageSnip!-example-list (quote wx:image-snip%) + (list + (list nstring-example-list long-example-list bool-example-list bool-example-list)) + (list 'set-offset void-example-list float-example-list float-example-list) + (list 'set-bitmap void-example-list wxBitmap!-example-list) + (list 'get-filetype long-example-list) + (list 'get-filename nstring-example-list bool?-example-list) + (list 'load-file void-example-list nstring-example-list long-example-list bool-example-list bool-example-list) + (list 'set-admin void-example-list wxSnipAdmin^-example-list) + (list 'resize bool-example-list float-example-list float-example-list) + (list 'write void-example-list wxMediaStreamOut%-example-list) + (list 'match? bool-example-list wxSnip!-example-list) + (list 'do-font void-example-list int-example-list bool-example-list) + (list 'do-edit void-example-list int-example-list bool-example-list long-example-list) + (list 'own-caret void-example-list bool-example-list) + (list 'on-char void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list wxMouseEvent%-example-list) + (list 'size-cache-invalid void-example-list) + (list 'copy wxSnip!-example-list) + (list 'get-text string-example-list long-example-list long-example-list bool-example-list) + (list 'merge-with wxSnip!-example-list wxSnip!-example-list) + (list 'split void-example-list long-example-list wxSnip!*-example-list wxSnip!*-example-list) + (list 'draw void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list int-example-list) + (list 'partial-offset float-example-list wxDC!-example-list float-example-list float-example-list long-example-list) + (list 'get-extent void-example-list wxDC!-example-list float-example-list float-example-list float?-example-list float?-example-list float?-example-list float?-example-list float?-example-list float?-example-list))) +(hash-table-put! classinfo wx:media-snip% + (list wxMediaSnip!-example-list (quote wx:media-snip%) + (list + (list wxMediaBuffer^-example-list bool-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list int-example-list)) + (list 'get-inset void-example-list int*-example-list int*-example-list int*-example-list int*-example-list) + (list 'set-inset void-example-list int-example-list int-example-list int-example-list int-example-list) + (list 'get-margin void-example-list int*-example-list int*-example-list int*-example-list int*-example-list) + (list 'set-margin void-example-list int-example-list int-example-list int-example-list int-example-list) + (list 'border-visible? bool-example-list) + (list 'show-border void-example-list bool-example-list) + (list 'get-min-height float-example-list) + (list 'get-min-width float-example-list) + (list 'set-min-height void-example-list float-example-list) + (list 'set-min-width void-example-list float-example-list) + (list 'get-max-height float-example-list) + (list 'get-max-width float-example-list) + (list 'set-max-height void-example-list float-example-list) + (list 'set-max-width void-example-list float-example-list) + (list 'set-admin void-example-list wxSnipAdmin^-example-list) + (list 'resize bool-example-list float-example-list float-example-list) + (list 'write void-example-list wxMediaStreamOut%-example-list) + (list 'match? bool-example-list wxSnip!-example-list) + (list 'do-font void-example-list int-example-list bool-example-list) + (list 'do-edit void-example-list int-example-list bool-example-list long-example-list) + (list 'own-caret void-example-list bool-example-list) + (list 'on-char void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list wxKeyEvent%-example-list) + (list 'on-event void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list wxMouseEvent%-example-list) + (list 'size-cache-invalid void-example-list) + (list 'copy wxSnip!-example-list) + (list 'get-text string-example-list long-example-list long-example-list bool-example-list) + (list 'merge-with wxSnip!-example-list wxSnip!-example-list) + (list 'split void-example-list long-example-list wxSnip!*-example-list wxSnip!*-example-list) + (list 'draw void-example-list wxDC!-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list float-example-list int-example-list) + (list 'partial-offset float-example-list wxDC!-example-list float-example-list float-example-list long-example-list) + (list 'get-extent void-example-list wxDC!-example-list float-example-list float-example-list float?-example-list float?-example-list float?-example-list float?-example-list float?-example-list float?-example-list) + (list 'set-media void-example-list wxMediaBuffer^-example-list) + (list 'get-media wxMediaBuffer^-example-list) + (list 'get-this-media wxMediaBuffer^-example-list))) +(hash-table-put! classinfo wx:buffer-data-class% + (list wxBufferDataClass!-example-list (quote wx:buffer-data-class%) + (list + (list)) + (list 'read wxBufferData^-example-list wxMediaStreamIn%-example-list) + (list 'get-classname string-example-list) + (list 'set-classname void-example-list string-example-list) + (list 'get-required bool-example-list) + (list 'set-required void-example-list bool-example-list))) +(hash-table-put! classinfo wx:buffer-data-class-list% + (list wxBufferDataClassList!-example-list (quote wx:buffer-data-class-list%) + (list + (list)) + (list 'nth wxBufferDataClass^-example-list int-example-list) + (list 'number int-example-list) + (list 'add void-example-list wxBufferDataClass!-example-list) + (list 'find-position short-example-list wxBufferDataClass!-example-list) + (list 'find wxBufferDataClass^-example-list string-example-list))) +(hash-table-put! classinfo wx:buffer-data% + (list wxBufferData!-example-list (quote wx:buffer-data%) + (list + (list)) + (list 'write bool-example-list wxMediaStreamOut%-example-list) + (list 'get-dataclass wxBufferDataClass^-example-list) + (list 'set-dataclass void-example-list wxBufferDataClass^-example-list) + (list 'get-next wxBufferData^-example-list) + (list 'set-next void-example-list wxBufferData^-example-list))) +(hash-table-put! classinfo wx:mult-colour% + (list wxMultColour!-example-list (quote wx:mult-colour%) + (list) + (list 'set void-example-list float-example-list float-example-list float-example-list) + (list 'get void-example-list float*-example-list float*-example-list float*-example-list) + (list 'get-r float-example-list) + (list 'set-r void-example-list float-example-list) + (list 'get-g float-example-list) + (list 'set-g void-example-list float-example-list) + (list 'get-b float-example-list) + (list 'set-b void-example-list float-example-list))) +(hash-table-put! classinfo wx:add-colour% + (list wxAddColour!-example-list (quote wx:add-colour%) + (list) + (list 'set void-example-list short-example-list short-example-list short-example-list) + (list 'get void-example-list short*-example-list short*-example-list short*-example-list) + (list 'get-r short-example-list) + (list 'set-r void-example-list short-example-list) + (list 'get-g short-example-list) + (list 'set-g void-example-list short-example-list) + (list 'get-b short-example-list) + (list 'set-b void-example-list short-example-list))) +(hash-table-put! classinfo wx:style-delta% + (list wxStyleDelta!-example-list (quote wx:style-delta%) + (list + (list int-example-list int-example-list)) + (list 'copy void-example-list wxStyleDelta!-example-list) + (list 'collapse bool-example-list wxStyleDelta%-example-list) + (list 'equal? bool-example-list wxStyleDelta%-example-list) + (list 'set-delta-foreground wxStyleDelta!-example-list wxColour%-example-list) + (list 'set-delta-foreground wxStyleDelta!-example-list string-example-list) + (list 'set-delta-background wxStyleDelta!-example-list wxColour%-example-list) + (list 'set-delta-background wxStyleDelta!-example-list string-example-list) + (list 'set-delta-face wxStyleDelta!-example-list string-example-list) + (list 'set-delta wxStyleDelta!-example-list int-example-list int-example-list) + (list 'get-family int-example-list) + (list 'set-family void-example-list int-example-list) + (list 'get-face nstring-example-list) + (list 'set-face void-example-list nstring-example-list) + (list 'get-size-mult float-example-list) + (list 'set-size-mult void-example-list float-example-list) + (list 'get-size-add int-example-list) + (list 'set-size-add void-example-list int-example-list) + (list 'get-weight-on int-example-list) + (list 'set-weight-on void-example-list int-example-list) + (list 'get-weight-off int-example-list) + (list 'set-weight-off void-example-list int-example-list) + (list 'get-style-on int-example-list) + (list 'set-style-on void-example-list int-example-list) + (list 'get-style-off int-example-list) + (list 'set-style-off void-example-list int-example-list) + (list 'get-underlined-on bool-example-list) + (list 'set-underlined-on void-example-list bool-example-list) + (list 'get-underlined-off bool-example-list) + (list 'set-underlined-off void-example-list bool-example-list) + (list 'get-transparent-text-backing-on bool-example-list) + (list 'set-transparent-text-backing-on void-example-list bool-example-list) + (list 'get-transparent-text-backing-off bool-example-list) + (list 'set-transparent-text-backing-off void-example-list bool-example-list) + (list 'get-foreground-mult wxMultColour%-example-list) + (list 'get-background-mult wxMultColour%-example-list) + (list 'get-foreground-add wxAddColour%-example-list) + (list 'get-background-add wxAddColour%-example-list) + (list 'get-alignment-on int-example-list) + (list 'set-alignment-on void-example-list int-example-list) + (list 'get-alignment-off int-example-list) + (list 'set-alignment-off void-example-list int-example-list))) +(hash-table-put! classinfo wx:style% + (list wxStyle!-example-list (quote wx:style%) + (list) + (list 'switch-to void-example-list wxDC!-example-list wxStyle!-example-list) + (list 'set-shift-style void-example-list wxStyle!-example-list) + (list 'get-shift-style wxStyle!-example-list) + (list 'is-join? bool-example-list) + (list 'set-delta void-example-list wxStyleDelta%-example-list) + (list 'get-delta void-example-list wxStyleDelta%-example-list) + (list 'set-base-style void-example-list wxStyle!-example-list) + (list 'get-base-style wxStyle!-example-list) + (list 'get-transparent-text-backing bool-example-list) + (list 'get-alignment int-example-list) + (list 'get-colour wxColour%-example-list) + (list 'get-foreground wxColour%-example-list) + (list 'get-font wxFont!-example-list) + (list 'get-underlined bool-example-list) + (list 'get-style int-example-list) + (list 'get-weight int-example-list) + (list 'get-size int-example-list) + (list 'get-face nstring-example-list) + (list 'get-family int-example-list) + (list 'get-name string-example-list))) +(hash-table-put! classinfo wx:style-list% + (list wxStyleList!-example-list (quote wx:style-list%) + (list + (list)) + (list 'is-used? bool-example-list) + (list 'adjust-usage void-example-list bool-example-list) + (list 'style-to-index int-example-list wxStyle!-example-list) + (list 'index-to-style wxStyle^-example-list int-example-list) + (list 'convert wxStyle!-example-list wxStyle!-example-list) + (list 'replace-named-style wxStyle!-example-list string-example-list wxStyle^-example-list) + (list 'new-named-style wxStyle!-example-list string-example-list wxStyle^-example-list) + (list 'find-named-style wxStyle!-example-list string-example-list) + (list 'find-or-create-join-style wxStyle!-example-list wxStyle^-example-list wxStyle!-example-list) + (list 'find-or-create-style wxStyle!-example-list wxStyle^-example-list wxStyleDelta!-example-list) + (list 'number int-example-list) + (list 'basic-style wxStyle!-example-list) + (list 'copy void-example-list wxStyleList!-example-list) + (list 'clear void-example-list))) +(hash-table-put! classinfo wx:text% + (list wxText!-example-list (quote wx:text%) + (list + (list wxPanel!-example-list wxFunction-example-list nstring-example-list string-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'set-editable void-example-list bool-example-list) + (list 'paste void-example-list) + (list 'cut void-example-list) + (list 'copy void-example-list) + (list 'set-value void-example-list string-example-list) + (list 'get-value string-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list))) +(hash-table-put! classinfo wx:multi-text% + (list wxMultiText!-example-list (quote wx:multi-text%) + (list + (list wxPanel!-example-list wxFunction-example-list nstring-example-list string-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'get-value string-example-list))) +(hash-table-put! classinfo wx:text-window% + (list wxTextWindow!-example-list (quote wx:text-window%) + (list + (list wxFrame!-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list) + (list wxPanel!-example-list int-example-list int-example-list int-example-list int-example-list long-example-list string-example-list)) + (list 'on-char void-example-list wxKeyEvent%-example-list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list) + (list 'write-text void-example-list string-example-list) + (list 'show-position void-example-list long-example-list) + (list 'set-insertion-point-end void-example-list) + (list 'set-insertion-point void-example-list long-example-list) + (list 'set-font void-example-list wxFont!-example-list) + (list 'replace void-example-list long-example-list long-example-list string-example-list) + (list 'remove void-example-list long-example-list long-example-list) + (list 'x-y-to-position long-example-list long-example-list long-example-list) + (list 'position-to-x-y void-example-list long-example-list long*-example-list long*-example-list) + (list 'modified? bool-example-list) + (list 'load-file bool-example-list pathname-example-list) + (list 'set-selection void-example-list long-example-list long-example-list) + (list 'get-number-of-lines int-example-list) + (list 'get-line-length long-example-list int-example-list) + (list 'get-last-position long-example-list) + (list 'get-insertion-point long-example-list) + (list 'get-contents string-example-list) + (list 'discard-edits void-example-list) + (list 'paste void-example-list) + (list 'cut void-example-list) + (list 'copy void-example-list) + (list 'clear void-example-list) + (list 'popup-menu bool-example-list wxMenu!-example-list float-example-list float-example-list))) +(hash-table-put! classinfo wx:window% + (list wxWindow!-example-list (quote wx:window%) + (list) + (list 'pre-on-event bool-example-list wxWindow!-example-list wxMouseEvent!-example-list) + (list 'pre-on-char bool-example-list wxWindow!-example-list wxKeyEvent!-example-list) + (list 'on-size void-example-list int-example-list int-example-list) + (list 'on-set-focus void-example-list) + (list 'on-kill-focus void-example-list) + (list 'get-y int-example-list) + (list 'get-x int-example-list) + (list 'get-width int-example-list) + (list 'get-height int-example-list) + (list 'center void-example-list int-example-list) + (list 'get-label string-example-list) + (list 'get-grand-parent wxWindow^-example-list) + (list 'get-text-extent void-example-list string-example-list float*-example-list float*-example-list float?-example-list float?-example-list wxFont^-example-list bool-example-list) + (list 'get-parent wxWindow^-example-list) + (list 'refresh void-example-list) + (list 'screen-to-client void-example-list int*-example-list int*-example-list) + (list 'client-to-screen void-example-list int*-example-list int*-example-list) + (list 'get-char-width float-example-list) + (list 'get-char-height float-example-list) + (list 'get-name nstring-example-list) + (list 'enable void-example-list bool-example-list) + (list 'get-position void-example-list int*-example-list int*-example-list) + (list 'get-client-size void-example-list int*-example-list int*-example-list) + (list 'get-size void-example-list int*-example-list int*-example-list) + (list 'fit void-example-list) + (list 'is-shown? bool-example-list) + (list 'show void-example-list bool-example-list) + (list 'set-cursor wxCursor^-example-list wxCursor!-example-list) + (list 'move void-example-list int-example-list int-example-list) + (list 'set-size void-example-list int-example-list int-example-list int-example-list int-example-list int-example-list) + (list 'set-focus void-example-list) + (list 'centre void-example-list int-example-list))) + +(define classes + (list + 'wxEventGlobal + 'wxMediaGlobal + 'wxsGlobal + wx:add-colour% + wx:bitmap% + wx:brush% + wx:brush-list% + wx:buffer-data% + wx:buffer-data-class% + wx:buffer-data-class-list% + wx:button% + wx:canvas% + wx:canvas-dc% + wx:canvas-media-admin% + wx:check-box% + wx:choice% + wx:clipboard% + wx:clipboard-client% + wx:colour% + wx:colour-database% + wx:colour-map% + wx:command-event% + wx:cursor% + wx:dc% + wx:dialog-box% + wx:event% + wx:font% + wx:font-list% + wx:font-name-directory% + wx:frame% + wx:gauge% + wx:icon% + wx:image-snip% + wx:int-point% + wx:item% + wx:key-event% + wx:keymap% + wx:list-box% + wx:media-admin% + wx:media-buffer% + wx:media-canvas% + wx:media-edit% + wx:media-pasteboard% + wx:media-snip% + wx:media-snip-media-admin% + wx:media-stream-in% + wx:media-stream-in-base% + wx:media-stream-in-string-base% + wx:media-stream-out% + wx:media-stream-out-base% + wx:media-stream-out-string-base% + wx:media-wordbreak-map% + wx:memory-dc% + wx:menu% + wx:menu-bar% + wx:message% + wx:meta-file% + wx:meta-file-dc% + wx:mouse-event% + wx:mult-colour% + wx:multi-text% + wx:object% + wx:panel% + wx:pen% + wx:pen-list% + wx:point% + wx:post-script-dc% + wx:printer-dc% + wx:radio-box% + wx:slider% + wx:snip% + wx:snip-admin% + wx:snip-class% + wx:snip-class-list% + wx:style% + wx:style-delta% + wx:style-list% + wx:tab-snip% + wx:text% + wx:text-snip% + wx:text-window% + wx:timer% + wx:window%)) + diff --git a/collects/tests/mzscheme/README b/collects/tests/mzscheme/README new file mode 100644 index 0000000..d3a818a --- /dev/null +++ b/collects/tests/mzscheme/README @@ -0,0 +1,45 @@ + +To run all of the tests, run: + > (load "PATHTOHEREall.ss") +where PATHTOHERE is the path to this directory. + +Test failures may cause the test to stop before finishing, but most +test failures will let the test continue, and a summary message at the +end will enummerate the failures that occurred. + +Some files are directories are created (in the current directory) +during the run. The files are named "tmp" where is a number. +The directory is named "deep". If the test suite passes, the directory +should be removed, but some "tmp" files will remain. (The "tmp" +files are automatically replaced if the test suite is run again.) + +Unless your machine clock is always exactly in sync with your disk, +don't worry about failures that look like this: + ((path) (#f #t (#<|primitive:<=|> 11 39 11))) + ((path) (#f #t (#<|primitive:<=|> 11 39 11))) + ((path) (#f #t (#<|primitive:<=|> 11 39 11))) + +Additionally, test expand-defmacro by running: + > (load "PATHTOHEREexpand.ss") + +Test compilation and writing/reading compiled code with: + > (load "PATHTOHEREcompile.ss") + +Run the tests with no output except for the results with: + > (load "PATHTOHEREquiet.ss") + +Run 3 copies of the test suite concurrently in separate threads: + > (load "PATHTOHEREparallel.ss") + +MzLib tests are run with: + > (load "PATHTOHEREmzlib.ss") + + +To run the test suite in MzRice, use these flags: + --case-insens --auto-else --no-set-undef --no-sig-undef + + +Please report bugs using + http://www.cs.rice.edu/CS/PLT/Gnats/ +or (as a last resort) send mail to + plt-bugs@rice.edu diff --git a/collects/tests/mzscheme/all.ss b/collects/tests/mzscheme/all.ss new file mode 100644 index 0000000..7ecae32 --- /dev/null +++ b/collects/tests/mzscheme/all.ss @@ -0,0 +1,38 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(load-relative "basic.ss") +(load-relative "read.ss") +(unless (defined? 'building-flat-tests) + (load-relative "macro.ss")) +(load-relative "syntax.ss") +(load-relative "number.ss") +(load-relative "object.ss") +(load-relative "struct.ss") +(load-relative "unit.ss") +(load-relative "unitsig.ss") +(load-relative "thread.ss") +(unless (or (defined? 'read/zodiac) + (defined? 'in-drscheme?)) + (load-relative "namespac.ss")) +(unless (or (defined? 'building-flat-tests) + (defined? 'read/zodiac) + (defined? 'in-drscheme?)) + (load-relative "param.ss")) +(load-relative "file.ss") +(load-relative "path.ss") +(unless (defined? 'building-flat-tests) + (load-relative "hashper.ss")) +(unless (or (defined? 'building-flat-tests) + (defined? 'read/zodiac) + (defined? 'in-drscheme?)) + (load-relative "optimize.ss")) +(unless (defined? 'building-flat-tests) + (load-relative "name.ss")) + +;; Ok, so this isn't really all of them. Here are more: +; thrport.ss +; deep.ss + +; See also README diff --git a/collects/tests/mzscheme/basic.ss b/collects/tests/mzscheme/basic.ss new file mode 100644 index 0000000..26f033c --- /dev/null +++ b/collects/tests/mzscheme/basic.ss @@ -0,0 +1,1289 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(test '() 'null null) +(test '() 'null ()) + +(let ([f (lambda () #&7)]) + (test #t eq? (f) (f))) + +(test #t type-symbol? #) +(test #t type-symbol? #<<\>>) +(test #t type-symbol? #<<>) +(test #t type-symbol? '#) +(test #f type-symbol? ') +(test #t eq? # '#) +(test #f eq? # #) + +(arity-test type-symbol? 1 1) + +(SECTION 2 1);; test that all symbol characters are supported. +'(+ - ... !.. $.+ %.- &.! *.: /:. :+. <-. =. >. ?. ~. _. ^.) + +(SECTION 3 4) +(define disjoint-type-functions + (list boolean? char? null? number? pair? procedure? string? symbol? vector?)) +(define type-examples + (list + #t #f #\a '() 9739 '(test) record-error "test" "" 'test '#() '#(a b c) )) +(define i 1) +(for-each (lambda (x) (display (make-string i #\ )) + (set! i (+ 3 i)) + (write x) + (newline)) + disjoint-type-functions) +(define type-matrix + (map (lambda (x) + (let ((t (map (lambda (f) (f x)) disjoint-type-functions))) + (write t) + (write x) + (newline) + t)) + type-examples)) + +(SECTION 6 1) +(test #f not #t) +(test #f not 3) +(test #f not (list 3)) +(test #t not #f) +(test #f not '()) +(test #f not (list)) +(test #f not 'nil) +(arity-test not 1 1) + +(test #t boolean? #f) +(test #t boolean? #t) +(test #f boolean? 0) +(test #f boolean? '()) +(arity-test boolean? 1 1) + +(SECTION 6 2) +(test #t eqv? 'a 'a) +(test #f eqv? 'a 'b) +(test #t eqv? 2 2) +(test #f eqv? 2 2.0) +(test #t eqv? '() '()) +(test #t eqv? '10000 '10000) +(test #t eqv? 10000000000000000000 10000000000000000000) +(test #f eqv? 10000000000000000000 10000000000000000001) +(test #f eqv? 10000000000000000000 20000000000000000000) +(test #f eqv? (cons 1 2) (cons 1 2)) +(test #f eqv? (lambda () 1) (lambda () 2)) +(test #f eqv? #f 'nil) +(let ((p (lambda (x) x))) + (test #t eqv? p p)) +(define gen-counter + (lambda () + (let ((n 0)) + (lambda () (set! n (+ n 1)) n)))) +(let ((g (gen-counter))) (test #t eqv? g g)) +(test #f eqv? (gen-counter) (gen-counter)) +(letrec ((f (lambda () (if (eqv? f g) 'f 'both))) + (g (lambda () (if (eqv? f g) 'g 'both)))) + (test #f eqv? f g)) + +(test #t eq? 'a 'a) +(test #f eq? (list 'a) (list 'a)) +(test #t eq? '() '()) +(test #t eq? car car) +(let ((x '(a))) (test #t eq? x x)) +(let ((x '#())) (test #t eq? x x)) +(let ((x (lambda (x) x))) (test #t eq? x x)) + +(test #t equal? 'a 'a) +(test #t equal? '("a") '("a")) +(test #t equal? '(a) '(a)) +(test #t equal? '(a (b) c) '(a (b) c)) +(test #t equal? '("a" ("b") "c") '("a" ("b") "c")) +(test #t equal? "abc" "abc") +(test #t equal? 2 2) +(test #t equal? (make-vector 5 'a) (make-vector 5 'a)) +(test #t equal? (box "a") (box "a")) +(test #f equal? "" (string #\null)) + +(test #f equal? 'a "a") +(test #f equal? 'a 'b) +(test #f equal? '(a) '(b)) +(test #f equal? '(a (b) d) '(a (b) c)) +(test #f equal? '(a (b) c) '(d (b) c)) +(test #f equal? '(a (b) c) '(a (d) c)) +(test #f equal? "abc" "abcd") +(test #f equal? "abcd" "abc") +(test #f equal? 2 3) +(test #f equal? 2.0 2) +(test #f equal? (make-vector 5 'b) (make-vector 5 'a)) +(test #f equal? (box "a") (box "b")) + +(arity-test eq? 2 2) +(arity-test eqv? 2 2) +(arity-test equal? 2 2) + +(SECTION 6 3) +(test '(a b c d e) 'dot '(a . (b . (c . (d . (e . ())))))) +(define x (list 'a 'b 'c)) +(define y x) +(and list? (test #t list? y)) +(set-cdr! x 4) +(test '(a . 4) 'set-cdr! x) +(test #t eqv? x y) +(test '(a b c . d) 'dot '(a . (b . (c . d)))) +(test #f list? y) +(let ((x (list 'a))) (set-cdr! x x) (test #f list? x)) +(arity-test list? 1 1) + +(test #t pair? '(a . b)) +(test #t pair? '(a . 1)) +(test #t pair? '(a b c)) +(test #f pair? '()) +(test #f pair? '#(a b)) +(arity-test pair? 1 1) + +(test '(a) cons 'a '()) +(test '((a) b c d) cons '(a) '(b c d)) +(test '("a" b c) cons "a" '(b c)) +(test '(a . 3) cons 'a 3) +(test '((a b) . c) cons '(a b) 'c) +(arity-test cons 2 2) + +(test 'a car '(a b c)) +(test '(a) car '((a) b c d)) +(test 1 car '(1 . 2)) +(arity-test car 1 1) +(error-test '(car 1)) + +(test '(b c d) cdr '((a) b c d)) +(test 2 cdr '(1 . 2)) +(arity-test cdr 1 1) +(error-test '(cdr 1)) + +(test '(a 7 c) list 'a (+ 3 4) 'c) +(test '() list) + +(test 3 length '(a b c)) +(test 3 length '(a (b) (c d e))) +(test 0 length '()) +(arity-test length 1 1) +(error-test '(length 1)) +(error-test '(length '(1 . 2))) +(error-test '(length "a")) +; (error-test '(length (quote #0=(1 . #0#)))) +(error-test '(let ([p (cons 1 1)]) (set-cdr! p p) (length p))) +(define x (cons 4 0)) +(set-cdr! x x) +(error-test '(length x)) + +(define l '(1 2 3)) +(set-cdr! l 5) +(test '(1 . 5) 'set-cdr! l) +(set-car! l 0) +(test '(0 . 5) 'set-car! l) +(arity-test set-car! 2 2) +(arity-test set-cdr! 2 2) +(error-test '(set-car! 4 4)) +(error-test '(set-cdr! 4 4)) + +(define (box-tests box unbox box? set-box! set-box!-name unbox-name) + (define b (box 5)) + (test 5 unbox b) + (when set-box! + (set-box! b 6) + (test 6 unbox b)) + (test #t box? b) + (test #f box? 5) + (arity-test box 1 1) + (arity-test unbox 1 1) + (arity-test box? 1 1) + (when set-box! + (arity-test set-box! 2 2)) + (error-test `(,unbox-name 8)) + (when set-box! + (error-test `(,set-box!-name 8 8)))) +(box-tests box unbox box? set-box! 'set-box! 'unbox) +(box-tests make-weak-box weak-box-value weak-box? #f #f 'weak-box-value) + +(test '(x y) append '(x) '(y)) +(test '(a b c d) append '(a) '(b c d)) +(test '(a (b) (c)) append '(a (b)) '((c))) +(test '() append) +(test '(a b c . d) append '(a b) '(c . d)) +(test 'a append '() 'a) +(test 1 append 1) +(test '(1 . 2) append '(1) 2) +(test '(1 . 2) append '(1) 2) +(error-test '(append '(1 2 . 3) 1)) +(error-test '(append '(1 2 3) 1 '(4 5 6))) +(test '(x y) append! '(x) '(y)) +(test '(a b c d) append! '(a) '(b c d)) +(test '(a (b) (c)) append! '(a (b)) '((c))) +(test '() append!) +(test '(a b c . d) append! '(a b) '(c . d)) +(test 'a append! '() 'a) +(test 1 append! 1) +(error-test '(append! '(1 2 . 3) 1)) +(error-test '(append! '(1 2 3) 1 '(4 5 6))) + +(define l '(1 2)) +(define l2 '(3 4 . 7)) +(define l3 (append l l2)) +(test '(1 2 3 4 . 7) 'append l3) +(set-car! l2 5) +(test '(1 2 5 4 . 7) 'append l3) +(set-car! l3 0) +(test '(0 2 5 4 . 7) 'append l3) +(test '(1 2) 'append l) + +(let* ([l '(1 2)] + [l2 '(3 4 . 7)] + [l3 (append! l l2)]) + (test '(1 2 3 4 . 7) 'append! l3) + (set-car! l2 5) + (test '(1 2 5 4 . 7) 'append! l3) + (set-car! l3 0) + (test '(0 2 5 4 . 7) 'append! l3) + (test '(0 2 5 4 . 7) 'append! l)) + +(test '(c b a) reverse '(a b c)) +(test '((e (f)) d (b c) a) reverse '(a (b c) d (e (f)))) +(arity-test reverse 1 1) +(error-test '(reverse 1)) +(error-test '(reverse '(1 . 1))) + +(define l '(a b c)) +(test '(c b a) reverse! l) +(test '(a) 'reverse! l) +(test '((e (f)) d (b c) a) reverse! '(a (b c) d (e (f)))) +(arity-test reverse! 1 1) +(error-test '(reverse! 1)) +(error-test '(reverse! '(1 . 1))) + +(test 'c list-ref '(a b c d) 2) +(test 'c list-ref '(a b c . d) 2) +(arity-test list-ref 2 2) +(error-test '(list-ref 1 1) exn:application:range:list?) +(error-test '(list-ref '(a b . c) 2) exn:application:range:list?) +(error-test '(list-ref '(1 2 3) 2.0)) +(error-test '(list-ref '(1) '(1))) +(error-test '(list-ref '(1) 1) exn:application:range:list?) +(error-test '(list-ref '() 0) exn:application:range:list?) +(error-test '(list-ref '() 0) exn:application:range:list?) +(error-test '(list-ref '(1) -1)) + +(test '(c d) list-tail '(a b c d) 2) +(test '(a b c d) list-tail '(a b c d) 0) +(test '(b c . d) list-tail '(a b c . d) 1) +(test 1 list-tail 1 0) +(arity-test list-tail 2 2) +(error-test '(list-tail 1 1) exn:application:range:list?) +(error-test '(list-tail '(1 2 3) 2.0)) +(error-test '(list-tail '(1) '(1))) +(error-test '(list-tail '(1) -1)) +(error-test '(list-tail '(1) 2) exn:application:range:list?) +(error-test '(list-tail '(1 2 . 3) 3) exn:application:range:list?) + +(define (test-mem memq memq-name) + (test '(a b c) memq 'a '(a b c)) + (test '(b c) memq 'b '(a b c)) + (test '(b . c) memq 'b '(a b . c)) + (test '#f memq 'a '(b c d)) + + (arity-test memq 2 2) + (error-test `(,memq-name 'a 1) exn:application:list?) + (error-test `(,memq-name 'a '(1 . 2)) exn:application:list?)) + +(test-mem memq 'memq) +(test-mem memv 'memv) +(test-mem member 'member) + +(test #f memq "apple" '("apple")) +(test #f memv "apple" '("apple")) +(test '("apple") member "apple" '("apple")) + +; (test #f memq 1/2 '(1/2)) ; rationals are immutable and we may want to optimize +(test '(1/2) memv 1/2 '(1/2)) +(test '(1/2) member 1/2 '(1/2)) + +(test '((1 2)) member '(1 2) '(1 2 (1 2))) + +(define (test-ass assq assq-name) + (define e '((a 1) (b 2) (c 3))) + (test '(a 1) assq 'a e) + (test '(b 2) assq 'b e) + (test #f assq 'd e) + (test '(a 1) assq 'a '((x 0) (a 1) b 2)) + (test '(a 1) assq 'a '((x 0) (a 1) . 0)) + (arity-test assq 2 2) + + (error-test `(,assq-name 1 1) exn:application:list?) + (error-test `(,assq-name 1 '(1 2)) exn:application:list?) + (error-test `(,assq-name 1 '((0) . 2)) exn:application:list?)) + +(test-ass assq 'assq) +(test-ass assv 'assv) +(test-ass assoc 'assoc) + +(test #f assq '(a) '(((a)) ((b)) ((c)))) +(test #f assv '(a) '(((a)) ((b)) ((c)))) +(test '((b) 1) assoc '(b) '(((a)) ((b) 1) ((c)))) + +; (test #f assq '1/2 '(((a)) (1/2) ((c)))) ; rationals are immutable and we may want to optimize +(test '(1/2) assv '1/2 '(((a)) (1/2) ((c)))) +(test '(1/2) assoc '1/2 '(((a)) (1/2) ((c)))) + +(SECTION 6 4) +(test #t symbol? 'foo) +(test #t symbol? (car '(a b))) +(test #f symbol? "bar") +(test #t symbol? 'nil) +(test #f symbol? '()) +(test #f symbol? #f) +;;; But first, what case are symbols in? Determine the standard case: +(define char-standard-case char-upcase) +(if (string=? (symbol->string 'A) "a") + (set! char-standard-case char-downcase)) +(test #t 'standard-case + (string=? (symbol->string 'a) (symbol->string 'A))) +(test #t 'standard-case + (or (string=? (symbol->string 'a) "A") + (string=? (symbol->string 'A) "a"))) +(define (str-copy s) + (let ((v (make-string (string-length s)))) + (do ((i (- (string-length v) 1) (- i 1))) + ((< i 0) v) + (string-set! v i (string-ref s i))))) +(define (string-standard-case s) + (set! s (str-copy s)) + (do ((i 0 (+ 1 i)) + (sl (string-length s))) + ((>= i sl) s) + (string-set! s i (char-standard-case (string-ref s i))))) +(test (string-standard-case "flying-fish") symbol->string 'flying-fish) +(test (string-standard-case "martin") symbol->string 'Martin) +(test "Malvina" symbol->string (string->symbol "Malvina")) +(test #t 'standard-case (eq? 'a 'A)) + +(define x (string #\a #\b)) +(define y (string->symbol x)) +(string-set! x 0 #\c) +(test "cb" 'string-set! x) +(test "ab" symbol->string y) +(test y string->symbol "ab") + +(test #t eq? 'mISSISSIppi 'mississippi) +(test #f 'string->symbol (eq? 'bitBlt (string->symbol "bitBlt"))) +(test 'JollyWog string->symbol (symbol->string 'JollyWog)) + +(arity-test symbol? 1 1) + +(SECTION 6 6) +(test #t eqv? '#\ #\Space) +(test #t eqv? #\space '#\Space) +(test #t char? #\a) +(test #t char? #\() +(test #t char? #\ ) +(test #t char? '#\newline) +(arity-test char? 1 1) + +(test #t char=? #\A) +(test #f char=? #\A #\B) +(test #f char=? #\A #\A #\B) +(test #f char=? #\A #\B #\A) +(test #f char=? #\a #\b) +(test #f char=? #\9 #\0) +(test #t char=? #\A #\A) +(test #t char=? #\A #\A #\A) +(test #t char=? #\370 #\370) +(test #f char=? #\371 #\370) +(test #f char=? #\370 #\371) +(arity-test char=? 1 -1) +(error-test '(char=? #\a 1)) +(error-test '(char=? #\a #\b 1)) +(error-test '(char=? 1 #\a)) + +(test #t char? #\A) +(test #f char>? #\A #\B) +(test #t char>? #\B #\A) +(test #f char>? #\A #\B #\C) +(test #f char>? #\B #\A #\C) +(test #t char>? #\C #\B #\A) +(test #f char>? #\a #\b) +(test #t char>? #\9 #\0) +(test #f char>? #\A #\A) +(test #f char>? #\370 #\370) +(test #t char>? #\371 #\370) +(test #f char>? #\370 #\371) +(arity-test char>? 1 -1) +(error-test '(char>? #\a 1)) +(error-test '(char>? #\a #\a 1)) +(error-test '(char>? 1 #\a)) + +(test #t char<=? #\A) +(test #t char<=? #\A #\B) +(test #t char<=? #\A #\B #\C) +(test #t char<=? #\A #\A #\C) +(test #f char<=? #\A #\B #\A) +(test #f char<=? #\B #\A #\C) +(test #t char<=? #\a #\b) +(test #f char<=? #\9 #\0) +(test #t char<=? #\A #\A) +(test #t char<=? #\370 #\370) +(test #f char<=? #\371 #\370) +(test #t char<=? #\370 #\371) +(arity-test char<=? 1 -1) +(error-test '(char<=? #\a 1)) +(error-test '(char<=? #\b #\a 1)) +(error-test '(char<=? 1 #\a)) + +(test #t char>=? #\A) +(test #f char>=? #\A #\B) +(test #f char>=? #\a #\b) +(test #t char>=? #\9 #\0) +(test #t char>=? #\A #\A) +(test #t char>=? #\370 #\370) +(test #t char>=? #\371 #\370) +(test #f char>=? #\370 #\371) +(arity-test char>=? 1 -1) +(error-test '(char>=? #\a 1)) +(error-test '(char>=? #\a #\b 1)) +(error-test '(char>=? 1 #\a)) + +(test #t char-ci=? #\A) +(test #f char-ci=? #\A #\B) +(test #f char-ci=? #\A #\A #\B) +(test #f char-ci=? #\a #\B) +(test #f char-ci=? #\A #\b) +(test #f char-ci=? #\a #\b) +(test #f char-ci=? #\9 #\0) +(test #t char-ci=? #\A #\A) +(test #t char-ci=? #\A #\a) +(test #t char-ci=? #\A #\a #\A) +(test #t char-ci=? #\370 #\370) +(test #f char-ci=? #\371 #\370) +(test #f char-ci=? #\370 #\371) +(arity-test char-ci=? 1 -1) +(error-test '(char-ci=? #\a 1)) +(error-test '(char-ci=? #\a #\b 1)) +(error-test '(char-ci=? 1 #\a)) + +(test #t char-ci? #\A) +(test #f char-ci>? #\A #\B) +(test #f char-ci>? #\B #\A #\C) +(test #t char-ci>? #\C #\B #\A) +(test #f char-ci>? #\a #\B) +(test #f char-ci>? #\A #\b) +(test #f char-ci>? #\a #\b) +(test #t char-ci>? #\C #\b #\A) +(test #t char-ci>? #\9 #\0) +(test #f char-ci>? #\A #\A) +(test #f char-ci>? #\A #\a) +(test #f char-ci>? #\370 #\370) +(test #t char-ci>? #\371 #\370) +(test #f char-ci>? #\370 #\371) +(arity-test char-ci>? 1 -1) +(error-test '(char-ci>? #\a 1)) +(error-test '(char-ci>? #\a #\b 1)) +(error-test '(char-ci>? 1 #\a)) + +(test #t char-ci<=? #\A) +(test #t char-ci<=? #\A #\B) +(test #t char-ci<=? #\a #\B) +(test #t char-ci<=? #\a #\B #\C) +(test #f char-ci<=? #\a #\b #\A) +(test #t char-ci<=? #\A #\b) +(test #t char-ci<=? #\a #\b) +(test #f char-ci<=? #\9 #\0) +(test #t char-ci<=? #\A #\A) +(test #t char-ci<=? #\A #\a) +(test #t char-ci<=? #\370 #\370) +(test #f char-ci<=? #\371 #\370) +(test #t char-ci<=? #\370 #\371) +(arity-test char-ci<=? 1 -1) +(error-test '(char-ci<=? #\a 1)) +(error-test '(char-ci<=? #\b #\a 1)) +(error-test '(char-ci<=? 1 #\a)) + +(test #t char-ci>=? #\A) +(test #f char-ci>=? #\A #\B) +(test #f char-ci>=? #\B #\A #\C) +(test #t char-ci>=? #\B #\B #\A) +(test #f char-ci>=? #\a #\B) +(test #f char-ci>=? #\A #\b) +(test #f char-ci>=? #\a #\b) +(test #t char-ci>=? #\9 #\0) +(test #t char-ci>=? #\A #\A) +(test #t char-ci>=? #\A #\a) +(test #t char-ci>=? #\370 #\370) +(test #t char-ci>=? #\371 #\370) +(test #f char-ci>=? #\370 #\371) +(arity-test char-ci>=? 1 -1) +(error-test '(char-ci>=? #\a 1)) +(error-test '(char-ci>=? #\a #\b 1)) +(error-test '(char-ci>=? 1 #\a)) + +(define (ascii-range start end) + (let ([s (char->integer start)] + [e (char->integer end)]) + (let loop ([n e][l (list end)]) + (if (= n s) + l + (let ([n (sub1 n)]) + (loop n (cons (integer->char n) l))))))) + +(define uppers (ascii-range #\A #\Z)) +(define lowers (ascii-range #\a #\z)) +(define alphas (append uppers lowers)) +(define digits (ascii-range #\0 #\9)) +(define whites (list #\newline #\return #\space #\page #\tab #\vtab)) + +(define (test-all is-a? name members) + (let loop ([n 0]) + (unless (= n 256) + (let ([c (integer->char n)]) + (test (and (memq c members) #t) `(,is-a? (integer->char ,n)) (is-a? c)) + (loop (add1 n))))) + (arity-test char-alphabetic? 1 1) + (error-test `(,name 1))) + +(test-all char-alphabetic? 'char-alphabetic? alphas) +(test-all char-numeric? 'char-numeric? digits) +(test-all char-whitespace? 'char-whitespace? whites) +(test-all char-upper-case? 'char-upper-case? uppers) +(test-all char-lower-case? 'char-lower-case? lowers) + +(let loop ([n 0]) + (unless (= n 256) + (test n 'integer->char (char->integer (integer->char n))) + (loop (add1 n)))) + +(test 0 char->integer #\nul) +(test 10 char->integer #\newline) +(test 13 char->integer #\return) +(test 9 char->integer #\tab) +(test 8 char->integer #\backspace) +(test 12 char->integer #\page) +(test 32 char->integer #\space) +(test 127 char->integer #\rubout) +(test #\null 'null #\nul) +(test #\newline 'linefeed #\linefeed) + +(test #\. integer->char (char->integer #\.)) +(test #\A integer->char (char->integer #\A)) +(test #\a integer->char (char->integer #\a)) +(test #\371 integer->char (char->integer #\371)) +(arity-test integer->char 1 1) +(arity-test char->integer 1 1) +(error-test '(integer->char 5.0)) +(error-test '(integer->char 'a)) +(error-test '(integer->char -1)) +(error-test '(integer->char 256)) +(error-test '(integer->char 10000000000000000)) +(error-test '(char->integer 5)) + +(define (test-up/down case case-name members memassoc) + (let loop ([n 0]) + (unless (= n 256) + (let ([c (integer->char n)]) + (if (memq c members) + (test (cdr (assq c memassoc)) case c) + (test n `(char->integer (,case-name (integer->char ,n))) (char->integer (case c))))) + (loop (add1 n)))) + (arity-test case 1 1) + (error-test `(,case-name 2))) + +(test-up/down char-upcase 'char-upcase lowers (map cons lowers uppers)) +(test-up/down char-downcase 'char-downcase uppers (map cons uppers lowers)) + +(SECTION 6 7) +(test #t string? "The word \"recursion\\\" has many meanings.") +(test #t string? "") +(arity-test string? 1 1) +(test 3 'make-string (string-length (make-string 3))) +(test "" make-string 0) +(arity-test make-string 1 2) +(error-test '(make-string "hello")) +(error-test '(make-string 5 "hello")) +(error-test '(make-string 5.0 #\b)) +(error-test '(make-string 5.2 #\a)) +(error-test '(make-string -5 #\f)) +(error-test '(make-string 500000000000000 #\f) exn:misc:out-of-memory?) + +(define f (make-string 3 #\*)) +(test "?**" 'string-set! (begin (string-set! f 0 #\?) f)) +(arity-test string-set! 3 3) +(error-test '(string-set! "hello" 'a #\a)) +(error-test '(string-set! 'hello 4 #\a)) +(error-test '(string-set! "hello" 4 'a)) +(error-test '(string-set! "hello" 4.0 'a)) +(error-test '(string-set! "hello" 5 #\a) exn:application:range:bounds:string?) +(error-test '(string-set! "hello" -1 #\a)) +(error-test '(string-set! "hello" (expt 2 100) #\a) exn:application:range:bounds:string?) +(test "abc" string #\a #\b #\c) +(test "" string) +(error-test '(string #\a 1)) +(error-test '(string 1 #\a)) +(error-test '(string 1)) +(test 3 string-length "abc") +(test 0 string-length "") +(arity-test string-length 1 1) +(error-test '(string-length 'apple)) +(test #\a string-ref "abc" 0) +(test #\c string-ref "abc" 2) +(arity-test string-ref 2 2) +(error-test '(string-ref 'apple 4)) +(error-test '(string-ref "apple" 4.0)) +(error-test '(string-ref "apple" '(4))) +(error-test '(string-ref "apple" 5) exn:application:range:bounds:string?) +(error-test '(string-ref "" 0) exn:application:range:bounds:string?) +(error-test '(string-ref "" (expt 2 100)) exn:application:range:bounds:string?) +(error-test '(string-ref "apple" -1)) +(test "" substring "ab" 0 0) +(test "" substring "ab" 1 1) +(test "" substring "ab" 2 2) +(test "a" substring "ab" 0 1) +(test "b" substring "ab" 1 2) +(test "ab" substring "ab" 0 2) +(test (string #\a #\nul #\b) substring (string #\- #\a #\nul #\b #\*) 1 4) +(arity-test substring 3 3) +(error-test '(substring 'hello 2 3)) +(error-test '(substring "hello" "2" 3)) +(error-test '(substring "hello" 2.0 3)) +(error-test '(substring "hello" 2 3.0)) +(error-test '(substring "hello" 2 "3")) +(error-test '(substring "hello" 2 7) exn:application:range:bounds:string?) +(error-test '(substring "hello" -2 3)) +(error-test '(substring "hello" 4 3) exn:application:range:bounds:string?) +(error-test '(substring "hello" (expt 2 100) 3) exn:application:range:bounds:string?) +(error-test '(substring "hello" 3 (expt 2 100)) exn:application:range:bounds:string?) +(test "foobar" string-append "foo" "bar") +(test "foo" string-append "foo") +(test "foo" string-append "foo" "") +(test "foogoo" string-append "foo" "" "goo") +(test "foo" string-append "" "foo") +(test "" string-append) +(test (string #\a #\nul #\b #\c #\nul #\d) + string-append (string #\a #\nul #\b) (string #\c #\nul #\d)) +(error-test '(string-append 1)) +(error-test '(string-append "hello" 1)) +(error-test '(string-append "hello" 1 "done")) +(test "" make-string 0) +(define s "hello") +(define s2 (string-copy s)) +(test "hello" 'string-copy s2) +(string-set! s 2 #\x) +(test "hello" 'string-copy s2) +(test (string #\a #\nul #\b) string-copy (string #\a #\nul #\b)) +(string-fill! s #\x) +(test "xxxxx" 'string-fill! s) +(arity-test string-copy 1 1) +(arity-test string-fill! 2 2) +(error-test '(string-copy 'blah)) +(error-test '(string-fill! "oops" 5)) + +(define ax (string #\a #\nul #\370 #\x)) +(define abigx (string #\a #\nul #\370 #\X)) +(define ax2 (string #\a #\nul #\370 #\x)) +(define ay (string #\a #\nul #\371 #\x)) + +(test #t string=? "string") +(test #t string? "string") +(test #t string<=? "string") +(test #t string>=? "string") +(test #t string-ci=? "string") +(test #t string-ci? "string") +(test #t string-ci<=? "string") +(test #t string-ci>=? "string") + +(test #t string=? "" "") +(test #f string? "" "") +(test #t string<=? "" "") +(test #t string>=? "" "") +(test #t string-ci=? "" "") +(test #f string-ci? "" "") +(test #t string-ci<=? "" "") +(test #t string-ci>=? "" "") + +(test #f string=? "A" "B") +(test #f string=? "a" "b") +(test #f string=? "9" "0") +(test #t string=? "A" "A") +(test #f string=? "A" "AB") +(test #t string=? ax ax2) +(test #f string=? ax abigx) +(test #f string=? ax ay) +(test #f string=? ay ax) + +(test #t string? "A" "B") +(test #f string>? "a" "b") +(test #t string>? "9" "0") +(test #f string>? "A" "A") +(test #f string>? "A" "AB") +(test #t string>? "AB" "A") +(test #f string>? ax ax2) +(test #f string>? ax ay) +(test #t string>? ay ax) + +(test #t string<=? "A" "B") +(test #t string<=? "a" "b") +(test #f string<=? "9" "0") +(test #t string<=? "A" "A") +(test #t string<=? "A" "AB") +(test #f string<=? "AB" "A") +(test #t string<=? ax ax2) +(test #t string<=? ax ay) +(test #f string<=? ay ax) + +(test #f string>=? "A" "B") +(test #f string>=? "a" "b") +(test #t string>=? "9" "0") +(test #t string>=? "A" "A") +(test #f string>=? "A" "AB") +(test #t string>=? "AB" "A") +(test #t string>=? ax ax2) +(test #f string>=? ax ay) +(test #t string>=? ay ax) + +(test #f string-ci=? "A" "B") +(test #f string-ci=? "a" "B") +(test #f string-ci=? "A" "b") +(test #f string-ci=? "a" "b") +(test #f string-ci=? "9" "0") +(test #t string-ci=? "A" "A") +(test #t string-ci=? "A" "a") +(test #f string-ci=? "A" "AB") +(test #t string-ci=? ax ax2) +(test #t string-ci=? ax abigx) +(test #f string-ci=? ax ay) +(test #f string-ci=? ay ax) +(test #f string-ci=? abigx ay) +(test #f string-ci=? ay abigx) + +(test #t string-ci? "A" "B") +(test #f string-ci>? "a" "B") +(test #f string-ci>? "A" "b") +(test #f string-ci>? "a" "b") +(test #t string-ci>? "9" "0") +(test #f string-ci>? "A" "A") +(test #f string-ci>? "A" "a") +(test #f string-ci>? "A" "AB") +(test #t string-ci>? "AB" "A") +(test #f string-ci>? ax ax2) +(test #f string-ci>? ax abigx) +(test #f string-ci>? ax ay) +(test #t string-ci>? ay ax) +(test #f string-ci>? abigx ay) +(test #t string-ci>? ay abigx) + +(test #t string-ci<=? "A" "B") +(test #t string-ci<=? "a" "B") +(test #t string-ci<=? "A" "b") +(test #t string-ci<=? "a" "b") +(test #f string-ci<=? "9" "0") +(test #t string-ci<=? "A" "A") +(test #t string-ci<=? "A" "a") +(test #t string-ci<=? "A" "AB") +(test #f string-ci<=? "AB" "A") +(test #t string-ci<=? ax ax2) +(test #t string-ci<=? ax abigx) +(test #t string-ci<=? ax ay) +(test #f string-ci<=? ay ax) +(test #t string-ci<=? abigx ay) +(test #f string-ci<=? ay abigx) + +(test #f string-ci>=? "A" "B") +(test #f string-ci>=? "a" "B") +(test #f string-ci>=? "A" "b") +(test #f string-ci>=? "a" "b") +(test #t string-ci>=? "9" "0") +(test #t string-ci>=? "A" "A") +(test #t string-ci>=? "A" "a") +(test #f string-ci>=? "A" "AB") +(test #t string-ci>=? "AB" "A") +(test #t string-ci>=? ax ax2) +(test #t string-ci>=? ax abigx) +(test #f string-ci>=? ax ay) +(test #t string-ci>=? ay ax) +(test #f string-ci>=? abigx ay) +(test #t string-ci>=? ay abigx) + +(map (lambda (pred) + (arity-test pred 1 -1) + (let ([predname (string->symbol + (primitive-name pred))]) + (error-test `(,predname "a" 1)) + (error-test `(,predname "a" "b" 5)) + (error-test `(,predname 1 "a")))) + (list string=? + string>? + string=? + string<=? + string-ci=? + string-ci>? + string-ci=? + string-ci<=?)) + +(SECTION 6 8) +(test #t vector? '#(0 (2 2 2 2) "Anna")) +(test #t vector? '#()) +(arity-test vector? 1 1) +(test '#(a b c) vector 'a 'b 'c) +(test '#() vector) +(test 3 vector-length '#(0 (2 2 2 2) "Anna")) +(test 0 vector-length '#()) +(arity-test vector-length 1 1) +(error-test '(vector-length "apple")) +(test 8 vector-ref '#(1 1 2 3 5 8 13 21) 5) +(arity-test vector-ref 2 2) +(error-test '(vector-ref "apple" 3)) +(error-test '(vector-ref #(4 5 6) 3) exn:application:range:bounds:vector?) +(error-test '(vector-ref #() 0) exn:application:range:bounds:vector?) +(error-test '(vector-ref #() (expt 2 100)) exn:application:range:bounds:vector?) +(error-test '(vector-ref #(4 5 6) -1)) +(error-test '(vector-ref #(4 5 6) 2.0)) +(error-test '(vector-ref #(4 5 6) "2")) +(test '#(0 ("Sue" "Sue") "Anna") 'vector-set + (let ((vec (vector 0 '(2 2 2 2) "Anna"))) + (vector-set! vec 1 '("Sue" "Sue")) + vec)) +(test '#(hi hi) make-vector 2 'hi) +(test '#() make-vector 0) +(test '#() make-vector 0 'a) +(arity-test make-vector 1 2) +(error-test '(make-vector "a" 'a)) +(error-test '(make-vector 1.0 'a)) +(error-test '(make-vector 10.2 'a)) +(error-test '(make-vector -1 'a)) +(error-test '(make-vector 1000000000000000000000 'a) exn:misc:out-of-memory?) +(arity-test vector-set! 3 3) +(error-test '(vector-set! #() 0 'x) exn:application:range:bounds:vector?) +(error-test '(vector-set! #(1 2 3) -1 'x)) +(error-test '(vector-set! #(1 2 3) 3 'x) exn:application:range:bounds:vector?) +(error-test '(vector-set! #(1 2 3) (expt 2 100) 'x) exn:application:range:bounds:vector?) +(error-test '(vector-set! '(1 2 3) 2 'x)) +(error-test '(vector-set! #(1 2 3) "2" 'x)) +(define v (quote #(1 2 3))) +(vector-fill! v 0) +(test (quote #(0 0 0)) 'vector-fill! v) +(arity-test vector-fill! 2 2) +(error-test '(vector-fill! '(1 2 3) 0)) + +(SECTION 6 9) +(test #t procedure? car) +(test #f procedure? 'car) +(test #t procedure? (lambda (x) (* x x))) +(test #f procedure? '(lambda (x) (* x x))) +(test #t call-with-current-continuation procedure?) +(test #t call-with-escaping-continuation procedure?) +(test #t procedure? (case-lambda ((x) x) ((x y) (+ x y)))) +(arity-test procedure? 1 1) + +(test 7 apply + (list 3 4)) +(test 7 apply (lambda (a b) (+ a b)) (list 3 4)) +(test 17 apply + 10 (list 3 4)) +(test '() apply list '()) +(define compose (lambda (f g) (lambda args (f (apply g args))))) +(test 30 (compose sqrt *) 12 75) +(error-test '(apply) exn:application:arity?) +(error-test '(apply (lambda x x)) exn:application:arity?) +(error-test '(apply (lambda x x) 1)) +(error-test '(apply (lambda x x) 1 2)) +(error-test '(apply (lambda x x) 1 '(2 . 3))) + +(test '(b e h) map cadr '((a b) (d e) (g h))) +(test '(5 7 9) map + '(1 2 3) '(4 5 6)) +(test '#(0 1 4 9 16) 'for-each + (let ((v (make-vector 5))) + (for-each (lambda (i) (vector-set! v i (* i i))) + '(0 1 2 3 4)) + v)) + +(define (map-tests map) + (let ([size? exn:application:list-sizes?] + [non-list? type?]) + (error-test `(,map (lambda (x y) (+ x y)) '(1 2) '1)) + (error-test `(,map (lambda (x y) (+ x y)) '2 '(1 2))) + (error-test `(,map (lambda (x y) (+ x y)) '(1 2) '(1 2 3)) size?) + (error-test `(,map (lambda (x y) (+ x y)) '(1 2 3) '(1 2)) size?) + (error-test `(,map (lambda (x) (+ x)) '(1 2 . 3)) non-list?) + (error-test `(,map (lambda (x y) (+ x y)) '(1 2 . 3) '(1 2)) non-list?) + (error-test `(,map (lambda (x y) (+ x y)) '(1 2 . 3) '(1 2 3)) non-list?) + (error-test `(,map (lambda (x y) (+ x y)) '(1 2) '(1 2 . 3)) non-list?) + (error-test `(,map (lambda (x y) (+ x y)) '(1 2 3) '(1 2 . 3)) non-list?) + (error-test `(,map) exn:application:arity?) + (error-test `(,map (lambda (x y) (+ x y))) exn:application:arity?) + (error-test `(,map (lambda () 10) null) exn:application:map-arity?) + (error-test `(,map (lambda (x) 10) '(1 2) '(3 4)) exn:application:map-arity?))) +(map-tests 'map) +(map-tests 'for-each) +(map-tests 'andmap) +(map-tests 'ormap) + +(test (void) for-each (lambda (x) (values 1 2)) '(1 2)) +(error-test '(map (lambda (x) (values 1 2)) '(1 2)) arity?) + +(test #t andmap add1 null) +(test #f ormap add1 null) +(test #f andmap positive? '(1 -2 3)) +(test #t ormap positive? '(1 -2 3)) +(test #f andmap negative? '(1 -2 3)) +(test #t ormap negative? '(1 -2 3)) +(test 4 andmap add1 '(1 2 3)) +(test 2 ormap add1 '(1 2 3)) + +(error-test '(ormap (lambda (x) (values 1 2)) '(1 2)) arity?) +(error-test '(andmap (lambda (x) (values 1 2)) '(1 2)) arity?) + +(error-test '(ormap (lambda (x) (values 1 2)) '(1)) arity?) +(error-test '(andmap (lambda (x) (values 1 2)) '(1)) arity?) + +(test -3 call-with-current-continuation + (lambda (exit) + (for-each (lambda (x) (if (negative? x) (exit x))) + '(54 0 37 -3 245 19)) + #t)) +(define list-length + (lambda (obj) + (call-with-current-continuation + (lambda (return) + (letrec ((r (lambda (obj) (cond ((null? obj) 0) + ((pair? obj) (+ (r (cdr obj)) 1)) + (else (return #f)))))) + (r obj)))))) +(test 4 list-length '(1 2 3 4)) +(test #f list-length '(a b . c)) +(test '() map cadr '()) + +;;; This tests full conformance of call-with-current-continuation. It +;;; is a separate test because some schemes do not support call/cc +;;; other than escape procedures. I am indebted to +;;; raja@copper.ucs.indiana.edu (Raja Sooriamurthi) for fixing this +;;; code. The function leaf-eq? compares the leaves of 2 arbitrary +;;; trees constructed of conses. +(define (next-leaf-generator obj eot) + (letrec ((return #f) + (cont (lambda (x) + (recurx obj) + (set! cont (lambda (x) (return eot))) + (cont #f))) + (recurx (lambda (obj) + (if (pair? obj) + (for-each recurx obj) + (call-with-current-continuation + (lambda (c) + (set! cont c) + (return obj))))))) + (lambda () (call-with-current-continuation + (lambda (ret) (set! return ret) (cont #f)))))) +(define (leaf-eq? x y) + (let* ((eot (list 'eot)) + (xf (next-leaf-generator x eot)) + (yf (next-leaf-generator y eot))) + (letrec ((loop (lambda (x y) + (cond ((not (eq? x y)) #f) + ((eq? eot x) #t) + (else (loop (xf) (yf))))))) + (loop (xf) (yf))))) +(define (test-cont) + (newline) + (display ";testing continuations; ") + (SECTION 6 9) + (test #t leaf-eq? '(a (b (c))) '((a) b c)) + (test #f leaf-eq? '(a (b (c))) '((a) b c d)) + '(report-errs)) + +(define (test-cc-values test-call/cc) + (test '(a b c) + call-with-values + (lambda () + (test-call/cc + (lambda (k) + (dynamic-wind + void + (lambda () + (k 'a 'b 'c)) + (lambda () + (values 1 2)))))) + list) + + (test 1 dynamic-wind + (lambda () (test-call/cc void)) + (lambda () 1) + (lambda () (test-call/cc void))) + + ; Try devious jumping with pre- and post-thunks: + (test 2 test-call/cc + (lambda (exit) + (dynamic-wind + (lambda () (exit 2)) + void + void))) + (test 3 test-call/cc + (lambda (exit) + (dynamic-wind + void + void + (lambda () (exit 3))))) + + (let ([rv + (lambda (get-v) + (let ([x 0]) + (test-call/cc + (lambda (exit) + (dynamic-wind + void + (lambda () (exit)) + (lambda () (set! x (get-v)))))) + x))] + [r56 + (lambda () + (let ([x 0] + [y 1] + [c1 #f]) + (dynamic-wind + (lambda () (set! x (add1 x))) + (lambda () + (let/cc k (set! c1 k)) + (if (>= x 5) + (set! c1 #f))) + (lambda () (set! y (add1 y)))) + (when c1 (c1)) + (list x y)))] + [rx.y + (lambda (get-x get-y) + (let ([c1 #f] + [x 0] + [y 0]) + (let ([v + (dynamic-wind + (lambda () (set! y x)) + (lambda () (let/cc k (set! c1 k))) + (lambda () + (set! x (get-x)) + (when c1 + ((begin0 + c1 + (set! c1 #f)) + (get-y)))))]) + (cons y v))))] + [rv2 + (lambda (get-v) + (let ([c1 #f] + [give-up #f]) + (test-call/cc + (lambda (exit) + (dynamic-wind + (lambda () (when give-up (give-up (get-v)))) + (lambda () (let/cc k (set! c1 k))) + (lambda () (set! give-up exit) (c1)))))))] + [r10-11-12 + (lambda () + (let ([c2 #f] + [x 10] + [y 11]) + (let ([v (dynamic-wind + (lambda () (set! y (add1 y))) + (lambda () (begin0 x (set! x (add1 x)))) + (lambda () (let/cc k (set! c2 k))))]) + (when c2 ((begin0 + c2 + (set! c2 #f)))) + (list v x y))))] + [r13.14 + (lambda () + (let ([c0 #f] + [x 11] + [y 12]) + (dynamic-wind + (lambda () (let/cc k (set! c0 k))) + (lambda () (set! x (add1 x))) + (lambda () (set! y (add1 y)) + (when c0 ((begin0 + c0 + (set! c0 #f)))))) + (cons x y)))] + [ra-b-a-b + (lambda (get-a get-b) + (let ([l null]) + (let ((k-in (test-call/cc (lambda (k1) + (dynamic-wind + (lambda () (set! l (append l (list (get-a))))) + (lambda () + (call/cc (lambda (k2) (k1 k2)))) + (lambda () (set! l (append l (list (get-b)))))))))) + (k-in (lambda (v) l)))))]) + + (test 4 rv (lambda () 4)) + (test '(5 6) r56) + + (test '(7 . 8) rx.y (lambda () 7) (lambda () 8)) + + (test 9 rv2 (lambda () 9)) + + (test '(10 11 12) r10-11-12) + + (test '(13 . 14) r13.14) + + ; !!! fixed in 50: + (test '(enter exit enter exit) + ra-b-a-b (lambda () 'enter) (lambda () 'exit)) + + (test '((13 . 14) (10 11 12) (13 . 14) (10 11 12)) + ra-b-a-b r13.14 r10-11-12) + (test '((10 11 12) (13 . 14) (10 11 12) (13 . 14)) + ra-b-a-b r10-11-12 r13.14) + + (test '((enter exit enter exit) + (exit enter exit enter) + (enter exit enter exit) + (exit enter exit enter)) + ra-b-a-b + (lambda () (ra-b-a-b (lambda () 'enter) (lambda () 'exit))) + (lambda () (ra-b-a-b (lambda () 'exit) (lambda () 'enter)))) + + (test '(enter exit enter exit) + rv (lambda () (ra-b-a-b (lambda () 'enter) (lambda () 'exit)))) + (test '(enter exit enter exit) + rv2 (lambda () (ra-b-a-b (lambda () 'enter) (lambda () 'exit)))) + + (test '(10 11 12) rv r10-11-12) + (test '(10 11 12) rv2 r10-11-12) + + (test '(13 . 14) rv r13.14) + (test '(13 . 14) rv2 r13.14) + + )) + + +(test-cc-values call/cc) +(test-cc-values call/ec) + +(arity-test call/cc 1 1) +(arity-test call/ec 1 1) +(error-test '(call/cc 4)) +(error-test '(call/cc (lambda () 0))) +(error-test '(call/ec 4)) +(error-test '(call/ec (lambda () 0))) + +(test #t primitive? car) +(test #f primitive? leaf-eq?) +(arity-test primitive? 1 1) + +(test 1 arity arity) +(test 2 arity cons) +(test (make-arity-at-least 1) arity >) +(test (list 0 1) arity current-output-port) +(test (list 1 3 (make-arity-at-least 5)) + arity (case-lambda [(x) 0] [(x y z) 1] [(x y z w u . rest) 2])) +(arity-test arity 1 1) + +(test #t procedure-arity-includes? cons 2) +(test #f procedure-arity-includes? cons 0) +(test #f procedure-arity-includes? cons 3) +(test #t procedure-arity-includes? list 3) +(test #t procedure-arity-includes? list 3000) +(test #t procedure-arity-includes? (lambda () 0) 0) +(test #f procedure-arity-includes? (lambda () 0) 1) +(test #f procedure-arity-includes? cons 10000000000000000000000000000) +(test #t procedure-arity-includes? list 10000000000000000000000000000) +(test #t procedure-arity-includes? (lambda x x) 10000000000000000000000000000) + +(error-test '(procedure-arity-includes? cons -1)) +(error-test '(procedure-arity-includes? cons 1.0)) +(error-test '(procedure-arity-includes? 'cons 1)) + +(arity-test procedure-arity-includes? 2 2) + +(newline) +(display ";testing scheme 4 functions; ") +(SECTION 6 7) +(test '(#\P #\space #\l) string->list "P l") +(test '() string->list "") +(test "1\\\"" list->string '(#\1 #\\ #\")) +(test "" list->string '()) +(arity-test list->string 1 1) +(arity-test string->list 1 1) +(error-test '(string->list 'hello)) +(error-test '(list->string 'hello)) +(error-test '(list->string '(#\h . #\e))) +(SECTION 6 8) +(test '(dah dah didah) vector->list '#(dah dah didah)) +(test '() vector->list '#()) +(test '#(dididit dah) list->vector '(dididit dah)) +(test '#() list->vector '()) +(arity-test list->vector 1 1) +(arity-test vector->list 1 1) +(error-test '(vector->list 'hello)) +(error-test '(list->vector 'hello)) +(error-test '(list->vector '(#\h . #\e))) + +(test-cont) + +(report-errs) + +"last item in file" diff --git a/collects/tests/mzscheme/censor.ss b/collects/tests/mzscheme/censor.ss new file mode 100644 index 0000000..52ef262 --- /dev/null +++ b/collects/tests/mzscheme/censor.ss @@ -0,0 +1,30 @@ + +; run a thunk using a censor that removes dangerous chars from a +; string for printing to a terminal +(lambda (thunk) + (let ([censor (lambda (s) + (list->string + (let loop ([s (string->list s)]) + (if (null? s) + null + (let ([c (car s)]) + (cond + [(and (not (char-whitespace? c)) (or (char<=? c #\space) (char>=? c #\200))) + (append (cons #\{ (string->list + (number->string + (char->integer c)))) + (cons #\} (loop (cdr s))))] + [else + (cons c (loop (cdr s)))]))))))]) + (let* ([oldp (current-output-port)] + [cp (make-output-port + (lambda (s) + (display (censor s) oldp)) + void)]) + (dynamic-wind + (lambda () (current-output-port cp)) + thunk + (lambda () + (current-output-port oldp)))))) + + diff --git a/collects/tests/mzscheme/cmdline.ss b/collects/tests/mzscheme/cmdline.ss new file mode 100644 index 0000000..618422d --- /dev/null +++ b/collects/tests/mzscheme/cmdline.ss @@ -0,0 +1,159 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'COMMAND-LINE) + +(require-library "cmdline.ss") + +(define (r-append opt . rest) + (append opt (list (list->vector rest)))) + +(test '("-bye" #()) + parse-command-line + "test" + #("--hi" "-bye") + (list + (list + 'multi + (list (list "--hi") + (lambda (flag v) v) + (list "Hello" "x")))) + r-append + '("arg")) + +(test '("1" "2" #("3")) + parse-command-line + "test" + #("-xi" "1" "2" "3") + (list + (list + 'multi + (list (list "-x" "-i") + (lambda (flag v) v) + (list "x or i" "x")))) + r-append + '("arg")) + +(test '(("-x" "a" "b") ("-i") #()) + parse-command-line + "test" + #("-xi" "a" "b") + (list + (list + 'multi + (list (list "-x" "-i") + list + (list "xi")))) + r-append + '("arg")) + +(test '("--simple" ("-x" . "a") ("-i" . "b") #()) + parse-command-line + "test" + #("--simple" "-xi" "a" "b") + (list + (list + 'multi + (list (list "--simple") (lambda (v) v) (list "S")) + (list (list "-x" "-i") + cons + (list "xi" "v")))) + r-append + '("arg")) + +(test '(("-x" "a" "c") ("-i" . "b") #("d")) + parse-command-line + "test" + #("-xi" "a" "c" "b" "d") + (list + (list + 'multi + (list (list "-x") + (lambda (x y z) (list x y z)) + (list "X" "y" "z")) + (list (list "-i") + cons + (list "i" "v")))) + r-append + '("arg")) + +(define (test-end-flags v include?) + (test (list + (list->vector + (let ([l '("-xi" "--bad" "--")]) + (if include? + (cons v l) + l)))) + parse-command-line + "test" + (vector v "-xi" "--bad" "--") + (list + (list + 'multi + (list (list "-x" "-i") + list + (list "xi")))) + r-append + '("arg"))) + +(test-end-flags "1" #t) +(test-end-flags "+" #t) +(test-end-flags "-" #t) +(test-end-flags "--" #f) +(test-end-flags "-1" #t) +(test-end-flags "+1" #t) +(test-end-flags "-1.4" #t) +(test-end-flags "+1999.0" #t) + +(define (test-bad-flag v name) ; -h and -i defined + (test 'yes-it-worked + (lambda (x-ignored y-ignored) + (with-handlers ([void + (lambda (exn) + (if (regexp-match + (format "unknown flag: ~s" name) + (exn-message exn)) + 'yes-it-worked + exn))]) + (parse-command-line + "test" + (vector name "--") + (list + (list + 'multi + (list (list "-x" "-i") + list + (list "x i")))) + r-append + '("arg")))) + v name)) + +(test-bad-flag "--ok" "--ok") +(test-bad-flag "-xbi" "-b") + +(test (void) parse-command-line "test" #() null void '("arg")) +(test (void) parse-command-line "test" #() (list (list 'once-each (list null void '("")))) void '("arg")) +(test (void) parse-command-line "test" #() (list (list 'once-any (list null void '("")))) void '("arg")) +(test (void) parse-command-line "test" #() (list (list 'multi (list null void '("")))) void '("arg")) +(test (void) parse-command-line "test" #() (list (list 'multi)) void '("arg")) + +(test "2" parse-command-line "test" #("1" "2") null (lambda (a b c) c) '("b" "c")) + +(error-test '(parse-command-line 'test #() null void '("arg"))) +(error-test '(parse-command-line "test" 9 null void '("arg"))) +(error-test '(parse-command-line "test" #() (list 0) void '("arg"))) +(error-test '(parse-command-line "test" #() (list (list 'malti)) void '("arg"))) +(error-test '(parse-command-line "test" #() (list (list 'multi (list 0 void '("")))) void '("arg"))) +(error-test '(parse-command-line "test" #() (list (list 'multi (list (list 0) void '("")))) void '("arg"))) +(error-test '(parse-command-line "test" #() (list (list 'multi (list (list "hi") void '("")))) void '("arg"))) +(error-test '(parse-command-line "test" #() (list (list 'multi (list (list "--") void '("")))) void '("arg"))) +(error-test '(parse-command-line "test" #() (list (list 'multi (list (list "-xi") void '("")))) void '("arg"))) +(error-test '(parse-command-line "test" #() (list (list 'multi (list (list "-x") (lambda () null) '("")))) void '("arg"))) +(error-test '(parse-command-line "test" #() (list (list 'multi (list (list "--xi") void ""))) void '("arg"))) +(error-test '(parse-command-line "test" #() (list (list 'multi (list (list "--xi") void '("" a)))) void '("arg"))) +(error-test '(parse-command-line "test" #() null (lambda () null) null)) + +(error-test '(parse-command-line "test" #() null (lambda (x y) null) null) exn:user?) + +(report-errs) diff --git a/collects/tests/mzscheme/compfile.ss b/collects/tests/mzscheme/compfile.ss new file mode 100644 index 0000000..4cd9181 --- /dev/null +++ b/collects/tests/mzscheme/compfile.ss @@ -0,0 +1,11 @@ + +(require-library "compat.ss") +(require-library "compat.ss") +(require-library "compat.ss") + +(defmacro test (x y) (string-append x y)) + +(test "a" "b") + +(load x) +(require-library) diff --git a/collects/tests/mzscheme/compile.ss b/collects/tests/mzscheme/compile.ss new file mode 100644 index 0000000..47fb239 --- /dev/null +++ b/collects/tests/mzscheme/compile.ss @@ -0,0 +1,83 @@ + +; Tests compilation and writing/reading compiled code +; by setting the eval handler and running all tests + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(define file + (if #f + (open-output-file "x" 'replace) + (make-output-port void void))) + +(define try-one + (lambda (e) + (let ([c (compile e)] + [p (open-output-string)]) + (write c p) + (let ([s (get-output-string p)]) + ; (write (string->list s)) (newline) + (let ([e (parameterize ([read-accept-compiled #t]) + (read (open-input-string s)))]) + (eval e)))))) + +(letrec ([orig (current-eval)] + [orig-load (current-load)] + [my-load + (lambda (filename) + (let ([f (open-input-file filename)]) + (dynamic-wind + void + (lambda () + (let loop ([results (list (void))]) + (let ([v (parameterize ([read-accept-compiled #t]) + (read f))]) + (if (eof-object? v) + (apply values results) + (loop (call-with-values + (lambda () (my-eval v orig)) + list)))))) + (lambda () + (close-input-port f)))))] + [my-eval + (case-lambda + [(x next-eval) + (let ([p (open-output-string)] + [c (compile x)]) + (write c p) + (let ([s (get-output-string p)]) + ; (display s file) (newline file) + (let ([e (parameterize ([read-accept-compiled #t]) + (read (open-input-string s)))]) + ; (write e file) (newline file) + (parameterize ([current-eval next-eval]) + (orig e)))))] + [(x) (my-eval x orig)])]) + (dynamic-wind + (lambda () + (set! teval (lambda (x) (my-eval x my-eval))) + ; (read-accept-compiled #t) + (current-eval my-eval) + (current-load my-load)) + (lambda () + (load-relative "all.ss")) + (lambda () + (set! teval eval) + (close-output-port file) + ; (read-accept-compiled #f) + (current-eval orig) + (current-load orig-load)))) + +; Check compiled number I/O: +(let ([l (let loop ([n -512][l null]) + (if (= n 513) + l + (loop (add1 n) (cons n l))))] + [p (open-output-string)]) + (write (compile `(quote ,l)) p) + (let ([s (open-input-string (get-output-string p))]) + (let ([l2 (parameterize ([read-accept-compiled #t]) + (eval (read s)))]) + (test #t equal? l l2)))) + +(report-errs) diff --git a/collects/tests/mzscheme/compilex.ss b/collects/tests/mzscheme/compilex.ss new file mode 100644 index 0000000..5e417fb --- /dev/null +++ b/collects/tests/mzscheme/compilex.ss @@ -0,0 +1,14 @@ + +; Tests simple compilation by setting the eval handler and +; running all tests + +(let ([orig (current-eval)]) + (dynamic-wind + (lambda () + (current-eval + (lambda (x) + (orig (compile x))))) + (lambda () + (load "all.ss")) + (lambda () + (current-eval orig)))) diff --git a/collects/tests/mzscheme/date.ss b/collects/tests/mzscheme/date.ss new file mode 100644 index 0000000..10671b7 --- /dev/null +++ b/collects/tests/mzscheme/date.ss @@ -0,0 +1,42 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'date) + +(require-library "date.ss") + +(define (test-find s m h d mo y) + (let* ([secs (find-seconds s m h d mo y)] + [date (seconds->date secs)]) + (test #t 'same + (and (= s (date-second date)) + (= m (date-minute date)) + (= h (date-hour date)) + (= d (date-day date)) + (= mo (date-month date)) + (= y (date-year date)))))) + +(test-find 0 0 0 1 4 1975) +(test-find 0 0 0 1 4 2005) + +; Bad dates +(error-test '(find-seconds 0 0 0 0 0 1990) exn:user?) +(error-test '(find-seconds 0 0 0 0 1 1990) exn:user?) +(error-test '(find-seconds 0 0 0 1 0 1990) exn:user?) + +; Early/late +(error-test '(find-seconds 0 0 0 1 1 1490) exn:user?) +(error-test '(find-seconds 0 0 0 1 1 2890) exn:user?) + +; 1990 April 1 was start of daylight savings: +(test-find 0 0 1 1 4 1990) ; ok +(let ([s (find-seconds 1 0 3 1 4 1990)]) ; ok + (when (date-dst? (seconds->date s)) + ; We have daylight savings here; 2:01 AM doesn't exist + (error-test '(find-seconds 0 1 2 1 4 1990) exn:user?) + ; This date is ambiguous; find-seconds should find + ; one of the two possible values, though: + (test-find 0 30 1 27 10 1996))) + +(report-errs) diff --git a/collects/tests/mzscheme/deep.ss b/collects/tests/mzscheme/deep.ss new file mode 100644 index 0000000..6232160 --- /dev/null +++ b/collects/tests/mzscheme/deep.ss @@ -0,0 +1,47 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'deep) + +; Test deep stacks + +(define proc-depth 100000) + +(test (- proc-depth) 'deep-recursion (let loop ([n proc-depth]) + (if (zero? n) + 0 + (sub1 (loop (sub1 n)))))) + +(define paren-port + (let* ([depth 50000] + [closing? #f] + [count depth]) + (make-input-port + (lambda () + (cond + [closing? + (if (= count depth) + eof + (begin + (set! count (add1 count)) + #\) ))] + [else + (set! count (sub1 count)) + (when (zero? count) + (set! closing? #t)) + #\(])) + (lambda () #t) + void))) + +(define deep-list (read paren-port)) + +(test #t 'read-deep (pair? deep-list)) + +(define s (open-output-string)) +(display deep-list s) + +(test #t 'equal? (equal? deep-list (read (open-input-string (get-output-string s))))) + +(report-errs) + diff --git a/collects/tests/mzscheme/em-imp.ss b/collects/tests/mzscheme/em-imp.ss new file mode 100644 index 0000000..69a97a0 --- /dev/null +++ b/collects/tests/mzscheme/em-imp.ss @@ -0,0 +1,467 @@ +;;; -*- scheme -*- +;;; Fortran-style implementation of an EM clustering algorithm. +;;; +;;; Written by Jeffrey Mark Siskind (qobi@cs.toronto.edu) +;;; R4RS-ified by by Lars Thomas Hansen (lth@cs.uoregon.edu) +;;; Random number generator by Ozan Yigit. +;;; +;;; To run: (run-benchmark) +;;; You must provide your own timer function. +;;; +;;; Some benchmark times: +;;; +;;; Chez Scheme 4.1 for SunOS running on Sparc 10/51 (1MB,96MB,50MHz), Solaris: +;;; Optimize-level 2: 112s run (CPU), 2.8s gc, 326 MB allocated, 1181 GCs +;;; Optimize-level 3: 79s run (CPU), 2.8s gc, 326 MB allocated, 1163 GCs + +(define make-model vector) +(define (model-pi model) (vector-ref model 0)) +(define (set-model-pi! model x) (vector-set! model 0 x)) +(define (model-mu model) (vector-ref model 1)) +(define (model-sigma model) (vector-ref model 2)) +(define (model-log-pi model) (vector-ref model 3)) +(define (set-model-log-pi! model x) (vector-set! model 3 x)) +(define (model-sigma-inverse model) (vector-ref model 4)) +(define (model-log-determinant-sigma model) (vector-ref model 5)) +(define (set-model-log-sigma-determinant! model x) (vector-set! model 5 x)) + +;--------------------------------------------------------------------------- +; Minimal Standard Random Number Generator +; Park & Miller, CACM 31(10), Oct 1988, 32 bit integer version. +; better constants, as proposed by Park. +; By Ozan Yigit + +(define *seed* 1) + +(define (srand seed) + (set! *seed* seed) + *seed*) + +(define (rand) + (let ((A 48271) + (M 2147483647) + (Q 44488) + (R 3399)) + (let* ((hi (quotient *seed* Q)) + (lo (modulo *seed* Q)) + (test (- (* A lo) (* R hi)))) + (if (> test 0) + (set! *seed* test) + (set! *seed* (+ test M))))) + *seed*) + +;--------------------------------------------------------------------------- + +(define (panic s) (error 'panic s)) + +(define *rand-max* 2147483648) + +(define log-math-precision 35.0) + +(define minus-infinity (- *rand-max*)) + +(define first car) + +(define second cadr) + +(define rest cdr) + +(define (reduce f l i) + (cond ((null? l) i) + ((null? (rest l)) (first l)) + (else (let loop ((l (rest l)) (c (first l))) + (if (null? l) c (loop (rest l) (f c (first l)))))))) + +(define (every-n p n) + (let loop ((i 0)) (or (>= i n) (and (p i) (loop (+ i 1)))))) + +(define (sum f n) + (let loop ((n (- n 1)) (c 0.0)) + (if (negative? n) c (loop (- n 1) (+ c (f n)))))) + +(define (add-exp e1 e2) + (let* ((e-max (max e1 e2)) + (e-min (min e1 e2)) + (factor (floor e-min))) + (if (= e-max minus-infinity) + minus-infinity + (if (> (- e-max factor) log-math-precision) + e-max + (+ (log (+ (exp (- e-max factor)) (exp (- e-min factor)))) + factor))))) + +(define (map-n f n) + (let loop ((i 0) (c '())) + (if (< i n) (loop (+ i 1) (cons (f i) c)) (reverse c)))) + +(define (map-n-vector f n) + (let ((v (make-vector n))) + (let loop ((i 0)) + (if (< i n) + (begin (vector-set! v i (f i)) + (loop (+ i 1))))) + v)) + +(define (remove-if-not p l) + (let loop ((l l) (c '())) + (cond ((null? l) (reverse c)) + ((p (first l)) (loop (rest l) (cons (first l) c))) + (else (loop (rest l) c))))) + +(define (positionv x l) + (let loop ((l l) (i 0)) + (cond ((null? l) #f) + ((eqv? x (first l)) i) + (else (loop (rest l) (+ i 1)))))) + +(define (make-matrix m n) + (map-n-vector (lambda (i) (make-vector n)) m)) + +(define (make-matrix-initial m n initial) + (map-n-vector (lambda (i) (make-vector n initial)) m)) + +(define (matrix-rows a) (vector-length a)) + +(define (matrix-columns a) (vector-length (vector-ref a 0))) + +(define (matrix-ref a i j) (vector-ref (vector-ref a i) j)) + +(define (matrix-set! a i j x) (vector-set! (vector-ref a i) j x)) + +(define (matrix-row-ref a i) (vector-ref a i)) + +(define (matrix-row-set! a i v) (vector-set! a i v)) + +(define (determinant a) + (if (not (= (matrix-rows a) (matrix-columns a))) + (panic "Can only find determinant of a square matrix")) + (call-with-current-continuation + (lambda (return) + (let* ((n (matrix-rows a)) + (b (make-matrix n n)) + (d 1.0)) + (do ((i 0 (+ i 1))) ((= i n)) + (do ((j 0 (+ j 1))) ((= j n)) (matrix-set! b i j (matrix-ref a i j)))) + (do ((i 0 (+ i 1))) ((= i n)) + ;; partial pivoting reduces rounding errors + (let ((greatest (abs (matrix-ref b i i))) + (index i)) + (do ((j (+ i 1) (+ j 1))) ((= j n)) + (let ((x (abs (matrix-ref b j i)))) + (if (> x greatest) (begin (set! index j) (set! greatest x))))) + (if (= greatest 0.0) (return 0.0)) + (if (not (= index i)) + (let ((v (matrix-row-ref b i))) + (matrix-row-set! b i (matrix-row-ref b index)) + (matrix-row-set! b index v) + (set! d (- d)))) + (let ((c (matrix-ref b i i))) + (set! d (* d c)) + (do ((j i (+ j 1))) ((= j n)) + (matrix-set! b i j (/ (matrix-ref b i j) c))) + (do ((j (+ i 1) (+ j 1))) ((= j n)) + (let ((e (matrix-ref b j i))) + (do ((k (+ i 1) (+ k 1))) ((= k n)) + (matrix-set! + b j k (- (matrix-ref b j k) (* e (matrix-ref b i k)))))))))) + d)))) + +(define (invert-matrix! a b) + (if (not (= (matrix-rows a) (matrix-columns a))) + (panic "Can only invert a square matrix")) + (let* ((n (matrix-rows a)) + (c (make-matrix n n))) + (do ((i 0 (+ i 1))) ((= i n)) + (do ((j 0 (+ j 1))) ((= j n)) + (matrix-set! b i j 0.0) + (matrix-set! c i j (matrix-ref a i j)))) + (do ((i 0 (+ i 1))) ((= i n)) (matrix-set! b i i 1.0)) + (do ((i 0 (+ i 1))) ((= i n)) + (if (zero? (matrix-ref c i i)) + (call-with-current-continuation + (lambda (return) + (do ((j 0 (+ j 1))) ((= j n)) + (if (and (> j i) (not (zero? (matrix-ref c j i)))) + (begin + (let ((e (vector-ref c i))) + (vector-set! c i (vector-ref c j)) + (vector-set! c j e)) + (let ((e (vector-ref b i))) + (vector-set! b i (vector-ref b j)) + (vector-set! b j e)) + (return #f)))) + (panic "Matrix is singular")))) + (let ((d (/ (matrix-ref c i i)))) + (do ((j 0 (+ j 1))) ((= j n)) + (matrix-set! c i j (* d (matrix-ref c i j))) + (matrix-set! b i j (* d (matrix-ref b i j)))) + (do ((k 0 (+ k 1))) ((= k n)) + (let ((d (- (matrix-ref c k i)))) + (if (not (= k i)) + (do ((j 0 (+ j 1))) ((= j n)) + (matrix-set! + c k j (+ (matrix-ref c k j) (* d (matrix-ref c i j)))) + (matrix-set! + b k j (+ (matrix-ref b k j) (* d (matrix-ref b i j)))))))))))) + +(define (jacobi! a) + (if (not (and (= (matrix-rows a) (matrix-columns a)) + (every-n (lambda (i) + (every-n (lambda (j) + (= (matrix-ref a i j) (matrix-ref a j i))) + (matrix-rows a))) + (matrix-rows a)))) + (panic "Can only compute eigenvalues/eigenvectors of a symmetric matrix")) + (let* ((n (matrix-rows a)) + (d (make-vector n)) + (v (make-matrix-initial n n 0.0)) + (b (make-vector n)) + (z (make-vector n 0.0))) + (do ((ip 0 (+ ip 1))) ((= ip n)) + (matrix-set! v ip ip 1.0) + (vector-set! b ip (matrix-ref a ip ip)) + (vector-set! d ip (matrix-ref a ip ip))) + (let loop ((i 0)) + (if (> i 50) (panic "Too many iterations in JACOBI!")) + (let ((sm (sum (lambda (ip) + (sum (lambda (ir) + (let ((iq (+ ip ir 1))) + (abs (matrix-ref a ip iq)))) + (- n ip 1))) + (- n 1)))) + (if (not (zero? sm)) + (begin + (let ((tresh (if (< i 3) (/ (* 0.2 sm) (* n n)) 0.0))) + (do ((ip 0 (+ ip 1))) ((= ip (- n 1))) + (do ((ir 0 (+ ir 1))) ((= ir (- n ip 1))) + (let* ((iq (+ ip ir 1)) + (g (* 100.0 (abs (matrix-ref a ip iq))))) + (cond + ((and (> i 3) + (= (+ (abs (vector-ref d ip)) g) + (abs (vector-ref d ip))) + (= (+ (abs (vector-ref d iq)) g) + (abs (vector-ref d iq)))) + (matrix-set! a ip iq 0.0)) + ((> (abs (matrix-ref a ip iq)) tresh) + (let* ((h (- (vector-ref d iq) (vector-ref d ip))) + (t (if (= (+ (abs h) g) (abs h)) + (/ (matrix-ref a ip iq) h) + (let ((theta (/ (* 0.5 h) + (matrix-ref a ip iq)))) + (if (negative? theta) + (- (/ (+ (abs theta) + (sqrt (+ (* theta theta) 1.0))))) + (/ (+ (abs theta) + (sqrt (+ (* theta theta) 1.0)))))))) + (c (/ (sqrt (+ (* t t) 1.0)))) + (s (* t c)) + (tau (/ s (+ c 1.0))) + (h (* t (matrix-ref a ip iq)))) + (define (rotate a i j k l) + (let ((g (matrix-ref a i j)) + (h (matrix-ref a k l))) + (matrix-set! a i j (- g (* s (+ h (* g tau))))) + (matrix-set! a k l (+ h (* s (- g (* h tau))))))) + (vector-set! z ip (- (vector-ref z ip) h)) + (vector-set! z iq (+ (vector-ref z iq) h)) + (vector-set! d ip (- (vector-ref d ip) h)) + (vector-set! d iq (+ (vector-ref d iq) h)) + (matrix-set! a ip iq 0.0) + (do ((j 0 (+ j 1))) ((= j n)) + (cond ((< j ip) (rotate a j ip j iq)) + ((< ip j iq) (rotate a ip j j iq)) + ((< iq j) (rotate a ip j iq j))) + (rotate v j ip j iq))))))))) + (do ((ip 0 (+ ip 1))) ((= ip n)) + (vector-set! b ip (+ (vector-ref b ip) (vector-ref z ip))) + (vector-set! d ip (vector-ref b ip)) + (vector-set! z ip 0.0)) + (loop (+ i 1)))))) + (do ((i 0 (+ i 1))) ((= i (- n 1))) + (let ((k i) + (p (vector-ref d i))) + (do ((l 0 (+ l 1))) ((= l (- n i 1))) + (let* ((j (+ i l 1))) + (if (>= (vector-ref d j) p) + (begin (set! k j) (set! p (vector-ref d j)))))) + (if (not (= k i)) + (begin (vector-set! d k (vector-ref d i)) + (vector-set! d i p) + (do ((j 0 (+ j 1))) ((= j n)) + (let ((p (matrix-ref v j i))) + (matrix-set! v j i (matrix-ref v j k)) + (matrix-set! v j k p))))))) + (list d v))) + +(define (clip-eigenvalues! a v) + (let* ((j (jacobi! a)) + (l (first j)) + (e (second j))) + (do ((k1 0 (+ k1 1))) ((= k1 (vector-length a))) + (let ((a-k1 (vector-ref a k1)) + (e-k1 (vector-ref e k1))) + (do ((k2 0 (+ k2 1))) ((= k2 (vector-length a-k1))) + (let ((e-k2 (vector-ref e k2)) + (s 0.0)) + (do ((k 0 (+ k 1))) ((= k (vector-length a))) + (set! s (+ s (* (max (vector-ref v k) (vector-ref l k)) + (vector-ref e-k1 k) + (vector-ref e-k2 k))))) + (vector-set! a-k1 k2 s))))))) + +;;; EM + +(define (e-step! x z models) + (do ((i 0 (+ i 1))) ((= i (vector-length x))) + (let ((xi (vector-ref x i)) + (zi (vector-ref z i))) + (do ((j 0 (+ j 1))) ((= j (vector-length models))) + ;; Compute for each model. + (let* ((model (vector-ref models j)) + (log-pi (model-log-pi model)) + (mu (model-mu model)) + (sigma-inverse (model-sigma-inverse model)) + (log-determinant-sigma (model-log-determinant-sigma model)) + (t 0.0)) + ;; Compute likelihoods (note: up to constant for all models). + (set! t 0.0) + (do ((k1 0 (+ k1 1))) ((= k1 (vector-length xi))) + (let ((sigma-inverse-k1 (vector-ref sigma-inverse k1))) + (do ((k2 0 (+ k2 1))) ((= k2 (vector-length xi))) + (set! t (+ t (* (- (vector-ref xi k1) (vector-ref mu k1)) + (vector-ref sigma-inverse-k1 k2) + (- (vector-ref xi k2) (vector-ref mu k2)))))))) + (vector-set! zi j (- log-pi (* 0.5 (+ log-determinant-sigma t)))))))) + (let ((l 0.0)) + (do ((i 0 (+ i 1))) ((= i (vector-length x))) + (let ((s minus-infinity) + (zi (vector-ref z i))) + ;; Normalize ownerships to sum to one. + (do ((j 0 (+ j 1))) ((= j (vector-length models))) + (set! s (add-exp s (vector-ref zi j)))) + (do ((j 0 (+ j 1))) ((= j (vector-length models))) + (vector-set! zi j (exp (- (vector-ref zi j) s)))) + (set! l (+ l s)))) + ;; Return log likelihood. + l)) + +(define (m-step! x models z clip) + (let ((kk (vector-length (vector-ref x 0)))) + ;; For each model, optimize parameters. + (do ((j 0 (+ j 1))) ((= j (vector-length models))) + (let* ((model (vector-ref models j)) + (mu (model-mu model)) + (sigma (model-sigma model)) + (s 0.0)) + ;; Optimize values. + (do ((k 0 (+ k 1))) ((= k kk)) + (do ((i 0 (+ i 1))) ((= i (vector-length x))) + (set! s (+ s (vector-ref (vector-ref z i) j))))) + (do ((k 0 (+ k 1))) ((= k kk)) + (let ((m 0.0)) + (do ((i 0 (+ i 1))) ((= i (vector-length x))) + (set! m (+ m (* (vector-ref (vector-ref z i) j) + (vector-ref (vector-ref x i) k))))) + (vector-set! mu k (/ m s)))) + (do ((k1 0 (+ k1 1))) ((= k1 kk)) + (let ((sigma-k1 (vector-ref sigma k1)) + (mu-k1 (vector-ref mu k1))) + (do ((k2 0 (+ k2 1))) ((= k2 kk)) + (let ((mu-k2 (vector-ref mu k2)) + (m 0.0)) + (do ((i 0 (+ i 1))) ((= i (vector-length x))) + (set! m (+ m (* (vector-ref (vector-ref z i) j) + (- (vector-ref (vector-ref x i) k1) mu-k1) + (- (vector-ref (vector-ref x i) k2) mu-k2))))) + (vector-set! sigma-k1 k2 (/ m s)))))) + (clip-eigenvalues! sigma clip) + (set-model-pi! model (/ s (vector-length x))) + (set-model-log-pi! model (log (/ s (vector-length x)))) + (invert-matrix! sigma (model-sigma-inverse model)) + (set-model-log-sigma-determinant! model (log (determinant sigma))))))) + +(define (em! x z models clip em-kick-off-tolerance em-convergence-tolerance) + (let loop ((old-log-likelihood minus-infinity) (starting? #t)) + (let ((log-likelihood (e-step! x z models))) + (cond + ((or (and starting? (> log-likelihood old-log-likelihood)) + (> log-likelihood (+ old-log-likelihood em-convergence-tolerance))) + (m-step! x models z clip) + (loop log-likelihood + (and starting? + (not (= (vector-length models) 1)) + (or (= old-log-likelihood minus-infinity) + (< log-likelihood + (+ old-log-likelihood em-kick-off-tolerance)))))) + (else old-log-likelihood))))) + +(define (noise epsilon) (- (* 2.0 epsilon (/ (rand) *rand-max*)) epsilon)) + +(define (initial-z ii jj) + (map-n-vector + (lambda (i) + (let ((zi (map-n-vector (lambda (j) (+ (/ jj) (noise (/ jj)))) jj)) + (s 0.0)) + (do ((j 0 (+ j 1))) ((= j jj)) (set! s (+ s (vector-ref zi j)))) + (do ((j 0 (+ j 1))) ((= j jj)) (vector-set! zi j (/ (vector-ref zi j) s))) + zi)) + ii)) + +(define (ems x clip em-kick-off-tolerance em-convergence-tolerance + ems-convergence-tolerance) + (let loop ((jj 1) + (old-z #f) + (old-models #f) + (old-log-likelihood minus-infinity)) + (let* ((kk (vector-length (vector-ref x 0))) + (z (initial-z (vector-length x) jj)) + (models (map-n-vector + (lambda (j) + (make-model 0.0 + (make-vector kk) + (make-matrix kk kk) + 0.0 + (make-matrix kk kk) + 0.0)) + jj))) + (m-step! x models z clip) + (let ((new-log-likelihood + (em! + x z models clip em-kick-off-tolerance em-convergence-tolerance))) + (if (> (- (/ old-log-likelihood new-log-likelihood) 1.0) + ems-convergence-tolerance) + (loop (+ jj 1) z models new-log-likelihood) + (list old-z old-models)))))) + +(define (em-clusterer x clip em-kick-off-tolerance em-convergence-tolerance + ems-convergence-tolerance) + (let* ((z-models (ems x clip em-kick-off-tolerance + em-convergence-tolerance + ems-convergence-tolerance)) + (z (first z-models)) + (models (second z-models))) + (e-step! x z models) + (let ((clusters + (map-n (lambda (i) + (let ((zi (vector->list (vector-ref z i)))) + (list i (positionv (reduce max zi minus-infinity) zi)))) + (vector-length z)))) + (map-n (lambda (j) + (map (lambda (cluster) (vector-ref x (first cluster))) + (remove-if-not (lambda (cluster) (= (second cluster) j)) + clusters))) + (vector-length (vector-ref z 0)))))) + +(define (go) + (em-clusterer + '#(#(1.0) #(2.0) #(3.0) #(11.0) #(12.0) #(13.0)) '#(1.0) 10.0 1.0 0.01)) + +(define (run-benchmark) + (srand 1) + (do ((i 0 (+ i 1))) ((= i 100)) + (write (go)) + (newline))) + +; eof + diff --git a/collects/tests/mzscheme/expand.ss b/collects/tests/mzscheme/expand.ss new file mode 100644 index 0000000..92ab7dd --- /dev/null +++ b/collects/tests/mzscheme/expand.ss @@ -0,0 +1,18 @@ + +; Tests macro expansion by setting the eval handler and +; running all tests + +(let ([orig (current-eval)]) + (dynamic-wind + (lambda () + (current-eval + (lambda (x) + (orig + (expand-defmacro + (expand-defmacro + (expand-defmacro-once + (expand-defmacro-once x)))))))) + (lambda () + (load-relative "all.ss")) + (lambda () + (current-eval orig)))) diff --git a/collects/tests/mzscheme/fact.ss b/collects/tests/mzscheme/fact.ss new file mode 100644 index 0000000..d991f2f --- /dev/null +++ b/collects/tests/mzscheme/fact.ss @@ -0,0 +1,6 @@ +(define fact + (lambda (n) + (let loop ([n n][res 1]) + (if (zero? n) + res + (loop (sub1 n) (* n res)))))) diff --git a/collects/tests/mzscheme/file.ss b/collects/tests/mzscheme/file.ss new file mode 100644 index 0000000..1cc70d1 --- /dev/null +++ b/collects/tests/mzscheme/file.ss @@ -0,0 +1,520 @@ + + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(define testing.ss (build-path (current-load-relative-directory) "testing.ss")) + +(SECTION 6 10 1) +(test #t input-port? (current-input-port)) +(test #t output-port? (current-output-port)) +(test #t output-port? (current-error-port)) +(test (void) current-input-port (current-input-port)) +(test (void) current-output-port (current-output-port)) +(test (void) current-error-port (current-error-port)) +(test #t call-with-input-file testing.ss input-port?) +(define this-file (open-input-file testing.ss)) +(test #t input-port? this-file) +(close-input-port this-file) +(define this-file (open-input-file testing.ss 'binary)) +(test #t input-port? this-file) +(close-input-port this-file) +(define this-file (open-input-file testing.ss 'text)) +(test #t input-port? this-file) +(arity-test input-port? 1 1) +(arity-test output-port? 1 1) +(arity-test current-input-port 0 1) +(arity-test current-output-port 0 1) +(arity-test current-error-port 0 1) +(error-test '(current-input-port 8)) +(error-test '(current-output-port 8)) +(error-test '(current-error-port 8)) +(error-test '(current-input-port (current-output-port))) +(error-test '(current-output-port (current-input-port))) +(error-test '(current-error-port (current-input-port))) +(SECTION 6 10 2) +(test #\; peek-char this-file) +(arity-test peek-char 0 1) +(test #\; read-char this-file) +(arity-test read-char 0 1) +(test '(define cur-section '()) read this-file) +(arity-test read 0 1) +(test #\( peek-char this-file) +(test '(define errs '()) read this-file) +(close-input-port this-file) +(close-input-port this-file) +(arity-test close-input-port 1 1) +(arity-test close-output-port 1 1) +(error-test '(peek-char 5)) +(error-test '(peek-char (current-output-port))) +(error-test '(read-char 5)) +(error-test '(read-char (current-output-port))) +(error-test '(read 5)) +(error-test '(read (current-output-port))) +(error-test '(close-input-port 5)) +(error-test '(close-output-port 5)) +(error-test '(close-input-port (current-output-port))) +(error-test '(close-output-port (current-input-port))) +(define (check-test-file name) + (define test-file (open-input-file name)) + (test #t 'input-port? + (call-with-input-file + name + (lambda (test-file) + (test load-test-obj read test-file) + (test #t eof-object? (peek-char test-file)) + (test #t eof-object? (read-char test-file)) + (input-port? test-file)))) + (test #\; read-char test-file) + (test display-test-obj read test-file) + (test load-test-obj read test-file) + (close-input-port test-file)) +(SECTION 6 10 3) +(define write-test-obj + '(#t #f #\a () 9739 -3 . #((test) "te \" \" st" "" test #() b c))) +(define display-test-obj + '(#t #f a () 9739 -3 . #((test) te " " st test #() b c))) +(define load-test-obj + (list 'define 'foo (list 'quote write-test-obj))) +(let ([f (lambda (test-file) + (write-char #\; test-file) + (display write-test-obj test-file) + (newline test-file) + (write load-test-obj test-file) + (output-port? test-file))]) + (test #t call-with-output-file + "tmp1" f 'truncate)) +(check-test-file "tmp1") + +(test (string #\null #\null #\" #\null #\") + 'write-null + (let ([p (open-output-string)]) + (write-char #\null p) + (display (string #\null) p) + (write (string #\null) p) + (let ([s (get-output-string p)]) + s))) + +(arity-test open-input-file 1 2) +(error-test '(open-input-file 8)) +(error-test '(open-input-file "x" 8)) +(error-test '(open-input-file "x" 'something-else)) +(error-test '(open-input-file "badfile") exn:i/o:filesystem:file?) + +(arity-test open-output-file 1 3) +(error-test '(open-output-file 8)) +(error-test '(open-output-file "x" 8)) +(error-test '(open-output-file "x" 'something-else)) +(let ([conflict? exn:application:mode-conflict?] + [modes '(binary text)] + [replacement '(error replace truncate append)]) + (for-each + (lambda (ones) + (for-each + (lambda (one) + (error-test `(open-output-file "x" ',one 'bad)) + (error-test `(open-output-file "x" ',one 8)) + (error-test `(open-output-file "x" 'bad ',one)) + (error-test `(open-output-file "x" 8 ',one)) + (error-test `(call-with-output-file "x" void ',one 'bad)) + (error-test `(call-with-output-file "x" void ',one 8)) + (error-test `(call-with-output-file "x" void 'bad ',one)) + (error-test `(call-with-output-file "x" void 8 ',one)) + (error-test `(with-output-to-file "x" void ',one 8)) + (error-test `(with-output-to-file "x" void ',one 'bad)) + (error-test `(with-output-to-file "x" void 8 ',one)) + (error-test `(with-output-to-file "x" void 'bad ',one)) + (for-each + (lambda (two) + (error-test `(open-output-file "x" ',one ',two) conflict?) + (error-test `(call-with-output-file "x" void ',one ',two) conflict?) + (error-test `(with-output-to-file "x" void ',one ',two) conflict?)) + ones)) + ones)) + `(,modes ,replacement))) +(error-test '(open-output-file (build-path (current-directory) "baddir" "x")) + exn:i/o:filesystem:file?) + +(delete-file "tmp4") +(close-output-port (open-output-file "tmp4")) +(error-test '(let ([c (make-custodian)]) + (let ([p (parameterize ([current-custodian c]) + (open-output-file "tmp4" 'replace))]) + (custodian-shutdown-all c) + (display 'hi p))) + exn:i/o:port-closed?) +(error-test '(open-output-file "tmp4" 'error) exn:i/o:filesystem:file-exists?) +(define p (open-output-file "tmp4" 'replace)) +(display 7 p) +(display "" p) +(close-output-port p) +(close-output-port (open-output-file "tmp4" 'truncate)) +(define p (open-input-file "tmp4")) +(test eof read p) +(close-input-port p) +(define p (open-output-file "tmp4" 'replace)) +(display 7 p) +(close-output-port p) +(define p (open-output-file "tmp4" 'append)) +(display 7 p) +(close-output-port p) +(error-test '(display 9 p) exn:i/o:port-closed?) +(error-test '(write 9 p) exn:i/o:port-closed?) +(error-test '(write-char #\a p) exn:i/o:port-closed?) + +(error-test '(let ([c (make-custodian)]) + (let ([p (parameterize ([current-custodian c]) + (open-input-file "tmp4"))]) + (custodian-shutdown-all c) + (read p))) + exn:i/o:port-closed?) +(define p (open-input-file "tmp4")) +(test 77 read p) +(close-input-port p) +(error-test '(read p) exn:i/o:port-closed?) +(error-test '(read-char p) exn:i/o:port-closed?) +(error-test '(char-ready? p) exn:i/o:port-closed?) + +(arity-test call-with-input-file 2 3) +(arity-test call-with-output-file 2 4) +(arity-test with-input-from-file 2 3) +(arity-test with-output-to-file 2 4) + +(error-test '(call-with-input-file "x" 8)) +(error-test '(call-with-input-file 8 (lambda (x) x))) +(error-test '(call-with-input-file 8 (lambda () 9))) +(error-test '(call-with-input-file "x" (lambda (x) x) 8)) +(error-test '(call-with-input-file "x" (lambda (x) x) 'bad)) + +(error-test '(call-with-output-file "x" 8)) +(error-test '(call-with-output-file 8 (lambda (x) x))) +(error-test '(call-with-output-file 8 (lambda () 9))) +(error-test '(call-with-output-file "x" (lambda (x) x) 8)) +(error-test '(call-with-output-file "x" (lambda (x) x) 'bad)) + +(error-test '(with-input-from-file "x" 8)) +(error-test '(with-input-from-file 8 (lambda () 9))) +(error-test '(with-input-from-file 8 (lambda (x) x))) +(error-test '(with-input-from-file "x" (lambda () 9) 8)) +(error-test '(with-input-from-file "x" (lambda () 9) 'bad)) + +(error-test '(with-output-to-file "x" 8)) +(error-test '(with-output-to-file 8 (lambda () 9))) +(error-test '(with-output-to-file 8 (lambda (x) x))) +(error-test '(with-output-to-file "x" (lambda () 9) 8)) +(error-test '(with-output-to-file "x" (lambda () 9) 'bad)) + +(define s (open-output-string)) +(test #f input-port? s) +(test #t output-port? s) +(let ([c (current-output-port)]) + (current-output-port s) + (display 8) + (current-output-port c)) +(test "8" get-output-string s) +(let ([c (current-error-port)]) + (current-error-port s) + (display 9 (current-error-port)) + (current-error-port c)) +(test "89" get-output-string s) +(define s (open-input-string (get-output-string s))) +(test #t input-port? s) +(test #f output-port? s) +(test 89 + 0 + (let ([c (current-input-port)]) + (current-input-port s) + (begin0 + (read) + (current-input-port c)))) +(test eof read s) + +(arity-test open-output-string 0 0) +(arity-test open-input-string 1 1) +(arity-test get-output-string 1 1) + +(error-test '(get-output-string 9)) +(error-test '(get-output-string (current-output-port))) + +(define-values (out in) (make-pipe)) +(test #t input-port? out) +(test #t output-port? in) +(let loop ([n 1000]) + (unless (zero? n) + (display n in) + (newline in) + (loop (sub1 n)))) +(let loop ([n 999]) + (unless (zero? n) + (read out) + (loop (sub1 n)))) +(test 1 read out) +(close-output-port in) +(test eof read out) +(close-input-port out) +(arity-test make-pipe 0 0) + +(test #t input-port? (make-input-port void void void)) +(error-test '(read (make-input-port void void void)) + exn:i/o:user-port?) +(arity-test make-input-port 3 3) +(error-test '(make-input-port 8 void void)) +(error-test '(make-input-port void 8 void)) +(error-test '(make-input-port void void 8)) +(error-test '(make-input-port add1 void void)) +(error-test '(make-input-port void add1 void)) +(error-test '(make-input-port void void add1)) + +(test #t output-port? (make-output-port void void)) +(arity-test make-output-port 2 2) +(error-test '(make-output-port 8 void)) +(error-test '(make-output-port void 8)) +(error-test '(make-output-port (lambda () 9) void)) +(error-test '(make-output-port void add1)) + +(define test-file + (open-output-file "tmp2" 'truncate)) +(write-char #\; test-file) +(display write-test-obj test-file) +(newline test-file) +(write load-test-obj test-file) +(test #t output-port? test-file) +(close-output-port test-file) +(check-test-file "tmp2") + +(define ui (make-input-port (lambda () #\") (lambda () #t) void)) +(test "" read ui) +(arity-test (port-read-handler ui) 1 1) +(error-test '((port-read-handler ui) 8)) +(let ([old (port-read-handler ui)]) + (port-read-handler ui (lambda (x) "hello")) + (test "hello" read ui) + (port-read-handler ui old) + (test "" read ui)) +(arity-test port-read-handler 1 2) +(error-test '(port-read-handler 1)) +(error-test '(port-read-handler ui 8)) +(error-test '(port-read-handler (current-output-port) 8)) +(error-test '(port-read-handler ui (lambda () 9))) +(error-test '(port-read-handler ui (lambda (x y) 9))) + +(define sp (open-output-string)) +(test (void) display "hello" sp) +(test "hello" get-output-string sp) +(test (void) write "hello" sp) +(test "hello\"hello\"" get-output-string sp) +(arity-test (port-display-handler sp) 2 2) +(arity-test (port-write-handler sp) 2 2) +(arity-test (port-print-handler sp) 2 2) +(error-test '((port-display-handler sp) 8 8)) +(error-test '((port-write-handler sp) 8 8)) +(error-test '((port-print-handler sp) 8 8)) +(let ([oldd (port-display-handler sp)] + [oldw (port-write-handler sp)] + [oldp (port-print-handler sp)] + [adding (let ([s "hello\"hello\""]) + (lambda (a) + (set! s (string-append s a)) + s))]) + (port-display-handler sp (lambda (v p) (oldd "X" p) (values 1 2))) + (test (void) display "hello" sp) + (test (adding "X") get-output-string sp) + (test (void) write "hello" sp) + (test (adding "\"hello\"") get-output-string sp) + (test (void) print "hello" sp) + (test (adding "\"hello\"") get-output-string sp) + + (port-write-handler sp (lambda (v p) (oldd "Y" p) 5)) + (test (void) display "hello" sp) + (test (adding "X") get-output-string sp) + (test (void) write "hello" sp) + (test (adding "Y") get-output-string sp) + (test (void) print "hello" sp) + (test (adding "\"hello\"") get-output-string sp) + (parameterize ([global-port-print-handler display]) + (test (void) print "hello" sp) + (test (adding "X") get-output-string sp)) + (parameterize ([global-port-print-handler oldd]) + (test (void) print "hello" sp) + (test (adding "hello") get-output-string sp)) + (test (void) print "hello" sp) + (test (adding "\"hello\"") get-output-string sp) + + + (port-print-handler sp (lambda (v p) (oldd "Z" p) 5)) + (test (void) display "hello" sp) + (test (adding "X") get-output-string sp) + (test (void) write "hello" sp) + (test (adding "Y") get-output-string sp) + (test (void) print "hello" sp) + (test (adding "Z") get-output-string sp) + (parameterize ([global-port-print-handler display]) + (test (void) print "hello" sp) + (test (adding "Z") get-output-string sp)) + (test (void) print "hello" sp) + (test (adding "Z") get-output-string sp) + + (port-display-handler sp oldd) + (test (void) display "hello" sp) + (test (adding "hello") get-output-string sp) + (test (void) write "hello" sp) + (test (adding "Y") get-output-string sp) + + (port-write-handler sp oldw) + (test (void) display "hello" sp) + (test (adding "hello") get-output-string sp) + (test (void) write "hello" sp) + (test (adding "\"hello\"") get-output-string sp) + + (port-display-handler sp oldw) + (port-write-handler sp oldd) + (port-print-handler sp oldp) + (test (void) display "hello" sp) + (test (adding "\"hello\"") get-output-string sp) + (test (void) write "hello" sp) + (test (adding "hello") get-output-string sp) + (test (void) print "goodbye" sp) + (test (adding "\"goodbye\"") get-output-string sp) + (port-display-handler sp oldd) + (port-write-handler sp oldw)) +(error-test '(port-display-handler 1)) +(error-test '(port-display-handler sp 8)) +(error-test '(port-display-handler (current-input-port) 8)) +(error-test '(port-display-handler sp (lambda (x) 9))) +(error-test '(port-display-handler sp (lambda (x y z) 9))) +(error-test '(port-write-handler 1)) +(error-test '(port-write-handler sp 8)) +(error-test '(port-write-handler (current-input-port) 8)) +(error-test '(port-write-handler sp (lambda (x) 9))) +(error-test '(port-write-handler sp (lambda (x y z) 9))) + +(SECTION 6 10 4) +(load "tmp1") +(test write-test-obj 'load foo) + +(SECTION 'INEXACT-I/IO) +(define wto write-test-obj) +(define dto display-test-obj) +(define lto load-test-obj) +(define f-3.25 (string->number "-3.25")) +(define f.25 (string->number ".25")) +(set! write-test-obj (list f.25 f-3.25));.25 inexact errors less likely. +(set! display-test-obj (list f.25 f-3.25));.3 often has such errors (~10^-13) +(set! load-test-obj (list 'define 'foo (list 'quote write-test-obj))) +(let ([f (lambda (test-file) + (write-char #\; test-file) + (display write-test-obj test-file) + (newline test-file) + (write load-test-obj test-file) + (output-port? test-file))]) + (test #t call-with-output-file + "tmp3" f 'truncate)) +(check-test-file "tmp3") +(set! write-test-obj wto) +(set! display-test-obj dto) +(set! load-test-obj lto) + +(define badc-range-start 0) +(define badc-range-end 255) + +(SECTION 'PRINTF) +(define (test-format format format-name) + (test "hello---~---there" format "~a---~~---~a" "hello" 'there) + (test "\"hello\"---~---there" format "~s---~~---~s" "hello" 'there) + (test "\"hello\"---~---there" format "~v---~~---~v" "hello" 'there) + (test (string #\a #\newline #\b #\newline #\c) format "a~nb~%c") + (let ([try-newline-stuff + (lambda (newlines) + (test "12" format (apply string `(#\1 #\~ #\space ,@newlines #\space #\2))) + (test "12" format (apply string `(#\1 #\~ ,@newlines #\space #\2))) + (test "12" format (apply string `(#\1 #\~ ,@newlines #\2))) + (test (apply string `(#\1 ,@newlines #\2)) + format (apply string `(#\1 #\~ ,@newlines #\space ,@newlines #\2))))]) + (for-each try-newline-stuff '((#\return) (#\newline) (#\return #\newline)))) + (test "twenty=20..." format "twenty=~s..." 20) + (test "twenty=20..." format "twenty=~v..." 20) + (test "twenty=20..." format "twenty=~e..." 20) + (test "twenty=14..." format "twenty=~x..." 20) + (test "twenty=24..." format "twenty=~o..." 20) + (test "twenty=10100..." format "twenty=~b..." 20) + (test "zee=z..." format "zee=~c..." #\z) + + (test #\. + (lambda (s) (string-ref s (sub1 (string-length s)))) + (parameterize ([error-print-width 40]) + (format "~e" #100(v)))) + + (begin + (define bads + (let loop ([i badc-range-end]) + (cond + [(eq? i badc-range-start) (list (integer->char i))] + [else (let ([c (integer->char i)] + [rest (loop (sub1 i))]) + (case c + [(#\~ #\% #\n #\a #\s #\c #\o #\x #\b #\v #\e + #\N #\A #\S #\C #\O #\X #\B #\V #\E) + rest] + [else (if (char-whitespace? c) + rest + (cons c rest))]))]))) + + (define with-censor (load-relative "censor.ss")) + + ; test for all bad tags; the string we generate shouldn't + ; be printed to a terminal directly because it can contain contain + ; control characters; censor it + (unless (defined? 'building-flat-tests) + (with-censor + (lambda () + (for-each (lambda (c) + (error-test `(,@format-name ,(format "a~~~cb" c) 0))) + bads))))) + + (error-test `(,@format-name 9)) + (error-test `(,@format-name "apple~")) + (error-test `(,@format-name "~o") exn:application:fprintf:no-argument?) + (error-test `(,@format-name "~o" 1 2) exn:application:fprintf:extra-arguments?) + (error-test `(,@format-name "~c" 1) exn:application:fprintf:argument-type?) + (error-test `(,@format-name "~x" 'a) exn:application:fprintf:argument-type?) + (error-test `(,@format-name "~x" 4.0) exn:application:fprintf:argument-type?) + (error-test `(,@format-name "~x" 5+4.0i) exn:application:fprintf:argument-type?)) + +(test-format format '(format)) +(test-format + (lambda args + (let ([p (open-output-string)]) + (apply fprintf p args) + (get-output-string p))) + '(fprintf (current-output-port))) +(test-format + (lambda args + (let ([p (open-output-string)]) + (parameterize ([current-output-port p]) + (apply printf args)) + (get-output-string p))) + '(printf)) + +(arity-test format 1 -1) +(arity-test printf 1 -1) +(arity-test fprintf 2 -1) + +(define success-1? (putenv "APPLE" "AnApple")) +(define success-2? (putenv "BANANA" "AnotherApple")) +(error-test `(getenv 7)) +(error-test `(getenv (string #\a #\nul #\b))) +(error-test `(putenv 7 "hi")) +(error-test `(putenv "hi" 7)) +(error-test `(putenv (string #\a #\nul #\b) "hi")) +(error-test `(putenv "hi" (string #\a #\nul #\b))) +(collect-garbage) +(unless (eq? (system-type) 'macos) + (test #t 'success-1 success-1?) + (test #t 'success-2 success-2?) + (test "AnApple" getenv "APPLE") + (test "AnotherApple" getenv "BANANA")) +(test #f getenv "AnUndefinedEnvironmentVariable") + +(arity-test getenv 1 1) +(arity-test putenv 2 2) + +(report-errs) diff --git a/collects/tests/mzscheme/fold.ss b/collects/tests/mzscheme/fold.ss new file mode 100644 index 0000000..8911ca0 --- /dev/null +++ b/collects/tests/mzscheme/fold.ss @@ -0,0 +1,46 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'function) + +(require-library "function.ss") + +(test (list 1 2 3 4) foldl cons '() (list 4 3 2 1)) +(test (list 1 2 3 4) foldr cons '() (list 1 2 3 4)) +(test + (list (list 5 6) (list 3 4) (list 1 2)) + foldl (lambda (x y sofar) (cons (list x y) sofar)) + '() + (list 1 3 5) + (list 2 4 6)) +(test + (list (list 1 2) (list 3 4) (list 5 6)) + foldr (lambda (x y sofar) (cons (list x y) sofar)) + '() + (list 1 3 5) + (list 2 4 6)) + +(arity-test foldl 3 -1) +(arity-test foldr 3 -1) + +(test 0 (compose add1 sub1) 0) +(test 2 (compose add1 (lambda () 1))) +(test 5 (compose (lambda (a b) a) (lambda (x) (values (add1 x) x))) 4) +(test -1 (compose (lambda (a b) (+ a b)) (lambda (x y) (values (- y) x))) 2 3) +(test 'hi (compose (case-lambda [(x) 'bye][(y z) 'hi]) (lambda () (values 1 2)))) +(test 'ok (compose (lambda () 'ok) (lambda () (values)))) +(test 'ok (compose (lambda () 'ok) (lambda (w) (values))) 5) +(test-values '(1 2 3) (lambda () ((compose (lambda (x) (values x (add1 x) (+ x 2))) (lambda (y) y)) 1))) + +(error-test '(compose 5)) +(error-test '(compose add1 sub1 5)) +(error-test '(compose add1 5 sub1)) +(error-test '(compose 5 add1 sub1)) +(error-test '((compose add1 (lambda () (values 1 2)))) exn:application:arity?) +(error-test '((compose add1 sub1)) exn:application:arity?) +(error-test '((compose (lambda () 1) add1) 8) exn:application:arity?) + +(arity-test compose 1 -1) + +(report-errs) diff --git a/collects/tests/mzscheme/hashper.ss b/collects/tests/mzscheme/hashper.ss new file mode 100644 index 0000000..a2822be --- /dev/null +++ b/collects/tests/mzscheme/hashper.ss @@ -0,0 +1,57 @@ +; Test suite to ensure #% objects are handled properly by MzRice. +; Report problems to Shriram Krishnamurthi . + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(define bad#%? + (if (defined? 'read/zodiac) + exn? + syntaxe?)) + +; Masking names shouldn't hurt the #% versions.. + +(define car 3) +(test 3 #%car (cons 3 2)) +(define car #%car) + +(let ((lambda 2)) + (test #t equal? 2 ((#%lambda (x) x) lambda))) + +; You can't mask the #% versions. + +(error-test '(define #%lambda 2) bad#%?) +(error-test '(set! #%lambda 2) bad#%?) + +; We allow random #% things to be set!'ed and define'd. + +(test #t equal? (void) (eval '(define #%foo 3))) +(test #t equal? 4 (begin (set! #%foo 4) #%foo)) + +; But you can't bind #% things either. + +(error-test '(let ((#%car 3)) 3) syntaxe?) +(error-test '(let ((#%lambda 3)) 3) syntaxe?) + +; Let's try out all #% syntax to make sure it's immune. (We'll skip +; the macro stuff.) + +(map (lambda (s) + (error-test `(define ,s 3) bad#%?) + (error-test `(set! ,s 3) bad#%?)) + '(#%lambda #%let-values #%letrec*-values #%define-values #%quote + #%if #%begin #%set! #%begin0 #%case-lambda #%struct)) + +; And a few primitives, for good measure. + +(map (lambda (s) + (error-test `(define ,s 3) bad#%?) + (error-test `(set! ,s 3) bad#%?)) + '(#%car #%cdr #%cons)) + +(newline) +(newline) + +; (printf "Done with #% test suite!~n~n") + +(report-errs) diff --git a/collects/tests/mzscheme/image.ss b/collects/tests/mzscheme/image.ss new file mode 100644 index 0000000..41219f0 --- /dev/null +++ b/collects/tests/mzscheme/image.ss @@ -0,0 +1,32 @@ + +; Tests image saving/loading by dumping an image +; and loading it with every report-errs + +(define dump/restore + (lambda () + (printf "Dumping image...~n") + (let ([result (write-image-to-file "tmp9")]) + (if (vector? result) + (printf "Continuing ~a~n" result) + (read-image-from-file "tmp9" #("after" "restore")))))) + +(define ll null) +(define load-relative + (lambda (f) + (set! ll (append ll (list f))))) + +(#%load-relative "all.ss") + +(define load-relative #%load-relative) + +(define go + (let ([d (current-load-relative-directory)]) + (lambda () + (parameterize ([current-load-relative-directory d]) + (for-each + (lambda (f) + (load-relative f) + (dump/restore)) + ll))))) + +(printf "Run `(go)'~n") diff --git a/collects/tests/mzscheme/ktest.ss b/collects/tests/mzscheme/ktest.ss new file mode 100644 index 0000000..86d2d0d --- /dev/null +++ b/collects/tests/mzscheme/ktest.ss @@ -0,0 +1,11 @@ +(define k + (call-with-current-continuation + (lambda (exit) + (let loop ((n 60000)) + (if (zero? n) + (let ((v (call-with-current-continuation (lambda (k) k)))) + (if (number? v) + v + (exit v))) + (- (loop (- n 1)) 1)))))) + diff --git a/collects/tests/mzscheme/loadable.ss b/collects/tests/mzscheme/loadable.ss new file mode 100644 index 0000000..eb943a3 --- /dev/null +++ b/collects/tests/mzscheme/loadable.ss @@ -0,0 +1 @@ +"This is a simple file used by param.ss" diff --git a/collects/tests/mzscheme/loop.ss b/collects/tests/mzscheme/loop.ss new file mode 100644 index 0000000..18fde59 --- /dev/null +++ b/collects/tests/mzscheme/loop.ss @@ -0,0 +1,29 @@ + + +(define five +) + +(define (one v) + (if (equal? v 15) + (apply five (list 1 2 3 4 5)) + 15)) + +(define (dloop x d) + (if (zero? d) + 0 + (if (equal? x 15) + (let ([v (one 10)]) + (let ([c (one v)]) + (add1 (dloop c (sub1 d))))) + (dloop 15 d)))) + +(define (loop) + (let loop ([n 0]) + (let ([v (dloop 0 n)]) + (if (equal? n v) + (begin + (when (zero? (modulo n 100)) + (printf "~a~n" n)) + (loop (add1 n))) + (error 'loop "messed up: ~a != ~a~n" n v))))) + + diff --git a/collects/tests/mzscheme/ltest.ss b/collects/tests/mzscheme/ltest.ss new file mode 100644 index 0000000..5765a97 --- /dev/null +++ b/collects/tests/mzscheme/ltest.ss @@ -0,0 +1,88 @@ +(printf "nested loop~n") +(time + (let loop ([n 10000]) + (unless (zero? n) + (let loop2 ([m 10]) + (if (zero? m) + (loop (sub1 n)) + (loop2 (sub1 m))))))) + +(printf "single loop~n") +(time + (let loop ([n 100000]) + (unless (zero? n) + (loop (sub1 n))))) + +(printf "Y loop~n") +(time + ((lambda (f n) (f f n)) + (lambda (loop n) + (unless (zero? n) + (loop loop (sub1 n)))) + 100000)) + + +(printf "let closure recur~n") +(time + (let ([f (lambda (x) (sub1 x))]) + (let loop ([n 100000]) + (unless (zero? n) + (loop (f n)))))) + +(printf "direct closure recur~n") +(time + (let loop ([n 100000]) + (unless (zero? n) + (loop ((lambda (x) (sub1 x)) n))))) + +(printf "direct closure recur if~n") +(time + (let loop ([n 100000]) + (if (zero? n) + (void) + (loop ((lambda (x) (sub1 x)) n))))) + +(printf "let closure top-level~n") +(define loop + (let ([f (lambda (x) (sub1 x))]) + (lambda (n) + (unless (zero? n) + (loop (f n)))))) +(time (loop 100000)) + +(printf "direct closure top-level~n") +(define loop + (lambda (n) + (unless (zero? n) + (loop ((lambda (x) (sub1 x)) n))))) +(time (loop 100000)) + + +; > (load "ltest.ss") +; cpu time: 1820 real time: 1826 +; cpu time: 1420 real time: 1422 +; cpu time: 1960 real time: 1957 +; cpu time: 2630 real time: 2626 +; > (load "ltest.ss") +; cpu time: 1790 real time: 1803 +; cpu time: 1430 real time: 1468 +; cpu time: 2150 real time: 2159 +; cpu time: 2820 real time: 2824 + +; > (load "ltest.ss") +; nested loop +; cpu time: 1750 real time: 1817 +; single loop +; cpu time: 1430 real time: 1425 +; Y loop +; cpu time: 1500 real time: 1500 +; let closure recur +; cpu time: 1830 real time: 1835 +; direct closure recur +; cpu time: 1790 real time: 1791 +; direct closure recur if +; cpu time: 1800 real time: 1793 +; let closure top-level +; cpu time: 1810 real time: 1804 +; direct closure top-level +; cpu time: 1760 real time: 1758 diff --git a/collects/tests/mzscheme/macro.ss b/collects/tests/mzscheme/macro.ss new file mode 100644 index 0000000..3b752ff --- /dev/null +++ b/collects/tests/mzscheme/macro.ss @@ -0,0 +1,35 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + + +(SECTION 'MACRO) + +(define-macro mx + (lambda (x) + (list x 1 8))) +(test 9 'macro (mx +)) +(test -7 'macro (mx -)) +(test 18 'macro (let ([mx (lambda (x) (x 1 8 9))]) (mx +))) +(when (defined? 'let-macro) + (teval '(test 13 'let-macro (let-macro mx (lambda (x) (list x 6 7)) (mx +)))) + (teval '(test -7 'let-macro (let-macro mx2 (lambda (x y) (list 'mx y)) (mx2 + -)))) + (teval '(test '(10) 'let-macro ((lambda () (let-macro x (lambda x (cons 'list x)) (x 10)))))) + (teval '(test '(10) 'let-macro (let () (define-macro x (lambda x (cons 'list x))) (x 10)))) + ; (test '(10) eval '((lambda () (define-macro x (lambda x (cons 'list x))) (x 10)))) + ) + +(define a-global-var 1) +(define-macro a-macro (lambda () a-global-var)) +(test 1 'macro (a-macro)) + +(when (defined? 'let-macro) + (teval '(define (defmacro-test) + (define-macro define-alias (lambda (x y) `(define ,x ,y))) + (test 45 'define + (let ((x 5)) + (define-alias foo (lambda (y) (bar x y))) + (define-alias bar (lambda (a b) (+ (* a b) a))) + (foo (+ x 3))))))) + +(report-errs) diff --git a/collects/tests/mzscheme/macrolib.ss b/collects/tests/mzscheme/macrolib.ss new file mode 100644 index 0000000..c247e6d --- /dev/null +++ b/collects/tests/mzscheme/macrolib.ss @@ -0,0 +1,72 @@ + +(if (not (defined? 'SECTION)) + (load "testing.ss")) + +(SECTION 'macrolib) + +(require-library "macro.ss") + +(let ([u (letrec ([x x]) x)]) + (let ([l1 + (let+ ([rec a a] + [recs [b c] [c b]] + [rec d 1] + [val e 1] + [val x 1] + [val y 2] + [vals (x y) (y x)] + [rec (values f) (values 1)] + [vals [(values g h) (values 2 3)]] + [val i 3] + [_ (set! i 4) + (set! i 5)]) + 'x + (list a b c d e x y f g h i))] + [l2 (list u u u 1 1 2 1 1 2 3 5)]) + (test l1 'let-plus l2))) + +(require-library "shared.ss") + +(test "((car . cdr) #(one two three four five six) #&box (list1 list2 list3 list4) # 3 3)" + 'shared + (let ([s (open-output-string)]) + (display + (shared ((a (cons 'car 'cdr)) + (b (vector 'one 'two 'three 'four 'five 'six)) + (c (box 'box)) + (d (list 'list1 'list2 'list3 'list4)) + (e (make-weak-box 'weak-box)) + (f (+ 1 2)) + (g 3)) + (list a b c d e f g)) + s) + (get-output-string s))) + +(define x 7) +(test 6 'local (local ((define x 6)) x)) +(test 7 'local x) +(test 6 vector-ref (struct->vector (local ((define x 6) (define-struct a (b))) (make-a x))) 1) +(test #t 'local (local [(define o (lambda (x) (if (zero? x) #f (e (sub1 x))))) + (define e (lambda (x) (if (zero? x) #t (o (sub1 x)))))] + (e 10))) +(test 'second 'local (local ((define x 10) (define u 'second)) (cons x 1) u)) +(test-values '(4 6) (lambda () (local ((define y 6) (define x 4)) (values x y)))) +(test 10 'local (let ([x 10]) (local ((define y (lambda () x))) (define x 5) (y)))) +(test 5 'local (let ([x 10]) (local ((define y (lambda () x))) (define x 5) x))) +(test 8 'local (local [(define lambda 8)] lambda)) +(test 9 'local (local [(define lambda 9) (define lambda2 lambda)] lambda2)) +(test 1 'local (local ((define-values (a b c) (values 1 2 3))) a)) +(test 1 (lambda () (local ((define-values (a b c) (values 1 2 3))) a))) +(syntax-test '(local)) +(syntax-test '(local . 1)) +(syntax-test '(local ())) +(syntax-test '(local () . 1)) +(syntax-test '(local 1 1)) +(syntax-test '(local (1) 1)) +(syntax-test '(local (x) 1)) +(syntax-test '(local ((+ 1 2)) 1)) +(syntax-test '(local ((define x)) 1)) +(syntax-test '(local ((define x 4) (+ 1 2)) 1)) +(syntax-test '(local ((define x 4) (+ 1 2) (define y 10)) 1)) + +(report-errs) diff --git a/collects/tests/mzscheme/makeflat.ss b/collects/tests/mzscheme/makeflat.ss new file mode 100644 index 0000000..bf20fdc --- /dev/null +++ b/collects/tests/mzscheme/makeflat.ss @@ -0,0 +1,60 @@ + +(unless (defined? 'flat-load) + (define flat-load "all.ss")) +(unless (defined? 'lines-per-file) + (define lines-per-file +inf.0)) + +(require-library "pretty.ss") + + +(define line-count 0) +(define file-count 0) + +(define flatp (open-output-file "flat.ss" 'replace)) +(define old-eval (current-eval)) +(define old-namespace (current-namespace)) + +(pretty-print '(define error-test void) flatp) +(pretty-print '(define building-flat-tests #t) flatp) +(pretty-print '(define section #f) flatp) + +(define (flat-pp v) + (pretty-print v flatp) + (set! line-count (add1 line-count)) + (when (>= line-count lines-per-file) + (set! line-count 0) + (set! file-count (add1 file-count)) + (close-output-port flatp) + (set! flatp + (open-output-file + (format "flat~a.ss" file-count) + 'replace)))) + +(define error-test + (case-lambda + [(expr) (error-test expr #f)] + [(expr exn?) + (unless (eq? exn? exn:syntax?) + (flat-pp `(thunk-error-test (lambda () ,expr) + (quote ,expr) + ,@(if exn? + (list (string->symbol + (primitive-name + exn?))) + null))))])) + +(define building-flat-tests #t) + +(dynamic-wind + (lambda () + (current-eval + (lambda (e) + (unless (or (and (pair? e) + (memq (car e) '(load load-relative error-test))) + (not (eq? (current-namespace) old-namespace))) + (flat-pp e)) + (old-eval e)))) + (lambda () + (load flat-load)) + (lambda () + (current-eval old-eval))) diff --git a/collects/tests/mzscheme/mzlib.ss b/collects/tests/mzscheme/mzlib.ss new file mode 100644 index 0000000..839e909 --- /dev/null +++ b/collects/tests/mzscheme/mzlib.ss @@ -0,0 +1,29 @@ + +; Test MzLib +; See also pptest.ss and ztest.ss + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +; Should be named "function" instead: +(load-relative "fold.ss") + +(load-relative "date.ss") + +(load-relative "cmdline.ss") + +(load-relative "pconvert.ss") + +; Last - so macros are not present by accident +(load-relative "macrolib.ss") + +(require-library "core.ss") +(test #t 'invoke-core-in-#%-space + (begin + (let ([l (require-library "corer.ss")]) + (parameterize ([current-namespace (make-namespace 'hash-percent-syntax)]) + (invoke-unit/sig l))) + #t)) + + +(report-errs) diff --git a/collects/tests/mzscheme/mzthr.ss b/collects/tests/mzscheme/mzthr.ss new file mode 100644 index 0000000..844710d --- /dev/null +++ b/collects/tests/mzscheme/mzthr.ss @@ -0,0 +1,75 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'mzlib-threads) + +(require-library "thread.ss") + +(define sema (make-semaphore)) +(define sema2 (make-semaphore)) +(define c-out 0) +(define SLEEP-TIME 0.1) + +;;; consumer-thread ;;; + +(define-values (th g) (consumer-thread (case-lambda + [(f arg) (set! c-out (f arg)) + (semaphore-post sema)] + [(f arg1 arg2) (set! c-out (f arg1 arg2)) + (semaphore-post sema)]))) +(g + 1 2) +(semaphore-wait sema) +(test 3 'consumer-thread c-out) + +; queue 2 +(g car '(4 5)) +(g semaphore-wait sema2) +(semaphore-wait sema) +(test 4 'consumer-thread c-out) +(semaphore-post sema2) +(semaphore-wait sema) +(test (void) 'consumer-thread c-out) + +; queue 3 +(g / 2) +(g semaphore-wait sema2) +(g (lambda (s) (semaphore-wait s) 5) sema2) +(semaphore-wait sema) +(test 1/2 'consumer-thread c-out) +(semaphore-post sema2) +(semaphore-wait sema) +(test (void) 'consumer-thread c-out) +(semaphore-post sema2) +(semaphore-wait sema) +(test 5 'consumer-thread c-out) + +; kill the consumer +(kill-thread th) +(g - 7) +(sleep SLEEP-TIME) +(test 5 'consumer-thread c-out) + +(arity-test consumer-thread 1 1) +(error-test '(consumer-thread 9)) +(arity-test g 2 3) + +;;; semaphore-wait-multiple ;;; + +(test #f semaphore-wait-multiple (list sema sema2) SLEEP-TIME) +(semaphore-post sema) +(test sema semaphore-wait-multiple (list sema sema2)) +(test #f semaphore-wait-multiple (list sema sema2) SLEEP-TIME) +(semaphore-post sema2) +(test sema2 semaphore-wait-multiple (list sema sema2)) +(test #f semaphore-wait-multiple (list sema sema2) SLEEP-TIME) +(semaphore-post sema) +(semaphore-post sema2) +(let ([first (semaphore-wait-multiple (list sema sema2))]) + (test #t semaphore? first) + (test (if (eq? first sema) sema2 sema) semaphore-wait-multiple (list sema sema2))) +(test #f semaphore-wait-multiple (list sema sema2) SLEEP-TIME) + +(arity-test semaphore-wait-multiple 1 3) + +(report-errs) diff --git a/collects/tests/mzscheme/name.ss b/collects/tests/mzscheme/name.ss new file mode 100644 index 0000000..f5cd5f7 --- /dev/null +++ b/collects/tests/mzscheme/name.ss @@ -0,0 +1,103 @@ + +; Test MzScheme's name inference + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'NAMES) + +(arity-test inferred-name 1 1) +(test #f inferred-name 0) +(test #f inferred-name 'hello) +(test #f inferred-name "hi") + +; Test ok when no name for proc +(test #f inferred-name (lambda () 0)) +(test #f inferred-name (case-lambda)) +(test #f inferred-name (case-lambda [(x) 9])) +(test #f inferred-name (case-lambda [(x) 9][(y z) 12])) + +; Test constructs that don't provide a name +(test #f inferred-name (let ([x (cons (lambda () 10) 0)]) (car x))) +(test #f inferred-name (let ([x (let ([y (lambda (x) x)]) (y (lambda () 10)))]) x)) + +; Test ok when name for proc +(define f (lambda () 0)) +(define f2 (lambda (a) 0)) +(define f3 (case-lambda)) +(define f4 (case-lambda [(x) 9])) +(define f5 (case-lambda [(x) 9][(y z) 10])) + +(test 'f inferred-name f) +(test 'f2 inferred-name f2) +(test 'f3 inferred-name f3) +(test 'f4 inferred-name f4) +(test 'f5 inferred-name f5) + +; Test constructs that do provide a name +(test 'a inferred-name (let ([a (lambda () 0)]) a)) +(test 'a inferred-name (let ([a (lambda () 0)]) (let ([b a]) b))) +(test 'b inferred-name (let* ([b (lambda () 0)]) b)) +(test 'c inferred-name (letrec ([c (lambda () 0)]) c)) +(test 'loop inferred-name (let loop () loop)) + +(test 'd inferred-name (let ([d (begin (lambda () x))]) d)) +(test 'e inferred-name (let ([e (begin0 (lambda () x))]) e)) + +(test 'd2 inferred-name (let ([d2 (begin 7 (lambda () x))]) d2)) +(test 'e2 inferred-name (let ([e2 (begin0 (lambda () x) 7)]) e2)) + +(test 'd3 inferred-name (let ([d3 (begin (cons 1 2) (lambda () x))]) d3)) +(test 'e3 inferred-name (let ([e3 (begin0 (lambda () x) (cons 1 2))]) e3)) + +(test 'f inferred-name (let ([f (begin0 (begin (cons 1 2) (lambda () x)) (cons 1 2))]) f)) + +(test 'g1 inferred-name (let ([g1 (if (cons 1 2) (lambda () x) #f)]) g1)) +(test 'g2 inferred-name (let ([g2 (if (negative? (car (cons 1 2))) #t (lambda () x))]) g2)) + +(test 'w inferred-name (let ([w (let ([x 5]) (lambda () x))]) w)) +(test 'z inferred-name (let ([z (let ([x 5]) (cons 1 2) (lambda () x))]) z)) + +(set! f (lambda () 10)) +(test 'f inferred-name f) + +; Test class stuff ok when no name +(test #f inferred-name (class null ())) +(test #f inferred-name (interface ())) + +; Test class stuff ok when name +(test 'c1 inferred-name (let ([c1 (class null ())]) c1)) +(test 'i1 inferred-name (let ([i1 (interface ())]) i1)) +(test 'm inferred-name + (ivar + (make-object + (class null () + (public + [m (lambda () 10)]))) + m)) + ; Use external name: +(test 'mex inferred-name + (ivar + (make-object + (class null () + (public + [(m mex) (lambda () 10)]))) + mex)) + +; Test unit stuff ok when no name +(test #f inferred-name (unit (import) (export))) +(test #f inferred-name (compound-unit (import) (link) (export))) + +; Test class stuff ok when name +(test 'u1 inferred-name (let ([u1 (unit (import) (export))]) u1)) +(test 'u2 inferred-name (let ([u2 (compound-unit (import) (link) (export))]) u2)) + +(test 'x inferred-name (invoke-unit + (unit (import) (export) (define x (lambda () 0)) x))) +(test 'x2 inferred-name (invoke-unit + (unit (import) (export x2) (define x2 (lambda () 0)) x2))) + ; Use external name: +(test 'x3 inferred-name (invoke-unit + (unit (import) (export (x x3)) (define x (lambda () 0)) x))) + +(report-errs) diff --git a/collects/tests/mzscheme/namespac.ss b/collects/tests/mzscheme/namespac.ss new file mode 100644 index 0000000..c7d6e14 --- /dev/null +++ b/collects/tests/mzscheme/namespac.ss @@ -0,0 +1,105 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'namespaces) + +(define flag-map + (list (list 'constants + 'no-constants + '(#%define car 5) + exn:misc:constant? + #f) + (list 'keywords + 'no-keywords + '(#%let ([#%lambda 7]) (void)) + exn:syntax? + #f) + (list 'call/cc=call/ec + 'call/cc!=call/ec + '((call/cc (#%lambda (x) x)) void) + exn:misc:continuation? + #f) + (list 'hash-percent-syntax + 'all-syntax + '(if #t (void)) + exn:variable? + #f))) + +(define (do-one-by-one more less) + (let loop ([n (length flag-map)]) + (unless (zero? n) + (let ([test-info + (let loop ([l flag-map][p 1]) + (if (null? l) + '() + (let* ([g (car l)] + [g++ (cdddr g)]) + (cons + (cond + [(= p n) (cons (less g) (less g++))] + [else (cons (more g) (more g++))]) + (loop (cdr l) (add1 p))))))]) + (let* ([flags (map car test-info)] + [namespace (apply make-namespace flags)]) + (printf "trying: ~s~n" flags) + (let loop ([tests (map caddr flag-map)] + [results (map cdr test-info)]) + (if (null? results) + '() + (begin + (if (car results) + (error-test + `(with-handlers ([(#%lambda (x) #f) void]) ; outside parameterize re-raises exns after escaping + (parameterize ([current-namespace ,namespace]) + (eval ',(car tests)))) + (car results)) + (with-handlers ([(lambda (x) #f) void]) + (parameterize ([current-namespace namespace]) + (test (void) eval (car tests))))) + (loop (cdr tests) (cdr results))))))) + (loop (sub1 n))))) + +(unless (defined? 'building-flat-tests) + (do-one-by-one car cadr) + (do-one-by-one cadr car)) + +; Test primitive-name +(let ([gvl (parameterize ([current-namespace (make-namespace)]) (make-global-value-list))] + [aliases (list (cons "call/cc" "call-with-current-continuation") + (cons "call/ec" "call-with-escaping-continuation") + (cons "unit/sig?" "unit-with-signature?") + (cons "unit/sig->unit" "unit-with-signature-unit") + (cons "unit-with-signature->unit" "unit-with-signature-unit"))]) + (test #t 'names + (andmap + (lambda (nv-pair) + (let ([name (car nv-pair)] + [value (cdr nv-pair)]) + (or (not (primitive? value)) + (let* ([s (symbol->string name)] + [sr (if (char=? #\# (string-ref s 0)) + (substring s 2 (string-length s)) + s)] + [st (let ([m (assoc sr aliases)]) + (if m + (cdr m) + sr))]) + (equal? st (primitive-name value)))))) + gvl))) + +(define (test-empty . flags) + (let ([e (apply make-namespace flags)]) + (parameterize ([current-namespace e]) + (test null make-global-value-list) + (test 'unbound 'empty-namespace + (with-handlers ([void (lambda (exn) 'unbound)]) + (eval 'car))) + (test 'unbound 'empty-namespace + (with-handlers ([void (lambda (exn) 'unbound)]) + (eval '#%car))) + (global-defined-value 'hello 5) + (test 5 'empty-namespace (eval 'hello)) + (test '((hello . 5)) make-global-value-list)))) +(test-empty 'empty) +(apply test-empty (append '(empty) (map car flag-map) (map cadr flag-map))) diff --git a/collects/tests/mzscheme/nch.ss b/collects/tests/mzscheme/nch.ss new file mode 100644 index 0000000..45398e6 --- /dev/null +++ b/collects/tests/mzscheme/nch.ss @@ -0,0 +1,30 @@ + +(define (fact n) + (if (zero? n) + 1 + (* n (fact (- n 1))))) + +(define f1000 (fact 1000)) + +(define (divall n d) + (if (<= n 1) + d + (divall (/ n d) (+ 1 d)))) + +(define (nch n c) + (/ (fact n) (fact (- n c)) (fact c))) + +(define (snch n) + (letrec ((loop + (lambda (i) + (if (> i n) + 0 + (+ (nch n i) (loop (+ i 1))))))) + (loop 0))) + +(define (fsum n) + (if (zero? n) + 1 + (+ (fact n) (fsum (- n 1))))) + + diff --git a/collects/tests/mzscheme/number.ss b/collects/tests/mzscheme/number.ss new file mode 100644 index 0000000..87d0714 --- /dev/null +++ b/collects/tests/mzscheme/number.ss @@ -0,0 +1,1239 @@ + + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 6 5 5) +(test #f number? 'a) +(test #f complex? 'a) +(test #f real? 'a) +(test #f rational? 'a) +(test #f integer? 'a) + +(test #t number? 3) +(test #t complex? 3) +(test #t real? 3) +(test #t rational? 3) +(test #t integer? 3) + +(test #t number? 3.0) +(test #t complex? 3.0) +(test #t real? 3.0) +(test #t rational? 3.0) +(test #t integer? 3.0) + +(test #t number? 3.1) +(test #t complex? 3.1) +(test #t real? 3.1) +(test #t rational? 3.1) +(test #f integer? 3.1) + +(test #t number? 3/2) +(test #t complex? 3/2) +(test #t real? 3/2) +(test #t rational? 3/2) +(test #f integer? 3/2) + +(test #t number? 3+i) +(test #t complex? 3+i) +(test #f real? 3+i) +(test #f rational? 3+i) +(test #f integer? 3+i) + +(test #t exact? 3) +(test #t exact? 3/4) +(test #f exact? 3.0) +(test #t exact? (expt 2 100)) +(test #t exact? 3+4i) +(test #f exact? 3.0+4i) + +(test #f inexact? 3) +(test #f inexact? 3/4) +(test #t inexact? 3.0) +(test #f inexact? (expt 2 100)) +(test #f inexact? 3+4i) +(test #t inexact? 3.0+4i) + +(test #t complex? -4.242154731064108e-5-6.865001427422244e-5i) +(test #f exact? -4.242154731064108e-5-6.865001427422244e-5i) +(test #t inexact? -4.242154731064108e-5-6.865001427422244e-5i) + +(test #t complex? -4.242154731064108f-5-6.865001427422244f-5i) +(test #f exact? -4.242154731064108f-5-6.865001427422244f-5i) +(test #t inexact? -4.242154731064108f-5-6.865001427422244f-5i) + +(test #t number? +inf.0) +(test #t complex? +inf.0) +(test #t real? +inf.0) +(test #t rational? +inf.0) +(test #t integer? +inf.0) + +(test #t number? -inf.0) +(test #t complex? -inf.0) +(test #t real? -inf.0) +(test #t rational? -inf.0) +(test #t integer? -inf.0) + +(test #t number? +nan.0) +(test #t complex? +nan.0) +(test #t real? +nan.0) +(test #t rational? +nan.0) +(test #f integer? +nan.0) + +(arity-test inexact? 1 1) +(arity-test number? 1 1) +(arity-test complex? 1 1) +(arity-test real? 1 1) +(arity-test rational? 1 1) +(arity-test integer? 1 1) +(arity-test exact? 1 1) +(arity-test inexact? 1 1) + +(error-test '(exact? 'a)) +(error-test '(inexact? 'a)) + +(test "+inf.0" number->string +inf.0) +(test "-inf.0" number->string -inf.0) +(test "+nan.0" number->string +nan.0) +(test "+nan.0" number->string +nan.0) + +(test #t = 0) +(test #t > 0) +(test #t < 0) +(test #t >= 0) +(test #t <= 0) +(test #t = 22 22 22) +(test #t = 22 22) +(test #f = 34 34 35) +(test #f = 34 35) +(test #t > 3 -6246) +(test #f > 9 9 -2424) +(test #t >= 3 -4 -6246) +(test #t >= 9 9) +(test #f >= 8 9) +(test #t < -1 2 3 4 5 6 7 8) +(test #f < -1 2 3 4 4 5 6 7) +(test #t <= -1 2 3 4 5 6 7 8) +(test #t <= -1 2 3 4 4 5 6 7) +(test #f < 1 3 2) +(test #f >= 1 3 2) + +(define (test-compare lo m hi) ; all positive! + (define -lo (- lo)) + (define -m (- m)) + (define -hi (- hi)) + + (define (test-lh l h) + (test #f > l h) + (test #t < l h) + (test #f = l h) + (test #f >= l h) + (test #t <= l h)) + + (define (test-hl h l) + (test #t > h l) + (test #f < h l) + (test #f = h l) + (test #t >= h l) + (test #f <= h l)) + + (define (test-zero z) + (test-hl m z) + (test-lh -m z) + (test-hl z -m) + (test-lh z m)) + + (test-lh m hi) + (test-hl -m -hi) + + (test #f > m m) + (test #f < m m) + (test #t = m m) + (test #t >= m m) + (test #t <= m m) + + (test-hl m -m) + (test-lh -m m) + + (test-hl m lo) + (test-lh -m -lo) + + (test-zero 0) + (test-zero 0.0)) + +(test-compare 0.5 1.2 2.3) +(test-compare 2/5 1/2 2/3) +(test #t = 1/2 2/4) + +(test-compare 0.5 6/5 2.3) +(test-compare 1 11922615739/10210200 3000) +(test-compare 1.0 11922615739/10210200 3000.0) + +(test #f > 0 (/ 1 (expt 2 400))) + +(test #t < 0.5 2/3) +(test #f < 2/3 0.5) +(test #t = 0.5 1/2) +(test #t = +0.5i +1/2i) +(test #f = +0.5i 1+1/2i) + +(test #f = 1+2i 2+i) + +(define (test-nan.0 f . args) + (apply test +nan.0 f args)) + +(define (test-nan c) + (test #f < +nan.0 c) + (test #f > +nan.0 c) + (test #f = +nan.0 c) + (test #f <= +nan.0 c) + (test #f >= +nan.0 c)) +(test-nan 0) +(test-nan 0.0) +(test-nan 0.3) +(test-nan +nan.0) +(test-nan +inf.0) +(test-nan -inf.0) +(test #f = +nan.0 1+2i) +(test #f = +nan.0 (make-rectangular +inf.0 -inf.0)) + +(test-compare 999999999999 1000000000000 1000000000001) +(define big-num (expt 2 1500)) +(test-compare (sub1 big-num) big-num (add1 big-num)) +(test-compare 1.0 (expt 10 100) 1e200) + +(define (inf-zero-test inf rx negnot) + (let ([inf-test-x + (lambda (r v) + (test r < v inf) + (test (not r) > v inf) + (test r <= v inf) + (test (not r) >= v inf) + + (test (not r) < inf v) + (test r > inf v) + (test (not r) <= inf v) + (test r >= inf v))]) + (inf-test-x rx 5) + (inf-test-x (negnot rx) -5) + (inf-test-x rx big-num) + (inf-test-x (negnot rx) (- big-num)) + (inf-test-x rx (/ big-num 3)) + (inf-test-x (negnot rx) (/ (- big-num) 3)) + (inf-test-x rx (/ 1 big-num)) + (inf-test-x (negnot rx) (/ 1 (- big-num))))) +(inf-zero-test +inf.0 #t (lambda (x) x)) +(inf-zero-test -inf.0 #f (lambda (x) x)) +(inf-zero-test 0.0 #f not) + +(error-test '(= 1 'a)) +(error-test '(= 1 1 'a)) +(error-test '(= 1 2 'a)) +(error-test '(= 'a 1)) +(error-test '(= 'a)) +(error-test '(> 1 'a)) +(error-test '(> 1 0 'a)) +(error-test '(> 1 2 'a)) +(error-test '(> 'a 1)) +(error-test '(< 1 'a)) +(error-test '(< 1 2 'a)) +(error-test '(< 1 0 'a)) +(error-test '(< 'a 1)) +(error-test '(>= 1 'a)) +(error-test '(>= 1 1 'a)) +(error-test '(>= 1 2 'a)) +(error-test '(>= 'a 1)) +(error-test '(<= 1 'a)) +(error-test '(<= 1 1 'a)) +(error-test '(<= 1 0 'a)) +(error-test '(<= 'a 1)) + +(arity-test = 1 -1) +(arity-test < 1 -1) +(arity-test > 1 -1) +(arity-test <= 1 -1) +(arity-test >= 1 -1) + +(test #t zero? 0) +(test #t zero? 0.0) +(test #t zero? +0.0i) +(test #t zero? 0/1) +(test #f zero? 1) +(test #f zero? -1) +(test #f zero? -100) +(test #f zero? 1.0) +(test #f zero? -1.0) +(test #f zero? 1/2) +(test #f zero? -1/2) +(test #f zero? -1/2+2i) +(test #f zero? +inf.0) +(test #f zero? -inf.0) +(test #f zero? +nan.0) +(test #t positive? 4) +(test #f positive? -4) +(test #f positive? 0) +(test #t positive? 4.0) +(test #f positive? -4.0) +(test #f positive? 0.0) +(test #t positive? 2/4) +(test #f positive? -2/4) +(test #f positive? 0/2) +(test #t positive? +inf.0) +(test #f positive? -inf.0) +(test #f positive? +nan.0) +(test #f negative? 4) +(test #t negative? -4) +(test #f negative? 0) +(test #f negative? 4.0) +(test #t negative? -4.0) +(test #f negative? 0.0) +(test #f negative? 2/4) +(test #t negative? -2/4) +(test #f negative? 0/4) +(test #f negative? +inf.0) +(test #t negative? -inf.0) +(test #f negative? +nan.0) +(test #t odd? 3) +(test #f odd? 2) +(test #f odd? -4) +(test #t odd? -1) +(test #t odd? +inf.0) +(test #t odd? -inf.0) +(test #f even? 3) +(test #t even? 2) +(test #t even? -4) +(test #f even? -1) +(test #t even? +inf.0) +(test #t even? -inf.0) + +(arity-test zero? 1 1) +(arity-test positive? 1 1) +(arity-test negative? 1 1) +(arity-test odd? 1 1) +(arity-test even? 1 1) + +(error-test '(positive? 2+i)) +(error-test '(negative? 2+i)) +(error-test '(odd? 4.1)) +(error-test '(even? 4.1)) +(error-test '(odd? 4+1i)) +(error-test '(even? 4+1i)) +(error-test '(even? +nan.0)) + +(error-test '(positive? 'i)) +(error-test '(negative? 'i)) +(error-test '(odd? 'a)) +(error-test '(even? 'a)) +(error-test '(odd? 'i)) +(error-test '(even? 'i)) + +(test 5 max 5) +(test 5 min 5) +(test 38 max 34 5 7 38 6) +(test -24 min 3 5 5 330 4 -24) +(test 38.0 max 34 5.0 7 38 6) +(test -24.0 min 3 5 5 330 4 -24.0) +(test 2/3 max 1/2 2/3) +(test 2/3 max 2/3 1/2) +(test 2/3 max 2/3 -4/5) +(test 1/2 min 1/2 2/3) +(test 1/2 min 2/3 1/2) +(test -4/5 min 2/3 -4/5) +(test +inf.0 max +inf.0 0 -inf.0) +(test -inf.0 min +inf.0 0 -inf.0) +(test-nan.0 max +inf.0 +nan.0 0 -inf.0) +(test-nan.0 min +inf.0 0 +nan.0 -inf.0) + +(error-test '(max 0 'a)) +(error-test '(min 0 'a)) +(error-test '(max 'a 0)) +(error-test '(min 'a 0)) +(error-test '(max 'a)) +(error-test '(min 'a)) +(error-test '(min 2 4+i)) +(error-test '(max 2 4+i)) +(error-test '(min 4+i)) +(error-test '(max 4+i)) + +(arity-test max 1 -1) +(arity-test min 1 -1) + +(test 0 +) +(test 7 + 3 4) +(test 6 + 1 2 3) +(test 7.0 + 3 4.0) +(test 6.0 + 1 2.0 3) +(test 19/12 + 1/4 1/3 1) +(test +i + +i) +(test 3/2+1i + 1 2+2i -i -3/2) +(test 3 + 3) +(test 0 +) +(test 4 * 4) +(test 16.0 * 4 4.0) +(test 1 *) +(test 6/25 * 3/5 1/5 2) +(test #i+6/25 * 3/5 1/5 2.0) +(test +6/25i * 3/5 1/5 2 +i) +(test #i+6/25i * 3/5 1/5 2.0 +i) +(test 18805208620685182736256260714897 + * (sub1 (expt 2 31)) + 8756857658476587568751) + +(arity-test * 0 -1) +(arity-test + 0 -1) +(arity-test - 1 -1) +(arity-test / 1 -1) + +(test 2 add1 1) +(test 0 add1 -1) +(test 2.0 add1 1.0) +(test 0.0 add1 -1.0) +(test 3/2 add1 1/2) +(test 1/2 add1 -1/2) +(test 2.0+i add1 1.0+i) +(test 0.0+i add1 -1.0+i) + +(error-test '(add1 "a")) +(arity-test add1 1 1) + +(test 1 sub1 2) +(test -2 sub1 -1) +(test 1.0 sub1 2.0) +(test -2.0 sub1 -1.0) +(test -1/2 sub1 1/2) +(test -3/2 sub1 -1/2) +(test 1.0+i sub1 2.0+i) +(test -2.0+i sub1 -1.0+i) + +(error-test '(sub1 "a")) +(arity-test sub1 1 1) + +(test 1024 expt 2 10) +(test 1/1024 expt 2 -10) +(arity-test expt 2 2) + +(test 0 apply + (map inexact->exact (list 3.2e+270 -2.4e+270 -8e+269))) +(test 0 apply + (map inexact->exact (list 3.2f+7 -2.4f+7 -8f+6))) + +(test #t positive? (inexact->exact 0.1)) +(test #t negative? (inexact->exact -0.1)) +(test 0 + (inexact->exact -0.1) (inexact->exact 0.1)) +(arity-test inexact->exact 1 1) +(error-test '(inexact->exact 'a)) +(test 1+i inexact->exact 1.0+1.0i) + +(test #t positive? (exact->inexact 1/10)) +(test #t negative? (exact->inexact -1/10)) +(test 0.0 + (exact->inexact -1/10) (exact->inexact 1/10)) +(arity-test exact->inexact 1 1) +(error-test '(exact->inexact 'a)) +(test 1.0+1.0i exact->inexact 1+1i) + +(error-test '(inexact->exact +inf.0)) +(error-test '(inexact->exact -inf.0)) +(error-test '(inexact->exact +nan.0)) + +(error-test '(* 'a 0)) +(error-test '(+ 'a 0)) +(error-test '(+ 0 'a)) +(error-test '(* 0 'a)) +(error-test '(+ 'a)) +(error-test '(* 'a)) + +(define (test-inf-plus-times v) + (define (test+ +) + (test +inf.0 + v (+ +inf.0)) + (test -inf.0 + v (+ -inf.0)) + (test +inf.0 + (- v) (+ +inf.0)) + (test -inf.0 + (- v) (+ -inf.0)) + + (test +inf.0 + +inf.0 v) + (test -inf.0 + -inf.0 v) + (test +inf.0 + +inf.0 (- v)) + (test -inf.0 + -inf.0 (- v)) + + (test-nan.0 + +nan.0 v) + (test-nan.0 + v +nan.0)) + + (test+ +) + (test+ -) + + (test +inf.0 * +inf.0 v) + (test -inf.0 * -inf.0 v) + (test -inf.0 * +inf.0 (- v)) + (test +inf.0 * -inf.0 (- v)) + + (test +inf.0 * v +inf.0) + (test -inf.0 * v -inf.0) + (test -inf.0 * (- v) +inf.0) + (test +inf.0 * (- v) -inf.0) + + (test-nan.0 * +nan.0 v) + (test-nan.0 * v +nan.0)) + +(test-inf-plus-times 1) +(test-inf-plus-times 1.0) +(test-inf-plus-times (expt 2 100)) + +(test -inf.0 - +inf.0) +(test +inf.0 - -inf.0) +(test +inf.0 + +inf.0 +inf.0) +(test -inf.0 + -inf.0 -inf.0) +(test-nan.0 + +inf.0 -inf.0) +(test-nan.0 - +inf.0 +inf.0) +(test-nan.0 - -inf.0 -inf.0) +(test +inf.0 * +inf.0 +inf.0) +(test -inf.0 * +inf.0 -inf.0) +(test-nan.0 * +inf.0 0) +(test-nan.0 + +nan.0 +nan.0) +(test-nan.0 - +nan.0 +nan.0) +(test-nan.0 * +nan.0 +nan.0) + +(test 1/2 / 1 2) +(test 1/2 / 1/4 1/2) +(test 0.5 / 1 2.0) +(test 0.5 / 1.0 2) +(test 1/2+3/2i / 1+3i 2) +(test 1/5-3/5i / 2 1+3i) + +(test +inf.0 / 1.0 0.0) +(test -inf.0 / -1.0 0.0) + +(define (test-inf-zero-div v) + (test 0.0 / v +inf.0) + (test 0.0 / v -inf.0) + (test 0.0 / (- v) +inf.0) + (test 0.0 / (- v) -inf.0) + + (test +inf.0 / +inf.0 v) + (test -inf.0 / -inf.0 v) + (test -inf.0 / +inf.0 (- v)) + (test +inf.0 / -inf.0 (- v)) + + (test 0.0 / 0.0 v) + (test 0.0 / 0.0 (- v)) + + (test +inf.0 / v 0.0) + (test -inf.0 / (- v) 0.0) + + (test-nan.0 / +nan.0 v) + (test-nan.0 / v +nan.0)) + +(test-inf-zero-div big-num) +(test-inf-zero-div (/ big-num 3)) + +(test-nan.0 / +inf.0 +inf.0) +(test-nan.0 / +inf.0 -inf.0) +(test-nan.0 / +nan.0 -nan.0) + +(test 1.0 exact->inexact (/ big-num (add1 big-num))) + +(error-test '(/ 0) exn:application:math:zero?) +(error-test '(/ 1 0) exn:application:math:zero?) +(error-test '(/ 1/2 0) exn:application:math:zero?) +(error-test '(/ 1+2i 0) exn:application:math:zero?) +(error-test '(/ 1.0 0) exn:application:math:zero?) + +(test -1 - 3 4) +(test -3 - 3) +(test -1.0 - 3.0 4) +(test -3.0 - 3.0) +(test 7 abs -7) +(test 7.0 abs -7.0) +(test 7 abs 7) +(test 0 abs 0) +(test 1/2 abs 1/2) +(test 1/2 abs -1/2) +(test +inf.0 abs +inf.0) +(test +inf.0 abs -inf.0) +(test-nan.0 abs -nan.0) + +(arity-test abs 1 1) +(error-test '(-) exn:application:arity?) +(error-test '(abs 'a)) +(error-test '(abs +5i)) + +(test 5 quotient 35 7) +(test 5.0 quotient 35 7.0) +(test 5.0 quotient 36 7.0) +(test 5.0 quotient 36.0 7) +(test -5 quotient -35 7) +(test -5.0 quotient -35 7.0) +(test -5 quotient 35 -7) +(test -5.0 quotient 35 -7.0) +(test 5 quotient -35 -7) +(test 5.0 quotient -35 -7.0) +(test -5.0 quotient -36 7.0) +(test -5.0 quotient 36.0 -7) +(test 1 modulo 13 4) +(test 1 remainder 13 4) +(test 1.0 modulo 13 4.0) +(test 1.0 remainder 13 4.0) +(test 3 modulo -13 4) +(test -1 remainder -13 4) +(test 3.0 modulo -13 4.0) +(test -1.0 remainder -13 4.0) +(test -3 modulo 13 -4) +(test 1 remainder 13 -4) +(test -3.0 modulo 13.0 -4) +(test 1.0 remainder 13.0 -4) +(test -1 modulo -13 -4) +(test -1 remainder -13 -4) +(test -1.0 modulo -13 -4.0) +(test -1.0 remainder -13 -4.0) +(test -2 remainder -3333333332 -3) +(test -2 modulo -3333333332 -3) +(test 2 remainder 3333333332 -3) +(test -1 modulo 3333333332 -3) +(test 0 modulo 4 2) +(test 0 modulo -4 2) +(test 0 modulo 4 -2) +(test 0 modulo -4 -2) +(test 0.0 modulo 4.0 2) +(test 0.0 modulo -4.0 2) +(test 0.0 modulo 4.0 -2) +(test 0.0 modulo -4.0 -2) +(define (divtest n1 n2) + (= n1 (+ (* n2 (quotient n1 n2)) + (remainder n1 n2)))) +(test #t divtest 238 9) +(test #t divtest -238 9) +(test #t divtest 238 -9) +(test #t divtest -238 -9) + +(test 13.0 quotient 1324.0 100) + +(define (test-qrm-inf v) + (define iv (exact->inexact v)) + + (test 0.0 quotient v +inf.0) + (test 0.0 quotient v -inf.0) + (test iv remainder v +inf.0) + (test iv remainder v -inf.0) + (test iv modulo v +inf.0) + (test -inf.0 modulo v -inf.0) + + (test +inf.0 quotient +inf.0 v) + (test -inf.0 quotient -inf.0 v) + (test 0.0 remainder +inf.0 v) + (test 0.0 remainder -inf.0 v) + (test 0.0 modulo +inf.0 v) + (test 0.0 modulo -inf.0 v)) + +(test-qrm-inf 9) +(test-qrm-inf 9.0) +(test-qrm-inf (expt 2 100)) + +(arity-test quotient 2 2) +(arity-test modulo 2 2) +(arity-test remainder 2 2) + +(error-test '(quotient 'a 1)) +(error-test '(quotient 1 'a)) +(error-test '(quotient 1 +nan.0)) +(error-test '(quotient +nan.0 1)) +(error-test '(modulo 'a 1)) +(error-test '(modulo 1 'a)) +(error-test '(modulo +nan.0 1)) +(error-test '(modulo 1 +nan.0)) +(error-test '(remainder 'a 1)) +(error-test '(remainder 1 'a)) +(error-test '(remainder +nan.0 1)) +(error-test '(remainder 1 +nan.0)) +(error-test '(quotient 'a 1.0)) +(error-test '(quotient 1.0 'a)) +(error-test '(modulo 'a 1.0)) +(error-test '(modulo 1.0 'a)) +(error-test '(remainder 'a 1.0)) +(error-test '(remainder 1.0 'a)) +(error-test '(quotient 1/2 1)) +(error-test '(remainder 1/2 1)) +(error-test '(modulo 1/2 1)) +(error-test '(quotient 2 1/2)) +(error-test '(remainder 2 1/2)) +(error-test '(modulo 2 1/2)) +(error-test '(quotient 12.3 1)) +(error-test '(remainder 12.3 1)) +(error-test '(modulo 12.3 1)) +(error-test '(quotient 2 12.3)) +(error-test '(remainder 2 12.3)) +(error-test '(modulo 2 12.3)) +(error-test '(quotient 1+2i 1)) +(error-test '(remainder 1+2i 1)) +(error-test '(modulo 1+2i 1)) +(error-test '(quotient 2 1+2i)) +(error-test '(remainder 2 1+2i)) +(error-test '(modulo 2 1+2i)) + +(test 10 bitwise-ior 10) +(test 10 bitwise-and 10) +(test 10 bitwise-xor 10) +(test 7 bitwise-ior 3 4) +(test 0 bitwise-and 3 4) +(test 7 bitwise-xor 3 4) +(test 7 bitwise-ior 3 4 1) +(test 1 bitwise-and 3 5 1) +(test 6 bitwise-xor 3 4 1) + +(test #x1ffff7777 bitwise-ior #x1aaaa5555 #x155553333) +(test #x100001111 bitwise-and #x1aaaa5555 #x155553333) +(test #x0ffff6666 bitwise-xor #x1aaaa5555 #x155553333) + +(test #x3ffff7777 bitwise-ior #x2aaaa5555 #x155553333) +(test #x000001111 bitwise-and #x2aaaa5555 #x155553333) +(test #x3ffff6666 bitwise-xor #x2aaaa5555 #x155553333) + +(test #x3ffff7777 bitwise-ior #x2aaaa5555 #x155553333) +(test #x000001111 bitwise-and #x2aaaa5555 #x155553333) +(test #x3ffff6666 bitwise-xor #x2aaaa5555 #x155553333) + +(test #xfffffffffffffe bitwise-not #x-FFFFFFFFFFFFFF) +(test #x-100000000000000 bitwise-not #xFFFFFFFFFFFFFF) + +(test (bitwise-and (bitwise-not #x-2aaaa5555) (bitwise-not #x-15555aaaa)) + bitwise-not (bitwise-ior #x-2aaaa5555 #x-15555aaaa)) +(test (bitwise-and (bitwise-not #x-2aaaa5555) (bitwise-not #x-155553333)) + bitwise-not (bitwise-ior #x-2aaaa5555 #x-155553333)) +(test (bitwise-and (bitwise-not #x-2aaaa5555) (bitwise-not #x-15555333)) + bitwise-not (bitwise-ior #x-2aaaa5555 #x-15555333)) + +(test #x-155553333 bitwise-xor #x-2aaaa5555 (bitwise-xor #x-2aaaa5555 #x-155553333)) +(test #x-15555333 bitwise-xor #x-2aaaa5555 (bitwise-xor #x-2aaaa5555 #x-15555333)) + +(arity-test bitwise-ior 1 -1) +(arity-test bitwise-and 1 -1) +(arity-test bitwise-xor 1 -1) +(arity-test bitwise-not 1 1) + +(define error-test-bitwise-procs + (lambda (v) + (error-test `(bitwise-ior ,v)) + (error-test `(bitwise-and ,v)) + (error-test `(bitwise-xor ,v)) + (error-test `(bitwise-not ,v)) + (error-test `(bitwise-ior 1 ,v)) + (error-test `(bitwise-and 1 ,v)) + (error-test `(bitwise-xor 1 ,v)) + (error-test `(bitwise-ior ,v 1)) + (error-test `(bitwise-and ,v 1)) + (error-test `(bitwise-xor ,v 1)))) + +(error-test-bitwise-procs 1.0) +(error-test-bitwise-procs 1/2) +(error-test-bitwise-procs 1+2i) +(error-test-bitwise-procs +inf.0) +(error-test-bitwise-procs ''a) + +(test 1 arithmetic-shift 1 0) +(test 1024 arithmetic-shift 1 10) +(test 1 arithmetic-shift 1024 -10) +(test 256 arithmetic-shift 1024 -2) +(test 0 arithmetic-shift 1024 -11) +(test 0 arithmetic-shift 1024 -20) +(test 0 arithmetic-shift 1024 -40) +(test 0 arithmetic-shift 1024 -20000000000000000000) + +(test (expt 2 40) arithmetic-shift (expt 2 40) 0) +(test (expt 2 50) arithmetic-shift (expt 2 40) 10) +(test (expt 2 30) arithmetic-shift (expt 2 40) -10) ; somewhere close to here is a boundary... +(test (expt 2 29) arithmetic-shift (expt 2 40) -11) +(test (expt 2 31) arithmetic-shift (expt 2 40) -9) +(test 1 arithmetic-shift (expt 2 40) -40) +(test 0 arithmetic-shift (expt 2 40) -41) +(test 0 arithmetic-shift (expt 2 40) -100) + +(test -1 arithmetic-shift -1 0) +(test -1024 arithmetic-shift -1 10) +(test -1 arithmetic-shift -1024 -10) +(test -256 arithmetic-shift -1024 -2) +(test -1 arithmetic-shift -1024 -11) +(test -1 arithmetic-shift -1024 -20) +(test -1 arithmetic-shift -1024 -20000000000000000000) + +(test (- (expt 2 40)) arithmetic-shift (- (expt 2 40)) 0) +(test (- (expt 2 50)) arithmetic-shift (- (expt 2 40)) 10) +(test (- (expt 2 30)) arithmetic-shift (- (expt 2 40)) -10) ; somewhere close to here is a boundary... +(test (- (expt 2 29)) arithmetic-shift (- (expt 2 40)) -11) +(test (- (expt 2 31)) arithmetic-shift (- (expt 2 40)) -9) +(test -1 arithmetic-shift (- (expt 2 40)) -40) +(test -1 arithmetic-shift (- (expt 2 40)) -41) +(test -1 arithmetic-shift (- (expt 2 40)) -100) + +(arity-test arithmetic-shift 2 2) +(error-test '(arithmetic-shift "a" 1)) +(error-test '(arithmetic-shift 1 "a")) +(error-test '(arithmetic-shift 1.0 1)) +(error-test '(arithmetic-shift 1 1.0)) +(error-test '(arithmetic-shift 1 (expt 2 80)) exn:misc:out-of-memory?) + +(test 4 gcd 0 4) +(test 4 gcd -4 0) +(test 4 gcd 32 -36) +(test 2 gcd 6 10 14) +(test 0 gcd) +(test 5 gcd 5) +(test 5.0 gcd 5.0 10) +(test 9.0 gcd +inf.0 9) +(test 9.0 gcd -inf.0 9) +(test 288 lcm 32 -36) +(test 12 lcm 2 3 4) +(test 1 lcm) +(test 5 lcm 5) +(test 30.0 lcm 5 6.0) + +(error-test '(gcd +nan.0)) +(error-test '(gcd 'a)) +(error-test '(gcd 'a 1)) +(error-test '(gcd 1 'a)) +(error-test '(lcm +nan.0)) +(error-test '(lcm 'a)) +(error-test '(lcm 'a 1)) +(error-test '(lcm 1 'a)) +(error-test '(gcd 1/2)) +(error-test '(gcd 3 1/2)) +(error-test '(gcd 1/2 3)) +(error-test '(lcm 1/2)) +(error-test '(lcm 3 1/2)) +(error-test '(lcm 1/2 3)) +(error-test '(gcd 1+2i)) +(error-test '(lcm 1+2i)) +(error-test '(gcd 1 1+2i)) +(error-test '(lcm 1 1+2i)) + +(arity-test gcd 0 -1) +(arity-test lcm 0 -1) + +(test 2 floor 5/2) +(test 3 ceiling 5/2) +(test 2 round 5/2) +(test 2 truncate 5/2) +(test -3 floor -5/2) +(test -2 ceiling -5/2) +(test -2 round -5/2) +(test -2 truncate -5/2) + +(test 1 floor 4/3) +(test 2 ceiling 4/3) +(test 1 round 4/3) +(test 1 truncate 4/3) +(test -2 floor -4/3) +(test -1 ceiling -4/3) +(test -1 round -4/3) +(test -1 truncate -4/3) + +(test 1 floor 5/3) +(test 2 ceiling 5/3) +(test 2 round 5/3) +(test 1 truncate 5/3) +(test -2 floor -5/3) +(test -1 ceiling -5/3) +(test -2 round -5/3) +(test -1 truncate -5/3) + +(test 2 floor 11/4) +(test 3 ceiling 11/4) +(test 3 round 11/4) +(test 2 truncate 11/4) +(test -3 floor -11/4) +(test -2 ceiling -11/4) +(test -3 round -11/4) +(test -2 truncate -11/4) + +(test 2 floor 9/4) +(test 3 ceiling 9/4) +(test 2 round 9/4) +(test 2 truncate 9/4) +(test -3 floor -9/4) +(test -2 ceiling -9/4) +(test -2 round -9/4) +(test -2 truncate -9/4) + +(define (test-fcrt-int v) + (test v floor v) + (test v ceiling v) + (test v round v) + (test v truncate v)) + +(test-fcrt-int 2) +(test-fcrt-int 2.0) +(test-fcrt-int (expt 2 100)) +(test-fcrt-int +inf.0) +(test-fcrt-int -inf.0) + +(test-nan.0 floor +nan.0) +(test-nan.0 ceiling +nan.0) +(test-nan.0 round +nan.0) +(test-nan.0 truncate +nan.0) + +(arity-test round 1 1) +(arity-test floor 1 1) +(arity-test ceiling 1 1) +(arity-test truncate 1 1) + +(error-test '(floor 2+i)) +(error-test '(ceiling 2+i)) +(error-test '(truncate 2+i)) +(error-test '(round 2+i)) + +(error-test '(floor "a")) +(error-test '(ceiling "a")) +(error-test '(truncate "a")) +(error-test '(round "a")) + +(test 5 numerator 5) +(test 5000000000000 numerator 5000000000000) +(test 5.0 numerator 5.0) +(test 1 denominator 5) +(test 1 denominator 5000000000000) +(test 1.0 denominator 5.0) +(test 2 numerator 2/3) +(test 3 denominator 2/3) +(test 1000.0 round (* 10000.0 (/ (numerator 0.1) (denominator 0.1)))) + +(test +inf.0 numerator +inf.0) +(test -inf.0 numerator -inf.0) +(test-nan.0 numerator +nan.0) +(test 1.0 denominator +inf.0) +(test 1.0 denominator -inf.0) +(test-nan.0 denominator +nan.0) + +(error-test '(numerator 'a)) +(error-test '(numerator 1+2i)) +(error-test '(denominator 'a)) +(error-test '(denominator 1+2i)) + +(arity-test numerator 1 1) +(arity-test denominator 1 1) + +(define (test-on-reals f filter) + (test (filter 5) f 5) + (test (filter 5.0) f 5.0) + (test (filter 1/5) f 1/5) + (test (filter (expt 2 100)) f (expt 2 100))) + +(test 1+2i make-rectangular 1 2) +(test 1.0+2.0i make-rectangular 1.0 2) +(test-nan.0 make-rectangular +nan.0 1) +(test-nan.0 make-rectangular 1 +nan.0) +(test 1 real-part 1+2i) +(test 1/5 real-part 1/5+2i) +(test-on-reals real-part (lambda (x) x)) +(test 2.0 imag-part 1+2.0i) +(test 1/5 imag-part 1+1/5i) +(test-on-reals imag-part (lambda (x) (if (exact? x) 0 0.0))) +(test-nan.0 real-part +nan.0) +(test-nan.0 imag-part +nan.0) +(test 6@1 (lambda (x) x) 6.0@1.0) +(test 324.0 floor (* 100 (real-part 6@1))) +(test 50488.0 floor (* 10000 (imag-part 6@1))) +(test 1.0 make-polar 1 0) +(let ([v (make-polar 1 1)]) + (test 5403.0 floor (* 10000 (real-part v))) + (test 84147.0 floor (* 100000 (imag-part v))) + (test 10000.0 round (* 10000.0 (magnitude v)))) +(let ([v (make-polar 1 2)]) + (test -416.0 ceiling (* 1000 (real-part v))) + (test 909.0 floor (* 1000 (imag-part v))) + (test 1.0 magnitude v) + (test 2.0 angle v)) +(test-nan.0 make-polar +nan.0 1) +(test-nan.0 make-polar 1 +nan.0) +(test 785.0 floor (* 1000 (angle (make-rectangular 1 1)))) +(test 14142.0 floor (* 10000 (magnitude (make-rectangular 1 1)))) +(test-on-reals magnitude (lambda (x) x)) +(test-on-reals angle (lambda (x) (if (exact? x) 0 0.0))) + +(error-test '(make-rectangular 1 'a)) +(error-test '(make-rectangular 'a 1)) +(error-test '(make-rectangular 1+2i 1)) +(error-test '(make-rectangular 1 1+2i)) +(arity-test make-rectangular 2 2) + +(error-test '(make-polar 1 'a)) +(error-test '(make-polar 'a 1)) +(error-test '(make-polar 1+2i 1)) +(error-test '(make-polar 1 1+2i)) +(arity-test make-polar 2 2) + +(error-test '(real-part 'a)) +(error-test '(imag-part 'a)) +(arity-test real-part 1 1) +(arity-test imag-part 1 1) + +(error-test '(angle 'a)) +(error-test '(magnitude 'a)) +(arity-test angle 1 1) +(arity-test magnitude 1 1) + +(test -1 * +i +i) +(test 1 * +i -i) +(test 2 * 1+i 1-i) +(test +2i * 1+i 1+i) +(test 0.5 - (+ 0.5 +i) +i) +(test 1/2 - (+ 1/2 +i) +i) +(test 1.0 - (+ 1 +0.5i) +1/2i) + +(test 1 sqrt 1) +(test 1.0 sqrt 1.0) +(test 25 sqrt 625) +(test 3/7 sqrt 9/49) +(test 0.5 sqrt 0.25) +(test +1i sqrt -1) +(test +2/3i sqrt -4/9) +(test +1.0i sqrt -1.0) +(test 1+1i sqrt +2i) +(test 2+1i sqrt 3+4i) +(test +inf.0 sqrt +inf.0) +(test (make-rectangular 0 +inf.0) sqrt -inf.0) +(test-nan.0 sqrt +nan.0) + +(error-test '(sqrt "a")) +(arity-test sqrt 1 1) + +(test -13/64-21/16i expt -3/4+7/8i 2) +(let ([v (expt -3/4+7/8i 2+3i)]) + (test 3826.0 floor (* 10000000 (real-part v))) + (test -137.0 ceiling (* 100000 (imag-part v)))) +(test 49.0 floor (* 10 (expt 2 2.3))) +(test 189.0 floor (* 1000 (expt 2.3 -2))) +(test 1/4 expt 2 -2) +(test 1/1125899906842624 expt 2 -50) +(test 1/1024 expt 1/2 10) +(test 1024 expt 1/2 -10) +(test 707.0 floor (* 1000 (expt 1/2 1/2))) +(test 707.0 floor (* 1000 (expt 1/2 0.5))) +(test 707.0 floor (* 1000 (expt 0.5 1/2))) +(test +inf.0 expt 2 +inf.0) +(test +inf.0 expt +inf.0 10) +(test 1.0 expt +inf.0 0) +(test 0.0 expt 2 -inf.0) +(test -inf.0 expt -inf.0 11) +(test +inf.0 expt -inf.0 10) +(test 1.0 expt -inf.0 0) +(test-nan.0 expt +nan.0 0) +(test-nan.0 expt +nan.0 10) +(test-nan.0 expt 2 +nan.0) + +;;;;From: fred@sce.carleton.ca (Fred J Kaudel) +;;; Modified by jaffer. +(define f3.9 (string->number "3.9")) +(define f4.0 (string->number "4.0")) +(define f-3.25 (string->number "-3.25")) +(define f.25 (string->number ".25")) +(define f4.5 (string->number "4.5")) +(define f3.5 (string->number "3.5")) +(define f0.0 (string->number "0.0")) +(define f0.8 (string->number "0.8")) +(define f1.0 (string->number "1.0")) +(newline) +(display ";testing inexact numbers; ") +(newline) +(SECTION 6 5 5) +(test #t inexact? f3.9) +(test #f exact? f3.9) +(test #t 'inexact? (inexact? (max f3.9 4))) +(test f4.0 'max (max f3.9 4)) +(test f4.0 'exact->inexact (exact->inexact 4)) + +; Should at least be close... +(test 4.0 round (log (exp 4.0))) +(test 125.0 round (* 1000 (asin (sin 0.125)))) +(test 125.0 round (* 1000 (asin (sin 1/8)))) +(test 125.0 round (* 1000 (acos (cos 0.125)))) +(test 125.0 round (* 1000 (acos (cos 1/8)))) +(test 785.0 round (* 1000 (atan 1 1))) +(test 2356.0 round (* 1000 (atan 1 -1))) +(test -785.0 round (* 1000 (atan -1 1))) +(test 785.0 round (* 1000 (atan 1))) +(test 0.0 atan 0 0) +(test 100.0 round (* 100 (tan (atan 1)))) +(test 1024.0 round (expt 2.0 10.0)) +(test 1024.0 round (expt -2.0 10.0)) +(test -512.0 round (expt -2.0 9.0)) +(test 32.0 round (sqrt 1024.0)) + +(define (test-inf-bad f) + (test-nan.0 f +inf.0) + (test-nan.0 f -inf.0) + (test-nan.0 f +nan.0)) + +(test-inf-bad tan) +(test-inf-bad sin) +(test-inf-bad cos) +(test-inf-bad asin) +(test-inf-bad acos) + +(test 11/7 rationalize (inexact->exact (atan +inf.0 1)) 1/100) +(test -11/7 rationalize (inexact->exact (atan -inf.0 1)) 1/100) +(test 0.0 atan 1 +inf.0) +(test 22/7 rationalize (inexact->exact (atan 1 -inf.0)) 1/100) + +; Is this really right??? +(test 7/9 rationalize (inexact->exact (atan +inf.0 +inf.0)) 1/100) +(test 26/11 rationalize (inexact->exact (atan +inf.0 -inf.0)) 1/100) +(test -7/9 rationalize (inexact->exact (atan -inf.0 +inf.0)) 1/100) + +(test-nan.0 atan +nan.0) +(test-nan.0 atan 1 +nan.0) +(test-nan.0 atan +nan.0 1) + +(map (lambda (f fname) + (error-test `(,fname "a")) + (arity-test f 1 1)) + (list log exp asin acos tan) + `(log exp asin acos tan)) +(error-test '(atan "a" 1)) +(error-test '(atan 2+i 1)) +(error-test '(atan "a")) +(error-test '(atan 1 "a")) +(error-test '(atan 1 2+i)) +(arity-test atan 1 2) + +(define (z-round c) (make-rectangular (round (real-part c)) (round (imag-part c)))) + +(test 3166.+1960.i z-round (* 1000 (sin 1+2i))) +(test -3166.-1960.i z-round (* 1000 (sin -1-2i))) +(test -642.-1069.i z-round (* 1000 (cos 2+i))) +(test -642.-1069.i z-round (* 1000 (cos -2-i))) +(test 272-1084.i z-round (* 1000 (tan 1-i))) +(test -272+1084.i z-round (* 1000 (tan -1+i))) + +(test 693.+3142.i z-round (* 1000 (log -2))) +(test 1571.-1317.i z-round (* 1000 (asin 2))) +(test -1571.+1317.i z-round (* 1000 (asin -2))) +(test +3688.i z-round (* 1000 (acos 20))) +(test 3142.-3688.i z-round (* 1000 (acos -20))) + +(define (cs2 c) (+ (* (cos c) (cos c)) (* (sin c) (sin c)))) +(test 1000.0 round (* 1000 (cs2 2+3i))) +(test 1000.0 round (* 1000 (cs2 -2+3i))) +(test 1000.0 round (* 1000 (cs2 2-3i))) + +(test #t positive? (real-part (sqrt (- 1 (* 2+3i 2+3i))))) + +(test (- f4.0) round (- f4.5)) +(test (- f4.0) round (- f3.5)) +(test (- f4.0) round (- f3.9)) +(test f0.0 round f0.0) +(test f0.0 round f.25) +(test f1.0 round f0.8) +(test f4.0 round f3.5) +(test f4.0 round f4.5) +(let ((x (string->number "4195835.0")) + (y (string->number "3145727.0"))) + (test #t 'pentium-fdiv-bug (> f1.0 (- x (* (/ x y) y))))) + +(test (exact->inexact 1/3) rationalize .3 1/10) +(test 1/3 rationalize 3/10 1/10) +(test (exact->inexact 1/3) rationalize .3 -1/10) +(test 1/3 rationalize 3/10 -1/10) +(test 0 rationalize 3/10 4/10) +(test 0.0 rationalize .3 4/10) + +(define (test-rat-inf v) + (define zero (if (exact? v) 0 0.0)) + + (test +inf.0 rationalize +inf.0 v) + (test -inf.0 rationalize -inf.0 v) + (test-nan.0 rationalize +nan.0 v) + + (test zero rationalize v +inf.0) + (test zero rationalize v -inf.0) + (test-nan.0 rationalize v +nan.0)) + +(let loop ([i 100]) + (unless (= i -100) + (test (/ i 100) rationalize (inexact->exact (/ i 100.0)) 1/100000) + (loop (sub1 i)))) + +(arity-test rationalize 2 2) + +(define tb + (lambda (n1 n2) + (= n1 (+ (* n2 (quotient n1 n2)) + (remainder n1 n2))))) +(newline) +(display ";testing bignums; ") +(newline) +(SECTION 6 5 5) + +(test -2147483648 - 2147483648) +(test 2147483648 - -2147483648) +(test #f = -2147483648 2147483648) +(test #t = -2147483648 -2147483648) +(test #t = 2147483648 2147483648) +(test 2147483647 sub1 2147483648) +(test 2147483648 add1 2147483647) +(test 2147483648 * 1 2147483648) + +(test 437893890380859375 expt 15 15) + +(test 0 modulo -2177452800 86400) +(test 0 modulo 2177452800 -86400) +(test 0 modulo 2177452800 86400) +(test 0 modulo -2177452800 -86400) + +(test 86399 modulo -2177452801 86400) +(test -1 modulo 2177452799 -86400) +(test 1 modulo 2177452801 86400) +(test -86399 modulo -2177452799 -86400) + +(test #t 'remainder (tb 281474976710655 65535)) +(test #t 'remainder (tb 281474976710654 65535)) +(SECTION 6 5 6) +(test 281474976710655 string->number "281474976710655") +(test "281474976710655" number->string 281474976710655) +(test "-4" number->string -4 16) +(test "-e" number->string -14 16) +(test "0" number->string 0 16) +(test "30000000" number->string #x30000000 16) + + +(SECTION 6 5 6) +(test "0" number->string 0) +(test "100" number->string 100) +(test "100" number->string 256 16) +(test 256 string->number "100" 16) +(test 15 string->number "#o17") +(test 15 string->number "#o17" 10) + +(load-relative "numstrs.ss") +(let loop ([l number-table]) + (unless (null? l) + (let* ([pair (car l)] + [v (car pair)] + [v (if (or (eq? v 'X) + (symbol? v) + (eof-object? v)) + #f + v)] + [s (cadr pair)]) + (test v string->number s)) + (loop (cdr l)))) + +(test #f string->number "88" 7) +(test #f string->number "") +(test #f string->number " 1") +(test #f string->number ".") +(test #f string->number "#4@#i5") +(test #t symbol? '1/x) +(test #t symbol? '1+ei) +(test #t symbol? '|1/0|) + +(arity-test string->number 1 2) +(arity-test number->string 1 2) + +(error-test '(number->string 'a)) +(error-test '(number->string 1 'a)) +(error-test '(number->string 'a 10)) +(error-test '(number->string 1.8 8) exn:application:math:radix?) +(error-test '(number->string 1 -1)) + +(error-test '(string->number 'a)) +(error-test '(string->number 'a 'a)) +(error-test '(string->number "12" -1)) +(error-test '(string->number "12" 17)) +(error-test '(string->number "1" "1")) +(error-test '(string->number 1 1)) + +(report-errs) diff --git a/collects/tests/mzscheme/numstrs.ss b/collects/tests/mzscheme/numstrs.ss new file mode 100644 index 0000000..5489fc7 --- /dev/null +++ b/collects/tests/mzscheme/numstrs.ss @@ -0,0 +1,126 @@ + +(define number-table + `((,(+ 1/2 +i) "1/2+i") + (100 "100") + (0.1 ".1") + (1/20000 "#e1/2e-4") + (10.0 "1e1") + (10.0 "1E1") + (10.0 "1s1") + (10.0 "1S1") + (10.0 "1f1") + (10.0 "1F1") + (10.0 "1l1") + (10.0 "1L1") + (10.0 "1d1") + (10.0 "1D1") + (0.0 "0e13") + (+inf.0 ".3e2666666666") + (+inf.0 "+INF.0") + (+nan.0 "+NaN.0") + (10.0 "1#") + (10.0 "1#e0") + (10.0 "1####e-3") + (10.0 "1#.e0") + (10.0 "10.#e0") + (10.0 "10.e0") + (10.0 "1#.e0") + (10.0 "10.0#e0") + (10.0 "1#.##e0") + (10 "#e1#") + (10 "#e1#e0") + (10 "#e1#.e0") + (5e-5 "1/2e-4") + (5e-5 "#i1/2e-4") + (0.5 "#i1/2") + (1/2 "#e1/2") + (0.5 "#i0.5") + (1/2 "#e0.5") + (1/20 "#e0.5e-1") + (1/20 "#e0.005e1") + (1.0+0.5i "1+0.5i") + (1/2 "1/2@0") + (-1/2 "-1/2@0") + (1/2 "1/2@-0") + (0 "#b#e0") + (0.0 "#b#i0") + (4.0 "#b1e10") + (4 "#b#e1e10") + (1/10+1/5i "#e0.1+0.2i") + (0.0+80.0i "#i+8#i") + (521976 "#x7f6f8") + (1+8i "#b#e1+1#e10i") + (1.125 "#x1.2") + + (#f "d") + (D "D") + (#f "i") + (I "I") + (#f "3i") + (3I "3I") + (#f "33i") + (33I "33I") + (#f "3.3i") + (3.3I "3.3I") + (#f "e") + (#f "e1") + (#f "e1") + (#f "-") + (#f "+") + (X "#e-") + (X "#e+") + (X "#i-") + (X "#i+") + (#f "+.") + (X "#e+.") + (#f "/") + (#f "+1+1") + (#f "+1/+1") + (#f "1//2") + (#f "mod//") + (#f "-1.0/2") + (#f "/2") + (#f "2..") + (#f ".2.") + (X "#e2..") + (X "#e.2.") + (#f "1#.0e4") + (#f "1#0e4") + (#f "1#0.e4") + (#f "1##.##0e4") + (#f "2i") + (#f "/2i") + (#f "2@2i") + (#f "2@@2") + (#f "-2@-+2") + (#f "1/1-e4") + (#f "1.-2") + (X "#e1.-2") + (X "#b#b0") + (X "#b#o0") + (X "#i#i0") + (X "#e#e0") + (X "#i8#i") + (X "#i4@#i5") + (X "#i4+#d6i") + (X "#i4+#d6") + (#f "4ef5") + (X "#e4ef5") + (X "1/0") + (X "5+1/0i") + (X "1/0+5i") + (X "5@1/0") + (X "1/0@5") + (X "1/0e2") + (#f "1/0+hi") + (#f "x+1/0i") + (#f "+nan.0+1i") + (#f "1+nan.0i") + (#f "1++nan.0i") + (#f "1+inf.0i") + (#f "1++inf.0i") + (#f "+nan.0@1") + (#f "+inf.0@1") + (#f "1@+inf.0") + (#f "1e1/0") + (#f "011111122222222223333333333444444x"))) diff --git a/collects/tests/mzscheme/object.ss b/collects/tests/mzscheme/object.ss new file mode 100644 index 0000000..ccc6d89 --- /dev/null +++ b/collects/tests/mzscheme/object.ss @@ -0,0 +1,507 @@ + +; Test MzScheme's object system + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'OBJECT) + +(define (test-class* cl* renames) + (syntax-test `(,cl*)) + (syntax-test `(,cl* ,@renames . x)) + (syntax-test `(,cl* ,@renames 0)) + (syntax-test `(,cl* ,@renames () . x)) + (syntax-test `(,cl* ,@renames () 0)) + (syntax-test `(,cl* ,@renames () x)) + (syntax-test `(,cl* ,@renames () ())) + (syntax-test `(,cl* ,@renames () () (0) x)) + (syntax-test `(,cl* ,@renames () () 0)) + (syntax-test `(,cl* ,@renames () () . x)) + (syntax-test `(,cl* ,@renames () () () . x)) + (syntax-test `(,cl* ,@renames () () () x)) + (syntax-test `(,cl* ,@renames () () () public)) + (syntax-test `(,cl* ,@renames () () () (x))) + (syntax-test `(,cl* ,@renames () () (x) ())) + + (begin + (define (try-dotted cl) + (syntax-test `(,cl* ,@renames () () () (,cl . x)))) + + (map try-dotted '(public private inherit rename + inherit-from rename-from + sequence))) + + (begin + (define (try-defn-kind cl) + (syntax-test `(,cl* ,@renames () () () (,cl 8))) + (syntax-test `(,cl* ,@renames () () () (,cl [8 9]))) + (syntax-test `(,cl* ,@renames () () () (,cl [(x) 9]))) + (syntax-test `(,cl* ,@renames () () () (,cl [(x y x) 9]))) + (syntax-test `(,cl* ,@renames () () () (,cl [x . 1]))) + (syntax-test `(,cl* ,@renames () () () (,cl [x 1 . 3]))) + (syntax-test `(,cl* ,@renames () () () (,cl [x 1 3])))) + + (try-defn-kind 'public) + (try-defn-kind 'private)) + + (begin + (define (try-defn-rename-kind cl) + (syntax-test `(,cl* ,@renames () () () (,cl [((x) y) 9]))) + (syntax-test `(,cl* ,@renames () () () (,cl [(x (y)) 9]))) + (syntax-test `(,cl* ,@renames () () () (,cl [(x . y) 9]))) + (syntax-test `(,cl* ,@renames () () () (,cl [(x 1) 9]))) + (syntax-test `(,cl* ,@renames () () () (,cl [(1 x) 9])))) + (try-defn-rename-kind 'public)) + + (begin + (define (try-ref-kind cl) + (syntax-test `(,cl* ,@renames () () () (,cl 8))) + (syntax-test `(,cl* ,@renames () () () (,cl x 8))) + (syntax-test `(,cl* ,@renames () () () (,cl (x . y)))) + (syntax-test `(,cl* ,@renames () () () (,cl (x y z))))) + + (map try-ref-kind '(inherit rename share))) + (error-test `(,cl* ,@renames () () () (inherit x)) exn:object:inherit?) + (error-test `(,cl* ,@renames () () () (inherit (x y))) exn:object:inherit?) + (syntax-test `(,cl* ,@renames () () () (inherit (x y z)))) + (syntax-test `(,cl* ,@renames () () () (inherit (x 5)))) + (syntax-test `(,cl* ,@renames () () () (inherit (x)))) + (syntax-test `(,cl* ,@renames () () () (rename x))) + (syntax-test `(,cl* ,@renames () () () (rename (x)))) + (syntax-test `(,cl* ,@renames () () () (rename ((x) y)))) + (syntax-test `(,cl* ,@renames () () () (rename ((x y) y)))) + (syntax-test `(,cl* ,@renames () () () (rename ((1) y)))) + + (syntax-test `(,cl* ,@renames () () () (sequence 1 . 2))) + + (syntax-test `(,cl* ,@renames () () () (public [x 7] [x 9]))) + (syntax-test `(,cl* ,@renames () () (x) (public [x 7]))) + (syntax-test `(,cl* ,@renames () () (x) (public [(x w) 7]))) + (syntax-test `(,cl* ,@renames () () () (public [(x y) 7] [(z y) 9]))) + (syntax-test `(,cl* ,@renames () () () (public [(x y) 7] [(x z) 9]))) + + (syntax-test `(,cl* ,@renames () a ())) + (syntax-test `(,cl* ,@renames () (1 . a) ()))) + +(test-class* 'class* ()) +(test-class* 'class*/names '((this super))) + +(syntax-test `(class*/names 8 () () () ())) +(syntax-test `(class*/names () () () ())) +(syntax-test `(class*/names (8) () () ())) +(syntax-test `(class*/names (this . 8) () () ())) +(syntax-test `(class*/names (this 8) () () ())) +(syntax-test `(class*/names (this super-init . 8) () () ())) +(syntax-test `(class*/names (this super-init 8) () () ())) + +(test #t class? (class* () () ())) +(test #t class? (class* () () ())) +(test #t class? (class* () () x)) +(test #t class? (class* () () () (public))) +(test #t class? (class* () () () (public sequence))) +(test #t class? (class* () () (x) (public [(y x) 9]))) +(test #t class? (class*/names (this super-init) () () () (public))) + +(syntax-test `(interface)) +(syntax-test `(interface . x)) +(syntax-test `(interface 8)) +(syntax-test `(interface () 8)) +(syntax-test `(interface () x . y)) +(syntax-test `(interface () x 8)) +(syntax-test `(interface () x x)) +(error-test `(interface (8) x) exn:object:interface-type?) + +(test #t interface? (interface ())) +(test #t interface? (interface () x)) +(test #f interface? (class* () () ())) + +(define i0.1 (interface () x y)) +(define i0.2 (interface () y c d)) +(define i1 (interface (i0.1 i0.2) e)) +(define ix (interface () x y)) + +(test #t interface-extension? i1 i0.1) +(test #t interface-extension? i1 i0.2) +(test #f interface-extension? i0.1 i1) +(test #f interface-extension? i0.2 i1) +(test #f interface-extension? i0.2 i0.1) +(test #f interface-extension? i0.1 i0.2) + +(error-test '(let [(bad (class* () (i0.1) ()))] bad) exn:object:implement?) +(test #t class? (class* () (i0.1) () (public x y))) +(error-test '(let ([cl (class* () (i0.1 i0.2) () (public x y c))]) cl) exn:object:implement?) +(error-test '(class* () (i1) () (public x y c)) exn:object:implement?) +(test #t class? (class* () (i0.1 i0.1) () (public x y c d))) +(error-test '(class* () (i1) () (public x y c d)) exn:object:implement?) +(test #t class? (class* () (i1) () (public x y c d e))) + +(define c1 + (let ((v 10)) + (class* '() (i1) (in [in-2 'banana] . in-rest) + (public (x 1) (y 2)) + (private (a in) (b3 3)) + (public (b1 2) (b2 2) (e 0)) + (public (c 3) (d 7) + (f-1-a (lambda () a)) + (f-1-b1 (lambda () b1)) + (f-1-b2 (lambda () b2)) + (f-1-c (lambda () c)) + (f-1-v (lambda () v)) + (f-1-x (lambda () x)) + (f-1-top-a (lambda () (ivar this a))) + (f-1-other-e (lambda (o) (ivar o e))) + (f-1-set-b2 (lambda (v) (set! b2 v) b2)) + (f-1-in-2 (lambda () in-2)) + (f-1-in-rest (lambda () in-rest))) + (sequence + (set! e in))))) + +(test #t implementation? c1 i0.1) +(test #t implementation? c1 i0.2) +(test #t implementation? c1 i1) +(test #f implementation? c1 ix) + +(define o1 (make-object c1 0 'apple "first" "last")) + +(define c2 + (let ((v 20)) + (class c1 () + (inherit b2 (sup-set-b2 f-1-set-b2)) + (rename (also-e e) + (also-b2 b2)) + (public (a 4) (b1 5) (c 6) + (f-2-a (lambda () a)) + (f-2-b1 (lambda () b1)) + (f-2-b2 (lambda () b2)) + (f-2-also-b2 (lambda () also-b2)) + (f-2-c (lambda () c)) + ((i-f-2-v f-2-v) (lambda () v)) + (f-2-v-copy (lambda () (i-f-2-v))) + (f-2-set-b2 (lambda (v) (sup-set-b2 v)))) + (private (y 3)) + (sequence + (super-init 1))))) + +(test #t implementation? c2 i0.1) +(test #t implementation? c2 i0.2) +(test #t implementation? c2 i1) +(test #f implementation? c2 ix) + +(define o2 (make-object c2)) + +(define c2.1 + (class*/names (this c2-init) c2 () () + (sequence + (c2-init)))) + +(define o2.1 (make-object c2.1)) + +(define c3 + (class* () () () + (public (x 6) (z 7) (b2 8) + (f-3-b2 (lambda () b2))))) + +(define o3 (make-object c3)) + +(define c6 + (class null (x-x) + (public + [(i-a x-a) (lambda () 'x-a)] + [(x-a i-a) (lambda () 'i-a)] + [(i-x x-x) (lambda () 'x-x)] + [x-a-copy (lambda () (i-a))] + [i-a-copy (lambda () (x-a))]))) + +(define o6 (make-object c6 'bad)) + +(define c7 + (class*/names (self super-init) () () () + (public + [get-self (lambda () self)]))) + +(define o7 (make-object c7)) + +(define display-test + (lambda (p v) + (printf "Should be ~s: ~s ~a~n" + p v (if (equal? p v) + "" + "ERROR")))) + +(define ivar? exn:object:ivar?) + +(test #t is-a? o1 c1) +(test #t is-a? o1 i1) +(test #t is-a? o2 c1) +(test #t is-a? o2 i1) +(test #f is-a? o1 c2) +(test #t is-a? o2 c2) +(test #t is-a? o2.1 c1) +(test #f is-a? o1 c3) +(test #f is-a? o2 c3) +(test #f is-a? o1 ix) +(test #f is-a? o2 ix) +(test #f is-a? o3 i1) +(test #f is-a? i1 i1) +(test #t subclass? c2 c1) +(test #t subclass? c2.1 c1) +(test #f subclass? c1 c2) +(test #f subclass? c1 c3) +(test #f subclass? i1 c3) +(test #t ivar-in-class? 'f-1-a c1) +(test #t ivar-in-class? 'f-1-a c2) +(test #f ivar-in-class? 'f-2-a c1) +(test #t ivar-in-class? 'f-2-a c2) + +(error-test '(is-a? o1 o1)) +(error-test '(subclass? o1 o1)) +(error-test '(subclass? o1 i1)) +(error-test '(implementation? o1 o1)) +(error-test '(implementation? o1 c1)) +(error-test '(ivar-in-class? 0 c1)) +(error-test '(ivar-in-class? 'a i1)) +(error-test '(ivar-in-class? 'a o1)) + +(arity-test object? 1 1) +(arity-test class? 1 1) +(arity-test interface? 1 1) +(arity-test is-a? 2 2) +(arity-test subclass? 2 2) +(arity-test interface-extension? 2 2) +(arity-test ivar-in-class? 2 2) + +(arity-test uq-ivar 2 2) +(arity-test uq-make-generic 2 2) + +(error-test '(ivar o1 a) ivar?) +(test 4 uq-ivar o2 'a) + +(test 0 'send (send o1 f-1-a)) +(test 1 'send (send o2 f-1-a)) +(test 4 'send (send o2 f-2-a)) + +(test 'apple 'send (send o1 f-1-in-2)) +(test 'banana 'send (send o2 f-1-in-2)) +(test '("first" "last") 'send (send o1 f-1-in-rest)) +(test '() 'send (send o2 f-1-in-rest)) + +(error-test '(send o1 f-1-top-a) ivar?) +(test 4 'send (send o2 f-1-top-a)) + +(test 5 uq-ivar o2 'b1) + +(test 2 'send (send o1 f-1-b1)) +(test 2 'send (send o1 f-1-b2)) +(test 5 'send (send o2 f-1-b1)) +(test 2 'send (send o2 f-1-b2)) +(test 5 'send (send o2 f-2-b1)) +(test 2 'send (send o2 f-2-b2)) +(test 2 'send (send o2 f-2-also-b2)) + +(test 3 uq-ivar o1 'c) +(test 6 uq-ivar o2 'c) + +(test 3 'send (send o1 f-1-c)) +(test 6 'send (send o2 f-1-c)) +(test 6 'send (send o2 f-2-c)) + +(test 7 uq-ivar o1 'd) +(test 7 uq-ivar o2 'd) + +(test 10 'send (send o1 f-1-v)) +(test 10 'send (send o2 f-1-v)) +(test 20 'send (send o2 f-2-v)) +(test 20 'send (send o2 f-2-v-copy)) + +(error-test '(ivar o2 i-f-2-v) ivar?) + +(test 0 'send (send o1 f-1-other-e o1)) +(test 1 'send (send o1 f-1-other-e o2)) + +(test 2 uq-ivar o2 'y) + +(test 3 'send (send o2 f-2-set-b2 3)) +(test 3 'send (send o2 f-2-also-b2)) + +(test 'i-a 'send (send o6 i-a)) +(test 'x-a 'send (send o6 x-a)) +(test 'i-a 'send (send o6 i-a-copy)) +(test 'x-a 'send (send o6 x-a-copy)) +(test 'x-x 'send (send o6 x-x)) + +(test #t eq? o7 (send o7 get-self)) + +(define g1 (make-generic c1 x)) +(test 1 g1 o1) +(test 1 g1 o2) + +(define g2 (make-generic c2 x)) +(test 1 g2 o2) + +(define g0 (make-generic i0.1 x)) +(test 1 g0 o1) +(test 1 g0 o2) +(test 'hi g0 (make-object (class* () (i0.1) () (public [x 'hi][y 'bye])))) + +(error-test '(g2 o1) exn:object:generic?) +(error-test '(g0 o3) exn:object:generic?) + +(error-test '(class* 7 () ()) exn:object:class-type?) +(error-test '(let ([c (class* 7 () ())]) c) exn:object:class-type?) +(error-test '(class* () (i1 7) ()) exn:object:interface-type?) +(error-test '(let ([c (class* () (i1 7) ())]) c) exn:object:interface-type?) +(error-test '(interface (8) x) exn:object:interface-type?) +(error-test '(let ([i (interface (8) x)]) i) exn:object:interface-type?) +(error-test '(interface (i1 8) x) exn:object:interface-type?) +(error-test '(make-generic c2 not-there) exn:object:class-ivar?) + +(error-test '(make-object (class* c1 () ())) exn:object:init:never?) +(error-test '(make-object (let ([c (class* c1 () ())]) c)) exn:object:init:never?) + +(error-test '(make-object + (class* c2 () () (sequence (super-init) (super-init)))) + exn:object:init:multiple?) +(error-test '(make-object + (let ([c (class* c2 () () (sequence (super-init) (super-init)))]) c)) + exn:object:init:multiple?) + +(error-test '(make-object (class null (x))) exn:application:arity?) +(error-test '(make-object (let ([c (class null (x))]) c)) exn:application:arity?) + + +(define c100 + (let loop ([n 99][c c1]) + (if (zero? n) + c + (loop (sub1 n) (class c args + (public (z n)) + (sequence + (apply super-init args))))))) + +(define o100 (make-object c100 100)) +(test 100 'send (send o100 f-1-a)) +(test 1 'ivar (ivar o100 z)) + +(test 5 'init (let ([g-x 8]) (make-object (class* () () ([x (set! g-x 5)]))) g-x)) +(test 8 'init (let ([g-x 8]) (make-object (class* () () ([x (set! g-x 5)])) 0) g-x)) + +(test (letrec ([x x]) x) 'init (send (make-object + (class* () () ([x y] [y x]) (public (f (lambda () x))))) + f)) + +(define inh-test-expr + (lambda (super derive-pre? rename? override? override-pre?) + (let* ([order + (lambda (pre? a b) + (if pre? + (list a b) + (list b a)))] + [base-class + `(class ,(if super + super + '(class null (n) (public [name (lambda () n)]))) + () + ,(if (not rename?) + '(inherit name) + '(rename [super-name name])) + ,@(order + derive-pre? + `(public [w ,(if rename? 'super-name 'name)]) + '(sequence (super-init 'tester))))]) + `(ivar + (make-object + ,(if override? + `(class ,base-class () + ,@(order + override-pre? + '(sequence (super-init)) + '(public [name (lambda () 'o-tester)]))) + base-class)) + w)))) + +(define (do-override-tests super) + (define (eval-test v e) + (teval `(test ,v (quote, e) + (let ([v ,e]) + (if (procedure? v) + (v) + v))))) + + (eval-test '(letrec ([x x]) x) (inh-test-expr super #t #f #f #f)) + (eval-test '(letrec ([x x]) x) (inh-test-expr super #t #f #t #t)) + (eval-test '(letrec ([x x]) x) (inh-test-expr super #f #f #t #t)) + + (eval-test '(letrec ([x x]) x) (inh-test-expr super #t #t #f #f)) + (eval-test '(letrec ([x x]) x) (inh-test-expr super #t #t #t #f)) + (eval-test '(letrec ([x x]) x) (inh-test-expr super #t #t #t #t)) + + (eval-test ''tester (inh-test-expr super #f #f #f #f)) + (eval-test ''o-tester (inh-test-expr super #t #f #t #f)) + (eval-test ''o-tester (inh-test-expr super #f #f #t #f)) + + (eval-test ''tester (inh-test-expr super #f #t #f #f)) + (eval-test ''tester (inh-test-expr super #f #t #t #t)) + (eval-test ''tester (inh-test-expr super #f #t #t #f))) + +(do-override-tests #f) + +(when (defined? 'primclass%) + (error-test '(make-object primclass%) exn:application:arity?) + (error-test '(make-object primsubclass%) exn:application:arity?) + + (define o (make-object primclass% 'tester)) + (arity-test (ivar o name) 0 0) + (test 'tester (ivar o name)) + (test "primclass%" (ivar o class-name)) + + (define o2 (make-object primsubclass% 'tester)) + (arity-test (ivar o2 name) 0 0) + (arity-test (ivar o2 detail) 0 0) + (test 'tester (ivar o2 name)) + (test #f (ivar o2 detail)) + (test "primsubclass%" (ivar o2 class-name)) + + (do-override-tests 'primclass%) + (do-override-tests 'primsubclass%) + + (define name-g (make-generic primclass% name)) + (define class-name-g (make-generic primclass% class-name)) + + (define sub-name-g (make-generic primsubclass% name)) + (define sub-class-name-g (make-generic primsubclass% class-name)) + (define sub-detail-g (make-generic primsubclass% detail)) + + (test 'tester (name-g o)) + (test "primclass%" (class-name-g o)) + + (test 'tester (name-g o2)) + (test "primsubclass%" (class-name-g o2)) + (test 'tester (sub-name-g o2)) + (test "primsubclass%" (sub-class-name-g o2)) + (test #f (sub-detail-g o2)) + + (define c% + (class primsubclass% () + (inherit name detail class-name) + (sequence (super-init 'example)) + (public + [n name] + [d detail] + [c class-name]))) + + (define o3 (make-object c%)) + (test 'example (ivar o3 n)) + (test #f (ivar o3 d)) + (test "primsubclass%" (ivar o3 c)) + (test 'example (ivar o3 name)) + (test #f (ivar o3 detail)) + (test "primsubclass%" (ivar o3 class-name)) + + (test 'example (name-g o3)) + (test "primsubclass%" (class-name-g o3)) + (test 'example (sub-name-g o3)) + (test "primsubclass%" (sub-class-name-g o3)) + (test #f (sub-detail-g o3))) + +(report-errs) + diff --git a/collects/tests/mzscheme/oe.ss b/collects/tests/mzscheme/oe.ss new file mode 100644 index 0000000..b2b1740 --- /dev/null +++ b/collects/tests/mzscheme/oe.ss @@ -0,0 +1,42 @@ +(define-values (odd) (lambda (x) (if (zero? x) #f (even (- x 1))))) +(define-values (even) (lambda (x) (if (zero? x) #t (odd (- x 1))))) + +(define-values (odd2) + (letrec ([even (lambda (x) (if (zero? x) #t (odd (- x 1))))] + [odd (lambda (x) (if (zero? x) #f (even (- x 1))))]) + odd)) + +(define-values (odd3) + (let ([test (lambda (base other) + (lambda (x) (if (zero? x) base ((other) (- x 1)))))]) + (letrec ([odd (test #f (lambda () even))] + [even (test #t (lambda () odd))]) + odd))) + +(define-values (fib) + (lambda (n) + (if (<= n 1) + 1 + (+ (fib (- n 1)) (fib (- n 2)))))) + +(define-values (mutate) + (lambda (n) + (let loop () + (unless (zero? n) + (set! n (sub1 n)) + (loop))))) + +(define-values (mutate-evil) + (lambda (n) + (let loop ([n n]) + (unless (zero? n) + (set! n (sub1 n)) + (loop n))))) + +(define-values (c-loop) + (let-values ([(a b c d e f g) (values 1 2 3 4 5 6 7)]) + (lambda (n) + (let loop ([n n]) + (if (zero? n) + (+ a b c d e f g) + (loop (sub1 n))))))) diff --git a/collects/tests/mzscheme/oee.ss b/collects/tests/mzscheme/oee.ss new file mode 100644 index 0000000..a4a4827 --- /dev/null +++ b/collects/tests/mzscheme/oee.ss @@ -0,0 +1,45 @@ + +; Test the oe extension + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(define b1 (class null () (public [z1 7][z2 8]))) +(define b3 (class null () (public [z1 13][z2 14]))) + +(define i1 (mktinterface (interface () z1))) +(define i3 (mktinterface (interface () z2))) + +(define c1 (mktclass b1 i1)) +(define c3 (mktclass b3 i3)) + +(define o1 (make-object c1 1 2)) +(define o2 (make-object c1 3 4)) +(define o3 (make-object c3 5 6)) + +(test 5 'oee (send o1 get-y)) +(test 5 'oee (send o2 get-y)) +(test 5 'oee (send o3 get-y)) + +(test 7 'oee (send o1 get-z1)) +(test 7 'oee (send o2 get-z1)) +(test 13 'oee (send o3 get-z1)) + +(test 8 'oee (send o1 get-z2)) +(test 8 'oee (send o2 get-z2)) +(test 14 'oee (send o3 get-z2)) + +(test 1 'oee (send o1 get-x1)) +(test 3 'oee (send o2 get-x1)) +(test 5 'oee (send o3 get-x1)) + +(test 2 'oee (send o1 get-x2)) +(test 4 'oee (send o2 get-x2)) +(test 6 'oee (send o3 get-x2)) + +(error-test '(mktinterface 0) exn:object:interface-type?) +(error-test '(mktclass 0 i1) exn:object:class-type?) +(error-test '(mktclass b1 0) exn:object:interface-type?) +(error-test '(mktclass b1 (interface () not-there)) exn:object:implement?) + +(report-errs) diff --git a/collects/tests/mzscheme/optimize.ss b/collects/tests/mzscheme/optimize.ss new file mode 100644 index 0000000..f23115a --- /dev/null +++ b/collects/tests/mzscheme/optimize.ss @@ -0,0 +1,57 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'optimization) + +(define (comp=? c1 c2) + (let ([s1 (open-output-string)] + [s2 (open-output-string)]) + (write c1 s1) + (write c2 s2) + (string=? (get-output-string s1) (get-output-string s2)))) + +(define test-comp + (case-lambda + [(expr1 expr2) (test-comp expr1 expr2 #t)] + [(expr1 expr2 same?) + (test same? `(compile ,same? ,expr2) (comp=? (compile expr1) (compile expr2)))])) + +(test-comp 5 '(if #t 5 (cons 1 2))) +(test-comp 5 '(if #f (cons 1 2) 5)) + +(test-comp 5 '(begin0 5 'hi "apple" 1.5)) +(test-comp 5 '(begin0 5 (begin0 'hi "apple" 1.5))) +(test-comp 5 '(begin0 5 (begin0 'hi "apple") 1.5)) +(test-comp 5 '(begin0 5 (begin 'hi "apple" 1.5))) +(test-comp 5 '(begin0 5 (begin 'hi "apple") 1.5)) +(test-comp 5 '(begin0 (begin0 5 'hi "apple" 1.5))) +(test-comp 5 '(begin0 (begin0 5 'hi "apple") 1.5)) + +(test-comp 5 '(begin 'hi "apple" 1.5 5)) +(test-comp 5 '(begin (begin 'hi "apple" 1.5) 5)) +(test-comp 5 '(begin (begin 'hi "apple") 1.5 5)) +(test-comp 5 '(begin (begin0 'hi "apple" 1.5) 5)) +(test-comp 5 '(begin (begin0 'hi "apple") 1.5 5)) +(test-comp 5 '(begin (begin 'hi "apple" 1.5 5))) +(test-comp 5 '(begin 'hi (begin "apple" 1.5 5))) + +(test-comp '(let ([x 8][y 9]) (lambda () x)) + '(let ([x 8][y 9]) (lambda () (if #f y x)))) +(test-comp '(let ([x 8][y 9]) (lambda () (+ x y))) + '(let ([x 8][y 9]) (lambda () (if #f y (+ x y))))) + +(test-comp '(let ([x 5]) (set! x 2)) '(let ([x 5]) (set! x x) (set! x 2))) + +(test-comp '(let* () (f 5)) + '(f 5)) +(test-comp '(letrec* () (f 5)) + '(f 5)) +(test-comp '(with-handlers () (f 5)) + '(f 5)) +(test-comp '(parameterize () (f 5)) + '(f 5)) +(test-comp '(fluid-let () (f 5)) + '(f 5)) + +(report-errs) diff --git a/collects/tests/mzscheme/parallel.ss b/collects/tests/mzscheme/parallel.ss new file mode 100644 index 0000000..4cab5b5 --- /dev/null +++ b/collects/tests/mzscheme/parallel.ss @@ -0,0 +1,50 @@ + +;; Runs 3 threads perfoming the test suite simultaneously. Each +;; thread creates a directory sub to run in, so that filesystem +;; tests don't collide. + +; Runs n versions of test in parallel threads and namespaces, +; waiting until all are done +(define (parallel n test) + (let ([done (make-semaphore)] + [go (make-semaphore)]) + (let loop ([n n]) + (unless (zero? n) + (let ([ns (make-namespace)] + [p (make-parameterization)]) + (thread + (lambda () + (with-parameterization + p + (lambda () + (parameterize ([current-namespace ns] + [parameterization-branch-handler + (lambda () (make-parameterization p))]) + (let ([dirname (format "sub~s" n)]) + (unless (directory-exists? dirname) + (make-directory dirname)) + (current-directory dirname) + (dynamic-wind + void + (lambda () + (load test)) + (lambda () + (semaphore-post done) + (semaphore-wait go) + (printf "~nThread ~s:" n) + (eval '(report-errs)) + (current-directory (build-path 'up)) + (delete-directory dirname) + (semaphore-post done))))))))) + (loop (sub1 n))))) + (let loop ([n n]) + (unless (zero? n) + (semaphore-wait done) + (loop (sub1 n)))) + (let loop ([n n]) + (unless (zero? n) + (semaphore-post go) + (semaphore-wait done) + (loop (sub1 n)))))) + +(parallel 3 (path->complete-path "all.ss" (current-load-relative-directory))) diff --git a/collects/tests/mzscheme/param.ss b/collects/tests/mzscheme/param.ss new file mode 100644 index 0000000..0c6adff --- /dev/null +++ b/collects/tests/mzscheme/param.ss @@ -0,0 +1,567 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'parameterizations) + +(let ([p (open-output-file "tmp5" 'replace)]) + (display (compile '(cons 1 2)) p) + (close-output-port p)) + +(define-struct tester (x)) +(define a-tester (make-tester 5)) + +(define (check-write-string v s) + (let ([p (open-output-string)]) + (display v p) + (let ([s2 (get-output-string p)]) + (or (string=? s s2) + (error 'check-string "strings didn't match: ~s vs. ~s" + s s2))))) + +(define exn:check-string? exn:user?) + +(define called-break? #f) + +(define erroring-set? #f) + +(define erroring-port + (make-output-port (let ([orig (current-output-port)]) + (lambda (s) + (if erroring-set? + (begin + (set! erroring-set? #f) + (error 'output)) + (display s orig)))) + void)) + +(define erroring-eval + (let ([orig (current-eval)]) + (lambda (x) + (if erroring-set? + (begin + (set! erroring-set? #f) + (error 'eval)) + (orig x))))) + +(define blocking-thread + (lambda (thunk) + (let ([x #f]) + (thread-wait (thread (lambda () (set! x (thunk))))) + x))) + +(define main-cust (current-custodian)) +(define main-executor (current-will-executor)) + +(define zero-arg-proc (lambda () #t)) +(define one-arg-proc (lambda (x) #t)) +(define two-arg-proc (lambda (x y) #t)) +(define three-arg-proc (lambda (x y z) #t)) + +(define test-param1 (make-parameter 'one)) +(define test-param2 (make-parameter + 'two + ; generates type error: + (lambda (x) (if (symbol? x) + x + (add1 'x))))) + +(test 'one test-param1) +(test 'two test-param2) + +(arity-test make-parameter 1 2) +(error-test '(make-parameter 0 zero-arg-proc)) +(error-test '(make-parameter 0 two-arg-proc)) + +(define-struct bad-test (value exn?)) + +(define params (list + (list read-case-sensitive + (list #f #t) + '(if (eq? (read (open-input-string "HELLO")) (quote hello)) + (void) + (error (quote hello))) + exn:user? + #f) + (list read-square-bracket-as-paren + (list #t #f) + '(when (symbol? (read (open-input-string "[4]"))) + (error 'read)) + exn:user? + #f) + (list read-curly-brace-as-paren + (list #t #f) + '(when (symbol? (read (open-input-string "{4}"))) + (error 'read)) + exn:user? + #f) + (list read-accept-box + (list #t #f) + '(read (open-input-string "#&5")) + exn:read:unsupported? + #f) + (list read-accept-graph + (list #t #f) + '(read (open-input-string "#0=(1 . #0#)")) + exn:read:unsupported? + #f) + (list read-accept-compiled + (list #t #f) + '(let ([p (open-input-file "tmp5")]) + (dynamic-wind + void + (lambda () (read p)) + (lambda () (close-input-port p)))) + exn:read:unsupported? + #f) + (list read-accept-type-symbol + (list #t #f) + '(read (open-input-string "#")) + exn:read:unsupported? + #f) + (list read-accept-bar-quote + (list #t #f) + '(let ([p (open-input-string "|hello #$ there| x")]) + (read p) + (read p)) + exn:read:unsupported? + #f) + (list print-graph + (list #t #f) + '(check-write-string (quote (#0=(1 2) . #0#)) "(#0=(1 2) . #0#)") + exn:check-string? + #f) + (list print-struct + (list #t #f) + '(check-write-string a-tester "#(struct:tester 5)") + exn:check-string? + #f) + (list print-box + (list #t #f) + '(check-write-string (box 5) "#&5") + exn:check-string? + #f) + + (list current-input-port + (list (make-input-port (lambda () #\x) (lambda () #t) void) + (make-input-port (lambda () 5) (lambda () #t) void)) + '(read-char) + exn:i/o:user-port? + '("bad string")) + (list current-output-port + (list (current-output-port) + erroring-port) + '(begin + (set! erroring-set? #t) + (display 5) + (set! erroring-set? #f)) + exn:user? + '("bad string")) + +#| + ; Doesn't work since error-test sets the port! + (list current-error-port + (list (current-error-port) + erroring-port) + '(begin + (set! erroring-set? #t) + ((error-display-handler) "hello") + (set! erroring-set? #f)) + exn:user? + "bad setting") +|# + + (list compile-allow-cond-fallthrough + (list #t #f) + '(cond) + exn:else? + #f) + + (list compile-allow-set!-undefined + (list #t #f) + '(eval `(set! ,(gensym) 9)) + exn:variable? + #f) + + (list current-namespace + (list (make-namespace) + (make-namespace 'hash-percent-syntax)) + '(begin 0) + exn:variable? + '("bad setting")) + + (list error-print-width + (list 10 50) + '(when (< 10 (error-print-width)) (error 'print-width)) + exn:user? + '("bad setting")) + (list error-value->string-handler + (list (error-value->string-handler) (lambda (x w) (error 'converter))) + '(format "~e" 10) + exn:user? + (list "bad setting" zero-arg-proc one-arg-proc three-arg-proc)) + + (list debug-info-handler + (list (debug-info-handler) + (lambda () 'boo!)) + `(with-handlers ([(lambda (x) (not (eq? (exn-debug-info x) 'boo!))) void]) + (/ 0)) + exn:application:math:zero? + (list "bad setting" one-arg-proc two-arg-proc)) + + (list user-break-poll-handler + (list (user-break-poll-handler) + (lambda () (set! called-break? #t) #f)) + `(begin + (set! called-break? #f) + ((user-break-poll-handler)) + (if called-break? + (error 'break)) + (set! called-break? #f)) + exn:user? + (list "bad setting" one-arg-proc two-arg-proc)) + (list break-enabled + (list #t #f) + '(let ([cont? #f]) + (thread-wait + (parameterize ([parameterization-branch-handler + current-parameterization]) + (thread + (lambda () + (break-thread (current-thread)) + (sleep) + (set! cont? #t))))) + (when cont? + (error 'break-enabled))) + exn:user? + #f) + ; exception-break-enabled: still needs test! + + (list current-print + (list (current-print) + (lambda (x) (display "frog"))) + `(let ([i (open-input-string "5")] + [o (open-output-string)]) + (parameterize ([current-input-port i] + [current-output-port o]) + (read-eval-print-loop)) + (let ([s (get-output-string o)]) + (unless (char=? #\5 (string-ref s 2)) + (error 'print)))) + exn:user? + (list "bad setting" zero-arg-proc two-arg-proc)) + + (list current-prompt-read + (list (current-prompt-read) + (let ([x #f]) + (lambda () + (set! x (not x)) + (if x + '(quote hi) + eof)))) + `(let ([i (open-input-string "5")] + [o (open-output-string)]) + (parameterize ([current-input-port i] + [current-output-port o]) + (read-eval-print-loop)) + (let ([s (get-output-string o)]) + (unless (and (char=? #\> (string-ref s 0)) + (not (char=? #\h (string-ref s 0)))) + (error 'prompt)))) + exn:user? + (list "bad setting" one-arg-proc two-arg-proc)) + + (list current-load + (list (current-load) (lambda (f) (error "This won't do it"))) + '(load "tmp5") + exn:user? + (list "bad setting" zero-arg-proc two-arg-proc)) + (list current-eval + (list (current-eval) erroring-eval) + '(begin + (set! erroring-set? #t) + (eval 5) + (set! erroring-set? #f)) + exn:user? + (list "bad setting" zero-arg-proc two-arg-proc)) + + (list current-load-relative-directory + (list (current-load-relative-directory) + (build-path (current-load-relative-directory) 'up)) + '(load-relative "loadable.ss") + exn:i/o:filesystem:file? + (append (list 0) + (map + (lambda (t) + (make-bad-test t exn:i/o:filesystem:path?)) + (list + "definitely a bad path" + (string #\a #\nul #\b) + "relative" + (build-path 'up)))) + equal?) + + (list global-port-print-handler + (list write display) + '(let ([s (open-output-string)]) + (print "hi" s) + (unless (char=? #\" (string-ref (get-output-string s) 0)) + (error 'global-port-print-handler))) + exn:user? + (list "bad setting" zero-arg-proc one-arg-proc three-arg-proc)) + + (list current-custodian + (list main-cust (make-custodian)) + '(let ([th (parameterize ([current-custodian main-cust]) + (thread (lambda () (sleep 1))))]) + (kill-thread th)) + exn:misc:thread:kill? + (list "bad setting")) + + (list current-will-executor + (list main-executor (make-will-executor)) + '(unless (eq? main-executor (current-will-executor)) + (error 'will-exec)) + exn:user? + (list "bad setting")) + + (list exit-handler + (list void (lambda (x) (error 'exit-handler))) + '(exit) + exn:user? + (list "bad setting" zero-arg-proc two-arg-proc)) + + (list test-param1 + (list 'one 'bad-one) + '(when (eq? (test-param1) 'bad-one) + (error 'bad-one)) + exn:user? + #f) + (list test-param2 + (list 'two 'bad-two) + '(when (eq? (test-param2) 'bad-two) + (error 'bad-two)) + exn:user? + '("bad string")))) + +(for-each + (lambda (d) + (let ([param (car d)] + [alt1 (caadr d)] + [alt2 (cadadr d)] + [expr (caddr d)] + [exn? (cadddr d)]) + (parameterize ([param alt1]) + (test (void) void (teval expr))) + (parameterize ([param alt2]) + (error-test expr exn?)))) + params) + +(define p1 (make-parameterization)) +(define p2 (make-parameterization p1)) +(define p3 (make-parameterization p2)) +(define p3.again (make-parameterization-with-sharing p3 p3 null void)) + +(test #t parameterization? p1) +(test #f parameterization? 'hi) +(arity-test parameterization? 1 1) + +(test 'one (in-parameterization p3 test-param1)) +(test 'two (in-parameterization p3 test-param2)) + +(define test-param3 (make-parameter 'hi)) +(test 'hi (in-parameterization p3 test-param3)) +((in-parameterization p3 test-param3) 'goodbye) +(test 'goodbye (in-parameterization p3.again test-param3)) + +(arity-test make-parameterization 0 1) +(error-test '(make-parameterization #f)) + +(arity-test in-parameterization 2 2) +(error-test '(in-parameterization #f current-output-port)) +(error-test '(in-parameterization p1 (lambda (x) 8))) +(error-test '(in-parameterization p1 add1)) + +; Randomly set some +(for-each + (lambda (d) + (let* ([param (car d)] + [alt1 (caadr d)]) + (when (zero? (random 2)) + (display "setting ") (display param) (newline) + (test (void) (in-parameterization p1 param) alt1)))) + params) + +(test #f parameter? add1) + +(for-each + (lambda (d) + (let* ([param (car d)] + [alt1 (caadr d)] + [bads (cadddr (cdr d))] + [pp1 (in-parameterization p1 param)]) + (test #t parameter? param) + (arity-test param 0 1) + (arity-test pp1 0 1) + (when bads + (for-each + (lambda (bad) + (let-values ([(bad exn?) + (if (bad-test? bad) + (values (bad-test-value bad) + (bad-test-exn? bad)) + (values bad + exn:application:type?))]) + (error-test `(,param ,bad) exn?) + (error-test `(,pp1 ,bad) exn?))) + bads)))) + params) + +((in-parameterization p1 error-print-width) 577) +(define main-pw (error-print-width)) +(test #f = 577 main-pw) + +(test #t = main-pw (blocking-thread (lambda () (error-print-width)))) +(parameterize ([parameterization-branch-handler + (lambda () + (make-parameterization p1))]) + (test #t equal? '(577 578 578) + (blocking-thread + (lambda () + (list + (begin0 + (error-print-width) + (error-print-width 578)) + (error-print-width) + (blocking-thread ; this thread made with p1's branch handler, which is the default one + (lambda () (error-print-width))))))) + (test #t = main-pw (error-print-width))) + +(test #t = main-pw (error-print-width)) +(test #t = main-pw (blocking-thread (lambda () (error-print-width)))) + +(test 577 'ize (parameterize ([error-print-width 577]) + (error-print-width))) +(test main-pw error-print-width) + +(test 577 with-new-parameterization + (lambda () + (error-print-width 577) + (error-print-width))) +(test main-pw error-print-width) + +(define (make-sharing share-from) + (make-parameterization-with-sharing + p1 #f + (list read-case-sensitive test-param2 test-param1) + (lambda (x) + (if (or (parameter-procedure=? x read-case-sensitive) + (parameter-procedure=? x test-param2)) + share-from + #f)))) + +(define (check-sharing p-share other inh) + (define (check-one-param param v1 v2 shared?) + (with-parameterization + p-share + (lambda () + (test v1 param) + (parameterize ([param v2]) + (test v2 param) + (test (if shared? v2 v1) (in-parameterization other param)) + (test v1 (in-parameterization inh param)) + (if shared? + (begin + ((in-parameterization other param) v1) + (test v1 param) + (param v2)) + (with-parameterization + other + (lambda () + (parameterize ([param v1]) + (test v2 (in-parameterization p-share param))))))) + (test v1 param) + (test v1 (in-parameterization other param)) + (with-parameterization + other + (lambda () + (parameterize ([param v2]) + (test v2 param) + (test v1 (in-parameterization inh param)) + (test (if shared? v2 v1) (in-parameterization p-share param))))) + (with-parameterization + inh + (lambda () + (let ([o1 ((in-parameterization other param))] + [o2 ((in-parameterization p-share param))]) + (parameterize ([param v2]) + (test v2 param) + (test o1 (in-parameterization other param)) + (test o2 (in-parameterization p-share param)))))) + (test v1 param)))) + + (check-one-param read-accept-compiled #f #t #f) + (check-one-param read-case-sensitive #f #t #t) + (check-one-param test-param1 'one 'uno #f) + (check-one-param test-param2 'two 'dos #t)) + +((in-parameterization p1 read-accept-compiled) #f) +((in-parameterization p1 read-case-sensitive) #f) + +((in-parameterization p1 test-param2) 'two) +((in-parameterization p1 test-param1) 'one) + +(define ps1.a (make-sharing p3)) +(define ps1.b (make-sharing p3)) +(define ps2 (make-sharing ps1.a)) + +(check-sharing ps1.a p3 p1) +(check-sharing ps1.b p3 p1) +(check-sharing ps2 p3 p1) +(check-sharing ps2 ps1.a p1) + +(test #t parameterization? (make-parameterization-with-sharing (current-parameterization) #f null void)) +(test #t parameterization? (make-parameterization-with-sharing (current-parameterization) (current-parameterization) null void)) + +(arity-test make-parameterization-with-sharing 4 4) +(error-test '(make-parameterization-with-sharing #f #f null void)) +(error-test '(make-parameterization-with-sharing (current-parameterization) 2 null void)) +(error-test '(make-parameterization-with-sharing (current-parameterization) #f (list 5) void)) +(error-test '(make-parameterization-with-sharing (current-parameterization) #f (list read-case-sensitive read-case-sensitive) void)) +(error-test '(make-parameterization-with-sharing (current-parameterization) #f (list read-case-sensitive) (lambda () 0))) +(error-test '(make-parameterization-with-sharing (current-parameterization) #f (list read-case-sensitive) (lambda (x) 0)) + exn:misc:parameterization?) + +(arity-test with-new-parameterization 1 1) +(arity-test with-parameterization 2 2) + +(arity-test parameterization-branch-handler 0 1) +(error-test '(parameterization-branch-handler 0)) +(error-test '(parameterization-branch-handler (lambda (x) x))) +(error-test '(parameterize ([parameterization-branch-handler void]) + (thread void)) + exn:misc:parameterization?) + +(test #t parameter-procedure=? read-accept-compiled read-accept-compiled) +(test #f parameter-procedure=? read-accept-compiled read-case-sensitive) +(error-test '(parameter-procedure=? read-accept-compiled 5)) +(error-test '(parameter-procedure=? 5 read-accept-compiled)) +(arity-test parameter-procedure=? 2 2) + +; Test current-library-collection-paths? +; Test require-library-use-compiled? + +; Use this with SGC to check GC behavior: +(define save-it #f) +(define (pgc-check) + (let ([rp (current-parameterization)]) + (let loop ([n 100][p rp]) + (if (zero? n) + (set! save-it p) + (begin + (make-parameter n) + (make-parameterization) + (make-parameterization-with-sharing rp rp null void) + (loop (sub1 n) (make-parameterization-with-sharing p p null void))))))) + +(report-errs) diff --git a/collects/tests/mzscheme/path.ss b/collects/tests/mzscheme/path.ss new file mode 100644 index 0000000..003ebb9 --- /dev/null +++ b/collects/tests/mzscheme/path.ss @@ -0,0 +1,326 @@ +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'PATH) + +(test #f relative-path? (current-directory)) +(test #t relative-path? "down") +(test #t relative-path? (build-path 'up "down")) +(test #t relative-path? (build-path 'same "down")) +(test #t relative-path? (build-path 'same "down" "deep")) +(test #f relative-path? (build-path (current-directory) 'up "down")) +(test #f relative-path? (build-path (current-directory) 'same "down")) +(test #f relative-path? (build-path (current-directory) 'same "down" "deep")) +(test #f relative-path? (string #\a #\nul #\b)) + +(arity-test relative-path? 1 1) +(error-test '(relative-path? 'a)) + +(test #t absolute-path? (current-directory)) +(test #f absolute-path? (build-path 'up)) +(test #f absolute-path? (string #\a #\nul #\b)) + +(arity-test absolute-path? 1 1) +(error-test '(absolute-path? 'a)) + +(test #t complete-path? (current-directory)) +(test #f complete-path? (build-path 'up)) +(test #f complete-path? (string #\a #\nul #\b)) + +(arity-test complete-path? 1 1) +(error-test '(complete-path? 'a)) + +(call-with-output-file "tmp6" void 'replace) +(define existant "tmp6") + +(test #t file-exists? existant) + +(test #t make-directory "down") +(test #f make-directory "down") +(test #t directory-exists? "down") +(test #f file-exists? "down") + +(define deepdir (build-path "down" "deep")) +(test #t make-directory deepdir) +(test #f make-directory deepdir) +(test #t directory-exists? deepdir) +(test #f file-exists? deepdir) + +(test #t file-exists? (build-path "down" 'up existant)) +(test #t file-exists? (build-path deepdir 'up 'up existant)) +(test #t file-exists? (build-path 'same deepdir 'same 'up 'same 'up existant)) + +(test #f file-exists? (build-path "down" existant)) +(test #f file-exists? (build-path deepdir 'up existant)) +(test #f file-exists? (build-path 'same deepdir 'same 'same 'up existant)) + +(delete-file "tmp6") + +(test #f file-exists? (build-path "down" 'up "badfile")) +(test #f file-exists? (build-path deepdir 'up 'up "badfile")) +(test #f file-exists? (build-path 'same deepdir 'same 'up 'same 'up "badfile")) + +(error-test '(open-output-file (build-path "wrong" "down" "tmp8")) + exn:i/o:filesystem:file?) +(error-test '(open-output-file (build-path deepdir "wrong" "tmp7")) + exn:i/o:filesystem:file?) + +(define start-time (current-seconds)) +(close-output-port (open-output-file "tmp5" 'replace)) +(close-output-port (open-output-file (build-path "down" "tmp8") 'replace)) +(close-output-port (open-output-file (build-path deepdir "tmp7") 'replace)) +(define end-time (current-seconds)) + +(map + (lambda (f) + (let ([time (seconds->date (file-modify-seconds f))] + [start (seconds->date start-time)] + [end (seconds->date end-time)]) + (test #t = (date-year start) (date-year time) (date-year end)) + (test #t = (date-month start) (date-month time) (date-month end)) + (test #t = (date-day start) (date-day time) (date-day end)) + (test #t = (date-week-day start) (date-week-day time) (date-week-day end)) + (test #t = (date-year-day start) (date-year-day time) (date-year-day end)) + (test #t = (date-hour start) (date-hour time) (date-hour end)) + (test #t <= (date-minute start) (date-minute time) (date-minute end)) + (test #t <= (date-second start) (date-second time) (date-second end)))) + (list "tmp5" + (build-path "down" "tmp8") + (build-path deepdir "tmp7"))) + +(test #t file-exists? "tmp5") +(test #t file-exists? (build-path "down" "tmp8")) +(test #t file-exists? (build-path deepdir "tmp7")) + +(test #t rename-file "tmp5" "tmp5x") +(test #f rename-file "tmp5" "tmp5x") +(test #t rename-file (build-path "down" "tmp8") (build-path "down" "tmp8x")) +(test #f rename-file (build-path "down" "tmp8") (build-path "down" "tmp8x")) +(test #t rename-file (build-path deepdir "tmp7") (build-path deepdir "tmp7x")) +(test #f rename-file (build-path deepdir "tmp7") (build-path deepdir "tmp7x")) + +(test #t rename-file (build-path deepdir "tmp7x") "tmp7x") +(test #f rename-file (build-path deepdir "tmp7x") "tmp7x") +(test #t rename-file "tmp7x" (build-path deepdir "tmp7x")) +(test #f rename-file "tmp7x" (build-path deepdir "tmp7x")) + +(test #f not (member "tmp5x" (directory-list))) +(test #t 'directory-list + (let ([l (directory-list "down")]) + (or (equal? l '("deep" "tmp8x")) + (equal? l '("tmp8x" "deep"))))) +(test '("tmp7x") directory-list deepdir) + +(test #f delete-directory deepdir) +(test #f delete-directory "down") + +(test #t delete-file (build-path deepdir "tmp7x")) +(test #f delete-file (build-path deepdir "tmp7x")) +(test #t delete-file (build-path "down" "tmp8x")) +(test #f delete-file (build-path "down" "tmp8x")) +(test #t delete-file "tmp5x") +(test #f delete-file "tmp5x") + +(test #f delete-directory "down") +(test #t delete-directory deepdir) +(test #f delete-directory deepdir) +(test #t delete-directory "down") +(test #f delete-directory "down") + +; Redefine these per-platform +(define drives null) +(define nondrive-roots (list "/")) +(define a (list "a")) +(define a/b (list "a/b" "a//b")) +(define a/b/c (list "a/b/c" "a//b/c")) +(define /a/b (list "/a/b")) +(define a/../b (list "a/../b")) +(define a/./b (list "a/./b")) +(define a/../../b (list "a/../../b")) +(define trail-sep "/") + +(define add-slashes + (lambda (l) + (if (null? l) + null + (let loop ([s (car l)][rest (add-slashes (cdr l))]) + (let ([naya (regexp-replace "/" s "\\")]) + (if (string=? naya s) + (cons s rest) + (loop naya (cons s rest)))))))) + +(when (eq? (system-type) 'windows) + (set! drives (list "c:" "c:/" "//hello/start" "//hello/start/")) + (set! nondrive-roots null) + (for-each + (lambda (var) + (eval `(set! ,var (add-slashes ,var)))) + '(a a/b a/b/c /a/b a/../b a/./b a/../../b))) + + +(when (eq? (system-type) 'macos) + (set! drives null) + (set! nondrive-roots (filesystem-root-list)) + (set! a (list ":a")) + (set! a/b (list ":a:b")) + (set! a/b/c (list ":a:b:c")) + (set! /a/b (list "a:b")) + (set! a/../b (list ":a::b")) + (set! a/./b null) + (set! a/../../b (list ":a:::b")) + (set! trail-sep ":")) + +(define roots (append drives nondrive-roots)) + +(define a/ (map (lambda (s) (string-append s trail-sep)) a)) +(define a/b/ (map (lambda (s) (string-append s trail-sep)) a/b)) +(define a/b/c/ (map (lambda (s) (string-append s trail-sep)) a/b/c)) +(define /a/b/ (map (lambda (s) (string-append s trail-sep)) /a/b)) + +(define absols (append roots /a/b /a/b/)) +(define nondrive-absols (append nondrive-roots /a/b /a/b/)) +(define rels (append a a/ a/b a/b/ a/b/c a/b/c/ a/../b a/./b a/../../b)) + +(define i (lambda (x) x)) + +(test #f ormap i (map relative-path? roots)) +(test #t andmap i (map relative-path? a/b)) +(test #f ormap i (map relative-path? /a/b)) + +(test #t andmap i (map absolute-path? roots)) +(test #f ormap i (map absolute-path? a/b)) + +(test #t andmap i (map complete-path? drives)) +(test #t andmap i (map complete-path? nondrive-roots)) +(test #f ormap i (map complete-path? a/b)) + +(for-each + (lambda (abs) + (for-each + (lambda (rel) + (test #t string? (build-path abs rel)) + (for-each + (lambda (rel2) + (test #t string? (build-path abs rel rel2))) + rels)) + rels)) + absols) + +(for-each + (lambda (drive) + (for-each + (lambda (root) + (test #t string? (build-path drive root)) + (for-each + (lambda (rel) + (test #t string? (build-path drive root rel))) + rels)) + nondrive-absols)) + drives) + +(for-each + (lambda (rel) + (test (build-path (current-directory) rel) + path->complete-path rel)) + rels) + +(define (test-path expect f . args) + (test (normal-case-path (expand-path expect)) + normal-case-path (expand-path (apply f args)))) + +(for-each + (lambda (absol) + (let ([cabsol (path->complete-path absol)]) + (for-each + (lambda (rel) + (test-path (build-path cabsol rel) path->complete-path rel cabsol) + (test-path (build-path cabsol rel rel) path->complete-path rel (build-path cabsol rel)) + (error-test `(path->complete-path ,rel ,rel) exn:i/o:filesystem:path?)) + rels))) + absols) + +(for-each + (lambda (drive) + (for-each + (lambda (rel) + (unless (relative-path? rel) + (test-path (build-path (current-drive) rel) + path->complete-path rel)) + (test-path (build-path drive rel) path->complete-path rel drive) + (test-path (if (relative-path? rel) + (build-path drive rel rel) + (build-path drive rel)) + path->complete-path rel (build-path drive rel))) + (append rels nondrive-absols))) + drives) + +(for-each + (lambda (drive) + (test drive path->complete-path drive) + (test drive path->complete-path drive drive)) + drives) + +(unless (eq? (system-type) 'macos) + (for-each + (lambda (abs1) + (for-each + (lambda (abs2) + (error-test `(build-path ,abs1 ,abs2) exn:i/o:filesystem:path?)) + absols)) + nondrive-roots)) + +(for-each + (lambda (root) + (let-values ([(base name dir?) (split-path root)]) + (test #f 'split-path base) + (test #t 'split-path dir?))) + roots) + +(let ([check-a/b + (lambda (a/b end/?) + (for-each + (lambda (path) + (let*-values ([(base name dir?) (split-path path)] + [(base2 name2 dir?2) (split-path base)]) + (test "b" substring name 0 1) + (test end/? 'split-path dir?) + (test "a" substring name2 0 1) + (test 'relative 'split-path base2) + (test #t 'split-path dir?2) + (for-each + (lambda (root) + (let ([bigpath (build-path root path)]) + (let*-values ([(base name dir?) (split-path bigpath)] + [(base2 name2 dir?2) (split-path base)] + [(base3 name3 dir?3) (split-path base2)]) + (test #f 'split-path base3) + (test #t 'split-path dir?3)))) + roots))) + a/b))]) + (check-a/b a/b #f) + (check-a/b a/b/ #t)) + +(arity-test split-path 1 1) + +(arity-test path->complete-path 1 2) +(error-test '(path->complete-path 1)) +(error-test '(path->complete-path "a" 1)) + +(map + (lambda (f) + (error-test `(,f (string #\a #\nul #\b)) exn:i/o:filesystem:path?)) + '(build-path split-path file-exists? directory-exists? + delete-file directory-list make-directory delete-directory + file-modify-seconds file-or-directory-permissions + expand-path resolve-path path->complete-path + open-input-file open-output-file)) +(map + (lambda (f) + (error-test `(,f (string #\a #\nul #\b) "a") exn:i/o:filesystem:path?) + (error-test `(,f "a" (string #\a #\nul #\b)) exn:i/o:filesystem:path?)) + '(rename-file path->complete-path)) + +; normal-case-path doesn't check for pathness: +(test #t string? (normal-case-path (string #\a #\nul #\b))) + +(report-errs) diff --git a/collects/tests/mzscheme/pconvert.ss b/collects/tests/mzscheme/pconvert.ss new file mode 100644 index 0000000..078ce91 --- /dev/null +++ b/collects/tests/mzscheme/pconvert.ss @@ -0,0 +1,261 @@ + +(unless (defined? 'SECTION) + (load-relative "testing.ss")) + +(SECTION 'pconvert) + +(require-library "pconver.ss") + +(constructor-style-printing #t) +(quasi-read-style-printing #f) + +(define (xl) 1) +(define (xu) (unit (import) (export))) +(define (xc) (class '() ())) + +(begin + (define-struct test (value constructor-sexp shared-constructor-sexp + quasi-sexp shared-quasi-sexp cons-as-list)) + + (define-struct no-cons-test (value constructor-sexp shared-constructor-sexp + quasi-sexp shared-quasi-sexp)) + (define-struct same-test (value sexp)) + (define get-value + (lambda (test-case) + (cond + [(test? test-case) + (test-value test-case)] + [(no-cons-test? test-case) + (no-cons-test-value test-case)] + [(same-test? test-case) + (same-test-value test-case)]))) + (define run-test + (lambda (test-case) + (let* ([before (get-value test-case)] + [cmp + (lambda (selector constructor-style? quasi-read? sharing? cons-as-list?) + (unless (parameterize ([constructor-style-printing constructor-style?] + [show-sharing sharing?] + [quasi-read-style-printing quasi-read?] + [abbreviate-cons-as-list cons-as-list?]) + (test (selector test-case) print-convert before)) + (printf ">> (constructor-style-printing ~a) (quasi-read-style-printing ~a) (show-sharing ~a) (abbreviate-cons-as-list ~a)~n" + constructor-style? quasi-read? sharing? cons-as-list?)))]) + ;(printf "testing: ~s~n" before) + ;(printf ".") (flush-output (current-output-port)) + (cond + [(test? test-case) + (cmp test-shared-constructor-sexp #t #f #t #t) + (cmp test-constructor-sexp #t #f #f #t) + (cmp test-shared-quasi-sexp #f #f #t #t) + (cmp test-quasi-sexp #f #f #f #t) + (cmp test-cons-as-list #t #f #f #f)] + [(no-cons-test? test-case) + (cmp no-cons-test-shared-constructor-sexp #t #f #t #t) + (cmp no-cons-test-constructor-sexp #t #f #f #t) + (cmp no-cons-test-shared-quasi-sexp #f #f #t #t) + (cmp no-cons-test-quasi-sexp #f #f #f #t)] + [(same-test? test-case) + (cmp same-test-sexp #t #t #t #t) + (cmp same-test-sexp #t #t #t #f) + (cmp same-test-sexp #t #t #f #t) + (cmp same-test-sexp #t #t #f #f) + (cmp same-test-sexp #t #f #t #t) + (cmp same-test-sexp #t #f #t #f) + (cmp same-test-sexp #t #f #f #t) + (cmp same-test-sexp #t #f #f #f) + (cmp same-test-sexp #f #t #t #t) + (cmp same-test-sexp #f #t #t #f) + (cmp same-test-sexp #f #t #f #t) + (cmp same-test-sexp #f #t #f #f) + (cmp same-test-sexp #f #f #t #t) + (cmp same-test-sexp #f #f #t #f) + (cmp same-test-sexp #f #f #f #t) + (cmp same-test-sexp #f #f #f #f)])))) + + (define + tests + (list + (make-same-test "abc" "abc") + (make-same-test 8 8) + (make-same-test 'a ''a) + (make-test (list 1) '(list 1) '(list 1) '`(1) '`(1) '(cons 1 null)) + (make-same-test (vector 0 0 0 0 0 0 0 0 0 0) '(vector 0 0 0 0 0 0 0 0 0 0)) + (make-same-test (delay 1) '(delay ...)) + (make-same-test (let-struct a (a) (make-a 3)) '(make-a 3)) + (make-same-test (box 3) '(box 3)) + (make-test null 'null 'null '`() '`() 'null) + (make-same-test add1 'add1) + (make-same-test (void) '(void)) + (make-same-test (unit (import) (export)) '(unit ...)) + (make-same-test (make-weak-box 12) '(make-weak-box 12)) + (make-same-test (regexp "1") '(regexp ...)) + (make-same-test (lambda () 0) '(lambda () ...)) + (make-same-test xl 'xl) + (make-same-test (letrec ([xl (lambda () 1)]) xl) '(lambda () ...)) + (make-same-test (letrec ([xl-ID-BETTER-NOT-BE-DEFINED (lambda () 1)]) + xl-ID-BETTER-NOT-BE-DEFINED) + '(lambda () ...)) + (make-same-test xc 'xc) + (make-same-test (letrec ([xc (class '() ())]) xc) '(class ...)) + (make-same-test (letrec ([xc-ID-BETTER-NOT-BE-DEFINED (class '() ())]) + xc-ID-BETTER-NOT-BE-DEFINED) + '(class ...)) + (make-same-test xu 'xu) + (make-same-test (letrec ([xu (unit (import) (export))]) xu) + '(unit ...)) + (make-same-test (letrec ([xu-ID-BETTER-NOT-BE-DEFINED (unit (import) (export))]) + xu-ID-BETTER-NOT-BE-DEFINED) + '(unit ...)) + (make-same-test (lambda (x) x) '(lambda (a1) ...)) + (make-same-test (lambda x x) '(lambda args ...)) + (make-same-test (lambda (a b . c) a) '(lambda (a1 a2 . args) ...)) + (make-same-test (case-lambda) '(case-lambda)) + (make-same-test (case-lambda [() a] [(x) a]) '(case-lambda [() ...] [(a1) ...])) + (make-same-test (case-lambda [() a] [(x y) a]) + '(case-lambda [() ...] [(a1 a2) ...])) + (make-same-test (case-lambda [() a] [(x . y) a]) + '(case-lambda [() ...] [(a1 . args) ...])) + (make-same-test (case-lambda [() a] [x a]) + '(case-lambda [() ...] [args ...])) + (make-same-test (case-lambda [() a] [(x y z) a] [x a]) + '(case-lambda [() ...] [(a1 a2 a3) ...] [args ...])) + (make-same-test (let ([ht (make-hash-table)]) + (hash-table-put! ht 'x 1) + ht) + '(make-hash-table)) + (make-test (list 'a (box (list ())) (cons 1 '())) + '(list (quote a) (box (list null)) (list 1)) + '(list (quote a) (box (list null)) (list 1)) + '`(a ,(box `(())) (1)) + '`(a ,(box `(())) (1)) + '(cons 'a + (cons (box (cons null null)) + (cons (cons 1 null) + null)))) + (make-test (let ([x (list 1)]) (set-car! x x) x) + '(shared ([-0- (list -0-)]) -0-) + '(shared ([-0- (list -0-)]) -0-) + '(shared ([-0- `(,-0-)]) -0-) + '(shared ([-0- `(,-0-)]) -0-) + '(shared ([-0- (cons -0- null)]) -0-)) + (make-test (let ([x (list 1)]) (set-cdr! x x) x) + '(shared ([-0- (cons 1 -0-)]) -0-) + '(shared ([-0- (cons 1 -0-)]) -0-) + '(shared ([-0- `(1 . ,-0-)]) -0-) + '(shared ([-0- `(1 . ,-0-)]) -0-) + '(shared ([-0- (cons 1 -0-)]) -0-)) + (make-test (let* ([a (list 1 2 3)] + [b (list 1 a (cdr a))]) + (set-car! b b) + (append b (list (list 2 3)))) + '(shared ([-1- (list -1- (list 1 2 3) (list 2 3))]) + (list -1- (list 1 2 3) (list 2 3) (list 2 3))) + '(shared ([-1- (list -1- -3- -4-)] + [-3- (cons 1 -4-)] + [-4- (list 2 3)]) + (list -1- -3- -4- (list 2 3))) + '(shared ([-1- `(,-1- (1 2 3) (2 3))]) + `(,-1- (1 2 3) (2 3) (2 3))) + '(shared ([-1- `(,-1- ,-3- ,-4-)] + [-3- `(1 . ,-4-)] + [-4- `(2 3)]) + `(,-1- ,-3- ,-4- (2 3))) + '(shared ([-1- (cons -1- + (cons (cons 1 (cons 2 (cons 3 null))) + (cons (cons 2 (cons 3 null)) + null)))]) + (cons -1- + (cons (cons 1 (cons 2 (cons 3 null))) + (cons (cons 2 (cons 3 null)) + (cons (cons 2 (cons 3 null)) + null)))))) + (make-no-cons-test (let* ([a (list 1 2 3)] + [b (list 1 a (cdr a))]) + (set-car! b b) + (let* ([share-list (append b (list (list 2 3)))] + [v (vector 1 share-list (cdr share-list))]) + (vector-set! v 0 v) + v)) + '(shared + ((-0- (vector -0- + (list -2- + (list 1 2 3) + (list 2 3) + (list 2 3)) + (list (list 1 2 3) + (list 2 3) + (list 2 3)))) + (-2- (list -2- (list 1 2 3) (list 2 3)))) + -0-) + '(shared + ((-0- (vector -0- (cons -2- -8-) -8-)) + (-2- (list -2- -4- -5-)) + (-4- (cons 1 -5-)) + (-5- (list 2 3)) + (-8- (list -4- -5- (list 2 3)))) + -0-) + '(shared + ((-0- (vector -0- + `(,-2- + (1 2 3) + (2 3) + (2 3)) + `((1 2 3) + (2 3) + (2 3)))) + (-2- `(,-2- (1 2 3) (2 3)))) + -0-) + '(shared + ((-0- (vector -0- `(,-2- . ,-8-) -8-)) + (-2- `(,-2- ,-4- ,-5-)) + (-4- `(1 . ,-5-)) + (-5- `(2 3)) + (-8- `(,-4- ,-5- (2 3)))) + -0-)))) + (for-each run-test tests)) + +(begin + (define make-test-shared + (lambda (shared?) + (lambda (object output) + (parameterize ([constructor-style-printing #t] + [show-sharing #t] + [quasi-read-style-printing #f] + [abbreviate-cons-as-list #t]) + (test (if shared? + `(shared ((-1- ,output)) + (list -1- -1-)) + `(list ,output ,output)) + print-convert + (list object object)))))) + (define test-shared (make-test-shared #t)) + (define test-not-shared (make-test-shared #f)) + + (test-not-shared #t #t) + (test-not-shared #f #f) + (test-not-shared 1 1) + (test-not-shared 3276832768 3276832768) + (test-not-shared (regexp "") '(regexp ...)) + (let ([in (open-input-string "")]) (test-not-shared in in)) + (let ([out (open-output-string)]) (test-not-shared out out)) + (test-not-shared #\a #\a) + (test-not-shared 'x ''x) + (test-not-shared (lambda (x) x) '(lambda (a1) ...)) + (test-not-shared (make-promise (lambda () 1)) '(delay ...)) + (test-not-shared (class () ()) '(class ...)) + (test-not-shared (unit (import) (export)) '(unit ...)) + (test-not-shared (make-object (class () ())) '(make-object (class ...))) + + (test-shared "abc" "abc") + (test-shared (list 1 2 3) '(list 1 2 3)) + (test-shared (vector 1 2 3) '(vector 1 2 3)) + (let-struct a () (test-shared (make-a) '(make-a))) + (test-shared (box 1) '(box 1)) + (test-shared (make-hash-table) '(make-hash-table))) + +(arity-test print-convert 1 2) +(arity-test build-share 1 1) +(arity-test get-shared 1 2) +(arity-test print-convert-expr 3 3) +(report-errs) diff --git a/collects/tests/mzscheme/pretty.ss b/collects/tests/mzscheme/pretty.ss new file mode 100644 index 0000000..7bef9fe --- /dev/null +++ b/collects/tests/mzscheme/pretty.ss @@ -0,0 +1,64 @@ + +; Test pretty-print; relies on personal inspection of the results + +(require-library "pretty.ss") + +(define-struct s (a b c)) + +(define (make k?) + (let ([make (if k? make (lambda (x) '(end)))]) + (list + 1 + 'a + "a" + (list 'long-name-numero-uno-one-the-first-supreme-item + 'long-name-number-two-di-ar-ge-second-line) + (map (lambda (v v2) + (make-s v 2 v2)) + (make #f) + (reverse (make #f))) + '(1) + '(1 2 3) + '(1 . 2) + #(1 2 3 4 5) + '(#0=() . #0#) + '#1=(1 . #1#) + (map box (make #f)) + (make #f)))) + +(define vs (make #t)) + +(define print-line-no + (lambda (line port offset width) + (if line + (begin + (when (positive? line) (write-char #\newline port)) + (fprintf port "~s~a~a~a " line + (if (< line 10) " " "") + (if (< line 100) " " "") + (if (< line 1000) " " "")) + 5) + (fprintf port "!~n")))) + +(define modes + (list + (list "DEPTH=2" pretty-print-depth 2) + (list "GRAPH-ON" print-graph #t) + (list "STRUCT-ON" print-struct #t) + (list "LINE-NO-ON" pretty-print-print-line print-line-no))) + +(define num-combinations (arithmetic-shift 1 (length modes))) + +(let loop ([n 0]) + (when (< n num-combinations) + (let loop ([modes modes][n n]) + (cond + [(null? modes) (printf ":~n") (map pretty-print vs)] + [(positive? (bitwise-and n 1)) + (let ([mode (car modes)]) + (printf "~s " (car mode)) + (parameterize ([(cadr mode) (caddr mode)]) + (loop (cdr modes) (arithmetic-shift n -1))))] + [else + (loop (cdr modes) (arithmetic-shift n -1))])) + (loop (add1 n)))) diff --git a/collects/tests/mzscheme/quiet.ss b/collects/tests/mzscheme/quiet.ss new file mode 100644 index 0000000..8bd4810 --- /dev/null +++ b/collects/tests/mzscheme/quiet.ss @@ -0,0 +1,9 @@ + +(unless (defined? 'quiet-load) + (define quiet-load "all.ss")) + +(let ([p (make-output-port void void)]) + (parameterize ([current-output-port p]) + (load-relative quiet-load)) + (report-errs)) + diff --git a/collects/tests/mzscheme/read.ss b/collects/tests/mzscheme/read.ss new file mode 100644 index 0000000..ab34213 --- /dev/null +++ b/collects/tests/mzscheme/read.ss @@ -0,0 +1,168 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'READING) +(define readstr + (lambda (s) + (let* ([o (open-input-string s)] + [read (if (defined? 'read/zodiac) + (let ([r (read/zodiac (open-input-string s))]) + (lambda () + (let ([orig (error-escape-handler )]) + (dynamic-wind + (lambda () (error-escape-handler + (lambda () + (error-escape-handler orig) + (error 'read/zodiac)))) + r + (lambda () (error-escape-handler orig)))))) + (lambda () (read o)))]) + (let loop ([last eof]) + (let ([v (read)]) + (if (eof-object? v) + last + (loop v))))))) + +(define readerrtype + (if (defined? 'read/zodiac) + (lambda (x) (lambda (y) #t)) + (lambda (x) x))) + +; Make sure {whitespace} == {delimiter} +(let ([with-censor (load-relative "censor.ss")]) + (with-censor + (lambda () + (let loop ([n 0]) + (unless (= n 256) + (let* ([c0 (integer->char n)] + [c (if (read-case-sensitive) + c0 + (char-downcase c0))]) + (cond + [(char-whitespace? c) + (test 'b readstr (string #\a c #\b))] + [(char=? #\\ c) (test 'ab readstr (string #\a c #\b))] + [(char=? #\; c) (test 'a readstr (string #\a c #\b))] + [(char=? #\' c) (test ''b readstr (string #\a c #\b))] + [(char=? #\` c) (test '`b readstr (string #\a c #\b))] + [(char=? #\, c) (test ',b readstr (string #\a c #\b))] + [else + (test (string->symbol (string #\a (char-downcase c) #\b)) + 'readstr + (with-handlers ([void + (lambda (x) + (string->symbol (string #\a (char-downcase c) #\b)))]) + (readstr (string #\a c #\b))))])) + (loop (add1 n))))))) + +(error-test '(readstr ")") (readerrtype exn:read:paren?)) +(error-test '(readstr "[)") (readerrtype exn:read:paren?)) +(error-test '(readstr "[}") (readerrtype exn:read:paren?)) +(error-test '(readstr "8 )") (readerrtype exn:read:paren?)) +(error-test '(readstr "(8 . )") (readerrtype exn:read:paren?)) + +(load-relative "numstrs.ss") +(let loop ([l number-table]) + (unless (null? l) + (let* ([pair (car l)] + [v (car pair)] + [s (cadr pair)]) + (cond + [(eq? v 'X) (error-test `(readstr ,s) (readerrtype exn:read:number?))] + [v (test v readstr s)] + [else (test (string->symbol s) readstr s)])) + (loop (cdr l)))) + +(error-test '(readstr "#\\silly") (readerrtype exn:read:char?)) +(error-test '(readstr "#\\nully") (readerrtype exn:read:char?)) +(error-test '(readstr "#\\nu") (readerrtype exn:read:char?)) +(error-test '(readstr "#\\733") (readerrtype exn:read:char?)) +(error-test '(readstr "#\\433") (readerrtype exn:read:char?)) + +(error-test '(readstr "(hi") (readerrtype exn:read:eof?)) +(error-test '(readstr "\"hi") (readerrtype exn:read:eof?)) +(error-test '(readstr "#(hi") (readerrtype exn:read:eof?)) +(error-test '(readstr "#4(hi") (readerrtype exn:read:eof?)) +(error-test '(readstr "|hi") (readerrtype exn:read:eof?)) +(error-test '(readstr "#\\") (readerrtype exn:read:eof?)) +(error-test '(readstr "#| hi") (readerrtype exn:read:eof?)) + +(error-test '(readstr ".") (readerrtype exn:read:dot?)) +(error-test '(readstr "a .") (readerrtype exn:read:dot?)) +(error-test '(readstr "a . b") (readerrtype exn:read:dot?)) +(error-test '(readstr "( . )") (readerrtype exn:read:dot?)) +(error-test '(readstr "( . 8)") (readerrtype exn:read:dot?)) +(error-test '(readstr "(0 . 8 9)") (readerrtype exn:read:dot?)) +(error-test '(readstr "( . 8 9)") (readerrtype exn:read:dot?)) +(error-test '(readstr "#(8 . )") (readerrtype exn:read:dot?)) +(error-test '(readstr "#( . )") (readerrtype exn:read:dot?)) +(error-test '(readstr "#( . 8)") (readerrtype exn:read:dot?)) +(error-test '(readstr "#(0 . 8 9)") (readerrtype exn:read:dot?)) +(error-test '(readstr "#( . 8 9)") (readerrtype exn:read:dot?)) +(error-test '(readstr "#( 8 . 9)") (readerrtype exn:read:dot?)) +(error-test '(readstr "#( 8 . (9))") (readerrtype exn:read:dot?)) + +(error-test '(readstr "#Q") (readerrtype exn:read:unsupported?)) +(error-test '(readstr "##") (readerrtype exn:read:unsupported?)) +(error-test '(readstr "#?") (readerrtype exn:read:unsupported?)) +(error-test '(readstr "#-1()") (readerrtype exn:read:unsupported?)) + +(test 2 vector-length (readstr "#2()")) +(test 0 vector-ref (readstr "#2()") 1) +(test 2 vector-length (readstr "#000000000000000000000000000000002()")) + +(error-test '(readstr "#2(1 2 3)") (readerrtype exn:read:vector-length?)) +(error-test '(readstr "#200000000000(1 2 3)") (readerrtype exn:misc:out-of-memory?)) + +(unless (defined? 'read/zodiac) + (test #t (lambda (x) (eq? (car x) (cdr x))) (readstr "(#0=(1 2) . #0#)")) + (test #t (lambda (x) (eq? (car x) (cdr x))) (readstr "(#1=(1 2) . #0001#)"))) + +(error-test '(readstr "#0#") (readerrtype exn:read:graph?)) +(error-test '(readstr "#0=#0#") (readerrtype exn:read:graph?)) +(error-test '(readstr "(#0# #0=7)") (readerrtype exn:read:graph?)) +(error-test '(readstr "(#0=7 #1#)") (readerrtype exn:read:graph?)) +(error-test '(readstr "#012345678=7") (readerrtype exn:read:graph?)) +(error-test '(readstr "(#12345678=7 #012345678#)") (readerrtype exn:read:graph?)) + +(test 3 string-length (readstr (string #\" #\a #\nul #\b #\"))) +(test (string->symbol (string #\a #\nul #\b)) 'sym (readstr (string #\a #\nul #\b))) +(test (string->symbol (string #\1 #\nul #\b)) 'sym (readstr (string #\1 #\nul #\b))) + +; Test read/write invariance on symbols and use of pipe quotes +(define (test-write-sym with-bar without-bar s) + (let ([sym (string->symbol s)]) + (parameterize ([read-case-sensitive #t]) + (let ([p (open-output-string)]) + (write sym p) + (test with-bar 'write-sym-with-bar (get-output-string p)) + (test sym read (open-input-string (get-output-string p)))) + (let ([p (open-output-string)]) + (parameterize ([read-accept-bar-quote #f]) + (write sym p) + (test without-bar 'write-sym-no-bar (get-output-string p)) + (test sym read (open-input-string (get-output-string p))))) + (let ([p (open-output-string)]) + (display sym p) + (test s 'display-sym (get-output-string p)))))) + +(test-write-sym "a->b" "a->b" "a->b") +(test-write-sym "|a,b|" "a\\,b" "a,b") +(test-write-sym "a\\|b" "a|b" "a|b") +(test-write-sym "|a\\b|" "a\\\\b" "a\\b") + +(load-relative "numstrs.ss") +(let loop ([l number-table]) + (cond + [(null? l) 'done] + [(or (number? (caar l)) (eq? (caar l) 'X)) + (test-write-sym (string-append "|" (cadar l) "|") + (string-append "\\" (cadar l)) + (cadar l)) + (loop (cdr l))] + [else + (test-write-sym (cadar l) (cadar l) (cadar l)) + (loop (cdr l))])) + +(report-errs) diff --git a/collects/tests/mzscheme/struct.ss b/collects/tests/mzscheme/struct.ss new file mode 100644 index 0000000..f3dd129 --- /dev/null +++ b/collects/tests/mzscheme/struct.ss @@ -0,0 +1,234 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'STRUCT) + +(test 7 call-with-values + (lambda () (struct a (b c))) + (lambda args (length args))) +(let-values ([(type make pred sel1 set1 sel2 set2) (struct a (b c))]) + (test #t struct-type? type) + (test #t procedure? make) + (test 2 arity make) + (test 1 arity sel1) + (test 2 arity set1) + (test #t struct-setter-procedure? set2) + (test #f struct-setter-procedure? sel2)) + +(define-struct a (b c)) +(define-struct aa ()) +(define ai (make-a 1 2)) +(define aai (make-aa)) +(test #t struct-type? struct:a) +(test #f struct-type? 5) +(test #t procedure? a?) +(test #t a? ai) +(test #f a? 1) +(test #f aa? ai) +(test 1 a-b ai) +(test 2 a-c ai) +(define ai2 (make-a 1 2)) +(set-a-b! ai2 3) +(set-a-c! ai2 4) +(test 1 a-b ai) +(test 2 a-c ai) +(test 3 a-b ai2) +(test 4 a-c ai2) +(define-struct a (b c)) +(test #f a? ai) +(arity-test make-a 2 2) +(error-test `(make-aa 1) exn:application:arity?) +(arity-test a? 1 1) +(arity-test a-b 1 1) +(arity-test a-c 1 1) +(arity-test set-a-b! 2 2) +(arity-test set-a-c! 2 2) +(error-test `(a-b 5)) +(error-test `(a-b ,ai)) +(error-test `(set-a-b! ai 5)) +(error-test `(set-a-c! ai 5)) +(error-test `(begin (define-struct (a 9) (b c)) (void)) exn:struct:struct-type?) + +(arity-test struct-type? 1 1) + +(define (gen-struct-syntax-test formname suffix) + (syntax-test `(,formname 1 (x) ,@suffix)) + (syntax-test `(,formname a (1) ,@suffix)) + (syntax-test `(,formname a (x 1) ,@suffix)) + (syntax-test `(,formname a (x . y) ,@suffix)) + (syntax-test `(,formname (a) (x) ,@suffix)) + (syntax-test `(,formname (a . y) (x) ,@suffix)) + (syntax-test `(,formname (a 2 3) (x) ,@suffix))) +(define (struct-syntax-test formname) + (syntax-test `(,formname)) + (syntax-test `(,formname . a)) + (syntax-test `(,formname a . x)) + (syntax-test `(,formname a x)) + (gen-struct-syntax-test formname '())) + +(struct-syntax-test 'struct) +(struct-syntax-test 'define-struct) +(gen-struct-syntax-test 'let-struct '(5)) + +(define-struct base0 ()) +(define-struct base1 (a)) +(define-struct base2 (l r)) +(define-struct base3 (x y z)) + +(define-struct (one00 struct:base0) ()) +(define-struct (one01 struct:base1) ()) +(define-struct (one02 struct:base2) ()) +(define-struct (one03 struct:base3) ()) + +(define-struct (one10 struct:base0) (a)) +(define-struct (one11 struct:base1) (a)) +(define-struct (one12 struct:base2) (a)) +(define-struct (one13 struct:base3) (a)) + +(define-struct (one20 struct:base0) (l r)) +(define-struct (one21 struct:base1) (l r)) +(define-struct (one22 struct:base2) (l r)) +(define-struct (one23 struct:base3) (l r)) + +(define-struct (one30 struct:base0) (x y z)) +(define-struct (one31 struct:base1) (x y z)) +(define-struct (one32 struct:base2) (x y z)) +(define-struct (one33 struct:base3) (x y z)) + +(define-struct (two100 struct:one00) (a)) +(define-struct (two101 struct:one01) (a)) +(define-struct (two102 struct:one02) (a)) +(define-struct (two103 struct:one03) (a)) +(define-struct (two110 struct:one10) (a)) +(define-struct (two111 struct:one11) (a)) +(define-struct (two112 struct:one12) (a)) +(define-struct (two113 struct:one13) (a)) +(define-struct (two120 struct:one20) (a)) +(define-struct (two121 struct:one21) (a)) +(define-struct (two122 struct:one22) (a)) +(define-struct (two123 struct:one23) (a)) +(define-struct (two130 struct:one30) (a)) +(define-struct (two131 struct:one31) (a)) +(define-struct (two132 struct:one32) (a)) +(define-struct (two133 struct:one33) (a)) + +(define x00 (make-one00)) + +(define x01 (make-one01 1)) + +(define x10 (make-one10 1)) +(define x11 (make-one11 1 2)) +(define x12 (make-one12 1 2 3)) +(define x13 (make-one13 1 2 3 4)) + +(define x31 (make-one31 1 2 3 4)) + +(define x33 (make-one33 1 2 3 4 5 6)) + +(define x132 (make-two132 1 2 3 4 5 6)) + +(define (ones v) + (cond + [(one00? v) 'one00] + [(one01? v) 'one01] + [(one02? v) 'one02] + [(one03? v) 'one03] + + [(one10? v) 'one10] + [(one11? v) 'one11] + [(one12? v) 'one12] + [(one13? v) 'one13] + + [(one20? v) 'one20] + [(one21? v) 'one21] + [(one22? v) 'one22] + [(one23? v) 'one23] + + [(one30? v) 'one30] + [(one31? v) 'one31] + [(one32? v) 'one32] + [(one33? v) 'one33])) + +(define (multi v) + (cond + [(two130? v) 'two130] + [(two131? v) 'two131] + [(two132? v) 'two132] + [(two133? v) 'two133] + + [(one10? v) 'one10] + [(one11? v) 'one11] + [(one12? v) 'one12] + [(one13? v) 'one13] + + [(one20? v) 'one20] + [(one21? v) 'one21] + [(one22? v) 'one22] + [(one23? v) 'one23] + + [(base0? v) 'base0] + [(base1? v) 'base1] + [(base2? v) 'base2] + [(base3? v) 'base3])) + +(define (dummy v) + 'ok) + +(define (go f v n) + (time + (let loop ([n n]) + (unless (zero? n) + (f v) + (loop (sub1 n)))))) + +(define check + (lambda (l) + (cond + [(null? l) #f] + [else + (test (caddr l) (car l) (cadr l)) + (check (cdddr l))]))) + +(define ones-test + (list x00 'one00 + x10 'one10 + x11 'one11 + x12 'one12 + x13 'one13 + x33 'one33)) + +(define multi-test + (list x00 'base0 + x10 'one10 + x11 'one11 + x12 'one12 + x13 'one13 + x33 'base3 + x132 'two132)) + +(letrec ([bundle + (lambda (l f) + (if (null? l) + null + (list* f (car l) (cadr l) + (bundle (cddr l) f))))]) + (check (append + (bundle ones-test ones) + (bundle multi-test multi) + (list base1-a x11 1 + one11-a x11 2 + one10-a x10 1 + + base1-a x31 1 + one31-z x31 4 + + base2-l x132 1 + two132-a x132 6 + one32-y x132 4)))) + + +(error-test '(struct x (y z)) exn:application:arity?) +(error-test '(let ([x (struct x (y z))]) 10) exn:application:arity?) + +(report-errs) diff --git a/collects/tests/mzscheme/structc.ss b/collects/tests/mzscheme/structc.ss new file mode 100644 index 0000000..2e7d616 --- /dev/null +++ b/collects/tests/mzscheme/structc.ss @@ -0,0 +1,182 @@ + +(define ones-case + (make-struct-case + (list + one00? + one01? + one02? + one03? + + one10? + one11? + one12? + one13? + + one20? + one21? + one22? + one23? + + one30? + one31? + one32? + one33?) + + (list + (lambda (x) 'one00) + (lambda (x) 'one01) + (lambda (x) 'one02) + (lambda (x) 'one03) + + (lambda (x) 'one10) + (lambda (x) 'one11) + (lambda (x) 'one12) + (lambda (x) 'one13) + + (lambda (x) 'one20) + (lambda (x) 'one21) + (lambda (x) 'one22) + (lambda (x) 'one23) + + (lambda (x) 'one30) + (lambda (x) 'one31) + (lambda (x) 'one32) + (lambda (x) 'one33)))) + +(define multi-case + (make-struct-case + (list + two130? + two131? + two132? + two133? + + one10? + one11? + one12? + one13? + + one20? + one21? + one22? + one23? + + base0? + base1? + base2? + base3?) + + (list + (lambda (x) 'two130) + (lambda (x) 'two131) + (lambda (x) 'two132) + (lambda (x) 'two133) + + (lambda (x) 'one10) + (lambda (x) 'one11) + (lambda (x) 'one12) + (lambda (x) 'one13) + + (lambda (x) 'one20) + (lambda (x) 'one21) + (lambda (x) 'one22) + (lambda (x) 'one23) + + (lambda (x) 'base0) + (lambda (x) 'base1) + (lambda (x) 'base2) + (lambda (x) 'base3)) + + (lambda (x) x))) + +(letrec ([bundle + (lambda (l f) + (if (null? l) + null + (list* f (car l) (cadr l) + (bundle (cddr l) f))))]) + (check (append + (bundle ones-test ones-case) + (bundle multi-test multi-case) + (list base1-a x11 1 + one11-a x11 2 + one10-a x10 1 + + base1-a x31 1 + one31-z x31 4 + + base2-l x132 1 + two132-a x132 6 + one32-y x132 4)))) + +(test #t arity-at-least? (multi-case (arity void))) + +(arity-test multi-case 1 1) + +(error-test `(,ones-case 6) type?) +(error-test `(,multi-case 6) type?) + +(error-test `(,ones-case (arity void)) exn:else?) + +(test (void) (make-struct-case null null void) x00) +(test #t procedure? (make-struct-case null null)) + +(error-test `((make-struct-case null null) x00) exn:else?) + +(error-test `(make-struct-case (list 8) (list void))) +(error-test `(make-struct-case (list exn:misc? 8) (list void void))) +(error-test `(make-struct-case (list exn:misc? 8 exn?) (list void void void))) +(error-test `(make-struct-case exn? (list void))) +(error-test `(make-struct-case (list* exn:misc? exn?) (list void))) + +(error-test `(make-struct-case (list exn?) (list 8))) +(error-test `(make-struct-case (list exn?) (list (lambda () 8)))) +(error-test `(make-struct-case (list exn:misc? exn?) + (list void string-set!))) +(error-test `(make-struct-case (list exn:misc? exn:syntax? exn?) + (list void void string-set!))) +(error-test `(make-struct-case (list exn?) void)) +(error-test `(make-struct-case (list exn?) (list* void void))) + +(error-test `(make-struct-case (list exn:misc?) (list void void)) + exn:application:list-sizes?) +(error-test `(make-struct-case (list exn:misc? exn?) (list void)) + exn:application:list-sizes?) + +(arity-test make-struct-case 2 3) + +(test 0 (struct-case-lambda x (else 0)) (arity void)) +(test (arity void) (struct-case-lambda x (else)) (arity void)) +(test (arity void) (struct-case-lambda x (arity-at-least?)) (arity void)) +(test 0 (struct-case-lambda x (arity-at-least? 0) (else 1)) (arity void)) + +(define s (struct-case-lambda x + [exn? 'exn] + [arity-at-least? x] + [else (cons x 5)])) + +(test 'exn s (make-exn 1 2)) +(test (arity void) s (arity void)) +(test (cons x00 5) s x00) + +(arity-test s 1 1) + +(error-test '(s 9)) +(error-test '(struct-case-lambda) syntaxe?) +(error-test '(struct-case-lambda 5) syntaxe?) +(error-test '(struct-case-lambda x . 5) syntaxe?) +(error-test '(struct-case-lambda x ()) syntaxe?) +(error-test '(struct-case-lambda x else) syntaxe?) +(error-test '(struct-case-lambda x (else 9) (exn? 8)) syntaxe?)) + +(define time-branch + (lambda (proc list) + (time + (let loop ([n 1000]) + (unless (zero? n) + (let loop ([l list]) + (unless (null? l) + (proc (car l)) + (loop (cddr l)))) + (loop (sub1 n))))))) + diff --git a/collects/tests/mzscheme/syntax.ss b/collects/tests/mzscheme/syntax.ss new file mode 100644 index 0000000..c27e36c --- /dev/null +++ b/collects/tests/mzscheme/syntax.ss @@ -0,0 +1,870 @@ + +(if (not (defined? 'SECTION)) + (load "testing.ss")) + +(test 0 'with-handlers (with-handlers () 0)) +(test 1 'with-handlers (with-handlers ([void void]) 1)) +(test 2 'with-handlers (with-handlers ([void void]) 1 2)) +(test 'zero 'zero + (with-handlers ((zero? (lambda (x) 'zero))) + (raise 0))) +(test 'zero 'zero + (with-handlers ((zero? (lambda (x) 'zero)) + (positive? (lambda (x) 'positive))) + (raise 0))) +(test 'positive 'positive + (with-handlers ((zero? (lambda (x) 'zero)) + (positive? (lambda (x) 'positive))) + (raise 1))) +(error-test '(with-handlers () + (/ 0)) + exn:application:math:zero?) +(error-test '(with-handlers ((zero? (lambda (x) 'zero))) + (/ 0)) + exn:application:math:zero?) +(error-test '(with-handlers ((zero? (lambda (x) 'zero)) + (boolean? (lambda (x) 'boolean))) + (/ 0)) + exn:application:math:zero?) +(syntax-test '(with-handlers)) +(syntax-test '(with-handlers . 1)) +(syntax-test '(with-handlers ((zero? (lambda (x) 'zero))))) +(syntax-test '(with-handlers ((zero? (lambda (x) 'zero))) . 1)) +(syntax-test '(with-handlers (zero?) 1)) +(syntax-test '(with-handlers ((zero?)) 1)) +(syntax-test '(with-handlers ((zero? . zero?)) 1)) +(syntax-test '(with-handlers ((zero? zero?) . 2) 1)) +(syntax-test '(with-handlers ((zero? zero?) zero?) 1)) +(syntax-test '(with-handlers ((zero? zero?) (zero?)) 1)) +(syntax-test '(with-handlers ((zero? zero?) (zero?)) 1)) +(syntax-test '(with-handlers ((zero? zero? zero?)) 1)) +(syntax-test '(with-handlers ((zero? zero? . zero?)) 1)) +(syntax-test '(with-handlers ((zero? zero?)) 1 . 2)) + +(error-test '(with-handlers ((0 void)) (/ 0)) + exn:application:non-procedure?) +(error-test '(with-handlers ((void 0)) (/ 0)) + exn:application:non-procedure?) +(error-test '(with-handlers ((unbound-variable void)) 0) + exn:variable?) +(error-test '(with-handlers ((void unbound-variable)) 0) + exn:variable?) +(error-test '(with-handlers (((values 1 2) void)) 0) + arity?) +(error-test '(with-handlers ((void (values 1 2))) 0) + arity?) + +(test-values '(1 2) (lambda () (with-handlers ([void void]) + (values 1 2)))) + +(SECTION 4 1 2) +(test '(quote a) 'quote (quote 'a)) +(test '(quote a) 'quote ''a) +(syntax-test '(quote)) +(syntax-test '(quote 1 2)) + +(SECTION 4 1 3) +(test 12 (if #f + *) 3 4) +(syntax-test '(+ 3 . 4)) + +(SECTION 4 1 4) +(test 8 (lambda (x) (+ x x)) 4) +(define reverse-subtract + (lambda (x y) (- y x))) +(test 3 reverse-subtract 7 10) +(define add4 + (let ((x 4)) + (lambda (y) (+ x y)))) +(test 10 add4 6) +(test (letrec([x x]) x) 'lambda ((lambda () (begin (define d d) d)))) +(test '(3 4 5 6) (lambda x x) 3 4 5 6) +(test '(5 6) (lambda (x y . z) z) 3 4 5 6) +(test 'second (lambda () (cons 'first 2) 'second)) +(syntax-test '(lambda)) +(syntax-test '(lambda x)) +(syntax-test '(lambda . x)) +(syntax-test '(lambda x . x)) +(syntax-test '(lambda x . 5)) +(syntax-test '(lambda ((x)) x)) +(syntax-test '(lambda 5 x)) +(syntax-test '(lambda (5) x)) +(syntax-test '(lambda (x (y)) x)) +(syntax-test '(lambda (x . 5) x)) +(syntax-test '(lambda (x) x . 5)) + +(let ([f + (case-lambda + [() 'zero] + [(x) (cons 1 1) 'one] + [(x y) 'two] + [(x y z . rest) 'three+] + [x 'bad])] + [g + (case-lambda + [(x y z) 'three] + [(x y) (cons 2 2) 'two] + [(x) 'one] + [() 'zero] + [x (cons 0 'more!) 'more])] + [h + (case-lambda + [(x y) 'two] + [(x y z w) 'four])]) + (test 'zero f) + (test 'one f 1) + (test 'two f 1 2) + (test 'three+ f 1 2 3) + (test 'three+ f 1 2 3 4) + (test 'three+ f 1 2 3 4 5 6 7 8 9 10) + + (test 'zero g) + (test 'one g 1) + (test 'two g 1 2) + (test 'three g 1 2 3) + (test 'more g 1 2 3 4 5 6 7 8 9 10) + + (test 'two h 1 2) + (test 'four h 1 2 3 4) + (let ([h '(case-lambda + [(x y) 'two] + [(x y z w) 'four])]) + (error-test (list h) arity?) + (error-test (list* h '(1)) arity?) + (error-test (list* h '(1 2 3)) arity?) + (error-test (list* h '(1 2 3 4 5 6)) arity?))) + +(error-test '((case-lambda)) arity?) + +(syntax-test '(case-lambda [])) +(syntax-test '(case-lambda 1)) +(syntax-test '(case-lambda x)) +(syntax-test '(case-lambda [x])) +(syntax-test '(case-lambda [x 8][y])) +(syntax-test '(case-lambda [x][y 9])) +(syntax-test '(case-lambda [8 8])) +(syntax-test '(case-lambda [((x)) 8])) +(syntax-test '(case-lambda [(8) 8])) +(syntax-test '(case-lambda [(x . 9) 8])) +(syntax-test '(case-lambda [x . 8])) +(syntax-test '(case-lambda [(x) . 8])) +(syntax-test '(case-lambda . [(x) 8])) +(syntax-test '(case-lambda [(x) 8] . [y 7])) +(syntax-test '(case-lambda [(x) 8] . [y 7])) +(syntax-test '(case-lambda [(x) 8] [8 7])) +(syntax-test '(case-lambda [(x) 8] [((y)) 7])) +(syntax-test '(case-lambda [(x) 8] [(8) 7])) +(syntax-test '(case-lambda [(x) 8] [(y . 8) 7])) +(syntax-test '(case-lambda [(x) 8] [y . 7])) +(syntax-test '(case-lambda [(x) 8] [(y) . 7])) + +(SECTION 4 1 5) +(test 'yes 'if (if (> 3 2) 'yes 'no)) +(test 'no 'if (if (> 2 3) 'yes 'no)) +(test '1 'if (if (> 3 2) (- 3 2) (+ 3 2))) +(test-values '(1 2) (lambda () (if (cons 1 2) (values 1 2) 0))) +(test-values '(1 2) (lambda () (if (not (cons 1 2)) 0 (values 1 2)))) +(syntax-test '(if . #t)) +(syntax-test '(if #t . 1)) +(syntax-test '(if #t 1 . 2)) +(syntax-test '(if #t)) +(syntax-test '(if #t 1 2 3)) +(syntax-test '(if #t 1 2 . 3)) +(error-test '(if (values 1 2) 3 4) arity?) + +(test (void) 'when (when (> 1 2) 0)) +(test (void) 'when (when (> 1 2) (cons 1 2) 0)) +(test 0 'when (when (< 1 2) 0)) +(test 0 'when (when (< 1 2) (cons 1 2) 0)) +(test-values '(0 10) (lambda () (when (< 1 2) (values 0 10)))) +(syntax-test '(when)) +(syntax-test '(when . 1)) +(syntax-test '(when 1)) +(syntax-test '(when 1 . 2)) +(error-test '(when (values 1 2) 0) arity?) + +(test (void) 'unless (unless (< 1 2) 0)) +(test (void) 'unless (unless (< 1 2) (cons 1 2) 0)) +(test 0 'unless (unless (> 1 2) 0)) +(test 0 'unless (unless (> 1 2) (cons 1 2) 0)) +(test-values '(0 10) (lambda () (unless (> 1 2) (values 0 10)))) +(syntax-test '(unless)) +(syntax-test '(unless . 1)) +(syntax-test '(unless 1)) +(syntax-test '(unless 1 . 2)) +(error-test '(unless (values 1 2) 0) arity?) + +(SECTION 4 1 6) +(define x 2) +(test 3 'define (+ x 1)) +(set! x 4) +(test 5 'set! (+ x 1)) +(syntax-test '(set!)) +(syntax-test '(set! x)) +(syntax-test '(set! x 1 2)) +(syntax-test '(set! 1 2)) +(syntax-test '(set! (x) 1)) +(syntax-test '(set! . x)) +(syntax-test '(set! x . 1)) +(syntax-test '(set! x 1 . 2)) + +(set!-values (x) 9) +(test 9 'set!-values x) +(test (void) 'set!-values (set!-values () (values))) +(set!-values (x x) (values 1 2)) +(test 2 'set!-values x) +(syntax-test '(set!-values)) +(syntax-test '(set!-values . x)) +(syntax-test '(set!-values x)) +(syntax-test '(set!-values 8)) +(syntax-test '(set!-values (x))) +(syntax-test '(set!-values (x) . 0)) +(syntax-test '(set!-values x 0)) +(syntax-test '(set!-values (x . y) 0)) +(syntax-test '(set!-values (x . 8) 0)) +(syntax-test '(set!-values (x 8) 0)) +(syntax-test '(set!-values (x) 0 1)) +(syntax-test '(set!-values (x) 0 . 1)) + +(error-test '(set!-values () 1) arity?) +(error-test '(set!-values () (values 1 2)) arity?) +(error-test '(set!-values (x) (values)) arity?) +(error-test '(set!-values (x) (values 1 2)) arity?) +(error-test '(set!-values (x y) 1) arity?) +(error-test '(set!-values (x y) (values 1 2 3)) arity?) + +(error-test '(set! unbound-variable 5) exn:variable?) + +(SECTION 4 2 1) +(test 'greater 'cond (cond ((> 3 2) 'greater) + ((< 3 2) 'less))) +(test 'equal 'cond (cond ((> 3 3) 'greater) + ((< 3 3) 'less) + (else 'equal))) +(test 2 'cond (cond ((assv 'b '((a 1) (b 2))) => cadr) + (else #f))) +(test #f 'cond (cond ((assv 'z '((a 1) (b 2))) => cadr) + (else #f))) +(syntax-test '(cond ((assv 'z '((a 1) (b 2))) => cadr) + (else 8) + (else #f))) +(test #f 'cond (let ([else #f]) + (cond ((assv 'z '((a 1) (b 2))) => cadr) + (else 8) + (#t #f)))) +(test 'second 'cond (cond ((< 1 2) (cons 1 2) 'second))) +(test 'second-again 'cond (cond ((> 1 2) 'ok) (else (cons 1 2) 'second-again))) +(test 1 'cond (cond (1))) +(test 1 'cond (cond (#f) (1))) +(test 1 'cond (cond (#f 7) (1))) +(test 2 'cond (cond (#f 7) (1 => add1))) +(test add1 'cond (let ([=> 9]) (cond (#f 7) (1 => add1)))) +(non-z '(test 0 'case (case (* 2 3) + (6 0) + (else 7)))) +(test 'composite 'case (case (* 2 3) + ((2 3 5 7) 'prime) + ((1 4 6 8 9) 'composite))) +(test 'consonant 'case (case (car '(c d)) + ((a e i o u) 'vowel) + ((w y) 'semivowel) + (else 'consonant))) +(test 'second 'case (case 10 + [(10) (cons 1 2) 'second] + [else 5])) +(test 'second-again 'case (case 11 + [(10) (cons 1 2) 'second] + [else (cons 1 2) 'second-again])) +(test-values '(10 9) (lambda () + (cond + [(positive? 0) 'a] + [(positive? 10) (values 10 9)] + [else #f]))) +(test-values '(10 9) (lambda () + (case (string->symbol "hello") + [(bye) 'a] + [(hello) (values 10 9)] + [else #f]))) +(error-test '(cond [(values 1 2) 8]) arity?) +(error-test '(case (values 1 2) [(a) 8]) arity?) + +(test #t 'and (and (= 2 2) (> 2 1))) +(test #f 'and (and (= 2 2) (< 2 1))) +(test '(f g) 'and (and 1 2 'c '(f g))) +(test #t 'and (and)) +(test-values '(1 12) (lambda () (and (cons 1 2) (values 1 12)))) +(test #t 'or (or (= 2 2) (> 2 1))) +(test #t 'or (or (= 2 2) (< 2 1))) +(test #f 'or (or #f #f #f)) +(test #f 'or (or)) +(test '(b c) 'or (or (memq 'b '(a b c)) (+ 3 0))) +(test-values '(1 12) (lambda () (or (not (cons 1 2)) (values 1 12)))) +(syntax-test '(cond #t)) +(syntax-test '(cond ()) ) +(syntax-test '(cond (1 =>)) ) +(syntax-test '(cond (1 => 3 4)) ) +(syntax-test '(cond . #t)) +(syntax-test '(cond (#t . 1))) +(syntax-test '(cond (#t 1) #f)) +(syntax-test '(cond (#t 1) . #f)) +(error-test '(cond ((values #t #f) 1)) arity?) +(syntax-test '(case)) +(syntax-test '(case 0 #t)) +(syntax-test '(case . 0)) +(syntax-test '(case 0 . #t)) +(syntax-test '(case 0 (0 #t))) +(syntax-test '(case 0 ())) +(syntax-test '(case 0 (0))) +(syntax-test '(case 0 (0 . 8))) +(syntax-test '(case 0 ((0 . 1) 8))) +(syntax-test '(case 0 (0 8) #f)) +(syntax-test '(case 0 (0 8) . #f)) +(syntax-test '(case 0 (else 1) (else 2))) +(error-test '(case 0 ((0) =>)) exn:variable?) +(syntax-test '(and . 1)) +(syntax-test '(and 1 . 2)) +(syntax-test '(or . 1)) +(syntax-test '(or 1 . 2)) +(error-test '(and #t (values 1 2) 8) arity?) +(error-test '(or #f (values 1 2) 8) arity?) + +(SECTION 4 2 2) +(test 6 'let (let ((x 2) (y 3)) (* x y))) +(test 'second 'let (let ((x 2) (y 3)) (* x y) 'second)) +(test 6 'let-values (let-values (((x) 2) ((y) 3)) (* x y))) +(test 6 'let-values (let-values (((x y) (values 2 3))) (* x y))) +(test 35 'let (let ((x 2) (y 3)) (let ((x 7) (z (+ x y))) (* z x)))) +(test 35 'let-values (let-values (((x y) (values 2 3))) (let-values (((x) 7) ((z) (+ x y))) (* z x)))) +(test 70 'let* (let ((x 2) (y 3)) (let* ((x 7) (z (+ x y))) (* z x)))) +(test 70 'let*-values (let ((x 2) (y 3)) (let*-values (((x) 7) ((z) (+ x y))) (* z x)))) +(test #t 'letrec (letrec ((-even? + (lambda (n) (if (zero? n) #t (-odd? (- n 1))))) + (-odd? + (lambda (n) (if (zero? n) #f (-even? (- n 1)))))) + (-even? 88))) +(test #t 'letrec-values (letrec-values (((-even? -odd?) + (values + (lambda (n) (if (zero? n) #t (-odd? (- n 1)))) + (lambda (n) (if (zero? n) #f (-even? (- n 1))))))) + (-even? 88))) +(define x 34) +(test 5 'let (let ((x 3)) (define x 5) x)) +(test 5 'let (let ((x 3)) (define-values (x w) (values 5 8)) x)) +(test 34 'let x) +(test 6 'let (let () (define x 6) x)) +(test 34 'let x) +(test 7 'let* (let* ((x 3)) (define x 7) x)) +(test 34 'let* x) +(test 8 'let* (let* () (define x 8) x)) +(test 34 'let* x) +(test 9 'letrec (letrec () (define x 9) x)) +(test 34 'letrec x) +(test 10 'letrec (letrec ((x 3)) (define x 10) x)) +(test 34 'letrec x) +(teval '(test 5 'letrec* (letrec* ((x 5)(y x)) y))) +(test 3 'let (let ((y 'apple) (x 3) (z 'banana)) x)) +(test 3 'let* (let* ((y 'apple) (x 3) (z 'banana)) x)) +(test 3 'letrec (letrec ((y 'apple) (x 3) (z 'banana)) x)) +(test 3 'let* (let* ((x 7) (y 'apple) (z (set! x 3))) x)) +(test 3 'let* (let* ((x 7) (y 'apple) (z (if (not #f) (set! x 3) #f))) x)) +(test 3 'let* (let* ((x 7) (y 'apple) (z (if (not #t) #t (set! x 3)))) x)) +(test 3 'let-values (let-values (((y x z) (values 'apple 3 'banana))) x)) +(test 3 'let*-values (let*-values (((y x z) (values 'apple 3 'banana))) x)) +(test 3 'letrec-values (letrec-values (((y x z) (values 'apple 3 'banana))) x)) +(test 3 'let*-values (let*-values (((x y) (values 7 'apple)) ((z) (set! x 3))) x)) +(test 3 'let*-values (let*-values (((x y) (values 7 'apple)) ((z) (if (not #f) (set! x 3) #f))) x)) +(test 3 'let*-values (let*-values (((x y) (values 7 'apple)) ((z) (if (not #t) #t (set! x 3)))) x)) + +(test-values '(3 4) (lambda () (let ([x 3][y 4]) (values x y)))) +(test-values '(3 -4) (lambda () (let loop ([x 3][y -4]) (values x y)))) +(test-values '(3 14) (lambda () (let* ([x 3][y 14]) (values x y)))) +(test-values '(3 24) (lambda () (letrec ([x 3][y 24]) (values x y)))) +(test-values '(3 24) (lambda () (letrec* ([x 3][y 24]) (values x y)))) +(test-values '(3 54) (lambda () (let-values ([(x y) (values 3 54)]) (values x y)))) +(test-values '(3 64) (lambda () (let*-values ([(x y) (values 3 64)]) (values x y)))) +(test-values '(3 74) (lambda () (letrec-values ([(x y) (values 3 74)]) (values x y)))) +(test-values '(3 84) (lambda () (letrec*-values ([(x y) (values 3 84)]) (values x y)))) + +(test '(10 11) 'letrec-values (letrec-values ([(names kps) + (letrec ([oloop 10]) + (values oloop (add1 oloop)))]) + (list names kps))) + +(define (error-test-let expr) + (syntax-test (cons 'let expr)) + (syntax-test (cons 'let (cons 'name expr))) + (syntax-test (cons 'let* expr)) + (syntax-test (cons 'letrec expr)) + (syntax-test (cons 'letrec* expr))) +(error-test-let 'x) +(error-test-let '(x)) +(error-test-let '(())) +(error-test-let '(x ())) +(syntax-test '(let* x () 1)) +(syntax-test '(letrec x () 1)) +(syntax-test '(letrec* x () 1)) +(error-test-let '(x . 1)) +(error-test-let '(() . 1)) +(error-test-let '(((x 1)))) +(error-test-let '(((x 1)) . 1)) +(error-test-let '(((x . 1)) 1)) +(error-test-let '(((1 1)) 1)) +(error-test-let '(((x 1) 1) 1)) +(error-test-let '(((x 1) . 1) 1)) +(error-test-let '(((x 1 1)) 1)) +(error-test-let '(((x 1 1)) 1)) +(error-test-let '(((x 1)) 1 . 2)) + +(define (do-error-test-let-values expr syntax-test) + (syntax-test (cons 'let-values expr)) + (syntax-test (cons 'let*-values expr)) + (syntax-test (cons 'letrec-values expr)) + (syntax-test (cons 'letrec*-values expr))) +(define (error-test-let-values expr) + (do-error-test-let-values expr syntax-test)) +(error-test-let-values 'x) +(error-test-let-values '(x)) +(error-test-let-values '(())) +(error-test-let-values '(x ())) +(syntax-test '(let*-values x () 1)) +(syntax-test '(letrec-values x () 1)) +(syntax-test '(letrec*-values x () 1)) +(error-test-let-values '(x . 1)) +(error-test-let-values '(() . 1)) +(error-test-let-values '((((x) 1)))) +(error-test-let-values '((((x) 1)) . 1)) +(error-test-let-values '((((x) . 1)) 1)) +(error-test-let-values '((((1) 1)) 1)) +(error-test-let-values '((((x 1) 1)) 1)) +(error-test-let-values '((((1 x) 1)) 1)) +(error-test-let-values '((((x) 1) . 1) 1)) +(error-test-let-values '((((x) 1 1)) 1)) +(error-test-let-values '((((x . y) 1)) 1)) +(error-test-let-values '((((x . 1) 1)) 1)) +(error-test-let-values '((((x) 1)) 1 . 2)) + +(do-error-test-let-values '((((x y) 1)) 1) (lambda (x) (error-test x arity?))) +(do-error-test-let-values '((((x) (values 1 2))) 1) (lambda (x) (error-test x arity?))) +(do-error-test-let-values '(((() (values 1))) 1) (lambda (x) (error-test x arity?))) +(do-error-test-let-values '((((x) (values))) 1) (lambda (x) (error-test x arity?))) + +(test 5 'embedded (let () (define y (lambda () x)) (define x 5) (y))) + +(let ([wrap (lambda (body) + (syntax-test `(let () ,@body)) + (syntax-test `(let () (begin ,@body))))]) + (wrap '((define x 7) (define x 8) x)) + (wrap '(2 (define y 8) x)) + (wrap '((define 3 8) x)) + (wrap '((define-values x 8) x))) + +(syntax-test '(let () (begin (define x 5)) x)) + +(SECTION 4 2 3) +(define x 0) +(define (test-begin bg nested-bg) + (let* ([make-args + (lambda (bg b) + (if (eq? bg 'begin) + b + (let* ([len (length b)] + [last (list-ref b (sub1 len))]) + (cons last + (let loop ([l b]) + (if (null? (cdr l)) + null + (cons (car l) (loop (cdr l)))))))))] + [test-bg + (lambda (v b) + (let* ([args (make-args bg b)] + [expr (cons bg args)]) + (printf "~s:~n" expr) + (teval `(test ,v (quote ,bg) ,expr))))] + [make-bg + (lambda (b) + (cons nested-bg (make-args nested-bg b)))] + [make-test-bg-d + (lambda (bg) + (lambda (v1 v2 b) + (test-bg (if (eq? bg 'begin) + v1 + v2) + b)))] + [test-bg-d (make-test-bg-d bg)] + [test-bg-d2 (make-test-bg-d nested-bg)]) + (teval '(set! x 0)) + (test-bg-d 6 1 '((set! x 5) (+ x 1))) + (test-bg 5 '(5)) + (test-bg 3 '(2 3)) + (test-bg 3 `(2 (,bg 3))) + (test-bg 3 `(,(make-bg '(2)) ,(make-bg '(3)))) + (test-bg-d 7 6 '((set! x 6) 'a (+ x 1))) + (test-bg ''w '((set! x 6) 'a (+ x 1) 'w)) + (test-bg-d 8 7 '('b (set! x 7) (+ x 1))) + (test-bg-d 9 8 '('b (set! x 8) 'a (+ x 1))) + (test-bg ''z '('b (set! x 8) 'a (+ x 1) 'z)) + (test-bg-d 7 9 `(,(make-bg '((set! x 6) 'a)) (+ x 1))) + (test-bg 10 `(,(make-bg '((set! x 60) 'a)) 10)) + (teval '(test 60 'x x)) + (test-bg 10 `(,(make-bg '((set! x 65) 'a)) (add1 20) 10)) + (teval '(test 65 'x x)) + (test-bg ''a `(10 ,(make-bg '((set! x 66) 'a)))) + (teval '(test 66 'x x)) + (test-bg ''a `(10 (add1 32) ,(make-bg '((set! x 67) 'a)))) + (teval '(test 67 'x x)) + (teval '(set! x 6)) + (test-bg-d 8 7 `(,(make-bg '('b (set! x 7) 'a)) (+ x 1))) + (test-bg-d 9 8 `(,(make-bg '('b (set! x 8))) ,(make-bg '('a (+ x 1))))) + (test-bg-d2 10 9 `(,(make-bg `(,(make-bg `('b (set! x 9) ,(make-bg '('a (+ x 1))))))))) + (test-bg ''s `(,(make-bg `(,(make-bg `('b (set! x 9) ,(make-bg '('a (+ x 1) 's)))))))) + (test-bg ''t `(,(make-bg `(,(make-bg `('b (set! x 9) ,(make-bg '('a (+ x 1))))))) 't)) + (teval `(test 5 call-with-values (lambda () ,(make-bg '((values 1 2) (values 1 3 1)))) +)) + (syntax-test `(,bg)) + (syntax-test `(,bg . 1)) + (syntax-test `(,bg 1 . 2)))) + +(test-begin 'begin 'begin) +(test-begin 'begin0 'begin) +(test-begin 'begin0 'begin0) +(test-begin 'begin 'begin0) + +(test 4 'implicit-begin (let ([x 4][y 7]) 'y x)) +(test 4 'implicit-begin (let ([x 4][y 7]) y x)) + +(SECTION 4 2 5) +(define f-check #t) +(define f (delay (begin (set! f-check #f) 5))) +(test #t (lambda () f-check)) +(test 5 force f) +(test #f (lambda () f-check)) +(test 5 force f) +(define f-check-2 (delay (values 1 5))) +(test-values '(1 5) (lambda () (force f-check-2))) +(values 1 2) +(test-values '(1 5) (lambda () (force f-check-2))) +(syntax-test '(delay)) +(syntax-test '(delay . 1)) +(syntax-test '(delay 1 . 2)) +(syntax-test '(delay 1 2)) + +(SECTION 4 2 6) +(test '(list 3 4) 'quasiquote `(list ,(+ 1 2) 4)) +(test '(list a (quote a)) 'quasiquote (let ((name 'a)) `(list ,name ',name))) +(test '(a 3 4 5 6 b) 'quasiquote `(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b)) +(test '((foo 7) . cons) + 'quasiquote + `((foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons)))) +(test '#(10 5 2 4 3 8) 'quasiquote `#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8)) +(test 5 'quasiquote `,(+ 2 3)) +(test '(a `(b ,(+ 1 2) ,(foo 4 d) e) f) + 'quasiquote `(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)) +(test '(a `(b ,x ,'y d) e) 'quasiquote + (let ((name1 'x) (name2 'y)) `(a `(b ,,name1 ,',name2 d) e))) +(test '(list 3 4) 'quasiquote (quasiquote (list (unquote (+ 1 2)) 4))) +(test '`(list ,(+ 1 2) 4) 'quasiquote '(quasiquote (list (unquote (+ 1 2)) 4))) +(test '(()) 'qq `((,@()))) +(define x 5) +(test '(quasiquote (unquote x)) 'qq ``,x) +(test '(quasiquote (unquote 5)) 'qq ``,,x) +(test '(quasiquote (unquote-splicing x)) 'qq ``,@x) +(test '(quasiquote (unquote-splicing 5)) 'qq ``,@,x) +(test '(quasiquote (quasiquote (quasiquote (unquote (unquote (unquote x)))))) 'qq ````,,,x) +(test '(quasiquote (quasiquote (quasiquote (unquote (unquote (unquote 5)))))) 'qq ````,,,,x) + +(test '(quasiquote (unquote result)) 'qq `(quasiquote ,result)) +(test (list 'quasiquote car) 'qq `(,'quasiquote ,car)) + +(syntax-test '(quasiquote)) +(syntax-test '(quasiquote . 5)) +(syntax-test '(quasiquote 1 . 2)) +(syntax-test '(quasiquote 1 2)) +(syntax-test '(unquote 7)) +(syntax-test '(unquote-splicing 7)) + +(syntax-test '`(1 . ,@5)) +(error-test '`(1 ,@5)) +(error-test '`(1 ,@5 2)) + +(define (qq-test e) + (syntax-test e ) + (syntax-test (list 'quasiquote e)) + (syntax-test (list 'quasiquote e)) + (syntax-test (list 'quasiquote (list 'quasiquote e))) + (syntax-test (list 'quasiquote (list 'quasiquote (list 'unquote e)))) + (syntax-test (list 'quasiquote (list 'quasiquote (list 'unquote-splicing e))))) +(qq-test '(unquote)) +(qq-test '(unquote 7 8 9)) +(qq-test '(unquote-splicing)) +(qq-test '(unquote-splicing 7 8 9)) + +(test '(unquote . 5) 'qq (quasiquote (unquote . 5))) +(test '(unquote 1 . 5) 'qq (quasiquote (unquote 1 . 5))) +(test '(unquote 1 2 . 5) 'qq (quasiquote (unquote 1 2 . 5))) + +(test '(unquote 1 2 7 . 5) 'qq (quasiquote (unquote 1 2 ,(+ 3 4) . 5))) +(test '(unquote 1 2 (unquote (+ 3 4)) . 5) 'qq (quasiquote (unquote 1 2 ,',(+ 3 4) . 5))) + +(test '(1 2 3 4 . 5) 'qq `(1 ,@'(2 3 4) . 5)) + +(error-test '`(10 ,(values 1 2)) arity?) +(error-test '`(10 ,@(values 1 2)) arity?) + +(SECTION 5 2 1) +(define add3 (lambda (x) (+ x 3))) +(test 6 'define (add3 3)) +(define (add3 x) (+ x 3)) +(test 6 'define (add3 3)) +(define first car) +(test 1 'define (first '(1 2))) +(syntax-test '(define)) +(syntax-test '(define . x)) +(syntax-test '(define x)) +(syntax-test '(define x . 1)) +(syntax-test '(define 1 2)) +(syntax-test '(define (1) 1)) +(syntax-test '(define (x 1) 1)) +(syntax-test '(define x 1 . 2)) +(syntax-test '(define x 1 2)) + +(define-values (add3) (lambda (x) (+ x 3))) +(test 6 'define (add3 3)) +(define-values (add3 another) (values (lambda (x) (+ x 3)) 9)) +(test 6 'define (add3 3)) +(test 9 'define another) +(define-values (first second third) (values car cadr caddr)) +(test 1 'define (first '(1 2))) +(test 2 'define (second '(1 2))) +(test 3 'define (third '(1 2 3))) +(define-values () (values)) +(syntax-test '(define-values)) +(syntax-test '(define-values . x)) +(syntax-test '(define-values x)) +(syntax-test '(define-values (x))) +(syntax-test '(define-values x . 1)) +(syntax-test '(define-values (x) . 1)) +(syntax-test '(define-values 1 2)) +(syntax-test '(define-values (1) 2)) +(syntax-test '(define-values (x 1) 1)) +(syntax-test '(define-values (x . y) 1)) +(syntax-test '(define-values (x) 1 . 2)) +(syntax-test '(define-values (x) 1 2)) + +(syntax-test '((define x 2) 0 1)) +(syntax-test '(+ (define x 2) 1)) +(syntax-test '(if (define x 2) 0 1)) +(syntax-test '(begin0 (define x 2))) +(syntax-test '(begin0 (define x 2) 0)) +(syntax-test '(begin0 0 (define x 2))) +(syntax-test '(let () (define x 2))) +(syntax-test '(letrec () (define x 2))) +(syntax-test '(lambda () (define x 2))) + +; Unfortunately, there's no good way to test this for mzc: +(unless (defined? 'building-flat-tests) + (error-test '(define x (values)) exn:application:arity?) + (error-test '(define x (values 1 2)) exn:application:arity?) + (error-test '(define-values () 3) exn:application:arity?) + (error-test '(define-values () (values 1 3)) exn:application:arity?) + (error-test '(define-values (x y) (values)) exn:application:arity?) + (error-test '(define-values (x y) 3) exn:application:arity?) + (error-test '(define-values (x y) (values 1 2 3)) exn:application:arity?)) + +(define ed-t0 0) +(test 0 'begin0-define (begin0 0 (define x 5) (set! ed-t0 x))) +(test 5 'begi0-define ed-t0) + +(begin (define ed-t1 1) (define ed-t2 2)) +(test 1 'begin-define ed-t1) +(test 2 'begin-define ed-t2) +(if (zero? (car (cons 0 0))) (define ed-t3 3) (define ed-t3 -3)) +(test 3 'begin-define ed-t3) + +(SECTION 5 2 2) +(test 45 'define + (let ((x 5)) + (define foo (lambda (y) (bar x y))) + (define bar (lambda (a b) (+ (* a b) a))) + (foo (+ x 3)))) +(define x 34) +(define (foo) (define x 5) x) +(test 5 foo) +(test 34 'define x) +(define foo (lambda () (define x 5) x)) +(test 5 foo) +(test 34 'define x) +(define (foo x) ((lambda () (define x 5) x)) x) +(test 88 foo 88) +(test 4 foo 4) +(test 34 'define x) + +'(teval '(test 5 'define + (let () + (define x 5) + (define define (lambda (a b) (+ a b))) + (define x 7) + x))) +'(teval '(syntax-test '(let () + (define define 5) + (define y 6) + y))) + +(syntax-test '(let () + (define x 5))) +(syntax-test '(let () + (if #t + (define x 5)) + 5)) + +(SECTION 4 2 4) +(test '#(0 1 2 3 4) 'do (do ((vec (make-vector 5)) + (i 0 (+ i 1))) + ((= i 5) vec) + (vector-set! vec i i))) +(test 25 'do (let ((x '(1 3 5 7 9))) + (do ((x x (cdr x)) + (sum 0 (+ sum (car x)))) + ((null? x) sum)))) +(test 1 'let (let foo () 1)) +(test '((6 1 3) (-5 -2)) 'let + (let loop ((numbers '(3 -2 1 6 -5)) + (nonneg '()) + (neg '())) + (cond ((null? numbers) (list nonneg neg)) + ((negative? (car numbers)) + (loop (cdr numbers) + nonneg + (cons (car numbers) neg))) + (else + (loop (cdr numbers) + (cons (car numbers) nonneg) + neg))))) +(test 5 'do (do ((x 1)) (#t 5))) +(test-values '(10 5) (lambda () (do ((x 1)) (#t (values 10 5))))) +(syntax-test '(do)) +(syntax-test '(do ()) ) +(syntax-test '(do () ()) ) +(syntax-test '(do (1) (#t 5) 5)) +(syntax-test '(do ((1)) (#t 5) 5)) +(syntax-test '(do ((1 7)) (#t 5) 5)) +(syntax-test '(do ((x . 1)) (#t 5) 5)) +(syntax-test '(do ((x 1) 2) (#t 5) 5)) +(syntax-test '(do ((x 1) . 2) (#t 5) 5)) +(syntax-test '(do ((x 1)) (#t . 5) 5)) +(syntax-test '(do ((x 1)) (#t 5) . 5)) + +(SECTION 'let/cc) + +(test 0 'let/cc (let/cc k (k 0) 1)) +(test 0 'let/cc (let/cc k 0)) +(test 1 'let/cc (let/cc k (cons 1 2) 1)) +(test-values '(2 1) (lambda () (let/cc k (values 2 1)))) +(test-values '(2 1) (lambda () (let/cc k (k 2 1)))) +(syntax-test '(let/cc)) +(syntax-test '(let/cc . k)) +(syntax-test '(let/cc k)) +(syntax-test '(let/cc k . 1)) +(syntax-test '(let/cc 1 1)) + +(test 0 'let/ec (let/ec k (k 0) 1)) +(test 0 'let/ec (let/ec k 0)) +(test 1 'let/ec (let/ec k (cons 1 2) 1)) +(test-values '(2 1) (lambda () (let/ec k (values 2 1)))) +(test-values '(2 1) (lambda () (let/ec k (k 2 1)))) +(syntax-test '(let/ec)) +(syntax-test '(let/ec . k)) +(syntax-test '(let/ec k)) +(syntax-test '(let/ec k . 1)) +(syntax-test '(let/ec 1 1)) + +(SECTION 'fluid-let) +(define x 1) +(define y -1) +(define (get-x) x) +(test 5 'fluid-let (fluid-let () 5)) +(test 2 'fluid-let (fluid-let ([x 2]) x)) +(test 0 'fluid-let (fluid-let ([x 2][y -2]) (+ x y))) +(test 20 'fluid-let (fluid-let ([x 20]) (get-x))) +(test 1 'fluid-let-done x) +(error-test '(fluid-let ([x 10]) (error 'bad)) exn:user?) +(test 1 'fluid-let-done-escape x) +(test 3 'fluid-let (let* ([x 0][y (lambda () x)]) (fluid-let ([x 3]) (y)))) +(test 0 'fluid-let (let* ([x 0][y (lambda () x)]) (fluid-let ([x 3]) (y)) (y))) +(test-values '(34 56) (lambda () (fluid-let ([x 34][y 56]) (values x y)))) +(test 'second 'fluid-let (fluid-let ([x 2][y -2]) (+ x y) 'second)) + +(error-test '(fluid-let ([undefined-variable 0]) 8) exn:variable?) + +(syntax-test '(fluid-let)) +(syntax-test '(fluid-let . 1)) +(syntax-test '(fluid-let x 9)) +(syntax-test '(fluid-let 1 9)) +(syntax-test '(fluid-let (x) 9)) +(syntax-test '(fluid-let ([x]) 9)) +(syntax-test '(fluid-let ([x . 5]) 9)) +(syntax-test '(fluid-let ([x 5] . y) 9)) +(syntax-test '(fluid-let ([x 5] [y]) 9)) +(syntax-test '(fluid-let ([x 5]) . 9)) +(syntax-test '(fluid-let ([x 5]) 9 . 10)) + +(SECTION 'parameterize) + +(test 5 'parameterize (parameterize () 5)) +(test 6 'parameterize (parameterize ([error-print-width 10]) 6)) +(test 7 'parameterize (parameterize ([error-print-width 10] + [current-exception-handler void]) + 7)) +(define oepw (error-print-width)) +(error-test '(parameterize ([error-print-width 777]) (error 'bad)) exn:user?) +(test oepw 'parameterize (error-print-width)) +(error-test '(parameterize ([error-print-width 777] + [current-output-port (current-error-port)]) + (error 'bad)) + exn:user?) +(error-test '(parameterize ([error-print-width 'a]) 10)) + +(error-test '(parameterize) syntaxe?) +(error-test '(parameterize ()) syntaxe?) +(error-test '(parameterize ((x y))) syntaxe?) +(error-test '(parameterize ((x y)) . 8) syntaxe?) +(error-test '(parameterize (x) 8) syntaxe?) +(error-test '(parameterize (9) 8) syntaxe?) +(error-test '(parameterize ((x z) . y) 8) syntaxe?) +(error-test '(parameterize ((x . z)) 8) syntaxe?) +(error-test '(parameterize ((x . 9)) 8) syntaxe?) +(error-test '(parameterize ((x . 9)) 8) syntaxe?) + +(SECTION 'time) +(test 1 'time (time 1)) +(test -1 'time (time (cons 1 2) -1)) +(test-values '(-1 1) (lambda () (time (values -1 1)))) +(syntax-test '(time)) +(syntax-test '(time . 1)) +(syntax-test '(time 1 . 2)) + +(SECTION 'compiler) +; Tests specifically aimed at the compiler +(error-test '(let ([x (values 1 2)]) x) exn:application:arity?) +; Known primitive +(error-test '(let ([x (#%make-pipe)]) x) exn:application:arity?) +; Known local +(error-test '(let* ([f (lambda () (values 1 2))][x (f)]) x) exn:application:arity?) + +; Known local with global in its closure +(test 15 'known (let ([g (lambda () + (letrec ([f (lambda (x) + (+ x 5))]) + (f 10)))]) + (g))) +; Known local with a set! +(test 16 'known (let ([g (lambda () + (letrec ([f (lambda (x) + (let ([y x]) + (set! x 7) + (+ y 5)))]) + (f 11)))]) + (g))) +; Known local non-function +(error-test '(apply (lambda () (let ([f 12]) (f))) null) exn:application:non-procedure?) +; Known local with revsed arguments: +(test 10 (letrec ([f (lambda (a b) (if (zero? a) b (f b a)))]) f) 10 0) + +(report-errs) diff --git a/collects/tests/mzscheme/tcp.ss b/collects/tests/mzscheme/tcp.ss new file mode 100644 index 0000000..7d62b51 --- /dev/null +++ b/collects/tests/mzscheme/tcp.ss @@ -0,0 +1,33 @@ + +(define (tread) + (let ([l (tcp-listen 40000)]) + (let-values ([(r w) (tcp-accept l)]) + (read-line) + (printf "Hit return to start reading~n") + (read-line) + (let loop ([last 'none-read]) + (let ([v (read r)]) + (if (eof-object? v) + last + (loop v))))))) + +(define (twrite) + (let-values ([(r w) (tcp-connect "localhost" 40000)]) + (let loop ([n 0]) + (if (tcp-port-send-waiting? w) + (begin + (printf "write-full at ~s~n" n) + (let loop ([m 0]) + (if (= m 5) + (begin + (printf "done: ~s~n" (+ m n -1)) + (close-output-port w) + (close-input-port r)) + (begin + (fprintf w "~s~n" (+ m n)) + (loop (add1 m)))))) + (begin + (fprintf w "~s~n" n) + (loop (add1 n))))))) + + \ No newline at end of file diff --git a/collects/tests/mzscheme/testing.ss b/collects/tests/mzscheme/testing.ss new file mode 100644 index 0000000..fa3023b --- /dev/null +++ b/collects/tests/mzscheme/testing.ss @@ -0,0 +1,318 @@ +;;; `test.scm' Test correctness of MzScheme implementations. +;;; Copyright (C) 1991, 1992, 1993, 1994 Aubrey Jaffer. +;;; Modified for MzScheme by Matthew + +;;; MODIFIED for MzScheme - Matthew 8/95 +;;; Added a few more tests, like append!, reverse!, etc. +;;; Added testing for inexact numbers +;;; Added a lot of error testing +;;; modified for rational and complex numbers - Matthew 12/95 +;;; modified to test exceptions and more of MzScheme - Matthew 4/96 +;;; split into multiple files - Matthew 4/96 +;;; extended, extended, extended + +;;; This includes examples from +;;; William Clinger and Jonathan Rees, editors. +;;; Revised^4 Report on the Algorithmic Language Scheme +;;; and the IEEE specification. + +; The format of the next line is important: file.ss relies on it +(define cur-section '())(define errs '()) + +(define teval eval) + +(define SECTION (lambda args + (display "SECTION") (write args) (newline) + (set! cur-section args) #t)) +(define record-error (lambda (e) (set! errs (cons (list cur-section e) errs)))) + +(print-struct #t) + +(define number-of-tests 0) +(define number-of-error-tests 0) +(define number-of-exn-tests 0) + +(define test + (lambda (expect fun . args) + (set! number-of-tests (add1 number-of-tests)) + (write (cons fun args)) + (display " ==> ") + (flush-output) + ((lambda (res) + (write res) + (newline) + (cond ((not (equal? expect res)) + (record-error (list res expect (cons fun args))) + (display " BUT EXPECTED ") + (write expect) + (newline) + #f) + (else #t))) + (if (procedure? fun) (apply fun args) (car args))))) + +(define exn-table + (list (cons exn? (cons exn-message string?)) + (cons exn:variable? (cons exn:variable-id symbol?)) + (cons exn:application:non-procedure? (cons exn:application-value + (lambda (x) (not (procedure? x))))) + (cons exn:application:arity? (cons exn:application-value integer?)) + (cons exn:application:arity? (cons exn:application:arity-expected + (lambda (a) + (or (integer? a) + (and (arity-at-least? a) + (integer? (arity-at-least-value a))) + (and (list? a) + (andmap + (lambda (a) + (or (integer? a) + (and (arity-at-least? a) + (integer? + (arity-at-least-value a))))) + a)))))) + (cons exn:application:type? (cons exn:application:type-expected symbol?)) + (cons exn:application:range? (cons exn:application-value integer?)) + (cons exn:application:range:bounds? (cons exn:application:range:bounds-min integer?)) + (cons exn:application:range:bounds? (cons exn:application:range:bounds-max integer?)) + (cons exn:application:math:zero? (cons exn:application-value zero?)) + (cons exn:application:math:radix? (cons exn:application-value integer?)) + (cons exn:application:list-sizes? (cons exn:application-value list?)) + (cons exn:application:map-arity? (cons exn:application-value procedure?)) + (cons exn:application:map-arity? (cons exn:application:map-arity-provided + (lambda (x) (and (integer? x) (positive? x))))) + (cons exn:application:mode-conflict? + (cons exn:application-value symbol?)) + (cons exn:application:mode-conflict? + (cons exn:application:mode-conflict-filename + string?)) + (cons exn:application:file-position? + (cons exn:application-value (lambda (x) (or (input-port? x) + (output-port? x))))) + (cons exn:application:fprintf:extra-arguments? + (cons exn:application-value string?)) + (cons exn:application:fprintf:extra-arguments? + (cons exn:application:fprintf:extra-arguments-extras list?)) + (cons exn:application:fprintf:no-argument? + (cons exn:application-value string?)) + (cons exn:application:fprintf:argument-type? + (cons exn:application:fprintf:argument-type-expected symbol?)) + + (cons exn:struct:struct-type? + (cons exn:struct:struct-type-value (lambda (x) (not (struct-type? x))))) + + (cons exn:read? (cons exn:read-port input-port?)) + (cons exn:read:number? (cons exn:read:number-input string?)) + (cons exn:read:char? (cons exn:read:char-input string?)) + (cons exn:read:eof? (cons exn:read:eof-expected string?)) + (cons exn:read:unsupported? (cons exn:read:unsupported-input string?)) + (cons exn:read:vector-length? (cons exn:read:vector-length-input string?)) + + (cons exn:object:class-type? (cons exn:object:class-type-value + (lambda (x) (not (class? x))))) + (cons exn:object:interface-type? (cons exn:object:interface-type-value + (lambda (x) (not (interface? x))))) + (cons exn:object:generic? (cons exn:object:generic-object object?)) + (cons exn:object:inherit? (cons exn:object:inherit-ivar symbol?)) + (cons exn:object:implement? (cons exn:object:implement-ivar symbol?)) + (cons exn:object:class-ivar? (cons exn:object:class-ivar-class class?)) + (cons exn:object:class-ivar? (cons exn:object:class-ivar-ivar symbol?)) + (cons exn:object:interface-ivar? (cons exn:object:interface-ivar-interface interface?)) + (cons exn:object:interface-ivar? (cons exn:object:interface-ivar-ivar symbol?)) + (cons exn:object:ivar? (cons exn:object:ivar-object object?)) + (cons exn:object:ivar? (cons exn:object:ivar-ivar symbol?)) + (cons exn:object:private-class? (cons exn:object:private-class-class class?)) + (cons exn:object:init? (cons exn:object:init-object object?)) + (cons exn:object:init? (cons exn:object:init-class class?)) + + (cons exn:unit:non-unit? (cons exn:unit:non-unit-value (lambda (x) (not (unit? x))))) + (cons exn:unit:arity? (cons exn:unit:arity-unit unit?)) + (cons exn:unit:import? (cons exn:unit:import-in-unit unit?)) + (cons exn:unit:import? (cons exn:unit:import-out-unit unit?)) + (cons exn:unit:import? (cons exn:unit:import-in-tag symbol?)) + (cons exn:unit:import? (cons exn:unit:import-out-tag symbol?)) + (cons exn:unit:import? (cons exn:unit:import-name symbol?)) + (cons exn:unit:export? (cons exn:unit:export-unit unit?)) + (cons exn:unit:export? (cons exn:unit:export-tag symbol?)) + (cons exn:unit:export? (cons exn:unit:export-name symbol?)) + (cons exn:unit:invoke:variable? (cons exn:unit:invoke:variable-name symbol?)) + (cons exn:unit:signature:non-signed-unit? + (cons exn:unit:signature:non-signed-unit-value (lambda (x) (not (unit/sig? x))))) + (cons exn:unit:signature:arity? + (cons exn:unit:signature:arity-unit unit/sig?)) + (cons exn:unit:signature:match? (cons exn:unit:signature:match-dest-context string?)) + (cons exn:unit:signature:match? (cons exn:unit:signature:match-src-context string?)) + (cons exn:unit:signature:match? (cons exn:unit:signature:match-variable string?)) + + (cons exn:i/o:read? (cons exn:i/o:read-port input-port?)) + (cons exn:i/o:write? (cons exn:i/o:write-port output-port?)) + (cons exn:i/o:filesystem? (cons exn:i/o:filesystem-pathname string?)) + (cons exn:i/o:port-closed? (cons exn:i/o:port-closed-port + (lambda (x) (or (input-port? x) (output-port? x))))) + (cons exn:i/o:user-port? (cons exn:i/o:user-port-port input-port?)) + + (cons exn:i/o:tcp:connect? (cons exn:i/o:tcp:connect-address string?)) + (cons exn:i/o:tcp:connect? (cons exn:i/o:tcp:connect-port-id integer?)) + (cons exn:i/o:tcp:listen? (cons exn:i/o:tcp:listen-port-id integer?)) + (cons exn:i/o:tcp:accept? (cons exn:i/o:tcp:accept-listener tcp-listener?)) + (cons exn:i/o:tcp:listener-closed? (cons exn:i/o:tcp:listener-closed-listener tcp-listener?)) + + (cons exn:misc:constant? (cons exn:misc:constant-id symbol?)))) + +(define thunk-error-test + (case-lambda + [(th expr) (thunk-error-test th expr exn:application:type?)] + [(th expr exn?) + (set! number-of-error-tests (add1 number-of-error-tests)) + (write expr) + (display " =e=> ") + (call/ec (lambda (escape) + (let* ([old-esc-handler (error-escape-handler)] + [old-handler (current-exception-handler)] + [orig-err-port (current-error-port)] + [test-handler + (lambda () + (escape #t))] + [test-exn-handler + (lambda (e) + (when (and exn? (not (exn? e))) + (printf " WRONG EXN TYPE: ~s " e) + (record-error (list e 'exn-type expr))) + + (for-each + (lambda (row) + (let ([pred? (car row)]) + (when (pred? e) + (set! number-of-exn-tests + (add1 number-of-exn-tests)) + (let ([sel (cadr row)] + [pred? (cddr row)]) + (unless (pred? (sel e)) + (printf " WRONG EXN ELEM: ~s " e) + (record-error (list e 'exn-elem expr))))))) + exn-table) + + (old-handler e))]) + (dynamic-wind + (lambda () + (current-error-port (current-output-port)) + (current-exception-handler test-exn-handler) + (error-escape-handler test-handler)) + (lambda () + (let ([v (th)]) + (write v) + (display " BUT EXPECTED ERROR") + (record-error (list v 'Error expr)) + (newline) + #f)) + (lambda () + (current-error-port orig-err-port) + (current-exception-handler old-handler) + (error-escape-handler old-esc-handler))))))])) + +(if (not (defined? 'error-test)) + (define error-test + (case-lambda + [(expr) (error-test expr exn:application:type?)] + [(expr exn?) + (thunk-error-test (lambda () (eval expr)) expr exn?)]))) + +(define (syntax-test expr) + (error-test expr exn:syntax?) + (error-test `(if #f ,expr) exn:syntax?)) + +(define (arity-test f min max) + (letrec ([aok? + (lambda (a) + (cond + [(integer? a) (= a min max)] + [(arity-at-least? a) (and (negative? max) + (= (arity-at-least-value a) min))] + [(and (list? a) (andmap integer? a)) + (and (= min (car a)) (= max + (let loop ([l a]) + (if (null? (cdr l)) + (car l) + (loop (cdr l))))))] + [(list? a) + ; Just check that all are consistent for now. + ; This should be improved. + (andmap + (lambda (a) + (if (number? a) + (<= min a (if (negative? max) a max)) + (>= (arity-at-least-value a) min))) + a)] + [else #f]))] + [make-ok? + (lambda (v) + (lambda (e) + (and (exn:application:arity? e) + (= (exn:application-value e) v) + (aok? (exn:application:arity-expected e)))))] + [do-test + (lambda (f args check?) + (set! number-of-error-tests (add1 number-of-error-tests)) + (printf "(apply ~s '~s) =e=> " f args) + (let/ec done + (let ([v (with-handlers ([void + (lambda (exn) + (if (check? exn) + (printf " ~a~n" (exn-message exn)) + (let ([ok-type? (exn:application:arity? exn)]) + (printf " WRONG EXN ~a: ~s~n" + (if ok-type? + "FIELD" + "TYPE") + exn) + (record-error (list exn + (if ok-type? + 'exn-field + 'exn-type) + (cons f args))))) + (done (void)))]) + (apply f args))]) + (printf "~s~n BUT EXPECTED ERROR~n" v) + (record-error (list v 'Error (cons f args))))))]) + (let loop ([n 0][l '()]) + (unless (>= n min) + (do-test f l (make-ok? n)) + (loop (add1 n) (cons 1 l)))) + (let loop ([n min]) + (test #t procedure-arity-includes? f n) + (unless (>= n max) + (loop (add1 n)))) + (if (>= max 0) + (do-test f (let loop ([n 0][l '(1)]) + (if (= n max) + l + (loop (add1 n) (cons 1 l)))) + (make-ok? (add1 max))) + (test #t procedure-arity-includes? f (arithmetic-shift 1 100))))) + +(define (test-values l thunk) + (test l call-with-values thunk list)) + +(define (report-errs) + (printf "~nPerformed ~a expression tests (~a good expressions, ~a bad expressions)~n" + (+ number-of-tests number-of-error-tests) + number-of-tests + number-of-error-tests) + (printf "and ~a exception field tests.~n~n" + number-of-exn-tests) + (if (null? errs) + (display "Passed all tests.") + (begin + (display "Errors were:") + (newline) + (display "(SECTION (got expected (call)))") + (newline) + (for-each (lambda (l) (write l) (newline)) + errs))) + (newline) + (display "(Other messages report successful tests of error-handling behavior.)") + (newline)) + +(define type? exn:application:type?) +(define arity? exn:application:arity?) +(define syntaxe? exn:syntax?) + +(define non-z void) diff --git a/collects/tests/mzscheme/thread.ss b/collects/tests/mzscheme/thread.ss new file mode 100644 index 0000000..b1bb038 --- /dev/null +++ b/collects/tests/mzscheme/thread.ss @@ -0,0 +1,142 @@ + + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'threads) + +(define t (thread (lambda () 8))) +(test #t thread? t) + +(arity-test thread 1 1) +(error-test '(thread 5) type?) +(error-test '(thread (lambda (x) 8)) type?) +(arity-test thread? 1 1) + +; Should be able to make an arbitrarily deep chain of custodians +; if only the first & last are accssible: +(test #t custodian? + (let loop ([n 1000][c (current-custodian)]) + (if (zero? n) + c + (loop (sub1 n) (make-custodian c))))) + +(define SLEEP-TIME 0.1) +(define result 0) +(define th1 0) +(define set-ready + (let ([s (make-semaphore 1)] + [r #f]) + (lambda (v) + (semaphore-wait s) + (begin0 + r + (set! r v) + (semaphore-post s))))) +(define cm (make-custodian)) +(define th2 (parameterize ([current-custodian cm]) + (thread + (lambda () + (let ([cm2 (make-custodian cm)]) + (parameterize ([current-custodian cm2]) + (set! th1 (thread + (lambda () + (let loop () + (let ([r (set-ready #f)]) + (sleep SLEEP-TIME) + (set! result (add1 result)) + (when r (semaphore-post r))) + (loop))))))))))) +(define start result) +(let ([r (make-semaphore)]) + (set-ready r) + (semaphore-wait r)) +(test #f eq? start result) +(kill-thread th2) +(set! start result) +(let ([r (make-semaphore)]) + (set-ready r) + (semaphore-wait r)) +(test #f eq? start result) +(test #t thread-running? th1) +(custodian-shutdown-all cm) +(thread-wait th1) +(set! start result) +(test #f thread-running? th1) +(sleep SLEEP-TIME) +(test #t eq? start result) + +(error-test `(parameterize ([current-custodian cm]) (kill-thread (current-thread))) + exn:misc:thread:kill?) + +(test #t custodian? cm) +(test #f custodian? 1) +(arity-test custodian? 1 1) + +(arity-test make-custodian 0 1) +(error-test '(make-custodian 0)) + +(test (void) kill-thread t) +(arity-test kill-thread 1 1) +(error-test '(kill-thread 5) type?) + +(test #t thread-running? (current-thread)) +(arity-test thread-running? 1 1) +(error-test '(thread-running? 5) type?) + +(arity-test sleep 0 1) +(error-test '(sleep 'a) type?) +(error-test '(sleep 1+3i) type?) + +(define s (make-semaphore 1)) + +(test #t semaphore? s) + +(arity-test make-semaphore 0 1) +(error-test '(make-semaphore "a") type?) +(error-test '(make-semaphore -1) type?) +(error-test '(make-semaphore 1.0) type?) +(error-test '(make-semaphore (expt 2 64)) exn:misc:semaphore?) +(arity-test semaphore? 1 1) + +(define test-block + (lambda (block? thunk) + (let* ([hit? #f] + [t (parameterize + ([current-custodian (make-custodian)]) + (thread (lambda () (thunk) (set! hit? #t))))]) + (sleep 0.1) + (begin0 (test block? 'nondeterministic-block-test (not hit?)) + (kill-thread t))))) + +(test #t semaphore-try-wait? s) +(test #f semaphore-try-wait? s) +(semaphore-post s) +(test #t semaphore-try-wait? s) +(test #f semaphore-try-wait? s) +(semaphore-post s) +(test-block #f (lambda () (semaphore-wait s))) +(test-block #t (lambda () (semaphore-wait s))) +(semaphore-post s) +(test-block #f (lambda () (semaphore-wait/enable-break s))) +(test-block #t (lambda () (semaphore-wait/enable-break s))) + +(arity-test semaphore-try-wait? 1 1) +(arity-test semaphore-wait 1 1) +(arity-test semaphore-post 1 1) + +(define s (make-semaphore)) +(define result 0) +(define t-loop + (lambda (n m) + (lambda () + (if (zero? n) + (begin + (set! result m) + (semaphore-post s)) + (thread (t-loop (sub1 n) (add1 m))))))) +(thread (t-loop 25 1)) +(semaphore-wait s) +(test 26 'thread-loop result) + +(report-errs) diff --git a/collects/tests/mzscheme/thrport.ss b/collects/tests/mzscheme/thrport.ss new file mode 100644 index 0000000..86d378f --- /dev/null +++ b/collects/tests/mzscheme/thrport.ss @@ -0,0 +1,59 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'multi-threaded-ports) + +; Read from file with 3 threads, all writing to the same pipe +; read from pipe with 3 threads, all writing to the same output string +; compare resulting character content to the original file +(test 0 'threaded-ports + (let*-values ([(f-in) (open-input-file + (path->complete-path "testing.ss" + (current-load-relative-directory)))] + [(p-in p-out) (make-pipe)] + [(s-out) (open-output-string)] + [(in->out) (lambda (in out) + (lambda () + (let loop () + (let ([c (read-char in)] + [dummy (lambda () 'hi)]) + (unless (eof-object? c) + (write-char c out) + (loop))))))] + [(f->p) (in->out f-in p-out)] + [(p->s) (in->out p-in s-out)] + [(sthread) (lambda (thunk) + (let ([t (thread (lambda () (sleep) (thunk)))]) + (thread-weight t 101) + t))]) + (thread + (lambda () + (for-each thread-wait + (list (sthread f->p) + (sthread f->p) + (sthread f->p))) + (close-output-port p-out))) + (for-each thread-wait + (list (sthread p->s) + (sthread p->s) + (sthread p->s))) + (let ([s (get-output-string s-out)] + [hits (make-vector 256 0)]) + (for-each (lambda (c) + (let ([n (char->integer c)]) + (vector-set! hits n (add1 (vector-ref hits n))))) + (string->list s)) + (file-position f-in 0) + (let loop () + (let ([c (read-char f-in)]) + (unless (eof-object? c) + (let ([n (char->integer c)]) + (vector-set! hits n (sub1 (vector-ref hits n)))) + (loop)))) + (let loop ([i 0][total 0]) + (if (= i 256) + total + (loop (add1 i) (+ total (abs (vector-ref hits i))))))))) + +(report-errs) diff --git a/collects/tests/mzscheme/ttt/listlib.ss b/collects/tests/mzscheme/ttt/listlib.ss new file mode 100644 index 0000000..c02be8c --- /dev/null +++ b/collects/tests/mzscheme/ttt/listlib.ss @@ -0,0 +1,42 @@ +;; -------------------------------------------------------------------------- +;; list-library.ss +;; export: +;; collect: +;; (A ((cons B (listof B)) (listof B) (union A C) -> (union A C)) +;; -> +;; ((listof B) -> (union A C))) + +; #| +; (unit/sig +; (collect filter set-minus subset?) +; (import plt:userspace^) +; |# + + (define collect + (lambda (base combine) + (local ((define C + (lambda (l) + (cond + ((null? l) base) + (else (combine l (car l) (C (cdr l)))))))) + C))) + + (define filter + (lambda (p? l) + [(collect null (lambda (_ x rest) (if (p? x) (cons x rest) rest))) l])) + + ;; set library + (define set-minus + (lambda (set1 set2) + [(collect null (lambda (_ e1 rest) (if (member e1 set2) rest (cons e1 rest)))) + set1])) + + (define subset? + (lambda (state1 state2) + (cond + ((null? state1) #t) + (else (and (member (car state1) state2) + (subset? (cdr state1) state2)))))) +; #| +; ) +; |# diff --git a/collects/tests/mzscheme/ttt/tic-bang.ss b/collects/tests/mzscheme/ttt/tic-bang.ss new file mode 100644 index 0000000..85422cd --- /dev/null +++ b/collects/tests/mzscheme/ttt/tic-bang.ss @@ -0,0 +1,123 @@ +;; -------------------------------------------------------------------------- +;; tic-bang.ss +;; This is an imperative version. + +;; This program plays through all possibilities of a tic-tac-toe +;; game, given the first move of a player. It only prints how many +;; states are being processed and how many states are terminal at +;; each stage of the game. + +;; This program lacks the capability to print how a situation arose. + +;; It relies on list-library.ss. + +;; representations of fields, states, and collections of states +(define BLANK 0) + +(define new-state + (lambda () + (make-2vec 3 BLANK))) + +(define update-state + (lambda (state x y token) + (2vec-set! state x y token) + state)) + +(define blank? + (lambda (astate i j) + (eq? (2vec-ref astate i j) BLANK))) + +(define clone-state + (lambda (state) + (let ((s (new-state))) + (let loop ((i 0) (j 0)) + (cond + ((and (= i 3) (= j 0)) (void)) + ((< j 3) (update-state s i j (2vec-ref state i j)) (loop i (+ j 1))) + ((< i 3) (loop (+ i 1) 0)) + (else 'bad))) + s))) + +;(define-type state (2vector (union 'x 'o '_))) +;(define-type states (listof state)) + +(define PLAYER 1) +(define OPPONENT 2) + +(define tic-tac-toe + (lambda (x y) + (tic (list (update-state (new-state) (- x 1) (- y 1) PLAYER))))) + +(define make-move + (lambda (other-move p/o tag) + (lambda (states) + (printf "~s: processing ~s states ~n" tag (length states)) + (let ((t (print&remove-terminals states))) + (printf "terminal states removed: ~s~n" + (- (length states) (length t))) + (if (null? t) + (void) + (other-move (apply append (map p/o t)))))))) + +(define tic (make-move (lambda (x) (tac x)) (lambda (x) (opponent x)) 'tic)) + +(define tac (make-move (lambda (x) (tic x)) (lambda (x) (player x)) 'tac)) + +(define make-players + (lambda (p/o) + (lambda (astate) + (let loop ((i 0) (j 0)) + (cond + ((and (= i 3) (= j 0)) null) + ((< j 3) (if (blank? astate i j) + (cons (update-state (clone-state astate) i j p/o) + (loop i (+ j 1))) + (loop i (+ j 1)))) + ((< i 3) (loop (+ i 1) 0)) + (else (error 'make-player "ouch"))))))) + +(define player (make-players PLAYER)) + +(define opponent (make-players OPPONENT)) + +(define print&remove-terminals + (local ((define print-state + (lambda (x) + ;(display ".") + (void)))) + + (collect null (lambda (_ astate rest) + (if (terminal? astate) + (begin (print-state astate) rest) + (cons astate rest)))))) + +(define terminal? + (lambda (astate) + (or (terminal-row 0 astate) + (terminal-row 1 astate) + (terminal-row 2 astate) + (terminal-col 0 astate) + (terminal-col 1 astate) + (terminal-col 2 astate) + (terminal-posdg astate) + (terminal-negdg astate)))) + +(define terminal-row + (lambda (n state) + (and (not (blank? state n 0)) + (= (2vec-ref state n 0) (2vec-ref state n 1) (2vec-ref state n 2))))) + +(define terminal-col + (lambda (n state) + (and (not (blank? state 0 n)) + (= (2vec-ref state 0 n) (2vec-ref state 1 n) (2vec-ref state 2 n))))) + +(define terminal-posdg + (lambda (state) + (and (not (blank? state 0 0)) + (= (2vec-ref state 0 0) (2vec-ref state 1 1) (2vec-ref state 2 2))))) + +(define terminal-negdg + (lambda (state) + (and (not (blank? state 0 2)) + (= (2vec-ref state 0 2) (2vec-ref state 1 1) (2vec-ref state 2 0))))) diff --git a/collects/tests/mzscheme/ttt/tic-func.ss b/collects/tests/mzscheme/ttt/tic-func.ss new file mode 100644 index 0000000..337a77a --- /dev/null +++ b/collects/tests/mzscheme/ttt/tic-func.ss @@ -0,0 +1,119 @@ +;; -------------------------------------------------------------------------- +;; tic-func.ss +;; This program plays through all possibilities of a tic-tac-toe +;; game, given the first move of a player. It only prints how many +;; states are being processed and how many states are terminal at +;; each stage of the game. But it is constructed so that it can +;; print how to get to a winning terminal state. + +;; It relies on list-library.ss. + +;; representations of fields, states, and collections of states +(define null '()) +(define-structure (entry x y who)) +(define entry-field + (lambda (an-entry) + (list (entry-x an-entry) (entry-y an-entry)))) +;(define-type state (listof (structure:entry num num (union 'x 'o))) +;(define-type states (listof state)) + +(define PLAYER 'x) +(define OPPONENT 'o) + +(define tic-tac-toe + (lambda (x y) + (tic (list (list (make-entry x y PLAYER)))))) + +(define make-move + (lambda (other-move p/o tag) + (lambda (states) + (printf "~s: processing ~s states of length ~s ~n" + tag (length states) (length (car states))) + (let ((t (print&remove-terminals states))) + (printf "terminal states removed: ~s~n" + (- (length states) (length t))) + (if (null? t) + (void) + (other-move (apply append (map p/o t)))))))) + +(define tic (make-move (lambda (x) (tac x)) (lambda (x) (opponent x)) 'tic)) + +(define tac (make-move (lambda (x) (tic x)) (lambda (x) (player x)) 'tac)) + +(define make-players + (local ((define rest-of-fields + (lambda (used-fields) + (set-minus ALL-FIELDS used-fields)))) + (lambda (player/opponent) + (lambda (astate) + (map (lambda (counter-move) + (let ((counter-x (car counter-move)) + (counter-y (cadr counter-move))) + (cons (make-entry counter-x counter-y player/opponent) + astate))) + (rest-of-fields (map entry-field astate))))))) + +(define player (make-players PLAYER)) + +(define opponent (make-players OPPONENT)) + +(define terminal? + (local ((define filter-p/o + (lambda (p/o astate) + (map entry-field + (filter (lambda (x) (eq? (entry-who x) p/o)) astate))))) + (lambda (astate) + (and (>= (length astate) 5) + (let ((PLAYERf (filter-p/o PLAYER astate)) + (OPPONENTf (filter-p/o OPPONENT astate))) + (or + (= (length astate) 9) + (ormap (lambda (ts) (subset? ts PLAYERf)) TERMINAL-STATES) + (ormap (lambda (ts) (subset? ts OPPONENTf)) TERMINAL-STATES))))))) + +(define print&remove-terminals + (local ( + + (define print-state1 + (lambda (x) + (display x) + (newline))) + + (define print-state2 + (lambda (astate) + (cond + ((null? astate) (printf "------------~n")) + (else (print-state (cdr astate)) + (let ((x (car astate))) + (printf " ~s @ (~s,~s) ~n" + (entry-who x) (entry-x x) (entry-y x))))))) + + (define print-state + (lambda (x) + ;(display ".") + (void)))) + + (collect null (lambda (_ astate rest) + (if (terminal? astate) + (begin (print-state astate) rest) + (cons astate rest)))))) +;; fields +(define T + (lambda (alof) + (cond + ((null? alof) null) + (else (cons (list (cadr (car alof)) (car (car alof))) + (T (cdr alof))))))) + +(define row1 (list (list 1 1) (list 1 2) (list 1 3))) +(define row2 (list (list 2 1) (list 2 2) (list 2 3))) +(define row3 (list (list 3 1) (list 3 2) (list 3 3))) +(define col1 (list (list 1 1) (list 2 1) (list 3 1))) +(define col2 (list (list 1 2) (list 2 2) (list 3 2))) +(define col3 (list (list 1 3) (list 2 3) (list 3 3))) +(define posd (list (list 1 1) (list 2 2) (list 3 3))) +(define negd (list (list 1 3) (list 2 2) (list 3 1))) + +(define TERMINAL-STATES (list row1 row2 row3 col1 col2 col3 posd negd)) + +(define ALL-FIELDS (append row1 row2 row3)) diff --git a/collects/tests/mzscheme/ttt/ttt.ss b/collects/tests/mzscheme/ttt/ttt.ss new file mode 100644 index 0000000..091e9f1 --- /dev/null +++ b/collects/tests/mzscheme/ttt/ttt.ss @@ -0,0 +1,14 @@ + +(read-case-sensitive #t) +(require-library "core.ss") +(load "listlib.ss") +(load "veclib.ss") +(load "tic-func.ss") + +(let loop () + (collect-garbage) + (collect-garbage) + (collect-garbage) + (dump-memory-stats) + (time (tic-tac-toe 1 1)) + (loop)) diff --git a/collects/tests/mzscheme/ttt/veclib.ss b/collects/tests/mzscheme/ttt/veclib.ss new file mode 100644 index 0000000..18ac802 --- /dev/null +++ b/collects/tests/mzscheme/ttt/veclib.ss @@ -0,0 +1,57 @@ +;; -------------------------------------------------------------------------- +;; 2vec-library.ss + +; #| +; (unit/sig +; (make-2vec 2vec-ref 2vec-set! collect) +; (import plt:userspace^) +; |# + + ;; 2 dimensional, square vectors + + (define collect + (lambda (base combine) + (local ((define C + (lambda (l) + (cond + ((null? l) base) + (else (combine l (car l) (C (cdr l)))))))) + C))) + + (define (make-2vec N element) + (make-vector (* N N) element)) + + (define (2vec-ref 2vec i j) + (let ((L (sqrt (vector-length 2vec)))) + (vector-ref 2vec (+ (* i L) j)))) + + (define (2vec-set! 2vec i j element) + (let ((L (sqrt (vector-length 2vec)))) + (if (and (< i L) (< j L)) + (vector-set! 2vec (+ (* i L) j) element) + (error '2vec-set! "~s ~s" i j)))) + + (define (I N) + (let ((2vec (make-2vec N 0))) + (let loop ((i 0) (j 0)) + (if (= i N) + (void) + (begin + (2vec-set! 2vec i j 1) + (loop (add1 i) (add1 j))))) + 2vec)) + + (define (P N) + (let ((2vec (make-2vec N 0))) + (let loop ((i 0) (j 0)) + (cond + [(and (= i N) (= j 0)) (void)] + [(< j N) (2vec-set! 2vec i j (list i j)) (loop i (add1 j))] + [(< i N) (loop (add1 i) 0)] + [else (error 'P "impossible ~s ~s" i j)])) + 2vec)) + +; #| +; ) +; |# + diff --git a/collects/tests/mzscheme/uinc.ss b/collects/tests/mzscheme/uinc.ss new file mode 100644 index 0000000..ea489aa --- /dev/null +++ b/collects/tests/mzscheme/uinc.ss @@ -0,0 +1,2 @@ + +(+ 4 5) diff --git a/collects/tests/mzscheme/uinc2.ss b/collects/tests/mzscheme/uinc2.ss new file mode 100644 index 0000000..c1de73f --- /dev/null +++ b/collects/tests/mzscheme/uinc2.ss @@ -0,0 +1,2 @@ + +(define x 8) diff --git a/collects/tests/mzscheme/unit.ss b/collects/tests/mzscheme/unit.ss new file mode 100644 index 0000000..6c4febf --- /dev/null +++ b/collects/tests/mzscheme/unit.ss @@ -0,0 +1,383 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'unit) + +(syntax-test '(unit)) +(syntax-test '(unit (import))) +(syntax-test '(unit (impLort))) +(syntax-test '(unit (impLort) (export) 5)) +(syntax-test '(unit (import) (expLort) 5)) +(syntax-test '(unit import (export) 5)) +(syntax-test '(unit (import) export 5)) +(syntax-test '(unit (import) (export) . 5)) +(syntax-test '(unit (import 8) (export) 5)) +(syntax-test '(unit (import . i) (export) 5)) +(syntax-test '(unit (import (i)) (export) 5)) +(syntax-test '(unit (import i 8) (export) 5)) +(syntax-test '(unit (import i . b) (export) 5)) +(syntax-test '(unit (import i (b)) (export) 5)) +(syntax-test '(unit (import i) (export 7) 5)) +(syntax-test '(unit (import i) (export . a) (define a 6))) +(syntax-test '(unit (import i) (export a . b) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export (a x) . b) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export (a 8) b) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export b (a 8)) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export (a . x) b) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export b (a . x)) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export (a x y) b) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export (a x . y) b) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export b (a x . y)) (define a 5) (define b 6))) + +(syntax-test '(unit (import i) (export) (begin))) +(syntax-test '(unit (import i) (export) (begin 1 . 2))) +(syntax-test '(unit (import i) (export b a) (begin (define a 5) (define b 6) . x))) +(syntax-test '(unit (import i) (export b a) (begin (define a 5) (define b 6)) (define b 6))) + +(syntax-test '(unit (import #%car) (export) (define a 5))) +(syntax-test '(unit (import) (export #%car) (define a 5))) +(syntax-test '(unit (import) (export #%car) (define #%car 5))) +(syntax-test '(unit (import) (export) (define #%car 5))) +(syntax-test '(unit (import) (export) (define-values (3) 5))) + +(syntax-test '(unit (import a) (export (a x) b) (define a 5) (define b 6))) +(syntax-test '(unit (import a) (export (a x) (a y)) (define a 5) (define b 6))) +(syntax-test '(unit (import i a) (export (a x) b) (define a 5) (define b 6))) +(syntax-test '(unit (import b) (export (a x) b) (define a 5) (define b 6))) +(syntax-test '(unit (import i j i) (export (a x) b) (define a 5) (define b 6))) +(syntax-test '(unit (import i j j) (export (a x) b) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export a a) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export (a x) (b x)) (define a 5) (define b 6))) +(syntax-test '(unit (import i) (export (a x) b) (define a 5) (define a 6) (define b 6))) +(syntax-test '(unit (import make-i) (export (a x) b) (define a 5) (define-struct i ()) (define b 6))) +(syntax-test '(unit (import i) (export (make-a x) b) (define make-a 5) (define-struct a ()) (define b 6))) +(syntax-test '(unit (import i) (export (a x) b) (define a 5) (define r 6) (define r 7) (define b 6))) + +(syntax-test '(unit (import i) (export b (a x)) 5)) +(syntax-test '(unit (import i) (export (a x) b) (define x 5) (define b 6))) +(syntax-test '(unit (import i) (export (a x) b) (set! a 5) (define b 6))) + +(syntax-test '(compound-unit (import) (link (A (0 (A)))) (export))) ; self-import +(syntax-test '(compound-unit (import) (link (A (0 (A x)))) (export))) ; self-import + +(unless (defined? 'test-global-var) + (define test-global-var 5) + (syntax-test '(unit (import) (export) test-global-var)) + (constant-name 'test-global-var) + (syntax-test '(unit (import) (export) test-global-var))) + +(test #t unit? (unit (import) (export))) +(test #t unit? (unit (import) (export) 5)) +(test #t unit? (unit (import i) (export (a x)) (define a 8) (define x 5))) +(test 5 (lambda (f) (invoke-unit f)) (unit (import) (export) 5)) + +(test #t unit? (unit (import i) (export b a) (begin (define a 5) (define b 6)))) +(test #t unit? (unit (import i) (export b a) 'a (begin (define a 5) (define b 6)) 'b)) +(test #t unit? (unit (import i) (export b a) (begin (define a 5)) (define b 6))) +(test #t unit? (unit (import i) (export b a) (define a 5) (begin (define b 6)))) +(test #t unit? (unit (import i) (export b a) (define a 5) (begin (define y 7) (define b 6)) (+ y b a))) + +(test 3 'embedded-deeply ((invoke-unit (unit (import) (export) (lambda () (define x 3) x))))) +(test 1 'embedded-deeply-struct ((invoke-unit (unit (import) (export) (lambda () + (define-struct a ()) + make-a + 1))))) +(syntax-test '(compound-unit)) +(syntax-test '(compound-unit . x)) +(syntax-test '(compound-unit (import))) +(syntax-test '(compound-unit (import) . x)) +(syntax-test '(compound-unit (import) (link))) +(syntax-test '(compound-unit (import) (link) . x)) +(syntax-test '(compound-unit import (link) (export))) +(syntax-test '(compound-unit (import) link (export))) +(syntax-test '(compound-unit (import) (link) export)) +(syntax-test '(compound-unit ((import)) (link) (export))) +(syntax-test '(compound-unit (import) ((link)) (export))) +(syntax-test '(compound-unit (import) (link) ((export)))) +(syntax-test '(compound-unit (import . a) (link) (export))) +(syntax-test '(compound-unit (import b . a) (link) (export))) +(syntax-test '(compound-unit (import 1) (link) (export))) +(syntax-test '(compound-unit (import (a)) (link) (export))) +(syntax-test '(compound-unit (import (a . b)) (link) (export))) +(syntax-test '(compound-unit (import (a (b))) (link) (export))) +(syntax-test '(compound-unit (import ((a) b)) (link) (export))) +(syntax-test '(compound-unit (import) (link . a) (export))) +(syntax-test '(compound-unit (import) (link a) (export))) +(syntax-test '(compound-unit (import) (link (a)) (export))) +(syntax-test '(compound-unit (import) (link (a (b)) . c) (export))) +(syntax-test '(compound-unit (import) (link (a (b) . c)) (export))) +(syntax-test '(compound-unit (import) (link (a (b . c)) (c (d))) (export))) +(syntax-test '(compound-unit (import) (link (a (b c . e)) (c (d)) (e (f))) (export))) +(syntax-test '(compound-unit (import) (link (a (b 1))) (export))) +(syntax-test '(compound-unit (import) (link (a (b))) (export . a))) +(syntax-test '(compound-unit (import) (link (a (b))) (export a))) +(syntax-test '(compound-unit (import) (link (a (b))) (export (a w) . a))) +(syntax-test '(compound-unit (import) (link (a (b))) (export (a 1)))) +(syntax-test '(compound-unit (import) (link (a (b))) (export (a (x))))) +(syntax-test '(compound-unit (import) (link (a (b))) (export (1 w)))) + + +; Simple: + +(define m1 + (unit + (import) + (export x y a? set-a-b!) + + (define-struct a (b c)) + + (define x 7) + (define z 8) + (define y (lambda () (* z x))) + + (list x y z))) + +(test #t apply (lambda (x y z) (and (= x 7) (= z 8) (procedure? y) (= 0 (arity y)))) + (invoke-unit m1)) + +(test #t apply + (lambda (x y-val a? set-a-b!) + (and (= x 7) (= y-val 56) + (= 1 (arity a?)) + (= 2 (arity set-a-b!)))) + (invoke-unit + (compound-unit + (import) + (link [M (m1)] + [N ((unit + (import x y a? set-a-b!) + (export) + (list x (y) a? set-a-b!)) + (M x y a? set-a-b!))]) + (export)))) + +; Structures: + + +(define m2-1 + (unit + (import) + (export x struct:a a? v y) + + (define x 5) + (define-struct a (b c)) + (define v (make-a 5 6)) + (define (y v) (a? v)))) + +(define m2-2 + (unit + (import struct:a a?) + (export x? make-x x-z both) + + (define-struct (x struct:a) (y z)) + (define both (lambda (v) + (and (a? v) (x? v)))))) + +(define m2-3 + (compound-unit + (import) + (link [O (m2-1)][T (m2-2 (O struct:a) (O a?))]) + (export [O x struct:a v y] + [T x? make-x x-z both]))) + + +(let ([p (open-output-string)]) + (invoke-unit + (compound-unit + (import) + (link [M (m2-3)] + [N ((unit + (import x v struct:a y x? make-x x-z both) + (export) + (define (filter v) + (if (procedure? v) + `(proc: ,(inferred-name v)) + v)) + (display + (map filter (list x v struct:a y make-x x? x-z both)) + p) + (let ([v2 (make-x 1 2 3 4)]) + (display (map filter + (list x (struct-type? struct:a) + v (y v) (y x) + v2 + (y v2) + (x? v2) + (both v) + (both v2))) + p))) + (M x v struct:a y x? make-x x-z both))]) + (export))) + + (test (string-append "(5 #(struct:a 5 6) # (proc: y)" + " (proc: make-x) (proc: x?)" + " (proc: x-z) (proc: both))" + "(5 #t #(struct:a 5 6) #t #f #(struct:x 1 2 3 4) #t #t #f #t)") + get-output-string p)) + +; Compound with circularity + +(define make-z + (lambda (x-val) + (unit + (import z) + (export (x z) y) + + (define x x-val) + (define y (lambda () (- z x)))))) + +(define z1 (make-z 8)) +(define z2 (make-z 7)) + +(define m3 + (compound-unit + (import) + (link [Z1 (z1 (Z2 z))][Z2 (z2 (Z1 z))]) + (export [Z1 (y y1) (z x1)][Z2 (y y2) (z x2)]))) + +(invoke-open-unit m3) +(test '(-1 1 8 7) 'invoke-open-unit (list (y1) (y2) x1 x2)) + +; Dynamic linking + +(let ([u + (unit + (import x) + (export) + + (+ x 8))]) + + (test 10 'dynamic (invoke-unit + (unit + (import) + (export w) + + (define w 2) + + (invoke-unit u w))))) + +; Linking environemtns + +(if (defined? 'x) + (undefine 'x)) + +(define (make--eval) + (let ([n (make-namespace)]) + (lambda (e) + (let ([orig (current-namespace)]) + (dynamic-wind + (lambda () (current-namespace n)) + (lambda () (eval e)) + (lambda () (current-namespace orig))))))) + +(define u + (unit + (import) + (export x) + (define x 5))) +(define e (make--eval)) +(e (list 'invoke-open-unit u #f)) +(test #f defined? 'x) +(test #t e '(defined? 'x)) + +(define u2 + (let ([u u]) + (unit + (import) + (export) + (invoke-open-unit u #f)))) +(define e (make--eval)) +(e (list 'invoke-open-unit u2 #f)) +(test #f defined? 'x) +(test #t e '(defined? 'x)) + + +; Misc + +(test 12 'nested-units + (invoke-unit + (compound-unit + (import) + (link (a@ ((unit (import) (export s@:a) (define s@:a 5)))) + (u@ ((compound-unit + (import a@:s@:a) + (link (r@ ((unit (import a) (export) (+ a 7)) a@:s@:a))) + (export)) + (a@ s@:a)))) + (export)))) + +; Import linking via invoke-unit + +(test '(5 7 (7 2)) 'invoke-unit-linking + (let ([u (unit (import x) (export) x)] + [v (unit (import x) (export) (lambda () x))] + [x 5]) + (list (invoke-unit u x) + (begin + (set! x 7) + (invoke-unit u x)) + (let ([f (invoke-unit v x)]) + (list + (f) + (begin + (set! x 2) + (f))))))) + +; Shadowed syntax definitions: + +(test 8 'unit (invoke-unit (unit (import) (export) (define lambda 8) lambda))) +(test 9 'unit (invoke-unit (unit (import) (export) (begin (define lambda 9) (define lambda2 lambda)) lambda2))) + +; Multiple values +(test '(1 2 3) + call-with-values + (lambda () (invoke-unit (unit (import) (export) (values 1 2 3)))) + list) + +; Units within units: + +(define u (unit + (import) + (export) + (define y 10) + (define x 5) + (unit + (import) + (export) + x))) +(test #t unit? u) +(define u2 (invoke-unit u)) +(test #t unit? u2) +(test 5 'invoke-unit-in-unit (invoke-unit u2)) + +; Units and objects combined: + +(define u@ + (unit (import x) (export) + (class* () () () (public (y x))))) +(define v (invoke-unit u@ car)) +(test #t class? v) +(define w (make-object v)) +(test car 'ivar (ivar w y)) + +(define c% + (class* () () (x) + (public (z (unit (import) (export) x))))) +(define u (ivar (make-object c% car) z)) +(test #t unit? u) +(test car 'invoke (invoke-unit u)) + + +(define c% + (class* () () (x) (public (y x)) + (public (z (unit (import) (export) y))))) +(define u (make-object c% 3)) +(define u2 (ivar u z)) +(test #t unit? u2) +(test 3 'invoke (invoke-unit u2)) + +(test (letrec* ([x y][y 0]) x) 'invoke + (invoke-unit (unit (import) (export) (define x y) (define y 7) x))) + +(report-errs) diff --git a/collects/tests/mzscheme/unitsig.ss b/collects/tests/mzscheme/unitsig.ss new file mode 100644 index 0000000..81d9be9 --- /dev/null +++ b/collects/tests/mzscheme/unitsig.ss @@ -0,0 +1,441 @@ + +(if (not (defined? 'SECTION)) + (load-relative "testing.ss")) + +(SECTION 'unit/sig) + +(undefine 'a) +(undefine 'b) + +(syntax-test '(define-signature)) +(syntax-test '(define-signature)) +(syntax-test '(define-signature 8)) +(syntax-test '(define-signature . x)) +(syntax-test '(define-signature x)) +(syntax-test '(define-signature 8)) +(syntax-test '(define-signature x (8))) +(syntax-test '(define-signature x (a . 8))) +(syntax-test '(define-signature x (a . y))) +(syntax-test '(define-signature x (y y))) +(syntax-test '(define-signature x ((y)))) +(syntax-test '(define-signature x ((struct)))) +(syntax-test '(define-signature x ((struct y)))) +(syntax-test '(define-signature x ((struct . y)))) +(syntax-test '(define-signature x ((struct y . x)))) +(syntax-test '(define-signature x ((struct y x)))) +(syntax-test '(define-signature x ((struct y (x)) . x))) +(syntax-test '(define-signature x ((unit)))) +(syntax-test '(define-signature x ((unit y)))) +(syntax-test '(define-signature x ((unit . y)))) +(syntax-test '(define-signature x ((unit y : a)))) +(define-signature a ()) +(syntax-test '(define-signature x ((unit y a)))) +(syntax-test '(define-signature x ((unit y . a)))) +(syntax-test '(define-signature x ((unit y : . a)))) +(syntax-test '(define-signature x ((unit y a) . x))) +(syntax-test '(define-signature x (y (unit y a)))) + +(syntax-test '(unit/sig)) +(syntax-test '(unit/sig 8)) +(syntax-test '(unit/sig b)) +(define-signature b (x y)) +(syntax-test '(unit/sig (a))) +(syntax-test '(unit/sig a (impLort))) +(syntax-test '(unit/sig a (impLort) 5)) +(syntax-test '(unit/sig a import 5)) +(syntax-test '(unit/sig a (import . x) . 5)) +(syntax-test '(unit/sig a (import (x) 8) 5)) +(syntax-test '(unit/sig a (import (x) . i) 5)) +(syntax-test '(unit/sig a (import (i : a) . b) 5)) +(syntax-test '(unit/sig b (import (i : a)) 5)) +(syntax-test '(unit/sig a (import (i : a x)) 5)) +(syntax-test '(unit/sig a (import (i : a) x) 5)) +(syntax-test '(unit/sig b (import (i : a)) (define x 7))) +(syntax-test '(unit/sig b (import (i : a)) (define x 7) (define i:y 6))) +(syntax-test '(unit/sig blah (import) (define x 7))) + +(syntax-test '(unit/sig () (import) (begin))) +(syntax-test '(unit/sig () (import) (begin 1 . 2))) +(syntax-test '(unit/sig () (import) (begin (define x 5)) (define x 5))) + +(define b@ (unit/sig b (import) (define x 9) (define y 9))) +(define b2@ (unit/sig b (import (i : a)) (define x 9) (define y 9))) +(define b3@ (unit/sig b (import (i : ())) (define x 9) (define y 9))) +(define b3u@ (unit/sig b (import ()) (define x 9) (define y 9))) +(define b3u2@ (unit/sig b (import a) (define x 9) (define y 9))) +(define-signature >b ((unit b@ : b))) +(define b3u3@ (unit/sig b (import (i : >b)) (define x 9) (define y 9))) + +(define >b@ (compound-unit/sig (import) (link [b@ : b (b@)]) (export (unit b@)))) + +(syntax-test '(compound-unit/sig)) +(syntax-test '(compound-unit/sig 8)) +(syntax-test '(compound-unit/sig b)) +(syntax-test '(compound-unit/sig (import) (link) (export (var (U x))))) +(syntax-test '(compound-unit/sig (import a) (link) (export))) +(syntax-test '(compound-unit/sig (import 5) (link) (export))) +(syntax-test '(compound-unit/sig (import . i) (link) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link ()) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@)) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ b)) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b)) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b ())) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@ 5))) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@ . i))) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@ (i . a)))) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@ (i a a)))) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@ c@))) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@ (c@ a)))) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export . b@))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export b@))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (unit)))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (unit c@)))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (unit b@ : c)))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (unit b@ (b@))))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (unit b@ : (b@))))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var)))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (open)))) +(error-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@ (i : a)))) (export)) exn:unit:signature:arity?) +(error-test '(compound-unit/sig (import (i : a)) (link (b@ : b (5 (i : a)))) (export)) exn:unit:signature:non-signed-unit?) +(error-test '(compound-unit/sig (import (i : b)) (link (b@ : b (b3@ (i : b)))) (export)) exn:unit:signature:match:extra?) +(error-test '(compound-unit/sig (import (i : b)) (link (b@ : b (b3u@ (i : b)))) (export)) exn:unit:signature:match:extra?) +(error-test '(compound-unit/sig (import (i : b)) (link (b@ : b (b3u2@ (i : b)))) (export)) exn:unit:signature:match:extra?) +(error-test '(compound-unit/sig (import (i : >b)) (link (b@ : b (b3@ (i : >b)))) (export)) exn:unit:signature:match:extra?) +(error-test '(compound-unit/sig (import (i : ((open a) x))) (link (b@ : b (b3@ (i : ((open a) x))))) (export)) exn:unit:signature:match:extra?) +(error-test '(compound-unit/sig (import (i : ((unit b@ : ((open b) w))))) (link (b@ : b (b3u3@ i))) (export)) exn:unit:signature:match:extra?) +(error-test '(compound-unit/sig (import (i : a)) (link (b@ : (w) (b@))) (export)) exn:unit:signature:match:missing?) +(error-test '(compound-unit/sig (import (i : ())) (link (b@ : b (b3u3@ i))) (export)) exn:unit:signature:match:missing?) +(error-test '(compound-unit/sig (import (i : ((unit b@ : ())))) (link (b@ : b (b3u3@ i))) (export)) exn:unit:signature:match:missing?) +(error-test '(compound-unit/sig (import (i : (b@))) (link (b@ : b (b3u3@ i))) (export)) exn:unit:signature:match:kind?) +(error-test '(compound-unit/sig (import (i : ((unit b@ : (x (unit y : ())))))) (link (b@ : b (b3u3@ i))) (export)) exn:unit:signature:match:kind?) +(syntax-test '(compound-unit/sig (import) (link [b@ : b (0 5)]) (export))) +(syntax-test '(compound-unit/sig (import) (link [b@ : b (0 ())]) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : a (5 (i : b)))) (export))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var b@)))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var (b@))))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var (b@ x y))))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var (5 x))))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var (b@ 5))))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var ((b@ w) 5))))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var ((b@ 7) 5))))) +(syntax-test '(compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var (b@ x . a))))) + +(syntax-test '(compound-unit/sig (import) (link (A : () (0 A))) (export))) ; self-import +(syntax-test '(compound-unit/sig (import) (link (A : (x) (0 A))) (export))) ; self-import + +(test #t unit/sig? (unit/sig a (import))) +(test #t unit/sig? (unit/sig b (import) (define x 1) (define y 2))) +(test #t unit/sig? (unit/sig a (import (i : b)) i:x)) +(test 5 (lambda (f) (invoke-unit/sig f ())) (unit/sig a (import ()) 5)) +(test #t unit/sig? (unit/sig (x) (import) (begin (define x 5)))) +(test #t unit/sig? (unit/sig (x) (import) (define a 14) (begin (define x 5) (define y 10)) (define z 12))) +(test #t unit/sig? (compound-unit/sig (import) (link) (export))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b2@ (i : a)))) (export))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b2@ ((i) : a)))) (export))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b2@ ((i) : ())))) (export))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var (b@ x))))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var (b@ x) w)))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (var ((b@) x) w)))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (unit b@)))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (unit (b@))))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (unit b@ b@)))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (open b@)))) +(test #t unit/sig? (compound-unit/sig (import (i : a)) (link (b@ : b (b@))) (export (open (b@ : b))))) + +; Include: + +(define i1@ + (unit/sig + () + (import) + + (include "uinc.ss"))) + +(test 9 'include (invoke-unit/sig i1@)) + +(define i2@ + (unit/sig + () + (import) + + (include "uinc.ss") + (include "uinc2.ss") + (include "uinc.ss") + (+ x 2))) + +(test 10 'include (invoke-unit/sig i2@)) + +; Simple: + +(define-signature m1^ + (x y a? set-a-b!)) + +(define m1@ + (unit/sig + m1^ + (import) + + (define-struct a (b c)) + + (define x 7) + (define z 8) + (define y (lambda () (* z x))) + + (list x y z))) + +(test #t apply (lambda (x y z) (and (= x 7) (= z 8) (procedure? y) (= 0 (arity y)))) + (invoke-unit/sig m1@)) + +(test #t apply + (lambda (x y-val a? set-a-b!) + (and (= x 7) (= y-val 56) + (= 1 (arity a?)) + (= 2 (arity set-a-b!)))) + (invoke-unit/sig + (compound-unit/sig + (import) + (link [M@ : m1^ (m1@)] + [N@ : () ((unit/sig + () + (import (i@ : m1^)) + (list i@:x (i@:y) i@:a? i@:set-a-b!)) + M@)]) + (export (open M@))))) + +; More: + +(define-signature m2-1-lite^ + (x struct:a v y)) + +(define-signature m2-1^ + (a? + (open m2-1-lite^))) + +(define-signature m2-2^ + (x? make-x x-z both)) + +(define m2-1@ + (unit/sig + m2-1^ + (import) + + (define x 5) + (define-struct a (b c)) + (define v (make-a 5 6)) + (define (y v) (a? v)))) + +(define m2-2@ + (unit/sig + m2-2^ + (import m2-1^) + + (define-struct (x struct:a) (y z)) + (define both (lambda (v) + (and (a? v) (x? v)))))) + +(define-signature m2-3^ + (simple)) + +(let-signature m2-3^ + ((unit one@ : m2-1-lite^) + (unit two@ : m2-2^) + a?-again) + + (define m2-3@ + (compound-unit/sig + + (import) + (link [O@ : m2-1^ (m2-1@)] + [T@ : m2-2^ (m2-2@ O@)]) + (export (unit (O@ : m2-1-lite^) one@) + (unit T@ two@) + (var (O@ a?) a?-again)))) + + (let ([p (open-output-string)] + [filter (lambda (v) + (if (procedure? v) + `(proc: ,(inferred-name v)) + v))]) + (invoke-unit/sig + (compound-unit/sig + (import) + (link [M@ : m2-3^ (m2-3@)] + [N@ : () ((unit/sig + () + (import (i : m2-3^)) + (display (map + filter + (list i:one@:x i:one@:v i:one@:struct:a i:one@:y + i:two@:make-x i:two@:x? i:two@:x-z i:two@:both + i:a?-again)) + p) + (let ([v2 (i:two@:make-x 1 2 3 4)]) + (display (map + filter + (list i:one@:x (struct-type? i:one@:struct:a) + i:one@:v (i:one@:y i:one@:v) (i:one@:y i:one@:x) + v2 + (i:one@:y v2) + (i:two@:x? v2) + (i:two@:both i:one@:v) + (i:two@:both v2))) + p))) + M@)]) + (export))) + (test (string-append "(5 #(struct:a 5 6) # (proc: y)" + " (proc: make-x) (proc: x?)" + " (proc: x-z) (proc: both) (proc: a?))" + "(5 #t #(struct:a 5 6) #t #f #(struct:x 1 2 3 4) #t #t #f #t)") + get-output-string p))) + +(test 5 'let-sig + (invoke-unit/sig + (unit/sig + m2-3^ + (import) + (define simple 5) + simple))) + +(define-signature big^ + (a b c)) +(define-signature little^ + (a b c)) + +(test 11 + 'link-restrict + (invoke-unit/sig + (compound-unit/sig + (import) + (link [a@ : big^ ((unit/sig big^ (import) (define a 5) (define b 6) (define c 7)))] + [b@ : () ((unit/sig () (import (i : little^)) (+ i:a i:b)) + (a@ : little^))]) + (export)))) + +(define-signature just-a^ + (a)) +(define-signature >just-a^ + ((unit s@ : just-a^))) + +; Test a path for linking: root is a constiuent +(test 12 + 'link-path + (invoke-unit/sig + (compound-unit/sig + (import) + (link [a@ : >just-a^ ((compound-unit/sig + (import) + (link [i@ : just-a^ ((unit/sig + just-a^ + (import) + (define a 5)))]) + (export (unit i@ s@))))] + [r@ : () ((unit/sig + () + (import (i : just-a^)) + (+ i:a 7)) + (a@ s@))]) + (export)))) + +; Test a path for linking: root is an import +(test 12 + 'import-path + (invoke-unit/sig + (compound-unit/sig + (import) + (link [a@ : >just-a^ ((compound-unit/sig + (import) + (link [i@ : just-a^ ((unit/sig + just-a^ + (import) + (define a 5)))]) + (export (unit i@ s@))))] + [u@ : () ((compound-unit/sig + (import (a@ : >just-a^)) + (link [r@ : () ((unit/sig + () + (import (i : just-a^)) + (+ i:a 7)) + (a@ s@))]) + (export)) + a@)]) + (export)))) + +; Export var from embedded unit: + +(define-signature e ((unit w : (embedded-v)))) +(invoke-open-unit/sig + (compound-unit/sig + (import) + (link [E : e ((compound-unit/sig + (import) + (link [w : (embedded-v) ((unit/sig (embedded-v) + (import) + (define embedded-v 0)))]) + (export (unit w))))]) + (export (var ((E w) embedded-v))))) +(test 0 'embedded-v embedded-v) + +; Signature ordering + +(define o1 (unit/sig (num sym) (import) (define num 5) (define sym 'a))) +(define o2 (unit/sig () (import (sym num)) (list sym (+ num)))) + +(test (list 'a 5) + 'order + (invoke-unit/sig + (compound-unit/sig + (import) + (link [one : (num sym) (o1)] + [two : () (o2 one)]) + (export)))) + +; unit->unit/sig, etc. + +(define-signature s1 + (a b c)) +(define-signature s2 + (+)) + +(define us1 + (unit + (import +) + (export a b c) + + (define a 1) + (define b 2) + (define c 3) + (+ a b c))) + +(test 6 'u->s (invoke-unit us1 +)) +(test 6 'u->s (invoke-unit/sig (unit->unit/sig us1 (s2) s1) s2)) + +; Exporting a name twice: + +(syntax-test + '(compound-unit/sig + (import) + (link [A : (a) ((unit/sig (a) (import) (define a 1)))]) + (export (var (A a)) (open A)))) + +(syntax-test + '(compound-unit/sig + (import) + (link [A : (a) ((unit/sig (a) (import) (define a 1)))] + [B : (b) ((unit/sig (b) (import) (define b 2)))]) + (export (unit A x) (unit B x)))) + +(syntax-test + '(compound-unit/sig + (import) + (link [A : (a) ((unit/sig (a) (import) (define a 1)))] + [B : (b) ((unit/sig (b) (import) (define b 2)))]) + (export (unit A) (unit B A)))) + +; Shadowed syntax definitions: + +(test 8 'unit/sig (invoke-unit/sig (unit/sig () (import) (define lambda 8) lambda))) +(test 9 'unit/sig (invoke-unit/sig (unit/sig () (import) (begin (define lambda 9) (define lambda2 lambda)) lambda2))) + +(report-errs) + diff --git a/collects/tests/mzscheme/ztest.ss b/collects/tests/mzscheme/ztest.ss new file mode 100644 index 0000000..2956776 --- /dev/null +++ b/collects/tests/mzscheme/ztest.ss @@ -0,0 +1,20 @@ +;; rudimentary test harness for complex math routines in +;; zmath.ss + +(require-library "zmath.ss") + +(define ztest + (lambda (z) + (printf "z = ~a~n" z) + (printf " zabs(z) = ~a~n" (zabs z)) + (printf " zlog(z) = ~a~n" (zlog z)) + (printf " zexp(z) = ~a~n" (zexp z)) + (printf " zsqrt(z) = ~a~n" (zsqrt z)) + (printf " zsin(z) = ~a~n" (zsin z)) + (printf " zcos(z) = ~a~n" (zcos z)) + (printf " ztan(z) = ~a~n" (ztan z)) + (printf " zasin(z) = ~a~n" (zasin z)) + (printf " zacos(z) = ~a~n" (zacos z)) + (printf " zatan(z) = ~a~n" (zatan z)))) + +(ztest 0.5) diff --git a/notes/drscheme/openbugs b/notes/drscheme/openbugs new file mode 100644 index 0000000..34e8067 --- /dev/null +++ b/notes/drscheme/openbugs @@ -0,0 +1,11 @@ +- in the language dialog box, "allow set! on undefined" is ignored + +- check syntax doesn't traverse unit or class expressions + +- check syntax: identifiers with newlines in them have their arrows + start from funny places. + +- eval'ing images in drscheme is broken + +- backup files don't preserve file permissions + diff --git a/notes/mred/COPYING.LIB b/notes/mred/COPYING.LIB new file mode 100644 index 0000000..eb685a5 --- /dev/null +++ b/notes/mred/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/notes/mred/FONTS b/notes/mred/FONTS new file mode 100644 index 0000000..c584f91 --- /dev/null +++ b/notes/mred/FONTS @@ -0,0 +1,432 @@ + +Do not read this file. If you want to change the fonts in MrEd, +use the preferences dialog instead. + +Ok, if you're still reading, you must really want to do something that +can't be done via the preferences dialog. Most likely, it *can* be +done, and this file will tell you how if you're pantient enough. + +--------------------------------------------------- + 1. Welcome to the Weird World of MrEd Fonts +--------------------------------------------------- + +MrEd's font system is designed to appear to work gracefully across +platforms to a naive MrEd user. It is also designed to provide +complete configuration control to a knowledgeable user (this may be +especially necessary under X Windows). These are somewhat +contradictory goals, and leave MrEd with a somewhat complex font +system. + +Terminology will be developed here to explain the working of the font +system, but do not expect these terms to be used by the MrEd +toolbox. The toolbox is designed to do what a programmer or user +probably wanted using names that a programmer or user would probably +understand intuitively. + +A "real font" is a device-speicific font used to draw or measure text +for a screen or a printer. MrEd handles three kinds of real fonts: + + * Screen fonts + * PostScript font names + * AFM font files + +An "abstract font" is a platform- and device-independent entity +that describes a font. MrEd uses 8 abstract fonts: + + * "Default" + * "Decorative" + * "Roman" + * "Script" + * "Swiss" + * "Modern" + * "Teletype" + * "System" + +The "System" abstract font is intended only for use with screen-based +controls. The "Teletype" abstract font is rarely used. + +There are two basic problems: + + * Mapping abstract fonts to real fonts + * Specifying a real font without a corresponding abstract font + +The solution in the latter case is simply to let the user or +programmer invent new abstract fonts. However, the new abstract font +is associated with a core abstract font so that a suitable default +real font can be selected when no information about the new abstract +font is available. + +Abstract fonts are mapped to real fonts via the low-level setup +resource file read by MrEd at startup time. (Under X Windows, X +resources can be specified in any way, but specifying X resources +through the startup file is the preferred mechanism.) + +In the case of real fonts for an X Windows screen, it is necssary to +map not only an abstract font toa real font, but an abstract font +combined with a weight, style, and size to a real font - hence, the +insane complexity of MrEd's font system. + +--------------------------- + 1. Resource Entries +--------------------------- + +First, we consider the mechanism tha maps abstract fonts to real fonts +in the case that the information is provided via resources. + +To find a font name in the resource, MrEd looks for a resource item +named by: + +