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)



Lovely introduction to macros using (ice-9 syncase), thanks!

Just one hitch: the (for ) loop syntax works great when the macro is
defined in the same file, or in a file read with (load "for.scm")
but when I try to add it to my own module of convenience functions, it
doesn't seem to be available to code which uses the module.

(yes, the module is in the GUILE_LOAD_PATH and is getting loaded)

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)


Any hints on what I'm doing wrong?


On Wed, 28 Jun 2000, Clark McGrew wrote:

> Here's a (rather) verbose implementation that can be cut and pasted.
 
> (use-modules (ice-9 syncase))
 
> (define-syntax for
>   (syntax-rules ()
>     ;; Handle the "normal" case.  This is used when the evaluator stumbles




; file for.scm

(display "in for.scm\n")

(define-module (for))

;
; 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".

(use-modules (ice-9 syncase))

(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]