SkillAgentSearch skills...

Elvm

EsoLangVM Compiler Infrastructure

Install / Use

/learn @shinh/Elvm
About this skill

Quality Score

0/100

Category

Operations

Supported Platforms

Universal

README

ELVM Compiler Infrastructure

Build Status

ELVM is similar to LLVM but dedicated to Esoteric Languages. This project consists of two components - frontend and backend. Currently, the only frontend we have is a modified version of 8cc. The modified 8cc translates C code to an internal representation format called ELVM IR (EIR). Unlike LLVM bitcode, EIR is designed to be extremely simple, so there's more chance we can write a translator from EIR to an esoteric language.

Currently, there are 60 backends:

  1. Acc!!
  2. Aheui
  3. Awk (by @dubek)
  4. Befunge
  5. Binary Lambda Calculus (by @woodrush)
  6. Brainfuck
  7. C
  8. C++14 constexpr (compile-time) (by @kw-udon)
  9. C++ Template Metaprogramming (compile-time) (by @kw-udon) (WIP)
  10. C# (by @masaedw)
  11. C-INTERCAL
  12. CMake (by @ooxi)
  13. CommonLisp (by @youz)
  14. Conway's Game of Life (via QFTASM) (by @woodrush)
  15. Crystal (compile-time) (by @MakeNowJust)
  16. Emacs Lisp
  17. F# (by @masaedw)
  18. Forth (by @dubek)
  19. Fortran (by @samcoppini)
  20. Go (by @shogo82148)
  21. Go text/template (Gomplate) (by @Syuparn)
  22. Grass (by @woodrush)
  23. HeLL (by @esoteric-programmer)
  24. J (by @dubek)
  25. Java
  26. JavaScript
  27. Kinx (by @Kray-G)
  28. Lambda calculus (by @woodrush)
  29. Lazy K (by @woodrush)
  30. LLVM IR (by @retrage)
  31. LOLCODE (by @gamerk)
  32. Lua (by @retrage)
  33. Octave (by @inaniwa3)
  34. Perl5 (by @mackee)
  35. PHP (by @zonuexe)
  36. Piet
  37. POSIX Shell
  38. Python
  39. Ruby
  40. Scheme syntax-rules (by @zeptometer)
  41. Scratch3.0 (by @algon-320)
  42. SQLite3 (by @youz)
  43. SUBLEQ (by @gamerk)
  44. Swift (by @kwakasa)
  45. Tcl (by @dubek)
  46. TeX (by @hak7a3)
  47. TensorFlow (WIP)
  48. Turing machine (by @ND-CSE-30151)
  49. Unlambda (by @irori)
  50. Universal Lambda (by @woodrush)
  51. Vim script (by @rhysd)
  52. WebAssembly (by @dubek)
  53. WebAssembly System Interface (by @sanemat)
  54. Whirl by (@samcoppini)
  55. W-Machine by (@jcande)
  56. Whitespace
  57. arm-linux (by @irori)
  58. i386-linux
  59. sed

The above list contains languages which are known to be difficult to program in, but with ELVM, you can create programs in such languages. You can easily create Brainfuck programs by writing C code for example. One of interesting testcases ELVM has is a tiny Lisp interpreter. The all above language backends are passing the test, which means you can run Lisp on the above languages.

Moreover, 8cc and ELVM themselves are written in C. So we can run a C compiler written in the above languages to compile the ELVM's compiler toolchain itself, though such compilation takes long time in some esoteric languages.

A demo site

http://shinh.skr.jp/elvm/8cc.js.html

As written, ELVM toolchain itself runs on all supported language backends. The above demo runs ELVM toolchain on JavaScript (thus slow).

Example big programs

ELVM internals

ELVM IR

  • Harvard architecture, not Neumann (allowing self-modifying code is hard)
  • 6 registers: A, B, C, D, SP, and BP
  • Ops: mov, add, sub, load, store, setcc, jcc, putc, getc, and exit
  • Psuedo ops: .text, .data, .long, and .string
  • mul/div/mod are implemented by _builtin*
  • No bit operations
  • No floating point arithmetic
  • sizeof(char) == sizeof(int) == sizeof(void*) == 1
  • The word-size is backend dependent, but most backend uses 24bit words
  • A single programming counter may contain multiple operations

See ELVM.md for more detail.

Directories

shinh/8cc's eir branch is the frontend C compiler.

ir/ directory has a parser and an interpreter of ELVM IR. ELVM IR has

target/ directory has backend implementations. Code in this directory uses the IR parser to generate backend code.

libc/ directory has an incomplete libc implementation which is necessary to run tests.

Notes on language backends

Brainfuck

Running a Lisp interpreter on Brainfuck was the first motivation of this project (bflisp). ELVM IR is designed for Brainfuck but it turned out such a simple IR could be suitable for other esoteric languages.

As Brainfuck is slow, this project contains a Brainfuck interpreter/compiler in tools/bfopt.cc. You can also use other optimized Brainfuck implementations such as tritium. Note you need implementations with 8bit cells. For tritium, you need to specify `-b' flag.

Unlambda

This backend was contributed by @irori. See also 8cc.unl.

This backend is tested with @irori's interpreter. tools/rununl.sh automatically downloads it.

C-INTERCAL

This backend uses 16bit registers and address space, though ELVM's standard is 24bit. Due to the lack of address space, you cannot compile large C programs using 8cc on C-INTERCAL.

This backend won't be tested by default because C-INTERCAL is slow. Use

$ CINT=1 make i

to run them. Note you may need to adjust tools/runi.sh.

You can make faster executables by doing something like

$ cp out/fizzbuzz.c.eir.i fizzbuzz.i && ick fizzbuzz.i
$ ./fizzbuzz

But compilation takes much more time as it uses gcc instead of tcc.

Piet

This backend also has 16bit address space. There's the same limitation as C-INTERCAL's.

This backend won't be tested by default because npiet is slow. Use

$ PIET=1 make piet

to run them.

Befunge

BefLisp, which translates LLVM bitcode to Befunge, has very similar code. The interpreter, tools/befunge.cc is mostly Befunge-93, but its address space is extended to make Befunge-93 Turing-complete.

Whitespace

This backend is tested with @koturn's Whitespace implementation.

Emacs Lisp

This backend is somewhat more interesting than other non-esoteric backends. You can run a C compiler on Emacs:

  • M-x load-file tools/elvm.el
  • open test/putchar.c (or write C code without #include)
  • M-x 8cc
  • Now you'll see ELVM IR. You need to prepend a backend name (`el' for example) as the first line.
  • M-x elc
  • M-x eval-buffer
  • M-x elvm-main

Vim script

This backend was contributed by @rhysd. You can run a C compiler on Vim:

  • Open test/hello.c (or write your C code)
  • :source /path/to/out/8cc.vim
  • Now you can see ELVM IR in the buffer
  • Please prepend a backend name (vim for Vim) to the first line
  • :source /path/to/out/elc.vim
  • You can see Vim script code as the compilation result in current buffer
  • You can :source to run the code

You can find more descriptions and released vim script in 8cc.vim.

TeX

This backend was contributed by @hak7a3. See also 8cc.tex.

C++14 constexpr (compile-time)

This backend was contributed by @kw-udon. You can find more descriptions in constexpr-8cc.

sed

This backend is very slow so only limited tests run by default. You can run them by

$ FULL=1 make sed

but it could take years to run all tests. I believe C compiler in sed works, but I haven't confirmed it's working yet. You can try Lisp interpreter instead:

$ FULL=1 make out/lisp.c.eir.sed.out.diff
$ echo '(+ 4 3)' | time sed -n -f out/lisp.c.eir.sed

This backend should support both GNU sed and BSD sed, so this backend is more portable than sedlisp, though much slower. Also note, due to limitation of BSD sed, programs cannot output non-ASCII characters and NUL.

HeLL

This backend was contributed by [@esoteric-programmer](https://github.com/esoter

View on GitHub
GitHub Stars1.2k
CategoryOperations
Updated8h ago
Forks147

Languages

C

Security Score

95/100

Audited on Apr 5, 2026

No findings