Haxe in Haxe

A port of the Haxe compiler from OCaml to Haxe. A C backend (hxc) compiles it to a native binary, or to WebAssembly for the playground below.

Playground

Run type-checks and runs the program with --interp. Compile to HXB writes an HXB archive. It runs locally as 64-bit WebAssembly, which needs a recent Chrome, Edge or Firefox.

Loading compiler…
Output

				
			

Completion, hover and diagnostics come from the same compiler. Download: ~2 MB of WebAssembly, ~0.2 MB of standard library. Some examples are from try.haxe.org (MIT).

Download

Builds of the latest commit on main, with the standard library included:

haxe-in-haxe -cp src --main Main --interp
haxe-in-haxe -cp src --main Main --js out.js

It takes the same arguments as haxe. The Linux and macOS builds are compiled with zig cc; like the Cosmopolitan build they carry mbedtls and libuv, so sys.ssl and eval.luv work in macros and --interp. Set HAXE_STD_PATH to the std directory in the archive. The Windows build and haxe-in-haxe.com are the Cosmopolitan build, which is slower (about 1.6× the time of the native builds on large compiles) and carries the standard library inside. All files: nightly release.

hxc for other programs

The C backend is also available as a Haxe target through the hxc haxelib package: Haxe types the program and writes HXB, hxc turns it into C, and a C compiler builds it. See hxc/haxelib/README.md.

Tools

lix.com (~6 MB): lix, the Haxe package manager, and haxeshim, ported from Haxe on Node.js and compiled by hxc into one Cosmopolitan binary for Linux, macOS, Windows and the BSDs. It is lix, haxe, haxelib and neko in one file: it acts as the command it is named or linked as.

Install it in a directory on your PATH and let it create the haxe, haxelib and neko commands next to itself (lix shims: symbolic links, or hard links on Windows). Linux and macOS:

curl -fLo ~/bin/lix https://haxe-in-haxe.ben.mk/tools/lix.com && chmod +x ~/bin/lix
lix shims

Windows (PowerShell), e.g. into C:\tools, a directory on your PATH:

curl.exe -fLo C:\tools\lix.com https://haxe-in-haxe.ben.mk/tools/lix.com
lix shims

Then, in a project: lix downloads Haxe versions and libraries into the project's scope, and haxe runs the version and libraries of the scope it is called in, so editors and build scripts that call haxe get the right ones:

lix scope create                # a .haxerc for this directory
lix install haxe 4.3.7          # download it and use it here
lix +lib tink_core              # haxe_libraries/tink_core.hxml (dependencies downloaded in parallel)
haxe -lib tink_core --run Main  # runs Haxe 4.3.7 with tink_core
lix use haxe 4.3.6              # switch to another downloaded version
lix download                    # after a clone: the scope's Haxe and missing libraries (8 at a time, LIX_JOBS)

The haxe shim adds about 2 ms to a compiler call (Node.js: about 60 ms). The compiler server modes (--wait, --server-listen, --server-connect) run on libuv with hxcoro coroutines. Compared with the npm package on 26 scenarios, output and installed files are identical. Details: tools/lix/README.md.

Status

The port follows upstream (haxe/src, commit 995a7d1) module by module. For the same arguments it should produce the same output as the reference compiler; this is tested for:

Details: test/TESTING.md.

Benchmarks

The port, built for different runtimes, compiling to HXB. CPU time, best of 3, -D disable-parallelism; a run counts only if its output is identical to the reference's.

Loading results…

With parallel passes on 4 threads, the native build compiles itself in 4.18 s (the reference with 4 domains: 4.03 s). Reproduce: site/bench/run.py.

Target generators

Compile time of the native build against the reference for each target, on two projects. CPU time, best of 3; every output file identical. C++ and HL/C stop at the generated sources.

Loading results…

Reproduce: site/bench/targets.py.