Programs written in legit are defined entirely by the commits in a Git repository. The content of the repository is ignored. legit is designed so that all relevant information is visible when running git log --graph --oneline
, see the examples below.
Influences: Folders, Befunge, Brainfuck, Elymas.
In each legit program, two data structures are available: A stack, and a brainfuck-like endless tape, with a head moving on it. Both hold signed integers.
Execution starts at the commit pointed to by the master branch. Commit messages can contain a series of instructions, seperated with spaces, which are executed one by one. Only the first line is considered, so lines after that can be used for comments.
- If a commit has only one parent, execution will continue there after executing all instructions in the current commit.
- If a commit has multiple parents (numbered 0, 1, 2, ...), the top stack element will be popped. If that element is n, to go n-th parent, or to the last one, if n is outside of the available range.
For all instructions, popping from the empty stack will return a value of 0.
Control flow:
[<tag>]
: jump to the specified Git tag. For example,[loop]
will jump to the tag loop.quit
: stop the program.
I/O:
get
: read a char from standard input and place its ASCII value on the stack. On EOF, push a 0.put
: pop top stack value and write it to standard output as a char. The value is always truncated to an unsigned byte.<Number>
: push the specified integer on the stack. For example,42
will push the value 42."<Letters>"
: unescape string, then push the individual ASCII characters on the stack. For example,"Hi\n"
will push the numbers 72, 105, and 10.
Stack operations:
dup
: duplicate top stack valuepop
: pop top stack value and discard itadd
: pop two topmost stack values, add them, push result on the stacksub
: pop two topmost stack values, subtract top one from bottom one, push result on the stackcmp
: pop two topmost stack values, pushes 1 if bottommost one is larger, 0 otherwise
Tape operations:
read
: place value of current tape cell on the stackwrite
: pop top stack value and write it to the current tape cellleft
: pop top stack value, move tape head left for that many placesright
: pop top stack value, move tape head right for that many places
legit
comes with some examples: You can generate them like this:
make -C examples
Alternatively, you can also clone them directly from GitHub:
A simple hello world program.
A ROT13 implementation.
A fully-functioning Brainfuck interpreter!
This program outputs the Git commands required to create itself.
This doesn't actually exist yet. I challenge you to write it! :)
This repository provides both an interpreter (better suited for development and debugging purposes) and a compiler (which produces highly efficient binaries).
For both, you'll need Ruby, and the "rugged" Gem:
gem install rugged
To execute a program, run
ruby interpreter.rb examples/hello/
The compiler compiles a legit program to LLVM IR. You can then use LLVM tools to build binaries for all plaforms where you have a C standard library available (legit will be linked with exit
, getchar
and putchar
).
First, run the compiler to create a .ll file:
ruby compiler.rb examples/hello/
And then, run a tool like clang
to optimize it and produce a binary:
clang -O3 hello.ll -o hello
As an alternative to the second step, you can use the provided Makefile and simply run make hello
.
The legit logo is a modification of Jason Long's original Git logo. The original as well as the modification are available under the terms of CC BY 3.0.
All other files in this repository are available under the terms of CC0.