Writing a Compiler in Go
squanch.org
squanch.org
I also got interested in it and found the same article from 1988 that OP is referencing, which resulted in me writing a simple BASIC to DCPU-16 ASM compiler, also in Go [0]. The code isn't of very high quality (it was just a pet project) but if anyone wants to take a look, go ahead.
[0]: http://www.zachtronics.com/tis-100/ [1]: https://en.wikipedia.org/wiki/Zachary_Barth
My one gripe with it however is that it takes the middle ground between teaching assembly to people unfamiliar with programming and those who already have some knowledge, and doesn't quite satisfy either.
I would recommend using that as a template for one's own compiler, because it's written in idiomatic Go (originally by the language creators) and is cleanly split across abstraction boundaries (packages "scanner", "parser", "ast", and so on.)
There's also a smaller, simpler parser in the "text/template/parse" package, that is used to parse the templating languages in "text/template" and "html/template". As an introduction to it, I recommend the talk "Lexical Scanning in Go" by Rob Pike:
The careful package split is something to be copied, though.
See "Go, From C to Go by Russ Cox" (with video) at https://github.com/gophercon/2014-talks
High quality? Isn't the compiler since 1.5 auto-generated from C for the most part, and quite crap with regards to optimizations/readability?
The provided scaffolding code is either Java or C++, but with a bit more work, it's perfectly reasonable to re-write it in whatever language you desire. Here's mine, in Go: https://github.com/zellyn/gocool
Admittedly, it is the world's dumbest compiler (uses a single register, and there's no optimization), but it's still fun to actually "slay the dragon" and stop believing that only wizards can build a compiler. :-)
Generating bytecodes in a suitable text format, that can be either be easily validated and executed with a dumb interpreter, or translated into machine code via a Macro Assembler.
Surely the code performance sucks, but it gives the students the gratification of producing something that executes real machine code and that they can show off to their friends.
It has a lot of theory, which may not be terribly interesting if you just want to learn to build a compiler, but it's complete and the language you're building the compiler for has a little bit of everything.
> What I came up with is very-much-not-idiomatic-go, but it does map (basically) line for line with the original Turbo Pascal.
Why not use this as an exercise in how to write idiomatic Go? The backdrop of wanting to apply Go isn't exactly followed up on if you're just going to copy completely different idioms without any regard for your new language.
I know it's touched upon later in the piece, but it really doesn't make sense to make this an afterthought.
As a separate project I would certainly like to write a compiler that takes advantages of go's features.
Reading the source of the Go stdlib is a good exercise in preparation of "letting go" of your idiosyncratic perspective. In that regard it doesn't matter if you are coming from Java or Haskell or any other "world".
"Perspective is worth 80 IQ points." - Alan Kay
(who probably hates Go but that's OK too ;)
https://en.wikipedia.org/wiki/Web_Content_Accessibility_Guid...
However, if you write things idiomatically and use a bit of thought, it's not hopeless, either. You can write type-safe nodes with interfaces, for instance:
type ArithExpr struct {
Op ArithOp
L ArithNode
R ArithNode
}
where ArithNode is definitely an interface (implemented by ArithExpr) and ArithOp may be, depending on your mood. "Pattern matching" can not be perfectly replicated, especially if you deeply match, but "run this on ArithNodes recursively" is actually not that hard to express. Invert the pattern matching into method calls; it isn't a perfect translation but it hits many of the use cases. Modest cleverness in the methods may be helpful, for instance, it may be helpful for all nodes to implement a "RunOnNodeIfArithNode" method that usually does nothing, and only works on ArithNodes, to avoid a lot of assertions and checking in the core algorithms, that sort of thing. Don't try to port a pattern-matching approach, use the native stuff you've actually got. In the end I can't promise you'd never have any type assertions, but it should be possible to write a compiler that isn't drenched in them.Still not my first choice, though. Might prefer it over Python, though; it would certainly be more verbose but the way I'd use the strong typing would probably make up for that in safety.
What you just said has got this old Smalltalker starting to think of pattern matching as "polymorphism on steroids." Is that what it actually is?
My real point here is use what you've got; trying to use object polymorphism in Haskell would be as big a mistake there as trying to naively jam pattern matching into Go. Stick to the native idioms as much as possible. While I agree that Go's native idioms are limiting compared to some other languages I also think a lot of people grossly overestimate the limitations.
Huh? While it has both, Go is as far from lambdas and reflection as you can go and still be modern language.
Most C compilers are written in C. I would not argue that C is a language particularly suited to writing compilers though.
Uau! Great idea, I went through those tutorials back when I started hanging around USENET comp.compilers group.
I learned a lot with them, nice to see them being brought to newer generations.
It is largely transliterated from the Inferno version
written in Limbo which in turn was largely transliterated
from the Plan 9 version written in C and documented at
http://plan9.bell-labs.com/magic/man2html/1/yacc
For a real example in action, see the mtail project: https://github.com/google/mtail/blob/master/vm/compiler.goI built e8vm.io (https://github.com/e8vm/e8vm, https://e8vm.io), which is all written in go, and it has a full-blown compiler, with no optimizations though. The language has go-like syntax and C-like run time.
shanhu.io (https://shanhu.io) provides an online playground for the language, which runs the compiler right inside the browser, thanks to gopherjs.