Flat Leon Works

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

【Nim】メモ

基本情報

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

リンク

言語仕様メモ

  • テンプレートとマクロにはなんでも引数として渡せるわけではなく、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外では意味をなさないプラグマとなっている。

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