[plt-scheme] Newbie macro problem
Hi,
I need a replacement for format that behaves exactly like format except
that it takes an arbitrary number of arguments and simply ignores any
more arguments than the format string requires:
(flex-format "hello ~a" 'world) ==> "hello world"
(flex-format "hello ~a" 'world 'folks 'good-day) ==> "hello world"
Looks simple, and I've defined a function count-format-arguments that
returns the number of format-tags that require an argument. If I have a
function defined as (flex-format str . rest)
(sublist rest 0 (count-format-arguments str))
yields a list of the arguments that are really required by str,
ommiting any further arguments.
However, I simply can't figure out how to actually define flex-format.
I'v tried various functions and macros for hours and never got the
right result. Using apply and quasi-quotes, I either got errors about a
missing syntax-transformer, or I didn't get the quasi-quotation right.
Could someone show me how to define flex-format or explain a similar
example to me?
Best regards,
Erich
======
(define (count-format-arguments str)
(let loop ((li (string->list str))
(elem #f)
(c 0))
(cond ((null? li) c)
((not elem) (loop (cdr li) (car li) c))
((equal? elem #\~) (case (car li)
((#\a #\A #\v #\V #\s #\S #\e #\E #\c
#\C #\b #\B #\o #\O #\x #\X)
(loop (cdr li) (car li) (+ c 1)))
(else (loop (cdr li) (car li) c))))
(else (loop (cdr li) (car li) c)))))
; grabbed from the Net:
(define sublist
(lambda (ls m n)
(define (sublist-internal result ls m n)
(cond ((or (= m n) (= n 0)) ; limit cases
result)
((null? ls)
;; either complain or return a useful default
result)
((= m 0)
(sublist-internal (cons (car ls) result) (cdr ls) 0 (- n
1)))
(else (sublist-internal result (cdr ls) (- m 1) (- n
1)))))
(reverse! (sublist-internal '() ls m n))))