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
XSLTで作るBrainfuck処理系
Search
MakKi
June 14, 2025
Programming
390
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
XSLTで作るBrainfuck処理系
関数型まつり2025
MakKi
June 14, 2025
More Decks by MakKi
See All by MakKi
テストだけじゃない!インプロセスDBで生まれるGoらしさ
makki_d
0
47
テストだけじゃない!インプロセスDBで生まれるGoらしさ
makki_d
0
60
SQLだけでマイグレーションしたい!
makki_d
0
1.4k
Recap: An Operating System in Go
makki_d
2
170
眼鏡と視力についての誤解を解く
makki_d
0
230
標準ライブラリの動向とイテレータのパフォーマンス
makki_d
3
780
range over funcのエラー処理
makki_d
1
1.8k
GoとテストとインプロセスDB
makki_d
3
690
君は古の言語M4を知っているか (LT)
makki_d
0
570
Other Decks in Programming
See All in Programming
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
130
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
680
運用エージェントは "作る" から "育てる" へ - 記憶と自己進化の3層設計パターン / self-evolving-agents-three-layer-agent-design
gawa
12
3.6k
AI時代の仕事技芸論 — ソフトウェア開発で「遊ぶように働く」職人的熟達のすすめ
kuranuki
1
640
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
520
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
4
1.5k
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
1.9k
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
150
ふつうのFeature Flag実践入門
irof
7
3.6k
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
330
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
18
6.3k
技術記事、AIに書かせるか、自分で書くか? 〜それでも私が自分の手で書く理由〜 / #QiitaConference
jnchito
2
1.3k
Featured
See All Featured
KATA
mclloyd
PRO
35
15k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
860
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Tell your own story through comics
letsgokoyo
1
950
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
170
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
First, design no harm
axbom
PRO
2
1.2k
Transcript
XSLTで作るBrainfuck処理系 XSLTは関数型言語たり得るか?
自己紹介 • 牧内大輔(MakKi) ◦ @makki_d ◦ makiuchi-d • KLab株式会社 ◦
スマホゲーム、主にサーバサイドや同期通信まわり • OSS ◦ gozxing: バーコードQRコード ◦ arelo: 自動リロード ◦ EMLauncher: スマホデバッグアプリ配信 ◦ WSNet2: 同期通信 • Go言語界隈によく出没
XSLT
• EXtensible Stylesheet Language Transformation • XMLをXMLや他の形式に変換するスタイルシート 言語 ◦ XSL自身もXMLで記述する
XSLTとは XML </> HTML < > TXT Aa XML </> XSLT XSL </>
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/> <xsl:template match="/">
<html> <body> <h1>Library Books</h1> <ul> <xsl:apply-templates select="library/book"/> </ul> </body> </html> </xsl:template> <xsl:template match="book"> <li> <strong> <xsl:value-of select="title"/> </strong> by <xsl:value-of select="author"/> </li> </xsl:template> </xsl:stylesheet> convert.xsl <?xml version="1.0" encoding="utf-8"?> <library> <book> <title>Learning XSLT</title> <author>John Doe</author> </book> <book> <title>XML in Action</title> <author>Jane Smith</author> </book> </library> input.xml <html> <body> <h1>Library Books</h1> <ul> <li> <strong>Learning XSLT</strong> by John Doe </li> <li> <strong>XML in Action</strong> by Jane Smith </li> </ul> </body> </html> output.html
XSLTの特徴 • 宣言的なテンプレート <xsl:template> • テンプレートの再帰呼び出し による繰り返し処理 • パターンマッチング でテンプレートを自動選択
• 変数 <xsl:variable> が不変(再代入不可) すごく関数型言語ぽい!
XSLTは関数型言語か? • そもそもプログラミング言語 と言えるのか? ◦ プログラミング言語であるからにはチューリング完全が求められる • プログラミング言語ならばチューリング完全 であるべき ◦
計算可能なアルゴリズムは全てチューリングマシン上の計算に書き換えられる ▪ チューリングマシンはあらゆる計算可能な計算が可能 ◦ チューリングマシンと同等の能力を持つことを「チューリング完全」と呼ぶ ▪ チューリング完全ならあらゆる計算可能な計算が可能 • チューリング完全な 処理系を実装できればチューリング完全
Brainfuckを実装してみた
Brainfuckとは • 記号のみで記述 • 8つの命令しかない言語 • メモリ配列 とポインタを持つ • もちろんチューリング完全
実装が簡単! +++++++++[>++++++++>+++++++++ ++>+++++<<<-]>.>++.+++++++..+ ++.>-.------------.<++++++++. --------.+++.------.--------. >+. hello.bf
BrainfuckをXMLで表現 • 各命令をタグで表現 ◦ 記号と1:1対応 • XSLTプロセッサがパースしてくれる ◦ [と ]の対応が親子関係でわかる
• 標準入力も含めることに <?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="bf.xsl"?> <bf> <code> <inc/><inc/> <loop> <dec/><right/><read/><inc/><print/><left/> <end/> </loop> </code> <input>Aa</input> </bf> atob.xml “Aa”を”Bb”にするプログラム: ++[->,+.]
ポインタのインクリメント( >) • 状態を引数でまるごと伝搬 ◦ ptr: ポインタ ◦ mem: メモリ配列
◦ input: 標準入力文字列 • <right/>のテンプレート ◦ 次の命令のテンプレート呼び出し ◦ 直後の兄弟要素 ▪ following-sibling::*[1] ◦ 引数のptrを+1 <xsl:template match="right"> <xsl:param name="ptr"/> <xsl:param name="mem"/> <xsl:param name="input"/> <xsl:apply-templates select="following-sibling::*[1]"> <xsl:with-param name="ptr" select="$ptr + 1"/> <xsl:with-param name="mem" select="$mem"/> <xsl:with-param name="input" select="$input"/> </xsl:apply-templates> </xsl:template>
メモリの実装 • メモリ配列の表現 ◦ 連番のXML要素 ▪ key = '_'+ptrの値 •
読み出し ◦ 名前が$keyな要素の値 ▪ sumで存在しないとき0に • 書き込み ◦ write-valテンプレート ◦ $key以外の要素のコピー ◦ $keyの要素を追加 ▪ 値を$valに <_0>65</_0> <_1>66</_1> <_2>67</_2> <_3>68</_3> sum(exsl:node-set($mem)/*[name()=$key]) <xsl:template name="write-val"> <xsl:param name="mem"/> <xsl:param name="key"/> <xsl:param name="val"/> <xsl:for-each select="exsl:node-set($mem)/*[name()!=$key]"> <xsl:copy-of select="."/> </xsl:for-each> <xsl:element name="{$key}"> <xsl:value-of select="$val"/> </xsl:element> </xsl:template>
値のインクリメント( +) • ポインタが指すメモリの現在の値 ◦ 取り出すための key('_' + ptr) ◦
値 val • write-val テンプレート ◦ メモリの"$key"に"$val+1" を書く ◦ まるごと作り直して次の命令に渡す <xsl:template match="inc"> <!-- param 省略 --> <xsl:variable name="key" select="concat('_', $ptr)"/> <xsl:variable name="val" select="sum(exsl:node-set($mem)/*[name()=$key])"/> <xsl:variable name="mem"> <xsl:call-template name="write-val"> <xsl:with-param name="mem" select="$mem"/> <xsl:with-param name="key" select="$key"/> <xsl:with-param name="val" select="$val + 1"/> </xsl:call-template> </xsl:variable> <!-- apply-templates 省略 -->
ループ([ ]) • <xsl:choose>で分岐 ◦ 非0のとき:子要素の先頭 ▪ "*[1]" ◦ 0のとき:直後の兄弟要素
▪ "following-sibling::*[1]" • ループ終端 <end/> ◦ 親要素でapply-template ▪ "parent::node()" <!-- いろいろ省略 --> <xsl:choose> <xsl:when test="$val != 0"> <xsl:apply-templates select="*[1]"> <xsl:with-param name="ptr" select="$ptr"/> <xsl:with-param name="mem" select="$mem"/> <xsl:with-param name="input" select="$input"/> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="following-sibling::*[1]"> <xsl:with-param name="ptr" select="$ptr"/> <xsl:with-param name="mem" select="$mem"/> <xsl:with-param name="input" select="$input"/> </xsl:apply-templates> </xsl:otherwise> </xsl:choose>
実装できた! • https://github.com/makiuchi-d/bfxslt • 解説記事 KLabTechBook Vol. 14 ◦ 技術書典18にて頒布中
▪ 物理本500円(在庫残り1冊) ▪ 電子版0円 ◦ ブログでも読めます 新刊もあります
XSLTは プログラミング言語 である
関数型言語たり得るか?
関数型言語であるためには • 関数が一級オブジェクト ◦ 関数を変数に拘束できたり演算できたり • XSLTのテンプレートは一級オブジェクトではない ◦ テンプレート自体を変数や引数に拘束できない ◦
動的生成もできない ▪ XSL自体もXMLなのでXSLからXSLを生成するXSLTを多段で呼べばあるいは ……
XSLTは 関数型言語ぽい プログラミング言語である
つづく? 実はXSLT2.0でtemplateとは別にfunctionが導入され XSLT3.0でfunctionが一級オブジェクトになったのは また別のお話……