💾 Archived View for republic.circumlunar.space › users › dbane › gemlog › 2021-09-20.gmi captured on 2024-05-12 at 16:00:09. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2022-03-01)

-=-=-=-=-=-=-

Oberon FFI

There haven't been many updates lately both because of "Real Life", and the fact that Easy-ISLisp is now quite stable.

Easy-ISLisp

An aim of Sasagawa-san's, which I agree with, is that the interpreter be simple and easy to read. This puts a limit on performance, but that's fine, you can rewrite "hot" code in a faster programming language. C is a very popular choice for this, but I wanted to explore the memory-safe alternative Oberon which should be almost as fast.

Oberon Dialects

Go and Rust are popular languages in this space now, but back in the 1990s there were other choices: Turbo Pascal was the most popular, followed by Modula-2 and Oberon. Oberon is the only one I learned much about. It's also much simpler/more minimal than Go or Rust.

I used a "to-C" transpiler, obnc. This implements the Oberon-07 dialect (there isn't a massive difference between them). The steps follow.

OBNC Home Page

Target Code

This is the Oberon code you want to call.

MODULE Hello;
   IMPORT Out;
   PROCEDURE World*();
   BEGIN Out.String("Hello World!"); Out.Ln;
   END World;
END Hello.

FFI Glue Code

This is the glue code to call from the interpreter (tested on macOS).

(c-include "\".obnc/Hello.c\"")
(c-option "-I/Users/me/include /Users/me/lib/obnc/Out.o /Users/me/lib/obnc/OBNC.o -L/opt/homebrew/lib -lgc")

(defun hello-world ()
   (c-lang "OBNC_Init(0, NULL);")
   (c-lang "Out__Init();")
   (c-lang "res = NIL; Hello__World_();"))

Notes:

Compilation

obnc-compile Hello.Mod
eisl -c
(compile-file "oberon.lsp")
(load "oberon.o")
(hello-world)

And that's it. It's only slightly more complicated than the C interface, but personally I much prefer the safety of Oberon. It's a nice path to improve performance, if you've confirmed that that is a problem.

If I won the lottery :-) it might be nice to port the whole interpreter to Oberon, with just a few minor changes:

Back to my gemlog