This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: more guile for perl refugees (split, join)


Steve Tell <tell@telltronics.org> writes:

> By analogy to define and define-public, I'm wondering if this should be
> using somthing like "define-public-syntax," but I don't see any such
> thing in (ice-9 syncase)

Unfortunately macros and the current module system don't play well
together.  However, below is a version of your code which works in the
latest CVS Guile.

If you have an older Guile, please replace :export (for) with a
free-standing (export for) form:

  (define-module (for)
    :use-syntax (ice-9 syncase))
  
  (export for)

If you want better code loading performance, you can replace
:use-syntax with :use-module .  This works for almost all kinds of
macros, but fails for some special cases, such as macros explicitly
manipulating identifiers and singleton macros.

; file for.scm

(define-module (for)
  :use-syntax (ice-9 syncase)
  :export (for))

(display "in for.scm\n")

;
; From a guile-list posting by Clark McGrew <mcgrew@ale.physics.sunysb.edu>
;
;  This implements a simple looping structure.
;
;  [[syntax]] (for (<counter> <start> <finish>) <body> ...)
;             (for (<counter> <start> <finish> <step>) <body> ...)
;
;      For is an iteration construct.  It specifies the variable <counter>
;      to take values between <start> and <finish>.  If <step> is provided
;      then <counter> is incremented by that value between each iteration,
;      otherwise, it changes by 1.  If <start> is less than <finish> then
;      <counter> will increase with each iteration.  If <start> is greater
;      than <finish> then <counter> will decrease, and if <start> is equal
;      to <finish> the <body> will be executed once for the value of
;      <start>. 
; 
;  [[example]]
;     (for (i 1 3) 
;        (display i) 
;        (display " "))
;            will print "1 2 3".

(define-syntax for
  (syntax-rules ()
    ;; Handle the "normal" case.  This is used when the evaluator stumbles
    ;; across "(for (i 1 5) body)" or "(for (i 5 1) body)".
    ((for (<counter> <start> <finish>) <body> ...)
     (do
	 ;; Set the initial conditions for the loop.
	 ((<counter>			; The name of the counter
	   <start>			; The initial value of the counter
	   (if (> <finish> <start>)		; The increment. This checks the
	       (+ <counter> 1)		; sign so the loop goes the right 
	       (- <counter> 1))))		; direction.
	 ;; Decide when the loop should terminate.
	 ((if (< <start> <finish>)
	      (< <finish> <counter>)	; An incrementing loop.
	      (< <counter> <finish>))	; A decrementing loop.
	  #t)
       ;; The code that gets executed at each iteration will go here.  
       <body> ...))

    ;; Handle a for loop with a user defined step.  This is used when the 
    ;; evalulator stumbles across "(for (i 1 5 2) body)"
    ((for (<counter> <start> <finish> <step>) <body> ...)
     (do 
	 ;; Set the initial conditions for the loop.
	 ((<counter>			; The name of the counter.
	   <start>			; The initial value of the counter.
	   (+ <counter> <step>)))	; The increment for each iteration.
	 ;; Decide when the loop should terminate.
	 ((if (< <start> <finish>)
	      (or (< <counter> <start>)	; An incrementing loop
		  (< <finish> <counter>))
	      (or (> <counter> <start>)	; A decrementing loop.
		  (> <finish> <counter>))) 
	  #t)
       ;; The code that gets executed at each iteration will go here.  
       <body> ...))))

     
(display "done with for.scm\n")

; file test_for.scm
;
; for.scm should be in the same directory, or else you'll need
; to fiddle with GUILE_LOAD_PATH
(use-modules (for))

;should print "1 2 3".
(for (i 1 3) 
     (display i) 
     (display " "))
(newline)

;should print "3 2 1".
     (for (i 3 1) 
        (display i) 
        (display " "))
(newline)

; should print "1.0 2.5 4.0".
     (for (i 1.0 4.0 1.5)
        (display i)
        (display " "))
(newline)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]