I was always fascinated by the idea that just one man could have created TempleOS. Building an OS alone in 10 years is like building a one-man-built skyscraper. I’ve decided to try to understand HolyC, the C “dialect” the OS is written, even for fun, because I am sure I will never be able to create what Terry A. Davis has done.
This is a little experiment when I document the steps I’ve followed in this first approach to the TempleOS source code. I know it has already been studied, and I can find tons of documentation online. But this isn’t funny.
Where to start
I am an experienced C/C++ programmer, so I’m confident it will be very funny. The TempleOS source code is in the Public Domain, and you can find it at https://github.com/cia-foundation/TempleOS.
Let’s start with something simple. I’ve found a file called Kernel/QSort.HC that, on a rapid look, seems to be an implementation of Quicksort. The Quicksort algorithm is one of the very first you learn when you start talking about sorting stuff; that’s why it’s a good start.
From the file I can extrapolate four functions:
U0 QSortI64(I64 *base,I64 num, I64 (*fp_compare)(I64 e1,I64 e2));
U0 QSort2a(U8 **base,I64 num,I64 (*fp_compare)(U8 **_e1,U8 **_e2));
U0 QSort2b(U8 *base,I64 num, I64 width, I64 (*fp_compare)(U8 *e1,U8 *e2),U8 *tmp);
U0 QSort(U8 *base,I64 num, I64 width, I64 (*fp_compare)(U8 *e1,U8 *e2));
Quick considerations
U0seems to be aNULL(unsigned zero?).U8is a char of 8 characters.I64is a 64-bit integer (and so on).- Pointers appear the same as C.
TempleOS is a 64-bit-only OS, so it makes sense to name the variable with the dimensions in bit directly. Other considerations
pivot=base[num/2];Integer division is truncated toward zero, like in C.MAlloc(width*2)andFreeare the names for the correspondingmallocandfreestdlib functions.
The code now reports about a: Maybe, look at $LK,"::/Demo/MultiCore/MPRadix.HC"$. The $LK ... $ is probably some smart link you can select to jump to the other file. It can stand for LinK. The fact that it’s a string surrounded by two characters you don’t usually find in a C file can help select it. But let’s move on to Demo/MultiCore/MPRadix.HC.
On to the first demo
Something new in this file immediately caught my eye.
- HolyC supports C++ one-line comments (C does it, too, but only since from C99).
- There is a
no_warn dummy;it probably mutes the compiler. The dummy variable is not used inside the function. "$$GREEN$$QSort$$FG$$\n";probably write something in the console."Time:%9.6f\n",tS-t0;it’s a printf without the declaration of the function? Wow!D(arg2+NUM/4);A debug output?
I had already lost three functionalities on my way, so I decided to clone the repository and search the code broadly. I found the D function very quickly. As the comment says, it’s a debug function.
Now, up to point 3, the $$ syntax. As I imagined, it’s used all over the place. But I founded:
- A
DocPrint(doc,"$$LTBLUE$$"); - And a
DocPrint(doc,"$$MU,\"%d\",LE=%d$$\n",i,i);
So, it is a printf, and the format is similar. But I can see a simple dangling string in the code, which is interesting. During my searches, I also found that DocBottom is the same as calling DocBottom(). If you have no parameters to pass to a function, you can save two parentheses characters. Cool!
After searching and digging, I arrived at the lexer. You don’t need to write printf to output or use strange, non-mnemonic ANSI colors. I find this fascinating and wonder how complex the C LARL will become.
Searching for a complete program
I decided to search for a complete program, and given my accumulated knowledge, I searched for “I32 main(“. Nothing. “I64 main(“, nothing again. I don’t want to search for the result online; in this little experiment, I want to understand the code from the OS code, not from any external document.
U0 main(. I found it; the main() function returns NULL and does not accept arguments. In the meantime, I saw a file called HolyC.DD, the documentation of HolyC? Yes, I could have searched for documentation as the first step, but like I already said, it’s not funny. Digging through the kernel files is interesting!
The HolyC documentation file
The file starts with a:
$WW,1$$FG,5$$TX+CX,"HolyC"$$FG$
* See $LK,"::/Doc/CompilerOverview.DD"$.
* See $LK,"Scoping and Linkage",A="FI:::/Doc/ScopingLinkage.DD"$ for details on $FG,2$extern$FG$, $FG,2$import$FG$, $FG,2$_extern$FG$, $FG,2$_import$FG$, etc.
Like I thought, the $$LK,"path"$$ is a link to a filesystem. This is
Built-in types include $FG,2$I0,I8,I16,I32,I64$FG$ for signed 0-8 byte
Like I thought as well. I32 is like writing int32_t. Having HolyC built-in types in C will be easy work. Just a tiny list of type definitions:
#include <stdint.h>
typedef int16_t I16;
typedef int32_t I32;
// and so on.
Now the good part:
Function with no args, or just default args can be called without parentheses.
Default args? Like in PHP? I didn’t notice it! And better:
Default args don't have to be on the end.
It’s not like PHP. So this is working code:
// The function: I64 Dir(U8 *files_find_mask,Bool full)
Dir("*")
Dir();
Dir;
// Default args not at the end
U0 Test(I64 i=4,I64 j,I64 k=5) {
// ...
}
U0 DemoHolyC(U8 drv,U8 *fmt,U8 *name,I64 age) {
// This is sent to PutChars()
"Hello World!\n";
// To Print()
"%s age %d\n",name,age;
// An empty string followed by a string (fmt) is a string
"" fmt,name,age;
// To PutChars(). Same behavior as before
'' drv;
// To PutChars()
'*';
}
The main() function
I searched for the main() function, and I didn’t need to because I just found from this file that:
Any code outside of functions gets executed upon start-up in order.
Like in a lot of scripting languages. And this is nothing compared to this:
I64 AddNums(...)
{
I64 i,res=0;
for (i=0;i<argc;i++)
res+=argv[i];
return res;
}
Every function and any code outside a function can access parameters and the count from the global argc and argv! And also:
- The if short-syntax 13<=age<20.
- The switch cases automatically start from zero and increment by one, no need to specify the number.
- The switch cases can be nested.
- All values are extended to 64-bit when accessed. Intermediate calculations are done with 64-bit values.
- And so on.
Farewell Terry
I then decided to stop. Such a naive analysis is not the way to study the TempleOS or pay respect to him. Having mental problems is one of the worst things that can happen to you.
I have drug-resistant epilepsy, and programming is one of the few things that keep a smile on my face. Today, I’ve smiled a lot every time I saw something HolyC has, and C does not.
Until next time.