Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Wasmで拡張できる軽量マークアップ言語 Brack

Wasmで拡張できる軽量マークアップ言語 Brack

第14期サイボウズ・ラボユース成果発表会 2025.03.28
後半は https://github.com/uekann が作成

Mutsuha Asada

March 28, 2025
Tweet

More Decks by Mutsuha Asada

Other Decks in Programming

Transcript

  1. 2 @momeemt @mutsuha_asada https://momee.mt 浅田 睦葉(Mutsuha Asada) 🎓 所属 ・筑波大学情報学群情報科学類

    B3 🐣 興味があること ・コンパイラやそのツールチェーン(LSP、サニタイザ) ・ビルドシステム(Nix, Meson, etc...) 🍳 趣味 ・音楽、お笑い、料理など 自己紹介
  2. 概要 3 ・開発中のマークアップ言語についてお話しします 📚 目次 マークアップ言語を自作する背景 1. 言語仕様とプラグインシステム 2. ブログジェネレータの実装

    3. ビルドツールの実装 4. 展望とまとめ(前半) 5. Language Serverの導入 6. パーサの概要 7. エラートレラントなパーサの実装 8. 展望とまとめ(後半) 9.
  3. 軽量マークアップ言語を自作する背景 5 ・ブログを書くため  ・ 🤔「自作言語でブログ書きたくね?」  ・最初は雑な思い付き ・たいていの場合はMarkdownが採用される  → Zenn、Qiita、GitHub README、その他、etc...

      👍 データ記述の整合性を保ちつつ、ソースコードの可読性も意識されている   😞 ブログの場合には変換後のコンテンツのみが重要 + 多様な表現力が求められる   😞 標準的で明文化された仕様を持たないので方言が無数に存在 1. マークアップを自作する背景
  4. Markdownクイズ 😄 6 ・Markdownはオフィシャルな統一された規格が無く、  CommonMarkやGitHub Flavored Markdown(GFM)などの後発の規格がいくつかある  → 脚注はCommonMarkに定義されている?GFMには?  →

    インライン脚注はpandocで変換できる?  → リストの要素に見出しを含めてMarkdown.plで変換できる?CommonMark準拠だと?  → MultiMarkdownを使うとルビを振ることはできる? ・我々はMarkdownの枠を超えた表現力をMarkdownに要求している まあ確かに欲しいよな 知人のMarp製スライド pタグを省略できる JSXであるところのMDX 1. マークアップを自作する背景
  5. 1. マークアップを自作する背景 Markdownクイズ 😄 7 ・Markdownはオフィシャルな統一された規格が無く、  CommonMarkやGitHub Flavored Markdown(GFM)などの後発の規格がいくつかある  →

    脚注はCommonMarkに定義されている?GFMには?  → インライン脚注はpandocで変換できる?  → リストの要素に見出しを含めてMarkdown.plで変換できる?CommonMark準拠だと?  → MultiMarkdownを使うとルビを振ることはできる? ・我々はMarkdownの枠を超えた表現力をMarkdownに要求している まあ確かに欲しいよな 知人のMarp製スライド pタグを省略できる JSXであるところのMDX 変換規則・対象を拡張することを 前提にしたマークアップ言語が欲しい
  6. プロトタイプ (2022) の評価 10 ・ 👍 良い点  ① 毎日の日報を書くためのブログ言語として十分に動作する   →

    https://blog.momee.mt はこのプロトタイプで動いている  ② コマンドとマクロが実装されており、Nimの関数で直感的に書ける ・ 😞 改善するべき点  ① 独自のコマンドを実装するためにはNimを書かなければならない  ② プラグインが静的に解決されるため、追加・削除するにはビルドし直すしかない  ③ ブログがNimが提供する謎のテンプレートエンジンによって生成されており、   現代的なフロントエンド技術と組み合わせることが難しい   → 真面目に動かすには車輪の再発明をたくさんしなければいけない 1. マークアップを自作する背景
  7. 12 プラグインシステムの変更 ・2023年12月ごろに友人(上野)がBrackの開発に関心を示した  → まずは問題点①、②を解決してからチーム開発を始めることにした ・動的にプラグインをロード・実行できる仕組みを入れる  ・選択肢   ・動的リンク(so, dylib, dll)

      ・Luaなどのスクリプト言語のランタイムを組み込む   ・VM言語で実装し直して、中間形式をプラグインとして扱う(JVM、.NETなど)   ・WebAssembly  ・Wasmは移植性が高く、サンドボックスモデルを持つ   → 将来的なエコシステムの拡充も見込める   ・これを入れよう! 2. 言語仕様とプラグインシステム
  8. Extism Wasmtime (Wasm Runtime) 実 行 Brack Compiler 解析・AST化 必要な関数をコール

    呼び出し・ABIの解決 (実行時) 14 Wasmを用いたプラグインシステム Brack文書 プラグイン 様々な言語から コンパイル 2. 言語仕様とプラグインシステム
  9. Brack Compiler HTMLを生成 Blog Generator JSONに変換 18 実装したブログジェネレータ ・モダンなフロントエンドと組み合わせるためにJSONを出力  →

    Next.jsプロジェクトをテンプレートにしてブログ記事を描画 記事データ fetch フロントエンド 👍 フロントエンドとBrackを分離できているので フロントエンド技術自体はなんでも良い 3. ブログジェネレータの実装
  10. 22 ビルドツールの必要性 ・以前はNimプログラムをビルドする際にプラグインも解決されていた  → しかし、新しいコンパイラは実行時にWasmバイナリを読みに行く  ・プラグインのパス、依存関係や文書の設定を記述できるビルドツールが必要 ・どんな要求を満たしたい?  ・1バイナリであること   → 軽量マークアップ言語を使いたい人が文書を書くことに興味があるのであって

       残念ながら複雑なビルドやインストール工程には興味がない  ・グローバルを汚染しないこと   ・Wasmバイナリは1つ1つが軽量なのでプロジェクトごとに用意しても問題ない  ・エラー報告がわかりやすい  ・設定ファイルはtomlで書きたい 4. ビルドツールの実装
  11. 23 4. ビルドツールの実装 ビルドツールの必要性 ・以前はNimプログラムをビルドする際にプラグインも解決されていた  → しかし、新しいコンパイラは実行時にWasmバイナリを読みに行く  ・プラグインのパス、依存関係や文書の設定を記述できるビルドツールが必要 ・どんな要求を満たしたい?  ・1バイナリであること

      → 軽量マークアップ言語を使いたい人が文書を書くことに興味があるのであって    残念ながら複雑なビルドやインストール工程には興味がない  ・グローバルを汚染しないこと   ・Wasmバイナリは1つ1つが軽量なのでプロジェクトごとに用意しても問題ない  ・エラー報告がわかりやすい ベースは`cargo`コマンド CLIコマンドは`go`コマンド を目指した作りにしたい
  12. 29 まとめ(前半) ・Wasmで変換規則を拡張できるBrackという軽量マークアップ言語を作っている ・ブログを書くための言語として作っていて、将来的にはスライドやPDFも吐きたい ・元々はNimで実装していて、定義したコマンドをコンパイル時に結合して実現して いたが、① ライブラリの実装者がNimを書かなければいけない ② ライブラリが増減 するときにビルドし直さなければいけない

    ③ Nimのテンプレートエンジンに密結合し ておりモダンなフロントエンド技術と組み合わせるのが困難という問題があった ・そこでWebAssemblyをプラグインとして利用するコンパイラをRustで書き直した ・ブログジェネレータが生成したHTMLをJSONに変換するようにしたので、モダンな フロントエンド技術と組み合わせることが容易になった ・ブログを書くためのCLIやデプロイワークフローについても実装した ・ビルドツールの実装をしていて、使い勝手はCargoに近く、1バイナリで完結する点 やコマンドのインタフェースはGoに近いものを目指している 5. 展望とまとめ(前半)
  13. 自己紹介 31 @uekann @uekann_ https://uekann.com (準備中) 上野 幹太(Kanta Ueno) 🎓

    所属 ・筑波大学情報学群情報科学類 B3 🐣 興味があること ・ブラックボックス最適化(CMA-ESなど) ・なんだろう...... 🍳 趣味 ・写真、スキー、散歩、音楽など
  14. 概要 32 ・開発中のマークアップ言語についてお話しします 📚 目次 マークアップ言語を自作する背景 1. ブログジェネレータの実装 2. ビルドツールの実装

    3. プラグインシステムの実装 4. 展望とまとめ(前半) 5. Language Serverの導入 6. パーサの概要 7. エラートレラントなパーサの実装 8. 展望とまとめ(後半) 9.
  15. LSP (Language Server Protocol) 37 Microsoftが規定したLanguage Serverの通信仕様 → BrackもLanguage Serverを作ろう!

    Brackに関するドキュメントが充実していなくても、 Language Serverから得られる情報によって、 執筆体験が損なわれないようにしたい 6. Language Serverの導入
  16. Language Serverの実装 39 困りごと これはLanguage Serverの問題ではなく、コンパイラそのものが抱える問題 今回はLanguage Serverを実装したタイミングで表面化した 構文エラーが1つしか表示されない →

    構文エラーが複数ある場合、1つ直すと別のエラーが出てくる。(つらい) 複数の構文エラーを同時にキャッチできるパーサを作ろう! 6. Language Serverの導入
  17. document stmt curly module command arg エラートレラントなパース 47 パースに失敗しても読み飛ばしてエラーを回収したい ・どこまでASTを遡って

    ・どこまでトークンを読み飛ばして パースを再開する? ? 無限に条件分岐が必要... 7. パーサの概要
  18. 具象構文木(CST)の導入 50 document stmt curly module command arg stmt expr

    square document ? stmt? curly? module? command? arg? stmt? expr? square? ゆるい規則に基づいて木構造(CST)を構成 ASTへの変換を試みる 8. エラートレラントなパーサの実装