Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
A Lisp to Lua compiler. Reader Macros, Macros, Lambdas, Lua functions...
Lua Common Lisp NewLisp
Branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
.gitignore
LICENSE Add more operators, Fix Let, Add license
README.markdown Added Gitter badge
compiler.lua Rewrite the core compiler to implement Reader macros.
core.lua
exception.lua
import.lua
itertools.lua
l2l
reader.lua
sample01.lsp Fix "bug" in sample01.lsp.
sample01.lua Fix "bug" in sample01.lsp.
sample02.lsp
sample02.lua
sample03.lsp
sample03.lua Rewrite the core compiler to implement Reader macros.
sample05.lsp
sample05.lua Re-compiled sample05.lsp.

README.markdown

Lisp to Lua Compiler

Join the chat at https://gitter.im/meric/l2l

A Lisp to Lua compiler, compatible with LuaJIT (built with -DLUAJIT_ENABLE_LUA52COMPAT) or Lua5.3.

Features

Contribute

Play around. Make issues. Submit pull requests. :)

How To

  • ./l2l to launch REPL.

    ;; Welcome to Lua-To-Lisp REPL!
    ;; Type '(print "hello world!") to start.
    >->o (print "Hello world!")
    Hello world!
    =   nil
    >->o 
    
  • ./l2l sample01.lsp to compile sample01.lsp and output Lua to stdout.

  • ./l2l sample01.lsp | lua to compile and run sample01.lsp immediately.
  • ./l2l sample02.lsp sample03.lsp to compile two lisp files where one requires the other.

  • Change prompt string by setting the _P global variable.

    >->o (set _P ">> ")
    =   >> 
    >> (print "Hello World")
    Hello World
    =   nil
    >> 
    
  • The read macro table is _R. _R.META stores locations of all read symbols.

    >->o (set _R.META {}) ;; _R.META is too big.
    =   table: 0x7fcf90c54c90
    >->o (show _R)
    =   {"}" function: 0x7fcf90c1a930 "META" {(show _R) {1 6 2 9 0 6}} ";" function: 0x7fcf90c1a8c0 "position" function: 0x7fcf90c1b1a0 ")" function: 0x7fcf90c1a8e0 "(" function: 0x7fcf90c1ac10 "'" function: 0x7fcf90c1ad30 "," function: 0x7fcf90c1adb0 "[" function: 0x7fcf90c1aab0 "#" function: 0x7fcf90c1adf0 "\"" function: 0x7fcf90c1a9d0 "]" function: 0x7fcf90c1a980 "`" function: 0x7fcf90c1ad70 "{" function: 0x7fcf90c1ab80}
    >->o 
    
  • The dispatch read macro table is _D.

    >->o (show _D)
    =   {"." function: 0x7fcf90c27360 " " function: 0x7fcf90c1a890 "'" function: 0x7fcf90c1acf0}
    
  • The compiler table is _C.

    >->o (show _C)
    =   {"_60_61" function: 0x7fac1bc1e4d0 "_105_102" function: 0x7fac1bc948f0 "_" function: 0x7fac1bc26280 "defcompiler" function: 0x7fac1bc266a0 "defun" function: 0x7fac1bc26820 "_111_114" function: 0x7fac1bc261c0 "quasiquote" function: 0x7fac1bc26460 "_119_104_105_108_101" function: 0x7fac1bc3b300 "cadr" function: 0x7fac1bc26780 "_35" function: 0x7fac1bc26370 "_100_111" function: 0x7fac1bc64040 "car" function: 0x7fac1bc26720 "_58" function: 0x7fac1bc26330 "_62" function: 0x7fac1bc1e570 "cond" function: 0x7fac1bc264b0 "_47" function: 0x7fac1bc262c0 "chunk" function: 0x7fac1bc4a340 "_46_46" function: 0x7fac1bc0be00 "_43" function: 0x7fac1bc26240 "_110_111_116" function: 0x7fac1bc26190 "_46" function: 0x7fac1bc26300 "_62_61" function: 0x7fac1bc26090 "quote" function: 0x7fac1bc26420 "_98_114_101_97_107" function: 0x7fac1bc6bc30 "set" function: 0x7fac1bc263a0 "table_quote" function: 0x7fac1bc263e0 "_61_61" function: 0x7fac1bc1e3d0 "defmacro" function: 0x7fac1bc717b0 "let" function: 0x7fac1bc267b0 "_42" function: 0x7fac1bc26200 "lambda" function: 0x7fac1bc26650 "_60" function: 0x7fac1bc1e450 "_97_110_100" function: 0x7fac1bc26130 "cdr" function: 0x7fac1bc26750}
    >->o 
    
  • The format of a compiler is a function with at least two arguments. For example:

    local function compile_subtract(block, stream, ...)
      return "("..map(bind(compile, block, stream), {...}):concat(" - ")..")"
    end
    

    This implements compiling (- 1 2 3) to (1 - 2 - 3).

    A compiler function inserts any non-expression Lua statements into block, and returns a single Lua expression which should either be the value or reference to the value that will be returned in its parent lisp block (which is likely to be a lisp function).

    The arguments of a function are raw lisp values, uncompiled and unprocessed. They must be compiled before being inserted into generated Lua code.

  • Use the defcompiler helper to define compilers in lisp. For example:

    (defcompiler -- (block stream str)
        (table.insert block (.. "\n--" (tostring str))))
    

    This implements comments that will be printed directly into the Lua output.

    defcompiler will put your compiler into _C table as well as activate the compiler immediately for use. Right after the above compiler declaration you can have:

    `(-- "This is a comment")`
    

    and the code will be output directly as "-- This is a comment" into the Lua source code.

  • defmacro is currently implemented like so:

    (defcompiler defmacro (block stream name parameters ...)
      (let 
        (params (list.push (list.push parameters 'stream) 'block)
         code `(defcompiler ,name ,params
                 (let (fn (eval `(lambda ,parameters ,...)))
                   (compile block stream (fn ,(list.unpack parameters))))))
        (eval code)
        (compile block stream code)))
    

TODO

  • The _R.META does not record locations accurately enough during the compiler stage.
Something went wrong with that request. Please try again.