Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Is there any example of this assembly style of programming in Lisp?


Any time people claim that Lisp is a functional programming language, I like to drag out this example posted by Joe Marshall to comp.lang.lisp[1]:

    (DEFUN RDSYL (L DF)
      (PROG (LL BRAKP ANS CH)
            (SETQ DF (MERGEF DF '((* *) * *)))
         AA (SETQ LL (SETQ BRAKP () ))
          A (SETQ CH (OR (CAR L) #/_))
            (COND ((OR (= CH #/ ) (= CH #//))     ;"/", " "
                   (POP L)
                   (SETQ CH (CAR L)))
                  ((AND (= CH #/[) (NOT #%(ITSP)))    ;"["
                   (SETQ BRAKP 'T))
                  ((AND (= CH #/]) (NOT #%(ITSP))) (SETQ BRAKP () )) ;"]"
                  ((OR (= CH #/( ) (= CH #/) )) (RETURN () ))  ;Cant have parens here
                  ((= CH #/,)     ;Comma
                   (COND ((NOT BRAKP)
                          (POP L)
                          (GO RET))))
                  ((= CH #/_) (GO RET)))
           (PUSH CH LL)
           (POP L)
           (GO A)
      RET  (SETQ DF (MERGEF (NAMELIST (MAKNAM (NREVERSE LL))) DF))
           (SETQ ANS (NCONC ANS (LIST DF)))
           (AND (= CH #/,) (GO AA))
           (RETURN ANS) ))
There is a lot of this kind of code around in the various Lisp Machine sources (CADR is legally available for poking around in[2]). Occasionally things like this pop up in contemporary Lisp compilers or IO/concurrency libraries. Some algorithms are much easier to express with goto.

[1] https://groups.google.com/forum/#!msg/comp.lang.lisp/4nwskBo...

[2] http://www.unlambda.com/cadr/


If you look at code with really low-level operators like CAR, CDR, CONS, ATOM, NULL, etc then this is the assembly level of Lisp. If you look at some Lisp Machines, which had a processor with a for Lisp optimized instruction set, many of those mapped relatively direct to corresponding machine instructions - using a mostly stack machine.

The CLISP implementation of Common Lisp has a virtual machine implementation.

Let's take some simple demonstration code:

    [1]> (defun foo (a)
            (car (cdr (if (null a)
                          '(1 2)
                          (cons 3 a)))))
    FOO
Now we compile it for the CLISP virtual machine:

    [2]> (compile 'foo)
    FOO ;
    NIL ;
    NIL
If we look at the disassembled virtual machine code, you'll see that the machine code has actually similar primitives for its stack machine:

    [3]> (disassemble 'foo)

    Disassembly of function FOO
    (CONST 0) = (1 2)
    (CONST 1) = 3
    1 required argument
    0 optional arguments
    No rest parameter
    No keyword parameters
    11 byte-code instructions:
    0     (LOAD&JMPIFNOT 1 L10)
    3     (CONST&PUSH 1)                      ; 3
    4     (LOAD 2)
    5     (CONS)
    6     L6
    6     (CDR)
    7     (CAR)
    8     (SKIP&RET 2)
    10    L10
    10    (CONST 0)                           ; (1 2)
    11    (JMP L6)
    NIL

Unrelated to that there is also the idea to program assembler code embedded in Lisp - this is often called LAP code (Lisp Assembler Program). Several implementations are using this.


SBCL is mostly written in Common Lisp. It has a compiler that can compile itself. Part of that compiler are definitions of building blocks (VOPs or virtual operations) that describe snippets of assembly code. So as always, you use the tools provided by Lisp to create a DSL that allows you to write code as is practical for your use case.

For an example look at https://github.com/sbcl/sbcl/blob/master/src/compiler/x86-64...

You can find similar code for other ISAs in neighbouring directories.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: