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
meil
December 06, 2019
Programming
0
820
プログラミング言語(?)を自作した話
meil
December 06, 2019
Tweet
Share
More Decks by meil
See All by meil
クラシルの開発で使ってるGitHub Actions
meilcli
0
190
GitHub ActionsのActionを作る
meilcli
0
430
GitHub Actions入門
meilcli
0
410
Azure Pipelinesのすゝめ
meilcli
0
320
Other Decks in Programming
See All in Programming
PipeCDのプラグイン化で目指すところ
warashi
1
280
High-Level Programming Languages in AI Era -Human Thought and Mind-
hayat01sh1da
PRO
0
780
iOS 26にアップデートすると実機でのHot Reloadができない?
umigishiaoi
0
130
AI コーディングエージェントの時代へ:JetBrains が描く開発の未来
masaruhr
1
160
データの民主化を支える、透明性のあるデータ利活用への挑戦 2025-06-25 Database Engineering Meetup#7
y_ken
0
360
Goで作る、開発・CI環境
sin392
0
230
今ならAmazon ECSのサービス間通信をどう選ぶか / Selection of ECS Interservice Communication 2025
tkikuc
21
4k
ruby.wasmで多人数リアルタイム通信ゲームを作ろう
lnit
3
490
猫と暮らす Google Nest Cam生活🐈 / WebRTC with Google Nest Cam
yutailang0119
0
120
イベントストーミング図からコードへの変換手順 / Procedure for Converting Event Storming Diagrams to Code
nrslib
2
840
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
690
Discover Metal 4
rei315
2
140
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
740
Embracing the Ebb and Flow
colly
86
4.7k
Git: the NoSQL Database
bkeepers
PRO
430
65k
Mobile First: as difficult as doing things right
swwweet
223
9.7k
Producing Creativity
orderedlist
PRO
346
40k
Documentation Writing (for coders)
carmenintech
72
4.9k
Building Applications with DynamoDB
mza
95
6.5k
Why Our Code Smells
bkeepers
PRO
336
57k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
The Language of Interfaces
destraynor
158
25k
Intergalactic Javascript Robots from Outer Space
tanoku
271
27k
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作成まではできてないです