Reverse the process of the Fennel compiler
Collapse nested . lookup calls into a single . call.
Tidy up flatten-associative function using a match.
Currently bnot is broken with --use-bit-lib; disable test for now.



You can also use your local clone with git send-email.


Turn Lua code into Fennel code. This compiler does the opposite of what the Fennel compiler does.

There is a web-based demo where you can see it in action on Fennel's web site without installing anything.


The only prerequisites are having Lua and GNU Make installed.

$ make
$ ./antifennel targetfile.lua > targetfile.fnl

The antifennel script is self-contained and can be moved or symlinked onto your $PATH; all it requires to run is Lua. It will default to using luajit but you can run make LUA=lua5.4 to override the Lua implementation.

Or during development, run without building:

$ luajit antifennel.lua targetfile.lua > targetfile.fnl


The Antifennel compiler assumes its input file is valid Lua 5.1; it does not attempt to give good error messages when provided with files that won't parse or support newer features of Lua.

Antifennel supports all bitwise operators introduced in Lua 5.3.

Antifennel will never emit variadic operators, hashfns, or pattern matches, even in cases that would result in much better code.

Fennel code does not support goto, so neither does Antifennel.

Early returns will compile to very ugly Fennel code, but they should be correct. If you want better output, consider changing the Lua code to remove early returns before running Antifennel on it; for instance here:

local function f(x)
  if x:skip() then
    return x:done()
  print(x, x.context)

... would be better as:

local function f(x)
  if x:skip() then
    return x:done()
    print(x, x.context)

This is not required, but it will result in much nicer-looking code.

Multiple value assignment doesn't work if setting table keys that aren't static. For instance, this is OK:

tbl.field1.q, x = "QUEUE", 13

But this is not supported:

tbl.field1[id], x = "IDENTIFIER", 99

The second example must be split into two separate assignments in order to compile, since tset does not support multiple value assignment in Fennel.


Included with fennel-mode is an antifennel.el file which provides integration to run from inside Emacs.


Send patches directly to the maintainer or the Fennel mailing list

Copyright © 2020-2022 Phil Hagelberg and contributors Released under the MIT/X11 license, same as Fennel

Lua parser/lexer (contents of the lang/ directory) by Francesc Abbate