1
2
Fork
You've already forked lia
0
Lisp-Induced Metassembly - A bottom-up metaprogrammable assembler.
  • Janet 100%
2024年12月27日 22:46:55 +01:00
example Staged example directory, fixed compilation errors, polished 2024年12月27日 20:32:26 +01:00
src Formatting 2024年12月27日 22:46:55 +01:00
.gitignore Initial commit 2024年12月23日 17:25:56 +00:00
LICENSE Initial commit 2024年12月23日 17:25:56 +00:00
project.janet Add current work from local 2024年12月27日 18:23:25 +01:00
README.md Updated readme 2024年12月27日 22:42:48 +01:00

lia

Lisp-Induced Metassembly - A bottom-up metaprogrammable assembler.

Concept

Introduction

Assembly is very redundant to write and does not have many abstractions; most programming patterns in assembly can either not be expressed at all or are painfully hard to write and dependent on the assembler. Assembly's syntax is also very regular , or at least, can be very regular:

mov eax, ebx
add eax, eax, 5
li a1, 24
lw a0, TextLabel

We can simply abstract most of the syntax of assembly by informally defining the grammar of an instruction as

Verb[, Argument1[, Argument2[,...]]]

This implies an array of tokens written as such can be "transpiled" to assembly:

{"Verb","Argument1","Argument2",...}

It follows that an array of these metainstructions could represent a program:

{{"mov","eax","ebx"},
 {"add","eax","eax",5},
 {"li","a1",24},
 {"lw","a0","TextLabel"}}

It follows that components of this program could be generated on the fly:

function dup(registername)
 return {"mul",registername,registername,2}
{dup("eax"),
 {"add","eax","eax","5"},
 ...}

Multiple metainstructions (ex, {{"mov","eax","ebx"},{"add","eax","eax","5"}}) are called a subprogram thereafter. Functions that return these metainstruction(s) could be placed around to increase comprehension and reduce runtime overhead. These correspond to macros you may have seen in assemblers that exist already.

Unfortunately, the verbose syntax and context of a C-like language leads to fighting with the syntax and overcomplicating the program. Even Python-like languages won't help very much if we have a function that produces a metainstructions array sometimes and otherwise returns an empty metainstructions array, lest we bother with even more boilerplate and verbosity. So the choice of the language matters.

An old language that people think belongs in the grave (very wrongly) would be practically perfect for this: Lisp.

Why not regular Lisp?

A standard lisp has two small issues for a metaprogrammable assembler:

  • it is somewhat unfamiliar to stubborn C-like programmers, missing a lot of abstractions and nice sugar syntax they might want to rapidly prototype their ideas,
  • single-linked lists are slightly more awkward to manipulate in this specific use case; an array would be better.

Introducing Janet. The issue mentionned above is

[#...;(flatten[(may-return-empty-subprogram:eax)])#...]

Janet provides both C- and Lisp-like abstractions , retains good homoiconicity and eliminates verbose syntax of instruction. This makes it perfect for this kind of job where we must interface with very low level code using very high level code.

Examples

More examples are available under the example subdirectory.

Dependencies

WIP

  • Janet (tested with 1.36.0 , probably works under that; janet is a pretty stable language.)

Installing

WIP

Just git clone the repo and mess around. The repo maintainer is on Nix and cannot be currently bothered messing around with JPM to make this installable.