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
900
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
プログラミング言語(?)を自作した話
meil
December 06, 2019
More Decks by meil
See All by meil
クラシルの開発で使ってるGitHub Actions
meilcli
0
210
GitHub ActionsのActionを作る
meilcli
0
450
GitHub Actions入門
meilcli
0
470
Azure Pipelinesのすゝめ
meilcli
0
340
Other Decks in Programming
See All in Programming
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.8k
「寝てても仕事が進む」Claude Codeで組む第二の脳
tomoyafujita2016
0
340
全PRの83%がAIレビューだけでマージできるようになった開発組織はその後どうなったか
athug
1
1.8k
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
960
komatsuna「分散システムにおけるバグ分析手法」
komatsunaqa
0
270
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
0
1.8k
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
650
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
3.6k
AI時代のPHPer生存戦略 ~「言語、もうなんでもよくない?」に本気で向き合う~
vivion
0
800
ソフトウェア設計に溶けるインフラ ― AWS CDK のインフラ認識論
konokenj
3
800
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
220
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
560
Featured
See All Featured
Producing Creativity
orderedlist
PRO
348
40k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.1k
How to Think Like a Performance Engineer
csswizardry
28
2.7k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
250
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
170
Chasing Engaging Ingredients in Design
codingconduct
0
270
Product Roadmaps are Hard
iamctodd
55
12k
The Cost Of JavaScript in 2023
addyosmani
55
10k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
430
HDC tutorial
michielstock
2
790
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作成まではできてないです