The elegance of Lisp with the cold-blooded efficiency of Assembly. Tl;dr: lllm is a DSL for writing Assembly via the Lisp family of programming languages. This is the Janet -first and currently only- implementation.
arson 6dac554ff3 Update 'README.md' | 1 рік тому | |
---|---|---|
examples | 2 роки тому | |
graphics | 2 роки тому | |
src | 2 роки тому | |
test | 2 роки тому | |
LICENSE | 2 роки тому | |
README.md | 1 рік тому | |
project.janet | 2 роки тому | |
setup.sh | 2 роки тому |
"Lisp is a slow language." --Famous last words
This is the Janet-flavoured implementation of lllm.
It currently focuses on the x86_64 but it would be trivial to add support for other architectures.
*** Tl;dr: lllm is a family of DSLs for writing Assembly via the Lisp family of programming languages. ***
This is the first -and currently only- Janet lllm implementation*. Janet is a quite portable and embeddable pseudo-Lisp that is mostly written in standard C99; think of it as Clojure if you don't like the Java ecosystem, or, better, as Lisp with much easier UNIX-/C-y data manipulation.
lllm is not a "compiler" nor is it "compiled" in the standard sense.
It could be said that current compilers are built "top-down", ie. abstractions are first defined, such as arrays, and then bruteforced into fitting the architecture's machine code (or the architecture is built around the compiler, which could promote some amount of language lock-in in the worst cases)
By analogy, lllm would build itself "bottom-up": you begin by defining extremely simple abstractions (such as loops) that directly translate to a list of assembly instructions; then, you begin abstracting those abstractions, raising the level of abstraction higher (print statements, BIOS mode handling, a generic syscall function ...) as necessary, while keeping your code highly flexible and hackable.
Keep in mind lllm (and lllm-janet) is still in its infancy; while it seems to work as intended and is a very simple concept in and of itself, it and its libraries are still heavily subject to change.
With that said, you can use it to generate perfectly valid assembly code and even bootloaders.
(: There is a systems programming lisp called Ink. it uses extremely similar concepts to lllm to write Assembly, that was independently developped for a Lisp operating system called Yalo; I did not know of it when I came up with lllm, but I find it amazing someone else thought of combining Assembly and Lisp too.)*
The REAL (unless declared INTEGER) and official way.
git clone "https://notabug.org/debris/lllm-janet"
cd lllm-janet
jpm build
jpm test
doas(sudo) jpm install
Alternatively, the setup.sh script should probably do most of the job itself:
git clone "https://notabug.org/debris/lllm-janet"
cd lllm-janet && sh setup.sh
No warranty, though!
Alternatively:
doas(sudo) jpm install "https://notabug.org/debris/lllm-janet"
The name of the executable is lllma
, which stands for LLLM Assembler. Name may change in the future (lljm
?)
There are plenty of symbols provided as llllm
s (Libraries for LLLM). For development under x86_64 Linux, use lllm/llllnx
. For barebones x86_64 development, use lllm/lllb
.
This section is not complete.
Use (doc symbol)
in the Janet REPL after importing a llllm ((import lllm/llllnx)
for example) for the meantime.
An lllm-operation
(in lllm-janet) is data of this kind:
['operationA 'argA1 ... 'argn]
such that operationA
is a symbol that is equivalent to an assembly operation, argA1
is a argument to that operation, etc...
It will be converted to assembly as the line operationA argA1, ..., argn
.
lllm will transemble data of this kind:
@[
lllm-operation
...
lllm-operation
]
(ie. an array of lllm-operation
s of any length.)
As such, any function or macro that generates a valid lllm-operation
can be used to generate and abstract assembly away. This is where the power of lllm resides.
Inserting an indexable data structure like ["string"]
into an indexable to transemble will escape "string" into assembly code. This is your escape hatch. It's useful for defining odd macros like "$-$$" (though you could use a prefix-infix converter to write (- '$ '$$)
or something).
Also, you'll probably need some x86_64 opcodes cheat sheet like this one , and maybe another for Linux syscalls.
And maybe a guide on x86_64 too.
For OS development and lllm/lllb
, or just a really good introduction to assembly, check out this great tutorial by Daedalus Community.
I have no idea how repository management works. If you want to contribute, please contact me through the community space or directly on Matrix.
We have a space on Matrix here, feel free to join.