Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
プログラミング言語(?)を自作した話
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
meil
December 06, 2019
Programming
870
0
Share
プログラミング言語(?)を自作した話
meil
December 06, 2019
More Decks by meil
See All by meil
クラシルの開発で使ってるGitHub Actions
meilcli
0
210
GitHub ActionsのActionを作る
meilcli
0
440
GitHub Actions入門
meilcli
0
440
Azure Pipelinesのすゝめ
meilcli
0
330
Other Decks in Programming
See All in Programming
夢の無限スパゲッティ製造機 -実装篇- #phpstudy
o0h
PRO
0
200
実践ハーネスエンジニアリング #MOSHTech
kajitack
7
6.1k
Codex CLIのSubagentsによる並列API実装 / Parallel API Implementation with Codex CLI Subagents
takatty
2
870
実践CRDT
tamadeveloper
0
420
飯MCP
yusukebe
0
490
CursorとClaudeCodeとCodexとOpenCodeを実際に比較してみた
terisuke
1
340
Nuxt Server Components
wattanx
0
260
Symfonyの特性(設計思想)を手軽に活かす特性(trait)
ickx
0
130
Going Multiplatform with Your Android App (Android Makers 2026)
zsmb
2
370
GNU Makeの使い方 / How to use GNU Make
kaityo256
PRO
16
5.6k
Coding at the Speed of Thought: The New Era of Symfony Docker
dunglas
0
4.8k
PHP でエミュレータを自作して Ubuntu を動かそう
m3m0r7
PRO
2
170
Featured
See All Featured
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
160
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.8k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
Art, The Web, and Tiny UX
lynnandtonic
304
21k
Technical Leadership for Architectural Decision Making
baasie
3
320
Documentation Writing (for coders)
carmenintech
77
5.3k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
110
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
490
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
410
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.4k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.4k
Transcript
プログラミング言語(?)を自作した話 Mobile Act OSAKA #12
自己紹介 • Twitter: @penguin_sharp • GitHub: MeilCli • Web: https://meilcli.net
• Skill: C#, Kotlin, Android, Azure Pipelines, GitHub Actions • Work: Fenrir Inc. ◦ Android Application Engineer ◦ 発言は個人の見解であり所属する組織の公式見解ではありません
なぜ言語を自作することになったのか
A. GitHub ActionsのAction間でデータのやり取りを簡単にできるようにしたかったから jobs: carthage: runs-on: macOS-latest steps: - uses:
actions/checkout@v1 - uses: MeilCli/carthage-update-check-action@master id: outdated - uses: 8398a7/action-slack@v2 if: steps.outdated.outputs.has_carthage_update != 'false' with: status: ${{ job.status }} text: ${{ steps.outdated.outputs.carthage_update_text }} author_name: GitHub Actions env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} 自作Action Slackに通知する Action
A. GitHub ActionsのAction間でデータのやり取りを簡単にできるようにしたかったから jobs: carthage: runs-on: macOS-latest steps: - uses:
actions/checkout@v1 - uses: MeilCli/carthage-update-check-action@master id: outdated - uses: 8398a7/action-slack@v2 if: steps.outdated.outputs.has_carthage_update != 'false' with: status: ${{ job.status }} text: ${{ steps.outdated.outputs.carthage_update_text }} author_name: GitHub Actions env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} OutputのIDを指定 自作Actionの出力 (テキスト)
A. GitHub ActionsのAction間でデータのやり取りを簡単にできるようにしたかったから jobs: carthage: runs-on: macOS-latest steps: - uses:
actions/checkout@v1 - uses: MeilCli/carthage-update-check-action@master id: outdated - uses: 8398a7/action-slack@v2 if: steps.outdated.outputs.has_carthage_update != 'false' with: status: ${{ job.status }} text: ${{ steps.outdated.outputs.carthage_update_text }} author_name: GitHub Actions env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} Json形式での出力 も対応してる そのまま通知されるので 人間が読める形式である 必要性
A. GitHub ActionsのAction間でデータのやり取りを簡単にできるようにしたかったから jobs: carthage: runs-on: macOS-latest steps: - uses:
actions/checkout@v1 - uses: MeilCli/carthage-update-check-action@master id: outdated - uses: 8398a7/action-slack@v2 if: steps.outdated.outputs.has_carthage_update != 'false' with: status: ${{ job.status }} text: ${{ steps.outdated.outputs.carthage_update_text }} author_name: GitHub Actions env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} Actionの間にJson to Textな変換ができる Actionがあれば便利そう
言語の要件 • GitHub Actionsで動かすのでNode.js上で動作 • JSON Object to TextやJSON Array
to TextなどなどTextへの柔軟な変換性 • TypeScriptで作成 ◦ JavaScript使いたくないので… • ついでに ◦ 実装と言語仕様は切り離して他言語での実装もできるように ◦ 言語仕様に対するテストデータを実装と切り離して用意 ▪ 各実装でのテストが楽になりそう
どういう感じの実装にするか
C#の場合 ※図はちょっとてきとーに作ってます コンパイラー プログラムコード 言語仕様など プログラムコード(CIL) ランタイム コンパイラーな ど 実行
C++やWeb Assemblyなど
作るもの コンパイラー プログラムコード 言語仕様など ?????????? ランタイム コンパイラーな ど 実行 C++やWeb
Assemblyなど Node.js Node.jsで動作
作るもの コンパイラー プログラムコード 言語仕様など ランタイム 実行 コンパイル結果を中間言語などにする必 要はなくそのままNode.js上で実行すれ ばいい インタプリタっぽい(?)
コンパイラーどうやって作るか
コンパイラーのしくみ Wikipediaによるとコンパイラーは以下の部分からなることが多いらしい • ソースコードを読み込み、トークンに分解する字句解析部 • トークン列をもとにプログラムの構文木を構築する構文解析部 • 構文木からオブジェクトコードを生成するコード生成部 https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9#%E3%81%97%E3%81%8F%E 3%81%BF%E3%81%A8%E8%A8%AD%E8%A8%88
なるほど
みようみまねでコンパイラーを作ってみる コンパイルから実行まで4つのフェーズに分ける • 字句解析(Lexer): コードをTokenに変換 • パーサー(AST Parser): Tokenから構文木に変換(実行不能形式) •
構文解析(Semantic Analyzer): 構文木を実行可能な構文木に変換 • コンパイラー(Compiler): 実行可能な構文木から実行用のオブジェクト生成 ◦ コンパイラーの中でコンパイラーって名前が出てきたややこしいですがいい名前が思いつかな かっただけです
Lexer 1. あらかじめ決めた言語仕様から意味上 の区別となるトークンを決定する 2. プログラムコードを1文字ずつ読み込み、 トークンの種類を抽出する 3. ついでにエスケープシークエンスを行っ ておく
https://github.com/MeilCli/Jfol.TS/blob/master/src/lexers/lexer.ts
AST Parser 1. トークンを1つずつ見ていき、 特定の意味のあるトークンが きたら特定の分解を行うという 感じにする 2. このときツリー状になるように 分解する
https://github.com/MeilCli/Jfol.TS/blob/master/src/ast/p arser.ts
Semantic Analyzer • AST ParserでパースしたNodeのま までは実行しにくい形になっている ◦ 式を単純に分解している • 演算子の優先度を加味した構文木
に変換する ◦ 逆ポーランド記法への変換を使う 中置記法: (2 + 4) * (1 + 3) 後置記法: 2 4 + 1 3 + * 前置記法: * + 2 4 + 1 3 これを構文木で↓のように表す * + + 2 4 1 3
Compiler • Semantic Analyzerで実行可能な構文木になっているので組み込みの関数や 演算子などと紐付ける • 紐づくNodeは以下の感じ ◦ リテラル ◦
関数 ◦ 演算子 ◦ フィールド(JSON) • 紐付けができたら実行するだけ ◦ 細かい仕組みを説明すると長くなるので割愛
肝心の構文について あまり深くは考えずに作成(実験的構文としてそのうち破壊的変更するかも) • $フィールド名でJSONのフィールドを参照 ◦ 配列の場合は$フィールド名[配列のループ時に実行するボディ ] • $$関数名(引数)[関数ボディ]で関数を実行 •
フィールドや関数以外の文字はそのまま出力
こういう感じ { "array": [ { "package": { "name": "pack1" }
}, { "package": { "name": "pack2" } } ] } Packages Total: $$(array.length) $array[$$index: $(package.name)$$separator[\n]] JSON 自作言語 Packages Total: 2 0: pack1 1: pack2 結果
おわりに • 言語仕様: https://github.com/MeilCli/Jfol • 実装: https://github.com/MeilCli/Jfol.TS • テストデータ: https://github.com/MeilCli/Jfol.Test
• Playground: https://github.com/MeilCli/Jfol.Playground なお、npmへ公開した直後に他のことにモチベが出たため 本題のGitHub ActionsのAction作成まではできてないです