diff --git a/collects/2htdp/private/image-more.ss b/collects/2htdp/private/image-more.ss
index 4af533fb28..5068aa47e4 100644
--- a/collects/2htdp/private/image-more.ss
+++ b/collects/2htdp/private/image-more.ss
@@ -2,6 +2,7 @@
(require "../../mrlib/image-core.ss"
"img-err.ss"
+ scheme/match
scheme/contract
scheme/class
scheme/gui/base
@@ -117,7 +118,7 @@
(overlay/internal 'middle 'middle image (cons image2 image3)))
;; underlay : image image image ... -> image
-(define (underlay image image2 . image3)
+(define/chk (underlay image image2 . image3)
(let ([imgs (reverse (list* image image2 image3))])
(overlay/internal 'middle 'middle (car imgs) (cdr imgs))))
@@ -279,9 +280,10 @@
(crop/internal x1 y1 width height image))
(define (crop/internal x1 y1 width height image)
- (let ([iw (min width (get-right image))]
- [ih (min height (get-bottom image))])
- (make-image (make-crop (rectangle-points iw ih)
+ (let* ([iw (min width (get-right image))]
+ [ih (min height (get-bottom image))]
+ [points (rectangle-points iw ih)])
+ (make-image (make-crop points
(make-translate (- x1) (- y1) (image-shape image)))
(make-bb iw
ih
@@ -363,26 +365,28 @@
(- (ltrb-bottom ltrb) (ltrb-top ltrb)))
#f)))
-(define (rotate-normalized-shape angle shape)
+(define/contract (rotate-normalized-shape angle shape)
+ (-> number? normalized-shape? normalized-shape?)
(cond
[(overlay? shape)
(let ([top-shape (rotate-normalized-shape angle (overlay-top shape))]
- [bottom-shape (rotate-simple angle (overlay-bottom shape))])
+ [bottom-shape (rotate-cn-or-simple-shape angle (overlay-bottom shape))])
(make-overlay top-shape bottom-shape))]
[else
- (rotate-cropped-simple angle shape)]))
+ (rotate-cn-or-simple-shape angle shape)]))
-;; rotate-cropped-simple : angle cropped-simple-shape -> cropped-simple-shape
-(define (rotate-cropped-simple angle shape)
+(define/contract (rotate-cn-or-simple-shape angle shape)
+ (-> number? cn-or-simple-shape? cn-or-simple-shape?)
(cond
[(crop? shape)
(make-crop (rotate-points angle (crop-points shape))
- (rotate-cropped-simple angle (crop-shape shape)))]
- [else
+ (rotate-normalized-shape angle (crop-shape shape)))]
+ [else
(rotate-simple angle shape)]))
;; rotate-simple : angle simple-shape -> simple-shape
(define (rotate-simple θ simple-shape)
+ (-> number? simple-shape? simple-shape?)
(cond
[(line-segment? simple-shape)
(make-line-segment (rotate-point (line-segment-start simple-shape)
@@ -425,21 +429,21 @@
(min (ltrb-right ltrb1) (ltrb-right ltrb2))
(min (ltrb-bottom ltrb1) (ltrb-bottom ltrb2))))
-;; normalized-shape-bb : normalized-shape -> ltrb
-(define (normalized-shape-bb shape)
+(define/contract (normalized-shape-bb shape)
+ (-> normalized-shape? ltrb?)
(cond
[(overlay? shape)
(let ([top-ltrb (normalized-shape-bb (overlay-top shape))]
- [bottom-ltrb (simple-bb (overlay-bottom shape))])
+ [bottom-ltrb (cn-or-simple-shape-bb (overlay-bottom shape))])
(union-ltrb top-ltrb bottom-ltrb))]
[else
- (cropped-simple-bb shape)]))
+ (cn-or-simple-shape-bb shape)]))
-;; cropped-simple-bb : cropped-simple-shape -> ltrb
-(define (cropped-simple-bb shape)
+(define/contract (cn-or-simple-shape-bb shape)
+ (-> cn-or-simple-shape? ltrb?)
(cond
[(crop? shape)
- (let ([ltrb (cropped-simple-bb (crop-shape shape))]
+ (let ([ltrb (normalized-shape-bb (crop-shape shape))]
[crop-ltrb (points->ltrb (crop-points shape))])
(intersect-ltrb crop-ltrb ltrb))]
[else
@@ -448,7 +452,8 @@
;; simple-bb : simple-shape -> ltrb
;; returns the bounding box of 'shape'
;; (only called for rotated shapes, so bottom=baseline)
-(define (simple-bb simple-shape)
+(define/contract (simple-bb simple-shape)
+ (-> simple-shape? ltrb?)
(cond
[(line-segment? simple-shape)
(let ([x1 (point-x (line-segment-start simple-shape))]
@@ -484,6 +489,7 @@
(make-ltrb left top right bottom)))
(define (np-atomic-bb atomic-shape)
+ (-> np-atomic-shape? (values number? number? number? number?))
(cond
[(ellipse? atomic-shape)
(let ([θ (ellipse-angle atomic-shape)])
@@ -554,6 +560,7 @@
;; rotate-atomic : angle np-atomic-shape -> np-atomic-shape
(define (rotate-atomic θ atomic-shape)
+ (-> number? np-atomic-shape? np-atomic-shape?)
(cond
[(ellipse? atomic-shape)
(cond
diff --git a/collects/2htdp/private/img-err.ss b/collects/2htdp/private/img-err.ss
index 2b072c8ac7..78ed2ca40e 100644
--- a/collects/2htdp/private/img-err.ss
+++ b/collects/2htdp/private/img-err.ss
@@ -49,7 +49,7 @@
[(define/chk (fn-name args ... . final-arg) body ...)
(identifier? #'final-arg)
(let ([len (length (syntax->list #'(args ...)))])
- (with-syntax ([(i ...) (build-list len values)])
+ (with-syntax ([(i ...) (build-list len add1)])
#`(define (fn-name args ... . final-arg)
(let ([args (check/normalize 'fn-name 'args args i)] ...
[final-arg (map/i (λ (x j) (check/normalize 'fn-name 'final-arg x (+ #,len j)))
diff --git a/collects/2htdp/tests/image-equality-performance.ss b/collects/2htdp/tests/image-equality-performance.ss
new file mode 100644
index 0000000000..79960d210e
--- /dev/null
+++ b/collects/2htdp/tests/image-equality-performance.ss
@@ -0,0 +1,908 @@
+#lang scheme
+
+#|
+
+This is a file from Guillaume that ran very slowly with the
+htdp/image library; here it is used as a performance test.
+Porting to #lang scheme +2htdp/image consisted of adding requires,
+changing overlay/xy to underlay/xy, defining empty-scene, and
+adding the check-expect macro (and related code).
+Also added the timing code at the end.
+
+|#
+
+
+(require 2htdp/image
+ (only-in mrlib/image-core
+ skip-image-equality-fast-path))
+
+(define-syntax (check-expect stx)
+ (syntax-case stx ()
+ [(_ a b)
+ (with-syntax ([line (syntax-line stx)])
+ #'(set! tests (cons (list (λ () a) (λ () b) line)
+ tests)))]))
+(define tests '())
+(define (run-tests)
+ (for-each
+ (λ (l)
+ (let ([a-res ((list-ref l 0))]
+ [b-res ((list-ref l 1))]
+ [line (list-ref l 2)])
+ (unless (equal? a-res b-res)
+ (error 'test "test failed; expected ~s and ~s to be equal, but they weren't, line ~a"
+ a-res
+ b-res
+ line))))
+ tests))
+
+(define (empty-scene w h)
+ (overlay
+ (rectangle w h 'solid 'white)
+ (rectangle w h 'outline 'black)))
+
+;;Program for creating game of croos-circle game
+;;contract :image->image
+
+;;defining a union square
+;;A square is either
+;;A square is blank
+;;A square is cross
+;;A square is Circle
+
+;;defining width of square
+(define square-width 150)
+
+;;defining th height and width of scene
+(define width (* square-width 3))
+(define height (* square-width 3))
+
+
+;;defining the image circle
+(define Circle (underlay/xy (circle 20 'solid 'orange) 0 0 (circle 10 'solid 'white)))
+;;defining the image cross
+(define cross (underlay/xy (rectangle 10 30 'solid 'green) 0 0 (rectangle 30 10 'solid 'green)))
+;;defining the blank image
+(define blank (underlay/xy (rectangle square-width square-width 'solid 'red) 0 0
+ (rectangle (- square-width 8) (- square-width 8) 'solid 'white)))
+
+;;Given a square returns
+;;the image of square
+;;draw-square :square ->image
+(define (draw-square square)
+ (cond[(equal? 'Circle square)(underlay/xy blank 0 0 Circle)]
+ [(equal? 'cross square)(underlay/xy blank 0 0 cross)]
+ [(equal? 'blank square)blank]
+ ))
+
+
+;;test
+(check-expect(draw-square 'Circle)(underlay/xy blank 0 0 Circle))
+(check-expect(draw-square 'cross)(underlay/xy blank 0 0 cross))
+(check-expect(draw-square 'blank)blank)
+
+;;== Cross and circles, part #3 ==
+
+
+;;define a structure for ROW
+;;ROW structure used for creating a ROW in the board
+;;contract ROW:image image image->image
+(define-struct ROW (left middle right) #:transparent)
+
+
+;; defining a blank row
+
+(define blank-ROW (make-ROW 'blank 'blank 'blank))
+;;defining the cross row
+(define cross-ROW (make-ROW 'blank 'cross 'blank))
+
+;;defineing the cross-row-blank secoend combination
+(define cross-ROW-blank (make-ROW 'cross 'cross 'blank ))
+;;defining a row cross-row
+(define cross-row (make-ROW 'cross 'cross 'cross ))
+;;defining a row blank-circle
+(define blank-circle (make-ROW 'Circle 'blank 'blank))
+;;defining a row cross-circle
+(define cross-circle (make-ROW 'cross 'cross 'Circle ))
+;;defining a row circle-cross
+(define circle-cross (make-ROW 'cross 'Circle 'Circle ))
+;;defining a row cross-blank
+(define cross-blank (make-ROW 'cross 'blank 'blank ))
+;;function for creating ROW with the square
+;;contract:square square square->ROW
+;template: for draw-row
+;template for ROW
+;(define (a-row-function a-row)
+; ... (row-left a-row) ;; is a square
+; ... (row-mid a-row) ;; is a square
+; ... (row-right a-row)) ;; is a square
+
+
+
+(define (draw-row row)
+ (underlay/xy (draw-square(ROW-left row)) (image-width blank) 0
+ (underlay/xy (draw-square(ROW-middle row)) (image-width blank) 0 (draw-square(ROW-right row)) )))
+
+;;test
+
+(check-expect (draw-row (make-ROW 'Circle 'cross 'blank))
+ (underlay/xy (draw-square 'Circle) (image-width blank) 0
+ (underlay/xy (draw-square 'cross ) (image-width blank) 0 (draw-square 'blank) )))
+
+(check-expect (draw-row (make-ROW 'Circle 'cross 'blank))
+ (underlay/xy (draw-square 'Circle) (image-width blank) 0
+ (underlay/xy (draw-square 'cross ) (image-width blank) 0 (draw-square 'blank) )))
+
+(check-expect (draw-row (make-ROW 'Circle 'blank 'cross))
+ (underlay/xy (draw-square 'Circle) (image-width blank) 0
+ (underlay/xy (draw-square 'blank ) (image-width blank) 0 (draw-square 'cross) )))
+
+(check-expect (draw-row cross-ROW-blank)
+ (underlay/xy (draw-square 'cross) (image-width blank) 0
+ (underlay/xy (draw-square 'cross ) (image-width blank) 0 (draw-square 'blank) )))
+
+(check-expect (draw-row cross-row )
+ (underlay/xy (draw-square 'cross) (image-width blank) 0
+ (underlay/xy (draw-square 'cross ) (image-width blank) 0 (draw-square 'cross) )))
+
+;;define a structure for BOARD
+;;contract make-BOARD :image image image->image
+(define-struct BOARD (top-row center-row bottom-row) #:transparent)
+
+;; purpose : defining an empty board
+(define empty-board (make-BOARD blank-ROW
+ blank-ROW
+ blank-ROW))
+
+;;function for creating board with the row
+
+;template: for draw-board
+;(define (a-board-function a-row)
+; ... (top-row a-row) ;; is a square
+; ... (center-row a-row) ;; is a square
+; ... (bottom-row a-row)) ;; is a square
+
+;;defining the background
+(define background (empty-scene width height))
+
+
+;;this function will reusing the fuction draw-row for creating row
+;;contract:row row row->board
+
+;;test
+(check-expect (draw-board (make-BOARD cross-ROW-blank
+ cross-ROW
+ cross-row ))
+ (underlay/xy (draw-row cross-ROW-blank)
+ 0 (image-height (draw-row cross-ROW))
+ (underlay/xy (draw-row cross-ROW)
+ 0 (image-height (draw-row cross-ROW))
+ (draw-row cross-row ))))
+
+(check-expect (draw-board (make-BOARD cross-circle
+ (make-ROW 'Circle 'cross 'blank)
+ circle-cross))
+ (underlay/xy (draw-row cross-circle)
+ 0 (image-height (draw-row cross-circle))
+ (underlay/xy (draw-row (make-ROW 'Circle 'cross 'blank))
+ 0 (image-height (draw-row(make-ROW 'Circle 'cross 'blank)))
+ (draw-row circle-cross))))
+
+(check-expect(draw-board (make-BOARD cross-circle
+ (make-ROW 'Circle 'cross 'Circle)
+ circle-cross))
+ (underlay/xy (draw-row cross-circle)
+ 0 (image-height (draw-row cross-circle))
+ (underlay/xy (draw-row (make-ROW 'Circle 'cross 'Circle))
+ 0 (image-height (draw-row (make-ROW 'Circle 'cross 'Circle)))
+ (draw-row circle-cross))))
+
+(check-expect (draw-board (make-BOARD (make-ROW 'blank 'cross 'Circle)
+ (make-ROW 'Circle 'cross 'cross)
+ circle-cross))
+ (underlay/xy (draw-row (make-ROW 'blank 'cross 'Circle))
+ 0 (image-height (draw-row (make-ROW 'blank 'cross 'Circle)))
+ (underlay/xy (draw-row (make-ROW 'Circle 'cross 'cross))
+ 0 (image-height (draw-row (make-ROW 'Circle 'cross 'cross)))
+ (draw-row circle-cross))) )
+
+(check-expect (draw-board (make-BOARD (make-ROW 'blank 'cross 'Circle)
+ (make-ROW 'Circle 'blank 'cross)
+ (make-ROW 'cross 'blank 'Circle)))
+ (underlay/xy (draw-row (make-ROW 'blank 'cross 'Circle))
+ 0 (image-height (draw-row (make-ROW 'blank 'cross 'Circle)))
+ (underlay/xy (draw-row (make-ROW 'Circle 'blank 'cross))
+ 0 (image-height (draw-row (make-ROW 'Circle 'blank 'cross)))
+ (draw-row (make-ROW 'cross 'blank 'Circle)))))
+
+
+
+
+(define (draw-board board)
+ (underlay/xy (draw-row (BOARD-top-row board))
+ 0 (image-height (draw-row (BOARD-top-row board)))
+ (underlay/xy (draw-row (BOARD-center-row board))
+ 0 (image-height (draw-row(BOARD-center-row board)))
+ (draw-row (BOARD-bottom-row board)))))
+
+;;purpose: given the x coordinate of the mouse click and returns
+;;the symbol 'L, the symbol 'M, or the symbol 'R,
+;;depending on whether that X position falls on the right, the middle or the left of the board.
+;;contract: which-column:: number -> symbol
+
+;;test
+
+(check-expect (which-column (* square-width .5)) 'L)
+(check-expect (which-column (* square-width 1.5)) 'M)
+(check-expect (which-column (* square-width 2.3)) 'R)
+
+(define (which-column x-pos)
+ (cond[(and (>= x-pos 0)(<= x-pos square-width))'L]
+ [(and (>= x-pos (+ square-width 1))(<= x-pos (* 2 square-width)))'M]
+ [(and (>= x-pos (+ (* 2 square-width) 1))(<= x-pos (* 3 square-width)))'R]
+ [else "play in the board,you played outside the square"]))
+
+
+
+;;purpose: given the y coordinate of the mouse click and returns
+;;the symbol 'T, the symbol 'C, or the symbol 'B,
+;;depending on whether that Y position falls on the top, the center or the bottom of the board.
+;;contract: which-row:: number -> symbol
+
+;;test
+
+(check-expect (which-row (* square-width .6)) 'T)
+(check-expect (which-row (* square-width 1.3)) 'C)
+(check-expect (which-row (* square-width 2.7)) 'B)
+
+(define (which-row y-pos)
+ (cond[(and (>= y-pos 0)(<= y-pos square-width))'T]
+ [(and (>= y-pos (+ square-width 1))(<= y-pos (* 2 square-width)))'C]
+ [(and (>= y-pos (+ (* 2 square-width) 1))(<= y-pos (* 3 square-width)))'B]
+ [else "play in the board,you played outside the square"]))
+
+
+
+;;purpose: give the row and the square to be played and returns a new row replacing the left square
+;; play-on-left : row square ->row
+
+;;test
+(check-expect (play-on-left (make-ROW 'blank 'cross 'Circle) 'Circle)
+ (make-ROW 'Circle 'cross 'Circle))
+
+(check-expect (play-on-left (make-ROW 'blank 'cross 'Circle) 'cross)
+ cross-circle)
+
+(check-expect (play-on-left cross-ROW 'Circle)
+ (make-ROW 'Circle 'cross 'blank))
+(define (play-on-left row play)
+ (make-ROW play (ROW-middle row) (ROW-right row)))
+
+
+;;purpose: give the row and the square to be played and returns a new row replacing the middle square
+;; play-on-middle : row square ->row
+
+;;test
+(check-expect (play-on-middle (make-ROW 'blank 'blank 'Circle) 'Circle)
+ (make-ROW 'blank 'Circle 'Circle))
+
+(check-expect (play-on-middle (make-ROW 'blank 'blank 'Circle) 'cross)
+ (make-ROW 'blank 'cross 'Circle))
+
+(check-expect (play-on-middle blank-ROW 'Circle)
+ (make-ROW 'blank 'Circle 'blank))
+
+(define (play-on-middle row play)
+ (make-ROW (ROW-left row) play (ROW-right row)))
+
+
+;;purpose: give the row and the square to be played and returns a new row replacing the right square
+;; play-on-right : row square ->row
+
+;;test
+(check-expect (play-on-right blank-ROW 'Circle)
+ (make-ROW 'blank 'blank 'Circle))
+
+(check-expect (play-on-right (make-ROW 'blank 'Circle 'blank) 'cross)
+ (make-ROW 'blank 'Circle 'cross))
+
+(check-expect (play-on-right blank-ROW 'Circle)
+ (make-ROW 'blank 'blank 'Circle))
+
+(define (play-on-right row play)
+ (make-ROW (ROW-left row) (ROW-middle row) play ))
+
+;;purpose : given the row, which column ,square to be played returns new row replacing the column
+;; play-on-row : row square symbol -> row
+
+(check-expect (play-on-row blank-ROW 'L 'Circle)
+ (make-ROW 'Circle 'blank 'blank))
+(check-expect (play-on-row blank-ROW 'M 'Circle)
+ (make-ROW 'blank 'Circle 'blank))
+(check-expect (play-on-row blank-ROW 'R 'Circle)
+ (make-ROW 'blank 'blank 'Circle))
+
+(define (play-on-row row column-label play)
+ (cond [(equal? column-label 'L) (make-ROW play (ROW-middle row) (ROW-right row))]
+ [(equal? column-label 'M) (make-ROW (ROW-left row) play (ROW-right row))]
+ [(equal? column-label 'R) (make-ROW (ROW-left row) (ROW-middle row) play)]
+ [else row]))
+
+;;purpose given a board, a square to be played and the label of the position to be played
+;;returns a new board with the square to be played at the labeled position on the top row
+
+;; play-on-board-at-top : board square symbol -> board
+;;test
+(check-expect (play-on-board-at-top empty-board 'Circle 'L)
+ (make-BOARD (make-ROW 'Circle 'blank 'blank)
+ blank-ROW
+ blank-ROW))
+
+
+(check-expect (play-on-board-at-top empty-board 'Circle 'M)
+ (make-BOARD (make-ROW 'blank 'Circle 'blank)
+ blank-ROW
+ blank-ROW))
+
+
+(check-expect (play-on-board-at-top empty-board 'cross 'R)
+ (make-BOARD (make-ROW 'blank 'blank 'cross)
+ blank-ROW
+ blank-ROW))
+
+
+(define (play-on-board-at-top board play column-label)
+ (make-BOARD(play-on-row (BOARD-top-row board) column-label play)
+ (BOARD-center-row board)(BOARD-bottom-row board))
+ )
+
+
+
+;;purpose given a board, a square to be played and the label of the position to be played
+;;returns a new board with the square to be played at the labeled position on the middle row
+
+;; play-on-board-at-top : board square symbol -> board
+;;test
+(check-expect (play-on-board-at-middle empty-board 'Circle 'L)
+ (make-BOARD blank-ROW
+ (make-ROW 'Circle 'blank 'blank)
+ blank-ROW))
+
+
+(check-expect (play-on-board-at-middle empty-board 'Circle 'M)
+ (make-BOARD blank-ROW
+ (make-ROW 'blank 'Circle 'blank)
+ blank-ROW))
+
+
+(check-expect (play-on-board-at-middle empty-board 'cross 'R)
+ (make-BOARD blank-ROW
+ (make-ROW 'blank 'blank 'cross)
+ blank-ROW))
+
+
+(define (play-on-board-at-middle board play column-label)
+ (make-BOARD (BOARD-top-row board) (play-on-row (BOARD-center-row board) column-label play)
+ (BOARD-bottom-row board))
+ )
+;;purpose given a board, a square to be played and the label of the position to be played
+;;returns a new board with the square to be played at the labeled position on the bottom row
+
+;; play-on-board-at-top : board square symbol -> board
+;;test
+(check-expect (play-on-board-at-bottom empty-board 'Circle 'L)
+ (make-BOARD blank-ROW
+ blank-ROW
+ (make-ROW 'Circle 'blank 'blank)))
+
+
+(check-expect (play-on-board-at-bottom empty-board 'Circle 'M)
+ (make-BOARD blank-ROW
+ blank-ROW
+ (make-ROW 'blank 'Circle 'blank)))
+
+
+(check-expect (play-on-board-at-bottom empty-board 'cross 'R)
+ (make-BOARD blank-ROW
+ blank-ROW
+ (make-ROW 'blank 'blank 'cross)))
+
+
+(define (play-on-board-at-bottom board play column-label)
+ (make-BOARD (BOARD-top-row board) (BOARD-center-row board)
+ (play-on-row (BOARD-bottom-row board) column-label play)
+ )
+ )
+
+
+;;purpose :given the board ,square to be played,column and row label and returns a new board
+;;with the square to be played at the position reffered
+;; play-on-board : board square symbol symbol -> board
+
+;;test
+(check-expect (play-on-board empty-board 'cross 'R 'T)
+ (make-BOARD (make-ROW 'blank 'blank 'cross )
+ blank-ROW
+ blank-ROW))
+
+
+(check-expect (play-on-board empty-board 'cross 'L 'C)
+ (make-BOARD blank-ROW
+ cross-blank
+ blank-ROW))
+
+
+(check-expect (play-on-board empty-board 'cross 'M 'B)
+ (make-BOARD blank-ROW
+ blank-ROW
+ cross-ROW))
+
+
+(define (play-on-board board play column-label row-label)
+ (cond [(equal? row-label 'T) (play-on-board-at-top board play column-label)]
+ [(equal? row-label 'C) (play-on-board-at-middle board play column-label)]
+ [(equal? row-label 'B) (play-on-board-at-bottom board play column-label)]
+ [else board]))
+
+
+;;purpose : Given a board structure, a return the image of that board centered on the scene.
+;;create-board:board->scene
+
+;;test
+(check-expect (create-board (make-BOARD blank-ROW
+ blank-ROW
+ cross-ROW))
+ (place-image (draw-board (make-BOARD blank-ROW
+ blank-ROW
+ cross-ROW))
+ (/ square-width 2)(/ square-width 2) background))
+
+(check-expect (create-board (make-BOARD (make-ROW 'Circle 'cross 'Circle)
+ blank-ROW
+ cross-ROW))
+ (place-image (draw-board (make-BOARD (make-ROW 'Circle 'cross 'Circle)
+ blank-ROW
+ cross-ROW))
+ (/ square-width 2)(/ square-width 2) background))
+
+(check-expect (create-board (make-BOARD (make-ROW 'Circle 'cross 'blank)
+ blank-ROW
+ cross-ROW))
+ (place-image (draw-board (make-BOARD (make-ROW 'Circle 'cross 'blank)
+ blank-ROW
+ cross-ROW))
+ (/ square-width 2)(/ square-width 2) background))
+
+(define (create-board board)
+ (place-image (draw-board board)(/ square-width 2)(/ square-width 2) background)
+ )
+
+;; clack1 : Mouse handler. Plays a cross (always a cross) where the mouse is clicked, on button-up.
+;; clack1 : board number number symbol -> board
+
+(define (clack1 board x y event)
+ (cond [(symbol=? event 'button-up)
+ (play-on-board board 'cross (which-column x) (which-row y))]
+ [else board]))
+
+(check-expect (clack1 (make-BOARD blank-ROW
+ blank-ROW
+ cross-ROW) 40 68 'button-up)
+ (make-BOARD cross-blank
+ blank-ROW
+ cross-ROW))
+
+(check-expect (clack1 (make-BOARD blank-ROW
+ blank-ROW
+ cross-ROW) 160 168 'button-up)
+ (make-BOARD blank-ROW
+ (make-ROW 'blank 'cross 'blank)
+ cross-ROW))
+
+(check-expect (clack1 (make-BOARD blank-ROW
+ blank-ROW
+ blank-ROW) 310 365 'button-up)
+ (make-BOARD blank-ROW
+ blank-ROW
+ (make-ROW 'blank 'blank 'cross)
+ ))
+;; purpose : Given the current player, return which player goes next.
+;; other-player : square -> square
+
+(define (other-player play)
+ (cond [(equal? play 'Circle) 'cross]
+ [(equal? play 'cross) 'Circle]))
+
+(check-expect (other-player 'cross) 'Circle)
+(check-expect (other-player 'Circle) 'cross)
+
+;; purpose : Given a horz. pos (either 'L, 'M or 'R), finds the content of that square.
+;; lookup-square : row symbol -> square
+
+(define (lookup-square column-label row)
+ (cond [(equal? column-label 'L)(ROW-left row)]
+ [(equal? column-label 'M)(ROW-middle row)]
+ [(equal? column-label 'R)(ROW-right row)]))
+
+(check-expect(lookup-square 'L (make-ROW 'blank 'Circle 'cross)) 'blank)
+(check-expect(lookup-square 'M (make-ROW 'blank 'Circle 'cross)) 'Circle)
+(check-expect(lookup-square 'R (make-ROW 'blank 'Circle 'cross)) 'cross)
+
+;; lookup-row : Given a vert. pos (either 'T, 'C or 'B), finds that row.
+;; lookup-row : board symbol -> row
+
+(define(lookup-row row-label board)
+ (cond [(equal? row-label 'T)(BOARD-top-row board)]
+ [(equal? row-label 'C)(BOARD-center-row board)]
+ [(equal? row-label 'B)(BOARD-bottom-row board)]))
+
+
+(check-expect(lookup-row 'T (make-BOARD (make-ROW 'cross 'blank 'Circle)
+ blank-ROW
+ blank-ROW)) (make-ROW 'cross 'blank 'Circle))
+
+(check-expect(lookup-row 'C (make-BOARD blank-ROW
+ (make-ROW 'cross 'blank 'Circle)
+ blank-ROW)) (make-ROW 'cross 'blank 'Circle))
+
+(check-expect(lookup-row 'B (make-BOARD blank-ROW
+ blank-ROW
+ (make-ROW 'cross 'blank 'Circle)
+ )) (make-ROW 'cross 'blank 'Circle))
+
+;; lookup : Given a horz. and a vert. pos, finds that square.
+;; lookup : board symbol symbol -> square
+
+(define (lookup board column-label row-label)
+ (lookup-square column-label (lookup-row row-label board)))
+
+(check-expect(lookup(make-BOARD (make-ROW 'cross 'blank 'Circle)
+ blank-ROW
+ blank-ROW) 'L 'T) 'cross)
+
+(check-expect(lookup(make-BOARD blank-ROW
+ (make-ROW 'cross 'blank 'Circle)
+ blank-ROW) 'M 'C) 'blank)
+
+(check-expect(lookup(make-BOARD blank-ROW
+ blank-ROW
+ (make-ROW 'cross 'blank 'Circle)
+ ) 'R 'B) 'Circle)
+
+
+;; move-legal? : Return true if the square at horizondal and vertical position is blank.
+;; move-legal? : board symbol symbol -> boolean
+
+(define(move-legal? board column-label row-label)
+ (equal? (lookup board column-label row-label) 'blank))
+
+(check-expect (move-legal? empty-board 'L 'C) true)
+(check-expect (move-legal? (make-BOARD blank-ROW
+ (make-ROW 'Circle 'cross cross)
+ blank-ROW)
+ 'M 'C) false)
+;;define a structure for game
+;;contract make-game :square board number->game
+(define-struct GAME (next-player board move-count) #:transparent)
+
+;;defining the initial-game
+(define initial-game (make-GAME 'cross empty-board 0))
+
+;;purpose: Given a game and a horz. and vert. position, the next player plays in that square, if legal. The move-count goes up by 1,and the next-player switches hand.
+;; play-on-game : game symbol symbol -> game
+
+(check-expect(play-on-game initial-game 'L 'T)
+ (make-GAME 'Circle
+ (make-BOARD cross-blank blank-ROW blank-ROW) 1))
+
+(check-expect(play-on-game (make-GAME 'Circle
+ (make-BOARD cross-blank blank-ROW blank-ROW) 1)
+ 'M 'C )
+ (make-GAME 'cross
+ (make-BOARD cross-blank
+ (make-ROW 'blank 'Circle 'blank)
+ blank-ROW) 2))
+(check-expect(play-on-game(make-GAME 'cross
+ (make-BOARD cross-blank
+ (make-ROW 'blank 'Circle 'blank)
+ blank-ROW) 2)
+ 'R 'B)
+ (make-GAME 'Circle
+ (make-BOARD cross-blank
+ (make-ROW 'blank 'Circle 'blank)
+ (make-ROW 'blank 'blank 'cross)) 3))
+
+(define (play-on-game game column-label row-label)
+ (cond [ (move-legal? (GAME-board game) column-label row-label)
+ (make-GAME (other-player (GAME-next-player game))
+ (play-on-board (GAME-board game) (GAME-next-player game) column-label row-label)
+ (+ (GAME-move-count game) 1))]
+ [else game]))
+
+;; game-over? : Returns true when the game is over.
+;; game-over? : game -> boolean
+(check-expect (game-over? (make-GAME 'Circle (make-BOARD cross-blank
+ (make-ROW 'blank 'Circle 'blank)
+ (make-ROW 'blank 'blank 'cross))3)) false)
+(check-expect (game-over? (make-GAME 'Circle (make-BOARD cross-ROW-blank
+ (make-ROW 'blank 'Circle 'blank)
+ (make-ROW 'blank 'blank 'cross))3)) false)
+(check-expect (game-over? (make-GAME 'Circle (make-BOARD cross-circle
+ (make-ROW 'cross 'Circle 'cross)
+ (make-ROW 'Circle 'cross 'Circle))9))true)
+(define (game-over? game)
+ (>= (GAME-move-count game) 9))
+
+
+
+;; clack2 : Mouse handler. Plays the game on button-up.
+;; clack2 : game number number symbol -> game
+
+(check-expect (clack2 initial-game 90 90 'button-up)
+ (make-GAME 'Circle
+ (make-BOARD cross-blank blank-ROW blank-ROW) 1))
+
+(check-expect (clack2 (make-GAME 'Circle
+ (make-BOARD cross-blank blank-ROW blank-ROW) 1)
+ 160 160 'button-up)
+ (make-GAME 'cross
+ (make-BOARD cross-blank
+ (make-ROW 'blank 'Circle 'blank)
+ blank-ROW) 2))
+
+(check-expect (clack2 (make-GAME 'cross
+ (make-BOARD cross-blank
+ (make-ROW 'blank 'Circle 'blank)
+ blank-ROW) 2)310 310 'button-up)
+ (make-GAME 'Circle (make-BOARD cross-blank
+ (make-ROW 'blank 'Circle 'blank)
+ (make-ROW 'blank 'blank 'cross)) 3))
+
+
+(define (clack2 game x y event)
+ (cond [(symbol=? event 'button-up)
+ (play-on-game game (which-column x) (which-row y))]
+ [else game]))
+
+;; game->scene : Draws a game
+;; game->scene : game -> scene
+
+(check-expect (game->scene (make-GAME 'Circle
+ (make-BOARD cross-blank blank-ROW blank-ROW) 1))
+ (place-image (draw-board (make-BOARD cross-blank blank-ROW blank-ROW))
+ (/ square-width 2)(/ square-width 2) background))
+
+
+(check-expect (game->scene (make-GAME 'cross
+ (make-BOARD (make-ROW 'cross 'blank 'Circle) blank-ROW blank-ROW) 1))
+ (place-image (draw-board (make-BOARD (make-ROW 'cross 'blank 'Circle) blank-ROW blank-ROW))
+ (/ square-width 2)(/ square-width 2) background))
+
+(define (game->scene game)
+ (place-image (draw-board (GAME-board game)) (/ square-width 2)(/ square-width 2) background)
+ )
+
+
+;; winning-triple? : Return true if a, b, and c are all the same symbol as player.
+;; winning-triple? : symbol symbol symbol symbol -> boolean
+
+(check-expect (winning-triple? 'cross 'cross 'cross 'cross)true)
+(check-expect (winning-triple? 'Circle 'Circle 'blank 'cross)false)
+(check-expect (winning-triple? 'Circle 'Circle 'Circle 'Circle)true)
+(check-expect (winning-triple? 'cross 'blank 'cross 'cross)false)
+
+
+(define (winning-triple? player a b c)
+ (and(and (equal? player a)(equal? player b))(equal? player c)))
+
+
+;; winning-row? : Returns true if the indicated row is a win for the given player.
+;; winning-row? : board square symbol -> boolean
+
+(check-expect (winning-row? (make-BOARD cross-row
+ circle-cross
+ (make-ROW 'Circle 'blank 'blank))
+ 'cross 'T)true)
+
+
+
+(check-expect (winning-row? (make-BOARD (make-ROW 'cross 'blank 'Circle)
+ circle-cross
+ (make-ROW 'blank 'cross 'blank))
+ 'Circle 'C)false)
+
+
+
+(check-expect (winning-row? (make-BOARD (make-ROW 'cross 'Circle 'blank )
+ (make-ROW 'cross 'Circle 'cross)
+ (make-ROW 'Circle 'Circle 'Circle))
+ 'Circle 'B)true)
+
+(define (winning-row? board player vertical-pos)
+ (cond[(equal? vertical-pos 'T)(winning-triple? player (ROW-left (BOARD-top-row board))
+ (ROW-middle (BOARD-top-row board))
+ (ROW-right (BOARD-top-row board)))]
+ [(equal? vertical-pos 'C)(winning-triple? player (ROW-left (BOARD-center-row board))
+ (ROW-middle (BOARD-center-row board))
+ (ROW-right (BOARD-center-row board)))]
+ [(equal? vertical-pos 'B)(winning-triple? player (ROW-left (BOARD-bottom-row board))
+ (ROW-middle (BOARD-bottom-row board))
+ (ROW-right (BOARD-bottom-row board)))]
+ [else false]
+ ))
+
+
+;; winning-column? : Return true if the indicated column is a win for the given player.
+;; winnnig-column? : board square symbol -> boolean
+
+
+(check-expect (winning-column? (make-BOARD cross-ROW-blank
+ circle-cross
+ cross-blank)
+ 'cross 'L)true)
+
+
+
+(check-expect (winning-column? (make-BOARD circle-cross
+ circle-cross
+ (make-ROW 'blank 'Circle 'blank))
+ 'Circle 'M)true)
+
+
+
+(check-expect (winning-column? (make-BOARD circle-cross
+ (make-ROW 'cross 'blank 'Circle)
+ (make-ROW 'Circle 'Circle 'Circle))
+ 'Circle 'R)true)
+
+(check-expect (winning-column? (make-BOARD circle-cross
+ cross-blank
+ (make-ROW 'Circle 'Circle 'Circle))
+ 'Circle 'R)false)
+
+
+(define (winning-column? board player horizontal-pos)
+ (cond[(equal? horizontal-pos 'L)(winning-triple? player (ROW-left (BOARD-top-row board))
+ (ROW-left (BOARD-center-row board))
+ (ROW-left (BOARD-bottom-row board)))]
+ [(equal? horizontal-pos 'M)(winning-triple? player (ROW-middle (BOARD-top-row board))
+ (ROW-middle (BOARD-center-row board))
+ (ROW-middle (BOARD-bottom-row board)))]
+ [(equal? horizontal-pos 'R)(winning-triple? player (ROW-right (BOARD-top-row board))
+ (ROW-right (BOARD-center-row board))
+ (ROW-right (BOARD-bottom-row board)))]
+ [else false]
+ ))
+
+
+
+;; winning-down-diagonal? : Return true if the top-left to bottom-right diagonal is a win.
+;; winning-down-diagonal? : board square -> boolean
+
+
+
+
+(check-expect (winning-down-diagonal?(make-BOARD (make-ROW 'Circle 'Circle 'Circle)
+ (make-ROW 'cross 'Circle 'blank)
+ (make-ROW 'cross 'blank 'Circle))
+ 'Circle)true)
+
+(check-expect (winning-down-diagonal?(make-BOARD circle-cross
+ cross-blank
+ (make-ROW 'Circle 'blank 'Circle))
+ 'Circle)false)
+(check-expect (winning-down-diagonal?(make-BOARD (make-ROW 'cross 'blank 'cross )
+ (make-ROW 'Circle 'cross 'blank)
+ (make-ROW 'blank 'Circle 'cross))
+ 'cross)true)
+
+
+(define (winning-down-diagonal? board player)
+ (and (equal? player (ROW-right (BOARD-bottom-row board))) (and (equal? player(ROW-middle (BOARD-center-row board)))
+ (equal? player (ROW-left (BOARD-top-row board))))))
+
+
+;; winning-up-diagonal? : Return true if the bottom-left to top-right diagonal is a win.
+;; winning-up-diagonal? : board square -> boolean
+
+(check-expect (winning-up-diagonal?(make-BOARD circle-cross
+ (make-ROW 'cross 'Circle 'blank)
+ (make-ROW 'Circle 'blank 'Circle))
+ 'Circle)true)
+
+(check-expect (winning-up-diagonal?(make-BOARD circle-cross
+ cross-blank
+ (make-ROW 'Circle 'blank 'Circle))
+ 'Circle)false)
+(check-expect (winning-up-diagonal?(make-BOARD (make-ROW 'cross 'blank 'cross )
+ (make-ROW 'Circle 'cross 'blank)
+ (make-ROW 'cross 'blank 'Circle))
+ 'cross)true)
+
+
+(define (winning-up-diagonal? board player)
+ (and (equal? player (ROW-left (BOARD-bottom-row board))) (and (equal? player(ROW-middle (BOARD-center-row board)))
+ (equal? player (ROW-right (BOARD-top-row board))))))
+
+;; winning-board? : Returns true if the given board is a win for the given player.
+;; winning-board? : board square -> boolean
+
+(check-expect (winning-board? (make-BOARD cross-row
+ circle-cross
+ blank-circle)
+ 'cross)true)
+
+(check-expect (winning-board? (make-BOARD circle-cross
+ cross-row
+ blank-circle)
+ 'cross)true)
+(check-expect (winning-board? (make-BOARD circle-cross
+ blank-circle
+ cross-row )
+ 'cross)true)
+
+(check-expect (winning-board? (make-BOARD (make-ROW 'Circle 'cross 'cross)
+ (make-ROW 'Circle 'cross 'Circle)
+ blank-circle)
+ 'Circle)true)
+(check-expect (winning-board? (make-BOARD (make-ROW 'cross 'Circle 'cross)
+ circle-cross
+ (make-ROW 'Circle 'Circle 'blank))
+ 'Circle)true)
+(check-expect (winning-board? (make-BOARD cross-circle
+ circle-cross
+ (make-ROW 'Circle 'blank 'Circle))
+ 'Circle)true)
+
+(check-expect (winning-board? (make-BOARD cross-circle
+ circle-cross
+ blank-circle)
+ 'Circle)true)
+(check-expect (winning-board? (make-BOARD (make-ROW 'cross 'Circle 'cross)
+ cross-circle
+ (make-ROW 'Circle 'blank 'cross))
+ 'cross)true)
+
+(define (winning-board? board player)
+ (or (winning-up-diagonal? board player)
+ (or (winning-down-diagonal? board player)
+ (or (winning-row? board player 'T)
+ (or (winning-row? board player 'C)
+ (or (winning-row? board player 'B)
+ (or (winning-column? board player 'L)
+ (or (winning-column? board player 'M)
+ (winning-column? board player 'R)))))))))
+
+
+
+;; game-over-or-win? : Returns true when the game is over either because the board is full,
+;; or because someone won.
+;; game-over-or-win? : game -> boolean
+
+(check-expect (game-over-or-win? (make-GAME 'Circle
+ (make-BOARD (make-ROW 'cross 'blank 'Circle) blank-ROW blank-ROW) 3))false)
+
+
+(check-expect (game-over-or-win? (make-GAME 'Circle
+ (make-BOARD (make-ROW 'cross 'blank 'Circle)
+ (make-ROW 'blank 'cross 'Circle)
+ (make-ROW 'cross 'blank 'Circle))7))true)
+
+
+(check-expect (game-over-or-win? (make-GAME 'cross
+ (make-BOARD cross-circle
+ (make-ROW 'Circle 'cross 'Circle)
+ (make-ROW 'cross 'Circle 'cross))9))
+ true)
+
+(define (game-over-or-win? game)
+ (or (winning-board? (GAME-board game) (GAME-next-player game))
+ (game-over? game)))
+
+
+(collect-garbage) (collect-garbage) (collect-garbage)
+(printf "running tests with fast path optimization in place\n")
+(time (run-tests))
+(printf "running tests without fast path optimization in place\n")
+(parameterize ([skip-image-equality-fast-path #t])
+ (time (run-tests)))
diff --git a/collects/2htdp/tests/test-image.ss b/collects/2htdp/tests/test-image.ss
index ca20179c10..2372d1a0ec 100644
--- a/collects/2htdp/tests/test-image.ss
+++ b/collects/2htdp/tests/test-image.ss
@@ -32,7 +32,9 @@
make-ellipse
make-polygon
make-point
- make-crop )
+ make-crop
+ crop?
+ normalized-shape?)
(only-in "../private/image-more.ss"
bring-between
swizzle)
@@ -1319,6 +1321,37 @@
2 7
(circle 4 'solid 'black)))
+;; this test case checks to make sure the number of crops doesn't
+;; grow when normalizing shapes.
+(let* ([an-image
+ (crop
+ 0 0 50 50
+ (crop
+ 0 10 60 60
+ (crop
+ 10 0 60 60
+ (overlay
+ (overlay
+ (ellipse 20 50 'solid 'red)
+ (ellipse 30 40 'solid 'black))
+ (overlay
+ (ellipse 20 50 'solid 'red)
+ (ellipse 30 40 'solid 'black))))))]
+ [an-image+crop
+ (crop 40 40 10 10 an-image)])
+
+ (define (count-crops s)
+ (define crops 0)
+ (let loop ([s s])
+ (when (crop? s)
+ (set! crops (+ crops 1)))
+ (when (struct? s)
+ (for-each loop (vector->list (struct->vector s)))))
+ crops)
+
+ (test (+ (count-crops (normalize-shape (image-shape an-image))) 1)
+ =>
+ (count-crops (normalize-shape (image-shape an-image+crop)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
@@ -1458,3 +1491,71 @@
#rx"^polygon: expected The pages linked below show some benchmark results on a collection of fairly standard
- (mostly Gabriel) Scheme benchmarks. The benchmark results page shows some
+ benchmark results on a collection of fairly standard (mostly
+ Gabriel) Scheme benchmarks. Tables show relative performance, with the actual time for the fastest
- run shown on the left. So, by default, 1
- is the fastest, but select any implementation to normalize the table with
- respect to that implementation's speed. A -- appears when a benchmark
- didn't run in an implementation (and you should assume a benchmark problem,
- rather than an implementation problem). Tables show relative performance, with the actual time for the
+ fastest run shown on the left. So, by
+ default, 1 is the fastest,
+ but select any implementation to normalize the table with respect
+ to that implementation's speed. A - appears when a
+ benchmark didn't run in an implementation for some reason (possibly
+ not a good one). Small gray numbers are (relative) compile times.
+The compilers-only page shows
+just the compilers among the tested implementations. For those
+results, the small gray numbers are (relative) compile times, where
+the compile time for the nothing benchmark is subtracted from
+every other benchmark's compile time. Run times are averaged over three runs. All reported times are CPU time (system plus user).
- Where available, the times are based on the output of the implementation's time
- syntactic form, otherwise /usr/bin/time is used. Run times are averaged over three runs for compilers or one run for
+ interpreters. All reported times are CPU time (system plus user).
+ The times are based on the output of the
+ implementation's time syntactic form or similar
+ functions. Compiler configuration:
+ Machine:
About the Benchmarks
-
-
Compiler configurations: +
In general, we attempt to use the various implementations in a compentent way, but not in a sophisticated way. For example, we do not tweak inlining parameters or specify fixnum arithmetic (where appropriate), which could produce significant improvements from some compilers.
-For a larger set of benchmarks and a more sophisticated use of the compilers, - see Marc Feeley's page: - http://www.iro.umontreal.ca/~gambit/bench.html. +
For more benchmarks and a more sophisticated use of a few compilers, + including fixnum- and flonum-specific arithmetic as well as unsafe modes, + see Gambit benchmark results.
For further details on the benchmarks here, see the benchmark source and infrastructure, which is available form the PLT SVN repository:
@@ -50,8 +69,3 @@ R6RS library (we expect).http://svn.plt-scheme.org/plt/trunk/collects/tests/mzscheme/benchmarks/common/
-< 0) || (x
>= THISOBJECT->Number())) { READY_TO_RETURN; return .scheme_void]
+
+@MACRO RANGEXRET[p.rv] = if ((x < -1) || (x >= THISOBJECT->Number())) { READY_TO_RETURN; return .scheme_void]
diff --git a/src/mred/wxs/wxs_chce.cxx b/src/mred/wxs/wxs_chce.cxx
index 227a37a41c..519baf1cc6 100644
--- a/src/mred/wxs/wxs_chce.cxx
+++ b/src/mred/wxs/wxs_chce.cxx
@@ -251,6 +251,7 @@ static l_TYPE l_POINT *l_MAKE_ARRAY(Scheme_Object *l, l_INTTYPE *c, char *who)
+
class os_wxChoice : public wxChoice {
public:
Scheme_Object *callback_closure;
diff --git a/src/mred/wxs/wxs_lbox.cxx b/src/mred/wxs/wxs_lbox.cxx
index 9b407808c6..915aae2844 100644
--- a/src/mred/wxs/wxs_lbox.cxx
+++ b/src/mred/wxs/wxs_lbox.cxx
@@ -289,6 +289,7 @@ static l_TYPE l_POINT *l_MAKE_ARRAY(Scheme_Object *l, l_INTTYPE *c, char *who)
+
class os_wxListBox : public wxListBox {
public:
Scheme_Object *callback_closure;
diff --git a/src/mred/wxs/wxs_rado.cxx b/src/mred/wxs/wxs_rado.cxx
index 10816ea348..50d6ceb8cc 100644
--- a/src/mred/wxs/wxs_rado.cxx
+++ b/src/mred/wxs/wxs_rado.cxx
@@ -345,6 +345,7 @@ static l_TYPE l_POINT *l_MAKE_ARRAY(Scheme_Object *l, l_INTTYPE *c, char *who)
+
class os_wxRadioBox : public wxRadioBox {
public:
Scheme_Object *callback_closure;
@@ -706,7 +707,7 @@ static Scheme_Object *os_wxRadioBoxSetSelection(int n, Scheme_Object *p[])
x0 = WITH_VAR_STACK(objscheme_unbundle_integer(p[POFFSET+0], "set-selection in radio-box%"));
- if ((x0 < 0) || (x0 >= THISOBJECT->Number())) { READY_TO_RETURN; return scheme_void; }
+ if ((x0 < -1) || (x0 >= THISOBJECT->Number())) { READY_TO_RETURN; return scheme_void; }
WITH_VAR_STACK(((wxRadioBox *)((Scheme_Class_Object *)p[0])->primdata)->SetSelection(x0));
diff --git a/src/mred/wxs/wxs_rado.xc b/src/mred/wxs/wxs_rado.xc
index 3208c8691e..04f1bc90ab 100644
--- a/src/mred/wxs/wxs_rado.xc
+++ b/src/mred/wxs/wxs_rado.xc
@@ -48,7 +48,7 @@
@ "get-selection" : int GetSelection();
@ "number" : int Number()
-@ "set-selection" : void SetSelection(int); : : /RANGE[0]
+@ "set-selection" : void SetSelection(int); : : /RANGEX[0]
@ "enable" : void Enable(int,bool); : : /RANGE[0] <> single-button
@ "enable" : void Enable(bool); <> all-buttons
diff --git a/src/mred/wxs/wxs_tabc.cxx b/src/mred/wxs/wxs_tabc.cxx
index 497bf18388..7fc3ba40cb 100644
--- a/src/mred/wxs/wxs_tabc.cxx
+++ b/src/mred/wxs/wxs_tabc.cxx
@@ -274,6 +274,7 @@ static int unbundle_symset_tabStyle(Scheme_Object *v, const char *where) {
+
class os_wxTabChoice : public wxTabChoice {
public:
Scheme_Object *callback_closure;
diff --git a/src/mzscheme/Makefile.in b/src/mzscheme/Makefile.in
index 97d3fbe380..f9d7425895 100644
--- a/src/mzscheme/Makefile.in
+++ b/src/mzscheme/Makefile.in
@@ -221,8 +221,7 @@ $(collectsdir)/scheme/private/kernstruct.ss: $(srcdir)/src/makeexn
$(srcdir)/src/$(CSTARTUPDEST): $(srcdir)/src/startup.ss $(srcdir)/src/schvers.h $(srcdir)/src/schminc.h
- ./mzscheme@CGC@ -cqu $(srcdir)/src/sstoinc.ss $(CSTARTUPEXTRA) < $(srcdir)/src/startup.ss > $(srcdir)/src/$(CSTARTUPDEST)
-
+ ./mzscheme@CGC@ -cqu $(srcdir)/src/sstoinc.ss $(CSTARTUPEXTRA) $(srcdir)/src/$(CSTARTUPDEST) < $(srcdir)/src/startup.ss
$(srcdir)/src/mzmark.c: $(srcdir)/src/mzmarksrc.c $(srcdir)/src/mkmark.ss
mzscheme -cu $(srcdir)/src/mkmark.ss < $(srcdir)/src/mzmarksrc.c > $(srcdir)/src/mzmark.c
diff --git a/src/mzscheme/configure.ac b/src/mzscheme/configure.ac
index 266010fb79..b2c75c1e32 100644
--- a/src/mzscheme/configure.ac
+++ b/src/mzscheme/configure.ac
@@ -354,7 +354,7 @@ ZLIB_INC='$(ZLIB_INC)'
PNG_A='$(PNG_A)'
PREFLAGS="$CPPFLAGS"
-PLACE_CGC_FLAGS=""
+MZRT_CGC_FLAGS=""
LIBATOM="LIBATOM_NONE"
ar_libtool_no_undefined=""
@@ -1142,16 +1142,24 @@ fi
if test "${enable_places}" = "yes" ; then
PREFLAGS="$PREFLAGS -DMZ_USE_PLACES"
- PLACE_CGC_FLAGS="$GC_THREADS_FLAG -DTHREAD_LOCAL_ALLOC"
LDFLAGS="$LDFLAGS -pthread"
- LIBATOM="LIBATOM_USE"
+ enable_mzrt=yes
fi
############### futures ###################
if test "${enable_futures}" = "yes" ; then
- PREFLAGS="$PREFLAGS -DFUTURES_ENABLED -DUSE_PTHREAD_INSTEAD_OF_ITIMER"
+ PREFLAGS="$PREFLAGS -DMZ_USE_FUTURES"
+ enable_mzrt=yes
+fi
+
+############### OS threads ###################
+
+if test "${enable_mzrt}" = "yes" ; then
+ PREFLAGS="$PREFLAGS -DUSE_PTHREAD_INSTEAD_OF_ITIMER"
LDFLAGS="$LDFLAGS -pthread"
+ MZRT_CGC_FLAGS="$GC_THREADS_FLAG -DTHREAD_LOCAL_ALLOC"
+ LIBATOM="LIBATOM_USE"
fi
################ Xrender ##################
@@ -1432,7 +1440,7 @@ AC_SUBST(FRAMEWORK_REL_INSTALL)
AC_SUBST(FRAMEWORK_PREFIX)
AC_SUBST(INSTALL_ORIG_TREE)
AC_SUBST(EXE_SUFFIX)
-AC_SUBST(PLACE_CGC_FLAGS)
+AC_SUBST(MZRT_CGC_FLAGS)
AC_SUBST(LIBATOM)
AC_SUBST(MREDLINKER)
diff --git a/src/mzscheme/gc/Makefile.in b/src/mzscheme/gc/Makefile.in
index 188c530451..f5db01a36b 100644
--- a/src/mzscheme/gc/Makefile.in
+++ b/src/mzscheme/gc/Makefile.in
@@ -47,7 +47,7 @@ mainsrcdir = @srcdir@/../..
# compiler options; mainly used to allow importing options
OPTIONS=@OPTIONS@ @CGCOPTIONS@
-BASEFLAGS= -I$(srcdir)/include -I$(AO_INSTALL_DIR)/src @CFLAGS@ @COMPFLAGS@ @PREFLAGS@ @PLACE_CGC_FLAGS@
+BASEFLAGS= -I$(srcdir)/include -I$(AO_INSTALL_DIR)/src @CFLAGS@ @COMPFLAGS@ @PREFLAGS@ @MZRT_CGC_FLAGS@
CFLAGS= $(BASEFLAGS) @PROFFLAGS@ $(OPTIONS) -DNO_EXECUTE_PERMISSION -DSILENT -DNO_GETENV -DLARGE_CONFIG -DATOMIC_UNCOLLECTABLE -DINITIAL_MARK_STACK_SIZE=8192
# To build the parallel collector on Linux, add to the above:
diff --git a/src/mzscheme/gc2/newgc.c b/src/mzscheme/gc2/newgc.c
index 17561ff814..32640c0b10 100644
--- a/src/mzscheme/gc2/newgc.c
+++ b/src/mzscheme/gc2/newgc.c
@@ -2978,7 +2978,7 @@ static void fprintf_debug(NewGC *gc, const char *msg, objhead *info, FILE* file,
fprintf(file, "RMP %p already freed and out of bounds\n", SCHEME_PATH_VAL(obj));
}
default:
- fprintf_buffer(file, ((char *)obj), (info->size * WORD_SIZE));
+ fprintf_buffer(file, ((char *)obj), (info->size * WORD_SIZE) - sizeof(objhead));
break;
}
}
@@ -3309,6 +3309,7 @@ static void clean_up_heap(NewGC *gc)
cleanup_vacated_pages(gc);
}
+#ifdef MZ_USE_PLACES
static void unprotect_old_pages(NewGC *gc)
{
Page_Range *protect_range = gc->protect_range;
@@ -3337,6 +3338,8 @@ static void unprotect_old_pages(NewGC *gc)
flush_protect_page_ranges(protect_range, 0);
}
+#endif
+
static void protect_old_pages(NewGC *gc)
{
Page_Range *protect_range = gc->protect_range;
diff --git a/src/mzscheme/include/scheme.h b/src/mzscheme/include/scheme.h
index f1b4e5469c..94b9f03ae3 100644
--- a/src/mzscheme/include/scheme.h
+++ b/src/mzscheme/include/scheme.h
@@ -147,25 +147,6 @@ typedef jmpbuf jmp_buf[1];
typedef struct FSSpec mzFSSpec;
#endif
-/* Set up MZ_EXTERN for DLL build */
-#if defined(WINDOWS_DYNAMIC_LOAD) \
- && !defined(LINK_EXTENSIONS_BY_TABLE) \
- && !defined(SCHEME_EMBEDDED_NO_DLL)
-# define MZ_DLLIMPORT __declspec(dllimport)
-# define MZ_DLLEXPORT __declspec(dllexport)
-# ifdef __mzscheme_private__
-# define MZ_DLLSPEC __declspec(dllexport)
-# else
-# define MZ_DLLSPEC __declspec(dllimport)
-# endif
-#else
-# define MZ_DLLSPEC
-# define MZ_DLLIMPORT
-# define MZ_DLLEXPORT
-#endif
-
-#define MZ_EXTERN extern MZ_DLLSPEC
-
#ifndef MZ_DONT_USE_JIT
# if defined(MZ_USE_JIT_PPC) || defined(MZ_USE_JIT_I386) || defined(MZ_USE_JIT_X86_64)
# define MZ_USE_JIT
diff --git a/src/mzscheme/include/schthread.h b/src/mzscheme/include/schthread.h
index 5d53e414b8..b21438887c 100644
--- a/src/mzscheme/include/schthread.h
+++ b/src/mzscheme/include/schthread.h
@@ -19,8 +19,8 @@
#ifndef SCHEME_THREADLOCAL_H
#define SCHEME_THREADLOCAL_H
-#if defined(MZ_USE_PLACES) || defined(FUTURES_ENABLED)
-# define USE_THREAD_LOCAL
+#if defined(MZ_USE_PLACES) || defined(MZ_USE_FUTURES)
+# define USE_THREAD_LOCAL
# if _MSC_VER
# define THREAD_LOCAL __declspec(thread)
# elif defined(OS_X) || (defined(linux) && defined(MZ_USES_SHARED_LIB))
@@ -35,7 +35,26 @@
# define THREAD_LOCAL /* empty */
#endif
-extern void scheme_init_os_thread();
+/* Set up MZ_EXTERN for DLL build */
+#if (defined(__WIN32__) || defined(WIN32) || defined(_WIN32)) \
+ && !defined(LINK_EXTENSIONS_BY_TABLE) \
+ && !defined(SCHEME_EMBEDDED_NO_DLL)
+# define MZ_DLLIMPORT __declspec(dllimport)
+# define MZ_DLLEXPORT __declspec(dllexport)
+# ifdef __mzscheme_private__
+# define MZ_DLLSPEC __declspec(dllexport)
+# else
+# define MZ_DLLSPEC __declspec(dllimport)
+# endif
+#else
+# define MZ_DLLSPEC
+# define MZ_DLLIMPORT
+# define MZ_DLLEXPORT
+#endif
+
+#define MZ_EXTERN extern MZ_DLLSPEC
+
+MZ_EXTERN void scheme_init_os_thread();
/* **************************************************************** */
/* Declarations that we wish were elsewhere, but are needed here to */
@@ -77,7 +96,7 @@ typedef long objhead;
/* **************************************** */
-#if FUTURES_ENABLED
+#if MZ_USE_FUTURES
# include