I find this really inspiring! I've got a similar hobby project (that I've been neglecting recently...) but with some different design choices. I don't want to hijack the thread but I thought it might be interesting to compare and contrast.
Instead of targeting x86 it uses Prof. Wirth's RISC CPU for Project Oberon. This is a really simple chip, there is a model function for it written in Oberon that is less than a page of code. It's also very well documented, and emulators exist in Java, C, Python, and Javascript, and there is a VHDL (or is it Verilog?) description which people have used to make FPGA-based workstations.
For the basis notation I'm using a dialect of Joy, an extremely simple and elegant purely functional, stack-based, concatinative language. It's like a combination of the best parts of Forth and Lisp. https://en.wikipedia.org/wiki/Joy_(programming_language)
(I'm pretty sure there's no simpler useful language than Joy.)
To bridge Joy to the CPU I took the high road: a compiler written in Prolog. It would be possible to use Forth lore to bootstrap from the metal up, but I was gobsmacked by
David Warren's "Logic Programming and Compiler Writing" (
https://news.ycombinator.com/item?id=17674859 ) and have spent the last year "moulting" from Python to Prolog programmer.
Anyhow, the compiler so far is concise but the model it implements for Joy on the CPU is still very crude. Between life, work, and learning more Prolog I haven't had much time to improve it.
The thing is, Prolog is a very simple language, the compiler is very simple and small, and Joy is also very very simple and small (especially if it's implemented in Prolog), and the underlying CPU is very simple and small. The tricky bit would be to, say, implement a Prolog interpreter in Joy. But if you do that you've closed the loop for self-hosting: Prolog-in-Joy, running on Joy-on-the-metal, implementing a compiler for Joy to the metal, bootstrapped through Prolog on the host.
(It would be simple to convert the Joy compiler in Prolog to a Joy compiler in Joy using the Prolog interpreter in Joy and partial evaluation. FWIW.)
For the OS I'm going to build a simple clone of OberonOS but using Joy rather than Oberon language. I made a model of this OS in Python and Tkinter to guide the reimplementation in Joy. This will also serve as a stress test for Joy: can you implement a whole (albeit simple) "OS" in a purely functional, stack-based, concatinative language? Maybe it sucks?
To sum up, a simple text-based UI/OS inspired by and loosely imitating OberonOS, targeting a simple but capable 32-bit RISC chip, with Joy as the shell and glue language and Prolog as the under-the-hood powerhouse systems language. And the whole thing should fit in under a hundred pages of code.
This sounds really interesting. I'm very happy you shared it. I'd love to see it when you publish it. Based on your description it seems like a lot of code, so I'm curious to see how tight we can keep the dependency chain.
The Prolog code is under the ./thun subdir. I apologize for the state of the repo & docs. I need to go through and update everything.
If you look at the Python code the vast majority of it is the type inference module and the library of functions and combinators. The parser, main loop, and most of the library are trivial. Most of the joy.utils.types module is a crude re-implementation of a subset of Prolog and can be discarded. The Prolog version of Joy is even shorter than the Python version.
The Joy compiler (which is only about half done) is really tight and simple (Joy doesn't use variable so no need for a symbol table; Joy doesn't use subroutines so no need for a call stack) and the last half of the functionality won't require double the code.
Meta-programming in both Joy and Prolog is really easy and powerful, and Joy in particular lends itself to a kind of Huffman encoding of your graph (Joy code forms a simple DAG.)
- - - -
I want to repeat, Mu is really inspiring. I'm looking forward to watching your progress. :-)
Instead of targeting x86 it uses Prof. Wirth's RISC CPU for Project Oberon. This is a really simple chip, there is a model function for it written in Oberon that is less than a page of code. It's also very well documented, and emulators exist in Java, C, Python, and Javascript, and there is a VHDL (or is it Verilog?) description which people have used to make FPGA-based workstations.
For the basis notation I'm using a dialect of Joy, an extremely simple and elegant purely functional, stack-based, concatinative language. It's like a combination of the best parts of Forth and Lisp. https://en.wikipedia.org/wiki/Joy_(programming_language)
(I'm pretty sure there's no simpler useful language than Joy.)
To bridge Joy to the CPU I took the high road: a compiler written in Prolog. It would be possible to use Forth lore to bootstrap from the metal up, but I was gobsmacked by David Warren's "Logic Programming and Compiler Writing" ( https://news.ycombinator.com/item?id=17674859 ) and have spent the last year "moulting" from Python to Prolog programmer.
Anyhow, the compiler so far is concise but the model it implements for Joy on the CPU is still very crude. Between life, work, and learning more Prolog I haven't had much time to improve it.
The thing is, Prolog is a very simple language, the compiler is very simple and small, and Joy is also very very simple and small (especially if it's implemented in Prolog), and the underlying CPU is very simple and small. The tricky bit would be to, say, implement a Prolog interpreter in Joy. But if you do that you've closed the loop for self-hosting: Prolog-in-Joy, running on Joy-on-the-metal, implementing a compiler for Joy to the metal, bootstrapped through Prolog on the host.
(It would be simple to convert the Joy compiler in Prolog to a Joy compiler in Joy using the Prolog interpreter in Joy and partial evaluation. FWIW.)
For the OS I'm going to build a simple clone of OberonOS but using Joy rather than Oberon language. I made a model of this OS in Python and Tkinter to guide the reimplementation in Joy. This will also serve as a stress test for Joy: can you implement a whole (albeit simple) "OS" in a purely functional, stack-based, concatinative language? Maybe it sucks?
To sum up, a simple text-based UI/OS inspired by and loosely imitating OberonOS, targeting a simple but capable 32-bit RISC chip, with Joy as the shell and glue language and Prolog as the under-the-hood powerhouse systems language. And the whole thing should fit in under a hundred pages of code.