News for hackers. Stuff that matters.
Re:TinyCompiler: A compiler in a week-end by zvmaz on Thursday February 20, 2025 @06:18PM (#43121780)
I don't think one can understand compilers in a "week-end".
Re:TinyCompiler: A compiler in a week-end by haqreu on Thursday February 20, 2025 @06:54PM (#43122193)
The "week-end" part refers to the fact that I wrote it in one week-end with little to no experience in compiler design. You can check the commit history, 12 to 14 Jan, 2024 :)
Re:TinyCompiler: A compiler in a week-end by not_a_bot_4sho on Friday February 21, 2025 @12:01AM (#43124208)
I think the "week-end" reference up above was a little tongue in cheek, since the modern spelling is a compound word: https://linguix.com/english/common-mistake/week_end_hyphen

Not to take away from this awesome sharing.

Re:TinyCompiler: A compiler in a week-end by sieve on Thursday February 20, 2025 @06:29PM (#43121908)
Compilers are some of the simplest "complicated" programs out there if you start by throwing yacc/bison/antlr/parser generators in the garbage.

Production compilers are complicated because of the feature set of languages and performance requirements.

You can write a lexer + parser + treewalk interpreter for a simple language in a day if you know what you are doing.

Re:TinyCompiler: A compiler in a week-end by RossBencina on Thursday February 20, 2025 @07:32PM (#43122562)
> lexer + parser + treewalk interpreter

If all you do is construct an AST and interpret it it's not really a compiler is it. It doesn't compile from source to target. At most you're describing a compiler front end (arguably), or an interpreter.

I would expect:

lexer + parser + AST definition and construction + semantic analysis/type checking + X + codegen to ASM/WASM/C

where X includes

  - definition of an intermediate representation (IR)
  - lowering AST to IR
  - static analysis
  - improvers/optimisation passes (at least some simple stuff)
  - code gen including register allocation
This can still be a simple "complicated" program, but there's more to a compiler than an AST interpreter.

EDIT: I notice that the author of the original article has also started work on an optimizing compiler: https://ssloy.github.io/tinyoptimizer/

Re:TinyCompiler: A compiler in a week-end by sieve on Thursday February 20, 2025 @07:38PM (#43122623)
> If all you do is construct an AST and interpret it it's not really a compiler is it.

What if I dumped the AST to disk, called it "bytecode" and updated the "interpreter" to run this "bytecode"? Would you consider that to be a compiler? :-)

> where X includes

I don't consider any of these things to be essential. There are entire languages out there which run on interpreters of some kind. There are others which compile down to C/JS. Many compilers use LLVM as their backend. By your definition, none of them use (or are) compilers.

Re:TinyCompiler: A compiler in a week-end by RossBencina on Thursday February 20, 2025 @08:12PM (#43122888)
> Would you consider that to be a compiler? :-)

:) No. Under my definition there needs to be some non-trivial transformation into or out of an intermediate and/or target representation (either syntax-directed directly out of the parser, or from a materialized AST). Personally I would argue that even if you trivially "compiled" to sequential bytecode, if the bytecode is then interpreted it is hard to argue that you have created a compiler (the pre-JIT cpython interpreter is still an interpreter, even though it includes a bytecode representation). But I can see that this point can be argued, and historically a school exercise of writing a Pascal-to-pcode converter would be called a compiler, so sure, you can take that perspective if you like. Just don't get confused about whether you are learning to build a compiler (definition 1) or a compiler (definition 2).

Re:TinyCompiler: A compiler in a week-end by sieve on Thursday February 20, 2025 @08:24PM (#43122964)
I have written all kinds of compilers, interpreters and vms over the last 15 years. A couple of them for work. The rest for fun. Some vms used RC, others did mark-and-sweep GC. Some vms even did JIT. A lot of them were simple treewalk interpreters because the point was to play with the syntax of the language.

Based on that experience, I would say your definition is more academic than realworldly as javac (or any compiler targeting the JVM) is not a real compiler according to it.

Re:TinyCompiler: A compiler in a week-end by RossBencina on Thursday February 20, 2025 @09:42PM (#43123399)
> javac (or any compiler targeting the JVM) is not a real compiler according to it

I think it depends on how you interpret my "non-trivial transformation into or out of an intermediate and/or target representation". For example if javac involves IR, SSA based analysis and transformation (which I assume it does) then that would be a non-trivial transformation and I'd call it a compiler. If on the other hand it was a direct syntax-directed transformation to java byte code then I'd call it a translator not a compiler. But I'm not claiming any authority over definitions here. Words aren't my strong suit.

Re:TinyCompiler: A compiler in a week-end by sieve on Thursday February 20, 2025 @10:05PM (#43123541)
> if javac involves IR, SSA based analysis and transformation (which I assume it does)

https://github.com/openjdk/jdk/blob/master/src/jdk.compiler/...

I am fairly certain that it does not. The JVM is a stack-machine.

I wrote a compiler for a simple programming language that compiled down to JVM bytecode for a project in the early 2010s. Its output for test programs was as fast as the comparative Java ones because they were fairly similar at the bytecode level.

The HotSpot JVM is where all the optimization effort is applied.

Re:TinyCompiler: A compiler in a week-end by vlovich123 on Thursday February 20, 2025 @11:02PM (#43123888)
I believe there’s some trivial optimization done by the frontend (constant folding, simplifying string concatenation, converting switch statements to lookup tables) but I think they’d agree with you that javac doesn’t really fit their definition of a compiler and that the HotSpot JIT is the true compiler based on how they talked about the Python interpreter pre-JIT.
Re:TinyCompiler: A compiler in a week-end by milesrout on Thursday February 20, 2025 @09:55PM (#43123479)
I strongly disagree with your definition. A naive syntax-directed translation to bytecode or machine code is still compilation. Lots of production compilers do exactly that eg Wirthian compilers.
Re:TinyCompiler: A compiler in a week-end by Tomte on Friday February 21, 2025 @02:09AM (#43124888)
javac does very, very few things. It intentionally emits byte code close to the source program. The HotSpot compiler in the JVM does the heavy lifting.
Re:TinyCompiler: A compiler in a week-end by whartung on Thursday February 20, 2025 @07:18PM (#43122429)
The hardest part (IMHO) about getting a simple language running, particularly for beginners, is the “expression”. Mostly for your typical algebraic style infix expressions with precedence.

Just getting the grammar straight on the naturally recursive structures can be a trick. They also touch a large portion of the code generation and run time.

Get:

  (a + c/2) * sqrt(b)
working and you’re 80% there.
Re:TinyCompiler: A compiler in a week-end by n42 on Thursday February 20, 2025 @08:07PM (#43122846)
well, in my personal experience, parsing is the easiest part. it's what you do with the AST once you have one that is the hard part. but for some reason an overwhelming amount of writing is about frontends when you could teach the concepts to a layman with some boxes and arrows.
Re:TinyCompiler: A compiler in a week-end by andai on Thursday February 20, 2025 @07:26PM (#43122492)
Is that really the hard part? I figured that part out before I knew much programming: made a simple Excel type formula parser. (A horrible, horrible solution based around replacing strings and manually counting parentheses... but it worked!)

I never got much farther than that though, I've looked into making a compiler many times and got overwhelmed every time.

Re:TinyCompiler: A compiler in a week-end by lelanthran on Friday February 21, 2025 @12:54AM (#43124426)
It's hard if:

1. You dont recognise the recursive nature of the problem,

Or

2. You don't recognise the stack-based nature in the problem (shunting yard algo, etc).

IOW, you did it the hard way :-).

Re:TinyCompiler: A compiler in a week-end by PhilipRoman on Friday February 21, 2025 @02:11AM (#43124897)
Good to know I wasn't alone in writing terrible expression parsers. Since I knew absolutely nothing about parsing, my parser/interpreter consisted of splitting on whitespace, followed by linear scanning to find the most high precedence operation, repeated until a single token remains (basically how a human would do it).
Re:TinyCompiler: A compiler in a week-end by sieve on Thursday February 20, 2025 @07:29PM (#43122528)
> The hardest part (IMHO) about getting a simple language running, particularly for beginners, is the “expression”

This is why teaching material should be tailored towards teaching rather than implementing demented stuff from the real world just because it is "there." You can easily implement a parser that ignores precedence and tell the reader that we are using brackets to force precedence instead.

In a real-word parser, you might use something like this[1] or some other home-grown algorithm if you didn't know about it. Doesn't matter as long as the parser works.

[1] Top-Down operator precedence (Pratt) parsing https://eli.thegreenplace.net/2010/01/02/top-down-operator-p...

Re:TinyCompiler: A compiler in a week-end by milesrout on Thursday February 20, 2025 @08:29PM (#43123008)
I think the hardest part is function calls. Implementing the standard calling convention is really fiddly and annoying when you have to save and restore registers around function calls if you want to do it efficiently (keeping track of which registers are dirty, doing parallel loads of registers into the right argument registers, spilling when appropriate, etc. It is fiddly.

The alternative is going to an IR and doing full register allocation but then you need to implement Lengauer-Tarjan to get into SSA, all the same parallel load stuff for phi functions/block arguments, out-of-SSA, reconstruct in optimisation passes all the information you discard by going to a linear IR, etc.

Re:TinyCompiler: A compiler in a week-end by haqreu on Friday February 21, 2025 @02:15AM (#43124921)
I'd argue that Lengauer-Tarjan is overrated. While it is neat, it's premature optimization IMHO. Fully maximal SSA (at the entry of each block insert a phi-node for each variable) + dead code elimination (we need it anyways) is much simpler.
Re:TinyCompiler: A compiler in a week-end by contificate on Friday February 21, 2025 @04:32AM (#43125700)
Typical implementations of Lengauer-Tarjan are often taken verbatim from Andrew Appel's book and involve higher constant factors than alternative algorithms - such as Cooper et al's "engineered" version of the usual fixpoint algorithm, which is very neat, simple, and performs well.

If you are saying that constructing SSA following the classical approach is a premature optimisation, perhaps you would prefer Braun et al's retelling of Cliff Click's SSA construction algorithm - which works backwards from uses to place phis and requires no dominance information to be computed.

Re:TinyCompiler: A compiler in a week-end by haqreu on Friday February 21, 2025 @05:04AM (#43125856)
Thank you for the reference, I'll check it.

Why not fully maximal SSA + DCE? I mean, other than timings consideration. Fully maximal does not even need any graph traversal, it is entirely local to each block.

Re:TinyCompiler: A compiler in a week-end by contificate on Friday February 21, 2025 @05:32AM (#43126024)
I think it will introduce too many redundant phis, but I've never used it in practice - so I can only speculate. I'm not convinced DCE will clean maximal SSA up substantially. Even the classic Cytron et al algorithm must be combined with liveness analysis to avoid placing dead phis (that is, it does not produce pruned SSA by default). In the past, there was always a fear that SSA has the potential to cause quadratic blowup in the number of variables - this concern is mostly theoretical but probably influenced some of the design decision around algorithms for constructing SSA.

Braun et al's algorithm works backwards from uses (which generate liveness), so you get pruned SSA out. In the case of reducible control flow graphs, you also get minimal SSA. This is all without any liveness or dominance computation beforehand. Granted, you may want those things later, but it's nice that you can construct a decent quality SSA with a fairly intuitive algorithm. Also shown in the paper is that you can incorporate a few light optimisations during SSA construction (constant folding, for example).

Re:TinyCompiler: A compiler in a week-end by haqreu on Friday February 21, 2025 @06:55AM (#43126514)
I'll definitely test maximal SSA + DCE in tinyoptimizer when I'll get to it. For the moment I made [1] somewhat-pruned mem2reg pass, not even sure how to call it. But it indeed required to compute dominance frontiers.

[1] https://ssloy.github.io/tinyoptimizer/mem2reg/

Re:TinyCompiler: A compiler in a week-end by contificate on Friday February 21, 2025 @10:22AM (#43128467)
Nice.

I'm always happy to see more accessible resources for compiler writers.

---

As an aside: for displaying CFGs on the page, it would be very interesting to emit something somewhat dynamic. SVGs are always a good start, but there is a neat library for doing hierarchical graph layout (dagre, with d3-dagre handling rendering as well). In my own efforts at pedagogy, I've been interested in producing CFGs in-browser whose basic blocks comprise a "unified diff" view of the block (this being achieved in realtime by maintaining a subset of LLVM whose CFGs are persistent). Then it is more obvious what has changed: at least in the case of mem2reg which shouldn't introduce new blocks or move too much around (I forget if it hoists allocas to the entry block or not).

It'd also be cool to distil what underlying ideas you have found to be most useful in your efforts. The constrained scope of them may be useful to me, as I've wanted to create a kind of "advent of compilers" for years (advent of code but with a heavy slant towards compiler tasks/algorithms).

Re:TinyCompiler: A compiler in a week-end by haqreu on Friday February 21, 2025 @05:40AM (#43126071)
Thank you!
Re:TinyCompiler: A compiler in a week-end by Rohansi on Friday February 21, 2025 @01:11AM (#43124515)
Pratt parsers are a really nice way to handle mathematical expressions like this vs. the usual recursive descent.

https://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-...

Re:TinyCompiler: A compiler in a week-end by rurban on Friday February 21, 2025 @02:07AM (#43124875)

    (a + c/2) * sqrt(b)
is not a simple language.

    (* (+ a (/ c 2)) (sqrt b))
would be a simple and precise to parse language, and the typical compiler for this is written in a day. Search for SIOD
Re:TinyCompiler: A compiler in a week-end by jcuenod on Thursday February 20, 2025 @06:51PM (#43122152)
Honestly, antlr made this pretty straightforward to me. I didn't want to work in java, but they have a ton of targets. You can definitely write it all yourself, and that's a great learning exercise. But I wanted to get a parser for a language idea I had in mind and it took a couple of days with antlr (https://github.com/chicory-lang/chicory)
Re:TinyCompiler: A compiler in a week-end by sieve on Thursday February 20, 2025 @06:56PM (#43122212)
Problem with these tools is, you have to spend time wrangling them instead of learning to write a lexer/parser yourself.

A recursive-descent parser is a beautiful thing and can be implemented very quickly.

Re:TinyCompiler: A compiler in a week-end by sitkack on Thursday February 20, 2025 @06:33PM (#43121947)
5 days if you don't, but have the right tutor.
Re:TinyCompiler: A compiler in a week-end by sieve on Thursday February 20, 2025 @06:40PM (#43122025)
If you know basic programming (js/python), a day is more than enough to get the concept across using a tiny language. Could probably be done in an hour.

The problem, always, is people are given terrible reading recommendations which makes the subject more complicated than it is.

Re:TinyCompiler: A compiler in a week-end by RossBencina on Thursday February 20, 2025 @08:21PM (#43122943)
I never took a compilers course. The first reading recommendation I got was The Dragon Book. Perhaps not the worst starting place at the time (mid 90s) but my memory of it was that the book was front-loaded with automata and parser theory. At the time I didn't really make it past the front end. It would be interesting to see a compiler tutorial that started at codegen and worked backwards (or started at the ends: lexing and codegen, and worked towards the middle in alternating chapters).
Re:TinyCompiler: A compiler in a week-end by sieve on Thursday February 20, 2025 @08:33PM (#43123041)
The Dragon Book is terrible as an introduction. There are better books I would probably recommend, but not to a beginner. The best "complete" intro out there today is Nystrom's Crafting Interpreters.[1]

[1] https://www.craftinginterpreters.com/contents.html

Re:TinyCompiler: A compiler in a week-end by RossBencina on Thursday February 20, 2025 @09:35PM (#43123366)
> There are better books I would probably recommend

I'm curious what you'd recommend.

For what it's worth my goal was to compile to machine code. Anything less would have seemed insufficient. Later I got Appel's "Modern Compiler Implementation in Java" and Allen and Kennedy "Optimizing Compilers for Modern Architectures".

Cooper and Torczon "Engineering a Compiler" was recommended here recently. I haven't seen it.

Re:TinyCompiler: A compiler in a week-end by sieve on Thursday February 20, 2025 @09:54PM (#43123469)
I got started from the books that were available here in the early 2000s. The one I like the most is "Programming Language Pragmatics" by Michael Scott, mainly for its simplicity. Then there is "Advanced Compiler Design and Implementation" by Steven Muchnick. I have Allen-Kennedy's book too, but I think it went over my head when I went through it. So I kept it aside.

"Engineering a Compiler" is quite approachable.

But, once you know the basics, you get the best bang-for-the-buck by looking at source code of various compilers and virtual machines.

Re:TinyCompiler: A compiler in a week-end by sitkack on Friday February 21, 2025 @02:25AM (#43124981)
There is a whole body of non-academic work aimed at practioners for implementing compilers.

Nils Holm's work https://t3x.org/

Teaching and Learning Compilers Incrementally - Jeremy Siek - RacketCon 2023 https://www.youtube.com/watch?v=43VA_QaTRT8

Nanopass https://nanopass.org/

original paper that was the basis for nanopass http://scheme2006.cs.uchicago.edu/11-ghuloum.pdf

https://www.reddit.com/r/ProgrammingLanguages/comments/gnzra...

The Crafting Interpreters and the Thorsten Ball books

https://craftinginterpreters.com/contents.html

https://interpreterbook.com/ https://compilerbook.com/

https://www.phind.com/search/cm7efcpv000002e6hqdbfojex

Re:TinyCompiler: A compiler in a week-end by ratmice on Friday February 21, 2025 @01:53PM (#43131400)
I don't think that the ghuloum 2006 paper was the initial basis for nanopass, at least the paper A Nanopass Framework for Compiler Education∗ seems to predate it in 2004 https://dl.acm.org/doi/10.1145/1016848.1016878
Re:TinyCompiler: A compiler in a week-end by delta_p_delta_x on Friday February 21, 2025 @04:59AM (#43125827)
> It would be interesting to see a compiler tutorial that started at codegen and worked backwards (or started at the ends: lexing and codegen, and worked towards the middle in alternating chapters)

This is exactly how my university's compiler course did it[1]. It was really nice to start with assembly and go upwards. We had all the lexing/parsing stuff being discussed around the middle of the semester rather than being saddled with theory-heavy regex, automata theory, etc right at the beginning.

[1]: https://ilyasergey.net/CS4212/

Re:TinyCompiler: A compiler in a week-end by mattgreenrocks on Thursday February 20, 2025 @06:24PM (#43121848)
One weekend is enough to survey the general concepts. That’s extremely useful on its own, as now you have a better idea of how to orient yourself.
Re:TinyCompiler: A compiler in a week-end by ramon156 on Thursday February 20, 2025 @06:28PM (#43121886)
You set your own bar. you could understand "how a compiler" in a day, but how much do you want to know?
Re:TinyCompiler: A compiler in a week-end by duped on Thursday February 20, 2025 @10:44PM (#43123782)
All a compiler does is take a well defined data structure and transform it into another, sometimes by encoding or sometimes by decoding. Really it's bread and butter stuff that every engineer does everyday but with the benefit that you can say something is undefined/out of scope way easier than talking to APIs you don't control.

The fun part are the magic algorithms you sometimes get to use

Re:TinyCompiler: A compiler in a week-end by jcranmer on Friday February 21, 2025 @12:45AM (#43124380)
> All a compiler does is take a well defined data structure and transform it into another

Sorry, having worked on language semantics topics, "well-defined" is not how I would describe either a programming language or the behavior of machine code.

Re:TinyCompiler: A compiler in a week-end by storoj on Friday February 21, 2025 @01:09AM (#43124505)
There should be a well-defined list of undefined behaviors.