Flat Leon Works

アプリやゲームを作ってます。

【Nim】メモ

基本情報

作者 : Andreas Rumpfさん ( GitHubではAraqという名前 )

リンク

標準ライブラリ

標準ライブラリ : Nim Standard Library

  • 言語コア機能
    • system : ライブラリとして実装されている言語機能など。暗黙にimportされる
    • macros : マクロ関係。マクロを使う場合はimportする必要がある
    • typeinfo : 実行時型情報関係
    • typetraits : 型情報関係
  • 文字列
  • OS
    • os : OS関係
    • ospaths : ファイルパス操作関係
    • osproc : プロセス関係
  • その他

言語仕様メモ

  • テンプレートとマクロにはなんでも引数として渡せるわけではなく、ASTとして表現可能なテキストしか受け付けない
  • 識別子ルールが一般的なものと少し違う (コード例:https://ideone.com/pDNafS)
    • _は連続してはいけない
    • _は先頭と末尾には使えない
    • 先頭以外の文字の大文字小文字は区別されない
  • マクロの引数は型指定があっても、すべてNimNode型として渡ってくる。
  • マクロに同じ引数を渡しても仮引数として渡ってくるNimNodeの構造は変わる
    • untypedかそうでないか
    • マクロ起動方式の違い(式マクロ(Expression Macros)と文マクロ(Statement Macros))
      • 文マクロの場合、StmtList(untypedの場合)あるいはStmtListExpr(型指定がある場合)として渡ってくる?

諸条件の違いによるマクロ仮引数のNimNode構造の違い

import macros

macro test1(x:untyped):untyped = echo treeRepr( x ); x
macro test2(x:string):untyped = echo treeRepr( x ); x

# 引数型がuntyped + 式マクロで起動
discard test1("111") # StrLit 111

# 引数型がuntyped + 文マクロで起動 (その1)
discard test1:"111"  # StmtList
                     #   StrLit 111

# 引数型がuntyped + 文マクロで起動 (その2)
discard test1:"111" & "+++"  # StmtList
                             #   Infix
                             #     Ident !"&"
                             #     StrLit 111
                             #     StrLit +++

# 引数型がstring + 式マクロで起動
discard test2("222") # StrLit 222

# 引数型がstring + 文マクロで起動  (その1)
discard test2:"222"  # StmtListExpr
                     #   StrLit 222

# 引数型がstring + 文マクロで起動  (その2)
discard test2:"222" & "+++"  # StmtListExpr
                             #   StrLit 222+++

テンプレートでのシンボル束縛(bind)について

Symbol binding in templates

テンプレートは衛生的なマクロなので、独自のスコープを持つ。ほとんどのシンボルはテンプレートが定義された場所にバインドる。

テンプレート仮引数の参照ルール

テンプレート仮引数はモジュール名.仮引数名に置き換えられる。したがって、グローバルシンボルを隠すことができる。 グローバルシンボルを取得した場合はbind文を使う。

テンプレートの衛生

デフォルトではテンプレートは衛生となっている。つまり、テンプレート内で定義された識別子は呼び出し元からはアクセスできないようになっている。

テンプレート内で宣言されたシンボルが呼び出し元からアクセス可能になるかどうかは inject と gensym プラグマで制御できる。 gensymプラグマを使った場合、テンプレート呼び出し元からはアクセスできない。 一方、injectプラグマを使った場合はアクセスできる。

デフォルトでは type, var, let, const は gensym で、proc, iterator, converter, template, macro は injectになっている。 ただし、シンボル名がテンプレート仮引数として渡ってきた場合は inject シンボルとなる。 inject、gensymプラグマはtemplate外では意味をなさないプラグマとなっている。

逆引きリファレンス未作成項目