スタックベース言語とインタプリタの仕組み
2025年11月26日 伊澤侑祐
1. スタックベースの計算
すべての演算はスタック(LIFO)を介して行われる
2. 逆ポーランド記法(RPN)
| 通常の記法 | Forth |
|---|---|
| (3 + 4) * 2 | 3 4 + 2 * |
3. 単純で拡張可能
基本的な「ワード」の組み合わせで新しいワードを定義
code.split()
def forth_eval(stack, code):
tokens = code.split() # 字句解析
for token in tokens: # 評価ループ
if 数値なら:
スタックにプッシュ
elif 演算子なら:
スタックから値を取り出して演算
elif 定義済みワードなら:
そのワードの本体を実行
1. 実行時に型が決まる(動的型付け)
x = 10 # xは整数
x = "hello" # 同じxが文字列に(エラーなし)
2. 実行時にプログラムを変更できる
: SQUARE DUP * ; ( 実行中に新しい命令を定義 )
5 SQUARE . ( すぐに使える → 出力: 25 )
3. 対話的な開発が可能(REPL)
> 3 4 + ← 入力
7 ← 即座に結果
(先週の復習)
3 4 +| 入力 | 操作 | スタック |
|---|---|---|
3 |
3をプッシュ | [3] |
4 |
4をプッシュ | [3, 4] |
+ |
2つポップして加算、結果をプッシュ | [7] |
3 4 + 2 *通常の記法: (3 + 4) × 2 = 14
| 入力 | スタック |
|---|---|
3 |
[3] |
4 |
[3, 4] |
+ |
[7] |
2 |
[7, 2] |
* |
[14] |
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]
数値と四則演算のみの最小限の実装
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)
>>> 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]
| ワード | 動作 | スタック変化 |
|---|---|---|
. |
トップを出力して削除 | (a → ) |
DUP |
トップを複製 | (a → a a) |
DROP |
トップを削除 | (a → ) |
SWAP |
上位2つを交換 | (a b → b a) |
OVER |
2番目をコピー | (a b → a b a) |
ROT |
3番目をトップへ | (a b c → b c a) |
: NAME ... ; で新しいワードを定義
: SQUARE DUP * ; ( 2乗を計算するワードを定義 )
5 SQUARE . ( 25を出力 )
: DOUBLE DUP + ;
: QUADRUPLE DOUBLE DOUBLE ;
5 QUADRUPLE . ( 20を出力 )
<, >, =)2DUP, NIP, TUCK)( ... ))