Hacking on Crystal Language
Você pode ver esse post em português
Yesterday I started to help on Crystal Programming Language, so here I’d like to share my thoughts as well serve as future reference.
- Issues that needs verification (current codebase)
- Reduce to minimal examples
- Work on small pulls requests
As I knew codetriage.com, I started looking for some old issues to contribute at least verify if still apply to current codebase.
My first challenge has put the compiler running with some releases (as crystal still doesn’t have a multi-version manager, brew did the job). The idea was to compile some versions and use brew switch.
You can check this gist on how to accomplish this.
After installed recent crystal lang versions I started digging into issues and found a simple one on the compiler. To work on compiler issues is must test against compiler head, so here are the steps to get compiler working:
Really easy, so let’s start hacking time!
First, I chose issue #194, don’t ask me why I thought would be an easy one hahah
Then when looking for a solution, I found a typo on docs and fixed. First PR sent, cool! It’s a nice way to warm up.
ps: Crystal build tests for formatting, including on documentation, so when sending a doc PR don’t use [skip ci]
The workflow for making a change on compiler is:
- make crystal spec
make crystal spec takes a lit bit longer, so you may find useful just
run a specific spec, then run
make crystal spec before committing.
ps: As I was playing with the compiler, I did
make clean crystal spec
before PR, just to recompile the compiler and check if everything was
ok, first-time specs were passing, but I broke the compiler hahaha this
is a useful tip ;)
I think everything before was just the introduction and context, let’s now really get into Crystal code.
If you read the issue, was a problem with the enum, values were being
i32 if not enum base type was specified and default (
was assumed, it’s crucial to understand the issue and terms
used because it will make easier to search the code.
I started looking at the specs for something similar (Crystal uses the
prefix for C bindings, as this is a problem on LibC binding example,
began on these files).
Found the spec/compiler/type_inference/c_enum_spec.cr and added the following test (based on other tests) to make it red:
ps: Its a crystal convention to add
(#123) to identify the issue that
test is covering.
Now was time to make it green, how do this? It was time to work on compiler source code.
As far as I remember from compiler classes, it wouldn’t be a lexer job
because the tokens were ok, just the meaning wasn’t then on
src/compiler/crystal I found the
semantic folder and searched for
enum exception being triggered.
Then, I found this exception being raised, and thought “cool, found an enum value check, so let’s start working on this piece of code.”
After a few time, I made it green with the code
This one checks the enum base type (it is the default one if value is
then if any value is not an
i32 then an exception is raised. (any
question about this leave in the comments)
make clean crystal spec and make sure everything is ok.
ps: Don’t forget to run
crystal tool format to format the source code.
After all of this, PR opened!
This contribution was an enjoyable time, I’d like to enumerate some reasons:
- It took 4 hours the complete process, never thought would be possible to make my first contribution in so fewer time.
- As the compiler is written in Crystal, it’s easy to read / code (I’m not an experienced Crystal dev)
- Contributing to a compiler/programming language is amazing.
- I learned a lot of compile-time / runtime in Crystal
- Here I put the obvious steps (I did A LOT of mistakes before make it working)
Would like to thank @jhass for all patience and support during this journey.
I hope this post serve as an inspiration to other contributors, after reading this, do you consider contributing to Crystal or another programming language?