トップ «前の日記(2011-08-26 (Fri)) 最新 次の日記(2012-02-27 (Mon))» 編集

uDiary

海野秀之(うんのひでゆき)の外部記憶

Twitter (twilog) / RSS / アンテナ / ぶくま

2006|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|08|
2010|01|02|03|05|06|07|10|11|
2011|03|08|
2012|02|04|07|08|10|
2013|01|02|03|05|06|08|11|12|
2014|01|02|05|06|07|08|09|12|
2015|01|02|03|04|

2011-08-29 (Mon)

[Scheme][3imp] グローバル変数に対応、組込み関数をいくつか。

3imp 4.5 節版処理系に改造をくわえていく。

普通に考えると、改造前の処理系について完全に理解してから、改造方針をたてて… とやるべきなのかも知れませんが、ここは触りながら理解していく方法で。

ひとまず、今回改造した版がこちら: sbscm-1.0.3.tar.bz2

Global 変数へのアクセス (define, set! および参照)をサポートし、 繰り返し VM を呼び出したときにグローバル変数が引き継がれるようにしました。

いくつかの組込み変数(四則と比較あたり)も追加してみました。

動かしてみた例:

Stack-Based Scheme Version 1.0.3 based on 3imp Section 4.5.
>>> (+ 1 2)
(frame (halt) (constant 2 (argument (constant 1 (argument (refer-global + (apply)))))))

==> 3

>>> (define x 1)
(constant 1 (define-global x (halt)))

==> x

>>> x
(refer-global x (halt))

==> 1

>>> (set! x (call/cc (lambda (cont) (cont 20))))
(frame (assign-global x (halt)) (conti (argument (close 0 (frame (return 1) (constant 20 (argument (refer-local 0 (apply))))) (apply)))))

==> 20

>>> (define fib (lambda (n) (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2))))))
(close 0 (frame (test (constant 1 (return 1)) (frame (return 1) (frame (argument (frame
 (argument (refer-global + (apply))) (frame (argument (refer-global fib (apply))) (constant 1
 (argument (refer-local 0 (argument (refer-global - (apply))))))))) (frame (argument
 (refer-global fib (apply))) (constant 2 (argument (refer-local 0 (argument (refer-global -
 (apply)))))))))) (constant 1 (argument (refer-local 0 (argument (refer-global <= (apply)))))))
 (define-global fib (halt)))

==> fib

>>> (fib 5)
(frame (halt) (constant 5 (argument (refer-global fib (apply)))))

==> 8

>>> (fib 20)
(frame (halt) (constant 20 (argument (refer-global fib (apply)))))

==> 10946

Global 変数は、e (environment) とは別のハッシュに格納している。 いまのところ、VM しかそのハッシュの中身を見ていないけど、define が組込み関数や syntax extension を隠す挙動を実現しようとすると、compile も global 変数を見ていないといけないような 気がするんだが。

…だいたい想像がつくような気もするけど、いまいちわかってないかも。 (だからこそ、作りながら理解する方針)

本日のツッコミ(全6件) [ツッコミを入れる]
# うんの (2011-08-29 (Mon) 22:27)

第一級の継続があるときの、グローバル変数の扱いがまちがっている気がする。

# うんの (2011-08-30 (Tue) 09:23)

http://practical-scheme.net/wiliki/wiliki.cgi?Scheme%3a%E4%BD%BF%E3%81%84%E3%81%9F%E3%81%84%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E7%B6%99%E7%B6%9A%E5%85%A5%E9%96%80#H-eivjo5zmspt にある環境破壊実験をやってみる。<br><br>Stack-Based Scheme Version 1.0.4 based on 3imp Section 4.5.<br>>>> (define k #f)<br>(constant #f (define-global k (halt)))<br><br>==> k<br><br>>>> (define x 1)<br>(constant 1 (define-global x (halt)))<br><br>==> x<br><br>>>> (+ x (call/cc (lambda (cont) ((set! k cont) 2))))<br>(frame (halt) (frame (argument (refer-global x (argument (refer-global + (apply))))) (conti (argument (close 0 (frame (return 1) (constant 2 (argument (refer-local 0 (assign-global k (apply)))))) (apply))))))<br><br>==> 3<br><br>>>> (k 20)<br>(frame (halt) (constant 20 (argument (refer-global k (apply)))))<br><br>==> 21<br><br>>>> (set! x 10)<br>(constant 10 (assign-global x (halt)))<br><br>==> 10<br><br>>>> (k 2)<br>(frame (halt) (constant 2 (argument (refer-global k (apply)))))<br><br>==> 12<br><br>継続なのに、環境破壊後の値を参照してしまっている(そりゃ、ああいう風にしたから当たり前なんですが)。<br><br>やっぱりだめです。

# うんの (2011-08-30 (Tue) 09:24)

+ が任意個の引数を取ってくれないので、リンク先とまったく同じ例はためせないという問題もあり。

# うんの (2011-08-30 (Tue) 09:27)

Gauche では、(+ x (call/cc (lambda (cont) cont 2))) とかけるな。<br><br>(cont 2) じゃなくてもいいのか。

# うんの (2011-09-06 (Tue) 17:02)

一個前のコメントに関連して:<br><br>gosh> (begin + 1 2)<br>2<br><br>そうなの。<br><br>R5RS 読んでみたけど、そうなる理由がいまいちわかんなかった。<br>(たぶん、読めてない)

# うんの (2011-09-13 (Tue) 14:22)

いろいろ誤読してたっぽい。


2006|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|08|
2010|01|02|03|05|06|07|10|11|
2011|03|08|
2012|02|04|07|08|10|
2013|01|02|03|05|06|08|11|12|
2014|01|02|05|06|07|08|09|12|
2015|01|02|03|04|
Categories 3imp | Card | Cutter | Dalvik | Euler | Football | GAE/J | Hand | Haskell | Re:View | Ruby | Scheme | TQD | Tiger | TigerBook読 | UikiTeXi | Verilog | Violin | Web | parconc | tDiary | お勉強 | エントロピー | ツン読 | | 将棋 | 政治について | | 模写してみよう | 確率論 | 設定など | 雑文 | 音声