woodrush / sectorlisp-ref-in-bf

SectorLISP C reference implementation in BF

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SectorLISP C Reference Implementation in BF

BF was mentioned in the original SectorLISP article. Just out of curiosity, I set off to explore how BF would perform if it were to run the C reference implementation version of SectorLISP, by compiling the reference implementation to BF (which is not the actual optimized version, but still serves as the point for this experiment).

I used ELVM (the Esoteric Language Virtual Machine) to compile the C source code for the reference implementation in the original SectorLISP repository. Some modifications were made it to make it compatible with ELVM. The code used for the compiled bf output is at ./sectorlisp/lisp_bf.c (which I have added in the forked submodule for SectorLISP).

The resulting BF source code ./lisp.bf is 9.5 MB, which does not even fit in the main sector of a floppy disk!

Most of the file size is probably due to the memory access unit generated by ELVM, used to translate the virtual memory addresses to BF's memory addresses. The original ELVM-compiled BF Lisp interpreter bflisp (more precisely, compiled with an older version of ELVM) has a BF source code size of 4.75 MB. The number of lines in the ELVM assembly file, however, is 4752 for the SectorLISP reference implementation (after removing the .long 0 directives), and 10409 for bflisp. Since ELVM uses a renewed version of bflisp's compiler, I suspect that the size of the memory access unit is different for ELVM and bflisp, and is also dominantly determining the resulting file size. Although there should be more efficient ways to implement a smaller Lisp interpreter in BF, with the tools at hand at the time, I was able to make an interpreter of this size.

This means that if the 99 bytes for BF were loaded into the boot sector, we would need an additional 9.5 or 4.75 megabytes to start evaluating Lisp. It's also noteworthy that the BF executable created in this repo is an optimized version, where consecutive pointer and value increments are optimized to one operation. This deviates from the specifications of the 99-byte implementation, articulating the performance of SectorLISP.

Shoutouts to SectorLISP and the author Justine Tunney!

Building and Testing

git submodule update --init --recursive

make
make test
make test-executable
  • make builds the BF source code and its optimized bf executable (by ELVM's bfopt). The resulting ./out/lisp.bf should match ./lisp.bf.
    • bfopt takes a BF source and creates an optimized executable, where consecutive pointer and value increments to a single step, etc. (as described in https://github.com/shinh/bflisp).
  • make test tests the behavior of the bf executable by comparing it with the cc-compiled executable, using the meta-circular evaluator included in the SectorLISP repository (included as a submodule).
  • make test-executable tests the behavior of the cc-compiled executable with the original source code for the C reference implementation for SectorLISP (which is not the fully optimized version, but still serves as a point for this experiment).

About

SectorLISP C reference implementation in BF

License:Other


Languages

Language:Brainfuck 100.0%Language:Shell 0.0%Language:Makefile 0.0%