git clone ''

(ql:quickload :cl-larval)


Lisp syntax for assembler for AVR microcontrollers.

VERY IMPORTANT!!!: there are a lot of assembler commands, that are named like CL builtin-functions, e.g. PUSH, SET, *, +, etc etc. To make usage of this package more convenient, only a single macro, WITH-LARVAL, is exported. Inside the body of this macro, several functions and macros are “overloaded” with their definitions in CL-LARVAL package.


    CL-USER> (+ 1 2 3) ; works as expected
    CL-USER> (cl-larval:with-larval () (+ 1 2 3)) ; and this instead generates output to STDOUT
    1 + 2 + 3

This effect is achieved using ABBROLET ir1-translator (analog of a macro), that lives in CL-CURLEX package. For now it should work under SBCL, CMUCL, CCL and ECL. If your favorite implementation is not supported, patches are very welcome.

If you still need access to CL versions of functions/macros inside the body of WITH-LARVAL, then construct their analogs in advance outside the body, for example:

    CL-USER> (flet ((cl* (&rest args) (apply #'* args)))
               (cl-larval:with-larval () (cl* 1 2 3)))

All assembler-generating functions/macros inside CL-LARVAL operate by side effect, printing output to stream STREAM, so, if you want to get assembler program as a string, use

    CL-USER> (with-output-to-string (stream)
               (cl-larval:with-larval (:stream stream)
                 (mov 'r1 'r2)
                 (push 'r3)
                   (.byte 'my-var 1))))
    "mov R1, R2
    push R3
    MY-VAR: .byte 1

The complete list of commands available is too long to place it here, so, please, consult any assembler manual for AVR microcontrollers, or the sources of this package. Note, that for readability most of the short commands, such as BRHS have corresponding long-named versions, such as BRANCH-IF-HALF-CARRY.

NOTE: to make code portable across many CL implementations, CL-PACKAGE-LOCKS package was used. However, so far it only really supports SBCL, but the situation (hopefully) will change in the near future.

TODO: the reason the sophisticated ABBROLET construction was used instead of a naive approach of a CL-DSL package is that I wanted to make SLIME hint properly, when inside WITH-LARVAL form. That is, for .DB form hint should actually be “(.db label &rest exprs)” and not some obscure “(.db &rest args)”. Right now I've implemented somewhat “dirty” way to do so - it interns many-many symbols in target package. If you know, how to avoid this, let me know.