Moggi documentation

Development

Working on the compiler itself. To use Moggi, start at quickstart.md: a release distribution already carries every runtime it needs, and none of what follows is needed for that.

Nix is the development environment, on Linux and macOS. It pins every Toolchain the compiler and the test suite use: PHP 8.5.7, nginx 1.31.1, .NET SDK 8, GraalVM CE (Java 21+). On Windows, or without Nix, php moggi.php and php test.php run the same two entry points with whatever is installed.

Setup

Install Nix (multi-user / daemon mode):

curl -L https://nixos.org/nix/install | sh -s -- --daemon

After installation, log out and back in (or run newgrp nix-users) so your user can access the Nix daemon.

Development shell

From the project root:

nix develop

This drops you into a shell with PHP, Java/GraalVM, and the .NET SDK on your PATH. Commands: moggi, runtest.

Optional: direnv

If you use direnv, the dev shell loads automatically when you cd into the project:

direnv allow

Building

Compile a single file:

moggi compile examples/twice                 # single deployable artifact (Main.phar)
moggi compile examples/twice -o app.phar     # artifact at an explicit path
moggi compile examples/twice -o out --unpacked # unpacked/development build (directory tree)

Compile a directory tree (preserves layout under the output dir):

moggi compile src -o out
moggi compile lib -o out/lib

Inspect the pipeline:

moggi compile examples/twice/Main.mog --ast
moggi compile examples/twice/Main.mog --ir
moggi compile examples/twice/Main.mog --opt-ir
moggi compile examples/twice/Main.mog --no-opt

Run moggi --help for the full option list.

Versions

The compiler’s version is a plain-text VERSION file; the standard library’s is the [package] version of its own manifest. moggi version reports both alongside the compiler fingerprint and the host toolchains:

cat VERSION            # compiler version
cat lib/base.moggi     # standard-library version, from [package]
moggi version          # versions + fingerprint + php/java/dotnet
moggi version --json

They are separate files on purpose: the compiler and the stdlib can be released independently. Cutting a release is a one-line edit to the relevant file — the number is read at run time, never compiled in.

The fingerprint is a hash of the compiler’s own sources, the same value the compile cache is keyed by. It identifies the exact build behind an artifact even when the version number has not moved.

Tests

runtest

Or php test.php from the project root. See testing.md.

Debugging a hang

When a compile or a test run spins without making progress, sample the running process instead of bisecting commits. phpspy dumps the PHP stacks of a live process:

git clone https://github.com/adsr/phpspy.git tools/phpspy   # add tools/ to .git/info/exclude
cd tools/phpspy && make
./phpspy --limit=1000 --pid=$(pgrep -n php) > /tmp/php.traces

Keep the clone local — .git/info/exclude is untracked, so the tool stays out of git status and never becomes part of the repository. It needs ptrace permission on the target (sudo or a permissive kernel.yama.ptrace_scope); without it the trace comes back empty, which is not evidence of a bug. Reproduce the hang as a direct moggi.php compile invocation first, then sample that pid.


Moggi compiles to PHP, the JVM and .NET. This site is generated from docs/ in the moggi-lang/moggi repository; the same pages are readable there as Markdown.