Crystalプロジェクトが異なるシャードを使用しているとします。そして、各シャードは、プロジェクト全体の編集の最後にクリーンアップを行いたいと思っています。マクロを使用することは可能ですか?例えば、このようなコンパイルの最後に実行する命令を定義することはできますか? (Crystal lang)
何か:あなたは複数のマクロの間でデータを共有する必要がある場合
{% at_end %}
{% system("rm 'tmp files'") %}
{% end %}
Crystalプロジェクトが異なるシャードを使用しているとします。そして、各シャードは、プロジェクト全体の編集の最後にクリーンアップを行いたいと思っています。マクロを使用することは可能ですか?例えば、このようなコンパイルの最後に実行する命令を定義することはできますか? (Crystal lang)
何か:あなたは複数のマクロの間でデータを共有する必要がある場合
{% at_end %}
{% system("rm 'tmp files'") %}
{% end %}
、あなたがHash
やArray
を使用して、関連するASTノードは、マクロからアクセス可能であるConstant
を介してそれらにアクセスすることができます。ここで重要な部分
STORAGE = [] of _
macro add(node)
{% STORAGE << node %}
end
macro list
{% for elem in STORAGE %}
{% puts "Elem: #{elem}" %}
{% end %}
end
add 1
add 2
add "hello"
add :world
add({a: 1, b: 2})
add 3 + 4
add a_call(arg1, 2)
list
である:ここで
はこれを実証する例(https://carc.in/#/r/372kでのライブ)です
ここSTORAGE = [] of _
私がある(特定の型の配列を宣言していますこの場合は関連しません。配列はマクロを介してのみアクセスされるため、通常のコードではこのタイプ(_
)を使用できません。マクロシステムは、それが配列であることだけを知る必要があります。
macro add(node)
{% STORAGE << node %}
end
次に、アレイASTノード(マクロシステムのArrayLiteral型)を変更できるマクロを作成します。 NumberLiteral
やSymbolLiteral
のような単純なノードからCall
、Def
、さらにはClassDef
のような複雑なノードに、あらゆる種類のASTノードを格納できることに注意してください。
macro list
{% for elem in STORAGE %}
{% puts "Elem: #{elem}" %}
{% end %}
end
そして最後に、私は単純に(コンパイル時に)STORAGE
配列の内容を印刷しますマクロを作成します。
同じことがHashLiteral
で行うことができます。
と同じように、あなたがキーまたは値としてASTノードのいずれかの種類を使用することができ、上述したように。あなたがマクロシステムで使用Constants
も通常のコードで見ることができ、それが名前の衝突を持つことが可能だということ
注意(ユーザーが自分自身のコードのためにあまりにも一定のSTORAGE
を使用することを望んでいますか?) 。 MyShard::MacroStorage::SomeInterestingNodes
のような特別なモジュールに定数を入れたり、M____ACRO_Storage____
のような複雑な命名パターンを使用することをお勧めします(< - これはユーザーが使用することはほとんどありません))
うわー。マクロで '[] of _'を使うことは決して考えなかったでしょう。あなたはどうやってそれについて知りましたか? (この回答に感謝します) –
他のコード、コンパイラのコードを読んで、言語の端を試してみてください:D – bew
これについての特定の用途を説明できますか? –
@JohannesMüllerマクロ間でデータを共有する必要があることがあります。だから私はそれらを一時ファイルに書きます。私がしなければ、私はヒープメモリを使用し、ブロック/ Procsケマルがそれを行う方法をキャプチャする必要があります。もし私が一時的なものを削除することができれば、それはもっと良いものになるでしょう。コンパイル後のファイル –
おもしろいアイデア...しかし、一時ファイルがヒープ割り当てよりもパフォーマンスが良いと考える理由は何ですか? :D –