Created
November 24, 2025 16:47
-
-
Save 3tty0n/11628c9ac211328ee3698825998a020c to your computer and use it in GitHub Desktop.
2025年度 スクリプト言語演習 Forth実装
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="ja"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Forth言語インタプリタ実装演習</title> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/4.5.0/reset.min.css"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/4.5.0/reveal.min.css"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/4.5.0/theme/white.min.css"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css"> | |
| <style> | |
| .reveal h1, .reveal h2, .reveal h3 { | |
| text-transform: none; | |
| } | |
| .reveal pre { | |
| width: 100%; | |
| font-size: 0.55em; | |
| } | |
| .reveal pre code { | |
| max-height: 500px; | |
| padding: 15px; | |
| } | |
| .reveal table { | |
| font-size: 0.7em; | |
| margin: 0 auto; | |
| } | |
| .reveal th, .reveal td { | |
| padding: 0.3em 0.6em; | |
| border: 1px solid #ccc; | |
| } | |
| .reveal th { | |
| background-color: #f0f0f0; | |
| } | |
| .reveal .small { | |
| font-size: 0.7em; | |
| } | |
| .reveal .highlight-box { | |
| background-color: #e7f3ff; | |
| border-left: 4px solid #2196F3; | |
| padding: 10px 15px; | |
| margin: 10px 0; | |
| text-align: left; | |
| } | |
| .reveal .two-column { | |
| display: flex; | |
| gap: 30px; | |
| justify-content: center; | |
| } | |
| .reveal .two-column > div { | |
| flex: 1; | |
| max-width: 45%; | |
| } | |
| .reveal .stack-viz { | |
| font-family: monospace; | |
| font-size: 0.6em; | |
| background-color: #f0f0f0; | |
| padding: 10px; | |
| border-radius: 5px; | |
| display: inline-block; | |
| } | |
| /* フロー図用のスタイル */ | |
| .flow-container { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 10px; | |
| margin: 20px 0; | |
| } | |
| .flow-row { | |
| display: flex; | |
| align-items: center; | |
| gap: 15px; | |
| justify-content: center; | |
| } | |
| .flow-box { | |
| padding: 12px 24px; | |
| border-radius: 8px; | |
| font-weight: bold; | |
| text-align: center; | |
| min-width: 120px; | |
| } | |
| .flow-box.source { | |
| background-color: #fff3e0; | |
| border: 2px solid #ff9800; | |
| color: #e65100; | |
| } | |
| .flow-box.process { | |
| background-color: #e3f2fd; | |
| border: 2px solid #2196f3; | |
| color: #1565c0; | |
| } | |
| .flow-box.output { | |
| background-color: #e8f5e9; | |
| border: 2px solid #4caf50; | |
| color: #2e7d32; | |
| } | |
| .flow-box.token { | |
| background-color: #fce4ec; | |
| border: 2px solid #e91e63; | |
| color: #c2185b; | |
| } | |
| .flow-box.decision { | |
| background-color: #f3e5f5; | |
| border: 2px solid #9c27b0; | |
| color: #7b1fa2; | |
| transform: rotate(0deg); | |
| } | |
| .flow-arrow { | |
| font-size: 1.5em; | |
| color: #666; | |
| } | |
| .flow-arrow.down { | |
| font-size: 1.2em; | |
| } | |
| .flow-label { | |
| font-size: 0.7em; | |
| color: #666; | |
| margin-top: -5px; | |
| } | |
| /* 比較図用 */ | |
| .compare-container { | |
| display: flex; | |
| gap: 40px; | |
| justify-content: center; | |
| margin: 20px 0; | |
| } | |
| .compare-box { | |
| padding: 20px; | |
| border-radius: 12px; | |
| width: 600px; | |
| } | |
| .compare-box.compiler { | |
| background-color: #fff8e1; | |
| border: 2px solid #ffc107; | |
| } | |
| .compare-box.interpreter { | |
| background-color: #e8f5e9; | |
| border: 2px solid #4caf50; | |
| } | |
| .compare-box h4 { | |
| margin-top: 0; | |
| margin-bottom: 15px; | |
| padding-bottom: 10px; | |
| border-bottom: 1px solid #ccc; | |
| } | |
| .compare-flow { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .compare-flow .step { | |
| padding: 8px 16px; | |
| border-radius: 6px; | |
| font-size: 0.85em; | |
| width: 80%; | |
| text-align: center; | |
| } | |
| .compare-flow .step.code { | |
| background-color: rgba(0,0,0,0.05); | |
| } | |
| .compare-flow .step.tool { | |
| background-color: rgba(0,0,0,0.1); | |
| font-weight: bold; | |
| } | |
| .compare-flow .step.result { | |
| background-color: rgba(0,0,0,0.15); | |
| } | |
| .compare-flow .arrow { | |
| color: #666; | |
| } | |
| .examples { | |
| font-size: 0.75em; | |
| color: #666; | |
| margin-top: 10px; | |
| } | |
| /* 評価ループ図 */ | |
| .eval-loop-container { | |
| position: relative; | |
| margin: 20px auto; | |
| width: 900px; | |
| } | |
| .eval-main-flow { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 20px; | |
| margin-bottom: 30px; | |
| } | |
| .eval-box { | |
| padding: 15px 25px; | |
| border-radius: 10px; | |
| font-weight: bold; | |
| text-align: center; | |
| } | |
| .eval-box.read { | |
| background-color: #bbdefb; | |
| border: 2px solid #1976d2; | |
| } | |
| .eval-box.get { | |
| background-color: #c8e6c9; | |
| border: 2px solid #388e3c; | |
| } | |
| .eval-box.eval { | |
| background-color: #ffccbc; | |
| border: 2px solid #e64a19; | |
| } | |
| .eval-branches { | |
| display: flex; | |
| justify-content: center; | |
| gap: 30px; | |
| margin-top: 20px; | |
| } | |
| .eval-branch { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .eval-branch .condition { | |
| padding: 10px 20px; | |
| background-color: #e1bee7; | |
| border: 2px solid #8e24aa; | |
| border-radius: 20px; | |
| font-size: 0.9em; | |
| } | |
| .eval-branch .action { | |
| padding: 8px 16px; | |
| background-color: #f5f5f5; | |
| border: 1px solid #999; | |
| border-radius: 5px; | |
| font-size: 0.8em; | |
| } | |
| .loop-arrow { | |
| position: absolute; | |
| right: 50px; | |
| top: 0; | |
| width: 80px; | |
| height: 60px; | |
| border: 3px solid #666; | |
| border-left: none; | |
| border-bottom: none; | |
| border-radius: 0 20px 0 0; | |
| } | |
| .loop-arrow::after { | |
| content: '↑'; | |
| position: absolute; | |
| left: -15px; | |
| top: 40px; | |
| font-size: 1.5em; | |
| color: #666; | |
| } | |
| /* 字句解析図 */ | |
| .lexer-container { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 20px; | |
| margin: 30px 0; | |
| } | |
| .lexer-row { | |
| display: flex; | |
| align-items: center; | |
| gap: 30px; | |
| } | |
| .lexer-input { | |
| padding: 15px 30px; | |
| background-color: #fff3e0; | |
| border: 2px solid #ff9800; | |
| border-radius: 8px; | |
| font-family: monospace; | |
| font-size: 1.1em; | |
| } | |
| .lexer-process { | |
| padding: 20px; | |
| background-color: #e3f2fd; | |
| border: 2px solid #2196f3; | |
| border-radius: 50%; | |
| text-align: center; | |
| } | |
| .lexer-process .title { | |
| font-weight: bold; | |
| font-size: 0.9em; | |
| } | |
| .lexer-process .sub { | |
| font-size: 0.7em; | |
| color: #666; | |
| } | |
| .lexer-output { | |
| display: flex; | |
| gap: 8px; | |
| } | |
| .lexer-token { | |
| padding: 10px 15px; | |
| background-color: #e8f5e9; | |
| border: 2px solid #4caf50; | |
| border-radius: 5px; | |
| font-family: monospace; | |
| } | |
| .big-arrow { | |
| font-size: 2em; | |
| color: #666; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="reveal"> | |
| <div class="slides"> | |
| <!-- タイトルスライド --> | |
| <section> | |
| <h1>Forth言語インタプリタ<br>実装演習</h1> | |
| <p class="small">スタックベース言語とインタプリタの仕組み</p> | |
| <p>2025年11月26日 伊澤侑祐</p> | |
| </section> | |
| <!-- 目次 --> | |
| <section> | |
| <h2>本日の内容</h2> | |
| <ol> | |
| <li>Forth とは</li> | |
| <li>動的言語とインタプリタ</li> | |
| <li>スタックとForthでの使い方</li> | |
| <li>参照実装</li> | |
| <li>演習問題</li> | |
| </ol> | |
| </section> | |
| <!-- セクション2: Forth言語とは --> | |
| <section> | |
| <section> | |
| <h2>1. Forth言語とは</h2> | |
| </section> | |
| <section> | |
| <h3>歴史と背景</h3> | |
| <ul> | |
| <li><strong>1970年代</strong>: Charles H. Moore が開発</li> | |
| <li class="fragment">もともと<strong>天文台の望遠鏡制御</strong>のために設計</li> | |
| <li class="fragment">その後、様々な分野で利用: | |
| <ul> | |
| <li>組み込み・制御システム</li> | |
| <li>宇宙開発</li> | |
| <ul><li><a href=https://www.forth.com/resources/space-applications>NASA</a>でも使用</li></ul> | |
| <li><strong>PostScript (印刷技術・PDFレンダリング)</strong></li> | |
| </ul> | |
| </li> | |
| </ul> | |
| <img src="https://www.forth.com/wp-content/uploads/2021/07/FORTH-Inc-with-graphic-tm-1200.png"/ width="600mm"> | |
| </section> | |
| <section> | |
| <h3>Forthの特徴</h3> | |
| <div style="text-align: left;"> | |
| <p><strong>1. スタックベースの計算</strong></p> | |
| <p class="small">すべての演算はスタック(LIFO)を介して行われる</p> | |
| <p class="fragment"><strong>2. 逆ポーランド記法(RPN)</strong></p> | |
| <div class="fragment"> | |
| <table> | |
| <tr> | |
| <th>通常の記法</th> | |
| <th>Forth</th> | |
| </tr> | |
| <tr> | |
| <td>(3 + 4) * 2</td> | |
| <td>3 4 + 2 *</td> | |
| </tr> | |
| </table> | |
| </div> | |
| <p class="fragment"><strong>3. 単純で拡張可能</strong></p> | |
| <p class="fragment small">基本的な「ワード」の組み合わせで新しいワードを定義</p> | |
| </div> | |
| </section> | |
| <section> | |
| <h3>なぜForthを学ぶのか?</h3> | |
| <ol> | |
| <li class="fragment"><strong>インタプリタの基礎</strong><br> | |
| <span class="small">シンプルな構文で実装原理を学びやすい</span></li> | |
| <li class="fragment"><strong>スタック機械の理解</strong><br> | |
| <span class="small">Java VM、Python VM、WebAssembly などで採用</span></li> | |
| <li class="fragment"><strong>言語設計の思想</strong><br> | |
| <span class="small">最小限の機能で最大限の表現力</span></li> | |
| </ol> | |
| </section> | |
| </section> | |
| <!-- セクション1: 動的言語とインタプリタ --> | |
| <section> | |
| <section> | |
| <h2>2. 動的言語とインタプリタ</h2> | |
| </section> | |
| <section> | |
| <h3>プログラムの実行方式</h3> | |
| <div class="compare-container"> | |
| <div class="compare-box compiler" style="font-size: 0.75em"> | |
| <h4>コンパイラ</h4> | |
| <div class="compare-flow"> | |
| <div class="step code">ソースコード</div> | |
| <div class="arrow">↓</div> | |
| <div class="step tool">コンパイラ</div> | |
| <div class="arrow">↓</div> | |
| <div class="step code">機械語(実行ファイル)</div> | |
| <div class="arrow">↓</div> | |
| <div class="step result">実行結果</div> | |
| </div> | |
| <div class="examples">例: C, C++, Rust, Go</div> | |
| </div> | |
| <div class="compare-box interpreter" style="font-size: 0.75em"> | |
| <h4>インタプリタ</h4> | |
| <div class="compare-flow"> | |
| <div class="step code">ソースコード</div> | |
| <div class="arrow">↓</div> | |
| <div class="step tool">インタプリタ</div> | |
| <div class="arrow">↓</div> | |
| <div class="step result">実行結果</div> | |
| <div style="font-size: 0.75em; color: #666; margin-top: 10px;"> | |
| (読みながら即座に実行) | |
| </div> | |
| </div> | |
| <div class="examples">例: Python, Ruby, JavaScript, <strong>Forth</strong></div> | |
| </div> | |
| </div> | |
| </section> | |
| <section> | |
| <h3>インタプリタの基本構造</h3> | |
| <div class="lexer-container" style="font-size: 0.75em"> | |
| <div class="lexer-row"> | |
| <div class="lexer-input">"3 4 + 2 *"</div> | |
| <div class="big-arrow">→</div> | |
| <div class="lexer-process"> | |
| <div class="title">字句解析</div> | |
| <div class="sub">Lexical Analysis</div> | |
| </div> | |
| <div class="big-arrow">→</div> | |
| <div class="lexer-output"> | |
| <div class="lexer-token">"3"</div> | |
| <div class="lexer-token">"4"</div> | |
| <div class="lexer-token">"+"</div> | |
| <div class="lexer-token">"2"</div> | |
| <div class="lexer-token">"*"</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="highlight-box"> | |
| <strong>Forthの場合</strong>: 字句解析は非常にシンプル<br> | |
| → 空白で文字列を分割するだけ! <code>code.split()</code> | |
| </div> | |
| </section> | |
| <section> | |
| <h3>ディスパッチループ (Dispatch Loop)</h3> | |
| <div class="eval-loop-container" style="font-size: 0.75em"> | |
| <div class="eval-main-flow"> | |
| <div class="eval-box read">READ</div> | |
| <div class="flow-arrow">→</div> | |
| <div class="eval-box get">トークンを<br>1つ取得</div> | |
| <div class="flow-arrow">→</div> | |
| <div class="eval-box eval">EVAL<br>(評価)</div> | |
| <div class="flow-arrow" style="color: #999;">↩︎ 繰り返し</div> | |
| </div> | |
| <div style="text-align: center; margin: 10px 0; color: #666;">↓ EVAL の際にトークンの種類で分岐 (Dispatch)</div> | |
| <div class="eval-branches"> | |
| <div class="eval-branch"> | |
| <div class="condition">数値?</div> | |
| <div class="action">→ プッシュ</div> | |
| </div> | |
| <div class="eval-branch"> | |
| <div class="condition">演算子?</div> | |
| <div class="action">→ 演算実行</div> | |
| </div> | |
| <div class="eval-branch"> | |
| <div class="condition">ワード?</div> | |
| <div class="action">→ 定義実行</div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section> | |
| <h3>Pythonでの実装パターン</h3> | |
| <pre><code class="python" data-trim> | |
| def forth_eval(stack, code): | |
| tokens = code.split() # 字句解析 | |
| for token in tokens: # 評価ループ | |
| if 数値なら: | |
| スタックにプッシュ | |
| elif 演算子なら: | |
| スタックから値を取り出して演算 | |
| elif 定義済みワードなら: | |
| そのワードの本体を実行 | |
| </code></pre> | |
| </section> | |
| <section> | |
| <h3>動的言語の特徴</h3> | |
| <div style="text-align: left;"> | |
| <p><strong>1. 実行時に型が決まる(動的型付け)</strong></p> | |
| <pre><code class="python" data-trim> | |
| x = 10 # xは整数 | |
| x = "hello" # 同じxが文字列に(エラーなし) | |
| </code></pre> | |
| <p class="fragment"><strong>2. 実行時にプログラムを変更できる</strong></p> | |
| <pre class="fragment"><code class="forth" data-trim> | |
| : SQUARE DUP * ; ( 実行中に新しい命令を定義 ) | |
| 5 SQUARE . ( すぐに使える → 出力: 25 ) | |
| </code></pre> | |
| <p class="fragment"><strong>3. 対話的な開発が可能(REPL)</strong></p> | |
| <pre class="fragment"><code data-trim> | |
| > 3 4 + ← 入力 | |
| 7 ← 即座に結果 | |
| </code></pre> | |
| </div> | |
| </section> | |
| </section> | |
| <!-- セクション3: スタックとForthでの使い方 --> | |
| <section> | |
| <section> | |
| <h2>3. スタックとForthでの使い方</h2> | |
| <p class="small">(先週の復習)</p> | |
| </section> | |
| <section> | |
| <h3>スタックの基本操作</h3> | |
| <div class="two-column"> | |
| <div> | |
| <ul> | |
| <li><strong>push</strong>: 値を追加</li> | |
| <li><strong>pop</strong>: 値を取り出す</li> | |
| <li><strong>peek</strong>: 値を見る(取り出さない)</li> | |
| </ul> | |
| </div> | |
| <div> | |
| <div class="stack-viz"> | |
| push(1): [1]<br> | |
| push(2): [1, 2]<br> | |
| push(3): [1, 2, 3] ← top<br> | |
| pop(): [1, 2] → 3を取得<br> | |
| pop(): [1] → 2を取得 | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section> | |
| <h3>Forthでの計算: <code>3 4 +</code></h3> | |
| <table> | |
| <tr> | |
| <th>入力</th> | |
| <th>操作</th> | |
| <th>スタック</th> | |
| </tr> | |
| <tr class="fragment"> | |
| <td><code>3</code></td> | |
| <td>3をプッシュ</td> | |
| <td>[3]</td> | |
| </tr> | |
| <tr class="fragment"> | |
| <td><code>4</code></td> | |
| <td>4をプッシュ</td> | |
| <td>[3, 4]</td> | |
| </tr> | |
| <tr class="fragment"> | |
| <td><code>+</code></td> | |
| <td>2つポップして加算、結果をプッシュ</td> | |
| <td>[7]</td> | |
| </tr> | |
| </table> | |
| </section> | |
| <section> | |
| <h3>Forthでの計算: <code>3 4 + 2 *</code></h3> | |
| <p class="small">通常の記法: (3 + 4) × 2 = 14</p> | |
| <table> | |
| <tr> | |
| <th>入力</th> | |
| <th>スタック</th> | |
| </tr> | |
| <tr class="fragment"> | |
| <td><code>3</code></td> | |
| <td>[3]</td> | |
| </tr> | |
| <tr class="fragment"> | |
| <td><code>4</code></td> | |
| <td>[3, 4]</td> | |
| </tr> | |
| <tr class="fragment"> | |
| <td><code>+</code></td> | |
| <td>[7]</td> | |
| </tr> | |
| <tr class="fragment"> | |
| <td><code>2</code></td> | |
| <td>[7, 2]</td> | |
| </tr> | |
| <tr class="fragment"> | |
| <td><code>*</code></td> | |
| <td>[14]</td> | |
| </tr> | |
| </table> | |
| </section> | |
| <section> | |
| <h3>スタック操作関数(先週の復習)</h3> | |
| <pre><code class="python" data-trim data-line-numbers> | |
| def stack_new(): | |
| return [] | |
| def stack_push(stack, value): | |
| stack.append(value) | |
| def stack_pop(stack): | |
| if len(stack) == 0: | |
| raise IndexError("Stack underflow") | |
| return stack.pop() | |
| def stack_peek(stack): | |
| if len(stack) == 0: | |
| raise IndexError("Stack underflow") | |
| return stack[-1] | |
| </code></pre> | |
| </section> | |
| </section> | |
| <!-- セクション4: 参照実装 --> | |
| <section> | |
| <section> | |
| <h2>4. 参照実装</h2> | |
| <p>数値と四則演算のみの最小限の実装</p> | |
| </section> | |
| <section> | |
| <h3>基本的なインタプリタ</h3> | |
| <pre><code class="python" data-trim data-line-numbers="1-4|5|7|8-16|17-30|17-20|21-24|25-27|28-30"> | |
| def forth_eval(stack, code): | |
| """ | |
| Forthコードを評価する (最小実装) | |
| """ | |
| tokens = code.split() # 字句解析 | |
| for token in tokens: # 評価ループ | |
| # 数値の場合:スタックにプッシュ | |
| try: | |
| num = int(token) | |
| stack_push(stack, num) | |
| continue | |
| except ValueError: | |
| pass | |
| # 演算子の場合 | |
| if token == '+': | |
| b = stack_pop(stack) | |
| a = stack_pop(stack) | |
| stack_push(stack, a + b) | |
| elif token == '-': | |
| b = stack_pop(stack) | |
| a = stack_pop(stack) | |
| stack_push(stack, a - b) | |
| elif token == '*': | |
| b, a = stack_pop(stack), stack_pop(stack) | |
| stack_push(stack, a * b) | |
| elif token == '/': | |
| b, a = stack_pop(stack), stack_pop(stack) | |
| stack_push(stack, a // b) | |
| </code></pre> | |
| </section> | |
| <section> | |
| <h3>動作確認</h3> | |
| <pre><code class="python" data-trim> | |
| >>> stack = stack_new() | |
| >>> forth_eval(stack, "3 4 +") | |
| >>> print(stack) | |
| [7] | |
| >>> stack = stack_new() | |
| >>> forth_eval(stack, "3 4 + 2 *") | |
| >>> print(stack) | |
| [14] | |
| >>> stack = stack_new() | |
| >>> forth_eval(stack, "10 3 -") | |
| >>> print(stack) | |
| [7] | |
| </code></pre> | |
| </section> | |
| </section> | |
| <!-- セクション5: 演習問題 --> | |
| <section> | |
| <section> | |
| <h2>5. 演習問題</h2> | |
| </section> | |
| <section> | |
| <h3>課題1: スタック操作ワード</h3> | |
| <table> | |
| <tr> | |
| <th>ワード</th> | |
| <th>動作</th> | |
| <th>スタック変化</th> | |
| </tr> | |
| <tr> | |
| <td><code>.</code></td> | |
| <td>トップを出力して削除</td> | |
| <td>(a → )</td> | |
| </tr> | |
| <tr> | |
| <td><code>DUP</code></td> | |
| <td>トップを複製</td> | |
| <td>(a → a a)</td> | |
| </tr> | |
| <tr> | |
| <td><code>DROP</code></td> | |
| <td>トップを削除</td> | |
| <td>(a → )</td> | |
| </tr> | |
| <tr> | |
| <td><code>SWAP</code></td> | |
| <td>上位2つを交換</td> | |
| <td>(a b → b a)</td> | |
| </tr> | |
| <tr> | |
| <td><code>OVER</code></td> | |
| <td>2番目をコピー</td> | |
| <td>(a b → a b a)</td> | |
| </tr> | |
| <tr> | |
| <td><code>ROT</code></td> | |
| <td>3番目をトップへ</td> | |
| <td>(a b c → b c a)</td> | |
| </tr> | |
| </table> | |
| </section> | |
| <section> | |
| <h3>課題2: ユーザ定義ワード(35分)</h3> | |
| <p><code>: NAME ... ;</code> で新しいワードを定義</p> | |
| <pre><code class="forth" data-trim> | |
| : SQUARE DUP * ; ( 2乗を計算するワードを定義 ) | |
| 5 SQUARE . ( 25を出力 ) | |
| : DOUBLE DUP + ; | |
| : QUADRUPLE DOUBLE DOUBLE ; | |
| 5 QUADRUPLE . ( 20を出力 ) | |
| </code></pre> | |
| <div class="highlight-box fragment"> | |
| <strong>ポイント</strong>: 辞書(dictionary)にワード名と本体を保存 | |
| </div> | |
| </section> | |
| <section> | |
| <h3>発展課題</h3> | |
| <ul> | |
| <li><strong>発展1</strong>: 比較演算子(<code><</code>, <code>></code>, <code>=</code>)</li> | |
| <li><strong>発展2</strong>: 追加のスタック操作(<code>2DUP</code>, <code>NIP</code>, <code>TUCK</code>)</li> | |
| <li><strong>発展3</strong>: コメント機能(<code>( ... )</code>)</li> | |
| </ul> | |
| </section> | |
| </section> | |
| <!-- まとめ --> | |
| <section> | |
| <h2>まとめ</h2> | |
| <ul> | |
| <li><strong>インタプリタ</strong>: 字句解析 ⇢ ディスパッチループ ⇢ 結果</li> | |
| <li><strong>動的言語</strong>: 実行時に拡張可能</li> | |
| <li><strong>Forth</strong>:</li> | |
| <ul> | |
| <li>プログラム: 逆ポーランド記法</li> | |
| <li>処理系: スタックをデータ処理に用いるインタプリタ</li> | |
| </ul> | |
| </ul> | |
| <div class="highlight-box fragment"> | |
| 今週の目標: Forthインタプリタを自分で実装する | |
| <ul> | |
| <li>残り時間: ノートブックを開いて演習問題に取り組む</li> | |
| </ul> | |
| </div> | |
| </section> | |
| </div> | |
| </div> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/4.5.0/reveal.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/4.5.0/plugin/highlight/highlight.min.js"></script> | |
| <script> | |
| Reveal.initialize({ | |
| hash: true, | |
| slideNumber: true, | |
| plugins: [ RevealHighlight ], | |
| transition: 'slide', | |
| width: 1200, | |
| height: 700 | |
| }); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment