From: funkyj
Subject: OT: sexps for other languages?
Date: 
Message-ID: <1155842362.781184.17930@p79g2000cwp.googlegroups.com>
Where I work all of the code we write is C or assembly (for
special firmware).

the firmware I have to work on uses a C like preprocessor with a
macro system that is a little more powerful than C's.

One of the big challenges is that some branch instructions have
1, 2 or 3 committed slots (instructions after the branch that are
always executed regardless of which branch is taken) and these
are inside of parameterized macros.

As I tinkered with this maze of twisty passages that all looked
alike I was thinking "if I had lisp macros this code could be a
lot simpler!".

For example, some macros take as a parameter a list of
instructions that are suppose to go in a committed slot.  There
are all sorts of restrictions that must be enforced (no branches
in a committed slot, the committed slot is exactly <n>
instructions big, etc...).  The assembler will warn me of some
mistakes but others (e.g. for the list of committed slot
instructions I pass a macro name and this macro expands to 6
instructions leaving 3 instructions that fall outside of the
committed slot -- not the intent of the macro).

So this got me to thinking ...

* maybe I should write a new language, called "(incf asm)".
  Following in the tradition of early C++, this language would be
  a preprocessor that outputs my firmware assembler's source
  code.  The preprocessor would be implemented in CL and (I hope)
  would leverage CL's parser logic and macro facility.

This immediately leads to a family of similar ideas:

* implement an sexp based C language
* implement an sexp based <insert language name here>

there are many reasons to implement some things in C or assembly
so why not create versions of these languages that use
s-expressions?  This one small change would provide these
languages with much of the macro power lisp enjoys!

Of course you need to know 2 languages to get the full power out
of these sexp variants (CL and the target language).  If you have
heard of this being done before please share what you can.


Coming back to the (incf asm) topic: I'm still very much a lisp
newbie.  Can folks outline how I can best leverage my lisp system
(I have access to CMUCL and CLISP) so that can implement the file
handling and language parsing of (incf asm) with as little coding
as possible?

Do I read in the (incf asm) source file and feed it to lisp's
'eval' function?

While coming up with a preprocessor that translates (incf C) into
C might be some work, creating an (incf asm) to asm preprocessor
should be much easier as asm syntax is already very regular.  Any
suggestions as to how to (incf asm) preprocessor easy to
implement while also keeping the (incf asm) syntax terse and
readable would be helpful.

Regards,
  --fj

From: Ari Johnson
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <87k6572mhy.fsf@bender.theari.com>
"funkyj" <······@gmail.com> writes:

> Do I read in the (incf asm) source file and feed it to lisp's
> 'eval' function?

Not to EVAL.  You would write your own compiler that translates from
Lisp-looking input to assembly-looking output.
From: funkyj
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <1155843793.470751.59790@i42g2000cwa.googlegroups.com>
Ari Johnson wrote:
> "funkyj" <······@gmail.com> writes:
>
> > Do I read in the (incf asm) source file and feed it to lisp's
> > 'eval' function?
>
> Not to EVAL.  You would write your own compiler that translates from
> Lisp-looking input to assembly-looking output.

OK, but how do I leverage the existing lisp parser to generate lisp
lists that represent the source code?

  I'm hoping that I don't have to reinvent the wheel with regards to
parsing (incf asm) source.   I want the general syntax of (incf asm) to
be identical to lisp (i.e. lists are enclosed in parens, single quote
and backquote semantics don't change)

example:

this
  ;; deposit bit field, <src reg> <starting src bit> <bitfield width>
<dst reg> <dst bit>
  (:depb :r7 5 3 :r22 4)

and this

  (:define_const x 4)
  (:define_const z 16)
  (:depb :r7 (+ x 1) 3 :r22 (/ z 4))

would generate the same assembly code.

    depb r7 5 3 r22 4

Cheers,
  --fj
From: Ari Johnson
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <874pwbrv0w.fsf@bender.theari.com>
"funkyj" <······@gmail.com> writes:

> Ari Johnson wrote:
> > "funkyj" <······@gmail.com> writes:
> >
> > > Do I read in the (incf asm) source file and feed it to lisp's
> > > 'eval' function?
> >
> > Not to EVAL.  You would write your own compiler that translates from
> > Lisp-looking input to assembly-looking output.
> 
> OK, but how do I leverage the existing lisp parser to generate lisp
> lists that represent the source code?

You may want to check out the "parenscript" utility.  It converts from
s-expressions to JavaScript.

>   I'm hoping that I don't have to reinvent the wheel with regards to
> parsing (incf asm) source.   I want the general syntax of (incf asm) to
> be identical to lisp (i.e. lists are enclosed in parens, single quote
> and backquote semantics don't change)

See the function named READ.

> example:
> 
> this
>   ;; deposit bit field, <src reg> <starting src bit> <bitfield width>
> <dst reg> <dst bit>
>   (:depb :r7 5 3 :r22 4)
> 
> and this
> 
>   (:define_const x 4)
>   (:define_const z 16)
>   (:depb :r7 (+ x 1) 3 :r22 (/ z 4))

Why not just write it all in Common Lisp and have a few functions that
happen to output assembly code?  For instance:

(in-package "ASSEMBLY-CODE-LIBRARY")

(defun depb (reg1 arg1 arg2 reg2 arg3)
  (format *assembly-output* "~&depb ~A ~D ~D ~A ~D"
          (register-name reg1)
          (coerce arg1 'integer)
          (coerce arg2 'integer)
          (register-name reg2)
          (coerce arg3 'integer)))


(in-package "SOME-ACTUAL-PROGRAM")

(defun do-something-cool ()
  (depb :r7 (+ x 1) 3 :r22 (/ z 4)))
From: Jack Unrue
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <ojj9e2tbmmdcf36tthf5jtkfohs4nf8dfq@4ax.com>
On 17 Aug 2006 12:43:13 -0700, "funkyj" <······@gmail.com> wrote:
> 
> Ari Johnson wrote:
> > "funkyj" <······@gmail.com> writes:
> >
> > > Do I read in the (incf asm) source file and feed it to lisp's
> > > 'eval' function?
> >
> > Not to EVAL.  You would write your own compiler that translates from
> > Lisp-looking input to assembly-looking output.
> 
> OK, but how do I leverage the existing lisp parser to generate lisp
> lists that represent the source code?
> 
>   I'm hoping that I don't have to reinvent the wheel with regards to
> parsing (incf asm) source.   I want the general syntax of (incf asm) to
> be identical to lisp (i.e. lists are enclosed in parens, single quote
> and backquote semantics don't change)
> 
> example:
> 
> this
>   ;; deposit bit field, <src reg> <starting src bit> <bitfield width>
> <dst reg> <dst bit>
>   (:depb :r7 5 3 :r22 4)
> 
> and this
> 
>   (:define_const x 4)
>   (:define_const z 16)
>   (:depb :r7 (+ x 1) 3 :r22 (/ z 4))
> 
> would generate the same assembly code.
> 
>     depb r7 5 3 r22 4

You may want to read Chapters 30 & 31 of PCL, which explain the
implementation of an HTML generation language. Your target is an
assembly syntax, but you'll find that the underlying concepts apply
just as well. Note in particular that you can support arbitrary Lisp
expressions within your language and Peter Seibel explains how to do
that in those chapters.

-- 
Jack Unrue
From: Rob Thorpe
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <1155894862.519244.55990@75g2000cwc.googlegroups.com>
funkyj wrote:
> Ari Johnson wrote:
> > "funkyj" <······@gmail.com> writes:
> >
> > > Do I read in the (incf asm) source file and feed it to lisp's
> > > 'eval' function?
> >
> > Not to EVAL.  You would write your own compiler that translates from
> > Lisp-looking input to assembly-looking output.
>
> OK, but how do I leverage the existing lisp parser to generate lisp
> lists that represent the source code?

Read about "read" and "print" and what they do in detail.

See also Sassy, which someone mentioned earlier, it does fairly much
what you are talking about.
From: Scott Bell
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <1155855392.619446.259060@m79g2000cwm.googlegroups.com>
I'm not sure if this is helpful to you or not (not Common Lisp),
but there's a full x86 assembler written in mostly-R5RS Scheme
called "Sassy": http://home.earthlink.net/~krautj/sassy/sassy.html

It seems like an interesting project, and folks are already using
it to generate native code from high-level languages such as Scheme
(e.g. Larceny x86).
From: Tim Bradshaw
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <ec45ap$bsc$1$830fa795@news.demon.co.uk>
On 2006-08-17 20:19:22 +0100, "funkyj" <······@gmail.com> said:

> Do I read in the (incf asm) source file and feed it to lisp's
> 'eval' function?

Probably not.  You read the source file and pass it to transformation 
tools that you write.  This isn't as hard to do as you might think, 
fortunately - remember you can use all the destructuring tools etc that 
the language gives you, and backquote etc.

--tim
From: Paolo Amoroso
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <8764gq752w.fsf@plato.moon.paoloamoroso.it>
"funkyj" <······@gmail.com> writes:

> * maybe I should write a new language, called "(incf asm)".
>   Following in the tradition of early C++, this language would be
>   a preprocessor that outputs my firmware assembler's source
>   code.  The preprocessor would be implemented in CL and (I hope)
>   would leverage CL's parser logic and macro facility.

See:

  http://www.cl-user.net/asp/search?search=assembler


Paolo
-- 
Why Lisp? http://wiki.alu.org/RtL%20Highlight%20Film
The Common Lisp Directory: http://www.cl-user.net
From: Pascal Bourguignon
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <87zme2hy3x.fsf@thalassa.informatimago.com>
"funkyj" <······@gmail.com> writes:
> * maybe I should write a new language, called "(incf asm)".
>   Following in the tradition of early C++, this language would be
>   a preprocessor that outputs my firmware assembler's source
>   code.  The preprocessor would be implemented in CL and (I hope)
>   would leverage CL's parser logic and macro facility.

Writting an assembler is Lisp is easy.  

You benefit immediately of Lisp macros, and can use any lisp function
at macro-expansion / assembly time.

You may have to be careful not to mixup the phases however.  Just
provide a driver to read and process at (CL) run-time the LAP forms
and "assemble" with an explicit macro-expansion phase.

There are various examples of sexpified java too:
http://www.franz.com/support/documentation/6.2/doc/jil.htm


> This immediately leads to a family of similar ideas:
>
> * implement an sexp based C language
> * implement an sexp based <insert language name here>
>
> there are many reasons to implement some things in C or assembly
> so why not create versions of these languages that use
> s-expressions?  This one small change would provide these
> languages with much of the macro power lisp enjoys!

There are already some options for sexps to C.  
For example, gcl and CLiCC.

http://www.cliki.net/CLiCC
CLiCC starts from:

    ;;---------------------------------------------------------------------
    ;; TAILP sublist list
    ;;---------------------------------------------------------------------
    (defun tailp (sublist list)
      (cond
        ((eql sublist list) t)
        ((atom list) nil)
        (t (tailp sublist (cdr list)))))


and generates:

    void Ftailp(CL_FORM *base)
    {
        M1_1:;
        if(EQL(ARG(0), ARG(1)))
        {
            LOAD_SYMBOL(SYMBOL(Slisp, 48), ARG(0));	/* T */
        }
        else
        {
            if(CL_ATOMP(ARG(1)))
            {
                LOAD_NIL(ARG(0));
            }
            else
            {
                COPY(GET_CDR(ARG(1)), ARG(2));
                COPY(ARG(2), ARG(1));
                goto M1_1;
            }
        }
        goto RETURN1;
        RETURN1:;
    }



However, I wouldn't say that the generated C source is entirely human
readable or maintenable (even if it's one objective of CLiCC,
contrarily to gcl).  At least, it couldn't pass for C code to a customer...


I'd want it to generate something more like:

   /*---------------------------------------------------------------------*/
   /* TAILP sublist list                                                  */
   /*---------------------------------------------------------------------*/
   bool tailp(object_t* sublist,object_t* list){
        if(sublist==list){
            return(true);
        }else if(atom(list)){
            return(false);
        }else{
            return(tailp(sublist,list_rest((list_t*)list)));
        }}

I started such a project, but could work on it only two days in the
past year.



> Coming back to the (incf asm) topic: I'm still very much a lisp
> newbie.  Can folks outline how I can best leverage my lisp system
> (I have access to CMUCL and CLISP) so that can implement the file
> handling and language parsing of (incf asm) with as little coding
> as possible?

The most tedious part is to collect the processor CodOps.  If you can
copy-and-paste from some computer readable reference, all the better.
Beware that often the description of the codops in the processor
reference manuals display _less_ orthogonality than exist really in
the processor instruction sets.  So you may need to process manually
these descriptions.  An good alternative would be to get them from gcc.

Next, you have to streamline and sexpify the assembler instruction syntax.

Instead of writing:

        cntr   eql -16(a5)
        offset eql 4
        flag   eql -12
    fnc1:
        move.l offset(a0),d3
        move.b d3,flag(a7)
        asr.l #8,d3
        move.w d3,cntr
        ret

You'd write:

(define cntr (-16 a5)
(define offset 4)
(define flag -12)

(deflap fnc1
  (move.l (a0 offset) d3)
  (move.b d3 (a5 flag))
 label
  (asr.l  (imm 8)  d3) ; or you could have a reader macro for #immediate
  (move.w d3  cntr)
  (bne.s label)
  (ret))


Once you have sexps, anything else can be done with lisp macros and
functions.


> Do I read in the (incf asm) source file and feed it to lisp's
> 'eval' function?

No.  
It's simplier to have a ASSEMBLE function similar to COMPILE.
It would read the assembler source file forms, macroexpand them, and
translate the LAP to vectors of bytes written to the binary file.

If your lisp implementation allows you to insert in the system new
executable code (at worse, you could copy the assembled bytes to a FFI
allocated buffer and call a FFI C function to execute them), then you
could have a macro to assemble in core, and to call these functions.


(defasm <lisp-function-name> (<lisp-arguments>)
  "some doc"
  (move.l (a0 offset) d3)
  (move.b d3 (a5 flag))
 label
  (asr.l  (imm 8)  d3) ; or you could have a reader macro for #immediate
  (move.w d3  cntr)
  (bne.s label)
  (ret))

But this defasm is a lisp macro easily written. It would call the
assembler, store the bytes, keep a map of the function name to the
bytes, and generate a lisp function to call it.


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

This universe shipped by weight, not volume.  Some expansion may have
occurred during shipment.
From: Debian User
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <44e8b44e$0$11660$dbd4f001@news.wanadoo.nl>
Maybe a bit different than a CL solution, but there is a emacs lisp
based c preprocessor available:

cgen.el
elpp.el 
elppc.el

Basically it allows you to insert elisp in your c code and to
autogenerate c code from elisp s-expressions.
From: funkyj
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <1156218703.245998.156190@m73g2000cwd.googlegroups.com>
Thanks everyone for the interesting suggestions.

I think I want to generate assembly source that is processed by the
network processor's proprietary assembler so the PCL 'html generation'
chapter sounds the most promising (low hanging fruit).

None the less, all the comments gave me lots to think about.

   ...

Regarding CLiCC example given by Pascal B:

That looks like lisp that compiles to C as an intermediate language.  I
was thinking along the lines of the C language (no built in garbage
collection, you still have printf, malloc, free, char, int, struct
etc.) with the only change being that sexps are used rather than the
standard C syntax.  The idea is that you would still be writing regular
C code but you would have access to CL as a macro language.

In other words I am shooting for the simplest answer to the question:
how can I give my asm or C language lisp macros?

Thanks again for all the interesting replies!

  --fj
From: Juho Snellman
Subject: Re: OT: sexps for other languages?
Date: 
Message-ID: <slrneel0nv.njt.jsnell@sbz-30.cs.Helsinki.FI>
funkyj <······@gmail.com> wrote:
> That looks like lisp that compiles to C as an intermediate language.  I
> was thinking along the lines of the C language (no built in garbage
> collection, you still have printf, malloc, free, char, int, struct
> etc.) with the only change being that sexps are used rather than the
> standard C syntax.  The idea is that you would still be writing regular
> C code but you would have access to CL as a macro language.

Have a look at scexp.

-- 
Juho Snellman