ポエム
Nim
ソースコードリーディング

この記事は Nim Advent Calendar 2017 の記事です。

tl;dr

ソースコードを読んだ感想文です。もっとテクニカルなことを期待している皆様、すみません。

筆者について

今年初めての参加なので、自己紹介を少し。

  • Nim書いてません
  • 気が向いたらxv6のコードを読んでます
  • PHPエンジニアという肩書です
  • 仕事ではPowerShellとシェルスクリプトを書きます
  • 月収10万円です

rstast.nim とは

Nimの標準モジュールrstastの実装コードです。
名前からもわかるかもしれませんが、RestructuredTextの抽象構文木を実装したものです。

Githubでも公開されています
今回はGithubに2017年12月3日時点でのソースコードを引用して感想を述べたいと思います。

なんで実装コード読んだの?

2ヶ月前ほど、Go言語製静的サイトジェネレーターHUGOに触発され、
RestructuredTextをソースにした静的サイトジェネレータがあったら良いなあと思い、Nimでの実装を覗いてみたので、今回はその感想を書かせていただきます。

実際に読んでみて

以降、読んでみて抱いたくだらない所感を書いていきます。

筆者が特に感動した部分しか解説しません。ソースコードに興味を持たれた方は、是非Githubで公開されているソースコードを読むことをお勧めします。

Types

型の列挙ではありますが、

type
  RstNodeKind* = enum        ## the possible node kinds of an PRstNode
    rnInner,                  # an inner node or a root
    rnHeadline,               # a headline
    rnOverline,               # an over- and underlined headline
    rnTransition,             # a transition (the ------------- <hr> thingie)
    rnParagraph,              # a paragraph
    rnBulletList,             # a bullet list
    rnBulletItem,             # a bullet item
    rnEnumList,               # an enumerated list
    rnEnumItem,               # an enumerated item
    rnDefList,                # a definition list
    rnDefItem,                # an item of a definition list consisting of ...
    rnDefName,                # ... a name part ...
    rnDefBody,                # ... and a body part ...
    rnFieldList,              # a field list
    rnField,                  # a field item
    rnFieldName,              # consisting of a field name ...
    rnFieldBody,              # ... and a field body
    rnOptionList, rnOptionListItem, rnOptionGroup, rnOption, rnOptionString,
    rnOptionArgument, rnDescription, rnLiteralBlock, rnQuotedLiteralBlock,
    rnLineBlock,              # the | thingie
    rnLineBlockItem,          # sons of the | thing
    rnBlockQuote,             # text just indented
    rnTable, rnGridTable, rnTableRow, rnTableHeaderCell, rnTableDataCell,
    rnLabel,                  # used for footnotes and other things
    rnFootnote,               # a footnote
    rnCitation,               # similar to footnote
    rnStandaloneHyperlink, rnHyperlink, rnRef, rnDirective, # a directive
    rnDirArg, rnRaw, rnTitle, rnContents, rnImage, rnFigure, rnCodeBlock,
    rnRawHtml, rnRawLatex,
    rnContainer,              # ``container`` directive
    rnIndex,                  # index directve:
                              # .. index::
                              #   key
                              #     * `file#id <file#id>`_
                              #     * `file#id <file#id>'_
    rnSubstitutionDef,        # a definition of a substitution
    rnGeneralRole,            # Inline markup:
    rnSub, rnSup, rnIdx,
    rnEmphasis,               # "*"
    rnStrongEmphasis,         # "**"
    rnTripleEmphasis,         # "***"
    rnInterpretedText,        # "`"
    rnInlineLiteral,          # "``"
    rnSubstitutionReferences, # "|"
    rnSmiley,                 # some smiley
    rnLeaf                    # a leaf; the node's text field contains the
                              # leaf val

読者として有難かったのは、ちゃんとコメントで、
「この列挙型のアイテムは、このマークアップに対応してるよ」
と書いており、容易にこのセクションの定義を読むことができました。

また、読み始めは疑問符が頭に浮かんでいた接頭の rn ですが、 RstNode の省略だと分かれば、むしろ丁寧な列挙をしているなと思いましたし、そこまで丁寧にするということは、頻発する(よく使う)列挙型なのは、容易に想像できる気がします。

proc renderRstToRst

一番処理をゴリゴリ書いていて、読み応えのある部分かもしれません。

実際に読んで頂いたほうが、ここで変な解説や感想を入れて説明するよりはわかるかと思いますので、該当箇所へのリンクを貼っておきます。

rstast.nim#L111 - proc renderRstToRst


今回は rstast 単体をフォーカスして読みましたが、合わせて rstモジュールのソースコードと一緒に読むと、もっと理解が深まるかもしれません。

まとめ

実装のコードを臆することなく読むと、

  • 言語開発者が考えているであろう理想のコーディング
  • 読みやすいコードの書き方
  • コードの読み解き方

という、良いコーディング作法が読み取れる気がするので、楽しいと思います。

レッツ、ソースコードリーディング!