This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
Re: more guile for perl refugees (split, join)
- To: Steve Tell <tell at telltronics dot org>
- Subject: Re: more guile for perl refugees (split, join)
- From: Mikael Djurfeldt <mdj at mdj dot nada dot kth dot se>
- Date: 01 Jul 2000 19:15:21 +0200
- Cc: clark dot mcgrew at sunysb dot edu, Guile Mailing List <guile at sourceware dot cygnus dot com>
- Cc: djurfeldt at nada dot kth dot se
- References: <Pine.LNX.4.21.0007010226150.12661-100000@ariel.lan.telltronics.org>
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)