Go Generate and AST
The apostle Paul in prison | Rembrandt Harmenszoon van Rijn

Go Generate and AST

I recently have been playing around with Go’s built in generator for the standard go compiler. I love the idea of a language having reflection, but what I love more is a way for the language to have a way to generate boiler plate code. The benefit of generated code over reflection is performance and compile time checks. In reflection you’re often fiddling with non compile checking strings, you may have fields or functions that get completely stripped from not being used, and other things you just have to infer.

Go Generate

The key to generating Go code is to use the built in //go:generate comment. You can use this anywhere in the file, but I like to use it as a decorator for things like structs. For example, in the following:

Go generate structure example
Adding //go:generate above struct

In this case you'll notice I've placed //go:generate go run ../generators/serialized/main.go right above the struct. The reason for this is that the file, line number, and package are passed as environment variables (GOFILE, GOLINE, and GOPACKAGE respectively). This allows us to snipe the exact struct based on the provided line number in the file.

Another great feature you may have noticed is that I didn't need to compile a separate executable constantly, I can just use go run ../generators/serialized/main.go. This allows me to have the generator code directly in my project and to call it up whenever it is needed. Once you've got all this setup, you can use:

Parsing the AST

From here, the world is your oyster, you can go ahead and write out your code generator. Note that I like to use parser.ParseComments as I put extra generation context in comments. Just remember to put a comment at the top of your generated file like // Code generated by "serialized"; DO NOT EDIT., this way the go tools can help with warning you or others about not editing the file.

Walking the AST

As a bonus, I'll go over a little bit on how you can walk the AST from this generated code. Let's say that we just wanted to get the specific struct within the file that is directly below the generate comment. Here is a simple way of doing that:

Getting the struct just under the //go:generate comment

This wasn't pretty, but it'll get the job done. Basically you need to find the position of the comment by looking through the source code. Once the position is found, you need to match it up to a position of a declaration in the ast. If you were to want to get all structs within the entire file, rather than just the one directly under the comment, you can just remove all the position stuff, which means you don't need to read the file source and you can just use the file directly.

Get all structures in the file

Note: You can click on any image of code to view copyable code, or you can get a copy of any code in this article from my website.

要查看或添加评论,请登录

Brent Farris的更多文章

  • x64 Assembly

    x64 Assembly

    Something that I have gotten really into recently is x64 Assembly programming. So, I thought I would jot down some of…

  • Notes on Writing a Ray Tracer using CUDA

    Notes on Writing a Ray Tracer using CUDA

    What took the CPU (1 thread) over 30 seconds to render, I was able to get CUDA to render in ~20 milliseconds. There are…

  • BIOS Programming in VirtualBox

    BIOS Programming in VirtualBox

    There are three things I want to explain how to do here, (1) basic BIOS interrupts, (2) reading keyboard input, and (3)…

    1 条评论
  • The rise of programming specialists

    The rise of programming specialists

    The more software developers (programmers) that I see enter the job market, the more I see programmers isolating…

社区洞察

其他会员也浏览了