Live data from Hacker News

Writing a C compiler in 500 lines of Python (2023)

vgel.me

31–40 of 114 posts

Re: Writing a C compiler in 500 lines of Python (2023)

#31

Earlier quoted context omitted.

Fast to run or fast to compile?

Fast to compile. It was very fast comparing to the others then. Since computers were slow (8086/80286) compiling speed actually mattered. https://www.pcengines.ch/tp3.htm

As an ex-Gentoo user I can confirm that compiling speed still matters on certain machines.

Re: Writing a C compiler in 500 lines of Python (2023)

#32
post #23

I find it surprising that a single-pass compiler is easier to implement than a traditional lexer->parser->AST->emitter. (I'm not a compiler expert, though.) I'd have expected that generating an AST would be at least as simple, if not simpler. Plus by generating an AST, doing some simple optimization is a lot easier: one can pattern-match parts of the AST and replace them with more efficient equivalents. Maybe I'm ove…

I think this might depend on the language you're writing in. Historically, at least, it's pretty verbose to define a data type in Python compared to languages that are more designed for writing compilers. Consider these definitions from my prototype Bicicleta interpreter, which is written in ML, specifically OCaml: type methods = NoDefs (* name, body, is_positional ... *) | Definition of string * bicexpr * bool * met…

My impression is that in general the traditional approach of methods as members of a class is more verbose and less extensible than the ML/Lisp generic function approach. I know I certainly prefer generic functions when I have to design polymorphic interfaces.

Re: Writing a C compiler in 500 lines of Python (2023)

#33
post #7

Now write a Python compiler in 500 lines of C.

A python VM that consumes bytecode might be doable in not-ludicrous-amounts of C. Not 500 lines I suppose. But something manageable I think? Especially if you targeted the older releases.

In the CPython reference interpreter, that VM can be found at

https://github.com/python/cpython/blob/main/Python/ceval.c

It's 3619 lines. It's explained in this 515 line file:

https://github.com/python/cpython/blob/main/InternalDocs/

For comparison, there is a pure Python bytecode interpreter, its VM is here:

https://github.com/nedbat/byterun/blob/master/byterun/pyvm2....

It's 1043 lines.

Re: Writing a C compiler in 500 lines of Python (2023)

#35

Earlier quoted context omitted.

Fast to compile. It was very fast comparing to the others then. Since computers were slow (8086/80286) compiling speed actually mattered. https://www.pcengines.ch/tp3.htm

As an ex-Gentoo user I can confirm that compiling speed still matters on certain machines.

I have never worked as a system programmer so I never had the need to compile something big. I guess it could be an issue with very large software like Oracle Database, the Linux kernel and other similar stuffs.

Re: Writing a C compiler in 500 lines of Python (2023)

#36
post #6

This article breaks it down well enough to make me feel like I could write my own C compiler targeting AVR. (I probably could... but it would not be easy.) Never actually looked into how compilers work before, it's surprisingly similar/related to linguistics.

You should study C4, which is a C(subset) compiler in ~500 lines, but more interestingly, it can compile itself: https://news.ycombinator.com/item?id=8558822

Re: Writing a C compiler in 500 lines of Python (2023)

#37
post #23

I find it surprising that a single-pass compiler is easier to implement than a traditional lexer->parser->AST->emitter. (I'm not a compiler expert, though.) I'd have expected that generating an AST would be at least as simple, if not simpler. Plus by generating an AST, doing some simple optimization is a lot easier: one can pattern-match parts of the AST and replace them with more efficient equivalents. Maybe I'm ove…

I think this might depend on the language you're writing in. Historically, at least, it's pretty verbose to define a data type in Python compared to languages that are more designed for writing compilers. Consider these definitions from my prototype Bicicleta interpreter, which is written in ML, specifically OCaml: type methods = NoDefs (* name, body, is_positional ... *) | Definition of string * bicexpr * bool * met…

GC doesn't matter much for a simple compiler, as you either don't need to allocate much (single pass, Wirth-style compilers that generate code inline) or most of what you allocate becomes garbage all at once at the end (AST).

In my half-finished Ruby compiler prototype, even before I added type tagging, and so allocated every integer on the heap, I just didn't add a GC for a long time because it was fine to just leak, because the compiler isn't generally long running.

Re: Writing a C compiler in 500 lines of Python (2023)

#38
post #15

Now write a Python compiler in 500 lines of C.

Not to be that guy, but Python is an interpreted language. That said, I guess technically you could make something that compiles python to an executable? This is hacker news after all

A language is not inherently interpreted or compiled.

Some languages are more or less easy to compile efficiently and without embedding a JIT compiler, but any language can be compiled.

For Python in particular, there are already compilers.

If you want a nightmarish language to compile, look at Ruby. There are compilers even for Ruby.

Re: Writing a C compiler in 500 lines of Python (2023)

#39
post #37
post #23

Earlier quoted context omitted.

I think this might depend on the language you're writing in. Historically, at least, it's pretty verbose to define a data type in Python compared to languages that are more designed for writing compilers. Consider these definitions from my prototype Bicicleta interpreter, which is written in ML, specifically OCaml: type methods = NoDefs (* name, body, is_positional ... *) | Definition of string * bicexpr * bool * met…

GC doesn't matter much for a simple compiler, as you either don't need to allocate much (single pass, Wirth-style compilers that generate code inline) or most of what you allocate becomes garbage all at once at the end (AST). In my half-finished Ruby compiler prototype, even before I added type tagging, and so allocated every integer on the heap, I just didn't add a GC for a long time because it was fine to just leak…

Yeah, I never got around to writing a GC for Ur-Scheme either—you could argue that it's also "half-finished" but it does successfully compile itself correctly. It's not so much the GC that matters as it is the ability to allocate on the heap without much ceremony. I should have thought of that before I posted, and I appreciate the correction.

Re: Writing a C compiler in 500 lines of Python (2023)

#40
After many years of programming in other languages, I finally learned C, and came to realize that there aren't actually any compilers that implement all of the C spec. Even GCC and Clang have their grey areas and their bugs.

Before this, I had thought that C was a simple language. An idea propped up by articles likes this, as well as the oft touted fact that nearly every embedded system has a C compiler; no matter what you'll always have a C compiler.

This point was driven home by part of a blog post that simply states "you can't actually parse a C header"[0]. The blog makes a good supporting case for their claim. They link to a paper that says[1]:

> There exist many commercial and academic tools that can parse C.... Unfortunately, these parsers are often either designed for an older version of the language (such as C89) or plain incorrect. The C11 parsers found in popular compilers, such as GCC and Clang, are very likely correct, but their size is in the tens of thousands of lines.

And sure enough, in the OP linked blog post, they state they are only implementing a subset of the language. Of course, it still has value as a teaching tool; this is just a tangential fact about C I wanted to discuss.

[0]: https://faultlore.com/blah/c-isnt-a-language/#you-cant-actua...

[1]: https://hal.science/hal-01633123/document

Post reply on HN