Welcome to the CHICKEN Scheme pasting service

coops and modules pasted by megane on Fri Jun 22 21:05:46 2012

(use coops)

(module
 m1
 *
 (import chicken scheme)
 (use coops)
 (define-class a1)
 (define-method (foo (o a1))
   (print "1")))

(module
 m2
 *
 (import chicken scheme)
 (use coops)
 (define-class a2)
 (define-method (foo (o a2))
   (print "2")))

(import m1 m2)

(print (foo (make a2)))
(print (foo (make a1)))

;; 2
;; #<unspecified>

;; Error: (foo) no method defined for given argument classes: (#<coops standard-class `a1'>)

no title pasted by megane on Fri Jun 22 21:21:08 2012

(use coops)

(module
 m1
 *
 (import chicken scheme)
 (use coops)
 (define-class a1)
 (define (foo o)
   (print "1")))

(module
 m2
 *
 (import chicken scheme)
 (use coops)
 (import m1)
 (define-class a2)
 (define (foo o)
   (print "2")))

(import m1 m2)

(print (foo (make a2)))

Warning: redefinition of imported value binding: foo
2
#<unspecified>

.foo pasted by megane on Fri Jun 22 21:25:32 2012

(use coops)

(module
 m1
 *
 (import chicken scheme)
 (use coops)
 (define-class a1 ()
   ((foo 1)))
 (define .foo (getter-with-setter
	       (lambda (o) (slot-value o 'foo))
	       (lambda (o v) (set! (slot-value o 'foo) v)))))

(module
 m2
 *
 (import chicken scheme)
 (use coops)
 (import m1)
 (define-class a2 ()
   ((foo 2)))
 (define .foo (getter-with-setter
	       (lambda (o) (slot-value o 'foo))
	       (lambda (o v) (set! (slot-value o 'foo) v)))))

(import m1 m2)

(print (.foo (make a2)))

no title pasted by megane on Fri Jun 22 21:52:05 2012

(import mydepend)
(myprovide coops-wrap)

;; A replacement for define-class that does not redefine the same class.
;; With it you can safely reload the file and update only the methods.
(module
 coops-wrap
 (variable-bound?
  defclass)
 (import chicken scheme)
 (use coops) 
 (use srfi-1
      srfi-13
      srfi-69) 
 (begin-for-syntax (import chicken))
 
 (define-syntax variable-bound?
   (ir-macro-transformer
    (lambda (e i c)
      (let [(varname (second e))]
	`(handle-exceptions
	     exn
	   (not (equal? "unbound variable"
			((condition-property-accessor 'exn 'message) exn)))
	   ,varname
	   #t)))))

 (begin-for-syntax
  (define-syntax variable-bound?
    (ir-macro-transformer
     (lambda (e i c)
       (let [(varname (second e))]
	 `(handle-exceptions
	      exn
	    (not (equal? "unbound variable"
			 ((condition-property-accessor 'exn 'message) exn)))
	    ,varname
	    #t))))))

 (begin-for-syntax
  (define-syntax defonce
    (ir-macro-transformer
     (lambda (e i c)
       `(unless (variable-bound? ,(second e))
	  (define ,(second e) ,(third e)))))))
 
 (define-syntax defonce
   (ir-macro-transformer
    (lambda (e i c)
      `(unless (variable-bound? ,(second e))
	 (define ,(second e) ,(third e))))))

 (begin-for-syntax
  (define-syntax dm			; debug message
    (ir-macro-transformer
     (lambda (e i c)
       (if #t
	   `(print ,@(drop e 1))
	   `(begin))))))

 (define-for-syntax (defonce var val)
   `(unless (variable-bound? ,var)
      (define ,var ,val)))

 (cond-expand
  (development
   (print "Defining coops-warp in development mode")
   (export
    -get-class-form
    -set-class-form
    -coops-wrap-get-class
    -coops-wrap-set-class
    *coops-wrap-classes*
    *coops-wrap-class-forms*
    coops-wrap-update-forms-s)
   ;; class symbol -> quoted class definition form
   (defonce *coops-wrap-class-forms* (make-hash-table))

   (define (-get-class-form sym)
     (hash-table-ref/default *coops-wrap-class-forms* sym #f))

   (define (-set-class-form sym form id)
     (hash-table-set! *coops-wrap-class-forms* sym (list form id)))

   (begin-for-syntax
    (defonce *coops-wrap-class-forms-s* (make-hash-table))
    (defonce *coops-wrap-cur-class-id* 0)

    (define (-get-next-class-id parent-ids)
      (let [(new-id (apply max *coops-wrap-cur-class-id* parent-ids))]
	(set! *coops-wrap-cur-class-id* (add1 new-id))
	new-id))
    
    (define (-set-class-form-s sym form id)
      (hash-table-set! *coops-wrap-class-forms-s* sym (list form id)))
    
    (define (-get-class-form-s sym)
      (hash-table-ref/default *coops-wrap-class-forms-s* sym #f)))

   ;; class symbol -> class-object
   (defonce *coops-wrap-classes* (make-hash-table))
   (define (-coops-wrap-get-class sym)
     (hash-table-ref *coops-wrap-classes* sym))

   (define (-coops-wrap-set-class sym value)
     (hash-table-set! *coops-wrap-classes* sym value))

   ;; Shovels stuff from *coops-wrap-class-forms* to *coops-wrap-class-forms-s*.
   ;; This makes the syntax environment aware of defined classes.
   (define-syntax coops-wrap-update-forms-s
     (ir-macro-transformer
      (lambda _
	`(let [(new-forms-s (make-hash-table))]
	   (print "--- update-forms-s ---")
	   (print "*coops-wrap-classes* \t\t" (hash-table-keys *coops-wrap-classes*))
	   (print "*coops-wrap-class-forms* \t" (hash-table-keys *coops-wrap-class-forms*))
	   (print "*coops-wrap-class-forms-s* \t" (hash-table-keys *coops-wrap-class-forms-s*))
	   (for-each
	    (lambda (s)
	      (hash-table-set! new-forms-s s
			       (hash-table-ref *coops-wrap-class-forms* s)))
	    (hash-table-keys *coops-wrap-class-forms*))
	   (set! *coops-wrap-class-forms-s* new-forms-s)
	   (print "old *coops-wrap-cur-class-id*" *coops-wrap-cur-class-id*)
	   (set! *coops-wrap-cur-class-id*
		 (add1 (apply max *coops-wrap-cur-class-id*
			      (append
			       (map second (hash-table-values *coops-wrap-class-forms*))
			       (map second (hash-table-values *coops-wrap-class-forms-s*))))))
	   (print "new *coops-wrap-cur-class-id*" *coops-wrap-cur-class-id*))))))
  (else))

 ;; Expands the writer: reader: accessor: fields.
 (define-for-syntax (expand-orig-accessors i f class-sym)
   ;;(dm "\nAcc " class-sym " " f)
   (cond
    ((null? (drop f 1)) '('()))
    ((not (keyword? (second f))) '('()))
    (else
     (let [(slot-sym (first f))]
       (let loop2 [(fs (drop f 1))
		   (ret '())]
	 (if (null? fs)
	     (begin
	       ;;(dm "Accessors: " (reverse ret)) 
	       (reverse ret))
	     (let [(kw (first fs))
		   (acc-sym (second fs))]
	       (loop2 (drop fs 2)
		      (append (or (and (or (eq? accessor: kw)
					   (eq? writer: kw))
				       `((define-method ((setter ,acc-sym) (o ,class-sym) v)
					   (set! (slot-value o ',slot-sym) v))
					 (export ,acc-sym)))
				  '())
			      (or (and (or (eq? accessor: kw)
					   (eq? reader: kw))
				       `((define-method (,acc-sym (o ,class-sym))
					   (slot-value o ',slot-sym))
					 (export ,acc-sym)))
				  '())
			      ret)))))))))
 
 (define-for-syntax (get-accessors e i c)
   (let* [(class-sym (second e))
	  (const-sym (i (string->symbol
			 (string-append
			  (symbol->string (i class-sym)) "."))))]
     (let* [(slot-syms (or (and (eq? 4 (length e)) (map i (map first (fourth e))))
			   '()))
	    (slot-forms (or (and (eq? 4 (length e)) (fourth e))
			    '()))
	    (accessor-forms
	     (map (lambda (slot-sym f)
		    (let [(acc-sym (i (string->symbol
				       (string-append
					"." (symbol->string slot-sym)))))]
		      (print "s " slot-sym " " acc-sym)
		      `(begin
			 (export ,acc-sym)
			 (define-method (,acc-sym (o ,class-sym))
			   (slot-value o ',(i slot-sym)))
			 (define-method ((setter ,acc-sym) (o ,class-sym) v)
			   (set! (slot-value o ',(i slot-sym)) v))
			 ;; (define ,acc-sym (getter-with-setter
			 ;; 		   (lambda (o) (slot-value o ',(i slot-sym)))
			 ;; 		   (lambda (o v)
			 ;; 		     (set! (slot-value o ',(i slot-sym)) v))))
			 ,@(expand-orig-accessors i f class-sym))))
		  slot-syms
		  slot-forms))
	    (accessor-forms (filter (lambda (o) o) accessor-forms))]
       accessor-forms)))

 (define-for-syntax (get-class e i c define-class?) 
   (let* [(class-sym (second e))
	  (class-name (symbol->string (i class-sym)))
	  (const-sym (i (string->symbol
			 (string-append
			  (or (and (string-prefix? "<" class-name)
				   (string-suffix? ">" class-name)
				   (substring class-name 1 (sub1 (string-length class-name))))
			      class-name)
			  "."))))
	  (strip-accessors
	   (lambda (f)
	     (if (eq? 4 (length f))
		 (append
		  (take f 3)
		  (list (map (lambda (slot-form)
			       (if (< (length slot-form) 3)
				   slot-form
				   (cons (first slot-form)
					 (let [(init (drop-while (lambda (v)
								   (not (eq? v initform:)))
								 slot-form))]
					   (if (null? init)
					       '()
					       (take init 2))))))
			     (fourth f))))
		 f)))]
     `(begin
	;;(begin-for-syntax (print "defining" (quote ,e)))
	(export ,class-sym)
	,(cond-expand
	  (development
	   (if define-class?
	       `(begin
		  ;;(begin-for-syntax (print "New class " (quote ,class-sym)))
		  (define-class ,@(drop (strip-accessors e) 1))
		  (-coops-wrap-set-class ',(i class-sym) ,class-sym))
	       `(begin
		  ;;(begin-for-syntax (print "Fetching def from table " ',class-sym))
		  (define ,class-sym (-coops-wrap-get-class ',(i class-sym))))))
	  (else
	   `(define-class ,@(drop e 1))))
	(export ,const-sym)
	(define ,const-sym (lambda o (apply make ,class-sym o)))
	
	;;(begin-for-syntax (print "defined" (quote ,e))) 
	)))

 (define-for-syntax (defoo e i c define-class?)
   (print (get-accessors e i c))
   `(begin ,(get-class e i c define-class?)
	   ,@(get-accessors e i c)))

 (define-syntax defclass
   ;; Does various things:
   ;;
   ;; - exports the class
   ;;
   ;; - defines and exports foo. constructor
   ;;
   ;; - defines and exports .foo slot accessors
   ;;
   ;; If the class is already defined then does not redefine it.
   ;;
   ;; When feature development is defined:
   ;;
   ;; The quoted form of the defclass call is stored to a
   ;; variable. Defclass is not "called" again if this form has not
   ;; changed.
   (ir-macro-transformer
    (lambda (e i c)
      (dm "")
      (dm "---   "(cond-expand (development "DEV") (else "NON DEV"))
	  " " (i (second e))
	  " module: " (and (##sys#current-module)
			   (##sys#slot (##sys#current-module) 1)))
      (let* [(to-form-sym (lambda (s)
			    (string->symbol
			     (string-append
			      "#"
			      (symbol->string s)
			      "#"))))
	     (parent-ids (lambda (form)
			   (map (compose second -get-class-form-s to-form-sym)
				(or (and (< 1 (length form)) (second form))
				    '())))) 
	     (formsym (i (to-form-sym (i (second e)))))
	     (parent-changed?
	      (lambda ()
		(let* [(form-id (-get-class-form-s formsym))
		       (old-form (first form-id))
		       (old-id (second form-id))
		       (parent-ids (parent-ids old-form))]
		  (dm "Parents " (or (and (< 1 (length old-form)) (second old-form)) '())) 
		  (dm "Old id " old-id " parent ids " parent-ids)
		  (find (lambda (pi) (> pi old-id)) parent-ids))))(class-sym (i (second e)))
	     (def-form (strip-syntax (drop e 1)))]
	(cond-expand
	 (development
	  ;; (dm "syntax form table START")
	  ;; (for-each (lambda (k) (dm k))
	  ;; 	    (hash-table-keys *coops-wrap-class-forms-s*))
	  ;; (dm "syntax form table END")
	   
	  ;;(dm "Bdound" (variable-bound? *coops-wrap-classes*))
	  ;;(dm "forms-s" (hash-table-keys *coops-wrap-class-forms-s*))
	   
	  (if (not (-get-class-form-s formsym))
	      ;; NOTE: Here the wrong thing is done and define-class is
	      ;; used at non-toplevel context. For this hack to work
	      ;; these branches have to be in this order!
	      (let [(class-id (-get-next-class-id (parent-ids (i (drop e 1)))))]
		(dm "New class " class-sym " id: " class-id)
		(-set-class-form-s formsym def-form class-id)
		`(begin
		   (begin-for-syntax (-set-class-form-s ',(i formsym) ',(i def-form) ,class-id))
		   (-set-class-form (quote ,formsym) (quote ,(i def-form)) ,class-id)
		   ,(defoo e i c #t)))
	      (if (equal? (first (-get-class-form-s formsym)) def-form) 
		  (if (parent-changed?)
		      (let [(class-id (-get-next-class-id (parent-ids (i (drop e 1)))))]
			(dm "Redefining class because of parent change, new id " class-id )
			(-set-class-form-s formsym def-form class-id)
			`(begin
			   (-set-class-form (quote ,formsym) (quote ,(i def-form)) ,class-id) 
			   ,(defoo e i c #t)))
		      (begin
			(dm "Not redefining class " class-sym)
			`(begin
			   ;;(begin-for-syntax (print "class " ,(second e)))
			   ,(defoo e i c #f))))
		  (let [(class-id (-get-next-class-id (parent-ids (i (drop e 1)))))]
		    (dm "Redefining class " class-sym " id: " class-id)
		    (dm "old " (-get-class-form-s formsym))
		    (-set-class-form-s formsym def-form class-id)
		    (dm "new " (-get-class-form-s formsym)) 
		    `(begin
		       (begin-for-syntax (-set-class-form-s ',(i formsym) ',(i def-form) ,class-id))
		       (-set-class-form (quote ,formsym) (quote ,(i def-form)) ,class-id) 
		       ,(defoo e i c #t))))))
	 (else 
	  (defoo e i c #t)))))))
 )

it werks added by megane on Fri Jun 22 23:31:19 2012

(use coops)

(module
 foo
 (get-acc)
 (import chicken scheme)
 (use coops)
 (use srfi-69)
 (define *accs* (make-hash-table))
 (define (get-acc s)
   (or (hash-table-ref/default *accs* s #f)
       (and (hash-table-set! *accs* s (make-generic-procedure a))
	    (hash-table-ref *accs* s)))))

(module
 m1
 (a1 .foo)
 (import chicken scheme)
 (use coops)
 (import foo)
 (define-class a1)
 (define .foo (get-acc 'foo))
 (register-generic-procedure .foo)
 (define-method (.foo (o a1)) 1))

(module
 m2
 (a2 .foo)
 (import chicken scheme)
 (use coops)
 (import foo)
 ;;(import (only m1 foo))
 (define-class a2)
 (define .foo (get-acc 'foo))
 (register-generic-procedure .foo)
 (define-method (.foo (o a2)) 
   2))

(import m1 m2)

(print "2=" (.foo (make a2)))
(print "1=" (.foo (make a1)))

;; 2=2
;; 1=1

Your annotation:

Enter a new annotation:

Your nick:
The title of your paste:
Your paste (mandatory) :
What module provides regular expressions support?
Visually impaired? Let me spell it for you (wav file) download WAV