Created Tutorial: Hacking the Nimrod compiler: Pragmas (markdown)
This commit is contained in:
parent
2579d00ee0
commit
00714f14fb
|
@ -0,0 +1,73 @@
|
|||
## Introduction
|
||||
As there are no tutorials (that I know of) on how to add new features to the nimrod
|
||||
compiler I have decided to make one, based on me implementing the `requires`
|
||||
pragma which will be used for Babel Packages.
|
||||
|
||||
As with many tasks there are many tools that are very helpful, I have used
|
||||
the *nimgrep* tool which is in the tools/ directory in Nimrod's repository, but I'm sure you know of other tools which can be very helpful!
|
||||
|
||||
## First steps
|
||||
The first thing I have decided to do was create a test file, it follows:
|
||||
|
||||
{.requires packageA "0.7" "0.9".}
|
||||
echo("hi")
|
||||
|
||||
(It originally had a `..` between the two string literals, I decided to get rid
|
||||
of that because I noticed that pragmas don't support it, I might come back to it.)
|
||||
|
||||
I then saved that file as *"pragmaTest.nim"* and compiled it with
|
||||
`nimrod c pragmaTest.nim`. This has caused `pragmaTest.nim(1, 10) Error: invalid pragma: requires`.
|
||||
|
||||
The next step was quite obvious, searching for "invalid pragma:", `nimgrep --recursive --ext:nim "invalid\ pragma:"`,
|
||||
this only gives one result.
|
||||
|
||||
../Nimrod/rod/msgs.nim
|
||||
258: errInvalidPragmaX: "invalid pragma: $1",
|
||||
|
||||
After some more intellectual grepping and looking through files, I noticed that the pragma() function in pragmas.nim
|
||||
takes an argument called `validPragmas` this lead me to *semtypes.nim* and *semstmts.nim*
|
||||
after searching for (yes, you've guessed it) `pragma(`(please note this needs escaping when used as a regex).
|
||||
|
||||
There was many `pragma` calls, I have looked at most of them and since I wanted
|
||||
a "global"(not sure if that's the correct term) pragma, for example
|
||||
`{.warning: "warning".}`. The `pragma` function is called with many different
|
||||
valid pragma groups. There is among many others, `stmtPragmas`, which is what
|
||||
I wanted, it's defined in *pragmas.nim*.
|
||||
|
||||
## Hacking the code!
|
||||
I found where `TSpecialWords` is defined(*wordrecg.nim*) and added `wRequires`
|
||||
there, to the `specialWords` array below, and also to `stmtPragmas`. I then added `wRequires` to the case statement in the `pragma` function in *pragmas.nim*.
|
||||
|
||||
This is where the `debug` function came into play, it is a function that pretty prints a
|
||||
node in the AST, it is very useful. I added two `debug` calls one for the 'it' node
|
||||
and another one for the 'n' node.
|
||||
|
||||
I then bootstrapped by executing `./koch boot`. After I got the beautiful "SUCCESS",
|
||||
I compiled *pragmaTest.nim*. And I got this output:
|
||||
|
||||
{
|
||||
"kind": "nkIdent",
|
||||
"ident": "requires"
|
||||
}
|
||||
{
|
||||
"kind": "nkPragma",
|
||||
"sons": [
|
||||
{
|
||||
"kind": "nkIdent",
|
||||
"ident": "requires"
|
||||
},
|
||||
{
|
||||
"kind": "nkIdent",
|
||||
"ident": "packageA"
|
||||
},
|
||||
{
|
||||
"kind": "nkStrLit",
|
||||
"strVal": "0.7"
|
||||
},
|
||||
{
|
||||
"kind": "nkStrLit",
|
||||
"strVal": "0.9"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue