Skip to content

maltasea/lua_of_ocaml

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

80 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

loo chicken

lua_of_ocaml

ocaml >> lua 5.1

home · source

Compiles OCaml bytecode programs to Lua 5.1, inspired by js_of_ocaml.

Note: this project was written in a heavily guided, multi-hour chat session with Claude Code. Most of it with Model: Deepseek v4.0, and some Opus 4.7 — nothing agentic.

first steps

install

opam install js_of_ocaml-compiler
git clone git@github.com:maltasea/lua_of_ocaml.git
cd lua_of_ocaml
dune build

run hello world

echo 'let () = print_endline "hello from lua"' > hello.ml
make hello

hello from lua

your own programs

Edit hello.ml, then make hello.

any bytecode

./loo.sh prog.ml              # .ml → stdout
./loo.sh prog.ml out.lua      # .ml → out.lua
lua out.lua

./loo.sh is generated by make — no install needed.

how it works

ocaml source
 → ocamlc → bytecode
  → jsoo parser (reused)
    → IR (Code.program)
      → generate_lua.ml → Lua AST
        → output_lua.ml → .lua text
          + runtime/lua/*.lua
          → luajit hello.lua

The IR from js_of_ocaml is target-agnostic. lua_of_ocaml reuses the bytecode parser and optimizations, and provides a structural CFG code generator modeled on js_of_ocaml's generate.ml.

files

file what
compiler/lib/lua.ml lua 5.1 ast
compiler/lib/output_lua.ml lua pretty printer
compiler/lib/generate_lua.ml ir → lua
compiler/bin-lua_of_ocaml/ cli tool
runtime/lua/*.lua lua runtime
test/ tests

ffi: ocaml talking to lua

external becomes a direct lua call. dummy c stub for linking.

(* mylib.ml *)
external lua_add : int -> int -> int = "lua_add"

/* mylib_stubs.c — just so ocamlc links */
#include <caml/mlvalues.h>
CAMLprim value lua_add(value a, value b) { return Val_int(0); }

ocamlc -c mylib_stubs.c
ocamlc -c mylib.ml
ocamlc -custom -o mylib.byte mylib_stubs.o mylib.cmo
./loo.sh mylib.byte -o mylib.lua

ocaml values in lua: ints tagged n*2, floats boxed {253, v}, strings plain, blocks {tag, f1, f2, ...}.

real example: example-game/ — löve2d chicken jump.

source tracing

generated lua has --# file:line markers. use ocamlc -g.

tests

make test                          # 26 tests
bash test/behavioral/run.sh        # 5 behavioral tests

license

lgpl-2.1-or-later with ocaml-lgpl-linking-exception (same as jsoo)

made in a long chat with claude code — nothing agentic, just vibes

lua_of_ocaml — ocaml → lua 5.1

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors