From: Kenny Tilton
Subject: hoots n hollers with c2lisp
Date: 
Message-ID: <B3pyf.2232$cj3.1234@news-wrt-01.rdc-nyc.rr.com>
I thought you all might get a laugh out of this. My C2Lisp hack is 
staggering to its feets, but I ended up with:

    (printf "%d %d" x y)

..in the Lisp output. It occurred to me I could convert that too 
automatically to format, but then I realized, uh-oh, format (and printf 
to a lesser degree) is its own language.

Hmmm. Anyone got a printf to format string translator?

:)

kt

From: Jeff M.
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <1137338528.000372.76360@z14g2000cwz.googlegroups.com>
I'd imagine for *most* formats, you could just substitute % for ~ and
any letters following % with A. So printf("%d %d", x, y) turns into
(format t "~A ~A" x y). It's really only when you get into the actual
formatting that things may get a little trickier.

Jeff M.
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <8764olz9uy.fsf@qrnik.zagroda>
"Jeff M." <·······@gmail.com> writes:

> I'd imagine for *most* formats, you could just substitute % for ~ and
> any letters following % with A. So printf("%d %d", x, y) turns into
> (format t "~A ~A" x y).

Except when x and y are characters.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Nathan Baum
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <dqeif6$502$1@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com>
Marcin 'Qrczak' Kowalczyk wrote:
> "Jeff M." <·······@gmail.com> writes:
> 
>> I'd imagine for *most* formats, you could just substitute % for ~ and
>> any letters following % with A. So printf("%d %d", x, y) turns into
>> (format t "~A ~A" x y).
> 
> Except when x and y are characters.
> 

It's impossible to pass a "char" value to printf: any "char" value is 
automatically promoted to an "int".

This implies that a C->Lisp converter must transform

   char x = foo(), y = bar();
   printf("%d %d", x, y)

into the moral equivalent of

   (let ((x (foo))
         (y (bar)))
     (declare (character x y))
     (format t "~A ~A" (char-code x) (char-code y)))
From: Pascal Bourguignon
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <874q45ytj9.fsf@thalassa.informatimago.com>
Nathan Baum <···········@btinternet.com> writes:

> Marcin 'Qrczak' Kowalczyk wrote:
>> "Jeff M." <·······@gmail.com> writes:
>> 
>>> I'd imagine for *most* formats, you could just substitute % for ~ and
>>> any letters following % with A. So printf("%d %d", x, y) turns into
>>> (format t "~A ~A" x y).
>> Except when x and y are characters.
>> 
>
> It's impossible to pass a "char" value to printf: any "char" value is
> automatically promoted to an "int".
>
> This implies that a C->Lisp converter must transform
>
>    char x = foo(), y = bar();
>    printf("%d %d", x, y)
>
> into the moral equivalent of
>
>    (let ((x (foo))
>          (y (bar)))
>      (declare (character x y))
>      (format t "~A ~A" (char-code x) (char-code y)))

Unless the format string contains %c.

       int in=65;char ch=67;
       printf("%d %d %c %c",ch,in,ch,in);
-->
       (let ((in 65)
             (ch (code-char 67)))
         (format t "~D ~D ~C ~C" (char-code ch) in ch (code-char in)))

And I don't see why you should use ~A for %d.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NEW GRAND UNIFIED THEORY DISCLAIMER: The manufacturer may
technically be entitled to claim that this product is
ten-dimensional. However, the consumer is reminded that this
confers no legal rights above and beyond those applicable to
three-dimensional objects, since the seven new dimensions are
"rolled up" into such a small "area" that they cannot be
detected.
From: Nathan Baum
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <dqemma$ad3$1@nwrdmz02.dmz.ncs.ea.ibs-infra.bt.com>
Pascal Bourguignon wrote:
> Nathan Baum <···········@btinternet.com> writes:
> 
>> Marcin 'Qrczak' Kowalczyk wrote:
>>> "Jeff M." <·······@gmail.com> writes:
>>>
>>>> I'd imagine for *most* formats, you could just substitute % for ~ and
>>>> any letters following % with A. So printf("%d %d", x, y) turns into
>>>> (format t "~A ~A" x y).
>>> Except when x and y are characters.
>>>
>> It's impossible to pass a "char" value to printf: any "char" value is
>> automatically promoted to an "int".
>>
>> This implies that a C->Lisp converter must transform
>>
>>    char x = foo(), y = bar();
>>    printf("%d %d", x, y)
>>
>> into the moral equivalent of
>>
>>    (let ((x (foo))
>>          (y (bar)))
>>      (declare (character x y))
>>      (format t "~A ~A" (char-code x) (char-code y)))
> 
> Unless the format string contains %c.

I don't think some other format string containing %c changes what it 
should do to %d, which was all that my example was talking about.

Obviously, other printf formatting codes will need to be transformed 
into other Lisp forms.

> And I don't see why you should use ~A for %d.

Sure. ~D is the correct choice.
From: John Thingstad
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <op.s3fgftzepqzri1@mjolner.upc.no>
On Sun, 15 Jan 2006 11:01:05 +0100, Kenny Tilton  
<·············@nyc.rr.com> wrote:

> I thought you all might get a laugh out of this. My C2Lisp hack is  
> staggering to its feets, but I ended up with:
>
>     (printf "%d %d" x y)
>
> ..in the Lisp output. It occurred to me I could convert that too  
> automatically to format, but then I realized, uh-oh, format (and printf  
> to a lesser degree) is its own language.
>
> Hmmm. Anyone got a printf to format string translator?
>
> :)
>
> kt

This has cropped up before. I belive Garath McCaughan wrote the readmacro
fixes and I wrote a crude dispatcher for printf.

http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/2cc33e1afde253a6/b8d315d96908f7da?lnk=st&q=printf+group%3Acomp.lang.lisp+author%3AThingstad&rnum=1&hl=en#b8d315d96908f7da


-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: John Thingstad
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <op.s3fjqxq5pqzri1@mjolner.upc.no>
On Sun, 15 Jan 2006 17:08:07 +0100, John Thingstad  
<··············@chello.no> wrote:

> This has cropped up before. I belive Garath McCaughan wrote the readmacro
> fixes and I wrote a crude dispatcher for printf.
>
> http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/2cc33e1afde253a6/b8d315d96908f7da?lnk=st&q=printf+group%3Acomp.lang.lisp+author%3AThingstad&rnum=1&hl=en#b8d315d96908f7da
>
>

erm. You need to read all the posts to get the numerous improvements.
As luck would have it I have a improved version on my file system so here
goes:

CL-USER 4 >  (format t (printf->format #S"int=%10d\tfloat=%10.3f\n") 2  
3.1415)
int=         2	float=     3.142
NIL

(defvar *string-escape-character* #\\)

(defvar *string-escape-table*
   ;; built with LIST and CONS so it's legal to modify it
   (list
     (cons #\t #\Tab)
     (cons #\n #\Newline)
     (cons #\r #\Return)))

(defvar *escaped-string-delimiters*
   (list #\" #\'))

(defvar *complex-delimiter* #\()

(set-dispatch-macro-character #\# #\S
   (lambda (stream sub-char infix-arg)
     (declare (ignore sub-char infix-arg))
     (let ((delimiter (read-char stream))
           (escaped nil))
       (assert (member delimiter *escaped-string-delimiters*))
       (coerce (loop for next-char = (read-char stream) nconc
                     (cond
                      (escaped
                       (progn (setf escaped nil)
                         (list (or (cdr (assoc next-char  
*string-escape-table*))
                                   next-char))))
                      ((char= next-char delimiter)
                       (loop-finish))
                      ((char= next-char *string-escape-character*)
                       (setf escaped t)
                       nil)
                      (t (list next-char))))
               'string))))

(defvar *digits* '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
(defvar *sign* '(#\+ #\-))
(defvar *format-translation-table*
   (list
    (cons #\d #\D)
    (cons #\f #\F)
    (cons #\s #\A)
    (cons #\c #\C)))

(defun read-int-string (istream)
   (with-output-to-string (ostream)
     (when (member (peek-char nil istream) *sign*)
       (write-char (read-char istream) ostream))
     (loop for char = (read-char istream) until (not (member char *digits*))
           do (write-char char ostream)
           finally (unread-char char istream))))

(defun printf->format (format)
   (with-output-to-string (ostream)
     (with-input-from-string (istream format)
       (loop for char = (read-char istream nil 'EOF) until (not (characterp  
char)) do
             (if (char= char #\%)
                 (progn
                   (write-char #\~ ostream)
                   (write-string (read-int-string istream) ostream)
                   (when (char= (peek-char nil istream) #\.)
                     (setf char (read-char istream))
                     (write-char #\, ostream)
                     (write-string (read-int-string istream) ostream))
                   (setf char (read-char istream))
                   (write-char (cdr (assoc char  
*format-translation-table*)) ostream))
               (princ char ostream))))))

(define-compiler-macro printf->format (&whole whole format)
     (if (stringp format)
         (printf->format format)
       whole))

It still is fairly incomplete, but it should be fairly easy to extend.
-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Rob Warnock
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <1OmdncRns7C9n1benZ2dnUVZ_tOdnZ2d@speakeasy.net>
John Thingstad <··············@chello.no> wrote:
+---------------
| > This has cropped up before. I belive Garath McCaughan wrote the readmacro
| > fixes and I wrote a crude dispatcher for printf.
...
| As luck would have it I have a improved version on my file system ...
| CL-USER 4 >  (format t (printf->format #S"int=%10d\tfloat=%10.3f\n") 2  
+---------------

This is really cool! But... I'd hate to lose the ANSI standard
structure-reader readmacro, as in #S(FOO :A 1 :B 2 :C 3).
Is there any reason a naked #" isn't better as the community's
default read-as-C-string readmacro?


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: John Thingstad
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <op.s3gbrotbpqzri1@mjolner.upc.no>
On Mon, 16 Jan 2006 03:17:04 +0100, Rob Warnock <····@rpw3.org> wrote:

> John Thingstad <··············@chello.no> wrote:
> +---------------
> | > This has cropped up before. I belive Garath McCaughan wrote the  
> readmacro
> | > fixes and I wrote a crude dispatcher for printf.
> ...
> | As luck would have it I have a improved version on my file system ...
> | CL-USER 4 >  (format t (printf->format #S"int=%10d\tfloat=%10.3f\n") 2
> +---------------
>
> This is really cool! But... I'd hate to lose the ANSI standard
> structure-reader readmacro, as in #S(FOO :A 1 :B 2 :C 3).
> Is there any reason a naked #" isn't better as the community's
> default read-as-C-string readmacro?
>

Well I was going to use #C.
But that of course conflicts with complex.
Hence the unused (defvar *complex-delimiter* #\()
But it seemed overly complicated so I changed it..
In principle it can be anything you want..
Missed the use of S. I think Garret originally
used E, but I found that hard to remember.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Rob Warnock
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <vtWdnb32YJHd9VbeRVn-uA@speakeasy.net>
John Thingstad <··············@chello.no> wrote:
+---------------
| Rob Warnock <····@rpw3.org> wrote:
| > This is really cool! But... I'd hate to lose the ANSI standard
| > structure-reader readmacro, as in #S(FOO :A 1 :B 2 :C 3).
| > Is there any reason a naked #" isn't better as the community's
| > default read-as-C-string readmacro?
| 
| Well I was going to use #C.
| But that of course conflicts with complex.
| Hence the unused (defvar *complex-delimiter* #\()
| But it seemed overly complicated so I changed it..
| In principle it can be anything you want..
+---------------

Yes, but... It's always best to use something that's not already
defined by the standard.

+---------------
| Missed the use of S.
+---------------

Which is why I have CLHS 2.4.8 "Sharpsign" permanently bookmarked,
for its Figure 2.19 "Standard #Dispatching Macro Character Syntax"!  ;-}

    http://www.lispworks.com/documentation/HyperSpec/Body/02_dh.htm

Remember that the second character of a dispatching macro character
sequence does *not* have to be a letter. It can be any character at
all except digits or whitespace [or #\<]. Sometimes people get fixated
on the letters when they're learning all the various predefined
dispatching readmacros and forget that the undefined non-letter ones
are available for users, too.

+---------------
| I think Garret originally used E, but I found that hard to remember.
+---------------

That's why I suggested #" -- to me it implies a special kind of string.
And I don't worry about typing it up for C-like strings, since one
could always use an integer prefix to select some *other* type of
special string if needed.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Joerg Hoehle
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <u3bjllh9m.fsf@users.sourceforge.net>
····@rpw3.org (Rob Warnock) writes:
> John Thingstad <··············@chello.no> wrote:
> | CL-USER 4 >  (format t (printf->format #S"int=%10d\tfloat=%10.3f\n") 2  
> This is really cool! But... I'd hate to lose the ANSI standard
> structure-reader readmacro, as in #S(FOO :A 1 :B 2 :C 3).

Why is that actually a reader macro? It's sole purpose seem to be to
pass the result to printf->format. So why should this function not
just take the original C string?

Then you can write a compiler macro for printf-format, which might in
turn call FORMATTER, and then the printf stuff might compile to native
code in some Lisps :)

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: John Thingstad
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <op.s3k0luumpqzri1@mjolner.upc.no>
On Wed, 18 Jan 2006 15:53:09 +0100, Joerg Hoehle  
<······@users.sourceforge.net> wrote:

> ····@rpw3.org (Rob Warnock) writes:
>> John Thingstad <··············@chello.no> wrote:
>> | CL-USER 4 >  (format t (printf->format #S"int=%10d\tfloat=%10.3f\n") 2
>> This is really cool! But... I'd hate to lose the ANSI standard
>> structure-reader readmacro, as in #S(FOO :A 1 :B 2 :C 3).
>
> Why is that actually a reader macro? It's sole purpose seem to be to
> pass the result to printf->format. So why should this function not
> just take the original C string?
>
> Then you can write a compiler macro for printf-format, which might in
> turn call FORMATTER, and then the printf stuff might compile to native
> code in some Lisps :)
>
> Regards,
> 	Jorg Hohle
> Telekom/T-Systems Technology Center

I feel it better reflects the way strings are processed in C.
The parts handled by the printer macro are in fact common to all
C strings, not just the format strings of the printer macro.
In the name of extensibillity I chose to stick with Gareth's code.

Incedentally I had a dream..
In this dream Kenny Tilton included my code in his C-to-lisp library.
The notes of it's incompleteness lost.
Every time someone used the code some bug turned up and it was traced
to my code. I got famous alright..
My name was remembered forever as 'OH. That ······@@'.
I found that the only remedy was to come up with a complete version.
So I am working on one now. Expect it tomorrow I guess.

(PS. I changed the reader format to #"...")

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Kenny Tilton
Subject: Omigod! [was Re: hoots n hollers with c2lisp]
Date: 
Message-ID: <Ziyyf.594$yE4.567@news-wrt-01.rdc-nyc.rr.com>
John Thingstad wrote:
> On Sun, 15 Jan 2006 17:08:07 +0100, John Thingstad  
> <··············@chello.no> wrote:
> 
>> This has cropped up before. I belive Garath McCaughan wrote the readmacro
>> fixes and I wrote a crude dispatcher for printf.
>>
>> http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/2cc33e1afde253a6/b8d315d96908f7da?lnk=st&q=printf+group%3Acomp.lang.lisp+author%3AThingstad&rnum=1&hl=en#b8d315d96908f7da 
>>
>>
>>
> 
> erm. You need to read all the posts to get the numerous improvements.
> As luck would have it I have a improved version on my file system so here
> goes:

Cool, thx. I'll put that in my lisp-c library and let those printfs 
through and see what happens.

kt
From: Gareth McCaughan
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <873bjnty6v.fsf@g.mccaughan.ntlworld.com>
John Thingstad wrote:

[Kenny:]
>> Hmmm. Anyone got a printf to format string translator?

[John:]
> This has cropped up before. I belive Garath McCaughan wrote the readmacro
> fixes and I wrote a crude dispatcher for printf.

Just for clarity, all my code did was to handle C-style
escapes in literal strings. The handling of printf
formatting was done by John and I accept neither credit
nor blame for it :-). (And my name is "Gareth", not
"Garath" or "Garret". In the latter case, I think there
may be some confusion with the artist formerly known
as Erann Gat...)

-- 
Gareth McCaughan
.sig under construc
From: John Thingstad
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <op.s3imnotbpqzri1@mjolner.upc.no>
On Tue, 17 Jan 2006 02:59:08 +0100, Gareth McCaughan  
<················@pobox.com> wrote:

> Just for clarity, all my code did was to handle C-style
> escapes in literal strings. The handling of printf
> formatting was done by John and I accept neither credit
> nor blame for it :-). (And my name is "Gareth", not
> "Garath" or "Garret". In the latter case, I think there
> may be some confusion with the artist formerly known
> as Erann Gat...)
>

Yes. I noticed that I had misspelled your name and should probaly have  
sent a errata.
Sorry!
As for giving credit the other alternative taking the entire credit myself  
could
be construded as insulting.
I should note that Gareth (right!) 's code only supports 3 of the 9
ASCII control codes. This should be trivial to extend. Just add them to  
the table.
The format code is far worse. For good measure I read through my
"AT&T System V Interface Definition" printf definition.
My code only coveres the most common use. I'd say it would correctly parse
approx 80 % of printf statements. (Actual statements not 80% of the  
syntax.)
I also estimate that in order to bring that up to 100 % would require
approx 4 x the amount of work/code.
Be warned! This was at the time written as a educational example
to help a guy called Jim Newton. I never intended it to
be part of a library. If I had I would have made it far more complete
and robust.

(I did warn you that it was crude and incomplete..)

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: John Thingstad
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <op.s3nbsqwspqzri1@mjolner.upc.no>
On Sun, 15 Jan 2006 11:01:05 +0100, Kenny Tilton  
<·············@nyc.rr.com> wrote:

> I thought you all might get a laugh out of this. My C2Lisp hack is  
> staggering to its feets, but I ended up with:
>
>     (printf "%d %d" x y)
>
> ..in the Lisp output. It occurred to me I could convert that too  
> automatically to format, but then I realized, uh-oh, format (and printf  
> to a lesser degree) is its own language.
>
> Hmmm. Anyone got a printf to format string translator?
>
> :)
>
> kt

Well I mentioned something about a improved version so here goes.
It is still far from complete but it now handles formatting better
and more options.

CL-USER 5 > (printf:printf->format #"%f")
"~,6F"

CL-USER 6 > (format t (printf:printf->format ·······@······@%10s\n") 3 pi  
"hello")
3         @          ··········@     hello
NIL

CL-USER 7 > (format t (printf:printf->format ········@·······@%-10s\n") 3  
pi "hello")
··········@3.14159265          @hello
NIL

----------------------------------------------------------------------------------------

(defpackage printf
   (:use common-lisp)
   (:export printf->format))

(defvar *string-escape-character* #\\)

(defvar *string-escape-table*
   ;; built with LIST and CONS so it's legal to modify it
   (list
    (cons #\a #\Bell)
    (cons #\b #\Backspace)
    (cons #\f #\Page)
    (cons #\n #\Newline)
    (cons #\r #\Return)
    (cons #\t #\Tab)))

;;; Acclaim/Blame for this one goes to Garreth ..
(set-dispatch-macro-character #\# #\"
   (lambda (stream sub-char infix-arg)
     (declare (ignore sub-char infix-arg))
     (let ((delimiter #\")
           (escaped nil))
       (coerce (loop for next-char = (read-char stream) nconc
                     (cond
                      (escaped
                       (progn (setf escaped nil)
                         (list (or (cdr (assoc next-char  
*string-escape-table*))
                                   next-char))))
                      ((char= next-char delimiter)
                       (loop-finish))
                      ((char= next-char *string-escape-character*)
                       (setf escaped t)
                       nil)
                      (t (list next-char))))
               'string))))

(in-package printf)

(define-condition printf-error (error)
   ((ch :reader ch :initarg :ch))
   (:report (lambda (condition stream)
	     (format stream "'~A' is not valid in a printf format" (ch  
condition)))))

;;; Format of printf %[Flags][Width].[Precition][Size][Type]
(defvar *digits* '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
(defvar *flags* '(#\- #\+ #\# #\Space))
(defvar *size* '(#\h #\l #\L))
(defvar *sign* '(#\+ #\-))

(defmacro remember ((name value) calling (function &rest args))
   (assert (eq calling :calling))
   `(lambda ,args
      (let ((,name ,value))
      (declare (special ,name))
      (,function ,@args))))

(defmacro aif (test-form then-form &optional else-form)
   "From Paul Graham: On Lisp - Anamorphic macroes"
   `(let ((it ,test-form))
      (if it ,then-form ,else-form)))

(defun char-dispatch (flag width precition size)
   (declare (ignore flag width precition size))
   "~C")

(defun integer-dispatch (flag width precition size)
   "~<@><mincol>,<padchar>,<comma-char><comma-interval>"
   (declare (ignore size) (special type))
   (let ((modifier (if (and flag (char= flag #\+)) ··@ nil)) (padchar (if  
precition #\0 nil)))
     (with-output-to-string (ostream)
       (if (and flag (char= flag #\-))
           (progn ; left justify
             (write-char #\~ ostream)
             (when width (write-string width ostream))
             (write-string ·@<~" ostream)
             (write-char type ostream)
             (write-string "~>" ostream))
         (progn
           (write-char #\~ ostream)
           (when width (write-string width ostream))
           (when padchar
             (write-string ",'" ostream)
             (write-char padchar ostream))
           (when modifier (write-char modifier ostream))
           (write-char type ostream))))))

(defun ignore-dispatch (flag width precition size)
   (declare (ignore flag width precition size)))

(defun float-dispatch (flag width precition size)
   "~w,d,k,overflowchar,padchar"
   (declare (ignore size) (special type))
   (let ((w width) (d (if precition precition "6")))
     (with-output-to-string (ostream)
       (if (and flag (char= flag #\-))
           (progn ; left justify
             (write-char #\~ ostream)
             (when width (write-string width ostream))
             (write-string ·@<~" ostream)
             (write-char #\, ostream)
             (write-string d ostream)
             (write-char type ostream)
             (write-string "~>" ostream))
         (progn
           (write-char #\~ ostream)
           (when width (write-string w ostream))
           (write-char #\, ostream)
           (write-string d ostream)
           (write-char type ostream))))))

(defun string-dispatch (flag width precition size)
   "~mincol,colinc,minpad,padcharA"
   (declare (ignore precition size))
   (with-output-to-string (ostream)
     (write-char #\~ ostream)
     (when width (write-string width ostream))
     (when (and flag (char= flag #\-)) (write-char ··@ ostream))
     (write-string "<~A~>" ostream)))

(defun identity-dispatch (flag width precition size)
   (declare (ignore flag precition width size))
   "%")

(defparameter *type-dispatcher*
   (list
    (cons #\c #'char-dispatch)
    (cons #\d (remember (type #\D) :calling (integer-dispatch flag width  
precition size)))
    (cons #\e (remember (type #\E) :calling (float-dispatch flag width  
precition size)))
    (cons #\E (remember (type #\E) :calling (float-dispatch flag width  
precition size)))
    (cons #\f (remember (type #\F) :calling (float-dispatch flag width  
precition size)))
    (cons #\g (remember (type #\G) :calling (float-dispatch flag width  
precition size)))
    (cons #\G (remember (type #\G) :calling (float-dispatch flag width  
precition size)))
    (cons #\i (remember (type #\D) :calling (integer-dispatch flag width  
precition size)))
    (cons #\n #'ignore-dispatch)
    (cons #\o (remember (type #\O) :calling (integer-dispatch flag width  
precition size)))
    (cons #\p (remember (type #\X) :calling (integer-dispatch flag width  
precition size)))
    (cons #\u (remember (type #\D) :calling (integer-dispatch flag width  
precition size)))
    (cons #\s #'string-dispatch)
    (cons #\x (remember (type #\X) :calling (integer-dispatch flag width  
precition size)))
    (cons #\X (remember (type #\X) :calling (integer-dispatch flag width  
precition size)))
    (cons #\% #'identity-dispatch)))

(declaim (inline read-int-string-i))
(defun read-int-string-i (istream)
   (with-output-to-string (ostream)
     (when (member (peek-char nil istream) *sign*)
       (write-char (read-char istream) ostream))
     (loop for char = (read-char istream) until (not (member char *digits*))
           do (write-char char ostream)
           finally (unread-char char istream))))

(defun read-int-string (istream)
   (let ((it (read-int-string-i istream)))
     (if (= (length it) 0)
         nil
       it)))

(defun printf->format (format)
   (with-output-to-string (ostream)
     (with-input-from-string (istream format)
       (loop with flag = nil
             with width = nil
             with precition = nil
             with size = nil
             for char = (read-char istream nil 'EOF) until (not (characterp  
char)) do
             (if (char= char #\%)
                 (progn
                   (when (member (peek-char nil istream) *flags*)
                     (setf char (read-char istream))
                     (setf flag char))
                   (setf width (read-int-string istream))
                   (setf char (read-char istream))
                   (when (char= char #\.)
                     (setf precition (read-int-string istream))
                     (setf char (read-char istream)))
                   (when (member char *size*)
                     (setf size char)
                     (setf char (read-char istream)))
                   (aif (assoc char *type-dispatcher*)
                        (write-string (funcall (cdr it) flag width  
precition size) ostream)
                        (error 'printf-error :ch char))
                   (setf flag nil width nil precition nil size nil))
               (princ char ostream))))))

(define-compiler-macro printf->format (&whole whole format)
     (if (stringp format)
         (printf->format format)
       whole))

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Joerg Hoehle
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <uhd7vql4w.fsf@users.sourceforge.net>
"John Thingstad" <··············@chello.no> writes:


><······@users.sourceforge.net> wrote:
>> Why is that actually a reader macro?
Minutes after I posted this, I realised it need be because of "\n and
the other \t": escape hell. I canceled my post but it was too late :)

> Well I mentioned something about a improved version so here goes.

> (set-dispatch-macro-character #\# #\"
You should not alter the readtable if you are a library
provider. Instead, you can provide the dispatcher as a named function,
and/or provide an install-C-reader function (that could take an
optional dispatch character as argument, defaulting to #")

Incidentally, CLISP already uses #".  It will be hard to find one that
pleases everybody.

>   ;; built with LIST and CONS so it's legal to modify it
>   (list
>    (cons #\a #\Bell)
>    (cons #\b #\Backspace)
Most of these are not in ANSI-CL, so you may get compatibility issues.
You may try and use CODE-CHAR instead (presupposes ASCII).

> ;;; Format of printf %[Flags][Width].[Precition][Size][Type]
"Recent" additions are some %lld or something like that for the long long type.

Maybe there's enough value in the "foo\n" -> "foo#\Newline" converter
to export it on its own?  (Or just the stream-(not string) reading
version that the character macro dispatcher uses internally?)
defun READ-C-STRING (stream &optional recursive/eof-etc.)
  "read until closing \", substituting \\-characters"

Spelling: preciSion, not precition

>(defmacro remember ((name value) calling (function &rest args))
>(defparameter *type-dispatcher*
>    (cons #\d (remember (type #\D) :calling (integer-dispatch flag width  
>precition size)))

I don't understand what you're trying to achieve with this remember
code. As you're already creating a lambda, why not add the one
variable as an extra and constant parameter to the function you invoke?
(integer-dispatch flag width precision size type-as-#\D)
or
(integer-dispatch type-as-#\D flag width precision size)


Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: John Thingstad
Subject: Re: hoots n hollers with c2lisp
Date: 
Message-ID: <op.s3uiazqqpqzri1@mjolner.upc.no>
On Mon, 23 Jan 2006 11:44:15 +0100, Joerg Hoehle  
<······@users.sourceforge.net> wrote:

> You should not alter the readtable if you are a library
> provider. Instead, you can provide the dispatcher as a named function,
> and/or provide an install-C-reader function (that could take an
> optional dispatch character as argument, defaulting to #")

Good idea..

>> (defmacro remember ((name value) calling (function &rest args))
>> (defparameter *type-dispatcher*
>>    (cons #\d (remember (type #\D) :calling (integer-dispatch flag width
>> precition size)))
>
> I don't understand what you're trying to achieve with this remember
> code. As you're already creating a lambda, why not add the one
> variable as an extra and constant parameter to the function you invoke?
> (integer-dispatch flag width precision size type-as-#\D)
> or
> (integer-dispatch type-as-#\D flag width precision size)
>

Well It looked great at 3 am..
The next day it just seemed inefficient,
but I didn't get around to changing it..

Well I'll look ino the issues you mentioned.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/