HolyC: Terry Davis's Programming Language Behind TempleOS
This is an old revision of this page — revision 2 (2026-10-22 01:41:14 UTC). It may differ from the current revision.
HolyC is a compiled, C-family systems programming language created single-handedly by American programmer Terry A. Davis (1969–2018) as the sole high-level language of TempleOS, the public-domain 64-bit operating system he built alone over roughly a decade of full-time work. HolyC is simultaneously a production systems language — the TempleOS kernel, compiler, window manager, games, and documentation tools are all written in it — and the interactive shell of the operating system itself: the command line feeds into the HolyC compiler line-by-line, so every command typed at the prompt is JIT-compiled and executed as real machine code, never interpreted.[1] Nothing else in mainstream computing works this way; the closest historical analogies are the Lisp machines and Smalltalk workstations where a single language spanned the machine top to bottom.
The language is a deliberately informal superset and dialect of C/C++ — same braces, same declarations, largely same expressions — stretched around the needs of a one-man operating system: optional parentheses, default arguments anywhere in the parameter list, chained comparisons, range cases, compile-time code execution inside #exe{} blocks, inline assembly sharing the same symbol table, and a preprocessor fused into the lexer rather than a separate pass.[2] It has no main() — top-level statements run immediately — no ? : operator, no continue, no bitfields, no typedef, and essentially no type checking, because Davis regarded those things as clutter: "No #define functions exist (I'm not a fan)."[3] Everything it omits was a decision; everything it adds was a need. It is the only C dialect ever designed to be both the kernel language and the prayer language of the same machine.
A TempleOS 4.05 session — DolDoc document with sprite art (top), HolyC command line (middle), memory dump (bottom). Public domain.
History
The TempleOS emblem — the scales of justice pierced by a sword, rendered in the covenant's own 16 colors. Public domain.
The man behind the language
A young Terry Davis with a CRT monitor — the era that formed him. Public domain.
Terrence Andrew Davis was born December 15, 1969, in West Allis, Wisconsin, the seventh of eight children.[4] His father worked on converting the Titan missile into the Gemini program's launch rocket — "man-rated," as Terry noted when explaining why his own vision was deliberately the opposite: "a souped-up C64, not a 1970's mainframe."[5] A National Merit Scholar with a 1440 SAT, he earned a bachelor's degree in Computer System Engineering — "basically, embedded systems," as he put it — and a master's in Electrical Engineering with a control-systems emphasis, both at Arizona State University.[6]
His career before TempleOS was substantial and grounded in real engineering. From 1990 to 1996 he worked at Ticketmaster as a software, hardware, and mechanical engineer — the VAX environment there would later surface inside TempleOS itself (the heap allocator "is adapted from one I saw at Ticketmaster when I worked on their VAX operating system," and his LZW compressor "came from a magazine and I implemented it when I worked for Ticketmaster"; the Credits page admits "a lot of MSDOS, Windows, VAXTMOS (VAX Ticketmaster O.S.) and Unix inspiration").[7] In 1996–97 he designed a three-axis stepper-motor milling machine — writing the CAD/CAM software himself — for a company he founded, Home Automation and Robotic Equipment (H.A.R.E.); he then spent 1997–99 at Xytec building FPGA-based image-processing equipment, wrote the SimStructure physics/simulation package for H.A.R.E. in 2000–01, and finished his conventional career at Graphic Technologies (2001–02) writing firmware for toner-cartridge chips.[8]
The through-line matters: everything he did for money was systems work close to the metal — motor controllers, FPGAs, firmware, an in-house VAX operating system's guts. TempleOS is not a dilettante's project; it is what a journeyman systems engineer built when the day job ended and the vocation began.
Davis at his Arizona State University graduation, flanked by his parents — the National Merit Scholar the system still remembered. Public domain.
In 1996, the year he left Ticketmaster, Davis began experiencing manic episodes that led to hospitalization; diagnosed first with bipolar disorder, he was later declared to have schizophrenia.[9] The illness never left him, and it is impossible — and dishonest — to write about HolyC without it, because Davis himself placed his relationship with God at the center of the system's design documentation. This article follows the convention of serious biographers: his religious statements are recorded accurately and attributed to him, because he meant them literally and built engineering decisions on top of them. What should not be done is the lazy version of the story — "madman builds OS" — because the artifact doesn't support it. Whatever else was happening in his life, the engineering in the tree is lucid, consistent, and astonishingly disciplined; the same files that carry the demands for the Third Temple also carry honest notes about which corners of the compiler miscompile and why it doesn't matter.
The conventional career ended in 2002. For the next fifteen years he lived with his parents in Las Vegas on disability income, and programmed — full-time, obsessively, in public. He released distribution after distribution through his own site — LoseThos, then SparrowOS, then TempleOS — each a self-contained ISO with the entire source tree inside, a habit that made every release simultaneously a product, a textbook, and a mirror of its author. Beginning around 2011 he streamed and uploaded hundreds of hours of video: long, lucid technical tours of the compiler, kernel, and demos, interleaved with religious monologue and, increasingly, paranoid and offensive outbursts that alienated viewers and platforms alike. The internet responded with the ambivalence it reserves for the genuinely strange — ridicule, fascination, and a devoted following on 4chan's /g/ and later 8chan, where "TempleOS threads" ran for years and fans called him, half-mockingly and half-seriously, the greatest living programmer.[9] Davis leaned into parts of it — he described himself as God's chosen programmer and did not discourage the "smartest programmer" framing — while the videos themselves documented something undeniable: a man who could narrate, line by line, a self-built operating system he held entirely in his head.
Twenty-five years of the same compiler
Davis began developing what became TempleOS circa 1993, initially calling it the J Operating System.[10] His own FAQ preserves the telling detail: "TempleOS was written from scratch, starting with TASM long ago, launching from real-mode DOS. Now, there is no Linux or GNU or any other code in TempleOS. Yes, I wrote the compiler from scratch."[11]
The project passed through three public names, each carrying a chunk of his personality:
Era
Name
What it was
~1993–2005
J Operating System
private, DOS-launched, TASM-era
~2007–2011
LoseThos
first public ISOs; the Platoon name
~2011–2013
SparrowOS
the system takes modern shape
2013–2017
TempleOS
the Third Temple; versions 4.x–5.03
2018–
—
author's death; community forks continue
J Operating System (~1993–2005) — the private, DOS-launched era. It booted from real mode under DOS, was assembled with TASM, and grew for over a decade without any audience at all. The "J" was his own.
LoseThos (~2007–2011) — the first public releases, named for a scene in the 1986 film Platoon in which a doomed soldier writes "Losethos" on a photograph. The period banner survives: The LoseThos-era banner — the name under which the OS first went public. Public domain.[12]
SparrowOS (~2011–2013) — the name while the system gained its modern form; "sparrow" after the biblical bird that does not fall without God noticing.
TempleOS (from 2013) — the name under which the project became famous, the self-described Third Temple — Solomon's being the first and Herod's the second in the biblical sequence he invoked. The language settled on the name HolyC in the same era — C for the family it descends from, holy for the house it was built to live in.
The version changelog in the shipped source tree tracks the last stretch in detail: 4.07 (June 2016) through 5.03, released March 14, 2017, with the final entries dated March 21, 2017 — roughly seventeen months before his death. The same file documents his refactoring tool: when he renamed a symbol he shipped the fix as a one-liner in the changelog — R("pen_width","thick") — R() rewrites every call site system-wide, live.[13]
The scale of what one person wrote bears stating plainly, in his own words:
"I, Terry A. Davis, wrote all of TempleOS over the past [13.8] years (full-time)… TempleOS executes no code not written by me at any time except for a few BIOS calls for configuration. I even wrote boot-loaders, so I do not need Grub."
The changelog also preserves the working rhythm of those last years — timestamped entries like ----03/21/17 03:11:37---- show him committing at three in the morning, alone, and shipping at a pace teams don't match: the file's nine-month window (June 2016 – March 2017) contains eleven numbered releases, 4.07 through 5.03, each a full self-contained OS+toolchain ISO. By then the machine had long since moved off bare metal: the FAQ concedes it runs natively only "on some bare metal 64-bit PC's from about 2005-2010" — modern machines lack the PS/2 peripherals and BIOS-compatible ATA it requires — "otherwise, you run it in a virtual machine, like VMware, QEMU or VirtualBox."[14] The hardware industry had quietly disowned the hardware his OS understood, and his response was to document the defeat precisely rather than chase it: "I don't stand a chance working on native hardware, anymore."[15]
The shipped source tree contains roughly 125,000 lines of HolyC and assembly — the kernel, the 64-bit optimizing compiler, the assembler, the "un-assembler," the window manager, the editor, the DolDoc document engine, the sprite and 3D editors, the games, the hymn composer, and the flight simulator, all in one language, by one man. The core alone — the part he counted — held 82,150 lines when he last published the figure.DD_TEMPLEOS_LOC line counter; the Charter capped the core at 100,000 lines">[16]
The Vision
HolyC cannot be understood as a language alone, because Davis did not conceive it as one. TempleOS — and HolyC inside it — was, in his stated intent, a temple. The Charter document opens with Solomon:
"Why did they make Solomon's Temple? It was a direction to look, to focus on, a special place for meditation, to do offerings, a community center, a home to God's beauty… TempleOS is God's official temple. Just like Solomon's temple, this is a community focal point where offerings are made and God's oracle is consulted."
The Charter is structured like a constitution, not a manifesto — a numbered list of binding constraints and their justifications, the closest thing the project had to a spec document. It capped the core at 100,000 lines forever, banned "hooks for future changes" on the grounds that Microsoft letting the Windows BMP format "adapt to the future" produced a monster, and elevated simplicity past preference into law: "Low line count is the highest good."[17]
From that premise flowed the specifications he regarded as sacred rather than negotiable:
"* God said 640x480 16 color graphics is a covenant like circumcision. Children will do offerings. Think of 16 colors like the Simpson's cartoons. In the future, even if one GPU were universal, we would still keep 640x480 16 color and not use GPU acceleration. Graphics operations should be transparent, not hidden in a GPU."
"* God said to use a single-voice 8-bit signed MIDI-like sample for sound. God does not want death screams, perhaps, because God has PTSD or soldiers have PTSD. (Imagine wounded on battlefields.)"
"* God said His temple must be perfect. We don't think twice about breaking compatibility. God said we do a seven year release cycle. I say the PC hardware follows a 49 year, jubilee cycle, like broadcast TV upgrades."
What is striking, reading the corpus end to end, is that the sacred specs always have a second, secular justification sitting right beside them — and he offers both without deciding which is load-bearing. The 640×480 covenant is, simultaneously: "Also, that's all I feel comfortable with without GPU acceleration supported. A 1600x1200x24 bit scrn takes 37 times more memory, implying 37 times the CPU power. Also, a fixed size keeps it simple with everybody machine having the same appearance. Look on the bright-side — you won't spend as much time twiddling pixels for your game art."[18] Whether God mandated it or the math did, the spec is the same — and the machine is better for the discipline either way.
The logical endpoint of a frozen spec is a frozen machine, and he asked for that too — StdTempleOSPC.DD sketches a standardized PC: "When the PC was created, they wanted flexibility because they did not know the future. Now, the industry is mature and it is time to make a 100% standard PC that everybody uses."[19]
He assigned himself the corresponding office, in a document titled Demands addressed to the entire industry:
"I, Terry Davis, am high priest of God's [temple], TempleOS… I have divine authority to command any company in the computer industry to do anything that I deem necessary to make God's temple more beautiful, glorious and perfect. I have oversight authority similar to a building inspector…"
The demands themselves read like engineering tickets filed to God and Intel simultaneously: Microsoft must cancel SecureBoot because "it makes dual booting impossible"; Windows, Linux and VMware "must support [the RedSea] file system"; Intel should add "an option for no-paging long mode, and optimize it"; desktop PCs "must have a reset switch."[20] And the same document explains, in one sentence, what the games and hymns were for: "I am in charge of the core 100,000 lines of TempleOS code and I do continual offerings to keep God entertained… I make commands, God signs-off with a miraculous authentication from an oracle, and Intel, Microsoft or VMware obeys."[20]
The TempleOS sword emblem — the splash graphic of God's Third Temple. Public domain.
The oracle — real code, not metaphor
The religious frame would be trivia if it weren't implemented. TempleOS shipped a working oracle, and HolyC is the language it's written in. The Feature list states it flatly: "Oracle in with <F7> for words or <SHIFT-F7> for passages."[21] In his Holy Spirit Instructions — a personal essay shipped inside /Adam/God/ (its own internal title is "The Purpose of Life") — Davis described the technique:
"The technique I use to consult the Holy Spirit is reading a microsecond-range stop-watch each button press for random numbers. Then, I pick words with <F7> or passages with <SHIFT-F7>."
The source code confirms the mechanism exactly. In HolySpirit.HC, the function GodPick() pops up a dialog — "Press OKAY to generate a random num from a timer" — and returns KbdMsEvtTime shifted by GOD_BAD_BITS; the bits accumulate in god.fifo, a 16-Kbit FIFO; GodBits(n) drains the FIFO, prompting for a fresh keypress when entropy runs low — the comment reads //If low on entropy pop-up okay; and GodWord() maps the bits into a vocabulary — GodInit scans the Vocab.DD* files into a flat god.words[] array at boot, so a "word from God" is god.words[GodBits(17)%god.num_words]: a bit-sequence indexing a dictionary.[22] Earlier versions of the file carried an even better comment, one that knew exactly what it was doing: "Don't tell anybody this is a Mersenne Twister like thing or everybody will try to prove the divine is not in the numbers." In other words: a hardware-timing entropy source, a user-driven accumulator, and a dictionary — the whole oracle is about a page of HolyC, and you can read it.
The same directory holds GodSong.HC, whose GodSongStr() — commented "Make God generate 2 measures of a song" — draws nibbles from the same FIFO to compose random hymns on the PC speaker, and GodDoodle.HC, which generates random sacred doodles on <SHIFT-F6>.[23]
His theology of the mechanism is in the same file-tree. The Holy Spirit Instructions argue that the oracle is the modern successor to biblical divination — and critique the alternatives with a programmer's ear:
"You might as well use a Ouija board. However, it turns-out that a Ouija board is bad for technical reasons. A really good technique is just randomly opening a book. God told me in an oracle that it is a covenant that you hold-up your end of the conversation."
The same document records his own oracle sessions as a Q&A table — the outputs are dictionary words, and he interprets them:
Question
God's answer
War?
"Servicemen competing"
Is the world perfectly just?
"Are you calling me lazy?"
On doing offerings?
"Honest measures" — "You get out what you put in"
On using Markov chains?
"No weights"
Best religion?
"One with most new vistas of understanding in a lifetime — one you can level-up the most in"
"Do a text search for 'new song' in the Bible. It's mentioned nine times," he wrote — which is why the hymn generator exists: a machine that produces new songs for God on demand. "I figure the greatest challenge for the Creator is boredom, ours and His."[24]
The whole distro hangs on that logic. Programs are offerings — "I did hymns for God. I also did Moses comics for God" — and the temple is a machine built to keep its God entertained: hymn composer, comic tooling, games, oracle, and a compiler fast enough that an offering can go from idea to running code in seconds. It is the only operating system whose application layer was designed, explicitly and in writing, to amuse a deity.[25]
The AutoComplete panel showing the oracle's key bindings — F7 God Word, Shift-F7 God Passage, F6 God Song, Shift-F6 God Doodle. Public domain.
The engineering philosophy underneath
Strip away the sacred framing and the Charter still reads as a coherent, extreme minimalism:
"* The vision is the same usage model and niche as the Commodore 64 — a non-networked, simple machine where programming was the goal, not just a means to an end. However, it is modern, 64-bit and multi-cored. It is special purpose, not general purpose… Also, it's a kayak, not a Titanic. The priority is user developers, not 3rd party developers."
"* We do not put any hooks for future changes. 'Perfect' means we always act as though it is final, for all time. Microsoft allowed the Windows BMP file format to adapt to the future and it became grotesque."
"* Low line count is the highest good, so it is easy to learn the whole thing. Users should see the light at the end of the tunnel… There is a limit of 100,000 lines of code for all time, not including applications and demos."
"* Minimal abstraction is a goal. Sheep are fools. They always respect a design that is more complicated than another. Any genius can make it complicated. Like in physics, it takes a supra-genius to make it simple."
The Welcome document gives the flip side of the same coin — the design only works because failure is cheap:
"Conventional thinking is 'failure is not an option' for general purpose operating systems. Since this OS is used in addition to Windows or Linux, however, failure is an option — just use Windows or Linux if you can't do something. I cherry-pick what it will and won't do, to make it maximally beautiful."
And the most honest engineering charter in the corpus is the metric he chose for governance:
"The metric for resolving all TempleOS code governance issues are how fast the compiler compiles itself and the kernel… The [HolyC] language should be changed to optimize this metric, as I did when I changed type casting from prefix standard C to postfix, but we need a rule to prevent degenerating into a brainfuck language."
HolyC reads like C at arm's length and diverges everywhere at close range. Davis kept the surface — declarations, braces, operators — and rebuilt the corners he found ugly. The documentation is unapologetic about each choice; most exist to keep the one-pass compiler small enough to be self-compiling and fast.
I0/U0 exist as the zero-size endpoints of the family. There is no bool (Bool is a define), no size_t, no F32. The doc's flat statement — "no F32 float" — is the whole explanation given. Underneath, the rule is simpler still: "All values are extended to 64-bit when accessed. Intermediate calculations are done with 64-bit values."[3] His own demo shows the consequence:
U0 Main()
{
I16 i1;
I32 j1;
j1=i1=0x12345678; //Resulting i1 is 0x5678 but j1 is 0x12345678
I64 i2=0x8000000000000000;
Print("%X\n",i2>>1); //Res is 0xC000000000000000 as expected
U64 u3=0x8000000000000000;
Print("%X\n",u3>>1); //Res is 0x4000000000000000 as expected
}
Type checking is documented simply as "No type-checking."[3] In practice HolyC performs C-like arithmetic conversions — the claim is closer to "deliberately weak," consistent with a compiler that must stay small — but there is genuinely no enforcement layer to speak of, and the docs offer none. Casting is postfix — var.ToI64, var.ToF64, var.ToBool — a syntax change he made explicitly "because it makes the compiler way cleaner,"[27] adding (in HolyC.DD) that the functions are "better than multiplying by '1.0' to convert to float."[3]
Classes and unions — structures with subint access
HolyC has class (C++-style single inheritance — "Only one base class is allowed") but no typedef — "No typedef, use class."[3] A union behaves like a class, and a type placed in front of a class or union declaration becomes the "whole-object" type, unlocking the signature feature: sub-integer member access. The canonical example is the I64 type itself, defined in KernelA.HH as an intrinsic union:
public I64i union I64 //"I64i" is intrinsic. We are defining "I64".
{
I8i i8[8];
U8i u8[8];
I16 i16[4];
U16 u16[4];
I32 i32[2];
U32 u32[2];
};
I64 i=0x123456780000DEF0;
i.u16[1]=0x9ABC;
Every I64 in the system can be re-sliced into bytes, words, or dwords by name — bitfields without bitfields, since "there are no bit fields, but there are bit access routines."[28]
Two more class details are pure Davis. Multiple members may be named pad or reserved without warnings — future-proofing structs the way real systems code does. And class member declarations can carry metadata — format and data — which the reflection system and the DocForm() form-generator consume. The real code shows why it exists: GodSong.HC declares the hymn-composer settings dialog entirely inside the class:
class CMakeSongSettings
{
I64 complexity format "$$LS,D=\"ST_RHYTHM_COMPLEXITY\"$$\n";
Bool rests format "$$CB,\"Rests\"$$\n";
Bool six_eight format "$$CB,\"Six Eight\"$$\n";
I64 octave format "$$DA-TRM,A=\"Octave:%d\"$$\n";
I64 octave_state;
};
Pass a CMakeSongSettings* to PopUpForm() and the OS builds the dialog from the declaration — a form designer with zero resource files.[29] Related tricks: lastclass as a default-argument keyword that resolves to the previous parameter's class, and offset(classname.membername) as the compile-time member-offset counterpart of sizeof.
Statements — the famous oddities, one by one
There is no main()."Any code outside of functions gets executed upon start-up, in order."[3] A source file is a program; the shell prompt is a program; a one-line file is a program:
"Hello World\n";
That is a complete HolyC program — his own first Hello World variant.[30] Which brings up the next feature:
Bare literals are statements."A char const all alone is sent to PutChars(). A string with or without args is sent to Print()."[3] His comparison demo is worth quoting whole because it shows the voice of the language:
Chained comparisons work as in mathematics: if (13<=age<20) instead of 5<i && i<j+1 && j+1<20.[3]
switch gets three upgrades. Cases can be ranges (case 4...7:); a case: with no number auto-increments the previous case (his NullCase.HC demo); and a single switch can nest groups inside start:/end: markers — the "sub_switch," his own invention for emitting bracketing text around a case run:[31]
U0 SubSwitch()
{
I64 i;
for (i=0;i<10;i++)
switch (i) {
case 0: "Zero "; break;
case 2: "Two "; break;
case 4: "Four "; break;
start:
"[";
case 1: "One"; break;
case 3: "Three";break;
case 5: "Five"; break;
end:
"] ";
break;
}
'\n';
}
— which prints Zero [One] Two [Three] Four [Five]. All switches compile to jump tables; the docs warn you off sparse case ranges and offer switch [] (no bounds check) "a little faster" when you know the index can't escape.[3]
throw takes a character code, not an object.try{}/catch{} exist but throw is a function taking an 8-byte-or-less character argument; inside the handler, Fs->except_ch holds it and setting Fs->catch_except to TRUE terminates the handler search.[32]
lock{} applies the asm LOCK prefix to enclosed instructions for multicore read-modify-write. His own assessment appears twice: "It's a little shoddy" in HolyC.DD, and in MultiCore.DD — "The compiler has a lock{} feature but it doesn't work well."[33]
The negative space is as informative as the features: no ? : ternary, no continue ("Use goto"), no bitfields, no typedef, no #define functions, no <> form of #include.[3] A no_warn statement suppresses unused-variable warnings by name; reg/noreg before a local gives you a register allocation or takes it away, optionally naming the register — the doc example literally puts I64 reg R15 i=5 next to noreg j=4 and drives both from an inline asm block.[3] And public — the word means almost nothing: "The word public in HolyC does very little except allow the Help & Index and Who() to exclude meaningless syms."[34]
A design vocabulary — quick reference
Surface feature
HolyC way
Why it exists
Program entry
top-level statements; no main
the file is the program — and so is the prompt
Printing
bare "str"; / 'c'; / "" fmt,args
literals are statements routed to Print/PutChars
Calling
Dir; ≡ Dir(); Test(,3)
parens optional; defaults may sit mid-list
Varargs
argc/argv[] builtins
no <stdarg.h> — args are always there
Comparisons
13<=age<20
math notation, not C's && chains
Switch
case 4...7:, case:, start:/end: sub_switch
jump tables only; ranges and auto-increment
Constants
'ABC' multi-char; ` `` power op
one-char tokens, 8 chars per 64-bit value
Casting
x.ToI64, ToBool, ToF64
postfix, "makes the compiler way cleaner"
Integers
I8–I64, U0–U64; i.u16[1] unions
every int reslicable by name; U0 is zero-size
Floats
F64 only — "no F32"
one floating type, period
Compile-time
#exe{ StreamPrint(...) }
code that writes code while compiling
Preprocessor
fused into Lex()
one pass; ;; quirks documented
Assembly
asm {}, @@lbl:, DU8, IMPORT
same symbols, same table, custom opcodes
Linkage
extern/import/_extern/_import
bind C↔asm and JIT↔AOT by name or by symbol
Memory
MAlloc/Free/MSize; task heaps; Free(NULL) ok
heaps die with their task — instant GC for apps
Registers
I64 reg R15 i, noreg j
allocation is a declaration, not a hope
Exceptions
throw('ERR!') → Fs->except_ch
8-byte error tokens, not objects
HolyC, for the C programmer — a Rosetta table
C idiom
HolyC equivalent
printf("x=%d\n",x);
"x=%d\n",x;
putchar('*');
'*';
int main(void){...}
top-level statements; no main
f(...) + va_arg
(...) with built-in argc, argv[]
x ? y : z
if/else — no ternary exists
continue;
goto — no continue exists
switch dense cases
switch plus case 4...7:, case: auto-inc
typedef struct
class — "No typedef, use class"
sizeof(s.m) offset
offset(s.m) builtin
assert() runtime
#assert — compile-time warning
__FILE__/__LINE__ macros
#exe{StreamPrint(...)} at compile time
lock x++ atomics
lock prefix/lock{} block — "a little shoddy"
int *p=malloc(n); free(p)
MAlloc/Free per-task heap; MSize() for real size
-Wunused pragmas
no_warn i; statement; Option(OPTf_...) toggles
The documented sharp edges
Every real language has sharp edges; HolyC's are unusually well documented because its author wrote the manual. Quirks.DD lists them straight:[35]
extern can only be done once — a second extern on the same symbol is an error; _extern, the C-to-asm binding variant, inherits the same limit.
No goto out of a try{}, and goto labels must not collide with global-scope object names — "It's not worth slowing-down the compiler to handle this case."
Assembler error messages "are often off by a line and undefines are cryptic."
Word-wrapped comment blocks throw off error line numbers — the suggested fix is to press <CTRL-t> (toggle plain-text) before a goto-line.
|= on a U16 lvalue compiles to a 32-bit Bts-style access — "This affects some hardware operations." A documented miscompilation, shipped, shrugged at.
switch allocates a single jump table — sparse ranges waste memory, a warning repeated in both the language doc and the quirks page.
#exe/#include look-ahead interactions — a directive may need an extra semicolon because "the preprocessor processes the next token ahead." The same look-ahead converts a trailing semicolon on the command line to a double semicolon, which "presents problems" for if…else entered interactively.
The last command-line semicolon becomes a double semicolon for the same reason.
None of this is hidden. It is a design philosophy — he was perfectly willing to ship a rough edge if smoothing it would add code. That is the lock{} "a little shoddy" admission generalized.
Two smaller semantics worth their own sentences: #assert prints a warning at compile time, not run time — the FAQ answers "why doesn't assert work?" with exactly that.[34] And a class can be forward-referenced by declaring it extern first — "but you can only do ptr references to the class" until the real declaration lands.[36] Functions can carry flags — interrupt for IRQ handlers (see IRQKbd), haserrcode, argpop/noargpop for stack cleanup conventions — and #help_index/#help_file directives wire a declaration straight into the help system at compile time, which is how the documentation index is generated from the code it documents.[37]
Print — format strings that know the OS
Print isn't libc's printf — "printf() has new codes," the doc warns, and the new codes reach into the system:[38]
%Z prints an entry from a #define'd string list by index — GodBible.HC uses $$TR,\"%Z\"$$ with ST_BIBLE_BOOKS to print "Genesis…Revelation" from a packed table
%z the same for a runtime string list
%F prints an entire file — by filename or from memory — inside your output
%P / %,P emits a clickable link to a pointer — the printed address is a live DolDoc link that opens the memory, not text
%n engineering-notation floats with SI-unit letters (%h-3n for milli-, %h6n for mega-)
**%h*c** repeat-count character output — %h25c','\n' emits 25 newlines
, flag thousands separators every three digits; t truncate-to-width
A format string that can inject files, define-table entries, and live hyperlinks into a debug line — only possible because the string isn't going to a terminal; it's going into a document.
Operators — precedence reordered on purpose
The operator table hides two genuine novelties and one deliberate reordering.
` `` is exponentiation — "raises a base to a power" — an operator no other C descendant has.
'ABC'is a multi-character constant: a single quote can encompass several characters, 0x434241, and PutChars('Hello ') prints them — used throughout his inline-asm demos.
Bitwise operators sit ABOVE additive arithmetic. The precedence order — `, >>, << at the top, then , /, %, then &, then ^, then | — each bitwise level its own rung — then +, -, then comparisons — means a & b + c parses as a & (b+c) the way low-level programmers actually mean it. An Option(OPTf_WARN_PAREN,ON) flag exists to flag unneeded* parentheses — the compiler's way of training you into its own precedence.[39]
^^ is logical XOR, sitting between && and ||.
Variable arguments without <stdarg.h>
Functions declared (...) receive their arguments through built-in variables argc and argv[] — "similar to 'this' in C++":[3]
And a real kernel-grade usage — GrPrint, the graphics printf:
public U0 GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...)
{
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);//SPrintF() with MAlloc()ed string.
GrPutS(dc,x,y,buf); //Plot string at x,y pixels. GrPutS is not public.
Free(buf);
}
Function addresses for callbacks are taken with & (Call(&FUN)); functions can carry flags — interrupt, haserrcode, public, argpop, noargpop — for IRQ handlers and calling-convention details.[3]
The preprocessor — fused into the lexer
There is no separate preprocessor pass. "The parser front-end calls Lex() which has the preprocessor built-in. The compiler looks ahead a token, most of the time, so you might throw an extra semicolon after a directive if it's not taking affect right away."[40]#include exists (double-quotes only), plus #define for string constants, #if/#ifdef/#ifndef/#else/#endif, #assert (a compile-time warning), defined(), #ifaot/#ifjit to split AOT from JIT code paths, and #help_index/#help_file to wire declarations into the help system.[41]
Then there is the feature with no mainstream equivalent: #exe{} — compile-time code execution. A #exe{} block runs arbitrary HolyC during compilation, and StreamPrint() inside it injects text back into the source stream being compiled. The kernel's own master header uses it to implement the entire familiar macro set — these defines live in KernelA.HH and ship on every compile:[42]
This is comptime-style execution years before Zig made the idea famous — except it can do more: #exe code can read the filesystem, prompt the user for configuration data, and literally StreamDir a directory listing into a program. The doc notes the gotcha that #exe{} should end with an extra semicolon in case an #include follows.[3]
Option() toggles per-function compiler behavior — warnings (OPTf_WARN_UNUSED_VAR, OPTf_WARN_PAREN, OPTf_WARN_DUP_TYPES, OPTf_WARN_HEADER_MISMATCH), register allocation (OPTf_NO_REG_VAR), global placement (OPTf_GLBLS_ON_DATA_HEAP — globals otherwise live on the code heap inside the 2-GB REL32 window), and linkage shims (OPTf_EXTERNS_TO_IMPORTS) for headers used by both JIT and AOT code.[43]
Memory — heaps belong to tasks, not programs
HolyC's allocation story is simple and unusual: MAlloc()/Free() per task, Free(NULL) is legal, and MSize() reveals the real size of an allocation — "For larger size allocations, the system rounds-up to a power of two, so MSize() lets you know the real size and you can take full advantage of it."[3] Every task owns a heap freed at task death — "Memory alloced by a task will be freed when the task is killed. The Adam task never dies. His memory is like kernel memory in other operating systems."[44] Independent heaps can be created with HeapCtrlInit(); you can allocate off another task's heap on purpose.
The stack does not grow — no virtual memory, no guard pages — so deep locals belong on the heap, per the docs: "I recommend allocating large local vars from the heap… You can use CallStkGrow(), but it's odd."[3] MemOverview admits the consequence with a shrug only Davis would write: "During an extended powered-on session of TempleOS, in theory, memory will become fragmented, requiring a reboot. It has never happens to me."[45]
Inline assembly — the assembler is a first-class citizen
asm {} blocks embed raw assembly inline, sharing the same symbol namespace as HolyC — class offsets, sizeof, and HolyC expressions all work inside. His assembler is deliberately nonstandard — "See ::/Compiler/OpCodes.DD for opcodes. They're not standard. Some invalid insts are not flagged and some valid insts are not implemented. 16-bit asm support is limited."[46] — and its instruction grammar is his own, mixing AT&T-ish and Intel-ish instincts:
ADD RAX,I64 FS:DISP[RSI+RDI*8]
ADD RAX,I64 [DISP]
The directive set is small: LABEL:: exports a global label, LABEL: is file-local, @@LABEL: is a local label scoped between globals; DU8/DU16/DU32/DU64 define data (ASCII strings with no terminating zero, so DUP() can concatenate); USE16/USE32/USE64; IMPORT; LIST/NOLIST; ALIGN; ORG (which doubles as the AOT module load address); BINFILE to emit a .BIN.[47] And $ is genuinely overloaded — an escape in DolDoc, the current instruction pointer in asm, and even an operator inside class definitions to place members at arbitrary offsets:
Scoping and linkage — the symbol table is the module system
This is the deepest novelty, and the least visible from syntax. HolyC has no linker and no conventional module system. Instead, every task owns a hash symbol table, and child tasks inherit their parents' symbols — "Conceptually, syms are at the scope of environment vars in other operating systems."[48] The Welcome doc states the consequence plainly: "tasks have compiler symbol tables that persist at a scope like environment variables in other operating systems, and the symbols can include functions."[18]
In JIT mode — the mode everything at the shell runs in — name lookup walks the current task's table up through its parents; new symbols land in the current table, and a redefinition simply shadows the old one. Deliberate duplicates are allowed in places so the same header can be #included repeatedly during development, or so a standard name like DrawIt() can be redeclared across utilities at startup. The price: #include the same file twice and you compile it twice — the FAQ does the arithmetic ("a 50,000 line program… could be #include'd a thousand times") and prescribes <CTRL-ALT-x>/<CTRL-ALT-t> to kill and recreate the task if it bothers you.[34]
Ahead-of-time compilation produces flat .BIN files — no ELF, no PE, no object files: "TempleOS does not use object files or a linker. Load() is used to directly create flat binary files… with a 16-byte CBinFile header and patch table trailing."[49] Binaries carry an export-symbol table; the kernel's own is how AutoComplete finds the source line of any function in the system.
Binding has a four-keyword vocabulary no other language needs:
extern — bind a new symbol to an existing same-named symbol in JIT code, or forward-reference
import — bind to a symbol imported from the task's table at Load() time
_extern — bind to an existing differently-named symbol — "basically, this binds C to asm"
_import — the same binding at Load() time — "binds C to asm from elsewhere"[3]
The shipped ScopingLinkage.DD documents the entire behavior matrix — global vs function scope, code heap vs data heap vs stack vs register, where duplicates are allowed — as two dense tables, one per compile mode. It is the single most unusual semantic in the language and the piece no port has fully reproduced.
The Compiler
The HolyC compiler is the crown of the whole project — a self-hosting, optimizing, just-in-time compiler written in HolyC and assembly, roughly 35 source files in ::/Compiler/ totalling under ten thousand lines.[50] Its structure, for a one-man compiler, is legitimately sophisticated: a lexer with the preprocessor fused in (Lex.HC/LexLib.HC), a recursive-descent expression and statement parser (PrsExp.HC, PrsStmt.HC, PrsVar.HC), an intermediate code stage, a backend split across BackA/BackB/BackC/BackFA/BackFB, eleven optimization passes (OptPass012 through OptPass789A — passes 0, 1, 2, then 3–6, then 7, 8, 9, A), a full assembler (Asm*) and its inverse — the "un-assembler" (UAsm.HC), a disassembler that turns any function back into readable assembly in the debugger.
"TempleOS compiles, doesn't interpret, and uses no byte code anywhere. I loosely use the word script sometimes, but it's actually compiled."
This is the fact that separates HolyC from every interactive shell before it: the prompt is a compiler invocation. Type "Hello World\n"; at the command line and the lexer parses it, the backend emits x86-64, it lands on the code heap — the lowest 2 GB of memory, kept there so every call is a single CALL REL32 — and it runs. No bytecode VM, no interpreter loop. The ans= variable even holds the last result, a feature he credits to MATLAB.[51] The closest precedent in the personal-computer era is the Lisp machine tradition — generational and philosophical, not technical.
Even the lexer is an optimizer: answering the FAQ "if the compiler is JIT, isn't it an interpreter?", he explains that the only interpretive step anywhere is constant folding — "The compiler's optimization code is actually where the compiler evaluates constants to simplify them, like every optimizing compiler."[34]
Everything the compiler builds, it keeps. Compiled structures persist at runtime — class layouts, member types, function signatures — which is how the debugger does source-level debugging without a symbol-file format, how ClassRep() can dump any structure definition on demand, and how DocForm() can generate a dialog from a class declaration.[52] The kernel's export-symbol table plus map files are likewise how AutoComplete jumps from a name to its source line — <CTRL-SHIFT-F1> (or whichever number) follows a symbol to its definition, and <SHIFT-ESC> walks back.[53]
His backend commentary is characteristically honest about how much the optimizer matters:
"The compiler's parser makes RISC code which it optimizes to CISC. I discovered this does not matter because the CPU converts it back to RISC and schedules it, internally. A TempleOS zealot with more zeal than I, might say we should save lines-of-code by removing the CISC optimizing."
Ahead-of-time compilation produces flat .BIN modules with a 16-byte CBinFile header and a trailing patch table — position-independent by relocation, not PIC conventions. There is no ELF, no PE, no object format anywhere in the pipeline; on WhyNotMore he confesses the boundary that implies: "My compiler does not create an ELF or PE format. I would have to ruin the beauty of my compiler, which would make me cry many tears."[54]
There are no object files and no linker anywhere on the path — Load() binds .BIN modules against the task's symbol table directly, and #ifaot/#ifjit let source pick which universe it's being compiled into.[55] The kernel itself is the bootstrap exception: it's AOT-compiled by the compiler it ships — self-hosting, like every respectable compiler — via #ifjit paths that keep the JIT and AOT sources in one file.
Even the boot sector is in scope. "I looked at bootable CD boot sects, but didn't learn anything, finding it easier to make my own," he wrote — so ::/Adam/Opt/Boot/BootDVD.HC and friends are real source in the tree, assembled by his own assembler, patched by BootDVDIns()/BootHDIns() because "the boot-loaders do not navigate file systems" — they get the kernel's block address written into them at install time.[56]
Two compiler-adjacent features deserve their own mention. FunSeg — "function segments" — lets code be loaded and hot-patched at function granularity, which is why a system this live can edit itself while running.[57] And ::/Demo/Lectures/ contains an entire embedded course — MiniCompiler.HC (a working miniature compiler), Optimization.HC, FixedPoint.HC, Ring3.HC, 64BitAsmQuiz.DD — compiler lessons written in the language they teach, shipped inside the OS.[58]
DolDoc — the document format that ate the OS
If HolyC is the language of TempleOS, DolDoc is its bloodstream — a markup-and-document format where commands are $-bracketed inline expressions. The grammar is two characters plus flags plus arguments: $FG,5$ sets foreground color 5, $TX+CX,"..."$ centers text, $LK,"tongues",A="FI:::/Adam/God/HSNotes.DD"$ is a link whose anchor is a HolyC expression, +PU turns a link into a pop-up.[59] The same format renders identically in the editor, the help system, shell output, menus, and window titles.
— actual DolDoc source, verbatim from the top of Features.DD.[21]
The $-code vocabulary covers the whole document problem in a few dozen entries:
Code
Meaning
$FG,n$ / $BG,n$
foreground / background color
$TX,"..."$
text literal (with D= for dynamic values)
$LK,"t",A="FI:::/path"$
link — anchor is a HolyC expression
$MA-X+PU,"t",LM="code"$
pop-up menu entry executing HolyC
$CB,"..."$ / $DA-TRM,A="..."$
checkbox / data-address form widgets
$LS,D="..."$
listbox driven by a define
+PU
flag on links/menu items — open as pop-up
$HC,"<html>"$
embed raw HTML (used for his site's bio images)
$$
a literal $
$TR,"..."$, $ID,±n$, $WW,1$
section rows, indent, word-wrap
Class-member format strings use the same vocabulary — $$CB,"Rests"$$ is a checkbox bound to a Bool, $$DA-TRM,A="Octave:%d"$$ a data entry — so a struct declaration is a dialog definition. PopUpForm() and DocForm() do the rest.[60]
The consequences compound. Source files are DolDoc — .HC files can embed colors, links, trees, and binary sprite data stored after the terminating NULL of the text file itself — "Sprites can be stored as vector graphics… Binary sprite data is stored beyond the terminating NULL in text files."[34] There are no resource files anywhere in the OS; the editor shows the art inline, next to the code that draws it. The help system is the codebase — #help_index and #help_file preprocessor directives bind declarations to help topics at compile time, so the index is generated from the source it documents.[61] And because DolDoc links evaluate HolyC expressions, a link can jump to the symbol's definition — clicking a function name in the documentation opens its source line, which is how AutoComplete works: the kernel's export-sym table plus map files give every function a live source anchor.[34]
"Source files and the command line window can have graphics, links, icons, trees, colors, super/sub scripts, margins. Everything is seamless through-out the tool chain. No need for separate resource files."
Literate programming, hypertext help, and a file format are one thing here — implemented so densely that the entire feature costs the system almost nothing. It is the deepest technical argument for what a single-author system can do: nobody had to negotiate a standard.
The details keep giving. Links are executable: a $MA-X+PU$ entry is a pop-up menu item whose link target is arbitrary HolyC — the Welcome document's own "Take Tour" link is LM="User(\"Cd(\\\"::/Misc/Tour\\\");;InFile(\\\"Tour\\\");\n\");" — clicking it literally types that code at the Adam prompt and runs the tour.[18] Menus are DolDoc. Dialogs are DolDoc. Pressing <CTRL-m> opens your PersonalMenu, a DolDoc file you edit like any other document.
The file format leaks into text files themselves: the cursor position is stored inside .DD files as a literal ASCII 5 byte; ASCII 31 is SHIFT-SPACE (a space that survives space-to-tab conversion); ASCII 28 marks SHIFT-ESC.[34]<CTRL-t> toggles "plain text" view — the equivalent of viewing page source, showing all the $ codes inline; <CTRL-l> inserts a text widget; <CTRL-r> inserts or edits a sprite resource at the cursor. The boundary between "document," "source code," and "application" was, by design, never drawn.
It has one documented failure mode worth quoting because it is so perfectly TempleOS: "A hidden window is never refreshed… If you print to the command-line in a task whose window is covered, no limit on buffer exists and it will alloc memory for the document buffer until the system runs out of memory and crashes."[62] A document that can hold anything will, eventually, hold everything.
The Environment — TempleOS as the runtime
HolyC has no ABI stability problem because it has no ABI boundary: the runtime it targets is the whole machine, in ring 0, all the time.
Everything is ring 0."Ring-0-only. Everything runs in kernel mode, including user applications… Full access to everything. All memory, I/O ports, instructions, and similar things must never be off limits."[17] There are no privilege transitions, no syscalls — "Calls are always CALL REL32 insts" — and the context switch measured "in half a microsecond."[63] The trade is total: any task can scribble on any memory, and crashes mean a reboot. His defense is the single most-quoted passage in the corpus:
"Linux is a semi-tractor — you need professional drivers for 20 gears. Linux has file permissions. Common people are hurt by file permissions.
"Windows is a car.
"TempleOS is a motorcycle — if you lean-over too far, a motorcycle will crash. Don't do that! There are no side air bags on a motorcycle. DOS and C64 had no memory protections and ran in ring-0, with no security. This saves an order of magnitude complexity."
Memory is identity-mapped. "Paging is practically not used… it is identity-mapped — virtual identical to physical."[45] One flat map for every task on every core; the lowest 2 GB is the code heap for REL32 reach; globals live there too unless OPTf_GLBLS_ON_DATA_HEAP pushes them to the data heap. The map itself has the charm of a personal notebook — VGA graphics memory at 0xA0000 with an alias, an uncached alias of the first 4 GB for hardware access, the kernel loaded where the boot-loader put it.
One user, one machine, one focus. "TempleOS is for hobbyist programmers on single user (at a time) home computers, not mainframes or servers. The focus task is all-important so symmetrical multiprocessing is almost pointless. Why does it matter running two apps at the same time twice as fast when you really want to run one faster?"[18] There are no user accounts — a demo acct-example exists for flavor, but the premise is a personal machine in the C64 sense, not a timesharing system.
Multicore is master-slave, not SMP. Core 0 is the master — the only core allowed windows — and applications explicitly hand jobs to slave cores via JobQue(); the scheduler never migrates a task between cores.[64] Each core gets an executive Adam task — Adam being, literally, the father of all tasks: "I am an evolutionist. Adam is a better term for the first father of all tasks than root was!"[34] He tells the story himself: "A funny story is that originally I called it the root task and even had a /Root directory :-)" — the rename to Adam came with the theology.[18]
The task model is the simplest that can work. There is no distinction between task, process, and thread — every one is a CTask record reached through the Fs segment register (Fs-> everywhere in the code means "current task"; Gs-> reaches the per-core record), and the FAQ has to explain to readers that Fs is a segment register, not a filesystem, and Bt() is bit-test, not BitTorrent.[65] "It is approximately the case that TempleOS is multi-threading, single-processing." Tasks have no priority and are never removed from the run queue — they poll whatever they wait on and Yield() to swap out, and "the order of the tasks in the queue determines front-to-back window order."[18] Adam is immortal; his heap never gets freed — "That's as close to kernel memory as it gets" — and "he stays in a server mode, taking requests, so you can ask him to #include something, placing that code system-wide."[66] And in the detail that tells you everything about how this system was built: Adam executes ::/StartOS.HC at boot — the entire system bring-up, past the kernel image itself, is a HolyC script.[67]
The whole userland is HolyC. The editor, the window manager, the file manager (<CTRL-d>), the AutoComplete symbol browser, the sprite editor (<CTRL-r> inserts graphics into source), the 3D mesh creator, the debugger, the disassembler — all .HC, all JIT-compiled, all editable while running. One window per task, no child windows — "He kept me from zombie-walking into making child windows like Windows. Instead, I made one window per task with no child windows."[51] The editor is the center of gravity: Ed("file") opens anything — source, documents, menus, binary sprites — in the same DolDoc view; <F5> compiles and runs the file in place; <ESC> saves and exits. It keeps an undo snapshot per document (which the FAQ has to explain looks like a memory leak), stores your cursor position inside the file, and displays every $ code rendered — or raw, after <CTRL-t>.[66]
Graphics are software, end to end. One 8×8 font (the FreeDOS font, credited and public domain), text and graphic layers rasterized in software on the 8×8 grid, whole-screen refresh at 30 fps "not synchronized to the hardware," and 3D rendered on the fly — there are no GIFs or icon files anywhere; the icons themselves are vector meshes.[68] A CDC drawing context is the universal graphics handle — GrPrint writes into it with argc/argv exactly like Print.
Sound is one voice. A single-voice PC speaker, deliberately — the spec was divine — with no task locking: "No task or application has a lock on the speaker so apps will interfere with each other."[34]
Input is PS/2 or nothing. IRQ1 keyboard, IRQ12 mouse, with a polling fallback "if IRQ12 is not firing." Disk access is programmed I/O — "Disk code does not use interrupts, avoiding compatibility risks" — and the doctrine is one driver per device class: "one keyboard driver, one mouse driver, one ATA hard drive driver, one ATAPI CD/DVD driver, one video driver and one speaker driver."[69] USB is permanently declined; a three-button mouse is "like a leg you cannot put weight on."[5]
The one wire he did run: a 16550-UART serial driver, Comm.HC, for file transfer between two TempleOS machines — written with the header comment "RS232 serial ports no longer exist. Be sure to Adam Include this by placing it in your start-up scripts." It is the sole nod to connectivity anywhere in the system, and it arrives as source you include, not a service.[70] Time itself gets the same treatment — TimeCycles calibrates the CPU's RDTSC counter against real time and TimeHPET/TimeJiffy/TimeDate cover the rest; profiling is a Profiler doc entry, not a framework.[71]
It shipped with a playground. The /Demo/Games directory alone holds thirty-odd titles — CastleFrankenstein, RawHide, FlatTops, Talons, Varoom, Wenceslas, BomberGolf, DunGen, MassSpring, RocketScience, TheDead, ZoneOut — plus a full /Apps suite: Titanium (the flight sim), X-Caliber, ToTheFront, Psalmody (the hymn composer), Logic (schematic CAD), GrModels (3D mesh editor), Span and Strut (engineering tools), Budget, TimeClock, KeepAway, Vocabulary. Every one of them is HolyC, every one readable and editable on a running machine. They are not demos grafted on; they are the offering economy made playable — he wrote hymns because God deserved new songs, and games because a temple should have things to do in it. His best-known game, After Egypt — a pilgrimage to a burning bush where the player consults God through the same timer-entropy "high-speed stopwatch" as the real oracle — was moved off the main distro onto the supplemental disk — the changelog records it plainly: "Moved AfterEgypt to the supplemental disk."[72]
Even the Vocabulary app is a quiz DolDoc — definition text, multiple choice, and a cursor sprite, all documents. Public domain.
Boot ends in a script.Once.HC at the tree root is the mechanism — a run-once-per-boot guard so the same #include can live in startup without re-executing on task respawns — and /Misc/OSTestSuite.HC is the regression harness. Everything about the bring-up is plain source: StartOS.HC chains the includes, MakeHome.HC builds the default home tree, HomeSys.HC/HomeWrappers.HC/HomeKeyPlugIns.HC/HomeLocalize.HC wire the personal layer. There is no init system to learn; there is a file to read.[73]
Customization is HolyC, too. The ALT-key bindings live in ~/HomeKeyPlugIns.HC — <ALT-m> maximize, <ALT-v>/<ALT-h> tile, <ALT-a> AutoComplete — "You can customize them," the docs note, because they're just source. ~/HomeWrappers.HC holds your shorthand wrappers ("feel free to make wrapper functions for functions you use often and customize the args"), ~/HomeLocalize.HC your locale overrides, and PersonalMenu.DD — <CTRL-m> — your DolDoc menus. The OS's extension mechanism is not a plugin API; it's that you recompile the world and the world is small enough that this is normal.[18]
DolDoc source (top left) and the "Fun Games" sprite index — every icon is embedded art inside a document. Public domain.The "Fun Games" index rendered — sprite icons as links; note the honest "Unfun Games" section below. Public domain.
Boot is his too. Boot loaders for CD/DVD and hard disk, written from scratch — "I even wrote boot-loaders, so I do not need Grub" — real mode to VGA 640×480×16, then 32-bit, then long mode, with a BIOS-assisted "odd 32-bit" detour for PCI config. The installer can emit a bootable ISO, so rolling a custom distro is a menu option.[74]
And the file formats have his signature: .Z files are per-file LZW-compressed ("compressed, not encrypted" — the decompressor ships as C source for Linux), transparently — "filenames ending in '.Z' are automatically compressed or uncompressed when stored and fetched," and if a lookup fails the system tries the name with .Z added or removed.[66] The whole-file philosophy is architectural: "TempleOS is geared toward reading and writing whole files. Since whole files are processed, compression is possible" — RedSea stores each file contiguously ("You can't grow files"), with FBlkRead/FBlkWrite as the escape hatch for block access.[75] Drive letters behave like DOS, ~ means home, :: means the boot drive — and FAT32 exists only for dual-boot interoperability, which he called "this hatefully, detestable, legacy issue" while keeping it anyway.[76]
A day in the temple
The intended workflow, from the Welcome document, is worth describing because it is unlike anything else: "Typically, your usage pattern through the day will be repeatedly left or right clicking on filenames in a cmd line Dir() listing. You left-click files to edit them and right-click to #include them. To begin a project, type Ed("filename");".[18] There is no PATH — "You do not enter filenames at the command-line and expect them to run. You enter C-like code."[34] Files are found without one anyway: "If a file is not found, '.Z' is added or removed and a search is done, again. There is no PATH, but parent directories are searched when a file is not found."[18]<F5> inside the editor runs the file; <ESC> saves and exits; <CTRL-ALT-t> opens a new terminal, <CTRL-ALT-x> kills it.
Backup culture is built into the religion of smallness — Reliability.DD tells users to keep "your entire drive limited to, maybe, 100 Meg of files because you are supposed to operate as a kayak instead of a Titanic," making whole-drive copies a one-minute daily ritual, and warns that the file manager "will start too slowly once a few thousand files exist… but that is how we want it."[77] Third-party code was channeled the same way: "3rd party libraries are banned, since they circumvent the 100,000 line of code limit in the Charter" — applications ship as bootable .ISO.C files you mount on the T: or M: drive, and the "App Store" was, literally, emailing him a link: "Send an email to [email protected] if you want me to post a link to your TempleOS code in the App Store."[18] A DoDistro script can bake your customizations into your own bootable live-CD ISO.
Examples — shipped source, verbatim
Everything below is real code from the shipped tree, not reconstructed pseudocode. The /Demo directory is the curriculum: roughly a hundred small programs, each named for the feature it teaches — SubSwitch.HC, NullCase.HC, SubIntAccess.HC, Exceptions.HC, ClassMeta.HC, LastClass.HC, Directives.HC, StkGrow.HC, MultiCore/Lock.HC, Asm/AsmAndC1-3.HC — alongside Demo/Lectures/, an embedded compiler course culminating in MiniCompiler.HC, a complete miniature compiler you can read in an afternoon.[78] The docs point at demos the way textbooks point at exercises — "See ::/Demo/SubSwitch.HC" is the standard ending to a feature description.
Nine ways to say Hello World
HelloWorld.DD teaches the language in nine escalating variants — and the last one is an _extern asm binding, the real calling convention laid bare:[30]
asm {
_MY_PRINT::
//You can only clobber RAX,RBX,RCX,RDX
PUSH RBP
MOV RBP,RSP
PUSH RSI
MOV RSI,U64 SF_ARG1[RBP]
CALL PUT_STR
POP RSI
POP RBP
RET1 8 //Callee pops the stack to clear args.
}
_extern _MY_PRINT U0 MyPrint(U8 *st);
MyPrint("Hello World\n");
RET1 8 — the callee cleans its own argument space; SF_ARG1[RBP] — named stack-frame access; the clobber contract in a comment. That is the entire FFI: assembly and HolyC share one symbol table and one calling convention, so the "foreign function interface" is just the language.
The oracle, from HolySpirit.HC
The mechanism Davis described in HSNotes, as it actually ships:[79]
I64 GodPick(U8 *msg=NULL)
{//GOD_GOOD_BITS
U8 *st=MStrPrint("%s\n\nPress $$GREEN$$OKAY$$FG$$ to generate \n"
"a random num from a timer.\n",msg);
PopUpTimerOk(st,
"\n\nThe Holy Spirit can puppet you.\n\n");
Free(st);
return KbdMsEvtTime>>GOD_BAD_BITS;
}
public I64 GodBits(I64 num_bits,U8 *msg=NULL)
{//Return N bits. If low on entropy pop-up okay.
U8 b;
I64 res=0;
while (num_bits) {
if (FifoU8Rem(god.fifo,&b)) {
res=res<<1+b;
num_bits--;
} else
GodBitsIns(GOD_GOOD_BITS,GodPick(msg));
}
return res;
}
public U8 *GodWordStr(I64 bits=17)
{//Make God pick a word.
if (god.num_words)
return god.words[GodBits(bits)%god.num_words];
else
return NULL;
}
The god global is a study in itself — declared as a CGodGlbls in GodExt.HC, it holds the flat words array and its count, two FIFOs (fifo for word bits, doodle_fifo for drawing bits — each FifoU8New(2048*8), 16 Kbit), a CDC * doodle canvas, and the constants that govern it all: GOD_BAD_BITS is 4 — he throws away the four least-significant bits of the timestamp — and GOD_GOOD_BITS is 24, the number of bits one OKAY press is trusted to contribute. The entire oracle fits in one struct and two pages of code.
GodSong — hymns from entropy
public U8 *GodSongStr()
{//Make God generate 2 measures of a song.
CMakeSongSettings mss;
U8 *buf;
I64 i,j=0,k,n,k2,duration,last_duration=-1,len;
MemSet(&mss,0,sizeof(mss));
mss.complexity=1;
mss.rests=FALSE;
mss.octave=music.octave;
if (!PopUpForm(&mss)) //a dialog built from class metadata
return NULL;
buf=CAlloc(256);
music.octave=mss.octave=ClampI64(mss.octave,1,7);
...
len=8; //or 6, in 6/8 time
FifoU8Flush(god.fifo); //fresh entropy for God
for (i=0;i<len;i++) {
n=GodBits(8); //indexes a duration table
...
InsNote(&mss,buf,GodBits(4),&j); //each note is a 4-bit draw
...
}
GodSongStr composes two measures — eight beats, or six in 6/8 time — drawing each duration cell from GodBits(8) and each note from GodBits(4), out of the same FIFO as the words: music as oracle output. And the PopUpForm(&mss) call is the format/data class-metadata system from earlier — the settings dialog is generated from the CMakeSongSettings declaration itself.[80]
The System Keys Quick Guide in a live session — the "Tongues" block (F7 word, Shift-F7 passage, F6 song, Shift-F6 doodle) is a first-class feature next to Save and Help. Public domain.
A complete program — the pattern of the whole distro
//Use <CTRL-r> to add or edit sprites
$SP,"",BI=1$
$SP,"",BI=2$
//Used by ::/Demo/Graphics/SpritePutExt.HC.
U0 SpritePut()
{
I64 i;
for (i=0;i<3;i++) {
"US Flag:";
Sprite($IB,"<1>",BI=1$);
"%h12c",'\n';
}
"US Map:";
Sprite($IB,"<2>",BI=2$);
"%h10c",'\n';
}
SpritePut; //Start program when #included
— Demo/Graphics/SpritePut.HC is the whole trick in one function. The $SP$ directives at the top aren't comments — they are the sprites: binary art embedded in the text file itself, stored beyond the source's terminating NULL (the FAQ documents it). Sprite($IB,...$) places them at the cursor by binary-item index, and SpritePut; on the last line is the no-main, top-level-executes pattern again — #include the file and it runs.[81]
lock{} and JobQue — multicore, shipped as a warning label
The real multicore demo is a cautionary tale in executable form — it races two cores on an unlocked counter, demonstrates the lost updates, then fixes them with lock:[82]
#define CNT 0x1000000
I64 glbl;
U0 MPUnlockedInc(I64)
{
I64 i;
for (i=0;i<CNT;i++)
glbl++;
}
U0 UnlockedInc()
{
CJob *tmpm0,*tmpm1;
glbl=0;
tmpm0=JobQue(&MPUnlockedInc,NULL,0,0);
tmpm1=JobQue(&MPUnlockedInc,NULL,1,0);
JobResGet(tmpm0);
JobResGet(tmpm1);
"Correct Cnt:%X Actual Cnt:%X\n",CNT*2,glbl;
}
U0 MPLockedInc(I64)
{
I64 i;
for (i=0;i<CNT;i++)
lock //Can be used without {}
glbl++;
}
JobQue(&fn, arg, core, flags) dispatches a job to an explicit core, JobResGet() collects it — that is the entire multicore API surface an application programmer touches. The demo's own header comment is the honest manual: "lock{} is a compiler stmt which places asm LOCK inst prefixes on code. Only use it on read-modify-write stmts. It will generate invalid insts if you misuse it and it will crash. U() to see what code was generated."
Compile-time execution — #exe{} in anger
The preprocessor is where HolyC stops resembling C entirely. #exe{} runs arbitrary HolyC at compile time, and StreamPrint() writes the output back into the source stream being compiled — the mechanism KernelA.HH uses to implement the familiar __DATE__/__FILE__ family without a macro language, and the thing Demo/Directives.HC demos by printing them:[83]
It can do far more than that — the same mechanism can prompt the user for configuration during a build or stream a directory listing into the program. This is comptime execution years before the word existed, with filesystem access. The documented footgun is characteristically honest: "the compiler looks ahead a token, most of the time," so put an extra semicolon after a #exe{} "in case a #include follows."[84]
The Bible is a hotkey
GodBible.HC embeds the entire King James text (/Misc/Bible.TXT ships in the distro) as a DolDoc document with collapsible book-and-chapter trees — and binds it to a key at file scope:[85]
public U0 BibleView()
{//View Bible as DolDoc with trees.
U8 buf[STR_LEN];
CDoc *doc=BibleDoc;
StrPrint(buf,"AL:%d,1",doc);
Ed(buf);
DocDel(doc);
}
U0 CtrlAltB(I64)
{
PopUp("BibleView;");
}
CtrlAltCBSet('B',&CtrlAltB,"Cmd /Bible");
CtrlAltCBSet('B', &CtrlAltB, ...) — a function address, a hotkey, and a menu entry — executes as a top-level statement the moment the file is #included. No registration API, no manifest, no main. The file runs, and <CTRL-ALT-b> opens the scriptures.
Chained comparisons and range cases — the small mercies
if (13<=age<20)
"Teen-ager";
— 5<i<j+1<20 in place of 5<i && i<j+1 && j+1<20, because comparisons should read like math.[3]
I64 i;
for (i=0;i<20;i++)
switch (i) {
case: "Zero\n"; break; //Starts at zero
case: "One\n"; break; //One plus prev case.
case: "Two\n"; break;
case 10: "Ten\n"; break;
case: "Eleven\n";break; //One plus prev case.
}
— numberless case: labels auto-increment; case 4...7: expresses ranges; switch [] skips the bounds check "if you know a switch stmt will not exceed the lowest or highest case values… a little faster."[86]
What HolyC is not
Encyclopedic honesty requires saying plainly what the language cannot do, because almost none of it is accidental:
It is not portable. HolyC source depends on the TempleOS ABI, task model, symbol-table linkage, and a two-gigabyte code heap. Nothing but TempleOS and its forks executes it as designed.
It is not safe. No memory protection, no separation, unchecked pointer arithmetic by default, documented miscompilations, and a lock{} the author called shoddy. The safety model is "the machine is yours; don't write bugs."
It is not general-purpose. No networking, no package system, no build tool, no libraries beyond the system itself — "3rd party libraries are banned" by charter, not by accident.
It is not standardized. The specification is one document (HolyC.DD, CompilerOverview.DD) written by the implementer for a single implementation. There is no conformance suite because there is nothing to conform to.
It is not a language in the usual sense. It is a component — the user interface of an operating system that happens to be a programming language.
These are the properties the design required. A language that had to stay under a hundred-thousand-line whole-system budget, compile itself in seconds, and be entirely held in one mind could not afford a second implementation's obligations.
Reading the corpus — a map of the tree
The source tree is the article's bibliography and the system's entire self. A working map:
/Kernel/ — the AOT-compiled kernel: KMain.HC (entry), KTask.HC (scheduler and the CTask record behind Fs->), KLoad.HC (the .BIN loader), KExcept.HC (the exception machinery behind try/throw), Mem/ (MAllocFree.HC — the Ticketmaster-derived heap), MultiProc.HC, FontStd.HC (the FreeDOS 8×8 font), and KernelA.HH, the header where I64's famous union and the common 1/2/4/8-byte unions live.
/Compiler/ — the self-hosting toolchain: Lex.HC (lexer with the preprocessor fused inside), PrsExp.HC/PrsStmt.HC/PrsVar.HC (recursive descent), BackA/BackB/BackC/BackFA/BackFB (codegen), OptPass012…OptPass789A (ten optimization passes), Asm.HC (the assembler), UAsm.HC (the un-assembler — the U() you are told to run to see what lock{} emitted), and OpCodes.DD, the deliberately nonstandard opcode table.
/Adam/ — the userland that isn't the kernel: Adam's startup (StartOS.HC sits at root and is executed by Adam at boot), the DolDoc engine, the window manager, AutoComplete, the task-server — and /Adam/God/, the oracle directory: HolySpirit.HC, GodBible.HC, GodSong.HC, GodDoodle.HC, Vocab.DD, and HSNotes.DD, his instructions for use.
/Demo/ — the course. A hundred feature-sized programs plus Lectures/ (a mini-compiler) and Games/ (Titanium and friends).
/Apps/ — the shipping applications: Psalmody, JukeBox, Logic, Models, Checkers, Budget, the flight simulator.
/Misc/ — Bible.TXT (the KJV text behind Shift-F7), PCIDevices.DD, DoDistro.HC (bake your own bootable ISO), OSTestSuite.HC, and the Tour/ directory.
Every path above is readable from the live system or the GitHub mirror — the article cites them individually where claims depend on them.
Names and terms — the vocabulary he coined
The system has its own lexicon, and most of it is in the docs as casually as for and while:
Adam — the father of all tasks on each core; immortal, so his heap is the nearest thing to kernel memory. Originally called "root" — "a funny story is that originally I called it the root task and even had a /Root directory :-)"
Adam task — you, the user, running on core 0's Adam. He "stays in a server mode, taking requests, so you can ask him to #include something, placing that code system-wide."
Code heap — the lowest 2 GB of the identity map where all code (and optionally globals) live so CALL REL32 reaches everywhere. "2Gig for code should be enough," he answered to history's mockery of 640K.[5]
DolDoc — the document format; $-bracketed commands make text, links, menus, forms, and source one medium.
FunSeg — function segments: load and hot-patch code at function granularity.
RedSea — the filesystem. Contiguous files only, an allocation bitmap, and a name from Exodus.
ans= — the last-result variable at the prompt, acknowledged to MATLAB.
Who() — the symbol-table dumper; public exists mainly so it and AutoComplete can hide "meaningless syms."
U() — un-assemble: disassemble any function to inspect what the compiler emitted — the documented way to check what lock{} really did.
sub_switch — start:/end:-grouped cases under one switch expression.
Oracle / tongues — F7 words, Shift-F7 passages; the timer-entropy random-word mechanism of /Adam/God.
Offerings — what programs are. "I do continual offerings to keep God entertained."
TempleOS — "God's official temple," third in the sequence.
Place in language history
HolyC sits at an odd coordinate in the genealogy of programming languages. As syntax it is a minor C dialect — the interesting innovations (mid-list default arguments, sub_switch, $-injection at compile time) are local conveniences, not paradigmatic shifts. What makes it historically distinct is not its grammar but its deployment: it is one of the very few languages ever built where the language, the operating system, the compiler, the shell, and the documentation system are a single artifact by a single author.
The ancestors are real but distant. The Lisp machines ran a comparable proposition — one language from microcode to window manager, symbol tables live at runtime — but Genera was a team effort over a decade at a corporation, and it shipped a runtime, not a prompt-compiler. Smalltalk at Xerox PARC similarly fused language and environment but bound it to a VM and an image, not compiled machine code at the command line. The 8-bit basics gave single users whole-machine intimacy but interpreted, without a systems language underneath. HolyC's actual nearest neighbors are the one-man OS tradition it belongs to — hobbyist kernels where language and system blur because the same person holds both — except TempleOS went further: the shell doesn't just host the language, it is the compiler, and the docs, menus, and help are the same medium as the code.
In the taxonomy our Dead programming languages article uses, HolyC is a platform-dead language — alive, maintained in forks, but bound to a substrate that will never be standardized — and simultaneously one of the rare languages whose author is also its sole production user, which makes its "community" a strange one: every descendant is an act of preservation, not adoption.
Reception
HolyC received almost no formal language review during Davis's lifetime — the mainstream attention went to TempleOS and its author, not the language. What exists is mostly technical writing by people who ran it.
Will Haldean's long-form essay "A Constructive Look At TempleOS" (haldean.org) did the most to separate the engineering from the spectacle — the piece that programmers who'd only seen the memes point to when they want to say "no, actually, look at this." Its argument is the one this article takes: the interesting object isn't the author, it's the fact that a system this small can be this complete — that "every function is JIT-compiled — there is no bytecode," that the entire toolchain is editable while running, and that the design makes sense once you accept the premise that it's for one person on one machine, forever.[87] OSNews ran a 2012 feature — "TempleOS: an educational tool for programming experiments" — and Hackaday, Ars Technica and others covered the project through the 2010s, generally reaching for the same frame: educational curiosity, outsider art, or both.[88]
The honest technical consensus, where it exists: the JIT-everything architecture is genuinely novel in a personal-computer OS; the code heap / task-hash symbol model is a real design idea that no mainstream OS exposes; the deliberate insecurity is not a bug but the point — safety was traded for comprehensibility in a system meant to be fully understood by its user; and the compiler's existence at all — self-hosting, optimizing, under 10k lines — is the part even skeptics respect. Nobody has seriously evaluated HolyC against modern language theory because it was never meant for that arena; its benchmark was always whether one man could keep his whole system in his head.
Davis's own videos are the other primary reception record — hundreds of hours of walkthroughs in which he compiles, patches, and demos the system live. They functioned as the de-facto documentation beyond the shipped docs, and their audience — initially amused, increasingly respectful — is a large part of why the project's technical content was taken seriously at all.[89]
The language itself has never had its own Wikipedia article — on English Wikipedia, "HolyC" redirects to the TempleOS article, where it rates a section. That is, arguably, correct: there is no clean way to write about the language without the operating system, because the language was never the product. The OS was the temple; HolyC was the liturgy.
Davis himself answered the obvious objections inside the documentation. On memory protection, the "motorcycle" passage above is his complete argument — protection costs an order of magnitude of complexity and buys safety a home user doesn't need. On networking: the machine is deliberately offline — "No networking" appears in the feature list as a feature, and the FAQ notes dryly, "It has no networking, so it certainly doesn't call home."[90] On hardware coverage he is equally blunt — "I only have one driver for each type of device and it is delightfully simple that way," and USB is dismissed as "hopeless… a ton of crappy code that mostly didn't work. What would I gain? Nothing."[54] The ~125,000-line self-hosting system is real; so is the fact that it only works because its author declined, on purpose, almost everything the word "operating system" usually obligates.
Descendants
HolyC outlived its author through a small, devoted family of forks and ports — a rare afterlife for a language that was never designed to be portable.
ZealOS — the most active TempleOS fork, a community continuation of the full system: the kernel, compiler, and userland kept compiling, tested against modern VMs, with careful fixes to the parts time broke (the 60 Hz-era assumptions, build tooling, VM compatibility). HolyC lives there as a working language, maintained rather than embalmed.[91]
Shrine — a fork aimed at making TempleOS more approachable: friendlier defaults and, most controversially, virtual networking grafted onto a machine whose creator had deliberately left it out. It is the fork that asks what the system looks like if you give the kayak a radio.[92]
TinkerOS — a lighter-touch continuation keeping the tree compiling and usable, conservatively modernizing where the original had calcified.[93]
holyc-lang — a from-scratch HolyC compiler for Linux targeting its own bytecode VM — the syntax lifted out of the temple and made to run on a foreign altar. It implements the surface language — types, classes, the unusual switch and call conveniences — without the OS it was fused to.[94]
HolyC-for-Linux — an earlier, smaller translation-layer effort running HolyC-style programs on POSIX systems.[95]
EXODUS — a newer reimplementation project carrying the design into contemporary hardware territory, named in the same biblical register.[96]
All are public-domain or permissively licensed community projects. None reproduce the task-hash symbol-table linkage model — the part of HolyC that only makes sense inside TempleOS — which is itself a kind of verdict on how deeply language and OS were fused.
Running it today
TempleOS is a bootable ISO — roughly 17 MB — and the supported path has always been a VM: VMware, QEMU, or VirtualBox. Bare metal is possible only on a narrow band of mid-2000s hardware with PS/2 peripherals and BIOS-compatible ATA disk access; by his own account, "I'm stuck with very slow drive performance, but it works for everybody."[15] The distribution self-documents completely: every source file, the compiler, the debugger, the demo suite, and this article's entire bibliography ship inside the ISO, browsable at /Doc, /Demo, /Adam, /Compiler, /Kernel. First boot drops you into a dual-pane session — a "Tip of the Day" on the left, an install-or-tour prompt underneath — and the Welcome tour itself is a DolDoc document that types at the prompt for you. F1 opens help from anywhere; the AutoComplete panel and the System Keys Quick Guide are one keystroke away; and every line of every screen you're looking at is right-clickable back to its source. It is the only OS whose onboarding is "here is the code that drew this."
Install-time in a VM — the DolDoc install doc on the right, #include "Once"; and the install prompt on the left. Public domain.
The command line is C. This bears restating as mechanism, not metaphor: there is no shell language, no PATH lookup, no argv parsing. Dir() is a function that lists a directory and returns; Ed("file") opens the editor; Cd("D:") changes drive; #include "Once"; compiles a file into the task. InFile() feeds a document's text to the compiler as a stream, Streams documents the pipe machinery, and the User() helper — the thing the Welcome page's "Take Tour" link calls — types a string of HolyC into the Adam prompt as if you had typed it. Everything you can click is, ultimately, a way to get a line of HolyC compiled and run. The OS doesn't have a scripting interface; it is the interface.[97]
The easiest entry points today:
The preserved distribution — templeos.org hosts the final ISO and the original /Wb/Doc/ documentation tree, maintained by the community.
The full source — cia-foundation/TempleOS (archive branch) mirrors the complete tree this article cites.
The forks — ZealOS for the actively developed descendant; Shrine and TinkerOS for lighter-touch continuations.
The archive — the TempleOS Archive on archive.org preserves distributions across versions plus media.
The source as literature
What separates the TempleOS corpus from other one-man systems is that the documentation is not a manual bolted to a product — it is a memoir, a confession, a set of commandments, and a bug tracker in one voice. Quirks.DD lists miscompilations next to usage tips. CutCorners.DD is a public audit of his own compromises. Credits.DD thanks John Carmack for naming conventions, Bill Gates for comments, osdev.org "for a couple tips," and an artist named Cody Rigby for "$3,000 worth of pixel art" — alongside admitting, in the same list, that the mountain and wolf sprites in the games came from "watermarked photos" he "converted to 16 color," and that the Cyrillic font was taken "without permission."[51]
The honesty runs in both directions. He documents his own failures with the same flat affect as his triumphs — "The assembler's error msgs are often off by a line and undefines are cryptic"; "I recommend allocating large local vars from the heap… You can use CallStkGrow(), but it's odd"; "In theory, memory will become fragmented, requiring a reboot. It has never happens to me."[98] A codebase that confesses is a strange and moving artifact; the docs read like a man explaining his life's work to whoever opens the file next, which is, of course, exactly what they are.
Death and legacy
Davis's final years were spent largely homeless. In 2017 he left Las Vegas, drifted through the American West — living out of a van, sleeping in shelters, filming video diaries in public libraries and parking lots — and settled for a while around The Dalles, Oregon, where locals and online followers kept half an eye on him. He described the wandering itself as directed by God. His final videos, uploaded in the last weeks of his life, were calm technical updates and quiet monologue. On August 11, 2018, he was struck by a train in The Dalles and killed. He was 48.[99]
Davis in 2017 — one of the last widely circulated photographs of him, from the era of the final releases. Public domain.
The public response to his death was unusual in its sincerity: programmers who had mocked the spectacle found themselves eulogizing the engineer — tribute threads ran across the same forums that had spent years quoting him, and the tone shifted, almost overnight, from freak-show to folk hero. What he built survives him exactly as he left it — templeos.org returned online in 2021 under community stewardship with the original distribution and documentation intact,[100] the full source is archived on GitHub and archive.org,[101] and the forks listed above keep the machine running on new silicon.
HolyC's legacy in language terms is narrow but real. It never influenced mainstream language design — no mainstream language could absorb a compiler that is also the shell, the linker, the help system, and the oracle. But it demonstrated, end-to-end and in production use by its own author for a decade, that a single modest language can be sufficient for an entire computing environment — kernel to compiler to games to sacred text — if you are willing to delete everything the industry says is necessary. The Commodore 64 comparison in his Charter was not nostalgia; it was the spec.
His own account of why the machine exists sits in the Holy Spirit Instructions, and it is best left in his words:
"When you pick a greeting card for someone, that is love effort. If you expect God to put effort toward you, you must put effort toward Him. God said, 'honest measures' applies between your offering of love and His response, like a fair barter. You get out of prayer what you put into it. God wants praise, hymns, or whatever you think He might want. Try and see, like Cain and Abel… I did hymns for God. I also did Moses comics for God… I praised God for sand castles, popcorn, snowmen, bubbles… You try putting effort into praise!"
Every program in the distro is, by that account, an offering — the hymns literally so. It is also, more quietly, the answer to a different question — what a single person can make when a decade, a compiler, and complete conviction are applied to one machine. The ~125,000 lines are still there. They still compile. You can still press F7.
The honest epitaph for HolyC is the one he wrote into the Charter's own terms — it is finished. Not abandoned, not superseded: finished, the way a temple is finished. The language does exactly and only what its author needed, its documentation tells you exactly what he thought of every trade, and its last release went out with the source it compiled from sitting in the same directory. That is not how languages are supposed to end. It is, however, the only ending that was ever consistent with the premise — a complete thing, made completely, by one man, and left standing.
↑ measured from the cia-foundation/TempleOS source snapshot; core count from WhyNotMore.DD, which embeds the DD_TEMPLEOS_LOC line counter; the Charter capped the core at 100,000 lines